@north-light/crouter 0.3.241 → 0.3.242

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 (56) 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 +366 -366
  9. package/dist/commands/node/create.js +8 -3
  10. package/dist/commands/sys/daemon.js +1 -1
  11. package/dist/core/__tests__/child-death-wake.test.js +0 -48
  12. package/dist/core/__tests__/daemon-boot.test.js +0 -8
  13. package/dist/core/__tests__/dead-node-policy-table.test.js +1 -2
  14. package/dist/core/__tests__/integration/deferred-no-wake.test.js +14 -2
  15. package/dist/core/__tests__/lifecycle.test.js +5 -5
  16. package/dist/core/__tests__/relaunch-root.test.js +91 -1
  17. package/dist/core/__tests__/revive-capacity.test.js +36 -1
  18. package/dist/core/__tests__/seam/broker-cap-freeze.test.js +73 -0
  19. package/dist/core/__tests__/seam/dormancy-release.test.js +1 -2
  20. package/dist/core/canvas/canvas.d.ts +6 -5
  21. package/dist/core/canvas/canvas.js +8 -7
  22. package/dist/core/canvas/types.d.ts +6 -0
  23. package/dist/core/review/realize.js +1 -1
  24. package/dist/core/runtime/broker/node-named.d.ts +1 -0
  25. package/dist/core/runtime/host.js +114 -103
  26. package/dist/core/runtime/lifecycle.js +3 -2
  27. package/dist/core/runtime/naming.d.ts +26 -8
  28. package/dist/core/runtime/naming.js +75 -43
  29. package/dist/core/runtime/reset.js +12 -5
  30. package/dist/core/runtime/revive-all.d.ts +4 -11
  31. package/dist/core/runtime/revive-all.js +6 -13
  32. package/dist/core/runtime/warm-pool.js +4 -4
  33. package/dist/daemon/api/__tests__/node-create-description.test.js +1 -0
  34. package/dist/daemon/api/handlers/broker-ops.js +14 -7
  35. package/dist/daemon/api/handlers/feedback-comments.js +1 -1
  36. package/dist/daemon/api/map.js +2 -0
  37. package/dist/daemon/crtrd.js +17 -20
  38. package/dist/daemon/messaging/node-message.d.ts +1 -0
  39. package/dist/daemon/messaging/node-message.js +6 -2
  40. package/dist/daemon/reconcilers/live-obligation.d.ts +1 -2
  41. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +0 -5
  42. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +9 -13
  43. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +0 -6
  44. package/dist/daemon/reconcilers/node-lifecycle/terminating.d.ts +0 -2
  45. package/dist/daemon/reconcilers/node-lifecycle/terminating.js +0 -10
  46. package/dist/daemon/reconcilers/node-lifecycle/tick.d.ts +2 -2
  47. package/dist/daemon/reconcilers/node-lifecycle/tick.js +4 -2
  48. package/dist/daemon/reconcilers/storage-maintenance.js +2 -2
  49. package/dist/daemon/review/comment-notify.d.ts +1 -0
  50. package/dist/daemon/review/comment-notify.js +1 -0
  51. package/dist/pi-extensions/broker-local.d.ts +1 -0
  52. package/dist/pi-extensions/broker-local.js +12 -7
  53. package/dist/pi-extensions/canvas-recap.js +1 -0
  54. package/dist/pi-extensions/canvas-stophook.js +2 -0
  55. package/package.json +1 -1
  56. package/runtime.lock.json +2 -2
