@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.
- package/CHANGELOG.md +12 -0
- package/README.md +3 -3
- package/docs/README.md +2 -2
- package/docs/getting-started.md +1 -1
- package/docs/runtime-connection.md +37 -0
- package/package.json +43 -2
- package/src/agent/skill-discovery.ts +119 -0
- package/src/cli/config-overrides.ts +1 -5
- package/src/cli/entrypoint.ts +0 -6
- package/src/cli/help.ts +0 -43
- package/src/cli/index.ts +0 -2
- package/src/cli/management-commands.ts +1 -109
- package/src/cli/management.ts +1 -32
- package/src/cli/package-verification.ts +12 -4
- package/src/cli/parser.ts +0 -16
- package/src/cli/status.ts +1 -1
- package/src/cli/types.ts +0 -8
- package/src/input/commands/delegation-runtime.ts +0 -8
- package/src/input/commands/experience-runtime.ts +0 -177
- package/src/input/commands/guidance-runtime.ts +0 -69
- package/src/input/commands/local-runtime.ts +1 -57
- package/src/input/commands/local-setup-review.ts +1 -1
- package/src/input/commands/operator-runtime.ts +1 -145
- package/src/input/commands/platform-access-runtime.ts +2 -195
- package/src/input/commands/product-runtime.ts +0 -116
- package/src/input/commands/security-runtime.ts +88 -0
- package/src/input/commands/session-content.ts +0 -97
- package/src/input/commands/shell-core.ts +0 -13
- package/src/input/commands.ts +2 -95
- package/src/panels/builtin/operations.ts +3 -184
- package/src/panels/confirm-state.ts +1 -1
- package/src/panels/index.ts +0 -11
- package/src/version.ts +1 -1
- package/docs/deployment-and-services.md +0 -52
- package/src/cli/service-command.ts +0 -26
- package/src/cli/surface-command.ts +0 -247
- package/src/input/commands/branch-runtime.ts +0 -72
- package/src/input/commands/control-room-runtime.ts +0 -234
- package/src/input/commands/discovery-runtime.ts +0 -61
- package/src/input/commands/hooks-runtime.ts +0 -207
- package/src/input/commands/incident-runtime.ts +0 -106
- package/src/input/commands/integration-runtime.ts +0 -437
- package/src/input/commands/local-setup.ts +0 -288
- package/src/input/commands/managed-runtime.ts +0 -240
- package/src/input/commands/marketplace-runtime.ts +0 -305
- package/src/input/commands/memory-product-runtime.ts +0 -148
- package/src/input/commands/operator-panel-runtime.ts +0 -146
- package/src/input/commands/platform-services-runtime.ts +0 -271
- package/src/input/commands/profile-sync-runtime.ts +0 -110
- package/src/input/commands/provider.ts +0 -363
- package/src/input/commands/remote-runtime-pool.ts +0 -89
- package/src/input/commands/remote-runtime-setup.ts +0 -226
- package/src/input/commands/remote-runtime.ts +0 -432
- package/src/input/commands/replay-runtime.ts +0 -25
- package/src/input/commands/services-runtime.ts +0 -220
- package/src/input/commands/settings-sync-runtime.ts +0 -197
- package/src/input/commands/share-runtime.ts +0 -127
- package/src/input/commands/skills-runtime.ts +0 -226
- package/src/input/commands/teleport-runtime.ts +0 -68
- package/src/panels/cockpit-panel.ts +0 -183
- package/src/panels/communication-panel.ts +0 -153
- package/src/panels/control-plane-panel.ts +0 -211
- package/src/panels/forensics-panel.ts +0 -364
- package/src/panels/hooks-panel.ts +0 -239
- package/src/panels/incident-review-panel.ts +0 -197
- package/src/panels/marketplace-panel.ts +0 -212
- package/src/panels/ops-control-panel.ts +0 -150
- package/src/panels/ops-strategy-panel.ts +0 -235
- package/src/panels/orchestration-panel.ts +0 -272
- package/src/panels/plugins-panel.ts +0 -178
- package/src/panels/remote-panel.ts +0 -449
- package/src/panels/routes-panel.ts +0 -178
- package/src/panels/services-panel.ts +0 -231
- package/src/panels/settings-sync-panel.ts +0 -120
- package/src/panels/skills-panel.ts +0 -431
- package/src/panels/watchers-panel.ts +0 -193
- package/src/verification/live-verifier.ts +0 -588
- 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
|
|
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 {
|
|
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 '../../
|
|
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 {
|
|
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
|
}
|