@pellux/goodvibes-agent 0.1.8 → 0.1.9
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 +8 -0
- package/package.json +1 -1
- package/src/cli/agent-knowledge-command.ts +25 -2
- package/src/cli/help.ts +4 -4
- package/src/renderer/process-indicator.ts +7 -6
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GoodVibes Agent will be recorded here.
|
|
4
4
|
|
|
5
|
+
## 0.1.9 - 2026-05-31
|
|
6
|
+
|
|
7
|
+
- 75e5d4a Align shell surface delegation test
|
|
8
|
+
- a24c581 Use delegation wording in runtime indicator
|
|
9
|
+
- 259a75f Guard Agent knowledge isolation
|
|
10
|
+
- 59b6729 Align task help with Agent policy
|
|
11
|
+
- 0074a76 Classify stale daemon knowledge routes
|
|
12
|
+
|
|
5
13
|
## 0.1.8 - 2026-05-31
|
|
6
14
|
|
|
7
15
|
- 384c85a Remove stale WRFC artifact test
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Near-fork GoodVibes operator assistant with the GoodVibes TUI shell, renderer, input, fullscreen workspace, and daemon-connected Agent product brain.",
|
|
6
6
|
"type": "module",
|
|
@@ -17,10 +17,12 @@ interface AgentDaemonConnection {
|
|
|
17
17
|
|
|
18
18
|
interface AgentKnowledgeFailure {
|
|
19
19
|
readonly ok: false;
|
|
20
|
-
readonly kind: 'daemon_unavailable' | 'auth_required' | 'daemon_route_unavailable' | 'daemon_error';
|
|
20
|
+
readonly kind: 'daemon_unavailable' | 'auth_required' | 'version_mismatch' | 'daemon_route_unavailable' | 'daemon_error';
|
|
21
21
|
readonly error: string;
|
|
22
22
|
readonly baseUrl: string;
|
|
23
23
|
readonly route: string;
|
|
24
|
+
readonly daemonVersion?: string;
|
|
25
|
+
readonly expectedSdkVersion?: string;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
interface AgentKnowledgeSuccess<TData> {
|
|
@@ -200,13 +202,28 @@ async function fetchDaemonStatus(connection: AgentDaemonConnection): Promise<{ r
|
|
|
200
202
|
}
|
|
201
203
|
}
|
|
202
204
|
|
|
203
|
-
function classifyKnowledgeError(error: unknown, connection: AgentDaemonConnection, route: string): AgentKnowledgeFailure {
|
|
205
|
+
async function classifyKnowledgeError(error: unknown, connection: AgentDaemonConnection, route: string): Promise<AgentKnowledgeFailure> {
|
|
204
206
|
const message = summarizeError(error);
|
|
205
207
|
const lower = message.toLowerCase();
|
|
206
208
|
if (lower.includes('401') || lower.includes('unauthorized') || lower.includes('auth')) {
|
|
207
209
|
return { ok: false, kind: 'auth_required', error: message, baseUrl: connection.baseUrl, route };
|
|
208
210
|
}
|
|
209
211
|
if (lower.includes('404') || lower.includes('not found')) {
|
|
212
|
+
const metadata = readPackageMetadata();
|
|
213
|
+
const daemon = await fetchDaemonStatus(connection);
|
|
214
|
+
const daemonRecord = isRecord(daemon.body) ? daemon.body : {};
|
|
215
|
+
const daemonVersion = readString(daemonRecord, 'version') ?? 'unknown';
|
|
216
|
+
if (daemon.ok && daemonVersion !== metadata.sdkVersion) {
|
|
217
|
+
return {
|
|
218
|
+
ok: false,
|
|
219
|
+
kind: 'version_mismatch',
|
|
220
|
+
error: `External daemon SDK version ${daemonVersion} does not match Agent SDK pin ${metadata.sdkVersion}; Agent Knowledge route is unavailable.`,
|
|
221
|
+
baseUrl: connection.baseUrl,
|
|
222
|
+
route,
|
|
223
|
+
daemonVersion,
|
|
224
|
+
expectedSdkVersion: metadata.sdkVersion,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
210
227
|
return { ok: false, kind: 'daemon_route_unavailable', error: message, baseUrl: connection.baseUrl, route };
|
|
211
228
|
}
|
|
212
229
|
if (lower.includes('fetch') || lower.includes('connect') || lower.includes('econnrefused')) {
|
|
@@ -407,6 +424,12 @@ function formatFailure(failure: AgentKnowledgeFailure, json: boolean): string {
|
|
|
407
424
|
` ${failure.error}`,
|
|
408
425
|
` daemon: ${failure.baseUrl}`,
|
|
409
426
|
` route: ${failure.route}`,
|
|
427
|
+
failure.kind === 'version_mismatch' && failure.daemonVersion && failure.expectedSdkVersion
|
|
428
|
+
? ` versions: daemon=${failure.daemonVersion} expected=${failure.expectedSdkVersion}`
|
|
429
|
+
: null,
|
|
430
|
+
failure.kind === 'version_mismatch'
|
|
431
|
+
? ' next: update/restart the external GoodVibes daemon so /status matches the Agent SDK pin.'
|
|
432
|
+
: null,
|
|
410
433
|
failure.kind === 'daemon_route_unavailable'
|
|
411
434
|
? ' next: update/restart the external GoodVibes daemon to the SDK version required by this Agent package.'
|
|
412
435
|
: null,
|
package/src/cli/help.ts
CHANGED
|
@@ -45,7 +45,7 @@ export function renderGoodVibesHelp(binary = 'goodvibes-agent'): string {
|
|
|
45
45
|
' subscription Start/finish/logout provider subscription sessions',
|
|
46
46
|
' secrets List, set, link, delete, and test GoodVibes secret refs',
|
|
47
47
|
' sessions List, show, export, or resume saved sessions',
|
|
48
|
-
' tasks List/show in-process tasks
|
|
48
|
+
' tasks List/show in-process runtime tasks (read-only)',
|
|
49
49
|
' pair|qrcode Print companion pairing payload and QR code',
|
|
50
50
|
' surfaces Inspect/check browser/listener/external surfaces (read-only)',
|
|
51
51
|
' listener test Test HTTP listener/webhook readiness',
|
|
@@ -198,9 +198,9 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
198
198
|
examples: ['sessions list', 'sessions show latest-session', 'sessions export abc123 session.json'],
|
|
199
199
|
},
|
|
200
200
|
tasks: {
|
|
201
|
-
usage: ['tasks list', 'tasks show <taskId>'
|
|
202
|
-
summary: 'Inspect runtime tasks
|
|
203
|
-
examples: ['tasks list', 'tasks
|
|
201
|
+
usage: ['tasks list', 'tasks show <taskId>'],
|
|
202
|
+
summary: 'Inspect in-process runtime tasks. Agent blocks copied task submission; use run for one-shot work or delegate for explicit build/fix/review handoff.',
|
|
203
|
+
examples: ['tasks list', 'tasks show task-123', 'run "check provider readiness"', 'delegate "fix the failing tests"'],
|
|
204
204
|
},
|
|
205
205
|
surfaces: {
|
|
206
206
|
usage: ['surfaces [list]', 'surfaces check', 'surfaces show <surfaceId>'],
|
|
@@ -20,7 +20,7 @@ function truncateToWidth(text: string, maxWidth: number): string {
|
|
|
20
20
|
* renderProcessIndicator — shows a one-line summary of active runtime
|
|
21
21
|
* activity below the input area.
|
|
22
22
|
*
|
|
23
|
-
* Dimmed when no entries are active, highlighted (cyan) when delegated
|
|
23
|
+
* Dimmed when no entries are active, highlighted (cyan) when delegated work
|
|
24
24
|
* records or shell exec processes are running. Includes an `Enter to view`
|
|
25
25
|
* hint when active.
|
|
26
26
|
*/
|
|
@@ -32,6 +32,7 @@ export function renderProcessIndicator(
|
|
|
32
32
|
agentProgress?: string,
|
|
33
33
|
): Line[] {
|
|
34
34
|
const total = agentCount + toolCount;
|
|
35
|
+
const delegationLabel = (count: number): string => `${count} delegation${count !== 1 ? 's' : ''}`;
|
|
35
36
|
const renderPlainStatus = (text: string, style: { fg: string; bold?: boolean; dim?: boolean }): Line[] => (
|
|
36
37
|
[UIFactory.stringToLine(` ${text}`, width, style)]
|
|
37
38
|
);
|
|
@@ -59,7 +60,7 @@ export function renderProcessIndicator(
|
|
|
59
60
|
// --- Focused state: always render before idle/active branches ---
|
|
60
61
|
if (focused) {
|
|
61
62
|
const parts: string[] = [];
|
|
62
|
-
if (agentCount > 0) parts.push(
|
|
63
|
+
if (agentCount > 0) parts.push(delegationLabel(agentCount));
|
|
63
64
|
if (toolCount > 0) parts.push(`${toolCount} tool${toolCount !== 1 ? 's' : ''} running`);
|
|
64
65
|
const label = total === 0
|
|
65
66
|
? `No runtime activity ${GLYPHS.status.pending} back to input`
|
|
@@ -71,18 +72,18 @@ export function renderProcessIndicator(
|
|
|
71
72
|
return renderPlainStatus('No runtime activity', { fg: '238', dim: true });
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
// Build the label: "2
|
|
75
|
+
// Build the label: "2 delegations | Turn 3 | write - src/foo.ts"
|
|
75
76
|
const parts: string[] = [];
|
|
76
77
|
if (agentCount > 0) {
|
|
77
|
-
parts.push(
|
|
78
|
+
parts.push(delegationLabel(agentCount));
|
|
78
79
|
}
|
|
79
80
|
if (toolCount > 0) {
|
|
80
81
|
parts.push(`${toolCount} tool${toolCount !== 1 ? 's' : ''} running`);
|
|
81
82
|
}
|
|
82
83
|
// Append the first running agent's progress (truncated to fit)
|
|
83
84
|
/**
|
|
84
|
-
* Number of columns reserved for the
|
|
85
|
-
* Breakdown: "
|
|
85
|
+
* Number of columns reserved for the delegation count label and hint text.
|
|
86
|
+
* Breakdown: "N delegations" prefix (~15 chars) + " | " separator (~3)
|
|
86
87
|
* + " Enter to view " hint (~17) + padding (~8) ≈ 43 chars.
|
|
87
88
|
*/
|
|
88
89
|
const PROGRESS_RESERVED_CHARS = 43;
|
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.9';
|
|
10
10
|
try {
|
|
11
11
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8'));
|
|
12
12
|
_version = pkg.version ?? _version;
|