Skip to content

feat(settings): add core extensions management#481

Open
sazora wants to merge 7 commits into
FerroxLabs:mainfrom
sazora:steve/core-extensions-settings
Open

feat(settings): add core extensions management#481
sazora wants to merge 7 commits into
FerroxLabs:mainfrom
sazora:steve/core-extensions-settings

Conversation

@sazora

@sazora sazora commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a first-class Settings > Extensions route, sidebar item, and settings-wrapper entry
  • include the Extensions management and Builder UI in core Wayland so installed user-data extensions remain manageable after app updates
  • expand extension bridge/IPC typing and native contribution resolution for packaged app use
  • route Extension Builder drafting through the existing resilient one-shot completion path instead of binding directly to the first configured provider

Why

The packaged app can preserve user-data extension folders across updates, but it cannot preserve local renderer/source patches. Without a core Extensions settings surface, updates can leave installed extensions on disk while removing the UI needed to inspect, enable, permission-review, or build them.

Verification

  • bunx vitest run tests/unit/process/bridge/extensionsBridge.builder.test.ts
  • bun run typecheck
  • bun run package
  • git diff --check
  • compiled renderer asset grep confirmed /settings/extensions, the sidebar Extensions entry, and Extension Builder UI are present

@github-actions github-actions Bot added area:desktop-ui Desktop UI area:core Wayland Core engine / backends area:mcp MCP servers & tools labels Jun 30, 2026
@sazora sazora force-pushed the steve/core-extensions-settings branch from 50885d9 to 28e95b2 Compare June 30, 2026 15:05
@github-actions github-actions Bot added area:packaging Signing, notarization, updater area:workflows Workflows & automation labels Jun 30, 2026
@sazora sazora force-pushed the steve/core-extensions-settings branch 4 times, most recently from 2e759a9 to dff6379 Compare June 30, 2026 20:54
@FerroxLabs

Copy link
Copy Markdown
Owner

[Overwatch ruling -- confirmed with Sean] This PR bundles three distinct features under one title. Decision: SPLIT into three PRs.

  1. Extensions settings surface (~2700 lines) -- APPROVED to land, on its own PR, rebased on current main (this PR is currently conflicting). We will review this slice first.
  2. User-acronyms / slash-commands subsystem (~700 lines) -- separate PR. It re-touches already-closed Feature: user-defined slash commands with MCP-backed recipes #28/Feature: first-class saved acronyms through the shared send pipeline #89 and needs its own justification.
  3. ProjectOperator MCP server (executes shell via exec, 120s timeout) -- separate PR + MANDATORY security audit before merge. It intersects the GHSA-8r7g approval/posture class we just hardened; it will not land without that audit.
    As an external author (@sazora), each slice gets an independent non-author cross-audit before merge. Please split; we will start with the extensions slice.

@FerroxLabs

Copy link
Copy Markdown
Owner

[Overwatch, with Sean] Deep-researched this. Decision: ACCEPT-WITH-CONSTRAINTS on the extensions-management slice.
The extension-management surface + the permission-review gate (safe auto-enables; moderate/dangerous stay disabled until approved; approval goes stale when manifest permissions change) are solid and close a real post-update orphaning gap — we'll take that slice (still split per the earlier note: management separate from user-acronyms and separate from the ProjectOperator MCP server).
Two constraints before merge:

  1. Keep the AI Builder / author-your-own flow behind an advanced-mode flag, off by default — our core user is the non-developer everyman, not an extension author.
  2. Hold any host-bridge settings tab to first-party-bundled ONLY until the bridge routes through our centralized approval/posture layer. A postMessage path to an installer/exec capability (e.g. triggerInstall) from a sandboxed iframe is the exact seam our trust model (GHSA-8r7g) governs; per-action capability routing needs to be centralized, not a hardcoded per-extension-name check in the renderer.
    Nice architecture overall — it's faithful to the VS Code contribution-point + sandboxed-webview model; the missing half is the trust/brokering layer, which the constraints above cover.

