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 +78 -6
- package/dist/index.js.map +3 -3
- package/dist/meta.json +16 -6
- package/dist/orchestrator.js +62 -6
- package/dist/orchestrator.js.map +2 -2
- package/dist/setup.js +16 -0
- package/dist/setup.js.map +2 -2
- package/dist/src/orchestrator.d.ts.map +1 -1
- package/dist/src/setup.d.ts.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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.
|
|
1337
|
-
"3.
|
|
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,
|