English | 中文
- Docker + Compose v2 (Desktop / OrbStack / Colima) and/or Apple Container
on macOS (
brew install container). Install detects engines: aborts if none; prompts if several are reachable (--docker-context/--runtimefor CI). - An LLM API key (for real answers;
CASST_MOCK=1works for plumbing smoke) - Git remotes you are allowed to clone (public HTTPS or a PAT in
secrets/gh_token) - A code2wiki image: published
ghcr.io/finogeeks/code2wiki:<ver>, or a local dogfood tag such ascode2wiki:dev(setCODE2WIKI_IMAGEin.env) - Optional: host FinClaw CLI for A2A/MCP
caller smokes (
./scripts/ensure-finclaw.shinstalls it)
No clone, no flags — run in a terminal; prompts ask for site, pack, remotes:
curl -fsSL https://raw.githubusercontent.com/finogeeks/code2wiki/main/install.sh | shFrom an existing intake checkout (also interactive by default):
./scripts/get-started.shCI / non-interactive (all required args explicit):
./scripts/get-started.sh --site ~/casst-site --pack acme \
--repo my-app=https://github.com/org/app.gitUseful flags: --lang zh|en, --mock, --skip-finclaw, --skip-caller,
--agent (FinClaw setup chat after complete), --force, --no-up (stop after
configure). Locale also follows CODE2WIKI_LANG or LANG (zh* → Chinese).
Success means runtime/eval/SETUP_COMPLETE.json exists and the banner prints
SETUP_COMPLETE. Then jump to §7 Operator console.
./scripts/init-site.sh ~/casst-site --pack acme
cd ~/casst-siteIf another appliance already binds host :8080, edit .env:
CODE2WIKI_PORT=18080
CASST_PUBLIC_BASE_URL=http://127.0.0.1:18080
# optional when multiple sites share one Docker daemon:
# COMPOSE_PROJECT_NAME=casst-acmePrefer the helper (writes YAML + LLM .env knobs + optional secrets):
./scripts/configure-pack.sh --pack acme \
--repo my-app=https://github.com/org/app.git \
--llm-provider openai --llm-model gpt-4.1 \
--llm-base-url '' --llm-key-file ./my-key.txt
# interactive TTY also works without --repo / --llm-* (prompts for provider,
# base URL, model, and API key — no provider assumed)Or edit profiles/acme/sources.yaml by hand. Keep visibility: private unless
the corpus is intentionally public. Use expect_sources: [your-source-id] in
retrieval-eval.yaml (not expect_source_ids).
# Non-secret LLM routing lives in .env (also set by configure-pack):
# LLM_PROVIDER=… LLM_BASE_URL=… LLM_MODEL=…
printf '%s' 'sk-…' > secrets/llm_api_key
printf '%s' 'ghp-…' > secrets/gh_token # if needed
chmod 600 secrets/*configure-pack can mint secrets/a2a_peer_token when empty. Do not put the
API key in .env — only provider / base URL / model.
# Prefer published GHCR (default when CODE2WIKI_IMAGE is unset):
# echo 'CODE2WIKI_IMAGE=ghcr.io/finogeeks/code2wiki:0.1.0' >> .env
# Local dogfood fallback:
# echo 'CODE2WIKI_IMAGE=code2wiki:dev' >> .env
./scripts/pull-image.sh # uses CODE2WIKI_IMAGE / VERSION; refreshes registry tags
# CODE2WIKI_PULL=0 ./scripts/pull-image.sh # airgap: keep local copy only
./scripts/up.sh # facade on CODE2WIKI_PORT (default :8080)
./scripts/doctor.sh # /healthz./scripts/activate.sh acme
# Clone remotes into the appliance mirror store and warm the knowledge cache.
# Skipping this leaves corpus-link empty and asks poorly grounded.
# Newer images also seed a README overview stub when a product has no ledger pages.
./scripts/ingest.sh
# or: ./scripts/ingest.sh --source <id>
# optional routing gate (needs retrieval-eval filled):
./scripts/exec.sh ./scripts/casst-retrieval-eval.py \
--fixtures profiles/acme/retrieval-eval.yaml./scripts/ask.sh "How do I deploy the product?" --product <source-id>
./scripts/setup-complete.sh # doctor + REST/A2A smoke + FinClaw callers
# or: ./scripts/smoke-facade.sh <source-id>The facade scopes the capability ledger with a products array. Prefer an
explicit source id (or rely on auto-scope when the pack has exactly one source).
Multi-source packs: pass --product for each relevant id.
First success = a JSON answer from /v1/ask. Grounding may return a short
degraded envelope if the model over-claims; that still proves the ledger path.
Capability pages under runtime/answer-cache/wiki/capabilities/ improve answer
quality (see operator skills inside the image).
After a few asks, open the operator console in a browser:
http://127.0.0.1:${CODE2WIKI_PORT:-8080}/operator
Example with a non-default port: http://127.0.0.1:18080/operator.
This is an ops review UI (not a chat window). It shows request counts,
gaps, FAQ drafts, and alias candidates so the appliance is not a black box.
Reads are open by default; approve / reject / apply need
CASST_OPERATOR_TOKEN set on the facade (Compose / .env), then paste the
same value into the console’s token field.
Populate the console from live asks (journal → report → snapshot):
# Inside the running image (default min cluster size is 2; use 1 while dogfooding)
./scripts/exec.sh sh -c 'EXPERIENCE_MIN_COUNT=1 ./scripts/run-experience-loop.sh all'Then click Reload snapshot on /operator. Optional dissatisfaction signal:
curl -sS -X POST "http://127.0.0.1:${CODE2WIKI_PORT:-8080}/v1/feedback" \
-H 'content-type: application/json' \
-d '{"request_id":"<id-from-ask-or-journal>","verdict":"incomplete","detail":"…"}'Journal path on the site: runtime/logs/casst-journal.jsonl.
/healthz → operator.console / operator.snapshot_present confirms the UI.
Site helpers (after SETUP_COMPLETE):
./scripts/ask-casst-a2a.sh "Your question"
./scripts/ask-casst-mcp.sh "Your question"
./scripts/run-setup-agent.sh # FinClaw setup-guide profileSee calling.md (中文) for protocol details.
| Symptom | Likely cause |
|---|---|
pull / up cannot find image |
Set CODE2WIKI_IMAGE=code2wiki:dev (or a GHCR tag) in .env |
| Port already allocated | Change CODE2WIKI_PORT (+ CASST_PUBLIC_BASE_URL) |
| Ask times out / empty body | Raise CODE2WIKI_ASK_TIMEOUT; check LLM key / provider in logs |
| Answers say ledger unknown / no capabilities | Run ./scripts/ingest.sh; pass --product <source-id>; confirm CASST_LEDGER_ROOT |
Retrieval eval 0% with expect=[] |
Use expect_sources: in retrieval-eval.yaml |
[corpus-link] SKIP … no local/mirror |
Ingest/reconcile not run, or mirror path not linked (ingest.sh fixes this) |
/operator empty (0 gaps / drafts) |
Run experience loop after some asks; click Reload snapshot |
| Approve / apply returns 503 | Set CASST_OPERATOR_TOKEN in Compose / .env and restart; paste token in UI |
finclaw: command not found |
./scripts/ensure-finclaw.sh then source runtime/.finclaw-env or put ~/.local/bin on PATH |
| get-started non-interactive fails | Pass --repo id=url (repeatable) or run on a TTY |