forgedock 1.1.11 → 1.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 (109) hide show
  1. package/README.md +9 -3
  2. package/bin/cli-spawn-shared.mjs +25 -0
  3. package/bin/engine/phases.mjs +178 -28
  4. package/bin/engine/state.mjs +39 -7
  5. package/bin/engine-cli.mjs +85 -3
  6. package/bin/engine.mjs +71 -8
  7. package/bin/forgedock.mjs +322 -20
  8. package/bin/hooks/pre-tool-use.mjs +345 -10
  9. package/bin/init-enrich-api.mjs +12 -4
  10. package/bin/init-enrich-cli.mjs +328 -0
  11. package/bin/init-enrich.mjs +137 -0
  12. package/bin/journey.mjs +116 -15
  13. package/bin/runner.mjs +653 -10
  14. package/commands/adopt.md +1 -1
  15. package/commands/analytics.md +10 -7
  16. package/commands/audit-agents.md +29 -6
  17. package/commands/audit.md +9 -20
  18. package/commands/autopilot.md +52 -78
  19. package/commands/changelog.md +1 -1
  20. package/commands/ci-audit.md +19 -10
  21. package/commands/cleanup.md +1 -1
  22. package/commands/compat-audit.md +1 -1
  23. package/commands/deploy-info.md +1 -1
  24. package/commands/deploy-pr.md +1 -1
  25. package/commands/design-bench.md +1 -1
  26. package/commands/design-render-critique-loop.md +1 -1
  27. package/commands/diagnose.md +1 -1
  28. package/commands/forge-stats.md +6 -5
  29. package/commands/forgedock-init.md +1 -1
  30. package/commands/geo-audit.md +9 -6
  31. package/commands/incident-response.md +15 -5
  32. package/commands/issue.md +302 -15
  33. package/commands/milestone.md +45 -18
  34. package/commands/optimize.md +1 -1
  35. package/commands/orchestrate/phase-1-resolve.md +20 -5
  36. package/commands/orchestrate/phase-4-execution.md +8 -1
  37. package/commands/orchestrate/phase-5-cleanup.md +43 -2
  38. package/commands/orchestrate/phase-6-report.md +1 -0
  39. package/commands/orchestrate.md +1 -1
  40. package/commands/pipeline-health/phase-4-proposals.md +40 -10
  41. package/commands/pipeline-health/phase-5-report.md +140 -13
  42. package/commands/pipeline-health.md +1 -1
  43. package/commands/pipeline-resume.md +1 -1
  44. package/commands/pipeline-status.md +1 -1
  45. package/commands/qa-sweep.md +27 -4
  46. package/commands/recover-orphans.md +1 -1
  47. package/commands/replay.md +16 -2
  48. package/commands/review-pr-agents/protocols.md +4 -0
  49. package/commands/review-pr-agents/spec-cli.md +179 -0
  50. package/commands/review-pr-agents.md +7 -4
  51. package/commands/review-pr-staging.md +44 -15
  52. package/commands/review-pr.md +122 -28
  53. package/commands/rollback.md +15 -5
  54. package/commands/security-audit.md +14 -11
  55. package/commands/signal-planner.md +32 -12
  56. package/commands/spec-doctor.md +1 -1
  57. package/commands/sync-ecosystem.md +54 -11
  58. package/commands/test-gate.md +49 -11
  59. package/commands/upgrade-deps.md +518 -0
  60. package/commands/validate.md +16 -5
  61. package/commands/work-on/build/architect.md +1 -1
  62. package/commands/work-on/build/context.md +1 -1
  63. package/commands/work-on/build/implement.md +2 -2
  64. package/commands/work-on/build/validate.md +64 -2
  65. package/commands/work-on/build.md +10 -2
  66. package/commands/work-on/close.md +1 -1
  67. package/commands/work-on/decompose.md +35 -25
  68. package/commands/work-on/investigate.md +2 -2
  69. package/commands/work-on/remediate.md +1 -1
  70. package/commands/work-on/review.md +5 -3
  71. package/commands/work-on-monolithic.md +1 -1
  72. package/commands/work-on.md +28 -7
  73. package/docs/AIDER.md +264 -0
  74. package/docs/AUTOPILOT-CRON.md +130 -0
  75. package/docs/CI.md +18 -0
  76. package/docs/CONFIG.md +41 -2
  77. package/docs/CURSOR.md +135 -0
  78. package/docs/OPENCODE.md +312 -0
  79. package/docs/demo.gif +0 -0
  80. package/docs/eval/README.md +4 -4
  81. package/docs/launch/show-hn.md +3 -3
  82. package/docs/site/annotations-explained.md +2 -2
  83. package/docs/site/architecture.md +180 -0
  84. package/docs/site/command-reference.md +38 -0
  85. package/docs/site/configuration.md +243 -0
  86. package/docs/site/for-companies.md +4 -4
  87. package/docs/site/forge-annotation-protocol.md +1 -1
  88. package/docs/site/github-is-the-memory.md +2 -2
  89. package/docs/site/how-it-works.md +1 -1
  90. package/docs/site/public/llms-full.txt +380 -0
  91. package/docs/site/public/llms.txt +35 -0
  92. package/docs/spec/review-protocol.md +6 -0
  93. package/docs/spec-graph-schema.md +3 -3
  94. package/package.json +2 -2
  95. package/packages/protocol/README.md +75 -0
  96. package/packages/protocol/src/card.js +114 -0
  97. package/packages/protocol/src/cli.js +4 -77
  98. package/packages/protocol/src/emit.js +14 -3
  99. package/packages/protocol/src/index.js +2 -1
  100. package/packages/protocol/src/parse.js +17 -8
  101. package/packages/protocol/src/types.js +1 -1
  102. package/packages/protocol/src/validate.js +11 -0
  103. package/scripts/check-command-side-effects.sh +261 -0
  104. package/scripts/check-spec-markers.sh +273 -0
  105. package/scripts/classify-lane.sh +29 -7
  106. package/scripts/forge-run.sh +322 -0
  107. package/templates/cross-repo-trigger.yml +282 -0
  108. package/templates/cursor/forge.mdc +148 -0
  109. package/templates/github-actions/forgedock-autopilot.yml +113 -0
