@mifune/agro 0.13.0 → 0.15.0-minimal.1

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/agro.js +59 -46
  2. package/package.json +1 -1
package/dist/agro.js CHANGED
@@ -1479,11 +1479,6 @@ fi
1479
1479
  # shellcheck source=paths.sh
1480
1480
  . "$PATHS_SH"
1481
1481
 
1482
- MIGRATOR="$SCRIPT_DIR/migrate-harness-yaml.sh"
1483
- if [ -f "$REPO_DIR/harness.yaml" ] && [ -f "$MIGRATOR" ]; then
1484
- sh "$MIGRATOR" "$REPO_DIR" >&2 || true
1485
- fi
1486
-
1487
1482
  ENV_FILE="$REPO_DIR/.env"
1488
1483
  [ -f "$ENV_FILE" ] || ENV_FILE="$REPO_DIR/.devcontainer/.env"
1489
1484
 
@@ -2221,6 +2216,18 @@ function resolveExecutionTarget(opts) {
2221
2216
  return new DockerComposeExecutionTarget(opts);
2222
2217
  }
2223
2218
 
2219
+ // src/lib/version.ts
2220
+ var AGRO_VERSION = true ? "0.15.0-minimal.1" : "0.0.0-dev";
2221
+ var OFFICIAL_IMAGE = "ghcr.io/mifunedev/agro";
2222
+ var RELEASE_VERSION = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[a-z][a-z0-9]*\.[0-9]+)?$/;
2223
+ function parseReleaseVersion(value) {
2224
+ const bare = value.startsWith("v") ? value.slice(1) : value;
2225
+ return RELEASE_VERSION.test(bare) ? bare : void 0;
2226
+ }
2227
+ function officialImageRef(version) {
2228
+ return `${OFFICIAL_IMAGE}:${RELEASE_VERSION.test(version) ? version : "latest"}`;
2229
+ }
2230
+
2224
2231
  // src/lib/config-render.ts
2225
2232
  var RETIRED_KEYS = [
2226
2233
  "WORKTREES_DIR",
@@ -2242,6 +2249,12 @@ var RETIRED_KEYS = [
2242
2249
  "LANGFUSE_BASE_URL",
2243
2250
  "LANGFUSE_PRIVACY_PRESET"
2244
2251
  ];
2252
+ function runsPrebuiltImage(config) {
2253
+ return config.image?.mode === "image";
2254
+ }
2255
+ function sandboxImageRef(config) {
2256
+ return config.image?.ref ?? (runsPrebuiltImage(config) ? officialImageRef(AGRO_VERSION) : void 0);
2257
+ }
2245
2258
  function renderComposeVars(config) {
2246
2259
  const out = [];
2247
2260
  const put = (key, value) => {
@@ -2257,7 +2270,7 @@ function renderComposeVars(config) {
2257
2270
  put("DOCKER_SOCKET", config.access?.dockerSocket);
2258
2271
  put("SANDBOX_SSH", config.access?.ssh);
2259
2272
  put("SANDBOX_SSH_PORT", config.access?.sshPort);
2260
- put("AGRO_SANDBOX_IMAGE", config.image?.ref);
2273
+ put("AGRO_SANDBOX_IMAGE", sandboxImageRef(config));
2261
2274
  put("AGRO_PULL_POLICY", config.image?.pullPolicy);
2262
2275
  for (const { key, value } of out) {
2263
2276
  if (isSecretKey(key)) {
@@ -2318,7 +2331,6 @@ function sandboxRoot(opts) {
2318
2331
  return root;
2319
2332
  }
2320
2333
  var DEFAULT_CONTAINER_NAME = DEFAULT_SANDBOX_NAME;
2321
- var DEFAULT_SANDBOX_IMAGE = "ghcr.io/mifunedev/agro:latest";
2322
2334
  function configuredField(root, path4) {
2323
2335
  const file = agroConfigPath(root);
2324
2336
  if (!existsSync10(file)) return void 0;
@@ -2363,7 +2375,7 @@ async function runSandbox(opts, io) {
2363
2375
  const root = resolveProjectRoot(opts.cwd);
2364
2376
  const useImage = opts.image === true || opts.imageRef !== void 0;
2365
2377
  const useNoBuild = useImage || opts.noBuild === true;
2366
- const imageRef = useImage ? opts.imageRef ?? configuredImage(root) ?? DEFAULT_SANDBOX_IMAGE : void 0;
2378
+ const imageRef = useImage ? opts.imageRef ?? configuredImage(root) ?? officialImageRef(AGRO_VERSION) : void 0;
2367
2379
  const env = imageRef === void 0 ? void 0 : { ...process.env, ...agroEnvPair("SANDBOX_IMAGE", imageRef) };
2368
2380
  if (opts.printArgv === true) {
2369
2381
  const script = requireLifecycleScript(root, "docker-compose.sh");
@@ -3933,9 +3945,6 @@ async function runSandboxInstall(opts, io) {
3933
3945
  if (opts.imageRef !== void 0) {
3934
3946
  config.image = { ...config.image, ref: opts.imageRef, mode: "image" };
3935
3947
  }
3936
- if (configCheckout(config) !== void 0 && config.image?.mode === "image" && nonEmpty(config.image?.ref) === void 0) {
3937
- config.image = { ...config.image, ref: DEFAULT_SANDBOX_IMAGE };
3938
- }
3939
3948
  const useNoBuild = opts.noBuild === true || !(configCheckout(config) !== void 0 && config.image?.mode === "build");
3940
3949
  const sandboxOpts = {
3941
3950
  bin: opts.bin,
@@ -4422,19 +4431,6 @@ async function runHarnessStatus(name, opts, io) {
4422
4431
  function hermesTargetRoot(target) {
4423
4432
  return target.kind === "docker-compose" ? "/home/sandbox/harness" : target.workspace.targetRoot;
4424
4433
  }
4425
- async function reconcileHermes(target, io, bin, user, root = hermesTargetRoot(target)) {
4426
- const result = await target.exec({
4427
- argv: remoteControlDirScript(root, "scripts/link-providers.sh", ["--init", "--hermes-only"]),
4428
- env: agroEnvPair("PROJECT_ROOT", root),
4429
- ...user ? { user } : {},
4430
- stdio: "inherit"
4431
- });
4432
- if (result.exitCode !== 0) {
4433
- io.stderr(`${bin} harness: Hermes integration failed (exit ${result.exitCode}); no installation success reported.
4434
- `);
4435
- }
4436
- return result.exitCode;
4437
- }
4438
4434
  function unreachableReason(status) {
4439
4435
  return runtimeIsAbsent(status) ? "No container runtime is on PATH." : `The sandbox is not running (${status}).`;
4440
4436
  }
@@ -4517,7 +4513,7 @@ async function installOnHost(entry, opts, io, run, status) {
4517
4513
  });
4518
4514
  if (linked.exitCode !== 0) {
4519
4515
  io.stderr(
4520
- `${bin} harness: could not link provider skills in ${root} (exit ${linked.exitCode}); nothing was installed.
4516
+ `${bin} harness: could not link provider hooks in ${root} (exit ${linked.exitCode}); nothing was installed.
4521
4517
  Run: bash ${root}/.agro/scripts/link-providers.sh --init
4522
4518
  `
4523
4519
  );
@@ -4528,10 +4524,6 @@ Run: bash ${root}/.agro/scripts/link-providers.sh --init
4528
4524
  ...agroEnvPair("PROJECT_ROOT", root),
4529
4525
  HERMES_HOME: `${root}/.hermes`
4530
4526
  } : void 0;
4531
- if (hermes) {
4532
- const code = await reconcileHermes(target, io, bin, void 0, root);
4533
- if (code !== 0) return code;
4534
- }
4535
4527
  if (await probeInstalled(target, entry, prefix, void 0, installEnv) === true) {
4536
4528
  io.stdout(`${entry.id}: already installed (${entry.binary})
4537
4529
  `);
@@ -4562,8 +4554,6 @@ Run: bash ${root}/.agro/scripts/link-providers.sh --init
4562
4554
  `);
4563
4555
  return 1;
4564
4556
  }
4565
- const code = await reconcileHermes(target, io, bin, void 0, root);
4566
- if (code !== 0) return code;
4567
4557
  }
4568
4558
  const receipt = {
4569
4559
  prefix,
@@ -4717,10 +4707,6 @@ async function runHarnessInstall(name, opts, io) {
4717
4707
  ...agroEnvPair("PROJECT_ROOT", hermesTargetRoot(target)),
4718
4708
  HERMES_HOME: `${hermesTargetRoot(target)}/.hermes`
4719
4709
  } : void 0;
4720
- if (hermes) {
4721
- const code = await reconcileHermes(target, io, opts.bin, "sandbox");
4722
- if (code !== 0) return code;
4723
- }
4724
4710
  const already = await probeInstalled(target, entry, SANDBOX_HARNESS_PREFIX, "sandbox", installEnv);
4725
4711
  if (already === true) {
4726
4712
  io.stdout(`${entry.id}: already installed (${entry.binary})
@@ -4750,8 +4736,6 @@ async function runHarnessInstall(name, opts, io) {
4750
4736
  `);
4751
4737
  return 1;
4752
4738
  }
4753
- const code = await reconcileHermes(target, io, opts.bin, "sandbox");
4754
- if (code !== 0) return code;
4755
4739
  }
4756
4740
  io.stdout(`${entry.id}: installed \u2014 see ${sourceDocsUrl(entry.docsPath)} for authentication
4757
4741
  `);
@@ -5678,7 +5662,6 @@ function fetchRemoteSource(opts) {
5678
5662
  }
5679
5663
 
5680
5664
  // src/cli.ts
5681
- var VERSION = true ? "0.13.0" : "0.0.0-dev";
5682
5665
  var DEFAULT_SOURCE_CONTROL_DIR = resolve11(
5683
5666
  dirname10(fileURLToPath(import.meta.url)),
5684
5667
  "../.."
@@ -5706,7 +5689,7 @@ function integrationLines() {
5706
5689
  }
5707
5690
  function printAgroHelp(product = AGRO_PRODUCT) {
5708
5691
  const { bin, title } = product;
5709
- process.stdout.write(`${bin} \u2014 ${title} (v${VERSION})
5692
+ process.stdout.write(`${bin} \u2014 ${title} (v${AGRO_VERSION})
5710
5693
 
5711
5694
  Usage:
5712
5695
  ${bin} sandbox <args...> Create and list sandboxes (install|list)
@@ -5871,7 +5854,8 @@ function printSandboxHelp(bin = AGRO_PRODUCT.bin) {
5871
5854
  Usage:
5872
5855
  ${bin} sandbox install <runtime> [--name <name>] [--checkout <dir>]
5873
5856
  [--home-mount <dir>] [--yes]
5874
- [--image[=<ref>]] [--no-build] [--print-argv]
5857
+ [--version <X.Y.Z> | --image[=<ref>]]
5858
+ [--no-build] [--print-argv]
5875
5859
  ${bin} sandbox list [--json]
5876
5860
 
5877
5861
  \`install\` writes a sandbox entry under \${${stateNames(bin).envPrefix}HOME:-~/${stateNames(bin).userStateDir}}/sandboxes/<name>/,
@@ -5898,9 +5882,15 @@ Flags:
5898
5882
  Docker-managed volume. Relative paths resolve against the
5899
5883
  working directory. The directory is created when absent
5900
5884
  --yes Non-interactive: keep every default and ask nothing
5901
- --image[=<ref>] Run the prebuilt image instead of building (implies
5902
- --no-build). Ref resolves last-wins: --image=<ref> >
5903
- ${stateNames(bin).configFile} image.ref > ${DEFAULT_SANDBOX_IMAGE}.
5885
+ --version <X.Y.Z>
5886
+ Run the official release image ghcr.io/mifunedev/agro:<X.Y.Z>
5887
+ (implies --image). A leading v and a -<channel>.<n>
5888
+ pre-release suffix are accepted
5889
+ --image Run the prebuilt image instead of building (implies
5890
+ --no-build). The ref resolves first-match: --version or
5891
+ --image=<ref> > ${stateNames(bin).envPrefix}SANDBOX_IMAGE >
5892
+ ${stateNames(bin).configFile} image.ref > ${officialImageRef(AGRO_VERSION)}
5893
+ --image=<ref> Run a custom image (implies --image); conflicts with --version
5904
5894
  --no-build Suppress the local build and reuse an existing image
5905
5895
  --print-argv Print the docker compose argv that would run, then exit
5906
5896
  without writing an entry
@@ -6376,6 +6366,7 @@ function parseSandboxArgs(rest, bin = AGRO_PRODUCT.bin) {
6376
6366
  if (isHelpFlag(tail[0])) return { ok: true, args: { ...args, help: true } };
6377
6367
  const positionals = [];
6378
6368
  const checkoutSpellings = /* @__PURE__ */ new Set();
6369
+ let version;
6379
6370
  for (let i = 0; i < tail.length; i++) {
6380
6371
  const token = tail[i];
6381
6372
  const valueFlag = SANDBOX_VALUE_FLAGS[token];
@@ -6402,6 +6393,18 @@ function parseSandboxArgs(rest, bin = AGRO_PRODUCT.bin) {
6402
6393
  }
6403
6394
  args.image = true;
6404
6395
  args.imageRef = ref;
6396
+ } else if (token === "--version" || token.startsWith("--version=")) {
6397
+ const value = token === "--version" ? tail[++i] : token.slice("--version=".length);
6398
+ if (value === void 0 || value === "") {
6399
+ return { ok: false, error: `${bin} sandbox ${head}: --version requires a value` };
6400
+ }
6401
+ version = parseReleaseVersion(value);
6402
+ if (version === void 0) {
6403
+ return {
6404
+ ok: false,
6405
+ error: `${bin} sandbox ${head}: --version "${value}" is not a release version \u2014 expected X.Y.Z`
6406
+ };
6407
+ }
6405
6408
  } else if (token === "--json") {
6406
6409
  args.json = true;
6407
6410
  } else if (token.startsWith("-")) {
@@ -6416,6 +6419,16 @@ function parseSandboxArgs(rest, bin = AGRO_PRODUCT.bin) {
6416
6419
  error: `${bin} sandbox ${head}: --checkout conflicts with --repo \u2014 pass exactly one, and prefer --checkout`
6417
6420
  };
6418
6421
  }
6422
+ if (version !== void 0) {
6423
+ if (args.imageRef !== void 0) {
6424
+ return {
6425
+ ok: false,
6426
+ error: `${bin} sandbox ${head}: --version conflicts with --image=<ref> \u2014 pass --version for an official release or --image=<ref> for a custom image`
6427
+ };
6428
+ }
6429
+ args.image = true;
6430
+ args.imageRef = officialImageRef(version);
6431
+ }
6419
6432
  if (head === "list") {
6420
6433
  if (positionals.length > 0) {
6421
6434
  return { ok: false, error: `${bin} sandbox list: unexpected argument "${positionals[0]}"` };
@@ -6687,7 +6700,7 @@ async function runWithRemoteSource(hooks, fn) {
6687
6700
  const checkoutDir = mkdtemp();
6688
6701
  try {
6689
6702
  fetch2({ destDir: checkoutDir, repoUrl: hooks.repoUrl, ref: hooks.ref });
6690
- out(`fetched payload v${readPayloadVersion(checkoutDir)} (installed CLI v${VERSION})
6703
+ out(`fetched payload v${readPayloadVersion(checkoutDir)} (installed CLI v${AGRO_VERSION})
6691
6704
  `);
6692
6705
  return await fn(checkoutDir);
6693
6706
  } finally {
@@ -6703,7 +6716,7 @@ async function main(argv) {
6703
6716
  return 0;
6704
6717
  }
6705
6718
  if (isVersionFlag(first)) {
6706
- process.stdout.write(`${VERSION}
6719
+ process.stdout.write(`${AGRO_VERSION}
6707
6720
  `);
6708
6721
  return 0;
6709
6722
  }
@@ -6809,7 +6822,7 @@ async function main(argv) {
6809
6822
  };
6810
6823
  return await runSelfUpgrade(
6811
6824
  { dryRun: parsed.args.dryRun, argv1: process.argv[1] },
6812
- defaultDeps(VERSION),
6825
+ defaultDeps(AGRO_VERSION),
6813
6826
  io
6814
6827
  );
6815
6828
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mifune/agro",
3
- "version": "0.13.0",
3
+ "version": "0.15.0-minimal.1",
4
4
  "description": "AGRO CLI — create and manage sandboxes for coding agents.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/mifunedev/agro#readme",