@pellux/goodvibes-agent 0.1.106 → 0.1.108

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +41 -10
  2. package/README.md +28 -9
  3. package/docs/README.md +5 -5
  4. package/docs/{runtime-connection.md → connected-services.md} +8 -8
  5. package/docs/getting-started.md +29 -10
  6. package/docs/release-and-publishing.md +4 -4
  7. package/package.json +2 -12
  8. package/src/agent/reminder-schedule-format.ts +75 -0
  9. package/src/agent/reminder-schedule.ts +494 -0
  10. package/src/agent/routine-schedule-format.ts +7 -7
  11. package/src/agent/routine-schedule-promotion.ts +1 -1
  12. package/src/agent/routine-schedule-receipts.ts +1 -1
  13. package/src/agent/skill-discovery.ts +2 -0
  14. package/src/cli/agent-knowledge-args.ts +93 -0
  15. package/src/cli/agent-knowledge-command.ts +200 -369
  16. package/src/cli/agent-knowledge-format.ts +58 -7
  17. package/src/cli/agent-knowledge-methods.ts +84 -0
  18. package/src/cli/agent-knowledge-runtime.ts +240 -0
  19. package/src/cli/config-overrides.ts +2 -2
  20. package/src/cli/help.ts +31 -11
  21. package/src/cli/management-commands.ts +2 -2
  22. package/src/cli/management.ts +8 -8
  23. package/src/cli/package-verification.ts +7 -3
  24. package/src/cli/parser.ts +10 -2
  25. package/src/cli/service-posture.ts +6 -6
  26. package/src/cli/status.ts +32 -32
  27. package/src/cli/tui-startup.ts +3 -1
  28. package/src/input/agent-workspace-activation.ts +24 -13
  29. package/src/input/agent-workspace-basic-command-editors.ts +448 -0
  30. package/src/input/agent-workspace-categories.ts +42 -34
  31. package/src/input/agent-workspace-channels.ts +3 -3
  32. package/src/input/agent-workspace-command-editor.ts +65 -0
  33. package/src/input/agent-workspace-editors.ts +17 -2
  34. package/src/input/agent-workspace-knowledge-query-editor.ts +74 -0
  35. package/src/input/agent-workspace-knowledge-url-editor.ts +95 -0
  36. package/src/input/agent-workspace-reminder-schedule-editor.ts +125 -0
  37. package/src/input/agent-workspace-routine-schedule-editor.ts +127 -0
  38. package/src/input/agent-workspace-setup.ts +2 -2
  39. package/src/input/agent-workspace-types.ts +20 -2
  40. package/src/input/agent-workspace-voice-media.ts +5 -5
  41. package/src/input/agent-workspace.ts +39 -2
  42. package/src/input/commands/agent-runtime-profile-runtime.ts +1 -1
  43. package/src/input/commands/agent-skills-runtime.ts +94 -2
  44. package/src/input/commands/brief-runtime.ts +126 -0
  45. package/src/input/commands/channels-runtime.ts +47 -0
  46. package/src/input/commands/health-runtime.ts +10 -10
  47. package/src/input/commands/knowledge.ts +176 -1
  48. package/src/input/commands/planning-runtime.ts +1 -1
  49. package/src/input/commands/platform-access-runtime.ts +10 -10
  50. package/src/input/commands/policy-dispatch.ts +1 -1
  51. package/src/input/commands/schedule-runtime.ts +42 -5
  52. package/src/input/commands/security-runtime.ts +1 -1
  53. package/src/input/commands/session-content.ts +1 -1
  54. package/src/input/commands/session-workflow.ts +1 -1
  55. package/src/input/commands/shell-core.ts +4 -2
  56. package/src/input/commands/tasks-runtime.ts +3 -3
  57. package/src/input/commands.ts +4 -0
  58. package/src/input/handler-onboarding.ts +4 -4
  59. package/src/input/handler.ts +3 -2
  60. package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
  61. package/src/input/onboarding/onboarding-wizard-operator-steps.ts +13 -13
  62. package/src/input/onboarding/onboarding-wizard-steps.ts +8 -8
  63. package/src/input/settings-modal-agent-policy.ts +1 -1
  64. package/src/input/slash-command-parser.ts +60 -0
  65. package/src/panels/builtin/agent.ts +1 -1
  66. package/src/panels/builtin/operations.ts +2 -2
  67. package/src/panels/provider-account-snapshot.ts +1 -1
  68. package/src/panels/provider-health-domains.ts +6 -6
  69. package/src/panels/subscription-panel.ts +1 -1
  70. package/src/panels/tasks-panel.ts +3 -3
  71. package/src/renderer/agent-workspace.ts +43 -30
  72. package/src/renderer/help-overlay.ts +1 -1
  73. package/src/renderer/settings-modal.ts +13 -13
  74. package/src/runtime/bootstrap-hook-bridge.ts +1 -1
  75. package/src/runtime/bootstrap.ts +8 -8
  76. package/src/runtime/index.ts +2 -2
  77. package/src/runtime/onboarding/derivation.ts +6 -6
  78. package/src/shell/service-settings-sync.ts +1 -1
  79. package/src/version.ts +1 -1
