@north-light/crouter 0.3.241 → 0.3.243

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.
Files changed (62) hide show
  1. package/dist/api/dto/broker-ops.d.ts +8 -3
  2. package/dist/api/dto/broker.d.ts +4 -2
  3. package/dist/api/dto/inbox.d.ts +1 -0
  4. package/dist/api/dto/nodes.d.ts +4 -0
  5. package/dist/api/dto/review-comments.d.ts +1 -0
  6. package/dist/builtin-memory/04-orchestration-kernel.md +1 -1
  7. package/dist/clients/attach/session/profile-files.js +4 -1
  8. package/dist/clients/attach/viewer.js +1 -1
  9. package/dist/commands/node/create.js +8 -3
  10. package/dist/commands/sys/context/admin/docs-panel.d.ts +17 -7
  11. package/dist/commands/sys/context/admin/docs-panel.js +43 -23
  12. package/dist/commands/sys/context/admin/list-view.d.ts +22 -11
  13. package/dist/commands/sys/context/admin/list-view.js +112 -53
  14. package/dist/commands/sys/context/admin/shell.d.ts +3 -0
  15. package/dist/commands/sys/context/admin/shell.js +11 -2
  16. package/dist/commands/sys/daemon.js +1 -1
  17. package/dist/core/__tests__/child-death-wake.test.js +0 -48
  18. package/dist/core/__tests__/daemon-boot.test.js +0 -8
  19. package/dist/core/__tests__/dead-node-policy-table.test.js +1 -2
  20. package/dist/core/__tests__/integration/deferred-no-wake.test.js +14 -2
  21. package/dist/core/__tests__/lifecycle.test.js +5 -5
  22. package/dist/core/__tests__/relaunch-root.test.js +91 -1
  23. package/dist/core/__tests__/revive-capacity.test.js +36 -1
  24. package/dist/core/__tests__/seam/broker-cap-freeze.test.js +73 -0
  25. package/dist/core/__tests__/seam/dormancy-release.test.js +1 -2
  26. package/dist/core/canvas/canvas.d.ts +6 -5
  27. package/dist/core/canvas/canvas.js +8 -7
  28. package/dist/core/canvas/types.d.ts +6 -0
  29. package/dist/core/review/realize.js +1 -1
  30. package/dist/core/runtime/broker/node-named.d.ts +1 -0
  31. package/dist/core/runtime/host.js +114 -103
  32. package/dist/core/runtime/lifecycle.js +3 -2
  33. package/dist/core/runtime/naming.d.ts +26 -8
  34. package/dist/core/runtime/naming.js +75 -43
  35. package/dist/core/runtime/reset.js +12 -5
  36. package/dist/core/runtime/revive-all.d.ts +4 -11
  37. package/dist/core/runtime/revive-all.js +6 -13
  38. package/dist/core/runtime/warm-pool.js +4 -4
  39. package/dist/daemon/api/__tests__/node-create-description.test.js +1 -0
  40. package/dist/daemon/api/handlers/broker-ops.js +14 -7
  41. package/dist/daemon/api/handlers/feedback-comments.js +1 -1
  42. package/dist/daemon/api/map.js +2 -0
  43. package/dist/daemon/crtrd.js +17 -20
  44. package/dist/daemon/messaging/node-message.d.ts +1 -0
  45. package/dist/daemon/messaging/node-message.js +6 -2
  46. package/dist/daemon/reconcilers/live-obligation.d.ts +1 -2
  47. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +0 -5
  48. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +9 -13
  49. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +0 -6
  50. package/dist/daemon/reconcilers/node-lifecycle/terminating.d.ts +0 -2
  51. package/dist/daemon/reconcilers/node-lifecycle/terminating.js +0 -10
  52. package/dist/daemon/reconcilers/node-lifecycle/tick.d.ts +2 -2
  53. package/dist/daemon/reconcilers/node-lifecycle/tick.js +4 -2
  54. package/dist/daemon/reconcilers/storage-maintenance.js +2 -2
  55. package/dist/daemon/review/comment-notify.d.ts +1 -0
  56. package/dist/daemon/review/comment-notify.js +1 -0
  57. package/dist/pi-extensions/broker-local.d.ts +1 -0
  58. package/dist/pi-extensions/broker-local.js +12 -7
  59. package/dist/pi-extensions/canvas-recap.js +1 -0
  60. package/dist/pi-extensions/canvas-stophook.js +2 -0
  61. package/package.json +1 -1
  62. package/runtime.lock.json +2 -2
