@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 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.41",
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.41';
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 {