@growthagent/ci 0.5.0 → 0.6.0
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/cli.js +47 -15
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { execFileSync, spawnSync } from "node:child_process";
|
|
5
|
-
import { cpSync, existsSync as
|
|
6
|
-
import
|
|
4
|
+
import { execFileSync, spawnSync as spawnSync2 } from "node:child_process";
|
|
5
|
+
import { cpSync, existsSync as existsSync3, mkdirSync, readFileSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
6
|
+
import path6 from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
|
|
9
9
|
// ../github/src/app.ts
|
|
@@ -53,6 +53,34 @@ import path3 from "node:path";
|
|
|
53
53
|
import { promisify } from "node:util";
|
|
54
54
|
var run = promisify(execFile);
|
|
55
55
|
|
|
56
|
+
// src/lockfiles.ts
|
|
57
|
+
import { spawnSync } from "node:child_process";
|
|
58
|
+
import { existsSync as existsSync2, rmSync as rmSync2 } from "node:fs";
|
|
59
|
+
import path4 from "node:path";
|
|
60
|
+
var LOCKFILES = [
|
|
61
|
+
"pnpm-lock.yaml",
|
|
62
|
+
"package-lock.json",
|
|
63
|
+
"yarn.lock",
|
|
64
|
+
"bun.lockb",
|
|
65
|
+
"bun.lock",
|
|
66
|
+
"npm-shrinkwrap.json"
|
|
67
|
+
];
|
|
68
|
+
function discardLockfileChanges(cwd = process.cwd()) {
|
|
69
|
+
const git = (args) => spawnSync("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
70
|
+
const touched = [];
|
|
71
|
+
for (const lockfile of LOCKFILES) {
|
|
72
|
+
if (!existsSync2(path4.join(cwd, lockfile))) continue;
|
|
73
|
+
const tracked = git(["ls-files", "--error-unmatch", "--", lockfile]).status === 0;
|
|
74
|
+
if (tracked) {
|
|
75
|
+
git(["restore", "--staged", "--worktree", "--", lockfile]);
|
|
76
|
+
} else {
|
|
77
|
+
rmSync2(path4.join(cwd, lockfile), { force: true });
|
|
78
|
+
}
|
|
79
|
+
touched.push(lockfile);
|
|
80
|
+
}
|
|
81
|
+
return touched;
|
|
82
|
+
}
|
|
83
|
+
|
|
56
84
|
// src/patch.ts
|
|
57
85
|
var MAX_CAPTURED_LINES = 400;
|
|
58
86
|
var ALLOWED_DEPENDENCIES = ["posthog-js", "posthog-node"];
|
|
@@ -292,11 +320,11 @@ function validatePatch(patch, limits = DEFAULT_PATCH_LIMITS) {
|
|
|
292
320
|
// src/provider-config.ts
|
|
293
321
|
import { mkdtempSync as mkdtempSync2, writeFileSync } from "node:fs";
|
|
294
322
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
295
|
-
import
|
|
323
|
+
import path5 from "node:path";
|
|
296
324
|
var RUN_TOKEN_ENV = "GX_RUN_TOKEN";
|
|
297
325
|
function writeGoogleProviderConfig(model) {
|
|
298
326
|
const gateway = (process.env.GX_GATEWAY_URL ?? "").replace(/\/$/, "");
|
|
299
|
-
const dir = mkdtempSync2(
|
|
327
|
+
const dir = mkdtempSync2(path5.join(tmpdir3(), "growth-agent-pi-"));
|
|
300
328
|
const config = {
|
|
301
329
|
providers: {
|
|
302
330
|
"growthagent-google": {
|
|
@@ -307,7 +335,7 @@ function writeGoogleProviderConfig(model) {
|
|
|
307
335
|
}
|
|
308
336
|
}
|
|
309
337
|
};
|
|
310
|
-
writeFileSync(
|
|
338
|
+
writeFileSync(path5.join(dir, "models.json"), JSON.stringify(config, null, 2));
|
|
311
339
|
return dir;
|
|
312
340
|
}
|
|
313
341
|
|
|
@@ -416,14 +444,14 @@ function buildPrompt(fields, briefing) {
|
|
|
416
444
|
}
|
|
417
445
|
|
|
418
446
|
// src/cli.ts
|
|
419
|
-
var HERE =
|
|
447
|
+
var HERE = path6.dirname(fileURLToPath(import.meta.url));
|
|
420
448
|
var PATCH_FILE = "growth-agent.patch";
|
|
421
449
|
function assetsDir() {
|
|
422
|
-
const packaged =
|
|
423
|
-
return
|
|
450
|
+
const packaged = path6.join(HERE, "assets", "skills");
|
|
451
|
+
return existsSync3(packaged) ? packaged : path6.join(HERE, "..", "assets", "skills");
|
|
424
452
|
}
|
|
425
453
|
function sh(cmd, args, opts = {}) {
|
|
426
|
-
const r =
|
|
454
|
+
const r = spawnSync2(cmd, args, { encoding: "utf8", stdio: ["inherit", "pipe", "inherit"] });
|
|
427
455
|
if (r.status !== 0 && !opts.allowFail) {
|
|
428
456
|
throw new Error(`${cmd} ${args.join(" ")} exited ${r.status}`);
|
|
429
457
|
}
|
|
@@ -547,7 +575,7 @@ async function implement() {
|
|
|
547
575
|
console.log(
|
|
548
576
|
meta.kind === "instrumentation" ? `\u25B8 instrumentation request #${issue.number}` : `\u25B8 change request #${issue.number} \u2014 flag ${meta.flagKey} on ${meta.surface}`
|
|
549
577
|
);
|
|
550
|
-
const skillsDir =
|
|
578
|
+
const skillsDir = path6.resolve(process.cwd(), ".pi", "skills");
|
|
551
579
|
mkdirSync(skillsDir, { recursive: true });
|
|
552
580
|
cpSync(assetsDir(), skillsDir, { recursive: true });
|
|
553
581
|
const prompt = buildPrompt(meta, extractBriefing(issue.body));
|
|
@@ -563,7 +591,7 @@ async function implement() {
|
|
|
563
591
|
console.log(`\u25B8 running pi (${piProvider}/${model})`);
|
|
564
592
|
let piStatus;
|
|
565
593
|
try {
|
|
566
|
-
const pi =
|
|
594
|
+
const pi = spawnSync2(
|
|
567
595
|
"pi",
|
|
568
596
|
["-p", prompt, "--provider", piProvider, "--model", model, "--thinking", "high"],
|
|
569
597
|
{
|
|
@@ -594,6 +622,10 @@ async function implement() {
|
|
|
594
622
|
const piTracked = sh("git", ["ls-files", "--", ".pi"], { allowFail: true });
|
|
595
623
|
if (piTracked) sh("git", ["checkout", "--", ".pi"], { allowFail: true });
|
|
596
624
|
sh("git", ["clean", "-fdq", ".pi"], { allowFail: true });
|
|
625
|
+
const discarded = discardLockfileChanges();
|
|
626
|
+
if (discarded.length) {
|
|
627
|
+
console.log(`\u25B8 discarded the model's ${discarded.join(", ")}; the trusted job derives it`);
|
|
628
|
+
}
|
|
597
629
|
sh("git", ["add", "-A"]);
|
|
598
630
|
const patch = sh("git", ["diff", "--staged"]);
|
|
599
631
|
if (!patch.trim()) {
|
|
@@ -619,9 +651,9 @@ function regenerateLockfile() {
|
|
|
619
651
|
{ lockfile: "yarn.lock", bin: "yarn", args: ["install", "--mode=update-lockfile"] }
|
|
620
652
|
];
|
|
621
653
|
for (const m of managers) {
|
|
622
|
-
if (!
|
|
654
|
+
if (!existsSync3(m.lockfile)) continue;
|
|
623
655
|
console.log(`\u25B8 regenerating ${m.lockfile} from the manifest`);
|
|
624
|
-
const result =
|
|
656
|
+
const result = spawnSync2(m.bin, m.args, { stdio: ["ignore", "inherit", "inherit"] });
|
|
625
657
|
if (result.status !== 0) {
|
|
626
658
|
console.error(
|
|
627
659
|
`Could not regenerate ${m.lockfile} (${m.bin} exited ${result.status}). The dependency change is in package.json but the lockfile is stale \u2014 run the install locally on this branch before merging.`
|
|
@@ -641,7 +673,7 @@ function apply() {
|
|
|
641
673
|
const meta = validatedMeta(issue);
|
|
642
674
|
const title = safeTitle(issue);
|
|
643
675
|
const branch = branchFor(issue, meta.slug);
|
|
644
|
-
if (!
|
|
676
|
+
if (!existsSync3(PATCH_FILE)) {
|
|
645
677
|
console.error(`No ${PATCH_FILE} was produced by the implementer job.`);
|
|
646
678
|
return 1;
|
|
647
679
|
}
|