@@ -1,13 +1,3 @@
1
- // terminating.ts — the Terminating state's owner, and P4's file to own outright.
2
- //
3
- // A terminal row that still holds a process is a node whose teardown has been
4
- // requested but not finished. P4 gives it one bounded shutdown request and an
5
- // escalation after its grace, moving the inline `headlessBrokerHost.teardown`
6
- // calls at the close/reset sites into this daemon-side lane. P3 changes no
7
- // teardown behavior: it only OBSERVES such rows (the tick queries terminal rows
8
- // carrying a recorded pid) and hands them here, so P4 edits this file alone.
9
- /** Handle a terminal row that still holds a process. Deliberately inert until
10
- * P4: a row reaching here is already excluded from every other tick duty. */
11
1
  export function handleTerminatingRow(row) {
12
2
  void row;
13
3
  }
@@ -2,8 +2,8 @@ import { type NodeRow } from '../../../core/canvas/index.js';
2
2
  import type { FleetRegistry } from '../../../core/runtime/fleet.js';
3
3
  import { type FrozenCounts } from './freeze-lane.js';
4
4
  export interface NodeLifecycleContext {
5
- /** Every active and idle row (human rows excluded), plus terminal rows that
6
- * still hold a recorded pid. */
5
+ /** Every active and idle row (human rows excluded), plus terminal rows with
6
+ * a recorded pid or frozen mark. */
7
7
  rows: readonly NodeRow[];
8
8
  fleet: FleetRegistry;
9
9
  }
@@ -64,9 +64,11 @@ export class NodeLifecycleReconciler {
64
64
  this.thawMark(row);
65
65
  return;
66
66
  }
67
- // 2. A terminal row still holding a process is Terminating, and P4's.
68
67
  if (isTerminal(row)) {
69
- handleTerminatingRow(row);
68
+ if (row.pi_pid != null)
69
+ handleTerminatingRow(row);
70
+ else if (row.frozen_at != null)
71
+ candidates.push({ row, enact: 'thaw' });
70
72
  return;
71
73
  }
72
74
  // A paused profile launches nothing, and its stuck-delivery episode is over
