forge-dev-framework 1.0.1

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 (140) hide show
  1. package/.claude/rules/api-patterns.md +98 -0
  2. package/.claude/rules/security-baseline.md +204 -0
  3. package/.claude/rules/testing-standards.md +177 -0
  4. package/.claude/rules/ui-conventions.md +142 -0
  5. package/README.md +261 -0
  6. package/bin/forge.js +14 -0
  7. package/dist/bin/forge.js +14 -0
  8. package/dist/cli/index.d.ts +22 -0
  9. package/dist/cli/index.d.ts.map +1 -0
  10. package/dist/cli/index.js +116 -0
  11. package/dist/cli/index.js.map +1 -0
  12. package/dist/commands/base.d.ts +31 -0
  13. package/dist/commands/base.d.ts.map +1 -0
  14. package/dist/commands/base.js +31 -0
  15. package/dist/commands/base.js.map +1 -0
  16. package/dist/commands/config.d.ts +14 -0
  17. package/dist/commands/config.d.ts.map +1 -0
  18. package/dist/commands/config.js +175 -0
  19. package/dist/commands/config.js.map +1 -0
  20. package/dist/commands/generate.d.ts +17 -0
  21. package/dist/commands/generate.d.ts.map +1 -0
  22. package/dist/commands/generate.js +159 -0
  23. package/dist/commands/generate.js.map +1 -0
  24. package/dist/commands/help.d.ts +11 -0
  25. package/dist/commands/help.d.ts.map +1 -0
  26. package/dist/commands/help.js +65 -0
  27. package/dist/commands/help.js.map +1 -0
  28. package/dist/commands/index.d.ts +8 -0
  29. package/dist/commands/index.d.ts.map +1 -0
  30. package/dist/commands/index.js +8 -0
  31. package/dist/commands/index.js.map +1 -0
  32. package/dist/commands/init.d.ts +10 -0
  33. package/dist/commands/init.d.ts.map +1 -0
  34. package/dist/commands/init.js +22 -0
  35. package/dist/commands/init.js.map +1 -0
  36. package/dist/commands/status.d.ts +13 -0
  37. package/dist/commands/status.d.ts.map +1 -0
  38. package/dist/commands/status.js +101 -0
  39. package/dist/commands/status.js.map +1 -0
  40. package/dist/commands/stubs.d.ts +14 -0
  41. package/dist/commands/stubs.d.ts.map +1 -0
  42. package/dist/commands/stubs.js +30 -0
  43. package/dist/commands/stubs.js.map +1 -0
  44. package/dist/generators/index.d.ts +11 -0
  45. package/dist/generators/index.d.ts.map +1 -0
  46. package/dist/generators/index.js +10 -0
  47. package/dist/generators/index.js.map +1 -0
  48. package/dist/generators/required-fields.d.ts +74 -0
  49. package/dist/generators/required-fields.d.ts.map +1 -0
  50. package/dist/generators/required-fields.js +179 -0
  51. package/dist/generators/required-fields.js.map +1 -0
  52. package/dist/generators/template-engine.d.ts +65 -0
  53. package/dist/generators/template-engine.d.ts.map +1 -0
  54. package/dist/generators/template-engine.js +209 -0
  55. package/dist/generators/template-engine.js.map +1 -0
  56. package/dist/generators/token-validator.d.ts +51 -0
  57. package/dist/generators/token-validator.d.ts.map +1 -0
  58. package/dist/generators/token-validator.js +141 -0
  59. package/dist/generators/token-validator.js.map +1 -0
  60. package/dist/generators/types.d.ts +433 -0
  61. package/dist/generators/types.d.ts.map +1 -0
  62. package/dist/generators/types.js +5 -0
  63. package/dist/generators/types.js.map +1 -0
  64. package/dist/generators/xml-task-generator.d.ts +67 -0
  65. package/dist/generators/xml-task-generator.d.ts.map +1 -0
  66. package/dist/generators/xml-task-generator.js +297 -0
  67. package/dist/generators/xml-task-generator.js.map +1 -0
  68. package/dist/git/__tests__/worktree.test.d.ts +5 -0
  69. package/dist/git/__tests__/worktree.test.d.ts.map +1 -0
  70. package/dist/git/__tests__/worktree.test.js +121 -0
  71. package/dist/git/__tests__/worktree.test.js.map +1 -0
  72. package/dist/git/codeowners.d.ts +101 -0
  73. package/dist/git/codeowners.d.ts.map +1 -0
  74. package/dist/git/codeowners.js +216 -0
  75. package/dist/git/codeowners.js.map +1 -0
  76. package/dist/git/commit.d.ts +135 -0
  77. package/dist/git/commit.d.ts.map +1 -0
  78. package/dist/git/commit.js +223 -0
  79. package/dist/git/commit.js.map +1 -0
  80. package/dist/git/hooks/commit-msg.d.ts +8 -0
  81. package/dist/git/hooks/commit-msg.d.ts.map +1 -0
  82. package/dist/git/hooks/commit-msg.js +34 -0
  83. package/dist/git/hooks/commit-msg.js.map +1 -0
  84. package/dist/git/hooks/pre-commit.d.ts +8 -0
  85. package/dist/git/hooks/pre-commit.d.ts.map +1 -0
  86. package/dist/git/hooks/pre-commit.js +34 -0
  87. package/dist/git/hooks/pre-commit.js.map +1 -0
  88. package/dist/git/pre-commit-hooks.d.ts +117 -0
  89. package/dist/git/pre-commit-hooks.d.ts.map +1 -0
  90. package/dist/git/pre-commit-hooks.js +270 -0
  91. package/dist/git/pre-commit-hooks.js.map +1 -0
  92. package/dist/git/wipe-protocol.d.ts +281 -0
  93. package/dist/git/wipe-protocol.d.ts.map +1 -0
  94. package/dist/git/wipe-protocol.js +237 -0
  95. package/dist/git/wipe-protocol.js.map +1 -0
  96. package/dist/git/worktree.d.ts +69 -0
  97. package/dist/git/worktree.d.ts.map +1 -0
  98. package/dist/git/worktree.js +202 -0
  99. package/dist/git/worktree.js.map +1 -0
  100. package/dist/scripts/install.d.ts +8 -0
  101. package/dist/scripts/install.d.ts.map +1 -0
  102. package/dist/scripts/install.js +161 -0
  103. package/dist/scripts/install.js.map +1 -0
  104. package/dist/types/config.d.ts +30 -0
  105. package/dist/types/config.d.ts.map +1 -0
  106. package/dist/types/config.js +23 -0
  107. package/dist/types/config.js.map +1 -0
  108. package/dist/types/index.d.ts +6 -0
  109. package/dist/types/index.d.ts.map +1 -0
  110. package/dist/types/index.js +6 -0
  111. package/dist/types/index.js.map +1 -0
  112. package/dist/types/state.d.ts +56 -0
  113. package/dist/types/state.d.ts.map +1 -0
  114. package/dist/types/state.js +6 -0
  115. package/dist/types/state.js.map +1 -0
  116. package/dist/utils/config.d.ts +15 -0
  117. package/dist/utils/config.d.ts.map +1 -0
  118. package/dist/utils/config.js +80 -0
  119. package/dist/utils/config.js.map +1 -0
  120. package/dist/utils/errors.d.ts +25 -0
  121. package/dist/utils/errors.d.ts.map +1 -0
  122. package/dist/utils/errors.js +48 -0
  123. package/dist/utils/errors.js.map +1 -0
  124. package/dist/utils/index.d.ts +11 -0
  125. package/dist/utils/index.d.ts.map +1 -0
  126. package/dist/utils/index.js +9 -0
  127. package/dist/utils/index.js.map +1 -0
  128. package/dist/utils/logger.d.ts +34 -0
  129. package/dist/utils/logger.d.ts.map +1 -0
  130. package/dist/utils/logger.js +73 -0
  131. package/dist/utils/logger.js.map +1 -0
  132. package/dist/utils/state-api.d.ts +128 -0
  133. package/dist/utils/state-api.d.ts.map +1 -0
  134. package/dist/utils/state-api.js +170 -0
  135. package/dist/utils/state-api.js.map +1 -0
  136. package/dist/utils/template-client.d.ts +73 -0
  137. package/dist/utils/template-client.d.ts.map +1 -0
  138. package/dist/utils/template-client.js +151 -0
  139. package/dist/utils/template-client.js.map +1 -0
  140. package/package.json +72 -0
