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
|
@@ -0,0 +1,1135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for communicating with the Neural Interface Express server.
|
|
3
|
+
* The MCP server delegates all browser operations to the Neural Interface
|
|
4
|
+
* which manages Playwright sessions, CDP screencast, stealth, etc.
|
|
5
|
+
*/
|
|
6
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
7
|
+
import { randomUUID } from 'node:crypto';
|
|
8
|
+
import { getIdentity, effectivePins, terminalIdFor, callerRole, setReleaseHook, peekStdioIdentity, isHttpMode, } from './identity.js';
|
|
9
|
+
const BASE_URL = process.env.NEURAL_INTERFACE_URL
|
|
10
|
+
|| `http://localhost:${process.env.NEURAL_PORT || '3344'}`;
|
|
11
|
+
const DEFAULT_TIMEOUT = 10_000;
|
|
12
|
+
const LONG_TIMEOUT = 30_000;
|
|
13
|
+
const SESSION_CREATE_TIMEOUT = 70_000;
|
|
14
|
+
// Existing engagement spacing can consume 90 seconds before the click begins.
|
|
15
|
+
const CLICK_TIMEOUT = 120_000;
|
|
16
|
+
export function isBrowserV2Enabled() {
|
|
17
|
+
return process.env.SYNABUN_BROWSER_V2 !== '0';
|
|
18
|
+
}
|
|
19
|
+
const resolvedRoutes = new WeakMap();
|
|
20
|
+
const resolutionRefresh = new AsyncLocalStorage();
|
|
21
|
+
const browserCancellation = new AsyncLocalStorage();
|
|
22
|
+
export function runWithBrowserCancellation(signal, run, scope = 'browser') {
|
|
23
|
+
return signal ? browserCancellation.run({ signal, scope }, run) : run();
|
|
24
|
+
}
|
|
25
|
+
const batchContext = new AsyncLocalStorage();
|
|
26
|
+
export function runBrowserBatchContext(context, run) {
|
|
27
|
+
return batchContext.run(context, run);
|
|
28
|
+
}
|
|
29
|
+
/** Inside a browser_batch step. Browser assistance is off there: a batch is a known sequence. */
|
|
30
|
+
export function inBrowserBatch() {
|
|
31
|
+
return batchContext.getStore() !== undefined;
|
|
32
|
+
}
|
|
33
|
+
/** The MCP caller's cancellation signal, so an advisory judgment ends with the tool call that asked for it. */
|
|
34
|
+
export function currentBrowserSignal() {
|
|
35
|
+
return browserCancellation.getStore()?.signal;
|
|
36
|
+
}
|
|
37
|
+
function browserMetric(record) {
|
|
38
|
+
if (process.env.SYNABUN_BROWSER_METRICS === '1') {
|
|
39
|
+
console.error(JSON.stringify({ source: 'browser-client', ...record }));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Platform tools (BlueSky, X, Facebook, YouTube, …) always act on normal pages, so
|
|
43
|
+
// inside this scope resolution requires the default browser: an explicit session
|
|
44
|
+
// the server says does not serve it is dropped for the default one.
|
|
45
|
+
const platformRoute = new AsyncLocalStorage();
|
|
46
|
+
export function withPlatformRoute(run) {
|
|
47
|
+
return platformRoute.run(true, run);
|
|
48
|
+
}
|
|
49
|
+
function inPlatformRoute() {
|
|
50
|
+
return platformRoute.getStore() === true;
|
|
51
|
+
}
|
|
52
|
+
// The default browser as the Neural Interface last described it (its
|
|
53
|
+
// X-Synabun-Browser-Default header on every /api/browser response: connect mode
|
|
54
|
+
// and MoreLogin env). Part of every route key, so a change of browser settings
|
|
55
|
+
// drops every cached route of this process; the server in-process calls
|
|
56
|
+
// noteBrowserDefault when the settings are saved.
|
|
57
|
+
let browserDefault = '';
|
|
58
|
+
export function noteBrowserDefault(signature) {
|
|
59
|
+
if (typeof signature === 'string' && signature !== browserDefault)
|
|
60
|
+
browserDefault = signature;
|
|
61
|
+
}
|
|
62
|
+
function routeKey(id, sessionId, tabId, wantsDefaultBrowser = false) {
|
|
63
|
+
const pins = effectivePins(id);
|
|
64
|
+
// Only an explicit id resolves differently for page-opening and platform calls
|
|
65
|
+
// (resolveSessionUncached may drop it), so only then do they get their own slot.
|
|
66
|
+
return JSON.stringify([sessionId, tabId, pins.browserSessionId, pins.browserTabId,
|
|
67
|
+
id.state.ancestorPinnedSession, id.state.ancestorPinnedTab, sessionId ? wantsDefaultBrowser : null, browserDefault]);
|
|
68
|
+
}
|
|
69
|
+
export function isBrowserFastMode() {
|
|
70
|
+
return process.env.SYNABUN_BROWSER_FAST === '1';
|
|
71
|
+
}
|
|
72
|
+
export function isBrowserCompactMode() {
|
|
73
|
+
return process.env.SYNABUN_BROWSER_COMPACT === '1' || isBrowserFastMode();
|
|
74
|
+
}
|
|
75
|
+
async function requestOnce(method, path, body, timeout = DEFAULT_TIMEOUT) {
|
|
76
|
+
const cancellation = browserCancellation.getStore();
|
|
77
|
+
const callerSignal = cancellation?.signal;
|
|
78
|
+
const cancellationCode = cancellation?.scope === 'batch' ? 'BATCH_CANCELLED' : 'BROWSER_CANCELLED';
|
|
79
|
+
const cancellationLabel = cancellation?.scope === 'batch' ? 'Browser batch' : 'Browser request';
|
|
80
|
+
if (callerSignal?.aborted)
|
|
81
|
+
return { error: `${cancellationLabel} cancelled before the request started.`, code: cancellationCode, actionStarted: false };
|
|
82
|
+
const requestId = randomUUID();
|
|
83
|
+
const startedAt = performance.now();
|
|
84
|
+
const deadline = Date.now() + timeout;
|
|
85
|
+
let responseBytes = 0;
|
|
86
|
+
let estimatedTextTokens = 0;
|
|
87
|
+
let status;
|
|
88
|
+
const controller = new AbortController();
|
|
89
|
+
const cancel = () => controller.abort();
|
|
90
|
+
callerSignal?.addEventListener('abort', cancel, { once: true });
|
|
91
|
+
if (callerSignal?.aborted)
|
|
92
|
+
cancel();
|
|
93
|
+
let sent = false;
|
|
94
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
95
|
+
try {
|
|
96
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
97
|
+
// Per-caller routing identity: the server maps this to the caller's owned
|
|
98
|
+
// tab (_tabOwners) so tab-less browser calls never land on another
|
|
99
|
+
// automation's tab. Derived per-request over HTTP, per-process for stdio.
|
|
100
|
+
headers['X-Synabun-Terminal'] = terminalIdFor(getIdentity());
|
|
101
|
+
// Assistant runtimes forward their role so /api/assistant/* can tell an
|
|
102
|
+
// orchestrator apart from a worker run (workers must never dispatch).
|
|
103
|
+
const role = callerRole();
|
|
104
|
+
if (role)
|
|
105
|
+
headers['X-Synabun-Role'] = role;
|
|
106
|
+
headers['X-Synabun-Request-Id'] = requestId;
|
|
107
|
+
headers['X-Synabun-Deadline'] = String(deadline);
|
|
108
|
+
// Lets the server refuse advisory payloads and auto-heal for a batch step on its own authority.
|
|
109
|
+
if (batchContext.getStore())
|
|
110
|
+
headers['X-Synabun-Batch'] = '1';
|
|
111
|
+
const opts = {
|
|
112
|
+
method,
|
|
113
|
+
headers,
|
|
114
|
+
signal: controller.signal,
|
|
115
|
+
};
|
|
116
|
+
if (body && method !== 'GET') {
|
|
117
|
+
opts.body = JSON.stringify(body);
|
|
118
|
+
}
|
|
119
|
+
if (callerSignal?.aborted)
|
|
120
|
+
return { error: `${cancellationLabel} cancelled before the request started.`, code: cancellationCode, actionStarted: false };
|
|
121
|
+
sent = true;
|
|
122
|
+
const res = await fetch(`${BASE_URL}${path}`, opts);
|
|
123
|
+
status = res.status;
|
|
124
|
+
noteBrowserDefault(res.headers?.get?.('X-Synabun-Browser-Default'));
|
|
125
|
+
const responseText = await res.text();
|
|
126
|
+
const data = JSON.parse(responseText);
|
|
127
|
+
if (process.env.SYNABUN_BROWSER_METRICS === '1') {
|
|
128
|
+
responseBytes = Buffer.byteLength(responseText, 'utf8');
|
|
129
|
+
// Approximation, not provider-billed usage; exclude base64 image fields.
|
|
130
|
+
const { image: _image, screenshot: _screenshot, data: _data, ...textFields } = data;
|
|
131
|
+
estimatedTextTokens = Math.ceil(JSON.stringify(textFields).length / 4);
|
|
132
|
+
}
|
|
133
|
+
if (!res.ok && !data.error) {
|
|
134
|
+
data.error = `HTTP ${res.status}`;
|
|
135
|
+
}
|
|
136
|
+
return data;
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
140
|
+
if (callerSignal?.aborted) {
|
|
141
|
+
return { error: `${cancellationLabel} cancelled; inspect the page before retrying.`, code: cancellationCode, ...(sent ? { outcome: 'uncertain' } : { actionStarted: false }) };
|
|
142
|
+
}
|
|
143
|
+
if (controller.signal.aborted || /abort/i.test(msg)) {
|
|
144
|
+
return { error: `Request timed out after ${timeout}ms; outcome may be uncertain. Inspect the page before retrying.`, code: 'REQUEST_TIMEOUT', outcome: 'uncertain' };
|
|
145
|
+
}
|
|
146
|
+
return { error: `Neural Interface unreachable: ${msg}. Is the Neural Interface server running?`, code: 'TRANSPORT_ERROR', outcome: 'uncertain' };
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
clearTimeout(timer);
|
|
150
|
+
callerSignal?.removeEventListener('abort', cancel);
|
|
151
|
+
if (path.startsWith('/api/browser/')) {
|
|
152
|
+
browserMetric({ requestId, phase: 'http', method,
|
|
153
|
+
operation: path.split('?')[0].replace(/\/sessions\/[^/]+/, '/sessions/:id'),
|
|
154
|
+
durationMs: Math.round((performance.now() - startedAt) * 100) / 100,
|
|
155
|
+
status, responseBytes, estimatedTextTokens });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function request(method, path, body, timeout = DEFAULT_TIMEOUT) {
|
|
160
|
+
const result = await requestOnce(method, path, body, timeout);
|
|
161
|
+
const context = batchContext.getStore();
|
|
162
|
+
const missingRoute = result.actionStarted === false
|
|
163
|
+
&& (result.code === 'SESSION_NOT_FOUND' || result.code === 'TAB_NOT_FOUND');
|
|
164
|
+
const match = /^\/api\/browser\/sessions\/([^/?]+)\/(.+)$/.exec(path);
|
|
165
|
+
if (isBrowserV2Enabled() && missingRoute && match) {
|
|
166
|
+
const id = getIdentity();
|
|
167
|
+
const cached = resolvedRoutes.get(id);
|
|
168
|
+
resolvedRoutes.delete(id);
|
|
169
|
+
// Batches are pinned to their original tab and never recover midway.
|
|
170
|
+
const pinnedSession = effectivePins(id).browserSessionId || id.state.ancestorPinnedSession;
|
|
171
|
+
if (!context && cached?.route.sessionId === match[1]
|
|
172
|
+
&& (!cached.sessionId || cached.sessionId === pinnedSession)) {
|
|
173
|
+
// Clear unpinned fast-mode state too: a force-refresh must not reuse it.
|
|
174
|
+
if (id.state.interactiveSessionId === match[1]) {
|
|
175
|
+
id.state.interactiveSessionId = null;
|
|
176
|
+
id.state.interactiveTabId = null;
|
|
177
|
+
}
|
|
178
|
+
if (id.state.affinitySessionId === match[1])
|
|
179
|
+
id.state.affinitySessionId = null;
|
|
180
|
+
const refreshed = await resolutionRefresh.run(true, () => resolveSession(cached.sessionId, cached.autoCreate, cached.tabId, { platform: cached.platform === true }));
|
|
181
|
+
if (!('error' in refreshed)) {
|
|
182
|
+
const nextPath = path.replace(`/sessions/${match[1]}/`, `/sessions/${refreshed.sessionId}/`);
|
|
183
|
+
const nextBody = body ? { ...body, tabId: refreshed.tabId } : undefined;
|
|
184
|
+
const url = new URL(nextPath, BASE_URL);
|
|
185
|
+
if (refreshed.tabId)
|
|
186
|
+
url.searchParams.set('tabId', refreshed.tabId);
|
|
187
|
+
else
|
|
188
|
+
url.searchParams.delete('tabId');
|
|
189
|
+
return requestOnce(method, `${url.pathname}${url.search}`, nextBody, timeout);
|
|
190
|
+
}
|
|
191
|
+
// Recovery failed: report why (e.g. "MoreLogin connect failed: …"), not the
|
|
192
|
+
// bare "Session not found" that triggered it. Nothing was started.
|
|
193
|
+
return { ...result, error: refreshed.error, recoveryFailed: true };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// The server refused a session that does not serve the default browser (the
|
|
197
|
+
// settings changed under a cached route): forget it, so the next call resolves
|
|
198
|
+
// the default browser. Not retried here: the page the call meant is in the other browser.
|
|
199
|
+
if (result.code === 'NOT_DEFAULT_BROWSER' && match) {
|
|
200
|
+
const id = getIdentity();
|
|
201
|
+
resolvedRoutes.delete(id);
|
|
202
|
+
if (id.state.interactiveSessionId === match[1]) {
|
|
203
|
+
id.state.interactiveSessionId = null;
|
|
204
|
+
id.state.interactiveTabId = null;
|
|
205
|
+
}
|
|
206
|
+
if (id.state.affinitySessionId === match[1])
|
|
207
|
+
id.state.affinitySessionId = null;
|
|
208
|
+
}
|
|
209
|
+
if (context && result.error)
|
|
210
|
+
context.errors.push(result);
|
|
211
|
+
else if (context && typeof result.snapshotError === 'string') {
|
|
212
|
+
context.errors.push({ error: result.snapshotError, code: 'SNAPSHOT_FAILED' });
|
|
213
|
+
}
|
|
214
|
+
return result;
|
|
215
|
+
}
|
|
216
|
+
export async function reportRuntimeMcpProfile(profile, options = {}) {
|
|
217
|
+
if (!String(process.env.SYNABUN_TERMINAL_SESSION || '').trim()) {
|
|
218
|
+
return { reported: false, hostRefresh: 'notification' };
|
|
219
|
+
}
|
|
220
|
+
const result = await request('POST', '/api/mcp/runtime-profile', {
|
|
221
|
+
profile,
|
|
222
|
+
catalogMode: options.catalogMode || 'profiled',
|
|
223
|
+
}, 2_000);
|
|
224
|
+
if (result.ok) {
|
|
225
|
+
const hostRefresh = result.hostRefresh === 'scheduled'
|
|
226
|
+
|| result.hostRefresh === 'notification'
|
|
227
|
+
|| result.hostRefresh === 'not-needed'
|
|
228
|
+
? result.hostRefresh
|
|
229
|
+
: 'unavailable';
|
|
230
|
+
const runtimeKind = result.runtimeKind === 'opencode' || result.runtimeKind === 'codex' || result.runtimeKind === 'loop'
|
|
231
|
+
? result.runtimeKind
|
|
232
|
+
: undefined;
|
|
233
|
+
return {
|
|
234
|
+
reported: true,
|
|
235
|
+
hostRefresh,
|
|
236
|
+
runtimeKind,
|
|
237
|
+
correlationId: typeof result.correlationId === 'string' ? result.correlationId : undefined,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
reported: false,
|
|
242
|
+
hostRefresh: 'unavailable',
|
|
243
|
+
error: typeof result.error === 'string' ? result.error : 'Runtime profile report failed',
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
// All per-caller identity state (recovery cache, session affinity, interactive
|
|
247
|
+
// tab cache, ancestor-PID pins) lives on the CallerIdentity object resolved by
|
|
248
|
+
// getIdentity() — per HTTP caller over the HTTP transport, a per-process
|
|
249
|
+
// singleton for stdio. Module-level versions of this state were the root cause
|
|
250
|
+
// of cross-automation tab collisions: every HTTP caller shared them.
|
|
251
|
+
// Join the ONE shared browser with a dedicated, owned tab (instead of launching a
|
|
252
|
+
// second browser on a persistent profile, which fails with "profile is locked").
|
|
253
|
+
async function acquireInteractive(id, url) {
|
|
254
|
+
const resp = await request('POST', '/api/browser/acquire', {
|
|
255
|
+
clientId: id.clientId,
|
|
256
|
+
url: url || 'about:blank',
|
|
257
|
+
}, SESSION_CREATE_TIMEOUT);
|
|
258
|
+
if (resp.error || !resp.sessionId) {
|
|
259
|
+
return { error: `Failed to acquire a shared browser tab: ${resp.error || 'no session returned'}` };
|
|
260
|
+
}
|
|
261
|
+
id.state.interactiveSessionId = resp.sessionId;
|
|
262
|
+
id.state.interactiveTabId = resp.tabId || null;
|
|
263
|
+
id.state.affinitySessionId = id.state.interactiveSessionId;
|
|
264
|
+
return { sessionId: id.state.interactiveSessionId, tabId: id.state.interactiveTabId || undefined };
|
|
265
|
+
}
|
|
266
|
+
function adoptCreatedSession(id, created, tabId) {
|
|
267
|
+
const sessionId = created.sessionId;
|
|
268
|
+
id.state.affinitySessionId = sessionId;
|
|
269
|
+
return { sessionId, tabId };
|
|
270
|
+
}
|
|
271
|
+
// Pages (localhost included) only run where the server says the default browser
|
|
272
|
+
// is. Absent servesDefault (older server, or a managed / real-Chrome setup) keeps
|
|
273
|
+
// the previous behavior.
|
|
274
|
+
function servesDefault(s) {
|
|
275
|
+
return s.servesDefault !== false;
|
|
276
|
+
}
|
|
277
|
+
function describeSession(s) {
|
|
278
|
+
return `${s.profileMode || 'unknown'} mode${s.moreloginEnvId ? `, MoreLogin env ${s.moreloginEnvId}` : ''}`;
|
|
279
|
+
}
|
|
280
|
+
function describeDefault(list) {
|
|
281
|
+
const def = list.defaultBrowser;
|
|
282
|
+
if (def?.connectMode === 'morelogin')
|
|
283
|
+
return `MoreLogin${def.moreloginEnvId ? ` env ${def.moreloginEnvId}` : ''}`;
|
|
284
|
+
return 'the configured browser';
|
|
285
|
+
}
|
|
286
|
+
// Best-effort release of an identity's owned tab, so the shared browser can be
|
|
287
|
+
// grace-reaped once no owners remain. Fire-and-forget — never blocks shutdown.
|
|
288
|
+
// Also registered as the identity-eviction hook (HTTP DELETE / idle TTL).
|
|
289
|
+
function releaseTabFor(id) {
|
|
290
|
+
if (!id.state.interactiveSessionId)
|
|
291
|
+
return;
|
|
292
|
+
try {
|
|
293
|
+
void fetch(`${BASE_URL}/api/browser/release`, {
|
|
294
|
+
method: 'POST',
|
|
295
|
+
headers: { 'Content-Type': 'application/json' },
|
|
296
|
+
body: JSON.stringify({ clientId: id.clientId }),
|
|
297
|
+
}).catch(() => { });
|
|
298
|
+
}
|
|
299
|
+
catch { /* best-effort */ }
|
|
300
|
+
}
|
|
301
|
+
setReleaseHook(releaseTabFor);
|
|
302
|
+
// Process exit hooks only matter for stdio (one process per caller). In HTTP
|
|
303
|
+
// mode the NI server hosts many identities — their tabs are released by MCP
|
|
304
|
+
// session DELETE or idle eviction, and an NI shutdown takes the browser with it.
|
|
305
|
+
function releaseOnExit() {
|
|
306
|
+
if (isHttpMode())
|
|
307
|
+
return;
|
|
308
|
+
const stdio = peekStdioIdentity();
|
|
309
|
+
if (stdio)
|
|
310
|
+
releaseTabFor(stdio);
|
|
311
|
+
}
|
|
312
|
+
process.once('exit', releaseOnExit);
|
|
313
|
+
// SIGTERM / SIGINT end a stdio server here: release its tab, exit 0. Served
|
|
314
|
+
// over HTTP, the process belongs to its host. The Neural Interface runs
|
|
315
|
+
// mcp-server/dist in process and owns these signals (server.js
|
|
316
|
+
// gracefulShutdown: WhatsApp Link, terminal host, then the database); this
|
|
317
|
+
// listener is registered before its listeners, so exiting here would preempt
|
|
318
|
+
// all of them. The mode is read when the signal arrives, not at import:
|
|
319
|
+
// server.js loads this module through its static imports, long before
|
|
320
|
+
// createMcpRoutes() calls markHttpMode(). A host with no listener of its own
|
|
321
|
+
// (the standalone dist/http.js) still exits here, because registering this
|
|
322
|
+
// listener already took Node's default exit on the signal away from it.
|
|
323
|
+
function exitOnSignal(signal) {
|
|
324
|
+
const onSignal = () => {
|
|
325
|
+
if (isHttpMode() && process.listeners(signal).some((listener) => listener !== onSignal))
|
|
326
|
+
return;
|
|
327
|
+
releaseOnExit();
|
|
328
|
+
process.exit(0);
|
|
329
|
+
};
|
|
330
|
+
return onSignal;
|
|
331
|
+
}
|
|
332
|
+
process.once('SIGTERM', exitOnSignal('SIGTERM'));
|
|
333
|
+
process.once('SIGINT', exitOnSignal('SIGINT'));
|
|
334
|
+
// Ancestor-PID fallback (Layer B). Walks the process tree once and caches the
|
|
335
|
+
// resolved loop pins on the identity. Used when codex/opencode strip
|
|
336
|
+
// SYNABUN_BROWSER_* env on MCP child spawn — we map our PID chain up to a known
|
|
337
|
+
// PTY and pull the loop's session/tab IDs from that loop's state file.
|
|
338
|
+
// Bounded retry instead of a permanent single-shot latch: a fast codex/opencode
|
|
339
|
+
// exec spawn can call MCP before its PTY is registered server-side, so the first
|
|
340
|
+
// ancestor lookup misses. Retry a few times until matched, then give up.
|
|
341
|
+
const ANCESTOR_MAX_ATTEMPTS = 4;
|
|
342
|
+
async function getAncestorPids() {
|
|
343
|
+
const ppid = typeof process.ppid === 'number' ? process.ppid : 0;
|
|
344
|
+
if (!ppid)
|
|
345
|
+
return [];
|
|
346
|
+
const pids = [ppid];
|
|
347
|
+
const isWin = process.platform === 'win32';
|
|
348
|
+
const { exec } = await import('node:child_process');
|
|
349
|
+
const runCmd = (cmd) => new Promise((resolve) => {
|
|
350
|
+
exec(cmd, { timeout: 1500, windowsHide: true }, (_err, stdout) => resolve(stdout || ''));
|
|
351
|
+
});
|
|
352
|
+
let current = ppid;
|
|
353
|
+
for (let i = 0; i < 6; i++) {
|
|
354
|
+
let parent = 0;
|
|
355
|
+
try {
|
|
356
|
+
if (isWin) {
|
|
357
|
+
const out = await runCmd(`wmic process where ProcessId=${current} get ParentProcessId /value`);
|
|
358
|
+
const m = /ParentProcessId=(\d+)/i.exec(out);
|
|
359
|
+
parent = m ? Number(m[1]) : 0;
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
const out = await runCmd(`ps -o ppid= -p ${current}`);
|
|
363
|
+
parent = Number(out.trim().split(/\s+/)[0]) || 0;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
catch {
|
|
367
|
+
parent = 0;
|
|
368
|
+
}
|
|
369
|
+
if (!parent || parent === 1 || parent === current)
|
|
370
|
+
break;
|
|
371
|
+
pids.push(parent);
|
|
372
|
+
current = parent;
|
|
373
|
+
}
|
|
374
|
+
return pids;
|
|
375
|
+
}
|
|
376
|
+
async function resolveFromAncestors(id) {
|
|
377
|
+
// Over HTTP this code runs in the Neural Interface's own process — walking
|
|
378
|
+
// OUR pid chain would resolve the NI server, not the caller. HTTP callers
|
|
379
|
+
// carry their identity in headers/Mcp-Session-Id instead.
|
|
380
|
+
if (id.source !== 'stdio')
|
|
381
|
+
return;
|
|
382
|
+
if (id.state.ancestorPinnedSession)
|
|
383
|
+
return; // already resolved
|
|
384
|
+
if (id.state.ancestorAttempts >= ANCESTOR_MAX_ATTEMPTS)
|
|
385
|
+
return; // give up after N misses
|
|
386
|
+
id.state.ancestorAttempts++;
|
|
387
|
+
try {
|
|
388
|
+
const pids = await getAncestorPids();
|
|
389
|
+
if (pids.length === 0)
|
|
390
|
+
return;
|
|
391
|
+
const resp = await request('POST', '/api/loop/resolve-from-ancestors', { pids }, 2000);
|
|
392
|
+
// Capture the owning terminalSessionId whenever a PTY matched (even if its
|
|
393
|
+
// loop file lacked browser pins) — it's needed for the X-Synabun-Terminal header.
|
|
394
|
+
if (resp.terminalSessionId)
|
|
395
|
+
id.state.ancestorPinnedTerminal = resp.terminalSessionId;
|
|
396
|
+
if (resp.matched) {
|
|
397
|
+
id.state.ancestorPinnedSession = resp.browserSessionId || null;
|
|
398
|
+
id.state.ancestorPinnedTab = resp.browserTabId || null;
|
|
399
|
+
console.error(`[MCP] ancestor lookup matched: session=${id.state.ancestorPinnedSession} tab=${id.state.ancestorPinnedTab} terminal=${id.state.ancestorPinnedTerminal}`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
catch { /* best-effort */ }
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Resolve which session ID to use.
|
|
406
|
+
* - If sessionId provided, return it immediately (server returns 404 if invalid).
|
|
407
|
+
* - If 1 session exists, auto-select it.
|
|
408
|
+
* - If 0 sessions exist and autoCreate is true, create one.
|
|
409
|
+
* - If multiple sessions and no ID, return error listing them.
|
|
410
|
+
*/
|
|
411
|
+
async function resolveSessionUncached(sessionId, autoCreate, tabId, platform = false) {
|
|
412
|
+
// Per-caller identity: pins come from launch headers (HTTP) or live env
|
|
413
|
+
// (stdio); all caches below live on the identity, never module-level.
|
|
414
|
+
const id = getIdentity();
|
|
415
|
+
const pins = effectivePins(id);
|
|
416
|
+
// Every page tool runs in the default browser only. An explicit id the server
|
|
417
|
+
// says does not serve it (managed Chrome, or another MoreLogin env while
|
|
418
|
+
// MoreLogin is the default) is dropped for a navigation (localhost included)
|
|
419
|
+
// or a platform tool, and the default browser resolved instead; any other page
|
|
420
|
+
// tool is refused, since the page it names is in the other browser. The
|
|
421
|
+
// server refuses them too (NOT_DEFAULT_BROWSER).
|
|
422
|
+
const wantsDefaultBrowser = platform || !!autoCreate;
|
|
423
|
+
if (sessionId && sessionId !== (pins.browserSessionId || id.state.ancestorPinnedSession)) {
|
|
424
|
+
const listed = await request('GET', '/api/browser/sessions');
|
|
425
|
+
const named = (listed.sessions || []).find(s => s.id === sessionId);
|
|
426
|
+
if (named && !servesDefault(named)) {
|
|
427
|
+
if (!wantsDefaultBrowser) {
|
|
428
|
+
return { error: `Browser session ${sessionId} is not the default browser (${describeSession(named)}; the default is ${describeDefault(listed)}), so SynaBun's browser tools do not act on it. Leave sessionId out: browser_navigate opens the page in the default browser.` };
|
|
429
|
+
}
|
|
430
|
+
console.error(`[MCP] not using session ${sessionId} (${describeSession(named)}) — resolving ${describeDefault(listed)}`);
|
|
431
|
+
sessionId = undefined;
|
|
432
|
+
tabId = undefined;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
// Resolve tab ID from explicit param or pin.
|
|
436
|
+
// When a tab is pinned (loop/agent context), the pin wins even if the caller
|
|
437
|
+
// passes a different tabId — prevents tab-leak across loops.
|
|
438
|
+
// If pins are missing (codex/opencode env-strip case), try ancestor-PID
|
|
439
|
+
// lookup (stdio only) and use whatever the Neural Interface reports for our PTY.
|
|
440
|
+
if (!pins.browserSessionId && !pins.browserTabId && !sessionId) {
|
|
441
|
+
await resolveFromAncestors(id);
|
|
442
|
+
}
|
|
443
|
+
const pinnedTab = pins.browserTabId || id.state.ancestorPinnedTab || undefined;
|
|
444
|
+
const resolvedTabId = pinnedTab || tabId || undefined;
|
|
445
|
+
if (pinnedTab && tabId && tabId !== pinnedTab) {
|
|
446
|
+
console.error(`[MCP] tabId override ignored: pinned=${pinnedTab} requested=${tabId}`);
|
|
447
|
+
}
|
|
448
|
+
// Agent/loop-scoped browser session — set by the orchestrator to pin
|
|
449
|
+
// this caller to a specific browser session (multi-session isolation).
|
|
450
|
+
// If pinned session died, check recovery cache first, then auto-create.
|
|
451
|
+
const pinnedSession = pins.browserSessionId || id.state.ancestorPinnedSession || undefined;
|
|
452
|
+
// Loop prompts intentionally pass their injected sessionId/tabId on every
|
|
453
|
+
// call. Treat an explicit session that matches the pin as pinned traffic too;
|
|
454
|
+
// otherwise the old fast path skipped liveness checks and returned a stale
|
|
455
|
+
// tab forever after a renderer/page closed.
|
|
456
|
+
if (pinnedSession && (!sessionId || sessionId === pinnedSession)) {
|
|
457
|
+
// Check recovery cache first — avoids re-creating on every call after recovery.
|
|
458
|
+
// Return the RECOVERED tab, never the stale pinned tab (which 404s).
|
|
459
|
+
if (id.state.recoveredSessionId) {
|
|
460
|
+
const recheck = await request('GET', '/api/browser/sessions');
|
|
461
|
+
const alive = (recheck.sessions || []).find(s => s.id === id.state.recoveredSessionId);
|
|
462
|
+
if (alive)
|
|
463
|
+
return { sessionId: id.state.recoveredSessionId, tabId: id.state.recoveredTabId || undefined };
|
|
464
|
+
id.state.recoveredSessionId = null; // recovered session also died — try fresh recovery
|
|
465
|
+
id.state.recoveredTabId = null;
|
|
466
|
+
}
|
|
467
|
+
const check = await request('GET', '/api/browser/sessions');
|
|
468
|
+
const active = (check.sessions || []).find(s => s.id === pinnedSession);
|
|
469
|
+
// A run's pinned browser must be the default one. Hard-fail rather than work
|
|
470
|
+
// in the wrong browser.
|
|
471
|
+
if (active && !servesDefault(active)) {
|
|
472
|
+
return { error: `Pinned browser session ${pinnedSession} is not the default browser (${describeSession(active)}; the default is ${describeDefault(check)}), so this run will not use it. Start the run again so it acquires the default browser.` };
|
|
473
|
+
}
|
|
474
|
+
if (active) {
|
|
475
|
+
// Also verify the resolved tab still exists in the session; if not, recover.
|
|
476
|
+
const tabList = active.tabs;
|
|
477
|
+
const tabAlive = !resolvedTabId || !tabList || tabList.some(t => t.id === resolvedTabId);
|
|
478
|
+
if (tabAlive)
|
|
479
|
+
return { sessionId: pinnedSession, tabId: resolvedTabId };
|
|
480
|
+
console.error(`[MCP] Pinned tab ${resolvedTabId} not found in active session ${pinnedSession} — recovering`);
|
|
481
|
+
const terminalSessionId = pins.terminalSessionId || undefined;
|
|
482
|
+
const recovered = await request('POST', '/api/loop/recover-browser', terminalSessionId ? { terminalSessionId } : {}, SESSION_CREATE_TIMEOUT);
|
|
483
|
+
if (!recovered.error && recovered.sessionId) {
|
|
484
|
+
id.state.recoveredSessionId = recovered.sessionId;
|
|
485
|
+
id.state.recoveredTabId = recovered.tabId || null;
|
|
486
|
+
return { sessionId: id.state.recoveredSessionId, tabId: id.state.recoveredTabId || undefined };
|
|
487
|
+
}
|
|
488
|
+
return { sessionId: pinnedSession, tabId: resolvedTabId }; // fall through to old tab (will fail gracefully)
|
|
489
|
+
}
|
|
490
|
+
// Pinned session is gone — rejoin the SHARED loop browser with a fresh owned
|
|
491
|
+
// tab (not an isolated new browser), and adopt the NEW tabId. Forwarding the
|
|
492
|
+
// stale pinned tab into a different session would 404 every subsequent call.
|
|
493
|
+
console.error(`[MCP] Pinned browser session ${pinnedSession} is gone — recovering via shared loop browser`);
|
|
494
|
+
const terminalSessionId = pins.terminalSessionId || undefined;
|
|
495
|
+
const recovered = await request('POST', '/api/loop/recover-browser', terminalSessionId ? { terminalSessionId } : {}, SESSION_CREATE_TIMEOUT);
|
|
496
|
+
if (recovered.error || !recovered.sessionId) {
|
|
497
|
+
return { error: `Pinned browser session ${pinnedSession} is no longer available and recovery failed: ${recovered.error || 'no session returned'}` };
|
|
498
|
+
}
|
|
499
|
+
id.state.recoveredSessionId = recovered.sessionId;
|
|
500
|
+
id.state.recoveredTabId = recovered.tabId || null;
|
|
501
|
+
return { sessionId: id.state.recoveredSessionId, tabId: id.state.recoveredTabId || undefined };
|
|
502
|
+
}
|
|
503
|
+
if (sessionId) {
|
|
504
|
+
// Checked above against the default browser; the server 404s a session that
|
|
505
|
+
// does not exist. The route cache spares the check on the next calls.
|
|
506
|
+
id.state.affinitySessionId = sessionId;
|
|
507
|
+
return { sessionId, tabId: resolvedTabId };
|
|
508
|
+
}
|
|
509
|
+
// Reuse the dedicated tab THIS caller already acquired in the shared
|
|
510
|
+
// browser (set by a prior acquireInteractive). The X-Synabun-Terminal header routes
|
|
511
|
+
// tab-less calls to it, but returning the tabId keeps routing robust if the header
|
|
512
|
+
// is ever dropped. Re-acquired below if the underlying session has since died.
|
|
513
|
+
if (!sessionId && id.state.interactiveSessionId) {
|
|
514
|
+
if (isBrowserFastMode()) {
|
|
515
|
+
// Fast mode trusts the cache without a verify round-trip.
|
|
516
|
+
return { sessionId: id.state.interactiveSessionId, tabId: resolvedTabId || id.state.interactiveTabId || undefined };
|
|
517
|
+
}
|
|
518
|
+
const check = await request('GET', '/api/browser/sessions');
|
|
519
|
+
const alive = (check.sessions || []).find(s => s.id === id.state.interactiveSessionId);
|
|
520
|
+
if (alive && servesDefault(alive))
|
|
521
|
+
return { sessionId: id.state.interactiveSessionId, tabId: resolvedTabId || id.state.interactiveTabId || undefined };
|
|
522
|
+
id.state.interactiveSessionId = null;
|
|
523
|
+
id.state.interactiveTabId = null; // session gone — fall through to re-acquire
|
|
524
|
+
}
|
|
525
|
+
// Codex fast mode favors one direct create call on first navigate. This avoids
|
|
526
|
+
// the list-sessions round trip that dominates short browser flows. If the profile
|
|
527
|
+
// is persistent, a second launchPersistentContext fails with "profile is locked" —
|
|
528
|
+
// fall back to acquiring a dedicated tab in the shared browser instead.
|
|
529
|
+
if (autoCreate && isBrowserFastMode()) {
|
|
530
|
+
const created = await request('POST', '/api/browser/sessions', {
|
|
531
|
+
url: autoCreate.url || 'about:blank',
|
|
532
|
+
}, SESSION_CREATE_TIMEOUT);
|
|
533
|
+
if (created.error) {
|
|
534
|
+
if (/lock/i.test(created.error))
|
|
535
|
+
return acquireInteractive(id, autoCreate.url);
|
|
536
|
+
return { error: `Failed to auto-create session: ${created.error}` };
|
|
537
|
+
}
|
|
538
|
+
return adoptCreatedSession(id, created, resolvedTabId);
|
|
539
|
+
}
|
|
540
|
+
// List sessions (single GET used for both affinity check and auto-selection)
|
|
541
|
+
const data = await request('GET', '/api/browser/sessions');
|
|
542
|
+
if (data.error)
|
|
543
|
+
return { error: data.error };
|
|
544
|
+
const allSessions = (data.sessions || []);
|
|
545
|
+
// Check affinity — reuse session this caller previously used/created
|
|
546
|
+
if (id.state.affinitySessionId) {
|
|
547
|
+
const affinityAlive = allSessions.find(s => s.id === id.state.affinitySessionId);
|
|
548
|
+
if (affinityAlive && servesDefault(affinityAlive)) {
|
|
549
|
+
return { sessionId: id.state.affinitySessionId, tabId: resolvedTabId };
|
|
550
|
+
}
|
|
551
|
+
id.state.affinitySessionId = null; // session gone (or not the default browser), clear affinity
|
|
552
|
+
}
|
|
553
|
+
// Interactive sessions (no pinned env var) must not grab loop/agent/interactive-owned
|
|
554
|
+
// sessions. Pinned sessions already returned above; explicit sessionId trusted above.
|
|
555
|
+
// Never adopt or auto-select a browser that is not the default one for normal pages.
|
|
556
|
+
const sessions = allSessions.filter(s => !s.loopOwned && !s.agentOwned && !s.interactiveOwned && servesDefault(s));
|
|
557
|
+
// Under a persistent profile, a second launchPersistentContext fails with "profile is
|
|
558
|
+
// locked", and any owned session means a shared persistent browser is already running.
|
|
559
|
+
// In those cases, don't try to spawn a separate browser — join the ONE shared browser
|
|
560
|
+
// with a dedicated, owned tab. For a clean profile with no owners, keep the historical
|
|
561
|
+
// separate-browser behavior (no lock, no regression).
|
|
562
|
+
const lockRisk = allSessions.some(s => s.persistent || s.loopOwned || s.agentOwned || s.interactiveOwned);
|
|
563
|
+
const autoCreateSession = async () => {
|
|
564
|
+
if (lockRisk)
|
|
565
|
+
return acquireInteractive(id, autoCreate?.url);
|
|
566
|
+
const created = await request('POST', '/api/browser/sessions', {
|
|
567
|
+
url: autoCreate?.url || 'about:blank',
|
|
568
|
+
}, SESSION_CREATE_TIMEOUT);
|
|
569
|
+
if (created.error) {
|
|
570
|
+
if (/lock/i.test(created.error))
|
|
571
|
+
return acquireInteractive(id, autoCreate?.url);
|
|
572
|
+
return { error: `Failed to auto-create session: ${created.error}` };
|
|
573
|
+
}
|
|
574
|
+
return adoptCreatedSession(id, created, resolvedTabId);
|
|
575
|
+
};
|
|
576
|
+
// If autoCreate is available (browser_navigate) and unowned sessions exist but none
|
|
577
|
+
// are ours (no affinity), create/acquire our own instead of hijacking another caller's.
|
|
578
|
+
// This prevents sidepanel from grabbing the CLI's session and vice versa.
|
|
579
|
+
if (sessions.length > 0 && autoCreate) {
|
|
580
|
+
return autoCreateSession();
|
|
581
|
+
}
|
|
582
|
+
if (sessions.length === 1) {
|
|
583
|
+
// No autoCreate — caller wants to interact with an existing page (click, snapshot, etc.).
|
|
584
|
+
// Adopting is ONLY safe for a pristine, unowned session (e.g. a page the user opened
|
|
585
|
+
// manually in the NI UI). If ANOTHER automation already owns a tab here (it plain-created
|
|
586
|
+
// the session or acquired a tab — see _tabOwners), adopting makes us a tab-less freeloader
|
|
587
|
+
// that FAILS CLOSED (404) the moment the session goes multi-tab — the sidepanel-vs-CLI
|
|
588
|
+
// collision. In that case acquire our OWN dedicated tab in the shared browser instead.
|
|
589
|
+
const myTerminalId = terminalIdFor(id);
|
|
590
|
+
const loneOwners = sessions[0].tabOwners || {};
|
|
591
|
+
const ownedByOther = Object.keys(loneOwners).some(k => k !== id.clientId && k !== myTerminalId);
|
|
592
|
+
if (ownedByOther) {
|
|
593
|
+
return acquireInteractive(id, autoCreate?.url);
|
|
594
|
+
}
|
|
595
|
+
id.state.affinitySessionId = sessions[0].id;
|
|
596
|
+
return { sessionId: sessions[0].id, tabId: resolvedTabId };
|
|
597
|
+
}
|
|
598
|
+
if (sessions.length === 0) {
|
|
599
|
+
if (autoCreate) {
|
|
600
|
+
return autoCreateSession();
|
|
601
|
+
}
|
|
602
|
+
const ownedCount = allSessions.length - sessions.length;
|
|
603
|
+
if (ownedCount > 0) {
|
|
604
|
+
// Active automations hold the shared browser and there is no unowned session for
|
|
605
|
+
// us. Don't grab their tab and don't error — acquire our OWN dedicated tab so even
|
|
606
|
+
// a tab-less first tool (snapshot/click) is isolated. about:blank is fine; a later
|
|
607
|
+
// navigate reuses this same owned tab via the X-Synabun-Terminal routing.
|
|
608
|
+
return acquireInteractive(id, undefined);
|
|
609
|
+
}
|
|
610
|
+
return { error: 'No browser sessions open. Use browser_session to create one first, or use browser_navigate with a URL to auto-create.' };
|
|
611
|
+
}
|
|
612
|
+
// Multiple available sessions — require explicit ID
|
|
613
|
+
const list = sessions.map(s => ` ${s.id} — ${s.title || s.url}`).join('\n');
|
|
614
|
+
return { error: `Multiple browser sessions open. Specify sessionId:\n${list}` };
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Per-caller route cache. Only the server can declare an action safe to retry.
|
|
618
|
+
* `platform` (or a withPlatformRoute scope) marks a platform tool call: like a
|
|
619
|
+
* navigation, it only runs in the default browser.
|
|
620
|
+
*/
|
|
621
|
+
export async function resolveSession(sessionId, autoCreate, tabId, opts = {}) {
|
|
622
|
+
const context = batchContext.getStore();
|
|
623
|
+
if (context)
|
|
624
|
+
return context.route;
|
|
625
|
+
const startedAt = performance.now();
|
|
626
|
+
const id = getIdentity();
|
|
627
|
+
const platform = opts.platform === true || inPlatformRoute();
|
|
628
|
+
const key = routeKey(id, sessionId, tabId, platform || !!autoCreate);
|
|
629
|
+
const cached = resolvedRoutes.get(id);
|
|
630
|
+
if (isBrowserV2Enabled() && !resolutionRefresh.getStore() && cached?.key === key) {
|
|
631
|
+
browserMetric({ phase: 'session-resolution', cached: true, durationMs: performance.now() - startedAt });
|
|
632
|
+
return { ...cached.route };
|
|
633
|
+
}
|
|
634
|
+
const result = await resolveSessionUncached(sessionId, autoCreate, tabId, platform);
|
|
635
|
+
if (!('error' in result))
|
|
636
|
+
resolvedRoutes.set(id, { key: routeKey(id, sessionId, tabId, platform || !!autoCreate), route: { ...result }, sessionId, tabId, autoCreate, platform });
|
|
637
|
+
browserMetric({ phase: 'session-resolution', cached: false, durationMs: performance.now() - startedAt });
|
|
638
|
+
return result;
|
|
639
|
+
}
|
|
640
|
+
/** Batches require a concrete tab owned by this caller, verified once up front. */
|
|
641
|
+
export async function resolveBatchRoute(sessionId, tabId) {
|
|
642
|
+
const resolved = await resolveSession(sessionId, undefined, tabId);
|
|
643
|
+
if ('error' in resolved)
|
|
644
|
+
return resolved;
|
|
645
|
+
const result = await listSessions();
|
|
646
|
+
if (result.error)
|
|
647
|
+
return { error: result.error };
|
|
648
|
+
const session = result.sessions?.find(s => s.id === resolved.sessionId);
|
|
649
|
+
const id = getIdentity();
|
|
650
|
+
const ownedTabs = [session?.tabOwners?.[terminalIdFor(id)], session?.tabOwners?.[id.clientId]].filter(Boolean);
|
|
651
|
+
const ownedTab = resolved.tabId || ownedTabs[0];
|
|
652
|
+
if (!ownedTab || !ownedTabs.includes(ownedTab)) {
|
|
653
|
+
return { error: 'browser_batch requires a tab owned by this caller. Use browser_navigate to acquire a tab first.' };
|
|
654
|
+
}
|
|
655
|
+
return { sessionId: resolved.sessionId, tabId: ownedTab };
|
|
656
|
+
}
|
|
657
|
+
// ── Cache invalidation ──
|
|
658
|
+
export async function invalidateCache(reason, id) {
|
|
659
|
+
try {
|
|
660
|
+
// Passing the changed memory id lets the NI patch its link cache
|
|
661
|
+
// incrementally instead of recomputing all pairwise links.
|
|
662
|
+
await request('POST', '/api/cache/invalidate', { reason, id });
|
|
663
|
+
}
|
|
664
|
+
catch {
|
|
665
|
+
// Fire-and-forget — don't block MCP tools if Neural Interface is down
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
// ── Session management ──
|
|
669
|
+
export async function listSessions() {
|
|
670
|
+
return request('GET', '/api/browser/sessions');
|
|
671
|
+
}
|
|
672
|
+
export async function createSession(url) {
|
|
673
|
+
return request('POST', '/api/browser/sessions', {
|
|
674
|
+
url: url || 'about:blank',
|
|
675
|
+
}, SESSION_CREATE_TIMEOUT);
|
|
676
|
+
}
|
|
677
|
+
export async function closeSession(sessionId) {
|
|
678
|
+
return request('DELETE', `/api/browser/sessions/${sessionId}`);
|
|
679
|
+
}
|
|
680
|
+
// ── Navigation ──
|
|
681
|
+
export async function navigate(sessionId, url, tabId, returnSnapshot, snapshot, snapshotOptions, assist) {
|
|
682
|
+
return request('POST', `/api/browser/sessions/${sessionId}/navigate`, {
|
|
683
|
+
url,
|
|
684
|
+
...(isBrowserCompactMode() && { compact: true }),
|
|
685
|
+
...(snapshot && { snapshot }),
|
|
686
|
+
...(isBrowserV2Enabled() && { snapshotMaxChars: 12000 }),
|
|
687
|
+
...snapshotOptions,
|
|
688
|
+
...(returnSnapshot && { returnSnapshot }),
|
|
689
|
+
...(assist?.semanticContext && { semanticContext: true }),
|
|
690
|
+
...(tabId && { tabId }),
|
|
691
|
+
}, LONG_TIMEOUT);
|
|
692
|
+
}
|
|
693
|
+
export async function goBack(sessionId, tabId) {
|
|
694
|
+
return request('POST', `/api/browser/sessions/${sessionId}/back`, { ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) });
|
|
695
|
+
}
|
|
696
|
+
export async function goForward(sessionId, tabId) {
|
|
697
|
+
return request('POST', `/api/browser/sessions/${sessionId}/forward`, { ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) });
|
|
698
|
+
}
|
|
699
|
+
export async function reload(sessionId, tabId) {
|
|
700
|
+
return request('POST', `/api/browser/sessions/${sessionId}/reload`, { ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) }, LONG_TIMEOUT);
|
|
701
|
+
}
|
|
702
|
+
// ── Interaction (ref- or selector-based) ──
|
|
703
|
+
export async function click(sessionId, selector, nthMatch, tabId, textHint, returnSnapshot, ref, snapshot, snapshotOptions, assist) {
|
|
704
|
+
return request('POST', `/api/browser/sessions/${sessionId}/click`, {
|
|
705
|
+
...(selector && { selector }),
|
|
706
|
+
...(ref && { ref }),
|
|
707
|
+
...(nthMatch !== undefined && { nthMatch }),
|
|
708
|
+
...(textHint && { textHint }),
|
|
709
|
+
...(assist && { assist: true }),
|
|
710
|
+
...(isBrowserCompactMode() && { compact: true }),
|
|
711
|
+
...(snapshot && { snapshot }),
|
|
712
|
+
...(isBrowserV2Enabled() && { snapshotMaxChars: 6000 }),
|
|
713
|
+
...snapshotOptions,
|
|
714
|
+
...(returnSnapshot && { returnSnapshot }),
|
|
715
|
+
...(tabId && { tabId }),
|
|
716
|
+
}, CLICK_TIMEOUT);
|
|
717
|
+
}
|
|
718
|
+
export async function fill(sessionId, selector, value, nthMatch, tabId, textHint, ref, assist) {
|
|
719
|
+
return request('POST', `/api/browser/sessions/${sessionId}/fill`, { ...(selector && { selector }), ...(ref && { ref }), value, ...(assist && { assist: true }), ...(nthMatch !== undefined && { nthMatch }), ...(textHint && { textHint }), ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) });
|
|
720
|
+
}
|
|
721
|
+
export async function type(sessionId, selector, text, nthMatch, tabId, textHint, mode, ref, assist) {
|
|
722
|
+
// An explicit mode (including 'paragraphs') is always honored; only the unset case falls back to fast-mode insert.
|
|
723
|
+
const resolvedMode = mode || (isBrowserFastMode() ? 'insert' : 'sequential');
|
|
724
|
+
return request('POST', `/api/browser/sessions/${sessionId}/type`, { selector, ...(ref && { ref }), text, mode: resolvedMode, ...(assist && { assist: true }), ...(nthMatch !== undefined && { nthMatch }), ...(textHint && { textHint }), ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) });
|
|
725
|
+
}
|
|
726
|
+
export async function hover(sessionId, selector, nthMatch, tabId, textHint, ref, assist) {
|
|
727
|
+
return request('POST', `/api/browser/sessions/${sessionId}/hover`, { ...(selector && { selector }), ...(ref && { ref }), ...(assist && { assist: true }), ...(nthMatch !== undefined && { nthMatch }), ...(textHint && { textHint }), ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) });
|
|
728
|
+
}
|
|
729
|
+
export async function selectOption(sessionId, selector, value, nthMatch, tabId, ref, textHint, assist) {
|
|
730
|
+
return request('POST', `/api/browser/sessions/${sessionId}/select`, { ...(selector && { selector }), ...(ref && { ref }), value, ...(textHint && { textHint }), ...(assist && { assist: true }), ...(nthMatch !== undefined && { nthMatch }), ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) });
|
|
731
|
+
}
|
|
732
|
+
export async function pressKey(sessionId, key, tabId) {
|
|
733
|
+
return request('POST', `/api/browser/sessions/${sessionId}/press`, { key, ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) });
|
|
734
|
+
}
|
|
735
|
+
export async function scroll(sessionId, opts, tabId) {
|
|
736
|
+
return request('POST', `/api/browser/sessions/${sessionId}/scroll`, { ...(isBrowserV2Enabled() && { snapshotMaxChars: 12000 }), ...opts, ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) }, LONG_TIMEOUT);
|
|
737
|
+
}
|
|
738
|
+
export async function upload(sessionId, selector, filePaths, nthMatch, tabId, ref, textHint, assist) {
|
|
739
|
+
return request('POST', `/api/browser/sessions/${sessionId}/upload`, { ...(selector && { selector }), ...(ref && { ref }), filePaths, ...(textHint && { textHint }), ...(assist && { assist: true }), ...(nthMatch !== undefined && { nthMatch }), ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) }, LONG_TIMEOUT);
|
|
740
|
+
}
|
|
741
|
+
// ── Observation ──
|
|
742
|
+
export async function snapshot(sessionId, selector, tabId, opts) {
|
|
743
|
+
const hasOpts = !!(opts && (opts.mode || opts.viewport || opts.depth || opts.diff || opts.force || opts.maxChars || opts.baselineId || opts.includeFullText));
|
|
744
|
+
// Always POST when selector OR opts present (POST supports a body); GET only for bare defaults.
|
|
745
|
+
if (selector || hasOpts) {
|
|
746
|
+
return request('POST', `/api/browser/sessions/${sessionId}/snapshot`, {
|
|
747
|
+
...(selector && { selector }),
|
|
748
|
+
...(opts?.mode && { mode: opts.mode }),
|
|
749
|
+
...(opts?.viewport && { viewport: true }),
|
|
750
|
+
...(opts?.depth && { depth: opts.depth }),
|
|
751
|
+
...(opts?.diff && { diff: true }),
|
|
752
|
+
...(opts?.force && { force: true }),
|
|
753
|
+
...(opts?.maxChars && { maxChars: opts.maxChars }),
|
|
754
|
+
...(opts?.baselineId && { baselineId: opts.baselineId }),
|
|
755
|
+
// Intent ranking parses every ref of this capture even when only a diff is shown; never a second capture.
|
|
756
|
+
...(opts?.includeFullText && { includeFullText: true }),
|
|
757
|
+
...(tabId && { tabId }),
|
|
758
|
+
}, LONG_TIMEOUT);
|
|
759
|
+
}
|
|
760
|
+
const qs = tabId ? `?tabId=${tabId}` : '';
|
|
761
|
+
return request('GET', `/api/browser/sessions/${sessionId}/snapshot${qs}`);
|
|
762
|
+
}
|
|
763
|
+
export async function getContent(sessionId, tabId, opts) {
|
|
764
|
+
const params = new URLSearchParams();
|
|
765
|
+
if (tabId)
|
|
766
|
+
params.set('tabId', tabId);
|
|
767
|
+
if (opts?.maxChars)
|
|
768
|
+
params.set('maxChars', String(opts.maxChars));
|
|
769
|
+
if (opts?.offset)
|
|
770
|
+
params.set('offset', String(opts.offset));
|
|
771
|
+
if (opts?.selector)
|
|
772
|
+
params.set('selector', opts.selector);
|
|
773
|
+
const qs = params.size ? `?${params}` : '';
|
|
774
|
+
return request('GET', `/api/browser/sessions/${sessionId}/content${qs}`);
|
|
775
|
+
}
|
|
776
|
+
export async function getMarkdown(sessionId, tabId, opts) {
|
|
777
|
+
const params = new URLSearchParams();
|
|
778
|
+
if (tabId)
|
|
779
|
+
params.set('tabId', tabId);
|
|
780
|
+
if (opts?.maxChars)
|
|
781
|
+
params.set('maxChars', String(opts.maxChars));
|
|
782
|
+
if (opts?.offset)
|
|
783
|
+
params.set('offset', String(opts.offset));
|
|
784
|
+
if (opts?.selector)
|
|
785
|
+
params.set('selector', opts.selector);
|
|
786
|
+
const qs = params.size ? `?${params}` : '';
|
|
787
|
+
return request('GET', `/api/browser/sessions/${sessionId}/markdown${qs}`, undefined, LONG_TIMEOUT);
|
|
788
|
+
}
|
|
789
|
+
export async function fetchMarkdown(url, timeout) {
|
|
790
|
+
return request('POST', '/api/fetch-markdown', { url, timeout }, LONG_TIMEOUT);
|
|
791
|
+
}
|
|
792
|
+
export async function screenshot(sessionId, tabId, opts) {
|
|
793
|
+
const params = new URLSearchParams();
|
|
794
|
+
if (tabId)
|
|
795
|
+
params.set('tabId', tabId);
|
|
796
|
+
if (opts?.maxWidth !== undefined)
|
|
797
|
+
params.set('maxWidth', String(opts.maxWidth));
|
|
798
|
+
if (opts?.quality !== undefined)
|
|
799
|
+
params.set('quality', String(opts.quality));
|
|
800
|
+
if (opts?.width !== undefined)
|
|
801
|
+
params.set('width', String(opts.width));
|
|
802
|
+
if (opts?.height !== undefined)
|
|
803
|
+
params.set('height', String(opts.height));
|
|
804
|
+
if (opts?.fullPage)
|
|
805
|
+
params.set('fullPage', '1');
|
|
806
|
+
if (opts?.format)
|
|
807
|
+
params.set('format', opts.format);
|
|
808
|
+
if (opts?.save)
|
|
809
|
+
params.set('save', '1');
|
|
810
|
+
if (opts?.path)
|
|
811
|
+
params.set('path', opts.path);
|
|
812
|
+
const qs = params.size ? `?${params}` : '';
|
|
813
|
+
// A resized or full-page capture (and a saved file) takes longer than a plain one.
|
|
814
|
+
return request('GET', `/api/browser/sessions/${sessionId}/screenshot-base64${qs}`, undefined, LONG_TIMEOUT);
|
|
815
|
+
}
|
|
816
|
+
/** The tab's buffered console messages and page errors (browser_console). */
|
|
817
|
+
export async function consoleMessages(sessionId, tabId, opts) {
|
|
818
|
+
const params = new URLSearchParams();
|
|
819
|
+
if (tabId)
|
|
820
|
+
params.set('tabId', tabId);
|
|
821
|
+
if (opts?.level)
|
|
822
|
+
params.set('level', opts.level);
|
|
823
|
+
if (opts?.since)
|
|
824
|
+
params.set('since', opts.since);
|
|
825
|
+
if (opts?.limit !== undefined)
|
|
826
|
+
params.set('limit', String(opts.limit));
|
|
827
|
+
if (opts?.clear)
|
|
828
|
+
params.set('clear', '1');
|
|
829
|
+
const qs = params.size ? `?${params}` : '';
|
|
830
|
+
return request('GET', `/api/browser/sessions/${sessionId}/console${qs}`);
|
|
831
|
+
}
|
|
832
|
+
// ── Advanced ──
|
|
833
|
+
export async function evaluate(sessionId, script, tabId) {
|
|
834
|
+
return request('POST', `/api/browser/sessions/${sessionId}/evaluate`, { script, ...(tabId && { tabId }) }, LONG_TIMEOUT);
|
|
835
|
+
}
|
|
836
|
+
export async function extract(sessionId, script, tabId, opts) {
|
|
837
|
+
return request('POST', `/api/browser/sessions/${sessionId}/extract`, {
|
|
838
|
+
script, ...opts, ...(tabId && { tabId }),
|
|
839
|
+
}, Math.min(30_000, opts.timeoutMs || 15_000) + 2_000);
|
|
840
|
+
}
|
|
841
|
+
// Read-only structured state of the X/Twitter composer (quote card, submit button, modal,
|
|
842
|
+
// stale draft). The detection script lives server-side so the loop publish gate shares it.
|
|
843
|
+
export async function xComposeState(sessionId, tabId) {
|
|
844
|
+
return request('POST', `/api/browser/sessions/${sessionId}/x-compose-state`, { ...(tabId && { tabId }) }, LONG_TIMEOUT);
|
|
845
|
+
}
|
|
846
|
+
// ── Browser assistance (read-only context; the judgments run in this process, never in the Neural Interface) ──
|
|
847
|
+
/** Bounded, value-free description of the current page. Read-only: safe to call after any outcome. */
|
|
848
|
+
export async function semanticContext(sessionId, tabId, opts) {
|
|
849
|
+
return request('POST', `/api/browser/sessions/${sessionId}/semantic-context`, {
|
|
850
|
+
...(opts?.purpose && { purpose: opts.purpose }),
|
|
851
|
+
...(opts?.scope && { scope: opts.scope }),
|
|
852
|
+
...(opts?.social && { social: true }),
|
|
853
|
+
...(tabId && { tabId }),
|
|
854
|
+
}, 6000);
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* The one auto-heal click. It names a candidate inside a context the server
|
|
858
|
+
* minted after a click it confirmed never started; the selector and the
|
|
859
|
+
* fingerprint stay on the server. Deliberately `requestOnce`: route recovery
|
|
860
|
+
* could re-issue this on another tab, and a heal is never sent twice.
|
|
861
|
+
*/
|
|
862
|
+
export async function clickAutoHeal(sessionId, tabId, pick, snapshot) {
|
|
863
|
+
return requestOnce('POST', `/api/browser/sessions/${sessionId}/click`, {
|
|
864
|
+
autoHeal: { contextId: pick.contextId, candidateId: pick.candidateId },
|
|
865
|
+
...(isBrowserCompactMode() && { compact: true }),
|
|
866
|
+
...(snapshot && { snapshot }),
|
|
867
|
+
...(isBrowserV2Enabled() && { snapshotMaxChars: 6000 }),
|
|
868
|
+
...(tabId && { tabId }),
|
|
869
|
+
}, 15_000);
|
|
870
|
+
}
|
|
871
|
+
// Upload a local image file to BlueSky as a blob, using the page's own session
|
|
872
|
+
// token. The Neural Interface reads the file from disk (the MCP page context
|
|
873
|
+
// can't), pulls accessJwt/pdsUrl from the bsky.app tab, and POSTs the bytes to
|
|
874
|
+
// com.atproto.repo.uploadBlob. Returns { ok, blob } (the AT Protocol blob ref).
|
|
875
|
+
export async function uploadBlueskyBlob(sessionId, filePath, tabId) {
|
|
876
|
+
return request('POST', `/api/browser/sessions/${sessionId}/bluesky/upload-blob`, { filePath, ...(tabId && { tabId }) }, LONG_TIMEOUT);
|
|
877
|
+
}
|
|
878
|
+
export async function waitFor(sessionId, opts, tabId) {
|
|
879
|
+
return request('POST', `/api/browser/sessions/${sessionId}/wait`, { ...opts, ...(isBrowserCompactMode() && { compact: true }), ...(tabId && { tabId }) }, LONG_TIMEOUT);
|
|
880
|
+
}
|
|
881
|
+
// ── Whiteboard ──
|
|
882
|
+
/** Read the board. `images: false` asks the server to replace image dataUrls
|
|
883
|
+
* with their byte size (the tools never need the base64 payload). */
|
|
884
|
+
export async function getWhiteboard(opts = {}) {
|
|
885
|
+
return request('GET', opts.images === false ? '/api/whiteboard?images=0' : '/api/whiteboard');
|
|
886
|
+
}
|
|
887
|
+
export async function addWhiteboardElements(elements, coordMode, layout) {
|
|
888
|
+
return request('POST', '/api/whiteboard/elements', { elements, coordMode, layout });
|
|
889
|
+
}
|
|
890
|
+
/** Atomic update/remove ops (one save, one broadcast, per-op results). */
|
|
891
|
+
export async function batchWhiteboardOps(ops, coordMode) {
|
|
892
|
+
return request('POST', '/api/whiteboard/elements/batch', { ops, coordMode });
|
|
893
|
+
}
|
|
894
|
+
export async function updateWhiteboardElement(id, updates, coordMode) {
|
|
895
|
+
return request('PUT', `/api/whiteboard/elements/${id}`, { updates, coordMode });
|
|
896
|
+
}
|
|
897
|
+
export async function removeWhiteboardElement(id) {
|
|
898
|
+
return request('DELETE', `/api/whiteboard/elements/${id}`);
|
|
899
|
+
}
|
|
900
|
+
export async function clearWhiteboard() {
|
|
901
|
+
return request('POST', '/api/whiteboard/clear');
|
|
902
|
+
}
|
|
903
|
+
export async function whiteboardScreenshot(opts = {}) {
|
|
904
|
+
const query = opts.crop === 'usable' ? '?crop=usable' : '';
|
|
905
|
+
return request('GET', `/api/whiteboard/screenshot${query}`, undefined, 15_000);
|
|
906
|
+
}
|
|
907
|
+
// ── Cards (Memory Card MCP integration) ──
|
|
908
|
+
export async function getCards() {
|
|
909
|
+
return request('GET', '/api/cards');
|
|
910
|
+
}
|
|
911
|
+
export async function openCard(memoryId, opts) {
|
|
912
|
+
return request('POST', '/api/cards/open', { memoryId, ...opts });
|
|
913
|
+
}
|
|
914
|
+
export async function closeCard(memoryId) {
|
|
915
|
+
return request('POST', '/api/cards/close', memoryId ? { memoryId } : {});
|
|
916
|
+
}
|
|
917
|
+
export async function updateCard(memoryId, updates, coordMode) {
|
|
918
|
+
return request('PUT', `/api/cards/${memoryId}`, { ...updates, coordMode });
|
|
919
|
+
}
|
|
920
|
+
export async function cardsScreenshot() {
|
|
921
|
+
return request('GET', '/api/cards/screenshot', undefined, 15_000);
|
|
922
|
+
}
|
|
923
|
+
// ── TicTacToe ──
|
|
924
|
+
export async function tictactoeStart(piece) {
|
|
925
|
+
return request('POST', '/api/games/tictactoe/start', { piece });
|
|
926
|
+
}
|
|
927
|
+
export async function tictactoeMove(cell) {
|
|
928
|
+
return request('POST', '/api/games/tictactoe/move', { cell });
|
|
929
|
+
}
|
|
930
|
+
export async function tictactoeState() {
|
|
931
|
+
return request('GET', '/api/games/tictactoe/state');
|
|
932
|
+
}
|
|
933
|
+
export async function tictactoeEnd() {
|
|
934
|
+
return request('POST', '/api/games/tictactoe/end');
|
|
935
|
+
}
|
|
936
|
+
// ── Git ──
|
|
937
|
+
export async function gitStatus(path) {
|
|
938
|
+
return request('GET', `/api/git/status?path=${encodeURIComponent(path)}`);
|
|
939
|
+
}
|
|
940
|
+
export async function gitDiff(path, maxLines) {
|
|
941
|
+
const qs = `path=${encodeURIComponent(path)}${maxLines ? `&maxLines=${maxLines}` : ''}`;
|
|
942
|
+
return request('GET', `/api/git/diff?${qs}`, undefined, LONG_TIMEOUT);
|
|
943
|
+
}
|
|
944
|
+
export async function gitCommit(path, message, files) {
|
|
945
|
+
return request('POST', '/api/git/commit', { path, message, files });
|
|
946
|
+
}
|
|
947
|
+
export async function gitLog(path, count) {
|
|
948
|
+
return request('GET', `/api/git/log?path=${encodeURIComponent(path)}&count=${count || 10}`);
|
|
949
|
+
}
|
|
950
|
+
export async function gitBranches(path) {
|
|
951
|
+
return request('GET', `/api/terminal/branches?path=${encodeURIComponent(path)}`);
|
|
952
|
+
}
|
|
953
|
+
// ── Style Guide ──
|
|
954
|
+
// `projectPath` is any path inside a registered project; the server resolves it to the project root.
|
|
955
|
+
function styleGuideQuery(params) {
|
|
956
|
+
const query = new URLSearchParams();
|
|
957
|
+
for (const [key, value] of Object.entries(params))
|
|
958
|
+
if (value !== undefined && value !== null && value !== '')
|
|
959
|
+
query.set(key, value);
|
|
960
|
+
return query.toString();
|
|
961
|
+
}
|
|
962
|
+
export async function getStyleGuide(projectPath) {
|
|
963
|
+
return request('GET', `/api/style-guide?${styleGuideQuery({ projectPath })}`);
|
|
964
|
+
}
|
|
965
|
+
/** The compact text agents get: { summary, tokensEstimate, saved, revision, projectPath }. */
|
|
966
|
+
export async function getStyleGuideSummary(projectPath, taskClass) {
|
|
967
|
+
return request('GET', `/api/style-guide/summary?${styleGuideQuery({ projectPath, taskClass })}`);
|
|
968
|
+
}
|
|
969
|
+
/** One export format as text: { format, contentType, filename, text, revision }. */
|
|
970
|
+
export async function getStyleGuideExport(projectPath, format, theme) {
|
|
971
|
+
return request('GET', `/api/style-guide/export?${styleGuideQuery({ projectPath, format, theme, as: 'json' })}`);
|
|
972
|
+
}
|
|
973
|
+
/** Write the project's artifacts now: { written: [{ format, path, changed }] }. */
|
|
974
|
+
export async function writeStyleGuideExports(projectPath, formats) {
|
|
975
|
+
return request('POST', '/api/style-guide/export', { projectPath, ...(formats?.length ? { formats } : {}) });
|
|
976
|
+
}
|
|
977
|
+
/** WCAG ratio + APCA for two colors (or aliases, with a project): { ratio, aa, aaa, aaLarge, apca, fg, bg }. */
|
|
978
|
+
export async function styleGuideContrast(body) {
|
|
979
|
+
return request('POST', '/api/style-guide/contrast', body);
|
|
980
|
+
}
|
|
981
|
+
/** An agent's only write to a guide: a merge patch the user accepts or rejects. { id, pending, ignored, diff } */
|
|
982
|
+
export async function proposeStyleGuideChange(body) {
|
|
983
|
+
const identity = getIdentity();
|
|
984
|
+
const runId = effectivePins(identity).terminalSessionId || identity.state.ancestorPinnedTerminal;
|
|
985
|
+
return request('POST', '/api/style-guide/proposals', { ...(!body.runId && runId ? { runId } : {}), ...body });
|
|
986
|
+
}
|
|
987
|
+
/** The project's proposals (a bare array on success). */
|
|
988
|
+
export async function listStyleGuideProposals(projectPath, status) {
|
|
989
|
+
return request('GET', `/api/style-guide/proposals?${styleGuideQuery({ projectPath, status })}`);
|
|
990
|
+
}
|
|
991
|
+
/** Registered projects with their guide's status (a bare array on success). */
|
|
992
|
+
export async function listStyleGuideProjects() {
|
|
993
|
+
return request('GET', '/api/style-guide/projects');
|
|
994
|
+
}
|
|
995
|
+
export async function listProjects() {
|
|
996
|
+
return request('GET', '/api/projects');
|
|
997
|
+
}
|
|
998
|
+
// ── Image store ──
|
|
999
|
+
export async function listImages() {
|
|
1000
|
+
return request('GET', '/api/images');
|
|
1001
|
+
}
|
|
1002
|
+
export async function deleteImage(filename) {
|
|
1003
|
+
return request('DELETE', `/api/images/${encodeURIComponent(filename)}`);
|
|
1004
|
+
}
|
|
1005
|
+
// ── YouTube trailer pipeline (sourcing + download + API) ──
|
|
1006
|
+
// These delegate to the Neural Interface server, which holds the IGDB/Twitch
|
|
1007
|
+
// token, the Steam proxy, the yt-dlp binary, and the YouTube OAuth credentials.
|
|
1008
|
+
const DOWNLOAD_TIMEOUT = 600_000; // trailer downloads can be large/slow
|
|
1009
|
+
/**
|
|
1010
|
+
* Discover candidate trailers. `source` selects the discovery backend:
|
|
1011
|
+
* 'igdb' — query IGDB for games + Steam appid + YouTube trailer ids
|
|
1012
|
+
* 'steam' — resolve Steam appdetails movies[] for explicit appids/query
|
|
1013
|
+
* 'youtube' — search YouTube directly for recently published trailer videos
|
|
1014
|
+
* 'auto' — IGDB discovery enriched with Steam mp4 URLs (default)
|
|
1015
|
+
*/
|
|
1016
|
+
export async function youtubeDiscover(body) {
|
|
1017
|
+
return request('POST', '/api/sources/discover', body, LONG_TIMEOUT);
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Download a trailer to disk. Prefers a direct Steam mp4 URL; falls back to
|
|
1021
|
+
* yt-dlp on a YouTube id/url. Returns `{ filePath, bytes, source }`.
|
|
1022
|
+
*/
|
|
1023
|
+
export async function youtubeDownload(body) {
|
|
1024
|
+
return request('POST', '/api/youtube/download', body, DOWNLOAD_TIMEOUT);
|
|
1025
|
+
}
|
|
1026
|
+
export async function youtubeGetConfig() {
|
|
1027
|
+
return request('GET', '/api/youtube/config');
|
|
1028
|
+
}
|
|
1029
|
+
export async function youtubeSetConfig(config) {
|
|
1030
|
+
return request('PUT', '/api/youtube/config', config);
|
|
1031
|
+
}
|
|
1032
|
+
/** Test configured credentials. `target`: 'youtube' | 'igdb' | 'steam' | 'all'. */
|
|
1033
|
+
export async function youtubeTest(target) {
|
|
1034
|
+
return request('POST', '/api/youtube/test', target ? { target } : {}, LONG_TIMEOUT);
|
|
1035
|
+
}
|
|
1036
|
+
/** Read-only analytics via the YouTube Data/Analytics API (OAuth). */
|
|
1037
|
+
export async function youtubeAnalytics(body) {
|
|
1038
|
+
return request('POST', '/api/youtube/analytics', body, LONG_TIMEOUT);
|
|
1039
|
+
}
|
|
1040
|
+
// ── MoreLogin (anti-detect browser) — proxied to the Neural Interface ──
|
|
1041
|
+
export async function moreloginStatus() {
|
|
1042
|
+
return request('GET', '/api/morelogin/status', undefined, LONG_TIMEOUT);
|
|
1043
|
+
}
|
|
1044
|
+
export async function moreloginProfiles() {
|
|
1045
|
+
return request('GET', '/api/morelogin/profiles', undefined, LONG_TIMEOUT);
|
|
1046
|
+
}
|
|
1047
|
+
export async function moreloginCreate(name) {
|
|
1048
|
+
return request('POST', '/api/morelogin/profiles', name ? { name } : {}, LONG_TIMEOUT);
|
|
1049
|
+
}
|
|
1050
|
+
export async function moreloginStart(envId) {
|
|
1051
|
+
return request('POST', '/api/morelogin/start', { envId }, SESSION_CREATE_TIMEOUT);
|
|
1052
|
+
}
|
|
1053
|
+
export async function moreloginStop(envId) {
|
|
1054
|
+
return request('POST', '/api/morelogin/stop', { envId }, LONG_TIMEOUT);
|
|
1055
|
+
}
|
|
1056
|
+
export async function moreloginUseDefault(envId) {
|
|
1057
|
+
return request('POST', '/api/morelogin/use-default', envId ? { envId } : { clear: true });
|
|
1058
|
+
}
|
|
1059
|
+
// A dispatch may acquire a browser tab before the run is accepted.
|
|
1060
|
+
const ASSISTANT_DISPATCH_TIMEOUT = 90_000;
|
|
1061
|
+
// Long-poll waits block server-side for up to timeoutMs; the HTTP deadline
|
|
1062
|
+
// must always outlive them so a timed-out wait is reported by the server.
|
|
1063
|
+
const ASSISTANT_WAIT_MARGIN_MS = 15_000;
|
|
1064
|
+
function assistantRunPath(runId, suffix = '') {
|
|
1065
|
+
return `/api/assistant/runs/${encodeURIComponent(runId)}${suffix}`;
|
|
1066
|
+
}
|
|
1067
|
+
function queryString(params) {
|
|
1068
|
+
const qs = new URLSearchParams();
|
|
1069
|
+
for (const [key, value] of Object.entries(params)) {
|
|
1070
|
+
if (value === undefined || value === null || value === '')
|
|
1071
|
+
continue;
|
|
1072
|
+
qs.set(key, String(value));
|
|
1073
|
+
}
|
|
1074
|
+
const rendered = qs.toString();
|
|
1075
|
+
return rendered ? `?${rendered}` : '';
|
|
1076
|
+
}
|
|
1077
|
+
export async function assistantCatalog(opts = {}) {
|
|
1078
|
+
return request('GET', `/api/assistant/catalog${queryString({ view: 'brain', provider: opts.provider, q: opts.search })}`, undefined, LONG_TIMEOUT);
|
|
1079
|
+
}
|
|
1080
|
+
// agent_route may show the user a route card and wait for the answer; the
|
|
1081
|
+
// server caps its own wait below this deadline (X-Synabun-Deadline).
|
|
1082
|
+
const ASSISTANT_ROUTE_TIMEOUT = 115_000;
|
|
1083
|
+
export async function assistantRoute(body) {
|
|
1084
|
+
return request('POST', '/api/assistant/route', body, ASSISTANT_ROUTE_TIMEOUT);
|
|
1085
|
+
}
|
|
1086
|
+
// agent_clarify shows the user a question card and waits briefly for the
|
|
1087
|
+
// answers; like agent_route, the server caps its wait below this deadline.
|
|
1088
|
+
export async function assistantClarify(body) {
|
|
1089
|
+
return request('POST', '/api/assistant/clarify', body, ASSISTANT_ROUTE_TIMEOUT);
|
|
1090
|
+
}
|
|
1091
|
+
export async function assistantListRuns(opts = {}) {
|
|
1092
|
+
return request('GET', `/api/assistant/runs${queryString({
|
|
1093
|
+
active: opts.activeOnly ? 1 : undefined,
|
|
1094
|
+
assistantSessionId: opts.assistantSessionId,
|
|
1095
|
+
workflowId: opts.workflowId,
|
|
1096
|
+
})}`);
|
|
1097
|
+
}
|
|
1098
|
+
/** Usage of one task ("current", an id) or the session ("all"); `runId` with "all" adds that run's totals over its tasks. */
|
|
1099
|
+
export async function assistantUsage(assistantSessionId, task = 'current', runId) {
|
|
1100
|
+
return request('GET', `/api/assistant/sessions/${encodeURIComponent(assistantSessionId)}/usage${queryString({ task, run: runId })}`);
|
|
1101
|
+
}
|
|
1102
|
+
export async function assistantDispatch(body) {
|
|
1103
|
+
return request('POST', '/api/assistant/dispatch', body, ASSISTANT_DISPATCH_TIMEOUT);
|
|
1104
|
+
}
|
|
1105
|
+
export async function assistantRun(runId) {
|
|
1106
|
+
return request('GET', assistantRunPath(runId));
|
|
1107
|
+
}
|
|
1108
|
+
export async function assistantResult(runId) {
|
|
1109
|
+
return request('GET', assistantRunPath(runId, '/result'));
|
|
1110
|
+
}
|
|
1111
|
+
export async function assistantTranscript(runId, opts = {}) {
|
|
1112
|
+
return request('GET', assistantRunPath(runId, `/transcript${queryString({ format: opts.format, tail: opts.tail, maxChars: opts.maxChars })}`), undefined, LONG_TIMEOUT);
|
|
1113
|
+
}
|
|
1114
|
+
export async function assistantSend(runId, body) {
|
|
1115
|
+
return request('POST', assistantRunPath(runId, '/send'), body, LONG_TIMEOUT);
|
|
1116
|
+
}
|
|
1117
|
+
export async function assistantPermission(runId, body) {
|
|
1118
|
+
return request('POST', assistantRunPath(runId, '/permission'), body, LONG_TIMEOUT);
|
|
1119
|
+
}
|
|
1120
|
+
export async function assistantWaitRun(runId, opts) {
|
|
1121
|
+
return request('GET', assistantRunPath(runId, `/wait${queryString({ until: opts.until, timeout: opts.timeoutMs })}`), undefined, opts.timeoutMs + ASSISTANT_WAIT_MARGIN_MS);
|
|
1122
|
+
}
|
|
1123
|
+
export async function assistantWaitMany(body) {
|
|
1124
|
+
return request('POST', '/api/assistant/wait', body, body.timeoutMs + ASSISTANT_WAIT_MARGIN_MS);
|
|
1125
|
+
}
|
|
1126
|
+
export async function assistantStop(runId, reason) {
|
|
1127
|
+
return request('POST', assistantRunPath(runId, '/stop'), reason ? { reason } : {}, LONG_TIMEOUT);
|
|
1128
|
+
}
|
|
1129
|
+
export async function assistantKillAll(body = {}) {
|
|
1130
|
+
return request('POST', '/api/assistant/kill-all', body, LONG_TIMEOUT);
|
|
1131
|
+
}
|
|
1132
|
+
export async function assistantFocus(runId, focus) {
|
|
1133
|
+
return request('POST', assistantRunPath(runId, '/focus'), { focus });
|
|
1134
|
+
}
|
|
1135
|
+
//# sourceMappingURL=neural-interface.js.map
|