@proletariat/cli 0.3.14 → 0.3.15

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
@@ -15,7 +15,7 @@
15
15
 
16
16
  > ⚠️ **Beta Software** — Under active development. Commands and APIs may change between versions, and bugs are actively being squashed.
17
17
  >
18
- > - [Book a call](https://cal.com/chrismcdermut) - Feedback, ideas, or chat multi-agent workflows and the future of work/labor (and economic labor theory..)
18
+ > **Let's get you shipping** [Book a call][cal-link] - I'm happy to help you get prlt running or chat feedback, ideas, multi-agent workflows, and the future of work/labor (and economic labor theory..)
19
19
 
20
20
  ---
21
21
 
@@ -55,6 +55,9 @@ prlt work spawn # Interactive: select tickets, environment, a
55
55
  # Agent creates PR → You review → Merge → Done
56
56
  ```
57
57
 
58
+ <details>
59
+ <summary><b>Workflow Diagram</b> (click to expand)</summary>
60
+
58
61
  ```mermaid
59
62
  sequenceDiagram
60
63
  participant You
@@ -76,6 +79,8 @@ sequenceDiagram
76
79
  You->>GitHub: Review & approve
77
80
  ```
78
81
 
82
+ </details>
83
+
79
84
  Spawn agents to implement, groom, or review—not just write code.
80
85
 
81
86
  ### Interactive Menus
@@ -83,19 +88,19 @@ Spawn agents to implement, groom, or review—not just write code.
83
88
  `prlt work` guides you through project and ticket selection:
84
89
 
85
90
  <p align="center">
86
- <img src="docs/images/work/work-project-select.png" alt="Project Selection" width="600">
91
+ <img src="https://raw.githubusercontent.com/chrismcdermut/proletariat/main/docs/images/work/work-project-select.png" alt="Project Selection" width="600">
87
92
  </p>
88
93
 
89
94
  Choose your operation—start a single agent, batch spawn, or watch a column:
90
95
 
91
96
  <p align="center">
92
- <img src="docs/images/work/work-operations-menu.png" alt="Work Operations Menu" width="600">
97
+ <img src="https://raw.githubusercontent.com/chrismcdermut/proletariat/main/docs/images/work/work-operations-menu.png" alt="Work Operations Menu" width="600">
93
98
  </p>
94
99
 
95
100
  Select tickets to spawn, grouped by priority:
96
101
 
97
102
  <p align="center">
98
- <img src="docs/images/work/work-ticket-select.png" alt="Ticket Selection" width="800">
103
+ <img src="https://raw.githubusercontent.com/chrismcdermut/proletariat/main/docs/images/work/work-ticket-select.png" alt="Ticket Selection" width="800">
99
104
  </p>
100
105
 
101
106
  ---
@@ -249,7 +254,7 @@ $ prlt ticket create
249
254
  View ticket details with `prlt ticket`:
250
255
 
251
256
  <p align="center">
252
- <img src="docs/images/ticket/ticket-view.png" alt="Ticket View" width="600">
257
+ <img src="https://raw.githubusercontent.com/chrismcdermut/proletariat/main/docs/images/ticket/ticket-view.png" alt="Ticket View" width="600">
253
258
  </p>
254
259
 
255
260
  #### 2. JSON Mode (AI Agents)
@@ -381,7 +386,7 @@ Each agent works in its own branch. No conflicts.
381
386
  Monitor running agents with `prlt execution`:
382
387
 
383
388
  <p align="center">
384
- <img src="docs/images/execution/execution-list.png" alt="Execution List" width="800">
389
+ <img src="https://raw.githubusercontent.com/chrismcdermut/proletariat/main/docs/images/execution/execution-list.png" alt="Execution List" width="800">
385
390
  </p>
386
391
 
387
392
  ```mermaid
@@ -414,7 +419,7 @@ flowchart LR
414
419
  Agent-created PRs ready for review:
415
420
 
416
421
  <p align="center">
417
- <img src="docs/images/execution/github-prs.png" alt="GitHub Pull Requests" width="800">
422
+ <img src="https://raw.githubusercontent.com/chrismcdermut/proletariat/main/docs/images/execution/github-prs.png" alt="GitHub Pull Requests" width="800">
418
423
  </p>
419
424
 
420
425
  ### Command Reference
@@ -637,7 +642,7 @@ Claude Code handles its own authentication via `claude login`.
637
642
 
638
643
  - **Discord**: [discord.gg/tmZyjNNSvw](https://discord.gg/tmZyjNNSvw)
639
644
  - **GitHub Issues**: [Report bugs or request features](https://github.com/chrismcdermut/proletariat-cli/issues)
640
- - **Chat**: [Book a call](https://cal.com/chrismcdermut) Feedback, ideas, or talk multi-agent workflows
645
+ - **Setup Help**: [Book a call][cal-link] - I'll help you get things running
641
646
 
642
647
  ---
643
648
 
@@ -654,3 +659,5 @@ Apache 2.0
654
659
  [Star on GitHub](https://github.com/chrismcdermut/proletariat) | [Install from NPM](https://www.npmjs.com/package/@proletariat/cli) | [Report Issues](https://github.com/chrismcdermut/proletariat/issues)
655
660
 
656
661
  Made with ⚒️ by the proletariat.
662
+
663
+ [cal-link]: https://cal.com/chrismcdermut
@@ -9,6 +9,7 @@ export default class Add extends Command {
9
9
  'no-container': import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
10
  theme: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
11
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ clone: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
13
  };
13
14
  static strict: boolean;
14
15
  run(): Promise<void>;
@@ -32,6 +32,10 @@ export default class Add extends Command {
32
32
  description: 'Output prompt configuration as JSON (for AI agents/scripts)',
33
33
  default: false,
34
34
  }),
35
+ clone: Flags.boolean({
36
+ description: 'Use independent git clone instead of worktree (more isolation, no real-time sync)',
37
+ default: false,
38
+ }),
35
39
  };
36
40
  static strict = false; // Allow multiple agent names
37
41
  async run() {
@@ -249,6 +253,7 @@ export default class Add extends Command {
249
253
  const addedAgents = await addAgentsToWorkspace(workspaceInfo, agentNames, {
250
254
  skipDevcontainer: flags['no-container'],
251
255
  themeId,
256
+ mountMode: flags.clone ? 'clone' : 'worktree',
252
257
  });
253
258
  if (addedAgents.length === 0) {
254
259
  this.log(chalk.yellow('No new agents to add. All specified agents already exist.'));
@@ -13,6 +13,7 @@ import { runExecution, isDockerRunning, isDevcontainerCliInstalled } from '../..
13
13
  import { ExecutionStorage } from '../../lib/execution/storage.js';
14
14
  import { loadExecutionConfig, getTerminalApp, getShell, hasTerminalPreference, hasShellPreference } from '../../lib/execution/config.js';
15
15
  import { hasDevcontainerConfig } from '../../lib/execution/devcontainer.js';
16
+ import { detectRepoWorktrees, resolveWorktreePath } from '../../lib/execution/context.js';
16
17
  import { isGHInstalled, isGHAuthenticated, getPRFeedback, hasPendingFeedback, formatPRFeedbackForPrompt, } from '../../lib/pr/index.js';
17
18
  import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
18
19
  export default class WorkRevise extends PMOCommand {
@@ -187,23 +188,14 @@ export default class WorkRevise extends PMOCommand {
187
188
  db.close();
188
189
  this.error(`Agent directory not found at ${agentDir}.`);
189
190
  }
190
- let worktreePath = agentDir;
191
- const agentContents = fs.readdirSync(agentDir);
192
- const repoWorktrees = agentContents.filter(item => {
193
- const itemPath = path.join(agentDir, item);
194
- const gitPath = path.join(itemPath, '.git');
195
- return fs.statSync(itemPath).isDirectory() && fs.existsSync(gitPath);
196
- });
197
- if (repoWorktrees.length === 1) {
198
- worktreePath = path.join(agentDir, repoWorktrees[0]);
199
- }
200
- else if (repoWorktrees.length > 1) {
201
- worktreePath = agentDir;
191
+ // Detect repository worktrees within agent directory
192
+ const repoWorktrees = detectRepoWorktrees(agentDir);
193
+ const worktreePath = resolveWorktreePath(agentDir, repoWorktrees);
194
+ if (repoWorktrees.length > 1) {
202
195
  this.log(styles.muted(` Repos: ${repoWorktrees.join(', ')}`));
203
196
  }
204
- else {
197
+ else if (repoWorktrees.length === 0) {
205
198
  this.log(styles.muted(` No git worktree found, using current directory`));
206
- worktreePath = process.cwd();
207
199
  }
208
200
  // Get branch from ticket metadata or current branch
209
201
  const branch = ticket.metadata?.pr_branch || this.getCurrentBranch(worktreePath);
@@ -221,6 +213,8 @@ export default class WorkRevise extends PMOCommand {
221
213
  worktreePath,
222
214
  branch,
223
215
  hqPath,
216
+ pmoPath: this.pmoPath,
217
+ repoWorktrees,
224
218
  // Revision-specific context
225
219
  isRevision: true,
226
220
  prFeedback: formattedFeedback,
@@ -24,6 +24,7 @@ export default class WorkSpawn extends PMOCommand {
24
24
  action: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
25
25
  session: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
26
26
  focus: import("@oclif/core/interfaces").BooleanFlag<boolean>;
27
+ clone: import("@oclif/core/interfaces").BooleanFlag<boolean>;
27
28
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
28
29
  };
29
30
  execute(): Promise<void>;
@@ -109,6 +109,10 @@ export default class WorkSpawn extends PMOCommand {
109
109
  description: 'Bring terminal to foreground when opening new tabs (default: opens in background)',
110
110
  default: false,
111
111
  }),
112
+ clone: Flags.boolean({
113
+ description: 'Use independent git clone instead of worktree (more isolation, no real-time sync)',
114
+ default: false,
115
+ }),
112
116
  };
113
117
  async execute() {
114
118
  const { flags, argv } = await this.parse(WorkSpawn);
@@ -757,6 +761,9 @@ export default class WorkSpawn extends PMOCommand {
757
761
  // IMPORTANT: Pass --project to avoid re-prompting for project selection
758
762
  // Pass --ephemeral to signal work:start should create an ephemeral agent
759
763
  const startArgs = [ticket.id, '--project', projectId, '--ephemeral'];
764
+ // Pass clone flag if specified
765
+ if (flags.clone)
766
+ startArgs.push('--clone');
760
767
  if (flags['per-ticket']) {
761
768
  // Per-ticket mode: only pass display flag, let start prompt for the rest
762
769
  // batchDisplayMode is for devcontainer, batchDisplay is for host
@@ -26,6 +26,7 @@ export default class WorkStart extends PMOCommand {
26
26
  agent: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
27
27
  ephemeral: import("@oclif/core/interfaces").BooleanFlag<boolean>;
28
28
  focus: import("@oclif/core/interfaces").BooleanFlag<boolean>;
29
+ clone: import("@oclif/core/interfaces").BooleanFlag<boolean>;
29
30
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
30
31
  };
31
32
  execute(): Promise<void>;
@@ -14,6 +14,7 @@ import { runExecution, isDockerRunning, isGitHubTokenAvailable, isDevcontainerCl
14
14
  import { ExecutionStorage, ContainerStorage } from '../../lib/execution/storage.js';
15
15
  import { loadExecutionConfig, getTerminalApp, promptTerminalPreference, getShell, promptShellPreference, hasTerminalPreference, hasShellPreference, getOrPromptCoderName } from '../../lib/execution/config.js';
16
16
  import { hasDevcontainerConfig } from '../../lib/execution/devcontainer.js';
17
+ import { detectRepoWorktrees, resolveWorktreePath } from '../../lib/execution/context.js';
17
18
  import { isGHInstalled, isGHAuthenticated } from '../../lib/pr/index.js';
18
19
  /**
19
20
  * Try to execute a git command, return true if successful
@@ -169,6 +170,10 @@ export default class WorkStart extends PMOCommand {
169
170
  description: 'Bring terminal to foreground when opening new tabs (default: opens in background)',
170
171
  default: false,
171
172
  }),
173
+ clone: Flags.boolean({
174
+ description: 'Use independent git clone instead of worktree (more isolation, no real-time sync)',
175
+ default: false,
176
+ }),
172
177
  };
173
178
  async execute() {
174
179
  const { args, flags } = await this.parse(WorkStart);
@@ -314,6 +319,7 @@ export default class WorkStart extends PMOCommand {
314
319
  const ephemeralResult = await createEphemeralAgent(workspaceInfo, {
315
320
  skipDevcontainer: flags['run-on-host'],
316
321
  log: (msg) => this.log(msg),
322
+ mountMode: flags.clone ? 'clone' : 'worktree',
317
323
  });
318
324
  agentName = ephemeralResult.name;
319
325
  agentWorktreePath = ephemeralResult.worktreePath;
@@ -381,6 +387,7 @@ export default class WorkStart extends PMOCommand {
381
387
  const ephemeralResult = await createEphemeralAgent(workspaceInfo, {
382
388
  skipDevcontainer: flags['run-on-host'],
383
389
  log: (msg) => this.log(msg),
390
+ mountMode: flags.clone ? 'clone' : 'worktree',
384
391
  });
385
392
  agentName = ephemeralResult.name;
386
393
  agentWorktreePath = ephemeralResult.worktreePath;
@@ -397,6 +404,7 @@ export default class WorkStart extends PMOCommand {
397
404
  const ephemeralResult = await createEphemeralAgent(workspaceInfo, {
398
405
  skipDevcontainer: flags['run-on-host'],
399
406
  log: (msg) => this.log(msg),
407
+ mountMode: flags.clone ? 'clone' : 'worktree',
400
408
  });
401
409
  agentName = ephemeralResult.name;
402
410
  agentWorktreePath = ephemeralResult.worktreePath;
@@ -495,31 +503,14 @@ export default class WorkStart extends PMOCommand {
495
503
  }
496
504
  }
497
505
  }
498
- // Find worktree path for agent
499
- // Agent directory may contain multiple repo worktrees - use the agent dir itself
500
- // so Claude can work across all repos (frontend, backend, etc.)
501
- let worktreePath = agentDir;
502
- // Check if agent has repository worktrees (subdirectories with .git)
503
- const agentContents = fs.readdirSync(agentDir);
504
- const repoWorktrees = agentContents.filter(item => {
505
- const itemPath = path.join(agentDir, item);
506
- const gitPath = path.join(itemPath, '.git');
507
- return fs.statSync(itemPath).isDirectory() && fs.existsSync(gitPath);
508
- });
509
- if (repoWorktrees.length === 1) {
510
- // Single repo - open directly in the repo worktree
511
- worktreePath = path.join(agentDir, repoWorktrees[0]);
512
- }
513
- else if (repoWorktrees.length > 1) {
514
- // Multiple repos - open in agent directory, Claude can navigate between them
515
- worktreePath = agentDir;
506
+ // Detect repository worktrees within agent directory
507
+ const repoWorktrees = detectRepoWorktrees(agentDir);
508
+ const worktreePath = resolveWorktreePath(agentDir, repoWorktrees);
509
+ if (repoWorktrees.length > 1) {
516
510
  this.log(styles.muted(` Repos: ${repoWorktrees.join(', ')}`));
517
511
  }
518
- else {
519
- // No git worktrees found - agent is a placeholder
520
- // Fall back to the current working directory
512
+ else if (repoWorktrees.length === 0) {
521
513
  this.log(styles.muted(` No git worktree found for agent, using current directory`));
522
- worktreePath = process.cwd();
523
514
  }
524
515
  // Get coder name for branch naming (prompts on first use)
525
516
  const coderName = await getOrPromptCoderName(db);
@@ -647,6 +638,7 @@ export default class WorkStart extends PMOCommand {
647
638
  branch,
648
639
  hqPath,
649
640
  pmoPath: this.pmoPath, // PMO path for container mounting
641
+ repoWorktrees,
650
642
  // Action context
651
643
  actionId: selectedAction?.id,
652
644
  actionName: selectedAction?.name || (customPrompt ? 'Custom' : undefined),
@@ -1500,6 +1492,7 @@ export default class WorkStart extends PMOCommand {
1500
1492
  ...(flags['run-on-host'] ? ['--run-on-host'] : []),
1501
1493
  ...(flags.force ? ['--force'] : []),
1502
1494
  '--permission-mode', batchPermissionMode,
1495
+ ...(flags.clone ? ['--clone'] : []),
1503
1496
  ]);
1504
1497
  successCount++;
1505
1498
  }
@@ -1527,17 +1520,9 @@ export default class WorkStart extends PMOCommand {
1527
1520
  if (!fs.existsSync(agentDir)) {
1528
1521
  throw new Error(`Agent directory not found: ${agentDir}`);
1529
1522
  }
1530
- // Find worktree path
1531
- let worktreePath = agentDir;
1532
- const agentContents = fs.readdirSync(agentDir);
1533
- const repoWorktrees = agentContents.filter(item => {
1534
- const itemPath = path.join(agentDir, item);
1535
- const gitPath = path.join(itemPath, '.git');
1536
- return fs.statSync(itemPath).isDirectory() && fs.existsSync(gitPath);
1537
- });
1538
- if (repoWorktrees.length === 1) {
1539
- worktreePath = path.join(agentDir, repoWorktrees[0]);
1540
- }
1523
+ // Detect repository worktrees within agent directory
1524
+ const repoWorktrees = detectRepoWorktrees(agentDir);
1525
+ const worktreePath = resolveWorktreePath(agentDir, repoWorktrees);
1541
1526
  // Get coder name for branch naming (prompts on first use)
1542
1527
  const coderName = await getOrPromptCoderName(db);
1543
1528
  // Use ticket's existing branch or generate a new one
@@ -1583,6 +1568,7 @@ export default class WorkStart extends PMOCommand {
1583
1568
  branch,
1584
1569
  hqPath: workspaceInfo.path,
1585
1570
  pmoPath: this.pmoPath,
1571
+ repoWorktrees,
1586
1572
  createPR: flags['create-pr'] || false,
1587
1573
  // Use 'implement' action for batch mode
1588
1574
  actionId: defaultAction?.id,
@@ -1,4 +1,4 @@
1
- import { Agent, Repository } from '../database/index.js';
1
+ import { Agent, Repository, MountMode as DBMountMode } from '../database/index.js';
2
2
  export interface AgentStatus {
3
3
  name: string;
4
4
  exists: boolean;
@@ -68,9 +68,11 @@ export declare function validateAgentNames(agentNames: string[]): {
68
68
  valid: string[];
69
69
  invalid: string[];
70
70
  };
71
+ export type MountMode = DBMountMode;
71
72
  export interface AddAgentOptions {
72
73
  skipDevcontainer?: boolean;
73
74
  themeId?: string;
75
+ mountMode?: DBMountMode;
74
76
  }
75
77
  /**
76
78
  * Create agent worktrees and update database
@@ -90,6 +92,8 @@ export interface EphemeralAgentOptions {
90
92
  * Optional logger for conflict messages (e.g., when a tmux session or directory already exists)
91
93
  */
92
94
  log?: (message: string) => void;
95
+ /** Mount mode: 'worktree' = git worktree (default), 'clone' = independent clone */
96
+ mountMode?: DBMountMode;
93
97
  }
94
98
  export interface EphemeralAgentResult {
95
99
  name: string;
@@ -283,15 +283,15 @@ export async function addAgentsToWorkspace(workspaceInfo, agentNames, options) {
283
283
  if (newAgents.length === 0) {
284
284
  return [];
285
285
  }
286
- // Create worktrees
286
+ // Create worktrees/clones
287
287
  if (workspaceInfo.type === 'hq') {
288
288
  await createAgentWorktrees(workspaceInfo.agentsPath, newAgents, workspaceInfo.path, options);
289
289
  }
290
290
  else {
291
291
  await createAgentWorktrees(workspaceInfo.agentsPath, newAgents, undefined, options);
292
292
  }
293
- // Add to database (with optional theme ID)
294
- addAgentsToDatabase(workspaceInfo.path, newAgents, options?.themeId);
293
+ // Add to database (with optional theme ID and mount mode)
294
+ addAgentsToDatabase(workspaceInfo.path, newAgents, options?.themeId, options?.mountMode || 'clone');
295
295
  return newAgents;
296
296
  }
297
297
  /**
@@ -441,27 +441,53 @@ export async function createEphemeralAgent(workspaceInfo, options) {
441
441
  if (!fs.existsSync(agentDir)) {
442
442
  fs.mkdirSync(agentDir, { recursive: true });
443
443
  }
444
- // Create worktrees for each repository
444
+ // Create worktrees/clones for each repository
445
445
  const reposPath = path.join(workspaceInfo.path, 'repos');
446
+ const mountMode = options?.mountMode || 'worktree';
446
447
  if (fs.existsSync(reposPath) && workspaceInfo.repositories.length > 0) {
447
448
  for (const repo of workspaceInfo.repositories) {
448
449
  const sourceRepoPath = path.join(reposPath, repo.name);
449
- const worktreePath = path.join(agentDir, repo.name);
450
- if (fs.existsSync(sourceRepoPath) && !fs.existsSync(worktreePath)) {
451
- try {
452
- // Create git worktree for the repository
453
- // Don't create a branch yet - that happens in work:start
454
- // Use --detach to create without a branch reference
455
- execSync(`git worktree add --detach "${worktreePath}"`, {
456
- cwd: sourceRepoPath,
457
- stdio: 'pipe'
458
- });
450
+ const targetPath = path.join(agentDir, repo.name);
451
+ if (fs.existsSync(sourceRepoPath) && !fs.existsSync(targetPath)) {
452
+ if (mountMode === 'clone') {
453
+ // CLONE MODE: Create independent git clone
454
+ try {
455
+ // Get remote URL from source repo
456
+ const remoteUrl = execSync('git remote get-url origin', {
457
+ cwd: sourceRepoPath,
458
+ encoding: 'utf-8',
459
+ stdio: ['pipe', 'pipe', 'pipe']
460
+ }).trim();
461
+ if (remoteUrl) {
462
+ execSync(`git clone "${remoteUrl}" "${targetPath}"`, {
463
+ stdio: 'pipe'
464
+ });
465
+ }
466
+ }
467
+ catch {
468
+ // If clone fails, try to just create the directory
469
+ if (!fs.existsSync(targetPath)) {
470
+ fs.mkdirSync(targetPath, { recursive: true });
471
+ }
472
+ }
459
473
  }
460
- catch {
461
- // If worktree creation fails, try to just create the directory
462
- // The agent can still work without a worktree (e.g., for non-git projects)
463
- if (!fs.existsSync(worktreePath)) {
464
- fs.mkdirSync(worktreePath, { recursive: true });
474
+ else {
475
+ // WORKTREE MODE: Create git worktree
476
+ try {
477
+ // Create git worktree for the repository
478
+ // Don't create a branch yet - that happens in work:start
479
+ // Use --detach to create without a branch reference
480
+ execSync(`git worktree add --detach "${targetPath}"`, {
481
+ cwd: sourceRepoPath,
482
+ stdio: 'pipe'
483
+ });
484
+ }
485
+ catch {
486
+ // If worktree creation fails, try to just create the directory
487
+ // The agent can still work without a worktree (e.g., for non-git projects)
488
+ if (!fs.existsSync(targetPath)) {
489
+ fs.mkdirSync(targetPath, { recursive: true });
490
+ }
465
491
  }
466
492
  }
467
493
  }
@@ -474,12 +500,13 @@ export async function createEphemeralAgent(workspaceInfo, options) {
474
500
  createDevcontainerConfig({
475
501
  agentName,
476
502
  agentDir,
477
- repoWorktrees: workspaceInfo.repositories.map(r => r.name)
503
+ repoWorktrees: mountMode === 'worktree' ? workspaceInfo.repositories.map(r => r.name) : undefined,
504
+ mountMode,
478
505
  });
479
506
  }
480
507
  }
481
508
  // Add to database
482
- const agent = addEphemeralAgentToDatabase(workspaceInfo.path, agentName, baseName, options?.themeId);
509
+ const agent = addEphemeralAgentToDatabase(workspaceInfo.path, agentName, baseName, options?.themeId, mountMode);
483
510
  return {
484
511
  name: agentName,
485
512
  baseName,
@@ -20,11 +20,15 @@ export { findHQRoot } from '../workspace.js';
20
20
  * Prompt user to enter agent names
21
21
  */
22
22
  export declare function promptAgentNames(existingAgents?: string[]): Promise<string[]>;
23
+ export type MountMode = 'worktree' | 'clone';
23
24
  export interface CreateAgentOptions {
24
25
  skipDevcontainer?: boolean;
26
+ mountMode?: MountMode;
25
27
  }
26
28
  /**
27
- * Create agent worktrees (shared between HQ and workspace-only modes)
29
+ * Create agent repos (worktree or clone mode)
30
+ * - worktree mode: Uses git worktree add (shared .git, requires parent repo mounts in container)
31
+ * - clone mode: Uses git clone (independent repo, no path translation needed)
28
32
  */
29
33
  export declare function createAgentWorktrees(workspacePath: string, agents: string[], hqPath?: string, options?: CreateAgentOptions): Promise<void>;
30
34
  /**