package/src/cli/parser.ts CHANGED
@@ -7,7 +7,6 @@ import type {
7
7
 
8
8
  const COMMAND_ALIASES: Readonly<Record<string, GoodVibesCliCommand>> = {
9
9
  tui: 'tui',
10
- app: 'tui',
11
10
  run: 'run',
12
11
  exec: 'run',
13
12
  e: 'run',
@@ -61,6 +60,8 @@ const COMMAND_ALIASES: Readonly<Record<string, GoodVibesCliCommand>> = {
61
60
  version: 'version',
62
61
  };
63
62
 
63
+ const RETIRED_LAUNCHER_ALIASES = new Set(['app', 'launch', 'start']);
64
+
64
65
  function createDefaultFlags(): GoodVibesCliFlags {
65
66
  return {
66
67
  provider: undefined,
@@ -201,7 +202,14 @@ export function parseGoodVibesCli(
201
202
 
202
203
  if (!token.startsWith('-') || token === '-') {
203
204
  if (!sawCommand) {
204
- const normalized = COMMAND_ALIASES[token.toLowerCase()];
205
+ const commandToken = token.toLowerCase();
206
+ if (RETIRED_LAUNCHER_ALIASES.has(commandToken)) {
207
+ command = 'unknown';
208
+ rawCommand = token;
209
+ sawCommand = true;
210
+ continue;
211
+ }
212
+ const normalized = COMMAND_ALIASES[commandToken];
205
213
  if (normalized) {
206
214
  command = normalized;
207
215
  rawCommand = token;
@@ -143,7 +143,7 @@ function resolveConfiguredLogPath(runtime: CliServiceRuntime): string | undefine
143
143
  function createExternalDaemonLifecycle(logPath: string | undefined): CliExternalDaemonLifecyclePosture {
144
144
  return {
145
145
  platform: 'manual',
146
- path: 'external GoodVibes runtime host',
146
+ path: 'connected GoodVibes services',
147
147
  installed: false,
148
148
  autostart: false,
149
149
  running: false,
@@ -151,7 +151,7 @@ function createExternalDaemonLifecycle(logPath: string | undefined): CliExternal
151
151
  commandPreview: 'managed outside goodvibes-agent',
152
152
  suggestedCommands: [],
153
153
  lastAction: 'status',
154
- pidPath: 'external GoodVibes runtime host',
154
+ pidPath: 'connected GoodVibes services',
155
155
  lastError: null,
156
156
  };
157
157
  }
@@ -184,13 +184,13 @@ export async function buildCliServicePosture(
184
184
  const issues: string[] = [];
185
185
 
186
186
  if (serverBackedEnabled && !config.enabled) {
187
- issues.push('External runtime connection settings are present, but Agent runtime lifecycle ownership is disabled by design.');
187
+ issues.push('Connected-service settings are present, but Agent service ownership is disabled by design.');
188
188
  }
189
189
  if (config.enabled && !config.autostart) {
190
- issues.push('External runtime host config has autostart off.');
190
+ issues.push('Connected-service autostart is off.');
191
191
  }
192
192
  if (config.enabled && !config.restartOnFailure) {
193
- issues.push('External runtime host config has restart-on-failure off.');
193
+ issues.push('Connected-service restart-on-failure is off.');
194
194
  }
195
195
  for (const endpoint of endpoints) {
196
196
  if (endpoint.enabled && options.probe && endpoint.reachable === false) {
@@ -239,7 +239,7 @@ export function formatCliServicePosture(posture: CliServicePosture, json = false
239
239
  ` log: ${posture.log.path ?? 'n/a'} (${posture.log.exists ? 'present' : 'missing'})`,
240
240
  ...(posture.log.readError ? [` log read error: ${posture.log.readError}`] : []),
241
241
  '',
242
- 'Runtime connection checks:',
242
+ 'Connected GoodVibes API checks:',
243
243
  ...posture.endpoints.map((endpoint) =>
244
244
  ` ${endpoint.label}: enabled=${yesNo(endpoint.enabled)} ${endpoint.binding.hostMode} ${endpoint.binding.host}:${endpoint.binding.port} posture=${endpoint.bindPosture.label}${endpoint.reachable === undefined ? '' : ` reachable=${yesNo(endpoint.reachable)}`}`,
245
245
  ),
package/src/cli/status.ts CHANGED
@@ -126,20 +126,20 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
126
126
  id: 'external-runtime-unreachable',
127
127
  area: 'runtime',
128
128
  severity: 'warning',
129
- summary: 'External GoodVibes runtime is not reachable.',
129
+ summary: 'Connected GoodVibes services are not reachable.',
130
130
  cause: `Agent could not reach ${options.externalRuntime.baseUrl}${options.externalRuntime.error ? `: ${options.externalRuntime.error}` : '.'}`,
131
- impact: 'Companion chat, isolated Agent Knowledge, approvals, automation status, and build delegation cannot work until the external runtime is available.',
132
- action: 'Start or repair the runtime-owning GoodVibes TUI/host, then rerun goodvibes-agent status.',
131
+ impact: 'Companion chat, isolated Agent Knowledge, approvals, automation status, and build delegation cannot work until connected GoodVibes services are available.',
132
+ action: 'Start or repair the owning GoodVibes host, then rerun goodvibes-agent status.',
133
133
  });
134
134
  } else if (!options.externalRuntime.compatible) {
135
135
  findings.push({
136
136
  id: 'external-runtime-version-mismatch',
137
137
  area: 'runtime',
138
138
  severity: 'warning',
139
- summary: 'External GoodVibes runtime SDK version does not match Agent.',
140
- cause: `Runtime reports SDK ${options.externalRuntime.version}; Agent expects ${options.externalRuntime.expectedVersion}.`,
139
+ summary: 'Connected GoodVibes service SDK version does not match Agent.',
140
+ cause: `Connected service reports SDK ${options.externalRuntime.version}; Agent expects ${options.externalRuntime.expectedVersion}.`,
141
141
  impact: 'Agent-only routes, especially isolated Agent Knowledge, may be missing or incompatible.',
142
- action: 'Update/restart the runtime-owning GoodVibes TUI/host so /status matches this Agent package SDK pin.',
142
+ action: 'Update the owning GoodVibes host so /status matches this Agent package SDK pin.',
143
143
  });
144
144
  }
145
145
 
@@ -148,10 +148,10 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
148
148
  id: 'external-runtime-token-missing',
149
149
  area: 'auth',
150
150
  severity: 'warning',
151
- summary: 'External runtime operator token is missing.',
151
+ summary: 'Connected-service operator token is missing.',
152
152
  cause: `No operator token was found at ${options.externalRuntime.operatorToken.path}.`,
153
- impact: 'Agent can inspect only unauthenticated routes and cannot use protected runtime APIs.',
154
- action: 'Pair or provision access through the runtime-owning GoodVibes TUI/host, then rerun goodvibes-agent auth.',
153
+ impact: 'Agent can inspect only unauthenticated routes and cannot use protected connected-service APIs.',
154
+ action: 'Pair or provision access through the owning GoodVibes host, then rerun goodvibes-agent auth.',
155
155
  });
156
156
  }
157
157
 
@@ -163,7 +163,7 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
163
163
  summary: 'Isolated Agent Knowledge route is not ready.',
164
164
  cause: `${options.externalRuntime.agentKnowledge.route} returned ${options.externalRuntime.agentKnowledge.kind}${options.externalRuntime.agentKnowledge.statusCode === null ? '' : ` (${options.externalRuntime.agentKnowledge.statusCode})`}.`,
165
165
  impact: 'Agent Knowledge ask/search will not use any fallback wiki or non-Agent knowledge segment; it will fail closed until the Agent route is available.',
166
- action: 'Update/restart the external runtime to the Agent-compatible SDK and verify goodvibes-agent compat.',
166
+ action: 'Update the connected GoodVibes services to the Agent-compatible SDK and verify goodvibes-agent compat.',
167
167
  });
168
168
  }
169
169
  }
@@ -173,10 +173,10 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
173
173
  id: 'runtime-ownership-external',
174
174
  area: 'runtime',
175
175
  severity: 'warning',
176
- summary: 'External runtime connection settings are present while Agent lifecycle ownership is disabled by design.',
177
- cause: 'One or more runtime connection, inbound events, or browser companion settings are enabled while service.enabled is false.',
178
- impact: 'The external GoodVibes runtime must own availability for those endpoints; Agent will not start or enable them.',
179
- action: 'Manage runtime availability from GoodVibes TUI or the owning host, then use Agent for read-only diagnostics.',
176
+ summary: 'Connected-service settings are present while Agent service ownership is disabled by design.',
177
+ cause: 'One or more connected API, inbound events, or browser companion settings are enabled while service.enabled is false.',
178
+ impact: 'The owning GoodVibes host must provide availability for those endpoints; Agent will not start or enable them.',
179
+ action: 'Manage connected-service availability from GoodVibes TUI or the owning host, then use Agent for read-only diagnostics.',
180
180
  });
