@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,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
|
+
export type AgentWorkspaceWorkPlanEditorKind = 'workplan-add' | 'workplan-show' | 'workplan-status' | 'workplan-delete' | 'workplan-clear-completed';
|
|
7
|
+
|
|
8
|
+
export type AgentWorkspaceWorkPlanEditorSubmission =
|
|
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
|
+
const STATUS_COMMANDS: Record<string, string> = {
|
|
23
|
+
pending: 'pending',
|
|
24
|
+
todo: 'pending',
|
|
25
|
+
start: 'start',
|
|
26
|
+
active: 'start',
|
|
27
|
+
progress: 'start',
|
|
28
|
+
in_progress: 'start',
|
|
29
|
+
blocked: 'blocked',
|
|
30
|
+
block: 'blocked',
|
|
31
|
+
done: 'done',
|
|
32
|
+
complete: 'done',
|
|
33
|
+
completed: 'done',
|
|
34
|
+
failed: 'failed',
|
|
35
|
+
fail: 'failed',
|
|
36
|
+
cancelled: 'cancelled',
|
|
37
|
+
canceled: 'cancelled',
|
|
38
|
+
cancel: 'cancelled',
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function isAgentWorkspaceWorkPlanEditorKind(kind: string): kind is AgentWorkspaceWorkPlanEditorKind {
|
|
42
|
+
return kind === 'workplan-add'
|
|
43
|
+
|| kind === 'workplan-show'
|
|
44
|
+
|| kind === 'workplan-status'
|
|
45
|
+
|| kind === 'workplan-delete'
|
|
46
|
+
|| kind === 'workplan-clear-completed';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function isAffirmative(value: string): boolean {
|
|
50
|
+
return /^(y|yes|true)$/i.test(value.trim());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function unconfirmed(editor: AgentWorkspaceLocalEditor, message: string, status: string): AgentWorkspaceWorkPlanEditorSubmission {
|
|
54
|
+
return {
|
|
55
|
+
kind: 'editor',
|
|
56
|
+
editor: { ...editor, message },
|
|
57
|
+
status,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function dispatch(command: string, title: string, status: string, detail: string, safety: 'safe' | 'read-only' | 'delegates' | 'blocked'): AgentWorkspaceWorkPlanEditorSubmission {
|
|
62
|
+
return {
|
|
63
|
+
kind: 'dispatch',
|
|
64
|
+
command,
|
|
65
|
+
status,
|
|
66
|
+
actionResult: {
|
|
67
|
+
kind: 'dispatched',
|
|
68
|
+
title,
|
|
69
|
+
detail,
|
|
70
|
+
command,
|
|
71
|
+
safety,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function buildAgentWorkspaceWorkPlanEditorSubmission(
|
|
77
|
+
editor: AgentWorkspaceLocalEditor,
|
|
78
|
+
readField: AgentWorkspaceFieldReader,
|
|
79
|
+
): AgentWorkspaceWorkPlanEditorSubmission {
|
|
80
|
+
if (editor.kind === 'workplan-add') {
|
|
81
|
+
const parts = ['/workplan', 'add', quoteSlashCommandArg(readField('title'))];
|
|
82
|
+
const owner = readField('owner');
|
|
83
|
+
const source = readField('source');
|
|
84
|
+
const notes = readField('notes');
|
|
85
|
+
if (owner.length > 0) parts.push('--owner', quoteSlashCommandArg(owner));
|
|
86
|
+
if (source.length > 0) parts.push('--source', quoteSlashCommandArg(source));
|
|
87
|
+
if (notes.length > 0) parts.push('--notes', quoteSlashCommandArg(notes));
|
|
88
|
+
return dispatch(
|
|
89
|
+
parts.join(' '),
|
|
90
|
+
'Opening work plan item creation',
|
|
91
|
+
'Opening work plan item creation.',
|
|
92
|
+
'The workspace handed a visible work plan item creation command to the shell-owned command router.',
|
|
93
|
+
'safe',
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (editor.kind === 'workplan-show') {
|
|
98
|
+
const format = readField('format').trim().toLowerCase();
|
|
99
|
+
const command = format === 'markdown' ? '/workplan markdown' : '/workplan show';
|
|
100
|
+
return dispatch(
|
|
101
|
+
command,
|
|
102
|
+
'Opening work plan detail',
|
|
103
|
+
'Opening work plan detail.',
|
|
104
|
+
'The workspace handed read-only work plan detail inspection to the shell-owned command router.',
|
|
105
|
+
'read-only',
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (editor.kind === 'workplan-status') {
|
|
110
|
+
const requested = readField('status').trim().toLowerCase().replace(/[\s-]+/g, '_');
|
|
111
|
+
const commandStatus = STATUS_COMMANDS[requested];
|
|
112
|
+
if (!commandStatus) {
|
|
113
|
+
return {
|
|
114
|
+
kind: 'editor',
|
|
115
|
+
editor: { ...editor, message: 'Invalid status. Use pending, start, blocked, done, failed, or cancelled.' },
|
|
116
|
+
status: 'Work plan status update needs a valid status.',
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const command = `/workplan ${commandStatus} ${quoteSlashCommandArg(readField('id'))}`;
|
|
120
|
+
return dispatch(
|
|
121
|
+
command,
|
|
122
|
+
'Opening work plan status update',
|
|
123
|
+
'Opening work plan status update.',
|
|
124
|
+
'The workspace handed a visible work plan status update command to the shell-owned command router.',
|
|
125
|
+
'safe',
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (editor.kind === 'workplan-delete') {
|
|
130
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
131
|
+
return unconfirmed(editor, 'Work plan removal not confirmed. Type yes, then press Enter.', 'Work plan removal not confirmed.');
|
|
132
|
+
}
|
|
133
|
+
const command = `/workplan remove ${quoteSlashCommandArg(readField('id'))} --yes`;
|
|
134
|
+
return dispatch(
|
|
135
|
+
command,
|
|
136
|
+
'Opening work plan item removal',
|
|
137
|
+
'Opening work plan item removal.',
|
|
138
|
+
'The workspace handed a confirmed work plan removal command to the shell-owned command router.',
|
|
139
|
+
'safe',
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
144
|
+
return unconfirmed(editor, 'Clear completed work plan items not confirmed. Type yes, then press Enter.', 'Clear completed work plan items not confirmed.');
|
|
145
|
+
}
|
|
146
|
+
return dispatch(
|
|
147
|
+
'/workplan clear-completed --yes',
|
|
148
|
+
'Opening completed work plan cleanup',
|
|
149
|
+
'Opening completed work plan cleanup.',
|
|
150
|
+
'The workspace handed a confirmed work plan cleanup command to the shell-owned command router.',
|
|
151
|
+
'safe',
|
|
152
|
+
);
|
|
153
|
+
}
|
|
@@ -11,24 +11,15 @@ import { AGENT_WORKSPACE_CATEGORIES } from './agent-workspace-categories.ts';
|
|
|
11
11
|
import { buildAgentWorkspaceCommandEditorSubmission, isAgentWorkspaceCommandEditorKind } from './agent-workspace-command-editor.ts';
|
|
12
12
|
import { quoteSlashCommandArg } from './slash-command-parser.ts';
|
|
13
13
|
import { createDeleteEditor, createMemoryUpdateEditor, createPersonaUpdateEditor, createRoutineUpdateEditor, createSkillUpdateEditor, editorCategoryId, isAffirmative, splitList } from './agent-workspace-editors.ts';
|
|
14
|
+
import { createAgentWorkspaceLearnedBehavior } from './agent-workspace-learned-behavior.ts';
|
|
14
15
|
import { deleteAgentWorkspaceMemoryEditor, submitAgentWorkspaceMemoryEditor } from './agent-workspace-memory-editor.ts';
|
|
16
|
+
import { jumpAgentWorkspaceSelection, moveAgentWorkspaceSelection, selectAgentWorkspaceCategory } from './agent-workspace-navigation.ts';
|
|
17
|
+
import { buildAgentWorkspaceRequirements } from './agent-workspace-requirements.ts';
|
|
15
18
|
import { buildAgentWorkspaceRuntimeSnapshot } from './agent-workspace-snapshot.ts';
|
|
16
19
|
import type { AgentWorkspaceAction, AgentWorkspaceActionResult, AgentWorkspaceCategory, AgentWorkspaceCommandDispatcher, AgentWorkspaceEditorField, AgentWorkspaceFocusPane, AgentWorkspaceLocalEditor, AgentWorkspaceLocalEditorKind, AgentWorkspaceLocalLibraryItem, AgentWorkspaceLocalOperation, AgentWorkspaceRuntimeSnapshot } from './agent-workspace-types.ts';
|
|
17
20
|
|
|
18
21
|
export type { AgentWorkspaceChannelRisk, AgentWorkspaceChannelStatus } from './agent-workspace-channels.ts';
|
|
19
|
-
export type {
|
|
20
|
-
AgentWorkspaceAction,
|
|
21
|
-
AgentWorkspaceActionResult,
|
|
22
|
-
AgentWorkspaceCategory,
|
|
23
|
-
AgentWorkspaceCommandDispatcher,
|
|
24
|
-
AgentWorkspaceEditorField,
|
|
25
|
-
AgentWorkspaceFocusPane,
|
|
26
|
-
AgentWorkspaceLocalEditor,
|
|
27
|
-
AgentWorkspaceLocalEditorKind,
|
|
28
|
-
AgentWorkspaceLocalLibraryItem,
|
|
29
|
-
AgentWorkspaceLocalOperation,
|
|
30
|
-
AgentWorkspaceRuntimeSnapshot,
|
|
31
|
-
} from './agent-workspace-types.ts';
|
|
22
|
+
export type { AgentWorkspaceAction, AgentWorkspaceActionResult, AgentWorkspaceCategory, AgentWorkspaceCommandDispatcher, AgentWorkspaceEditorField, AgentWorkspaceFocusPane, AgentWorkspaceLocalEditor, AgentWorkspaceLocalEditorKind, AgentWorkspaceLocalLibraryItem, AgentWorkspaceLocalOperation, AgentWorkspaceRuntimeSnapshot } from './agent-workspace-types.ts';
|
|
32
23
|
export { AGENT_WORKSPACE_MODAL_NAME } from './agent-workspace-types.ts';
|
|
33
24
|
export { buildAgentWorkspaceRuntimeSnapshot } from './agent-workspace-snapshot.ts';
|
|
34
25
|
export { handleAgentWorkspaceToken } from './agent-workspace-token.ts';
|
|
@@ -52,7 +43,7 @@ export class AgentWorkspace {
|
|
|
52
43
|
private context: CommandContext | null = null;
|
|
53
44
|
private dispatchCommand: AgentWorkspaceCommandDispatcher | null = null;
|
|
54
45
|
|
|
55
|
-
open(context: CommandContext, dispatchCommand: AgentWorkspaceCommandDispatcher): void {
|
|
46
|
+
open(context: CommandContext, dispatchCommand: AgentWorkspaceCommandDispatcher, categoryId?: string): void {
|
|
56
47
|
this.context = context;
|
|
57
48
|
this.dispatchCommand = dispatchCommand;
|
|
58
49
|
this.runtimeSnapshot = buildAgentWorkspaceRuntimeSnapshot(context);
|
|
@@ -61,6 +52,16 @@ export class AgentWorkspace {
|
|
|
61
52
|
this.status = 'Ready. Choose an operator flow; ordinary assistant work stays in the main conversation.';
|
|
62
53
|
this.lastActionResult = null;
|
|
63
54
|
this.localEditor = null;
|
|
55
|
+
if (categoryId && !this.selectCategory(categoryId)) {
|
|
56
|
+
const normalized = categoryId.trim();
|
|
57
|
+
this.status = `Unknown Agent workspace area: ${normalized}.`;
|
|
58
|
+
this.lastActionResult = {
|
|
59
|
+
kind: 'guidance',
|
|
60
|
+
title: 'Unknown Agent workspace area',
|
|
61
|
+
detail: `Use one of: ${this.categories.map((category) => category.id).join(', ')}.`,
|
|
62
|
+
safety: 'safe',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
64
65
|
this.clampSelection();
|
|
65
66
|
}
|
|
66
67
|
|
|
@@ -90,6 +91,10 @@ export class AgentWorkspace {
|
|
|
90
91
|
return this.actions[this.selectedActionIndex] ?? null;
|
|
91
92
|
}
|
|
92
93
|
|
|
94
|
+
selectCategory(categoryIdOrLabel: string): boolean {
|
|
95
|
+
return selectAgentWorkspaceCategory(this, categoryIdOrLabel);
|
|
96
|
+
}
|
|
97
|
+
|
|
93
98
|
selectedLocalLibraryItem(kind: AgentWorkspaceLocalEditorKind): AgentWorkspaceLocalLibraryItem | null {
|
|
94
99
|
const items = this.localLibraryItems(kind);
|
|
95
100
|
if (items.length === 0) return null;
|
|
@@ -110,35 +115,19 @@ export class AgentWorkspace {
|
|
|
110
115
|
}
|
|
111
116
|
|
|
112
117
|
moveUp(): void {
|
|
113
|
-
|
|
114
|
-
this.selectedCategoryIndex = Math.max(0, this.selectedCategoryIndex - 1);
|
|
115
|
-
this.selectedActionIndex = 0;
|
|
116
|
-
} else {
|
|
117
|
-
this.selectedActionIndex = Math.max(0, this.selectedActionIndex - 1);
|
|
118
|
-
}
|
|
119
|
-
this.clampSelection();
|
|
118
|
+
moveAgentWorkspaceSelection(this, -1);
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
moveDown(): void {
|
|
123
|
-
|
|
124
|
-
this.selectedCategoryIndex = Math.min(this.categories.length - 1, this.selectedCategoryIndex + 1);
|
|
125
|
-
this.selectedActionIndex = 0;
|
|
126
|
-
} else {
|
|
127
|
-
this.selectedActionIndex = Math.min(this.actions.length - 1, this.selectedActionIndex + 1);
|
|
128
|
-
}
|
|
129
|
-
this.clampSelection();
|
|
122
|
+
moveAgentWorkspaceSelection(this, 1);
|
|
130
123
|
}
|
|
131
124
|
|
|
132
125
|
jumpHome(): void {
|
|
133
|
-
|
|
134
|
-
else this.selectedActionIndex = 0;
|
|
135
|
-
this.clampSelection();
|
|
126
|
+
jumpAgentWorkspaceSelection(this, 'home');
|
|
136
127
|
}
|
|
137
128
|
|
|
138
129
|
jumpEnd(): void {
|
|
139
|
-
|
|
140
|
-
else this.selectedActionIndex = this.actions.length - 1;
|
|
141
|
-
this.clampSelection();
|
|
130
|
+
jumpAgentWorkspaceSelection(this, 'end');
|
|
142
131
|
}
|
|
143
132
|
|
|
144
133
|
refreshRuntimeSnapshot(): void {
|
|
@@ -184,7 +173,7 @@ export class AgentWorkspace {
|
|
|
184
173
|
if (!editor || text.length === 0) return;
|
|
185
174
|
const field = editor.fields[editor.selectedFieldIndex];
|
|
186
175
|
if (!field) return;
|
|
187
|
-
this.replaceEditorField(editor.selectedFieldIndex, `${field.value}${text}`, editor.message);
|
|
176
|
+
this.replaceEditorField(editor.selectedFieldIndex, `${field.value}${field.multiline ? text.replace(/\r\n?/g, '\n') : text.replace(/[\r\n]+/g, ' ')}`, editor.message);
|
|
188
177
|
}
|
|
189
178
|
|
|
190
179
|
appendEditorNewline(): void {
|
|
@@ -432,6 +421,12 @@ export class AgentWorkspace {
|
|
|
432
421
|
return memory;
|
|
433
422
|
}
|
|
434
423
|
|
|
424
|
+
private learnedBehaviorTarget(): Exclude<AgentWorkspaceLocalEditorKind, 'memory' | 'profile'> {
|
|
425
|
+
const target = this.editorField('target').trim().toLowerCase();
|
|
426
|
+
if (target === 'persona' || target === 'skill' || target === 'routine') return target;
|
|
427
|
+
throw new Error('Behavior type must be skill, routine, or persona.');
|
|
428
|
+
}
|
|
429
|
+
|
|
435
430
|
private finishLocalOperation(kind: AgentWorkspaceLocalEditorKind, title: string, detail: string): void {
|
|
436
431
|
this.runtimeSnapshot = this.context ? buildAgentWorkspaceRuntimeSnapshot(this.context) : this.runtimeSnapshot;
|
|
437
432
|
this.clampLocalLibrarySelection(kind);
|
|
@@ -528,7 +523,18 @@ export class AgentWorkspace {
|
|
|
528
523
|
this.submitLocalDeleteEditor(shellPaths, editor);
|
|
529
524
|
return;
|
|
530
525
|
}
|
|
531
|
-
if (editor.kind === '
|
|
526
|
+
if (editor.kind === 'learned-behavior') {
|
|
527
|
+
const created = createAgentWorkspaceLearnedBehavior(shellPaths, {
|
|
528
|
+
target: this.learnedBehaviorTarget(),
|
|
529
|
+
name: this.editorField('name'),
|
|
530
|
+
description: this.editorField('description'),
|
|
531
|
+
notes: this.editorField('notes'),
|
|
532
|
+
tags: splitList(this.editorField('tags')),
|
|
533
|
+
triggers: splitList(this.editorField('triggers')),
|
|
534
|
+
enable: isAffirmative(this.editorField('enable')),
|
|
535
|
+
});
|
|
536
|
+
this.finishLocalEditor(created.kind, created.id, created.name, 'Created');
|
|
537
|
+
} else if (editor.kind === 'profile') {
|
|
532
538
|
const template = this.editorField('template');
|
|
533
539
|
const templateId = template && template.toLowerCase() !== 'none' ? template : undefined;
|
|
534
540
|
const profile = createAgentRuntimeProfile(shellPaths.homeDirectory, this.editorField('name'), {
|
|
@@ -572,6 +578,7 @@ export class AgentWorkspace {
|
|
|
572
578
|
procedure: this.editorField('procedure'),
|
|
573
579
|
triggers: splitList(this.editorField('triggers')),
|
|
574
580
|
tags: splitList(this.editorField('tags')),
|
|
581
|
+
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
575
582
|
provenance: 'agent-workspace',
|
|
576
583
|
});
|
|
577
584
|
registry.setEnabled(updated.id, isAffirmative(this.editorField('enabled')));
|
|
@@ -584,6 +591,7 @@ export class AgentWorkspace {
|
|
|
584
591
|
procedure: this.editorField('procedure'),
|
|
585
592
|
triggers: splitList(this.editorField('triggers')),
|
|
586
593
|
tags: splitList(this.editorField('tags')),
|
|
594
|
+
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
587
595
|
enabled: isAffirmative(this.editorField('enabled')),
|
|
588
596
|
source: 'user',
|
|
589
597
|
provenance: 'agent-workspace',
|
|
@@ -598,6 +606,7 @@ export class AgentWorkspace {
|
|
|
598
606
|
steps: this.editorField('steps'),
|
|
599
607
|
triggers: splitList(this.editorField('triggers')),
|
|
600
608
|
tags: splitList(this.editorField('tags')),
|
|
609
|
+
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
601
610
|
provenance: 'agent-workspace',
|
|
602
611
|
});
|
|
603
612
|
registry.setEnabled(updated.id, isAffirmative(this.editorField('enabled')));
|
|
@@ -610,6 +619,7 @@ export class AgentWorkspace {
|
|
|
610
619
|
steps: this.editorField('steps'),
|
|
611
620
|
triggers: splitList(this.editorField('triggers')),
|
|
612
621
|
tags: splitList(this.editorField('tags')),
|
|
622
|
+
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
613
623
|
enabled: isAffirmative(this.editorField('enabled')),
|
|
614
624
|
source: 'user',
|
|
615
625
|
provenance: 'agent-workspace',
|
|
@@ -755,7 +765,7 @@ export class AgentWorkspace {
|
|
|
755
765
|
this.lastActionResult = {
|
|
756
766
|
kind: 'refreshed',
|
|
757
767
|
title: 'Created Agent profile',
|
|
758
|
-
detail: `Created isolated Agent profile ${profile.id}${starter}. Launch it with goodvibes-agent --agent-profile ${profile.id}. The current
|
|
768
|
+
detail: `Created isolated Agent profile ${profile.id}${starter}. Launch it with goodvibes-agent --agent-profile ${profile.id}. The current Agent session was not switched.`,
|
|
759
769
|
safety: 'safe',
|
|
760
770
|
};
|
|
761
771
|
this.clampSelection();
|
|
@@ -110,7 +110,7 @@ export interface CommandShellUiOpeners {
|
|
|
110
110
|
focusPrompt?: () => void;
|
|
111
111
|
openPolicyPanel?: () => void;
|
|
112
112
|
openMcpWorkspace?: () => void;
|
|
113
|
-
openAgentWorkspace?: () => void;
|
|
113
|
+
openAgentWorkspace?: (categoryId?: string) => void;
|
|
114
114
|
openSecurityPanel?: () => void;
|
|
115
115
|
openKnowledgePanel?: () => void;
|
|
116
116
|
openSubscriptionPanel?: () => void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdirSync } from 'node:fs';
|
|
2
2
|
import { dirname } from 'node:path';
|
|
3
3
|
import {
|
|
4
|
+
clearAgentRuntimeProfileSelection,
|
|
4
5
|
createAgentRuntimeProfileFromDiscovered,
|
|
5
6
|
createAgentRuntimeProfileTemplateFromDiscovered,
|
|
6
7
|
createAgentRuntimeProfile,
|
|
@@ -10,6 +11,9 @@ import {
|
|
|
10
11
|
importAgentRuntimeProfileTemplate,
|
|
11
12
|
listAgentRuntimeProfiles,
|
|
12
13
|
listAgentRuntimeProfileTemplates,
|
|
14
|
+
readAgentRuntimeProfileSelection,
|
|
15
|
+
resolveAgentRuntimeProfileHome,
|
|
16
|
+
setAgentRuntimeProfileSelection,
|
|
13
17
|
type AgentRuntimeProfileInfo,
|
|
14
18
|
type AgentRuntimeProfileTemplateSummary,
|
|
15
19
|
} from '../../agent/runtime-profile.ts';
|
|
@@ -49,14 +53,29 @@ function templateLine(template: AgentRuntimeProfileTemplateSummary): string {
|
|
|
49
53
|
|
|
50
54
|
function renderProfiles(homeDirectory: string): string {
|
|
51
55
|
const profiles = listAgentRuntimeProfiles(homeDirectory);
|
|
56
|
+
const selected = readAgentRuntimeProfileSelection(homeDirectory);
|
|
57
|
+
const defaultLine = selected ? ` default: ${selected.id}${selected.exists ? '' : ' (missing)'}` : ' default: (base Agent home)';
|
|
52
58
|
if (profiles.length === 0) {
|
|
53
59
|
return [
|
|
54
60
|
'Agent Profiles',
|
|
61
|
+
defaultLine,
|
|
55
62
|
' No isolated Agent profiles yet.',
|
|
56
63
|
' Create one with /agent-profile create <name> --template <id> --yes.',
|
|
57
64
|
].join('\n');
|
|
58
65
|
}
|
|
59
|
-
return ['Agent Profiles', ...profiles.map(profileLine)].join('\n');
|
|
66
|
+
return ['Agent Profiles', defaultLine, ...profiles.map(profileLine)].join('\n');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function renderProfileDetail(homeDirectory: string, name: string): string {
|
|
70
|
+
const profile = resolveAgentRuntimeProfileHome(homeDirectory, name);
|
|
71
|
+
const info = listAgentRuntimeProfiles(homeDirectory).find((entry) => entry.id === profile.id) ?? { ...profile, createdAt: null };
|
|
72
|
+
const starter = info.starterTemplateId ? [` starter: ${info.starterTemplateId} (${info.starterTemplateName ?? info.starterTemplateId})`] : [];
|
|
73
|
+
return [
|
|
74
|
+
`Agent profile: ${profile.id}`,
|
|
75
|
+
` home: ${profile.homeDirectory}`,
|
|
76
|
+
...starter,
|
|
77
|
+
` use: goodvibes-agent --agent-profile ${profile.id}`,
|
|
78
|
+
].join('\n');
|
|
60
79
|
}
|
|
61
80
|
|
|
62
81
|
function renderTemplates(homeDirectory: string): string {
|
|
@@ -92,7 +111,7 @@ function renderGuide(homeDirectory: string): string {
|
|
|
92
111
|
'5. Create an Agent profile from the imported starter:',
|
|
93
112
|
' /agent-profile create <name> --template <imported-id> --yes',
|
|
94
113
|
'',
|
|
95
|
-
'This writes only Agent-local starter/profile state. It does not mutate connected GoodVibes
|
|
114
|
+
'This writes only Agent-local starter/profile state. It does not mutate connected GoodVibes host, default wiki, or non-Agent knowledge segments.',
|
|
96
115
|
].join('\n');
|
|
97
116
|
}
|
|
98
117
|
|
|
@@ -117,7 +136,7 @@ export function registerAgentRuntimeProfileRuntimeCommands(registry: CommandRegi
|
|
|
117
136
|
name: 'agent-profile',
|
|
118
137
|
aliases: ['runtime-profile', 'agent-profiles'],
|
|
119
138
|
description: 'Manage isolated Agent profiles and starter templates',
|
|
120
|
-
usage: '[list|templates|guide|template show|template export|template import|template from-discovered|create|create-from-discovered|delete]',
|
|
139
|
+
usage: '[list|show|default|use|templates|guide|template show|template export|template import|template from-discovered|create|create-from-discovered|delete]',
|
|
121
140
|
async handler(args, ctx) {
|
|
122
141
|
const shellPaths = requireShellPaths(ctx);
|
|
123
142
|
const homeDirectory = shellPaths.homeDirectory;
|
|
@@ -136,6 +155,72 @@ export function registerAgentRuntimeProfileRuntimeCommands(registry: CommandRegi
|
|
|
136
155
|
return;
|
|
137
156
|
}
|
|
138
157
|
|
|
158
|
+
if (sub === 'show' || sub === 'path' || sub === 'home') {
|
|
159
|
+
const name = commandArgs[1];
|
|
160
|
+
if (!name) {
|
|
161
|
+
ctx.print('Usage: /agent-profile show <name>');
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
ctx.print(renderProfileDetail(homeDirectory, name));
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (sub === 'default') {
|
|
169
|
+
const target = commandArgs[1];
|
|
170
|
+
if (target === 'clear' || target === 'none' || target === 'base') {
|
|
171
|
+
if (!parsed.yes) {
|
|
172
|
+
requireYesFlag(ctx, 'clear the default Agent profile', '/agent-profile default clear --yes');
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
clearAgentRuntimeProfileSelection(homeDirectory);
|
|
176
|
+
ctx.print('Default Agent profile cleared. Next launch uses the base Agent home unless --agent-profile is provided.');
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (target) {
|
|
180
|
+
if (!parsed.yes) {
|
|
181
|
+
requireYesFlag(ctx, `set default Agent profile ${target}`, '/agent-profile default <name> --yes');
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const selected = setAgentRuntimeProfileSelection(homeDirectory, target);
|
|
185
|
+
ctx.print([
|
|
186
|
+
`Default Agent profile selected: ${selected.id}`,
|
|
187
|
+
` home: ${selected.homeDirectory}`,
|
|
188
|
+
' next launch: goodvibes-agent',
|
|
189
|
+
' explicit override: goodvibes-agent --agent-profile <name>',
|
|
190
|
+
].join('\n'));
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const selected = readAgentRuntimeProfileSelection(homeDirectory);
|
|
194
|
+
ctx.print(selected
|
|
195
|
+
? [
|
|
196
|
+
`Default Agent profile: ${selected.id}${selected.exists ? '' : ' (missing)'}`,
|
|
197
|
+
` home: ${selected.homeDirectory}`,
|
|
198
|
+
' next launch: goodvibes-agent',
|
|
199
|
+
].join('\n')
|
|
200
|
+
: 'No default Agent profile selected. Next launch uses the base Agent home.');
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (sub === 'use' || sub === 'select' || sub === 'switch') {
|
|
205
|
+
const name = commandArgs[1];
|
|
206
|
+
if (!name) {
|
|
207
|
+
ctx.print('Usage: /agent-profile use <name> --yes');
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (!parsed.yes) {
|
|
211
|
+
requireYesFlag(ctx, `set default Agent profile ${name}`, '/agent-profile use <name> --yes');
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const selected = setAgentRuntimeProfileSelection(homeDirectory, name);
|
|
215
|
+
ctx.print([
|
|
216
|
+
`Default Agent profile selected: ${selected.id}`,
|
|
217
|
+
` home: ${selected.homeDirectory}`,
|
|
218
|
+
' next launch: goodvibes-agent',
|
|
219
|
+
' explicit override: goodvibes-agent --agent-profile <name>',
|
|
220
|
+
].join('\n'));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
139
224
|
if (sub === 'guide' || sub === 'author') {
|
|
140
225
|
ctx.print(renderGuide(homeDirectory));
|
|
141
226
|
return;
|
|
@@ -283,7 +368,7 @@ export function registerAgentRuntimeProfileRuntimeCommands(registry: CommandRegi
|
|
|
283
368
|
return;
|
|
284
369
|
}
|
|
285
370
|
|
|
286
|
-
ctx.print('Usage: /agent-profile [list|templates|guide|template show <id>|template export <id> <path> --yes|template import <path> --yes|create <name> [--template <id>] --yes|create-from-discovered <name> --yes|delete <name> --yes]');
|
|
371
|
+
ctx.print('Usage: /agent-profile [list|show <name>|default [<name>|clear] --yes|use <name> --yes|templates|guide|template show <id>|template export <id> <path> --yes|template import <path> --yes|create <name> [--template <id>] --yes|create-from-discovered <name> --yes|delete <name> --yes]');
|
|
287
372
|
} catch (error) {
|
|
288
373
|
ctx.print(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
289
374
|
}
|