@lumenflow/cli 3.12.6 → 3.12.8

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 (111) hide show
  1. package/dist/config-set.js +82 -32
  2. package/dist/config-set.js.map +1 -1
  3. package/dist/wu-claim.js +2 -1
  4. package/dist/wu-claim.js.map +1 -1
  5. package/dist/wu-done-policies.js +9 -9
  6. package/dist/wu-done-policies.js.map +1 -1
  7. package/dist/wu-spawn-strategy-resolver.js +14 -6
  8. package/dist/wu-spawn-strategy-resolver.js.map +1 -1
  9. package/package.json +8 -8
  10. package/packs/sidekick/.turbo/turbo-build.log +1 -1
  11. package/packs/sidekick/package.json +1 -1
  12. package/packs/software-delivery/.turbo/turbo-build.log +1 -1
  13. package/packs/software-delivery/package.json +1 -1
  14. package/dist/chunk-2D2VOCA4.js +0 -37
  15. package/dist/chunk-2D5KFYGX.js +0 -284
  16. package/dist/chunk-2GXVIN57.js +0 -14072
  17. package/dist/chunk-2MQ7HZWZ.js +0 -26
  18. package/dist/chunk-2UFQ3A3C.js +0 -643
  19. package/dist/chunk-3RG5ZIWI.js +0 -10
  20. package/dist/chunk-4N74J3UT.js +0 -15
  21. package/dist/chunk-5GTOXFYR.js +0 -392
  22. package/dist/chunk-5VY6MQMC.js +0 -240
  23. package/dist/chunk-67XVPMRY.js +0 -1297
  24. package/dist/chunk-6HO4GWJE.js +0 -164
  25. package/dist/chunk-6W5XHWYV.js +0 -1890
  26. package/dist/chunk-6X4EMYJQ.js +0 -64
  27. package/dist/chunk-6XYXI2NQ.js +0 -772
  28. package/dist/chunk-7ANSOV6Q.js +0 -285
  29. package/dist/chunk-A624LFLB.js +0 -1380
  30. package/dist/chunk-ADN5NHG4.js +0 -126
  31. package/dist/chunk-B7YJYJKG.js +0 -33
  32. package/dist/chunk-CCLHCPKG.js +0 -210
  33. package/dist/chunk-CK36VROC.js +0 -1584
  34. package/dist/chunk-D3UOFRSB.js +0 -81
  35. package/dist/chunk-DFR4DJBM.js +0 -230
  36. package/dist/chunk-DSYBDHYH.js +0 -79
  37. package/dist/chunk-DWMLTXKQ.js +0 -1176
  38. package/dist/chunk-E3REJTAJ.js +0 -28
  39. package/dist/chunk-EA3IVO64.js +0 -633
  40. package/dist/chunk-EK2AKZKD.js +0 -55
  41. package/dist/chunk-ELD7JTTT.js +0 -343
  42. package/dist/chunk-EX6TT2XI.js +0 -195
  43. package/dist/chunk-EXINSFZE.js +0 -82
  44. package/dist/chunk-EZ6ZBYBM.js +0 -510
  45. package/dist/chunk-FBKAPTJ2.js +0 -16
  46. package/dist/chunk-FVLV5RYH.js +0 -1118
  47. package/dist/chunk-GDNSBQVK.js +0 -2485
  48. package/dist/chunk-GPQHMBNN.js +0 -278
  49. package/dist/chunk-GTFJB67L.js +0 -68
  50. package/dist/chunk-HANJXVKW.js +0 -1127
  51. package/dist/chunk-HEVS5YLD.js +0 -269
  52. package/dist/chunk-HMEVZKPQ.js +0 -9
  53. package/dist/chunk-HRGSYNLM.js +0 -3511
  54. package/dist/chunk-ISZR5N4K.js +0 -60
  55. package/dist/chunk-J6SUPR2C.js +0 -226
  56. package/dist/chunk-JERYVEIZ.js +0 -244
  57. package/dist/chunk-JHHWGL2N.js +0 -87
  58. package/dist/chunk-JONWQUB5.js +0 -775
  59. package/dist/chunk-K2DIWWDM.js +0 -1766
  60. package/dist/chunk-KY4PGL5V.js +0 -969
  61. package/dist/chunk-L737LQ4C.js +0 -1285
  62. package/dist/chunk-LFTWYIB2.js +0 -497
  63. package/dist/chunk-LV47RFNJ.js +0 -41
  64. package/dist/chunk-MKSAITI7.js +0 -15
  65. package/dist/chunk-MZ7RKIX4.js +0 -212
  66. package/dist/chunk-NAP6CFSO.js +0 -84
  67. package/dist/chunk-ND6MY37M.js +0 -16
  68. package/dist/chunk-NMG736UR.js +0 -683
  69. package/dist/chunk-NRAXROED.js +0 -32
  70. package/dist/chunk-NRIZR3A7.js +0 -690
  71. package/dist/chunk-NX43BG3M.js +0 -233
  72. package/dist/chunk-O645XLSI.js +0 -297
  73. package/dist/chunk-OMJD6A3S.js +0 -235
  74. package/dist/chunk-QB6SJD4T.js +0 -430
  75. package/dist/chunk-QFSTL4J3.js +0 -276
  76. package/dist/chunk-QLGDFMFX.js +0 -212
  77. package/dist/chunk-RIAAGL2E.js +0 -13
  78. package/dist/chunk-RWO5XMZ6.js +0 -86
  79. package/dist/chunk-RXRKBBSM.js +0 -149
  80. package/dist/chunk-RZOZMML6.js +0 -363
  81. package/dist/chunk-U7I7FS7T.js +0 -113
  82. package/dist/chunk-UI42RODY.js +0 -717
  83. package/dist/chunk-UTVMVSCO.js +0 -519
  84. package/dist/chunk-V6OJGLBA.js +0 -1746
  85. package/dist/chunk-W2JHVH7D.js +0 -152
  86. package/dist/chunk-WD3Y7VQN.js +0 -280
  87. package/dist/chunk-WOCTQ5MS.js +0 -303
  88. package/dist/chunk-WZR3ZUNN.js +0 -696
  89. package/dist/chunk-XGI665H7.js +0 -150
  90. package/dist/chunk-XKY65P2T.js +0 -304
  91. package/dist/chunk-Y4CQZY65.js +0 -57
  92. package/dist/chunk-YFEXKLVE.js +0 -194
  93. package/dist/chunk-YHO3HS5X.js +0 -287
  94. package/dist/chunk-YLS7AZSX.js +0 -738
  95. package/dist/chunk-ZE473AO6.js +0 -49
  96. package/dist/chunk-ZF747T3O.js +0 -644
  97. package/dist/chunk-ZHCZHZH3.js +0 -43
  98. package/dist/chunk-ZZNZX2XY.js +0 -87
  99. package/dist/constants-7QAP3VQ4.js +0 -23
  100. package/dist/dist-IY3UUMWK.js +0 -33
  101. package/dist/invariants-runner-W5RGHCSU.js +0 -27
  102. package/dist/lane-lock-6J36HD5O.js +0 -35
  103. package/dist/mem-checkpoint-core-EANG2GVN.js +0 -14
  104. package/dist/mem-signal-core-2LZ2WYHW.js +0 -19
  105. package/dist/memory-store-OLB5FO7K.js +0 -18
  106. package/dist/service-6BYCOCO5.js +0 -13
  107. package/dist/spawn-policy-resolver-NTSZYQ6R.js +0 -17
  108. package/dist/spawn-task-builder-R4E2BHSW.js +0 -22
  109. package/dist/wu-done-pr-WLFFFEPJ.js +0 -25
  110. package/dist/wu-done-validation-3J5E36FE.js +0 -30
  111. package/dist/wu-duplicate-id-detector-5S7JHELK.js +0 -232
@@ -1,26 +0,0 @@
1
- import {
2
- getGitForCwd
3
- } from "./chunk-2UFQ3A3C.js";
4
- import {
5
- die
6
- } from "./chunk-RXRKBBSM.js";
7
-
8
- // ../core/dist/git-staged-validator.js
9
- function ensureStaged(paths) {
10
- const git = getGitForCwd();
11
- const raw = git.run("git diff --cached --name-only");
12
- const staged = raw ? raw.split(/\r?\n/).filter((s) => Boolean(s)) : [];
13
- const normalizedPaths = paths.filter((p) => typeof p === "string" && p.length > 0);
14
- const missing = normalizedPaths.filter((p) => {
15
- const pathToCheck = p.endsWith("/") ? p.slice(0, -1) : p;
16
- return !staged.some((name) => name === pathToCheck || name.startsWith(`${pathToCheck}/`));
17
- });
18
- if (missing.length) {
19
- die(`Stage updates for: ${missing.join(", ")}`);
20
- }
21
- return staged;
22
- }
23
-
24
- export {
25
- ensureStaged
26
- };
@@ -1,643 +0,0 @@
1
- import {
2
- ENV_VARS,
3
- GIT_COMMANDS,
4
- GIT_FLAGS,
5
- GIT_REFS
6
- } from "./chunk-DWMLTXKQ.js";
7
- import {
8
- ErrorCodes,
9
- createError
10
- } from "./chunk-RXRKBBSM.js";
11
-
12
- // ../core/dist/git-adapter.js
13
- import { simpleGit } from "simple-git";
14
- import { existsSync, rmSync } from "fs";
15
- function assertNonEmptyString(value, name) {
16
- if (typeof value !== "string") {
17
- throw new TypeError(`${name} must be a string, got ${typeof value}`);
18
- }
19
- if (value === "") {
20
- throw createError(ErrorCodes.INVALID_ARGUMENT, `${name} must be a non-empty string`);
21
- }
22
- }
23
- function assertOptionalString(value, name) {
24
- if (value !== void 0 && value !== null && typeof value !== "string") {
25
- throw new TypeError(`${name} must be a string, got ${typeof value}`);
26
- }
27
- }
28
- function assertStringOrArray(value, name) {
29
- if (typeof value === "string") {
30
- if (value === "") {
31
- throw createError(ErrorCodes.INVALID_ARGUMENT, `${name} must be a non-empty string or array`);
32
- }
33
- return;
34
- }
35
- if (Array.isArray(value)) {
36
- if (value.length === 0) {
37
- throw createError(ErrorCodes.INVALID_ARGUMENT, `${name} must be a non-empty string or array`);
38
- }
39
- return;
40
- }
41
- throw new TypeError(`${name} must be a string or array, got ${typeof value}`);
42
- }
43
- function assertArray(value, name) {
44
- if (!Array.isArray(value)) {
45
- throw new TypeError(`${name} must be an array, got ${typeof value}`);
46
- }
47
- }
48
- var GitAdapter = class {
49
- git;
50
- /**
51
- * Create a GitAdapter instance
52
- * @param {object} [options] - Configuration options
53
- * @param {object} [options.git] - simple-git instance (for testing)
54
- * @param {string} [options.baseDir] - Base directory for git operations
55
- */
56
- constructor(options = {}) {
57
- if (options.baseDir && process.env[ENV_VARS.DEBUG]) {
58
- console.log(`[git-adapter] DEBUG: GitAdapter constructor with baseDir=${options.baseDir}`);
59
- }
60
- this.git = options.git || simpleGit(options.baseDir);
61
- }
62
- /**
63
- * Get current branch name
64
- * @returns {Promise<string>} Current branch name
65
- * @example
66
- * await git.getCurrentBranch(); // "lane/operations/wu-1213"
67
- */
68
- async getCurrentBranch() {
69
- const result = await this.git.revparse([GIT_FLAGS.ABBREV_REF, "HEAD"]);
70
- return result.trim();
71
- }
72
- /**
73
- * Get git status (porcelain format string for compatibility)
74
- * @returns {Promise<string>} Status output in porcelain format
75
- * @example
76
- * await git.getStatus(); // " M file.txt\n?? untracked.txt"
77
- */
78
- async getStatus() {
79
- const result = await this.git.raw(["status", GIT_FLAGS.PORCELAIN]);
80
- return result.trim();
81
- }
82
- /**
83
- * Get unpushed commits (compared to upstream)
84
- * @returns {Promise<string>} Oneline log output for unpushed commits
85
- * @example
86
- * await git.getUnpushedCommits(); // "abc123 fix: ...\n"
87
- */
88
- async getUnpushedCommits() {
89
- const result = await this.git.raw([
90
- GIT_COMMANDS.LOG,
91
- GIT_REFS.UPSTREAM_RANGE,
92
- GIT_FLAGS.ONELINE
93
- ]);
94
- return result.trim();
95
- }
96
- /**
97
- * Check if a branch exists
98
- * @param {string} branch - Branch name
99
- * @returns {Promise<boolean>} True if branch exists
100
- * @throws {TypeError} If branch is not a string
101
- * @throws {Error} If branch is empty
102
- * @example
103
- * await git.branchExists('main'); // true
104
- * await git.branchExists('nonexistent'); // false
105
- */
106
- async branchExists(branch) {
107
- assertNonEmptyString(branch, "branch");
108
- try {
109
- await this.git.raw(["rev-parse", "--verify", branch]);
110
- return true;
111
- } catch {
112
- return false;
113
- }
114
- }
115
- /**
116
- * Check if a remote branch exists via git ls-remote --heads
117
- * @param {string} remote - Remote name (e.g., 'origin')
118
- * @param {string} branch - Branch name
119
- * @returns {Promise<boolean>} True if remote branch exists
120
- * @throws {TypeError} If remote or branch is not a string
121
- * @throws {Error} If remote or branch is empty
122
- * @example
123
- * await git.remoteBranchExists('origin', 'lane/operations/wu-123'); // true/false
124
- */
125
- async remoteBranchExists(remote, branch) {
126
- assertNonEmptyString(remote, "remote");
127
- assertNonEmptyString(branch, "branch");
128
- const result = await this.git.raw(["ls-remote", "--heads", remote, branch]);
129
- return result.trim().length > 0;
130
- }
131
- /**
132
- * Fetch from remote
133
- * @param {string} [remote] - Remote name (defaults to fetching all)
134
- * @param {string} [branch] - Branch name
135
- * @throws {TypeError} If remote or branch is not a string (when provided)
136
- * @example
137
- * await git.fetch('origin', 'main');
138
- * await git.fetch(); // Fetch all remotes
139
- */
140
- async fetch(remote, branch) {
141
- assertOptionalString(remote, "remote");
142
- assertOptionalString(branch, "branch");
143
- if (remote && branch) {
144
- await this.git.fetch(remote, branch);
145
- } else if (remote) {
146
- await this.git.fetch(remote);
147
- } else {
148
- await this.git.fetch();
149
- }
150
- }
151
- /**
152
- * Pull from remote branch
153
- * @param {string} remote - Remote name
154
- * @param {string} branch - Branch name
155
- * @throws {TypeError} If remote or branch is not a string
156
- * @example
157
- * await git.pull('origin', 'main');
158
- */
159
- async pull(remote, branch) {
160
- assertNonEmptyString(remote, "remote");
161
- assertNonEmptyString(branch, "branch");
162
- await this.git.pull(remote, branch);
163
- }
164
- /**
165
- * Get git config value
166
- * @param {string} key - Config key (e.g., 'user.email')
167
- * @returns {Promise<string>} Config value
168
- * @example
169
- * await git.getConfigValue('user.email'); // "user@example.com"
170
- */
171
- async getConfigValue(key) {
172
- const result = await this.git.raw(["config", key]);
173
- return result.trim();
174
- }
175
- /**
176
- * Check if working tree is clean (no uncommitted changes)
177
- * @returns {Promise<boolean>} True if clean
178
- * @example
179
- * await git.isClean(); // true or false
180
- */
181
- async isClean() {
182
- const status = await this.getStatus();
183
- return status === "";
184
- }
185
- /**
186
- * Add files to staging area
187
- * @param {string|string[]} files - Files to add
188
- * @throws {TypeError} If files is not a string or array
189
- * @throws {Error} If files is empty string or empty array
190
- * @example
191
- * await git.add('file.txt');
192
- * await git.add(['file1.txt', 'file2.txt']);
193
- * await git.add('.'); // Add all
194
- */
195
- async add(files) {
196
- assertStringOrArray(files, "files");
197
- await this.git.add(files);
198
- }
199
- /**
200
- * Add files to staging area including deletions
201
- *
202
- * WU-1813: Stages modifications, additions, AND deletions for specified files.
203
- * Unlike add(), this uses `git add -A` which properly handles tracked file deletions.
204
- *
205
- * When files array is empty, stages all changes in the working directory (git add -A .)
206
- * to catch UnsafeAny deletions that might not have been explicitly listed.
207
- *
208
- * @param {string[]} files - Files to add (empty array = add all)
209
- * @example
210
- * await git.addWithDeletions(['modified.txt', 'deleted.txt']);
211
- * await git.addWithDeletions([]); // Add all changes including deletions
212
- */
213
- async addWithDeletions(files) {
214
- if (files && files.length > 0) {
215
- await this.git.raw(["add", "-A", "--", ...files]);
216
- } else {
217
- await this.git.raw(["add", "-A", "."]);
218
- }
219
- }
220
- /**
221
- * Commit changes
222
- * @param {string} message - Commit message
223
- * @throws {TypeError} If message is not a string
224
- * @throws {Error} If message is empty
225
- * @example
226
- * await git.commit('feat: add new feature');
227
- */
228
- async commit(message) {
229
- assertNonEmptyString(message, "message");
230
- await this.git.commit(message);
231
- }
232
- /**
233
- * Push to remote
234
- * @param {string} [remote='origin'] - Remote name
235
- * @param {string} [branch] - Branch name (uses current branch if not specified)
236
- * @param {object} [options] - Push options
237
- * @param {boolean} [options.setUpstream] - Set upstream tracking (-u flag)
238
- * @throws {TypeError} If remote or branch is not a string (when provided)
239
- * @example
240
- * await git.push('origin', 'main');
241
- * await git.push('origin', 'feature', { setUpstream: true });
242
- */
243
- async push(remote = "origin", branch, options = {}) {
244
- assertOptionalString(remote, "remote");
245
- assertOptionalString(branch, "branch");
246
- const pushOptions = {};
247
- if (options.setUpstream) {
248
- pushOptions[GIT_FLAGS.UPSTREAM] = null;
249
- }
250
- await this.git.push(remote, branch, pushOptions);
251
- }
252
- /**
253
- * Push using refspec to push local ref to different remote ref
254
- *
255
- * WU-1435: Enables push-only pattern to keep local main pristine.
256
- * Pushes directly to origin/main without updating local main.
257
- *
258
- * @param {string} remote - Remote name (e.g., 'origin')
259
- * @param {string} localRef - Local ref to push (e.g., 'tmp/wu-claim/wu-123')
260
- * @param {string} remoteRef - Remote ref to update (e.g., 'main')
261
- * @example
262
- * await git.pushRefspec('origin', 'tmp/wu-claim/wu-123', 'main');
263
- * // Equivalent to: git push origin tmp/wu-claim/wu-123:main
264
- */
265
- async pushRefspec(remote, localRef, remoteRef) {
266
- const refspec = `${localRef}:${remoteRef}`;
267
- await this.git.push(remote, refspec);
268
- }
269
- /**
270
- * Create and checkout a new branch
271
- * @param {string} branch - Branch name
272
- * @param {string} [startPoint] - Starting commit (defaults to HEAD)
273
- * @throws {TypeError} If branch is not a string, or startPoint is not a string (when provided)
274
- * @throws {Error} If branch is empty
275
- * @example
276
- * await git.createBranch('feature/new-feature');
277
- * await git.createBranch('hotfix/bug', 'main');
278
- */
279
- async createBranch(branch, startPoint) {
280
- assertNonEmptyString(branch, "branch");
281
- assertOptionalString(startPoint, "startPoint");
282
- const args = [GIT_FLAGS.BRANCH, branch];
283
- if (startPoint) {
284
- args.push(startPoint);
285
- }
286
- await this.git.checkout(args);
287
- }
288
- /**
289
- * Checkout a branch
290
- * @param {string} branch - Branch name
291
- * @throws {TypeError} If branch is not a string
292
- * @throws {Error} If branch is empty
293
- * @example
294
- * await git.checkout('main');
295
- */
296
- async checkout(branch) {
297
- assertNonEmptyString(branch, "branch");
298
- await this.git.checkout(branch);
299
- }
300
- /**
301
- * Get commit hash
302
- * @param {string} [ref='HEAD'] - Git ref
303
- * @returns {Promise<string>} Commit hash
304
- * @example
305
- * await git.getCommitHash(); // "a1b2c3d..."
306
- * await git.getCommitHash('main'); // "e4f5g6h..."
307
- */
308
- async getCommitHash(ref = "HEAD") {
309
- const result = await this.git.revparse([ref]);
310
- return result.trim();
311
- }
312
- /**
313
- * Merge a branch
314
- *
315
- * WU-1749: Bug 1 fix - Return success status and handle false positive failures.
316
- * simple-git's merge() returns a MergeSummary that we now properly handle.
317
- *
318
- * @param {string} branch - Branch to merge
319
- * @param {object} [options] - Merge options
320
- * @param {boolean} [options.ffOnly] - Fast-forward only merge
321
- * @returns {Promise<{success: boolean}>} Merge result
322
- * @throws {TypeError} If branch is not a string
323
- * @throws {Error} If branch is empty
324
- * @example
325
- * await git.merge('feature-branch');
326
- * await git.merge('feature-branch', { ffOnly: true });
327
- */
328
- async merge(branch, options = {}) {
329
- assertNonEmptyString(branch, "branch");
330
- const args = [];
331
- if (options.ffOnly) {
332
- args.push(GIT_FLAGS.FF_ONLY);
333
- }
334
- args.push(branch);
335
- await this.git.merge(args);
336
- return { success: true };
337
- }
338
- /**
339
- * Get commit log
340
- *
341
- * WU-1749: Bug 4 fix - Add log() method for counting commits.
342
- * Used by wu-done-retry-helpers.ts to count previous completion attempts.
343
- *
344
- * @param {object} [options] - Log options
345
- * @param {number} [options.maxCount] - Maximum number of commits to return
346
- * @returns {Promise<{all: Array<{hash: string, message: string}>, total: number}>} Log result
347
- * @example
348
- * await git.log({ maxCount: 50 });
349
- */
350
- async log(options = {}) {
351
- return await this.git.log(options);
352
- }
353
- // New semantic methods for wu- scripts (WU-1213)
354
- /**
355
- * Find common ancestor (merge base) of two refs
356
- * @param {string} ref1 - First ref
357
- * @param {string} ref2 - Second ref
358
- * @returns {Promise<string>} Common ancestor commit hash
359
- * @throws {TypeError} If ref1 or ref2 is not a string
360
- * @example
361
- * await git.mergeBase('main', 'feature'); // "abc123def456"
362
- */
363
- async mergeBase(ref1, ref2) {
364
- assertNonEmptyString(ref1, "ref1");
365
- assertNonEmptyString(ref2, "ref2");
366
- const result = await this.git.raw(["merge-base", ref1, ref2]);
367
- return result.trim();
368
- }
369
- /**
370
- * Simulate merge and detect conflicts without touching working tree
371
- * @param {string} base - Base commit hash
372
- * @param {string} ref1 - First ref to merge
373
- * @param {string} ref2 - Second ref to merge
374
- * @returns {Promise<string>} Merge tree output (contains conflict markers if conflicts exist)
375
- * @example
376
- * await git.mergeTree('base123', 'main', 'feature');
377
- */
378
- async mergeTree(base, ref1, ref2) {
379
- const result = await this.git.raw(["merge-tree", base, ref1, ref2]);
380
- return result;
381
- }
382
- /**
383
- * List commits with various options
384
- * @param {string[]} args - Arguments to pass to git rev-list
385
- * @returns {Promise<string>} Rev-list output
386
- * @example
387
- * await git.revList(['--count', '--left-right', 'main...feature']); // "5\t0"
388
- */
389
- async revList(args) {
390
- const result = await this.git.raw(["rev-list", ...args]);
391
- return result.trim();
392
- }
393
- /**
394
- * Add a worktree with new branch
395
- * @param {string} path - Worktree path
396
- * @param {string} branch - Branch name
397
- * @param {string} [startPoint] - Starting commit (defaults to HEAD)
398
- * @throws {TypeError} If path or branch is not a string
399
- * @throws {Error} If path or branch is empty
400
- * @example
401
- * await git.worktreeAdd('worktrees/feature', 'feature-branch', 'main');
402
- */
403
- async worktreeAdd(path, branch, startPoint) {
404
- assertNonEmptyString(path, "path");
405
- assertNonEmptyString(branch, "branch");
406
- assertOptionalString(startPoint, "startPoint");
407
- const args = ["worktree", "add", path, GIT_FLAGS.BRANCH, branch];
408
- if (startPoint) {
409
- args.push(startPoint);
410
- }
411
- await this.git.raw(args);
412
- }
413
- /**
414
- * Remove a worktree
415
- *
416
- * WU-1476: Layer 1 defense - explicit directory cleanup after git worktree remove.
417
- * Git worktree remove can leave orphan directories when:
418
- * - The worktree was forcefully removed
419
- * - Git worktree metadata was corrupted
420
- * - Previous wu:done failed mid-workflow
421
- *
422
- * @param {string} worktreePath - Worktree path
423
- * @param {object} [options] - Remove options
424
- * @param {boolean} [options.force] - Force removal
425
- * @example
426
- * await git.worktreeRemove('worktrees/feature');
427
- * await git.worktreeRemove('worktrees/feature', { force: true });
428
- */
429
- async worktreeRemove(worktreePath, options = {}) {
430
- const args = ["worktree", "remove"];
431
- if (options.force) {
432
- args.push(GIT_FLAGS.FORCE);
433
- }
434
- args.push(worktreePath);
435
- try {
436
- await this.git.raw(args);
437
- } catch (err) {
438
- if (existsSync(worktreePath)) {
439
- rmSync(worktreePath, { recursive: true, force: true });
440
- }
441
- throw err;
442
- }
443
- if (existsSync(worktreePath)) {
444
- try {
445
- rmSync(worktreePath, { recursive: true, force: true });
446
- } catch (rmErr) {
447
- console.warn(`[git-adapter] worktreeRemove: git succeeded but directory cleanup failed for ${worktreePath}: ${rmErr instanceof Error ? rmErr.message : String(rmErr)}`);
448
- }
449
- }
450
- }
451
- /**
452
- * List all worktrees
453
- * @returns {Promise<string>} Worktree list in porcelain format
454
- * @example
455
- * await git.worktreeList();
456
- */
457
- async worktreeList() {
458
- const result = await this.git.raw(["worktree", "list", GIT_FLAGS.PORCELAIN]);
459
- return result;
460
- }
461
- /**
462
- * Delete a branch
463
- * @param {string} branch - Branch name
464
- * @param {object} [options] - Delete options
465
- * @param {boolean} [options.force] - Force delete (use -D instead of -d)
466
- * @throws {TypeError} If branch is not a string
467
- * @throws {Error} If branch is empty
468
- * @example
469
- * await git.deleteBranch('feature');
470
- * await git.deleteBranch('feature', { force: true });
471
- */
472
- async deleteBranch(branch, options = {}) {
473
- assertNonEmptyString(branch, "branch");
474
- const flag = options.force ? GIT_FLAGS.DELETE_FORCE : GIT_FLAGS.DELETE;
475
- await this.git.branch([flag, branch]);
476
- }
477
- /**
478
- * Create a branch WITHOUT switching to it (WU-1262)
479
- * Used for micro-worktree pattern where main checkout stays on main
480
- * @param {string} branch - Branch name to create
481
- * @param {string} [startPoint] - Starting commit (defaults to HEAD)
482
- * @example
483
- * await git.createBranchNoCheckout('tmp/wu-create/wu-123', 'main');
484
- */
485
- async createBranchNoCheckout(branch, startPoint) {
486
- const args = ["branch", branch];
487
- if (startPoint) {
488
- args.push(startPoint);
489
- }
490
- await this.git.raw(args);
491
- }
492
- /**
493
- * Add a worktree for an EXISTING branch (WU-1262)
494
- * Unlike worktreeAdd, this doesn't create a new branch
495
- * @param {string} path - Worktree path
496
- * @param {string} branch - Existing branch name
497
- * @example
498
- * await git.worktreeAddExisting('/tmp/wu-create-xyz', 'tmp/wu-create/wu-123');
499
- */
500
- async worktreeAddExisting(path, branch) {
501
- await this.git.raw(["worktree", "add", path, branch]);
502
- }
503
- /**
504
- * Rebase current branch onto target (WU-1262)
505
- * Used in micro-worktree to rebase temp branch when main moves
506
- * @param {string} onto - Target ref to rebase onto
507
- * @throws {TypeError} If onto is not a string
508
- * @throws {Error} If onto is empty
509
- * @example
510
- * await git.rebase('main');
511
- */
512
- async rebase(onto) {
513
- assertNonEmptyString(onto, "onto");
514
- const gitWithEditor = this.git.env({ ...process.env, GIT_EDITOR: "true" });
515
- await gitWithEditor.rebase([onto]);
516
- }
517
- /**
518
- * Reset HEAD to specified commit
519
- * @param {string} [ref] - Commit ref to reset to (defaults to HEAD)
520
- * @param {object} [options] - Reset options
521
- * @param {boolean} [options.hard] - Hard reset (--hard flag)
522
- * @example
523
- * await git.reset('abc123', { hard: true });
524
- */
525
- async reset(ref, options = {}) {
526
- const args = ["reset"];
527
- if (options.hard) {
528
- args.push(GIT_FLAGS.HARD);
529
- }
530
- if (ref) {
531
- args.push(ref);
532
- }
533
- await this.git.raw(args);
534
- }
535
- /**
536
- * Execute arbitrary git command via raw()
537
- * @param {string[]} args - Git command arguments
538
- * @returns {Promise<string>} Command output
539
- * @throws {TypeError} If args is not an array
540
- * @example
541
- * await git.raw(['status', '--porcelain']);
542
- */
543
- async raw(args) {
544
- assertArray(args, "args");
545
- const result = await this.git.raw(args);
546
- return result;
547
- }
548
- /**
549
- * WU-2208: List file/directory names at a given git ref and tree path.
550
- *
551
- * Uses `git ls-tree --name-only <ref> <path>/` to enumerate entries.
552
- * Returns an array of filenames (not full paths) within the directory.
553
- * Returns empty array if the path does not exist at the given ref.
554
- *
555
- * @param ref - Git ref (e.g., 'origin/main')
556
- * @param path - Directory path relative to repo root
557
- * @returns Array of filenames in the directory at the given ref
558
- */
559
- async listTreeAtRef(ref, path) {
560
- assertNonEmptyString(ref, "ref");
561
- assertNonEmptyString(path, "path");
562
- try {
563
- const dirPath = path.endsWith("/") ? path : `${path}/`;
564
- const result = await this.git.raw(["ls-tree", "--name-only", ref, dirPath]);
565
- if (!result || result.trim().length === 0) {
566
- return [];
567
- }
568
- return result.trim().split("\n").filter((line) => line.length > 0);
569
- } catch {
570
- return [];
571
- }
572
- }
573
- /**
574
- * WU-2208: Show a file's content at a given git ref.
575
- *
576
- * Uses `git show <ref>:<path>` to retrieve file content.
577
- * Returns empty string if the file does not exist at the given ref.
578
- *
579
- * @param ref - Git ref (e.g., 'origin/main')
580
- * @param path - File path relative to repo root
581
- * @returns File content as string, or empty string if not found
582
- */
583
- async showFileAtRef(ref, path) {
584
- assertNonEmptyString(ref, "ref");
585
- assertNonEmptyString(path, "path");
586
- try {
587
- const result = await this.git.raw(["show", `${ref}:${path}`]);
588
- return result ?? "";
589
- } catch {
590
- return "";
591
- }
592
- }
593
- // Deprecated methods (for backward compatibility during migration)
594
- /**
595
- * @deprecated Use async methods directly instead
596
- * Legacy method for backward compatibility
597
- * Execute a git command and return trimmed output
598
- * @param {string} cmd - Command to execute
599
- * @returns {string} Trimmed command output
600
- */
601
- run(cmd) {
602
- throw createError(ErrorCodes.DEPRECATED_API, `GitAdapter.run() is deprecated (WU-1213). Use async methods instead. Attempted to run: ${cmd}`);
603
- }
604
- /**
605
- * @deprecated Use worktreeAdd() instead
606
- */
607
- addWorktree(path, branch, startPoint) {
608
- return this.worktreeAdd(path, branch, startPoint);
609
- }
610
- /**
611
- * @deprecated Use worktreeRemove() instead
612
- */
613
- removeWorktree(path, options) {
614
- return this.worktreeRemove(path, options);
615
- }
616
- };
617
- function createGitForPath(baseDir) {
618
- return new GitAdapter({ baseDir });
619
- }
620
- function getGitForCwd() {
621
- const cwd = process.cwd();
622
- if (process.env[ENV_VARS.DEBUG]) {
623
- console.log(`[git-adapter] DEBUG: getGitForCwd() creating adapter with baseDir=${cwd}`);
624
- }
625
- return new GitAdapter({ baseDir: cwd });
626
- }
627
- var singletonWarned = false;
628
- var gitSingleton = new GitAdapter();
629
- var git = new Proxy(gitSingleton, {
630
- get(target, prop) {
631
- if (!singletonWarned) {
632
- console.warn("[DEPRECATED] git singleton captured cwd at import time. Use createGitForPath(path) or getGitForCwd() for explicit directory control.");
633
- singletonWarned = true;
634
- }
635
- const value = target[prop];
636
- return typeof value === "function" ? value.bind(target) : value;
637
- }
638
- });
639
-
640
- export {
641
- createGitForPath,
642
- getGitForCwd
643
- };
@@ -1,10 +0,0 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
- export {
9
- __require
10
- };
@@ -1,15 +0,0 @@
1
- import {
2
- LUMENFLOW_PATHS
3
- } from "./chunk-DWMLTXKQ.js";
4
-
5
- // ../memory/dist/paths.js
6
- var LUMENFLOW_MEMORY_PATHS = {
7
- BASE: LUMENFLOW_PATHS.BASE,
8
- STATE_DIR: LUMENFLOW_PATHS.STATE_DIR,
9
- MEMORY_DIR: LUMENFLOW_PATHS.MEMORY_DIR,
10
- SESSION_CURRENT: LUMENFLOW_PATHS.SESSION_CURRENT
11
- };
12
-
13
- export {
14
- LUMENFLOW_MEMORY_PATHS
15
- };