outfitter 0.2.3 → 0.2.4

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 (129) hide show
  1. package/dist/cli.js +2 -2
  2. package/dist/index.js +1 -1
  3. package/dist/shared/{chunk-b0y0cwkr.js → chunk-tpwtpa74.js} +20 -21
  4. package/package.json +3 -3
  5. package/templates/cli/package.json.template +1 -1
  6. package/templates/cli/src/program.ts.template +11 -3
  7. package/dist/actions.d.ts +0 -2
  8. package/dist/actions.js +0 -34
  9. package/dist/commands/add.d.ts +0 -54
  10. package/dist/commands/add.js +0 -16
  11. package/dist/commands/check.d.ts +0 -91
  12. package/dist/commands/check.js +0 -14
  13. package/dist/commands/demo.d.ts +0 -21
  14. package/dist/commands/demo.js +0 -8
  15. package/dist/commands/docs-module-loader.d.ts +0 -2
  16. package/dist/commands/docs-module-loader.js +0 -8
  17. package/dist/commands/doctor.d.ts +0 -2
  18. package/dist/commands/doctor.js +0 -13
  19. package/dist/commands/init.d.ts +0 -7
  20. package/dist/commands/init.js +0 -31
  21. package/dist/commands/migrate-kit.d.ts +0 -2
  22. package/dist/commands/migrate-kit.js +0 -15
  23. package/dist/commands/repo.d.ts +0 -3
  24. package/dist/commands/repo.js +0 -9
  25. package/dist/commands/scaffold.d.ts +0 -4
  26. package/dist/commands/scaffold.js +0 -31
  27. package/dist/commands/shared-deps.d.ts +0 -36
  28. package/dist/commands/shared-deps.js +0 -10
  29. package/dist/commands/update-planner.d.ts +0 -58
  30. package/dist/commands/update-planner.js +0 -8
  31. package/dist/commands/update-workspace.d.ts +0 -76
  32. package/dist/commands/update-workspace.js +0 -16
  33. package/dist/commands/update.d.ts +0 -113
  34. package/dist/commands/update.js +0 -21
  35. package/dist/create/index.d.ts +0 -5
  36. package/dist/create/index.js +0 -29
  37. package/dist/create/planner.d.ts +0 -3
  38. package/dist/create/planner.js +0 -21
  39. package/dist/create/presets.d.ts +0 -3
  40. package/dist/create/presets.js +0 -12
  41. package/dist/create/types.d.ts +0 -2
  42. package/dist/create/types.js +0 -1
  43. package/dist/engine/blocks.d.ts +0 -3
  44. package/dist/engine/blocks.js +0 -12
  45. package/dist/engine/collector.d.ts +0 -2
  46. package/dist/engine/collector.js +0 -8
  47. package/dist/engine/config.d.ts +0 -3
  48. package/dist/engine/config.js +0 -12
  49. package/dist/engine/executor.d.ts +0 -3
  50. package/dist/engine/executor.js +0 -16
  51. package/dist/engine/index.d.ts +0 -8
  52. package/dist/engine/index.js +0 -59
  53. package/dist/engine/names.d.ts +0 -2
  54. package/dist/engine/names.js +0 -16
  55. package/dist/engine/post-scaffold.d.ts +0 -3
  56. package/dist/engine/post-scaffold.js +0 -8
  57. package/dist/engine/render-plan.d.ts +0 -7
  58. package/dist/engine/render-plan.js +0 -9
  59. package/dist/engine/template.d.ts +0 -3
  60. package/dist/engine/template.js +0 -17
  61. package/dist/engine/types.d.ts +0 -2
  62. package/dist/engine/types.js +0 -8
  63. package/dist/engine/workspace.d.ts +0 -3
  64. package/dist/engine/workspace.js +0 -13
  65. package/dist/manifest.d.ts +0 -71
  66. package/dist/manifest.js +0 -16
  67. package/dist/output-mode.d.ts +0 -2
  68. package/dist/output-mode.js +0 -10
  69. package/dist/shared/outfitter-193jvzg4.d.ts +0 -5
  70. package/dist/shared/outfitter-1dd0k853.js +0 -194
  71. package/dist/shared/outfitter-1h7k8xxt.js +0 -29
  72. package/dist/shared/outfitter-1qwpjt6w.js +0 -125
  73. package/dist/shared/outfitter-2ngep1h2.d.ts +0 -5
  74. package/dist/shared/outfitter-2np85etz.js +0 -95
  75. package/dist/shared/outfitter-33w361tc.d.ts +0 -18
  76. package/dist/shared/outfitter-344t1r38.js +0 -1
  77. package/dist/shared/outfitter-3weh61w7.d.ts +0 -25
  78. package/dist/shared/outfitter-4s9meh3j.js +0 -221
  79. package/dist/shared/outfitter-6a4bq054.js +0 -322
  80. package/dist/shared/outfitter-6bkqjk86.d.ts +0 -3
  81. package/dist/shared/outfitter-6gc3g5wk.js +0 -98
  82. package/dist/shared/outfitter-7cv5fg1m.js +0 -61
  83. package/dist/shared/outfitter-7ha7p61k.d.ts +0 -6
  84. package/dist/shared/outfitter-7r12fj7f.js +0 -30
  85. package/dist/shared/outfitter-8y2dfx6n.js +0 -11
  86. package/dist/shared/outfitter-9c8edfsn.js +0 -715
  87. package/dist/shared/outfitter-9x1brcmq.js +0 -184
  88. package/dist/shared/outfitter-a79xrm12.d.ts +0 -17
  89. package/dist/shared/outfitter-amc4jbs1.d.ts +0 -50
  90. package/dist/shared/outfitter-ara3djt0.js +0 -73
  91. package/dist/shared/outfitter-avhm5z6w.js +0 -82
  92. package/dist/shared/outfitter-b5nd42y4.d.ts +0 -45
  93. package/dist/shared/outfitter-dd0btgec.d.ts +0 -40
  94. package/dist/shared/outfitter-e2zz5wv7.d.ts +0 -51
  95. package/dist/shared/outfitter-ehp18x1n.js +0 -1
  96. package/dist/shared/outfitter-fnsmx3xg.js +0 -750
  97. package/dist/shared/outfitter-gdvm5c0b.d.ts +0 -4
  98. package/dist/shared/outfitter-gp4v5gkf.js +0 -322
  99. package/dist/shared/outfitter-h1mnzzd1.d.ts +0 -14
  100. package/dist/shared/outfitter-hpymx4m9.js +0 -184
  101. package/dist/shared/outfitter-hvsaxgcp.js +0 -1
  102. package/dist/shared/outfitter-j8yc7294.d.ts +0 -22
  103. package/dist/shared/outfitter-jyxwznk1.js +0 -404
  104. package/dist/shared/outfitter-k112c427.js +0 -21
  105. package/dist/shared/outfitter-k56rmt24.d.ts +0 -30
  106. package/dist/shared/outfitter-ksa1pp4t.d.ts +0 -4
  107. package/dist/shared/outfitter-mdt37hqm.js +0 -4
  108. package/dist/shared/outfitter-mtbpabf3.js +0 -91
  109. package/dist/shared/outfitter-nm4m0v6x.d.ts +0 -131
  110. package/dist/shared/outfitter-nmeecf1b.js +0 -531
  111. package/dist/shared/outfitter-npyfbdmc.d.ts +0 -6
  112. package/dist/shared/outfitter-pxt58tsq.js +0 -582
  113. package/dist/shared/outfitter-q9agarmb.js +0 -42
  114. package/dist/shared/outfitter-qfgj5xpq.js +0 -70
  115. package/dist/shared/outfitter-qfh36ddg.d.ts +0 -66
  116. package/dist/shared/outfitter-s6k8y2p4.js +0 -269
  117. package/dist/shared/outfitter-sftf1s26.js +0 -199
  118. package/dist/shared/outfitter-sg7ncy4a.d.ts +0 -51
  119. package/dist/shared/outfitter-sgtq57qr.d.ts +0 -5
  120. package/dist/shared/outfitter-txre6cdn.d.ts +0 -60
  121. package/dist/shared/outfitter-vh4xgb93.js +0 -35
  122. package/dist/shared/outfitter-ya44h1km.js +0 -191
  123. package/dist/shared/outfitter-zwyvewr1.js +0 -36
  124. package/dist/targets/index.d.ts +0 -4
  125. package/dist/targets/index.js +0 -29
  126. package/dist/targets/registry.d.ts +0 -3
  127. package/dist/targets/registry.js +0 -28
  128. package/dist/targets/types.d.ts +0 -2
  129. package/dist/targets/types.js +0 -1
