@outfitter/presets 0.2.0 → 0.3.0

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 (74) hide show
  1. package/README.md +30 -0
  2. package/dist/index.js +1 -1
  3. package/package.json +25 -24
  4. package/presets/_base/AGENTS.md.template +3 -0
  5. package/presets/_base/CLAUDE.md.template +35 -0
  6. package/presets/_examples/cli-todo/src/program.ts.template +202 -0
  7. package/presets/_examples/mcp-files/src/mcp.ts.template +181 -0
  8. package/presets/basic/.lefthook.yml.template +2 -2
  9. package/presets/basic/README.md.template +22 -0
  10. package/presets/basic/package.json.template +41 -37
  11. package/presets/basic/src/index.test.ts.template +26 -0
  12. package/presets/basic/src/index.ts.template +32 -15
  13. package/presets/basic/tsconfig.json.template +28 -29
  14. package/presets/cli/.lefthook.yml.template +2 -2
  15. package/presets/cli/CLAUDE.md.template +60 -0
  16. package/presets/cli/README.md.template +5 -1
  17. package/presets/cli/package.json.template +47 -44
  18. package/presets/cli/src/commands/hello.ts.template +26 -0
  19. package/presets/cli/src/index.test.ts.template +38 -0
  20. package/presets/cli/src/index.ts.template +2 -0
  21. package/presets/cli/src/program.ts.template +17 -19
  22. package/presets/cli/src/types.ts.template +13 -0
  23. package/presets/cli/tsconfig.json.template +29 -29
  24. package/presets/daemon/.lefthook.yml.template +2 -2
  25. package/presets/daemon/CLAUDE.md.template +53 -0
  26. package/presets/daemon/README.md.template +6 -7
  27. package/presets/daemon/package.json.template +50 -47
  28. package/presets/daemon/src/cli.ts.template +73 -66
  29. package/presets/daemon/src/daemon-main.ts.template +56 -55
  30. package/presets/daemon/src/daemon.ts.template +7 -3
  31. package/presets/daemon/src/index.test.ts.template +9 -0
  32. package/presets/daemon/tsconfig.json.template +21 -21
  33. package/presets/full-stack/CLAUDE.md.template +66 -0
  34. package/presets/full-stack/apps/cli/package.json.template +34 -33
  35. package/presets/full-stack/apps/cli/src/cli.ts.template +16 -15
  36. package/presets/full-stack/apps/cli/src/index.test.ts.template +12 -11
  37. package/presets/full-stack/apps/cli/tsconfig.json.template +32 -32
  38. package/presets/full-stack/apps/mcp/package.json.template +35 -34
  39. package/presets/full-stack/apps/mcp/src/index.test.ts.template +12 -11
  40. package/presets/full-stack/apps/mcp/src/mcp.ts.template +10 -10
  41. package/presets/full-stack/apps/mcp/src/server.ts.template +3 -2
  42. package/presets/full-stack/apps/mcp/tsconfig.json.template +32 -32
  43. package/presets/full-stack/package.json.template +20 -14
  44. package/presets/full-stack/packages/core/package.json.template +31 -30
  45. package/presets/full-stack/packages/core/src/handlers.ts.template +29 -24
  46. package/presets/full-stack/packages/core/src/index.test.ts.template +23 -21
  47. package/presets/full-stack/packages/core/src/types.ts.template +11 -8
  48. package/presets/full-stack/packages/core/tsconfig.json.template +29 -29
  49. package/presets/library/CLAUDE.md.template +68 -0
  50. package/presets/library/bunup.config.ts.template +16 -16
  51. package/presets/library/package.json.template +51 -50
  52. package/presets/library/src/handlers.ts.template +51 -27
  53. package/presets/library/src/index.test.ts.template +40 -29
  54. package/presets/library/src/types.ts.template +14 -8
  55. package/presets/library/tsconfig.json.template +29 -29
  56. package/presets/mcp/.lefthook.yml.template +2 -2
  57. package/presets/mcp/CLAUDE.md.template +97 -0
  58. package/presets/mcp/README.md.template +12 -9
  59. package/presets/mcp/package.json.template +48 -44
  60. package/presets/mcp/src/index.test.ts.template +49 -0
  61. package/presets/mcp/src/index.ts.template +2 -0
  62. package/presets/mcp/src/mcp.ts.template +16 -16
  63. package/presets/mcp/src/server.ts.template +8 -1
  64. package/presets/mcp/src/tools/hello.ts.template +48 -0
  65. package/presets/mcp/tsconfig.json.template +21 -21
  66. package/presets/minimal/.lefthook.yml.template +2 -2
  67. package/presets/minimal/README.md.template +22 -0
  68. package/presets/minimal/package.json.template +47 -44
  69. package/presets/minimal/src/index.test.ts.template +19 -0
  70. package/presets/minimal/src/index.ts.template +10 -15
  71. package/presets/minimal/tsconfig.json.template +28 -29
  72. package/presets/cli/biome.json.template +0 -4
  73. package/presets/daemon/biome.json.template +0 -4
  74. package/presets/mcp/biome.json.template +0 -4