@@ -0,0 +1,518 @@
1
+ ---
2
+ description: Autonomous dependency upgrade pipeline — detect outdated dependencies, create upgrade issues, and run /work-on to investigate, build, test, and merge each upgrade
3
+ argument-hint: [--dry-run | --ecosystem npm|pip|cargo | --allow-major | --limit N | --batch]
4
+ ---
5
+ <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
+ <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
7
+
8
+ # /upgrade-deps — Autonomous Dependency Upgrade Pipeline
9
+
10
+ **Input**: $ARGUMENTS
11
+
12
+ You are a dependency upgrade agent. Your job is to detect outdated packages, triage them by semver risk level, create GitHub issues for eligible upgrades, and run them through the full `/work-on` pipeline — so each upgrade gets investigation, compatibility verification, quality gate, review, and merge — rather than a blind version bump PR.
13
+
14
+ **Agent model policy**: Default `model: "sonnet"`. If Sonnet is rate-limited, fall back to `model: "opus"`.
15
+ **NEVER use plan mode (EnterPlanMode).**
16
+
17
+ ---
18
+
19
+ ## Argument Parsing
20
+
21
+ | Flag | Effect |
22
+ |------|--------|
23
+ | (none) | Detect + triage + report (no issue creation, no fixing) |
24
+ | `--dry-run` | Run all phases but do NOT create issues, PRs, or labels — report only |
25
+ | `--ecosystem npm` | Limit detection to npm only |
26
+ | `--ecosystem pip` | Limit detection to pip only |
27
+ | `--ecosystem cargo` | Limit detection to cargo only |
28
+ | `--allow-major` | Include major upgrades in issue creation (default: flag for human review only) |
29
+ | `--limit N` | Cap issue creation to at most N issues per run (default: 10) |
30
+ | `--batch` | Group all patch upgrades into one batch issue instead of one-per-package |
31
+ | `--fix` | After issue creation, also invoke `/work-on` on each created issue |
32
+
33
+ Parse `$ARGUMENTS`:
34
+
35
+ ```bash
36
+ DRY_RUN=false
37
+ ECOSYSTEM_FILTER=""
38
+ ALLOW_MAJOR=false
39
+ ISSUE_LIMIT=10
40
+ BATCH_PATCHES=false
41
+ DO_FIX=false
42
+ NEXT_IS_ECOSYSTEM=false
43
+ NEXT_IS_LIMIT=false
44
+
45
+ for arg in $ARGUMENTS; do
46
+ case "$arg" in
47
+ --dry-run) DRY_RUN=true ;;
48
+ --allow-major) ALLOW_MAJOR=true ;;
49
+ --batch) BATCH_PATCHES=true ;;
50
+ --fix) DO_FIX=true ;;
51
+ --ecosystem) NEXT_IS_ECOSYSTEM=true ;;
52
+ --limit) NEXT_IS_LIMIT=true ;;
53
+ *)
54
+ if [ "$NEXT_IS_ECOSYSTEM" = "true" ]; then
55
+ ECOSYSTEM_FILTER="$arg"
56
+ NEXT_IS_ECOSYSTEM=false
57
+ elif [ "$NEXT_IS_LIMIT" = "true" ]; then
58
+ ISSUE_LIMIT="$arg"
59
+ NEXT_IS_LIMIT=false
60
+ fi
61
+ ;;
62
+ esac
63
+ done
64
+ ```
65
+
66
+ If `DRY_RUN=true`, prefix all actions with `[DRY RUN]` and skip all `gh issue create`, `gh issue edit`, and `Skill()` invocations — report what would happen instead.
67
+
68
+ ---
69
+
70
+ ## Phase 0: Config Resolution
71
+
72
+ **Config variables used by this command** (set in `forge.yaml → upgrade_deps`):
73
+ - `{ECOSYSTEMS}` ← `upgrade_deps.ecosystems` — list of ecosystems to check (default: `["npm"]`)
74
+ - `{ALLOW_MAJOR_CONFIG}` ← `upgrade_deps.allow_major` (default: `false`) — whether to create issues for major upgrades
75
+ - `{EXCLUDE_PACKAGES}` ← `upgrade_deps.exclude` — list of package names to skip regardless of semver level
76
+ - `{ISSUE_BATCH_SIZE}` ← `upgrade_deps.issue_batch_size` — how many patch packages to group per batch issue (default: 5)
77
+
78
+ Read `forge.yaml` at the project root before running any phase:
79
+
80
+ ```bash
81
+ CONFIG_FILE="${FORGE_CONFIG:-forge.yaml}"
82
+ if [ ! -f "$CONFIG_FILE" ]; then
83
+ echo "ERROR: forge.yaml not found. Run: npx forgedock init && /forgedock-init"
84
+ exit 1
85
+ fi
86
+
87
+ GH_REPO=$(yq '.project.owner + "/" + .project.repo' "$CONFIG_FILE")
88
+ GH_FLAG="-R $GH_REPO"
89
+ REPO_PATH=$(yq '.paths.root' "$CONFIG_FILE")
90
+ STAGING_BRANCH=$(yq '.branches.staging // "staging"' "$CONFIG_FILE")
91
+
92
+ # upgrade_deps section (all optional — fall back to defaults)
93
+ ECOSYSTEMS_CONFIG=$(yq '.upgrade_deps.ecosystems // ["npm"] | join(" ")' "$CONFIG_FILE" 2>/dev/null || echo "npm")
94
+ ALLOW_MAJOR_CONFIG=$(yq '.upgrade_deps.allow_major // false' "$CONFIG_FILE" 2>/dev/null || echo "false")
95
+ EXCLUDE_PACKAGES=$(yq '.upgrade_deps.exclude // [] | join(" ")' "$CONFIG_FILE" 2>/dev/null || echo "")
96
+ ISSUE_BATCH_SIZE=$(yq '.upgrade_deps.issue_batch_size // 5' "$CONFIG_FILE" 2>/dev/null || echo "5")
97
+
98
+ # CLI flags override config values
99
+ [ "$ECOSYSTEM_FILTER" != "" ] && ECOSYSTEMS_CONFIG="$ECOSYSTEM_FILTER"
100
+ [ "$ALLOW_MAJOR" = "true" ] && ALLOW_MAJOR_CONFIG="true"
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Phase 1: Detect Outdated Dependencies
106
+
107
+ Run dependency detection for each configured ecosystem. Skip an ecosystem if its tool is not installed.
108
+
109
+ ### 1A: npm
110
+
111
+ ```bash
112
+ if echo "$ECOSYSTEMS_CONFIG" | grep -q "npm"; then
113
+ if command -v npm >/dev/null 2>&1; then
114
+ echo "--- npm ecosystem ---"
115
+ cd "$REPO_PATH"
116
+ NPM_OUTDATED=$(npm outdated --json 2>/dev/null || echo "{}")
117
+ echo "$NPM_OUTDATED" | python3 -c "
118
+ import json, sys
119
+ data = json.load(sys.stdin)
120
+ for pkg, info in data.items():
121
+ current = info.get('current', 'N/A')
122
+ wanted = info.get('wanted', 'N/A')
123
+ latest = info.get('latest', 'N/A')
124
+ print(f'{pkg}|{current}|{wanted}|{latest}')
125
+ " 2>/dev/null || true
126
+ else
127
+ echo "npm not installed — skipping npm ecosystem"
128
+ fi
129
+ fi
130
+ ```
131
+
132
+ ### 1B: pip
133
+
134
+ ```bash
135
+ if echo "$ECOSYSTEMS_CONFIG" | grep -q "pip"; then
136
+ PIP_CMD=""
137
+ command -v pip3 >/dev/null 2>&1 && PIP_CMD="pip3"
138
+ command -v pip >/dev/null 2>&1 && PIP_CMD="${PIP_CMD:-pip}"
139
+
140
+ if [ -n "$PIP_CMD" ]; then
141
+ echo "--- pip ecosystem ---"
142
+ $PIP_CMD list --outdated --format=json 2>/dev/null | python3 -c "
143
+ import json, sys
144
+ data = json.load(sys.stdin)
145
+ for pkg in data:
146
+ print(f'{pkg[\"name\"]}|{pkg[\"version\"]}|{pkg[\"latest_version\"]}')
147
+ " 2>/dev/null || true
148
+ else
149
+ echo "pip/pip3 not installed — skipping pip ecosystem"
150
+ fi
151
+ fi
152
+ ```
153
+
154
+ ### 1C: cargo
155
+
156
+ ```bash
157
+ if echo "$ECOSYSTEMS_CONFIG" | grep -q "cargo"; then
158
+ if command -v cargo >/dev/null 2>&1 && command -v cargo-outdated >/dev/null 2>&1; then
159
+ echo "--- cargo ecosystem ---"
160
+ cd "$REPO_PATH"
161
+ cargo outdated --format json 2>/dev/null | python3 -c "
162
+ import json, sys
163
+ try:
164
+ data = json.load(sys.stdin)
165
+ for dep in data.get('dependencies', []):
166
+ name = dep.get('name', '')
167
+ project = dep.get('project', 'N/A')
168
+ latest = dep.get('latest', 'N/A')
169
+ print(f'{name}|{project}|{latest}')
170
+ except: pass
171
+ " 2>/dev/null || true
172
+ else
173
+ command -v cargo >/dev/null 2>&1 || echo "cargo not installed — skipping cargo ecosystem"
174
+ command -v cargo-outdated >/dev/null 2>&1 || echo "cargo-outdated not installed — run: cargo install cargo-outdated"
175
+ fi
176
+ fi
177
+ ```
178
+
179
+ ### 1D: Aggregate results
180
+
181
+ Collect all detected outdated packages into a structured list:
182
+
183
+ ```
184
+ OUTDATED_PACKAGES = [
185
+ { name, current_version, latest_version, semver_level, ecosystem }
186
+ ]
187
+ ```
188
+
189
+ Compute `semver_level` for each package:
190
+ - **patch**: major and minor match (e.g., 1.2.3 → 1.2.9)
191
+ - **minor**: major matches, minor differs (e.g., 1.2.3 → 1.5.0)
192
+ - **major**: major version differs (e.g., 1.x.x → 2.x.x)
193
+
194
+ ---
195
+
196
+ ## Phase 2: Triage
197
+
198
+ **Goal**: Filter, classify, and rank the detected upgrades.
199
+
200
+ ### 2A: Apply exclusions
201
+
202
+ ```bash
203
+ # Filter out packages in the EXCLUDE_PACKAGES list
204
+ for pkg in $EXCLUDE_PACKAGES; do
205
+ echo "Skipping excluded package: $pkg"
206
+ # Remove from OUTDATED_PACKAGES
207
+ done
208
+ ```
209
+
210
+ ### 2B: Apply semver gate
211
+
212
+ - **patch** and **minor**: eligible for issue creation (default behavior)
213
+ - **major**: eligible only if `ALLOW_MAJOR_CONFIG=true` or `--allow-major` was passed; otherwise, flag for human review
214
+
215
+ ### 2C: Deduplication — skip if open issue already tracks this upgrade
216
+
217
+ Before creating any issue, check for existing open issues that already track the same package upgrade:
218
+
219
+ ```bash
220
+ for pkg in ${ELIGIBLE_PACKAGES}; do
221
+ # Pass $pkg to jq via the environment (env.PKG) instead of splicing it into the
222
+ # jq program text — avoids breaking the outer quoting if $pkg ever contained a
223
+ # single quote or other shell-meaningful character.
224
+ export PKG="$pkg"
225
+ EXISTING=$(gh issue list $GH_FLAG --state open \
226
+ --search "upgrade $pkg" --limit 5 \
227
+ --json number,title \
228
+ --jq '.[] | select(.title | test("upgrade.*" + env.PKG; "i")) | .number' 2>/dev/null | head -1)
229
+
230
+ if [ -n "$EXISTING" ]; then
231
+ echo "Skipping $pkg — open issue #$EXISTING already tracks this upgrade"
232
+ # Add $pkg to SKIPPED list with reason "existing-issue:#$EXISTING"
233
+ fi
234
+ done
235
+ ```
236
+
237
+ ### 2D: Apply limit
238
+
239
+ Cap the final eligible list to `$ISSUE_LIMIT` packages. Prioritize by semver impact:
240
+ 1. minor upgrades (higher value)
241
+ 2. patch upgrades (lower value, safe to batch)
242
+
243
+ If `BATCH_PATCHES=true`, group all patch-level packages into one batch issue (up to `$ISSUE_BATCH_SIZE` per batch issue).
244
+
245
+ ### 2E: Major upgrade report (human review required)
246
+
247
+ For major upgrades when `ALLOW_MAJOR_CONFIG=false`, collect them for the summary report but do NOT create issues. Print:
248
+
249
+ ```
250
+ Major upgrades detected (not auto-processed — require human review):
251
+ {package}: {current} → {latest} [major]
252
+ ```
253
+
254
+ ---
255
+
256
+ ## Phase 3: Issue Creation
257
+
258
+ For each eligible package (or batch), create a GitHub issue:
259
+
260
+ ### 3A: Per-package issue (patch or minor, non-batched)
261
+
262
+ ```bash
263
+ # DRY_RUN guard — must stay above the create it guards (forge#1609). In dry-run
264
+ # mode print the would-be issue and move on; never create it.
265
+ if [ "$DRY_RUN" = "true" ]; then
266
+ echo "[DRY RUN] Would create issue: feat(deps): upgrade {PACKAGE} from {CURRENT} to {LATEST} ({SEMVER_LEVEL})"
267
+ else
268
+ gh issue create $GH_FLAG \
269
+ --title "feat(deps): upgrade {PACKAGE} from {CURRENT} to {LATEST} ({SEMVER_LEVEL})" \
270
+ --label "enhancement" \
271
+ --body "$(cat <<'ISSUE_EOF'
272
+ ## Problem
273
+
274
+ {PACKAGE} is outdated: current version {CURRENT}, latest is {LATEST} ({SEMVER_LEVEL} bump).
275
+
276
+ Dependency upgrades are repetitive, well-scoped work. This issue tracks the upgrade through the full ForgeDock pipeline: investigate compatibility, implement the upgrade, run tests, review, and merge.
277
+
278
+ ## Affected Files
279
+
280
+ Files that may need changes:
281
+ 1. `package.json` / `requirements.txt` / `Cargo.toml` — version constraint update
282
+ 2. Lockfile (`package-lock.json` / `poetry.lock` / `Cargo.lock`) — regenerated by install command
283
+
284
+ Additional files will be identified if the new version has breaking changes requiring code updates.
285
+
286
+ ## Expected Behavior
287
+
288
+ - Package is updated to {LATEST} (or the highest compatible version within {SEMVER_LEVEL} range)
289
+ - All existing tests pass
290
+ - No breaking changes introduced
291
+
292
+ ## Acceptance Criteria
293
+
294
+ - [ ] `{PACKAGE}` version updated from `{CURRENT}` to `{LATEST}` in the manifest
295
+ - [ ] Lockfile regenerated (`npm install` / `pip install` / `cargo update`)
296
+ - [ ] Test suite passes (no regressions)
297
+ - [ ] Breaking changes identified and addressed (especially for minor upgrades)
298
+ - [ ] CHANGELOG or release notes consulted for deprecation notices
299
+
300
+ ## Context
301
+
302
+ **Ecosystem**: {ECOSYSTEM}
303
+ **Semver level**: {SEMVER_LEVEL}
304
+ **Detected by**: `/upgrade-deps` cycle on {DATE}
305
+ **Release notes**: https://www.npmjs.com/package/{PACKAGE}/v/{LATEST} (adjust URL for ecosystem)
306
+
307
+ ---
308
+ *Created by `/upgrade-deps`. Will be validated before any changes are applied.*
309
+ ISSUE_EOF
310
+ )"
311
+ fi
312
+ ```
313
+
314
+ ### 3B: Batch patch issue (when `--batch` is set)
315
+
316
+ Group multiple patch-level packages into one issue:
317
+
318
+ ```bash
319
+ BATCH_PACKAGE_LIST=$(printf '- `%s`: %s → %s\n' {PACKAGE} {CURRENT} {LATEST})
320
+
321
+ # DRY_RUN guard — must stay above the create it guards (forge#1609).
322
+ if [ "$DRY_RUN" = "true" ]; then
323
+ echo "[DRY RUN] Would create batch issue: feat(deps): batch patch upgrades — {COUNT} packages ({DATE})"
324
+ echo "[DRY RUN] Packages: $BATCH_PACKAGE_LIST"
325
+ else
326
+ gh issue create $GH_FLAG \
327
+ --title "feat(deps): batch patch upgrades — {COUNT} packages ({DATE})" \
328
+ --label "enhancement" \
329
+ --body "$(cat <<'BATCH_ISSUE_EOF'
330
+ ## Problem
331
+
332
+ {COUNT} dependencies have patch-level updates available. Patch upgrades are low-risk (semver guarantees no breaking changes) and are batched here for efficiency.
333
+
334
+ ## Packages in This Batch
335
+
336
+ {BATCH_PACKAGE_LIST}
337
+
338
+ ## Affected Files
339
+
340
+ 1. `package.json` / `requirements.txt` / `Cargo.toml` — version constraint updates
341
+ 2. Lockfile — regenerated after all updates
342
+
343
+ ## Expected Behavior
344
+
345
+ All listed packages updated to their latest patch version. Full test suite passes.
346
+
347
+ ## Acceptance Criteria
348
+
349
+ - [ ] All listed packages updated in the manifest
350
+ - [ ] Lockfile regenerated
351
+ - [ ] Test suite passes with no regressions
352
+
353
+ ## Context
354
+
355
+ **Ecosystem**: {ECOSYSTEM}
356
+ **Semver level**: patch (all)
357
+ **Detected by**: `/upgrade-deps` cycle on {DATE}
358
+
359
+ ---
360
+ *Batch created by `/upgrade-deps`. Investigate step will verify each package's patch notes.*
361
+ BATCH_ISSUE_EOF
362
+ )"
363
+ fi
364
+ ```
365
+
366
+ **DRY_RUN check**: enforced inline in 3A and 3B above — the guard wraps each `gh issue create` rather than being stated after it, so a dry run cannot create issues even if only one section is read in isolation (forge#1609).
367
+
368
+ Store created issue numbers as `CREATED_ISSUES` (empty when `DRY_RUN=true`).
369
+
370
+ ---
371
+
372
+ ## Phase 4: Fix (requires `--fix` flag)
373
+
374
+ **Skip unless `--fix` was passed.**
375
+
376
+ For each issue in `CREATED_ISSUES`, invoke `/work-on` via the Skill tool:
377
+
378
+ ```
379
+ Skill(skill: "work-on", args: "{ISSUE_NUMBER}")
380
+ ```
381
+
382
+ Run **sequentially** — each `/work-on` invocation is heavyweight. If one fails, continue to the next and record the outcome.
383
+
384
+ Track outcomes:
385
+
386
+ ```
387
+ FIX_RESULTS = [
388
+ { issue: NUMBER, outcome: "merged" | "invalid" | "failed" | "needs-human", pr: PR_NUMBER | null }
389
+ ]
390
+ ```
391
+
392
+ **DRY_RUN check**: If `DRY_RUN=true`, print what would be invoked but skip `Skill()` calls.
393
+
394
+ ---
395
+
396
+ ## Phase 5: Summary Report
397
+
398
+ Print a structured report at the end of every run:
399
+
400
+ ```markdown
401
+ ## /upgrade-deps Cycle Report — {DATE}
402
+
403
+ ### Detection Results
404
+ | Ecosystem | Outdated | Eligible | Skipped (existing issue) | Skipped (excluded) | Major (human review) |
405
+ |-----------|----------|----------|--------------------------|-------------------|----------------------|
406
+ | npm | {N} | {N} | {N} | {N} | {N} |
407
+ | pip | {N} | {N} | {N} | {N} | {N} |
408
+
409
+ ### Issues Created
410
+ {list with issue numbers and titles, or "None — use --fix=false dry-run or no --fix flag"}
411
+
412
+ ### Major Upgrades (Human Review Required)
413
+ {list: package: current → latest [major], or "None detected"}
414
+
415
+ ### Fix Results (only if --fix was passed)
416
+ | Issue | Package | Outcome | PR |
417
+ |-------|---------|---------|-----|
418
+ | #{N} | {pkg} | merged | #{PR} |
419
+
420
+ ### Next Steps
421
+ - [ ] Review major upgrades above and create issues manually if appropriate
422
+ - [ ] Set `upgrade_deps.exclude` in `forge.yaml` for packages that should never auto-upgrade
423
+ - [ ] Run `/upgrade-deps --fix` to also execute the pipeline for created issues
424
+ ```
425
+
426
+ ---
427
+
428
+ ## Scheduling via GitHub Actions
429
+
430
+ To run `/upgrade-deps` on a schedule, add a workflow to `.github/workflows/upgrade-deps.yml` in your project:
431
+
432
+ ```yaml
433
+ # .github/workflows/upgrade-deps.yml
434
+ # Runs /upgrade-deps weekly — creates GitHub issues for outdated deps.
435
+ # Issues flow through the ForgeDock pipeline: investigate → build → review → merge.
436
+ name: Weekly Dependency Upgrade Check
437
+
438
+ on:
439
+ schedule:
440
+ - cron: '0 9 * * 1' # Every Monday at 09:00 UTC
441
+ workflow_dispatch: # Allow manual trigger
442
+
443
+ jobs:
444
+ upgrade-deps:
445
+ runs-on: ubuntu-latest
446
+ permissions:
447
+ contents: read
448
+ issues: write
449
+
450
+ steps:
451
+ - uses: actions/checkout@v4
452
+
453
+ - name: Set up Claude Code
454
+ run: npm install -g @anthropic-ai/claude-code
455
+
456
+ - name: Run /upgrade-deps
457
+ env:
458
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
459
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
460
+ run: |
461
+ claude -p "/upgrade-deps --limit 5" --allowedTools "Bash,Read,Write,Edit,Glob,Grep"
462
+ ```
463
+
464
+ > **Note**: The workflow above creates issues only (no `--fix`). To also invoke `/work-on` from CI, add `--fix` to the claude command. Each `/work-on` run uses Anthropic API credits proportional to issue complexity. Review your budget before enabling `--fix` in scheduled workflows.
465
+
466
+ ---
467
+
468
+ ## forge.yaml Configuration Reference
469
+
470
+ Add an `upgrade_deps` section to your `forge.yaml` to configure the command:
471
+
472
+ ```yaml
473
+ # upgrade_deps (OPTIONAL)
474
+ # Controls /upgrade-deps behavior.
475
+ upgrade_deps:
476
+ # Ecosystems to check (default: ["npm"])
477
+ ecosystems:
478
+ - npm
479
+ - pip
480
+ # - cargo # requires: cargo install cargo-outdated
481
+
482
+ # Whether to create issues for major version upgrades (default: false)
483
+ # Major upgrades carry breaking-change risk — enable only with human review process.
484
+ allow_major: false
485
+
486
+ # Packages to never auto-upgrade (excluded from issue creation and /work-on)
487
+ # Useful for packages with known breaking changes or intentional version pins.
488
+ exclude:
489
+ # - "some-package" # example: pinned intentionally
490
+
491
+ # How many patch packages to group per batch issue when --batch is used (default: 5)
492
+ issue_batch_size: 5
493
+ ```
494
+
495
+ ---
496
+
497
+ ## Safety Rules
498
+
499
+ 1. **NEVER bump a major version without `--allow-major`** — major upgrades have breaking-change risk and require human review.
500
+ 2. **NEVER bypass the deduplication check** — if an open issue already tracks an upgrade, skip it.
501
+ 3. **NEVER create more than `ISSUE_LIMIT` issues per run** — prevents runaway issue flooding.
502
+ 4. **NEVER skip `/work-on` investigation** — every upgrade goes through full pipeline (investigate compatibility, build, test, review). A blind version bump PR is not a valid outcome.
503
+ 5. **DRY_RUN means NO side effects** — no issues created, no `/work-on` calls. Report only.
504
+ 6. **NEVER run cargo-outdated if cargo-outdated is not installed** — detect tool availability first.
505
+ 7. **NEVER upgrade excluded packages** — respect the `upgrade_deps.exclude` list in `forge.yaml`.
506
+
507
+ ---
508
+
509
+ ## Integration with /autopilot
510
+
511
+ `/upgrade-deps` is a peer to `/autopilot` — both create issues and optionally invoke `/work-on`. They are complementary:
512
+
513
+ | Command | Signal source | Scope |
514
+ |---------|--------------|-------|
515
+ | `/autopilot` | Production health, CI failures, backlog | Platform operational health |
516
+ | `/upgrade-deps` | Package registries (npm, pip, cargo) | Dependency freshness |
517
+
518
+ `/autopilot` does NOT detect outdated dependencies. Use `/upgrade-deps` for dependency-specific work, and pair it with `/autopilot` for full-spectrum platform maintenance.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Independently verify if a reported issue is actually a problem before making code changes.
3
- argument-hint: [issue description or #number]
3
+ argument-hint: "[issue description or #number]"
4
4
  install: extras
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -91,10 +91,17 @@ If CONFIRMED — recommended next step:
91
91
  Root cause: [one sentence]
92
92
  Fix approach: [one sentence]
93
93
  Create issue:
94
+ Route through the `/issue` create-hook's programmatic invocation contract (see `commands/issue.md` § "Programmatic Invocation Contract") instead of calling the raw issue-creation command directly — this gets dedup (Phase 2D) and body validation (Phase 3F) for free:
95
+
94
96
  ```bash
