outfitter 0.2.4 → 0.2.6

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 (131) hide show
  1. package/README.md +8 -5
  2. package/dist/actions.d.ts +2 -0
  3. package/dist/actions.js +34 -0
  4. package/dist/cli.js +1 -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/upgrade-codemods.d.ts +42 -0
  26. package/dist/commands/upgrade-codemods.js +15 -0
  27. package/dist/commands/upgrade-planner.d.ts +58 -0
  28. package/dist/commands/upgrade-planner.js +8 -0
  29. package/dist/commands/upgrade-workspace.d.ts +76 -0
  30. package/dist/commands/upgrade-workspace.js +16 -0
  31. package/dist/commands/upgrade.d.ts +214 -0
  32. package/dist/commands/upgrade.js +25 -0
  33. package/dist/create/index.d.ts +5 -0
  34. package/dist/create/index.js +29 -0
  35. package/dist/create/planner.d.ts +3 -0
  36. package/dist/create/planner.js +21 -0
  37. package/dist/create/presets.d.ts +3 -0
  38. package/dist/create/presets.js +12 -0
  39. package/dist/create/types.d.ts +2 -0
  40. package/dist/create/types.js +1 -0
  41. package/dist/engine/blocks.d.ts +3 -0
  42. package/dist/engine/blocks.js +12 -0
  43. package/dist/engine/collector.d.ts +2 -0
  44. package/dist/engine/collector.js +8 -0
  45. package/dist/engine/config.d.ts +3 -0
  46. package/dist/engine/config.js +12 -0
  47. package/dist/engine/executor.d.ts +3 -0
  48. package/dist/engine/executor.js +16 -0
  49. package/dist/engine/index.d.ts +8 -0
  50. package/dist/engine/index.js +59 -0
  51. package/dist/engine/names.d.ts +2 -0
  52. package/dist/engine/names.js +16 -0
  53. package/dist/engine/post-scaffold.d.ts +3 -0
  54. package/dist/engine/post-scaffold.js +8 -0
  55. package/dist/engine/render-plan.d.ts +7 -0
  56. package/dist/engine/render-plan.js +9 -0
  57. package/dist/engine/template.d.ts +3 -0
  58. package/dist/engine/template.js +17 -0
  59. package/dist/engine/types.d.ts +2 -0
  60. package/dist/engine/types.js +8 -0
  61. package/dist/engine/workspace.d.ts +3 -0
  62. package/dist/engine/workspace.js +13 -0
  63. package/dist/index.d.ts +10 -0
  64. package/dist/index.js +1 -1
  65. package/dist/manifest.d.ts +71 -0
  66. package/dist/manifest.js +16 -0
  67. package/dist/output-mode.d.ts +2 -0
  68. package/dist/output-mode.js +10 -0
  69. package/dist/shared/{chunk-tpwtpa74.js → chunk-k59f60cp.js} +858 -396
  70. package/dist/shared/outfitter-193jvzg4.d.ts +5 -0
  71. package/dist/shared/outfitter-1dd0k853.js +194 -0
  72. package/dist/shared/outfitter-1dvma85c.js +322 -0
  73. package/dist/shared/outfitter-1h7k8xxt.js +29 -0
  74. package/dist/shared/outfitter-2ngep1h2.d.ts +5 -0
  75. package/dist/shared/outfitter-2np85etz.js +95 -0
  76. package/dist/shared/outfitter-33w361tc.d.ts +18 -0
  77. package/dist/shared/outfitter-344t1r38.js +1 -0
  78. package/dist/shared/outfitter-3weh61w7.d.ts +25 -0
  79. package/dist/shared/outfitter-4s9meh3j.js +221 -0
  80. package/dist/shared/outfitter-66b25bj8.js +125 -0
  81. package/dist/shared/outfitter-6bkqjk86.d.ts +3 -0
  82. package/dist/shared/outfitter-79vfxt6y.js +269 -0
  83. package/dist/shared/outfitter-7ha7p61k.d.ts +6 -0
  84. package/dist/shared/outfitter-7r12fj7f.js +30 -0
  85. package/dist/shared/outfitter-8y2dfx6n.js +11 -0
  86. package/dist/shared/outfitter-9x1brcmq.js +184 -0
  87. package/dist/shared/outfitter-9zqc2njf.js +859 -0
  88. package/dist/shared/outfitter-a79xrm12.d.ts +17 -0
  89. package/dist/shared/outfitter-amc4jbs1.d.ts +50 -0
  90. package/dist/shared/outfitter-ara3djt0.js +73 -0
  91. package/dist/shared/outfitter-avhm5z6w.js +82 -0
  92. package/dist/shared/outfitter-bkwpbkr9.d.ts +63 -0
  93. package/dist/shared/outfitter-bn9c8p2e.js +204 -0
  94. package/dist/shared/outfitter-bpr28y54.js +70 -0
  95. package/dist/shared/outfitter-cwq39bv4.d.ts +48 -0
  96. package/dist/shared/outfitter-d7pq7d0k.js +196 -0
  97. package/dist/shared/outfitter-dd0btgec.d.ts +40 -0
  98. package/dist/shared/outfitter-e2zz5wv7.d.ts +51 -0
  99. package/dist/shared/outfitter-ehp18x1n.js +1 -0
  100. package/dist/shared/outfitter-gdvm5c0b.d.ts +4 -0
  101. package/dist/shared/outfitter-h1mnzzd1.d.ts +14 -0
  102. package/dist/shared/outfitter-hvsaxgcp.js +1 -0
  103. package/dist/shared/outfitter-hws10ze7.js +532 -0
  104. package/dist/shared/outfitter-j833sxws.js +61 -0
  105. package/dist/shared/outfitter-j8yc7294.d.ts +22 -0
  106. package/dist/shared/outfitter-k112c427.js +21 -0
  107. package/dist/shared/outfitter-k56rmt24.d.ts +30 -0
  108. package/dist/shared/outfitter-ksa1pp4t.d.ts +4 -0
  109. package/dist/shared/outfitter-ksyvwmb5.js +191 -0
  110. package/dist/shared/outfitter-mdt37hqm.js +4 -0
  111. package/dist/shared/outfitter-mtbpabf3.js +91 -0
  112. package/dist/shared/outfitter-mxz69pgy.js +713 -0
  113. package/dist/shared/outfitter-npemy7ta.d.ts +53 -0
  114. package/dist/shared/outfitter-npyfbdmc.d.ts +6 -0
  115. package/dist/shared/outfitter-pyy1zkfh.d.ts +133 -0
  116. package/dist/shared/outfitter-q9agarmb.js +42 -0
  117. package/dist/shared/outfitter-qfh36ddg.d.ts +66 -0
  118. package/dist/shared/outfitter-qn864k6h.js +581 -0
  119. package/dist/shared/outfitter-rdc5v5ms.js +746 -0
  120. package/dist/shared/outfitter-sgtq57qr.d.ts +5 -0
  121. package/dist/shared/outfitter-ttjr95y9.js +98 -0
  122. package/dist/shared/outfitter-vh4xgb93.js +35 -0
  123. package/dist/shared/outfitter-yvksv5qb.js +322 -0
  124. package/dist/shared/outfitter-zwyvewr1.js +36 -0
  125. package/dist/targets/index.d.ts +4 -0
  126. package/dist/targets/index.js +29 -0
  127. package/dist/targets/registry.d.ts +3 -0
  128. package/dist/targets/registry.js +28 -0
  129. package/dist/targets/types.d.ts +2 -0
  130. package/dist/targets/types.js +1 -0
  131. package/package.json +21 -14
