synabun 2.0.10 → 2.2.0
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 +207 -0
- package/README.md +25 -2
- package/THIRD-PARTY-LICENSES.md +22 -0
- package/bin/synabun.js +71 -24
- package/docs/whatsapp.md +13 -13
- package/hooks/claude-code/pre-websearch.mjs +12 -1
- package/hooks/claude-code/shared.mjs +5 -0
- package/hooks/claude-code/stop.mjs +1 -1
- package/lib/claude-hooks.js +172 -18
- package/lib/client-config-repair.js +30 -17
- package/lib/desktop-app.js +7 -1
- package/lib/external-tools.js +7 -6
- package/lib/first-launch-protection.js +57 -12
- package/lib/mcp-dist.js +176 -0
- package/lib/release-npm-ci.mjs +138 -0
- package/lib/release-publish.mjs +91 -0
- package/lib/release-scan.mjs +50 -0
- package/lib/server-crash-record.js +123 -0
- package/lib/server-exit.js +318 -0
- package/lib/server-supervisor.js +508 -0
- package/lib/start-launcher.js +37 -4
- package/lib/tools-cli.js +45 -0
- package/lib/update-snapshot.js +302 -0
- package/lib/virustotal.mjs +203 -0
- package/lib/windows-crash-event.js +269 -0
- package/mcp-server/dist/http.d.ts +20 -1
- package/mcp-server/dist/http.d.ts.map +1 -1
- package/mcp-server/dist/http.js +59 -12
- package/mcp-server/dist/http.js.map +1 -1
- package/mcp-server/dist/index.d.ts +33 -27
- package/mcp-server/dist/index.d.ts.map +1 -1
- package/mcp-server/dist/index.js +128 -143
- package/mcp-server/dist/index.js.map +1 -1
- package/mcp-server/dist/preload.js +1 -1
- package/mcp-server/dist/preload.js.map +1 -1
- package/mcp-server/dist/services/budget-judgments.d.ts +1 -1
- package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -1
- package/mcp-server/dist/services/budget-judgments.js +5 -3
- package/mcp-server/dist/services/budget-judgments.js.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
- package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.js +81 -28
- package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
- package/mcp-server/dist/services/identity.d.ts +2 -2
- package/mcp-server/dist/services/identity.js +2 -2
- package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
- package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
- package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
- package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
- package/mcp-server/dist/services/memory-sessions.d.ts +1 -1
- package/mcp-server/dist/services/memory-sessions.d.ts.map +1 -1
- package/mcp-server/dist/services/memory-sessions.js +28 -2
- package/mcp-server/dist/services/memory-sessions.js.map +1 -1
- package/mcp-server/dist/services/neural-interface.d.ts +18 -11
- package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
- package/mcp-server/dist/services/neural-interface.js +67 -11
- package/mcp-server/dist/services/neural-interface.js.map +1 -1
- package/mcp-server/dist/services/server-instructions.d.ts +7 -2
- package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
- package/mcp-server/dist/services/server-instructions.js +22 -63
- package/mcp-server/dist/services/server-instructions.js.map +1 -1
- package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
- package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-catalog.js +339 -0
- package/mcp-server/dist/services/tool-catalog.js.map +1 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
- package/mcp-server/dist/services/tool-list.d.ts +108 -0
- package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-list.js +334 -0
- package/mcp-server/dist/services/tool-list.js.map +1 -0
- package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
- package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-runtime.js +400 -0
- package/mcp-server/dist/services/tool-runtime.js.map +1 -0
- package/mcp-server/dist/services/typesafe-config.js +1 -1
- package/mcp-server/dist/services/typesafe-config.js.map +1 -1
- package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
- package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
- package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
- package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
- package/mcp-server/dist/tools/agents.d.ts +14 -14
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +29 -19
- package/mcp-server/dist/tools/agents.js.map +1 -1
- package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
- package/mcp-server/dist/tools/choice.d.ts +6 -0
- package/mcp-server/dist/tools/choice.d.ts.map +1 -1
- package/mcp-server/dist/tools/choice.js +18 -13
- package/mcp-server/dist/tools/choice.js.map +1 -1
- package/mcp-server/dist/tools/git-tools.js +2 -2
- package/mcp-server/dist/tools/git-tools.js.map +1 -1
- package/mcp-server/dist/tools/image-tools.d.ts +1 -1
- package/mcp-server/dist/tools/image-tools.js +1 -1
- package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
- package/mcp-server/dist/tools/morelogin.js +9 -6
- package/mcp-server/dist/tools/morelogin.js.map +1 -1
- package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
- package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
- package/mcp-server/dist/tools/skill-tools.js +642 -0
- package/mcp-server/dist/tools/skill-tools.js.map +1 -0
- package/mcp-server/dist/tools/skill.d.ts +7 -0
- package/mcp-server/dist/tools/skill.d.ts.map +1 -0
- package/mcp-server/dist/tools/skill.js +11 -0
- package/mcp-server/dist/tools/skill.js.map +1 -0
- package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
- package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
- package/mcp-server/dist/tools/tool-groups.js +147 -0
- package/mcp-server/dist/tools/tool-groups.js.map +1 -0
- package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
- package/mcp-server/dist/tools/whiteboard-format.js +7 -4
- package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
- package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
- package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
- package/mcp-server/package-lock.json +2 -2
- package/mcp-server/package.json +1 -1
- package/mcp-server/src/http.ts +75 -12
- package/mcp-server/src/index.ts +147 -154
- package/mcp-server/src/preload.ts +12 -12
- package/mcp-server/src/services/budget-judgments.ts +5 -3
- package/mcp-server/src/services/codex-config-heal.ts +80 -29
- package/mcp-server/src/services/identity.ts +2 -2
- package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
- package/mcp-server/src/services/memory-sessions.ts +24 -3
- package/mcp-server/src/services/neural-interface.ts +81 -21
- package/mcp-server/src/services/server-instructions.ts +29 -64
- package/mcp-server/src/services/tool-catalog.ts +403 -0
- package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
- package/mcp-server/src/services/tool-list.ts +410 -0
- package/mcp-server/src/services/tool-runtime.ts +457 -0
- package/mcp-server/src/services/typesafe-config.ts +1 -1
- package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
- package/mcp-server/src/tools/agents.ts +29 -20
- package/mcp-server/src/tools/choice.ts +17 -12
- package/mcp-server/src/tools/git-tools.ts +2 -2
- package/mcp-server/src/tools/image-tools.ts +1 -1
- package/mcp-server/src/tools/morelogin.ts +6 -4
- package/mcp-server/src/tools/skill-tools.ts +592 -0
- package/mcp-server/src/tools/skill.ts +13 -0
- package/mcp-server/src/tools/tool-groups.ts +164 -0
- package/mcp-server/src/tools/whiteboard-format.ts +9 -3
- package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
- package/neural-interface/i18n/en.json +3953 -228
- package/neural-interface/i18n/pt-BR.json +3901 -179
- package/neural-interface/lib/agent-sandbox-elevation.js +6 -0
- package/neural-interface/lib/antigravity/acp-client-host.js +554 -0
- package/neural-interface/lib/antigravity/acp-connection.js +299 -0
- package/neural-interface/lib/antigravity/bypass.js +100 -0
- package/neural-interface/lib/antigravity/catalog.js +273 -0
- package/neural-interface/lib/antigravity/home.js +260 -0
- package/neural-interface/lib/antigravity/migrate-gemini.js +139 -0
- package/neural-interface/lib/antigravity/panel-bridge.js +1058 -0
- package/neural-interface/lib/antigravity/policy-hook.mjs +78 -0
- package/neural-interface/lib/antigravity/policy.js +74 -0
- package/neural-interface/lib/antigravity/tool-call.js +178 -0
- package/neural-interface/lib/antigravity/transcripts.js +252 -0
- package/neural-interface/lib/antigravity/usage.js +43 -0
- package/neural-interface/lib/assistant-api.js +128 -28
- package/neural-interface/lib/assistant-brains/antigravity.js +423 -0
- package/neural-interface/lib/assistant-brains/claude.js +4 -3
- package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
- package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
- package/neural-interface/lib/assistant-brains/codex.js +9 -5
- package/neural-interface/lib/assistant-brains/opencode.js +120 -54
- package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
- package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
- package/neural-interface/lib/assistant-budget-planner.js +7 -3
- package/neural-interface/lib/assistant-budget-split.js +42 -15
- package/neural-interface/lib/assistant-catalog.js +81 -15
- package/neural-interface/lib/assistant-config.js +6 -3
- package/neural-interface/lib/assistant-dispatch.js +1073 -200
- package/neural-interface/lib/assistant-envelope.js +156 -2
- package/neural-interface/lib/assistant-evidence.js +80 -0
- package/neural-interface/lib/assistant-hidden-models.js +7 -5
- package/neural-interface/lib/assistant-persona.js +93 -19
- package/neural-interface/lib/assistant-plan-permissions.js +25 -9
- package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
- package/neural-interface/lib/assistant-route-gate.js +6 -4
- package/neural-interface/lib/assistant-router.js +245 -38
- package/neural-interface/lib/assistant-runtime.js +214 -30
- package/neural-interface/lib/assistant-task-prompt.js +87 -21
- package/neural-interface/lib/assistant-tools.js +51 -0
- package/neural-interface/lib/assistant-usage.js +29 -0
- package/neural-interface/lib/backup-service.js +626 -4
- package/neural-interface/lib/backup-zip-reader.js +10 -5
- package/neural-interface/lib/backup-zip-writer.js +257 -0
- package/neural-interface/lib/browser-execution.js +10 -2
- package/neural-interface/lib/browser-guard-cdp.js +84 -0
- package/neural-interface/lib/browser-network-guard.js +476 -0
- package/neural-interface/lib/browser-policy-roots.js +64 -0
- package/neural-interface/lib/browser-tool-policy.js +198 -38
- package/neural-interface/lib/claude-agent-bridge.js +11 -2
- package/neural-interface/lib/claude-history-cache.js +210 -0
- package/neural-interface/lib/claude-hooks-status.js +103 -0
- package/neural-interface/lib/claude-model-catalog.js +5 -1
- package/neural-interface/lib/claude-temporary.js +5 -11
- package/neural-interface/lib/cli-install-api.js +1 -1
- package/neural-interface/lib/cli-install.js +163 -154
- package/neural-interface/lib/cli-resolver.js +13 -3
- package/neural-interface/lib/cli-update-planner.js +52 -41
- package/neural-interface/lib/cloudflared/tunnel.js +42 -2
- package/neural-interface/lib/codex-mcp-approvals.js +11 -0
- package/neural-interface/lib/codex-rollout-reader.js +52 -0
- package/neural-interface/lib/codex-worker-app-server.js +191 -0
- package/neural-interface/lib/confined-fs.js +30 -3
- package/neural-interface/lib/crash-notice-api.js +98 -0
- package/neural-interface/lib/editor-completion-opencode.js +68 -68
- package/neural-interface/lib/editor-git-api.js +3 -20
- package/neural-interface/lib/exec-loop-command.js +13 -10
- package/neural-interface/lib/file-explorer-api.js +74 -40
- package/neural-interface/lib/file-explorer-watch.js +9 -3
- package/neural-interface/lib/git-bash/install.js +52 -6
- package/neural-interface/lib/git-bash/manager.js +59 -17
- package/neural-interface/lib/git-bash/pins.js +12 -0
- package/neural-interface/lib/git-read.js +2 -2
- package/neural-interface/lib/git-status-runner.js +390 -0
- package/neural-interface/lib/git-status-watchdog.js +40 -0
- package/neural-interface/lib/greeting/budgets.js +1 -0
- package/neural-interface/lib/greeting/engine.js +2 -2
- package/neural-interface/lib/greeting/sources.js +10 -12
- package/neural-interface/lib/greeting/writer.js +1 -1
- package/neural-interface/lib/http-guards.js +8 -2
- package/neural-interface/lib/install-details.js +4 -1
- package/neural-interface/lib/mcp-agent-servers.js +67 -0
- package/neural-interface/lib/mcp-client-config.js +35 -33
- package/neural-interface/lib/mcp-external-servers.js +332 -0
- package/neural-interface/lib/mcp-installer.js +2 -1
- package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
- package/neural-interface/lib/memory-session-capture.js +17 -3
- package/neural-interface/lib/morelogin.js +177 -25
- package/neural-interface/lib/native-loop-providers.js +965 -66
- package/neural-interface/lib/native-loop-runtime.js +290 -42
- package/neural-interface/lib/opencode-config.js +557 -0
- package/neural-interface/lib/opencode-db-schema.js +17 -34
- package/neural-interface/lib/opencode-history.js +48 -218
- package/neural-interface/lib/opencode-mcp-ready.js +108 -0
- package/neural-interface/lib/opencode-native-boundary.js +53 -0
- package/neural-interface/lib/opencode-protocol.js +249 -112
- package/neural-interface/lib/opencode-runtime-config.js +32 -22
- package/neural-interface/lib/opencode-serve-records.js +39 -21
- package/neural-interface/lib/opencode-v2-client.js +48 -153
- package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
- package/neural-interface/lib/opencode-worker-data.js +27 -0
- package/neural-interface/lib/opencode2-client.js +73 -37
- package/neural-interface/lib/opencode2-proxy.js +23 -63
- package/neural-interface/lib/opencode2-translate.js +51 -2
- package/neural-interface/lib/owner-authority.js +249 -0
- package/neural-interface/lib/page-session.js +275 -0
- package/neural-interface/lib/path-confine.js +12 -9
- package/neural-interface/lib/peer-identity.js +793 -0
- package/neural-interface/lib/pty-host/core.js +28 -1
- package/neural-interface/lib/pty-host/lifetime.js +12 -0
- package/neural-interface/lib/pty-host/manager.js +12 -1
- package/neural-interface/lib/remote-policy.js +1 -1
- package/neural-interface/lib/request-gate.js +20 -2
- package/neural-interface/lib/rulesets/api.js +7 -6
- package/neural-interface/lib/rulesets/fs-safe.js +1 -1
- package/neural-interface/lib/rulesets/installer.js +180 -36
- package/neural-interface/lib/rulesets/json-edit.js +1 -1
- package/neural-interface/lib/rulesets/render.js +1 -1
- package/neural-interface/lib/session-cache-builder.js +81 -31
- package/neural-interface/lib/session-title-generator.js +58 -36
- package/neural-interface/lib/skills/api-v2.js +495 -0
- package/neural-interface/lib/skills/bundle.js +418 -0
- package/neural-interface/lib/skills/catalog.js +298 -0
- package/neural-interface/lib/skills/creation-api.js +191 -0
- package/neural-interface/lib/skills/creation-brief.js +247 -0
- package/neural-interface/lib/skills/creation-sources.js +285 -0
- package/neural-interface/lib/skills/creation.js +843 -0
- package/neural-interface/lib/skills/deploy.js +569 -0
- package/neural-interface/lib/skills/digest.js +119 -0
- package/neural-interface/lib/skills/discover.js +111 -0
- package/neural-interface/lib/skills/draft-confinement.js +216 -0
- package/neural-interface/lib/skills/eval-confinement.js +399 -0
- package/neural-interface/lib/skills/eval-sandbox.js +280 -0
- package/neural-interface/lib/skills/eval-trace.js +135 -0
- package/neural-interface/lib/skills/evals-api.js +212 -0
- package/neural-interface/lib/skills/evals.js +1573 -0
- package/neural-interface/lib/skills/export.js +203 -0
- package/neural-interface/lib/skills/frontmatter.js +64 -0
- package/neural-interface/lib/skills/health.js +75 -0
- package/neural-interface/lib/skills/json-edit.js +165 -0
- package/neural-interface/lib/skills/known-bridge-digests.json +441 -0
- package/neural-interface/lib/skills/known-bridges.js +96 -0
- package/neural-interface/lib/skills/library.js +823 -0
- package/neural-interface/lib/skills/local-store.js +21 -0
- package/neural-interface/lib/skills/migration.js +433 -0
- package/neural-interface/lib/skills/operations.js +45 -0
- package/neural-interface/lib/skills/ownership.js +427 -0
- package/neural-interface/lib/skills/packages.js +88 -0
- package/neural-interface/lib/skills/reviews.js +212 -0
- package/neural-interface/lib/skills/revision.js +80 -0
- package/neural-interface/lib/skills/roots.js +269 -0
- package/neural-interface/lib/skills/runtime-checks.js +358 -0
- package/neural-interface/lib/skills/scan-assets.js +252 -0
- package/neural-interface/lib/skills/scan-context.js +26 -0
- package/neural-interface/lib/skills/scan-shell.js +324 -0
- package/neural-interface/lib/skills/scan.js +364 -0
- package/neural-interface/lib/skills/scanners.js +54 -0
- package/neural-interface/lib/skills/service.js +530 -0
- package/neural-interface/lib/skills/telemetry.js +119 -0
- package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
- package/neural-interface/lib/synabun-version.js +1 -1
- package/neural-interface/lib/system-activity.js +1 -1
- package/neural-interface/lib/tool-lists.js +124 -0
- package/neural-interface/lib/whatsapp/brain.js +7 -3
- package/neural-interface/lib/whatsapp/bridge.js +6 -3
- package/neural-interface/lib/whatsapp/cards.js +22 -9
- package/neural-interface/lib/whatsapp/config.js +1 -1
- package/neural-interface/lib/worker-confinement.js +1268 -0
- package/neural-interface/lib/worker-guard-setting.js +56 -0
- package/neural-interface/lib/worker-mcp-channel.js +175 -0
- package/neural-interface/lib/worker-question.js +74 -0
- package/neural-interface/lib/worker-relay-ports.js +227 -0
- package/neural-interface/lib/worker-resume.js +238 -0
- package/neural-interface/lib/worker-sandbox.js +329 -0
- package/neural-interface/package-lock.json +34 -12
- package/neural-interface/package.json +3 -2
- package/neural-interface/public/index.html +3 -1
- package/neural-interface/public/index2d.html +19 -11
- package/neural-interface/public/onboarding.html +3 -3
- package/neural-interface/public/shared/account-menu.js +8 -5
- package/neural-interface/public/shared/agent-runtime-options.js +125 -31
- package/neural-interface/public/shared/agy/agy-bypass.js +47 -0
- package/neural-interface/public/shared/agy/agy-client.js +266 -0
- package/neural-interface/public/shared/agy/agy-commands.js +120 -0
- package/neural-interface/public/shared/agy/agy-copy.js +326 -0
- package/neural-interface/public/shared/agy/agy-diff.js +161 -0
- package/neural-interface/public/shared/agy/agy-events.js +469 -0
- package/neural-interface/public/shared/agy/agy-greeting.js +26 -0
- package/neural-interface/public/shared/agy/agy-options.js +232 -0
- package/neural-interface/public/shared/agy/agy-panel.js +2543 -0
- package/neural-interface/public/shared/agy/agy-render.js +392 -0
- package/neural-interface/public/shared/agy/agy-setup.js +149 -0
- package/neural-interface/public/shared/agy/agy-styles.js +604 -0
- package/neural-interface/public/shared/agy/agy-tabs-logic.js +181 -0
- package/neural-interface/public/shared/api.js +1527 -1336
- package/neural-interface/public/shared/app-frame.js +192 -0
- package/neural-interface/public/shared/assistant/asst-agents-dock.js +36 -6
- package/neural-interface/public/shared/assistant/asst-api.js +1 -1
- package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
- package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
- package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +105 -44
- package/neural-interface/public/shared/assistant/asst-budget.js +5 -4
- package/neural-interface/public/shared/assistant/asst-control.js +205 -26
- package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
- package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
- package/neural-interface/public/shared/assistant/asst-hosts.js +16 -7
- package/neural-interface/public/shared/assistant/asst-limit-dock.js +45 -0
- package/neural-interface/public/shared/assistant/asst-limit-wait.js +327 -0
- package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
- package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
- package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
- package/neural-interface/public/shared/assistant/asst-panel.js +151 -19
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
- package/neural-interface/public/shared/assistant/asst-render.js +445 -82
- package/neural-interface/public/shared/assistant/asst-route.js +304 -53
- package/neural-interface/public/shared/assistant/asst-routes-editor.js +9 -8
- package/neural-interface/public/shared/assistant/asst-scenes.js +56 -1
- package/neural-interface/public/shared/assistant/asst-sidepanel.js +117 -10
- package/neural-interface/public/shared/assistant/asst-slash.js +17 -9
- package/neural-interface/public/shared/assistant/asst-state.js +87 -24
- package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +93 -21
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +190 -23
- package/neural-interface/public/shared/assistant/asst-usage.js +2 -1
- package/neural-interface/public/shared/automation-context.js +5 -2
- package/neural-interface/public/shared/cc-dropdown.js +89 -19
- package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
- package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
- package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
- package/neural-interface/public/shared/cdx/cdx-output.js +34 -10
- package/neural-interface/public/shared/cdx/cdx-panel.js +59 -151
- package/neural-interface/public/shared/cdx/cdx-preview.js +12 -0
- package/neural-interface/public/shared/cdx/cdx-protocol.js +39 -11
- package/neural-interface/public/shared/cdx/cdx-render.js +57 -38
- package/neural-interface/public/shared/cdx/cdx-requests.js +14 -4
- package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
- package/neural-interface/public/shared/cdx/cdx-styles.js +15 -3
- package/neural-interface/public/shared/cdx/cdx-tabs.js +127 -44
- package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
- package/neural-interface/public/shared/cli-install-controller.js +218 -0
- package/neural-interface/public/shared/cli-install-view.js +11 -12
- package/neural-interface/public/shared/cli-status.js +11 -10
- package/neural-interface/public/shared/constants.js +5 -4
- package/neural-interface/public/shared/context-menu-areas.js +34 -0
- package/neural-interface/public/shared/context-menu-logic.js +243 -0
- package/neural-interface/public/shared/context-menu-model.js +367 -0
- package/neural-interface/public/shared/context-menu.js +372 -0
- package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
- package/neural-interface/public/shared/cp/cp-restore.js +162 -0
- package/neural-interface/public/shared/cp/cp-tool-cards.js +10 -3
- package/neural-interface/public/shared/crash-notice-view.js +168 -0
- package/neural-interface/public/shared/desktop-bridge.js +17 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +12 -0
- package/neural-interface/public/shared/desktop-titlebar.js +13 -4
- package/neural-interface/public/shared/desktop-update-view.js +21 -0
- package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
- package/neural-interface/public/shared/explorer/fx-api.js +4 -4
- package/neural-interface/public/shared/explorer/fx-links.js +3 -3
- package/neural-interface/public/shared/explorer/fx-logic.js +1 -1
- package/neural-interface/public/shared/explorer/fx-main.js +48 -16
- package/neural-interface/public/shared/explorer/fx-tree.js +1 -0
- package/neural-interface/public/shared/greeting/greeting-card.js +2 -2
- package/neural-interface/public/shared/greeting/greeting-view.js +1 -0
- package/neural-interface/public/shared/html-shell.js +30 -15
- package/neural-interface/public/shared/i18n.js +2 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
- package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
- package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
- package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
- package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
- package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
- package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +74 -259
- package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
- package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +13 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +13 -22
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
- package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
- package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
- package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
- package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
- package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +17 -21
- package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
- package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +60 -50
- package/neural-interface/public/shared/page-session.js +96 -0
- package/neural-interface/public/shared/provider-icons.js +4 -2
- package/neural-interface/public/shared/registry.js +5 -3
- package/neural-interface/public/shared/retired-2d.js +3 -0
- package/neural-interface/public/shared/schedules-view.js +195 -61
- package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
- package/neural-interface/public/shared/settings/settings-data.js +3 -1
- package/neural-interface/public/shared/settings/settings-ia.js +6 -6
- package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
- package/neural-interface/public/shared/settings/settings-rules.js +2 -2
- package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
- package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
- package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
- package/neural-interface/public/shared/showcase-privacy.js +6 -1
- package/neural-interface/public/shared/sidepanel-session-status.js +3 -3
- package/neural-interface/public/shared/skills/ss-args.js +96 -0
- package/neural-interface/public/shared/skills/ss-creation.js +222 -0
- package/neural-interface/public/shared/skills/ss-dialog.js +133 -0
- package/neural-interface/public/shared/skills/ss-doc.js +173 -0
- package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
- package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
- package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
- package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
- package/neural-interface/public/shared/skills/ss-evals.js +417 -0
- package/neural-interface/public/shared/skills/ss-form.js +159 -0
- package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
- package/neural-interface/public/shared/skills/ss-ids.js +32 -0
- package/neural-interface/public/shared/skills/ss-lint.js +149 -0
- package/neural-interface/public/shared/skills/ss-presets.js +117 -0
- package/neural-interface/public/shared/skills/ss-profiles.js +513 -0
- package/neural-interface/public/shared/skills/ss-resources.js +165 -0
- package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
- package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
- package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
- package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
- package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
- package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
- package/neural-interface/public/shared/skills/studio/sx-create-ai.js +237 -0
- package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
- package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
- package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
- package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
- package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
- package/neural-interface/public/shared/skills/studio/sx-dom.js +230 -0
- package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
- package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
- package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
- package/neural-interface/public/shared/skills/studio/sx-fixes-view.js +359 -0
- package/neural-interface/public/shared/skills/studio/sx-fixes.js +327 -0
- package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
- package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
- package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
- package/neural-interface/public/shared/skills/studio/sx-install-flow.js +282 -0
- package/neural-interface/public/shared/skills/studio/sx-install.js +313 -0
- package/neural-interface/public/shared/skills/studio/sx-library-view.js +748 -0
- package/neural-interface/public/shared/skills/studio/sx-library.js +479 -0
- package/neural-interface/public/shared/skills/studio/sx-main.js +690 -0
- package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
- package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
- package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
- package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
- package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
- package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
- package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
- package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
- package/neural-interface/public/shared/skills/studio/sx-subject.js +249 -0
- package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
- package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
- package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
- package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +426 -0
- package/neural-interface/public/shared/state.js +1 -1
- package/neural-interface/public/shared/streaming-markdown.js +58 -0
- package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
- package/neural-interface/public/shared/styles.css +1822 -1756
- package/neural-interface/public/shared/synabun-mascot.js +1115 -9
- package/neural-interface/public/shared/text-cache.js +29 -0
- package/neural-interface/public/shared/tool-list-picker.js +55 -0
- package/neural-interface/public/shared/tool-list-storage.js +24 -0
- package/neural-interface/public/shared/tool-list-view.js +112 -0
- package/neural-interface/public/shared/topright-overflow-logic.js +54 -0
- package/neural-interface/public/shared/tour/tour-actor.js +268 -0
- package/neural-interface/public/shared/tour/tour-beats.js +336 -0
- package/neural-interface/public/shared/tour/tour-engine.js +884 -0
- package/neural-interface/public/shared/tour/tour-ink.js +390 -0
- package/neural-interface/public/shared/tour/tour-stage.js +440 -0
- package/neural-interface/public/shared/tour/tour-state.js +40 -0
- package/neural-interface/public/shared/tour/tour-tips.js +99 -0
- package/neural-interface/public/shared/tour/tour.css +144 -0
- package/neural-interface/public/shared/ui-antigravity-panel.js +19 -0
- package/neural-interface/public/shared/ui-assistant.js +2 -0
- package/neural-interface/public/shared/ui-automation-studio.js +111 -140
- package/neural-interface/public/shared/ui-claude-panel.js +376 -82
- package/neural-interface/public/shared/ui-cli-banner.js +23 -167
- package/neural-interface/public/shared/ui-command-runner.js +6 -3
- package/neural-interface/public/shared/ui-context-menu.js +295 -0
- package/neural-interface/public/shared/ui-cost-widget.js +57 -59
- package/neural-interface/public/shared/ui-crash-notice.js +187 -0
- package/neural-interface/public/shared/ui-detail.js +15 -3
- package/neural-interface/public/shared/ui-file-explorer.js +48 -6
- package/neural-interface/public/shared/ui-file-links.js +2 -2
- package/neural-interface/public/shared/ui-games.js +2 -2
- package/neural-interface/public/shared/ui-image-gallery.js +50 -47
- package/neural-interface/public/shared/ui-judgments.js +1 -1
- package/neural-interface/public/shared/ui-keybinds.js +33 -2
- package/neural-interface/public/shared/ui-link.js +3 -3
- package/neural-interface/public/shared/ui-menubar.js +10 -20
- package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
- package/neural-interface/public/shared/ui-native-loop-router.js +11 -1
- package/neural-interface/public/shared/ui-navbar.js +49 -24
- package/neural-interface/public/shared/ui-notifications.js +1 -0
- package/neural-interface/public/shared/ui-panels.js +96 -65
- package/neural-interface/public/shared/ui-resume.js +9 -7
- package/neural-interface/public/shared/ui-schedules-studio.js +546 -431
- package/neural-interface/public/shared/ui-scroll-follow.js +16 -5
- package/neural-interface/public/shared/ui-sessions.js +27 -15
- package/neural-interface/public/shared/ui-settings.js +683 -526
- package/neural-interface/public/shared/ui-sidepanel-session-entry.js +9 -2
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +4 -4
- package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
- package/neural-interface/public/shared/ui-sidepanel-tray.js +48 -7
- package/neural-interface/public/shared/ui-sidepanel-windows.js +18 -13
- package/neural-interface/public/shared/ui-skills.js +33 -2830
- package/neural-interface/public/shared/ui-styleguide.js +5 -2
- package/neural-interface/public/shared/ui-sync.js +15 -5
- package/neural-interface/public/shared/ui-terminal.js +270 -190
- package/neural-interface/public/shared/ui-tool-updates.js +6 -4
- package/neural-interface/public/shared/ui-tooltip.js +81 -51
- package/neural-interface/public/shared/ui-topright-overflow.js +233 -0
- package/neural-interface/public/shared/ui-trash.js +6 -4
- package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
- package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
- package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
- package/neural-interface/public/shared/ui-tutorial.css +47 -100
- package/neural-interface/public/shared/ui-tutorial.js +285 -509
- package/neural-interface/public/shared/ui-update.js +38 -2
- package/neural-interface/public/shared/ui-whiteboard.js +312 -59
- package/neural-interface/public/shared/ui-worker-end.js +5 -1
- package/neural-interface/public/shared/ui-workspaces.js +3 -2
- package/neural-interface/public/shared/view-variant.js +66 -0
- package/neural-interface/public/shared/whatsapp/wa-view.js +3 -3
- package/neural-interface/public/shared/whiteboard-list.js +172 -0
- package/neural-interface/public/shared/worker-end.js +10 -3
- package/neural-interface/public/shared/worker-questions.js +34 -0
- package/neural-interface/public/shared/worker-restart.js +12 -0
- package/neural-interface/public/sidepanel-session.html +2 -2
- package/neural-interface/public/variant/2d/background.js +2 -1
- package/neural-interface/public/variant/2d/context-menu.js +8 -2
- package/neural-interface/public/variant/2d/graph.js +42 -20
- package/neural-interface/public/variant/2d/hulls.js +14 -9
- package/neural-interface/public/variant/2d/lasso.js +11 -7
- package/neural-interface/public/variant/2d/main.js +32 -1
- package/neural-interface/public/variant/2d/minimap.js +11 -13
- package/neural-interface/public/variant/3d/main.js +69 -6
- package/neural-interface/public/variant/3d/map-controls.js +24 -9
- package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
- package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
- package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
- package/neural-interface/public/vendor/caveat/caveat.css +17 -0
- package/neural-interface/public/vendor/caveat/manifest.json +12 -0
- package/neural-interface/public/vendor/yaml/LICENSE +13 -0
- package/neural-interface/public/vendor/yaml/manifest.json +4 -0
- package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
- package/neural-interface/scripts/build-vendor.mjs +32 -0
- package/neural-interface/server.js +4553 -2855
- package/neural-interface/templates/rulesets/README.md +1 -1
- package/neural-interface/templates/rulesets/core.md +1 -1
- package/neural-interface/templates/rulesets/legacy-hashes.json +23 -5
- package/neural-interface/templates/rulesets/manifest.json +8 -8
- package/npm-shrinkwrap.json +34 -12
- package/package.json +17 -3
- package/postinstall.js +9 -4
- package/preuninstall.js +1 -1
- package/setup.js +97 -322
- package/skills/skill-forge/SKILL.md +177 -0
- package/skills/skill-forge/evals/evals.json +54 -0
- package/skills/skill-forge/references/package.md +105 -0
- package/skills/skill-forge/references/review-and-recovery.md +63 -0
- package/skills/skill-forge/references/runtime-profiles.md +20 -0
- package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
- package/skills/synabun/SKILL.md +10 -7
- package/skills/synabun/modules/audit.md +1 -5
- package/skills/synabun/modules/changelog.md +1 -5
- package/skills/synabun/modules/idea.md +1 -1
- package/skills/synabun/modules/memorize.md +6 -9
- package/skills/synabun/modules/schedule.md +6 -6
- package/mcp-server/dist/services/profiles.d.ts +0 -120
- package/mcp-server/dist/services/profiles.d.ts.map +0 -1
- package/mcp-server/dist/services/profiles.js +0 -387
- package/mcp-server/dist/services/profiles.js.map +0 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
- package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
- package/mcp-server/dist/tools/leonardo.d.ts +0 -13
- package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
- package/mcp-server/dist/tools/leonardo.js +0 -21
- package/mcp-server/dist/tools/leonardo.js.map +0 -1
- package/mcp-server/dist/tools/profile.d.ts +0 -17
- package/mcp-server/dist/tools/profile.d.ts.map +0 -1
- package/mcp-server/dist/tools/profile.js +0 -114
- package/mcp-server/dist/tools/profile.js.map +0 -1
- package/mcp-server/src/services/profiles.ts +0 -428
- package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
- package/mcp-server/src/tools/leonardo.ts +0 -30
- package/mcp-server/src/tools/profile.ts +0 -122
- package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
- package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
- package/neural-interface/lib/mcp-profile-servers.js +0 -120
- package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
- package/skills/leonardo/SKILL.md +0 -168
- package/skills/leonardo/icon.svg +0 -1
- package/skills/leonardo/modules/browser-guide.md +0 -378
- package/skills/leonardo/modules/image-prompter.md +0 -283
- package/skills/leonardo/modules/model-advisor.md +0 -100
- package/skills/leonardo/modules/prompt-library.md +0 -110
- package/skills/leonardo/modules/style-guide.md +0 -186
- package/skills/leonardo/modules/video-prompter.md +0 -317
- /package/neural-interface/templates/rulesets/{gemini.md → antigravity.md} +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { retainExternalRefs } from './mcp-external-servers.js';
|
|
2
|
+
import { storedToolList, toolListRecord, readStoredToolListRecord } from './tool-lists.js';
|
|
1
3
|
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
2
4
|
import { dirname, resolve } from 'node:path';
|
|
3
5
|
|
|
4
|
-
export const NATIVE_LOOP_PROFILES = new Set(['claude-code', 'codex', 'opencode']);
|
|
6
|
+
export const NATIVE_LOOP_PROFILES = new Set(['claude-code', 'codex', 'opencode', 'antigravity']);
|
|
5
7
|
|
|
6
8
|
export function isNativeLoopProfile(profile) {
|
|
7
9
|
return NATIVE_LOOP_PROFILES.has(String(profile || ''));
|
|
@@ -20,6 +22,7 @@ function cleanDescriptor(record) {
|
|
|
20
22
|
provider: record.provider,
|
|
21
23
|
providerSessionId: record.providerSessionId || null,
|
|
22
24
|
providerThreadId: record.providerThreadId || null,
|
|
25
|
+
...(record.antigravityHome ? { antigravityHome: record.antigravityHome } : {}),
|
|
23
26
|
source: record.source,
|
|
24
27
|
focus: !!record.focus,
|
|
25
28
|
status: record.status,
|
|
@@ -30,7 +33,9 @@ function cleanDescriptor(record) {
|
|
|
30
33
|
contextMode: record.contextMode || null,
|
|
31
34
|
modelContextWindow: record.modelContextWindow || null,
|
|
32
35
|
effort: record.effort || null,
|
|
33
|
-
|
|
36
|
+
tools: storedToolList(record),
|
|
37
|
+
externalMcpVersion: 2,
|
|
38
|
+
...(record.toolListError ? { toolListError: record.toolListError } : {}),
|
|
34
39
|
accountId: record.accountId || null,
|
|
35
40
|
currentIteration: record.currentIteration || 0,
|
|
36
41
|
totalIterations: record.totalIterations || 0,
|
|
@@ -49,13 +54,23 @@ function cleanDescriptor(record) {
|
|
|
49
54
|
// existing consumers (router, sidepanels, schedules) are unaffected.
|
|
50
55
|
runMode: record.runMode || 'loop',
|
|
51
56
|
turnState: record.turnState || null,
|
|
57
|
+
pending: record.status === 'running' ? (record.pendingRequests || []) : [],
|
|
52
58
|
// What the last turn's result said (task mode: done, blocked or needs_input; the dispatcher's
|
|
53
59
|
// lastResult.status): an idle warm worker whose turn ended asking waits on the user.
|
|
54
60
|
outcome: record.outcome || null,
|
|
55
61
|
assistantSessionId: record.assistantSessionId || null,
|
|
62
|
+
// A dispatched worker a server restart cut off (status 'suspended') waits for its resume on the next start;
|
|
63
|
+
// `resumes` counts how often it was resumed (assistant-dispatch.js resumeRun).
|
|
64
|
+
suspendedAt: record.suspendedAt || null,
|
|
65
|
+
suspendReason: record.suspendReason || null,
|
|
66
|
+
resumes: Number(record.resumes) || 0,
|
|
67
|
+
resumedAt: record.resumedAt || null,
|
|
56
68
|
};
|
|
57
69
|
}
|
|
58
70
|
|
|
71
|
+
/** Run statuses that hold a run in the ledger as live: it runs, or waits for its resume after a restart. */
|
|
72
|
+
const LIVE_STATUSES = new Set(['starting', 'running', 'suspended']);
|
|
73
|
+
|
|
59
74
|
function readJson(path, fallback = null) {
|
|
60
75
|
try { return JSON.parse(readFileSync(path, 'utf8')); }
|
|
61
76
|
catch { return fallback; }
|
|
@@ -76,6 +91,7 @@ export class NativeLoopRuntime {
|
|
|
76
91
|
constructor({
|
|
77
92
|
stateDir,
|
|
78
93
|
ledgerPath,
|
|
94
|
+
toolListOptions = () => ({}),
|
|
79
95
|
providerFactories = {},
|
|
80
96
|
buildPrompt,
|
|
81
97
|
onEvent = () => {},
|
|
@@ -95,10 +111,14 @@ export class NativeLoopRuntime {
|
|
|
95
111
|
// A truthy `met` ends the run early with stoppedReason 'goal_met'; the
|
|
96
112
|
// iteration and time caps stay the fallback.
|
|
97
113
|
judgeGoal = null,
|
|
114
|
+
// How long a dispatched worker the restart cut off waits, from this start, for its dispatcher to resume it
|
|
115
|
+
// (or end it) before it ends as interrupted by itself.
|
|
116
|
+
resumeHoldMs = 60_000,
|
|
98
117
|
} = {}) {
|
|
99
118
|
if (!stateDir) throw new Error('NativeLoopRuntime requires stateDir');
|
|
100
119
|
if (typeof buildPrompt !== 'function') throw new Error('NativeLoopRuntime requires buildPrompt');
|
|
101
120
|
this.stateDir = stateDir;
|
|
121
|
+
this.toolListOptions = toolListOptions;
|
|
102
122
|
this.judgeGoal = typeof judgeGoal === 'function' ? judgeGoal : null;
|
|
103
123
|
this.ledgerPath = ledgerPath || resolve(dirname(stateDir), 'native-loop-runs.json');
|
|
104
124
|
this.providerFactories = { ...providerFactories };
|
|
@@ -113,6 +133,8 @@ export class NativeLoopRuntime {
|
|
|
113
133
|
this.providerStartupTimeoutMs = providerStartupTimeoutMs;
|
|
114
134
|
this.claimTtlMs = claimTtlMs;
|
|
115
135
|
this.ledgerFlushMs = Math.max(50, Number(ledgerFlushMs) || 200);
|
|
136
|
+
this.resumeHoldMs = Math.max(1000, Number(resumeHoldMs) || 60_000);
|
|
137
|
+
this._holdTimers = new Map();
|
|
116
138
|
this.records = new Map();
|
|
117
139
|
this._pendingPersist = false;
|
|
118
140
|
this._persistTimer = null;
|
|
@@ -164,6 +186,14 @@ export class NativeLoopRuntime {
|
|
|
164
186
|
return this._emit('sidepanel:run-updated', record, { reason: 'turn-state' });
|
|
165
187
|
}
|
|
166
188
|
|
|
189
|
+
/** A live worker's requests, durable for a late attach or page reload. Resolvers stay in the dispatcher. */
|
|
190
|
+
setPendingRequests(runId, requests) {
|
|
191
|
+
const record = this.records.get(runId);
|
|
192
|
+
if (!record) return null;
|
|
193
|
+
record.pendingRequests = structuredClone(requests || []);
|
|
194
|
+
return this._emit('sidepanel:run-updated', record, { reason: 'pending-requests' });
|
|
195
|
+
}
|
|
196
|
+
|
|
167
197
|
/**
|
|
168
198
|
* Task-mode helper: records what the wrapper's last turn reported ('done' |
|
|
169
199
|
* 'blocked' | 'needs_input', the dispatcher's lastResult.status) and
|
|
@@ -184,8 +214,33 @@ export class NativeLoopRuntime {
|
|
|
184
214
|
if (!Array.isArray(rows)) return;
|
|
185
215
|
for (const row of rows) {
|
|
186
216
|
if (!row?.runId) continue;
|
|
187
|
-
|
|
188
|
-
|
|
217
|
+
let stored;
|
|
218
|
+
try { stored = readStoredToolListRecord(row, this.toolListOptions()); }
|
|
219
|
+
catch (error) {
|
|
220
|
+
// A historical run may name a custom preset the owner has since deleted. Refuse that
|
|
221
|
+
// run, preserve the original selection for diagnosis, and keep the rest of the server up.
|
|
222
|
+
stored = { ...row, tools: [], status: 'failed', stoppedReason: 'tools_invalid',
|
|
223
|
+
error: error.message, toolListError: { code: error.code, message: error.message,
|
|
224
|
+
original: row.tools ?? row.mcpProfile ?? null } };
|
|
225
|
+
delete stored.mcpProfile;
|
|
226
|
+
}
|
|
227
|
+
const record = { ...stored, adapter: null, timer: null, execution: null };
|
|
228
|
+
const cutOff = record.status === 'starting' || record.status === 'running' || record.status === 'suspended';
|
|
229
|
+
if (cutOff && record.runMode === 'task' && isNativeLoopProfile(record.provider)) {
|
|
230
|
+
// A dispatched Claude Code worker the restart cut off (suspended by the last shutdown, or left running by a
|
|
231
|
+
// crash): held for its dispatcher, which resumes it (assistant-dispatch.js resumeRun) or ends it. Its state file
|
|
232
|
+
// stays as it is. Nobody takes it within resumeHoldMs: it ends as interrupted, as every cut-off run did before.
|
|
233
|
+
record.status = 'suspended';
|
|
234
|
+
record.suspendedAt = record.suspendedAt || iso(this.now());
|
|
235
|
+
record.suspendReason = record.suspendReason || 'server_restart';
|
|
236
|
+
record.turnState = 'suspended';
|
|
237
|
+
record.pendingRequests = [];
|
|
238
|
+
record.stopping = false;
|
|
239
|
+
this.records.set(record.runId, record);
|
|
240
|
+
this._hold(record);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (cutOff) {
|
|
189
244
|
record.status = 'interrupted';
|
|
190
245
|
record.stoppedReason = 'server_restart';
|
|
191
246
|
record.completedAt = record.completedAt || iso(this.now());
|
|
@@ -208,9 +263,9 @@ export class NativeLoopRuntime {
|
|
|
208
263
|
|
|
209
264
|
_writeLedgerNow() {
|
|
210
265
|
const records = [...this.records.values()];
|
|
211
|
-
const active = records.filter((record) =>
|
|
266
|
+
const active = records.filter((record) => LIVE_STATUSES.has(record.status));
|
|
212
267
|
const terminal = records
|
|
213
|
-
.filter((record) => !
|
|
268
|
+
.filter((record) => !LIVE_STATUSES.has(record.status))
|
|
214
269
|
.sort((a, b) => String(b.startedAt || '').localeCompare(String(a.startedAt || '')));
|
|
215
270
|
const retained = [...active, ...terminal.slice(0, Math.max(0, 500 - active.length))];
|
|
216
271
|
const retainedIds = new Set(retained.map((record) => record.runId));
|
|
@@ -221,7 +276,7 @@ export class NativeLoopRuntime {
|
|
|
221
276
|
}
|
|
222
277
|
}
|
|
223
278
|
const rows = retained
|
|
224
|
-
.map(cleanDescriptor)
|
|
279
|
+
.map(record => toolListRecord(cleanDescriptor(record)))
|
|
225
280
|
.sort((a, b) => String(b.startedAt || '').localeCompare(String(a.startedAt || '')));
|
|
226
281
|
try { writeJsonAtomic(this.ledgerPath, rows); }
|
|
227
282
|
catch (error) { this.log(null, 'ledger:error', error.message); }
|
|
@@ -265,11 +320,13 @@ export class NativeLoopRuntime {
|
|
|
265
320
|
|
|
266
321
|
_readState(runId) {
|
|
267
322
|
const path = this._statePath(runId);
|
|
268
|
-
|
|
323
|
+
const state = existsSync(path) ? readJson(path, null) : null;
|
|
324
|
+
return state ? readStoredToolListRecord(state, this.toolListOptions()) : null;
|
|
269
325
|
}
|
|
270
326
|
|
|
271
327
|
_writeState(runId, state) {
|
|
272
|
-
|
|
328
|
+
const { permissionBroker: _broker, ...stored } = state;
|
|
329
|
+
writeJsonAtomic(this._statePath(runId), toolListRecord(stored, this.toolListOptions()));
|
|
273
330
|
}
|
|
274
331
|
|
|
275
332
|
_writeTerminalState(record, patch) {
|
|
@@ -285,8 +342,9 @@ export class NativeLoopRuntime {
|
|
|
285
342
|
record.version = (Number(record.version) || 0) + 1;
|
|
286
343
|
record.updatedAt = iso(this.now());
|
|
287
344
|
// Force-flush on terminal transitions (a crash between throttled flushes
|
|
288
|
-
// would otherwise leave the run listed as running after a restart)
|
|
289
|
-
|
|
345
|
+
// would otherwise leave the run listed as running after a restart), and on
|
|
346
|
+
// a suspension (the next start resumes the run from this ledger).
|
|
347
|
+
const terminal = ['completed', 'failed', 'stopped', 'interrupted', 'suspended'].includes(record.status);
|
|
290
348
|
this._persistLedger({ force: terminal });
|
|
291
349
|
const descriptor = cleanDescriptor(record);
|
|
292
350
|
const message = { type, run: descriptor, ...extra };
|
|
@@ -298,6 +356,7 @@ export class NativeLoopRuntime {
|
|
|
298
356
|
_setIdentity(record, identity = {}) {
|
|
299
357
|
const providerSessionId = identity.providerSessionId || identity.sessionId || null;
|
|
300
358
|
const providerThreadId = identity.providerThreadId || identity.threadId || null;
|
|
359
|
+
const antigravityHome = typeof identity.antigravityHome === "string" && identity.antigravityHome ? identity.antigravityHome : null;
|
|
301
360
|
let changed = false;
|
|
302
361
|
if (providerSessionId && providerSessionId !== record.providerSessionId) {
|
|
303
362
|
record.providerSessionId = providerSessionId;
|
|
@@ -307,6 +366,10 @@ export class NativeLoopRuntime {
|
|
|
307
366
|
record.providerThreadId = providerThreadId;
|
|
308
367
|
changed = true;
|
|
309
368
|
}
|
|
369
|
+
if (antigravityHome && antigravityHome !== record.antigravityHome) {
|
|
370
|
+
record.antigravityHome = antigravityHome;
|
|
371
|
+
changed = true;
|
|
372
|
+
}
|
|
310
373
|
if (changed) this._emit('sidepanel:run-updated', record, { reason: 'identity' });
|
|
311
374
|
if ((record.providerSessionId || record.providerThreadId) && record._resolveIdentity) {
|
|
312
375
|
record._resolveIdentity(cleanDescriptor(record));
|
|
@@ -333,7 +396,7 @@ export class NativeLoopRuntime {
|
|
|
333
396
|
mkdirSync(this.stateDir, { recursive: true });
|
|
334
397
|
const startedAt = state.startedAt || iso(this.now());
|
|
335
398
|
const nativeState = {
|
|
336
|
-
...state,
|
|
399
|
+
...toolListRecord(state, this.toolListOptions()),
|
|
337
400
|
runId,
|
|
338
401
|
terminalSessionId: runId,
|
|
339
402
|
active: true,
|
|
@@ -351,6 +414,7 @@ export class NativeLoopRuntime {
|
|
|
351
414
|
provider: state.profile,
|
|
352
415
|
providerSessionId: null,
|
|
353
416
|
providerThreadId: null,
|
|
417
|
+
antigravityHome: typeof state.antigravityHome === "string" && state.antigravityHome ? state.antigravityHome : null,
|
|
354
418
|
source,
|
|
355
419
|
focus,
|
|
356
420
|
status: 'starting',
|
|
@@ -361,7 +425,7 @@ export class NativeLoopRuntime {
|
|
|
361
425
|
contextMode: state.contextMode || null,
|
|
362
426
|
modelContextWindow: state.modelContextWindow || null,
|
|
363
427
|
effort: state.effort || null,
|
|
364
|
-
|
|
428
|
+
tools: storedToolList(state, this.toolListOptions()),
|
|
365
429
|
accountId: state.codexAccountId || null,
|
|
366
430
|
currentIteration: Number(state.currentIteration) || 0,
|
|
367
431
|
totalIterations: Number(state.totalIterations) || 1,
|
|
@@ -400,6 +464,24 @@ export class NativeLoopRuntime {
|
|
|
400
464
|
record.timer.unref?.();
|
|
401
465
|
}
|
|
402
466
|
|
|
467
|
+
this._bootstrap(record, factory, nativeState, { source, profile: state.profile });
|
|
468
|
+
|
|
469
|
+
// For back-compat: callers that awaited launch() to know whether the run was
|
|
470
|
+
// accepted can observe the descriptor. The failure (if any) is delivered via
|
|
471
|
+
// sidepanel:run-failed and via record.bootstrap rejecting with the original
|
|
472
|
+
// startup error. The descriptor itself resolves immediately with the
|
|
473
|
+
// 'starting' state so the HTTP caller is never gated on provider boot.
|
|
474
|
+
return cleanDescriptor(record);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Start the provider of a run whose record is in place (launch, resume) and drive it. Sets record.bootstrap: it
|
|
479
|
+
* resolves once the provider started and rejects with the startup error. A provider that cannot start ends the
|
|
480
|
+
* run as failed, or (`failAs: 'interrupted'`, a resume) as interrupted with the reason resume_failed.
|
|
481
|
+
*/
|
|
482
|
+
_bootstrap(record, factory, nativeState, { source = record.source, profile = record.provider, failAs = 'failed' } = {}) {
|
|
483
|
+
const runId = record.runId;
|
|
484
|
+
const state = { profile };
|
|
403
485
|
const startupSignal = record.startupAbortController.signal;
|
|
404
486
|
const factoryPromise = Promise.resolve().then(() => factory({
|
|
405
487
|
...nativeState,
|
|
@@ -418,7 +500,8 @@ export class NativeLoopRuntime {
|
|
|
418
500
|
if (!adapter || candidateCleaned) return;
|
|
419
501
|
candidateCleaned = true;
|
|
420
502
|
try { await adapter.abort?.(reason); } catch {}
|
|
421
|
-
|
|
503
|
+
// Suspended for a server shutdown while it started (suspend): its process is ended now, as a started one's is.
|
|
504
|
+
try { await adapter.dispose?.({ preserveSession: true, ...(record.status === 'suspended' ? { terminate: true } : {}) }); } catch {}
|
|
422
505
|
};
|
|
423
506
|
const finishBootstrap = async () => {
|
|
424
507
|
clearTimeout(startupTimer);
|
|
@@ -479,6 +562,7 @@ export class NativeLoopRuntime {
|
|
|
479
562
|
runId,
|
|
480
563
|
emit: (event) => this._emitProviderEvent(record, event),
|
|
481
564
|
setTurnState: (turnState) => this.setTurnState(runId, turnState),
|
|
565
|
+
setPendingRequests: (requests) => this.setPendingRequests(runId, requests),
|
|
482
566
|
setOutcome: (outcome) => this.setOutcome(runId, outcome),
|
|
483
567
|
readState: () => this._readState(runId),
|
|
484
568
|
})
|
|
@@ -497,11 +581,15 @@ export class NativeLoopRuntime {
|
|
|
497
581
|
if (candidate) await cleanupCandidate(candidate, error?.code || 'startup_failed');
|
|
498
582
|
else factoryPromise.then((adapter) => cleanupCandidate(adapter, error?.code || 'startup_failed')).catch(() => {});
|
|
499
583
|
}
|
|
500
|
-
|
|
501
|
-
record,
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
584
|
+
if (failAs === 'interrupted') {
|
|
585
|
+
await this._fail(record, error, 'resume_failed', { status: 'interrupted' });
|
|
586
|
+
} else {
|
|
587
|
+
await this._fail(
|
|
588
|
+
record,
|
|
589
|
+
error,
|
|
590
|
+
error?.code === 'NATIVE_LOOP_PROVIDER_START_TIMEOUT' ? 'provider_startup_timeout' : 'provider_error',
|
|
591
|
+
);
|
|
592
|
+
}
|
|
505
593
|
} finally {
|
|
506
594
|
await finishBootstrap();
|
|
507
595
|
// Re-throw so record.bootstrap rejects with the original startup error.
|
|
@@ -516,15 +604,147 @@ export class NativeLoopRuntime {
|
|
|
516
604
|
// timer holds the process until cleanup. Swallow the unhandled rejection
|
|
517
605
|
// here because callers that care must await record.bootstrap explicitly.
|
|
518
606
|
bootstrap.catch(() => {});
|
|
607
|
+
return bootstrap;
|
|
608
|
+
}
|
|
519
609
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
610
|
+
/**
|
|
611
|
+
* Continue a suspended run (a dispatched worker a server restart cut off; assistant-dispatch.js resumeRun) as the
|
|
612
|
+
* same record: its runId, tab, claim, title and startedAt stay, its version keeps growing. The state file is written
|
|
613
|
+
* again at iteration 0 of 1, so the drive runs the run's one task iteration again (the dispatcher's wrapper decides
|
|
614
|
+
* what that turn sends), and the provider factory gets what `state` carries to continue the provider session
|
|
615
|
+
* (resumeSessionId, costBaseUsd). Resolves with the descriptor once the provider started; a provider that cannot
|
|
616
|
+
* start ends the run as interrupted (resume_failed) and the promise rejects with why.
|
|
617
|
+
*/
|
|
618
|
+
async resume({ runId, state, buildPrompt = null, wrapAdapter = null } = {}) {
|
|
619
|
+
const record = this.records.get(runId);
|
|
620
|
+
if (!record) throw new Error(`Native loop ${runId} is not known`);
|
|
621
|
+
if (record.status !== 'suspended') throw new Error(`Native loop ${runId} is ${record.status}, not suspended`);
|
|
622
|
+
if (buildPrompt !== null && typeof buildPrompt !== 'function') throw new Error('Native loop buildPrompt override must be a function');
|
|
623
|
+
if (wrapAdapter !== null && typeof wrapAdapter !== 'function') throw new Error('Native loop wrapAdapter override must be a function');
|
|
624
|
+
if (!state?.profile || !isNativeLoopProfile(state.profile)) throw new Error(`Unsupported native loop profile: ${state?.profile || 'unknown'}`);
|
|
625
|
+
const factory = this.providerFactories[state.profile];
|
|
626
|
+
if (!factory) throw new Error(`Native provider unavailable: ${state.profile}`);
|
|
627
|
+
this._clearHold(record);
|
|
628
|
+
mkdirSync(this.stateDir, { recursive: true });
|
|
629
|
+
const totalIterations = Number(state.totalIterations) || 1;
|
|
630
|
+
const nativeState = {
|
|
631
|
+
...toolListRecord(state, this.toolListOptions()),
|
|
632
|
+
runId,
|
|
633
|
+
terminalSessionId: runId,
|
|
634
|
+
active: true,
|
|
635
|
+
pending: false,
|
|
636
|
+
driverType: 'native',
|
|
637
|
+
runtimeType: 'native',
|
|
638
|
+
surface: 'sidepanel',
|
|
639
|
+
startedAt: record.startedAt || state.startedAt || iso(this.now()),
|
|
640
|
+
currentIteration: 0,
|
|
641
|
+
totalIterations,
|
|
642
|
+
};
|
|
643
|
+
this._writeState(runId, nativeState);
|
|
644
|
+
Object.assign(record, {
|
|
645
|
+
status: 'starting',
|
|
646
|
+
stoppedReason: null,
|
|
647
|
+
completedAt: null,
|
|
648
|
+
error: null,
|
|
649
|
+
adapter: null,
|
|
650
|
+
timer: null,
|
|
651
|
+
execution: null,
|
|
652
|
+
stopping: false,
|
|
653
|
+
startupAbortController: new AbortController(),
|
|
654
|
+
turnState: 'starting',
|
|
655
|
+
currentIteration: 0,
|
|
656
|
+
totalIterations,
|
|
657
|
+
browserSessionId: state.browserSessionId || null,
|
|
658
|
+
browserTabId: state.browserTabId || null,
|
|
659
|
+
suspendedAt: null,
|
|
660
|
+
suspendReason: null,
|
|
661
|
+
...(typeof state.antigravityHome === "string" && state.antigravityHome ? { antigravityHome: state.antigravityHome } : {}),
|
|
662
|
+
resumes: (Number(record.resumes) || 0) + 1,
|
|
663
|
+
resumedAt: iso(this.now()),
|
|
664
|
+
buildPrompt,
|
|
665
|
+
wrapAdapter,
|
|
666
|
+
});
|
|
667
|
+
record.identityPromise = new Promise((resolveIdentity) => { record._resolveIdentity = resolveIdentity; });
|
|
668
|
+
record.startupCancelPromise = new Promise((resolveCancel) => { record._cancelStartup = resolveCancel; });
|
|
669
|
+
this._emit('sidepanel:run-updated', record, { reason: 'resuming' });
|
|
670
|
+
await this._bootstrap(record, factory, nativeState, { profile: state.profile, failAs: 'interrupted' });
|
|
525
671
|
return cleanDescriptor(record);
|
|
526
672
|
}
|
|
527
673
|
|
|
674
|
+
/** The hold of a run the restart cut off: it ends as interrupted when nobody resumes it in time. */
|
|
675
|
+
_hold(record) {
|
|
676
|
+
this._clearHold(record);
|
|
677
|
+
const timer = setTimeout(() => {
|
|
678
|
+
this._holdTimers.delete(record.runId);
|
|
679
|
+
this.endSuspended(record.runId, record.suspendReason || 'server_restart').catch(() => {});
|
|
680
|
+
}, this.resumeHoldMs);
|
|
681
|
+
timer.unref?.();
|
|
682
|
+
this._holdTimers.set(record.runId, timer);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
_clearHold(record) {
|
|
686
|
+
const timer = this._holdTimers.get(record?.runId);
|
|
687
|
+
if (timer) { clearTimeout(timer); this._holdTimers.delete(record.runId); }
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/** Whether a run waits for its resume after a restart (suspended). */
|
|
691
|
+
isSuspended(runId) {
|
|
692
|
+
return this.records.get(runId)?.status === 'suspended';
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* The dispatcher takes a suspended run over (it resumes it or ends it itself): its hold no longer ends it.
|
|
697
|
+
* Returns whether the run is suspended.
|
|
698
|
+
*/
|
|
699
|
+
keepSuspended(runId) {
|
|
700
|
+
const record = this.records.get(runId);
|
|
701
|
+
if (!record || record.status !== 'suspended') return false;
|
|
702
|
+
this._clearHold(record);
|
|
703
|
+
return true;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* A suspended run that will not be resumed ends as interrupted (`reason`, by default why it was suspended), with an
|
|
708
|
+
* event, so a tab that waited for its resume shows how it ended. `error`: why it was not resumed.
|
|
709
|
+
*/
|
|
710
|
+
async endSuspended(runId, reason = null, { error = null } = {}) {
|
|
711
|
+
const record = this.records.get(runId);
|
|
712
|
+
if (!record || record.status !== 'suspended') return false;
|
|
713
|
+
this._clearHold(record);
|
|
714
|
+
record.status = 'interrupted';
|
|
715
|
+
record.stoppedReason = reason || record.suspendReason || 'server_restart';
|
|
716
|
+
record.completedAt = iso(this.now());
|
|
717
|
+
if (error) record.error = String(error);
|
|
718
|
+
this._writeTerminalState(record, { active: false, pending: false, completedAt: record.completedAt, stoppedReason: record.stoppedReason, ...(error ? { error: record.error } : {}) });
|
|
719
|
+
this._releaseRuntimeRefs(record);
|
|
720
|
+
this._emit('sidepanel:run-stopped', record);
|
|
721
|
+
try { await this.onFinish(cleanDescriptor(record)); } catch {}
|
|
722
|
+
return true;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Suspend a running dispatched worker for a server shutdown (shutdown's `keep`): its CLI is ended (the adapter's
|
|
727
|
+
* dispose with terminate), its state file stays active, and the record waits as suspended for the next start to
|
|
728
|
+
* resume it. No run-stopped event and no end: a run-updated with the reason 'suspended'.
|
|
729
|
+
*/
|
|
730
|
+
async suspend(runId, reason = 'server_shutdown') {
|
|
731
|
+
const record = this.records.get(runId);
|
|
732
|
+
if (!record || !['starting', 'running'].includes(record.status) || record.stopping) return false;
|
|
733
|
+
record.stopping = true;
|
|
734
|
+
clearTimeout(record.timer);
|
|
735
|
+
record.status = 'suspended';
|
|
736
|
+
record.suspendedAt = iso(this.now());
|
|
737
|
+
record.suspendReason = reason;
|
|
738
|
+
if (record._resolveIdentity) { record._resolveIdentity(null); record._resolveIdentity = null; }
|
|
739
|
+
try { record.startupAbortController?.abort(reason); } catch {}
|
|
740
|
+
if (record._cancelStartup) { record._cancelStartup(reason); record._cancelStartup = null; }
|
|
741
|
+
try { await record.adapter?.dispose?.({ preserveSession: true, terminate: true }); } catch {}
|
|
742
|
+
this._releaseRuntimeRefs(record, { turnState: 'suspended' });
|
|
743
|
+
record.stopping = false;
|
|
744
|
+
this._emit('sidepanel:run-updated', record, { reason: 'suspended' });
|
|
745
|
+
return true;
|
|
746
|
+
}
|
|
747
|
+
|
|
528
748
|
async _drive(record) {
|
|
529
749
|
let failures = 0;
|
|
530
750
|
while (this.isAlive(record.runId)) {
|
|
@@ -618,7 +838,7 @@ export class NativeLoopRuntime {
|
|
|
618
838
|
}
|
|
619
839
|
}
|
|
620
840
|
|
|
621
|
-
_releaseRuntimeRefs(record) {
|
|
841
|
+
_releaseRuntimeRefs(record, { turnState = 'terminal' } = {}) {
|
|
622
842
|
if (!record) return;
|
|
623
843
|
record.adapter = null;
|
|
624
844
|
record.timer = null;
|
|
@@ -630,7 +850,9 @@ export class NativeLoopRuntime {
|
|
|
630
850
|
record.startupAbortController = null;
|
|
631
851
|
record.buildPrompt = null;
|
|
632
852
|
record.wrapAdapter = null;
|
|
633
|
-
|
|
853
|
+
record.pendingRequests = [];
|
|
854
|
+
if (turnState === 'suspended') record.turnState = 'suspended';
|
|
855
|
+
else if (record.turnState && record.turnState !== 'terminal') record.turnState = 'terminal';
|
|
634
856
|
}
|
|
635
857
|
|
|
636
858
|
async _complete(record, reason = 'completed') {
|
|
@@ -646,10 +868,11 @@ export class NativeLoopRuntime {
|
|
|
646
868
|
try { await this.onFinish(cleanDescriptor(record)); } catch {}
|
|
647
869
|
}
|
|
648
870
|
|
|
649
|
-
|
|
650
|
-
|
|
871
|
+
/** `status`: 'failed', or 'interrupted' for a resume that could not start (reason resume_failed). */
|
|
872
|
+
async _fail(record, error, reason = 'provider_error', { status = 'failed' } = {}) {
|
|
873
|
+
if (!record || ['completed', 'failed', 'stopped', 'interrupted', 'suspended'].includes(record.status)) return;
|
|
651
874
|
clearTimeout(record.timer);
|
|
652
|
-
record.status = 'failed';
|
|
875
|
+
record.status = status === 'interrupted' ? 'interrupted' : 'failed';
|
|
653
876
|
record.error = error?.message || String(error);
|
|
654
877
|
record.stoppedReason = reason;
|
|
655
878
|
record.completedAt = iso(this.now());
|
|
@@ -660,12 +883,27 @@ export class NativeLoopRuntime {
|
|
|
660
883
|
try { await record.adapter?.abort?.(reason); } catch {}
|
|
661
884
|
try { await record.adapter?.dispose?.({ preserveSession: true }); } catch {}
|
|
662
885
|
this._releaseRuntimeRefs(record);
|
|
663
|
-
this._emit('sidepanel:run-failed', record);
|
|
886
|
+
this._emit(record.status === 'interrupted' ? 'sidepanel:run-stopped' : 'sidepanel:run-failed', record);
|
|
664
887
|
try { await this.onFinish(cleanDescriptor(record)); } catch {}
|
|
665
888
|
}
|
|
666
889
|
|
|
667
|
-
|
|
890
|
+
/**
|
|
891
|
+
* `terminate` (a server shutdown): the provider's process is ended at once (the Claude adapter's dispose), never
|
|
892
|
+
* left to finish its tool call after the server is gone. A suspended run (waiting for its resume) ends as stopped.
|
|
893
|
+
*/
|
|
894
|
+
async stop(runId, reason = 'user', { terminate = false } = {}) {
|
|
668
895
|
const record = this.records.get(runId);
|
|
896
|
+
if (record?.status === 'suspended' && !record.stopping) {
|
|
897
|
+
this._clearHold(record);
|
|
898
|
+
record.status = 'stopped';
|
|
899
|
+
record.stoppedReason = reason;
|
|
900
|
+
record.completedAt = iso(this.now());
|
|
901
|
+
this._writeTerminalState(record, { active: false, pending: false, completedAt: record.completedAt, stoppedReason: reason });
|
|
902
|
+
this._releaseRuntimeRefs(record);
|
|
903
|
+
this._emit('sidepanel:run-stopped', record);
|
|
904
|
+
try { await this.onFinish(cleanDescriptor(record)); } catch {}
|
|
905
|
+
return true;
|
|
906
|
+
}
|
|
669
907
|
if (!record || !['starting', 'running'].includes(record.status) || record.stopping) return false;
|
|
670
908
|
record.stopping = true;
|
|
671
909
|
clearTimeout(record.timer);
|
|
@@ -677,7 +915,7 @@ export class NativeLoopRuntime {
|
|
|
677
915
|
if (record._cancelStartup) { record._cancelStartup(reason); record._cancelStartup = null; }
|
|
678
916
|
this._writeTerminalState(record, { active: false, pending: false, completedAt: record.completedAt, stoppedReason: reason });
|
|
679
917
|
try { await record.adapter?.abort?.(reason); } catch {}
|
|
680
|
-
try { await record.adapter?.dispose?.({ preserveSession: true }); } catch {}
|
|
918
|
+
try { await record.adapter?.dispose?.({ preserveSession: true, ...(terminate ? { terminate: true } : {}) }); } catch {}
|
|
681
919
|
this._releaseRuntimeRefs(record);
|
|
682
920
|
this._emit('sidepanel:run-stopped', record);
|
|
683
921
|
try { await this.onFinish(cleanDescriptor(record)); } catch {}
|
|
@@ -735,19 +973,21 @@ export class NativeLoopRuntime {
|
|
|
735
973
|
return released;
|
|
736
974
|
}
|
|
737
975
|
|
|
738
|
-
|
|
976
|
+
setTools(runId, tools) {
|
|
739
977
|
const record = this.records.get(runId);
|
|
740
|
-
|
|
741
|
-
if (!
|
|
742
|
-
|
|
743
|
-
record.
|
|
978
|
+
if (!record) return null;
|
|
979
|
+
if (!Array.isArray(tools)) throw Object.assign(new Error('tools must be an array'), { code: 'TOOLS_INVALID', status: 400 });
|
|
980
|
+
const normalized = storedToolList({ tools: retainExternalRefs(tools, record.tools) });
|
|
981
|
+
if (JSON.stringify(record.tools) === JSON.stringify(normalized)) return cleanDescriptor(record);
|
|
982
|
+
record.tools = normalized;
|
|
983
|
+
delete record.mcpProfile;
|
|
744
984
|
try {
|
|
745
985
|
const state = this._readState(record.runId);
|
|
746
|
-
if (state) this._writeState(record.runId, { ...state,
|
|
986
|
+
if (state) this._writeState(record.runId, { ...state, tools: normalized });
|
|
747
987
|
} catch (error) {
|
|
748
988
|
this.log(record.runId, 'native:state-write-error', error?.message || String(error));
|
|
749
989
|
}
|
|
750
|
-
return this._emit('sidepanel:run-updated', record, { reason: 'mcp-
|
|
990
|
+
return this._emit('sidepanel:run-updated', record, { reason: 'mcp-tools' });
|
|
751
991
|
}
|
|
752
992
|
|
|
753
993
|
get(runId) {
|
|
@@ -757,15 +997,23 @@ export class NativeLoopRuntime {
|
|
|
757
997
|
|
|
758
998
|
list({ activeOnly = false } = {}) {
|
|
759
999
|
return [...this.records.values()]
|
|
760
|
-
.filter((record) => !activeOnly ||
|
|
1000
|
+
.filter((record) => !activeOnly || LIVE_STATUSES.has(record.status))
|
|
761
1001
|
.map(cleanDescriptor)
|
|
762
1002
|
.sort((a, b) => String(b.startedAt || '').localeCompare(String(a.startedAt || '')));
|
|
763
1003
|
}
|
|
764
1004
|
|
|
765
|
-
|
|
1005
|
+
/**
|
|
1006
|
+
* The server is going down. `keep`: the runs its dispatcher suspends to resume on the next start
|
|
1007
|
+
* (assistant-dispatch.js suspendForShutdown); every other running run is stopped. Either way each provider process
|
|
1008
|
+
* is ended now (terminate), so nothing outlives the server. A run still waiting for its resume stays suspended.
|
|
1009
|
+
*/
|
|
1010
|
+
async shutdown(reason = 'server_shutdown', { keep = [] } = {}) {
|
|
1011
|
+
const kept = new Set((Array.isArray(keep) ? keep : []).map(String));
|
|
766
1012
|
await Promise.allSettled([...this.records.values()]
|
|
767
1013
|
.filter((record) => ['starting', 'running'].includes(record.status))
|
|
768
|
-
.map((record) => this.stop(record.runId, reason)));
|
|
1014
|
+
.map((record) => (kept.has(record.runId) ? this.suspend(record.runId, reason) : this.stop(record.runId, reason, { terminate: true }))));
|
|
1015
|
+
for (const timer of this._holdTimers.values()) clearTimeout(timer);
|
|
1016
|
+
this._holdTimers.clear();
|
|
769
1017
|
this._persistLedger({ force: true });
|
|
770
1018
|
}
|
|
771
1019
|
}
|