@@ -1,66 +0,0 @@
1
- import { AddBlockResult } from "@outfitter/tooling";
2
- /**
3
- * Unified placeholder values for template substitution.
4
- */
5
- interface PlaceholderValues {
6
- readonly name: string;
7
- readonly projectName: string;
8
- readonly packageName: string;
9
- readonly binName: string;
10
- readonly version: string;
11
- readonly description: string;
12
- readonly author: string;
13
- readonly year: string;
14
- }
15
- /**
16
- * A single change operation in a scaffold plan.
17
- */
18
- type ScaffoldChange = {
19
- readonly type: "copy-template";
20
- readonly template: string;
21
- readonly targetDir: string;
22
- readonly overlayBaseTemplate: boolean;
23
- } | {
24
- readonly type: "inject-shared-config";
25
- } | {
26
- readonly type: "rewrite-local-dependencies";
27
- readonly mode: "workspace";
28
- } | {
29
- readonly type: "add-blocks";
30
- readonly blocks: readonly string[];
31
- };
32
- /**
33
- * A complete scaffold plan.
34
- */
35
- interface ScaffoldPlan {
36
- readonly values: PlaceholderValues;
37
- readonly changes: readonly ScaffoldChange[];
38
- }
39
- /**
40
- * Result of executing a scaffold plan.
41
- */
42
- interface ScaffoldResult {
43
- readonly projectDir: string;
44
- readonly blocksAdded?: AddBlockResult | undefined;
45
- }
46
- /**
47
- * Dry-run collector support.
48
- */
49
- interface EngineCollector {
50
- add(op: unknown): void;
51
- }
52
- /**
53
- * Shared options used by engine functions.
54
- */
55
- interface EngineOptions {
56
- readonly force: boolean;
57
- readonly collector?: EngineCollector | undefined;
58
- }
59
- /**
60
- * Unified error type for engine operations.
61
- */
62
- declare class ScaffoldError extends Error {
63
- readonly _tag: "ScaffoldError";
64
- constructor(message: string);
65
- }
66
- export { PlaceholderValues, ScaffoldChange, ScaffoldPlan, ScaffoldResult, EngineCollector, EngineOptions, ScaffoldError };
@@ -1,269 +0,0 @@
1
- // @bun
2
- import {
3
- stampBlock
4
- } from "./outfitter-mtbpabf3.js";
5
- import {
6
- resolveStructuredOutputMode
7
- } from "./outfitter-7r12fj7f.js";
8
-
9
- // apps/outfitter/src/commands/add.ts
10
- import {
11
- chmodSync,
12
- existsSync,
13
- mkdirSync,
14
- readFileSync,
15
- writeFileSync
16
- } from "fs";
17
- import { dirname, join, resolve } from "path";
18
- import { fileURLToPath } from "url";
19
- import { output } from "@outfitter/cli/output";
20
- import { Result } from "@outfitter/contracts";
21
- import { RegistrySchema } from "@outfitter/tooling";
22
- class AddError extends Error {
23
- _tag = "AddError";
24
- constructor(message) {
25
- super(message);
26
- this.name = "AddError";
27
- }
28
- }
29
- function getRegistryPath() {
30
- let currentDir = dirname(fileURLToPath(import.meta.url));
31
- for (let i = 0;i < 10; i++) {
32
- const registryPath = join(currentDir, "node_modules/@outfitter/tooling/registry/registry.json");
33
- if (existsSync(registryPath)) {
34
- return registryPath;
35
- }
36
- const monoRepoPath = join(currentDir, "packages/tooling/registry/registry.json");
37
- if (existsSync(monoRepoPath)) {
38
- return monoRepoPath;
39
- }
40
- currentDir = dirname(currentDir);
41
- }
42
- throw new AddError("Could not find registry.json. Ensure @outfitter/tooling is installed.");
43
- }
44
- function readToolingVersion(registryPath) {
45
- try {
46
- const toolingRoot = dirname(dirname(registryPath));
47
- const pkgPath = join(toolingRoot, "package.json");
48
- const content = readFileSync(pkgPath, "utf-8");
49
- const pkg = JSON.parse(content);
50
- return pkg.version ?? "unknown";
51
- } catch {
52
- return "unknown";
53
- }
54
- }
55
- function loadRegistry() {
56
- try {
57
- const registryPath = getRegistryPath();
58
- const content = readFileSync(registryPath, "utf-8");
59
- const parsed = JSON.parse(content);
60
- const registry = RegistrySchema.parse(parsed);
61
- const toolingVersion = readToolingVersion(registryPath);
62
- return Result.ok({ registry, toolingVersion });
63
- } catch (error) {
64
- const message = error instanceof Error ? error.message : "Unknown error";
65
- return Result.err(new AddError(`Failed to load registry: ${message}`));
66
- }
67
- }
68
- function resolveBlock(registry, blockName, visited = new Set) {
69
- if (visited.has(blockName)) {
70
- return Result.err(new AddError(`Circular dependency detected for block: ${blockName}`));
71
- }
72
- visited.add(blockName);
73
- const block = registry.blocks[blockName];
74
- if (!block) {
75
- const available = Object.keys(registry.blocks).join(", ");
76
- return Result.err(new AddError(`Block '${blockName}' not found. Available blocks: ${available}`));
77
- }
78
- if (block.extends && block.extends.length > 0) {
79
- const mergedFiles = [];
80
- const mergedDeps = {};
81
- const mergedDevDeps = {};
82
- for (const extendedName of block.extends) {
83
- const extendedResult = resolveBlock(registry, extendedName, visited);
84
- if (extendedResult.isErr()) {
85
- return extendedResult;
86
- }
87
- const extended = extendedResult.value;
88
- if (extended.files) {
89
- mergedFiles.push(...extended.files);
90
- }
91
- if (extended.dependencies) {
92
- Object.assign(mergedDeps, extended.dependencies);
93
- }
94
- if (extended.devDependencies) {
95
- Object.assign(mergedDevDeps, extended.devDependencies);
96
- }
97
- }
98
- if (block.files) {
99
- mergedFiles.push(...block.files);
100
- }
101
- if (block.dependencies) {
102
- Object.assign(mergedDeps, block.dependencies);
103
- }
104
- if (block.devDependencies) {
105
- Object.assign(mergedDevDeps, block.devDependencies);
106
- }
107
- return Result.ok({
108
- name: block.name,
109
- description: block.description,
110
- files: mergedFiles.length > 0 ? mergedFiles : undefined,
111
- dependencies: Object.keys(mergedDeps).length > 0 ? mergedDeps : undefined,
112
- devDependencies: Object.keys(mergedDevDeps).length > 0 ? mergedDevDeps : undefined
113
- });
114
- }
115
- return Result.ok(block);
116
- }
117
- function writeFile(filePath, content, executable) {
118
- const dir = dirname(filePath);
119
- if (!existsSync(dir)) {
120
- mkdirSync(dir, { recursive: true });
121
- }
122
- writeFileSync(filePath, content, "utf-8");
123
- if (executable) {
124
- chmodSync(filePath, 493);
125
- }
126
- }
127
- function updatePackageJson(cwd, dependencies, devDependencies, dryRun) {
128
- const packageJsonPath = join(cwd, "package.json");
129
- if (!existsSync(packageJsonPath)) {
130
- return { dependencies, devDependencies };
131
- }
132
- const content = readFileSync(packageJsonPath, "utf-8");
133
- const pkg = JSON.parse(content);
134
- const existingDeps = pkg["dependencies"] ?? {};
135
- const existingDevDeps = pkg["devDependencies"] ?? {};
136
- const addedDeps = {};
137
- const addedDevDeps = {};
138
- for (const [name, version] of Object.entries(dependencies)) {
139
- if (!existingDeps[name]) {
140
- existingDeps[name] = version;
141
- addedDeps[name] = version;
142
- }
143
- }
144
- for (const [name, version] of Object.entries(devDependencies)) {
145
- if (!(existingDevDeps[name] || existingDeps[name])) {
146
- existingDevDeps[name] = version;
147
- addedDevDeps[name] = version;
148
- }
149
- }
150
- if (!dryRun && (Object.keys(addedDeps).length > 0 || Object.keys(addedDevDeps).length > 0)) {
151
- if (Object.keys(existingDeps).length > 0) {
152
- pkg["dependencies"] = existingDeps;
153
- }
154
- if (Object.keys(existingDevDeps).length > 0) {
155
- pkg["devDependencies"] = existingDevDeps;
156
- }
157
- writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}
158
- `);
159
- }
160
- return { dependencies: addedDeps, devDependencies: addedDevDeps };
161
- }
162
- async function runAdd(input) {
163
- const { block: blockName, force, dryRun, cwd = process.cwd() } = input;
164
- const resolvedCwd = resolve(cwd);
165
- const registryResult = loadRegistry();
166
- if (registryResult.isErr()) {
167
- return registryResult;
168
- }
169
- const { registry, toolingVersion } = registryResult.value;
170
- const blockResult = resolveBlock(registry, blockName);
171
- if (blockResult.isErr()) {
172
- return blockResult;
173
- }
174
- const block = blockResult.value;
175
- const created = [];
176
- const skipped = [];
177
- const overwritten = [];
178
- if (block.files) {
179
- for (const file of block.files) {
180
- const targetPath = join(resolvedCwd, file.path);
181
- const fileExists = existsSync(targetPath);
182
- if (fileExists && !force) {
183
- skipped.push(file.path);
184
- continue;
185
- }
186
- if (!dryRun) {
187
- writeFile(targetPath, file.content, file.executable ?? false);
188
- }
189
- if (fileExists) {
190
- overwritten.push(file.path);
191
- } else {
192
- created.push(file.path);
193
- }
194
- }
195
- }
196
- const { dependencies, devDependencies } = updatePackageJson(resolvedCwd, block.dependencies ?? {}, block.devDependencies ?? {}, dryRun);
197
- if (!dryRun) {
198
- const stampResult = await stampBlock(resolvedCwd, blockName, toolingVersion);
199
- if (stampResult.isErr()) {
200
- process.stderr.write(`Warning: failed to stamp manifest: ${stampResult.error.message}
201
- `);
202
- }
203
- }
204
- return Result.ok({
205
- created,
206
- skipped,
207
- overwritten,
208
- dependencies,
209
- devDependencies
210
- });
211
- }
212
- async function printAddResults(result, dryRun, options) {
213
- const structuredMode = resolveStructuredOutputMode(options?.mode);
214
- if (structuredMode) {
215
- await output({
216
- dryRun,
217
- created: result.created,
218
- overwritten: result.overwritten,
219
- skipped: result.skipped,
220
- dependencies: result.dependencies,
221
- devDependencies: result.devDependencies
222
- }, { mode: structuredMode });
223
- return;
224
- }
225
- const lines = [];
226
- const prefix = dryRun ? "[dry-run] Would " : "";
227
- if (result.created.length > 0) {
228
- lines.push(`${prefix}create ${result.created.length} file(s):`);
229
- for (const file of result.created) {
230
- lines.push(` \u2713 ${file}`);
231
- }
232
- }
233
- if (result.overwritten.length > 0) {
234
- lines.push(`${prefix}overwrite ${result.overwritten.length} file(s):`);
235
- for (const file of result.overwritten) {
236
- lines.push(` \u2713 ${file}`);
237
- }
238
- }
239
- if (result.skipped.length > 0) {
240
- lines.push(`Skipped ${result.skipped.length} existing file(s):`);
241
- for (const file of result.skipped) {
242
- lines.push(` - ${file} (use --force to overwrite)`);
243
- }
244
- }
245
- const depCount = Object.keys(result.dependencies).length + Object.keys(result.devDependencies).length;
246
- if (depCount > 0) {
247
- lines.push("", `${prefix}add ${depCount} package(s) to package.json:`);
248
- for (const [name, version] of Object.entries(result.dependencies)) {
249
- lines.push(` + ${name}@${version}`);
250
- }
251
- for (const [name, version] of Object.entries(result.devDependencies)) {
252
- lines.push(` + ${name}@${version} (dev)`);
253
- }
254
- if (!dryRun) {
255
- lines.push("", "Run `bun install` to install new dependencies.");
256
- }
257
- }
258
- await output(lines, { mode: "human" });
259
- }
260
- function listBlocks() {
261
- const registryResult = loadRegistry();
262
- if (registryResult.isErr()) {
263
- return registryResult;
264
- }
265
- const blocks = Object.keys(registryResult.value.registry.blocks);
266
- return Result.ok(blocks);
267
- }
268
-
269
- export { AddError, runAdd, printAddResults, listBlocks };
@@ -1,199 +0,0 @@
1
- // @bun
2
- import {
3
- resolveStructuredOutputMode
4
- } from "./outfitter-7r12fj7f.js";
5
-
6
- // apps/outfitter/src/commands/doctor.ts
7
- import { existsSync, readFileSync } from "fs";
8
- import { join, resolve } from "path";
9
- import { output } from "@outfitter/cli/output";
10
- import { createTheme } from "@outfitter/tui/render";
11
- var MIN_BUN_VERSION = "1.3.6";
12
- function checkBunVersion() {
13
- const required = MIN_BUN_VERSION;
14
- const current = Bun.version;
15
- const passed = Bun.semver.satisfies(current, `>=${required}`);
16
- return {
17
- passed,
18
- version: current,
19
- required,
20
- ...passed ? {} : {
21
- error: `Bun version ${current} is below minimum required ${required}`
22
- }
23
- };
24
- }
25
- function checkPackageJson(cwd) {
26
- const packageJsonPath = join(cwd, "package.json");
27
- if (!existsSync(packageJsonPath)) {
28
- return {
29
- passed: false,
30
- error: "package.json not found in current directory"
31
- };
32
- }
33
- try {
34
- const content = readFileSync(packageJsonPath, "utf-8");
35
- const parsed = JSON.parse(content);
36
- if (typeof parsed["name"] !== "string" || parsed["name"].length === 0) {
37
- return {
38
- passed: false,
39
- error: "package.json is missing required 'name' field"
40
- };
41
- }
42
- if (typeof parsed["version"] !== "string" || parsed["version"].length === 0) {
43
- return {
44
- passed: false,
45
- error: "package.json is missing required 'version' field"
46
- };
47
- }
48
- return {
49
- passed: true,
50
- name: parsed["name"],
51
- version: parsed["version"]
52
- };
53
- } catch (error) {
54
- const message = error instanceof Error ? error.message : "Unknown error";
55
- return {
56
- passed: false,
57
- error: `package.json is invalid JSON: ${message}`
58
- };
59
- }
60
- }
61
- function checkDependencies(cwd) {
62
- const packageJsonPath = join(cwd, "package.json");
63
- if (!existsSync(packageJsonPath)) {
64
- return { passed: true, count: 0 };
65
- }
66
- try {
67
- const content = readFileSync(packageJsonPath, "utf-8");
68
- const parsed = JSON.parse(content);
69
- const dependencies = parsed["dependencies"];
70
- const devDependencies = parsed["devDependencies"];
71
- const allDeps = [
72
- ...Object.keys(dependencies ?? {}),
73
- ...Object.keys(devDependencies ?? {})
74
- ];
75
- if (allDeps.length === 0) {
76
- return { passed: true, count: 0 };
77
- }
78
- const nodeModulesPath = join(cwd, "node_modules");
79
- if (!existsSync(nodeModulesPath)) {
80
- return {
81
- passed: false,
82
- count: allDeps.length,
83
- error: "node_modules not found. Run 'bun install' to install dependencies."
84
- };
85
- }
86
- const missing = [];
87
- for (const dep of allDeps) {
88
- const depPath = join(nodeModulesPath, dep);
89
- if (!existsSync(depPath)) {
90
- missing.push(dep);
91
- }
92
- }
93
- if (missing.length > 0) {
94
- return {
95
- passed: false,
96
- count: allDeps.length,
97
- missing,
98
- error: `Missing dependencies: ${missing.join(", ")}. Run 'bun install' to install.`
99
- };
100
- }
101
- return { passed: true, count: allDeps.length };
102
- } catch {
103
- return { passed: true, count: 0 };
104
- }
105
- }
106
- function checkConfigFiles(cwd) {
107
- return {
108
- tsconfig: existsSync(join(cwd, "tsconfig.json")),
109
- biome: existsSync(join(cwd, "biome.json"))
110
- };
111
- }
112
- function checkDirectories(cwd) {
113
- return {
114
- src: existsSync(join(cwd, "src")),
115
- tests: existsSync(join(cwd, "src", "__tests__")) || existsSync(join(cwd, "tests"))
116
- };
117
- }
118
- function runDoctor(options) {
119
- const cwd = resolve(options.cwd);
120
- const bunVersion = checkBunVersion();
121
- const packageJson = checkPackageJson(cwd);
122
- const dependencies = checkDependencies(cwd);
123
- const configFiles = checkConfigFiles(cwd);
124
- const directories = checkDirectories(cwd);
125
- const checkResults = [
126
- bunVersion.passed,
127
- packageJson.passed,
128
- dependencies.passed,
129
- configFiles.tsconfig,
130
- directories.src
131
- ];
132
- const passed = checkResults.filter(Boolean).length;
133
- const failed = checkResults.length - passed;
134
- const total = checkResults.length;
135
- return {
136
- checks: {
137
- bunVersion,
138
- packageJson,
139
- dependencies,
140
- configFiles,
141
- directories
142
- },
143
- summary: { passed, failed, total },
144
- exitCode: failed > 0 ? 1 : 0
145
- };
146
- }
147
- async function printDoctorResults(result, options) {
148
- const structuredMode = resolveStructuredOutputMode(options?.mode);
149
- if (structuredMode) {
150
- await output(result, { mode: structuredMode });
151
- return;
152
- }
153
- const theme = createTheme();
154
- const lines = ["", "Outfitter Doctor", "", "=".repeat(50)];
155
- const bunIcon = result.checks.bunVersion.passed ? theme.success("[PASS]") : theme.error("[FAIL]");
156
- lines.push(`${bunIcon} Bun Version: ${result.checks.bunVersion.version} (requires ${result.checks.bunVersion.required})`);
157
- if (result.checks.bunVersion.error) {
158
- lines.push(` ${theme.muted(result.checks.bunVersion.error)}`);
159
- }
160
- const pkgIcon = result.checks.packageJson.passed ? theme.success("[PASS]") : theme.error("[FAIL]");
161
- lines.push(`${pkgIcon} package.json`);
162
- if (result.checks.packageJson.error) {
163
- lines.push(` ${theme.muted(result.checks.packageJson.error)}`);
164
- } else if (result.checks.packageJson.name) {
165
- lines.push(` ${theme.muted(`${result.checks.packageJson.name}@${result.checks.packageJson.version}`)}`);
166
- }
167
- const depsIcon = result.checks.dependencies.passed ? theme.success("[PASS]") : theme.error("[FAIL]");
168
- lines.push(`${depsIcon} Dependencies`);
169
- if (result.checks.dependencies.error) {
170
- lines.push(` ${theme.muted(result.checks.dependencies.error)}`);
171
- } else if (result.checks.dependencies.count !== undefined) {
172
- lines.push(` ${theme.muted(`${result.checks.dependencies.count} dependencies installed`)}`);
173
- }
174
- const tsconfigIcon = result.checks.configFiles.tsconfig ? theme.success("[PASS]") : theme.warning("[WARN]");
175
- lines.push(`${tsconfigIcon} tsconfig.json`);
176
- const srcIcon = result.checks.directories.src ? theme.success("[PASS]") : theme.warning("[WARN]");
177
- lines.push(`${srcIcon} src/ directory`);
178
- lines.push("", "=".repeat(50));
179
- const summaryColor = result.exitCode === 0 ? theme.success : theme.error;
180
- lines.push(summaryColor(`${result.summary.passed}/${result.summary.total} checks passed`));
181
- if (result.exitCode !== 0) {
182
- lines.push("", theme.muted("Run 'outfitter doctor' after fixing issues to verify."));
183
- }
184
- await output(lines, { mode: "human" });
185
- }
186
- function doctorCommand(program) {
187
- program.command("doctor").description("Validate environment and dependencies").option("--json", "Output as JSON", false).action(async (_flags, command) => {
188
- const resolvedFlags = command.optsWithGlobals();
189
- const outputOptions = resolvedFlags.json ? { mode: "json" } : undefined;
190
- if (resolvedFlags.json) {
191
- process.env["OUTFITTER_JSON"] = "1";
192
- }
193
- const result = await runDoctor({ cwd: process.cwd() });
194
- await printDoctorResults(result, outputOptions);
195
- process.exit(result.exitCode);
196
- });
197
- }
198
-
199
- export { runDoctor, printDoctorResults, doctorCommand };
@@ -1,51 +0,0 @@
1
- import { OutputMode } from "@outfitter/cli/types";
2
- import { Result } from "@outfitter/contracts";
3
- import { Command } from "commander";
4
- interface DiffPreview {
5
- readonly path: string;
6
- readonly preview: string;
7
- }
8
- /**
9
- * Options for the migrate-kit command.
10
- */
11
- interface MigrateKitOptions {
12
- /** Target directory to migrate (defaults to cwd). */
13
- readonly targetDir?: string | undefined;
14
- /** Run codemod without writing changes to disk. */
15
- readonly dryRun?: boolean | undefined;
16
- }
17
- /**
18
- * Result from migrate-kit execution.
19
- */
20
- interface MigrateKitResult {
21
- readonly targetDir: string;
22
- readonly dryRun: boolean;
23
- readonly packageJsonFiles: number;
24
- readonly sourceFiles: number;
25
- readonly manifestUpdates: number;
26
- readonly importRewrites: number;
27
- readonly changedFiles: readonly string[];
28
- readonly diffs: readonly DiffPreview[];
29
- }
30
- /**
31
- * Error returned when migration fails.
32
- */
33
- declare class MigrateKitError extends Error {
34
- readonly _tag: "MigrateKitError";
35
- constructor(message: string);
36
- }
37
- /**
38
- * Runs the migrate-kit codemod programmatically.
39
- */
40
- declare function runMigrateKit(options: MigrateKitOptions): Promise<Result<MigrateKitResult, MigrateKitError>>;
41
- /**
42
- * Print migrate-kit results.
43
- */
44
- declare function printMigrateKitResults(result: MigrateKitResult, options?: {
45
- mode?: OutputMode;
46
- }): Promise<void>;
47
- /**
48
- * Register `migrate kit` command directly on Commander.
49
- */
50
- declare function migrateKitCommand(program: Command): void;
51
- export { MigrateKitOptions, MigrateKitResult, MigrateKitError, runMigrateKit, printMigrateKitResults, migrateKitCommand };
@@ -1,5 +0,0 @@
1
- import { ScaffoldError } from "./outfitter-qfh36ddg";
2
- import { Result } from "@outfitter/contracts";
3
- declare function injectSharedConfig(targetDir: string): Result<void, ScaffoldError>;
4
- declare function rewriteLocalDependencies(targetDir: string): Result<void, ScaffoldError>;
5
- export { injectSharedConfig, rewriteLocalDependencies };
@@ -1,60 +0,0 @@
1
- import { TargetId } from "./outfitter-k56rmt24";
2
- import { PostScaffoldResult } from "./outfitter-3weh61w7";
3
- import { OutputMode } from "@outfitter/cli/types";
4
- import { Result } from "@outfitter/contracts";
5
- import { AddBlockResult } from "@outfitter/tooling";
6
- import { Command } from "commander";
7
- type InitStructure = "single" | "workspace";
8
- type InitPresetId = Extract<TargetId, "minimal" | "cli" | "mcp" | "daemon">;
9
- /**
10
- * Options for the init command.
11
- */
12
- interface InitOptions {
13
- readonly targetDir: string;
14
- readonly name: string | undefined;
15
- readonly bin?: string | undefined;
16
- readonly preset?: InitPresetId | undefined;
17
- /** @deprecated Use `preset` instead. */
18
- readonly template?: string | undefined;
19
- readonly structure?: InitStructure | undefined;
20
- readonly workspaceName?: string | undefined;
21
- readonly local?: boolean | undefined;
22
- readonly force: boolean;
23
- readonly with?: string | undefined;
24
- readonly noTooling?: boolean | undefined;
25
- readonly yes?: boolean | undefined;
26
- readonly dryRun?: boolean | undefined;
27
- readonly skipInstall?: boolean | undefined;
28
- readonly skipGit?: boolean | undefined;
29
- readonly skipCommit?: boolean | undefined;
30
- readonly installTimeout?: number | undefined;
31
- }
32
- /**
33
- * Result of running init.
34
- */
35
- interface InitResult {
36
- readonly structure: InitStructure;
37
- readonly rootDir: string;
38
- readonly projectDir: string;
39
- readonly preset: InitPresetId;
40
- readonly packageName: string;
41
- readonly blocksAdded?: AddBlockResult | undefined;
42
- readonly postScaffold: PostScaffoldResult;
43
- readonly dryRunPlan?: {
44
- readonly operations: readonly unknown[];
45
- readonly summary: Record<string, number>;
46
- } | undefined;
47
- }
48
- /**
49
- * Error returned when initialization fails.
50
- */
51
- declare class InitError extends Error {
52
- readonly _tag: "InitError";
53
- constructor(message: string);
54
- }
55
- declare function runInit(options: InitOptions, presetOverride?: InitPresetId): Promise<Result<InitResult, InitError>>;
56
- declare function printInitResults(result: InitResult, options?: {
57
- mode?: OutputMode;
58
- }): Promise<void>;
59
- declare function initCommand(program: Command): void;
60
- export { InitStructure, InitPresetId, InitOptions, InitResult, InitError, runInit, printInitResults, initCommand };
@@ -1,35 +0,0 @@
1
- // @bun
2
- // apps/outfitter/src/create/presets.ts
3
- var CREATE_PRESETS = {
4
- basic: {
5
- id: "basic",
6
- template: "basic",
7
- summary: "Minimal Bun + TypeScript project.",
8
- defaultBlocks: ["scaffolding"]
9
- },
10
- cli: {
11
- id: "cli",
12
- template: "cli",
13
- summary: "CLI starter with Outfitter command ergonomics.",
14
- defaultBlocks: ["scaffolding"]
15
- },
16
- daemon: {
17
- id: "daemon",
18
- template: "daemon",
19
- summary: "Daemon + control CLI starter.",
20
- defaultBlocks: ["scaffolding"]
21
- },
22
- mcp: {
23
- id: "mcp",
24
- template: "mcp",
25
- summary: "MCP server starter.",
26
- defaultBlocks: ["scaffolding"]
27
- }
28
- };
29
- var CREATE_PRESET_IDS = Object.keys(CREATE_PRESETS);
30
- function getCreatePreset(id) {
31
- const presets = CREATE_PRESETS;
32
- return presets[id];
33
- }
34
-
35
- export { CREATE_PRESETS, CREATE_PRESET_IDS, getCreatePreset };