outfitter 0.2.7 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/README.md +1 -2
  2. package/dist/cli.js +1 -1
  3. package/dist/index.d.ts +5 -6
  4. package/dist/index.js +8 -7
  5. package/dist/shared/{chunk-x6644tk8.js → chunk-3pwh8ys4.js} +124 -154
  6. package/package.json +15 -11
  7. package/dist/actions.d.ts +0 -2
  8. package/dist/actions.js +0 -35
  9. package/dist/commands/add.d.ts +0 -54
  10. package/dist/commands/add.js +0 -16
  11. package/dist/commands/check-tsdoc.d.ts +0 -22
  12. package/dist/commands/check-tsdoc.js +0 -8
  13. package/dist/commands/check.d.ts +0 -91
  14. package/dist/commands/check.js +0 -14
  15. package/dist/commands/demo.d.ts +0 -21
  16. package/dist/commands/demo.js +0 -8
  17. package/dist/commands/docs-module-loader.d.ts +0 -2
  18. package/dist/commands/docs-module-loader.js +0 -8
  19. package/dist/commands/doctor.d.ts +0 -2
  20. package/dist/commands/doctor.js +0 -25
  21. package/dist/commands/init.d.ts +0 -7
  22. package/dist/commands/init.js +0 -32
  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 -32
  27. package/dist/commands/shared-deps.d.ts +0 -21
  28. package/dist/commands/shared-deps.js +0 -11
  29. package/dist/commands/upgrade-codemods.d.ts +0 -42
  30. package/dist/commands/upgrade-codemods.js +0 -15
  31. package/dist/commands/upgrade-planner.d.ts +0 -58
  32. package/dist/commands/upgrade-planner.js +0 -8
  33. package/dist/commands/upgrade-workspace.d.ts +0 -2
  34. package/dist/commands/upgrade-workspace.js +0 -16
  35. package/dist/commands/upgrade.d.ts +0 -221
  36. package/dist/commands/upgrade.js +0 -25
  37. package/dist/create/index.d.ts +0 -5
  38. package/dist/create/index.js +0 -30
  39. package/dist/create/planner.d.ts +0 -3
  40. package/dist/create/planner.js +0 -22
  41. package/dist/create/presets.d.ts +0 -3
  42. package/dist/create/presets.js +0 -12
  43. package/dist/create/types.d.ts +0 -2
  44. package/dist/create/types.js +0 -1
  45. package/dist/engine/blocks.d.ts +0 -3
  46. package/dist/engine/blocks.js +0 -12
  47. package/dist/engine/collector.d.ts +0 -2
  48. package/dist/engine/collector.js +0 -8
  49. package/dist/engine/config.d.ts +0 -3
  50. package/dist/engine/config.js +0 -15
  51. package/dist/engine/dependency-versions.d.ts +0 -12
  52. package/dist/engine/dependency-versions.js +0 -12
  53. package/dist/engine/executor.d.ts +0 -3
  54. package/dist/engine/executor.js +0 -19
  55. package/dist/engine/index.d.ts +0 -8
  56. package/dist/engine/index.js +0 -68
  57. package/dist/engine/names.d.ts +0 -2
  58. package/dist/engine/names.js +0 -24
  59. package/dist/engine/post-scaffold.d.ts +0 -3
  60. package/dist/engine/post-scaffold.js +0 -8
  61. package/dist/engine/render-plan.d.ts +0 -7
  62. package/dist/engine/render-plan.js +0 -9
  63. package/dist/engine/template.d.ts +0 -3
  64. package/dist/engine/template.js +0 -17
  65. package/dist/engine/types.d.ts +0 -2
  66. package/dist/engine/types.js +0 -8
  67. package/dist/engine/workspace.d.ts +0 -3
  68. package/dist/engine/workspace.js +0 -20
  69. package/dist/manifest.d.ts +0 -71
  70. package/dist/manifest.js +0 -16
  71. package/dist/output-mode.d.ts +0 -2
  72. package/dist/output-mode.js +0 -10
  73. package/dist/shared/outfitter-109s75x0.d.ts +0 -76
  74. package/dist/shared/outfitter-1fy7byz5.js +0 -170
  75. package/dist/shared/outfitter-1h7k8xxt.js +0 -29
  76. package/dist/shared/outfitter-20f6a2n4.js +0 -35
  77. package/dist/shared/outfitter-344t1r38.js +0 -1
  78. package/dist/shared/outfitter-4q1zfmvc.js +0 -154
  79. package/dist/shared/outfitter-4s9meh3j.js +0 -221
  80. package/dist/shared/outfitter-5akzvppx.js +0 -125
  81. package/dist/shared/outfitter-5y646xzk.js +0 -301
  82. package/dist/shared/outfitter-5yjr404v.d.ts +0 -22
  83. package/dist/shared/outfitter-63gse8fv.js +0 -316
  84. package/dist/shared/outfitter-6bkqjk86.d.ts +0 -3
  85. package/dist/shared/outfitter-6fgk6adm.d.ts +0 -40
  86. package/dist/shared/outfitter-79vfxt6y.js +0 -269
  87. package/dist/shared/outfitter-7ch26yq8.js +0 -885
  88. package/dist/shared/outfitter-7r12fj7f.js +0 -30
  89. package/dist/shared/outfitter-8y2dfx6n.js +0 -11
  90. package/dist/shared/outfitter-9x1brcmq.js +0 -184
  91. package/dist/shared/outfitter-a79xrm12.d.ts +0 -17
  92. package/dist/shared/outfitter-amc4jbs1.d.ts +0 -50
  93. package/dist/shared/outfitter-bn9c8p2e.js +0 -204
  94. package/dist/shared/outfitter-bpr28y54.js +0 -70
  95. package/dist/shared/outfitter-dpj9erew.d.ts +0 -4
  96. package/dist/shared/outfitter-e9rrfekb.d.ts +0 -51
  97. package/dist/shared/outfitter-ehp18x1n.js +0 -1
  98. package/dist/shared/outfitter-f9znfhkn.d.ts +0 -5
  99. package/dist/shared/outfitter-fhnjpjwc.d.ts +0 -18
  100. package/dist/shared/outfitter-fn20r49x.d.ts +0 -5
  101. package/dist/shared/outfitter-h3q6ae6d.d.ts +0 -48
  102. package/dist/shared/outfitter-ha89qf8q.js +0 -132
  103. package/dist/shared/outfitter-hsp8vy5m.d.ts +0 -146
  104. package/dist/shared/outfitter-hvsaxgcp.js +0 -1
  105. package/dist/shared/outfitter-j833sxws.js +0 -61
  106. package/dist/shared/outfitter-ksyvwmb5.js +0 -191
  107. package/dist/shared/outfitter-m3ehh37q.d.ts +0 -22
  108. package/dist/shared/outfitter-m44n0qzw.js +0 -161
  109. package/dist/shared/outfitter-mdt37hqm.js +0 -4
  110. package/dist/shared/outfitter-mt7d1ek2.js +0 -698
  111. package/dist/shared/outfitter-mtbpabf3.js +0 -91
  112. package/dist/shared/outfitter-n9g1zk4x.d.ts +0 -66
  113. package/dist/shared/outfitter-p71qb0f0.js +0 -82
  114. package/dist/shared/outfitter-pcj9gg2g.js +0 -909
  115. package/dist/shared/outfitter-pj9vp00r.js +0 -601
  116. package/dist/shared/outfitter-qakwgrrh.d.ts +0 -4
  117. package/dist/shared/outfitter-r419zfgs.d.ts +0 -30
  118. package/dist/shared/outfitter-s7jetkge.d.ts +0 -18
  119. package/dist/shared/outfitter-ttjr95y9.js +0 -98
  120. package/dist/shared/outfitter-vh4xgb93.js +0 -35
  121. package/dist/shared/outfitter-w1j80j1r.js +0 -326
  122. package/dist/shared/outfitter-xe5mzgdc.js +0 -208
  123. package/dist/shared/outfitter-ybbazsxq.d.ts +0 -14
  124. package/dist/shared/outfitter-yraebrmw.d.ts +0 -5
  125. package/dist/shared/outfitter-yvksv5qb.js +0 -322
  126. package/dist/shared/outfitter-z0we32cp.d.ts +0 -63
  127. package/dist/shared/outfitter-z5sx06qe.d.ts +0 -25
  128. package/dist/shared/outfitter-zwyvewr1.js +0 -36
  129. package/dist/targets/index.d.ts +0 -4
  130. package/dist/targets/index.js +0 -29
  131. package/dist/targets/registry.d.ts +0 -3
  132. package/dist/targets/registry.js +0 -28
  133. package/dist/targets/types.d.ts +0 -2
  134. package/dist/targets/types.js +0 -1
  135. package/template-versions.json +0 -22
  136. package/templates/.gitkeep +0 -0
  137. package/templates/basic/.gitignore.template +0 -30
  138. package/templates/basic/.lefthook.yml.template +0 -26
  139. package/templates/basic/package.json.template +0 -46
  140. package/templates/basic/src/index.ts.template +0 -26
  141. package/templates/basic/tsconfig.json.template +0 -34
  142. package/templates/cli/.gitignore.template +0 -4
  143. package/templates/cli/.lefthook.yml.template +0 -26
  144. package/templates/cli/README.md.template +0 -35
  145. package/templates/cli/biome.json.template +0 -4
  146. package/templates/cli/package.json.template +0 -53
  147. package/templates/cli/src/cli.ts.template +0 -8
  148. package/templates/cli/src/index.ts.template +0 -7
  149. package/templates/cli/src/program.ts.template +0 -31
  150. package/templates/cli/tsconfig.json.template +0 -34
  151. package/templates/daemon/.gitignore.template +0 -4
  152. package/templates/daemon/.lefthook.yml.template +0 -26
  153. package/templates/daemon/README.md.template +0 -67
  154. package/templates/daemon/biome.json.template +0 -4
  155. package/templates/daemon/package.json.template +0 -56
  156. package/templates/daemon/src/cli.ts.template +0 -96
  157. package/templates/daemon/src/daemon-main.ts.template +0 -79
  158. package/templates/daemon/src/daemon.ts.template +0 -11
  159. package/templates/daemon/src/index.ts.template +0 -7
  160. package/templates/daemon/tsconfig.json.template +0 -23
  161. package/templates/full-stack/.gitignore.template +0 -30
  162. package/templates/full-stack/README.md.template +0 -30
  163. package/templates/full-stack/apps/cli/package.json.template +0 -39
  164. package/templates/full-stack/apps/cli/src/cli.ts.template +0 -24
  165. package/templates/full-stack/apps/cli/src/index.test.ts.template +0 -18
  166. package/templates/full-stack/apps/cli/src/index.ts.template +0 -5
  167. package/templates/full-stack/apps/cli/tsconfig.json.template +0 -37
  168. package/templates/full-stack/apps/mcp/package.json.template +0 -40
  169. package/templates/full-stack/apps/mcp/src/index.test.ts.template +0 -18
  170. package/templates/full-stack/apps/mcp/src/index.ts.template +0 -6
  171. package/templates/full-stack/apps/mcp/src/mcp.ts.template +0 -22
  172. package/templates/full-stack/apps/mcp/src/server.ts.template +0 -10
  173. package/templates/full-stack/apps/mcp/tsconfig.json.template +0 -37
  174. package/templates/full-stack/package.json.template +0 -16
  175. package/templates/full-stack/packages/core/package.json.template +0 -36
  176. package/templates/full-stack/packages/core/src/handlers.ts.template +0 -31
  177. package/templates/full-stack/packages/core/src/index.test.ts.template +0 -30
  178. package/templates/full-stack/packages/core/src/index.ts.template +0 -8
  179. package/templates/full-stack/packages/core/src/types.ts.template +0 -13
  180. package/templates/full-stack/packages/core/tsconfig.json.template +0 -34
  181. package/templates/library/.gitignore.template +0 -30
  182. package/templates/library/README.md.template +0 -29
  183. package/templates/library/bunup.config.ts.template +0 -20
  184. package/templates/library/package.json.template +0 -55
  185. package/templates/library/src/handlers.ts.template +0 -31
  186. package/templates/library/src/index.test.ts.template +0 -35
  187. package/templates/library/src/index.ts.template +0 -8
  188. package/templates/library/src/types.ts.template +0 -13
  189. package/templates/library/tsconfig.json.template +0 -34
  190. package/templates/mcp/.gitignore.template +0 -4
  191. package/templates/mcp/.lefthook.yml.template +0 -26
  192. package/templates/mcp/README.md.template +0 -54
  193. package/templates/mcp/biome.json.template +0 -4
  194. package/templates/mcp/package.json.template +0 -53
  195. package/templates/mcp/src/index.ts.template +0 -7
  196. package/templates/mcp/src/mcp.ts.template +0 -33
  197. package/templates/mcp/src/server.ts.template +0 -8
  198. package/templates/mcp/tsconfig.json.template +0 -23
  199. package/templates/minimal/.gitignore.template +0 -30
  200. package/templates/minimal/.lefthook.yml.template +0 -26
  201. package/templates/minimal/package.json.template +0 -53
  202. package/templates/minimal/src/index.ts.template +0 -26
  203. package/templates/minimal/tsconfig.json.template +0 -34
