@growthagent/ci 0.6.0 → 0.8.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 +37 -59
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  // src/cli.ts
4
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
- import { fileURLToPath } from "node:url";
5
+ import { cpSync, existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
6
+ import path7 from "node:path";
7
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
8
8
 
9
9
  // ../github/src/app.ts
10
10
  import { createSign } from "node:crypto";
@@ -53,10 +53,30 @@ import path3 from "node:path";
53
53
  import { promisify } from "node:util";
54
54
  var run = promisify(execFile);
55
55
 
56
+ // ../github/src/actions.ts
57
+ import { readFileSync } from "node:fs";
58
+ import path4 from "node:path";
59
+ import { fileURLToPath } from "node:url";
60
+ var HERE = path4.dirname(fileURLToPath(import.meta.url));
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");
75
+
56
76
  // src/lockfiles.ts
57
77
  import { spawnSync } from "node:child_process";
58
78
  import { existsSync as existsSync2, rmSync as rmSync2 } from "node:fs";
59
- import path4 from "node:path";
79
+ import path5 from "node:path";
60
80
  var LOCKFILES = [
61
81
  "pnpm-lock.yaml",
62
82
  "package-lock.json",
@@ -69,12 +89,12 @@ function discardLockfileChanges(cwd = process.cwd()) {
69
89
  const git = (args) => spawnSync("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
70
90
  const touched = [];
71
91
  for (const lockfile of LOCKFILES) {
72
- if (!existsSync2(path4.join(cwd, lockfile))) continue;
92
+ if (!existsSync2(path5.join(cwd, lockfile))) continue;
73
93
  const tracked = git(["ls-files", "--error-unmatch", "--", lockfile]).status === 0;
74
94
  if (tracked) {
75
95
  git(["restore", "--staged", "--worktree", "--", lockfile]);
76
96
  } else {
77
- rmSync2(path4.join(cwd, lockfile), { force: true });
97
+ rmSync2(path5.join(cwd, lockfile), { force: true });
78
98
  }
79
99
  touched.push(lockfile);
80
100
  }
@@ -320,11 +340,11 @@ function validatePatch(patch, limits = DEFAULT_PATCH_LIMITS) {
320
340
  // src/provider-config.ts
321
341
  import { mkdtempSync as mkdtempSync2, writeFileSync } from "node:fs";
322
342
  import { tmpdir as tmpdir3 } from "node:os";
323
- import path5 from "node:path";
343
+ import path6 from "node:path";
324
344
  var RUN_TOKEN_ENV = "GX_RUN_TOKEN";
325
345
  function writeGoogleProviderConfig(model) {
326
346
  const gateway = (process.env.GX_GATEWAY_URL ?? "").replace(/\/$/, "");
327
- const dir = mkdtempSync2(path5.join(tmpdir3(), "growth-agent-pi-"));
347
+ const dir = mkdtempSync2(path6.join(tmpdir3(), "growth-agent-pi-"));
328
348
  const config = {
329
349
  providers: {
330
350
  "growthagent-google": {
@@ -335,7 +355,7 @@ function writeGoogleProviderConfig(model) {
335
355
  }
336
356
  }
337
357
  };
338
- writeFileSync(path5.join(dir, "models.json"), JSON.stringify(config, null, 2));
358
+ writeFileSync(path6.join(dir, "models.json"), JSON.stringify(config, null, 2));
339
359
  return dir;
340
360
  }
341
361
 
@@ -444,11 +464,11 @@ function buildPrompt(fields, briefing) {
444
464
  }
445
465
 
446
466
  // src/cli.ts
447
- var HERE = path6.dirname(fileURLToPath(import.meta.url));
467
+ var HERE2 = path7.dirname(fileURLToPath2(import.meta.url));
448
468
  var PATCH_FILE = "growth-agent.patch";
449
469
  function assetsDir() {
450
- const packaged = path6.join(HERE, "assets", "skills");
451
- return existsSync3(packaged) ? packaged : path6.join(HERE, "..", "assets", "skills");
470
+ const packaged = path7.join(HERE2, "assets", "skills");
471
+ return existsSync3(packaged) ? packaged : path7.join(HERE2, "..", "assets", "skills");
452
472
  }
453
473
  function sh(cmd, args, opts = {}) {
454
474
  const r = spawnSync2(cmd, args, { encoding: "utf8", stdio: ["inherit", "pipe", "inherit"] });
@@ -465,7 +485,7 @@ function required(name) {
465
485
  function readIssue() {
466
486
  const eventPath = process.env.GITHUB_EVENT_PATH;
467
487
  if (eventPath) {
468
- const event = JSON.parse(readFileSync(eventPath, "utf8"));
488
+ const event = JSON.parse(readFileSync2(eventPath, "utf8"));
469
489
  if (event.issue) {
470
490
  return {
471
491
  number: event.issue.number,
@@ -575,7 +595,7 @@ async function implement() {
575
595
  console.log(
576
596
  meta.kind === "instrumentation" ? `\u25B8 instrumentation request #${issue.number}` : `\u25B8 change request #${issue.number} \u2014 flag ${meta.flagKey} on ${meta.surface}`
577
597
  );
578
- const skillsDir = path6.resolve(process.cwd(), ".pi", "skills");
598
+ const skillsDir = path7.resolve(process.cwd(), ".pi", "skills");
579
599
  mkdirSync(skillsDir, { recursive: true });
580
600
  cpSync(assetsDir(), skillsDir, { recursive: true });
581
601
  const prompt = buildPrompt(meta, extractBriefing(issue.body));
@@ -677,7 +697,7 @@ function apply() {
677
697
  console.error(`No ${PATCH_FILE} was produced by the implementer job.`);
678
698
  return 1;
679
699
  }
680
- const patch = readFileSync(PATCH_FILE, "utf8");
700
+ const patch = readFileSync2(PATCH_FILE, "utf8");
681
701
  const verdict = validatePatch(patch);
682
702
  if (!verdict.ok) {
683
703
  console.error(`Refusing to apply the patch: ${verdict.reason}`);
@@ -706,50 +726,8 @@ function apply() {
706
726
  Implements #${issue.number}.
707
727
 
708
728
  Flag: ${meta.flagKey}`]);
709
- sh("git", ["push", "-u", "origin", branch]);
710
- const stat2 = sh("git", ["diff", "--stat", "HEAD~1", "HEAD"]);
711
- const prBody = meta.kind === "instrumentation" ? [
712
- `Implements #${issue.number}.`,
713
- "",
714
- "This adds measurement only. No behaviour changes, no features \u2014 a user",
715
- "should not be able to tell it shipped.",
716
- "",
717
- "### Changed files",
718
- "",
719
- stat2,
720
- "",
721
- "Once this is merged and deployed, connect the analytics project in Growth",
722
- "Agent so it can read what these events record."
723
- ].join("\n") : [
724
- `Implements #${issue.number}.`,
725
- "",
726
- `Both branches are behind \`${meta.flagKey}\`, which is at **0%**. Merging this does not`,
727
- "expose anyone to the variant \u2014 the flag is ramped only after a deployment succeeds and",
728
- "exposure events are confirmed arriving in production.",
729
- "",
730
- "### Changed files",
731
- "",
732
- stat2,
733
- "",
734
- "### How to check both branches locally",
735
- "",
736
- `Override the flag \`${meta.flagKey}\` in your local analytics client and reload \`${meta.surface}\`.`,
737
- "",
738
- `Primary metric: \`${meta.primaryMetric}\`.`
739
- ].join("\n");
740
- const prUrl = sh("gh", [
741
- "pr",
742
- "create",
743
- "--title",
744
- `[growth] ${title}`,
745
- "--body",
746
- prBody,
747
- "--head",
748
- branch,
749
- "--label",
750
- "growth-agent"
751
- ]);
752
- console.log(`\u25B8 opened ${prUrl}`);
729
+ sh("git", ["push", "--force", "-u", "origin", branch]);
730
+ console.log(`\u25B8 pushed ${branch} \u2014 Growth Agent opens the pull request`);
753
731
  return 0;
754
732
  }
755
733
  async function main() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growthagent/ci",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {