@growthagent/ci 0.5.0 → 0.7.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.
Files changed (2) hide show
  1. package/dist/cli.js +52 -20
  2. 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 existsSync2, mkdirSync, readFileSync, writeFileSync as writeFileSync2 } from "node:fs";
6
- import path5 from "node:path";
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 path4 from "node:path";
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(path4.join(tmpdir3(), "growth-agent-pi-"));
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(path4.join(dir, "models.json"), JSON.stringify(config, null, 2));
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 = path5.dirname(fileURLToPath(import.meta.url));
447
+ var HERE = path6.dirname(fileURLToPath(import.meta.url));
420
448
  var PATCH_FILE = "growth-agent.patch";
421
449
  function assetsDir() {
422
- const packaged = path5.join(HERE, "assets", "skills");
423
- return existsSync2(packaged) ? packaged : path5.join(HERE, "..", "assets", "skills");
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 = spawnSync(cmd, args, { encoding: "utf8", stdio: ["inherit", "pipe", "inherit"] });
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 = path5.resolve(process.cwd(), ".pi", "skills");
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 = spawnSync(
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 (!existsSync2(m.lockfile)) continue;
654
+ if (!existsSync3(m.lockfile)) continue;
623
655
  console.log(`\u25B8 regenerating ${m.lockfile} from the manifest`);
624
- const result = spawnSync(m.bin, m.args, { stdio: ["ignore", "inherit", "inherit"] });
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 (!existsSync2(PATCH_FILE)) {
676
+ if (!existsSync3(PATCH_FILE)) {
645
677
  console.error(`No ${PATCH_FILE} was produced by the implementer job.`);
646
678
  return 1;
647
679
  }
@@ -674,7 +706,7 @@ function apply() {
674
706
  Implements #${issue.number}.
675
707
 
676
708
  Flag: ${meta.flagKey}`]);
677
- sh("git", ["push", "-u", "origin", branch]);
709
+ sh("git", ["push", "--force", "-u", "origin", branch]);
678
710
  const stat2 = sh("git", ["diff", "--stat", "HEAD~1", "HEAD"]);
679
711
  const prBody = meta.kind === "instrumentation" ? [
680
712
  `Implements #${issue.number}.`,
@@ -705,18 +737,18 @@ Flag: ${meta.flagKey}`]);
705
737
  "",
706
738
  `Primary metric: \`${meta.primaryMetric}\`.`
707
739
  ].join("\n");
740
+ const prTitle = title.startsWith("[growth]") ? title : `[growth] ${title}`;
708
741
  const prUrl = sh("gh", [
709
742
  "pr",
710
743
  "create",
711
744
  "--title",
712
- `[growth] ${title}`,
745
+ prTitle,
713
746
  "--body",
714
747
  prBody,
715
748
  "--head",
716
- branch,
717
- "--label",
718
- "growth-agent"
749
+ branch
719
750
  ]);
751
+ sh("gh", ["pr", "edit", branch, "--add-label", "growth-agent"], { allowFail: true });
720
752
  console.log(`\u25B8 opened ${prUrl}`);
721
753
  return 0;
722
754
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growthagent/ci",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {