@deepseek-harness-tui/dsh-tui 0.15.0 → 0.16.1
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/README.md +98 -8
- package/guide/dsh-tui-guide/claude-backend.en.md +8 -0
- package/guide/dsh-tui-guide/claude-backend.md +5 -0
- package/guide/dsh-tui-guide/codex-backend.en.md +13 -3
- package/guide/dsh-tui-guide/codex-backend.md +9 -2
- package/guide/dsh-tui-guide/configuration.en.md +39 -2
- package/guide/dsh-tui-guide/configuration.md +34 -2
- package/guide/dsh-tui-guide/getting-started.en.md +32 -9
- package/guide/dsh-tui-guide/getting-started.md +27 -8
- package/guide/dsh-tui-guide/interaction.en.md +8 -1
- package/guide/dsh-tui-guide/interaction.md +8 -1
- package/guide/dsh-tui-guide/plugins.en.md +66 -5
- package/guide/dsh-tui-guide/plugins.md +37 -3
- package/guide/dsh-tui-guide/user-guide.en.md +3 -2
- package/guide/dsh-tui-guide/user-guide.md +3 -2
- package/lib/settings.json +1 -1
- package/lib/types/adapter/channel/projection.d.ts.map +1 -1
- package/lib/types/adapter/channel/projection.js +1 -0
- package/lib/types/adapter/channel/ui-policy.d.ts +1 -1
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
- package/lib/types/adapter/channel/ui-policy.js +1 -0
- package/lib/types/adapter/ports/channel-catalog.d.ts +5 -1
- package/lib/types/adapter/ports/channel-catalog.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-settings.d.ts +5 -3
- package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-ui.d.ts +7 -1
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-view.d.ts +47 -0
- package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel.d.ts +2 -0
- package/lib/types/adapter/ports/channel.d.ts.map +1 -1
- package/lib/types/agent/events.d.ts +3 -2
- package/lib/types/agent/events.d.ts.map +1 -1
- package/lib/types/backends/codex/contract.d.ts +3 -0
- package/lib/types/backends/codex/contract.d.ts.map +1 -1
- package/lib/types/backends/codex/contract.js +3 -0
- package/lib/types/backends/codex/session/async-questions.d.ts +17 -0
- package/lib/types/backends/codex/session/async-questions.d.ts.map +1 -0
- package/lib/types/backends/codex/session/async-questions.js +89 -0
- package/lib/types/backends/codex/session/session.d.ts.map +1 -1
- package/lib/types/backends/codex/session/session.js +35 -9
- package/lib/types/backends/codex/text.d.ts +3 -3
- package/lib/types/backends/codex/text.js +1 -1
- package/lib/types/backends/codex/translate/items.d.ts.map +1 -1
- package/lib/types/backends/codex/translate/items.js +3 -1
- package/lib/types/backends/codex/translate/question-reply.d.ts +11 -0
- package/lib/types/backends/codex/translate/question-reply.d.ts.map +1 -0
- package/lib/types/backends/codex/translate/question-reply.js +53 -0
- package/lib/types/channel/projection.d.ts.map +1 -1
- package/lib/types/channel/projection.js +10 -0
- package/lib/types/commands.d.ts +10 -0
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +11 -2
- package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
- package/lib/types/components/CommandSuggestions.js +4 -1
- package/lib/types/components/LogoV2.d.ts +4 -1
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +5 -3
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +95 -14
- package/lib/types/components/PermissionsPicker.d.ts +10 -1
- package/lib/types/components/PermissionsPicker.d.ts.map +1 -1
- package/lib/types/components/PermissionsPicker.js +24 -16
- package/lib/types/components/PluginInstallPane.d.ts +21 -0
- package/lib/types/components/PluginInstallPane.d.ts.map +1 -0
- package/lib/types/components/PluginInstallPane.js +84 -0
- package/lib/types/components/PluginManagePane.d.ts +21 -0
- package/lib/types/components/PluginManagePane.d.ts.map +1 -0
- package/lib/types/components/PluginManagePane.js +69 -0
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +7 -3
- package/lib/types/components/SubagentCard.d.ts +13 -1
- package/lib/types/components/SubagentCard.d.ts.map +1 -1
- package/lib/types/components/SubagentCard.js +27 -12
- package/lib/types/components/SubagentDashboard.d.ts +8 -1
- package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
- package/lib/types/components/SubagentDashboard.js +58 -16
- package/lib/types/components/launchpadLayout.d.ts +14 -1
- package/lib/types/components/launchpadLayout.d.ts.map +1 -1
- package/lib/types/components/launchpadLayout.js +36 -17
- package/lib/types/components/messages/TeamMessageBubble.d.ts +20 -0
- package/lib/types/components/messages/TeamMessageBubble.d.ts.map +1 -0
- package/lib/types/components/messages/TeamMessageBubble.js +15 -0
- package/lib/types/components/sidePanel/PanelHost.d.ts.map +1 -1
- package/lib/types/components/sidePanel/PanelHost.js +5 -1
- package/lib/types/components/sidePanel/PanelStore.d.ts +8 -0
- package/lib/types/components/sidePanel/PanelStore.d.ts.map +1 -1
- package/lib/types/components/sidePanel/PanelStore.js +11 -0
- package/lib/types/components/sidePanel/SidePanelColumn.d.ts.map +1 -1
- package/lib/types/components/sidePanel/SidePanelColumn.js +13 -1
- package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts +7 -0
- package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts.map +1 -1
- package/lib/types/components/sidePanel/SidePanelRuntimeContext.js +4 -0
- package/lib/types/components/sidePanel/btw/BtwComposer.d.ts +3 -0
- package/lib/types/components/sidePanel/btw/BtwComposer.d.ts.map +1 -1
- package/lib/types/components/sidePanel/btw/BtwComposer.js +20 -8
- package/lib/types/components/sidePanel/btw/BtwPanelAdapter.d.ts +2 -1
- package/lib/types/components/sidePanel/btw/BtwPanelAdapter.d.ts.map +1 -1
- package/lib/types/components/sidePanel/btw/BtwPanelAdapter.js +104 -13
- package/lib/types/components/sidePanel/btw/BtwThreadScene.d.ts +6 -2
- package/lib/types/components/sidePanel/btw/BtwThreadScene.d.ts.map +1 -1
- package/lib/types/components/sidePanel/btw/BtwThreadScene.js +61 -15
- package/lib/types/components/sidePanel/btw/BtwThreadView.d.ts +14 -4
- package/lib/types/components/sidePanel/btw/BtwThreadView.d.ts.map +1 -1
- package/lib/types/components/sidePanel/btw/BtwThreadView.js +90 -5
- package/lib/types/components/sidePanel/btw/threads.d.ts +18 -0
- package/lib/types/components/sidePanel/btw/threads.d.ts.map +1 -1
- package/lib/types/components/sidePanel/btw/threads.js +51 -0
- package/lib/types/components/sidePanel/builtinPanels.d.ts.map +1 -1
- package/lib/types/components/sidePanel/builtinPanels.js +5 -1
- package/lib/types/components/sidePanel/companion/SplashMascot.d.ts +5 -1
- package/lib/types/components/sidePanel/companion/SplashMascot.d.ts.map +1 -1
- package/lib/types/components/sidePanel/companion/SplashMascot.js +19 -4
- package/lib/types/components/sidePanel/companion/skins.d.ts +8 -0
- package/lib/types/components/sidePanel/companion/skins.d.ts.map +1 -1
- package/lib/types/components/sidePanel/companion/skins.js +57 -12
- package/lib/types/components/sidePanel/types.d.ts +6 -0
- package/lib/types/components/sidePanel/types.d.ts.map +1 -1
- package/lib/types/components/splashArtRows.d.ts +29 -0
- package/lib/types/components/splashArtRows.d.ts.map +1 -0
- package/lib/types/components/splashArtRows.js +31 -0
- package/lib/types/components/teamRoster.d.ts +70 -0
- package/lib/types/components/teamRoster.d.ts.map +1 -0
- package/lib/types/components/teamRoster.js +78 -0
- package/lib/types/dsh-adapter/admission-loader.d.ts +82 -0
- package/lib/types/dsh-adapter/admission-loader.d.ts.map +1 -1
- package/lib/types/dsh-adapter/admission-loader.js +73 -28
- package/lib/types/dsh-adapter/agent-view.d.ts.map +1 -1
- package/lib/types/dsh-adapter/agent-view.js +3 -1
- package/lib/types/dsh-adapter/approvals.d.ts +7 -0
- package/lib/types/dsh-adapter/approvals.d.ts.map +1 -1
- package/lib/types/dsh-adapter/approvals.js +45 -1
- package/lib/types/dsh-adapter/backend/translate.d.ts.map +1 -1
- package/lib/types/dsh-adapter/backend/translate.js +68 -8
- package/lib/types/dsh-adapter/backend-assembly.d.ts +31 -0
- package/lib/types/dsh-adapter/backend-assembly.d.ts.map +1 -0
- package/lib/types/dsh-adapter/backend-assembly.js +225 -0
- package/lib/types/dsh-adapter/backend-contribution.d.ts +36 -0
- package/lib/types/dsh-adapter/backend-contribution.d.ts.map +1 -1
- package/lib/types/dsh-adapter/backend-contribution.js +41 -0
- package/lib/types/dsh-adapter/backend-registry.d.ts.map +1 -1
- package/lib/types/dsh-adapter/backend-registry.js +22 -3
- package/lib/types/dsh-adapter/backends.d.ts.map +1 -1
- package/lib/types/dsh-adapter/backends.js +4 -5
- package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -1
- package/lib/types/dsh-adapter/bundled-presets.js +60 -3
- package/lib/types/dsh-adapter/channel/binding-events.d.ts +1 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/binding-events.js +1 -0
- package/lib/types/dsh-adapter/channel/command-completions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/command-completions.js +64 -7
- package/lib/types/dsh-adapter/channel/compaction.d.ts +7 -2
- package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/compaction.js +100 -26
- package/lib/types/dsh-adapter/channel/core/binding-feed.d.ts +3 -0
- package/lib/types/dsh-adapter/channel/core/binding-feed.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/core/binding-feed.js +2 -1
- package/lib/types/dsh-adapter/channel/core/compose.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/core/compose.js +12 -0
- package/lib/types/dsh-adapter/channel/extensions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/extensions.js +68 -8
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts +6 -0
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/mode-permission-actions.js +104 -12
- package/lib/types/dsh-adapter/channel/model-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/model-actions.js +8 -1
- package/lib/types/dsh-adapter/channel/permissions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/permissions.js +4 -1
- package/lib/types/dsh-adapter/channel/projection-helpers.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/projection-helpers.js +2 -0
- package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-metadata.js +4 -3
- package/lib/types/dsh-adapter/channel/session-reset.js +2 -2
- package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-resume.js +7 -0
- package/lib/types/dsh-adapter/channel/settings-host.d.ts +3 -0
- package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/settings-host.js +135 -5
- package/lib/types/dsh-adapter/channel/state.d.ts +6 -0
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.js +18 -6
- package/lib/types/dsh-adapter/channel/transcript.d.ts +7 -0
- package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/transcript.js +19 -2
- package/lib/types/dsh-adapter/compat/agent-team-0.2.0.d.ts +55 -0
- package/lib/types/dsh-adapter/compat/agent-team-0.2.0.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/agent-team-0.2.0.js +96 -0
- package/lib/types/dsh-adapter/contract.d.ts +4 -4
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +5 -5
- package/lib/types/dsh-adapter/effect-ledger.d.ts +7 -0
- package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
- package/lib/types/dsh-adapter/effect-ledger.js +8 -1
- package/lib/types/dsh-adapter/entry-slot.d.ts +3 -1
- package/lib/types/dsh-adapter/entry-slot.d.ts.map +1 -1
- package/lib/types/dsh-adapter/entry-slot.js +2 -2
- package/lib/types/dsh-adapter/fresh-agent.d.ts.map +1 -1
- package/lib/types/dsh-adapter/fresh-agent.js +6 -1
- package/lib/types/dsh-adapter/host-access.d.ts.map +1 -1
- package/lib/types/dsh-adapter/host-access.js +99 -0
- package/lib/types/dsh-adapter/host-contract.d.ts +1 -1
- package/lib/types/dsh-adapter/host-contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/host-contract.js +4 -3
- package/lib/types/dsh-adapter/host-dsh.d.ts +8 -2
- package/lib/types/dsh-adapter/host-dsh.d.ts.map +1 -1
- package/lib/types/dsh-adapter/host-dsh.js +45 -30
- package/lib/types/dsh-adapter/host-entry.js +40 -13
- package/lib/types/dsh-adapter/index.d.ts +9 -10
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +8 -6
- package/lib/types/dsh-adapter/install/pnpm-profile-add.d.ts.map +1 -1
- package/lib/types/dsh-adapter/install/pnpm-profile-add.js +9 -3
- package/lib/types/dsh-adapter/invariant.d.ts +7 -2
- package/lib/types/dsh-adapter/invariant.d.ts.map +1 -1
- package/lib/types/dsh-adapter/invariant.js +6 -3
- package/lib/types/dsh-adapter/migrate/index.js +2 -2
- package/lib/types/dsh-adapter/panels.d.ts.map +1 -1
- package/lib/types/dsh-adapter/panels.js +6 -0
- package/lib/types/dsh-adapter/plugin-declaration.d.ts +99 -1
- package/lib/types/dsh-adapter/plugin-declaration.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-declaration.js +132 -2
- package/lib/types/dsh-adapter/plugin-feed.d.ts +94 -0
- package/lib/types/dsh-adapter/plugin-feed.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-feed.js +135 -0
- package/lib/types/dsh-adapter/plugin-guard.d.ts +115 -0
- package/lib/types/dsh-adapter/plugin-guard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-guard.js +108 -0
- package/lib/types/dsh-adapter/plugin-install.d.ts +160 -0
- package/lib/types/dsh-adapter/plugin-install.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-install.js +545 -0
- package/lib/types/dsh-adapter/plugin-manage.d.ts +178 -0
- package/lib/types/dsh-adapter/plugin-manage.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-manage.js +468 -0
- package/lib/types/dsh-adapter/plugin-manager.d.ts +78 -2
- package/lib/types/dsh-adapter/plugin-manager.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-manager.js +32 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +49 -2
- package/lib/types/dsh-adapter/plugins-info.d.ts +87 -1
- package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugins-info.js +131 -26
- package/lib/types/dsh-adapter/process-exit.d.ts +1 -1
- package/lib/types/dsh-adapter/process-exit.d.ts.map +1 -1
- package/lib/types/dsh-adapter/process-exit.js +1 -1
- package/lib/types/dsh-adapter/session-projection-store.d.ts +66 -0
- package/lib/types/dsh-adapter/session-projection-store.d.ts.map +1 -0
- package/lib/types/dsh-adapter/session-projection-store.js +149 -0
- package/lib/types/dsh-adapter/settingsEditor.js +2 -2
- package/lib/types/dsh-adapter/sideQuestion.d.ts +21 -0
- package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sideQuestion.js +53 -0
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
- package/lib/types/dsh-adapter/subagents.js +2 -1
- package/lib/types/dsh-adapter/team-mode.d.ts +74 -0
- package/lib/types/dsh-adapter/team-mode.d.ts.map +1 -0
- package/lib/types/dsh-adapter/team-mode.js +188 -0
- package/lib/types/dsh-adapter/team-roster.d.ts +67 -0
- package/lib/types/dsh-adapter/team-roster.d.ts.map +1 -0
- package/lib/types/dsh-adapter/team-roster.js +136 -0
- package/lib/types/dsh-adapter/team-tools.d.ts +58 -0
- package/lib/types/dsh-adapter/team-tools.d.ts.map +1 -0
- package/lib/types/dsh-adapter/team-tools.js +208 -0
- package/lib/types/dsh-adapter/types.d.ts +1 -1
- package/lib/types/dsh-adapter/types.d.ts.map +1 -1
- package/lib/types/i18n.d.ts +607 -16
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +295 -9
- package/lib/types/ink/components/ScrollBox.d.ts +9 -0
- package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
- package/lib/types/ink/components/ScrollBox.js +23 -0
- package/lib/types/ink/dom.d.ts.map +1 -1
- package/lib/types/kernelPrefs.d.ts +1 -1
- package/lib/types/kernelPrefs.d.ts.map +1 -1
- package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -1
- package/lib/types/native-ts/yoga-layout/index.js +8 -1
- package/lib/types/permissionPresetLabels.d.ts +25 -0
- package/lib/types/permissionPresetLabels.d.ts.map +1 -0
- package/lib/types/permissionPresetLabels.js +33 -0
- package/lib/types/preset-patch.d.ts +22 -0
- package/lib/types/preset-patch.d.ts.map +1 -0
- package/lib/types/preset-patch.js +14 -0
- package/lib/types/screens/Chat.d.ts +33 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +301 -9
- package/lib/types/screens/Launchpad.d.ts +7 -1
- package/lib/types/screens/Launchpad.d.ts.map +1 -1
- package/lib/types/screens/Launchpad.js +19 -4
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/Settings.js +1 -0
- package/lib/types/screens/chat/usePluginWriteFlow.d.ts +68 -0
- package/lib/types/screens/chat/usePluginWriteFlow.d.ts.map +1 -0
- package/lib/types/screens/chat/usePluginWriteFlow.js +92 -0
- package/lib/types/screens/chatOverlay.d.ts +19 -1
- package/lib/types/screens/chatOverlay.d.ts.map +1 -1
- package/lib/types/sessionModes.d.ts +5 -3
- package/lib/types/sessionModes.d.ts.map +1 -1
- package/lib/types/sessionModes.js +9 -3
- package/lib/types/tips.js +2 -2
- package/lib/types/update.d.ts +31 -22
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +85 -42
- package/lib/types/utils/paths.d.ts +11 -0
- package/lib/types/utils/paths.d.ts.map +1 -1
- package/lib/types/utils/paths.js +13 -0
- package/package.json +126 -120
- package/tui-profile/feed/README.md +63 -0
- package/tui-profile/feed/first-party.json +10 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PluginInstallStep } from '../dsh-adapter/plugin-install.js';
|
|
3
|
+
/**
|
|
4
|
+
* `/plugin install <spec>`: the pane that asks what the flow cannot answer on
|
|
5
|
+
* its own (Stage C-4).
|
|
6
|
+
*
|
|
7
|
+
* The flow (`dsh-adapter/plugin-install.ts`) writes every line of the install
|
|
8
|
+
* into the transcript as it happens — the inspection, pnpm's phases, the result
|
|
9
|
+
* — so this pane only carries the two things a person must decide before that:
|
|
10
|
+
* gate 1's pre-install notice and gate 3's trust confirmation. It also renders
|
|
11
|
+
* the two "decide and retry" steps (unapproved build scripts, an incompatible
|
|
12
|
+
* version), which are the same kind of question.
|
|
13
|
+
*
|
|
14
|
+
* Presentational only: the step state lives in Chat, keys are handled there
|
|
15
|
+
* (Enter confirms / retries, Esc cancels), exactly like the SDK install wizard.
|
|
16
|
+
*/
|
|
17
|
+
export declare function PluginInstallPane({ step, busy }: {
|
|
18
|
+
step: PluginInstallStep;
|
|
19
|
+
busy: boolean;
|
|
20
|
+
}): React.ReactNode;
|
|
21
|
+
//# sourceMappingURL=PluginInstallPane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginInstallPane.d.ts","sourceRoot":"","sources":["../../../src/components/PluginInstallPane.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,iBAAiB,EAAqB,MAAM,kCAAkC,CAAA;AAqB5F;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,KAAK,CAAC,SAAS,CAgF7G"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { t } from '../i18n.js';
|
|
3
|
+
import { Box, Text } from '../ui.js';
|
|
4
|
+
import { cleanRenderText, NOTICE_CELLS } from '../channel/sanitize.js';
|
|
5
|
+
import { HintLine } from './design-system/HintLine.js';
|
|
6
|
+
import { LoadingState } from './design-system/LoadingState.js';
|
|
7
|
+
import { Pane } from './design-system/Pane.js';
|
|
8
|
+
/** Foreign text on its way to the screen: control sequences stripped, bounded. */
|
|
9
|
+
const clean = (value) => cleanRenderText(value, NOTICE_CELLS);
|
|
10
|
+
/**
|
|
11
|
+
* The target's identity is the subject of the confirmation, and it is foreign
|
|
12
|
+
* text like everything else here: the name comes from the package's own
|
|
13
|
+
* manifest, so it can carry newlines or thousands of cells. Bounded to what a
|
|
14
|
+
* line can show — at 50 columns an unbounded name buries the title and the key
|
|
15
|
+
* hints, which are exactly what the person needs to answer the question.
|
|
16
|
+
*/
|
|
17
|
+
const TARGET_CELLS = 80;
|
|
18
|
+
/**
|
|
19
|
+
* `/plugin install <spec>`: the pane that asks what the flow cannot answer on
|
|
20
|
+
* its own (Stage C-4).
|
|
21
|
+
*
|
|
22
|
+
* The flow (`dsh-adapter/plugin-install.ts`) writes every line of the install
|
|
23
|
+
* into the transcript as it happens — the inspection, pnpm's phases, the result
|
|
24
|
+
* — so this pane only carries the two things a person must decide before that:
|
|
25
|
+
* gate 1's pre-install notice and gate 3's trust confirmation. It also renders
|
|
26
|
+
* the two "decide and retry" steps (unapproved build scripts, an incompatible
|
|
27
|
+
* version), which are the same kind of question.
|
|
28
|
+
*
|
|
29
|
+
* Presentational only: the step state lives in Chat, keys are handled there
|
|
30
|
+
* (Enter confirms / retries, Esc cancels), exactly like the SDK install wizard.
|
|
31
|
+
*/
|
|
32
|
+
export function PluginInstallPane({ step, busy }) {
|
|
33
|
+
if (busy) {
|
|
34
|
+
return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "remember", bold: true, children: t('plugins-install-pane-title') }), _jsx(Box, { marginTop: 1, children: _jsx(LoadingState, { message: t('plugins-install-installing') }) })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('plugins-install-key-cancel') }) })] }));
|
|
35
|
+
}
|
|
36
|
+
if (step.kind === 'confirm') {
|
|
37
|
+
const { artifact, trust, notice } = step;
|
|
38
|
+
const spec = artifact.name === undefined
|
|
39
|
+
? t('plugins-install-unidentified')
|
|
40
|
+
: cleanRenderText(`${artifact.name}${artifact.version === undefined ? '' : `@${artifact.version}`}`, TARGET_CELLS);
|
|
41
|
+
return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: t('plugins-install-pane-title') }) }), _jsx(Text, { children: t('plugins-install-configure', {
|
|
42
|
+
spec,
|
|
43
|
+
kind: artifact.kind,
|
|
44
|
+
bundle: artifact.bundle === true ? 'bundle' : artifact.bundle === false ? 'not a bundle' : 'unknown',
|
|
45
|
+
}) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [trust.kind === 'third-party' && _jsx(Text, { children: t('plugins-install-trust-third-party') }), notice.kind === 'declared' && _jsx(Text, { dimColor: true, children: t('plugins-install-notice-declared') }), notice.kind === 'undeclared' && _jsx(Text, { children: t('plugins-install-notice-undeclared') }), notice.kind === 'invalid' && _jsx(Text, { children: t('plugins-install-notice-invalid', { err: notice.error }) }), notice.kind === 'unjudged' && _jsx(Text, { children: t('plugins-install-notice-unjudged') })] })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('plugins-install-key-confirm') }) })] }));
|
|
46
|
+
}
|
|
47
|
+
if (step.kind === 'build-blocked') {
|
|
48
|
+
return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "remember", bold: true, children: t('plugins-install-pane-title') }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { children: t('plugins-install-builds-title') }), step.builds.map(build => _jsx(Text, { dimColor: true, children: ` ${clean(build)}` }, build))] })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('plugins-install-key-builds') }) })] }));
|
|
49
|
+
}
|
|
50
|
+
if (step.kind === 'incompatible') {
|
|
51
|
+
return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "remember", bold: true, children: t('plugins-install-pane-title') }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { children: t('plugins-install-incompatible-title') }), step.packages.map(entry => _jsx(Text, { dimColor: true, children: describe(entry) }, `${entry.name}@${entry.version}`))] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { children: t('plugins-install-exemptions-title') }), exemptionLines(step.exemptions).map((line, index) => _jsx(Text, { dimColor: true, children: line }, index))] })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('plugins-install-key-incompatible') }) })] }));
|
|
52
|
+
}
|
|
53
|
+
// `done` never renders: its lines are already in the transcript, so Chat
|
|
54
|
+
// closes the pane instead of leaving an empty box behind.
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* One package the running host refuses, with the peers it fails.
|
|
59
|
+
*
|
|
60
|
+
* Every field here is foreign text — a package name, a version, a peer range
|
|
61
|
+
* the author wrote — and the pane is a render path like any other, so each one
|
|
62
|
+
* goes through the same sanitizer the rest of the interface uses before it can
|
|
63
|
+
* reach the screen.
|
|
64
|
+
*/
|
|
65
|
+
function describe(entry) {
|
|
66
|
+
const peers = Object.entries(entry.peers)
|
|
67
|
+
.map(([name, range]) => `${clean(name)} ${clean(range)}`)
|
|
68
|
+
.join(', ');
|
|
69
|
+
return ` ${clean(entry.name)}@${clean(entry.version)} (running ${clean(entry.runtimeVersion)}${peers === '' ? '' : `; needs ${peers}`})`;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The profile's compatibility file as rows. The file maps `package@version` to
|
|
73
|
+
* the runtime versions exempted for it, and a corrupt one answers warnings
|
|
74
|
+
* instead — both shapes are the person's business here, because this is the
|
|
75
|
+
* step where they decide whether to add another. The file is user-editable and
|
|
76
|
+
* carries whatever somebody typed, so its rows are sanitized too.
|
|
77
|
+
*/
|
|
78
|
+
function exemptionLines(exemptions) {
|
|
79
|
+
const rows = Object.entries(exemptions.exemptions)
|
|
80
|
+
.map(([packageVersion, runtimes]) => ` ${clean(packageVersion)} → ${runtimes.map(runtime => clean(runtime)).join(', ')}`);
|
|
81
|
+
if (rows.length === 0 && exemptions.warnings.length === 0)
|
|
82
|
+
return [` ${t('plugins-info-registries-none')}`];
|
|
83
|
+
return [...rows, ...exemptions.warnings.map(warning => ` ${clean(warning)}`)];
|
|
84
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PluginManageStep } from '../dsh-adapter/plugin-manage.js';
|
|
3
|
+
/**
|
|
4
|
+
* `/plugin remove | enable | disable`: the pane that asks what the flow cannot
|
|
5
|
+
* answer on its own (Stage C-5).
|
|
6
|
+
*
|
|
7
|
+
* The flow (`dsh-adapter/plugin-manage.ts`) writes every line of the action into
|
|
8
|
+
* the transcript — what it resolved, why it refused, what the service answered —
|
|
9
|
+
* so this pane only carries the one thing a person must decide before the write.
|
|
10
|
+
* Unlike the install pane there is no progress, no cancellation and no retry:
|
|
11
|
+
* each action is a single call that settles once.
|
|
12
|
+
*
|
|
13
|
+
* Presentational only, and the same three parts as its install sibling
|
|
14
|
+
* (`PluginInstallPane`): the pane, the facts that make the question answerable,
|
|
15
|
+
* and the key hints. Keys are handled in Chat (Enter answers, Esc closes).
|
|
16
|
+
*/
|
|
17
|
+
export declare function PluginManagePane({ step, busy }: {
|
|
18
|
+
step: PluginManageStep;
|
|
19
|
+
busy: boolean;
|
|
20
|
+
}): React.ReactNode;
|
|
21
|
+
//# sourceMappingURL=PluginManagePane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginManagePane.d.ts","sourceRoot":"","sources":["../../../src/components/PluginManagePane.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,iCAAiC,CAAA;AAiB3F;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,KAAK,CAAC,SAAS,CAqD3G"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { t } from '../i18n.js';
|
|
3
|
+
import { Box, Text } from '../ui.js';
|
|
4
|
+
import { cleanRenderText, NOTICE_CELLS } from '../channel/sanitize.js';
|
|
5
|
+
import { HintLine } from './design-system/HintLine.js';
|
|
6
|
+
import { LoadingState } from './design-system/LoadingState.js';
|
|
7
|
+
import { Pane } from './design-system/Pane.js';
|
|
8
|
+
/** Foreign text on its way to the screen: control sequences stripped, bounded. */
|
|
9
|
+
const clean = (value) => cleanRenderText(value, NOTICE_CELLS);
|
|
10
|
+
/**
|
|
11
|
+
* The target's identity is the subject of the question, and it is foreign text
|
|
12
|
+
* like everything else here: a package name and a module specifier come from
|
|
13
|
+
* somebody else's manifest, so either can carry newlines or thousands of cells.
|
|
14
|
+
* Bounded to what a line can show — at 50 columns an unbounded name buries the
|
|
15
|
+
* title and the key hints, which are exactly what the person needs to answer.
|
|
16
|
+
*/
|
|
17
|
+
const TARGET_CELLS = 80;
|
|
18
|
+
/**
|
|
19
|
+
* `/plugin remove | enable | disable`: the pane that asks what the flow cannot
|
|
20
|
+
* answer on its own (Stage C-5).
|
|
21
|
+
*
|
|
22
|
+
* The flow (`dsh-adapter/plugin-manage.ts`) writes every line of the action into
|
|
23
|
+
* the transcript — what it resolved, why it refused, what the service answered —
|
|
24
|
+
* so this pane only carries the one thing a person must decide before the write.
|
|
25
|
+
* Unlike the install pane there is no progress, no cancellation and no retry:
|
|
26
|
+
* each action is a single call that settles once.
|
|
27
|
+
*
|
|
28
|
+
* Presentational only, and the same three parts as its install sibling
|
|
29
|
+
* (`PluginInstallPane`): the pane, the facts that make the question answerable,
|
|
30
|
+
* and the key hints. Keys are handled in Chat (Enter answers, Esc closes).
|
|
31
|
+
*/
|
|
32
|
+
export function PluginManagePane({ step, busy }) {
|
|
33
|
+
if (busy) {
|
|
34
|
+
// A write is in flight. Esc closes the pane and the write finishes anyway —
|
|
35
|
+
// the service has no cancellation for these three, and saying "cancelling"
|
|
36
|
+
// here would be a promise nobody can keep.
|
|
37
|
+
return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "remember", bold: true, children: t('plugins-manage-pane-title') }), _jsx(Box, { marginTop: 1, children: _jsx(LoadingState, { message: t('plugins-manage-working') }) })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('plugins-manage-key-busy') }) })] }));
|
|
38
|
+
}
|
|
39
|
+
if (step.kind === 'confirm') {
|
|
40
|
+
return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: t('plugins-manage-pane-title') }) }), _jsx(Text, { children: t('plugins-manage-configure', {
|
|
41
|
+
action: t(actionKeyOf(step.target)),
|
|
42
|
+
target: describe(step.target),
|
|
43
|
+
}) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [step.question.kind === 'remove' && (_jsx(Text, { children: t('plugins-manage-remove-facts', {
|
|
44
|
+
rows: String(step.target.kind === 'bundle' ? step.target.rows : 0),
|
|
45
|
+
overrides: String(step.target.kind === 'bundle' ? step.target.overrides : 0),
|
|
46
|
+
}) })), step.question.kind === 'trust' && _jsx(Text, { children: t('plugins-manage-trust-facts') }), step.question.kind === 'host-row' && _jsx(Text, { children: t('plugins-manage-host-row-facts') }), step.question.kind === 'team-active' && (_jsxs(_Fragment, { children: [step.question.members > 0 && _jsx(Text, { children: t('plugins-manage-team-active-facts', { members: String(step.question.members) }) }), step.question.unseen > 0 && _jsx(Text, { children: t('plugins-manage-team-unseen-facts', { members: String(step.question.unseen) }) }), _jsx(Text, { children: t('plugins-manage-team-active-stop') })] }))] })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('plugins-manage-key-confirm') }) })] }));
|
|
47
|
+
}
|
|
48
|
+
// `done` never renders: its lines are already in the transcript, so Chat
|
|
49
|
+
// closes the pane instead of leaving an empty box behind.
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
/** Which verb the title asks about. */
|
|
53
|
+
function actionKeyOf(target) {
|
|
54
|
+
return target.action === 'remove'
|
|
55
|
+
? 'plugins-manage-action-remove'
|
|
56
|
+
: target.action === 'enable' ? 'plugins-manage-action-enable' : 'plugins-manage-action-disable';
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The target as one bounded cell. A bundle is named by its package name; a row
|
|
60
|
+
* by the module it loads, which is what the report listed it as and what a
|
|
61
|
+
* person typed to get here.
|
|
62
|
+
*/
|
|
63
|
+
function describe(target) {
|
|
64
|
+
if (target.kind === 'bundle') {
|
|
65
|
+
const version = target.version === undefined ? '' : `@${target.version}`;
|
|
66
|
+
return cleanRenderText(`${target.name}${version}`, TARGET_CELLS);
|
|
67
|
+
}
|
|
68
|
+
return cleanRenderText(target.moduleName, TARGET_CELLS);
|
|
69
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PromptInput.d.ts","sourceRoot":"","sources":["../../../src/components/PromptInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AA8BzB,OAAO,KAAK,EAAE,SAAS,IAAI,OAAO,EAAE,MAAM,iCAAiC,CAAA;AAC3E,OAAO,KAAK,EACV,gBAAgB,EAGjB,MAAM,2BAA2B,CAAA;AAClC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAA;AAa1E,OAAO,EAIL,KAAK,gBAAgB,EAEtB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAgLjF;gFACgF;AAChF,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,gBAAgB,EAAE,CAWpB;AAqLD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,IAAI,OAAO,CAAA;IAClB,yFAAyF;IACzF,IAAI,IAAI,MAAM,CAAA;IACd,4EAA4E;IAC5E,aAAa,CAAC,IAAI,SAAS;QAAE,KAAK,EAAE,eAAe,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACtE,KAAK,IAAI,IAAI,CAAA;IACb;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IAC5B;;;;;OAKG;IACH,oBAAoB,IAAI,OAAO,CAAA;IAC/B,yEAAyE;IACzE,aAAa,IAAI,OAAO,CAAA;IACxB,2EAA2E;IAC3E,SAAS,IAAI,OAAO,CAAA;IACpB;yEACqE;IACrE,SAAS,IAAI,OAAO,CAAA;CAAC;AAEvB;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,KAAK,OAAO,CAAA;IACrE;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,IAAI,IAAI,CAAA;IACpB;;;OAGG;IACH,YAAY,CACV,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAClC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC7B,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB,kEAAkE;IAClE,eAAe,CAAC,IAAI,IAAI,CAAA;IACxB;;;OAGG;IACH,mBAAmB,CAAC,IAAI,IAAI,CAAA;IAC5B;;;;;;;;OAQG;IACH,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAA;IACrC,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IACxD;;;;;;;OAOG;IACH,YAAY,CAAC,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAAA;IAC7G;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,qBAAqB,CAAC,IAAI,IAAI,CAAA;IAC9B;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,eAAe,EACf,SAAiB,EACjB,aAAoB,EACpB,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,4BAA4B,EAC5B,aAAa,EACb,YAAY,EACZ,gBAAwB,EACxB,qBAAqB,EACrB,GAAc,GACf,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"PromptInput.d.ts","sourceRoot":"","sources":["../../../src/components/PromptInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AA8BzB,OAAO,KAAK,EAAE,SAAS,IAAI,OAAO,EAAE,MAAM,iCAAiC,CAAA;AAC3E,OAAO,KAAK,EACV,gBAAgB,EAGjB,MAAM,2BAA2B,CAAA;AAClC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAA;AAa1E,OAAO,EAIL,KAAK,gBAAgB,EAEtB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAgLjF;gFACgF;AAChF,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,gBAAgB,EAAE,CAWpB;AAqLD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,IAAI,OAAO,CAAA;IAClB,yFAAyF;IACzF,IAAI,IAAI,MAAM,CAAA;IACd,4EAA4E;IAC5E,aAAa,CAAC,IAAI,SAAS;QAAE,KAAK,EAAE,eAAe,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACtE,KAAK,IAAI,IAAI,CAAA;IACb;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IAC5B;;;;;OAKG;IACH,oBAAoB,IAAI,OAAO,CAAA;IAC/B,yEAAyE;IACzE,aAAa,IAAI,OAAO,CAAA;IACxB,2EAA2E;IAC3E,SAAS,IAAI,OAAO,CAAA;IACpB;yEACqE;IACrE,SAAS,IAAI,OAAO,CAAA;CAAC;AAEvB;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,KAAK,OAAO,CAAA;IACrE;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,IAAI,IAAI,CAAA;IACpB;;;OAGG;IACH,YAAY,CACV,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAClC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC7B,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB,kEAAkE;IAClE,eAAe,CAAC,IAAI,IAAI,CAAA;IACxB;;;OAGG;IACH,mBAAmB,CAAC,IAAI,IAAI,CAAA;IAC5B;;;;;;;;OAQG;IACH,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAA;IACrC,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IACxD;;;;;;;OAOG;IACH,YAAY,CAAC,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAAA;IAC7G;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,qBAAqB,CAAC,IAAI,IAAI,CAAA;IAC9B;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,eAAe,EACf,SAAiB,EACjB,aAAoB,EACpB,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,4BAA4B,EAC5B,aAAa,EACb,YAAY,EACZ,gBAAwB,EACxB,qBAAqB,EACrB,GAAc,GACf,EAAE,gBAAgB,4BAi4HlB"}
|
|
@@ -954,6 +954,7 @@ export function PromptInput({ channel, toastSuppressed, suspended = false, curso
|
|
|
954
954
|
// index space: `suggestions` stays the only list selection, Enter dispatch and
|
|
955
955
|
// clicks read, and the default selection stays the first normal-region row.
|
|
956
956
|
// The region is marked by colour only — it costs no display row.
|
|
957
|
+
const completionInput = value;
|
|
957
958
|
const completions = value.startsWith('/') ? channel.commandCompletions(value) : [];
|
|
958
959
|
const holdOf = (commandLine) => workingHoldOf(commandLine, channel.commandList.find(command => command.name === commandLine.replace(/^\//, '').split(/[\t ]/u)[0])?.skill === true) !== undefined;
|
|
959
960
|
const normalCompletions = channel.working
|
|
@@ -1709,7 +1710,10 @@ export function PromptInput({ channel, toastSuppressed, suspended = false, curso
|
|
|
1709
1710
|
editDocked(dockSelectedRef.current);
|
|
1710
1711
|
return;
|
|
1711
1712
|
}
|
|
1712
|
-
|
|
1713
|
+
// A preceding edit in this stdin batch has already updated valueRef, but
|
|
1714
|
+
// the completion rows still belong to the last render. Submit the current
|
|
1715
|
+
// draft through the ordinary path instead of accepting a stale row.
|
|
1716
|
+
if (overlayOpen && value === completionInput) {
|
|
1713
1717
|
const command = suggestions[selectedCommand];
|
|
1714
1718
|
if (command) {
|
|
1715
1719
|
tryRunCommand(command.commandLine);
|
|
@@ -2427,7 +2431,7 @@ export function PromptInput({ channel, toastSuppressed, suspended = false, curso
|
|
|
2427
2431
|
}
|
|
2428
2432
|
if (key.tab && overlayOpen) {
|
|
2429
2433
|
const command = suggestions[selectedCommand];
|
|
2430
|
-
if (command) {
|
|
2434
|
+
if (command && value === completionInput) {
|
|
2431
2435
|
updateFoldBlock(null);
|
|
2432
2436
|
setInput(command.replacement, command.replacement.length, 'step');
|
|
2433
2437
|
}
|
|
@@ -3809,7 +3813,7 @@ export function PromptInput({ channel, toastSuppressed, suspended = false, curso
|
|
|
3809
3813
|
onPick: (index) => {
|
|
3810
3814
|
const command = suggestions[index];
|
|
3811
3815
|
if (command)
|
|
3812
|
-
tryRunCommand(command.commandLine);
|
|
3816
|
+
tryRunCommand(valueRef.current === completionInput ? command.commandLine : valueRef.current);
|
|
3813
3817
|
},
|
|
3814
3818
|
// 滚轮 = 移动选中行(与 ↑/↓ 同路径,窗口跟随)
|
|
3815
3819
|
onWheelStep: (step) => {
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { SubagentState } from '../dsh-adapter/subagents.js';
|
|
3
3
|
import type { ClickEvent } from '../ink/events/click-event.js';
|
|
4
|
+
import type { TeamMemberStatus } from './teamRoster.js';
|
|
4
5
|
export interface SubagentCardProps {
|
|
5
6
|
subagent: SubagentState;
|
|
6
7
|
focused?: boolean;
|
|
7
8
|
onClick?(event: ClickEvent): void;
|
|
8
9
|
variant?: 'default' | 'panel';
|
|
10
|
+
/** Agent Teams: the row is this teammate — its name replaces the
|
|
11
|
+
* description and its member state replaces the run status. */
|
|
12
|
+
teamMember?: {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly status: TeamMemberStatus;
|
|
15
|
+
};
|
|
9
16
|
}
|
|
10
|
-
|
|
17
|
+
/** Status glyph and color of a team member (`·`-style in minimal UI). */
|
|
18
|
+
export declare function teamStatusGlyph(status: TeamMemberStatus, minimalUi: boolean): {
|
|
19
|
+
readonly glyph: string;
|
|
20
|
+
readonly color?: 'warning' | 'subtle' | 'error' | 'accent';
|
|
21
|
+
};
|
|
22
|
+
export declare function SubagentCard({ subagent, focused, onClick, variant, teamMember }: SubagentCardProps): React.ReactNode;
|
|
11
23
|
//# sourceMappingURL=SubagentCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubagentCard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAIhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;
|
|
1
|
+
{"version":3,"file":"SubagentCard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAIhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAOvD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IACjC,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;IAC7B;oEACgE;IAChE,UAAU,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAA;CAC1E;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,OAAO,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAA;CAAE,CAQpK;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAmB,EAAE,UAAU,EAAE,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CA2FhI"}
|
|
@@ -8,9 +8,21 @@ function formatDuration(ms) {
|
|
|
8
8
|
const seconds = Math.floor(ms / 1000);
|
|
9
9
|
return seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m${seconds % 60}s`;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
/** Status glyph and color of a team member (`·`-style in minimal UI). */
|
|
12
|
+
export function teamStatusGlyph(status, minimalUi) {
|
|
13
|
+
switch (status) {
|
|
14
|
+
case 'running': return minimalUi ? { glyph: '·' } : { glyph: '🟡', color: 'warning' };
|
|
15
|
+
case 'idle': return minimalUi ? { glyph: '○' } : { glyph: '🔵', color: 'accent' };
|
|
16
|
+
case 'active': return minimalUi ? { glyph: '◇' } : { glyph: '🟣', color: 'accent' };
|
|
17
|
+
case 'provisioning': return minimalUi ? { glyph: '…' } : { glyph: '⚪', color: 'subtle' };
|
|
18
|
+
case 'failed': return minimalUi ? { glyph: '×' } : { glyph: '🔴', color: 'error' };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function SubagentCard({ subagent, focused, onClick, variant = 'default', teamMember }) {
|
|
12
22
|
const panelMode = variant === 'panel';
|
|
13
|
-
const running =
|
|
23
|
+
const running = teamMember !== undefined
|
|
24
|
+
? teamMember.status === 'running'
|
|
25
|
+
: subagent.status === 'running' || subagent.status === 'starting';
|
|
14
26
|
const [clockRef] = useAnimationFrame(running ? 1000 : null);
|
|
15
27
|
// Unknown rows have no completion time, so they do not get a fabricated duration.
|
|
16
28
|
const elapsed = running
|
|
@@ -25,15 +37,18 @@ export function SubagentCard({ subagent, focused, onClick, variant = 'default' }
|
|
|
25
37
|
const [hovered, setHovered] = useState(false);
|
|
26
38
|
const liveLine = running ? subagent.output[subagent.output.length - 1] : undefined;
|
|
27
39
|
const minimalUi = isMinimalUiMode();
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
const teamGlyph = teamMember === undefined ? undefined : teamStatusGlyph(teamMember.status, minimalUi);
|
|
41
|
+
const glyph = teamGlyph !== undefined ? teamGlyph.glyph
|
|
42
|
+
: running ? (minimalUi ? '·' : '🟡')
|
|
43
|
+
: subagent.status === 'unknown' ? (minimalUi ? '·' : '⚪')
|
|
44
|
+
: subagent.status === 'failed' || subagent.status === 'cancelled' ? (minimalUi ? '×' : '🔴')
|
|
45
|
+
: (minimalUi ? '✓' : '🟢');
|
|
46
|
+
const glyphColor = teamGlyph !== undefined ? teamGlyph.color
|
|
47
|
+
: minimalUi ? undefined
|
|
48
|
+
: running ? 'warning'
|
|
49
|
+
: subagent.status === 'unknown' ? 'subtle'
|
|
50
|
+
: subagent.status === 'failed' || subagent.status === 'cancelled' ? 'error'
|
|
51
|
+
: 'success';
|
|
37
52
|
const hoverTint = onClick !== undefined && hovered && !focused;
|
|
38
53
|
// Keep the description on one row; narrower panels progressively drop metadata.
|
|
39
54
|
const { columns } = useTerminalSize();
|
|
@@ -55,7 +70,7 @@ export function SubagentCard({ subagent, focused, onClick, variant = 'default' }
|
|
|
55
70
|
subagent.effort,
|
|
56
71
|
shownDuration === undefined ? undefined : formatDuration(shownDuration),
|
|
57
72
|
].filter(part => part !== undefined && part !== '').join(' · ');
|
|
58
|
-
return _jsxs(Box, { ref: clockRef, flexDirection: "column", paddingLeft: 1, marginBottom: panelMode ? 0 : 1, onClick: onClick, onMouseEnter: onClick !== undefined ? () => setHovered(true) : undefined, onMouseLeave: onClick !== undefined ? () => setHovered(false) : undefined, backgroundColor: hoverTint ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { flexShrink: 0, marginRight: 1, children: _jsx(Text, { color: glyphColor, children: glyph }) }), _jsx(Box, { flexGrow: 1, flexShrink: 1, overflow: "hidden", children: _jsx(Text, { bold: true, color: focused ? 'accent' : undefined, wrap: "truncate-end", children: panelMode ? subagent.description : `${t('subagent-card-prefix')}${subagent.description}` }) }), subagent.mode === 'continuable' && (_jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { color: focused ? 'accent' : 'warning', children: t('subagent-mode-continuable') }) })), subagent.mode === 'one-shot' && (_jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { dimColor: true, children: t('subagent-mode-one-shot') }) })), !panelMode && meta !== '' && (_jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { dimColor: true, wrap: "truncate-end", children: meta }) }))] }), panelMode && panelMeta !== '' && _jsx(Box, { paddingLeft: 3, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: panelMeta }) }), panelMode
|
|
73
|
+
return _jsxs(Box, { ref: clockRef, flexDirection: "column", paddingLeft: 1, marginBottom: panelMode ? 0 : 1, onClick: onClick, onMouseEnter: onClick !== undefined ? () => setHovered(true) : undefined, onMouseLeave: onClick !== undefined ? () => setHovered(false) : undefined, backgroundColor: hoverTint ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { flexShrink: 0, marginRight: 1, children: _jsx(Text, { color: glyphColor, children: glyph }) }), _jsx(Box, { flexGrow: 1, flexShrink: 1, overflow: "hidden", children: _jsx(Text, { bold: true, color: focused ? 'accent' : undefined, wrap: "truncate-end", children: teamMember !== undefined ? teamMember.name : panelMode ? subagent.description : `${t('subagent-card-prefix')}${subagent.description}` }) }), teamMember !== undefined && (_jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { color: focused ? 'accent' : teamGlyph?.color, dimColor: teamMember.status === 'provisioning', children: t(`team-status-${teamMember.status}`) }) })), teamMember === undefined && subagent.mode === 'continuable' && (_jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { color: focused ? 'accent' : 'warning', children: t('subagent-mode-continuable') }) })), teamMember === undefined && subagent.mode === 'one-shot' && (_jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { dimColor: true, children: t('subagent-mode-one-shot') }) })), !panelMode && meta !== '' && (_jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { dimColor: true, wrap: "truncate-end", children: meta }) }))] }), panelMode && panelMeta !== '' && _jsx(Box, { paddingLeft: 3, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: panelMeta }) }), panelMode
|
|
59
74
|
? previewRows.map(row => _jsx(Text, { dimColor: true, wrap: "truncate", children: ` ${row.text}` }, row.key))
|
|
60
75
|
: liveLine !== undefined && _jsx(Text, { dimColor: true, wrap: "truncate", children: ` │ ${liveLine}` })] });
|
|
61
76
|
}
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import type { SubagentState } from '../dsh-adapter/subagents.js';
|
|
3
3
|
import type { SidePanelKeyFlags } from './sidePanel/types.js';
|
|
4
4
|
import type { AgentMessageView, AgentIdentity } from './messages/agentTeam.js';
|
|
5
|
+
import type { TeamView } from '../adapter/ports/channel-view.js';
|
|
5
6
|
export interface SubagentDashboardProps {
|
|
6
7
|
subagents: readonly SubagentState[];
|
|
7
8
|
/** Optional cross-session agents, kept separate from this session children. */
|
|
@@ -15,6 +16,12 @@ export interface SubagentDashboardProps {
|
|
|
15
16
|
onOpenView?: (agentId: string) => void;
|
|
16
17
|
/** 代理↔代理消息流:每张卡下显示最后一条 from → to 摘要。 */
|
|
17
18
|
messages?: readonly AgentMessageView[];
|
|
19
|
+
/** Agent Teams: present → team mode (members joined with their subagent
|
|
20
|
+
* rows, a read-only task board, the failure banner). */
|
|
21
|
+
team?: TeamView;
|
|
22
|
+
/** The session on screen: inside a teammate the subagent rows are its own
|
|
23
|
+
* children, so the roster is not joined with them. */
|
|
24
|
+
sessionId?: string;
|
|
18
25
|
/** `panel` 挂在侧栏宿主里(去外层 padding、键盘走 usePanelInput 分发器);
|
|
19
26
|
* default(缺省)与整屏形态逐字节一致。 */
|
|
20
27
|
variant?: 'default' | 'panel';
|
|
@@ -32,5 +39,5 @@ export declare function ExitButton({ onClick }: {
|
|
|
32
39
|
* SubagentDashboard — overlay panel showing all active/recent subagents.
|
|
33
40
|
* Keyboard: up/down to navigate, Enter to view detail, Esc to close.
|
|
34
41
|
*/
|
|
35
|
-
export declare function SubagentDashboard({ subagents, peers, onClose, onSelect, onOpenView, messages, variant, focused, visible, }: SubagentDashboardProps): React.ReactNode;
|
|
42
|
+
export declare function SubagentDashboard({ subagents, team, sessionId, peers, onClose, onSelect, onOpenView, messages, variant, focused, visible, }: SubagentDashboardProps): React.ReactNode;
|
|
36
43
|
//# sourceMappingURL=SubagentDashboard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubagentDashboard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentDashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAMhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"SubagentDashboard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentDashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAMhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAC9E,OAAO,KAAK,EAAY,QAAQ,EAAE,MAAM,kCAAkC,CAAA;AAI1E,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAA;IACnC,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,aAAa,EAAE,CAAA;IACzC;mDAC+C;IAC/C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC;0BACsB;IACtB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,wCAAwC;IACxC,QAAQ,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAA;IACtC;6DACyD;IACzD,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf;2DACuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;iCAC6B;IAC7B,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;IAC7B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAOjF;AAED,yCAAyC;AACzC,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,GAAG,KAAK,CAAC,SAAS,CAWhF;AAgED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,IAAI,EACJ,SAAS,EACT,KAAK,EACL,OAAO,EACP,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,OAAmB,EACnB,OAAc,EACd,OAAc,GACf,EAAE,sBAAsB,GAAG,KAAK,CAAC,SAAS,CAkS1C"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { Box, Text, useInput, ScrollBox, useTerminalSize } from '../ui.js';
|
|
4
|
-
import { SubagentCard } from './SubagentCard.js';
|
|
4
|
+
import { SubagentCard, teamStatusGlyph } from './SubagentCard.js';
|
|
5
5
|
import { t } from '../i18n.js';
|
|
6
6
|
import { Divider } from './design-system/Divider.js';
|
|
7
7
|
import { isPlainReturnInput } from '../utils/modifiers.js';
|
|
8
8
|
import { usePanelInput } from './sidePanel/usePanelInput.js';
|
|
9
9
|
import { AgentMessagesSummary } from './messages/AgentMessageFlow.js';
|
|
10
|
+
import { isTeamTaskBlocked, teamDashboardModel, teamTaskProgress } from './teamRoster.js';
|
|
11
|
+
import { isMinimalUiMode } from '../minimalUiMode.js';
|
|
10
12
|
/** Accept Ink's Enter flag and the panel dispatcher's normalized alias. */
|
|
11
13
|
export function isPanelPlainReturn(input, key) {
|
|
12
14
|
return isPlainReturnInput(input, {
|
|
@@ -21,13 +23,29 @@ export function ExitButton({ onClick }) {
|
|
|
21
23
|
const [hovered, setHovered] = React.useState(false);
|
|
22
24
|
return (_jsx(Box, { onClick: onClick, onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), children: _jsx(Text, { color: hovered ? 'text' : 'subtle', children: ' ✕' }) }));
|
|
23
25
|
}
|
|
26
|
+
/** A teammate the host has not announced as a subagent yet. */
|
|
27
|
+
function TeamRosterOnlyRow({ row, focused, panelMode, self }) {
|
|
28
|
+
const { glyph, color } = teamStatusGlyph(row.status, isMinimalUiMode());
|
|
29
|
+
return (_jsxs(Box, { flexDirection: "row", paddingLeft: 1, marginBottom: panelMode ? 0 : 1, children: [_jsx(Box, { flexShrink: 0, marginRight: 1, children: _jsx(Text, { color: color, children: glyph }) }), _jsx(Box, { flexGrow: 1, flexShrink: 1, overflow: "hidden", children: _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { bold: true, color: focused ? 'accent' : undefined, children: row.member.name }), self && _jsx(Text, { dimColor: true, children: ' · ' + t('team-self-mark') })] }) }), _jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { color: focused ? 'accent' : color, dimColor: row.status === 'provisioning', children: t(`team-status-${row.status}`) }) })] }));
|
|
30
|
+
}
|
|
31
|
+
const TASK_GLYPH = {
|
|
32
|
+
pending: { glyph: '○', color: 'subtle' },
|
|
33
|
+
in_progress: { glyph: '◐', color: 'accent' },
|
|
34
|
+
completed: { glyph: '●', color: 'success' },
|
|
35
|
+
};
|
|
36
|
+
/** The team's shared task board, read-only; narrow widths drop the owner. */
|
|
37
|
+
function TeamTaskBoard({ tasks }) {
|
|
38
|
+
const { columns } = useTerminalSize();
|
|
39
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { dimColor: true, wrap: "truncate-end", children: t('team-tasks-title', teamTaskProgress(tasks)) }), tasks.length === 0 && _jsx(Text, { dimColor: true, children: ' ' + t('team-tasks-empty') }), tasks.map(task => (_jsxs(Box, { flexDirection: "row", paddingLeft: 1, children: [_jsx(Box, { flexShrink: 0, marginRight: 1, children: _jsx(Text, { color: TASK_GLYPH[task.status].color, children: TASK_GLYPH[task.status].glyph }) }), _jsx(Box, { flexGrow: 1, flexShrink: 1, overflow: "hidden", children: _jsx(Text, { dimColor: task.status === 'completed', wrap: "truncate-end", children: task.subject }) }), columns >= 40 && task.ownerName !== undefined && (_jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { dimColor: true, children: '@' + task.ownerName }) })), isTeamTaskBlocked(task) && (_jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { color: "warning", children: t('team-task-blocked') }) })), task.writeScopeWarnings.length > 0 && (_jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(Text, { color: "warning", children: '⚠' + task.writeScopeWarnings.length }) }))] }, task.id)))] }));
|
|
40
|
+
}
|
|
24
41
|
/**
|
|
25
42
|
* SubagentDashboard — overlay panel showing all active/recent subagents.
|
|
26
43
|
* Keyboard: up/down to navigate, Enter to view detail, Esc to close.
|
|
27
44
|
*/
|
|
28
|
-
export function SubagentDashboard({ subagents, peers, onClose, onSelect, onOpenView, messages, variant = 'default', focused = true, visible = true, }) {
|
|
45
|
+
export function SubagentDashboard({ subagents, team, sessionId, peers, onClose, onSelect, onOpenView, messages, variant = 'default', focused = true, visible = true, }) {
|
|
29
46
|
const panelMode = variant === 'panel';
|
|
30
|
-
|
|
47
|
+
// Focus follows the row's key: team mode reorders the rows, and the roster can shrink.
|
|
48
|
+
const [focus, setFocus] = React.useState({ index: 0 });
|
|
31
49
|
const scrollRef = React.useRef(null);
|
|
32
50
|
const { rows, columns } = useTerminalSize();
|
|
33
51
|
// Keep top-level children first when the roster includes nested agents.
|
|
@@ -35,6 +53,29 @@ export function SubagentDashboard({ subagents, peers, onClose, onSelect, onOpenV
|
|
|
35
53
|
const nestedRows = subagents.filter(isNestedSpawn);
|
|
36
54
|
const flatRows = subagents.filter(row => !isNestedSpawn(row));
|
|
37
55
|
const ordered = nestedRows.length === 0 ? subagents : [...flatRows, ...nestedRows];
|
|
56
|
+
const model = team === undefined ? undefined : teamDashboardModel(team, subagents, sessionId);
|
|
57
|
+
const others = new Set(model?.others);
|
|
58
|
+
const nested = nestedRows.length;
|
|
59
|
+
const rowEntry = (subagent) => ({ key: subagent.agentId, subagent, nested: nested > 0 && isNestedSpawn(subagent) });
|
|
60
|
+
const entries = model === undefined
|
|
61
|
+
? ordered.map(rowEntry)
|
|
62
|
+
: [
|
|
63
|
+
...model.teammates.map(row => ({ key: row.member.id, teamRow: row, nested: false, ...row.subagent === undefined ? {} : { subagent: row.subagent } })),
|
|
64
|
+
...ordered.filter(row => others.has(row)).map(rowEntry),
|
|
65
|
+
];
|
|
66
|
+
const othersStart = model === undefined ? -1 : model.teammates.length;
|
|
67
|
+
const focusOf = (state) => {
|
|
68
|
+
const found = state.key === undefined ? -1 : entries.findIndex(entry => entry.key === state.key);
|
|
69
|
+
return found >= 0 ? found : Math.min(state.index, Math.max(0, entries.length - 1));
|
|
70
|
+
};
|
|
71
|
+
const focusIndex = focusOf(focus);
|
|
72
|
+
const moveFocus = (delta) => {
|
|
73
|
+
setFocus((prev) => {
|
|
74
|
+
const index = Math.max(0, Math.min(entries.length - 1, focusOf(prev) + delta));
|
|
75
|
+
const key = entries[index]?.key;
|
|
76
|
+
return key === undefined ? { index } : { index, key };
|
|
77
|
+
});
|
|
78
|
+
};
|
|
38
79
|
useInput((input, key, event) => {
|
|
39
80
|
if (panelMode)
|
|
40
81
|
return;
|
|
@@ -45,19 +86,19 @@ export function SubagentDashboard({ subagents, peers, onClose, onSelect, onOpenV
|
|
|
45
86
|
}
|
|
46
87
|
if (key.upArrow) {
|
|
47
88
|
event.stopImmediatePropagation();
|
|
48
|
-
|
|
89
|
+
moveFocus(-1);
|
|
49
90
|
scrollRef.current?.scrollBy(-3);
|
|
50
91
|
return;
|
|
51
92
|
}
|
|
52
93
|
if (key.downArrow) {
|
|
53
94
|
event.stopImmediatePropagation();
|
|
54
|
-
|
|
95
|
+
moveFocus(1);
|
|
55
96
|
scrollRef.current?.scrollBy(3);
|
|
56
97
|
return;
|
|
57
98
|
}
|
|
58
99
|
if (isPlainReturnInput(input, key) && onSelect) {
|
|
59
100
|
event.stopImmediatePropagation();
|
|
60
|
-
const selected =
|
|
101
|
+
const selected = entries[focusIndex]?.subagent;
|
|
61
102
|
if (selected)
|
|
62
103
|
onSelect(selected.agentId);
|
|
63
104
|
return;
|
|
@@ -65,7 +106,7 @@ export function SubagentDashboard({ subagents, peers, onClose, onSelect, onOpenV
|
|
|
65
106
|
// v = 主屏查看(Enter 仍是详情)。
|
|
66
107
|
if (input.toLowerCase() === 'v' && onOpenView) {
|
|
67
108
|
event.stopImmediatePropagation();
|
|
68
|
-
const selected =
|
|
109
|
+
const selected = entries[focusIndex]?.subagent;
|
|
69
110
|
if (selected)
|
|
70
111
|
onOpenView(selected.agentId);
|
|
71
112
|
return;
|
|
@@ -78,23 +119,23 @@ export function SubagentDashboard({ subagents, peers, onClose, onSelect, onOpenV
|
|
|
78
119
|
if (key.escape === true || (key.ctrl === true && input === 'c'))
|
|
79
120
|
return false;
|
|
80
121
|
if (key.upArrow === true) {
|
|
81
|
-
|
|
122
|
+
moveFocus(-1);
|
|
82
123
|
scrollRef.current?.scrollBy(-3);
|
|
83
124
|
return true;
|
|
84
125
|
}
|
|
85
126
|
if (key.downArrow === true) {
|
|
86
|
-
|
|
127
|
+
moveFocus(1);
|
|
87
128
|
scrollRef.current?.scrollBy(3);
|
|
88
129
|
return true;
|
|
89
130
|
}
|
|
90
131
|
if (isPanelPlainReturn(input, key)) {
|
|
91
|
-
const selected =
|
|
132
|
+
const selected = entries[focusIndex]?.subagent;
|
|
92
133
|
if (selected !== undefined)
|
|
93
134
|
onSelect?.(selected.agentId);
|
|
94
135
|
return true;
|
|
95
136
|
}
|
|
96
137
|
if (input.toLowerCase() === 'v' && onOpenView !== undefined) {
|
|
97
|
-
const selected =
|
|
138
|
+
const selected = entries[focusIndex]?.subagent;
|
|
98
139
|
if (selected !== undefined)
|
|
99
140
|
onOpenView(selected.agentId);
|
|
100
141
|
return true;
|
|
@@ -105,13 +146,14 @@ export function SubagentDashboard({ subagents, peers, onClose, onSelect, onOpenV
|
|
|
105
146
|
const running = subagents.filter(s => s.status === 'running').length;
|
|
106
147
|
const completed = subagents.filter(s => s.status === 'completed').length;
|
|
107
148
|
const failed = subagents.filter(s => s.status === 'failed').length;
|
|
108
|
-
const
|
|
149
|
+
const memberCount = (status) => model?.teammates.filter(row => row.status === status).length ?? 0;
|
|
150
|
+
const teamSep = panelMode ? ' · ' : ' ';
|
|
109
151
|
// Full-screen keeps its inset; the panel uses one cell on each side.
|
|
110
152
|
const outer = panelMode
|
|
111
153
|
? { paddingLeft: 1, paddingRight: 1, paddingTop: 0 }
|
|
112
154
|
: { paddingX: 2, paddingY: 1 };
|
|
113
|
-
return (_jsxs(Box, { flexDirection: "column", ...outer, children: [!panelMode && _jsx(Divider, { color: "accent", title: t('subagent-dashboard-title') }), _jsxs(Box, { flexDirection: "row", gap: 3, marginTop: panelMode ? 0 : 1, marginBottom: panelMode ? 0 : 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: "accent", children: running }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-running')] })] }), _jsxs(Text, { children: [_jsx(Text, { color: "success", children: completed }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-completed')] })] }), failed > 0 && (_jsxs(Text, { children: [_jsx(Text, { color: "error", children: failed }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-failed')] })] })), nested > 0 && (_jsxs(Text, { children: [_jsx(Text, { color: "accent", children: nested }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-nested')] })] })), _jsx(Box, { flexGrow: 1 }), !panelMode && onClose !== undefined && _jsx(ExitButton, { onClick: onClose })] }), _jsx(Box, { flexDirection: "column", maxHeight: panelMode ? Math.max(6, rows - 4) : Math.max(10, rows - 10), marginTop: panelMode ? 0 : 1, children:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
155
|
+
return (_jsxs(Box, { flexDirection: "column", ...outer, children: [!panelMode && _jsx(Divider, { color: "accent", title: t(team === undefined ? 'subagent-dashboard-title' : 'team-dashboard-title') }), _jsxs(Box, { flexDirection: "row", gap: 3, marginTop: panelMode ? 0 : 1, marginBottom: panelMode ? 0 : 1, children: [team !== undefined ? (_jsx(Box, { flexShrink: 1, overflow: "hidden", children: _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { color: "accent", children: memberCount('running') }), _jsx(Text, { dimColor: true, children: ' ' + t('team-status-running') + teamSep }), _jsx(Text, { color: "accent", children: memberCount('idle') }), _jsx(Text, { dimColor: true, children: ' ' + t('team-status-idle') + teamSep }), memberCount('provisioning') > 0 && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: memberCount('provisioning') }), _jsx(Text, { dimColor: true, children: ' ' + t('team-status-provisioning') + teamSep })] })), memberCount('active') > 0 && (_jsxs(_Fragment, { children: [_jsx(Text, { color: "accent", children: memberCount('active') }), _jsx(Text, { dimColor: true, children: ' ' + t('team-status-active') + teamSep })] })), memberCount('failed') > 0 && (_jsxs(_Fragment, { children: [_jsx(Text, { color: "error", children: memberCount('failed') }), _jsx(Text, { dimColor: true, children: ' ' + t('team-status-failed') + teamSep })] })), _jsx(Text, { dimColor: true, children: t('team-tasks-count', teamTaskProgress(team.tasks)) })] }) })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [_jsx(Text, { color: "accent", children: running }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-running')] })] }), _jsxs(Text, { children: [_jsx(Text, { color: "success", children: completed }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-completed')] })] }), failed > 0 && (_jsxs(Text, { children: [_jsx(Text, { color: "error", children: failed }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-failed')] })] })), nested > 0 && (_jsxs(Text, { children: [_jsx(Text, { color: "accent", children: nested }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-nested')] })] }))] })), _jsx(Box, { flexGrow: 1 }), !panelMode && onClose !== undefined && _jsx(ExitButton, { onClick: onClose })] }), team?.failure !== undefined && (_jsx(Text, { color: "error", wrap: "wrap", children: '⚠ ' + t('team-failure', { failure: team.failure }) })), _jsx(Box, { flexDirection: "column", maxHeight: panelMode ? Math.max(6, rows - 4) : Math.max(10, rows - 10), marginTop: panelMode ? 0 : 1, children: _jsxs(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: [model !== undefined && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: t('team-members-title') }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: ' ◆ ' + t(model.viewedFromLead ? 'team-lead-row' : 'team-lead-row-peer') })] })), model === undefined && subagents.length === 0 ? (_jsxs(Box, { flexDirection: "column", alignItems: "center", marginTop: Math.max(2, Math.floor((rows - 16) / 3)), children: [_jsx(Text, { dimColor: true, children: '○' }), _jsx(Text, { dimColor: true, children: t('subagent-none') }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: t('subagent-empty-hint') }) })] })) : (entries.map(({ key, subagent, teamRow, nested: nestedMark }, index) => (_jsxs(Box, { flexDirection: "column", children: [index === othersStart && _jsx(Text, { dimColor: true, children: t('team-others-title') }), nestedMark && (_jsx(Text, { dimColor: true, children: ' ↳ ' + t('subagent-nested-mark') })), subagent === undefined ? (teamRow !== undefined && _jsx(TeamRosterOnlyRow, { row: teamRow, focused: index === focusIndex, panelMode: panelMode, self: teamRow.member.id === sessionId })) : (_jsx(SubagentCard, { subagent: subagent, variant: panelMode ? 'panel' : 'default', focused: index === focusIndex, onClick: onSelect !== undefined
|
|
156
|
+
// Click = view detail, same as Enter on the focused card.
|
|
157
|
+
? () => onSelect(subagent.agentId)
|
|
158
|
+
: undefined, ...teamRow === undefined ? {} : { teamMember: { name: teamRow.member.name, status: teamRow.status } } })), teamRow?.status === 'failed' && teamRow.member.error !== undefined && (_jsx(Text, { color: "error", wrap: "truncate-end", children: ' │ ' + teamRow.member.error })), teamRow?.status === 'idle' && subagent?.status === 'failed' && (_jsx(Text, { color: "error", wrap: "truncate-end", children: ' │ ' + t('team-last-run-failed', { error: subagent.error ?? '' }).trimEnd() })), subagent !== undefined && messages !== undefined && messages.length > 0 && (_jsx(AgentMessagesSummary, { messages: messages.filter(message => message.from === subagent.agentId || message.to === subagent.agentId), selfAgentId: subagent.agentId })), subagent !== undefined && onOpenView !== undefined && (!panelMode || index === focusIndex) && (_jsx(Box, { paddingLeft: 1, onClick: () => onOpenView(subagent.agentId), children: _jsx(Text, { color: "subtle", children: `⤢ ${t('agent-view-open-action')}` }) })), !panelMode && index < entries.length - 1 && index + 1 !== othersStart && (_jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(20, Math.min(72, columns - 6))) }))] }, key)))), team !== undefined && _jsx(TeamTaskBoard, { tasks: team.tasks })] }) }), peers !== undefined && (!panelMode || peers.length > 0) && (_jsx(Box, { flexDirection: "column", children: panelMode ? (_jsx(Text, { dimColor: true, wrap: "truncate-end", children: t('agents-peers-title') + ' · ' + peers.length })) : (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: t('agents-peers-title') }), peers.length === 0 ? (_jsx(Text, { dimColor: true, children: ' ' + t('agents-peers-empty') })) : (_jsxs(Box, { flexDirection: "column", children: [peers.map(peer => (_jsx(Text, { dimColor: true, wrap: "truncate-end", children: ' · ' + (peer.name ?? peer.label ?? peer.agentId.slice(0, 8)) + ' · ' + peer.agentId.slice(0, 8) }, peer.agentId))), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: ' ' + t('agents-peers-note') })] }))] })) })), !panelMode && (_jsxs(_Fragment, { children: [_jsx(Divider, { color: "subtle", title: "" }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: onSelect ? t('subagent-dashboard-hint-detail') : t('subagent-dashboard-hint-basic') }) })] }))] }));
|
|
117
159
|
}
|