synabun 2.0.10 → 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 +86 -0
- package/README.md +25 -2
- package/THIRD-PARTY-LICENSES.md +22 -0
- 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/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 +37 -4
- 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 +3463 -200
- package/neural-interface/i18n/pt-BR.json +3411 -151
- package/neural-interface/lib/assistant-api.js +127 -28
- 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-catalog.js +6 -7
- package/neural-interface/lib/assistant-dispatch.js +871 -156
- package/neural-interface/lib/assistant-envelope.js +3 -1
- 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 +56 -18
- 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-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-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 +68 -68
- package/neural-interface/lib/exec-loop-command.js +4 -8
- 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 +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 +547 -47
- package/neural-interface/lib/native-loop-runtime.js +268 -41
- 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 +44 -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/peer-identity.js +763 -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 +17 -30
- 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 +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/tool-lists.js +124 -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 +18 -12
- package/neural-interface/package.json +2 -2
- package/neural-interface/public/index.html +3 -1
- 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 +35 -19
- 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 +33 -2
- 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 +49 -35
- 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-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 +7 -6
- package/neural-interface/public/shared/assistant/asst-panel.js +106 -11
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
- package/neural-interface/public/shared/assistant/asst-render.js +401 -77
- package/neural-interface/public/shared/assistant/asst-route.js +83 -12
- package/neural-interface/public/shared/assistant/asst-scenes.js +2 -0
- 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 +11 -15
- package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +59 -21
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +156 -16
- 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 +8 -7
- package/neural-interface/public/shared/cdx/cdx-panel.js +45 -149
- package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
- package/neural-interface/public/shared/cdx/cdx-render.js +47 -29
- 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 +11 -3
- package/neural-interface/public/shared/cdx/cdx-tabs.js +52 -39
- 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/crash-notice-view.js +168 -0
- package/neural-interface/public/shared/desktop-update-view.js +20 -0
- package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
- package/neural-interface/public/shared/html-shell.js +9 -11
- 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 +47 -252
- 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-render.js +6 -21
- 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 +0 -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 +14 -47
- 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 +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-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/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 +1525 -1779
- 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-automation-studio.js +91 -128
- package/neural-interface/public/shared/ui-claude-panel.js +77 -5
- 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-image-gallery.js +50 -47
- package/neural-interface/public/shared/ui-keybinds.js +26 -1
- package/neural-interface/public/shared/ui-menubar.js +8 -18
- package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
- package/neural-interface/public/shared/ui-native-loop-router.js +7 -1
- package/neural-interface/public/shared/ui-navbar.js +4 -24
- package/neural-interface/public/shared/ui-panels.js +96 -65
- package/neural-interface/public/shared/ui-schedules-studio.js +507 -423
- package/neural-interface/public/shared/ui-sessions.js +5 -3
- package/neural-interface/public/shared/ui-settings.js +594 -462
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +1 -1
- package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
- package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
- 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 +124 -180
- 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 +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 +311 -58
- 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 +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 +3934 -2454
- 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 +4 -4
- 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
|
@@ -15,14 +15,18 @@
|
|
|
15
15
|
// reactive fallback); Assistant task runs' workers in
|
|
16
16
|
// native-loop-providers.js (Claude),
|
|
17
17
|
// assistant-brains/codex-browser-policy-hook.mjs and
|
|
18
|
-
// assistant-brains/
|
|
18
|
+
// assistant-brains/opencode2-browser-policy/
|
|
19
19
|
//
|
|
20
20
|
// Lexical, like remote-policy.js: a speed bump, not a sandbox. A shell that
|
|
21
21
|
// builds a program name at run time, or a script loading a browser library
|
|
22
22
|
// from a file SynaBun cannot read, gets past it. Mentions (rg playwright,
|
|
23
|
-
// cat pw.cjs, sed -i … pw.cjs, git, code that only names a library)
|
|
24
|
-
//
|
|
25
|
-
//
|
|
23
|
+
// cat pw.cjs, sed -i … pw.cjs, git, code that only names a library), a
|
|
24
|
+
// syntax check (node --check <file>: Node parses it and runs nothing) and
|
|
25
|
+
// automated tests (npm test, node --test, vitest, jest, npx playwright test)
|
|
26
|
+
// run from inside one allowed project on files inside that same project
|
|
27
|
+
// always pass. The allowed projects are the session's own and the `roots` its
|
|
28
|
+
// caller passes: the registered SynaBun projects that are code projects
|
|
29
|
+
// (lib/browser-policy-roots.js, read by the caller as a run starts).
|
|
26
30
|
// Computer use on a browser window is refused by the desktop guards
|
|
27
31
|
// (lib/desktop/guards.js), which know the app a click or a key lands in.
|
|
28
32
|
// Pure ESM with no imports of SynaBun's own, loaded by Node and by OpenCode's
|
|
@@ -68,6 +72,9 @@ function browserToolNames(tools) {
|
|
|
68
72
|
};
|
|
69
73
|
}
|
|
70
74
|
|
|
75
|
+
// Where automated tests run, and the syntax check: one sentence for the rule text and every refusal.
|
|
76
|
+
const TEST_RUN_RULE = 'Automated tests run through their test runner (npm test, node --test, vitest, jest, npx playwright test, not its UI or debug mode) from inside the project they belong to: cd into that project first and name only its own files. That project may be this session\'s or any registered SynaBun project that is a code project (git, package.json or deno.json at its top; never the Downloads folder). A syntax check (node --check <file>) always runs.';
|
|
77
|
+
|
|
71
78
|
/**
|
|
72
79
|
* The browser rule, as bullet lines: the brain's persona (its host's tool
|
|
73
80
|
* names in `tools`), the worker prompts of browser runs. `host`: claude /
|
|
@@ -78,7 +85,8 @@ export function browserPolicyText({ tools = '', host = null } = {}) {
|
|
|
78
85
|
const web = WEB_TOOL_WORDS[hostKey(host)] || 'WebSearch / WebFetch (OpenCode webfetch / websearch, Codex web_search)';
|
|
79
86
|
return [
|
|
80
87
|
`- Every page, public or localhost, goes through SynaBun's browser tools (${t.navigate}, ${t.snapshot}, ${t.screenshot}, ${t.console} and the other browser_* tools); they open the browser configured in SynaBun (MoreLogin). Nothing else opens a page.`,
|
|
81
|
-
'- Never run Playwright, Puppeteer or Selenium code of your own to look at a page (a script, node -e, python -c, a heredoc), and never `npx playwright` except to run
|
|
88
|
+
'- Never run Playwright, Puppeteer or Selenium code of your own to look at a page (a script, node -e, python -c, a heredoc), and never `npx playwright` except to run automated tests (npx playwright test).',
|
|
89
|
+
`- ${TEST_RUN_RULE}`,
|
|
82
90
|
'- Never launch Chrome, Chromium, Edge, chrome-headless-shell or any other browser binary, and never take headless screenshots (--headless, --screenshot).',
|
|
83
91
|
'- Never `open` a URL or a browser app, and never use computer use on a browser app.',
|
|
84
92
|
`- Never use the Playwright, Chrome DevTools, Claude-in-Chrome or any other browser MCP tools, nor ${web}.`,
|
|
@@ -230,6 +238,27 @@ function insideDir(path, dir) {
|
|
|
230
238
|
const rel = relative(resolve(dir), resolve(path));
|
|
231
239
|
return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
|
|
232
240
|
}
|
|
241
|
+
// macOS and Windows name a folder in any letter case: an exclusion below compares that way.
|
|
242
|
+
const caseless = (path) => (process.platform === 'darwin' || process.platform === 'win32' ? path.toLowerCase() : path);
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Where a test runner may run: the session's project, then each of `roots`
|
|
246
|
+
* (the caller's registered code projects) that is an absolute path, never
|
|
247
|
+
* the home folder or a folder above it, never the Downloads folder or
|
|
248
|
+
* anything in it (the caller's rule, held here too by name alone).
|
|
249
|
+
*/
|
|
250
|
+
function testRoots(project, roots) {
|
|
251
|
+
const out = [project];
|
|
252
|
+
const home = caseless(resolve(homedir()));
|
|
253
|
+
const downloads = caseless(resolve(homedir(), 'Downloads'));
|
|
254
|
+
for (const root of Array.isArray(roots) ? roots : []) {
|
|
255
|
+
if (typeof root !== 'string' || !isAbsolute(root)) continue;
|
|
256
|
+
const path = resolve(root);
|
|
257
|
+
if (insideDir(home, caseless(path)) || insideDir(caseless(path), downloads)) continue;
|
|
258
|
+
if (!out.includes(path)) out.push(path);
|
|
259
|
+
}
|
|
260
|
+
return out;
|
|
261
|
+
}
|
|
233
262
|
/** A regular file up to MAX_SCRIPT_BYTES, else null. */
|
|
234
263
|
function defaultReadFile(path) {
|
|
235
264
|
const stat = statSync(path);
|
|
@@ -549,13 +578,12 @@ function pathArgs(args) {
|
|
|
549
578
|
}
|
|
550
579
|
|
|
551
580
|
/**
|
|
552
|
-
* A
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
581
|
+
* A test runner's command, wherever it runs: { rest (its arguments, the files
|
|
582
|
+
* among them), playwright } for npm|pnpm|yarn|bun test (and run test*), node
|
|
583
|
+
* --test, deno test, vitest, jest, playwright test — through a package runner
|
|
584
|
+
* too — else null.
|
|
556
585
|
*/
|
|
557
|
-
function
|
|
558
|
-
if (!insideDir(cwd, project)) return false;
|
|
586
|
+
function testRunner(words) {
|
|
559
587
|
const [head, ...args] = words;
|
|
560
588
|
const name = programName(head);
|
|
561
589
|
let rest = null;
|
|
@@ -575,14 +603,58 @@ function isTestRun(words, { cwd, project }) {
|
|
|
575
603
|
if (run?.pkg === 'vitest' || run?.pkg === 'jest') rest = run.args;
|
|
576
604
|
else if (PLAYWRIGHT_TEST.has(run?.pkg) && run.args[0] === 'test') { rest = run.args.slice(1); playwright = true; }
|
|
577
605
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
606
|
+
return rest === null ? null : { rest, playwright };
|
|
607
|
+
}
|
|
608
|
+
/** The allowed projects (ctx.roots) the command runs from (`cwd`, where it runs, `cd` included). */
|
|
609
|
+
const rootsHolding = (cwd, roots) => roots.filter((root) => insideDir(cwd, root));
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Automated tests: a test runner (testRunner) run from inside one of the
|
|
613
|
+
* allowed projects (the session's own, or a registered code project the
|
|
614
|
+
* caller passed) on file arguments, if any, that lie inside that same one.
|
|
615
|
+
*/
|
|
616
|
+
function isTestRun(words, { cwd, roots }) {
|
|
617
|
+
const run = testRunner(words);
|
|
618
|
+
if (!run) return false;
|
|
619
|
+
if (run.playwright && run.rest.some((arg) => PLAYWRIGHT_INTERACTIVE.test(arg))) return false;
|
|
620
|
+
const files = pathArgs(run.rest).map((path) => resolvePath(cwd, path));
|
|
621
|
+
return rootsHolding(cwd, roots).some((root) => files.every((file) => insideDir(file, root)));
|
|
622
|
+
}
|
|
623
|
+
/** Where a test run that is not exempt ran from, for its refusal. */
|
|
624
|
+
function testRunWhere({ cwd, roots }) {
|
|
625
|
+
return rootsHolding(cwd, roots).length
|
|
626
|
+
? 'on files outside the project it runs in'
|
|
627
|
+
: `run from ${cwd}, outside this session's project and every registered code project`;
|
|
581
628
|
}
|
|
582
629
|
/** Why a `playwright test` that is not an automated test run is refused. */
|
|
583
|
-
function playwrightTestWhy(runner, args,
|
|
630
|
+
function playwrightTestWhy(runner, args, ctx) {
|
|
584
631
|
if (args.some((arg) => PLAYWRIGHT_INTERACTIVE.test(arg))) return `${runner} test in its UI or debug mode (a browser window)`;
|
|
585
|
-
return
|
|
632
|
+
return `${runner} test ${testRunWhere(ctx)}`;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* `node --check <file>` / `node -c <file>` (or its program on stdin): Node
|
|
637
|
+
* parses the program and runs none of it. Checked on Node 24: the forms
|
|
638
|
+
* below run code and are not exempt, so the usual check applies to them:
|
|
639
|
+
* any other option before the file (-r / --require and --import run the
|
|
640
|
+
* module they name, --env-file and --experimental-config-file can add a
|
|
641
|
+
* --require, --run runs a package.json script; -e / -p, --test and --watch
|
|
642
|
+
* Node refuses to combine with --check), NODE_OPTIONS set anywhere on the
|
|
643
|
+
* line (it can hold a --require), `inspect` as the file (node inspect
|
|
644
|
+
* starts the next file under the debugger) and arguments xargs supplies.
|
|
645
|
+
* Only node / nodejs started directly: a package runner's (npx node) is not.
|
|
646
|
+
*/
|
|
647
|
+
function syntaxCheckOnly(args, seg, ctx) {
|
|
648
|
+
if (ctx.nodeOptions || seg.words.some((word) => word.includes('NODE_OPTIONS') || programName(word) === 'xargs')) return false;
|
|
649
|
+
let check = false;
|
|
650
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
651
|
+
const arg = args[i];
|
|
652
|
+
if (arg === '--check' || arg === '-c') { check = true; continue; }
|
|
653
|
+
if (arg === '--') return check && args[i + 1] !== 'inspect';
|
|
654
|
+
if (arg.startsWith('-') && arg !== '-') return false;
|
|
655
|
+
return check && arg !== 'inspect';
|
|
656
|
+
}
|
|
657
|
+
return check;
|
|
586
658
|
}
|
|
587
659
|
|
|
588
660
|
/** What `open` / xdg-open is asked to show when it is a browser, a URL or a web page, else null. */
|
|
@@ -660,14 +732,28 @@ const RUNTIME_VALUE_OPTIONS = {
|
|
|
660
732
|
ts: new Set(['--tsconfig', '-P', '--project', '-O', '--compiler-options', '-r', '--require', '--import', '--loader', '-C', '--conditions', '--env-file', '--config', '--root', '--mode', '-I', '--ignore']),
|
|
661
733
|
};
|
|
662
734
|
const EVAL_FLAG = /^(?:--eval|--print|-[A-Za-z]*[ep])$/;
|
|
735
|
+
// Options whose value is a module the runtime loads and runs before the program (node -r, --import, a loader; bun --preload).
|
|
736
|
+
const PRELOAD_OPTIONS = new Set(['-r', '--require', '--import', '--loader', '--experimental-loader', '--preload']);
|
|
737
|
+
const PRELOAD_INLINE = /^(--require|--import|--loader|--experimental-loader|--preload)=(.*)$/;
|
|
738
|
+
|
|
739
|
+
/** The modules a list of runtime options preloads (`-r x`, `--import=x` …), in order. */
|
|
740
|
+
function preloadsIn(words) {
|
|
741
|
+
const out = [];
|
|
742
|
+
for (let i = 0; i < words.length; i += 1) {
|
|
743
|
+
if (PRELOAD_OPTIONS.has(words[i])) { if (words[i + 1] !== undefined) out.push(words[i + 1]); i += 1; continue; }
|
|
744
|
+
const inline = PRELOAD_INLINE.exec(words[i]);
|
|
745
|
+
if (inline) out.push(inline[2]);
|
|
746
|
+
}
|
|
747
|
+
return out;
|
|
748
|
+
}
|
|
663
749
|
|
|
664
750
|
/**
|
|
665
|
-
* A JS runtime's arguments → { code: [inline code], script,
|
|
751
|
+
* A JS runtime's arguments → { code: [inline code], script, preload }: node,
|
|
666
752
|
* bun, deno, tsx, ts-node and friends. `script` "-" or none (and no code):
|
|
667
|
-
* the program comes from stdin.
|
|
753
|
+
* the program comes from stdin. `preload`: the modules its options load first.
|
|
668
754
|
*/
|
|
669
755
|
function jsProgram(name, args) {
|
|
670
|
-
const out = { code: [], script: null };
|
|
756
|
+
const out = { code: [], script: null, preload: [] };
|
|
671
757
|
let list = args;
|
|
672
758
|
let valued = NODE_VALUE_OPTIONS;
|
|
673
759
|
if (name === 'bun') {
|
|
@@ -683,14 +769,25 @@ function jsProgram(name, args) {
|
|
|
683
769
|
valued = RUNTIME_VALUE_OPTIONS.ts;
|
|
684
770
|
if (list[0] === 'watch') list = list.slice(1); // tsx watch <file>
|
|
685
771
|
}
|
|
772
|
+
const node = name === 'node' || name === 'nodejs';
|
|
686
773
|
for (let i = 0; i < list.length; i += 1) {
|
|
687
774
|
const arg = list[i];
|
|
688
775
|
if (arg === '-') { out.script = '-'; return out; }
|
|
689
|
-
if (arg === '--') {
|
|
776
|
+
if (arg === '--') {
|
|
777
|
+
// `node -- inspect <file>` is node inspect too.
|
|
778
|
+
const inspect = node && !out.inspect && list[i + 1] === 'inspect';
|
|
779
|
+
out.script = list[i + (inspect ? 2 : 1)] ?? null;
|
|
780
|
+
return out;
|
|
781
|
+
}
|
|
690
782
|
if (/^--(?:eval|print)=/.test(arg)) { out.code.push(arg.slice(arg.indexOf('=') + 1)); return out; }
|
|
691
783
|
if (EVAL_FLAG.test(arg)) { if (list[i + 1] !== undefined) out.code.push(list[i + 1]); return out; }
|
|
784
|
+
if (PRELOAD_OPTIONS.has(arg) && valued.has(arg)) { if (list[i + 1] !== undefined) out.preload.push(list[i + 1]); i += 1; continue; }
|
|
785
|
+
const inline = PRELOAD_INLINE.exec(arg);
|
|
786
|
+
if (inline) { out.preload.push(inline[2]); continue; }
|
|
692
787
|
if (valued.has(arg)) { i += 1; continue; }
|
|
693
788
|
if (arg.startsWith('-')) continue;
|
|
789
|
+
// `node inspect <file>` runs <file> under the debugger.
|
|
790
|
+
if (arg === 'inspect' && node && !out.inspect) { out.inspect = true; continue; }
|
|
694
791
|
out.script = arg;
|
|
695
792
|
return out;
|
|
696
793
|
}
|
|
@@ -723,6 +820,17 @@ const FILE_READERS = new Set(['cat', 'type', 'head', 'tail', 'bat', 'more', 'les
|
|
|
723
820
|
function interpreterDenial(name, args, seg, ctx) {
|
|
724
821
|
const python = PYTHON.test(name);
|
|
725
822
|
const program = python ? pythonProgram(args) : jsProgram(name, args);
|
|
823
|
+
// A preloaded file runs before the program (with --check too): its options', and NODE_OPTIONS set on the command itself.
|
|
824
|
+
if (!python) {
|
|
825
|
+
const inherited = seg.words.filter((word) => word.startsWith('NODE_OPTIONS=')).flatMap((word) => preloadsIn(word.slice(13).trim().split(/\s+/)));
|
|
826
|
+
for (const module of [...inherited, ...program.preload]) {
|
|
827
|
+
if (!PATH_LIKE.test(module)) continue; // a package name: not read
|
|
828
|
+
let file = module;
|
|
829
|
+
if (/^file:/i.test(module)) { try { file = decodeURIComponent(new URL(module).pathname); } catch { continue; } }
|
|
830
|
+
const what = codeMarker(readScript(ctx, resolvePath(ctx.cwd, file)));
|
|
831
|
+
if (what) return `preloading ${module}, a script that ${what}, into ${name}`;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
726
834
|
for (const code of program.code) {
|
|
727
835
|
const what = codeMarker(code);
|
|
728
836
|
if (what) return `inline code that ${what} (${name} ${python ? '-c' : '-e'})`;
|
|
@@ -818,7 +926,12 @@ function segmentDenial(words, seg, ctx) {
|
|
|
818
926
|
}
|
|
819
927
|
if (name === 'playwright' && args[0] === 'test') return playwrightTestWhy(name, args.slice(1), ctx);
|
|
820
928
|
if (BROWSER_CLIS.has(name)) return `${name}${args[0] ? ` ${args[0]}` : ''} (a browser CLI)`;
|
|
821
|
-
if (
|
|
929
|
+
if ((name === 'node' || name === 'nodejs') && syntaxCheckOnly(args, seg, ctx)) return null;
|
|
930
|
+
if (JS_RUNTIMES.has(name) || PYTHON.test(name)) {
|
|
931
|
+
const why = interpreterDenial(name, args, seg, ctx);
|
|
932
|
+
// node --test / deno test of a browser test from outside the project it belongs to: say where it may run.
|
|
933
|
+
return why && testRunner(words) ? `${why} (${name === 'deno' ? 'deno test' : `${name} --test`} ${testRunWhere(ctx)})` : why;
|
|
934
|
+
}
|
|
822
935
|
// A script run as a program (./shot.sh, ./pw.cjs, /tmp/x): by its shebang, else its extension.
|
|
823
936
|
if (/[/\\]/.test(head)) {
|
|
824
937
|
const text = readScript(ctx, resolvePath(ctx.cwd, head));
|
|
@@ -838,7 +951,10 @@ function segmentDenial(words, seg, ctx) {
|
|
|
838
951
|
function commandDenial(text, ctx) {
|
|
839
952
|
if (ctx.depth > MAX_DEPTH) return null;
|
|
840
953
|
let cwd = ctx.cwd;
|
|
954
|
+
// NODE_OPTIONS set or exported earlier on the line reaches every later node (syntaxCheckOnly).
|
|
955
|
+
let nodeOptions = ctx.nodeOptions === true;
|
|
841
956
|
for (const seg of simpleCommands(text)) {
|
|
957
|
+
if (seg.words.some((word) => word.includes('NODE_OPTIONS'))) nodeOptions = true;
|
|
842
958
|
const words = commandWords(seg.words);
|
|
843
959
|
// `cd dir && node pw.cjs`: the rest of the line runs there (a bare cd: the home folder).
|
|
844
960
|
if (words[0] === 'cd' || words[0] === 'pushd') {
|
|
@@ -847,7 +963,7 @@ function commandDenial(text, ctx) {
|
|
|
847
963
|
else if (words[0] === 'cd' && words.length === 1) cwd = homedir();
|
|
848
964
|
continue;
|
|
849
965
|
}
|
|
850
|
-
const why = segmentDenial(words, seg, { ...ctx, cwd });
|
|
966
|
+
const why = segmentDenial(words, seg, { ...ctx, cwd, nodeOptions });
|
|
851
967
|
if (why) return why;
|
|
852
968
|
}
|
|
853
969
|
return null;
|
|
@@ -855,13 +971,15 @@ function commandDenial(text, ctx) {
|
|
|
855
971
|
|
|
856
972
|
/** A shell tool's command: a string (a command line) or an argv array (Codex). */
|
|
857
973
|
function argvDenial(argv, ctx) {
|
|
858
|
-
const
|
|
974
|
+
const raw = argv.map((arg) => String(arg ?? ''));
|
|
975
|
+
const words = commandWords(raw);
|
|
859
976
|
if (!words.length) return null;
|
|
860
977
|
if (SHELLS.has(programName(words[0]))) {
|
|
861
978
|
const script = shellScript(words.slice(1));
|
|
862
979
|
if (script !== null) return commandDenial(script, ctx);
|
|
863
980
|
}
|
|
864
|
-
|
|
981
|
+
// The segment keeps its wrappers and assignments (env NODE_OPTIONS=… node --check …).
|
|
982
|
+
return segmentDenial(words, { words: raw, heredocs: [], inputs: [], pipedFrom: null }, ctx);
|
|
865
983
|
}
|
|
866
984
|
|
|
867
985
|
// Where each host puts a shell tool's command and its working directory.
|
|
@@ -889,18 +1007,22 @@ function shellDenial(input, ctx) {
|
|
|
889
1007
|
// ── the refusal ─────────────────────────────────────────────────────────────
|
|
890
1008
|
|
|
891
1009
|
function refusal(tool, what) {
|
|
892
|
-
return `SynaBun browser policy: ${tool} was refused — ${what}. Every page, public or localhost, goes through SynaBun's browser tools (browser_navigate, browser_snapshot, browser_screenshot, browser_console and the other browser_* tools), which open the browser configured in SynaBun. If the SynaBun browser fails or cannot do this, stop and report it; do not switch to another browser or tool.
|
|
1010
|
+
return `SynaBun browser policy: ${tool} was refused — ${what}. Every page, public or localhost, goes through SynaBun's browser tools (browser_navigate, browser_snapshot, browser_screenshot, browser_console and the other browser_* tools), which open the browser configured in SynaBun. If the SynaBun browser fails or cannot do this, stop and report it; do not switch to another browser or tool. ${TEST_RUN_RULE}`;
|
|
893
1011
|
}
|
|
894
1012
|
|
|
895
1013
|
/**
|
|
896
1014
|
* Why this tool call may not run under the browser policy (the refusal text),
|
|
897
1015
|
* else null. `host`: claude / codex / opencode (null: any). `cwd`: the
|
|
898
|
-
* project directory: relative script paths resolve against it, and
|
|
899
|
-
* runner
|
|
900
|
-
*
|
|
901
|
-
*
|
|
1016
|
+
* session's project directory: relative script paths resolve against it, and
|
|
1017
|
+
* a test runner may run inside it. `roots`: the other projects a test runner
|
|
1018
|
+
* may run inside (absolute paths: the registered code projects,
|
|
1019
|
+
* lib/browser-policy-roots.js; the home folder, a folder above it and the
|
|
1020
|
+
* Downloads folder are dropped). A test run's directory and its files lie in
|
|
1021
|
+
* one of them. `readFile(path)` returns an executed script's text or null
|
|
1022
|
+
* (tests); by default a regular file up to MAX_SCRIPT_BYTES is read, and
|
|
1023
|
+
* anything unreadable is allowed.
|
|
902
1024
|
*/
|
|
903
|
-
export function browserToolDenial(tool, input = {}, { host = null, cwd = null, readFile = defaultReadFile } = {}) {
|
|
1025
|
+
export function browserToolDenial(tool, input = {}, { host = null, cwd = null, roots = [], readFile = defaultReadFile } = {}) {
|
|
904
1026
|
const name = String(tool ?? '').trim();
|
|
905
1027
|
if (!name) return null;
|
|
906
1028
|
const kind = hostKey(host);
|
|
@@ -919,8 +1041,41 @@ export function browserToolDenial(tool, input = {}, { host = null, cwd = null, r
|
|
|
919
1041
|
}
|
|
920
1042
|
if (isSynabunTool(name) || /^mcp__/i.test(name)) return null;
|
|
921
1043
|
if (WEB_TOOLS.has(lower)) return refusal(name, 'web search / fetch outside the SynaBun browser');
|
|
1044
|
+
// OpenCode's own browser tool drives a browser that is not SynaBun's.
|
|
1045
|
+
if (kind === 'opencode' && lower === 'browser') return refusal(name, 'OpenCode\'s own browser');
|
|
922
1046
|
if (!SHELL_TOOLS.has(lower)) return null;
|
|
923
1047
|
const project = cwd ? resolve(String(cwd)) : process.cwd();
|
|
924
|
-
const why = shellDenial(args, { project, cwd: project, readFile: typeof readFile === 'function' ? readFile : defaultReadFile, depth: 0 });
|
|
1048
|
+
const why = shellDenial(args, { roots: testRoots(project, roots), cwd: project, readFile: typeof readFile === 'function' ? readFile : defaultReadFile, depth: 0 });
|
|
925
1049
|
return why ? refusal(name, why) : null;
|
|
926
1050
|
}
|
|
1051
|
+
|
|
1052
|
+
// ── SynaBun's own OpenCode serves ───────────────────────────────────────────
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* The port a web address (http, https, ws, wss) opens: its own, else the scheme's (80 / 443); null for any other
|
|
1056
|
+
* address (about:blank, data:, file:, chrome:) or one that cannot be read.
|
|
1057
|
+
*/
|
|
1058
|
+
export function addressPort(url) {
|
|
1059
|
+
let parsed;
|
|
1060
|
+
try { parsed = new URL(String(url ?? '')); } catch { return null; }
|
|
1061
|
+
if (!/^(?:https?|wss?):$/.test(parsed.protocol)) return null;
|
|
1062
|
+
const port = Number(parsed.port || (parsed.protocol === 'https:' || parsed.protocol === 'wss:' ? 443 : 80));
|
|
1063
|
+
return Number.isInteger(port) && port > 0 ? port : null;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
* Why the SynaBun browser may not open this address (the refusal text), else null: it is on the port of one of
|
|
1068
|
+
* SynaBun's own OpenCode serves running now (`ports`, a Set or a list: server.js liveOpencodeServePorts). Such a
|
|
1069
|
+
* serve's API changes a session's rules or moves it; nothing a page does needs it. Any host counts, not only
|
|
1070
|
+
* localhost: a name that resolves to this computer reaches the serve too. server.js refuses a navigation to it and
|
|
1071
|
+
* aborts every request and WebSocket of the browser to it (installServePortGuard), whatever opened the page.
|
|
1072
|
+
*/
|
|
1073
|
+
export function browserServePortDenial(url, ports) {
|
|
1074
|
+
const port = addressPort(url);
|
|
1075
|
+
if (!port) return null;
|
|
1076
|
+
const live = ports instanceof Set ? ports : new Set(Array.isArray(ports) ? ports.map(Number) : []);
|
|
1077
|
+
if (!live.has(port)) return null;
|
|
1078
|
+
let host = '';
|
|
1079
|
+
try { host = new URL(String(url)).hostname; } catch { /* addressPort read it */ }
|
|
1080
|
+
return `SynaBun browser policy: ${host}:${port} is one of SynaBun's own OpenCode servers, which the SynaBun browser never opens (their API changes what a session may do). Use your tools instead; whatever they cannot do is yours to report.`;
|
|
1081
|
+
}
|
|
@@ -2895,10 +2895,12 @@ export class ClaudeSession {
|
|
|
2895
2895
|
catch { this._greetingNote = ''; }
|
|
2896
2896
|
}
|
|
2897
2897
|
|
|
2898
|
-
// SynaBun skill injection runs FIRST; unrecognized /commands pass through to the CLI
|
|
2898
|
+
// SynaBun skill injection runs FIRST; unrecognized /commands pass through to the CLI. A skill Claude Code
|
|
2899
|
+
// loads by itself in this session (the account's or the project's) is left to it (server.js
|
|
2900
|
+
// resolveSkillPrompt), so its own settings apply; only a SynaBun skill it cannot see is handed over as text.
|
|
2899
2901
|
if (prompt && prompt.startsWith('/')) {
|
|
2900
2902
|
try {
|
|
2901
|
-
const injected = deps.maybeInjectSkillPrompt(prompt);
|
|
2903
|
+
const injected = deps.maybeInjectSkillPrompt(prompt, { cwd: cwd || this.cwd || null, runtime: 'claude', accountId: (queryAccount?.account ?? this.accountId) || 'default' });
|
|
2902
2904
|
if (injected.command === 'clear' && !injected.skill) return; // client-only
|
|
2903
2905
|
if (injected.skill) {
|
|
2904
2906
|
log('skill injection: /' + injected.command);
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SynaBun — the real state of SynaBun's Claude Code hooks (Settings → Automations)
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// What GET /api/claude-code/integrations reports as `claudeHooks`, read from the files Claude Code itself reads:
|
|
6
|
+
// the user's ~/.claude/settings.json (SynaBun's handlers live there), the managed settings an organization may
|
|
7
|
+
// install, and the registered projects' .claude/settings.json and settings.local.json. It answers "would a Claude
|
|
8
|
+
// Code session the owner starts by themselves run SynaBun's hooks?", which a count of entries alone does not:
|
|
9
|
+
// • Claude Code's own switches: disableAllHooks (any scope) runs no hook at all; allowManagedHooksOnly (managed
|
|
10
|
+
// settings) runs none of the user's or a project's;
|
|
11
|
+
// • a project whose SynaBun handlers differ from the user's: Claude Code runs one copy of identical handlers from
|
|
12
|
+
// both files and both copies of different ones (every hook twice: the 2026-09-15 bug);
|
|
13
|
+
// • macOS / Linux: a Claude Code started from the Dock, Finder, a desktop app or launchd has no login PATH. The
|
|
14
|
+
// handlers then look for Node in the usual folders and SYNABUN_NODE (lib/claude-hooks.js); `node: null` says
|
|
15
|
+
// such a launch would find none.
|
|
16
|
+
// Pure apart from the file reads, which are injected (tests drive it with an in-memory tree).
|
|
17
|
+
|
|
18
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
19
|
+
import { homedir } from 'node:os';
|
|
20
|
+
import { join } from 'node:path';
|
|
21
|
+
import { hookInstallBlocker, hookInstallState, hookNodeWithoutPath, hooksSwitchedOff, managedClaudeSettingsPath, projectHooksAgree } from '../../lib/claude-hooks.js';
|
|
22
|
+
import { packagedRuntime } from '../../lib/packaged-runtime.js';
|
|
23
|
+
|
|
24
|
+
/** Bumped when the shape changes; the page shows the hooks' state only from a server that sends one. */
|
|
25
|
+
export const CLAUDE_HOOKS_STATUS_VERSION = 1;
|
|
26
|
+
|
|
27
|
+
/** A settings file: { settings } (parsed), { missing: true }, or { error } (it exists and cannot be read or parsed: why). */
|
|
28
|
+
export function readSettingsFile(path, { read = (p) => readFileSync(p, 'utf8'), exists = existsSync } = {}) {
|
|
29
|
+
try {
|
|
30
|
+
if (!path || !exists(path)) return { missing: true };
|
|
31
|
+
} catch { return { missing: true }; }
|
|
32
|
+
let raw;
|
|
33
|
+
try { raw = read(path); } catch (error) { return { error: String(error?.code || error?.message || error) }; }
|
|
34
|
+
try {
|
|
35
|
+
const settings = JSON.parse(raw);
|
|
36
|
+
return settings && typeof settings === 'object' && !Array.isArray(settings) ? { settings } : { error: 'not a JSON object' };
|
|
37
|
+
} catch (error) { return { error: `not valid JSON: ${error?.message || error}` }; }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {object} o
|
|
42
|
+
* @param {string} o.userPath the user's ~/.claude/settings.json
|
|
43
|
+
* @param {Array<{path:string,label?:string}>} [o.projects] the registered projects
|
|
44
|
+
* @param {string} [o.managedPath] managed settings (managedClaudeSettingsPath)
|
|
45
|
+
* @param {string} [o.platform]
|
|
46
|
+
* @param {object|null} [o.runtime] lib/packaged-runtime.js packagedRuntime()
|
|
47
|
+
* @param {(path:string) => string} [o.read] @param {(path:string) => boolean} [o.exists]
|
|
48
|
+
* @param {(path:string) => boolean} [o.runnable] a file Node could be started from (tests)
|
|
49
|
+
* @param {string} [o.home]
|
|
50
|
+
*/
|
|
51
|
+
export function claudeHooksStatus({ userPath, projects = [], managedPath = managedClaudeSettingsPath(), platform = process.platform, runtime = packagedRuntime(), read, exists, runnable, home = homedir() } = {}) {
|
|
52
|
+
const io = { ...(read ? { read } : {}), ...(exists ? { exists } : {}) };
|
|
53
|
+
const base = { version: CLAUDE_HOOKS_STATUS_VERSION, settingsPath: userPath || null, installBlocker: hookInstallBlocker(runtime) };
|
|
54
|
+
const user = readSettingsFile(userPath, io);
|
|
55
|
+
if (user.error) return { ...base, state: 'error', error: user.error, installed: 0, current: 0, duplicates: 0, total: 0, events: {}, blockedBy: null, projects: [], node: null, nodeMissing: false, needsRepair: false };
|
|
56
|
+
const settings = user.settings || {};
|
|
57
|
+
const install = hookInstallState(settings, { runtime, platform });
|
|
58
|
+
const state = install.installed === 0 ? 'off' : install.installed === install.total ? 'on' : 'partial';
|
|
59
|
+
|
|
60
|
+
// Claude Code's own switches. Managed settings first: nothing below them can turn hooks back on.
|
|
61
|
+
let blockedBy = null;
|
|
62
|
+
const managed = readSettingsFile(managedPath, io);
|
|
63
|
+
const managedSwitch = hooksSwitchedOff(managed.settings, { managed: true });
|
|
64
|
+
if (managedSwitch) blockedBy = { setting: managedSwitch, scope: 'managed', path: managedPath };
|
|
65
|
+
else {
|
|
66
|
+
const userSwitch = hooksSwitchedOff(settings);
|
|
67
|
+
if (userSwitch) blockedBy = { setting: userSwitch, scope: 'user', path: userPath };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// The registered projects: hooks switched off there, or SynaBun handlers that would run next to the user's.
|
|
71
|
+
const projectIssues = [];
|
|
72
|
+
for (const project of Array.isArray(projects) ? projects : []) {
|
|
73
|
+
if (!project?.path) continue;
|
|
74
|
+
for (const name of ['settings.json', 'settings.local.json']) {
|
|
75
|
+
const file = join(project.path, '.claude', name);
|
|
76
|
+
const found = readSettingsFile(file, io);
|
|
77
|
+
if (!found.settings) continue;
|
|
78
|
+
let issue = hooksSwitchedOff(found.settings) ? 'disableAllHooks' : projectHooksAgree(settings, found.settings) === 'different' ? 'different' : null;
|
|
79
|
+
// Off for the user, still on there: that project's sessions keep running them.
|
|
80
|
+
if (!issue && install.installed === 0 && hookInstallState(found.settings, { targetProjectPath: project.path, runtime, platform }).installed > 0) issue = 'project-only';
|
|
81
|
+
if (issue) projectIssues.push({ path: project.path, label: project.label || null, file, issue });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Asked of the packaged application too: its entry finds its own Node, so the answer is only shown for the others.
|
|
86
|
+
const node = platform === 'win32' || runtime ? null : hookNodeWithoutPath({ env: settings.env || {}, home, platform, ...(runnable ? { runnable } : {}) });
|
|
87
|
+
const nodeMissing = install.installed > 0 && platform !== 'win32' && !runtime && !node;
|
|
88
|
+
return {
|
|
89
|
+
...base,
|
|
90
|
+
state,
|
|
91
|
+
installed: install.installed,
|
|
92
|
+
current: install.current,
|
|
93
|
+
duplicates: install.duplicates,
|
|
94
|
+
total: install.total,
|
|
95
|
+
events: install.events,
|
|
96
|
+
blockedBy,
|
|
97
|
+
projects: projectIssues,
|
|
98
|
+
node,
|
|
99
|
+
nodeMissing,
|
|
100
|
+
// What turning the hooks on again would put right: an old command form, an extra copy, a project out of step.
|
|
101
|
+
needsRepair: install.installed > 0 && (install.current < install.installed || install.duplicates > 0 || projectIssues.some((p) => p.issue === 'different') || nodeMissing),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
@@ -49,7 +49,7 @@ const READ_TOOLS = new Set([
|
|
|
49
49
|
]);
|
|
50
50
|
// One tool, both: the actions that only read. Any other action is refused, an
|
|
51
51
|
// action nobody listed included. `''` is the tool's own default action.
|
|
52
|
-
// (`
|
|
52
|
+
// (`tool_groups`: `add` / `set` write the runtime list, to a file and to the server.)
|
|
53
53
|
const READ_ACTIONS = Object.freeze({
|
|
54
54
|
memories: new Set(['recent', 'stats', 'by-category', 'by-project', 'get', 'get-batch', 'history', 'context']),
|
|
55
55
|
category: new Set(['list']),
|
|
@@ -57,7 +57,7 @@ const READ_ACTIONS = Object.freeze({
|
|
|
57
57
|
fb_groups: new Set(['worklist', 'list', 'stats']),
|
|
58
58
|
image_staged: new Set(['list']),
|
|
59
59
|
morelogin: new Set(['status', 'list']),
|
|
60
|
-
|
|
60
|
+
tool_groups: new Set(['get']),
|
|
61
61
|
});
|
|
62
62
|
// Acting on the outside world through the browser, an API or the desktop: what
|
|
63
63
|
// Bash and Edit do too. They leave what they do where they do it (a post, a
|
|
@@ -84,19 +84,13 @@ const ACT_TOOLS = new Set([
|
|
|
84
84
|
'gsc_removals_cancel', 'gsc_screenshot', 'gsc_security_issues', 'gsc_settings', 'gsc_shopping', 'gsc_sitemap', 'gsc_users', 'gsc_videos_report',
|
|
85
85
|
'youtube_analytics', 'youtube_channel', 'youtube_download', 'youtube_endscreen', 'youtube_metadata', 'youtube_navigate',
|
|
86
86
|
'youtube_playlist', 'youtube_schedule', 'youtube_source', 'youtube_thumbnail',
|
|
87
|
-
'leonardo_browser_download', 'leonardo_browser_generate', 'leonardo_browser_library', 'leonardo_browser_navigate',
|
|
88
87
|
'computer', 'computer_apps', 'computer_ax', 'computer_status',
|
|
89
88
|
'git',
|
|
90
89
|
]);
|
|
91
90
|
// An acting tool that also changes one of SynaBun's stores unless it is told
|
|
92
|
-
// not to: allowed with that input only
|
|
93
|
-
//
|
|
94
|
-
const ACT_WHEN = Object.freeze({
|
|
95
|
-
leonardo_browser_reference: {
|
|
96
|
-
ok: (input) => input?.autoClear === false,
|
|
97
|
-
why: 'it removes the staged images from SynaBun\'s store unless it is called with autoClear: false',
|
|
98
|
-
},
|
|
99
|
-
});
|
|
91
|
+
// not to: allowed with that input only, as `{ ok: (input) => boolean, why }`.
|
|
92
|
+
// No tool of the server needs one today.
|
|
93
|
+
const ACT_WHEN = Object.freeze({});
|
|
100
94
|
// Why a storing tool that looks like an acting one is off.
|
|
101
95
|
const STORE_REASONS = Object.freeze({
|
|
102
96
|
youtube_upload: 'it records every upload as a memory',
|