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
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SynaBun Neural Interface — the notice after an automatic restart: what it says
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// When SynaBun's server crashes after it was up, its supervisor starts it again
|
|
6
|
+
// and leaves the new server a record of the crash (lib/server-crash-record.js,
|
|
7
|
+
// GET /api/system/crash-notice). The owner's pages say so until it is dismissed:
|
|
8
|
+
// that the server stopped unexpectedly and was restarted, when and how it ended,
|
|
9
|
+
// and what the restart ended. This module decides the words; ui-crash-notice.js
|
|
10
|
+
// asks the server and draws them.
|
|
11
|
+
//
|
|
12
|
+
// What the restart ends is what the code does when the server process dies and
|
|
13
|
+
// a new one starts, nothing more:
|
|
14
|
+
// - terminals: the pty host ends with the server and kills its shells
|
|
15
|
+
// (lib/pty-host/host.js on 'disconnect'); a new host has none of them
|
|
16
|
+
// - runs: dispatched worker runs and native loops that were running are marked
|
|
17
|
+
// interrupted at boot (lib/assistant-dispatch.js, lib/native-loop-runtime.js);
|
|
18
|
+
// Quick Timers, schedule timers set for later and the schedule queue live in
|
|
19
|
+
// memory; saved schedules keep firing. The program a run had started is not
|
|
20
|
+
// always ended with the server: on macOS and Linux a CLI whose input is not
|
|
21
|
+
// the server's (`claude -p`, `codex exec`) ends at its next write to the
|
|
22
|
+
// server, and on Windows one started through a shell is not in the server's
|
|
23
|
+
// job: hence "a step already under way may still finish"
|
|
24
|
+
// - replies: a Claude Code, Codex or Assistant turn in progress is gone, the
|
|
25
|
+
// conversation stays and the next message resumes it (an OpenCode serve that
|
|
26
|
+
// outlived the server may be adopted and go on: hence "may have been")
|
|
27
|
+
// - browser: the sessions SynaBun drove live in memory; their profiles stay
|
|
28
|
+
// - public address: cloudflared is not started again, a new start gets a new
|
|
29
|
+
// one. Windows ends it with the server (its job); on macOS and Linux it
|
|
30
|
+
// outlives a crash, and the new server ends it by its record at start
|
|
31
|
+
// (server.js sweepLeftoverTunnels). One it could not end is `tunnel:
|
|
32
|
+
// 'unknown'` in the notice, and the notice says the address may still be open
|
|
33
|
+
//
|
|
34
|
+
// No imports and no DOM: `node --test` loads this file as it is
|
|
35
|
+
// (tests/crash-notice-view.test.mjs). CRASH_NOTICE_COPY is the English of every
|
|
36
|
+
// sentence; `crashNotice.*` in i18n/en.json must equal it and i18n/pt-BR.json
|
|
37
|
+
// must have the same keys.
|
|
38
|
+
|
|
39
|
+
export const CRASH_NOTICE_COPY = Object.freeze({
|
|
40
|
+
title: 'SynaBun\'s server stopped unexpectedly and was restarted automatically.',
|
|
41
|
+
whenToday: 'It happened at {time}.',
|
|
42
|
+
whenEarlier: 'It happened on {date} at {time}.',
|
|
43
|
+
whenManyToday: 'It happened {count} times, the last at {time}.',
|
|
44
|
+
whenManyEarlier: 'It happened {count} times, the last on {date} at {time}.',
|
|
45
|
+
how: 'How it ended: {exit}.',
|
|
46
|
+
lostTitle: 'What the restart ended',
|
|
47
|
+
lostTerminals: 'Open terminals were closed.',
|
|
48
|
+
lostRuns: 'Agent runs and loops that were running were interrupted, though a step already under way may still finish on its own. Timers and queued runs were cleared. Saved schedules keep running.',
|
|
49
|
+
lostReplies: 'Replies being written in the side panels or the Assistant may have been cut off. The conversations are kept: send again what did not finish.',
|
|
50
|
+
lostBrowser: 'Browser sessions SynaBun was driving ended. Their saved sign-ins are kept.',
|
|
51
|
+
lostTunnel: 'The public address, if it was on, is off. Turning it on again gives a new address.',
|
|
52
|
+
lostTunnelUnknown: 'The public address, if it was on, may still be open: SynaBun could not end the cloudflared that served it. Ending that process, or restarting the computer, closes it.',
|
|
53
|
+
openLogs: 'Open logs',
|
|
54
|
+
openLogsFailed: 'The logs folder could not be opened.',
|
|
55
|
+
dismiss: 'Dismiss',
|
|
56
|
+
label: 'Server restarted after a crash',
|
|
57
|
+
exitCode: 'exit code {code}',
|
|
58
|
+
exitText: '{status}, {kind}',
|
|
59
|
+
kindNativeCrash: 'native crash',
|
|
60
|
+
kindOutOfMemory: 'out of memory',
|
|
61
|
+
kindNodeFatal: 'Node.js fatal error',
|
|
62
|
+
kindError: 'stopped by an error',
|
|
63
|
+
kindKilled: 'ended by force',
|
|
64
|
+
kindInterrupted: 'interrupted',
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
/** The order the notice lists what the restart ended (the last: lostTunnelUnknown for a notice whose `tunnel` is 'unknown'). */
|
|
68
|
+
export const CRASH_NOTICE_LOST = Object.freeze(['lostTerminals', 'lostRuns', 'lostReplies', 'lostBrowser', 'lostTunnel']);
|
|
69
|
+
|
|
70
|
+
/** The word for each kind lib/server-exit.js names; a kind without one shows the status alone. */
|
|
71
|
+
export const CRASH_KIND_KEYS = Object.freeze({
|
|
72
|
+
'native-crash': 'kindNativeCrash',
|
|
73
|
+
'out-of-memory': 'kindOutOfMemory',
|
|
74
|
+
'node-fatal': 'kindNodeFatal',
|
|
75
|
+
error: 'kindError',
|
|
76
|
+
killed: 'kindKilled',
|
|
77
|
+
interrupted: 'kindInterrupted',
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
/** A sentence of CRASH_NOTICE_COPY in English with its {values} filled; an unknown key is itself. */
|
|
81
|
+
export function fillCrashNoticeCopy(key, params = {}) {
|
|
82
|
+
const text = Object.prototype.hasOwnProperty.call(CRASH_NOTICE_COPY, key) ? CRASH_NOTICE_COPY[key] : key;
|
|
83
|
+
return text.replace(/\{(\w+)\}/g, (whole, name) => (params[name] != null ? String(params[name]) : whole));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const ID = /^[0-9a-f]{16}$/;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The notice in an answer of GET /api/system/crash-notice (or a `crash-notice:changed`
|
|
90
|
+
* message: both carry `notice`), checked field by field; null when there is none.
|
|
91
|
+
* `tunnel: 'unknown'` is there only when the server could not end the crashed
|
|
92
|
+
* server's cloudflared.
|
|
93
|
+
*/
|
|
94
|
+
export function readCrashNotice(answer) {
|
|
95
|
+
const notice = answer && typeof answer === 'object' ? answer.notice : null;
|
|
96
|
+
if (!notice || typeof notice !== 'object' || Array.isArray(notice)) return null;
|
|
97
|
+
if (typeof notice.id !== 'string' || !ID.test(notice.id)) return null;
|
|
98
|
+
const at = Number(notice.at);
|
|
99
|
+
if (!Number.isFinite(at) || at <= 0) return null;
|
|
100
|
+
const exit = notice.exit && typeof notice.exit === 'object' && !Array.isArray(notice.exit) ? notice.exit : {};
|
|
101
|
+
return {
|
|
102
|
+
id: notice.id,
|
|
103
|
+
at,
|
|
104
|
+
count: Number.isInteger(notice.count) && notice.count > 0 ? Math.min(notice.count, 999) : 1,
|
|
105
|
+
exit: {
|
|
106
|
+
hex: typeof exit.hex === 'string' && /^0x[0-9a-f]{8}$/i.test(exit.hex) ? `0x${exit.hex.slice(2).toUpperCase()}` : '',
|
|
107
|
+
signal: typeof exit.signal === 'string' && /^SIG[A-Z0-9]{1,10}$/.test(exit.signal) ? exit.signal : '',
|
|
108
|
+
code: Number.isInteger(exit.code) ? exit.code : null,
|
|
109
|
+
kind: typeof exit.kind === 'string' && /^[a-z][a-z-]{0,23}$/.test(exit.kind) ? exit.kind : '',
|
|
110
|
+
},
|
|
111
|
+
...(notice.tunnel === 'unknown' ? { tunnel: 'unknown' } : {}),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** How it ended in the reader's words ("0xC0000409, native crash"), or '' when the record names nothing. */
|
|
116
|
+
export function crashExitWords(exit, t = fillCrashNoticeCopy) {
|
|
117
|
+
if (!exit || typeof exit !== 'object') return '';
|
|
118
|
+
const status = exit.hex || exit.signal || (Number.isInteger(exit.code) ? t('exitCode', { code: exit.code }) : '');
|
|
119
|
+
if (!status) return '';
|
|
120
|
+
const key = CRASH_KIND_KEYS[exit.kind];
|
|
121
|
+
return key ? t('exitText', { status, kind: t(key) }) : status;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** When it happened, in the reader's locale: { today, date, time } (the date is for another day). */
|
|
125
|
+
export function crashTimeParts(at, { now = Date.now(), locale = undefined } = {}) {
|
|
126
|
+
const when = new Date(at);
|
|
127
|
+
if (!Number.isFinite(when.getTime())) return null;
|
|
128
|
+
const day = new Date(now);
|
|
129
|
+
const today = when.getFullYear() === day.getFullYear() && when.getMonth() === day.getMonth() && when.getDate() === day.getDate();
|
|
130
|
+
const format = (fn, options, fallback) => { try { return fn.call(when, locale, options); } catch { return fallback; } };
|
|
131
|
+
return {
|
|
132
|
+
today,
|
|
133
|
+
date: format(Date.prototype.toLocaleDateString, { dateStyle: 'medium' }, when.toISOString().slice(0, 10)),
|
|
134
|
+
time: format(Date.prototype.toLocaleTimeString, { hour: '2-digit', minute: '2-digit' }, when.toISOString().slice(11, 16)),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* What the notice shows, or null: { id, label, title, when, how, lostTitle, lost[], actions[] }.
|
|
140
|
+
* `t(key, params)` is a sentence of CRASH_NOTICE_COPY in the page's language; `canOpenLogs`
|
|
141
|
+
* says whether this page can open the logs folder (the desktop app, or a page on this computer).
|
|
142
|
+
*/
|
|
143
|
+
export function crashNoticeView(notice, { t = fillCrashNoticeCopy, now = Date.now(), locale = undefined, canOpenLogs = false } = {}) {
|
|
144
|
+
if (!notice || typeof notice !== 'object' || !notice.id) return null;
|
|
145
|
+
const parts = crashTimeParts(notice.at, { now, locale }) || { today: true, date: '', time: '' };
|
|
146
|
+
const many = notice.count > 1;
|
|
147
|
+
const whenKey = `${many ? 'whenMany' : 'when'}${parts.today ? 'Today' : 'Earlier'}`;
|
|
148
|
+
const exit = crashExitWords(notice.exit, t);
|
|
149
|
+
return {
|
|
150
|
+
id: notice.id,
|
|
151
|
+
label: t('label'),
|
|
152
|
+
title: t('title'),
|
|
153
|
+
when: t(whenKey, { count: notice.count, date: parts.date, time: parts.time }),
|
|
154
|
+
how: exit ? t('how', { exit }) : '',
|
|
155
|
+
lostTitle: t('lostTitle'),
|
|
156
|
+
lost: CRASH_NOTICE_LOST.map((key) => t(key === 'lostTunnel' && notice.tunnel === 'unknown' ? 'lostTunnelUnknown' : key)),
|
|
157
|
+
actions: [
|
|
158
|
+
...(canOpenLogs ? [{ id: 'logs', label: t('openLogs') }] : []),
|
|
159
|
+
{ id: 'dismiss', label: t('dismiss') },
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** True for a page served from this computer's loopback address: the only one the logs folder opens for. */
|
|
165
|
+
export function isLoopbackHost(hostname) {
|
|
166
|
+
const host = String(hostname || '').toLowerCase().replace(/^\[|\]$/g, '');
|
|
167
|
+
return host === 'localhost' || host === '::1' || /^127(?:\.\d{1,3}){3}$/.test(host);
|
|
168
|
+
}
|
|
@@ -48,3 +48,20 @@ export function desktopWindow(win = globalThis.window) {
|
|
|
48
48
|
if (!facts || facts.style !== 'overlay' || !['darwin', 'win32', 'linux'].includes(facts.platform)) return null;
|
|
49
49
|
return api;
|
|
50
50
|
}
|
|
51
|
+
|
|
52
|
+
/** True on Windows (desktop bridge platform `'win32'`, or Windows browser/window navigator). */
|
|
53
|
+
export function isWindowsPlatform(win = globalThis.window) {
|
|
54
|
+
const platform = desktopBridge(win)?.platform;
|
|
55
|
+
if (typeof platform === 'string' && platform) return platform === 'win32';
|
|
56
|
+
try {
|
|
57
|
+
const nav = win?.navigator ?? globalThis.navigator;
|
|
58
|
+
if (!nav || typeof nav !== 'object') return false;
|
|
59
|
+
const uaPlatform = nav.userAgentData?.platform;
|
|
60
|
+
if (typeof uaPlatform === 'string' && uaPlatform) return /^win/i.test(uaPlatform);
|
|
61
|
+
if (typeof nav.platform === 'string' && nav.platform) return /^win/i.test(nav.platform);
|
|
62
|
+
if (typeof nav.userAgent === 'string' && nav.userAgent) return /\bwindows\b/i.test(nav.userAgent);
|
|
63
|
+
} catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
@@ -197,3 +197,15 @@ export function drawnUnderBar(style, barLevel) {
|
|
|
197
197
|
const level = Number.isFinite(z) ? (positioned ? z : Math.max(z, 0)) : 0;
|
|
198
198
|
return level < barLevel;
|
|
199
199
|
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* True for a body-level overlay that never receives pointer events on itself or any child (such as `.ui-tooltip` or
|
|
203
|
+
* `#synabun-desktop-drag-strip`), so its hover/move mutations can never cover the bar's drag region.
|
|
204
|
+
*/
|
|
205
|
+
export function isPassiveOverlay(node) {
|
|
206
|
+
if (!node || typeof node !== 'object') return false;
|
|
207
|
+
if (node.id === 'synabun-desktop-drag-strip') return true;
|
|
208
|
+
if (typeof node.classList?.contains === 'function' && node.classList.contains('ui-tooltip')) return true;
|
|
209
|
+
const cls = typeof node.className === 'string' ? node.className : '';
|
|
210
|
+
return /(?:^|\s)ui-tooltip(?:\s|$)/.test(cls);
|
|
211
|
+
}
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
import { desktopWindow } from './desktop-bridge.js';
|
|
29
29
|
import { colorSender, textTone } from './desktop-titlebar-page.js';
|
|
30
|
-
import { barCovered, changedClasses, drawnUnderBar, fallbackTitlebarArea, overlayColorsFor, stackLevel, styleChange, titleBarActive } from './desktop-titlebar-view.js';
|
|
30
|
+
import { barCovered, changedClasses, drawnUnderBar, fallbackTitlebarArea, isPassiveOverlay, overlayColorsFor, stackLevel, styleChange, titleBarActive } from './desktop-titlebar-view.js';
|
|
31
31
|
import { t } from './i18n.js';
|
|
32
32
|
|
|
33
33
|
const MENU_ICON = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16"/><path d="M4 12h16"/><path d="M4 17h16"/></svg>';
|
|
@@ -52,6 +52,7 @@ export function initDesktopTitleBar({ doc = document, view = window } = {}) {
|
|
|
52
52
|
const facts = api.titleBar;
|
|
53
53
|
const html = doc.documentElement;
|
|
54
54
|
html.classList.add('desktop-titlebar', `desktop-titlebar--${facts.platform}`);
|
|
55
|
+
if (facts.platform === 'win32') html.classList.add('platform-win32');
|
|
55
56
|
const wco = view.navigator?.windowControlsOverlay || null;
|
|
56
57
|
let state = { maximized: false, fullScreen: false, focused: true };
|
|
57
58
|
const send = colorSender(api, doc);
|
|
@@ -168,14 +169,22 @@ export function initDesktopTitleBar({ doc = document, view = window } = {}) {
|
|
|
168
169
|
return null;
|
|
169
170
|
};
|
|
170
171
|
const hasElement = (nodes) => { for (const node of nodes || []) if (node?.nodeType === 1) return true; return false; };
|
|
172
|
+
const onlyPassiveElements = (nodes) => {
|
|
173
|
+
for (const node of nodes || []) if (node?.nodeType === 1 && !isPassiveOverlay(node)) return false;
|
|
174
|
+
return true;
|
|
175
|
+
};
|
|
171
176
|
// Each change → [IGNORE | SOON | NOW, whether the bar has to be measured].
|
|
172
177
|
const QUIET = [IGNORE, false];
|
|
173
178
|
const childListChange = (record) => {
|
|
174
179
|
if (!hasElement(record.addedNodes) && !hasElement(record.removedNodes)) return QUIET; // text
|
|
175
180
|
const target = record.target;
|
|
176
|
-
if (target === body) {
|
|
181
|
+
if (target === body) {
|
|
182
|
+
if (onlyPassiveElements(record.addedNodes) && onlyPassiveElements(record.removedNodes)) return QUIET;
|
|
183
|
+
judgeAgain();
|
|
184
|
+
return [NOW, true]; // an overlay's root; a sibling selector may match anew
|
|
185
|
+
}
|
|
177
186
|
const part = partOf(target);
|
|
178
|
-
if (!part || part === bar) return QUIET; // off the page,
|
|
187
|
+
if (!part || part === bar || isPassiveOverlay(part)) return QUIET; // off the page, passive tooltip, or inside the bar
|
|
179
188
|
toJudge.add(part);
|
|
180
189
|
if (target === part) return [NOW, true]; // an overlay's root got or lost a child (:empty, :has() can show it)
|
|
181
190
|
return [SOON, !underBar.has(part)];
|
|
@@ -189,7 +198,7 @@ export function initDesktopTitleBar({ doc = document, view = window } = {}) {
|
|
|
189
198
|
return [NOW, true];
|
|
190
199
|
}
|
|
191
200
|
const part = partOf(target);
|
|
192
|
-
if (!part) return QUIET;
|
|
201
|
+
if (!part || isPassiveOverlay(part)) return QUIET;
|
|
193
202
|
if (part === bar) return target === bar ? [NOW, true] : QUIET;
|
|
194
203
|
toJudge.add(part);
|
|
195
204
|
// Shown, hidden or restacked: on the next frame; only moved, sized or repainted: at the throttled pace. Inside a
|
|
@@ -76,6 +76,10 @@ export const DESKTOP_COPY = Object.freeze({
|
|
|
76
76
|
metaReadyOff: 'Ready to install',
|
|
77
77
|
metaCountdown: 'Restarting to install it',
|
|
78
78
|
metaPostponed: 'Postponed: installs on quit or later',
|
|
79
|
+
// The button at the top right while a downloaded update waits for a restart, as Discord's green one.
|
|
80
|
+
restartButton: 'Restart to update',
|
|
81
|
+
restartTooltip: 'SynaBun v{latest} is ready: restart to update',
|
|
82
|
+
restartSoon: 'Restarting soon',
|
|
79
83
|
}),
|
|
80
84
|
// What an update waits for (the app's server names it, GET /api/system/activity).
|
|
81
85
|
busy: Object.freeze({
|
|
@@ -83,6 +87,7 @@ export const DESKTOP_COPY = Object.freeze({
|
|
|
83
87
|
'claude-panel': 'a Claude Code panel reply',
|
|
84
88
|
'codex-panel': 'a Codex panel reply',
|
|
85
89
|
'opencode-panel': 'an OpenCode panel reply',
|
|
90
|
+
'antigravity-panel': 'an Antigravity panel reply',
|
|
86
91
|
'claude-cli': 'a Claude Code session in use',
|
|
87
92
|
loop: 'a loop',
|
|
88
93
|
schedule: 'a schedule',
|
|
@@ -422,6 +427,22 @@ export function desktopUpdateTooltip(state, { t = fillDesktopCopy } = {}) {
|
|
|
422
427
|
return t('update.tooltip', params);
|
|
423
428
|
}
|
|
424
429
|
|
|
430
|
+
/**
|
|
431
|
+
* The top right button while a downloaded update waits for a restart into it, or null: { label, tooltip, asked }.
|
|
432
|
+
* Only an update this copy installs by restarting (not one to move to Applications or to install by hand). After
|
|
433
|
+
* Restart to update, while something still runs, it says that the restart is coming (`asked`).
|
|
434
|
+
*/
|
|
435
|
+
export function desktopRestartButton(state, { t = fillDesktopCopy } = {}) {
|
|
436
|
+
const s = readDesktopUpdateState(state);
|
|
437
|
+
if (desktopUpdateStep(s) !== 'downloaded' || s.install !== 'restart' || s.manualFile) return null;
|
|
438
|
+
const asked = s.auto?.now === true;
|
|
439
|
+
return {
|
|
440
|
+
label: t(asked ? 'update.restartSoon' : 'update.restartButton'),
|
|
441
|
+
tooltip: t('update.restartTooltip', { latest: s.latest || '', current: s.current }),
|
|
442
|
+
asked,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
|
|
425
446
|
/**
|
|
426
447
|
* The notice at the bottom right, or null:
|
|
427
448
|
* countdown SynaBun is idle and restarts into the update: the seconds left, and Later
|
|
@@ -80,9 +80,9 @@ export function matchesExpectedMarkdown(content, expected) {
|
|
|
80
80
|
return String(content).replace(/\r\n/g, '\n') === expected.replace(/\r\n/g, '\n');
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
/** Whether a path is the user's OpenCode configuration file. */
|
|
83
|
+
/** Whether a path is the user's OpenCode configuration file (OpenCode 2's opencode.json or opencode.jsonc). */
|
|
84
84
|
export function isOpencodeConfigPath(path) {
|
|
85
|
-
return String(path || '').replace(/\\/g, '/')
|
|
85
|
+
return /\/\.config\/opencode\/opencode\.jsonc?$/.test(String(path || '').replace(/\\/g, '/'));
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
const OUTSIDE_ROOTS = 'Path outside registered project roots';
|
|
@@ -96,15 +96,15 @@ export function createExplorerApi({ fetchImpl = (...args) => fetch(...args), Eve
|
|
|
96
96
|
return old.ok ? fromLegacySearch(old) : old;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
async function git(root) {
|
|
99
|
+
async function git(root, signal, refresh = false) {
|
|
100
100
|
await capabilities();
|
|
101
|
-
if (caps.explorer) return request(`/api/explorer/git?root=${encodeURIComponent(root)}
|
|
102
|
-
const old = await request(`/api/git/status?path=${encodeURIComponent(root)}
|
|
101
|
+
if (caps.explorer) return request(`/api/explorer/git?root=${encodeURIComponent(root)}${refresh ? '&refresh=1' : ''}`, { signal });
|
|
102
|
+
const old = await request(`/api/git/status?path=${encodeURIComponent(root)}${refresh ? '&refresh=1' : ''}`, { signal });
|
|
103
103
|
if (!old.ok) return old;
|
|
104
104
|
if (!old.isGit) return { ok: true, isGit: false };
|
|
105
105
|
const changes = {};
|
|
106
106
|
for (const change of old.changes || []) if (change?.path) changes[change.path] = change.status;
|
|
107
|
-
return { ok: true, isGit: true, branch: old.branch || '', changes, ignored: [], legacy: true };
|
|
107
|
+
return { ok: true, isGit: true, branch: old.branch || '', changes, ignored: [], legacy: true, ...(old.partial ? { partial: true, scanState: old.scanState } : {}) };
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
async function create(parent, name, type) {
|
|
@@ -110,13 +110,13 @@ export function createEditorLink({ openFile, save, tabs, repoint, subscribe, onC
|
|
|
110
110
|
|
|
111
111
|
// ── The agents ──
|
|
112
112
|
|
|
113
|
-
export const SEND_TARGETS = Object.freeze(['claude', 'codex', 'opencode', 'assistant']);
|
|
114
|
-
const TARGET_NAMES = { claude: 'Claude Code', codex: 'Codex', opencode: 'OpenCode' };
|
|
113
|
+
export const SEND_TARGETS = Object.freeze(['claude', 'codex', 'opencode', 'antigravity', 'assistant']);
|
|
114
|
+
const TARGET_NAMES = { claude: 'Claude Code', codex: 'Codex', opencode: 'OpenCode', antigravity: 'Antigravity' };
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
117
|
* @param {object} o
|
|
118
118
|
* @param {object} o.deps what each panel offers: `sendToFocusedSession(kind, data)`, `claude(path)`, `codex(path)`,
|
|
119
|
-
* `opencode(path)`, `assistant(path)`, and `lastActive()` (the panel used last)
|
|
119
|
+
* `opencode(path)`, `antigravity(path)`, `assistant(path)`, and `lastActive()` (the panel used last)
|
|
120
120
|
* @param {(key: string, params?: object) => string} o.t
|
|
121
121
|
*/
|
|
122
122
|
export function createSender({ deps, t }) {
|
|
@@ -56,7 +56,7 @@ export function sameListing(a, b) {
|
|
|
56
56
|
if (!a || !b || a.length !== b.length) return false;
|
|
57
57
|
for (let i = 0; i < a.length; i++) {
|
|
58
58
|
const x = a[i]; const y = b[i];
|
|
59
|
-
if (x.name !== y.name || x.type !== y.type || x.size !== y.size || x.mtime !== y.mtime || !!x.link !== !!y.link || !!x.outside !== !!y.outside || !!x.broken !== !!y.broken) return false;
|
|
59
|
+
if (x.name !== y.name || x.type !== y.type || x.size !== y.size || x.mtime !== y.mtime || !!x.link !== !!y.link || !!x.outside !== !!y.outside || !!x.broken !== !!y.broken || !!x.ignored !== !!y.ignored || (x.ignored === null) !== (y.ignored === null)) return false;
|
|
60
60
|
}
|
|
61
61
|
return true;
|
|
62
62
|
}
|
|
@@ -48,7 +48,9 @@ const EXPAND_LEVEL_MAX = 200;
|
|
|
48
48
|
* @param {object} host.send what each side panel offers for a path (fx-links.js createSender)
|
|
49
49
|
* @param {(name: string) => object} host.fileIcon @param {string} host.folderSvg
|
|
50
50
|
* @param {{ all: { hex: string, key: string }[], of: (path: string) => string | undefined, set: Function, move: Function }} host.colors
|
|
51
|
-
* @param {(git: { isGit: boolean, branch: string, count: number
|
|
51
|
+
* @param {(git: { isGit: boolean, branch: string, count: number, scanState?: 'ready' | 'scanning' | 'timed-out' | 'failed',
|
|
52
|
+
* shown?: boolean, loud?: boolean }) => void} host.onGit `shown`: a result of this project is already on screen;
|
|
53
|
+
* `loud`: the scan is the project's first or one the owner asked for (Refresh), not a background one.
|
|
52
54
|
* @param {() => void} host.addProject
|
|
53
55
|
* @param {typeof fetch} [host.fetchImpl]
|
|
54
56
|
*/
|
|
@@ -77,7 +79,10 @@ export function createExplorer(host) {
|
|
|
77
79
|
let watcher = null;
|
|
78
80
|
let saidLimited = false; // this project was told once that not everything on disk is followed
|
|
79
81
|
let loaded = Promise.resolve();
|
|
80
|
-
let gitTimer = 0; let
|
|
82
|
+
let gitTimer = 0; let gitRequest = null; let gitRefresh = false; let gitAgain = false; let lastGitAt = 0;
|
|
83
|
+
// gitShown: a result of this project is on screen. gitLoud: the owner asked (Refresh), so a slow scan may say so.
|
|
84
|
+
// gitSettled: the last state a scan ended in, put back when a scan that said 'scanning' is called off.
|
|
85
|
+
let gitShown = false; let gitLoud = false; let gitSettled = 'ready';
|
|
81
86
|
let diskTimer = 0; let lastDiskAt = 0; const diskDue = new Set();
|
|
82
87
|
let filterTimer = 0; let searchAbort = null;
|
|
83
88
|
let persistTimer = 0; let lastFocusRefresh = 0;
|
|
@@ -114,18 +119,20 @@ export function createExplorer(host) {
|
|
|
114
119
|
const ed = editor.state();
|
|
115
120
|
const status = item.missing ? 'deleted' : S.git.statusOf(below, isDir);
|
|
116
121
|
const tone = item.missing ? 'deleted' : S.git.toneOf(below, isDir);
|
|
117
|
-
const ignored = S.git.isIgnored(below);
|
|
122
|
+
const ignored = !!item.ignored || S.git.isIgnored(below);
|
|
123
|
+
const ignoreUnknown = item.ignored === null && !ignored;
|
|
118
124
|
const open = !isDir && ed.open.has(path);
|
|
119
125
|
const dirty = !isDir && ed.dirty.has(path);
|
|
120
126
|
const cut = !!S.clipboard && S.clipboard.mode === 'cut' && S.clipboard.paths.some((held) => isWithin(held, path));
|
|
121
127
|
const words = [];
|
|
122
128
|
if (status) words.push(t(`fileExplorer.git.${status}`)); else if (tone) words.push(t('fileExplorer.git.contains'));
|
|
123
129
|
if (ignored) words.push(t('fileExplorer.git.ignored'));
|
|
130
|
+
else if (ignoreUnknown) words.push(t('fileExplorer.git.ignoreUnknown'));
|
|
124
131
|
if (dirty) words.push(t('fileExplorer.row.unsaved')); else if (open) words.push(t('fileExplorer.row.open'));
|
|
125
132
|
if (item.outside) words.push(t('fileExplorer.row.linkOutside')); else if (item.broken) words.push(t('fileExplorer.row.linkBroken')); else if (item.link) words.push(t('fileExplorer.row.link'));
|
|
126
133
|
if (cut) words.push(t('fileExplorer.row.cut'));
|
|
127
134
|
return {
|
|
128
|
-
tone, letter: status ? GIT_MARKS[status].letter : '', ignored, open, dirty, cut, words,
|
|
135
|
+
tone, letter: status ? GIT_MARKS[status].letter : '', ignored, ignoreUnknown, open, dirty, cut, words,
|
|
129
136
|
active: !isDir && ed.active === path,
|
|
130
137
|
missing: !!item.missing,
|
|
131
138
|
faint: !!item.outside || !!item.broken,
|
|
@@ -296,24 +303,46 @@ export function createExplorer(host) {
|
|
|
296
303
|
|
|
297
304
|
// ── Git ──
|
|
298
305
|
|
|
306
|
+
function cancelGit() {
|
|
307
|
+
clearTimeout(gitTimer);
|
|
308
|
+
gitRequest?.controller.abort();
|
|
309
|
+
gitRequest = null; gitAgain = false; gitRefresh = false; gitLoud = false;
|
|
310
|
+
}
|
|
299
311
|
async function loadGit() {
|
|
300
|
-
if (!S.root) return;
|
|
301
|
-
if (
|
|
302
|
-
|
|
312
|
+
if (!S.root || !S.visible) return;
|
|
313
|
+
if (gitRequest?.root === S.root) { gitAgain = true; return; }
|
|
314
|
+
gitRequest?.controller.abort();
|
|
315
|
+
const request = { root: S.root, controller: new AbortController() };
|
|
316
|
+
gitRequest = request;
|
|
303
317
|
const mine = epoch;
|
|
304
|
-
const
|
|
305
|
-
|
|
318
|
+
const refresh = gitRefresh; gitRefresh = false;
|
|
319
|
+
// A background scan (the watcher, focus, the popover) never puts words in the header while a result is shown:
|
|
320
|
+
// only the first scan of a project, or one the owner asked for, is loud.
|
|
321
|
+
const loud = gitLoud || !gitShown; gitLoud = false;
|
|
322
|
+
let said = '';
|
|
323
|
+
const say = (scanState) => { said = scanState; host.onGit({ ...gitState(scanState), loud }); };
|
|
324
|
+
const slow = setTimeout(() => { if (gitRequest === request && mine === epoch) say('scanning'); }, 1500);
|
|
325
|
+
const got = await api.git(request.root, request.controller.signal, refresh);
|
|
326
|
+
clearTimeout(slow);
|
|
327
|
+
if (gitRequest !== request) return;
|
|
328
|
+
gitRequest = null;
|
|
306
329
|
if (mine === epoch && got.ok) {
|
|
307
|
-
S.git = gitIndex(got);
|
|
308
|
-
|
|
330
|
+
if (!got.partial || !S.git.isGit) S.git = gitIndex(got);
|
|
331
|
+
gitShown = true;
|
|
332
|
+
say(gitSettled = got.scanState || 'ready');
|
|
309
333
|
if (S.changedOnly) { buildView(); tree.render(); } else tree.refreshRows();
|
|
310
334
|
updateCount();
|
|
311
|
-
}
|
|
335
|
+
} else if (mine === epoch && got.code !== 'aborted') say(gitSettled = 'failed');
|
|
336
|
+
else if (mine === epoch && said === 'scanning') say(gitSettled);
|
|
312
337
|
if (gitAgain) { gitAgain = false; queueGit(); }
|
|
313
338
|
}
|
|
339
|
+
function gitState(scanState) {
|
|
340
|
+
return { isGit: S.git.isGit, branch: S.git.branch, count: S.git.count, scanState, shown: gitShown };
|
|
341
|
+
}
|
|
314
342
|
// Soon after the last sign of a change, and never more often than once in a while: a file that is written
|
|
315
343
|
// without pause (a log, a database) does not make git run without pause.
|
|
316
344
|
function queueGit() {
|
|
345
|
+
if (!S.root || !S.visible) return;
|
|
317
346
|
clearTimeout(gitTimer);
|
|
318
347
|
gitTimer = setTimeout(() => { lastGitAt = Date.now(); loadGit(); }, Math.max(GIT_DELAY_MS, lastGitAt + GIT_MIN_INTERVAL_MS - Date.now()));
|
|
319
348
|
}
|
|
@@ -654,7 +683,7 @@ export function createExplorer(host) {
|
|
|
654
683
|
case 'sortBy': return [back(), ...SORTS.map((mode) => ({ id: `sort:${mode}`, label: t(`fileExplorer.menu.sort.${mode}`), checked: S.sort === mode }))];
|
|
655
684
|
case 'expandAll': expandLevel(); break;
|
|
656
685
|
case 'collapseAll': collapseAll(); break;
|
|
657
|
-
case 'refresh': refreshAll(); break;
|
|
686
|
+
case 'refresh': gitRefresh = true; gitLoud = true; refreshAll(); break;
|
|
658
687
|
default:
|
|
659
688
|
}
|
|
660
689
|
return undefined;
|
|
@@ -739,7 +768,7 @@ export function createExplorer(host) {
|
|
|
739
768
|
});
|
|
740
769
|
on('fe-collapse-all', collapseAll);
|
|
741
770
|
// Refresh also asks what the server has: one that was restarted since the page loaded is found out here.
|
|
742
|
-
on('fe-refresh', async () => { await host.readServer?.(); await api.capabilities(); syncToolbar(); await refreshAll(); if (!watcher) startWatch(); });
|
|
771
|
+
on('fe-refresh', async () => { gitRefresh = true; gitLoud = true; await host.readServer?.(); await api.capabilities(); syncToolbar(); await refreshAll(); if (!watcher) startWatch(); });
|
|
743
772
|
on('fe-more', (event) => { const box = event.currentTarget.getBoundingClientRect(); openMenu({ y: box.top + box.height / 2, keyboard: event.detail === 0 }); });
|
|
744
773
|
on('fe-filter-clear', () => { clearFilter(); filterInput.focus(); });
|
|
745
774
|
filterInput.addEventListener('input', () => setFilter(filterInput.value));
|
|
@@ -773,11 +802,13 @@ export function createExplorer(host) {
|
|
|
773
802
|
function setProject(project) {
|
|
774
803
|
persist();
|
|
775
804
|
epoch++;
|
|
805
|
+
cancelGit();
|
|
776
806
|
stopWatch();
|
|
777
807
|
saidLimited = false;
|
|
778
808
|
closeFlyout({ refocus: false });
|
|
779
809
|
searchAbort?.abort();
|
|
780
810
|
clearTimeout(gitTimer);
|
|
811
|
+
gitShown = false; gitSettled = 'ready';
|
|
781
812
|
S.dirs = new Map(); S.git = gitIndex(null); S.view = null; S.viewOpen = new Set(); S.viewClosed = new Set();
|
|
782
813
|
S.search = null; S.filter = ''; S.clipboard = null;
|
|
783
814
|
reads.clear();
|
|
@@ -824,7 +855,7 @@ export function createExplorer(host) {
|
|
|
824
855
|
/** The panel is shown or hidden: the disk is followed only while it is shown. */
|
|
825
856
|
function setVisible(visible) {
|
|
826
857
|
S.visible = !!visible;
|
|
827
|
-
if (S.visible) { if (S.root) { startWatch(); if (S.dirs.size) refreshAll(); } } else { persist(); stopWatch(); closeFlyout({ refocus: false }); }
|
|
858
|
+
if (S.visible) { if (S.root) { startWatch(); if (S.dirs.size) refreshAll(); } } else { persist(); cancelGit(); host.onGit(gitState(gitSettled)); stopWatch(); closeFlyout({ refocus: false }); }
|
|
828
859
|
}
|
|
829
860
|
|
|
830
861
|
/** Show a file of the project in the tree: its folders open, its row is selected and marked. */
|
|
@@ -850,7 +881,8 @@ export function createExplorer(host) {
|
|
|
850
881
|
setProject,
|
|
851
882
|
setVisible,
|
|
852
883
|
reveal,
|
|
853
|
-
|
|
884
|
+
/** Read the disk and git again. `quiet`: nobody asked for it in so many words (the git popover opened). */
|
|
885
|
+
refresh: ({ quiet = false } = {}) => { gitRefresh = true; if (!quiet) gitLoud = true; return refreshAll(); },
|
|
854
886
|
collapseAll,
|
|
855
887
|
/** The icons changed: every row is drawn again. */
|
|
856
888
|
redraw() { if (S.root) { const now = tree.selection(); const top = tree.scrollTop(); tree.setRoot(S.root); tree.render(); tree.select(now.selected, { focus: now.focus, quiet: true, scroll: false }); tree.setScrollTop(top); } },
|
|
@@ -161,6 +161,7 @@ export function createTree({ el, mac, icons, hooks }) {
|
|
|
161
161
|
node.classList.toggle('fe-node--selected', selected.has(path));
|
|
162
162
|
node.classList.toggle('fe-node--focus', focus === path);
|
|
163
163
|
node.classList.toggle('fe-node--ignored', !!info.ignored);
|
|
164
|
+
node.dataset.ignoreState = info.ignoreUnknown ? 'unknown' : info.ignored ? 'ignored' : 'known';
|
|
164
165
|
node.classList.toggle('fe-node--cut', !!info.cut);
|
|
165
166
|
node.classList.toggle('fe-node--open', !!info.open);
|
|
166
167
|
node.classList.toggle('fe-node--active', !!info.active);
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// SynaBun — Greeting: the card every surface mounts
|
|
3
3
|
// ═══════════════════════════════════════════
|
|
4
4
|
//
|
|
5
|
-
// One renderer for the greeting: the Assistant and the Claude Code, Codex
|
|
6
|
-
// OpenCode panels mount it inside the empty state they already have, Settings
|
|
5
|
+
// One renderer for the greeting: the Assistant and the Claude Code, Codex,
|
|
6
|
+
// OpenCode and Antigravity panels mount it inside the empty state they already have, Settings
|
|
7
7
|
// shows the same card as its preview. greeting-view.js decides the words; this
|
|
8
8
|
// file asks the server (`POST /api/greeting/open`) and draws.
|
|
9
9
|
//
|
|
@@ -41,6 +41,7 @@ export const GREETING_COPY = Object.freeze({
|
|
|
41
41
|
'agent.claude-code': 'Claude Code',
|
|
42
42
|
'agent.codex': 'Codex',
|
|
43
43
|
'agent.opencode': 'OpenCode',
|
|
44
|
+
'agent.antigravity': 'Antigravity',
|
|
44
45
|
open: 'Open memory',
|
|
45
46
|
'source.writer': 'Written ahead by {model}',
|
|
46
47
|
'source.fallback': 'Put together from the records, no model',
|