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,1346 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// UI-JUDGMENTS — Settings → Judgments (TypeSafe / Jev)
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// The settings home for every Jev judgment SynaBun makes: the API key and
|
|
6
|
+
// where it comes from, the operational kill switch, one row per judgment
|
|
7
|
+
// surface, cost and cache, the corpus backfill, the bench that gates
|
|
8
|
+
// "apply judged importance", the judgment log, misfiled memories and trash
|
|
9
|
+
// triage. Runtime knobs live server-side in kv_config (PUT /api/typesafe/config)
|
|
10
|
+
// so every process obeys them without a restart; only UI preferences (the
|
|
11
|
+
// log filters, telemetry window) go to storage.
|
|
12
|
+
//
|
|
13
|
+
// Contract with ui-settings.js: buildJudgmentsTab() returns a static shell
|
|
14
|
+
// (never blocks the panel opening); wireJudgmentsTab(overlay, deps) loads
|
|
15
|
+
// live data and binds handlers. The delegated collapsible and eye-toggle
|
|
16
|
+
// handlers in ui-settings.js bind to this markup once, so nothing below ever
|
|
17
|
+
// replaces an .iface-section wrapper or a static input — only inner
|
|
18
|
+
// containers are re-rendered.
|
|
19
|
+
|
|
20
|
+
import { escapeHtml, debounce } from './utils.js';
|
|
21
|
+
import { storage } from './storage.js';
|
|
22
|
+
import * as kit from './settings/settings-kit.js';
|
|
23
|
+
|
|
24
|
+
// Mirrors ui-settings.js (module-local there; duplicated to avoid an import cycle).
|
|
25
|
+
const CHEVRON_ICON = '<svg class="cc-section-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>';
|
|
26
|
+
const EYE_CLOSED = '<svg viewBox="0 0 24 24"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><line x1="1" y1="1" x2="23" y2="23"/></svg>';
|
|
27
|
+
|
|
28
|
+
const LOG_FILTER_KEY = 'synabun-judgments-log-filter';
|
|
29
|
+
const HOOK_BUDGET_MS = 1400; // judgeText() in the hooks aborts at 1500 ms
|
|
30
|
+
const TRIAGE_PAGE = 50; // rows per page; the whole ranking arrives in one answer
|
|
31
|
+
const TRIAGE_LIMIT = '2000'; // the service ceiling: every candidate found is judged and returned
|
|
32
|
+
// ── Coding sessions, log counters, limits (servers that attribute log rows to sessions) ──
|
|
33
|
+
const WINDOW_KEY = 'synabun-judgments-window'; // telemetry window: h24 | d7 | process
|
|
34
|
+
const SESSIONS_DAYS = 7;
|
|
35
|
+
const TIMELINE_LIMIT = 500;
|
|
36
|
+
const LEGACY_HOOK_SURFACES = ['prompt-urgency', 'agent-message', 'turn-worth', 'loop-goal', 'brief-rank']; // budget warning for servers that predate budgetMs
|
|
37
|
+
// The extra knobs some surfaces have. Their caption and help are settings.redesign.judgments.limit.<key>.{label,help}.
|
|
38
|
+
const LIMIT_FIELDS = [
|
|
39
|
+
{ key: 'minScore', min: 0, max: 4, step: 0.1, width: 58 },
|
|
40
|
+
{ key: 'maxItems', min: 1, max: 50, step: 1, width: 58 },
|
|
41
|
+
{ key: 'debounceMs', min: 0, max: 600000, step: 1000, width: 84 },
|
|
42
|
+
{ key: 'bashOnlyMinProbability', min: 0, max: 1, step: 0.05, width: 58 },
|
|
43
|
+
];
|
|
44
|
+
const RELEVANCE_NAMES = ['irrelevant', 'tangential', 'background', 'direct', 'decisive']; // the rerank / brief-rank rubric, 0–4: settings.redesign.judgments.relevance.<name>
|
|
45
|
+
const CHIP = 'display:inline-block;padding:0 6px;border:1px solid var(--s-medium);border-radius:9px;font-size:10.5px;font-family:monospace;color:var(--t-muted);font-weight:400';
|
|
46
|
+
const PRE = 'margin:0;white-space:pre-wrap;font-size:11px;max-height:160px;overflow:auto';
|
|
47
|
+
const LINK = 'color:var(--accent);text-decoration:underline dotted;text-underline-offset:2px;cursor:pointer';
|
|
48
|
+
/** A server new enough to attribute log rows to sessions and count from the log. Older ones get the per-process view. */
|
|
49
|
+
const serverV2 = (cfg) => Boolean(cfg && (Array.isArray(cfg.origins) || (cfg.logStats && typeof cfg.logStats === 'object')));
|
|
50
|
+
const fin = (v) => v != null && v !== '' && Number.isFinite(Number(v));
|
|
51
|
+
const shortId = (id) => String(id ?? '').slice(0, 8);
|
|
52
|
+
const memLink = (id) => (id == null || id === '') ? '' : `<a href="#" class="jv-entity" data-entity="${attr(id)}" title="${attr(id)}${kit.te('settings.redesign.judgments.showEveryJudgmentAboutThisMemory')}" style="${LINK};font-family:monospace">${escapeHtml(shortId(id))}</a>`;
|
|
53
|
+
const when = (iso) => fin(Date.parse(iso)) ? new Date(iso).toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }) : '—';
|
|
54
|
+
const day = (iso) => fin(Date.parse(iso)) ? new Date(iso).toLocaleDateString([], { year: 'numeric', month: 'short', day: 'numeric' }) : '—';
|
|
55
|
+
/** A Noul answer as logged ({type:'noul', noul}), or a bare number. */
|
|
56
|
+
const prob = (a) => { const v = a && typeof a === 'object' ? (a.noul ?? a.probability) : a; return fin(v) ? Number(v) : null; };
|
|
57
|
+
|
|
58
|
+
const attr = (s) => String(s ?? '').replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<');
|
|
59
|
+
const num = (n) => Number(n || 0).toLocaleString('en-US');
|
|
60
|
+
const money = (n) => (n == null || !Number.isFinite(Number(n))) ? '—' : `$${Number(n) < 0.01 && Number(n) > 0 ? Number(n).toFixed(4) : Number(n).toFixed(2)}`;
|
|
61
|
+
const pct = (n) => (n == null || !Number.isFinite(Number(n))) ? '—' : `${Math.round(Number(n) * 100)}%`;
|
|
62
|
+
const clock = (iso) => iso ? new Date(iso).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' }) : '—';
|
|
63
|
+
const stamp = (iso) => iso ? new Date(iso).toLocaleString() : kit.tx('settings.redesign.judgments.never');
|
|
64
|
+
const relevanceName = (score) => { const name = RELEVANCE_NAMES[Math.round(Number(score))]; return name ? kit.tx(`settings.redesign.judgments.relevance.${name}`) : ''; };
|
|
65
|
+
const duration = (ms) => { const s = Math.round(Number(ms || 0) / 1000); if (s < 90) return `${s}s`; const m = Math.round(s / 60); if (m < 120) return `${m} min`; return `${(m / 60).toFixed(1)} h`; };
|
|
66
|
+
const btnStyle = 'margin:0;width:auto;flex:0 0 auto;padding:4px 10px';
|
|
67
|
+
const inputStyle = 'flex:1;font-family:monospace;font-size:12px';
|
|
68
|
+
const smallInput = 'font-family:monospace;font-size:12px;width:72px;padding:3px 6px;background:var(--s-darker);color:var(--t-primary);border:1px solid var(--s-medium);border-radius:6px';
|
|
69
|
+
const boxStyle = 'display:none;margin-top:10px;padding:10px 12px;border-radius:8px;font-size:12px;line-height:1.5';
|
|
70
|
+
const okBg = 'rgba(76,175,80,0.12)', errBg = 'rgba(244,67,54,0.12)', warnBg = 'rgba(255,193,7,0.12)';
|
|
71
|
+
|
|
72
|
+
// ── Markup helpers ──
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
// Section id → its slug under settings.redesign.section.ai_decisions (title and one-line purpose).
|
|
76
|
+
const SECTION_SLUG = {
|
|
77
|
+
'jv-sec-connection': 'decision_service', 'jv-sec-master': 'master_switch', 'jv-sec-sessions': 'coding_sessions',
|
|
78
|
+
'jv-sec-surfaces': 'surfaces', 'jv-sec-telemetry': 'cost_telemetry', 'jv-sec-cache': 'answer_cache',
|
|
79
|
+
'jv-sec-backfill': 'backfill', 'jv-sec-bench': 'bench', 'jv-sec-browser': 'browser_assistance',
|
|
80
|
+
'jv-sec-desktop': 'desktop_assistance', 'jv-sec-log': 'judgment_log', 'jv-sec-misfiled': 'misfiled',
|
|
81
|
+
'jv-sec-supersessions': 'superseded_by_jev', 'jv-sec-triage': 'trash_triage',
|
|
82
|
+
};
|
|
83
|
+
// Everyday sections; the rest carry the "Advanced" tag.
|
|
84
|
+
const EVERYDAY = new Set(['jv-sec-connection', 'jv-sec-master']);
|
|
85
|
+
|
|
86
|
+
/** One section card (settings-kit.js): an accordion; the shell opens the ones the user left open. */
|
|
87
|
+
function section({ id, title, badgeId, body }) {
|
|
88
|
+
const slug = SECTION_SLUG[id];
|
|
89
|
+
return kit.card({
|
|
90
|
+
id,
|
|
91
|
+
section: slug ? `ai_decisions.${slug}` : id,
|
|
92
|
+
title: slug ? undefined : kit.esc(title),
|
|
93
|
+
purpose: slug ? undefined : '',
|
|
94
|
+
status: badgeId ? `<span id="${badgeId}"></span>` : '',
|
|
95
|
+
body,
|
|
96
|
+
advanced: !EVERYDAY.has(id),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const toggle = (id, cls = '') => `<label class="recall-toggle"><input type="checkbox" id="${id}" class="${cls}"><span class="recall-toggle-track"></span></label>`;
|
|
100
|
+
const button = (id, label, extra = '') => `<button class="conn-add-btn" id="${id}" style="${btnStyle}" ${extra}>${label}</button>`;
|
|
101
|
+
const tile = (id, label) => `<div class="db-stat"><span class="db-stat-label">${label}</span><span class="db-stat-value" id="${id}">—</span></div>`;
|
|
102
|
+
|
|
103
|
+
// ── Shell ──
|
|
104
|
+
|
|
105
|
+
export function buildJudgmentsTab() {
|
|
106
|
+
return `
|
|
107
|
+
<div class="stg-pane" data-stg-pane="judgments">
|
|
108
|
+
<div class="settings-status">
|
|
109
|
+
<span class="settings-status-dot disconnected" id="jv-status-dot"></span>
|
|
110
|
+
<span id="jv-status-line">${kit.te('settings.redesign.judgments.checkingTypesafe')}</span>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
${section({ id: 'jv-sec-connection', title: kit.tx('settings.redesign.judgments.connection'), badgeId: 'jv-key-source-badge', body: `
|
|
114
|
+
<div class="settings-hint" style="margin-bottom:10px">${kit.te('settings.redesign.judgments.jevTypesafeSystemOneReturnsTyped')} <code>~/.synabun/.env</code> ${kit.te('settings.redesign.judgments.andNeverLeavesTheServerOnly')}</div>
|
|
115
|
+
<div class="settings-field">
|
|
116
|
+
<label for="jv-api-key">${kit.te('settings.redesign.judgments.apiKey')}</label>
|
|
117
|
+
<div class="settings-key-row" style="display:flex;gap:6px">
|
|
118
|
+
<input type="password" id="jv-api-key" value="" placeholder="${kit.te('settings.redesign.judgments.pasteATypesafeApiKey')}" autocomplete="off" spellcheck="false" style="${inputStyle}">
|
|
119
|
+
<button class="conn-add-btn settings-toggle-vis" id="jv-key-eye" data-target="jv-api-key" style="margin:0;width:auto;flex:0 0 auto;padding:4px 8px" data-tooltip="${kit.te('settings.redesign.judgments.name.keyEye')}" aria-label="${kit.te('settings.redesign.judgments.name.keyEye')}">${EYE_CLOSED}</button>
|
|
120
|
+
${button('jv-key-save', kit.tx('settings.redesign.judgments.save'))}${button('jv-key-test', kit.tx('settings.redesign.judgments.test'))}${button('jv-key-clear', kit.tx('settings.redesign.judgments.clear'))}
|
|
121
|
+
</div>
|
|
122
|
+
<div class="settings-hint" id="jv-key-hint">${kit.te('settings.redesign.judgments.noKeyStored')}</div>
|
|
123
|
+
</div>
|
|
124
|
+
<div id="jv-key-warning" style="${boxStyle};background:${warnBg}"></div>
|
|
125
|
+
<div class="settings-field">
|
|
126
|
+
<label for="jv-base-url">${kit.te('settings.redesign.judgments.baseUrl')}</label>
|
|
127
|
+
<div class="settings-key-row" style="display:flex;gap:6px">
|
|
128
|
+
<input type="text" id="jv-base-url" value="" placeholder="https://api.typesafe.ai" autocomplete="off" spellcheck="false" style="${inputStyle}">
|
|
129
|
+
${button('jv-base-url-save', kit.tx('settings.redesign.judgments.save'))}
|
|
130
|
+
</div>
|
|
131
|
+
<div class="settings-hint" id="jv-base-url-hint">${kit.te('settings.redesign.judgments.blankDefaultAppliesImmediatelyA')} <code>TYPESAFE_BASE_URL</code> ${kit.te('settings.redesign.judgments.exportInTheServerSShell')}</div>
|
|
132
|
+
</div>
|
|
133
|
+
<div class="settings-field">
|
|
134
|
+
<label for="jv-model">${kit.te('settings.redesign.judgments.model')}</label>
|
|
135
|
+
<div class="settings-key-row" style="display:flex;gap:6px;align-items:center">
|
|
136
|
+
<select id="jv-model" style="${smallInput};width:auto;min-width:160px"></select>
|
|
137
|
+
<span class="settings-hint" style="margin:0">${kit.te('settings.redesign.judgments.aliasesMoveWhenTypesafeShipsA')}</span>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
<div id="jv-test-result" style="${boxStyle}"></div>
|
|
141
|
+
` })}
|
|
142
|
+
|
|
143
|
+
${kit.card({ id: 'jv-sec-master', section: 'ai_decisions.master_switch', body: `
|
|
144
|
+
<div class="recall-control-header" style="margin-top:6px">
|
|
145
|
+
<span class="recall-control-label">${kit.te('settings.redesign.judgments.jevJudgments')} <span id="jv-master-badge" style="font-size:11px;color:var(--t-muted);margin-left:8px"></span></span>
|
|
146
|
+
${toggle('jv-master-toggle')}
|
|
147
|
+
</div>
|
|
148
|
+
<div class="settings-hint" id="jv-master-hint">${kit.te('settings.redesign.judgments.operationalKillSwitchWhenOffEvery')} <code>/history|previous|old|antes|anterior/i</code>${kit.te('settings.redesign.judgments.rerankKeepsFusionOrderOnlyThe')} <code>SYNABUN_TYPESAFE=off</code> ${kit.te('settings.redesign.judgments.inTheServerSEnvironmentForces')}</div>` })}
|
|
149
|
+
|
|
150
|
+
${section({ id: 'jv-sec-sessions', title: kit.tx('settings.redesign.judgments.codingSessions'), badgeId: 'jv-sessions-badge', body: `
|
|
151
|
+
<div class="settings-hint" style="margin-bottom:8px">${kit.th('settings.redesign.judgments.whatJevDecidedInsideEachClaude', { SESSIONS_DAYS: SESSIONS_DAYS })} <strong style="color:#ffc107">${kit.te('settings.redesign.judgments.amber')}</strong> ${kit.te('settings.redesign.judgments.marksAnAnswerThatCrossedIts')}</div>
|
|
152
|
+
<div class="settings-key-row" style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">
|
|
153
|
+
${button('jv-sessions-refresh', kit.tx('settings.redesign.judgments.refresh'))}
|
|
154
|
+
<span class="settings-hint" id="jv-sessions-status" style="margin:0"></span>
|
|
155
|
+
</div>
|
|
156
|
+
<div id="jv-sessions-list" style="display:flex;flex-direction:column;gap:6px;margin-top:8px"></div>
|
|
157
|
+
` })}
|
|
158
|
+
|
|
159
|
+
${section({ id: 'jv-sec-surfaces', title: kit.tx('settings.redesign.judgments.surfaces'), badgeId: 'jv-surfaces-badge', body: `
|
|
160
|
+
<div class="settings-hint" id="jv-surfaces-hint" style="margin-bottom:8px">${kit.th('settings.redesign.judgments.oneRowPerJudgmentTurningA', { HOOK_BUDGET_MS: HOOK_BUDGET_MS })}</div>
|
|
161
|
+
<div class="stg-mcp-matrix-scroll">
|
|
162
|
+
<table class="cc-cheatsheet-table" id="jv-surfaces-table" style="width:100%">
|
|
163
|
+
<thead><tr><th>${kit.te('settings.redesign.judgments.on')}</th><th>${kit.te('settings.redesign.judgments.surface')}</th><th>${kit.te('settings.redesign.judgments.timeoutMs')}</th><th title="${kit.te('settings.redesign.judgments.minimumChoiceScoreConfidence')}">${kit.te('settings.redesign.judgments.threshold')}</th><th title="${kit.te('settings.redesign.judgments.minimumNoulProbabilityOnSurfacesThat')}">${kit.te('settings.redesign.judgments.probability')}</th><th id="jv-sf-h-calls">${kit.te('settings.redesign.judgments.calls')}</th><th id="jv-sf-h-avg">${kit.te('settings.redesign.judgments.avgMs')}</th><th id="jv-sf-h-fail">${kit.te('settings.redesign.judgments.fail')}</th><th id="jv-sf-h-skipped">${kit.te('settings.redesign.judgments.skipped')}</th></tr></thead>
|
|
164
|
+
<tbody id="jv-surfaces-body"></tbody>
|
|
165
|
+
</table>
|
|
166
|
+
</div>
|
|
167
|
+
<div class="settings-hint" id="jv-surfaces-status" style="margin-top:6px"></div>
|
|
168
|
+
` })}
|
|
169
|
+
|
|
170
|
+
${section({ id: 'jv-sec-telemetry', title: 'Cost & telemetry', badgeId: 'jv-telemetry-badge', body: `
|
|
171
|
+
<div class="settings-key-row" id="jv-st-window-row" style="display:none;gap:6px;align-items:center;flex-wrap:wrap;margin-bottom:8px">
|
|
172
|
+
<span class="settings-hint" style="margin:0">${kit.te('settings.redesign.judgments.figuresFor')}</span>
|
|
173
|
+
<select id="jv-st-window" style="${smallInput};width:auto"><option value="h24">${kit.te('settings.redesign.judgments.theLast24HLog')}</option><option value="d7">${kit.te('settings.redesign.judgments.theLast7DLog')}</option><option value="process">${kit.te('settings.redesign.judgments.thisProcess')}</option></select>
|
|
174
|
+
<span class="settings-hint" id="jv-st-window-hint" style="margin:0"></span>
|
|
175
|
+
</div>
|
|
176
|
+
<div class="db-stats-row" style="display:grid;grid-template-columns:repeat(4,1fr);gap:8px">
|
|
177
|
+
${tile('jv-st-calls', kit.tx('settings.redesign.judgments.calls'))}${tile('jv-st-hits', kit.tx('settings.redesign.judgments.answered'))}${tile('jv-st-failures', kit.tx('settings.redesign.judgments.failed2'))}${tile('jv-st-cached', kit.tx('settings.redesign.judgments.fromCache'))}
|
|
178
|
+
${tile('jv-st-in', kit.tx('settings.redesign.judgments.tokensIn'))}${tile('jv-st-out', kit.tx('settings.redesign.judgments.tokensOut'))}${tile('jv-st-avg', kit.tx('settings.redesign.judgments.avgMs'))}${tile('jv-st-cost', kit.tx('settings.redesign.judgments.estSpend'))}
|
|
179
|
+
</div>
|
|
180
|
+
<div class="settings-hint" id="jv-st-lasterror" style="margin-top:8px"></div>
|
|
181
|
+
<div class="settings-key-row" style="display:flex;gap:6px;align-items:center;margin-top:10px;flex-wrap:wrap">
|
|
182
|
+
<span class="settings-hint" style="margin:0">${kit.te('settings.redesign.judgments.pricePerMillionIn')}</span>
|
|
183
|
+
<input type="number" id="jv-rate-in" min="0" step="0.001" style="${smallInput}">
|
|
184
|
+
<span class="settings-hint" style="margin:0">${kit.te('settings.redesign.judgments.out')}</span>
|
|
185
|
+
<input type="number" id="jv-rate-out" min="0" step="0.001" style="${smallInput}">
|
|
186
|
+
${button('jv-rates-save', kit.tx('settings.redesign.judgments.saveRates'))}
|
|
187
|
+
${button('jv-metrics-reset', kit.tx('settings.redesign.judgments.resetCounters'))}
|
|
188
|
+
</div>
|
|
189
|
+
<div class="settings-hint" style="margin-top:6px">${kit.te('settings.redesign.judgments.typesafeListsJev1130')}</div>
|
|
190
|
+
` })}
|
|
191
|
+
|
|
192
|
+
${kit.card({ id: 'jv-sec-cache', section: 'ai_decisions.answer_cache', body: `
|
|
193
|
+
<div class="settings-key-row" style="display:flex;gap:12px;align-items:center;margin-top:6px">
|
|
194
|
+
<span class="settings-hint" style="margin:0">${kit.te('settings.redesign.judgments.entries')} <strong id="jv-cache-size">—</strong> ${kit.te('settings.redesign.judgments.hitRatio')} <strong id="jv-cache-ratio">—</strong></span>
|
|
195
|
+
${button('jv-cache-clear', kit.tx('settings.redesign.judgments.clearCache'))}
|
|
196
|
+
</div>
|
|
197
|
+
<div class="settings-hint">${kit.te('settings.redesign.judgments.identicalStateQuestionsModelReuseThe')}</div>` })}
|
|
198
|
+
|
|
199
|
+
${section({ id: 'jv-sec-backfill', title: kit.tx('settings.redesign.judgments.backfill2'), badgeId: 'jv-backfill-badge', body: `
|
|
200
|
+
<div class="settings-hint" id="jv-coverage" style="margin-bottom:6px">${kit.te('settings.redesign.judgments.coverage')}</div>
|
|
201
|
+
<div class="db-reindex-bar-track"><div id="jv-coverage-bar" class="db-reindex-bar" style="width:0%"></div></div>
|
|
202
|
+
<div class="settings-hint" style="margin:10px 0 8px">${kit.te('settings.redesign.judgments.memoriesIndexedBeforeJudgmentsExistedNev')}</div>
|
|
203
|
+
<div class="settings-key-row" style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">
|
|
204
|
+
<input type="text" id="jv-bf-project" placeholder="${kit.te('settings.redesign.judgments.allProjects')}" autocomplete="off" spellcheck="false" style="${smallInput};width:150px">
|
|
205
|
+
<input type="number" id="jv-bf-limit" placeholder="${kit.te('settings.redesign.judgments.allRows')}" min="1" style="${smallInput};width:110px">
|
|
206
|
+
${button('jv-bf-estimate', kit.tx('settings.redesign.judgments.estimate'))}${button('jv-bf-start', kit.tx('settings.redesign.judgments.start'), 'disabled')}${button('jv-bf-pause', kit.tx('settings.redesign.judgments.pause'), 'disabled')}${button('jv-bf-resume', kit.tx('settings.redesign.judgments.resume'), 'disabled')}${button('jv-bf-cancel', kit.tx('settings.redesign.judgments.cancel'), 'disabled')}
|
|
207
|
+
</div>
|
|
208
|
+
<div id="jv-bf-estimate-box" style="${boxStyle};background:var(--s-darker)"></div>
|
|
209
|
+
<div style="display:flex;align-items:center;gap:8px;margin-top:12px">
|
|
210
|
+
<div class="wiz-status-dot" id="jv-bf-dot"></div>
|
|
211
|
+
<span id="jv-bf-text" style="font-size:12px">${kit.te('settings.redesign.judgments.idle')}</span>
|
|
212
|
+
</div>
|
|
213
|
+
<div class="db-reindex-bar-track" style="margin-top:6px"><div id="jv-bf-bar" class="db-reindex-bar" style="width:0%"></div></div>
|
|
214
|
+
<div class="settings-hint" id="jv-bf-summary" style="margin-top:6px"></div>
|
|
215
|
+
<div class="settings-hint" id="jv-bf-error" style="color:#f66"></div>
|
|
216
|
+
<div id="jv-bf-report" style="${boxStyle};background:var(--s-darker)"></div>
|
|
217
|
+
` })}
|
|
218
|
+
|
|
219
|
+
${section({ id: 'jv-sec-bench', title: kit.tx('settings.redesign.judgments.bench2'), badgeId: 'jv-bench-badge', body: `
|
|
220
|
+
<div class="settings-hint" style="margin-bottom:8px">${kit.te('settings.redesign.judgments.replaysStoredMemoriesThroughBothThe')} <code>benchmarks/typesafe-<surface>-<date>.json</code>${kit.te('settings.redesign.judgments.sameCodeAs')} <code>node mcp-server/scripts/bench-typesafe.mjs</code>.</div>
|
|
221
|
+
<div class="settings-key-row" style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">
|
|
222
|
+
<select id="jv-bench-surface" style="${smallInput};width:auto"><option value="importance">${kit.te('settings.redesign.judgments.importance')}</option><option value="kind">${kit.te('settings.redesign.judgments.kind')}</option><option value="relation">${kit.te('settings.redesign.judgments.relation')}</option><option value="historical">${kit.te('settings.redesign.judgments.historical')}</option><option value="browser">${kit.te('settings.redesign.judgments.browserFixtures')}</option><option value="desktop">${kit.te('settings.redesign.judgments.desktopFixtures')}</option></select>
|
|
223
|
+
<input type="number" id="jv-bench-limit" value="50" min="1" max="200" style="${smallInput};width:80px">
|
|
224
|
+
<input type="text" id="jv-bench-project" placeholder="${kit.te('settings.redesign.judgments.allProjects')}" autocomplete="off" spellcheck="false" style="${smallInput};width:150px">
|
|
225
|
+
${button('jv-bench-run', kit.tx('settings.redesign.judgments.runBench'))}
|
|
226
|
+
<span id="jv-bench-spinner" style="display:none"><div class="wiz-status-dot spin" style="display:inline-block"></div></span>
|
|
227
|
+
</div>
|
|
228
|
+
<div class="settings-hint" id="jv-bench-last" style="margin-top:6px">${kit.te('settings.redesign.judgments.lastBenchNever')}</div>
|
|
229
|
+
<div id="jv-bench-result" style="${boxStyle};background:var(--s-darker)">
|
|
230
|
+
<div id="jv-bench-summary"></div>
|
|
231
|
+
<div class="stg-mcp-matrix-scroll" style="margin-top:8px"><table class="cc-cheatsheet-table" id="jv-bench-table" style="width:100%"></table></div>
|
|
232
|
+
</div>
|
|
233
|
+
<div class="recall-control-header" style="margin-top:14px">
|
|
234
|
+
<span class="recall-control-label">${kit.te('settings.redesign.judgments.applyJudgedImportanceToMemories')}</span>
|
|
235
|
+
${toggle('jv-apply-importance')}
|
|
236
|
+
</div>
|
|
237
|
+
<div class="settings-hint" id="jv-apply-hint">${kit.te('settings.redesign.judgments.offByDefaultMaintenanceRecordsJev')} <code>memories.importance</code> ${kit.te('settings.redesign.judgments.untilThisIsOnLockedUntil')}</div>
|
|
238
|
+
` })}
|
|
239
|
+
|
|
240
|
+
${section({ id: 'jv-sec-browser', title: kit.tx('settings.redesign.judgments.browserAssistance'), badgeId: 'jv-browser-badge', body: `
|
|
241
|
+
<div class="settings-hint" style="margin-bottom:8px">${kit.te('settings.redesign.judgments.jevAdvisesTheBrowserToolsIt')} <code>browser_navigate</code> ${kit.te('settings.redesign.judgments.itSaysWhetherThePageIs')} <code>intent</code> ${kit.te('settings.redesign.judgments.orAFailedSelectorS')} <code>textHint</code> ${kit.te('settings.redesign.judgments.itRanksTheVisibleControlsAnd')}</div>
|
|
242
|
+
<div id="jv-ba-mode" style="${boxStyle}"></div>
|
|
243
|
+
<div class="settings-hint" id="jv-ba-bench" style="margin-top:6px"></div>
|
|
244
|
+
<div class="settings-hint" id="jv-ba-reasons" style="margin-top:4px;color:#ffc107"></div>
|
|
245
|
+
<div id="jv-ba-counters" style="display:flex;flex-wrap:wrap;gap:6px;margin-top:8px"></div>
|
|
246
|
+
<div class="settings-hint" style="margin-top:4px">${kit.te('settings.redesign.judgments.countersBelongToThisServerProcess')}</div>
|
|
247
|
+
<div class="recall-control-header" style="margin-top:14px">
|
|
248
|
+
<span class="recall-control-label">${kit.te('settings.redesign.judgments.enableSafeAutoHeal')}</span>
|
|
249
|
+
${toggle('jv-ba-autoheal')}
|
|
250
|
+
</div>
|
|
251
|
+
<div class="settings-hint" id="jv-ba-hint">${kit.te('settings.redesign.judgments.offByDefaultWhenOnA')} <code>browser_click</code> ${kit.te('settings.redesign.judgments.whoseSelectorMatchedNothingMayBe')} <strong>${kit.te('settings.redesign.judgments.once')}</strong>${kit.te('settings.redesign.judgments.onAPlainSameOriginNavigation')} <em>${kit.te('settings.redesign.judgments.browser')}</em> ${kit.te('settings.redesign.judgments.benchHasPassedForExactlyThis')} <code>jev-latest</code>${kit.te('settings.redesign.judgments.these')} <code>browser-target</code> ${kit.te('settings.redesign.judgments.thresholdsThisWordingTheseRiskRules')}</div>
|
|
252
|
+
<details style="margin-top:10px">
|
|
253
|
+
<summary style="cursor:pointer;font-size:12px">${kit.te('settings.redesign.judgments.whatMayBeSentToTypesafe')}</summary>
|
|
254
|
+
<div class="settings-hint" style="margin-top:6px"><strong>${kit.te('settings.redesign.judgments.mayBeSent')}</strong>${kit.te('settings.redesign.judgments.fromAnyPageYouBrowseHere')}</div>
|
|
255
|
+
<div class="settings-hint" style="margin-top:6px"><strong>${kit.te('settings.redesign.judgments.neverSent')}</strong>${kit.te('settings.redesign.judgments.anythingTypedIntoAFieldA')} <code>[input]</code>${kit.te('settings.redesign.judgments.hiddenDomQueryStringsAndFragments')}</div>
|
|
256
|
+
</details>
|
|
257
|
+
<div class="settings-hint" style="margin-top:8px;color:#ffc107">${kit.te('settings.redesign.judgments.alwaysAdvisoryWhateverThisSwitchSays')} <code>browser_batch</code>${kit.te('settings.redesign.judgments.andAnyPageWithAControl')}</div>
|
|
258
|
+
` })}
|
|
259
|
+
|
|
260
|
+
${section({ id: 'jv-sec-desktop', title: kit.tx('settings.redesign.judgments.desktopAssistance'), badgeId: 'jv-desktop-badge', body: `
|
|
261
|
+
<div class="settings-hint" style="margin-bottom:8px">${kit.te('settings.redesign.judgments.jevAdvisesComputerUseItNever')} <code>computer_ax</code> <code>intent</code>${kit.te('settings.redesign.judgments.itRanksTheControlsOfThe')} <code>desktop-target</code> ${kit.te('settings.redesign.judgments.surfaceAboveCanBeSwitchedOff')}</div>
|
|
262
|
+
<div id="jv-da-mode" style="${boxStyle}"></div>
|
|
263
|
+
<div class="settings-hint" id="jv-da-bench" style="margin-top:6px"></div>
|
|
264
|
+
<div class="settings-hint" id="jv-da-reasons" style="margin-top:4px;color:#ffc107"></div>
|
|
265
|
+
<div id="jv-da-counters" style="display:flex;flex-wrap:wrap;gap:6px;margin-top:8px"></div>
|
|
266
|
+
<div class="settings-hint" style="margin-top:4px">${kit.te('settings.redesign.judgments.countersBelongToThisServerProcess')}</div>
|
|
267
|
+
<div class="recall-control-header" style="margin-top:14px">
|
|
268
|
+
<span class="recall-control-label">${kit.te('settings.redesign.judgments.enablePressByIntent')}</span>
|
|
269
|
+
${toggle('jv-da-press')}
|
|
270
|
+
</div>
|
|
271
|
+
<div class="settings-hint" id="jv-da-hint">${kit.te('settings.redesign.judgments.offByDefaultWhenOn')} <code>computer_ax</code> ${kit.te('settings.redesign.judgments.action')} <code>press</code> ${kit.te('settings.redesign.judgments.withAn')} <code>intent</code> ${kit.te('settings.redesign.judgments.andNo')} <code>ref</code> ${kit.te('settings.redesign.judgments.mayPress')} <strong>${kit.te('settings.redesign.judgments.once')}</strong>${kit.te('settings.redesign.judgments.aPlainEnabledButtonLinkTab')} <em>${kit.te('settings.redesign.judgments.desktop')}</em> ${kit.te('settings.redesign.judgments.benchHasPassedForExactlyThis')} <code>jev-latest</code>${kit.te('settings.redesign.judgments.these')} <code>desktop-target</code> ${kit.te('settings.redesign.judgments.thresholdsThisWordingTheSharedAnd')}</div>
|
|
272
|
+
<details style="margin-top:10px">
|
|
273
|
+
<summary style="cursor:pointer;font-size:12px">${kit.te('settings.redesign.judgments.whatMayBeSentToTypesafe')}</summary>
|
|
274
|
+
<div class="settings-hint" style="margin-top:6px"><strong>${kit.te('settings.redesign.judgments.mayBeSent')}</strong>${kit.te('settings.redesign.judgments.fromWhicheverAppIsInFront')}</div>
|
|
275
|
+
<div class="settings-hint" style="margin-top:6px"><strong>${kit.te('settings.redesign.judgments.neverSent')}</strong>${kit.te('settings.redesign.judgments.fieldValuesOrAnythingTypedWindow')}</div>
|
|
276
|
+
</details>
|
|
277
|
+
<div class="settings-hint" style="margin-top:8px;color:#ffc107">${kit.te('settings.redesign.judgments.alwaysAdvisoryWhateverThisSwitchSays2')}</div>
|
|
278
|
+
` })}
|
|
279
|
+
|
|
280
|
+
${section({ id: 'jv-sec-log', title: kit.tx('settings.redesign.judgments.judgmentLog'), badgeId: 'jv-log-badge', body: `
|
|
281
|
+
<div class="settings-key-row" style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">
|
|
282
|
+
<select id="jv-log-surface" style="${smallInput};width:auto"><option value="">${kit.te('settings.redesign.judgments.allSurfaces')}</option></select>
|
|
283
|
+
<select id="jv-log-origin" style="${smallInput};width:auto"><option value="">${kit.te('settings.redesign.judgments.allOrigins')}</option><option value="live">${kit.te('settings.redesign.judgments.live')}</option><option value="backfill">${kit.te('settings.redesign.judgments.backfill')}</option><option value="bench">${kit.te('settings.redesign.judgments.bench')}</option></select>
|
|
284
|
+
<input type="text" id="jv-log-session" placeholder="${kit.te('settings.redesign.judgments.sessionId')}" title="${kit.te('settings.redesign.judgments.rowsFromOneClaudeCodeSession')}" autocomplete="off" spellcheck="false" style="${smallInput};width:110px;display:none">
|
|
285
|
+
<input type="text" id="jv-log-entity" placeholder="${kit.te('settings.redesign.judgments.memoryId')}" title="${kit.te('settings.redesign.judgments.rowsAboutOneMemory')}" autocomplete="off" spellcheck="false" style="${smallInput};width:110px">
|
|
286
|
+
<input type="text" id="jv-log-project" placeholder="${kit.te('settings.redesign.judgments.project')}" title="${kit.te('settings.redesign.judgments.rowsFromOneProject')}" autocomplete="off" spellcheck="false" style="${smallInput};width:100px;display:none">
|
|
287
|
+
<select id="jv-log-limit" style="${smallInput};width:auto"><option>25</option><option selected>50</option><option>100</option><option>200</option></select>
|
|
288
|
+
${button('jv-log-refresh', kit.tx('settings.redesign.judgments.refresh'))}
|
|
289
|
+
<span class="settings-hint" id="jv-log-status" style="margin:0"></span>
|
|
290
|
+
</div>
|
|
291
|
+
<div class="settings-hint" style="margin:6px 0">${kit.te('settings.redesign.judgments.whenSomeoneAsksWhyDidIt')}</div>
|
|
292
|
+
<div id="jv-log-list" style="display:flex;flex-direction:column;gap:4px"></div>
|
|
293
|
+
` })}
|
|
294
|
+
|
|
295
|
+
${section({ id: 'jv-sec-misfiled', title: kit.tx('settings.redesign.judgments.misfiled'), badgeId: 'jv-misfiled-badge', body: `
|
|
296
|
+
<div class="settings-hint" style="margin-bottom:8px">${kit.te('settings.redesign.judgments.atEvery')} <code>remember</code>${kit.te('settings.redesign.judgments.jevJudgesWhichCategoryFitsThe')}</div>
|
|
297
|
+
<div id="jv-misfiled-list" style="display:flex;flex-direction:column;gap:6px"></div>
|
|
298
|
+
` })}
|
|
299
|
+
|
|
300
|
+
${section({ id: 'jv-sec-supersessions', title: kit.tx('settings.redesign.judgments.supersededByJev'), badgeId: 'jv-supersessions-badge', body: `
|
|
301
|
+
<div class="settings-hint" style="margin-bottom:8px">${kit.te('settings.redesign.judgments.whenJevJudgesANewMemory')} <code>supersedes</code> ${kit.te('settings.redesign.judgments.relationTheOlderMemoryLeavesCurrent')}</div>
|
|
302
|
+
<div class="settings-hint" id="jv-supersessions-status" style="margin:0 0 6px"></div>
|
|
303
|
+
<div id="jv-supersessions-list" style="display:flex;flex-direction:column;gap:6px"></div>
|
|
304
|
+
` })}
|
|
305
|
+
|
|
306
|
+
${section({ id: 'jv-sec-triage', title: kit.tx('settings.redesign.judgments.trashTriage'), badgeId: 'jv-triage-badge', body: `
|
|
307
|
+
<div class="settings-hint" style="margin-bottom:8px">${kit.te('settings.redesign.judgments.forgetCandidatesDuplicatesOldLowImportan')}</div>
|
|
308
|
+
<div class="settings-key-row" style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">
|
|
309
|
+
<input type="text" id="jv-triage-project" placeholder="${kit.te('settings.redesign.judgments.allProjects')}" autocomplete="off" spellcheck="false" style="${smallInput};width:150px">
|
|
310
|
+
${button('jv-triage-run', kit.tx('settings.redesign.judgments.findCandidates'))}
|
|
311
|
+
<span id="jv-triage-spinner" style="display:none"><div class="wiz-status-dot spin" style="display:inline-block"></div></span>
|
|
312
|
+
<span class="settings-hint" id="jv-triage-status" style="margin:0"></span>
|
|
313
|
+
</div>
|
|
314
|
+
<div class="settings-key-row" id="jv-triage-bulk" style="display:none;gap:8px;align-items:center;flex-wrap:wrap;margin-top:8px">
|
|
315
|
+
<label style="display:flex;align-items:center;gap:6px;font-size:12px;cursor:pointer"><input type="checkbox" id="jv-triage-all"> ${kit.te('settings.redesign.judgments.selectAllShown')}</label>
|
|
316
|
+
${button('jv-triage-trash-selected', kit.tx('settings.redesign.judgments.move0ToTrash'), 'disabled')}
|
|
317
|
+
</div>
|
|
318
|
+
<div id="jv-triage-list" style="display:flex;flex-direction:column;gap:6px;margin-top:8px"></div>
|
|
319
|
+
<div id="jv-triage-more-wrap" style="display:none;margin-top:8px">${button('jv-triage-more', kit.tx('settings.redesign.judgments.showMore'))}</div>
|
|
320
|
+
` })}
|
|
321
|
+
</div>`;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// ── Wiring ──
|
|
325
|
+
|
|
326
|
+
export function wireJudgmentsTab(overlay, { toast = () => {}, initial = null } = {}) {
|
|
327
|
+
const $ = (id) => overlay.querySelector('#' + id);
|
|
328
|
+
// Names for the controls whose only caption is a placeholder or a neighbouring word (screen readers, voice control).
|
|
329
|
+
const CONTROL_NAMES = {
|
|
330
|
+
'jv-st-window': 'window', 'jv-rate-in': 'rateIn', 'jv-rate-out': 'rateOut', 'jv-bf-project': 'bfProject', 'jv-bf-limit': 'bfLimit',
|
|
331
|
+
'jv-bench-surface': 'benchSurface', 'jv-bench-limit': 'benchLimit', 'jv-bench-project': 'benchProject', 'jv-log-surface': 'logSurface',
|
|
332
|
+
'jv-log-origin': 'logOrigin', 'jv-log-session': 'logSession', 'jv-log-entity': 'logEntity', 'jv-log-project': 'logProject',
|
|
333
|
+
'jv-log-limit': 'logLimit', 'jv-triage-project': 'triageProject',
|
|
334
|
+
'jv-master-toggle': 'masterToggle', 'jv-apply-importance': 'applyImportance', 'jv-ba-autoheal': 'baAutoheal', 'jv-da-press': 'daPress',
|
|
335
|
+
};
|
|
336
|
+
for (const [id, name] of Object.entries(CONTROL_NAMES)) $(id)?.setAttribute('aria-label', kit.tx(`settings.redesign.judgments.name.${name}`));
|
|
337
|
+
if (!$('jv-status-dot')) return;
|
|
338
|
+
const tabBody = kit.paneOf(overlay, 'judgments');
|
|
339
|
+
const alive = () => document.body.contains(overlay);
|
|
340
|
+
const tabActive = () => alive() && kit.paneActive(overlay, 'judgments');
|
|
341
|
+
|
|
342
|
+
const readJson = async (res) => {
|
|
343
|
+
const text = await res.text();
|
|
344
|
+
let json;
|
|
345
|
+
try { json = JSON.parse(text); } catch { json = { ok: false, error: text.slice(0, 120) || `HTTP ${res.status}` }; }
|
|
346
|
+
if (!res.ok && json.ok !== false) json = { ok: false, error: json.error || `HTTP ${res.status}`, status: res.status };
|
|
347
|
+
if (json.status === undefined) json.status = res.status;
|
|
348
|
+
return json;
|
|
349
|
+
};
|
|
350
|
+
const request = async (method, url, body) => {
|
|
351
|
+
try {
|
|
352
|
+
const res = await fetch(url, { method, headers: body === undefined ? {} : { 'Content-Type': 'application/json' }, body: body === undefined ? undefined : JSON.stringify(body) });
|
|
353
|
+
return await readJson(res);
|
|
354
|
+
} catch (error) { return { ok: false, error: error?.message || kit.tx('settings.redesign.judgments.networkError'), status: 0 }; }
|
|
355
|
+
};
|
|
356
|
+
const jget = (url) => request('GET', url);
|
|
357
|
+
const jput = (url, body) => request('PUT', url, body);
|
|
358
|
+
const jpost = (url, body) => request('POST', url, body ?? {});
|
|
359
|
+
|
|
360
|
+
const state = { cfg: null, backfill: null, openLogIds: new Set(), lastLogSignature: '', timers: {}, armed: {}, triageAbort: null, triageTrashed: new Set(), triageSelected: new Set(), triageLast: null, triagePage: 1 };
|
|
361
|
+
Object.assign(state, {
|
|
362
|
+
sessions: new Map(), sessionsSignature: '', sessionsBooted: false, sessionsUnsupported: false,
|
|
363
|
+
openSessions: new Set(), openTimelineIds: new Set(), timelineHtml: new Map(), timelineKeys: new Map(), timelineLoading: new Set(),
|
|
364
|
+
supersessionsBooted: false, supersessionsUnsupported: false,
|
|
365
|
+
});
|
|
366
|
+
// Shown once the config says the server has them (an older server has neither endpoint).
|
|
367
|
+
$('jv-sec-sessions').style.display = 'none';
|
|
368
|
+
$('jv-sec-supersessions').style.display = 'none';
|
|
369
|
+
{ const saved = storage.getItem(WINDOW_KEY); if (['h24', 'd7', 'process'].includes(saved)) $('jv-st-window').value = saved; }
|
|
370
|
+
|
|
371
|
+
// Which sections are open is the shell's (settings-shell.js: applyStoredSections / storeSectionState).
|
|
372
|
+
// Sections that load on demand refresh whenever they get expanded — by a click, a deep link's `expand`, or a restore.
|
|
373
|
+
const onExpand = { 'jv-sec-log': () => refreshLog(true), 'jv-sec-misfiled': () => refreshMisfiled(), 'jv-sec-sessions': () => refreshSessions(true), 'jv-sec-supersessions': () => refreshSupersessions() };
|
|
374
|
+
const expandObserver = new MutationObserver((records) => {
|
|
375
|
+
for (const r of records) {
|
|
376
|
+
const el = r.target;
|
|
377
|
+
if (el.classList.contains('collapsed') || !onExpand[el.id]) continue;
|
|
378
|
+
onExpand[el.id]();
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
for (const id of Object.keys(onExpand)) { const el = $(id); if (el) expandObserver.observe(el, { attributes: true, attributeFilter: ['class'] }); }
|
|
382
|
+
|
|
383
|
+
// ── Focus-safe input sync ──
|
|
384
|
+
const setValue = (el, value) => { if (!el || document.activeElement === el) return; const v = value == null ? '' : String(value); if (el.value !== v) el.value = v; };
|
|
385
|
+
const setChecked = (el, on) => { if (!el || document.activeElement === el) return; if (el.checked !== Boolean(on)) el.checked = Boolean(on); };
|
|
386
|
+
const setText = (el, text) => { if (el && el.textContent !== String(text)) el.textContent = String(text); };
|
|
387
|
+
const show = (el, html, bg) => { if (!el) return; el.style.display = html ? 'block' : 'none'; el.innerHTML = html || ''; if (bg) el.style.background = bg; };
|
|
388
|
+
|
|
389
|
+
// ── Renderers ──
|
|
390
|
+
function setHeader(cfg) {
|
|
391
|
+
const dot = $('jv-status-dot'), line = $('jv-status-line');
|
|
392
|
+
if (!cfg || cfg.ok === false) {
|
|
393
|
+
dot.className = 'settings-status-dot disconnected';
|
|
394
|
+
line.textContent = cfg?.status === 404 ? kit.tx('settings.redesign.judgments.typesafeSettingsUnavailableTheServerIs') : kit.tx('settings.redesign.judgments.typesafeSettingsUnavailable', { error: cfg?.error || kit.tx('settings.redesign.judgments.noResponse') });
|
|
395
|
+
setNavStatus('disconnected');
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const on = cfg.enabled;
|
|
399
|
+
dot.className = `settings-status-dot ${on ? 'connected' : 'disconnected'}`;
|
|
400
|
+
const s = cfg.stats || {};
|
|
401
|
+
const w = statsWindow(cfg);
|
|
402
|
+
line.textContent = on
|
|
403
|
+
? w.key !== 'process' ? kit.tx('settings.redesign.judgments.connectedCallsFailedInAvgMs', { model: cfg.model, num: num(w.s.calls), num2: num(w.s.failures), label: w.label, num3: num(w.s.avgMs) })
|
|
404
|
+
: kit.tx('settings.redesign.judgments.connectedAnsweredFailedThisProcessAvg', { model: cfg.model, num: num(s.hits), num2: num(s.failures), num3: num(s.avgMs) })
|
|
405
|
+
: cfg.killSwitch ? kit.tx('settings.redesign.judgments.offSynabunTypesafeOffIsSet')
|
|
406
|
+
: !cfg.masterEnabled ? kit.tx('settings.redesign.judgments.offMasterSwitchIsOff')
|
|
407
|
+
: !cfg.hasKey ? kit.tx('settings.redesign.judgments.noApiKeyPasteOneBelow') : kit.tx('settings.redesign.judgments.off');
|
|
408
|
+
setNavStatus(on ? 'connected' : 'disconnected');
|
|
409
|
+
}
|
|
410
|
+
function setNavStatus(status) {
|
|
411
|
+
kit.setNavStatus(overlay, 'judgments', status);
|
|
412
|
+
}
|
|
413
|
+
function renderConnection(cfg) {
|
|
414
|
+
const badge = $('jv-key-source-badge');
|
|
415
|
+
const sourceLabel = cfg.keySource === 'env' ? kit.tx('settings.redesign.judgments.shellEnv') : cfg.keySource === 'dotenv' ? '.env' : 'none';
|
|
416
|
+
setText(badge, cfg.hasKey ? `${cfg.maskedKey} · ${sourceLabel}` : kit.tx('settings.redesign.judgments.noKey'));
|
|
417
|
+
badge.style.color = cfg.shadowed ? '#ffc107' : cfg.hasKey ? 'var(--accent)' : 'var(--t-muted)';
|
|
418
|
+
const input = $('jv-api-key');
|
|
419
|
+
input.dataset.mask = cfg.maskedKey || '';
|
|
420
|
+
input.placeholder = cfg.hasKey ? kit.tx('settings.redesign.judgments.storedPasteToReplace', { maskedKey: cfg.maskedKey }) : kit.tx('settings.redesign.judgments.pasteATypesafeApiKey');
|
|
421
|
+
setText($('jv-key-hint'), cfg.hasKey ? kit.tx('settings.redesign.judgments.keyStored', { key: cfg.maskedKey, source: sourceLabel, note: cfg.keySource === 'env' && !cfg.shadowed ? (" " + kit.tx('settings.redesign.judgments.theEnvCopyMatches')) : '' }) : kit.tx('settings.redesign.judgments.noKeyStoredTypesafeKeysAre'));
|
|
422
|
+
let warning = '';
|
|
423
|
+
if (cfg.shadowed) warning = `<strong>${kit.te('settings.redesign.judgments.aShellExportIsOverridingThe')}</strong> ${kit.te('settings.redesign.judgments.theServerWasLaunchedFromA')} <code>TYPESAFE_API_KEY</code>${kit.te('settings.redesign.judgments.soTheKeyIn')} <code>~/.synabun/.env</code> ${kit.th('settings.redesign.judgments.onDiskIsIgnoredSavingHere', { maskedKey: escapeHtml(String(cfg.maskedKey || '')) })}`;
|
|
424
|
+
else if (cfg.launchShellExport && cfg.keySource === 'env') warning = `${kit.te('settings.redesign.judgments.thisServerWasLaunchedWith')} <code>TYPESAFE_API_KEY</code> ${kit.te('settings.redesign.judgments.exportedInItsShellAndThere')} <code>~/.synabun/.env</code>${kit.te('settings.redesign.judgments.saveTheKeyHereSoA')}`;
|
|
425
|
+
else if (cfg.launchShellExport && cfg.hasKey) warning = `${kit.te('settings.redesign.judgments.noteThisServerWasLaunchedWith')} <code>TYPESAFE_API_KEY</code> ${kit.te('settings.redesign.judgments.exportedInItsShellAfterA')}`;
|
|
426
|
+
show($('jv-key-warning'), warning, warnBg);
|
|
427
|
+
const baseInput = $('jv-base-url');
|
|
428
|
+
setValue(baseInput, cfg.configuredBaseUrl || '');
|
|
429
|
+
baseInput.placeholder = cfg.baseUrlDefault || 'https://api.typesafe.ai';
|
|
430
|
+
setText($('jv-base-url-hint'), cfg.baseUrlSource === 'env'
|
|
431
|
+
? kit.tx('settings.redesign.judgments.usingFromTheServerSTypesafe', { baseUrl: cfg.baseUrl, baseUrlShadowed: cfg.baseUrlShadowed ? (" " + kit.tx('settings.redesign.judgments.itOverridesTheValueSavedHere')) : '' })
|
|
432
|
+
: kit.tx('settings.redesign.judgments.usingBlankDefaultAppliesImmediately', { baseUrl: cfg.baseUrl, baseUrlSource: cfg.baseUrlSource }));
|
|
433
|
+
const model = $('jv-model');
|
|
434
|
+
if (document.activeElement !== model) {
|
|
435
|
+
const models = Array.isArray(cfg.models) ? cfg.models : ['jev-latest'];
|
|
436
|
+
const want = models.map(m => `<option value="${attr(m)}"${m === cfg.model ? ' selected' : ''}>${escapeHtml(m)}</option>`).join('');
|
|
437
|
+
if (model.innerHTML !== want) model.innerHTML = want;
|
|
438
|
+
model.value = cfg.model;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function renderMaster(cfg) {
|
|
442
|
+
const t = $('jv-master-toggle');
|
|
443
|
+
setChecked(t, cfg.masterEnabled);
|
|
444
|
+
t.disabled = Boolean(cfg.killSwitch);
|
|
445
|
+
setText($('jv-master-badge'), cfg.killSwitch ? kit.tx('settings.redesign.judgments.forcedOffBySynabunTypesafeOff') : cfg.masterEnabled ? (cfg.hasKey ? kit.tx('settings.redesign.judgments.stateOn') : kit.tx('settings.redesign.judgments.onButNoKey')) : kit.tx('settings.redesign.judgments.offAllSurfacesUseTheirFallbacks'));
|
|
446
|
+
}
|
|
447
|
+
function surfaceRow(name, s, all = {}) {
|
|
448
|
+
const threshold = s.minConfidence != null
|
|
449
|
+
? `<input type="number" class="jv-sf-threshold" aria-label="${attr(kit.tx('settings.redesign.judgments.name.sfThreshold', { name: s.label || name }))}" min="0" max="1" step="0.05" value="${attr(s.minConfidence)}" style="${smallInput};width:64px">`
|
|
450
|
+
: '<span style="color:var(--t-muted)">—</span>';
|
|
451
|
+
const probability = s.minProbability != null
|
|
452
|
+
? `<input type="number" class="jv-sf-probability" aria-label="${attr(kit.tx('settings.redesign.judgments.name.sfProbability', { name: s.label || name }))}" min="0" max="1" step="0.05" value="${attr(s.minProbability)}" style="${smallInput};width:64px">`
|
|
453
|
+
: '<span style="color:var(--t-muted)">—</span>';
|
|
454
|
+
// A rider is asked inside its lead's request, so the lead's timeout is the one that applies.
|
|
455
|
+
const lead = s.ridesWith ? String(all[s.ridesWith]?.label || s.ridesWith) : null;
|
|
456
|
+
const timeout = lead
|
|
457
|
+
? `<span class="jv-sf-lead-timeout settings-hint" style="margin:0" title="${kit.th('settings.redesign.judgments.askedInsideSRequestSoThat', { attr: attr(lead) })}">${kit.te('settings.redesign.judgments.leadS')}</span>`
|
|
458
|
+
: `<input type="number" class="jv-sf-timeout" aria-label="${attr(kit.tx('settings.redesign.judgments.name.sfTimeout', { name: s.label || name }))}" min="200" max="30000" step="100" value="${attr(s.timeoutMs)}" style="${smallInput};width:78px"><div class="jv-sf-warn settings-hint" style="margin:2px 0 0;color:#ffc107;display:none">${kit.te('settings.redesign.judgments.overTheHookBudget')}</div>`;
|
|
459
|
+
// Limits sit under the description: the table already fills the panel, so a column of their own would squeeze every description.
|
|
460
|
+
const limits = LIMIT_FIELDS.filter(f => s[f.key] != null).map(f => `<label title="${kit.te(`settings.redesign.judgments.limit.${f.key}.help`)}" style="display:inline-flex;flex-wrap:wrap;align-items:center;gap:2px 4px;font-size:11px;color:var(--t-muted)">${kit.te(`settings.redesign.judgments.limit.${f.key}.label`)}<input type="number" class="jv-sf-limit" data-key="${f.key}" min="${f.min}" max="${f.max}" step="${f.step}" value="${attr(s[f.key])}" style="${smallInput};width:${f.width}px"></label>`).join('');
|
|
461
|
+
return `<tr id="jv-sf-${attr(name)}" data-surface="${attr(name)}">
|
|
462
|
+
<td><label class="recall-toggle"><input type="checkbox" class="jv-sf-enabled" aria-label="${attr(kit.tx('settings.redesign.judgments.name.sfEnabled', { name: s.label || name }))}"${s.enabled ? ' checked' : ''}><span class="recall-toggle-track"></span></label></td>
|
|
463
|
+
<td><div style="font-weight:600">${escapeHtml(s.label || name)} <span style="font-weight:400;color:var(--t-muted);font-size:11px">${escapeHtml(name)}</span></div><div class="settings-hint" style="margin:2px 0 0;max-width:420px">${escapeHtml(s.description || '')}<br><span style="opacity:.75">${kit.te('settings.redesign.judgments.fallback')} ${escapeHtml(s.fallback || '')}</span></div>${lead ? `<div class="settings-hint jv-sf-rides" style="margin:2px 0 0;color:var(--accent)">${kit.th('settings.redesign.judgments.ridesWithAskedInTheSame', { lead: escapeHtml(lead) })}</div>` : ''}${limits ? `<div class="jv-sf-limits" style="display:flex;flex-wrap:wrap;gap:4px 10px;margin-top:5px">${limits}</div>` : ''}</td>
|
|
464
|
+
<td>${timeout}</td>
|
|
465
|
+
<td>${threshold}</td>
|
|
466
|
+
<td>${probability}</td>
|
|
467
|
+
<td class="jv-sf-calls">0</td><td class="jv-sf-avg">0</td><td class="jv-sf-fail">0</td><td class="jv-sf-skipped" title="${kit.te('settings.redesign.judgments.thisProcessOnlyCallsSkippedBecause')}">0</td>
|
|
468
|
+
</tr>`;
|
|
469
|
+
}
|
|
470
|
+
function renderSurfaces(cfg) {
|
|
471
|
+
const body = $('jv-surfaces-body');
|
|
472
|
+
const names = Object.keys(cfg.surfaces || {});
|
|
473
|
+
// Rebuilt when the surfaces or a row's shape change (a restarted server can add fields); values sync in place below.
|
|
474
|
+
const shape = names.map(n => { const s = cfg.surfaces[n] || {}; return [n, s.ridesWith || '', s.minConfidence != null, s.minProbability != null, ...LIMIT_FIELDS.map(f => s[f.key] != null)].join(':'); }).join('|');
|
|
475
|
+
if (body.dataset.shape !== shape) { body.innerHTML = names.map(n => surfaceRow(n, cfg.surfaces[n], cfg.surfaces)).join(''); body.dataset.shape = shape; }
|
|
476
|
+
// Counters come from the judgment log when the server keeps them there; otherwise from this process.
|
|
477
|
+
const logStats = cfg.logStats && typeof cfg.logStats === 'object' ? cfg.logStats : null;
|
|
478
|
+
// A server that sends budgetMs names each hook's budget; an older one gets the list this page always used.
|
|
479
|
+
const budgets = names.some(n => fin(cfg.surfaces[n]?.budgetMs));
|
|
480
|
+
let on = 0;
|
|
481
|
+
for (const name of names) {
|
|
482
|
+
const s = cfg.surfaces[name];
|
|
483
|
+
const row = body.querySelector(`tr[data-surface="${name}"]`);
|
|
484
|
+
if (!row) continue;
|
|
485
|
+
if (s.enabled) on++;
|
|
486
|
+
setChecked(row.querySelector('.jv-sf-enabled'), s.enabled);
|
|
487
|
+
setValue(row.querySelector('.jv-sf-timeout'), s.timeoutMs);
|
|
488
|
+
setValue(row.querySelector('.jv-sf-threshold'), s.minConfidence);
|
|
489
|
+
setValue(row.querySelector('.jv-sf-probability'), s.minProbability);
|
|
490
|
+
for (const input of row.querySelectorAll('.jv-sf-limit')) setValue(input, s[input.dataset.key]);
|
|
491
|
+
const lead = s.ridesWith ? cfg.surfaces[s.ridesWith] : null;
|
|
492
|
+
setText(row.querySelector('.jv-sf-lead-timeout'), lead && fin(lead.timeoutMs) ? `lead's · ${num(lead.timeoutMs)}` : "lead's");
|
|
493
|
+
const m = s.metrics || {};
|
|
494
|
+
const calls = row.querySelector('.jv-sf-calls'), avg = row.querySelector('.jv-sf-avg'), fail = row.querySelector('.jv-sf-fail');
|
|
495
|
+
if (logStats) {
|
|
496
|
+
const h = logStats.surfaces?.[name]?.h24 || {}, d = logStats.surfaces?.[name]?.d7 || {};
|
|
497
|
+
setText(calls, `${num(h.calls)} / ${num(d.calls)}`);
|
|
498
|
+
setText(avg, num(Math.round(Number(Number(h.calls) ? h.avgMs : d.avgMs) || 0)));
|
|
499
|
+
avg.title = Number(h.calls) ? kit.tx('settings.redesign.judgments.averageOverTheLast24H') : kit.tx('settings.redesign.judgments.averageOverTheLast7D');
|
|
500
|
+
setText(fail, num(h.failures));
|
|
501
|
+
} else {
|
|
502
|
+
setText(calls, num(m.calls));
|
|
503
|
+
setText(avg, num(m.avgMs));
|
|
504
|
+
avg.title = '';
|
|
505
|
+
setText(fail, num(m.failures));
|
|
506
|
+
}
|
|
507
|
+
setText(row.querySelector('.jv-sf-skipped'), num(m.skipped));
|
|
508
|
+
const warn = row.querySelector('.jv-sf-warn');
|
|
509
|
+
if (warn) {
|
|
510
|
+
const budget = budgets ? (fin(s.budgetMs) ? Number(s.budgetMs) : null) : LEGACY_HOOK_SURFACES.includes(name) ? HOOK_BUDGET_MS : null;
|
|
511
|
+
const over = budget != null && Number(s.timeoutMs) > budget;
|
|
512
|
+
warn.style.display = over ? 'block' : 'none';
|
|
513
|
+
if (over) setText(warn, kit.tx('settings.redesign.judgments.overTheMsHookBudget', { num: num(budget) }));
|
|
514
|
+
}
|
|
515
|
+
row.style.opacity = s.enabled ? '1' : '0.6';
|
|
516
|
+
}
|
|
517
|
+
// Non-breaking spaces: the header may wrap after its first word, never inside "24 h".
|
|
518
|
+
setText($('jv-sf-h-calls'), logStats ? kit.tx('settings.redesign.judgments.callsWindows') : kit.tx('settings.redesign.judgments.calls'));
|
|
519
|
+
setText($('jv-sf-h-fail'), logStats ? kit.tx('settings.redesign.judgments.failWindow') : kit.tx('settings.redesign.judgments.fail'));
|
|
520
|
+
$('jv-sf-h-skipped').title = logStats ? kit.tx('settings.redesign.judgments.thisProcessOnlyASurfaceThat') : '';
|
|
521
|
+
const hint = $('jv-surfaces-hint');
|
|
522
|
+
const oldest = logStats ? Date.parse(logStats.oldest) : NaN;
|
|
523
|
+
const text = logStats
|
|
524
|
+
? kit.tx('settings.redesign.judgments.oneRowPerJudgmentTurningA2', { fin: fin(oldest) && Date.now() - oldest < SESSIONS_DAYS * 864e5 ? (" " + kit.tx('settings.redesign.judgments.theLogReachesBackOnlyTo', { stamp: stamp(logStats.oldest) })) : '' })
|
|
525
|
+
: kit.tx('settings.redesign.judgments.oneRowPerJudgmentTurningA', { HOOK_BUDGET_MS: HOOK_BUDGET_MS });
|
|
526
|
+
setText(hint, text);
|
|
527
|
+
setText($('jv-surfaces-badge'), kit.tx('settings.redesign.judgments.surfacesOn', { on, total: names.length }));
|
|
528
|
+
}
|
|
529
|
+
function spend(stats, rateIn, rateOut) {
|
|
530
|
+
const cost = Number(stats.inputTokens || 0) / 1e6 * (rateIn || 0) + Number(stats.outputTokens || 0) / 1e6 * (rateOut || 0);
|
|
531
|
+
return money(cost);
|
|
532
|
+
}
|
|
533
|
+
/** The figures the header and the tiles show: the log's 24 h or 7 d totals when the server keeps them, else this process's counters. */
|
|
534
|
+
function statsWindow(cfg) {
|
|
535
|
+
const logStats = cfg?.logStats && typeof cfg.logStats === 'object' ? cfg.logStats : null;
|
|
536
|
+
const wanted = $('jv-st-window').value;
|
|
537
|
+
if (!logStats || wanted === 'process') return { key: 'process', label: kit.tx('settings.redesign.judgments.thisProcess'), s: cfg?.stats || {} };
|
|
538
|
+
const key = wanted === 'd7' ? 'd7' : 'h24';
|
|
539
|
+
const t = logStats.totals?.[key] || {};
|
|
540
|
+
const calls = Number(t.calls || 0), failures = Number(t.failures || 0);
|
|
541
|
+
// The log's totals carry calls, failures, latency and input tokens; anything else shows as a dash.
|
|
542
|
+
return { key, label: key === 'd7' ? kit.tx('settings.redesign.judgments.theLast7D') : kit.tx('settings.redesign.judgments.theLast24H'), s: { calls, failures, hits: fin(t.hits) ? Number(t.hits) : Math.max(0, calls - failures), cached: fin(t.cached) ? Number(t.cached) : null, inputTokens: Number(t.inputTokens || 0), outputTokens: fin(t.outputTokens) ? Number(t.outputTokens) : null, avgMs: fin(t.avgMs) ? Math.round(Number(t.avgMs)) : 0 } };
|
|
543
|
+
}
|
|
544
|
+
function renderStatsWindow(cfg, w) {
|
|
545
|
+
const logStats = cfg.logStats && typeof cfg.logStats === 'object' ? cfg.logStats : null;
|
|
546
|
+
$('jv-st-window-row').style.display = logStats ? 'flex' : 'none';
|
|
547
|
+
$('jv-metrics-reset').title = logStats ? kit.tx('settings.redesign.judgments.resetsThisProcessSCountersThe') : '';
|
|
548
|
+
if (!logStats) return;
|
|
549
|
+
const hint = $('jv-st-window-hint');
|
|
550
|
+
const oldest = Date.parse(logStats.oldest);
|
|
551
|
+
const partial = fin(oldest) && Date.now() - oldest < SESSIONS_DAYS * 864e5;
|
|
552
|
+
setText(hint, !fin(oldest) ? kit.tx('settings.redesign.judgments.theJudgmentLogIsEmpty')
|
|
553
|
+
: partial ? kit.tx('settings.redesign.judgments.theLogReachesBackOnlyTo2', { stamp: stamp(logStats.oldest), duration: duration(Date.now() - oldest) })
|
|
554
|
+
: kit.tx('settings.redesign.judgments.theLogReachesBackTo', { stamp: stamp(logStats.oldest) }));
|
|
555
|
+
hint.style.color = partial && w.key === 'd7' ? '#ffc107' : '';
|
|
556
|
+
}
|
|
557
|
+
function renderTelemetry(cfg) {
|
|
558
|
+
const s = cfg.stats || {};
|
|
559
|
+
const w = statsWindow(cfg), ws = w.s;
|
|
560
|
+
const dash = (n) => (n == null ? '—' : num(n));
|
|
561
|
+
setText($('jv-st-calls'), num(ws.calls)); setText($('jv-st-hits'), num(ws.hits)); setText($('jv-st-failures'), num(ws.failures)); setText($('jv-st-cached'), dash(ws.cached));
|
|
562
|
+
setText($('jv-st-in'), num(ws.inputTokens)); setText($('jv-st-out'), dash(ws.outputTokens)); setText($('jv-st-avg'), num(ws.avgMs));
|
|
563
|
+
renderStatsWindow(cfg, w);
|
|
564
|
+
const rateIn = Number($('jv-rate-in').value || cfg.costPerMillionInput || 0), rateOut = Number($('jv-rate-out').value || cfg.costPerMillionOutput || 0);
|
|
565
|
+
setText($('jv-st-cost'), (rateIn || rateOut) ? spend(ws, rateIn, rateOut) : kit.tx('settings.redesign.judgments.setRates'));
|
|
566
|
+
setValue($('jv-rate-in'), cfg.costPerMillionInput); setValue($('jv-rate-out'), cfg.costPerMillionOutput);
|
|
567
|
+
const err = $('jv-st-lasterror');
|
|
568
|
+
err.textContent = s.lastError ? kit.tx('settings.redesign.judgments.lastError', { lastError: s.lastError, lastErrorAt: s.lastErrorAt ? (" " + kit.tx('settings.redesign.judgments.at', { clock: clock(s.lastErrorAt) })) : '', retryAfterMs: s.retryAfterMs > 0 ? (" " + kit.tx('settings.redesign.judgments.rateLimitedRetryInS', { retryAfterMs: Math.ceil(s.retryAfterMs / 1000) })) : '' }) : kit.tx('settings.redesign.judgments.noErrorsThisProcess');
|
|
569
|
+
err.style.color = s.lastError ? '#f66' : '';
|
|
570
|
+
setText($('jv-telemetry-badge'), kit.tx('settings.redesign.judgments.telemetryBadge', { calls: num(ws.calls), tokens: num(ws.inputTokens), window: w.key === 'd7' ? ' · 7 d' : w.key === 'h24' ? ' · 24 h' : '' }));
|
|
571
|
+
const size = Number(s.cacheSize || 0), cached = Number(s.cached || 0), calls = Number(s.calls || 0);
|
|
572
|
+
setText($('jv-cache-size'), num(size));
|
|
573
|
+
setText($('jv-cache-ratio'), (cached + calls) ? pct(cached / (cached + calls)) : '—');
|
|
574
|
+
}
|
|
575
|
+
function renderCoverage(cfg) {
|
|
576
|
+
const c = cfg.coverage || { judged: 0, total: 0 };
|
|
577
|
+
const ratio = c.total ? c.judged / c.total : 0;
|
|
578
|
+
setText($('jv-coverage'), kit.tx('settings.redesign.judgments.coverageLiveMemoriesJudged', { num: num(c.judged), num2: num(c.total), pct: pct(ratio) }));
|
|
579
|
+
$('jv-coverage-bar').style.width = `${Math.round(ratio * 100)}%`;
|
|
580
|
+
}
|
|
581
|
+
function renderBench(cfg) {
|
|
582
|
+
const last = cfg.benchRunAt;
|
|
583
|
+
const summaries = cfg.bench || {};
|
|
584
|
+
const parts = Object.entries(summaries).map(([s, b]) => `${s} ${pct(b.agreement)} (n=${b.n})`);
|
|
585
|
+
setText($('jv-bench-last'), last ? kit.tx('settings.redesign.judgments.lastImportanceBench', { stamp: stamp(last), count: parts.length ? ` · ${parts.join(' · ')}` : '' }) : kit.tx('settings.redesign.judgments.lastBenchNeverRunOneTo'));
|
|
586
|
+
setText($('jv-bench-badge'), last ? kit.tx('settings.redesign.judgments.benchBadge', { date: new Date(last).toLocaleDateString() }) : kit.tx('settings.redesign.judgments.notRun'));
|
|
587
|
+
const apply = $('jv-apply-importance');
|
|
588
|
+
apply.disabled = !last;
|
|
589
|
+
setChecked(apply, cfg.applyJudgedImportance);
|
|
590
|
+
}
|
|
591
|
+
// ── Browser assistance ──
|
|
592
|
+
const BA_COUNTERS = [['pageAssessments', kit.tx('settings.redesign.judgments.pageAssessments')], ['recommendations', kit.tx('settings.redesign.judgments.recommendations')], ['shadowAutoHealEligible', kit.tx('settings.redesign.judgments.wouldHaveHealedShadow')], ['autoHealAttempted', kit.tx('settings.redesign.judgments.autoHealAttempted')],
|
|
593
|
+
['autoHealSucceeded', kit.tx('settings.redesign.judgments.autoHealSucceeded')], ['blockedBySafety', kit.tx('settings.redesign.judgments.blockedBySafety')], ['skippedRateLimit', kit.tx('settings.redesign.judgments.skippedRateLimit')], ['fallbackUnavailable', kit.tx('settings.redesign.judgments.fallbackUnavailable')]];
|
|
594
|
+
function renderBrowserAssist(cfg) {
|
|
595
|
+
const ba = cfg.browserAssist;
|
|
596
|
+
const toggleEl = $('jv-ba-autoheal');
|
|
597
|
+
if (!toggleEl) return;
|
|
598
|
+
// This file is served from disk, so it can be newer than the running server: say so rather than render an empty section.
|
|
599
|
+
if (!ba) {
|
|
600
|
+
setText($('jv-browser-badge'), kit.tx('settings.redesign.judgments.restartTheNeuralInterfaceAfterNpm'));
|
|
601
|
+
show($('jv-ba-mode'), kit.tx('settings.redesign.judgments.thisServerWasStartedBeforeBrowser'), warnBg);
|
|
602
|
+
toggleEl.disabled = true;
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
const on = ba.mode === 'auto-heal';
|
|
606
|
+
setText($('jv-browser-badge'), on ? kit.tx('settings.redesign.judgments.autoHealOn') : ba.autoHealEnabled ? kit.tx('settings.redesign.judgments.shadowAutoHealLocked') : kit.tx('settings.redesign.judgments.stateShadow'));
|
|
607
|
+
show($('jv-ba-mode'), `<strong>${on ? kit.te('settings.redesign.judgments.autoHeal') : kit.te('settings.redesign.judgments.shadow')}</strong> — ${on
|
|
608
|
+
? kit.te('settings.redesign.judgments.adviceOnEverySurfaceAndOne')
|
|
609
|
+
: kit.te('settings.redesign.judgments.adviceOnlyHintsAreReorderedAnd')}<br><span style="font-family:monospace;font-size:11px;opacity:.85">${kit.te('settings.redesign.judgments.basis')} ${escapeHtml(ba.basis || kit.tx('settings.redesign.judgments.unavailable'))}</span>`, on ? okBg : 'var(--s-darker)');
|
|
610
|
+
const b = ba.targetBench;
|
|
611
|
+
setText($('jv-ba-bench'), b
|
|
612
|
+
? kit.tx('settings.redesign.judgments.lastBrowserBenchmark', { stamp: stamp(b.at), model: b.model, passed: b.passed ? kit.tx('settings.redesign.judgments.passedEveryGate') : kit.tx('settings.redesign.judgments.didNotPass'), reportFile: b.reportFile ? ` · ${String(b.reportFile).split('/').slice(-2).join('/')}` : '' })
|
|
613
|
+
: kit.tx('settings.redesign.judgments.lastBrowserBenchmarkNeverPickBrowser'));
|
|
614
|
+
setText($('jv-ba-reasons'), ba.eligible ? '' : (ba.reasons || []).join(' '));
|
|
615
|
+
$('jv-ba-counters').innerHTML = BA_COUNTERS.map(([key, label]) => `<div class="db-stat"><span class="db-stat-label">${label}</span><span class="db-stat-value">${num((ba.counters || {})[key])}</span></div>`).join('');
|
|
616
|
+
// Turning it off is always possible; turning it on needs a passing benchmark of this exact configuration.
|
|
617
|
+
toggleEl.disabled = !ba.eligible && !ba.autoHealEnabled;
|
|
618
|
+
setChecked(toggleEl, ba.autoHealEnabled);
|
|
619
|
+
}
|
|
620
|
+
// ── Desktop assistance ──
|
|
621
|
+
const DA_COUNTERS = [['intentSnapshots', kit.tx('settings.redesign.judgments.intentSnapshots')], ['recommendations', kit.tx('settings.redesign.judgments.recommendations')], ['pressEligibleAdvisory', kit.tx('settings.redesign.judgments.wouldHavePressedLocked')], ['pressAttempted', kit.tx('settings.redesign.judgments.pressesAttempted')],
|
|
622
|
+
['pressSucceeded', kit.tx('settings.redesign.judgments.pressesSucceeded')], ['blockedBySafety', kit.tx('settings.redesign.judgments.blockedBySafety')], ['skippedRateLimit', kit.tx('settings.redesign.judgments.skippedRateLimit')], ['fallbackUnavailable', kit.tx('settings.redesign.judgments.fallbackUnavailable')]];
|
|
623
|
+
function renderDesktopAssist(cfg) {
|
|
624
|
+
const da = cfg.desktopAssist;
|
|
625
|
+
const toggleEl = $('jv-da-press');
|
|
626
|
+
if (!toggleEl) return;
|
|
627
|
+
// Served from disk, so possibly newer than the running server: say so rather than render an empty section.
|
|
628
|
+
if (!da) {
|
|
629
|
+
setText($('jv-desktop-badge'), kit.tx('settings.redesign.judgments.restartAfterNpmRunMcpBuild'));
|
|
630
|
+
show($('jv-da-mode'), '' + kit.te('settings.redesign.judgments.thisServerWasStartedBeforeDesktop') + ' <code>npm run mcp:build</code> ' + kit.te('settings.redesign.judgments.toLoadItUntilThenComputer') + '', warnBg);
|
|
631
|
+
setText($('jv-da-bench'), ''); setText($('jv-da-reasons'), ''); $('jv-da-counters').innerHTML = '';
|
|
632
|
+
toggleEl.disabled = true;
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
const on = da.mode === 'press';
|
|
636
|
+
setText($('jv-desktop-badge'), on ? kit.tx('settings.redesign.judgments.pressByIntentOn') : da.pressEnabled ? kit.tx('settings.redesign.judgments.advisoryPressLocked') : 'advisory');
|
|
637
|
+
show($('jv-da-mode'), `<strong>${on ? kit.te('settings.redesign.judgments.pressByIntent') : kit.te('settings.redesign.judgments.advisory')}</strong> — ${on
|
|
638
|
+
? kit.te('settings.redesign.judgments.aRankedListAndAdviceOn')
|
|
639
|
+
: kit.te('settings.redesign.judgments.aRankedListAndAdviceOn2')}<br><span style="font-family:monospace;font-size:11px;opacity:.85">${kit.te('settings.redesign.judgments.basis')} ${escapeHtml(da.basis || kit.tx('settings.redesign.judgments.unavailable'))}</span>`, on ? okBg : 'var(--s-darker)');
|
|
640
|
+
const b = da.targetBench;
|
|
641
|
+
setText($('jv-da-bench'), b
|
|
642
|
+
? kit.tx('settings.redesign.judgments.lastDesktopBenchmark', { stamp: stamp(b.at), model: b.model, passed: b.passed ? kit.tx('settings.redesign.judgments.passedEveryGate') : kit.tx('settings.redesign.judgments.didNotPass'), reportFile: b.reportFile ? ` · ${String(b.reportFile).split('/').slice(-2).join('/')}` : '' })
|
|
643
|
+
: kit.tx('settings.redesign.judgments.lastDesktopBenchmarkNeverPickDesktop'));
|
|
644
|
+
setText($('jv-da-reasons'), da.eligible ? '' : (da.reasons || []).join(' '));
|
|
645
|
+
$('jv-da-counters').innerHTML = DA_COUNTERS.map(([key, label]) => `<div class="db-stat"><span class="db-stat-label">${label}</span><span class="db-stat-value">${num((da.counters || {})[key])}</span></div>`).join('');
|
|
646
|
+
// Off is always reachable; on needs a passing desktop benchmark of this exact configuration.
|
|
647
|
+
toggleEl.disabled = !da.eligible && !da.pressEnabled;
|
|
648
|
+
setChecked(toggleEl, da.pressEnabled);
|
|
649
|
+
}
|
|
650
|
+
function applyConfig(cfg) {
|
|
651
|
+
if (!cfg || cfg.ok === false) { setHeader(cfg); return; }
|
|
652
|
+
state.cfg = cfg;
|
|
653
|
+
setHeader(cfg); renderConnection(cfg); renderMaster(cfg); renderSurfaces(cfg); renderTelemetry(cfg); renderCoverage(cfg); renderBench(cfg); renderBrowserAssist(cfg);
|
|
654
|
+
renderDesktopAssist(cfg);
|
|
655
|
+
renderSessionsMeta(cfg); renderSupersessionsMeta(cfg); syncLogFilters(cfg);
|
|
656
|
+
if (cfg.backfill) applyBackfill(cfg.backfill);
|
|
657
|
+
const logSurface = $('jv-log-surface');
|
|
658
|
+
if (logSurface.options.length <= 1) {
|
|
659
|
+
for (const name of Object.keys(cfg.surfaces || {})) { const o = document.createElement('option'); o.value = name; o.textContent = name; logSurface.appendChild(o); }
|
|
660
|
+
const o = document.createElement('option'); o.value = 'connection-test'; o.textContent = kit.tx('settings.redesign.judgments.connectionTest'); logSurface.appendChild(o);
|
|
661
|
+
// Filters saved before session / memory / project existed parse the same; the new fields just stay blank.
|
|
662
|
+
try { const f = JSON.parse(storage.getItem(LOG_FILTER_KEY) || 'null'); if (f) { logSurface.value = f.surface || ''; $('jv-log-origin').value = f.origin || ''; $('jv-log-limit').value = f.limit || '50'; for (const key of ['session', 'entity', 'project']) if (typeof f[key] === 'string') $(`jv-log-${key}`).value = f[key]; } } catch { /* defaults */ }
|
|
663
|
+
if ($('jv-log-origin').selectedIndex < 0) $('jv-log-origin').value = ''; // an origin this server does not list
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
async function loadConfig() { applyConfig(await jget('/api/typesafe/config')); }
|
|
667
|
+
async function putConfig(patch, okMessage) {
|
|
668
|
+
const res = await jput('/api/typesafe/config', patch);
|
|
669
|
+
if (res.ok === false) { toast(kit.tx('settings.redesign.judgments.errJudgments', { error: res.error || kit.tx('settings.redesign.judgments.saveFailed') })); await loadConfig(); return null; }
|
|
670
|
+
applyConfig(res);
|
|
671
|
+
if (okMessage) toast(okMessage);
|
|
672
|
+
return res;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// ── Connection handlers ──
|
|
676
|
+
$('jv-key-save').addEventListener('click', async () => {
|
|
677
|
+
const value = $('jv-api-key').value.trim();
|
|
678
|
+
if (!value) { toast(kit.tx('settings.redesign.judgments.pasteAKeyFirst')); return; }
|
|
679
|
+
const res = await putConfig({ apiKey: value }, kit.tx('settings.redesign.judgments.typesafeKeySaved'));
|
|
680
|
+
if (res) { $('jv-api-key').value = ''; }
|
|
681
|
+
});
|
|
682
|
+
$('jv-key-clear').addEventListener('click', async () => {
|
|
683
|
+
const btn = $('jv-key-clear');
|
|
684
|
+
if (!state.armed.clear) { state.armed.clear = true; btn.textContent = kit.tx('settings.redesign.judgments.confirmClear'); setTimeout(() => { state.armed.clear = false; btn.textContent = kit.tx('settings.redesign.judgments.clear'); }, 5000); return; }
|
|
685
|
+
state.armed.clear = false; btn.textContent = kit.tx('settings.redesign.judgments.clear');
|
|
686
|
+
await putConfig({ apiKey: '' }, kit.tx('settings.redesign.judgments.typesafeKeyRemoved'));
|
|
687
|
+
show($('jv-test-result'), '');
|
|
688
|
+
});
|
|
689
|
+
$('jv-key-test').addEventListener('click', async () => {
|
|
690
|
+
const pending = $('jv-api-key').value.trim();
|
|
691
|
+
if (pending) { const saved = await putConfig({ apiKey: pending }); if (!saved) return; $('jv-api-key').value = ''; }
|
|
692
|
+
const box = $('jv-test-result');
|
|
693
|
+
show(box, kit.tx('settings.redesign.judgments.testing'), 'var(--s-darker)');
|
|
694
|
+
const res = await jpost('/api/typesafe/test');
|
|
695
|
+
if (res.ok) {
|
|
696
|
+
show(box, `<strong>${kit.te('settings.redesign.judgments.ok')}</strong> ${kit.th('settings.redesign.judgments.msInOutAt', { num: num(res.latencyMs), num2: num(res.inputTokens), num3: num(res.outputTokens), model: escapeHtml(res.model || '') })} ${escapeHtml(res.baseUrl || '')}<pre style="margin:6px 0 0;white-space:pre-wrap;font-size:11px">${escapeHtml(JSON.stringify(res.answer, null, 2))}</pre>`, okBg);
|
|
697
|
+
} else show(box, `<strong>${kit.te('settings.redesign.judgments.notWorking')}</strong> · ${escapeHtml(res.reason || res.error || kit.tx('settings.redesign.judgments.unknown'))}${res.latencyMs ? (" " + kit.th('settings.redesign.judgments.ms', { num: num(res.latencyMs) })) : ''}`, errBg);
|
|
698
|
+
loadConfig();
|
|
699
|
+
});
|
|
700
|
+
$('jv-base-url-save').addEventListener('click', () => putConfig({ baseUrl: $('jv-base-url').value.trim() }, kit.tx('settings.redesign.judgments.baseUrlSaved')));
|
|
701
|
+
$('jv-model').addEventListener('change', () => putConfig({ model: $('jv-model').value }, kit.tx('settings.redesign.judgments.modelSetTo', { value: $('jv-model').value })));
|
|
702
|
+
|
|
703
|
+
// ── Master switch ──
|
|
704
|
+
$('jv-master-toggle').addEventListener('change', () => putConfig({ enabled: $('jv-master-toggle').checked }, $('jv-master-toggle').checked ? kit.tx('settings.redesign.judgments.judgmentsOn') : kit.tx('settings.redesign.judgments.judgmentsOffEverySurfaceNowUses')));
|
|
705
|
+
|
|
706
|
+
// ── Surfaces ──
|
|
707
|
+
const surfaceDebounce = new Map();
|
|
708
|
+
const readRow = (row) => {
|
|
709
|
+
const patch = { enabled: row.querySelector('.jv-sf-enabled').checked };
|
|
710
|
+
// A rider has no timeout of its own to send: it rides on its lead's.
|
|
711
|
+
const to = row.querySelector('.jv-sf-timeout');
|
|
712
|
+
if (to) patch.timeoutMs = Number(to.value);
|
|
713
|
+
const th = row.querySelector('.jv-sf-threshold');
|
|
714
|
+
if (th) patch.minConfidence = Number(th.value);
|
|
715
|
+
const pr = row.querySelector('.jv-sf-probability');
|
|
716
|
+
if (pr) patch.minProbability = Number(pr.value);
|
|
717
|
+
// Limits: only the fields this surface carries; a half-typed (empty) value is left for the server to keep.
|
|
718
|
+
for (const input of row.querySelectorAll('.jv-sf-limit')) if (fin(input.value)) patch[input.dataset.key] = Number(input.value);
|
|
719
|
+
return patch;
|
|
720
|
+
};
|
|
721
|
+
async function putSurface(row) {
|
|
722
|
+
const name = row.dataset.surface;
|
|
723
|
+
const res = await putConfig({ surfaces: { [name]: readRow(row) } });
|
|
724
|
+
setText($('jv-surfaces-status'), res ? kit.tx('settings.redesign.judgments.savedAt', { name, time: clock(new Date().toISOString()) }) : kit.tx('settings.redesign.judgments.couldNotSave', { name: name }));
|
|
725
|
+
}
|
|
726
|
+
$('jv-surfaces-body').addEventListener('change', (e) => {
|
|
727
|
+
const row = e.target.closest('tr[data-surface]');
|
|
728
|
+
if (!row) return;
|
|
729
|
+
surfaceDebounce.get(row.dataset.surface)?.cancel?.();
|
|
730
|
+
putSurface(row);
|
|
731
|
+
});
|
|
732
|
+
$('jv-surfaces-body').addEventListener('input', (e) => {
|
|
733
|
+
const row = e.target.closest('tr[data-surface]');
|
|
734
|
+
if (!row || !e.target.matches('.jv-sf-timeout, .jv-sf-threshold, .jv-sf-probability, .jv-sf-limit')) return;
|
|
735
|
+
let fn = surfaceDebounce.get(row.dataset.surface);
|
|
736
|
+
if (!fn) { fn = debounce(() => putSurface(row), 600); surfaceDebounce.set(row.dataset.surface, fn); }
|
|
737
|
+
fn();
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
// ── Telemetry / cache ──
|
|
741
|
+
const liveSpend = () => { if (state.cfg) setText($('jv-st-cost'), spend(statsWindow(state.cfg).s, Number($('jv-rate-in').value || 0), Number($('jv-rate-out').value || 0))); };
|
|
742
|
+
$('jv-st-window').addEventListener('change', () => { storage.setItem(WINDOW_KEY, $('jv-st-window').value); if (state.cfg) { setHeader(state.cfg); renderTelemetry(state.cfg); } });
|
|
743
|
+
$('jv-rate-in').addEventListener('input', liveSpend); $('jv-rate-out').addEventListener('input', liveSpend);
|
|
744
|
+
$('jv-rates-save').addEventListener('click', () => putConfig({ costPerMillionInput: Number($('jv-rate-in').value || 0), costPerMillionOutput: Number($('jv-rate-out').value || 0) }, kit.tx('settings.redesign.judgments.ratesSaved')));
|
|
745
|
+
$('jv-metrics-reset').addEventListener('click', async () => { const r = await jpost('/api/typesafe/metrics/reset'); if (r.ok) { toast(kit.tx('settings.redesign.judgments.countersReset')); loadConfig(); } else toast(kit.tx('settings.redesign.judgments.errJudgments', { error: r.error })); });
|
|
746
|
+
$('jv-cache-clear').addEventListener('click', async () => { const r = await jpost('/api/typesafe/cache/clear'); if (r.ok) { toast(kit.tx('settings.redesign.judgments.answerCacheCleared')); loadConfig(); } else toast(kit.tx('settings.redesign.judgments.errJudgments', { error: r.error })); });
|
|
747
|
+
|
|
748
|
+
// ── Backfill ──
|
|
749
|
+
function applyBackfill(b) {
|
|
750
|
+
if (!b) return;
|
|
751
|
+
state.backfill = b;
|
|
752
|
+
const status = b.status || 'idle';
|
|
753
|
+
setText($('jv-backfill-badge'), status);
|
|
754
|
+
const est = b.estimate;
|
|
755
|
+
const inputs = { project: $('jv-bf-project').value.trim() || null, limit: $('jv-bf-limit').value ? Number($('jv-bf-limit').value) : null };
|
|
756
|
+
const estMatches = est && (est.rows != null) && state.estimateFor && state.estimateFor.project === inputs.project && state.estimateFor.limit === inputs.limit;
|
|
757
|
+
if (est) show($('jv-bf-estimate-box'), `<strong>${kit.te('settings.redesign.judgments.estimate')}</strong> ${kit.th('settings.redesign.judgments.memoriesImportanceKindRequestsRelationRe', { basis: escapeHtml(est.basis), stamp: stamp(est.at), num: num(est.rows), num2: num(est.calls.importanceKind), num3: num(est.calls.relations), num4: num(est.tokens.input), num5: num(est.tokens.output) })} <strong>${money(est.costUsd)}</strong> ${kit.th('settings.redesign.judgments.atMInAboutAtConcurrent', { input: est.rates.input, duration: duration(est.wallClockMs), concurrency: est.concurrency })}${est.sample ? (" " + kit.th('settings.redesign.judgments.neighbourSampleHadCandidates', { withCandidates: est.sample.withCandidates, size: est.sample.size })) : ''}`, 'var(--s-darker)');
|
|
758
|
+
const running = status === 'running', paused = status === 'paused';
|
|
759
|
+
$('jv-bf-estimate').disabled = running;
|
|
760
|
+
$('jv-bf-start').disabled = running || paused || !estMatches;
|
|
761
|
+
$('jv-bf-start').textContent = state.armed.start ? kit.tx('settings.redesign.judgments.confirmStart', { money: money(est?.costUsd) }) : kit.tx('settings.redesign.judgments.start');
|
|
762
|
+
$('jv-bf-pause').disabled = !running;
|
|
763
|
+
$('jv-bf-resume').disabled = !paused;
|
|
764
|
+
$('jv-bf-cancel').disabled = !(running || paused);
|
|
765
|
+
const dot = $('jv-bf-dot');
|
|
766
|
+
dot.className = `wiz-status-dot${running ? ' spin' : status === 'done' ? ' green' : (paused && b.pausedReason === 'failures') || status === 'cancelled' ? ' red' : ''}`;
|
|
767
|
+
const total = Number(b.total || 0), judged = Number(b.judged || 0), remaining = Number(b.jobs?.pending || 0) + Number(b.jobs?.running || 0);
|
|
768
|
+
setText($('jv-bf-text'), status === 'idle' ? kit.tx('settings.redesign.judgments.idle')
|
|
769
|
+
: running ? kit.tx('settings.redesign.judgments.bfRunning', { judged: num(judged), remaining: num(remaining), retry: b.retryAfterMs > 0 ? (" " + kit.tx('settings.redesign.judgments.rateLimitedRetryingInS', { retryAfterMs: Math.ceil(b.retryAfterMs / 1000) })) : '' })
|
|
770
|
+
: paused ? kit.tx('settings.redesign.judgments.bfPaused', { reason: b.pausedReason === 'failures' ? (" " + kit.tx('settings.redesign.judgments.afterRepeatedFailures')) : '', judged: num(judged), remaining: num(remaining) })
|
|
771
|
+
: status === 'done' ? kit.tx('settings.redesign.judgments.doneJudgedIn', { num: num(judged), duration: duration(b.report?.wallClockMs) })
|
|
772
|
+
: kit.tx('settings.redesign.judgments.bfCancelled', { judged: num(judged) }));
|
|
773
|
+
$('jv-bf-bar').style.width = total ? `${Math.min(100, Math.round(judged / total * 100))}%` : '0%';
|
|
774
|
+
setText($('jv-bf-summary'), (judged || b.failures) ? kit.tx('settings.redesign.judgments.relationsSimilarPossibleConflictDuplicat', { num: num(b.relationsCreated?.similar), num2: num(b.relationsCreated?.possible_conflict), num3: num(b.relationsCreated?.duplicate_of), num4: num(b.disagreements?.kind), num5: num(b.disagreements?.importance), num6: num(b.tokensIn), num7: num(b.tokensOut), num8: num(b.failures), startedAt: b.startedAt ? (" " + kit.tx('settings.redesign.judgments.started', { stamp: stamp(b.startedAt) })) : '' }) : '');
|
|
775
|
+
setText($('jv-bf-error'), b.lastError ? kit.tx('settings.redesign.judgments.lastError2', { lastError: b.lastError, lastErrorAt: b.lastErrorAt ? (" " + kit.tx('settings.redesign.judgments.at', { clock: clock(b.lastErrorAt) })) : '' }) : '');
|
|
776
|
+
const r = b.report;
|
|
777
|
+
show($('jv-bf-report'), r ? `<strong>${kit.te('settings.redesign.judgments.report')}</strong> ${kit.th('settings.redesign.judgments.ofJudgedSkippedFailuresWallClock', { num: num(r.judged), num2: num(r.total), num3: num(r.skipped), num4: num(r.failures), duration: duration(r.wallClockMs), num5: num(r.avgLatencyMs), num6: num(r.relationsCreated.similar), num7: num(r.relationsCreated.possible_conflict), num8: num(r.relationsCreated.duplicate_of), pct: pct(r.disagreements.kindRate), pct2: pct(r.disagreements.importanceRate), num9: num(r.tokensIn), money: money(r.costUsd), num10: num(r.coverageAfter.judged) })} ${num(r.coverageAfter.total)}` : '', 'var(--s-darker)');
|
|
778
|
+
if (running || paused) startTimer('backfill', 2000, pollBackfill); else stopTimer('backfill');
|
|
779
|
+
}
|
|
780
|
+
async function pollBackfill() {
|
|
781
|
+
if (!tabActive()) return;
|
|
782
|
+
const r = await jget('/api/typesafe/backfill/status');
|
|
783
|
+
if (r.ok) { applyBackfill(r.backfill); if (['done', 'cancelled'].includes(r.backfill.status)) loadConfig(); }
|
|
784
|
+
}
|
|
785
|
+
const bfInputs = () => ({ project: $('jv-bf-project').value.trim() || null, limit: $('jv-bf-limit').value ? Number($('jv-bf-limit').value) : null });
|
|
786
|
+
async function bfAction(action, extra = {}) {
|
|
787
|
+
const r = await jpost('/api/typesafe/backfill', { action, ...bfInputs(), ...extra });
|
|
788
|
+
if (r.ok === false) { toast(kit.tx('settings.redesign.judgments.errBackfill', { error: r.error })); return null; }
|
|
789
|
+
applyBackfill(r.backfill);
|
|
790
|
+
return r.backfill;
|
|
791
|
+
}
|
|
792
|
+
$('jv-bf-estimate').addEventListener('click', async () => { $('jv-bf-estimate').disabled = true; const b = await bfAction('estimate'); state.estimateFor = b ? bfInputs() : null; $('jv-bf-estimate').disabled = false; if (b) applyBackfill(b); });
|
|
793
|
+
for (const id of ['jv-bf-project', 'jv-bf-limit']) $(id).addEventListener('input', () => { state.armed.start = false; if (state.backfill) applyBackfill(state.backfill); });
|
|
794
|
+
$('jv-bf-start').addEventListener('click', async () => {
|
|
795
|
+
if (!state.armed.start) { state.armed.start = true; applyBackfill(state.backfill); setTimeout(() => { state.armed.start = false; if (state.backfill) applyBackfill(state.backfill); }, 8000); return; }
|
|
796
|
+
state.armed.start = false;
|
|
797
|
+
const b = await bfAction('start', { confirm: true });
|
|
798
|
+
if (b) toast(kit.tx('settings.redesign.judgments.backfillStarted'));
|
|
799
|
+
});
|
|
800
|
+
$('jv-bf-pause').addEventListener('click', () => bfAction('pause'));
|
|
801
|
+
$('jv-bf-resume').addEventListener('click', () => bfAction('resume'));
|
|
802
|
+
$('jv-bf-cancel').addEventListener('click', async () => {
|
|
803
|
+
const btn = $('jv-bf-cancel');
|
|
804
|
+
if (!state.armed.cancel) { state.armed.cancel = true; btn.textContent = kit.tx('settings.redesign.judgments.confirmCancel'); setTimeout(() => { state.armed.cancel = false; btn.textContent = kit.tx('settings.redesign.judgments.cancel'); }, 5000); return; }
|
|
805
|
+
state.armed.cancel = false; btn.textContent = kit.tx('settings.redesign.judgments.cancel');
|
|
806
|
+
await bfAction('cancel');
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
// ── Bench ──
|
|
810
|
+
function benchTable(report) {
|
|
811
|
+
const rows = report.disagreements || [];
|
|
812
|
+
const table = $('jv-bench-table');
|
|
813
|
+
if (!rows.length) { table.innerHTML = '<tr><td class="settings-hint">' + kit.te('settings.redesign.judgments.noDisagreementsInThisSample') + '</td></tr>'; return; }
|
|
814
|
+
const cols = ['id', 'stored', 'judged', 'confidence', 'category', 'note'].filter(c => rows.some(r => r[c] != null));
|
|
815
|
+
table.innerHTML = `<thead><tr>${cols.map(c => `<th>${c}</th>`).join('')}</tr></thead><tbody>${rows.map(r => `<tr>${cols.map(c => `<td style="font-family:monospace;font-size:11px">${escapeHtml(c === 'confidence' ? pct(r[c]) : String(r[c] ?? '').slice(0, 80))}</td>`).join('')}</tr>`).join('')}</tbody>`;
|
|
816
|
+
}
|
|
817
|
+
$('jv-bench-run').addEventListener('click', async () => {
|
|
818
|
+
const btn = $('jv-bench-run'); btn.disabled = true; $('jv-bench-spinner').style.display = 'inline';
|
|
819
|
+
const surface = $('jv-bench-surface').value;
|
|
820
|
+
const r = await jpost('/api/typesafe/bench', { surface, limit: Number($('jv-bench-limit').value) || 50, project: $('jv-bench-project').value.trim() || undefined });
|
|
821
|
+
btn.disabled = false; $('jv-bench-spinner').style.display = 'none';
|
|
822
|
+
if (r.ok === false) { toast(kit.tx('settings.redesign.judgments.errBench', { error: r.error })); return; }
|
|
823
|
+
const rep = r.report;
|
|
824
|
+
const a = rep.agreement || {};
|
|
825
|
+
const lines = [];
|
|
826
|
+
if (surface === 'browser') {
|
|
827
|
+
const rate = (x) => (x && x.value != null ? `${(x.value * 100).toFixed(1)}% (${x.numerator}/${x.of})` : 'n/a');
|
|
828
|
+
const t = rep.target, p = rep.pageState, so = rep.social, g = rep.gates || {};
|
|
829
|
+
if (t) lines.push(kit.tx('settings.redesign.judgments.targetTop1PrecisionAbstentionAuto', { rate: rate(t.top1), rate2: rate(t.precision), rate3: rate(t.abstention), rate4: rate(t.eligiblePrecision), rate5: rate(t.coverage), num: num(t.unsafeSelections), num2: num(t.forbiddenAutoExecutable) }));
|
|
830
|
+
if (p) lines.push(kit.tx('settings.redesign.judgments.pageStateMacroF1BlockerRecall', { macroF1: p.macroF1 == null ? 'n/a' : (p.macroF1 * 100).toFixed(1) + '%', rate: rate(p.blockerRecall), num: num(p.authAsUsable) }));
|
|
831
|
+
if (so) lines.push(kit.tx('settings.redesign.judgments.socialStateControlUnsafe', { rate: rate(so.stateAccuracy), rate2: rate(so.candidateAccuracy), num: num(so.unsafeSelections) }));
|
|
832
|
+
lines.push(kit.tx('settings.redesign.judgments.autoHealGatePageStateAdvice', { passed: g.autoHeal?.passed ? kit.tx('settings.redesign.judgments.passed') : kit.tx('settings.redesign.judgments.notPassed', { failed: (g.autoHeal?.failed || []).join(', ') }), passed2: g.pageStateAdvisory?.passed ? kit.tx('settings.redesign.judgments.passed') : kit.tx('settings.redesign.judgments.notPassed', { failed: (g.pageStateAdvisory?.failed || []).join(', ') }) }));
|
|
833
|
+
lines.push(kit.tx('settings.redesign.judgments.benchLatency', { median: num(rep.latency?.medianMs), p95: num(rep.latency?.p95Ms), recorded: r.recorded?.recorded ? kit.tx('settings.redesign.judgments.recordedAsThisConfigurationSBenchmark') : kit.tx('settings.redesign.judgments.notRecorded', { reason: r.recorded?.reason || kit.tx('settings.redesign.judgments.unknown') }) }));
|
|
834
|
+
}
|
|
835
|
+
if (surface === 'desktop') {
|
|
836
|
+
const rate = (x) => (x && x.value != null ? `${(x.value * 100).toFixed(1)}% (${x.numerator}/${x.of})` : 'n/a');
|
|
837
|
+
const t = rep.target, g = rep.gates || {};
|
|
838
|
+
if (t) lines.push(kit.tx('settings.redesign.judgments.desktopTop1AdvisedPrecisionAbstention', { rate: rate(t.top1), rate2: rate(t.precision), rate3: rate(t.abstention), rate4: rate(t.eligiblePrecision), rate5: rate(t.coverage), num: num(t.unsafePresses), num2: num(t.forbiddenPresses) }));
|
|
839
|
+
lines.push(kit.tx('settings.redesign.judgments.pressByIntentGate', { passed: g.press?.passed ? kit.tx('settings.redesign.judgments.passed') : kit.tx('settings.redesign.judgments.notPassed', { failed: (g.press?.failed || []).join(', ') }) }));
|
|
840
|
+
lines.push(kit.tx('settings.redesign.judgments.benchLatency', { median: num(rep.latency?.medianMs), p95: num(rep.latency?.p95Ms), recorded: r.recorded?.recorded ? kit.tx('settings.redesign.judgments.recordedAsThisConfigurationSBenchmark') : kit.tx('settings.redesign.judgments.notRecorded', { reason: r.recorded?.reason || kit.tx('settings.redesign.judgments.unknown') }) }));
|
|
841
|
+
}
|
|
842
|
+
if (a.importance) lines.push(kit.tx('settings.redesign.judgments.importanceMeanWithin1PointWithin', { meanAbsDelta: a.importance.meanAbsDelta, within1: a.importance.within1, of: a.importance.of, within2: a.importance.within2, of2: a.importance.of }));
|
|
843
|
+
if (a.kind) lines.push(kit.tx('settings.redesign.judgments.kindAgree', { agree: a.kind.agree, of: a.kind.of, pct: pct(a.kind.rate) }));
|
|
844
|
+
if (a.relation) lines.push(kit.tx('settings.redesign.judgments.relationsAgree', { agree: a.relation.agree, of: a.relation.of, pct: pct(a.relation.rate) }));
|
|
845
|
+
if (a.historical) lines.push(kit.tx('settings.redesign.judgments.historicalAgree', { agree: a.historical.agree, of: a.historical.of, pct: pct(a.historical.rate) }));
|
|
846
|
+
$('jv-bench-summary').innerHTML = `<strong>${escapeHtml(surface)}</strong> ${kit.th('settings.redesign.judgments.itemsJudged', { num: num(rep.n), num2: num(rep.judged), unavailable: rep.unavailable ? (" " + kit.th('settings.redesign.judgments.unavailable2', { num: num(rep.unavailable) })) : '' })} ${lines.map(escapeHtml).join(' · ')}<br>${num(rep.tokens.input)} ${kit.th('settings.redesign.judgments.tokensInAvgPerItemAvg', { num: num(rep.tokens.avgInputPerItem), num2: num(rep.latency.avgMs) })} ${money(rep.cost)}${r.file ? ` · <code>${escapeHtml(r.file.split('/').slice(-2).join('/'))}</code>` : ''}`;
|
|
847
|
+
benchTable(rep);
|
|
848
|
+
show($('jv-bench-result'), $('jv-bench-result').innerHTML, 'var(--s-darker)');
|
|
849
|
+
toast(kit.tx('settings.redesign.judgments.benchDone', { surface, judged: num(rep.judged) }));
|
|
850
|
+
loadConfig();
|
|
851
|
+
});
|
|
852
|
+
$('jv-ba-autoheal').addEventListener('change', () => putConfig({ browserAssist: { autoHealEnabled: $('jv-ba-autoheal').checked } },
|
|
853
|
+
$('jv-ba-autoheal').checked ? kit.tx('settings.redesign.judgments.safeAutoHealIsOnOne') : kit.tx('settings.redesign.judgments.safeAutoHealIsOffAdvice')));
|
|
854
|
+
$('jv-da-press').addEventListener('change', () => putConfig({ desktopAssist: { pressEnabled: $('jv-da-press').checked } },
|
|
855
|
+
$('jv-da-press').checked ? kit.tx('settings.redesign.judgments.pressByIntentIsOnOne') : kit.tx('settings.redesign.judgments.pressByIntentIsOffAdvice')));
|
|
856
|
+
$('jv-apply-importance').addEventListener('change', () => putConfig({ applyJudgedImportance: $('jv-apply-importance').checked }, $('jv-apply-importance').checked ? kit.tx('settings.redesign.judgments.judgedImportanceWillBeAppliedBy') : kit.tx('settings.redesign.judgments.judgedImportanceStaysRecordedOnly')));
|
|
857
|
+
|
|
858
|
+
// ── Judgment log ──
|
|
859
|
+
function logRow(row) {
|
|
860
|
+
const answers = typeof row.answers === 'string' ? row.answers : JSON.stringify(row.answers, null, 2);
|
|
861
|
+
const riders = Array.isArray(row.surfaces) ? row.surfaces.filter(x => x && x !== row.surface) : [];
|
|
862
|
+
const outcome = row.outcome && typeof row.outcome === 'object' ? row.outcome : null;
|
|
863
|
+
const summary = `${clock(row.created_at)} · <code>${escapeHtml(row.surface)}</code>${riders.map(x => ` <span style="${CHIP}">+${escapeHtml(x)}</span>`).join('')} ${kit.th('settings.redesign.judgments.qMs', { origin: escapeHtml(row.origin), model: escapeHtml(row.model || ''), num: num(row.question_count), num2: num(row.latency_ms), num3: num(row.input_tokens) })}${num(row.output_tokens)}${row.cached ? ' · <span style="color:var(--accent)">' + kit.te('settings.redesign.judgments.cached') + '</span>' : ''}${row.error ? ` · <span style="color:#f66">${escapeHtml(row.error)}</span>` : ''}${row.entity_id ? ` · ${memLink(row.entity_id)}` : ''}${row.session_id ? ` · <a href="#" class="jv-session-link" data-session="${attr(row.session_id)}" title="${attr(row.session_id)}${kit.te('settings.redesign.judgments.thisSessionSJudgments')}" style="${LINK};font-family:monospace">${kit.te('settings.redesign.judgments.session')} ${escapeHtml(shortId(row.session_id))}</a>` : ''}${row.project ? ` · ${escapeHtml(row.project)}` : ''}`;
|
|
864
|
+
return `<details class="jv-log-row" data-id="${attr(row.id)}"${state.openLogIds.has(String(row.id)) ? ' open' : ''} style="font-size:12px;border:1px solid var(--s-medium);border-radius:6px;padding:4px 8px;background:var(--s-darker)">
|
|
865
|
+
<summary style="cursor:pointer;list-style:none" title="${attr(row.created_at)}">${summary}</summary>
|
|
866
|
+
<div class="settings-hint" style="margin:6px 0 2px">${kit.te('settings.redesign.judgments.state')}</div><pre style="margin:0;white-space:pre-wrap;font-size:11px;max-height:160px;overflow:auto">${escapeHtml(row.state_preview || '')}</pre>
|
|
867
|
+
<div class="settings-hint" style="margin:6px 0 2px">${kit.te('settings.redesign.judgments.answers')}</div><pre style="margin:0;white-space:pre-wrap;font-size:11px;max-height:200px;overflow:auto">${escapeHtml(answers || '—')}</pre>
|
|
868
|
+
${outcome ? `<div class="settings-hint" style="margin:6px 0 2px">${kit.te('settings.redesign.judgments.outcome')}</div><pre style="${PRE}">${escapeHtml(JSON.stringify(outcome, null, 2))}</pre>` : ''}
|
|
869
|
+
</details>`;
|
|
870
|
+
}
|
|
871
|
+
async function refreshLog(force = false) {
|
|
872
|
+
if (!alive()) return;
|
|
873
|
+
const filter = { surface: $('jv-log-surface').value, origin: $('jv-log-origin').value, limit: $('jv-log-limit').value,
|
|
874
|
+
session: $('jv-log-session').value.trim(), entity: $('jv-log-entity').value.trim(), project: $('jv-log-project').value.trim() };
|
|
875
|
+
storage.setItem(LOG_FILTER_KEY, JSON.stringify(filter));
|
|
876
|
+
const qs = new URLSearchParams({ limit: filter.limit }); if (filter.surface) qs.set('surface', filter.surface); if (filter.origin) qs.set('origin', filter.origin);
|
|
877
|
+
if (filter.entity) qs.set('entity', filter.entity);
|
|
878
|
+
// An older server ignores session and project, so they are neither shown nor sent to it.
|
|
879
|
+
if (serverV2(state.cfg)) { if (filter.session) qs.set('session', filter.session); if (filter.project) qs.set('project', filter.project); }
|
|
880
|
+
const r = await jget(`/api/typesafe/log?${qs}`);
|
|
881
|
+
if (r.ok === false) { setText($('jv-log-status'), r.error || 'unavailable'); return; }
|
|
882
|
+
const signature = `${JSON.stringify(filter)}:${r.rows.length}:${r.rows[0]?.id ?? ''}`;
|
|
883
|
+
setText($('jv-log-status'), kit.tx('settings.redesign.judgments.logRowsOf', { shown: num(r.rows.length), total: num(r.total) }));
|
|
884
|
+
setText($('jv-log-badge'), kit.tx('settings.redesign.judgments.logRows', { total: num(r.total) }));
|
|
885
|
+
if (!force && signature === state.lastLogSignature) return;
|
|
886
|
+
state.lastLogSignature = signature;
|
|
887
|
+
const list = $('jv-log-list');
|
|
888
|
+
list.innerHTML = r.rows.length ? r.rows.map(logRow).join('') : '<div class="settings-hint">' + kit.te('settings.redesign.judgments.noJudgmentsLoggedYet') + '</div>';
|
|
889
|
+
}
|
|
890
|
+
$('jv-log-list').addEventListener('toggle', (e) => { const d = e.target; if (d?.classList?.contains('jv-log-row')) { if (d.open) state.openLogIds.add(d.dataset.id); else state.openLogIds.delete(d.dataset.id); } }, true);
|
|
891
|
+
$('jv-log-refresh').addEventListener('click', () => refreshLog(true));
|
|
892
|
+
for (const id of ['jv-log-surface', 'jv-log-origin', 'jv-log-limit']) $(id).addEventListener('change', () => refreshLog(true));
|
|
893
|
+
const typedLogFilter = debounce(() => refreshLog(true), 500);
|
|
894
|
+
for (const id of ['jv-log-session', 'jv-log-entity', 'jv-log-project']) {
|
|
895
|
+
$(id).addEventListener('input', typedLogFilter);
|
|
896
|
+
$(id).addEventListener('change', () => { typedLogFilter.cancel(); refreshLog(true); });
|
|
897
|
+
}
|
|
898
|
+
overlay.addEventListener('settings-close', () => typedLogFilter.cancel());
|
|
899
|
+
/** Session and project filters exist only where the server can apply them; origins come from the server's list. */
|
|
900
|
+
function syncLogFilters(cfg) {
|
|
901
|
+
const v2 = serverV2(cfg);
|
|
902
|
+
for (const id of ['jv-log-session', 'jv-log-project']) $(id).style.display = v2 ? '' : 'none';
|
|
903
|
+
const origin = $('jv-log-origin');
|
|
904
|
+
const want = Array.isArray(cfg.origins) ? cfg.origins.filter(o => typeof o === 'string' && o) : [];
|
|
905
|
+
if (!want.length || document.activeElement === origin) return;
|
|
906
|
+
if (Array.from(origin.options, o => o.value).filter(Boolean).join('|') === want.join('|')) return;
|
|
907
|
+
const value = origin.value;
|
|
908
|
+
// A select is as wide as its longest option, so the note on "live" goes in its tooltip.
|
|
909
|
+
origin.innerHTML = '<option value="">' + kit.te('settings.redesign.judgments.allOrigins') + '</option>' + want.map(o => o === 'live'
|
|
910
|
+
? '<option value="live" title="' + kit.te('settings.redesign.judgments.everyOriginExceptBackfillAndBench') + '">' + kit.te('settings.redesign.judgments.liveRealTime') + '</option>'
|
|
911
|
+
: `<option value="${attr(o)}">${escapeHtml(o)}</option>`).join('');
|
|
912
|
+
origin.value = want.includes(value) ? value : '';
|
|
913
|
+
}
|
|
914
|
+
/** Point the log at one memory or one session, clearing the other filters, and bring it into view. */
|
|
915
|
+
function filterLogBy({ entity = '', session = '' }) {
|
|
916
|
+
for (const [id, value] of [['jv-log-surface', ''], ['jv-log-origin', ''], ['jv-log-project', ''], ['jv-log-entity', entity], ['jv-log-session', session]]) $(id).value = value;
|
|
917
|
+
const sec = $('jv-sec-log');
|
|
918
|
+
if (sec.classList.contains('collapsed')) sec.classList.remove('collapsed'); // the expand observer refreshes it
|
|
919
|
+
else refreshLog(true);
|
|
920
|
+
sec.scrollIntoView?.({ block: 'start', behavior: 'smooth' });
|
|
921
|
+
}
|
|
922
|
+
// Memory ids and session ids anywhere in the tab (timeline, log, supersessions) filter the log.
|
|
923
|
+
tabBody.addEventListener('click', (e) => {
|
|
924
|
+
const link = e.target.closest?.('a.jv-entity, a.jv-session-link');
|
|
925
|
+
if (!link) return;
|
|
926
|
+
e.preventDefault();
|
|
927
|
+
if (link.classList.contains('jv-entity')) filterLogBy({ entity: link.dataset.entity || '' });
|
|
928
|
+
else filterLogBy({ session: link.dataset.session || '' });
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
// ── Misfiled ──
|
|
932
|
+
async function refreshMisfiled() {
|
|
933
|
+
if (!alive()) return;
|
|
934
|
+
const r = await jget('/api/typesafe/category-checks?limit=50');
|
|
935
|
+
const list = $('jv-misfiled-list');
|
|
936
|
+
if (r.ok === false) { list.innerHTML = `<div class="settings-hint">${escapeHtml(r.error || kit.tx('settings.redesign.judgments.unavailable'))}</div>`; return; }
|
|
937
|
+
setText($('jv-misfiled-badge'), `${num(r.total)}`);
|
|
938
|
+
list.innerHTML = r.rows.length ? r.rows.map(row => `<div style="display:flex;gap:8px;align-items:flex-start;padding:8px 10px;border:1px solid var(--s-medium);border-radius:8px;background:var(--s-darker);font-size:12px">
|
|
939
|
+
<div style="flex:1;min-width:0"><div><code>${escapeHtml(row.category)}</code> → <code>${escapeHtml(row.category_judged)}</code> <span style="color:var(--t-muted)">(${pct(row.category_confidence)} · ${escapeHtml(row.project)} · ${escapeHtml(String(row.id).slice(0, 8))})</span></div><div class="settings-hint" style="margin:4px 0 0;white-space:pre-wrap">${escapeHtml(row.preview || '')}</div></div>
|
|
940
|
+
<button class="conn-add-btn jv-mf-apply" data-id="${attr(row.id)}" style="${btnStyle}">${kit.te('settings.redesign.judgments.apply')}</button><button class="conn-add-btn jv-mf-dismiss" data-id="${attr(row.id)}" style="${btnStyle}">${kit.te('settings.redesign.judgments.dismiss')}</button>
|
|
941
|
+
</div>`).join('') : '<div class="settings-hint">' + kit.te('settings.redesign.judgments.noDisagreementsRecordedNewWritesWill') + '</div>';
|
|
942
|
+
}
|
|
943
|
+
$('jv-misfiled-list').addEventListener('click', async (e) => {
|
|
944
|
+
const btn = e.target.closest('button[data-id]'); if (!btn) return;
|
|
945
|
+
const action = btn.classList.contains('jv-mf-apply') ? 'apply' : 'dismiss';
|
|
946
|
+
btn.disabled = true;
|
|
947
|
+
const r = await jpost(`/api/typesafe/category-checks/${encodeURIComponent(btn.dataset.id)}`, { action });
|
|
948
|
+
if (r.ok === false) { toast(kit.tx('settings.redesign.judgments.categoryCheck', { error: r.error })); btn.disabled = false; return; }
|
|
949
|
+
toast(action === 'apply' ? kit.tx('settings.redesign.judgments.memoryMoved') : kit.tx('settings.redesign.judgments.dismissed'));
|
|
950
|
+
refreshMisfiled();
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
// An endpoint this server does not have: a 404, or a 2xx that is not the JSON asked for (an SPA fallback, an empty object).
|
|
954
|
+
const missingEndpoint = (r) => r.status === 404 || (r.status >= 200 && r.status < 300);
|
|
955
|
+
|
|
956
|
+
// ── Coding sessions ──
|
|
957
|
+
// One card per Claude Code session (GET /api/typesafe/sessions). Opening a card reads that
|
|
958
|
+
// session's rows oldest first (GET /api/typesafe/log?session=…&order=asc) and gives each
|
|
959
|
+
// surface its own line. Hidden on servers that predate session attribution.
|
|
960
|
+
const knob = (surface, key, fallback) => { const v = state.cfg?.surfaces?.[surface]?.[key]; return fin(v) ? Number(v) : fallback; };
|
|
961
|
+
const flagged = (html, on) => (on ? `<strong style="color:#ffc107">${html}</strong>` : html);
|
|
962
|
+
const idList = (list) => (Array.isArray(list) ? list : []).map(x => (x && typeof x === 'object' ? x.id : x)).filter(x => x != null && x !== '').map(String);
|
|
963
|
+
// Rider answers on the prompt turn: [answer key, label, the rider's surface, its default bar].
|
|
964
|
+
const PROMPT_RIDERS = [['new_task', kit.tx('settings.redesign.judgments.newTask'), 'task-boundary', 0.6], ['past_session', kit.tx('settings.redesign.judgments.pastSession'), 'session-lookup', 0.7], ['reveals_preference', 'preference', 'user-learning', 0.7]];
|
|
965
|
+
const STOP_ANSWERS = [
|
|
966
|
+
['human_blocker', kit.tx('settings.redesign.judgments.blockedOnAHuman'), () => 0.5], ['waiting_for_user', kit.tx('settings.redesign.judgments.waitingForTheUser'), () => 0.5],
|
|
967
|
+
['worth_remembering', kit.tx('settings.redesign.judgments.worthRemembering'), () => knob('turn-worth', 'minConfidence', 0.35)], ['unsupported_claim', kit.tx('settings.redesign.judgments.unsupportedClaim'), () => knob('claim-check', 'minProbability', 0.9)],
|
|
968
|
+
];
|
|
969
|
+
const levelName = (c) => (typeof c.level === 'string' && c.level ? c.level.split(':')[0] : relevanceName(c.relevance)) || '—';
|
|
970
|
+
function urgencyLine(row, a, o) {
|
|
971
|
+
const parts = [];
|
|
972
|
+
const u = a.urgency;
|
|
973
|
+
if (u && typeof u === 'object' && typeof u.choice === 'string') parts.push(`${kit.te('settings.redesign.judgments.urgency')} <strong>${escapeHtml(u.choice)}</strong> ${pct(u.confidence)}`);
|
|
974
|
+
for (const [key, label, surface, bar] of PROMPT_RIDERS) { const p = prob(a[key]); if (p != null) parts.push(flagged(`${label} ${pct(p)}`, p >= knob(surface, 'minProbability', bar))); }
|
|
975
|
+
// The Assistant's recall gate records what it did with the answer.
|
|
976
|
+
if (o && typeof o.decision === 'string' && o.decision) parts.push(`→ ${escapeHtml(o.decision)}${o.fallback === true ? (" " + kit.tx('settings.redesign.judgments.regexFallback')) : ''}`);
|
|
977
|
+
return { line: parts.join(' · ') };
|
|
978
|
+
}
|
|
979
|
+
function rankLine(row, a, o) {
|
|
980
|
+
if (!o || !Array.isArray(o.candidates)) return { line: '' };
|
|
981
|
+
const injected = new Set(idList(o.injected)), dropped = new Set(idList(o.dropped));
|
|
982
|
+
const rel = (c) => (fin(c.relevance) ? Number(c.relevance) : -1);
|
|
983
|
+
const candidates = o.candidates.filter(c => c && typeof c === 'object').sort((x, y) => rel(y) - rel(x));
|
|
984
|
+
const fate = (id) => injected.has(id) ? '<span style="color:var(--accent)">' + kit.te('settings.redesign.judgments.injected') + '</span>' : dropped.has(id) ? '<span style="color:#ffc107">' + kit.te('settings.redesign.judgments.dropped') + '</span>' : '<span style="color:var(--t-muted)">' + kit.te('settings.redesign.judgments.notInjected') + '</span>';
|
|
985
|
+
const detail = candidates.length ? `<div class="settings-hint" style="margin:6px 0 2px">${num(candidates.length)} ${kit.te('settings.redesign.judgments.judgedMostRelevantFirst')}</div><div class="jv-tl-candidates" style="display:flex;flex-direction:column;gap:2px;font-size:11px">${candidates.map(c => `<div>${memLink(c.id)} · ${escapeHtml(levelName(c))}${fin(c.relevance) ? ` ${Number(c.relevance).toFixed(1)}` : ''} · ${fate(String(c.id ?? ''))}</div>`).join('')}</div>` : '';
|
|
986
|
+
// Withheld: the Assistant's urgency judgment declined the turn, so nothing was injected or committed.
|
|
987
|
+
const withheld = typeof o.withheld === 'string' && o.withheld ? (" " + kit.th('settings.redesign.judgments.logWithheld', { reason: escapeHtml(o.withheld) })) : '';
|
|
988
|
+
return { line: kit.th('settings.redesign.judgments.logInjected', { injected: num(injected.size), dropped: num(dropped.size), floor: fin(o.floor) ? kit.te('settings.redesign.judgments.logFloor', { floor: Number(o.floor).toFixed(1) }) : kit.te('settings.redesign.judgments.noFloor'), withheld }), detail };
|
|
989
|
+
}
|
|
990
|
+
// Assistant workers (worker-outcome, rider worker-claim): what Jev read, and what the dispatcher did with it.
|
|
991
|
+
function workerLine(row, a, o) {
|
|
992
|
+
const parts = [];
|
|
993
|
+
const s = a.status, c = a.cause;
|
|
994
|
+
// A judgment under minConfidence was logged but not applied: say so, so it doesn't read as missing.
|
|
995
|
+
const bar = knob('worker-outcome', 'minConfidence', 0.7);
|
|
996
|
+
const below = (answer, applied) => (applied === false || (applied == null && Number(answer.confidence) < bar)) ? ` (below ${pct(bar)})` : '';
|
|
997
|
+
if (s && typeof s === 'object' && typeof s.choice === 'string') parts.push(`${kit.te('settings.redesign.judgments.status')} <strong>${escapeHtml(s.choice)}</strong> ${pct(s.confidence)}${s.choice === 'unclear' ? '' : below(s, o?.applied?.status)}`);
|
|
998
|
+
if (c && typeof c === 'object' && typeof c.choice === 'string') parts.push(kit.th('settings.redesign.judgments.logCause', { cause: `${escapeHtml(c.choice)} ${pct(c.confidence)}${below(c, o?.applied?.cause)}` }));
|
|
999
|
+
const p = prob(a.unsupported_claim);
|
|
1000
|
+
if (p != null) parts.push(flagged(kit.tx('settings.redesign.judgments.unsupportedClaim2', { pct: pct(p) }), p >= knob('worker-claim', 'minProbability', 0.9)));
|
|
1001
|
+
if (o?.retried === true) parts.push(kit.tx('settings.redesign.judgments.retryTurn'));
|
|
1002
|
+
if (o && typeof o.escalation === 'string' && o.escalation) parts.push(`→ ${escapeHtml(o.escalation)}`);
|
|
1003
|
+
return { line: parts.join(' · ') };
|
|
1004
|
+
}
|
|
1005
|
+
function stopLine(row, a) {
|
|
1006
|
+
const parts = [];
|
|
1007
|
+
for (const [key, label, bar] of STOP_ANSWERS) { const p = prob(a[key]); if (p != null) parts.push(flagged(`${label} ${pct(p)}`, p >= bar())); }
|
|
1008
|
+
return { line: parts.join(' · ') };
|
|
1009
|
+
}
|
|
1010
|
+
function staleLine(row, a, o) {
|
|
1011
|
+
const out = o || {};
|
|
1012
|
+
const p = fin(out.probability) ? Number(out.probability) : prob(a.accurate);
|
|
1013
|
+
const stale = typeof out.stale === 'boolean' ? out.stale : (row.surface === 'edit-stale' && p != null ? p < knob('edit-stale', 'minProbability', 0.4) : null);
|
|
1014
|
+
const file = out.file ? `<span title="${attr(out.file)}" style="font-family:monospace">${escapeHtml(String(out.file).split(/[\\/]/).slice(-3).join('/'))}</span>` : '';
|
|
1015
|
+
return { line: [file, row.entity_id ? kit.th('settings.redesign.judgments.logMemory', { memory: memLink(row.entity_id) }) : '', p != null ? kit.tx('settings.redesign.judgments.pStillAccurate', { pct: pct(p) }) : '', stale == null ? '' : stale ? flagged('stale', true) : kit.tx('settings.redesign.judgments.notStale')].filter(Boolean).join(' · ') };
|
|
1016
|
+
}
|
|
1017
|
+
function planLine(row, a, o) {
|
|
1018
|
+
if (!o) return { line: '' };
|
|
1019
|
+
const conflicts = idList(o.conflicts);
|
|
1020
|
+
const checked = fin(o.checked) ? (" " + kit.tx('settings.redesign.judgments.logOfChecked', { checked: num(o.checked) })) : '';
|
|
1021
|
+
return { line: conflicts.length ? `${flagged(kit.tx(conflicts.length === 1 ? 'settings.redesign.judgments.logConflicts.one' : 'settings.redesign.judgments.logConflicts.other', { count: num(conflicts.length) }), true)}${checked}: ${conflicts.map(memLink).join(', ')}` : kit.tx('settings.redesign.judgments.noConflicts', { checked: checked }) };
|
|
1022
|
+
}
|
|
1023
|
+
function digestLine(row, a, o) {
|
|
1024
|
+
if (!o) return { line: '' };
|
|
1025
|
+
const picked = Array.isArray(o.picked) ? o.picked.length : o.picked;
|
|
1026
|
+
return { line: kit.tx('settings.redesign.judgments.logPicked', { picked: fin(picked) ? num(picked) : '—', of: fin(o.of) ? num(o.of) : '—' }) };
|
|
1027
|
+
}
|
|
1028
|
+
function loopLine(row, a) {
|
|
1029
|
+
const p = prob(a.goal_met);
|
|
1030
|
+
return { line: p == null ? '' : flagged(kit.tx('settings.redesign.judgments.pGoalMet', { pct: pct(p) }), p >= knob('loop-goal', 'minConfidence', 0.8)) };
|
|
1031
|
+
}
|
|
1032
|
+
const TIMELINE = {
|
|
1033
|
+
'prompt-urgency': urgencyLine, 'rerank': rankLine, 'brief-rank': rankLine,
|
|
1034
|
+
'agent-message': stopLine, 'turn-worth': stopLine, 'claim-check': stopLine,
|
|
1035
|
+
'edit-stale': staleLine, 'stale-check': staleLine, 'plan-conflict': planLine, 'compact-digest': digestLine, 'loop-goal': loopLine,
|
|
1036
|
+
'worker-outcome': workerLine, 'worker-claim': workerLine,
|
|
1037
|
+
};
|
|
1038
|
+
const SHOWS_ENTITY = new Set(['edit-stale', 'stale-check']);
|
|
1039
|
+
// Rows whose entity is an Assistant run id, not a memory.
|
|
1040
|
+
const RUN_ENTITY = new Set(['worker-outcome', 'worker-claim']);
|
|
1041
|
+
function timelineRow(row) {
|
|
1042
|
+
const a = row.answers && typeof row.answers === 'object' ? row.answers : {};
|
|
1043
|
+
const o = row.outcome && typeof row.outcome === 'object' ? row.outcome : null;
|
|
1044
|
+
let view = { line: '' };
|
|
1045
|
+
const format = Object.prototype.hasOwnProperty.call(TIMELINE, row.surface) ? TIMELINE[row.surface] : null;
|
|
1046
|
+
try { view = format?.(row, a, o) || view; } catch { view = { line: '' }; }
|
|
1047
|
+
// Anything without a formatter, or with nothing to show, gets the compact line.
|
|
1048
|
+
const line = view.line || (row.error ? kit.tx('settings.redesign.judgments.noAnswer') : `q×${num(row.question_count)}`);
|
|
1049
|
+
const riders = Array.isArray(row.surfaces) ? row.surfaces.filter(x => x && x !== row.surface) : [];
|
|
1050
|
+
const meta = [`${num(row.latency_ms)} ms`, row.cached ? '<span style="color:var(--accent)">' + kit.te('settings.redesign.judgments.cached') + '</span>' : '', row.error ? `<span style="color:#f66">${escapeHtml(row.error)}</span>` : '',
|
|
1051
|
+
row.entity_id && !SHOWS_ENTITY.has(row.surface) ? (RUN_ENTITY.has(row.surface) ? `${kit.te('settings.redesign.judgments.run')} <code title="${attr(row.entity_id)}">${escapeHtml(shortId(row.entity_id))}</code>` : kit.th('settings.redesign.judgments.logMemory', { memory: memLink(row.entity_id) })) : '', row.origin ? escapeHtml(row.origin) : ''].filter(Boolean).join(' · ');
|
|
1052
|
+
const answers = typeof row.answers === 'string' ? row.answers : JSON.stringify(row.answers ?? null, null, 2);
|
|
1053
|
+
return `<details class="jv-tl-row" data-id="${attr(row.id)}" data-surface="${attr(row.surface)}"${state.openTimelineIds.has(String(row.id)) ? ' open' : ''} style="font-size:12px;border:1px solid var(--s-medium);border-radius:6px;padding:3px 8px;background:var(--s-darker)">
|
|
1054
|
+
<summary style="cursor:pointer;list-style:none" title="${attr(row.created_at)}">${clock(row.created_at)} · <code>${escapeHtml(row.surface)}</code>${riders.map(x => ` <span style="${CHIP}">+${escapeHtml(x)}</span>`).join('')} · <span class="jv-tl-line">${line}</span> <span style="color:var(--t-muted)">· ${meta}</span></summary>
|
|
1055
|
+
${view.detail || ''}
|
|
1056
|
+
<div class="settings-hint" style="margin:6px 0 2px">${kit.te('settings.redesign.judgments.state')}</div><pre style="${PRE}">${escapeHtml(row.state_preview || '')}</pre>
|
|
1057
|
+
<div class="settings-hint" style="margin:6px 0 2px">${kit.te('settings.redesign.judgments.answers')}</div><pre style="${PRE}">${escapeHtml(answers || '—')}</pre>
|
|
1058
|
+
${o ? `<div class="settings-hint" style="margin:6px 0 2px">${kit.te('settings.redesign.judgments.outcome')}</div><pre style="${PRE}">${escapeHtml(JSON.stringify(o, null, 2))}</pre>` : ''}
|
|
1059
|
+
</details>`;
|
|
1060
|
+
}
|
|
1061
|
+
function timelineHtml(sessionId, rows) {
|
|
1062
|
+
if (!rows.length) return '<div class="settings-hint">' + kit.te('settings.redesign.judgments.noJudgmentsLoggedForThisSession') + '</div>';
|
|
1063
|
+
return `<div class="settings-hint" style="margin:0 0 6px">${num(rows.length)} ${kit.th('settings.redesign.judgments.judgmentOldestFirst', { count: rows.length === 1 ? '' : 's', count2: rows.length >= TIMELINE_LIMIT ? (" " + kit.th('settings.redesign.judgments.theFirst', { num: num(TIMELINE_LIMIT) })) : '' })} <a href="#" class="jv-session-link" data-session="${attr(sessionId)}" style="${LINK}">${kit.te('settings.redesign.judgments.openInTheJudgmentLog')}</a></div>
|
|
1064
|
+
<div style="display:flex;flex-direction:column;gap:3px">${rows.map(timelineRow).join('')}</div>`;
|
|
1065
|
+
}
|
|
1066
|
+
const sessionKey = (s) => (s ? `${s.calls}:${s.last_at}` : '');
|
|
1067
|
+
// Assistant sessions log as assistant-<uuid>: show the part that tells them apart.
|
|
1068
|
+
const sessionLabel = (id) => (/^assistant-/.test(String(id ?? '')) ? kit.tx('settings.redesign.judgments.assistantSession', { id: String(id).slice(10, 18) }) : shortId(id));
|
|
1069
|
+
const sessionCardEl = (id) => Array.from($('jv-sessions-list').querySelectorAll('details.jv-sess')).find(d => d.dataset.session === id) || null;
|
|
1070
|
+
function sessionCard(s) {
|
|
1071
|
+
const id = String(s.session_id ?? '');
|
|
1072
|
+
const first = Date.parse(s.first_at), last = Date.parse(s.last_at);
|
|
1073
|
+
const sameDay = fin(first) && fin(last) && new Date(first).toDateString() === new Date(last).toDateString();
|
|
1074
|
+
const lastText = sameDay ? new Date(last).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : when(s.last_at);
|
|
1075
|
+
const span = fin(first) && fin(last) && last - first >= 1000 ? ` (${duration(last - first)})` : '';
|
|
1076
|
+
const counts = s.surfaces && typeof s.surfaces === 'object' ? Object.entries(s.surfaces).filter(([, n]) => Number(n) > 0).sort((x, y) => Number(y[1]) - Number(x[1])) : [];
|
|
1077
|
+
return `<details class="jv-sess" data-session="${attr(id)}"${state.openSessions.has(id) ? ' open' : ''} style="font-size:12px;border:1px solid var(--s-medium);border-radius:8px;padding:6px 10px;background:var(--s-darker)">
|
|
1078
|
+
<summary style="cursor:pointer" title="${attr(id)}"><code>${escapeHtml(sessionLabel(id) || '—')}</code> ${kit.th('settings.redesign.judgments.judgment', { project: escapeHtml(s.project || kit.tx('settings.redesign.judgments.noProject')), when: escapeHtml(when(s.first_at)), lastText: escapeHtml(lastText), span: escapeHtml(span), num: num(s.calls) })}${Number(s.calls) === 1 ? '' : 's'}${Number(s.failures) ? ` · <span style="color:#f66">${num(s.failures)} ${kit.te('settings.redesign.judgments.failed')}</span>` : ''}
|
|
1079
|
+
<span class="jv-sess-chips" style="display:flex;flex-wrap:wrap;gap:4px;margin:4px 0 0 14px">${counts.map(([name, n]) => `<span style="${CHIP}">${escapeHtml(name)} ${num(n)}</span>`).join('')}</span>
|
|
1080
|
+
</summary>
|
|
1081
|
+
<div class="jv-sess-timeline" style="margin-top:8px">${state.timelineHtml.get(id) || '<div class="settings-hint">' + kit.te('settings.redesign.judgments.loading') + '</div>'}</div>
|
|
1082
|
+
</details>`;
|
|
1083
|
+
}
|
|
1084
|
+
function renderSessionsMeta(cfg) {
|
|
1085
|
+
const sec = $('jv-sec-sessions');
|
|
1086
|
+
const available = serverV2(cfg) && !state.sessionsUnsupported;
|
|
1087
|
+
sec.style.display = available ? '' : 'none';
|
|
1088
|
+
if (available && !state.sessionsBooted && !sec.classList.contains('collapsed')) { state.sessionsBooted = true; refreshSessions(true); }
|
|
1089
|
+
}
|
|
1090
|
+
async function refreshSessions(force = false) {
|
|
1091
|
+
if (!alive()) return;
|
|
1092
|
+
const sec = $('jv-sec-sessions');
|
|
1093
|
+
if (!serverV2(state.cfg) || state.sessionsUnsupported) { sec.style.display = 'none'; return; }
|
|
1094
|
+
state.sessionsBooted = true;
|
|
1095
|
+
const qs = new URLSearchParams({ since: new Date(Date.now() - SESSIONS_DAYS * 864e5).toISOString(), limit: '30' });
|
|
1096
|
+
const r = await jget(`/api/typesafe/sessions?${qs}`);
|
|
1097
|
+
if (!alive()) return;
|
|
1098
|
+
if (!Array.isArray(r.rows)) {
|
|
1099
|
+
if (missingEndpoint(r)) { state.sessionsUnsupported = true; sec.style.display = 'none'; return; }
|
|
1100
|
+
setText($('jv-sessions-status'), r.error || 'unavailable');
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
const rows = r.rows.filter(s => s && typeof s === 'object' && s.session_id != null && s.session_id !== '');
|
|
1104
|
+
state.sessions = new Map(rows.map(s => [String(s.session_id), s]));
|
|
1105
|
+
setText($('jv-sessions-badge'), kit.tx(rows.length === 1 ? 'settings.redesign.judgments.sessionsBadge.one' : 'settings.redesign.judgments.sessionsBadge.other', { count: num(rows.length), days: SESSIONS_DAYS }));
|
|
1106
|
+
setText($('jv-sessions-status'), rows.length ? kit.tx('settings.redesign.judgments.theMostRecentNewestActivityFirst', { num: num(rows.length) }) : '');
|
|
1107
|
+
const signature = rows.map(s => `${s.session_id}:${sessionKey(s)}`).join('|');
|
|
1108
|
+
if (force || signature !== state.sessionsSignature) {
|
|
1109
|
+
state.sessionsSignature = signature;
|
|
1110
|
+
$('jv-sessions-list').innerHTML = rows.length ? rows.map(sessionCard).join('')
|
|
1111
|
+
: `<div class="settings-hint">${kit.th('settings.redesign.judgments.noJudgmentsCarryASessionId', { SESSIONS_DAYS: SESSIONS_DAYS })}</div>`;
|
|
1112
|
+
}
|
|
1113
|
+
// Open timelines follow their session: reload when it gained judgments (or on an explicit refresh).
|
|
1114
|
+
for (const id of state.openSessions) if (state.sessions.has(id) && (force || state.timelineKeys.get(id) !== sessionKey(state.sessions.get(id)))) loadTimeline(id);
|
|
1115
|
+
}
|
|
1116
|
+
async function loadTimeline(id) {
|
|
1117
|
+
if (state.timelineLoading.has(id)) return;
|
|
1118
|
+
state.timelineLoading.add(id);
|
|
1119
|
+
state.timelineKeys.set(id, sessionKey(state.sessions.get(id)));
|
|
1120
|
+
try {
|
|
1121
|
+
const r = await jget(`/api/typesafe/log?${new URLSearchParams({ session: id, order: 'asc', limit: String(TIMELINE_LIMIT) })}`);
|
|
1122
|
+
if (!alive()) return;
|
|
1123
|
+
let html;
|
|
1124
|
+
if (Array.isArray(r.rows)) {
|
|
1125
|
+
// Only this session's rows, oldest first, even from a server that ignores `session` or `order`.
|
|
1126
|
+
const rows = r.rows.filter(row => row && typeof row === 'object' && String(row.session_id ?? '') === id);
|
|
1127
|
+
if (rows.every(row => fin(row.id))) rows.sort((x, y) => Number(x.id) - Number(y.id));
|
|
1128
|
+
html = timelineHtml(id, rows); state.timelineHtml.set(id, html);
|
|
1129
|
+
} else {
|
|
1130
|
+
html = `<div class="settings-hint" style="color:#f66">${escapeHtml(r.error || kit.tx('settings.redesign.judgments.theTimelineIsUnavailable'))}</div>`;
|
|
1131
|
+
state.timelineKeys.delete(id);
|
|
1132
|
+
}
|
|
1133
|
+
const box = sessionCardEl(id)?.querySelector('.jv-sess-timeline');
|
|
1134
|
+
if (box) box.innerHTML = html;
|
|
1135
|
+
} catch (error) {
|
|
1136
|
+
// Called without await (a toggle, a poll): render the failure rather than reject.
|
|
1137
|
+
state.timelineKeys.delete(id);
|
|
1138
|
+
const box = sessionCardEl(id)?.querySelector('.jv-sess-timeline');
|
|
1139
|
+
if (box) box.innerHTML = `<div class="settings-hint" style="color:#f66">${escapeHtml(error?.message || kit.tx('settings.redesign.judgments.theTimelineCouldNotBeDrawn'))}</div>`;
|
|
1140
|
+
} finally { state.timelineLoading.delete(id); }
|
|
1141
|
+
}
|
|
1142
|
+
// <details> toggles do not bubble; capture them. Re-rendered open cards fire one too, which is harmless.
|
|
1143
|
+
$('jv-sessions-list').addEventListener('toggle', (e) => {
|
|
1144
|
+
const d = e.target;
|
|
1145
|
+
if (d?.classList?.contains('jv-tl-row')) { if (d.open) state.openTimelineIds.add(d.dataset.id); else state.openTimelineIds.delete(d.dataset.id); return; }
|
|
1146
|
+
if (!d?.classList?.contains('jv-sess')) return;
|
|
1147
|
+
const id = d.dataset.session;
|
|
1148
|
+
if (!d.open) { state.openSessions.delete(id); return; }
|
|
1149
|
+
state.openSessions.add(id);
|
|
1150
|
+
if (!state.timelineHtml.has(id)) loadTimeline(id);
|
|
1151
|
+
}, true);
|
|
1152
|
+
$('jv-sessions-refresh').addEventListener('click', () => refreshSessions(true));
|
|
1153
|
+
|
|
1154
|
+
// ── Superseded by Jev ──
|
|
1155
|
+
function renderSupersessionsMeta(cfg) {
|
|
1156
|
+
const sec = $('jv-sec-supersessions');
|
|
1157
|
+
const info = cfg.supersessions && typeof cfg.supersessions === 'object' ? cfg.supersessions : null;
|
|
1158
|
+
if (!info || state.supersessionsUnsupported) { sec.style.display = 'none'; return; }
|
|
1159
|
+
sec.style.display = '';
|
|
1160
|
+
setText($('jv-supersessions-badge'), kit.tx('settings.redesign.judgments.supersessionsActive', { count: num(info.active) }));
|
|
1161
|
+
if (!state.supersessionsBooted && !sec.classList.contains('collapsed')) { state.supersessionsBooted = true; refreshSupersessions(); }
|
|
1162
|
+
}
|
|
1163
|
+
function supersessionRow(row) {
|
|
1164
|
+
const side = (label, id, created, preview, dim) => `<div style="min-width:0"><div class="settings-hint" style="margin:0 0 2px">${label} · ${memLink(id)} · ${escapeHtml(day(created))}</div><div style="white-space:pre-wrap;overflow-wrap:anywhere${dim ? ';opacity:.75' : ''}">${escapeHtml(preview || '')}</div></div>`;
|
|
1165
|
+
return `<div class="jv-ss-row" data-id="${attr(row.id)}" style="padding:8px 10px;border:1px solid var(--s-medium);border-radius:8px;background:var(--s-darker);font-size:12px">
|
|
1166
|
+
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">
|
|
1167
|
+
<span style="flex:1;min-width:0"><code>${escapeHtml(row.category || '—')}</code> ${kit.th('settings.redesign.judgments.recorded', { project: escapeHtml(row.project || kit.tx('settings.redesign.judgments.noProject')) })} ${escapeHtml(when(row.created_at))}${row.automatic ? (" " + kit.te('settings.redesign.judgments.byJev')) : ' · <span style="color:var(--accent)">' + kit.te('settings.redesign.judgments.kept') + '</span>'}</span>
|
|
1168
|
+
${row.automatic ? `<button class="conn-add-btn jv-ss-keep" data-id="${attr(row.id)}" style="${btnStyle}">${kit.te('settings.redesign.judgments.keep')}</button>` : ''}<button class="conn-add-btn jv-ss-undo" data-id="${attr(row.id)}" style="${btnStyle}">${kit.te('settings.redesign.judgments.undo')}</button>
|
|
1169
|
+
</div>
|
|
1170
|
+
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:6px">${side(kit.tx('settings.redesign.judgments.newerCurrent'), row.from_id, row.from_created_at, row.from_preview, false)}${side(kit.tx('settings.redesign.judgments.olderOutOfCurrentRecall'), row.to_id, row.to_created_at, row.to_preview, true)}</div>
|
|
1171
|
+
</div>`;
|
|
1172
|
+
}
|
|
1173
|
+
async function refreshSupersessions() {
|
|
1174
|
+
if (!alive()) return;
|
|
1175
|
+
const sec = $('jv-sec-supersessions'), list = $('jv-supersessions-list');
|
|
1176
|
+
if (!state.cfg?.supersessions || state.supersessionsUnsupported) { sec.style.display = 'none'; return; }
|
|
1177
|
+
state.supersessionsBooted = true;
|
|
1178
|
+
const r = await jget('/api/typesafe/supersessions?limit=50');
|
|
1179
|
+
if (!alive()) return;
|
|
1180
|
+
if (!Array.isArray(r.rows)) {
|
|
1181
|
+
if (missingEndpoint(r)) { state.supersessionsUnsupported = true; sec.style.display = 'none'; return; }
|
|
1182
|
+
list.innerHTML = `<div class="settings-hint">${escapeHtml(r.error || kit.tx('settings.redesign.judgments.unavailable'))}</div>`;
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1185
|
+
const rows = r.rows.filter(row => row && typeof row === 'object');
|
|
1186
|
+
setText($('jv-supersessions-status'), rows.length ? kit.tx('settings.redesign.judgments.showingOfNewestFirst', { num: num(rows.length), num2: num(fin(r.total) ? r.total : rows.length) }) : '');
|
|
1187
|
+
list.innerHTML = rows.length ? rows.map(supersessionRow).join('')
|
|
1188
|
+
: '<div class="settings-hint">' + kit.te('settings.redesign.judgments.nothingSupersededWhenMaintenanceRelatesA') + '</div>';
|
|
1189
|
+
}
|
|
1190
|
+
$('jv-supersessions-list').addEventListener('click', async (e) => {
|
|
1191
|
+
const btn = e.target.closest('button.jv-ss-undo, button.jv-ss-keep'); if (!btn) return;
|
|
1192
|
+
const action = btn.classList.contains('jv-ss-undo') ? 'undo' : 'keep';
|
|
1193
|
+
btn.disabled = true;
|
|
1194
|
+
const r = await jpost(`/api/typesafe/supersessions/${encodeURIComponent(btn.dataset.id)}`, { action });
|
|
1195
|
+
if (r.ok === false) { toast(kit.tx('settings.redesign.judgments.errSupersession', { error: r.error || kit.tx('settings.redesign.judgments.failed') })); btn.disabled = false; return; }
|
|
1196
|
+
toast(action === 'undo' ? kit.tx('settings.redesign.judgments.undoneTheOlderMemoryIsBack') : kit.tx('settings.redesign.judgments.keptTheRelationIsConfirmed'));
|
|
1197
|
+
await refreshSupersessions();
|
|
1198
|
+
loadConfig();
|
|
1199
|
+
});
|
|
1200
|
+
|
|
1201
|
+
// ── Trash triage ──
|
|
1202
|
+
// The server streams NDJSON snapshots (?stream=1) so rows show while batches
|
|
1203
|
+
// are still being judged; a plain JSON answer renders the same way.
|
|
1204
|
+
async function streamTriage(url, onSnapshot) {
|
|
1205
|
+
state.triageAbort?.abort();
|
|
1206
|
+
const controller = new AbortController();
|
|
1207
|
+
state.triageAbort = controller;
|
|
1208
|
+
try {
|
|
1209
|
+
const res = await fetch(url, { signal: controller.signal });
|
|
1210
|
+
if (!res.ok || !(res.headers.get('content-type') || '').includes('ndjson') || !res.body?.getReader) return await readJson(res);
|
|
1211
|
+
const reader = res.body.getReader();
|
|
1212
|
+
const decoder = new TextDecoder();
|
|
1213
|
+
let buffer = '';
|
|
1214
|
+
while (true) {
|
|
1215
|
+
const { done, value } = await reader.read();
|
|
1216
|
+
if (done) break;
|
|
1217
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1218
|
+
let idx;
|
|
1219
|
+
while ((idx = buffer.indexOf('\n')) !== -1) {
|
|
1220
|
+
const line = buffer.slice(0, idx).trim();
|
|
1221
|
+
buffer = buffer.slice(idx + 1);
|
|
1222
|
+
if (!line) continue;
|
|
1223
|
+
let payload;
|
|
1224
|
+
try { payload = JSON.parse(line); } catch { continue; }
|
|
1225
|
+
if (payload.done || payload.ok === false) return payload;
|
|
1226
|
+
onSnapshot(payload);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
return { ok: false, error: kit.tx('settings.redesign.judgments.theTriageStreamEndedEarly') };
|
|
1230
|
+
} catch (error) {
|
|
1231
|
+
return { ok: false, error: error?.name === 'AbortError' ? kit.tx('settings.redesign.judgments.cancelled') : (error?.message || kit.tx('settings.redesign.judgments.networkError')), status: 0 };
|
|
1232
|
+
} finally {
|
|
1233
|
+
if (state.triageAbort === controller) state.triageAbort = null;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
function triageRow(row, pending) {
|
|
1237
|
+
const scoreText = row.expendability == null ? (pending ? '…' : '—') : Number(row.expendability).toFixed(1);
|
|
1238
|
+
return `<div data-row="${attr(row.id)}" style="display:flex;gap:8px;align-items:flex-start;padding:8px 10px;border:1px solid var(--s-medium);border-radius:8px;background:var(--s-darker);font-size:12px">
|
|
1239
|
+
<input type="checkbox" class="jv-tr-pick" aria-label="${kit.te('settings.redesign.judgments.name.triagePick')}" data-id="${attr(row.id)}"${state.triageSelected.has(row.id) ? ' checked' : ''} style="margin-top:3px;flex:0 0 auto">
|
|
1240
|
+
<div style="min-width:60px;text-align:center"><div style="font-size:16px;font-weight:700">${escapeHtml(scoreText)}</div><div class="settings-hint" style="margin:0">${escapeHtml(row.level || '')}</div></div>
|
|
1241
|
+
<div style="flex:1;min-width:0"><div><code>${escapeHtml(row.category)}</code> ${kit.th('settings.redesign.judgments.importance2', { project: escapeHtml(row.project), importance: escapeHtml(String(row.importance)) })} ${escapeHtml(row.reasons?.join(', ') || '')}</div><div class="settings-hint" style="margin:4px 0 0;white-space:pre-wrap">${escapeHtml(row.preview || '')}</div></div>
|
|
1242
|
+
<button class="conn-add-btn jv-tr-trash" data-id="${attr(row.id)}" style="${btnStyle}">${kit.te('settings.redesign.judgments.moveToTrash')}</button>
|
|
1243
|
+
</div>`;
|
|
1244
|
+
}
|
|
1245
|
+
/** Renders the last answer: the page of rows, the status line and the selection controls. */
|
|
1246
|
+
function renderTriage(r) {
|
|
1247
|
+
if (r) state.triageLast = r;
|
|
1248
|
+
const answer = state.triageLast;
|
|
1249
|
+
if (!answer) return;
|
|
1250
|
+
const rows = (answer.rows || []).filter(row => !state.triageTrashed.has(row.id));
|
|
1251
|
+
const pending = Number(answer.pending || 0);
|
|
1252
|
+
const shown = pending ? rows.length : Math.min(state.triagePage * TRIAGE_PAGE, rows.length);
|
|
1253
|
+
const unjudged = answer.judged ? rows.filter(row => row.expendability == null).length : 0;
|
|
1254
|
+
setText($('jv-triage-status'), pending
|
|
1255
|
+
? kit.tx('settings.redesign.judgments.judgingOfCandidatesLeft', { num: num(pending), num2: num(answer.candidates) })
|
|
1256
|
+
: kit.tx('settings.redesign.judgments.triageShowing', { shown: num(shown), total: num(rows.length), detail: " " + (answer.judged ? kit.tx('settings.redesign.judgments.triageJudged', { saved: answer.saved ? (" " + kit.tx('settings.redesign.judgments.fromSavedScores', { num: num(answer.saved) })) : '', unjudged: unjudged ? (" " + kit.tx('settings.redesign.judgments.notJudgedThisTime', { num: num(unjudged) })) : '' }) : kit.tx('settings.redesign.judgments.fallbackOrdering')) }));
|
|
1257
|
+
setText($('jv-triage-badge'), `${num(rows.length)}`);
|
|
1258
|
+
$('jv-triage-list').innerHTML = rows.length ? rows.slice(0, shown).map(row => triageRow(row, pending)).join('') : '<div class="settings-hint">' + kit.te('settings.redesign.judgments.noCandidatesFound') + '</div>';
|
|
1259
|
+
const remaining = rows.length - shown;
|
|
1260
|
+
$('jv-triage-more-wrap').style.display = remaining > 0 ? 'block' : 'none';
|
|
1261
|
+
setText($('jv-triage-more'), kit.tx('settings.redesign.judgments.showMoreLeft', { num: num(remaining) }));
|
|
1262
|
+
$('jv-triage-bulk').style.display = rows.length ? 'flex' : 'none';
|
|
1263
|
+
for (const id of [...state.triageSelected]) if (!rows.some(row => row.id === id)) state.triageSelected.delete(id);
|
|
1264
|
+
const picks = Array.from($('jv-triage-list').querySelectorAll('input.jv-tr-pick'));
|
|
1265
|
+
$('jv-triage-all').checked = picks.length > 0 && picks.every(pick => pick.checked);
|
|
1266
|
+
renderTriageSelection();
|
|
1267
|
+
}
|
|
1268
|
+
function renderTriageSelection() {
|
|
1269
|
+
const btn = $('jv-triage-trash-selected');
|
|
1270
|
+
const count = state.triageSelected.size;
|
|
1271
|
+
btn.disabled = count === 0;
|
|
1272
|
+
setText(btn, state.armed.triage && count ? kit.tx('settings.redesign.judgments.triageConfirm', { count: num(count) }) : kit.tx('settings.redesign.judgments.moveToTrash2', { num: num(count) }));
|
|
1273
|
+
}
|
|
1274
|
+
$('jv-triage-run').addEventListener('click', async () => {
|
|
1275
|
+
const btn = $('jv-triage-run'); btn.disabled = true; $('jv-triage-spinner').style.display = 'inline';
|
|
1276
|
+
state.triageTrashed = new Set(); state.triageSelected = new Set(); state.triageLast = null; state.triagePage = 1; state.armed.triage = false;
|
|
1277
|
+
const qs = new URLSearchParams({ limit: TRIAGE_LIMIT, stream: '1' }); const project = $('jv-triage-project').value.trim(); if (project) qs.set('project', project);
|
|
1278
|
+
setText($('jv-triage-status'), kit.tx('settings.redesign.judgments.findingCandidates'));
|
|
1279
|
+
const r = await streamTriage(`/api/trash/candidates?${qs}`, renderTriage);
|
|
1280
|
+
btn.disabled = false; $('jv-triage-spinner').style.display = 'none';
|
|
1281
|
+
if (r.ok === false) { setText($('jv-triage-status'), r.status === 404 ? kit.tx('settings.redesign.judgments.notAvailableOnThisServerYet') : (r.error || 'unavailable')); return; }
|
|
1282
|
+
renderTriage(r);
|
|
1283
|
+
});
|
|
1284
|
+
$('jv-triage-more').addEventListener('click', () => { state.triagePage++; renderTriage(); });
|
|
1285
|
+
$('jv-triage-all').addEventListener('change', () => {
|
|
1286
|
+
for (const pick of $('jv-triage-list').querySelectorAll('input.jv-tr-pick')) {
|
|
1287
|
+
pick.checked = $('jv-triage-all').checked;
|
|
1288
|
+
if (pick.checked) state.triageSelected.add(pick.dataset.id); else state.triageSelected.delete(pick.dataset.id);
|
|
1289
|
+
}
|
|
1290
|
+
state.armed.triage = false;
|
|
1291
|
+
renderTriageSelection();
|
|
1292
|
+
});
|
|
1293
|
+
$('jv-triage-list').addEventListener('change', (e) => {
|
|
1294
|
+
const pick = e.target.closest('input.jv-tr-pick'); if (!pick) return;
|
|
1295
|
+
if (pick.checked) state.triageSelected.add(pick.dataset.id); else state.triageSelected.delete(pick.dataset.id);
|
|
1296
|
+
state.armed.triage = false;
|
|
1297
|
+
const picks = Array.from($('jv-triage-list').querySelectorAll('input.jv-tr-pick'));
|
|
1298
|
+
$('jv-triage-all').checked = picks.length > 0 && picks.every(box => box.checked);
|
|
1299
|
+
renderTriageSelection();
|
|
1300
|
+
});
|
|
1301
|
+
$('jv-triage-trash-selected').addEventListener('click', async () => {
|
|
1302
|
+
const ids = [...state.triageSelected];
|
|
1303
|
+
if (!ids.length) return;
|
|
1304
|
+
if (!state.armed.triage) {
|
|
1305
|
+
state.armed.triage = true; renderTriageSelection();
|
|
1306
|
+
setTimeout(() => { if (state.armed.triage) { state.armed.triage = false; renderTriageSelection(); } }, 5000);
|
|
1307
|
+
return;
|
|
1308
|
+
}
|
|
1309
|
+
state.armed.triage = false;
|
|
1310
|
+
const btn = $('jv-triage-trash-selected'); btn.disabled = true;
|
|
1311
|
+
const r = await jpost('/api/trash/candidates/trash-selected', { ids });
|
|
1312
|
+
if (r.ok === false) { toast(kit.tx('settings.redesign.judgments.errTrash', { error: r.error })); renderTriageSelection(); return; }
|
|
1313
|
+
for (const id of ids) state.triageTrashed.add(id);
|
|
1314
|
+
state.triageSelected.clear();
|
|
1315
|
+
renderTriage();
|
|
1316
|
+
toast(kit.tx('settings.redesign.judgments.movedToTrashRestorableFromThe2', { num: num(r.trashed), count: r.skipped?.length ? (" " + kit.tx('settings.redesign.judgments.skipped2', { num: num(r.skipped.length) })) : '' }));
|
|
1317
|
+
});
|
|
1318
|
+
$('jv-triage-list').addEventListener('click', async (e) => {
|
|
1319
|
+
const btn = e.target.closest('button.jv-tr-trash'); if (!btn) return;
|
|
1320
|
+
btn.disabled = true;
|
|
1321
|
+
const r = await jpost(`/api/trash/candidates/${encodeURIComponent(btn.dataset.id)}/trash`);
|
|
1322
|
+
if (r.ok === false) { toast(kit.tx('settings.redesign.judgments.errTrash', { error: r.error })); btn.disabled = false; return; }
|
|
1323
|
+
state.triageTrashed.add(btn.dataset.id);
|
|
1324
|
+
state.triageSelected.delete(btn.dataset.id);
|
|
1325
|
+
renderTriage();
|
|
1326
|
+
toast(kit.tx('settings.redesign.judgments.movedToTrashRestorableFromThe'));
|
|
1327
|
+
});
|
|
1328
|
+
|
|
1329
|
+
// ── Timers ──
|
|
1330
|
+
function startTimer(name, ms, fn) {
|
|
1331
|
+
if (state.timers[name]) return;
|
|
1332
|
+
state.timers[name] = setInterval(() => { if (!alive()) return stopAll(); fn().catch?.(() => {}); }, ms);
|
|
1333
|
+
}
|
|
1334
|
+
function stopTimer(name) { if (state.timers[name]) clearInterval(state.timers[name]); delete state.timers[name]; }
|
|
1335
|
+
function stopAll() { for (const name of Object.keys(state.timers)) stopTimer(name); for (const fn of surfaceDebounce.values()) fn.cancel?.(); expandObserver.disconnect(); state.triageAbort?.abort(); }
|
|
1336
|
+
overlay.addEventListener('settings-close', stopAll);
|
|
1337
|
+
startTimer('config', 5000, async () => { if (tabActive()) await loadConfig(); });
|
|
1338
|
+
startTimer('log', 5000, async () => { if (tabActive() && !$('jv-sec-log').classList.contains('collapsed')) await refreshLog(); });
|
|
1339
|
+
startTimer('sessions', 10000, async () => { const sec = $('jv-sec-sessions'); if (tabActive() && sec.style.display !== 'none' && !sec.classList.contains('collapsed')) await refreshSessions(); });
|
|
1340
|
+
|
|
1341
|
+
// ── Boot ──
|
|
1342
|
+
if (initial && initial.ok !== false) applyConfig(initial); else loadConfig();
|
|
1343
|
+
jget('/api/typesafe/backfill/status').then(r => { if (r.ok) applyBackfill(r.backfill); });
|
|
1344
|
+
if (!$('jv-sec-log').classList.contains('collapsed')) refreshLog(true);
|
|
1345
|
+
if (!$('jv-sec-misfiled').classList.contains('collapsed')) refreshMisfiled();
|
|
1346
|
+
}
|