refactor(workspaces): standardize launcher injection (AI-config + MCP/persona/skills + commit)#245
Merged
Conversation
setup_git_excludes only guarded .claude/settings.local.json and .codex/auth.json, but OpenAlice's per-workspace Codex config (writeCodexConfig) writes the API key to .codex/env.json (OPENALICE_WORKSPACE_KEY) and a possibly-private base_url to .codex/config.toml — neither was excluded. auto-quant workspaces are clones of the public TraderAlice/Auto-Quant on a pushable autoresearch/<tag> branch; the bootstrap comment explicitly says the excludes exist to keep secrets "out of any push to upstream Auto-Quant" — but it missed the file that actually holds the key. A user who set a custom Codex provider on an auto-quant workspace and pushed the branch would have leaked their key. Add both files to the default block in _common.sh:setup_git_excludes — one place, covers chat/finance/auto-quant and any future template. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per-workspace AI-provider config (key/endpoint/model) was written by four CLI-specific functions living in the webui route file (readClaudeConfig/writeClaudeConfig/readCodexConfig/writeCodexConfig), dispatched ad-hoc from the route handlers. That put per-CLI file-format logic in the wrong layer and duplicated the dispatch. Standardize the contract, keep the per-CLI format behind it: - New WorkspaceAiCred (superset shape: authMode is Claude-only, wireApi Codex-only) + optional writeAiConfig/readAiConfig on the CliAdapter interface (cli-adapter.ts). - Move the four function bodies verbatim into claudeAdapter / codexAdapter (+ the tomlString helper and path/env-name constants). shell has none. - Thin GET/PUT /:id/agent-config to dispatch via svc.adapters.get(agent) — response shape unchanged. Behavior-preserving: a golden spec (ai-config.spec.ts) asserts the exact bytes the pre-move writers produced for both CLIs across the full input matrix (x-api-key / bearer / model-only / reset / chat / responses) plus read round-trips. tsc --noEmit clean; full suite 1713 passed. This is the seam a future config-push (apply-profile-to-workspaces) will build on. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ial commit Each template's bootstrap.sh hand-rolled its own context injection (MCP config, persona, skills) and initial commit. Standardize: the launcher now injects and commits uniformly, gated by template.json manifest flags; bootstrap.sh shrinks to harness-unique materialization. - Manifest flags injectMcp / injectPersona / bundledSkills (defaults preserve each template's behavior): chat = all three, finance = mcp + persona, auto-quant = none. - context-injector.ts: launcher writes the standard .mcp.json (URL placeholder kept for spawn-time resolution), composes Alice persona + the template's CLAUDE.md into CLAUDE.md/AGENTS.md, and copies bundled skills from default/skills/ into both discovery paths. Byte-identical to the old _common.sh bash (golden spec asserts it). - workspace-creator.ts: after bootstrap → inject → commit. The launcher owns the initial commit for EVERY template (no launcherCommits exemption); failure cleans up the dir and returns injection_failed. - "Harness rule": every workspace is a fresh-git repo with one clean initial commit, no inherited history, no pushable remote. auto-quant conforms by scrubbing its clone (rm -rf .git && git init), which also removes the public-remote key-leak vector Phase 0 hardened. - Moved the scan-value-chain skill (chat-bundled stopgap) → default/skills/. - Deleted the duplicated template files/mcp.json; removed the now-dead _common.sh helpers (write_mcp_config / compose_persona_claude_md / commit_initial). Verified: tsc --noEmit clean; injector golden (MCP bytes + persona composition + skills into both paths); e2e (real bootstrap → inject → commit = one clean launcher commit, clean tree); full suite 1718 passed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Per-template
bootstrap.shscripts each hand-rolled their own context injection and initial commit, and per-CLI AI-config write logic lived in the webui routes. This standardizes both behind the launcher, so what gets injected is uniform and centrally owned — and hardens a credential leak along the way. Three independent, behavior-preserving commits:53a0185security:setup_git_excludesonly guarded.claude/settings.local.json+.codex/auth.json, but per-workspace Codex config writes the API key to.codex/env.jsonand a base_url to.codex/config.toml— neither excluded. auto-quant workspaces were clones of the public Auto-Quant repo on a pushable branch, so a custom Codex provider + push would leak the key. Added both to the default exclude block.7420909AI-config unification: moved the four CLI-specific config writers out ofwebui/routes/workspaces.tsintoCliAdapter.writeAiConfig/readAiConfig(claude/codex), behind a sharedWorkspaceAiCred. Routes now dispatch viasvc.adapters; response shape unchanged. This is the seam a future config-push builds on.286ab83launcher-owned injection + uniform commit:context-injector.tswrites the standard.mcp.json(placeholder kept for spawn-time URL resolution), composes Alice persona + the template's CLAUDE.md into CLAUDE.md/AGENTS.md, and copies bundled skills fromdefault/skills/into both discovery paths — gated by newtemplate.jsonflags (injectMcp/injectPersona/bundledSkills). The launcher now makes the initial commit for every template (no per-template exemption). "Harness rule": every workspace is a fresh-git repo with one clean initial commit, no inherited history, no pushable remote — auto-quant conforms by scrubbing its clone (rm -rf .git && git init), which also removes the Phase-0 leak's remaining vector.bootstrap.sh shrinks to harness-unique materialization; the duplicated template
files/mcp.jsonand the now-dead_common.shhelpers are removed.Test plan
tsc --noEmitcleanbootstrap → inject → commityields one cleanlauncher@localcommit, clean tree; auto-quant's clone history + remote are scrubbed/mcpand discoversscan-value-chain(standard CLI discovery; files verified in place)Boundary touch
Touches AI-provider credential handling (per-workspace agent config moved into adapters) and a security hardening (Codex key git-excludes). No broker/trading code, no migrations.
🤖 Generated with Claude Code