Skip to content

feat(new-agent): create from a bundle URL + opt-in preview archetypes - #4030

Merged
mabry1985 merged 2 commits into
mainfrom
feat/new-agent-from-bundle-url
Oct 4, 2026
Merged

mabry1985 merged 2 commits into
mainfrom
feat/new-agent-from-bundle-url

Conversation

@mabry1985

@mabry1985 mabry1985 commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

Problem

Settings ▸ New agent only offered the catalog cards (Basic, Cowork, Engineer, …) and "From a snapshot". The catalog's held archetypes 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)

  • New "From a bundle URL" tab: repository URL + optional ref. A GitHub /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.
  • Look up calls the new GET /api/archetypes/from-url?url=&ref=. It's a read-only peek that reuses ops.plugins.peek_bundle. It returns the bundle's archetype: block as an /api/archetypes row, the same bundle peek /preview serves, and trusted / source from the ADR 0071 D3 trust predicate.
  • Preview + trust step: shows the bundle's description and what it installs: each plugin with its ref, the built-ins it turns on (reusing 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 as RunsCodeWarning in TrustAckDialog.tsx.
  • Next opens the same set-up dialog as the catalog cards, with its own flow state. Required config_inputs still block Create. Create posts bundle + ref.
  • POST /api/fleet now accepts ref. It's validated with the installer's ref check, then passed through ops.fleet.create → manager.create(bundle_ref=) → plugin install --ref, and recorded as bundle_ref in workspace.yaml.

Preview (held) archetypes, opt-in only

  • GET /api/archetypes?include_held=1 adds the catalog's held entries, each marked held: true. Without the flag they never appear. /api/archetypes/{id}/preview resolves held ids.
  • In the picker, Advanced has a "Show preview archetypes" switch. It is saved per console in localStorage (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

  • Python: tests/test_fleet_routes.py covers held hidden/opt-in/dedupe/preview, from-url validation (9 bad URLs, bad ref), shaping, trust, 502, and create ref forwarding/rejection. tests/test_workspaces.py covers bundle_ref → install + workspace.yaml, and --ref reaching the CLI. Full suite: 11917 passed.
  • Vitest: NewAgentPanel.test.ts covers URL flow, trust gating, create payload, and preview-switch persistence. Also bundleUrl.test.ts, previewArchetypesPref.test.ts, archetypeFlow.test.ts. Full suite: 3327 passed.
  • Playwright: fleet.spec.ts (URL flow end to end, unreadable repo, Preview badge + reload persistence) and new-agent.mobile.spec.ts (URL flow fits a phone). Both specs: 46 passed.
  • ruff check . ✓ · lint-imports (4 kept) ✓ · checked against the real analyst-archetype@v0.1.0 on an isolated instance.

Notes / open questions

  • POST /api/fleet still 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)?
  • The member ref shown in the preview is the one the manifest declares. For floor pins, the install may resolve a newer compatible tag.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Create an agent from a bundle URL, optionally pinned to a branch, tag, or commit. Preview its contents and setup requirements before proceeding; untrusted sources require confirmation.
    • Enable preview archetypes in Advanced settings. They’re hidden by default, marked with a Preview badge when shown, and your preference is saved.
  • Documentation
    • Updated operator API documentation with bundle-preview and preview-archetype options.

@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

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
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: acc73ba0-d6b6-4b1a-8dde-439263089e8e
📥 Commits

Reviewing files that changed from the base of the PR and between 1b5fd72 and 6f929e7.

📒 Files selected for processing (28)
  • apps/web/e2e/fixtures.mjs
  • apps/web/e2e/fleet.spec.ts
  • apps/web/e2e/mock-server.mjs
  • apps/web/e2e/new-agent.mobile.spec.ts
  • apps/web/src/app/theme.css
  • apps/web/src/lib/api/fleet.ts
  • apps/web/src/lib/archetypeFlow.test.ts
  • apps/web/src/lib/archetypeFlow.ts
  • apps/web/src/lib/bundleUrl.test.ts
  • apps/web/src/lib/bundleUrl.ts
  • apps/web/src/lib/previewArchetypesPref.test.ts
  • apps/web/src/lib/previewArchetypesPref.ts
  • apps/web/src/lib/queries.ts
  • apps/web/src/lib/types.ts
  • apps/web/src/plugins/TrustAckDialog.tsx
  • apps/web/src/settings/BundleUrlSource.tsx
  • apps/web/src/settings/NewAgentPanel.tsx
  • apps/web/src/settings/__tests__/NewAgentPanel.test.ts
  • apps/web/src/settings/bundleUrl.css
  • apps/web/src/setup/ArchetypePicker.tsx
  • apps/web/src/setup/ArchetypePreviewDialog.tsx
  • changelog.d/4030.added.md
  • docs/reference/operator-api.md
  • graph/workspaces/manager.py
  • operator_api/fleet_routes.py
  • ops/fleet.py
  • tests/test_fleet_routes.py
  • tests/test_workspaces.py
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

mabry1985 added a commit that referenced this pull request Oct 4, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@protoreview protoreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
[]

mabry1985 and others added 2 commits October 4, 2026 10:14
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>
@mabry1985
mabry1985 force-pushed the feat/new-agent-from-bundle-url branch from 3ad975d to 6f929e7 Compare October 4, 2026 17:14
@mabry1985

Copy link
Copy Markdown
Member Author

Merging 6f929e7. I rebased this onto #4029, which was merged first. The conflicts in _install_bundle_into were resolved by keeping #4029's error reporting and adding the ref parameter; the test additions are kept from both PRs.

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: ref passes installer._validate_ref on both preview and create, so no .. and nothing that reaches git as an option. Argv is a list with no shell. The URL flow shows the source-trust check and the bundle's contents before Create. Preview archetypes are opt-in. 99 workspace tests pass, and CI is green.

🤖 Generated with Claude Code

@protoreview protoreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
  }
]

@mabry1985
mabry1985 merged commit 69cd6b0 into main Oct 4, 2026
22 of 23 checks passed
@mabry1985
mabry1985 deleted the feat/new-agent-from-bundle-url branch October 4, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant