Files
waggle-os/docs/redesign-warm-hive/PR4-BUILD-PLAN.md
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

9.1 KiB
Raw Permalink Blame History

Warm-Hive PR4 — Marketplace + shared install store ("sync") — Build Plan

Source design: docs/design_handoff_waggle_app/SCREENS.md §09. Recon: docs/redesign-warm-hive/pr4-recon/ (5 docs). Branch: feature/warm-hive-pr4 (off main @ 876807ca). Status: plan — decisions §3 need founder ratification before feature code.


1. The design contract (screen 09)

Skills + connectors + MCP as one shelf, agent-searchable. Two variations, one store:

  • A — Browse & ask: centered agent-search bar → suggestion box (connector + skill + tool, each with a "why" + install) · "N in this workspace" count bar · All/Skills/Connectors/MCP filter · card grid (kind badge, name, desc, install count, Add).
  • B — Inline in chat: the same picker mid-conversation — offer a missing connector with a vault-aware approval ("token → your vault") → connected follow-up.
  • CRITICAL — "sync": one store powers grid + agent-pick + inline. Type-aware one-click: skill Add→Adding…→Added (instant) · connector Connect→Signing in…→Connected (~1.1s, token→vault) · MCP Enable→Enabling…→Enabled. Each fires a toast + updates the count bar. Installing in any view reflects in all.

2. Current state (grounded in recon — the engine exists; the gap is surface + a store)

