automata-cli 0.10.0-develop.432 → 0.11.0-develop.440

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/index.js +147 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -331,13 +331,135 @@ var configCommand = new Command("config").description("Configure automata settin
331
331
  import { Command as Command2 } from "commander";
332
332
 
333
333
  // src/git/gitService.ts
334
- import { spawnSync as spawnSync2 } from "child_process";
334
+ import { spawnSync as spawnSync3 } from "child_process";
335
335
  import { existsSync } from "fs";
336
336
 
337
- // src/config/azdoService.ts
337
+ // src/remote/azdoPrerequisites.ts
338
338
  import { spawnSync } from "child_process";
339
+ var MIN_AZDO_VERSION = "0.20.0";
340
+ var AZDO_NO_UPDATE_CHECK = "--no-update-check";
341
+ function defaultRunner(args) {
342
+ const result = spawnSync("azdo", args, { encoding: "utf8" });
343
+ const code = result.error?.code;
344
+ return {
345
+ stdout: result.stdout ?? "",
346
+ stderr: result.stderr ?? "",
347
+ status: result.status ?? 1,
348
+ missing: code === "ENOENT"
349
+ };
350
+ }
351
+ function parseVersion(text) {
352
+ const match = /(\d{1,9})\.(\d{1,9})\.(\d{1,9})(?:-([0-9A-Za-z.-]{1,64}))?/.exec(text);
353
+ if (!match) return null;
354
+ return { parts: [Number(match[1]), Number(match[2]), Number(match[3])], prerelease: match[4] ?? null };
355
+ }
356
+ function compareVersions(a, b) {
357
+ for (let i = 0; i < 3; i++) {
358
+ if (a.parts[i] !== b.parts[i]) return a.parts[i] < b.parts[i] ? -1 : 1;
359
+ }
360
+ if (a.prerelease === b.prerelease) return 0;
361
+ if (a.prerelease === null) return 1;
362
+ if (b.prerelease === null) return -1;
363
+ return a.prerelease < b.prerelease ? -1 : 1;
364
+ }
365
+ function formatVersion(v) {
366
+ return v.parts.join(".") + (v.prerelease ? `-${v.prerelease}` : "");
367
+ }
368
+ function extractIdentity(stdout) {
369
+ try {
370
+ const parsed = JSON.parse(stdout);
371
+ const id = parsed.identity;
372
+ if (typeof id === "string" && id) return id;
373
+ if (id && typeof id === "object") {
374
+ const o = id;
375
+ for (const key of ["displayName", "uniqueName", "providerDisplayName", "id"]) {
376
+ if (typeof o[key] === "string" && o[key]) return o[key];
377
+ }
378
+ }
379
+ } catch {
380
+ }
381
+ return null;
382
+ }
383
+ function checkAzdoPrerequisites(run5 = defaultRunner) {
384
+ const v = run5(["--version", AZDO_NO_UPDATE_CHECK]);
385
+ if (v.missing) {
386
+ return { ok: false, reason: "missing", message: "`azdo` CLI is not installed or not on PATH." };
387
+ }
388
+ const version2 = v.status === 0 ? parseVersion(v.stdout) : null;
389
+ if (!version2) {
390
+ return { ok: false, reason: "missing", message: "Could not determine the `azdo` CLI version (`azdo --version`)." };
391
+ }
392
+ const min = parseVersion(MIN_AZDO_VERSION);
393
+ if (compareVersions(version2, min) < 0) {
394
+ return {
395
+ ok: false,
396
+ reason: "too-old",
397
+ message: `azdo-cli ${formatVersion(version2)} is too old; ${MIN_AZDO_VERSION} or newer is required.`
398
+ };
399
+ }
400
+ const auth = run5(["auth", "diagnose", "--json", AZDO_NO_UPDATE_CHECK]);
401
+ const identity = auth.status === 0 ? extractIdentity(auth.stdout) : null;
402
+ if (!identity) {
403
+ return {
404
+ ok: false,
405
+ reason: "unauthenticated",
406
+ message: "`azdo` is not authenticated. Run `azdo auth login` and check `azdo auth diagnose`."
407
+ };
408
+ }
409
+ return { ok: true, version: formatVersion(version2), identity };
410
+ }
411
+ var verified = null;
412
+ function assertAzdoReady(run5) {
413
+ if (verified?.ok) return;
414
+ const result = checkAzdoPrerequisites(run5);
415
+ if (!result.ok) throw new Error(result.message);
416
+ verified = result;
417
+ }
418
+
419
+ // src/remote/originUrl.ts
420
+ function strip(name) {
421
+ return decodeURIComponent(name).replace(/\.git$/, "");
422
+ }
423
+ function orNull(parse) {
424
+ try {
425
+ return parse();
426
+ } catch (error) {
427
+ if (error instanceof URIError) return null;
428
+ throw error;
429
+ }
430
+ }
431
+ function parseGitHub(url) {
432
+ const match = /^(?:https?:\/\/(?:[^@/]+@)?(?:www\.)?github\.com\/|(?:ssh:\/\/)?git@github\.com[:/])([^/]+)\/([^/]+?)(?:\.git)?\/?$/i.exec(
433
+ url
434
+ );
435
+ return match ? { kind: "github", owner: match[1], repo: match[2] } : null;
436
+ }
437
+ function parseAzdo(url) {
438
+ const dev = /^https?:\/\/(?:[^@/]+@)?dev\.azure\.com\/([^/]+)\/([^/]+)\/_git\/([^/?#]+)\/?$/.exec(url);
439
+ if (dev) {
440
+ return { kind: "azdo", organization: strip(dev[1]), project: strip(dev[2]), repo: strip(dev[3]) };
441
+ }
442
+ const vs = /^https?:\/\/(?:[^@/]+@)?([^./]+)\.visualstudio\.com\/(?:DefaultCollection\/)?([^/]+)\/_git\/([^/?#]+)\/?$/i.exec(
443
+ url
444
+ );
445
+ if (vs) {
446
+ return { kind: "azdo", organization: strip(vs[1]), project: strip(vs[2]), repo: strip(vs[3]) };
447
+ }
448
+ const ssh = /^(?:ssh:\/\/)?(?:[^@/]+@)?ssh\.dev\.azure\.com[:/]v3\/([^/]+)\/([^/]+)\/([^/?#]+?)\/?$/.exec(url);
449
+ if (ssh) {
450
+ return { kind: "azdo", organization: strip(ssh[1]), project: strip(ssh[2]), repo: strip(ssh[3]) };
451
+ }
452
+ return null;
453
+ }
454
+ function parseOrigin(rawUrl) {
455
+ const url = rawUrl.trim();
456
+ return orNull(() => parseAzdo(url) ?? parseGitHub(url));
457
+ }
458
+
459
+ // src/config/azdoService.ts
460
+ import { spawnSync as spawnSync2 } from "child_process";
339
461
  function run(cmd, args) {
340
- const result = spawnSync(cmd, args, { encoding: "utf8" });
462
+ const result = spawnSync2(cmd, args, { encoding: "utf8" });
341
463
  if (result.error) {
342
464
  const err = result.error;
343
465
  if (err.code === "ENOENT") {
@@ -364,7 +486,7 @@ function mapStatus(azdoStatus) {
364
486
  }
365
487
  }
366
488
  function getPrInfo() {
367
- const { stdout, stderr, status } = run("azdo", ["pr", "status", "--json"]);
489
+ const { stdout, stderr, status } = run("azdo", ["pr", "status", "--json", "--no-update-check"]);
368
490
  if (status !== 0) {
369
491
  throw new Error(stderr.trim() || "Failed to query Azure DevOps PR status. Is `azdo` installed and authenticated?");
370
492
  }
@@ -471,7 +593,7 @@ Set it explicitly with: automata config set git-trunk-branch <branch>`;
471
593
  // src/git/gitService.ts
472
594
  function run2(cmd, args) {
473
595
  const startedAt = Date.now();
474
- const result = spawnSync2(cmd, args, { encoding: "utf8" });
596
+ const result = spawnSync3(cmd, args, { encoding: "utf8" });
475
597
  const status = result.status ?? 1;
476
598
  recordCommand(cmd, args, startedAt, result.error ? -1 : status);
477
599
  return {
@@ -493,11 +615,15 @@ function parseOwnerRepo() {
493
615
  const { stdout, status } = run2("git", ["remote", "get-url", "origin"]);
494
616
  if (status !== 0) return null;
495
617
  const url = stdout.trim();
496
- const https = /github\.com\/([^/]+\/[^/]+?)(?:\.git)?$/.exec(url);
497
- if (https) return https[1];
498
- const ssh = /github\.com:([^/]+\/[^/]+?)(?:\.git)?$/.exec(url);
499
- if (ssh) return ssh[1];
500
- return null;
618
+ const origin = parseOrigin(url);
619
+ return origin?.kind === "github" ? `${origin.owner}/${origin.repo}` : null;
620
+ }
621
+ function assertAzdoRemote() {
622
+ const { stdout, status } = run2("git", ["remote", "get-url", "origin"]);
623
+ if (status === 0 && parseOrigin(stdout)?.kind === "github") {
624
+ throw new Error("remoteType is `azdo` but `origin` is a GitHub URL. Fix `remoteType` in .automata/config.json.");
625
+ }
626
+ assertAzdoReady();
501
627
  }
502
628
  function extractLastMarkdownUrl(markdown) {
503
629
  const matches = [...markdown.matchAll(/\]\((https?:\/\/[^)]+)\)/g)];
@@ -923,6 +1049,7 @@ async function getPrInfoGh(branch) {
923
1049
  async function getPrInfo2(branch) {
924
1050
  const config = readConfig();
925
1051
  if (selectBackend(config) === "azdo") {
1052
+ assertAzdoRemote();
926
1053
  return getPrInfo();
927
1054
  }
928
1055
  return getPrInfoGh(branch);
@@ -1838,11 +1965,11 @@ import { createInterface as createInterface2 } from "readline";
1838
1965
  import { Command as Command3 } from "commander";
1839
1966
 
1840
1967
  // src/config/githubService.ts
1841
- import { spawnSync as spawnSync3 } from "child_process";
1968
+ import { spawnSync as spawnSync4 } from "child_process";
1842
1969
  var GITHUB_ISSUE_COMMENT_URL_RE = /github\.com\/([^/]+\/[^/]+)\/issues\/\d+#issuecomment-(\d+)/;
1843
1970
  function run3(cmd, args) {
1844
1971
  const startedAt = Date.now();
1845
- const result = spawnSync3(cmd, args, { encoding: "utf8" });
1972
+ const result = spawnSync4(cmd, args, { encoding: "utf8" });
1846
1973
  recordCommand(cmd, args, startedAt, result.error ? -1 : result.status ?? 1);
1847
1974
  if (result.error) {
1848
1975
  const err = result.error;
@@ -1997,10 +2124,10 @@ function addCopilotReviewer(prNumber) {
1997
2124
  }
1998
2125
 
1999
2126
  // src/github/ghWorkService.ts
2000
- import { spawnSync as spawnSync4 } from "child_process";
2127
+ import { spawnSync as spawnSync5 } from "child_process";
2001
2128
  function run4(cmd, args) {
2002
2129
  const startedAt = Date.now();
2003
- const result = spawnSync4(cmd, args, { encoding: "utf8" });
2130
+ const result = spawnSync5(cmd, args, { encoding: "utf8" });
2004
2131
  recordCommand(cmd, args, startedAt, result.error ? -1 : result.status ?? 1);
2005
2132
  if (result.error) {
2006
2133
  const err = result.error;
@@ -2448,7 +2575,7 @@ function parseCreatedPrUrl(stdout, head) {
2448
2575
  }
2449
2576
 
2450
2577
  // src/claude/claudeService.ts
2451
- import { spawn, spawnSync as spawnSync5 } from "child_process";
2578
+ import { spawn, spawnSync as spawnSync6 } from "child_process";
2452
2579
  import { createInterface } from "readline";
2453
2580
 
2454
2581
  // src/cli/spawnUtils.ts
@@ -2633,7 +2760,7 @@ function invokeClaudeCode(prompt, options = {}) {
2633
2760
  function invokeClaudeCodeSync(prompt, yolo, model, effort) {
2634
2761
  const claudeBin = resolveCommand("claude");
2635
2762
  const args = buildClaudeArgs(prompt, { yolo, model, effort, verbose: false });
2636
- const result = spawnSync5(claudeBin, args, { encoding: "utf8", stdio: "inherit" });
2763
+ const result = spawnSync6(claudeBin, args, { encoding: "utf8", stdio: "inherit" });
2637
2764
  handleSpawnError(result.error, "claude");
2638
2765
  handleExitCode(result.status, "Claude Code");
2639
2766
  }
@@ -2739,7 +2866,7 @@ function summarizeTool(name, input) {
2739
2866
  }
2740
2867
 
2741
2868
  // src/codex/codexService.ts
2742
- import { spawn as spawn2, spawnSync as spawnSync6 } from "child_process";
2869
+ import { spawn as spawn2, spawnSync as spawnSync7 } from "child_process";
2743
2870
  function toTomlBasicString(value) {
2744
2871
  return JSON.stringify(value);
2745
2872
  }
@@ -2760,7 +2887,7 @@ function invokeCodexCode(prompt, options = {}) {
2760
2887
  function invokeCodexCodeSync(prompt, yolo, model, effort) {
2761
2888
  const codexBin = resolveCommand("codex");
2762
2889
  const args = buildCodexArgs(prompt, { yolo, model, effort });
2763
- const result = spawnSync6(codexBin, args, { encoding: "utf8", stdio: "inherit" });
2890
+ const result = spawnSync7(codexBin, args, { encoding: "utf8", stdio: "inherit" });
2764
2891
  handleSpawnError(result.error, "codex");
2765
2892
  handleExitCode(result.status, "Codex");
2766
2893
  }
@@ -5414,11 +5541,11 @@ function readWorkRecords(options = {}) {
5414
5541
  }
5415
5542
 
5416
5543
  // src/git/repoStatus.ts
5417
- import { spawnSync as spawnSync7 } from "child_process";
5544
+ import { spawnSync as spawnSync8 } from "child_process";
5418
5545
  var GIT_BIN = resolveCommand("git");
5419
5546
  function git(args) {
5420
5547
  const startedAt = Date.now();
5421
- const result = spawnSync7(GIT_BIN, args, { encoding: "utf8" });
5548
+ const result = spawnSync8(GIT_BIN, args, { encoding: "utf8" });
5422
5549
  const status = result.status ?? 1;
5423
5550
  recordCommand(GIT_BIN, args, startedAt, result.error ? -1 : status);
5424
5551
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "automata-cli",
3
- "version": "0.10.0-develop.432",
3
+ "version": "0.11.0-develop.440",
4
4
  "description": "Automata CLI tool",
5
5
  "type": "module",
6
6
  "engines": {