@@ -0,0 +1,5 @@
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 };
@@ -0,0 +1,98 @@
1
+ // @bun
2
+ import {
3
+ resolveStructuredOutputMode
4
+ } from "./outfitter-7r12fj7f.js";
5
+
6
+ // apps/outfitter/src/engine/render-plan.ts
7
+ import { relative } from "path";
8
+ import { output } from "@outfitter/cli";
9
+ async function renderOperationPlan(collector, options) {
10
+ const structuredMode = resolveStructuredOutputMode(options?.mode);
11
+ if (structuredMode) {
12
+ await output(collector.toJSON(), { mode: structuredMode });
13
+ return;
14
+ }
15
+ const rootDir = options?.rootDir ?? process.cwd();
16
+ const operations = collector.getOperations();
17
+ const lines = ["[dry-run] Operation plan:", ""];
18
+ const fileCreates = operations.filter((op) => op.type === "file-create");
19
+ const fileOverwrites = operations.filter((op) => op.type === "file-overwrite");
20
+ const fileSkips = operations.filter((op) => op.type === "file-skip");
21
+ const dirCreates = operations.filter((op) => op.type === "dir-create");
22
+ const blockAdds = operations.filter((op) => op.type === "block-add");
23
+ const depAdds = operations.filter((op) => op.type === "dependency-add");
24
+ const configInjects = operations.filter((op) => op.type === "config-inject");
25
+ const installOps = operations.filter((op) => op.type === "install");
26
+ const gitOps = operations.filter((op) => op.type === "git");
27
+ if (fileCreates.length > 0) {
28
+ lines.push(`Create ${fileCreates.length} file(s):`);
29
+ for (const op of fileCreates) {
30
+ lines.push(` + ${relative(rootDir, op.path)}`);
31
+ }
32
+ lines.push("");
33
+ }
34
+ if (fileOverwrites.length > 0) {
35
+ lines.push(`Overwrite ${fileOverwrites.length} file(s):`);
36
+ for (const op of fileOverwrites) {
37
+ lines.push(` ~ ${relative(rootDir, op.path)}`);
38
+ }
39
+ lines.push("");
40
+ }
41
+ if (fileSkips.length > 0) {
42
+ lines.push(`Skip ${fileSkips.length} file(s):`);
43
+ for (const op of fileSkips) {
44
+ lines.push(` - ${relative(rootDir, op.path)} (${op.reason})`);
45
+ }
46
+ lines.push("");
47
+ }
48
+ if (dirCreates.length > 0) {
49
+ lines.push(`Create ${dirCreates.length} directory(ies):`);
50
+ for (const op of dirCreates) {
51
+ lines.push(` + ${relative(rootDir, op.path)}/`);
52
+ }
53
+ lines.push("");
54
+ }
55
+ if (depAdds.length > 0) {
56
+ lines.push(`Add ${depAdds.length} dependency(ies):`);
57
+ for (const dep of depAdds) {
58
+ const suffix = dep.section === "devDependencies" ? " (dev)" : "";
59
+ lines.push(` + ${dep.name}@${dep.version}${suffix}`);
60
+ }
61
+ lines.push("");
62
+ }
63
+ if (blockAdds.length > 0) {
64
+ lines.push(`Add ${blockAdds.length} block(s):`);
65
+ for (const block of blockAdds) {
66
+ lines.push(` + ${block.name}`);
67
+ }
68
+ lines.push("");
69
+ }
70
+ if (configInjects.length > 0) {
71
+ lines.push(`Config injections (${configInjects.length}):`);
72
+ for (const op of configInjects) {
73
+ lines.push(` ~ ${relative(rootDir, op.target)} (${op.description})`);
74
+ }
75
+ lines.push("");
76
+ }
77
+ if (installOps.length > 0 || gitOps.length > 0) {
78
+ lines.push("Post-scaffold:");
79
+ for (const op of installOps) {
80
+ lines.push(` $ ${op.command}`);
81
+ }
82
+ for (const op of gitOps) {
83
+ if (op.action === "init") {
84
+ lines.push(" $ git init");
85
+ } else if (op.action === "add-all") {
86
+ lines.push(" $ git add .");
87
+ } else {
88
+ lines.push(` $ git commit -m "${op.message ?? ""}"`);
89
+ }
90
+ }
91
+ lines.push("");
92
+ }
93
+ const summary = collector.countByType();
94
+ lines.push(`Total operations: ${Object.values(summary).reduce((a, b) => a + b, 0)}`);
95
+ await output(lines, { mode: "human" });
96
+ }
97
+
98
+ export { renderOperationPlan };
@@ -0,0 +1,35 @@
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 };
@@ -0,0 +1,322 @@
1
+ // @bun
2
+ // apps/outfitter/src/commands/upgrade-workspace.ts
3
+ import { existsSync, readFileSync } from "fs";
4
+ import { basename, dirname, join, resolve } from "path";
5
+ import { InternalError, Result } from "@outfitter/contracts";
6
+ function detectWorkspaceRoot(cwd) {
7
+ let current = resolve(cwd);
8
+ const root = resolve("/");
9
+ while (true) {
10
+ if (existsSync(join(current, "pnpm-workspace.yaml"))) {
11
+ return Result.ok(current);
12
+ }
13
+ const pkgPath = join(current, "package.json");
14
+ if (existsSync(pkgPath)) {
15
+ try {
16
+ const raw = readFileSync(pkgPath, "utf-8");
17
+ const pkg = JSON.parse(raw);
18
+ if (hasWorkspacesField(pkg)) {
19
+ return Result.ok(current);
20
+ }
21
+ } catch {}
22
+ }
23
+ if (current === root) {
24
+ break;
25
+ }
26
+ const parent = dirname(current);
27
+ if (parent === current) {
28
+ break;
29
+ }
30
+ current = parent;
31
+ }
32
+ return Result.ok(null);
33
+ }
34
+ function hasWorkspacesField(pkg) {
35
+ const workspaces = pkg.workspaces;
36
+ if (Array.isArray(workspaces) && workspaces.length > 0) {
37
+ return true;
38
+ }
39
+ if (workspaces && typeof workspaces === "object" && !Array.isArray(workspaces)) {
40
+ const packages = workspaces.packages;
41
+ if (Array.isArray(packages) && packages.length > 0) {
42
+ return true;
43
+ }
44
+ }
45
+ return false;
46
+ }
47
+ function resolveWorkspacePatterns(pkg) {
48
+ const workspaces = pkg.workspaces;
49
+ let patterns;
50
+ if (Array.isArray(workspaces)) {
51
+ patterns = workspaces;
52
+ } else if (workspaces && typeof workspaces === "object" && !Array.isArray(workspaces)) {
53
+ const packages = workspaces.packages;
54
+ if (Array.isArray(packages)) {
55
+ patterns = packages;
56
+ } else {
57
+ return [];
58
+ }
59
+ } else {
60
+ return [];
61
+ }
62
+ return patterns.filter((p) => typeof p === "string").map(normalizeWorkspacePattern);
63
+ }
64
+ function normalizeWorkspacePattern(pattern) {
65
+ let value = pattern.trim().replaceAll("\\", "/");
66
+ if (value.length === 0)
67
+ return value;
68
+ if (value.endsWith("/")) {
69
+ value = value.slice(0, -1);
70
+ }
71
+ if (value.endsWith("package.json")) {
72
+ return value;
73
+ }
74
+ return `${value}/package.json`;
75
+ }
76
+ function collectWorkspaceManifests(rootDir) {
77
+ const resolvedRoot = resolve(rootDir);
78
+ const rootPackageJson = join(resolvedRoot, "package.json");
79
+ if (!existsSync(rootPackageJson)) {
80
+ return Result.err(InternalError.create("No package.json found at workspace root", {
81
+ rootDir: resolvedRoot
82
+ }));
83
+ }
84
+ let pkg;
85
+ try {
86
+ const raw = readFileSync(rootPackageJson, "utf-8");
87
+ pkg = JSON.parse(raw);
88
+ } catch {
89
+ return Result.err(InternalError.create("Invalid JSON in root package.json", {
90
+ rootDir: resolvedRoot
91
+ }));
92
+ }
93
+ const workspacePatterns = resolveWorkspacePatterns(pkg);
94
+ const files = new Set([rootPackageJson]);
95
+ for (const pattern of workspacePatterns) {
96
+ if (pattern.length === 0)
97
+ continue;
98
+ const glob = new Bun.Glob(pattern);
99
+ for (const entry of glob.scanSync({ cwd: resolvedRoot })) {
100
+ const absolute = resolve(resolvedRoot, entry);
101
+ if (existsSync(absolute) && basename(absolute) === "package.json") {
102
+ files.add(absolute);
103
+ }
104
+ }
105
+ }
106
+ return Result.ok(Array.from(files).sort((a, b) => a.localeCompare(b)));
107
+ }
108
+ function extractOutfitterDeps(manifestPath) {
109
+ let pkg;
110
+ try {
111
+ const raw = readFileSync(manifestPath, "utf-8");
112
+ pkg = JSON.parse(raw);
113
+ } catch {
114
+ return Result.err(InternalError.create("Failed to parse package.json", {
115
+ path: manifestPath
116
+ }));
117
+ }
118
+ const deps = {
119
+ ...pkg.dependencies ?? {},
120
+ ...pkg.devDependencies ?? {}
121
+ };
122
+ const packages = [];
123
+ for (const [name, version] of Object.entries(deps)) {
124
+ if (!name.startsWith("@outfitter/"))
125
+ continue;
126
+ if (version.startsWith("workspace:")) {
127
+ const wsVersion = version.slice("workspace:".length);
128
+ if (wsVersion === "*" || wsVersion === "~" || wsVersion === "^") {
129
+ continue;
130
+ }
131
+ const wsClean = wsVersion.replace(/^[\^~>=<]+/, "");
132
+ try {
133
+ if (!Bun.semver.satisfies(wsClean, "*"))
134
+ continue;
135
+ } catch {
136
+ continue;
137
+ }
138
+ packages.push({ name, version: wsClean });
139
+ continue;
140
+ }
141
+ const cleaned = version.replace(/^[\^~>=<]+/, "");
142
+ try {
143
+ if (!Bun.semver.satisfies(cleaned, "*"))
144
+ continue;
145
+ } catch {
146
+ continue;
147
+ }
148
+ packages.push({ name, version: cleaned });
149
+ }
150
+ return Result.ok(packages);
151
+ }
152
+ function getInstalledPackagesFromWorkspace(rootDir) {
153
+ const resolvedRoot = resolve(rootDir);
154
+ const wsRootResult = detectWorkspaceRoot(resolvedRoot);
155
+ if (wsRootResult.isErr())
156
+ return wsRootResult;
157
+ const effectiveRoot = wsRootResult.value ?? resolvedRoot;
158
+ let manifestPaths;
159
+ if (wsRootResult.value !== null) {
160
+ const manifestsResult = collectWorkspaceManifests(effectiveRoot);
161
+ if (manifestsResult.isErr())
162
+ return manifestsResult;
163
+ manifestPaths = manifestsResult.value;
164
+ } else {
165
+ const rootPkg = join(resolvedRoot, "package.json");
166
+ if (!existsSync(rootPkg)) {
167
+ return Result.err(InternalError.create("No package.json found", { cwd: resolvedRoot }));
168
+ }
169
+ manifestPaths = [rootPkg];
170
+ }
171
+ const packageVersionMap = new Map;
172
+ const manifestsByPackage = new Map;
173
+ for (const manifestPath of manifestPaths) {
174
+ const depsResult = extractOutfitterDeps(manifestPath);
175
+ if (depsResult.isErr())
176
+ return depsResult;
177
+ const deps = depsResult.value;
178
+ for (const dep of deps) {
179
+ let versionMap = packageVersionMap.get(dep.name);
180
+ if (!versionMap) {
181
+ versionMap = new Map;
182
+ packageVersionMap.set(dep.name, versionMap);
183
+ }
184
+ let manifests = versionMap.get(dep.version);
185
+ if (!manifests) {
186
+ manifests = [];
187
+ versionMap.set(dep.version, manifests);
188
+ }
189
+ manifests.push(manifestPath);
190
+ let pkgManifests = manifestsByPackage.get(dep.name);
191
+ if (!pkgManifests) {
192
+ pkgManifests = [];
193
+ manifestsByPackage.set(dep.name, pkgManifests);
194
+ }
195
+ pkgManifests.push(manifestPath);
196
+ }
197
+ }
198
+ const packages = [];
199
+ const conflicts = [];
200
+ for (const [name, versionMap] of packageVersionMap) {
201
+ const versions = Array.from(versionMap.entries()).map(([version, manifests]) => ({ version, manifests })).sort((a, b) => {
202
+ try {
203
+ return Bun.semver.order(a.version, b.version);
204
+ } catch {
205
+ return a.version.localeCompare(b.version);
206
+ }
207
+ });
208
+ if (versions.length > 1) {
209
+ conflicts.push({ name, versions });
210
+ }
211
+ const lowest = versions[0];
212
+ if (lowest) {
213
+ packages.push({ name, version: lowest.version });
214
+ }
215
+ }
216
+ packages.sort((a, b) => a.name.localeCompare(b.name));
217
+ return Result.ok({
218
+ packages,
219
+ conflicts,
220
+ manifestsByPackage,
221
+ manifestPaths,
222
+ workspaceRoot: wsRootResult.value
223
+ });
224
+ }
225
+ async function applyUpdatesToWorkspace(manifestPaths, manifestsByPackage, updates) {
226
+ const updateMap = new Map;
227
+ for (const u of updates) {
228
+ updateMap.set(u.name, u.latestVersion);
229
+ }
230
+ const manifestsToUpdate = new Set;
231
+ for (const u of updates) {
232
+ const manifests = manifestsByPackage.get(u.name);
233
+ if (manifests) {
234
+ for (const m of manifests) {
235
+ manifestsToUpdate.add(m);
236
+ }
237
+ }
238
+ }
239
+ for (const manifestPath of manifestPaths) {
240
+ if (!manifestsToUpdate.has(manifestPath))
241
+ continue;
242
+ let raw;
243
+ try {
244
+ raw = readFileSync(manifestPath, "utf-8");
245
+ } catch {
246
+ return Result.err(InternalError.create("Failed to read package.json for apply", {
247
+ path: manifestPath
248
+ }));
249
+ }
250
+ let pkg;
251
+ try {
252
+ pkg = JSON.parse(raw);
253
+ } catch {
254
+ return Result.err(InternalError.create("Invalid JSON in package.json", {
255
+ path: manifestPath
256
+ }));
257
+ }
258
+ let changed = false;
259
+ for (const section of ["dependencies", "devDependencies"]) {
260
+ const deps = pkg[section];
261
+ if (!deps)
262
+ continue;
263
+ for (const name of Object.keys(deps)) {
264
+ const newVersion = updateMap.get(name);
265
+ if (newVersion === undefined)
266
+ continue;
267
+ const currentSpecifier = deps[name];
268
+ if (currentSpecifier === undefined)
269
+ continue;
270
+ if (currentSpecifier.startsWith("workspace:") && ["*", "~", "^"].includes(currentSpecifier.slice("workspace:".length))) {
271
+ continue;
272
+ }
273
+ const prefix = getVersionPrefix(currentSpecifier);
274
+ deps[name] = `${prefix}${newVersion}`;
275
+ changed = true;
276
+ }
277
+ }
278
+ if (changed) {
279
+ try {
280
+ const updated = `${JSON.stringify(pkg, null, 2)}
281
+ `;
282
+ await Bun.write(manifestPath, updated);
283
+ } catch {
284
+ return Result.err(InternalError.create("Failed to write updated package.json", {
285
+ path: manifestPath
286
+ }));
287
+ }
288
+ }
289
+ }
290
+ return Result.ok(undefined);
291
+ }
292
+ function getVersionPrefix(specifier) {
293
+ if (specifier.startsWith("workspace:")) {
294
+ const inner = specifier.slice("workspace:".length);
295
+ return `workspace:${getVersionPrefix(inner)}`;
296
+ }
297
+ const match = specifier.match(/^([\^~>=<]+)/);
298
+ return match?.[1] ?? "";
299
+ }
300
+ async function runInstall(cwd) {
301
+ try {
302
+ const proc = Bun.spawn(["bun", "install"], {
303
+ cwd,
304
+ stdout: "pipe",
305
+ stderr: "pipe"
306
+ });
307
+ const exitCode = await proc.exited;
308
+ if (exitCode !== 0) {
309
+ const stderr = await new Response(proc.stderr).text();
310
+ return Result.err(InternalError.create("bun install failed", {
311
+ cwd,
312
+ exitCode,
313
+ stderr: stderr.trim()
314
+ }));
315
+ }
316
+ } catch {
317
+ return Result.err(InternalError.create("Failed to run bun install", { cwd }));
318
+ }
319
+ return Result.ok(undefined);
320
+ }
321
+
322
+ export { detectWorkspaceRoot, collectWorkspaceManifests, getInstalledPackagesFromWorkspace, applyUpdatesToWorkspace, runInstall };
@@ -0,0 +1,36 @@
1
+ // @bun
2
+ // apps/outfitter/src/commands/docs-module-loader.ts
3
+ import { existsSync } from "fs";
4
+ import { createRequire } from "module";
5
+ import { dirname, join } from "path";
6
+ import { pathToFileURL } from "url";
7
+ var require2 = createRequire(import.meta.url);
8
+ function resolveDocsEntrypoint() {
9
+ const packageJsonPath = require2.resolve("@outfitter/docs/package.json");
10
+ const packageRoot = dirname(packageJsonPath);
11
+ const srcEntrypoint = join(packageRoot, "src", "index.ts");
12
+ if (existsSync(srcEntrypoint)) {
13
+ return srcEntrypoint;
14
+ }
15
+ const distEntrypoint = join(packageRoot, "dist", "index.js");
16
+ if (existsSync(distEntrypoint)) {
17
+ return distEntrypoint;
18
+ }
19
+ throw new Error("Unable to resolve @outfitter/docs entrypoint (expected src/index.ts or dist/index.js).");
20
+ }
21
+ var docsModulePromise;
22
+ async function loadDocsModule() {
23
+ if (!docsModulePromise) {
24
+ docsModulePromise = (async () => {
25
+ const entrypoint = resolveDocsEntrypoint();
26
+ const module = await import(pathToFileURL(entrypoint).href);
27
+ if (typeof module.createDocsCommand !== "function" || typeof module.executeCheckCommand !== "function" || typeof module.executeSyncCommand !== "function" || typeof module.executeExportCommand !== "function") {
28
+ throw new Error("Resolved @outfitter/docs entrypoint does not export required docs functions.");
29
+ }
30
+ return module;
31
+ })();
32
+ }
33
+ return await docsModulePromise;
34
+ }
35
+
36
+ export { loadDocsModule };
@@ -0,0 +1,4 @@
1
+ import "../shared/outfitter-y784nh31";
2
+ import { INIT_TARGET_IDS, READY_TARGET_IDS, SCAFFOLD_TARGET_IDS, TARGET_IDS, TARGET_REGISTRY, getInitTarget, getReadyTarget, getScaffoldTarget, getTarget, listTargets, resolvePlacement } from "../shared/outfitter-33w361tc";
3
+ import { TargetCategory, TargetDefinition, TargetId, TargetScope, TargetStatus } from "../shared/outfitter-k56rmt24";
4
+ export { resolvePlacement, listTargets, getTarget, getScaffoldTarget, getReadyTarget, getInitTarget, TargetStatus, TargetScope, TargetId, TargetDefinition, TargetCategory, TARGET_REGISTRY, TARGET_IDS, SCAFFOLD_TARGET_IDS, READY_TARGET_IDS, INIT_TARGET_IDS };
@@ -0,0 +1,29 @@
1
+ // @bun
2
+ import"../shared/outfitter-ehp18x1n.js";
3
+ import {
4
+ INIT_TARGET_IDS,
5
+ READY_TARGET_IDS,
6
+ SCAFFOLD_TARGET_IDS,
7
+ TARGET_IDS,
8
+ TARGET_REGISTRY,
9
+ getInitTarget,
10
+ getReadyTarget,
11
+ getScaffoldTarget,
12
+ getTarget,
13
+ listTargets,
14
+ resolvePlacement
15
+ } from "../shared/outfitter-1dd0k853.js";
16
+ import"../shared/outfitter-mdt37hqm.js";
17
+ export {
18
+ resolvePlacement,
19
+ listTargets,
20
+ getTarget,
21
+ getScaffoldTarget,
22
+ getReadyTarget,
23
+ getInitTarget,
24
+ TARGET_REGISTRY,
25
+ TARGET_IDS,
26
+ SCAFFOLD_TARGET_IDS,
27
+ READY_TARGET_IDS,
28
+ INIT_TARGET_IDS
29
+ };
@@ -0,0 +1,3 @@
1
+ import { INIT_TARGET_IDS, READY_TARGET_IDS, SCAFFOLD_TARGET_IDS, TARGET_IDS, TARGET_REGISTRY, getInitTarget, getReadyTarget, getScaffoldTarget, getTarget, listTargets, resolvePlacement } from "../shared/outfitter-33w361tc";
2
+ import "../shared/outfitter-k56rmt24";
3
+ export { resolvePlacement, listTargets, getTarget, getScaffoldTarget, getReadyTarget, getInitTarget, TARGET_REGISTRY, TARGET_IDS, SCAFFOLD_TARGET_IDS, READY_TARGET_IDS, INIT_TARGET_IDS };
@@ -0,0 +1,28 @@
1
+ // @bun
2
+ import {
3
+ INIT_TARGET_IDS,
4
+ READY_TARGET_IDS,
5
+ SCAFFOLD_TARGET_IDS,
6
+ TARGET_IDS,
7
+ TARGET_REGISTRY,
8
+ getInitTarget,
9
+ getReadyTarget,
10
+ getScaffoldTarget,
11
+ getTarget,
12
+ listTargets,
13
+ resolvePlacement
14
+ } from "../shared/outfitter-1dd0k853.js";
15
+ import"../shared/outfitter-mdt37hqm.js";
16
+ export {
17
+ resolvePlacement,
18
+ listTargets,
19
+ getTarget,
20
+ getScaffoldTarget,
21
+ getReadyTarget,
22
+ getInitTarget,
23
+ TARGET_REGISTRY,
24
+ TARGET_IDS,
25
+ SCAFFOLD_TARGET_IDS,
26
+ READY_TARGET_IDS,
27
+ INIT_TARGET_IDS
28
+ };
@@ -0,0 +1,2 @@
1
+ import { TargetCategory, TargetDefinition, TargetId, TargetScope, TargetStatus } from "../shared/outfitter-k56rmt24";
2
+ export { TargetStatus, TargetScope, TargetId, TargetDefinition, TargetCategory };
@@ -0,0 +1 @@
1
+ // @bun
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.4",
4
+ "version": "0.2.6",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
@@ -82,22 +82,28 @@
82
82
  "default": "./dist/commands/shared-deps.js"
