@lumenflow/cli 4.24.0 → 5.0.1

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 (287) hide show
  1. package/README.md +54 -52
  2. package/dist/agent-issues-query.js +10 -2
  3. package/dist/agent-issues-query.js.map +1 -1
  4. package/dist/agent-runtime-enrollment-events.js +44 -0
  5. package/dist/agent-runtime-enrollment-events.js.map +1 -0
  6. package/dist/agent-session-end.js +47 -0
  7. package/dist/agent-session-end.js.map +1 -1
  8. package/dist/agent-session-heartbeat.js +250 -0
  9. package/dist/agent-session-heartbeat.js.map +1 -0
  10. package/dist/agent-session.js +299 -5
  11. package/dist/agent-session.js.map +1 -1
  12. package/dist/capacity-snapshot-emitter.js +73 -0
  13. package/dist/capacity-snapshot-emitter.js.map +1 -0
  14. package/dist/claim-queue.js +276 -0
  15. package/dist/claim-queue.js.map +1 -0
  16. package/dist/config-set.js +22 -3
  17. package/dist/config-set.js.map +1 -1
  18. package/dist/control-plane-sidecar-runner.js +145 -0
  19. package/dist/control-plane-sidecar-runner.js.map +1 -0
  20. package/dist/delegation-list.js +160 -1
  21. package/dist/delegation-list.js.map +1 -1
  22. package/dist/delegation-role-resolver.js +69 -0
  23. package/dist/delegation-role-resolver.js.map +1 -0
  24. package/dist/docs-generate-pack-reference.js +500 -0
  25. package/dist/docs-generate-pack-reference.js.map +1 -0
  26. package/dist/docs-sync.js +116 -1
  27. package/dist/docs-sync.js.map +1 -1
  28. package/dist/file-edit.js +28 -8
  29. package/dist/file-edit.js.map +1 -1
  30. package/dist/file-write.js +29 -5
  31. package/dist/file-write.js.map +1 -1
  32. package/dist/gate-co-change.js +25 -7
  33. package/dist/gate-co-change.js.map +1 -1
  34. package/dist/gate-conditional.js +19 -7
  35. package/dist/gate-conditional.js.map +1 -1
  36. package/dist/gates-runners.js +42 -33
  37. package/dist/gates-runners.js.map +1 -1
  38. package/dist/gates-utils.js +34 -20
  39. package/dist/gates-utils.js.map +1 -1
  40. package/dist/gates.js +79 -7
  41. package/dist/gates.js.map +1 -1
  42. package/dist/hooks/config-resolver.js +10 -1
  43. package/dist/hooks/config-resolver.js.map +1 -1
  44. package/dist/init-package-config.js +1 -1
  45. package/dist/init-package-config.js.map +1 -1
  46. package/dist/init-scaffolding.js +5 -1
  47. package/dist/init-scaffolding.js.map +1 -1
  48. package/dist/init-templates.js +10 -0
  49. package/dist/init-templates.js.map +1 -1
  50. package/dist/init.js +1 -1
  51. package/dist/init.js.map +1 -1
  52. package/dist/initiative-create.js +17 -0
  53. package/dist/initiative-create.js.map +1 -1
  54. package/dist/initiative-remove-wu.js +17 -3
  55. package/dist/initiative-remove-wu.js.map +1 -1
  56. package/dist/kernel-event-sync/emitters.js +104 -0
  57. package/dist/kernel-event-sync/emitters.js.map +1 -0
  58. package/dist/kernel-event-sync/index.js +13 -0
  59. package/dist/kernel-event-sync/index.js.map +1 -0
  60. package/dist/kernel-event-sync/lifecycle-emitters.js +160 -0
  61. package/dist/kernel-event-sync/lifecycle-emitters.js.map +1 -0
  62. package/dist/kernel-event-sync/narrow-emissions.js +89 -0
  63. package/dist/kernel-event-sync/narrow-emissions.js.map +1 -0
  64. package/dist/kernel-event-sync/software-delivery-emitters.js +297 -0
  65. package/dist/kernel-event-sync/software-delivery-emitters.js.map +1 -0
  66. package/dist/lane-lock.js +14 -1
  67. package/dist/lane-lock.js.map +1 -1
  68. package/dist/lane-suggest.js +21 -0
  69. package/dist/lane-suggest.js.map +1 -1
  70. package/dist/lumenflow-upgrade.js +7 -5
  71. package/dist/lumenflow-upgrade.js.map +1 -1
  72. package/dist/mem-context.js +145 -0
  73. package/dist/mem-context.js.map +1 -1
  74. package/dist/mem-create.js +39 -6
  75. package/dist/mem-create.js.map +1 -1
  76. package/dist/mem-inbox.js +16 -0
  77. package/dist/mem-inbox.js.map +1 -1
  78. package/dist/mem-roster.js +95 -0
  79. package/dist/mem-roster.js.map +1 -0
  80. package/dist/mem-signal.js +97 -2
  81. package/dist/mem-signal.js.map +1 -1
  82. package/dist/metrics-snapshot.js +3 -2
  83. package/dist/metrics-snapshot.js.map +1 -1
  84. package/dist/orchestrate-init-status.js +117 -2
  85. package/dist/orchestrate-init-status.js.map +1 -1
  86. package/dist/orchestrate-initiative.js +83 -10
  87. package/dist/orchestrate-initiative.js.map +1 -1
  88. package/dist/orchestrate-monitor-quality.js +289 -0
  89. package/dist/orchestrate-monitor-quality.js.map +1 -0
  90. package/dist/orchestrate-monitor.js +85 -0
  91. package/dist/orchestrate-monitor.js.map +1 -1
  92. package/dist/pack-validate.js +127 -2
  93. package/dist/pack-validate.js.map +1 -1
  94. package/dist/plan-create.js +18 -0
  95. package/dist/plan-create.js.map +1 -1
  96. package/dist/plan-link.js +13 -0
  97. package/dist/plan-link.js.map +1 -1
  98. package/dist/plan-promote.js +14 -0
  99. package/dist/plan-promote.js.map +1 -1
  100. package/dist/pre-commit-check.js +4 -3
  101. package/dist/pre-commit-check.js.map +1 -1
  102. package/dist/public-manifest.js +17 -3
  103. package/dist/public-manifest.js.map +1 -1
  104. package/dist/release.js +28 -10
  105. package/dist/release.js.map +1 -1
  106. package/dist/session-cross-link.js +139 -0
  107. package/dist/session-cross-link.js.map +1 -0
  108. package/dist/sidecar-manager.js +208 -0
  109. package/dist/sidecar-manager.js.map +1 -0
  110. package/dist/state-path-resolvers.js +18 -0
  111. package/dist/state-path-resolvers.js.map +1 -1
  112. package/dist/stream-heartbeat.js +151 -0
  113. package/dist/stream-heartbeat.js.map +1 -0
  114. package/dist/sync-templates.js +56 -2
  115. package/dist/sync-templates.js.map +1 -1
  116. package/dist/wu-block.js +47 -5
  117. package/dist/wu-block.js.map +1 -1
  118. package/dist/wu-claim-branch.js +8 -4
  119. package/dist/wu-claim-branch.js.map +1 -1
  120. package/dist/wu-claim-state.js +5 -3
  121. package/dist/wu-claim-state.js.map +1 -1
  122. package/dist/wu-claim-worktree.js +5 -3
  123. package/dist/wu-claim-worktree.js.map +1 -1
  124. package/dist/wu-claim.js +261 -9
  125. package/dist/wu-claim.js.map +1 -1
  126. package/dist/wu-done-auto-cleanup.js +3 -2
  127. package/dist/wu-done-auto-cleanup.js.map +1 -1
  128. package/dist/wu-done-git-ops.js +12 -8
  129. package/dist/wu-done-git-ops.js.map +1 -1
  130. package/dist/wu-done-preflight.js +3 -3
  131. package/dist/wu-done-preflight.js.map +1 -1
  132. package/dist/wu-done.js +46 -10
  133. package/dist/wu-done.js.map +1 -1
  134. package/dist/wu-lifecycle-sync/gate-scope-resolver.js +16 -0
  135. package/dist/wu-lifecycle-sync/gate-scope-resolver.js.map +1 -0
  136. package/dist/wu-lifecycle-sync/kernel-event-sync-shim.js +10 -0
  137. package/dist/wu-lifecycle-sync/kernel-event-sync-shim.js.map +1 -0
  138. package/dist/wu-prep.js +363 -22
  139. package/dist/wu-prep.js.map +1 -1
  140. package/dist/wu-prune.js +68 -27
  141. package/dist/wu-prune.js.map +1 -1
  142. package/dist/wu-release.js +34 -3
  143. package/dist/wu-release.js.map +1 -1
  144. package/dist/wu-review.js +167 -0
  145. package/dist/wu-review.js.map +1 -0
  146. package/dist/wu-spawn-prompt-builders.js +296 -40
  147. package/dist/wu-spawn-prompt-builders.js.map +1 -1
  148. package/dist/wu-spawn-strategy-resolver.js +126 -14
  149. package/dist/wu-spawn-strategy-resolver.js.map +1 -1
  150. package/dist/wu-unblock.js +52 -22
  151. package/dist/wu-unblock.js.map +1 -1
  152. package/package.json +13 -8
  153. package/packs/agent-runtime/agent-heartbeat.ts +163 -0
  154. package/packs/agent-runtime/auto-session-integration.ts +874 -0
  155. package/packs/agent-runtime/delegation-registry-schema.ts +220 -0
  156. package/packs/agent-runtime/delegation-registry-store.ts +269 -0
  157. package/packs/agent-runtime/delegation-tree.ts +328 -0
  158. package/packs/agent-runtime/index.ts +9 -0
  159. package/packs/agent-runtime/manifest.ts +109 -19
  160. package/packs/agent-runtime/manifest.yaml +150 -0
  161. package/packs/agent-runtime/memory-coordination-contract.ts +86 -0
  162. package/packs/agent-runtime/memory.d.ts +19 -0
  163. package/packs/agent-runtime/orchestration.ts +238 -23
  164. package/packs/agent-runtime/package.json +11 -2
  165. package/packs/agent-runtime/remote-controls/index.ts +7 -0
  166. package/packs/agent-runtime/remote-controls/operations.ts +399 -0
  167. package/packs/agent-runtime/remote-controls/port.ts +48 -0
  168. package/packs/agent-runtime/remote-controls/state-store.ts +258 -0
  169. package/packs/agent-runtime/remote-controls/types.ts +105 -0
  170. package/packs/agent-runtime/session-schema.ts +423 -0
  171. package/packs/agent-runtime/tool-impl/index.ts +1 -0
  172. package/packs/agent-runtime/tool-impl/remote-controls.mock.ts +252 -0
  173. package/packs/agent-runtime/tool-impl/remote-controls.ts +273 -0
  174. package/packs/agent-runtime/tsconfig.json +1 -1
  175. package/packs/agent-runtime/turn-lifecycle-events.ts +501 -0
  176. package/packs/sidekick/channel-ingress.ts +137 -0
  177. package/packs/sidekick/manifest.ts +74 -0
  178. package/packs/sidekick/manifest.yaml +88 -0
  179. package/packs/sidekick/package.json +3 -1
  180. package/packs/sidekick/sidekick-events.ts +517 -0
  181. package/packs/sidekick/src/adapters/cloud-queue.ts +101 -0
  182. package/packs/sidekick/src/adapters/control-plane-bridge.adapter.ts +378 -0
  183. package/packs/sidekick/src/adapters/filesystem-bridge.adapter.ts +224 -0
  184. package/packs/sidekick/src/domain/channel.types.ts +84 -0
  185. package/packs/sidekick/src/ports/channel-bridge.port.ts +75 -0
  186. package/packs/sidekick/src/routines/commit.ts +74 -0
  187. package/packs/sidekick/tool-impl/channel-tools.ts +47 -0
  188. package/packs/sidekick/tool-impl/memory-tools.ts +17 -0
  189. package/packs/sidekick/tool-impl/routine-commit.ts +102 -0
  190. package/packs/sidekick/tool-impl/routine-tools.ts +67 -7
  191. package/packs/sidekick/tool-impl/runtime-context.ts +4 -0
  192. package/packs/sidekick/tool-impl/storage.ts +3 -0
  193. package/packs/sidekick/tool-impl/system-tools.ts +7 -0
  194. package/packs/sidekick/tool-impl/task-tools.ts +46 -0
  195. package/packs/sidekick/tsconfig.json +1 -1
  196. package/packs/software-delivery/manifest-schema.ts +30 -0
  197. package/packs/software-delivery/manifest.ts +160 -11
  198. package/packs/software-delivery/manifest.yaml +210 -230
  199. package/packs/software-delivery/package.json +88 -3
  200. package/packs/software-delivery/src/commands/index.ts +5 -0
  201. package/packs/software-delivery/src/config/delivery-review-contract.ts +20 -0
  202. package/packs/software-delivery/src/config/env-accessors.ts +19 -0
  203. package/packs/software-delivery/src/config/index.ts +8 -0
  204. package/packs/software-delivery/src/config/normalize-config-keys.ts +19 -0
  205. package/packs/software-delivery/src/config/schemas/lumenflow-config-schema-types.ts +436 -0
  206. package/packs/software-delivery/src/config/workspace-reader.ts +310 -0
  207. package/packs/software-delivery/src/constants/backlog-patterns.ts +31 -0
  208. package/packs/software-delivery/src/constants/client-ids.ts +19 -0
  209. package/packs/software-delivery/src/constants/config-contract.ts +7 -0
  210. package/packs/software-delivery/src/constants/docs-layout-presets.ts +50 -0
  211. package/packs/software-delivery/src/constants/duration-constants.ts +20 -0
  212. package/packs/software-delivery/src/constants/gate-constants.ts +32 -0
  213. package/packs/software-delivery/src/constants/index.ts +29 -0
  214. package/packs/software-delivery/src/constants/lock-constants.ts +35 -0
  215. package/packs/software-delivery/src/constants/object-guards.ts +12 -0
  216. package/packs/software-delivery/src/constants/section-headings.ts +107 -0
  217. package/packs/software-delivery/src/constants/wu-cli-constants.ts +485 -0
  218. package/packs/software-delivery/src/constants/wu-domain-constants.ts +466 -0
  219. package/packs/software-delivery/src/constants/wu-git-constants.ts +7 -0
  220. package/packs/software-delivery/src/constants/wu-id-format.ts +327 -0
  221. package/packs/software-delivery/src/constants/wu-paths-constants.ts +358 -0
  222. package/packs/software-delivery/src/constants/wu-statuses.ts +287 -0
  223. package/packs/software-delivery/src/constants/wu-type-helpers.ts +67 -0
  224. package/packs/software-delivery/src/constants/wu-ui-constants.ts +267 -0
  225. package/packs/software-delivery/src/constants/wu-validation-constants.ts +73 -0
  226. package/packs/software-delivery/src/domain/index.ts +5 -0
  227. package/packs/software-delivery/src/domain/orchestration.constants.ts +168 -0
  228. package/packs/software-delivery/src/domain/orchestration.schemas.ts +239 -0
  229. package/packs/software-delivery/src/domain/orchestration.types.ts +178 -0
  230. package/packs/software-delivery/src/methodology/incremental-test.ts +90 -0
  231. package/packs/software-delivery/src/methodology/index.ts +6 -0
  232. package/packs/software-delivery/src/methodology/manual-test-validator.ts +292 -0
  233. package/packs/software-delivery/src/policy/coverage-gate.ts +270 -0
  234. package/packs/software-delivery/src/policy/gates-agent-mode.ts +223 -0
  235. package/packs/software-delivery/src/policy/gates-config-internal.ts +121 -0
  236. package/packs/software-delivery/src/policy/gates-config.ts +293 -0
  237. package/packs/software-delivery/src/policy/gates-coverage.ts +247 -0
  238. package/packs/software-delivery/src/policy/gates-presets.ts +134 -0
  239. package/packs/software-delivery/src/policy/gates-schemas.ts +173 -0
  240. package/packs/software-delivery/src/policy/index.ts +22 -0
  241. package/packs/software-delivery/src/policy/package-manager-resolver.ts +319 -0
  242. package/packs/software-delivery/src/policy/resolve-policy.ts +518 -0
  243. package/packs/software-delivery/src/ports/config.ports.ts +90 -0
  244. package/packs/software-delivery/src/ports/dashboard-renderer.port.ts +125 -0
  245. package/packs/software-delivery/src/ports/index.ts +10 -0
  246. package/packs/software-delivery/src/ports/sync-validator.ports.ts +59 -0
  247. package/packs/software-delivery/src/ports/wu-helpers.ports.ts +168 -0
  248. package/packs/software-delivery/src/ports/wu-state.ports.ts +241 -0
  249. package/packs/software-delivery/src/primitives/index.ts +5 -0
  250. package/packs/software-delivery/src/runtime/index.ts +6 -0
  251. package/packs/software-delivery/src/runtime/work-classifier.ts +561 -0
  252. package/packs/software-delivery/src/sandbox/index.ts +10 -0
  253. package/packs/software-delivery/src/sandbox/sandbox-allowlist.ts +118 -0
  254. package/packs/software-delivery/src/sandbox/sandbox-backend-linux.ts +88 -0
  255. package/packs/software-delivery/src/sandbox/sandbox-backend-macos.ts +154 -0
  256. package/packs/software-delivery/src/sandbox/sandbox-backend-windows.ts +47 -0
  257. package/packs/software-delivery/src/sandbox/sandbox-profile.ts +153 -0
  258. package/packs/software-delivery/src/schemas/index.ts +5 -0
  259. package/packs/software-delivery/src/state/date-utils.ts +158 -0
  260. package/packs/software-delivery/src/state/index.ts +15 -0
  261. package/packs/software-delivery/src/state/state-machine.ts +119 -0
  262. package/packs/software-delivery/src/state/wu-doc-types.ts +51 -0
  263. package/packs/software-delivery/src/state/wu-paths.ts +381 -0
  264. package/packs/software-delivery/src/state/wu-schema.ts +1139 -0
  265. package/packs/software-delivery/src/state/wu-state-schema.ts +255 -0
  266. package/packs/software-delivery/src/state/wu-yaml.ts +338 -0
  267. package/packs/software-delivery/src/types.d.ts +16 -0
  268. package/packs/software-delivery/tool-impl/wu-lifecycle-tools.ts +18 -0
  269. package/packs/software-delivery/tsconfig.json +28 -2
  270. package/templates/core/AGENTS.md.template +76 -17
  271. package/templates/core/LUMENFLOW.md.template +265 -66
  272. package/templates/core/_frameworks/lumenflow/wu-sizing-guide.md.template +180 -116
  273. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +26 -8
  274. package/templates/core/ai/onboarding/existing-project-bootstrap.md.template +171 -0
  275. package/templates/core/ai/onboarding/first-15-mins.md.template +3 -1
  276. package/templates/core/ai/onboarding/first-wu-mistakes.md.template +1 -1
  277. package/templates/core/ai/onboarding/initiative-orchestration.md.template +46 -30
  278. package/templates/core/ai/onboarding/quick-ref-commands.md.template +36 -33
  279. package/templates/core/ai/onboarding/release-process.md.template +8 -7
  280. package/templates/core/ai/onboarding/starting-prompt.md.template +2 -0
  281. package/templates/core/ai/onboarding/troubleshooting-wu-done.md.template +62 -0
  282. package/templates/vendors/claude/.claude/CLAUDE.md.template +29 -54
  283. package/templates/vendors/cursor/.cursor/rules/lumenflow.md.template +24 -52
  284. package/templates/vendors/windsurf/.windsurf/rules/lumenflow.md.template +24 -52
  285. package/packs/agent-runtime/.turbo/turbo-build.log +0 -4
  286. package/packs/sidekick/.turbo/turbo-build.log +0 -4
  287. package/packs/software-delivery/.turbo/turbo-build.log +0 -4
@@ -0,0 +1,328 @@
1
+ // Copyright (c) 2026 Hellmai Ltd
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+
4
+ /**
5
+ * Delegation Tree Builder (ADR-014 follow-up, WU-2763)
6
+ *
7
+ * Builds and formats delegation trees for visualization.
8
+ *
9
+ * Core now re-exports this module as a compatibility shim.
10
+ */
11
+
12
+ import fs from 'node:fs/promises';
13
+ import path from 'node:path';
14
+ import { parse as parseYAML } from 'yaml';
15
+ import { DelegationRegistryStore } from './delegation-registry-store.js';
16
+ import {
17
+ DelegationStatus,
18
+ type DelegationOwnershipScope,
19
+ type DelegationRoleDescriptor,
20
+ type DelegationSchemaVersion,
21
+ } from './delegation-registry-schema.js';
22
+
23
+ interface RegistryRecord {
24
+ id: string;
25
+ parentWuId: string;
26
+ targetWuId: string;
27
+ lane: string;
28
+ status: string;
29
+ delegatedAt: string;
30
+ completedAt: string | null;
31
+ pickedUpAt?: string;
32
+ pickedUpBy?: string;
33
+ schemaVersion?: DelegationSchemaVersion;
34
+ requested_role?: DelegationRoleDescriptor;
35
+ actual_role?: DelegationRoleDescriptor;
36
+ capabilities?: string[];
37
+ ownership_scope?: DelegationOwnershipScope;
38
+ }
39
+
40
+ interface DelegationRecord {
41
+ id: string;
42
+ parentWuId: string;
43
+ targetWuId: string;
44
+ lane: string;
45
+ status: string;
46
+ delegatedAt: string;
47
+ completedAt: string | null;
48
+ pickedUpAt?: string;
49
+ pickedUpBy?: string;
50
+ schemaVersion?: DelegationSchemaVersion;
51
+ requested_role?: DelegationRoleDescriptor;
52
+ actual_role?: DelegationRoleDescriptor;
53
+ capabilities?: string[];
54
+ ownership_scope?: DelegationOwnershipScope;
55
+ }
56
+
57
+ interface DelegationTreeNode {
58
+ wuId: string;
59
+ delegationId: string | null;
60
+ status: string | null;
61
+ lane: string | null;
62
+ delegatedAt: string | null;
63
+ children: DelegationTreeNode[];
64
+ schemaVersion?: DelegationSchemaVersion;
65
+ requested_role?: DelegationRoleDescriptor;
66
+ actual_role?: DelegationRoleDescriptor;
67
+ capabilities?: string[];
68
+ ownership_scope?: DelegationOwnershipScope;
69
+ }
70
+
71
+ /**
72
+ * Status indicators for terminal output.
73
+ */
74
+ export const STATUS_INDICATORS = Object.freeze({
75
+ [DelegationStatus.PENDING]: '\u25CB',
76
+ [DelegationStatus.COMPLETED]: '\u2713',
77
+ [DelegationStatus.TIMEOUT]: '\u23F1',
78
+ [DelegationStatus.CRASHED]: '\u2717',
79
+ [DelegationStatus.ESCALATED]: '!',
80
+ });
81
+
82
+ const TREE_CHARS = Object.freeze({
83
+ VERTICAL: '\u2502',
84
+ BRANCH: '\u251C',
85
+ LAST_BRANCH: '\u2514',
86
+ HORIZONTAL: '\u2500',
87
+ });
88
+
89
+ function getStatusIndicator(status: string | null): string {
90
+ switch (status) {
91
+ case DelegationStatus.PENDING:
92
+ return STATUS_INDICATORS[DelegationStatus.PENDING];
93
+ case DelegationStatus.COMPLETED:
94
+ return STATUS_INDICATORS[DelegationStatus.COMPLETED];
95
+ case DelegationStatus.TIMEOUT:
96
+ return STATUS_INDICATORS[DelegationStatus.TIMEOUT];
97
+ case DelegationStatus.CRASHED:
98
+ return STATUS_INDICATORS[DelegationStatus.CRASHED];
99
+ case DelegationStatus.ESCALATED:
100
+ return STATUS_INDICATORS[DelegationStatus.ESCALATED];
101
+ default:
102
+ return '?';
103
+ }
104
+ }
105
+
106
+ function toDelegationRecord(record: RegistryRecord): DelegationRecord {
107
+ return {
108
+ id: record.id,
109
+ parentWuId: record.parentWuId,
110
+ targetWuId: record.targetWuId,
111
+ lane: record.lane,
112
+ status: record.status,
113
+ delegatedAt: record.delegatedAt,
114
+ completedAt: record.completedAt,
115
+ pickedUpAt: record.pickedUpAt,
116
+ pickedUpBy: record.pickedUpBy,
117
+ schemaVersion: record.schemaVersion,
118
+ requested_role: record.requested_role,
119
+ actual_role: record.actual_role,
120
+ capabilities: record.capabilities,
121
+ ownership_scope: record.ownership_scope,
122
+ };
123
+ }
124
+
125
+ /**
126
+ * Builds a delegation tree from flat delegation events.
127
+ */
128
+ export function buildDelegationTree(
129
+ delegations: DelegationRecord[],
130
+ rootWuId: string,
131
+ ): DelegationTreeNode {
132
+ const root: DelegationTreeNode = {
133
+ wuId: rootWuId,
134
+ delegationId: null,
135
+ status: null,
136
+ lane: null,
137
+ delegatedAt: null,
138
+ children: [],
139
+ };
140
+
141
+ if (delegations.length === 0) {
142
+ return root;
143
+ }
144
+
145
+ const delegationsByParent = new Map<string, DelegationRecord[]>();
146
+ for (const delegation of delegations) {
147
+ const existing = delegationsByParent.get(delegation.parentWuId) ?? [];
148
+ existing.push(delegation);
149
+ delegationsByParent.set(delegation.parentWuId, existing);
150
+ }
151
+
152
+ const buildChildren = (parentWuId: string): DelegationTreeNode[] => {
153
+ const childDelegations = delegationsByParent.get(parentWuId) ?? [];
154
+ return childDelegations.map((delegation) => ({
155
+ wuId: delegation.targetWuId,
156
+ delegationId: delegation.id,
157
+ status: delegation.status,
158
+ lane: delegation.lane,
159
+ delegatedAt: delegation.delegatedAt,
160
+ children: buildChildren(delegation.targetWuId),
161
+ schemaVersion: delegation.schemaVersion,
162
+ requested_role: delegation.requested_role,
163
+ actual_role: delegation.actual_role,
164
+ capabilities: delegation.capabilities,
165
+ ownership_scope: delegation.ownership_scope,
166
+ }));
167
+ };
168
+
169
+ root.children = buildChildren(rootWuId);
170
+ return root;
171
+ }
172
+
173
+ /**
174
+ * Formats a delegation tree for terminal display.
175
+ */
176
+ export function formatDelegationTree(tree: DelegationTreeNode): string {
177
+ const lines: string[] = [];
178
+ lines.push(`${tree.wuId} (root)`);
179
+
180
+ if (tree.children.length === 0) {
181
+ lines.push(' (no delegations)');
182
+ return lines.join('\n');
183
+ }
184
+
185
+ const formatChildren = (children: DelegationTreeNode[], prefix: string): void => {
186
+ children.forEach((child, index) => {
187
+ const isLast = index === children.length - 1;
188
+ const branch = isLast
189
+ ? `${TREE_CHARS.LAST_BRANCH}${TREE_CHARS.HORIZONTAL}${TREE_CHARS.HORIZONTAL}`
190
+ : `${TREE_CHARS.BRANCH}${TREE_CHARS.HORIZONTAL}${TREE_CHARS.HORIZONTAL}`;
191
+ const indicator = getStatusIndicator(child.status);
192
+ const delegationInfo = child.delegationId ? ` [${child.delegationId}]` : '';
193
+ const laneInfo = child.lane ? ` (${child.lane})` : '';
194
+
195
+ lines.push(`${prefix}${branch} ${indicator} ${child.wuId}${delegationInfo}${laneInfo}`);
196
+
197
+ const childPrefix = prefix + (isLast ? ' ' : `${TREE_CHARS.VERTICAL} `);
198
+ formatChildren(child.children, childPrefix);
199
+ });
200
+ };
201
+
202
+ formatChildren(tree.children, '');
203
+ return lines.join('\n');
204
+ }
205
+
206
+ /**
207
+ * Gets all delegations for a WU (direct + descendants).
208
+ */
209
+ export async function getDelegationsByWU(
210
+ wuId: string,
211
+ baseDir: string,
212
+ ): Promise<DelegationRecord[]> {
213
+ const store = new DelegationRegistryStore(baseDir);
214
+
215
+ try {
216
+ await store.load();
217
+ } catch (error) {
218
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
219
+ return [];
220
+ }
221
+ throw error;
222
+ }
223
+
224
+ const allRecords = store.getAllDelegations();
225
+ if (allRecords.length === 0) {
226
+ return [];
227
+ }
228
+
229
+ const result: DelegationRecord[] = [];
230
+ const seenDelegationIds = new Set<string>();
231
+ const visitedWuIds = new Set<string>();
232
+ const queue = [wuId];
233
+
234
+ while (queue.length > 0) {
235
+ const currentWuId = queue.shift();
236
+ if (!currentWuId || visitedWuIds.has(currentWuId)) {
237
+ continue;
238
+ }
239
+
240
+ visitedWuIds.add(currentWuId);
241
+ const childRecords = store.getByParent(currentWuId) as RegistryRecord[];
242
+ for (const child of childRecords) {
243
+ if (!seenDelegationIds.has(child.id)) {
244
+ result.push(toDelegationRecord(child));
245
+ seenDelegationIds.add(child.id);
246
+ }
247
+ queue.push(child.targetWuId);
248
+ }
249
+ }
250
+
251
+ return result;
252
+ }
253
+
254
+ /**
255
+ * Gets all delegations for an initiative.
256
+ */
257
+ export async function getDelegationsByInitiative(
258
+ initiativeId: string,
259
+ registryDir: string,
260
+ wuDir: string,
261
+ ): Promise<DelegationRecord[]> {
262
+ const initiativeWuIds = await getWUsForInitiative(initiativeId, wuDir);
263
+ if (initiativeWuIds.size === 0) {
264
+ return [];
265
+ }
266
+
267
+ const store = new DelegationRegistryStore(registryDir);
268
+ try {
269
+ await store.load();
270
+ } catch (error) {
271
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
272
+ return [];
273
+ }
274
+ throw error;
275
+ }
276
+
277
+ return (store.getAllDelegations() as RegistryRecord[])
278
+ .filter((record) => initiativeWuIds.has(record.parentWuId))
279
+ .map(toDelegationRecord);
280
+ }
281
+
282
+ async function getWUsForInitiative(initiativeId: string, wuDir: string): Promise<Set<string>> {
283
+ const wuIds = new Set<string>();
284
+ let files: string[];
285
+
286
+ try {
287
+ files = await fs.readdir(wuDir);
288
+ } catch (error) {
289
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
290
+ return wuIds;
291
+ }
292
+ throw error;
293
+ }
294
+
295
+ const wuFiles = files.filter((file) => file.startsWith('WU-') && file.endsWith('.yaml'));
296
+ for (const file of wuFiles) {
297
+ try {
298
+ const content = await fs.readFile(path.join(wuDir, file), 'utf-8');
299
+ const doc = parseYAML(content) as { initiative?: string; id?: string };
300
+ if (doc.initiative === initiativeId && typeof doc.id === 'string') {
301
+ wuIds.add(doc.id);
302
+ }
303
+ } catch {
304
+ continue;
305
+ }
306
+ }
307
+
308
+ return wuIds;
309
+ }
310
+
311
+ /**
312
+ * Converts a delegation tree to JSON.
313
+ */
314
+ export function treeToJSON(tree: DelegationTreeNode): DelegationTreeNode {
315
+ return {
316
+ wuId: tree.wuId,
317
+ delegationId: tree.delegationId,
318
+ status: tree.status,
319
+ lane: tree.lane,
320
+ delegatedAt: tree.delegatedAt,
321
+ ...(tree.schemaVersion !== undefined ? { schemaVersion: tree.schemaVersion } : {}),
322
+ ...(tree.requested_role !== undefined ? { requested_role: tree.requested_role } : {}),
323
+ ...(tree.actual_role !== undefined ? { actual_role: tree.actual_role } : {}),
324
+ ...(tree.capabilities !== undefined ? { capabilities: tree.capabilities } : {}),
325
+ ...(tree.ownership_scope !== undefined ? { ownership_scope: tree.ownership_scope } : {}),
326
+ children: tree.children.map((child): DelegationTreeNode => treeToJSON(child)),
327
+ };
328
+ }
@@ -3,9 +3,18 @@
3
3
 
4
4
  export * from './constants.js';
5
5
  export * from './capability-factory.js';
6
+ export * from './agent-heartbeat.js';
7
+ export * from './auto-session-integration.js';
8
+ export * from './delegation-registry-schema.js';
9
+ export * from './delegation-registry-store.js';
10
+ export * from './delegation-tree.js';
6
11
  export * from './manifest.js';
12
+ export * from './memory-coordination-contract.js';
7
13
  export * from './orchestration.js';
8
14
  export * from './pack-registration.js';
9
15
  export * from './policy-factory.js';
16
+ export * from './remote-controls/index.js';
17
+ export * from './session-schema.js';
18
+ export * from './turn-lifecycle-events.js';
10
19
  export * from './types.js';
11
20
  export * from './tools/index.js';
@@ -24,11 +24,61 @@ import {
24
24
  AGENT_RUNTIME_TURN_STATUSES,
25
25
  type AgentRuntimeToolName,
26
26
  } from './types.js';
27
+ import { AGENT_RUNTIME_EVENT_KIND_VALUES as AGENT_RUNTIME_EMITTED_EVENT_KIND_VALUES } from './turn-lifecycle-events.js';
28
+ import {
29
+ AGENT_RUNTIME_REMOTE_CONTROL_APPROVALS,
30
+ AGENT_RUNTIME_REMOTE_CONTROL_APPROVAL_ID,
31
+ AGENT_RUNTIME_REMOTE_CONTROL_TOOL_NAMES,
32
+ AGENT_RUNTIME_REMOTE_CONTROL_TOOL_NAME_VALUES,
33
+ type AgentRuntimeRemoteControlToolName,
34
+ } from './remote-controls/types.js';
27
35
 
28
36
  const EXECUTE_TURN_TOOL_ENTRY = 'tool-impl/agent-turn-tools.ts#agentExecuteTurnTool';
29
37
  const CAPABILITY_FACTORY_ENTRY = 'capability-factory.ts#createAgentRuntimeCapabilityFactory';
30
38
  const POLICY_FACTORY_ENTRY = 'policy-factory.ts#createAgentRuntimePolicyFactory';
31
39
 
40
+ // WU-2733 (INIT-060 Phase 3, ADR-013 §1 + §6 governance): real
41
+ // kernel-side entries. The tracer-bullet mock entries from WU-2732
42
+ // (previously at tool-impl/remote-controls.mock.ts) are superseded;
43
+ // mock exports remain in-tree only for contract-pin unit tests. Tool
44
+ // names, permissions, scopes, approvals, and input schemas stay
45
+ // identical — the wire contract is frozen.
46
+ const REMOTE_CONTROL_TOOL_ENTRIES = {
47
+ [AGENT_RUNTIME_REMOTE_CONTROL_TOOL_NAMES.RESUME_WORKFLOW]:
48
+ 'tool-impl/remote-controls.ts#resumeWorkflowTool',
49
+ [AGENT_RUNTIME_REMOTE_CONTROL_TOOL_NAMES.PAUSE_TURN]:
50
+ 'tool-impl/remote-controls.ts#pauseTurnTool',
51
+ [AGENT_RUNTIME_REMOTE_CONTROL_TOOL_NAMES.ABORT_TURN]:
52
+ 'tool-impl/remote-controls.ts#abortTurnTool',
53
+ [AGENT_RUNTIME_REMOTE_CONTROL_TOOL_NAMES.ELEVATE_AUTONOMY]:
54
+ 'tool-impl/remote-controls.ts#elevateAutonomyTool',
55
+ [AGENT_RUNTIME_REMOTE_CONTROL_TOOL_NAMES.LOWER_AUTONOMY]:
56
+ 'tool-impl/remote-controls.ts#lowerAutonomyTool',
57
+ [AGENT_RUNTIME_REMOTE_CONTROL_TOOL_NAMES.APPROVE_INFLIGHT]:
58
+ 'tool-impl/remote-controls.ts#approveInflightTool',
59
+ } as const satisfies Record<AgentRuntimeRemoteControlToolName, string>;
60
+
61
+ const REMOTE_CONTROL_INPUT_SCHEMA: Record<string, unknown> = {
62
+ type: 'object',
63
+ properties: {
64
+ session_id: { type: 'string', minLength: 1 },
65
+ reason: { type: 'string', minLength: 1 },
66
+ },
67
+ additionalProperties: false,
68
+ };
69
+
70
+ const REMOTE_CONTROL_READ_SCOPE = {
71
+ type: 'path',
72
+ pattern: AGENT_RUNTIME_STORAGE_PATTERN,
73
+ access: 'read',
74
+ } as const;
75
+
76
+ const REMOTE_CONTROL_WRITE_SCOPE = {
77
+ type: 'path',
78
+ pattern: AGENT_RUNTIME_STORAGE_PATTERN,
79
+ access: 'write',
80
+ } as const;
81
+
32
82
  const EXECUTE_TURN_INPUT_SCHEMA: Record<string, unknown> = {
33
83
  type: 'object',
34
84
  properties: {
@@ -149,25 +199,48 @@ const EXECUTE_TURN_OUTPUT_SCHEMA: Record<string, unknown> = {
149
199
  additionalProperties: false,
150
200
  };
151
201
 
152
- const MANIFEST_TOOL_DEFINITIONS = [
153
- {
154
- name: AGENT_RUNTIME_TOOL_NAMES.EXECUTE_TURN,
155
- entry: EXECUTE_TURN_TOOL_ENTRY,
202
+ function buildRemoteControlToolDefinition(name: AgentRuntimeRemoteControlToolName): {
203
+ name: AgentRuntimeRemoteControlToolName;
204
+ entry: string;
205
+ permission: 'write';
206
+ required_scopes: readonly [typeof REMOTE_CONTROL_READ_SCOPE, typeof REMOTE_CONTROL_WRITE_SCOPE];
207
+ required_approvals: readonly string[];
208
+ input_schema: Record<string, unknown>;
209
+ } {
210
+ return {
211
+ name,
212
+ entry: REMOTE_CONTROL_TOOL_ENTRIES[name],
156
213
  permission: 'write',
157
- required_scopes: [
158
- { type: 'path', pattern: AGENT_RUNTIME_STORAGE_PATTERN, access: 'read' },
159
- { type: 'path', pattern: AGENT_RUNTIME_STORAGE_PATTERN, access: 'write' },
160
- {
161
- type: 'network',
162
- posture: 'allowlist',
163
- allowlist_entries: [...AGENT_RUNTIME_STATIC_PROVIDER_ALLOWLIST],
164
- },
165
- ],
166
- required_env: [AGENT_RUNTIME_API_KEY_ENV, AGENT_RUNTIME_BASE_URL_ENV],
167
- input_schema: EXECUTE_TURN_INPUT_SCHEMA,
168
- output_schema: EXECUTE_TURN_OUTPUT_SCHEMA,
169
- },
170
- ] as const;
214
+ required_scopes: [REMOTE_CONTROL_READ_SCOPE, REMOTE_CONTROL_WRITE_SCOPE],
215
+ required_approvals: [...AGENT_RUNTIME_REMOTE_CONTROL_APPROVALS[name]],
216
+ input_schema: REMOTE_CONTROL_INPUT_SCHEMA,
217
+ };
218
+ }
219
+
220
+ const EXECUTE_TURN_TOOL_DEFINITION = {
221
+ name: AGENT_RUNTIME_TOOL_NAMES.EXECUTE_TURN,
222
+ entry: EXECUTE_TURN_TOOL_ENTRY,
223
+ permission: 'write',
224
+ required_scopes: [
225
+ { type: 'path', pattern: AGENT_RUNTIME_STORAGE_PATTERN, access: 'read' },
226
+ { type: 'path', pattern: AGENT_RUNTIME_STORAGE_PATTERN, access: 'write' },
227
+ {
228
+ type: 'network',
229
+ posture: 'allowlist',
230
+ allowlist_entries: [...AGENT_RUNTIME_STATIC_PROVIDER_ALLOWLIST],
231
+ },
232
+ ],
233
+ required_env: [AGENT_RUNTIME_API_KEY_ENV, AGENT_RUNTIME_BASE_URL_ENV],
234
+ input_schema: EXECUTE_TURN_INPUT_SCHEMA,
235
+ output_schema: EXECUTE_TURN_OUTPUT_SCHEMA,
236
+ } as const;
237
+
238
+ const MANIFEST_TOOL_DEFINITIONS = [
239
+ EXECUTE_TURN_TOOL_DEFINITION,
240
+ ...AGENT_RUNTIME_REMOTE_CONTROL_TOOL_NAME_VALUES.map((name) =>
241
+ buildRemoteControlToolDefinition(name),
242
+ ),
243
+ ];
171
244
 
172
245
  export const AGENT_RUNTIME_MANIFEST = DomainPackManifestSchema.parse({
173
246
  id: AGENT_RUNTIME_PACK_ID,
@@ -187,6 +260,8 @@ export const AGENT_RUNTIME_MANIFEST = DomainPackManifestSchema.parse({
187
260
  },
188
261
  ],
189
262
  evidence_types: ['agent-runtime.turn', 'agent-runtime.provider-call'],
263
+ emitted_event_kinds: [...AGENT_RUNTIME_EMITTED_EVENT_KIND_VALUES],
264
+ required_approvals: [AGENT_RUNTIME_REMOTE_CONTROL_APPROVAL_ID],
190
265
  state_aliases: {
191
266
  paused: 'waiting',
192
267
  },
@@ -198,10 +273,25 @@ export type AgentRuntimeManifestTool = AgentRuntimePackManifest['tools'][number]
198
273
 
199
274
  export const AGENT_RUNTIME_MANIFEST_TOOL_NAMES = AGENT_RUNTIME_MANIFEST.tools.map(
200
275
  (tool) => tool.name,
201
- ) as readonly AgentRuntimeToolName[];
276
+ ) as readonly (AgentRuntimeToolName | AgentRuntimeRemoteControlToolName)[];
202
277
 
203
278
  export function getAgentRuntimeManifestToolByName(
204
279
  name: string,
205
280
  ): AgentRuntimeManifestTool | undefined {
206
281
  return AGENT_RUNTIME_MANIFEST.tools.find((tool) => tool.name === name);
207
282
  }
283
+
284
+ /**
285
+ * WU-2732 (INIT-060 Phase 3, ADR-013 §3 tool exposure): the 6
286
+ * remote-callable remote-control tools. The HTTP tool-api surface
287
+ * uses this list to build its allowlist so the set is the single
288
+ * source of truth (mirrors WU-2729 software-delivery precedent —
289
+ * no duplicate allowlist in surface code).
290
+ */
291
+ export const AGENT_RUNTIME_REMOTE_CALLABLE_TOOLS = [
292
+ ...AGENT_RUNTIME_REMOTE_CONTROL_TOOL_NAME_VALUES,
293
+ ] as const satisfies readonly AgentRuntimeRemoteControlToolName[];
294
+
295
+ export function getAgentRuntimeRemoteCallableToolNames(): AgentRuntimeRemoteControlToolName[] {
296
+ return [...AGENT_RUNTIME_REMOTE_CALLABLE_TOOLS];
297
+ }
@@ -180,6 +180,138 @@ tools:
180
180
  - provider
181
181
  - finish_reason
182
182
  additionalProperties: false
183
+ # WU-2732 (INIT-060 Phase 3, ADR-013 §1 + §6): six remote-control tools
184
+ # with mock tracer-bullet implementations. Real impls replace the mock
185
+ # entries in WU-2733 without changing names, scopes, or approvals.
186
+ - name: agent-runtime:resume_workflow
187
+ entry: tool-impl/remote-controls.ts#resumeWorkflowTool
188
+ permission: write
189
+ required_scopes:
190
+ - type: path
191
+ pattern: .agent-runtime/**
192
+ access: read
193
+ - type: path
194
+ pattern: .agent-runtime/**
195
+ access: write
196
+ required_approvals: []
197
+ input_schema:
198
+ type: object
199
+ properties:
200
+ session_id:
201
+ type: string
202
+ minLength: 1
203
+ reason:
204
+ type: string
205
+ minLength: 1
206
+ additionalProperties: false
207
+ - name: agent-runtime:pause_turn
208
+ entry: tool-impl/remote-controls.ts#pauseTurnTool
209
+ permission: write
210
+ required_scopes:
211
+ - type: path
212
+ pattern: .agent-runtime/**
213
+ access: read
214
+ - type: path
215
+ pattern: .agent-runtime/**
216
+ access: write
217
+ required_approvals:
218
+ - agent-runtime:remote_control
219
+ input_schema:
220
+ type: object
221
+ properties:
222
+ session_id:
223
+ type: string
224
+ minLength: 1
225
+ reason:
226
+ type: string
227
+ minLength: 1
228
+ additionalProperties: false
229
+ - name: agent-runtime:abort_turn
230
+ entry: tool-impl/remote-controls.ts#abortTurnTool
231
+ permission: write
232
+ required_scopes:
233
+ - type: path
234
+ pattern: .agent-runtime/**
235
+ access: read
236
+ - type: path
237
+ pattern: .agent-runtime/**
238
+ access: write
239
+ required_approvals:
240
+ - agent-runtime:remote_control
241
+ input_schema:
242
+ type: object
243
+ properties:
244
+ session_id:
245
+ type: string
246
+ minLength: 1
247
+ reason:
248
+ type: string
249
+ minLength: 1
250
+ additionalProperties: false
251
+ - name: agent-runtime:elevate_autonomy
252
+ entry: tool-impl/remote-controls.ts#elevateAutonomyTool
253
+ permission: write
254
+ required_scopes:
255
+ - type: path
256
+ pattern: .agent-runtime/**
257
+ access: read
258
+ - type: path
259
+ pattern: .agent-runtime/**
260
+ access: write
261
+ required_approvals:
262
+ - agent-runtime:remote_control
263
+ input_schema:
264
+ type: object
265
+ properties:
266
+ session_id:
267
+ type: string
268
+ minLength: 1
269
+ reason:
270
+ type: string
271
+ minLength: 1
272
+ additionalProperties: false
273
+ - name: agent-runtime:lower_autonomy
274
+ entry: tool-impl/remote-controls.ts#lowerAutonomyTool
275
+ permission: write
276
+ required_scopes:
277
+ - type: path
278
+ pattern: .agent-runtime/**
279
+ access: read
280
+ - type: path
281
+ pattern: .agent-runtime/**
282
+ access: write
283
+ required_approvals: []
284
+ input_schema:
285
+ type: object
286
+ properties:
287
+ session_id:
288
+ type: string
289
+ minLength: 1
290
+ reason:
291
+ type: string
292
+ minLength: 1
293
+ additionalProperties: false
294
+ - name: agent-runtime:approve_inflight
295
+ entry: tool-impl/remote-controls.ts#approveInflightTool
296
+ permission: write
297
+ required_scopes:
298
+ - type: path
299
+ pattern: .agent-runtime/**
300
+ access: read
301
+ - type: path
302
+ pattern: .agent-runtime/**
303
+ access: write
304
+ required_approvals: []
305
+ input_schema:
306
+ type: object
307
+ properties:
308
+ session_id:
309
+ type: string
310
+ minLength: 1
311
+ reason:
312
+ type: string
313
+ minLength: 1
314
+ additionalProperties: false
183
315
  policies:
184
316
  - id: agent-runtime.policy.default
185
317
  trigger: on_tool_request
@@ -188,6 +320,24 @@ policies:
188
320
  evidence_types:
189
321
  - agent-runtime.turn
190
322
  - agent-runtime.provider-call
323
+ required_approvals:
324
+ - agent-runtime:remote_control
325
+ emitted_event_kinds:
326
+ - agent-runtime:turn_started
327
+ - agent-runtime:turn_completed
328
+ - agent-runtime:turn_aborted
329
+ - agent-runtime:tool_called
330
+ - agent-runtime:approval_required
331
+ - agent-runtime:workflow_node_started
332
+ - agent-runtime:workflow_node_completed
333
+ - agent-runtime:workflow_node_failed
334
+ - agent-runtime:workflow_paused
335
+ - agent-runtime:scheduled_wakeup_set
336
+ - agent-runtime:budget_threshold
337
+ - agent-runtime:agent_session_enrolled
338
+ - agent-runtime:agent_session_ended
339
+ - agent-runtime:agent_session_stalled
340
+ - agent-runtime:autonomy_changed
191
341
  state_aliases:
192
342
  paused: waiting
193
343
  lane_templates: []