forge-workflow 0.0.7 → 0.0.9

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 (68) hide show
  1. package/.claude/commands/premerge.md +2 -2
  2. package/.claude/commands/review.md +5 -2
  3. package/.claude/commands/ship.md +4 -3
  4. package/.claude/rules/greptile-review-process.md +4 -4
  5. package/.cline/workflows/premerge.md +2 -2
  6. package/.cline/workflows/review.md +5 -2
  7. package/.cline/workflows/ship.md +4 -3
  8. package/.codex/skills/premerge/SKILL.md +2 -2
  9. package/.codex/skills/review/SKILL.md +5 -2
  10. package/.codex/skills/ship/SKILL.md +4 -3
  11. package/.cursor/commands/premerge.md +2 -2
  12. package/.cursor/commands/review.md +5 -2
  13. package/.cursor/commands/ship.md +4 -3
  14. package/.github/prompts/premerge.prompt.md +2 -2
  15. package/.github/prompts/review.prompt.md +5 -2
  16. package/.github/prompts/ship.prompt.md +4 -3
  17. package/.github/workflows/beads-to-github.yml +1 -1
  18. package/.github/workflows/github-to-beads.yml +1 -1
  19. package/.kilocode/workflows/premerge.md +2 -2
  20. package/.kilocode/workflows/review.md +5 -2
  21. package/.kilocode/workflows/ship.md +4 -3
  22. package/.opencode/commands/premerge.md +2 -2
  23. package/.opencode/commands/review.md +5 -2
  24. package/.opencode/commands/ship.md +4 -3
  25. package/.roo/commands/premerge.md +2 -2
  26. package/.roo/commands/review.md +5 -2
  27. package/.roo/commands/ship.md +4 -3
  28. package/AGENTS.md +9 -9
  29. package/README.md +12 -6
  30. package/bin/forge.js +21 -3
  31. package/docs/BEADS_GITHUB_SYNC.md +6 -2
  32. package/docs/EXAMPLES.md +22 -22
  33. package/docs/ROADMAP.md +3 -3
  34. package/docs/TOOLCHAIN.md +60 -52
  35. package/lib/agents/codex.plugin.json +3 -0
  36. package/lib/agents-config.js +18 -12
  37. package/lib/codex-skills.js +54 -1
  38. package/lib/commands/_issue.js +172 -0
  39. package/lib/commands/claim.js +5 -0
  40. package/lib/commands/close.js +5 -0
  41. package/lib/commands/create.js +5 -0
  42. package/lib/commands/issue.js +5 -0
  43. package/lib/commands/list.js +5 -0
  44. package/lib/commands/plan.js +5 -2
  45. package/lib/commands/ready.js +5 -0
  46. package/lib/commands/setup.js +231 -17
  47. package/lib/commands/ship.js +188 -5
  48. package/lib/commands/show.js +5 -0
  49. package/lib/commands/status.js +20 -33
  50. package/lib/commands/sync.js +3 -1
  51. package/lib/commands/test.js +90 -25
  52. package/lib/commands/update.js +5 -0
  53. package/lib/commands/validate.js +218 -1
  54. package/lib/setup-action-log.js +2 -0
  55. package/lib/setup-summary-renderer.js +15 -11
  56. package/lib/workflow/enforce-stage.js +12 -8
  57. package/lib/workflow/state-manager.js +193 -0
  58. package/package.json +1 -1
  59. package/scripts/dep-guard.sh +11 -1
  60. package/scripts/forge-team/lib/hooks.sh +1 -1
  61. package/scripts/forge-team/lib/verify.sh +1 -1
  62. package/scripts/forge-team/lib/workload.sh +56 -27
  63. package/scripts/forge-team/tests/workload.test.sh +35 -4
  64. package/scripts/github-beads-sync/run-bd.mjs +4 -2
  65. package/scripts/lib/eval-runner.js +50 -0
  66. package/scripts/smart-status.sh +10 -1
  67. package/scripts/sync-utils.sh +39 -0
  68. package/scripts/test.js +144 -38
