@pellux/goodvibes-agent 0.1.70 → 0.1.71

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 (60) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +42 -1
  3. package/src/agent/skill-discovery.ts +119 -0
  4. package/src/input/commands/delegation-runtime.ts +0 -8
  5. package/src/input/commands/experience-runtime.ts +0 -177
  6. package/src/input/commands/guidance-runtime.ts +0 -69
  7. package/src/input/commands/local-runtime.ts +1 -57
  8. package/src/input/commands/local-setup-review.ts +1 -1
  9. package/src/input/commands/operator-runtime.ts +1 -145
  10. package/src/input/commands/platform-access-runtime.ts +2 -195
  11. package/src/input/commands/product-runtime.ts +0 -116
  12. package/src/input/commands/security-runtime.ts +88 -0
  13. package/src/input/commands/session-content.ts +0 -97
  14. package/src/input/commands/shell-core.ts +0 -13
  15. package/src/input/commands.ts +2 -95
  16. package/src/panels/builtin/operations.ts +3 -184
  17. package/src/panels/index.ts +0 -11
  18. package/src/version.ts +1 -1
  19. package/src/input/commands/branch-runtime.ts +0 -72
  20. package/src/input/commands/control-room-runtime.ts +0 -234
  21. package/src/input/commands/discovery-runtime.ts +0 -61
  22. package/src/input/commands/hooks-runtime.ts +0 -207
  23. package/src/input/commands/incident-runtime.ts +0 -106
  24. package/src/input/commands/integration-runtime.ts +0 -437
  25. package/src/input/commands/local-setup.ts +0 -288
  26. package/src/input/commands/managed-runtime.ts +0 -240
  27. package/src/input/commands/marketplace-runtime.ts +0 -305
  28. package/src/input/commands/memory-product-runtime.ts +0 -148
  29. package/src/input/commands/operator-panel-runtime.ts +0 -146
  30. package/src/input/commands/platform-services-runtime.ts +0 -271
  31. package/src/input/commands/profile-sync-runtime.ts +0 -110
  32. package/src/input/commands/provider.ts +0 -363
  33. package/src/input/commands/remote-runtime-pool.ts +0 -89
  34. package/src/input/commands/remote-runtime-setup.ts +0 -226
  35. package/src/input/commands/remote-runtime.ts +0 -432
  36. package/src/input/commands/replay-runtime.ts +0 -25
  37. package/src/input/commands/services-runtime.ts +0 -220
  38. package/src/input/commands/settings-sync-runtime.ts +0 -197
  39. package/src/input/commands/share-runtime.ts +0 -127
  40. package/src/input/commands/skills-runtime.ts +0 -226
  41. package/src/input/commands/teleport-runtime.ts +0 -68
  42. package/src/panels/cockpit-panel.ts +0 -183
  43. package/src/panels/communication-panel.ts +0 -153
  44. package/src/panels/control-plane-panel.ts +0 -211
  45. package/src/panels/forensics-panel.ts +0 -364
  46. package/src/panels/hooks-panel.ts +0 -239
  47. package/src/panels/incident-review-panel.ts +0 -197
  48. package/src/panels/marketplace-panel.ts +0 -212
  49. package/src/panels/ops-control-panel.ts +0 -150
  50. package/src/panels/ops-strategy-panel.ts +0 -235
  51. package/src/panels/orchestration-panel.ts +0 -272
  52. package/src/panels/plugins-panel.ts +0 -178
  53. package/src/panels/remote-panel.ts +0 -449
  54. package/src/panels/routes-panel.ts +0 -178
  55. package/src/panels/services-panel.ts +0 -231
  56. package/src/panels/settings-sync-panel.ts +0 -120
  57. package/src/panels/skills-panel.ts +0 -431
  58. package/src/panels/watchers-panel.ts +0 -193
  59. package/src/verification/live-verifier.ts +0 -588
  60. package/src/verification/verification-ledger.ts +0 -239
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to GoodVibes Agent will be recorded here.
4
4
 
5
+ ## 0.1.71 - 2026-05-31
6
+
7
+ - Stopped importing copied TUI slash-command modules that do not belong to the Agent product surface.
8
+ - Trimmed the built-in panel registry to Agent-relevant approval, automation, auth, provider, security, task, and policy views.
9
+ - Reduced package contents so hidden copied command and panel modules are not shipped with the installed Agent TUI.
10
+
5
11
  ## 0.1.70 - 2026-05-31
