@pellux/goodvibes-daemon-sdk 1.13.1 → 1.15.0

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.
@@ -63,6 +63,19 @@ interface ControlRouteContext {
63
63
  text: string;
64
64
  at: number;
65
65
  }[]) | undefined;
66
+ /**
67
+ * The minimum CLIENT build this daemon accepts as a full participant,
68
+ * announced on /status as a response header (the body has a closed schema,
69
+ * and a header is additive and ignorable by older clients).
70
+ *
71
+ * A daemon update does not restart the clients attached to it, so without
72
+ * this a process started days ago keeps executing shared-session work under
73
+ * whatever rules its build shipped with. Supplying it lets every client
74
+ * check itself on the liveness probe it already performs.
75
+ */
76
+ readonly clientCompatibilityFloor?: string | undefined;
77
+ /** Header name carrying {@link clientCompatibilityFloor}. */
78
+ readonly clientCompatibilityFloorHeader?: string | undefined;
66
79
  }
67
80
  export declare function createDaemonControlRouteHandlers(context: ControlRouteContext): DaemonControlRouteHandlers;
68
81
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"control-routes.d.ts","sourceRoot":"","sources":["../src/control-routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"control-routes.d.ts","sourceRoot":"","sources":["../src/control-routes.ts"],"names":[],"mappings":"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"}
@@ -31,11 +31,14 @@ export function createDaemonControlRouteHandlers(context) {
31
31
  // receipt-neutral, so an identity probe or keepalive that parses only
32
32
  // status/version can never eat a receipt before a rendering surface.
33
33
  const consumeReceipts = new URL(req.url).searchParams.get('receipts') === 'consume';
34
+ const floorHeader = context.clientCompatibilityFloor && context.clientCompatibilityFloorHeader
35
+ ? { [context.clientCompatibilityFloorHeader]: context.clientCompatibilityFloor }
36
+ : undefined;
34
37
  return Response.json({
35
38
  status: 'running',
36
39
  version: context.version,
37
40
  ...(consumeReceipts && context.collectReceipts ? { receipts: context.collectReceipts() } : {}),
38
- });
41
+ }, floorHeader ? { headers: floorHeader } : undefined);
39
42
  },
