@xera-ai/cli 0.9.0 → 0.9.2

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 +78 -12
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -266,6 +266,7 @@ var TEMPLATE_DIR = TEMPLATE_ROOT;
266
266
 
267
267
  // src/commands/init.ts
268
268
  var require2 = createRequire(import.meta.url);
269
+ var CLI_VERSION = require2("../package.json").version;
269
270
  function cancel2() {
270
271
  p.cancel("Aborted.");
271
272
  process.exit(0);
@@ -282,6 +283,18 @@ async function prompt(flag, defaultValue, ask) {
282
283
  }
283
284
  async function initCommand(opts) {
284
285
  const cwd = process.cwd();
286
+ if (!process.stdin.isTTY && !opts.yes) {
287
+ console.error(pc2.red(`
288
+ error: stdin is not a TTY \u2014 interactive prompts cannot run.
289
+ `));
290
+ console.error(` Pass ${pc2.cyan("-y / --yes")} and use flags to run non-interactively:
291
+ `);
292
+ console.error(` xera init -y --shape web --pk MYPROJ --ju https://myco.atlassian.net
293
+ `);
294
+ console.error(` Run ${pc2.cyan("xera init --help")} to see all available flags.
295
+ `);
296
+ process.exit(1);
297
+ }
285
298
  p.intro(pc2.cyan("xera \u2014 project setup"));
286
299
  const shape = await prompt(opts.shape, opts.yes ? "web" : undefined, () => p.select({
287
300
  message: "What kind of testing does this project do?",
@@ -402,7 +415,7 @@ async function initCommand(opts) {
402
415
  const skillsDir = join3(skillsSrc, "..");
403
416
  for (const target of [".claude/skills", ".claude/commands"]) {
404
417
  copyDir(skillsDir, join3(cwd, target));
405
- for (const name of ["package.json", "version.json"]) {
418
+ for (const name of ["package.json", "version.json", "CHANGELOG.md"]) {
406
419
  const f = join3(cwd, target, name);
407
420
  if (existsSync3(f))
408
421
  unlinkSync(f);
@@ -433,12 +446,12 @@ async function initCommand(opts) {
433
446
  pkg.scripts["xera:heal-prepare"] = "xera-internal heal-prepare";
434
447
  pkg.scripts["xera:disputes"] = "xera-internal disputes";
435
448
  pkg.dependencies = pkg.dependencies ?? {};
436
- pkg.dependencies["@xera-ai/core"] = "^0.8.0";
437
- pkg.dependencies["@xera-ai/prompts"] = "^0.8.0";
449
+ pkg.dependencies["@xera-ai/core"] = `^${CLI_VERSION}`;
450
+ pkg.dependencies["@xera-ai/prompts"] = `^${CLI_VERSION}`;
438
451
  if (wantsWeb)
439
- pkg.dependencies["@xera-ai/web"] = "^0.8.0";
452
+ pkg.dependencies["@xera-ai/web"] = `^${CLI_VERSION}`;
440
453
  if (wantsHttp)
441
- pkg.dependencies["@xera-ai/http"] = "^0.8.0";
454
+ pkg.dependencies["@xera-ai/http"] = `^${CLI_VERSION}`;
442
455
  pkg.devDependencies = pkg.devDependencies ?? {};
443
456
  pkg.devDependencies["@playwright/test"] = "^1.60.0";
444
457
  pkg.devDependencies["@types/node"] = "^25.8.0";
@@ -486,6 +499,7 @@ import { join as join4 } from "path";
486
499
  import * as p2 from "@clack/prompts";
487
500
  import pc3 from "picocolors";
488
501
  var require3 = createRequire2(import.meta.url);
502
+ var CLI_VERSION2 = require3("../package.json").version;
489
503
  async function initUpdateCommand(_opts) {
490
504
  const cwd = process.cwd();
491
505
  p2.intro(pc3.cyan("xera init --update"));
@@ -496,12 +510,12 @@ async function initUpdateCommand(_opts) {
496
510
  }
497
511
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
498
512
  pkg.dependencies = pkg.dependencies ?? {};
499
- pkg.dependencies["@xera-ai/core"] = "^0.8.0";
500
- pkg.dependencies["@xera-ai/prompts"] = "^0.8.0";
513
+ pkg.dependencies["@xera-ai/core"] = `^${CLI_VERSION2}`;
514
+ pkg.dependencies["@xera-ai/prompts"] = `^${CLI_VERSION2}`;
501
515
  if (pkg.dependencies["@xera-ai/web"])
502
- pkg.dependencies["@xera-ai/web"] = "^0.8.0";
516
+ pkg.dependencies["@xera-ai/web"] = `^${CLI_VERSION2}`;
503
517
  if (pkg.dependencies["@xera-ai/http"])
504
- pkg.dependencies["@xera-ai/http"] = "^0.8.0";
518
+ pkg.dependencies["@xera-ai/http"] = `^${CLI_VERSION2}`;
505
519
  pkg.scripts = pkg.scripts ?? {};
506
520
  pkg.scripts["xera:auth-setup"] = "xera-internal auth-setup";
507
521
  pkg.scripts["xera:graph-record"] = "xera-internal graph-record";
@@ -564,6 +578,43 @@ var require4 = createRequire3(import.meta.url);
564
578
  var VERSION = require4("../package.json").version;
565
579
  var VALID_SHAPES = ["web", "api", "mixed"];
566
580
  var VALID_AUTH_STRATEGIES = ["bearer", "apiKey", "basic", "oauth-cc", "none"];
581
+ var KNOWN_COMMANDS = ["init", "doctor"];
582
+ function levenshtein(a, b) {
583
+ const m = a.length;
584
+ const n = b.length;
585
+ const dp = Array.from({ length: m + 1 }, (_, i) => Array.from({ length: n + 1 }, (_2, j) => i === 0 ? j : j === 0 ? i : 0));
586
+ for (let i = 1;i <= m; i++) {
587
+ for (let j = 1;j <= n; j++) {
588
+ dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
589
+ }
590
+ }
591
+ return dp[m][n];
592
+ }
593
+ function didYouMean(input) {
594
+ let best;
595
+ let bestDist = Number.POSITIVE_INFINITY;
596
+ for (const cmd of KNOWN_COMMANDS) {
597
+ const d = levenshtein(input.toLowerCase(), cmd);
598
+ if (d < bestDist) {
599
+ bestDist = d;
600
+ best = cmd;
601
+ }
602
+ }
603
+ return bestDist <= 3 ? best : undefined;
604
+ }
605
+ function unknownCommand(input) {
606
+ console.error(pc4.red(`
607
+ error: Unknown command '${input}'
608
+ `));
609
+ const suggestion = didYouMean(input);
610
+ if (suggestion) {
611
+ console.error(` Did you mean ${pc4.cyan(suggestion)}?
612
+ `);
613
+ }
614
+ console.error(` Run ${pc4.cyan("xera --help")} to see available commands.
615
+ `);
616
+ process.exit(1);
617
+ }
567
618
  async function main() {
568
619
  const cli = cac("xera");
569
620
  cli.help();
@@ -577,14 +628,18 @@ async function main() {
577
628
  const initOpts = { yes: !!opts.yes };
578
629
  if (opts.shape !== undefined) {
579
630
  if (!VALID_SHAPES.includes(opts.shape)) {
580
- console.error(pc4.red(`[xera] --shape must be one of: ${VALID_SHAPES.join(", ")}`));
631
+ console.error(pc4.red(`
632
+ error: --shape must be one of: ${VALID_SHAPES.join(", ")}
633
+ `));
581
634
  process.exit(1);
582
635
  }
583
636
  initOpts.shape = opts.shape;
584
637
  }
585
638
  if (opts.authStrategy !== undefined) {
586
639
  if (!VALID_AUTH_STRATEGIES.includes(opts.authStrategy)) {
587
- console.error(pc4.red(`[xera] --auth-strategy must be one of: ${VALID_AUTH_STRATEGIES.join(", ")}`));
640
+ console.error(pc4.red(`
641
+ error: --auth-strategy must be one of: ${VALID_AUTH_STRATEGIES.join(", ")}
642
+ `));
588
643
  process.exit(1);
589
644
  }
590
645
  initOpts.authStrategy = opts.authStrategy;
@@ -615,11 +670,22 @@ async function main() {
615
670
  const exit = await doctorCommand(opts);
616
671
  process.exit(exit);
617
672
  });
673
+ const rawArgs = process.argv.slice(2);
674
+ if (rawArgs.length === 0) {
675
+ cli.outputHelp();
676
+ process.exit(0);
677
+ }
678
+ const firstArg = rawArgs[0];
679
+ if (!firstArg.startsWith("-") && !KNOWN_COMMANDS.includes(firstArg)) {
680
+ unknownCommand(firstArg);
681
+ }
618
682
  try {
619
683
  cli.parse(process.argv, { run: false });
620
684
  await cli.runMatchedCommand();
621
685
  } catch (e) {
622
- console.error(pc4.red(`[xera] ${e.message}`));
686
+ console.error(pc4.red(`
687
+ error: ${e.message}
688
+ `));
623
689
  process.exit(1);
624
690
  }
625
691
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xera-ai/cli",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "xera": "./bin/xera"
@@ -15,8 +15,8 @@
15
15
  "typecheck": "tsc --noEmit"
16
16
  },
17
17
  "dependencies": {
18
- "@xera-ai/core": "^0.9.0",
19
- "@xera-ai/skills": "^0.9.0",
18
+ "@xera-ai/core": "^0.9.2",
19
+ "@xera-ai/skills": "^0.9.2",
20
20
  "@clack/prompts": "1.4.0",
21
21
  "cac": "7.0.0",
22
22
  "picocolors": "1.1.1"