@xopcai/xopc 0.0.106 → 0.0.108
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/manifest.json +1 -1
- package/dist/extensions/dashscope/xopc.extension.json +7 -2
- package/dist/extensions/fal/xopc.extension.json +7 -2
- package/dist/extensions/feishu/src/adapters/gateway-setup.js +22 -26
- package/dist/extensions/feishu/src/adapters/gateway-setup.js.map +1 -1
- package/dist/extensions/feishu/xopc.extension.json +458 -26
- package/dist/extensions/google/xopc.extension.json +7 -2
- package/dist/extensions/minimax/xopc.extension.json +8 -2
- package/dist/extensions/openai/xopc.extension.json +7 -2
- package/dist/extensions/telegram/xopc.extension.json +10 -2
- package/dist/extensions/weixin/xopc.extension.json +57 -14
- package/dist/gateway/static/root/apple-touch-icon.png +0 -0
- package/dist/gateway/static/root/assets/agents-56kCGHdV.js +78 -0
- package/dist/gateway/static/root/assets/apps-page-Dd88J47r.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-Ckyvnvml.js +1 -0
- package/dist/gateway/static/root/assets/cron-page-DKo2ZdRA.js +1 -0
- package/dist/gateway/static/root/assets/{dist-OM9qGfm5.js → dist-dmxWdtPG.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-D-WHrr_w.js → extension-debug-page-iGpG-vpp.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CCgjSoKn.js → extension-page-I7-3uHiD.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BJH5a-Gn.js → extension-settings-page-BisnHG7r.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-CkvRO30i.js → fetch-CFdKBnE6.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-BkKyRDrF.js → gateway-startup-retry-DdngdObI.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-CVyP6pFj.js → heartbeat-config-api-tbWAFPN8.js} +1 -1
- package/dist/gateway/static/root/assets/index-DI5_GsZt.css +1 -0
- package/dist/gateway/static/root/assets/index-slwUkhxH.js +4845 -0
- package/dist/gateway/static/root/assets/{logs-page-R6Vv_Ja6.js → logs-page-CCZiXrWu.js} +2 -2
- package/dist/gateway/static/root/assets/{note-detail-page-BUDarLhh.js → note-detail-page-BYbw2GLl.js} +4 -4
- package/dist/gateway/static/root/assets/{note-time-Cc2-T21g.js → note-time-Cya72Lte.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-DrAO7VRK.js +1 -0
- package/dist/gateway/static/root/assets/{schema-form-CrlOmEZt.js → schema-form-a6UJCK55.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DNU3Ymvz.js +1 -0
- package/dist/gateway/static/root/assets/{settings-advanced-gate-BBAQxxew.js → settings-advanced-gate-CyEJYTbw.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-DjPD-ErC.js → settings-form-section-DpHo2ecA.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-YRwe4q56.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BjvPht3V.js → share-preview-page-B7rf4QB4.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-we1NAt7u.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-DYgVdRB4.js → theme-store-BZozwAeK.js} +1 -1
- package/dist/gateway/static/root/assets/url-DQRqHuL-.js +3 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-Btagks_B.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-page.utils-D4sqR0yX.js → workflow-page.utils-DvzJKs6W.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-BgOAgCOG.js +18 -0
- package/dist/gateway/static/root/favicon-16.png +0 -0
- package/dist/gateway/static/root/favicon-32.png +0 -0
- package/dist/gateway/static/root/favicon.ico +0 -0
- package/dist/gateway/static/root/favicon.svg +18 -0
- package/dist/gateway/static/root/index.html +11 -10
- package/dist/package.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +4 -0
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +4 -2
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
- package/dist/src/agent/starter-agents.d.ts +19 -0
- package/dist/src/agent/starter-agents.js +190 -0
- package/dist/src/agent/starter-agents.js.map +1 -0
- package/dist/src/agent/workflow/runtime.js +49 -15
- package/dist/src/agent/workflow/runtime.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +11 -0
- package/dist/src/channels/catalog/channel-catalog-service.js +13 -0
- package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -1
- package/dist/src/channels/plugins/types.adapters.d.ts +2 -0
- package/dist/src/cli/commands/extension-create.d.ts +2 -0
- package/dist/src/cli/commands/extension-create.js +165 -0
- package/dist/src/cli/commands/extension-create.js.map +1 -0
- package/dist/src/cli/commands/extension-dev.js +0 -2
- package/dist/src/cli/commands/extension-dev.js.map +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +104 -80
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
- package/dist/src/cli/commands/extension-pack.d.ts +13 -0
- package/dist/src/cli/commands/extension-pack.js +159 -91
- package/dist/src/cli/commands/extension-pack.js.map +1 -1
- package/dist/src/cli/commands/extension.d.ts +2 -0
- package/dist/src/cli/commands/extension.js +375 -3
- package/dist/src/cli/commands/extension.js.map +1 -1
- package/dist/src/cli/commands/gateway/run-foreground.js +1 -2
- package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +0 -2
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/setup.js +0 -2
- package/dist/src/cli/commands/setup.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +9 -6
- package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
- package/dist/src/config/paths.d.ts +2 -2
- package/dist/src/config/paths.js +10 -6
- package/dist/src/config/paths.js.map +1 -1
- package/dist/src/config/schema.d.ts +2 -0
- package/dist/src/config/schema.js +3 -1
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/extensions/api.d.ts +4 -2
- package/dist/src/extensions/api.js +31 -12
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -0
- package/dist/src/extensions/discover-extensions.js.map +1 -1
- package/dist/src/extensions/install.d.ts +1 -0
- package/dist/src/extensions/install.js +51 -8
- package/dist/src/extensions/install.js.map +1 -1
- package/dist/src/extensions/loader.d.ts +0 -4
- package/dist/src/extensions/loader.js +54 -87
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/lockfile.d.ts +9 -1
- package/dist/src/extensions/lockfile.js.map +1 -1
- package/dist/src/extensions/normalize-manifest.js +20 -4
- package/dist/src/extensions/normalize-manifest.js.map +1 -1
- package/dist/src/extensions/package-contract.d.ts +12 -0
- package/dist/src/extensions/package-contract.js +59 -0
- package/dist/src/extensions/package-contract.js.map +1 -0
- package/dist/src/extensions/sdk/core.d.ts +1 -1
- package/dist/src/extensions/sdk/index.d.ts +1 -1
- package/dist/src/extensions/sdk/index.js.map +1 -1
- package/dist/src/extensions/types/manifest.d.ts +15 -0
- package/dist/src/gateway/agents-admin.d.ts +0 -8
- package/dist/src/gateway/agents-admin.js +1 -26
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js +1 -55
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/channels.js +10 -1
- package/dist/src/gateway/hono/routes/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +130 -0
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/service.d.ts +2 -0
- package/dist/src/gateway/service.js +44 -0
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/notes/agent-context.d.ts +12 -4
- package/dist/src/notes/agent-context.js.map +1 -1
- package/dist/src/tui/backends/embedded-backend.js +0 -7
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.js +0 -7
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/tui-backend.d.ts +0 -1
- package/dist/src/tui/tui-commands.js +1 -1
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-picker-overlay.js +1 -1
- package/dist/src/tui/tui-picker-overlay.js.map +1 -1
- package/dist/src/workflows/domain/definition-utils.d.ts +1 -0
- package/dist/src/workflows/domain/definition-utils.js +32 -2
- package/dist/src/workflows/domain/definition-utils.js.map +1 -1
- package/dist/src/workflows/domain/definition.d.ts +2 -0
- package/dist/src/workflows/domain/event.d.ts +2 -1
- package/dist/src/workflows/domain/index.d.ts +1 -0
- package/dist/src/workflows/domain/index.js +3 -2
- package/dist/src/workflows/domain/run.d.ts +27 -1
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/domain/schema-validation.d.ts +8 -0
- package/dist/src/workflows/domain/schema-validation.js +28 -0
- package/dist/src/workflows/domain/schema-validation.js.map +1 -0
- package/dist/src/workflows/draft/index.d.ts +3 -0
- package/dist/src/workflows/draft/index.js +3 -0
- package/dist/src/workflows/draft/workflow-draft-prompt.d.ts +23 -0
- package/dist/src/workflows/draft/workflow-draft-prompt.js +98 -0
- package/dist/src/workflows/draft/workflow-draft-prompt.js.map +1 -0
- package/dist/src/workflows/draft/workflow-draft-service.d.ts +12 -0
- package/dist/src/workflows/draft/workflow-draft-service.js +131 -0
- package/dist/src/workflows/draft/workflow-draft-service.js.map +1 -0
- package/dist/src/workflows/draft/workflow-draft-validator.d.ts +4 -0
- package/dist/src/workflows/draft/workflow-draft-validator.js +133 -0
- package/dist/src/workflows/draft/workflow-draft-validator.js.map +1 -0
- package/dist/src/workflows/draft/workflow-draft.types.d.ts +44 -0
- package/dist/src/workflows/draft/workflow-draft.types.js +1 -0
- package/dist/src/workflows/engine/projector.js +1 -0
- package/dist/src/workflows/engine/projector.js.map +1 -1
- package/dist/src/workflows/engine/workflow-engine.d.ts +18 -0
- package/dist/src/workflows/engine/workflow-engine.js +320 -11
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/dist/src/workflows/index.js +4 -3
- package/dist/src/workflows/service/workflow-run-service.d.ts +14 -3
- package/dist/src/workflows/service/workflow-run-service.js +227 -6
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +7 -2
- package/package.json +4 -2
- package/dist/gateway/static/root/assets/agents-3eP0vqFO.js +0 -396
- package/dist/gateway/static/root/assets/apps-page-CZ2ZKrko.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BbETa93K.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-DCtUkHMu.js +0 -1
- package/dist/gateway/static/root/assets/index-BPYKW7FB.css +0 -1
- package/dist/gateway/static/root/assets/index-CEZxETzw.js +0 -4845
- package/dist/gateway/static/root/assets/notes-page-EAHl16bq.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-Ce_xuuSB.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-KhQ9QgH0.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-C0laq7l1.js +0 -2
- package/dist/gateway/static/root/assets/url-DPEStU4M.js +0 -3
- package/dist/gateway/static/root/assets/voice-api-key-field-DeGckWkl.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-DFjM95g5.js +0 -27
- package/dist/src/agent/builtin-agent-ids.d.ts +0 -2
- package/dist/src/agent/builtin-agent-ids.js +0 -17
- package/dist/src/agent/builtin-agent-ids.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui-commands.js","names":["listAllAuthProfiles"],"sources":["../../../src/tui/tui-commands.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { KeybindingsManager, TUI } from '@earendil-works/pi-tui';\n\nimport type {\n TuiCompactionResult,\n TuiModelChoice,\n TuiShareRequest,\n TuiSessionStats,\n TuiSessionItem,\n TuiStartupResources,\n TuiTranscriptTreeEntry,\n TuiAgentInfo,\n} from './tui-backend.js';\nimport type { ChatLog } from './components/chat-log.js';\nimport {\n formatKeyIds,\n formatXopcTuiHotkeys,\n type TuiHotkeyExtensionShortcut,\n} from './format-tui-hotkeys.js';\nimport { getTuiKeybindingsPath } from './tui-keybindings-file.js';\nimport type { TuiState } from './tui-types.js';\nimport { createWorkflowCatalog } from '../agent/workflow/catalog.js';\nimport {\n isValidAgentId,\n normalizeAgentId,\n parseAgentSessionKey,\n} from '../routing/agent-session-key.js';\nimport {\n normalizeReasoningLevel,\n normalizeThinkLevel,\n normalizeVerboseLevel,\n type ReasoningLevel,\n type ThinkLevel,\n type VerboseLevel,\n} from '../agent/transcript/thinking-types.js';\nimport {\n getAuthStorePath,\n listAllProfiles as listAllAuthProfiles,\n listProfilesForProvider,\n removeAuthProfile,\n type AuthProfileEntry,\n} from '../auth/profiles/index.js';\nimport { loadConfig, resolveConfigPath } from '../config/index.js';\nimport type { TuiSlashCommandContext, TuiSlashCommandHandler } from '../extensions/types/tui.js';\nimport { provenanceTracker } from '../extensions/security.js';\nimport type { ProjectTrustStoreEntry } from '../project-trust/trust-store.js';\nimport { providerSupportsOAuth } from '../providers/index.js';\n\nimport { rewriteUnknownSlashAsWorkflow } from './tui-workflow-slash.js';\nimport { formatTuiStartupText } from './tui-startup-text.js';\n\ninterface SlashCommandDef {\n name: string;\n originalName?: string;\n description: string;\n}\n\nexport type TuiExtensionSlashCommandEntry = SlashCommandDef & {\n handler: TuiSlashCommandHandler;\n getContext?: () => TuiSlashCommandContext;\n};\n\nfunction keyLabel(\n keybindings: KeybindingsManager | undefined,\n id: Parameters<KeybindingsManager['getKeys']>[0],\n fallback: string,\n): string {\n return keybindings ? formatKeyIds(keybindings, id, { capitalize: true }) : fallback;\n}\n\nexport function getSlashCommands(\n _isLocal: boolean,\n keybindings?: KeybindingsManager,\n): SlashCommandDef[] {\n const abortKey = keyLabel(keybindings, 'app.interrupt', 'Escape');\n const toolsKey = keyLabel(keybindings, 'app.tools.expand', 'Ctrl+O');\n const thinkingKey = keyLabel(keybindings, 'app.thinking.toggle', 'Ctrl+T');\n const sessionKey = keyLabel(keybindings, 'app.session.resume', 'Ctrl+Shift+P');\n const modelCycleKey = keyLabel(keybindings, 'app.model.cycleForward', 'Ctrl+P');\n return [\n { name: 'help', description: 'Show available commands' },\n { name: 'abort', description: `Abort active run (or press ${abortKey})` },\n { name: 'recover', description: 'Reload history and reattach to a stalled run' },\n { name: 'retry', description: 'Abort current run if needed and resend the last user message' },\n { name: 'tools', description: `Toggle tool output expanded/collapsed (or ${toolsKey})` },\n { name: 'thinking', description: `Toggle thinking display (or ${thinkingKey})` },\n { name: 'copy', description: 'Copy last assistant message to clipboard' },\n { name: 'exit', description: 'Exit the TUI' },\n { name: 'quit', description: 'Quit the TUI' },\n { name: 'model', description: 'Open model picker (optional search text)' },\n { name: 'models', description: 'List available models' },\n { name: 'switch', description: 'Switch model — copy `provider/model` from /models' },\n { name: 'login', description: 'Login to an OAuth provider' },\n { name: 'logout', description: 'Remove stored provider auth profiles' },\n { name: 'usage', description: 'Show token usage statistics' },\n { name: 'session', description: 'Show current session info' },\n { name: 'agent', description: 'Show or switch agent for this TUI session' },\n { name: 'agents', description: 'List available agents' },\n { name: 'new', description: 'Start a new isolated TUI session (tui-{uuid})' },\n { name: 'fork', description: 'Fork current session transcript into a new session' },\n { name: 'clone', description: 'Duplicate current session transcript into a new session' },\n { name: 'trust', description: 'Manage project trust and show extension security policy' },\n { name: 'name', description: 'Show or set current session display name' },\n { name: 'reset', description: 'Reset current session transcript and reload history' },\n { name: 'clear', description: 'Alias for /reset' },\n { name: 'list', description: 'List sessions' },\n { name: 'resume', description: `Open session picker (or ${sessionKey})` },\n { name: 'tree', description: 'Show grouped session tree' },\n { name: 'scoped-models', description: `Choose models for ${modelCycleKey} cycling` },\n { name: 'compact', description: 'Compact session history (local API)' },\n { name: 'think', description: 'Set thinking level (e.g. /think high)' },\n { name: 'reasoning', description: 'Set reasoning visibility (e.g. /reasoning stream)' },\n { name: 'verbose', description: 'Toggle verbose mode' },\n { name: 'status', description: 'Show agent status' },\n { name: 'config', description: 'Show or update configuration' },\n { name: 'context', description: 'Show context budget' },\n { name: 'btw', description: 'Side question without saving to session' },\n { name: 'export', description: 'Export session (markdown/html/json)' },\n { name: 'import', description: 'Import an xopc JSON session export' },\n { name: 'share', description: 'Create a share link for a workspace file/folder/site' },\n { name: 'settings', description: 'Open TUI settings overlay' },\n { name: 'reload', description: 'Reload keybindings, TUI settings, theme, and extension UI' },\n { name: 'reload-keybindings', description: `Reload ${getTuiKeybindingsPath()}` },\n { name: 'start', description: 'Show welcome message' },\n { name: 'hotkeys', description: 'Show resolved keyboard shortcuts (pi-style)' },\n { name: 'changelog', description: 'Show version history' },\n { name: 'workflows', description: 'List saved workflows (built-in + ~/.xopc/workflows/)' },\n { name: 'workflow', description: 'Workflow subcommands: list, view <name>, save <name>' },\n ];\n}\n\nfunction formatExtraSlashCommands(commands: SlashCommandDef[]): string[] {\n const seen = new Set(getSlashCommands(true).map((command) => command.name));\n const lines: string[] = [];\n for (const command of commands) {\n const name = command.name.replace(/^\\//, '').trim().toLowerCase();\n const originalName = command.originalName?.replace(/^\\//, '').trim().toLowerCase();\n if (!name || seen.has(name) || (originalName && seen.has(originalName))) continue;\n seen.add(name);\n lines.push(` /${name} — ${command.description}`);\n }\n return lines;\n}\n\nexport function formatTuiHelpText(\n isLocal: boolean,\n keybindings?: KeybindingsManager,\n extraSlashCommands: SlashCommandDef[] = [],\n): string {\n const commands = getSlashCommands(isLocal, keybindings);\n const interrupt = keyLabel(keybindings, 'app.interrupt', 'Escape');\n const thinkCycle = keyLabel(keybindings, 'app.thinking.cycle', 'Shift+Tab');\n const modelNext = keyLabel(keybindings, 'app.model.cycleForward', 'Ctrl+P');\n const modelPrev = keyLabel(keybindings, 'app.model.cycleBackward', 'Shift+Ctrl+P');\n const modelPicker = keyLabel(keybindings, 'app.model.select', 'Ctrl+L');\n const sessionPicker = keyLabel(keybindings, 'app.session.resume', 'Ctrl+Shift+P');\n const sessionTree = keyLabel(keybindings, 'app.session.tree', '(not bound)');\n const sessionFork = keyLabel(keybindings, 'app.session.fork', '(not bound)');\n const toolExpand = keyLabel(keybindings, 'app.tools.expand', 'Ctrl+O');\n const thinkingToggle = keyLabel(keybindings, 'app.thinking.toggle', 'Ctrl+T');\n const editorExternal = keyLabel(keybindings, 'app.editor.external', 'Ctrl+G');\n const suspend = keyLabel(keybindings, 'app.suspend', 'Ctrl+Z');\n const followUp = keyLabel(keybindings, 'app.message.followUp', 'Alt+Enter');\n const dequeue = keyLabel(keybindings, 'app.message.dequeue', 'Alt+Up');\n const pasteImage = keyLabel(keybindings, 'app.clipboard.pasteImage', 'Ctrl+V / Alt+V');\n const clearInput = keyLabel(keybindings, 'app.clear', 'Ctrl+C');\n const exit = keyLabel(keybindings, 'app.exit', 'Ctrl+D');\n const lines = ['Available commands:'];\n for (const c of commands) {\n lines.push(` /${c.name} — ${c.description}`);\n }\n const extraCommandLines = formatExtraSlashCommands(extraSlashCommands);\n if (extraCommandLines.length > 0) {\n lines.push('', 'Extension commands:');\n lines.push(...extraCommandLines);\n }\n lines.push('', 'Keyboard shortcuts (defaults align with pi coding-agent where noted):');\n lines.push(` ${interrupt} — Abort active run`);\n lines.push(` ${thinkCycle} — Cycle /think level`);\n lines.push(` ${modelNext} / ${modelPrev} — Next / previous model (/switch)`);\n lines.push(` ${modelPicker} — Model picker`);\n lines.push(` ${sessionPicker} — Session picker (rename/delete)`);\n lines.push(` ${sessionTree} — Session tree`);\n lines.push(` ${sessionFork} — Fork current session`);\n lines.push(` /scoped-models — Limit ${modelNext} model cycle set`);\n lines.push(` ${toolExpand} — Toggle tool output`);\n lines.push(` ${thinkingToggle} — Toggle thinking block display`);\n lines.push(` ${editorExternal} — Edit draft in $EDITOR`);\n lines.push(` ${suspend} — Suspend to shell (Unix)`);\n lines.push(` ${followUp} — Queue follow-up while busy (sends when this reply finishes)`);\n lines.push(` ${dequeue} — Restore queued messages to editor`);\n lines.push(' Enter (while busy) — Steer: inject at next tool boundary');\n lines.push(` ${pasteImage} — Paste image from clipboard`);\n lines.push(' /settings — Theme, thinking display, terminal progress, …');\n lines.push(` ${getTuiKeybindingsPath()} — Custom shortcuts (use /reload)`);\n lines.push(` ${clearInput} — Clear input; repeat within ~0.5s to exit when empty`);\n lines.push(` ${exit} — Exit when input empty`);\n lines.push(' !cmd — Local shell (gated; runs on this machine)');\n lines.push('', 'Use /hotkeys for the resolved binding list from the active keymap.');\n return lines.join('\\n');\n}\n\nexport function formatTuiStartText(\n state: TuiState,\n isLocal: boolean,\n keybindings?: KeybindingsManager,\n resources?: TuiStartupResources,\n): string {\n return formatTuiStartupText({\n state,\n isLocal,\n keybindings,\n resources,\n expanded: true,\n });\n}\n\nimport {\n formatTuiConfigInfo,\n formatTuiContextInfo,\n formatTuiLoginInfo,\n formatTuiModelsInfo,\n formatTuiSessionInfo,\n formatTuiSessionListInfo,\n formatTuiSessionTreeInfo,\n formatTuiStoredAuthProfilesInfo,\n formatTuiTranscriptTreeInfo,\n formatTuiTrustInfo,\n formatTuiUsageInfo,\n formatTuiWorkflowDetail,\n formatTuiWorkflowsInfo,\n loadTuiChangelogInfo,\n nextVerboseLevel,\n parseTuiExportRequest,\n parseTuiImportRequest,\n parseTuiShareRequest,\n writeTuiDebugInfo,\n type TuiExportRequest,\n type TuiImportRequest,\n} from './tui-command-formatters.js';\n\nexport type CommandHandlerDeps = {\n state: TuiState;\n chatLog: ChatLog;\n tui: TUI;\n isLocalMode: boolean;\n abortActive: () => Promise<void>;\n sendMessage: (text: string) => void;\n requestExit: () => void;\n updateFooter: () => void;\n keybindings: KeybindingsManager;\n uiOverlays?: {\n openModelPicker: (initialSearch?: string) => void;\n openAgentPicker?: () => void;\n openSessionPicker: () => void;\n openSessionTree: () => void;\n openTranscriptTree: () => void;\n openUserMessageFork: () => void;\n openScopedModels: () => void;\n openThinkingSelector: () => void;\n openSettings: () => void;\n openProjectTrust: () => void;\n reloadKeybindings: () => void | Promise<void>;\n };\n setThinkingLevel?: (level: ThinkLevel) => void | Promise<void>;\n setReasoningLevel?: (level: ReasoningLevel) => void | Promise<void>;\n setVerboseLevel?: (level: VerboseLevel) => void | Promise<void>;\n copyLastAssistant?: () => void | Promise<void>;\n renameCurrentSession?: (name: string) => void | Promise<void>;\n runCompaction?: (instructions?: string) => void | Promise<void | TuiCompactionResult>;\n listModels?: () => TuiModelChoice[] | Promise<TuiModelChoice[]>;\n switchModel?: (modelRef: string) => void | Promise<void>;\n listSessions?: () => TuiSessionItem[] | Promise<TuiSessionItem[]>;\n listAgents?: () => TuiAgentInfo[] | Promise<TuiAgentInfo[]>;\n switchAgentSession?: (sessionKey: string, agentId: string) => void | Promise<void>;\n getSessionStats?: () => TuiSessionStats | Promise<TuiSessionStats>;\n getStartupResources?: () => TuiStartupResources | undefined;\n loadTranscriptTree?: () => TuiTranscriptTreeEntry[] | Promise<TuiTranscriptTreeEntry[]>;\n exportSession?: (request: TuiExportRequest) => void | Promise<void>;\n importSession?: (request: TuiImportRequest) => void | Promise<void>;\n createShare?: (request: TuiShareRequest) => void | Promise<void>;\n authProfiles?: {\n listAll: () => AuthProfileEntry[] | Promise<AuthProfileEntry[]>;\n listProvider: (provider: string) => AuthProfileEntry[] | Promise<AuthProfileEntry[]>;\n remove: (profileId: string) => boolean | Promise<boolean>;\n getStorePath: () => string;\n };\n projectTrust?: {\n cwd: string;\n hasProjectResources: () => boolean;\n getStorePath: () => string;\n getEntry: () => ProjectTrustStoreEntry | null;\n getSessionDecision: () => boolean | null;\n };\n runLogin?: (provider?: string) => void | Promise<void>;\n runBtwQuery?: (question: string) => void | Promise<void>;\n forkSession?: (rawKey?: string) => void | Promise<void>;\n extensionSlashCommands?: TuiExtensionSlashCommandEntry[];\n extensionShortcuts?: TuiHotkeyExtensionShortcut[];\n currentAgentId?: string;\n setSession?: (rawKey: string) => Promise<void>;\n resetSession?: () => Promise<void>;\n recoverStream?: () => void | Promise<void>;\n retryLastMessage?: () => void | Promise<void>;\n};\n\nfunction defaultAuthProfiles(): NonNullable<CommandHandlerDeps['authProfiles']> {\n return {\n listAll: () => listAllAuthProfiles(),\n listProvider: (provider) => listProfilesForProvider(provider),\n remove: (profileId) => removeAuthProfile(profileId),\n getStorePath: () => getAuthStorePath(),\n };\n}\n\nfunction formatAgentsList(agents: TuiAgentInfo[], currentAgentId?: string): string {\n if (agents.length === 0) {\n return 'No agents available.';\n }\n const current = currentAgentId?.trim().toLowerCase();\n const sorted = [...agents].sort((a, b) => {\n if (a.id === current && b.id !== current) return -1;\n if (b.id === current && a.id !== current) return 1;\n if (a.id === 'coder' && b.id !== 'coder') return -1;\n if (b.id === 'coder' && a.id !== 'coder') return 1;\n return a.id.localeCompare(b.id);\n });\n return [\n 'Available agents:',\n ...sorted.map((agent) => {\n const marker = agent.id === current ? '*' : ' ';\n const label = agent.displayName ? ` — ${agent.displayName}` : '';\n return `${marker} ${agent.id} (${agent.source})${label}`;\n }),\n '',\n 'Switch with: /agent <id>',\n ].join('\\n');\n}\n\nfunction formatCurrentAgent(state: TuiState): string {\n const parsed = parseAgentSessionKey(state.currentSessionKey);\n if (!parsed) {\n return `Current session is not an agent session.\\nSession: ${state.currentSessionKey}`;\n }\n const lines = [\n `Current agent: ${parsed.agentId}`,\n `Session: ${state.currentSessionKey}`,\n ];\n const workspace = state.sessionInfo.effectiveWorkspacePath?.trim();\n if (workspace) lines.push(`Workspace: ${workspace}`);\n const provider = state.sessionInfo.modelProvider?.trim();\n const model = state.sessionInfo.model?.trim();\n if (model) lines.push(`Model: ${provider ? `${provider}/${model}` : model}`);\n return lines.join('\\n');\n}\n\nexport function createTuiCommandHandler(deps: CommandHandlerDeps): (input: string) => void {\n const {\n state,\n chatLog,\n tui,\n isLocalMode,\n abortActive,\n sendMessage,\n requestExit,\n updateFooter,\n keybindings,\n uiOverlays,\n extensionSlashCommands = [],\n extensionShortcuts = [],\n setSession,\n resetSession,\n } = deps;\n\n const runReset = async () => {\n await abortActive();\n if (resetSession) {\n await resetSession();\n chatLog.addSystem(`session ${state.currentSessionKey} reset`);\n } else {\n chatLog.clearAll();\n state.messageFollowUpQueue.length = 0;\n state.steeringQueue.length = 0;\n chatLog.addSystem('Session cleared (reset not available in this mode).');\n }\n tui.requestRender();\n };\n\n return (input: string) => {\n const trimmed = input.replace(/^\\//, '').trim();\n const [commandName, ...restParts] = trimmed.split(/\\s+/);\n const normalizedCommand = (commandName ?? '').toLowerCase();\n const commandArgs = restParts.join(' ');\n\n switch (normalizedCommand) {\n case 'help':\n chatLog.addSystem(formatTuiHelpText(isLocalMode, keybindings, extensionSlashCommands));\n tui.requestRender();\n return;\n case 'start':\n chatLog.addSystem(formatTuiStartText(state, isLocalMode, keybindings, deps.getStartupResources?.()));\n tui.requestRender();\n return;\n case 'hotkeys':\n case 'keys':\n chatLog.addSystem(formatXopcTuiHotkeys(keybindings, extensionShortcuts));\n tui.requestRender();\n return;\n case 'changelog':\n chatLog.addSystem(loadTuiChangelogInfo());\n tui.requestRender();\n return;\n case 'debug':\n try {\n const debugPath = writeTuiDebugInfo({ state, tui });\n chatLog.addSystem(`Debug log written\\n${debugPath}`);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Debug log failed: ${errorMessage}`);\n }\n tui.requestRender();\n return;\n case 'session':\n case 'status':\n void Promise.resolve(deps.getSessionStats?.())\n .catch(() => undefined)\n .then((stats) => {\n chatLog.addSystem(formatTuiSessionInfo(state, stats));\n tui.requestRender();\n });\n return;\n case 'agents':\n if (uiOverlays?.openAgentPicker) {\n uiOverlays.openAgentPicker();\n return;\n }\n void Promise.resolve(deps.listAgents?.() ?? [])\n .then((agents) => {\n const current = parseAgentSessionKey(state.currentSessionKey)?.agentId;\n chatLog.addSystem(formatAgentsList(agents, current));\n tui.requestRender();\n })\n .catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Agents list failed: ${errorMessage}`);\n tui.requestRender();\n });\n return;\n case 'agent': {\n const targetRaw = commandArgs.trim();\n if (!targetRaw) {\n chatLog.addSystem(formatCurrentAgent(state));\n tui.requestRender();\n return;\n }\n void (async () => {\n const parsedCurrent = parseAgentSessionKey(state.currentSessionKey);\n if (!parsedCurrent) {\n chatLog.addSystem('Cannot switch agent: current session is not an agent session.');\n tui.requestRender();\n return;\n }\n if (state.activeRunId) {\n chatLog.addSystem('Cannot switch agent while a run is active. Abort first.');\n tui.requestRender();\n return;\n }\n if (!isValidAgentId(targetRaw)) {\n chatLog.addSystem(`Invalid agent id: ${targetRaw}`);\n tui.requestRender();\n return;\n }\n const targetAgentId = normalizeAgentId(targetRaw);\n const agents = await Promise.resolve(deps.listAgents?.() ?? []);\n if (!agents.some((agent) => agent.enabled !== false && agent.id === targetAgentId)) {\n chatLog.addSystem(`Unknown agent: ${targetAgentId}`);\n tui.requestRender();\n return;\n }\n const targetSessionKey = `agent:${targetAgentId}:${parsedCurrent.rest}`;\n if (targetSessionKey === state.currentSessionKey) {\n chatLog.addSystem(`Already using agent: ${targetAgentId}`);\n tui.requestRender();\n return;\n }\n if (!deps.switchAgentSession) {\n chatLog.addSystem('Agent switching is not available in this mode.');\n tui.requestRender();\n return;\n }\n await deps.switchAgentSession(targetSessionKey, targetAgentId);\n chatLog.addSystem(`Switched to agent: ${targetAgentId}\\nSession: ${targetSessionKey}`);\n tui.requestRender();\n })().catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Agent switch failed: ${errorMessage}`);\n tui.requestRender();\n });\n return;\n }\n case 'usage':\n void Promise.resolve(deps.getSessionStats?.())\n .catch(() => undefined)\n .then((stats) => {\n chatLog.addSystem(formatTuiUsageInfo(state, stats));\n tui.requestRender();\n });\n return;\n case 'context':\n chatLog.addSystem(formatTuiContextInfo(state));\n tui.requestRender();\n return;\n case 'config':\n chatLog.addSystem(formatTuiConfigInfo(state));\n tui.requestRender();\n return;\n case 'trust':\n if (uiOverlays?.openProjectTrust) {\n uiOverlays.openProjectTrust();\n return;\n }\n chatLog.addSystem(\n formatTuiTrustInfo(loadConfig(), {\n configPath: resolveConfigPath(),\n provenance: provenanceTracker.getAll(),\n cwd: deps.projectTrust?.cwd,\n hasProjectResources: deps.projectTrust?.hasProjectResources(),\n projectTrustStorePath: deps.projectTrust?.getStorePath(),\n projectTrustEntry: deps.projectTrust?.getEntry(),\n projectTrustSessionDecision: deps.projectTrust?.getSessionDecision(),\n }),\n );\n tui.requestRender();\n return;\n case 'export':\n if (!deps.exportSession) {\n chatLog.addSystem('Export is not available in this mode.');\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.exportSession(parseTuiExportRequest(commandArgs))).then(() => {\n tui.requestRender();\n });\n return;\n case 'import':\n if (!deps.importSession) {\n chatLog.addSystem('Import is not available in this mode.');\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.importSession(parseTuiImportRequest(commandArgs))).then(() => {\n tui.requestRender();\n });\n return;\n case 'share': {\n if (!deps.createShare) {\n chatLog.addSystem('Share is not available in this mode.');\n tui.requestRender();\n return;\n }\n const request = parseTuiShareRequest(commandArgs);\n if (!request) {\n chatLog.addSystem(\n [\n 'Usage: /share <workspace-path> [friend|colleague|public] [--site|--zip|--file]',\n 'Optional: --title \"Title\" --description \"Description\"',\n ].join('\\n'),\n );\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.createShare(request)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'btw':\n case 'aside': {\n const question = commandArgs.trim();\n if (!question) {\n chatLog.addSystem(\n 'Usage: /btw <question>\\nAnswers use the current session as read-only background and are not saved.',\n );\n tui.requestRender();\n return;\n }\n if (!deps.runBtwQuery) {\n chatLog.addSystem('/btw is not available in this mode.');\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.runBtwQuery(question)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'workflows':\n try {\n chatLog.addSystem(formatTuiWorkflowsInfo(createWorkflowCatalog().list()));\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Workflow list failed: ${errorMessage}`);\n }\n tui.requestRender();\n return;\n case 'workflow': {\n const [subcommandRaw, ...workflowRest] = commandArgs.trim().split(/\\s+/);\n const subcommand = (subcommandRaw || 'list').toLowerCase();\n if (subcommand === 'list' || subcommand === 'ls') {\n try {\n chatLog.addSystem(formatTuiWorkflowsInfo(createWorkflowCatalog().list()));\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Workflow list failed: ${errorMessage}`);\n }\n tui.requestRender();\n return;\n }\n if (subcommand === 'view' || subcommand === 'show') {\n const name = workflowRest[0]?.trim();\n if (!name) {\n chatLog.addSystem('Usage: /workflow view <name>');\n tui.requestRender();\n return;\n }\n try {\n chatLog.addSystem(formatTuiWorkflowDetail(name));\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Workflow view failed: ${errorMessage}`);\n }\n tui.requestRender();\n return;\n }\n if (subcommand === 'save') {\n chatLog.addSystem('/workflow save is available through the workflow tool after a generated workflow run.');\n tui.requestRender();\n return;\n }\n chatLog.addSystem('Usage: /workflow list | /workflow view <name> | /workflow save <name>');\n tui.requestRender();\n return;\n }\n case 'models':\n void Promise.resolve(deps.listModels?.() ?? []).then((models) => {\n chatLog.addSystem(formatTuiModelsInfo(models));\n tui.requestRender();\n });\n return;\n case 'model':\n if (uiOverlays) {\n uiOverlays.openModelPicker(commandArgs.trim() || undefined);\n return;\n }\n chatLog.addSystem('Model picker is not available in this mode. Use /models and /switch <provider/model>.');\n tui.requestRender();\n return;\n case 'list':\n void Promise.resolve(deps.listSessions?.() ?? []).then((sessions) => {\n chatLog.addSystem(\n formatTuiSessionListInfo(sessions, { currentSessionKey: state.currentSessionKey }),\n );\n tui.requestRender();\n });\n return;\n case 'tree':\n if (uiOverlays) {\n uiOverlays.openTranscriptTree();\n return;\n }\n if (deps.loadTranscriptTree) {\n void Promise.resolve(deps.loadTranscriptTree()).then((entries) => {\n chatLog.addSystem(formatTuiTranscriptTreeInfo(entries));\n tui.requestRender();\n });\n return;\n }\n uiOverlays?.openSessionTree();\n if (uiOverlays) return;\n void Promise.resolve(deps.listSessions?.() ?? []).then((sessions) => {\n chatLog.addSystem(\n formatTuiSessionTreeInfo(sessions, { currentSessionKey: state.currentSessionKey }),\n );\n tui.requestRender();\n });\n return;\n case 'switch': {\n const modelRef = commandArgs.trim();\n if (!modelRef) {\n chatLog.addSystem('Usage: /switch <provider/model>');\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.switchModel?.(modelRef)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'login':\n if (deps.runLogin && (!commandArgs.trim() || providerSupportsOAuth(commandArgs.trim()))) {\n void Promise.resolve(deps.runLogin(commandArgs.trim() || undefined))\n .catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Login failed: ${errorMessage}`);\n })\n .finally(() => tui.requestRender());\n return;\n }\n chatLog.addSystem(formatTuiLoginInfo(commandArgs));\n tui.requestRender();\n return;\n case 'logout': {\n const provider = commandArgs.trim();\n const authProfiles = deps.authProfiles ?? defaultAuthProfiles();\n void (async () => {\n try {\n if (!provider) {\n const profiles = await authProfiles.listAll();\n chatLog.addSystem(\n formatTuiStoredAuthProfilesInfo(profiles, { authStorePath: authProfiles.getStorePath() }),\n );\n tui.requestRender();\n return;\n }\n\n const profiles = await authProfiles.listProvider(provider);\n if (profiles.length === 0) {\n chatLog.addSystem(\n [\n `No stored auth profiles found for provider: ${provider}`,\n 'Environment variables and config credentials are unchanged.',\n ].join('\\n'),\n );\n tui.requestRender();\n return;\n }\n\n let removed = 0;\n for (const profile of profiles) {\n if (await authProfiles.remove(profile.profileId)) {\n removed += 1;\n }\n }\n chatLog.addSystem(\n [\n `Logged out from ${provider}: removed ${removed} stored auth profile${removed === 1 ? '' : 's'}.`,\n 'Environment variables and config credentials are unchanged.',\n ].join('\\n'),\n );\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Logout failed: ${errorMessage}`);\n }\n tui.requestRender();\n })();\n return;\n }\n case 'exit':\n case 'quit':\n requestExit();\n return;\n case 'abort':\n case 'stop':\n case 'cancel':\n void abortActive().then(() => {\n chatLog.addSystem('Aborted.');\n tui.requestRender();\n });\n return;\n case 'recover':\n void Promise.resolve(deps.recoverStream?.())\n .catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Recover failed: ${errorMessage}`);\n })\n .finally(() => tui.requestRender());\n return;\n case 'retry':\n void Promise.resolve(deps.retryLastMessage?.())\n .catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Retry failed: ${errorMessage}`);\n })\n .finally(() => tui.requestRender());\n return;\n case 'tools':\n state.toolsExpanded = !state.toolsExpanded;\n chatLog.setToolsExpanded(state.toolsExpanded);\n chatLog.addSystem(`Tools: ${state.toolsExpanded ? 'expanded' : 'collapsed'}`);\n tui.requestRender();\n return;\n case 'thinking':\n state.showThinking = !state.showThinking;\n chatLog.setShowThinking(state.showThinking);\n chatLog.addSystem(`Thinking display: ${state.showThinking ? 'on' : 'off'}`);\n updateFooter();\n tui.requestRender();\n return;\n case 'copy':\n void Promise.resolve(deps.copyLastAssistant?.()).then(() => {\n tui.requestRender();\n });\n return;\n case 'name': {\n const name = commandArgs.trim();\n if (!name) {\n const currentName = state.sessionInfo.displayName?.trim();\n chatLog.addSystem(currentName ? `Session name: ${currentName}` : 'Usage: /name <name>');\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.renameCurrentSession?.(name)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'resume':\n case 'sessions':\n uiOverlays?.openSessionPicker();\n return;\n case 'scoped-models':\n case 'scopedmodels':\n uiOverlays?.openScopedModels();\n return;\n case 'think': {\n const level = normalizeThinkLevel(commandArgs);\n if (!commandArgs.trim()) {\n uiOverlays?.openThinkingSelector();\n return;\n }\n if (!level) {\n chatLog.addSystem(`Invalid thinking level: ${commandArgs}`);\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.setThinkingLevel?.(level)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'reasoning': {\n const level = normalizeReasoningLevel(commandArgs);\n if (!commandArgs.trim()) {\n const current = state.sessionInfo.reasoningLevel?.trim();\n chatLog.addSystem(\n current\n ? `Reasoning visibility: ${current}`\n : 'Usage: /reasoning <off|on|stream>',\n );\n tui.requestRender();\n return;\n }\n if (!level) {\n chatLog.addSystem(`Invalid reasoning visibility: ${commandArgs}`);\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.setReasoningLevel?.(level)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'verbose': {\n const raw = commandArgs.trim();\n const level = raw ? normalizeVerboseLevel(raw) : nextVerboseLevel(state.sessionInfo.verboseLevel);\n if (raw && !level) {\n chatLog.addSystem(`Invalid verbose level: ${commandArgs}`);\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.setVerboseLevel?.(level)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'settings':\n uiOverlays?.openSettings();\n return;\n case 'reload':\n case 'reload-keybindings':\n case 'reload-keybind':\n void Promise.resolve(uiOverlays?.reloadKeybindings())\n .then(() => {\n chatLog.addSystem('Reloaded keybindings, TUI settings, theme, and extension UI.');\n tui.requestRender();\n })\n .catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Reload failed: ${errorMessage}`);\n tui.requestRender();\n });\n return;\n case 'compact':\n void deps.runCompaction?.(commandArgs.trim() || undefined);\n return;\n default:\n break;\n }\n\n switch (normalizedCommand) {\n case 'new': {\n void (async () => {\n try {\n await abortActive();\n const uniqueKey = `tui-${randomUUID()}`;\n if (setSession) {\n await setSession(uniqueKey);\n chatLog.addSystem(`new session: ${state.currentSessionKey}`);\n } else {\n chatLog.clearAll();\n state.messageFollowUpQueue.length = 0;\n state.steeringQueue.length = 0;\n chatLog.addSystem('New session requires gateway or local session support.');\n }\n tui.requestRender();\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`new session failed: ${errorMessage}`);\n tui.requestRender();\n }\n })();\n return;\n }\n case 'fork': {\n if (!commandArgs.trim() && uiOverlays) {\n uiOverlays.openUserMessageFork();\n return;\n }\n void Promise.resolve(deps.forkSession?.(commandArgs.trim() || undefined)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'clone':\n void Promise.resolve(deps.forkSession?.(commandArgs.trim() || undefined)).then(() => {\n tui.requestRender();\n });\n return;\n case 'reset':\n case 'restart':\n void runReset();\n return;\n case 'clear':\n void runReset();\n return;\n default:\n break;\n }\n\n const extensionCmd = extensionSlashCommands.find((c) => c.name === normalizedCommand);\n if (extensionCmd) {\n void Promise.resolve(\n extensionCmd.handler(commandArgs, extensionCmd.getContext?.()),\n ).then(() => {\n tui.requestRender();\n });\n return;\n }\n\n // Unknown slash that names a known workflow → rewrite into a natural prompt\n // so the assistant deterministically calls workflow({name}) instead of\n // depending on the model to puzzle out \"/audit_repo\".\n if (input.trimStart().startsWith('/')) {\n const rewritten = rewriteUnknownSlashAsWorkflow(normalizedCommand, commandArgs);\n if (rewritten) {\n chatLog.addSystem(`▶ Running workflow: ${normalizedCommand}`);\n tui.requestRender();\n sendMessage(rewritten);\n return;\n }\n }\n\n sendMessage(input);\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tui-commands.js","names":["listAllAuthProfiles"],"sources":["../../../src/tui/tui-commands.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { KeybindingsManager, TUI } from '@earendil-works/pi-tui';\n\nimport type {\n TuiCompactionResult,\n TuiModelChoice,\n TuiShareRequest,\n TuiSessionStats,\n TuiSessionItem,\n TuiStartupResources,\n TuiTranscriptTreeEntry,\n TuiAgentInfo,\n} from './tui-backend.js';\nimport type { ChatLog } from './components/chat-log.js';\nimport {\n formatKeyIds,\n formatXopcTuiHotkeys,\n type TuiHotkeyExtensionShortcut,\n} from './format-tui-hotkeys.js';\nimport { getTuiKeybindingsPath } from './tui-keybindings-file.js';\nimport type { TuiState } from './tui-types.js';\nimport { createWorkflowCatalog } from '../agent/workflow/catalog.js';\nimport {\n isValidAgentId,\n normalizeAgentId,\n parseAgentSessionKey,\n} from '../routing/agent-session-key.js';\nimport {\n normalizeReasoningLevel,\n normalizeThinkLevel,\n normalizeVerboseLevel,\n type ReasoningLevel,\n type ThinkLevel,\n type VerboseLevel,\n} from '../agent/transcript/thinking-types.js';\nimport {\n getAuthStorePath,\n listAllProfiles as listAllAuthProfiles,\n listProfilesForProvider,\n removeAuthProfile,\n type AuthProfileEntry,\n} from '../auth/profiles/index.js';\nimport { loadConfig, resolveConfigPath } from '../config/index.js';\nimport type { TuiSlashCommandContext, TuiSlashCommandHandler } from '../extensions/types/tui.js';\nimport { provenanceTracker } from '../extensions/security.js';\nimport type { ProjectTrustStoreEntry } from '../project-trust/trust-store.js';\nimport { providerSupportsOAuth } from '../providers/index.js';\n\nimport { rewriteUnknownSlashAsWorkflow } from './tui-workflow-slash.js';\nimport { formatTuiStartupText } from './tui-startup-text.js';\n\ninterface SlashCommandDef {\n name: string;\n originalName?: string;\n description: string;\n}\n\nexport type TuiExtensionSlashCommandEntry = SlashCommandDef & {\n handler: TuiSlashCommandHandler;\n getContext?: () => TuiSlashCommandContext;\n};\n\nfunction keyLabel(\n keybindings: KeybindingsManager | undefined,\n id: Parameters<KeybindingsManager['getKeys']>[0],\n fallback: string,\n): string {\n return keybindings ? formatKeyIds(keybindings, id, { capitalize: true }) : fallback;\n}\n\nexport function getSlashCommands(\n _isLocal: boolean,\n keybindings?: KeybindingsManager,\n): SlashCommandDef[] {\n const abortKey = keyLabel(keybindings, 'app.interrupt', 'Escape');\n const toolsKey = keyLabel(keybindings, 'app.tools.expand', 'Ctrl+O');\n const thinkingKey = keyLabel(keybindings, 'app.thinking.toggle', 'Ctrl+T');\n const sessionKey = keyLabel(keybindings, 'app.session.resume', 'Ctrl+Shift+P');\n const modelCycleKey = keyLabel(keybindings, 'app.model.cycleForward', 'Ctrl+P');\n return [\n { name: 'help', description: 'Show available commands' },\n { name: 'abort', description: `Abort active run (or press ${abortKey})` },\n { name: 'recover', description: 'Reload history and reattach to a stalled run' },\n { name: 'retry', description: 'Abort current run if needed and resend the last user message' },\n { name: 'tools', description: `Toggle tool output expanded/collapsed (or ${toolsKey})` },\n { name: 'thinking', description: `Toggle thinking display (or ${thinkingKey})` },\n { name: 'copy', description: 'Copy last assistant message to clipboard' },\n { name: 'exit', description: 'Exit the TUI' },\n { name: 'quit', description: 'Quit the TUI' },\n { name: 'model', description: 'Open model picker (optional search text)' },\n { name: 'models', description: 'List available models' },\n { name: 'switch', description: 'Switch model — copy `provider/model` from /models' },\n { name: 'login', description: 'Login to an OAuth provider' },\n { name: 'logout', description: 'Remove stored provider auth profiles' },\n { name: 'usage', description: 'Show token usage statistics' },\n { name: 'session', description: 'Show current session info' },\n { name: 'agent', description: 'Show or switch agent for this TUI session' },\n { name: 'agents', description: 'List available agents' },\n { name: 'new', description: 'Start a new isolated TUI session (tui-{uuid})' },\n { name: 'fork', description: 'Fork current session transcript into a new session' },\n { name: 'clone', description: 'Duplicate current session transcript into a new session' },\n { name: 'trust', description: 'Manage project trust and show extension security policy' },\n { name: 'name', description: 'Show or set current session display name' },\n { name: 'reset', description: 'Reset current session transcript and reload history' },\n { name: 'clear', description: 'Alias for /reset' },\n { name: 'list', description: 'List sessions' },\n { name: 'resume', description: `Open session picker (or ${sessionKey})` },\n { name: 'tree', description: 'Show grouped session tree' },\n { name: 'scoped-models', description: `Choose models for ${modelCycleKey} cycling` },\n { name: 'compact', description: 'Compact session history (local API)' },\n { name: 'think', description: 'Set thinking level (e.g. /think high)' },\n { name: 'reasoning', description: 'Set reasoning visibility (e.g. /reasoning stream)' },\n { name: 'verbose', description: 'Toggle verbose mode' },\n { name: 'status', description: 'Show agent status' },\n { name: 'config', description: 'Show or update configuration' },\n { name: 'context', description: 'Show context budget' },\n { name: 'btw', description: 'Side question without saving to session' },\n { name: 'export', description: 'Export session (markdown/html/json)' },\n { name: 'import', description: 'Import an xopc JSON session export' },\n { name: 'share', description: 'Create a share link for a workspace file/folder/site' },\n { name: 'settings', description: 'Open TUI settings overlay' },\n { name: 'reload', description: 'Reload keybindings, TUI settings, theme, and extension UI' },\n { name: 'reload-keybindings', description: `Reload ${getTuiKeybindingsPath()}` },\n { name: 'start', description: 'Show welcome message' },\n { name: 'hotkeys', description: 'Show resolved keyboard shortcuts (pi-style)' },\n { name: 'changelog', description: 'Show version history' },\n { name: 'workflows', description: 'List saved workflows (built-in + ~/.xopc/workflows/)' },\n { name: 'workflow', description: 'Workflow subcommands: list, view <name>, save <name>' },\n ];\n}\n\nfunction formatExtraSlashCommands(commands: SlashCommandDef[]): string[] {\n const seen = new Set(getSlashCommands(true).map((command) => command.name));\n const lines: string[] = [];\n for (const command of commands) {\n const name = command.name.replace(/^\\//, '').trim().toLowerCase();\n const originalName = command.originalName?.replace(/^\\//, '').trim().toLowerCase();\n if (!name || seen.has(name) || (originalName && seen.has(originalName))) continue;\n seen.add(name);\n lines.push(` /${name} — ${command.description}`);\n }\n return lines;\n}\n\nexport function formatTuiHelpText(\n isLocal: boolean,\n keybindings?: KeybindingsManager,\n extraSlashCommands: SlashCommandDef[] = [],\n): string {\n const commands = getSlashCommands(isLocal, keybindings);\n const interrupt = keyLabel(keybindings, 'app.interrupt', 'Escape');\n const thinkCycle = keyLabel(keybindings, 'app.thinking.cycle', 'Shift+Tab');\n const modelNext = keyLabel(keybindings, 'app.model.cycleForward', 'Ctrl+P');\n const modelPrev = keyLabel(keybindings, 'app.model.cycleBackward', 'Shift+Ctrl+P');\n const modelPicker = keyLabel(keybindings, 'app.model.select', 'Ctrl+L');\n const sessionPicker = keyLabel(keybindings, 'app.session.resume', 'Ctrl+Shift+P');\n const sessionTree = keyLabel(keybindings, 'app.session.tree', '(not bound)');\n const sessionFork = keyLabel(keybindings, 'app.session.fork', '(not bound)');\n const toolExpand = keyLabel(keybindings, 'app.tools.expand', 'Ctrl+O');\n const thinkingToggle = keyLabel(keybindings, 'app.thinking.toggle', 'Ctrl+T');\n const editorExternal = keyLabel(keybindings, 'app.editor.external', 'Ctrl+G');\n const suspend = keyLabel(keybindings, 'app.suspend', 'Ctrl+Z');\n const followUp = keyLabel(keybindings, 'app.message.followUp', 'Alt+Enter');\n const dequeue = keyLabel(keybindings, 'app.message.dequeue', 'Alt+Up');\n const pasteImage = keyLabel(keybindings, 'app.clipboard.pasteImage', 'Ctrl+V / Alt+V');\n const clearInput = keyLabel(keybindings, 'app.clear', 'Ctrl+C');\n const exit = keyLabel(keybindings, 'app.exit', 'Ctrl+D');\n const lines = ['Available commands:'];\n for (const c of commands) {\n lines.push(` /${c.name} — ${c.description}`);\n }\n const extraCommandLines = formatExtraSlashCommands(extraSlashCommands);\n if (extraCommandLines.length > 0) {\n lines.push('', 'Extension commands:');\n lines.push(...extraCommandLines);\n }\n lines.push('', 'Keyboard shortcuts (defaults align with pi coding-agent where noted):');\n lines.push(` ${interrupt} — Abort active run`);\n lines.push(` ${thinkCycle} — Cycle /think level`);\n lines.push(` ${modelNext} / ${modelPrev} — Next / previous model (/switch)`);\n lines.push(` ${modelPicker} — Model picker`);\n lines.push(` ${sessionPicker} — Session picker (rename/delete)`);\n lines.push(` ${sessionTree} — Session tree`);\n lines.push(` ${sessionFork} — Fork current session`);\n lines.push(` /scoped-models — Limit ${modelNext} model cycle set`);\n lines.push(` ${toolExpand} — Toggle tool output`);\n lines.push(` ${thinkingToggle} — Toggle thinking block display`);\n lines.push(` ${editorExternal} — Edit draft in $EDITOR`);\n lines.push(` ${suspend} — Suspend to shell (Unix)`);\n lines.push(` ${followUp} — Queue follow-up while busy (sends when this reply finishes)`);\n lines.push(` ${dequeue} — Restore queued messages to editor`);\n lines.push(' Enter (while busy) — Steer: inject at next tool boundary');\n lines.push(` ${pasteImage} — Paste image from clipboard`);\n lines.push(' /settings — Theme, thinking display, terminal progress, …');\n lines.push(` ${getTuiKeybindingsPath()} — Custom shortcuts (use /reload)`);\n lines.push(` ${clearInput} — Clear input; repeat within ~0.5s to exit when empty`);\n lines.push(` ${exit} — Exit when input empty`);\n lines.push(' !cmd — Local shell (gated; runs on this machine)');\n lines.push('', 'Use /hotkeys for the resolved binding list from the active keymap.');\n return lines.join('\\n');\n}\n\nexport function formatTuiStartText(\n state: TuiState,\n isLocal: boolean,\n keybindings?: KeybindingsManager,\n resources?: TuiStartupResources,\n): string {\n return formatTuiStartupText({\n state,\n isLocal,\n keybindings,\n resources,\n expanded: true,\n });\n}\n\nimport {\n formatTuiConfigInfo,\n formatTuiContextInfo,\n formatTuiLoginInfo,\n formatTuiModelsInfo,\n formatTuiSessionInfo,\n formatTuiSessionListInfo,\n formatTuiSessionTreeInfo,\n formatTuiStoredAuthProfilesInfo,\n formatTuiTranscriptTreeInfo,\n formatTuiTrustInfo,\n formatTuiUsageInfo,\n formatTuiWorkflowDetail,\n formatTuiWorkflowsInfo,\n loadTuiChangelogInfo,\n nextVerboseLevel,\n parseTuiExportRequest,\n parseTuiImportRequest,\n parseTuiShareRequest,\n writeTuiDebugInfo,\n type TuiExportRequest,\n type TuiImportRequest,\n} from './tui-command-formatters.js';\n\nexport type CommandHandlerDeps = {\n state: TuiState;\n chatLog: ChatLog;\n tui: TUI;\n isLocalMode: boolean;\n abortActive: () => Promise<void>;\n sendMessage: (text: string) => void;\n requestExit: () => void;\n updateFooter: () => void;\n keybindings: KeybindingsManager;\n uiOverlays?: {\n openModelPicker: (initialSearch?: string) => void;\n openAgentPicker?: () => void;\n openSessionPicker: () => void;\n openSessionTree: () => void;\n openTranscriptTree: () => void;\n openUserMessageFork: () => void;\n openScopedModels: () => void;\n openThinkingSelector: () => void;\n openSettings: () => void;\n openProjectTrust: () => void;\n reloadKeybindings: () => void | Promise<void>;\n };\n setThinkingLevel?: (level: ThinkLevel) => void | Promise<void>;\n setReasoningLevel?: (level: ReasoningLevel) => void | Promise<void>;\n setVerboseLevel?: (level: VerboseLevel) => void | Promise<void>;\n copyLastAssistant?: () => void | Promise<void>;\n renameCurrentSession?: (name: string) => void | Promise<void>;\n runCompaction?: (instructions?: string) => void | Promise<void | TuiCompactionResult>;\n listModels?: () => TuiModelChoice[] | Promise<TuiModelChoice[]>;\n switchModel?: (modelRef: string) => void | Promise<void>;\n listSessions?: () => TuiSessionItem[] | Promise<TuiSessionItem[]>;\n listAgents?: () => TuiAgentInfo[] | Promise<TuiAgentInfo[]>;\n switchAgentSession?: (sessionKey: string, agentId: string) => void | Promise<void>;\n getSessionStats?: () => TuiSessionStats | Promise<TuiSessionStats>;\n getStartupResources?: () => TuiStartupResources | undefined;\n loadTranscriptTree?: () => TuiTranscriptTreeEntry[] | Promise<TuiTranscriptTreeEntry[]>;\n exportSession?: (request: TuiExportRequest) => void | Promise<void>;\n importSession?: (request: TuiImportRequest) => void | Promise<void>;\n createShare?: (request: TuiShareRequest) => void | Promise<void>;\n authProfiles?: {\n listAll: () => AuthProfileEntry[] | Promise<AuthProfileEntry[]>;\n listProvider: (provider: string) => AuthProfileEntry[] | Promise<AuthProfileEntry[]>;\n remove: (profileId: string) => boolean | Promise<boolean>;\n getStorePath: () => string;\n };\n projectTrust?: {\n cwd: string;\n hasProjectResources: () => boolean;\n getStorePath: () => string;\n getEntry: () => ProjectTrustStoreEntry | null;\n getSessionDecision: () => boolean | null;\n };\n runLogin?: (provider?: string) => void | Promise<void>;\n runBtwQuery?: (question: string) => void | Promise<void>;\n forkSession?: (rawKey?: string) => void | Promise<void>;\n extensionSlashCommands?: TuiExtensionSlashCommandEntry[];\n extensionShortcuts?: TuiHotkeyExtensionShortcut[];\n currentAgentId?: string;\n setSession?: (rawKey: string) => Promise<void>;\n resetSession?: () => Promise<void>;\n recoverStream?: () => void | Promise<void>;\n retryLastMessage?: () => void | Promise<void>;\n};\n\nfunction defaultAuthProfiles(): NonNullable<CommandHandlerDeps['authProfiles']> {\n return {\n listAll: () => listAllAuthProfiles(),\n listProvider: (provider) => listProfilesForProvider(provider),\n remove: (profileId) => removeAuthProfile(profileId),\n getStorePath: () => getAuthStorePath(),\n };\n}\n\nfunction formatAgentsList(agents: TuiAgentInfo[], currentAgentId?: string): string {\n if (agents.length === 0) {\n return 'No agents available.';\n }\n const current = currentAgentId?.trim().toLowerCase();\n const sorted = [...agents].sort((a, b) => {\n if (a.id === current && b.id !== current) return -1;\n if (b.id === current && a.id !== current) return 1;\n if (a.id === 'coder' && b.id !== 'coder') return -1;\n if (b.id === 'coder' && a.id !== 'coder') return 1;\n return a.id.localeCompare(b.id);\n });\n return [\n 'Available agents:',\n ...sorted.map((agent) => {\n const marker = agent.id === current ? '*' : ' ';\n const label = agent.displayName ? ` — ${agent.displayName}` : '';\n return `${marker} ${agent.id}${label}`;\n }),\n '',\n 'Switch with: /agent <id>',\n ].join('\\n');\n}\n\nfunction formatCurrentAgent(state: TuiState): string {\n const parsed = parseAgentSessionKey(state.currentSessionKey);\n if (!parsed) {\n return `Current session is not an agent session.\\nSession: ${state.currentSessionKey}`;\n }\n const lines = [\n `Current agent: ${parsed.agentId}`,\n `Session: ${state.currentSessionKey}`,\n ];\n const workspace = state.sessionInfo.effectiveWorkspacePath?.trim();\n if (workspace) lines.push(`Workspace: ${workspace}`);\n const provider = state.sessionInfo.modelProvider?.trim();\n const model = state.sessionInfo.model?.trim();\n if (model) lines.push(`Model: ${provider ? `${provider}/${model}` : model}`);\n return lines.join('\\n');\n}\n\nexport function createTuiCommandHandler(deps: CommandHandlerDeps): (input: string) => void {\n const {\n state,\n chatLog,\n tui,\n isLocalMode,\n abortActive,\n sendMessage,\n requestExit,\n updateFooter,\n keybindings,\n uiOverlays,\n extensionSlashCommands = [],\n extensionShortcuts = [],\n setSession,\n resetSession,\n } = deps;\n\n const runReset = async () => {\n await abortActive();\n if (resetSession) {\n await resetSession();\n chatLog.addSystem(`session ${state.currentSessionKey} reset`);\n } else {\n chatLog.clearAll();\n state.messageFollowUpQueue.length = 0;\n state.steeringQueue.length = 0;\n chatLog.addSystem('Session cleared (reset not available in this mode).');\n }\n tui.requestRender();\n };\n\n return (input: string) => {\n const trimmed = input.replace(/^\\//, '').trim();\n const [commandName, ...restParts] = trimmed.split(/\\s+/);\n const normalizedCommand = (commandName ?? '').toLowerCase();\n const commandArgs = restParts.join(' ');\n\n switch (normalizedCommand) {\n case 'help':\n chatLog.addSystem(formatTuiHelpText(isLocalMode, keybindings, extensionSlashCommands));\n tui.requestRender();\n return;\n case 'start':\n chatLog.addSystem(formatTuiStartText(state, isLocalMode, keybindings, deps.getStartupResources?.()));\n tui.requestRender();\n return;\n case 'hotkeys':\n case 'keys':\n chatLog.addSystem(formatXopcTuiHotkeys(keybindings, extensionShortcuts));\n tui.requestRender();\n return;\n case 'changelog':\n chatLog.addSystem(loadTuiChangelogInfo());\n tui.requestRender();\n return;\n case 'debug':\n try {\n const debugPath = writeTuiDebugInfo({ state, tui });\n chatLog.addSystem(`Debug log written\\n${debugPath}`);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Debug log failed: ${errorMessage}`);\n }\n tui.requestRender();\n return;\n case 'session':\n case 'status':\n void Promise.resolve(deps.getSessionStats?.())\n .catch(() => undefined)\n .then((stats) => {\n chatLog.addSystem(formatTuiSessionInfo(state, stats));\n tui.requestRender();\n });\n return;\n case 'agents':\n if (uiOverlays?.openAgentPicker) {\n uiOverlays.openAgentPicker();\n return;\n }\n void Promise.resolve(deps.listAgents?.() ?? [])\n .then((agents) => {\n const current = parseAgentSessionKey(state.currentSessionKey)?.agentId;\n chatLog.addSystem(formatAgentsList(agents, current));\n tui.requestRender();\n })\n .catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Agents list failed: ${errorMessage}`);\n tui.requestRender();\n });\n return;\n case 'agent': {\n const targetRaw = commandArgs.trim();\n if (!targetRaw) {\n chatLog.addSystem(formatCurrentAgent(state));\n tui.requestRender();\n return;\n }\n void (async () => {\n const parsedCurrent = parseAgentSessionKey(state.currentSessionKey);\n if (!parsedCurrent) {\n chatLog.addSystem('Cannot switch agent: current session is not an agent session.');\n tui.requestRender();\n return;\n }\n if (state.activeRunId) {\n chatLog.addSystem('Cannot switch agent while a run is active. Abort first.');\n tui.requestRender();\n return;\n }\n if (!isValidAgentId(targetRaw)) {\n chatLog.addSystem(`Invalid agent id: ${targetRaw}`);\n tui.requestRender();\n return;\n }\n const targetAgentId = normalizeAgentId(targetRaw);\n const agents = await Promise.resolve(deps.listAgents?.() ?? []);\n if (!agents.some((agent) => agent.enabled !== false && agent.id === targetAgentId)) {\n chatLog.addSystem(`Unknown agent: ${targetAgentId}`);\n tui.requestRender();\n return;\n }\n const targetSessionKey = `agent:${targetAgentId}:${parsedCurrent.rest}`;\n if (targetSessionKey === state.currentSessionKey) {\n chatLog.addSystem(`Already using agent: ${targetAgentId}`);\n tui.requestRender();\n return;\n }\n if (!deps.switchAgentSession) {\n chatLog.addSystem('Agent switching is not available in this mode.');\n tui.requestRender();\n return;\n }\n await deps.switchAgentSession(targetSessionKey, targetAgentId);\n chatLog.addSystem(`Switched to agent: ${targetAgentId}\\nSession: ${targetSessionKey}`);\n tui.requestRender();\n })().catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Agent switch failed: ${errorMessage}`);\n tui.requestRender();\n });\n return;\n }\n case 'usage':\n void Promise.resolve(deps.getSessionStats?.())\n .catch(() => undefined)\n .then((stats) => {\n chatLog.addSystem(formatTuiUsageInfo(state, stats));\n tui.requestRender();\n });\n return;\n case 'context':\n chatLog.addSystem(formatTuiContextInfo(state));\n tui.requestRender();\n return;\n case 'config':\n chatLog.addSystem(formatTuiConfigInfo(state));\n tui.requestRender();\n return;\n case 'trust':\n if (uiOverlays?.openProjectTrust) {\n uiOverlays.openProjectTrust();\n return;\n }\n chatLog.addSystem(\n formatTuiTrustInfo(loadConfig(), {\n configPath: resolveConfigPath(),\n provenance: provenanceTracker.getAll(),\n cwd: deps.projectTrust?.cwd,\n hasProjectResources: deps.projectTrust?.hasProjectResources(),\n projectTrustStorePath: deps.projectTrust?.getStorePath(),\n projectTrustEntry: deps.projectTrust?.getEntry(),\n projectTrustSessionDecision: deps.projectTrust?.getSessionDecision(),\n }),\n );\n tui.requestRender();\n return;\n case 'export':\n if (!deps.exportSession) {\n chatLog.addSystem('Export is not available in this mode.');\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.exportSession(parseTuiExportRequest(commandArgs))).then(() => {\n tui.requestRender();\n });\n return;\n case 'import':\n if (!deps.importSession) {\n chatLog.addSystem('Import is not available in this mode.');\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.importSession(parseTuiImportRequest(commandArgs))).then(() => {\n tui.requestRender();\n });\n return;\n case 'share': {\n if (!deps.createShare) {\n chatLog.addSystem('Share is not available in this mode.');\n tui.requestRender();\n return;\n }\n const request = parseTuiShareRequest(commandArgs);\n if (!request) {\n chatLog.addSystem(\n [\n 'Usage: /share <workspace-path> [friend|colleague|public] [--site|--zip|--file]',\n 'Optional: --title \"Title\" --description \"Description\"',\n ].join('\\n'),\n );\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.createShare(request)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'btw':\n case 'aside': {\n const question = commandArgs.trim();\n if (!question) {\n chatLog.addSystem(\n 'Usage: /btw <question>\\nAnswers use the current session as read-only background and are not saved.',\n );\n tui.requestRender();\n return;\n }\n if (!deps.runBtwQuery) {\n chatLog.addSystem('/btw is not available in this mode.');\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.runBtwQuery(question)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'workflows':\n try {\n chatLog.addSystem(formatTuiWorkflowsInfo(createWorkflowCatalog().list()));\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Workflow list failed: ${errorMessage}`);\n }\n tui.requestRender();\n return;\n case 'workflow': {\n const [subcommandRaw, ...workflowRest] = commandArgs.trim().split(/\\s+/);\n const subcommand = (subcommandRaw || 'list').toLowerCase();\n if (subcommand === 'list' || subcommand === 'ls') {\n try {\n chatLog.addSystem(formatTuiWorkflowsInfo(createWorkflowCatalog().list()));\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Workflow list failed: ${errorMessage}`);\n }\n tui.requestRender();\n return;\n }\n if (subcommand === 'view' || subcommand === 'show') {\n const name = workflowRest[0]?.trim();\n if (!name) {\n chatLog.addSystem('Usage: /workflow view <name>');\n tui.requestRender();\n return;\n }\n try {\n chatLog.addSystem(formatTuiWorkflowDetail(name));\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Workflow view failed: ${errorMessage}`);\n }\n tui.requestRender();\n return;\n }\n if (subcommand === 'save') {\n chatLog.addSystem('/workflow save is available through the workflow tool after a generated workflow run.');\n tui.requestRender();\n return;\n }\n chatLog.addSystem('Usage: /workflow list | /workflow view <name> | /workflow save <name>');\n tui.requestRender();\n return;\n }\n case 'models':\n void Promise.resolve(deps.listModels?.() ?? []).then((models) => {\n chatLog.addSystem(formatTuiModelsInfo(models));\n tui.requestRender();\n });\n return;\n case 'model':\n if (uiOverlays) {\n uiOverlays.openModelPicker(commandArgs.trim() || undefined);\n return;\n }\n chatLog.addSystem('Model picker is not available in this mode. Use /models and /switch <provider/model>.');\n tui.requestRender();\n return;\n case 'list':\n void Promise.resolve(deps.listSessions?.() ?? []).then((sessions) => {\n chatLog.addSystem(\n formatTuiSessionListInfo(sessions, { currentSessionKey: state.currentSessionKey }),\n );\n tui.requestRender();\n });\n return;\n case 'tree':\n if (uiOverlays) {\n uiOverlays.openTranscriptTree();\n return;\n }\n if (deps.loadTranscriptTree) {\n void Promise.resolve(deps.loadTranscriptTree()).then((entries) => {\n chatLog.addSystem(formatTuiTranscriptTreeInfo(entries));\n tui.requestRender();\n });\n return;\n }\n uiOverlays?.openSessionTree();\n if (uiOverlays) return;\n void Promise.resolve(deps.listSessions?.() ?? []).then((sessions) => {\n chatLog.addSystem(\n formatTuiSessionTreeInfo(sessions, { currentSessionKey: state.currentSessionKey }),\n );\n tui.requestRender();\n });\n return;\n case 'switch': {\n const modelRef = commandArgs.trim();\n if (!modelRef) {\n chatLog.addSystem('Usage: /switch <provider/model>');\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.switchModel?.(modelRef)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'login':\n if (deps.runLogin && (!commandArgs.trim() || providerSupportsOAuth(commandArgs.trim()))) {\n void Promise.resolve(deps.runLogin(commandArgs.trim() || undefined))\n .catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Login failed: ${errorMessage}`);\n })\n .finally(() => tui.requestRender());\n return;\n }\n chatLog.addSystem(formatTuiLoginInfo(commandArgs));\n tui.requestRender();\n return;\n case 'logout': {\n const provider = commandArgs.trim();\n const authProfiles = deps.authProfiles ?? defaultAuthProfiles();\n void (async () => {\n try {\n if (!provider) {\n const profiles = await authProfiles.listAll();\n chatLog.addSystem(\n formatTuiStoredAuthProfilesInfo(profiles, { authStorePath: authProfiles.getStorePath() }),\n );\n tui.requestRender();\n return;\n }\n\n const profiles = await authProfiles.listProvider(provider);\n if (profiles.length === 0) {\n chatLog.addSystem(\n [\n `No stored auth profiles found for provider: ${provider}`,\n 'Environment variables and config credentials are unchanged.',\n ].join('\\n'),\n );\n tui.requestRender();\n return;\n }\n\n let removed = 0;\n for (const profile of profiles) {\n if (await authProfiles.remove(profile.profileId)) {\n removed += 1;\n }\n }\n chatLog.addSystem(\n [\n `Logged out from ${provider}: removed ${removed} stored auth profile${removed === 1 ? '' : 's'}.`,\n 'Environment variables and config credentials are unchanged.',\n ].join('\\n'),\n );\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Logout failed: ${errorMessage}`);\n }\n tui.requestRender();\n })();\n return;\n }\n case 'exit':\n case 'quit':\n requestExit();\n return;\n case 'abort':\n case 'stop':\n case 'cancel':\n void abortActive().then(() => {\n chatLog.addSystem('Aborted.');\n tui.requestRender();\n });\n return;\n case 'recover':\n void Promise.resolve(deps.recoverStream?.())\n .catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Recover failed: ${errorMessage}`);\n })\n .finally(() => tui.requestRender());\n return;\n case 'retry':\n void Promise.resolve(deps.retryLastMessage?.())\n .catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Retry failed: ${errorMessage}`);\n })\n .finally(() => tui.requestRender());\n return;\n case 'tools':\n state.toolsExpanded = !state.toolsExpanded;\n chatLog.setToolsExpanded(state.toolsExpanded);\n chatLog.addSystem(`Tools: ${state.toolsExpanded ? 'expanded' : 'collapsed'}`);\n tui.requestRender();\n return;\n case 'thinking':\n state.showThinking = !state.showThinking;\n chatLog.setShowThinking(state.showThinking);\n chatLog.addSystem(`Thinking display: ${state.showThinking ? 'on' : 'off'}`);\n updateFooter();\n tui.requestRender();\n return;\n case 'copy':\n void Promise.resolve(deps.copyLastAssistant?.()).then(() => {\n tui.requestRender();\n });\n return;\n case 'name': {\n const name = commandArgs.trim();\n if (!name) {\n const currentName = state.sessionInfo.displayName?.trim();\n chatLog.addSystem(currentName ? `Session name: ${currentName}` : 'Usage: /name <name>');\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.renameCurrentSession?.(name)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'resume':\n case 'sessions':\n uiOverlays?.openSessionPicker();\n return;\n case 'scoped-models':\n case 'scopedmodels':\n uiOverlays?.openScopedModels();\n return;\n case 'think': {\n const level = normalizeThinkLevel(commandArgs);\n if (!commandArgs.trim()) {\n uiOverlays?.openThinkingSelector();\n return;\n }\n if (!level) {\n chatLog.addSystem(`Invalid thinking level: ${commandArgs}`);\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.setThinkingLevel?.(level)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'reasoning': {\n const level = normalizeReasoningLevel(commandArgs);\n if (!commandArgs.trim()) {\n const current = state.sessionInfo.reasoningLevel?.trim();\n chatLog.addSystem(\n current\n ? `Reasoning visibility: ${current}`\n : 'Usage: /reasoning <off|on|stream>',\n );\n tui.requestRender();\n return;\n }\n if (!level) {\n chatLog.addSystem(`Invalid reasoning visibility: ${commandArgs}`);\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.setReasoningLevel?.(level)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'verbose': {\n const raw = commandArgs.trim();\n const level = raw ? normalizeVerboseLevel(raw) : nextVerboseLevel(state.sessionInfo.verboseLevel);\n if (raw && !level) {\n chatLog.addSystem(`Invalid verbose level: ${commandArgs}`);\n tui.requestRender();\n return;\n }\n void Promise.resolve(deps.setVerboseLevel?.(level)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'settings':\n uiOverlays?.openSettings();\n return;\n case 'reload':\n case 'reload-keybindings':\n case 'reload-keybind':\n void Promise.resolve(uiOverlays?.reloadKeybindings())\n .then(() => {\n chatLog.addSystem('Reloaded keybindings, TUI settings, theme, and extension UI.');\n tui.requestRender();\n })\n .catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`Reload failed: ${errorMessage}`);\n tui.requestRender();\n });\n return;\n case 'compact':\n void deps.runCompaction?.(commandArgs.trim() || undefined);\n return;\n default:\n break;\n }\n\n switch (normalizedCommand) {\n case 'new': {\n void (async () => {\n try {\n await abortActive();\n const uniqueKey = `tui-${randomUUID()}`;\n if (setSession) {\n await setSession(uniqueKey);\n chatLog.addSystem(`new session: ${state.currentSessionKey}`);\n } else {\n chatLog.clearAll();\n state.messageFollowUpQueue.length = 0;\n state.steeringQueue.length = 0;\n chatLog.addSystem('New session requires gateway or local session support.');\n }\n tui.requestRender();\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n chatLog.addSystem(`new session failed: ${errorMessage}`);\n tui.requestRender();\n }\n })();\n return;\n }\n case 'fork': {\n if (!commandArgs.trim() && uiOverlays) {\n uiOverlays.openUserMessageFork();\n return;\n }\n void Promise.resolve(deps.forkSession?.(commandArgs.trim() || undefined)).then(() => {\n tui.requestRender();\n });\n return;\n }\n case 'clone':\n void Promise.resolve(deps.forkSession?.(commandArgs.trim() || undefined)).then(() => {\n tui.requestRender();\n });\n return;\n case 'reset':\n case 'restart':\n void runReset();\n return;\n case 'clear':\n void runReset();\n return;\n default:\n break;\n }\n\n const extensionCmd = extensionSlashCommands.find((c) => c.name === normalizedCommand);\n if (extensionCmd) {\n void Promise.resolve(\n extensionCmd.handler(commandArgs, extensionCmd.getContext?.()),\n ).then(() => {\n tui.requestRender();\n });\n return;\n }\n\n // Unknown slash that names a known workflow → rewrite into a natural prompt\n // so the assistant deterministically calls workflow({name}) instead of\n // depending on the model to puzzle out \"/audit_repo\".\n if (input.trimStart().startsWith('/')) {\n const rewritten = rewriteUnknownSlashAsWorkflow(normalizedCommand, commandArgs);\n if (rewritten) {\n chatLog.addSystem(`▶ Running workflow: ${normalizedCommand}`);\n tui.requestRender();\n sendMessage(rewritten);\n return;\n }\n }\n\n sendMessage(input);\n };\n}\n"],"mappings":"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"}
|
|
@@ -52,7 +52,7 @@ function agentSelectItems(agents, currentAgentId) {
|
|
|
52
52
|
}).map((agent) => ({
|
|
53
53
|
label: agent.id === current ? `${agent.id} (current)` : agent.id,
|
|
54
54
|
value: agent.id,
|
|
55
|
-
description: agent.displayName
|
|
55
|
+
description: agent.displayName
|
|
56
56
|
}));
|
|
57
57
|
}
|
|
58
58
|
function formatSessionTreeOpenedHint(keybindings) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui-picker-overlay.js","names":[],"sources":["../../../src/tui/tui-picker-overlay.ts"],"sourcesContent":["import type { KeybindingsManager, SelectItem } from '@earendil-works/pi-tui';\n\nimport { ScopedModelsSelector } from './components/scoped-models-selector.js';\nimport { SettingsSelector } from './components/settings-selector.js';\nimport { SearchableSelectList } from './components/searchable-select-list.js';\nimport { SessionSelector } from './components/session-selector.js';\nimport { ThinkingSelector } from './components/thinking-selector.js';\nimport { formatKeyIds } from './format-tui-hotkeys.js';\nimport type { TuiAgentInfo, TuiSessionItem } from './tui-backend.js';\nimport type { PickerServices } from './tui-picker-services.js';\nimport { formatSessionPickerDescription } from './tui-session-format.js';\nimport { searchableSelectListTheme, theme } from './theme.js';\nimport { filterTuiTranscriptTreeEntries } from './tui-transcript-tree.js';\nimport {\n defaultTranscriptForkKey,\n formatTranscriptTreeFilterHint,\n formatUserMessageForkOpenedHint,\n TranscriptTreeSelectList,\n userMessageForkSelectItems,\n} from './tui-transcript-tree-picker.js';\nimport {\n listThinkingLevels,\n normalizeThinkLevel,\n type ThinkLevel,\n} from '../agent/transcript/thinking-types.js';\nimport { parseAgentSessionKey } from '../routing/agent-session-key.js';\nimport {\n getProjectTrustOptions,\n hasTrustRequiringProjectResources,\n} from '../project-trust/trust-store.js';\n\nfunction formatSelectNavigationHint(keybindings: KeybindingsManager): string {\n const up = formatKeyIds(keybindings, 'tui.select.up', { capitalize: true });\n const down = formatKeyIds(keybindings, 'tui.select.down', { capitalize: true });\n return `${up}/${down}`;\n}\n\nexport function formatScopedModelsOpenedHint(keybindings: KeybindingsManager): string {\n const modelCycle = formatKeyIds(keybindings, 'app.model.cycleForward', { capitalize: true });\n return `Scoped models for ${modelCycle}`;\n}\n\nexport function formatScopedModelsSavedHint(params: {\n refs: string[] | null;\n total: number;\n keybindings: KeybindingsManager;\n}): string {\n const modelCycle = formatKeyIds(params.keybindings, 'app.model.cycleForward', {\n capitalize: true,\n });\n if (params.refs === null) {\n return `${modelCycle} cycles all ${params.total} models`;\n }\n const count = params.refs.length;\n return `${modelCycle} cycles ${count} scoped model${count === 1 ? '' : 's'}`;\n}\n\nexport function formatSettingsOpenedHint(keybindings: KeybindingsManager): string {\n const nav = formatSelectNavigationHint(keybindings);\n const confirm = formatKeyIds(keybindings, 'tui.select.confirm', { capitalize: true });\n const cancel = formatKeyIds(keybindings, 'tui.select.cancel', { capitalize: true });\n return `Settings (${nav} · ${confirm} toggle · ${cancel} close)`;\n}\n\nexport function formatThinkingSelectorHint(keybindings: KeybindingsManager): string {\n const nav = formatSelectNavigationHint(keybindings);\n const confirm = formatKeyIds(keybindings, 'tui.select.confirm', { capitalize: true });\n const cancel = formatKeyIds(keybindings, 'tui.select.cancel', { capitalize: true });\n return `Thinking level (${nav} · ${confirm} select · ${cancel} close)`;\n}\n\nexport function formatThinkingLevelSavedHint(level: ThinkLevel): string {\n return `Thinking level: ${level}`;\n}\n\nexport function formatProjectTrustOpenedHint(keybindings: KeybindingsManager): string {\n const nav = formatSelectNavigationHint(keybindings);\n const confirm = formatKeyIds(keybindings, 'tui.select.confirm', { capitalize: true });\n const cancel = formatKeyIds(keybindings, 'tui.select.cancel', { capitalize: true });\n return `Project trust (${nav} · ${confirm} select · ${cancel} close)`;\n}\n\nexport function formatAgentPickerOpenedHint(keybindings: KeybindingsManager): string {\n const nav = formatSelectNavigationHint(keybindings);\n const confirm = formatKeyIds(keybindings, 'tui.select.confirm', { capitalize: true });\n const cancel = formatKeyIds(keybindings, 'tui.select.cancel', { capitalize: true });\n return `Switch agent (${nav} · ${confirm} select · ${cancel} close)`;\n}\n\nfunction agentSelectItems(agents: TuiAgentInfo[], currentAgentId?: string): SelectItem[] {\n const current = currentAgentId?.trim().toLowerCase();\n return [...agents]\n .filter((agent) => agent.enabled !== false)\n .sort((a, b) => {\n if (a.id === current && b.id !== current) return -1;\n if (b.id === current && a.id !== current) return 1;\n if (a.id === 'coder' && b.id !== 'coder') return -1;\n if (b.id === 'coder' && a.id !== 'coder') return 1;\n return a.id.localeCompare(b.id);\n })\n .map((agent) => ({\n label: agent.id === current ? `${agent.id} (current)` : agent.id,\n value: agent.id,\n description: agent.displayName\n ? `${agent.source} · ${agent.displayName}`\n : agent.source,\n }));\n}\n\nexport function formatSessionTreeOpenedHint(keybindings: KeybindingsManager): string {\n const nav = formatSelectNavigationHint(keybindings);\n const confirm = formatKeyIds(keybindings, 'tui.select.confirm', { capitalize: true });\n const cancel = formatKeyIds(keybindings, 'tui.select.cancel', { capitalize: true });\n return `Session tree (${nav} · type to filter · ${confirm} resume · ${cancel} close)`;\n}\n\nfunction resumeSession(svc: PickerServices, sessionKey: string): void {\n svc.setSessionKey(sessionKey);\n svc.clearChatForSessionSwitch();\n svc.chatLog.addSystem(`Session: ${sessionKey}`);\n void svc\n .refreshSessionInfo()\n .then(() => svc.loadSessionHistory())\n .then(() => {\n svc.updateHeader();\n svc.tui.requestRender();\n });\n svc.tui.requestRender();\n}\n\nfunction sessionTreeGroup(session: TuiSessionItem): { agentId: string; root: string; leaf: string } {\n const raw = session.key.trim();\n const parts = raw.split(':').filter(Boolean);\n if (parts.length >= 3 && parts[0] === 'agent') {\n const rest = parts.slice(2);\n return {\n agentId: parts[1] ?? 'main',\n root: rest[0] ?? raw,\n leaf: rest.length > 1 ? rest.slice(1).join(':') : rest.join(':') || raw,\n };\n }\n return { agentId: 'legacy', root: raw || 'session', leaf: raw || 'session' };\n}\n\nexport function sessionTreeSelectItems(\n sessions: TuiSessionItem[],\n currentSessionKey?: string,\n): SelectItem[] {\n const byKey = new Map(sessions.map((session) => [session.key, session]));\n return [...sessions]\n .sort((a, b) => {\n const ga = sessionTreeGroup(a);\n const gb = sessionTreeGroup(b);\n const groupCmp = `${ga.agentId}:${ga.root}`.localeCompare(`${gb.agentId}:${gb.root}`);\n if (groupCmp !== 0) return groupCmp;\n return (b.updatedAt ?? 0) - (a.updatedAt ?? 0);\n })\n .map((session) => {\n const group = sessionTreeGroup(session);\n const current = session.key === currentSessionKey ? '* ' : ' ';\n const label = session.displayName?.trim() || group.leaf;\n const parent = session.forkedFromSessionKey\n ? (byKey.get(session.forkedFromSessionKey)?.displayName?.trim() ?? session.forkedFromSessionKey)\n : null;\n const description = [\n `${group.agentId}/${group.root}`,\n formatSessionPickerDescription(session, { showKey: Boolean(session.displayName) }),\n parent ? `forked from ${parent}` : '',\n ]\n .filter(Boolean)\n .join(' · ');\n return {\n value: session.key,\n label: `${current}${label}`,\n description,\n searchText: `${session.key} ${session.displayName ?? ''} ${session.model ?? ''} ${parent ?? ''}`,\n };\n });\n}\n\n\n\n\n\nexport async function openAgentPickerOverlay(svc: PickerServices): Promise<void> {\n const parsed = parseAgentSessionKey(svc.state.currentSessionKey);\n if (!parsed) {\n svc.chatLog.addSystem('Cannot switch agent: current session is not an agent session.');\n svc.tui.requestRender();\n return;\n }\n if (svc.state.activeRunId) {\n svc.chatLog.addSystem('Cannot switch agent while a run is active. Abort first.');\n svc.tui.requestRender();\n return;\n }\n if (!svc.switchAgentSession) {\n svc.chatLog.addSystem('Agent switching is not available in this mode.');\n svc.tui.requestRender();\n return;\n }\n const agents = await svc.client.listAgents();\n const items = agentSelectItems(agents, parsed.agentId);\n if (items.length === 0) {\n svc.chatLog.addSystem('No agents available.');\n svc.tui.requestRender();\n return;\n }\n svc.chatLog.addSystem(theme.dim(formatAgentPickerOpenedHint(svc.keybindings)));\n const list = new SearchableSelectList(items, Math.min(10, items.length), searchableSelectListTheme, {\n searchPromptText: 'agent> ',\n });\n const closeSelector = svc.openEditorSelector(list, list);\n list.onSelect = (item) => {\n closeSelector();\n const targetAgentId = item.value;\n if (targetAgentId === parsed.agentId) {\n svc.chatLog.addSystem(`Already using agent: ${targetAgentId}`);\n svc.tui.requestRender();\n return;\n }\n const targetSessionKey = `agent:${targetAgentId}:${parsed.rest}`;\n void Promise.resolve(svc.switchAgentSession?.(targetSessionKey, targetAgentId))\n .then(() => {\n svc.chatLog.addSystem(`Switched to agent: ${targetAgentId}\\nSession: ${targetSessionKey}`);\n })\n .catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n svc.chatLog.addSystem(`Agent switch failed: ${errorMessage}`);\n })\n .finally(() => svc.tui.requestRender());\n svc.tui.requestRender();\n };\n list.onCancel = () => closeSelector();\n svc.tui.requestRender();\n}\n\n/** Ctrl+Shift+P — session picker with rename/delete. */\nexport async function openSessionPickerOverlay(svc: PickerServices): Promise<void> {\n const sessions = await svc.client.listSessions();\n if (sessions.length === 0) {\n svc.chatLog.addSystem('No sessions listed.');\n svc.tui.requestRender();\n return;\n }\n\n const selector = new SessionSelector(\n sessions,\n {\n onResume: (sessionKey) => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n resumeSession(svc, sessionKey);\n },\n onRename: async (sessionKey, name) => {\n const result = await svc.client.renameSession(sessionKey, name);\n return result.ok ? { ok: true } : { ok: false, error: 'Rename failed' };\n },\n onDelete: async (sessionKey) => {\n if (sessionKey === svc.state.currentSessionKey) {\n return { ok: false, error: 'Switch away before deleting the active session' };\n }\n const result = await svc.client.deleteSession(sessionKey);\n return result.ok ? { ok: true } : { ok: false, error: 'Delete failed' };\n },\n onCancel: () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n },\n requestRender: () => svc.tui.requestRender(),\n },\n svc.keybindings,\n sessions.find((s) => s.key === svc.state.currentSessionKey)?.cwd ?? process.cwd(),\n svc.state.currentSessionKey,\n );\n\n svc.openOverlay(selector);\n svc.chatLog.addSystem(theme.dim('Session picker'));\n svc.tui.requestRender();\n}\n\n/** Searchable session tree navigation overlay. */\nexport async function openSessionTreeOverlay(svc: PickerServices): Promise<void> {\n const sessions = await svc.client.listSessions();\n if (sessions.length === 0) {\n svc.chatLog.addSystem('No sessions listed.');\n svc.tui.requestRender();\n return;\n }\n\n const items = sessionTreeSelectItems(sessions, svc.state.currentSessionKey);\n const list = new SearchableSelectList(items, Math.min(14, items.length), searchableSelectListTheme);\n list.onSelect = (item) => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n resumeSession(svc, item.value);\n };\n list.onCancel = () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n };\n\n svc.openOverlay(list);\n svc.chatLog.addSystem(theme.dim(formatSessionTreeOpenedHint(svc.keybindings)));\n svc.tui.requestRender();\n}\n\n/** Searchable current-transcript tree overlay. */\nexport async function openTranscriptTreeOverlay(svc: PickerServices): Promise<void> {\n const entries = await svc.client.loadTranscriptTree(svc.state.currentSessionKey);\n const filterMode = svc.getTuiSettings().treeFilterMode;\n const visibleEntries = filterTuiTranscriptTreeEntries(entries, filterMode);\n if (visibleEntries.length === 0) {\n svc.chatLog.addSystem('No transcript entries found.');\n svc.tui.requestRender();\n return;\n }\n\n const byId = new Map(entries.map((entry) => [entry.id, entry]));\n const list = new TranscriptTreeSelectList(entries, filterMode, svc.keybindings, Math.min(16, visibleEntries.length));\n list.onSelect = (item) => {\n const entry = byId.get(item.value);\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n if (!entry) {\n svc.tui.requestRender();\n return;\n }\n const targetKey = defaultTranscriptForkKey(svc.state.currentSessionKey, entry.id);\n const sourceSessionKey = svc.state.currentSessionKey;\n svc.chatLog.addSystem(theme.dim(`Forking transcript at ${entry.id}...`));\n void svc.client\n .forkSessionAt(sourceSessionKey, targetKey, entry.id)\n .then((result) => {\n resumeSession(svc, result.sessionKey);\n svc.chatLog.addBranchSummary({\n sourceSessionKey,\n targetSessionKey: result.sessionKey,\n rowCount: result.rowCount,\n entryId: entry.id,\n });\n })\n .catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n svc.chatLog.addSystem(`Fork failed: ${errorMessage}`);\n svc.tui.requestRender();\n });\n svc.tui.requestRender();\n };\n list.onCancel = () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n };\n list.onFilterChange = (mode) => {\n svc.chatLog.addSystem(theme.dim(`Transcript tree filter: ${mode}`));\n svc.tui.requestRender();\n };\n list.onLabelSubmit = (entry, label) => {\n void svc.client\n .setTranscriptLabel(svc.state.currentSessionKey, entry.id, label)\n .then(() => {\n list.updateEntryLabel(entry.id, label);\n svc.chatLog.addSystem(\n theme.dim(label?.trim() ? `Labeled ${entry.id}: ${label.trim()}` : `Cleared label for ${entry.id}`),\n );\n svc.tui.requestRender();\n })\n .catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n svc.chatLog.addSystem(`Label failed: ${errorMessage}`);\n svc.tui.requestRender();\n });\n };\n\n svc.openOverlay(list);\n svc.chatLog.addSystem(theme.dim(formatTranscriptTreeFilterHint(svc.keybindings, filterMode)));\n svc.tui.requestRender();\n}\n\n/** Pi-style `/fork` overlay: select a previous user message and branch there. */\nexport async function openUserMessageForkOverlay(svc: PickerServices): Promise<void> {\n const entries = await svc.client.loadTranscriptTree(svc.state.currentSessionKey);\n const byId = new Map(entries.map((entry) => [entry.id, entry]));\n const items = userMessageForkSelectItems(entries);\n if (items.length === 0) {\n svc.chatLog.addSystem('No messages to fork from.');\n svc.tui.requestRender();\n return;\n }\n\n const list = new SearchableSelectList(items, Math.min(10, items.length), searchableSelectListTheme, {\n wrapNavigation: true,\n });\n list.setSelectedIndex(items.length - 1);\n list.onSelect = (item) => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n const entry = byId.get(item.value);\n const targetKey = defaultTranscriptForkKey(svc.state.currentSessionKey, item.value);\n const sourceSessionKey = svc.state.currentSessionKey;\n svc.chatLog.addSystem(theme.dim(`Forking from ${item.value}...`));\n void svc.client\n .forkSessionAt(sourceSessionKey, targetKey, item.value)\n .then((result) => {\n resumeSession(svc, result.sessionKey);\n if (entry?.contentText) {\n svc.setEditorText(entry.contentText);\n }\n svc.chatLog.addBranchSummary({\n sourceSessionKey,\n targetSessionKey: result.sessionKey,\n rowCount: result.rowCount,\n entryId: item.value,\n restoredText: entry?.contentText,\n });\n })\n .catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n svc.chatLog.addSystem(`Fork failed: ${errorMessage}`);\n svc.tui.requestRender();\n });\n svc.tui.requestRender();\n };\n list.onCancel = () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n };\n\n svc.openOverlay(list);\n svc.chatLog.addSystem(theme.dim(formatUserMessageForkOpenedHint(svc.keybindings)));\n svc.tui.requestRender();\n}\n\n/** `/scoped-models` — limit Ctrl+P model cycle set. */\nexport async function openScopedModelsOverlay(svc: PickerServices): Promise<void> {\n const catalog = await svc.client.listModels();\n svc.setModelChoices(catalog);\n if (catalog.length === 0) {\n svc.chatLog.addSystem('No models available.');\n svc.tui.requestRender();\n return;\n }\n\n const selector = new ScopedModelsSelector(\n catalog,\n svc.getScopedModelRefs(),\n {\n onSave: (refs) => {\n svc.setScopedModelRefs(refs);\n svc.refreshCycleModels();\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.chatLog.addSystem(\n theme.dim(formatScopedModelsSavedHint({\n refs,\n total: catalog.length,\n keybindings: svc.keybindings,\n })),\n );\n svc.tui.requestRender();\n },\n onCancel: () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n },\n requestRender: () => svc.tui.requestRender(),\n },\n svc.keybindings,\n );\n\n svc.openOverlay(selector);\n svc.chatLog.addSystem(theme.dim(formatScopedModelsOpenedHint(svc.keybindings)));\n svc.tui.requestRender();\n}\n\n/** `/settings` — TUI preferences overlay. */\nexport function openSettingsOverlay(svc: PickerServices): void {\n const selector = new SettingsSelector(svc.getTuiSettings(), {\n onChange: (settings) => svc.applyTuiSettings(settings),\n onThemePreview: (themeId) => svc.previewTheme(themeId),\n onReloadKeybindings: () => svc.reloadKeybindings(),\n onCancel: () => {\n svc.previewTheme(svc.getTuiSettings().theme);\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n },\n });\n\n svc.openOverlay(selector);\n svc.chatLog.addSystem(theme.dim(formatSettingsOpenedHint(svc.keybindings)));\n svc.tui.requestRender();\n}\n\n/** `/think` — select and persist the current session thinking level. */\nexport function openThinkingSelectorOverlay(svc: PickerServices): void {\n const current = normalizeThinkLevel(svc.state.sessionInfo.thinkingLevel) ?? 'medium';\n const levels = listThinkingLevels(\n svc.state.sessionInfo.modelProvider,\n svc.state.sessionInfo.model,\n ).map((level) => (level === 'on' ? 'low' : level)) as ThinkLevel[];\n const uniqueLevels = [...new Set(levels)];\n\n const selector = new ThinkingSelector(current, uniqueLevels, {\n onSelect: (level) => {\n void svc.setThinkingLevel(level).then(() => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n });\n },\n onCancel: () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n },\n }, svc.keybindings);\n\n svc.openOverlay(selector);\n svc.chatLog.addSystem(theme.dim(formatThinkingSelectorHint(svc.keybindings)));\n svc.tui.requestRender();\n}\n\nexport function openProjectTrustOverlay(svc: PickerServices): void {\n const cwd = process.cwd();\n const trustStore = svc.getProjectTrustStore();\n const currentStored = trustStore.getEntry(cwd);\n const sessionDecision = svc.getProjectTrustSessionDecision();\n const hasProjectResources = hasTrustRequiringProjectResources(cwd);\n const options = getProjectTrustOptions(cwd, { includeSessionOnly: true });\n const optionsByLabel = new Map(options.map((option) => [option.label, option]));\n const items: SelectItem[] = options.map((option) => ({\n value: option.label,\n label: option.label,\n description: option.savedPath ?? 'Current TUI session only',\n }));\n const list = new SearchableSelectList(items, Math.min(8, items.length), searchableSelectListTheme, {\n searchPromptText: 'trust: ',\n });\n\n list.onSelect = (item) => {\n const selected = optionsByLabel.get(item.value);\n if (!selected) return;\n if (selected.updates.length > 0) {\n trustStore.setMany(selected.updates);\n svc.setProjectTrustSessionDecision(null);\n } else {\n svc.setProjectTrustSessionDecision(selected.trusted);\n }\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n const scope = selected.savedPath ? `saved for ${selected.savedPath}` : 'this session only';\n svc.chatLog.addSystem(theme.dim(`Project trust: ${selected.trusted ? 'trusted' : 'not trusted'} (${scope})`));\n svc.tui.requestRender();\n };\n list.onCancel = () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n };\n\n svc.openOverlay(list);\n const storedLabel = currentStored\n ? `${currentStored.decision ? 'trusted' : 'not trusted'} from ${currentStored.path}`\n : 'not saved';\n const sessionLabel = sessionDecision === null ? 'none' : sessionDecision ? 'trusted' : 'not trusted';\n svc.chatLog.addSystem(\n theme.dim(\n [\n formatProjectTrustOpenedHint(svc.keybindings),\n `Project resources: ${hasProjectResources ? 'detected' : 'none detected'}`,\n `Stored: ${storedLabel}`,\n `Session: ${sessionLabel}`,\n ].join('\\n'),\n ),\n );\n svc.tui.requestRender();\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tui-picker-overlay.js","names":[],"sources":["../../../src/tui/tui-picker-overlay.ts"],"sourcesContent":["import type { KeybindingsManager, SelectItem } from '@earendil-works/pi-tui';\n\nimport { ScopedModelsSelector } from './components/scoped-models-selector.js';\nimport { SettingsSelector } from './components/settings-selector.js';\nimport { SearchableSelectList } from './components/searchable-select-list.js';\nimport { SessionSelector } from './components/session-selector.js';\nimport { ThinkingSelector } from './components/thinking-selector.js';\nimport { formatKeyIds } from './format-tui-hotkeys.js';\nimport type { TuiAgentInfo, TuiSessionItem } from './tui-backend.js';\nimport type { PickerServices } from './tui-picker-services.js';\nimport { formatSessionPickerDescription } from './tui-session-format.js';\nimport { searchableSelectListTheme, theme } from './theme.js';\nimport { filterTuiTranscriptTreeEntries } from './tui-transcript-tree.js';\nimport {\n defaultTranscriptForkKey,\n formatTranscriptTreeFilterHint,\n formatUserMessageForkOpenedHint,\n TranscriptTreeSelectList,\n userMessageForkSelectItems,\n} from './tui-transcript-tree-picker.js';\nimport {\n listThinkingLevels,\n normalizeThinkLevel,\n type ThinkLevel,\n} from '../agent/transcript/thinking-types.js';\nimport { parseAgentSessionKey } from '../routing/agent-session-key.js';\nimport {\n getProjectTrustOptions,\n hasTrustRequiringProjectResources,\n} from '../project-trust/trust-store.js';\n\nfunction formatSelectNavigationHint(keybindings: KeybindingsManager): string {\n const up = formatKeyIds(keybindings, 'tui.select.up', { capitalize: true });\n const down = formatKeyIds(keybindings, 'tui.select.down', { capitalize: true });\n return `${up}/${down}`;\n}\n\nexport function formatScopedModelsOpenedHint(keybindings: KeybindingsManager): string {\n const modelCycle = formatKeyIds(keybindings, 'app.model.cycleForward', { capitalize: true });\n return `Scoped models for ${modelCycle}`;\n}\n\nexport function formatScopedModelsSavedHint(params: {\n refs: string[] | null;\n total: number;\n keybindings: KeybindingsManager;\n}): string {\n const modelCycle = formatKeyIds(params.keybindings, 'app.model.cycleForward', {\n capitalize: true,\n });\n if (params.refs === null) {\n return `${modelCycle} cycles all ${params.total} models`;\n }\n const count = params.refs.length;\n return `${modelCycle} cycles ${count} scoped model${count === 1 ? '' : 's'}`;\n}\n\nexport function formatSettingsOpenedHint(keybindings: KeybindingsManager): string {\n const nav = formatSelectNavigationHint(keybindings);\n const confirm = formatKeyIds(keybindings, 'tui.select.confirm', { capitalize: true });\n const cancel = formatKeyIds(keybindings, 'tui.select.cancel', { capitalize: true });\n return `Settings (${nav} · ${confirm} toggle · ${cancel} close)`;\n}\n\nexport function formatThinkingSelectorHint(keybindings: KeybindingsManager): string {\n const nav = formatSelectNavigationHint(keybindings);\n const confirm = formatKeyIds(keybindings, 'tui.select.confirm', { capitalize: true });\n const cancel = formatKeyIds(keybindings, 'tui.select.cancel', { capitalize: true });\n return `Thinking level (${nav} · ${confirm} select · ${cancel} close)`;\n}\n\nexport function formatThinkingLevelSavedHint(level: ThinkLevel): string {\n return `Thinking level: ${level}`;\n}\n\nexport function formatProjectTrustOpenedHint(keybindings: KeybindingsManager): string {\n const nav = formatSelectNavigationHint(keybindings);\n const confirm = formatKeyIds(keybindings, 'tui.select.confirm', { capitalize: true });\n const cancel = formatKeyIds(keybindings, 'tui.select.cancel', { capitalize: true });\n return `Project trust (${nav} · ${confirm} select · ${cancel} close)`;\n}\n\nexport function formatAgentPickerOpenedHint(keybindings: KeybindingsManager): string {\n const nav = formatSelectNavigationHint(keybindings);\n const confirm = formatKeyIds(keybindings, 'tui.select.confirm', { capitalize: true });\n const cancel = formatKeyIds(keybindings, 'tui.select.cancel', { capitalize: true });\n return `Switch agent (${nav} · ${confirm} select · ${cancel} close)`;\n}\n\nfunction agentSelectItems(agents: TuiAgentInfo[], currentAgentId?: string): SelectItem[] {\n const current = currentAgentId?.trim().toLowerCase();\n return [...agents]\n .filter((agent) => agent.enabled !== false)\n .sort((a, b) => {\n if (a.id === current && b.id !== current) return -1;\n if (b.id === current && a.id !== current) return 1;\n if (a.id === 'coder' && b.id !== 'coder') return -1;\n if (b.id === 'coder' && a.id !== 'coder') return 1;\n return a.id.localeCompare(b.id);\n })\n .map((agent) => ({\n label: agent.id === current ? `${agent.id} (current)` : agent.id,\n value: agent.id,\n description: agent.displayName,\n }));\n}\n\nexport function formatSessionTreeOpenedHint(keybindings: KeybindingsManager): string {\n const nav = formatSelectNavigationHint(keybindings);\n const confirm = formatKeyIds(keybindings, 'tui.select.confirm', { capitalize: true });\n const cancel = formatKeyIds(keybindings, 'tui.select.cancel', { capitalize: true });\n return `Session tree (${nav} · type to filter · ${confirm} resume · ${cancel} close)`;\n}\n\nfunction resumeSession(svc: PickerServices, sessionKey: string): void {\n svc.setSessionKey(sessionKey);\n svc.clearChatForSessionSwitch();\n svc.chatLog.addSystem(`Session: ${sessionKey}`);\n void svc\n .refreshSessionInfo()\n .then(() => svc.loadSessionHistory())\n .then(() => {\n svc.updateHeader();\n svc.tui.requestRender();\n });\n svc.tui.requestRender();\n}\n\nfunction sessionTreeGroup(session: TuiSessionItem): { agentId: string; root: string; leaf: string } {\n const raw = session.key.trim();\n const parts = raw.split(':').filter(Boolean);\n if (parts.length >= 3 && parts[0] === 'agent') {\n const rest = parts.slice(2);\n return {\n agentId: parts[1] ?? 'main',\n root: rest[0] ?? raw,\n leaf: rest.length > 1 ? rest.slice(1).join(':') : rest.join(':') || raw,\n };\n }\n return { agentId: 'legacy', root: raw || 'session', leaf: raw || 'session' };\n}\n\nexport function sessionTreeSelectItems(\n sessions: TuiSessionItem[],\n currentSessionKey?: string,\n): SelectItem[] {\n const byKey = new Map(sessions.map((session) => [session.key, session]));\n return [...sessions]\n .sort((a, b) => {\n const ga = sessionTreeGroup(a);\n const gb = sessionTreeGroup(b);\n const groupCmp = `${ga.agentId}:${ga.root}`.localeCompare(`${gb.agentId}:${gb.root}`);\n if (groupCmp !== 0) return groupCmp;\n return (b.updatedAt ?? 0) - (a.updatedAt ?? 0);\n })\n .map((session) => {\n const group = sessionTreeGroup(session);\n const current = session.key === currentSessionKey ? '* ' : ' ';\n const label = session.displayName?.trim() || group.leaf;\n const parent = session.forkedFromSessionKey\n ? (byKey.get(session.forkedFromSessionKey)?.displayName?.trim() ?? session.forkedFromSessionKey)\n : null;\n const description = [\n `${group.agentId}/${group.root}`,\n formatSessionPickerDescription(session, { showKey: Boolean(session.displayName) }),\n parent ? `forked from ${parent}` : '',\n ]\n .filter(Boolean)\n .join(' · ');\n return {\n value: session.key,\n label: `${current}${label}`,\n description,\n searchText: `${session.key} ${session.displayName ?? ''} ${session.model ?? ''} ${parent ?? ''}`,\n };\n });\n}\n\n\n\n\n\nexport async function openAgentPickerOverlay(svc: PickerServices): Promise<void> {\n const parsed = parseAgentSessionKey(svc.state.currentSessionKey);\n if (!parsed) {\n svc.chatLog.addSystem('Cannot switch agent: current session is not an agent session.');\n svc.tui.requestRender();\n return;\n }\n if (svc.state.activeRunId) {\n svc.chatLog.addSystem('Cannot switch agent while a run is active. Abort first.');\n svc.tui.requestRender();\n return;\n }\n if (!svc.switchAgentSession) {\n svc.chatLog.addSystem('Agent switching is not available in this mode.');\n svc.tui.requestRender();\n return;\n }\n const agents = await svc.client.listAgents();\n const items = agentSelectItems(agents, parsed.agentId);\n if (items.length === 0) {\n svc.chatLog.addSystem('No agents available.');\n svc.tui.requestRender();\n return;\n }\n svc.chatLog.addSystem(theme.dim(formatAgentPickerOpenedHint(svc.keybindings)));\n const list = new SearchableSelectList(items, Math.min(10, items.length), searchableSelectListTheme, {\n searchPromptText: 'agent> ',\n });\n const closeSelector = svc.openEditorSelector(list, list);\n list.onSelect = (item) => {\n closeSelector();\n const targetAgentId = item.value;\n if (targetAgentId === parsed.agentId) {\n svc.chatLog.addSystem(`Already using agent: ${targetAgentId}`);\n svc.tui.requestRender();\n return;\n }\n const targetSessionKey = `agent:${targetAgentId}:${parsed.rest}`;\n void Promise.resolve(svc.switchAgentSession?.(targetSessionKey, targetAgentId))\n .then(() => {\n svc.chatLog.addSystem(`Switched to agent: ${targetAgentId}\\nSession: ${targetSessionKey}`);\n })\n .catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n svc.chatLog.addSystem(`Agent switch failed: ${errorMessage}`);\n })\n .finally(() => svc.tui.requestRender());\n svc.tui.requestRender();\n };\n list.onCancel = () => closeSelector();\n svc.tui.requestRender();\n}\n\n/** Ctrl+Shift+P — session picker with rename/delete. */\nexport async function openSessionPickerOverlay(svc: PickerServices): Promise<void> {\n const sessions = await svc.client.listSessions();\n if (sessions.length === 0) {\n svc.chatLog.addSystem('No sessions listed.');\n svc.tui.requestRender();\n return;\n }\n\n const selector = new SessionSelector(\n sessions,\n {\n onResume: (sessionKey) => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n resumeSession(svc, sessionKey);\n },\n onRename: async (sessionKey, name) => {\n const result = await svc.client.renameSession(sessionKey, name);\n return result.ok ? { ok: true } : { ok: false, error: 'Rename failed' };\n },\n onDelete: async (sessionKey) => {\n if (sessionKey === svc.state.currentSessionKey) {\n return { ok: false, error: 'Switch away before deleting the active session' };\n }\n const result = await svc.client.deleteSession(sessionKey);\n return result.ok ? { ok: true } : { ok: false, error: 'Delete failed' };\n },\n onCancel: () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n },\n requestRender: () => svc.tui.requestRender(),\n },\n svc.keybindings,\n sessions.find((s) => s.key === svc.state.currentSessionKey)?.cwd ?? process.cwd(),\n svc.state.currentSessionKey,\n );\n\n svc.openOverlay(selector);\n svc.chatLog.addSystem(theme.dim('Session picker'));\n svc.tui.requestRender();\n}\n\n/** Searchable session tree navigation overlay. */\nexport async function openSessionTreeOverlay(svc: PickerServices): Promise<void> {\n const sessions = await svc.client.listSessions();\n if (sessions.length === 0) {\n svc.chatLog.addSystem('No sessions listed.');\n svc.tui.requestRender();\n return;\n }\n\n const items = sessionTreeSelectItems(sessions, svc.state.currentSessionKey);\n const list = new SearchableSelectList(items, Math.min(14, items.length), searchableSelectListTheme);\n list.onSelect = (item) => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n resumeSession(svc, item.value);\n };\n list.onCancel = () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n };\n\n svc.openOverlay(list);\n svc.chatLog.addSystem(theme.dim(formatSessionTreeOpenedHint(svc.keybindings)));\n svc.tui.requestRender();\n}\n\n/** Searchable current-transcript tree overlay. */\nexport async function openTranscriptTreeOverlay(svc: PickerServices): Promise<void> {\n const entries = await svc.client.loadTranscriptTree(svc.state.currentSessionKey);\n const filterMode = svc.getTuiSettings().treeFilterMode;\n const visibleEntries = filterTuiTranscriptTreeEntries(entries, filterMode);\n if (visibleEntries.length === 0) {\n svc.chatLog.addSystem('No transcript entries found.');\n svc.tui.requestRender();\n return;\n }\n\n const byId = new Map(entries.map((entry) => [entry.id, entry]));\n const list = new TranscriptTreeSelectList(entries, filterMode, svc.keybindings, Math.min(16, visibleEntries.length));\n list.onSelect = (item) => {\n const entry = byId.get(item.value);\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n if (!entry) {\n svc.tui.requestRender();\n return;\n }\n const targetKey = defaultTranscriptForkKey(svc.state.currentSessionKey, entry.id);\n const sourceSessionKey = svc.state.currentSessionKey;\n svc.chatLog.addSystem(theme.dim(`Forking transcript at ${entry.id}...`));\n void svc.client\n .forkSessionAt(sourceSessionKey, targetKey, entry.id)\n .then((result) => {\n resumeSession(svc, result.sessionKey);\n svc.chatLog.addBranchSummary({\n sourceSessionKey,\n targetSessionKey: result.sessionKey,\n rowCount: result.rowCount,\n entryId: entry.id,\n });\n })\n .catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n svc.chatLog.addSystem(`Fork failed: ${errorMessage}`);\n svc.tui.requestRender();\n });\n svc.tui.requestRender();\n };\n list.onCancel = () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n };\n list.onFilterChange = (mode) => {\n svc.chatLog.addSystem(theme.dim(`Transcript tree filter: ${mode}`));\n svc.tui.requestRender();\n };\n list.onLabelSubmit = (entry, label) => {\n void svc.client\n .setTranscriptLabel(svc.state.currentSessionKey, entry.id, label)\n .then(() => {\n list.updateEntryLabel(entry.id, label);\n svc.chatLog.addSystem(\n theme.dim(label?.trim() ? `Labeled ${entry.id}: ${label.trim()}` : `Cleared label for ${entry.id}`),\n );\n svc.tui.requestRender();\n })\n .catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n svc.chatLog.addSystem(`Label failed: ${errorMessage}`);\n svc.tui.requestRender();\n });\n };\n\n svc.openOverlay(list);\n svc.chatLog.addSystem(theme.dim(formatTranscriptTreeFilterHint(svc.keybindings, filterMode)));\n svc.tui.requestRender();\n}\n\n/** Pi-style `/fork` overlay: select a previous user message and branch there. */\nexport async function openUserMessageForkOverlay(svc: PickerServices): Promise<void> {\n const entries = await svc.client.loadTranscriptTree(svc.state.currentSessionKey);\n const byId = new Map(entries.map((entry) => [entry.id, entry]));\n const items = userMessageForkSelectItems(entries);\n if (items.length === 0) {\n svc.chatLog.addSystem('No messages to fork from.');\n svc.tui.requestRender();\n return;\n }\n\n const list = new SearchableSelectList(items, Math.min(10, items.length), searchableSelectListTheme, {\n wrapNavigation: true,\n });\n list.setSelectedIndex(items.length - 1);\n list.onSelect = (item) => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n const entry = byId.get(item.value);\n const targetKey = defaultTranscriptForkKey(svc.state.currentSessionKey, item.value);\n const sourceSessionKey = svc.state.currentSessionKey;\n svc.chatLog.addSystem(theme.dim(`Forking from ${item.value}...`));\n void svc.client\n .forkSessionAt(sourceSessionKey, targetKey, item.value)\n .then((result) => {\n resumeSession(svc, result.sessionKey);\n if (entry?.contentText) {\n svc.setEditorText(entry.contentText);\n }\n svc.chatLog.addBranchSummary({\n sourceSessionKey,\n targetSessionKey: result.sessionKey,\n rowCount: result.rowCount,\n entryId: item.value,\n restoredText: entry?.contentText,\n });\n })\n .catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n svc.chatLog.addSystem(`Fork failed: ${errorMessage}`);\n svc.tui.requestRender();\n });\n svc.tui.requestRender();\n };\n list.onCancel = () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n };\n\n svc.openOverlay(list);\n svc.chatLog.addSystem(theme.dim(formatUserMessageForkOpenedHint(svc.keybindings)));\n svc.tui.requestRender();\n}\n\n/** `/scoped-models` — limit Ctrl+P model cycle set. */\nexport async function openScopedModelsOverlay(svc: PickerServices): Promise<void> {\n const catalog = await svc.client.listModels();\n svc.setModelChoices(catalog);\n if (catalog.length === 0) {\n svc.chatLog.addSystem('No models available.');\n svc.tui.requestRender();\n return;\n }\n\n const selector = new ScopedModelsSelector(\n catalog,\n svc.getScopedModelRefs(),\n {\n onSave: (refs) => {\n svc.setScopedModelRefs(refs);\n svc.refreshCycleModels();\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.chatLog.addSystem(\n theme.dim(formatScopedModelsSavedHint({\n refs,\n total: catalog.length,\n keybindings: svc.keybindings,\n })),\n );\n svc.tui.requestRender();\n },\n onCancel: () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n },\n requestRender: () => svc.tui.requestRender(),\n },\n svc.keybindings,\n );\n\n svc.openOverlay(selector);\n svc.chatLog.addSystem(theme.dim(formatScopedModelsOpenedHint(svc.keybindings)));\n svc.tui.requestRender();\n}\n\n/** `/settings` — TUI preferences overlay. */\nexport function openSettingsOverlay(svc: PickerServices): void {\n const selector = new SettingsSelector(svc.getTuiSettings(), {\n onChange: (settings) => svc.applyTuiSettings(settings),\n onThemePreview: (themeId) => svc.previewTheme(themeId),\n onReloadKeybindings: () => svc.reloadKeybindings(),\n onCancel: () => {\n svc.previewTheme(svc.getTuiSettings().theme);\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n },\n });\n\n svc.openOverlay(selector);\n svc.chatLog.addSystem(theme.dim(formatSettingsOpenedHint(svc.keybindings)));\n svc.tui.requestRender();\n}\n\n/** `/think` — select and persist the current session thinking level. */\nexport function openThinkingSelectorOverlay(svc: PickerServices): void {\n const current = normalizeThinkLevel(svc.state.sessionInfo.thinkingLevel) ?? 'medium';\n const levels = listThinkingLevels(\n svc.state.sessionInfo.modelProvider,\n svc.state.sessionInfo.model,\n ).map((level) => (level === 'on' ? 'low' : level)) as ThinkLevel[];\n const uniqueLevels = [...new Set(levels)];\n\n const selector = new ThinkingSelector(current, uniqueLevels, {\n onSelect: (level) => {\n void svc.setThinkingLevel(level).then(() => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n });\n },\n onCancel: () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n },\n }, svc.keybindings);\n\n svc.openOverlay(selector);\n svc.chatLog.addSystem(theme.dim(formatThinkingSelectorHint(svc.keybindings)));\n svc.tui.requestRender();\n}\n\nexport function openProjectTrustOverlay(svc: PickerServices): void {\n const cwd = process.cwd();\n const trustStore = svc.getProjectTrustStore();\n const currentStored = trustStore.getEntry(cwd);\n const sessionDecision = svc.getProjectTrustSessionDecision();\n const hasProjectResources = hasTrustRequiringProjectResources(cwd);\n const options = getProjectTrustOptions(cwd, { includeSessionOnly: true });\n const optionsByLabel = new Map(options.map((option) => [option.label, option]));\n const items: SelectItem[] = options.map((option) => ({\n value: option.label,\n label: option.label,\n description: option.savedPath ?? 'Current TUI session only',\n }));\n const list = new SearchableSelectList(items, Math.min(8, items.length), searchableSelectListTheme, {\n searchPromptText: 'trust: ',\n });\n\n list.onSelect = (item) => {\n const selected = optionsByLabel.get(item.value);\n if (!selected) return;\n if (selected.updates.length > 0) {\n trustStore.setMany(selected.updates);\n svc.setProjectTrustSessionDecision(null);\n } else {\n svc.setProjectTrustSessionDecision(selected.trusted);\n }\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n const scope = selected.savedPath ? `saved for ${selected.savedPath}` : 'this session only';\n svc.chatLog.addSystem(theme.dim(`Project trust: ${selected.trusted ? 'trusted' : 'not trusted'} (${scope})`));\n svc.tui.requestRender();\n };\n list.onCancel = () => {\n svc.closeOverlay();\n svc.tui.setFocus(svc.editor);\n svc.tui.requestRender();\n };\n\n svc.openOverlay(list);\n const storedLabel = currentStored\n ? `${currentStored.decision ? 'trusted' : 'not trusted'} from ${currentStored.path}`\n : 'not saved';\n const sessionLabel = sessionDecision === null ? 'none' : sessionDecision ? 'trusted' : 'not trusted';\n svc.chatLog.addSystem(\n theme.dim(\n [\n formatProjectTrustOpenedHint(svc.keybindings),\n `Project resources: ${hasProjectResources ? 'detected' : 'none detected'}`,\n `Stored: ${storedLabel}`,\n `Session: ${sessionLabel}`,\n ].join('\\n'),\n ),\n );\n svc.tui.requestRender();\n}\n"],"mappings":"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"}
|
|
@@ -11,5 +11,6 @@ export interface WorkflowDefinitionBuildInput {
|
|
|
11
11
|
manifest?: WorkflowDefinitionManifest;
|
|
12
12
|
}
|
|
13
13
|
export declare function buildWorkflowDefinition(input: WorkflowDefinitionBuildInput): WorkflowDefinition;
|
|
14
|
+
export declare function hashWorkflowStableValue(value: unknown): string;
|
|
14
15
|
export declare function normalizeWorkflowDefinitionId(value: string): string;
|
|
15
16
|
export declare function toWorkflowDefinitionTitle(value: string): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
1
2
|
//#region src/workflows/domain/definition-utils.ts
|
|
2
3
|
const DEFAULT_WORKFLOW_CONCURRENCY = 4;
|
|
3
4
|
const DEFAULT_WORKFLOW_TIMEOUT_SEC = 1800;
|
|
@@ -11,7 +12,8 @@ function buildWorkflowDefinition(input) {
|
|
|
11
12
|
})) ?? [];
|
|
12
13
|
const manifest = input.manifest;
|
|
13
14
|
const manifestDefaults = manifest?.defaults ?? {};
|
|
14
|
-
|
|
15
|
+
const runtimeHash = hashWorkflowStableValue(input.script);
|
|
16
|
+
const base = {
|
|
15
17
|
id: input.name,
|
|
16
18
|
name: input.name,
|
|
17
19
|
title: manifest?.title ?? toWorkflowDefinitionTitle(input.name),
|
|
@@ -43,6 +45,34 @@ function buildWorkflowDefinition(input) {
|
|
|
43
45
|
updatedAtMs: nowMs
|
|
44
46
|
}
|
|
45
47
|
};
|
|
48
|
+
return {
|
|
49
|
+
...base,
|
|
50
|
+
runtimeHash,
|
|
51
|
+
contentHash: hashWorkflowStableValue({
|
|
52
|
+
id: base.id,
|
|
53
|
+
name: base.name,
|
|
54
|
+
title: base.title,
|
|
55
|
+
description: base.description,
|
|
56
|
+
version: base.version,
|
|
57
|
+
inputSchema: base.inputSchema,
|
|
58
|
+
outputSchema: base.outputSchema,
|
|
59
|
+
phases: base.phases,
|
|
60
|
+
runtimeHash,
|
|
61
|
+
defaults: base.defaults,
|
|
62
|
+
permissions: base.permissions,
|
|
63
|
+
resources: base.resources,
|
|
64
|
+
tags: base.metadata.tags
|
|
65
|
+
})
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function hashWorkflowStableValue(value) {
|
|
69
|
+
return createHash("sha256").update(stableStringify(value)).digest("hex");
|
|
70
|
+
}
|
|
71
|
+
function stableStringify(value) {
|
|
72
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
73
|
+
if (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(",")}]`;
|
|
74
|
+
const record = value;
|
|
75
|
+
return `{${Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`).join(",")}}`;
|
|
46
76
|
}
|
|
47
77
|
function normalizePositiveInt(value, fallback) {
|
|
48
78
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 1) return fallback;
|
|
@@ -55,6 +85,6 @@ function toWorkflowDefinitionTitle(value) {
|
|
|
55
85
|
return value.split(/[_-]+/g).filter(Boolean).map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`).join(" ");
|
|
56
86
|
}
|
|
57
87
|
//#endregion
|
|
58
|
-
export { DEFAULT_WORKFLOW_CONCURRENCY, DEFAULT_WORKFLOW_MAX_SUBAGENTS, DEFAULT_WORKFLOW_TIMEOUT_SEC, buildWorkflowDefinition, normalizeWorkflowDefinitionId, toWorkflowDefinitionTitle };
|
|
88
|
+
export { DEFAULT_WORKFLOW_CONCURRENCY, DEFAULT_WORKFLOW_MAX_SUBAGENTS, DEFAULT_WORKFLOW_TIMEOUT_SEC, buildWorkflowDefinition, hashWorkflowStableValue, normalizeWorkflowDefinitionId, toWorkflowDefinitionTitle };
|
|
59
89
|
|
|
60
90
|
//# sourceMappingURL=definition-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition-utils.js","names":[],"sources":["../../../../src/workflows/domain/definition-utils.ts"],"sourcesContent":["import type { WorkflowMeta } from '../../agent/workflow/types.js';\n\nimport type { WorkflowDefinition, WorkflowDefinitionManifest } from './definition.js';\n\nexport const DEFAULT_WORKFLOW_CONCURRENCY = 4;\nexport const DEFAULT_WORKFLOW_TIMEOUT_SEC = 30 * 60;\nexport const DEFAULT_WORKFLOW_MAX_SUBAGENTS = 100;\n\nexport interface WorkflowDefinitionBuildInput {\n name: string;\n source: 'builtin' | 'user';\n script: string;\n meta: WorkflowMeta;\n manifest?: WorkflowDefinitionManifest;\n}\n\nexport function buildWorkflowDefinition(input: WorkflowDefinitionBuildInput): WorkflowDefinition {\n const nowMs = Date.now();\n const phases = input.meta.phases?.map((phase, index) => ({\n id: normalizeWorkflowDefinitionId(phase.title) || `phase-${index + 1}`,\n title: phase.title,\n description: phase.detail,\n })) ?? [];\n\n const manifest = input.manifest;\n const manifestDefaults = manifest?.defaults ?? {};\n\n
|
|
1
|
+
{"version":3,"file":"definition-utils.js","names":[],"sources":["../../../../src/workflows/domain/definition-utils.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\nimport type { WorkflowMeta } from '../../agent/workflow/types.js';\n\nimport type { WorkflowDefinition, WorkflowDefinitionManifest } from './definition.js';\n\nexport const DEFAULT_WORKFLOW_CONCURRENCY = 4;\nexport const DEFAULT_WORKFLOW_TIMEOUT_SEC = 30 * 60;\nexport const DEFAULT_WORKFLOW_MAX_SUBAGENTS = 100;\n\nexport interface WorkflowDefinitionBuildInput {\n name: string;\n source: 'builtin' | 'user';\n script: string;\n meta: WorkflowMeta;\n manifest?: WorkflowDefinitionManifest;\n}\n\nexport function buildWorkflowDefinition(input: WorkflowDefinitionBuildInput): WorkflowDefinition {\n const nowMs = Date.now();\n const phases = input.meta.phases?.map((phase, index) => ({\n id: normalizeWorkflowDefinitionId(phase.title) || `phase-${index + 1}`,\n title: phase.title,\n description: phase.detail,\n })) ?? [];\n\n const manifest = input.manifest;\n const manifestDefaults = manifest?.defaults ?? {};\n\n const runtimeHash = hashWorkflowStableValue(input.script);\n const base = {\n id: input.name,\n name: input.name,\n title: manifest?.title ?? toWorkflowDefinitionTitle(input.name),\n description: manifest?.description ?? input.meta.description,\n version: manifest?.version ?? '1.0.0',\n inputSchema: manifest?.inputSchema,\n outputSchema: manifest?.outputSchema,\n phases,\n runtime: {\n kind: 'script' as const,\n source: input.script,\n },\n defaults: {\n concurrency: normalizePositiveInt(manifestDefaults.concurrency, DEFAULT_WORKFLOW_CONCURRENCY),\n timeoutSec: normalizePositiveInt(manifestDefaults.timeoutSec, DEFAULT_WORKFLOW_TIMEOUT_SEC),\n maxSubagents: normalizePositiveInt(\n manifestDefaults.maxSubagents,\n input.meta.estimatedAgents?.max ?? DEFAULT_WORKFLOW_MAX_SUBAGENTS,\n ),\n },\n permissions: manifest?.permissions,\n resources: manifest?.resources,\n metadata: {\n tags: manifest?.tags ?? input.meta.tags ?? [],\n builtIn: input.source === 'builtin',\n source: input.source,\n whenToUse: manifest?.whenToUse ?? input.meta.whenToUse,\n estimatedAgents: input.meta.estimatedAgents,\n examplePrompts: input.meta.examplePrompts,\n i18n: input.meta.i18n,\n createdAtMs: nowMs,\n updatedAtMs: nowMs,\n },\n };\n\n return {\n ...base,\n runtimeHash,\n contentHash: hashWorkflowStableValue({\n id: base.id,\n name: base.name,\n title: base.title,\n description: base.description,\n version: base.version,\n inputSchema: base.inputSchema,\n outputSchema: base.outputSchema,\n phases: base.phases,\n runtimeHash,\n defaults: base.defaults,\n permissions: base.permissions,\n resources: base.resources,\n tags: base.metadata.tags,\n }),\n };\n}\n\nexport function hashWorkflowStableValue(value: unknown): string {\n return createHash('sha256').update(stableStringify(value)).digest('hex');\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(',')}]`;\n const record = value as Record<string, unknown>;\n return `{${Object.keys(record)\n .filter((key) => record[key] !== undefined)\n .sort()\n .map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`)\n .join(',')}}`;\n}\n\nfunction normalizePositiveInt(value: number | undefined, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 1) {\n return fallback;\n }\n return Math.floor(value);\n}\n\nexport function normalizeWorkflowDefinitionId(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nexport function toWorkflowDefinitionTitle(value: string): string {\n return value\n .split(/[_-]+/g)\n .filter(Boolean)\n .map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)\n .join(' ');\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { WorkflowArtifactRef, WorkflowResultEnvelope } from './result.js';
|
|
2
|
-
import type { WorkflowRun, WorkflowRunError } from './run.js';
|
|
2
|
+
import type { WorkflowAgentInvocationSnapshot, WorkflowRun, WorkflowRunError } from './run.js';
|
|
3
3
|
export type WorkflowEventType = 'run_queued' | 'run_started' | 'phase_started' | 'phase_completed' | 'agent_queued' | 'agent_started' | 'agent_step_started' | 'agent_step_completed' | 'agent_completed' | 'log_appended' | 'artifact_created' | 'run_completed' | 'run_failed' | 'run_cancelled';
|
|
4
4
|
export interface WorkflowEventEnvelope<T = WorkflowEventPayload> {
|
|
5
5
|
id: string;
|
|
@@ -29,6 +29,7 @@ export interface AgentQueuedPayload {
|
|
|
29
29
|
phaseId?: string;
|
|
30
30
|
prompt?: string;
|
|
31
31
|
sessionKey: string;
|
|
32
|
+
invocation?: WorkflowAgentInvocationSnapshot;
|
|
32
33
|
}
|
|
33
34
|
export interface AgentStartedPayload {
|
|
34
35
|
agentId: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { DEFAULT_WORKFLOW_CONCURRENCY, DEFAULT_WORKFLOW_MAX_SUBAGENTS, DEFAULT_WORKFLOW_TIMEOUT_SEC, buildWorkflowDefinition, normalizeWorkflowDefinitionId, toWorkflowDefinitionTitle } from "./definition-utils.js";
|
|
1
|
+
import { DEFAULT_WORKFLOW_CONCURRENCY, DEFAULT_WORKFLOW_MAX_SUBAGENTS, DEFAULT_WORKFLOW_TIMEOUT_SEC, buildWorkflowDefinition, hashWorkflowStableValue, normalizeWorkflowDefinitionId, toWorkflowDefinitionTitle } from "./definition-utils.js";
|
|
2
2
|
import { isTerminalWorkflowRunStatus } from "./run.js";
|
|
3
3
|
import { validateWorkflowDefinitionInput } from "./validation.js";
|
|
4
|
-
|
|
4
|
+
import { validateWorkflowJsonSchema } from "./schema-validation.js";
|
|
5
|
+
export { DEFAULT_WORKFLOW_CONCURRENCY, DEFAULT_WORKFLOW_MAX_SUBAGENTS, DEFAULT_WORKFLOW_TIMEOUT_SEC, buildWorkflowDefinition, hashWorkflowStableValue, isTerminalWorkflowRunStatus, normalizeWorkflowDefinitionId, toWorkflowDefinitionTitle, validateWorkflowDefinitionInput, validateWorkflowJsonSchema };
|