synabun 2.0.0 → 2.0.7
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 +97 -0
- package/NOTICE +5 -0
- package/README.md +2 -1
- package/THIRD-PARTY-LICENSES.md +59 -0
- package/benchmarks/fixtures/browser/README.md +1 -1
- package/benchmarks/fixtures/desktop/README.md +1 -1
- package/docs/whatsapp.md +153 -18
- package/hooks/claude-code/pre-compact.mjs +11 -0
- package/hooks/claude-code/prompt-submit.mjs +60 -184
- package/hooks/claude-code/session-start.mjs +73 -16
- package/hooks/claude-code/shared.mjs +26 -3
- package/hooks/claude-code/stop.mjs +5 -5
- package/lib/child-path.js +303 -0
- package/lib/claude-hooks.js +2 -1
- package/lib/data-home-migration.js +2 -0
- package/lib/desktop-app.js +265 -0
- package/lib/external-tools.js +7 -3
- package/lib/log-redact.js +102 -0
- package/lib/packaged-runtime.js +138 -11
- package/lib/start-launcher.js +88 -1
- package/mcp-server/dist/http.d.ts +3 -1
- package/mcp-server/dist/http.d.ts.map +1 -1
- package/mcp-server/dist/http.js +15 -4
- package/mcp-server/dist/http.js.map +1 -1
- package/mcp-server/dist/index.d.ts.map +1 -1
- package/mcp-server/dist/index.js +9 -6
- package/mcp-server/dist/index.js.map +1 -1
- package/mcp-server/dist/services/budget-judgments.d.ts +108 -0
- package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -0
- package/mcp-server/dist/services/budget-judgments.js +153 -0
- package/mcp-server/dist/services/budget-judgments.js.map +1 -0
- package/mcp-server/dist/services/codex-config-heal.d.ts +5 -1
- package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.js +41 -4
- package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
- package/mcp-server/dist/services/identity.d.ts +11 -0
- package/mcp-server/dist/services/identity.d.ts.map +1 -1
- package/mcp-server/dist/services/identity.js +24 -0
- package/mcp-server/dist/services/identity.js.map +1 -1
- package/mcp-server/dist/services/neural-interface.d.ts +13 -0
- package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
- package/mcp-server/dist/services/neural-interface.js +34 -2
- package/mcp-server/dist/services/neural-interface.js.map +1 -1
- package/mcp-server/dist/services/typesafe-config.d.ts +1 -1
- package/mcp-server/dist/services/typesafe-config.d.ts.map +1 -1
- package/mcp-server/dist/services/typesafe-config.js +4 -1
- package/mcp-server/dist/services/typesafe-config.js.map +1 -1
- package/mcp-server/dist/tools/agents.d.ts +10 -7
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +34 -13
- package/mcp-server/dist/tools/agents.js.map +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts +17 -0
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -0
- package/mcp-server/dist/tools/whatsapp-send-file.js +44 -0
- package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -0
- package/mcp-server/dist/tui.js +2 -1
- package/mcp-server/dist/tui.js.map +1 -1
- package/mcp-server/dist/version.d.ts +5 -0
- package/mcp-server/dist/version.d.ts.map +1 -0
- package/mcp-server/dist/version.js +21 -0
- package/mcp-server/dist/version.js.map +1 -0
- package/mcp-server/package-lock.json +2 -2
- package/mcp-server/package.json +1 -3
- package/mcp-server/run.mjs +15 -9
- package/mcp-server/src/http.ts +18 -3
- package/mcp-server/src/index.ts +9 -6
- package/mcp-server/src/services/budget-judgments.ts +183 -0
- package/mcp-server/src/services/codex-config-heal.ts +35 -4
- package/mcp-server/src/services/identity.ts +27 -0
- package/mcp-server/src/services/neural-interface.ts +34 -2
- package/mcp-server/src/services/typesafe-config.ts +4 -1
- package/mcp-server/src/tools/agents.ts +33 -14
- package/mcp-server/src/tools/whatsapp-send-file.ts +51 -0
- package/mcp-server/src/tui.ts +2 -1
- package/mcp-server/src/version.ts +22 -0
- package/neural-interface/i18n/en.json +2126 -209
- package/neural-interface/i18n/pt-BR.json +2123 -207
- package/neural-interface/lib/account-usage.js +163 -0
- package/neural-interface/lib/assistant-api.js +316 -57
- package/neural-interface/lib/assistant-brains/claude.js +19 -2
- package/neural-interface/lib/assistant-brains/codex.js +3 -0
- package/neural-interface/lib/assistant-brains/opencode.js +17 -4
- package/neural-interface/lib/assistant-budget-planner.js +390 -0
- package/neural-interface/lib/assistant-budget-split.js +408 -0
- package/neural-interface/lib/assistant-budget.js +94 -95
- package/neural-interface/lib/assistant-catalog.js +179 -27
- package/neural-interface/lib/assistant-config.js +91 -14
- package/neural-interface/lib/assistant-dispatch.js +494 -138
- package/neural-interface/lib/assistant-hidden-models.js +393 -66
- package/neural-interface/lib/assistant-jev.js +26 -3
- package/neural-interface/lib/assistant-memory.js +24 -10
- package/neural-interface/lib/assistant-persona.js +73 -12
- package/neural-interface/lib/assistant-plan-permissions.js +8 -1
- package/neural-interface/lib/assistant-pricing.js +21 -6
- package/neural-interface/lib/assistant-route-accounts.js +14 -0
- package/neural-interface/lib/assistant-route-gate.js +19 -3
- package/neural-interface/lib/assistant-router.js +373 -42
- package/neural-interface/lib/assistant-runtime.js +488 -59
- package/neural-interface/lib/assistant-task-prompt.js +13 -3
- package/neural-interface/lib/assistant-test-density.js +142 -0
- package/neural-interface/lib/assistant-user-context-budgets.js +123 -0
- package/neural-interface/lib/assistant-user-context.js +908 -0
- package/neural-interface/lib/assistant-user-knowledge.js +328 -0
- package/neural-interface/lib/assistant-user-learn.js +404 -0
- package/neural-interface/lib/assistant-user-threads.js +226 -0
- package/neural-interface/lib/assistant-user-writer.js +183 -0
- package/neural-interface/lib/augmented-path.js +317 -53
- package/neural-interface/lib/browser-background-tab.js +134 -0
- package/neural-interface/lib/browser-screenshot.js +678 -61
- package/neural-interface/lib/claude-accounts.js +342 -31
- package/neural-interface/lib/claude-agent-bridge.js +123 -9
- package/neural-interface/lib/claude-executable.js +6 -1
- package/neural-interface/lib/claude-model-catalog.js +33 -5
- package/neural-interface/lib/claude-panel-auth.js +221 -0
- package/neural-interface/lib/claude-profile-api-key.js +62 -0
- package/neural-interface/lib/claude-temporary.js +46 -7
- package/neural-interface/lib/cli-install-api.js +137 -0
- package/neural-interface/lib/cli-install.js +797 -0
- package/neural-interface/lib/cli-path.js +130 -0
- package/neural-interface/lib/cli-resolver.js +744 -0
- package/neural-interface/lib/cli-update-planner.js +143 -7
- package/neural-interface/lib/cloudflared/install.js +533 -0
- package/neural-interface/lib/cloudflared/manager.js +545 -0
- package/neural-interface/lib/cloudflared/pins.js +115 -0
- package/neural-interface/lib/cloudflared/pins.json +63 -0
- package/neural-interface/lib/cloudflared/tunnel.js +265 -0
- package/neural-interface/lib/codex-account-auth.js +178 -0
- package/neural-interface/lib/codex-accounts.js +489 -0
- package/neural-interface/lib/codex-capabilities.js +2 -1
- package/neural-interface/lib/codex-compat-rpc.js +8 -2
- package/neural-interface/lib/codex-mcp-approvals.js +5 -1
- package/neural-interface/lib/codex-panel-auth.js +62 -0
- package/neural-interface/lib/codex-session-settings.js +1 -1
- package/neural-interface/lib/codex-settings-schema.js +120 -0
- package/neural-interface/lib/desktop/config.js +3 -0
- package/neural-interface/lib/editor-completion-endpoint.js +264 -0
- package/neural-interface/lib/editor-completion-opencode.js +436 -0
- package/neural-interface/lib/editor-completion.js +714 -0
- package/neural-interface/lib/editor-config.js +149 -0
- package/neural-interface/lib/editor-files-api.js +268 -0
- package/neural-interface/lib/editor-git-api.js +134 -0
- package/neural-interface/lib/file-explorer-api.js +1039 -0
- package/neural-interface/lib/file-explorer-system.js +355 -0
- package/neural-interface/lib/file-explorer-trash.ps1 +85 -0
- package/neural-interface/lib/file-explorer-watch.js +239 -0
- package/neural-interface/lib/git-bash/bzip2.js +339 -0
- package/neural-interface/lib/git-bash/claude-settings.js +73 -0
- package/neural-interface/lib/git-bash/extract-worker.js +34 -0
- package/neural-interface/lib/git-bash/install.js +529 -0
- package/neural-interface/lib/git-bash/licenses/COPYING +360 -0
- package/neural-interface/lib/git-bash/licenses/LGPL-2.1 +511 -0
- package/neural-interface/lib/git-bash/manager.js +268 -0
- package/neural-interface/lib/git-bash/pins.js +206 -0
- package/neural-interface/lib/git-bash/pins.json +34 -0
- package/neural-interface/lib/git-bash/resolver.js +194 -0
- package/neural-interface/lib/git-diff-api.js +103 -0
- package/neural-interface/lib/git-read.js +234 -0
- package/neural-interface/lib/greeting/api.js +89 -0
- package/neural-interface/lib/greeting/budgets.js +90 -0
- package/neural-interface/lib/greeting/engine.js +461 -0
- package/neural-interface/lib/greeting/facts.js +320 -0
- package/neural-interface/lib/greeting/sources.js +252 -0
- package/neural-interface/lib/greeting/writer.js +139 -0
- package/neural-interface/lib/http-guards.js +189 -13
- package/neural-interface/lib/install-details.js +145 -0
- package/neural-interface/lib/machine-names.js +88 -0
- package/neural-interface/lib/mcp-installer.js +14 -2
- package/neural-interface/lib/memory-api.js +31 -7
- package/neural-interface/lib/native-loop-providers.js +26 -8
- package/neural-interface/lib/native-loop-runtime.js +9 -4
- package/neural-interface/lib/os-path.js +319 -0
- package/neural-interface/lib/plugin-installer.js +4 -2
- package/neural-interface/lib/project-storage.js +5 -7
- package/neural-interface/lib/provider-panel-api-key-auth.js +92 -0
- package/neural-interface/lib/provider-panel-terminal-auth.js +95 -0
- package/neural-interface/lib/pty-host/core.js +2 -1
- package/neural-interface/lib/pty-host/manager.js +27 -2
- package/neural-interface/lib/remote-policy.js +20 -11
- package/neural-interface/lib/request-gate.js +589 -0
- package/neural-interface/lib/session-title-generator.js +4 -3
- package/neural-interface/lib/system-about.js +340 -0
- package/neural-interface/lib/system-activity.js +66 -0
- package/neural-interface/lib/terminal-env.js +11 -3
- package/neural-interface/lib/terminal-path.js +55 -0
- package/neural-interface/lib/ui-blob-api.js +108 -0
- package/neural-interface/lib/ui-blob-store.js +68 -0
- package/neural-interface/lib/virtual-socket.js +12 -1
- package/neural-interface/lib/whatsapp/baileys-adapter.js +165 -45
- package/neural-interface/lib/whatsapp/bridge.js +78 -34
- package/neural-interface/lib/whatsapp/commands.js +13 -14
- package/neural-interface/lib/whatsapp/config.js +134 -20
- package/neural-interface/lib/whatsapp/fake-baileys.js +99 -14
- package/neural-interface/lib/whatsapp/host-core.js +168 -35
- package/neural-interface/lib/whatsapp/inbound.js +5 -3
- package/neural-interface/lib/whatsapp/local-file.js +524 -0
- package/neural-interface/lib/whatsapp/manager.js +92 -32
- package/neural-interface/lib/whatsapp/paths.js +11 -1
- package/neural-interface/lib/whatsapp/protocol.js +65 -5
- package/neural-interface/lib/whatsapp/redact.js +63 -0
- package/neural-interface/lib/whatsapp/service.js +343 -91
- package/neural-interface/lib/whatsapp/transcription.js +463 -0
- package/neural-interface/package-lock.json +701 -2
- package/neural-interface/package.json +13 -2
- package/neural-interface/public/index.html +2 -0
- package/neural-interface/public/index2d.html +2 -0
- package/neural-interface/public/install-app.html +9 -6
- package/neural-interface/public/offline.html +19 -3
- package/neural-interface/public/onboarding.html +107 -2
- package/neural-interface/public/shared/account-i18n.js +7 -0
- package/neural-interface/public/shared/account-menu.js +539 -0
- package/neural-interface/public/shared/account-usage.js +19 -0
- package/neural-interface/public/shared/account-view.js +335 -0
- package/neural-interface/public/shared/agent-runtime-options.js +50 -14
- package/neural-interface/public/shared/assistant/asst-accounts.js +182 -184
- package/neural-interface/public/shared/assistant/asst-api.js +32 -2
- package/neural-interface/public/shared/assistant/asst-automation.js +286 -0
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +430 -81
- package/neural-interface/public/shared/assistant/asst-budget.js +259 -303
- package/neural-interface/public/shared/assistant/asst-composer.js +11 -1
- package/neural-interface/public/shared/assistant/asst-mascot.js +140 -61
- package/neural-interface/public/shared/assistant/asst-menu.js +27 -11
- package/neural-interface/public/shared/assistant/asst-panel.js +198 -42
- package/neural-interface/public/shared/assistant/asst-render.js +197 -23
- package/neural-interface/public/shared/assistant/asst-route-models.js +108 -0
- package/neural-interface/public/shared/assistant/asst-route.js +95 -343
- package/neural-interface/public/shared/assistant/asst-routes-editor.js +534 -0
- package/neural-interface/public/shared/assistant/asst-sanitize.js +8 -1
- package/neural-interface/public/shared/assistant/asst-sidepanel.js +31 -9
- package/neural-interface/public/shared/assistant/asst-slash.js +1 -1
- package/neural-interface/public/shared/assistant/asst-state.js +186 -2
- package/neural-interface/public/shared/assistant/asst-styles.js +247 -11
- package/neural-interface/public/shared/blob-store.js +111 -22
- package/neural-interface/public/shared/cdx/cdx-commands.js +4 -1
- package/neural-interface/public/shared/cdx/cdx-features.js +22 -14
- package/neural-interface/public/shared/cdx/cdx-icons.js +2 -0
- package/neural-interface/public/shared/cdx/cdx-panel.js +80 -118
- package/neural-interface/public/shared/cdx/cdx-render.js +25 -89
- package/neural-interface/public/shared/cdx/cdx-settings.js +231 -0
- package/neural-interface/public/shared/cdx/cdx-styles.js +164 -107
- package/neural-interface/public/shared/cdx/cdx-tabs.js +348 -668
- package/neural-interface/public/shared/cdx/cdx-ws.js +2 -0
- package/neural-interface/public/shared/claude-account-view.js +3 -0
- package/neural-interface/public/shared/cli-install-view.js +392 -0
- package/neural-interface/public/shared/cli-status.js +282 -22
- package/neural-interface/public/shared/constants.js +6 -1
- package/neural-interface/public/shared/cp/cp-events.js +2 -1
- package/neural-interface/public/shared/cp/cp-rehydrate.js +2 -1
- package/neural-interface/public/shared/cp/cp-styles.js +61 -0
- package/neural-interface/public/shared/desktop-bridge.js +39 -0
- package/neural-interface/public/shared/desktop-titlebar-page.js +59 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +122 -0
- package/neural-interface/public/shared/desktop-titlebar.js +153 -0
- package/neural-interface/public/shared/desktop-update-view.js +462 -0
- package/neural-interface/public/shared/editor/editor-ai-logic.js +409 -0
- package/neural-interface/public/shared/editor/editor-ai.js +619 -0
- package/neural-interface/public/shared/editor/editor-commands.js +212 -0
- package/neural-interface/public/shared/editor/editor-compare.js +103 -0
- package/neural-interface/public/shared/editor/editor-completion-list.js +172 -0
- package/neural-interface/public/shared/editor/editor-doc.js +257 -0
- package/neural-interface/public/shared/editor/editor-git-logic.js +131 -0
- package/neural-interface/public/shared/editor/editor-git.js +95 -0
- package/neural-interface/public/shared/editor/editor-languages.js +156 -0
- package/neural-interface/public/shared/editor/editor-lint.js +229 -0
- package/neural-interface/public/shared/editor/editor-loader.js +51 -0
- package/neural-interface/public/shared/editor/editor-markdown.js +90 -0
- package/neural-interface/public/shared/editor/editor-menu.js +233 -0
- package/neural-interface/public/shared/editor/editor-minimap.js +371 -0
- package/neural-interface/public/shared/editor/editor-palette-logic.js +192 -0
- package/neural-interface/public/shared/editor/editor-palette.js +125 -0
- package/neural-interface/public/shared/editor/editor-panel-logic.js +288 -0
- package/neural-interface/public/shared/editor/editor-panel.js +2099 -0
- package/neural-interface/public/shared/editor/editor-prefs.js +224 -0
- package/neural-interface/public/shared/editor/editor-safety.js +500 -0
- package/neural-interface/public/shared/editor/editor-search.js +352 -0
- package/neural-interface/public/shared/editor/editor-statusbar.js +144 -0
- package/neural-interface/public/shared/editor/editor-tabs-logic.js +331 -0
- package/neural-interface/public/shared/editor/editor-tabs.js +233 -0
- package/neural-interface/public/shared/editor/editor-theme.js +244 -0
- package/neural-interface/public/shared/editor/editor-view.js +332 -0
- package/neural-interface/public/shared/explorer/fx-api.js +216 -0
- package/neural-interface/public/shared/explorer/fx-links.js +204 -0
- package/neural-interface/public/shared/explorer/fx-logic.js +537 -0
- package/neural-interface/public/shared/explorer/fx-main.js +865 -0
- package/neural-interface/public/shared/explorer/fx-names.js +87 -0
- package/neural-interface/public/shared/explorer/fx-ops.js +370 -0
- package/neural-interface/public/shared/explorer/fx-popups.js +490 -0
- package/neural-interface/public/shared/explorer/fx-tree.js +790 -0
- package/neural-interface/public/shared/file-links.js +339 -0
- package/neural-interface/public/shared/git-bash-view.js +145 -0
- package/neural-interface/public/shared/greeting/greeting-card.js +178 -0
- package/neural-interface/public/shared/greeting/greeting-view.js +148 -0
- package/neural-interface/public/shared/html-shell.js +161 -165
- package/neural-interface/public/shared/i18n.js +19 -1
- package/neural-interface/public/shared/install-details-view.js +86 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +4 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-greeting.js +47 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +131 -17
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -1
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +22 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +158 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +3 -2
- package/neural-interface/public/shared/pwa-install-page.js +32 -2
- package/neural-interface/public/shared/pwa-install.css +3 -3
- package/neural-interface/public/shared/pwa-install.js +100 -1
- package/neural-interface/public/shared/settings/settings-about-pane.js +271 -0
- package/neural-interface/public/shared/settings/settings-about.js +254 -0
- package/neural-interface/public/shared/settings/settings-code-editor-pane.js +412 -0
- package/neural-interface/public/shared/settings/settings-code-editor.js +328 -0
- package/neural-interface/public/shared/settings/settings-greeting.js +133 -0
- package/neural-interface/public/shared/settings/settings-ia.js +33 -4
- package/neural-interface/public/shared/settings/settings-user-context.js +154 -0
- package/neural-interface/public/shared/showcase-privacy.js +489 -0
- package/neural-interface/public/shared/start-bridge.js +238 -19
- package/neural-interface/public/shared/storage.js +30 -3
- package/neural-interface/public/shared/styles.css +1710 -770
- package/neural-interface/public/shared/synabun-mascot.js +68 -58
- package/neural-interface/public/shared/tunnel-view.js +167 -0
- package/neural-interface/public/shared/ui-claude-panel.js +369 -229
- package/neural-interface/public/shared/ui-cli-banner.js +355 -0
- package/neural-interface/public/shared/ui-detail.js +15 -0
- package/neural-interface/public/shared/ui-explorer.js +22 -0
- package/neural-interface/public/shared/ui-file-explorer.js +481 -2496
- package/neural-interface/public/shared/ui-file-links.js +103 -0
- package/neural-interface/public/shared/ui-git-bash.js +124 -0
- package/neural-interface/public/shared/ui-help.js +26 -0
- package/neural-interface/public/shared/ui-invite.js +126 -116
- package/neural-interface/public/shared/ui-judgments.js +10 -1
- package/neural-interface/public/shared/ui-keybinds.js +4 -0
- package/neural-interface/public/shared/ui-loading.js +187 -19
- package/neural-interface/public/shared/ui-menubar.js +25 -33
- package/neural-interface/public/shared/ui-native-loop-router-state.js +11 -0
- package/neural-interface/public/shared/ui-native-loop-router.js +15 -2
- package/neural-interface/public/shared/ui-navbar.js +48 -22
- package/neural-interface/public/shared/ui-provider-auth.js +104 -0
- package/neural-interface/public/shared/ui-provider-terminal-auth.js +223 -0
- package/neural-interface/public/shared/ui-sessions.js +9 -3
- package/neural-interface/public/shared/ui-settings.js +509 -490
- package/neural-interface/public/shared/ui-sidepanel-runtime.js +2 -1
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +3 -1
- package/neural-interface/public/shared/ui-sync.js +22 -0
- package/neural-interface/public/shared/ui-terminal.js +40 -5
- package/neural-interface/public/shared/ui-tool-updates.js +5 -0
- package/neural-interface/public/shared/ui-tunnel.js +130 -0
- package/neural-interface/public/shared/ui-tutorial-steps.js +6 -2
- package/neural-interface/public/shared/ui-update.js +594 -5
- package/neural-interface/public/shared/ui-whatsapp.js +21 -6
- package/neural-interface/public/shared/ui-whiteboard.js +12 -0
- package/neural-interface/public/shared/ui-worker-end.js +245 -0
- package/neural-interface/public/shared/ui-workspaces.js +41 -27
- package/neural-interface/public/shared/whatsapp/wa-view.js +51 -8
- package/neural-interface/public/shared/worker-end.js +253 -0
- package/neural-interface/public/sw.js +2 -2
- package/neural-interface/public/variant/2d/main.js +10 -1
- package/neural-interface/public/variant/3d/main.js +10 -1
- package/neural-interface/public/vendor/codemirror/chunks/apl-CSDKT72Z.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/asciiarmor-JYYPU5BM.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/asn1-NRWCZDA6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/asterisk-5OU6D4ZQ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/brainfuck-ID4N4SYC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-4RZWGCS2.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-ACTJM3JR.js +11 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-S6BMAXLK.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-TO2RDOHQ.js +3 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-US2GMZZQ.js +13 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-WYYO5ZAJ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-XALZTDJC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-YRNUTRDV.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-Z3QOKH62.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/clike-OWQBSOGL.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/clojure-KV75UQWC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/cmake-GTEP5Y3C.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/cobol-WCZ7QEGJ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/coffeescript-TGLBOT6B.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/commonlisp-WVVI432V.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/crystal-S6R6HLKQ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/css-PDA2RINP.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/cypher-HL5QPL4C.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/d-HHJH2HAJ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/diff-MN3A35BY.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-25SQLBVS.js +3 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-27ZGGJJS.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-4E52OJIF.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-6FT73XDC.js +2 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-BE6YGRMW.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-CJSGKW2O.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-CRPH2WLI.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-CTG7JEQN.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-I3FEVELX.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-IM5BBSWZ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-KERUKTIF.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-LXTMWZAM.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-MABASSET.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-MJVBUZLL.js +3 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-MNB3WZVU.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-QYWXOE3U.js +7 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-TEBOFWLZ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-UNXFROM3.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-XL2SLQO6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-XO42Y3AP.js +6 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-Y2WWDWJK.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-YFEZKWMU.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-ZY7SWQO6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dockerfile-3Y4R4NCH.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dtd-5343GJ4P.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dylan-FI2CXSW2.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ebnf-GNQ77YWA.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ecl-MRPUAE2L.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/eiffel-DZROES27.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/elm-4KICRFKQ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/erlang-3IHYC263.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/factor-C6D3E5UK.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/fcl-VYTWUJMI.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/forth-ZBO2EH5M.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/fortran-5NDCRWIK.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/gas-SKRMOXFP.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/gherkin-L45YXZLW.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/groovy-GLPTLN44.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/haskell-E7NF7P4Y.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/haxe-K2NVDOB6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/http-Q6DRQIJB.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/idl-MZYNJVLN.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/javascript-6YRYK2HR.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/julia-HXEL2T5G.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/livescript-MV7CI2JZ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/lua-E36NHOOD.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mathematica-3XOZZCMC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mbox-ODYGFKS7.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mirc-WB43AWF5.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mllike-ZT6ET7ZH.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/modelica-LLMZPFGA.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mscgen-2OPNNYFH.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mumps-6P3HWJH6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/nginx-TCGKQTRW.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/nsis-ATIGIXTJ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ntriples-5PLBI5OV.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/octave-QF2S3NL6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/oz-JFIVFFH2.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/pascal-JG6SW76V.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/perl-4B3IWVVO.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/pig-ABEBH4MI.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/powershell-H32XE7TL.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/properties-NN644MMA.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/protobuf-YKWQK2J3.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/pug-RIYXEKFW.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/puppet-JZQ5WPEV.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/python-EBCGGHAC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/q-5UMH2YQY.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/r-7XMGG453.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/rpm-IEV7TSLR.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ruby-T4SPFPNM.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/sas-GEDX67ET.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/scheme-FTLOWKPC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/shell-HUFRKFSJ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/sieve-P5QUDVYO.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/smalltalk-2SORJNQI.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/solr-M22TGAR5.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/sparql-4M3KL752.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/spreadsheet-3K23LA4N.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/sql-VHRFMUBI.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/stex-QZDAQUY2.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/stylus-7ZDKAKBD.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/swift-WCLCLGMR.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/tcl-JLMU6WOK.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/textile-4CHDKZ4T.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/tiddlywiki-DKMCZZQ4.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/tiki-F4JIG36Q.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/toml-BHMHTIM2.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/troff-YQ2KV5NT.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ttcn-ZHRCVFJY.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ttcn-cfg-KJOVTY4X.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/turtle-535P5N6I.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/vb-76UMQHOT.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/vbscript-CGNDTK6Z.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/velocity-VSJDO5T5.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/verilog-4T6ETXIP.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/vhdl-T7FNAXUN.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/webidl-P6MJSJ6J.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/xquery-UOVILRGN.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/yacas-CV2APROL.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/z80-3KFNVM4M.js +1 -0
- package/neural-interface/public/vendor/codemirror/codemirror-6.43.14-75f05e67.min.js +2 -0
- package/neural-interface/public/vendor/codemirror/manifest.json +60 -0
- package/neural-interface/scripts/build-vendor.mjs +78 -2
- package/neural-interface/scripts/vendor-codemirror-entry.js +121 -0
- package/neural-interface/server.js +2085 -1629
- package/neural-interface/templates/rulesets/README.md +1 -1
- package/package.json +5 -8
- package/setup.js +53 -15
- package/benchmarks/browser-live-results.json +0 -79
- package/benchmarks/browser-v2-results.json +0 -258
- package/neural-interface/lib/codex-capabilities.d.ts +0 -41
- package/neural-interface/public/category-logos/claude.svg +0 -1
- package/neural-interface/public/category-logos/gemini-color.svg +0 -1
- package/neural-interface/public/category-logos/openai.svg +0 -1
- package/neural-interface/public/category-logos/synabun.png +0 -0
- package/neural-interface/public/claude.svg +0 -1
- package/neural-interface/public/gallery.svg +0 -6
- package/neural-interface/public/leonardoai.svg +0 -1
- package/neural-interface/public/mcp.svg +0 -4
- package/neural-interface/public/opencode-logo-dark-square.svg +0 -1
- package/neural-interface/public/pin-svgrepo-com.svg +0 -25
- package/neural-interface/public/sessionicon.svg +0 -8
- package/neural-interface/public/toolbar-album.svg +0 -8
- package/neural-interface/public/toolbar-question.svg +0 -6
- package/neural-interface/public/toolbar-sessions.svg +0 -6
- package/neural-interface/scripts/codex-protocol-fixture.mjs +0 -83
- package/skills/synabun/synabunicon.png +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { capabilityAvailability, flattenNativeCatalog, reviewTarget } from './cdx-commands.js';
|
|
2
|
+
import { t } from '../i18n.js';
|
|
2
3
|
import { knownCodexCapabilities } from './cdx-capabilities.js';
|
|
3
4
|
import { codexReadableValue, parseCodexAttachmentPayload, codexGatewayState, codexVerificationState, codexHttpsHandoff } from './cdx-protocol.js';
|
|
4
5
|
|
|
@@ -333,23 +334,27 @@ export function updateCodexGateway(tab, value) {
|
|
|
333
334
|
accountSecurityViews.get(tab)?.();
|
|
334
335
|
}
|
|
335
336
|
|
|
336
|
-
export async function mountCodexAccountSecurity({ host, request, tab, capabilities }) {
|
|
337
|
+
export async function mountCodexAccountSecurity({ host, experimentalHost = host, request, tab, capabilities }) {
|
|
338
|
+
const tr = (key, params) => t(`codexSettings.${key}`, params);
|
|
337
339
|
const view = { error: message => { error.textContent = message; } };
|
|
338
340
|
const error = element('div', 'cxp-settings-hint'); error.setAttribute('role', 'alert');
|
|
339
341
|
const gateway = element('div', 'cxp-settings-section');
|
|
340
342
|
const verification = element('div', 'cxp-settings-section');
|
|
341
|
-
host.append(gateway,
|
|
343
|
+
host.append(gateway, error);
|
|
344
|
+
experimentalHost.append(verification);
|
|
342
345
|
const available = name => capabilityAvailability(knownCodexCapabilities(tab) || capabilities, name);
|
|
343
346
|
const renderGateway = () => {
|
|
344
347
|
if (!host.isConnected || tab.closed) { accountSecurityViews.delete(tab); return; }
|
|
345
348
|
gateway.replaceChildren();
|
|
346
349
|
if (!available('gateway_oauth_read').supported) return;
|
|
347
350
|
const value = tab.gatewayOAuth || {};
|
|
351
|
+
gateway.hidden = !value.required;
|
|
352
|
+
if (!value.required) return;
|
|
348
353
|
const state = codexGatewayState(value);
|
|
349
|
-
gateway.append(element('div', 'cxp-settings-section-title', '
|
|
350
|
-
gateway.append(element('div', 'cxp-settings-hint', `${value.providerName || value.providerId || '
|
|
354
|
+
gateway.append(element('div', 'cxp-settings-section-title', tr('gateway')));
|
|
355
|
+
gateway.append(element('div', 'cxp-settings-hint', `${value.providerName || value.providerId || tr('provider')} · ${tr(`gatewayStates.${value.status || 'notReady'}`)}`));
|
|
351
356
|
const action = state.pending ? 'gateway_oauth_cancel' : 'gateway_oauth_login';
|
|
352
|
-
gateway.append(button(state.pending ? '
|
|
357
|
+
gateway.append(button(tr(state.pending ? 'cancel' : 'signIn'), async () => {
|
|
353
358
|
if (!available(action).supported) throw new Error(available(action).reason);
|
|
354
359
|
await request(action, {});
|
|
355
360
|
// Notification is authoritative; do not overwrite a completed login with a stale optimistic state.
|
|
@@ -360,10 +365,10 @@ export async function mountCodexAccountSecurity({ host, request, tab, capabiliti
|
|
|
360
365
|
}, view, available(action)));
|
|
361
366
|
if (!available(action).supported) gateway.append(element('div', 'cxp-settings-hint', available(action).reason));
|
|
362
367
|
const handoff = codexHttpsHandoff(value.authUrl);
|
|
363
|
-
if (value.authUrl && !handoff) gateway.append(element('div', 'cxp-settings-hint', '
|
|
368
|
+
if (value.authUrl && !handoff) gateway.append(element('div', 'cxp-settings-hint', tr('httpsRequired')));
|
|
364
369
|
if (handoff && state.pending) {
|
|
365
|
-
gateway.append(element('div', 'cxp-settings-hint',
|
|
366
|
-
gateway.append(button(
|
|
370
|
+
gateway.append(element('div', 'cxp-settings-hint', tr('continueAt', { host: handoff.host })));
|
|
371
|
+
gateway.append(button(tr('openHost', { host: handoff.host }), () => {
|
|
367
372
|
window.open(handoff.url, '_blank', 'noopener,noreferrer');
|
|
368
373
|
}, view));
|
|
369
374
|
}
|
|
@@ -386,12 +391,15 @@ export async function mountCodexAccountSecurity({ host, request, tab, capabiliti
|
|
|
386
391
|
const response = await request('verification_status', {});
|
|
387
392
|
if (!host.isConnected || tab.closed) return;
|
|
388
393
|
const state = codexVerificationState(response.verification);
|
|
389
|
-
|
|
390
|
-
verification.
|
|
391
|
-
verification.
|
|
394
|
+
const reason = response.verification?.unavailableReason;
|
|
395
|
+
verification.hidden = !!reason && reason !== 'credentialMissing';
|
|
396
|
+
if (verification.hidden) return;
|
|
397
|
+
verification.append(element('div', 'cxp-settings-section-title', tr('verification')));
|
|
398
|
+
verification.append(element('div', 'cxp-settings-hint', tr(state.enrolled ? 'credentialReady' : 'credentialMissing')));
|
|
399
|
+
verification.append(element('div', 'cxp-settings-hint', tr('localCredential')));
|
|
392
400
|
const action = state.enrolled ? 'verification_delete' : 'verification_enroll';
|
|
393
|
-
const control = button(state.enrolled ? '
|
|
394
|
-
if (state.enrolled && !window.confirm('
|
|
401
|
+
const control = button(tr(state.enrolled ? 'remove' : 'enroll'), async () => {
|
|
402
|
+
if (state.enrolled && !window.confirm(tr('removeCredential'))) return;
|
|
395
403
|
await request(action, {}); await readVerification();
|
|
396
404
|
}, view, available(action));
|
|
397
405
|
if (state.enrolled) control.style.color = 'var(--cxp-danger)';
|
|
@@ -399,7 +407,7 @@ export async function mountCodexAccountSecurity({ host, request, tab, capabiliti
|
|
|
399
407
|
if (!available(action).supported) verification.append(element('div', 'cxp-settings-hint', available(action).reason));
|
|
400
408
|
} catch (failure) {
|
|
401
409
|
if (available('verification_status').supported) {
|
|
402
|
-
verification.append(element('div', 'cxp-settings-hint',
|
|
410
|
+
verification.append(element('div', 'cxp-settings-hint', tr('error', { message: failure.message })));
|
|
403
411
|
}
|
|
404
412
|
}
|
|
405
413
|
}
|
|
@@ -41,6 +41,8 @@ export let windowId = hostedSidepanelId || sessionStorage.getItem('cxp-window-id
|
|
|
41
41
|
// ── Storage Keys ──
|
|
42
42
|
export const STOR = {
|
|
43
43
|
threadId: 'synabun-codex-panel-thread',
|
|
44
|
+
// The account that thread belongs to (its rollout lives in that account's CODEX_HOME).
|
|
45
|
+
threadAccount: 'synabun-codex-panel-thread-account',
|
|
44
46
|
title: 'synabun-codex-panel-title',
|
|
45
47
|
project: 'synabun-codex-panel-project',
|
|
46
48
|
projectThreads: 'synabun-codex-panel-project-threads',
|
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
import { storage } from '../storage.js';
|
|
5
5
|
import { state, emit, on } from '../state.js';
|
|
6
6
|
import { registerSidepanel, setSidepanelVisible, sidepanelAcceptsKeyboard, openAnotherSidepanelSession } from '../ui-sidepanel-windows.js';
|
|
7
|
-
import {
|
|
7
|
+
import { mountCliBanner } from '../ui-cli-banner.js';
|
|
8
8
|
import { nativeLoopWindowId } from '../ui-native-window-id.js';
|
|
9
9
|
import { createStickyScrollController, getStickyScrollController } from '../ui-scroll-follow.js';
|
|
10
|
+
import { wireFileLinks } from '../ui-file-links.js';
|
|
11
|
+
import { trackWorkerEnd } from '../ui-worker-end.js';
|
|
12
|
+
import { isDispatchedRun } from '../worker-end.js';
|
|
10
13
|
import { injectStyles } from './cdx-styles.js';
|
|
11
14
|
import { mountContextMenu } from './cdx-context-menu.js';
|
|
12
15
|
import { teardownMcpApps } from './cdx-mcp-app-host.js';
|
|
@@ -27,6 +30,7 @@ import {
|
|
|
27
30
|
requestModelList, populateModelDropdown,
|
|
28
31
|
setSessionLabel, renameActiveSession, promptNameNewSession, openSettingsPanel, renderSessionMenu,
|
|
29
32
|
toggleAccountMenu,
|
|
33
|
+
mountCodexAccountMenu,
|
|
30
34
|
contextMenuData, contextMenuReading, refreshContextMenuDetails,
|
|
31
35
|
addImageFromFile, removeImage, renderImageStrip,
|
|
32
36
|
addPathChip, removePathChip, renderPathStrip,
|
|
@@ -39,6 +43,7 @@ import {
|
|
|
39
43
|
handleNotify,
|
|
40
44
|
appendLocalUserMessage, hydrateCodexAutomationHistory,
|
|
41
45
|
clearPlanHandoffState,
|
|
46
|
+
placeWorkerEnd,
|
|
42
47
|
withTab,
|
|
43
48
|
ensureProjectsLoaded,
|
|
44
49
|
setActiveProject,
|
|
@@ -58,8 +63,7 @@ document.addEventListener('visibilitychange', () => {
|
|
|
58
63
|
let _panel = null;
|
|
59
64
|
let _visible = false;
|
|
60
65
|
let _resizeBound = false;
|
|
61
|
-
let
|
|
62
|
-
let _cliUnsub = null;
|
|
66
|
+
let _cliBanner = null; // the CLI banner and send-block (ui-cli-banner.js)
|
|
63
67
|
|
|
64
68
|
// ═══════════════════════════════════════════
|
|
65
69
|
// Bound State (mirrors active tab — managed by cdx-tabs)
|
|
@@ -107,7 +111,6 @@ let _contextMenu = null;
|
|
|
107
111
|
* monolith and are referenced by wireEvents / ensurePanel.
|
|
108
112
|
*
|
|
109
113
|
* Expected shape:
|
|
110
|
-
* maybeOpenProjectFileLink(href, event) -> bool
|
|
111
114
|
* flushCardBody(itemState)
|
|
112
115
|
* resetThreadState(opts)
|
|
113
116
|
* appendSystem(text, tone)
|
|
@@ -272,7 +275,6 @@ function buildPanel() {
|
|
|
272
275
|
<button class="cxp-btn" id="cxp-slide" title="Slide panel"><svg viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg></button>
|
|
273
276
|
</div>
|
|
274
277
|
<div class="cxp-session-menu" id="cxp-session-menu"></div>
|
|
275
|
-
<div class="cxp-account-menu" id="cxp-account-menu"></div>
|
|
276
278
|
</div>
|
|
277
279
|
<div class="cxp-messages-container" id="cxp-messages-container"></div>
|
|
278
280
|
<div class="cxp-bottom">
|
|
@@ -403,122 +405,66 @@ function startupEmptyText() {
|
|
|
403
405
|
}
|
|
404
406
|
|
|
405
407
|
// ── CLI installation status (banner + send-block) ──
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
`;
|
|
429
|
-
container.parentNode.insertBefore(banner, container);
|
|
430
|
-
const btn = banner.querySelector('.cxp-cli-banner-recheck');
|
|
431
|
-
btn?.addEventListener('click', async () => {
|
|
432
|
-
btn.disabled = true;
|
|
433
|
-
btn.textContent = 'Checking…';
|
|
434
|
-
try { await recheckCliStatus('codex'); }
|
|
435
|
-
finally {
|
|
436
|
-
if (btn.isConnected) {
|
|
437
|
-
btn.disabled = false;
|
|
438
|
-
btn.textContent = 'Re-check';
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
});
|
|
442
|
-
renderCliBannerContent(banner);
|
|
443
|
-
return banner;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
// Two very different situations reach this banner, and telling the user the
|
|
447
|
-
// CLI is "not installed" when it is installed sends them off to reinstall
|
|
448
|
-
// something that is already there. Distinguish them.
|
|
449
|
-
function renderCliBannerContent(banner) {
|
|
450
|
-
const titleEl = banner.querySelector('.cxp-cli-banner-title');
|
|
451
|
-
const bodyEl = banner.querySelector('.cxp-cli-banner-body');
|
|
452
|
-
if (!titleEl || !bodyEl) return;
|
|
453
|
-
const label = getCliLabel('codex');
|
|
454
|
-
bodyEl.replaceChildren();
|
|
455
|
-
|
|
456
|
-
if (_cliInstalled === null) {
|
|
457
|
-
titleEl.textContent = `${label} CLI not installed`;
|
|
458
|
-
const cmd = getCliInstallCommand('codex');
|
|
459
|
-
bodyEl.append('Run ');
|
|
460
|
-
const code = document.createElement('code');
|
|
461
|
-
code.textContent = cmd;
|
|
462
|
-
bodyEl.append(code, ' or follow the install guide.');
|
|
463
|
-
return;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
titleEl.textContent = `${label} CLI failed to start`;
|
|
467
|
-
bodyEl.append(`${label} v${_cliInstalled} is installed, but it could not be launched. `);
|
|
468
|
-
if (_cliFailureReason) {
|
|
469
|
-
const code = document.createElement('code');
|
|
470
|
-
code.textContent = _cliFailureReason;
|
|
471
|
-
bodyEl.append(code);
|
|
472
|
-
} else {
|
|
473
|
-
bodyEl.append('Check the CLI path in Settings, then re-check.');
|
|
408
|
+
// One controller (ui-cli-banner.js) draws the banner above the transcript while
|
|
409
|
+
// Codex is not usable: not installed (with Install, which runs OpenAI's own
|
|
410
|
+
// installer on the server), being installed, failed to install, or found but
|
|
411
|
+
// failed to start (with the error it gave). It toggles `cxp-cli-blocked` on the
|
|
412
|
+
// panel, which syncInputEnabled (cdx-tabs.js) reads to keep Send off. What it
|
|
413
|
+
// says is cli-install-view.js (`cliInstall.*` strings).
|
|
414
|
+
let _cliWasBlocked = false;
|
|
415
|
+
|
|
416
|
+
function cliBanner() {
|
|
417
|
+
if (!_cliBanner) {
|
|
418
|
+
_cliBanner = mountCliBanner({
|
|
419
|
+
toolKey: 'codex',
|
|
420
|
+
prefix: 'cxp',
|
|
421
|
+
panel: () => _panel,
|
|
422
|
+
anchor: () => panelEl('#cxp-messages-container'),
|
|
423
|
+
onBlockedChange: (blocked) => {
|
|
424
|
+
try { syncInputEnabled(); } catch {}
|
|
425
|
+
const usableAgain = _cliWasBlocked && !blocked;
|
|
426
|
+
_cliWasBlocked = blocked;
|
|
427
|
+
if (usableAgain) reconnectAfterCli();
|
|
428
|
+
},
|
|
429
|
+
});
|
|
474
430
|
}
|
|
431
|
+
return _cliBanner;
|
|
475
432
|
}
|
|
476
433
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
const
|
|
481
|
-
|
|
434
|
+
// Codex was installed (or found again) after this tab's session could not start it: the tab connects again, so
|
|
435
|
+
// Send works without reopening the panel. A tab that is running, or one an automation owns, is left alone.
|
|
436
|
+
function reconnectAfterCli() {
|
|
437
|
+
const tab = activeTab();
|
|
438
|
+
if (!tab || tab.closed || tab.automationActive || tab.running) return;
|
|
439
|
+
if (tab.connected && tab.bootstrapped) return;
|
|
440
|
+
try {
|
|
441
|
+
if (tab.ws && tab.ws.readyState === WebSocket.OPEN) disconnectTab(tab);
|
|
442
|
+
connectTab(tab);
|
|
443
|
+
} catch (error) {
|
|
444
|
+
console.warn('[cdx-panel] reconnect after Codex became usable failed', error);
|
|
445
|
+
}
|
|
482
446
|
}
|
|
483
447
|
|
|
484
448
|
function refreshCliBanner() {
|
|
485
449
|
if (!_panel) return;
|
|
486
|
-
|
|
487
|
-
_panel.classList.toggle('cxp-cli-blocked', missing);
|
|
488
|
-
if (missing) ensureCliBannerEl();
|
|
489
|
-
else removeCliBannerEl();
|
|
450
|
+
cliBanner().refresh();
|
|
490
451
|
try { syncInputEnabled(); } catch {}
|
|
491
452
|
}
|
|
492
453
|
|
|
493
454
|
export function isCdxCliInstalled() {
|
|
494
|
-
return
|
|
455
|
+
return !cliBanner().blocked();
|
|
495
456
|
}
|
|
496
457
|
|
|
458
|
+
// A session could not start Codex: "failed to start" with its words at once,
|
|
459
|
+
// then the server is asked again and its answer decides what stays. (The
|
|
460
|
+
// answer is read from the re-check itself: a spawn failure does not change
|
|
461
|
+
// the version, so a change-only notification would never clear the banner.)
|
|
497
462
|
export function flagCdxCliInstallFailure(reason = null) {
|
|
498
|
-
|
|
499
|
-
_cliFailureReason = reason ? String(reason).slice(0, 300) : null;
|
|
500
|
-
refreshCliBanner();
|
|
501
|
-
// Clear the latch from the value recheckCliStatus RETURNS. Relying on the
|
|
502
|
-
// subscriber callback alone deadlocked: the callback only fired when the
|
|
503
|
-
// version string changed, and a spawn failure does not change the version,
|
|
504
|
-
// so the banner could never be dismissed — the Re-check button included.
|
|
505
|
-
recheckCliStatus('codex')
|
|
506
|
-
.then((info) => {
|
|
507
|
-
if (!info?.installed) return;
|
|
508
|
-
_cliInstallFailureForced = false;
|
|
509
|
-
_cliFailureReason = null;
|
|
510
|
-
refreshCliBanner();
|
|
511
|
-
})
|
|
512
|
-
.catch(() => {});
|
|
463
|
+
cliBanner().flagFailure(reason);
|
|
513
464
|
}
|
|
514
465
|
|
|
515
466
|
function ensureCliSubscription() {
|
|
516
|
-
|
|
517
|
-
_cliUnsub = subscribeCliStatus('codex', (info) => {
|
|
518
|
-
_cliInstalled = info?.installed || null;
|
|
519
|
-
if (_cliInstalled) { _cliInstallFailureForced = false; _cliFailureReason = null; }
|
|
520
|
-
refreshCliBanner();
|
|
521
|
-
});
|
|
467
|
+
cliBanner();
|
|
522
468
|
}
|
|
523
469
|
|
|
524
470
|
// ═══════════════════════════════════════════
|
|
@@ -785,14 +731,18 @@ async function saveRecallProfile(profile) {
|
|
|
785
731
|
// ═══════════════════════════════════════════
|
|
786
732
|
|
|
787
733
|
function wireEvents() {
|
|
788
|
-
//
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
734
|
+
// File links open in the code editor (../ui-file-links.js, shared with the other panels): one listener for
|
|
735
|
+
// every tab's transcript, so stored and streaming messages behave alike. Card heads bind in cdx-render.
|
|
736
|
+
wireFileLinks(panelEl('#cxp-messages-container'), {
|
|
737
|
+
// A relative path is a path in the project of the tab on screen (a worker run's tab has the run's folder).
|
|
738
|
+
cwd: (link) => (allTabs().find((tab) => tab.messagesEl?.contains(link)) || activeTab())?.project || '',
|
|
739
|
+
textLinks: 'a.cxp-file-link',
|
|
740
|
+
// A path the editor does not open keeps what a click on it did: it is copied.
|
|
741
|
+
copyPath: (link, path) => navigator.clipboard.writeText(path).then(() => {
|
|
742
|
+
link.classList.add('cxp-file-link-copied');
|
|
743
|
+
setTimeout(() => link.classList.remove('cxp-file-link-copied'), 1500);
|
|
744
|
+
}),
|
|
745
|
+
});
|
|
796
746
|
|
|
797
747
|
const input = panelEl('#cxp-input');
|
|
798
748
|
const send = panelEl('#cxp-send');
|
|
@@ -899,7 +849,6 @@ function wireEvents() {
|
|
|
899
849
|
},
|
|
900
850
|
onOpen: () => {
|
|
901
851
|
sessionMenu?.classList.remove('open');
|
|
902
|
-
panelEl('#cxp-account-menu')?.classList.remove('open');
|
|
903
852
|
panelEl('#cxp-effort-menu')?.classList.remove('open');
|
|
904
853
|
refreshContextMenuDetails();
|
|
905
854
|
},
|
|
@@ -909,8 +858,8 @@ function wireEvents() {
|
|
|
909
858
|
// After this click has reached the document, whose handler closes the menu.
|
|
910
859
|
onAccount: () => setTimeout(() => toggleAccountMenu(), 0),
|
|
911
860
|
});
|
|
912
|
-
// The account menu
|
|
913
|
-
panelEl('
|
|
861
|
+
// The header account menu (account-menu.js, shared with the Claude panel): before the cog.
|
|
862
|
+
mountCodexAccountMenu(panelEl('.cxp-actions'), _panel);
|
|
914
863
|
const slideBtn = panelEl('#cxp-slide');
|
|
915
864
|
slideBtn?.addEventListener('click', () => setVisible(false));
|
|
916
865
|
const changelogBtn = panelEl('#cxp-action-changelog');
|
|
@@ -1028,7 +977,6 @@ function wireEvents() {
|
|
|
1028
977
|
});
|
|
1029
978
|
document.addEventListener('click', (event) => {
|
|
1030
979
|
if (!event.target.closest('.cxp-header')) sessionMenu?.classList.remove('open');
|
|
1031
|
-
if (!event.target.closest('#cxp-account-menu')) panelEl('#cxp-account-menu')?.classList.remove('open');
|
|
1032
980
|
if (!event.target.closest('.cxp-dropdown')) {
|
|
1033
981
|
_panel?.querySelectorAll('.cxp-dropdown.open').forEach((node) => node.classList.remove('open'));
|
|
1034
982
|
}
|
|
@@ -1274,6 +1222,19 @@ export async function attachCodexAutomation(run, {
|
|
|
1274
1222
|
ensurePanel();
|
|
1275
1223
|
await ensureProjectsLoaded();
|
|
1276
1224
|
if (isCancelled()) return { ok: false, reason: 'dismissed' };
|
|
1225
|
+
const running = run.status === 'starting' || run.status === 'running';
|
|
1226
|
+
// The user continued this run's thread by hand after the run ended: the tab stays theirs. The
|
|
1227
|
+
// dock's Focus raises it; the run is let go again, and nothing in the tab changes.
|
|
1228
|
+
const own = allTabs().find((entry) => !entry.automationRunId && entry.releasedRunId === run.runId && entry.threadId === threadId);
|
|
1229
|
+
if (own && !running) {
|
|
1230
|
+
window.dispatchEvent(new CustomEvent('native-loop:dismissed', { detail: { runId: run.runId } }));
|
|
1231
|
+
if (focus) {
|
|
1232
|
+
if (!_visible) await toggleCodexPanel();
|
|
1233
|
+
const ownIdx = allTabs().indexOf(own);
|
|
1234
|
+
if (ownIdx >= 0) switchTab(ownIdx);
|
|
1235
|
+
}
|
|
1236
|
+
return { ok: true, tabId: own.id, released: true };
|
|
1237
|
+
}
|
|
1277
1238
|
let tab = allTabs().find((entry) => entry.automationRunId === run.runId);
|
|
1278
1239
|
if (!tab) {
|
|
1279
1240
|
tab = createTab({
|
|
@@ -1291,7 +1252,6 @@ export async function attachCodexAutomation(run, {
|
|
|
1291
1252
|
}, { autoSwitch: false });
|
|
1292
1253
|
}
|
|
1293
1254
|
if (!tab) return { ok: false, reason: 'tab_limit' };
|
|
1294
|
-
const running = run.status === 'starting' || run.status === 'running';
|
|
1295
1255
|
// A task-mode worker between turns (waiting for a follow-up) is alive, not working.
|
|
1296
1256
|
const working = running && run.turnState !== 'idle' && run.turnState !== 'terminal';
|
|
1297
1257
|
tab.automationRunId = run.runId;
|
|
@@ -1315,10 +1275,12 @@ export async function attachCodexAutomation(run, {
|
|
|
1315
1275
|
return { ok: false, reason: 'dismissed' };
|
|
1316
1276
|
}
|
|
1317
1277
|
}
|
|
1318
|
-
|
|
1278
|
+
// (A dispatched worker's failure, with its reason, is on its end card.)
|
|
1279
|
+
if (run.status === 'failed' && run.error && !isDispatchedRun(run) && tab._automationLifecycleError !== run.error) {
|
|
1319
1280
|
tab._automationLifecycleError = run.error;
|
|
1320
1281
|
withTab(tab, () => appendSystem(run.error, 'error'));
|
|
1321
1282
|
}
|
|
1283
|
+
trackWorkerEnd(run, { apply: (view) => { tab._workerEnd = view; placeWorkerEnd(tab); } });
|
|
1322
1284
|
saveTabs();
|
|
1323
1285
|
renderPills();
|
|
1324
1286
|
if (focus) {
|
|
@@ -16,6 +16,7 @@ import { bindExpandableCard, setCardExpanded } from './cdx-cards.js';
|
|
|
16
16
|
import { mountMcpAppCard } from './cdx-mcp-app-host.js';
|
|
17
17
|
import { OUTPUT_LIMITS, boundedText, jsonAnswer, prettyJsonFences, readableStructuredValue, fileChangeDiffs, parseUnifiedDiff, deduplicateTurnDiff } from './cdx-output-model.js';
|
|
18
18
|
import { renderReadableOutput, renderReadableBlock, cleanOutputBlocks, hydrateOutputControls, observeOutputBlocks, renderDiffView, restoreDiffViews } from './cdx-output.js';
|
|
19
|
+
import { fileLinkTitle, fillFileLinkCopy, isInsideRoots, parseFileLinkTarget } from '../file-links.js';
|
|
19
20
|
export { setCardExpanded } from './cdx-cards.js';
|
|
20
21
|
|
|
21
22
|
// ── Shared context (set by cdx-tabs via setRenderContext) ──
|
|
@@ -375,101 +376,45 @@ export function postProcessRenderedHtml(container) {
|
|
|
375
376
|
// ═══════════════════════════════════════════
|
|
376
377
|
// File Path Linking
|
|
377
378
|
// ═══════════════════════════════════════════
|
|
379
|
+
// What a target means is decided in ../file-links.js, shared with the other panels; a click is taken by the
|
|
380
|
+
// one listener cdx-panel.js puts on the transcript (../ui-file-links.js), so links in a stored transcript
|
|
381
|
+
// work like fresh ones.
|
|
378
382
|
|
|
379
383
|
export function normalizePathForCompare(path) {
|
|
380
384
|
return String(path || '').replace(/\\/g, '/').replace(/\/+$/, '');
|
|
381
385
|
}
|
|
382
386
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
]);
|
|
390
|
-
for (const root of roots) {
|
|
391
|
-
if (!root) continue;
|
|
392
|
-
if (normalized === root || normalized.startsWith(`${root}/`)) return true;
|
|
393
|
-
}
|
|
394
|
-
return false;
|
|
387
|
+
// The folder a relative link is read from: the project of the tab the transcript belongs to.
|
|
388
|
+
function fileLinkWhere() {
|
|
389
|
+
return {
|
|
390
|
+
cwd: _ctx.boundTab?.project || _ctx.project || '',
|
|
391
|
+
origin: globalThis.location?.origin || '',
|
|
392
|
+
};
|
|
395
393
|
}
|
|
396
394
|
|
|
397
|
-
export function
|
|
398
|
-
|
|
399
|
-
let raw = String(rawTarget).trim();
|
|
400
|
-
if (!raw || raw === '#') return null;
|
|
401
|
-
if (raw.startsWith('file://')) {
|
|
402
|
-
try { raw = decodeURIComponent(new URL(raw).pathname || ''); }
|
|
403
|
-
catch { raw = raw.replace(/^file:\/\//, ''); }
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
let pathPart = raw;
|
|
407
|
-
let hash = '';
|
|
408
|
-
if (/^[a-z]+:\/\//i.test(raw)) {
|
|
409
|
-
try {
|
|
410
|
-
const parsed = new URL(raw, window.location.origin);
|
|
411
|
-
if (parsed.origin !== window.location.origin) return null;
|
|
412
|
-
pathPart = parsed.pathname || '';
|
|
413
|
-
hash = parsed.hash || '';
|
|
414
|
-
} catch {
|
|
415
|
-
return null;
|
|
416
|
-
}
|
|
417
|
-
} else {
|
|
418
|
-
const hashIndex = raw.indexOf('#');
|
|
419
|
-
if (hashIndex >= 0) {
|
|
420
|
-
pathPart = raw.slice(0, hashIndex);
|
|
421
|
-
hash = raw.slice(hashIndex);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
try { pathPart = decodeURIComponent(pathPart); } catch {}
|
|
426
|
-
pathPart = normalizePathForCompare(pathPart);
|
|
427
|
-
|
|
428
|
-
let line = null;
|
|
429
|
-
let column = null;
|
|
430
|
-
const suffixMatch = pathPart.match(/:(\d+)(?::(\d+))?$/);
|
|
431
|
-
if (suffixMatch) {
|
|
432
|
-
line = Number(suffixMatch[1]) || null;
|
|
433
|
-
column = Number(suffixMatch[2]) || null;
|
|
434
|
-
pathPart = normalizePathForCompare(pathPart.slice(0, suffixMatch.index));
|
|
435
|
-
}
|
|
436
|
-
if (!isProjectFilePath(pathPart)) return null;
|
|
437
|
-
const hashMatch = hash.match(/^#L(\d+)(?:C(\d+))?$/i);
|
|
438
|
-
if (hashMatch) {
|
|
439
|
-
line = Number(hashMatch[1]) || line;
|
|
440
|
-
column = Number(hashMatch[2]) || column;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
return { filePath: pathPart, line, column };
|
|
395
|
+
export function isProjectFilePath(path) {
|
|
396
|
+
return isInsideRoots(path, [_ctx.boundTab?.project, _ctx.project, ...(_ctx.projects || []).map((entry) => entry?.path)]);
|
|
444
397
|
}
|
|
445
398
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
line: target.line || undefined,
|
|
451
|
-
column: target.column || undefined,
|
|
452
|
-
});
|
|
453
|
-
return true;
|
|
399
|
+
// A link target that is a file of this tab's project or of a registered one, or null.
|
|
400
|
+
function projectFileTarget(rawTarget) {
|
|
401
|
+
const target = parseFileLinkTarget(rawTarget, fileLinkWhere());
|
|
402
|
+
return target?.path && isProjectFilePath(target.path) ? target : null;
|
|
454
403
|
}
|
|
455
404
|
|
|
456
|
-
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
event?.preventDefault?.();
|
|
460
|
-
return openProjectFileTarget(target);
|
|
405
|
+
function openInEditorTitle(target) {
|
|
406
|
+
const { key, params } = fileLinkTitle(target);
|
|
407
|
+
return _ctx.fileLinkText?.(key, params) || fillFileLinkCopy(key, params);
|
|
461
408
|
}
|
|
462
409
|
|
|
463
410
|
export function markProjectFileAnchors(container) {
|
|
464
411
|
if (!container) return;
|
|
465
412
|
container.querySelectorAll('a[href]').forEach((link) => {
|
|
466
|
-
const target =
|
|
413
|
+
const target = projectFileTarget(link.getAttribute('href'));
|
|
467
414
|
if (!target) return;
|
|
468
415
|
link.classList.add('cxp-file-link');
|
|
469
|
-
link.dataset.projectFilePath = target.
|
|
470
|
-
link.title = target
|
|
471
|
-
? `Open in editor${target.column ? ` at line ${target.line}, column ${target.column}` : ` at line ${target.line}`}`
|
|
472
|
-
: 'Open in editor';
|
|
416
|
+
link.dataset.projectFilePath = target.path;
|
|
417
|
+
link.title = openInEditorTitle(target);
|
|
473
418
|
});
|
|
474
419
|
}
|
|
475
420
|
|
|
@@ -497,19 +442,10 @@ export function linkifyFilePaths(container) {
|
|
|
497
442
|
const link = document.createElement('a');
|
|
498
443
|
link.className = 'cxp-file-link';
|
|
499
444
|
link.textContent = pathStr;
|
|
500
|
-
const target =
|
|
501
|
-
link.title = target
|
|
502
|
-
? `Open in editor${target.column ? ` at line ${target.line}, column ${target.column}` : ` at line ${target.line}`}`
|
|
503
|
-
: target ? 'Open in editor' : 'Click to copy path';
|
|
445
|
+
const target = projectFileTarget(pathStr);
|
|
446
|
+
link.title = target ? openInEditorTitle(target) : 'Click to copy path';
|
|
504
447
|
link.href = '#';
|
|
505
|
-
|
|
506
|
-
if (maybeOpenProjectFileLink(pathStr, e)) return;
|
|
507
|
-
e.preventDefault();
|
|
508
|
-
const cleanPath = pathStr.replace(/:\d+(:\d+)?$/, '');
|
|
509
|
-
navigator.clipboard.writeText(cleanPath).catch(() => {});
|
|
510
|
-
link.classList.add('cxp-file-link-copied');
|
|
511
|
-
setTimeout(() => link.classList.remove('cxp-file-link-copied'), 1500);
|
|
512
|
-
});
|
|
448
|
+
// The click is taken on the transcript (cdx-panel.js): the editor when it can open the path, else a copy.
|
|
513
449
|
frag.appendChild(link);
|
|
514
450
|
lastIndex = match.index + match[0].length;
|
|
515
451
|
}
|