@pellux/goodvibes-agent 0.1.70 → 0.1.72

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 (78) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +3 -3
  3. package/docs/README.md +2 -2
  4. package/docs/getting-started.md +1 -1
  5. package/docs/runtime-connection.md +37 -0
  6. package/package.json +43 -2
  7. package/src/agent/skill-discovery.ts +119 -0
  8. package/src/cli/config-overrides.ts +1 -5
  9. package/src/cli/entrypoint.ts +0 -6
  10. package/src/cli/help.ts +0 -43
  11. package/src/cli/index.ts +0 -2
  12. package/src/cli/management-commands.ts +1 -109
  13. package/src/cli/management.ts +1 -32
  14. package/src/cli/package-verification.ts +12 -4
  15. package/src/cli/parser.ts +0 -16
  16. package/src/cli/status.ts +1 -1
  17. package/src/cli/types.ts +0 -8
  18. package/src/input/commands/delegation-runtime.ts +0 -8
  19. package/src/input/commands/experience-runtime.ts +0 -177
  20. package/src/input/commands/guidance-runtime.ts +0 -69
  21. package/src/input/commands/local-runtime.ts +1 -57
  22. package/src/input/commands/local-setup-review.ts +1 -1
  23. package/src/input/commands/operator-runtime.ts +1 -145
  24. package/src/input/commands/platform-access-runtime.ts +2 -195
  25. package/src/input/commands/product-runtime.ts +0 -116
  26. package/src/input/commands/security-runtime.ts +88 -0
  27. package/src/input/commands/session-content.ts +0 -97
  28. package/src/input/commands/shell-core.ts +0 -13
  29. package/src/input/commands.ts +2 -95
  30. package/src/panels/builtin/operations.ts +3 -184
  31. package/src/panels/confirm-state.ts +1 -1
  32. package/src/panels/index.ts +0 -11
  33. package/src/version.ts +1 -1
  34. package/docs/deployment-and-services.md +0 -52
  35. package/src/cli/service-command.ts +0 -26
  36. package/src/cli/surface-command.ts +0 -247
  37. package/src/input/commands/branch-runtime.ts +0 -72
  38. package/src/input/commands/control-room-runtime.ts +0 -234
  39. package/src/input/commands/discovery-runtime.ts +0 -61
  40. package/src/input/commands/hooks-runtime.ts +0 -207
  41. package/src/input/commands/incident-runtime.ts +0 -106
  42. package/src/input/commands/integration-runtime.ts +0 -437
  43. package/src/input/commands/local-setup.ts +0 -288
  44. package/src/input/commands/managed-runtime.ts +0 -240
  45. package/src/input/commands/marketplace-runtime.ts +0 -305
  46. package/src/input/commands/memory-product-runtime.ts +0 -148
  47. package/src/input/commands/operator-panel-runtime.ts +0 -146
  48. package/src/input/commands/platform-services-runtime.ts +0 -271
  49. package/src/input/commands/profile-sync-runtime.ts +0 -110
  50. package/src/input/commands/provider.ts +0 -363
  51. package/src/input/commands/remote-runtime-pool.ts +0 -89
  52. package/src/input/commands/remote-runtime-setup.ts +0 -226
  53. package/src/input/commands/remote-runtime.ts +0 -432
  54. package/src/input/commands/replay-runtime.ts +0 -25
  55. package/src/input/commands/services-runtime.ts +0 -220
  56. package/src/input/commands/settings-sync-runtime.ts +0 -197
  57. package/src/input/commands/share-runtime.ts +0 -127
  58. package/src/input/commands/skills-runtime.ts +0 -226
  59. package/src/input/commands/teleport-runtime.ts +0 -68
  60. package/src/panels/cockpit-panel.ts +0 -183
  61. package/src/panels/communication-panel.ts +0 -153
  62. package/src/panels/control-plane-panel.ts +0 -211
  63. package/src/panels/forensics-panel.ts +0 -364
  64. package/src/panels/hooks-panel.ts +0 -239
  65. package/src/panels/incident-review-panel.ts +0 -197
  66. package/src/panels/marketplace-panel.ts +0 -212
  67. package/src/panels/ops-control-panel.ts +0 -150
  68. package/src/panels/ops-strategy-panel.ts +0 -235
  69. package/src/panels/orchestration-panel.ts +0 -272
  70. package/src/panels/plugins-panel.ts +0 -178
  71. package/src/panels/remote-panel.ts +0 -449
  72. package/src/panels/routes-panel.ts +0 -178
  73. package/src/panels/services-panel.ts +0 -231
  74. package/src/panels/settings-sync-panel.ts +0 -120
  75. package/src/panels/skills-panel.ts +0 -431
  76. package/src/panels/watchers-panel.ts +0 -193
  77. package/src/verification/live-verifier.ts +0 -588
  78. package/src/verification/verification-ledger.ts +0 -239
