@pellux/goodvibes-agent 0.1.116 → 0.1.117
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -663
- package/README.md +38 -52
- package/dist/package/main.js +37826 -35924
- package/docs/README.md +5 -4
- package/docs/{connected-services.md → connected-host.md} +18 -10
- package/docs/getting-started.md +41 -44
- package/docs/release-and-publishing.md +6 -4
- package/package.json +3 -3
- package/src/agent/behavior-discovery-summary.ts +1 -3
- package/src/agent/persona-discovery.ts +1 -3
- package/src/agent/persona-registry.ts +5 -3
- package/src/agent/reminder-schedule-format.ts +6 -6
- package/src/agent/reminder-schedule.ts +1 -1
- package/src/agent/routine-registry.ts +43 -4
- package/src/agent/routine-schedule-format.ts +6 -6
- package/src/agent/routine-schedule-promotion.ts +1 -1
- package/src/agent/routine-schedule-receipts.ts +1 -1
- package/src/agent/runtime-profile-starters.ts +3 -3
- package/src/agent/runtime-profile.ts +78 -0
- package/src/agent/skill-registry.ts +190 -13
- package/src/cli/agent-knowledge-command.ts +2 -2
- package/src/cli/agent-knowledge-format.ts +2 -2
- package/src/cli/agent-knowledge-runtime.ts +1 -1
- package/src/cli/bundle-command.ts +1 -1
- package/src/cli/entrypoint.ts +16 -7
- package/src/cli/help.ts +26 -19
- package/src/cli/local-library-command.ts +75 -21
- package/src/cli/management-commands.ts +7 -6
- package/src/cli/management.ts +6 -51
- package/src/cli/parser.ts +23 -2
- package/src/cli/profiles-command.ts +119 -1
- package/src/cli/routines-command.ts +139 -11
- package/src/cli/service-posture.ts +11 -11
- package/src/cli/status.ts +21 -25
- package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
- package/src/input/agent-workspace-access-command-editors.ts +170 -0
- package/src/input/agent-workspace-activation.ts +2 -1
- package/src/input/agent-workspace-basic-command-editor-submission.ts +345 -92
- package/src/input/agent-workspace-basic-command-editors.ts +480 -7
- package/src/input/agent-workspace-categories.ts +175 -15
- package/src/input/agent-workspace-channel-command-editor-submission.ts +49 -0
- package/src/input/agent-workspace-channel-command-editors.ts +47 -0
- package/src/input/agent-workspace-command-editor.ts +23 -1
- package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
- package/src/input/agent-workspace-editors.ts +27 -0
- package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
- package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
- package/src/input/agent-workspace-learned-behavior.ts +67 -0
- package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
- package/src/input/agent-workspace-library-command-editors.ts +35 -0
- package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
- package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
- package/src/input/agent-workspace-memory-command-editors.ts +180 -0
- package/src/input/agent-workspace-navigation.ts +45 -0
- package/src/input/agent-workspace-notify-editor-submission.ts +107 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +146 -0
- package/src/input/agent-workspace-operations-command-editors.ts +119 -0
- package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
- package/src/input/agent-workspace-provider-command-editors.ts +93 -0
- package/src/input/agent-workspace-requirements.ts +11 -0
- package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
- package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
- package/src/input/agent-workspace-session-command-editors.ts +249 -0
- package/src/input/agent-workspace-setup.ts +24 -14
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
- package/src/input/agent-workspace-snapshot.ts +50 -8
- package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
- package/src/input/agent-workspace-task-command-editors.ts +47 -0
- package/src/input/agent-workspace-types.ts +120 -0
- package/src/input/agent-workspace-voice-media.ts +1 -1
- package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
- package/src/input/agent-workspace.ts +47 -37
- package/src/input/command-registry.ts +1 -1
- package/src/input/commands/agent-runtime-profile-runtime.ts +89 -4
- package/src/input/commands/agent-skills-runtime.ts +76 -12
- package/src/input/commands/agent-workspace-runtime.ts +4 -3
- package/src/input/commands/brief-runtime.ts +38 -9
- package/src/input/commands/channels-runtime.ts +3 -3
- package/src/input/commands/compat-runtime.ts +32 -0
- package/src/input/commands/health-runtime.ts +22 -24
- package/src/input/commands/knowledge.ts +26 -5
- package/src/input/commands/local-provider-runtime.ts +7 -3
- package/src/input/commands/local-setup-review.ts +4 -14
- package/src/input/commands/mcp-runtime.ts +8 -12
- package/src/input/commands/operator-runtime.ts +8 -67
- package/src/input/commands/personas-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +7 -70
- package/src/input/commands/policy-dispatch.ts +1 -1
- package/src/input/commands/policy.ts +1 -5
- package/src/input/commands/product-runtime.ts +2 -2
- package/src/input/commands/qrcode-runtime.ts +6 -4
- package/src/input/commands/routines-runtime.ts +44 -6
- package/src/input/commands/runtime-services.ts +1 -14
- package/src/input/commands/security-runtime.ts +3 -8
- package/src/input/commands/session-content.ts +1 -1
- package/src/input/commands/session-workflow.ts +5 -14
- package/src/input/commands/shell-core.ts +8 -2
- package/src/input/commands/subscription-runtime.ts +1 -6
- package/src/input/commands/support-bundle-runtime.ts +53 -0
- package/src/input/commands/tasks-runtime.ts +2 -2
- package/src/input/commands.ts +4 -0
- package/src/input/feed-context-factory.ts +0 -1
- package/src/input/handler-content-actions.ts +0 -25
- package/src/input/handler-feed.ts +0 -2
- package/src/input/handler-interactions.ts +2 -31
- package/src/input/handler-onboarding.ts +29 -12
- package/src/input/handler-shortcuts.ts +1 -3
- package/src/input/handler.ts +4 -7
- package/src/input/keybindings.ts +9 -9
- package/src/input/mcp-workspace.ts +90 -26
- package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
- package/src/input/onboarding/onboarding-wizard-apply.ts +49 -0
- package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +81 -3
- package/src/input/onboarding/onboarding-wizard-steps.ts +14 -7
- package/src/input/onboarding/onboarding-wizard-types.ts +1 -0
- package/src/input/onboarding/onboarding-wizard.ts +19 -2
- package/src/input/profile-picker-modal.ts +2 -2
- package/src/input/settings-modal-agent-policy.ts +6 -6
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal.ts +14 -14
- package/src/main.ts +0 -2
- package/src/panels/automation-control-panel.ts +3 -3
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +2 -2
- package/src/panels/builtin/session.ts +26 -18
- package/src/panels/builtin/shared.ts +6 -6
- package/src/panels/project-planning-panel.ts +1 -1
- package/src/panels/provider-health-domains.ts +3 -3
- package/src/panels/qr-panel.ts +44 -20
- package/src/panels/subscription-panel.ts +3 -3
- package/src/panels/system-messages-panel.ts +2 -2
- package/src/panels/tasks-panel.ts +4 -4
- package/src/planning/project-planning-coordinator.ts +2 -2
- package/src/renderer/agent-workspace.ts +26 -5
- package/src/renderer/block-actions.ts +1 -3
- package/src/renderer/help-overlay.ts +13 -8
- package/src/renderer/mcp-workspace.ts +32 -13
- package/src/renderer/model-picker-overlay.ts +0 -1
- package/src/renderer/model-workspace.ts +0 -2
- package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
- package/src/renderer/panel-picker-overlay.ts +1 -1
- package/src/renderer/profile-picker-modal.ts +2 -2
- package/src/renderer/settings-modal-helpers.ts +23 -23
- package/src/renderer/settings-modal.ts +18 -18
- package/src/renderer/system-message.ts +1 -1
- package/src/runtime/agent-runtime-events.ts +129 -0
- package/src/runtime/bootstrap-command-parts.ts +3 -2
- package/src/runtime/bootstrap-core.ts +4 -64
- package/src/runtime/bootstrap-shell.ts +42 -4
- package/src/runtime/bootstrap.ts +8 -27
- package/src/runtime/connected-host-auth.ts +42 -0
- package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
- package/src/runtime/index.ts +1 -5
- package/src/runtime/onboarding/apply.ts +213 -0
- package/src/runtime/onboarding/derivation.ts +5 -5
- package/src/runtime/onboarding/snapshot.ts +2 -2
- package/src/runtime/onboarding/types.ts +26 -1
- package/src/runtime/onboarding/verify.ts +81 -2
- package/src/runtime/operator-token-cleanup.ts +2 -2
- package/src/runtime/services.ts +27 -12
- package/src/shell/service-settings-sync.ts +7 -7
- package/src/shell/ui-openers.ts +27 -38
- package/src/tools/agent-local-registry-tool.ts +10 -4
- package/src/tools/agent-tool-policy-guard.ts +5 -7
- package/src/version.ts +1 -1
- package/src/cli/package-verification.ts +0 -274
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
import type { AgentWorkspaceOperationsCommandEditorKind } from './agent-workspace-operations-command-editors.ts';
|
|
3
|
+
import { isAgentWorkspaceOperationsCommandEditorKind } from './agent-workspace-operations-command-editors.ts';
|
|
4
|
+
import { quoteSlashCommandArg } from './slash-command-parser.ts';
|
|
5
|
+
|
|
6
|
+
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
7
|
+
|
|
8
|
+
function isAffirmative(value: string): boolean {
|
|
9
|
+
return /^(y|yes|true)$/i.test(value.trim());
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function unconfirmed(editor: AgentWorkspaceLocalEditor, message: string): AgentWorkspaceOperationsCommandEditorSubmission {
|
|
13
|
+
return {
|
|
14
|
+
kind: 'editor',
|
|
15
|
+
editor: { ...editor, message },
|
|
16
|
+
status: message,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type AgentWorkspaceOperationsCommandEditorSubmission =
|
|
21
|
+
| {
|
|
22
|
+
readonly kind: 'editor';
|
|
23
|
+
readonly editor: AgentWorkspaceLocalEditor;
|
|
24
|
+
readonly status: string;
|
|
25
|
+
readonly actionResult?: AgentWorkspaceActionResult;
|
|
26
|
+
}
|
|
27
|
+
| {
|
|
28
|
+
readonly kind: 'dispatch';
|
|
29
|
+
readonly command: string;
|
|
30
|
+
readonly status: string;
|
|
31
|
+
readonly actionResult: AgentWorkspaceActionResult;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export function isAgentWorkspaceOperationsCommandSubmissionKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceOperationsCommandEditorKind {
|
|
35
|
+
return isAgentWorkspaceOperationsCommandEditorKind(kind);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function buildAgentWorkspaceOperationsCommandEditorSubmission(
|
|
39
|
+
editor: AgentWorkspaceLocalEditor,
|
|
40
|
+
readField: AgentWorkspaceFieldReader,
|
|
41
|
+
): AgentWorkspaceOperationsCommandEditorSubmission {
|
|
42
|
+
if (editor.kind === 'plan-seed') {
|
|
43
|
+
const command = `/plan ${quoteSlashCommandArg(readField('goal'))}`;
|
|
44
|
+
return {
|
|
45
|
+
kind: 'dispatch',
|
|
46
|
+
command,
|
|
47
|
+
status: 'Opening planning goal seeding.',
|
|
48
|
+
actionResult: {
|
|
49
|
+
kind: 'dispatched',
|
|
50
|
+
title: 'Opening planning goal seeding',
|
|
51
|
+
detail: 'The workspace handed a concrete planning goal to the shell-owned command router without spawning coding agents.',
|
|
52
|
+
command,
|
|
53
|
+
safety: 'safe',
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (editor.kind === 'plan-approve') {
|
|
58
|
+
if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Planning approval not confirmed. Type yes, then press Enter.');
|
|
59
|
+
return {
|
|
60
|
+
kind: 'dispatch',
|
|
61
|
+
command: '/plan approve --yes',
|
|
62
|
+
status: 'Opening planning approval.',
|
|
63
|
+
actionResult: {
|
|
64
|
+
kind: 'dispatched',
|
|
65
|
+
title: 'Opening planning approval',
|
|
66
|
+
detail: 'The workspace handed confirmed planning approval to the shell-owned command router.',
|
|
67
|
+
command: '/plan approve --yes',
|
|
68
|
+
safety: 'safe',
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (editor.kind === 'plan-override') {
|
|
73
|
+
if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Planning strategy override not confirmed. Type yes, then press Enter.');
|
|
74
|
+
const command = `/plan override ${quoteSlashCommandArg(readField('strategy'))} --yes`;
|
|
75
|
+
return {
|
|
76
|
+
kind: 'dispatch',
|
|
77
|
+
command,
|
|
78
|
+
status: 'Opening planning strategy override.',
|
|
79
|
+
actionResult: {
|
|
80
|
+
kind: 'dispatched',
|
|
81
|
+
title: 'Opening planning strategy override',
|
|
82
|
+
detail: 'The workspace handed a confirmed planning strategy override to the shell-owned command router.',
|
|
83
|
+
command,
|
|
84
|
+
safety: 'safe',
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (editor.kind === 'plan-clear') {
|
|
89
|
+
if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Planning clear not confirmed. Type yes, then press Enter.');
|
|
90
|
+
return {
|
|
91
|
+
kind: 'dispatch',
|
|
92
|
+
command: '/plan clear --yes',
|
|
93
|
+
status: 'Opening planning clear.',
|
|
94
|
+
actionResult: {
|
|
95
|
+
kind: 'dispatched',
|
|
96
|
+
title: 'Opening planning clear',
|
|
97
|
+
detail: 'The workspace handed confirmed planning-state clearing to the shell-owned command router.',
|
|
98
|
+
command: '/plan clear --yes',
|
|
99
|
+
safety: 'safe',
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (editor.kind === 'routine-receipt' || editor.kind === 'schedule-receipt') {
|
|
104
|
+
const routine = editor.kind === 'routine-receipt';
|
|
105
|
+
const command = `/${routine ? 'routines' : 'schedule'} receipt ${quoteSlashCommandArg(readField('receiptId'))}`;
|
|
106
|
+
const title = routine ? 'Opening routine receipt' : 'Opening schedule receipt';
|
|
107
|
+
return {
|
|
108
|
+
kind: 'dispatch',
|
|
109
|
+
command,
|
|
110
|
+
status: `${title}.`,
|
|
111
|
+
actionResult: {
|
|
112
|
+
kind: 'dispatched',
|
|
113
|
+
title,
|
|
114
|
+
detail: routine
|
|
115
|
+
? 'The workspace handed read-only routine receipt inspection to the shell-owned command router.'
|
|
116
|
+
: 'The workspace handed read-only schedule receipt inspection to the shell-owned command router.',
|
|
117
|
+
command,
|
|
118
|
+
safety: 'read-only',
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const plan = editor.kind === 'plan-show';
|
|
123
|
+
const approval = editor.kind === 'approval-review';
|
|
124
|
+
const command = plan
|
|
125
|
+
? `/plan show ${quoteSlashCommandArg(readField('planId'))}`
|
|
126
|
+
: approval
|
|
127
|
+
? `/approval review ${quoteSlashCommandArg(readField('kind'))}`
|
|
128
|
+
: `/health repair ${quoteSlashCommandArg(readField('domain'))}`;
|
|
129
|
+
const title = plan ? 'Opening saved plan' : approval ? 'Opening approval review' : 'Opening health repair guidance';
|
|
130
|
+
return {
|
|
131
|
+
kind: 'dispatch',
|
|
132
|
+
command,
|
|
133
|
+
status: `${title}.`,
|
|
134
|
+
actionResult: {
|
|
135
|
+
kind: 'dispatched',
|
|
136
|
+
title,
|
|
137
|
+
detail: plan
|
|
138
|
+
? 'The workspace handed read-only saved-plan inspection to the shell-owned command router.'
|
|
139
|
+
: approval
|
|
140
|
+
? 'The workspace handed read-only approval class review to the shell-owned command router.'
|
|
141
|
+
: 'The workspace handed read-only health repair guidance to the shell-owned command router.',
|
|
142
|
+
command,
|
|
143
|
+
safety: 'read-only',
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
|
|
3
|
+
export type AgentWorkspaceOperationsCommandEditorKind = Extract<
|
|
4
|
+
AgentWorkspaceEditorKind,
|
|
5
|
+
'plan-seed' | 'plan-show' | 'plan-approve' | 'plan-override' | 'plan-clear' | 'health-repair' | 'approval-review' | 'routine-receipt' | 'schedule-receipt'
|
|
6
|
+
>;
|
|
7
|
+
|
|
8
|
+
export function isAgentWorkspaceOperationsCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceOperationsCommandEditorKind {
|
|
9
|
+
return kind === 'plan-seed'
|
|
10
|
+
|| kind === 'plan-show'
|
|
11
|
+
|| kind === 'plan-approve'
|
|
12
|
+
|| kind === 'plan-override'
|
|
13
|
+
|| kind === 'plan-clear'
|
|
14
|
+
|| kind === 'health-repair'
|
|
15
|
+
|| kind === 'approval-review'
|
|
16
|
+
|| kind === 'routine-receipt'
|
|
17
|
+
|| kind === 'schedule-receipt';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createAgentWorkspaceOperationsCommandEditor(kind: AgentWorkspaceOperationsCommandEditorKind): AgentWorkspaceLocalEditor {
|
|
21
|
+
if (kind === 'plan-seed') {
|
|
22
|
+
return {
|
|
23
|
+
kind,
|
|
24
|
+
mode: 'create',
|
|
25
|
+
title: 'Seed Planning Goal',
|
|
26
|
+
selectedFieldIndex: 0,
|
|
27
|
+
message: 'Seed Agent planning state from a concrete goal. This stays in the main Agent planning flow and does not spawn coding agents.',
|
|
28
|
+
fields: [
|
|
29
|
+
{ id: 'goal', label: 'Planning goal', value: '', required: true, multiline: true, hint: 'Describe the goal or operating plan to evaluate. Ctrl-J inserts a new line.' },
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (kind === 'health-repair') {
|
|
34
|
+
return {
|
|
35
|
+
kind,
|
|
36
|
+
mode: 'create',
|
|
37
|
+
title: 'Show Health Repair Guidance',
|
|
38
|
+
selectedFieldIndex: 0,
|
|
39
|
+
message: 'Show health repair guidance for one domain. Agent does not start services or mutate connected-host lifecycle.',
|
|
40
|
+
fields: [
|
|
41
|
+
{ id: 'domain', label: 'Domain', value: 'settings', required: true, multiline: false, hint: 'settings, auth, accounts, host, remote, mcp, continuity, or maintenance.' },
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (kind === 'approval-review') {
|
|
46
|
+
return {
|
|
47
|
+
kind,
|
|
48
|
+
mode: 'create',
|
|
49
|
+
title: 'Review Approval Class',
|
|
50
|
+
selectedFieldIndex: 0,
|
|
51
|
+
message: 'Review one approval class without approving, denying, or mutating pending requests.',
|
|
52
|
+
fields: [
|
|
53
|
+
{ id: 'kind', label: 'Approval kind', value: 'shell', required: true, multiline: false, hint: 'shell, file, network, delegate, mcp, remote, hook, or plugin.' },
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (kind === 'plan-approve') {
|
|
58
|
+
return {
|
|
59
|
+
kind,
|
|
60
|
+
mode: 'update',
|
|
61
|
+
title: 'Approve Planning State',
|
|
62
|
+
selectedFieldIndex: 0,
|
|
63
|
+
message: 'Approve the current Agent planning state for execution. This changes planning state and requires typed confirmation.',
|
|
64
|
+
fields: [
|
|
65
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /plan approve with --yes.' },
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (kind === 'plan-override') {
|
|
70
|
+
return {
|
|
71
|
+
kind,
|
|
72
|
+
mode: 'update',
|
|
73
|
+
title: 'Override Planning Strategy',
|
|
74
|
+
selectedFieldIndex: 0,
|
|
75
|
+
message: 'Override the planner strategy through the runtime bridge. This changes planner state and requires typed confirmation.',
|
|
76
|
+
fields: [
|
|
77
|
+
{ id: 'strategy', label: 'Strategy', value: 'serial', required: true, multiline: false, hint: 'Planner strategy, such as serial.' },
|
|
78
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /plan override with --yes.' },
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
if (kind === 'plan-clear') {
|
|
83
|
+
return {
|
|
84
|
+
kind,
|
|
85
|
+
mode: 'delete',
|
|
86
|
+
title: 'Clear Planning State',
|
|
87
|
+
selectedFieldIndex: 0,
|
|
88
|
+
message: 'Clear planner state. This is destructive and requires typed confirmation.',
|
|
89
|
+
fields: [
|
|
90
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /plan clear with --yes.' },
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (kind === 'routine-receipt' || kind === 'schedule-receipt') {
|
|
95
|
+
const routine = kind === 'routine-receipt';
|
|
96
|
+
return {
|
|
97
|
+
kind,
|
|
98
|
+
mode: 'create',
|
|
99
|
+
title: routine ? 'Show Routine Promotion Receipt' : 'Show Schedule Receipt',
|
|
100
|
+
selectedFieldIndex: 0,
|
|
101
|
+
message: routine
|
|
102
|
+
? 'Show one local routine schedule-promotion receipt without reconciling or mutating connected schedules.'
|
|
103
|
+
: 'Show one local schedule receipt without reconciling or mutating connected schedules.',
|
|
104
|
+
fields: [
|
|
105
|
+
{ id: 'receiptId', label: 'Receipt id', value: '', required: true, multiline: false, hint: 'Receipt id from Promotion receipts.' },
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
kind,
|
|
111
|
+
mode: 'create',
|
|
112
|
+
title: 'Show Saved Plan',
|
|
113
|
+
selectedFieldIndex: 0,
|
|
114
|
+
message: 'Show one saved execution plan by id or prefix without approving or starting execution.',
|
|
115
|
+
fields: [
|
|
116
|
+
{ id: 'planId', label: 'Plan id', value: '', required: true, multiline: false, hint: 'Plan id or unique prefix from Saved plans.' },
|
|
117
|
+
],
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
import type { AgentWorkspaceProviderCommandEditorKind } from './agent-workspace-provider-command-editors.ts';
|
|
3
|
+
import { isAgentWorkspaceProviderCommandEditorKind } from './agent-workspace-provider-command-editors.ts';
|
|
4
|
+
import { quoteSlashCommandArg } from './slash-command-parser.ts';
|
|
5
|
+
|
|
6
|
+
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
7
|
+
|
|
8
|
+
export type AgentWorkspaceProviderCommandEditorSubmission =
|
|
9
|
+
| {
|
|
10
|
+
readonly kind: 'editor';
|
|
11
|
+
readonly editor: AgentWorkspaceLocalEditor;
|
|
12
|
+
readonly status: string;
|
|
13
|
+
readonly actionResult?: AgentWorkspaceActionResult;
|
|
14
|
+
}
|
|
15
|
+
| {
|
|
16
|
+
readonly kind: 'dispatch';
|
|
17
|
+
readonly command: string;
|
|
18
|
+
readonly status: string;
|
|
19
|
+
readonly actionResult: AgentWorkspaceActionResult;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function isAffirmative(value: string): boolean {
|
|
23
|
+
return /^(y|yes|true)$/i.test(value.trim());
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function unconfirmed(editor: AgentWorkspaceLocalEditor, label: string): AgentWorkspaceProviderCommandEditorSubmission {
|
|
27
|
+
return {
|
|
28
|
+
kind: 'editor',
|
|
29
|
+
editor: { ...editor, message: `${label} not confirmed. Type yes, then press Enter.` },
|
|
30
|
+
status: `${label} not confirmed.`,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function isAgentWorkspaceProviderCommandSubmissionKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceProviderCommandEditorKind {
|
|
35
|
+
return isAgentWorkspaceProviderCommandEditorKind(kind);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function buildAgentWorkspaceProviderCommandEditorSubmission(
|
|
39
|
+
editor: AgentWorkspaceLocalEditor,
|
|
40
|
+
readField: AgentWorkspaceFieldReader,
|
|
41
|
+
): AgentWorkspaceProviderCommandEditorSubmission {
|
|
42
|
+
if (editor.kind === 'provider-use') {
|
|
43
|
+
const model = readField('model');
|
|
44
|
+
const command = [
|
|
45
|
+
'/provider',
|
|
46
|
+
quoteSlashCommandArg(readField('provider')),
|
|
47
|
+
...(model.length > 0 ? [quoteSlashCommandArg(model)] : []),
|
|
48
|
+
].join(' ');
|
|
49
|
+
return {
|
|
50
|
+
kind: 'dispatch',
|
|
51
|
+
command,
|
|
52
|
+
status: 'Opening provider selection.',
|
|
53
|
+
actionResult: {
|
|
54
|
+
kind: 'dispatched',
|
|
55
|
+
title: 'Opening provider selection',
|
|
56
|
+
detail: 'The workspace handed provider selection to the shell-owned command router.',
|
|
57
|
+
command,
|
|
58
|
+
safety: 'safe',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (editor.kind === 'provider-inspect') {
|
|
63
|
+
const command = `/accounts show ${quoteSlashCommandArg(readField('provider'))}`;
|
|
64
|
+
return {
|
|
65
|
+
kind: 'dispatch',
|
|
66
|
+
command,
|
|
67
|
+
status: 'Opening provider inspection.',
|
|
68
|
+
actionResult: {
|
|
69
|
+
kind: 'dispatched',
|
|
70
|
+
title: 'Opening provider inspection',
|
|
71
|
+
detail: 'The workspace handed read-only provider inspection to the shell-owned command router.',
|
|
72
|
+
command,
|
|
73
|
+
safety: 'read-only',
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (editor.kind === 'provider-routes') {
|
|
78
|
+
const command = `/accounts routes ${quoteSlashCommandArg(readField('provider'))}`;
|
|
79
|
+
return {
|
|
80
|
+
kind: 'dispatch',
|
|
81
|
+
command,
|
|
82
|
+
status: 'Opening provider route inspection.',
|
|
83
|
+
actionResult: {
|
|
84
|
+
kind: 'dispatched',
|
|
85
|
+
title: 'Opening provider route inspection',
|
|
86
|
+
detail: 'The workspace handed read-only provider route inspection to the shell-owned command router.',
|
|
87
|
+
command,
|
|
88
|
+
safety: 'read-only',
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (editor.kind === 'provider-account-repair') {
|
|
93
|
+
const command = `/accounts repair ${quoteSlashCommandArg(readField('provider'))}`;
|
|
94
|
+
return {
|
|
95
|
+
kind: 'dispatch',
|
|
96
|
+
command,
|
|
97
|
+
status: 'Opening provider account repair review.',
|
|
98
|
+
actionResult: {
|
|
99
|
+
kind: 'dispatched',
|
|
100
|
+
title: 'Opening provider account repair review',
|
|
101
|
+
detail: 'The workspace handed read-only provider account repair guidance to the shell-owned command router.',
|
|
102
|
+
command,
|
|
103
|
+
safety: 'read-only',
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (editor.kind === 'provider-add') {
|
|
108
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
109
|
+
return unconfirmed(editor, 'Custom provider add');
|
|
110
|
+
}
|
|
111
|
+
const key = readField('apiKey');
|
|
112
|
+
const parts = [
|
|
113
|
+
'/provider',
|
|
114
|
+
'add',
|
|
115
|
+
quoteSlashCommandArg(readField('name')),
|
|
116
|
+
quoteSlashCommandArg(readField('baseUrl')),
|
|
117
|
+
];
|
|
118
|
+
const redactedParts = [...parts];
|
|
119
|
+
if (key.length > 0) {
|
|
120
|
+
parts.push(quoteSlashCommandArg(key));
|
|
121
|
+
redactedParts.push('<redacted-api-key>');
|
|
122
|
+
}
|
|
123
|
+
parts.push('--yes');
|
|
124
|
+
redactedParts.push('--yes');
|
|
125
|
+
return {
|
|
126
|
+
kind: 'dispatch',
|
|
127
|
+
command: parts.join(' '),
|
|
128
|
+
status: 'Opening custom provider add.',
|
|
129
|
+
actionResult: {
|
|
130
|
+
kind: 'dispatched',
|
|
131
|
+
title: 'Opening custom provider add',
|
|
132
|
+
detail: 'The workspace handed a confirmed custom provider add command to the shell-owned command router without rendering the raw API key.',
|
|
133
|
+
command: redactedParts.join(' '),
|
|
134
|
+
safety: 'safe',
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
140
|
+
return unconfirmed(editor, 'Custom provider removal');
|
|
141
|
+
}
|
|
142
|
+
const command = `/provider remove ${quoteSlashCommandArg(readField('name'))} --yes`;
|
|
143
|
+
return {
|
|
144
|
+
kind: 'dispatch',
|
|
145
|
+
command,
|
|
146
|
+
status: 'Opening custom provider removal.',
|
|
147
|
+
actionResult: {
|
|
148
|
+
kind: 'dispatched',
|
|
149
|
+
title: 'Opening custom provider removal',
|
|
150
|
+
detail: 'The workspace handed a confirmed custom provider removal command to the shell-owned command router.',
|
|
151
|
+
command,
|
|
152
|
+
safety: 'safe',
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
|
|
3
|
+
export type AgentWorkspaceProviderCommandEditorKind = Extract<
|
|
4
|
+
AgentWorkspaceEditorKind,
|
|
5
|
+
'provider-add' | 'provider-remove' | 'provider-use' | 'provider-inspect' | 'provider-routes' | 'provider-account-repair'
|
|
6
|
+
>;
|
|
7
|
+
|
|
8
|
+
export function isAgentWorkspaceProviderCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceProviderCommandEditorKind {
|
|
9
|
+
return kind === 'provider-add'
|
|
10
|
+
|| kind === 'provider-remove'
|
|
11
|
+
|| kind === 'provider-use'
|
|
12
|
+
|| kind === 'provider-inspect'
|
|
13
|
+
|| kind === 'provider-routes'
|
|
14
|
+
|| kind === 'provider-account-repair';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createAgentWorkspaceProviderCommandEditor(kind: AgentWorkspaceProviderCommandEditorKind): AgentWorkspaceLocalEditor {
|
|
18
|
+
if (kind === 'provider-use') {
|
|
19
|
+
return {
|
|
20
|
+
kind,
|
|
21
|
+
mode: 'create',
|
|
22
|
+
title: 'Use Provider',
|
|
23
|
+
selectedFieldIndex: 0,
|
|
24
|
+
message: 'Switch the Agent chat provider through the TUI command router. Add a model id when you want an exact provider/model route.',
|
|
25
|
+
fields: [
|
|
26
|
+
{ id: 'provider', label: 'Provider id', value: '', required: true, multiline: false, hint: 'Provider row id, such as openai-subscriber, openai, anthropic, or a custom provider.' },
|
|
27
|
+
{ id: 'model', label: 'Model id', value: '', required: false, multiline: false, hint: 'Optional model id or provider:model registry key. Blank uses the provider default selectable model.' },
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (kind === 'provider-inspect') {
|
|
32
|
+
return {
|
|
33
|
+
kind,
|
|
34
|
+
mode: 'create',
|
|
35
|
+
title: 'Inspect Provider',
|
|
36
|
+
selectedFieldIndex: 0,
|
|
37
|
+
message: 'Inspect provider auth and setup routes from the Agent TUI without changing provider selection.',
|
|
38
|
+
fields: [
|
|
39
|
+
{ id: 'provider', label: 'Provider id', value: '', required: true, multiline: false, hint: 'Provider row id to inspect.' },
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (kind === 'provider-routes') {
|
|
44
|
+
return {
|
|
45
|
+
kind,
|
|
46
|
+
mode: 'create',
|
|
47
|
+
title: 'Inspect Provider Routes',
|
|
48
|
+
selectedFieldIndex: 0,
|
|
49
|
+
message: 'Inspect provider account routes from the Agent TUI without changing routing or auth.',
|
|
50
|
+
fields: [
|
|
51
|
+
{ id: 'provider', label: 'Provider id', value: '', required: true, multiline: false, hint: 'Provider row id to inspect.' },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (kind === 'provider-account-repair') {
|
|
56
|
+
return {
|
|
57
|
+
kind,
|
|
58
|
+
mode: 'create',
|
|
59
|
+
title: 'Review Provider Account Repair',
|
|
60
|
+
selectedFieldIndex: 0,
|
|
61
|
+
message: 'Show provider account repair guidance from the Agent TUI without starting login or storing tokens.',
|
|
62
|
+
fields: [
|
|
63
|
+
{ id: 'provider', label: 'Provider id', value: '', required: true, multiline: false, hint: 'Provider row id to inspect.' },
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (kind === 'provider-add') {
|
|
68
|
+
return {
|
|
69
|
+
kind,
|
|
70
|
+
mode: 'create',
|
|
71
|
+
title: 'Add Custom Provider',
|
|
72
|
+
selectedFieldIndex: 0,
|
|
73
|
+
message: 'Add an OpenAI-compatible provider for Agent chat/model routing. Type yes on the final field to confirm.',
|
|
74
|
+
fields: [
|
|
75
|
+
{ id: 'name', label: 'Provider name', value: '', required: true, multiline: false, hint: 'Letters, numbers, hyphens, and underscores only.' },
|
|
76
|
+
{ id: 'baseUrl', label: 'Base URL', value: '', required: true, multiline: false, hint: 'OpenAI-compatible base URL, such as http://127.0.0.1:8000/v1.' },
|
|
77
|
+
{ id: 'apiKey', label: 'API key', value: '', required: false, multiline: false, hint: 'Optional API key. Prefer a local provider or a secret-backed provider config when possible.', redact: true },
|
|
78
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /provider add with --yes.' },
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
kind,
|
|
84
|
+
mode: 'delete',
|
|
85
|
+
title: 'Remove Custom Provider',
|
|
86
|
+
selectedFieldIndex: 0,
|
|
87
|
+
message: 'Remove one custom provider config from the Agent provider list. Type yes on the final field to confirm.',
|
|
88
|
+
fields: [
|
|
89
|
+
{ id: 'name', label: 'Provider name', value: '', required: true, multiline: false, hint: 'Existing custom provider name.' },
|
|
90
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /provider remove with --yes.' },
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { buildAgentSkillRequirements, type AgentSkillRequirement } from '../agent/skill-registry.ts';
|
|
2
|
+
import { splitList } from './agent-workspace-editors.ts';
|
|
3
|
+
|
|
4
|
+
export type AgentWorkspaceEditorFieldReader = (fieldId: string) => string;
|
|
5
|
+
|
|
6
|
+
export function buildAgentWorkspaceRequirements(readField: AgentWorkspaceEditorFieldReader): readonly AgentSkillRequirement[] {
|
|
7
|
+
return buildAgentSkillRequirements({
|
|
8
|
+
env: splitList(readField('requiresEnv')),
|
|
9
|
+
commands: splitList(readField('requiresCommands')),
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
import { quoteSlashCommandArg } from './slash-command-parser.ts';
|
|
3
|
+
|
|
4
|
+
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
5
|
+
|
|
6
|
+
type AgentWorkspaceSecretEditorSubmission =
|
|
7
|
+
| {
|
|
8
|
+
readonly kind: 'editor';
|
|
9
|
+
readonly editor: AgentWorkspaceLocalEditor;
|
|
10
|
+
readonly status: string;
|
|
11
|
+
readonly actionResult?: AgentWorkspaceActionResult;
|
|
12
|
+
}
|
|
13
|
+
| {
|
|
14
|
+
readonly kind: 'dispatch';
|
|
15
|
+
readonly command: string;
|
|
16
|
+
readonly status: string;
|
|
17
|
+
readonly actionResult: AgentWorkspaceActionResult;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function isAffirmative(value: string): boolean {
|
|
21
|
+
return /^(y|yes|true)$/i.test(value.trim());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function secretScopeFlag(scope: string): string | null {
|
|
25
|
+
const normalized = scope.trim().toLowerCase();
|
|
26
|
+
if (normalized === 'user') return '--user';
|
|
27
|
+
if (normalized === 'project') return '--project';
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function secretStorageFlag(storage: string): string | null {
|
|
32
|
+
const normalized = storage.trim().toLowerCase();
|
|
33
|
+
if (normalized === 'plaintext') return '--plaintext';
|
|
34
|
+
if (normalized === 'secure') return '--secure';
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function appendOptionalSecretFlags(parts: string[], scope: string, storage: string): void {
|
|
39
|
+
const scopeFlag = secretScopeFlag(scope);
|
|
40
|
+
const storageFlag = secretStorageFlag(storage);
|
|
41
|
+
if (scopeFlag) parts.push(scopeFlag);
|
|
42
|
+
if (storageFlag) parts.push(storageFlag);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function isAgentWorkspaceSecretEditorKind(kind: AgentWorkspaceLocalEditor['kind']): kind is 'secret-set' | 'secret-link' | 'secret-test' | 'secret-delete' {
|
|
46
|
+
return kind === 'secret-set' || kind === 'secret-link' || kind === 'secret-test' || kind === 'secret-delete';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function buildAgentWorkspaceSecretEditorSubmission(
|
|
50
|
+
editor: AgentWorkspaceLocalEditor,
|
|
51
|
+
readField: AgentWorkspaceFieldReader,
|
|
52
|
+
): AgentWorkspaceSecretEditorSubmission {
|
|
53
|
+
if (editor.kind === 'secret-set') {
|
|
54
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
55
|
+
return {
|
|
56
|
+
kind: 'editor',
|
|
57
|
+
editor: { ...editor, message: 'Secret value storage not confirmed. Type yes, then press Enter.' },
|
|
58
|
+
status: 'Secret value storage not confirmed.',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const key = readField('key');
|
|
62
|
+
const parts = ['/secrets', 'set', quoteSlashCommandArg(key), quoteSlashCommandArg(readField('value'))];
|
|
63
|
+
appendOptionalSecretFlags(parts, readField('scope'), readField('storage'));
|
|
64
|
+
parts.push('--yes');
|
|
65
|
+
const redactedParts = ['/secrets', 'set', quoteSlashCommandArg(key), '<redacted>'];
|
|
66
|
+
appendOptionalSecretFlags(redactedParts, readField('scope'), readField('storage'));
|
|
67
|
+
redactedParts.push('--yes');
|
|
68
|
+
return {
|
|
69
|
+
kind: 'dispatch',
|
|
70
|
+
command: parts.join(' '),
|
|
71
|
+
status: 'Opening secret value storage.',
|
|
72
|
+
actionResult: {
|
|
73
|
+
kind: 'dispatched',
|
|
74
|
+
title: 'Opening secret value storage',
|
|
75
|
+
detail: 'The workspace handed a confirmed secret value storage command to the shell-owned command router without rendering the raw value.',
|
|
76
|
+
command: redactedParts.join(' '),
|
|
77
|
+
safety: 'safe',
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (editor.kind === 'secret-link') {
|
|
82
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
83
|
+
return {
|
|
84
|
+
kind: 'editor',
|
|
85
|
+
editor: { ...editor, message: 'Secret reference link not confirmed. Type yes, then press Enter.' },
|
|
86
|
+
status: 'Secret reference link not confirmed.',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const key = readField('key');
|
|
90
|
+
const parts = ['/secrets', 'link', quoteSlashCommandArg(key), quoteSlashCommandArg(readField('ref'))];
|
|
91
|
+
appendOptionalSecretFlags(parts, readField('scope'), readField('storage'));
|
|
92
|
+
parts.push('--yes');
|
|
93
|
+
const redactedParts = ['/secrets', 'link', quoteSlashCommandArg(key), '<secret-ref>'];
|
|
94
|
+
appendOptionalSecretFlags(redactedParts, readField('scope'), readField('storage'));
|
|
95
|
+
redactedParts.push('--yes');
|
|
96
|
+
return {
|
|
97
|
+
kind: 'dispatch',
|
|
98
|
+
command: parts.join(' '),
|
|
99
|
+
status: 'Opening secret reference link.',
|
|
100
|
+
actionResult: {
|
|
101
|
+
kind: 'dispatched',
|
|
102
|
+
title: 'Opening secret reference link',
|
|
103
|
+
detail: 'The workspace handed a confirmed secret reference link command to the shell-owned command router without rendering the full reference.',
|
|
104
|
+
command: redactedParts.join(' '),
|
|
105
|
+
safety: 'safe',
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (editor.kind === 'secret-test') {
|
|
110
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
111
|
+
return {
|
|
112
|
+
kind: 'editor',
|
|
113
|
+
editor: { ...editor, message: 'Secret reference test not confirmed. Type yes, then press Enter.' },
|
|
114
|
+
status: 'Secret reference test not confirmed.',
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
kind: 'dispatch',
|
|
119
|
+
command: `/secrets test ${quoteSlashCommandArg(readField('ref'))}`,
|
|
120
|
+
status: 'Opening secret reference test.',
|
|
121
|
+
actionResult: {
|
|
122
|
+
kind: 'dispatched',
|
|
123
|
+
title: 'Opening secret reference test',
|
|
124
|
+
detail: 'The workspace handed a confirmed secret reference test command to the shell-owned command router; the command output remains redacted.',
|
|
125
|
+
command: '/secrets test <secret-ref>',
|
|
126
|
+
safety: 'safe',
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
131
|
+
return {
|
|
132
|
+
kind: 'editor',
|
|
133
|
+
editor: { ...editor, message: 'Secret deletion not confirmed. Type yes, then press Enter.' },
|
|
134
|
+
status: 'Secret deletion not confirmed.',
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
const key = readField('key');
|
|
138
|
+
const parts = ['/secrets', 'delete', quoteSlashCommandArg(key)];
|
|
139
|
+
appendOptionalSecretFlags(parts, readField('scope'), readField('storage'));
|
|
140
|
+
parts.push('--yes');
|
|
141
|
+
return {
|
|
142
|
+
kind: 'dispatch',
|
|
143
|
+
command: parts.join(' '),
|
|
144
|
+
status: 'Opening secret deletion.',
|
|
145
|
+
actionResult: {
|
|
146
|
+
kind: 'dispatched',
|
|
147
|
+
title: 'Opening secret deletion',
|
|
148
|
+
detail: 'The workspace handed a confirmed secret deletion command to the shell-owned command router.',
|
|
149
|
+
command: parts.join(' '),
|
|
150
|
+
safety: 'safe',
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|