outfitter 0.2.0 → 0.2.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.
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  import {
3
3
  outfitterActions
4
- } from "./shared/chunk-fe7djmgg.js";
4
+ } from "./shared/chunk-f3sch043.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { buildCliCommands } from "@outfitter/cli/actions";
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  printDoctorResults,
7
7
  runDoctor,
8
8
  runInit
9
- } from "./shared/chunk-fe7djmgg.js";
9
+ } from "./shared/chunk-f3sch043.js";
10
10
  export {
11
11
  runInit,
12
12
  runDoctor,
@@ -829,7 +829,7 @@ function initCommand(program) {
829
829
  return typeof flags.opts === "function" ? flags.opts() : flags;
830
830
  };
831
831
  const resolveLocal = (flags) => Boolean(flags.local || flags.workspace);
832
- const withCommonOptions = (command) => command.option("-n, --name <name>", "Package name (defaults to directory name)").option("-b, --bin <name>", "Binary name (defaults to project name)").option("-f, --force", "Overwrite existing files", false).option("--local", "Use workspace:* for @outfitter dependencies", false).option("--workspace", "Alias for --local", false).option("--json", "Output as JSON", false).option("--with <blocks>", "Tooling to add (comma-separated: scaffolding, claude, biome, lefthook, bootstrap)").option("--no-tooling", "Skip tooling setup");
832
+ const withCommonOptions = (command) => command.option("-n, --name <name>", "Package name (defaults to directory name)").option("-b, --bin <name>", "Binary name (defaults to project name)").option("-f, --force", "Overwrite existing files", false).option("--local", "Use workspace:* for @outfitter dependencies", false).option("--workspace", "Alias for --local", false).option("--with <blocks>", "Tooling to add (comma-separated: scaffolding, claude, biome, lefthook, bootstrap)").option("--no-tooling", "Skip tooling setup").option("--json", "Output as JSON", false);
833
833
  const resolveOutputMode = (flags) => {
834
834
  if (flags.json) {
835
835
  process.env["OUTFITTER_JSON"] = "1";
@@ -924,12 +924,13 @@ function initCommand(program) {
924
924
  }
925
925
 
926
926
  // src/actions.ts
927
- import { output as output5 } from "@outfitter/cli/output";
927
+ import { resolve as resolve5 } from "node:path";
928
+ import { output as output6 } from "@outfitter/cli/output";
928
929
  import {
929
930
  createActionRegistry,
930
931
  defineAction,
931
- InternalError,
932
- Result as Result3
932
+ InternalError as InternalError2,
933
+ Result as Result4
933
934
  } from "@outfitter/contracts";
934
935
  import { z } from "zod";
935
936
 
@@ -1297,6 +1298,229 @@ async function printDemoResults(result) {
1297
1298
  }
1298
1299
  }
1299
1300
 
1301
+ // src/commands/update.ts
1302
+ import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
1303
+ import { join as join4, resolve as resolve4 } from "node:path";
1304
+ import { output as output5 } from "@outfitter/cli/output";
1305
+ import { createTheme as createTheme4 } from "@outfitter/cli/render";
1306
+ import { InternalError, Result as Result3 } from "@outfitter/contracts";
1307
+ function getInstalledPackages(cwd) {
1308
+ const pkgPath = join4(cwd, "package.json");
1309
+ if (!existsSync4(pkgPath)) {
1310
+ return Result3.err(InternalError.create("No package.json found", { cwd }));
1311
+ }
1312
+ let raw;
1313
+ try {
1314
+ raw = readFileSync4(pkgPath, "utf-8");
1315
+ } catch {
1316
+ return Result3.err(InternalError.create("Failed to read package.json", { cwd }));
1317
+ }
1318
+ let pkg;
1319
+ try {
1320
+ pkg = JSON.parse(raw);
1321
+ } catch {
1322
+ return Result3.err(InternalError.create("Invalid JSON in package.json", { cwd }));
1323
+ }
1324
+ const deps = {
1325
+ ...pkg.dependencies ?? {},
1326
+ ...pkg.devDependencies ?? {}
1327
+ };
1328
+ const packages = [];
1329
+ for (const [name, version] of Object.entries(deps)) {
1330
+ if (!name.startsWith("@outfitter/"))
1331
+ continue;
1332
+ if (version.startsWith("workspace:")) {
1333
+ const wsVersion = version.slice("workspace:".length);
1334
+ if (wsVersion === "*" || wsVersion === "~" || wsVersion === "^") {
1335
+ continue;
1336
+ }
1337
+ const wsClean = wsVersion.replace(/^[\^~>=<]+/, "");
1338
+ try {
1339
+ if (!Bun.semver.satisfies(wsClean, "*"))
1340
+ continue;
1341
+ } catch {
1342
+ continue;
1343
+ }
1344
+ packages.push({ name, version: wsClean });
1345
+ continue;
1346
+ }
1347
+ const cleaned = version.replace(/^[\^~>=<]+/, "");
1348
+ try {
1349
+ if (!Bun.semver.satisfies(cleaned, "*"))
1350
+ continue;
1351
+ } catch {
1352
+ continue;
1353
+ }
1354
+ packages.push({ name, version: cleaned });
1355
+ }
1356
+ return Result3.ok(packages);
1357
+ }
1358
+ async function getLatestVersion(name) {
1359
+ try {
1360
+ const proc = Bun.spawn(["npm", "view", name, "version"], {
1361
+ stdout: "pipe",
1362
+ stderr: "pipe"
1363
+ });
1364
+ const stdout = await new Response(proc.stdout).text();
1365
+ const exitCode = await proc.exited;
1366
+ if (exitCode !== 0)
1367
+ return null;
1368
+ return stdout.trim() || null;
1369
+ } catch {
1370
+ return null;
1371
+ }
1372
+ }
1373
+ var MIGRATION_DOC_PATHS = [
1374
+ "plugins/kit/shared/migrations",
1375
+ "node_modules/@outfitter/kit/shared/migrations"
1376
+ ];
1377
+ function findMigrationDocsDir(cwd, binaryDir) {
1378
+ for (const relative of MIGRATION_DOC_PATHS) {
1379
+ const dir = join4(cwd, relative);
1380
+ if (existsSync4(dir))
1381
+ return dir;
1382
+ }
1383
+ let current = resolve4(cwd);
1384
+ const root = resolve4("/");
1385
+ while (current !== root) {
1386
+ const parent = resolve4(current, "..");
1387
+ if (parent === current)
1388
+ break;
1389
+ current = parent;
1390
+ for (const relative of MIGRATION_DOC_PATHS) {
1391
+ const dir = join4(current, relative);
1392
+ if (existsSync4(dir))
1393
+ return dir;
1394
+ }
1395
+ }
1396
+ const resolvedBinaryDir = binaryDir ?? resolve4(import.meta.dir, "../../../..");
1397
+ for (const relative of MIGRATION_DOC_PATHS) {
1398
+ const dir = join4(resolvedBinaryDir, relative);
1399
+ if (existsSync4(dir))
1400
+ return dir;
1401
+ }
1402
+ return null;
1403
+ }
1404
+ function readMigrationDocs(migrationsDir, shortName, fromVersion, toVersion) {
1405
+ const glob = new Bun.Glob(`outfitter-${shortName}-*.md`);
1406
+ const versionPattern = new RegExp(`^outfitter-${shortName}-(\\d+\\.\\d+\\.\\d+)\\.md$`);
1407
+ const docs = [];
1408
+ for (const entry of glob.scanSync({ cwd: migrationsDir })) {
1409
+ const match = entry.match(versionPattern);
1410
+ if (!match?.[1])
1411
+ continue;
1412
+ const docVersion = match[1];
1413
+ if (Bun.semver.order(docVersion, fromVersion) <= 0)
1414
+ continue;
1415
+ if (Bun.semver.order(docVersion, toVersion) > 0)
1416
+ continue;
1417
+ const filePath = join4(migrationsDir, entry);
1418
+ const content = readFileSync4(filePath, "utf-8");
1419
+ const body = content.replace(/^---\n[\s\S]*?\n---\n*/, "").trim();
1420
+ if (body) {
1421
+ docs.push({ version: docVersion, content: body });
1422
+ }
1423
+ }
1424
+ docs.sort((a, b) => Bun.semver.order(a.version, b.version));
1425
+ return docs.map((d) => d.content);
1426
+ }
1427
+ async function runUpdate(options) {
1428
+ const cwd = resolve4(options.cwd);
1429
+ const installedResult = getInstalledPackages(cwd);
1430
+ if (installedResult.isErr())
1431
+ return installedResult;
1432
+ const installed = installedResult.value;
1433
+ if (installed.length === 0) {
1434
+ return Result3.ok({
1435
+ packages: [],
1436
+ total: 0,
1437
+ updatesAvailable: 0,
1438
+ hasBreaking: false
1439
+ });
1440
+ }
1441
+ const packages = await Promise.all(installed.map(async (pkg) => {
1442
+ const latest = await getLatestVersion(pkg.name);
1443
+ const updateAvailable = latest !== null && Bun.semver.order(latest, pkg.version) > 0;
1444
+ const breaking = updateAvailable && latest !== null ? getMajor(latest) > getMajor(pkg.version) : false;
1445
+ return {
1446
+ name: pkg.name,
1447
+ current: pkg.version,
1448
+ latest,
1449
+ updateAvailable,
1450
+ breaking
1451
+ };
1452
+ }));
1453
+ const updatesAvailable = packages.filter((p) => p.updateAvailable).length;
1454
+ const hasBreaking = packages.some((p) => p.breaking);
1455
+ return Result3.ok({
1456
+ packages,
1457
+ total: packages.length,
1458
+ updatesAvailable,
1459
+ hasBreaking
1460
+ });
1461
+ }
1462
+ function getMajor(version) {
1463
+ const parts = version.split(".");
1464
+ return Number.parseInt(parts[0] ?? "0", 10);
1465
+ }
1466
+ async function printUpdateResults(result, options) {
1467
+ const mode = options?.mode;
1468
+ if (mode === "json" || mode === "jsonl") {
1469
+ await output5(result, { mode });
1470
+ return;
1471
+ }
1472
+ const theme = createTheme4();
1473
+ const lines = ["", "Outfitter Update", "", "=".repeat(60)];
1474
+ if (result.packages.length === 0) {
1475
+ lines.push("No @outfitter/* packages found in package.json.");
1476
+ await output5(lines);
1477
+ return;
1478
+ }
1479
+ lines.push(` ${"Package".padEnd(28)} ${"Current".padEnd(10)} ${"Available".padEnd(10)} Migration`);
1480
+ lines.push(` ${"─".repeat(28)} ${"─".repeat(10)} ${"─".repeat(10)} ${"─".repeat(20)}`);
1481
+ for (const pkg of result.packages) {
1482
+ const name = pkg.name.padEnd(28);
1483
+ const current = pkg.current.padEnd(10);
1484
+ const available = (pkg.latest ?? "unknown").padEnd(10);
1485
+ let migration;
1486
+ if (pkg.latest === null) {
1487
+ migration = theme.muted("lookup failed");
1488
+ } else if (!pkg.updateAvailable) {
1489
+ migration = theme.muted("up to date");
1490
+ } else if (pkg.breaking) {
1491
+ migration = theme.error("major (breaking)");
1492
+ } else {
1493
+ migration = theme.success("minor (no breaking)");
1494
+ }
1495
+ lines.push(` ${name} ${current} ${available} ${migration}`);
1496
+ }
1497
+ lines.push("");
1498
+ if (result.updatesAvailable > 0) {
1499
+ lines.push(theme.muted("Run 'outfitter update --guide' for migration instructions."));
1500
+ } else {
1501
+ lines.push(theme.success("All packages are up to date."));
1502
+ }
1503
+ if (options?.guide && result.updatesAvailable > 0) {
1504
+ const cwd = options.cwd ?? process.cwd();
1505
+ const migrationsDir = findMigrationDocsDir(cwd);
1506
+ if (migrationsDir) {
1507
+ lines.push("", "=".repeat(60), "", "Migration Guide", "");
1508
+ for (const pkg of result.packages) {
1509
+ if (!(pkg.updateAvailable && pkg.latest))
1510
+ continue;
1511
+ const shortName = pkg.name.replace("@outfitter/", "");
1512
+ const docs = readMigrationDocs(migrationsDir, shortName, pkg.current, pkg.latest);
1513
+ for (const doc of docs) {
1514
+ lines.push(doc, "", "---", "");
1515
+ }
1516
+ }
1517
+ } else {
1518
+ lines.push("", theme.muted("Migration docs not found locally. See https://github.com/outfitter-dev/outfitter for migration guides."));
1519
+ }
1520
+ }
1521
+ await output5(lines);
1522
+ }
1523
+
1300
1524
  // src/actions.ts
1301
1525
  var outputModeSchema = z.enum(["human", "json", "jsonl"]).optional();
1302
1526
  var initInputSchema = z.object({
@@ -1364,11 +1588,6 @@ var commonInitOptions = [
1364
1588
  flags: "--workspace",
1365
1589
  description: "Alias for --local",
1366
1590
  defaultValue: false
1367
- },
1368
- {
1369
- flags: "--json",
1370
- description: "Output as JSON",
1371
- defaultValue: false
1372
1591
  }
1373
1592
  ];
1374
1593
  var templateOption = {
@@ -1394,13 +1613,13 @@ function createInitAction(options) {
1394
1613
  const outputOptions = outputMode ? { mode: outputMode } : undefined;
1395
1614
  const result = await runInit(initInput);
1396
1615
  if (result.isErr()) {
1397
- return Result3.err(new InternalError({
1616
+ return Result4.err(new InternalError2({
1398
1617
  message: result.error.message,
1399
1618
  context: { action: options.id }
1400
1619
  }));
1401
1620
  }
1402
1621
  await printInitResults(initInput.targetDir, result.value, outputOptions);
1403
- return Result3.ok({ ok: true });
1622
+ return Result4.ok({ ok: true });
1404
1623
  }
1405
1624
  });
1406
1625
  }
@@ -1429,11 +1648,14 @@ var demoAction = defineAction({
1429
1648
  defaultValue: false
1430
1649
  }
1431
1650
  ],
1432
- mapInput: (context) => ({
1433
- section: context.args[0],
1434
- list: Boolean(context.flags["list"]),
1435
- animate: Boolean(context.flags["animate"])
1436
- })
1651
+ mapInput: (context) => {
1652
+ resolveOutputMode(context.flags);
1653
+ return {
1654
+ section: context.args[0],
1655
+ list: Boolean(context.flags["list"]),
1656
+ animate: Boolean(context.flags["animate"])
1657
+ };
1658
+ }
1437
1659
  },
1438
1660
  handler: async (input) => {
1439
1661
  const result = await runDemo(input);
@@ -1441,7 +1663,7 @@ var demoAction = defineAction({
1441
1663
  if (result.exitCode !== 0) {
1442
1664
  process.exit(result.exitCode);
1443
1665
  }
1444
- return Result3.ok(result);
1666
+ return Result4.ok(result);
1445
1667
  }
1446
1668
  });
1447
1669
  var doctorAction = defineAction({
@@ -1452,13 +1674,6 @@ var doctorAction = defineAction({
1452
1674
  cli: {
1453
1675
  command: "doctor",
1454
1676
  description: "Validate environment and dependencies",
1455
- options: [
1456
- {
1457
- flags: "--json",
1458
- description: "Output as JSON",
1459
- defaultValue: false
1460
- }
1461
- ],
1462
1677
  mapInput: (context) => {
1463
1678
  const outputMode = resolveOutputMode(context.flags);
1464
1679
  return {
@@ -1475,7 +1690,7 @@ var doctorAction = defineAction({
1475
1690
  if (result.exitCode !== 0) {
1476
1691
  process.exit(result.exitCode);
1477
1692
  }
1478
- return Result3.ok(result);
1693
+ return Result4.ok(result);
1479
1694
  }
1480
1695
  });
1481
1696
  var addInputSchema = z.object({
@@ -1504,11 +1719,6 @@ var addAction = defineAction({
1504
1719
  flags: "--dry-run",
1505
1720
  description: "Show what would be added without making changes",
1506
1721
  defaultValue: false
1507
- },
1508
- {
1509
- flags: "--json",
1510
- description: "Output as JSON",
1511
- defaultValue: false
1512
1722
  }
1513
1723
  ],
1514
1724
  mapInput: (context) => {
@@ -1527,13 +1737,13 @@ var addAction = defineAction({
1527
1737
  const outputOptions = outputMode ? { mode: outputMode } : undefined;
1528
1738
  const result = await runAdd(addInput);
1529
1739
  if (result.isErr()) {
1530
- return Result3.err(new InternalError({
1740
+ return Result4.err(new InternalError2({
1531
1741
  message: result.error.message,
1532
1742
  context: { action: "add" }
1533
1743
  }));
1534
1744
  }
1535
1745
  await printAddResults(result.value, addInput.dryRun, outputOptions);
1536
- return Result3.ok(result.value);
1746
+ return Result4.ok(result.value);
1537
1747
  }
1538
1748
  });
1539
1749
  var listBlocksAction = defineAction({
@@ -1545,13 +1755,6 @@ var listBlocksAction = defineAction({
1545
1755
  group: "add",
1546
1756
  command: "list",
1547
1757
  description: "List available blocks",
1548
- options: [
1549
- {
1550
- flags: "--json",
1551
- description: "Output as JSON",
1552
- defaultValue: false
1553
- }
1554
- ],
1555
1758
  mapInput: (context) => {
1556
1759
  const outputMode = resolveOutputMode(context.flags);
1557
1760
  return {
@@ -1562,21 +1765,72 @@ var listBlocksAction = defineAction({
1562
1765
  handler: async (input) => {
1563
1766
  const result = listBlocks();
1564
1767
  if (result.isErr()) {
1565
- return Result3.err(new InternalError({
1768
+ return Result4.err(new InternalError2({
1566
1769
  message: result.error.message,
1567
1770
  context: { action: "add.list" }
1568
1771
  }));
1569
1772
  }
1570
1773
  if (input.outputMode === "json" || input.outputMode === "jsonl") {
1571
- await output5({ blocks: result.value }, { mode: input.outputMode });
1774
+ await output6({ blocks: result.value }, { mode: input.outputMode });
1572
1775
  } else {
1573
1776
  const lines = [
1574
1777
  "Available blocks:",
1575
1778
  ...result.value.map((block) => ` - ${block}`)
1576
1779
  ];
1577
- await output5(lines);
1780
+ await output6(lines);
1781
+ }
1782
+ return Result4.ok({ blocks: result.value });
1783
+ }
1784
+ });
1785
+ var updateInputSchema = z.object({
1786
+ cwd: z.string(),
1787
+ guide: z.boolean(),
1788
+ outputMode: outputModeSchema
1789
+ });
1790
+ var updateAction = defineAction({
1791
+ id: "update",
1792
+ description: "Check for @outfitter/* package updates and migration guidance",
1793
+ surfaces: ["cli"],
1794
+ input: updateInputSchema,
1795
+ cli: {
1796
+ command: "update",
1797
+ description: "Check for @outfitter/* package updates and migration guidance",
1798
+ options: [
1799
+ {
1800
+ flags: "--guide",
1801
+ description: "Show migration instructions for available updates",
1802
+ defaultValue: false
1803
+ },
1804
+ {
1805
+ flags: "--cwd <path>",
1806
+ description: "Working directory (defaults to current directory)"
1807
+ }
1808
+ ],
1809
+ mapInput: (context) => {
1810
+ const outputMode = resolveOutputMode(context.flags);
1811
+ const cwd = typeof context.flags["cwd"] === "string" ? resolve5(process.cwd(), context.flags["cwd"]) : process.cwd();
1812
+ return {
1813
+ cwd,
1814
+ guide: Boolean(context.flags["guide"]),
1815
+ ...outputMode ? { outputMode } : {}
1816
+ };
1578
1817
  }
1579
- return Result3.ok({ blocks: result.value });
1818
+ },
1819
+ handler: async (input) => {
1820
+ const { outputMode, ...updateInput } = input;
1821
+ const result = await runUpdate(updateInput);
1822
+ if (result.isErr()) {
1823
+ return Result4.err(new InternalError2({
1824
+ message: result.error.message,
1825
+ context: { action: "update" }
1826
+ }));
1827
+ }
1828
+ await printUpdateResults(result.value, {
1829
+ ...outputMode ? { mode: outputMode } : {},
1830
+ guide: updateInput.guide,
1831
+ cwd: updateInput.cwd
1832
+ });
1833
+ return Result4.ok(result.value);
1580
1834
  }
1581
1835
  });
1582
1836
  var outfitterActions = createActionRegistry().add(createInitAction({
@@ -1599,6 +1853,6 @@ var outfitterActions = createActionRegistry().add(createInitAction({
1599
1853
  description: "Scaffold a new daemon project",
1600
1854
  command: "daemon [directory]",
1601
1855
  templateOverride: "daemon"
1602
- })).add(demoAction).add(doctorAction).add(addAction).add(listBlocksAction);
1856
+ })).add(demoAction).add(doctorAction).add(addAction).add(listBlocksAction).add(updateAction);
1603
1857
 
1604
1858
  export { runDoctor, printDoctorResults, doctorCommand, InitError, runInit, initCommand, outfitterActions };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "outfitter",
3
3
  "description": "Outfitter umbrella CLI for scaffolding and project management",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
@@ -10,40 +10,34 @@
10
10
  "module": "./dist/index.js",
11
11
  "types": "./dist/index.d.ts",
12
12
  "exports": {
13
- "./commands/demo/errors": {
13
+ ".": {
14
14
  "import": {
15
- "types": "./dist/commands/demo/errors.d.ts",
16
- "default": "./dist/commands/demo/errors.js"
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
17
  }
18
18
  },
19
19
  "./commands/demo": {
20
20
  "import": {
21
- "types": "./dist/commands/demo.d.ts",
22
- "default": "./dist/commands/demo.js"
23
- }
24
- },
25
- "./actions": {
26
- "import": {
27
- "types": "./dist/actions.d.ts",
28
- "default": "./dist/actions.js"
21
+ "types": "./dist/commands/demo/index.d.ts",
22
+ "default": "./dist/commands/demo/index.js"
29
23
  }
30
24
  },
31
- ".": {
25
+ "./commands/demo/errors": {
32
26
  "import": {
33
- "types": "./dist/index.d.ts",
34
- "default": "./dist/index.js"
27
+ "types": "./dist/commands/demo/errors.d.ts",
28
+ "default": "./dist/commands/demo/errors.js"
35
29
  }
36
30
  },
37
- "./commands/doctor": {
31
+ "./actions": {
38
32
  "import": {
39
- "types": "./dist/commands/doctor.d.ts",
40
- "default": "./dist/commands/doctor.js"
33
+ "types": "./dist/actions.d.ts",
34
+ "default": "./dist/actions.js"
41
35
  }
42
36
  },
43
- "./commands/init": {
37
+ "./commands/update": {
44
38
  "import": {
45
- "types": "./dist/commands/init.d.ts",
46
- "default": "./dist/commands/init.js"
39
+ "types": "./dist/commands/update.d.ts",
40
+ "default": "./dist/commands/update.js"
47
41
  }
48
42
  },
49
43
  "./commands/shared-deps": {
@@ -52,12 +46,24 @@
52
46
  "default": "./dist/commands/shared-deps.js"
53
47
  }
54
48
  },
49
+ "./commands/doctor": {
50
+ "import": {
51
+ "types": "./dist/commands/doctor.d.ts",
52
+ "default": "./dist/commands/doctor.js"
53
+ }
54
+ },
55
55
  "./commands/add": {
56
56
  "import": {
57
57
  "types": "./dist/commands/add.d.ts",
58
58
  "default": "./dist/commands/add.js"
59
59
  }
60
60
  },
61
+ "./commands/init": {
62
+ "import": {
63
+ "types": "./dist/commands/init.d.ts",
64
+ "default": "./dist/commands/init.js"
65
+ }
66
+ },
61
67
  "./package.json": "./package.json"
62
68
  },
63
69
  "bin": {
@@ -80,11 +86,11 @@
80
86
  },
81
87
  "dependencies": {
82
88
  "@clack/prompts": "^0.10.0",
83
- "@outfitter/cli": "0.2.0",
84
- "@outfitter/config": "0.2.0",
89
+ "@outfitter/cli": "0.3.0",
90
+ "@outfitter/config": "0.3.0",
85
91
  "@outfitter/contracts": "0.2.0",
86
- "@outfitter/logging": "0.2.0",
87
- "@outfitter/tooling": "0.2.0",
92
+ "@outfitter/logging": "0.3.0",
93
+ "@outfitter/tooling": "0.2.1",
88
94
  "commander": "^14.0.2",
89
95
  "zod": "^4.3.5"
90
96
  },