Isolate core runtime and add headless foundation#118
Conversation
|
Release-mode build regression found while testing local production install. Repro: This fails in release compile on this PR with:
I checked That release build succeeds, so this appears PR-introduced. Minimal local fix that allowed local production install to complete:
|
|
I hit a blocker while validating a local production build from PR #118 using the MCP CLI connected to the running app. Repro:
Expected: the selection is still visible in the bound context. Actual: readback comes back empty, with It looks like the selection is built for the mutation response, then not persisted into the bound app/tab state used by readback/export. I haven’t found the exact cause yet, so I’m not saying PR #118 introduced this. But I did hit it while testing a production build from this PR, and it blocks the rest of the MCP validation until we understand why selection writes don’t survive readback. |
|
For what it's worth, I've been working with this branch all day today and not had any problems. |
There was a problem hiding this comment.
Nice, I left some questions. Have not reviewed all of the code. At this point, I'm just trying to understand how it works and the direction you are considering for it.
...
logged an issue here with some thoughts as well:
#133
| Registration(name: "prompt", capability: .safeProfile) | ||
| ] | ||
|
|
||
| static let blockedCapabilities: [String: Capability] = [ |
There was a problem hiding this comment.
I’m trying to understand the intended layering here. Is HeadlessToolRegistry meant to own headless tool policy long term, or is the plan for it to eventually derive from a shared/core catalog?
I ask because there seem to be a few related policy vocabularies now: this registry, the app MCP capability map, and the Core session/capability types. As headless grows, it feels like app MCP/headless/CLI-facing surfaces may want to ask the same shared model: "for this runtime/profile, which tools are advertised, blocked, gated, or implemented?"
Maybe the eventual shape is a shared catalog entry with tool name, capabilities, profile availability, implementation availability, and safety contract, with each adapter filtering from that instead of maintaining its own list.
| try await assertError(fixture.server, frame: initializeRequest(id: 5), code: -32600) | ||
| } | ||
|
|
||
| func testRequestOnlyNotificationsAreIgnoredWithoutExecutingTools() async throws { |
There was a problem hiding this comment.
These lifecycle tests are useful. I’m curious whether we should also add a small set of public-contract tests for the headless tool surface itself.
For example, instead of only testing server lifecycle mechanics, maybe we could lock down:
- the exact default
tools/listsurface - broad categories that remain unavailable until intentionally supported
- the response shape for blocked/unavailable tools
- fail-closed behavior when permissions change but a tool still has no registered implementation
That would make the headless automation surface easier to evolve without accidentally changing what external callers can rely on.
Expert review — core isolation + headless foundationThis review covered the full merge-base diff ( Overall: this is unusually disciplined work for its size — the containment design in the headless host is genuinely fail-closed (per-component Blocking / major1. Codex 2. Guardrails pin commit objects that exist only on a side branch — squash/rebase merge or branch deletion breaks 3. Queued MCP tool calls now hard-fail on benign catalog churn 4. 5. 6. New suspension point in 7. Selection-revision recording dropped for direct UI snapshot commits 8. Headless: blocking stdin read on the cooperative pool (deadlock risk) 9. Headless: no SIGPIPE handling + exception-raising stdout writes 10. Main-actor perf regressions on prompt copy/estimate paths
Needs sign-off / minor (grouped)Projection & token accounting
Workspace persistence
App MCP runtime
Headless host
Build / guardrails / tooling
Verified sound (worth keeping as-is)
Review method: six parallel subsystem deep-dives over the merge-base diff at |
Summary
RepoPromptCore, with narrow macOS and app composition adaptersrepoprompt-headlesshost/CLI, packaging/install flows, direct-stdio MCP tools, and shared-runtime characterization fixturesValidation
make dev-formatmake dev-lintmake guardrailsmake conductor-selftestmake dev-swift-build PRODUCT=RepoPromptmake dev-swift-build PRODUCT=repoprompt-mcpmake dev-swift-build PRODUCT=repoprompt-headlessmake dev-testmake dev-headless-smokecommitandpushmodes, including staged/outgoing secret scansThe post-rebase validation above ran against
origin/mainat2544c83. A non-disruptive live-app smoke was attempted, but no CE app/MCP server was running; the app was intentionally not launched or disturbed.