@@ -1,20 +0,0 @@
1
- // @bun
2
- import {
3
- buildWorkspaceRootPackageJson,
4
- buildWorkspaceRootReadme,
5
- detectWorkspaceRoot,
6
- getWorkspacePatterns,
7
- hasWorkspacesField,
8
- scaffoldWorkspaceRoot
9
- } from "../shared/outfitter-1fy7byz5.js";
10
- import"../shared/outfitter-4q1zfmvc.js";
11
- import"../shared/outfitter-8y2dfx6n.js";
12
- import"../shared/outfitter-mdt37hqm.js";
13
- export {
14
- scaffoldWorkspaceRoot,
15
- hasWorkspacesField,
16
- getWorkspacePatterns,
17
- detectWorkspaceRoot,
18
- buildWorkspaceRootReadme,
19
- buildWorkspaceRootPackageJson
20
- };
@@ -1,71 +0,0 @@
1
- import { OutfitterError, Result } from "@outfitter/contracts";
2
- import { ZodType } from "zod";
3
- /** A single block entry in the manifest. */
4
- interface BlockEntry {
5
- /** ISO 8601 timestamp of when the block was installed or last updated. */
6
- installedAt: string;
7
- /** Tooling version the block was installed from. */
8
- installedFrom: string;
9
- }
10
- /** The full manifest structure. */
11
- interface Manifest {
12
- /** Map of block name to install metadata. */
13
- blocks: Record<string, BlockEntry>;
14
- /** Manifest format version. Currently always 1. */
15
- version: 1;
16
- }
17
- /**
18
- * Schema for a single block entry in the manifest.
19
- */
20
- declare const BlockEntrySchema: ZodType<BlockEntry>;
21
- /**
22
- * Schema for the manifest file.
23
- */
24
- declare const ManifestSchema: ZodType<Manifest>;
25
- /**
26
- * Reads and validates `.outfitter/manifest.json`.
27
- *
28
- * @param cwd - Working directory containing the `.outfitter/` folder
29
- * @returns The parsed manifest, or `null` if the file does not exist
30
- *
31
- * @example
32
- * ```typescript
33
- * const result = await readManifest(process.cwd());
34
- * if (result.isOk() && result.value) {
35
- * console.log(result.value.blocks);
36
- * }
37
- * ```
38
- */
39
- declare function readManifest(cwd: string): Promise<Result<Manifest | null, OutfitterError>>;
40
- /**
41
- * Writes a manifest to `.outfitter/manifest.json`.
42
- *
43
- * Creates the `.outfitter/` directory if it does not exist.
44
- * Writes atomically via `Bun.write`.
45
- *
46
- * @param cwd - Working directory to write the manifest into
47
- * @param manifest - The manifest data to write
48
- *
49
- * @example
50
- * ```typescript
51
- * await writeManifest(process.cwd(), { version: 1, blocks: {} });
52
- * ```
53
- */
54
- declare function writeManifest(cwd: string, manifest: Manifest): Promise<Result<void, OutfitterError>>;
55
- /**
56
- * Adds or updates a block entry in the manifest (read-modify-write).
57
- *
58
- * If no manifest exists, creates a new one. If the block already exists,
59
- * updates its `installedFrom` and `installedAt` fields.
60
- *
61
- * @param cwd - Working directory containing the project
62
- * @param blockName - Name of the block to stamp
63
- * @param toolingVersion - Version of the tooling package the block was installed from
64
- *
65
- * @example
66
- * ```typescript
67
- * await stampBlock(process.cwd(), "biome", "0.2.1");
68
- * ```
69
- */
70
- declare function stampBlock(cwd: string, blockName: string, toolingVersion: string): Promise<Result<void, OutfitterError>>;
71
- export { writeManifest, stampBlock, readManifest, ManifestSchema, Manifest, BlockEntrySchema, BlockEntry };
package/dist/manifest.js DELETED
@@ -1,16 +0,0 @@
1
- // @bun
2
- import {
3
- BlockEntrySchema,
4
- ManifestSchema,
5
- readManifest,
6
- stampBlock,
7
- writeManifest
8
- } from "./shared/outfitter-mtbpabf3.js";
9
- import"./shared/outfitter-mdt37hqm.js";
10
- export {
11
- writeManifest,
12
- stampBlock,
13
- readManifest,
14
- ManifestSchema,
15
- BlockEntrySchema
16
- };
@@ -1,2 +0,0 @@
1
- import { CliOutputMode, StructuredOutputMode, resolveOutputModeFromContext, resolveStructuredOutputMode } from "./shared/outfitter-a79xrm12.js";
2
- export { resolveStructuredOutputMode, resolveOutputModeFromContext, StructuredOutputMode, CliOutputMode };
@@ -1,10 +0,0 @@
1
- // @bun
2
- import {
3
- resolveOutputModeFromContext,
4
- resolveStructuredOutputMode
5
- } from "./shared/outfitter-7r12fj7f.js";
6
- import"./shared/outfitter-mdt37hqm.js";
7
- export {
8
- resolveStructuredOutputMode,
9
- resolveOutputModeFromContext
10
- };
@@ -1,76 +0,0 @@
1
- import { OutfitterError } from "@outfitter/contracts";
2
- import { Result } from "@outfitter/contracts";
3
- /** A package dependency found across workspace manifests. */
4
- interface WorkspacePackageEntry {
5
- /** Full package name (e.g. "@outfitter/cli") */
6
- readonly name: string;
7
- /** Cleaned semver version (without range prefix) */
8
- readonly version: string;
9
- }
10
- /** Version conflict: same package at different versions in different manifests. */
11
- interface VersionConflict {
12
- /** Full package name */
13
- readonly name: string;
14
- /** All distinct versions found, with their manifest paths */
15
- readonly versions: ReadonlyArray<{
16
- readonly version: string;
17
- readonly manifests: readonly string[];
18
- }>;
19
- }
20
- /** Result of scanning a workspace for @outfitter/* packages. */
21
- interface WorkspaceScanResult {
22
- /** Version conflicts found across manifests */
23
- readonly conflicts: readonly VersionConflict[];
24
- /** All manifest paths scanned */
25
- readonly manifestPaths: readonly string[];
26
- /** Maps package name to the manifest paths that contain it */
27
- readonly manifestsByPackage: ReadonlyMap<string, readonly string[]>;
28
- /** Deduplicated @outfitter/* packages (uses lowest version for conflicts) */
29
- readonly packages: readonly WorkspacePackageEntry[];
30
- /** Workspace root directory (null if not a workspace) */
31
- readonly workspaceRoot: string | null;
32
- }
33
- /**
34
- * Walk up from `cwd` looking for a workspace root.
35
- *
36
- * Workspace root is identified by:
37
- * - `package.json` with a `workspaces` field (npm/yarn/bun)
38
- * - `pnpm-workspace.yaml` file
39
- *
40
- * Returns `null` (as Ok) if no workspace root found — this is not an error,
41
- * it means the project is a standalone package.
42
- */
43
- declare function detectWorkspaceRoot(cwd: string): Result<string | null, OutfitterError>;
44
- /**
45
- * Collect all package.json files from a workspace root directory.
46
- *
47
- * Reads workspace patterns from the root package.json, resolves globs,
48
- * and returns sorted absolute paths to all matching package.json files.
49
- * Always includes the root package.json itself.
50
- */
51
- declare function collectWorkspaceManifests(rootDir: string): Result<string[], OutfitterError>;
52
- /**
53
- * Scan all workspace manifests, collect @outfitter/* deps,
54
- * deduplicate, and detect version conflicts.
55
- *
56
- * For deduplication: when the same package appears at the same version
57
- * in multiple manifests, it appears once in the result.
58
- * When versions differ, the lowest version is used and a conflict is reported.
59
- */
60
- declare function getInstalledPackagesFromWorkspace(rootDir: string): Result<WorkspaceScanResult, OutfitterError>;
61
- /**
62
- * Apply version updates to all manifests in a workspace that contain
63
- * the specified @outfitter/* packages.
64
- *
65
- * Preserves the existing version range prefix (^, ~, >=, etc.) in each manifest.
66
- * Does NOT run `bun install` — the caller is responsible for that.
67
- */
68
- declare function applyUpdatesToWorkspace(manifestPaths: readonly string[], manifestsByPackage: ReadonlyMap<string, readonly string[]>, updates: readonly {
69
- name: string;
70
- latestVersion: string;
71
- }[]): Promise<Result<void, OutfitterError>>;
72
- /**
73
- * Run `bun install` at the given directory.
74
- */
75
- declare function runInstall(cwd: string): Promise<Result<void, OutfitterError>>;
76
- export { WorkspacePackageEntry, VersionConflict, WorkspaceScanResult, detectWorkspaceRoot, collectWorkspaceManifests, getInstalledPackagesFromWorkspace, applyUpdatesToWorkspace, runInstall };
@@ -1,170 +0,0 @@
1
- // @bun
2
- import {
3
- sanitizePackageName
4
- } from "./outfitter-4q1zfmvc.js";
5
- import {
6
- ScaffoldError
7
- } from "./outfitter-8y2dfx6n.js";
8
-
9
- // apps/outfitter/src/engine/workspace.ts
10
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
11
- import { dirname, join, resolve } from "path";
12
- import { Result } from "@outfitter/contracts";
13
- function deriveWorkspaceScopeForExamples(workspaceName) {
14
- const sanitized = sanitizePackageName(workspaceName);
15
- if (sanitized.startsWith("@")) {
16
- const separator = sanitized.indexOf("/");
17
- if (separator > 1) {
18
- return sanitized.slice(0, separator);
19
- }
20
- if (sanitized.length > 1) {
21
- return sanitized;
22
- }
23
- }
24
- if (sanitized.length > 0) {
25
- return `@${sanitized}`;
26
- }
27
- return "@your-scope";
28
- }
29
- function buildWorkspaceRootReadme(workspaceName) {
30
- const workspaceScope = deriveWorkspaceScopeForExamples(workspaceName);
31
- return `# ${workspaceName}
32
-
33
- ## Structure
34
-
35
- \`\`\`
36
- ${workspaceName}/
37
- \u251C\u2500\u2500 apps/ # Runnable applications (CLI, MCP, daemon, API)
38
- \u251C\u2500\u2500 packages/ # Shared libraries
39
- \u2514\u2500\u2500 package.json # Workspace root
40
- \`\`\`
41
-
42
- ## Getting Started
43
-
44
- \`\`\`bash
45
- # Install all dependencies
46
- bun install
47
-
48
- # Build all packages
49
- bun run build
50
-
51
- # Run tests
52
- bun run test
53
-
54
- # Typecheck
55
- bun run typecheck
56
- \`\`\`
57
-
58
- ## Adding Packages
59
-
60
- \`\`\`bash
61
- # Add a new app
62
- outfitter init --name ${workspaceScope}/my-app --preset cli
63
-
64
- # Add a shared library
65
- outfitter init --name ${workspaceScope}/my-lib --preset library
66
- \`\`\`
67
- `;
68
- }
69
- function buildWorkspaceRootPackageJson(workspaceName) {
70
- const workspacePackage = {
71
- name: workspaceName,
72
- private: true,
73
- version: "0.1.0",
74
- workspaces: ["apps/*", "packages/*"],
75
- scripts: {
76
- build: "bun run --filter '*' build",
77
- dev: "bun run --filter '*' dev",
78
- test: "bun run --filter '*' test",
79
- typecheck: "bun run --filter '*' typecheck",
80
- lint: "bun run --filter '*' lint",
81
- "lint:fix": "bun run --filter '*' lint:fix",
82
- format: "bun run --filter '*' format"
83
- }
84
- };
85
- return `${JSON.stringify(workspacePackage, null, 2)}
86
- `;
87
- }
88
- function scaffoldWorkspaceRoot(rootDir, workspaceName, force) {
89
- const packageJsonPath = join(rootDir, "package.json");
90
- if (existsSync(packageJsonPath) && !force) {
91
- return Result.err(new ScaffoldError(`Directory '${rootDir}' already has a package.json. Use --force to overwrite.`));
92
- }
93
- try {
94
- if (!existsSync(rootDir)) {
95
- mkdirSync(rootDir, { recursive: true });
96
- }
97
- mkdirSync(join(rootDir, "apps"), { recursive: true });
98
- mkdirSync(join(rootDir, "packages"), { recursive: true });
99
- writeFileSync(packageJsonPath, buildWorkspaceRootPackageJson(workspaceName), "utf-8");
100
- const readmePath = join(rootDir, "README.md");
101
- if (force || !existsSync(readmePath)) {
102
- writeFileSync(readmePath, buildWorkspaceRootReadme(workspaceName), "utf-8");
103
- }
104
- const gitignorePath = join(rootDir, ".gitignore");
105
- if (force || !existsSync(gitignorePath)) {
106
- writeFileSync(gitignorePath, `node_modules
107
- **/dist
108
- `, "utf-8");
109
- }
110
- return Result.ok(undefined);
111
- } catch (error) {
112
- const message = error instanceof Error ? error.message : "Unknown error";
113
- return Result.err(new ScaffoldError(`Failed to scaffold workspace root: ${message}`));
114
- }
115
- }
116
- function getWorkspacePatterns(workspaces) {
117
- if (Array.isArray(workspaces)) {
118
- return workspaces.filter((entry) => typeof entry === "string");
119
- }
120
- if (workspaces && typeof workspaces === "object" && !Array.isArray(workspaces)) {
121
- const packages = workspaces.packages;
122
- if (Array.isArray(packages)) {
123
- return packages.filter((entry) => typeof entry === "string");
124
- }
125
- }
126
- return [];
127
- }
128
- function hasWorkspacesField(pkg) {
129
- const workspaces = pkg.workspaces;
130
- if (Array.isArray(workspaces) && workspaces.length > 0) {
131
- return true;
132
- }
133
- if (workspaces && typeof workspaces === "object" && !Array.isArray(workspaces)) {
134
- const packages = workspaces.packages;
135
- if (Array.isArray(packages) && packages.length > 0) {
136
- return true;
137
- }
138
- }
139
- return false;
140
- }
141
- function detectWorkspaceRoot(cwd) {
142
- let current = resolve(cwd);
143
- const root = resolve("/");
144
- while (true) {
145
- if (existsSync(join(current, "pnpm-workspace.yaml"))) {
146
- return Result.ok(current);
147
- }
148
- const pkgPath = join(current, "package.json");
149
- if (existsSync(pkgPath)) {
150
- try {
151
- const raw = readFileSync(pkgPath, "utf-8");
152
- const pkg = JSON.parse(raw);
153
- if (hasWorkspacesField(pkg)) {
154
- return Result.ok(current);
155
- }
156
- } catch {}
157
- }
158
- if (current === root) {
159
- break;
160
- }
161
- const parent = dirname(current);
162
- if (parent === current) {
163
- break;
164
- }
165
- current = parent;
166
- }
167
- return Result.ok(null);
168
- }
169
-
170
- export { buildWorkspaceRootReadme, buildWorkspaceRootPackageJson, scaffoldWorkspaceRoot, getWorkspacePatterns, hasWorkspacesField, detectWorkspaceRoot };
@@ -1,29 +0,0 @@
1
- // @bun
2
- // apps/outfitter/src/engine/collector.ts
3
- class OperationCollector {
4
- operations = [];
5
- add(op) {
6
- this.operations.push(op);
7
- }
8
- getOperations() {
9
- return this.operations;
10
- }
11
- countByType() {
12
- const counts = {};
13
- for (const op of this.operations) {
14
- counts[op.type] = (counts[op.type] ?? 0) + 1;
15
- }
16
- return counts;
17
- }
18
- isEmpty() {
19
- return this.operations.length === 0;
20
- }
21
- toJSON() {
22
- return {
23
- operations: this.operations,
24
- summary: this.countByType()
25
- };
26
- }
27
- }
28
-
29
- export { OperationCollector };
@@ -1,35 +0,0 @@
1
- // @bun
2
- import {
3
- resolveTemplateDependencyVersions
4
- } from "./outfitter-m44n0qzw.js";
5
-
6
- // apps/outfitter/src/commands/shared-deps.ts
7
- var _dependencyVersions;
8
- function getDependencyVersions() {
9
- if (!_dependencyVersions) {
10
- _dependencyVersions = resolveTemplateDependencyVersions();
11
- }
12
- return _dependencyVersions;
13
- }
14
- function pickVersion(source, name, fallback) {
15
- return source[name] ?? fallback;
16
- }
17
- var SHARED_DEV_DEPS = {
18
- "@biomejs/biome": pickVersion(getDependencyVersions().external, "@biomejs/biome", "^2.4.4"),
19
- "@outfitter/tooling": pickVersion(getDependencyVersions().internal, "@outfitter/tooling", "^0.2.4"),
20
- "@types/bun": pickVersion(getDependencyVersions().external, "@types/bun", "^1.3.9"),
21
- lefthook: pickVersion(getDependencyVersions().external, "lefthook", "^2.1.1"),
22
- typescript: pickVersion(getDependencyVersions().external, "typescript", "^5.9.3"),
23
- ultracite: pickVersion(getDependencyVersions().external, "ultracite", "^7.2.3")
24
- };
25
- var SHARED_SCRIPTS = {
26
- check: "ultracite check",
27
- "clean:artifacts": "rm -rf dist .turbo",
28
- "verify:ci": "bun run typecheck && bun run check && bun run build && bun run test",
29
- lint: "biome check .",
30
- "lint:fix": "biome check . --write",
31
- format: "biome format --write .",
32
- typecheck: "tsc --noEmit"
33
- };
34
-
35
- export { SHARED_DEV_DEPS, SHARED_SCRIPTS };
@@ -1 +0,0 @@
1
- // @bun
@@ -1,154 +0,0 @@
1
- // @bun
2
- // apps/outfitter/src/engine/names.ts
3
- import { basename, isAbsolute, relative } from "path";
4
- function deriveProjectName(packageName) {
5
- const trimmed = packageName.trim();
6
- if (!trimmed.startsWith("@")) {
7
- return trimmed;
8
- }
9
- const scopeSeparator = trimmed.indexOf("/");
10
- if (scopeSeparator < 0) {
11
- return trimmed;
12
- }
13
- return trimmed.slice(scopeSeparator + 1).trim();
14
- }
15
- function deriveBinName(projectName) {
16
- return projectName.toLowerCase().replace(/\s+/g, "-");
17
- }
18
- function resolveAuthor() {
19
- const fromEnv = process.env["GIT_AUTHOR_NAME"] ?? process.env["GIT_COMMITTER_NAME"] ?? process.env["AUTHOR"] ?? process.env["USER"] ?? process.env["USERNAME"];
20
- if (fromEnv) {
21
- return fromEnv;
22
- }
23
- try {
24
- const result = Bun.spawnSync(["git", "config", "--get", "user.name"], {
25
- stdout: "pipe",
26
- stderr: "ignore"
27
- });
28
- if (result.exitCode === 0) {
29
- const value = result.stdout.toString().trim();
30
- return value.length > 0 ? value : "";
31
- }
32
- } catch {}
33
- return "";
34
- }
35
- function resolveYear() {
36
- return String(new Date().getFullYear());
37
- }
38
- function resolvePackageName(targetDir, name) {
39
- return name ?? basename(targetDir);
40
- }
41
- var WINDOWS_ABSOLUTE_PATH_RE = /^[a-zA-Z]:[\\/]/;
42
- var PACKAGE_SEGMENT_RE = /^[a-z0-9._-]+$/;
43
- var RESERVED_PACKAGE_NAMES = new Set(["node_modules", "favicon.ico"]);
44
- function validateProjectDirectoryName(name) {
45
- const trimmed = name.trim();
46
- if (trimmed.length === 0) {
47
- return "must not be empty";
48
- }
49
- if (trimmed === "." || trimmed === "..") {
50
- return "must not be '.' or '..'";
51
- }
52
- if (isAbsolute(trimmed) || WINDOWS_ABSOLUTE_PATH_RE.test(trimmed)) {
53
- return "must not be an absolute path";
54
- }
55
- if (trimmed.includes("/") || trimmed.includes("\\")) {
56
- return "must not contain path separators";
57
- }
58
- return;
59
- }
60
- function isPathWithin(basePath, targetPath) {
61
- const relativePath = relative(basePath, targetPath);
62
- if (relativePath === "") {
63
- return true;
64
- }
65
- if (isAbsolute(relativePath)) {
66
- return false;
67
- }
68
- const segments = relativePath.split(/[\\/]/);
69
- return !segments.includes("..");
70
- }
71
- function sanitizePackageSegment(value) {
72
- return value.trim().toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^[._-]+|[._-]+$/g, "");
73
- }
74
- function sanitizePackageName(name) {
75
- const trimmed = name.trim();
76
- if (trimmed.startsWith("@")) {
77
- const separator = trimmed.indexOf("/");
78
- if (separator > 1 && separator < trimmed.length - 1) {
79
- const scope = sanitizePackageSegment(trimmed.slice(1, separator));
80
- const pkg = sanitizePackageSegment(trimmed.slice(separator + 1));
81
- if (scope.length > 0 && pkg.length > 0) {
82
- return `@${scope}/${pkg}`;
83
- }
84
- if (pkg.length > 0) {
85
- return pkg;
86
- }
87
- if (scope.length > 0) {
88
- return scope;
89
- }
90
- return "";
91
- }
92
- }
93
- return sanitizePackageSegment(trimmed);
94
- }
95
- function validatePackageSegment(segment, kind) {
96
- if (segment.length === 0) {
97
- return `${kind} must not be empty`;
98
- }
99
- if (!PACKAGE_SEGMENT_RE.test(segment)) {
100
- return `${kind} contains invalid characters`;
101
- }
102
- if (kind === "name" && (segment.startsWith(".") || segment.startsWith("_"))) {
103
- return `${kind} must not start with '.' or '_'`;
104
- }
105
- return;
106
- }
107
- function validatePackageName(name) {
108
- const trimmed = name.trim();
109
- if (trimmed.length === 0) {
110
- return "must not be empty";
111
- }
112
- if (trimmed.length > 214) {
113
- return "must be 214 characters or fewer";
114
- }
115
- if (trimmed !== trimmed.toLowerCase()) {
116
- return "must be lowercase";
117
- }
118
- if (/\s/.test(trimmed)) {
119
- return "must not contain spaces";
120
- }
121
- if (trimmed.startsWith("@")) {
122
- const separator = trimmed.indexOf("/");
123
- if (separator <= 1 || separator === trimmed.length - 1) {
124
- return "scoped names must be in the form @scope/name";
125
- }
126
- if (trimmed.indexOf("/", separator + 1) !== -1) {
127
- return "scoped names must contain exactly one '/' separator";
128
- }
129
- const scope = trimmed.slice(1, separator);
130
- const pkg = trimmed.slice(separator + 1);
131
- const scopeError = validatePackageSegment(scope, "scope");
132
- if (scopeError) {
133
- return scopeError;
134
- }
135
- const nameError = validatePackageSegment(pkg, "name");
136
- if (nameError) {
137
- return nameError;
138
- }
139
- if (RESERVED_PACKAGE_NAMES.has(pkg)) {
140
- return `'${pkg}' is a reserved package name`;
141
- }
142
- return;
143
- }
144
- const segmentError = validatePackageSegment(trimmed, "name");
145
- if (segmentError) {
146
- return segmentError;
147
- }
148
- if (RESERVED_PACKAGE_NAMES.has(trimmed)) {
149
- return `'${trimmed}' is a reserved package name`;
150
- }
151
- return;
152
- }
153
-
154
- export { deriveProjectName, deriveBinName, resolveAuthor, resolveYear, resolvePackageName, validateProjectDirectoryName, isPathWithin, sanitizePackageName, validatePackageName };