@lumenflow/cli 5.5.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 (213) 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 +37 -0
  7. package/dist/gate-defaults.js.map +1 -1
  8. package/dist/gates/monolithic-file-contention-guard.js +167 -0
  9. package/dist/gates/monolithic-file-contention-guard.js.map +1 -0
  10. package/dist/gates/prod-migration-drift.js +207 -0
  11. package/dist/gates/prod-migration-drift.js.map +1 -0
  12. package/dist/gates/test-over-deletion-guard.js +255 -0
  13. package/dist/gates/test-over-deletion-guard.js.map +1 -0
  14. package/dist/gates-runners.js +44 -3
  15. package/dist/gates-runners.js.map +1 -1
  16. package/dist/gates.js +3 -2
  17. package/dist/gates.js.map +1 -1
  18. package/dist/lumenflow-setup.js +144 -0
  19. package/dist/lumenflow-setup.js.map +1 -0
  20. package/dist/lumenflow-upgrade.js +2 -1
  21. package/dist/lumenflow-upgrade.js.map +1 -1
  22. package/dist/mem-create.js +10 -1
  23. package/dist/mem-create.js.map +1 -1
  24. package/dist/mem-signal.js +21 -4
  25. package/dist/mem-signal.js.map +1 -1
  26. package/dist/orchestrate-initiative.js +28 -3
  27. package/dist/orchestrate-initiative.js.map +1 -1
  28. package/dist/public-manifest.js +17 -0
  29. package/dist/public-manifest.js.map +1 -1
  30. package/dist/release.js +53 -18
  31. package/dist/release.js.map +1 -1
  32. package/dist/wu-done-gates.js +13 -9
  33. package/dist/wu-done-gates.js.map +1 -1
  34. package/dist/wu-edit-operations.js +74 -0
  35. package/dist/wu-edit-operations.js.map +1 -1
  36. package/dist/wu-edit-validators.js +58 -0
  37. package/dist/wu-edit-validators.js.map +1 -1
  38. package/dist/wu-edit.js +106 -4
  39. package/dist/wu-edit.js.map +1 -1
  40. package/dist/wu-prep.js +41 -7
  41. package/dist/wu-prep.js.map +1 -1
  42. package/dist/wu-recover.js +6 -0
  43. package/dist/wu-recover.js.map +1 -1
  44. package/dist/wu-release.js +120 -2
  45. package/dist/wu-release.js.map +1 -1
  46. package/dist/wu-sizing-validation.js +47 -17
  47. package/dist/wu-sizing-validation.js.map +1 -1
  48. package/dist/wu-status.js +33 -0
  49. package/dist/wu-status.js.map +1 -1
  50. package/package.json +13 -11
  51. package/packs/agent-runtime/package.json +1 -1
  52. package/packs/sidekick/package.json +1 -1
  53. package/packs/software-delivery/package.json +1 -1
  54. package/templates/core/AGENTS.md.template +67 -3
  55. package/templates/core/LUMENFLOW.md.template +197 -47
  56. package/packs/agent-runtime/agent-heartbeat.ts +0 -163
  57. package/packs/agent-runtime/auto-session-integration.ts +0 -888
  58. package/packs/agent-runtime/capability-factory.ts +0 -104
  59. package/packs/agent-runtime/constants.ts +0 -21
  60. package/packs/agent-runtime/delegation-registry-schema.ts +0 -220
  61. package/packs/agent-runtime/delegation-registry-store.ts +0 -269
  62. package/packs/agent-runtime/delegation-tree.ts +0 -328
  63. package/packs/agent-runtime/index.ts +0 -20
  64. package/packs/agent-runtime/manifest.ts +0 -348
  65. package/packs/agent-runtime/memory-coordination-contract.ts +0 -86
  66. package/packs/agent-runtime/orchestration.ts +0 -2027
  67. package/packs/agent-runtime/pack-registration.ts +0 -110
  68. package/packs/agent-runtime/policy-factory.ts +0 -165
  69. package/packs/agent-runtime/remote-controls/index.ts +0 -7
  70. package/packs/agent-runtime/remote-controls/operations.ts +0 -405
  71. package/packs/agent-runtime/remote-controls/port.ts +0 -48
  72. package/packs/agent-runtime/remote-controls/state-store.ts +0 -258
  73. package/packs/agent-runtime/remote-controls/types.ts +0 -105
  74. package/packs/agent-runtime/session-schema.ts +0 -467
  75. package/packs/agent-runtime/tool-impl/agent-turn-tools.ts +0 -793
  76. package/packs/agent-runtime/tool-impl/index.ts +0 -6
  77. package/packs/agent-runtime/tool-impl/provider-adapters.ts +0 -1245
  78. package/packs/agent-runtime/tool-impl/remote-controls.mock.ts +0 -256
  79. package/packs/agent-runtime/tool-impl/remote-controls.ts +0 -273
  80. package/packs/agent-runtime/tools/index.ts +0 -4
  81. package/packs/agent-runtime/tools/types.ts +0 -47
  82. package/packs/agent-runtime/turn-lifecycle-events.ts +0 -590
  83. package/packs/agent-runtime/types.ts +0 -128
  84. package/packs/agent-runtime/vitest.config.ts +0 -11
  85. package/packs/sidekick/channel-ingress.ts +0 -137
  86. package/packs/sidekick/constants.ts +0 -10
  87. package/packs/sidekick/index.ts +0 -8
  88. package/packs/sidekick/manifest-schema.ts +0 -49
  89. package/packs/sidekick/manifest.ts +0 -512
  90. package/packs/sidekick/pack-registration.ts +0 -110
  91. package/packs/sidekick/policy-factory.ts +0 -38
  92. package/packs/sidekick/sidekick-events.ts +0 -694
  93. package/packs/sidekick/src/adapters/cloud-queue.ts +0 -101
  94. package/packs/sidekick/src/adapters/control-plane-bridge.adapter.ts +0 -386
  95. package/packs/sidekick/src/adapters/filesystem-bridge.adapter.ts +0 -228
  96. package/packs/sidekick/src/domain/channel.types.ts +0 -64
  97. package/packs/sidekick/src/ports/channel-bridge.port.ts +0 -92
  98. package/packs/sidekick/src/routines/commit.ts +0 -74
  99. package/packs/sidekick/tool-impl/channel-tools.ts +0 -577
  100. package/packs/sidekick/tool-impl/channel-transports.ts +0 -75
  101. package/packs/sidekick/tool-impl/index.ts +0 -29
  102. package/packs/sidekick/tool-impl/memory-tools.ts +0 -290
  103. package/packs/sidekick/tool-impl/routine-commit.ts +0 -102
  104. package/packs/sidekick/tool-impl/routine-tools.ts +0 -440
  105. package/packs/sidekick/tool-impl/runtime-context.ts +0 -28
  106. package/packs/sidekick/tool-impl/shared.ts +0 -125
  107. package/packs/sidekick/tool-impl/storage.ts +0 -325
  108. package/packs/sidekick/tool-impl/system-tools.ts +0 -160
  109. package/packs/sidekick/tool-impl/task-tools.ts +0 -506
  110. package/packs/sidekick/tools/channel-tools.ts +0 -53
  111. package/packs/sidekick/tools/index.ts +0 -9
  112. package/packs/sidekick/tools/memory-tools.ts +0 -53
  113. package/packs/sidekick/tools/routine-tools.ts +0 -53
  114. package/packs/sidekick/tools/system-tools.ts +0 -47
  115. package/packs/sidekick/tools/task-tools.ts +0 -61
  116. package/packs/sidekick/tools/types.ts +0 -57
  117. package/packs/sidekick/vitest.config.ts +0 -11
  118. package/packs/software-delivery/constants.ts +0 -10
  119. package/packs/software-delivery/extensions.ts +0 -140
  120. package/packs/software-delivery/gate-policies.ts +0 -134
  121. package/packs/software-delivery/index.ts +0 -8
  122. package/packs/software-delivery/manifest-schema.ts +0 -268
  123. package/packs/software-delivery/manifest.ts +0 -657
  124. package/packs/software-delivery/pack-registration.ts +0 -113
  125. package/packs/software-delivery/src/commands/index.ts +0 -5
  126. package/packs/software-delivery/src/config/delivery-review-contract.ts +0 -256
  127. package/packs/software-delivery/src/config/env-accessors.ts +0 -66
  128. package/packs/software-delivery/src/config/index.ts +0 -8
  129. package/packs/software-delivery/src/config/normalize-config-keys.ts +0 -9
  130. package/packs/software-delivery/src/config/schemas/lumenflow-config-schema-types.ts +0 -460
  131. package/packs/software-delivery/src/config/workspace-reader.ts +0 -375
  132. package/packs/software-delivery/src/constants/backlog-patterns.ts +0 -31
  133. package/packs/software-delivery/src/constants/client-ids.ts +0 -19
  134. package/packs/software-delivery/src/constants/config-contract.ts +0 -7
  135. package/packs/software-delivery/src/constants/docs-layout-presets.ts +0 -50
  136. package/packs/software-delivery/src/constants/duration-constants.ts +0 -20
  137. package/packs/software-delivery/src/constants/gate-constants.ts +0 -32
  138. package/packs/software-delivery/src/constants/index.ts +0 -29
  139. package/packs/software-delivery/src/constants/lock-constants.ts +0 -35
  140. package/packs/software-delivery/src/constants/object-guards.ts +0 -12
  141. package/packs/software-delivery/src/constants/section-headings.ts +0 -107
  142. package/packs/software-delivery/src/constants/wu-cli-constants.ts +0 -500
  143. package/packs/software-delivery/src/constants/wu-domain-constants.ts +0 -466
  144. package/packs/software-delivery/src/constants/wu-git-constants.ts +0 -7
  145. package/packs/software-delivery/src/constants/wu-id-format.ts +0 -327
  146. package/packs/software-delivery/src/constants/wu-paths-constants.ts +0 -384
  147. package/packs/software-delivery/src/constants/wu-statuses.ts +0 -287
  148. package/packs/software-delivery/src/constants/wu-type-helpers.ts +0 -67
  149. package/packs/software-delivery/src/constants/wu-ui-constants.ts +0 -267
  150. package/packs/software-delivery/src/constants/wu-validation-constants.ts +0 -73
  151. package/packs/software-delivery/src/domain/index.ts +0 -5
  152. package/packs/software-delivery/src/domain/orchestration.constants.ts +0 -166
  153. package/packs/software-delivery/src/domain/orchestration.schemas.ts +0 -238
  154. package/packs/software-delivery/src/domain/orchestration.types.ts +0 -176
  155. package/packs/software-delivery/src/methodology/incremental-test.ts +0 -122
  156. package/packs/software-delivery/src/methodology/index.ts +0 -6
  157. package/packs/software-delivery/src/methodology/manual-test-validator.ts +0 -292
  158. package/packs/software-delivery/src/policy/coverage-gate.ts +0 -270
  159. package/packs/software-delivery/src/policy/gates-agent-mode.ts +0 -223
  160. package/packs/software-delivery/src/policy/gates-config-internal.ts +0 -121
  161. package/packs/software-delivery/src/policy/gates-config.ts +0 -300
  162. package/packs/software-delivery/src/policy/gates-coverage.ts +0 -356
  163. package/packs/software-delivery/src/policy/gates-presets.ts +0 -134
  164. package/packs/software-delivery/src/policy/gates-schemas.ts +0 -173
  165. package/packs/software-delivery/src/policy/index.ts +0 -22
  166. package/packs/software-delivery/src/policy/package-manager-resolver.ts +0 -319
  167. package/packs/software-delivery/src/policy/resolve-policy.ts +0 -601
  168. package/packs/software-delivery/src/ports/config.ports.ts +0 -90
  169. package/packs/software-delivery/src/ports/dashboard-renderer.port.ts +0 -125
  170. package/packs/software-delivery/src/ports/index.ts +0 -10
  171. package/packs/software-delivery/src/ports/sync-validator.ports.ts +0 -59
  172. package/packs/software-delivery/src/ports/wu-helpers.ports.ts +0 -168
  173. package/packs/software-delivery/src/ports/wu-state.ports.ts +0 -241
  174. package/packs/software-delivery/src/primitives/index.ts +0 -5
  175. package/packs/software-delivery/src/runtime/index.ts +0 -6
  176. package/packs/software-delivery/src/runtime/work-classifier.ts +0 -561
  177. package/packs/software-delivery/src/sandbox/index.ts +0 -10
  178. package/packs/software-delivery/src/sandbox/sandbox-allowlist.ts +0 -118
  179. package/packs/software-delivery/src/sandbox/sandbox-backend-linux.ts +0 -88
  180. package/packs/software-delivery/src/sandbox/sandbox-backend-macos.ts +0 -154
  181. package/packs/software-delivery/src/sandbox/sandbox-backend-windows.ts +0 -47
  182. package/packs/software-delivery/src/sandbox/sandbox-profile.ts +0 -153
  183. package/packs/software-delivery/src/schemas/index.ts +0 -5
  184. package/packs/software-delivery/src/state/date-utils.ts +0 -158
  185. package/packs/software-delivery/src/state/index.ts +0 -15
  186. package/packs/software-delivery/src/state/state-machine.ts +0 -119
  187. package/packs/software-delivery/src/state/wu-doc-types.ts +0 -51
  188. package/packs/software-delivery/src/state/wu-paths.ts +0 -381
  189. package/packs/software-delivery/src/state/wu-schema.ts +0 -1139
  190. package/packs/software-delivery/src/state/wu-state-schema.ts +0 -255
  191. package/packs/software-delivery/src/state/wu-yaml.ts +0 -338
  192. package/packs/software-delivery/tool-impl/agent-tools.ts +0 -263
  193. package/packs/software-delivery/tool-impl/delegation-tools.ts +0 -66
  194. package/packs/software-delivery/tool-impl/flow-metrics-tools.ts +0 -219
  195. package/packs/software-delivery/tool-impl/git-runner.ts +0 -113
  196. package/packs/software-delivery/tool-impl/git-tools.ts +0 -316
  197. package/packs/software-delivery/tool-impl/index.ts +0 -15
  198. package/packs/software-delivery/tool-impl/initiative-orchestration-tools.ts +0 -720
  199. package/packs/software-delivery/tool-impl/lane-lock.ts +0 -246
  200. package/packs/software-delivery/tool-impl/memory-tools.ts +0 -470
  201. package/packs/software-delivery/tool-impl/pending-runtime-tools.ts +0 -21
  202. package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +0 -329
  203. package/packs/software-delivery/tool-impl/runtime-native-tools.ts +0 -687
  204. package/packs/software-delivery/tool-impl/worker-loader.ts +0 -52
  205. package/packs/software-delivery/tool-impl/worktree-tools.ts +0 -46
  206. package/packs/software-delivery/tool-impl/wu-lifecycle-tools.ts +0 -807
  207. package/packs/software-delivery/tools/delegation-tools.ts +0 -23
  208. package/packs/software-delivery/tools/git-tools.ts +0 -55
  209. package/packs/software-delivery/tools/index.ts +0 -8
  210. package/packs/software-delivery/tools/lane-lock-tool.ts +0 -37
  211. package/packs/software-delivery/tools/types.ts +0 -71
  212. package/packs/software-delivery/tools/worktree-tools.ts +0 -49
  213. 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
- }