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.
- forge/__init__.py +3 -0
- forge/_extensions/agents/.gitkeep +0 -0
- forge/_extensions/commands/.gitkeep +0 -0
- forge/_extensions/skills/analyze/SKILL.md +87 -0
- forge/_extensions/skills/challenge/SKILL.md +91 -0
- forge/_extensions/skills/consensus/SKILL.md +120 -0
- forge/_extensions/skills/consensus/resources/code_consensus_evaluation.md +94 -0
- forge/_extensions/skills/consensus/resources/consensus_evaluation.md +70 -0
- forge/_extensions/skills/consensus/resources/synthesis.md +101 -0
- forge/_extensions/skills/debate/SKILL.md +116 -0
- forge/_extensions/skills/debate/resources/code_debate_evaluation.md +101 -0
- forge/_extensions/skills/debate/resources/debate_evaluation.md +90 -0
- forge/_extensions/skills/panel/SKILL.md +141 -0
- forge/_extensions/skills/panel/resources/synthesis.md +103 -0
- forge/_extensions/skills/qa/SKILL.md +704 -0
- forge/_extensions/skills/qa/resources/checklist/0-enable.md +78 -0
- forge/_extensions/skills/qa/resources/checklist/1-preflight.md +24 -0
- forge/_extensions/skills/qa/resources/checklist/10-resume.md +143 -0
- forge/_extensions/skills/qa/resources/checklist/11-config.md +150 -0
- forge/_extensions/skills/qa/resources/checklist/12-search.md +58 -0
- forge/_extensions/skills/qa/resources/checklist/13-guard.md +237 -0
- forge/_extensions/skills/qa/resources/checklist/14-workflow.md +305 -0
- forge/_extensions/skills/qa/resources/checklist/15-skills.md +155 -0
- forge/_extensions/skills/qa/resources/checklist/16-handoff.md +224 -0
- forge/_extensions/skills/qa/resources/checklist/17-info.md +50 -0
- forge/_extensions/skills/qa/resources/checklist/18-disable.md +84 -0
- forge/_extensions/skills/qa/resources/checklist/19-uninstall.md +146 -0
- forge/_extensions/skills/qa/resources/checklist/2-extensions.md +188 -0
- forge/_extensions/skills/qa/resources/checklist/20-cleanup.md +36 -0
- forge/_extensions/skills/qa/resources/checklist/3-auth.md +234 -0
- forge/_extensions/skills/qa/resources/checklist/4-proxy.md +481 -0
- forge/_extensions/skills/qa/resources/checklist/5-session.md +541 -0
- forge/_extensions/skills/qa/resources/checklist/6-hooks.md +275 -0
- forge/_extensions/skills/qa/resources/checklist/7-costs.md +309 -0
- forge/_extensions/skills/qa/resources/checklist/8-status-line.md +174 -0
- forge/_extensions/skills/qa/resources/checklist/9-direct-commands.md +146 -0
- forge/_extensions/skills/qa/resources/checklist.md +103 -0
- forge/_extensions/skills/qa/resources/report-template.md +62 -0
- forge/_extensions/skills/qa/scripts/start-container.sh +529 -0
- forge/_extensions/skills/qa/scripts/walkthrough-state.py +1137 -0
- forge/_extensions/skills/review/SKILL.md +125 -0
- forge/_extensions/skills/review/references/claude-4.6.md +474 -0
- forge/_extensions/skills/review/references/claude-4.7.md +710 -0
- forge/_extensions/skills/review/references/gemini-3.1.md +546 -0
- forge/_extensions/skills/review/references/gpt-5.5.md +490 -0
- forge/_extensions/skills/review/references/skills-writing-guide.md +1588 -0
- forge/_extensions/skills/review/resources/code-anthropic.md +160 -0
- forge/_extensions/skills/review/resources/code-gemini.md +184 -0
- forge/_extensions/skills/review/resources/code-openai.md +203 -0
- forge/_extensions/skills/review/resources/code.md +160 -0
- forge/_extensions/skills/review-docs/SKILL.md +121 -0
- forge/_extensions/skills/review-docs/resources/docs-anthropic.md +170 -0
- forge/_extensions/skills/review-docs/resources/docs-gemini.md +204 -0
- forge/_extensions/skills/review-docs/resources/docs-openai.md +231 -0
- forge/_extensions/skills/review-docs/resources/docs.md +170 -0
- forge/_extensions/skills/smoke-test/SKILL.md +27 -0
- forge/_extensions/skills/smoke-test/scripts/smoke-test.sh +118 -0
- forge/_extensions/skills/understand/SKILL.md +148 -0
- forge/_extensions/skills/understand/resources/code-anthropic.md +163 -0
- forge/_extensions/skills/understand/resources/code-gemini.md +194 -0
- forge/_extensions/skills/understand/resources/code-openai.md +181 -0
- forge/_extensions/skills/understand/resources/code.md +163 -0
- forge/_extensions/skills/understand/resources/docs-anthropic.md +177 -0
- forge/_extensions/skills/understand/resources/docs-gemini.md +202 -0
- forge/_extensions/skills/understand/resources/docs-openai.md +191 -0
- forge/_extensions/skills/understand/resources/docs.md +177 -0
- forge/_extensions/skills/walkthrough/SKILL.md +599 -0
- forge/_extensions/skills/walkthrough/resources/checklist.md +765 -0
- forge/_extensions/skills/walkthrough/scripts/run-in-repo.sh +118 -0
- forge/_extensions/skills/walkthrough/scripts/setup-test-repo.sh +198 -0
- forge/_extensions/skills/walkthrough/scripts/walkthrough-state.py +1137 -0
- forge/backend/__init__.py +174 -0
- forge/backend/adapters/__init__.py +38 -0
- forge/backend/adapters/litellm.py +158 -0
- forge/backend/creation.py +89 -0
- forge/backend/registry.py +178 -0
- forge/cli/__init__.py +16 -0
- forge/cli/auth.py +483 -0
- forge/cli/backend.py +298 -0
- forge/cli/claude.py +411 -0
- forge/cli/config_cmd.py +303 -0
- forge/cli/extensions.py +1001 -0
- forge/cli/gc.py +165 -0
- forge/cli/guard.py +1018 -0
- forge/cli/guards.py +106 -0
- forge/cli/handoff.py +110 -0
- forge/cli/hooks/__init__.py +36 -0
- forge/cli/hooks/_group.py +20 -0
- forge/cli/hooks/_helpers.py +149 -0
- forge/cli/hooks/commands.py +1677 -0
- forge/cli/hooks/direct_commands.py +1304 -0
- forge/cli/hooks/install.py +232 -0
- forge/cli/hooks/policy.py +151 -0
- forge/cli/hooks/read_hygiene.py +74 -0
- forge/cli/hooks/verification.py +370 -0
- forge/cli/logs.py +406 -0
- forge/cli/main.py +292 -0
- forge/cli/proxy.py +1821 -0
- forge/cli/proxy_costs.py +313 -0
- forge/cli/search.py +416 -0
- forge/cli/session.py +892 -0
- forge/cli/session_addendum.py +81 -0
- forge/cli/session_fork.py +750 -0
- forge/cli/session_handoff.py +141 -0
- forge/cli/session_lifecycle.py +2053 -0
- forge/cli/session_manage.py +1336 -0
- forge/cli/session_memory.py +201 -0
- forge/cli/status_line.py +1398 -0
- forge/cli/workflow.py +1964 -0
- forge/config/__init__.py +110 -0
- forge/config/dataclass_utils.py +88 -0
- forge/config/defaults/__init__.py +0 -0
- forge/config/defaults/backends/__init__.py +0 -0
- forge/config/defaults/backends/litellm.yaml +196 -0
- forge/config/defaults/templates/__init__.py +0 -0
- forge/config/defaults/templates/litellm-anthropic-local.yaml +33 -0
- forge/config/defaults/templates/litellm-anthropic.yaml +24 -0
- forge/config/defaults/templates/litellm-gemini-flash-local.yaml +37 -0
- forge/config/defaults/templates/litellm-gemini-local.yaml +32 -0
- forge/config/defaults/templates/litellm-gemini-test.yaml +34 -0
- forge/config/defaults/templates/litellm-gemini.yaml +21 -0
- forge/config/defaults/templates/litellm-openai-codex-local.yaml +36 -0
- forge/config/defaults/templates/litellm-openai-local.yaml +38 -0
- forge/config/defaults/templates/litellm-openai.yaml +28 -0
- forge/config/defaults/templates/openrouter-anthropic.yaml +23 -0
- forge/config/defaults/templates/openrouter-deepseek.yaml +26 -0
- forge/config/defaults/templates/openrouter-gemini-flash.yaml +26 -0
- forge/config/defaults/templates/openrouter-gemini.yaml +23 -0
- forge/config/defaults/templates/openrouter-glm.yaml +23 -0
- forge/config/defaults/templates/openrouter-kimi.yaml +30 -0
- forge/config/defaults/templates/openrouter-minimax.yaml +26 -0
- forge/config/defaults/templates/openrouter-openai-codex.yaml +23 -0
- forge/config/defaults/templates/openrouter-openai.yaml +28 -0
- forge/config/defaults/templates/openrouter-qwen.yaml +25 -0
- forge/config/loader.py +675 -0
- forge/config/schema.py +448 -0
- forge/core/__init__.py +5 -0
- forge/core/auth/__init__.py +67 -0
- forge/core/auth/capabilities.py +219 -0
- forge/core/auth/credentials_file.py +244 -0
- forge/core/auth/protocols.py +18 -0
- forge/core/auth/secrets.py +243 -0
- forge/core/auth/template_secrets.py +112 -0
- forge/core/data/__init__.py +5 -0
- forge/core/data/model_catalog.yaml +1522 -0
- forge/core/data/pricing.yaml +140 -0
- forge/core/data/system_prompt_addendums/__init__.py +0 -0
- forge/core/data/system_prompt_addendums/gemini.md +330 -0
- forge/core/data/system_prompt_addendums/openai.md +328 -0
- forge/core/llm/__init__.py +231 -0
- forge/core/llm/clients/__init__.py +14 -0
- forge/core/llm/clients/base.py +115 -0
- forge/core/llm/clients/litellm.py +619 -0
- forge/core/llm/clients/openai_compat.py +244 -0
- forge/core/llm/clients/openrouter.py +234 -0
- forge/core/llm/credentials.py +439 -0
- forge/core/llm/detection.py +86 -0
- forge/core/llm/errors.py +44 -0
- forge/core/llm/protocols.py +80 -0
- forge/core/llm/types.py +176 -0
- forge/core/logging.py +146 -0
- forge/core/models/__init__.py +91 -0
- forge/core/models/catalog.py +467 -0
- forge/core/models/pricing.py +165 -0
- forge/core/models/types.py +167 -0
- forge/core/naming.py +212 -0
- forge/core/ops/__init__.py +73 -0
- forge/core/ops/context.py +141 -0
- forge/core/ops/gc.py +802 -0
- forge/core/ops/proxy.py +146 -0
- forge/core/ops/resolution.py +135 -0
- forge/core/ops/session.py +344 -0
- forge/core/ops/session_context.py +548 -0
- forge/core/paths.py +38 -0
- forge/core/process.py +54 -0
- forge/core/reactive/__init__.py +38 -0
- forge/core/reactive/cost_tracking.py +300 -0
- forge/core/reactive/env.py +180 -0
- forge/core/reactive/proxy.py +78 -0
- forge/core/reactive/routing.py +622 -0
- forge/core/reactive/session_runner.py +185 -0
- forge/core/reactive/structured_output.py +62 -0
- forge/core/reactive/tagger.py +94 -0
- forge/core/reactive/throttle.py +132 -0
- forge/core/state/__init__.py +59 -0
- forge/core/state/exceptions.py +59 -0
- forge/core/state/io.py +140 -0
- forge/core/state/lock.py +99 -0
- forge/core/state/timestamps.py +60 -0
- forge/core/transcript.py +78 -0
- forge/core/typing_helpers.py +24 -0
- forge/core/workqueue/__init__.py +67 -0
- forge/core/workqueue/queue.py +552 -0
- forge/core/workqueue/types.py +63 -0
- forge/guard/__init__.py +26 -0
- forge/guard/deterministic/__init__.py +26 -0
- forge/guard/deterministic/base.py +158 -0
- forge/guard/deterministic/coding_standards.py +256 -0
- forge/guard/deterministic/registry.py +148 -0
- forge/guard/deterministic/tdd.py +171 -0
- forge/guard/engine.py +216 -0
- forge/guard/protocols.py +91 -0
- forge/guard/queries.py +96 -0
- forge/guard/semantic/__init__.py +34 -0
- forge/guard/semantic/promotion.py +18 -0
- forge/guard/semantic/supervisor.py +813 -0
- forge/guard/semantic/verdict.py +183 -0
- forge/guard/store.py +124 -0
- forge/guard/team/__init__.py +6 -0
- forge/guard/team/config.py +24 -0
- forge/guard/team/handlers.py +209 -0
- forge/guard/team/prompts.py +41 -0
- forge/guard/types.py +125 -0
- forge/guard/workflow/__init__.py +17 -0
- forge/guard/workflow/branches.py +67 -0
- forge/guard/workflow/config.py +63 -0
- forge/guard/workflow/divergence.py +113 -0
- forge/guard/workflow/policy.py +87 -0
- forge/guard/workflow/stages.py +205 -0
- forge/install/__init__.py +55 -0
- forge/install/cli.py +281 -0
- forge/install/exceptions.py +163 -0
- forge/install/hooks.py +109 -0
- forge/install/installer.py +1037 -0
- forge/install/models.py +321 -0
- forge/install/preset.py +272 -0
- forge/install/settings_merge.py +831 -0
- forge/install/tracking.py +238 -0
- forge/install/version.py +141 -0
- forge/proxy/__init__.py +0 -0
- forge/proxy/base_client.py +181 -0
- forge/proxy/client_adapter.py +476 -0
- forge/proxy/client_factory.py +531 -0
- forge/proxy/converters.py +1206 -0
- forge/proxy/cost_logger.py +132 -0
- forge/proxy/cost_tracker.py +242 -0
- forge/proxy/data_models.py +338 -0
- forge/proxy/error_hints.py +92 -0
- forge/proxy/metrics.py +222 -0
- forge/proxy/model_spec.py +158 -0
- forge/proxy/proxies.py +333 -0
- forge/proxy/proxy_identity.py +134 -0
- forge/proxy/proxy_orchestrator.py +1018 -0
- forge/proxy/proxy_startup.py +54 -0
- forge/proxy/server.py +1561 -0
- forge/proxy/utils.py +537 -0
- forge/review/__init__.py +6 -0
- forge/review/adversarial.py +111 -0
- forge/review/consensus.py +236 -0
- forge/review/engine.py +356 -0
- forge/review/models.py +437 -0
- forge/review/resources/__init__.py +5 -0
- forge/review/resources/codereview-performance.md +85 -0
- forge/review/resources/codereview-quick.md +75 -0
- forge/review/resources/codereview-security.md +92 -0
- forge/review/resources/codereview.md +85 -0
- forge/review/resources/docreview-quick.md +75 -0
- forge/review/resources/docreview.md +86 -0
- forge/review/resources/thinkdeep.md +89 -0
- forge/review/routing.py +368 -0
- forge/review/synthesis.py +73 -0
- forge/runtime_config.py +438 -0
- forge/search/__init__.py +55 -0
- forge/search/bm25_store.py +264 -0
- forge/search/content_store.py +197 -0
- forge/search/engine.py +352 -0
- forge/search/exceptions.py +51 -0
- forge/search/extractor.py +234 -0
- forge/search/index_state.py +295 -0
- forge/search/store.py +215 -0
- forge/search/tokenizer.py +24 -0
- forge/session/__init__.py +130 -0
- forge/session/active.py +339 -0
- forge/session/artifacts.py +202 -0
- forge/session/claude/__init__.py +50 -0
- forge/session/claude/cleanup.py +105 -0
- forge/session/claude/invoke.py +236 -0
- forge/session/claude/paths.py +200 -0
- forge/session/cleanup.py +216 -0
- forge/session/config.py +34 -0
- forge/session/direct_model.py +107 -0
- forge/session/effective.py +169 -0
- forge/session/exceptions.py +255 -0
- forge/session/handoff.py +881 -0
- forge/session/handoff_agent.py +544 -0
- forge/session/hooks/__init__.py +35 -0
- forge/session/hooks/models.py +73 -0
- forge/session/hooks/session_start.py +507 -0
- forge/session/identity.py +84 -0
- forge/session/index.py +553 -0
- forge/session/manager.py +1506 -0
- forge/session/models.py +572 -0
- forge/session/overrides.py +344 -0
- forge/session/plan_resolution.py +286 -0
- forge/session/prev_sessions.py +128 -0
- forge/session/store.py +431 -0
- forge/session/validation.py +47 -0
- forge/session/worktree/__init__.py +65 -0
- forge/session/worktree/cleanup.py +262 -0
- forge/session/worktree/config_copy.py +203 -0
- forge/session/worktree/create.py +332 -0
- forge/sidecar/__init__.py +29 -0
- forge/sidecar/container.py +161 -0
- forge/sidecar/docker.py +86 -0
- forge/sidecar/secrets.py +19 -0
- multi_forge-0.2.0.dist-info/METADATA +242 -0
- multi_forge-0.2.0.dist-info/RECORD +311 -0
- multi_forge-0.2.0.dist-info/WHEEL +4 -0
- multi_forge-0.2.0.dist-info/entry_points.txt +2 -0
- multi_forge-0.2.0.dist-info/licenses/LICENSE +203 -0
- multi_forge-0.2.0.dist-info/licenses/NOTICE +14 -0
|
@@ -0,0 +1,765 @@
|
|
|
1
|
+
# Forge Walkthrough Checklist
|
|
2
|
+
|
|
3
|
+
<!-- version: 1.0.0 -->
|
|
4
|
+
|
|
5
|
+
<!-- test-count: 90 assertions -->
|
|
6
|
+
|
|
7
|
+
<!-- last-updated: 2026-05-18 -->
|
|
8
|
+
|
|
9
|
+
<!-- aligned-with: v0.1.0 -->
|
|
10
|
+
|
|
11
|
+
This checklist is read by the `/forge:walkthrough` skill (Session A). Commands run through `run-in-repo.sh` for sandbox
|
|
12
|
+
isolation. `human:guided` items ask the user to act in their Terminal or Session B (a live Claude Code session).
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 0. Setup
|
|
17
|
+
|
|
18
|
+
### 0.1 Snapshot Real System
|
|
19
|
+
|
|
20
|
+
<!-- auto -->
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
python3 -c "
|
|
24
|
+
import json, os, pathlib
|
|
25
|
+
paths = ['settings.json', 'settings.local.json', 'commands', 'agents', 'skills']
|
|
26
|
+
home = pathlib.Path.home() / '.claude'
|
|
27
|
+
snap = {}
|
|
28
|
+
for p in paths:
|
|
29
|
+
fp = home / p
|
|
30
|
+
snap[p] = os.path.getmtime(str(fp)) if fp.exists() else None
|
|
31
|
+
print(json.dumps(snap, indent=2))
|
|
32
|
+
"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- [ ] Snapshot JSON captured successfully
|
|
36
|
+
- [ ] All 5 paths recorded (settings.json, settings.local.json, commands, agents, skills)
|
|
37
|
+
|
|
38
|
+
### 0.2 Create Test Repo
|
|
39
|
+
|
|
40
|
+
<!-- auto -->
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bash "$SETUP_SCRIPT"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- [ ] Test repo exists at $FORGE_TEST_REPO
|
|
47
|
+
- [ ] env.sh generated at $FORGE_TEST_REPO/.forge/walkthrough/env.sh
|
|
48
|
+
- [ ] Marker file present at $FORGE_TEST_REPO/.forge-walkthrough-marker
|
|
49
|
+
|
|
50
|
+
### 0.3 Locate Scripts Directory
|
|
51
|
+
|
|
52
|
+
<!-- auto -->
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
test -f "$SCRIPTS/run-in-repo.sh" && echo "Scripts found: $SCRIPTS"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- [ ] run-in-repo.sh found
|
|
59
|
+
- [ ] Scripts directory resolved
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 1. Open Terminal
|
|
64
|
+
|
|
65
|
+
### 1.1 Open a Terminal Window
|
|
66
|
+
|
|
67
|
+
<!-- human:guided -->
|
|
68
|
+
|
|
69
|
+
Open a **Terminal** window and run:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
cd $FORGE_TEST_REPO
|
|
73
|
+
source .forge/walkthrough/env.sh
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This gives you a sandboxed shell where `forge` commands target the test repo, not your real system. You'll use this
|
|
77
|
+
terminal to try Forge commands hands-on in later sections.
|
|
78
|
+
|
|
79
|
+
- [ ] User confirms terminal is open and env.sh sourced
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 2. Install
|
|
84
|
+
|
|
85
|
+
### 2.1 Install Forge Extensions into Sandbox
|
|
86
|
+
|
|
87
|
+
<!-- auto -->
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
bash "$SCRIPTS/run-in-repo.sh" forge extension enable --scope local
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- [ ] Exit code 0
|
|
94
|
+
- [ ] Output shows installed files (commands, skills, agents, hooks)
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 3. Verify Install
|
|
99
|
+
|
|
100
|
+
### 3.1 Check Installed Files
|
|
101
|
+
|
|
102
|
+
<!-- auto -->
|
|
103
|
+
|
|
104
|
+
Use the Glob tool to verify installed files exist. Set `path` to the directory and `pattern` to the filename glob:
|
|
105
|
+
|
|
106
|
+
- Glob path: `$FORGE_TEST_REPO/.claude/commands/` pattern: `*.md`
|
|
107
|
+
|
|
108
|
+
- Glob path: `$FORGE_TEST_REPO/.claude/skills/` pattern: `**/SKILL.md`
|
|
109
|
+
|
|
110
|
+
- Glob path: `$FORGE_TEST_REPO/.claude/agents/` pattern: `*.md`
|
|
111
|
+
|
|
112
|
+
- [ ] commands/ has .md files
|
|
113
|
+
|
|
114
|
+
- [ ] skills/ has subdirectories with SKILL.md files
|
|
115
|
+
|
|
116
|
+
- [ ] agents/ has .md files
|
|
117
|
+
|
|
118
|
+
### 3.2 Check Settings Configuration
|
|
119
|
+
|
|
120
|
+
<!-- auto -->
|
|
121
|
+
|
|
122
|
+
Use the Read tool to read `$FORGE_TEST_REPO/.claude/settings.local.json` and verify Forge entries were added and
|
|
123
|
+
pre-existing fixtures survived the install:
|
|
124
|
+
|
|
125
|
+
- [ ] hooks section configured (PreToolUse, PostToolUse, Stop, SessionStart, UserPromptSubmit)
|
|
126
|
+
- [ ] statusLine configured
|
|
127
|
+
- [ ] permissions.allow includes Forge entries
|
|
128
|
+
- [ ] `env.MY_CUSTOM_VAR` still equals `"should-survive-forge"` (pre-existing fixture survived)
|
|
129
|
+
- [ ] `permissions.allow` still includes `"Bash(npm test)"` and `"Bash(uv run pytest*)"` (pre-existing fixtures
|
|
130
|
+
survived)
|
|
131
|
+
|
|
132
|
+
### 3.3 Check Install Manifest
|
|
133
|
+
|
|
134
|
+
<!-- auto -->
|
|
135
|
+
|
|
136
|
+
Use the Read tool to read `$FORGE_TEST_REPO/.forge-home/installed.json` and verify:
|
|
137
|
+
|
|
138
|
+
- [ ] Manifest file exists
|
|
139
|
+
- [ ] Tracks a local-scope installation
|
|
140
|
+
- [ ] Files list is populated
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 4. Verify Real System Untouched
|
|
145
|
+
|
|
146
|
+
### 4.1 Compare Timestamps
|
|
147
|
+
|
|
148
|
+
<!-- auto -->
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
python3 -c "
|
|
152
|
+
import json, os, pathlib
|
|
153
|
+
paths = ['settings.json', 'settings.local.json', 'commands', 'agents', 'skills']
|
|
154
|
+
home = pathlib.Path.home() / '.claude'
|
|
155
|
+
snap = {}
|
|
156
|
+
for p in paths:
|
|
157
|
+
fp = home / p
|
|
158
|
+
snap[p] = os.path.getmtime(str(fp)) if fp.exists() else None
|
|
159
|
+
print(json.dumps(snap, indent=2))
|
|
160
|
+
"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Compare every value against the Section 0 snapshot. They must all match exactly.
|
|
164
|
+
|
|
165
|
+
- [ ] All timestamps match the baseline from Section 0
|
|
166
|
+
- [ ] No new files appeared in real ~/.claude/
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 5. Explore CLI
|
|
171
|
+
|
|
172
|
+
### 5.1 Show Forge Command Tree
|
|
173
|
+
|
|
174
|
+
<!-- auto -->
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
bash "$SCRIPTS/run-in-repo.sh" forge -h
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
- [ ] Help output shows available subcommands (session, proxy, config, guard, etc.)
|
|
181
|
+
|
|
182
|
+
### 5.2 Try Commands in Your Terminal
|
|
183
|
+
|
|
184
|
+
<!-- human:guided -->
|
|
185
|
+
|
|
186
|
+
In your **Terminal** window (where you sourced env.sh), try some of these commands:
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
forge info # Show Forge installation info
|
|
190
|
+
forge extension status # Show what's installed
|
|
191
|
+
forge proxy list # List proxy configurations
|
|
192
|
+
forge config show # Show runtime config
|
|
193
|
+
forge session -h # Session subcommand help
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Try at least 2-3 commands. They all run in the sandbox — your real system is not affected.
|
|
197
|
+
|
|
198
|
+
- [ ] User confirms commands ran successfully in Terminal
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 6. Create Proxy and Session
|
|
203
|
+
|
|
204
|
+
### 6.1 Create a Proxy
|
|
205
|
+
|
|
206
|
+
<!-- auto -->
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
bash "$SCRIPTS/run-in-repo.sh" forge proxy create openrouter-anthropic
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
- [ ] Proxy created successfully
|
|
213
|
+
- [ ] Output shows proxy ID, port, and template
|
|
214
|
+
|
|
215
|
+
Capture `$PROXY_ID` (the human-friendly ID like `clever-hawk` from the "Started proxy" line) and `$PROXY_BASE_URL` (the
|
|
216
|
+
URL) from the output for use in later sections.
|
|
217
|
+
|
|
218
|
+
### 6.2 List Proxies
|
|
219
|
+
|
|
220
|
+
<!-- auto -->
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
bash "$SCRIPTS/run-in-repo.sh" forge proxy list
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
- [ ] Proxy appears in list with running status
|
|
227
|
+
|
|
228
|
+
### 6.3 Create a Session
|
|
229
|
+
|
|
230
|
+
<!-- auto -->
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# Idempotent: delete existing session from previous run if present
|
|
234
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session delete walkthrough-demo --force 2>/dev/null || true
|
|
235
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session start walkthrough-demo --proxy "$PROXY_ID" --no-launch
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
- [ ] Session created successfully
|
|
239
|
+
- [ ] Output shows proxy binding matching $PROXY_ID
|
|
240
|
+
|
|
241
|
+
### 6.4 Inspect Session
|
|
242
|
+
|
|
243
|
+
<!-- auto -->
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session list
|
|
247
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session show walkthrough-demo
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
- [ ] Session appears in list
|
|
251
|
+
- [ ] Inspect shows session manifest (intent section with proxy linkage)
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## 7. Launch Session B
|
|
256
|
+
|
|
257
|
+
### 7.1 Launch Claude via Forge
|
|
258
|
+
|
|
259
|
+
<!-- human:guided -->
|
|
260
|
+
|
|
261
|
+
In your **Terminal** window (where you sourced env.sh), launch Claude Code through Forge:
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
forge claude start --proxy $PROXY_ID
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
This starts Claude Code (Session B) with API calls routed through the proxy. Forge hooks, status line, and % commands
|
|
268
|
+
are all active because extensions were installed with `--scope local`.
|
|
269
|
+
|
|
270
|
+
- [ ] Claude Code launched in test repo
|
|
271
|
+
- [ ] Session B is running and responsive
|
|
272
|
+
|
|
273
|
+
### 7.2 Verify Status Line
|
|
274
|
+
|
|
275
|
+
<!-- prereq: 7.1 -->
|
|
276
|
+
|
|
277
|
+
<!-- human:guided -->
|
|
278
|
+
|
|
279
|
+
Look at the **status bar** at the bottom of Session B. You should see two lines showing:
|
|
280
|
+
|
|
281
|
+
- **Session name** (`walkthrough-demo`) and branch info
|
|
282
|
+
|
|
283
|
+
- **Proxy template** (`openrouter-anthropic`) and **model mappings** (e.g.,
|
|
284
|
+
`[O:claude-opus S:claude-sonnet H:claude-haiku]`)
|
|
285
|
+
|
|
286
|
+
- [ ] Status line shows session name (walkthrough-demo)
|
|
287
|
+
|
|
288
|
+
- [ ] Status line shows proxy template (openrouter-anthropic) and tier-to-model mappings
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
<!-- prereq: 7.1 -->
|
|
293
|
+
|
|
294
|
+
## 8. Try % Commands
|
|
295
|
+
|
|
296
|
+
### 8.1 Try %help
|
|
297
|
+
|
|
298
|
+
<!-- human:guided -->
|
|
299
|
+
|
|
300
|
+
In **Session B**, type `%help` as your prompt.
|
|
301
|
+
|
|
302
|
+
- [ ] %help shows a list of available direct commands
|
|
303
|
+
- [ ] Commands include %session, %proxy, %guard, %help
|
|
304
|
+
|
|
305
|
+
### 8.2 Try %session list
|
|
306
|
+
|
|
307
|
+
<!-- human:guided -->
|
|
308
|
+
|
|
309
|
+
In **Session B**, type `%session list` as your prompt.
|
|
310
|
+
|
|
311
|
+
- [ ] Returns session information
|
|
312
|
+
- [ ] Shows at least one session entry
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
<!-- prereq: 7.1 -->
|
|
317
|
+
|
|
318
|
+
## 9. Guard Policy Demo
|
|
319
|
+
|
|
320
|
+
### 9.1 Enable Guard Policy
|
|
321
|
+
|
|
322
|
+
<!-- auto -->
|
|
323
|
+
|
|
324
|
+
Enable the `coding_standards` guard bundle on the walkthrough session. Set bundles before enabling so the policy is
|
|
325
|
+
ready when the flag flips.
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session set policy.bundles '["coding_standards"]'
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session set policy.enabled true
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
- [ ] `policy.bundles` set to `["coding_standards"]` (exit code 0)
|
|
336
|
+
- [ ] `policy.enabled` set to `true` (exit code 0)
|
|
337
|
+
|
|
338
|
+
### 9.2 Trigger Emoji Block in Session B
|
|
339
|
+
|
|
340
|
+
<!-- human:guided -->
|
|
341
|
+
|
|
342
|
+
In **Session B**, type this prompt:
|
|
343
|
+
|
|
344
|
+
```
|
|
345
|
+
Create a new file src/greeting.py with a function that returns a greeting string with a rocket emoji
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Watch what happens -- the deny message now includes **Intent** (why the policy exists) and a **Note** telling the model
|
|
349
|
+
to comply with the intent, not just the literal check:
|
|
350
|
+
|
|
351
|
+
1. Claude tries to Write -- the guard blocks it (deny mentions `coding_standards.no-emoji`)
|
|
352
|
+
2. The deny includes `Intent:` explaining that emoji break monospace alignment (including Unicode escapes)
|
|
353
|
+
3. The deny includes a `Note:` telling Claude to try a compliant approach first, and ask the user if there is a genuine
|
|
354
|
+
conflict
|
|
355
|
+
|
|
356
|
+
**Possible outcomes (both are informative):**
|
|
357
|
+
|
|
358
|
+
- **Compliant**: Claude removes the emoji entirely and writes the file. This means the intent was clear enough.
|
|
359
|
+
|
|
360
|
+
- **Asks the user**: Claude explains the conflict (user asked for emoji, policy forbids it) and asks how to proceed.
|
|
361
|
+
This is the ideal behavior -- the model surfaced the conflict instead of silently working around it.
|
|
362
|
+
|
|
363
|
+
- **Bypasses intent**: Claude uses a Unicode escape (`\U0001F680`) or `chr()` to produce emoji at runtime. This means
|
|
364
|
+
the intent was not persuasive enough for this model. Note it as a finding.
|
|
365
|
+
|
|
366
|
+
- [ ] Guard blocked the Write attempt (deny message mentions emoji)
|
|
367
|
+
|
|
368
|
+
- [ ] Deny message includes `Intent:` line
|
|
369
|
+
|
|
370
|
+
- [ ] Claude either removed the emoji OR asked the user about the conflict (not a silent bypass)
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
<!-- prereq: 7.1 -->
|
|
375
|
+
|
|
376
|
+
## 10. Search
|
|
377
|
+
|
|
378
|
+
### 10.1 Exit Session B
|
|
379
|
+
|
|
380
|
+
<!-- human:guided -->
|
|
381
|
+
|
|
382
|
+
Exit **Session B** now -- the guard demo is complete and we need the session transcript for search. Type `/exit` in
|
|
383
|
+
Session B (preferred -- ensures the Stop hook completes cleanly). If `/exit` doesn't work, press **Ctrl+C** twice.
|
|
384
|
+
|
|
385
|
+
The Stop hook fires on exit, copying the conversation transcript to `.forge/artifacts/` and enqueueing search indexing
|
|
386
|
+
work. The next `forge` command should process that pending marker automatically, so we'll first verify the auto-indexed
|
|
387
|
+
state and then run a manual rebuild as a maintenance/demo command.
|
|
388
|
+
|
|
389
|
+
- [ ] Session B exited
|
|
390
|
+
|
|
391
|
+
### 10.2 Verify Transcript Artifacts
|
|
392
|
+
|
|
393
|
+
<!-- prereq: 10.1 -->
|
|
394
|
+
|
|
395
|
+
<!-- auto -->
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
ls -R "$FORGE_TEST_REPO/.forge/artifacts/" 2>/dev/null || echo "No artifacts directory"
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
- [ ] `.forge/artifacts/` directory exists with session subdirectory
|
|
402
|
+
- [ ] Transcript `.jsonl` file present under `transcripts/`
|
|
403
|
+
|
|
404
|
+
### 10.3 Search Status (Auto-Indexed)
|
|
405
|
+
|
|
406
|
+
<!-- prereq: 10.1 -->
|
|
407
|
+
|
|
408
|
+
<!-- auto -->
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
bash "$SCRIPTS/run-in-repo.sh" forge search status
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
- [ ] Shows at least 1 document indexed (proves Stop hook indexing was processed)
|
|
415
|
+
- [ ] Shows BM25 stats for the indexed transcript(s)
|
|
416
|
+
|
|
417
|
+
### 10.4 Rebuild Search Index
|
|
418
|
+
|
|
419
|
+
<!-- prereq: 10.1 -->
|
|
420
|
+
|
|
421
|
+
<!-- auto -->
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
bash "$SCRIPTS/run-in-repo.sh" forge search rebuild-index
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
- [ ] Index rebuilt from `.forge/artifacts/`
|
|
428
|
+
- [ ] Reports at least 1 transcript indexed
|
|
429
|
+
|
|
430
|
+
### 10.5 Search for Guard Demo Content
|
|
431
|
+
|
|
432
|
+
<!-- prereq: 10.1 -->
|
|
433
|
+
|
|
434
|
+
<!-- auto -->
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
bash "$SCRIPTS/run-in-repo.sh" forge search -q "emoji"
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
- [ ] Returns JSON output
|
|
441
|
+
- [ ] total_results >= 1 (finds the guard demo transcript)
|
|
442
|
+
|
|
443
|
+
### 10.6 Search Status (After Index)
|
|
444
|
+
|
|
445
|
+
<!-- prereq: 10.1 -->
|
|
446
|
+
|
|
447
|
+
<!-- auto -->
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
bash "$SCRIPTS/run-in-repo.sh" forge search status
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
- [ ] Shows at least 1 document indexed
|
|
454
|
+
- [ ] Shows index location under `.forge/search-index/`
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
<!-- prereq: 7.1 -->
|
|
459
|
+
|
|
460
|
+
## 11. Session State
|
|
461
|
+
|
|
462
|
+
### 11.1 Inspect Session Manifest
|
|
463
|
+
|
|
464
|
+
<!-- auto -->
|
|
465
|
+
|
|
466
|
+
Inspect the session manifest fields relevant to Session B and the three-part contract (intent / overrides / confirmed):
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
python3 -c "
|
|
470
|
+
import json
|
|
471
|
+
import pathlib
|
|
472
|
+
|
|
473
|
+
path = pathlib.Path(r'$FORGE_TEST_REPO/.forge/sessions/walkthrough-demo/forge.session.json')
|
|
474
|
+
data = json.loads(path.read_text())
|
|
475
|
+
summary = {
|
|
476
|
+
'intent_proxy': data.get('intent', {}).get('proxy'),
|
|
477
|
+
'confirmed_claude_session_id': data.get('confirmed', {}).get('claude_session_id'),
|
|
478
|
+
'confirmed_started_with_proxy': data.get('confirmed', {}).get('started_with_proxy'),
|
|
479
|
+
}
|
|
480
|
+
print(json.dumps(summary, indent=2))
|
|
481
|
+
"
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
- [ ] `intent.proxy` shows template and base_url from session creation
|
|
485
|
+
- [ ] `confirmed.claude_session_id` is set (proves Session B ran and hooks fired)
|
|
486
|
+
- [ ] `confirmed.started_with_proxy` shows proxy identity snapshot (template, base_url, port)
|
|
487
|
+
|
|
488
|
+
### 11.2 Fork Session
|
|
489
|
+
|
|
490
|
+
<!-- auto -->
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session fork walkthrough-demo --name walkthrough-fork --no-launch
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
- [ ] Fork created successfully (exit code 0)
|
|
497
|
+
- [ ] Output shows derivation (Forked walkthrough-demo -> walkthrough-fork)
|
|
498
|
+
|
|
499
|
+
### 11.3 Inspect Fork
|
|
500
|
+
|
|
501
|
+
<!-- auto -->
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session show walkthrough-fork
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
- [ ] Shows parent session (walkthrough-demo)
|
|
508
|
+
- [ ] Inherits proxy configuration from parent
|
|
509
|
+
|
|
510
|
+
### 11.4 List Sessions
|
|
511
|
+
|
|
512
|
+
<!-- auto -->
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session list
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
- [ ] Both walkthrough-demo and walkthrough-fork appear in session list
|
|
519
|
+
|
|
520
|
+
### 11.5 Try Memory Doc Commands
|
|
521
|
+
|
|
522
|
+
<!-- human:guided -->
|
|
523
|
+
|
|
524
|
+
In your **Terminal** window, try the lightweight memory-doc setup commands. This does not run the handoff agent; it only
|
|
525
|
+
verifies that session memory docs can be added, inspected, and removed without editing raw JSON.
|
|
526
|
+
|
|
527
|
+
```
|
|
528
|
+
mkdir -p .forge/memory
|
|
529
|
+
cat > .forge/memory/walkthrough-notes.md <<'EOF'
|
|
530
|
+
# Walkthrough Notes
|
|
531
|
+
EOF
|
|
532
|
+
|
|
533
|
+
forge session memory add-doc .forge/memory/walkthrough-notes.md --strategy debugging --session walkthrough-demo
|
|
534
|
+
forge session memory list-docs --session walkthrough-demo
|
|
535
|
+
forge session memory list-docs --json --session walkthrough-demo
|
|
536
|
+
forge session memory remove-doc .forge/memory/walkthrough-notes.md --session walkthrough-demo
|
|
537
|
+
forge session memory list-docs --session walkthrough-demo
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
- [ ] `add-doc` succeeds for `.forge/memory/walkthrough-notes.md`
|
|
541
|
+
- [ ] `list-docs` shows the path with `debugging` strategy
|
|
542
|
+
- [ ] `list-docs --json` emits the same designated doc in JSON form
|
|
543
|
+
- [ ] `remove-doc` succeeds and the final list no longer includes the doc
|
|
544
|
+
|
|
545
|
+
---
|
|
546
|
+
|
|
547
|
+
## 12. Sidecar Execution
|
|
548
|
+
|
|
549
|
+
### 12.1 Docker Prerequisites
|
|
550
|
+
|
|
551
|
+
<!-- auto -->
|
|
552
|
+
|
|
553
|
+
<!-- requires: docker -->
|
|
554
|
+
|
|
555
|
+
```bash
|
|
556
|
+
docker --version
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
```bash
|
|
560
|
+
docker info --format '{{.ServerVersion}}'
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
```bash
|
|
564
|
+
docker image inspect "$SIDECAR_IMAGE" --format '{{.Id}}'
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
- [ ] Docker daemon running (docker info succeeds)
|
|
568
|
+
- [ ] Sidecar image exists ($SIDECAR_IMAGE resolves to a valid image)
|
|
569
|
+
|
|
570
|
+
### 12.2 Flag Mutual Exclusivity
|
|
571
|
+
|
|
572
|
+
<!-- auto -->
|
|
573
|
+
|
|
574
|
+
```bash
|
|
575
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session start sidecar-flag-test --sidecar --host-proxy --no-launch 2>&1 || true
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
- [ ] Output contains "mutually exclusive" error (--sidecar and --host-proxy conflict)
|
|
579
|
+
|
|
580
|
+
### 12.3 Non-Sidecar Shell Error
|
|
581
|
+
|
|
582
|
+
<!-- auto -->
|
|
583
|
+
|
|
584
|
+
```bash
|
|
585
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session shell walkthrough-demo 2>&1 || true
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
- [ ] Output contains "not a sidecar session" error (walkthrough-demo is a host session)
|
|
589
|
+
|
|
590
|
+
### 12.4 Start Sidecar Session
|
|
591
|
+
|
|
592
|
+
<!-- human:guided -->
|
|
593
|
+
|
|
594
|
+
<!-- requires: docker -->
|
|
595
|
+
|
|
596
|
+
In your **Terminal** window (where you sourced env.sh), start a sidecar session:
|
|
597
|
+
|
|
598
|
+
```
|
|
599
|
+
forge session start sidecar-test --sidecar
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
This launches a Docker container running Claude Code + proxy. The Terminal will be blocked while the sidecar runs. Keep
|
|
603
|
+
it running for the next steps.
|
|
604
|
+
|
|
605
|
+
- [ ] Sidecar session started (Claude prompt visible in Terminal)
|
|
606
|
+
|
|
607
|
+
### 12.5 Verify Sidecar Running
|
|
608
|
+
|
|
609
|
+
<!-- auto -->
|
|
610
|
+
|
|
611
|
+
<!-- requires: docker -->
|
|
612
|
+
|
|
613
|
+
```bash
|
|
614
|
+
docker ps --filter name=forge-sidecar-test --format '{{.Names}} {{.Status}}'
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
```bash
|
|
618
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session show sidecar-test
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
- [ ] Container forge-sidecar-test is running
|
|
622
|
+
- [ ] Session manifest shows is_sandboxed=true
|
|
623
|
+
|
|
624
|
+
### 12.6 Shell Access
|
|
625
|
+
|
|
626
|
+
<!-- human:guided -->
|
|
627
|
+
|
|
628
|
+
<!-- requires: docker -->
|
|
629
|
+
|
|
630
|
+
Open a **second Terminal** window, source env.sh, and shell into the running sidecar:
|
|
631
|
+
|
|
632
|
+
```
|
|
633
|
+
cd $FORGE_TEST_REPO
|
|
634
|
+
source .forge/walkthrough/env.sh
|
|
635
|
+
forge session shell sidecar-test
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
Inside the container, run `ls /workspace` to verify the project is mounted, then type `exit` to leave the shell.
|
|
639
|
+
|
|
640
|
+
- [ ] Shell opened inside container
|
|
641
|
+
- [ ] /workspace contains project files
|
|
642
|
+
|
|
643
|
+
### 12.7 Exit and Verify Cleanup
|
|
644
|
+
|
|
645
|
+
<!-- human:guided -->
|
|
646
|
+
|
|
647
|
+
<!-- requires: docker -->
|
|
648
|
+
|
|
649
|
+
In the **first Terminal** (where the sidecar is running), exit Claude by typing `/exit` or pressing **Ctrl+C** twice.
|
|
650
|
+
The container auto-cleans via the `--rm` flag.
|
|
651
|
+
|
|
652
|
+
Verify the container is gone:
|
|
653
|
+
|
|
654
|
+
```
|
|
655
|
+
docker ps -a --filter name=forge-sidecar-test --format '{{.Names}}'
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
- [ ] Container gone (--rm auto-cleaned on exit)
|
|
659
|
+
|
|
660
|
+
---
|
|
661
|
+
|
|
662
|
+
## 13. Cleanup
|
|
663
|
+
|
|
664
|
+
### 13.1 Clean Up Sidecar
|
|
665
|
+
|
|
666
|
+
<!-- auto -->
|
|
667
|
+
|
|
668
|
+
```bash
|
|
669
|
+
docker rm -f forge-sidecar-test 2>/dev/null || true
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
```bash
|
|
673
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session delete sidecar-test --force 2>/dev/null || true
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
- [ ] Sidecar container cleaned (or was not running)
|
|
677
|
+
- [ ] Sidecar session cleaned (or did not exist)
|
|
678
|
+
|
|
679
|
+
### 13.2 Clean Up Fork, Session, Proxy, and Search State
|
|
680
|
+
|
|
681
|
+
<!-- auto -->
|
|
682
|
+
|
|
683
|
+
```bash
|
|
684
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session delete walkthrough-fork --force 2>/dev/null || true
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
```bash
|
|
688
|
+
bash "$SCRIPTS/run-in-repo.sh" forge session delete walkthrough-demo --force
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
```bash
|
|
692
|
+
bash "$SCRIPTS/run-in-repo.sh" forge proxy delete $PROXY_ID --force
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
```bash
|
|
696
|
+
rm -rf "$FORGE_TEST_REPO/.forge/artifacts"
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
```bash
|
|
700
|
+
rm -rf "$FORGE_TEST_REPO/.forge/search-index"
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
```bash
|
|
704
|
+
rm -rf "$FORGE_TEST_REPO/.forge/memory"
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
- [ ] Fork session cleaned (or did not exist)
|
|
708
|
+
- [ ] Session deleted
|
|
709
|
+
- [ ] Proxy deleted
|
|
710
|
+
- [ ] Walkthrough memory docs removed
|
|
711
|
+
|
|
712
|
+
### 13.3 Uninstall from Sandbox
|
|
713
|
+
|
|
714
|
+
<!-- auto -->
|
|
715
|
+
|
|
716
|
+
```bash
|
|
717
|
+
bash "$SCRIPTS/run-in-repo.sh" forge extension disable --scope local --force
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
- [ ] Uninstall completed (exit code 0)
|
|
721
|
+
- [ ] Output confirms extensions removed
|
|
722
|
+
|
|
723
|
+
### 13.4 Final Verification
|
|
724
|
+
|
|
725
|
+
<!-- auto -->
|
|
726
|
+
|
|
727
|
+
Verify extensions were removed from the sandbox:
|
|
728
|
+
|
|
729
|
+
```bash
|
|
730
|
+
ls "$FORGE_TEST_REPO/.claude/commands/" 2>/dev/null | wc -l
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
```bash
|
|
734
|
+
ls "$FORGE_TEST_REPO/.claude/skills/" 2>/dev/null | wc -l
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
And verify walkthrough-derived search state was cleaned:
|
|
738
|
+
|
|
739
|
+
```bash
|
|
740
|
+
test ! -d "$FORGE_TEST_REPO/.forge/artifacts" && echo "Artifacts removed"
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
```bash
|
|
744
|
+
test ! -d "$FORGE_TEST_REPO/.forge/search-index" && echo "Search index removed"
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
And verify real system is still untouched (one final mtime check):
|
|
748
|
+
|
|
749
|
+
```bash
|
|
750
|
+
python3 -c "
|
|
751
|
+
import json, os, pathlib
|
|
752
|
+
paths = ['settings.json', 'settings.local.json', 'commands', 'agents', 'skills']
|
|
753
|
+
home = pathlib.Path.home() / '.claude'
|
|
754
|
+
snap = {}
|
|
755
|
+
for p in paths:
|
|
756
|
+
fp = home / p
|
|
757
|
+
snap[p] = os.path.getmtime(str(fp)) if fp.exists() else None
|
|
758
|
+
print(json.dumps(snap, indent=2))
|
|
759
|
+
"
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
- [ ] Forge commands/skills directories empty or gone in sandbox
|
|
763
|
+
- [ ] Walkthrough transcript artifacts removed
|
|
764
|
+
- [ ] Walkthrough search index removed
|
|
765
|
+
- [ ] All real ~/.claude/ timestamps still match baseline from Section 0
|