Files
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
15 KiB
JSON

{"repo": "aibek-koken/liveassist", "files": {"proxy/.env.example": {"a9494f45b6d8e0f8e75a85adaa48ab9608d99b58": {"t": 1785745179.2079093, "n": 109, "h": "67988b60c2c2ed70", "c": "DEEPSEEK_API_KEY=your_deepseek_api_key\nDEEPSEEK_MODEL=deepseek-v4-flash\nAPP_SHARED_SECRET=your_shared_secret\n"}, "2a03e353eafe87b643f600e5c4e59168205a399f": {"t": 1785748426.613346, "n": 109, "h": "67988b60c2c2ed70", "c": "DEEPSEEK_API_KEY=your_deepseek_api_key\nDEEPSEEK_MODEL=deepseek-v4-flash\nAPP_SHARED_SECRET=your_shared_secret\n"}, "b8db147c2388ba09e63e216b941f7c3a4cf695cf": {"t": 1785748428.7325327, "n": 72, "h": "e382890ca367944d", "c": "GEMINI_API_KEY=your_gemini_api_key\nAPP_SHARED_SECRET=your_shared_secret\n"}}, "scripts/claude-safe-approve.sh": {"a9494f45b6d8e0f8e75a85adaa48ab9608d99b58": {"t": 1786068353.7539382, "n": 14212, "h": "590e3c8198aa053b", "c": "#!/usr/bin/env bash\nset -euo pipefail\n\nusage() {\n cat <<'USAGE'\nUsage:\n scripts/claude-safe-approve.sh policy\n scripts/claude-safe-approve.sh claude-args\n scripts/claude-safe-approve.sh allowed-files TASK-ID\n scripts/claude-safe-approve.sh classify-command \"COMMAND\"\n scripts/claude-safe-approve.sh validate-files TASK-ID [FILE...]\n scripts/claude-safe-approve.sh scan-log LOGFILE\n\nThis helper is a conservative policy layer for the CRM Assistant overnight runner.\nIt does not bypass Claude Code permissions. It documents safe defaults, emits\nClaude CLI tool allow/deny arguments, and performs post-run checks that the task\nonly changed files allowed for its current scope.\nUSAGE\n}\n\nalways_allowed_files() {\n cat <<'EOF'\nCLAUDE.md\nDoc/10-crm-assistant-task-queue.md\nDoc/12-claude-night-handoff.md\nEOF\n}\n\nrunner_maintenance_files() {\n cat <<'EOF'\nscripts/claude-night-runner.sh\nscripts/claude-task-prompt-builder.sh\nscripts/claude-safe-approve.sh\nscripts/claude-night-status.sh\nDoc/11-claude-night-runner-protocol.md\nEOF\n}\n\nprotected_files() {\n cat <<'EOF'\nsrc/renderer/src/overlay.tsx\nsrc-tauri/src/hotkey.rs\nsrc-tauri/src/lib.rs\nsrc-tauri/src/answer.rs\nproxy/server.js\ndb/schema.sql\nsrc-tauri/Cargo.toml\npackage.json\npackage-lock.json\nelectron-builder.yml\n.github/workflows/release.yml\nEOF\n}\n\nallowed_files_for_task() {\n case \"${1:-}\" in\n TASK-A)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/types.ts\nsrc/renderer/src/crm-assistant/mockData.ts\nsrc/renderer/src/crm-assistant/CrmAssistantView.tsx\nsrc/renderer/src/crm-assistant/SessionNoteInput.tsx\nEOF\n ;;\n TASK-B)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/LeadSelector.tsx\nsrc/renderer/src/crm-assistant/ApprovalBoard.tsx\nsrc/renderer/src/crm-assistant/ActionRow.tsx\nsrc/renderer/src/crm-assistant/WriteResultPanel.tsx\nsrc/renderer/src/crm-assistant/CrmAssistantView.tsx\nEOF\n ;;\n TASK-C)\n cat <<'EOF'\nsrc/renderer/src/App.tsx\nCLAUDE.md\nDoc/10-crm-assistant-task-queue.md\nDoc/12-claude-night-handoff.md\nEOF\n ;;\n TASK-D)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/extraction/types.ts\nsrc/renderer/src/crm-assistant/extraction/contracts.ts\nsrc/renderer/src/crm-assistant/extraction/fixtures.ts\nsrc/renderer/src/crm-assistant/extraction/fixtures.test.ts\nEOF\n ;;\n TASK-E)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/CrmAssistantView.tsx\nsrc/renderer/src/crm-assistant/SessionNoteInput.tsx\nsrc/renderer/src/crm-assistant/extraction/types.ts\nsrc/renderer/src/crm-assistant/extraction/contracts.ts\nsrc/renderer/src/crm-assistant/extraction/fixtures.ts\nsrc/renderer/src/crm-assistant/extraction/localExtractionService.ts\nsrc/renderer/src/crm-assistant/extraction/localExtractionService.test.ts\nEOF\n ;;\n TASK-F)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/extraction/types.ts\nsrc/renderer/src/crm-assistant/extraction/contracts.ts\nsrc/renderer/src/crm-assistant/extraction/localExtractionService.ts\nsrc/renderer/src/crm-assistant/extraction/extractionGateway.ts\nDoc/15-crm-phase2-extraction-architecture.md\nEOF\n ;;\n TASK-G)\n cat <<'EOF'\nCLAUDE.md\nDoc/10-crm-assistant-task-queue.md\nDoc/12-claude-night-handoff.md\nEOF\n ;;\n TASK-H)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/CrmAssistantView.tsx\nsrc/renderer/src/crm-assistant/SessionNoteInput.tsx\nsrc/renderer/src/crm-assistant/extraction/types.ts\nsrc/renderer/src/crm-assistant/extraction/contracts.ts\nsrc/renderer/src/crm-assistant/extraction/fixtures.ts\nsrc/renderer/src/crm-assistant/extraction/fixtures.test.ts\nsrc/renderer/src/crm-assistant/extraction/localExtractionService.ts\nsrc/renderer/src/crm-assistant/extraction/localExtractionService.test.ts\nsrc/renderer/src/crm-assistant/extraction/extractionGateway.ts\nsrc/renderer/src/crm-assistant/extraction/extractionGateway.test.ts\nsrc/renderer/src/crm-assistant/extraction/aiExtractionPrompt.ts\nsrc/renderer/src/crm-assistant/extraction/aiExtractionProvider.ts\nsrc/renderer/src/crm-assistant/extraction/aiExtractionProvider.test.ts\nsrc/renderer/src/crm-assistant/extraction/aiExtractionParser.ts\nsrc/renderer/src/crm-assistant/extraction/aiExtractionParser.test.ts\nEOF\n ;;\n TASK-I)\n cat <<'EOF'\nCLAUDE.md\nDoc/10-crm-assistant-task-queue.md\nDoc/11-claude-night-runner-protocol.md\nDoc/12-claude-night-handoff.md\nDoc/16-crm-phase3-context-pack.md\nsrc/renderer/src/crm-assistant/CrmAssistantView.tsx\nsrc/renderer/src/crm-assistant/SessionNoteInput.tsx\nsrc/renderer/src/crm-assistant/extraction/types.ts\nsrc/renderer/src/crm-assistant/extraction/contracts.ts\nsrc/renderer/src/crm-assistant/extraction/fixtures.ts\nsrc/renderer/src/crm-assistant/extraction/fixtures.test.ts\nsrc/renderer/src/crm-assistant/extraction/localExtractionService.ts\nsrc/renderer/src/crm-assistant/extraction/localExtractionService.test.ts\nsrc/renderer/src/crm-assistant/extraction/extractionGateway.ts\nsrc/renderer/src/crm-assistant/extraction/extractionGateway.test.ts\nsrc/renderer/src/crm-assistant/extraction/aiExtractionPrompt.ts\nsrc/renderer/src/crm-assistant/extraction/aiExtractionProvider.ts\nsrc/renderer/src/crm-assistant/extraction/aiExtractionProvider.test.ts\nsrc/renderer/src/crm-assistant/extraction/aiExtractionParser.ts\nsrc/renderer/src/crm-assistant/extraction/aiExtractionParser.test.ts\nEOF\n ;;\n TASK-J)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/types.ts\nsrc/renderer/src/crm-assistant/mockData.ts\nsrc/renderer/src/crm-assistant/integration/types.ts\nsrc/renderer/src/crm-assistant/integration/config.ts\nsrc/renderer/src/crm-assistant/integration/sandboxProvider.ts\nsrc/renderer/src/crm-assistant/integration/sandboxProvider.test.ts\nsrc/renderer/src/crm-assistant/integration/applyPipeline.ts\nsrc/renderer/src/crm-assistant/integration/applyPipeline.test.ts\nDoc/17-crm-phase4-context-pack.md\nEOF\n ;;\n TASK-K)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/CrmAssistantView.tsx\nsrc/renderer/src/crm-assistant/ApprovalBoard.tsx\nsrc/renderer/src/crm-assistant/ActionRow.tsx\nsrc/renderer/src/crm-assistant/WriteResultPanel.tsx\nsrc/renderer/src/crm-assistant/types.ts\nsrc/renderer/src/crm-assistant/mockData.ts\nsrc/renderer/src/crm-assistant/integration/types.ts\nsrc/renderer/src/crm-assistant/integration/config.ts\nsrc/renderer/src/crm-assistant/integration/sandboxProvider.ts\nsrc/renderer/src/crm-assistant/integration/sandboxProvider.test.ts\nsrc/renderer/src/crm-assistant/integration/applyPipeline.ts\nsrc/renderer/src/crm-assistant/integration/applyPipeline.test.ts\nCLAUDE.md\nDoc/10-crm-assistant-task-queue.md\nDoc/12-claude-night-handoff.md\nDoc/17-crm-phase4-context-pack.md\nEOF\n ;;\n TASK-L)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/CrmAssistantView.tsx\nsrc/renderer/src/crm-assistant/ApprovalBoard.tsx\nsrc/renderer/src/crm-assistant/ActionRow.tsx\nsrc/renderer/src/crm-assistant/WriteResultPanel.tsx\nsrc/renderer/src/crm-assistant/LeadSelector.tsx\nsrc/renderer/src/crm-assistant/types.ts\nsrc/renderer/src/crm-assistant/mockData.ts\nsrc/renderer/src/crm-assistant/integration/types.ts\nsrc/renderer/src/crm-assistant/integration/sandboxProvider.ts\nsrc/renderer/src/crm-assistant/history/actionHistory.ts\nsrc/renderer/src/crm-assistant/history/actionHistory.test.ts\nsrc/renderer/src/crm-assistant/history/CrmActionHistoryPanel.tsx\nsrc/renderer/src/crm-assistant/history/CrmContextPreview.tsx\nDoc/18-crm-phase5-context-pack.md\nEOF\n ;;\n TASK-M)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/CrmAssistantView.tsx\nsrc/renderer/src/crm-assistant/SessionNoteInput.tsx\nsrc/renderer/src/crm-assistant/ApprovalBoard.tsx\nsrc/renderer/src/crm-assistant/ActionRow.tsx\nsrc/renderer/src/crm-assistant/WriteResultPanel.tsx\nsrc/renderer/src/crm-assistant/types.ts\nsrc/renderer/src/crm-assistant/mockData.ts\nsrc/renderer/src/crm-assistant/extraction/types.ts\nsrc/renderer/src/crm-assistant/extraction/contracts.ts\nsrc/renderer/src/crm-assistant/extraction/fixtures.ts\nsrc/renderer/src/crm-assistant/extraction/localExtractionService.ts\nsrc/renderer/src/crm-assistant/extraction/localExtractionService.test.ts\nsrc/renderer/src/crm-assistant/integration/types.ts\nsrc/renderer/src/crm-assistant/integration/applyPipeline.ts\nsrc/renderer/src/crm-assistant/integration/applyPipeline.test.ts\nsrc/renderer/src/crm-assistant/review/reviewModel.ts\nsrc/renderer/src/crm-assistant/review/reviewModel.test.ts\nCLAUDE.md\nDoc/10-crm-assistant-task-queue.md\nDoc/12-claude-night-handoff.md\nDoc/18-crm-phase5-context-pack.md\nEOF\n ;;\n TASK-N)\n cat <<'EOF'\nsrc/renderer/src/crm-assistant/CrmAssistantView.tsx\nsrc/renderer/src/crm-assistant/ApprovalBoard.tsx\nsrc/renderer/src/crm-assistant/ActionRow.tsx\nsrc/renderer/src/crm-assistant/WriteResultPanel.tsx\nsrc/renderer/src/crm-assistant/LeadSelector.tsx\nsrc/renderer/src/crm-assistant/types.ts\nsrc/renderer/src/crm-assistant/mockData.ts\nsrc/renderer/src/crm-assistant/integration/types.ts\nsrc/renderer/src/crm-assistant/integration/config.ts\nsrc/renderer/src/crm-assistant/integration/sandboxProvider.ts\nsrc/renderer/src/crm-assistant/integration/applyPipeline.ts\nsrc/renderer/src/crm-assistant/history/actionHistory.ts\nsrc/renderer/src/crm-assistant/history/CrmActionHistoryPanel.tsx\nsrc/renderer/src/crm-assistant/history/CrmContextPreview.tsx\nCLAUDE.md\nDoc/10-crm-assistant-task-queue.md\nDoc/11-claude-night-runner-protocol.md\nDoc/12-claude-night-handoff.md\nDoc/19-crm-phase6-context-pack.md\nDoc/20-crm-pilot-readiness-checklist.md\nDoc/21-crm-phase6-final-handoff.md\nEOF\n ;;\n RUNNER-MAINTENANCE)\n runner_maintenance_files\n ;;\n *)\n return 1\n ;;\n esac\n}\n\npolicy() {\n cat <<'EOF'\nSafe auto-approval policy for the CRM Assistant overnight runner\n\nAllowed by default:\n- Read/search/list files.\n- Create new files inside the current task's approved scope.\n- Edit files listed in the current task scope.\n- Update CLAUDE.md, Doc/10 task queue, and Doc/12 handoff.\n- Run: npm run typecheck, npm run test, npm run web:build.\n- Run: cargo test.\n- Run: git status, git diff.\n- Run read-only shell helpers: ls, cat, sed, grep, rg, find.\n- Run mkdir for planned folders.\n\nNever auto-approve:\n- rm -rf or deleting source/db/env files.\n- git push, git reset --hard, git clean -fd.\n- Adding dependencies unless the active task explicitly scopes them.\n- Changing protected overlay/hotkey/AppKit/SSE/document-RAG files unless the active task explicitly scopes them.\n- Changing proxy/server.js /generate behavior unless the active task explicitly scopes it.\n- Changing db/schema.sql unless the active task explicitly scopes it.\n- Real amoCRM OAuth, write-back, production CRM access, secrets, or tokens.\n- CI/release config changes.\n- Claude-side commits. Optional runner-side --auto-commit happens only after validation and safe-approve.\n\nClaude Code global bypass modes are intentionally not used by this runner.\nThe runner uses constrained allowed/disallowed tool lists and then validates\nchanged files after each task.\nEOF\n}\n\nclaude_args() {\n cat <<'EOF'\n--permission-mode\nacceptEdits\n--allowedTools\nRead,LS,Glob,Grep,Edit,Write,Bash(git status),Bash(git diff),Bash(git diff --check),Bash(npm run typecheck),Bash(npm run test),Bash(npm run web:build),Bash(cargo test),Bash(mkdir *),Bash(rg *),Bash(find *),Bash(ls *),Bash(cat *),Bash(sed *),Bash(grep *)\n--disallowedTools\nBash(rm *),Bash(git push*),Bash(git reset*),Bash(git clean*),Bash(git commit*),Bash(npm install*),Bash(cargo add*),Bash(curl *),Bash(wget *),Bash(open *),Bash(gh *),Bash(chmod *)\nEOF\n}\n\nclassify_command() {\n local command=\"${1:-}\"\n case \"$command\" in\n *\"rm -rf\"*|*\"git push\"*|*\"git reset --hard\"*|*\"git clean -fd\"*|*\"npm install\"*|*\"cargo add\"*|*\"curl \"*|*\"wget \"*|*\"open \"*|*\"gh \"*|*\"APP_SECRET\"*|*\"DEEPSEEK_API_KEY\"*|*\"AMO\"*TOKEN*|*\"amoCRM\"*write*)\n echo \"deny\"\n return 2\n ;;\n \"npm run typecheck\"|\"npm run test\"|\"npm run web:build\"|\"cargo test\"|git\\ status*|git\\ diff*|ls*|cat*|sed*|grep*|rg*|find*|mkdir*)\n echo \"allow\"\n ;;\n *)\n echo \"review\"\n return 1\n ;;\n esac\n}\n\nis_allowed_file() {\n local task_id=\"$1\"\n local file=\"$2\"\n\n case \"$file\" in\n .claude-runs/*)\n return 0\n ;;\n esac\n\n if always_allowed_files | grep -Fxq \"$file\"; then\n return 0\n fi\n\n if allowed_files_for_task \"$task_id\" | grep -Fxq \"$file\"; then\n return 0\n fi\n\n return 1\n}\n\nvalidate_files() {\n local task_id=\"$1\"\n shift || true\n\n local -a files=()\n if [ \"$#\" -gt 0 ]; then\n files=(\"$@\")\n else\n while IFS= read -r line; do\n [ -n \"$line\" ] && files+=(\"$line\")\n done\n fi\n\n if [ \"${#files[@]}\" -eq 0 ]; then\n return 0\n fi\n\n local failed=0\n local file\n for file in \"${files[@]}\"; do\n [ -z \"$file\" ] && continue\n if protected_files | grep -Fxq \"$file\"; then\n if ! is_allowed_file \"$task_id\" \"$file\"; then\n echo \"DENY protected file changed outside scope: $file\" >&2\n failed=1\n continue\n fi\n fi\n\n if ! is_allowed_file \"$task_id\" \"$file\"; then\n echo \"DENY file changed outside task scope: $file\" >&2\n failed=1\n fi\n done\n\n if [ \"$failed\" -ne 0 ]; then\n return 2\n fi\n}\n\nscan_log() {\n local logfile=\"$1\"\n local secret_pattern='(DEEPSEEK_API_KEY|APP_SHARED_SECRET|AMO_CLIENT_SECRET|AMO_ACCESS_TOKEN|AMO_REFRESH_TOKEN|access_token|refresh_token|Authorization:[[:space:]]*Bearer|client_secret|x-app-secret)'\n [ -f \"$logfile\" ] || return 0\n\n if grep -E '(^|[[:space:]])(rm -rf|git push|git reset --hard|git clean -fd|npm install|cargo add)([[:space:]]|$)' \"$logfile\" >/dev/null; then\n echo \"Potential dangerous command found in log: $logfile\" >&2\n return 2\n fi\n\n if grep -Eiq \"$secret_pattern\" \"$logfile\"; then\n echo \"Potential secret reference found in log: $logfile\" >&2\n return 2\n fi\n}\n\nmain() {\n local command=\"${1:-help}\"\n shift || true\n\n case \"$command\" in\n policy)\n policy\n ;;\n claude-args)\n claude_args\n ;;\n allowed-files)\n allowed_files_for_task \"${1:?TASK-ID is required}\"\n ;;\n classify-command)\n classify_command \"$*\"\n ;;\n validate-files)\n validate_files \"${1:?TASK-ID is required}\" \"${@:2}\"\n ;;\n scan-log)\n scan_log \"${1:?LOGFILE is required}\"\n ;;\n help|--help|-h)\n usage\n ;;\n *)\n usage >&2\n exit 2\n ;;\n esac\n}\n\nmain \"$@\"\n"}}}}