@crouton-kit/crouter 0.3.14 → 0.3.16

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 (224) hide show
  1. package/dist/build-root.d.ts +8 -0
  2. package/dist/build-root.js +30 -0
  3. package/dist/builtin-personas/design/base.md +3 -7
  4. package/dist/builtin-personas/design/orchestrator.md +4 -3
  5. package/dist/builtin-personas/developer/base.md +3 -7
  6. package/dist/builtin-personas/developer/orchestrator.md +5 -4
  7. package/dist/builtin-personas/explore/base.md +3 -7
  8. package/dist/builtin-personas/explore/orchestrator.md +1 -5
  9. package/dist/builtin-personas/general/base.md +2 -4
  10. package/dist/builtin-personas/general/orchestrator.md +2 -4
  11. package/dist/builtin-personas/lifecycle/resident.md +2 -0
  12. package/dist/builtin-personas/lifecycle/terminal.md +6 -0
  13. package/dist/builtin-personas/orchestration-kernel.md +42 -3
  14. package/dist/builtin-personas/plan/base.md +3 -5
  15. package/dist/builtin-personas/plan/orchestrator.md +5 -4
  16. package/dist/builtin-personas/plan/reviewers/architecture-fit/base.md +9 -0
  17. package/dist/builtin-personas/plan/reviewers/code-smells/base.md +9 -0
  18. package/dist/builtin-personas/plan/reviewers/pattern-consistency/base.md +9 -0
  19. package/dist/builtin-personas/plan/reviewers/requirements-coverage/base.md +9 -0
  20. package/dist/builtin-personas/plan/reviewers/security/base.md +9 -0
  21. package/dist/builtin-personas/review/base.md +3 -5
  22. package/dist/builtin-personas/review/orchestrator.md +2 -6
  23. package/dist/builtin-personas/runtime-base.md +3 -19
  24. package/dist/builtin-personas/spec/base.md +3 -5
  25. package/dist/builtin-personas/spec/orchestrator.md +4 -3
  26. package/dist/builtin-personas/spine/has-manager.md +10 -0
  27. package/dist/builtin-personas/spine/no-manager.md +2 -0
  28. package/dist/builtin-skills/skills/crouter-development/personas/SKILL.md +96 -0
  29. package/dist/builtin-skills/skills/crouter-development/personas/base-prompt/SKILL.md +49 -0
  30. package/dist/builtin-skills/skills/crouter-development/personas/orchestrator-prompt/SKILL.md +49 -0
  31. package/dist/builtin-skills/skills/planning/SKILL.md +1 -1
  32. package/dist/builtin-skills/skills/spec/SKILL.md +2 -2
  33. package/dist/cli.js +6 -29
  34. package/dist/commands/attention.js +76 -7
  35. package/dist/commands/canvas-prune.d.ts +2 -0
  36. package/dist/commands/canvas-prune.js +66 -0
  37. package/dist/commands/canvas.js +5 -8
  38. package/dist/commands/chord.d.ts +2 -0
  39. package/dist/commands/chord.js +143 -0
  40. package/dist/commands/daemon.js +8 -5
  41. package/dist/commands/dashboard.js +2 -0
  42. package/dist/commands/human/prompts.js +28 -27
  43. package/dist/commands/human/queue.js +30 -14
  44. package/dist/commands/human/shared.d.ts +26 -21
  45. package/dist/commands/human/shared.js +45 -67
  46. package/dist/commands/human.js +4 -14
  47. package/dist/commands/node.d.ts +11 -0
  48. package/dist/commands/node.js +221 -99
  49. package/dist/commands/pkg/market-inspect.js +6 -4
  50. package/dist/commands/pkg/market-manage.js +10 -6
  51. package/dist/commands/pkg/market.js +2 -4
  52. package/dist/commands/pkg/plugin-inspect.js +6 -4
  53. package/dist/commands/pkg/plugin-manage.js +12 -7
  54. package/dist/commands/pkg/plugin.js +2 -4
  55. package/dist/commands/pkg.js +0 -4
  56. package/dist/commands/push.js +178 -15
  57. package/dist/commands/revive.js +5 -3
  58. package/dist/commands/skill/author.js +6 -4
  59. package/dist/commands/skill/find.js +8 -5
  60. package/dist/commands/skill/read.js +2 -0
  61. package/dist/commands/skill/state.js +6 -4
  62. package/dist/commands/skill.js +0 -6
  63. package/dist/commands/sys/config.js +21 -7
  64. package/dist/commands/sys/doctor.js +2 -0
  65. package/dist/commands/sys/update.js +4 -0
  66. package/dist/commands/sys.js +0 -6
  67. package/dist/commands/tmux-spread.d.ts +2 -0
  68. package/dist/commands/tmux-spread.js +129 -0
  69. package/dist/core/__tests__/canvas-inbox-watcher.test.js +25 -0
  70. package/dist/core/__tests__/child-followup.test.d.ts +1 -0
  71. package/dist/core/__tests__/child-followup.test.js +83 -0
  72. package/dist/core/__tests__/close.test.d.ts +1 -0
  73. package/dist/core/__tests__/close.test.js +148 -0
  74. package/dist/core/__tests__/context-intro.test.d.ts +1 -0
  75. package/dist/core/__tests__/context-intro.test.js +196 -0
  76. package/dist/core/__tests__/daemon-boot.test.d.ts +1 -0
  77. package/dist/core/__tests__/daemon-boot.test.js +93 -0
  78. package/dist/core/__tests__/daemon-liveness.test.d.ts +1 -0
  79. package/dist/core/__tests__/daemon-liveness.test.js +223 -0
  80. package/dist/core/__tests__/focuses.test.d.ts +1 -0
  81. package/dist/core/__tests__/focuses.test.js +196 -0
  82. package/dist/core/__tests__/fork.test.d.ts +1 -0
  83. package/dist/core/__tests__/fork.test.js +91 -0
  84. package/dist/core/__tests__/home-session.test.d.ts +1 -0
  85. package/dist/core/__tests__/home-session.test.js +153 -0
  86. package/dist/core/__tests__/human-cancel-guard.test.d.ts +1 -0
  87. package/dist/core/__tests__/human-cancel-guard.test.js +49 -0
  88. package/dist/core/__tests__/keystone.test.d.ts +1 -0
  89. package/dist/core/__tests__/keystone.test.js +185 -0
  90. package/dist/core/__tests__/kickoff.test.d.ts +1 -0
  91. package/dist/core/__tests__/kickoff.test.js +89 -0
  92. package/dist/core/__tests__/lifecycle.test.d.ts +1 -0
  93. package/dist/core/__tests__/lifecycle.test.js +178 -0
  94. package/dist/core/__tests__/listing-completeness.test.d.ts +1 -0
  95. package/dist/core/__tests__/listing-completeness.test.js +31 -0
  96. package/dist/core/__tests__/memory.test.d.ts +1 -0
  97. package/dist/core/__tests__/memory.test.js +152 -0
  98. package/dist/core/__tests__/migration.test.d.ts +1 -0
  99. package/dist/core/__tests__/migration.test.js +238 -0
  100. package/dist/core/__tests__/pane-column.test.d.ts +1 -0
  101. package/dist/core/__tests__/pane-column.test.js +153 -0
  102. package/dist/core/__tests__/passive-subscription.test.js +24 -1
  103. package/dist/core/__tests__/persona-compose.test.d.ts +1 -0
  104. package/dist/core/__tests__/persona-compose.test.js +53 -0
  105. package/dist/core/__tests__/persona-subkind.test.d.ts +1 -0
  106. package/dist/core/__tests__/persona-subkind.test.js +62 -0
  107. package/dist/core/__tests__/persona.test.d.ts +1 -0
  108. package/dist/core/__tests__/persona.test.js +107 -0
  109. package/dist/core/__tests__/placement-focus.test.d.ts +1 -0
  110. package/dist/core/__tests__/placement-focus.test.js +266 -0
  111. package/dist/core/__tests__/placement-reconcile.test.d.ts +1 -0
  112. package/dist/core/__tests__/placement-reconcile.test.js +212 -0
  113. package/dist/core/__tests__/placement-revive.test.d.ts +1 -0
  114. package/dist/core/__tests__/placement-revive.test.js +238 -0
  115. package/dist/core/__tests__/placement-teardown.test.d.ts +1 -0
  116. package/dist/core/__tests__/placement-teardown.test.js +178 -0
  117. package/dist/core/__tests__/prune.test.d.ts +1 -0
  118. package/dist/core/__tests__/prune.test.js +116 -0
  119. package/dist/core/__tests__/push-final-guard.test.d.ts +1 -0
  120. package/dist/core/__tests__/push-final-guard.test.js +71 -0
  121. package/dist/core/__tests__/relaunch.test.d.ts +1 -0
  122. package/dist/core/__tests__/relaunch.test.js +334 -0
  123. package/dist/core/__tests__/reset.test.js +26 -7
  124. package/dist/core/__tests__/revive.test.d.ts +1 -0
  125. package/dist/core/__tests__/revive.test.js +217 -0
  126. package/dist/core/__tests__/spawn-root.test.d.ts +1 -0
  127. package/dist/core/__tests__/spawn-root.test.js +73 -0
  128. package/dist/core/__tests__/steer-note.test.d.ts +1 -0
  129. package/dist/core/__tests__/steer-note.test.js +39 -0
  130. package/dist/core/__tests__/stop-guard.test.d.ts +1 -0
  131. package/dist/core/__tests__/stop-guard.test.js +82 -0
  132. package/dist/core/__tests__/subcommand-tier.test.js +35 -33
  133. package/dist/core/__tests__/tmux-surface.test.d.ts +1 -0
  134. package/dist/core/__tests__/tmux-surface.test.js +105 -0
  135. package/dist/core/__tests__/unknown-path.test.js +8 -2
  136. package/dist/core/canvas/attention.d.ts +10 -0
  137. package/dist/core/canvas/attention.js +40 -0
  138. package/dist/core/canvas/canvas.d.ts +66 -7
  139. package/dist/core/canvas/canvas.js +209 -21
  140. package/dist/core/canvas/db.d.ts +8 -0
  141. package/dist/core/canvas/db.js +205 -4
  142. package/dist/core/canvas/focuses.d.ts +22 -0
  143. package/dist/core/canvas/focuses.js +81 -0
  144. package/dist/core/canvas/index.d.ts +3 -0
  145. package/dist/core/canvas/index.js +3 -0
  146. package/dist/core/canvas/labels.d.ts +27 -0
  147. package/dist/core/canvas/labels.js +36 -0
  148. package/dist/core/canvas/render.js +25 -10
  149. package/dist/core/canvas/telemetry.d.ts +14 -0
  150. package/dist/core/canvas/telemetry.js +35 -0
  151. package/dist/core/canvas/types.d.ts +115 -12
  152. package/dist/core/command.d.ts +25 -1
  153. package/dist/core/command.js +23 -15
  154. package/dist/core/config.js +36 -2
  155. package/dist/core/feed/feed.js +3 -3
  156. package/dist/core/feed/inbox.d.ts +3 -1
  157. package/dist/core/feed/inbox.js +45 -5
  158. package/dist/core/feed/passive.js +24 -11
  159. package/dist/core/help.d.ts +26 -13
  160. package/dist/core/help.js +44 -37
  161. package/dist/core/personas/index.d.ts +1 -1
  162. package/dist/core/personas/index.js +1 -1
  163. package/dist/core/personas/loader.d.ts +40 -1
  164. package/dist/core/personas/loader.js +63 -1
  165. package/dist/core/personas/resolve.d.ts +13 -6
  166. package/dist/core/personas/resolve.js +46 -34
  167. package/dist/core/runtime/bearings.d.ts +20 -0
  168. package/dist/core/runtime/bearings.js +92 -0
  169. package/dist/core/runtime/close.d.ts +14 -0
  170. package/dist/core/runtime/close.js +151 -0
  171. package/dist/core/runtime/demote.js +24 -12
  172. package/dist/core/runtime/front-door.js +1 -1
  173. package/dist/core/runtime/kickoff.d.ts +23 -6
  174. package/dist/core/runtime/kickoff.js +92 -36
  175. package/dist/core/runtime/launch.d.ts +26 -12
  176. package/dist/core/runtime/launch.js +78 -19
  177. package/dist/core/runtime/lifecycle.d.ts +13 -0
  178. package/dist/core/runtime/lifecycle.js +86 -0
  179. package/dist/core/runtime/memory.d.ts +43 -0
  180. package/dist/core/runtime/memory.js +165 -0
  181. package/dist/core/runtime/naming.d.ts +22 -0
  182. package/dist/core/runtime/naming.js +166 -0
  183. package/dist/core/runtime/nodes.d.ts +39 -1
  184. package/dist/core/runtime/nodes.js +69 -10
  185. package/dist/core/runtime/persona.d.ts +25 -0
  186. package/dist/core/runtime/persona.js +139 -0
  187. package/dist/core/runtime/placement.d.ts +299 -0
  188. package/dist/core/runtime/placement.js +688 -0
  189. package/dist/core/runtime/promote.d.ts +14 -7
  190. package/dist/core/runtime/promote.js +57 -67
  191. package/dist/core/runtime/reset.d.ts +47 -4
  192. package/dist/core/runtime/reset.js +223 -52
  193. package/dist/core/runtime/revive.d.ts +26 -2
  194. package/dist/core/runtime/revive.js +166 -39
  195. package/dist/core/runtime/spawn.d.ts +20 -5
  196. package/dist/core/runtime/spawn.js +163 -43
  197. package/dist/core/runtime/stop-guard.d.ts +1 -1
  198. package/dist/core/runtime/stop-guard.js +18 -8
  199. package/dist/core/runtime/tmux-chrome.d.ts +1 -0
  200. package/dist/core/runtime/tmux-chrome.js +4 -0
  201. package/dist/core/runtime/tmux.d.ts +113 -20
  202. package/dist/core/runtime/tmux.js +221 -39
  203. package/dist/core/spawn.js +15 -0
  204. package/dist/daemon/crtrd.d.ts +12 -1
  205. package/dist/daemon/crtrd.js +152 -34
  206. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.d.ts +1 -0
  207. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +266 -0
  208. package/dist/pi-extensions/canvas-commands.js +16 -13
  209. package/dist/pi-extensions/canvas-context-intro.d.ts +70 -0
  210. package/dist/pi-extensions/canvas-context-intro.js +164 -0
  211. package/dist/pi-extensions/canvas-goal-capture.d.ts +3 -0
  212. package/dist/pi-extensions/canvas-goal-capture.js +15 -1
  213. package/dist/pi-extensions/canvas-inbox-watcher.js +11 -0
  214. package/dist/pi-extensions/canvas-nav.d.ts +12 -4
  215. package/dist/pi-extensions/canvas-nav.js +594 -262
  216. package/dist/pi-extensions/canvas-resume.d.ts +22 -0
  217. package/dist/pi-extensions/canvas-resume.js +173 -0
  218. package/dist/pi-extensions/canvas-stophook.d.ts +16 -0
  219. package/dist/pi-extensions/canvas-stophook.js +340 -228
  220. package/dist/types.d.ts +28 -0
  221. package/dist/types.js +16 -0
  222. package/package.json +2 -2
  223. package/dist/core/runtime/presence.d.ts +0 -38
  224. package/dist/core/runtime/presence.js +0 -154