@@ -1,49 +1,52 @@
1
1
  {
2
- "name": "{{packageName}}",
3
- "version": "{{version}}",
4
- "description": "{{description}}",
5
- "type": "module",
6
- "bin": {
7
- "{{binName}}": "./dist/cli.js",
8
- "{{binName}}d": "./dist/daemon.js"
9
- },
10
- "main": "./dist/index.js",
11
- "types": "./dist/index.d.ts",
12
- "exports": {
13
- ".": {
14
- "types": "./dist/index.d.ts",
15
- "import": "./dist/index.js"
16
- }
17
- },
18
- "scripts": {
19
- "build": "bun build src/cli.ts src/daemon.ts --outdir dist --target bun && bun build src/index.ts --outdir dist --target bun --sourcemap",
20
- "dev": "bun --watch src/daemon.ts -- --foreground",
21
- "dev:daemon": "bun --watch src/daemon.ts -- --foreground",
22
- "typecheck": "tsc --noEmit",
23
- "check": "ultracite check",
24
- "verify:ci": "bun run typecheck && bun run check && bun run build && bun run test",
25
- "test": "bun test",
26
- "test:watch": "bun test --watch",
27
- "lint": "biome check .",
28
- "lint:fix": "biome check . --write",
29
- "format": "biome format --write .",
30
- "clean:artifacts": "rm -rf dist .turbo"
31
- },
32
- "dependencies": {
33
- "@outfitter/contracts": "workspace:*",
34
- "@outfitter/types": "workspace:*",
35
- "@outfitter/daemon": "workspace:*",
36
- "@outfitter/cli": "workspace:*",
37
- "@outfitter/logging": "workspace:*",
38
- "commander": "^14.0.2"
39
- },
40
- "devDependencies": {},
41
- "outfitter": {
42
- "template": {
43
- "kind": "runnable",
44
- "placement": "apps",
45
- "surfaces": ["cli", "daemon"]
46
- }
47
- },
48
- "license": "MIT"
2
+ "name": "{{packageName}}",
3
+ "version": "{{version}}",
4
+ "description": "{{description}}",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "{{binName}}": "./dist/cli.js",
8
+ "{{binName}}d": "./dist/daemon.js"
9
+ },
10
+ "type": "module",
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ }
18
+ },
19
+ "scripts": {
20
+ "build": "bun build src/cli.ts src/daemon.ts --outdir dist --target bun && bun build src/index.ts --outdir dist --target bun --sourcemap",
21
+ "dev": "bun --watch src/daemon.ts -- --foreground",
22
+ "dev:daemon": "bun --watch src/daemon.ts -- --foreground",
23
+ "typecheck": "tsc --noEmit",
24
+ "check": "ultracite check",
25
+ "verify:ci": "bun run typecheck && bun run check && bun run build && bun run test",
26
+ "test": "bun test",
27
+ "test:watch": "bun test --watch",
28
+ "lint": "oxlint .",
29
+ "lint:fix": "oxlint --fix .",
30
+ "format": "oxfmt --write .",
31
+ "clean:artifacts": "rm -rf dist .turbo"
32
+ },
33
+ "dependencies": {
34
+ "@outfitter/cli": "workspace:*",
35
+ "@outfitter/contracts": "workspace:*",
36
+ "@outfitter/daemon": "workspace:*",
37
+ "@outfitter/logging": "workspace:*",
38
+ "@outfitter/types": "workspace:*",
39
+ "commander": "catalog:"
40
+ },
41
+ "devDependencies": {},
42
+ "outfitter": {
43
+ "template": {
44
+ "kind": "runnable",
45
+ "placement": "apps",
46
+ "surfaces": [
47
+ "cli",
48
+ "daemon"
49
+ ]
50
+ }
51
+ }
49
52
  }