181
181
  }
182
182
 
@@ -185,9 +185,9 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
185
185
  id: 'runtime-autostart-disabled',
186
186
  area: 'runtime',
187
187
  severity: 'warning',
188
- summary: 'External runtime host config has autostart off.',
188
+ summary: 'Connected-service autostart is off.',
189
189
  cause: 'service.enabled is true and service.autostart is false.',
190
- impact: 'The external GoodVibes runtime may not be available after login or reboot even though host-managed startup is selected.',
190
+ impact: 'Connected GoodVibes services may not be available after login or reboot even though host-managed startup is selected.',
191
191
  action: 'Configure autostart from GoodVibes TUI or the owning host; Agent will not mutate this setting.',
192
192
  });
193
193
  }
@@ -197,9 +197,9 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
197
197
  id: 'runtime-restart-disabled',
198
198
  area: 'runtime',
199
199
  severity: 'warning',
200
- summary: 'External runtime host config has restart-on-failure off.',
200
+ summary: 'Connected-service restart-on-failure is off.',
201
201
  cause: 'service.enabled is true and service.restartOnFailure is false.',
202
- impact: 'A crashed runtime or listener may stay down until manually restarted.',
202
+ impact: 'A crashed connected service or listener may stay down until manually restarted.',
203
203
  action: 'Configure restart-on-failure from GoodVibes TUI or the owning host; Agent will not mutate this setting.',