package/src/cli/parser.ts CHANGED
@@ -11,12 +11,6 @@ const COMMAND_ALIASES: Readonly<Record<string, GoodVibesCliCommand>> = {
11
11
  run: 'run',
12
12
  exec: 'run',
13
13
  e: 'run',
14
- serve: 'serve',
15
- daemon: 'serve',
16
- server: 'serve',
17
- web: 'web',
18
- service: 'service',
19
- services: 'service',
20
14
  status: 'status',
21
15
  doctor: 'doctor',
22
16
  onboarding: 'onboarding',
@@ -51,18 +45,8 @@ const COMMAND_ALIASES: Readonly<Record<string, GoodVibesCliCommand>> = {
51
45
  pair: 'pair',
52
46
  qrcode: 'pair',
53
47
  qr: 'pair',
54
- surfaces: 'surfaces',
55
- surface: 'surfaces',
56
- listener: 'listener',
57
- 'http-listener': 'listener',
58
- webhook: 'listener',
59
- 'control-plane': 'control-plane',
60
- controlplane: 'control-plane',
61
- cp: 'control-plane',
62
48
  bundle: 'bundle',
63
49
  bundles: 'bundle',
64
- remote: 'remote',
65
- bridge: 'bridge',
66
50
  completion: 'completion',
67
51
  completions: 'completion',
68
52
  help: 'help',
package/src/cli/status.ts CHANGED
@@ -163,7 +163,7 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
163
163
  summary: issue,
164
164
  cause: 'The service lifecycle inspection found a mismatch between configured service/surface state and observed host state.',
165
165
  impact: 'Runtime API, listener, or web availability may not match the configuration.',
166
- action: 'Use goodvibes-agent service check for read-only detail, then manage the runtime from GoodVibes TUI or your host tooling.',
166
+ action: 'Use Agent status and doctor diagnostics here, then manage the runtime from GoodVibes TUI or your host tooling.',
167
167
  });
168
168
  }
169
169
  }
package/src/cli/types.ts CHANGED
@@ -1,9 +1,6 @@
1
1
  export type GoodVibesCliCommand =
2
2
  | 'tui'
3
3
  | 'run'
4
- | 'serve'
5
- | 'web'
6
- | 'service'
7
4
  | 'status'
8
5
  | 'doctor'
9
6
  | 'onboarding'
@@ -22,12 +19,7 @@ export type GoodVibesCliCommand =
22
19
  | 'sessions'
23
20
  | 'tasks'
24
21
  | 'pair'
25
- | 'surfaces'
26
- | 'listener'
27
- | 'control-plane'
28
22
  | 'bundle'
29
- | 'remote'
30
- | 'bridge'
31
23
  | 'completion'
32
24
  | 'help'
33
25
  | 'version'
@@ -118,12 +118,4 @@ export function registerDelegationRuntimeCommands(registry: CommandRegistry): vo
118
118
  argsHint: '[--wrfc] <task>',
119
119
  handler: makeHandler(false),
120
120
  });
121
- registry.register({
122
- name: 'wrfc',
123
- aliases: ['review'],
124
- description: 'Explicitly delegate build/fix/review work to GoodVibes TUI with WRFC requested',
125
- usage: '<task>',
126
- argsHint: '<task>',
127
- handler: makeHandler(true),
128
- });
129
121
  }