@@ -2,13 +2,14 @@
2
2
  /**
3
3
  * {{projectName}} CLI entry point
4
4
  *
5
- * Commands: start, stop, restart, status
5
+ * Commands: start, stop, status
6
6
  */
7
7
 
8
- import { createCLI, command } from "@outfitter/cli";
9
- import { createLogger } from "@outfitter/logging";
10
8
  import { spawn } from "node:child_process";
9
+
10
+ import { createCLI, command } from "@outfitter/cli/command";
11
11
  import { getSocketPath, getLockPath, isDaemonAlive } from "@outfitter/daemon";
12
+ import { createLogger } from "@outfitter/logging";
12
13
 
13
14
  const logger = createLogger({ name: "{{binName}}" });
14
15
 
@@ -17,80 +18,86 @@ const socketPath = getSocketPath(TOOL_NAME);
17
18
  const lockPath = getLockPath(TOOL_NAME);
18
19
 
19
20
  const program = createCLI({
20
- name: "{{binName}}",
21
- version: "{{version}}",
22
- description: "{{description}}",
21
+ name: "{{binName}}",
22
+ version: "{{version}}",
23
+ description: "{{description}}",
23
24
  });
24
25
 
25
26
  program.register(
26
- command("start")
27
- .description("Start the daemon")
28
- .option("-f, --foreground", "Run in foreground")
29
- .action(async ({ flags }) => {
30
- const foreground = Boolean((flags as { foreground?: boolean }).foreground);
27
+ command("start")
28
+ .description("Start the daemon")
29
+ .option("-f, --foreground", "Run in foreground")
30
+ .action(async ({ flags }) => {
31
+ const foreground = Boolean(
32
+ (flags as { foreground?: boolean }).foreground
33
+ );
31
34
 
32
- if (await isDaemonAlive(lockPath)) {
33
- logger.warn`Daemon is already running`;
34
- process.exit(1);
35
- }
35
+ if (await isDaemonAlive(lockPath)) {
36
+ logger.warn("Daemon is already running");
37
+ process.exit(1);
38
+ }
36
39
 
37
- if (foreground) {
38
- // Run in foreground - import and run daemon directly
39
- const { runDaemon } = await import("./daemon-main.js");
40
- await runDaemon();
41
- } else {
42
- // Spawn daemon in background
43
- const daemon = spawn(process.execPath, [import.meta.dir + "/daemon.js"], {
44
- detached: true,
45
- stdio: "ignore",
46
- });
47
- daemon.unref();
48
- logger.info`Daemon started with PID ${daemon.pid}`;
49
- }
50
- }),
40
+ if (foreground) {
41
+ // Run in foreground - import and run daemon directly
42
+ const { runDaemon } = await import("./daemon-main.js");
43
+ await runDaemon();
44
+ } else {
45
+ // Spawn daemon in background
46
+ const daemon = spawn(
47
+ process.execPath,
48
+ [import.meta.dir + "/daemon.js"],
49
+ {
50
+ detached: true,
51
+ stdio: "ignore",
52
+ }
53
+ );
54
+ daemon.unref();
55
+ logger.info(`Daemon started with PID ${daemon.pid}`);
56
+ }
57
+ })
51
58
  );
