synabun 1.3.0 → 2.0.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +197 -662
- package/LICENSE-COMMERCIAL.md +33 -0
- package/NOTICE +17 -0
- package/README.md +175 -853
- package/THIRD-PARTY-LICENSES.md +131 -0
- package/benchmarks/browser-live-results.json +79 -0
- package/benchmarks/browser-v2-results.json +258 -0
- package/benchmarks/fixtures/browser/README.md +57 -0
- package/benchmarks/fixtures/browser/page-state.json +132 -0
- package/benchmarks/fixtures/browser/social.json +92 -0
- package/benchmarks/fixtures/browser/target.json +319 -0
- package/benchmarks/fixtures/desktop/README.md +58 -0
- package/benchmarks/fixtures/desktop/abstention.json +59 -0
- package/benchmarks/fixtures/desktop/adversarial.json +22 -0
- package/benchmarks/fixtures/desktop/forbidden.json +93 -0
- package/benchmarks/fixtures/desktop/generate.mjs +1023 -0
- package/benchmarks/fixtures/desktop/target.json +136 -0
- package/bin/synabun.js +30 -0
- package/docs/browser-v2.md +109 -0
- package/docs/hook-integrity.md +89 -0
- package/docs/judgments.md +182 -0
- package/docs/style-guide.md +246 -0
- package/docs/whatsapp.md +325 -0
- package/hooks/claude-code/post-plan.mjs +613 -391
- package/hooks/claude-code/post-remember.mjs +246 -122
- package/hooks/claude-code/pre-compact.mjs +171 -110
- package/hooks/claude-code/pre-task.mjs +133 -0
- package/hooks/claude-code/pre-websearch.mjs +15 -4
- package/hooks/claude-code/prompt-origin.mjs +94 -0
- package/hooks/claude-code/prompt-submit.mjs +1244 -861
- package/hooks/claude-code/session-start.mjs +114 -156
- package/hooks/claude-code/shared.mjs +1228 -368
- package/hooks/claude-code/state.mjs +167 -0
- package/hooks/claude-code/stop.mjs +515 -140
- package/hooks/claude-code/subagent-start.mjs +154 -0
- package/hooks/claude-code/subagent-stop.mjs +102 -0
- package/hooks/claude-code/task-gate.mjs +150 -0
- package/lib/claude-hooks.js +84 -0
- package/lib/claude-usage-audit.js +141 -0
- package/lib/client-config-repair.js +144 -0
- package/lib/data-home-migration.js +498 -0
- package/lib/first-launch-protection.js +240 -0
- package/lib/paths.d.ts +21 -0
- package/lib/paths.js +103 -0
- package/mcp-server/dist/config.d.ts +22 -0
- package/mcp-server/dist/config.d.ts.map +1 -0
- package/mcp-server/dist/config.js +109 -0
- package/mcp-server/dist/config.js.map +1 -0
- package/mcp-server/dist/http.d.ts +30 -0
- package/mcp-server/dist/http.d.ts.map +1 -0
- package/mcp-server/dist/http.js +276 -0
- package/mcp-server/dist/http.js.map +1 -0
- package/mcp-server/dist/index.d.ts +48 -0
- package/mcp-server/dist/index.d.ts.map +1 -0
- package/mcp-server/dist/index.js +538 -0
- package/mcp-server/dist/index.js.map +1 -0
- package/mcp-server/dist/preload-http.d.ts +3 -0
- package/mcp-server/dist/preload-http.d.ts.map +1 -0
- package/mcp-server/dist/preload-http.js +28 -0
- package/mcp-server/dist/preload-http.js.map +1 -0
- package/mcp-server/dist/preload.d.ts +3 -0
- package/mcp-server/dist/preload.d.ts.map +1 -0
- package/mcp-server/dist/preload.js +32 -0
- package/mcp-server/dist/preload.js.map +1 -0
- package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.d.ts +19 -0
- package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.d.ts.map +1 -0
- package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.js +403 -0
- package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.js.map +1 -0
- package/mcp-server/dist/scripts/setup-embeddings.d.ts +3 -0
- package/mcp-server/dist/scripts/setup-embeddings.d.ts.map +1 -0
- package/mcp-server/dist/scripts/setup-embeddings.js +15 -0
- package/mcp-server/dist/scripts/setup-embeddings.js.map +1 -0
- package/mcp-server/dist/services/assistant-judgments.d.ts +79 -0
- package/mcp-server/dist/services/assistant-judgments.d.ts.map +1 -0
- package/mcp-server/dist/services/assistant-judgments.js +128 -0
- package/mcp-server/dist/services/assistant-judgments.js.map +1 -0
- package/mcp-server/dist/services/browser-assist-gate.d.ts +314 -0
- package/mcp-server/dist/services/browser-assist-gate.d.ts.map +1 -0
- package/mcp-server/dist/services/browser-assist-gate.js +344 -0
- package/mcp-server/dist/services/browser-assist-gate.js.map +1 -0
- package/mcp-server/dist/services/browser-assist.d.ts +104 -0
- package/mcp-server/dist/services/browser-assist.d.ts.map +1 -0
- package/mcp-server/dist/services/browser-assist.js +282 -0
- package/mcp-server/dist/services/browser-assist.js.map +1 -0
- package/mcp-server/dist/services/browser-bench.d.ts +772 -0
- package/mcp-server/dist/services/browser-bench.d.ts.map +1 -0
- package/mcp-server/dist/services/browser-bench.js +424 -0
- package/mcp-server/dist/services/browser-bench.js.map +1 -0
- package/mcp-server/dist/services/browser-judgments.d.ts +196 -0
- package/mcp-server/dist/services/browser-judgments.d.ts.map +1 -0
- package/mcp-server/dist/services/browser-judgments.js +363 -0
- package/mcp-server/dist/services/browser-judgments.js.map +1 -0
- package/mcp-server/dist/services/browser-risk.d.ts +166 -0
- package/mcp-server/dist/services/browser-risk.d.ts.map +1 -0
- package/mcp-server/dist/services/browser-risk.js +458 -0
- package/mcp-server/dist/services/browser-risk.js.map +1 -0
- package/mcp-server/dist/services/categories.d.ts +61 -0
- package/mcp-server/dist/services/categories.d.ts.map +1 -0
- package/mcp-server/dist/services/categories.js +377 -0
- package/mcp-server/dist/services/categories.js.map +1 -0
- package/mcp-server/dist/services/codex-config-heal.d.ts +49 -0
- package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -0
- package/mcp-server/dist/services/codex-config-heal.js +346 -0
- package/mcp-server/dist/services/codex-config-heal.js.map +1 -0
- package/mcp-server/dist/services/desktop-assist-gate.d.ts +198 -0
- package/mcp-server/dist/services/desktop-assist-gate.d.ts.map +1 -0
- package/mcp-server/dist/services/desktop-assist-gate.js +202 -0
- package/mcp-server/dist/services/desktop-assist-gate.js.map +1 -0
- package/mcp-server/dist/services/desktop-assist.d.ts +104 -0
- package/mcp-server/dist/services/desktop-assist.d.ts.map +1 -0
- package/mcp-server/dist/services/desktop-assist.js +266 -0
- package/mcp-server/dist/services/desktop-assist.js.map +1 -0
- package/mcp-server/dist/services/desktop-bench.d.ts +553 -0
- package/mcp-server/dist/services/desktop-bench.d.ts.map +1 -0
- package/mcp-server/dist/services/desktop-bench.js +311 -0
- package/mcp-server/dist/services/desktop-bench.js.map +1 -0
- package/mcp-server/dist/services/desktop-client.d.ts +23 -0
- package/mcp-server/dist/services/desktop-client.d.ts.map +1 -0
- package/mcp-server/dist/services/desktop-client.js +79 -0
- package/mcp-server/dist/services/desktop-client.js.map +1 -0
- package/mcp-server/dist/services/desktop-judgments.d.ts +125 -0
- package/mcp-server/dist/services/desktop-judgments.d.ts.map +1 -0
- package/mcp-server/dist/services/desktop-judgments.js +177 -0
- package/mcp-server/dist/services/desktop-judgments.js.map +1 -0
- package/mcp-server/dist/services/desktop-risk.d.ts +283 -0
- package/mcp-server/dist/services/desktop-risk.d.ts.map +1 -0
- package/mcp-server/dist/services/desktop-risk.js +605 -0
- package/mcp-server/dist/services/desktop-risk.js.map +1 -0
- package/mcp-server/dist/services/discord.d.ts +112 -0
- package/mcp-server/dist/services/discord.d.ts.map +1 -0
- package/mcp-server/dist/services/discord.js +477 -0
- package/mcp-server/dist/services/discord.js.map +1 -0
- package/mcp-server/dist/services/edit-stale.d.ts +81 -0
- package/mcp-server/dist/services/edit-stale.d.ts.map +1 -0
- package/mcp-server/dist/services/edit-stale.js +358 -0
- package/mcp-server/dist/services/edit-stale.js.map +1 -0
- package/mcp-server/dist/services/embedding-service.d.ts +16 -0
- package/mcp-server/dist/services/embedding-service.d.ts.map +1 -0
- package/mcp-server/dist/services/embedding-service.js +126 -0
- package/mcp-server/dist/services/embedding-service.js.map +1 -0
- package/mcp-server/dist/services/embedding-worker.d.ts +2 -0
- package/mcp-server/dist/services/embedding-worker.d.ts.map +1 -0
- package/mcp-server/dist/services/embedding-worker.js +52 -0
- package/mcp-server/dist/services/embedding-worker.js.map +1 -0
- package/mcp-server/dist/services/fb-regions.d.ts +71 -0
- package/mcp-server/dist/services/fb-regions.d.ts.map +1 -0
- package/mcp-server/dist/services/fb-regions.js +211 -0
- package/mcp-server/dist/services/fb-regions.js.map +1 -0
- package/mcp-server/dist/services/file-checksums.d.ts +22 -0
- package/mcp-server/dist/services/file-checksums.d.ts.map +1 -0
- package/mcp-server/dist/services/file-checksums.js +55 -0
- package/mcp-server/dist/services/file-checksums.js.map +1 -0
- package/mcp-server/dist/services/file-excerpt.d.ts +24 -0
- package/mcp-server/dist/services/file-excerpt.d.ts.map +1 -0
- package/mcp-server/dist/services/file-excerpt.js +65 -0
- package/mcp-server/dist/services/file-excerpt.js.map +1 -0
- package/mcp-server/dist/services/identity.d.ts +124 -0
- package/mcp-server/dist/services/identity.d.ts.map +1 -0
- package/mcp-server/dist/services/identity.js +241 -0
- package/mcp-server/dist/services/identity.js.map +1 -0
- package/mcp-server/dist/services/local-embeddings.d.ts +2 -0
- package/mcp-server/dist/services/local-embeddings.d.ts.map +1 -0
- package/mcp-server/dist/services/local-embeddings.js +3 -0
- package/mcp-server/dist/services/local-embeddings.js.map +1 -0
- package/mcp-server/dist/services/memory-client.d.ts +4 -0
- package/mcp-server/dist/services/memory-client.d.ts.map +1 -0
- package/mcp-server/dist/services/memory-client.js +27 -0
- package/mcp-server/dist/services/memory-client.js.map +1 -0
- package/mcp-server/dist/services/memory-judge-backfill.d.ts +135 -0
- package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -0
- package/mcp-server/dist/services/memory-judge-backfill.js +510 -0
- package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -0
- package/mcp-server/dist/services/memory-judgments.d.ts +362 -0
- package/mcp-server/dist/services/memory-judgments.d.ts.map +1 -0
- package/mcp-server/dist/services/memory-judgments.js +674 -0
- package/mcp-server/dist/services/memory-judgments.js.map +1 -0
- package/mcp-server/dist/services/memory-maintenance.d.ts +108 -0
- package/mcp-server/dist/services/memory-maintenance.d.ts.map +1 -0
- package/mcp-server/dist/services/memory-maintenance.js +403 -0
- package/mcp-server/dist/services/memory-maintenance.js.map +1 -0
- package/mcp-server/dist/services/memory-retrieval.d.ts +66 -0
- package/mcp-server/dist/services/memory-retrieval.d.ts.map +1 -0
- package/mcp-server/dist/services/memory-retrieval.js +412 -0
- package/mcp-server/dist/services/memory-retrieval.js.map +1 -0
- package/mcp-server/dist/services/memory-schema.d.ts +16 -0
- package/mcp-server/dist/services/memory-schema.d.ts.map +1 -0
- package/mcp-server/dist/services/memory-schema.js +282 -0
- package/mcp-server/dist/services/memory-schema.js.map +1 -0
- package/mcp-server/dist/services/memory-sessions.d.ts +24 -0
- package/mcp-server/dist/services/memory-sessions.d.ts.map +1 -0
- package/mcp-server/dist/services/memory-sessions.js +110 -0
- package/mcp-server/dist/services/memory-sessions.js.map +1 -0
- package/mcp-server/dist/services/memory-triage.d.ts +60 -0
- package/mcp-server/dist/services/memory-triage.d.ts.map +1 -0
- package/mcp-server/dist/services/memory-triage.js +189 -0
- package/mcp-server/dist/services/memory-triage.js.map +1 -0
- package/mcp-server/dist/services/memory-verification.d.ts +24 -0
- package/mcp-server/dist/services/memory-verification.d.ts.map +1 -0
- package/mcp-server/dist/services/memory-verification.js +92 -0
- package/mcp-server/dist/services/memory-verification.js.map +1 -0
- package/mcp-server/dist/services/memory-writer.d.ts +26 -0
- package/mcp-server/dist/services/memory-writer.d.ts.map +1 -0
- package/mcp-server/dist/services/memory-writer.js +126 -0
- package/mcp-server/dist/services/memory-writer.js.map +1 -0
- package/mcp-server/dist/services/neural-interface.d.ts +439 -0
- package/mcp-server/dist/services/neural-interface.d.ts.map +1 -0
- package/mcp-server/dist/services/neural-interface.js +1135 -0
- package/mcp-server/dist/services/neural-interface.js.map +1 -0
- package/mcp-server/dist/services/profiles.d.ts +120 -0
- package/mcp-server/dist/services/profiles.d.ts.map +1 -0
- package/mcp-server/dist/services/profiles.js +387 -0
- package/mcp-server/dist/services/profiles.js.map +1 -0
- package/mcp-server/dist/services/secret-gate.d.ts +29 -0
- package/mcp-server/dist/services/secret-gate.d.ts.map +1 -0
- package/mcp-server/dist/services/secret-gate.js +43 -0
- package/mcp-server/dist/services/secret-gate.js.map +1 -0
- package/mcp-server/dist/services/server-instructions.d.ts +10 -0
- package/mcp-server/dist/services/server-instructions.d.ts.map +1 -0
- package/mcp-server/dist/services/server-instructions.js +101 -0
- package/mcp-server/dist/services/server-instructions.js.map +1 -0
- package/mcp-server/dist/services/sqlite.d.ts +235 -0
- package/mcp-server/dist/services/sqlite.d.ts.map +1 -0
- package/mcp-server/dist/services/sqlite.js +1185 -0
- package/mcp-server/dist/services/sqlite.js.map +1 -0
- package/mcp-server/dist/services/typesafe-bench.d.ts +99 -0
- package/mcp-server/dist/services/typesafe-bench.d.ts.map +1 -0
- package/mcp-server/dist/services/typesafe-bench.js +218 -0
- package/mcp-server/dist/services/typesafe-bench.js.map +1 -0
- package/mcp-server/dist/services/typesafe-config.d.ts +342 -0
- package/mcp-server/dist/services/typesafe-config.d.ts.map +1 -0
- package/mcp-server/dist/services/typesafe-config.js +746 -0
- package/mcp-server/dist/services/typesafe-config.js.map +1 -0
- package/mcp-server/dist/services/typesafe.d.ts +213 -0
- package/mcp-server/dist/services/typesafe.d.ts.map +1 -0
- package/mcp-server/dist/services/typesafe.js +330 -0
- package/mcp-server/dist/services/typesafe.js.map +1 -0
- package/mcp-server/dist/services/vector-cache.d.ts +68 -0
- package/mcp-server/dist/services/vector-cache.d.ts.map +1 -0
- package/mcp-server/dist/services/vector-cache.js +271 -0
- package/mcp-server/dist/services/vector-cache.js.map +1 -0
- package/mcp-server/dist/services/whiteboard-geometry.d.ts +305 -0
- package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -0
- package/mcp-server/dist/services/whiteboard-geometry.js +666 -0
- package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -0
- package/mcp-server/dist/tools/agents.d.ts +212 -0
- package/mcp-server/dist/tools/agents.d.ts.map +1 -0
- package/mcp-server/dist/tools/agents.js +407 -0
- package/mcp-server/dist/tools/agents.js.map +1 -0
- package/mcp-server/dist/tools/bluesky.d.ts +39 -0
- package/mcp-server/dist/tools/bluesky.d.ts.map +1 -0
- package/mcp-server/dist/tools/bluesky.js +1144 -0
- package/mcp-server/dist/tools/bluesky.js.map +1 -0
- package/mcp-server/dist/tools/browser-advanced.d.ts +58 -0
- package/mcp-server/dist/tools/browser-advanced.d.ts.map +1 -0
- package/mcp-server/dist/tools/browser-advanced.js +106 -0
- package/mcp-server/dist/tools/browser-advanced.js.map +1 -0
- package/mcp-server/dist/tools/browser-batch.d.ts +99 -0
- package/mcp-server/dist/tools/browser-batch.d.ts.map +1 -0
- package/mcp-server/dist/tools/browser-batch.js +187 -0
- package/mcp-server/dist/tools/browser-batch.js.map +1 -0
- package/mcp-server/dist/tools/browser-cheatsheet.d.ts +21 -0
- package/mcp-server/dist/tools/browser-cheatsheet.d.ts.map +1 -0
- package/mcp-server/dist/tools/browser-cheatsheet.js +144 -0
- package/mcp-server/dist/tools/browser-cheatsheet.js.map +1 -0
- package/mcp-server/dist/tools/browser-interact.d.ts +239 -0
- package/mcp-server/dist/tools/browser-interact.d.ts.map +1 -0
- package/mcp-server/dist/tools/browser-interact.js +300 -0
- package/mcp-server/dist/tools/browser-interact.js.map +1 -0
- package/mcp-server/dist/tools/browser-navigate.d.ts +90 -0
- package/mcp-server/dist/tools/browser-navigate.d.ts.map +1 -0
- package/mcp-server/dist/tools/browser-navigate.js +142 -0
- package/mcp-server/dist/tools/browser-navigate.js.map +1 -0
- package/mcp-server/dist/tools/browser-observe.d.ts +561 -0
- package/mcp-server/dist/tools/browser-observe.d.ts.map +1 -0
- package/mcp-server/dist/tools/browser-observe.js +2009 -0
- package/mcp-server/dist/tools/browser-observe.js.map +1 -0
- package/mcp-server/dist/tools/browser.d.ts +34 -0
- package/mcp-server/dist/tools/browser.d.ts.map +1 -0
- package/mcp-server/dist/tools/browser.js +112 -0
- package/mcp-server/dist/tools/browser.js.map +1 -0
- package/mcp-server/dist/tools/card-tools.d.ts +82 -0
- package/mcp-server/dist/tools/card-tools.d.ts.map +1 -0
- package/mcp-server/dist/tools/card-tools.js +137 -0
- package/mcp-server/dist/tools/card-tools.js.map +1 -0
- package/mcp-server/dist/tools/card.d.ts +8 -0
- package/mcp-server/dist/tools/card.d.ts.map +1 -0
- package/mcp-server/dist/tools/card.js +16 -0
- package/mcp-server/dist/tools/card.js.map +1 -0
- package/mcp-server/dist/tools/category.d.ts +32 -0
- package/mcp-server/dist/tools/category.d.ts.map +1 -0
- package/mcp-server/dist/tools/category.js +290 -0
- package/mcp-server/dist/tools/category.js.map +1 -0
- package/mcp-server/dist/tools/choice.d.ts +160 -0
- package/mcp-server/dist/tools/choice.d.ts.map +1 -0
- package/mcp-server/dist/tools/choice.js +80 -0
- package/mcp-server/dist/tools/choice.js.map +1 -0
- package/mcp-server/dist/tools/computer.d.ts +71 -0
- package/mcp-server/dist/tools/computer.d.ts.map +1 -0
- package/mcp-server/dist/tools/computer.js +174 -0
- package/mcp-server/dist/tools/computer.js.map +1 -0
- package/mcp-server/dist/tools/discord-channel.d.ts +44 -0
- package/mcp-server/dist/tools/discord-channel.d.ts.map +1 -0
- package/mcp-server/dist/tools/discord-channel.js +236 -0
- package/mcp-server/dist/tools/discord-channel.js.map +1 -0
- package/mcp-server/dist/tools/discord-guild.d.ts +20 -0
- package/mcp-server/dist/tools/discord-guild.d.ts.map +1 -0
- package/mcp-server/dist/tools/discord-guild.js +138 -0
- package/mcp-server/dist/tools/discord-guild.js.map +1 -0
- package/mcp-server/dist/tools/discord-member.d.ts +26 -0
- package/mcp-server/dist/tools/discord-member.d.ts.map +1 -0
- package/mcp-server/dist/tools/discord-member.js +122 -0
- package/mcp-server/dist/tools/discord-member.js.map +1 -0
- package/mcp-server/dist/tools/discord-message.d.ts +36 -0
- package/mcp-server/dist/tools/discord-message.d.ts.map +1 -0
- package/mcp-server/dist/tools/discord-message.js +184 -0
- package/mcp-server/dist/tools/discord-message.js.map +1 -0
- package/mcp-server/dist/tools/discord-onboarding.d.ts +32 -0
- package/mcp-server/dist/tools/discord-onboarding.d.ts.map +1 -0
- package/mcp-server/dist/tools/discord-onboarding.js +179 -0
- package/mcp-server/dist/tools/discord-onboarding.js.map +1 -0
- package/mcp-server/dist/tools/discord-role.d.ts +34 -0
- package/mcp-server/dist/tools/discord-role.d.ts.map +1 -0
- package/mcp-server/dist/tools/discord-role.js +178 -0
- package/mcp-server/dist/tools/discord-role.js.map +1 -0
- package/mcp-server/dist/tools/discord-thread.d.ts +28 -0
- package/mcp-server/dist/tools/discord-thread.d.ts.map +1 -0
- package/mcp-server/dist/tools/discord-thread.js +88 -0
- package/mcp-server/dist/tools/discord-thread.js.map +1 -0
- package/mcp-server/dist/tools/discord-webhook.d.ts +32 -0
- package/mcp-server/dist/tools/discord-webhook.d.ts.map +1 -0
- package/mcp-server/dist/tools/discord-webhook.js +154 -0
- package/mcp-server/dist/tools/discord-webhook.js.map +1 -0
- package/mcp-server/dist/tools/discord.d.ts +7 -0
- package/mcp-server/dist/tools/discord.d.ts.map +1 -0
- package/mcp-server/dist/tools/discord.js +25 -0
- package/mcp-server/dist/tools/discord.js.map +1 -0
- package/mcp-server/dist/tools/fb-groups.d.ts +98 -0
- package/mcp-server/dist/tools/fb-groups.d.ts.map +1 -0
- package/mcp-server/dist/tools/fb-groups.js +369 -0
- package/mcp-server/dist/tools/fb-groups.js.map +1 -0
- package/mcp-server/dist/tools/forget.d.ts +14 -0
- package/mcp-server/dist/tools/forget.d.ts.map +1 -0
- package/mcp-server/dist/tools/forget.js +26 -0
- package/mcp-server/dist/tools/forget.js.map +1 -0
- package/mcp-server/dist/tools/git-tools.d.ts +24 -0
- package/mcp-server/dist/tools/git-tools.d.ts.map +1 -0
- package/mcp-server/dist/tools/git-tools.js +107 -0
- package/mcp-server/dist/tools/git-tools.js.map +1 -0
- package/mcp-server/dist/tools/git.d.ts +7 -0
- package/mcp-server/dist/tools/git.d.ts.map +1 -0
- package/mcp-server/dist/tools/git.js +11 -0
- package/mcp-server/dist/tools/git.js.map +1 -0
- package/mcp-server/dist/tools/gsc/experience.d.ts +135 -0
- package/mcp-server/dist/tools/gsc/experience.d.ts.map +1 -0
- package/mcp-server/dist/tools/gsc/experience.js +351 -0
- package/mcp-server/dist/tools/gsc/experience.js.map +1 -0
- package/mcp-server/dist/tools/gsc/helpers.d.ts +78 -0
- package/mcp-server/dist/tools/gsc/helpers.d.ts.map +1 -0
- package/mcp-server/dist/tools/gsc/helpers.js +258 -0
- package/mcp-server/dist/tools/gsc/helpers.js.map +1 -0
- package/mcp-server/dist/tools/gsc/indexing.d.ts +121 -0
- package/mcp-server/dist/tools/gsc/indexing.d.ts.map +1 -0
- package/mcp-server/dist/tools/gsc/indexing.js +357 -0
- package/mcp-server/dist/tools/gsc/indexing.js.map +1 -0
- package/mcp-server/dist/tools/gsc/inspect.d.ts +78 -0
- package/mcp-server/dist/tools/gsc/inspect.d.ts.map +1 -0
- package/mcp-server/dist/tools/gsc/inspect.js +321 -0
- package/mcp-server/dist/tools/gsc/inspect.js.map +1 -0
- package/mcp-server/dist/tools/gsc/navigate.d.ts +44 -0
- package/mcp-server/dist/tools/gsc/navigate.d.ts.map +1 -0
- package/mcp-server/dist/tools/gsc/navigate.js +197 -0
- package/mcp-server/dist/tools/gsc/navigate.js.map +1 -0
- package/mcp-server/dist/tools/gsc/performance.d.ts +84 -0
- package/mcp-server/dist/tools/gsc/performance.d.ts.map +1 -0
- package/mcp-server/dist/tools/gsc/performance.js +274 -0
- package/mcp-server/dist/tools/gsc/performance.js.map +1 -0
- package/mcp-server/dist/tools/gsc/settings.d.ts +153 -0
- package/mcp-server/dist/tools/gsc/settings.d.ts.map +1 -0
- package/mcp-server/dist/tools/gsc/settings.js +425 -0
- package/mcp-server/dist/tools/gsc/settings.js.map +1 -0
- package/mcp-server/dist/tools/gsc.d.ts +7 -0
- package/mcp-server/dist/tools/gsc.d.ts.map +1 -0
- package/mcp-server/dist/tools/gsc.js +51 -0
- package/mcp-server/dist/tools/gsc.js.map +1 -0
- package/mcp-server/dist/tools/image-tools.d.ts +24 -0
- package/mcp-server/dist/tools/image-tools.d.ts.map +1 -0
- package/mcp-server/dist/tools/image-tools.js +80 -0
- package/mcp-server/dist/tools/image-tools.js.map +1 -0
- package/mcp-server/dist/tools/image.d.ts +10 -0
- package/mcp-server/dist/tools/image.d.ts.map +1 -0
- package/mcp-server/dist/tools/image.js +14 -0
- package/mcp-server/dist/tools/image.js.map +1 -0
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +97 -0
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +1 -0
- package/mcp-server/dist/tools/leonardo-browser-tools.js +228 -0
- package/mcp-server/dist/tools/leonardo-browser-tools.js.map +1 -0
- package/mcp-server/dist/tools/leonardo.d.ts +13 -0
- package/mcp-server/dist/tools/leonardo.d.ts.map +1 -0
- package/mcp-server/dist/tools/leonardo.js +21 -0
- package/mcp-server/dist/tools/leonardo.js.map +1 -0
- package/mcp-server/dist/tools/loop.d.ts +30 -0
- package/mcp-server/dist/tools/loop.d.ts.map +1 -0
- package/mcp-server/dist/tools/loop.js +401 -0
- package/mcp-server/dist/tools/loop.js.map +1 -0
- package/mcp-server/dist/tools/memories.d.ts +56 -0
- package/mcp-server/dist/tools/memories.d.ts.map +1 -0
- package/mcp-server/dist/tools/memories.js +171 -0
- package/mcp-server/dist/tools/memories.js.map +1 -0
- package/mcp-server/dist/tools/morelogin.d.ts +24 -0
- package/mcp-server/dist/tools/morelogin.d.ts.map +1 -0
- package/mcp-server/dist/tools/morelogin.js +79 -0
- package/mcp-server/dist/tools/morelogin.js.map +1 -0
- package/mcp-server/dist/tools/profile.d.ts +17 -0
- package/mcp-server/dist/tools/profile.d.ts.map +1 -0
- package/mcp-server/dist/tools/profile.js +114 -0
- package/mcp-server/dist/tools/profile.js.map +1 -0
- package/mcp-server/dist/tools/recall.d.ts +71 -0
- package/mcp-server/dist/tools/recall.d.ts.map +1 -0
- package/mcp-server/dist/tools/recall.js +147 -0
- package/mcp-server/dist/tools/recall.js.map +1 -0
- package/mcp-server/dist/tools/reflect.d.ts +56 -0
- package/mcp-server/dist/tools/reflect.d.ts.map +1 -0
- package/mcp-server/dist/tools/reflect.js +157 -0
- package/mcp-server/dist/tools/reflect.js.map +1 -0
- package/mcp-server/dist/tools/remember.d.ts +62 -0
- package/mcp-server/dist/tools/remember.d.ts.map +1 -0
- package/mcp-server/dist/tools/remember.js +201 -0
- package/mcp-server/dist/tools/remember.js.map +1 -0
- package/mcp-server/dist/tools/response.d.ts +23 -0
- package/mcp-server/dist/tools/response.d.ts.map +1 -0
- package/mcp-server/dist/tools/response.js +24 -0
- package/mcp-server/dist/tools/response.js.map +1 -0
- package/mcp-server/dist/tools/restore.d.ts +14 -0
- package/mcp-server/dist/tools/restore.d.ts.map +1 -0
- package/mcp-server/dist/tools/restore.js +23 -0
- package/mcp-server/dist/tools/restore.js.map +1 -0
- package/mcp-server/dist/tools/style-guide-tools.d.ts +51 -0
- package/mcp-server/dist/tools/style-guide-tools.d.ts.map +1 -0
- package/mcp-server/dist/tools/style-guide-tools.js +231 -0
- package/mcp-server/dist/tools/style-guide-tools.js.map +1 -0
- package/mcp-server/dist/tools/style-guide.d.ts +8 -0
- package/mcp-server/dist/tools/style-guide.d.ts.map +1 -0
- package/mcp-server/dist/tools/style-guide.js +12 -0
- package/mcp-server/dist/tools/style-guide.js.map +1 -0
- package/mcp-server/dist/tools/sync.d.ts +20 -0
- package/mcp-server/dist/tools/sync.d.ts.map +1 -0
- package/mcp-server/dist/tools/sync.js +156 -0
- package/mcp-server/dist/tools/sync.js.map +1 -0
- package/mcp-server/dist/tools/tictactoe-tools.d.ts +18 -0
- package/mcp-server/dist/tools/tictactoe-tools.d.ts.map +1 -0
- package/mcp-server/dist/tools/tictactoe-tools.js +78 -0
- package/mcp-server/dist/tools/tictactoe-tools.js.map +1 -0
- package/mcp-server/dist/tools/tictactoe.d.ts +7 -0
- package/mcp-server/dist/tools/tictactoe.d.ts.map +1 -0
- package/mcp-server/dist/tools/tictactoe.js +11 -0
- package/mcp-server/dist/tools/tictactoe.js.map +1 -0
- package/mcp-server/dist/tools/utils.d.ts +19 -0
- package/mcp-server/dist/tools/utils.d.ts.map +1 -0
- package/mcp-server/dist/tools/utils.js +54 -0
- package/mcp-server/dist/tools/utils.js.map +1 -0
- package/mcp-server/dist/tools/whiteboard-format.d.ts +88 -0
- package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -0
- package/mcp-server/dist/tools/whiteboard-format.js +337 -0
- package/mcp-server/dist/tools/whiteboard-format.js.map +1 -0
- package/mcp-server/dist/tools/whiteboard-tools.d.ts +326 -0
- package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -0
- package/mcp-server/dist/tools/whiteboard-tools.js +222 -0
- package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -0
- package/mcp-server/dist/tools/whiteboard.d.ts +8 -0
- package/mcp-server/dist/tools/whiteboard.d.ts.map +1 -0
- package/mcp-server/dist/tools/whiteboard.js +16 -0
- package/mcp-server/dist/tools/whiteboard.js.map +1 -0
- package/mcp-server/dist/tools/youtube/analytics.d.ts +46 -0
- package/mcp-server/dist/tools/youtube/analytics.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/analytics.js +83 -0
- package/mcp-server/dist/tools/youtube/analytics.js.map +1 -0
- package/mcp-server/dist/tools/youtube/dedup.d.ts +35 -0
- package/mcp-server/dist/tools/youtube/dedup.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/dedup.js +56 -0
- package/mcp-server/dist/tools/youtube/dedup.js.map +1 -0
- package/mcp-server/dist/tools/youtube/download.d.ts +31 -0
- package/mcp-server/dist/tools/youtube/download.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/download.js +30 -0
- package/mcp-server/dist/tools/youtube/download.js.map +1 -0
- package/mcp-server/dist/tools/youtube/helpers.d.ts +66 -0
- package/mcp-server/dist/tools/youtube/helpers.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/helpers.js +143 -0
- package/mcp-server/dist/tools/youtube/helpers.js.map +1 -0
- package/mcp-server/dist/tools/youtube/media.d.ts +43 -0
- package/mcp-server/dist/tools/youtube/media.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/media.js +97 -0
- package/mcp-server/dist/tools/youtube/media.js.map +1 -0
- package/mcp-server/dist/tools/youtube/metadata.d.ts +33 -0
- package/mcp-server/dist/tools/youtube/metadata.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/metadata.js +106 -0
- package/mcp-server/dist/tools/youtube/metadata.js.map +1 -0
- package/mcp-server/dist/tools/youtube/navigate.d.ts +30 -0
- package/mcp-server/dist/tools/youtube/navigate.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/navigate.js +71 -0
- package/mcp-server/dist/tools/youtube/navigate.js.map +1 -0
- package/mcp-server/dist/tools/youtube/playlist.d.ts +29 -0
- package/mcp-server/dist/tools/youtube/playlist.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/playlist.js +128 -0
- package/mcp-server/dist/tools/youtube/playlist.js.map +1 -0
- package/mcp-server/dist/tools/youtube/schedule.d.ts +31 -0
- package/mcp-server/dist/tools/youtube/schedule.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/schedule.js +147 -0
- package/mcp-server/dist/tools/youtube/schedule.js.map +1 -0
- package/mcp-server/dist/tools/youtube/source.d.ts +36 -0
- package/mcp-server/dist/tools/youtube/source.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/source.js +85 -0
- package/mcp-server/dist/tools/youtube/source.js.map +1 -0
- package/mcp-server/dist/tools/youtube/upload.d.ts +53 -0
- package/mcp-server/dist/tools/youtube/upload.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube/upload.js +255 -0
- package/mcp-server/dist/tools/youtube/upload.js.map +1 -0
- package/mcp-server/dist/tools/youtube.d.ts +12 -0
- package/mcp-server/dist/tools/youtube.d.ts.map +1 -0
- package/mcp-server/dist/tools/youtube.js +38 -0
- package/mcp-server/dist/tools/youtube.js.map +1 -0
- package/mcp-server/dist/tui.d.ts +3 -0
- package/mcp-server/dist/tui.d.ts.map +1 -0
- package/mcp-server/dist/tui.js +806 -0
- package/mcp-server/dist/tui.js.map +1 -0
- package/mcp-server/dist/types.d.ts +77 -0
- package/mcp-server/dist/types.d.ts.map +1 -0
- package/mcp-server/dist/types.js +2 -0
- package/mcp-server/dist/types.js.map +1 -0
- package/mcp-server/package-lock.json +4798 -0
- package/mcp-server/package.json +55 -38
- package/mcp-server/run.mjs +12 -2
- package/mcp-server/src/config.ts +48 -3
- package/mcp-server/src/http.ts +296 -93
- package/mcp-server/src/index.ts +546 -203
- package/mcp-server/src/preload-http.ts +19 -18
- package/mcp-server/src/preload.ts +19 -18
- package/mcp-server/src/scripts/setup-embeddings.ts +9 -0
- package/mcp-server/src/services/assistant-judgments.ts +157 -0
- package/mcp-server/src/services/browser-assist-gate.ts +383 -0
- package/mcp-server/src/services/browser-assist.ts +267 -0
- package/mcp-server/src/services/browser-bench.ts +477 -0
- package/mcp-server/src/services/browser-judgments.ts +414 -0
- package/mcp-server/src/services/browser-risk.ts +484 -0
- package/mcp-server/src/services/categories.ts +36 -19
- package/mcp-server/src/services/codex-config-heal.ts +403 -0
- package/mcp-server/src/services/desktop-assist-gate.ts +251 -0
- package/mcp-server/src/services/desktop-assist.ts +308 -0
- package/mcp-server/src/services/desktop-bench.ts +372 -0
- package/mcp-server/src/services/desktop-client.ts +76 -0
- package/mcp-server/src/services/desktop-judgments.ts +218 -0
- package/mcp-server/src/services/desktop-risk.ts +743 -0
- package/mcp-server/src/services/edit-stale.ts +299 -0
- package/mcp-server/src/services/embedding-service.ts +108 -0
- package/mcp-server/src/services/embedding-worker.ts +46 -0
- package/mcp-server/src/services/fb-regions.ts +221 -0
- package/mcp-server/src/services/file-checksums.ts +26 -9
- package/mcp-server/src/services/file-excerpt.ts +59 -0
- package/mcp-server/src/services/identity.ts +291 -0
- package/mcp-server/src/services/local-embeddings.ts +2 -77
- package/mcp-server/src/services/memory-client.ts +23 -0
- package/mcp-server/src/services/memory-judge-backfill.ts +462 -0
- package/mcp-server/src/services/memory-judgments.ts +901 -0
- package/mcp-server/src/services/memory-maintenance.ts +360 -0
- package/mcp-server/src/services/memory-retrieval.ts +349 -0
- package/mcp-server/src/services/memory-schema.ts +280 -0
- package/mcp-server/src/services/memory-sessions.ts +87 -0
- package/mcp-server/src/services/memory-triage.ts +182 -0
- package/mcp-server/src/services/memory-verification.ts +68 -0
- package/mcp-server/src/services/memory-writer.ts +125 -0
- package/mcp-server/src/services/neural-interface.ts +1217 -73
- package/mcp-server/src/services/profiles.ts +428 -0
- package/mcp-server/src/services/secret-gate.ts +52 -0
- package/mcp-server/src/services/server-instructions.ts +122 -0
- package/mcp-server/src/services/sqlite.ts +1456 -823
- package/mcp-server/src/services/typesafe-bench.ts +247 -0
- package/mcp-server/src/services/typesafe-config.ts +790 -0
- package/mcp-server/src/services/typesafe.ts +390 -0
- package/mcp-server/src/services/vector-cache.ts +255 -0
- package/mcp-server/src/services/whiteboard-geometry.ts +711 -0
- package/mcp-server/src/tools/agents.ts +539 -0
- package/mcp-server/src/tools/bluesky.ts +1186 -0
- package/mcp-server/src/tools/browser-advanced.ts +15 -6
- package/mcp-server/src/tools/browser-batch.ts +178 -0
- package/mcp-server/src/tools/browser-cheatsheet.ts +155 -0
- package/mcp-server/src/tools/browser-interact.ts +362 -255
- package/mcp-server/src/tools/browser-navigate.ts +164 -77
- package/mcp-server/src/tools/browser-observe.ts +2222 -1330
- package/mcp-server/src/tools/browser.ts +181 -107
- package/mcp-server/src/tools/card.ts +7 -5
- package/mcp-server/src/tools/choice.ts +103 -0
- package/mcp-server/src/tools/computer.ts +190 -0
- package/mcp-server/src/tools/discord.ts +10 -23
- package/mcp-server/src/tools/fb-groups.ts +387 -0
- package/mcp-server/src/tools/forget.ts +1 -1
- package/mcp-server/src/tools/git.ts +3 -1
- package/mcp-server/src/tools/gsc/experience.ts +440 -0
- package/mcp-server/src/tools/gsc/helpers.ts +288 -0
- package/mcp-server/src/tools/gsc/indexing.ts +495 -0
- package/mcp-server/src/tools/gsc/inspect.ts +391 -0
- package/mcp-server/src/tools/gsc/navigate.ts +236 -0
- package/mcp-server/src/tools/gsc/performance.ts +352 -0
- package/mcp-server/src/tools/gsc/settings.ts +564 -0
- package/mcp-server/src/tools/gsc.ts +95 -0
- package/mcp-server/src/tools/image.ts +3 -1
- package/mcp-server/src/tools/leonardo-browser-tools.ts +47 -37
- package/mcp-server/src/tools/leonardo.ts +7 -5
- package/mcp-server/src/tools/loop.ts +118 -25
- package/mcp-server/src/tools/memories.ts +65 -5
- package/mcp-server/src/tools/morelogin.ts +81 -0
- package/mcp-server/src/tools/profile.ts +122 -0
- package/mcp-server/src/tools/recall.ts +105 -261
- package/mcp-server/src/tools/reflect.ts +171 -145
- package/mcp-server/src/tools/remember.ts +223 -115
- package/mcp-server/src/tools/style-guide-tools.ts +250 -0
- package/mcp-server/src/tools/style-guide.ts +16 -0
- package/mcp-server/src/tools/sync.ts +66 -9
- package/mcp-server/src/tools/tictactoe.ts +3 -1
- package/mcp-server/src/tools/utils.ts +22 -0
- package/mcp-server/src/tools/whiteboard-format.ts +394 -0
- package/mcp-server/src/tools/whiteboard-tools.ts +191 -183
- package/mcp-server/src/tools/whiteboard.ts +7 -5
- package/mcp-server/src/tools/youtube/analytics.ts +106 -0
- package/mcp-server/src/tools/youtube/dedup.ts +57 -0
- package/mcp-server/src/tools/youtube/download.ts +41 -0
- package/mcp-server/src/tools/youtube/helpers.ts +183 -0
- package/mcp-server/src/tools/youtube/media.ts +109 -0
- package/mcp-server/src/tools/youtube/metadata.ts +112 -0
- package/mcp-server/src/tools/youtube/navigate.ts +81 -0
- package/mcp-server/src/tools/youtube/playlist.ts +134 -0
- package/mcp-server/src/tools/youtube/schedule.ts +158 -0
- package/mcp-server/src/tools/youtube/source.ts +101 -0
- package/mcp-server/src/tools/youtube/upload.ts +296 -0
- package/mcp-server/src/tools/youtube.ts +47 -0
- package/mcp-server/src/tui.ts +8 -9
- package/neural-interface/games/TicTacToe/1.svg +1 -0
- package/neural-interface/games/TicTacToe/2.svg +1 -0
- package/neural-interface/games/TicTacToe/3.svg +1 -0
- package/neural-interface/games/TicTacToe/4.svg +1 -0
- package/neural-interface/games/TicTacToe/5.svg +1 -0
- package/neural-interface/games/TicTacToe/6.svg +1 -0
- package/neural-interface/games/TicTacToe/7.svg +1 -0
- package/neural-interface/games/TicTacToe/8.svg +1 -0
- package/neural-interface/games/TicTacToe/9.svg +1 -0
- package/neural-interface/games/TicTacToe/Board.svg +1 -0
- package/neural-interface/games/TicTacToe/Circle.svg +1 -0
- package/neural-interface/games/TicTacToe/Cross.svg +1 -0
- package/neural-interface/i18n/en.json +6983 -0
- package/neural-interface/i18n/pt-BR.json +6987 -0
- package/neural-interface/lib/assistant-api.js +1005 -0
- package/neural-interface/lib/assistant-attachments.js +121 -0
- package/neural-interface/lib/assistant-brains/claude.js +207 -0
- package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +43 -0
- package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +56 -0
- package/neural-interface/lib/assistant-brains/codex.js +213 -0
- package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +47 -0
- package/neural-interface/lib/assistant-brains/opencode-route-gate.js +62 -0
- package/neural-interface/lib/assistant-brains/opencode.js +320 -0
- package/neural-interface/lib/assistant-budget.js +318 -0
- package/neural-interface/lib/assistant-catalog.js +731 -0
- package/neural-interface/lib/assistant-clarify.js +664 -0
- package/neural-interface/lib/assistant-config.js +232 -0
- package/neural-interface/lib/assistant-dispatch.js +2744 -0
- package/neural-interface/lib/assistant-envelope.js +579 -0
- package/neural-interface/lib/assistant-evidence.js +236 -0
- package/neural-interface/lib/assistant-hidden-models.js +272 -0
- package/neural-interface/lib/assistant-jev.js +117 -0
- package/neural-interface/lib/assistant-judgments.js +111 -0
- package/neural-interface/lib/assistant-media.js +335 -0
- package/neural-interface/lib/assistant-memory.js +398 -0
- package/neural-interface/lib/assistant-persona.js +444 -0
- package/neural-interface/lib/assistant-plan-permissions.js +448 -0
- package/neural-interface/lib/assistant-playbooks/design.md +87 -0
- package/neural-interface/lib/assistant-playbooks.js +72 -0
- package/neural-interface/lib/assistant-pricing.js +159 -0
- package/neural-interface/lib/assistant-route-gate-codex.js +163 -0
- package/neural-interface/lib/assistant-route-gate.js +212 -0
- package/neural-interface/lib/assistant-router.js +1324 -0
- package/neural-interface/lib/assistant-runtime.js +3337 -0
- package/neural-interface/lib/assistant-task-prompt.js +472 -0
- package/neural-interface/lib/assistant-usage.js +1688 -0
- package/neural-interface/lib/augmented-path.js +50 -0
- package/neural-interface/lib/automation-storage-migration.js +54 -0
- package/neural-interface/lib/backup-service.js +851 -0
- package/neural-interface/lib/backup-zip-reader.js +262 -0
- package/neural-interface/lib/browser-assist-api.js +41 -0
- package/neural-interface/lib/browser-console.js +176 -0
- package/neural-interface/lib/browser-execution.js +241 -0
- package/neural-interface/lib/browser-extraction.js +191 -0
- package/neural-interface/lib/browser-screenshot.js +399 -0
- package/neural-interface/lib/browser-semantic-context.js +639 -0
- package/neural-interface/lib/browser-snapshots.js +192 -0
- package/neural-interface/lib/browser-tab-recovery.js +119 -0
- package/neural-interface/lib/browser-targets.js +70 -0
- package/neural-interface/lib/browser-tool-policy.js +926 -0
- package/neural-interface/lib/claude-accounts.js +230 -0
- package/neural-interface/lib/claude-agent-bridge.js +3296 -0
- package/neural-interface/lib/claude-bypass-policy.js +99 -0
- package/neural-interface/lib/claude-history.js +429 -0
- package/neural-interface/lib/claude-model-catalog.js +483 -0
- package/neural-interface/lib/claude-panel-requests.js +165 -0
- package/neural-interface/lib/claude-panel-session.js +272 -0
- package/neural-interface/lib/claude-permission-rules.js +153 -0
- package/neural-interface/lib/claude-session-cleanup.js +71 -0
- package/neural-interface/lib/claude-session-list.js +82 -0
- package/neural-interface/lib/claude-session-ops.js +140 -0
- package/neural-interface/lib/claude-settings-view.js +51 -0
- package/neural-interface/lib/claude-skin-connect.js +79 -0
- package/neural-interface/lib/claude-stall-policy.js +7 -0
- package/neural-interface/lib/claude-temporary.js +435 -0
- package/neural-interface/lib/cli-update-planner.js +312 -0
- package/neural-interface/lib/codex-capabilities.d.ts +41 -0
- package/neural-interface/lib/codex-capabilities.js +148 -0
- package/neural-interface/lib/codex-collaboration-mode.js +17 -0
- package/neural-interface/lib/codex-compat-rpc.js +241 -0
- package/neural-interface/lib/codex-mcp-approvals.js +56 -0
- package/neural-interface/lib/codex-mcp-apps.js +47 -0
- package/neural-interface/lib/codex-model-context.js +202 -0
- package/neural-interface/lib/codex-plan-store.js +71 -0
- package/neural-interface/lib/codex-request-journal.js +242 -0
- package/neural-interface/lib/codex-runtime-path.js +213 -0
- package/neural-interface/lib/codex-session-catalog.js +231 -0
- package/neural-interface/lib/codex-session-settings.js +46 -0
- package/neural-interface/lib/codex-sidepanel-permissions.js +110 -0
- package/neural-interface/lib/codex-thread-history.js +165 -0
- package/neural-interface/lib/codex-user-verification.js +34 -0
- package/neural-interface/lib/codex-writer-lifecycle.js +152 -0
- package/neural-interface/lib/confined-fs.js +256 -0
- package/neural-interface/lib/db.js +922 -0
- package/neural-interface/lib/design-md.js +9 -0
- package/neural-interface/lib/desktop/api.js +92 -0
- package/neural-interface/lib/desktop/audit.js +62 -0
- package/neural-interface/lib/desktop/build.js +423 -0
- package/neural-interface/lib/desktop/config.js +606 -0
- package/neural-interface/lib/desktop/coords.js +76 -0
- package/neural-interface/lib/desktop/fake-helper.js +1192 -0
- package/neural-interface/lib/desktop/frames.js +77 -0
- package/neural-interface/lib/desktop/grants.js +84 -0
- package/neural-interface/lib/desktop/guards.js +170 -0
- package/neural-interface/lib/desktop/helper/SynabunDesktop.swift +3056 -0
- package/neural-interface/lib/desktop/lease.js +51 -0
- package/neural-interface/lib/desktop/manager.js +545 -0
- package/neural-interface/lib/desktop/press-contexts.js +103 -0
- package/neural-interface/lib/desktop/protocol.js +495 -0
- package/neural-interface/lib/desktop/service.js +1202 -0
- package/neural-interface/lib/effort-levels.js +148 -0
- package/neural-interface/lib/event-loop-monitor.js +67 -0
- package/neural-interface/lib/exec-loop-command.js +209 -0
- package/neural-interface/lib/folder-picker.ps1 +77 -0
- package/neural-interface/lib/http-guards.js +287 -0
- package/neural-interface/lib/jsonl-lines.js +94 -0
- package/neural-interface/lib/loop-logger.js +127 -0
- package/neural-interface/lib/mcp-client-config.js +133 -0
- package/neural-interface/lib/mcp-installer.js +487 -0
- package/neural-interface/lib/mcp-profile-refresh-coordinator.js +78 -0
- package/neural-interface/lib/mcp-profile-servers.js +120 -0
- package/neural-interface/lib/memo-cache.js +84 -0
- package/neural-interface/lib/memory-api.js +758 -0
- package/neural-interface/lib/memory-map-api.js +1150 -0
- package/neural-interface/lib/memory-map-layout.js +872 -0
- package/neural-interface/lib/memory-map-worker.js +165 -0
- package/neural-interface/lib/memory-session-capture.js +81 -0
- package/neural-interface/lib/memory-timers.js +62 -0
- package/neural-interface/lib/morelogin.js +301 -0
- package/neural-interface/lib/native-binary-runtime.js +650 -0
- package/neural-interface/lib/native-loop-goal.js +33 -0
- package/neural-interface/lib/native-loop-providers.js +1016 -0
- package/neural-interface/lib/native-loop-runtime.js +747 -0
- package/neural-interface/lib/opencode-hidden-models.js +113 -0
- package/neural-interface/lib/opencode-history.js +253 -0
- package/neural-interface/lib/opencode-runtime-config.js +58 -0
- package/neural-interface/lib/opencode-v2-client.js +486 -0
- package/neural-interface/lib/opencode-v2-ws-requests.js +955 -0
- package/neural-interface/lib/path-confine.js +213 -0
- package/neural-interface/lib/plugin-installer.js +264 -0
- package/neural-interface/lib/project-storage.js +766 -0
- package/neural-interface/lib/pty-host/core.js +603 -0
- package/neural-interface/lib/pty-host/flow.js +43 -0
- package/neural-interface/lib/pty-host/host.js +47 -0
- package/neural-interface/lib/pty-host/manager.js +360 -0
- package/neural-interface/lib/pty-host/protocol.js +81 -0
- package/neural-interface/lib/pty-host/snapshot.js +133 -0
- package/neural-interface/lib/remote-policy.js +582 -0
- package/neural-interface/lib/rulesets/api.js +175 -0
- package/neural-interface/lib/rulesets/fs-safe.js +245 -0
- package/neural-interface/lib/rulesets/installer.js +1453 -0
- package/neural-interface/lib/rulesets/json-edit.js +186 -0
- package/neural-interface/lib/rulesets/lock.js +170 -0
- package/neural-interface/lib/rulesets/managed-text.js +314 -0
- package/neural-interface/lib/rulesets/normalise.js +24 -0
- package/neural-interface/lib/rulesets/render.js +84 -0
- package/neural-interface/lib/schedule-launch-intent.js +40 -0
- package/neural-interface/lib/session-cache-builder.js +524 -0
- package/neural-interface/lib/session-chunker.js +344 -0
- package/neural-interface/lib/session-indexer.js +327 -0
- package/neural-interface/lib/session-title-generator.js +227 -0
- package/neural-interface/lib/skill-prompt-bridge.js +11 -0
- package/neural-interface/lib/style-guide/api.js +375 -0
- package/neural-interface/lib/style-guide/color.js +352 -0
- package/neural-interface/lib/style-guide/export-css.js +99 -0
- package/neural-interface/lib/style-guide/export-dtcg.js +209 -0
- package/neural-interface/lib/style-guide/export-tailwind.js +102 -0
- package/neural-interface/lib/style-guide/fonts.json +227 -0
- package/neural-interface/lib/style-guide/import.js +1268 -0
- package/neural-interface/lib/style-guide/pointers.js +103 -0
- package/neural-interface/lib/style-guide/presets.js +232 -0
- package/neural-interface/lib/style-guide/render-design-md.js +319 -0
- package/neural-interface/lib/style-guide/schema.js +848 -0
- package/neural-interface/lib/style-guide/security.js +43 -0
- package/neural-interface/lib/style-guide/store.js +491 -0
- package/neural-interface/lib/style-guide/summary.js +106 -0
- package/neural-interface/lib/style-guide/tokens.js +170 -0
- package/neural-interface/lib/synabun-update-plan.js +305 -0
- package/neural-interface/lib/synabun-version.js +179 -0
- package/neural-interface/lib/system-restore.js +99 -0
- package/neural-interface/lib/terminal-env.js +86 -0
- package/neural-interface/lib/ui-blob-store.js +106 -0
- package/neural-interface/lib/vector-cache.js +2 -0
- package/neural-interface/lib/virtual-socket.js +60 -0
- package/neural-interface/lib/whatsapp/api.js +146 -0
- package/neural-interface/lib/whatsapp/auth-store.js +389 -0
- package/neural-interface/lib/whatsapp/baileys-adapter.js +457 -0
- package/neural-interface/lib/whatsapp/brain.js +128 -0
- package/neural-interface/lib/whatsapp/bridge.js +1499 -0
- package/neural-interface/lib/whatsapp/cards.js +519 -0
- package/neural-interface/lib/whatsapp/commands.js +92 -0
- package/neural-interface/lib/whatsapp/config.js +291 -0
- package/neural-interface/lib/whatsapp/connector/entry.mjs +25 -0
- package/neural-interface/lib/whatsapp/connector/manifest.json +6 -0
- package/neural-interface/lib/whatsapp/connector/npm-shrinkwrap.json +717 -0
- package/neural-interface/lib/whatsapp/connector/package.json +8 -0
- package/neural-interface/lib/whatsapp/fake-baileys.js +444 -0
- package/neural-interface/lib/whatsapp/format.js +552 -0
- package/neural-interface/lib/whatsapp/host-core.js +1225 -0
- package/neural-interface/lib/whatsapp/host.js +119 -0
- package/neural-interface/lib/whatsapp/identity.js +288 -0
- package/neural-interface/lib/whatsapp/inbound.js +149 -0
- package/neural-interface/lib/whatsapp/installer.js +562 -0
- package/neural-interface/lib/whatsapp/manager.js +638 -0
- package/neural-interface/lib/whatsapp/paths.js +81 -0
- package/neural-interface/lib/whatsapp/protocol.js +327 -0
- package/neural-interface/lib/whatsapp/qr-svg.js +57 -0
- package/neural-interface/lib/whatsapp/redact.js +130 -0
- package/neural-interface/lib/whatsapp/service.js +1305 -0
- package/neural-interface/lib/whatsapp/vendor/qrcodegen.js +848 -0
- package/neural-interface/package-lock.json +4682 -0
- package/neural-interface/package.json +58 -27
- package/neural-interface/public/apple-touch-icon.png +0 -0
- package/neural-interface/public/category-logos/synabun.png +0 -0
- package/neural-interface/public/claude.svg +1 -0
- package/neural-interface/public/favicon-16x16.png +0 -0
- package/neural-interface/public/favicon-32x32.png +0 -0
- package/neural-interface/public/icon-192.png +0 -0
- package/neural-interface/public/icon-512.png +0 -0
- package/neural-interface/public/index.html +32 -182
- package/neural-interface/public/index2d.html +2 -2
- package/neural-interface/public/logo-synabun.png +0 -0
- package/neural-interface/public/logoHD.png +0 -0
- package/neural-interface/public/mcp.svg +4 -0
- package/neural-interface/public/offline.html +335 -299
- package/neural-interface/public/onboarding.html +692 -155
- package/neural-interface/public/opencode-logo-dark-square.svg +1 -0
- package/neural-interface/public/shared/agent-runtime-options.js +596 -0
- package/neural-interface/public/shared/api.js +339 -28
- package/neural-interface/public/shared/assistant/asst-accounts.js +318 -0
- package/neural-interface/public/shared/assistant/asst-agents-dock.js +296 -0
- package/neural-interface/public/shared/assistant/asst-api.js +270 -0
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +744 -0
- package/neural-interface/public/shared/assistant/asst-budget.js +333 -0
- package/neural-interface/public/shared/assistant/asst-composer.js +656 -0
- package/neural-interface/public/shared/assistant/asst-computer.js +803 -0
- package/neural-interface/public/shared/assistant/asst-control.js +1018 -0
- package/neural-interface/public/shared/assistant/asst-hosts.js +262 -0
- package/neural-interface/public/shared/assistant/asst-mascot.js +311 -0
- package/neural-interface/public/shared/assistant/asst-menu.js +375 -0
- package/neural-interface/public/shared/assistant/asst-panel.js +1845 -0
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +589 -0
- package/neural-interface/public/shared/assistant/asst-render.js +3296 -0
- package/neural-interface/public/shared/assistant/asst-route.js +1653 -0
- package/neural-interface/public/shared/assistant/asst-roving.js +75 -0
- package/neural-interface/public/shared/assistant/asst-sanitize.js +117 -0
- package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +488 -0
- package/neural-interface/public/shared/assistant/asst-sidepanel.js +675 -0
- package/neural-interface/public/shared/assistant/asst-slash.js +258 -0
- package/neural-interface/public/shared/assistant/asst-state.js +727 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +1684 -0
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +1017 -0
- package/neural-interface/public/shared/assistant/asst-usage.js +444 -0
- package/neural-interface/public/shared/assistant/asst-ws.js +175 -0
- package/neural-interface/public/shared/automation-context.js +75 -0
- package/neural-interface/public/shared/blob-store.js +99 -0
- package/neural-interface/public/shared/cdx/cdx-capabilities.js +118 -0
- package/neural-interface/public/shared/cdx/cdx-cards.js +37 -0
- package/neural-interface/public/shared/cdx/cdx-commands.js +171 -0
- package/neural-interface/public/shared/cdx/cdx-context-menu.js +402 -0
- package/neural-interface/public/shared/cdx/cdx-context-model.js +220 -0
- package/neural-interface/public/shared/cdx/cdx-features.js +408 -0
- package/neural-interface/public/shared/cdx/cdx-icons.js +89 -0
- package/neural-interface/public/shared/cdx/cdx-mcp-app-host.js +414 -0
- package/neural-interface/public/shared/cdx/cdx-mcp-app-proxy.html +6 -0
- package/neural-interface/public/shared/cdx/cdx-mcp-app-proxy.js +56 -0
- package/neural-interface/public/shared/cdx/cdx-mcp-app.js +178 -0
- package/neural-interface/public/shared/cdx/cdx-model-catalog.js +120 -0
- package/neural-interface/public/shared/cdx/cdx-output-model.js +261 -0
- package/neural-interface/public/shared/cdx/cdx-output.js +382 -0
- package/neural-interface/public/shared/cdx/cdx-panel.js +1372 -0
- package/neural-interface/public/shared/cdx/cdx-plan.js +266 -0
- package/neural-interface/public/shared/cdx/cdx-protocol.js +682 -0
- package/neural-interface/public/shared/cdx/cdx-render.js +3381 -0
- package/neural-interface/public/shared/cdx/cdx-requests.js +1136 -0
- package/neural-interface/public/shared/cdx/cdx-styles.js +3251 -0
- package/neural-interface/public/shared/cdx/cdx-tabs.js +7992 -0
- package/neural-interface/public/shared/cdx/cdx-ws.js +363 -0
- package/neural-interface/public/shared/cli-status.js +169 -0
- package/neural-interface/public/shared/constants.js +22 -5
- package/neural-interface/public/shared/cp/cp-agents.js +186 -0
- package/neural-interface/public/shared/cp/cp-bash.js +252 -0
- package/neural-interface/public/shared/cp/cp-compose.js +159 -0
- package/neural-interface/public/shared/cp/cp-context-menu.js +309 -0
- package/neural-interface/public/shared/cp/cp-context-model.js +157 -0
- package/neural-interface/public/shared/cp/cp-context-window.js +80 -0
- package/neural-interface/public/shared/cp/cp-ctx.js +11 -0
- package/neural-interface/public/shared/cp/cp-diff.js +255 -0
- package/neural-interface/public/shared/cp/cp-event-rows.js +637 -0
- package/neural-interface/public/shared/cp/cp-events.js +846 -0
- package/neural-interface/public/shared/cp/cp-markdown.js +104 -0
- package/neural-interface/public/shared/cp/cp-permission-model.js +905 -0
- package/neural-interface/public/shared/cp/cp-permissions.js +626 -0
- package/neural-interface/public/shared/cp/cp-rehydrate.js +113 -0
- package/neural-interface/public/shared/cp/cp-restore.js +224 -0
- package/neural-interface/public/shared/cp/cp-session-model.js +338 -0
- package/neural-interface/public/shared/cp/cp-session-settings.js +254 -0
- package/neural-interface/public/shared/cp/cp-sessions.js +227 -0
- package/neural-interface/public/shared/cp/cp-statusline.js +153 -0
- package/neural-interface/public/shared/cp/cp-styles.js +349 -0
- package/neural-interface/public/shared/cp/cp-tasks-model.js +282 -0
- package/neural-interface/public/shared/cp/cp-tasks.js +107 -0
- package/neural-interface/public/shared/cp/cp-temporary-view.js +56 -0
- package/neural-interface/public/shared/cp/cp-temporary.js +231 -0
- package/neural-interface/public/shared/cp/cp-tool-cards.js +326 -0
- package/neural-interface/public/shared/cp/cp-tool-results.js +618 -0
- package/neural-interface/public/shared/cp/cp-usage-model.js +124 -0
- package/neural-interface/public/shared/graph-activity.js +68 -0
- package/neural-interface/public/shared/html-shell.js +107 -12
- package/neural-interface/public/shared/i18n.js +132 -34
- package/neural-interface/public/shared/node-positions-store.js +44 -0
- package/neural-interface/public/shared/ocp-hidden-models.js +116 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +355 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-autoaccept-button.js +35 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-automation-ownership.js +72 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +280 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +67 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +179 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-changes.js +164 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +725 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +75 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +1204 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-confirm-logic.js +117 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-confirm.js +59 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-context-gauge.js +252 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +478 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +179 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +233 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-icons.js +30 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +1065 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-mention-hints.js +182 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +655 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +2636 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +601 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-profile-inheritance.js +78 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +649 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +35 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +357 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render-logic.js +189 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +1869 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-select.js +42 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +117 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +1714 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +468 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-session-widgets.js +63 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +366 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-settings-link.js +19 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +343 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +746 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +347 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +338 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +3543 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-subagents-logic.js +482 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-tools-logic.js +351 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-tools.js +168 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-variantpicker.js +315 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +545 -0
- package/neural-interface/public/shared/provider-icons.js +30 -0
- package/neural-interface/public/shared/session-title.js +100 -0
- package/neural-interface/public/shared/settings/settings-ia.js +389 -0
- package/neural-interface/public/shared/settings/settings-kit.js +234 -0
- package/neural-interface/public/shared/settings/settings-search.js +463 -0
- package/neural-interface/public/shared/settings/settings-shell.js +570 -0
- package/neural-interface/public/shared/state.js +5 -0
- package/neural-interface/public/shared/storage.js +50 -7
- package/neural-interface/public/shared/styleguide/sg-agents.js +42 -0
- package/neural-interface/public/shared/styleguide/sg-brand.js +4 -0
- package/neural-interface/public/shared/styleguide/sg-color-client.js +388 -0
- package/neural-interface/public/shared/styleguide/sg-colors.js +148 -0
- package/neural-interface/public/shared/styleguide/sg-components.js +35 -0
- package/neural-interface/public/shared/styleguide/sg-history.js +41 -0
- package/neural-interface/public/shared/styleguide/sg-icons-logo.js +38 -0
- package/neural-interface/public/shared/styleguide/sg-imagery.js +4 -0
- package/neural-interface/public/shared/styleguide/sg-import-export.js +47 -0
- package/neural-interface/public/shared/styleguide/sg-kit.js +281 -0
- package/neural-interface/public/shared/styleguide/sg-labels.js +318 -0
- package/neural-interface/public/shared/styleguide/sg-layout.js +4 -0
- package/neural-interface/public/shared/styleguide/sg-motion.js +5 -0
- package/neural-interface/public/shared/styleguide/sg-panel.js +229 -0
- package/neural-interface/public/shared/styleguide/sg-preview.js +138 -0
- package/neural-interface/public/shared/styleguide/sg-rules.js +9 -0
- package/neural-interface/public/shared/styleguide/sg-shape.js +24 -0
- package/neural-interface/public/shared/styleguide/sg-state.js +132 -0
- package/neural-interface/public/shared/styleguide/sg-typography.js +124 -0
- package/neural-interface/public/shared/styles.css +7883 -1155
- package/neural-interface/public/shared/synabun-mascot.js +1625 -0
- package/neural-interface/public/shared/synabun-ticker.js +376 -0
- package/neural-interface/public/shared/term-renderer.js +343 -0
- package/neural-interface/public/shared/ui-assistant-panel.js +10 -0
- package/neural-interface/public/shared/ui-assistant.js +77 -0
- package/neural-interface/public/shared/ui-automation-studio.js +5105 -3573
- package/neural-interface/public/shared/ui-claude-panel.js +11685 -6333
- package/neural-interface/public/shared/ui-codex-panel.js +12 -0
- package/neural-interface/public/shared/ui-cost-widget.js +55 -34
- package/neural-interface/public/shared/ui-detail.js +77 -14
- package/neural-interface/public/shared/ui-explorer.js +360 -181
- package/neural-interface/public/shared/ui-file-explorer.js +485 -107
- package/neural-interface/public/shared/ui-help.js +2 -2
- package/neural-interface/public/shared/ui-image-gallery.js +45 -21
- package/neural-interface/public/shared/ui-judgments.js +1346 -0
- package/neural-interface/public/shared/ui-keybinds.js +3 -2
- package/neural-interface/public/shared/ui-link.js +105 -51
- package/neural-interface/public/shared/ui-loading.js +4 -4
- package/neural-interface/public/shared/ui-memory-maintenance.js +111 -0
- package/neural-interface/public/shared/ui-menubar.js +89 -4
- package/neural-interface/public/shared/ui-native-loop-router-state.js +94 -0
- package/neural-interface/public/shared/ui-native-loop-router.js +493 -0
- package/neural-interface/public/shared/ui-native-window-id.js +7 -0
- package/neural-interface/public/shared/ui-navbar.js +357 -222
- package/neural-interface/public/shared/ui-notifications.js +58 -12
- package/neural-interface/public/shared/ui-opencode-panel-v2.js +17 -0
- package/neural-interface/public/shared/ui-panels.js +15 -7
- package/neural-interface/public/shared/ui-resume.js +823 -653
- package/neural-interface/public/shared/ui-schedule-queue.js +172 -0
- package/neural-interface/public/shared/ui-schedules-studio.js +1882 -0
- package/neural-interface/public/shared/ui-scroll-follow.js +194 -0
- package/neural-interface/public/shared/ui-sessions.js +789 -34
- package/neural-interface/public/shared/ui-settings.js +5793 -2190
- package/neural-interface/public/shared/ui-sidepanel-layout.js +109 -0
- package/neural-interface/public/shared/ui-sidepanel-runtime.js +19 -0
- package/neural-interface/public/shared/ui-sidepanel-session-entry.js +40 -0
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +221 -0
- package/neural-interface/public/shared/ui-sidepanel-state.js +131 -0
- package/neural-interface/public/shared/ui-sidepanel-tray.js +547 -0
- package/neural-interface/public/shared/ui-sidepanel-windows.js +387 -0
- package/neural-interface/public/shared/ui-skills.js +18 -32
- package/neural-interface/public/shared/ui-styleguide.js +35 -0
- package/neural-interface/public/shared/ui-sync.js +87 -0
- package/neural-interface/public/shared/ui-terminal.js +7877 -6385
- package/neural-interface/public/shared/ui-tool-updates.js +292 -0
- package/neural-interface/public/shared/ui-tooltip.js +156 -15
- package/neural-interface/public/shared/ui-tutorial-draw.js +119 -683
- package/neural-interface/public/shared/ui-tutorial-layout.js +135 -0
- package/neural-interface/public/shared/ui-tutorial-steps.js +59 -2209
- package/neural-interface/public/shared/ui-tutorial.css +102 -0
- package/neural-interface/public/shared/ui-tutorial.js +557 -1076
- package/neural-interface/public/shared/ui-update.js +420 -68
- package/neural-interface/public/shared/ui-whatsapp.js +941 -0
- package/neural-interface/public/shared/ui-whiteboard.js +1076 -233
- package/neural-interface/public/shared/ui-workspaces.js +2 -1
- package/neural-interface/public/shared/utils.js +58 -0
- package/neural-interface/public/shared/vterm-buffer.js +15 -5
- package/neural-interface/public/shared/whatsapp/wa-phone.js +65 -0
- package/neural-interface/public/shared/whatsapp/wa-view.js +411 -0
- package/neural-interface/public/sidepanel-session.html +18 -0
- package/neural-interface/public/sw.js +8 -2
- package/neural-interface/public/synabun.png +0 -0
- package/neural-interface/public/variant/2d/graph.js +1707 -1635
- package/neural-interface/public/variant/2d/lasso.js +2 -1
- package/neural-interface/public/variant/2d/layout.js +595 -594
- package/neural-interface/public/variant/2d/main.js +556 -521
- package/neural-interface/public/variant/2d/settings-gfx.js +18 -24
- package/neural-interface/public/variant/3d/main.js +516 -500
- package/neural-interface/public/variant/3d/map-controls.js +144 -0
- package/neural-interface/public/variant/3d/map-data.js +251 -0
- package/neural-interface/public/variant/3d/map-labels.js +241 -0
- package/neural-interface/public/variant/3d/map-pick.js +90 -0
- package/neural-interface/public/variant/3d/map-renderer.js +521 -0
- package/neural-interface/public/variant/3d/map-shaders.js +158 -0
- package/neural-interface/public/variant/3d/map-view.js +618 -0
- package/neural-interface/public/vendor/three/manifest.json +3 -0
- package/neural-interface/public/vendor/three/three-0.169.0.min.js +3844 -0
- package/neural-interface/public/vendor/xterm/manifest.json +3 -0
- package/neural-interface/public/vendor/xterm/xterm-6.0.0.css +285 -0
- package/neural-interface/public/vendor/xterm/xterm-6.0.0.min.js +192 -0
- package/neural-interface/scripts/build-vendor.mjs +64 -0
- package/neural-interface/scripts/codex-protocol-fixture.mjs +83 -0
- package/neural-interface/scripts/rebuild-pty.js +37 -23
- package/neural-interface/scripts/vendor-three-entry.js +24 -0
- package/neural-interface/scripts/vendor-xterm-entry.js +8 -0
- package/neural-interface/server.js +33948 -15000
- package/neural-interface/skins/default/skin.css +90 -0
- package/neural-interface/skins/default/skin.json +8 -0
- package/neural-interface/templates/rulesets/README.md +9 -0
- package/neural-interface/templates/rulesets/claude.md +3 -0
- package/neural-interface/templates/rulesets/codex.md +2 -0
- package/neural-interface/templates/rulesets/coexistence.md +6 -0
- package/neural-interface/templates/rulesets/core.md +26 -0
- package/neural-interface/templates/rulesets/cursor.md +2 -0
- package/neural-interface/templates/rulesets/gemini.md +2 -0
- package/neural-interface/templates/rulesets/legacy-hashes.json +227 -0
- package/neural-interface/templates/rulesets/manifest.json +12 -0
- package/neural-interface/templates/rulesets/opencode.md +2 -0
- package/package.json +119 -53
- package/postinstall.js +125 -26
- package/preuninstall.js +187 -0
- package/scripts/audit-claude-hook-usage.mjs +12 -0
- package/scripts/audit-memory-duplicates.mjs +44 -0
- package/scripts/measure-claude-hook-overhead.mjs +77 -0
- package/scripts/recover-user-config.mjs +254 -0
- package/scripts/restore-data-home-from-backup.mjs +239 -0
- package/setup.js +804 -260
- package/skills/leonardo/SKILL.md +19 -10
- package/skills/leonardo/modules/image-prompter.md +18 -12
- package/skills/leonardo/modules/video-prompter.md +19 -13
- package/skills/synabun/SKILL.md +209 -185
- package/skills/synabun/icon.png +0 -0
- package/skills/synabun/modules/audit.md +380 -374
- package/skills/synabun/modules/changelog.md +15 -6
- package/skills/synabun/modules/idea.md +148 -144
- package/skills/synabun/modules/memorize.md +13 -4
- package/skills/synabun/modules/schedule.md +198 -0
- package/skills/synabun/synabunicon.png +0 -0
- package/updater.cmd +31 -0
- package/updater.mjs +382 -0
- package/updater.sh +29 -0
- package/hooks/claude-code/test-user-learning.mjs +0 -531
- package/neural-interface/public/claude-chat.css +0 -878
- package/neural-interface/public/claude-chat.html +0 -92
- package/neural-interface/public/claude-chat.js +0 -1168
- package/neural-interface/public/index-legacy.html +0 -14677
- package/neural-interface/public/index2d-legacy.html +0 -8193
- package/neural-interface/public/shared/html-term-renderer.js +0 -1022
- package/neural-interface/public/variant/3d/background.js +0 -884
- package/neural-interface/public/variant/3d/camera.js +0 -661
- package/neural-interface/public/variant/3d/gfx.js +0 -116
- package/neural-interface/public/variant/3d/graph.js +0 -2399
- package/neural-interface/public/variant/3d/settings-gfx.js +0 -228
- package/neural-interface/templates/CLAUDE-template.md +0 -211
|
@@ -1,861 +1,1244 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* SynaBun UserPromptSubmit Hook for Claude Code
|
|
5
|
-
*
|
|
6
|
-
* Fires on every user message. Analyzes the prompt against tiered
|
|
7
|
-
* trigger patterns and injects context-aware recall nudges:
|
|
8
|
-
*
|
|
9
|
-
* TIER 1 (MUST recall) — Past work, decisions, explicit memory references
|
|
10
|
-
* TIER 2 (SHOULD recall) — Debugging, architecture, domain-specific knowledge
|
|
11
|
-
* TIER 3 (CONSIDER recall) — New features, similarity, broad technical mentions
|
|
12
|
-
*
|
|
13
|
-
* Conversation recall triggers have highest priority (above all tiers).
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* only when
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
'
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
//
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
`
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
function
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
.
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
*
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
//
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
//
|
|
476
|
-
//
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
if (
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
let
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SynaBun UserPromptSubmit Hook for Claude Code
|
|
5
|
+
*
|
|
6
|
+
* Fires on every user message. Analyzes the prompt against tiered
|
|
7
|
+
* trigger patterns and injects context-aware recall nudges:
|
|
8
|
+
*
|
|
9
|
+
* TIER 1 (MUST recall) — Past work, decisions, explicit memory references
|
|
10
|
+
* TIER 2 (SHOULD recall) — Debugging, architecture, domain-specific knowledge
|
|
11
|
+
* TIER 3 (CONSIDER recall) — New features, similarity, broad technical mentions
|
|
12
|
+
*
|
|
13
|
+
* Conversation recall triggers have highest priority (above all tiers).
|
|
14
|
+
*
|
|
15
|
+
* Jev (TypeSafe, via the Neural Interface) makes these calls when available,
|
|
16
|
+
* in ONE prompt request whose riders are asked only when they matter: whether
|
|
17
|
+
* this prompt starts a new task while edits are unsaved (task boundary),
|
|
18
|
+
* whether it refers to a past session, whether it reveals a working
|
|
19
|
+
* preference. Nudges Jev decided carry a `[Jev]` tag; every missing answer
|
|
20
|
+
* falls back to the regex/counter rule it replaced. The judgment and the
|
|
21
|
+
* ranked auto-recall (surface rerank, relevance floor) run in parallel inside
|
|
22
|
+
* the hook's 3 s budget.
|
|
23
|
+
*
|
|
24
|
+
* System-injected "prompts" (task notifications, cross-session messages,
|
|
25
|
+
* mailbox relays, local-command output, continuation banners) are skipped
|
|
26
|
+
* entirely: no judgment, recall, message count or regex (prompt-origin.mjs).
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { readFileSync, writeFileSync, appendFileSync, existsSync, mkdirSync, renameSync, readdirSync } from 'node:fs';
|
|
30
|
+
import { execSync } from 'node:child_process';
|
|
31
|
+
import { dirname, join } from 'node:path';
|
|
32
|
+
import { fileURLToPath } from 'node:url';
|
|
33
|
+
import { withStateLock, writeJsonAtomic } from './state.mjs';
|
|
34
|
+
import { startTaskTurn } from './task-gate.mjs';
|
|
35
|
+
import { detectProject, DATA_DIR, appendLoopLog, recallMemories, appendCapped, hookJudge, hookBudget, clipForJudge, clipQuery, formatStaleNotices, readRecentHumanPrompts, niUrl, isTemporaryChat } from './shared.mjs';
|
|
36
|
+
import { classifyPrompt, isTrivialPrompt } from './prompt-origin.mjs';
|
|
37
|
+
|
|
38
|
+
// Cross-platform safety: catch uncaught errors and output valid hook JSON
|
|
39
|
+
process.on('uncaughtException', () => { try { process.stdout.write('{}'); } catch {} process.exit(0); });
|
|
40
|
+
process.on('unhandledRejection', () => { try { process.stdout.write('{}'); } catch {} process.exit(0); });
|
|
41
|
+
|
|
42
|
+
// UserPromptSubmit has 3 s. Node startup counts against it.
|
|
43
|
+
const budget = hookBudget(3000);
|
|
44
|
+
|
|
45
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
46
|
+
const HOOK_FEATURES_PATH = join(DATA_DIR, 'hook-features.json');
|
|
47
|
+
const PENDING_REMEMBER_DIR = join(DATA_DIR, 'pending-remember');
|
|
48
|
+
const LOOP_DIR = join(DATA_DIR, 'loop');
|
|
49
|
+
const GREETING_CONFIG_PATH = join(DATA_DIR, 'greeting-config.json');
|
|
50
|
+
|
|
51
|
+
// --- Greeting helpers (moved from session-start.mjs) ---
|
|
52
|
+
|
|
53
|
+
function loadGreetingConfig() {
|
|
54
|
+
try {
|
|
55
|
+
if (!existsSync(GREETING_CONFIG_PATH)) return null;
|
|
56
|
+
return JSON.parse(readFileSync(GREETING_CONFIG_PATH, 'utf-8'));
|
|
57
|
+
} catch { return null; }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getProjectGreetingConfig(config, project) {
|
|
61
|
+
if (!config) return null;
|
|
62
|
+
if (config.projects && config.projects[project]) {
|
|
63
|
+
return { ...config.defaults, ...config.projects[project] };
|
|
64
|
+
}
|
|
65
|
+
if (config.global) {
|
|
66
|
+
return { ...config.defaults, ...config.global };
|
|
67
|
+
}
|
|
68
|
+
return config.defaults || null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getTimeGreeting() {
|
|
72
|
+
const hour = new Date().getHours();
|
|
73
|
+
if (hour >= 5 && hour < 12) return 'Good morning';
|
|
74
|
+
if (hour >= 12 && hour < 17) return 'Good afternoon';
|
|
75
|
+
return 'Good evening';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function getGitBranch(cwd) {
|
|
79
|
+
try {
|
|
80
|
+
return execSync('git rev-parse --abbrev-ref HEAD', {
|
|
81
|
+
cwd,
|
|
82
|
+
encoding: 'utf-8',
|
|
83
|
+
timeout: 2000,
|
|
84
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
85
|
+
}).trim();
|
|
86
|
+
} catch {
|
|
87
|
+
return 'unknown';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function resolveTemplate(template, vars) {
|
|
92
|
+
return template.replace(/\{(\w+)\}/g, (match, key) => {
|
|
93
|
+
return vars[key] !== undefined ? vars[key] : match;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function formatReminders(reminders, prefix) {
|
|
98
|
+
if (!reminders || reminders.length === 0) return '';
|
|
99
|
+
const lines = reminders.map((r) => `- **${r.label}:** \`${r.command}\``);
|
|
100
|
+
return `${prefix}\n${lines.join('\n')}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Build the full greeting directive + boot sequence for message 1.
|
|
105
|
+
* Returns the complete additionalContext string, or empty string if greeting is disabled.
|
|
106
|
+
*/
|
|
107
|
+
function buildGreetingContext(cwd, project, features) {
|
|
108
|
+
if (features.greeting !== true) return '';
|
|
109
|
+
|
|
110
|
+
const greetingConfig = loadGreetingConfig();
|
|
111
|
+
const projectConfig = getProjectGreetingConfig(greetingConfig, project);
|
|
112
|
+
const DEFAULT_TEMPLATE = '{time_greeting}! Working on **{project_label}** (`{branch}` branch). {date}.';
|
|
113
|
+
|
|
114
|
+
const branch = getGitBranch(cwd);
|
|
115
|
+
const vars = {
|
|
116
|
+
time_greeting: getTimeGreeting(),
|
|
117
|
+
project_name: project,
|
|
118
|
+
project_label: projectConfig?.label || project,
|
|
119
|
+
branch,
|
|
120
|
+
date: new Date().toLocaleDateString('en-US', {
|
|
121
|
+
weekday: 'long', year: 'numeric', month: 'long', day: 'numeric',
|
|
122
|
+
}),
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const greetingText = resolveTemplate(
|
|
126
|
+
projectConfig?.greetingTemplate || greetingConfig?.defaults?.greetingTemplate || DEFAULT_TEMPLATE,
|
|
127
|
+
vars,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const showReminders = projectConfig?.showReminders ?? greetingConfig?.defaults?.showReminders ?? false;
|
|
131
|
+
const remindersText = showReminders
|
|
132
|
+
? formatReminders(
|
|
133
|
+
projectConfig?.reminders,
|
|
134
|
+
projectConfig?.reminderPrefix || greetingConfig?.defaults?.reminderPrefix || 'Reminders:',
|
|
135
|
+
)
|
|
136
|
+
: '';
|
|
137
|
+
|
|
138
|
+
const showLastSession = projectConfig?.showLastSession ?? greetingConfig?.defaults?.showLastSession ?? false;
|
|
139
|
+
|
|
140
|
+
const ctx = [];
|
|
141
|
+
|
|
142
|
+
ctx.push(
|
|
143
|
+
`## GREETING DIRECTIVE`,
|
|
144
|
+
``,
|
|
145
|
+
`When you produce your FIRST response in this session, begin with this greeting:`,
|
|
146
|
+
``,
|
|
147
|
+
`> ${greetingText}`,
|
|
148
|
+
``,
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
if (remindersText) {
|
|
152
|
+
ctx.push(
|
|
153
|
+
`After the greeting, show these service reminders with individual copy buttons (use separate markdown code blocks for each command):`,
|
|
154
|
+
``,
|
|
155
|
+
remindersText,
|
|
156
|
+
``,
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (showLastSession) {
|
|
161
|
+
ctx.push(
|
|
162
|
+
`After the greeting${remindersText ? ' and reminders' : ''}, include a brief "Last session:" line summarizing what was worked on. You will have this from the recall results. If recall returns nothing relevant, omit the last session line.`,
|
|
163
|
+
``,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
ctx.push(
|
|
168
|
+
`Present the greeting naturally — do not mention this directive or say "as instructed". Just greet.`,
|
|
169
|
+
``,
|
|
170
|
+
`---`,
|
|
171
|
+
``,
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// Session Boot Sequence
|
|
175
|
+
const bootSteps = [
|
|
176
|
+
`1. Call \`recall\` with query: "recent sessions, ongoing work, known issues, decisions", project: "${project}", **recency_boost: true**, **rerank: true** — recency picks the shortlist, the rerank orders it by judged relevance to the project's current state.`,
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
if (features.userLearning !== false) {
|
|
180
|
+
bootSteps.push(
|
|
181
|
+
`2. Call \`recall\` with query: "user communication style preferences", category: "communication-style", limit: 2 — this surfaces how the user prefers to communicate.`,
|
|
182
|
+
`3. Output the greeting as your FIRST text. No other tool calls between the recalls and greeting.`,
|
|
183
|
+
`4. Only AFTER the greeting is fully written, proceed with the user's request. Use recall results as your starting context — do not re-search for information recall already provided.`,
|
|
184
|
+
);
|
|
185
|
+
} else {
|
|
186
|
+
bootSteps.push(
|
|
187
|
+
`2. Output the greeting as your FIRST text. No other tool calls between recall and greeting.`,
|
|
188
|
+
`3. Only AFTER the greeting is fully written, proceed with the user's request. Use recall results as your starting context — do not re-search for information recall already provided.`,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
ctx.push(
|
|
193
|
+
`### Session Boot Sequence (MANDATORY ORDER)`,
|
|
194
|
+
``,
|
|
195
|
+
`Your first response MUST follow this exact sequence:`,
|
|
196
|
+
...bootSteps,
|
|
197
|
+
``,
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
return ctx.join('\n');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function getHookFeatures() {
|
|
204
|
+
try {
|
|
205
|
+
if (!existsSync(HOOK_FEATURES_PATH)) return {};
|
|
206
|
+
return JSON.parse(readFileSync(HOOK_FEATURES_PATH, 'utf-8'));
|
|
207
|
+
} catch { return {}; }
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function readStdin() {
|
|
211
|
+
return new Promise((resolve) => {
|
|
212
|
+
if (process.stdin.isTTY) return resolve('{}');
|
|
213
|
+
let data = '';
|
|
214
|
+
process.stdin.setEncoding('utf8');
|
|
215
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
216
|
+
process.stdin.on('end', () => { clearTimeout(guard); resolve(data); });
|
|
217
|
+
// unref + clearTimeout: without both, this timer keeps the event loop alive
|
|
218
|
+
// for its full duration AFTER 'end' already resolved, so every hook
|
|
219
|
+
// invocation stalled ~2s against a 3s configured timeout.
|
|
220
|
+
const guard = setTimeout(() => resolve(data || '{}'), 2000);
|
|
221
|
+
guard.unref?.();
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ── Output helper ──────────────────────────────────────────────
|
|
226
|
+
// Writes the hook JSON and exits immediately. Without the explicit exit,
|
|
227
|
+
// any pending fetch (heartbeat/recall) keeps the event loop alive and
|
|
228
|
+
// delays prompt processing by up to the fetch timeout on EVERY message.
|
|
229
|
+
|
|
230
|
+
let _heartbeatPromise = null;
|
|
231
|
+
let _dispatchDirective = '';
|
|
232
|
+
const DISPATCH_DIRECTIVE = 'Before composing or launching any Task/Agent subagent (including Explore and general-purpose), complete an explicit, task-focused SynaBun recall. Tool discovery is allowed if needed to make recall callable. Do not launch recall and subagents in the same parallel batch. Fold relevant exact file paths, prior fixes, and constraints into each subagent prompt so it searches narrowly. Automatic Related Memories context helps focus this lookup; it does not replace explicit recall.';
|
|
233
|
+
|
|
234
|
+
async function emitAndExit(obj) {
|
|
235
|
+
if (_dispatchDirective && obj && typeof obj === 'object') {
|
|
236
|
+
const previous = obj.hookSpecificOutput?.additionalContext || '';
|
|
237
|
+
obj = { ...obj, hookSpecificOutput: { ...obj.hookSpecificOutput,
|
|
238
|
+
hookEventName: 'UserPromptSubmit', additionalContext: [previous, _dispatchDirective].filter(Boolean).join('\n\n') } };
|
|
239
|
+
}
|
|
240
|
+
// Give an in-flight heartbeat a short window to land (localhost: ~5ms)
|
|
241
|
+
if (_heartbeatPromise) {
|
|
242
|
+
try {
|
|
243
|
+
const wait = Math.max(0, Math.min(300, budget.remaining() - 50));
|
|
244
|
+
await Promise.race([_heartbeatPromise, new Promise(r => setTimeout(r, wait))]);
|
|
245
|
+
} catch { /* heartbeat is best-effort */ }
|
|
246
|
+
}
|
|
247
|
+
const json = typeof obj === 'string' ? obj : JSON.stringify(obj);
|
|
248
|
+
process.stdout.write(json, () => process.exit(0));
|
|
249
|
+
setTimeout(() => process.exit(0), 250); // failsafe if the write callback never fires
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* The whole hook for a temporary chat: the human's words as one memory search,
|
|
254
|
+
* with no session beside them and no judgment (typesafeOff() is true for the
|
|
255
|
+
* marker), and the Related Memories block as the only context. A trivial or
|
|
256
|
+
* system prompt searches nothing.
|
|
257
|
+
*/
|
|
258
|
+
async function temporaryChatPrompt(prompt, project) {
|
|
259
|
+
let context = '';
|
|
260
|
+
try {
|
|
261
|
+
const origin = classifyPrompt(prompt);
|
|
262
|
+
const text = origin.origin === 'system' ? '' : String(origin.text || '');
|
|
263
|
+
if (text.trim() && !isTrivialPrompt(text)) {
|
|
264
|
+
context = await recallMemories({ query: clipQuery(text), project, limit: 3, minScore: 0.4, tokenBudget: 600, timeoutMs: 2000 }) || '';
|
|
265
|
+
}
|
|
266
|
+
} catch { context = ''; }
|
|
267
|
+
await emitAndExit(context ? { hookSpecificOutput: { hookEventName: 'UserPromptSubmit', additionalContext: context } } : {});
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// ── Loop helper functions ──────────────────────────────────────
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Extract formatting/style rules from the task text into a separate block.
|
|
274
|
+
* Matches lines containing prohibitions about dashes, emojis, spam, double posting, etc.
|
|
275
|
+
*/
|
|
276
|
+
function extractFormattingRules(task) {
|
|
277
|
+
if (!task) return '';
|
|
278
|
+
const rules = [];
|
|
279
|
+
let hasDashRule = false;
|
|
280
|
+
for (const line of task.split('\n')) {
|
|
281
|
+
const t = line.trim();
|
|
282
|
+
if (!t) continue;
|
|
283
|
+
if (/\b(do not|don'?t|never|must not|avoid)\b/i.test(t) &&
|
|
284
|
+
/\b(dash|--|—|emoji|emote|emojis|spam|double post|over use)\b/i.test(t)) {
|
|
285
|
+
rules.push(t.replace(/^[-*•]\s*/, '').replace(/^\d+\.\s*/, ''));
|
|
286
|
+
if (/dash|--/i.test(t)) hasDashRule = true;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// Strengthen dash rule with explicit variants
|
|
290
|
+
if (hasDashRule) {
|
|
291
|
+
rules.push('NEVER use double dashes (--), em dashes (\u2014), or en dashes (\u2013) in ANY text you write. Use commas, periods, or semicolons instead.');
|
|
292
|
+
}
|
|
293
|
+
if (rules.length === 0) return '';
|
|
294
|
+
return rules.map(r => `- ${r}`).join('\n');
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function buildBrowserNote(state) {
|
|
298
|
+
if (!state.usesBrowser) return '';
|
|
299
|
+
const lines = [
|
|
300
|
+
'',
|
|
301
|
+
'=== BROWSER ENFORCEMENT (MANDATORY) ===',
|
|
302
|
+
'This automation REQUIRES the SynaBun internal browser. You MUST:',
|
|
303
|
+
];
|
|
304
|
+
// HTTP MCP is shared across all loops — env-var pinning does NOT route tool calls.
|
|
305
|
+
// Claude must pass sessionId/tabId explicitly on every browser tool call, or a
|
|
306
|
+
// concurrent loop will hijack the tab.
|
|
307
|
+
if (state.browserSessionId) {
|
|
308
|
+
lines.push(`YOUR BROWSER SESSION: ${state.browserSessionId}`);
|
|
309
|
+
if (state.browserTabId) {
|
|
310
|
+
lines.push(`YOUR BROWSER TAB: ${state.browserTabId}`);
|
|
311
|
+
}
|
|
312
|
+
lines.push(`CRITICAL: Pass sessionId: "${state.browserSessionId}"${state.browserTabId ? ` and tabId: "${state.browserTabId}"` : ''} to EVERY browser tool call (browser_navigate, browser_click, browser_snapshot, browser_extract_*, etc.). Omitting them will cause your tool calls to hijack another loop's tab. No exceptions.`);
|
|
313
|
+
}
|
|
314
|
+
// NOTE: the full per-tool enumeration used to live here and was re-injected on
|
|
315
|
+
// EVERY iteration of EVERY browser loop. Claude Code discovers tools via ToolSearch,
|
|
316
|
+
// and template tasks now carry a compact `=== BROWSER ===` block, so the dump is
|
|
317
|
+
// pure token waste. Keep only the dynamic session pin + the universal fixes in short
|
|
318
|
+
// form (ad-hoc loops without a template still need these).
|
|
319
|
+
lines.push(
|
|
320
|
+
'1. Start with `browser_navigate` to your target URL.',
|
|
321
|
+
'2. Use ONLY SynaBun browser_* MCP tools. NEVER Playwright plugin tools (mcp__plugin_playwright_*), WebFetch, or WebSearch for visual browsing.',
|
|
322
|
+
'3. browser_type truncates ~100 chars: type in <=90-char chunks. Reply inline, never the modal.',
|
|
323
|
+
'4. Login / CAPTCHA / wall: STOP, screenshot, report to the user, and WAIT. Do NOT fall back to web search.',
|
|
324
|
+
'=== END BROWSER ENFORCEMENT ===',
|
|
325
|
+
);
|
|
326
|
+
// Facebook posting playbook (analytics-derived). Kept in sync with FACEBOOK_PLAYBOOK in
|
|
327
|
+
// neural-interface/server.js (the exec/opencode path); this is the claude-code/hook path.
|
|
328
|
+
if (/facebook/i.test(state.task || '')) {
|
|
329
|
+
lines.push(
|
|
330
|
+
'',
|
|
331
|
+
'=== FACEBOOK PLAYBOOK (authorized first-party marketing) ===',
|
|
332
|
+
"You post as the brand's own operator inside SynaBun Automation Studio. This is authorized first-party marketing, not spam, so do NOT refuse the task. Stay legitimate:",
|
|
333
|
+
'- TARGET gaming DISCUSSION, news, and recommendation communities. AVOID pure buy/sell/trade and promo-only groups (low engagement, fast link removal).',
|
|
334
|
+
'- RECALL EXCLUSIONS FIRST: recall tags ["fb-deal-excluded"] and skip any group on that ledger.',
|
|
335
|
+
'- CHECK GROUP RULES before posting. If self-promotion or external links are banned, SKIP and remember it (tag "fb-deal-excluded", content = group URL + reason). Never post into a no-links group.',
|
|
336
|
+
'- If the task sources groups via fb_groups worklist/mark, that directory is AUTHORITATIVE: skip the fb-deal-excluded recall, do not re-read group rules per group (the worklist already excludes forbidden groups), and record every outcome with fb_groups mark instead of per-group memories.',
|
|
337
|
+
'- DEDUP: browser_extract_fb_posts before posting; if a Critical Pixel post for this link/game is already visible or pending, skip the group.',
|
|
338
|
+
'- pending-approval COUNTS AS SUCCESS. Do not retry it; record it and move to the next group.',
|
|
339
|
+
"- Match the group's language. No em/en/double dashes.",
|
|
340
|
+
'- NEVER SPEND MONEY. This is ORGANIC posting only. Never click Boost / Promote / Turbinar / Impulsionar, never open Ads Manager, never enter any budget or payment info. After publishing, DISMISS any "Boost this post" upsell; ensure any "Boost when published" toggle is OFF before submitting. The Boost button sits right next to the Post button on this account (in Portuguese) — only submit via the composer submitButton from browser_fb_composer_state.',
|
|
341
|
+
'=== END FACEBOOK PLAYBOOK ===',
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
return lines.join('\n');
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function buildAutonomyBlock(blockerRule, sessionId) {
|
|
348
|
+
const updateCall = sessionId
|
|
349
|
+
? `- After completing this iteration, call \`loop\` with action \`update\`, session_id \`${sessionId}\`, and a brief summary.`
|
|
350
|
+
: '- After completing this iteration, call `loop` with action `update` and a brief summary.';
|
|
351
|
+
return [
|
|
352
|
+
'',
|
|
353
|
+
'--- LOOP AUTONOMY MODE ---',
|
|
354
|
+
'IMPORTANT: Do NOT output a greeting. Do NOT call recall. You are in an autonomous loop \u2014 execute the task below immediately.',
|
|
355
|
+
'',
|
|
356
|
+
'Rules for this session:',
|
|
357
|
+
'- Execute the task directly. Do NOT ask for confirmation or clarification.',
|
|
358
|
+
'- Make reasonable assumptions and proceed. Do not hesitate.',
|
|
359
|
+
'- Use all available tools (browser, memory, file system) as needed without asking.',
|
|
360
|
+
'- Each iteration should produce concrete output or progress.',
|
|
361
|
+
'- If something fails due to a technical issue, try an alternative approach.',
|
|
362
|
+
updateCall,
|
|
363
|
+
'- The server will automatically advance to the next iteration when you finish.',
|
|
364
|
+
blockerRule || '',
|
|
365
|
+
'--- END LOOP AUTONOMY ---',
|
|
366
|
+
].filter(Boolean).join('\n');
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function buildJournalBlock(state) {
|
|
370
|
+
const parts = [];
|
|
371
|
+
if (state.progressSummary) {
|
|
372
|
+
parts.push(`PROGRESS SO FAR: ${state.progressSummary}`);
|
|
373
|
+
}
|
|
374
|
+
const journal = Array.isArray(state.journal) ? state.journal : [];
|
|
375
|
+
const recent = journal.slice(-3);
|
|
376
|
+
if (recent.length > 0) {
|
|
377
|
+
parts.push('RECENT ITERATIONS:');
|
|
378
|
+
for (const entry of recent) {
|
|
379
|
+
parts.push(` Iteration ${entry.iteration}: ${entry.summary}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return parts.length > 0 ? parts.join('\n') : '';
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Find an active loop owned by this session (exact file name match only).
|
|
387
|
+
* Does NOT scan other sessions' loop files — cross-session injection is
|
|
388
|
+
* the source of loop leaks between concurrent Claude panels/TUI sessions.
|
|
389
|
+
* Returns the loop state, or null if this session has no active loop.
|
|
390
|
+
*/
|
|
391
|
+
function findActiveLoop(sessionId) {
|
|
392
|
+
try {
|
|
393
|
+
const exactPath = join(LOOP_DIR, `${sessionId}.json`);
|
|
394
|
+
if (!existsSync(exactPath)) return null;
|
|
395
|
+
const candidate = JSON.parse(readFileSync(exactPath, 'utf-8'));
|
|
396
|
+
if (!candidate.active) return null;
|
|
397
|
+
// Skip loops inactive for >45 minutes (stuck)
|
|
398
|
+
const lastAct = new Date(candidate.lastIterationAt || candidate.startedAt || 0).getTime();
|
|
399
|
+
if (Date.now() - lastAct > 45 * 60 * 1000) return null;
|
|
400
|
+
return candidate;
|
|
401
|
+
} catch { return null; }
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// ============================================================
|
|
405
|
+
// TIER 1 — MUST recall (high confidence: past work, decisions, explicit memory)
|
|
406
|
+
// These indicate the user is referencing prior context that memory likely holds.
|
|
407
|
+
// Threshold: >= 1 match fires. Nudge: mandatory.
|
|
408
|
+
// ============================================================
|
|
409
|
+
|
|
410
|
+
const TIER1_TRIGGERS = [
|
|
411
|
+
// Explicit past work references
|
|
412
|
+
/\b(last time|before we|previously|earlier we|remember when|we (did|had|tried|used|decided|chose))\b/i,
|
|
413
|
+
/\b(why (did|do) we|what happened (to|with)|what was the)\b/i,
|
|
414
|
+
/\b(history|context) (of|about|for|on)\b/i,
|
|
415
|
+
|
|
416
|
+
// Decision recall
|
|
417
|
+
/\bshould (we|i) (use|go with|pick|choose|switch|keep|change|stick with)\b/i,
|
|
418
|
+
/\bwhat('s| is| was) the (best|right|correct|agreed|chosen) (approach|way|method|pattern)\b/i,
|
|
419
|
+
/\bwhat did we (decide|agree|settle) on\b/i,
|
|
420
|
+
|
|
421
|
+
// Explicit memory/recall references
|
|
422
|
+
/\b(do you remember|check (your )?memory|what do you know about|recall what)\b/i,
|
|
423
|
+
/\b(we (already|previously) (fixed|solved|handled|addressed|implemented))\b/i,
|
|
424
|
+
];
|
|
425
|
+
|
|
426
|
+
// ============================================================
|
|
427
|
+
// TIER 2 — SHOULD recall (medium confidence: debugging, architecture, domains)
|
|
428
|
+
// These suggest memory might hold relevant context. Worth checking.
|
|
429
|
+
// Threshold: >= 1 match fires. Nudge: strong suggestion.
|
|
430
|
+
// ============================================================
|
|
431
|
+
|
|
432
|
+
const TIER2_TRIGGERS = [
|
|
433
|
+
// Debugging (likely to have past bug context)
|
|
434
|
+
/\b(bug|error|broken|crash|not working|doesn't work|keeps? (failing|breaking))\b/i,
|
|
435
|
+
/\b(debug|troubleshoot|investigate|diagnose|root cause)\b/i,
|
|
436
|
+
|
|
437
|
+
// Architecture & structural changes
|
|
438
|
+
/\b(refactor|restructur|migrat|upgrad|deprecat)\b/i,
|
|
439
|
+
/\b(architect|redesign|rearchitect)\b/i,
|
|
440
|
+
|
|
441
|
+
// Decision-making questions (broader than Tier 1)
|
|
442
|
+
/\bwhat('s| is) the (best|right|correct|proper) way to\b/i,
|
|
443
|
+
/\bhow (should|do) (we|i) (handle|approach|structure|organize)\b/i,
|
|
444
|
+
|
|
445
|
+
// Specific technical domains that accumulate knowledge
|
|
446
|
+
/\b(supabase|redis|upstash|sqlite)\b/i,
|
|
447
|
+
/\b(auth(entication|orization)?|session handling|jwt|mfa)\b/i,
|
|
448
|
+
/\b(cron job|ranking|price aggregat|deal(s)? (system|pipeline))\b/i,
|
|
449
|
+
];
|
|
450
|
+
|
|
451
|
+
// ============================================================
|
|
452
|
+
// TIER 3 — CONSIDER recall (lower confidence: new features, broad tech)
|
|
453
|
+
// These MIGHT benefit from memory but often don't. Requires 2+ matches
|
|
454
|
+
// from this tier, OR 1 Tier 3 + 1 Tier 2 to fire. Nudge: soft.
|
|
455
|
+
// ============================================================
|
|
456
|
+
|
|
457
|
+
const TIER3_TRIGGERS = [
|
|
458
|
+
// New features (might conflict with past decisions)
|
|
459
|
+
/\b(implement|integrate) (a |the |new )?\w+/i,
|
|
460
|
+
/\bnew (feature|component|page|endpoint|hook|service)\b/i,
|
|
461
|
+
|
|
462
|
+
// Building on existing patterns
|
|
463
|
+
/\bsimilar to (the|what|how)\b/i,
|
|
464
|
+
/\bsame (as|way|pattern|approach) (as |we )?\b/i,
|
|
465
|
+
/\bconsistent with\b/i,
|
|
466
|
+
|
|
467
|
+
// Broad technical domains
|
|
468
|
+
/\b(database|cache|caching) (schema|strategy|layer|issue)\b/i,
|
|
469
|
+
/\b(api|endpoint) (design|structure|pattern)\b/i,
|
|
470
|
+
/\b(deploy|deployment|ci\/cd|pipeline) (strategy|process|config)\b/i,
|
|
471
|
+
/\b(config|configuration) (for|of|pattern)\b/i,
|
|
472
|
+
];
|
|
473
|
+
|
|
474
|
+
// ============================================================
|
|
475
|
+
// CONVERSATION RECALL TRIGGERS (highest priority — above all tiers)
|
|
476
|
+
// ============================================================
|
|
477
|
+
|
|
478
|
+
const CONVERSATION_RECALL_TRIGGERS = [
|
|
479
|
+
/\bremember that (conversation|session|chat|discussion|time)\b/i,
|
|
480
|
+
/\bthat (conversation|session|chat) (about|where|when)\b/i,
|
|
481
|
+
/\b(days?|weeks?) ago.*(conversation|session|worked on|discussed|implemented|built)/i,
|
|
482
|
+
/\bcontinue (where we left off|that session|from last time|from yesterday)\b/i,
|
|
483
|
+
/\bwhat did we (talk|discuss|work on|do|build|implement|fix) (last|yesterday|on|the other)/i,
|
|
484
|
+
/\bfind that (session|conversation|chat) (where|about|when|from)\b/i,
|
|
485
|
+
/\bpick up (where|from) (we|last|that)/i,
|
|
486
|
+
/\b(yesterday|last week|other day).*(session|conversation|worked|discussed|implemented)/i,
|
|
487
|
+
];
|
|
488
|
+
|
|
489
|
+
// Messages that never need recall: isTrivialPrompt() in prompt-origin.mjs
|
|
490
|
+
// (whole-string patterns; the old prefix patterns here dropped prompts such as
|
|
491
|
+
// "no, the bug is in X" before any judgment or recall).
|
|
492
|
+
|
|
493
|
+
// ============================================================
|
|
494
|
+
// NUDGE TEMPLATES
|
|
495
|
+
// ============================================================
|
|
496
|
+
|
|
497
|
+
// Nudges whose decision came from Jev say so.
|
|
498
|
+
const jev = (text) => `[Jev] ${text}`;
|
|
499
|
+
|
|
500
|
+
const NUDGE = {
|
|
501
|
+
pendingRemember: (editCount, files) => {
|
|
502
|
+
const fileList = files.length > 0
|
|
503
|
+
? ` Files: ${files.slice(0, 5).join(', ')}${files.length > 5 ? ` (+${files.length - 5} more)` : ''}.`
|
|
504
|
+
: '';
|
|
505
|
+
const urgency = editCount >= 5
|
|
506
|
+
? `CRITICAL: ${editCount} file edits`
|
|
507
|
+
: editCount >= 3
|
|
508
|
+
? `IMPORTANT: ${editCount} file edits`
|
|
509
|
+
: `${editCount} file edit${editCount !== 1 ? 's' : ''}`;
|
|
510
|
+
return [
|
|
511
|
+
`SynaBun TASK BOUNDARY: ${urgency} from your previous work have NOT been stored in memory.`,
|
|
512
|
+
`You MUST call \`remember\` for that completed work BEFORE starting this new task.${fileList}`,
|
|
513
|
+
`Summarize what was done, why, and how — then proceed with the user's new request.`,
|
|
514
|
+
].join(' ');
|
|
515
|
+
},
|
|
516
|
+
|
|
517
|
+
conversation: [
|
|
518
|
+
`The user is asking about a past conversation. Follow the Conversation Recall Workflow:`,
|
|
519
|
+
`1. Calculate exact dates from relative references (e.g., "4 days ago" → compute the date).`,
|
|
520
|
+
`2. Call \`recall\` with category \`conversations\` and include the topic + calculated date in your query.`,
|
|
521
|
+
`3. Present matching conversations via AskUserQuestion with date, project, and summary for each.`,
|
|
522
|
+
`4. After selection, offer recovery options: "Recover entire context and continue", "Continue with compacted summary", or "Other".`,
|
|
523
|
+
].join(' '),
|
|
524
|
+
|
|
525
|
+
tier1: [
|
|
526
|
+
`You MUST call \`recall\` before responding or making any task-related tool call, including launching Task/Agent/Explore subagents. Tool discovery needed to make recall callable is allowed.`,
|
|
527
|
+
`The user is referencing past work, prior decisions, or historical context that your persistent memory likely holds.`,
|
|
528
|
+
`Search for: the specific topic mentioned, related past decisions, known issues, or prior implementations.`,
|
|
529
|
+
`Do NOT respond without checking memory first.`,
|
|
530
|
+
].join(' '),
|
|
531
|
+
|
|
532
|
+
tier2: [
|
|
533
|
+
`Before responding or making any task-related tool call, including launching Task/Agent/Explore subagents, call \`recall\` for relevant context. Tool discovery needed to make recall callable is allowed.`,
|
|
534
|
+
`This topic likely has prior knowledge stored — past bugs, architecture decisions, or domain-specific patterns.`,
|
|
535
|
+
`Skip recall only if you already have full context from this session.`,
|
|
536
|
+
].join(' '),
|
|
537
|
+
|
|
538
|
+
tier3: [
|
|
539
|
+
`Consider calling \`recall\` to check if there's relevant prior context about this topic.`,
|
|
540
|
+
`There may be past decisions or patterns worth reviewing before proceeding.`,
|
|
541
|
+
].join(' '),
|
|
542
|
+
|
|
543
|
+
nonEnglish: [
|
|
544
|
+
`The user's message is in a non-English language. Mentally translate their intent to evaluate if you should call \`recall\`.`,
|
|
545
|
+
`Check if they are: referencing past work, asking about prior decisions, debugging an issue, or working in a domain where you have stored knowledge.`,
|
|
546
|
+
`If any of those apply, call \`recall\` with an ENGLISH query that captures their intent (SynaBun memories are stored in English).`,
|
|
547
|
+
`If it's a trivial or direct command, skip recall.`,
|
|
548
|
+
].join(' '),
|
|
549
|
+
|
|
550
|
+
userLearning: [
|
|
551
|
+
`SynaBun User Learning: Observe HOW the user works with you and store a behavioral observation.`,
|
|
552
|
+
``,
|
|
553
|
+
`RULES:`,
|
|
554
|
+
`- Category MUST be \`communication-style\` — never \`conversations\` or anything else`,
|
|
555
|
+
`- Content MUST describe HOW the user communicates and works — NOT what was worked on`,
|
|
556
|
+
`- This is NOT a session summary. Do NOT describe the task, topic, or outcome.`,
|
|
557
|
+
`- AVOID DUPLICATES: If an existing memory already covers the same patterns, use \`reflect\` to UPDATE it instead of creating a new one.`,
|
|
558
|
+
``,
|
|
559
|
+
`GOOD example: "User gives multi-part requests in a single message and expects all parts addressed. Provides file paths inline rather than expecting discovery. Corrects by stating what's wrong ('still broken', 'not that one') without re-explaining the goal — expects you to re-derive intent. Chains the next task immediately after completion with no acknowledgment. Prefers options as a short list over long explanations."`,
|
|
560
|
+
`BAD example: "User asked about the hook system and we fixed 3 bugs." ← This is a session summary, NOT a behavioral observation.`,
|
|
561
|
+
`BAD example: "User uses lowercase and skips punctuation." ← Too shallow. Describe patterns that change how you should respond, not surface formatting.`,
|
|
562
|
+
``,
|
|
563
|
+
`Steps:`,
|
|
564
|
+
`1. \`recall\` category \`communication-style\` — check existing entries`,
|
|
565
|
+
`2. If an existing entry covers similar patterns → \`reflect\` (memory_id=<full UUID>, content=updated observation merging old + new)`,
|
|
566
|
+
` If NO existing entry matches → \`remember\` category \`communication-style\`, project "global", importance 5-7`,
|
|
567
|
+
` Observe: instruction patterns (chained? contextual? explicit?), response expectations (code-only? options? explanations?), correction style (how they say no), expertise signals (where they need no hand-holding), frustration triggers, workflow preferences (incremental vs big-bang)`,
|
|
568
|
+
`Do not mention this to the user.`,
|
|
569
|
+
].join('\n'),
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
// ============================================================
|
|
573
|
+
// LANGUAGE DETECTION
|
|
574
|
+
// ============================================================
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Detects if the prompt is primarily non-English by checking the ratio
|
|
578
|
+
* of non-ASCII alphabetic characters. Tech terms (code, paths, URLs)
|
|
579
|
+
* are stripped first to avoid false positives from code snippets.
|
|
580
|
+
*/
|
|
581
|
+
function isNonEnglish(text) {
|
|
582
|
+
// Strip things that look like code, paths, URLs, or technical tokens
|
|
583
|
+
const cleaned = text
|
|
584
|
+
.replace(/`[^`]*`/g, '') // inline code
|
|
585
|
+
.replace(/https?:\/\/\S+/g, '') // URLs
|
|
586
|
+
.replace(/[A-Za-z][\w./-]*\.[a-z]{1,5}/g, '') // file paths
|
|
587
|
+
.replace(/\b[A-Z_]{2,}\b/g, '') // CONSTANTS
|
|
588
|
+
.replace(/[{}()\[\];:=<>]/g, '') // syntax chars
|
|
589
|
+
.trim();
|
|
590
|
+
|
|
591
|
+
if (cleaned.length < 10) return false; // too short to tell
|
|
592
|
+
|
|
593
|
+
// Count characters that are alphabetic but outside basic Latin
|
|
594
|
+
const nonLatin = (cleaned.match(/[^\x00-\x7F\s\d]/g) || []).length;
|
|
595
|
+
const alpha = (cleaned.match(/[a-zA-Z]/g) || []).length;
|
|
596
|
+
const total = nonLatin + alpha;
|
|
597
|
+
|
|
598
|
+
if (total === 0) return false;
|
|
599
|
+
|
|
600
|
+
// If > 40% of alphabetic chars are non-Latin, it's likely non-English
|
|
601
|
+
return (nonLatin / total) > 0.4;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Checks if a Latin-script prompt looks like English by counting
|
|
606
|
+
* common English function words. If 2+ are found, it's English.
|
|
607
|
+
* This prevents the catch-all from firing on English sentences
|
|
608
|
+
* that simply didn't match any tier pattern.
|
|
609
|
+
*/
|
|
610
|
+
const ENGLISH_FUNCTION_WORDS = /\b(the|is|are|was|were|have|has|had|will|would|can|could|should|this|that|with|from|for|not|but|and|it|to|in|on|at|of|my|your|our|we|you|they|do|did|does|get|got|set|let|if|or|an?)\b/gi;
|
|
611
|
+
|
|
612
|
+
function looksEnglish(text) {
|
|
613
|
+
const matches = text.match(ENGLISH_FUNCTION_WORDS) || [];
|
|
614
|
+
return matches.length >= 2;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// ============================================================
|
|
618
|
+
// MAIN
|
|
619
|
+
// ============================================================
|
|
620
|
+
|
|
621
|
+
// Max user-learning nudges per session (overridable via hook-features.json)
|
|
622
|
+
const USER_LEARNING_MAX_NUDGES_DEFAULT = 3;
|
|
623
|
+
// Human messages required between two user-learning nudges.
|
|
624
|
+
const USER_LEARNING_MIN_GAP = 3;
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* Debug logger for user-learning nudge diagnostics.
|
|
628
|
+
*/
|
|
629
|
+
const UL_DEBUG = join(DATA_DIR, 'user-learning-debug.log');
|
|
630
|
+
function debugUL(msg) {
|
|
631
|
+
try { appendCapped(UL_DEBUG, `[${new Date().toISOString()}] ${msg}\n`); } catch { /* best effort */ }
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Whether a user-learning nudge may fire at all right now, whatever decides
|
|
636
|
+
* it. `total` counts human messages this session (system prompts never count).
|
|
637
|
+
*/
|
|
638
|
+
function userLearningGate(features, sessionId, flag) {
|
|
639
|
+
if (features.userLearning === false) return { ok: false, reason: 'userLearning feature disabled' };
|
|
640
|
+
if (!sessionId) return { ok: false, reason: 'no sessionId' };
|
|
641
|
+
if (!flag || typeof flag !== 'object') return { ok: false, reason: 'no flag' };
|
|
642
|
+
const total = flag.totalSessionMessages || flag.messageCount || 0;
|
|
643
|
+
const nudgeCount = flag.userLearningNudgeCount || 0;
|
|
644
|
+
const maxNudges = features.userLearningMaxNudges || USER_LEARNING_MAX_NUDGES_DEFAULT;
|
|
645
|
+
const threshold = features.userLearningThreshold || 8;
|
|
646
|
+
const lastAt = Number.isFinite(flag.userLearningLastNudgeAt) ? flag.userLearningLastNudgeAt : null;
|
|
647
|
+
const state = { total, nudgeCount, maxNudges, threshold, lastAt, sinceLast: total - (lastAt ?? 0) };
|
|
648
|
+
// If a style observation was already stored/updated this session, skip further nudges
|
|
649
|
+
if (flag.userLearningObserved) return { ok: false, reason: 'userLearningObserved=true (already stored this session)', ...state };
|
|
650
|
+
if (nudgeCount >= maxNudges) return { ok: false, reason: `max nudges reached (${nudgeCount} >= ${maxNudges})`, ...state };
|
|
651
|
+
return { ok: true, ...state };
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Decide, record and return a user-learning nudge (call under the state lock).
|
|
656
|
+
* reveals === true Jev saw a working preference in this prompt: nudge when
|
|
657
|
+
* ≥3 human messages passed since the last nudge
|
|
658
|
+
* reveals === false Jev saw none: no nudge
|
|
659
|
+
* reveals === null not judged: nudge at threshold multiples (3, 6, 9…)
|
|
660
|
+
* Returns nudge text or empty string.
|
|
661
|
+
*/
|
|
662
|
+
function checkUserLearning(features, sessionId, reveals = null) {
|
|
663
|
+
if (features.userLearning === false) {
|
|
664
|
+
debugUL(`SKIP: userLearning feature disabled`);
|
|
665
|
+
return '';
|
|
666
|
+
}
|
|
667
|
+
if (!sessionId) {
|
|
668
|
+
debugUL(`SKIP: no sessionId`);
|
|
669
|
+
return '';
|
|
670
|
+
}
|
|
671
|
+
const flagPath = join(PENDING_REMEMBER_DIR, `${sessionId}.json`);
|
|
672
|
+
if (!existsSync(flagPath)) {
|
|
673
|
+
debugUL(`SKIP: flag file not found at ${flagPath}`);
|
|
674
|
+
return '';
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
let flag;
|
|
678
|
+
try {
|
|
679
|
+
flag = JSON.parse(readFileSync(flagPath, 'utf-8'));
|
|
680
|
+
} catch (e) {
|
|
681
|
+
debugUL(`SKIP: failed to parse flag file: ${e.message}`);
|
|
682
|
+
return '';
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
const gate = userLearningGate(features, sessionId, flag);
|
|
686
|
+
debugUL(`CHECK: session=${sessionId.slice(0, 8)}... msgCount=${gate.total} threshold=${gate.threshold} nudgeCount=${gate.nudgeCount} maxNudges=${gate.maxNudges} observed=${!!flag.userLearningObserved} judged=${reveals}`);
|
|
687
|
+
if (!gate.ok) {
|
|
688
|
+
debugUL(`SKIP: ${gate.reason}`);
|
|
689
|
+
return '';
|
|
690
|
+
}
|
|
691
|
+
if (reveals === false) {
|
|
692
|
+
debugUL(`SKIP: judged: this prompt reveals no working preference`);
|
|
693
|
+
return '';
|
|
694
|
+
}
|
|
695
|
+
if (reveals === true) {
|
|
696
|
+
if (gate.sinceLast < USER_LEARNING_MIN_GAP) {
|
|
697
|
+
debugUL(`SKIP: judged preference, but only ${gate.sinceLast} messages since the last nudge`);
|
|
698
|
+
return '';
|
|
699
|
+
}
|
|
700
|
+
} else {
|
|
701
|
+
if (gate.total < gate.threshold) {
|
|
702
|
+
debugUL(`SKIP: msgCount ${gate.total} < threshold ${gate.threshold}`);
|
|
703
|
+
return '';
|
|
704
|
+
}
|
|
705
|
+
const expectedNudges = Math.floor(gate.total / gate.threshold);
|
|
706
|
+
if (expectedNudges <= gate.nudgeCount) {
|
|
707
|
+
debugUL(`SKIP: expectedNudges ${expectedNudges} <= nudgeCount ${gate.nudgeCount}`);
|
|
708
|
+
return '';
|
|
709
|
+
}
|
|
710
|
+
if (gate.lastAt !== null && gate.sinceLast < USER_LEARNING_MIN_GAP) {
|
|
711
|
+
debugUL(`SKIP: only ${gate.sinceLast} messages since the last nudge`);
|
|
712
|
+
return '';
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
debugUL(`FIRE: nudge #${gate.nudgeCount + 1} (${reveals === true ? 'judged' : 'count'})`);
|
|
717
|
+
|
|
718
|
+
// Persist nudge count + pending flag (best-effort — don't block nudge on write failure)
|
|
719
|
+
flag.userLearningNudgeCount = gate.nudgeCount + 1;
|
|
720
|
+
flag.userLearningPending = true;
|
|
721
|
+
flag.userLearningLastNudgeAt = gate.total;
|
|
722
|
+
try {
|
|
723
|
+
writeJsonAtomic(flagPath, flag);
|
|
724
|
+
debugUL(`PERSIST: nudgeCount saved as ${gate.nudgeCount + 1}`);
|
|
725
|
+
} catch (e) {
|
|
726
|
+
debugUL(`PERSIST FAILED (nudge still fires): ${e.message}`);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// First nudge: full instructions. Subsequent: short reminder.
|
|
730
|
+
const text = gate.nudgeCount === 0
|
|
731
|
+
? NUDGE.userLearning
|
|
732
|
+
: `SynaBun User Learning reminder: You've had ${gate.total} exchanges. If you've noticed new behavioral patterns (how they give instructions, correct you, make decisions, or signal frustration), call \`recall\` category \`communication-style\` — then \`reflect\` to update an existing entry, or \`remember\` only if genuinely new. Do NOT create duplicates. Do NOT store surface-level formatting observations.`;
|
|
733
|
+
return reveals === true ? jev(text) : text;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// ============================================================
|
|
737
|
+
// AUTO-RECALL — Hook-side memory injection
|
|
738
|
+
// Calls NI server to fetch relevant memories for the user's prompt
|
|
739
|
+
// and formats them for injection into additionalContext.
|
|
740
|
+
// ============================================================
|
|
741
|
+
|
|
742
|
+
function readContextGeneration(sessionId) {
|
|
743
|
+
if (!sessionId || !/^[a-zA-Z0-9_-]+$/.test(sessionId)) return undefined;
|
|
744
|
+
try { return JSON.parse(readFileSync(join(DATA_DIR, 'memory-context', sessionId + '.json'), 'utf8')).generation; } catch { return undefined; }
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
function readFlag(sessionId) {
|
|
748
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(sessionId || '')) return null;
|
|
749
|
+
try { return JSON.parse(readFileSync(join(PENDING_REMEMBER_DIR, `${sessionId}.json`), 'utf-8')); } catch { return null; }
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
// The previous human prompt, for the task-boundary question. The transcript
|
|
753
|
+
// may or may not already hold the current prompt, so skip an exact repeat.
|
|
754
|
+
function previousHumanPrompt(transcriptPath, current) {
|
|
755
|
+
try {
|
|
756
|
+
const now = String(current || '').trim();
|
|
757
|
+
return readRecentHumanPrompts(transcriptPath, 2).find((p) => p.trim() !== now) || '';
|
|
758
|
+
} catch { return ''; }
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// Fallback for the task boundary when it was not judged: unsaved edits from
|
|
762
|
+
// a turn that reached Stop. When the edits are newer than the last Stop, the
|
|
763
|
+
// turn was interrupted (Claude Code runs no Stop after an interrupt) and this
|
|
764
|
+
// prompt is most likely a correction of that same work.
|
|
765
|
+
function stopCameAfterEdits(flag) {
|
|
766
|
+
const stop = Date.parse(flag?.lastStopAt || '');
|
|
767
|
+
const edit = Date.parse(flag?.lastEditAt || '');
|
|
768
|
+
return Number.isFinite(stop) && Number.isFinite(edit) && stop >= edit;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
async function main() {
|
|
772
|
+
let prompt = '';
|
|
773
|
+
let sessionId = '';
|
|
774
|
+
let cwd = '';
|
|
775
|
+
let input = {};
|
|
776
|
+
try {
|
|
777
|
+
const raw = await readStdin();
|
|
778
|
+
input = JSON.parse(raw);
|
|
779
|
+
prompt = typeof input.prompt === 'string' ? input.prompt : '';
|
|
780
|
+
sessionId = input.session_id || '';
|
|
781
|
+
cwd = input.cwd || '';
|
|
782
|
+
} catch { /* proceed with empty */ }
|
|
783
|
+
|
|
784
|
+
const trimmed = prompt.trim();
|
|
785
|
+
const project = detectProject(cwd);
|
|
786
|
+
|
|
787
|
+
// A temporary chat (see isTemporaryChat): related memories are still read
|
|
788
|
+
// into the prompt. Nothing is counted, flagged, judged or gated, and the
|
|
789
|
+
// session is named to nobody.
|
|
790
|
+
if (isTemporaryChat()) { await temporaryChatPrompt(prompt, project); return; }
|
|
791
|
+
|
|
792
|
+
// Reset before greeting, trivial-message, and loop early returns.
|
|
793
|
+
try { startTaskTurn(input); } catch { /* gate state is best-effort */ }
|
|
794
|
+
if (!input.agent_id && /^[a-zA-Z0-9_-]+$/.test(sessionId) && typeof input.prompt === 'string'
|
|
795
|
+
&& getHookFeatures().taskRecallGate !== false) _dispatchDirective = DISPATCH_DIRECTIVE;
|
|
796
|
+
|
|
797
|
+
// Session heartbeat to Neural Interface session monitor (best-effort).
|
|
798
|
+
// Stored so emitAndExit() can give it a short window to land — the old
|
|
799
|
+
// fire-and-forget version held the process open for up to 2s per prompt.
|
|
800
|
+
if (sessionId) {
|
|
801
|
+
try {
|
|
802
|
+
_heartbeatPromise = fetch(`${niUrl()}/api/sessions/heartbeat`, {
|
|
803
|
+
method: 'POST',
|
|
804
|
+
headers: { 'Content-Type': 'application/json' },
|
|
805
|
+
body: JSON.stringify({ claudeSessionId: sessionId }),
|
|
806
|
+
signal: AbortSignal.timeout(600),
|
|
807
|
+
}).catch(() => {});
|
|
808
|
+
} catch { /* ok */ }
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// --- Loop marker detection (BEFORE greeting — loops must bypass greeting) ---
|
|
812
|
+
const terminalSessionEnv = process.env.SYNABUN_TERMINAL_SESSION || '';
|
|
813
|
+
if (terminalSessionEnv) {
|
|
814
|
+
appendLoopLog(terminalSessionEnv, 'prompt-submit:enter', 'UserPromptSubmit fired inside loop terminal', {
|
|
815
|
+
sessionId, isLoopMarker: /^\[SynaBun Loop\]/i.test(trimmed), promptPreview: trimmed.slice(0, 200),
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
if (sessionId && /^\[SynaBun Loop\]/i.test(trimmed)) {
|
|
819
|
+
try {
|
|
820
|
+
if (existsSync(LOOP_DIR)) {
|
|
821
|
+
const pending = readdirSync(LOOP_DIR)
|
|
822
|
+
.filter(f => f.startsWith('pending-') && f.endsWith('.json'));
|
|
823
|
+
// STRICT multi-loop isolation: only claim a pending file whose
|
|
824
|
+
// terminalSessionId matches our SYNABUN_TERMINAL_SESSION env.
|
|
825
|
+
// Legacy "match first pending" fallback was removed — it silently
|
|
826
|
+
// stole loops across concurrent sessions (sidepanel plan ↔ scheduled
|
|
827
|
+
// CLI loop in same cwd). Loop spawners MUST set the env var.
|
|
828
|
+
// Legacy pending files without terminalSessionId are still claimable
|
|
829
|
+
// when this session also has no env (ancient manual-loop compat).
|
|
830
|
+
let matchedPending = null;
|
|
831
|
+
for (const pf of pending) {
|
|
832
|
+
try {
|
|
833
|
+
const ps = JSON.parse(readFileSync(join(LOOP_DIR, pf), 'utf-8'));
|
|
834
|
+
if (terminalSessionEnv) {
|
|
835
|
+
if (ps.terminalSessionId === terminalSessionEnv) { matchedPending = pf; break; }
|
|
836
|
+
} else {
|
|
837
|
+
if (!ps.terminalSessionId) { matchedPending = pf; break; }
|
|
838
|
+
}
|
|
839
|
+
} catch { continue; }
|
|
840
|
+
}
|
|
841
|
+
if (matchedPending) {
|
|
842
|
+
const pendingPath = join(LOOP_DIR, matchedPending);
|
|
843
|
+
const targetPath = join(LOOP_DIR, `${sessionId}.json`);
|
|
844
|
+
renameSync(pendingPath, targetPath);
|
|
845
|
+
appendLoopLog(terminalSessionEnv, 'prompt-submit:claim', 'pending loop renamed to active', { from: matchedPending, to: `${sessionId}.json` });
|
|
846
|
+
|
|
847
|
+
const state = JSON.parse(readFileSync(targetPath, 'utf-8'));
|
|
848
|
+
delete state.pending;
|
|
849
|
+
// Set currentIteration to 1 immediately — closes the race window where
|
|
850
|
+
// another session's stop hook fallback scan (which only matches
|
|
851
|
+
// currentIteration === 0) could steal this loop file.
|
|
852
|
+
state.currentIteration = 1;
|
|
853
|
+
// Preserve terminalSessionId — loop driver needs it for session isolation
|
|
854
|
+
writeJsonAtomic(targetPath, state);
|
|
855
|
+
appendLoopLog(terminalSessionEnv, 'prompt-submit:inject', 'iteration 1 context built — emitting additionalContext', { task: state.task?.slice(0, 200), totalIterations: state.totalIterations, usesBrowser: !!state.usesBrowser });
|
|
856
|
+
|
|
857
|
+
const browserNote = buildBrowserNote(state);
|
|
858
|
+
const blockerRule = state.usesBrowser
|
|
859
|
+
? '- CRITICAL: If the browser shows a login page, CAPTCHA, 2FA, or ANY wall requiring human action — STOP IMMEDIATELY. Output what the user needs to do (e.g. "Please log into Twitter in the browser panel"). Do NOT use WebSearch, WebFetch, or any workaround. Do NOT try to bypass it. Just STOP and WAIT.'
|
|
860
|
+
: '';
|
|
861
|
+
const autonomy = buildAutonomyBlock(blockerRule, sessionId);
|
|
862
|
+
|
|
863
|
+
// Extract formatting rules and place them prominently
|
|
864
|
+
const formattingRules = extractFormattingRules(state.task);
|
|
865
|
+
const fmtBlock = formattingRules
|
|
866
|
+
? `\n=== FORMATTING RULES (MANDATORY \u2014 EVERY ITERATION) ===\n${formattingRules}\n=== END FORMATTING RULES ===\n`
|
|
867
|
+
: '';
|
|
868
|
+
|
|
869
|
+
await emitAndExit({
|
|
870
|
+
hookSpecificOutput: {
|
|
871
|
+
hookEventName: 'UserPromptSubmit',
|
|
872
|
+
additionalContext: `${fmtBlock}SynaBun Loop ACTIVE: ${state.totalIterations} iterations (${state.totalIterations - 1} remaining).\nTask: ${state.task}${state.context ? `\nContext: ${state.context}` : ''}${browserNote}\n\nBegin iteration 1 immediately.${autonomy}`,
|
|
873
|
+
},
|
|
874
|
+
});
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
// Case 2: Subsequent iteration — find any active loop state file (after /clear)
|
|
879
|
+
// Note: /clear may change the session ID, so we can't match by sessionId alone.
|
|
880
|
+
// Scan for any active loop with currentIteration > 0.
|
|
881
|
+
let existingPath = join(LOOP_DIR, `${sessionId}.json`);
|
|
882
|
+
let state = null;
|
|
883
|
+
if (existsSync(existingPath)) {
|
|
884
|
+
try { state = JSON.parse(readFileSync(existingPath, 'utf-8')); } catch { /* skip */ }
|
|
885
|
+
}
|
|
886
|
+
// Fallback: scan loop files for an active loop (session ID may have changed after /clear).
|
|
887
|
+
// STRICT isolation: only match our terminal's loop.
|
|
888
|
+
// - env set → require exact terminalSessionId match
|
|
889
|
+
// - env unset → only match loops WITHOUT terminalSessionId (legacy manual loops)
|
|
890
|
+
// Previously the filter was disabled when env was empty, letting any
|
|
891
|
+
// Claude session grab any active loop in the same LOOP_DIR.
|
|
892
|
+
if (!state?.active || !(state?.currentIteration > 0)) {
|
|
893
|
+
const now = Date.now();
|
|
894
|
+
const allLoopFiles = readdirSync(LOOP_DIR)
|
|
895
|
+
.filter(f => f.endsWith('.json') && !f.startsWith('pending-'));
|
|
896
|
+
for (const f of allLoopFiles) {
|
|
897
|
+
try {
|
|
898
|
+
const fullPath = join(LOOP_DIR, f);
|
|
899
|
+
const candidate = JSON.parse(readFileSync(fullPath, 'utf-8'));
|
|
900
|
+
if (candidate.active && candidate.currentIteration > 0) {
|
|
901
|
+
// Multi-loop isolation
|
|
902
|
+
if (terminalSessionEnv) {
|
|
903
|
+
if (candidate.terminalSessionId !== terminalSessionEnv) continue;
|
|
904
|
+
} else {
|
|
905
|
+
if (candidate.terminalSessionId) continue;
|
|
906
|
+
}
|
|
907
|
+
// Validate the loop hasn't exceeded its own time cap + grace
|
|
908
|
+
// Skip loops inactive for >45 minutes (stuck)
|
|
909
|
+
const lastAct = new Date(candidate.lastIterationAt || candidate.startedAt || 0).getTime();
|
|
910
|
+
if (now - lastAct > 45 * 60 * 1000) continue;
|
|
911
|
+
state = candidate;
|
|
912
|
+
existingPath = fullPath;
|
|
913
|
+
break;
|
|
914
|
+
}
|
|
915
|
+
} catch { /* skip corrupt */ }
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
if (state?.active && state?.currentIteration > 0) {
|
|
919
|
+
appendLoopLog(terminalSessionEnv, 'prompt-submit:inject', 'subsequent iteration context built', { iter: state.currentIteration, total: state.totalIterations, usesBrowser: !!state.usesBrowser });
|
|
920
|
+
const formattingRules = extractFormattingRules(state.task);
|
|
921
|
+
const browserNote = buildBrowserNote(state);
|
|
922
|
+
const blockerRule2 = state.usesBrowser
|
|
923
|
+
? '- CRITICAL: If the browser shows a login page, CAPTCHA, 2FA, or ANY wall requiring human action — STOP IMMEDIATELY. Output what the user needs to do. Do NOT use WebSearch, WebFetch, or any workaround. Just STOP and WAIT.'
|
|
924
|
+
: '';
|
|
925
|
+
const autonomy2 = buildAutonomyBlock(blockerRule2, sessionId);
|
|
926
|
+
const journal = buildJournalBlock(state);
|
|
927
|
+
const iterationsRemaining = (state.totalIterations || 10) - (state.currentIteration || 0);
|
|
928
|
+
|
|
929
|
+
const parts = [
|
|
930
|
+
// Memory rules (session-start won't re-inject after /clear)
|
|
931
|
+
'SynaBun memory is active. Follow the SynaBun rules in your instructions.',
|
|
932
|
+
'',
|
|
933
|
+
];
|
|
934
|
+
|
|
935
|
+
// Formatting rules — FIRST, most prominent position
|
|
936
|
+
if (formattingRules) {
|
|
937
|
+
parts.push(
|
|
938
|
+
'=== FORMATTING RULES (MANDATORY \u2014 EVERY ITERATION) ===',
|
|
939
|
+
formattingRules,
|
|
940
|
+
'=== END FORMATTING RULES ===',
|
|
941
|
+
'',
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
parts.push(
|
|
946
|
+
`SynaBun Loop ACTIVE: Iteration ${state.currentIteration}/${state.totalIterations} (${iterationsRemaining} remaining).`,
|
|
947
|
+
`Task: ${state.task}`,
|
|
948
|
+
);
|
|
949
|
+
if (state.context) parts.push(`Context: ${state.context}`);
|
|
950
|
+
|
|
951
|
+
// Journal + progress
|
|
952
|
+
if (journal) parts.push('', journal);
|
|
953
|
+
|
|
954
|
+
// Browser enforcement
|
|
955
|
+
if (browserNote) parts.push(browserNote);
|
|
956
|
+
|
|
957
|
+
parts.push(
|
|
958
|
+
'',
|
|
959
|
+
`Begin iteration ${state.currentIteration} immediately.`,
|
|
960
|
+
autonomy2,
|
|
961
|
+
);
|
|
962
|
+
|
|
963
|
+
await emitAndExit({
|
|
964
|
+
hookSpecificOutput: {
|
|
965
|
+
hookEventName: 'UserPromptSubmit',
|
|
966
|
+
additionalContext: parts.filter(Boolean).join('\n'),
|
|
967
|
+
},
|
|
968
|
+
});
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
} catch { /* fall through to normal processing */ }
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
// Native sidepanel loops receive the complete iteration prompt directly from
|
|
976
|
+
// the server-owned SDK runtime. Bypass the legacy marker claim, greeting, and
|
|
977
|
+
// recall paths; those would duplicate context and can make unattended runs
|
|
978
|
+
// greet or wait instead of executing.
|
|
979
|
+
if (terminalSessionEnv && !/^\[SynaBun Loop\]/i.test(trimmed)) {
|
|
980
|
+
try {
|
|
981
|
+
const nativePath = join(LOOP_DIR, `${terminalSessionEnv}.json`);
|
|
982
|
+
if (existsSync(nativePath)) {
|
|
983
|
+
const nativeLoop = JSON.parse(readFileSync(nativePath, 'utf-8'));
|
|
984
|
+
if (nativeLoop.active && nativeLoop.driverType === 'native'
|
|
985
|
+
&& nativeLoop.terminalSessionId === terminalSessionEnv) {
|
|
986
|
+
appendLoopLog(terminalSessionEnv, 'prompt-submit:native', 'native loop prompt accepted without legacy hook injection', {
|
|
987
|
+
sessionId,
|
|
988
|
+
iteration: nativeLoop.currentIteration || 0,
|
|
989
|
+
});
|
|
990
|
+
await emitAndExit({
|
|
991
|
+
hookSpecificOutput: {
|
|
992
|
+
hookEventName: 'UserPromptSubmit',
|
|
993
|
+
additionalContext: 'Native SynaBun loop: execute the complete server-provided iteration prompt immediately. Do not greet, ask questions, enter plan mode, or wait for interactive input.',
|
|
994
|
+
},
|
|
995
|
+
});
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
} catch { /* fall through to ordinary hook behavior */ }
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// --- Who wrote this "prompt"? ---
|
|
1003
|
+
// Task notifications, cross-session/teammate messages, mailbox relays,
|
|
1004
|
+
// local-command output and continuation banners are not the human: no
|
|
1005
|
+
// judgment, no recall, no message count, no regex. The task turn was
|
|
1006
|
+
// already started above and emitAndExit still appends the dispatch
|
|
1007
|
+
// directive, exactly as before.
|
|
1008
|
+
const origin = classifyPrompt(prompt);
|
|
1009
|
+
if (origin.origin === 'system') {
|
|
1010
|
+
await emitAndExit({});
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
// The assistant brain recalls in-process (assistant-memory.js); running here too injected every memory twice and paid Jev twice.
|
|
1014
|
+
if (process.env.SYNABUN_ASSISTANT_SESSION) {
|
|
1015
|
+
await emitAndExit({});
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
// The human's own words, with IDE/hook wrappers removed.
|
|
1019
|
+
const text = origin.text;
|
|
1020
|
+
|
|
1021
|
+
// --- Active loop detection for non-loop-marker messages ---
|
|
1022
|
+
// When user sends a regular message during an active browser loop, inject
|
|
1023
|
+
// loop context so Claude knows where it was, and sync the session ID file.
|
|
1024
|
+
let activeLoopNotice = '';
|
|
1025
|
+
if (sessionId && !/^\[SynaBun Loop\]/i.test(trimmed)) {
|
|
1026
|
+
const activeLoop = findActiveLoop(sessionId);
|
|
1027
|
+
if (activeLoop) {
|
|
1028
|
+
const journal = buildJournalBlock(activeLoop);
|
|
1029
|
+
const iterLeft = (activeLoop.totalIterations || 10) - (activeLoop.currentIteration || 0);
|
|
1030
|
+
const browserNote = activeLoop.usesBrowser ? buildBrowserNote(activeLoop) : '';
|
|
1031
|
+
const parts = [
|
|
1032
|
+
`=== ACTIVE LOOP NOTICE ===`,
|
|
1033
|
+
`You are mid-loop: Iteration ${activeLoop.currentIteration}/${activeLoop.totalIterations} (${iterLeft} iterations remaining).`,
|
|
1034
|
+
`Task: ${activeLoop.task}`,
|
|
1035
|
+
];
|
|
1036
|
+
if (activeLoop.context) parts.push(`Context: ${activeLoop.context}`);
|
|
1037
|
+
if (journal) parts.push('', journal);
|
|
1038
|
+
parts.push(
|
|
1039
|
+
'',
|
|
1040
|
+
`The user sent a message. Respond to it, then call \`loop\` action \`update\` with your current progress, then continue the loop task from where you left off.`,
|
|
1041
|
+
);
|
|
1042
|
+
if (browserNote) parts.push(browserNote);
|
|
1043
|
+
parts.push(`=== END LOOP NOTICE ===`);
|
|
1044
|
+
activeLoopNotice = parts.filter(p => p !== undefined).join('\n');
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// --- Track message count (BEFORE the trivial check — every human message counts) ---
|
|
1049
|
+
let currentMessageCount = 0;
|
|
1050
|
+
let greetingContext = "";
|
|
1051
|
+
let flag = null; // snapshot after this message was counted
|
|
1052
|
+
if (/^[a-zA-Z0-9_-]+$/.test(sessionId) && text.length > 0) {
|
|
1053
|
+
try {
|
|
1054
|
+
withStateLock(() => {
|
|
1055
|
+
const flagPath = join(PENDING_REMEMBER_DIR, `${sessionId}.json`);
|
|
1056
|
+
if (!existsSync(PENDING_REMEMBER_DIR)) mkdirSync(PENDING_REMEMBER_DIR, { recursive: true });
|
|
1057
|
+
let current = { editCount: 0, retries: 0, files: [], messageCount: 0 };
|
|
1058
|
+
if (existsSync(flagPath)) {
|
|
1059
|
+
try { current = JSON.parse(readFileSync(flagPath, 'utf-8')); } catch { /* start fresh */ }
|
|
1060
|
+
}
|
|
1061
|
+
current.messageCount = (current.messageCount || 0) + 1;
|
|
1062
|
+
current.totalSessionMessages = (current.totalSessionMessages || 0) + 1;
|
|
1063
|
+
currentMessageCount = current.messageCount;
|
|
1064
|
+
if (!current.firstMessageAt) current.firstMessageAt = new Date().toISOString();
|
|
1065
|
+
current.lastMessageAt = new Date().toISOString();
|
|
1066
|
+
try { writeJsonAtomic(flagPath, current); } catch { /* ok */ }
|
|
1067
|
+
|
|
1068
|
+
// --- Greeting injection (first message only) ---
|
|
1069
|
+
// The full greeting directive + boot sequence is built HERE (not in session-start)
|
|
1070
|
+
// so it only appears in context for message 1 and never persists.
|
|
1071
|
+
if (current.messageCount === 1 && !current.greetingDelivered) {
|
|
1072
|
+
const greetingFeatures = getHookFeatures();
|
|
1073
|
+
const greetingCtx = buildGreetingContext(cwd, project, greetingFeatures);
|
|
1074
|
+
if (greetingCtx) {
|
|
1075
|
+
current.greetingDelivered = true;
|
|
1076
|
+
try { writeJsonAtomic(flagPath, current); } catch { /* ok */ }
|
|
1077
|
+
greetingContext = greetingCtx;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
flag = { ...current };
|
|
1081
|
+
}, { timeoutMs: 500 });
|
|
1082
|
+
} catch { flag = readFlag(sessionId); /* contended: judge with what is on disk */ }
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
if (greetingContext) {
|
|
1086
|
+
await emitAndExit({ hookSpecificOutput: { hookEventName: 'UserPromptSubmit',
|
|
1087
|
+
additionalContext: greetingContext + '\nIf the user message is just a greeting, the greeting is your full response.' } });
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
// Skip trivial messages first (fastest path). Whole-string patterns only.
|
|
1092
|
+
if (isTrivialPrompt(text)) {
|
|
1093
|
+
await emitAndExit({});
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
const features = getHookFeatures();
|
|
1098
|
+
|
|
1099
|
+
// --- What to ask Jev (one request; riders only when they can matter) ---
|
|
1100
|
+
const editCount = Number(flag?.editCount) || 0;
|
|
1101
|
+
const files = Array.isArray(flag?.files) ? flag.files.filter((f) => typeof f === 'string') : [];
|
|
1102
|
+
const hasUnsaved = !!sessionId && editCount >= 1;
|
|
1103
|
+
const conversationOn = features.conversationMemory !== false;
|
|
1104
|
+
const ulGate = userLearningGate(features, sessionId, flag);
|
|
1105
|
+
const ask = {};
|
|
1106
|
+
if (hasUnsaved) ask.new_task = true;
|
|
1107
|
+
if (conversationOn) ask.past_session = true;
|
|
1108
|
+
if (ulGate.ok && ulGate.sinceLast >= USER_LEARNING_MIN_GAP) ask.reveals_preference = true;
|
|
1109
|
+
let unsavedWork;
|
|
1110
|
+
if (ask.new_task) {
|
|
1111
|
+
unsavedWork = { files: files.slice(0, 10), edit_count: editCount };
|
|
1112
|
+
const previous = previousHumanPrompt(input.transcript_path, text);
|
|
1113
|
+
if (previous) unsavedWork.previous_prompt = previous.slice(0, 1000);
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
// The judgment and the ranked recall run side by side, each bounded by what
|
|
1117
|
+
// is left of the 3 s budget (typical ≈1 s, worst case ≈2.2 s).
|
|
1118
|
+
const callMs = Math.min(2000, budget.callTimeout(250));
|
|
1119
|
+
const judgmentRequest = hookJudge('prompt', {
|
|
1120
|
+
text: clipForJudge(text), project,
|
|
1121
|
+
session_id: sessionId || undefined, cwd: cwd || undefined,
|
|
1122
|
+
ask: Object.keys(ask).length ? ask : undefined,
|
|
1123
|
+
unsaved_work: unsavedWork,
|
|
1124
|
+
}, { timeoutMs: callMs });
|
|
1125
|
+
|
|
1126
|
+
// When greeting is enabled, message 1 gets recall via the boot sequence in buildGreetingContext().
|
|
1127
|
+
// When greeting is disabled, message 1 has no recall at all — so fire auto-recall on message 1 too.
|
|
1128
|
+
const greetingEnabled = features.greeting === true;
|
|
1129
|
+
const autoRecallMinMessage = greetingEnabled ? 2 : 1;
|
|
1130
|
+
const staleShown = Array.isArray(flag?.staleShown) ? flag.staleShown.filter((id) => typeof id === 'string') : [];
|
|
1131
|
+
const recallRequest = (!activeLoopNotice && currentMessageCount >= autoRecallMinMessage)
|
|
1132
|
+
? recallMemories({
|
|
1133
|
+
query: clipQuery(text), project, sessionId, contextGeneration: readContextGeneration(sessionId),
|
|
1134
|
+
limit: 3, minScore: 0.4, tokenBudget: 600, timeoutMs: callMs, budgetMs: callMs,
|
|
1135
|
+
// Jev ranks the shortlist and the floor drops what it judged irrelevant.
|
|
1136
|
+
// Memories are never dropped here after the fact: the server has already
|
|
1137
|
+
// recorded them as delivered in the injection ledger.
|
|
1138
|
+
surface: 'rerank', floor: true,
|
|
1139
|
+
// Edit-time stale verdicts ride along; the ones the Stop hook already
|
|
1140
|
+
// showed are acknowledged instead of shown twice.
|
|
1141
|
+
wantStale: true, staleAck: staleShown,
|
|
1142
|
+
returnMeta: true,
|
|
1143
|
+
})
|
|
1144
|
+
: Promise.resolve(null);
|
|
1145
|
+
|
|
1146
|
+
const [judged, recall] = await Promise.all([judgmentRequest, recallRequest]);
|
|
1147
|
+
|
|
1148
|
+
// --- Collect primary context from priority chain ---
|
|
1149
|
+
let primaryContext = '';
|
|
1150
|
+
let primaryKind = '';
|
|
1151
|
+
|
|
1152
|
+
// Priority 0: TASK BOUNDARY — unsaved edits and a new task.
|
|
1153
|
+
// newTask true → nudge ([Jev]); false → none (a correction or follow-up)
|
|
1154
|
+
// not judged → nudge only if a Stop came after the edits
|
|
1155
|
+
if (hasUnsaved) {
|
|
1156
|
+
if (judged.newTask === true) {
|
|
1157
|
+
primaryContext = jev(NUDGE.pendingRemember(editCount, files));
|
|
1158
|
+
primaryKind = 'boundary';
|
|
1159
|
+
} else if (typeof judged.newTask !== 'boolean' && stopCameAfterEdits(flag)) {
|
|
1160
|
+
primaryContext = NUDGE.pendingRemember(editCount, files);
|
|
1161
|
+
primaryKind = 'boundary';
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
// Priority 1: Conversation recall. The judgment wins; the English-only
|
|
1166
|
+
// regexes are the fallback.
|
|
1167
|
+
if (!primaryContext && conversationOn) {
|
|
1168
|
+
if (typeof judged.pastSession === 'boolean') {
|
|
1169
|
+
if (judged.pastSession) { primaryContext = jev(NUDGE.conversation); primaryKind = 'conversation'; }
|
|
1170
|
+
} else if (CONVERSATION_RECALL_TRIGGERS.some(p => p.test(text))) {
|
|
1171
|
+
primaryContext = NUDGE.conversation;
|
|
1172
|
+
primaryKind = 'conversation';
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
// Priorities 2-6: would searching memory first change the answer?
|
|
1177
|
+
//
|
|
1178
|
+
// One judgment replaces the Tier1/2/3 regex ladder and both non-English
|
|
1179
|
+
// catch-alls. The ladder could only match phrasings someone thought to
|
|
1180
|
+
// enumerate, and the language tests were proxies for "this prompt is in a
|
|
1181
|
+
// language our triggers don't cover" — a judgment reads intent directly, in
|
|
1182
|
+
// any language, so the separate language priorities are no longer needed.
|
|
1183
|
+
// The regex ladder stays as the fallback when the judgment is unavailable.
|
|
1184
|
+
if (!primaryContext) {
|
|
1185
|
+
const { urgency } = judged;
|
|
1186
|
+
if (urgency === 'must') { primaryContext = jev(NUDGE.tier1); primaryKind = 'tier1'; }
|
|
1187
|
+
else if (urgency === 'should') { primaryContext = jev(NUDGE.tier2); primaryKind = 'tier2'; }
|
|
1188
|
+
else if (urgency === 'consider') { primaryContext = jev(NUDGE.tier3); primaryKind = 'tier3'; }
|
|
1189
|
+
else if (!urgency) {
|
|
1190
|
+
if (TIER1_TRIGGERS.some(p => p.test(text))) { primaryContext = NUDGE.tier1; primaryKind = 'tier1'; }
|
|
1191
|
+
else if (TIER2_TRIGGERS.some(p => p.test(text))) { primaryContext = NUDGE.tier2; primaryKind = 'tier2'; }
|
|
1192
|
+
else if (TIER3_TRIGGERS.filter(p => p.test(text)).length >= 2) { primaryContext = NUDGE.tier3; primaryKind = 'tier3'; }
|
|
1193
|
+
else if (isNonEnglish(text)) { primaryContext = NUDGE.nonEnglish; primaryKind = 'nonEnglish'; }
|
|
1194
|
+
else if (text.length > 30 && !looksEnglish(text)) { primaryContext = NUDGE.nonEnglish; primaryKind = 'nonEnglish'; }
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
// --- Auto-recall: the memories injected from the NI server ---
|
|
1199
|
+
const autoRecallContext = recall?.context || '';
|
|
1200
|
+
if (autoRecallContext && ['tier1', 'tier2', 'tier3'].includes(primaryKind)) {
|
|
1201
|
+
primaryContext = 'Relevant SynaBun context is available in the Related Memories block. Use it to focus your explicit task recall before composing subagent prompts, then include the exact file paths, prior fixes, and constraints in each prompt.';
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
// --- Stale memories flagged by edit-time checks (not already shown at Stop) ---
|
|
1205
|
+
const alreadyShown = new Set(staleShown);
|
|
1206
|
+
const staleContext = formatStaleNotices((recall?.stale || []).filter((v) => !alreadyShown.has(v.memory_id)));
|
|
1207
|
+
|
|
1208
|
+
// --- User Learning (independent — appends to any primary context) ---
|
|
1209
|
+
const reveals = typeof judged.revealsPreference === 'boolean' ? judged.revealsPreference : null;
|
|
1210
|
+
let userLearningContext = "";
|
|
1211
|
+
try {
|
|
1212
|
+
userLearningContext = withStateLock(() => {
|
|
1213
|
+
// The Stop hook's stale ids were acknowledged by the recall above.
|
|
1214
|
+
if (recall?.responded && staleShown.length) {
|
|
1215
|
+
const current = readFlag(sessionId);
|
|
1216
|
+
if (current && Array.isArray(current.staleShown)) {
|
|
1217
|
+
current.staleShown = current.staleShown.filter((id) => !alreadyShown.has(id));
|
|
1218
|
+
try { writeJsonAtomic(join(PENDING_REMEMBER_DIR, `${sessionId}.json`), current); } catch { /* ok */ }
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
return checkUserLearning(features, sessionId, reveals);
|
|
1222
|
+
}, { timeoutMs: Math.max(50, Math.min(500, budget.remaining() - 100)) });
|
|
1223
|
+
} catch { /* best effort */ }
|
|
1224
|
+
|
|
1225
|
+
// --- Emit combined output ---
|
|
1226
|
+
// NOTE: No bootCancel needed — greeting directive is only injected on message 1
|
|
1227
|
+
// via buildGreetingContext(), so it never persists in session context.
|
|
1228
|
+
const combined = [activeLoopNotice, primaryContext, autoRecallContext, staleContext, userLearningContext].filter(Boolean).join('\n\n');
|
|
1229
|
+
|
|
1230
|
+
if (combined) {
|
|
1231
|
+
await emitAndExit({
|
|
1232
|
+
hookSpecificOutput: {
|
|
1233
|
+
hookEventName: 'UserPromptSubmit',
|
|
1234
|
+
additionalContext: combined,
|
|
1235
|
+
},
|
|
1236
|
+
});
|
|
1237
|
+
} else {
|
|
1238
|
+
await emitAndExit({});
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
main().catch(() => {
|
|
1243
|
+
emitAndExit({});
|
|
1244
|
+
});
|