feat(new-agent): create from a bundle URL + opt-in preview archetypes - #4030
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
📒 Files selected for processing (28)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
QA panel review — WARN
code-review-structural · head 3ad975dd5c2b · formal
⚠️ Coverage incomplete — this is not a clean pass. 1 of 5 review lane(s) did not complete a full pass this round:find_structural(structural pass unavailable or cut short: 16 of 28 features reviewed — feature cap reached: the 16 features with the most changed lines were reviewed, 12 were not (structuralmaxfeatures=16)). Findings from the lanes that ran stand, but a defect only the missing lanes would catch may be missed, so a PASS is capped at WARN. Where the brief below implies full coverage, this line supersedes it. The next push re-runs the full panel.
PR #4030 adds bundle-URL sourcing, held-archetype opt-in, and a ref parameter through the fleet stack. No findings were raised, so there was nothing to verify. The panel's four LLM finders (correctness, removed-behavior, cross-file, conventions) reviewed the full diff and found no defects; the protoPatch structural pass flagged 14 items in fleet_routes.py but every one targeted pre-existing fleet-management routes this PR does not modify. The changes are a clean extraction/refactor plus additive opt-in surface with extensive new test coverage. No verification was needed and none was performed — the empty pass is expected, not a gap.
No findings from the lanes that ran — coverage was incomplete (see above), so this is not a clean review.
findings JSON (machine-readable)
[]Settings > New agent gains a third source, "From a bundle URL": paste a bundle's git URL (+ optional ref, or a GitHub /tree/<ref> link), see a read-only peek of what it installs (plugins + refs, built-ins, config prompts, capability contract) and an explicit trust ack for a non-official source, then run the same set-up dialog the catalog cards use. Create posts `bundle` + `ref`. Server: - GET /api/archetypes/from-url?url=&ref= (validated git URL + ref; reuses ops.plugins.peek_bundle; reports source trust) - GET /api/archetypes?include_held=1 serves the catalog's held entries, flagged held: true (never by default); /preview resolves them - POST /api/fleet accepts `ref`, threaded through ops.fleet.create -> manager.create(bundle_ref) -> `plugin install --ref`, recorded in workspace.yaml Console: held archetypes appear only behind Advanced > "Show preview archetypes" (per-console localStorage pref), badged "Preview". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3ad975d to
6f929e7
Compare
|
Merging 6f929e7. I rebased this onto #4029, which was merged first. The conflicts in Review: the QA panel gave WARN with 0 findings at 3ad975d. Coverage was incomplete: the structural lane reached 16 of 28 features, and the four LLM lanes reviewed the full diff. I hand-checked the new trust surface: 🤖 Generated with Claude Code |
There was a problem hiding this comment.
QA panel review — WARN
code-review-structural · head 6f929e7bfbde · formal
⚠️ Coverage incomplete — this is not a clean pass. 1 of 5 review lane(s) did not complete a full pass this round:find_structural(structural pass unavailable or cut short: 16 of 28 features reviewed — feature cap reached: the 16 features with the most changed lines were reviewed, 12 were not (structuralmaxfeatures=16)). Findings from the lanes that ran stand, but a defect only the missing lanes would catch may be missed, so a PASS is capped at WARN. Where the brief below implies full coverage, this line supersedes it. The next push re-runs the full panel.
The panel's brief could not be read from this round's report (no delimited brief block). The findings below are unaffected.
Findings
| Severity | Location | Finding | Verified | |
|---|---|---|---|---|
| 🟡 | minor | operator_api/fleet_routes.py:369 |
The new _archetype_from_url endpoint interpolates the raw exception string into the 502 response body, leaking internal paths, resolved DNS names, or proxy con… | confirmed |
findings JSON (machine-readable)
[
{
"file": "operator_api/fleet_routes.py",
"line": 369,
"severity": "minor",
"category": "security",
"claim": "The new _archetype_from_url endpoint interpolates the raw exception string into the 502 response body, leaking internal paths, resolved DNS names, or proxy configuration to the client.",
"evidence": "f\"could not read bundle {clean_url}: {exc}\"",
"source": "protopatch",
"verdict": "confirmed",
"note": "Read file at head 6f929e7: line 368 contains exactly `raise HTTPException(502, f\"could not read bundle {clean_url}: {exc}\")`. The `exc` is the raw exception from `plugin_ops.peek_bundle()` (a network/git operation); its `str()` will include internal paths, hostnames, or proxy details in the response body.",
"line_original": 368,
"line_corrected": true
}
]
Problem
Settings ▸ New agent only offered the catalog cards (Basic, Cowork, Engineer, …) and "From a snapshot". The catalog's
heldarchetypes were invisible, and there was no way to create an agent from a bundle that isn't in the catalog.What changed
From a bundle URL (third source)
/tree/<ref>,/releases/tag/<ref>or/commit/<sha>link folds to repo + ref. The URL is checked in the console (lib/bundleUrl.ts) and again on the server.GET /api/archetypes/from-url?url=&ref=. It's a read-only peek that reusesops.plugins.peek_bundle. It returns the bundle'sarchetype:block as an/api/archetypesrow, the same bundle peek/previewserves, andtrusted/sourcefrom the ADR 0071 D3 trust predicate.MemberCard), config prompts, MCP servers and secrets, and the capability contract. A source that isn't official or acked needs an explicit "I trust this repository" before Next. The warning text is the plugin-install consent copy, now shared asRunsCodeWarninginTrustAckDialog.tsx.config_inputsstill block Create. Create postsbundle+ref.POST /api/fleetnow acceptsref. It's validated with the installer's ref check, then passed throughops.fleet.create→manager.create(bundle_ref=)→plugin install --ref, and recorded asbundle_refinworkspace.yaml.Preview (held) archetypes, opt-in only
GET /api/archetypes?include_held=1adds the catalog'sheldentries, each markedheld: true. Without the flag they never appear./api/archetypes/{id}/previewresolves held ids.lib/previewArchetypesPref.ts; every access is wrapped in try/catch, with an in-memory fallback). When it's on, held cards appear under Advanced with a DS Preview badge. The Setup Wizard doesn't offer the switch, so held archetypes never show there.Tests
tests/test_fleet_routes.pycovers held hidden/opt-in/dedupe/preview, from-url validation (9 bad URLs, bad ref), shaping, trust, 502, and createrefforwarding/rejection.tests/test_workspaces.pycoversbundle_ref→ install +workspace.yaml, and--refreaching the CLI. Full suite: 11917 passed.NewAgentPanel.test.tscovers URL flow, trust gating, create payload, and preview-switch persistence. AlsobundleUrl.test.ts,previewArchetypesPref.test.ts,archetypeFlow.test.ts. Full suite: 3327 passed.fleet.spec.ts(URL flow end to end, unreadable repo, Preview badge + reload persistence) andnew-agent.mobile.spec.ts(URL flow fits a phone). Both specs: 46 passed.ruff check .✓ ·lint-imports(4 kept) ✓ · checked against the realanalyst-archetype@v0.1.0on an isolated instance.Notes / open questions
POST /api/fleetstill does not enforce the plugin trust gate server-side. Consent happens in the console step, same as catalog creates today. Should the server require an ack for non-official bundle URLs (and the CLI too)?🤖 Generated with Claude Code
Summary by CodeRabbit