multi-forge 0.2.0__py3-none-any.whl

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 (311) hide show
  1. forge/__init__.py +3 -0
  2. forge/_extensions/agents/.gitkeep +0 -0
  3. forge/_extensions/commands/.gitkeep +0 -0
  4. forge/_extensions/skills/analyze/SKILL.md +87 -0
  5. forge/_extensions/skills/challenge/SKILL.md +91 -0
  6. forge/_extensions/skills/consensus/SKILL.md +120 -0
  7. forge/_extensions/skills/consensus/resources/code_consensus_evaluation.md +94 -0
  8. forge/_extensions/skills/consensus/resources/consensus_evaluation.md +70 -0
  9. forge/_extensions/skills/consensus/resources/synthesis.md +101 -0
  10. forge/_extensions/skills/debate/SKILL.md +116 -0
  11. forge/_extensions/skills/debate/resources/code_debate_evaluation.md +101 -0
  12. forge/_extensions/skills/debate/resources/debate_evaluation.md +90 -0
  13. forge/_extensions/skills/panel/SKILL.md +141 -0
  14. forge/_extensions/skills/panel/resources/synthesis.md +103 -0
  15. forge/_extensions/skills/qa/SKILL.md +704 -0
  16. forge/_extensions/skills/qa/resources/checklist/0-enable.md +78 -0
  17. forge/_extensions/skills/qa/resources/checklist/1-preflight.md +24 -0
  18. forge/_extensions/skills/qa/resources/checklist/10-resume.md +143 -0
  19. forge/_extensions/skills/qa/resources/checklist/11-config.md +150 -0
  20. forge/_extensions/skills/qa/resources/checklist/12-search.md +58 -0
  21. forge/_extensions/skills/qa/resources/checklist/13-guard.md +237 -0
  22. forge/_extensions/skills/qa/resources/checklist/14-workflow.md +305 -0
  23. forge/_extensions/skills/qa/resources/checklist/15-skills.md +155 -0
  24. forge/_extensions/skills/qa/resources/checklist/16-handoff.md +224 -0
  25. forge/_extensions/skills/qa/resources/checklist/17-info.md +50 -0
  26. forge/_extensions/skills/qa/resources/checklist/18-disable.md +84 -0
  27. forge/_extensions/skills/qa/resources/checklist/19-uninstall.md +146 -0
  28. forge/_extensions/skills/qa/resources/checklist/2-extensions.md +188 -0
  29. forge/_extensions/skills/qa/resources/checklist/20-cleanup.md +36 -0
  30. forge/_extensions/skills/qa/resources/checklist/3-auth.md +234 -0
  31. forge/_extensions/skills/qa/resources/checklist/4-proxy.md +481 -0
  32. forge/_extensions/skills/qa/resources/checklist/5-session.md +541 -0
  33. forge/_extensions/skills/qa/resources/checklist/6-hooks.md +275 -0
  34. forge/_extensions/skills/qa/resources/checklist/7-costs.md +309 -0
  35. forge/_extensions/skills/qa/resources/checklist/8-status-line.md +174 -0
  36. forge/_extensions/skills/qa/resources/checklist/9-direct-commands.md +146 -0
  37. forge/_extensions/skills/qa/resources/checklist.md +103 -0
  38. forge/_extensions/skills/qa/resources/report-template.md +62 -0
  39. forge/_extensions/skills/qa/scripts/start-container.sh +529 -0
  40. forge/_extensions/skills/qa/scripts/walkthrough-state.py +1137 -0
  41. forge/_extensions/skills/review/SKILL.md +125 -0
  42. forge/_extensions/skills/review/references/claude-4.6.md +474 -0
  43. forge/_extensions/skills/review/references/claude-4.7.md +710 -0
  44. forge/_extensions/skills/review/references/gemini-3.1.md +546 -0
  45. forge/_extensions/skills/review/references/gpt-5.5.md +490 -0
  46. forge/_extensions/skills/review/references/skills-writing-guide.md +1588 -0
  47. forge/_extensions/skills/review/resources/code-anthropic.md +160 -0
  48. forge/_extensions/skills/review/resources/code-gemini.md +184 -0
  49. forge/_extensions/skills/review/resources/code-openai.md +203 -0
  50. forge/_extensions/skills/review/resources/code.md +160 -0
  51. forge/_extensions/skills/review-docs/SKILL.md +121 -0
  52. forge/_extensions/skills/review-docs/resources/docs-anthropic.md +170 -0
  53. forge/_extensions/skills/review-docs/resources/docs-gemini.md +204 -0
  54. forge/_extensions/skills/review-docs/resources/docs-openai.md +231 -0
  55. forge/_extensions/skills/review-docs/resources/docs.md +170 -0
  56. forge/_extensions/skills/smoke-test/SKILL.md +27 -0
  57. forge/_extensions/skills/smoke-test/scripts/smoke-test.sh +118 -0
  58. forge/_extensions/skills/understand/SKILL.md +148 -0
  59. forge/_extensions/skills/understand/resources/code-anthropic.md +163 -0
  60. forge/_extensions/skills/understand/resources/code-gemini.md +194 -0
  61. forge/_extensions/skills/understand/resources/code-openai.md +181 -0
  62. forge/_extensions/skills/understand/resources/code.md +163 -0
  63. forge/_extensions/skills/understand/resources/docs-anthropic.md +177 -0
  64. forge/_extensions/skills/understand/resources/docs-gemini.md +202 -0
  65. forge/_extensions/skills/understand/resources/docs-openai.md +191 -0
  66. forge/_extensions/skills/understand/resources/docs.md +177 -0
  67. forge/_extensions/skills/walkthrough/SKILL.md +599 -0
  68. forge/_extensions/skills/walkthrough/resources/checklist.md +765 -0
  69. forge/_extensions/skills/walkthrough/scripts/run-in-repo.sh +118 -0
  70. forge/_extensions/skills/walkthrough/scripts/setup-test-repo.sh +198 -0
  71. forge/_extensions/skills/walkthrough/scripts/walkthrough-state.py +1137 -0
  72. forge/backend/__init__.py +174 -0
  73. forge/backend/adapters/__init__.py +38 -0
  74. forge/backend/adapters/litellm.py +158 -0
  75. forge/backend/creation.py +89 -0
  76. forge/backend/registry.py +178 -0
  77. forge/cli/__init__.py +16 -0
  78. forge/cli/auth.py +483 -0
  79. forge/cli/backend.py +298 -0
  80. forge/cli/claude.py +411 -0
  81. forge/cli/config_cmd.py +303 -0
  82. forge/cli/extensions.py +1001 -0
  83. forge/cli/gc.py +165 -0
  84. forge/cli/guard.py +1018 -0
  85. forge/cli/guards.py +106 -0
  86. forge/cli/handoff.py +110 -0
  87. forge/cli/hooks/__init__.py +36 -0
  88. forge/cli/hooks/_group.py +20 -0
  89. forge/cli/hooks/_helpers.py +149 -0
  90. forge/cli/hooks/commands.py +1677 -0
  91. forge/cli/hooks/direct_commands.py +1304 -0
  92. forge/cli/hooks/install.py +232 -0
  93. forge/cli/hooks/policy.py +151 -0
  94. forge/cli/hooks/read_hygiene.py +74 -0
  95. forge/cli/hooks/verification.py +370 -0
  96. forge/cli/logs.py +406 -0
  97. forge/cli/main.py +292 -0
  98. forge/cli/proxy.py +1821 -0
  99. forge/cli/proxy_costs.py +313 -0
  100. forge/cli/search.py +416 -0
  101. forge/cli/session.py +892 -0
  102. forge/cli/session_addendum.py +81 -0
  103. forge/cli/session_fork.py +750 -0
  104. forge/cli/session_handoff.py +141 -0
  105. forge/cli/session_lifecycle.py +2053 -0
  106. forge/cli/session_manage.py +1336 -0
  107. forge/cli/session_memory.py +201 -0
  108. forge/cli/status_line.py +1398 -0
  109. forge/cli/workflow.py +1964 -0
  110. forge/config/__init__.py +110 -0
  111. forge/config/dataclass_utils.py +88 -0
  112. forge/config/defaults/__init__.py +0 -0
  113. forge/config/defaults/backends/__init__.py +0 -0
  114. forge/config/defaults/backends/litellm.yaml +196 -0
  115. forge/config/defaults/templates/__init__.py +0 -0
  116. forge/config/defaults/templates/litellm-anthropic-local.yaml +33 -0
  117. forge/config/defaults/templates/litellm-anthropic.yaml +24 -0
  118. forge/config/defaults/templates/litellm-gemini-flash-local.yaml +37 -0
  119. forge/config/defaults/templates/litellm-gemini-local.yaml +32 -0
  120. forge/config/defaults/templates/litellm-gemini-test.yaml +34 -0
  121. forge/config/defaults/templates/litellm-gemini.yaml +21 -0
  122. forge/config/defaults/templates/litellm-openai-codex-local.yaml +36 -0
  123. forge/config/defaults/templates/litellm-openai-local.yaml +38 -0
  124. forge/config/defaults/templates/litellm-openai.yaml +28 -0
  125. forge/config/defaults/templates/openrouter-anthropic.yaml +23 -0
  126. forge/config/defaults/templates/openrouter-deepseek.yaml +26 -0
  127. forge/config/defaults/templates/openrouter-gemini-flash.yaml +26 -0
  128. forge/config/defaults/templates/openrouter-gemini.yaml +23 -0
  129. forge/config/defaults/templates/openrouter-glm.yaml +23 -0
  130. forge/config/defaults/templates/openrouter-kimi.yaml +30 -0
  131. forge/config/defaults/templates/openrouter-minimax.yaml +26 -0
  132. forge/config/defaults/templates/openrouter-openai-codex.yaml +23 -0
  133. forge/config/defaults/templates/openrouter-openai.yaml +28 -0
  134. forge/config/defaults/templates/openrouter-qwen.yaml +25 -0
  135. forge/config/loader.py +675 -0
  136. forge/config/schema.py +448 -0
  137. forge/core/__init__.py +5 -0
  138. forge/core/auth/__init__.py +67 -0
  139. forge/core/auth/capabilities.py +219 -0
  140. forge/core/auth/credentials_file.py +244 -0
  141. forge/core/auth/protocols.py +18 -0
  142. forge/core/auth/secrets.py +243 -0
  143. forge/core/auth/template_secrets.py +112 -0
  144. forge/core/data/__init__.py +5 -0
  145. forge/core/data/model_catalog.yaml +1522 -0
  146. forge/core/data/pricing.yaml +140 -0
  147. forge/core/data/system_prompt_addendums/__init__.py +0 -0
  148. forge/core/data/system_prompt_addendums/gemini.md +330 -0
  149. forge/core/data/system_prompt_addendums/openai.md +328 -0
  150. forge/core/llm/__init__.py +231 -0
  151. forge/core/llm/clients/__init__.py +14 -0
  152. forge/core/llm/clients/base.py +115 -0
  153. forge/core/llm/clients/litellm.py +619 -0
  154. forge/core/llm/clients/openai_compat.py +244 -0
  155. forge/core/llm/clients/openrouter.py +234 -0
  156. forge/core/llm/credentials.py +439 -0
  157. forge/core/llm/detection.py +86 -0
  158. forge/core/llm/errors.py +44 -0
  159. forge/core/llm/protocols.py +80 -0
  160. forge/core/llm/types.py +176 -0
  161. forge/core/logging.py +146 -0
  162. forge/core/models/__init__.py +91 -0
  163. forge/core/models/catalog.py +467 -0
  164. forge/core/models/pricing.py +165 -0
  165. forge/core/models/types.py +167 -0
  166. forge/core/naming.py +212 -0
  167. forge/core/ops/__init__.py +73 -0
  168. forge/core/ops/context.py +141 -0
  169. forge/core/ops/gc.py +802 -0
  170. forge/core/ops/proxy.py +146 -0
  171. forge/core/ops/resolution.py +135 -0
  172. forge/core/ops/session.py +344 -0
  173. forge/core/ops/session_context.py +548 -0
  174. forge/core/paths.py +38 -0
  175. forge/core/process.py +54 -0
  176. forge/core/reactive/__init__.py +38 -0
  177. forge/core/reactive/cost_tracking.py +300 -0
  178. forge/core/reactive/env.py +180 -0
  179. forge/core/reactive/proxy.py +78 -0
  180. forge/core/reactive/routing.py +622 -0
  181. forge/core/reactive/session_runner.py +185 -0
  182. forge/core/reactive/structured_output.py +62 -0
  183. forge/core/reactive/tagger.py +94 -0
  184. forge/core/reactive/throttle.py +132 -0
  185. forge/core/state/__init__.py +59 -0
  186. forge/core/state/exceptions.py +59 -0
  187. forge/core/state/io.py +140 -0
  188. forge/core/state/lock.py +99 -0
  189. forge/core/state/timestamps.py +60 -0
  190. forge/core/transcript.py +78 -0
  191. forge/core/typing_helpers.py +24 -0
  192. forge/core/workqueue/__init__.py +67 -0
  193. forge/core/workqueue/queue.py +552 -0
  194. forge/core/workqueue/types.py +63 -0
  195. forge/guard/__init__.py +26 -0
  196. forge/guard/deterministic/__init__.py +26 -0
  197. forge/guard/deterministic/base.py +158 -0
  198. forge/guard/deterministic/coding_standards.py +256 -0
  199. forge/guard/deterministic/registry.py +148 -0
  200. forge/guard/deterministic/tdd.py +171 -0
  201. forge/guard/engine.py +216 -0
  202. forge/guard/protocols.py +91 -0
  203. forge/guard/queries.py +96 -0
  204. forge/guard/semantic/__init__.py +34 -0
  205. forge/guard/semantic/promotion.py +18 -0
  206. forge/guard/semantic/supervisor.py +813 -0
  207. forge/guard/semantic/verdict.py +183 -0
  208. forge/guard/store.py +124 -0
  209. forge/guard/team/__init__.py +6 -0
  210. forge/guard/team/config.py +24 -0
  211. forge/guard/team/handlers.py +209 -0
  212. forge/guard/team/prompts.py +41 -0
  213. forge/guard/types.py +125 -0
  214. forge/guard/workflow/__init__.py +17 -0
  215. forge/guard/workflow/branches.py +67 -0
  216. forge/guard/workflow/config.py +63 -0
  217. forge/guard/workflow/divergence.py +113 -0
  218. forge/guard/workflow/policy.py +87 -0
  219. forge/guard/workflow/stages.py +205 -0
  220. forge/install/__init__.py +55 -0
  221. forge/install/cli.py +281 -0
  222. forge/install/exceptions.py +163 -0
  223. forge/install/hooks.py +109 -0
  224. forge/install/installer.py +1037 -0
  225. forge/install/models.py +321 -0
  226. forge/install/preset.py +272 -0
  227. forge/install/settings_merge.py +831 -0
  228. forge/install/tracking.py +238 -0
  229. forge/install/version.py +141 -0
  230. forge/proxy/__init__.py +0 -0
  231. forge/proxy/base_client.py +181 -0
  232. forge/proxy/client_adapter.py +476 -0
  233. forge/proxy/client_factory.py +531 -0
  234. forge/proxy/converters.py +1206 -0
  235. forge/proxy/cost_logger.py +132 -0
  236. forge/proxy/cost_tracker.py +242 -0
  237. forge/proxy/data_models.py +338 -0
  238. forge/proxy/error_hints.py +92 -0
  239. forge/proxy/metrics.py +222 -0
  240. forge/proxy/model_spec.py +158 -0
  241. forge/proxy/proxies.py +333 -0
  242. forge/proxy/proxy_identity.py +134 -0
  243. forge/proxy/proxy_orchestrator.py +1018 -0
  244. forge/proxy/proxy_startup.py +54 -0
  245. forge/proxy/server.py +1561 -0
  246. forge/proxy/utils.py +537 -0
  247. forge/review/__init__.py +6 -0
  248. forge/review/adversarial.py +111 -0
  249. forge/review/consensus.py +236 -0
  250. forge/review/engine.py +356 -0
  251. forge/review/models.py +437 -0
  252. forge/review/resources/__init__.py +5 -0
  253. forge/review/resources/codereview-performance.md +85 -0
  254. forge/review/resources/codereview-quick.md +75 -0
  255. forge/review/resources/codereview-security.md +92 -0
  256. forge/review/resources/codereview.md +85 -0
  257. forge/review/resources/docreview-quick.md +75 -0
  258. forge/review/resources/docreview.md +86 -0
  259. forge/review/resources/thinkdeep.md +89 -0
  260. forge/review/routing.py +368 -0
  261. forge/review/synthesis.py +73 -0
  262. forge/runtime_config.py +438 -0
  263. forge/search/__init__.py +55 -0
  264. forge/search/bm25_store.py +264 -0
  265. forge/search/content_store.py +197 -0
  266. forge/search/engine.py +352 -0
  267. forge/search/exceptions.py +51 -0
  268. forge/search/extractor.py +234 -0
  269. forge/search/index_state.py +295 -0
  270. forge/search/store.py +215 -0
  271. forge/search/tokenizer.py +24 -0
  272. forge/session/__init__.py +130 -0
  273. forge/session/active.py +339 -0
  274. forge/session/artifacts.py +202 -0
  275. forge/session/claude/__init__.py +50 -0
  276. forge/session/claude/cleanup.py +105 -0
  277. forge/session/claude/invoke.py +236 -0
  278. forge/session/claude/paths.py +200 -0
  279. forge/session/cleanup.py +216 -0
  280. forge/session/config.py +34 -0
  281. forge/session/direct_model.py +107 -0
  282. forge/session/effective.py +169 -0
  283. forge/session/exceptions.py +255 -0
  284. forge/session/handoff.py +881 -0
  285. forge/session/handoff_agent.py +544 -0
  286. forge/session/hooks/__init__.py +35 -0
  287. forge/session/hooks/models.py +73 -0
  288. forge/session/hooks/session_start.py +507 -0
  289. forge/session/identity.py +84 -0
  290. forge/session/index.py +553 -0
  291. forge/session/manager.py +1506 -0
  292. forge/session/models.py +572 -0
  293. forge/session/overrides.py +344 -0
  294. forge/session/plan_resolution.py +286 -0
  295. forge/session/prev_sessions.py +128 -0
  296. forge/session/store.py +431 -0
  297. forge/session/validation.py +47 -0
  298. forge/session/worktree/__init__.py +65 -0
  299. forge/session/worktree/cleanup.py +262 -0
  300. forge/session/worktree/config_copy.py +203 -0
  301. forge/session/worktree/create.py +332 -0
  302. forge/sidecar/__init__.py +29 -0
  303. forge/sidecar/container.py +161 -0
  304. forge/sidecar/docker.py +86 -0
  305. forge/sidecar/secrets.py +19 -0
  306. multi_forge-0.2.0.dist-info/METADATA +242 -0
  307. multi_forge-0.2.0.dist-info/RECORD +311 -0
  308. multi_forge-0.2.0.dist-info/WHEEL +4 -0
  309. multi_forge-0.2.0.dist-info/entry_points.txt +2 -0
  310. multi_forge-0.2.0.dist-info/licenses/LICENSE +203 -0
  311. multi_forge-0.2.0.dist-info/licenses/NOTICE +14 -0
@@ -0,0 +1,50 @@
1
+ <!-- prereq: 0.3 -->
2
+
3
+ ## 17. System Info
4
+
5
+ ### 17.1 `forge info`
6
+
7
+ <!-- auto -->
8
+
9
+ ```bash
10
+ forge info
11
+ ```
12
+
13
+ - [ ] Shows Forge version
14
+ - [ ] Shows installation status
15
+ - [ ] Shows proxy status
16
+ - [ ] Shows active session (if any)
17
+
18
+ ### 17.2 Debug Logging and `forge logs`
19
+
20
+ <!-- human:confirm -->
21
+
22
+ Run a Forge command with debug logging enabled, then use `forge logs` to inspect and clean up log files.
23
+
24
+ ```bash
25
+ # Run a command with debug logging
26
+ FORGE_DEBUG=1 forge info
27
+
28
+ # Show log locations and file counts
29
+ forge logs
30
+
31
+ # Verify logs were written
32
+ forge logs
33
+ # Expected: shows log directory path and file count > 0
34
+
35
+ # Clean up logs
36
+ forge logs --clean
37
+
38
+ # Verify cleanup
39
+ forge logs
40
+ # Expected: reports 0 log files when no Forge processes are running.
41
+ # If QA proxies are still running, active proxy logs may be retained.
42
+ ```
43
+
44
+ - [ ] `FORGE_DEBUG=1` enables debug logging (no crash, no error)
45
+ - [ ] `forge logs` shows log directory location and file counts
46
+ - [ ] Log files were actually written (count > 0 after debug run)
47
+ - [ ] `forge logs --clean` removes stale log files
48
+ - [ ] After cleanup, `forge logs` reports 0 files, or only logs for currently running Forge proxy processes
49
+
50
+ ---
@@ -0,0 +1,84 @@
1
+ <!-- prereq: 0.3, 2.4 -->
2
+
3
+ ## 18. Uninstallation (Incremental)
4
+
5
+ Test uninstalling individual scopes before the complete uninstall.
6
+
7
+ ### 18.1 Uninstall Local Scope Only
8
+
9
+ <!-- auto -->
10
+
11
+ <!-- destructive -->
12
+
13
+ ```bash
14
+ cd $FORGE_TEST_REPO
15
+
16
+ # Uninstall only the local scope
17
+ forge extension disable --scope local
18
+
19
+ # (Optional) Uninstall hooks-only path, if you used it
20
+ forge hook disable --local
21
+
22
+ # Verify local removal
23
+ ls .claude/commands/ # Should be empty or removed
24
+ cat .claude/settings.local.json | jq '.hooks' # Should have no Forge hooks
25
+
26
+ # Verify user scope STILL installed
27
+ ls ~/.claude/commands/ # Should still have Forge commands
28
+ cat ~/.claude/settings.json | jq '.hooks' # Should still have Forge hooks
29
+
30
+ # Check tracking
31
+ cat ~/.forge/installed.json | jq '.installations | keys'
32
+ # Should show only ["user"], not the local:... key
33
+ ```
34
+
35
+ - [ ] Local commands removed
36
+ - [ ] Local hooks removed from settings.local.json
37
+ - [ ] User scope commands still present
38
+ - [ ] User scope hooks still present
39
+ - [ ] Tracking shows only "user" key
40
+
41
+ ### 18.2 Verify Pre-Existing Settings Restored (Local)
42
+
43
+ <!-- auto -->
44
+
45
+ <!-- destructive -->
46
+
47
+ ```bash
48
+ # CRITICAL: Check that user's original settings survived uninstall
49
+ cat .claude/settings.local.json | jq '.'
50
+
51
+ # Original permissions should still be there
52
+ cat .claude/settings.local.json | jq '.permissions.allow'
53
+ # Should show: ["Bash(npm test)", "Bash(uv run pytest*)"]
54
+
55
+ # Custom env var should still be there
56
+ cat .claude/settings.local.json | jq '.env.MY_CUSTOM_VAR'
57
+ # Should show: "should-survive-forge"
58
+ ```
59
+
60
+ - [ ] Original `permissions.allow` entries preserved
61
+ - [ ] `env.MY_CUSTOM_VAR` still present
62
+ - [ ] Forge-added hooks removed; Forge-added permissions (Write, Edit) removed
63
+ - [ ] User-approved permissions (e.g., `Bash(forge workflow:*)`) may remain -- these are Claude Code auto-learned, not
64
+ Forge-managed
65
+
66
+ ### 18.3 Re-install Local for Complete Test
67
+
68
+ <!-- auto -->
69
+
70
+ <!-- destructive -->
71
+
72
+ ```bash
73
+ # Re-install local scope so we can test complete uninstall
74
+ forge extension enable --scope local
75
+
76
+ # Verify both scopes installed again
77
+ cat ~/.forge/installed.json | jq '.installations | keys'
78
+ # Should show: ["user", "local:/Users/..."]
79
+ ```
80
+
81
+ - [ ] Local scope re-installed
82
+ - [ ] Both installations tracked
83
+
84
+ ---
@@ -0,0 +1,146 @@
1
+ <!-- prereq: 0.3, 2.4, 18 -->
2
+
3
+ ## 19. Complete Uninstallation (setup.sh --uninstall)
4
+
5
+ This tests the curl-installable uninstall that removes EVERYTHING.
6
+
7
+ ### 19.1 Pre-Uninstall State Verification
8
+
9
+ <!-- auto -->
10
+
11
+ <!-- destructive -->
12
+
13
+ ```bash
14
+ # Verify we have both installations
15
+ cat ~/.forge/installed.json | jq '.installations | keys'
16
+ # Should show: ["user", "local:$FORGE_TEST_REPO"]
17
+
18
+ # Verify artifacts exist
19
+ ls ~/.forge/ # Should exist
20
+ ls ~/.forge/bin/forge # Should exist
21
+ ls ~/.claude/commands/ # Should have Forge commands
22
+ ls .claude/commands/ # Should have Forge commands (local)
23
+ ```
24
+
25
+ - [ ] Both user and local installations tracked
26
+ - [ ] `~/.forge/` exists
27
+ - [ ] User scope has Forge files
28
+ - [ ] Local scope has Forge files
29
+
30
+ ### 19.2 Run Complete Uninstall
31
+
32
+ <!-- auto -->
33
+
34
+ <!-- destructive -->
35
+
36
+ ```bash
37
+ # Run the uninstall script using the local copy
38
+ ~/.forge/repo/scripts/setup.sh --uninstall
39
+ ```
40
+
41
+ The script attempts to remove extensions via Forge CLI:
42
+
43
+ - `forge extension disable --all --force` (remove tracked extensions)
44
+
45
+ Then it removes `~/.forge/` and other artifacts.
46
+
47
+ - [ ] Script runs without errors
48
+ - [ ] ALL scopes uninstalled (via `forge extension disable --all --force` or equivalent)
49
+ - [ ] Shows "Found N Forge installation(s)" summary (if forge available)
50
+ - [ ] `~/.forge/` removed
51
+ - [ ] `~/.forge/sessions/` removed (Forge session data)
52
+ - [ ] Docker images removed (multi-forge-\*)
53
+ - [ ] Shell profile cleaned (block markers removed)
54
+
55
+ ### 19.3 Verify Complete Removal
56
+
57
+ <!-- auto -->
58
+
59
+ <!-- destructive -->
60
+
61
+ ```bash
62
+ # Verify ~/.forge/ is gone
63
+ ls ~/.forge/ 2>/dev/null || echo "~/.forge/ removed"
64
+
65
+ # Verify forge not on PATH (need new terminal or source profile)
66
+ # source ~/.zshrc # or restart terminal
67
+ # which forge # Should fail or show nothing
68
+
69
+ # Verify no Forge hooks in global settings
70
+ cat ~/.claude/settings.json | jq '.hooks'
71
+ # Should be null or empty of Forge entries
72
+
73
+ # Verify user commands removed
74
+ ls ~/.claude/commands/ 2>/dev/null | grep -v "^$" || echo "User commands removed"
75
+ ls ~/.claude/agents/ 2>/dev/null | grep -v "^$" || echo "User agents removed"
76
+ ls ~/.claude/skills/ 2>/dev/null | grep -v "^$" || echo "User skills removed"
77
+ ```
78
+
79
+ - [ ] `~/.forge/` directory removed
80
+ - [ ] Forge hooks removed from `~/.claude/settings.json`
81
+ - [ ] User commands/agents/skills removed
82
+
83
+ ### 19.4 Verify Local Project Settings Preserved
84
+
85
+ <!-- auto -->
86
+
87
+ <!-- destructive -->
88
+
89
+ ```bash
90
+ cd $FORGE_TEST_REPO
91
+
92
+ # CRITICAL: Local pre-existing settings should survive
93
+ cat .claude/settings.local.json | jq '.'
94
+
95
+ # Original permissions should still be there
96
+ cat .claude/settings.local.json | jq '.permissions.allow'
97
+ # Should show: ["Bash(npm test)", "Bash(uv run pytest*)"]
98
+
99
+ # Custom env var should still be there
100
+ cat .claude/settings.local.json | jq '.env.MY_CUSTOM_VAR'
101
+ # Should show: "should-survive-forge"
102
+ ```
103
+
104
+ - [ ] `.claude/settings.local.json` still exists
105
+ - [ ] Original permissions preserved
106
+ - [ ] `env.MY_CUSTOM_VAR` preserved
107
+ - [ ] Forge-added entries (hooks, Write/Edit permissions, env) removed; user-approved permissions (e.g.,
108
+ `Bash(forge workflow:*)`) may remain
109
+
110
+ ### 19.5 Verify Shell Profile Cleaned
111
+
112
+ <!-- auto -->
113
+
114
+ <!-- destructive -->
115
+
116
+ ```bash
117
+ # Check that block markers were removed from any shell profile Forge may touch.
118
+ PROFILES=("$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.zshrc" "$HOME/.config/fish/config.fish")
119
+ FOUND_PROFILE=0
120
+ FOUND_BACKUP=0
121
+
122
+ for profile in "${PROFILES[@]}"; do
123
+ if [ -f "$profile" ]; then
124
+ FOUND_PROFILE=1
125
+ echo "Checking $profile"
126
+ grep -n ">>> multi-forge >>>" "$profile" && exit 1 || true
127
+ grep -n "$HOME/.forge/bin" "$profile" && exit 1 || true
128
+ fi
129
+
130
+ if [ -f "$profile.forge-uninstall-backup" ]; then
131
+ FOUND_BACKUP=1
132
+ echo "Backup exists: $profile.forge-uninstall-backup"
133
+ fi
134
+ done
135
+
136
+ echo "profiles_found=$FOUND_PROFILE backups_found=$FOUND_BACKUP"
137
+ if [ "$FOUND_PROFILE" -eq 0 ]; then
138
+ echo "No shell profile exists in this container; profile cleanup is N/A."
139
+ fi
140
+ ```
141
+
142
+ - [ ] No `>>> multi-forge >>>` block remains in any existing shell profile
143
+ - [ ] No `.forge/bin` PATH entry remains in any existing shell profile
144
+ - [ ] Backup file exists for any profile that was modified; if no shell profile exists, profile cleanup is N/A
145
+
146
+ ---
@@ -0,0 +1,188 @@
1
+ <!-- prereq: 0.3, 1.1 -->
2
+
3
+ ## 2. Claude Code Extensions (`forge extension enable`)
4
+
5
+ ### 2.1 Basic Installation (User Scope)
6
+
7
+ <!-- auto -->
8
+
9
+ ```bash
10
+ # Install forge extensions (default: standard profile, user scope)
11
+ cd $FORGE_TEST_REPO
12
+ forge extension enable --scope user --symlink
13
+
14
+ # Optional: preview changes instead of applying
15
+ forge extension enable --scope user --dry-run
16
+
17
+ # Verify installation
18
+ ls -la $CLAUDE_HOME/skills/
19
+ cat $CLAUDE_HOME/settings.json | jq '.hooks'
20
+ cat $FORGE_HOME/installed.json | jq '.installations.user.modules_enabled'
21
+
22
+ # Optional: confirm status line + permissions were merged (user scope)
23
+ cat $CLAUDE_HOME/settings.json | jq '.statusLine'
24
+ cat $CLAUDE_HOME/settings.json | jq '.permissions'
25
+ ```
26
+
27
+ - [ ] `modules_enabled` in `installed.json` lists `commands` and `agents` (directories created only if source has
28
+ installable files)
29
+ - [ ] Skills installed to `$CLAUDE_HOME/skills/` (standard profile)
30
+ - [ ] Hooks configured in `$CLAUDE_HOME/settings.json` (or in `$CLAUDE_HOME/settings.local.json` if you used hooks-only
31
+ install)
32
+ - [ ] `$FORGE_HOME/installed.json` tracking file created
33
+
34
+ ### 2.2 Verify Installed Content
35
+
36
+ <!-- auto -->
37
+
38
+ ```bash
39
+ # Check what was installed
40
+ cat $FORGE_HOME/installed.json | jq '.'
41
+
42
+ # Verify user-scope status line setting
43
+ cat $CLAUDE_HOME/settings.json | jq '.statusLine'
44
+
45
+ # Verify user-scope permissions
46
+ cat $CLAUDE_HOME/settings.json | jq '.permissions'
47
+
48
+ # Verify skills are installed
49
+ ls $CLAUDE_HOME/skills/
50
+ ```
51
+
52
+ - [ ] `installed.json` lists all installed files
53
+ - [ ] `statusLine` points to `forge status-line`
54
+ - [ ] Permissions include Forge-required entries
55
+ - [ ] Skills directory contains skill folders (analyze, debate, panel, review, review-docs, etc.)
56
+
57
+ ### 2.3 Verify Pre-Existing Settings Preserved
58
+
59
+ <!-- auto -->
60
+
61
+ ```bash
62
+ # Check that user's original settings survived installation
63
+ cat .claude/settings.local.json | jq '.'
64
+
65
+ # Verify original permissions still present (merged, not replaced)
66
+ cat .claude/settings.local.json | jq '.permissions.allow'
67
+ # Should include BOTH:
68
+ # - Original: "Bash(npm test)", "Bash(uv run pytest*)"
69
+ # - Forge-added permissions (if any added to local scope)
70
+
71
+ # Verify custom env var preserved
72
+ cat .claude/settings.local.json | jq '.env.MY_CUSTOM_VAR'
73
+ # Should show: "should-survive-forge"
74
+ ```
75
+
76
+ - [ ] Original `permissions.allow` entries preserved
77
+ - [ ] `env.MY_CUSTOM_VAR` still present
78
+ - [ ] Forge merged settings, didn't replace
79
+
80
+ ### 2.4 Install Local Scope
81
+
82
+ <!-- auto -->
83
+
84
+ ```bash
85
+ # Install Forge extensions to LOCAL scope (this project only)
86
+ cd $FORGE_TEST_REPO
87
+ forge extension enable --scope local
88
+
89
+ # Verify local installation
90
+ cat .claude/settings.local.json | jq '.hooks'
91
+ LOCAL_KEY="local:$(cd "$FORGE_TEST_REPO" && pwd -P)"
92
+ cat $FORGE_HOME/installed.json | jq --arg key "$LOCAL_KEY" '.installations[$key].modules_enabled'
93
+ ```
94
+
95
+ - [ ] `modules_enabled` for local installation lists `commands` and `agents` (directories created only if source has
96
+ installable files)
97
+ - [ ] Hooks configured in `.claude/settings.local.json`
98
+
99
+ ### 2.5 Verify Both Installations Tracked
100
+
101
+ <!-- auto -->
102
+
103
+ ```bash
104
+ # Check tracking file shows BOTH installations
105
+ LOCAL_KEY="local:$(cd "$FORGE_TEST_REPO" && pwd -P)"
106
+ cat $FORGE_HOME/installed.json | jq '.installations | keys'
107
+ printf 'Expected local key: %s\n' "$LOCAL_KEY"
108
+
109
+ # Show user installation
110
+ cat $FORGE_HOME/installed.json | jq '.installations.user.scope'
111
+ # Should show: "user"
112
+
113
+ # Show local installation (note the key format with path)
114
+ cat $FORGE_HOME/installed.json | jq --arg key "$LOCAL_KEY" '.installations[$key].scope'
115
+ # Should show: "local"
116
+
117
+ # Verify project_path is tracked
118
+ cat $FORGE_HOME/installed.json | jq --arg key "$LOCAL_KEY" '.installations[$key].project_path'
119
+ # Should show the resolved path part of LOCAL_KEY
120
+ ```
121
+
122
+ - [ ] Tracking shows "user" key
123
+ - [ ] Tracking shows "local:/path/to/project" key
124
+ - [ ] Both installations tracked separately
125
+ - [ ] project_path field populated for local installation
126
+
127
+ ### 2.6 Test Double-Install Prevention
128
+
129
+ <!-- auto -->
130
+
131
+ ```bash
132
+ # Try to install local again to same project
133
+ forge extension enable --scope local
134
+
135
+ # Should either:
136
+ # - Say "already installed" and skip
137
+ # - Or update existing installation (idempotent)
138
+
139
+ # Verify only ONE local entry in tracking
140
+ cat $FORGE_HOME/installed.json | jq '.installations | keys | length'
141
+ # Should show 2 (user + 1 local), not 3
142
+ ```
143
+
144
+ - [ ] Re-running `forge extension enable --scope local` is idempotent
145
+ - [ ] No duplicate entries in tracking
146
+
147
+ ### 2.7 Check Install Status (Nearest Scope)
148
+
149
+ <!-- auto -->
150
+
151
+ ```bash
152
+ cd $FORGE_TEST_REPO
153
+
154
+ # Status for the nearest installation (auto-detects local/project/user)
155
+ forge extension status
156
+ ```
157
+
158
+ - [ ] `forge extension status` succeeds
159
+ - [ ] Shows detected scope + profile/modules summary
160
+
161
+ ### 2.8 Check Install Status (All Scopes)
162
+
163
+ <!-- auto -->
164
+
165
+ ```bash
166
+ cd $FORGE_TEST_REPO
167
+
168
+ # Show user + project + local scopes
169
+ forge extension status --all
170
+ ```
171
+
172
+ - [ ] Shows all three scopes (user/project/local)
173
+ - [ ] Missing scopes are shown as "Not installed" (does not error)
174
+
175
+ ### 2.9 Update Installation (Idempotent)
176
+
177
+ <!-- auto -->
178
+
179
+ ```bash
180
+ cd $FORGE_TEST_REPO
181
+
182
+ # Update the nearest installation (auto-detects)
183
+ forge extension sync
184
+ ```
185
+
186
+ - [ ] Update completes (or reports already up to date)
187
+
188
+ ---
@@ -0,0 +1,36 @@
1
+ ## 20. Cleanup
2
+
3
+ ### 20.1 Cleanup Test Artifacts
4
+
5
+ <!-- auto -->
6
+
7
+ <!-- destructive -->
8
+
9
+ ```bash
10
+ # Clean up test sessions and artifacts, but preserve the QA state mount
11
+ rm -rf .forge/sessions/ .forge/artifacts/ .forge/prev_sessions/ .forge/search-index/
12
+
13
+ # Remove shell profile backups (optional)
14
+ rm -f \
15
+ ~/.bashrc.forge-uninstall-backup \
16
+ ~/.bash_profile.forge-uninstall-backup \
17
+ ~/.zshrc.forge-uninstall-backup \
18
+ ~/.config/fish/config.fish.forge-uninstall-backup
19
+
20
+ # Remove QA cost fixture logs (safe: only QA-owned fixture names)
21
+ rm -f ~/.forge/costs/requests/qa-fixture_*.jsonl
22
+ rm -f ~/.forge/costs/verbs/qa-fixture_*.jsonl
23
+ rm -f ~/.forge/costs/requests/*_qa-cap-seed.jsonl
24
+
25
+ # Remove test repo entirely (optional)
26
+ # cd .. && rm -rf manual-testing/walkthrough/test-repo
27
+ ```
28
+
29
+ - [ ] `.forge/sessions/` removed (or did not exist)
30
+ - [ ] `.forge/qa/` preserved (QA state mount -- do NOT delete)
31
+ - [ ] Shell profile backup removed (if existed)
32
+ - [ ] QA cost fixture logs removed from `~/.forge/costs/requests/` (no `qa-fixture_*.jsonl`)
33
+ - [ ] QA cost fixture logs removed from `~/.forge/costs/verbs/` (no `qa-fixture_*.jsonl`)
34
+ - [ ] QA cap seed logs removed from `~/.forge/costs/requests/` (no `*_qa-cap-seed.jsonl`)
35
+
36
+ ---