@@ -3,7 +3,6 @@ import { dirname, resolve } from 'node:path';
3
3
  import type { CommandRegistry } from '../command-registry.ts';
4
4
  import { requirePanelManager, requireShellPaths } from './runtime-services.ts';
5
5
  import { requireYesFlag, stripYesFlag } from './confirmation.ts';
6
- import { resolveAgentDaemonConnection } from '../../agent/routine-schedule-promotion.ts';
7
6
 
8
7
  interface VoiceBundle {
9
8
  readonly version: 1;
@@ -22,159 +21,6 @@ function inspectVoiceBundle(bundle: VoiceBundle): string {
22
21
  }
23
22
 
24
23
  export function registerExperienceRuntimeCommands(registry: CommandRegistry): void {
25
- registry.register({
26
- name: 'remote-setup',
27
- description: 'Dedicated front-door for remote setup review and portable setup bundles',
28
- usage: '[review|export <path> --yes]',
29
- async handler(args, ctx) {
30
- const parsed = stripYesFlag(args);
31
- const commandArgs = [...parsed.rest];
32
- const sub = (commandArgs[0] ?? 'review').toLowerCase();
33
- if (ctx.executeCommand) {
34
- if (sub === 'review') {
35
- await ctx.executeCommand('remote', ['setup']);
36
- return;
37
- }
38
- if (sub === 'export') {
39
- const pathArg = commandArgs[1];
40
- if (!pathArg) {
41
- ctx.print('Usage: /remote-setup export <path> --yes');
42
- return;
43
- }
44
- if (!parsed.yes) {
45
- requireYesFlag(ctx, `export remote setup bundle to ${pathArg}`, '/remote-setup export <path> --yes');
46
- return;
47
- }
48
- await ctx.executeCommand('remote', ['setup', 'export', pathArg, '--yes']);
49
- return;
50
- }
51
- }
52
- ctx.print('Remote setup controls are not available in this runtime.');
53
- },
54
- });
55
-
56
- registry.register({
57
- name: 'remote-env',
58
- description: 'Dedicated front-door for remote environment snippets and portable env exports',
59
- usage: '[review|export <path> --yes]',
60
- async handler(args, ctx) {
61
- const parsed = stripYesFlag(args);
62
- const commandArgs = [...parsed.rest];
63
- const sub = (commandArgs[0] ?? 'review').toLowerCase();
64
- if (ctx.executeCommand) {
65
- if (sub === 'review') {
66
- await ctx.executeCommand('remote', ['env']);
67
- return;
68
- }
69
- if (sub === 'export') {
70
- const pathArg = commandArgs[1];
71
- if (!pathArg) {
72
- ctx.print('Usage: /remote-env export <path> --yes');
73
- return;
74
- }
75
- if (!parsed.yes) {
76
- requireYesFlag(ctx, `export remote environment snippet to ${pathArg}`, '/remote-env export <path> --yes');
77
- return;
78
- }
79
- await ctx.executeCommand('remote', ['env', 'export', pathArg, '--yes']);
80
- return;
81
- }
82
- }
83
- ctx.print('Remote environment controls are not available in this runtime.');
84
- },
85
- });
86
-
87
- registry.register({
88
- name: 'tunnel',
89
- description: 'Dedicated front-door for remote tunnel review and export flows',
90
- usage: '[review|export <path> --yes]',
91
- async handler(args, ctx) {
92
- const parsed = stripYesFlag(args);
93
- const commandArgs = [...parsed.rest];
94
- const sub = (commandArgs[0] ?? 'review').toLowerCase();
95
- if (ctx.executeCommand) {
96
- if (sub === 'review') {
97
- await ctx.executeCommand('remote', ['tunnel', 'review']);
98
- return;
99
- }
100
- if (sub === 'export') {
101
- const pathArg = commandArgs[1];
102
- if (!pathArg) {
103
- ctx.print('Usage: /tunnel export <path> --yes');
104
- return;
105
- }
106
- if (!parsed.yes) {
107
- requireYesFlag(ctx, `export remote tunnel review to ${pathArg}`, '/tunnel export <path> --yes');
108
- return;
109
- }
110
- await ctx.executeCommand('remote', ['tunnel', 'export', pathArg, '--yes']);
111
- return;
112
- }
113
- }
114
- ctx.print('Tunnel controls are not available in this runtime.');
115
- },
116
- });
117
-
118
- registry.register({
119
- name: 'bootstrap',
120
- description: 'Dedicated front-door for remote bootstrap bundle export and inspection',
121
- usage: '[export <path> --yes|inspect <path>]',
122
- async handler(args, ctx) {
123
- const parsed = stripYesFlag(args);
124
- const commandArgs = [...parsed.rest];
125
- const sub = (commandArgs[0] ?? '').toLowerCase();
126
- const pathArg = commandArgs[1];
127
- if (!ctx.executeCommand) {
128
- ctx.print('Bootstrap controls are not available in this runtime.');
129
- return;
130
- }
131
- if (sub === 'export' && pathArg) {
132
- if (!parsed.yes) {
133
- requireYesFlag(ctx, `export remote bootstrap bundle to ${pathArg}`, '/bootstrap export <path> --yes');
134
- return;
135
- }
136
- await ctx.executeCommand('remote', ['bootstrap', sub, pathArg, '--yes']);
137
- return;
138
- }
139
- if (sub === 'inspect' && pathArg) {
140
- await ctx.executeCommand('remote', ['bootstrap', sub, pathArg]);
141
- return;
142
- }
143
- ctx.print('Usage: /bootstrap [export <path> --yes|inspect <path>]');
144
- },
145
- });
146
-
147
- registry.register({
148
- name: 'worker-pool',
149
- aliases: ['pool'],
150
- description: 'Dedicated front-door for remote worker pool review flows',
151
- usage: '[list|show <id>]',
152
- async handler(args, ctx) {
153
- const sub = (args[0] ?? 'list').toLowerCase();
154
- if (!ctx.executeCommand) {
155
- ctx.print('Remote worker pool controls are not available in this runtime.');
156
- return;
157
- }
158
- if (sub === 'list') {
159
- await ctx.executeCommand('remote', ['pool', 'list']);
160
- return;
161
- }
162
- if (sub === 'show' && args[1]) {
163
- await ctx.executeCommand('remote', ['pool', 'show', args[1]]);
164
- return;
165
- }
166
- if (sub === 'create' && args[1] && args.length >= 3) {
167
- ctx.print('Remote worker pool mutation is blocked in GoodVibes Agent. Use /worker-pool list or /worker-pool show <id>.');
168
- return;
169
- }
170
- if ((sub === 'assign' || sub === 'unassign') && args[1] && args[2]) {
171
- ctx.print('Remote worker pool mutation is blocked in GoodVibes Agent. Use /worker-pool list or /worker-pool show <id>.');
172
- return;
173
- }
174
- ctx.print('Usage: /worker-pool [list|show <id>]');
175
- },
176
- });
177
-
178
24
  registry.register({
179
25
  name: 'approval',
180
26
  aliases: ['approvals'],
@@ -226,29 +72,6 @@ export function registerExperienceRuntimeCommands(registry: CommandRegistry): vo
226
72
  },
227
73
  });
228
74
 
229
- registry.register({
230
- name: 'memory-review',
231
- aliases: ['knowledge-review'],
232
- description: 'Dedicated front-door for knowledge review queues and task-specific memory injection explanations',
233
- usage: '[queue [limit]|explain <task...> [--scope <path> ...]]',
234
- async handler(args, ctx) {
235
- const sub = (args[0] ?? 'queue').toLowerCase();
236
- if (!ctx.executeCommand) {
237
- ctx.print('Memory review controls are not available in this runtime.');
238
- return;
239
- }
240
- if (sub === 'queue') {
241
- await ctx.executeCommand('knowledge', ['queue', ...(args[1] ? [args[1]] : [])]);
242
- return;
243
- }
244
- if (sub === 'explain' && args.length >= 2) {
245
- await ctx.executeCommand('knowledge', ['explain', ...args.slice(1)]);
246
- return;
247
- }
248
- ctx.print('Usage: /memory-review [queue [limit]|explain <task...> [--scope <path> ...]]');
249
- },
250
- });
251
-
252
75
  registry.register({
253
76
  name: 'voice',
254
77
  description: 'Review voice posture and package portable voice-surface metadata',
@@ -1,8 +1,4 @@
1
- import { estimateConversationTokens } from '@pellux/goodvibes-sdk/platform/core';
2
- import { evaluateSessionMaintenance, formatSessionMaintenanceLines, getGuidanceMode } from '@/runtime/index.ts';
3
- import { dismissGuidance, evaluateContextualGuidance, formatGuidanceItems, resetGuidance } from '@/runtime/index.ts';
4
1
  import type { CommandRegistry } from '../command-registry.ts';
5
- import { requireProviderApi, requireReadModels, requireSessionMemoryStore, requireShellPaths } from './runtime-services.ts';
6
2
 
7
3
  export function registerGuidanceRuntimeCommands(registry: CommandRegistry): void {
8
4
  registry.register({
@@ -37,69 +33,4 @@ export function registerGuidanceRuntimeCommands(registry: CommandRegistry): void
37
33
  ctx.print('Usage: /welcome [open|print]');
38
34
  },
39
35
  });
40
-
41
- registry.register({
42
- name: 'guidance',
43
- description: 'Review contextual operational guidance without interrupting the main conversation flow',
44
- usage: '[review|dismiss <id>|reset [id]]',
45
- async handler(args, ctx) {
46
- const sub = (args[0] ?? 'review').toLowerCase();
47
- const shellPaths = requireShellPaths(ctx);
48
- const guidanceOptions = {
49
- homeDirectory: shellPaths.homeDirectory,
50
- };
51
- if (sub === 'dismiss') {
52
- const id = args[1];
53
- if (!id) {
54
- ctx.print('Usage: /guidance dismiss <id>');
55
- return;
56
- }
57
- dismissGuidance(id, guidanceOptions);
58
- ctx.print(`Dismissed guidance item ${id}.`);
59
- return;
60
- }
61
- if (sub === 'reset') {
62
- resetGuidance(args[1], guidanceOptions);
63
- ctx.print(args[1] ? `Reset guidance item ${args[1]}.` : 'Reset all dismissed guidance items.');
64
- return;
65
- }
66
- if (sub !== 'review') {
67
- ctx.print('Usage: /guidance [review|dismiss <id>|reset [id]]');
68
- return;
69
- }
70
-
71
- const providerApi = requireProviderApi(ctx);
72
- const currentModel = await providerApi.getCurrentModel().catch(() => null); // best-effort: null handled as unknown context window
73
- const llmMessages = ctx.session.conversationManager.getMessagesForLLM();
74
- const readModels = requireReadModels(ctx);
75
- const session = readModels.session.getSnapshot();
76
- const mcp = readModels.mcp.getSnapshot();
77
- const health = readModels.health.getSnapshot();
78
- const marketplace = readModels.marketplace.getSnapshot();
79
- const maintenance = evaluateSessionMaintenance({
80
- configManager: ctx.platform.configManager,
81
- currentTokens: estimateConversationTokens(llmMessages),
82
- contextWindow: currentModel?.contextWindow ?? 0,
83
- messageCount: llmMessages.length,
84
- sessionMemoryCount: requireSessionMemoryStore(ctx).list().length,
85
- session: session.session,
86
- });
87
- const contextual = evaluateContextualGuidance(ctx.platform.configManager, {
88
- pendingApproval: session.pendingApproval,
89
- denialCount: session.denialCount,
90
- authRequiredMcpCount: mcp.servers.filter((server) => server.status === 'auth_required').length,
91
- degradedProviderCount: health.providerProblems.length,
92
- intelligenceUnavailable: false,
93
- recommendations: marketplace.recommendations,
94
- }, maintenance, guidanceOptions);
95
-
96
- ctx.print([
97
- `Guidance Review (${getGuidanceMode(ctx.platform.configManager)})`,
98
- '',
99
- ...formatGuidanceItems(contextual),
100
- '',
101
- ...formatSessionMaintenanceLines(maintenance, maintenance.guidanceMode === 'guided' ? 'guided' : 'minimal'),
102
- ].join('\n'));
103
- },
104
- });
105
36
  }
@@ -6,7 +6,7 @@ import type { SelectionItem } from '../selection-modal.ts';
6
6
  import type { ContentPart } from '@pellux/goodvibes-sdk/platform/providers';
7
7
  import { resolveAndValidatePath } from '@pellux/goodvibes-sdk/platform/utils';
8
8
  import { BUILTIN_SECRET_PROVIDER_SOURCES, describeSecretRef, isSecretRefInput, resolveSecretRef } from '@pellux/goodvibes-sdk/platform/config';
9
- import { openCommandPanel, requireBookmarkManager, requireProviderApi, requireSecretsManager } from './runtime-services.ts';
9
+ import { requireBookmarkManager, requireProviderApi, requireSecretsManager } from './runtime-services.ts';
10
10
  import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
11
11
  import { requireYesFlag, stripYesFlag } from './confirmation.ts';
12
12
 
@@ -50,62 +50,6 @@ function toggleBlocks(typeFilter: string, collapsed: boolean, ctx: CommandContex
50
50
  }
51
51
 
52
52
  export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
53
- registry.register({
54
- name: 'incident-review',
55
- aliases: [],
56
- description: 'Alias for /incident open',
57
- usage: '',
58
- handler(_args, ctx) {
59
- if (ctx.openIncidentPanel) {
60
- ctx.openIncidentPanel();
61
- return;
62
- }
63
- ctx.print('Incident panel is not available in this runtime.');
64
- },
65
- });
66
-
67
- registry.register({
68
- name: 'tools',
69
- aliases: ['t'],
70
- description: 'List available tools and review tool safety/status',
71
- usage: '[review|panel]',
72
- handler(args, ctx) {
73
- const sub = (args[0] ?? '').toLowerCase();
74
- if (sub === 'panel' || sub === 'review') {
75
- try {
76
- openCommandPanel(ctx, 'tools');
77
- } catch {
78
- // Panel registry may be unavailable in lightweight command-only contexts.
79
- }
80
- if (sub === 'review') {
81
- ctx.print([
82
- 'Tool Status',
83
- ' Tools are available for the main Agent conversation.',
84
- ' Read-only actions can run directly; writes, destructive changes, network effects, service changes, and external side effects require explicit user intent or approval.',
85
- ' Recent tool activity and approval posture are available in the tools and approvals views.',
86
- ' Build/fix/review work should be delegated explicitly with /delegate.',
87
- ].join('\n'));
88
- }
89
- return;
90
- }
91
- const tools = ctx.extensions.toolRegistry.list();
92
- if (ctx.openSelection) {
93
- const items: SelectionItem[] = tools.map(t => ({
94
- id: t.definition.name,
95
- label: t.definition.name,
96
- detail: typeof t.definition.description === 'string' ? t.definition.description.slice(0, 50) : '',
97
- }));
98
- ctx.openSelection('Available Tools', items, { allowSearch: true }, (result) => {
99
- if (!result) return;
100
- const tool = tools.find(t2 => t2.definition.name === result.item.id);
101
- if (tool) ctx.print(`Tool: ${tool.definition.name}\n ${tool.definition.description ?? ''}`);
102
- });
103
- return;
104
- }
105
- ctx.print(['Available tools:', ...tools.map(t => ` • ${t.definition.name}`)].join('\n'));
106
- },
107
- });
108
-
109
53
  registry.register({ name: 'expand', description: 'Expand blocks by type', usage: '[all|thinking|tool|code]', argsHint: '[all|thinking|tool|code]', handler(args, ctx) { toggleBlocks(args[0] || 'all', false, ctx); } });
110
54
  registry.register({ name: 'collapse', description: 'Collapse blocks by type', usage: '[all|thinking|tool|code]', argsHint: '[all|thinking|tool|code]', handler(args, ctx) { toggleBlocks(args[0] || 'all', true, ctx); } });
111
55
 
@@ -1,7 +1,7 @@
1
1
  import { dirname, join, resolve } from 'node:path';
2
2
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
3
  import type { CommandContext } from '../command-registry.ts';
4
- import { discoverSkills } from '../../panels/skills-panel.ts';
4
+ import { discoverSkills } from '../../agent/skill-discovery.ts';
5
5
  import { getPluginDirectories } from '../../plugins/loader';
6
6
  import { listBuiltinSubscriptionProviders } from '@pellux/goodvibes-sdk/platform/config';
7
7
  import type { SetupReviewSnapshot } from './local-setup-transfer.ts';
@@ -1,25 +1,11 @@
1
1
  import type { CommandRegistry } from '../command-registry.ts';
2
2
  import type { ProfileData } from '@pellux/goodvibes-sdk/platform/profiles';
3
- import type { ReplaySnapshotInput } from '@/runtime/index.ts';
4
3
  import { logger } from '@pellux/goodvibes-sdk/platform/utils';
5
- import { registerOperatorPanelCommand } from './operator-panel-runtime.ts';
6
- import { requireProfileManager, requireReplayEngine } from './runtime-services.ts';
4
+ import { requireProfileManager } from './runtime-services.ts';
7
5
  import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
8
6
  import { requireYesFlag, stripYesFlag } from './confirmation.ts';
9
7
 
10
- function printOpsMutationBlocked(print: (text: string) => void, target: string): void {
11
- print([
12
- `[Ops] ${target} mutation is blocked in GoodVibes Agent.`,
13
- ' policy: Agent does not control copied local task/agent lifecycle from the operator surface.',
14
- ' normal work: continue in the main conversation.',
15
- ' build/fix/review: use /delegate <task> for explicit GoodVibes TUI handoff.',
16
- ' result: no local task or agent state was changed.',
17
- ].join('\n'));
18
- }
19
-
20
8
  export function registerOperatorRuntimeCommands(registry: CommandRegistry): void {
21
- registerOperatorPanelCommand(registry);
22
-
23
9
  registry.register({
24
10
  name: 'settings',
25
11
  aliases: ['cfg-ui'],
@@ -249,134 +235,4 @@ export function registerOperatorRuntimeCommands(registry: CommandRegistry): void
249
235
  );
250
236
  },
251
237
  });
252
-
253
- registry.register({
254
- name: 'ops',
255
- description: 'Operator runtime status: view Agent posture without local task/agent lifecycle mutations',
256
- usage: '[view]',
257
- argsHint: '[view]',
258
- handler(args, ctx) {
259
- const sub = args[0];
260
-
261
- if (sub === 'view' || sub === undefined) {
262
- if (ctx.openOpsPanel) ctx.openOpsPanel();
263
- else ctx.print('Operator runtime status panel is not available. Enable the operator-control-plane feature flag.');
264
- return;
265
- }
266
-
267
- if (sub === 'task') {
268
- printOpsMutationBlocked(ctx.print, 'Task');
269
- return;
270
- }
271
-
272
- if (sub === 'agent') {
273
- printOpsMutationBlocked(ctx.print, 'Agent');
274
- return;
275
- }
276
-
277
- ctx.print(
278
- 'Usage: /ops <subcommand>\n'
279
- + ' /ops view — open the Ops Control panel (Ctrl+O)\n'
280
- + ' task/agent lifecycle commands are blocked in Agent; use /delegate for explicit build handoff'
281
- );
282
- },
283
- });
284
-
285
- registry.register({
286
- name: 'forensics',
287
- aliases: ['foren'],
288
- description: 'Failure Forensics: view, inspect, and export auto-classified failure reports',
289
- usage: '[latest | show <id> | export <id>]',
290
- argsHint: '[latest|show|export]',
291
- handler(args, ctx) {
292
- const sub = args[0];
293
- if (sub === undefined || sub === 'view') {
294
- if (ctx.openForensicsPanel) ctx.openForensicsPanel();
295
- else ctx.print('Forensics panel is not available.');
296
- return;
297
- }
298
- if (sub === 'latest') {
299
- if (!ctx.extensions.forensicsRegistry) {
300
- ctx.print('[Forensics] Registry not active.');
301
- return;
302
- }
303
- const report = ctx.extensions.forensicsRegistry.latest();
304
- if (!report) {
305
- ctx.print('[Forensics] No failure reports recorded this session.');
306
- return;
307
- }
308
- const lines: string[] = [
309
- `[Forensics] Latest failure report (id: ${report.id})`,
310
- ` Time: ${new Date(report.generatedAt).toISOString()}`,
311
- ` Classification: ${report.classification}`,
312
- ` Summary: ${report.summary}`,
313
- ];
314
- if (report.errorMessage) lines.push(` Error: ${report.errorMessage}`);
315
- if (report.stopReason) lines.push(` Stop reason: ${report.stopReason}`);
316
- if (report.taskId) lines.push(` Task ID: ${report.taskId}`);
317
- if (report.turnId) lines.push(` Turn ID: ${report.turnId}`);
318
- if (report.causalChain.length > 0) {
319
- lines.push(' Causal chain:');
320
- for (const entry of report.causalChain) {
321
- const marker = entry.isRootCause ? ' ● ' : ' · ';
322
- lines.push(` ${marker}${entry.description}`);
323
- }
324
- }
325
- if (report.jumpLinks.length > 0) {
326
- lines.push(' Jump links:');
327
- for (const link of report.jumpLinks) {
328
- lines.push(` [${link.kind}] ${link.label} → ${link.target}${link.args ? ` (${link.args})` : ''}`);
329
- }
330
- }
331
- lines.push(` Use "/forensics show ${report.id}" for full JSON.`);
332
- ctx.print(lines.join('\n'));
333
- return;
334
- }
335
- if (sub === 'show') {
336
- const id = args[1];
337
- if (!id) {
338
- ctx.print('Usage: /forensics show <id>');
339
- return;
340
- }
341
- if (!ctx.extensions.forensicsRegistry) {
342
- ctx.print('[Forensics] Registry not active.');
343
- return;
344
- }
345
- const json = ctx.extensions.forensicsRegistry.exportAsJson(id);
346
- if (!json) {
347
- ctx.print(`[Forensics] No report found with id "${id}". Use /forensics latest to see the most recent.`);
348
- return;
349
- }
350
- ctx.print(json);
351
- return;
352
- }
353
- if (sub === 'export') {
354
- const id = args[1];
355
- if (!id) {
356
- ctx.print('Usage: /forensics export <id>');
357
- return;
358
- }
359
- if (!ctx.extensions.forensicsRegistry) {
360
- ctx.print('[Forensics] Registry not active.');
361
- return;
362
- }
363
- const json = ctx.extensions.forensicsRegistry.exportBundleAsJson(id, {
364
- replaySnapshot: requireReplayEngine(ctx).getSnapshot() as ReplaySnapshotInput,
365
- });
366
- if (!json) {
367
- ctx.print(`[Forensics] No report found with id "${id}".`);
368
- return;
369
- }
370
- ctx.print(`[Forensics] Incident bundle ${id}:\n${json}`);
371
- return;
372
- }
373
- ctx.print(
374
- 'Usage: /forensics <subcommand>\n'
375
- + ' /forensics — open the Forensics panel\n'
376
- + ' /forensics latest — print the most recent failure report summary\n'
377
- + ' /forensics show <id> — show full JSON for a specific report\n'
378
- + ' /forensics export <id> — export incident bundle JSON to the conversation'
379
- );
380
- },
381
- });
382
238
  }