204
204
  });
205
205
  }
@@ -212,9 +212,9 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
212
212
  area: 'runtime',
213
213
  severity: 'warning',
214
214
  summary: issue,
215
- cause: 'The runtime connection inspection found a mismatch between configured endpoint state and observed host state.',
216
- impact: 'Runtime API, listener, or web availability may not match the configuration.',
217
- action: 'Use Agent status and doctor diagnostics here, then manage the runtime from GoodVibes TUI or your host tooling.',
215
+ cause: 'The connected-service inspection found a mismatch between configured endpoint state and observed host state.',
216
+ impact: 'Connected API, listener, or web availability may not match the configuration.',
217
+ action: 'Use Agent status and doctor diagnostics here, then manage connected services outside Agent.',
218
218
  });
219
219
  }
220
220
  }
@@ -226,7 +226,7 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
226
226
  severity: 'warning',
227
227
  summary: 'Agent setup has not been shown for this user.',
228
228
  cause: 'No global user setup check marker was found.',
229
- impact: 'Important runtime, network, provider, auth, or permission choices may still be implicit defaults.',
229
+ impact: 'Important connected-service, network, provider, auth, or permission choices may still be implicit defaults.',
230
230
  action: 'Run /setup in GoodVibes Agent or goodvibes-agent setup status to review setup state.',
