synabun 2.0.9 → 2.1.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 +115 -0
- package/README.md +25 -2
- package/THIRD-PARTY-LICENSES.md +68 -4
- package/bin/synabun.js +71 -24
- package/docs/whatsapp.md +2 -2
- 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/launcher.mjs +9 -3
- package/lib/claude-hooks.js +172 -18
- package/lib/client-config-repair.js +17 -8
- package/lib/desktop-app.js +7 -1
- package/lib/external-tools.js +1 -1
- 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 +43 -5
- package/lib/tools-cli.js +45 -0
- package/lib/update-snapshot.js +228 -0
- package/lib/virustotal.mjs +192 -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/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/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/neural-interface.d.ts +16 -10
- 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 +20 -62
- 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/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 +10 -10
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +22 -13
- 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/image-tools.d.ts +1 -1
- package/mcp-server/dist/tools/image-tools.js +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 +639 -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/codex-config-heal.ts +80 -29
- package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
- package/mcp-server/src/services/neural-interface.ts +79 -20
- package/mcp-server/src/services/server-instructions.ts +27 -63
- 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/whiteboard-geometry.ts +94 -9
- package/mcp-server/src/tools/agents.ts +22 -14
- package/mcp-server/src/tools/image-tools.ts +1 -1
- package/mcp-server/src/tools/skill-tools.ts +589 -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 +3680 -206
- package/neural-interface/i18n/pt-BR.json +3628 -157
- package/neural-interface/lib/account-usage.js +5 -3
- package/neural-interface/lib/app-controls-api.js +161 -0
- package/neural-interface/lib/assistant-api.js +148 -35
- 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 +122 -44
- package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +59 -0
- package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +97 -0
- package/neural-interface/lib/assistant-catalog.js +23 -9
- package/neural-interface/lib/assistant-dispatch.js +874 -156
- package/neural-interface/lib/assistant-envelope.js +22 -2
- package/neural-interface/lib/assistant-persona.js +80 -11
- package/neural-interface/lib/assistant-plan-permissions.js +10 -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 +13 -8
- package/neural-interface/lib/assistant-runtime.js +183 -26
- package/neural-interface/lib/assistant-task-prompt.js +78 -14
- package/neural-interface/lib/assistant-tools.js +51 -0
- package/neural-interface/lib/backup-service.js +620 -3
- 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 +83 -0
- package/neural-interface/lib/browser-network-guard.js +284 -0
- package/neural-interface/lib/browser-policy-roots.js +64 -0
- package/neural-interface/lib/browser-tool-policy.js +186 -31
- package/neural-interface/lib/claude-agent-bridge.js +4 -2
- package/neural-interface/lib/claude-hooks-status.js +103 -0
- package/neural-interface/lib/claude-model-catalog.js +64 -14
- package/neural-interface/lib/claude-temporary.js +5 -11
- package/neural-interface/lib/cli-install.js +18 -138
- package/neural-interface/lib/cli-resolver.js +4 -1
- package/neural-interface/lib/cli-update-planner.js +32 -31
- package/neural-interface/lib/cloudflared/tunnel.js +42 -2
- package/neural-interface/lib/codex-mcp-approvals.js +11 -0
- package/neural-interface/lib/codex-settings-schema.js +109 -47
- package/neural-interface/lib/codex-worker-app-server.js +172 -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 +164 -67
- package/neural-interface/lib/exec-loop-command.js +4 -1
- package/neural-interface/lib/http-guards.js +8 -2
- package/neural-interface/lib/install-details.js +4 -1
- package/neural-interface/lib/launch-cache.js +293 -0
- package/neural-interface/lib/login-start.js +524 -0
- package/neural-interface/lib/mcp-agent-servers.js +67 -0
- package/neural-interface/lib/mcp-client-config.js +0 -29
- package/neural-interface/lib/mcp-external-servers.js +323 -0
- package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
- package/neural-interface/lib/morelogin.js +30 -0
- package/neural-interface/lib/native-loop-providers.js +565 -50
- package/neural-interface/lib/native-loop-runtime.js +287 -41
- package/neural-interface/lib/opencode-config.js +557 -0
- package/neural-interface/lib/opencode-db-schema.js +58 -0
- package/neural-interface/lib/opencode-history.js +49 -204
- package/neural-interface/lib/opencode-mcp-ready.js +108 -0
- package/neural-interface/lib/opencode-native-boundary.js +44 -0
- package/neural-interface/lib/opencode-protocol.js +310 -0
- package/neural-interface/lib/opencode-provider-view.js +81 -0
- package/neural-interface/lib/opencode-runtime-config.js +32 -15
- package/neural-interface/lib/opencode-serve-records.js +624 -0
- package/neural-interface/lib/opencode-v2-client.js +53 -131
- package/neural-interface/lib/opencode-v2-ws-requests.js +35 -195
- package/neural-interface/lib/opencode-worker-activity.js +229 -0
- package/neural-interface/lib/opencode-worker-data.js +27 -0
- package/neural-interface/lib/opencode2-client.js +796 -0
- package/neural-interface/lib/opencode2-proxy.js +76 -0
- package/neural-interface/lib/opencode2-translate.js +1057 -0
- package/neural-interface/lib/owner-authority.js +249 -0
- package/neural-interface/lib/page-session.js +275 -0
- package/neural-interface/lib/peer-identity.js +763 -0
- package/neural-interface/lib/process-identity.js +361 -0
- package/neural-interface/lib/request-gate.js +17 -2
- package/neural-interface/lib/rulesets/api.js +1 -1
- package/neural-interface/lib/rulesets/fs-safe.js +1 -1
- package/neural-interface/lib/rulesets/installer.js +92 -27
- package/neural-interface/lib/rulesets/json-edit.js +1 -1
- package/neural-interface/lib/session-cache-builder.js +18 -10
- package/neural-interface/lib/session-title-generator.js +58 -18
- 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 +294 -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 +267 -0
- package/neural-interface/lib/skills/creation.js +843 -0
- package/neural-interface/lib/skills/deploy.js +564 -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 +214 -0
- package/neural-interface/lib/skills/eval-confinement.js +397 -0
- package/neural-interface/lib/skills/eval-sandbox.js +280 -0
- package/neural-interface/lib/skills/eval-trace.js +119 -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 +200 -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 +387 -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 +262 -0
- package/neural-interface/lib/skills/runtime-checks.js +355 -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 +522 -0
- package/neural-interface/lib/skills/telemetry.js +113 -0
- package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
- package/neural-interface/lib/style-guide/api.js +4 -3
- package/neural-interface/lib/tool-lists.js +124 -0
- package/neural-interface/lib/untrusted-file-headers.js +27 -0
- package/neural-interface/lib/whatsapp/bridge.js +6 -3
- package/neural-interface/lib/worker-confinement.js +1192 -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-relay-ports.js +227 -0
- package/neural-interface/lib/worker-resume.js +229 -0
- package/neural-interface/lib/worker-sandbox.js +299 -0
- package/neural-interface/package-lock.json +1354 -50
- package/neural-interface/package.json +6 -2
- package/neural-interface/public/index.html +5 -3
- package/neural-interface/public/index2d.html +19 -11
- package/neural-interface/public/onboarding.html +2 -2
- package/neural-interface/public/shared/account-menu.js +8 -5
- package/neural-interface/public/shared/agent-runtime-options.js +76 -16
- 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 +205 -19
- package/neural-interface/public/shared/assistant/asst-api.js +11 -3
- 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 +241 -112
- package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
- package/neural-interface/public/shared/assistant/asst-control.js +157 -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 +49 -2
- package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
- package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -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 +84 -12
- package/neural-interface/public/shared/assistant/asst-panel.js +303 -44
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +93 -58
- package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
- package/neural-interface/public/shared/assistant/asst-render.js +770 -100
- package/neural-interface/public/shared/assistant/asst-route.js +83 -12
- package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
- package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
- package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
- package/neural-interface/public/shared/assistant/asst-scenes.js +530 -0
- package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
- package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
- package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
- package/neural-interface/public/shared/assistant/asst-state.js +25 -15
- package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +102 -21
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +165 -13
- package/neural-interface/public/shared/automation-context.js +5 -2
- package/neural-interface/public/shared/cc-dropdown.js +550 -0
- 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 +8 -7
- package/neural-interface/public/shared/cdx/cdx-panel.js +58 -150
- package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
- package/neural-interface/public/shared/cdx/cdx-render.js +62 -32
- package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
- 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 +201 -74
- package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
- package/neural-interface/public/shared/cli-install-view.js +4 -8
- package/neural-interface/public/shared/cli-status.js +2 -2
- package/neural-interface/public/shared/constants.js +2 -2
- 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 +366 -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-markdown.js +4 -57
- package/neural-interface/public/shared/crash-notice-view.js +168 -0
- package/neural-interface/public/shared/data-cache.js +223 -0
- package/neural-interface/public/shared/desktop-bridge.js +11 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
- package/neural-interface/public/shared/desktop-titlebar.js +214 -28
- package/neural-interface/public/shared/desktop-update-view.js +35 -5
- package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
- package/neural-interface/public/shared/file-links.js +73 -8
- package/neural-interface/public/shared/html-shell.js +78 -86
- package/neural-interface/public/shared/i18n.js +2 -0
- package/neural-interface/public/shared/launch-prefetch.js +59 -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-caps.js +3 -2
- 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 +9 -2
- 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-modelpicker.js +54 -17
- 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 +140 -254
- package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +97 -203
- package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
- package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -22
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +20 -13
- 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 +53 -82
- 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 +48 -40
- 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 +205 -62
- package/neural-interface/public/shared/opencode-providers.js +39 -0
- package/neural-interface/public/shared/page-session.js +96 -0
- 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 +452 -0
- package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
- package/neural-interface/public/shared/settings/settings-app.js +243 -0
- package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
- package/neural-interface/public/shared/settings/settings-data.js +90 -0
- package/neural-interface/public/shared/settings/settings-ia.js +23 -6
- package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
- 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/sidepanel-session-status.js +49 -0
- package/neural-interface/public/shared/skills/ss-args.js +96 -0
- package/neural-interface/public/shared/skills/ss-creation.js +219 -0
- package/neural-interface/public/shared/skills/ss-dialog.js +130 -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 +141 -0
- package/neural-interface/public/shared/skills/ss-presets.js +117 -0
- package/neural-interface/public/shared/skills/ss-profiles.js +475 -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 +236 -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 +229 -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-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 +279 -0
- package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
- package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
- package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
- package/neural-interface/public/shared/skills/studio/sx-main.js +681 -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 +248 -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 +425 -0
- package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
- package/neural-interface/public/shared/styles.css +2065 -2150
- package/neural-interface/public/shared/synabun-mascot.js +1115 -9
- 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/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-assistant.js +27 -5
- package/neural-interface/public/shared/ui-automation-studio.js +155 -152
- package/neural-interface/public/shared/ui-bookmarks.js +2 -1
- package/neural-interface/public/shared/ui-claude-panel.js +153 -13
- package/neural-interface/public/shared/ui-codex-panel.js +1 -0
- 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 +21 -9
- package/neural-interface/public/shared/ui-file-links.js +1 -0
- package/neural-interface/public/shared/ui-image-gallery.js +56 -52
- package/neural-interface/public/shared/ui-invite.js +18 -2
- package/neural-interface/public/shared/ui-keybinds.js +26 -1
- package/neural-interface/public/shared/ui-link.js +9 -9
- package/neural-interface/public/shared/ui-menubar.js +229 -40
- package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
- package/neural-interface/public/shared/ui-native-loop-router.js +9 -1
- package/neural-interface/public/shared/ui-navbar.js +4 -24
- package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
- package/neural-interface/public/shared/ui-panels.js +96 -65
- package/neural-interface/public/shared/ui-schedules-studio.js +2267 -953
- package/neural-interface/public/shared/ui-sessions.js +20 -7
- package/neural-interface/public/shared/ui-settings.js +679 -496
- package/neural-interface/public/shared/ui-sidebar.js +4 -4
- package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +56 -5
- package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
- package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
- package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
- package/neural-interface/public/shared/ui-skills.js +42 -2781
- package/neural-interface/public/shared/ui-styleguide.js +5 -2
- package/neural-interface/public/shared/ui-sync.js +22 -5
- package/neural-interface/public/shared/ui-terminal.js +159 -199
- package/neural-interface/public/shared/ui-tool-updates.js +3 -1
- package/neural-interface/public/shared/ui-tooltip.js +10 -5
- package/neural-interface/public/shared/ui-trash.js +14 -5
- 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 -61
- package/neural-interface/public/shared/ui-tutorial.css +47 -100
- package/neural-interface/public/shared/ui-tutorial.js +285 -499
- package/neural-interface/public/shared/ui-update.js +121 -16
- package/neural-interface/public/shared/ui-whiteboard.js +313 -59
- package/neural-interface/public/shared/ui-worker-end.js +4 -0
- 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 +1 -1
- 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-restart.js +12 -0
- package/neural-interface/public/sidepanel-session.html +1 -1
- 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 +36 -2
- package/neural-interface/public/variant/2d/minimap.js +11 -13
- package/neural-interface/public/variant/3d/main.js +72 -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/highlight/LICENSE +29 -0
- package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
- package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
- package/neural-interface/public/vendor/highlight/manifest.json +5 -0
- package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
- package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
- package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
- package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
- package/neural-interface/public/vendor/marked/manifest.json +4 -0
- package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
- package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
- package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
- package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -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 +116 -3
- package/neural-interface/server.js +4834 -2541
- package/neural-interface/templates/rulesets/core.md +1 -1
- package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
- package/neural-interface/templates/rulesets/manifest.json +8 -8
- package/npm-shrinkwrap.json +18 -12
- package/package.json +16 -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 +5 -5
- 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
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SynaBun Neural Interface — Settings → Skills: the skill folders block
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// Under the skill chips: the move of SynaBun's old Codex prompt / OpenCode command bridges to native skill
|
|
6
|
+
// folders (review it, move them, undo the last move) and the switch that lets installs go into the shared
|
|
7
|
+
// ~/.agents/skills. Nothing moves when Settings opens: the owner reads the plan and presses Move (the server checks
|
|
8
|
+
// the plan's digest, installs the native folder first, keeps each bridge's bytes in the move's journal, and leaves
|
|
9
|
+
// every file that is not SynaBun's where it is). Words and states come from settings-skill-folders.js; requests
|
|
10
|
+
// carry the X-SynaBun-UI header the owner-only routes ask for (api.js). A change made anywhere else (another window,
|
|
11
|
+
// the Studio, an agent's submission, an install) reaches the block and the chips through `skills:changed`, in place,
|
|
12
|
+
// never under a plan the owner is reading.
|
|
13
|
+
|
|
14
|
+
import * as kit from './settings-kit.js';
|
|
15
|
+
import { chipState, installedToast, lastUndoable, readFoldersStatus, readMigrationOutcome, readMigrationPlan, readRevertOutcome, toggledAssistants } from './settings-skill-folders.js';
|
|
16
|
+
import { fetchClaudeCodeSkills, fetchSkillsConfig, fetchSkillsMigrations, fetchSkillsStatus, planSkillsBridgeMigration, planSkillsBridgeMigrationConfirmed, revertSkillsMigration, runSkillsBridgeMigration, saveSkillsConfig } from '../api.js';
|
|
17
|
+
import { on } from '../state.js';
|
|
18
|
+
|
|
19
|
+
export { chipState, installedToast };
|
|
20
|
+
|
|
21
|
+
const params = (p) => Object.fromEntries(Object.entries(p || {}).map(([k, v]) => [k, v && typeof v === 'object' && typeof v.key === 'string' ? kit.tx(v.key) : v]));
|
|
22
|
+
const say = (m) => (m ? kit.tx(m.key, params(m.params)) : '');
|
|
23
|
+
|
|
24
|
+
/** The block's markup (filled in by wireSkillFolders once the server answers). */
|
|
25
|
+
export function skillFoldersHTML() {
|
|
26
|
+
return `
|
|
27
|
+
<div class="stg-skill-folders" id="stg-skill-folders">
|
|
28
|
+
${kit.subhead(kit.te('settings.redesign.skills.folders.title'))}
|
|
29
|
+
<div class="stg-help" id="stg-skill-folders-status" role="status" aria-live="polite" style="margin-top:0">${kit.te('settings.redesign.skills.folders.loading')}</div>
|
|
30
|
+
<div class="stg-help" id="stg-skill-folders-others" hidden></div>
|
|
31
|
+
<ul class="stg-help" id="stg-skill-folders-plan" hidden></ul>
|
|
32
|
+
<div class="cc-skill-targets" role="group" id="stg-skill-folders-actions">
|
|
33
|
+
<button type="button" class="cc-skill-target" id="stg-skill-folders-review" hidden>${kit.te('settings.redesign.skills.folders.review')}</button>
|
|
34
|
+
<button type="button" class="cc-skill-target" id="stg-skill-folders-move" hidden>${kit.te('settings.redesign.skills.folders.move')}</button>
|
|
35
|
+
<button type="button" class="cc-skill-target" id="stg-skill-folders-cancel" hidden>${kit.te('settings.redesign.skills.folders.cancel')}</button>
|
|
36
|
+
<button type="button" class="cc-skill-target" id="stg-skill-folders-undo" hidden>${kit.te('settings.redesign.skills.folders.undo')}</button>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="cc-skill-row" id="stg-skill-folders-assistants" hidden>
|
|
39
|
+
<div class="cc-skill-info">
|
|
40
|
+
<span class="cc-skill-name">${kit.te('settings.redesign.skills.assistants.title')}</span>
|
|
41
|
+
<span class="cc-skill-desc" id="stg-skill-folders-assistants-help">${kit.te('settings.redesign.skills.assistants.help')}</span>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="cc-skill-targets" role="group" aria-label="${kit.te('settings.redesign.skills.assistants.title')}" id="stg-skill-folders-assistants-chips"></div>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="cc-skill-row" id="stg-skill-folders-shared" hidden>
|
|
46
|
+
<div class="cc-skill-info">
|
|
47
|
+
<span class="cc-skill-name">${kit.te('settings.redesign.skills.folders.sharedLabel')}</span>
|
|
48
|
+
<span class="cc-skill-desc">${kit.te('settings.redesign.skills.folders.sharedHelp')}</span>
|
|
49
|
+
</div>
|
|
50
|
+
<div class="cc-skill-targets"><button type="button" class="cc-skill-target" id="stg-skill-folders-shared-toggle" aria-pressed="false">${kit.te('settings.redesign.skills.folders.sharedOff')}</button></div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Read the skills again and redraw each runtime chip in place (its state, pressed, title). A chip that is being
|
|
57
|
+
* clicked is left to its own request.
|
|
58
|
+
* @param {HTMLElement} root the Settings overlay
|
|
59
|
+
*/
|
|
60
|
+
export async function refreshSkillChips(root) {
|
|
61
|
+
let skills;
|
|
62
|
+
try { skills = (await fetchClaudeCodeSkills())?.skills; } catch { return; }
|
|
63
|
+
if (!Array.isArray(skills)) return;
|
|
64
|
+
const byDir = new Map(skills.map((skill) => [skill.dirName, skill]));
|
|
65
|
+
for (const chip of root.querySelectorAll('.cc-skill-target[data-cc-skill][data-cc-target]')) {
|
|
66
|
+
const skill = byDir.get(chip.dataset.ccSkill);
|
|
67
|
+
if (!skill || chip.style.pointerEvents === 'none') continue;
|
|
68
|
+
const target = chip.dataset.ccTarget;
|
|
69
|
+
const installed = skill.installedTargets || { claude: !!skill.installed, codex: false, opencode: false };
|
|
70
|
+
const now = chipState(skill.targetStates?.[target], !!installed[target]);
|
|
71
|
+
chip.classList.toggle('on', now.on);
|
|
72
|
+
chip.dataset.state = now.on ? 'on' : 'off';
|
|
73
|
+
chip.dataset.installState = now.state;
|
|
74
|
+
chip.setAttribute('aria-pressed', now.on ? 'true' : 'false');
|
|
75
|
+
chip.title = kit.tx(now.key, { skill: skill.name || skill.dirName, assistant: chip.textContent.trim() });
|
|
76
|
+
const row = chip.closest('.cc-skill-row');
|
|
77
|
+
if (row) row.classList.toggle('installed', !!row.querySelector('.cc-skill-target.on'));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Fill the block in and wire its buttons.
|
|
83
|
+
* @param {HTMLElement} root the Settings overlay
|
|
84
|
+
* @param {{ toast?: (msg: string, ms?: number) => void, onChanged?: () => void, signal?: AbortSignal }} [o]
|
|
85
|
+
* `onChanged`: something here (or elsewhere) changed the skills; `signal`: the panel's life (its listeners end with it)
|
|
86
|
+
*/
|
|
87
|
+
export async function wireSkillFolders(root, { toast = () => {}, onChanged = () => {}, signal = null } = {}) {
|
|
88
|
+
const box = root.querySelector('#stg-skill-folders');
|
|
89
|
+
if (!box) return;
|
|
90
|
+
const $ = (id) => box.querySelector(`#${id}`);
|
|
91
|
+
const status = $('stg-skill-folders-status');
|
|
92
|
+
const others = $('stg-skill-folders-others');
|
|
93
|
+
const planList = $('stg-skill-folders-plan');
|
|
94
|
+
const review = $('stg-skill-folders-review');
|
|
95
|
+
const move = $('stg-skill-folders-move');
|
|
96
|
+
const cancel = $('stg-skill-folders-cancel');
|
|
97
|
+
const undo = $('stg-skill-folders-undo');
|
|
98
|
+
const shared = $('stg-skill-folders-shared');
|
|
99
|
+
const sharedToggle = $('stg-skill-folders-shared-toggle');
|
|
100
|
+
const assistantsRow = $('stg-skill-folders-assistants');
|
|
101
|
+
const assistantChips = $('stg-skill-folders-assistants-chips');
|
|
102
|
+
const assistantsHelp = $('stg-skill-folders-assistants-help');
|
|
103
|
+
let plan = null;
|
|
104
|
+
let undoable = null;
|
|
105
|
+
let working = false;
|
|
106
|
+
let assistants = null;
|
|
107
|
+
const ticked = new Set(); // the offered bridges the owner ticked ("Move it too")
|
|
108
|
+
|
|
109
|
+
const busy = (yes) => { working = yes; for (const b of [review, move, cancel, undo, sharedToggle, ...assistantChips.querySelectorAll('button'), ...planList.querySelectorAll('input')]) if (b) b.disabled = yes; };
|
|
110
|
+
const showPlan = (reading) => {
|
|
111
|
+
planList.replaceChildren(...reading.lines.map((line) => {
|
|
112
|
+
const li = document.createElement('li');
|
|
113
|
+
li.dataset.tone = line.tone;
|
|
114
|
+
if (line.offer) {
|
|
115
|
+
// A bridge file of a shipped skill that is not proven SynaBun's: moved only when the owner ticks it here.
|
|
116
|
+
const label = document.createElement('label');
|
|
117
|
+
label.className = 'stg-skill-folders-offer';
|
|
118
|
+
const box = document.createElement('input');
|
|
119
|
+
box.type = 'checkbox'; box.checked = !!line.offer.on; box.dataset.bridge = line.bridgeId; box.dataset.digest = line.offer.digest;
|
|
120
|
+
box.setAttribute('aria-label', kit.tx('settings.redesign.skills.folders.offerTick', { name: line.params.name }));
|
|
121
|
+
const text = document.createElement('span');
|
|
122
|
+
text.textContent = say(line);
|
|
123
|
+
label.append(box, text);
|
|
124
|
+
li.append(label);
|
|
125
|
+
} else li.textContent = say(line);
|
|
126
|
+
return li;
|
|
127
|
+
}));
|
|
128
|
+
planList.hidden = !reading.lines.length;
|
|
129
|
+
};
|
|
130
|
+
// A plan on screen: its lines, Move only when something would move, Cancel to put the block back.
|
|
131
|
+
const present = (next) => {
|
|
132
|
+
plan = next;
|
|
133
|
+
const reading = readMigrationPlan(plan, ticked);
|
|
134
|
+
showPlan(reading);
|
|
135
|
+
if (reading.empty) status.textContent = say(reading.empty);
|
|
136
|
+
move.hidden = reading.movable === 0;
|
|
137
|
+
cancel.hidden = false;
|
|
138
|
+
review.hidden = true;
|
|
139
|
+
};
|
|
140
|
+
// An offer ticked or unticked: the plan is asked again with the confirmations (a confirmed plan is another plan,
|
|
141
|
+
// taken by its own digest), and shown.
|
|
142
|
+
planList.addEventListener('change', async (e) => {
|
|
143
|
+
const box = e.target;
|
|
144
|
+
if (!box?.dataset?.bridge) return;
|
|
145
|
+
if (box.checked) ticked.add(box.dataset.bridge); else ticked.delete(box.dataset.bridge);
|
|
146
|
+
busy(true);
|
|
147
|
+
try {
|
|
148
|
+
const confirm = Object.fromEntries([...planList.querySelectorAll('input[data-bridge]')].filter((b) => ticked.has(b.dataset.bridge)).map((b) => [b.dataset.bridge, b.dataset.digest]));
|
|
149
|
+
present((await planSkillsBridgeMigrationConfirmed(confirm)).plan);
|
|
150
|
+
} catch (err) { toast(kit.tx('settings.redesign.skills.folders.failed', { message: err.message }), 6000); }
|
|
151
|
+
finally { busy(false); }
|
|
152
|
+
});
|
|
153
|
+
const drawAssistants = () => {
|
|
154
|
+
if (!assistants) { assistantsRow.hidden = true; return; }
|
|
155
|
+
assistantsRow.hidden = false;
|
|
156
|
+
assistantChips.replaceChildren(...assistants.chips.map((chip) => {
|
|
157
|
+
const b = document.createElement('button');
|
|
158
|
+
b.type = 'button';
|
|
159
|
+
b.className = `cc-skill-target${chip.on ? ' on' : ''}`;
|
|
160
|
+
b.dataset.assistant = chip.id;
|
|
161
|
+
b.setAttribute('aria-pressed', chip.on ? 'true' : 'false');
|
|
162
|
+
b.textContent = kit.tx(chip.key);
|
|
163
|
+
b.title = kit.tx(chip.on ? 'settings.redesign.skills.assistants.chipOn' : 'settings.redesign.skills.assistants.chipOff', { assistant: kit.tx(chip.key) });
|
|
164
|
+
return b;
|
|
165
|
+
}));
|
|
166
|
+
const detected = assistants.detectedWords.map((w) => kit.tx(w.key)).join(', ');
|
|
167
|
+
assistantsHelp.textContent = `${kit.tx('settings.redesign.skills.assistants.help')} ${kit.tx(assistants.auto ? 'settings.redesign.skills.assistants.detected' : 'settings.redesign.skills.assistants.chosen', { detected })}`;
|
|
168
|
+
if (!assistants.auto) {
|
|
169
|
+
const reset = document.createElement('button');
|
|
170
|
+
reset.type = 'button'; reset.className = 'cc-skill-target'; reset.dataset.assistant = 'auto';
|
|
171
|
+
reset.textContent = kit.tx('settings.redesign.skills.assistants.useDetected');
|
|
172
|
+
reset.title = kit.tx('settings.redesign.skills.assistants.detected', { detected });
|
|
173
|
+
assistantChips.append(reset);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
assistantChips.addEventListener('click', async (e) => {
|
|
177
|
+
const chip = e.target.closest?.('button[data-assistant]');
|
|
178
|
+
if (!chip || chip.disabled || !assistants) return;
|
|
179
|
+
const next = chip.dataset.assistant === 'auto' ? null : toggledAssistants(assistants.effective, chip.dataset.assistant);
|
|
180
|
+
busy(true);
|
|
181
|
+
try { await saveSkillsConfig({ assistants: next }); }
|
|
182
|
+
catch (err) { toast(kit.tx('settings.redesign.skills.folders.failed', { message: err.message }), 6000); }
|
|
183
|
+
finally { busy(false); }
|
|
184
|
+
await refresh();
|
|
185
|
+
});
|
|
186
|
+
async function refresh() {
|
|
187
|
+
let answer = null;
|
|
188
|
+
try { answer = await fetchSkillsStatus(); } catch { answer = null; }
|
|
189
|
+
const reading = readFoldersStatus(answer);
|
|
190
|
+
status.textContent = say(reading.message);
|
|
191
|
+
if (!reading.available) { for (const el of [others, planList, review, move, cancel, undo, shared, assistantsRow]) el.hidden = true; return; }
|
|
192
|
+
// The owner's assistants: the status carries them on a server with the preference; GET /config is the fuller read.
|
|
193
|
+
assistants = reading.assistants;
|
|
194
|
+
if (assistants) { try { const cfg = await fetchSkillsConfig(); if (cfg?.assistants) assistants = readFoldersStatus({ ok: true, bridges: {}, assistants: cfg.assistants }).assistants; } catch { /* the status' view */ } }
|
|
195
|
+
drawAssistants();
|
|
196
|
+
ticked.clear();
|
|
197
|
+
others.hidden = !reading.others;
|
|
198
|
+
others.textContent = say(reading.others);
|
|
199
|
+
review.hidden = !reading.canReview;
|
|
200
|
+
move.hidden = true; cancel.hidden = true; planList.hidden = true; plan = null;
|
|
201
|
+
shared.hidden = false;
|
|
202
|
+
sharedToggle.classList.toggle('on', reading.sharedAgentsRoot);
|
|
203
|
+
sharedToggle.setAttribute('aria-pressed', reading.sharedAgentsRoot ? 'true' : 'false');
|
|
204
|
+
sharedToggle.textContent = kit.tx(reading.sharedAgentsRoot ? 'settings.redesign.skills.folders.sharedOn' : 'settings.redesign.skills.folders.sharedOff');
|
|
205
|
+
try { undoable = lastUndoable((await fetchSkillsMigrations()).migrations); } catch { undoable = null; }
|
|
206
|
+
undo.hidden = !undoable;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
review.addEventListener('click', async () => {
|
|
210
|
+
busy(true);
|
|
211
|
+
try {
|
|
212
|
+
present((await planSkillsBridgeMigration()).plan);
|
|
213
|
+
} catch (err) { toast(kit.tx('settings.redesign.skills.folders.failed', { message: err.message }), 6000); }
|
|
214
|
+
finally { busy(false); }
|
|
215
|
+
});
|
|
216
|
+
cancel.addEventListener('click', () => refresh());
|
|
217
|
+
move.addEventListener('click', async () => {
|
|
218
|
+
const reading = readMigrationPlan(plan, ticked);
|
|
219
|
+
if (!reading.planDigest) return;
|
|
220
|
+
busy(true);
|
|
221
|
+
try {
|
|
222
|
+
const out = await runSkillsBridgeMigration(reading.planDigest, reading.confirm);
|
|
223
|
+
toast(say(readMigrationOutcome(out)), 8000);
|
|
224
|
+
onChanged();
|
|
225
|
+
} catch (err) {
|
|
226
|
+
// The bridges or their destinations changed since the plan was shown: nothing moved, the new plan is shown.
|
|
227
|
+
if (err.code === 'plan_changed' && err.body?.plan) { present(err.body.plan); toast(kit.tx('settings.redesign.skills.folders.planChanged'), 8000); return; }
|
|
228
|
+
toast(kit.tx('settings.redesign.skills.folders.failed', { message: err.message }), 6000);
|
|
229
|
+
} finally { busy(false); }
|
|
230
|
+
await refresh();
|
|
231
|
+
});
|
|
232
|
+
undo.addEventListener('click', async () => {
|
|
233
|
+
if (!undoable) return;
|
|
234
|
+
busy(true);
|
|
235
|
+
try {
|
|
236
|
+
const out = await revertSkillsMigration(undoable.journalId);
|
|
237
|
+
toast(say(readRevertOutcome(out)), 8000);
|
|
238
|
+
onChanged();
|
|
239
|
+
} catch (err) { toast(kit.tx('settings.redesign.skills.folders.failed', { message: err.message }), 6000); }
|
|
240
|
+
finally { busy(false); }
|
|
241
|
+
await refresh();
|
|
242
|
+
});
|
|
243
|
+
sharedToggle.addEventListener('click', async () => {
|
|
244
|
+
const next = sharedToggle.getAttribute('aria-pressed') !== 'true';
|
|
245
|
+
busy(true);
|
|
246
|
+
try { await saveSkillsConfig({ sharedAgentsRoot: next }); }
|
|
247
|
+
catch (err) { toast(kit.tx('settings.redesign.skills.folders.failed', { message: err.message }), 6000); }
|
|
248
|
+
finally { busy(false); }
|
|
249
|
+
await refresh();
|
|
250
|
+
});
|
|
251
|
+
// Changes from anywhere else: the chips follow at once; the block follows unless a plan is on screen or a request
|
|
252
|
+
// of its own is under way (a move is taken only by the digest of the plan shown, so a stale plan moves nothing).
|
|
253
|
+
let soon = 0;
|
|
254
|
+
const stop = on('sync:skills:changed', () => {
|
|
255
|
+
clearTimeout(soon);
|
|
256
|
+
soon = setTimeout(() => {
|
|
257
|
+
if (!box.isConnected) { stop(); return; }
|
|
258
|
+
onChanged();
|
|
259
|
+
if (!plan && !working) refresh();
|
|
260
|
+
}, 300);
|
|
261
|
+
});
|
|
262
|
+
signal?.addEventListener('abort', () => { stop(); clearTimeout(soon); }, { once: true });
|
|
263
|
+
if (signal?.aborted) { stop(); return; }
|
|
264
|
+
await refresh();
|
|
265
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SynaBun Neural Interface — Settings → Skills: skill folders, read (no DOM)
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// What the Skills Service says (GET /api/skills-studio/v2/status, the bridge migration's plan and outcome) turned
|
|
6
|
+
// into what Settings → Skills shows: whether the old Codex prompt / OpenCode command bridges can move to native
|
|
7
|
+
// skill folders, what each would do, the outcome of a move or an undo, the shared ~/.agents/skills switch, and
|
|
8
|
+
// each runtime chip's state (a native folder, an old bridge, someone else's folder). Every sentence is a
|
|
9
|
+
// settings.redesign.skills.* key; the pane (settings-skill-folders-pane.js) draws it.
|
|
10
|
+
|
|
11
|
+
const RUNTIME = { claude: 'settings.redesign.product.claude', codex: 'settings.redesign.product.codex', opencode: 'settings.redesign.product.opencode' };
|
|
12
|
+
|
|
13
|
+
/** What the status answer says, or that the server cannot say it yet (one from before the Skills Service). */
|
|
14
|
+
export function readFoldersStatus(answer) {
|
|
15
|
+
if (!answer || answer.ok !== true || !answer.bridges) return { available: false, message: { key: 'settings.redesign.skills.folders.unavailable' } };
|
|
16
|
+
const synabun = Number(answer.bridges.synabun) || 0;
|
|
17
|
+
const other = Number(answer.bridges.other) || 0;
|
|
18
|
+
return {
|
|
19
|
+
available: true,
|
|
20
|
+
sharedAgentsRoot: answer.config?.sharedAgentsRoot === true,
|
|
21
|
+
assistants: readAssistants(answer.assistants),
|
|
22
|
+
bridges: { synabun, other },
|
|
23
|
+
message: synabun === 0 ? { key: 'settings.redesign.skills.folders.bridgesNone' } : synabun === 1 ? { key: 'settings.redesign.skills.folders.bridgesOne' } : { key: 'settings.redesign.skills.folders.bridgesMany', params: { count: synabun } },
|
|
24
|
+
others: other === 0 ? null : other === 1 ? { key: 'settings.redesign.skills.folders.othersOne' } : { key: 'settings.redesign.skills.folders.othersMany', params: { count: other } },
|
|
25
|
+
canReview: synabun > 0,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const ASSISTANTS = ['claude', 'codex', 'opencode'];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The owner's assistants (GET /v2/config `assistants`: chosen, detected, effective): one chip per runtime, on when
|
|
33
|
+
* it is in effect, and whether the list is the detected one (nothing chosen yet). A server from before this has none.
|
|
34
|
+
*/
|
|
35
|
+
export function readAssistants(view) {
|
|
36
|
+
if (!view || !Array.isArray(view.effective)) return null;
|
|
37
|
+
const effective = view.effective.filter((r) => ASSISTANTS.includes(r));
|
|
38
|
+
const detected = (Array.isArray(view.detected) ? view.detected : []).filter((r) => ASSISTANTS.includes(r));
|
|
39
|
+
return {
|
|
40
|
+
auto: !Array.isArray(view.chosen),
|
|
41
|
+
effective, detected,
|
|
42
|
+
chips: ASSISTANTS.map((id) => ({ id, key: RUNTIME[id], on: effective.includes(id), detected: detected.includes(id) })),
|
|
43
|
+
detectedWords: detected.map((id) => ({ key: RUNTIME[id] })),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The list a chip's click sends (PUT /v2/config `assistants`): toggled, never empty (the last one stays on). */
|
|
48
|
+
export function toggledAssistants(effective, id) {
|
|
49
|
+
const now = (Array.isArray(effective) ? effective : []).filter((r) => ASSISTANTS.includes(r));
|
|
50
|
+
if (now.includes(id)) { const next = now.filter((r) => r !== id); return next.length ? next : now; }
|
|
51
|
+
return ASSISTANTS.filter((r) => now.includes(r) || r === id);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The lines of a migration plan, one per bridge of SynaBun's, and whether anything would move. The prompt and
|
|
56
|
+
* command files that are not SynaBun's are only counted (the status says how many): they are never moved, and a
|
|
57
|
+
* line each would bury the ones that are; except the bridge file of a skill SynaBun ships that is not proven its
|
|
58
|
+
* own (`offer`): that one is listed with a tick, "Move it too", and moves only once the owner confirms its bytes.
|
|
59
|
+
* @param {object} plan @param {Set<string>|string[]} [ticked] the offers the owner ticked (bridge ids)
|
|
60
|
+
*/
|
|
61
|
+
export function readMigrationPlan(plan, ticked = []) {
|
|
62
|
+
const steps = Array.isArray(plan?.steps) ? plan.steps : [];
|
|
63
|
+
const on = new Set(ticked);
|
|
64
|
+
const lines = steps.filter((s) => s.action !== 'leave' || s.proof !== 'none' || s.ledgerRecord || s.offer).map((s) => {
|
|
65
|
+
const params = { runtime: { key: RUNTIME[s.runtime] || RUNTIME.codex }, name: `/${s.name}`, destination: s.native?.destination || '', why: s.why || '' };
|
|
66
|
+
if (s.action === 'migrate') return { tone: 'ok', key: s.proof === 'owner-confirmed' ? 'settings.redesign.skills.folders.stepConfirmed' : 'settings.redesign.skills.folders.stepMigrate', params, bridgeId: s.bridgeId, offer: s.proof === 'owner-confirmed' ? { digest: s.digest, on: true } : null };
|
|
67
|
+
if (s.action === 'blocked') return { tone: 'warn', key: 'settings.redesign.skills.folders.stepBlocked', params };
|
|
68
|
+
if (s.offer) return { tone: 'offer', key: 'settings.redesign.skills.folders.stepOffer', params, bridgeId: s.bridgeId, offer: { digest: s.offer.digest, on: on.has(s.bridgeId) } };
|
|
69
|
+
return { tone: 'muted', key: 'settings.redesign.skills.folders.stepLeave', params };
|
|
70
|
+
});
|
|
71
|
+
const movable = steps.filter((s) => s.action === 'migrate').length;
|
|
72
|
+
const confirm = Object.fromEntries(steps.filter((s) => s.proof === 'owner-confirmed').map((s) => [s.bridgeId, s.digest]));
|
|
73
|
+
return { lines, movable, offered: steps.filter((s) => s.action === 'leave' && s.offer).length, confirm, planDigest: typeof plan?.planDigest === 'string' ? plan.planDigest : null, empty: movable === 0 ? { key: 'settings.redesign.skills.folders.nothing' } : null };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** What a move answered: done, in part (which and why), nothing to do. */
|
|
77
|
+
export function readMigrationOutcome(out) {
|
|
78
|
+
if (!out) return { tone: 'warn', key: 'settings.redesign.skills.folders.failed', params: { message: '' } };
|
|
79
|
+
if (out.nothingToDo) return { tone: 'muted', key: 'settings.redesign.skills.folders.nothing' };
|
|
80
|
+
if (out.status === 'done') return { tone: 'ok', key: 'settings.redesign.skills.folders.moved', params: { id: out.journalId } };
|
|
81
|
+
const failed = (out.results || []).filter((r) => r.outcome !== 'migrated').map((r) => `/${r.name}: ${r.error || r.outcome}`).join('; ');
|
|
82
|
+
if (out.status === 'failed') return { tone: 'warn', key: 'settings.redesign.skills.folders.failed', params: { message: failed } };
|
|
83
|
+
return { tone: 'warn', key: 'settings.redesign.skills.folders.movedPartly', params: { details: failed } };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** What an undo answered. */
|
|
87
|
+
export function readRevertOutcome(out) {
|
|
88
|
+
if (!out) return { tone: 'warn', key: 'settings.redesign.skills.folders.failed', params: { message: '' } };
|
|
89
|
+
if (out.status === 'reverted') return { tone: 'ok', key: 'settings.redesign.skills.folders.undone' };
|
|
90
|
+
const details = (out.results || []).filter((r) => r.bridge === 'conflict' || r.bridge === 'failed' || r.native === 'kept').map((r) => r.why || r.path).join('; ');
|
|
91
|
+
return { tone: 'warn', key: 'settings.redesign.skills.folders.undonePartly', params: { details } };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** The last move that can be undone, from GET /migrations (newest first). */
|
|
95
|
+
export function lastUndoable(list) {
|
|
96
|
+
const rows = (Array.isArray(list) ? list : []).filter((m) => m && (m.status === 'done' || m.status === 'partial' || m.status === 'partially-reverted') && m.migrated > 0);
|
|
97
|
+
rows.sort((a, b) => (a.createdAt < b.createdAt ? 1 : -1));
|
|
98
|
+
return rows[0] || null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* A runtime chip of a skill: its state (`native`: SynaBun's skill folder; `bridge`: an old bridge not moved yet;
|
|
103
|
+
* `shared`: SynaBun's copy in ~/.agents/skills, which Codex and OpenCode both read; `other`: a folder of that name
|
|
104
|
+
* SynaBun did not install, in the runtime's folder or the shared one; `installed`: a server from before the skill
|
|
105
|
+
* folders says only that it is there; `off`) and its title key.
|
|
106
|
+
* @param {object|undefined} state the skill's targetStates[runtime] from GET /api/skills
|
|
107
|
+
* @param {boolean} installed the older single flag (installedTargets[runtime])
|
|
108
|
+
*/
|
|
109
|
+
export function chipState(state, installed) {
|
|
110
|
+
if (!state) return installed ? { state: 'installed', on: true, key: 'settings.redesign.skills.chip.installed' } : { state: 'off', on: false, key: 'settings.redesign.skills.installFor' };
|
|
111
|
+
if (state.native === 'native' || state.native === 'modified') return { state: 'native', on: true, key: 'settings.redesign.skills.chip.native' };
|
|
112
|
+
if (state.bridge) return { state: 'bridge', on: true, key: 'settings.redesign.skills.chip.bridge' };
|
|
113
|
+
if (state.shared === 'native') return { state: 'shared', on: true, key: 'settings.redesign.skills.chip.shared' };
|
|
114
|
+
if (state.native === 'other') return { state: 'other', on: false, key: 'settings.redesign.skills.chip.other' };
|
|
115
|
+
if (state.shared === 'other') return { state: 'other', on: false, key: 'settings.redesign.skills.chip.otherShared' };
|
|
116
|
+
return { state: 'off', on: false, key: 'settings.redesign.skills.installFor' };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The toast after a chip installed a skill: a skill folder of its own, whether an old bridge of it is still there,
|
|
121
|
+
* and what the runtime needs to see it (`refresh` of the install answer: automatic, reload-skills, new-session).
|
|
122
|
+
*/
|
|
123
|
+
export function installedToast(answer) {
|
|
124
|
+
if (answer?.shared) return 'settings.redesign.skills.chip.installedShared';
|
|
125
|
+
if (answer?.bridge) return 'settings.redesign.skills.chip.installedBridgeLeft';
|
|
126
|
+
const kinds = new Set((Array.isArray(answer?.refresh) ? answer.refresh : []).map((r) => r?.kind));
|
|
127
|
+
if (kinds.has('new-session')) return 'settings.redesign.skills.chip.installedNewSession';
|
|
128
|
+
if (kinds.has('reload-skills')) return 'settings.redesign.skills.chip.installedReload';
|
|
129
|
+
return 'settings.redesign.skills.chip.installedNative';
|
|
130
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SETTINGS — Protect workers, in words
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// What `GET /api/assistant/worker-guard` (lib/assistant-api.js; the setting in lib/worker-guard-setting.js, what
|
|
6
|
+
// it means in lib/worker-confinement.js) says about Settings → Automations → Automation behavior → Protect
|
|
7
|
+
// workers: the mode in effect (enforce, warn, off), whether it can be changed, and what stands in the way. Pure:
|
|
8
|
+
// no DOM and no import, so node runs it (tests/settings-worker-guard-view.test.mjs).
|
|
9
|
+
//
|
|
10
|
+
// readWorkerGuardResponse({ status, body, error }) what the server answered → a reading
|
|
11
|
+
// describeWorkerGuard(reading, { tx }) the row as ui-settings.js draws it
|
|
12
|
+
// describeWorkerGuardSaveFailure(input, { tx }) the sentence for a choice that could not be saved
|
|
13
|
+
//
|
|
14
|
+
// `tx(key, params)` is the caller's translate function over the settings.redesign.* strings (the kit's `tx`).
|
|
15
|
+
// The row never shows a healthy-looking control for something that is not happening: a server started before
|
|
16
|
+
// the setting existed shows the default, disabled, and says a restart is missing.
|
|
17
|
+
|
|
18
|
+
const K = 'settings.redesign.hooks.workerGuard';
|
|
19
|
+
|
|
20
|
+
export const WORKER_GUARD_MODES = Object.freeze(['enforce', 'warn', 'off']);
|
|
21
|
+
export const WORKER_GUARD_DEFAULT = 'enforce';
|
|
22
|
+
|
|
23
|
+
const clean = (value, max = 200) => {
|
|
24
|
+
const text = String(value ?? '').replace(/\s+/g, ' ').trim();
|
|
25
|
+
return text.length > max ? `${text.slice(0, max - 1)}…` : text;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* What the server answered.
|
|
30
|
+
*
|
|
31
|
+
* ready the setting is there: `mode` is in effect, `modes` the choices
|
|
32
|
+
* old-server 404: the running server was started before the setting existed
|
|
33
|
+
* failed 503 WORKER_GUARD_UNAVAILABLE: the setting did not start; `reason` is the error
|
|
34
|
+
* unreadable anything else (no answer, a refusal, a body that is not the payload)
|
|
35
|
+
*/
|
|
36
|
+
export function readWorkerGuardResponse({ status = 0, body = null, error = null } = {}) {
|
|
37
|
+
const code = Number(status) || 0;
|
|
38
|
+
if (code === 404) return { state: 'old-server', mode: WORKER_GUARD_DEFAULT, modes: [...WORKER_GUARD_MODES], reason: null };
|
|
39
|
+
if (code === 503) return { state: 'failed', mode: WORKER_GUARD_DEFAULT, modes: [...WORKER_GUARD_MODES], reason: clean(body?.reason || body?.error) || null };
|
|
40
|
+
if (code >= 200 && code < 300 && body && typeof body === 'object' && body.ok !== false && WORKER_GUARD_MODES.includes(body.mode)) {
|
|
41
|
+
const modes = Array.isArray(body.modes) && body.modes.every((m) => WORKER_GUARD_MODES.includes(m)) && body.modes.length ? body.modes : [...WORKER_GUARD_MODES];
|
|
42
|
+
return { state: 'ready', mode: body.mode, modes, reason: null };
|
|
43
|
+
}
|
|
44
|
+
return { state: 'unreadable', mode: WORKER_GUARD_DEFAULT, modes: [...WORKER_GUARD_MODES], reason: clean(error || body?.error || (code ? `HTTP ${code}` : '')) || null };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The row: { ready, disabled, mode, options: [{ value, label, help }], note: { text, tone } | null, applies }. */
|
|
48
|
+
export function describeWorkerGuard(reading, { tx }) {
|
|
49
|
+
const r = reading || readWorkerGuardResponse({ status: 0 });
|
|
50
|
+
const options = (r.modes || WORKER_GUARD_MODES).map((value) => ({ value, label: tx(`${K}.mode.${value}`), help: tx(`${K}.modeHelp.${value}`) }));
|
|
51
|
+
let note = null;
|
|
52
|
+
if (r.state === 'old-server') note = { text: tx(`${K}.restart`), tone: 'warn' };
|
|
53
|
+
else if (r.state === 'failed') note = { text: r.reason ? tx(`${K}.failed`, { reason: r.reason }) : tx(`${K}.failedNoReason`), tone: 'warn' };
|
|
54
|
+
else if (r.state === 'unreadable') note = { text: r.reason ? tx(`${K}.unreadable`, { reason: r.reason }) : tx(`${K}.unreadableNoReason`), tone: 'warn' };
|
|
55
|
+
return {
|
|
56
|
+
ready: r.state === 'ready',
|
|
57
|
+
disabled: r.state !== 'ready',
|
|
58
|
+
mode: r.mode || WORKER_GUARD_DEFAULT,
|
|
59
|
+
options,
|
|
60
|
+
note,
|
|
61
|
+
applies: tx(`${K}.applies`),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The sentence under the row when a choice could not be saved: { status, body, error, mode }. */
|
|
66
|
+
export function describeWorkerGuardSaveFailure({ status = 0, body = null, error = null, mode = '' } = {}, { tx }) {
|
|
67
|
+
const code = Number(status) || 0;
|
|
68
|
+
const name = tx(`${K}.mode.${WORKER_GUARD_MODES.includes(mode) ? mode : WORKER_GUARD_DEFAULT}`);
|
|
69
|
+
if (code === 404) return tx(`${K}.save.oldServer`, { mode: name });
|
|
70
|
+
if (!code) return tx(`${K}.save.noAnswer`, { mode: name, reason: clean(error) || '' });
|
|
71
|
+
return tx(`${K}.save.failed`, { mode: name, reason: clean(body?.error || error) || `HTTP ${code}` });
|
|
72
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// What a detached session window (ui-sidepanel-sessions.js) is doing, for the
|
|
2
|
+
// pill the main window shows for it. It is read from the window's own tray
|
|
3
|
+
// pills, the ones its provider panel paints from its sessions' state: Claude
|
|
4
|
+
// (tabWorking: a turn or background agents and shells; tabNeedsYou: a
|
|
5
|
+
// permission or a question waiting), Codex (a turn or a thread being made; an
|
|
6
|
+
// approval or a question card waiting), OpenCode (tabPillState: a turn, an
|
|
7
|
+
// automation's turn, a sub-agent's, one waiting on you) and the SynaBun
|
|
8
|
+
// Assistant (sessionStatus). The same source as the tray pills, never a second
|
|
9
|
+
// guess. DOM-free.
|
|
10
|
+
|
|
11
|
+
const WORKING = /^(cp|cxp|ocpv2|asp)-pill-running$/;
|
|
12
|
+
const NEEDS_YOU = /^((cp|cxp|asp)-pill-attention|ocpv2-pill-waiting)$/;
|
|
13
|
+
|
|
14
|
+
/** The states a detached window's pill shows: a session in it needs you > one works > none. */
|
|
15
|
+
export const SESSION_WINDOW_STATES = Object.freeze(['action', 'working', 'idle']);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 'action' when a session in the window waits on you, 'working' when one works,
|
|
19
|
+
* else 'idle'. `pills`: the class names of each tray pill of the window.
|
|
20
|
+
*/
|
|
21
|
+
export function sessionWindowStatus(pills) {
|
|
22
|
+
let working = false;
|
|
23
|
+
for (const classes of pills || []) {
|
|
24
|
+
for (const cls of classes || []) {
|
|
25
|
+
if (NEEDS_YOU.test(cls)) return 'action';
|
|
26
|
+
if (WORKING.test(cls)) working = true;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return working ? 'working' : 'idle';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** A status a window reported, or 'idle' for anything else. */
|
|
33
|
+
export function normalizeSessionWindowStatus(status) {
|
|
34
|
+
return SESSION_WINDOW_STATES.includes(status) ? status : 'idle';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A dispatched worker's run (its descriptor) waits on your answer with no card
|
|
39
|
+
* in its tab: its turn ended asking you something (the run's outcome is
|
|
40
|
+
* needs_input while the warm worker rests between turns). Claude's and Codex's
|
|
41
|
+
* tabs say "needs you" for it, as OpenCode's do (automationTurnPhase); a card
|
|
42
|
+
* of their own (a permission, a question) says it already. A run that ended
|
|
43
|
+
* waits on nobody.
|
|
44
|
+
*/
|
|
45
|
+
export function runAwaitsAnswer(run) {
|
|
46
|
+
if (run?.status !== 'starting' && run?.status !== 'running') return false;
|
|
47
|
+
if (run.turnState === 'needs_input') return true;
|
|
48
|
+
return run.turnState === 'idle' && (run.outcome || run.lastResult?.status) === 'needs_input';
|
|
49
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SynaBun Neural Interface — Skills Studio: a skill's arguments, as Claude Code fills them
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// When a panel hands a SKILL.md to a model itself (a skill the runtime cannot see, server.js
|
|
6
|
+
// maybeInjectSkillPrompt), the body is filled the way Claude Code fills it (code.claude.com/docs/en/skills,
|
|
7
|
+
// "Available string substitutions", read 2026-10-21):
|
|
8
|
+
// $ARGUMENTS the argument text as typed; when nothing in the body takes the arguments, Claude Code
|
|
9
|
+
// adds "ARGUMENTS: <text>" at the end instead
|
|
10
|
+
// $ARGUMENTS[N], $N the Nth argument, counted from 0 ($0 is the first); a quoted phrase is one argument;
|
|
11
|
+
// one that is not there stays as written
|
|
12
|
+
// $name an argument named in the frontmatter's `arguments` (in that order); empty when missing
|
|
13
|
+
// \$... a backslash keeps the placeholder as text (the backslash goes)
|
|
14
|
+
// ${CLAUDE_SKILL_DIR} the skill's folder; ${CLAUDE_PROJECT_DIR} the project (when known); other ${CLAUDE_*}
|
|
15
|
+
// stay as written
|
|
16
|
+
// One pass over the text: what an argument brings in is never read again as a placeholder, so a "$&" or a
|
|
17
|
+
// "$ARGUMENTS" typed by the person reaches the model as they typed it. `$SKILL_DIR` (a convention of SynaBun's
|
|
18
|
+
// old bridges, not a runtime variable) is filled with the skill's folder too. No DOM.
|
|
19
|
+
|
|
20
|
+
/** The arguments as Claude Code counts them: split on white space, a "quoted phrase" or 'quoted phrase' is one. */
|
|
21
|
+
export function splitArguments(text) {
|
|
22
|
+
const out = [];
|
|
23
|
+
const s = String(text ?? '');
|
|
24
|
+
let i = 0;
|
|
25
|
+
while (i < s.length) {
|
|
26
|
+
while (i < s.length && /\s/.test(s[i])) i++;
|
|
27
|
+
if (i >= s.length) break;
|
|
28
|
+
let item = '';
|
|
29
|
+
while (i < s.length && !/\s/.test(s[i])) {
|
|
30
|
+
const quote = s[i];
|
|
31
|
+
if (quote === '"' || quote === "'") {
|
|
32
|
+
const close = s.indexOf(quote, i + 1);
|
|
33
|
+
if (close > i) { item += s.slice(i + 1, close); i = close + 1; continue; }
|
|
34
|
+
}
|
|
35
|
+
item += s[i];
|
|
36
|
+
i++;
|
|
37
|
+
}
|
|
38
|
+
out.push(item);
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** The names `arguments` declares (a space-separated text or a list), in order; [] for anything else. */
|
|
44
|
+
export function declaredArgumentNames(value) {
|
|
45
|
+
const list = typeof value === 'string' ? value.split(/[\s,]+/) : (Array.isArray(value) ? value : []);
|
|
46
|
+
return list.filter((n) => typeof n === 'string' && /^[A-Za-z_][A-Za-z0-9_]*$/.test(n.trim())).map((n) => n.trim());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// One regular expression for every placeholder, so the text is read once. Order matters inside the alternation:
|
|
50
|
+
// the escaped form first, then the longer names. Only an argument placeholder can be escaped: a backslash before
|
|
51
|
+
// ${CLAUDE_*} is not an escape (it stays, and the variable is filled).
|
|
52
|
+
const PLACEHOLDER = /\\\$(ARGUMENTS(?:\[\d+\])?|\d+|[A-Za-z_][A-Za-z0-9_]*)|\$ARGUMENTS\[(\d+)\]|\$ARGUMENTS\b|\$(\d+)|\$\{(CLAUDE_[A-Z_]+)\}|\$SKILL_DIR\b|\$([A-Za-z_][A-Za-z0-9_]*)/g;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Fill a skill body.
|
|
56
|
+
* @param {string} body the text after the frontmatter
|
|
57
|
+
* @param {object} o
|
|
58
|
+
* @param {string} [o.args] the argument text as typed (may be empty)
|
|
59
|
+
* @param {string[]|string} [o.declared] the frontmatter's `arguments`
|
|
60
|
+
* @param {string} [o.skillDir] the skill's folder
|
|
61
|
+
* @param {string} [o.projectDir] the project folder, when known
|
|
62
|
+
* @param {string} [o.emptyArguments] what $ARGUMENTS reads when nothing was typed (Claude Code: ''; SynaBun's panels
|
|
63
|
+
* say "(none)" so the instructions read as meant)
|
|
64
|
+
* @returns {{ text: string, consumed: boolean }} `consumed`: a placeholder took the arguments
|
|
65
|
+
*/
|
|
66
|
+
export function renderSkillBody(body, { args = '', declared = [], skillDir = '', projectDir = '', emptyArguments = '' } = {}) {
|
|
67
|
+
const text = String(body ?? '');
|
|
68
|
+
const typed = String(args ?? '');
|
|
69
|
+
const items = splitArguments(typed);
|
|
70
|
+
const names = declaredArgumentNames(declared);
|
|
71
|
+
let consumed = false;
|
|
72
|
+
const out = text.replace(PLACEHOLDER, (whole, escaped, indexed, positional, claudeVar, name) => {
|
|
73
|
+
if (escaped !== undefined) {
|
|
74
|
+
const placeholder = /^ARGUMENTS(?:\[\d+\])?$/.test(escaped) || /^\d+$/.test(escaped) || names.includes(escaped);
|
|
75
|
+
return placeholder ? `$${escaped}` : whole;
|
|
76
|
+
}
|
|
77
|
+
if (indexed !== undefined) { const v = items[Number(indexed)]; if (v === undefined) return whole; consumed = true; return v; }
|
|
78
|
+
if (positional !== undefined) { const v = items[Number(positional)]; if (v === undefined) return whole; consumed = true; return v; }
|
|
79
|
+
if (claudeVar !== undefined) {
|
|
80
|
+
if (claudeVar === 'CLAUDE_SKILL_DIR' && skillDir) return skillDir;
|
|
81
|
+
if (claudeVar === 'CLAUDE_PROJECT_DIR' && projectDir) return projectDir;
|
|
82
|
+
return whole;
|
|
83
|
+
}
|
|
84
|
+
if (whole === '$ARGUMENTS') { consumed = true; return typed.trim() ? typed : emptyArguments; }
|
|
85
|
+
if (whole === '$SKILL_DIR') return skillDir || whole;
|
|
86
|
+
if (name !== undefined) {
|
|
87
|
+
const at = names.indexOf(name);
|
|
88
|
+
if (at < 0) return whole;
|
|
89
|
+
consumed = true;
|
|
90
|
+
return items[at] ?? '';
|
|
91
|
+
}
|
|
92
|
+
return whole;
|
|
93
|
+
});
|
|
94
|
+
if (!consumed && typed.trim()) return { text: `${out}${out.endsWith('\n') ? '' : '\n'}\nARGUMENTS: ${typed}`, consumed: false };
|
|
95
|
+
return { text: out, consumed };
|
|
96
|
+
}
|