flight-rules 0.13.9 → 0.15.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.
package/README.md CHANGED
@@ -110,6 +110,8 @@ Flight Rules provides workflow commands that agents can execute:
110
110
  | `/prd.reconcile` | Update PRD based on what was actually built |
111
111
  | `/impl.reconcile` | Update implementation docs with status changes |
112
112
  | `/docs.reconcile` | Run all reconcile commands + consistency check |
113
+ | `/parallel.status` | Show all active parallel sessions |
114
+ | `/parallel.cleanup` | Clean up orphaned parallel sessions |
113
115
 
114
116
  ### Versioning
115
117
 
@@ -199,6 +201,63 @@ your-project/
199
201
  | `flight-rules adapter` | Generate agent-specific adapters (`--cursor`, `--claude`) |
200
202
  | `flight-rules update` | Update the Flight Rules CLI itself (`--channel` to switch dev/latest) |
201
203
  | `flight-rules ralph` | Run autonomous agent loop through task groups |
204
+ | `flight-rules parallel` | Manage parallel dev sessions with git worktrees |
205
+
206
+ ---
207
+
208
+ ## Parallel Dev Sessions
209
+
210
+ Flight Rules supports running multiple AI agents on the same project simultaneously using **git worktrees**. Each parallel session gets its own isolated directory and branch, so agents don't interfere with each other.
211
+
212
+ ### How It Works
213
+
214
+ 1. **Create a session** — `flight-rules parallel create <name>` creates a new worktree in a sibling directory (`../<project>-sessions/<name>/`) with a dedicated `session/<name>` branch
215
+ 2. **Work in isolation** — Open a new terminal, `cd` into the worktree, and run your AI agent. All file changes happen in the isolated directory
216
+ 3. **Track sessions** — `flight-rules parallel status` shows all active sessions, their branches, and ages
217
+ 4. **Integrate changes** — When done, `flight-rules parallel remove <name>` offers merge strategies: create a PR, merge directly, keep the branch, or abandon
218
+ 5. **Clean up** — `flight-rules parallel cleanup` detects orphaned sessions (e.g., from crashed terminals) and removes them
219
+
220
+ ### Session Directory Layout
221
+
222
+ ```
223
+ /my-project ← main working directory
224
+ /my-project-sessions/ ← parallel session worktrees
225
+ ├── auth-refactor/ ← Session A's worktree
226
+ ├── api-endpoints/ ← Session B's worktree
227
+ └── .manifest.json ← tracks active sessions
228
+ ```
229
+
230
+ ### Commands
231
+
232
+ ```bash
233
+ # Create a new parallel session
234
+ flight-rules parallel create auth-refactor
235
+
236
+ # See all active sessions
237
+ flight-rules parallel status
238
+
239
+ # End a session (offers merge workflow)
240
+ flight-rules parallel remove auth-refactor
241
+
242
+ # Clean up orphaned sessions
243
+ flight-rules parallel cleanup
244
+
245
+ # Skip confirmations
246
+ flight-rules parallel cleanup --force
247
+ flight-rules parallel remove auth-refactor --force
248
+ ```
249
+
250
+ ### Integration with Dev Sessions
251
+
252
+ The `/dev-session.start` command offers a parallel session option after establishing goals. When ending a session in a worktree, `/dev-session.end` automatically offers the merge workflow.
253
+
254
+ ### Features
255
+
256
+ - **Session manifest** — JSON file tracking all active sessions with metadata
257
+ - **Env file copying** — Automatically copies `.env`, `.env.local`, `.env.development.local` to new worktrees
258
+ - **Orphan detection** — Detects sessions where the worktree was removed without proper cleanup
259
+ - **Merge conflict awareness** — Warns when the base branch has diverged since the session started
260
+ - **Worktree validation** — Prevents creating nested parallel sessions
202
261
 
203
262
  ---
204
263
 
@@ -365,6 +424,7 @@ Tests are located in `tests/` and mirror the `src/` structure:
365
424
  | `tests/commands/init.test.ts` | 98.5% |
366
425
  | `tests/commands/upgrade.test.ts` | 100% |
367
426
  | `tests/commands/adapter.test.ts` | 79% |
427
+ | `tests/commands/parallel.test.ts` | New |
368
428
 
369
429
  ### Releasing
370
430
 
