@pellux/goodvibes-agent 0.1.41 → 0.1.43
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/README.md +2 -2
- package/docs/operator-capability-benchmark.md +2 -2
- package/package.json +1 -1
- package/src/input/agent-workspace.ts +14 -0
- package/src/operator/daemon-capability-audit.ts +39 -2
- package/src/renderer/agent-workspace.ts +8 -0
- 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.43 - 2026-05-31
|
|
6
|
+
|
|
7
|
+
- 3afba9c Add daemon route risk coverage
|
|
8
|
+
|
|
9
|
+
## 0.1.42 - 2026-05-31
|
|
10
|
+
|
|
11
|
+
- 3c84649 Surface daemon capabilities in Agent workspace
|
|
12
|
+
|
|
5
13
|
## 0.1.41 - 2026-05-31
|
|
6
14
|
|
|
7
15
|
- c108e13 Add live daemon capability audit
|
package/README.md
CHANGED
|
@@ -43,9 +43,9 @@ bun run package:install-check
|
|
|
43
43
|
bun run publish:check
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
Inside the Agent TUI, use `/agent`, `/home`, or `/operator` to open the operator workspace. It is the Agent-first fullscreen surface for setup, status, knowledge, local memory/skills, work-plan/approval review, automation observability, and explicit build delegation to GoodVibes TUI.
|
|
46
|
+
Inside the Agent TUI, use `/agent`, `/home`, or `/operator` to open the operator workspace. It is the Agent-first fullscreen surface for setup, status, live daemon capability coverage, knowledge, local memory/skills, work-plan/approval review, automation observability, and explicit build delegation to GoodVibes TUI.
|
|
47
47
|
|
|
48
|
-
Use `goodvibes-agent capabilities` or `/capabilities` to inspect the OpenClaw/Hermes benchmark, current Agent posture, configuration commands, usage paths, and remaining gaps. Use `goodvibes-agent capabilities daemon` or `/capabilities daemon` for a live read-only audit of the GoodVibes daemon method catalog and isolated Agent Knowledge route coverage.
|
|
48
|
+
Use `goodvibes-agent capabilities` or `/capabilities` to inspect the OpenClaw/Hermes benchmark, current Agent posture, configuration commands, usage paths, and remaining gaps. Use `goodvibes-agent capabilities daemon` or `/capabilities daemon` for a live read-only audit of the GoodVibes daemon method catalog, route risk posture, and isolated Agent Knowledge route coverage.
|
|
49
49
|
|
|
50
50
|
Inside the workspace, use `/agent-profile guide` to author custom profile starters without leaving the Agent TUI. The guided flow lists starters, exports starter JSON, imports edited local starters, and creates isolated runtime profiles from them.
|
|
51
51
|
|
|
@@ -56,7 +56,7 @@ The benchmark measures two different GoodVibes layers:
|
|
|
56
56
|
|
|
57
57
|
If the daemon already has a route but Agent lacks a good setup/workspace/CLI surface, the gap is treated as an Agent product gap rather than a missing platform capability.
|
|
58
58
|
|
|
59
|
-
Use `goodvibes-agent capabilities daemon` for the live read-only daemon audit. It checks the public control-plane method catalog and the isolated Agent Knowledge status route. It intentionally does not call default `/api/knowledge/*`, HomeGraph, or Home Assistant routes.
|
|
59
|
+
Use `goodvibes-agent capabilities daemon` for the live read-only daemon audit. It checks the public control-plane method catalog, route risk posture, and the isolated Agent Knowledge status route. It intentionally does not call default `/api/knowledge/*`, HomeGraph, or Home Assistant routes.
|
|
60
60
|
|
|
61
61
|
## Capability Targets
|
|
62
62
|
|
|
@@ -78,7 +78,7 @@ Use `goodvibes-agent capabilities daemon` for the live read-only daemon audit. I
|
|
|
78
78
|
|
|
79
79
|
GoodVibes Agent should exceed OpenClaw/Hermes by making these properties true from day one:
|
|
80
80
|
|
|
81
|
-
- Capability surfaces are discoverable through `goodvibes-agent capabilities`, `/capabilities`, onboarding, and the operator workspace.
|
|
81
|
+
- Capability surfaces are discoverable through `goodvibes-agent capabilities`, `goodvibes-agent capabilities daemon`, `/capabilities`, `/capabilities daemon`, onboarding, and the operator workspace.
|
|
82
82
|
- Agent Knowledge isolation is a release gate, not a convention.
|
|
83
83
|
- Routine-to-schedule promotion preserves Agent Knowledge isolation, uses only public external daemon schedule routes, supports explicit delivery targets, and stores redacted receipts.
|
|
84
84
|
- Model-visible tools are policy-gated for serial, non-secret, non-destructive use.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
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",
|
|
@@ -480,6 +480,20 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
480
480
|
{ id: 'auth', label: 'Auth review', detail: 'Review authentication posture without printing token values.', command: '/auth review', kind: 'command', safety: 'read-only' },
|
|
481
481
|
],
|
|
482
482
|
},
|
|
483
|
+
{
|
|
484
|
+
id: 'capabilities',
|
|
485
|
+
group: 'SETUP',
|
|
486
|
+
label: 'Capabilities',
|
|
487
|
+
summary: 'OpenClaw/Hermes benchmark and live daemon coverage.',
|
|
488
|
+
detail: 'Use this area to measure both layers: what GoodVibes Agent makes usable, and what the externally owned GoodVibes daemon actually exposes through public routes. Agent Knowledge is checked only through /api/goodvibes-agent/knowledge/*.',
|
|
489
|
+
actions: [
|
|
490
|
+
{ id: 'capabilities-benchmark', label: 'Benchmark report', detail: 'Show the OpenClaw/Hermes parity benchmark with Agent posture, setup commands, usage paths, and remaining product gaps.', command: '/capabilities', kind: 'command', safety: 'read-only' },
|
|
491
|
+
{ id: 'capabilities-daemon', label: 'Live daemon audit', detail: 'Inspect the public daemon method catalog plus isolated Agent Knowledge route coverage. Does not query default Knowledge/Wiki or HomeGraph.', command: '/capabilities daemon', kind: 'command', safety: 'read-only' },
|
|
492
|
+
{ id: 'capabilities-daemon-knowledge', label: 'Knowledge coverage', detail: 'Filter the live daemon audit to the isolated Agent Knowledge segment.', command: '/capabilities daemon knowledge', kind: 'command', safety: 'read-only' },
|
|
493
|
+
{ id: 'capabilities-daemon-channels', label: 'Channel coverage', detail: 'Filter the live daemon audit to channel and delivery gateway route coverage.', command: '/capabilities daemon channels', kind: 'command', safety: 'read-only' },
|
|
494
|
+
{ id: 'capabilities-daemon-automation', label: 'Automation coverage', detail: 'Filter the live daemon audit to automation, schedule, run, and capacity route coverage.', command: '/capabilities daemon automation', kind: 'command', safety: 'read-only' },
|
|
495
|
+
],
|
|
496
|
+
},
|
|
483
497
|
{
|
|
484
498
|
id: 'channels',
|
|
485
499
|
group: 'SETUP',
|
|
@@ -41,6 +41,12 @@ export interface DaemonCapabilityAuditArea {
|
|
|
41
41
|
readonly route: string;
|
|
42
42
|
readonly coverage: DaemonCapabilityRouteCoverage;
|
|
43
43
|
}[];
|
|
44
|
+
readonly routeRisk: {
|
|
45
|
+
readonly readOnlyMethodCount: number;
|
|
46
|
+
readonly mutatingMethodCount: number;
|
|
47
|
+
readonly authenticatedMethodCount: number;
|
|
48
|
+
readonly dangerousMethodIds: readonly string[];
|
|
49
|
+
};
|
|
44
50
|
readonly next: readonly string[];
|
|
45
51
|
}
|
|
46
52
|
|
|
@@ -75,12 +81,13 @@ export type DaemonCapabilityAuditResult =
|
|
|
75
81
|
| DaemonCapabilityAuditSuccess
|
|
76
82
|
| DaemonCapabilityAuditFailure;
|
|
77
83
|
|
|
78
|
-
interface DaemonMethodSummary {
|
|
84
|
+
export interface DaemonMethodSummary {
|
|
79
85
|
readonly id: string;
|
|
80
86
|
readonly title?: string;
|
|
81
87
|
readonly category?: string;
|
|
82
88
|
readonly invokable?: boolean;
|
|
83
89
|
readonly access?: string;
|
|
90
|
+
readonly dangerous?: boolean;
|
|
84
91
|
readonly http?: {
|
|
85
92
|
readonly method?: string;
|
|
86
93
|
readonly path?: string;
|
|
@@ -294,6 +301,7 @@ function readMethodSummaries(body: unknown): readonly DaemonMethodSummary[] {
|
|
|
294
301
|
category: readString(value, 'category') ?? undefined,
|
|
295
302
|
access: readString(value, 'access') ?? undefined,
|
|
296
303
|
invokable: typeof value.invokable === 'boolean' ? value.invokable : undefined,
|
|
304
|
+
dangerous: typeof value.dangerous === 'boolean' ? value.dangerous : undefined,
|
|
297
305
|
http: httpRecord
|
|
298
306
|
? {
|
|
299
307
|
method: readString(httpRecord, 'method') ?? undefined,
|
|
@@ -389,7 +397,9 @@ function failureFromThrown(error: unknown, connection: AgentDaemonConnection, ro
|
|
|
389
397
|
export function buildDaemonCapabilityAuditAreas(
|
|
390
398
|
methodIds: ReadonlySet<string>,
|
|
391
399
|
agentKnowledgeRouteReady: boolean | null,
|
|
400
|
+
methodSummaries: readonly DaemonMethodSummary[] = [],
|
|
392
401
|
): readonly DaemonCapabilityAuditArea[] {
|
|
402
|
+
const methodsById = new Map(methodSummaries.map((method) => [method.id, method]));
|
|
393
403
|
return DAEMON_CAPABILITY_REQUIREMENTS.map((requirement) => {
|
|
394
404
|
const presentRequiredMethodIds = requirement.requiredMethodIds.filter((methodId) => methodIds.has(methodId));
|
|
395
405
|
const missingRequiredMethodIds = requirement.requiredMethodIds.filter((methodId) => !methodIds.has(methodId));
|
|
@@ -404,6 +414,23 @@ export function buildDaemonCapabilityAuditAreas(
|
|
|
404
414
|
: 'missing',
|
|
405
415
|
} satisfies DaemonCapabilityAuditArea['agentRoutes'][number]));
|
|
406
416
|
const missingAgentRoutes = agentRoutes.filter((route) => route.coverage === 'missing');
|
|
417
|
+
const areaMethodIds = [...requirement.requiredMethodIds, ...requirement.optionalMethodIds];
|
|
418
|
+
const areaMethods = areaMethodIds.flatMap((methodId): DaemonMethodSummary[] => {
|
|
419
|
+
const method = methodsById.get(methodId);
|
|
420
|
+
return method ? [method] : [];
|
|
421
|
+
});
|
|
422
|
+
const readOnlyMethodCount = areaMethods.filter((method) => {
|
|
423
|
+
const verb = method.http?.method?.toUpperCase();
|
|
424
|
+
return verb === 'GET' || verb === 'HEAD';
|
|
425
|
+
}).length;
|
|
426
|
+
const mutatingMethodCount = areaMethods.filter((method) => {
|
|
427
|
+
const verb = method.http?.method?.toUpperCase();
|
|
428
|
+
return Boolean(verb) && verb !== 'GET' && verb !== 'HEAD';
|
|
429
|
+
}).length;
|
|
430
|
+
const authenticatedMethodCount = areaMethods.filter((method) => method.access === 'authenticated').length;
|
|
431
|
+
const dangerousMethodIds = areaMethods
|
|
432
|
+
.filter((method) => method.dangerous === true)
|
|
433
|
+
.map((method) => method.id);
|
|
407
434
|
const requiredCount = requirement.requiredMethodIds.length + requirement.requiredAgentRoutes.length;
|
|
408
435
|
const presentRequiredCount = presentRequiredMethodIds.length
|
|
409
436
|
+ agentRoutes.filter((route) => route.coverage === 'ready').length;
|
|
@@ -423,6 +450,12 @@ export function buildDaemonCapabilityAuditAreas(
|
|
|
423
450
|
presentOptionalMethodIds,
|
|
424
451
|
missingOptionalMethodIds,
|
|
425
452
|
agentRoutes,
|
|
453
|
+
routeRisk: {
|
|
454
|
+
readOnlyMethodCount,
|
|
455
|
+
mutatingMethodCount,
|
|
456
|
+
authenticatedMethodCount,
|
|
457
|
+
dangerousMethodIds,
|
|
458
|
+
},
|
|
426
459
|
next: requirement.next,
|
|
427
460
|
};
|
|
428
461
|
});
|
|
@@ -472,7 +505,7 @@ export async function fetchLiveDaemonCapabilityAudit(
|
|
|
472
505
|
defaultKnowledgeFallback: false,
|
|
473
506
|
homeGraphFallback: false,
|
|
474
507
|
warnings,
|
|
475
|
-
areas: buildDaemonCapabilityAuditAreas(methodIds, agentKnowledge.ok),
|
|
508
|
+
areas: buildDaemonCapabilityAuditAreas(methodIds, agentKnowledge.ok, methodSummaries),
|
|
476
509
|
};
|
|
477
510
|
} catch (error) {
|
|
478
511
|
return failureFromThrown(error, connection, daemonVersion === 'unknown' ? DAEMON_STATUS_ROUTE : DAEMON_METHOD_CATALOG_ROUTE);
|
|
@@ -528,6 +561,10 @@ export function renderDaemonCapabilityAudit(
|
|
|
528
561
|
lines.push(` optional methods: ${area.presentOptionalMethodIds.length}/${optionalTotal}`);
|
|
529
562
|
if (area.missingOptionalMethodIds.length > 0) lines.push(` missing optional: ${area.missingOptionalMethodIds.join(', ')}`);
|
|
530
563
|
}
|
|
564
|
+
lines.push(` route risk: ${area.routeRisk.readOnlyMethodCount} read-only; ${area.routeRisk.mutatingMethodCount} mutating; ${area.routeRisk.dangerousMethodIds.length} dangerous; ${area.routeRisk.authenticatedMethodCount} authenticated`);
|
|
565
|
+
if (area.routeRisk.dangerousMethodIds.length > 0) {
|
|
566
|
+
lines.push(` dangerous methods: ${area.routeRisk.dangerousMethodIds.join(', ')}`);
|
|
567
|
+
}
|
|
531
568
|
for (const route of area.agentRoutes) lines.push(` route: ${route.route} [${route.coverage}]`);
|
|
532
569
|
lines.push(` next: ${area.next.join(' | ')}`);
|
|
533
570
|
lines.push('');
|
|
@@ -88,6 +88,14 @@ function snapshotLines(category: AgentWorkspaceCategory, snapshot: AgentWorkspac
|
|
|
88
88
|
{ text: `Workspace: ${snapshot.workingDirectory}`, fg: PALETTE.muted },
|
|
89
89
|
{ text: `Home: ${snapshot.homeDirectory}`, fg: PALETTE.muted },
|
|
90
90
|
);
|
|
91
|
+
} else if (category.id === 'capabilities') {
|
|
92
|
+
base.push(
|
|
93
|
+
{ text: `External daemon: ${snapshot.daemonBaseUrl}`, fg: PALETTE.info },
|
|
94
|
+
{ text: 'Live audit source: /api/control-plane/methods plus /api/goodvibes-agent/knowledge/status.', fg: PALETTE.info },
|
|
95
|
+
{ text: 'Isolation: no default Knowledge/Wiki, HomeGraph, or Home Assistant route is used for Agent Knowledge coverage.', fg: PALETTE.good },
|
|
96
|
+
{ text: 'Readiness meaning: daemon route coverage is platform capability; missing Agent UX remains a product gap to close here.', fg: PALETTE.muted },
|
|
97
|
+
{ text: 'Use filtered audits for knowledge, channels, automation, voice/media/nodes, providers, MCP/tools, approvals, or sessions.', fg: PALETTE.muted },
|
|
98
|
+
);
|
|
91
99
|
} else if (category.id === 'channels') {
|
|
92
100
|
const enabledCount = snapshot.channels.filter((channel) => channel.enabled).length;
|
|
93
101
|
const readyCount = snapshot.channels.filter((channel) => channel.ready).length;
|
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.43';
|
|
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 {
|