52
59
 
53
60
  program.register(
54
- command("stop")
55
- .description("Stop the daemon")
56
- .action(async () => {
57
- if (!(await isDaemonAlive(lockPath))) {
58
- logger.warn`Daemon is not running`;
59
- process.exit(1);
60
- }
61
- // Signal daemon to stop via HTTP
62
- try {
63
- const response = await fetch(`http://unix:${socketPath}:/shutdown`, {
64
- method: "POST",
65
- });
66
- if (response.ok) {
67
- logger.info`Daemon stopped`;
68
- }
69
- } catch {
70
- logger.error`Failed to stop daemon`;
71
- process.exit(1);
72
- }
73
- }),
61
+ command("stop")
62
+ .description("Stop the daemon")
63
+ .action(async () => {
64
+ if (!(await isDaemonAlive(lockPath))) {
65
+ logger.warn("Daemon is not running");
66
+ process.exit(1);
67
+ }
68
+ // Signal daemon to stop via HTTP
69
+ try {
70
+ const response = await fetch(`http://unix:${socketPath}:/shutdown`, {
71
+ method: "POST",
72
+ });
73
+ if (response.ok) {
74
+ logger.info("Daemon stopped");
75
+ }
76
+ } catch {
77
+ logger.error("Failed to stop daemon");
78
+ process.exit(1);
79
+ }
80
+ })
74
81
  );
75
82
 
76
83
  program.register(
77
- command("status")
78
- .description("Check daemon status")
79
- .action(async () => {
80
- if (await isDaemonAlive(lockPath)) {
81
- logger.info`Daemon is running`;
82
- // Fetch health info
83
- try {
84
- const response = await fetch(`http://unix:${socketPath}:/health`);
85
- const health = await response.json();
86
- console.log(JSON.stringify(health, null, 2));
87
- } catch {
88
- logger.warn`Could not fetch health info`;
89
- }
90
- } else {
91
- logger.info`Daemon is not running`;
92
- }
93
- }),
84
+ command("status")
85
+ .description("Check daemon status")
86
+ .action(async () => {
87
+ if (await isDaemonAlive(lockPath)) {
88
+ logger.info("Daemon is running");
89
+ // Fetch health info
90
+ try {
91
+ const response = await fetch(`http://unix:${socketPath}:/health`);
92
+ const health = await response.json();
93
+ console.log(JSON.stringify(health, null, 2));
94
+ } catch {
95
+ logger.warn("Could not fetch health info");
96
+ }
97
+ } else {
98
+ logger.info("Daemon is not running");
99
+ }
100
+ })
94
101
  );
95
102
 
96
103
  program.parse(process.argv);
@@ -2,15 +2,16 @@
2
2
  * {{projectName}} daemon main logic
3
3
  */
4
4
 
5
- import { createLogger } from "@outfitter/logging";
5
+ import { mkdir } from "node:fs/promises";
6
+
6
7
  import {
7
- getSocketPath,
8
- getLockPath,
9
- getDaemonDir,
10
- acquireDaemonLock,
11
- releaseDaemonLock,
8
+ getSocketPath,
9
+ getLockPath,
10
+ getDaemonDir,
11
+ acquireDaemonLock,
12
+ releaseDaemonLock,
12
13
  } from "@outfitter/daemon";
13
- import { mkdir } from "node:fs/promises";
14
+ import { createLogger } from "@outfitter/logging";
14
15
 