package/bin/forge.js CHANGED
@@ -139,7 +139,7 @@ function loadAgentsFromPlugins() {
139
139
  agents[id] = {
140
140
  name: plugin.name,
141
141
  description: plugin.description || '',
142
- dirs: Object.values(plugin.directories || {}),
142
+ dirs: getRepoRelativePluginDirectories(plugin),
143
143
  hasCommands: plugin.capabilities?.commands || plugin.setup?.copyCommands || false,
144
144
  hasSkill: plugin.capabilities?.skills || plugin.setup?.createSkill || false,
145
145
  linkFile: plugin.files?.rootConfig || '',
@@ -153,6 +153,17 @@ function loadAgentsFromPlugins() {
153
153
  return agents;
154
154
  }
155
155
 
156
+ function isRepoRelativePluginPath(candidate) {
157
+ return typeof candidate === 'string'
158
+ && candidate.length > 0
159
+ && !path.isAbsolute(candidate)
160
+ && !/^[~$%]/.test(candidate);
161
+ }
162
+
163
+ function getRepoRelativePluginDirectories(plugin) {
164
+ return Object.values(plugin.directories || {}).filter(isRepoRelativePluginPath);
165
+ }
166
+
156
167
  // Agent definitions - loaded from plugin system
157
168
  const AGENTS = loadAgentsFromPlugins();
158
169
 
@@ -2383,7 +2394,7 @@ function displaySetupSummary(selectedAgents) {
2383
2394
 
2384
2395
  // Beads status
2385
2396
  if (isBeadsInitialized()) {
2386
- console.log(' ✓ Beads initialized - Track work: bd ready');
2397
+ console.log(' ✓ Beads initialized - Track work: forge ready');
2387
2398
  } else if (checkForBeads()) {
2388
2399
  console.log(' ! Beads available - Run: bd init');
2389
2400
  } else {
@@ -2541,6 +2552,13 @@ function parseFlags() {
2541
2552
  sync: false, // Scaffold Beads GitHub sync workflows (--sync)
2542
2553
  };
2543
2554
 
2555
+ // Issue passthrough commands delegate all flags to bd.
2556
+ // Skip global parsing so flags like --type, -p, --help reach the handler intact.
2557
+ const issuePassthroughCommands = ['create', 'update', 'claim', 'close', 'show', 'list', 'ready', 'issue'];
2558
+ if (issuePassthroughCommands.includes(args[0])) {
2559
+ return flags;
2560
+ }
2561
+
2544
2562
  for (let i = 0; i < args.length;) {
2545
2563
  const arg = args[i];
2546
2564
 
@@ -3329,7 +3347,7 @@ async function setupProjectTools(rl, question) {
3329
3347
  console.log('');
3330
3348
  console.log('• Beads - Git-backed issue tracking');
3331
3349
  console.log(' Persists tasks across sessions, tracks dependencies.');
3332
- console.log(' Command: bd ready, bd create, bd close');
3350
+ console.log(' Command: forge ready, forge create, forge close');
3333
3351
  console.log('');
3334
3352
  console.log('• Skills - Universal SKILL.md management');
3335
3353
  console.log(' Manage AI agent skills across all agents.');
@@ -3,10 +3,14 @@
3
3
  Automatic synchronization between GitHub Issues and Beads issue tracking.
4
4
 
5
5
  **GitHub Issues** = human/team/public interface.
6
- **Beads** = AI agent engine (`bd ready`, `bd close`).
6
+ **Beads** = issue engine behind Forge (`forge ready`, `forge close`).
7
7
 
8
8
  Neither side needs to know about the other. Contributors file issues on GitHub; AI agents pick up work via Beads. Status changes propagate automatically.
9
9
 
10
+ For human and agent workflows, prefer the Forge wrapper commands (`forge ready`,
11
+ `forge create`, `forge close`, `forge sync`). The workflow automation shown below
12
+ still calls `bd` directly as an internal implementation detail.
13
+
10
14
  ---
11
15
 
12
16
  ## Architecture
@@ -48,7 +52,7 @@ sequenceDiagram
48
52
  participant WF as GitHub Actions
49
53
  participant GH as GitHub Issues
50
54
 
51
- AI->>BD: bd close forge-abc
55
+ AI->>BD: forge close forge-abc
52
56
  BD->>Repo: Update issues.jsonl
53
57
  AI->>Repo: git push
54
58
  Repo->>WF: push trigger (paths: .beads/**)
package/docs/EXAMPLES.md CHANGED
@@ -109,7 +109,7 @@ git commit -m "feat: add health check endpoint"
109
109
  /status
110
110
 
111
111
  # If Beads installed:
112
- bd create "SQL injection in search endpoint" \
112
+ forge create "SQL injection in search endpoint" \
113
113
  --type bug \
114
114
  --priority 0 \
115
115
  --label "security,critical"
@@ -224,7 +224,7 @@ OWASP A03:2021 Injection"
224
224
  # ═══════════════════════════════════════════════════════════
225
225
  /status
226
226
 
227
- bd create "Extract auth logic to service" \
227
+ forge create "Extract auth logic to service" \
228
228
  --type chore \
229
229
  --priority 2
230
230
 
@@ -337,35 +337,35 @@ Team of 3 developers:
337
337
  # PROJECT SETUP (Once per project)
338
338
  # ═══════════════════════════════════════════════════════════
339
339
  bd init --prefix SHOP
340
- bd sync # Commit .beads/ to git
340
+ forge sync # Sync initial Beads state
341
341
 
342
342
  # ═══════════════════════════════════════════════════════════
343
343
  # ALICE: Payment Integration
344
344
  # ═══════════════════════════════════════════════════════════
345
345
 
346
346
  # Morning: Check what's available
347
- bd ready
347
+ forge ready
348
348
  # Output:
349
349
  # SHOP-1: Payment integration (ready)
350
350
  # SHOP-3: Admin dashboard (ready)
351
351
 
352
352
  # Claim work
353
- bd update SHOP-1 --status in_progress
353
+ forge claim SHOP-1
354
354
  /status
355
355
  /plan stripe-payment-integration
356
356
  /dev
357
357
 
358
358
  # Midday: Progress update
359
- bd comments SHOP-1 "Stripe SDK integrated, working on webhooks"
359
+ bd comments add SHOP-1 "Stripe SDK integrated, working on webhooks"
360
360
 
361
361
  # Afternoon: Blocked on API keys
362
- bd update SHOP-1 --status blocked --comment "Need production Stripe API keys"
362
+ forge update SHOP-1 --status blocked --comment "Need production Stripe API keys"
363
363
 
364
364
  # Create dependency
365
- bd create "Get Stripe API keys from DevOps" --type chore --priority 1
365
+ forge create "Get Stripe API keys from DevOps" --type chore --priority 1
366
366
  bd dep add SHOP-1 SHOP-5 # SHOP-1 depends on SHOP-5
367
367
 
368
- bd sync # Push to git
368
+ forge sync # Push Beads state
369
369
 
370
370
  # ═══════════════════════════════════════════════════════════
371
371
  # BOB: Email Notifications (Same Time)
@@ -373,24 +373,24 @@ bd sync # Push to git
373
373
 
374
374
  # Morning: Pull latest, check work
375
375
  git pull
376
- bd sync # Sync with Alice's updates
376
+ forge sync # Sync with Alice's updates
377
377
 
378
- bd ready
378
+ forge ready
379
379
  # Output:
380
380
  # SHOP-3: Admin dashboard (ready)
381
381
  # SHOP-2: Email notifications (ready)
382
382
 
383
383
  # Claim different feature
384
- bd update SHOP-2 --status in_progress
384
+ forge claim SHOP-2
385
385
  /plan email-notifications
386
386
  /dev
387
387
 
388
388
  # No conflicts with Alice (different files)
389
389
 
390
390
  # End of day: Complete
391
- bd close SHOP-2 --reason "Implemented with SendGrid"
391
+ forge close SHOP-2 --reason "Implemented with SendGrid"
392
392
  /ship
393
- bd sync
393
+ forge sync
394
394
 
395
395
  # ═══════════════════════════════════════════════════════════
396
396
  # CHARLIE: Admin Dashboard (Next Day)
@@ -398,17 +398,17 @@ bd sync
398
398
 
399
399
  # Morning: Check dependencies
400
400
  git pull
401
- bd sync
401
+ forge sync
402
402
 
403
- bd show SHOP-3
403
+ forge show SHOP-3
404
404
  # Output:
405
405
  # Status: ready
406
406
  # Depends on: (none)
407
407
 
408
- bd update SHOP-3 --status in_progress
408
+ forge claim SHOP-3
409
409
 
410
410
  # Discovers overlap with Bob's work
411
- bd comments SHOP-3 "Need Bob's email service for user notifications"
411
+ bd comments add SHOP-3 "Need Bob's email service for user notifications"
412
412
  bd dep add SHOP-3 SHOP-2 # SHOP-3 depends on SHOP-2
413
413
 
414
414
  # Bob's work already merged, so can proceed
@@ -428,7 +428,7 @@ bd blocked
428
428
  # SHOP-1: Payment integration (blocked by SHOP-5)
429
429
 
430
430
  # Find work with no blockers:
431
- bd ready
431
+ forge ready
432
432
 
433
433
  # See full project status:
434
434
  bd stats
@@ -440,7 +440,7 @@ bd stats
440
440
  # Done: 4
441
441
 
442
442
  # Always sync at end of session:
443
- bd sync
443
+ forge sync
444
444
  ```
445
445
 
446
446
  **Result**: Team can work in parallel, track dependencies, and avoid conflicts.
@@ -465,8 +465,8 @@ bd sync
465
465
 
466
466
  ### 4. Team Collaboration
467
467
  - Beads tracks dependencies
468
- - `bd ready` finds available work
469
- - `bd sync` at end of every session
468
+ - `forge ready` finds available work
469
+ - `forge sync` at end of every session
470
470
  - Comments keep teammates informed
471
471
 
472
472
  ---
package/docs/ROADMAP.md CHANGED
@@ -291,8 +291,8 @@ All PRs tracked in Beads with proper dependencies:
291
291
  | PR8 | forge-dwm | Blocked | P3 | PR7 |
292
292
  | ~~Skills CLI~~ | ~~forge-mlm~~ | ~~Absorbed into PR5.5 + PR6 + PR8~~ | — | — |
293
293
 
294
- **View all issues**: `bd list`
295
- **View ready work**: `bd ready`
294
+ **View all issues**: `forge list`
295
+ **View ready work**: `forge ready`
296
296
  **View blocked issues**: `bd blocked`
297
297
 
298
298
  ### Git Workflow
@@ -348,7 +348,7 @@ Each PR is self-contained and can be rolled back independently:
348
348
  ## Resources
349
349
 
350
350
  - **Master Plan**: `docs/plans/*.md`
351
- - **Beads Issues**: `bd list` or `bd show <issue-id>`
351
+ - **Beads Issues**: `forge list` or `forge show <issue-id>`
352
352
  - **Workflow Guide**: [AGENTS.md](../AGENTS.md)
353
353
  - **Architecture Docs**: Coming in PR0 - [ARCHITECTURE.md](./ARCHITECTURE.md)
354
354
 
package/docs/TOOLCHAIN.md CHANGED
@@ -42,7 +42,7 @@ Complete reference for all tools integrated with the Forge workflow.
42
42
  - **Persists across sessions** - Issues survive context clearing, compaction, new chats
43
43
  - **Git-backed** - Version controlled, mergeable, team-shareable
44
44
  - **Dependency tracking** - Know what blocks what
45
- - **Ready detection** - `bd ready` finds unblocked work automatically
45
+ - **Ready detection** - `forge ready` finds unblocked work automatically
46
46
  - **AI-optimized** - JSON output, semantic compaction, audit trails
47
47
 
48
48
  ### Installation
@@ -91,6 +91,11 @@ After `bd init`, creates `.beads/` directory:
91
91
 
92
92
  **Dual-database architecture**: JSONL for git versioning, SQLite for fast local queries. Background daemon keeps them in sync.
93
93
 
94
+ For day-to-day issue workflows, prefer the Forge wrapper commands (`forge ready`,
95
+ `forge create`, `forge update`, `forge close`, `forge sync`). Use `bd` directly
96
+ for Beads capabilities Forge does not wrap yet, such as `bd init`, `bd comments`,
97
+ `bd dep`, `bd blocked`, and `bd dolt *`.
98
+
94
99
  ### Complete Command Reference
95
100
 
96
101
  #### Initialization
@@ -106,36 +111,36 @@ bd init --prefix PROJ # Custom issue prefix (PROJ-xxx)
106
111
 
107
112
  ```bash
108
113
  # Create issues
109
- bd create "Title" # Basic issue
110
- bd create "Title" --type feature # With type (feature, bug, chore, etc.)
111
- bd create "Title" --priority 1 # With priority (0=critical, 4=backlog)
112
- bd create "Title" -p 0 -l "urgent,backend" # P0 with labels
114
+ forge create "Title" # Basic issue
115
+ forge create "Title" --type feature # With type (feature, bug, chore, etc.)
116
+ forge create "Title" --priority 1 # With priority (0=critical, 4=backlog)
117
+ forge create "Title" -p 0 -l "urgent,backend" # P0 with labels
113
118
 
114
119
  # View issues
115
- bd show <id> # Detailed view with audit trail
116
- bd list # All issues
117
- bd list --status open # Filter by status
118
- bd list --priority 1 # Filter by priority
119
- bd list --assignee bob # Filter by assignee
120
- bd list --label bug # Filter by label (AND logic)
121
- bd list --label-any bug,urgent # Filter by label (OR logic)
122
- bd list --type feature # Filter by type
123
- bd list --title-contains "auth" # Search titles
124
- bd list --limit 10 # Limit results
120
+ forge show <id> # Detailed view with audit trail
121
+ forge list # All issues
122
+ forge list --status open # Filter by status
123
+ forge list --priority 1 # Filter by priority
124
+ forge list --assignee bob # Filter by assignee
125
+ forge list --label bug # Filter by label (AND logic)
126
+ forge list --label-any bug,urgent # Filter by label (OR logic)
127
+ forge list --type feature # Filter by type
128
+ forge list --title-contains "auth" # Search titles
129
+ forge list --limit 10 # Limit results
125
130
 
126
131
  # Update issues
127
- bd update <id> --status in_progress # Change status
128
- bd update <id> --priority 2 # Change priority
129
- bd update <id> --assignee bob # Assign
130
- bd update <id> --title "New title" # Update title
131
- bd update <id> --description "..." # Update description
132
- bd update <id> --notes "..." # Add notes
133
- bd update <id> --label-add urgent # Add label
132
+ forge claim <id> # Claim work (sets in_progress)
133
+ forge update <id> --priority 2 # Change priority
134
+ forge update <id> --assignee bob # Assign
135
+ forge update <id> --title "New title" # Update title
136
+ forge update <id> --description "..." # Update description
137
+ forge update <id> --notes "..." # Add notes
138
+ forge update <id> --add-label urgent # Add label
134
139
 
135
140
  # Complete issues
136
- bd close <id> # Close single issue
137
- bd close <id1> <id2> <id3> # Close multiple (efficient)
138
- bd close <id> --reason "Completed auth" # Close with reason
141
+ forge close <id> # Close single issue
142
+ forge close <id1> <id2> <id3> # Close multiple (efficient)
143
+ forge close <id> --reason "Completed auth" # Close with reason
139
144
  bd delete <id> # Delete issue
140
145
  bd delete <id> --cascade # Delete with dependents
141
146
  ```
@@ -144,8 +149,8 @@ bd delete <id> --cascade # Delete with dependents
144
149
 
145
150
  ```bash
146
151
  # Find work
147
- bd ready # Issues with NO open blockers (start here!)
148
- bd ready --priority 1 # Filter ready work by priority
152
+ forge ready # Issues with NO open blockers (start here!)
153
+ forge ready --priority 1 # Filter ready work by priority
149
154
  bd blocked # Issues that ARE blocked
150
155
 
151
156
  # Dependencies
@@ -158,11 +163,11 @@ bd dep cycles # Detect cycles
158
163
 
159
164
  # Comments
160
165
  bd comments <id> # View comments
161
- bd comments <id> "Comment text" # Add comment
166
+ bd comments add <id> "Comment text" # Add comment
162
167
 
163
168
  # Git sync
164
- bd sync # Export to JSONL, commit, push
165
- bd sync --status # Check sync status
169
+ forge sync # Pull + push Beads state through the Forge wrapper
170
+ bd dolt status # Check Dolt sync/server status
166
171
  bd hooks install # Install git hooks for auto-sync
167
172
 
168
173
  # Maintenance
@@ -203,18 +208,18 @@ bd admin compact --days 90 # Compact old closed issues
203
208
 
204
209
  ```bash
205
210
  # Start of session
206
- bd ready # What can I work on?
207
- bd show <id> # Review the issue
208
- bd update <id> --status in_progress
211
+ forge ready # What can I work on?
212
+ forge show <id> # Review the issue
213
+ forge claim <id>
209
214
 
210
215
  # During work
211
- bd comments <id> "Progress update"
212
- bd update <id> --notes "Found edge case"
216
+ bd comments add <id> "Progress update"
217
+ forge update <id> --notes "Found edge case"
213
218
 
214
219
  # End of session
215
- bd close <id> # If done, or:
216
- bd update <id> --status blocked --comment "Needs API response"
217
- bd sync # Always sync at end!
220
+ forge close <id> # If done, or:
221
+ forge update <id> --status blocked --comment "Needs API response"
222
+ forge sync # Always sync at end!
218
223
  ```
219
224
 
220
225
  ---
@@ -556,7 +561,10 @@ bun add -g @beads/bd
556
561
  irm https://raw.githubusercontent.com/steveyegge/beads/main/install.ps1 | iex
557
562
  ```
558
563
 
559
- > **Why v0.49.x?** Earlier versions lack the `bd ready` dependency-aware query, `bd sync --status`, and the dual-database (JSONL + SQLite) architecture that Forge relies on.
564
+ > **Why Forge + Beads?** Forge wraps the supported day-to-day issue workflow
565
+ > (`forge ready`, `forge create`, `forge close`, `forge sync`) while Beads
566
+ > remains the underlying store for initialization, dependencies, comments, and
567
+ > Dolt-backed sync internals.
560
568
 
561
569
  ---
562
570
 
@@ -564,14 +572,14 @@ irm https://raw.githubusercontent.com/steveyegge/beads/main/install.ps1 | iex
564
572
 
565
573
  | Stage | Tools Used |
566
574
  |-------|------------|
567
- | `/status` | `bd ready`, `bd list`, `git status` |
575
+ | `/status` | `forge ready`, `forge list`, `git status` |
568
576
  | `/plan` (Phase 2) | Parallel AI, Context7, grep.app, codebase exploration |
569
- | `/plan` | `bd create`, `git checkout -b` |
570
- | `/dev` | Tests, code, `bd update`, `/tasks save` |
577
+ | `/plan` | `forge create`, `git checkout -b` |
578
+ | `/dev` | Tests, code, `forge update`, `/tasks save` |
571
579
  | `/validate` | Type check, lint, tests, SonarCloud |
572
- | `/ship` | `bd update --status done`, `gh pr create` |
580
+ | `/ship` | `forge close`, `gh pr create` |
573
581
  | `/review` | `gh pr view`, Greptile, SonarCloud |
574
- | `/premerge` | `bd sync`, doc updates, hand off PR |
582
+ | `/premerge` | `forge sync`, doc updates, hand off PR |
575
583
  | `/verify` | Documentation cross-check |
576
584
 
577
585
  ---
@@ -582,13 +590,13 @@ irm https://raw.githubusercontent.com/steveyegge/beads/main/install.ps1 | iex
582
590
 
583
591
  ```bash
584
592
  bd init # Initialize
585
- bd ready # Find unblocked work
586
- bd create "Title" # Create issue
587
- bd show <id> # View details
588
- bd update <id> --status X # Update status
593
+ forge ready # Find unblocked work
594
+ forge create "Title" # Create issue
595
+ forge show <id> # View details
596
+ forge update <id> --status X # Update status
589
597
  bd dep add <a> <b> # a depends on b
590
- bd close <id> # Complete
591
- bd sync # Git sync
598
+ forge close <id> # Complete
599
+ forge sync # Beads sync
592
600
  ```
593
601
 
594
602
  ### GitHub CLI
@@ -626,12 +634,12 @@ irm https://raw.githubusercontent.com/steveyegge/beads/main/install.ps1 | iex
626
634
 
627
635
  **"database locked"**
628
636
  ```bash
629
- bd sync --force
637
+ forge sync
630
638
  ```
631
639
 
632
640
  **Issues not showing after git pull**
633
641
  ```bash
634
- bd sync # Re-imports from JSONL
642
+ forge sync # Re-syncs Beads state through the Forge wrapper
635
643
  ```
636
644
 
637
645
  ### GitHub CLI
@@ -12,6 +12,9 @@
12
12
  "directories": {
13
13
  "skills": ".codex/skills"
14
14
  },
15
+ "installTargets": {
16
+ "skills": "$CODEX_HOME/skills"
17
+ },
15
18
  "setup": {
16
19
  "copyRules": false,
17
20
  "createSkill": true
@@ -220,16 +220,19 @@ Configuration: \`.mcp.json\` or agent-specific config files
220
220
 
221
221
  ## Issue Tracking
222
222
 
223
- Use **Beads** for persistent tracking across sessions:
223
+ Use **Forge's Beads wrapper** for persistent tracking across sessions:
224
224
 
225
225
  \`\`\`bash
226
- bd create "Feature name" # Create issue
227
- bd update <id> --status in_progress # Claim work
228
- bd update <id> --comment "Progress" # Add notes
229
- bd close <id> # Complete
230
- bd sync # Sync with git
226
+ forge create "Feature name" # Create issue
227
+ forge claim <id> # Claim work
228
+ forge update <id> --append-notes "Progress" # Add notes
229
+ forge close <id> # Complete
230
+ forge sync # Sync Beads state
231
231
  \`\`\`
232
232
 
233
+ Use \`bd\` directly only for capabilities Forge does not wrap yet, such as
234
+ \`bd init\`, \`bd comments\`, \`bd dep\`, and \`bd dolt\`.
235
+
233
236
  ## Git Workflow
234
237
 
235
238
  **Branch naming**:
@@ -480,16 +483,19 @@ Configure these MCP servers in \`.mcp.json\`:
480
483
 
481
484
  ## Issue Tracking with Beads
482
485
 
483
- Use **Beads** for persistent tracking across sessions:
486
+ Use **Forge's Beads wrapper** for persistent tracking across sessions:
484
487
 
485
488
  \`\`\`bash
486
- bd create "Feature name" # Create issue
487
- bd update <id> --status in_progress # Claim work
488
- bd update <id> --append-notes "Progress" # Add notes
489
- bd close <id> # Complete
490
- bd sync # Sync with git
489
+ forge create "Feature name" # Create issue
490
+ forge claim <id> # Claim work
491
+ forge update <id> --append-notes "Progress" # Add notes
492
+ forge close <id> # Complete
493
+ forge sync # Sync Beads state
491
494
  \`\`\`
492
495
 
496
+ Use \`bd\` directly only for capabilities Forge does not wrap yet, such as
497
+ \`bd init\`, \`bd comments\`, \`bd dep\`, and \`bd dolt\`.
498
+
493
499
  ## Code Quality Standards
494
500
 
495
501
  ${meta.language === 'TypeScript' ? `
@@ -1,4 +1,5 @@
1
1
  const fs = require('node:fs');
2
+ const os = require('node:os');
2
3
  const path = require('node:path');
3
4
 
4
5
  function injectForgeAdapter(content, commandName) {
@@ -37,7 +38,6 @@ function listCodexSkillEntries(sourceRoot) {
37
38
 
38
39
  return {
39
40
  commandName,
40
- dir: `.codex/skills/${commandName}/`,
41
41
  filename: 'SKILL.md',
42
42
  content: injectForgeAdapter(fs.readFileSync(sourceFile, 'utf8'), commandName),
43
43
  };
@@ -45,6 +45,59 @@ function listCodexSkillEntries(sourceRoot) {
45
45
  .filter(Boolean);
46
46
  }
47
47
 
48
+ function resolveCodexHome(options = {}) {
49
+ const env = options.env || process.env;
50
+ const homeDir = options.homeDir || os.homedir();
51
+ const explicitHome = String(env.CODEX_HOME || '').trim();
52
+
53
+ if (explicitHome) {
54
+ return path.resolve(explicitHome);
55
+ }
56
+
57
+ return path.join(homeDir, '.codex');
58
+ }
59
+
60
+ function resolveCodexSkillsInstallDir(options = {}) {
61
+ return path.join(resolveCodexHome(options), 'skills');
62
+ }
63
+
64
+ function formatCodexSkillsInstallDir(options = {}) {
65
+ const installDir = resolveCodexSkillsInstallDir(options);
66
+ const homeDir = path.resolve(options.homeDir || os.homedir());
67
+ const explicitHome = String((options.env || process.env).CODEX_HOME || '').trim();
68
+ const normalizedInstallDir = installDir.replace(/\\/g, '/');
69
+
70
+ if (explicitHome) {
71
+ const explicitInstallDir = path.join(path.resolve(explicitHome), 'skills').replace(/\\/g, '/');
72
+ if (normalizedInstallDir === explicitInstallDir) {
73
+ return '$CODEX_HOME/skills';
74
+ }
75
+ }
76
+
77
+ const defaultInstallDir = path.join(homeDir, '.codex', 'skills').replace(/\\/g, '/');
78
+ if (normalizedInstallDir === defaultInstallDir) {
79
+ return '~/.codex/skills';
80
+ }
81
+
82
+ return normalizedInstallDir;
83
+ }
84
+
85
+ function buildCodexSkillInstallPlan(sourceRoot, options = {}) {
86
+ const installDir = resolveCodexSkillsInstallDir(options);
87
+ const displayRoot = formatCodexSkillsInstallDir(options);
88
+
89
+ return listCodexSkillEntries(sourceRoot).map((entry) => ({
90
+ ...entry,
91
+ absolutePath: path.join(installDir, entry.commandName, entry.filename),
92
+ displayPath: `${displayRoot}/${entry.commandName}/${entry.filename}`,
93
+ displayRoot,
94
+ }));
95
+ }
96
+
48
97
  module.exports = {
98
+ buildCodexSkillInstallPlan,
99
+ formatCodexSkillsInstallDir,
49
100
  listCodexSkillEntries,
101
+ resolveCodexHome,
102
+ resolveCodexSkillsInstallDir,
50
103
  };