@pellux/goodvibes-agent 0.1.42 → 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,10 @@
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
+
5
9
  ## 0.1.42 - 2026-05-31
6
10
 
7
11
  - 3c84649 Surface daemon capabilities in Agent workspace
package/README.md CHANGED
@@ -45,7 +45,7 @@ bun run publish:check
45
45
 
46
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "0.1.42",
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",
@@ -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('');
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.42';
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 {