40
43
  getCurrentAuth: (req) => {
41
44
  const token = context.extractAuthToken(req).trim();
@@ -1 +1 @@
1
- {"version":3,"file":"error-response.d.ts","sourceRoot":"","sources":["../src/error-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,iBAAiB,EAGtB,KAAK,yBAAyB,EAC/B,MAAM,0BAA0B,CAAC;AAElC,oEAAoE;AACpE,MAAM,WAAW,wBAAwB;IACvC,uFAAuF;IACvF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,8EAA8E;IAC9E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAChD;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7C;AAkQD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,wBAA6B,GACrC,yBAAyB,CAgH3B;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,wBAA6B,GAAG,QAAQ,CAOlG;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,wBAA6B,GAAG,MAAM,CAEtG"}
1
+ {"version":3,"file":"error-response.d.ts","sourceRoot":"","sources":["../src/error-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,iBAAiB,EAGtB,KAAK,yBAAyB,EAC/B,MAAM,0BAA0B,CAAC;AAElC,oEAAoE;AACpE,MAAM,WAAW,wBAAwB;IACvC,uFAAuF;IACvF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,8EAA8E;IAC9E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAChD;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7C;AAyRD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,wBAA6B,GACrC,yBAAyB,CAgH3B;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,wBAA6B,GAAG,QAAQ,CAOlG;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,wBAA6B,GAAG,MAAM,CAEtG"}
@@ -61,7 +61,29 @@ function readMessage(error, fallbackMessage) {
61
61
  }
62
62
  return fallbackMessage ?? 'Unexpected error';
63
63
  }
64
- function inferCategory(status, code) {
64
+ /**
65
+ * Wording a spent account is reported with. Kept identical to the platform's
66
+ * own copies (`platform/types/errors.ts`, `platform/utils/error-display.ts`) so
67
+ * the daemon wire body and the platform agree on what "out of credit" is.
68
+ */
69
+ const BILLING_MESSAGE_PATTERN = /credit balance|insufficient[_\s-](?:credit|credits|quota|balance|funds)|out of credits|purchase credits|no credits|payment required|plans?[_\s&-]+billing|billing details/;
70
+ /**
71
+ * Category implied by the transport, refined by what the response SAID.
72
+ *
73
+ * 400 and 429 are deliberately not decided on the status alone. Providers
74
+ * report a spent account under both — Anthropic returns 400 with "credit
75
+ * balance is too low", and several return 429 for exhausted credit rather than
76
+ * throughput — so a status-only rule labels a billing failure `bad_request` or
77
+ * `rate_limit`. That matters beyond the wording: `rate_limit` reads as
78
+ * retryable, so a caller waits out a condition that never clears.
79
+ *
80
+ * The message is consulted only for those two statuses; every other status is
81
+ * unambiguous on its own.
82
+ */
83
+ function inferCategory(message, status, code) {
84
+ const msg = (message.length > MAX_INFER_MESSAGE_LENGTH
85
+ ? message.slice(0, MAX_INFER_MESSAGE_LENGTH)
86
+ : message).toLowerCase();
65
87
  if (status === 401)
66
88
  return DaemonErrorCategory.AUTHENTICATION;
67
89
  if (status === 402)
@@ -73,9 +95,9 @@ function inferCategory(status, code) {
73
95
  if (status === 408 || status === 504)
74
96
  return DaemonErrorCategory.TIMEOUT;
75
97
  if (status === 429)
76
- return DaemonErrorCategory.RATE_LIMIT;
98
+ return BILLING_MESSAGE_PATTERN.test(msg) ? DaemonErrorCategory.BILLING : DaemonErrorCategory.RATE_LIMIT;
77
99
  if (status === 400)
78
- return DaemonErrorCategory.BAD_REQUEST;
100
+ return BILLING_MESSAGE_PATTERN.test(msg) ? DaemonErrorCategory.BILLING : DaemonErrorCategory.BAD_REQUEST;
79
101
  if (status !== undefined && status >= 500)
80
102
  return DaemonErrorCategory.SERVICE;
81
103
  const normalizedCode = code?.toUpperCase();
@@ -251,7 +273,7 @@ export function buildErrorResponseBody(error, options = {}) {
251
273
  const phase = error.phase;
252
274
  const requestId = error.requestId;
253
275
  const network = getNetworkErrorMessage(message, provider);
254
- const inferred = inferCategory(status, error.code ?? providerCode);
276
+ const inferred = inferCategory(message, status, error.code ?? providerCode);
255
277
  const messageCategory = inferred === DaemonErrorCategory.UNKNOWN
256
278
  ? inferCategoryFromMessage(message)
257
279
  : inferred;
@@ -297,7 +319,7 @@ export function buildErrorResponseBody(error, options = {}) {
297
319
  const retryAfterMs = readNumberProperty(error.retryAfterMs);
298
320
  const message = error.error.trim() || options.fallbackMessage || 'Unexpected error';
299
321
  const network = getNetworkErrorMessage(message, provider);
300
- const inferred = inferCategory(status, code ?? providerCode);
322
+ const inferred = inferCategory(message, status, code ?? providerCode);
301
323
  const messageCategory = inferred === DaemonErrorCategory.UNKNOWN
302
324
  ? inferCategoryFromMessage(message)
303
325
  : inferred;
@@ -323,7 +345,7 @@ export function buildErrorResponseBody(error, options = {}) {
323
345
  }
324
346
  const message = readMessage(error, options.fallbackMessage);
325
347
  const network = getNetworkErrorMessage(message);
326
- const inferred = inferCategory(options.status);
348
+ const inferred = inferCategory(message, options.status);
327
349
  const messageCategory = inferred === DaemonErrorCategory.UNKNOWN
328
350
  ? inferCategoryFromMessage(message)
329
351
  : inferred;
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-rest-routes.d.ts","sourceRoot":"","sources":["../src/gateway-rest-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAYD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,gBAAgB,EA0E1D,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,OAAO,CAAC,8BAA8B,CAAC,GAChD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAe1B"}
1
+ {"version":3,"file":"gateway-rest-routes.d.ts","sourceRoot":"","sources":["../src/gateway-rest-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAYD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,gBAAgB,EAgF1D,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,OAAO,CAAC,8BAA8B,CAAC,GAChD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAe1B"}
@@ -80,6 +80,12 @@ export const GATEWAY_REST_ROUTES = [
80
80
  // power.* — sleep ownership: the chip state + the owner keep-awake toggle.
81
81
  route('GET', '/api/power/status', 'power.status.get'),
82
82
  route('POST', '/api/power/keep-awake', 'power.keepAwake.set'),
83
+ // devices.* — paired-phone capability nodes, the durable "always allow"
84
+ // grants surface, and the housekeeping sweep with its disclosure.
85
+ route('GET', '/api/devices/nodes', 'devices.nodes.list'),
86
+ route('GET', '/api/devices/grants', 'devices.grants.list'),
87
+ route('POST', '/api/devices/grants/revoke', 'devices.grants.revoke'),
88
+ route('POST', '/api/devices/housekeeping', 'devices.housekeeping.run'),
83
89
  // ops.memory.get — the MemoryGovernor snapshot (tier, budget, RSS/heap,
84
90
  // per-cache footprints, paused jobs, tripwire state).
85
91
  route('GET', '/api/ops/memory', 'ops.memory.get'),
@@ -11,6 +11,29 @@ export interface ConfigManagerLike {
11
11
  get(key: string): unknown;
12
12
  getAll(): Record<string, unknown>;
13
13
  setDynamic(key: string, value: unknown): void;
14
+ /**
15
+ * Absolute path of the settings file this manager writes to.
16
+ *
17
+ * Reported back on every config write. A caller and the host it is talking to
18
+ * routinely own DIFFERENT surface-scoped stores (`~/.goodvibes/agent/` versus
19
+ * `~/.goodvibes/tui/`), so "the setting was saved" is ambiguous until the file
20
+ * is named: a value written to the connected host is invisible to the caller's
21
+ * own store and vice versa, and reading it back locally shows the old value.
22
+ */
23
+ getConfigPath?(): string;
24
+ /**
25
+ * Which store the key resolves from and whether the DAEMON owns it.
26
+ *
27
+ * Ownership, not the caller's identity, decides where a value belongs: a
28
+ * daemon-owned key (chat surfaces, control-plane binding, watchers, device
29
+ * grants, retention) has exactly one home regardless of which client asked.
30
+ * Reported on every write so a caller never has to infer it from a path.
31
+ */
32
+ describeConfigKeySource?(key: string): {
33
+ readonly tier: string;
34
+ readonly daemonOwned: boolean;
35
+ readonly daemonTierPath: string | null;
36
+ };
14
37
  }
15
38
  export interface IntegrationApprovalSnapshotSourceLike {
16
39
  getApprovalSnapshot(): unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"system-route-types.d.ts","sourceRoot":"","sources":["../src/system-route-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"system-route-types.d.ts","sourceRoot":"","sources":["../src/system-route-types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"system-routes.d.ts","sourceRoot":"","sources":["../src/system-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAU9D,OAAO,KAAK,EAOV,wBAAwB,EAEzB,MAAM,yBAAyB,CAAC;AA6CjC,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,wBAAwB,GAChC,yBAAyB,CAkL3B"}
1
+ {"version":3,"file":"system-routes.d.ts","sourceRoot":"","sources":["../src/system-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAU9D,OAAO,KAAK,EAOV,wBAAwB,EAEzB,MAAM,yBAAyB,CAAC;AA6CjC,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,wBAAwB,GAChC,yBAAyB,CAqN3B"}
@@ -228,7 +228,39 @@ export function createDaemonSystemRouteHandlers(context) {
228
228
  catch (error) {
229
229
  return jsonErrorResponse(error, { status: 400, fallbackMessage: 'Failed to set config' });
230
230
  }
231
- return Response.json({ success: true, key, value });
231
+ // Report what the host now HOLDS, not what the caller asked for.
232
+ //
233
+ // Echoing the request back made this route say "success" for any write —
234
+ // it could not distinguish a value that took from one that was coerced,
235
+ // dropped, or overridden. It also never named the store, and the store is
236
+ // the whole question here: an agent writes over the control plane into the
237
+ // DAEMON's surface-scoped settings file, then reads the same key back from
238
+ // its OWN settings file and sees the old value. Both are correct; nothing
239
+ // said they were different files.
240
+ const current = context.configManager.get(key);
241
+ const source = context.configManager.describeConfigKeySource?.(key);
242
+ // A daemon-owned key does NOT live in the host's surface settings file —
243
+ // it lives in the daemon's own store. Reporting the surface path for it
244
+ // would name the wrong file, which is the confusion this replaces.
245
+ const persistedTo = (source?.daemonOwned ? source.daemonTierPath : null)
246
+ ?? context.configManager.getConfigPath?.();
247
+ if (!configValuesMatch(current, value)) {
248
+ return jsonErrorResponse({
249
+ error: `Config key ${key} did not take the requested value`
250
+ + `${persistedTo ? ` in ${persistedTo}` : ''}. The host now reports ${JSON.stringify(current)}.`,
251
+ code: 'CONFIG_SET_NOT_APPLIED',
252
+ }, { status: 409 });
253
+ }
254
+ // Name the OWNER as well as the file. "Saved" is only meaningful once a
255
+ // caller knows whether the value landed where the runtime that acts on it
256
+ // will read it — the whole point of daemon-owned config scope.
257
+ return Response.json({
258
+ success: true,
259
+ key,
260
+ value: current,
261
+ ...(persistedTo ? { persistedTo } : {}),
262
+ ...(source ? { tier: source.tier, daemonOwned: source.daemonOwned } : {}),
263
+ });
232
264
  },
233
265
  };
234
266
  }
@@ -435,6 +467,23 @@ async function handleApprovalAction(context, approvalId, action, req) {
435
467
  ? context.recordApiResponse(req, `/api/approvals/${approvalId}/${action}`, Response.json({ approval, recorded: recordedDecision(approval) }))
436
468
  : context.recordApiResponse(req, `/api/approvals/${approvalId}/${action}`, jsonErrorResponse({ error: 'Unknown approval' }, { status: 404 }));
437
469
  }
470
+ /**
471
+ * Compare a requested config value against what the host holds afterwards.
472
+ *
473
+ * Structural, because settings hold objects and arrays as well as scalars, and
474
+ * a config manager legitimately normalizes on the way in (trimming, filling a
475
+ * default sibling). Equal-by-value is the honest test of "did the write take".
476
+ */
477
+ function configValuesMatch(current, requested) {
478
+ if (Object.is(current, requested))
479
+ return true;
480
+ try {
481
+ return JSON.stringify(current) === JSON.stringify(requested);
482
+ }
483
+ catch {
484
+ return false;
485
+ }
486
+ }
438
487
  /**
439
488
  * Read an optional rememberTier off the request payload. Undefined when
440
489
  * absent; a 400 Response when present but not one of the broker's tiers.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-daemon-sdk",
3
- "version": "1.13.1",
3
+ "version": "1.15.0",
4
4
  "engines": {
5
5
  "bun": "1.3.10",
6
6
  "node": ">=22.0.0"
@@ -172,9 +172,9 @@
172
172
  "control-plane"
173
173
  ],
174
174
  "dependencies": {
175
- "@pellux/goodvibes-contracts": "1.13.1",
176
- "@pellux/goodvibes-errors": "1.13.1",
177
- "@pellux/goodvibes-transport-core": "1.13.1"
175
+ "@pellux/goodvibes-contracts": "1.15.0",
176
+ "@pellux/goodvibes-errors": "1.15.0",
177
+ "@pellux/goodvibes-transport-core": "1.15.0"
178
178
  },
179
179
  "publishConfig": {
180
180
  "access": "public"