@pellux/goodvibes-agent 0.1.91 → 0.1.92
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 +4 -0
- package/package.json +1 -1
- package/src/cli/bundle-command.ts +3 -3
- package/src/cli/help.ts +1 -1
- package/src/cli/management-commands.ts +19 -17
- package/src/cli/management.ts +8 -6
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.92",
|
|
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",
|
|
@@ -125,7 +125,7 @@ export async function handleBundleCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
125
125
|
|
|
126
126
|
if (sub === 'inspect') {
|
|
127
127
|
const path = rest[0];
|
|
128
|
-
if (!path) return { output:
|
|
128
|
+
if (!path) return { output: `Usage: ${runtime.cli.binary} bundle inspect <path>`, exitCode: 2 };
|
|
129
129
|
const sourcePath = shellPaths.resolveWorkspacePath(path);
|
|
130
130
|
const parsed = readJsonFile(sourcePath);
|
|
131
131
|
if (!parsed.ok) return { output: `Invalid bundle JSON: ${parsed.error}`, exitCode: 1 };
|
|
@@ -199,7 +199,7 @@ export async function handleBundleCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
199
199
|
|
|
200
200
|
if (sub === 'import') {
|
|
201
201
|
const path = rest[0];
|
|
202
|
-
if (!path) return { output:
|
|
202
|
+
if (!path) return { output: `Usage: ${runtime.cli.binary} bundle import <path>`, exitCode: 2 };
|
|
203
203
|
const sourcePath = shellPaths.resolveWorkspacePath(path);
|
|
204
204
|
const parsed = readJsonFile(sourcePath);
|
|
205
205
|
if (!parsed.ok) return { output: `Invalid bundle JSON: ${parsed.error}`, exitCode: 1 };
|
|
@@ -223,5 +223,5 @@ export async function handleBundleCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
223
223
|
};
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
return { output:
|
|
226
|
+
return { output: `Usage: ${runtime.cli.binary} bundle export [path]|inspect <path>|import <path>`, exitCode: 2 };
|
|
227
227
|
}
|
package/src/cli/help.ts
CHANGED
|
@@ -222,7 +222,7 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
222
222
|
],
|
|
223
223
|
},
|
|
224
224
|
subscription: {
|
|
225
|
-
usage: ['subscription list', 'subscription providers', 'subscription inspect <provider>', 'subscription login <provider> start
|
|
225
|
+
usage: ['subscription list', 'subscription providers', 'subscription inspect <provider>', 'subscription login <provider> start [--open]', 'subscription login <provider> finish <code-or-url>', 'subscription logout <provider>'],
|
|
226
226
|
summary: 'Manage OAuth/subscription-backed provider sessions such as OpenAI subscription access.',
|
|
227
227
|
examples: ['subscription providers', 'subscription login openai start --open', 'subscription inspect openai'],
|
|
228
228
|
},
|
|
@@ -14,6 +14,7 @@ import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../config/surface.ts';
|
|
|
14
14
|
|
|
15
15
|
export async function renderSubscriptions(runtime: CliCommandRuntime): Promise<string> {
|
|
16
16
|
return await withRuntimeServices(runtime, async (services) => {
|
|
17
|
+
const binary = runtime.cli.binary;
|
|
17
18
|
const [sub = 'list', ...rest] = runtime.cli.commandArgs;
|
|
18
19
|
const subscriptions = services.subscriptionManager.list();
|
|
19
20
|
const pending = services.subscriptionManager.listPending();
|
|
@@ -26,7 +27,7 @@ export async function renderSubscriptions(runtime: CliCommandRuntime): Promise<s
|
|
|
26
27
|
}
|
|
27
28
|
if (sub === 'inspect' || sub === 'show') {
|
|
28
29
|
const provider = rest[0];
|
|
29
|
-
if (!provider) return
|
|
30
|
+
if (!provider) return `Usage: ${binary} subscription inspect <provider>`;
|
|
30
31
|
const resolved = getSubscriptionProviderConfig(provider, services.serviceRegistry.get(provider));
|
|
31
32
|
if (!resolved && !services.subscriptionManager.get(provider) && !services.subscriptionManager.getPending(provider)) {
|
|
32
33
|
return `No stored or available subscription provider named ${provider}.`;
|
|
@@ -59,7 +60,7 @@ export async function renderSubscriptions(runtime: CliCommandRuntime): Promise<s
|
|
|
59
60
|
if (sub === 'login' || sub === 'start') {
|
|
60
61
|
const provider = sub === 'start' ? rest[0] : rest[0];
|
|
61
62
|
const mode = sub === 'start' ? 'start' : rest[1]?.toLowerCase();
|
|
62
|
-
if (!provider || mode !== 'start') return
|
|
63
|
+
if (!provider || mode !== 'start') return `Usage: ${binary} subscription login <provider> start [--open]`;
|
|
63
64
|
const resolved = getSubscriptionProviderConfig(provider, services.serviceRegistry.get(provider));
|
|
64
65
|
if (!resolved) return `No subscription provider found: ${provider}`;
|
|
65
66
|
if (provider === 'openai' && resolved.source === 'builtin') {
|
|
@@ -78,7 +79,7 @@ export async function renderSubscriptions(runtime: CliCommandRuntime): Promise<s
|
|
|
78
79
|
` state: ${started.state}`,
|
|
79
80
|
` redirectUri: ${started.redirectUri}`,
|
|
80
81
|
...(openResult ? [` open: ${openResult}`] : []),
|
|
81
|
-
` next:
|
|
82
|
+
` next: ${binary} subscription login ${provider} finish <code-or-url>`,
|
|
82
83
|
' authorizationUrl:',
|
|
83
84
|
` ${started.authorizationUrl}`,
|
|
84
85
|
].join('\n');
|
|
@@ -91,7 +92,7 @@ export async function renderSubscriptions(runtime: CliCommandRuntime): Promise<s
|
|
|
91
92
|
` state: ${started.pending.state}`,
|
|
92
93
|
` redirectUri: ${started.pending.redirectUri}`,
|
|
93
94
|
...(openResult ? [` open: ${openResult}`] : []),
|
|
94
|
-
` next:
|
|
95
|
+
` next: ${binary} subscription login ${provider} finish <code-or-url>`,
|
|
95
96
|
' authorizationUrl:',
|
|
96
97
|
` ${started.authorizationUrl}`,
|
|
97
98
|
].join('\n');
|
|
@@ -99,7 +100,7 @@ export async function renderSubscriptions(runtime: CliCommandRuntime): Promise<s
|
|
|
99
100
|
if (sub === 'finish' || (sub === 'login' && rest[1]?.toLowerCase() === 'finish')) {
|
|
100
101
|
const provider = sub === 'finish' ? rest[0] : rest[0];
|
|
101
102
|
const codeInput = sub === 'finish' ? rest[1] : rest[2];
|
|
102
|
-
if (!provider || !codeInput) return
|
|
103
|
+
if (!provider || !codeInput) return `Usage: ${binary} subscription login <provider> finish <code-or-url>`;
|
|
103
104
|
const resolved = getSubscriptionProviderConfig(provider, services.serviceRegistry.get(provider));
|
|
104
105
|
if (!resolved) return `No subscription provider found: ${provider}`;
|
|
105
106
|
const code = extractAuthorizationCode(codeInput);
|
|
@@ -127,7 +128,7 @@ export async function renderSubscriptions(runtime: CliCommandRuntime): Promise<s
|
|
|
127
128
|
}
|
|
128
129
|
if (sub === 'refresh') {
|
|
129
130
|
const provider = rest[0];
|
|
130
|
-
if (!provider) return
|
|
131
|
+
if (!provider) return `Usage: ${binary} subscription refresh <provider>`;
|
|
131
132
|
const resolved = getSubscriptionProviderConfig(provider, services.serviceRegistry.get(provider));
|
|
132
133
|
if (!resolved) return `No subscription provider found: ${provider}`;
|
|
133
134
|
const record = await services.subscriptionManager.refreshOAuthToken(provider, resolved.oauth);
|
|
@@ -135,12 +136,12 @@ export async function renderSubscriptions(runtime: CliCommandRuntime): Promise<s
|
|
|
135
136
|
}
|
|
136
137
|
if (sub === 'logout' || sub === 'remove') {
|
|
137
138
|
const provider = rest[0];
|
|
138
|
-
if (!provider) return
|
|
139
|
+
if (!provider) return `Usage: ${binary} subscription logout <provider>`;
|
|
139
140
|
const removed = services.subscriptionManager.logout(provider);
|
|
140
141
|
return removed ? `Subscription removed: ${provider}` : `No stored subscription session existed for ${provider}.`;
|
|
141
142
|
}
|
|
142
143
|
if (sub !== 'list' && sub !== 'status' && sub !== 'review') {
|
|
143
|
-
return
|
|
144
|
+
return `Usage: ${binary} subscription [list|providers|inspect <provider>|login <provider> start|finish <code-or-url>|refresh <provider>|logout <provider>]`;
|
|
144
145
|
}
|
|
145
146
|
const value = {
|
|
146
147
|
subscriptions: subscriptions.map((sub) => ({
|
|
@@ -180,7 +181,7 @@ export async function handleSecrets(runtime: CliCommandRuntime): Promise<string>
|
|
|
180
181
|
if (sub === 'test') {
|
|
181
182
|
const ref = rest.join(' ').trim();
|
|
182
183
|
if (!ref || !ref.startsWith('goodvibes://secrets/') || !isSecretRefInput(ref)) {
|
|
183
|
-
return
|
|
184
|
+
return `Usage: ${runtime.cli.binary} secrets test goodvibes://secrets/<source>/...`;
|
|
184
185
|
}
|
|
185
186
|
const resolved = await resolveSecretRef(ref, { resolveLocalSecret: (key) => secrets.get(key) });
|
|
186
187
|
const value = { ref: describeSecretRef(ref), resolved: Boolean(resolved.value) };
|
|
@@ -191,7 +192,7 @@ export async function handleSecrets(runtime: CliCommandRuntime): Promise<string>
|
|
|
191
192
|
const values = rest.filter((arg) => !arg.startsWith('--'));
|
|
192
193
|
const [key, ...rawValueParts] = values;
|
|
193
194
|
const value = rawValueParts.join(' ');
|
|
194
|
-
if (!key || !value) return `Usage:
|
|
195
|
+
if (!key || !value) return `Usage: ${runtime.cli.binary} secrets ${sub} <KEY> <value> [--user|--project] [--secure|--plaintext]`;
|
|
195
196
|
if (sub === 'link' && (!value.startsWith('goodvibes://secrets/') || !isSecretRefInput(value))) {
|
|
196
197
|
return 'Invalid secret reference. Use goodvibes://secrets/<source>/...';
|
|
197
198
|
}
|
|
@@ -203,7 +204,7 @@ export async function handleSecrets(runtime: CliCommandRuntime): Promise<string>
|
|
|
203
204
|
}
|
|
204
205
|
if (sub === 'delete') {
|
|
205
206
|
const key = rest.find((arg) => !arg.startsWith('--'));
|
|
206
|
-
if (!key) return
|
|
207
|
+
if (!key) return `Usage: ${runtime.cli.binary} secrets delete <KEY> [--user|--project] [--secure|--plaintext]`;
|
|
207
208
|
const flags = new Set(rest.filter((arg) => arg.startsWith('--')));
|
|
208
209
|
await secrets.delete(key, {
|
|
209
210
|
scope: flags.has('--user') ? 'user' : flags.has('--project') ? 'project' : undefined,
|
|
@@ -226,6 +227,7 @@ export async function handleSecrets(runtime: CliCommandRuntime): Promise<string>
|
|
|
226
227
|
|
|
227
228
|
export async function handleSessions(runtime: CliCommandRuntime): Promise<string | null> {
|
|
228
229
|
return await withRuntimeServices(runtime, (services) => {
|
|
230
|
+
const binary = runtime.cli.binary;
|
|
229
231
|
const [sub = 'list', ...rest] = runtime.cli.commandArgs;
|
|
230
232
|
const sessions = services.sessionManager.list();
|
|
231
233
|
if (sub === 'list') {
|
|
@@ -237,7 +239,7 @@ export async function handleSessions(runtime: CliCommandRuntime): Promise<string
|
|
|
237
239
|
}
|
|
238
240
|
if (sub === 'show' || sub === 'info') {
|
|
239
241
|
const target = rest.join(' ').trim();
|
|
240
|
-
if (!target) return
|
|
242
|
+
if (!target) return `Usage: ${binary} sessions show <id|name>`;
|
|
241
243
|
const found = sessions.find((session) => session.name === target || session.name.startsWith(target) || session.title.toLowerCase() === target.toLowerCase());
|
|
242
244
|
if (!found) return `Session not found: ${target}`;
|
|
243
245
|
return formatJsonOrText(runtime.cli)(found, [
|
|
@@ -252,7 +254,7 @@ export async function handleSessions(runtime: CliCommandRuntime): Promise<string
|
|
|
252
254
|
if (sub === 'export') {
|
|
253
255
|
const target = rest[0];
|
|
254
256
|
const outputPath = rest[1];
|
|
255
|
-
if (!target) return
|
|
257
|
+
if (!target) return `Usage: ${binary} sessions export <id|name> [path]`;
|
|
256
258
|
const found = sessions.find((session) => session.name === target || session.name.startsWith(target) || session.title.toLowerCase() === target.toLowerCase());
|
|
257
259
|
if (!found) return `Session not found: ${target}`;
|
|
258
260
|
const data = services.sessionManager.load(found.name);
|
|
@@ -267,9 +269,9 @@ export async function handleSessions(runtime: CliCommandRuntime): Promise<string
|
|
|
267
269
|
}
|
|
268
270
|
if (sub === 'resume') {
|
|
269
271
|
const target = rest.join(' ').trim();
|
|
270
|
-
return target ? null :
|
|
272
|
+
return target ? null : `Usage: ${binary} sessions resume <id|name>`;
|
|
271
273
|
}
|
|
272
|
-
return
|
|
274
|
+
return `Usage: ${binary} sessions list|show <id>|export <id> [path]|resume <id>`;
|
|
273
275
|
});
|
|
274
276
|
}
|
|
275
277
|
|
|
@@ -291,11 +293,11 @@ export async function handleTasks(runtime: CliCommandRuntime): Promise<string> {
|
|
|
291
293
|
: ['GoodVibes tasks', ...tasks.map((task) => ` ${task.id} ${task.status} ${task.kind} ${task.title}`)].join('\n');
|
|
292
294
|
}
|
|
293
295
|
if (sub === 'show') {
|
|
294
|
-
if (!rest[0]) return
|
|
296
|
+
if (!rest[0]) return `Usage: ${runtime.cli.binary} tasks show <taskId>`;
|
|
295
297
|
const task = tasks.find((candidate) => candidate.id === rest[0]);
|
|
296
298
|
return task ? JSON.stringify(task, null, 2) : `Unknown task: ${rest[0] ?? ''}`;
|
|
297
299
|
}
|
|
298
|
-
return
|
|
300
|
+
return `Usage: ${runtime.cli.binary} tasks list|show <taskId>`;
|
|
299
301
|
});
|
|
300
302
|
}
|
|
301
303
|
|
package/src/cli/management.ts
CHANGED
|
@@ -244,7 +244,7 @@ export function readAuthPaths(runtime: CliCommandRuntime) {
|
|
|
244
244
|
export async function runNonInteractiveAgent(runtime: CliCommandRuntime): Promise<number> {
|
|
245
245
|
const prompt = runtime.cli.flags.prompt ?? runtime.cli.positionals.join(' ').trim();
|
|
246
246
|
if (!prompt) {
|
|
247
|
-
console.error(
|
|
247
|
+
console.error(`Usage: ${runtime.cli.binary} run|exec [prompt]`);
|
|
248
248
|
return 2;
|
|
249
249
|
}
|
|
250
250
|
|
|
@@ -329,6 +329,7 @@ export async function runNonInteractiveAgent(runtime: CliCommandRuntime): Promis
|
|
|
329
329
|
|
|
330
330
|
async function renderProviders(runtime: CliCommandRuntime): Promise<string> {
|
|
331
331
|
return await withRuntimeServices(runtime, async (services) => {
|
|
332
|
+
const binary = runtime.cli.binary;
|
|
332
333
|
const [sub = 'list', ...rest] = runtime.cli.commandArgs;
|
|
333
334
|
const snapshots = await listProviderRuntimeSnapshots(services.providerRegistry);
|
|
334
335
|
const current = services.providerRegistry.getCurrentModel();
|
|
@@ -354,7 +355,7 @@ async function renderProviders(runtime: CliCommandRuntime): Promise<string> {
|
|
|
354
355
|
}
|
|
355
356
|
if (sub === 'use' || sub === 'set') {
|
|
356
357
|
const provider = rest[0];
|
|
357
|
-
if (!provider) return
|
|
358
|
+
if (!provider) return `Usage: ${binary} providers use <provider> [modelRegistryKey]`;
|
|
358
359
|
const providerModels = services.providerRegistry
|
|
359
360
|
.getSelectableModels()
|
|
360
361
|
.filter((model) => model.provider === provider || model.registryKey.startsWith(`${provider}:`));
|
|
@@ -377,7 +378,7 @@ async function renderProviders(runtime: CliCommandRuntime): Promise<string> {
|
|
|
377
378
|
}
|
|
378
379
|
if (sub === 'inspect' || sub === 'show') {
|
|
379
380
|
const provider = rest[0];
|
|
380
|
-
if (!provider) return
|
|
381
|
+
if (!provider) return `Usage: ${binary} providers inspect <provider>`;
|
|
381
382
|
const snapshot = snapshots.find((candidate) => candidate.providerId === provider);
|
|
382
383
|
if (!snapshot) return `No provider found: ${provider}`;
|
|
383
384
|
const setup = classifyProviderSetup({
|
|
@@ -404,7 +405,7 @@ async function renderProviders(runtime: CliCommandRuntime): Promise<string> {
|
|
|
404
405
|
` detail: ${snapshot.runtime.auth?.detail ?? snapshot.runtime.notes?.join('; ') ?? ''}`,
|
|
405
406
|
].join('\n'));
|
|
406
407
|
}
|
|
407
|
-
if (sub !== 'list') return
|
|
408
|
+
if (sub !== 'list') return `Usage: ${binary} providers [list|current|inspect <provider>|use <provider> [modelRegistryKey]]`;
|
|
408
409
|
const value = snapshots.map((snapshot) => ({
|
|
409
410
|
...classifyProviderSetup({
|
|
410
411
|
providerId: snapshot.providerId,
|
|
@@ -433,6 +434,7 @@ async function renderProviders(runtime: CliCommandRuntime): Promise<string> {
|
|
|
433
434
|
|
|
434
435
|
async function renderModels(runtime: CliCommandRuntime): Promise<string> {
|
|
435
436
|
return await withRuntimeServices(runtime, async (services) => {
|
|
437
|
+
const binary = runtime.cli.binary;
|
|
436
438
|
const [subOrFilter, ...rest] = runtime.cli.commandArgs;
|
|
437
439
|
const current = services.providerRegistry.getCurrentModel().registryKey;
|
|
438
440
|
const providerSnapshots = await listProviderRuntimeSnapshots(services.providerRegistry);
|
|
@@ -469,7 +471,7 @@ async function renderModels(runtime: CliCommandRuntime): Promise<string> {
|
|
|
469
471
|
}
|
|
470
472
|
if (subOrFilter === 'use' || subOrFilter === 'set') {
|
|
471
473
|
const modelKey = rest[0];
|
|
472
|
-
if (!modelKey) return
|
|
474
|
+
if (!modelKey) return `Usage: ${binary} models use <registryKey>`;
|
|
473
475
|
const model = services.providerRegistry
|
|
474
476
|
.getSelectableModels()
|
|
475
477
|
.find((candidate) => candidate.registryKey === modelKey || candidate.id === modelKey);
|
|
@@ -485,7 +487,7 @@ async function renderModels(runtime: CliCommandRuntime): Promise<string> {
|
|
|
485
487
|
}
|
|
486
488
|
if (subOrFilter === 'pin' || subOrFilter === 'unpin') {
|
|
487
489
|
const modelKey = rest[0];
|
|
488
|
-
if (!modelKey) return `Usage:
|
|
490
|
+
if (!modelKey) return `Usage: ${binary} models ${subOrFilter} <registryKey>`;
|
|
489
491
|
if (subOrFilter === 'pin') await services.favoritesStore.pinModel(modelKey);
|
|
490
492
|
else await services.favoritesStore.unpinModel(modelKey);
|
|
491
493
|
return `Model ${subOrFilter === 'pin' ? 'pinned' : 'unpinned'}: ${modelKey}`;
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '0.1.
|
|
9
|
+
let _version = '0.1.92';
|
|
10
10
|
let _sdkVersion = '0.33.35';
|
|
11
11
|
try {
|
|
12
12
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|