@growthagent/ci 0.8.0 → 0.10.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 +57 -38
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res, err) => function __init() {
|
|
4
|
+
if (err) throw err[0];
|
|
5
|
+
try {
|
|
6
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
|
+
} catch (e) {
|
|
8
|
+
throw err = [e], e;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// ../github/src/types.ts
|
|
13
|
+
var init_types = __esm({
|
|
14
|
+
"../github/src/types.ts"() {
|
|
15
|
+
"use strict";
|
|
16
|
+
}
|
|
17
|
+
});
|
|
2
18
|
|
|
3
19
|
// src/cli.ts
|
|
4
20
|
import { execFileSync, spawnSync as spawnSync2 } from "node:child_process";
|
|
5
|
-
import { cpSync, existsSync as existsSync3, mkdirSync, readFileSync
|
|
6
|
-
import
|
|
7
|
-
import { fileURLToPath
|
|
21
|
+
import { cpSync, existsSync as existsSync3, mkdirSync, readFileSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
22
|
+
import path6 from "node:path";
|
|
23
|
+
import { fileURLToPath } from "node:url";
|
|
24
|
+
|
|
25
|
+
// ../github/src/index.ts
|
|
26
|
+
init_types();
|
|
8
27
|
|
|
9
28
|
// ../github/src/app.ts
|
|
10
29
|
import { createSign } from "node:crypto";
|
|
@@ -33,6 +52,7 @@ var DEFAULT_LIMITS = {
|
|
|
33
52
|
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
34
53
|
|
|
35
54
|
// ../github/src/change-request.ts
|
|
55
|
+
init_types();
|
|
36
56
|
function parseChangeRequest(body) {
|
|
37
57
|
const match = body.match(/^---\n([\s\S]*?)\n---/);
|
|
38
58
|
if (!match) throw new Error("change request has no front matter");
|
|
@@ -45,6 +65,9 @@ function parseChangeRequest(body) {
|
|
|
45
65
|
return out;
|
|
46
66
|
}
|
|
47
67
|
|
|
68
|
+
// ../github/src/cleanup-request.ts
|
|
69
|
+
init_types();
|
|
70
|
+
|
|
48
71
|
// ../github/src/repos.ts
|
|
49
72
|
import { execFile } from "node:child_process";
|
|
50
73
|
import { mkdtempSync, existsSync, rmSync } from "node:fs";
|
|
@@ -53,30 +76,16 @@ import path3 from "node:path";
|
|
|
53
76
|
import { promisify } from "node:util";
|
|
54
77
|
var run = promisify(execFile);
|
|
55
78
|
|
|
56
|
-
// ../github/src/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
function read(name) {
|
|
62
|
-
for (const candidate of [
|
|
63
|
-
path4.join(HERE, "..", "..", "..", "action", name, "action.yml"),
|
|
64
|
-
path4.join(HERE, "..", "action", name, "action.yml")
|
|
65
|
-
]) {
|
|
66
|
-
try {
|
|
67
|
-
return readFileSync(candidate, "utf8");
|
|
68
|
-
} catch {
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
throw new Error(`could not find the ${name} action definition`);
|
|
72
|
-
}
|
|
73
|
-
var IMPLEMENT_ACTION = read("implement");
|
|
74
|
-
var APPLY_ACTION = read("apply");
|
|
79
|
+
// ../github/src/repair-request.ts
|
|
80
|
+
init_types();
|
|
81
|
+
|
|
82
|
+
// ../github/src/instrumentation-request.ts
|
|
83
|
+
init_types();
|
|
75
84
|
|
|
76
85
|
// src/lockfiles.ts
|
|
77
86
|
import { spawnSync } from "node:child_process";
|
|
78
87
|
import { existsSync as existsSync2, rmSync as rmSync2 } from "node:fs";
|
|
79
|
-
import
|
|
88
|
+
import path4 from "node:path";
|
|
80
89
|
var LOCKFILES = [
|
|
81
90
|
"pnpm-lock.yaml",
|
|
82
91
|
"package-lock.json",
|
|
@@ -89,12 +98,12 @@ function discardLockfileChanges(cwd = process.cwd()) {
|
|
|
89
98
|
const git = (args) => spawnSync("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
90
99
|
const touched = [];
|
|
91
100
|
for (const lockfile of LOCKFILES) {
|
|
92
|
-
if (!existsSync2(
|
|
101
|
+
if (!existsSync2(path4.join(cwd, lockfile))) continue;
|
|
93
102
|
const tracked = git(["ls-files", "--error-unmatch", "--", lockfile]).status === 0;
|
|
94
103
|
if (tracked) {
|
|
95
104
|
git(["restore", "--staged", "--worktree", "--", lockfile]);
|
|
96
105
|
} else {
|
|
97
|
-
rmSync2(
|
|
106
|
+
rmSync2(path4.join(cwd, lockfile), { force: true });
|
|
98
107
|
}
|
|
99
108
|
touched.push(lockfile);
|
|
100
109
|
}
|
|
@@ -340,11 +349,11 @@ function validatePatch(patch, limits = DEFAULT_PATCH_LIMITS) {
|
|
|
340
349
|
// src/provider-config.ts
|
|
341
350
|
import { mkdtempSync as mkdtempSync2, writeFileSync } from "node:fs";
|
|
342
351
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
343
|
-
import
|
|
352
|
+
import path5 from "node:path";
|
|
344
353
|
var RUN_TOKEN_ENV = "GX_RUN_TOKEN";
|
|
345
354
|
function writeGoogleProviderConfig(model) {
|
|
346
355
|
const gateway = (process.env.GX_GATEWAY_URL ?? "").replace(/\/$/, "");
|
|
347
|
-
const dir = mkdtempSync2(
|
|
356
|
+
const dir = mkdtempSync2(path5.join(tmpdir3(), "growth-agent-pi-"));
|
|
348
357
|
const config = {
|
|
349
358
|
providers: {
|
|
350
359
|
"growthagent-google": {
|
|
@@ -355,7 +364,7 @@ function writeGoogleProviderConfig(model) {
|
|
|
355
364
|
}
|
|
356
365
|
}
|
|
357
366
|
};
|
|
358
|
-
writeFileSync(
|
|
367
|
+
writeFileSync(path5.join(dir, "models.json"), JSON.stringify(config, null, 2));
|
|
359
368
|
return dir;
|
|
360
369
|
}
|
|
361
370
|
|
|
@@ -464,18 +473,27 @@ function buildPrompt(fields, briefing) {
|
|
|
464
473
|
}
|
|
465
474
|
|
|
466
475
|
// src/cli.ts
|
|
467
|
-
var
|
|
476
|
+
var HERE = path6.dirname(fileURLToPath(import.meta.url));
|
|
468
477
|
var PATCH_FILE = "growth-agent.patch";
|
|
469
478
|
function assetsDir() {
|
|
470
|
-
const packaged =
|
|
471
|
-
return existsSync3(packaged) ? packaged :
|
|
479
|
+
const packaged = path6.join(HERE, "assets", "skills");
|
|
480
|
+
return existsSync3(packaged) ? packaged : path6.join(HERE, "..", "assets", "skills");
|
|
472
481
|
}
|
|
473
482
|
function sh(cmd, args, opts = {}) {
|
|
474
|
-
|
|
483
|
+
return shRaw(cmd, args, opts).trim();
|
|
484
|
+
}
|
|
485
|
+
function shRaw(cmd, args, opts = {}) {
|
|
486
|
+
const r = spawnSync2(cmd, args, {
|
|
487
|
+
encoding: "utf8",
|
|
488
|
+
stdio: ["inherit", "pipe", "inherit"],
|
|
489
|
+
// A diff of a large change can exceed Node's 1MB default and be silently
|
|
490
|
+
// truncated, which produces the same corruption from a different cause.
|
|
491
|
+
maxBuffer: 64 * 1024 * 1024
|
|
492
|
+
});
|
|
475
493
|
if (r.status !== 0 && !opts.allowFail) {
|
|
476
494
|
throw new Error(`${cmd} ${args.join(" ")} exited ${r.status}`);
|
|
477
495
|
}
|
|
478
|
-
return
|
|
496
|
+
return r.stdout ?? "";
|
|
479
497
|
}
|
|
480
498
|
function required(name) {
|
|
481
499
|
const v = process.env[name];
|
|
@@ -485,7 +503,7 @@ function required(name) {
|
|
|
485
503
|
function readIssue() {
|
|
486
504
|
const eventPath = process.env.GITHUB_EVENT_PATH;
|
|
487
505
|
if (eventPath) {
|
|
488
|
-
const event = JSON.parse(
|
|
506
|
+
const event = JSON.parse(readFileSync(eventPath, "utf8"));
|
|
489
507
|
if (event.issue) {
|
|
490
508
|
return {
|
|
491
509
|
number: event.issue.number,
|
|
@@ -595,7 +613,7 @@ async function implement() {
|
|
|
595
613
|
console.log(
|
|
596
614
|
meta.kind === "instrumentation" ? `\u25B8 instrumentation request #${issue.number}` : `\u25B8 change request #${issue.number} \u2014 flag ${meta.flagKey} on ${meta.surface}`
|
|
597
615
|
);
|
|
598
|
-
const skillsDir =
|
|
616
|
+
const skillsDir = path6.resolve(process.cwd(), ".pi", "skills");
|
|
599
617
|
mkdirSync(skillsDir, { recursive: true });
|
|
600
618
|
cpSync(assetsDir(), skillsDir, { recursive: true });
|
|
601
619
|
const prompt = buildPrompt(meta, extractBriefing(issue.body));
|
|
@@ -647,12 +665,13 @@ async function implement() {
|
|
|
647
665
|
console.log(`\u25B8 discarded the model's ${discarded.join(", ")}; the trusted job derives it`);
|
|
648
666
|
}
|
|
649
667
|
sh("git", ["add", "-A"]);
|
|
650
|
-
const patch =
|
|
668
|
+
const patch = shRaw("git", ["diff", "--staged"]);
|
|
651
669
|
if (!patch.trim()) {
|
|
652
670
|
console.error("pi made no changes \u2014 nothing to open a PR for");
|
|
653
671
|
return 2;
|
|
654
672
|
}
|
|
655
|
-
writeFileSync2(PATCH_FILE, patch
|
|
673
|
+
writeFileSync2(PATCH_FILE, patch.endsWith("\n") ? patch : `${patch}
|
|
674
|
+
`, "utf8");
|
|
656
675
|
const verdict = validatePatch(patch);
|
|
657
676
|
if (!verdict.ok) {
|
|
658
677
|
console.error(`The produced patch was refused: ${verdict.reason}`);
|
|
@@ -697,7 +716,7 @@ function apply() {
|
|
|
697
716
|
console.error(`No ${PATCH_FILE} was produced by the implementer job.`);
|
|
698
717
|
return 1;
|
|
699
718
|
}
|
|
700
|
-
const patch =
|
|
719
|
+
const patch = readFileSync(PATCH_FILE, "utf8");
|
|
701
720
|
const verdict = validatePatch(patch);
|
|
702
721
|
if (!verdict.ok) {
|
|
703
722
|
console.error(`Refusing to apply the patch: ${verdict.reason}`);
|