Layer Reality today File anchors
Match engine searchCapabilities(need) → ranked candidates across native tools / skills / marketplace, each with matchReason ("why") + installAction. Reachable ONLY as the acquire_capability chat tool, which returns markdown and discards the structured proposal. packages/agent/src/capability-acquisition.ts:179; tool skill-tools.ts:406
Install backends (3, separate) skills = FS markdown reloaded into agentState.skills; connectors = vault credential connector:<id>; MCP = .mcp.json + live McpRuntime (PRO-gated, SecurityGate-scanned). No unified installed-set. routes/{skills,connectors,mcps}.ts; packages/marketplace/src/{db,installer}.ts
Install verbs skill/pkg POST /api/marketplace/install (PRO) · MCP POST /api/mcps/install (PRO) · connector POST /api/connectors/:id/connect (token→vault, ungated). All write the append-only install_audit (no workspace_id). routes/marketplace.ts:181, mcps.ts:189, connectors.ts:96
FE grid Phase-4B "Extend" surface: 6-facet rail, keyword search, vertical list of ExtensionCard, federates-at-read into local useState (discarded on unmount). Only marketplace skill/MCP pkgs install in-place; connectors/MCP = "Open in Hub" deep-links. Legacy tokens. MarketplaceApp.tsx (418 LOC), extend/ExtensionCard.tsx, lib/extension-catalog.ts
Variation B precursor CapabilityRequestCard (inline chat) — skill/marketplace only, own private phase state, no connector/vault approval, no shared state with grid. Approval channel is boolean-only (can't carry a token). chat-blocks/CapabilityRequestCard.tsx, capability-request-parser.ts, confirmation.ts

Net: the matching brain + the 3 install paths are done and tested. PR4 is (a) a shared FE install store the three surfaces subscribe to, (b) Variation A UI (agent-search bar + suggestion box + count bar + grid with type-aware verbs/micro-states), (c) one new route exposing the existing engine, (d) Variation B completion (connector/MCP + vault approval).

3. Decisions — RATIFIED (founder, 2026-06-16): D1 FE-derived global count · D2 collapse to 4 shelves · D3 in-place (OAuth→Hub fallback) · D4 sync = grid+pick+inline. D5D7 defaults stand.

# Decision Recommended (v1) Why / cost of the alternative
D1 "N in this workspace" count bar FE-derived global count from existing per-type list endpoints Real per-workspace tracking needs a new workspace_id migration across 3 backends + the OSS-excluded install_audit — large, and the substrate isn't workspace-partitioned. Honest label: "installed" not "in this workspace" if global.
D2 Facets Collapse to the design's 4: All / Skills / Connectors / MCP Matches screen 09 ("one simple shelf"). Agents/Models/Templates keep their dedicated hubs (already deep-links). Keeping the 6-domain superset diverges from the design.
D3 Connector/MCP in the grid In-place Connect/Enable reusing the real vault/runtime + SecurityGate; OAuth-only connectors fall back to the Connector Hub Design clearly wants in-place. Must NOT bypass security/OAuth gating. Token-paste connectors + MCP Enable work inline; OAuth-only can't finish inline.
D4 Sync scope Grid + agent-pick + inline-chat via an FE store; re-hydrate on nav so external Hub installs reconcile Refactoring ConnectorsApp/MCPHubApp/skills-center to also push to the store is a much bigger blast radius — defer.
D5 (default) Suggestion "why" engine's deterministic matchReason (free, honest, no model call) LLM-generated why is prettier but adds a model call + latency.
D6 (default) Card install count omit the social downloads count (local-single-user ≈ 0; honest-stats ethos) — show only a real Installed badge
D7 (default) PRO-gated items show as installable with an upsell on click (current behavior; moat: skills/MCP are the upgrade trigger)

4. Architecture

  • Shared store (the spine): new apps/web/src/providers/InstallProvider.tsx + useInstallStore() — an installed Map + installing Set keyed by extension-catalog namespaced ids; a type-aware install dispatcher (skill→installPack/skill; connector→connectConnector (vault); mcp→installMcp; pkg→installMarketplacePackage); a count selector; optimistic flip + reconcile (roll back on 403/SecurityGate, route to Upgrade/Approval). Hydrate from GET /api/skills, /connectors, /mcps, /marketplace/installed (no new read route for v1).
  • One new server route: POST /api/marketplace/agent-search {need} → wraps the existing searchCapabilities() (lift the dep assembly from local/index.ts:620), returns the structured proposal + a pickOnePerKind() grouping (connector+skill+tool). Mirrors GET /api/skills/suggestions. tsx-only → must tsc -p packages/server.
  • Reuse: extension-catalog.ts normalizers (flip installable:true for connector/mcp once the store can install them); CapabilityRequestCard for inline; warm components components/os/warm/* + warm tokens.

5. Phased plan (TDD; commit per phase; FE tsc -p apps/web/tsconfig.app.json + vitest each)

  • Phase A — shared install store (InstallProvider/useInstallStore): hydrate, type-aware dispatcher, count selector, optimistic+reconcile, toasts. Unit-tested in isolation. The spine everything else binds to.
  • Phase B — Variation A grid: ExtensionCard type-aware verbs (Add/Connect/Enable) + idle→in-progress→done micro-states reading the store; MarketplaceApp sources from the store, adds the count bar + 4-shelf filter (D2) + card grid + warm tokens; in-place connector/MCP (D3). Rewrite the 11 phase4b tests to the new contract.
  • Phase C — agent-search: POST /api/marketplace/agent-search (+ pickOnePerKind) wrapping searchCapabilities; the centered AskBar + suggestion box (connector/skill/tool, each "why" + install via the store) + example chips.
  • Phase D — Variation B inline: extend CapabilityRequest.kind to connector/mcp; vault-aware approval row (token→vault; approval channel stays boolean, FE calls connectConnector directly — no token on the approval channel); route installs through the shared store so chat ↔ grid ↔ count bar stay in sync; consolidate ApprovalGate/InlineApprovalCard.
  • Phase E — review + live smoke: adversarial review workflow; live smoke (grid install reflects in count bar + inline; agent-search returns real picks; 0 console errors).

6. Key risks (from recon)

  • 11 phase4b tests pin current testids + the {type,limit:30} call shape → Phase B rewrites them (expected, not collateral).
  • Optimistic flips must reconcile with server truth (install can 403 / SecurityGate-block after the flip) — across grid AND inline; count bar must not show a gate-rejected item.
  • Don't bypass Hub security/OAuth — in-place Connect/Enable reuse the real gated paths; OAuth-only → Hub fallback.
  • install_audit is OSS-excluded + append-only — never the source of truth for installed state; read per-type list endpoints.
  • Honest-stats / mind-isolation ethos — global count labeled honestly (D1); omit social download counts (D6).
  • Server routes run via tsx (not typechecked by npm run build) → explicit tsc -p packages/server gate on the new route.

7. Verification gates (per phase + final)

tsc -p apps/web/tsconfig.app.json 0 · tsc -p packages/server 0 (new route) · FE vitest green (incl. rewritten phase4b) · npm run lint · live smoke: install in grid → count bar + inline both reflect; agent-search returns connector+skill+tool with "why"; vault-aware inline approval; 0 console errors.