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,174 @@
1
+ <!-- prereq: 0.3, 2.1, 5.1 -->
2
+
3
+ ## 8. Status Line
4
+
5
+ ### 8.1 Direct Invocation
6
+
7
+ <!-- human:confirm -->
8
+
9
+ This is a rendered status-line smoke test. It does not call Claude or an LLM; it feeds a synthetic Claude Code
10
+ `statusLine` JSON payload into `forge status-line` and asks you to review the terminal-facing output.
11
+
12
+ Expected visible shape, with colors/spaces rendered by the terminal:
13
+
14
+ ```text
15
+ ${FORGE_TEST_REPO} (main) | test-session-1
16
+ [Opus 4.6] -------- 6%/200K | 3m | +12/-3 | in:28.0K out:17.5K
17
+ ```
18
+
19
+ The output may wrap to two physical terminal lines. A proxy template/tier prefix is expected only when
20
+ `ANTHROPIC_BASE_URL` points at a live or registered Forge proxy; if `test-session-1` was started without a proxy, no
21
+ proxy segment is expected here.
22
+
23
+ ```bash
24
+ cd $FORGE_TEST_REPO
25
+
26
+ # Mirror Claude Code's statusLine JSON contract and the Forge launch env.
27
+ BASE_URL=$(jq -r '.intent.proxy.base_url // empty' .forge/sessions/test-session-1/forge.session.json)
28
+ mkdir -p .forge/walkthrough
29
+ cat > .forge/walkthrough/status-line-transcript.jsonl <<EOF
30
+ {"requestId":"req-001","message":{"role":"user","content":[{"type":"text","text":"Read the config file."}]}}
31
+ {"requestId":"req-001","message":{"role":"assistant","content":[{"type":"text","text":"I'll inspect it."},{"type":"tool_use","id":"tool-001","name":"Read","input":{"file_path":"${FORGE_TEST_REPO}/config.yaml"}}]}}
32
+ {"requestId":"req-001","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"tool-001","content":"timeout: 10"}]}}
33
+ {"requestId":"req-002","message":{"role":"user","content":[{"type":"text","text":"Update the timeout and run tests."}]}}
34
+ {"requestId":"req-002","message":{"role":"assistant","content":[{"type":"tool_use","id":"tool-002","name":"Edit","input":{"file_path":"${FORGE_TEST_REPO}/config.yaml"}},{"type":"tool_use","id":"tool-003","name":"Bash","input":{"command":"uv run pytest"}}]}}
35
+ EOF
36
+ STATUS_INPUT=$(jq -nc \
37
+ --arg cwd "$FORGE_TEST_REPO" \
38
+ --arg transcript "$FORGE_TEST_REPO/.forge/walkthrough/status-line-transcript.jsonl" \
39
+ '{
40
+ workspace: {current_dir: $cwd},
41
+ model: {display_name: "Opus 4.6"},
42
+ transcript_path: $transcript,
43
+ context_window: {
44
+ context_window_size: 200000,
45
+ used_percentage: 6,
46
+ total_input_tokens: 28000,
47
+ total_output_tokens: 17500,
48
+ current_usage: {
49
+ input_tokens: 8500,
50
+ cache_creation_input_tokens: 2000,
51
+ cache_read_input_tokens: 1500
52
+ }
53
+ },
54
+ cost: {
55
+ total_duration_ms: 185000,
56
+ total_lines_added: 12,
57
+ total_lines_removed: 3
58
+ }
59
+ }')
60
+
61
+ echo "$STATUS_INPUT" \
62
+ | FORGE_SESSION=test-session-1 ANTHROPIC_BASE_URL="$BASE_URL" forge status-line
63
+ ```
64
+
65
+ - [ ] Shows compact workspace path, git branch, and `test-session-1`
66
+ - [ ] Shows `[Opus 4.6]` plus context usage `6%/200K` with a visible progress bar
67
+ - [ ] Shows seeded metrics: `3m`, `+12/-3`, `in:28.0K`, and `out:17.5K`
68
+ - [ ] If `ANTHROPIC_BASE_URL` belongs to a created/running proxy, also shows proxy template/tier info
69
+ - [ ] Does not print raw JSON, a Python traceback, or `[Error: ...]`
70
+ - [ ] ANSI/color and non-breaking-space internals are checked in 8.2, not by this rendered review
71
+
72
+ ### 8.2 Verify Display Elements
73
+
74
+ <!-- human:confirm -->
75
+
76
+ The status line uses a category-based layout with 5 categories: Where, Who, What, Metrics, State. This step
77
+ intentionally pipes the output through `cat -v`, so the output will look ugly on purpose:
78
+
79
+ - non-breaking spaces show up as `M-BM-`
80
+ - ANSI escapes show up as `^[[...`
81
+ - colorized line-change segments and dimmed `in:` / `out:` / `cache:` labels still show their raw escapes
82
+
83
+ Rendered output is covered in 8.1. This step is only checking that the raw escapes and hardened spacing are present.
84
+
85
+ ```bash
86
+ cd $FORGE_TEST_REPO
87
+
88
+ BASE_URL=$(jq -r '.intent.proxy.base_url // empty' .forge/sessions/test-session-1/forge.session.json)
89
+ mkdir -p .forge/walkthrough
90
+ cat > .forge/walkthrough/status-line-transcript.jsonl <<EOF
91
+ {"requestId":"req-001","message":{"role":"user","content":[{"type":"text","text":"Read the config file."}]}}
92
+ {"requestId":"req-001","message":{"role":"assistant","content":[{"type":"text","text":"I'll inspect it."},{"type":"tool_use","id":"tool-001","name":"Read","input":{"file_path":"${FORGE_TEST_REPO}/config.yaml"}}]}}
93
+ {"requestId":"req-001","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"tool-001","content":"timeout: 10"}]}}
94
+ {"requestId":"req-002","message":{"role":"user","content":[{"type":"text","text":"Update the timeout and run tests."}]}}
95
+ {"requestId":"req-002","message":{"role":"assistant","content":[{"type":"tool_use","id":"tool-002","name":"Edit","input":{"file_path":"${FORGE_TEST_REPO}/config.yaml"}},{"type":"tool_use","id":"tool-003","name":"Bash","input":{"command":"uv run pytest"}}]}}
96
+ EOF
97
+ STATUS_INPUT=$(jq -nc \
98
+ --arg cwd "$FORGE_TEST_REPO" \
99
+ --arg transcript "$FORGE_TEST_REPO/.forge/walkthrough/status-line-transcript.jsonl" \
100
+ '{
101
+ workspace: {current_dir: $cwd},
102
+ model: {display_name: "Opus 4.6 (200k context)"},
103
+ transcript_path: $transcript,
104
+ context_window: {
105
+ context_window_size: 200000,
106
+ used_percentage: 6,
107
+ total_input_tokens: 28000,
108
+ total_output_tokens: 17500,
109
+ current_usage: {
110
+ input_tokens: 8500,
111
+ cache_creation_input_tokens: 2000,
112
+ cache_read_input_tokens: 1500
113
+ }
114
+ },
115
+ cost: {
116
+ total_duration_ms: 185000,
117
+ total_lines_added: 12,
118
+ total_lines_removed: 3
119
+ }
120
+ }')
121
+
122
+ # Pipe through cat -v to inspect raw ANSI escapes and NBSP rendering.
123
+ # Expected: ugly raw output, not a pretty status line.
124
+ echo "$STATUS_INPUT" \
125
+ | FORGE_SESSION=test-session-1 ANTHROPIC_BASE_URL="$BASE_URL" forge status-line 2>&1 | cat -v
126
+ # Check for non-breaking spaces (M-BM-), ANSI codes (^[[...),
127
+ # and ASCII indicators/progress-bar text rather than rendered terminal styling.
128
+ ```
129
+
130
+ - [ ] Shows ANSI-colored ASCII segments in raw `cat -v` form
131
+ - [ ] Shows model name (cleaned, without redundant context info)
132
+ - [ ] Uses non-breaking spaces (prevents VSCode trimming)
133
+ - [ ] ANSI reset prefix present
134
+
135
+ ### 8.3 Breadcrumb Display (for resumed sessions)
136
+
137
+ <!-- human:confirm -->
138
+
139
+ ```bash
140
+ cd $FORGE_TEST_REPO
141
+
142
+ # Create a disposable derived-looking session so this step does not depend on section 10.
143
+ forge session delete test-session-breadcrumb --force 2>/dev/null || true
144
+ forge session start test-session-breadcrumb --no-launch >/dev/null
145
+
146
+ cat .forge/sessions/test-session-breadcrumb/forge.session.json \
147
+ | jq '.confirmed.derivation = {
148
+ "parent_session": "test-session-1",
149
+ "parent_transcript": ".forge/artifacts/test-session-1/transcript.jsonl",
150
+ "inherited_proxy": null,
151
+ "strategy": "minimal",
152
+ "depth": 1,
153
+ "resumed_at": "2026-03-16T00:00:00Z",
154
+ "lineage": ["test-session-1"]
155
+ }' > /tmp/test-session-breadcrumb.json && \
156
+ mv /tmp/test-session-breadcrumb.json .forge/sessions/test-session-breadcrumb/forge.session.json
157
+
158
+ BASE_URL=$(jq -r '.intent.proxy.base_url // empty' .forge/sessions/test-session-breadcrumb/forge.session.json)
159
+ STATUS_INPUT=$(jq -nc \
160
+ --arg cwd "$FORGE_TEST_REPO" \
161
+ '{
162
+ workspace: {current_dir: $cwd},
163
+ model: {display_name: "Opus 4.6"}
164
+ }')
165
+
166
+ echo "$STATUS_INPUT" \
167
+ | FORGE_SESSION=test-session-breadcrumb ANTHROPIC_BASE_URL="$BASE_URL" forge status-line 2>/dev/null
168
+
169
+ forge session delete test-session-breadcrumb --force >/dev/null
170
+ ```
171
+
172
+ - [ ] Shows session lineage breadcrumb (for example `test-session-1 > test-session-breadcrumb`)
173
+
174
+ ---
@@ -0,0 +1,146 @@
1
+ <!-- prereq: 0.3, 2.1, 5.1 -->
2
+
3
+ ## 9. Direct Commands (% commands)
4
+
5
+ ### 9.1 Test %help
6
+
7
+ <!-- auto -->
8
+
9
+ ```bash
10
+ # Simulate UserPromptSubmit with %help
11
+ echo '{"prompt": "%help"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
12
+ ```
13
+
14
+ - [ ] Returns help text listing available commands
15
+
16
+ ### 9.2 Test %session list
17
+
18
+ <!-- auto -->
19
+
20
+ ```bash
21
+ echo '{"prompt": "%session list"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
22
+ ```
23
+
24
+ - [ ] Returns session list (similar to CLI)
25
+
26
+ ### 9.3 Test %proxy list
27
+
28
+ <!-- auto -->
29
+
30
+ ```bash
31
+ echo '{"prompt": "%proxy list"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
32
+ ```
33
+
34
+ - [ ] Returns proxy list (read-only)
35
+
36
+ ### 9.4 Test %guard commands
37
+
38
+ <!-- auto -->
39
+
40
+ ```bash
41
+ # Guard status
42
+ echo '{"prompt": "%guard status"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
43
+
44
+ # Guard enable
45
+ echo '{"prompt": "%guard enable --bundle tdd"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
46
+
47
+ # Guard disable
48
+ echo '{"prompt": "%guard disable"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
49
+ ```
50
+
51
+ - [ ] `%guard status` returns policy state
52
+ - [ ] `%guard enable` enables TDD enforcement
53
+ - [ ] `%guard disable` disables all policy
54
+
55
+ ### 9.5 Test %guard check (Phase 18)
56
+
57
+ <!-- auto -->
58
+
59
+ ```bash
60
+ cd $FORGE_TEST_REPO
61
+
62
+ # Create a test file to generate a diff
63
+ echo 'def hello(): pass' > src/test_guard_check.py
64
+ git add src/test_guard_check.py && git commit -m "placeholder"
65
+ echo 'def hello(): return "world"' > src/test_guard_check.py
66
+
67
+ # Check unstaged changes against TDD bundle (should deny: impl without tests)
68
+ echo '{"prompt": "%guard check --bundle tdd"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
69
+
70
+ # Check staged changes
71
+ git add src/test_guard_check.py
72
+ echo '{"prompt": "%guard check --bundle tdd --staged"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
73
+
74
+ # With explicit bundle override
75
+ echo '{"prompt": "%guard check --bundle coding_standards"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
76
+
77
+ # Clean up the test file (revert the commit + remove the file)
78
+ git reset --hard HEAD~1
79
+ rm -f src/test_guard_check.py
80
+
81
+ # Ensure no unstaged changes remain (Forge may have modified settings.local.json etc.)
82
+ git checkout -- . 2>/dev/null || true
83
+
84
+ # Now verify "no changes" path
85
+ echo '{"prompt": "%guard check --bundle tdd"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
86
+ ```
87
+
88
+ - [ ] `%guard check` returns JSON with `passed`, `files_checked`, `bundles` fields
89
+ - [ ] Impl-only file denied by TDD bundle (`passed: false`)
90
+ - [ ] `--staged` flag evaluates staged changes instead of unstaged
91
+ - [ ] `--bundle` override selects specific bundle
92
+ - [ ] No changes returns `"No unstaged changes to check."`
93
+
94
+ ### 9.6 Test %config
95
+
96
+ <!-- auto -->
97
+
98
+ ```bash
99
+ echo '{"prompt": "%config"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
100
+ ```
101
+
102
+ - [ ] Returns effective runtime config (read-only)
103
+
104
+ ### 9.7 Test %session list --no-incognito
105
+
106
+ <!-- auto -->
107
+
108
+ ```bash
109
+ echo '{"prompt": "%session list --no-incognito"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
110
+ ```
111
+
112
+ - [ ] Returns a session list that excludes incognito sessions
113
+
114
+ ### 9.8 Test %proxy show
115
+
116
+ <!-- auto -->
117
+
118
+ <!-- prereq: 4.2 -->
119
+
120
+ ```bash
121
+ echo '{"prompt": "%proxy show test-proxy-nostart"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
122
+ ```
123
+
124
+ - [ ] Returns proxy details (template, base_url, status) for the requested proxy id
125
+
126
+ ### 9.9 Test %cancel-verification
127
+
128
+ <!-- auto -->
129
+
130
+ ```bash
131
+ cd $FORGE_TEST_REPO
132
+
133
+ # Configure verification (completion promise) on the session
134
+ forge session set verification '{"type":"completion_promise","promise":"FORGE_COMPLETED"}' --session test-session-1
135
+
136
+ # Enable bypass via direct command escape hatch
137
+ echo '{"prompt": "%cancel-verification"}' | FORGE_SESSION=test-session-1 forge hook user-prompt-submit
138
+
139
+ # Verify override set
140
+ cat .forge/sessions/test-session-1/forge.session.json | jq '.overrides.verification.bypass'
141
+ ```
142
+
143
+ - [ ] `%cancel-verification` returns "bypass enabled" message
144
+ - [ ] Session overrides include `verification.bypass: true`
145
+
146
+ ---
@@ -0,0 +1,103 @@
1
+ # Forge QA Checklist
2
+
3
+ <!-- checklist: index -->
4
+
5
+ <!-- version: 1.0.19 -->
6
+
7
+ <!-- test-count: 482 -->
8
+
9
+ <!-- last-updated: 2026-05-18 -->
10
+
11
+ <!-- aligned-with: v0.1.0 -->
12
+
13
+ **Test Repo**: `$FORGE_TEST_REPO`
14
+
15
+ **Last updated**: 2026-05-18 (add memory CLI and handoff report checks)
16
+
17
+ ---
18
+
19
+ ## Sections
20
+
21
+ - [0. Enable Forge (New User Flow)](checklist/0-enable.md)
22
+
23
+ <!-- section: 0 checklist/0-enable.md -->
24
+
25
+ - [1. Pre-Flight for Extension Tests](checklist/1-preflight.md)
26
+
27
+ <!-- section: 1 checklist/1-preflight.md -->
28
+
29
+ - [2. Claude Code Extensions (`forge extension enable`)](checklist/2-extensions.md)
30
+
31
+ <!-- section: 2 checklist/2-extensions.md -->
32
+
33
+ - [3. Authentication (`forge authentication`)](checklist/3-auth.md)
34
+
35
+ <!-- section: 3 checklist/3-auth.md -->
36
+
37
+ - [4. Proxy Management](checklist/4-proxy.md)
38
+
39
+ <!-- section: 4 checklist/4-proxy.md -->
40
+
41
+ - [5. Session Management](checklist/5-session.md)
42
+
43
+ <!-- section: 5 checklist/5-session.md -->
44
+
45
+ - [6. Hooks Testing](checklist/6-hooks.md)
46
+
47
+ <!-- section: 6 checklist/6-hooks.md -->
48
+
49
+ - [7. Cost Tracking & Spend Caps](checklist/7-costs.md)
50
+
51
+ <!-- section: 7 checklist/7-costs.md -->
52
+
53
+ - [8. Status Line](checklist/8-status-line.md)
54
+
55
+ <!-- section: 8 checklist/8-status-line.md -->
56
+
57
+ - [9. Direct Commands (% commands)](checklist/9-direct-commands.md)
58
+
59
+ <!-- section: 9 checklist/9-direct-commands.md -->
60
+
61
+ - [10. Session Resume (Phase 10 Feature)](checklist/10-resume.md)
62
+
63
+ <!-- section: 10 checklist/10-resume.md -->
64
+
65
+ - [11. Runtime Config + Claude Preset (`forge config`, `forge claude preset`)](checklist/11-config.md)
66
+
67
+ <!-- section: 11 checklist/11-config.md -->
68
+
69
+ - [12. Search (`forge search`)](checklist/12-search.md)
70
+
71
+ <!-- section: 12 checklist/12-search.md -->
72
+
73
+ - [13. Policy/Guard (`forge guard`)](checklist/13-guard.md)
74
+
75
+ <!-- section: 13 checklist/13-guard.md -->
76
+
77
+ - [14. Workflow Runners (`forge workflow`)](checklist/14-workflow.md)
78
+
79
+ <!-- section: 14 checklist/14-workflow.md -->
80
+
81
+ - [15. Skills (`/forge:review`, `/forge:understand`, `/forge:panel`, `/forge:consensus`)](checklist/15-skills.md)
82
+
83
+ <!-- section: 15 checklist/15-skills.md -->
84
+
85
+ - [16. Handoff Agent](checklist/16-handoff.md)
86
+
87
+ <!-- section: 16 checklist/16-handoff.md -->
88
+
89
+ - [17. System Info](checklist/17-info.md)
90
+
91
+ <!-- section: 17 checklist/17-info.md -->
92
+
93
+ - [18. Uninstallation (Incremental)](checklist/18-disable.md)
94
+
95
+ <!-- section: 18 checklist/18-disable.md -->
96
+
97
+ - [19. Complete Uninstallation (setup.sh --uninstall)](checklist/19-uninstall.md)
98
+
99
+ <!-- section: 19 checklist/19-uninstall.md -->
100
+
101
+ - [20. Cleanup](checklist/20-cleanup.md)
102
+
103
+ <!-- section: 20 checklist/20-cleanup.md -->
@@ -0,0 +1,62 @@
1
+ # Forge QA Report
2
+
3
+ | Field | Value |
4
+ | --------------------- | ------------------------------------------------------- |
5
+ | **Date** | YYYY-MM-DD |
6
+ | **Forge Version** | X.Y.Z (output of `forge --version`) |
7
+ | **Container** | container name (from `start-container.sh`) |
8
+ | **Checklist Version** | X.Y.Z (from checklist header `<!-- version: ... -->`) |
9
+ | **Duration** | HH:MM (from state file started_at to last_updated) |
10
+ | **Debug Logging** | Enabled by default in QA; artifacts copied when present |
11
+
12
+ ## Summary
13
+
14
+ | Category | Total | Pass | Fail | Skip |
15
+ | --------------------- | ----- | ----- | ----- | ----- |
16
+ | Enable (New User) | 0 | 0 | 0 | 0 |
17
+ | Pre-Flight | 0 | 0 | 0 | 0 |
18
+ | Extensions | 0 | 0 | 0 | 0 |
19
+ | Auth | 0 | 0 | 0 | 0 |
20
+ | Proxy | 0 | 0 | 0 | 0 |
21
+ | Session | 0 | 0 | 0 | 0 |
22
+ | Hooks | 0 | 0 | 0 | 0 |
23
+ | Status Line | 0 | 0 | 0 | 0 |
24
+ | Direct Commands | 0 | 0 | 0 | 0 |
25
+ | Session Resume | 0 | 0 | 0 | 0 |
26
+ | Runtime Config | 0 | 0 | 0 | 0 |
27
+ | Search | 0 | 0 | 0 | 0 |
28
+ | Guard | 0 | 0 | 0 | 0 |
29
+ | Workflow Runners | 0 | 0 | 0 | 0 |
30
+ | Skills | 0 | 0 | 0 | 0 |
31
+ | Handoff | 0 | 0 | 0 | 0 |
32
+ | System Info | 0 | 0 | 0 | 0 |
33
+ | Disable (Incremental) | 0 | 0 | 0 | 0 |
34
+ | Uninstall (Complete) | 0 | 0 | 0 | 0 |
35
+ | Cleanup | 0 | 0 | 0 | 0 |
36
+ | **TOTAL** | **0** | **0** | **0** | **0** |
37
+
38
+ ## Issues Found
39
+
40
+ | # | Section | Severity | Description |
41
+ | --- | ------- | --------------- | --------------------------------------------- |
42
+ | 1 | X.Y | high/medium/low | Brief description of what failed or was wrong |
43
+
44
+ If no issues: "No issues found."
45
+
46
+ ## Infrastructure
47
+
48
+ - **Forge**: version, install method (pip/uv)
49
+ - **Docker**: available/unavailable (docker info output)
50
+ - **Proxies**: count from `forge proxy list`, or "not tested"
51
+ - **Credentials**: auth status from hermetic FORGE_HOME, or "not tested"
52
+
53
+ ## Artifacts
54
+
55
+ - **step-logs/**: raw command output per checklist step (copied from the mounted QA state dir)
56
+ - **forge-logs/final/**: final Forge debug logs copied from the container at artifact-save time
57
+ - **forge-logs-snapshots/**: pre-clean snapshots captured before any checklist step runs `forge logs --clean`
58
+ - **transcript.jsonl**: copied when the QA session exits (if the transcript claim token is satisfied)
59
+
60
+ ## Notes
61
+
62
+ Observations from human checkpoint verifications, edge cases noticed, or anything that passed but looked suspicious.