@@ -19,8 +19,8 @@ export class StorageMaintenanceReconciler {
19
19
  run(now, ctx) {
20
20
  void ctx; // no consumer today — kept only for six-way call-site uniformity
21
21
  // Placement reap MUST precede focus GC, so GC catches a focus row the reap
22
- // strands. Both run after dormant-inbox reconciliation, so a same-tick
23
- // revive has already had the chance to re-anchor its focus.
22
+ // strands. Both run after the lifecycle tick, so a same-tick revive has
23
+ // already had the chance to re-anchor its focus.
24
24
  this.reapDeadResidue(now);
25
25
  this.gcStaleFocuses();
26
26
  this.reapGhostRows(now);
@@ -7,6 +7,7 @@ export interface CommentDelivery {
7
7
  status: 'delivered' | 'skipped' | 'failed';
8
8
  via?: 'engine' | 'inbox';
9
9
  woke: boolean;
10
+ reason?: 'capacity_frozen';
10
11
  error?: string;
11
12
  }
12
13
  /** Render the one bounded, durable comment notice delivered to a review companion. */
@@ -96,6 +96,7 @@ export async function notifyComment(args) {
96
96
  status: 'delivered',
97
97
  via: delivery.via,
98
98
  woke: delivery.revived,
99
+ ...(delivery.reason === undefined ? {} : { reason: delivery.reason }),
99
100
  };
100
101
  appendDeliveryEvent({
101
102
  review_id: args.review.review_id,
@@ -13,6 +13,7 @@ export declare function generateAndCommitInitialName(nodeId: string, prompt: str
13
13
  export declare function generateAndCommitRecapName(nodeId: string, conversation: string, expected: {
14
14
  name: string;
15
15
  description: string;
16
+ title: string;
16
17
  icon: string;
17
18
  kind: string;
18
19
  }, isStillAutomatic: () => boolean, onNamed?: (editorLabel: string) => void): void;
@@ -10,7 +10,7 @@ import { join } from 'node:path';
10
10
  import { CRTR_DIR_NAME } from '../types.js';
11
11
  import { brokerExtensionState, commitBrokerGeneratedName, } from '../core/runtime/broker/daemon-ops.js';
12
12
  import { publishNodeNamed } from '../core/runtime/broker/node-named.js';
13
- import { headlessName, headlessNameFromConversation, sanitizeSessionName, slugFromPrompt, } from '../core/runtime/naming.js';
13
+ import { headlessName, headlessNameFromConversation, sanitizeSessionName, sanitizeSessionTitle, slugFromPrompt, titleFromPrompt, } from '../core/runtime/naming.js';
14
14
  function contextDir(nodeId) {
15
15
  if (nodeId === '' || nodeId === '.' || nodeId === '..' || /[\\/\0]/u.test(nodeId)) {
16
16
  throw new TypeError('node_id must be a non-empty path segment');
@@ -37,8 +37,14 @@ export function readRoadmap(nodeId) {
37
37
  const path = join(contextDir(nodeId), 'roadmap.md');
38
38
  return existsSync(path) ? readFileSync(path, 'utf8') : null;
39
39
  }
40
- function generatedDescription(source, generated) {
41
- return sanitizeSessionName(generated.name) || slugFromPrompt(source);
40
+ /** The label fields to commit: what the namer produced, or what the source text
41
+ * itself yields when it produced nothing usable. */
42
+ function generatedLabel(source, generated) {
43
+ return {
44
+ description: sanitizeSessionName(generated.name) || slugFromPrompt(source),
45
+ title: sanitizeSessionTitle(generated.title) || titleFromPrompt(source),
46
+ icon: generated.icon,
47
+ };
42
48
  }
43
49
  /** Generate and commit the first name for a node. The initial operation is
44
50
  * guarded by crtrd, so a concurrent rename or another broker cannot be
@@ -53,8 +59,7 @@ export function generateAndCommitInitialName(nodeId, prompt, onNamed) {
53
59
  return undefined;
54
60
  return headlessName(body).then((generated) => commitBrokerGeneratedName(nodeId, {
55
61
  kind: 'initial',
56
- description: generatedDescription(body, generated),
57
- icon: generated.icon,
62
+ ...generatedLabel(body, generated),
58
63
  }));
59
64
  })
60
65
  .then((result) => {
@@ -68,6 +73,7 @@ export function generateAndCommitInitialName(nodeId, prompt, onNamed) {
68
73
  // has nothing left to re-read on.
69
74
  publishNodeNamed({
70
75
  description: result.description ?? '',
76
+ title: result.title ?? '',
71
77
  icon: result.icon ?? '',
72
78
  editorLabel: result.editorLabel,
73
79
  });
@@ -88,8 +94,7 @@ export function generateAndCommitRecapName(nodeId, conversation, expected, isSti
88
94
  return undefined;
89
95
  return commitBrokerGeneratedName(nodeId, {
90
96
  kind: 'recap',
91
- description: generatedDescription(body, generated),
92
- icon: generated.icon,
97
+ ...generatedLabel(body, generated),
93
98
  expected,
94
99
  });
95
100
  })
@@ -267,6 +267,7 @@ export function registerCanvasRecap(pi, recapGenerator = generateRecap, nameRege
267
267
  generateAndCommitRecapName(nodeId, conversation, {
268
268
  name: node.name,
269
269
  description: node.description ?? '',
270
+ title: node.title ?? '',
270
271
  icon: node.icon ?? '',
271
272
  kind: node.kind,
272
273
  }, () => pi.getSessionName?.() === original, (label) => {
@@ -360,6 +360,8 @@ export function registerCanvasStophook(pi) {
360
360
  // back into its calling broker. Do not await the operation that tears
361
361
  // this broker down from Pi's session-start dispatch.
362
362
  void relaunchBrokerRoot(nodeId).catch((error) => {
363
+ const message = error instanceof Error ? error.message : String(error);
364
+ ctx?.ui?.notify?.(`/new refused: ${message}`, 'error');
363
365
  emitEvent({
364
366
  event: 'broker.daemon.operation.failed',
365
367
  level: 'error',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.241",
3
+ "version": "0.3.243",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.241",
3
+ "version": "0.3.243",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/crouter",
9
- "version": "0.3.241",
9
+ "version": "0.3.243",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {