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,1144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BlueSky (AT Protocol) tool group — native SynaBun tools to control bsky.app.
|
|
3
|
+
*
|
|
4
|
+
* Unlike the DOM-scraping social extractors in browser-observe.ts, these tools
|
|
5
|
+
* call BlueSky's XRPC JSON API directly from inside the logged-in bsky.app page
|
|
6
|
+
* via ni.evaluate(). The page already holds a valid access token (read from
|
|
7
|
+
* localStorage['BSKY_STORAGE']); every script reuses it to fetch the account's
|
|
8
|
+
* PDS host (pdsUrl), which is NOT bsky.social — Bluesky shards users across
|
|
9
|
+
* *.host.bsky.network PDS hosts, and the token's audience is pinned to that PDS.
|
|
10
|
+
* App View reads (app.bsky.*) and the chat service (chat.bsky.*) are reached by
|
|
11
|
+
* the PDS's built-in proxy (chat needs an explicit atproto-proxy header).
|
|
12
|
+
*
|
|
13
|
+
* Requirement: a browser context logged in to bsky.app — localStorage is
|
|
14
|
+
* per-origin, so a blank assigned tab is initialized at bsky.app before the
|
|
15
|
+
* session token is read. Nonblank tabs are never navigated implicitly.
|
|
16
|
+
*
|
|
17
|
+
* The stored access token lives about 2 hours; bsky.app renews it with its
|
|
18
|
+
* refresh token when it boots or when a call reports ExpiredToken. A tab read
|
|
19
|
+
* right after it loaded can still hold the expired one, so every tool first
|
|
20
|
+
* makes sure the token is fresh (waiting for the page's own refresh, then
|
|
21
|
+
* reloading the tab once) and only then reports "not logged in" — when the page
|
|
22
|
+
* really holds no session.
|
|
23
|
+
*/
|
|
24
|
+
import { z } from 'zod';
|
|
25
|
+
import * as ni from '../services/neural-interface.js';
|
|
26
|
+
import { text } from './response.js';
|
|
27
|
+
import { coerceBoolean } from './utils.js';
|
|
28
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
29
|
+
// In-page JS helpers — prepended to every tool script. Plain ES5-ish JS with
|
|
30
|
+
// single quotes + string concat ONLY (these live inside TS template literals,
|
|
31
|
+
// so no backticks/template-literals are allowed in this block).
|
|
32
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
33
|
+
const BSKY_SESSION_JS = `
|
|
34
|
+
function __bskySession(){
|
|
35
|
+
function tryParse(s){ try { return JSON.parse(s); } catch(e){ return null; } }
|
|
36
|
+
var keys = ['BSKY_STORAGE','root','persisted-root','persisted:root','agent'];
|
|
37
|
+
var acct = null;
|
|
38
|
+
for (var i=0;i<keys.length;i++){
|
|
39
|
+
var raw;
|
|
40
|
+
try { raw = localStorage.getItem(keys[i]); }
|
|
41
|
+
catch(e){
|
|
42
|
+
return { __bskyError: 'BlueSky session storage is inaccessible on this page: ' + (e && e.message || e) + '. Use a top-level https://bsky.app tab in the same browser context.' };
|
|
43
|
+
}
|
|
44
|
+
if(!raw) continue;
|
|
45
|
+
var j = tryParse(raw);
|
|
46
|
+
if(!j) continue;
|
|
47
|
+
var sess = j.session || j;
|
|
48
|
+
var cand = sess.currentAccount
|
|
49
|
+
|| (Array.isArray(sess.accounts) && (sess.accounts.filter(function(a){return a && a.active && a.accessJwt;})[0] || sess.accounts.filter(function(a){return a && a.accessJwt;})[0]))
|
|
50
|
+
|| sess.currentSession
|
|
51
|
+
|| (sess.accessJwt ? sess : null);
|
|
52
|
+
if (cand && cand.accessJwt && cand.did){ acct = cand; break; }
|
|
53
|
+
}
|
|
54
|
+
if(!acct) return { __bskyNoSession: true, __bskyError: 'Not logged in to BlueSky (no session token found on this page). Open a bsky.app tab, sign in, then retry.' };
|
|
55
|
+
var pdsUrl = String(acct.pdsUrl || acct.service || 'https://bsky.social').replace(/[/]+$/, '');
|
|
56
|
+
return { accessJwt: acct.accessJwt, did: acct.did, handle: acct.handle || null, pdsUrl: pdsUrl };
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
// Token freshness from the access JWT's exp claim. bsky.app rewrites
|
|
60
|
+
// BSKY_STORAGE when it refreshes, so re-reading picks up the new token.
|
|
61
|
+
const BSKY_TOKEN_JS = `
|
|
62
|
+
function __bskyJwtExpMs(jwt){
|
|
63
|
+
try {
|
|
64
|
+
var part = String(jwt || '').split('.')[1];
|
|
65
|
+
if (!part) return null;
|
|
66
|
+
part = part.replace(/-/g, '+').replace(/_/g, '/');
|
|
67
|
+
while (part.length % 4) part += '=';
|
|
68
|
+
var claims = JSON.parse(atob(part));
|
|
69
|
+
return typeof claims.exp === 'number' ? claims.exp * 1000 : null;
|
|
70
|
+
} catch(e){ return null; }
|
|
71
|
+
}
|
|
72
|
+
function __bskyTokenState(){
|
|
73
|
+
var pageAgeMs = null;
|
|
74
|
+
try { pageAgeMs = Math.round(performance.now()); } catch(e){}
|
|
75
|
+
var s = __bskySession();
|
|
76
|
+
if (s.__bskyError) return { state: s.__bskyNoSession ? 'none' : 'error', error: s.__bskyError, pageAgeMs: pageAgeMs };
|
|
77
|
+
var exp = __bskyJwtExpMs(s.accessJwt);
|
|
78
|
+
if (exp === null) return { state: 'unknown', handle: s.handle, pageAgeMs: pageAgeMs };
|
|
79
|
+
return { state: exp - Date.now() > 15000 ? 'fresh' : 'expired', expiresAt: exp, handle: s.handle, pageAgeMs: pageAgeMs };
|
|
80
|
+
}
|
|
81
|
+
`;
|
|
82
|
+
const BSKY_XRPC_JS = `
|
|
83
|
+
var __bskyWrites = 0;
|
|
84
|
+
async function __bskyXrpc(method, opts){
|
|
85
|
+
opts = opts || {};
|
|
86
|
+
var verb = opts.verb || 'GET';
|
|
87
|
+
var s = __bskySession();
|
|
88
|
+
if (s.__bskyError) return s;
|
|
89
|
+
var url = s.pdsUrl + '/xrpc/' + method;
|
|
90
|
+
var headers = { 'Authorization': 'Bearer ' + s.accessJwt };
|
|
91
|
+
if (opts.proxy) headers['atproto-proxy'] = opts.proxy;
|
|
92
|
+
if (verb === 'GET' && opts.params){
|
|
93
|
+
var qs = new URLSearchParams();
|
|
94
|
+
var p = opts.params;
|
|
95
|
+
for (var k in p){
|
|
96
|
+
if (!Object.prototype.hasOwnProperty.call(p,k)) continue;
|
|
97
|
+
var v = p[k];
|
|
98
|
+
if (v === null || v === undefined || v === '') continue;
|
|
99
|
+
if (Array.isArray(v)){ for (var n=0;n<v.length;n++) qs.append(k, String(v[n])); }
|
|
100
|
+
else qs.append(k, String(v));
|
|
101
|
+
}
|
|
102
|
+
var qstr = qs.toString();
|
|
103
|
+
if (qstr) url += '?' + qstr;
|
|
104
|
+
}
|
|
105
|
+
var init = { method: verb, headers: headers };
|
|
106
|
+
if (verb === 'POST'){
|
|
107
|
+
headers['Content-Type'] = 'application/json';
|
|
108
|
+
init.body = JSON.stringify(opts.body || {});
|
|
109
|
+
}
|
|
110
|
+
var res;
|
|
111
|
+
try { res = await fetch(url, init); }
|
|
112
|
+
catch(e){ return { __bskyError: 'Network error calling ' + method + ': ' + (e && e.message || e) }; }
|
|
113
|
+
var data = null;
|
|
114
|
+
try { data = await res.json(); } catch(e){}
|
|
115
|
+
if (!res.ok){
|
|
116
|
+
var errName = data && data.error;
|
|
117
|
+
if (res.status === 401 || errName === 'ExpiredToken')
|
|
118
|
+
return { __bskyExpired: true, __bskyWrote: __bskyWrites > 0, __bskyError: 'BlueSky rejected the session token as expired on ' + method + '.' };
|
|
119
|
+
if (res.status === 429){
|
|
120
|
+
var reset = null; try { reset = res.headers.get('ratelimit-reset'); } catch(e){}
|
|
121
|
+
return { __bskyError: 'BlueSky rate limit hit on ' + method + (reset ? ' (resets at epoch ' + reset + ')' : '') + '. Back off and retry later.' };
|
|
122
|
+
}
|
|
123
|
+
return { __bskyError: 'XRPC ' + method + ' failed (' + res.status + '): ' + (errName || '') + ' ' + ((data && data.message) || '') };
|
|
124
|
+
}
|
|
125
|
+
// Writes that already landed make a whole-script retry unsafe (see runPrepared).
|
|
126
|
+
if (verb === 'POST') __bskyWrites++;
|
|
127
|
+
return data == null ? {} : data;
|
|
128
|
+
}
|
|
129
|
+
`;
|
|
130
|
+
const BSKY_NORMURI_JS = `
|
|
131
|
+
async function __bskyNormUri(input){
|
|
132
|
+
if (!input) return input;
|
|
133
|
+
if (String(input).indexOf('at://') === 0) return input;
|
|
134
|
+
var m = String(input).match(/[/]profile[/]([^/]+)[/]post[/]([^/?#]+)/);
|
|
135
|
+
if (!m) return input;
|
|
136
|
+
var actor = decodeURIComponent(m[1]); var rkey = m[2]; var did = actor;
|
|
137
|
+
if (actor.indexOf('did:') !== 0){
|
|
138
|
+
var r = await __bskyXrpc('com.atproto.identity.resolveHandle', { params:{ handle: actor } });
|
|
139
|
+
if (r.__bskyError || !r.did) return null;
|
|
140
|
+
did = r.did;
|
|
141
|
+
}
|
|
142
|
+
return 'at://' + did + '/app.bsky.feed.post/' + rkey;
|
|
143
|
+
}
|
|
144
|
+
async function __bskyResolveActor(input){
|
|
145
|
+
if (!input) return null;
|
|
146
|
+
if (String(input).indexOf('did:') === 0) return input;
|
|
147
|
+
var r = await __bskyXrpc('com.atproto.identity.resolveHandle', { params:{ handle: input } });
|
|
148
|
+
if (r.__bskyError || !r.did) return null;
|
|
149
|
+
return r.did;
|
|
150
|
+
}
|
|
151
|
+
`;
|
|
152
|
+
const BSKY_UPLOAD_JS = `
|
|
153
|
+
async function __bskyUploadBlobFromUrl(imgUrl){
|
|
154
|
+
var s = __bskySession();
|
|
155
|
+
if (s.__bskyError) return s;
|
|
156
|
+
var imgRes;
|
|
157
|
+
try { imgRes = await fetch(imgUrl); } catch(e){ return { __bskyError: 'Failed to fetch image URL: ' + (e && e.message || e) }; }
|
|
158
|
+
if (!imgRes.ok) return { __bskyError: 'Image URL returned ' + imgRes.status };
|
|
159
|
+
var ct = imgRes.headers.get('content-type') || 'image/jpeg';
|
|
160
|
+
var buf = await imgRes.arrayBuffer();
|
|
161
|
+
var up;
|
|
162
|
+
try { up = await fetch(s.pdsUrl + '/xrpc/com.atproto.repo.uploadBlob', { method:'POST', headers:{ 'Authorization':'Bearer '+s.accessJwt, 'Content-Type': ct }, body: buf }); }
|
|
163
|
+
catch(e){ return { __bskyError: 'uploadBlob network error: ' + (e && e.message || e) }; }
|
|
164
|
+
var d = null; try { d = await up.json(); } catch(e){}
|
|
165
|
+
if (!up.ok && (up.status === 401 || (d && d.error) === 'ExpiredToken'))
|
|
166
|
+
return { __bskyExpired: true, __bskyWrote: __bskyWrites > 0, __bskyError: 'BlueSky rejected the session token as expired on uploadBlob.' };
|
|
167
|
+
if (!up.ok) return { __bskyError: 'uploadBlob failed (' + up.status + '): ' + (d && d.error || '') };
|
|
168
|
+
return (d && d.blob) ? { blob: d.blob } : { __bskyError: 'uploadBlob returned no blob' };
|
|
169
|
+
}
|
|
170
|
+
`;
|
|
171
|
+
const BSKY_PAGINATE_JS = `
|
|
172
|
+
async function __bskyPaginate(method, params, itemsKey, maxItems, proxy){
|
|
173
|
+
var out = [];
|
|
174
|
+
var cursor = (params && params.cursor) || undefined;
|
|
175
|
+
var cap = maxItems || (params && params.limit) || 50;
|
|
176
|
+
var t0 = Date.now();
|
|
177
|
+
while (true){
|
|
178
|
+
var pp = Object.assign({}, params, { cursor: cursor });
|
|
179
|
+
var r = await __bskyXrpc(method, { params: pp, proxy: proxy });
|
|
180
|
+
if (r.__bskyError){ if (!out.length) return r; var o = {}; o[itemsKey] = out; o.cursor = cursor; o.partial = r.__bskyError; return o; }
|
|
181
|
+
var batch = r[itemsKey] || [];
|
|
182
|
+
for (var i=0;i<batch.length;i++) out.push(batch[i]);
|
|
183
|
+
cursor = r.cursor;
|
|
184
|
+
if (!maxItems) break;
|
|
185
|
+
if (out.length >= cap) break;
|
|
186
|
+
if (!cursor || batch.length === 0) break;
|
|
187
|
+
if (Date.now() - t0 > 25000) break;
|
|
188
|
+
}
|
|
189
|
+
var res = {}; res[itemsKey] = out.slice(0, cap); res.cursor = cursor; return res;
|
|
190
|
+
}
|
|
191
|
+
`;
|
|
192
|
+
const HELPERS = [BSKY_SESSION_JS, BSKY_XRPC_JS, BSKY_NORMURI_JS, BSKY_UPLOAD_JS, BSKY_PAGINATE_JS].join('\n');
|
|
193
|
+
const BSKY_APP_URL = 'https://bsky.app/';
|
|
194
|
+
const BSKY_TARGET_PROBE_JS = `(() => {
|
|
195
|
+
var href = ''; var origin = ''; var title = ''; var topLevel = false;
|
|
196
|
+
try { href = String(window.location.href || ''); } catch(e){}
|
|
197
|
+
try { origin = String(window.location.origin || ''); } catch(e){}
|
|
198
|
+
try { title = String(document.title || ''); } catch(e){}
|
|
199
|
+
try { topLevel = window.top === window.self; } catch(e){}
|
|
200
|
+
return { href: href, origin: origin, title: title, topLevel: topLevel };
|
|
201
|
+
})()`;
|
|
202
|
+
function isBlueskyTarget(target) {
|
|
203
|
+
if (!target.topLevel)
|
|
204
|
+
return false;
|
|
205
|
+
try {
|
|
206
|
+
const url = new URL(target.href);
|
|
207
|
+
return url.protocol === 'https:' && url.hostname === 'bsky.app';
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function isSafeBlankTarget(target) {
|
|
214
|
+
const href = String(target.href || '').trim().toLowerCase();
|
|
215
|
+
return href === '' || /^about:blank(?:[?#].*)?$/.test(href);
|
|
216
|
+
}
|
|
217
|
+
async function inspectBlueskyTarget(sessionId, tabId) {
|
|
218
|
+
const inspected = await ni.evaluate(sessionId, BSKY_TARGET_PROBE_JS, tabId);
|
|
219
|
+
if (inspected.error)
|
|
220
|
+
return { error: `Could not inspect the assigned BlueSky tab: ${inspected.error}` };
|
|
221
|
+
const target = inspected.result;
|
|
222
|
+
if (!target || typeof target.href !== 'string') {
|
|
223
|
+
return { error: 'Could not inspect the assigned BlueSky tab: invalid page context response.' };
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
href: target.href,
|
|
227
|
+
origin: typeof target.origin === 'string' ? target.origin : '',
|
|
228
|
+
title: typeof target.title === 'string' ? target.title : '',
|
|
229
|
+
topLevel: target.topLevel === true,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* BlueSky tools require origin-scoped localStorage from a top-level bsky.app
|
|
234
|
+
* document. Scheduled/owned tabs intentionally start at about:blank; it is safe
|
|
235
|
+
* to initialize only that blank tab. Never navigate a nonblank page implicitly,
|
|
236
|
+
* because it may be a user or another automation's tab selected by a stale ID.
|
|
237
|
+
*/
|
|
238
|
+
export async function ensureBlueskyPageTarget(sessionId, tabId) {
|
|
239
|
+
const inspected = await inspectBlueskyTarget(sessionId, tabId);
|
|
240
|
+
if ('error' in inspected)
|
|
241
|
+
return inspected;
|
|
242
|
+
if (isBlueskyTarget(inspected))
|
|
243
|
+
return { ok: true, target: inspected };
|
|
244
|
+
const pageLabel = inspected.href || '(empty URL)';
|
|
245
|
+
if (!inspected.topLevel) {
|
|
246
|
+
return { error: `BlueSky requires a top-level https://bsky.app tab; the assigned target is an iframe (${pageLabel}).` };
|
|
247
|
+
}
|
|
248
|
+
if (!isSafeBlankTarget(inspected)) {
|
|
249
|
+
return {
|
|
250
|
+
error: `The assigned browser tab is ${pageLabel}, not https://bsky.app. Refusing to navigate a nonblank tab automatically; pass the correct tabId or navigate the schedule-owned tab first.`,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const navigated = await ni.navigate(sessionId, BSKY_APP_URL, tabId, undefined, 'none');
|
|
254
|
+
if (navigated.error) {
|
|
255
|
+
return { error: `Could not initialize the blank BlueSky tab at ${BSKY_APP_URL}: ${navigated.error}` };
|
|
256
|
+
}
|
|
257
|
+
const verified = await inspectBlueskyTarget(sessionId, tabId);
|
|
258
|
+
if ('error' in verified)
|
|
259
|
+
return verified;
|
|
260
|
+
if (!isBlueskyTarget(verified)) {
|
|
261
|
+
return { error: `BlueSky tab initialization ended at ${verified.href || '(empty URL)'} instead of ${BSKY_APP_URL}.` };
|
|
262
|
+
}
|
|
263
|
+
return { ok: true, target: verified };
|
|
264
|
+
}
|
|
265
|
+
// JSON literal safe to embed inside JS source (escape the two line separators
|
|
266
|
+
// that are valid in JSON strings but terminate a JS line).
|
|
267
|
+
function jsLit(v) {
|
|
268
|
+
return JSON.stringify(v === undefined ? null : v)
|
|
269
|
+
.replace(/\u2028/g, '\\u2028')
|
|
270
|
+
.replace(/\u2029/g, '\\u2029');
|
|
271
|
+
}
|
|
272
|
+
function clampLimit(n, def = 50, max = 100) {
|
|
273
|
+
if (!n || n < 1)
|
|
274
|
+
return def;
|
|
275
|
+
return Math.min(n, max);
|
|
276
|
+
}
|
|
277
|
+
async function evalBsky(sessionId, tabId, body) {
|
|
278
|
+
// The Neural Interface runs this via page.evaluate(string), which compiles the
|
|
279
|
+
// whole string as ONE expression — so the helper function declarations must
|
|
280
|
+
// live INSIDE the IIFE, not before it (a leading `function ...` is not an
|
|
281
|
+
// expression and throws "Unexpected token").
|
|
282
|
+
const script = `(async () => {\n${HELPERS}\n${body}\n})()`;
|
|
283
|
+
const res = await ni.evaluate(sessionId, script, tabId);
|
|
284
|
+
if (res.error)
|
|
285
|
+
return { error: `BlueSky call failed: ${res.error}` };
|
|
286
|
+
const r = res.result;
|
|
287
|
+
if (r && r.__bskyError)
|
|
288
|
+
return { error: r.__bskyError, expired: r.__bskyExpired === true, wrote: r.__bskyWrote === true };
|
|
289
|
+
return { data: r };
|
|
290
|
+
}
|
|
291
|
+
// ── Token recovery ──
|
|
292
|
+
// A freshly initialized tab is usually still booting, and bsky.app renews an
|
|
293
|
+
// expired token during boot — so wait for that first; a page past its boot
|
|
294
|
+
// window gets one reload instead.
|
|
295
|
+
const TOKEN_POLL_MS = 500;
|
|
296
|
+
const TOKEN_BOOT_WAIT_MS = 8_000;
|
|
297
|
+
const TOKEN_RELOAD_WAIT_MS = 15_000;
|
|
298
|
+
const TOKEN_BOOT_WINDOW_MS = 20_000;
|
|
299
|
+
const TOKEN_STATE_SCRIPT = `(() => {\n${BSKY_SESSION_JS}\n${BSKY_TOKEN_JS}\nreturn __bskyTokenState();\n})()`;
|
|
300
|
+
// One deadline for the whole tool call: OpenCode and Codex stop an MCP tool call at
|
|
301
|
+
// about 60 s. Finding and opening the tab, the token checks and the reload must end
|
|
302
|
+
// SCRIPT_RESERVE before the deadline, so the tool's own request always has time.
|
|
303
|
+
const BSKY_CALL_BUDGET_MS = 48_000;
|
|
304
|
+
const BSKY_SCRIPT_RESERVE_MS = 12_000;
|
|
305
|
+
const BSKY_RENEW_MIN_MS = 3_000;
|
|
306
|
+
const NOT_LOGGED_IN = 'Not logged in to BlueSky (no session token found on this page). Open a bsky.app tab, sign in, then retry.';
|
|
307
|
+
const tokenUsable = (st) => st.state === 'fresh' || st.state === 'unknown';
|
|
308
|
+
const sleep = (ms) => new Promise((done) => setTimeout(done, ms));
|
|
309
|
+
/** Race one step against the call's deadline; the step itself keeps running. */
|
|
310
|
+
function beforeDeadline(work, deadlineAt, what) {
|
|
311
|
+
const ms = deadlineAt - Date.now();
|
|
312
|
+
const outOfTime = () => ({ error: `This BlueSky call ran out of its ${BSKY_CALL_BUDGET_MS / 1000} s time limit while ${what}.`, timedOut: true });
|
|
313
|
+
if (ms <= 0)
|
|
314
|
+
return Promise.resolve(outOfTime());
|
|
315
|
+
let timer;
|
|
316
|
+
const limit = new Promise((done) => { timer = setTimeout(() => done(outOfTime()), ms); });
|
|
317
|
+
return Promise.race([work, limit]).finally(() => clearTimeout(timer));
|
|
318
|
+
}
|
|
319
|
+
const timedOut = (value) => !!value && typeof value === 'object' && value.timedOut === true;
|
|
320
|
+
async function readTokenState(sessionId, tabId, deadlineAt) {
|
|
321
|
+
const res = await beforeDeadline(ni.evaluate(sessionId, TOKEN_STATE_SCRIPT, tabId), deadlineAt, 'reading the BlueSky session token');
|
|
322
|
+
if (timedOut(res))
|
|
323
|
+
return { state: 'error', error: res.error };
|
|
324
|
+
if (res.error)
|
|
325
|
+
return { state: 'error', error: `BlueSky call failed: ${res.error}` };
|
|
326
|
+
const r = res.result;
|
|
327
|
+
if (!r || typeof r.state !== 'string')
|
|
328
|
+
return { state: 'error', error: 'BlueSky call failed: invalid session probe response.' };
|
|
329
|
+
return r;
|
|
330
|
+
}
|
|
331
|
+
/** Poll until the page holds a usable token (or none at all), the wait ends, or the
|
|
332
|
+
* call's deadline passes. `staleExpiresAt` names a token the server already rejected. */
|
|
333
|
+
async function waitForToken(sessionId, tabId, timeoutMs, deadlineAt, staleExpiresAt) {
|
|
334
|
+
const waitUntil = Math.min(Date.now() + timeoutMs, deadlineAt);
|
|
335
|
+
for (;;) {
|
|
336
|
+
const st = await readTokenState(sessionId, tabId, deadlineAt);
|
|
337
|
+
const renewed = staleExpiresAt === undefined || st.expiresAt !== staleExpiresAt;
|
|
338
|
+
// A page mid-reload can fail to evaluate for a moment; keep polling.
|
|
339
|
+
if (st.state === 'none' || (tokenUsable(st) && renewed))
|
|
340
|
+
return st;
|
|
341
|
+
if (Date.now() + TOKEN_POLL_MS > waitUntil)
|
|
342
|
+
return st;
|
|
343
|
+
await sleep(TOKEN_POLL_MS);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Make sure the assigned bsky.app tab holds a usable session token before a
|
|
348
|
+
* tool runs: wait for the page's own refresh, then reload the tab once. Reports
|
|
349
|
+
* "not logged in" only when the page holds no session at all. Everything ends by
|
|
350
|
+
* `deadlineAt`. `forceReload`: the server rejected a token the page believed fresh.
|
|
351
|
+
*/
|
|
352
|
+
export async function ensureFreshBlueskySession(sessionId, tabId, opts = {}) {
|
|
353
|
+
const by = opts.deadlineAt ?? Date.now() + BSKY_CALL_BUDGET_MS - BSKY_SCRIPT_RESERVE_MS;
|
|
354
|
+
const first = await readTokenState(sessionId, tabId, by);
|
|
355
|
+
if (first.state === 'none')
|
|
356
|
+
return { error: first.error || NOT_LOGGED_IN };
|
|
357
|
+
if (first.state === 'error')
|
|
358
|
+
return { error: first.error || 'BlueSky call failed.' };
|
|
359
|
+
if (!opts.forceReload) {
|
|
360
|
+
if (tokenUsable(first))
|
|
361
|
+
return { ok: true, reloaded: false };
|
|
362
|
+
const pageAge = typeof first.pageAgeMs === 'number' ? first.pageAgeMs : Infinity;
|
|
363
|
+
if (pageAge < TOKEN_BOOT_WINDOW_MS) {
|
|
364
|
+
const booted = await waitForToken(sessionId, tabId, TOKEN_BOOT_WAIT_MS, by);
|
|
365
|
+
if (booted.state === 'none')
|
|
366
|
+
return { error: booted.error || NOT_LOGGED_IN };
|
|
367
|
+
if (tokenUsable(booted))
|
|
368
|
+
return { ok: true, reloaded: false };
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
// Reload this bsky.app tab once so the app resumes its session and renews the token.
|
|
372
|
+
const reloaded = await beforeDeadline(ni.reload(sessionId, tabId), by, 'reloading the bsky.app tab to renew the session');
|
|
373
|
+
if (timedOut(reloaded))
|
|
374
|
+
return { error: `BlueSky token expired, and this call ran out of its ${BSKY_CALL_BUDGET_MS / 1000} s time limit while reloading the bsky.app tab to renew it. Try again; the next call starts with a fresh time limit.` };
|
|
375
|
+
if (reloaded.error)
|
|
376
|
+
return { error: `BlueSky token expired, and reloading the bsky.app tab to renew it failed: ${reloaded.error}` };
|
|
377
|
+
const after = await waitForToken(sessionId, tabId, TOKEN_RELOAD_WAIT_MS, by, opts.forceReload ? first.expiresAt : undefined);
|
|
378
|
+
if (after.state === 'none') {
|
|
379
|
+
return { error: 'Not logged in to BlueSky: after reloading the bsky.app tab the page holds no session (the account was signed out). Sign in again in this browser profile, then retry.' };
|
|
380
|
+
}
|
|
381
|
+
if (tokenUsable(after))
|
|
382
|
+
return { ok: true, reloaded: true };
|
|
383
|
+
if (after.state === 'error')
|
|
384
|
+
return { error: `BlueSky token expired, and the bsky.app tab could not be read after reloading it: ${after.error}` };
|
|
385
|
+
if (Date.now() >= by)
|
|
386
|
+
return { error: 'BlueSky token was still expired when this call\'s time limit ran out (the bsky.app tab was reloaded once). Try again; the next call starts with a fresh time limit.' };
|
|
387
|
+
return { error: 'BlueSky token is still expired after waiting for bsky.app to renew it and reloading the tab once, so the saved session could not be renewed. Open bsky.app in this browser profile and sign in again if it asks.' };
|
|
388
|
+
}
|
|
389
|
+
/** Resolve the caller's tab in the default browser, make sure it is a
|
|
390
|
+
* top-level bsky.app page, and make sure it holds a usable session token — all
|
|
391
|
+
* before the call's deadline minus the time kept for the tool's own request. */
|
|
392
|
+
async function prepareBsky(args, deadlineAt = Date.now() + BSKY_CALL_BUDGET_MS) {
|
|
393
|
+
const prepBy = deadlineAt - BSKY_SCRIPT_RESERVE_MS;
|
|
394
|
+
const resolved = await beforeDeadline(ni.resolveSession(args.sessionId, undefined, args.tabId, { platform: true }), prepBy, 'finding the bsky.app tab');
|
|
395
|
+
if ('error' in resolved)
|
|
396
|
+
return { error: resolved.error };
|
|
397
|
+
const ready = await beforeDeadline(ensureBlueskyPageTarget(resolved.sessionId, resolved.tabId), prepBy, 'opening bsky.app');
|
|
398
|
+
if ('error' in ready)
|
|
399
|
+
return { error: ready.error };
|
|
400
|
+
const fresh = await ensureFreshBlueskySession(resolved.sessionId, resolved.tabId, { deadlineAt: prepBy });
|
|
401
|
+
if ('error' in fresh)
|
|
402
|
+
return fresh;
|
|
403
|
+
return { sessionId: resolved.sessionId, tabId: resolved.tabId, reloaded: fresh.reloaded, deadlineAt };
|
|
404
|
+
}
|
|
405
|
+
const UNCERTAIN = 'It may still finish in the page, so check the account before repeating a post, like, follow or message.';
|
|
406
|
+
/**
|
|
407
|
+
* Run a script on a prepared tab, within the call's deadline. When the server still
|
|
408
|
+
* rejects the token (revoked, clock skew) the tab is renewed and the script runs
|
|
409
|
+
* once more — only if nothing was written yet, the tab was not already reloaded
|
|
410
|
+
* for this call, and there is time left — so no post, like or message can repeat.
|
|
411
|
+
*/
|
|
412
|
+
async function runPrepared(route, body) {
|
|
413
|
+
const first = await beforeDeadline(evalBsky(route.sessionId, route.tabId, body), route.deadlineAt, 'waiting for BlueSky to answer');
|
|
414
|
+
if (timedOut(first))
|
|
415
|
+
return { error: `${first.error} ${UNCERTAIN}` };
|
|
416
|
+
if (!('error' in first) || !first.expired)
|
|
417
|
+
return first;
|
|
418
|
+
if (first.wrote || route.reloaded) {
|
|
419
|
+
return { error: `${first.error} The bsky.app tab was ${route.reloaded ? 'already reloaded once for this call' : 'not retried because part of this action was already written'}; check the account before trying again.`, expired: true, wrote: first.wrote };
|
|
420
|
+
}
|
|
421
|
+
if (route.deadlineAt - Date.now() < BSKY_SCRIPT_RESERVE_MS + BSKY_RENEW_MIN_MS) {
|
|
422
|
+
return { error: `${first.error} Not enough of this call's time limit is left to renew the session and try again; the next BlueSky call renews it first.`, expired: true, wrote: false };
|
|
423
|
+
}
|
|
424
|
+
const renewed = await ensureFreshBlueskySession(route.sessionId, route.tabId, { forceReload: true, deadlineAt: route.deadlineAt - BSKY_SCRIPT_RESERVE_MS });
|
|
425
|
+
if ('error' in renewed)
|
|
426
|
+
return renewed;
|
|
427
|
+
const second = await beforeDeadline(evalBsky(route.sessionId, route.tabId, body), route.deadlineAt, 'waiting for BlueSky to answer the retry');
|
|
428
|
+
if (timedOut(second))
|
|
429
|
+
return { error: `${second.error} ${UNCERTAIN}` };
|
|
430
|
+
if ('error' in second && second.expired) {
|
|
431
|
+
return { error: `${second.error} It was still rejected after the bsky.app tab renewed its session; sign in again in this browser profile if bsky.app asks.`, expired: true, wrote: second.wrote };
|
|
432
|
+
}
|
|
433
|
+
return second;
|
|
434
|
+
}
|
|
435
|
+
async function runBsky(args, body) {
|
|
436
|
+
const route = await prepareBsky(args);
|
|
437
|
+
if ('error' in route)
|
|
438
|
+
return route;
|
|
439
|
+
return runPrepared(route, body);
|
|
440
|
+
}
|
|
441
|
+
// ── Trimmers: shrink verbose AT Proto views to the useful, token-cheap fields ──
|
|
442
|
+
function trimActor(a) {
|
|
443
|
+
if (!a)
|
|
444
|
+
return a;
|
|
445
|
+
const out = { did: a.did, handle: a.handle };
|
|
446
|
+
if (a.displayName)
|
|
447
|
+
out.name = a.displayName;
|
|
448
|
+
if (a.description)
|
|
449
|
+
out.bio = a.description;
|
|
450
|
+
if (a.followersCount != null) {
|
|
451
|
+
out.followers = a.followersCount;
|
|
452
|
+
out.follows = a.followsCount;
|
|
453
|
+
out.posts = a.postsCount;
|
|
454
|
+
}
|
|
455
|
+
if (a.viewer)
|
|
456
|
+
out.viewer = { following: !!a.viewer.following, followedBy: !!a.viewer.followedBy, muted: !!a.viewer.muted, blocking: !!a.viewer.blocking };
|
|
457
|
+
return out;
|
|
458
|
+
}
|
|
459
|
+
function trimPost(v) {
|
|
460
|
+
if (!v)
|
|
461
|
+
return v;
|
|
462
|
+
const p = v.post || v;
|
|
463
|
+
const tp = p && p.$type;
|
|
464
|
+
if (tp && String(tp).indexOf('blocked') >= 0)
|
|
465
|
+
return { uri: p.uri, blocked: true };
|
|
466
|
+
if (tp && String(tp).indexOf('notFound') >= 0)
|
|
467
|
+
return { uri: p.uri, notFound: true };
|
|
468
|
+
const rec = p.record || {};
|
|
469
|
+
const out = {
|
|
470
|
+
uri: p.uri,
|
|
471
|
+
cid: p.cid,
|
|
472
|
+
text: rec.text != null ? rec.text : null,
|
|
473
|
+
counts: { replies: p.replyCount || 0, reposts: p.repostCount || 0, likes: p.likeCount || 0, quotes: p.quoteCount || 0 },
|
|
474
|
+
};
|
|
475
|
+
if (p.author)
|
|
476
|
+
out.author = { handle: p.author.handle, name: p.author.displayName || undefined, did: p.author.did };
|
|
477
|
+
if (rec.createdAt)
|
|
478
|
+
out.createdAt = rec.createdAt;
|
|
479
|
+
if (rec.reply)
|
|
480
|
+
out.isReply = true;
|
|
481
|
+
if (p.embed && p.embed.$type)
|
|
482
|
+
out.embed = String(p.embed.$type).split('#')[0].replace('app.bsky.embed.', '');
|
|
483
|
+
if (p.viewer)
|
|
484
|
+
out.viewer = { liked: !!p.viewer.like, reposted: !!p.viewer.repost };
|
|
485
|
+
if (v.reason && v.reason.$type && String(v.reason.$type).indexOf('Repost') >= 0)
|
|
486
|
+
out.repostedBy = (v.reason.by && v.reason.by.handle) || true;
|
|
487
|
+
return out;
|
|
488
|
+
}
|
|
489
|
+
function trimThread(thread, maxReplies = 50) {
|
|
490
|
+
if (!thread)
|
|
491
|
+
return null;
|
|
492
|
+
const tp = thread.$type ? String(thread.$type) : '';
|
|
493
|
+
if (tp.indexOf('notFound') >= 0)
|
|
494
|
+
return { uri: thread.uri, notFound: true };
|
|
495
|
+
if (tp.indexOf('blocked') >= 0)
|
|
496
|
+
return { uri: thread.uri, blocked: true };
|
|
497
|
+
const node = { post: trimPost(thread.post) };
|
|
498
|
+
if (thread.parent)
|
|
499
|
+
node.parent = trimPost(thread.parent.post || thread.parent);
|
|
500
|
+
if (Array.isArray(thread.replies))
|
|
501
|
+
node.replies = thread.replies.slice(0, maxReplies).map((r) => trimPost(r.post || r));
|
|
502
|
+
return node;
|
|
503
|
+
}
|
|
504
|
+
function trimNotif(n) {
|
|
505
|
+
const out = { reason: n.reason, uri: n.uri, cid: n.cid, isRead: !!n.isRead, indexedAt: n.indexedAt };
|
|
506
|
+
if (n.author)
|
|
507
|
+
out.author = { handle: n.author.handle, name: n.author.displayName || undefined, did: n.author.did };
|
|
508
|
+
if (n.reasonSubject)
|
|
509
|
+
out.reasonSubject = n.reasonSubject;
|
|
510
|
+
if (n.record && n.record.text)
|
|
511
|
+
out.text = n.record.text;
|
|
512
|
+
return out;
|
|
513
|
+
}
|
|
514
|
+
function trimConvo(c) {
|
|
515
|
+
return {
|
|
516
|
+
id: c.id,
|
|
517
|
+
members: (c.members || []).map((m) => ({ did: m.did, handle: m.handle, name: m.displayName || undefined })),
|
|
518
|
+
unread: c.unreadCount || 0,
|
|
519
|
+
lastMessage: c.lastMessage ? { text: c.lastMessage.text, sentAt: c.lastMessage.sentAt, sender: c.lastMessage.sender && c.lastMessage.sender.did } : undefined,
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
function trimMessage(m) {
|
|
523
|
+
return { id: m.id, sender: m.sender && m.sender.did, text: m.text, sentAt: m.sentAt };
|
|
524
|
+
}
|
|
525
|
+
// ── Formatters: compact single-line JSON, always echoing the next cursor ──
|
|
526
|
+
function fmtList(noun, items, cursor, partial) {
|
|
527
|
+
let msg = `${items.length} ${noun}(s) (cursor: ${cursor || 'end'}):\n\n${JSON.stringify(items)}`;
|
|
528
|
+
if (partial)
|
|
529
|
+
msg += `\n\n(partial — stopped early: ${partial})`;
|
|
530
|
+
return text(msg);
|
|
531
|
+
}
|
|
532
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
533
|
+
// Shared schema fragments
|
|
534
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
535
|
+
const sessionFields = {
|
|
536
|
+
sessionId: z.string().optional().describe('Browser session ID. If omitted, auto-selects the only open session.'),
|
|
537
|
+
tabId: z.string().optional().describe('Target a specific tab within the session (the bsky.app tab). Auto-resolved if omitted.'),
|
|
538
|
+
};
|
|
539
|
+
const cursorFields = {
|
|
540
|
+
limit: z.coerce.number().int().min(1).max(100).optional().describe('Items per page (default 50, max 100).'),
|
|
541
|
+
cursor: z.string().optional().describe('Pagination cursor from a prior call. Omit for the first page.'),
|
|
542
|
+
maxItems: z.coerce.number().int().min(1).max(500).optional().describe('Auto-paginate (follow cursors) until this many items are gathered in ONE call. Default = one page.'),
|
|
543
|
+
};
|
|
544
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
545
|
+
// 1. bluesky_session — whoami / login check
|
|
546
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
547
|
+
const blueskySessionSchema = {
|
|
548
|
+
validate: coerceBoolean().optional().describe('Also call com.atproto.server.getSession to verify the token server-side.'),
|
|
549
|
+
...sessionFields,
|
|
550
|
+
};
|
|
551
|
+
const blueskySessionDescription = 'BlueSky: who am I? Returns the logged-in account (did, handle, pdsUrl). Use first to confirm you are signed in. A blank assigned tab is safely initialized at bsky.app; nonblank tabs are never navigated implicitly. An expired session token is renewed inside the tool (waiting for bsky.app, then reloading its tab at most once), so "not logged in" means the page really has no session. Pass validate:true to check the token against the server.';
|
|
552
|
+
async function handleBlueskySession(args) {
|
|
553
|
+
const body = `
|
|
554
|
+
var s = __bskySession();
|
|
555
|
+
if (s.__bskyError) return s;
|
|
556
|
+
var out = { did: s.did, handle: s.handle, pdsUrl: s.pdsUrl };
|
|
557
|
+
if (${args.validate ? 'true' : 'false'}){
|
|
558
|
+
var v = await __bskyXrpc('com.atproto.server.getSession');
|
|
559
|
+
if (v.__bskyError) return v;
|
|
560
|
+
out.active = v.active; out.handle = v.handle || out.handle; out.email = v.email;
|
|
561
|
+
}
|
|
562
|
+
return out;`;
|
|
563
|
+
const r = await runBsky(args, body);
|
|
564
|
+
if ('error' in r)
|
|
565
|
+
return text(r.error);
|
|
566
|
+
return text(`BlueSky session: ${JSON.stringify(r.data)}`);
|
|
567
|
+
}
|
|
568
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
569
|
+
// 2. bluesky_timeline — home (following) feed
|
|
570
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
571
|
+
const blueskyTimelineSchema = { ...cursorFields, ...sessionFields };
|
|
572
|
+
const blueskyTimelineDescription = 'BlueSky: read your home timeline (following feed) as compact JSON posts (uri, cid, author, text, counts, viewer). Pass maxItems to auto-paginate. Returns the next cursor.';
|
|
573
|
+
async function handleBlueskyTimeline(args) {
|
|
574
|
+
const params = { limit: clampLimit(args.limit), cursor: args.cursor };
|
|
575
|
+
const body = `
|
|
576
|
+
var r = await __bskyPaginate('app.bsky.feed.getTimeline', ${jsLit(params)}, 'feed', ${args.maxItems || 0});
|
|
577
|
+
if (r.__bskyError) return r;
|
|
578
|
+
return { items: r.feed, cursor: r.cursor, partial: r.partial };`;
|
|
579
|
+
const r = await runBsky(args, body);
|
|
580
|
+
if ('error' in r)
|
|
581
|
+
return text(r.error);
|
|
582
|
+
return fmtList('post', (r.data.items || []).map(trimPost), r.data.cursor, r.data.partial);
|
|
583
|
+
}
|
|
584
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
585
|
+
// 3. bluesky_author_feed — a user's posts
|
|
586
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
587
|
+
const blueskyAuthorFeedSchema = {
|
|
588
|
+
actor: z.string().describe('Handle (e.g. alice.bsky.social) or DID of the author.'),
|
|
589
|
+
filter: z.enum(['posts_with_replies', 'posts_no_replies', 'posts_with_media', 'posts_and_author_threads']).optional()
|
|
590
|
+
.describe('Server-side filter. Default posts_with_replies.'),
|
|
591
|
+
...cursorFields, ...sessionFields,
|
|
592
|
+
};
|
|
593
|
+
const blueskyAuthorFeedDescription = "BlueSky: read a user's posts (author feed) as compact JSON. Pass actor (handle or DID), optional filter, and maxItems to auto-paginate.";
|
|
594
|
+
async function handleBlueskyAuthorFeed(args) {
|
|
595
|
+
const params = { actor: args.actor, filter: args.filter, limit: clampLimit(args.limit), cursor: args.cursor };
|
|
596
|
+
const body = `
|
|
597
|
+
var r = await __bskyPaginate('app.bsky.feed.getAuthorFeed', ${jsLit(params)}, 'feed', ${args.maxItems || 0});
|
|
598
|
+
if (r.__bskyError) return r;
|
|
599
|
+
return { items: r.feed, cursor: r.cursor, partial: r.partial };`;
|
|
600
|
+
const r = await runBsky(args, body);
|
|
601
|
+
if ('error' in r)
|
|
602
|
+
return text(r.error);
|
|
603
|
+
return fmtList('post', (r.data.items || []).map(trimPost), r.data.cursor, r.data.partial);
|
|
604
|
+
}
|
|
605
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
606
|
+
// 4. bluesky_thread — a post + its replies (returns uri+cid for replying)
|
|
607
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
608
|
+
const blueskyThreadSchema = {
|
|
609
|
+
uri: z.string().describe('Post AT-URI (at://...) OR a bsky.app post URL (https://bsky.app/profile/<handle>/post/<rkey>).'),
|
|
610
|
+
depth: z.coerce.number().int().min(0).max(20).optional().describe('Reply levels to fetch (default 6).'),
|
|
611
|
+
parentHeight: z.coerce.number().int().min(0).max(20).optional().describe('Parent levels to fetch (default 5).'),
|
|
612
|
+
...sessionFields,
|
|
613
|
+
};
|
|
614
|
+
const blueskyThreadDescription = 'BlueSky: read a post and its thread (parents + replies) as compact JSON. Accepts an AT-URI or a bsky.app post URL. Each post includes uri+cid (needed to reply/like/repost).';
|
|
615
|
+
async function handleBlueskyThread(args) {
|
|
616
|
+
const depth = args.depth != null ? args.depth : 6;
|
|
617
|
+
const ph = args.parentHeight != null ? args.parentHeight : 5;
|
|
618
|
+
const body = `
|
|
619
|
+
var uri = await __bskyNormUri(${jsLit(args.uri)});
|
|
620
|
+
if (!uri) return { __bskyError: 'Could not resolve that post URL to an at-uri.' };
|
|
621
|
+
var r = await __bskyXrpc('app.bsky.feed.getPostThread', { params:{ uri: uri, depth: ${depth}, parentHeight: ${ph} } });
|
|
622
|
+
if (r.__bskyError) return r;
|
|
623
|
+
return r.thread;`;
|
|
624
|
+
const r = await runBsky(args, body);
|
|
625
|
+
if ('error' in r)
|
|
626
|
+
return text(r.error);
|
|
627
|
+
return text(`Thread:\n\n${JSON.stringify(trimThread(r.data))}`);
|
|
628
|
+
}
|
|
629
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
630
|
+
// 5. bluesky_profile — actor profile
|
|
631
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
632
|
+
const blueskyProfileSchema = {
|
|
633
|
+
actor: z.string().describe('Handle or DID to look up.'),
|
|
634
|
+
...sessionFields,
|
|
635
|
+
};
|
|
636
|
+
const blueskyProfileDescription = 'BlueSky: get an actor profile (did, handle, name, bio, follower/following/post counts, and your viewer relationship: following/followedBy/muted/blocking).';
|
|
637
|
+
async function handleBlueskyProfile(args) {
|
|
638
|
+
const body = `
|
|
639
|
+
var r = await __bskyXrpc('app.bsky.actor.getProfile', { params:{ actor: ${jsLit(args.actor)} } });
|
|
640
|
+
if (r.__bskyError) return r;
|
|
641
|
+
return r;`;
|
|
642
|
+
const r = await runBsky(args, body);
|
|
643
|
+
if ('error' in r)
|
|
644
|
+
return text(r.error);
|
|
645
|
+
return text(`Profile:\n\n${JSON.stringify(trimActor(r.data))}`);
|
|
646
|
+
}
|
|
647
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
648
|
+
// 6. bluesky_search_posts
|
|
649
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
650
|
+
const blueskySearchPostsSchema = {
|
|
651
|
+
q: z.string().describe('Search query.'),
|
|
652
|
+
sort: z.enum(['top', 'latest']).optional().describe('Ranking. Default top.'),
|
|
653
|
+
since: z.string().optional().describe('Lower bound, ISO datetime or YYYY-MM-DD.'),
|
|
654
|
+
until: z.string().optional().describe('Upper bound, ISO datetime or YYYY-MM-DD.'),
|
|
655
|
+
author: z.string().optional().describe('Limit to posts by this handle/DID.'),
|
|
656
|
+
lang: z.string().optional().describe('BCP-47 language filter, e.g. en.'),
|
|
657
|
+
...cursorFields, ...sessionFields,
|
|
658
|
+
};
|
|
659
|
+
const blueskySearchPostsDescription = 'BlueSky: full-text search posts. Supports sort (top/latest), since/until, author, lang. Pass maxItems to auto-paginate. Returns compact posts + next cursor.';
|
|
660
|
+
async function handleBlueskySearchPosts(args) {
|
|
661
|
+
const params = { q: args.q, sort: args.sort, since: args.since, until: args.until, author: args.author, lang: args.lang, limit: clampLimit(args.limit), cursor: args.cursor };
|
|
662
|
+
const body = `
|
|
663
|
+
var r = await __bskyPaginate('app.bsky.feed.searchPosts', ${jsLit(params)}, 'posts', ${args.maxItems || 0});
|
|
664
|
+
if (r.__bskyError) return r;
|
|
665
|
+
return { items: r.posts, cursor: r.cursor, partial: r.partial };`;
|
|
666
|
+
const r = await runBsky(args, body);
|
|
667
|
+
if ('error' in r)
|
|
668
|
+
return text(r.error);
|
|
669
|
+
return fmtList('post', (r.data.items || []).map(trimPost), r.data.cursor, r.data.partial);
|
|
670
|
+
}
|
|
671
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
672
|
+
// 7. bluesky_search_actors
|
|
673
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
674
|
+
const blueskySearchActorsSchema = {
|
|
675
|
+
q: z.string().describe('Search query (name / handle).'),
|
|
676
|
+
...cursorFields, ...sessionFields,
|
|
677
|
+
};
|
|
678
|
+
const blueskySearchActorsDescription = 'BlueSky: search for users (actors). Returns compact actor cards (did, handle, name, bio, viewer relationship) + next cursor. Pass maxItems to auto-paginate.';
|
|
679
|
+
async function handleBlueskySearchActors(args) {
|
|
680
|
+
const params = { q: args.q, limit: clampLimit(args.limit), cursor: args.cursor };
|
|
681
|
+
const body = `
|
|
682
|
+
var r = await __bskyPaginate('app.bsky.actor.searchActors', ${jsLit(params)}, 'actors', ${args.maxItems || 0});
|
|
683
|
+
if (r.__bskyError) return r;
|
|
684
|
+
return { items: r.actors, cursor: r.cursor, partial: r.partial };`;
|
|
685
|
+
const r = await runBsky(args, body);
|
|
686
|
+
if ('error' in r)
|
|
687
|
+
return text(r.error);
|
|
688
|
+
return fmtList('actor', (r.data.items || []).map(trimActor), r.data.cursor, r.data.partial);
|
|
689
|
+
}
|
|
690
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
691
|
+
// 8. bluesky_notifications
|
|
692
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
693
|
+
const blueskyNotificationsSchema = {
|
|
694
|
+
priority: coerceBoolean().optional().describe('Only priority notifications.'),
|
|
695
|
+
markSeen: coerceBoolean().optional().describe('Mark notifications seen (updates the seen timestamp) after fetching.'),
|
|
696
|
+
...cursorFields, ...sessionFields,
|
|
697
|
+
};
|
|
698
|
+
const blueskyNotificationsDescription = 'BlueSky: list your notifications (likes, reposts, replies, mentions, follows) as compact JSON. Pass markSeen:true to clear the unread badge, maxItems to auto-paginate.';
|
|
699
|
+
async function handleBlueskyNotifications(args) {
|
|
700
|
+
const params = { limit: clampLimit(args.limit), cursor: args.cursor, priority: args.priority };
|
|
701
|
+
const body = `
|
|
702
|
+
var r = await __bskyPaginate('app.bsky.notification.listNotifications', ${jsLit(params)}, 'notifications', ${args.maxItems || 0});
|
|
703
|
+
if (r.__bskyError) return r;
|
|
704
|
+
if (${args.markSeen ? 'true' : 'false'}){
|
|
705
|
+
await __bskyXrpc('app.bsky.notification.updateSeen', { verb:'POST', body:{ seenAt: new Date().toISOString() } });
|
|
706
|
+
}
|
|
707
|
+
return { items: r.notifications, cursor: r.cursor, partial: r.partial };`;
|
|
708
|
+
const r = await runBsky(args, body);
|
|
709
|
+
if ('error' in r)
|
|
710
|
+
return text(r.error);
|
|
711
|
+
return fmtList('notification', (r.data.items || []).map(trimNotif), r.data.cursor, r.data.partial);
|
|
712
|
+
}
|
|
713
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
714
|
+
// 9. bluesky_graph — followers / follows
|
|
715
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
716
|
+
const blueskyGraphSchema = {
|
|
717
|
+
actor: z.string().describe('Handle or DID whose graph to read.'),
|
|
718
|
+
which: z.enum(['followers', 'follows']).describe('followers = who follows them; follows = who they follow.'),
|
|
719
|
+
...cursorFields, ...sessionFields,
|
|
720
|
+
};
|
|
721
|
+
const blueskyGraphDescription = "BlueSky: list an actor's followers or follows as compact actor cards + next cursor. Pass maxItems to auto-paginate.";
|
|
722
|
+
async function handleBlueskyGraph(args) {
|
|
723
|
+
const method = args.which === 'followers' ? 'app.bsky.graph.getFollowers' : 'app.bsky.graph.getFollows';
|
|
724
|
+
const key = args.which;
|
|
725
|
+
const params = { actor: args.actor, limit: clampLimit(args.limit), cursor: args.cursor };
|
|
726
|
+
const body = `
|
|
727
|
+
var r = await __bskyPaginate(${jsLit(method)}, ${jsLit(params)}, ${jsLit(key)}, ${args.maxItems || 0});
|
|
728
|
+
if (r.__bskyError) return r;
|
|
729
|
+
return { items: r[${jsLit(key)}], cursor: r.cursor, partial: r.partial };`;
|
|
730
|
+
const r = await runBsky(args, body);
|
|
731
|
+
if ('error' in r)
|
|
732
|
+
return text(r.error);
|
|
733
|
+
return fmtList('actor', (r.data.items || []).map(trimActor), r.data.cursor, r.data.partial);
|
|
734
|
+
}
|
|
735
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
736
|
+
// 10. bluesky_likes — likes on a post, or posts an actor liked
|
|
737
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
738
|
+
const blueskyLikesSchema = {
|
|
739
|
+
mode: z.enum(['post', 'actor']).describe('post = who liked a post (needs uri); actor = posts an actor has liked (needs actor).'),
|
|
740
|
+
uri: z.string().optional().describe('Post AT-URI or bsky.app URL (mode=post).'),
|
|
741
|
+
actor: z.string().optional().describe('Handle or DID (mode=actor).'),
|
|
742
|
+
...cursorFields, ...sessionFields,
|
|
743
|
+
};
|
|
744
|
+
const blueskyLikesDescription = 'BlueSky: list likes. mode=post → the actors who liked a given post; mode=actor → the posts an actor has liked. Pass maxItems to auto-paginate.';
|
|
745
|
+
async function handleBlueskyLikes(args) {
|
|
746
|
+
if (args.mode === 'post') {
|
|
747
|
+
if (!args.uri)
|
|
748
|
+
return text('mode=post requires uri (the post to inspect).');
|
|
749
|
+
const params = { limit: clampLimit(args.limit), cursor: args.cursor };
|
|
750
|
+
const body = `
|
|
751
|
+
var uri = await __bskyNormUri(${jsLit(args.uri)});
|
|
752
|
+
if (!uri) return { __bskyError: 'Could not resolve that post URL to an at-uri.' };
|
|
753
|
+
var p = Object.assign({ uri: uri }, ${jsLit(params)});
|
|
754
|
+
var r = await __bskyPaginate('app.bsky.feed.getLikes', p, 'likes', ${args.maxItems || 0});
|
|
755
|
+
if (r.__bskyError) return r;
|
|
756
|
+
return { items: r.likes, cursor: r.cursor, partial: r.partial };`;
|
|
757
|
+
const r = await runBsky(args, body);
|
|
758
|
+
if ('error' in r)
|
|
759
|
+
return text(r.error);
|
|
760
|
+
const items = (r.data.items || []).map((l) => ({ actor: trimActor(l.actor), createdAt: l.createdAt }));
|
|
761
|
+
return fmtList('like', items, r.data.cursor, r.data.partial);
|
|
762
|
+
}
|
|
763
|
+
if (!args.actor)
|
|
764
|
+
return text('mode=actor requires actor (handle or DID).');
|
|
765
|
+
const params = { actor: args.actor, limit: clampLimit(args.limit), cursor: args.cursor };
|
|
766
|
+
const body = `
|
|
767
|
+
var r = await __bskyPaginate('app.bsky.feed.getActorLikes', ${jsLit(params)}, 'feed', ${args.maxItems || 0});
|
|
768
|
+
if (r.__bskyError) return r;
|
|
769
|
+
return { items: r.feed, cursor: r.cursor, partial: r.partial };`;
|
|
770
|
+
const r = await runBsky(args, body);
|
|
771
|
+
if ('error' in r)
|
|
772
|
+
return text(r.error);
|
|
773
|
+
return fmtList('post', (r.data.items || []).map(trimPost), r.data.cursor, r.data.partial);
|
|
774
|
+
}
|
|
775
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
776
|
+
// 11. bluesky_feed — custom feed generators & lists
|
|
777
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
778
|
+
const blueskyFeedSchema = {
|
|
779
|
+
mode: z.enum(['feed', 'list']).describe('feed = a custom feed generator; list = a user list timeline.'),
|
|
780
|
+
uri: z.string().describe('AT-URI of the feed generator (mode=feed) or the list (mode=list).'),
|
|
781
|
+
...cursorFields, ...sessionFields,
|
|
782
|
+
};
|
|
783
|
+
const blueskyFeedDescription = 'BlueSky: read a custom feed generator (mode=feed) or a list timeline (mode=list) by its AT-URI. Returns compact posts + next cursor. Pass maxItems to auto-paginate.';
|
|
784
|
+
async function handleBlueskyFeed(args) {
|
|
785
|
+
const method = args.mode === 'feed' ? 'app.bsky.feed.getFeed' : 'app.bsky.feed.getListFeed';
|
|
786
|
+
const param = args.mode === 'feed' ? { feed: args.uri } : { list: args.uri };
|
|
787
|
+
const params = { ...param, limit: clampLimit(args.limit), cursor: args.cursor };
|
|
788
|
+
const body = `
|
|
789
|
+
var r = await __bskyPaginate(${jsLit(method)}, ${jsLit(params)}, 'feed', ${args.maxItems || 0});
|
|
790
|
+
if (r.__bskyError) return r;
|
|
791
|
+
return { items: r.feed, cursor: r.cursor, partial: r.partial };`;
|
|
792
|
+
const r = await runBsky(args, body);
|
|
793
|
+
if ('error' in r)
|
|
794
|
+
return text(r.error);
|
|
795
|
+
return fmtList('post', (r.data.items || []).map(trimPost), r.data.cursor, r.data.partial);
|
|
796
|
+
}
|
|
797
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
798
|
+
// 12. bluesky_post — create a post / reply / quote, with images
|
|
799
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
800
|
+
const blueskyPostSchema = {
|
|
801
|
+
text: z.string().describe('Post text (max 300 graphemes). @mentions, URLs and #hashtags are auto-detected into rich-text facets.'),
|
|
802
|
+
replyTo: z.string().optional().describe('Reply to this post (AT-URI or bsky.app URL). Root/parent refs are derived automatically.'),
|
|
803
|
+
quote: z.string().optional().describe('Quote-post this post (AT-URI or bsky.app URL).'),
|
|
804
|
+
images: z.array(z.object({
|
|
805
|
+
url: z.string().optional().describe('Image URL the browser can fetch.'),
|
|
806
|
+
path: z.string().optional().describe('Local file path on this machine (uploaded via the Neural Interface).'),
|
|
807
|
+
alt: z.string().optional().describe('Alt text (accessibility — recommended).'),
|
|
808
|
+
})).max(4).optional().describe('Up to 4 images; give url OR path for each. Images take precedence over a quote embed.'),
|
|
809
|
+
langs: z.array(z.string()).optional().describe('BCP-47 language tags. Default ["en"].'),
|
|
810
|
+
...sessionFields,
|
|
811
|
+
};
|
|
812
|
+
const blueskyPostDescription = 'BlueSky: publish a post. Supports plain text with auto-facets (@mentions, links, #hashtags), replies (replyTo), quote-posts (quote), and up to 4 images (by url or local path, each with alt text). A link card (OG preview with thumbnail) is auto-generated for the first URL when the post has no images and no quote. Returns the new post uri+cid.';
|
|
813
|
+
async function handleBlueskyPost(args) {
|
|
814
|
+
const resolved = await prepareBsky(args);
|
|
815
|
+
if ('error' in resolved)
|
|
816
|
+
return text(resolved.error);
|
|
817
|
+
const images = args.images || [];
|
|
818
|
+
if (images.length > 4)
|
|
819
|
+
return text('BlueSky allows at most 4 images per post.');
|
|
820
|
+
// Local-file images: upload via the Neural Interface (page context can't read disk).
|
|
821
|
+
const urlImages = [];
|
|
822
|
+
const preImages = [];
|
|
823
|
+
for (const img of images) {
|
|
824
|
+
if (img.path) {
|
|
825
|
+
const up = await beforeDeadline(ni.uploadBlueskyBlob(resolved.sessionId, img.path, resolved.tabId), resolved.deadlineAt - BSKY_SCRIPT_RESERVE_MS, `uploading ${img.path}`);
|
|
826
|
+
if (up.error)
|
|
827
|
+
return text(`Image upload failed for ${img.path}: ${up.error}${timedOut(up) ? ' Nothing was posted.' : ''}`);
|
|
828
|
+
const blob = up.blob;
|
|
829
|
+
if (!blob)
|
|
830
|
+
return text(`Image upload returned no blob for ${img.path}.`);
|
|
831
|
+
preImages.push({ blob, alt: img.alt || '' });
|
|
832
|
+
}
|
|
833
|
+
else if (img.url) {
|
|
834
|
+
urlImages.push({ url: img.url, alt: img.alt || '' });
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
const langs = args.langs && args.langs.length ? args.langs : ['en'];
|
|
838
|
+
const body = `
|
|
839
|
+
var TEXT = ${jsLit(args.text)};
|
|
840
|
+
var LANGS = ${jsLit(langs)};
|
|
841
|
+
var REPLY_TO = ${jsLit(args.replyTo || null)};
|
|
842
|
+
var QUOTE = ${jsLit(args.quote || null)};
|
|
843
|
+
var URL_IMAGES = ${jsLit(urlImages)};
|
|
844
|
+
var PRE_IMAGES = ${jsLit(preImages)};
|
|
845
|
+
|
|
846
|
+
var s = __bskySession();
|
|
847
|
+
if (s.__bskyError) return s;
|
|
848
|
+
|
|
849
|
+
function byteIdx(str, jsIdx){ return new TextEncoder().encode(str.slice(0, jsIdx)).length; }
|
|
850
|
+
var facets = [];
|
|
851
|
+
var firstUrl = null;
|
|
852
|
+
var re, m;
|
|
853
|
+
re = /https?:[/][/][^\\s)]+/g;
|
|
854
|
+
while ((m = re.exec(TEXT))){
|
|
855
|
+
if (!firstUrl) firstUrl = m[0];
|
|
856
|
+
facets.push({ index:{ byteStart: byteIdx(TEXT, m.index), byteEnd: byteIdx(TEXT, m.index + m[0].length) }, features:[{ '$type':'app.bsky.richtext.facet#link', uri: m[0] }] });
|
|
857
|
+
}
|
|
858
|
+
re = /(^|\\s)(#[^\\s#]+)/g;
|
|
859
|
+
while ((m = re.exec(TEXT))){
|
|
860
|
+
var tag = m[2]; var at = m.index + m[1].length;
|
|
861
|
+
facets.push({ index:{ byteStart: byteIdx(TEXT, at), byteEnd: byteIdx(TEXT, at + tag.length) }, features:[{ '$type':'app.bsky.richtext.facet#tag', tag: tag.slice(1) }] });
|
|
862
|
+
}
|
|
863
|
+
re = /(^|\\s)(@[a-zA-Z0-9.-]+)/g;
|
|
864
|
+
var pend = [];
|
|
865
|
+
while ((m = re.exec(TEXT))){
|
|
866
|
+
var mh = m[2].slice(1).replace(/[.]+$/, ''); var mat = m.index + m[1].length;
|
|
867
|
+
pend.push({ handle: mh, bs: byteIdx(TEXT, mat), be: byteIdx(TEXT, mat + 1 + mh.length) });
|
|
868
|
+
}
|
|
869
|
+
for (var i=0;i<pend.length;i++){
|
|
870
|
+
var rr = await __bskyXrpc('com.atproto.identity.resolveHandle', { params:{ handle: pend[i].handle } });
|
|
871
|
+
if (rr && rr.did) facets.push({ index:{ byteStart: pend[i].bs, byteEnd: pend[i].be }, features:[{ '$type':'app.bsky.richtext.facet#mention', did: rr.did }] });
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
var record = { '$type':'app.bsky.feed.post', text: TEXT, createdAt: new Date().toISOString() };
|
|
875
|
+
if (LANGS && LANGS.length) record.langs = LANGS;
|
|
876
|
+
if (facets.length) record.facets = facets;
|
|
877
|
+
|
|
878
|
+
if (REPLY_TO){
|
|
879
|
+
var ru = await __bskyNormUri(REPLY_TO);
|
|
880
|
+
if (!ru) return { __bskyError: 'Could not resolve replyTo to an at-uri.' };
|
|
881
|
+
var th = await __bskyXrpc('app.bsky.feed.getPostThread', { params:{ uri: ru, depth: 0, parentHeight: 0 } });
|
|
882
|
+
if (th.__bskyError) return th;
|
|
883
|
+
var pp = th.thread && th.thread.post;
|
|
884
|
+
if (!pp) return { __bskyError: 'replyTo post not found.' };
|
|
885
|
+
var parentRef = { uri: pp.uri, cid: pp.cid };
|
|
886
|
+
var rootRef = (pp.record && pp.record.reply && pp.record.reply.root) ? pp.record.reply.root : parentRef;
|
|
887
|
+
record.reply = { root: rootRef, parent: parentRef };
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
var imgs = [];
|
|
891
|
+
for (var i=0;i<PRE_IMAGES.length;i++) imgs.push({ alt: PRE_IMAGES[i].alt || '', image: PRE_IMAGES[i].blob });
|
|
892
|
+
for (var i=0;i<URL_IMAGES.length;i++){
|
|
893
|
+
var ub = await __bskyUploadBlobFromUrl(URL_IMAGES[i].url);
|
|
894
|
+
if (ub.__bskyError) return ub;
|
|
895
|
+
imgs.push({ alt: URL_IMAGES[i].alt || '', image: ub.blob });
|
|
896
|
+
}
|
|
897
|
+
var embed = null;
|
|
898
|
+
if (imgs.length){
|
|
899
|
+
embed = { '$type':'app.bsky.embed.images', images: imgs };
|
|
900
|
+
} else if (QUOTE){
|
|
901
|
+
var qu = await __bskyNormUri(QUOTE);
|
|
902
|
+
if (!qu) return { __bskyError: 'Could not resolve quote to an at-uri.' };
|
|
903
|
+
var qth = await __bskyXrpc('app.bsky.feed.getPostThread', { params:{ uri: qu, depth: 0, parentHeight: 0 } });
|
|
904
|
+
if (qth.__bskyError) return qth;
|
|
905
|
+
var qp = qth.thread && qth.thread.post;
|
|
906
|
+
if (!qp) return { __bskyError: 'quote post not found.' };
|
|
907
|
+
embed = { '$type':'app.bsky.embed.record', record: { uri: qp.uri, cid: qp.cid } };
|
|
908
|
+
} else if (firstUrl){
|
|
909
|
+
// OG link card (app.bsky.embed.external), built the way the official client does via
|
|
910
|
+
// CardyB (server-side OG fetch, avoids CORS on the target site). Best-effort: on ANY
|
|
911
|
+
// failure fall back to the bare faceted link so the post still publishes.
|
|
912
|
+
try {
|
|
913
|
+
var cardRes = await fetch('https://cardyb.bsky.app/v1/extract?url=' + encodeURIComponent(firstUrl));
|
|
914
|
+
if (cardRes.ok){
|
|
915
|
+
var card = await cardRes.json();
|
|
916
|
+
if (card && !card.error && (card.title || card.description)){
|
|
917
|
+
var ext = { uri: firstUrl, title: String(card.title || ''), description: String(card.description || '') };
|
|
918
|
+
if (card.image){
|
|
919
|
+
var tb = await __bskyUploadBlobFromUrl(card.image);
|
|
920
|
+
if (!tb.__bskyError && tb.blob) ext.thumb = tb.blob;
|
|
921
|
+
}
|
|
922
|
+
embed = { '$type':'app.bsky.embed.external', external: ext };
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
} catch(e){}
|
|
926
|
+
}
|
|
927
|
+
if (embed) record.embed = embed;
|
|
928
|
+
|
|
929
|
+
var cr = await __bskyXrpc('com.atproto.repo.createRecord', { verb:'POST', body:{ repo: s.did, collection:'app.bsky.feed.post', record: record } });
|
|
930
|
+
if (cr.__bskyError) return cr;
|
|
931
|
+
return { uri: cr.uri, cid: cr.cid };`;
|
|
932
|
+
const r = await runPrepared(resolved, body);
|
|
933
|
+
if ('error' in r)
|
|
934
|
+
return text(r.error);
|
|
935
|
+
return text(`Posted to BlueSky: ${JSON.stringify({ uri: r.data.uri, cid: r.data.cid })}`);
|
|
936
|
+
}
|
|
937
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
938
|
+
// 13. bluesky_action — like/repost/follow/mute/block/delete (+ undos)
|
|
939
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
940
|
+
const blueskyActionSchema = {
|
|
941
|
+
action: z.enum(['like', 'unlike', 'repost', 'unrepost', 'follow', 'unfollow', 'mute', 'unmute', 'block', 'unblock', 'delete'])
|
|
942
|
+
.describe('The action to perform.'),
|
|
943
|
+
target: z.string().describe('Post actions (like/unlike/repost/unrepost/delete): post AT-URI or bsky.app URL. Actor actions (follow/unfollow/mute/unmute/block/unblock): handle or DID.'),
|
|
944
|
+
...sessionFields,
|
|
945
|
+
};
|
|
946
|
+
const blueskyActionDescription = 'BlueSky: act on a post or actor. Post: like/unlike, repost/unrepost, delete (your own). Actor: follow/unfollow, mute/unmute, block/unblock. Undo actions resolve the record key automatically — never pass rkeys.';
|
|
947
|
+
async function handleBlueskyAction(args) {
|
|
948
|
+
const body = `
|
|
949
|
+
var ACTION = ${jsLit(args.action)};
|
|
950
|
+
var TARGET = ${jsLit(args.target)};
|
|
951
|
+
var s = __bskySession();
|
|
952
|
+
if (s.__bskyError) return s;
|
|
953
|
+
var did = s.did;
|
|
954
|
+
function rkeyFromUri(uri){ var parts = String(uri).split('/'); return parts[parts.length-1]; }
|
|
955
|
+
async function getPostRef(input){
|
|
956
|
+
var uri = await __bskyNormUri(input);
|
|
957
|
+
if (!uri) return { __bskyError: 'Could not resolve target to an at-uri.' };
|
|
958
|
+
var r = await __bskyXrpc('app.bsky.feed.getPosts', { params:{ uris: [uri] } });
|
|
959
|
+
if (r.__bskyError) return r;
|
|
960
|
+
var p = r.posts && r.posts[0];
|
|
961
|
+
if (!p) return { __bskyError: 'Target post not found.' };
|
|
962
|
+
return { uri: p.uri, cid: p.cid, viewer: p.viewer || {} };
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
if (ACTION === 'like' || ACTION === 'repost'){
|
|
966
|
+
var ref = await getPostRef(TARGET);
|
|
967
|
+
if (ref.__bskyError) return ref;
|
|
968
|
+
var col = ACTION === 'like' ? 'app.bsky.feed.like' : 'app.bsky.feed.repost';
|
|
969
|
+
var cr = await __bskyXrpc('com.atproto.repo.createRecord', { verb:'POST', body:{ repo: did, collection: col, record:{ '$type': col, subject:{ uri: ref.uri, cid: ref.cid }, createdAt: new Date().toISOString() } } });
|
|
970
|
+
if (cr.__bskyError) return cr;
|
|
971
|
+
return { ok:true, action: ACTION, uri: cr.uri };
|
|
972
|
+
}
|
|
973
|
+
if (ACTION === 'unlike' || ACTION === 'unrepost'){
|
|
974
|
+
var ref = await getPostRef(TARGET);
|
|
975
|
+
if (ref.__bskyError) return ref;
|
|
976
|
+
var existing = ACTION === 'unlike' ? ref.viewer.like : ref.viewer.repost;
|
|
977
|
+
if (!existing) return { ok:true, action: ACTION, note: 'was not ' + (ACTION === 'unlike' ? 'liked' : 'reposted') };
|
|
978
|
+
var col = ACTION === 'unlike' ? 'app.bsky.feed.like' : 'app.bsky.feed.repost';
|
|
979
|
+
var dr = await __bskyXrpc('com.atproto.repo.deleteRecord', { verb:'POST', body:{ repo: did, collection: col, rkey: rkeyFromUri(existing) } });
|
|
980
|
+
if (dr.__bskyError) return dr;
|
|
981
|
+
return { ok:true, action: ACTION };
|
|
982
|
+
}
|
|
983
|
+
if (ACTION === 'follow' || ACTION === 'block'){
|
|
984
|
+
var adid = await __bskyResolveActor(TARGET);
|
|
985
|
+
if (!adid) return { __bskyError: 'Could not resolve actor: ' + TARGET };
|
|
986
|
+
var col = ACTION === 'follow' ? 'app.bsky.graph.follow' : 'app.bsky.graph.block';
|
|
987
|
+
var cr = await __bskyXrpc('com.atproto.repo.createRecord', { verb:'POST', body:{ repo: did, collection: col, record:{ '$type': col, subject: adid, createdAt: new Date().toISOString() } } });
|
|
988
|
+
if (cr.__bskyError) return cr;
|
|
989
|
+
return { ok:true, action: ACTION, uri: cr.uri };
|
|
990
|
+
}
|
|
991
|
+
if (ACTION === 'unfollow' || ACTION === 'unblock'){
|
|
992
|
+
var adid = await __bskyResolveActor(TARGET);
|
|
993
|
+
if (!adid) return { __bskyError: 'Could not resolve actor: ' + TARGET };
|
|
994
|
+
var pr = await __bskyXrpc('app.bsky.actor.getProfile', { params:{ actor: adid } });
|
|
995
|
+
if (pr.__bskyError) return pr;
|
|
996
|
+
var v = pr.viewer || {};
|
|
997
|
+
var existing = ACTION === 'unfollow' ? v.following : v.blocking;
|
|
998
|
+
if (!existing) return { ok:true, action: ACTION, note: 'was not ' + (ACTION === 'unfollow' ? 'following' : 'blocking') };
|
|
999
|
+
var col = ACTION === 'unfollow' ? 'app.bsky.graph.follow' : 'app.bsky.graph.block';
|
|
1000
|
+
var dr = await __bskyXrpc('com.atproto.repo.deleteRecord', { verb:'POST', body:{ repo: did, collection: col, rkey: rkeyFromUri(existing) } });
|
|
1001
|
+
if (dr.__bskyError) return dr;
|
|
1002
|
+
return { ok:true, action: ACTION };
|
|
1003
|
+
}
|
|
1004
|
+
if (ACTION === 'mute' || ACTION === 'unmute'){
|
|
1005
|
+
var adid = await __bskyResolveActor(TARGET);
|
|
1006
|
+
if (!adid) return { __bskyError: 'Could not resolve actor: ' + TARGET };
|
|
1007
|
+
var method = ACTION === 'mute' ? 'app.bsky.graph.muteActor' : 'app.bsky.graph.unmuteActor';
|
|
1008
|
+
var mr = await __bskyXrpc(method, { verb:'POST', body:{ actor: adid } });
|
|
1009
|
+
if (mr.__bskyError) return mr;
|
|
1010
|
+
return { ok:true, action: ACTION };
|
|
1011
|
+
}
|
|
1012
|
+
if (ACTION === 'delete'){
|
|
1013
|
+
var uri = await __bskyNormUri(TARGET);
|
|
1014
|
+
if (!uri) return { __bskyError: 'Could not resolve target to an at-uri.' };
|
|
1015
|
+
var parts = String(uri).replace('at://','').split('/');
|
|
1016
|
+
var repo = parts[0]; var col = parts[1] || 'app.bsky.feed.post'; var rkey = parts[2];
|
|
1017
|
+
if (repo !== did) return { __bskyError: 'Can only delete your own records (target belongs to ' + repo + ').' };
|
|
1018
|
+
var dr = await __bskyXrpc('com.atproto.repo.deleteRecord', { verb:'POST', body:{ repo: did, collection: col, rkey: rkey } });
|
|
1019
|
+
if (dr.__bskyError) return dr;
|
|
1020
|
+
return { ok:true, action:'delete', uri: uri };
|
|
1021
|
+
}
|
|
1022
|
+
return { __bskyError: 'Unknown action: ' + ACTION };`;
|
|
1023
|
+
const r = await runBsky(args, body);
|
|
1024
|
+
if ('error' in r)
|
|
1025
|
+
return text(r.error);
|
|
1026
|
+
return text(`BlueSky action: ${JSON.stringify(r.data)}`);
|
|
1027
|
+
}
|
|
1028
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
1029
|
+
// 14. bluesky_resolve — handle → DID
|
|
1030
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
1031
|
+
const blueskyResolveSchema = {
|
|
1032
|
+
handle: z.string().describe('Handle to resolve, e.g. alice.bsky.social.'),
|
|
1033
|
+
...sessionFields,
|
|
1034
|
+
};
|
|
1035
|
+
const blueskyResolveDescription = 'BlueSky: resolve a handle to its DID (com.atproto.identity.resolveHandle).';
|
|
1036
|
+
async function handleBlueskyResolve(args) {
|
|
1037
|
+
const body = `
|
|
1038
|
+
var r = await __bskyXrpc('com.atproto.identity.resolveHandle', { params:{ handle: ${jsLit(args.handle)} } });
|
|
1039
|
+
if (r.__bskyError) return r;
|
|
1040
|
+
return { handle: ${jsLit(args.handle)}, did: r.did };`;
|
|
1041
|
+
const r = await runBsky(args, body);
|
|
1042
|
+
if ('error' in r)
|
|
1043
|
+
return text(r.error);
|
|
1044
|
+
return text(`Resolved: ${JSON.stringify(r.data)}`);
|
|
1045
|
+
}
|
|
1046
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
1047
|
+
// 15. bluesky_dm — direct messages (chat.bsky.* via the chat service proxy)
|
|
1048
|
+
// ═════════════════════════════════════════════════════════════════════════
|
|
1049
|
+
const CHAT_PROXY = 'did:web:api.bsky.chat#bsky_chat';
|
|
1050
|
+
const blueskyDmSchema = {
|
|
1051
|
+
action: z.enum(['list_convos', 'messages', 'send', 'mark_read'])
|
|
1052
|
+
.describe('list_convos = your DM conversations; messages = messages in a convo; send = send a message; mark_read = mark a convo read.'),
|
|
1053
|
+
convoId: z.string().optional().describe('Conversation ID (messages/mark_read; send if not using members).'),
|
|
1054
|
+
members: z.array(z.string()).optional().describe('For send: handles/DIDs to open/find a convo with, instead of convoId.'),
|
|
1055
|
+
text: z.string().optional().describe('Message text (required for send).'),
|
|
1056
|
+
...cursorFields, ...sessionFields,
|
|
1057
|
+
};
|
|
1058
|
+
const blueskyDmDescription = 'BlueSky DMs (chat.bsky.*): list_convos, read messages in a convo, send a message (by convoId or members), or mark_read. Returns compact JSON.';
|
|
1059
|
+
async function handleBlueskyDm(args) {
|
|
1060
|
+
const proxy = jsLit(CHAT_PROXY);
|
|
1061
|
+
if (args.action === 'list_convos') {
|
|
1062
|
+
const params = { limit: clampLimit(args.limit), cursor: args.cursor };
|
|
1063
|
+
const body = `
|
|
1064
|
+
var r = await __bskyPaginate('chat.bsky.convo.listConvos', ${jsLit(params)}, 'convos', ${args.maxItems || 0}, ${proxy});
|
|
1065
|
+
if (r.__bskyError) return r;
|
|
1066
|
+
return { items: r.convos, cursor: r.cursor, partial: r.partial };`;
|
|
1067
|
+
const r = await runBsky(args, body);
|
|
1068
|
+
if ('error' in r)
|
|
1069
|
+
return text(r.error);
|
|
1070
|
+
return fmtList('convo', (r.data.items || []).map(trimConvo), r.data.cursor, r.data.partial);
|
|
1071
|
+
}
|
|
1072
|
+
if (args.action === 'messages') {
|
|
1073
|
+
if (!args.convoId)
|
|
1074
|
+
return text('action=messages requires convoId.');
|
|
1075
|
+
const params = { convoId: args.convoId, limit: clampLimit(args.limit), cursor: args.cursor };
|
|
1076
|
+
const body = `
|
|
1077
|
+
var r = await __bskyPaginate('chat.bsky.convo.getMessages', ${jsLit(params)}, 'messages', ${args.maxItems || 0}, ${proxy});
|
|
1078
|
+
if (r.__bskyError) return r;
|
|
1079
|
+
return { items: r.messages, cursor: r.cursor, partial: r.partial };`;
|
|
1080
|
+
const r = await runBsky(args, body);
|
|
1081
|
+
if ('error' in r)
|
|
1082
|
+
return text(r.error);
|
|
1083
|
+
return fmtList('message', (r.data.items || []).map(trimMessage), r.data.cursor, r.data.partial);
|
|
1084
|
+
}
|
|
1085
|
+
if (args.action === 'send') {
|
|
1086
|
+
if (!args.text)
|
|
1087
|
+
return text('action=send requires text.');
|
|
1088
|
+
if (!args.convoId && !(args.members && args.members.length))
|
|
1089
|
+
return text('action=send requires convoId or members.');
|
|
1090
|
+
const body = `
|
|
1091
|
+
var convoId = ${jsLit(args.convoId || null)};
|
|
1092
|
+
var MEMBERS = ${jsLit(args.members || [])};
|
|
1093
|
+
if (!convoId){
|
|
1094
|
+
var dids = [];
|
|
1095
|
+
for (var i=0;i<MEMBERS.length;i++){ var d = await __bskyResolveActor(MEMBERS[i]); if (!d) return { __bskyError: 'Could not resolve member: ' + MEMBERS[i] }; dids.push(d); }
|
|
1096
|
+
var cr = await __bskyXrpc('chat.bsky.convo.getConvoForMembers', { params:{ members: dids }, proxy: ${proxy} });
|
|
1097
|
+
if (cr.__bskyError) return cr;
|
|
1098
|
+
convoId = cr.convo && cr.convo.id;
|
|
1099
|
+
if (!convoId) return { __bskyError: 'Could not open a conversation for those members.' };
|
|
1100
|
+
}
|
|
1101
|
+
var sm = await __bskyXrpc('chat.bsky.convo.sendMessage', { verb:'POST', proxy: ${proxy}, body:{ convoId: convoId, message: { text: ${jsLit(args.text)} } } });
|
|
1102
|
+
if (sm.__bskyError) return sm;
|
|
1103
|
+
return { ok:true, convoId: convoId, messageId: sm.id, sentAt: sm.sentAt };`;
|
|
1104
|
+
const r = await runBsky(args, body);
|
|
1105
|
+
if ('error' in r)
|
|
1106
|
+
return text(r.error);
|
|
1107
|
+
return text(`DM sent: ${JSON.stringify(r.data)}`);
|
|
1108
|
+
}
|
|
1109
|
+
// mark_read
|
|
1110
|
+
if (!args.convoId)
|
|
1111
|
+
return text('action=mark_read requires convoId.');
|
|
1112
|
+
const body = `
|
|
1113
|
+
var r = await __bskyXrpc('chat.bsky.convo.updateRead', { verb:'POST', proxy: ${proxy}, body:{ convoId: ${jsLit(args.convoId)} } });
|
|
1114
|
+
if (r.__bskyError) return r;
|
|
1115
|
+
return { ok:true, convoId: ${jsLit(args.convoId)} };`;
|
|
1116
|
+
const r = await runBsky(args, body);
|
|
1117
|
+
if ('error' in r)
|
|
1118
|
+
return text(r.error);
|
|
1119
|
+
return text(`DM convo marked read: ${JSON.stringify(r.data)}`);
|
|
1120
|
+
}
|
|
1121
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
1122
|
+
// Registration
|
|
1123
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
1124
|
+
/** Register BlueSky (AT Protocol) tools (15 tools). */
|
|
1125
|
+
export function registerBlueskyTools(server) {
|
|
1126
|
+
return [
|
|
1127
|
+
server.tool('bluesky_session', blueskySessionDescription, blueskySessionSchema, handleBlueskySession),
|
|
1128
|
+
server.tool('bluesky_timeline', blueskyTimelineDescription, blueskyTimelineSchema, handleBlueskyTimeline),
|
|
1129
|
+
server.tool('bluesky_author_feed', blueskyAuthorFeedDescription, blueskyAuthorFeedSchema, handleBlueskyAuthorFeed),
|
|
1130
|
+
server.tool('bluesky_thread', blueskyThreadDescription, blueskyThreadSchema, handleBlueskyThread),
|
|
1131
|
+
server.tool('bluesky_profile', blueskyProfileDescription, blueskyProfileSchema, handleBlueskyProfile),
|
|
1132
|
+
server.tool('bluesky_search_posts', blueskySearchPostsDescription, blueskySearchPostsSchema, handleBlueskySearchPosts),
|
|
1133
|
+
server.tool('bluesky_search_actors', blueskySearchActorsDescription, blueskySearchActorsSchema, handleBlueskySearchActors),
|
|
1134
|
+
server.tool('bluesky_notifications', blueskyNotificationsDescription, blueskyNotificationsSchema, handleBlueskyNotifications),
|
|
1135
|
+
server.tool('bluesky_graph', blueskyGraphDescription, blueskyGraphSchema, handleBlueskyGraph),
|
|
1136
|
+
server.tool('bluesky_likes', blueskyLikesDescription, blueskyLikesSchema, handleBlueskyLikes),
|
|
1137
|
+
server.tool('bluesky_feed', blueskyFeedDescription, blueskyFeedSchema, handleBlueskyFeed),
|
|
1138
|
+
server.tool('bluesky_post', blueskyPostDescription, blueskyPostSchema, handleBlueskyPost),
|
|
1139
|
+
server.tool('bluesky_action', blueskyActionDescription, blueskyActionSchema, handleBlueskyAction),
|
|
1140
|
+
server.tool('bluesky_resolve', blueskyResolveDescription, blueskyResolveSchema, handleBlueskyResolve),
|
|
1141
|
+
server.tool('bluesky_dm', blueskyDmDescription, blueskyDmSchema, handleBlueskyDm),
|
|
1142
|
+
];
|
|
1143
|
+
}
|
|
1144
|
+
//# sourceMappingURL=bluesky.js.map
|