@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.
- package/CHANGELOG.md +6 -0
- package/package.json +42 -1
- package/src/agent/skill-discovery.ts +119 -0
- 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/index.ts +0 -11
- package/src/version.ts +1 -1
- 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/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.
|
|
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 {
|
|
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';
|