6
12
 
7
13
  - Removed copied TUI coding, runtime lifecycle, and developer-maintenance slash commands from the visible Agent command registry.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "0.1.70",
3
+ "version": "0.1.71",
4
4
  "private": false,
5
5
  "description": "GoodVibes personal operator assistant TUI with a proactive Agent product brain, isolated Agent Knowledge, local profiles, routines, skills, personas, and explicit build delegation.",
6
6
  "type": "module",
@@ -16,11 +16,52 @@
16
16
  "!src/test",
17
17
  "!src/**/*.test.ts",
18
18
  "!src/**/__tests__",
19
+ "!src/input/commands/branch-runtime.ts",
20
+ "!src/input/commands/control-room-runtime.ts",
21
+ "!src/input/commands/discovery-runtime.ts",
22
+ "!src/input/commands/hooks-runtime.ts",
23
+ "!src/input/commands/incident-runtime.ts",
24
+ "!src/input/commands/integration-runtime.ts",
25
+ "!src/input/commands/local-setup.ts",
26
+ "!src/input/commands/managed-runtime.ts",
27
+ "!src/input/commands/marketplace-runtime.ts",
28
+ "!src/input/commands/memory-product-runtime.ts",
29
+ "!src/input/commands/operator-panel-runtime.ts",
30
+ "!src/input/commands/platform-services-runtime.ts",
31
+ "!src/input/commands/profile-sync-runtime.ts",
32
+ "!src/input/commands/provider.ts",
33
+ "!src/input/commands/remote-runtime.ts",
34
+ "!src/input/commands/remote-runtime-pool.ts",
35
+ "!src/input/commands/remote-runtime-setup.ts",
36
+ "!src/input/commands/replay-runtime.ts",
37
+ "!src/input/commands/services-runtime.ts",
38
+ "!src/input/commands/settings-sync-runtime.ts",
39
+ "!src/input/commands/share-runtime.ts",
40
+ "!src/input/commands/skills-runtime.ts",
41
+ "!src/input/commands/teleport-runtime.ts",
42
+ "!src/panels/cockpit-panel.ts",
43
+ "!src/panels/communication-panel.ts",
44
+ "!src/panels/control-plane-panel.ts",
19
45
  "!src/panels/diff-panel.ts",
46
+ "!src/panels/forensics-panel.ts",
20
47
  "!src/panels/git-panel.ts",
48
+ "!src/panels/hooks-panel.ts",
49
+ "!src/panels/incident-review-panel.ts",
50
+ "!src/panels/marketplace-panel.ts",
51
+ "!src/panels/ops-control-panel.ts",
52
+ "!src/panels/ops-strategy-panel.ts",
53
+ "!src/panels/orchestration-panel.ts",
54
+ "!src/panels/plugins-panel.ts",
55
+ "!src/panels/remote-panel.ts",
56
+ "!src/panels/routes-panel.ts",
21
57
  "!src/panels/sandbox-panel.ts",
58
+ "!src/panels/services-panel.ts",
59
+ "!src/panels/settings-sync-panel.ts",
60
+ "!src/panels/skills-panel.ts",
61
+ "!src/panels/watchers-panel.ts",
22
62
  "!src/panels/worktree-panel.ts",
23
63
  "!src/panels/wrfc-panel.ts",
64
+ "!src/verification",
24
65
  "tsconfig.json",
25
66
  "README.md",
26
67
  "CHANGELOG.md",
@@ -0,0 +1,119 @@
1
+ import { promises as fsPromises } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import type { ShellPathService } from '@/runtime/index.ts';
4
+ import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
5
+
6
+ export type SkillOrigin = 'project-local' | 'global' | 'custom';
7
+
8
+ export interface SkillRecord {
9
+ name: string;
10
+ description: string;
11
+ path: string;
12
+ origin: SkillOrigin;
13
+ dependencies: string[];
14
+ includes: string[];
15
+ frontmatter: Record<string, string>;
16
+ }
17
+
18
+ function parseFrontmatter(content: string): Record<string, string> {
19
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
20
+ if (!match) return {};
21
+ const result: Record<string, string> = {};
22
+ for (const line of match[1].split('\n')) {
23
+ const [key, ...rest] = line.split(':');
24
+ if (key && rest.length > 0) {
25
+ result[key.trim()] = rest.join(':').trim();
26
+ }
27
+ }
28
+ return result;
29
+ }
30
+
31
+ function getSkillDirectories(cwd: string, homeDir: string): Array<{ root: string; origin: SkillOrigin }> {
32
+ return [
33
+ { root: join(cwd, '.goodvibes', 'skills'), origin: 'project-local' },
34
+ { root: join(cwd, '.goodvibes', GOODVIBES_AGENT_SURFACE_ROOT, 'skills'), origin: 'project-local' },
35
+ { root: join(homeDir, '.goodvibes', 'skills'), origin: 'global' },
36
+ { root: join(homeDir, '.goodvibes', GOODVIBES_AGENT_SURFACE_ROOT, 'skills'), origin: 'global' },
37
+ ];
38
+ }
39
+
40
+ async function readSkillFile(path: string, origin: SkillOrigin): Promise<SkillRecord | null> {
41
+ let content = '';
42
+ try {
43
+ content = await fsPromises.readFile(path, 'utf-8');
44
+ } catch {
45
+ return null;
46
+ }
47
+
48
+ const frontmatter = parseFrontmatter(content);
49
+ const body = content.replace(/^---\n[\s\S]*?\n---\n?/, '');
50
+ const name = frontmatter.name ?? path.split(/[\\/]/).pop()?.replace(/\.md$/, '') ?? 'skill';
51
+ const description = frontmatter.description ?? frontmatter.summary ?? '';
52
+ const dependencies = frontmatter.depends_on
53
+ ? frontmatter.depends_on.split(',').map((item) => item.trim()).filter(Boolean)
54
+ : [];
55
+ const includes: string[] = [];
56
+ const includeRegex = /^@([\w/-]+)/gm;
57
+ let match: RegExpExecArray | null;
58
+ while ((match = includeRegex.exec(body)) !== null) {
59
+ includes.push(match[1]);
60
+ }
61
+
62
+ return {
63
+ name,
64
+ description,
65
+ path,
66
+ origin,
67
+ dependencies,
68
+ includes,
69
+ frontmatter,
70
+ };
71
+ }
72
+
73
+ async function scanSkillDirectory(root: string, origin: SkillOrigin): Promise<SkillRecord[]> {
74
+ let entries: string[] = [];
75
+ try {
76
+ entries = await fsPromises.readdir(root);
77
+ } catch {
78
+ return [];
79
+ }
80
+
81
+ const records: SkillRecord[] = [];
82
+ for (const entry of entries.sort((a, b) => a.localeCompare(b))) {
83
+ if (entry.endsWith('.md')) {
84
+ const record = await readSkillFile(join(root, entry), origin);
85
+ if (record) records.push(record);
86
+ continue;
87
+ }
88
+
89
+ const markerPath = join(root, entry, 'SKILL.md');
90
+ const record = await readSkillFile(markerPath, origin);
91
+ if (record) records.push(record);
92
+ }
93
+
94
+ return records;
95
+ }
96
+
97
+ export async function discoverSkills(shellPaths: Pick<ShellPathService, 'workingDirectory' | 'homeDirectory'>): Promise<SkillRecord[]> {
98
+ const cwd = shellPaths.workingDirectory;
99
+ const homeDir = shellPaths.homeDirectory;
100
+ const seen = new Set<string>();
101
+ const records: SkillRecord[] = [];
102
+
103
+ for (const { root, origin } of getSkillDirectories(cwd, homeDir)) {
104
+ for (const record of await scanSkillDirectory(root, origin)) {
105
+ if (seen.has(record.name.toLowerCase())) continue;
106
+ seen.add(record.name.toLowerCase());
107
+ records.push(record);
108
+ }
109
+ }
110
+
111
+ return records.sort((a, b) => {
112
+ const originRank = a.origin === b.origin
113
+ ? 0
114
+ : a.origin === 'project-local'
115
+ ? -1
116
+ : 1;
117
+ return originRank || a.name.localeCompare(b.name);
118
+ });
119
+ }
@@ -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';