Repository navigation
Conversation
|
One CI note for triage: the JS job fails on Everything attributable to the branch is green: the LOC allowlist entry now covers |
Wire UserSubagentRegistry::active_for to the existing ActivationScope
rule (crates/host-core/src/activation.rs): enabled records with a
Projects scope now stay out of sessions outside their projects, and
project-scoped records stay out of sessions with no project. Every
record scanned today still carries the default Global scope, so this
changes no behavior until scope assignment exists.
Deliberately NOT in this draft:
- set_scope persistence. user_skills set_scope is a documented stub
('scope is no longer persisted in capability files') while plugins
persist scope in capability state; subagents need the maintainer's
call between those two precedents before set_scope can be honest.
- Front-matter scope parsing, RPC surface, and the settings UI.
refs vastsa#1431
…stsa#1431) parse_record now reads a projects: [/abs/a, ...] front-matter key into the record's ActivationScope (Projects mode, normalized); its absence keeps the historical global visibility. render_document round-trips the list and drops it when the scope clears, following the fallbackModels pattern. CapabilityState stays boolean-only by design; the document is the record's home, and ADR 0112 deliberately has no project-level subagent directory, so front matter is the only persistence home that neither bends a shared schema nor invents a new state file. Still open on this branch: set_scope/update wiring that rewrites the document through render_document, RPC surface, settings UI. refs vastsa#1431
set_scope now normalizes the scope, rewrites the subagent document via render_document, and returns the rescanned record — hand-edited files and future RPC writes converge on one spelling, and active_for filters by the new scope on the next scan. Clearing the scope (Global default) drops the projects key from the document. Unknown ids stay a no-op. Remaining on this branch: honor UserSubagentInput.scope in create/update, expose an RPC surface, and a settings UI control. refs vastsa#1431
create applies a supplied ActivationScope (normalized) to the new record's document; update treats a supplied scope as set-or-clear and keeps the document's current scope when the input omits it, so RPC payloads and hand-edited files converge through the same front matter. The input field's protocol-compat comment and dead-code allowance are gone for good. Remaining on this branch: expose a setScope RPC surface and a settings UI control. refs vastsa#1431
Format-only fixups on the scope wiring (render_document hunk). Also verified this branch introduces no new clippy warnings: 5 on the branch, 5 on main, same set (the agents.setScope dispatch arm already existed — it pointed at the set_scope stub until 'implement set_scope through the document' made it real — so no RPC change is needed after all). refs vastsa#1431
The activation-scope wiring (vastsa#1431) pushed user_subagents.rs past the Rust 1000-LOC limit: scope parsing, document round-tripping, set_scope, and their tests share the existing parse/render/registry lifecycle. Exempting it here follows the user_skills.rs precedent (PR vastsa#515); the scope bookkeeping can be separated later if the maintainer prefers.
0b85306 to
21c1b38
Compare
feat(subagents): activation scope for user subagents (#1431)
Summary
User subagents today are visible to every session's delegation catalog; the only
containment is prose in the description (soft) or per-project disable overrides
(manual, inverse of what users need). Skills, MCP servers, and plugins have had
activation scopes since D192 (ADR 0056) — subagents are the last capability
family without one, and the spec, the IPC constant, the api bridge, and the
settings page payload have all referenced
agents.setScopealready. This PRcompletes that path:
active_forhonorsActivationScope.matches(project_path)— Global scopesfollow every session, Projects-scoped subagents stay out of unrelated
sessions and out of sessions with no project. Both runtime callers already
pass the session's project path (
session-launch.ts,launch-resolver.ts— "host-core owns the registry and the activation scope"), so the filter
engages on the real launch path with no further wiring.
projects: [/abs/a, ...]front-matterkey (absence = today's global behavior), parsed and round-tripped by
parse_record/render_documentfollowing thefallbackModelspattern.CapabilityStatestays boolean-only; ADR 0112's "no project-level subagentdirectory" is untouched — the scope rides the existing global documents.
set_scoperewrites the document throughrender_document; create/updatehonor
input.scope(None keeps the document's current value).agents.setScopedispatch arm already existedin
rpc/mod.rs— it pointed at theset_scopestub, which this PR makesreal. Code, spec (
06-host-rpc-protocol.md), and the existingprotocol.ts/api.ts/IPC bridge now agree without any of them moving.What is deliberately not here
AgentSubagentsPage(the save payload alreadypasses scope through; hand-edited front matter works today). Happy to add
it — with i18n ×9 — as a follow-up or in this PR, per your preference.
0322may collide with feat(settings): 支持配置会话标题生成 #1449's claim.
Proposed ADR (for maintainers to number)
Tests (all local, macOS arm64)
cargo test -p host-core825/825 (current HEAD), including new:visibility_honors_activation_scope,projects_scope_survives_record_document_round_trips,set_scope_rewrites_the_document_and_drives_visibility,create_and_update_honor_input_scope.pnpm typecheckclean.matches — host-core 800/800 (as of that base), agent-runtime 95 files/1312.
app.handshakeprotocolVersion=11) against a fixture
projects:-scoped subagent —agents.activereturns it only inside its named project, filters it forsessions with no project and outside the list, and keeps global ones
everywhere. Re-verified after each rebase.
refs #1431