outfitter 0.2.2 → 0.2.3

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 (135) hide show
  1. package/README.md +215 -116
  2. package/dist/actions.d.ts +2 -0
  3. package/dist/actions.js +34 -0
  4. package/dist/cli.js +3 -1
  5. package/dist/commands/add.d.ts +54 -0
  6. package/dist/commands/add.js +16 -0
  7. package/dist/commands/check.d.ts +91 -0
  8. package/dist/commands/check.js +14 -0
  9. package/dist/commands/demo.d.ts +21 -0
  10. package/dist/commands/demo.js +8 -0
  11. package/dist/commands/docs-module-loader.d.ts +2 -0
  12. package/dist/commands/docs-module-loader.js +8 -0
  13. package/dist/commands/doctor.d.ts +2 -0
  14. package/dist/commands/doctor.js +13 -0
  15. package/dist/commands/init.d.ts +7 -0
  16. package/dist/commands/init.js +31 -0
  17. package/dist/commands/migrate-kit.d.ts +2 -0
  18. package/dist/commands/migrate-kit.js +15 -0
  19. package/dist/commands/repo.d.ts +3 -0
  20. package/dist/commands/repo.js +9 -0
  21. package/dist/commands/scaffold.d.ts +4 -0
  22. package/dist/commands/scaffold.js +31 -0
  23. package/dist/commands/shared-deps.d.ts +36 -0
  24. package/dist/commands/shared-deps.js +10 -0
  25. package/dist/commands/update-planner.d.ts +58 -0
  26. package/dist/commands/update-planner.js +8 -0
  27. package/dist/commands/update-workspace.d.ts +76 -0
  28. package/dist/commands/update-workspace.js +16 -0
  29. package/dist/commands/update.d.ts +113 -0
  30. package/dist/commands/update.js +21 -0
  31. package/dist/create/index.d.ts +5 -0
  32. package/dist/create/index.js +29 -0
  33. package/dist/create/planner.d.ts +3 -0
  34. package/dist/create/planner.js +21 -0
  35. package/dist/create/presets.d.ts +3 -0
  36. package/dist/create/presets.js +12 -0
  37. package/dist/create/types.d.ts +2 -0
  38. package/dist/create/types.js +1 -0
  39. package/dist/engine/blocks.d.ts +3 -0
  40. package/dist/engine/blocks.js +12 -0
  41. package/dist/engine/collector.d.ts +2 -0
  42. package/dist/engine/collector.js +8 -0
  43. package/dist/engine/config.d.ts +3 -0
  44. package/dist/engine/config.js +12 -0
  45. package/dist/engine/executor.d.ts +3 -0
  46. package/dist/engine/executor.js +16 -0
  47. package/dist/engine/index.d.ts +8 -0
  48. package/dist/engine/index.js +59 -0
  49. package/dist/engine/names.d.ts +2 -0
  50. package/dist/engine/names.js +16 -0
  51. package/dist/engine/post-scaffold.d.ts +3 -0
  52. package/dist/engine/post-scaffold.js +8 -0
  53. package/dist/engine/render-plan.d.ts +7 -0
  54. package/dist/engine/render-plan.js +9 -0
  55. package/dist/engine/template.d.ts +3 -0
  56. package/dist/engine/template.js +17 -0
  57. package/dist/engine/types.d.ts +2 -0
  58. package/dist/engine/types.js +8 -0
  59. package/dist/engine/workspace.d.ts +3 -0
  60. package/dist/engine/workspace.js +13 -0
  61. package/dist/index.d.ts +228 -152
  62. package/dist/index.js +144 -14
  63. package/dist/manifest.d.ts +71 -0
  64. package/dist/manifest.js +16 -0
  65. package/dist/output-mode.d.ts +2 -0
  66. package/dist/output-mode.js +10 -0
  67. package/dist/shared/chunk-b0y0cwkr.js +5533 -0
  68. package/dist/shared/outfitter-193jvzg4.d.ts +5 -0
  69. package/dist/shared/outfitter-1dd0k853.js +194 -0
  70. package/dist/shared/outfitter-1h7k8xxt.js +29 -0
  71. package/dist/shared/outfitter-1qwpjt6w.js +125 -0
  72. package/dist/shared/outfitter-2ngep1h2.d.ts +5 -0
  73. package/dist/shared/outfitter-2np85etz.js +95 -0
  74. package/dist/shared/outfitter-33w361tc.d.ts +18 -0
  75. package/dist/shared/outfitter-344t1r38.js +1 -0
  76. package/dist/shared/outfitter-3weh61w7.d.ts +25 -0
  77. package/dist/shared/outfitter-4s9meh3j.js +221 -0
  78. package/dist/shared/outfitter-6a4bq054.js +322 -0
  79. package/dist/shared/outfitter-6bkqjk86.d.ts +3 -0
  80. package/dist/shared/outfitter-6gc3g5wk.js +98 -0
  81. package/dist/shared/outfitter-7cv5fg1m.js +61 -0
  82. package/dist/shared/outfitter-7ha7p61k.d.ts +6 -0
  83. package/dist/shared/outfitter-7r12fj7f.js +30 -0
  84. package/dist/shared/outfitter-8y2dfx6n.js +11 -0
  85. package/dist/shared/outfitter-9c8edfsn.js +715 -0
  86. package/dist/shared/outfitter-9x1brcmq.js +184 -0
  87. package/dist/shared/outfitter-a79xrm12.d.ts +17 -0
  88. package/dist/shared/outfitter-amc4jbs1.d.ts +50 -0
  89. package/dist/shared/outfitter-ara3djt0.js +73 -0
  90. package/dist/shared/outfitter-avhm5z6w.js +82 -0
  91. package/dist/shared/outfitter-b5nd42y4.d.ts +45 -0
  92. package/dist/shared/outfitter-dd0btgec.d.ts +40 -0
  93. package/dist/shared/outfitter-e2zz5wv7.d.ts +51 -0
  94. package/dist/shared/outfitter-ehp18x1n.js +1 -0
  95. package/dist/shared/outfitter-fnsmx3xg.js +750 -0
  96. package/dist/shared/outfitter-gdvm5c0b.d.ts +4 -0
  97. package/dist/shared/outfitter-gp4v5gkf.js +322 -0
  98. package/dist/shared/outfitter-h1mnzzd1.d.ts +14 -0
  99. package/dist/shared/outfitter-hpymx4m9.js +184 -0
  100. package/dist/shared/outfitter-hvsaxgcp.js +1 -0
  101. package/dist/shared/outfitter-j8yc7294.d.ts +22 -0
  102. package/dist/shared/outfitter-jyxwznk1.js +404 -0
  103. package/dist/shared/outfitter-k112c427.js +21 -0
  104. package/dist/shared/outfitter-k56rmt24.d.ts +30 -0
  105. package/dist/shared/outfitter-ksa1pp4t.d.ts +4 -0
  106. package/dist/shared/outfitter-mdt37hqm.js +4 -0
  107. package/dist/shared/outfitter-mtbpabf3.js +91 -0
  108. package/dist/shared/outfitter-nm4m0v6x.d.ts +131 -0
  109. package/dist/shared/outfitter-nmeecf1b.js +531 -0
  110. package/dist/shared/outfitter-npyfbdmc.d.ts +6 -0
  111. package/dist/shared/outfitter-pxt58tsq.js +582 -0
  112. package/dist/shared/outfitter-q9agarmb.js +42 -0
  113. package/dist/shared/outfitter-qfgj5xpq.js +70 -0
  114. package/dist/shared/outfitter-qfh36ddg.d.ts +66 -0
  115. package/dist/shared/outfitter-s6k8y2p4.js +269 -0
  116. package/dist/shared/outfitter-sftf1s26.js +199 -0
  117. package/dist/shared/outfitter-sg7ncy4a.d.ts +51 -0
  118. package/dist/shared/outfitter-sgtq57qr.d.ts +5 -0
  119. package/dist/shared/outfitter-txre6cdn.d.ts +60 -0
  120. package/dist/shared/outfitter-vh4xgb93.js +35 -0
  121. package/dist/shared/outfitter-ya44h1km.js +191 -0
  122. package/dist/shared/outfitter-zwyvewr1.js +36 -0
  123. package/dist/targets/index.d.ts +4 -0
  124. package/dist/targets/index.js +29 -0
  125. package/dist/targets/registry.d.ts +3 -0
  126. package/dist/targets/registry.js +28 -0
  127. package/dist/targets/types.d.ts +2 -0
  128. package/dist/targets/types.js +1 -0
  129. package/package.json +154 -37
  130. package/templates/minimal/.gitignore.template +30 -0
  131. package/templates/minimal/.lefthook.yml.template +26 -0
  132. package/templates/minimal/package.json.template +46 -0
  133. package/templates/minimal/src/index.ts.template +26 -0
  134. package/templates/minimal/tsconfig.json.template +34 -0
  135. package/dist/shared/chunk-sak1tt33.js +0 -3457
@@ -0,0 +1,750 @@
1
+ // @bun
2
+ import {
3
+ printMigrateKitResults,
4
+ runMigrateKit
5
+ } from "./outfitter-9c8edfsn.js";
6
+ import {
7
+ printScaffoldResults,
8
+ runScaffold
9
+ } from "./outfitter-nmeecf1b.js";
10
+ import {
11
+ printInitResults,
12
+ runInit
13
+ } from "./outfitter-pxt58tsq.js";
14
+ import {
15
+ printUpdateResults,
16
+ runUpdate
17
+ } from "./outfitter-jyxwznk1.js";
18
+ import {
19
+ printDoctorResults,
20
+ runDoctor
21
+ } from "./outfitter-sftf1s26.js";
22
+ import {
23
+ runDemo
24
+ } from "./outfitter-ya44h1km.js";
25
+ import {
26
+ printCheckResults,
27
+ runCheck
28
+ } from "./outfitter-gp4v5gkf.js";
29
+ import {
30
+ listBlocks,
31
+ printAddResults,
32
+ runAdd
33
+ } from "./outfitter-s6k8y2p4.js";
34
+ import {
35
+ resolveOutputModeFromContext,
36
+ resolveStructuredOutputMode
37
+ } from "./outfitter-7r12fj7f.js";
38
+
39
+ // apps/outfitter/src/actions.ts
40
+ import { resolve } from "path";
41
+ import { output } from "@outfitter/cli/output";
42
+ import {
43
+ createActionRegistry,
44
+ defineAction,
45
+ InternalError,
46
+ Result
47
+ } from "@outfitter/contracts";
48
+ import { z } from "zod";
49
+ var outputModeSchema = z.enum(["human", "json", "jsonl"]).default("human");
50
+ var initInputSchema = z.object({
51
+ targetDir: z.string(),
52
+ name: z.string().optional(),
53
+ bin: z.string().optional(),
54
+ preset: z.enum(["minimal", "cli", "mcp", "daemon"]).optional(),
55
+ template: z.string().optional(),
56
+ structure: z.enum(["single", "workspace"]).optional(),
57
+ workspaceName: z.string().optional(),
58
+ local: z.boolean().optional(),
59
+ force: z.boolean(),
60
+ with: z.string().optional(),
61
+ noTooling: z.boolean().optional(),
62
+ yes: z.boolean().optional(),
63
+ dryRun: z.boolean().optional(),
64
+ skipInstall: z.boolean().optional(),
65
+ skipGit: z.boolean().optional(),
66
+ skipCommit: z.boolean().optional(),
67
+ installTimeout: z.number().optional(),
68
+ outputMode: outputModeSchema
69
+ });
70
+ var scaffoldInputSchema = z.object({
71
+ target: z.string(),
72
+ name: z.string().optional(),
73
+ force: z.boolean(),
74
+ skipInstall: z.boolean(),
75
+ dryRun: z.boolean(),
76
+ with: z.string().optional(),
77
+ noTooling: z.boolean().optional(),
78
+ local: z.boolean().optional(),
79
+ installTimeout: z.number().optional(),
80
+ cwd: z.string(),
81
+ outputMode: outputModeSchema
82
+ });
83
+ var migrateKitInputSchema = z.object({
84
+ targetDir: z.string(),
85
+ dryRun: z.boolean(),
86
+ outputMode: outputModeSchema
87
+ });
88
+ var doctorInputSchema = z.object({
89
+ cwd: z.string(),
90
+ outputMode: outputModeSchema
91
+ });
92
+ function resolveStringFlag(value) {
93
+ return typeof value === "string" && value.length > 0 ? value : undefined;
94
+ }
95
+ function resolveNoToolingFlag(flags) {
96
+ if (typeof flags.noTooling === "boolean") {
97
+ return !flags.noTooling;
98
+ }
99
+ if (typeof flags.tooling === "boolean") {
100
+ if (!flags.tooling) {
101
+ return true;
102
+ }
103
+ return process.argv.includes("--tooling") ? false : undefined;
104
+ }
105
+ return;
106
+ }
107
+ function resolveLocalFlag(flags) {
108
+ if (flags.local === true || flags.workspace === true) {
109
+ return true;
110
+ }
111
+ return;
112
+ }
113
+ function resolveInitOptions(context, presetOverride) {
114
+ const flags = context.flags;
115
+ const targetDir = context.args[0] ?? process.cwd();
116
+ const name = resolveStringFlag(flags.name);
117
+ const bin = resolveStringFlag(flags.bin);
118
+ const preset = presetOverride ?? resolveStringFlag(flags.preset);
119
+ const template = resolveStringFlag(flags.template);
120
+ const structure = resolveStringFlag(flags.structure);
121
+ const workspaceName = resolveStringFlag(flags.workspaceName);
122
+ const local = resolveLocalFlag(flags);
123
+ const force = Boolean(flags.force);
124
+ const withBlocks = resolveStringFlag(flags.with);
125
+ const noTooling = resolveNoToolingFlag(flags);
126
+ const yes = Boolean(flags.yes);
127
+ const dryRun = Boolean(flags.dryRun ?? context.flags["dry-run"]);
128
+ const skipInstall = Boolean(flags.skipInstall ?? context.flags["skip-install"]);
129
+ const skipGit = Boolean(flags.skipGit ?? context.flags["skip-git"]);
130
+ const skipCommit = Boolean(flags.skipCommit ?? context.flags["skip-commit"]);
131
+ const installTimeoutValue = flags.installTimeout;
132
+ let installTimeout;
133
+ if (typeof installTimeoutValue === "string") {
134
+ installTimeout = Number.parseInt(installTimeoutValue, 10);
135
+ } else if (typeof installTimeoutValue === "number") {
136
+ installTimeout = installTimeoutValue;
137
+ }
138
+ const outputMode = resolveOutputModeFromContext(context.flags);
139
+ return {
140
+ targetDir,
141
+ name,
142
+ ...preset ? { preset } : {},
143
+ ...template ? { template } : {},
144
+ ...structure ? { structure } : {},
145
+ ...workspaceName ? { workspaceName } : {},
146
+ force,
147
+ ...local !== undefined ? { local } : {},
148
+ ...withBlocks ? { with: withBlocks } : {},
149
+ ...noTooling !== undefined ? { noTooling } : {},
150
+ ...bin ? { bin } : {},
151
+ ...yes ? { yes } : {},
152
+ ...dryRun ? { dryRun } : {},
153
+ ...skipInstall ? { skipInstall } : {},
154
+ ...skipGit ? { skipGit } : {},
155
+ ...skipCommit ? { skipCommit } : {},
156
+ ...installTimeout !== undefined ? { installTimeout } : {},
157
+ outputMode
158
+ };
159
+ }
160
+ function resolveScaffoldOptions(context) {
161
+ const flags = context.flags;
162
+ const outputMode = resolveOutputModeFromContext(context.flags);
163
+ const noTooling = resolveNoToolingFlag(flags);
164
+ const local = resolveLocalFlag(flags);
165
+ const installTimeoutValue = flags.installTimeout;
166
+ let installTimeout;
167
+ if (typeof installTimeoutValue === "string") {
168
+ installTimeout = Number.parseInt(installTimeoutValue, 10);
169
+ } else if (typeof installTimeoutValue === "number") {
170
+ installTimeout = installTimeoutValue;
171
+ }
172
+ return {
173
+ target: String(context.args[0] ?? ""),
174
+ name: resolveStringFlag(context.args[1]),
175
+ force: Boolean(flags.force),
176
+ skipInstall: Boolean(flags.skipInstall ?? context.flags["skip-install"]),
177
+ dryRun: Boolean(flags.dryRun ?? context.flags["dry-run"]),
178
+ ...local !== undefined ? { local } : {},
179
+ with: resolveStringFlag(flags.with),
180
+ ...noTooling !== undefined ? { noTooling } : {},
181
+ ...installTimeout !== undefined ? { installTimeout } : {},
182
+ cwd: process.cwd(),
183
+ outputMode
184
+ };
185
+ }
186
+ function resolveMigrateKitOptions(context) {
187
+ const flags = context.flags;
188
+ const outputMode = resolveOutputModeFromContext(context.flags);
189
+ return {
190
+ targetDir: context.args[0] ?? process.cwd(),
191
+ dryRun: Boolean(flags.dryRun || context.flags["dry-run"]),
192
+ outputMode
193
+ };
194
+ }
195
+ var commonInitOptions = [
196
+ {
197
+ flags: "-n, --name <name>",
198
+ description: "Package name (defaults to directory name)"
199
+ },
200
+ {
201
+ flags: "-b, --bin <name>",
202
+ description: "Binary name (defaults to project name)"
203
+ },
204
+ {
205
+ flags: "-f, --force",
206
+ description: "Overwrite existing files",
207
+ defaultValue: false
208
+ },
209
+ {
210
+ flags: "--local",
211
+ description: "Use workspace:* for @outfitter dependencies"
212
+ },
213
+ {
214
+ flags: "--workspace",
215
+ description: "Alias for --local"
216
+ },
217
+ {
218
+ flags: "--with <blocks>",
219
+ description: "Tooling to add (comma-separated: scaffolding, claude, biome, lefthook, bootstrap)"
220
+ },
221
+ {
222
+ flags: "--no-tooling",
223
+ description: "Skip tooling setup"
224
+ }
225
+ ];
226
+ var templateOption = {
227
+ flags: "-t, --template <template>",
228
+ description: "Template to use (deprecated, use --preset)"
229
+ };
230
+ function createInitAction(options) {
231
+ const presetOption = {
232
+ flags: "-p, --preset <preset>",
233
+ description: "Preset to use (minimal, cli, mcp, daemon)"
234
+ };
235
+ const initOptions = [...commonInitOptions];
236
+ initOptions.push({
237
+ flags: "-s, --structure <mode>",
238
+ description: "Project structure (single|workspace)"
239
+ });
240
+ initOptions.push({
241
+ flags: "--workspace-name <name>",
242
+ description: "Workspace root package name"
243
+ });
244
+ initOptions.push({
245
+ flags: "-y, --yes",
246
+ description: "Skip prompts and use defaults for missing values",
247
+ defaultValue: false
248
+ });
249
+ initOptions.push({
250
+ flags: "--dry-run",
251
+ description: "Preview changes without writing files",
252
+ defaultValue: false
253
+ });
254
+ initOptions.push({
255
+ flags: "--skip-install",
256
+ description: "Skip bun install",
257
+ defaultValue: false
258
+ });
259
+ initOptions.push({
260
+ flags: "--skip-git",
261
+ description: "Skip git init and initial commit",
262
+ defaultValue: false
263
+ });
264
+ initOptions.push({
265
+ flags: "--skip-commit",
266
+ description: "Skip initial commit only",
267
+ defaultValue: false
268
+ });
269
+ initOptions.push({
270
+ flags: "--install-timeout <ms>",
271
+ description: "bun install timeout in milliseconds"
272
+ });
273
+ if (options.includePresetOption) {
274
+ initOptions.push(presetOption);
275
+ }
276
+ if (options.includeTemplateOption) {
277
+ initOptions.push(templateOption);
278
+ }
279
+ return defineAction({
280
+ id: options.id,
281
+ description: options.description,
282
+ surfaces: ["cli"],
283
+ input: initInputSchema,
284
+ cli: {
285
+ group: "init",
286
+ command: options.command,
287
+ description: options.description,
288
+ options: initOptions,
289
+ mapInput: (context) => resolveInitOptions(context, options.presetOverride)
290
+ },
291
+ handler: async (input) => {
292
+ const { outputMode, ...initInput } = input;
293
+ const result = await runInit(initInput);
294
+ if (result.isErr()) {
295
+ return Result.err(new InternalError({
296
+ message: result.error.message,
297
+ context: { action: options.id }
298
+ }));
299
+ }
300
+ await printInitResults(result.value, { mode: outputMode });
301
+ return Result.ok(result.value);
302
+ }
303
+ });
304
+ }
305
+ var createAction = defineAction({
306
+ id: "create",
307
+ description: "Removed - use 'outfitter init' instead",
308
+ surfaces: ["cli"],
309
+ input: z.object({}).passthrough(),
310
+ cli: {
311
+ command: "create [directory]",
312
+ description: "Removed - use 'outfitter init' instead",
313
+ options: [],
314
+ mapInput: () => ({})
315
+ },
316
+ handler: async () => Result.err(new InternalError({
317
+ message: [
318
+ "The 'create' command has been removed.",
319
+ "",
320
+ "Use 'outfitter init' instead. It supports everything 'create' did:",
321
+ "",
322
+ " Interactive mode: outfitter init my-project",
323
+ " With preset: outfitter init my-project --preset cli",
324
+ " Skip prompts: outfitter init my-project --preset cli --yes",
325
+ " Workspace: outfitter init my-project --preset cli --structure workspace",
326
+ "",
327
+ "See 'outfitter init --help' for full options."
328
+ ].join("\\n"),
329
+ context: { action: "create" }
330
+ }))
331
+ });
332
+ var scaffoldAction = defineAction({
333
+ id: "scaffold",
334
+ description: "Add a capability to an existing project",
335
+ surfaces: ["cli"],
336
+ input: scaffoldInputSchema,
337
+ cli: {
338
+ command: "scaffold <target> [name]",
339
+ description: "Add a capability (cli, mcp, daemon, lib, ...) to an existing project",
340
+ options: [
341
+ {
342
+ flags: "-f, --force",
343
+ description: "Overwrite existing files",
344
+ defaultValue: false
345
+ },
346
+ {
347
+ flags: "--skip-install",
348
+ description: "Skip bun install",
349
+ defaultValue: false
350
+ },
351
+ {
352
+ flags: "--dry-run",
353
+ description: "Preview changes without executing",
354
+ defaultValue: false
355
+ },
356
+ {
357
+ flags: "--with <blocks>",
358
+ description: "Comma-separated tooling blocks to add"
359
+ },
360
+ {
361
+ flags: "--no-tooling",
362
+ description: "Skip default tooling blocks"
363
+ },
364
+ {
365
+ flags: "--local",
366
+ description: "Use workspace:* for @outfitter dependencies"
367
+ },
368
+ {
369
+ flags: "--install-timeout <ms>",
370
+ description: "bun install timeout in milliseconds"
371
+ }
372
+ ],
373
+ mapInput: resolveScaffoldOptions
374
+ },
375
+ handler: async (input) => {
376
+ const { outputMode, ...scaffoldInput } = input;
377
+ const result = await runScaffold(scaffoldInput);
378
+ if (result.isErr()) {
379
+ return Result.err(new InternalError({
380
+ message: result.error.message,
381
+ context: { action: "scaffold" }
382
+ }));
383
+ }
384
+ await printScaffoldResults(result.value, { mode: outputMode });
385
+ return Result.ok(result.value);
386
+ }
387
+ });
388
+ var demoInputSchema = z.object({
389
+ section: z.string().optional(),
390
+ list: z.boolean().optional(),
391
+ animate: z.boolean().optional(),
392
+ outputMode: outputModeSchema
393
+ });
394
+ var demoAction = defineAction({
395
+ id: "demo",
396
+ description: "Run the CLI demo app",
397
+ surfaces: ["cli"],
398
+ input: demoInputSchema,
399
+ cli: {
400
+ command: "demo [section]",
401
+ description: "Run the CLI demo app",
402
+ options: [
403
+ {
404
+ flags: "-l, --list",
405
+ description: "List available demo sections",
406
+ defaultValue: false
407
+ },
408
+ {
409
+ flags: "-a, --animate",
410
+ description: "Run animated demo (spinners only)",
411
+ defaultValue: false
412
+ }
413
+ ],
414
+ mapInput: (context) => {
415
+ const outputMode = resolveOutputModeFromContext(context.flags);
416
+ return {
417
+ section: context.args[0],
418
+ list: Boolean(context.flags["list"]),
419
+ animate: Boolean(context.flags["animate"]),
420
+ outputMode
421
+ };
422
+ }
423
+ },
424
+ handler: async (input) => {
425
+ const { outputMode, ...demoInput } = input;
426
+ try {
427
+ const result = await runDemo({ ...demoInput, outputMode });
428
+ if (result.exitCode !== 0) {
429
+ process.exit(result.exitCode);
430
+ }
431
+ return Result.ok(result);
432
+ } catch (error) {
433
+ return Result.err(new InternalError({
434
+ message: error instanceof Error ? error.message : "Failed to run demo",
435
+ context: { action: "demo" }
436
+ }));
437
+ }
438
+ }
439
+ });
440
+ var doctorAction = defineAction({
441
+ id: "doctor",
442
+ description: "Validate environment and dependencies",
443
+ surfaces: ["cli"],
444
+ input: doctorInputSchema,
445
+ cli: {
446
+ command: "doctor",
447
+ description: "Validate environment and dependencies",
448
+ mapInput: (context) => {
449
+ const outputMode = resolveOutputModeFromContext(context.flags);
450
+ return {
451
+ cwd: process.cwd(),
452
+ outputMode
453
+ };
454
+ }
455
+ },
456
+ handler: async (input) => {
457
+ const { outputMode, ...doctorInput } = input;
458
+ const result = await runDoctor(doctorInput);
459
+ await printDoctorResults(result, { mode: outputMode });
460
+ if (result.exitCode !== 0) {
461
+ process.exit(result.exitCode);
462
+ }
463
+ return Result.ok(result);
464
+ }
465
+ });
466
+ var addInputSchema = z.object({
467
+ block: z.string(),
468
+ force: z.boolean(),
469
+ dryRun: z.boolean(),
470
+ cwd: z.string().optional(),
471
+ outputMode: outputModeSchema
472
+ });
473
+ var addAction = defineAction({
474
+ id: "add",
475
+ description: "Add a block from the registry to your project",
476
+ surfaces: ["cli"],
477
+ input: addInputSchema,
478
+ cli: {
479
+ group: "add",
480
+ command: "<block>",
481
+ description: "Add a block from the registry (claude, biome, lefthook, bootstrap, scaffolding)",
482
+ options: [
483
+ {
484
+ flags: "-f, --force",
485
+ description: "Overwrite existing files",
486
+ defaultValue: false
487
+ },
488
+ {
489
+ flags: "--dry-run",
490
+ description: "Show what would be added without making changes",
491
+ defaultValue: false
492
+ }
493
+ ],
494
+ mapInput: (context) => {
495
+ const outputMode = resolveOutputModeFromContext(context.flags);
496
+ return {
497
+ block: context.args[0],
498
+ force: Boolean(context.flags["force"]),
499
+ dryRun: Boolean(context.flags["dry-run"] ?? context.flags["dryRun"]),
500
+ cwd: process.cwd(),
501
+ outputMode
502
+ };
503
+ }
504
+ },
505
+ handler: async (input) => {
506
+ const { outputMode, ...addInput } = input;
507
+ const result = await runAdd(addInput);
508
+ if (result.isErr()) {
509
+ return Result.err(new InternalError({
510
+ message: result.error.message,
511
+ context: { action: "add" }
512
+ }));
513
+ }
514
+ await printAddResults(result.value, addInput.dryRun, { mode: outputMode });
515
+ return Result.ok(result.value);
516
+ }
517
+ });
518
+ var listBlocksAction = defineAction({
519
+ id: "add.list",
520
+ description: "List available blocks",
521
+ surfaces: ["cli"],
522
+ input: z.object({ outputMode: outputModeSchema }),
523
+ cli: {
524
+ group: "add",
525
+ command: "list",
526
+ description: "List available blocks",
527
+ mapInput: (context) => {
528
+ const outputMode = resolveOutputModeFromContext(context.flags);
529
+ return {
530
+ outputMode
531
+ };
532
+ }
533
+ },
534
+ handler: async (input) => {
535
+ const result = listBlocks();
536
+ if (result.isErr()) {
537
+ return Result.err(new InternalError({
538
+ message: result.error.message,
539
+ context: { action: "add.list" }
540
+ }));
541
+ }
542
+ const structuredMode = resolveStructuredOutputMode(input.outputMode);
543
+ if (structuredMode) {
544
+ await output({ blocks: result.value }, { mode: structuredMode });
545
+ } else {
546
+ const lines = [
547
+ "Available blocks:",
548
+ ...result.value.map((block) => ` - ${block}`)
549
+ ];
550
+ await output(lines, { mode: "human" });
551
+ }
552
+ return Result.ok({ blocks: result.value });
553
+ }
554
+ });
555
+ var checkInputSchema = z.object({
556
+ cwd: z.string(),
557
+ verbose: z.boolean(),
558
+ block: z.string().optional(),
559
+ ci: z.boolean(),
560
+ outputMode: outputModeSchema
561
+ });
562
+ var checkAction = defineAction({
563
+ id: "check",
564
+ description: "Compare local config blocks against the registry for drift detection",
565
+ surfaces: ["cli"],
566
+ input: checkInputSchema,
567
+ cli: {
568
+ command: "check",
569
+ description: "Compare local config blocks against the registry for drift detection",
570
+ options: [
571
+ {
572
+ flags: "-v, --verbose",
573
+ description: "Show diffs for drifted files",
574
+ defaultValue: false
575
+ },
576
+ {
577
+ flags: "-b, --block <name>",
578
+ description: "Check a specific block only"
579
+ },
580
+ {
581
+ flags: "--ci",
582
+ description: "Machine-oriented output for CI",
583
+ defaultValue: false
584
+ },
585
+ {
586
+ flags: "--cwd <path>",
587
+ description: "Working directory (defaults to current directory)"
588
+ }
589
+ ],
590
+ mapInput: (context) => {
591
+ const outputMode = resolveOutputModeFromContext(context.flags);
592
+ const cwd = typeof context.flags["cwd"] === "string" ? resolve(process.cwd(), context.flags["cwd"]) : process.cwd();
593
+ const block = resolveStringFlag(context.flags["block"]);
594
+ return {
595
+ cwd,
596
+ verbose: Boolean(context.flags["verbose"]),
597
+ ...block !== undefined ? { block } : {},
598
+ ci: Boolean(context.flags["ci"]),
599
+ outputMode
600
+ };
601
+ }
602
+ },
603
+ handler: async (input) => {
604
+ const { outputMode, ci, ...checkInput } = input;
605
+ const effectiveMode = ci ? "json" : outputMode;
606
+ const result = await runCheck(checkInput);
607
+ if (result.isErr()) {
608
+ return Result.err(new InternalError({
609
+ message: result.error.message,
610
+ context: { action: "check" }
611
+ }));
612
+ }
613
+ await printCheckResults(result.value, {
614
+ mode: effectiveMode,
615
+ verbose: checkInput.verbose
616
+ });
617
+ if (result.value.driftedCount > 0 || result.value.missingCount > 0) {
618
+ process.exit(1);
619
+ }
620
+ return Result.ok(result.value);
621
+ }
622
+ });
623
+ var updateInputSchema = z.object({
624
+ cwd: z.string(),
625
+ guide: z.boolean(),
626
+ guidePackages: z.array(z.string()).optional(),
627
+ apply: z.boolean(),
628
+ breaking: z.boolean(),
629
+ outputMode: outputModeSchema
630
+ });
631
+ var updateAction = defineAction({
632
+ id: "update",
633
+ description: "Check for @outfitter/* package updates and migration guidance",
634
+ surfaces: ["cli"],
635
+ input: updateInputSchema,
636
+ cli: {
637
+ command: "update [packages...]",
638
+ description: "Check for @outfitter/* package updates and migration guidance",
639
+ options: [
640
+ {
641
+ flags: "--guide",
642
+ description: "Show migration instructions for available updates. Pass package names to filter.",
643
+ defaultValue: false
644
+ },
645
+ {
646
+ flags: "--apply",
647
+ description: "Apply non-breaking updates to package.json and run bun install",
648
+ defaultValue: false
649
+ },
650
+ {
651
+ flags: "--breaking",
652
+ description: "Include breaking updates when used with --apply",
653
+ defaultValue: false
654
+ },
655
+ {
656
+ flags: "--cwd <path>",
657
+ description: "Working directory (defaults to current directory)"
658
+ }
659
+ ],
660
+ mapInput: (context) => {
661
+ const outputMode = resolveOutputModeFromContext(context.flags);
662
+ const cwd = typeof context.flags["cwd"] === "string" ? resolve(process.cwd(), context.flags["cwd"]) : process.cwd();
663
+ const guidePackages = context.args.length > 0 ? context.args : undefined;
664
+ return {
665
+ cwd,
666
+ guide: Boolean(context.flags["guide"]),
667
+ ...guidePackages !== undefined ? { guidePackages } : {},
668
+ apply: Boolean(context.flags["apply"]),
669
+ breaking: Boolean(context.flags["breaking"]),
670
+ outputMode
671
+ };
672
+ }
673
+ },
674
+ handler: async (input) => {
675
+ const { outputMode, guidePackages, ...updateInput } = input;
676
+ const result = await runUpdate({
677
+ ...updateInput,
678
+ ...guidePackages !== undefined ? { guidePackages } : {}
679
+ });
680
+ if (result.isErr()) {
681
+ return Result.err(new InternalError({
682
+ message: result.error.message,
683
+ context: { action: "update" }
684
+ }));
685
+ }
686
+ await printUpdateResults(result.value, {
687
+ mode: outputMode,
688
+ guide: updateInput.guide,
689
+ cwd: updateInput.cwd,
690
+ applied: updateInput.apply ? result.value.applied : undefined,
691
+ breaking: updateInput.breaking
692
+ });
693
+ return Result.ok(result.value);
694
+ }
695
+ });
696
+ var migrateKitAction = defineAction({
697
+ id: "migrate.kit",
698
+ description: "Migrate foundation imports and dependencies to @outfitter/kit",
699
+ surfaces: ["cli"],
700
+ input: migrateKitInputSchema,
701
+ cli: {
702
+ group: "migrate",
703
+ command: "kit [directory]",
704
+ description: "Migrate foundation imports and dependencies to @outfitter/kit",
705
+ options: [
706
+ {
707
+ flags: "--dry-run",
708
+ description: "Preview changes without writing files",
709
+ defaultValue: false
710
+ }
711
+ ],
712
+ mapInput: resolveMigrateKitOptions
713
+ },
714
+ handler: async (input) => {
715
+ const { outputMode, ...migrateInput } = input;
716
+ const result = await runMigrateKit(migrateInput);
717
+ if (result.isErr()) {
718
+ return Result.err(new InternalError({
719
+ message: result.error.message,
720
+ context: { action: "migrate.kit" }
721
+ }));
722
+ }
723
+ await printMigrateKitResults(result.value, { mode: outputMode });
724
+ return Result.ok(result.value);
725
+ }
726
+ });
727
+ var outfitterActions = createActionRegistry().add(createAction).add(scaffoldAction).add(createInitAction({
728
+ id: "init",
729
+ description: "Create a new Outfitter project",
730
+ command: "[directory]",
731
+ includePresetOption: true,
732
+ includeTemplateOption: true
733
+ })).add(createInitAction({
734
+ id: "init.cli",
735
+ description: "Create a new CLI project",
736
+ command: "cli [directory]",
737
+ presetOverride: "cli"
738
+ })).add(createInitAction({
739
+ id: "init.mcp",
740
+ description: "Create a new MCP server",
741
+ command: "mcp [directory]",
742
+ presetOverride: "mcp"
743
+ })).add(createInitAction({
744
+ id: "init.daemon",
745
+ description: "Create a new daemon project",
746
+ command: "daemon [directory]",
747
+ presetOverride: "daemon"
748
+ })).add(demoAction).add(doctorAction).add(addAction).add(listBlocksAction).add(checkAction).add(migrateKitAction).add(updateAction);
749
+
750
+ export { outfitterActions };