15
16
  const logger = createLogger({ name: "{{binName}}d" });
16
17
 
@@ -18,62 +19,62 @@ const TOOL_NAME = "{{binName}}";
18
19
  const startTime = Date.now();
19
20
 
20
21
  export async function runDaemon(): Promise<void> {
21
- const socketPath = getSocketPath(TOOL_NAME);
22
- const lockPath = getLockPath(TOOL_NAME);
23
- const daemonDir = getDaemonDir(TOOL_NAME);
22
+ const socketPath = getSocketPath(TOOL_NAME);
23
+ const lockPath = getLockPath(TOOL_NAME);
24
+ const daemonDir = getDaemonDir(TOOL_NAME);
24
25
 
25
- // Ensure daemon directory exists
26
- await mkdir(daemonDir, { recursive: true });
26
+ // Ensure daemon directory exists
27
+ await mkdir(daemonDir, { recursive: true });
27
28
 
28
- // Acquire lock
29
- const lockResult = await acquireDaemonLock(lockPath);
30
- if (!lockResult.isOk()) {
31
- logger.error`Failed to acquire lock: ${lockResult.error.message}`;
32
- process.exit(1);
33
- }
34
- const lock = lockResult.value;
29
+ // Acquire lock
30
+ const lockResult = await acquireDaemonLock(lockPath);
31
+ if (!lockResult.isOk()) {
32
+ logger.error(`Failed to acquire lock: ${lockResult.error.message}`);
33
+ process.exit(1);
34
+ }
35
+ const lock = lockResult.value;
35
36
 
36
- logger.info`Daemon starting on ${socketPath}`;
37
+ logger.info(`Daemon starting on ${socketPath}`);
37
38
 
38
- // Create HTTP server on Unix socket
39
- const server = Bun.serve({
40
- unix: socketPath,
41
- fetch(request) {
42
- const url = new URL(request.url);
39
+ // Create HTTP server on Unix socket
40
+ const server = Bun.serve({
41
+ unix: socketPath,
42
+ fetch(request) {
43
+ const url = new URL(request.url);
43
44
 
44
- if (url.pathname === "/health") {
45
- return Response.json({
46
- status: "ok",
47
- uptime: Date.now() - startTime,
48
- version: "{{version}}",
49
- });
50
- }
45
+ if (url.pathname === "/health") {
46
+ return Response.json({
47
+ status: "ok",
48
+ uptime: Date.now() - startTime,
49
+ version: "{{version}}",
50
+ });
51
+ }
51
52
 
52
- if (url.pathname === "/shutdown" && request.method === "POST") {
53
- logger.info`Shutdown requested`;
54
- // Schedule shutdown
55
- setTimeout(async () => {
56
- await releaseDaemonLock(lock);
57
- server.stop();
58
- process.exit(0);
59
- }, 100);
60
- return new Response("Shutting down");
61
- }
53
+ if (url.pathname === "/shutdown" && request.method === "POST") {
54
+ logger.info("Shutdown requested");
55
+ // Schedule shutdown
56
+ setTimeout(async () => {
57
+ await releaseDaemonLock(lock);
58
+ server.stop();
59
+ process.exit(0);
60
+ }, 100);
61
+ return new Response("Shutting down");
62
+ }
62
63
 
63
- return new Response("Not found", { status: 404 });
64
- },
65
- });
64
+ return new Response("Not found", { status: 404 });
65
+ },
66
+ });
66
67
 
67
- // Handle signals
68
- const shutdown = async () => {
69
- logger.info`Received shutdown signal`;
70
- await releaseDaemonLock(lock);
71
- server.stop();
72
- process.exit(0);
73
- };
68
+ // Handle signals
69
+ const shutdown = async () => {
70
+ logger.info("Received shutdown signal");
71
+ await releaseDaemonLock(lock);
72
+ server.stop();
73
+ process.exit(0);
74
+ };
74
75
 
75
- process.on("SIGTERM", shutdown);
76
- process.on("SIGINT", shutdown);
76
+ process.on("SIGTERM", shutdown);
77
+ process.on("SIGINT", shutdown);
77
78
 
78
- logger.info`Daemon running`;
79
+ logger.info("Daemon running");
79
80
  }