83
83
  }
84
84
  },
85
- "./commands/update": {
85
+ "./commands/upgrade": {
86
86
  "import": {
87
- "types": "./dist/commands/update.d.ts",
88
- "default": "./dist/commands/update.js"
87
+ "types": "./dist/commands/upgrade.d.ts",
88
+ "default": "./dist/commands/upgrade.js"
89
89
  }
90
90
  },
91
- "./commands/update-planner": {
91
+ "./commands/upgrade-codemods": {
92
92
  "import": {
93
- "types": "./dist/commands/update-planner.d.ts",
94
- "default": "./dist/commands/update-planner.js"
93
+ "types": "./dist/commands/upgrade-codemods.d.ts",
94
+ "default": "./dist/commands/upgrade-codemods.js"
95
95
  }
96
96
  },
97
- "./commands/update-workspace": {
97
+ "./commands/upgrade-planner": {
98
98
  "import": {
99
- "types": "./dist/commands/update-workspace.d.ts",
100
- "default": "./dist/commands/update-workspace.js"
99
+ "types": "./dist/commands/upgrade-planner.d.ts",
100
+ "default": "./dist/commands/upgrade-planner.js"
101
+ }
102
+ },
103
+ "./commands/upgrade-workspace": {
104
+ "import": {
105
+ "types": "./dist/commands/upgrade-workspace.d.ts",
106
+ "default": "./dist/commands/upgrade-workspace.js"
101
107
  }
102
108
  },
103
109
  "./create": {
@@ -233,17 +239,18 @@
233
239
  "typecheck": "tsc --noEmit",
234
240
  "sync:templates": "bun run ../../scripts/sync-templates.ts",
235
241
  "prepack": "bun run sync:templates",
242
+ "prepublishOnly": "bun ../../scripts/check-publish-manifest.ts",
236
243
  "clean": "rm -rf dist"
237
244
  },
238
245
  "dependencies": {
239
246
  "@clack/prompts": "^0.10.0",
240
- "@outfitter/cli": "0.4.1",
247
+ "@outfitter/cli": "0.5.1",
241
248
  "@outfitter/tui": "0.2.0",
242
- "@outfitter/config": "0.3.1",
243
- "@outfitter/contracts": "0.3.0",
249
+ "@outfitter/config": "0.3.2",
250
+ "@outfitter/contracts": "0.4.0",
244
251
  "@outfitter/docs": "0.1.1",
245
252
  "@outfitter/logging": "0.4.0",
246
- "@outfitter/tooling": "0.2.3",
253
+ "@outfitter/tooling": "0.2.4",
247
254
  "commander": "^14.0.2",
248
255
  "typescript": "^5.9.3",
249
256
  "zod": "^4.3.5"