231
231
  });
232
232
  }
@@ -236,10 +236,10 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
236
236
  id: 'network-endpoint-without-runtime-auth-signal',
237
237
  area: 'auth',
238
238
  severity: 'risk',
239
- summary: 'Network-facing runtime endpoints are enabled without a visible runtime auth signal.',
240
- cause: `${networkFacingSurfaces.map(([name]) => name).join(', ')} are LAN/custom-bound, but Agent cannot see runtime auth state from its local compatibility files.`,
241
- impact: 'Remote access paths may be unusable or unsafe unless the external runtime owner configured auth.',
242
- action: 'Review runtime auth from the owning GoodVibes TUI or host tooling; Agent will not create local runtime users.',
239
+ summary: 'Network-facing connected-service endpoints are enabled without a visible auth signal.',
240
+ cause: `${networkFacingSurfaces.map(([name]) => name).join(', ')} are LAN/custom-bound, but Agent cannot see connected-service auth state from its local compatibility files.`,
241
+ impact: 'Remote access paths may be unusable or unsafe unless the owning host configured auth.',
242
+ action: 'Review connected-service auth outside Agent; Agent will not create local service users.',
243
243
  });
244
244
  }
245
245
 
@@ -251,7 +251,7 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
251
251
  summary: 'A bootstrap credential is still present while network-facing surfaces are enabled.',
252
252
  cause: `${networkFacingSurfaces.map(([name]) => name).join(', ')} are LAN/custom-bound and auth-bootstrap.txt exists.`,
253
253
  impact: 'Bootstrap credentials should be treated as temporary setup material, not long-lived network access credentials.',
254
- action: 'Use the runtime-owning GoodVibes TUI or host tooling to replace bootstrap auth and retire the bootstrap credential.',
254
+ action: 'Replace bootstrap auth and retire the bootstrap credential outside Agent.',
255
255
  });
256
256
  }
257
257
 