95
- gh issue create --title "fix: [concise description of the confirmed bug]" \
96
- --label "[priority],[bug|enhancement]" \
97
- --body "$(cat <<'BODY_EOF'
97
+ VALIDATE_ISSUE_TITLE="fix: [concise description of the confirmed bug]"
98
+ # Defense-in-depth: /issue's arg tokenizer (commands/issue.md, forge#2094) uses
99
+ # an xargs-based tokenizer that never expands backtick/$(...) substitution, so
100
+ # this is no longer required for safety — but strip it anyway so the raw title
101
+ # stays readable if it round-trips through any other eval-based consumer.
102
+ VALIDATE_ISSUE_TITLE=$(printf '%s' "$VALIDATE_ISSUE_TITLE" | tr '`' "'" | sed 's/\$(/$ (/g')
103
+ VALIDATE_ISSUE_BODY_FILE=$(mktemp)
104
+ cat <<'BODY_EOF' > "$VALIDATE_ISSUE_BODY_FILE"
98
105
  ## Problem
99
106
 
100
107
  [1-3 sentences: what the validation confirmed is wrong. Specific and concrete.]
@@ -123,7 +130,11 @@ Validated by \`/validate\` on [DATE]. Confidence: [High|Medium|Low].
123
130
  - [source]: [finding]
124
131
  - [source]: [finding]
125
132
  BODY_EOF
126
- )"
133
+
134
+ # [priority] and [bug|enhancement] are two separate labels — passed as repeated --label flags,
135
+ # never comma-joined (the /issue programmatic contract's --label is repeatable, not CSV).
136
+ Skill(skill="issue", args="--title \"$VALIDATE_ISSUE_TITLE\" --body-file \"$VALIDATE_ISSUE_BODY_FILE\" --label \"[priority]\" --label \"[bug|enhancement]\"")
137
+ rm -f "$VALIDATE_ISSUE_BODY_FILE"
127
138
  ```
