@pellux/goodvibes-agent 0.1.114 → 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 -650
- package/README.md +40 -50
- package/dist/package/main.js +38224 -35673
- package/docs/README.md +5 -4
- package/docs/{connected-services.md → connected-host.md} +18 -10
- package/docs/getting-started.md +43 -42
- package/docs/release-and-publishing.md +6 -4
- package/package.json +3 -3
- package/src/agent/behavior-discovery-summary.ts +165 -0
- 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 +331 -0
- package/src/agent/runtime-profile.ts +228 -330
- 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 +247 -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 +787 -0
- package/src/input/agent-workspace-basic-command-editors.ts +524 -459
- package/src/input/agent-workspace-categories.ts +177 -14
- 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 +25 -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 +49 -19
- 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 +56 -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 +124 -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 +160 -6
- 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 +126 -11
- package/src/input/onboarding/onboarding-wizard-steps.ts +15 -8
- 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 +52 -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 +25 -6
- package/src/runtime/onboarding/snapshot.ts +4 -2
- package/src/runtime/onboarding/types.ts +28 -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,55 @@
|
|
|
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
|
+
export type AgentWorkspaceDelegationEditorSubmission =
|
|
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
|
+
export function isAgentWorkspaceDelegationEditorKind(kind: string): kind is 'delegate-task' {
|
|
25
|
+
return kind === 'delegate-task';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function buildAgentWorkspaceDelegationEditorSubmission(
|
|
29
|
+
editor: AgentWorkspaceLocalEditor,
|
|
30
|
+
readField: AgentWorkspaceFieldReader,
|
|
31
|
+
): AgentWorkspaceDelegationEditorSubmission {
|
|
32
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
33
|
+
return {
|
|
34
|
+
kind: 'editor',
|
|
35
|
+
editor: { ...editor, message: 'Build delegation not confirmed. Type yes, then press Enter.' },
|
|
36
|
+
status: 'Build delegation not confirmed.',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const parts = ['/delegate'];
|
|
40
|
+
if (isAffirmative(readField('wrfc'))) parts.push('--wrfc');
|
|
41
|
+
parts.push(quoteSlashCommandArg(readField('task')));
|
|
42
|
+
const command = parts.join(' ');
|
|
43
|
+
return {
|
|
44
|
+
kind: 'dispatch',
|
|
45
|
+
command,
|
|
46
|
+
status: 'Opening explicit build delegation.',
|
|
47
|
+
actionResult: {
|
|
48
|
+
kind: 'dispatched',
|
|
49
|
+
title: 'Opening explicit build delegation',
|
|
50
|
+
detail: 'The workspace handed a confirmed build/fix/review task to the shell-owned command router.',
|
|
51
|
+
command,
|
|
52
|
+
safety: 'delegates',
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -30,6 +30,25 @@ export function createProfileEditor(templates: readonly AgentWorkspaceRuntimeSta
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
export function createLearnedBehaviorEditor(): AgentWorkspaceLocalEditor {
|
|
34
|
+
return {
|
|
35
|
+
kind: 'learned-behavior',
|
|
36
|
+
mode: 'create',
|
|
37
|
+
title: 'Capture Learned Behavior',
|
|
38
|
+
selectedFieldIndex: 0,
|
|
39
|
+
message: 'Turn a reviewed workflow or lesson into local Agent behavior. This writes only to local personas, skills, or routines.',
|
|
40
|
+
fields: [
|
|
41
|
+
{ id: 'target', label: 'Behavior type', value: 'skill', required: true, multiline: false, hint: 'skill, routine, or persona.' },
|
|
42
|
+
{ id: 'name', label: 'Name', value: '', required: true, multiline: false, hint: 'Short name for the learned behavior.' },
|
|
43
|
+
{ id: 'description', label: 'Description', value: '', required: true, multiline: false, hint: 'One-line summary of when to use it.' },
|
|
44
|
+
{ id: 'notes', label: 'Lesson or workflow', value: '', required: true, multiline: true, hint: 'Paste the procedure, persona guidance, or repeatable workflow. Ctrl-J inserts a new line.' },
|
|
45
|
+
{ id: 'triggers', label: 'Triggers', value: '', required: false, multiline: false, hint: 'Comma-separated words that suggest this behavior.' },
|
|
46
|
+
{ id: 'tags', label: 'Tags', value: 'learned', required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
47
|
+
{ id: 'enable', label: 'Enable or activate', value: 'yes', required: false, multiline: false, hint: 'yes/no. Skills and routines enable; personas activate.' },
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
33
52
|
export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind | 'knowledge-url'): AgentWorkspaceLocalEditor {
|
|
34
53
|
if (kind === 'profile') return createProfileEditor([]);
|
|
35
54
|
if (kind === 'knowledge-url') {
|
|
@@ -94,6 +113,8 @@ export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind | 'knowled
|
|
|
94
113
|
{ id: 'procedure', label: 'Procedure', value: '', required: true, multiline: true, hint: 'Reusable steps. Ctrl-J inserts a new line.' },
|
|
95
114
|
{ id: 'triggers', label: 'Triggers', value: '', required: false, multiline: false, hint: 'Comma-separated words that suggest this skill.' },
|
|
96
115
|
{ id: 'tags', label: 'Tags', value: '', required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
116
|
+
{ id: 'requiresEnv', label: 'Required env vars', value: '', required: false, multiline: false, hint: 'Comma-separated env var names. Values are never stored.' },
|
|
117
|
+
{ id: 'requiresCommands', label: 'Required commands', value: '', required: false, multiline: false, hint: 'Comma-separated binaries that must be on PATH.' },
|
|
97
118
|
{ id: 'enabled', label: 'Enable now', value: 'yes', required: false, multiline: false, hint: 'yes/no.' },
|
|
98
119
|
],
|
|
99
120
|
};
|
|
@@ -110,6 +131,8 @@ export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind | 'knowled
|
|
|
110
131
|
{ id: 'steps', label: 'Steps', value: '', required: true, multiline: true, hint: 'Workflow steps. Ctrl-J inserts a new line.' },
|
|
111
132
|
{ id: 'triggers', label: 'Triggers', value: '', required: false, multiline: false, hint: 'Comma-separated words that suggest this routine.' },
|
|
112
133
|
{ id: 'tags', label: 'Tags', value: '', required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
134
|
+
{ id: 'requiresEnv', label: 'Required env vars', value: '', required: false, multiline: false, hint: 'Comma-separated env var names. Values are never stored.' },
|
|
135
|
+
{ id: 'requiresCommands', label: 'Required commands', value: '', required: false, multiline: false, hint: 'Comma-separated binaries that must be on PATH.' },
|
|
113
136
|
{ id: 'enabled', label: 'Enable now', value: 'yes', required: false, multiline: false, hint: 'yes/no.' },
|
|
114
137
|
],
|
|
115
138
|
};
|
|
@@ -165,6 +188,8 @@ export function createSkillUpdateEditor(record: AgentSkillRecord): AgentWorkspac
|
|
|
165
188
|
{ id: 'procedure', label: 'Procedure', value: record.procedure, required: true, multiline: true, hint: 'Reusable steps. Ctrl-J inserts a new line.' },
|
|
166
189
|
{ id: 'triggers', label: 'Triggers', value: record.triggers.join(', '), required: false, multiline: false, hint: 'Comma-separated words that suggest this skill.' },
|
|
167
190
|
{ id: 'tags', label: 'Tags', value: record.tags.join(', '), required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
191
|
+
{ id: 'requiresEnv', label: 'Required env vars', value: record.requirements.filter((requirement) => requirement.kind === 'env').map((requirement) => requirement.name).join(', '), required: false, multiline: false, hint: 'Comma-separated env var names. Values are never stored.' },
|
|
192
|
+
{ id: 'requiresCommands', label: 'Required commands', value: record.requirements.filter((requirement) => requirement.kind === 'command').map((requirement) => requirement.name).join(', '), required: false, multiline: false, hint: 'Comma-separated binaries that must be on PATH.' },
|
|
168
193
|
{ id: 'enabled', label: 'Enabled', value: record.enabled ? 'yes' : 'no', required: false, multiline: false, hint: 'yes/no.' },
|
|
169
194
|
],
|
|
170
195
|
};
|
|
@@ -184,6 +209,8 @@ export function createRoutineUpdateEditor(record: AgentRoutineRecord): AgentWork
|
|
|
184
209
|
{ id: 'steps', label: 'Steps', value: record.steps, required: true, multiline: true, hint: 'Workflow steps. Ctrl-J inserts a new line.' },
|
|
185
210
|
{ id: 'triggers', label: 'Triggers', value: record.triggers.join(', '), required: false, multiline: false, hint: 'Comma-separated words that suggest this routine.' },
|
|
186
211
|
{ id: 'tags', label: 'Tags', value: record.tags.join(', '), required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
212
|
+
{ id: 'requiresEnv', label: 'Required env vars', value: record.requirements.filter((requirement) => requirement.kind === 'env').map((requirement) => requirement.name).join(', '), required: false, multiline: false, hint: 'Comma-separated env var names. Values are never stored.' },
|
|
213
|
+
{ id: 'requiresCommands', label: 'Required commands', value: record.requirements.filter((requirement) => requirement.kind === 'command').map((requirement) => requirement.name).join(', '), required: false, multiline: false, hint: 'Comma-separated binaries that must be on PATH.' },
|
|
187
214
|
{ id: 'enabled', label: 'Enabled', value: record.enabled ? 'yes' : 'no', required: false, multiline: false, hint: 'yes/no.' },
|
|
188
215
|
],
|
|
189
216
|
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
import type { AgentWorkspaceKnowledgeCommandEditorKind } from './agent-workspace-knowledge-command-editors.ts';
|
|
3
|
+
import { isAgentWorkspaceKnowledgeCommandEditorKind } from './agent-workspace-knowledge-command-editors.ts';
|
|
4
|
+
import { quoteSlashCommandArg } from './slash-command-parser.ts';
|
|
5
|
+
|
|
6
|
+
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
7
|
+
|
|
8
|
+
export type AgentWorkspaceKnowledgeCommandEditorSubmission =
|
|
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
|
+
export function isAgentWorkspaceKnowledgeCommandSubmissionKind(kind: string): kind is AgentWorkspaceKnowledgeCommandEditorKind {
|
|
23
|
+
return isAgentWorkspaceKnowledgeCommandEditorKind(kind as AgentWorkspaceKnowledgeCommandEditorKind);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isAffirmative(value: string): boolean {
|
|
27
|
+
return /^(y|yes|true)$/i.test(value.trim());
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function splitCommaList(value: string): readonly string[] {
|
|
31
|
+
return value.split(',').map((entry) => entry.trim()).filter(Boolean);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function unconfirmed(editor: AgentWorkspaceLocalEditor, message: string): AgentWorkspaceKnowledgeCommandEditorSubmission {
|
|
35
|
+
return {
|
|
36
|
+
kind: 'editor',
|
|
37
|
+
editor: { ...editor, message },
|
|
38
|
+
status: message,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function dispatch(command: string, title: string, detail: string, safety: AgentWorkspaceActionResult['safety']): AgentWorkspaceKnowledgeCommandEditorSubmission {
|
|
43
|
+
return {
|
|
44
|
+
kind: 'dispatch',
|
|
45
|
+
command,
|
|
46
|
+
status: `${title}.`,
|
|
47
|
+
actionResult: { kind: 'dispatched', title, detail, command, safety },
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function buildAgentWorkspaceKnowledgeCommandEditorSubmission(
|
|
52
|
+
editor: AgentWorkspaceLocalEditor,
|
|
53
|
+
readField: AgentWorkspaceFieldReader,
|
|
54
|
+
): AgentWorkspaceKnowledgeCommandEditorSubmission {
|
|
55
|
+
if (editor.kind === 'knowledge-get') {
|
|
56
|
+
return dispatch(
|
|
57
|
+
`/knowledge get ${quoteSlashCommandArg(readField('id'))}`,
|
|
58
|
+
'Opening Agent Knowledge item',
|
|
59
|
+
'The workspace handed a read-only Agent Knowledge item command to the shell-owned command router.',
|
|
60
|
+
'read-only',
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
if (editor.kind === 'knowledge-map') {
|
|
64
|
+
const query = readField('query');
|
|
65
|
+
const limit = readField('limit');
|
|
66
|
+
const parts = ['/knowledge', 'map'];
|
|
67
|
+
if (query.length > 0) parts.push(quoteSlashCommandArg(query));
|
|
68
|
+
if (limit.length > 0) parts.push('--limit', quoteSlashCommandArg(limit));
|
|
69
|
+
return dispatch(
|
|
70
|
+
parts.join(' '),
|
|
71
|
+
'Opening Agent Knowledge map',
|
|
72
|
+
'The workspace handed a read-only Agent Knowledge map command to the shell-owned command router.',
|
|
73
|
+
'read-only',
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
if (editor.kind === 'knowledge-connector-show') {
|
|
77
|
+
return dispatch(
|
|
78
|
+
`/knowledge connectors ${quoteSlashCommandArg(readField('connectorId'))}`,
|
|
79
|
+
'Opening Agent Knowledge connector',
|
|
80
|
+
'The workspace handed a read-only Agent Knowledge connector detail command to the shell-owned command router.',
|
|
81
|
+
'read-only',
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (editor.kind === 'knowledge-connector-doctor') {
|
|
85
|
+
return dispatch(
|
|
86
|
+
`/knowledge connectors doctor ${quoteSlashCommandArg(readField('connectorId'))}`,
|
|
87
|
+
'Opening Agent Knowledge connector doctor',
|
|
88
|
+
'The workspace handed a read-only Agent Knowledge connector doctor command to the shell-owned command router.',
|
|
89
|
+
'read-only',
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
if (editor.kind === 'knowledge-review-issue') {
|
|
93
|
+
if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Agent Knowledge issue review not confirmed. Type yes, then press Enter.');
|
|
94
|
+
const parts = [
|
|
95
|
+
'/knowledge',
|
|
96
|
+
'review-issue',
|
|
97
|
+
quoteSlashCommandArg(readField('issueId')),
|
|
98
|
+
quoteSlashCommandArg(readField('action')),
|
|
99
|
+
];
|
|
100
|
+
const reviewer = readField('reviewer');
|
|
101
|
+
const value = readField('value');
|
|
102
|
+
if (reviewer.length > 0) parts.push('--reviewer', quoteSlashCommandArg(reviewer));
|
|
103
|
+
if (value.length > 0) parts.push('--value', quoteSlashCommandArg(value));
|
|
104
|
+
parts.push('--yes');
|
|
105
|
+
return dispatch(
|
|
106
|
+
parts.join(' '),
|
|
107
|
+
'Opening Agent Knowledge issue review',
|
|
108
|
+
'The workspace handed a confirmed Agent Knowledge issue review command to the shell-owned command router.',
|
|
109
|
+
'safe',
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
if (editor.kind === 'knowledge-consolidate') {
|
|
113
|
+
if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Agent Knowledge consolidation not confirmed. Type yes, then press Enter.');
|
|
114
|
+
return dispatch(
|
|
115
|
+
`/knowledge consolidate ${quoteSlashCommandArg(readField('mode'))} --yes`,
|
|
116
|
+
'Opening Agent Knowledge consolidation',
|
|
117
|
+
'The workspace handed a confirmed Agent Knowledge consolidation command to the shell-owned command router.',
|
|
118
|
+
'safe',
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
const subcommand = editor.kind === 'knowledge-explain' ? 'explain' : 'packet';
|
|
122
|
+
const parts = ['/knowledge', subcommand, quoteSlashCommandArg(readField('task'))];
|
|
123
|
+
for (const scope of splitCommaList(readField('scopes'))) {
|
|
124
|
+
parts.push('--scope', quoteSlashCommandArg(scope));
|
|
125
|
+
}
|
|
126
|
+
return dispatch(
|
|
127
|
+
parts.join(' '),
|
|
128
|
+
subcommand === 'explain' ? 'Opening Agent Knowledge explanation' : 'Opening Agent Knowledge prompt packet',
|
|
129
|
+
'The workspace handed a read-only Agent Knowledge context command to the shell-owned command router.',
|
|
130
|
+
'read-only',
|
|
131
|
+
);
|
|
132
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
|
|
3
|
+
export type AgentWorkspaceKnowledgeCommandEditorKind = Extract<
|
|
4
|
+
AgentWorkspaceEditorKind,
|
|
5
|
+
| 'knowledge-get'
|
|
6
|
+
| 'knowledge-map'
|
|
7
|
+
| 'knowledge-connector-show'
|
|
8
|
+
| 'knowledge-connector-doctor'
|
|
9
|
+
| 'knowledge-review-issue'
|
|
10
|
+
| 'knowledge-consolidate'
|
|
11
|
+
| 'knowledge-packet'
|
|
12
|
+
| 'knowledge-explain'
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
export function isAgentWorkspaceKnowledgeCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceKnowledgeCommandEditorKind {
|
|
16
|
+
return kind === 'knowledge-get'
|
|
17
|
+
|| kind === 'knowledge-map'
|
|
18
|
+
|| kind === 'knowledge-connector-show'
|
|
19
|
+
|| kind === 'knowledge-connector-doctor'
|
|
20
|
+
|| kind === 'knowledge-review-issue'
|
|
21
|
+
|| kind === 'knowledge-consolidate'
|
|
22
|
+
|| kind === 'knowledge-packet'
|
|
23
|
+
|| kind === 'knowledge-explain';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function createAgentWorkspaceKnowledgeCommandEditor(kind: AgentWorkspaceKnowledgeCommandEditorKind): AgentWorkspaceLocalEditor {
|
|
27
|
+
if (kind === 'knowledge-get') {
|
|
28
|
+
return {
|
|
29
|
+
kind,
|
|
30
|
+
mode: 'create',
|
|
31
|
+
title: 'Show Agent Knowledge Item',
|
|
32
|
+
selectedFieldIndex: 0,
|
|
33
|
+
message: 'Show one source, node, or issue from the isolated Agent Knowledge segment.',
|
|
34
|
+
fields: [
|
|
35
|
+
{ id: 'id', label: 'Item id', value: '', required: true, multiline: false, hint: 'Agent Knowledge source, node, or issue id.' },
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (kind === 'knowledge-map') {
|
|
40
|
+
return {
|
|
41
|
+
kind,
|
|
42
|
+
mode: 'create',
|
|
43
|
+
title: 'Map Agent Knowledge',
|
|
44
|
+
selectedFieldIndex: 0,
|
|
45
|
+
message: 'Summarize the isolated Agent Knowledge graph map. Leave query blank for a bounded full map summary.',
|
|
46
|
+
fields: [
|
|
47
|
+
{ id: 'query', label: 'Query', value: '', required: false, multiline: false, hint: 'Optional map filter query.' },
|
|
48
|
+
{ id: 'limit', label: 'Limit', value: '50', required: false, multiline: false, hint: 'Maximum map records to summarize.' },
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (kind === 'knowledge-connector-show' || kind === 'knowledge-connector-doctor') {
|
|
53
|
+
const doctor = kind === 'knowledge-connector-doctor';
|
|
54
|
+
return {
|
|
55
|
+
kind,
|
|
56
|
+
mode: 'create',
|
|
57
|
+
title: doctor ? 'Doctor Agent Knowledge Connector' : 'Show Agent Knowledge Connector',
|
|
58
|
+
selectedFieldIndex: 0,
|
|
59
|
+
message: doctor
|
|
60
|
+
? 'Run a read-only readiness doctor for one Agent Knowledge connector.'
|
|
61
|
+
: 'Show one Agent Knowledge connector from the isolated Agent Knowledge connector registry.',
|
|
62
|
+
fields: [
|
|
63
|
+
{ id: 'connectorId', label: 'Connector id', value: '', required: true, multiline: false, hint: 'Connector id from the Agent Knowledge connector inventory.' },
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (kind === 'knowledge-review-issue') {
|
|
68
|
+
return {
|
|
69
|
+
kind,
|
|
70
|
+
mode: 'update',
|
|
71
|
+
title: 'Review Agent Knowledge Issue',
|
|
72
|
+
selectedFieldIndex: 0,
|
|
73
|
+
message: 'Accept, reject, resolve, reopen, edit, or forget one Agent Knowledge issue. Type yes on the final field to confirm.',
|
|
74
|
+
fields: [
|
|
75
|
+
{ id: 'issueId', label: 'Issue id', value: '', required: true, multiline: false, hint: 'Issue id from the review queue.' },
|
|
76
|
+
{ id: 'action', label: 'Action', value: 'resolve', required: true, multiline: false, hint: 'accept, reject, resolve, reopen, edit, or forget.' },
|
|
77
|
+
{ id: 'reviewer', label: 'Reviewer', value: 'agent', required: false, multiline: false, hint: 'Reviewer label. Blank defaults to agent.' },
|
|
78
|
+
{ id: 'value', label: 'Value JSON', value: '', required: false, multiline: true, hint: 'Optional JSON object for edit actions. Ctrl-J inserts a new line.' },
|
|
79
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /knowledge review-issue with --yes.' },
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (kind === 'knowledge-consolidate') {
|
|
84
|
+
return {
|
|
85
|
+
kind,
|
|
86
|
+
mode: 'update',
|
|
87
|
+
title: 'Consolidate Agent Knowledge',
|
|
88
|
+
selectedFieldIndex: 0,
|
|
89
|
+
message: 'Run isolated Agent Knowledge consolidation. Type yes on the final field to confirm.',
|
|
90
|
+
fields: [
|
|
91
|
+
{ id: 'mode', label: 'Mode', value: 'light', required: true, multiline: false, hint: 'light or deep.' },
|
|
92
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /knowledge consolidate with --yes.' },
|
|
93
|
+
],
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const explain = kind === 'knowledge-explain';
|
|
97
|
+
return {
|
|
98
|
+
kind,
|
|
99
|
+
mode: 'create',
|
|
100
|
+
title: explain ? 'Explain Memory Selection' : 'Build Prompt Packet',
|
|
101
|
+
selectedFieldIndex: 0,
|
|
102
|
+
message: explain
|
|
103
|
+
? 'Explain which Agent Knowledge and memory context would be selected for a task.'
|
|
104
|
+
: 'Build a compact Agent Knowledge prompt packet for a task.',
|
|
105
|
+
fields: [
|
|
106
|
+
{ id: 'task', label: 'Task', value: '', required: true, multiline: true, hint: 'Task or question. Ctrl-J inserts a new line.' },
|
|
107
|
+
{ id: 'scopes', label: 'Scopes', value: '', required: false, multiline: false, hint: 'Optional comma-separated --scope values.' },
|
|
108
|
+
],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ShellPathService } from '@/runtime/index.ts';
|
|
2
|
+
import { AgentPersonaRegistry } from '../agent/persona-registry.ts';
|
|
3
|
+
import { AgentRoutineRegistry } from '../agent/routine-registry.ts';
|
|
4
|
+
import { AgentSkillRegistry } from '../agent/skill-registry.ts';
|
|
5
|
+
import type { AgentWorkspaceLocalEditorKind } from './agent-workspace-types.ts';
|
|
6
|
+
|
|
7
|
+
export interface AgentWorkspaceLearnedBehaviorInput {
|
|
8
|
+
readonly target: Exclude<AgentWorkspaceLocalEditorKind, 'memory' | 'profile'>;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly description: string;
|
|
11
|
+
readonly notes: string;
|
|
12
|
+
readonly tags: readonly string[];
|
|
13
|
+
readonly triggers: readonly string[];
|
|
14
|
+
readonly enable: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface AgentWorkspaceLearnedBehaviorResult {
|
|
18
|
+
readonly kind: Exclude<AgentWorkspaceLocalEditorKind, 'memory' | 'profile'>;
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly name: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function createAgentWorkspaceLearnedBehavior(
|
|
24
|
+
shellPaths: ShellPathService,
|
|
25
|
+
input: AgentWorkspaceLearnedBehaviorInput,
|
|
26
|
+
): AgentWorkspaceLearnedBehaviorResult {
|
|
27
|
+
if (input.target === 'persona') {
|
|
28
|
+
const registry = AgentPersonaRegistry.fromShellPaths(shellPaths);
|
|
29
|
+
const created = registry.create({
|
|
30
|
+
name: input.name,
|
|
31
|
+
description: input.description,
|
|
32
|
+
body: input.notes,
|
|
33
|
+
tags: input.tags,
|
|
34
|
+
triggers: input.triggers,
|
|
35
|
+
source: 'agent',
|
|
36
|
+
provenance: 'agent-workspace-learned-behavior',
|
|
37
|
+
});
|
|
38
|
+
if (input.enable) registry.setActive(created.id);
|
|
39
|
+
return { kind: 'persona', id: created.id, name: created.name };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (input.target === 'skill') {
|
|
43
|
+
const created = AgentSkillRegistry.fromShellPaths(shellPaths).create({
|
|
44
|
+
name: input.name,
|
|
45
|
+
description: input.description,
|
|
46
|
+
procedure: input.notes,
|
|
47
|
+
tags: input.tags,
|
|
48
|
+
triggers: input.triggers,
|
|
49
|
+
enabled: input.enable,
|
|
50
|
+
source: 'agent',
|
|
51
|
+
provenance: 'agent-workspace-learned-behavior',
|
|
52
|
+
});
|
|
53
|
+
return { kind: 'skill', id: created.id, name: created.name };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const created = AgentRoutineRegistry.fromShellPaths(shellPaths).create({
|
|
57
|
+
name: input.name,
|
|
58
|
+
description: input.description,
|
|
59
|
+
steps: input.notes,
|
|
60
|
+
tags: input.tags,
|
|
61
|
+
triggers: input.triggers,
|
|
62
|
+
enabled: input.enable,
|
|
63
|
+
source: 'agent',
|
|
64
|
+
provenance: 'agent-workspace-learned-behavior',
|
|
65
|
+
});
|
|
66
|
+
return { kind: 'routine', id: created.id, name: created.name };
|
|
67
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
import type { AgentWorkspaceLibraryCommandEditorKind } from './agent-workspace-library-command-editors.ts';
|
|
3
|
+
import { isAgentWorkspaceLibraryCommandEditorKind } from './agent-workspace-library-command-editors.ts';
|
|
4
|
+
import { quoteSlashCommandArg } from './slash-command-parser.ts';
|
|
5
|
+
|
|
6
|
+
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
7
|
+
|
|
8
|
+
export type AgentWorkspaceLibraryCommandEditorSubmission =
|
|
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
|
+
export function isAgentWorkspaceLibraryCommandSubmissionKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceLibraryCommandEditorKind {
|
|
23
|
+
return isAgentWorkspaceLibraryCommandEditorKind(kind);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function buildAgentWorkspaceLibraryCommandEditorSubmission(
|
|
27
|
+
editor: AgentWorkspaceLocalEditor,
|
|
28
|
+
readField: AgentWorkspaceFieldReader,
|
|
29
|
+
): AgentWorkspaceLibraryCommandEditorSubmission {
|
|
30
|
+
const target = editor.kind.startsWith('persona') ? 'persona' : editor.kind.startsWith('skill') ? 'skill' : 'routine';
|
|
31
|
+
const root = target === 'persona' ? '/personas' : target === 'skill' ? '/agent-skills' : '/routines';
|
|
32
|
+
const search = editor.kind.endsWith('search');
|
|
33
|
+
const command = search
|
|
34
|
+
? `${root} search ${quoteSlashCommandArg(readField('query'))}`
|
|
35
|
+
: `${root} show ${quoteSlashCommandArg(readField('id'))}`;
|
|
36
|
+
const label = target === 'persona' ? 'persona' : target === 'skill' ? 'skill' : 'routine';
|
|
37
|
+
const title = search ? `Opening ${label} search` : `Opening ${label} detail`;
|
|
38
|
+
return {
|
|
39
|
+
kind: 'dispatch',
|
|
40
|
+
command,
|
|
41
|
+
status: `${title}.`,
|
|
42
|
+
actionResult: {
|
|
43
|
+
kind: 'dispatched',
|
|
44
|
+
title,
|
|
45
|
+
detail: `The workspace handed read-only local ${label} ${search ? 'search' : 'detail inspection'} to the shell-owned command router.`,
|
|
46
|
+
command,
|
|
47
|
+
safety: 'read-only',
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
|
|
3
|
+
export type AgentWorkspaceLibraryCommandEditorKind = Extract<
|
|
4
|
+
AgentWorkspaceEditorKind,
|
|
5
|
+
'persona-search' | 'persona-show' | 'skill-search' | 'skill-show' | 'routine-search' | 'routine-show'
|
|
6
|
+
>;
|
|
7
|
+
|
|
8
|
+
export function isAgentWorkspaceLibraryCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceLibraryCommandEditorKind {
|
|
9
|
+
return kind === 'persona-search'
|
|
10
|
+
|| kind === 'persona-show'
|
|
11
|
+
|| kind === 'skill-search'
|
|
12
|
+
|| kind === 'skill-show'
|
|
13
|
+
|| kind === 'routine-search'
|
|
14
|
+
|| kind === 'routine-show';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createAgentWorkspaceLibraryCommandEditor(kind: AgentWorkspaceLibraryCommandEditorKind): AgentWorkspaceLocalEditor {
|
|
18
|
+
const target = kind.startsWith('persona') ? 'persona' : kind.startsWith('skill') ? 'skill' : 'routine';
|
|
19
|
+
const search = kind.endsWith('search');
|
|
20
|
+
const label = target === 'persona' ? 'Persona' : target === 'skill' ? 'Skill' : 'Routine';
|
|
21
|
+
return {
|
|
22
|
+
kind,
|
|
23
|
+
mode: 'create',
|
|
24
|
+
title: search ? `Search ${label}s` : `Show ${label}`,
|
|
25
|
+
selectedFieldIndex: 0,
|
|
26
|
+
message: search
|
|
27
|
+
? `Search local Agent ${target}s by name, description, tags, triggers, or body.`
|
|
28
|
+
: `Show one local Agent ${target} by id.`,
|
|
29
|
+
fields: [
|
|
30
|
+
search
|
|
31
|
+
? { id: 'query', label: 'Search query', value: '', required: false, multiline: false, hint: `Optional text query. Blank lists every local ${target}.` }
|
|
32
|
+
: { id: 'id', label: `${label} id`, value: '', required: true, multiline: false, hint: `Existing local ${target} id.` },
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
import { quoteSlashCommandArg, tokenizeSlashCommand } from './slash-command-parser.ts';
|
|
3
|
+
|
|
4
|
+
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
5
|
+
|
|
6
|
+
export type AgentWorkspaceMcpCommandEditorKind = Extract<AgentWorkspaceEditorKind, 'mcp-server' | 'mcp-tools-server' | 'mcp-repair'>;
|
|
7
|
+
|
|
8
|
+
export type AgentWorkspaceMcpCommandEditorSubmission =
|
|
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
|
+
export function isAgentWorkspaceMcpCommandSubmissionKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceMcpCommandEditorKind {
|
|
23
|
+
return kind === 'mcp-server' || kind === 'mcp-tools-server' || kind === 'mcp-repair';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isAffirmative(value: string): boolean {
|
|
27
|
+
return /^(y|yes|true)$/i.test(value.trim());
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function splitCommaList(value: string): readonly string[] {
|
|
31
|
+
return value.split(',').map((entry) => entry.trim()).filter(Boolean);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function buildAgentWorkspaceMcpCommandEditorSubmission(
|
|
35
|
+
editor: AgentWorkspaceLocalEditor,
|
|
36
|
+
readField: AgentWorkspaceFieldReader,
|
|
37
|
+
): AgentWorkspaceMcpCommandEditorSubmission {
|
|
38
|
+
if (editor.kind === 'mcp-tools-server' || editor.kind === 'mcp-repair') {
|
|
39
|
+
const server = quoteSlashCommandArg(readField('server'));
|
|
40
|
+
const tools = editor.kind === 'mcp-tools-server';
|
|
41
|
+
const command = tools ? `/mcp tools ${server}` : `/mcp repair ${server}`;
|
|
42
|
+
const title = tools ? 'Opening MCP server tools' : 'Opening MCP repair guidance';
|
|
43
|
+
return {
|
|
44
|
+
kind: 'dispatch',
|
|
45
|
+
command,
|
|
46
|
+
status: `${title}.`,
|
|
47
|
+
actionResult: {
|
|
48
|
+
kind: 'dispatched',
|
|
49
|
+
title,
|
|
50
|
+
detail: tools
|
|
51
|
+
? 'The workspace handed read-only MCP server tool inspection to the shell-owned command router.'
|
|
52
|
+
: 'The workspace handed read-only MCP repair guidance to the shell-owned command router.',
|
|
53
|
+
command,
|
|
54
|
+
safety: 'read-only',
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
59
|
+
return {
|
|
60
|
+
kind: 'editor',
|
|
61
|
+
editor: { ...editor, message: 'MCP server add/update not confirmed. Type yes, then press Enter.' },
|
|
62
|
+
status: 'MCP server add/update not confirmed.',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const parts = [
|
|
66
|
+
'/mcp',
|
|
67
|
+
'add',
|
|
68
|
+
quoteSlashCommandArg(readField('name')),
|
|
69
|
+
quoteSlashCommandArg(readField('command')),
|
|
70
|
+
...tokenizeSlashCommand(readField('args')).map(quoteSlashCommandArg),
|
|
71
|
+
];
|
|
72
|
+
const scope = readField('scope');
|
|
73
|
+
const role = readField('role');
|
|
74
|
+
const trust = readField('trust');
|
|
75
|
+
if (scope.length > 0) parts.push('--scope', quoteSlashCommandArg(scope));
|
|
76
|
+
if (role.length > 0) parts.push('--role', quoteSlashCommandArg(role));
|
|
77
|
+
if (trust.length > 0) parts.push('--trust', quoteSlashCommandArg(trust));
|
|
78
|
+
for (const env of splitCommaList(readField('env'))) parts.push('--env', quoteSlashCommandArg(env));
|
|
79
|
+
for (const path of splitCommaList(readField('paths'))) parts.push('--path', quoteSlashCommandArg(path));
|
|
80
|
+
for (const host of splitCommaList(readField('hosts'))) parts.push('--host', quoteSlashCommandArg(host));
|
|
81
|
+
parts.push('--yes');
|
|
82
|
+
const command = parts.join(' ');
|
|
83
|
+
return {
|
|
84
|
+
kind: 'dispatch',
|
|
85
|
+
command,
|
|
86
|
+
status: 'Opening MCP server add/update.',
|
|
87
|
+
actionResult: {
|
|
88
|
+
kind: 'dispatched',
|
|
89
|
+
title: 'Opening MCP server add/update',
|
|
90
|
+
detail: 'The workspace handed a confirmed MCP server add/update command to the shell-owned command router.',
|
|
91
|
+
command,
|
|
92
|
+
safety: 'safe',
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|