@@ -1,14 +1,12 @@
1
1
  import { readConfig } from '../../core/config.js';
2
2
  import { spawnSync } from 'node:child_process';
3
- import { existsSync, readdirSync, readFileSync } from 'node:fs';
4
3
  import { join } from 'node:path';
5
4
  import { atomicWriteJson, readJson } from '@crouton-kit/humanloop';
6
5
  import { countPanesInCurrentWindow, spawnAndDetach, shellQuote } from '../../core/spawn.js';
7
- import { reportsDir } from '../../core/canvas/paths.js';
8
6
  export const DECK_SCHEMA_HINT = 'Deck must match the humanloop deck schema: {title?, ' +
9
7
  'source?:{sessionName?,askedBy?,blockedSince?}, ' +
10
8
  'interactions:[{id,title,subtitle?,(body?|bodyPath?),options:[{id,label,' +
11
- 'description?,shortcut?}],multiSelect?,allowFreetext?,freetextLabel?,' +
9
+ 'description?}],multiSelect?,allowFreetext?,freetextLabel?,' +
12
10
  "kind?:'notify'|'validation'|'decision'|'context'|'error'}]}.";
13
11
  export function resolveMaxPanes() {
14
12
  return readConfig('user').max_panes_per_window;
@@ -26,17 +24,31 @@ export function followUpDrain(_jobId) {
26
24
  return ('Not in tmux: a human must drain it — run `crtr human inbox` (or re-run ' +
27
25
  'inside tmux). The answer then arrives in your inbox.');
28
26
  }
27
+ /**
28
+ * Road sign for a spawned `human review`. It is a non-blocking kickoff, so the
29
+ * text steers the caller to stop rather than wait, verify, or re-present: the
30
+ * pane is already live and tracks the file, and the comments arrive via the
31
+ * inbox/wake when the human submits.
32
+ */
33
+ export function followUpReview(_jobId) {
34
+ return ("The document is live on the human's screen for anchored, line-by-line " +
35
+ 'review. The pane tracks the file — edit the .md in place and it re-renders ' +
36
+ 'on save, so never cancel and re-present just to show a change. Do not poll, ' +
37
+ 'verify it opened, or background this call; end your turn. The human reviews ' +
38
+ 'on their own time, and their comments (with any line edits) arrive in your ' +
39
+ 'inbox and wake you when they submit.');
40
+ }
29
41
  /**
30
42
  * Spawn the detached `_run` pane that drives the humanloop TUI for this node.
31
- * Returns whether the pane spawned, the follow_up text, and (when spawned) the
32
- * tmux pane id so a blocking caller (review) can detect the pane dying before
33
- * the human submits. Degrades to the inbox-drain follow_up when not in tmux /
34
- * spawn fails — kickoffs are intentionally non-fatal off-tmux.
43
+ * Returns whether the pane spawned and the follow_up road sign. Degrades to the
44
+ * inbox-drain follow_up when not in tmux / spawn fails kickoffs are
45
+ * intentionally non-fatal off-tmux.
35
46
  *
36
47
  * Completion routing needs no bookkeeping here: the human node was created
37
48
  * under the asking node as its parent (spawnNode auto-subscribes the parent),
38
- * so the `pushFinal` the `_run` worker emits fans the answer straight into the
39
- * asking node's inbox.
49
+ * so the `pushFinal` the `_run` worker emits for ask, approve, AND review —
50
+ * fans the answer straight into the asking node's inbox. The pane id is recorded
51
+ * on run.json (not returned) so `human cancel` can later kill the TUI.
40
52
  */
41
53
  export function spawnHumanJob(jobId, idir, cwd) {
42
54
  const spawn = spawnAndDetach({
@@ -57,66 +69,32 @@ export function spawnHumanJob(jobId, idir, cwd) {
57
69
  if (rc !== null)
58
70
  atomicWriteJson(rcPath, { ...rc, pane_id: spawn.paneId });
59
71
  }
60
- return {
61
- spawned: true,
62
- follow_up: followUpResult(jobId),
63
- ...(spawn.paneId !== undefined ? { paneId: spawn.paneId } : {}),
64
- };
65
- }
66
- /** Best-effort kill of a detached TUI pane. No-op (and never throws) when the
67
- * pane is already gone or tmux is unavailable — `human cancel` is best-effort. */
68
- export function killPane(paneId) {
69
- const r = spawnSync('tmux', ['kill-pane', '-t', paneId], { encoding: 'utf8' });
70
- return r.status === 0;
71
- }
72
- /** True when a tmux pane is still alive. */
73
- function paneAlive(paneId) {
74
- const r = spawnSync('tmux', ['display-message', '-p', '-t', paneId, '#{pane_id}'], {
75
- encoding: 'utf8',
76
- });
77
- return r.status === 0 && r.stdout.trim() !== '';
72
+ return { spawned: true, follow_up: followUpResult(jobId) };
78
73
  }
79
74
  /**
80
- * Block until `nodeId` emits a `final` report (the human submitted) or — when a
81
- * pane id is given that pane dies before submitting (the human closed it).
82
- * Polls once a second: this is a human-time operation, so a coarse poll is fine
83
- * and sidesteps fs.watch directory-existence races. The `_run` worker writes
84
- * the humanloop result as the report body (JSON), which we parse back out.
75
+ * Best-effort kill of a humanloop worker pane. SAFETY-CRITICAL: a malformed or
76
+ * empty `-t` target makes tmux fall back to the CALLER's current pane, so a bad
77
+ * paneId could kill the agent's own pi pane (and, if it is the last pane, the
78
+ * whole session). This refuses to kill anything that is not provably the worker:
79
+ *
80
+ * 1. paneId must be a real tmux pane id (`%<n>`) — never an empty/odd string.
81
+ * 2. The pane's start command must contain `verify` (the interaction dir, which
82
+ * humanloop bakes into the worker's `CRTR_HUMAN_DIR=... crtr human _run`
83
+ * launch). A shell (`zsh -l`) or the agent's pi never matches, so we can
84
+ * only ever kill the exact worker we spawned for this job.
85
+ *
86
+ * Returns true only when a matching pane was found and killed. Never throws.
85
87
  */
86
- export function waitForFinalReport(nodeId, paneId) {
87
- const dir = reportsDir(nodeId);
88
- const findFinal = () => {
89
- if (!existsSync(dir))
90
- return null;
91
- const files = readdirSync(dir).filter((f) => f.endsWith('-final.md')).sort();
92
- return files.length > 0 ? join(dir, files[files.length - 1]) : null;
93
- };
94
- const parse = (path) => {
95
- const body = readFileSync(path, 'utf8').replace(/^---[\s\S]*?---\n/, '').trim();
96
- try {
97
- return { status: 'done', result: JSON.parse(body) };
98
- }
99
- catch {
100
- return { status: 'done' };
101
- }
102
- };
103
- const immediate = findFinal();
104
- if (immediate !== null)
105
- return Promise.resolve(parse(immediate));
106
- return new Promise((resolve) => {
107
- const timer = setInterval(() => {
108
- const p = findFinal();
109
- if (p !== null) {
110
- clearInterval(timer);
111
- resolve(parse(p));
112
- return;
113
- }
114
- if (paneId !== undefined && !paneAlive(paneId)) {
115
- clearInterval(timer);
116
- resolve({ status: 'closed', reason: 'review pane closed before submit' });
117
- }
118
- }, 1000);
119
- if (typeof timer.unref === 'function')
120
- timer.unref();
88
+ export function killPane(paneId, verify) {
89
+ if (!/^%\d+$/.test(paneId))
90
+ return false;
91
+ const probe = spawnSync('tmux', ['display-message', '-p', '-t', paneId, '#{pane_start_command}'], {
92
+ encoding: 'utf8',
121
93
  });
94
+ // Pane is gone (status !== 0) → nothing to kill. Pane exists but its launch
95
+ // command doesn't carry our interaction dir → it is NOT our worker; refuse.
96
+ if (probe.status !== 0 || !probe.stdout.includes(verify))
97
+ return false;
98
+ const r = spawnSync('tmux', ['kill-pane', '-t', paneId], { encoding: 'utf8' });
99
+ return r.status === 0;
122
100
  }
@@ -18,24 +18,14 @@ export function registerHuman() {
18
18
  return defineBranch({
19
19
  name: 'human',
20
20
  rootEntry: {
21
- concept: 'human-in-the-loop decisions, document review, and live display: ask puts a structured choice to a person, approve gates a handoff on a Yes/No sign-off, review collects anchored comments on a plan or spec, notify informs without blocking, show puts a file live on screen',
21
+ concept: 'human-in-the-loop decisions, document review, and live display',
22
22
  desc: 'ask, approve, review, notify, show, cancel, inbox, list',
23
- useWhen: 'you have a question for the user or want their feedback — always reach for human instead of guessing or assuming when a person can decide',
23
+ useWhen: 'you have a question for the user, want their feedback, or are presenting them with options or a choice — always reach for human instead of guessing or assuming, or laying a choice out as prose, when a person can decide; and whenever the user wants to review a spec, plan, or requirements document, this is the command (use `human review` for anchored line-by-line comments)'
24
24
  },
25
25
  help: {
26
26
  name: 'human',
27
27
  summary: 'human-in-the-loop decisions, document review, and live display',
28
- model: "Reach for human whenever you have a question for the user or want their feedback — never guess or assume when a person can decide. ask puts a structured choice in front of them; approve gates a handoff on a Yes/No sign-off; review collects anchored comments on a plan or spec; notify informs without blocking; show puts a file live on screen. Every body and displayed file is directive-flavored markdown rendered by termrender (panels, columns, trees, callouts, mermaid) — see `termrender doc -h` for the directive set before authoring one. ask/approve/review are the DEFAULT channel for questions, sign-offs, and feedback — reach for them even for quick or open-ended asks (use `allowFreetext`), and don't substitute prose in your reply. ask and approve are kickoffs: they create a kind:'human' node under you and return instantly, never blocking — the answer is pushed to your inbox when the human responds, so just keep working and you'll be woken with it. review is different: it BLOCKS until the human submits, so background the call if you want to keep working (your harness notifies you when it finishes). 'Humans respond on human time' describes response latency only — it is never a reason to avoid asking. notify/show create no node.",
29
- children: [
30
- { name: 'ask', desc: 'put a decision deck to a person', useWhen: 'a structured choice needs a human' },
31
- { name: 'approve', desc: 'a Yes/No approval gate', useWhen: 'gating a handoff on human sign-off' },
32
- { name: 'review', desc: 'anchored-comment review of a .md', useWhen: 'a human should comment on a plan or spec' },
33
- { name: 'notify', desc: 'fire-and-forget acknowledgement', useWhen: 'informing a person without blocking' },
34
- { name: 'show', desc: 'put a file live on screen', useWhen: 'displaying a doc while a human comments' },
35
- { name: 'cancel', desc: 'retract a pending ask/approve/review', useWhen: 'a question went stale before the human answered' },
36
- { name: 'inbox', desc: 'interactively drain pending interactions', useWhen: 'a human clears the queue at their terminal' },
37
- { name: 'list', desc: 'enumerate pending interactions', useWhen: 'discovering what is blocked on a human' },
38
- ],
28
+ model: "Every body and displayed file is directive-flavored markdown rendered by termrender (panels, columns, trees, callouts, mermaid) — see `termrender doc -h` for the directive set before authoring one. ask, approve, and review are kickoffs: they create a kind:'human' node under you and return instantly, never blocking — the human's response is pushed to your inbox when they answer, so keep working (or just end your turn) and you'll be woken with it. review puts a .md live on the human's screen for anchored comments and tracks the file, so edit in place rather than canceling and re-presenting. notify and show create no node.",
39
29
  },
40
30
  children: [
41
31
  humanAsk,
@@ -43,9 +33,9 @@ export function registerHuman() {
43
33
  humanReview,
44
34
  humanNotify,
45
35
  humanShow,
36
+ humanCancel,
46
37
  humanInbox,
47
38
  humanList,
48
- humanCancel,
49
39
  humanRun,
50
40
  ],
51
41
  });
@@ -1,2 +1,13 @@
1
1
  import { type BranchDef } from '../core/command.js';
2
+ /** Decision road sign for a managed (non-root) child. Normally STD_CHILD_FOLLOW_UP,
3
+ * but when the SPAWNER is an orchestrator whose context has already grown past
4
+ * YIELD_NUDGE_THRESHOLD, steer it to yield now and let its fresh revive handle
5
+ * the child's result. */
6
+ export declare function childFollowUp(spawnerId: string | undefined): string;
7
+ /** The live node occupying a tmux pane (pane → window → node), or undefined.
8
+ * Defaults to $TMUX_PANE / the caller's current pane when `pane` is omitted —
9
+ * shared by `node demote` and `node cycle`, both of which act on "the agent in
10
+ * front of you". Exported for the `canvas chord` / `canvas tmux-spread` leaves,
11
+ * which resolve the active pane's node the same way. */
12
+ export declare function nodeInPane(pane?: string): string | undefined;
2
13
  export declare function registerNode(): BranchDef;