128
139
 
129
140
  If NOT A PROBLEM — why the report was wrong:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Pre-implementation architecture planning — traces ALL affected code paths and produces an ordered implementation plan before any code is written
3
- argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--files AFFECTED_FILES]
3
+ argument-hint: "[issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--files AFFECTED_FILES]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Pre-implementation context gathering — surfaces historical findings, bug patterns, and related code paths before the builder writes any code
3
- argument-hint: [issue number] [affected_files...] [--functions function_names...]
3
+ argument-hint: "[issue number] [affected_files...] [--functions function_names...]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Implementation agent — writes code, makes commits, posts builder comment
3
- argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--worktree PATH] [--branch BRANCH]
3
+ argument-hint: "[issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--worktree PATH] [--branch BRANCH]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -102,7 +102,7 @@ Extract from contract:
102
102
  | Refactor / Maintenance | Implement directly following contract deliverables |
103
103
  | Investigation | Spawn research agents, create GitHub issues for findings, skip to I5 |
104
104
 
105
- **Investigation task special case**: Research deeply, create GitHub issues for each finding using the Pipeline Issue Template (see `commands/issue.md` § "Pipeline Issue Template"). Each issue MUST include `## Problem`, `## Affected Files`, and `## Acceptance Criteria`. Use `gh issue create {GH_FLAG}` with a fully-structured body. Post a deliverables comment listing the created issues, close the original issue, return `IMPLEMENT_RESULT: status: INVESTIGATION_COMPLETE`.
105
+ **Investigation task special case**: Research deeply, create GitHub issues for each finding using the Pipeline Issue Template (see `commands/issue.md` § "Pipeline Issue Template"). Each issue MUST include `## Problem`, `## Affected Files`, and `## Acceptance Criteria`. Create each issue via the `/issue` create-hook's programmatic invocation contract (see `commands/issue.md` § "Programmatic Invocation Contract") — `Skill(skill="issue", args="--title \"...\" --body-file <path> --label ...")` — instead of calling the raw issue-creation command directly; this gets dedup and body validation for free. Post a deliverables comment listing the created issues, close the original issue, return `IMPLEMENT_RESULT: status: INVESTIGATION_COMPLETE`.
106
106
 
107
107
  ---
108
108