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
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure logic for which external MCP servers a profile grants to a runtime,
|
|
3
|
-
* and the write-guard applied to runtimes that bypass permission prompts.
|
|
4
|
-
*
|
|
5
|
-
* Kept free of filesystem access so the reconciliation rules — which decide
|
|
6
|
-
* whether a user's de-selection survives a restart — can be tested directly.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
function asObject(value) {
|
|
10
|
-
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function builtinNames(registry) {
|
|
14
|
-
return new Set(
|
|
15
|
-
Object.entries(asObject(asObject(registry).servers))
|
|
16
|
-
.filter(([, info]) => asObject(info).builtin)
|
|
17
|
-
.map(([name]) => name)
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* External servers the given profile (default: the active one) grants.
|
|
23
|
-
* Builtins are excluded — runtimes inject SynaBun separately with their own pins.
|
|
24
|
-
*/
|
|
25
|
-
export function selectProfileServerNames(registry, profileName) {
|
|
26
|
-
const reg = asObject(registry);
|
|
27
|
-
const servers = asObject(reg.servers);
|
|
28
|
-
const profile = asObject(asObject(reg.profiles)[profileName || reg.activeProfile]);
|
|
29
|
-
if (!Array.isArray(profile.servers)) return [];
|
|
30
|
-
const builtins = builtinNames(reg);
|
|
31
|
-
return profile.servers.filter(name => servers[name] && !builtins.has(name));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Startup reconciliation. Mutates `registry` in place; returns true if anything changed.
|
|
36
|
-
*
|
|
37
|
-
* `profileDefaults.knownServers` is the migration marker. On the first run under this
|
|
38
|
-
* scheme we only record the servers that already exist, so a server the user removed in
|
|
39
|
-
* the External Servers grid stays removed. Afterwards, only genuinely new servers are
|
|
40
|
-
* auto-assigned, and only when `autoAddNewServers` is on. Builtins are pruned from
|
|
41
|
-
* every profile's list because runtimes never read them from there.
|
|
42
|
-
*/
|
|
43
|
-
export function reconcileProfileServers(registry) {
|
|
44
|
-
const reg = asObject(registry);
|
|
45
|
-
let changed = false;
|
|
46
|
-
|
|
47
|
-
if (!reg.profileDefaults) {
|
|
48
|
-
reg.profileDefaults = { autoAddNewServers: true, excludeProfiles: ['core'] };
|
|
49
|
-
changed = true;
|
|
50
|
-
}
|
|
51
|
-
const defaults = reg.profileDefaults;
|
|
52
|
-
const exclude = new Set(defaults.excludeProfiles || []);
|
|
53
|
-
const builtins = builtinNames(reg);
|
|
54
|
-
const assignable = Object.keys(asObject(reg.servers)).filter(name => !builtins.has(name));
|
|
55
|
-
const seeded = Array.isArray(defaults.knownServers);
|
|
56
|
-
const known = new Set(seeded ? defaults.knownServers : assignable);
|
|
57
|
-
|
|
58
|
-
for (const [profileName, rawProfile] of Object.entries(asObject(reg.profiles))) {
|
|
59
|
-
const profile = asObject(rawProfile);
|
|
60
|
-
if (!Array.isArray(profile.servers)) { profile.servers = []; changed = true; }
|
|
61
|
-
const pruned = profile.servers.filter(name => !builtins.has(name));
|
|
62
|
-
if (pruned.length !== profile.servers.length) { profile.servers = pruned; changed = true; }
|
|
63
|
-
if (exclude.has(profileName) || !defaults.autoAddNewServers) continue;
|
|
64
|
-
for (const serverName of assignable) {
|
|
65
|
-
if (known.has(serverName)) continue;
|
|
66
|
-
if (!profile.servers.includes(serverName)) {
|
|
67
|
-
profile.servers.push(serverName);
|
|
68
|
-
changed = true;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const nextKnown = assignable.slice().sort();
|
|
74
|
-
if (!seeded || nextKnown.join(' ') !== defaults.knownServers.slice().sort().join(' ')) {
|
|
75
|
-
defaults.knownServers = nextKnown;
|
|
76
|
-
changed = true;
|
|
77
|
-
}
|
|
78
|
-
return changed;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Tools that mutate ad state or spend budget, keyed by MCP server name.
|
|
83
|
-
*
|
|
84
|
-
* FleetView agents run with `--permission-mode bypassPermissions`, so the read-only
|
|
85
|
-
* allowlist in .claude/settings.json does not apply to them. These are pushed as
|
|
86
|
-
* `--disallowedTools` instead: agents keep full read/reporting access, while anything
|
|
87
|
-
* that creates, edits, activates, or deletes stays with a human.
|
|
88
|
-
*/
|
|
89
|
-
export const MCP_SERVER_WRITE_TOOLS = {
|
|
90
|
-
'meta-ads': [
|
|
91
|
-
'ads_create_campaign', 'ads_create_ad_set', 'ads_create_ad', 'ads_create_creative',
|
|
92
|
-
'ads_update_entity', 'ads_activate_entity', 'ads_boost_ig_post',
|
|
93
|
-
'ads_create_custom_audience', 'ads_update_custom_audience',
|
|
94
|
-
'ads_update_custom_audience_users', 'ads_delete_custom_audience',
|
|
95
|
-
'ads_catalog_create', 'ads_catalog_update_catalog',
|
|
96
|
-
'ads_catalog_product_create', 'ads_catalog_update_product', 'ads_catalog_delete_product',
|
|
97
|
-
'ads_catalog_create_product_set', 'ads_catalog_update_product_set', 'ads_catalog_product_set_delete',
|
|
98
|
-
'ads_catalog_create_product_feed', 'ads_catalog_update_product_feed',
|
|
99
|
-
'ads_catalog_create_product_feed_upload_session', 'ads_catalog_product_feed_delete',
|
|
100
|
-
'ads_catalog_create_feed_rule', 'ads_catalog_product_feed_delete_rule',
|
|
101
|
-
'ads_catalog_event_source_connect', 'ads_catalog_event_source_disconnect',
|
|
102
|
-
'ads_pixel_event_create', 'ads_pixel_event_update', 'ads_pixel_event_delete',
|
|
103
|
-
'ads_pixel_parameter_create', 'ads_pixel_parameter_update', 'ads_pixel_parameter_delete',
|
|
104
|
-
'ads_experiment_abtest_create_test', 'ads_experiment_abtest_update_test',
|
|
105
|
-
'ads_experiment_lift_create_test',
|
|
106
|
-
],
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
/** Fully-qualified deny list for whichever servers an agent's --mcp-config actually grants. */
|
|
110
|
-
export function buildAgentDisallowedTools(mcpConfigJson) {
|
|
111
|
-
let serverNames = [];
|
|
112
|
-
try {
|
|
113
|
-
serverNames = Object.keys(asObject(JSON.parse(mcpConfigJson || '{}')).mcpServers || {});
|
|
114
|
-
} catch { return []; }
|
|
115
|
-
const deny = [];
|
|
116
|
-
for (const server of serverNames) {
|
|
117
|
-
for (const tool of MCP_SERVER_WRITE_TOOLS[server] || []) deny.push(`mcp__${server}__${tool}`);
|
|
118
|
-
}
|
|
119
|
-
return deny;
|
|
120
|
-
}
|
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
// ═══════════════════════════════════════════
|
|
2
|
-
// TUTORIAL DRAWING ENGINE
|
|
3
|
-
// ═══════════════════════════════════════════
|
|
4
|
-
//
|
|
5
|
-
// Hand-drawn SVG primitives for the workspace tour, in the style of the
|
|
6
|
-
// whiteboard. Zero knowledge of tutorial steps — pure drawing utilities.
|
|
7
|
-
//
|
|
8
|
-
// Core techniques:
|
|
9
|
-
// - Catmull-Rom spline interpolation for smooth, organic curves
|
|
10
|
-
// - Seeded PRNG for deterministic wobble (same seed = same wobble every time)
|
|
11
|
-
// - SVG stroke-dashoffset transitions for the stroke-by-stroke "draw-in"
|
|
12
|
-
//
|
|
13
|
-
// Every primitive takes { duration, delay } in ms and returns { destroy }.
|
|
14
|
-
// A duration of 0 (or prefers-reduced-motion) renders the finished stroke.
|
|
15
|
-
|
|
16
|
-
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
17
|
-
const EASE = 'cubic-bezier(0.2, 0, 0, 1)';
|
|
18
|
-
|
|
19
|
-
/** Seeded random for consistent wobble per seed string. */
|
|
20
|
-
export function seededRand(seed) {
|
|
21
|
-
let h = 0;
|
|
22
|
-
for (let i = 0; i < seed.length; i++) {
|
|
23
|
-
h = ((h << 5) - h + seed.charCodeAt(i)) | 0;
|
|
24
|
-
}
|
|
25
|
-
return () => {
|
|
26
|
-
h = (h * 16807 + 0) % 2147483647;
|
|
27
|
-
return (h & 0x7fffffff) / 2147483647;
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** Convert points to a smooth SVG path using Catmull-Rom → cubic bezier (open path). */
|
|
32
|
-
export function pointsToSmoothPath(pts) {
|
|
33
|
-
if (pts.length === 0) return '';
|
|
34
|
-
if (pts.length === 1) return `M ${pts[0][0]} ${pts[0][1]}`;
|
|
35
|
-
if (pts.length === 2) return `M ${pts[0][0]} ${pts[0][1]} L ${pts[1][0]} ${pts[1][1]}`;
|
|
36
|
-
|
|
37
|
-
let d = `M ${pts[0][0]} ${pts[0][1]}`;
|
|
38
|
-
for (let i = 0; i < pts.length - 1; i++) {
|
|
39
|
-
const p0 = pts[Math.max(0, i - 1)];
|
|
40
|
-
const p1 = pts[i];
|
|
41
|
-
const p2 = pts[Math.min(pts.length - 1, i + 1)];
|
|
42
|
-
const p3 = pts[Math.min(pts.length - 1, i + 2)];
|
|
43
|
-
// 1/6 is the uniform Catmull-Rom tangent: evenly spaced points on a circle stay a circle.
|
|
44
|
-
const cp1x = p1[0] + (p2[0] - p0[0]) / 6;
|
|
45
|
-
const cp1y = p1[1] + (p2[1] - p0[1]) / 6;
|
|
46
|
-
const cp2x = p2[0] - (p3[0] - p1[0]) / 6;
|
|
47
|
-
const cp2y = p2[1] - (p3[1] - p1[1]) / 6;
|
|
48
|
-
d += ` C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${p2[0]} ${p2[1]}`;
|
|
49
|
-
}
|
|
50
|
-
return d;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// ═══════════════════════════════════════════
|
|
54
|
-
// SVG HELPERS
|
|
55
|
-
// ═══════════════════════════════════════════
|
|
56
|
-
|
|
57
|
-
const instant = (duration) => duration <= 0 || window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
58
|
-
|
|
59
|
-
function createSvgPath(container, d, color, strokeWidth = 2) {
|
|
60
|
-
const path = document.createElementNS(SVG_NS, 'path');
|
|
61
|
-
path.setAttribute('d', d);
|
|
62
|
-
path.setAttribute('fill', 'none');
|
|
63
|
-
path.setAttribute('stroke', color);
|
|
64
|
-
path.setAttribute('stroke-width', String(strokeWidth));
|
|
65
|
-
path.setAttribute('stroke-linecap', 'round');
|
|
66
|
-
path.setAttribute('stroke-linejoin', 'round');
|
|
67
|
-
container.appendChild(path);
|
|
68
|
-
return path;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function animateStrokeDash(path, duration, delay) {
|
|
72
|
-
if (instant(duration)) return;
|
|
73
|
-
const length = path.getTotalLength();
|
|
74
|
-
path.style.strokeDasharray = String(length);
|
|
75
|
-
path.style.strokeDashoffset = String(length);
|
|
76
|
-
// Committing the start value makes the transition run from it.
|
|
77
|
-
path.getBoundingClientRect();
|
|
78
|
-
path.style.transition = `stroke-dashoffset ${duration}ms ${EASE} ${delay}ms`;
|
|
79
|
-
path.style.strokeDashoffset = '0';
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// ═══════════════════════════════════════════
|
|
83
|
-
// OUTLINE (around a target or the note)
|
|
84
|
-
// ═══════════════════════════════════════════
|
|
85
|
-
|
|
86
|
-
/** An ellipse inscribed in the rect, with a tail that overshoots the start. */
|
|
87
|
-
function ringPath(rect, j) {
|
|
88
|
-
const cx = rect.left + rect.width / 2, cy = rect.top + rect.height / 2;
|
|
89
|
-
const rx = rect.width / 2, ry = rect.height / 2;
|
|
90
|
-
const pts = [], n = 16, total = Math.PI * 2 + 0.5;
|
|
91
|
-
for (let i = 0; i <= n; i++) {
|
|
92
|
-
const a = -2.2 + (i / n) * total;
|
|
93
|
-
// The tail drifts outwards, the way a pen leaves a circle.
|
|
94
|
-
const drift = i === n ? 3 : i === n - 1 ? 1.5 : 0;
|
|
95
|
-
pts.push([cx + Math.cos(a) * (rx + j() + drift), cy + Math.sin(a) * (ry + j() + drift)]);
|
|
96
|
-
}
|
|
97
|
-
return pointsToSmoothPath(pts);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/** A rounded rectangle, clockwise from the top edge: bowed sides, soft corners, closing past the start. */
|
|
101
|
-
function boxPath(rect, radius, j) {
|
|
102
|
-
const { left: x1, top: y1, right: x2, bottom: y2 } = rect;
|
|
103
|
-
const r = Math.max(2, Math.min(radius, rect.width / 2, rect.height / 2));
|
|
104
|
-
const sx = x1 + r + Math.min(18, (rect.width - 2 * r) / 2);
|
|
105
|
-
let d = `M ${sx} ${y1 + j()}`, px = sx, py = y1;
|
|
106
|
-
const side = (bx, by) => {
|
|
107
|
-
const steps = Math.max(1, Math.round(Math.hypot(bx - px, by - py) / 110));
|
|
108
|
-
const ax = px, ay = py;
|
|
109
|
-
for (let i = 1; i <= steps; i++) {
|
|
110
|
-
const ex = ax + (bx - ax) * i / steps + (i < steps ? j() : 0);
|
|
111
|
-
const ey = ay + (by - ay) * i / steps + (i < steps ? j() : 0);
|
|
112
|
-
d += ` Q ${(px + ex) / 2 + j()} ${(py + ey) / 2 + j()} ${ex} ${ey}`;
|
|
113
|
-
px = ex; py = ey;
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
const corner = (cx, cy, ex, ey) => { d += ` Q ${cx + j()} ${cy + j()} ${ex} ${ey}`; px = ex; py = ey; };
|
|
117
|
-
side(x2 - r, y1); corner(x2, y1, x2, y1 + r);
|
|
118
|
-
side(x2, y2 - r); corner(x2, y2, x2 - r, y2);
|
|
119
|
-
side(x1 + r, y2); corner(x1, y2, x1, y2 - r);
|
|
120
|
-
side(x1, y1 + r); corner(x1, y1, x1 + r, y1 - 1);
|
|
121
|
-
// Close past the start, a little above the first stroke.
|
|
122
|
-
const tail = Math.min(sx + 22, x2 - r);
|
|
123
|
-
return `${d} Q ${(px + tail) / 2} ${y1 - 1.5 + j()} ${tail} ${y1 - 2.5}`;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Draw a hand-drawn outline on a rect: a ring for compact targets, a rounded box otherwise.
|
|
128
|
-
* @param {SVGElement} svg
|
|
129
|
-
* @param {{left,top,right,bottom,width,height}} rect - where the stroke runs (padding included)
|
|
130
|
-
* @param {Object} config - { shape: 'ring'|'box', color, strokeWidth, radius, wobble, wobbleSeed, duration, delay }
|
|
131
|
-
* @returns {{ destroy: Function }}
|
|
132
|
-
*/
|
|
133
|
-
export function createOutline(svg, rect, config) {
|
|
134
|
-
const {
|
|
135
|
-
shape = 'box',
|
|
136
|
-
color = 'rgba(255,255,255,0.3)',
|
|
137
|
-
strokeWidth = 2,
|
|
138
|
-
radius = 12,
|
|
139
|
-
wobble = 1.6,
|
|
140
|
-
wobbleSeed = 'outline',
|
|
141
|
-
duration = 250,
|
|
142
|
-
delay = 0,
|
|
143
|
-
} = config;
|
|
144
|
-
|
|
145
|
-
const rand = seededRand(wobbleSeed);
|
|
146
|
-
const j = () => (rand() - 0.5) * wobble;
|
|
147
|
-
const path = createSvgPath(svg, shape === 'ring' ? ringPath(rect, j) : boxPath(rect, radius, j), color, strokeWidth);
|
|
148
|
-
animateStrokeDash(path, duration, delay);
|
|
149
|
-
|
|
150
|
-
return {
|
|
151
|
-
elements: [path],
|
|
152
|
-
destroy() { path.remove(); },
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// ═══════════════════════════════════════════
|
|
157
|
-
// ANIMATED ARROW
|
|
158
|
-
// ═══════════════════════════════════════════
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Draw a hand-drawn animated arrow from point A to point B.
|
|
162
|
-
* @param {SVGElement} svg - Container SVG element
|
|
163
|
-
* @param {Object} config - { from:{x,y}, to:{x,y}, color, wobbleSeed, duration, delay, arrowheadSize }
|
|
164
|
-
* @returns {{ destroy: Function }}
|
|
165
|
-
*/
|
|
166
|
-
export function createAnimatedArrow(svg, config) {
|
|
167
|
-
const {
|
|
168
|
-
from, to,
|
|
169
|
-
color = 'rgba(255,255,255,0.35)',
|
|
170
|
-
wobbleSeed = 'arrow',
|
|
171
|
-
duration = 250,
|
|
172
|
-
delay = 0,
|
|
173
|
-
arrowheadSize = 12,
|
|
174
|
-
strokeWidth = 2,
|
|
175
|
-
} = config;
|
|
176
|
-
|
|
177
|
-
const rand = seededRand(wobbleSeed);
|
|
178
|
-
const dx = to.x - from.x;
|
|
179
|
-
const dy = to.y - from.y;
|
|
180
|
-
const dist = Math.hypot(dx, dy);
|
|
181
|
-
const perpAngle = Math.atan2(dy, dx) + Math.PI / 2;
|
|
182
|
-
|
|
183
|
-
// Control point: gentle perpendicular offset, capped so long arrows stay tight
|
|
184
|
-
const arcAmount = Math.min(dist * (0.12 + rand() * 0.1), 40) * (rand() < 0.5 ? -1 : 1);
|
|
185
|
-
const cpX = (from.x + to.x) / 2 + Math.cos(perpAngle) * arcAmount;
|
|
186
|
-
const cpY = (from.y + to.y) / 2 + Math.sin(perpAngle) * arcAmount;
|
|
187
|
-
|
|
188
|
-
// Quadratic bezier — clean, predictable arc
|
|
189
|
-
const bodyPath = createSvgPath(svg, `M ${from.x} ${from.y} Q ${cpX} ${cpY} ${to.x} ${to.y}`, color, strokeWidth);
|
|
190
|
-
animateStrokeDash(bodyPath, duration, delay);
|
|
191
|
-
|
|
192
|
-
// Arrowhead: two strokes at the tip, along the direction the arrow arrives in
|
|
193
|
-
const endAngle = Math.atan2(to.y - cpY, to.x - cpX);
|
|
194
|
-
const s = Math.min(arrowheadSize, Math.max(6, dist / 3));
|
|
195
|
-
const spread = 0.5;
|
|
196
|
-
const head = createSvgPath(svg,
|
|
197
|
-
`M ${to.x - Math.cos(endAngle - spread) * s} ${to.y - Math.sin(endAngle - spread) * s}`
|
|
198
|
-
+ ` L ${to.x} ${to.y}`
|
|
199
|
-
+ ` L ${to.x - Math.cos(endAngle + spread) * s} ${to.y - Math.sin(endAngle + spread) * s}`, color, strokeWidth);
|
|
200
|
-
animateStrokeDash(head, Math.min(duration, 120), delay + duration);
|
|
201
|
-
|
|
202
|
-
return {
|
|
203
|
-
elements: [bodyPath, head],
|
|
204
|
-
destroy() { bodyPath.remove(); head.remove(); },
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// ═══════════════════════════════════════════
|
|
209
|
-
// HAND-DRAWN UNDERLINE
|
|
210
|
-
// ═══════════════════════════════════════════
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Draw a wavy hand-drawn underline beneath a rect.
|
|
214
|
-
* @param {SVGElement} svg
|
|
215
|
-
* @param {{left,bottom,width}} rect
|
|
216
|
-
* @param {Object} config - { color, wobbleSeed, duration, delay, offset }
|
|
217
|
-
* @returns {{ destroy: Function }}
|
|
218
|
-
*/
|
|
219
|
-
export function createHandDrawnUnderline(svg, rect, config) {
|
|
220
|
-
const {
|
|
221
|
-
color = 'rgba(255,255,255,0.3)',
|
|
222
|
-
wobbleSeed = 'underline',
|
|
223
|
-
duration = 200,
|
|
224
|
-
delay = 0,
|
|
225
|
-
offset = 4,
|
|
226
|
-
} = config;
|
|
227
|
-
|
|
228
|
-
const rand = seededRand(wobbleSeed);
|
|
229
|
-
const j = () => (rand() - 0.5) * 3;
|
|
230
|
-
|
|
231
|
-
const y = rect.bottom + offset;
|
|
232
|
-
const pts = [];
|
|
233
|
-
const segments = 5;
|
|
234
|
-
for (let i = 0; i <= segments; i++) {
|
|
235
|
-
pts.push([rect.left + rect.width * (i / segments) + j(), y + j()]);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const path = createSvgPath(svg, pointsToSmoothPath(pts), color, 2);
|
|
239
|
-
animateStrokeDash(path, duration, delay);
|
|
240
|
-
|
|
241
|
-
return {
|
|
242
|
-
elements: [path],
|
|
243
|
-
destroy() { path.remove(); },
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// ═══════════════════════════════════════════
|
|
248
|
-
// DOODLE LIBRARY
|
|
249
|
-
// ═══════════════════════════════════════════
|
|
250
|
-
|
|
251
|
-
const DOODLE_LIBRARY = {
|
|
252
|
-
sparkle: {
|
|
253
|
-
paths: [
|
|
254
|
-
// 4-pointed star
|
|
255
|
-
'M 20 4 Q 21 18 36 20 Q 21 22 20 36 Q 19 22 4 20 Q 19 18 20 4',
|
|
256
|
-
// Small dots around
|
|
257
|
-
'M 10 8 L 10.5 8.5',
|
|
258
|
-
'M 30 32 L 30.5 32.5',
|
|
259
|
-
],
|
|
260
|
-
},
|
|
261
|
-
checkmark: {
|
|
262
|
-
paths: [
|
|
263
|
-
'M 6 18 Q 10 22 14 26 Q 20 14 30 8',
|
|
264
|
-
],
|
|
265
|
-
},
|
|
266
|
-
alert: {
|
|
267
|
-
paths: [
|
|
268
|
-
// Triangle outline
|
|
269
|
-
'M 20 5 L 36 33 L 4 33 Z',
|
|
270
|
-
// Exclamation line and dot
|
|
271
|
-
'M 20 14 L 20 23',
|
|
272
|
-
'M 20 28 L 20.3 28.3',
|
|
273
|
-
],
|
|
274
|
-
},
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Render a pre-defined SVG doodle (40×40 box) with stroke-dashoffset draw-in.
|
|
279
|
-
* @param {SVGElement} svg
|
|
280
|
-
* @param {string} doodleId - Key into DOODLE_LIBRARY
|
|
281
|
-
* @param {Object} config - { x, y, scale, color, duration, delay }
|
|
282
|
-
* @returns {{ destroy: Function }}
|
|
283
|
-
*/
|
|
284
|
-
export function createDoodle(svg, doodleId, config) {
|
|
285
|
-
const doodle = DOODLE_LIBRARY[doodleId];
|
|
286
|
-
if (!doodle) return { elements: [], destroy() {} };
|
|
287
|
-
|
|
288
|
-
const {
|
|
289
|
-
x = 0, y = 0,
|
|
290
|
-
scale = 1,
|
|
291
|
-
color = 'rgba(255,255,255,0.3)',
|
|
292
|
-
duration = 200,
|
|
293
|
-
delay = 0,
|
|
294
|
-
} = config;
|
|
295
|
-
|
|
296
|
-
const g = document.createElementNS(SVG_NS, 'g');
|
|
297
|
-
g.setAttribute('transform', `translate(${x}, ${y}) scale(${scale})`);
|
|
298
|
-
svg.appendChild(g);
|
|
299
|
-
|
|
300
|
-
const elements = [g];
|
|
301
|
-
doodle.paths.forEach((pathD, i) => {
|
|
302
|
-
const path = createSvgPath(g, pathD, color, 2 / scale);
|
|
303
|
-
animateStrokeDash(path, duration, delay + i * 80);
|
|
304
|
-
elements.push(path);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
return {
|
|
308
|
-
elements,
|
|
309
|
-
destroy() { g.remove(); },
|
|
310
|
-
};
|
|
311
|
-
}
|
package/skills/leonardo/SKILL.md
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: leonardo
|
|
3
|
-
description: "Master Media Prompter — expert AI image & video creation via Leonardo.ai (100% browser-based)"
|
|
4
|
-
argument-hint: "[video|image|quick <prompt>] or leave blank for guided creation"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Leonardo — Master Media Prompter (Browser Edition)
|
|
8
|
-
|
|
9
|
-
You are an expert AI media prompter specializing in Leonardo.ai. The user has invoked `/leonardo`.
|
|
10
|
-
|
|
11
|
-
**Input**: $ARGUMENTS
|
|
12
|
-
|
|
13
|
-
**Base directory**: This skill's base directory is shown above as "Base directory for this skill". Store it as `$SKILL_DIR` — you'll need it to load module files.
|
|
14
|
-
|
|
15
|
-
## How This Works
|
|
16
|
-
|
|
17
|
-
This is a **100% browser-based** workflow. Leonardo.ai runs in SynaBun's headed browser. You configure everything through the browser UI — no API key needed.
|
|
18
|
-
|
|
19
|
-
**Your tools:**
|
|
20
|
-
- `leonardo_browser_navigate` — go to image/video/library pages
|
|
21
|
-
- `leonardo_browser_generate` — fill prompt + click Generate
|
|
22
|
-
- `leonardo_browser_download` — screenshot the current page
|
|
23
|
-
- Generic browser tools (`browser_click`, `browser_fill`, `browser_snapshot`, `browser_screenshot`, `browser_evaluate`, `browser_press`, `browser_wait`) — configure ALL settings in the UI
|
|
24
|
-
|
|
25
|
-
**Critical workflow:** Always configure settings (model, style, dimensions, etc.) BEFORE calling `leonardo_browser_generate`. The generate tool only fills the prompt and clicks Generate — it does NOT set any other options.
|
|
26
|
-
|
|
27
|
-
## Runtime Compatibility
|
|
28
|
-
|
|
29
|
-
- **Interactive choice prompt** means an interactive option card the user clicks — not plain text choices.
|
|
30
|
-
- **Claude Code (REQUIRED path):** `AskUserQuestion` is a deferred tool — its schema is not loaded by default. Before the first prompt in this skill, call `ToolSearch` with query `select:AskUserQuestion` to load it, then call `AskUserQuestion` with 2-4 options. NEVER write the choices as plain text — the sidepanel will render text as static markdown, not an interactive card.
|
|
31
|
-
- **OpenCode (REQUIRED path):** call the native `question` tool — the sidepanel renders it as an interactive card via the `/question.asked` event. NEVER write the choices as plain text.
|
|
32
|
-
- **Codex (REQUIRED path):** call `request_user_input` — the sidepanel renders it as an interactive card. NEVER write the choices as plain text.
|
|
33
|
-
- **Other runtimes:** only when no interactive tool exists, fall back to a concise plain-text multiple-choice question and wait for the user's reply.
|
|
34
|
-
- **Load/read a module file** means: use whatever local file-reading mechanism exists in the current runtime. Do not depend on a tool literally being named `Read`.
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Step 1 — Route or Quick Mode
|
|
39
|
-
|
|
40
|
-
Parse `$ARGUMENTS` to determine the path:
|
|
41
|
-
|
|
42
|
-
**Quick mode** (power users — skip questionnaire):
|
|
43
|
-
- If args start with `quick` → extract the rest as a raw prompt. Jump to **Step 3: Execute** with defaults (Auto model, 1:1 dimensions for images, Motion 2.0 Fast for video).
|
|
44
|
-
- `quick video <prompt>` → video defaults.
|
|
45
|
-
- `quick image <prompt>` → image defaults.
|
|
46
|
-
|
|
47
|
-
**Direct routing** (skip the menu):
|
|
48
|
-
- `video` or `vid` → set `$TOPIC` to remaining text, jump to **Step 2a: Video Prompter**.
|
|
49
|
-
- `image` or `img` or `photo` → set `$TOPIC` to remaining text, jump to **Step 2b: Image Prompter**.
|
|
50
|
-
- `upscale` → jump to **Step 2c: Upscale**.
|
|
51
|
-
|
|
52
|
-
**Interactive menu** (args empty or unrecognized):
|
|
53
|
-
|
|
54
|
-
Use an interactive choice prompt with options:
|
|
55
|
-
|
|
56
|
-
- **Create Video** — "Expert-guided video creation with full control over models, motion, styles, and prompt engineering"
|
|
57
|
-
- **Create Image** — "Expert-guided image creation with model selection, style presets, dimensions, and prompt engineering"
|
|
58
|
-
- **Quick Generate** — "Skip the questionnaire — just describe what you want and I'll handle the rest"
|
|
59
|
-
- **Browse Library** — "View your recent Leonardo.ai generations"
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## Step 2a — Video Prompter
|
|
64
|
-
|
|
65
|
-
Load/read the video prompter module:
|
|
66
|
-
```
|
|
67
|
-
Load/read $SKILL_DIR/modules/video-prompter.md
|
|
68
|
-
```
|
|
69
|
-
Follow that module's instructions completely. It will guide you through a comprehensive questionnaire using interactive choice prompts, covering: concept, model selection, motion controls, motion elements, style stacking (Vibe + Lighting + Color Theme), dimensions, prompt enhancement, negative prompt, and more. When the module produces final parameters, proceed to **Step 3: Execute**.
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## Step 2b — Image Prompter
|
|
74
|
-
|
|
75
|
-
Load/read the image prompter module:
|
|
76
|
-
```
|
|
77
|
-
Load/read $SKILL_DIR/modules/image-prompter.md
|
|
78
|
-
```
|
|
79
|
-
Follow that module's instructions completely. It will guide you through a comprehensive questionnaire using interactive choice prompts, covering: concept, model selection, style preset, dimensions, number of images, and prompt engineering. When the module produces final parameters, proceed to **Step 3: Execute**.
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
## Step 2c — Upscale
|
|
84
|
-
|
|
85
|
-
1. Navigate to the upscaler page:
|
|
86
|
-
```
|
|
87
|
-
leonardo_browser_navigate page: "upscaler"
|
|
88
|
-
```
|
|
89
|
-
2. Use `browser_snapshot` to see the upscaler UI.
|
|
90
|
-
3. Ask the user to provide the image (they can upload or select from library).
|
|
91
|
-
4. Use `browser_click` and `browser_fill` to configure upscale settings.
|
|
92
|
-
5. Click the upscale button.
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
## Step 3 — Execute (Browser Workflow)
|
|
97
|
-
|
|
98
|
-
You now have a complete set of parameters from the prompter module. Execute them through the browser:
|
|
99
|
-
|
|
100
|
-
### 3a. Navigate to the correct page
|
|
101
|
-
```
|
|
102
|
-
leonardo_browser_navigate page: "image" # or "video"
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### 3b. Wait for page to load, then take a snapshot
|
|
106
|
-
```
|
|
107
|
-
browser_wait loadState: "load" timeout: 10000
|
|
108
|
-
browser_snapshot
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### 3c. Configure ALL settings in the UI
|
|
112
|
-
|
|
113
|
-
Load/read the browser guide module for detailed UI navigation instructions:
|
|
114
|
-
```
|
|
115
|
-
Load/read $SKILL_DIR/modules/browser-guide.md
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Follow the browser guide to set each parameter via `browser_click`, `browser_fill`, `browser_evaluate`, etc. The guide maps every setting to its UI element.
|
|
119
|
-
|
|
120
|
-
### 3c-ii. Upload reference images (if any)
|
|
121
|
-
|
|
122
|
-
If the prompter module set `$REFERENCE_TYPE` and `$REFERENCE_PATHS` (or `$START_FRAME` / `$END_FRAME` for video):
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
leonardo_browser_reference type: "$REFERENCE_TYPE" filePaths: ["$PATH1", "$PATH2"] autoClear: true
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
This opens the reference panel, selects the correct reference type, uploads the image(s), and auto-clears them from the SynaBun image store. Use `browser_snapshot` after to verify the reference is applied.
|
|
129
|
-
|
|
130
|
-
### 3d. Present summary to user before generating
|
|
131
|
-
|
|
132
|
-
Show the user what you're about to generate:
|
|
133
|
-
```
|
|
134
|
-
Generating [type]...
|
|
135
|
-
Prompt: "[the engineered prompt]"
|
|
136
|
-
Model: [selected model]
|
|
137
|
-
[Style/Dimensions/Motion controls if applicable]
|
|
138
|
-
[Reference: $REFERENCE_TYPE with N image(s) — if applicable]
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### 3e. Fill prompt and generate
|
|
142
|
-
```
|
|
143
|
-
leonardo_browser_generate prompt: "[engineered prompt]" type: "[image|video]"
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### 3f. Monitor generation
|
|
147
|
-
|
|
148
|
-
Wait for generation to complete:
|
|
149
|
-
```
|
|
150
|
-
browser_wait timeout: 10000
|
|
151
|
-
browser_screenshot
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
Show the user the results and offer follow-up actions via an interactive choice prompt:
|
|
155
|
-
|
|
156
|
-
- **Generate Again** — "Same settings, new generation"
|
|
157
|
-
- **Modify & Regenerate** — "Tweak the prompt or settings"
|
|
158
|
-
- **Upscale** — "Upscale this result" (images only)
|
|
159
|
-
- **Animate** — "Turn this image into a video" (images only — navigate to video page with image as start frame)
|
|
160
|
-
- **Download** — "Download the generated content"
|
|
161
|
-
- **Done** — "Finished"
|
|
162
|
-
|
|
163
|
-
If **Generate Again** → click Generate again (settings persist).
|
|
164
|
-
If **Modify & Regenerate** → ask what to change, update settings in browser, re-generate.
|
|
165
|
-
If **Upscale** → navigate to upscaler page with the image.
|
|
166
|
-
If **Animate** → navigate to video page, use "Add Image Guidance" to set the image as start frame.
|
|
167
|
-
If **Download** → click the download button on the generation.
|
|
168
|
-
If **Done** → end.
|