@@ -3,9 +3,13 @@
3
3
  * {{projectName}} daemon entry point
4
4
  */
5
5
 
6
+ import { createLogger } from "@outfitter/logging";
7
+
6
8
  import { runDaemon } from "./daemon-main.js";
7
9
 
8
- runDaemon().catch((error) => {
9
- console.error("Daemon failed:", error);
10
- process.exit(1);
10
+ const logger = createLogger({ name: "{{binName}}d" });
11
+
12
+ runDaemon().catch((error: unknown) => {
13
+ logger.error("Daemon failed", { error });
14
+ process.exit(1);
11
15
  });
@@ -0,0 +1,9 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import { runDaemon } from "./index.js";
4
+
5
+ describe("daemon", () => {
6
+ test("exports the daemon entrypoint", () => {
7
+ expect(typeof runDaemon).toBe("function");
8
+ });
9
+ });
@@ -1,23 +1,23 @@
1
1
  {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "strict": true,
7
- "esModuleInterop": true,
8
- "verbatimModuleSyntax": true,
9
- "skipLibCheck": true,
10
- "declaration": true,
11
- "declarationDir": "dist",
12
- "outDir": "dist",
13
- "rootDir": "src",
14
- "types": ["bun-types"],
15
- "noImplicitAny": true,
16
- "strictNullChecks": true,
17
- "noUncheckedIndexedAccess": true,
18
- "exactOptionalPropertyTypes": true,
19
- "noPropertyAccessFromIndexSignature": true
20
- },
21
- "include": ["src"],
22
- "exclude": ["node_modules", "dist"]
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "verbatimModuleSyntax": true,
9
+ "skipLibCheck": true,
10
+ "declaration": true,
11
+ "declarationDir": "dist",
12
+ "outDir": "dist",
13
+ "rootDir": "src",
14
+ "types": ["bun-types"],
15
+ "noImplicitAny": true,
16
+ "strictNullChecks": true,
17
+ "noUncheckedIndexedAccess": true,
18
+ "exactOptionalPropertyTypes": true,
19
+ "noPropertyAccessFromIndexSignature": true
20
+ },
21
+ "include": ["src"],
22
+ "exclude": ["node_modules", "dist"]
23
23
  }
