refactor(tui): re-land FEAT-020 plugin command shapes on main - #5865
refactor(tui): re-land FEAT-020 plugin command shapes on main#5865aboimpinto wants to merge 10 commits into
Conversation
…es to command contract - CommandPluginContext: object-safe synchronous facet covering registry reads/mutations, async-bridged install/update/uninstall with sync receipts (D11), export, legacy scan, kimi managed import, and marketplace - Portable DTOs: PluginSummary/Detail/Diagnostic/McpServerDetail, mutation outcome+receipt, export receipt, legacy tool+scan, managed candidate+scan, marketplace catalog/candidate/add/state, suggestion - PLUGIN = 1 << 10 capability bit and one plugin envelope slot with with_plugin builder - Contract tests: object safety, field/variant closure, sync receipt outcomes, exact-hash mismatch, managed/marketplace portability, envelope transport, duplicate-slot rejection, bit stability - Contract boundary gate green; workspace compiles; fmt clean; 23/23 contract tests pass Generated with Claude Code Signed-off-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
…misleading receipts Code-review finding: trust/enable/disable/revoke_trust returned a PluginMutationReceipt with outcome always NoChange, which is semantically wrong (NoChange means 'already up to date' in the install/update path). The host registry returns Result<(), String>; the handler renders the action word from its own dispatch arm and re-reads detail for post-mutation state. Return Result<(), String> — the exact-minimum typed surface. Generated with Claude Code Signed-off-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
…tricted exposure - PluginAdapter implements CommandPluginContext against App: registry reads (summaries/detail/diagnostics/validation/suggest), registry mutations (trust/enable/disable/revoke with skill-cache + active-skill side effects), async-bridged install/update/uninstall with synchronous receipts (D11), export, legacy scan, kimi managed scan/install, marketplace state/add/remove/install (incl. builtin official catalog) - CommandContextBundle grows to eleven slots with plugin; contexts() exposes plugin only for PLUGIN capability - Portable conversion helpers: summary/detail/mcp server/diagnostic/marketplace diagnostic/mutation receipt/export receipt/legacy tool/marketplace candidate/catalog - kimi_import: scan_managed_plugins_portable wrapper; group modules made pub(crate); plugin_network_policy/run_async exposed - Adapter tests: host-data projection, registry mutation + suggest behavior, restricted exposure (3 tests) - Full TUI lib suite 11395/0; boundary gate green; fmt clean Generated with Claude Code Signed-off-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
…acet parity - mod.rs: portable plugins() dispatch consuming workspace/presentation/plugin facets; legacy shell builds bundle and delegates (Phase 6 replaces with from_contract) - render.rs: render_bundle_detail/escape helpers consume portable PluginDetail + presentation facet - legacy.rs: consumes PluginLegacyScan; kimi_import.rs: consumes PluginManagedScan; marketplace.rs: consumes PluginMarketplaceState with localized plan text - Presentation facet: key_to_plugin_message_id maps all 52 plugin keys; source_path carried for marketplace provenance - Contract: PluginSuggestion.state_label, PluginDetail.inventory_summary, PluginMarketplaceCatalog.source_path, reload() facet method - Tests: 18 plugin tests converted to the portable shell path; full parity preserved - Full TUI lib 11394/0; contract 23/23; boundary gates green Generated with Claude Code Signed-off-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
…nk both frontiers - PluginsCmd implements contract RegisterCommand<CommandResult> with exact WORKSPACE | PRESENTATION | PLUGIN; PluginsCommands group registers via ContextualCommand::from_contract - plugins_contextual destructures facets with safe missing-facet errors; transitional App shell now test-only - Public dispatch tests: exact capability set, undeclared facets absent, public seam dispatch, no-panic matrix (3 tests) - Remove plugins from PENDING_GROUPS and scripts/command-migration-topology.json frontier (same commit) - Migration fixture updated for six-group frontier; feat015 legacy-assertion test adds plugin to MIGRATED - All gates green: contract 23/23, TUI lib 11397/0, migration/boundary/CI fixtures + live gates, fmt, diff hygiene Generated with Claude Code Signed-off-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
- Fix clippy findings in FEAT-020 plugin files: identical if blocks (contract.rs), useless as_ref/map (marketplace.rs), useless format + redundant closure (render.rs), manual unwrap_or_default (mod.rs), collapsible if (contract tests) - Boy Scout: repair pre-existing lints outside FEAT-020 scope (computer-use linux.rs &PathBuf->&Path, config catalog tests contains()/type_complexity) - cargo clippy --workspace --all-targets --locked -- -D warnings exits 0 with zero warnings Generated with Claude Code Signed-off-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
rollback_hash_mismatch called crate::plugins::install::uninstall directly from the portable handler, a TUI-owned executable dependency that violates the D1 boundary and would break the FEAT-040 physical move. Add CommandPluginContext::uninstall_path(name, plugins_dir) - a file-level rollback removal with no registry resolution or skill side effects - and route the content-hash-mismatch rollback through it. The host adapter owns the crate::plugins call. Verified: contract 23/23, plugins group 18/18, plugin-scoped TUI suite 205/0, clippy -D warnings clean. Signed-off-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
Append PLUGIN after the capability identities already published by FEAT-021/022 and preserve current-main behavior for marketplace-backed suggestions, one-shot reload nudges, canonical review tokens, and shared marketplace document validation. Do not resurrect the retired computer-use builtin catalog. Signed-off-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
Scope symlink refusal tests to Unix, where symlinks are actually created, so Windows all-feature test compilation remains warning-free. Scan all visible trust-command candidates in the binary acceptance harness so a retained partial command cannot hide the complete canonical review token. Signed-off-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
|
I checked both failed jobs and pushed focused repairs in
Local post-fix checks pass:
A fresh full matrix is now running. The PR remains Draft. Paulo Aboim Pinto |
Replace the stale 0.0.0.0 warning expectation with an explicit non-loopback rejection check and verify that the error explains the enforced loopback-only boundary. Signed-off-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
|
The new matrix fixed the previous Ubuntu and Windows failures: both full test jobs are green. The remaining Mobile runtime smoke failure was another stale current-main expectation: the script still expected an insecure mobile server to default to I pushed
The complete smoke script now passes locally, 9/9, against the current debug binary. Shell syntax and diff hygiene also pass. A fresh matrix is starting, and the PR remains Draft. Paulo Aboim Pinto |
|
The fresh head matrix for Passed checks include Linux, macOS, Windows, lint, Safety gate, Mobile runtime smoke, Runtime integrations, OHOS cargo check, npm wrapper smoke, signed-off-by, link, version drift, and GitGuardian. The remaining skipped jobs are intentional workflow outcomes. The previously failing jobs are confirmed repaired:
The branch is clean and GitHub reports it mergeable. I have marked PR #5865 Ready for Review. Paulo Aboim Pinto |
No-Issue: FEAT-020 is tracked in umbrella #5316, which must remain open for the remaining command-decomposition work.
Summary
Re-lands FEAT-020 on current
main. The original implementation PR #5657 was merged intocodex/v0912-integration-20260823, notmain; neither its merge commitece99d5nor its feature head is an ancestor of current main.This forward-port preserves the original seven authored commits, adds one current-main reconciliation commit, and includes one focused Boy Scout test repair for failures reproduced on current
main. It:CommandPluginContextfacet and typed portable plugin/marketplace outcomes;PluginAdapter, keepingApp, registry, config, async/network, marketplace, Kimi, and legacy-tool machinery host-side;/plugintoContextualCommand::from_contractwith exactWORKSPACE | PRESENTATION | PLUGINauthority;Command capability unavailable: <facet>;pluginsfrom both migration-frontier representations, leaving[config, core, debug, session];/pluginnames, aliases, usage, rendering, trust/install/update/uninstall behavior, marketplace CRUD, and Kimi import behavior.Current-main reconciliation
This is intentionally not a blind replay of the old integration branch:
PLUGINis appended at1 << 12; current main has already publishedPROJECT = 1 << 10andSKILL_GROUP = 1 << 11through FEAT-021/022./plugin list.LoadedPlugin::review_tokenimplementation.Current-main CI blocker repairs
-D warningsfailure without weakening Unix coverage.0.0.0.0warning smoke check with explicit rejection and loopback-guidance assertions, matching the runtime's enforced security boundary.Validation
cargo fmt --all -- --check— PASScargo test -p codewhale-command-contract --lib --locked— 43/43 PASSpython3 scripts/test_check_command_crate_boundaries.py— 8/8 PASS; live boundary gate PASSpython3 scripts/test_check_command_migration_manifest.py— 56/56 PASS; live migration gate PASS-D warnings— PASSgit diff --check— PASSA single-process full TUI lib run exercised all tests: 11,536 passed; tests competing for the process-global runtime owner lock failed together, while every plugin/marketplace Runtime API failure relevant to this change passed independently with an isolated runtime directory. The authoritative CI uses one-process-per-test
cargo nextestand will remain the merge gate. This PR stays draft until the complete required matrix is green.Provenance
ece99d5aba8288024e9aac08e8e29c13ac2209bfPaulo Aboim Pinto