@xopcai/xopc 0.0.112 → 0.0.114
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/dist/browser-ext/icons/icon-128.png +0 -0
- package/dist/browser-ext/icons/icon-16.png +0 -0
- package/dist/browser-ext/icons/icon-32.png +0 -0
- package/dist/browser-ext/icons/icon-48.png +0 -0
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/delivery-to.d.ts +3 -3
- package/dist/extensions/weixin/src/delivery-to.js.map +1 -1
- package/dist/gateway/static/root/apple-touch-icon.png +0 -0
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-EhRp-ZMa.js → agent-avatar-dicebear-Fp-p7bP1.js} +1 -1
- package/dist/gateway/static/root/assets/agent-browser-settings-page-CWh7trjd.js +6 -0
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-kC8OuLoj.js +1 -0
- package/dist/gateway/static/root/assets/agents-DJWG26Si.js +71 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BIy7KEsM.js → app-management-settings-panel-v24i25Oj.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DGQG8NwA.js → appearance-settings-ycbdJRuZ.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-0V3DXZ7J.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-uuQPupqx.js → archive-plugin-CJzSADJo.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DBkv0cAv.js → attachment-load-BTAB4zGS.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-DxxN_VAR.js → binary-plugins-DXR1-mct.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CwnUlRmO.js → block-editor-CzQri9h2.js} +44 -44
- package/dist/gateway/static/root/assets/channels-settings-CIKOkYdO.js +1 -0
- package/dist/gateway/static/root/assets/{config-api-BD-NcD5d.js → config-api-DRqjEvAx.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-settings-ClrDS5jH.js +2 -0
- package/dist/gateway/static/root/assets/{cron-api-C5DoipZA.js → cron-api-BXaZXv1o.js} +1 -1
- package/dist/gateway/static/root/assets/cron-page-Chi_4u4P.js +3 -0
- package/dist/gateway/static/root/assets/dreaming-settings-B0_rs2tj.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-BDHA9o_e.js → extension-debug-page-DSkqMYo7.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DmDLVSPE.js → extension-page-h2dGDbMN.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-1124aHw_.js → extension-settings-page-hN99RhOi.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-DOe56Wmy.js → fetch-D9QqUtzZ.js} +1 -1
- package/dist/gateway/static/root/assets/{format-interval-label-tsMSvBSR.js → format-interval-label-D6E687rG.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-CsD4FC9D.js → gateway-config-api-CLt_SKTC.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-HQ8FBhY2.js → gateway-settings-1PDi4lI0.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-C1zg7pH3.js → gateway-startup-retry-N7Z_sz7p.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-D_wwXL-t.js +1 -0
- package/dist/gateway/static/root/assets/goals-page-DZ2toZ8y.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-B5nI6lgz.js → goals-settings-LFlwtIKE.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-CIv42nJD.js → heartbeat-config-api-DGPadTw-.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-DFcVuJ3M.js → heartbeat-settings-BHHAs8ZX.js} +1 -1
- package/dist/gateway/static/root/assets/index-DefIdW9q.js +122 -0
- package/dist/gateway/static/root/assets/index-DzmWBkq-.css +1 -0
- package/dist/gateway/static/root/assets/{interval-presets-DGP3S7OB.js → interval-presets-CEklPQ_r.js} +1 -1
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-fETaDYQP.js → keyboard-shortcuts-settings-Ce_aQ8Iv.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-j_D2QTuQ.js +2 -0
- package/dist/gateway/static/root/assets/{markdown-split-CgeBJMOD.js → markdown-split-BMz3xPXO.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-C30GzlV2.js → media-plugins-BalOSoz9.js} +1 -1
- package/dist/gateway/static/root/assets/messages-BN_WiUg0.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-CMH_TmZz.js +2 -0
- package/dist/gateway/static/root/assets/note-detail-page-O18BrQPq.js +2 -0
- package/dist/gateway/static/root/assets/{note-image-lightbox-t1g0qZYh.js → note-image-lightbox-C5D1Q5mY.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-B_ZYCmY9.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DeWp9x5g.js → preview-open-alternatives-CYFR5U9l.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CwKgWixY.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BOaAOJI3.js → save-bar-controls-BQ79Z5IP.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-BLWLKqgw.js → schedule-field-Bgk6Emue.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-plqRFYT8.js → schema-form-DzS36TMa.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-C4fcD-7B.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-Ad2OJ86w.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-BP5zRrDI.js → settings-collapsible-section-CdjFnSAy.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-Bv8MZplG.js → settings-form-section-DZLy_exu.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-D2BMY5wo.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-aWwxl_E1.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-4OX1YCgp.js → share-preview-page-_qRDr4g_.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DUE83uIf.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-mWKJcrog.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-0Sx1Q58n.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-CGy4f_s2.js → system-settings-panel-hqaBF5aG.js} +1 -1
- package/dist/gateway/static/root/assets/use-agent-defaults-form-zbVIQLOA.js +1 -0
- package/dist/gateway/static/root/assets/{use-channel-catalog-CjGHnDvN.js → use-channel-catalog-CbXq97rT.js} +1 -1
- package/dist/gateway/static/root/assets/{use-settings-tab-guard-BMMFa0oA.js → use-settings-tab-guard-DwS3drWK.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-D6HR0hR2.js +1 -0
- package/dist/gateway/static/root/assets/{voice-player-store-D5vzWwls.js → voice-player-store-DSuOd9zy.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-page.utils-C0Uq3xyq.js +1 -0
- package/dist/gateway/static/root/assets/workflows-page-DW0fmWhQ.js +18 -0
- package/dist/gateway/static/root/favicon-16x16.png +0 -0
- package/dist/gateway/static/root/favicon-32x32.png +0 -0
- package/dist/gateway/static/root/favicon-icon.svg +1 -0
- package/dist/gateway/static/root/favicon.ico +0 -0
- package/dist/gateway/static/root/favicon.png +0 -0
- package/dist/gateway/static/root/favicon.svg +24 -17
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/gateway/static/root/logo-dark.svg +23 -15
- package/dist/gateway/static/root/logo.svg +23 -16
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +8 -0
- package/dist/src/agent/agent-manager.js +57 -22
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/bootstrap/project-agents-context.d.ts +2 -0
- package/dist/src/agent/bootstrap/project-agents-context.js +32 -0
- package/dist/src/agent/bootstrap/project-agents-context.js.map +1 -0
- package/dist/src/agent/goals/persistent-goal-service.js +2 -4
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
- package/dist/src/agent/inbound/inbound-loop.js +5 -1
- package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -2
- package/dist/src/agent/inbound/turn-dispatcher.js +2 -2
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.d.ts +27 -0
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +49 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +78 -3
- package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-types.d.ts +19 -0
- package/dist/src/agent/service/btw-query.js +11 -3
- package/dist/src/agent/service/btw-query.js.map +1 -1
- package/dist/src/agent/service/parse-outbound-session-key.js +13 -8
- package/dist/src/agent/service/parse-outbound-session-key.js.map +1 -1
- package/dist/src/agent/service/process-direct-one-shot.d.ts +2 -2
- package/dist/src/agent/service/process-direct-one-shot.js +1 -1
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
- package/dist/src/agent/service/process-direct-streaming.js +10 -5
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service.d.ts +1 -1
- package/dist/src/agent/service.js +9 -5
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +5 -0
- package/dist/src/agent/skills/filesystem-watcher.js +4 -3
- package/dist/src/agent/skills/filesystem-watcher.js.map +1 -1
- package/dist/src/agent/skills/index.js +2 -1
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +2 -1
- package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
- package/dist/src/agent/skills/types.d.ts +1 -1
- package/dist/src/agent/skills/watcher.js +2 -5
- package/dist/src/agent/skills/watcher.js.map +1 -1
- package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
- package/dist/src/agent/skills/workspace-skills-dir.js +11 -0
- package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -0
- package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
- package/dist/src/agent/tool-manuals/browser.js +62 -3
- package/dist/src/agent/tool-manuals/browser.js.map +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +4 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +13 -4
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -2
- package/dist/src/agent/tools/browser/tool/schemas.js +1 -2
- package/dist/src/agent/tools/browser/tool/schemas.js.map +1 -1
- package/dist/src/agent/tools/factory.js +1 -10
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
- package/dist/src/agent/workflow/subagent-runner.js +18 -1
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/ai-assist/text-assist.d.ts +3 -0
- package/dist/src/ai-assist/text-assist.js +25 -7
- package/dist/src/ai-assist/text-assist.js.map +1 -1
- package/dist/src/browser/actions/extension-registry-bridge.js +91 -7
- package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
- package/dist/src/browser/actions/registry.js +383 -7
- package/dist/src/browser/actions/registry.js.map +1 -1
- package/dist/src/browser/actions/types.d.ts +11 -3
- package/dist/src/browser/index.js +2 -2
- package/dist/src/browser/pipeline/output.d.ts +18 -16
- package/dist/src/browser/pipeline/output.js +28 -20
- package/dist/src/browser/pipeline/output.js.map +1 -1
- package/dist/src/browser/pipeline/runner.d.ts +7 -14
- package/dist/src/browser/pipeline/runner.js +349 -102
- package/dist/src/browser/pipeline/runner.js.map +1 -1
- package/dist/src/browser/pipeline/schema.d.ts +1 -0
- package/dist/src/browser/pipeline/schema.js +35 -58
- package/dist/src/browser/pipeline/schema.js.map +1 -1
- package/dist/src/browser/pipeline/source.d.ts +2 -0
- package/dist/src/browser/pipeline/source.js +10 -1
- package/dist/src/browser/pipeline/source.js.map +1 -1
- package/dist/src/browser/pipeline/template.d.ts +10 -2
- package/dist/src/browser/pipeline/template.js +50 -8
- package/dist/src/browser/pipeline/template.js.map +1 -1
- package/dist/src/channels/plugins/types.adapters.d.ts +2 -2
- package/dist/src/chat-commands/builtins/config.js +3 -5
- package/dist/src/chat-commands/builtins/config.js.map +1 -1
- package/dist/src/chat-commands/context.d.ts +5 -0
- package/dist/src/chat-commands/context.js +18 -9
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/chat-commands/index.d.ts +1 -1
- package/dist/src/chat-commands/index.js +2 -2
- package/dist/src/chat-commands/index.js.map +1 -1
- package/dist/src/chat-commands/processor.js +22 -21
- package/dist/src/chat-commands/processor.js.map +1 -1
- package/dist/src/chat-commands/session-key.d.ts +3 -15
- package/dist/src/chat-commands/session-key.js +3 -49
- package/dist/src/chat-commands/session-key.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +4 -0
- package/dist/src/cli/commands/browser-cli-helpers.js +11 -5
- package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +8 -8
- package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
- package/dist/src/config/rules.js +5 -0
- package/dist/src/config/rules.js.map +1 -1
- package/dist/src/connectors/builtin-catalog.js +180 -1
- package/dist/src/connectors/builtin-catalog.js.map +1 -1
- package/dist/src/connectors/health.js +18 -9
- package/dist/src/connectors/health.js.map +1 -1
- package/dist/src/connectors/types.d.ts +19 -0
- package/dist/src/connectors/usage.js +12 -4
- package/dist/src/connectors/usage.js.map +1 -1
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/types.d.ts +2 -2
- package/dist/src/extensions/types/tui.d.ts +2 -0
- package/dist/src/gateway/heartbeat/service.js +13 -1
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/app.js +13 -4
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/oauth-async.js +1 -1
- package/dist/src/gateway/hono/routes/agent-stream.js +6 -6
- package/dist/src/gateway/hono/routes/agent-stream.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +6 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/goals.js +16 -3
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/logs.js +1 -0
- package/dist/src/gateway/hono/routes/logs.js.map +1 -1
- package/dist/src/gateway/hono/routes/mcp.js +27 -8
- package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
- package/dist/src/gateway/hono/routes/notes.js +14 -2
- package/dist/src/gateway/hono/routes/notes.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +62 -4
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +3 -66
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/hono/sse.d.ts +2 -2
- package/dist/src/gateway/hono/sse.js +7 -15
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/resolve-webchat-session-key.d.ts +2 -6
- package/dist/src/gateway/resolve-webchat-session-key.js +5 -31
- package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +2 -3
- package/dist/src/gateway/service/agent-runner.js +9 -22
- package/dist/src/gateway/service/agent-runner.js.map +1 -1
- package/dist/src/gateway/service/run-gateway-agent.js +9 -7
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +9 -0
- package/dist/src/gateway/service/sessions-api.js +11 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.d.ts +1 -1
- package/dist/src/gateway/service.js +19 -5
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-file-search.d.ts +9 -0
- package/dist/src/gateway/workspace-file-search.js +76 -0
- package/dist/src/gateway/workspace-file-search.js.map +1 -0
- package/dist/src/goals/goal-notifications.d.ts +2 -0
- package/dist/src/goals/goal-notifications.js +16 -11
- package/dist/src/goals/goal-notifications.js.map +1 -1
- package/dist/src/goals/goal-service.js +1 -6
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/project-trust/trust-store.js +2 -0
- package/dist/src/project-trust/trust-store.js.map +1 -1
- package/dist/src/session/index.d.ts +1 -1
- package/dist/src/session/index.js +2 -2
- package/dist/src/session/init-session-turn.js +6 -9
- package/dist/src/session/init-session-turn.js.map +1 -1
- package/dist/src/session/manager.d.ts +5 -1
- package/dist/src/session/manager.js +5 -2
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/reset-type.d.ts +0 -2
- package/dist/src/session/reset-type.js +3 -9
- package/dist/src/session/reset-type.js.map +1 -1
- package/dist/src/session/resolve-session.js +9 -20
- package/dist/src/session/resolve-session.js.map +1 -1
- package/dist/src/session/store-reader.d.ts +5 -0
- package/dist/src/session/store-reader.js +1 -0
- package/dist/src/session/store.d.ts +11 -3
- package/dist/src/session/store.js +29 -13
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/types.d.ts +2 -4
- package/dist/src/session/types.js.map +1 -1
- package/dist/src/storage/sqlite/index.d.ts +2 -2
- package/dist/src/storage/sqlite/index.js +3 -3
- package/dist/src/storage/sqlite/migrations/010_session_id_identity.sql +30 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +2 -2
- package/dist/src/storage/sqlite/migrations/runner.js +4 -4
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +2 -2
- package/dist/src/storage/sqlite/row-mappers.d.ts +4 -4
- package/dist/src/storage/sqlite/row-mappers.js +11 -14
- package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
- package/dist/src/storage/sqlite/schema.js +3 -3
- package/dist/src/storage/sqlite/schema.js.map +1 -1
- package/dist/src/storage/sqlite/schema.sql +37 -10
- package/dist/src/storage/sqlite/session-metadata.d.ts +2 -7
- package/dist/src/storage/sqlite/session-metadata.js +18 -72
- package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
- package/dist/src/storage/sqlite/session-repository.d.ts +6 -5
- package/dist/src/storage/sqlite/session-repository.js +34 -40
- package/dist/src/storage/sqlite/session-repository.js.map +1 -1
- package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -2
- package/dist/src/storage/sqlite/transcript-repository.js +52 -52
- package/dist/src/storage/sqlite/transcript-repository.js.map +1 -1
- package/dist/src/tui/backends/embedded-backend.d.ts +11 -4
- package/dist/src/tui/backends/embedded-backend.js +27 -1
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +4 -1
- package/dist/src/tui/backends/gateway-sse-backend.js +21 -2
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/extension-host/autocomplete.js +13 -10
- package/dist/src/tui/extension-host/autocomplete.js.map +1 -1
- package/dist/src/tui/extension-host/runtime.d.ts +7 -0
- package/dist/src/tui/extension-host/runtime.js +6 -4
- package/dist/src/tui/extension-host/runtime.js.map +1 -1
- package/dist/src/tui/tui-backend.d.ts +9 -0
- package/dist/src/tui/tui-commands.js +85 -6
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-file-autocomplete.d.ts +5 -0
- package/dist/src/tui/tui-file-autocomplete.js +26 -0
- package/dist/src/tui/tui-file-autocomplete.js.map +1 -0
- package/dist/src/tui/tui-picker-overlay.js +1 -1
- package/dist/src/tui/tui.js +29 -11
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/utils/logger/context.d.ts +2 -2
- package/dist/src/utils/logger/context.js +2 -1
- package/dist/src/utils/logger/context.js.map +1 -1
- package/dist/src/utils/logger/log-store.js +1 -0
- package/dist/src/utils/logger/log-store.js.map +1 -1
- package/dist/src/utils/logger/pino-record.js +3 -0
- package/dist/src/utils/logger/pino-record.js.map +1 -1
- package/dist/src/utils/logger/types.d.ts +5 -0
- package/dist/src/utils/logger/types.js.map +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +13 -1
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agent-browser-settings-page-H4foVCiS.js +0 -6
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-DDNw2oNU.js +0 -1
- package/dist/gateway/static/root/assets/agents-E_X2kzS1.js +0 -71
- package/dist/gateway/static/root/assets/apps-page-BZLvInLr.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BHvUKlzw.js +0 -1
- package/dist/gateway/static/root/assets/connectors-settings-VBzXcEXL.js +0 -2
- package/dist/gateway/static/root/assets/cron-page-BLTpdm34.js +0 -3
- package/dist/gateway/static/root/assets/dreaming-settings-DSVhXTPq.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-BG3Onph0.js +0 -1
- package/dist/gateway/static/root/assets/goals-page-DgeKn8zL.js +0 -2
- package/dist/gateway/static/root/assets/index-5A_ZaABy.css +0 -1
- package/dist/gateway/static/root/assets/index-BTmbp2AU.js +0 -121
- package/dist/gateway/static/root/assets/logs-page-B1-b27lK.js +0 -2
- package/dist/gateway/static/root/assets/messages-BUUfPaZ9.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-DPcTS1-u.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-page-xeGb4owe.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-C_TdnKBe.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BtkPmJIN.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DOUjxzJm.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-qK_bnTrw.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-DmDfE1ww.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BEFwNcIZ.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CbKmJZot.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-YdtnUHtK.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-DwW1IzQ0.js +0 -2
- package/dist/gateway/static/root/assets/use-agent-defaults-form-BMuMvzl_.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-DnRbhMNq.js +0 -1
- package/dist/gateway/static/root/assets/workflow-page.utils-tjGpRVnw.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-DqqHKGj2.js +0 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autocomplete.js","names":[],"sources":["../../../../src/tui/extension-host/autocomplete.ts"],"sourcesContent":["import type {\n AutocompleteItem,\n AutocompleteProvider,\n AutocompleteSuggestions,\n} from '@earendil-works/pi-tui';\n\nimport type {\n TuiAutocompleteProvider,\n TuiAutocompleteProviderApi,\n TuiAutocompleteProviderFactory,\n} from '../../extensions/types/tui.js';\n\nexport interface ExtensionSlashCommandAutocompleteItem {\n originalName: string;\n name: string;\n description: string;\n}\n\nexport function dedupeAutocompleteItems(items: AutocompleteItem[]): AutocompleteItem[] {\n const seen = new Set<string>();\n return items.filter((item) => {\n if (seen.has(item.value)) return false;\n seen.add(item.value);\n return true;\n });\n}\n\nexport class ChainedAutocompleteProvider implements AutocompleteProvider {\n constructor(\n private readonly primary: AutocompleteProvider,\n private readonly extraProviders: TuiAutocompleteProvider[],\n private readonly extensionSlashCommands: ExtensionSlashCommandAutocompleteItem[],\n private readonly baseSlashCommandNames: Set<string>,\n private readonly getSessionKey: () => string,\n private readonly cwd: string,\n ) {}\n\n async getSuggestions(\n lines: string[],\n cursorLine: number,\n cursorCol: number,\n options: { signal: AbortSignal; force?: boolean },\n ): Promise<AutocompleteSuggestions | null> {\n const primary = await this.primary.getSuggestions(lines, cursorLine, cursorCol, options);\n\n const line = lines[cursorLine] ?? '';\n const beforeCursor = line.slice(0, cursorCol);\n\n const slashMatch = beforeCursor.match(/^\\/([\\w:-]*)$/);\n if (slashMatch && this.extensionSlashCommands.length > 0) {\n const query = (slashMatch[1] ?? '').toLowerCase();\n const prefix = `/${slashMatch[1] ?? ''}`;\n const items: AutocompleteItem[] = this.extensionSlashCommands\n .filter((c) => !this.baseSlashCommandNames.has(c.originalName))\n .filter((c) => !query || c.name.startsWith(query))\n .map((c) => ({\n value: `/${c.name}`,\n label: c.name,\n description: c.description,\n }));\n if (items.length > 0) {\n const merged = primary?.items ? [...primary.items, ...items] : items;\n const seen = new Set<string>();\n const deduped = merged.filter((item) => {\n if (seen.has(item.value)) return false;\n seen.add(item.value);\n return true;\n });\n return { prefix, items: deduped.slice(0, 30) };\n }\n }\n\n const atMatch = beforeCursor.match(/@([
|
|
1
|
+
{"version":3,"file":"autocomplete.js","names":[],"sources":["../../../../src/tui/extension-host/autocomplete.ts"],"sourcesContent":["import type {\n AutocompleteItem,\n AutocompleteProvider,\n AutocompleteSuggestions,\n} from '@earendil-works/pi-tui';\n\nimport type {\n TuiAutocompleteProvider,\n TuiAutocompleteProviderApi,\n TuiAutocompleteProviderFactory,\n} from '../../extensions/types/tui.js';\n\nexport interface ExtensionSlashCommandAutocompleteItem {\n originalName: string;\n name: string;\n description: string;\n}\n\nexport function dedupeAutocompleteItems(items: AutocompleteItem[]): AutocompleteItem[] {\n const seen = new Set<string>();\n return items.filter((item) => {\n if (seen.has(item.value)) return false;\n seen.add(item.value);\n return true;\n });\n}\n\nexport class ChainedAutocompleteProvider implements AutocompleteProvider {\n constructor(\n private readonly primary: AutocompleteProvider,\n private readonly extraProviders: TuiAutocompleteProvider[],\n private readonly extensionSlashCommands: ExtensionSlashCommandAutocompleteItem[],\n private readonly baseSlashCommandNames: Set<string>,\n private readonly getSessionKey: () => string,\n private readonly cwd: string,\n ) {}\n\n async getSuggestions(\n lines: string[],\n cursorLine: number,\n cursorCol: number,\n options: { signal: AbortSignal; force?: boolean },\n ): Promise<AutocompleteSuggestions | null> {\n const primary = await this.primary.getSuggestions(lines, cursorLine, cursorCol, options);\n\n const line = lines[cursorLine] ?? '';\n const beforeCursor = line.slice(0, cursorCol);\n\n const slashMatch = beforeCursor.match(/^\\/([\\w:-]*)$/);\n if (slashMatch && this.extensionSlashCommands.length > 0) {\n const query = (slashMatch[1] ?? '').toLowerCase();\n const prefix = `/${slashMatch[1] ?? ''}`;\n const items: AutocompleteItem[] = this.extensionSlashCommands\n .filter((c) => !this.baseSlashCommandNames.has(c.originalName))\n .filter((c) => !query || c.name.startsWith(query))\n .map((c) => ({\n value: `/${c.name}`,\n label: c.name,\n description: c.description,\n }));\n if (items.length > 0) {\n const merged = primary?.items ? [...primary.items, ...items] : items;\n const seen = new Set<string>();\n const deduped = merged.filter((item) => {\n if (seen.has(item.value)) return false;\n seen.add(item.value);\n return true;\n });\n return { prefix, items: deduped.slice(0, 30) };\n }\n }\n\n const atMatch = beforeCursor.match(/@([^\\s]*)$/);\n if (!atMatch) {\n return primary;\n }\n\n const query = atMatch[1] ?? '';\n const prefix = `@${query}`;\n const sessionKey = this.getSessionKey();\n const items: AutocompleteItem[] = [];\n\n for (const provider of this.extraProviders) {\n const suggestions = await provider(query, { cwd: this.cwd, sessionKey });\n for (const s of suggestions) {\n const value = s.value ?? `@${s.name}`;\n items.push({\n value,\n label: s.label ?? s.name,\n description: s.description,\n });\n }\n }\n\n if (items.length === 0) {\n return primary;\n }\n\n const primaryItems = primary?.prefix.startsWith('@') ? primary.items : [];\n const merged = dedupeAutocompleteItems([...primaryItems, ...items]);\n\n return {\n prefix: primary?.prefix.startsWith('@') ? primary.prefix : prefix,\n items: merged.slice(0, 30),\n };\n }\n\n applyCompletion(\n lines: string[],\n cursorLine: number,\n cursorCol: number,\n item: AutocompleteItem,\n prefix: string,\n ) {\n if (prefix.startsWith('@')) {\n const line = lines[cursorLine] ?? '';\n const before = line.slice(0, cursorCol);\n const start = before.length - prefix.length;\n const suffix = item.value.startsWith('@file:') && !item.value.endsWith('/') ? ' ' : '';\n const nextLine = line.slice(0, start) + item.value + suffix + line.slice(cursorCol);\n const nextLines = [...lines];\n nextLines[cursorLine] = nextLine;\n return {\n lines: nextLines,\n cursorLine,\n cursorCol: start + item.value.length + suffix.length,\n };\n }\n return this.primary.applyCompletion(lines, cursorLine, cursorCol, item, prefix);\n }\n\n shouldTriggerFileCompletion(\n lines: string[],\n cursorLine: number,\n cursorCol: number,\n ): boolean {\n return this.primary.shouldTriggerFileCompletion?.(lines, cursorLine, cursorCol) ?? false;\n }\n}\n\nexport class WrappedAutocompleteProvider implements AutocompleteProvider {\n constructor(\n private readonly baseProvider: AutocompleteProvider,\n private readonly factories: TuiAutocompleteProviderFactory[],\n ) {}\n\n private currentProvider(): AutocompleteProvider {\n let provider = this.baseProvider as TuiAutocompleteProviderApi;\n const triggerCharacters: string[] = [];\n for (const factory of this.factories) {\n provider = factory(provider);\n triggerCharacters.push(...(provider.triggerCharacters ?? []));\n }\n if (triggerCharacters.length > 0) {\n provider.triggerCharacters = [...new Set(triggerCharacters)];\n }\n return provider as AutocompleteProvider;\n }\n\n getSuggestions(\n lines: string[],\n cursorLine: number,\n cursorCol: number,\n options: { signal: AbortSignal; force?: boolean },\n ): Promise<AutocompleteSuggestions | null> {\n return this.currentProvider().getSuggestions(lines, cursorLine, cursorCol, options);\n }\n\n applyCompletion(\n lines: string[],\n cursorLine: number,\n cursorCol: number,\n item: AutocompleteItem,\n prefix: string,\n ): { lines: string[]; cursorLine: number; cursorCol: number } {\n return this.currentProvider().applyCompletion(lines, cursorLine, cursorCol, item, prefix);\n }\n\n shouldTriggerFileCompletion(\n lines: string[],\n cursorLine: number,\n cursorCol: number,\n ): boolean {\n return this.currentProvider().shouldTriggerFileCompletion?.(lines, cursorLine, cursorCol) ?? false;\n }\n}\n"],"mappings":"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"}
|
|
@@ -68,6 +68,13 @@ export interface CreateTuiExtensionRuntimeOptions {
|
|
|
68
68
|
reload?: () => Promise<void>;
|
|
69
69
|
sendUserMessage?: TuiReplacedSessionContext['sendUserMessage'];
|
|
70
70
|
sendMessage?: TuiReplacedSessionContext['sendMessage'];
|
|
71
|
+
searchWorkspaceFiles?: (sessionKey: string, query: string, options?: {
|
|
72
|
+
limit?: number;
|
|
73
|
+
}) => Promise<Array<{
|
|
74
|
+
name: string;
|
|
75
|
+
path: string;
|
|
76
|
+
isDirectory: boolean;
|
|
77
|
+
}>>;
|
|
71
78
|
cwd: string;
|
|
72
79
|
fdPath: string | null;
|
|
73
80
|
openOverlay: (component: Component, options?: OverlayOptions) => OverlayHandle | void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { theme } from "../theme.js";
|
|
2
|
+
import { createTuiFileAutocompleteProvider } from "../tui-file-autocomplete.js";
|
|
2
3
|
import { getGitBranchCached } from "../tui-git-branch.js";
|
|
3
4
|
import { ExtensionEditorDialog, ExtensionInputDialog, ExtensionSelectDialog } from "../components/extension-dialog.js";
|
|
4
|
-
import { createSkillsAutocompleteProvider } from "../tui-skills-autocomplete.js";
|
|
5
5
|
import { clearTuiToolRenderers } from "./tool-renderers.js";
|
|
6
6
|
import { createTuiExtensionHost, invokeTuiExtensionRegistrars } from "./host.js";
|
|
7
7
|
import { ChainedAutocompleteProvider, WrappedAutocompleteProvider } from "./autocomplete.js";
|
|
@@ -40,13 +40,15 @@ function createTuiExtensionRuntime(opts) {
|
|
|
40
40
|
const surface = new TuiExtensionSurface();
|
|
41
41
|
const slashCommands = [];
|
|
42
42
|
const shortcuts = [];
|
|
43
|
-
const autocompleteProviders = [
|
|
43
|
+
const autocompleteProviders = [];
|
|
44
|
+
if (opts.searchWorkspaceFiles) autocompleteProviders.push(createTuiFileAutocompleteProvider(opts.searchWorkspaceFiles));
|
|
45
|
+
const baseAutocompleteProviderCount = autocompleteProviders.length;
|
|
44
46
|
const autocompleteProviderFactories = [];
|
|
45
47
|
const disposers = [];
|
|
46
48
|
const autocompleteProvider = new WrappedAutocompleteProvider(new ChainedAutocompleteProvider(new CombinedAutocompleteProvider(opts.baseSlashCommands.map((c) => ({
|
|
47
49
|
name: c.name,
|
|
48
50
|
description: c.description
|
|
49
|
-
})), opts.cwd,
|
|
51
|
+
})), opts.cwd, null), autocompleteProviders, slashCommands, new Set(opts.baseSlashCommands.map((command) => command.name)), () => opts.getState().currentSessionKey, opts.cwd), autocompleteProviderFactories);
|
|
50
52
|
const invalidate = () => {
|
|
51
53
|
opts.header.setCustomComponent?.(surface.customHeader);
|
|
52
54
|
opts.header.setExtensionLines(surface.getHeaderLines());
|
|
@@ -611,7 +613,7 @@ function createTuiExtensionRuntime(opts) {
|
|
|
611
613
|
opts.setEditorComponent?.(void 0);
|
|
612
614
|
slashCommands.length = 0;
|
|
613
615
|
shortcuts.length = 0;
|
|
614
|
-
autocompleteProviders.length =
|
|
616
|
+
autocompleteProviders.length = baseAutocompleteProviderCount;
|
|
615
617
|
autocompleteProviderFactories.length = 0;
|
|
616
618
|
invalidate();
|
|
617
619
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","names":[],"sources":["../../../../src/tui/extension-host/runtime.ts"],"sourcesContent":["import {\n CombinedAutocompleteProvider,\n matchesKey,\n type Component,\n type AutocompleteItem,\n type AutocompleteProvider,\n type KeybindingsManager,\n type OverlayHandle,\n type OverlayOptions,\n type TUI,\n} from '@earendil-works/pi-tui';\n\nimport type { ExtensionRegistryImpl } from '../../extensions/loader.js';\nimport type {\n TuiAutocompleteProvider,\n TuiAutocompleteProviderFactory,\n TuiAutocompleteSuggestion,\n TuiActionUiContext,\n TuiCompactOptions,\n TuiCompactResult,\n TuiCustomComponent,\n TuiCustomFactory,\n TuiCustomOptions,\n TuiDialogOptions,\n TuiEditorFactory,\n TuiForkOptions,\n TuiFooterDataProvider,\n TuiFooterFactory,\n TuiHeaderFactory,\n TuiModelRegistry,\n TuiNotifyLevel,\n TuiOverlayHandle,\n TuiNavigateTreeOptions,\n TuiNewSessionOptions,\n TuiReasoningLevel,\n TuiReplacedSessionContext,\n TuiReplacementResult,\n TuiReadonlySessionManager,\n TuiSlashCommandContext,\n TuiShortcutHandler,\n TuiSlashCommandHandler,\n TuiSwitchSessionOptions,\n TuiSystemPromptOptions,\n TuiTerminalInputHandler,\n TuiSetThemeResult,\n TuiTheme,\n TuiThemeInfo,\n TuiThinkingLevel,\n TuiVerboseLevel,\n TuiWidgetFactory,\n TuiWorkingIndicatorOptions,\n} from '../../extensions/types/tui.js';\nimport type { ChatLog } from '../components/chat-log.js';\nimport {\n ExtensionEditorDialog,\n ExtensionInputDialog,\n ExtensionSelectDialog,\n} from '../components/extension-dialog.js';\nimport type { TuiHeader } from '../components/tui-header.js';\nimport type { TuiBottomBar } from '../components/tui-bottom-bar.js';\nimport type { TuiState } from '../tui-types.js';\nimport { theme } from '../theme.js';\nimport { getGitBranchCached } from '../tui-git-branch.js';\nimport { createSkillsAutocompleteProvider } from '../tui-skills-autocomplete.js';\nimport { createTuiExtensionHost, invokeTuiExtensionRegistrars } from './host.js';\nimport { ChainedAutocompleteProvider, WrappedAutocompleteProvider } from './autocomplete.js';\nimport {\n STALE_EXTENSION_CONTEXT_MESSAGE,\n boundedWidgetLines,\n createDefaultModelRegistry,\n createEmptySessionManager,\n getTuiContextUsage,\n getTuiModelInfo,\n getTuiReasoningLevel,\n getTuiThinkingLevel,\n getTuiVerboseLevel,\n hasPendingTuiMessages,\n invokeCustomFactory,\n isTuiIdle,\n notifyInChatLog,\n resolveCustomOverlayOptions,\n disposeComponent,\n} from './runtime-context.js';\nimport { clearTuiToolRenderers } from './tool-renderers.js';\nimport { TuiExtensionSurface } from './surface.js';\n\nexport interface TuiExtensionSlashCommand {\n originalName: string;\n name: string;\n description: string;\n handler: TuiSlashCommandHandler;\n getContext: () => TuiSlashCommandContext;\n}\n\nexport interface TuiExtensionShortcut {\n key: string;\n description: string;\n handler: TuiShortcutHandler;\n getContext: () => TuiSlashCommandContext;\n}\n\nexport interface TuiExtensionRuntime {\n surface: TuiExtensionSurface;\n slashCommands: TuiExtensionSlashCommand[];\n shortcuts: TuiExtensionShortcut[];\n autocompleteProvider: AutocompleteProvider;\n handleShortcut(data: string): boolean;\n activate(): Promise<void>;\n dispose(): void;\n}\n\nexport interface CreateTuiExtensionRuntimeOptions {\n registry?: ExtensionRegistryImpl;\n tui: TUI;\n chatLog: ChatLog;\n header: TuiHeader;\n bottomBar: TuiBottomBar;\n getState: () => TuiState;\n baseSlashCommands: Array<{ name: string; description: string }>;\n keybindings?: KeybindingsManager;\n addInputListener?: (handler: TuiTerminalInputHandler) => () => void;\n setTitle?: (title: string) => void;\n pasteToEditor?: (text: string) => void;\n setEditorText?: (text: string) => void;\n getEditorText?: () => string;\n setEditorComponent?: (factory: TuiEditorFactory | undefined) => void;\n getEditorComponent?: () => TuiEditorFactory | undefined;\n getThemeObject?: () => TuiTheme;\n getAllThemes?: () => TuiThemeInfo[];\n getTheme?: (name: string) => TuiTheme | undefined;\n setTheme?: (theme: string) => TuiSetThemeResult;\n getToolsExpanded?: () => boolean;\n setToolsExpanded?: (expanded: boolean) => void;\n getAvailableProviderCount?: () => number;\n getActiveSignal?: () => AbortSignal | undefined;\n isProjectTrusted?: () => boolean;\n getSessionManager?: () => TuiReadonlySessionManager;\n getModelRegistry?: () => TuiModelRegistry;\n getSystemPrompt?: () => string;\n getSystemPromptOptions?: () => TuiSystemPromptOptions;\n waitForIdle?: () => Promise<void>;\n newSession?: (options?: TuiNewSessionOptions) => Promise<TuiReplacementResult>;\n forkSession?: (entryId: string, options?: TuiForkOptions) => Promise<TuiReplacementResult>;\n navigateTree?: (targetId: string, options?: TuiNavigateTreeOptions) => Promise<TuiReplacementResult>;\n switchSession?: (sessionPath: string, options?: TuiSwitchSessionOptions) => Promise<TuiReplacementResult>;\n reload?: () => Promise<void>;\n sendUserMessage?: TuiReplacedSessionContext['sendUserMessage'];\n sendMessage?: TuiReplacedSessionContext['sendMessage'];\n cwd: string;\n fdPath: string | null;\n openOverlay: (component: Component, options?: OverlayOptions) => OverlayHandle | void;\n closeOverlay: () => void;\n onInvalidate: () => void;\n abortActive?: () => void | Promise<void>;\n requestExit?: () => void;\n compactSession?: (options?: TuiCompactOptions) => void | Promise<void | TuiCompactResult>;\n setModel?: (modelRef: string) => void | Promise<void>;\n setThinkingLevel?: (level: TuiThinkingLevel) => void | Promise<void>;\n setReasoningLevel?: (level: TuiReasoningLevel) => void | Promise<void>;\n setVerboseLevel?: (level: TuiVerboseLevel) => void | Promise<void>;\n setWorkingMessage?: (message?: string) => void;\n setWorkingVisible?: (visible: boolean) => void;\n setWorkingIndicator?: (options?: TuiWorkingIndicatorOptions) => void;\n}\n\nfunction recomputeSlashCommandInvocationNames(commands: TuiExtensionSlashCommand[]) {\n const counts = new Map<string, number>();\n for (const command of commands) {\n counts.set(command.originalName, (counts.get(command.originalName) ?? 0) + 1);\n }\n\n const seen = new Map<string, number>();\n const taken = new Set<string>();\n for (const command of commands) {\n const occurrence = (seen.get(command.originalName) ?? 0) + 1;\n seen.set(command.originalName, occurrence);\n\n let name = (counts.get(command.originalName) ?? 0) > 1\n ? `${command.originalName}:${occurrence}`\n : command.originalName;\n if (taken.has(name)) {\n let suffix = occurrence;\n do {\n suffix += 1;\n name = `${command.originalName}:${suffix}`;\n } while (taken.has(name));\n }\n command.name = name;\n taken.add(name);\n }\n}\n\nfunction suggestionsToAutocompleteItems(\n suggestions: TuiAutocompleteSuggestion[],\n): AutocompleteItem[] {\n return suggestions.map((s) => ({\n value: `@${s.name}`,\n label: s.name,\n description: s.description,\n }));\n}\n\nexport function createTuiExtensionRuntime(\n opts: CreateTuiExtensionRuntimeOptions,\n): TuiExtensionRuntime {\n const surface = new TuiExtensionSurface();\n const slashCommands: TuiExtensionSlashCommand[] = [];\n const shortcuts: TuiExtensionShortcut[] = [];\n const autocompleteProviders: TuiAutocompleteProvider[] = [\n createSkillsAutocompleteProvider(),\n ];\n const autocompleteProviderFactories: TuiAutocompleteProviderFactory[] = [];\n const disposers: Array<() => void> = [];\n\n const baseProvider = new CombinedAutocompleteProvider(\n opts.baseSlashCommands.map((c) => ({ name: c.name, description: c.description })),\n opts.cwd,\n opts.fdPath,\n );\n\n const chainedProvider = new ChainedAutocompleteProvider(\n baseProvider,\n autocompleteProviders,\n slashCommands,\n new Set(opts.baseSlashCommands.map((command) => command.name)),\n () => opts.getState().currentSessionKey,\n opts.cwd,\n );\n const autocompleteProvider = new WrappedAutocompleteProvider(\n chainedProvider,\n autocompleteProviderFactories,\n );\n\n const invalidate = () => {\n opts.header.setCustomComponent?.(surface.customHeader);\n opts.header.setExtensionLines(surface.getHeaderLines());\n opts.header.setExtensionComponents?.(surface.getHeaderComponents());\n opts.bottomBar.setCustomComponent?.(surface.customFooter);\n opts.bottomBar.setExtensionLines(surface.getFooterLines());\n opts.bottomBar.setExtensionComponents?.(surface.getFooterComponents());\n opts.bottomBar.setExtensionStatusParts(surface.getStatusParts());\n opts.onInvalidate();\n };\n\n const createWidgetComponent = (factory: TuiWidgetFactory): Component & { dispose?(): void } =>\n factory(opts.tui, theme) as Component & { dispose?(): void };\n\n const footerDataProvider: TuiFooterDataProvider = {\n getGitBranch: () => getGitBranchCached(opts.cwd),\n getExtensionStatuses: () => surface.statusSlots,\n getAvailableProviderCount: () => opts.getAvailableProviderCount?.() ?? 0,\n onBranchChange: () => () => {},\n };\n const modelRegistry = opts.getModelRegistry?.() ?? createDefaultModelRegistry();\n\n const setCustomHeader = (factory: TuiHeaderFactory | undefined) => {\n disposeComponent(surface.customHeader);\n surface.customHeader = factory\n ? (factory(opts.tui, theme) as Component & { dispose?(): void })\n : undefined;\n invalidate();\n };\n\n const setCustomFooter = (factory: TuiFooterFactory | undefined) => {\n disposeComponent(surface.customFooter);\n surface.customFooter = factory\n ? (factory(opts.tui, theme, footerDataProvider) as Component & { dispose?(): void })\n : undefined;\n invalidate();\n };\n\n const clearWidgetKey = (fullKey: string) => {\n surface.headerWidgets.delete(fullKey);\n surface.footerWidgets.delete(fullKey);\n const headerComponent = surface.headerWidgetComponents.get(fullKey);\n const footerComponent = surface.footerWidgetComponents.get(fullKey);\n surface.headerWidgetComponents.delete(fullKey);\n surface.footerWidgetComponents.delete(fullKey);\n disposeComponent(headerComponent);\n disposeComponent(footerComponent);\n };\n\n const createActionUiContext = (extensionId: string): TuiActionUiContext => {\n const widgetKey = (key: string) => `${extensionId}:${key}`;\n return {\n select: selectDialog,\n confirm: confirmDialog,\n input: inputDialog,\n notify: (message, level) => notifyInChatLog(opts.chatLog, opts.tui, message, level),\n onTerminalInput: (handler) => {\n const unregister = opts.addInputListener?.(handler);\n if (!unregister) return () => {};\n disposers.push(unregister);\n return () => {\n unregister();\n const idx = disposers.indexOf(unregister);\n if (idx >= 0) disposers.splice(idx, 1);\n };\n },\n setStatus: (key, text) => {\n const fullKey = widgetKey(key);\n if (!text) {\n surface.statusSlots.delete(fullKey);\n } else {\n surface.statusSlots.set(fullKey, text);\n }\n invalidate();\n },\n setWorkingMessage: (message) => {\n opts.setWorkingMessage?.(message ?? undefined);\n invalidate();\n },\n setWorkingVisible: (visible) => {\n opts.setWorkingVisible?.(visible);\n invalidate();\n },\n setWorkingIndicator: (indicator) => {\n opts.setWorkingIndicator?.(indicator ?? undefined);\n invalidate();\n },\n setHiddenThinkingLabel: (label) => {\n opts.chatLog.setHiddenThinkingLabel(label ?? undefined);\n invalidate();\n },\n setWidget: (key, content, options) => {\n const fullKey = widgetKey(key);\n clearWidgetKey(fullKey);\n if (!content) {\n invalidate();\n return;\n }\n if (typeof content === 'function') {\n const target = options?.placement === 'belowEditor'\n ? surface.footerWidgetComponents\n : surface.headerWidgetComponents;\n target.set(fullKey, createWidgetComponent(content as TuiWidgetFactory));\n } else {\n const target = options?.placement === 'belowEditor'\n ? surface.footerWidgets\n : surface.headerWidgets;\n target.set(fullKey, boundedWidgetLines(content));\n }\n invalidate();\n },\n setFooter: setCustomFooter,\n setHeader: setCustomHeader,\n custom: customOverlay,\n setTitle: (title) => opts.setTitle?.(title),\n pasteToEditor: (text) => opts.pasteToEditor?.(text),\n setEditorText: (text) => opts.setEditorText?.(text),\n getEditorText: () => opts.getEditorText?.() ?? '',\n editor: editorDialog,\n addAutocompleteProvider: (factory) => {\n autocompleteProviderFactories.push(factory);\n const dispose = () => {\n const idx = autocompleteProviderFactories.indexOf(factory);\n if (idx >= 0) autocompleteProviderFactories.splice(idx, 1);\n };\n disposers.push(dispose);\n return dispose;\n },\n setEditorComponent: (factory) => opts.setEditorComponent?.(factory),\n getEditorComponent: () => opts.getEditorComponent?.(),\n get theme() {\n return opts.getThemeObject?.() ?? {};\n },\n getAllThemes: () => opts.getAllThemes?.() ?? [],\n getTheme: (name) => opts.getTheme?.(name),\n setTheme: (nextTheme) => opts.setTheme?.(nextTheme) ?? {\n success: false,\n error: 'Theme switching is not available in this TUI host.',\n },\n getToolsExpanded: () => opts.getToolsExpanded?.() ?? false,\n setToolsExpanded: (expanded) => opts.setToolsExpanded?.(expanded),\n };\n };\n\n const createActionContext = (extensionId: string): TuiSlashCommandContext => {\n let staleMessage: string | undefined;\n const assertActive = () => {\n if (staleMessage) {\n throw new Error(staleMessage);\n }\n };\n const markStale = () => {\n staleMessage ??= STALE_EXTENSION_CONTEXT_MESSAGE;\n };\n const guardedReplacement = async (\n work: () => Promise<TuiReplacementResult>,\n ): Promise<TuiReplacementResult> => {\n assertActive();\n const result = await work();\n if (!result.cancelled) {\n markStale();\n }\n return result;\n };\n\n const context = Object.defineProperties(\n {\n isProjectTrusted: () => {\n assertActive();\n return opts.isProjectTrusted?.() ?? false;\n },\n isIdle: () => {\n assertActive();\n return isTuiIdle(opts.getState());\n },\n hasPendingMessages: () => {\n assertActive();\n return hasPendingTuiMessages(opts.getState());\n },\n abort: () => {\n assertActive();\n return opts.abortActive?.();\n },\n shutdown: () => {\n assertActive();\n return opts.requestExit?.();\n },\n compact: (options?: TuiCompactOptions) => {\n assertActive();\n return opts.compactSession?.(options);\n },\n getSystemPrompt: () => {\n assertActive();\n return opts.getSystemPrompt?.() ?? '';\n },\n getSystemPromptOptions: () => {\n assertActive();\n return opts.getSystemPromptOptions?.() ?? {\n cwd: opts.cwd,\n sessionKey: opts.getState().currentSessionKey,\n model: getTuiModelInfo(opts.getState()),\n };\n },\n waitForIdle: () => {\n assertActive();\n return opts.waitForIdle?.() ?? Promise.resolve();\n },\n newSession: (options?: TuiNewSessionOptions) =>\n guardedReplacement(() => opts.newSession?.(options) ?? Promise.resolve({ cancelled: true })),\n fork: (entryId: string, options?: TuiForkOptions) =>\n guardedReplacement(() => opts.forkSession?.(entryId, options) ?? Promise.resolve({ cancelled: true })),\n navigateTree: (targetId: string, options?: TuiNavigateTreeOptions) => {\n assertActive();\n return opts.navigateTree?.(targetId, options) ?? Promise.resolve({ cancelled: true });\n },\n switchSession: (sessionPath: string, options?: TuiSwitchSessionOptions) =>\n guardedReplacement(() =>\n opts.switchSession?.(sessionPath, options) ?? Promise.resolve({ cancelled: true }),\n ),\n reload: async () => {\n assertActive();\n await (opts.reload?.() ?? Promise.resolve());\n markStale();\n },\n getModel: () => {\n assertActive();\n return getTuiModelInfo(opts.getState());\n },\n setModel: (modelRef: string) => {\n assertActive();\n return opts.setModel?.(modelRef);\n },\n getThinkingLevel: () => {\n assertActive();\n return getTuiThinkingLevel(opts.getState());\n },\n setThinkingLevel: (level: TuiThinkingLevel) => {\n assertActive();\n return opts.setThinkingLevel?.(level);\n },\n getReasoningLevel: () => {\n assertActive();\n return getTuiReasoningLevel(opts.getState());\n },\n setReasoningLevel: (level: TuiReasoningLevel) => {\n assertActive();\n return opts.setReasoningLevel?.(level);\n },\n getVerboseLevel: () => {\n assertActive();\n return getTuiVerboseLevel(opts.getState());\n },\n setVerboseLevel: (level: TuiVerboseLevel) => {\n assertActive();\n return opts.setVerboseLevel?.(level);\n },\n getCommands: () => {\n assertActive();\n return [\n ...opts.baseSlashCommands.map((command) => ({\n name: command.name,\n description: command.description,\n source: 'builtin' as const,\n })),\n ...slashCommands.map((command) => ({\n name: command.name,\n description: command.description,\n source: 'extension' as const,\n })),\n ];\n },\n getContextUsage: () => {\n assertActive();\n return getTuiContextUsage(opts.getState());\n },\n notify: (message: string, level?: TuiNotifyLevel) => {\n assertActive();\n return notifyInChatLog(opts.chatLog, opts.tui, message, level);\n },\n },\n {\n mode: {\n enumerable: true,\n get: () => {\n assertActive();\n return 'tui';\n },\n },\n hasUI: {\n enumerable: true,\n get: () => {\n assertActive();\n return true;\n },\n },\n signal: {\n enumerable: true,\n get: () => {\n assertActive();\n return opts.getActiveSignal?.();\n },\n },\n ui: {\n enumerable: true,\n get: () => {\n assertActive();\n return createActionUiContext(extensionId);\n },\n },\n sessionManager: {\n enumerable: true,\n get: () => {\n assertActive();\n return opts.getSessionManager?.() ??\n createEmptySessionManager(opts.cwd, opts.getState().currentSessionKey);\n },\n },\n modelRegistry: {\n enumerable: true,\n get: () => {\n assertActive();\n return modelRegistry;\n },\n },\n model: {\n enumerable: true,\n get: () => {\n assertActive();\n return getTuiModelInfo(opts.getState());\n },\n },\n cwd: {\n enumerable: true,\n get: () => {\n assertActive();\n return opts.cwd;\n },\n },\n sessionKey: {\n enumerable: true,\n get: () => {\n assertActive();\n return opts.getState().currentSessionKey;\n },\n },\n },\n ) as TuiSlashCommandContext;\n return context;\n };\n\n const runDialog = <T>(\n createDialog: (resolve: (value: T) => void, cancel: () => void) => Component & {\n setCountdownSeconds?: (seconds: number | undefined) => void;\n },\n dialogOpts: TuiDialogOptions | undefined,\n cancelValue: T,\n ): Promise<T> =>\n new Promise((resolve) => {\n if (dialogOpts?.signal?.aborted) {\n resolve(cancelValue);\n return;\n }\n\n let settled = false;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let interval: ReturnType<typeof setInterval> | undefined;\n const finish = (value: T) => {\n if (settled) return;\n settled = true;\n if (timeout) clearTimeout(timeout);\n if (interval) clearInterval(interval);\n dialogOpts?.signal?.removeEventListener('abort', onAbort);\n opts.closeOverlay();\n opts.onInvalidate();\n resolve(value);\n };\n const onAbort = () => finish(cancelValue);\n\n dialogOpts?.signal?.addEventListener('abort', onAbort, { once: true });\n const dialog = createDialog(finish, () => finish(cancelValue));\n if (dialogOpts?.timeout != null && dialogOpts.timeout > 0) {\n const deadline = Date.now() + dialogOpts.timeout;\n const updateCountdown = () => {\n const remainingMs = Math.max(0, deadline - Date.now());\n dialog.setCountdownSeconds?.(Math.ceil(remainingMs / 1000));\n opts.onInvalidate();\n };\n updateCountdown();\n interval = setInterval(updateCountdown, 250);\n timeout = setTimeout(() => finish(cancelValue), dialogOpts.timeout);\n }\n\n opts.openOverlay(dialog);\n opts.onInvalidate();\n });\n\n const selectDialog = (\n title: string,\n options: string[],\n dialogOpts?: TuiDialogOptions,\n ): Promise<string | undefined> => {\n if (options.length === 0) return Promise.resolve(undefined);\n return runDialog(\n (resolve, cancel) =>\n new ExtensionSelectDialog(title, options, {\n onSelect: resolve,\n onCancel: cancel,\n }, opts.keybindings),\n dialogOpts,\n undefined,\n );\n };\n\n const confirmDialog = async (\n title: string,\n message: string,\n dialogOpts?: TuiDialogOptions,\n ): Promise<boolean> => {\n const result = await selectDialog(`${title}\\n${message}`, ['Yes', 'No'], dialogOpts);\n return result === 'Yes';\n };\n\n const inputDialog = (\n title: string,\n placeholder?: string,\n dialogOpts?: TuiDialogOptions,\n ): Promise<string | undefined> =>\n runDialog(\n (resolve, cancel) =>\n new ExtensionInputDialog(title, placeholder, {\n onSubmit: resolve,\n onCancel: cancel,\n }, opts.keybindings),\n dialogOpts,\n undefined,\n );\n\n const editorDialog = (\n title: string,\n prefill?: string,\n ): Promise<string | undefined> =>\n runDialog(\n (resolve, cancel) =>\n new ExtensionEditorDialog(opts.tui, title, prefill, {\n onSubmit: resolve,\n onCancel: cancel,\n }, opts.keybindings),\n undefined,\n undefined,\n );\n\n const customOverlay = <T>(\n factory: TuiCustomFactory<T>,\n customOpts?: TuiCustomOptions,\n ): Promise<T> =>\n new Promise((resolve, reject) => {\n let closed = false;\n let component: TuiCustomComponent | undefined;\n let cleanup: (() => void) | undefined;\n const removeCleanup = () => {\n if (!cleanup) return;\n const idx = disposers.indexOf(cleanup);\n if (idx >= 0) disposers.splice(idx, 1);\n };\n const close = (result: T) => {\n if (closed) return;\n closed = true;\n removeCleanup();\n opts.closeOverlay();\n opts.onInvalidate();\n try {\n component?.dispose?.();\n } catch {\n // Ignore extension component cleanup failures.\n }\n resolve(result);\n };\n\n Promise.resolve()\n .then(() => invokeCustomFactory(factory, opts.tui, opts.keybindings, close))\n .then((nextComponent) => {\n if (closed) return;\n component = nextComponent;\n cleanup = () => {\n if (closed) return;\n closed = true;\n opts.closeOverlay();\n opts.onInvalidate();\n try {\n component?.dispose?.();\n } catch {\n // Ignore extension component cleanup failures.\n }\n };\n disposers.push(cleanup);\n const overlayOptions = resolveCustomOverlayOptions(nextComponent, customOpts);\n const handle = opts.openOverlay(nextComponent as Component, overlayOptions);\n if (handle) {\n customOpts?.onHandle?.(handle as TuiOverlayHandle);\n }\n opts.onInvalidate();\n })\n .catch((err: unknown) => {\n if (closed) return;\n closed = true;\n removeCleanup();\n try {\n component?.dispose?.();\n } catch {\n // Ignore extension component cleanup failures.\n }\n reject(err);\n });\n });\n\n const createHost = (extensionId: string) =>\n createTuiExtensionHost({\n extensionId,\n surface,\n getSessionKey: () => opts.getState().currentSessionKey,\n notify: (message, level) => notifyInChatLog(opts.chatLog, opts.tui, message, level),\n onTerminalInputAdded: (handler) => {\n const unregister = opts.addInputListener?.(handler);\n if (!unregister) return () => {};\n disposers.push(unregister);\n return () => {\n unregister();\n const idx = disposers.indexOf(unregister);\n if (idx >= 0) disposers.splice(idx, 1);\n };\n },\n showOverlay: opts.openOverlay,\n hideOverlay: opts.closeOverlay,\n custom: customOverlay,\n createWidgetComponent,\n setFooter: setCustomFooter,\n setHeader: setCustomHeader,\n setTitle: (title) => opts.setTitle?.(title),\n pasteToEditor: (text) => opts.pasteToEditor?.(text),\n setEditorText: (text) => opts.setEditorText?.(text),\n getEditorText: () => opts.getEditorText?.() ?? '',\n editor: editorDialog,\n setEditorComponent: (factory) => opts.setEditorComponent?.(factory),\n getEditorComponent: () => opts.getEditorComponent?.(),\n getThemeObject: () => opts.getThemeObject?.() ?? {},\n getAllThemes: () => opts.getAllThemes?.() ?? [],\n getTheme: (name) => opts.getTheme?.(name),\n setTheme: (nextTheme) => opts.setTheme?.(nextTheme) ?? {\n success: false,\n error: 'Theme switching is not available in this TUI host.',\n },\n getToolsExpanded: () => opts.getToolsExpanded?.() ?? false,\n setToolsExpanded: (expanded) => opts.setToolsExpanded?.(expanded),\n select: selectDialog,\n confirm: confirmDialog,\n input: inputDialog,\n onAutocompleteProviderAdded: (provider) => {\n autocompleteProviders.push(provider);\n const dispose = () => {\n const idx = autocompleteProviders.indexOf(provider);\n if (idx >= 0) autocompleteProviders.splice(idx, 1);\n };\n disposers.push(dispose);\n return dispose;\n },\n onAutocompleteProviderFactoryAdded: (factory) => {\n autocompleteProviderFactories.push(factory);\n const dispose = () => {\n const idx = autocompleteProviderFactories.indexOf(factory);\n if (idx >= 0) autocompleteProviderFactories.splice(idx, 1);\n };\n disposers.push(dispose);\n return dispose;\n },\n onMessageRendererAdded: (customType, renderer) => {\n const normalized = customType.trim();\n if (!normalized) return () => {};\n opts.chatLog.setCustomMessageRenderer(normalized, renderer);\n opts.onInvalidate();\n const dispose = () => {\n opts.chatLog.setCustomMessageRenderer(normalized, undefined);\n opts.onInvalidate();\n };\n disposers.push(dispose);\n return dispose;\n },\n onSlashCommandAdded: (name, description, handler) => {\n const normalized = name.replace(/^\\//, '').toLowerCase();\n const entry: TuiExtensionSlashCommand = {\n originalName: normalized,\n name: normalized,\n description,\n handler,\n getContext: () => createActionContext(extensionId),\n };\n slashCommands.push(entry);\n recomputeSlashCommandInvocationNames(slashCommands);\n const dispose = () => {\n const idx = slashCommands.indexOf(entry);\n if (idx >= 0) slashCommands.splice(idx, 1);\n recomputeSlashCommandInvocationNames(slashCommands);\n };\n disposers.push(dispose);\n return dispose;\n },\n onShortcutAdded: (key, description, handler) => {\n const entry: TuiExtensionShortcut = {\n key,\n description,\n handler,\n getContext: () => createActionContext(extensionId),\n };\n shortcuts.push(entry);\n const dispose = () => {\n const idx = shortcuts.indexOf(entry);\n if (idx >= 0) shortcuts.splice(idx, 1);\n };\n disposers.push(dispose);\n return dispose;\n },\n setHiddenThinkingLabel: (label) => {\n opts.chatLog.setHiddenThinkingLabel(label);\n },\n setWorkingMessage: (message) => {\n opts.setWorkingMessage?.(message);\n },\n setWorkingVisible: (visible) => {\n opts.setWorkingVisible?.(visible);\n },\n setWorkingIndicator: (options) => {\n opts.setWorkingIndicator?.(options);\n },\n onInvalidate: invalidate,\n });\n\n return {\n surface,\n slashCommands,\n shortcuts,\n autocompleteProvider,\n handleShortcut(data: string): boolean {\n for (const shortcut of shortcuts) {\n if (data !== shortcut.key && !matchesKey(data, shortcut.key as never)) {\n continue;\n }\n Promise.resolve(\n shortcut.handler(shortcut.getContext()),\n ).catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n notifyInChatLog(\n opts.chatLog,\n opts.tui,\n `Shortcut handler error: ${errorMessage}`,\n 'error',\n );\n });\n return true;\n }\n return false;\n },\n async activate() {\n const registrars = opts.registry?.getTuiRegistrations() ?? [];\n await invokeTuiExtensionRegistrars(registrars, createHost, (extensionId, errorMessage) => {\n notifyInChatLog(\n opts.chatLog,\n opts.tui,\n `[${extensionId}] TUI init failed: ${errorMessage}`,\n 'error',\n );\n });\n invalidate();\n },\n dispose() {\n for (const dispose of disposers) dispose();\n disposers.length = 0;\n clearTuiToolRenderers();\n disposeComponent(surface.customHeader);\n disposeComponent(surface.customFooter);\n surface.disposeWidgetComponents();\n surface.customHeader = undefined;\n surface.customFooter = undefined;\n surface.headerWidgets.clear();\n surface.footerWidgets.clear();\n surface.statusSlots.clear();\n opts.chatLog.setHiddenThinkingLabel();\n opts.setWorkingMessage?.();\n opts.setWorkingVisible?.(true);\n opts.setWorkingIndicator?.();\n opts.setEditorComponent?.(undefined);\n slashCommands.length = 0;\n shortcuts.length = 0;\n autocompleteProviders.length = 1;\n autocompleteProviderFactories.length = 0;\n invalidate();\n },\n };\n}\n\n/** Exported for tests */\nexport { suggestionsToAutocompleteItems };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.js","names":[],"sources":["../../../../src/tui/extension-host/runtime.ts"],"sourcesContent":["import {\n CombinedAutocompleteProvider,\n matchesKey,\n type Component,\n type AutocompleteItem,\n type AutocompleteProvider,\n type KeybindingsManager,\n type OverlayHandle,\n type OverlayOptions,\n type TUI,\n} from '@earendil-works/pi-tui';\n\nimport type { ExtensionRegistryImpl } from '../../extensions/loader.js';\nimport type {\n TuiAutocompleteProvider,\n TuiAutocompleteProviderFactory,\n TuiAutocompleteSuggestion,\n TuiActionUiContext,\n TuiCompactOptions,\n TuiCompactResult,\n TuiCustomComponent,\n TuiCustomFactory,\n TuiCustomOptions,\n TuiDialogOptions,\n TuiEditorFactory,\n TuiForkOptions,\n TuiFooterDataProvider,\n TuiFooterFactory,\n TuiHeaderFactory,\n TuiModelRegistry,\n TuiNotifyLevel,\n TuiOverlayHandle,\n TuiNavigateTreeOptions,\n TuiNewSessionOptions,\n TuiReasoningLevel,\n TuiReplacedSessionContext,\n TuiReplacementResult,\n TuiReadonlySessionManager,\n TuiSlashCommandContext,\n TuiShortcutHandler,\n TuiSlashCommandHandler,\n TuiSwitchSessionOptions,\n TuiSystemPromptOptions,\n TuiTerminalInputHandler,\n TuiSetThemeResult,\n TuiTheme,\n TuiThemeInfo,\n TuiThinkingLevel,\n TuiVerboseLevel,\n TuiWidgetFactory,\n TuiWorkingIndicatorOptions,\n} from '../../extensions/types/tui.js';\nimport type { ChatLog } from '../components/chat-log.js';\nimport {\n ExtensionEditorDialog,\n ExtensionInputDialog,\n ExtensionSelectDialog,\n} from '../components/extension-dialog.js';\nimport type { TuiHeader } from '../components/tui-header.js';\nimport type { TuiBottomBar } from '../components/tui-bottom-bar.js';\nimport type { TuiState } from '../tui-types.js';\nimport { theme } from '../theme.js';\nimport { getGitBranchCached } from '../tui-git-branch.js';\nimport { createTuiFileAutocompleteProvider } from '../tui-file-autocomplete.js';\nimport { createTuiExtensionHost, invokeTuiExtensionRegistrars } from './host.js';\nimport { ChainedAutocompleteProvider, WrappedAutocompleteProvider } from './autocomplete.js';\nimport {\n STALE_EXTENSION_CONTEXT_MESSAGE,\n boundedWidgetLines,\n createDefaultModelRegistry,\n createEmptySessionManager,\n getTuiContextUsage,\n getTuiModelInfo,\n getTuiReasoningLevel,\n getTuiThinkingLevel,\n getTuiVerboseLevel,\n hasPendingTuiMessages,\n invokeCustomFactory,\n isTuiIdle,\n notifyInChatLog,\n resolveCustomOverlayOptions,\n disposeComponent,\n} from './runtime-context.js';\nimport { clearTuiToolRenderers } from './tool-renderers.js';\nimport { TuiExtensionSurface } from './surface.js';\n\nexport interface TuiExtensionSlashCommand {\n originalName: string;\n name: string;\n description: string;\n handler: TuiSlashCommandHandler;\n getContext: () => TuiSlashCommandContext;\n}\n\nexport interface TuiExtensionShortcut {\n key: string;\n description: string;\n handler: TuiShortcutHandler;\n getContext: () => TuiSlashCommandContext;\n}\n\nexport interface TuiExtensionRuntime {\n surface: TuiExtensionSurface;\n slashCommands: TuiExtensionSlashCommand[];\n shortcuts: TuiExtensionShortcut[];\n autocompleteProvider: AutocompleteProvider;\n handleShortcut(data: string): boolean;\n activate(): Promise<void>;\n dispose(): void;\n}\n\nexport interface CreateTuiExtensionRuntimeOptions {\n registry?: ExtensionRegistryImpl;\n tui: TUI;\n chatLog: ChatLog;\n header: TuiHeader;\n bottomBar: TuiBottomBar;\n getState: () => TuiState;\n baseSlashCommands: Array<{ name: string; description: string }>;\n keybindings?: KeybindingsManager;\n addInputListener?: (handler: TuiTerminalInputHandler) => () => void;\n setTitle?: (title: string) => void;\n pasteToEditor?: (text: string) => void;\n setEditorText?: (text: string) => void;\n getEditorText?: () => string;\n setEditorComponent?: (factory: TuiEditorFactory | undefined) => void;\n getEditorComponent?: () => TuiEditorFactory | undefined;\n getThemeObject?: () => TuiTheme;\n getAllThemes?: () => TuiThemeInfo[];\n getTheme?: (name: string) => TuiTheme | undefined;\n setTheme?: (theme: string) => TuiSetThemeResult;\n getToolsExpanded?: () => boolean;\n setToolsExpanded?: (expanded: boolean) => void;\n getAvailableProviderCount?: () => number;\n getActiveSignal?: () => AbortSignal | undefined;\n isProjectTrusted?: () => boolean;\n getSessionManager?: () => TuiReadonlySessionManager;\n getModelRegistry?: () => TuiModelRegistry;\n getSystemPrompt?: () => string;\n getSystemPromptOptions?: () => TuiSystemPromptOptions;\n waitForIdle?: () => Promise<void>;\n newSession?: (options?: TuiNewSessionOptions) => Promise<TuiReplacementResult>;\n forkSession?: (entryId: string, options?: TuiForkOptions) => Promise<TuiReplacementResult>;\n navigateTree?: (targetId: string, options?: TuiNavigateTreeOptions) => Promise<TuiReplacementResult>;\n switchSession?: (sessionPath: string, options?: TuiSwitchSessionOptions) => Promise<TuiReplacementResult>;\n reload?: () => Promise<void>;\n sendUserMessage?: TuiReplacedSessionContext['sendUserMessage'];\n sendMessage?: TuiReplacedSessionContext['sendMessage'];\n searchWorkspaceFiles?: (\n sessionKey: string,\n query: string,\n options?: { limit?: number },\n ) => Promise<Array<{ name: string; path: string; isDirectory: boolean }>>;\n cwd: string;\n fdPath: string | null;\n openOverlay: (component: Component, options?: OverlayOptions) => OverlayHandle | void;\n closeOverlay: () => void;\n onInvalidate: () => void;\n abortActive?: () => void | Promise<void>;\n requestExit?: () => void;\n compactSession?: (options?: TuiCompactOptions) => void | Promise<void | TuiCompactResult>;\n setModel?: (modelRef: string) => void | Promise<void>;\n setThinkingLevel?: (level: TuiThinkingLevel) => void | Promise<void>;\n setReasoningLevel?: (level: TuiReasoningLevel) => void | Promise<void>;\n setVerboseLevel?: (level: TuiVerboseLevel) => void | Promise<void>;\n setWorkingMessage?: (message?: string) => void;\n setWorkingVisible?: (visible: boolean) => void;\n setWorkingIndicator?: (options?: TuiWorkingIndicatorOptions) => void;\n}\n\nfunction recomputeSlashCommandInvocationNames(commands: TuiExtensionSlashCommand[]) {\n const counts = new Map<string, number>();\n for (const command of commands) {\n counts.set(command.originalName, (counts.get(command.originalName) ?? 0) + 1);\n }\n\n const seen = new Map<string, number>();\n const taken = new Set<string>();\n for (const command of commands) {\n const occurrence = (seen.get(command.originalName) ?? 0) + 1;\n seen.set(command.originalName, occurrence);\n\n let name = (counts.get(command.originalName) ?? 0) > 1\n ? `${command.originalName}:${occurrence}`\n : command.originalName;\n if (taken.has(name)) {\n let suffix = occurrence;\n do {\n suffix += 1;\n name = `${command.originalName}:${suffix}`;\n } while (taken.has(name));\n }\n command.name = name;\n taken.add(name);\n }\n}\n\nfunction suggestionsToAutocompleteItems(\n suggestions: TuiAutocompleteSuggestion[],\n): AutocompleteItem[] {\n return suggestions.map((s) => ({\n value: `@${s.name}`,\n label: s.name,\n description: s.description,\n }));\n}\n\nexport function createTuiExtensionRuntime(\n opts: CreateTuiExtensionRuntimeOptions,\n): TuiExtensionRuntime {\n const surface = new TuiExtensionSurface();\n const slashCommands: TuiExtensionSlashCommand[] = [];\n const shortcuts: TuiExtensionShortcut[] = [];\n const autocompleteProviders: TuiAutocompleteProvider[] = [];\n if (opts.searchWorkspaceFiles) {\n autocompleteProviders.push(createTuiFileAutocompleteProvider(opts.searchWorkspaceFiles));\n }\n const baseAutocompleteProviderCount = autocompleteProviders.length;\n const autocompleteProviderFactories: TuiAutocompleteProviderFactory[] = [];\n const disposers: Array<() => void> = [];\n\n const baseProvider = new CombinedAutocompleteProvider(\n opts.baseSlashCommands.map((c) => ({ name: c.name, description: c.description })),\n opts.cwd,\n null,\n );\n\n const chainedProvider = new ChainedAutocompleteProvider(\n baseProvider,\n autocompleteProviders,\n slashCommands,\n new Set(opts.baseSlashCommands.map((command) => command.name)),\n () => opts.getState().currentSessionKey,\n opts.cwd,\n );\n const autocompleteProvider = new WrappedAutocompleteProvider(\n chainedProvider,\n autocompleteProviderFactories,\n );\n\n const invalidate = () => {\n opts.header.setCustomComponent?.(surface.customHeader);\n opts.header.setExtensionLines(surface.getHeaderLines());\n opts.header.setExtensionComponents?.(surface.getHeaderComponents());\n opts.bottomBar.setCustomComponent?.(surface.customFooter);\n opts.bottomBar.setExtensionLines(surface.getFooterLines());\n opts.bottomBar.setExtensionComponents?.(surface.getFooterComponents());\n opts.bottomBar.setExtensionStatusParts(surface.getStatusParts());\n opts.onInvalidate();\n };\n\n const createWidgetComponent = (factory: TuiWidgetFactory): Component & { dispose?(): void } =>\n factory(opts.tui, theme) as Component & { dispose?(): void };\n\n const footerDataProvider: TuiFooterDataProvider = {\n getGitBranch: () => getGitBranchCached(opts.cwd),\n getExtensionStatuses: () => surface.statusSlots,\n getAvailableProviderCount: () => opts.getAvailableProviderCount?.() ?? 0,\n onBranchChange: () => () => {},\n };\n const modelRegistry = opts.getModelRegistry?.() ?? createDefaultModelRegistry();\n\n const setCustomHeader = (factory: TuiHeaderFactory | undefined) => {\n disposeComponent(surface.customHeader);\n surface.customHeader = factory\n ? (factory(opts.tui, theme) as Component & { dispose?(): void })\n : undefined;\n invalidate();\n };\n\n const setCustomFooter = (factory: TuiFooterFactory | undefined) => {\n disposeComponent(surface.customFooter);\n surface.customFooter = factory\n ? (factory(opts.tui, theme, footerDataProvider) as Component & { dispose?(): void })\n : undefined;\n invalidate();\n };\n\n const clearWidgetKey = (fullKey: string) => {\n surface.headerWidgets.delete(fullKey);\n surface.footerWidgets.delete(fullKey);\n const headerComponent = surface.headerWidgetComponents.get(fullKey);\n const footerComponent = surface.footerWidgetComponents.get(fullKey);\n surface.headerWidgetComponents.delete(fullKey);\n surface.footerWidgetComponents.delete(fullKey);\n disposeComponent(headerComponent);\n disposeComponent(footerComponent);\n };\n\n const createActionUiContext = (extensionId: string): TuiActionUiContext => {\n const widgetKey = (key: string) => `${extensionId}:${key}`;\n return {\n select: selectDialog,\n confirm: confirmDialog,\n input: inputDialog,\n notify: (message, level) => notifyInChatLog(opts.chatLog, opts.tui, message, level),\n onTerminalInput: (handler) => {\n const unregister = opts.addInputListener?.(handler);\n if (!unregister) return () => {};\n disposers.push(unregister);\n return () => {\n unregister();\n const idx = disposers.indexOf(unregister);\n if (idx >= 0) disposers.splice(idx, 1);\n };\n },\n setStatus: (key, text) => {\n const fullKey = widgetKey(key);\n if (!text) {\n surface.statusSlots.delete(fullKey);\n } else {\n surface.statusSlots.set(fullKey, text);\n }\n invalidate();\n },\n setWorkingMessage: (message) => {\n opts.setWorkingMessage?.(message ?? undefined);\n invalidate();\n },\n setWorkingVisible: (visible) => {\n opts.setWorkingVisible?.(visible);\n invalidate();\n },\n setWorkingIndicator: (indicator) => {\n opts.setWorkingIndicator?.(indicator ?? undefined);\n invalidate();\n },\n setHiddenThinkingLabel: (label) => {\n opts.chatLog.setHiddenThinkingLabel(label ?? undefined);\n invalidate();\n },\n setWidget: (key, content, options) => {\n const fullKey = widgetKey(key);\n clearWidgetKey(fullKey);\n if (!content) {\n invalidate();\n return;\n }\n if (typeof content === 'function') {\n const target = options?.placement === 'belowEditor'\n ? surface.footerWidgetComponents\n : surface.headerWidgetComponents;\n target.set(fullKey, createWidgetComponent(content as TuiWidgetFactory));\n } else {\n const target = options?.placement === 'belowEditor'\n ? surface.footerWidgets\n : surface.headerWidgets;\n target.set(fullKey, boundedWidgetLines(content));\n }\n invalidate();\n },\n setFooter: setCustomFooter,\n setHeader: setCustomHeader,\n custom: customOverlay,\n setTitle: (title) => opts.setTitle?.(title),\n pasteToEditor: (text) => opts.pasteToEditor?.(text),\n setEditorText: (text) => opts.setEditorText?.(text),\n getEditorText: () => opts.getEditorText?.() ?? '',\n editor: editorDialog,\n addAutocompleteProvider: (factory) => {\n autocompleteProviderFactories.push(factory);\n const dispose = () => {\n const idx = autocompleteProviderFactories.indexOf(factory);\n if (idx >= 0) autocompleteProviderFactories.splice(idx, 1);\n };\n disposers.push(dispose);\n return dispose;\n },\n setEditorComponent: (factory) => opts.setEditorComponent?.(factory),\n getEditorComponent: () => opts.getEditorComponent?.(),\n get theme() {\n return opts.getThemeObject?.() ?? {};\n },\n getAllThemes: () => opts.getAllThemes?.() ?? [],\n getTheme: (name) => opts.getTheme?.(name),\n setTheme: (nextTheme) => opts.setTheme?.(nextTheme) ?? {\n success: false,\n error: 'Theme switching is not available in this TUI host.',\n },\n getToolsExpanded: () => opts.getToolsExpanded?.() ?? false,\n setToolsExpanded: (expanded) => opts.setToolsExpanded?.(expanded),\n };\n };\n\n const createActionContext = (extensionId: string): TuiSlashCommandContext => {\n let staleMessage: string | undefined;\n const assertActive = () => {\n if (staleMessage) {\n throw new Error(staleMessage);\n }\n };\n const markStale = () => {\n staleMessage ??= STALE_EXTENSION_CONTEXT_MESSAGE;\n };\n const guardedReplacement = async (\n work: () => Promise<TuiReplacementResult>,\n ): Promise<TuiReplacementResult> => {\n assertActive();\n const result = await work();\n if (!result.cancelled) {\n markStale();\n }\n return result;\n };\n\n const context = Object.defineProperties(\n {\n isProjectTrusted: () => {\n assertActive();\n return opts.isProjectTrusted?.() ?? false;\n },\n isIdle: () => {\n assertActive();\n return isTuiIdle(opts.getState());\n },\n hasPendingMessages: () => {\n assertActive();\n return hasPendingTuiMessages(opts.getState());\n },\n abort: () => {\n assertActive();\n return opts.abortActive?.();\n },\n shutdown: () => {\n assertActive();\n return opts.requestExit?.();\n },\n compact: (options?: TuiCompactOptions) => {\n assertActive();\n return opts.compactSession?.(options);\n },\n getSystemPrompt: () => {\n assertActive();\n return opts.getSystemPrompt?.() ?? '';\n },\n getSystemPromptOptions: () => {\n assertActive();\n return opts.getSystemPromptOptions?.() ?? {\n cwd: opts.cwd,\n sessionKey: opts.getState().currentSessionKey,\n model: getTuiModelInfo(opts.getState()),\n };\n },\n waitForIdle: () => {\n assertActive();\n return opts.waitForIdle?.() ?? Promise.resolve();\n },\n newSession: (options?: TuiNewSessionOptions) =>\n guardedReplacement(() => opts.newSession?.(options) ?? Promise.resolve({ cancelled: true })),\n fork: (entryId: string, options?: TuiForkOptions) =>\n guardedReplacement(() => opts.forkSession?.(entryId, options) ?? Promise.resolve({ cancelled: true })),\n navigateTree: (targetId: string, options?: TuiNavigateTreeOptions) => {\n assertActive();\n return opts.navigateTree?.(targetId, options) ?? Promise.resolve({ cancelled: true });\n },\n switchSession: (sessionPath: string, options?: TuiSwitchSessionOptions) =>\n guardedReplacement(() =>\n opts.switchSession?.(sessionPath, options) ?? Promise.resolve({ cancelled: true }),\n ),\n reload: async () => {\n assertActive();\n await (opts.reload?.() ?? Promise.resolve());\n markStale();\n },\n getModel: () => {\n assertActive();\n return getTuiModelInfo(opts.getState());\n },\n setModel: (modelRef: string) => {\n assertActive();\n return opts.setModel?.(modelRef);\n },\n getThinkingLevel: () => {\n assertActive();\n return getTuiThinkingLevel(opts.getState());\n },\n setThinkingLevel: (level: TuiThinkingLevel) => {\n assertActive();\n return opts.setThinkingLevel?.(level);\n },\n getReasoningLevel: () => {\n assertActive();\n return getTuiReasoningLevel(opts.getState());\n },\n setReasoningLevel: (level: TuiReasoningLevel) => {\n assertActive();\n return opts.setReasoningLevel?.(level);\n },\n getVerboseLevel: () => {\n assertActive();\n return getTuiVerboseLevel(opts.getState());\n },\n setVerboseLevel: (level: TuiVerboseLevel) => {\n assertActive();\n return opts.setVerboseLevel?.(level);\n },\n getCommands: () => {\n assertActive();\n return [\n ...opts.baseSlashCommands.map((command) => ({\n name: command.name,\n description: command.description,\n source: 'builtin' as const,\n })),\n ...slashCommands.map((command) => ({\n name: command.name,\n description: command.description,\n source: 'extension' as const,\n })),\n ];\n },\n getContextUsage: () => {\n assertActive();\n return getTuiContextUsage(opts.getState());\n },\n notify: (message: string, level?: TuiNotifyLevel) => {\n assertActive();\n return notifyInChatLog(opts.chatLog, opts.tui, message, level);\n },\n },\n {\n mode: {\n enumerable: true,\n get: () => {\n assertActive();\n return 'tui';\n },\n },\n hasUI: {\n enumerable: true,\n get: () => {\n assertActive();\n return true;\n },\n },\n signal: {\n enumerable: true,\n get: () => {\n assertActive();\n return opts.getActiveSignal?.();\n },\n },\n ui: {\n enumerable: true,\n get: () => {\n assertActive();\n return createActionUiContext(extensionId);\n },\n },\n sessionManager: {\n enumerable: true,\n get: () => {\n assertActive();\n return opts.getSessionManager?.() ??\n createEmptySessionManager(opts.cwd, opts.getState().currentSessionKey);\n },\n },\n modelRegistry: {\n enumerable: true,\n get: () => {\n assertActive();\n return modelRegistry;\n },\n },\n model: {\n enumerable: true,\n get: () => {\n assertActive();\n return getTuiModelInfo(opts.getState());\n },\n },\n cwd: {\n enumerable: true,\n get: () => {\n assertActive();\n return opts.cwd;\n },\n },\n sessionKey: {\n enumerable: true,\n get: () => {\n assertActive();\n return opts.getState().currentSessionKey;\n },\n },\n },\n ) as TuiSlashCommandContext;\n return context;\n };\n\n const runDialog = <T>(\n createDialog: (resolve: (value: T) => void, cancel: () => void) => Component & {\n setCountdownSeconds?: (seconds: number | undefined) => void;\n },\n dialogOpts: TuiDialogOptions | undefined,\n cancelValue: T,\n ): Promise<T> =>\n new Promise((resolve) => {\n if (dialogOpts?.signal?.aborted) {\n resolve(cancelValue);\n return;\n }\n\n let settled = false;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let interval: ReturnType<typeof setInterval> | undefined;\n const finish = (value: T) => {\n if (settled) return;\n settled = true;\n if (timeout) clearTimeout(timeout);\n if (interval) clearInterval(interval);\n dialogOpts?.signal?.removeEventListener('abort', onAbort);\n opts.closeOverlay();\n opts.onInvalidate();\n resolve(value);\n };\n const onAbort = () => finish(cancelValue);\n\n dialogOpts?.signal?.addEventListener('abort', onAbort, { once: true });\n const dialog = createDialog(finish, () => finish(cancelValue));\n if (dialogOpts?.timeout != null && dialogOpts.timeout > 0) {\n const deadline = Date.now() + dialogOpts.timeout;\n const updateCountdown = () => {\n const remainingMs = Math.max(0, deadline - Date.now());\n dialog.setCountdownSeconds?.(Math.ceil(remainingMs / 1000));\n opts.onInvalidate();\n };\n updateCountdown();\n interval = setInterval(updateCountdown, 250);\n timeout = setTimeout(() => finish(cancelValue), dialogOpts.timeout);\n }\n\n opts.openOverlay(dialog);\n opts.onInvalidate();\n });\n\n const selectDialog = (\n title: string,\n options: string[],\n dialogOpts?: TuiDialogOptions,\n ): Promise<string | undefined> => {\n if (options.length === 0) return Promise.resolve(undefined);\n return runDialog(\n (resolve, cancel) =>\n new ExtensionSelectDialog(title, options, {\n onSelect: resolve,\n onCancel: cancel,\n }, opts.keybindings),\n dialogOpts,\n undefined,\n );\n };\n\n const confirmDialog = async (\n title: string,\n message: string,\n dialogOpts?: TuiDialogOptions,\n ): Promise<boolean> => {\n const result = await selectDialog(`${title}\\n${message}`, ['Yes', 'No'], dialogOpts);\n return result === 'Yes';\n };\n\n const inputDialog = (\n title: string,\n placeholder?: string,\n dialogOpts?: TuiDialogOptions,\n ): Promise<string | undefined> =>\n runDialog(\n (resolve, cancel) =>\n new ExtensionInputDialog(title, placeholder, {\n onSubmit: resolve,\n onCancel: cancel,\n }, opts.keybindings),\n dialogOpts,\n undefined,\n );\n\n const editorDialog = (\n title: string,\n prefill?: string,\n ): Promise<string | undefined> =>\n runDialog(\n (resolve, cancel) =>\n new ExtensionEditorDialog(opts.tui, title, prefill, {\n onSubmit: resolve,\n onCancel: cancel,\n }, opts.keybindings),\n undefined,\n undefined,\n );\n\n const customOverlay = <T>(\n factory: TuiCustomFactory<T>,\n customOpts?: TuiCustomOptions,\n ): Promise<T> =>\n new Promise((resolve, reject) => {\n let closed = false;\n let component: TuiCustomComponent | undefined;\n let cleanup: (() => void) | undefined;\n const removeCleanup = () => {\n if (!cleanup) return;\n const idx = disposers.indexOf(cleanup);\n if (idx >= 0) disposers.splice(idx, 1);\n };\n const close = (result: T) => {\n if (closed) return;\n closed = true;\n removeCleanup();\n opts.closeOverlay();\n opts.onInvalidate();\n try {\n component?.dispose?.();\n } catch {\n // Ignore extension component cleanup failures.\n }\n resolve(result);\n };\n\n Promise.resolve()\n .then(() => invokeCustomFactory(factory, opts.tui, opts.keybindings, close))\n .then((nextComponent) => {\n if (closed) return;\n component = nextComponent;\n cleanup = () => {\n if (closed) return;\n closed = true;\n opts.closeOverlay();\n opts.onInvalidate();\n try {\n component?.dispose?.();\n } catch {\n // Ignore extension component cleanup failures.\n }\n };\n disposers.push(cleanup);\n const overlayOptions = resolveCustomOverlayOptions(nextComponent, customOpts);\n const handle = opts.openOverlay(nextComponent as Component, overlayOptions);\n if (handle) {\n customOpts?.onHandle?.(handle as TuiOverlayHandle);\n }\n opts.onInvalidate();\n })\n .catch((err: unknown) => {\n if (closed) return;\n closed = true;\n removeCleanup();\n try {\n component?.dispose?.();\n } catch {\n // Ignore extension component cleanup failures.\n }\n reject(err);\n });\n });\n\n const createHost = (extensionId: string) =>\n createTuiExtensionHost({\n extensionId,\n surface,\n getSessionKey: () => opts.getState().currentSessionKey,\n notify: (message, level) => notifyInChatLog(opts.chatLog, opts.tui, message, level),\n onTerminalInputAdded: (handler) => {\n const unregister = opts.addInputListener?.(handler);\n if (!unregister) return () => {};\n disposers.push(unregister);\n return () => {\n unregister();\n const idx = disposers.indexOf(unregister);\n if (idx >= 0) disposers.splice(idx, 1);\n };\n },\n showOverlay: opts.openOverlay,\n hideOverlay: opts.closeOverlay,\n custom: customOverlay,\n createWidgetComponent,\n setFooter: setCustomFooter,\n setHeader: setCustomHeader,\n setTitle: (title) => opts.setTitle?.(title),\n pasteToEditor: (text) => opts.pasteToEditor?.(text),\n setEditorText: (text) => opts.setEditorText?.(text),\n getEditorText: () => opts.getEditorText?.() ?? '',\n editor: editorDialog,\n setEditorComponent: (factory) => opts.setEditorComponent?.(factory),\n getEditorComponent: () => opts.getEditorComponent?.(),\n getThemeObject: () => opts.getThemeObject?.() ?? {},\n getAllThemes: () => opts.getAllThemes?.() ?? [],\n getTheme: (name) => opts.getTheme?.(name),\n setTheme: (nextTheme) => opts.setTheme?.(nextTheme) ?? {\n success: false,\n error: 'Theme switching is not available in this TUI host.',\n },\n getToolsExpanded: () => opts.getToolsExpanded?.() ?? false,\n setToolsExpanded: (expanded) => opts.setToolsExpanded?.(expanded),\n select: selectDialog,\n confirm: confirmDialog,\n input: inputDialog,\n onAutocompleteProviderAdded: (provider) => {\n autocompleteProviders.push(provider);\n const dispose = () => {\n const idx = autocompleteProviders.indexOf(provider);\n if (idx >= 0) autocompleteProviders.splice(idx, 1);\n };\n disposers.push(dispose);\n return dispose;\n },\n onAutocompleteProviderFactoryAdded: (factory) => {\n autocompleteProviderFactories.push(factory);\n const dispose = () => {\n const idx = autocompleteProviderFactories.indexOf(factory);\n if (idx >= 0) autocompleteProviderFactories.splice(idx, 1);\n };\n disposers.push(dispose);\n return dispose;\n },\n onMessageRendererAdded: (customType, renderer) => {\n const normalized = customType.trim();\n if (!normalized) return () => {};\n opts.chatLog.setCustomMessageRenderer(normalized, renderer);\n opts.onInvalidate();\n const dispose = () => {\n opts.chatLog.setCustomMessageRenderer(normalized, undefined);\n opts.onInvalidate();\n };\n disposers.push(dispose);\n return dispose;\n },\n onSlashCommandAdded: (name, description, handler) => {\n const normalized = name.replace(/^\\//, '').toLowerCase();\n const entry: TuiExtensionSlashCommand = {\n originalName: normalized,\n name: normalized,\n description,\n handler,\n getContext: () => createActionContext(extensionId),\n };\n slashCommands.push(entry);\n recomputeSlashCommandInvocationNames(slashCommands);\n const dispose = () => {\n const idx = slashCommands.indexOf(entry);\n if (idx >= 0) slashCommands.splice(idx, 1);\n recomputeSlashCommandInvocationNames(slashCommands);\n };\n disposers.push(dispose);\n return dispose;\n },\n onShortcutAdded: (key, description, handler) => {\n const entry: TuiExtensionShortcut = {\n key,\n description,\n handler,\n getContext: () => createActionContext(extensionId),\n };\n shortcuts.push(entry);\n const dispose = () => {\n const idx = shortcuts.indexOf(entry);\n if (idx >= 0) shortcuts.splice(idx, 1);\n };\n disposers.push(dispose);\n return dispose;\n },\n setHiddenThinkingLabel: (label) => {\n opts.chatLog.setHiddenThinkingLabel(label);\n },\n setWorkingMessage: (message) => {\n opts.setWorkingMessage?.(message);\n },\n setWorkingVisible: (visible) => {\n opts.setWorkingVisible?.(visible);\n },\n setWorkingIndicator: (options) => {\n opts.setWorkingIndicator?.(options);\n },\n onInvalidate: invalidate,\n });\n\n return {\n surface,\n slashCommands,\n shortcuts,\n autocompleteProvider,\n handleShortcut(data: string): boolean {\n for (const shortcut of shortcuts) {\n if (data !== shortcut.key && !matchesKey(data, shortcut.key as never)) {\n continue;\n }\n Promise.resolve(\n shortcut.handler(shortcut.getContext()),\n ).catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n notifyInChatLog(\n opts.chatLog,\n opts.tui,\n `Shortcut handler error: ${errorMessage}`,\n 'error',\n );\n });\n return true;\n }\n return false;\n },\n async activate() {\n const registrars = opts.registry?.getTuiRegistrations() ?? [];\n await invokeTuiExtensionRegistrars(registrars, createHost, (extensionId, errorMessage) => {\n notifyInChatLog(\n opts.chatLog,\n opts.tui,\n `[${extensionId}] TUI init failed: ${errorMessage}`,\n 'error',\n );\n });\n invalidate();\n },\n dispose() {\n for (const dispose of disposers) dispose();\n disposers.length = 0;\n clearTuiToolRenderers();\n disposeComponent(surface.customHeader);\n disposeComponent(surface.customFooter);\n surface.disposeWidgetComponents();\n surface.customHeader = undefined;\n surface.customFooter = undefined;\n surface.headerWidgets.clear();\n surface.footerWidgets.clear();\n surface.statusSlots.clear();\n opts.chatLog.setHiddenThinkingLabel();\n opts.setWorkingMessage?.();\n opts.setWorkingVisible?.(true);\n opts.setWorkingIndicator?.();\n opts.setEditorComponent?.(undefined);\n slashCommands.length = 0;\n shortcuts.length = 0;\n autocompleteProviders.length = baseAutocompleteProviderCount;\n autocompleteProviderFactories.length = 0;\n invalidate();\n },\n };\n}\n\n/** Exported for tests */\nexport { suggestionsToAutocompleteItems };\n"],"mappings":"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"}
|
|
@@ -104,6 +104,11 @@ export interface TuiStartupResources {
|
|
|
104
104
|
workflows: string[];
|
|
105
105
|
connectors: string[];
|
|
106
106
|
}
|
|
107
|
+
export interface TuiWorkspaceFileSearchEntry {
|
|
108
|
+
name: string;
|
|
109
|
+
path: string;
|
|
110
|
+
isDirectory: boolean;
|
|
111
|
+
}
|
|
107
112
|
/** Read-only transcript tree row for current-session navigation/inspection. */
|
|
108
113
|
export interface TuiTranscriptTreeEntry {
|
|
109
114
|
id: string;
|
|
@@ -173,6 +178,10 @@ export interface TuiBackend {
|
|
|
173
178
|
}>;
|
|
174
179
|
/** Load startup resources shown in `/start` and initial help. */
|
|
175
180
|
getStartupResources?(sessionKey: string): Promise<TuiStartupResources>;
|
|
181
|
+
/** Fuzzy search files in this session's effective workspace. */
|
|
182
|
+
searchWorkspaceFiles?(sessionKey: string, query: string, options?: {
|
|
183
|
+
limit?: number;
|
|
184
|
+
}): Promise<TuiWorkspaceFileSearchEntry[]>;
|
|
176
185
|
/** Load chat history for a session. */
|
|
177
186
|
loadHistory(opts: {
|
|
178
187
|
sessionKey: string;
|
|
@@ -125,7 +125,7 @@ function getSlashCommands(_isLocal, keybindings) {
|
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
name: "clear",
|
|
128
|
-
description: "
|
|
128
|
+
description: "Clear the TUI view without resetting the session"
|
|
129
129
|
},
|
|
130
130
|
{
|
|
131
131
|
name: "list",
|
|
@@ -165,7 +165,7 @@ function getSlashCommands(_isLocal, keybindings) {
|
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
name: "config",
|
|
168
|
-
description: "Show
|
|
168
|
+
description: "Show current configuration"
|
|
169
169
|
},
|
|
170
170
|
{
|
|
171
171
|
name: "context",
|
|
@@ -175,6 +175,10 @@ function getSlashCommands(_isLocal, keybindings) {
|
|
|
175
175
|
name: "btw",
|
|
176
176
|
description: "Side question without saving to session"
|
|
177
177
|
},
|
|
178
|
+
{
|
|
179
|
+
name: "aside",
|
|
180
|
+
description: "Alias for /btw"
|
|
181
|
+
},
|
|
178
182
|
{
|
|
179
183
|
name: "export",
|
|
180
184
|
description: "Export session (markdown/html/json)"
|
|
@@ -217,7 +221,7 @@ function getSlashCommands(_isLocal, keybindings) {
|
|
|
217
221
|
},
|
|
218
222
|
{
|
|
219
223
|
name: "workflow",
|
|
220
|
-
description: "Workflow subcommands: list, view <name
|
|
224
|
+
description: "Workflow subcommands: list, view <name>"
|
|
221
225
|
}
|
|
222
226
|
];
|
|
223
227
|
}
|
|
@@ -579,11 +583,11 @@ function createTuiCommandHandler(deps) {
|
|
|
579
583
|
return;
|
|
580
584
|
}
|
|
581
585
|
if (subcommand === "save") {
|
|
582
|
-
chatLog.addSystem("/workflow save is
|
|
586
|
+
chatLog.addSystem("/workflow save is not a TUI command. Save generated workflows through the workflow tool.");
|
|
583
587
|
tui.requestRender();
|
|
584
588
|
return;
|
|
585
589
|
}
|
|
586
|
-
chatLog.addSystem("Usage: /workflow list | /workflow view <name>
|
|
590
|
+
chatLog.addSystem("Usage: /workflow list | /workflow view <name>");
|
|
587
591
|
tui.requestRender();
|
|
588
592
|
return;
|
|
589
593
|
}
|
|
@@ -633,6 +637,11 @@ function createTuiCommandHandler(deps) {
|
|
|
633
637
|
tui.requestRender();
|
|
634
638
|
return;
|
|
635
639
|
}
|
|
640
|
+
if (!deps.switchModel) {
|
|
641
|
+
chatLog.addSystem("Model switching is not available in this mode.");
|
|
642
|
+
tui.requestRender();
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
636
645
|
Promise.resolve(deps.switchModel?.(modelRef)).then(() => {
|
|
637
646
|
tui.requestRender();
|
|
638
647
|
});
|
|
@@ -690,12 +699,22 @@ function createTuiCommandHandler(deps) {
|
|
|
690
699
|
});
|
|
691
700
|
return;
|
|
692
701
|
case "recover":
|
|
702
|
+
if (!deps.recoverStream) {
|
|
703
|
+
chatLog.addSystem("Stream recovery is not available in this mode.");
|
|
704
|
+
tui.requestRender();
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
693
707
|
Promise.resolve(deps.recoverStream?.()).catch((err) => {
|
|
694
708
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
695
709
|
chatLog.addSystem(`Recover failed: ${errorMessage}`);
|
|
696
710
|
}).finally(() => tui.requestRender());
|
|
697
711
|
return;
|
|
698
712
|
case "retry":
|
|
713
|
+
if (!deps.retryLastMessage) {
|
|
714
|
+
chatLog.addSystem("Retry is not available in this mode.");
|
|
715
|
+
tui.requestRender();
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
699
718
|
Promise.resolve(deps.retryLastMessage?.()).catch((err) => {
|
|
700
719
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
701
720
|
chatLog.addSystem(`Retry failed: ${errorMessage}`);
|
|
@@ -715,6 +734,11 @@ function createTuiCommandHandler(deps) {
|
|
|
715
734
|
tui.requestRender();
|
|
716
735
|
return;
|
|
717
736
|
case "copy":
|
|
737
|
+
if (!deps.copyLastAssistant) {
|
|
738
|
+
chatLog.addSystem("Copy is not available in this mode.");
|
|
739
|
+
tui.requestRender();
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
718
742
|
Promise.resolve(deps.copyLastAssistant?.()).then(() => {
|
|
719
743
|
tui.requestRender();
|
|
720
744
|
});
|
|
@@ -727,6 +751,11 @@ function createTuiCommandHandler(deps) {
|
|
|
727
751
|
tui.requestRender();
|
|
728
752
|
return;
|
|
729
753
|
}
|
|
754
|
+
if (!deps.renameCurrentSession) {
|
|
755
|
+
chatLog.addSystem("Session rename is not available in this mode.");
|
|
756
|
+
tui.requestRender();
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
730
759
|
Promise.resolve(deps.renameCurrentSession?.(name)).then(() => {
|
|
731
760
|
tui.requestRender();
|
|
732
761
|
});
|
|
@@ -734,15 +763,31 @@ function createTuiCommandHandler(deps) {
|
|
|
734
763
|
}
|
|
735
764
|
case "resume":
|
|
736
765
|
case "sessions":
|
|
766
|
+
if (!uiOverlays) {
|
|
767
|
+
chatLog.addSystem("Session picker is not available in this mode. Use /list to show sessions.");
|
|
768
|
+
tui.requestRender();
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
737
771
|
uiOverlays?.openSessionPicker();
|
|
738
772
|
return;
|
|
739
773
|
case "scoped-models":
|
|
740
774
|
case "scopedmodels":
|
|
775
|
+
if (!uiOverlays) {
|
|
776
|
+
chatLog.addSystem("Scoped model picker is not available in this mode.");
|
|
777
|
+
tui.requestRender();
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
741
780
|
uiOverlays?.openScopedModels();
|
|
742
781
|
return;
|
|
743
782
|
case "think": {
|
|
744
783
|
const level = normalizeThinkLevel(commandArgs);
|
|
745
784
|
if (!commandArgs.trim()) {
|
|
785
|
+
if (!uiOverlays) {
|
|
786
|
+
const current = state.sessionInfo.thinkingLevel?.trim();
|
|
787
|
+
chatLog.addSystem(current ? `Thinking level: ${current}` : "Usage: /think <off|low|medium|high>");
|
|
788
|
+
tui.requestRender();
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
746
791
|
uiOverlays?.openThinkingSelector();
|
|
747
792
|
return;
|
|
748
793
|
}
|
|
@@ -751,6 +796,11 @@ function createTuiCommandHandler(deps) {
|
|
|
751
796
|
tui.requestRender();
|
|
752
797
|
return;
|
|
753
798
|
}
|
|
799
|
+
if (!deps.setThinkingLevel) {
|
|
800
|
+
chatLog.addSystem("Thinking level changes are not available in this mode.");
|
|
801
|
+
tui.requestRender();
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
754
804
|
Promise.resolve(deps.setThinkingLevel?.(level)).then(() => {
|
|
755
805
|
tui.requestRender();
|
|
756
806
|
});
|
|
@@ -769,6 +819,11 @@ function createTuiCommandHandler(deps) {
|
|
|
769
819
|
tui.requestRender();
|
|
770
820
|
return;
|
|
771
821
|
}
|
|
822
|
+
if (!deps.setReasoningLevel) {
|
|
823
|
+
chatLog.addSystem("Reasoning visibility changes are not available in this mode.");
|
|
824
|
+
tui.requestRender();
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
772
827
|
Promise.resolve(deps.setReasoningLevel?.(level)).then(() => {
|
|
773
828
|
tui.requestRender();
|
|
774
829
|
});
|
|
@@ -782,17 +837,32 @@ function createTuiCommandHandler(deps) {
|
|
|
782
837
|
tui.requestRender();
|
|
783
838
|
return;
|
|
784
839
|
}
|
|
840
|
+
if (!deps.setVerboseLevel) {
|
|
841
|
+
chatLog.addSystem("Verbose mode changes are not available in this mode.");
|
|
842
|
+
tui.requestRender();
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
785
845
|
Promise.resolve(deps.setVerboseLevel?.(level)).then(() => {
|
|
786
846
|
tui.requestRender();
|
|
787
847
|
});
|
|
788
848
|
return;
|
|
789
849
|
}
|
|
790
850
|
case "settings":
|
|
851
|
+
if (!uiOverlays) {
|
|
852
|
+
chatLog.addSystem("Settings are not available in this mode.");
|
|
853
|
+
tui.requestRender();
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
791
856
|
uiOverlays?.openSettings();
|
|
792
857
|
return;
|
|
793
858
|
case "reload":
|
|
794
859
|
case "reload-keybindings":
|
|
795
860
|
case "reload-keybind":
|
|
861
|
+
if (!uiOverlays) {
|
|
862
|
+
chatLog.addSystem("Reload is not available in this mode.");
|
|
863
|
+
tui.requestRender();
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
796
866
|
Promise.resolve(uiOverlays?.reloadKeybindings()).then(() => {
|
|
797
867
|
chatLog.addSystem("Reloaded keybindings, TUI settings, theme, and extension UI.");
|
|
798
868
|
tui.requestRender();
|
|
@@ -803,6 +873,11 @@ function createTuiCommandHandler(deps) {
|
|
|
803
873
|
});
|
|
804
874
|
return;
|
|
805
875
|
case "compact":
|
|
876
|
+
if (!deps.runCompaction) {
|
|
877
|
+
chatLog.addSystem("Compaction is not available in this mode.");
|
|
878
|
+
tui.requestRender();
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
806
881
|
deps.runCompaction?.(commandArgs.trim() || void 0);
|
|
807
882
|
return;
|
|
808
883
|
default: break;
|
|
@@ -849,7 +924,11 @@ function createTuiCommandHandler(deps) {
|
|
|
849
924
|
runReset();
|
|
850
925
|
return;
|
|
851
926
|
case "clear":
|
|
852
|
-
|
|
927
|
+
chatLog.clearAll();
|
|
928
|
+
state.messageFollowUpQueue.length = 0;
|
|
929
|
+
state.steeringQueue.length = 0;
|
|
930
|
+
chatLog.addSystem("TUI view cleared. Session transcript was not reset.");
|
|
931
|
+
tui.requestRender();
|
|
853
932
|
return;
|
|
854
933
|
default: break;
|
|
855
934
|
}
|