@@ -65,6 +65,7 @@ export interface BrokerExtensionNodeDTO {
65
65
  node_id: string;
66
66
  name: string;
67
67
  description?: string;
68
+ title?: string;
68
69
  icon?: string;
69
70
  kind: string;
70
71
  mode: 'base' | 'orchestrator';
@@ -124,26 +125,30 @@ export interface BrokerExtensionStateDTO {
124
125
  export type BrokerGeneratedNameRequest = {
125
126
  kind: 'initial';
126
127
  description: string;
128
+ title: string;
127
129
  icon: string;
128
130
  } | {
129
131
  kind: 'recap';
130
132
  description: string;
133
+ title: string;
131
134
  icon: string;
132
135
  expected: {
133
136
  name: string;
134
137
  description: string;
138
+ title: string;
135
139
  icon: string;
136
140
  kind: string;
137
141
  };
138
142
  };
139
143
  /** A daemon-selected Pi editor-label directive. No handler calls a broker.
140
- * `description`/`icon` are the values as STORED (an empty icon is left unset),
141
- * so the broker announces what the node now carries rather than what it asked
142
- * for. All three are present exactly when `applied`. */
144
+ * `description`/`title`/`icon` are the values as STORED (an empty title or icon
145
+ * is left unset), so the broker announces what the node now carries rather than
146
+ * what it asked for. All four are present exactly when `applied`. */
143
147
  export interface BrokerGeneratedNameResultDTO {
144
148
  applied: boolean;
145
149
  editorLabel?: string;
146
150
  description?: string;
151
+ title?: string;
147
152
  icon?: string;
148
153
  }
149
154
  export interface BrokerPersonaAckRequest {
@@ -55,12 +55,14 @@ export interface BrokerWelcomeFrame<M = unknown> {
55
55
  * It exists because the name lands SECONDS AFTER the turn that triggered it — a
56
56
  * consumer that settles its own display state on turn-end reads an unnamed node and
57
57
  * has nothing left to re-read on. This frame is the push: `description` is the
58
- * 3-8 word kebab-case handle, `icon` the Nerd Font glyph the namer chose (empty
59
- * when it chose none), and `editorLabel` crtrd's own rendered label for the node.
58
+ * 3-8 word kebab-case handle, `title` the prose sentence a conversation list
59
+ * shows, `icon` the Nerd Font glyph the namer chose (empty when it chose none),
60
+ * and `editorLabel` crtrd's own rendered label for the node.
60
61
  */
61
62
  export interface BrokerNodeNamedFrame {
62
63
  type: 'node_named';
63
64
  description: string;
65
+ title: string;
64
66
  icon: string;
65
67
  editorLabel: string;
66
68
  }
@@ -162,6 +162,7 @@ export interface PageFeedbackDeliveryDTO {
162
162
  status: 'delivered' | 'failed';
163
163
  via?: 'engine' | 'inbox';
164
164
  woke: boolean;
165
+ reason?: 'capacity_frozen';
165
166
  error?: string;
166
167
  }
167
168
  /** Create result: the new comment, the ticket's full feedback state after it,
@@ -166,6 +166,10 @@ export interface NodeFaultDTO {
166
166
  * `GET /v1/nodes/{id}` and by the create/lifecycle actions that yield a node. */
167
167
  export interface NodeDetailDTO extends NodeSummaryDTO {
168
168
  description?: string;
169
+ /** The namer's prose form of `description` — sentence case, punctuation intact
170
+ * (`NodeMeta.title`). What a surface showing this node to a person reads;
171
+ * absent on a node named before titles existed. */
172
+ title?: string;
169
173
  /** The Nerd Font glyph the namer chose for this node's work, when it has one
170
174
  * (`NodeMeta.icon`). Rendered ahead of the label by surfaces that want it. */
171
175
  icon?: string;
@@ -63,6 +63,7 @@ export interface ReviewCommentDeliveryDTO {
63
63
  status: 'delivered' | 'skipped' | 'failed';
64
64
  via?: 'engine' | 'inbox';
65
65
  woke: boolean;
66
+ reason?: 'capacity_frozen';
66
67
  error?: string;
67
68
  }
68
69
  /** Daemon-derived result of one comment mutation. */
@@ -62,7 +62,7 @@ Then advance. Reshape the phases themselves only when reality invalidates the pl
62
62
 
63
63
  ## Delegating
64
64
 
65
- How to write a child's prompt lives on `crtr node new -h`, read at the moment you spawn; this kernel owns the split and the management. Break the goal into units each small enough for one child to finish well in one window, and route findings across children: you are the relay point for everything your children report up, so when a child's task depends on an explore report, design, or spec an earlier child produced, hand that artifact into the new task. When a bounded unit itself contains enough independent work for worthwhile parallelism, create it directly as a sub-orchestrator (`crtr node new --kind <kind> --mode orchestrator`); when it is sequential, assign it to a base child that can yield across windows rather than relying on promotion.
65
+ How to write a child's prompt lives on `crtr node new -h`, read at the moment you spawn; this kernel owns the split and the management. Break the goal into units each small enough for one child to finish well in one window, and route findings across children: you are the relay point for everything your children report up, so when a child's task depends on an explore report, design, or spec an earlier child produced, hand that artifact into the new task. When a bounded unit itself contains enough independent work for worthwhile parallelism, create it directly as a sub-orchestrator (`crtr node new --kind <kind> --mode orchestrator`); when it is sequential, assign it to a base child that can yield across windows rather than relying on promotion. Fanning out many base children of your own kind is your job, not grounds for another coordinator: a sub-orchestrator of your own kind usually just recreates you one window poorer, so reserve sub-orchestrators for a unit of a different kind or a sub-goal genuinely too large for one layer.
66
66
 
67
67
  Every child's task must be a proper subset of your goal. Handing your whole remaining assignment to one child is recursion, not delegation — it recreates you one window poorer, and repeated once per window it builds a chain of managers with no worker. When a unit cannot be split and cannot run in parallel — a sole-writer implementation, one tightly interlocked surface — it is yours: work it hands-on and yield to continue across windows; hands-on work on an unsplittable unit is orchestration done right, not a lost plot.
68
68
 
@@ -171,7 +171,10 @@ export function launchProfileFileSearch(opts) {
171
171
  // horizontally scrolls against the same text — a hidden field would be
172
172
  // unsearchable, and a display slice would silently narrow the query.
173
173
  const yankPath = 'printf \'%s\' {} | { if command -v pbcopy >/dev/null 2>&1; then pbcopy; elif command -v wl-copy >/dev/null 2>&1; then wl-copy; elif command -v xclip >/dev/null 2>&1; then xclip -selection clipboard; else cat >/dev/null; fi; }; printf \'%s\' {} | tmux load-buffer -w -';
174
- const command = `{ ${scans.map((scan) => `${scan} &`).join(' ')} wait; } > ${shellQuote(candidates)} && ${shellQuote(fzf)} --print0 --scheme=path --hscroll-off=${HSCROLL_OFF} --header ${shellQuote('fuzzy path • ctrl-y yank file path')} --bind ${shellQuote(`ctrl-y:execute-silent(${yankPath})`)} --preview ${shellQuote('head -100 -- {}')} < ${shellQuote(candidates)} > ${shellQuote(selected)}`;
174
+ // `+abort` closes the popup the instant the path is copied — without it the
175
+ // silent yank leaves the popup unchanged and reads as a dead key. Aborting
176
+ // writes no selection, so the caller opens no file and just cleans up.
177
+ const command = `{ ${scans.map((scan) => `${scan} &`).join(' ')} wait; } > ${shellQuote(candidates)} && ${shellQuote(fzf)} --print0 --scheme=path --hscroll-off=${HSCROLL_OFF} --header ${shellQuote('fuzzy path • ctrl-y yank file path')} --bind ${shellQuote(`ctrl-y:execute-silent(${yankPath})+abort`)} --preview ${shellQuote('head -100 -- {}')} < ${shellQuote(candidates)} > ${shellQuote(selected)}`;
175
178
  try {
176
179
  execFile('tmux', ['display-popup', '-E', '-T', ' profile files ', '-w', '80%', '-h', '60%', ...surfaceTmuxStyleArgs(), command], () => {
177
180
  const file = selectionPath(selected);