You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Meta: Detailed build plan for a new forge try onboarding command, filed for execution. Phase 1's "hero skill must be keyless" requirement is coupled to #349 (weather skill → keyless API) — land or account for that first so the demo never dead-ends on a missing key.
Target: Claude Code, direct execution. Repo:github.com/initializ/forge (multi-module Go workspace, go.work, Go 1.25). Command owner:forge-cli. Keep forge-core free of any CLI/render dependency.
1. Objective
Ship forge try: a single command that takes a first-time user from install to talking to a working agent whose loop they can watch in under 60 seconds, with zero required decisions — no channels, no secrets file, no forge build, no container, no cluster.
The command must reuse the existing Runner, executor, OAuth flow, audit logger, and progress hooks. It does not introduce a second agent loop, a second scaffold path, or a second provider-resolution path.
The differentiator is that the loop is visible: as the agent picks a skill, calls a tool, and hits an egress check, those events render inline in the terminal. This is the same audit signal the enterprise story rests on, surfaced as the first-run delight.
2. Target experience (build to this exact spec)
$ forge try
forge try — talking to a live agent in your terminal.
No build, no cluster. Ctrl-D or /exit to quit.
Using OpenAI (signed in). # or "Using ANTHROPIC_API_KEY from env" / "Using local Ollama (llama3.2)"
Agent: quickstart · skills: weather · tools: http_request, datetime_now, math_calculate
Try: what's the weather in Tokyo?
fetch https://example.com and summarize it
what's 17% of 4,200?
you › what's the weather in Tokyo, should I pack an umbrella?
▸ skill weather
▸ tool weather_current(location="Tokyo")
▸ egress api.open-meteo.com ✓ allowed
◂ 18°C, light rain this evening
agent › 18°C in Tokyo with light rain expected tonight. Yes, take the umbrella.
audit {"event":"tool_exec","tool":"weather_current","egress":"api.open-meteo.com","decision":"allow"}
you › ^D
You just ran an agent whose every tool call and egress you can see and audit.
Want to keep it and make it yours? → forge try --keep (writes ./forge-quickstart)
Then edit skills/, run it as a service with `forge serve`, or deploy with `forge package`.
Non-interactive single-shot form (used by CI, tests, and copy-paste docs):
$ forge try --once "what's 2 + 2?"
3. Architecture decisions (locked — do not relitigate)
In-process, not HTTP.forge try builds the Runner/executor in-process and drives it from a stdin REPL. No A2A server, no daemon, no forge serve, no port binding. This is the fastest path and avoids the daemon/port machinery.
Ephemeral workspace by default. Scaffold the demo agent into a temp dir (os.MkdirTemp, cleaned on exit) unless --keep is passed, in which case scaffold into ./forge-quickstart. Never write encrypted secrets to disk for the ephemeral run.
Reuse scaffold() with a preset. Do not fork init logic. Add a preset descriptor that scaffold() consumes so forge try and forge init share one code path.
Reuse the existing provider resolution + OAuth.forge try adds an ordering policy on top of existing resolution (env key → saved OAuth → Ollama → interactive picker). It does not add a new LLM client or new credential store.
Consume existing audit + progress events; do not invent new ones. The visible-loop renderer subscribes to the audit sink and progress hooks already emitted by the runner. No new audit event constants.
Renderer lives in forge-cli.forge-core stays CLI/TTY-agnostic. The pretty renderer is a forge-cli concern.
Hero interaction must be genuinely keyless (beyond the model credential). Confirm the demo skill needs no third-party API key; if weather (embedded) requires one, use a keyless endpoint (e.g. Open-Meteo via http_request or a keyless weather variant) so the demo never dead-ends on a missing key. See Phase 1 verification. (Tracked by Weather embedded skill points at key-gated APIs (never works) — switch to a keyless service #349.)
4. Scope exclusions (out of scope for this doc)
Hosted/metered demo key proxied through Initializ. (Highest-value future add; note it, do not build it here.)
Any forge ui / web changes. Terminal only. (forge try --ui is a later, separate doc.)
Remote skill registry (Tier 3).
Authoring any new embedded skill. Reuse the existing registry.
Add a Preset field to the init/scaffold options and a quickstartPreset() returning the demo agent definition (see below). scaffold() consumes the preset instead of wizard answers. Do not duplicate scaffold.
forge-cli/internal/preset/quickstart.go
New (or inline in init.go). The demo agent: agent_id: quickstart, resolved model, skills: [weather-or-keyless-equivalent], tools: [http_request, datetime_now, math_calculate], egress auto-derived, no channels, memory in-memory. Include a short system prompt describing the capabilities and the three suggested prompts.
Demo preset requirements
Egress mode: allowlist, domains auto-derived from the chosen skill (no dev-open).
No channels, no secrets file, no long-term memory.
System prompt: friendly general assistant; may check weather, fetch URLs, do math/time; concise answers.
Verification
go build ./...
go vet ./...
# ephemeral scaffold + load, no model call:
forge try --yes --provider ollama --model llama3.2 --once ""# empty prompt -> load + summary + exit# expect: agent summary line printed, temp dir created then removed, exit 0
ls ./forge-quickstart 2>/dev/null &&echo"LEAK: ephemeral wrote to cwd (should not)"
forge try --keep --yes --provider ollama --once ""&&test -f ./forge-quickstart/forge.yaml &&echo"keep OK"
rm -rf ./forge-quickstart
Verify keylessness of the hero skill (blocking): confirm the weather embedded skill needs no third-party API key at runtime. If it does, switch the preset's hero to a keyless path (Open-Meteo https://api.open-meteo.com via http_request, or a keyless weather variant) and update the suggested prompts + egress domain accordingly. The hero interaction must never fail on a missing third-party key. (See #349.)
Anti-patterns
Do not copy/paste scaffold into a try-specific function.
Do not add a channel or secrets step.
Do not leave the temp dir behind on exit (defer cleanup, including on Ctrl-C).
Done when:forge try scaffolds, loads, summarizes, and cleans up, with --keep writing to ./forge-quickstart.
Phase 2 — Model credential auto-resolution
Goal:forge try picks the fastest available model credential with no prompts when one exists, and offers a minimal picker only when nothing is available.
File
Change
forge-cli/cmd/try.go
Add resolveTryProvider(ctx, flags) implementing the ordering policy below. Returns a resolved provider/model + a human label for the summary line.
Resolution order
--provider/--model flags, if set → use them.
Env key present (ANTHROPIC_API_KEY → OPENAI_API_KEY → GEMINI_API_KEY, in that preference) → use silently, print Using <PROVIDER> from env.
Saved OpenAI OAuth session (oauth.LoadCredentials() succeeds) → use OAuth/Responses, print Using OpenAI (signed in).
Ollama daemon reachable at 127.0.0.1:11434 → use with a small default model; print a one-line note that first response may be slow if the model must download. Do not silently block on a multi-GB pull; if the model is absent and no TTY, error with guidance.
Nothing available and TTY present → picker (bubbletea, reuse wizard components): [Sign in with OpenAI (recommended)] [Paste an API key] [Use local Ollama]. OpenAI → runOAuthFlow(). Paste → masked input, held in memory (written to disk only under --keep).
Nothing available and no TTY (CI) → clear error listing the three options.
Respect existing routing: OAuth tokens use the Responses endpoint; API keys use Chat Completions. Never mix (existing invariant). Reuse createProviderClient.
Verification
# env-key path (fastest, silent):
ANTHROPIC_API_KEY=sk-... forge try --once "say hi in 3 words"# expect: "Using ANTHROPIC_API_KEY from env", a reply, exit 0# no creds, no TTY -> actionable error, non-zero exit:
env -u ANTHROPIC_API_KEY -u OPENAI_API_KEY -u GEMINI_API_KEY forge try --once "hi"< /dev/null
Anti-patterns
No new credential store or .env mutation for the ephemeral run.
Do not fall through to an unauthenticated client (existing 401-surfacing behavior must hold).
No em-dashes in any printed string (house style).
Done when: each of the four credential sources drives a working reply, and the no-creds path gives an actionable message.
Phase 3 — In-process REPL driving the executor
Goal: A real conversation. Read stdin, run one agent turn per line through the existing executor, stream the assistant reply, maintain history in memory, exit on /exit, Ctrl-D, or Ctrl-C.
File
Change
forge-cli/cmd/try.go
Add the REPL loop. Build the Runner/executor once (Phase 1 preset + Phase 2 credentials), then per line call the executor with accumulated history. Handle --once as a single turn then exit.
forge-cli/runtime/runner.go
If needed, expose a minimal in-process "run one turn with history" entry that the REPL calls, reusing the same executor path forge run uses. Do not add a second executor.
Behavior
Maintain conversation history in a slice in memory; append user + assistant + tool messages exactly as the executor loop already does.
Stream assistant tokens to stdout under an agent › prefix.
Honor Ctrl-C mid-turn via the existing cancellation path (context cancel at iteration/tool boundary).
--once <prompt>: run exactly one turn, print, exit with the turn's status code.
Verification
go build ./... && go vet ./...
printf'what is 2+2?\n/exit\n'| forge try --provider ollama --model llama3.2
forge try --once "fetch https://example.com and give me the page title"# expect: a tool call happens (http_request), a real answer, clean exit
Anti-patterns
Do not stand up the A2A HTTP server or forge serve.
Do not reimplement the tool-calling loop; call the existing executor.
Do not persist sessions to disk for the ephemeral run.
Done when: multi-turn chat works, tools actually execute, cancel and exit are clean.
Phase 4 — Visible-loop renderer
Goal: The differentiator. Render skill/tool/egress/guardrail events inline as the turn runs, plus one compact audit line per turn. This is what makes the first 60 seconds feel like Forge and not a generic chatbot.
File
Change
forge-cli/internal/tryview/renderer.go
New. A renderer that subscribes to the audit sink + progress hooks and prints styled lines. Owns all lipgloss styling.
forge-cli/cmd/try.go
Attach the renderer to the runner (add it as a secondary audit sink / progress consumer alongside the existing NDJSON sink). Gate with --quiet (hide loop) and --audit (show full NDJSON instead of the compact line).
Event → line mapping
Event
Rendered line
skill selected (from tool_exec context / system)
▸ skill <name>
tool_exec phase=start
▸ tool <tool>(<short arg preview>)
egress_allowed
▸ egress <domain> ✓ allowed
egress_blocked
▸ egress <domain> ✗ blocked
guardrail_check decision=blocked
▸ guard <name> ✗ blocked
tool_exec phase=end
◂ <short result preview>
per-turn summary
one dim audit {…compact json…} line (suppressed by --quiet, expanded by --audit)
Styling: orange accent #F97316 for the ▸/labels; muted grey for the audit line. Auto-detect no-color / non-TTY and degrade to plain text.
Truncate arg/result previews (~80 cols); never dump full tool payloads inline.
The renderer reads from existing events only. If a field (e.g. domain) is not on the event, omit that line — do not re-derive it.
Verification
# hero path shows the loop:
forge try --once "what's the weather in Tokyo?"# expect skill+tool+egress lines then the answer
forge try --once "what's the weather in Tokyo?" --quiet # expect answer only, no loop lines
forge try --once "what's the weather in Tokyo?" --audit # expect full NDJSON per event
Anti-patterns
Do not add new audit event types or emit from forge-core for rendering.
Do not put any lipgloss/TTY code in forge-core.
Do not block the turn on rendering; rendering is a passive consumer.
Done when: the hero prompt shows skill → tool → egress → answer inline, --quiet and --audit both work, and non-TTY output is clean plain text.
Phase 5 — First-run polish + graduation hook
Goal: Frame the delight and hand the user up the ladder to building their own.
File
Change
forge-cli/cmd/try.go
Welcome banner (see Section 2). Print the three suggested prompts. On exit (interactive, not --once), print the graduation message.
forge-cli/cmd/try.go
If the ephemeral run was not--keep, the exit message offers forge try --keep (writes ./forge-quickstart). If it was--keep, point at editing skills/, forge serve, and forge package.
Copy rules: concise, problem-first, no em-dashes, orange accent only on the command tokens. Do not oversell.
Done when: banner, suggestions, and the correct graduation message all render.
Phase 6 — Docs: rebuild getting-started around forge try
Goal: Make the first documented step a single command with a payoff, and move the production pipeline out of the "quick start."
File
Change
docs/getting-started/quick-start.md
Rewrite. First code block is one command: brew install initializ/tap/forge && forge try. Then the hero transcript. Then a 4-rung ladder (below). Remove channels/build/deploy from this page.
Trim so it is not a prerequisite to the quick start; link, don't gate.
README.md (repo root)
Replace the getting-started snippet with the forge try one-liner + transcript.
forge.md §15 "How to create an agent"
Add a one-line pointer at the top: for a first taste, forge try; the pipeline below is for building your own.
The ladder (put in quick-start.md):
60sforge try — talk to an agent, watch it use a tool.
5 minforge try --keep then forge init — make it yours, edit a SKILL.md, add a skill.
15 minforge serve + tail the audit log + add a guardrail and watch it block.
Shipforge package — egress-enforced container into your own cluster.
Verification
# link check / build of docs site if applicable; otherwise manual review:
grep -n "forge try" docs/getting-started/quick-start.md README.md
grep -rn "slack" docs/getting-started/quick-start.md &&echo"FAIL: channels leaked into quick start"
Done when: quick-start's first block is forge try, the pipeline lives on its own page, and no channel/build steps remain in the quick start.
Phase 7 — Tests
File
Change
forge-cli/cmd/try_test.go
New. Table-driven, stdlib testing, no testify. Cover: preset builds a valid config; resolveTryProvider ordering (env > oauth > ollama > picker) with a mock TTY-absent path; --once single-turn exit code; ephemeral temp dir is removed; --keep writes to cwd.
forge-cli/internal/tryview/renderer_test.go
New. Feed synthetic audit/progress events; assert the mapped lines (allowed/blocked/guardrail), truncation, and plain-text (no-color) degradation.
Mock LLM/tool calls with httptest.NewServer where a network hop is implied; do not hit real providers in unit tests.
Verification
go test ./forge-cli/...
go build ./... && go vet ./...
Done when: new tests pass and the whole workspace builds and vets clean.
7. Global anti-pattern checklist (applies to every phase)
No second agent loop, scaffold path, or provider-resolution path — reuse.
No A2A server, daemon, or port binding in forge try.
No forge build, container, K8s, or egress-file generation in the try path.
No channels anywhere near try.
No new audit event constants; the renderer consumes existing events.
No lipgloss/TTY code in forge-core.
No secrets written to disk for the ephemeral run (only under --keep).
No silent fall-through to an unauthenticated LLM client.
No blocking on multi-GB Ollama pulls without a warning and a non-TTY error path.
No em-dashes in user-facing strings.
8. Definition of done (whole feature)
forge try on a clean machine with an OpenAI login (or any model key in env) drops the user into a streaming chat with a working agent, the hero prompt shows skill → tool → egress → answer inline plus one audit line, --once gives a one-line non-interactive demo, --keep graduates the agent to ./forge-quickstart, docs lead with the one-liner, and go build ./... && go vet ./... && go test ./forge-cli/... are green.
9. Deferred (name, do not build)
Hosted metered demo key via Initializ proxy (true zero-credential first run).
Build Plan:
forge try— Instant-Gratification OnboardingTarget: Claude Code, direct execution.
Repo:
github.com/initializ/forge(multi-module Go workspace,go.work, Go 1.25).Command owner:
forge-cli. Keepforge-corefree of any CLI/render dependency.1. Objective
Ship
forge try: a single command that takes a first-time user from install to talking to a working agent whose loop they can watch in under 60 seconds, with zero required decisions — no channels, no secrets file, noforge build, no container, no cluster.The command must reuse the existing Runner, executor, OAuth flow, audit logger, and progress hooks. It does not introduce a second agent loop, a second scaffold path, or a second provider-resolution path.
The differentiator is that the loop is visible: as the agent picks a skill, calls a tool, and hits an egress check, those events render inline in the terminal. This is the same audit signal the enterprise story rests on, surfaced as the first-run delight.
2. Target experience (build to this exact spec)
Non-interactive single-shot form (used by CI, tests, and copy-paste docs):
3. Architecture decisions (locked — do not relitigate)
forge trybuilds the Runner/executor in-process and drives it from a stdin REPL. No A2A server, no daemon, noforge serve, no port binding. This is the fastest path and avoids the daemon/port machinery.os.MkdirTemp, cleaned on exit) unless--keepis passed, in which case scaffold into./forge-quickstart. Never write encrypted secrets to disk for the ephemeral run.scaffold()with a preset. Do not fork init logic. Add a preset descriptor thatscaffold()consumes soforge tryandforge initshare one code path.forge tryadds an ordering policy on top of existing resolution (env key → saved OAuth → Ollama → interactive picker). It does not add a new LLM client or new credential store.forge-cli.forge-corestays CLI/TTY-agnostic. The pretty renderer is aforge-cliconcern.weather(embedded) requires one, use a keyless endpoint (e.g. Open-Meteo viahttp_requestor a keyless weather variant) so the demo never dead-ends on a missing key. See Phase 1 verification. (Tracked by Weather embedded skill points at key-gated APIs (never works) — switch to a keyless service #349.)4. Scope exclusions (out of scope for this doc)
forge ui/ web changes. Terminal only. (forge try --uiis a later, separate doc.)trypath.5. Reuse inventory (find these before writing new code)
forge tryscaffold(...)+ init options structforge-cli/cmd/init.gorunOAuthFlow()forge-cli/cmd/*(wrapped incmd/ui.goasOAuthFlowFunc)oauth.LoadCredentials()forge-core(llm/oauth)createProviderClient(...),ResolveModelConfig()forge-cli/runtime/runner.goOAuthClient,ResponsesClient,OpenAIClientforge-core/llm/OPENAI_API_KEY/ANTHROPIC_API_KEY/GEMINI_API_KEYforge-cli/runtimeregisterAuditHooks,registerProgressHooks,registerSkillTools, executor buildforge-cli/runtime/runner.goAuditLogger,Emit,EmitFromContext, audit constants (tool_exec,egress_allowed,egress_blocked,guardrail_check,llm_call,session_start/end)forge-core/runtime/audit.gotool_start/tool_endviaregisterProgressHooks)forge-cli/runtime/runner.goweather,http_requestbuiltin,datetime_now,math_calculate,uuid_generate)forge-skills/local/embedded/,forge-core/tools/builtins/lipgloss(already a dep)#F97316If any symbol name differs, adapt to the real name — do not create a parallel duplicate.
6. Phases
Each phase must build and run before starting the next. Stop on any failed verification and report; do not proceed.
Phase 1 — Command skeleton + demo preset + ephemeral scaffold
Goal:
forge tryexists, scaffolds the demo agent into a temp dir, loads it, prints the agent summary, and exits cleanly. No LLM call yet.forge-cli/cmd/try.gotryCmdcobra command. Flags:--keep,--provider,--model,--once <prompt>,--quiet,--audit,--yes. Positional optional first prompt.forge-cli/cmd/root.go(or whereverrootCmd.AddCommandlives)tryCmd. Optional hidden aliasdemo.forge-cli/cmd/init.goPresetfield to the init/scaffold options and aquickstartPreset()returning the demo agent definition (see below).scaffold()consumes the preset instead of wizard answers. Do not duplicatescaffold.forge-cli/internal/preset/quickstart.goagent_id: quickstart, resolved model,skills: [weather-or-keyless-equivalent],tools: [http_request, datetime_now, math_calculate], egress auto-derived, no channels, memory in-memory. Include a short system prompt describing the capabilities and the three suggested prompts.Demo preset requirements
mode: allowlist, domains auto-derived from the chosen skill (nodev-open).Verification
Verify keylessness of the hero skill (blocking): confirm the
weatherembedded skill needs no third-party API key at runtime. If it does, switch the preset's hero to a keyless path (Open-Meteohttps://api.open-meteo.comviahttp_request, or a keyless weather variant) and update the suggested prompts + egress domain accordingly. The hero interaction must never fail on a missing third-party key. (See #349.)Anti-patterns
scaffoldinto atry-specific function.Done when:
forge tryscaffolds, loads, summarizes, and cleans up, with--keepwriting to./forge-quickstart.Phase 2 — Model credential auto-resolution
Goal:
forge trypicks the fastest available model credential with no prompts when one exists, and offers a minimal picker only when nothing is available.forge-cli/cmd/try.goresolveTryProvider(ctx, flags)implementing the ordering policy below. Returns a resolved provider/model + a human label for the summary line.Resolution order
--provider/--modelflags, if set → use them.ANTHROPIC_API_KEY→OPENAI_API_KEY→GEMINI_API_KEY, in that preference) → use silently, printUsing <PROVIDER> from env.oauth.LoadCredentials()succeeds) → use OAuth/Responses, printUsing OpenAI (signed in).127.0.0.1:11434→ use with a small default model; print a one-line note that first response may be slow if the model must download. Do not silently block on a multi-GB pull; if the model is absent and no TTY, error with guidance.[Sign in with OpenAI (recommended)] [Paste an API key] [Use local Ollama]. OpenAI →runOAuthFlow(). Paste → masked input, held in memory (written to disk only under--keep).Respect existing routing: OAuth tokens use the Responses endpoint; API keys use Chat Completions. Never mix (existing invariant). Reuse
createProviderClient.Verification
Anti-patterns
.envmutation for the ephemeral run.Done when: each of the four credential sources drives a working reply, and the no-creds path gives an actionable message.
Phase 3 — In-process REPL driving the executor
Goal: A real conversation. Read stdin, run one agent turn per line through the existing executor, stream the assistant reply, maintain history in memory, exit on
/exit, Ctrl-D, or Ctrl-C.forge-cli/cmd/try.go--onceas a single turn then exit.forge-cli/runtime/runner.goforge runuses. Do not add a second executor.Behavior
agent ›prefix.--once <prompt>: run exactly one turn, print, exit with the turn's status code.Verification
Anti-patterns
forge serve.Done when: multi-turn chat works, tools actually execute, cancel and exit are clean.
Phase 4 — Visible-loop renderer
Goal: The differentiator. Render skill/tool/egress/guardrail events inline as the turn runs, plus one compact audit line per turn. This is what makes the first 60 seconds feel like Forge and not a generic chatbot.
forge-cli/internal/tryview/renderer.goforge-cli/cmd/try.go--quiet(hide loop) and--audit(show full NDJSON instead of the compact line).Event → line mapping
▸ skill <name>tool_execphase=start▸ tool <tool>(<short arg preview>)egress_allowed▸ egress <domain> ✓ allowedegress_blocked▸ egress <domain> ✗ blockedguardrail_checkdecision=blocked▸ guard <name> ✗ blockedtool_execphase=end◂ <short result preview>audit {…compact json…}line (suppressed by--quiet, expanded by--audit)#F97316for the▸/labels; muted grey for the audit line. Auto-detect no-color / non-TTY and degrade to plain text.Verification
Anti-patterns
forge-corefor rendering.forge-core.Done when: the hero prompt shows skill → tool → egress → answer inline,
--quietand--auditboth work, and non-TTY output is clean plain text.Phase 5 — First-run polish + graduation hook
Goal: Frame the delight and hand the user up the ladder to building their own.
forge-cli/cmd/try.go--once), print the graduation message.forge-cli/cmd/try.go--keep, the exit message offersforge try --keep(writes./forge-quickstart). If it was--keep, point at editingskills/,forge serve, andforge package.Copy rules: concise, problem-first, no em-dashes, orange accent only on the command tokens. Do not oversell.
Verification
Done when: banner, suggestions, and the correct graduation message all render.
Phase 6 — Docs: rebuild getting-started around
forge tryGoal: Make the first documented step a single command with a payoff, and move the production pipeline out of the "quick start."
docs/getting-started/quick-start.mdbrew install initializ/tap/forge && forge try. Then the hero transcript. Then a 4-rung ladder (below). Remove channels/build/deploy from this page.docs/getting-started/ship-to-production.mddocs/getting-started/installation.mdREADME.md(repo root)forge tryone-liner + transcript.forge.md§15 "How to create an agent"forge try; the pipeline below is for building your own.The ladder (put in quick-start.md):
forge try— talk to an agent, watch it use a tool.forge try --keepthenforge init— make it yours, edit aSKILL.md, add a skill.forge serve+ tail the audit log + add a guardrail and watch it block.forge package— egress-enforced container into your own cluster.Verification
Done when: quick-start's first block is
forge try, the pipeline lives on its own page, and no channel/build steps remain in the quick start.Phase 7 — Tests
forge-cli/cmd/try_test.gotesting, no testify. Cover: preset builds a valid config;resolveTryProviderordering (env > oauth > ollama > picker) with a mock TTY-absent path;--oncesingle-turn exit code; ephemeral temp dir is removed;--keepwrites to cwd.forge-cli/internal/tryview/renderer_test.goMock LLM/tool calls with
httptest.NewServerwhere a network hop is implied; do not hit real providers in unit tests.Verification
Done when: new tests pass and the whole workspace builds and vets clean.
7. Global anti-pattern checklist (applies to every phase)
forge try.forge build, container, K8s, or egress-file generation in thetrypath.try.forge-core.--keep).8. Definition of done (whole feature)
forge tryon a clean machine with an OpenAI login (or any model key in env) drops the user into a streaming chat with a working agent, the hero prompt shows skill → tool → egress → answer inline plus one audit line,--oncegives a one-line non-interactive demo,--keepgraduates the agent to./forge-quickstart, docs lead with the one-liner, andgo build ./... && go vet ./... && go test ./forge-cli/...are green.9. Deferred (name, do not build)
forge try --ui(browser variant reusingforge uichat).