nightralph 0.0.37 → 0.0.40

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.
package/dist/meta.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "inputs": {
3
3
  "src/setup.ts": {
4
- "bytes": 4884,
4
+ "bytes": 5445,
5
5
  "imports": [
6
6
  {
7
7
  "path": "node:fs",
@@ -27,7 +27,7 @@
27
27
  "format": "esm"
28
28
  },
29
29
  "src/worktree.ts": {
30
- "bytes": 5108,
30
+ "bytes": 5906,
31
31
  "imports": [
32
32
  {
33
33
  "path": "node:child_process",
@@ -142,7 +142,7 @@
142
142
  "format": "esm"
143
143
  },
144
144
  "src/orchestrator.ts": {
145
- "bytes": 65558,
145
+ "bytes": 68690,
146
146
  "imports": [
147
147
  {
148
148
  "path": "node:child_process",
@@ -169,6 +169,11 @@
169
169
  "kind": "import-statement",
170
170
  "external": true
171
171
  },
172
+ {
173
+ "path": "node:util",
174
+ "kind": "import-statement",
175
+ "external": true
176
+ },
172
177
  {
173
178
  "path": "src/worktree.ts",
174
179
  "kind": "import-statement",
@@ -234,7 +239,7 @@
234
239
  "format": "esm"
235
240
  },
236
241
  "src/index.ts": {
237
- "bytes": 10105,
242
+ "bytes": 10174,
238
243
  "imports": [
239
244
  {
240
245
  "path": "node:fs",
@@ -305,7 +310,7 @@
305
310
  "imports": [],
306
311
  "exports": [],
307
312
  "inputs": {},
308
- "bytes": 175862
313
+ "bytes": 182428
309
314
  },
310
315
  "dist/index.js": {
311
316
  "imports": [
@@ -374,6 +379,11 @@
374
379
  "kind": "import-statement",
375
380
  "external": true
376
381
  },
382
+ {
383
+ "path": "node:util",
384
+ "kind": "import-statement",
385
+ "external": true
386
+ },
377
387
  {
378
388
  "path": "node:child_process",
379
389
  "kind": "import-statement",
@@ -462,16 +472,16 @@
462
472
  "entryPoint": "src/index.ts",
463
473
  "inputs": {
464
474
  "src/index.ts": {
465
- "bytesInOutput": 6800
475
+ "bytesInOutput": 6856
466
476
  },
467
477
  "src/setup.ts": {
468
- "bytesInOutput": 4265
478
+ "bytesInOutput": 4816
469
479
  },
470
480
  "src/orchestrator.ts": {
471
- "bytesInOutput": 45107
481
+ "bytesInOutput": 47579
472
482
  },
473
483
  "src/worktree.ts": {
474
- "bytesInOutput": 3788
484
+ "bytesInOutput": 4523
475
485
  },
476
486
  "src/progress.ts": {
477
487
  "bytesInOutput": 4419
@@ -483,13 +493,13 @@
483
493
  "bytesInOutput": 7931
484
494
  },
485
495
  "src/testcmd.ts": {
486
- "bytesInOutput": 1911
496
+ "bytesInOutput": 1914
487
497
  },
488
498
  "src/resolve.ts": {
489
499
  "bytesInOutput": 1937
490
500
  }
491
501
  },
492
- "bytes": 81599
502
+ "bytes": 85416
493
503
  }
494
504
  }
495
505
  }
@@ -1,6 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
- import { spawn } from "node:child_process";
3
+ import { spawn, execFile } from "node:child_process";
4
4
  import {
5
5
  createWriteStream,
6
6
  mkdirSync,
@@ -12,12 +12,15 @@ import {
12
12
  import { tmpdir } from "node:os";
13
13
  import { join, dirname, basename } from "node:path";
14
14
  import { createInterface } from "node:readline";
15
+ import { promisify } from "node:util";
16
+ const execFileAsync = promisify(execFile);
15
17
  import {
16
18
  getRepoRoot,
17
19
  getRepoName,
18
20
  getCurrentBranch,
19
21
  createWorktree,
20
22
  removeWorktree,
23
+ buildBranchName,
21
24
  hasNewCommits,
22
25
  isDirty,
23
26
  commitDirty
@@ -53,6 +56,48 @@ async function removeWorktreeQuietly(worktreePath, d) {
53
56
  }
54
57
  }
55
58
  __name(removeWorktreeQuietly, "removeWorktreeQuietly");
59
+ async function commitTicketFiles(repoRoot, tickets, d) {
60
+ const paths = tickets.map((t) => t.filepath);
61
+ if (paths.length === 0) return;
62
+ try {
63
+ await execFileAsync(
64
+ "git",
65
+ ["add", "--force", ...paths],
66
+ { cwd: repoRoot }
67
+ );
68
+ try {
69
+ await execFileAsync(
70
+ "git",
71
+ [
72
+ "diff",
73
+ "--cached",
74
+ "--quiet",
75
+ "--",
76
+ ...paths
77
+ ],
78
+ { cwd: repoRoot }
79
+ );
80
+ return;
81
+ } catch {
82
+ }
83
+ await execFileAsync(
84
+ "git",
85
+ [
86
+ "commit",
87
+ "-m",
88
+ "nightralph: update ticket checklists",
89
+ "--",
90
+ ...paths
91
+ ],
92
+ { cwd: repoRoot }
93
+ );
94
+ } catch (err) {
95
+ d.log(
96
+ " Failed to commit ticket updates: " + formatErrorMessage(err)
97
+ );
98
+ }
99
+ }
100
+ __name(commitTicketFiles, "commitTicketFiles");
56
101
  const TICKET_RE = /^(\d+)-(.+)\.md$/;
57
102
  function parseTicketFilename(filename) {
58
103
  const m = filename.match(TICKET_RE);
@@ -264,14 +309,18 @@ function renderPrompt(specBody, ticket, opts) {
264
309
  "You are an autonomous coding agent. Implement the ticket using /tdd.",
265
310
  "",
266
311
  "Follow these rules:",
267
- "- Read the files directly relevant to the ticket before writing code.",
312
+ "- Read the files directly relevant to the ticket before writing code. Also read any AGENTS.md in or above the directories you will touch, plus CONTEXT.md and the relevant docs/adr/ entries if they exist. If they do not exist, proceed silently.",
313
+ "- Work ONLY on this ticket. Do not fix unrelated problems you notice.",
268
314
  "- Do NOT research external APIs or services via web search. Use the spec and ticket body as your sole reference for API shapes.",
269
315
  "- Use /tdd for every checklist item. For each item, write a failing test at the seams named in the spec's Testing Decisions section, then write only enough code to make it pass, then refactor.",
270
- `- Run \`${opts.testCmd}\` before committing. Do not commit with failing tests. The orchestrator runs the same command after you exit and rejects the ticket if it fails.`,
316
+ `- While iterating, run only the tests relevant to what you changed. Run \`${opts.testCmd}\` in full once, as the final gate before your last commit. Do not commit with failing tests. The orchestrator runs the same command after you exit and rejects the ticket if it fails.`,
317
+ "- If the project has a lint script, run it and fix what it reports.",
318
+ "- INTEGRITY: never delete, skip, weaken, or write tautological tests to force a green result. Only report a checklist item done when its real tests genuinely pass. If an item cannot be completed honestly, leave it unchecked and say what blocked you.",
271
319
  "- Do NOT read or modify files outside your current directory (the worktree).",
272
320
  "- Do NOT run git push.",
273
- "- Commit your work when finished.",
321
+ "- Commit after each checklist item, and make sure everything is committed when finished.",
274
322
  "- After completing each checklist item in the ticket, print a line: [x] <item text> (matching the checklist text exactly).",
323
+ "- Before your final commit, record reusable learnings in the nearest AGENTS.md (in or above the directories you modified; prefer that over the repo root). Good additions: module conventions, gotchas, files that must change together, how to test that area, environment requirements. Do NOT add ticket-specific details or temporary debugging notes. Only write when you have knowledge that would help future work in that directory.",
275
324
  ""
276
325
  ].join("\n");
277
326
  }
@@ -292,8 +341,9 @@ function renderMergePrompt(specBody, ticket) {
292
341
  "",
293
342
  "Your task:",
294
343
  "1. Find and resolve all conflict markers (<<<<<<< / ======= / >>>>>>>).",
295
- "2. Make sure the code compiles and tests pass.",
296
- "3. Commit the resolved files.",
344
+ "2. When AGENTS.md or other docs conflict, keep both sides' additions rather than picking one.",
345
+ "3. Make sure the code compiles and tests pass.",
346
+ "4. Commit the resolved files.",
297
347
  "",
298
348
  "Do NOT re-implement the ticket from scratch.",
299
349
  "Do NOT read or modify files outside your current directory (the worktree).",
@@ -814,7 +864,11 @@ function dryRunIsolated(opts) {
814
864
  );
815
865
  for (const t of ready) {
816
866
  const num = String(t.num).padStart(2, "0");
817
- const branchName = `${opts.repoName}/${num}-${t.slug}`;
867
+ const branchName = buildBranchName(
868
+ opts.repoRoot,
869
+ opts.repoName,
870
+ t
871
+ );
818
872
  const worktreePath = `../${opts.repoName}.${num}-${t.slug}`;
819
873
  console.log(` worktree: ${worktreePath}`);
820
874
  console.log(` branch: ${branchName}`);
@@ -1476,6 +1530,13 @@ async function runWavesIsolated(opts) {
1476
1530
  });
1477
1531
  }
1478
1532
  if (successfulBranches.length > 0) {
1533
+ await commitTicketFiles(
1534
+ repoRoot,
1535
+ successfulBranches.map(
1536
+ (sb) => ticketsByNum.get(sb.ticketNum)
1537
+ ),
1538
+ d
1539
+ );
1479
1540
  const mergeResult = await mergeWave({
1480
1541
  repoRoot,
1481
1542
  baseBranch,