@lumenflow/cli 5.5.0 → 5.7.14

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