@@ -15,6 +15,7 @@ async function copyDocsFromTemplates(templatesDir, docsDir, skipExisting) {
15
15
  ensureDir(docsDir);
16
16
  ensureDir(join(docsDir, 'implementation'));
17
17
  ensureDir(join(docsDir, 'session_logs'));
18
+ ensureDir(join(docsDir, 'backlog'));
18
19
  for (const file of DOC_FILES) {
19
20
  const srcPath = join(templatesDir, file.src);
20
21
  const destPath = join(docsDir, file.dest);
@@ -0,0 +1,104 @@
1
+ export interface SessionEntry {
2
+ id: string;
3
+ branch: string;
4
+ worktree: string;
5
+ startedAt: string;
6
+ goals: string[];
7
+ status: 'active' | 'completed' | 'abandoned';
8
+ }
9
+ export interface SessionManifest {
10
+ version: number;
11
+ project: string;
12
+ sessions: SessionEntry[];
13
+ }
14
+ export interface ParallelOptions {
15
+ force?: boolean;
16
+ }
17
+ /**
18
+ * Run a git command and return the result
19
+ */
20
+ export declare function runGitCommand(args: string[], cwd?: string): Promise<{
21
+ success: boolean;
22
+ output: string;
23
+ error: string;
24
+ }>;
25
+ /**
26
+ * Check if git working directory is clean
27
+ */
28
+ export declare function isGitClean(cwd?: string): Promise<boolean>;
29
+ /**
30
+ * Check if the current directory is inside a git worktree (not the main working tree)
31
+ */
32
+ export declare function isInsideWorktree(cwd?: string): Promise<boolean>;
33
+ /**
34
+ * Get list of git worktrees
35
+ */
36
+ export declare function listGitWorktrees(cwd?: string): Promise<Array<{
37
+ path: string;
38
+ branch: string;
39
+ bare: boolean;
40
+ }>>;
41
+ /**
42
+ * Get the number of commits the base branch is ahead of the session branch point
43
+ */
44
+ export declare function getCommitsAhead(baseBranch: string, sessionBranch: string, cwd?: string): Promise<number>;
45
+ /**
46
+ * Get the current branch name
47
+ */
48
+ export declare function getCurrentBranch(cwd?: string): Promise<string>;
49
+ /**
50
+ * Get the sessions directory path for a project
51
+ */
52
+ export declare function getSessionsDir(projectDir: string): string;
53
+ /**
54
+ * Get the manifest file path
55
+ */
56
+ export declare function getManifestPath(projectDir: string): string;
57
+ /**
58
+ * Read the session manifest, returning null if not found or invalid
59
+ */
60
+ export declare function readSessionManifest(projectDir: string): SessionManifest | null;
61
+ /**
62
+ * Write the session manifest
63
+ */
64
+ export declare function writeSessionManifest(projectDir: string, manifest: SessionManifest): void;
65
+ /**
66
+ * Create an empty manifest for a project
67
+ */
68
+ export declare function createEmptyManifest(projectDir: string): SessionManifest;
69
+ /**
70
+ * Add a session to the manifest
71
+ */
72
+ export declare function addSessionToManifest(projectDir: string, session: SessionEntry): SessionManifest;
73
+ /**
74
+ * Remove a session from the manifest by ID
75
+ */
76
+ export declare function removeSessionFromManifest(projectDir: string, sessionId: string): SessionManifest | null;
77
+ /**
78
+ * Copy common environment files from source to destination
79
+ */
80
+ export declare function copyEnvFiles(sourceDir: string, destDir: string): string[];
81
+ /**
82
+ * Format a relative time string from an ISO date
83
+ */
84
+ export declare function formatRelativeTime(isoDate: string): string;
85
+ /**
86
+ * Create a new parallel session
87
+ */
88
+ export declare function parallelCreate(sessionName: string, goals?: string[]): Promise<void>;
89
+ /**
90
+ * Show status of all parallel sessions
91
+ */
92
+ export declare function parallelStatus(): Promise<void>;
93
+ /**
94
+ * Clean up orphaned parallel sessions
95
+ */
96
+ export declare function parallelCleanup(options?: ParallelOptions): Promise<void>;
97
+ /**
98
+ * Remove a specific parallel session with merge workflow
99
+ */
100
+ export declare function parallelRemove(sessionName: string, options?: ParallelOptions): Promise<void>;
101
+ /**
102
+ * Main parallel command dispatcher
103
+ */
104
+ export declare function parallel(subcommand: string, args: string[], options?: ParallelOptions): Promise<void>;