@@ -379,7 +379,7 @@ export function renderCliStatus(options: CliStatusOptions): string {
379
379
  ? ` operatorTokens: ${options.auth.operatorTokenPresent ? 'present' : 'missing'} (${options.auth.operatorTokenPath})`
380
380
  : ' operatorTokens: unknown',
381
381
  '',
382
- 'Runtime Connection:',
382
+ 'Connected GoodVibes API:',
383
383
  ...(externalRuntime ? [
384
384
  ` baseUrl: ${externalRuntime.baseUrl}`,
385
385
  ` reachable: ${yesNo(externalRuntime.reachable)}${externalRuntime.statusCode === null ? '' : ` (HTTP ${externalRuntime.statusCode})`}`,
@@ -392,10 +392,10 @@ export function renderCliStatus(options: CliStatusOptions): string {
392
392
  ' live check: unavailable',
393
393
  ]),
394
394
  '',
395
- 'Runtime Ownership:',
395
+ 'Connected GoodVibes Services:',
396
396
  ' Agent role: client/operator TUI only',
397
- ' hosting lifecycle: external',
398
- ' Agent starts runtime: no',
397
+ ' service ownership: outside Agent',
398
+ ' Agent starts services: no',
399
399
  ...(options.service ? [
400
400
  ` platform: ${options.service.managed.platform}`,
401
401
  ` installed: ${yesNo(options.service.managed.installed)}`,
@@ -412,7 +412,7 @@ export function renderCliStatus(options: CliStatusOptions): string {
412
412
  if (options.doctor) {
413
413
  lines.push(
414
414
  '',
415
- 'External Runtime Config Signals:',
415
+ 'Connected-Service Config Signals:',
416
416
  ` host config present: ${yesNo(serviceEnabled)}`,
417
417
  ` host autostart: ${yesNo(serviceAutostart)}`,
418
418
  ` host restart policy: ${yesNo(restartOnFailure)}`,
@@ -100,6 +100,7 @@ export function applyInitialTuiCliState(options: {
100
100
  }): void {
101
101
  const { cli, input, commandRegistry, commandContext, shellPaths, render } = options;
102
102
  const globalOnboardingMarker = readOnboardingCheckMarker(shellPaths, 'user');
103
+ const seededPrompt = cli.flags.prompt ?? (cli.rawCommand === undefined && cli.positionals.length > 0 ? cli.positionals.join(' ') : undefined);
103
104
  if (cli.command === 'onboarding') {
104
105
  input.openOnboardingWizard({ mode: 'edit', reset: true });
105
106
  } else if (cli.command === 'sessions' && cli.commandArgs[0] === 'resume') {
@@ -109,9 +110,10 @@ export function applyInitialTuiCliState(options: {
109
110
  }
110
111
  } else if (!globalOnboardingMarker.exists) {
111
112
  input.openOnboardingWizard({ mode: 'new', reset: true });
113
+ } else if (cli.command === 'tui' && seededPrompt === undefined) {
114
+ input.openAgentWorkspace(commandContext);
112
115
  }
113
116
 
114
- const seededPrompt = cli.flags.prompt ?? (cli.rawCommand === undefined && cli.positionals.length > 0 ? cli.positionals.join(' ') : undefined);
115
117
  if (seededPrompt) {
116
118
  input.prompt = seededPrompt;
117
119
  input.cursorPos = seededPrompt.length;
@@ -1,4 +1,9 @@
1
1
  import { createLocalEditor, createProfileEditor } from './agent-workspace-editors.ts';
2
+ import { createAgentWorkspaceBasicCommandEditor, isAgentWorkspaceBasicCommandEditorKind } from './agent-workspace-basic-command-editors.ts';
3
+ import { createAgentKnowledgeQueryEditor } from './agent-workspace-knowledge-query-editor.ts';
4
+ import { createReminderScheduleEditor } from './agent-workspace-reminder-schedule-editor.ts';
5
+ import { createRoutineScheduleEditor } from './agent-workspace-routine-schedule-editor.ts';
6
+ import { parseSlashCommand } from './slash-command-parser.ts';
2
7
  import type {
3
8
  AgentWorkspaceActionResult,
4
9
  AgentWorkspaceCategory,
@@ -6,6 +11,7 @@ import type {
6
11
  AgentWorkspaceFocusPane,
7
12
  AgentWorkspaceLocalEditor,
8
13
  AgentWorkspaceLocalEditorKind,
14
+ AgentWorkspaceLocalLibraryItem,
9
15
  AgentWorkspaceLocalOperation,
10
16
  AgentWorkspaceRuntimeSnapshot,
11
17
  } from './agent-workspace-types.ts';
@@ -25,18 +31,12 @@ interface AgentWorkspaceActivationHost {
25
31
  focusActions(): void;
26
32
  clampSelection(): void;
27
33
  moveLocalLibraryItemSelection(kind: AgentWorkspaceLocalEditorKind, delta: number): void;
34
+ selectedLocalLibraryItem(kind: AgentWorkspaceLocalEditorKind): AgentWorkspaceLocalLibraryItem | null;
28
35
  applyLocalLibraryOperation(operation: AgentWorkspaceLocalOperation): void;
29
36
  hasCommandDispatch(): boolean;
30
37
  dispatchWorkspaceCommand: AgentWorkspaceCommandDispatcher;
31
38
  }
32
39
 
33
- function parseCommand(command: string): { readonly name: string; readonly args: readonly string[] } {
34
- const trimmed = command.trim().replace(/^\//, '');
35
- if (!trimmed) return { name: '', args: [] };
36
- const parts = trimmed.split(/\s+/);
37
- return { name: parts[0] ?? '', args: parts.slice(1) };
38
- }
39
-
40
40
  export function activateAgentWorkspaceSelection(
41
41
  workspace: AgentWorkspaceActivationHost,
42
42
  requestRender?: () => void,
@@ -52,9 +52,7 @@ export function activateAgentWorkspaceSelection(
52
52
  const action = workspace.selectedAction;
53
53
  if (!action) return;
54
54
  if (action.kind === 'editor' && action.editorKind) {
55
- workspace.localEditor = action.editorKind === 'profile'
56
- ? createProfileEditor(workspace.runtimeSnapshot?.runtimeStarterTemplates ?? [])
57
- : createLocalEditor(action.editorKind);
55
+ workspace.localEditor = createWorkspaceEditor(workspace, action.editorKind);
58
56
  workspace.status = `Editing ${workspace.localEditor.title}.`;
59
57
  workspace.lastActionResult = {
60
58
  kind: 'guidance',
@@ -87,7 +85,7 @@ export function activateAgentWorkspaceSelection(
87
85
  };
88
86
  return;
89
87
  }
90
- const parsed = parseCommand(action.command);
88
+ const parsed = parseSlashCommand(action.command);
91
89
  if (!parsed.name) {
92
90
  workspace.status = `No command is configured for ${action.label}.`;
93
91
  workspace.lastActionResult = {
@@ -99,11 +97,11 @@ export function activateAgentWorkspaceSelection(
99
97
  return;
100
98
  }
101
99
  if (/<[^>\s]+(?:\s+[^>]*)?>/.test(action.command)) {
102
- workspace.status = `Placeholder command not dispatched: ${action.command}.`;
100
+ workspace.status = `Command needs concrete values before dispatch: ${action.command}.`;
103
101
  workspace.lastActionResult = {
104
102
  kind: 'guidance',
105
103
  title: `${action.label} needs details`,
106
- detail: 'This action is a command template. Close the workspace and run it with real task text instead of placeholder values.',
104
+ detail: 'This action needs concrete values before it can run. Return to the composer and include the real task text.',
107
105
  command: action.command,
108
106
  safety: action.safety,
109
107
  };
@@ -131,6 +129,19 @@ export function activateAgentWorkspaceSelection(
131
129
  workspace.dispatchWorkspaceCommand(action.command);
132
130
  }
133
131
 
132
+ function createWorkspaceEditor(
133
+ workspace: AgentWorkspaceActivationHost,
134
+ editorKind: AgentWorkspaceCategory['actions'][number]['editorKind'],
135
+ ): AgentWorkspaceLocalEditor {
136
+ if (editorKind === 'profile') return createProfileEditor(workspace.runtimeSnapshot?.runtimeStarterTemplates ?? []);
137
+ if (editorKind && isAgentWorkspaceBasicCommandEditorKind(editorKind)) return createAgentWorkspaceBasicCommandEditor(editorKind);
138
+ if (editorKind === 'knowledge-ask') return createAgentKnowledgeQueryEditor('ask');
139
+ if (editorKind === 'knowledge-search') return createAgentKnowledgeQueryEditor('search');
140
+ if (editorKind === 'reminder-schedule') return createReminderScheduleEditor();
141
+ if (editorKind === 'routine-schedule') return createRoutineScheduleEditor(workspace.selectedLocalLibraryItem('routine'));
142
+ return createLocalEditor(editorKind ?? 'memory');
143
+ }
144
+
134
145
  function handleGuidanceOrWorkspaceAction(
135
146
  workspace: AgentWorkspaceActivationHost,
136
147
  action: AgentWorkspaceCategory['actions'][number],