nightralph 0.0.37 → 0.0.38

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/index.js CHANGED
@@ -61,6 +61,17 @@ function writeManagedSection(filePath, content) {
61
61
  }
62
62
  }
63
63
  __name(writeManagedSection, "writeManagedSection");
64
+ function ensureGitAttribute(filePath, line) {
65
+ if (!existsSync(filePath)) {
66
+ writeFileSync(filePath, line + "\n");
67
+ return;
68
+ }
69
+ const existing = readFileSync(filePath, "utf8");
70
+ if (existing.split("\n").includes(line)) return;
71
+ const sep = existing.endsWith("\n") ? "" : "\n";
72
+ writeFileSync(filePath, existing + sep + line + "\n");
73
+ }
74
+ __name(ensureGitAttribute, "ensureGitAttribute");
64
75
  function checkGhAuth() {
65
76
  try {
66
77
  execSync("gh auth status", { stdio: "ignore" });
@@ -171,6 +182,11 @@ function setup(opts) {
171
182
  const agentsPath = join(projectDir, "AGENTS.md");
172
183
  writeManagedSection(agentsPath, managedContent);
173
184
  console.log("\n AGENTS.md (updated)");
185
+ ensureGitAttribute(
186
+ join(projectDir, ".gitattributes"),
187
+ "AGENTS.md merge=union"
188
+ );
189
+ console.log(" .gitattributes (AGENTS.md merge=union)");
174
190
  console.log(
175
191
  `
176
192
  Source: ${upstream.repo} @ ${upstream.commit}`
@@ -179,7 +195,7 @@ Source: ${upstream.repo} @ ${upstream.commit}`
179
195
  __name(setup, "setup");
180
196
 
181
197
  // src/orchestrator.ts
182
- import { spawn as spawn2 } from "node:child_process";
198
+ import { spawn as spawn2, execFile as execFile4 } from "node:child_process";
183
199
  import {
184
200
  createWriteStream,
185
201
  mkdirSync as mkdirSync2,
@@ -191,6 +207,7 @@ import {
191
207
  import { tmpdir } from "node:os";
192
208
  import { join as join4, dirname, basename as basename2 } from "node:path";
193
209
  import { createInterface } from "node:readline";
210
+ import { promisify as promisify4 } from "node:util";
194
211
 
195
212
  // src/worktree.ts
196
213
  import { execFile, execFileSync } from "node:child_process";
@@ -1080,6 +1097,7 @@ function runTestCmd(opts) {
1080
1097
  __name(runTestCmd, "runTestCmd");
1081
1098
 
1082
1099
  // src/orchestrator.ts
1100
+ var execFileAsync4 = promisify4(execFile4);
1083
1101
  function formatErrorMessage(error) {
1084
1102
  return error instanceof Error ? error.message : String(error);
1085
1103
  }
@@ -1094,6 +1112,48 @@ async function removeWorktreeQuietly(worktreePath, d) {
1094
1112
  }
1095
1113
  }
1096
1114
  __name(removeWorktreeQuietly, "removeWorktreeQuietly");
1115
+ async function commitTicketFiles(repoRoot, tickets, d) {
1116
+ const paths = tickets.map((t) => t.filepath);
1117
+ if (paths.length === 0) return;
1118
+ try {
1119
+ await execFileAsync4(
1120
+ "git",
1121
+ ["add", "--force", ...paths],
1122
+ { cwd: repoRoot }
1123
+ );
1124
+ try {
1125
+ await execFileAsync4(
1126
+ "git",
1127
+ [
1128
+ "diff",
1129
+ "--cached",
1130
+ "--quiet",
1131
+ "--",
1132
+ ...paths
1133
+ ],
1134
+ { cwd: repoRoot }
1135
+ );
1136
+ return;
1137
+ } catch {
1138
+ }
1139
+ await execFileAsync4(
1140
+ "git",
1141
+ [
1142
+ "commit",
1143
+ "-m",
1144
+ "nightralph: update ticket checklists",
1145
+ "--",
1146
+ ...paths
1147
+ ],
1148
+ { cwd: repoRoot }
1149
+ );
1150
+ } catch (err) {
1151
+ d.log(
1152
+ " Failed to commit ticket updates: " + formatErrorMessage(err)
1153
+ );
1154
+ }
1155
+ }
1156
+ __name(commitTicketFiles, "commitTicketFiles");
1097
1157
  var TICKET_RE = /^(\d+)-(.+)\.md$/;
1098
1158
  function parseTicketFilename(filename) {
1099
1159
  const m = filename.match(TICKET_RE);
@@ -1305,14 +1365,18 @@ function renderPrompt(specBody, ticket, opts) {
1305
1365
  "You are an autonomous coding agent. Implement the ticket using /tdd.",
1306
1366
  "",
1307
1367
  "Follow these rules:",
1308
- "- Read the files directly relevant to the ticket before writing code.",
1368
+ "- 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.",
1369
+ "- Work ONLY on this ticket. Do not fix unrelated problems you notice.",
1309
1370
  "- Do NOT research external APIs or services via web search. Use the spec and ticket body as your sole reference for API shapes.",
1310
1371
  "- 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.",
1311
- `- 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.`,
1372
+ `- 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.`,
1373
+ "- If the project has a lint script, run it and fix what it reports.",
1374
+ "- 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.",
1312
1375
  "- Do NOT read or modify files outside your current directory (the worktree).",
1313
1376
  "- Do NOT run git push.",
1314
- "- Commit your work when finished.",
1377
+ "- Commit after each checklist item, and make sure everything is committed when finished.",
1315
1378
  "- After completing each checklist item in the ticket, print a line: [x] <item text> (matching the checklist text exactly).",
1379
+ "- 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.",
1316
1380
  ""
1317
1381
  ].join("\n");
1318
1382
  }
@@ -1333,8 +1397,9 @@ function renderMergePrompt(specBody, ticket) {
1333
1397
  "",
1334
1398
  "Your task:",
1335
1399
  "1. Find and resolve all conflict markers (<<<<<<< / ======= / >>>>>>>).",
1336
- "2. Make sure the code compiles and tests pass.",
1337
- "3. Commit the resolved files.",
1400
+ "2. When AGENTS.md or other docs conflict, keep both sides' additions rather than picking one.",
1401
+ "3. Make sure the code compiles and tests pass.",
1402
+ "4. Commit the resolved files.",
1338
1403
  "",
1339
1404
  "Do NOT re-implement the ticket from scratch.",
1340
1405
  "Do NOT read or modify files outside your current directory (the worktree).",
@@ -2517,6 +2582,13 @@ async function runWavesIsolated(opts) {
2517
2582
  });
2518
2583
  }
2519
2584
  if (successfulBranches.length > 0) {
2585
+ await commitTicketFiles(
2586
+ repoRoot,
2587
+ successfulBranches.map(
2588
+ (sb) => ticketsByNum.get(sb.ticketNum)
2589
+ ),
2590
+ d
2591
+ );
2520
2592
  const mergeResult = await mergeWave({
2521
2593
  repoRoot,
2522
2594
  baseBranch,