@sazora sazora force-pushed the steve/core-extensions-settings branch 2 times, most recently from fcfb843 to 3f70bd9 Compare July 2, 2026 16:32
@FerroxLabs

Copy link
Copy Markdown
Owner

Overwatch -> Main lane (free after #659): Sean wants this IN. Rebase steve/core-extensions-settings onto current ferrox/main (DIRTY), resolve conflicts, CI green, live-verify the core-extensions management settings actually work CDP :9333, self-cross-audit, flag needs:overwatch. source ~/.config/wl/main.env first.

@FerroxLabs

Copy link
Copy Markdown
Owner

Overwatch CORRECTION to Main (my earlier rebase-and-merge instruction was wrong — it contradicted the standing split ruling on this PR; disregard it). This PR does NOT merge as one bundle. Execute the already-decided SPLIT (ruled + confirmed with Sean):

LAND NOW (this is your task): extract ONLY the extensions-management slice (the ~2700-line extensions settings surface + the permission-review gate: safe auto-enables, moderate/dangerous stay disabled until approved, approval goes stale when manifest permissions change) into its OWN PR, rebased on current ferrox/main. Two mandatory constraints before it merges:

  1. Keep the AI Builder / author-your-own flow behind an advanced-mode flag, OFF by default (core user is the non-dev everyman, not an extension author).
  2. Host-bridge settings tab: first-party-bundled ONLY until the bridge routes through our centralized approval/posture layer. No postMessage path to an installer/exec capability (e.g. triggerInstall) until then.
    Then flag needs:overwatch — it gets an independent non-author cross-audit (external author) before merge.

DO NOT LAND in this batch: (2) the user-acronyms/slash-commands slice (~700 lines, re-touches closed #28/#89) = its own separate PR later; (3) the ProjectOperator MCP server (shell exec, 120s timeout) = separate PR with a MANDATORY security audit before merge (intersects the GHSA-8r7g approval/posture class). Leave those out of the slice you land now.

source ~/.config/wl/main.env first. If the split is impractical from this branch, cherry-pick the extensions-management files onto a fresh branch off main instead. Ask if the slice boundary is unclear.

@FerroxLabs

Copy link
Copy Markdown
Owner

Overwatch UPDATE (Sean: nothing parked, do it all right). Revised plan — still a SPLIT into three, but all three get done properly, none deferred:

SLICE 1 — extensions-management (Main, in progress): the ~2700-line surface + permission-review gate, on its own rebased PR, with the two constraints (AI Builder behind an advanced-mode flag off by default; host-bridge tab first-party-bundled only until it routes through centralized approval). Independent non-author cross-audit before merge. Continue.

SLICE 2 — user-acronyms / slash-commands (~700 lines): NOT parked. Split it onto its own PR too, rebased on main, with its own short justification (it re-touches closed #28/#89 — say what is new/why), and its own cross-audit. Main: produce this as the second split PR after the extensions slice lands, or hand it to a free lane — either way it gets done, not shelved.

SLICE 3 — ProjectOperator MCP (shell exec, 120s timeout): NOT deferred, but it does NOT reuse the raw exec bridge as-is. It gets a dedicated workstream: (a) a security design pass defining how its exec routes through our centralized approval/posture layer (the ACP permission flow + WorkspacePolicy trust model we just hardened in #657/#663), (b) rebuild to that design, (c) a scoped security audit + live-verify before merge. Overwatch is standing up the design pass now. Main: isolate the ProjectOperator files onto their own branch (do NOT merge, do NOT delete) so the security workstream has the original to work from, and keep them OUT of slices 1 and 2.

Net: three PRs, all pursued to done, the shell-exec one built to route through approval rather than bypass it. Ask if the slice boundaries are unclear.

@FerroxLabs

Copy link
Copy Markdown
Owner

Overwatch -> Main: UNBLOCK + simplified scope (supersedes my split instructions above).

I audited the actual current file set of this PR (33 files, 3595+/570-). The three-way split is already effectively done by the diff itself — stop trying to split, just rebase-and-land:

  • ProjectOperator MCP (slice 3): NOT in this diff. 0 of 33 files, 0 source hits — the author already descoped it. You do NOT isolate it from here. Its security-design spec is complete at ~/dev/wayland-worktrees/projectoperator-security-spec.md; its rebuild is a separate workstream once its source is located.
  • Standalone user-acronyms/slash-commands (slice 2): also NOT a separate thing here. The acronyms in this diff (IExtensionAcronym, getAcronyms, resolveExtensionAcronyms) are an EXTENSION CONTRIBUTION POINT of the extensions system — same class as settings-tabs, native-hooks, workspace-panels, file-preview-actions. They land WITH the extensions slice.
  • What IS in this diff = exactly slice 1: the extensions-management surface + permission-review gate + its contribution points. One coherent feature.

Your task, simplified: do NOT split anything out. Rebase this whole PR onto current ferrox/main. Because it is an external-author fork PR (sazora), recreate it as a FerroxLabs branch off main (cherry-pick / re-apply the 33 files), resolve conflicts, then:

  1. Constraint 1: AI Builder / author-your-own flow behind an advanced-mode flag, OFF by default.
  2. Constraint 2: host-bridge settings tab first-party-bundled ONLY — no postMessage path to an installer/exec capability (triggerInstall) until it routes through centralized approval/posture. If extensionsBridge.ts has a hardcoded per-extension-name renderer check for that, gate it off for now.
  3. CI green (lint, tsc, vitest).
  4. Live-verify CDP :9333 that extensions management + the permission-review gate actually work on a real profile.
  5. Self-cross-audit, then flag needs:overwatch for the independent non-author audit.

source ~/.config/wl/main.env and stamp instance:main on take. Short version: stop splitting, rebase-and-land the extensions slice with the two constraints.

@FerroxLabs

Copy link
Copy Markdown
Owner

Overwatch nudge: this PR is CONFLICTING against main and has not moved in ~2h. Rebase onto latest main (git fetch origin && git rebase origin/main), resolve, force-with-lease push, then flag needs:overwatch when green and I will cross-audit the extensions slice at head and merge on SHIP. This is slice 1 (extensions lands whole) — acronyms are an in-slice contribution point, not a separate PR.

@FerroxLabs

Copy link
Copy Markdown
Owner

Overwatch: still CONFLICTING and no movement in ~1h. This is deck-clearing we want landed before the next program spins up. Please either push the completed rebase (git fetch origin && git rebase origin/main, resolve, force-with-lease) or, if the conflict is gnarly, say so here and I will help scope it — recreating the branch fresh off current main is a valid reset if the history is tangled. Flag needs:overwatch when green and I cross-audit the extensions slice at head and merge.

@sazora sazora force-pushed the steve/core-extensions-settings branch from 3f70bd9 to 0ddafc2 Compare July 5, 2026 23:09
@sazora

sazora commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Rebased this branch onto current main and force-pushed the updated head.

What changed in this update:

  • rebuilt the existing 33-file extensions slice on top of current FerroxLabs/main
  • preserved the submitted PR content
  • added the follow-up local-safe builder hardening commit so builder scaffolds no longer emit host-bridge/settings-tab style local output

Verification I ran locally:

  • bun run typecheck
  • targeted Vitest slice for extensions/settings/builder: 9 files, 48 tests passed
  • mac local build completed successfully: out/mac-arm64/Wayland.app

Notes:

  • build completed with the existing optional hub/signal packaging warnings but produced a valid local app bundle
  • current PR head is now 0ddafc245

Flagging for re-review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core Wayland Core engine / backends area:desktop-ui Desktop UI area:mcp MCP servers & tools area:packaging Signing, notarization, updater area:workflows Workflows & automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants