@lumenflow/cli 5.4.0 → 5.7.12

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 (227) hide show
  1. package/README.md +42 -40
  2. package/dist/db-journal-recover.js +400 -0
  3. package/dist/db-journal-recover.js.map +1 -0
  4. package/dist/docs-sync.js +8 -3
  5. package/dist/docs-sync.js.map +1 -1
  6. package/dist/gate-defaults.js +191 -9
  7. package/dist/gate-defaults.js.map +1 -1
  8. package/dist/gate-registry.js.map +1 -1
  9. package/dist/gates/monolithic-file-contention-guard.js +167 -0
  10. package/dist/gates/monolithic-file-contention-guard.js.map +1 -0
  11. package/dist/gates/prod-migration-drift.js +207 -0
  12. package/dist/gates/prod-migration-drift.js.map +1 -0
  13. package/dist/gates/test-over-deletion-guard.js +255 -0
  14. package/dist/gates/test-over-deletion-guard.js.map +1 -0
  15. package/dist/gates-runners.js +401 -2
  16. package/dist/gates-runners.js.map +1 -1
  17. package/dist/gates.js +349 -4
  18. package/dist/gates.js.map +1 -1
  19. package/dist/lumenflow-setup.js +144 -0
  20. package/dist/lumenflow-setup.js.map +1 -0
  21. package/dist/lumenflow-upgrade.js +2 -1
  22. package/dist/lumenflow-upgrade.js.map +1 -1
  23. package/dist/mem-create.js +10 -1
  24. package/dist/mem-create.js.map +1 -1
  25. package/dist/mem-signal.js +21 -4
  26. package/dist/mem-signal.js.map +1 -1
  27. package/dist/metrics-cli.js +19 -2
  28. package/dist/metrics-cli.js.map +1 -1
  29. package/dist/metrics-snapshot.js +25 -2
  30. package/dist/metrics-snapshot.js.map +1 -1
  31. package/dist/orchestrate-initiative.js +28 -3
  32. package/dist/orchestrate-initiative.js.map +1 -1
  33. package/dist/public-manifest.js +17 -0
  34. package/dist/public-manifest.js.map +1 -1
  35. package/dist/release.js +53 -18
  36. package/dist/release.js.map +1 -1
  37. package/dist/wu-done-gates.js +121 -8
  38. package/dist/wu-done-gates.js.map +1 -1
  39. package/dist/wu-done.js +30 -6
  40. package/dist/wu-done.js.map +1 -1
  41. package/dist/wu-edit-operations.js +74 -0
  42. package/dist/wu-edit-operations.js.map +1 -1
  43. package/dist/wu-edit-validators.js +58 -0
  44. package/dist/wu-edit-validators.js.map +1 -1
  45. package/dist/wu-edit.js +106 -4
  46. package/dist/wu-edit.js.map +1 -1
  47. package/dist/wu-prep.js +132 -8
  48. package/dist/wu-prep.js.map +1 -1
  49. package/dist/wu-recover.js +6 -0
  50. package/dist/wu-recover.js.map +1 -1
  51. package/dist/wu-release.js +120 -2
  52. package/dist/wu-release.js.map +1 -1
  53. package/dist/wu-sizing-validation.js +47 -17
  54. package/dist/wu-sizing-validation.js.map +1 -1
  55. package/dist/wu-status.js +33 -0
  56. package/dist/wu-status.js.map +1 -1
  57. package/package.json +13 -11
  58. package/packs/agent-runtime/package.json +1 -1
  59. package/packs/sidekick/package.json +1 -1
  60. package/packs/software-delivery/package.json +1 -1
  61. package/templates/core/AGENTS.md.template +162 -26
  62. package/templates/core/LUMENFLOW.md.template +381 -70
  63. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +0 -5
  64. package/templates/core/ai/onboarding/agent-safety-card.md.template +63 -17
  65. package/templates/core/ai/onboarding/initiative-orchestration.md.template +4 -0
  66. package/templates/core/ai/onboarding/release-process.md.template +7 -7
  67. package/templates/core/ai/onboarding/vendor-support.md.template +74 -10
  68. package/templates/vendors/claude/.claude/skills/frontend-design/SKILL.md.template +1 -1
  69. package/templates/vendors/claude/.claude/skills/wu-lifecycle/SKILL.md.template +28 -0
  70. package/packs/agent-runtime/agent-heartbeat.ts +0 -163
  71. package/packs/agent-runtime/auto-session-integration.ts +0 -888
  72. package/packs/agent-runtime/capability-factory.ts +0 -104
  73. package/packs/agent-runtime/constants.ts +0 -21
  74. package/packs/agent-runtime/delegation-registry-schema.ts +0 -220
  75. package/packs/agent-runtime/delegation-registry-store.ts +0 -269
  76. package/packs/agent-runtime/delegation-tree.ts +0 -328
  77. package/packs/agent-runtime/index.ts +0 -20
  78. package/packs/agent-runtime/manifest.ts +0 -348
  79. package/packs/agent-runtime/memory-coordination-contract.ts +0 -86
  80. package/packs/agent-runtime/orchestration.ts +0 -2027
  81. package/packs/agent-runtime/pack-registration.ts +0 -110
  82. package/packs/agent-runtime/policy-factory.ts +0 -165
  83. package/packs/agent-runtime/remote-controls/index.ts +0 -7
  84. package/packs/agent-runtime/remote-controls/operations.ts +0 -405
  85. package/packs/agent-runtime/remote-controls/port.ts +0 -48
  86. package/packs/agent-runtime/remote-controls/state-store.ts +0 -258
  87. package/packs/agent-runtime/remote-controls/types.ts +0 -105
  88. package/packs/agent-runtime/session-schema.ts +0 -467
  89. package/packs/agent-runtime/tool-impl/agent-turn-tools.ts +0 -793
  90. package/packs/agent-runtime/tool-impl/index.ts +0 -6
  91. package/packs/agent-runtime/tool-impl/provider-adapters.ts +0 -1245
  92. package/packs/agent-runtime/tool-impl/remote-controls.mock.ts +0 -256
  93. package/packs/agent-runtime/tool-impl/remote-controls.ts +0 -273
  94. package/packs/agent-runtime/tools/index.ts +0 -4
  95. package/packs/agent-runtime/tools/types.ts +0 -47
  96. package/packs/agent-runtime/turn-lifecycle-events.ts +0 -590
  97. package/packs/agent-runtime/types.ts +0 -128
  98. package/packs/agent-runtime/vitest.config.ts +0 -11
  99. package/packs/sidekick/channel-ingress.ts +0 -137
  100. package/packs/sidekick/constants.ts +0 -10
  101. package/packs/sidekick/index.ts +0 -8
  102. package/packs/sidekick/manifest-schema.ts +0 -49
  103. package/packs/sidekick/manifest.ts +0 -512
  104. package/packs/sidekick/pack-registration.ts +0 -110
  105. package/packs/sidekick/policy-factory.ts +0 -38
  106. package/packs/sidekick/sidekick-events.ts +0 -694
  107. package/packs/sidekick/src/adapters/cloud-queue.ts +0 -101
  108. package/packs/sidekick/src/adapters/control-plane-bridge.adapter.ts +0 -386
  109. package/packs/sidekick/src/adapters/filesystem-bridge.adapter.ts +0 -228
  110. package/packs/sidekick/src/domain/channel.types.ts +0 -64
  111. package/packs/sidekick/src/ports/channel-bridge.port.ts +0 -92
  112. package/packs/sidekick/src/routines/commit.ts +0 -74
  113. package/packs/sidekick/tool-impl/channel-tools.ts +0 -577
  114. package/packs/sidekick/tool-impl/channel-transports.ts +0 -75
  115. package/packs/sidekick/tool-impl/index.ts +0 -29
  116. package/packs/sidekick/tool-impl/memory-tools.ts +0 -290
  117. package/packs/sidekick/tool-impl/routine-commit.ts +0 -102
  118. package/packs/sidekick/tool-impl/routine-tools.ts +0 -440
  119. package/packs/sidekick/tool-impl/runtime-context.ts +0 -28
  120. package/packs/sidekick/tool-impl/shared.ts +0 -125
  121. package/packs/sidekick/tool-impl/storage.ts +0 -325
  122. package/packs/sidekick/tool-impl/system-tools.ts +0 -160
  123. package/packs/sidekick/tool-impl/task-tools.ts +0 -506
  124. package/packs/sidekick/tools/channel-tools.ts +0 -53
  125. package/packs/sidekick/tools/index.ts +0 -9
  126. package/packs/sidekick/tools/memory-tools.ts +0 -53
  127. package/packs/sidekick/tools/routine-tools.ts +0 -53
  128. package/packs/sidekick/tools/system-tools.ts +0 -47
  129. package/packs/sidekick/tools/task-tools.ts +0 -61
  130. package/packs/sidekick/tools/types.ts +0 -57
  131. package/packs/sidekick/vitest.config.ts +0 -11
  132. package/packs/software-delivery/constants.ts +0 -10
  133. package/packs/software-delivery/extensions.ts +0 -140
  134. package/packs/software-delivery/gate-policies.ts +0 -134
  135. package/packs/software-delivery/index.ts +0 -8
  136. package/packs/software-delivery/manifest-schema.ts +0 -268
  137. package/packs/software-delivery/manifest.ts +0 -657
  138. package/packs/software-delivery/pack-registration.ts +0 -113
  139. package/packs/software-delivery/src/commands/index.ts +0 -5
  140. package/packs/software-delivery/src/config/delivery-review-contract.ts +0 -256
  141. package/packs/software-delivery/src/config/env-accessors.ts +0 -66
  142. package/packs/software-delivery/src/config/index.ts +0 -8
  143. package/packs/software-delivery/src/config/normalize-config-keys.ts +0 -9
  144. package/packs/software-delivery/src/config/schemas/lumenflow-config-schema-types.ts +0 -460
  145. package/packs/software-delivery/src/config/workspace-reader.ts +0 -375
  146. package/packs/software-delivery/src/constants/backlog-patterns.ts +0 -31
  147. package/packs/software-delivery/src/constants/client-ids.ts +0 -19
  148. package/packs/software-delivery/src/constants/config-contract.ts +0 -7
  149. package/packs/software-delivery/src/constants/docs-layout-presets.ts +0 -50
  150. package/packs/software-delivery/src/constants/duration-constants.ts +0 -20
  151. package/packs/software-delivery/src/constants/gate-constants.ts +0 -32
  152. package/packs/software-delivery/src/constants/index.ts +0 -29
  153. package/packs/software-delivery/src/constants/lock-constants.ts +0 -35
  154. package/packs/software-delivery/src/constants/object-guards.ts +0 -12
  155. package/packs/software-delivery/src/constants/section-headings.ts +0 -107
  156. package/packs/software-delivery/src/constants/wu-cli-constants.ts +0 -488
  157. package/packs/software-delivery/src/constants/wu-domain-constants.ts +0 -466
  158. package/packs/software-delivery/src/constants/wu-git-constants.ts +0 -7
  159. package/packs/software-delivery/src/constants/wu-id-format.ts +0 -327
  160. package/packs/software-delivery/src/constants/wu-paths-constants.ts +0 -384
  161. package/packs/software-delivery/src/constants/wu-statuses.ts +0 -287
  162. package/packs/software-delivery/src/constants/wu-type-helpers.ts +0 -67
  163. package/packs/software-delivery/src/constants/wu-ui-constants.ts +0 -267
  164. package/packs/software-delivery/src/constants/wu-validation-constants.ts +0 -73
  165. package/packs/software-delivery/src/domain/index.ts +0 -5
  166. package/packs/software-delivery/src/domain/orchestration.constants.ts +0 -166
  167. package/packs/software-delivery/src/domain/orchestration.schemas.ts +0 -238
  168. package/packs/software-delivery/src/domain/orchestration.types.ts +0 -176
  169. package/packs/software-delivery/src/methodology/incremental-test.ts +0 -122
  170. package/packs/software-delivery/src/methodology/index.ts +0 -6
  171. package/packs/software-delivery/src/methodology/manual-test-validator.ts +0 -292
  172. package/packs/software-delivery/src/policy/coverage-gate.ts +0 -270
  173. package/packs/software-delivery/src/policy/gates-agent-mode.ts +0 -223
  174. package/packs/software-delivery/src/policy/gates-config-internal.ts +0 -121
  175. package/packs/software-delivery/src/policy/gates-config.ts +0 -300
  176. package/packs/software-delivery/src/policy/gates-coverage.ts +0 -356
  177. package/packs/software-delivery/src/policy/gates-presets.ts +0 -134
  178. package/packs/software-delivery/src/policy/gates-schemas.ts +0 -173
  179. package/packs/software-delivery/src/policy/index.ts +0 -22
  180. package/packs/software-delivery/src/policy/package-manager-resolver.ts +0 -319
  181. package/packs/software-delivery/src/policy/resolve-policy.ts +0 -601
  182. package/packs/software-delivery/src/ports/config.ports.ts +0 -90
  183. package/packs/software-delivery/src/ports/dashboard-renderer.port.ts +0 -125
  184. package/packs/software-delivery/src/ports/index.ts +0 -10
  185. package/packs/software-delivery/src/ports/sync-validator.ports.ts +0 -59
  186. package/packs/software-delivery/src/ports/wu-helpers.ports.ts +0 -168
  187. package/packs/software-delivery/src/ports/wu-state.ports.ts +0 -241
  188. package/packs/software-delivery/src/primitives/index.ts +0 -5
  189. package/packs/software-delivery/src/runtime/index.ts +0 -6
  190. package/packs/software-delivery/src/runtime/work-classifier.ts +0 -561
  191. package/packs/software-delivery/src/sandbox/index.ts +0 -10
  192. package/packs/software-delivery/src/sandbox/sandbox-allowlist.ts +0 -118
  193. package/packs/software-delivery/src/sandbox/sandbox-backend-linux.ts +0 -88
  194. package/packs/software-delivery/src/sandbox/sandbox-backend-macos.ts +0 -154
  195. package/packs/software-delivery/src/sandbox/sandbox-backend-windows.ts +0 -47
  196. package/packs/software-delivery/src/sandbox/sandbox-profile.ts +0 -153
  197. package/packs/software-delivery/src/schemas/index.ts +0 -5
  198. package/packs/software-delivery/src/state/date-utils.ts +0 -158
  199. package/packs/software-delivery/src/state/index.ts +0 -15
  200. package/packs/software-delivery/src/state/state-machine.ts +0 -119
  201. package/packs/software-delivery/src/state/wu-doc-types.ts +0 -51
  202. package/packs/software-delivery/src/state/wu-paths.ts +0 -381
  203. package/packs/software-delivery/src/state/wu-schema.ts +0 -1139
  204. package/packs/software-delivery/src/state/wu-state-schema.ts +0 -255
  205. package/packs/software-delivery/src/state/wu-yaml.ts +0 -338
  206. package/packs/software-delivery/tool-impl/agent-tools.ts +0 -263
  207. package/packs/software-delivery/tool-impl/delegation-tools.ts +0 -66
  208. package/packs/software-delivery/tool-impl/flow-metrics-tools.ts +0 -219
  209. package/packs/software-delivery/tool-impl/git-runner.ts +0 -113
  210. package/packs/software-delivery/tool-impl/git-tools.ts +0 -316
  211. package/packs/software-delivery/tool-impl/index.ts +0 -15
  212. package/packs/software-delivery/tool-impl/initiative-orchestration-tools.ts +0 -720
  213. package/packs/software-delivery/tool-impl/lane-lock.ts +0 -246
  214. package/packs/software-delivery/tool-impl/memory-tools.ts +0 -470
  215. package/packs/software-delivery/tool-impl/pending-runtime-tools.ts +0 -21
  216. package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +0 -329
  217. package/packs/software-delivery/tool-impl/runtime-native-tools.ts +0 -687
  218. package/packs/software-delivery/tool-impl/worker-loader.ts +0 -52
  219. package/packs/software-delivery/tool-impl/worktree-tools.ts +0 -46
  220. package/packs/software-delivery/tool-impl/wu-lifecycle-tools.ts +0 -807
  221. package/packs/software-delivery/tools/delegation-tools.ts +0 -23
  222. package/packs/software-delivery/tools/git-tools.ts +0 -55
  223. package/packs/software-delivery/tools/index.ts +0 -8
  224. package/packs/software-delivery/tools/lane-lock-tool.ts +0 -37
  225. package/packs/software-delivery/tools/types.ts +0 -71
  226. package/packs/software-delivery/tools/worktree-tools.ts +0 -49
  227. package/packs/software-delivery/vitest.config.ts +0 -11
@@ -1,255 +0,0 @@
1
- // Copyright (c) 2026 Hellmai Ltd
2
- // SPDX-License-Identifier: LicenseRef-LumenFlow-Proprietary
3
-
4
- /**
5
- * WU State Schema (WU-1570)
6
- *
7
- * Zod schemas for WU state event validation.
8
- * Defines event types for WU lifecycle: create, claim, block, unblock, complete.
9
- *
10
- * @see {@link packages/@lumenflow/cli/src/lib/__tests__/wu-state-store.test.ts} - Tests
11
- */
12
-
13
- import { z } from 'zod';
14
-
15
- /**
16
- * WU event types
17
- *
18
- * - create: WU created (transitions to ready)
19
- * - claim: WU claimed (transitions to in_progress)
20
- * - block: WU blocked (transitions to blocked)
21
- * - unblock: WU unblocked (transitions back to in_progress)
22
- * - complete: WU completed (transitions to done)
23
- * - checkpoint: Progress checkpoint (WU-1748: cross-agent visibility)
24
- * - delegation: WU delegated from parent (WU-1947: parent-child relationships)
25
- * - release: WU released (WU-1080: transitions from in_progress to ready for orphan recovery)
26
- * - wu_renamed: WU id canonicalized or normalized (WU-2552: append-only rename, never rewrites history)
27
- */
28
- export const WU_EVENT_TYPES = [
29
- 'create',
30
- 'claim',
31
- 'block',
32
- 'unblock',
33
- 'complete',
34
- 'checkpoint',
35
- 'delegation',
36
- 'release',
37
- 'wu_renamed',
38
- ] as const;
39
-
40
- /** Type for WU event types */
41
- export type WUEventType = (typeof WU_EVENT_TYPES)[number];
42
-
43
- /**
44
- * WU Event Type constant object (WU-2044)
45
- *
46
- * Named constants for event type strings, analogous to WU_STATUS.
47
- * Use WU_EVENT_TYPE.CLAIM instead of raw 'claim' strings.
48
- */
49
- export const WU_EVENT_TYPE = Object.freeze({
50
- CREATE: 'create' as const,
51
- CLAIM: 'claim' as const,
52
- BLOCK: 'block' as const,
53
- UNBLOCK: 'unblock' as const,
54
- COMPLETE: 'complete' as const,
55
- CHECKPOINT: 'checkpoint' as const,
56
- DELEGATION: 'delegation' as const,
57
- RELEASE: 'release' as const,
58
- WU_RENAMED: 'wu_renamed' as const,
59
- });
60
-
61
- /**
62
- * WU status values (matches LumenFlow state machine)
63
- */
64
- export const WU_STATUSES = ['ready', 'in_progress', 'blocked', 'waiting', 'done'] as const;
65
-
66
- /** Type for WU status values */
67
- export type WUStatus = (typeof WU_STATUSES)[number];
68
-
69
- /**
70
- * Regex patterns for WU validation
71
- */
72
- export const WU_PATTERNS = {
73
- /** WU ID format: WU-{digits} */
74
- WU_ID: /^WU-\d+$/,
75
- };
76
-
77
- /**
78
- * Error messages for schema validation
79
- */
80
- const ERROR_MESSAGES = {
81
- EVENT_TYPE: `Event type must be one of: ${WU_EVENT_TYPES.join(', ')}`,
82
- WU_ID: 'WU ID must match pattern WU-XXX (e.g., WU-1570)',
83
- LANE_REQUIRED: 'Lane is required',
84
- TITLE_REQUIRED: 'Title is required',
85
- REASON_REQUIRED: 'Reason is required',
86
- TIMESTAMP_REQUIRED: 'Timestamp is required',
87
- };
88
-
89
- /**
90
- * Base event schema (common fields for all events)
91
- */
92
- const BaseEventSchema = z.object({
93
- /** Event type */
94
- type: z.enum(WU_EVENT_TYPES, {
95
- error: ERROR_MESSAGES.EVENT_TYPE,
96
- }),
97
-
98
- /** WU ID */
99
- wuId: z.string().regex(WU_PATTERNS.WU_ID, { message: ERROR_MESSAGES.WU_ID }),
100
-
101
- /** Event timestamp (ISO 8601 datetime) */
102
- timestamp: z.string().datetime({ message: ERROR_MESSAGES.TIMESTAMP_REQUIRED }),
103
- });
104
-
105
- /**
106
- * Create event schema
107
- */
108
- export const CreateEventSchema = BaseEventSchema.extend({
109
- type: z.literal('create'),
110
- lane: z.string().min(1, { message: ERROR_MESSAGES.LANE_REQUIRED }),
111
- title: z.string().min(1, { message: ERROR_MESSAGES.TITLE_REQUIRED }),
112
- });
113
-
114
- /**
115
- * Claim event schema
116
- */
117
- export const ClaimEventSchema = BaseEventSchema.extend({
118
- type: z.literal('claim'),
119
- lane: z.string().min(1, { message: ERROR_MESSAGES.LANE_REQUIRED }),
120
- title: z.string().min(1, { message: ERROR_MESSAGES.TITLE_REQUIRED }),
121
- });
122
-
123
- /**
124
- * Block event schema
125
- */
126
- export const BlockEventSchema = BaseEventSchema.extend({
127
- type: z.literal('block'),
128
- reason: z.string().min(1, { message: ERROR_MESSAGES.REASON_REQUIRED }),
129
- });
130
-
131
- /**
132
- * Unblock event schema
133
- */
134
- export const UnblockEventSchema = BaseEventSchema.extend({
135
- type: z.literal('unblock'),
136
- });
137
-
138
- /**
139
- * Complete event schema
140
- */
141
- export const CompleteEventSchema = BaseEventSchema.extend({
142
- type: z.literal('complete'),
143
- });
144
-
145
- /**
146
- * Checkpoint event schema (WU-1748: cross-agent visibility)
147
- * Records progress checkpoints for abandoned WU detection
148
- */
149
- export const CheckpointEventSchema = BaseEventSchema.extend({
150
- type: z.literal('checkpoint'),
151
- /** Checkpoint note/description */
152
- note: z.string().min(1, { message: 'Checkpoint note is required' }),
153
- /** Optional session ID */
154
- sessionId: z.string().optional(),
155
- /** Optional progress summary */
156
- progress: z.string().optional(),
157
- /** Optional next steps */
158
- nextSteps: z.string().optional(),
159
- });
160
-
161
- /**
162
- * Delegation event schema (WU-1947: parent-child relationships)
163
- * Records WU delegation relationships for tracking parent-child WUs
164
- */
165
- export const DelegationEventSchema = BaseEventSchema.extend({
166
- type: z.literal('delegation'),
167
- /** Parent WU ID that delegated this WU */
168
- parentWuId: z
169
- .string()
170
- .regex(WU_PATTERNS.WU_ID, { message: 'Parent WU ID must match pattern WU-XXX' }),
171
- /** Unique delegation identifier */
172
- delegationId: z.string().min(1, { message: 'Delegation ID is required' }),
173
- });
174
-
175
- /**
176
- * Release event schema (WU-1080: orphan recovery)
177
- * Releases an in_progress WU back to ready state when agent is interrupted.
178
- * Allows another agent to reclaim the orphaned WU.
179
- */
180
- export const ReleaseEventSchema = BaseEventSchema.extend({
181
- type: z.literal('release'),
182
- /** Reason for releasing the WU */
183
- reason: z.string().min(1, { message: ERROR_MESSAGES.REASON_REQUIRED }),
184
- });
185
-
186
- /**
187
- * WU renamed event schema (WU-2552: canonical WU IDs)
188
- *
189
- * Records a WU id change without rewriting history. Historical events
190
- * before the rename keep their original wuId field (audit trail intact).
191
- * Projections use {@link buildRenameProjection} to resolve an original id
192
- * to its current canonical id.
193
- *
194
- * Invariants:
195
- * - `wuId` field mirrors `from` so filter-by-wuId still returns this event
196
- * for queries about the original id.
197
- * - `from` and `to` accept any WU ID matching WU_PATTERNS.WU_ID, which is
198
- * intentionally permissive (matches both padded and unpadded legacy IDs).
199
- */
200
- export const WURenamedEventSchema = BaseEventSchema.extend({
201
- type: z.literal('wu_renamed'),
202
- /** Original WU ID (what the WU was called before the rename) */
203
- from: z.string().regex(WU_PATTERNS.WU_ID, { message: ERROR_MESSAGES.WU_ID }),
204
- /** New WU ID (what the WU is called after the rename) */
205
- to: z.string().regex(WU_PATTERNS.WU_ID, { message: ERROR_MESSAGES.WU_ID }),
206
- /** Optional human reason for the rename (e.g. 'canonicalize WU-5 to WU-0005') */
207
- reason: z.string().optional(),
208
- });
209
-
210
- /**
211
- * Union schema for all event types
212
- */
213
- export const WUEventSchema = z.discriminatedUnion('type', [
214
- CreateEventSchema,
215
- ClaimEventSchema,
216
- BlockEventSchema,
217
- UnblockEventSchema,
218
- CompleteEventSchema,
219
- CheckpointEventSchema,
220
- DelegationEventSchema,
221
- ReleaseEventSchema,
222
- WURenamedEventSchema,
223
- ]);
224
-
225
- /**
226
- * TypeScript types inferred from schemas
227
- */
228
- export type CreateEvent = z.infer<typeof CreateEventSchema>;
229
- export type ClaimEvent = z.infer<typeof ClaimEventSchema>;
230
- export type BlockEvent = z.infer<typeof BlockEventSchema>;
231
- export type UnblockEvent = z.infer<typeof UnblockEventSchema>;
232
- export type CompleteEvent = z.infer<typeof CompleteEventSchema>;
233
- export type CheckpointEvent = z.infer<typeof CheckpointEventSchema>;
234
- export type DelegationEvent = z.infer<typeof DelegationEventSchema>;
235
- export type ReleaseEvent = z.infer<typeof ReleaseEventSchema>;
236
- export type WURenamedEvent = z.infer<typeof WURenamedEventSchema>;
237
- export type WUEvent = z.infer<typeof WUEventSchema>;
238
-
239
- /**
240
- * Validates WU event data against schema
241
- *
242
- * @param {unknown} data - Data to validate
243
- * @returns {z.SafeParseReturnType<WUEvent, WUEvent>} Validation result
244
- *
245
- * @example
246
- * const result = validateWUEvent(eventData);
247
- * if (!result.success) {
248
- * result.error.issues.forEach(issue => {
249
- * console.error(`${issue.path.join('.')}: ${issue.message}`);
250
- * });
251
- * }
252
- */
253
- export function validateWUEvent(data: unknown) {
254
- return WUEventSchema.safeParse(data);
255
- }
@@ -1,338 +0,0 @@
1
- // Copyright (c) 2026 Hellmai Ltd
2
- // SPDX-License-Identifier: LicenseRef-LumenFlow-Proprietary
3
-
4
- import { existsSync, readFileSync, writeFileSync, promises as fs } from 'node:fs';
5
-
6
- import {
7
- createError,
8
- ErrorCodes,
9
- getErrorMessage,
10
- } from '@lumenflow/kernel/primitives/error-handler';
11
- import { parse, stringify } from 'yaml';
12
-
13
- import { STRING_LITERALS } from '../constants/wu-ui-constants.js';
14
-
15
- import { createWuPaths } from './wu-paths.js';
16
- import { BaseWUSchema } from './wu-schema.js';
17
-
18
- /**
19
- * Unified WU YAML I/O module.
20
- *
21
- * Replaces 4 duplicate read/write functions scattered across wu-claim, wu-done,
22
- * wu-block, and wu-unblock. Single source of truth for WU YAML operations.
23
- *
24
- * WU-1352: Standardized on yaml v2.8.1 (eemeli) with consistent stringify options.
25
- *
26
- * Functions:
27
- * - readWU(path, id): Read and validate WU YAML
28
- * - readWURaw(path): Read YAML without ID validation
29
- * - parseYAML(text): Parse YAML string to object
30
- * - writeWU(path, doc): Write WU YAML with consistent formatting
31
- * - stringifyYAML(doc): Stringify object to YAML with consistent formatting
32
- * - appendNote(doc, note): Append note to doc.notes field
33
- *
34
- * @example
35
- * import { readWU, writeWU, appendNote } from './lib/wu-yaml.js';
36
- * import { createWuPaths } from './wu-paths.js';
37
- *
38
- * const wuPaths = createWuPaths();
39
- *
40
- * // Read WU
41
- * const doc = readWU(wuPaths.WU('WU-123'), 'WU-123');
42
- *
43
- * // Modify doc
44
- * doc.status = 'in_progress';
45
- * appendNote(doc, 'Started work on this WU');
46
- *
47
- * // Write back
48
- * writeWU(wuPaths.WU('WU-123'), doc);
49
- */
50
-
51
- /**
52
- * WU-1352: YAML scalar type constants (from yaml library).
53
- * These match the string values expected by the yaml package.
54
- * @see https://github.com/eemeli/yaml/blob/main/docs/03_options.md
55
- */
56
- const YAML_SCALAR_TYPES = Object.freeze({
57
- /** Unquoted string (when safe) */
58
- PLAIN: 'PLAIN',
59
- /** Single-quoted string */
60
- QUOTE_SINGLE: 'QUOTE_SINGLE',
61
- /** Double-quoted string */
62
- QUOTE_DOUBLE: 'QUOTE_DOUBLE',
63
- /** Block literal (|) */
64
- BLOCK_LITERAL: 'BLOCK_LITERAL',
65
- /** Block folded (>) */
66
- BLOCK_FOLDED: 'BLOCK_FOLDED',
67
- });
68
-
69
- /** Standard line width for WU YAML files */
70
- const YAML_LINE_WIDTH = 100;
71
-
72
- /**
73
- * WU-1352: Standardized YAML stringify options.
74
- *
75
- * Ensures consistent output across all WU tools:
76
- * - lineWidth: 100 (wrap long lines)
77
- * - singleQuote: true (prefer 'single' over "double")
78
- * - defaultKeyType: PLAIN (unquoted keys when safe)
79
- *
80
- * @type {import('yaml').ToStringOptions}
81
- */
82
- export const YAML_STRINGIFY_OPTIONS = Object.freeze({
83
- lineWidth: YAML_LINE_WIDTH,
84
- singleQuote: true,
85
- defaultKeyType: YAML_SCALAR_TYPES.PLAIN,
86
- });
87
-
88
- /**
89
- * WU-2125: Parse YAML content string into a validated object.
90
- *
91
- * Shared parse boundary for all read functions. Wraps YAML parse errors
92
- * with structured error codes and path context.
93
- *
94
- * @param {string} text - Raw YAML content
95
- * @param {string} sourcePath - File path (for error messages)
96
- * @returns {Record<string, unknown>} Parsed document
97
- * @throws {Error} YAML_PARSE_ERROR if YAML is invalid
98
- */
99
- function parseWUYaml(text: string, sourcePath: string): Record<string, unknown> {
100
- try {
101
- return parse(text) as Record<string, unknown>;
102
- } catch (e: unknown) {
103
- const msg = getErrorMessage(e);
104
- throw createError(ErrorCodes.YAML_PARSE_ERROR, `Failed to parse YAML ${sourcePath}: ${msg}`, {
105
- path: sourcePath,
106
- originalError: msg,
107
- });
108
- }
109
- }
110
-
111
- /**
112
- * WU-2125: Validate that a parsed WU document's id field matches the expected ID.
113
- *
114
- * @param {unknown} doc - Parsed YAML document (may be null for empty files)
115
- * @param {string} expectedId - Expected WU ID (e.g., 'WU-123')
116
- * @param {string} wuPath - File path (for error messages)
117
- * @returns {Record<string, unknown>} Validated document
118
- * @throws {Error} WU_NOT_FOUND if doc is null or ID does not match
119
- */
120
- function validateWUId(doc: unknown, expectedId: string, wuPath: string): Record<string, unknown> {
121
- const parsed = doc as Record<string, unknown> | null;
122
- if (!parsed || parsed.id !== expectedId) {
123
- throw createError(
124
- ErrorCodes.WU_NOT_FOUND,
125
- `WU YAML id mismatch. Expected ${expectedId}, found ${parsed && parsed.id}`,
126
- { path: wuPath, expectedId, foundId: parsed && parsed.id },
127
- );
128
- }
129
- return parsed;
130
- }
131
-
132
- /**
133
- * Read and parse WU YAML file.
134
- *
135
- * Validates:
136
- * - File exists
137
- * - YAML is valid
138
- * - WU ID matches expected ID
139
- *
140
- * @param {string} wuPath - Path to WU YAML file
141
- * @param {string} expectedId - Expected WU ID (e.g., 'WU-123')
142
- * @returns {object} Parsed YAML document
143
- * @throws {Error} If file not found, YAML invalid, or ID mismatch
144
- */
145
- export function readWU(wuPath: string, expectedId: string): Record<string, unknown> {
146
- if (!existsSync(wuPath)) {
147
- throw createError(ErrorCodes.FILE_NOT_FOUND, `WU file not found: ${wuPath}`, {
148
- path: wuPath,
149
- expectedId,
150
- });
151
- }
152
-
153
- const text = readFileSync(wuPath, { encoding: 'utf-8' });
154
- const doc = parseWUYaml(text, wuPath);
155
- return validateWUId(doc, expectedId, wuPath);
156
- }
157
-
158
- /**
159
- * Read and parse WU YAML file asynchronously.
160
- *
161
- * Validates:
162
- * - File exists
163
- * - YAML is valid
164
- * - WU ID matches expected ID
165
- *
166
- * @param {string} wuPath - Path to WU YAML file
167
- * @param {string} expectedId - Expected WU ID (e.g., 'WU-123')
168
- * @returns {Promise<object>} Parsed YAML document
169
- * @throws {Error} If file not found, YAML invalid, or ID mismatch
170
- */
171
- export async function readWUAsync(
172
- wuPath: string,
173
- expectedId: string,
174
- ): Promise<Record<string, unknown>> {
175
- try {
176
- const text = await fs.readFile(wuPath, { encoding: 'utf-8' });
177
- const doc = parseWUYaml(text, wuPath);
178
- return validateWUId(doc, expectedId, wuPath);
179
- } catch (err: unknown) {
180
- const errObj = err as { code?: string };
181
- if (errObj.code === 'ENOENT') {
182
- throw createError(ErrorCodes.FILE_NOT_FOUND, `WU file not found: ${wuPath}`, {
183
- path: wuPath,
184
- expectedId,
185
- });
186
- }
187
- throw err;
188
- }
189
- }
190
-
191
- /**
192
- * Parse YAML string to object.
193
- * WU-1352: Centralized YAML parsing for consistency.
194
- *
195
- * @param {string} text - YAML string to parse
196
- * @returns {object} Parsed object
197
- * @throws {Error} If YAML is invalid
198
- */
199
- export function parseYAML(text: string): Record<string, unknown> {
200
- return parse(text) as Record<string, unknown>;
201
- }
202
-
203
- /**
204
- * Stringify object to YAML with standardized options.
205
- * WU-1352: Centralized YAML serialization for consistency.
206
- *
207
- * @param {object} doc - Object to stringify
208
- * @param {object} [options] - Additional stringify options (merged with YAML_STRINGIFY_OPTIONS)
209
- * @returns {string} YAML string
210
- */
211
- export function stringifyYAML(doc: unknown, options: Record<string, unknown> = {}): string {
212
- return stringify(doc, { ...YAML_STRINGIFY_OPTIONS, ...options });
213
- }
214
-
215
- /**
216
- * Read and parse YAML file without ID validation.
217
- * WU-1352: For cases where you don't know/need to validate the WU ID.
218
- *
219
- * @param {string} yamlPath - Path to YAML file
220
- * @returns {object} Parsed YAML document
221
- * @throws {Error} If file not found or YAML invalid
222
- */
223
- export function readWURaw(yamlPath: string): Record<string, unknown> {
224
- if (!existsSync(yamlPath)) {
225
- throw createError(ErrorCodes.FILE_NOT_FOUND, `YAML file not found: ${yamlPath}`, {
226
- path: yamlPath,
227
- });
228
- }
229
-
230
- const text = readFileSync(yamlPath, { encoding: 'utf-8' });
231
- return parseWUYaml(text, yamlPath);
232
- }
233
-
234
- /**
235
- * Read and parse YAML file without ID validation asynchronously.
236
- * WU-1352: For cases where you don't know/need to validate the WU ID.
237
- *
238
- * @param {string} yamlPath - Path to YAML file
239
- * @returns {Promise<object>} Parsed YAML document
240
- * @throws {Error} If file not found or YAML invalid
241
- */
242
- export async function readWURawAsync(yamlPath: string): Promise<Record<string, unknown>> {
243
- try {
244
- const text = await fs.readFile(yamlPath, { encoding: 'utf-8' });
245
- return parseWUYaml(text, yamlPath);
246
- } catch (err: unknown) {
247
- const errObj = err as { code?: string };
248
- if (errObj.code === 'ENOENT') {
249
- throw createError(ErrorCodes.FILE_NOT_FOUND, `YAML file not found: ${yamlPath}`, {
250
- path: yamlPath,
251
- });
252
- }
253
- throw err;
254
- }
255
- }
256
-
257
- /**
258
- * Write WU YAML file with consistent formatting.
259
- * WU-1352: Uses YAML_STRINGIFY_OPTIONS for consistent output.
260
- * WU-2115: Validates doc against BaseWUSchema before writing to prevent
261
- * malformed WU YAML from being silently persisted.
262
- *
263
- * @param {string} wuPath - Path to WU YAML file
264
- * @param {object} doc - YAML document to write
265
- * @throws {ZodError} If doc fails BaseWUSchema validation
266
- */
267
- export function writeWU(wuPath: string, doc: unknown): void {
268
- // WU-2115: Validate against schema before writing — throws ZodError on invalid data
269
- BaseWUSchema.parse(doc);
270
- const out = stringify(doc, YAML_STRINGIFY_OPTIONS);
271
- writeFileSync(wuPath, out, { encoding: 'utf-8' });
272
- }
273
-
274
- /**
275
- * Append note to WU document's notes field.
276
- *
277
- * Always outputs a string (Zod schema requires string type).
278
- * Handles various input formats:
279
- * - undefined/null/empty: Set note directly as string
280
- * - string: Append with newline separator
281
- * - array: Convert to newline-separated string, then append
282
- * - other: Replace with note
283
- *
284
- * @param {object} doc - WU document
285
- * @param {string} note - Note to append
286
- */
287
- export function appendNote(doc: Record<string, unknown>, note: string): void {
288
- // Do nothing if note is falsy
289
- if (!note) return;
290
-
291
- const existing = doc.notes;
292
-
293
- if (existing === undefined || existing === null || existing === '') {
294
- // No existing notes: set directly as string
295
- doc.notes = note;
296
- } else if (Array.isArray(existing)) {
297
- // Array notes: convert to string first (schema requires string), then append
298
- const joined = existing.filter(Boolean).join(STRING_LITERALS.NEWLINE).trimEnd();
299
- doc.notes = joined ? `${joined}${STRING_LITERALS.NEWLINE}${note}` : note;
300
- } else if (typeof existing === 'string') {
301
- // String notes: append with newline
302
- const trimmed = existing.trimEnd();
303
- doc.notes = trimmed ? `${trimmed}${STRING_LITERALS.NEWLINE}${note}` : note;
304
- } else {
305
- // Invalid type: replace with note
306
- doc.notes = note;
307
- }
308
- }
309
-
310
- /**
311
- * Append an agent session entry to a WU's agent_sessions[] array
312
- *
313
- * @param {string} wuId - WU ID (e.g., "WU-1234")
314
- * @param {object} sessionData - Session summary from endSession()
315
- * @throws {Error} if WU file not found
316
- */
317
- export function appendAgentSession(wuId: string, sessionData: Record<string, unknown>): void {
318
- const paths = createWuPaths();
319
- const wuPath = paths.WU(wuId);
320
-
321
- if (!existsSync(wuPath)) {
322
- throw createError(ErrorCodes.FILE_NOT_FOUND, `WU file not found: ${wuPath}`);
323
- }
324
-
325
- // Parse WU YAML
326
- const doc = readWU(wuPath, wuId);
327
-
328
- // Initialize agent_sessions array if needed
329
- if (!Array.isArray(doc.agent_sessions)) {
330
- doc.agent_sessions = [];
331
- }
332
-
333
- // Append session
334
- (doc.agent_sessions as unknown[]).push(sessionData);
335
-
336
- // Write back
337
- writeWU(wuPath, doc);
338
- }