synabun 2.0.10 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +207 -0
- package/README.md +25 -2
- package/THIRD-PARTY-LICENSES.md +22 -0
- package/bin/synabun.js +71 -24
- package/docs/whatsapp.md +13 -13
- package/hooks/claude-code/pre-websearch.mjs +12 -1
- package/hooks/claude-code/shared.mjs +5 -0
- package/hooks/claude-code/stop.mjs +1 -1
- package/lib/claude-hooks.js +172 -18
- package/lib/client-config-repair.js +30 -17
- package/lib/desktop-app.js +7 -1
- package/lib/external-tools.js +7 -6
- package/lib/first-launch-protection.js +57 -12
- package/lib/mcp-dist.js +176 -0
- package/lib/release-npm-ci.mjs +138 -0
- package/lib/release-publish.mjs +91 -0
- package/lib/release-scan.mjs +50 -0
- package/lib/server-crash-record.js +123 -0
- package/lib/server-exit.js +318 -0
- package/lib/server-supervisor.js +508 -0
- package/lib/start-launcher.js +37 -4
- package/lib/tools-cli.js +45 -0
- package/lib/update-snapshot.js +302 -0
- package/lib/virustotal.mjs +203 -0
- package/lib/windows-crash-event.js +269 -0
- package/mcp-server/dist/http.d.ts +20 -1
- package/mcp-server/dist/http.d.ts.map +1 -1
- package/mcp-server/dist/http.js +59 -12
- package/mcp-server/dist/http.js.map +1 -1
- package/mcp-server/dist/index.d.ts +33 -27
- package/mcp-server/dist/index.d.ts.map +1 -1
- package/mcp-server/dist/index.js +128 -143
- package/mcp-server/dist/index.js.map +1 -1
- package/mcp-server/dist/preload.js +1 -1
- package/mcp-server/dist/preload.js.map +1 -1
- package/mcp-server/dist/services/budget-judgments.d.ts +1 -1
- package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -1
- package/mcp-server/dist/services/budget-judgments.js +5 -3
- package/mcp-server/dist/services/budget-judgments.js.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
- package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.js +81 -28
- package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
- package/mcp-server/dist/services/identity.d.ts +2 -2
- package/mcp-server/dist/services/identity.js +2 -2
- package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
- package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
- package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
- package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
- package/mcp-server/dist/services/memory-sessions.d.ts +1 -1
- package/mcp-server/dist/services/memory-sessions.d.ts.map +1 -1
- package/mcp-server/dist/services/memory-sessions.js +28 -2
- package/mcp-server/dist/services/memory-sessions.js.map +1 -1
- package/mcp-server/dist/services/neural-interface.d.ts +18 -11
- package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
- package/mcp-server/dist/services/neural-interface.js +67 -11
- package/mcp-server/dist/services/neural-interface.js.map +1 -1
- package/mcp-server/dist/services/server-instructions.d.ts +7 -2
- package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
- package/mcp-server/dist/services/server-instructions.js +22 -63
- package/mcp-server/dist/services/server-instructions.js.map +1 -1
- package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
- package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-catalog.js +339 -0
- package/mcp-server/dist/services/tool-catalog.js.map +1 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
- package/mcp-server/dist/services/tool-list.d.ts +108 -0
- package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-list.js +334 -0
- package/mcp-server/dist/services/tool-list.js.map +1 -0
- package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
- package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-runtime.js +400 -0
- package/mcp-server/dist/services/tool-runtime.js.map +1 -0
- package/mcp-server/dist/services/typesafe-config.js +1 -1
- package/mcp-server/dist/services/typesafe-config.js.map +1 -1
- package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
- package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
- package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
- package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
- package/mcp-server/dist/tools/agents.d.ts +14 -14
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +29 -19
- package/mcp-server/dist/tools/agents.js.map +1 -1
- package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
- package/mcp-server/dist/tools/choice.d.ts +6 -0
- package/mcp-server/dist/tools/choice.d.ts.map +1 -1
- package/mcp-server/dist/tools/choice.js +18 -13
- package/mcp-server/dist/tools/choice.js.map +1 -1
- package/mcp-server/dist/tools/git-tools.js +2 -2
- package/mcp-server/dist/tools/git-tools.js.map +1 -1
- package/mcp-server/dist/tools/image-tools.d.ts +1 -1
- package/mcp-server/dist/tools/image-tools.js +1 -1
- package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
- package/mcp-server/dist/tools/morelogin.js +9 -6
- package/mcp-server/dist/tools/morelogin.js.map +1 -1
- package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
- package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
- package/mcp-server/dist/tools/skill-tools.js +642 -0
- package/mcp-server/dist/tools/skill-tools.js.map +1 -0
- package/mcp-server/dist/tools/skill.d.ts +7 -0
- package/mcp-server/dist/tools/skill.d.ts.map +1 -0
- package/mcp-server/dist/tools/skill.js +11 -0
- package/mcp-server/dist/tools/skill.js.map +1 -0
- package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
- package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
- package/mcp-server/dist/tools/tool-groups.js +147 -0
- package/mcp-server/dist/tools/tool-groups.js.map +1 -0
- package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
- package/mcp-server/dist/tools/whiteboard-format.js +7 -4
- package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
- package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
- package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
- package/mcp-server/package-lock.json +2 -2
- package/mcp-server/package.json +1 -1
- package/mcp-server/src/http.ts +75 -12
- package/mcp-server/src/index.ts +147 -154
- package/mcp-server/src/preload.ts +12 -12
- package/mcp-server/src/services/budget-judgments.ts +5 -3
- package/mcp-server/src/services/codex-config-heal.ts +80 -29
- package/mcp-server/src/services/identity.ts +2 -2
- package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
- package/mcp-server/src/services/memory-sessions.ts +24 -3
- package/mcp-server/src/services/neural-interface.ts +81 -21
- package/mcp-server/src/services/server-instructions.ts +29 -64
- package/mcp-server/src/services/tool-catalog.ts +403 -0
- package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
- package/mcp-server/src/services/tool-list.ts +410 -0
- package/mcp-server/src/services/tool-runtime.ts +457 -0
- package/mcp-server/src/services/typesafe-config.ts +1 -1
- package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
- package/mcp-server/src/tools/agents.ts +29 -20
- package/mcp-server/src/tools/choice.ts +17 -12
- package/mcp-server/src/tools/git-tools.ts +2 -2
- package/mcp-server/src/tools/image-tools.ts +1 -1
- package/mcp-server/src/tools/morelogin.ts +6 -4
- package/mcp-server/src/tools/skill-tools.ts +592 -0
- package/mcp-server/src/tools/skill.ts +13 -0
- package/mcp-server/src/tools/tool-groups.ts +164 -0
- package/mcp-server/src/tools/whiteboard-format.ts +9 -3
- package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
- package/neural-interface/i18n/en.json +3953 -228
- package/neural-interface/i18n/pt-BR.json +3901 -179
- package/neural-interface/lib/agent-sandbox-elevation.js +6 -0
- package/neural-interface/lib/antigravity/acp-client-host.js +554 -0
- package/neural-interface/lib/antigravity/acp-connection.js +299 -0
- package/neural-interface/lib/antigravity/bypass.js +100 -0
- package/neural-interface/lib/antigravity/catalog.js +273 -0
- package/neural-interface/lib/antigravity/home.js +260 -0
- package/neural-interface/lib/antigravity/migrate-gemini.js +139 -0
- package/neural-interface/lib/antigravity/panel-bridge.js +1058 -0
- package/neural-interface/lib/antigravity/policy-hook.mjs +78 -0
- package/neural-interface/lib/antigravity/policy.js +74 -0
- package/neural-interface/lib/antigravity/tool-call.js +178 -0
- package/neural-interface/lib/antigravity/transcripts.js +252 -0
- package/neural-interface/lib/antigravity/usage.js +43 -0
- package/neural-interface/lib/assistant-api.js +128 -28
- package/neural-interface/lib/assistant-brains/antigravity.js +423 -0
- package/neural-interface/lib/assistant-brains/claude.js +4 -3
- package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
- package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
- package/neural-interface/lib/assistant-brains/codex.js +9 -5
- package/neural-interface/lib/assistant-brains/opencode.js +120 -54
- package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
- package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
- package/neural-interface/lib/assistant-budget-planner.js +7 -3
- package/neural-interface/lib/assistant-budget-split.js +42 -15
- package/neural-interface/lib/assistant-catalog.js +81 -15
- package/neural-interface/lib/assistant-config.js +6 -3
- package/neural-interface/lib/assistant-dispatch.js +1073 -200
- package/neural-interface/lib/assistant-envelope.js +156 -2
- package/neural-interface/lib/assistant-evidence.js +80 -0
- package/neural-interface/lib/assistant-hidden-models.js +7 -5
- package/neural-interface/lib/assistant-persona.js +93 -19
- package/neural-interface/lib/assistant-plan-permissions.js +25 -9
- package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
- package/neural-interface/lib/assistant-route-gate.js +6 -4
- package/neural-interface/lib/assistant-router.js +245 -38
- package/neural-interface/lib/assistant-runtime.js +214 -30
- package/neural-interface/lib/assistant-task-prompt.js +87 -21
- package/neural-interface/lib/assistant-tools.js +51 -0
- package/neural-interface/lib/assistant-usage.js +29 -0
- package/neural-interface/lib/backup-service.js +626 -4
- package/neural-interface/lib/backup-zip-reader.js +10 -5
- package/neural-interface/lib/backup-zip-writer.js +257 -0
- package/neural-interface/lib/browser-execution.js +10 -2
- package/neural-interface/lib/browser-guard-cdp.js +84 -0
- package/neural-interface/lib/browser-network-guard.js +476 -0
- package/neural-interface/lib/browser-policy-roots.js +64 -0
- package/neural-interface/lib/browser-tool-policy.js +198 -38
- package/neural-interface/lib/claude-agent-bridge.js +11 -2
- package/neural-interface/lib/claude-history-cache.js +210 -0
- package/neural-interface/lib/claude-hooks-status.js +103 -0
- package/neural-interface/lib/claude-model-catalog.js +5 -1
- package/neural-interface/lib/claude-temporary.js +5 -11
- package/neural-interface/lib/cli-install-api.js +1 -1
- package/neural-interface/lib/cli-install.js +163 -154
- package/neural-interface/lib/cli-resolver.js +13 -3
- package/neural-interface/lib/cli-update-planner.js +52 -41
- package/neural-interface/lib/cloudflared/tunnel.js +42 -2
- package/neural-interface/lib/codex-mcp-approvals.js +11 -0
- package/neural-interface/lib/codex-rollout-reader.js +52 -0
- package/neural-interface/lib/codex-worker-app-server.js +191 -0
- package/neural-interface/lib/confined-fs.js +30 -3
- package/neural-interface/lib/crash-notice-api.js +98 -0
- package/neural-interface/lib/editor-completion-opencode.js +68 -68
- package/neural-interface/lib/editor-git-api.js +3 -20
- package/neural-interface/lib/exec-loop-command.js +13 -10
- package/neural-interface/lib/file-explorer-api.js +74 -40
- package/neural-interface/lib/file-explorer-watch.js +9 -3
- package/neural-interface/lib/git-bash/install.js +52 -6
- package/neural-interface/lib/git-bash/manager.js +59 -17
- package/neural-interface/lib/git-bash/pins.js +12 -0
- package/neural-interface/lib/git-read.js +2 -2
- package/neural-interface/lib/git-status-runner.js +390 -0
- package/neural-interface/lib/git-status-watchdog.js +40 -0
- package/neural-interface/lib/greeting/budgets.js +1 -0
- package/neural-interface/lib/greeting/engine.js +2 -2
- package/neural-interface/lib/greeting/sources.js +10 -12
- package/neural-interface/lib/greeting/writer.js +1 -1
- package/neural-interface/lib/http-guards.js +8 -2
- package/neural-interface/lib/install-details.js +4 -1
- package/neural-interface/lib/mcp-agent-servers.js +67 -0
- package/neural-interface/lib/mcp-client-config.js +35 -33
- package/neural-interface/lib/mcp-external-servers.js +332 -0
- package/neural-interface/lib/mcp-installer.js +2 -1
- package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
- package/neural-interface/lib/memory-session-capture.js +17 -3
- package/neural-interface/lib/morelogin.js +177 -25
- package/neural-interface/lib/native-loop-providers.js +965 -66
- package/neural-interface/lib/native-loop-runtime.js +290 -42
- package/neural-interface/lib/opencode-config.js +557 -0
- package/neural-interface/lib/opencode-db-schema.js +17 -34
- package/neural-interface/lib/opencode-history.js +48 -218
- package/neural-interface/lib/opencode-mcp-ready.js +108 -0
- package/neural-interface/lib/opencode-native-boundary.js +53 -0
- package/neural-interface/lib/opencode-protocol.js +249 -112
- package/neural-interface/lib/opencode-runtime-config.js +32 -22
- package/neural-interface/lib/opencode-serve-records.js +39 -21
- package/neural-interface/lib/opencode-v2-client.js +48 -153
- package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
- package/neural-interface/lib/opencode-worker-data.js +27 -0
- package/neural-interface/lib/opencode2-client.js +73 -37
- package/neural-interface/lib/opencode2-proxy.js +23 -63
- package/neural-interface/lib/opencode2-translate.js +51 -2
- package/neural-interface/lib/owner-authority.js +249 -0
- package/neural-interface/lib/page-session.js +275 -0
- package/neural-interface/lib/path-confine.js +12 -9
- package/neural-interface/lib/peer-identity.js +793 -0
- package/neural-interface/lib/pty-host/core.js +28 -1
- package/neural-interface/lib/pty-host/lifetime.js +12 -0
- package/neural-interface/lib/pty-host/manager.js +12 -1
- package/neural-interface/lib/remote-policy.js +1 -1
- package/neural-interface/lib/request-gate.js +20 -2
- package/neural-interface/lib/rulesets/api.js +7 -6
- package/neural-interface/lib/rulesets/fs-safe.js +1 -1
- package/neural-interface/lib/rulesets/installer.js +180 -36
- package/neural-interface/lib/rulesets/json-edit.js +1 -1
- package/neural-interface/lib/rulesets/render.js +1 -1
- package/neural-interface/lib/session-cache-builder.js +81 -31
- package/neural-interface/lib/session-title-generator.js +58 -36
- package/neural-interface/lib/skills/api-v2.js +495 -0
- package/neural-interface/lib/skills/bundle.js +418 -0
- package/neural-interface/lib/skills/catalog.js +298 -0
- package/neural-interface/lib/skills/creation-api.js +191 -0
- package/neural-interface/lib/skills/creation-brief.js +247 -0
- package/neural-interface/lib/skills/creation-sources.js +285 -0
- package/neural-interface/lib/skills/creation.js +843 -0
- package/neural-interface/lib/skills/deploy.js +569 -0
- package/neural-interface/lib/skills/digest.js +119 -0
- package/neural-interface/lib/skills/discover.js +111 -0
- package/neural-interface/lib/skills/draft-confinement.js +216 -0
- package/neural-interface/lib/skills/eval-confinement.js +399 -0
- package/neural-interface/lib/skills/eval-sandbox.js +280 -0
- package/neural-interface/lib/skills/eval-trace.js +135 -0
- package/neural-interface/lib/skills/evals-api.js +212 -0
- package/neural-interface/lib/skills/evals.js +1573 -0
- package/neural-interface/lib/skills/export.js +203 -0
- package/neural-interface/lib/skills/frontmatter.js +64 -0
- package/neural-interface/lib/skills/health.js +75 -0
- package/neural-interface/lib/skills/json-edit.js +165 -0
- package/neural-interface/lib/skills/known-bridge-digests.json +441 -0
- package/neural-interface/lib/skills/known-bridges.js +96 -0
- package/neural-interface/lib/skills/library.js +823 -0
- package/neural-interface/lib/skills/local-store.js +21 -0
- package/neural-interface/lib/skills/migration.js +433 -0
- package/neural-interface/lib/skills/operations.js +45 -0
- package/neural-interface/lib/skills/ownership.js +427 -0
- package/neural-interface/lib/skills/packages.js +88 -0
- package/neural-interface/lib/skills/reviews.js +212 -0
- package/neural-interface/lib/skills/revision.js +80 -0
- package/neural-interface/lib/skills/roots.js +269 -0
- package/neural-interface/lib/skills/runtime-checks.js +358 -0
- package/neural-interface/lib/skills/scan-assets.js +252 -0
- package/neural-interface/lib/skills/scan-context.js +26 -0
- package/neural-interface/lib/skills/scan-shell.js +324 -0
- package/neural-interface/lib/skills/scan.js +364 -0
- package/neural-interface/lib/skills/scanners.js +54 -0
- package/neural-interface/lib/skills/service.js +530 -0
- package/neural-interface/lib/skills/telemetry.js +119 -0
- package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
- package/neural-interface/lib/synabun-version.js +1 -1
- package/neural-interface/lib/system-activity.js +1 -1
- package/neural-interface/lib/tool-lists.js +124 -0
- package/neural-interface/lib/whatsapp/brain.js +7 -3
- package/neural-interface/lib/whatsapp/bridge.js +6 -3
- package/neural-interface/lib/whatsapp/cards.js +22 -9
- package/neural-interface/lib/whatsapp/config.js +1 -1
- package/neural-interface/lib/worker-confinement.js +1268 -0
- package/neural-interface/lib/worker-guard-setting.js +56 -0
- package/neural-interface/lib/worker-mcp-channel.js +175 -0
- package/neural-interface/lib/worker-question.js +74 -0
- package/neural-interface/lib/worker-relay-ports.js +227 -0
- package/neural-interface/lib/worker-resume.js +238 -0
- package/neural-interface/lib/worker-sandbox.js +329 -0
- package/neural-interface/package-lock.json +34 -12
- package/neural-interface/package.json +3 -2
- package/neural-interface/public/index.html +3 -1
- package/neural-interface/public/index2d.html +19 -11
- package/neural-interface/public/onboarding.html +3 -3
- package/neural-interface/public/shared/account-menu.js +8 -5
- package/neural-interface/public/shared/agent-runtime-options.js +125 -31
- package/neural-interface/public/shared/agy/agy-bypass.js +47 -0
- package/neural-interface/public/shared/agy/agy-client.js +266 -0
- package/neural-interface/public/shared/agy/agy-commands.js +120 -0
- package/neural-interface/public/shared/agy/agy-copy.js +326 -0
- package/neural-interface/public/shared/agy/agy-diff.js +161 -0
- package/neural-interface/public/shared/agy/agy-events.js +469 -0
- package/neural-interface/public/shared/agy/agy-greeting.js +26 -0
- package/neural-interface/public/shared/agy/agy-options.js +232 -0
- package/neural-interface/public/shared/agy/agy-panel.js +2543 -0
- package/neural-interface/public/shared/agy/agy-render.js +392 -0
- package/neural-interface/public/shared/agy/agy-setup.js +149 -0
- package/neural-interface/public/shared/agy/agy-styles.js +604 -0
- package/neural-interface/public/shared/agy/agy-tabs-logic.js +181 -0
- package/neural-interface/public/shared/api.js +1527 -1336
- package/neural-interface/public/shared/app-frame.js +192 -0
- package/neural-interface/public/shared/assistant/asst-agents-dock.js +36 -6
- package/neural-interface/public/shared/assistant/asst-api.js +1 -1
- package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
- package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
- package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +105 -44
- package/neural-interface/public/shared/assistant/asst-budget.js +5 -4
- package/neural-interface/public/shared/assistant/asst-control.js +205 -26
- package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
- package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
- package/neural-interface/public/shared/assistant/asst-hosts.js +16 -7
- package/neural-interface/public/shared/assistant/asst-limit-dock.js +45 -0
- package/neural-interface/public/shared/assistant/asst-limit-wait.js +327 -0
- package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
- package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
- package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
- package/neural-interface/public/shared/assistant/asst-panel.js +151 -19
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
- package/neural-interface/public/shared/assistant/asst-render.js +445 -82
- package/neural-interface/public/shared/assistant/asst-route.js +304 -53
- package/neural-interface/public/shared/assistant/asst-routes-editor.js +9 -8
- package/neural-interface/public/shared/assistant/asst-scenes.js +56 -1
- package/neural-interface/public/shared/assistant/asst-sidepanel.js +117 -10
- package/neural-interface/public/shared/assistant/asst-slash.js +17 -9
- package/neural-interface/public/shared/assistant/asst-state.js +87 -24
- package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +93 -21
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +190 -23
- package/neural-interface/public/shared/assistant/asst-usage.js +2 -1
- package/neural-interface/public/shared/automation-context.js +5 -2
- package/neural-interface/public/shared/cc-dropdown.js +89 -19
- package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
- package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
- package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
- package/neural-interface/public/shared/cdx/cdx-output.js +34 -10
- package/neural-interface/public/shared/cdx/cdx-panel.js +59 -151
- package/neural-interface/public/shared/cdx/cdx-preview.js +12 -0
- package/neural-interface/public/shared/cdx/cdx-protocol.js +39 -11
- package/neural-interface/public/shared/cdx/cdx-render.js +57 -38
- package/neural-interface/public/shared/cdx/cdx-requests.js +14 -4
- package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
- package/neural-interface/public/shared/cdx/cdx-styles.js +15 -3
- package/neural-interface/public/shared/cdx/cdx-tabs.js +127 -44
- package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
- package/neural-interface/public/shared/cli-install-controller.js +218 -0
- package/neural-interface/public/shared/cli-install-view.js +11 -12
- package/neural-interface/public/shared/cli-status.js +11 -10
- package/neural-interface/public/shared/constants.js +5 -4
- package/neural-interface/public/shared/context-menu-areas.js +34 -0
- package/neural-interface/public/shared/context-menu-logic.js +243 -0
- package/neural-interface/public/shared/context-menu-model.js +367 -0
- package/neural-interface/public/shared/context-menu.js +372 -0
- package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
- package/neural-interface/public/shared/cp/cp-restore.js +162 -0
- package/neural-interface/public/shared/cp/cp-tool-cards.js +10 -3
- package/neural-interface/public/shared/crash-notice-view.js +168 -0
- package/neural-interface/public/shared/desktop-bridge.js +17 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +12 -0
- package/neural-interface/public/shared/desktop-titlebar.js +13 -4
- package/neural-interface/public/shared/desktop-update-view.js +21 -0
- package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
- package/neural-interface/public/shared/explorer/fx-api.js +4 -4
- package/neural-interface/public/shared/explorer/fx-links.js +3 -3
- package/neural-interface/public/shared/explorer/fx-logic.js +1 -1
- package/neural-interface/public/shared/explorer/fx-main.js +48 -16
- package/neural-interface/public/shared/explorer/fx-tree.js +1 -0
- package/neural-interface/public/shared/greeting/greeting-card.js +2 -2
- package/neural-interface/public/shared/greeting/greeting-view.js +1 -0
- package/neural-interface/public/shared/html-shell.js +30 -15
- package/neural-interface/public/shared/i18n.js +2 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
- package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
- package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
- package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
- package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
- package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
- package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +74 -259
- package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
- package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +13 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +13 -22
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
- package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
- package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
- package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
- package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
- package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +17 -21
- package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
- package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +60 -50
- package/neural-interface/public/shared/page-session.js +96 -0
- package/neural-interface/public/shared/provider-icons.js +4 -2
- package/neural-interface/public/shared/registry.js +5 -3
- package/neural-interface/public/shared/retired-2d.js +3 -0
- package/neural-interface/public/shared/schedules-view.js +195 -61
- package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
- package/neural-interface/public/shared/settings/settings-data.js +3 -1
- package/neural-interface/public/shared/settings/settings-ia.js +6 -6
- package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
- package/neural-interface/public/shared/settings/settings-rules.js +2 -2
- package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
- package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
- package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
- package/neural-interface/public/shared/showcase-privacy.js +6 -1
- package/neural-interface/public/shared/sidepanel-session-status.js +3 -3
- package/neural-interface/public/shared/skills/ss-args.js +96 -0
- package/neural-interface/public/shared/skills/ss-creation.js +222 -0
- package/neural-interface/public/shared/skills/ss-dialog.js +133 -0
- package/neural-interface/public/shared/skills/ss-doc.js +173 -0
- package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
- package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
- package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
- package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
- package/neural-interface/public/shared/skills/ss-evals.js +417 -0
- package/neural-interface/public/shared/skills/ss-form.js +159 -0
- package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
- package/neural-interface/public/shared/skills/ss-ids.js +32 -0
- package/neural-interface/public/shared/skills/ss-lint.js +149 -0
- package/neural-interface/public/shared/skills/ss-presets.js +117 -0
- package/neural-interface/public/shared/skills/ss-profiles.js +513 -0
- package/neural-interface/public/shared/skills/ss-resources.js +165 -0
- package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
- package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
- package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
- package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
- package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
- package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
- package/neural-interface/public/shared/skills/studio/sx-create-ai.js +237 -0
- package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
- package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
- package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
- package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
- package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
- package/neural-interface/public/shared/skills/studio/sx-dom.js +230 -0
- package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
- package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
- package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
- package/neural-interface/public/shared/skills/studio/sx-fixes-view.js +359 -0
- package/neural-interface/public/shared/skills/studio/sx-fixes.js +327 -0
- package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
- package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
- package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
- package/neural-interface/public/shared/skills/studio/sx-install-flow.js +282 -0
- package/neural-interface/public/shared/skills/studio/sx-install.js +313 -0
- package/neural-interface/public/shared/skills/studio/sx-library-view.js +748 -0
- package/neural-interface/public/shared/skills/studio/sx-library.js +479 -0
- package/neural-interface/public/shared/skills/studio/sx-main.js +690 -0
- package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
- package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
- package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
- package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
- package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
- package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
- package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
- package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
- package/neural-interface/public/shared/skills/studio/sx-subject.js +249 -0
- package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
- package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
- package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
- package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +426 -0
- package/neural-interface/public/shared/state.js +1 -1
- package/neural-interface/public/shared/streaming-markdown.js +58 -0
- package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
- package/neural-interface/public/shared/styles.css +1822 -1756
- package/neural-interface/public/shared/synabun-mascot.js +1115 -9
- package/neural-interface/public/shared/text-cache.js +29 -0
- package/neural-interface/public/shared/tool-list-picker.js +55 -0
- package/neural-interface/public/shared/tool-list-storage.js +24 -0
- package/neural-interface/public/shared/tool-list-view.js +112 -0
- package/neural-interface/public/shared/topright-overflow-logic.js +54 -0
- package/neural-interface/public/shared/tour/tour-actor.js +268 -0
- package/neural-interface/public/shared/tour/tour-beats.js +336 -0
- package/neural-interface/public/shared/tour/tour-engine.js +884 -0
- package/neural-interface/public/shared/tour/tour-ink.js +390 -0
- package/neural-interface/public/shared/tour/tour-stage.js +440 -0
- package/neural-interface/public/shared/tour/tour-state.js +40 -0
- package/neural-interface/public/shared/tour/tour-tips.js +99 -0
- package/neural-interface/public/shared/tour/tour.css +144 -0
- package/neural-interface/public/shared/ui-antigravity-panel.js +19 -0
- package/neural-interface/public/shared/ui-assistant.js +2 -0
- package/neural-interface/public/shared/ui-automation-studio.js +111 -140
- package/neural-interface/public/shared/ui-claude-panel.js +376 -82
- package/neural-interface/public/shared/ui-cli-banner.js +23 -167
- package/neural-interface/public/shared/ui-command-runner.js +6 -3
- package/neural-interface/public/shared/ui-context-menu.js +295 -0
- package/neural-interface/public/shared/ui-cost-widget.js +57 -59
- package/neural-interface/public/shared/ui-crash-notice.js +187 -0
- package/neural-interface/public/shared/ui-detail.js +15 -3
- package/neural-interface/public/shared/ui-file-explorer.js +48 -6
- package/neural-interface/public/shared/ui-file-links.js +2 -2
- package/neural-interface/public/shared/ui-games.js +2 -2
- package/neural-interface/public/shared/ui-image-gallery.js +50 -47
- package/neural-interface/public/shared/ui-judgments.js +1 -1
- package/neural-interface/public/shared/ui-keybinds.js +33 -2
- package/neural-interface/public/shared/ui-link.js +3 -3
- package/neural-interface/public/shared/ui-menubar.js +10 -20
- package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
- package/neural-interface/public/shared/ui-native-loop-router.js +11 -1
- package/neural-interface/public/shared/ui-navbar.js +49 -24
- package/neural-interface/public/shared/ui-notifications.js +1 -0
- package/neural-interface/public/shared/ui-panels.js +96 -65
- package/neural-interface/public/shared/ui-resume.js +9 -7
- package/neural-interface/public/shared/ui-schedules-studio.js +546 -431
- package/neural-interface/public/shared/ui-scroll-follow.js +16 -5
- package/neural-interface/public/shared/ui-sessions.js +27 -15
- package/neural-interface/public/shared/ui-settings.js +683 -526
- package/neural-interface/public/shared/ui-sidepanel-session-entry.js +9 -2
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +4 -4
- package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
- package/neural-interface/public/shared/ui-sidepanel-tray.js +48 -7
- package/neural-interface/public/shared/ui-sidepanel-windows.js +18 -13
- package/neural-interface/public/shared/ui-skills.js +33 -2830
- package/neural-interface/public/shared/ui-styleguide.js +5 -2
- package/neural-interface/public/shared/ui-sync.js +15 -5
- package/neural-interface/public/shared/ui-terminal.js +270 -190
- package/neural-interface/public/shared/ui-tool-updates.js +6 -4
- package/neural-interface/public/shared/ui-tooltip.js +81 -51
- package/neural-interface/public/shared/ui-topright-overflow.js +233 -0
- package/neural-interface/public/shared/ui-trash.js +6 -4
- package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
- package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
- package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
- package/neural-interface/public/shared/ui-tutorial.css +47 -100
- package/neural-interface/public/shared/ui-tutorial.js +285 -509
- package/neural-interface/public/shared/ui-update.js +38 -2
- package/neural-interface/public/shared/ui-whiteboard.js +312 -59
- package/neural-interface/public/shared/ui-worker-end.js +5 -1
- package/neural-interface/public/shared/ui-workspaces.js +3 -2
- package/neural-interface/public/shared/view-variant.js +66 -0
- package/neural-interface/public/shared/whatsapp/wa-view.js +3 -3
- package/neural-interface/public/shared/whiteboard-list.js +172 -0
- package/neural-interface/public/shared/worker-end.js +10 -3
- package/neural-interface/public/shared/worker-questions.js +34 -0
- package/neural-interface/public/shared/worker-restart.js +12 -0
- package/neural-interface/public/sidepanel-session.html +2 -2
- package/neural-interface/public/variant/2d/background.js +2 -1
- package/neural-interface/public/variant/2d/context-menu.js +8 -2
- package/neural-interface/public/variant/2d/graph.js +42 -20
- package/neural-interface/public/variant/2d/hulls.js +14 -9
- package/neural-interface/public/variant/2d/lasso.js +11 -7
- package/neural-interface/public/variant/2d/main.js +32 -1
- package/neural-interface/public/variant/2d/minimap.js +11 -13
- package/neural-interface/public/variant/3d/main.js +69 -6
- package/neural-interface/public/variant/3d/map-controls.js +24 -9
- package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
- package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
- package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
- package/neural-interface/public/vendor/caveat/caveat.css +17 -0
- package/neural-interface/public/vendor/caveat/manifest.json +12 -0
- package/neural-interface/public/vendor/yaml/LICENSE +13 -0
- package/neural-interface/public/vendor/yaml/manifest.json +4 -0
- package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
- package/neural-interface/scripts/build-vendor.mjs +32 -0
- package/neural-interface/server.js +4553 -2855
- package/neural-interface/templates/rulesets/README.md +1 -1
- package/neural-interface/templates/rulesets/core.md +1 -1
- package/neural-interface/templates/rulesets/legacy-hashes.json +23 -5
- package/neural-interface/templates/rulesets/manifest.json +8 -8
- package/npm-shrinkwrap.json +34 -12
- package/package.json +17 -3
- package/postinstall.js +9 -4
- package/preuninstall.js +1 -1
- package/setup.js +97 -322
- package/skills/skill-forge/SKILL.md +177 -0
- package/skills/skill-forge/evals/evals.json +54 -0
- package/skills/skill-forge/references/package.md +105 -0
- package/skills/skill-forge/references/review-and-recovery.md +63 -0
- package/skills/skill-forge/references/runtime-profiles.md +20 -0
- package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
- package/skills/synabun/SKILL.md +10 -7
- package/skills/synabun/modules/audit.md +1 -5
- package/skills/synabun/modules/changelog.md +1 -5
- package/skills/synabun/modules/idea.md +1 -1
- package/skills/synabun/modules/memorize.md +6 -9
- package/skills/synabun/modules/schedule.md +6 -6
- package/mcp-server/dist/services/profiles.d.ts +0 -120
- package/mcp-server/dist/services/profiles.d.ts.map +0 -1
- package/mcp-server/dist/services/profiles.js +0 -387
- package/mcp-server/dist/services/profiles.js.map +0 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
- package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
- package/mcp-server/dist/tools/leonardo.d.ts +0 -13
- package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
- package/mcp-server/dist/tools/leonardo.js +0 -21
- package/mcp-server/dist/tools/leonardo.js.map +0 -1
- package/mcp-server/dist/tools/profile.d.ts +0 -17
- package/mcp-server/dist/tools/profile.d.ts.map +0 -1
- package/mcp-server/dist/tools/profile.js +0 -114
- package/mcp-server/dist/tools/profile.js.map +0 -1
- package/mcp-server/src/services/profiles.ts +0 -428
- package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
- package/mcp-server/src/tools/leonardo.ts +0 -30
- package/mcp-server/src/tools/profile.ts +0 -122
- package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
- package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
- package/neural-interface/lib/mcp-profile-servers.js +0 -120
- package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
- package/skills/leonardo/SKILL.md +0 -168
- package/skills/leonardo/icon.svg +0 -1
- package/skills/leonardo/modules/browser-guide.md +0 -378
- package/skills/leonardo/modules/image-prompter.md +0 -283
- package/skills/leonardo/modules/model-advisor.md +0 -100
- package/skills/leonardo/modules/prompt-library.md +0 -110
- package/skills/leonardo/modules/style-guide.md +0 -186
- package/skills/leonardo/modules/video-prompter.md +0 -317
- /package/neural-interface/templates/rulesets/{gemini.md → antigravity.md} +0 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SynaBun Neural Interface — Skills Studio 2.0: what can be done about each health problem
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// Every health item the Library shows (sx-library.js healthOf), and the few problems only this module finds (two
|
|
6
|
+
// library records of one skill, an installation older than the skill's latest version, folders the catalog could not
|
|
7
|
+
// read), get a resolution path here:
|
|
8
|
+
// - `auto`: one press, no choice to make, and nothing lost (frontmatter added to a SKILL.md that has none, a
|
|
9
|
+
// description taken from its own first paragraph, a second library record archived: Restore brings it back);
|
|
10
|
+
// - `guided`: a choice the owner makes (which copy to keep, rename or leave, update or keep mine): the panel says
|
|
11
|
+
// what each choice does and opens the place where it is made;
|
|
12
|
+
// - `dismiss`: the owner has seen it and it is fine as it is; kept per item and per problem (its fingerprint), so a
|
|
13
|
+
// problem that changes (another count, another runtime) is said again.
|
|
14
|
+
// Writes are never made here: the view (sx-fixes-view.js) sends them through the Studio's API (X-SynaBun-UI), and an
|
|
15
|
+
// install location is changed only through the existing install / remove flows. No DOM and no imports but the lint's
|
|
16
|
+
// name rule.
|
|
17
|
+
|
|
18
|
+
import { NAME_MAX } from '../ss-lint.js';
|
|
19
|
+
|
|
20
|
+
export const DISMISSED_KEY = 'skills-studio-dismissed-issues';
|
|
21
|
+
|
|
22
|
+
/** Every issue kind, with its default resolution mode (a kind may still be guided for one row: see issuesOf). */
|
|
23
|
+
export const ISSUE_KINDS = Object.freeze({
|
|
24
|
+
'not-text': 'guided',
|
|
25
|
+
invalid: 'guided',
|
|
26
|
+
warnings: 'guided',
|
|
27
|
+
update: 'guided',
|
|
28
|
+
shadowed: 'guided',
|
|
29
|
+
twice: 'guided',
|
|
30
|
+
'same-description': 'guided',
|
|
31
|
+
bridge: 'guided',
|
|
32
|
+
'duplicate-record': 'auto',
|
|
33
|
+
'stale-install': 'guided',
|
|
34
|
+
unreadable: 'guided',
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
/** The text rules a safe fix knows how to repair (sx-fixes-view reads the artifact's diagnostics to find them). */
|
|
38
|
+
export const TEXT_FIX_RULES = Object.freeze(['fm-missing', 'description-missing']);
|
|
39
|
+
|
|
40
|
+
const NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
41
|
+
const lower = (v) => (typeof v === 'string' ? v.toLowerCase() : '');
|
|
42
|
+
|
|
43
|
+
/** What makes one problem of one row itself: a different count or runtime is a different problem. */
|
|
44
|
+
export function fingerprintOf(rowKey, h) {
|
|
45
|
+
const detail = h.code === 'invalid' || h.code === 'warnings' ? String(h.count ?? '')
|
|
46
|
+
: h.code === 'shadowed' || h.code === 'twice' ? String(h.runtime || '')
|
|
47
|
+
: h.code === 'same-description' ? (h.names || []).map(lower).sort().join(',')
|
|
48
|
+
: h.code === 'bridge' ? (h.runtimes || []).slice().sort().join(',')
|
|
49
|
+
: h.code === 'duplicate-record' ? String(h.of || '')
|
|
50
|
+
: h.code === 'stale-install' ? String(h.latest || '')
|
|
51
|
+
: h.code === 'unreadable' ? String(h.count ?? '')
|
|
52
|
+
: '';
|
|
53
|
+
return `${rowKey}|${h.code}|${detail}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The dismissed problems, as a set of fingerprints, from what storage kept (anything unreadable is nothing). */
|
|
57
|
+
export function readDismissed(raw) {
|
|
58
|
+
try {
|
|
59
|
+
const o = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
|
60
|
+
return new Set(o && typeof o === 'object' && !Array.isArray(o) ? Object.keys(o) : []);
|
|
61
|
+
} catch { return new Set(); }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Storage text with these fingerprints added (each with when), at most 500 kept (the oldest go first). */
|
|
65
|
+
export function addDismissed(raw, fingerprints, now = new Date().toISOString()) {
|
|
66
|
+
let o = {};
|
|
67
|
+
try { const p = typeof raw === 'string' ? JSON.parse(raw) : raw; if (p && typeof p === 'object' && !Array.isArray(p)) o = p; } catch { o = {}; }
|
|
68
|
+
for (const f of fingerprints) o[f] = now;
|
|
69
|
+
const kept = Object.entries(o).sort((a, b) => String(b[1]).localeCompare(String(a[1]))).slice(0, 500);
|
|
70
|
+
return JSON.stringify(Object.fromEntries(kept));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Storage text without these fingerprints (Show again). */
|
|
74
|
+
export function removeDismissed(raw, fingerprints) {
|
|
75
|
+
let o = {};
|
|
76
|
+
try { const p = typeof raw === 'string' ? JSON.parse(raw) : raw; if (p && typeof p === 'object' && !Array.isArray(p)) o = p; } catch { o = {}; }
|
|
77
|
+
for (const f of fingerprints) delete o[f];
|
|
78
|
+
return JSON.stringify(o);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const SEVERITY_RANK = { err: 0, warn: 1, info: 2, off: 3, ok: 4 };
|
|
82
|
+
const DUP_WEIGHT = 250;
|
|
83
|
+
const STALE_WEIGHT = 60;
|
|
84
|
+
|
|
85
|
+
/** Who keeps the name when two library records hold one skill: installed, adopted, more versions, then the oldest. */
|
|
86
|
+
function originalFirst(a, b) {
|
|
87
|
+
const ia = (a.skill.installations || []).length; const ib = (b.skill.installations || []).length;
|
|
88
|
+
if (!!ia !== !!ib) return ib - ia;
|
|
89
|
+
const oa = a.skill.origin?.kind === 'adopted' ? 0 : 1; const ob = b.skill.origin?.kind === 'adopted' ? 0 : 1;
|
|
90
|
+
if (oa !== ob) return oa - ob;
|
|
91
|
+
if ((b.skill.revisions || 0) !== (a.skill.revisions || 0)) return (b.skill.revisions || 0) - (a.skill.revisions || 0);
|
|
92
|
+
return String(a.skill.createdAt || '').localeCompare(String(b.skill.createdAt || '')) || a.key.localeCompare(b.key);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Library records that are one skill twice (the same name, neither shipped by SynaBun): every record but the one that
|
|
97
|
+
* keeps the name, with `safe` when archiving it loses nothing (not installed, no open review, and no version or the
|
|
98
|
+
* very content of the original's latest). Archived, a record comes back with Restore.
|
|
99
|
+
* @returns {{ row: object, original: object, safe: boolean, why: string }[]}
|
|
100
|
+
*/
|
|
101
|
+
export function duplicateRecords(rows) {
|
|
102
|
+
const groups = new Map();
|
|
103
|
+
for (const row of rows) {
|
|
104
|
+
const s = row.skill;
|
|
105
|
+
if (!s?.skillId || s.origin?.kind === 'bundled' || !s.name) continue;
|
|
106
|
+
const k = lower(s.name);
|
|
107
|
+
if (!groups.has(k)) groups.set(k, []);
|
|
108
|
+
groups.get(k).push(row);
|
|
109
|
+
}
|
|
110
|
+
const out = [];
|
|
111
|
+
for (const list of groups.values()) {
|
|
112
|
+
if (list.length < 2) continue;
|
|
113
|
+
const sorted = list.slice().sort(originalFirst);
|
|
114
|
+
const original = sorted[0];
|
|
115
|
+
for (const row of sorted.slice(1)) {
|
|
116
|
+
const s = row.skill;
|
|
117
|
+
const why = (s.installations || []).length ? 'installed'
|
|
118
|
+
: row.review ? 'review'
|
|
119
|
+
: s.revisions && !(s.latest?.contentDigest && s.latest.contentDigest === original.skill.latest?.contentDigest) ? 'different'
|
|
120
|
+
: '';
|
|
121
|
+
out.push({ row, original, safe: !why, why });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The rows with what only this module finds added to their health (a duplicate record, an installation older than the
|
|
129
|
+
* latest version), the dismissed problems taken out, and attention counted again. Returns the same rows (changed).
|
|
130
|
+
* @param {object[]} rows built by sx-library.js buildRows
|
|
131
|
+
* @param {Set<string>} [dismissed] fingerprints
|
|
132
|
+
*/
|
|
133
|
+
export function applyFixState(rows, dismissed = new Set()) {
|
|
134
|
+
for (const d of duplicateRecords(rows)) {
|
|
135
|
+
if (!d.row.health.some((h) => h.code === 'duplicate-record')) d.row.health.push({ code: 'duplicate-record', sev: 'warn', of: d.original.key, name: d.original.label || d.original.name || '', safe: d.safe, why: d.why });
|
|
136
|
+
}
|
|
137
|
+
for (const row of rows) {
|
|
138
|
+
const s = row.skill;
|
|
139
|
+
const latest = s?.pointers?.latest || s?.latest?.revisionId || null;
|
|
140
|
+
if (latest && s.origin?.kind !== 'bundled' && !row.health.some((h) => h.code === 'stale-install')) {
|
|
141
|
+
const older = (s.installations || []).filter((i) => i.sourceRevisionId && i.sourceRevisionId !== latest);
|
|
142
|
+
if (older.length) row.health.push({ code: 'stale-install', sev: 'info', latest, count: older.length });
|
|
143
|
+
}
|
|
144
|
+
if (dismissed.size) row.health = row.health.filter((h) => h.sev === 'ok' || h.sev === 'off' || !dismissed.has(fingerprintOf(row.key, h)));
|
|
145
|
+
row.health = row.health.filter((h) => h.code !== 'ok');
|
|
146
|
+
if (!row.health.some((h) => h.sev === 'err' || h.sev === 'warn' || h.sev === 'info')) row.health.push({ code: 'ok', sev: 'ok' });
|
|
147
|
+
row.health.sort((a, b) => SEVERITY_RANK[a.sev] - SEVERITY_RANK[b.sev]);
|
|
148
|
+
const extra = row.health.reduce((n, h) => n + (h.code === 'duplicate-record' ? DUP_WEIGHT : h.code === 'stale-install' ? STALE_WEIGHT : 0), 0);
|
|
149
|
+
const base = dismissed.size ? recount(row) : row.attention || 0;
|
|
150
|
+
row.attention = base + extra;
|
|
151
|
+
row.needsAttention = row.attention > 0;
|
|
152
|
+
}
|
|
153
|
+
return rows;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// sx-library.js ATTENTION, for a row whose health lost dismissed items.
|
|
157
|
+
const ATTENTION = { 'not-text': 1000, invalid: 1000, update: 400, shadowed: 300, twice: 300, 'same-description': 200, bridge: 150, warnings: 100, review: 80, draft: 50 };
|
|
158
|
+
function recount(row) {
|
|
159
|
+
return row.health.reduce((n, h) => n + (ATTENTION[h.code] || 0) * (h.code === 'invalid' || h.code === 'warnings' ? Math.max(1, Math.min(9, Number(h.count) || 0)) : 1), 0);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* The issues of one row: each health item that is a problem, with what can be done about it.
|
|
164
|
+
* `can` says what the row allows: `edit` (its text can be changed here), `open` (it has a workspace), `archive` (the
|
|
165
|
+
* duplicate's record can leave the library), `dismiss` (not a guest).
|
|
166
|
+
* Actions: 'auto-text' (repair the text: which rules is learnt from the artifact's diagnostics), 'archive-duplicate',
|
|
167
|
+
* 'choose-copy', 'open-edit', 'open-publish', 'open-update', 'keep-mine', 'open-review', 'move-bridges',
|
|
168
|
+
* 'rescan', 'delete', 'dismiss'.
|
|
169
|
+
* @returns {{ code: string, sev: string, mode: 'auto'|'guided', fingerprint: string, health: object, actions: string[] }[]}
|
|
170
|
+
*/
|
|
171
|
+
export function issuesOf(row, can = {}) {
|
|
172
|
+
const out = [];
|
|
173
|
+
for (const h of row.health || []) {
|
|
174
|
+
if (!(h.code in ISSUE_KINDS)) continue;
|
|
175
|
+
const actions = [];
|
|
176
|
+
let mode = ISSUE_KINDS[h.code];
|
|
177
|
+
switch (h.code) {
|
|
178
|
+
case 'not-text':
|
|
179
|
+
if (can.open) actions.push('open-edit');
|
|
180
|
+
if (can.delete) actions.push('delete');
|
|
181
|
+
break;
|
|
182
|
+
case 'invalid':
|
|
183
|
+
case 'warnings':
|
|
184
|
+
// Whether a repair is safe is known once the text is read (the panel asks): until then it is guided.
|
|
185
|
+
if (can.edit) actions.push('auto-text');
|
|
186
|
+
if (can.open) actions.push('open-edit');
|
|
187
|
+
break;
|
|
188
|
+
case 'update':
|
|
189
|
+
if (can.open) actions.push('open-update', 'keep-mine');
|
|
190
|
+
break;
|
|
191
|
+
case 'shadowed':
|
|
192
|
+
case 'twice':
|
|
193
|
+
case 'same-description':
|
|
194
|
+
if (can.open) actions.push('open-edit');
|
|
195
|
+
break;
|
|
196
|
+
case 'bridge':
|
|
197
|
+
if (can.dismiss) actions.push('move-bridges');
|
|
198
|
+
break;
|
|
199
|
+
case 'duplicate-record':
|
|
200
|
+
if (!h.safe) mode = 'guided';
|
|
201
|
+
if (can.archive) actions.push(h.safe ? 'archive-duplicate' : 'choose-copy');
|
|
202
|
+
if (can.open) actions.push('open-edit');
|
|
203
|
+
break;
|
|
204
|
+
case 'stale-install':
|
|
205
|
+
if (can.open) actions.push('open-publish');
|
|
206
|
+
break;
|
|
207
|
+
default: break;
|
|
208
|
+
}
|
|
209
|
+
if (can.dismiss) actions.push('dismiss');
|
|
210
|
+
out.push({ code: h.code, sev: h.sev, mode, fingerprint: fingerprintOf(row.key, h), health: h, actions });
|
|
211
|
+
}
|
|
212
|
+
return out;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ── Text repairs ──
|
|
216
|
+
|
|
217
|
+
const INVISIBLE = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f----]/g;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* A description taken from a body's first paragraph of prose (not a heading, a list, a table, a quote or code),
|
|
221
|
+
* markdown marks removed, on one line, at most 280 characters cut at a word; null when there is none of 20 or more.
|
|
222
|
+
*/
|
|
223
|
+
export function descriptionFromBody(body) {
|
|
224
|
+
const lines = String(body || '').replace(/\r\n?/g, '\n').split('\n');
|
|
225
|
+
let inCode = false;
|
|
226
|
+
let para = [];
|
|
227
|
+
for (const line of lines) {
|
|
228
|
+
const tr = line.trim();
|
|
229
|
+
if (/^(```|~~~)/.test(tr)) { inCode = !inCode; if (para.length) break; continue; }
|
|
230
|
+
if (inCode) continue;
|
|
231
|
+
if (!tr) { if (para.length) break; continue; }
|
|
232
|
+
if (/^(#|[-*+]\s|\d+[.)]\s|\||>|<|---|===)/.test(tr)) { if (para.length) break; continue; }
|
|
233
|
+
para.push(tr);
|
|
234
|
+
}
|
|
235
|
+
let text = para.join(' ')
|
|
236
|
+
.replace(INVISIBLE, '')
|
|
237
|
+
.replace(/!\[[^\]]*\]\([^)]*\)/g, '')
|
|
238
|
+
.replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
|
|
239
|
+
.replace(/(\*\*|__|\*|_|`)(\S(?:.*?\S)?)\1/g, '$2')
|
|
240
|
+
.replace(/\s+/g, ' ')
|
|
241
|
+
.trim();
|
|
242
|
+
if (text.length < 20) return null;
|
|
243
|
+
if (text.length > 280) {
|
|
244
|
+
const cut = text.slice(0, 280);
|
|
245
|
+
const sentence = cut.lastIndexOf('. ');
|
|
246
|
+
text = sentence >= 120 ? cut.slice(0, sentence + 1) : `${cut.slice(0, cut.lastIndexOf(' ') > 200 ? cut.lastIndexOf(' ') : 280).trimEnd()}…`;
|
|
247
|
+
}
|
|
248
|
+
return text;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** A YAML scalar that reads back as exactly this text (a JSON string is a YAML double-quoted scalar). */
|
|
252
|
+
const yamlString = (s) => JSON.stringify(String(s));
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* The safe repair of a skill's or an agent's head file, from the problems its check found: frontmatter added to a file
|
|
256
|
+
* that has none (name from the folder when it is a valid name, description from its first paragraph), or a description
|
|
257
|
+
* added to frontmatter that lacks one. Line endings and a BOM are kept; nothing else changes. null when there is
|
|
258
|
+
* nothing safe to do (an agent needs both a name and a description; a description that cannot be taken from the text).
|
|
259
|
+
* @param {object} o
|
|
260
|
+
* @param {string} o.raw the file as read
|
|
261
|
+
* @param {{ ruleId: string }[]} o.diagnostics what the server's check said (GET artifact `diagnostics`)
|
|
262
|
+
* @param {'skill'|'agent'|'command'} o.type
|
|
263
|
+
* @param {string} [o.folderName]
|
|
264
|
+
* @returns {{ text: string, changes: { ruleId: string, added: string }[] } | null}
|
|
265
|
+
*/
|
|
266
|
+
export function planTextFix({ raw, diagnostics = [], type, folderName = '' }) {
|
|
267
|
+
if (typeof raw !== 'string' || type === 'command') return null;
|
|
268
|
+
const rules = new Set((diagnostics || []).map((d) => d?.ruleId));
|
|
269
|
+
const eol = raw.includes('\r\n') ? '\r\n' : '\n';
|
|
270
|
+
const bom = raw.startsWith('') ? '' : '';
|
|
271
|
+
const text = bom ? raw.slice(1) : raw;
|
|
272
|
+
if (rules.has('fm-missing')) {
|
|
273
|
+
if (/^---[ \t]*\r?\n/.test(text)) return null; // an unterminated block is the owner's to read
|
|
274
|
+
const name = NAME_RE.test(folderName) && folderName.length <= NAME_MAX ? folderName : '';
|
|
275
|
+
const description = descriptionFromBody(text);
|
|
276
|
+
if (type === 'agent' && (!name || !description)) return null;
|
|
277
|
+
if (!name && !description) return null;
|
|
278
|
+
const lines = ['---', ...(name ? [`name: ${name}`] : []), ...(description ? [`description: ${yamlString(description)}`] : []), '---', ''];
|
|
279
|
+
const changes = [];
|
|
280
|
+
if (name) changes.push({ ruleId: 'fm-missing', added: `name: ${name}` });
|
|
281
|
+
if (description) changes.push({ ruleId: 'fm-missing', added: `description: ${yamlString(description)}` });
|
|
282
|
+
return { text: `${bom}${lines.join(eol)}${text}`, changes };
|
|
283
|
+
}
|
|
284
|
+
if (rules.has('description-missing') && type === 'skill') {
|
|
285
|
+
const m = /^---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/.exec(text);
|
|
286
|
+
if (!m) return null;
|
|
287
|
+
const head = m[1];
|
|
288
|
+
if (/^description\s*:/m.test(head)) return null; // present but empty or of another type: the owner's to word
|
|
289
|
+
const body = text.slice(m[0].length);
|
|
290
|
+
const description = descriptionFromBody(body);
|
|
291
|
+
if (!description) return null;
|
|
292
|
+
const line = `description: ${yamlString(description)}`;
|
|
293
|
+
const headLines = head.split(/\r?\n/);
|
|
294
|
+
const at = headLines.findIndex((l) => /^name\s*:/.test(l));
|
|
295
|
+
headLines.splice(at >= 0 ? at + 1 : 0, 0, line);
|
|
296
|
+
const start = m[0].slice(0, m[0].indexOf('\n') + 1);
|
|
297
|
+
const close = m[0].slice(m[0].lastIndexOf(head) + head.length);
|
|
298
|
+
return { text: `${bom}${start}${headLines.join(eol)}${close}${body}`, changes: [{ ruleId: 'description-missing', added: line }] };
|
|
299
|
+
}
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* What "Fix all safe issues" would do, before it is done: one step per change, with the rows it skips and why.
|
|
305
|
+
* Text repairs are candidates until their file is read (`needsRead`), so the preview reads them first.
|
|
306
|
+
* @param {object[]} rows
|
|
307
|
+
* @param {(row: object) => object} canOf what each row allows (as for issuesOf)
|
|
308
|
+
* @returns {{ steps: { kind: 'text'|'archive', row: object, issue: object }[] }}
|
|
309
|
+
*/
|
|
310
|
+
export function safeFixCandidates(rows, canOf) {
|
|
311
|
+
const steps = [];
|
|
312
|
+
for (const row of rows) {
|
|
313
|
+
const can = canOf(row);
|
|
314
|
+
for (const issue of issuesOf(row, can)) {
|
|
315
|
+
if (issue.actions.includes('archive-duplicate')) steps.push({ kind: 'archive', row, issue });
|
|
316
|
+
else if (issue.actions.includes('auto-text') && !steps.some((s) => s.kind === 'text' && s.row === row)) steps.push({ kind: 'text', row, issue, needsRead: true });
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return { steps };
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/** How many issues the Library shows now, and how many of them have a one-press fix (text repairs not yet known). */
|
|
323
|
+
export function issueCounts(rows, canOf) {
|
|
324
|
+
let total = 0; let auto = 0;
|
|
325
|
+
for (const row of rows) for (const issue of issuesOf(row, canOf(row))) { total++; if (issue.actions.includes('archive-duplicate')) auto++; }
|
|
326
|
+
return { total, auto };
|
|
327
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SynaBun Neural Interface — Skills Studio 2.0: where the window is, and where a link takes it
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// The window opens where it was left (the shared panel system saves a moved or resized window, ui-panels.js), at
|
|
6
|
+
// min(1180px, 94% of the width) × min(760px, 86% of the height) the first time, and is kept inside the viewport
|
|
7
|
+
// below the menu bar. It can be docked: then it fills the work area beside the side panels (like the code editor)
|
|
8
|
+
// and leaves them usable. Its own width decides the layout (CSS container queries at 900 / 760 / 560 px):
|
|
9
|
+
// the rail folds to icons, the editor shows one pane at a time, the Library's rows become cards.
|
|
10
|
+
// A link into the Studio (`skills:open` with a detail) names a place, a skill, a review, a tab, a file and a line,
|
|
11
|
+
// or an AI drafting (a creation) to follow in Create.
|
|
12
|
+
// No DOM and no imports.
|
|
13
|
+
|
|
14
|
+
export const DEFAULT_SIZE = Object.freeze({ width: 1180, height: 760, widthShare: 0.94, heightShare: 0.86 });
|
|
15
|
+
export const MIN_SIZE = Object.freeze({ width: 380, height: 320 });
|
|
16
|
+
export const LAYOUTS = Object.freeze([{ name: 'compact', max: 560 }, { name: 'narrow', max: 760 }, { name: 'medium', max: 900 }]);
|
|
17
|
+
export const PLACES = Object.freeze(['library', 'review', 'create', 'discover', 'health']);
|
|
18
|
+
export const TABS = Object.freeze(['edit', 'test', 'versions', 'publish']);
|
|
19
|
+
|
|
20
|
+
const px = (v) => { const n = Number.parseFloat(v); return Number.isFinite(n) ? n : null; };
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The window's first rectangle: what was saved (kept inside the viewport), else the default size, centred.
|
|
24
|
+
* `frame` is the app frame's rect when the page has one (app-frame.js frameRect()): the window stays inside it, up to
|
|
25
|
+
* its edges. Without it, the window below the menu bar.
|
|
26
|
+
* @param {{ vw: number, vh: number, navbar?: number, saved?: { left?, top?, width?, height? } | null,
|
|
27
|
+
* frame?: { left: number, top: number, right: number, bottom: number } | null }} o
|
|
28
|
+
*/
|
|
29
|
+
export function initialRect({ vw, vh, navbar = 48, saved = null, frame = null }) {
|
|
30
|
+
const b = frame || { left: 0, top: navbar, right: vw, bottom: vh };
|
|
31
|
+
const bw = b.right - b.left, bh = b.bottom - b.top;
|
|
32
|
+
const room = frame
|
|
33
|
+
? { width: Math.max(MIN_SIZE.width, bw), height: Math.max(MIN_SIZE.height, bh) }
|
|
34
|
+
: { width: Math.max(MIN_SIZE.width, vw - 20), height: Math.max(MIN_SIZE.height, vh - navbar - 10) };
|
|
35
|
+
let width = px(saved?.width) ?? Math.min(DEFAULT_SIZE.width, Math.round((frame ? bw : vw) * DEFAULT_SIZE.widthShare));
|
|
36
|
+
let height = px(saved?.height) ?? Math.min(DEFAULT_SIZE.height, Math.round((frame ? bh : vh) * DEFAULT_SIZE.heightShare));
|
|
37
|
+
width = Math.round(Math.max(MIN_SIZE.width, Math.min(width, room.width)));
|
|
38
|
+
height = Math.round(Math.max(MIN_SIZE.height, Math.min(height, room.height)));
|
|
39
|
+
let left = px(saved?.left);
|
|
40
|
+
let top = px(saved?.top);
|
|
41
|
+
if (left === null) left = Math.round(b.left + (bw - width) / 2);
|
|
42
|
+
if (top === null) top = Math.round(b.top + Math.max(0, (bh - height) / 2));
|
|
43
|
+
left = Math.round(Math.max(b.left, Math.min(left, b.right - width)));
|
|
44
|
+
top = Math.round(Math.max(b.top, Math.min(top, b.bottom - height)));
|
|
45
|
+
return { left, top, width, height };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** The layout a width of the window gets (the same thresholds as the CSS container queries). */
|
|
49
|
+
export function layoutOf(width) {
|
|
50
|
+
for (const l of LAYOUTS) if (width <= l.max) return l.name;
|
|
51
|
+
return 'wide';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A link into the Studio, normalised: unknown values fall back, ids are kept only when they have their shape.
|
|
56
|
+
* @param {object} detail what `skills:open` carried
|
|
57
|
+
* @returns {{ place: string, tab: string|null, skillId: string|null, artifactId: string|null, reviewId: string|null,
|
|
58
|
+
* name: string|null, file: string|null, line: number|null, create: string|null, creationId: string|null }}
|
|
59
|
+
*/
|
|
60
|
+
export function parseOpen(detail) {
|
|
61
|
+
const d = detail && typeof detail === 'object' ? detail : {};
|
|
62
|
+
const shaped = (v, re) => (typeof v === 'string' && re.test(v) ? v : null);
|
|
63
|
+
const out = {
|
|
64
|
+
place: PLACES.includes(d.place) ? d.place : null,
|
|
65
|
+
tab: TABS.includes(d.tab) ? d.tab : null,
|
|
66
|
+
skillId: shaped(d.skillId, /^skl_[0-9a-f]{20}$/),
|
|
67
|
+
artifactId: shaped(d.artifactId, /^art_[0-9a-f]{20}$/),
|
|
68
|
+
reviewId: shaped(d.reviewId, /^rvw_[0-9a-f]{20}$/),
|
|
69
|
+
name: typeof d.name === 'string' && d.name.length <= 128 && !/[\\/]/.test(d.name) ? d.name : null,
|
|
70
|
+
file: typeof d.file === 'string' && d.file.length <= 512 && !d.file.split('/').includes('..') && !d.file.startsWith('/') ? d.file : null,
|
|
71
|
+
line: Number.isInteger(d.line) && d.line > 0 ? d.line : null,
|
|
72
|
+
create: d.create === 'blank' || d.create === 'import' ? d.create : null,
|
|
73
|
+
creationId: shaped(d.creationId, /^crt_[0-9a-f]{20}$/),
|
|
74
|
+
};
|
|
75
|
+
if (!out.place) out.place = out.reviewId ? 'review' : (out.create || out.creationId) ? 'create' : 'library';
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** The keys of the Studio (also the help it shows): ⌘/Ctrl on a Mac or not. */
|
|
80
|
+
export function shortcutLabel(key, mac) {
|
|
81
|
+
return key.replace(/Mod/g, mac ? '⌘' : 'Ctrl').replace(/Alt/g, mac ? '⌥' : 'Alt').replace(/Shift/g, mac ? '⇧' : 'Shift').replace(/Enter/g, mac ? '↵' : 'Enter').replace(/\+/g, mac ? '' : '+');
|
|
82
|
+
}
|