@@ -0,0 +1,98 @@
1
+ # FORGE API Design Patterns
2
+
3
+ > **Scope:** Internal FORGE APIs and interfaces between components.
4
+
5
+ ## File Naming
6
+
7
+ - Use `kebab-case.ts` for files
8
+ - Use `PascalCase` for types, interfaces, classes
9
+ - Use `camelCase` for functions, variables
10
+
11
+ ## Module Structure
12
+
13
+ Each module exports:
14
+ 1. Types/interfaces first
15
+ 2. Functions/operations
16
+ 3. Constants at the end
17
+
18
+ ```typescript
19
+ // src/state/event-types.ts
20
+ export interface StateEvent { ... }
21
+ export interface TaskStartedEvent extends StateEvent { ... }
22
+
23
+ export function createEvent(type: EventType, payload: unknown): StateEvent { ... }
24
+
25
+ export const EVENT_TYPES = ['TASK_STARTED', 'TASK_COMPLETED', ...] as const;
26
+ ```
27
+
28
+ ## Error Handling
29
+
30
+ - Define custom error types extending `Error`
31
+ - Include error codes for programmatic handling
32
+ - Provide context in error messages
33
+
34
+ ```typescript
35
+ export class StateValidationError extends Error {
36
+ constructor(
37
+ public schema: string,
38
+ public errors: z.ZodError,
39
+ ) {
40
+ super(`State validation failed for ${schema}: ${errors.message}`);
41
+ this.name = 'StateValidationError';
42
+ }
43
+ }
44
+ ```
45
+
46
+ ## Async Operations
47
+
48
+ - Use `async/await`, not Promises directly
49
+ - Return typed promises: `Promise<T>`
50
+ - Handle rejections with try/catch
51
+
52
+ ```typescript
53
+ export async function loadState(path: string): Promise<State> {
54
+ try {
55
+ const content = await fs.readFile(path, 'utf-8');
56
+ return JSON.parse(content);
57
+ } catch (error) {
58
+ throw new StateLoadError(path, error);
59
+ }
60
+ }
61
+ ```
62
+
63
+ ## Input Validation
64
+
65
+ - Use Zod schemas for all public APIs
66
+ - Validate at module boundaries
67
+ - Return typed results, never `any`
68
+
69
+ ```typescript
70
+ import { z } from 'zod';
71
+
72
+ const EventSchema = z.object({
73
+ eventId: z.string(),
74
+ timestamp: z.string().datetime(),
75
+ taskId: z.string(),
76
+ actor: z.string(),
77
+ type: z.enum(EVENT_TYPES),
78
+ payload: z.unknown(),
79
+ });
80
+
81
+ export function parseEvent(data: unknown): StateEvent {
82
+ return EventSchema.parse(data);
83
+ }
84
+ ```
85
+
86
+ ## File I/O
87
+
88
+ - Use absolute paths from project root
89
+ - Check file existence before reading
90
+ - Use atomic writes (write to temp, then rename)
91
+
92
+ ```typescript
93
+ export async function writeState(path: string, state: State): Promise<void> {
94
+ const tmpPath = `${path}.tmp`;
95
+ await fs.writeFile(tmpPath, JSON.stringify(state, null, 2));
96
+ await fs.rename(tmpPath, path);
97
+ }
98
+ ```
@@ -0,0 +1,204 @@
1
+ # FORGE Security Baseline
2
+
3
+ > **Scope:** Input validation, secrets management, dependency security, file operations.
4
+
5
+ ## Input Validation
6
+
7
+ **All user input MUST be validated** with Zod schemas:
8
+
9
+ ```typescript
10
+ const ConfigSchema = z.object({
11
+ mode: z.enum(['yolo', 'interactive']),
12
+ depth: z.enum(['quick', 'standard', 'comprehensive']),
13
+ maxTeammates: z.number().int().min(2).max(6),
14
+ });
15
+
16
+ export function loadConfig(path: string): Config {
17
+ const raw = JSON.parse(fs.readFileSync(path, 'utf-8'));
18
+ return ConfigSchema.parse(raw);
19
+ }
20
+ ```
21
+
22
+ ### Path Validation
23
+
24
+ Prevent directory traversal:
25
+
26
+ ```typescript
27
+ import { resolve, normalize } from 'path';
28
+
29
+ export function safeJoin(base: string, userPath: string): string {
30
+ const resolved = resolve(base, userPath);
31
+ if (!resolved.startsWith(base)) {
32
+ throw new Error('Invalid path: outside base directory');
33
+ }
34
+ return resolved;
35
+ }
36
+ ```
37
+
38
+ ## Secrets Management
39
+
40
+ **NEVER hardcode secrets.** Use environment variables:
41
+
42
+ ```typescript
43
+ export function getApiKey(): string {
44
+ const key = process.env.FORGE_API_KEY;
45
+ if (!key) {
46
+ throw new Error('FORGE_API_KEY environment variable not set');
47
+ }
48
+ return key;
49
+ }
50
+ ```
51
+
52
+ ### Git Ignore
53
+
54
+ Add to `.gitignore`:
55
+
56
+ ```
57
+ # FORGE
58
+ state/events/*.json # Optional: don't commit event logs
59
+ .planning/local/ # User-specific config
60
+ .env # Environment variables
61
+ *.tmp # Temp files
62
+ ```
63
+
64
+ ## Command Injection Prevention
65
+
66
+ **NEVER pass user input directly to shell commands.** Use array arguments:
67
+
68
+ ```typescript
69
+ // BAD
70
+ await execa(`git checkout ${userBranch}`);
71
+
72
+ // GOOD
73
+ await execa('git', ['checkout', userBranch]);
74
+ ```
75
+
76
+ ## File Permissions
77
+
78
+ Respect user's umask, don't over-permission:
79
+
80
+ ```typescript
81
+ import { constants } from 'fs';
82
+
83
+ await fs.writeFile(path, content, {
84
+ mode: 0o644, // rw-r--r--
85
+ });
86
+ ```
87
+
88
+ For sensitive files:
89
+
90
+ ```typescript
91
+ await fs.writeFile(path, secrets, {
92
+ mode: 0o600, // rw-------
93
+ });
94
+ ```
95
+
96
+ ## Dependency Security
97
+
98
+ Run `npm audit` in CI:
99
+
100
+ ```yaml
101
+ # .github/workflows/ci.yml
102
+ - name: Audit dependencies
103
+ run: npm audit --audit-level=moderate
104
+ ```
105
+
106
+ ### Locked Dependencies
107
+
108
+ Commit `package-lock.json`. Always install with exact versions:
109
+
110
+ ```bash
111
+ npm ci # Use lock file, don't update
112
+ ```
113
+
114
+ ## Code Execution Safety
115
+
116
+ **NO `eval()`, no dynamic imports from untrusted sources:**
117
+
118
+ ```typescript
119
+ // BAD
120
+ const module = await import(userPath);
121
+
122
+ // GOOD — validate against whitelist
123
+ const ALLOWED = ['state', 'cli', 'templates'];
124
+ if (ALLOWED.includes(userPath)) {
125
+ const module = await import(`./${userPath}`);
126
+ }
127
+ ```
128
+
129
+ ## Event Log Integrity
130
+
131
+ Events should be **append-only**. Never modify existing events:
132
+
133
+ ```typescript
134
+ export async function writeEvent(path: string, event: StateEvent): Promise<void> {
135
+ if (await fs.pathExists(path)) {
136
+ throw new Error(`Event file already exists: ${path}`);
137
+ }
138
+ await fs.writeFile(path, JSON.stringify(event, null, 2), { mode: 0o444 }); // read-only
139
+ }
140
+ ```
141
+
142
+ ## State Validation
143
+
144
+ Validate `STATE.json` against schema on every read:
145
+
146
+ ```typescript
147
+ export async function loadState(path: string): Promise<State> {
148
+ const content = await fs.readFile(path, 'utf-8');
149
+ const raw = JSON.parse(content);
150
+ return StateSchema.parse(raw); // Zod validation
151
+ }
152
+ ```
153
+
154
+ ## Git Worktree Isolation
155
+
156
+ Ensure worktrees can't access each other's files:
157
+
158
+ ```typescript
159
+ export function validateWorktreePath(worktreePath: string): void {
160
+ if (!worktreePath.startsWith('.worktrees/')) {
161
+ throw new Error('Invalid worktree: must be under .worktrees/');
162
+ }
163
+ }
164
+ ```
165
+
166
+ ## Error Messages
167
+
168
+ **Don't leak sensitive info in errors:**
169
+
170
+ ```typescript
171
+ // BAD — leaks file path
172
+ throw new Error(`Failed to read ${filePath}`);
173
+
174
+ // GOOD — generic error
175
+ throw new Error('Failed to read configuration file');
176
+ ```
177
+
178
+ ## CI/CD Security
179
+
180
+ ```yaml
181
+ # .github/workflows/ci.yml
182
+ permissions:
183
+ contents: read # No write access
184
+ issues: read
185
+ pull-requests: read
186
+
187
+ - name: Run tests
188
+ run: npm test
189
+ ```
190
+
191
+ ## Third-Party Code
192
+
193
+ Review all dependencies before adding:
194
+
195
+ ```bash
196
+ npm audit
197
+ npm ls <package>
198
+ ```
199
+
200
+ Prefer well-maintained packages with:
201
+ - Active development
202
+ - Security policy
203
+ - TypeScript types
204
+ - Low dependency count
@@ -0,0 +1,177 @@
1
+ # FORGE Testing Standards
2
+
3
+ > **Scope:** Test coverage, test structure, what to test and how.
4
+
5
+ ## Test Structure
6
+
7
+ Place tests next to source files with `.test.ts` suffix:
8
+
9
+ ```
10
+ src/state/
11
+ event-types.ts
12
+ event-types.test.ts
13
+ src/cli/
14
+ init.ts
15
+ init.test.ts
16
+ ```
17
+
18
+ ## Unit Tests
19
+
20
+ Test **pure functions** and **business logic**:
21
+
22
+ ```typescript
23
+ // event-types.test.ts
24
+ import { describe, it, expect } from 'jest';
25
+ import { parseEvent, createEvent } from './event-types';
26
+
27
+ describe('parseEvent', () => {
28
+ it('parses valid TASK_STARTED event', () => {
29
+ const event = parseEvent({
30
+ eventId: 'evt-001',
31
+ timestamp: '2026-02-11T21:10:00Z',
32
+ taskId: 'api-003',
33
+ actor: 'backend',
34
+ type: 'TASK_STARTED',
35
+ payload: {},
36
+ });
37
+
38
+ expect(event.type).toBe('TASK_STARTED');
39
+ });
40
+
41
+ it('throws on missing eventId', () => {
42
+ expect(() => parseEvent({})).toThrow('eventId');
43
+ });
44
+
45
+ it('throws on invalid timestamp format', () => {
46
+ expect(() => parseEvent({
47
+ eventId: 'evt-001',
48
+ timestamp: 'invalid',
49
+ taskId: 'api-003',
50
+ actor: 'backend',
51
+ type: 'TASK_STARTED',
52
+ payload: {},
53
+ })).toThrow('timestamp');
54
+ });
55
+ });
56
+ ```
57
+
58
+ ## Integration Tests
59
+
60
+ Test **workflows end-to-end**:
61
+
62
+ ```typescript
63
+ // state-merge.integration.test.ts
64
+ describe('State Steward merge', () => {
65
+ const testDir = tmpdir();
66
+
67
+ beforeEach(async () => {
68
+ await fs.mkdir(`${testDir}/state/events`, { recursive: true });
69
+ });
70
+
71
+ it('merges events in timestamp order', async () => {
72
+ await writeEvent(`${testDir}/state/events/evt-002.json`, {
73
+ timestamp: '2026-02-11T21:11:00Z',
74
+ type: 'TASK_COMPLETED',
75
+ });
76
+ await writeEvent(`${testDir}/state/events/evt-001.json`, {
77
+ timestamp: '2026-02-11T21:10:00Z',
78
+ type: 'TASK_STARTED',
79
+ });
80
+
81
+ const state = await mergeEvents(testDir);
82
+
83
+ expect(state.tasks[0].status).toBe('completed');
84
+ });
85
+ });
86
+ ```
87
+
88
+ ## Coverage Targets
89
+
90
+ - **Core logic** (state, events, templates): >90%
91
+ - **CLI commands**: >70%
92
+ - **Git operations**: >80%
93
+
94
+ Run: `npm run test:coverage`
95
+
96
+ ## Test Data
97
+
98
+ Create fixtures in `test/fixtures/`:
99
+
100
+ ```
101
+ test/fixtures/
102
+ events/
103
+ task-started.json
104
+ task-completed.json
105
+ state/
106
+ initial-state.json
107
+ ```
108
+
109
+ ## Mocking
110
+
111
+ Mock external dependencies (git, fs, network):
112
+
113
+ ```typescript
114
+ import { jest } from '@jest/globals';
115
+
116
+ jest.mock('execa', () => ({
117
+ execa: jest.fn(),
118
+ }));
119
+
120
+ import { execa } from 'execa';
121
+
122
+ it('creates git worktree', async () => {
123
+ (execa as jest.Mock).mockResolvedValue({ stdout: '' });
124
+
125
+ await createWorktree('api-003', 'forge/api-003');
126
+
127
+ expect(execa).toHaveBeenCalledWith('git', [
128
+ 'worktree', 'add', '.worktrees/api-003', '-b', 'forge/api-003',
129
+ ]);
130
+ });
131
+ ```
132
+
133
+ ## Test Organization
134
+
135
+ Use `describe` for logical groups, `it` for individual tests:
136
+
137
+ ```typescript
138
+ describe('State Steward', () => {
139
+ describe('mergeEvents', () => {
140
+ it('handles empty event directory');
141
+ it('sorts events by timestamp');
142
+ it('handles duplicate eventIds');
143
+ it('skips malformed events');
144
+ });
145
+ });
146
+ ```
147
+
148
+ ## Async Tests
149
+
150
+ Always `await` async operations:
151
+
152
+ ```typescript
153
+ it('merges events', async () => {
154
+ const state = await mergeEvents('/path/to/events');
155
+ expect(state).toBeDefined();
156
+ });
157
+ ```
158
+
159
+ ## Clean Up
160
+
161
+ Use `beforeEach` / `afterEach` for test isolation:
162
+
163
+ ```typescript
164
+ import { tmpdir } from 'os';
165
+ import { rimraf } from 'rimraf';
166
+
167
+ let testDir: string;
168
+
169
+ beforeEach(async () => {
170
+ testDir = path.join(tmpdir(), `forge-test-${Date.now()}`);
171
+ await fs.mkdir(testDir, { recursive: true });
172
+ });
173
+
174
+ afterEach(async () => {
175
+ await rimraf(testDir);
176
+ });
177
+ ```
@@ -0,0 +1,142 @@
1
+ # FORGE CLI UI Conventions
2
+
3
+ > **Scope:** Command-line interface patterns, user interaction, output formatting.
4
+
5
+ ## Output Style
6
+
7
+ ### Success Messages
8
+
9
+ - Green checkmark emoji ✓
10
+ - Concise, clear
11
+ - Include what changed
12
+
13
+ ```bash
14
+ ✓ Created state/events/evt-001.json
15
+ ✓ Merged 12 events to STATE.json
16
+ ```
17
+
18
+ ### Error Messages
19
+
20
+ - Red ✗ or [ERROR] prefix
21
+ - What went wrong + why + how to fix
22
+ - Stack traces only in --debug mode
23
+
24
+ ```bash
25
+ ✗ Failed to merge events: Invalid event format in evt-003.json
26
+ → Run 'forge validate' to check event schemas
27
+ ```
28
+
29
+ ### Warning Messages
30
+
31
+ - Yellow ⚠ prefix
32
+ - Not blocking, but noteworthy
33
+
34
+ ```bash
35
+ ⚠ Task api-003 is blocked by api-001 (in_progress)
36
+ ```
37
+
38
+ ### Info Messages
39
+
40
+ - Blue → prefix for steps
41
+ - Show progress for long operations
42
+
43
+ ```bash
44
+ → Loading events from state/events/...
45
+ → Found 47 events, merging...
46
+ ```
47
+
48
+ ## Progress Indicators
49
+
50
+ For operations >2 seconds, show progress:
51
+
52
+ ```typescript
53
+ import ora from 'ora';
54
+
55
+ const spinner = ora('Initializing project...').start();
56
+ // ... work ...
57
+ spinner.succeed('Project initialized');
58
+ ```
59
+
60
+ ## Help Text Format
61
+
62
+ ```bash
63
+ forge init Initialize a new FORGE project
64
+
65
+ USAGE:
66
+ forge init [options]
67
+
68
+ OPTIONS:
69
+ --name <name> Project name (default: current directory)
70
+ --quick Skip interactive prompts (use defaults)
71
+
72
+ EXAMPLES:
73
+ $ forge init
74
+ $ forge init --name my-app --quick
75
+ ```
76
+
77
+ ## Interactive Prompts
78
+
79
+ When prompting users:
80
+ - Show current value in brackets: `[default: my-app]`
81
+ - Allow (y/N) confirmations
82
+ - Validate input before accepting
83
+
84
+ ```typescript
85
+ import inquirer from 'inquirer';
86
+
87
+ const answers = await inquirer.prompt([
88
+ {
89
+ type: 'input',
90
+ name: 'projectName',
91
+ message: 'Project name:',
92
+ default: path.basename(process.cwd()),
93
+ },
94
+ {
95
+ type: 'confirm',
96
+ name: 'confirm',
97
+ message: 'Initialize project?',
98
+ default: true,
99
+ },
100
+ ]);
101
+ ```
102
+
103
+ ## Tables and Lists
104
+
105
+ For structured output (status, tasks, events):
106
+
107
+ ```bash
108
+ CURRENT TASKS:
109
+
110
+ ID STATUS OWNER TITLE
111
+ ──────────────────────────────────────────────────────
112
+ api-001 completed backend User CRUD API
113
+ api-002 in_progress backend Auth service
114
+ ui-001 pending frontend Login form
115
+ ```
116
+
117
+ ## ASCII Art Banner
118
+
119
+ Show on startup:
120
+
121
+ ```bash
122
+ █ ██ ██
123
+ █ █ █ █ █ █
124
+ ███ █ █
125
+ ```
126
+
127
+ ## Exit Codes
128
+
129
+ - `0`: Success
130
+ - `1`: General error
131
+ - `2`: Invalid arguments
132
+ - `3`: State corruption
133
+ - `4`: Git error
134
+
135
+ ## Verbose Flag
136
+
137
+ Support `-v` / `--verbose` for debug output:
138
+
139
+ ```bash
140
+ forge merge -v
141
+ # → Shows detailed event replay, validation errors, etc.
142
+ ```