@@ -0,0 +1,66 @@
1
+ # CLAUDE.md
2
+
3
+ Bun-first TypeScript monorepo. Tests before code. Result types, not exceptions.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ # Root (all packages)
9
+ bun run build # Build all packages (Bun workspaces)
10
+ bun run dev # Dev mode for all packages
11
+ bun run test # Test all packages
12
+ bun run typecheck # TypeScript validation
13
+ bun run check # Lint checks (all packages)
14
+ bun run lint:fix # Auto-fix lint issues (all packages)
15
+ bun run format # Auto-fix formatting (all packages)
16
+ bun run verify:ci # Full CI validation (typecheck + check + build + test)
17
+
18
+ # Single package
19
+ bun run --filter={{packageName}}-core build
20
+ bun run --filter={{packageName}}-core test
21
+ cd packages/core && bun test
22
+ ```
23
+
24
+ ## Architecture
25
+
26
+ Monorepo with shared core library, CLI app, and MCP server.
27
+
28
+ ### Project Structure
29
+
30
+ - `packages/core/` — Shared handlers and types (library)
31
+ - `apps/cli/` — CLI application (thin adapter over core handlers)
32
+ - `apps/mcp/` — MCP server (thin adapter over core handlers)
33
+
34
+ ### Handler Contract
35
+
36
+ All domain logic lives in `packages/core/` as transport-agnostic handlers returning `Result<T, E>`:
37
+
38
+ ```typescript
39
+ async function handler(
40
+ input: unknown,
41
+ ctx: HandlerContext
42
+ ): Promise<Result<Output, ValidationError>>;
43
+ ```
44
+
45
+ CLI and MCP are thin adapters over shared handlers. Write the handler once in core, expose it everywhere.
46
+
47
+ ### Adding a Feature
48
+
49
+ 1. Define types and Zod schema in `packages/core/src/types.ts`
50
+ 2. Implement handler in `packages/core/src/handlers.ts` returning `Result<T, E>`
51
+ 3. Add tests in `packages/core/src/<name>.test.ts`
52
+ 4. Wire CLI command in `apps/cli/src/` using CommandBuilder
53
+ 5. Wire MCP tool in `apps/mcp/src/` using `defineTool()`
54
+
55
+ ## Development Principles
56
+
57
+ - **TDD-First** — Write the test before the code (Red / Green / Refactor)
58
+ - **Result Types** — Handlers return `Result<T, E>`, not exceptions
59
+ - **Bun-First** — Use Bun-native APIs before npm packages
60
+ - **Strict TypeScript** — No `any`, no `as` casts; narrow instead of assert
61
+
62
+ ## Testing
63
+
64
+ - Runner: Bun test runner
65
+ - Files: `src/*.test.ts` within each package
66
+ - Run: `bun test` (per package) or `bun run test` (all packages from root)
@@ -1,35 +1,36 @@
1
1
  {
2
- "name": "{{packageName}}-cli",
3
- "version": "{{version}}",
4
- "description": "CLI surface for {{projectName}}",
5
- "type": "module",
6
- "bin": {
7
- "{{projectName}}": "./dist/cli.js"
8
- },
9
- "main": "./dist/index.js",
10
- "types": "./dist/index.d.ts",
11
- "exports": {
12
- ".": {
13
- "types": "./dist/index.d.ts",
14
- "import": "./dist/index.js"
15
- }
16
- },
17
- "scripts": {
18
- "build": "bun build src/cli.ts --outdir dist --target bun && bun build src/index.ts --outdir dist --target bun --sourcemap",
19
- "dev": "bun --watch src/cli.ts",
20
- "test": "bun test",
21
- "test:watch": "bun test --watch",
22
- "typecheck": "tsc --noEmit",
23
- "lint": "biome check .",
24
- "lint:fix": "biome check . --write",
25
- "format": "biome format --write .",
26
- "clean:artifacts": "rm -rf dist .turbo"
27
- },
28
- "dependencies": {
29
- "{{packageName}}-core": "workspace:*",
30
- "@outfitter/cli": "workspace:*",
31
- "@outfitter/contracts": "workspace:*"
32
- },
33
- "devDependencies": {},
34
- "license": "MIT"
2
+ "name": "{{packageName}}-cli",
3
+ "version": "{{version}}",
4
+ "description": "CLI surface for {{projectName}}",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "{{projectName}}": "./dist/cli.js"
8
+ },
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "bun build src/cli.ts --outdir dist --target bun && bun build src/index.ts --outdir dist --target bun --sourcemap",
20
+ "dev": "bun --watch src/cli.ts",
21
+ "test": "bun test",
22
+ "test:watch": "bun test --watch",
23
+ "typecheck": "tsc --noEmit",
24
+ "lint": "oxlint .",
25
+ "lint:fix": "oxlint --fix .",
26
+ "format": "oxfmt --write .",
27
+ "check": "ultracite check",
28
+ "clean:artifacts": "rm -rf dist .turbo"
29
+ },
30
+ "dependencies": {
31
+ "@outfitter/cli": "workspace:*",
32
+ "@outfitter/contracts": "workspace:*",
33
+ "{{packageName}}-core": "workspace:*"
34
+ },
35
+ "devDependencies": {}
35
36
  }