paseo-room 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -54,7 +54,7 @@ interactive stdin/stdout/stderr, and targets exactly one selected agent and role
54
54
  | `--room-home <path>` | `~/.paseo-room` | Where role homes are written. |
55
55
  | `--codex-home <path>` | `~/.codex` | Source Codex configuration. |
56
56
  | `--claude-home <path>` | `~/.claude` | Source Claude Code configuration. |
57
- | `--pi-home <path>` | `~/.pi/agent` | Source Pi configuration and global adapter package. |
57
+ | `--pi-home <path>` | `~/.pi/agent` | Source Pi configuration and the packages `--pi-extension` selects. |
58
58
  | `--codex-bin`, `--claude-bin`, `--pi-bin`, `--paseo-bin` | found on `PATH` | Executable overrides. |
59
59
 
60
60
  Environment equivalents: `PASEO_ROOM_HOME`, `CODEX_HOME`, `CLAUDE_CONFIG_DIR`, `PASEO_HOME`,
@@ -71,7 +71,9 @@ starts, its exit code is preserved; a signal is returned using the conventional
71
71
 
72
72
  - Node 22 or newer, macOS or Linux.
73
73
  - A running Paseo daemon with CLI and daemon on the same version. Codex requires
74
- **0.8.0-beta.1 or newer**; any selection containing Claude or Pi requires **0.8.0 or newer**.
74
+ **0.8.0-beta.1 or newer**; any selection containing Claude requires **0.8.0 or newer**, and
75
+ any selection containing Pi **0.11.1 or newer**, the first Paseo that hands a Pi seat its tools
76
+ through Pi's built-in MCP extension.
75
77
  Claude also requires Paseo plugins to be enabled explicitly: the generated trusted server plugin
76
78
  is the strong contract carrier, and `paseo-room` never enables plugins for you. The plugin
77
79
  requires Paseo `>=0.8.0` and has no upper bound. `paseo-room` checks compatibility before
@@ -84,12 +86,9 @@ starts, its exit code is preserved; a signal is returned using the conventional
84
86
  pins both `CLAUDE_CONFIG_DIR` and `CLAUDE_SECURESTORAGE_CONFIG_DIR` per role. It does not
85
87
  query Keychain state, and reports older-runtime Keychain isolation as unverifiable. See
86
88
  Anthropic's [credential-management reference](https://code.claude.com/docs/en/authentication#credential-management).
87
- - An initialised Pi home (`~/.pi/agent`) and an operator-installed global
88
- `pi-mcp-adapter` package under its `npm/node_modules` (`pi install npm:pi-mcp-adapter`). The
89
- package version is diagnostic, not a compatibility constraint. Pi 1.0's built-in MCP extension
90
- does not replace it: Paseo gives a Pi seat its MCP servers only through the adapter, which it
91
- recognises by name and configures with the adapter's own `--mcp-config` flag. The room never
92
- installs or upgrades Pi or the adapter; setup stops with that install command instead.
89
+ - An initialised Pi home (`~/.pi/agent`) and Pi 1.1.0 or newer. Seats use Pi's built-in `mcp`
90
+ and `codemode` extensions; `pi-mcp-adapter` is not needed, and the room never loads it. The
91
+ room never installs or upgrades Pi.
93
92
 
94
93
  ## What gets created
95
94
 
@@ -175,10 +174,9 @@ configuration.
175
174
  Pi role homes deliberately do not link `extensions`, `npm`, `git`, `trust.json`, runtime
176
175
  caches or session state. Their copied `settings.json` removes `packages` and `extensions`,
177
176
  so startup cannot install configured packages or discover unrelated configured extensions.
178
- The intended adapter remains in the operator's Pi package store and is loaded by canonical
179
- path. Every Pi provider pins `PI_MCP_CONFIG_MODE=exclusive`, making the role home's linked
180
- `mcp.json` the adapter's only configuration source and excluding generic global and project
181
- MCP config discovery.
177
+ Pi's built-in MCP extension reads only the role home's linked `mcp.json` and, for a trusted
178
+ project, its `.pi/mcp.json`; seats run with `--no-approve`, so no project is trusted and the
179
+ role home's file is the only configuration source besides the servers Paseo registers.
182
180
 
183
181
  ### Role authentication diagnostics
184
182
 
@@ -218,7 +216,7 @@ a minimal interactive login session in that role's home, isolated from the calle
218
216
  `--no-extensions --no-approve --append-system-prompt ''` and visibly asks you to run `/login`.
219
217
  The explicit empty append override suppresses discovery of the generated role
220
218
  `APPEND_SYSTEM.md`, including its runtime capsule and role instructions. This direct launch
221
- does not load `pi-mcp-adapter`, Paseo's integration extension, or the room-equivalent provider
219
+ does not load Pi's MCP extension, Paseo's integration extension, or the room-equivalent provider
222
220
  argv. No login path reads, copies, links, replaces, validates, or deletes a credential store.
223
221
 
224
222
  Codex diagnostics recognize an explicit `cli_auth_credentials_store` of `file`, `ephemeral`,
@@ -288,7 +286,7 @@ but what the model actually reads is not proven, and `CLAUDE.md` is what covers
288
286
  Pi providers use a strict command tail:
289
287
 
290
288
  ```text
291
- --no-extensions --extension <canonical pi-mcp-adapter entry>
289
+ --no-extensions --extension builtin:mcp --extension builtin:codemode
292
290
  [--extension <canonical entry of each selected package>] --no-approve
293
291
  --append-system-prompt <role APPEND_SYSTEM.md>
294
292
  ```
@@ -301,8 +299,8 @@ paseo-room setup --agent pi --pi-extension pi-blackbytes --pi-extension pi-provi
301
299
  ```
302
300
 
303
301
  Roles default to `supervisor,lead`; Peer gets an extension only when named, with a warning.
304
- Packages load only from your Pi home's `npm/node_modules`, with the same containment checks
305
- as the adapter; package prompts, skills and themes are not loaded. A package that is not
302
+ Packages load only from your Pi home's `npm/node_modules`, and every declared entry must
303
+ resolve inside the package; package prompts, skills and themes are not loaded. A package that is not
306
304
  installed is a warning with its `pi install npm:<package>` command and the seat starts without
307
305
  it; the room never installs one. Selecting a package states that it opens no second
308
306
  multi-agent path in a seat (`pi-blackbytes` 3.1.0 turns its sub-agents off when
@@ -312,15 +310,16 @@ flag removes the extensions and warns which ones. See
312
310
 
313
311
  This is Paseo's core `pi` provider, not an OMP provider or compatibility layer.
314
312
  Paseo appends and owns its own generated temporary integration extension; `paseo-room` does
315
- not resolve, create or include it. Before planning any writes, the room validates the exact
316
- global package identity and canonical entry containment, then runs one bounded offline Pi RPC
317
- `get_commands` probe that loads the adapter and every selected extension, with
318
- `PI_MCP_CONFIG_MODE=exclusive`, `PASEO_ROOM_ROLE=lead`, `HOME` set to a fresh temporary working
319
- directory that is removed afterwards, and `PI_CODING_AGENT_DIR` an empty directory inside it. This prevents adapter startup from selecting operator-global or caller
320
- project MCP configs during the probe. The correlated response must
321
- attribute `/mcp` to `source: "extension"` at that same canonical path. Missing, malformed,
322
- path-escaped or wrongly attributed adapters fail closed. The probe and setup do not write the
323
- operator or planned role homes.
313
+ not resolve, create or include it. Paseo registers the seat's MCP servers through that extension
314
+ with `pi.registerMcpServer`, but only after it finds a `/mcp` command from `builtin:mcp`. Their
315
+ tools default to `codemode` exposure, which is why `builtin:codemode` loads too: without it a
316
+ seat would hold Paseo's tools and have no way to call them. Before planning any writes, the room
317
+ runs one bounded offline Pi RPC `get_commands` probe that loads the same built-in extensions and
318
+ every selected extension, with `PASEO_ROOM_ROLE=lead`, `HOME` set to a fresh temporary working
319
+ directory that is removed afterwards, and `PI_CODING_AGENT_DIR` an empty directory inside it, so
320
+ no operator or caller-project MCP configuration is read. The correlated response must attribute
321
+ exactly one `/mcp` to `source: "extension"` at `builtin:mcp`; anything else fails closed. The
322
+ probe and setup do not write the operator or planned role homes.
324
323
 
325
324
  Each seat combines generated agent configuration with Paseo provider pins. Provider fields are
326
325
  still required where Paseo launch state outranks the agent's own configuration:
@@ -333,7 +332,7 @@ still required where Paseo launch state outranks the agent's own configuration:
333
332
  | `disableWorkflows: true` + `CLAUDE_CODE_DISABLE_WORKFLOWS=1` | Claude | Disables dynamic workflows through every entry point, beyond denying the `Workflow` tool. |
334
333
  | `crossSessionInbound: "refuse"` | Claude | Prevents another Claude session from injecting a turn into a room seat. |
335
334
  | `disableClaudeAiConnectors: true` + `ENABLE_CLAUDEAI_MCP_SERVERS=0` | Claude | Keeps the signed-in account's claude.ai connectors (Canva, Claude Docs, …) out of every seat. They bypass the room's MCP check and reach Peer, and one that needs authorising makes each seat ask you to connect it. Your own Claude Code sessions keep them. |
336
- | strict argv + `PI_MCP_CONFIG_MODE=exclusive` + additive runtime capsule | Pi | Disables extension discovery and project trust, and restricts adapter config to the role-home `mcp.json`; forbids a second agent control plane without claiming sandboxing. |
335
+ | strict argv + additive runtime capsule | Pi | Disables extension discovery and project trust, so Pi's built-in MCP reads only the role-home `mcp.json`; forbids a second agent control plane without claiming sandboxing. |
337
336
  | `paseoTools: {enabled}` | all | Room tools for Supervisor and Lead, never for Peer. |
338
337
 
339
338
  `verify` compares each provider's `command`, `env`, `paseoTools` and pins against what the
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ var init_package = __esm({
15
15
  "package.json"() {
16
16
  package_default = {
17
17
  name: "paseo-room",
18
- version: "0.18.0",
18
+ version: "0.19.0",
19
19
  description: "One CLI that configures Codex, Claude Code, and Pi role homes in $HOME and registers them with your local Paseo daemon.",
20
20
  keywords: [
21
21
  "paseo",
@@ -1643,7 +1643,9 @@ function parsePiExtensionSpec(spec) {
1643
1643
  if (rest.length > 0 || !NPM_NAME.test(name)) {
1644
1644
  throw new Error(`Not a Pi package selection: ${spec}. Use <npm package>[=<role>,<role>].`);
1645
1645
  }
1646
- if (name === PACKAGE_NAME) throw new Error(`${PACKAGE_NAME} is always loaded and cannot be selected.`);
1646
+ if (name === ADAPTER_PACKAGE) {
1647
+ throw new Error(`${ADAPTER_PACKAGE} cannot be selected: seats use Pi's built-in MCP extension, and Paseo would switch to the adapter if it were loaded.`);
1648
+ }
1647
1649
  if (roleList === void 0) return { package: name, roles: DEFAULT_EXTENSION_ROLES };
1648
1650
  const roles = roleList.split(",").map((role) => role.trim());
1649
1651
  const unknown = roles.filter((role) => !ROLES.some((known) => known === role));
@@ -1731,57 +1733,6 @@ async function resolvePiExtensions(home, choices, roles) {
1731
1733
  }
1732
1734
  return { byRole, checks };
1733
1735
  }
1734
- function adapterFailure(home, detail) {
1735
- return fail(
1736
- "pi.adapter",
1737
- detail,
1738
- `Install ${PACKAGE_NAME} into ${join10(home, "npm")} yourself with: pi install npm:${PACKAGE_NAME}. Pi's built-in MCP extension is not a substitute: Paseo hands a Pi seat its tools only through ${PACKAGE_NAME}. The room never installs Pi packages. Then run setup again.`
1739
- );
1740
- }
1741
- async function resolvePiAdapter(home) {
1742
- const packageRoot = join10(home, "npm", "node_modules", PACKAGE_NAME);
1743
- const manifestPath = join10(packageRoot, "package.json");
1744
- try {
1745
- await stat(packageRoot);
1746
- } catch (error) {
1747
- if (error.code === "ENOENT") {
1748
- return { check: adapterFailure(home, `${PACKAGE_NAME} is not installed in ${join10(home, "npm")}.`) };
1749
- }
1750
- }
1751
- try {
1752
- const [canonicalRoot, manifestStat, raw] = await Promise.all([
1753
- realpath(packageRoot),
1754
- stat(manifestPath),
1755
- readFile3(manifestPath, "utf8")
1756
- ]);
1757
- if (!manifestStat.isFile()) return { check: adapterFailure(home, `${manifestPath} is not a regular file.`) };
1758
- const manifest = asObject2(JSON.parse(raw));
1759
- if (!manifest || manifest.name !== PACKAGE_NAME) {
1760
- return { check: adapterFailure(home, `${manifestPath} does not identify ${PACKAGE_NAME}.`) };
1761
- }
1762
- const pi = asObject2(manifest.pi);
1763
- const declared = pi?.extensions;
1764
- if (!Array.isArray(declared) || declared.length !== 1 || typeof declared[0] !== "string" || !declared[0].trim()) {
1765
- return { check: adapterFailure(home, `${manifestPath} must declare one Pi extension entry.`) };
1766
- }
1767
- const declaration = declared[0];
1768
- if (isAbsolute2(declaration)) {
1769
- return { check: adapterFailure(home, `${manifestPath} declares an unsafe absolute extension path.`) };
1770
- }
1771
- const candidate = resolve3(packageRoot, declaration);
1772
- const [canonicalEntry, entryStat] = await Promise.all([realpath(candidate), stat(candidate)]);
1773
- if (!contains(canonicalRoot, canonicalEntry) || canonicalEntry === canonicalRoot || !entryStat.isFile()) {
1774
- return { check: adapterFailure(home, `The declared ${PACKAGE_NAME} extension escapes its package or is not a regular file.`) };
1775
- }
1776
- const version = typeof manifest.version === "string" && manifest.version.trim() ? manifest.version.trim() : "unknown";
1777
- return {
1778
- adapter: { entry: canonicalEntry, version },
1779
- check: pass("pi.adapter", `${PACKAGE_NAME} ${version} resolved to ${canonicalEntry}.`)
1780
- };
1781
- } catch {
1782
- return { check: adapterFailure(home, `Could not safely resolve ${PACKAGE_NAME} from ${manifestPath}.`) };
1783
- }
1784
- }
1785
1736
  function terminateProbe(child) {
1786
1737
  if (child.pid !== void 0) {
1787
1738
  try {
@@ -1797,7 +1748,7 @@ function terminateProbe(child) {
1797
1748
  child.stdout?.destroy();
1798
1749
  child.stderr?.destroy();
1799
1750
  }
1800
- function runProbeProcess(executable, adapterEntry, env, options, cwd) {
1751
+ function runProbeProcess(executable, env, options, cwd) {
1801
1752
  const timeoutMs = options.timeoutMs ?? PROBE_TIMEOUT_MS;
1802
1753
  const outputLimit = options.outputLimit ?? PROBE_OUTPUT_LIMIT;
1803
1754
  const args = [
@@ -1805,8 +1756,7 @@ function runProbeProcess(executable, adapterEntry, env, options, cwd) {
1805
1756
  "rpc",
1806
1757
  "--no-session",
1807
1758
  "--no-extensions",
1808
- "--extension",
1809
- adapterEntry,
1759
+ ...BUILTIN_EXTENSIONS,
1810
1760
  ...(options.extensions ?? []).flatMap((entry) => ["--extension", entry]),
1811
1761
  "--no-approve"
1812
1762
  ];
@@ -1863,17 +1813,16 @@ function runProbeProcess(executable, adapterEntry, env, options, cwd) {
1863
1813
  `);
1864
1814
  });
1865
1815
  }
1866
- async function runProbe(executable, adapterEntry, env, options) {
1816
+ async function runProbe(executable, env, options) {
1867
1817
  const createdCwd = await mkdtemp(join10(tmpdir(), "paseo-room-pi-probe-"));
1868
1818
  const cwd = await realpath(createdCwd);
1869
1819
  try {
1870
1820
  const agentDir = join10(cwd, "agent");
1871
1821
  await mkdir2(agentDir);
1872
- return await runProbeProcess(executable, adapterEntry, {
1822
+ return await runProbeProcess(executable, {
1873
1823
  ...env,
1874
1824
  HOME: cwd,
1875
1825
  PI_CODING_AGENT_DIR: agentDir,
1876
- PI_MCP_CONFIG_MODE: "exclusive",
1877
1826
  PI_OFFLINE: "1",
1878
1827
  [SEAT_ROLE_ENV]: "lead"
1879
1828
  }, options, cwd);
@@ -1885,13 +1834,13 @@ function probeFailure(message) {
1885
1834
  return fail(
1886
1835
  "pi.capability",
1887
1836
  message,
1888
- "Use a Pi and pi-mcp-adapter installation that exposes /mcp through the declared adapter entry."
1837
+ "Use Pi 1.1.0 or newer, whose built-in MCP extension exposes /mcp as builtin:mcp."
1889
1838
  );
1890
1839
  }
1891
- async function probePiMcp(executable, adapterEntry, env, options = {}) {
1840
+ async function probePiMcp(executable, env, options = {}) {
1892
1841
  let result;
1893
1842
  try {
1894
- result = await runProbe(executable, adapterEntry, env, options);
1843
+ result = await runProbe(executable, env, options);
1895
1844
  } catch {
1896
1845
  return probeFailure("Pi capability probe could not create or clean its isolated working directory.");
1897
1846
  }
@@ -1926,13 +1875,8 @@ async function probePiMcp(executable, adapterEntry, env, options = {}) {
1926
1875
  if (command?.source !== "extension") return probeFailure("Pi exposed /mcp from the wrong source.");
1927
1876
  const sourceInfo = asObject2(command.sourceInfo);
1928
1877
  if (typeof sourceInfo?.path !== "string") return probeFailure("Pi did not report the /mcp extension path.");
1929
- try {
1930
- const sourcePath = await realpath(sourceInfo.path);
1931
- if (sourcePath !== adapterEntry) return probeFailure("Pi loaded /mcp from a different extension path.");
1932
- } catch {
1933
- return probeFailure("Pi reported an unresolvable /mcp extension path.");
1934
- }
1935
- return pass("pi.capability", `Pi exposed /mcp from ${adapterEntry}.`);
1878
+ if (sourceInfo.path !== MCP_EXTENSION) return probeFailure("Pi loaded /mcp from a different extension path.");
1879
+ return pass("pi.capability", `Pi exposed /mcp from ${MCP_EXTENSION}.`);
1936
1880
  }
1937
1881
  async function readPiOptional(path) {
1938
1882
  try {
@@ -1970,7 +1914,7 @@ async function piCredentialDiagnostic(layout, role, binary = "pi") {
1970
1914
  fix: `Start a minimal, non-room-equivalent interactive login session with: ${launch}. Run /login, then exit Pi.`
1971
1915
  }] };
1972
1916
  }
1973
- var PACKAGE_NAME, PROBE_ID, PROBE_TIMEOUT_MS, PROBE_OUTPUT_LIMIT, SHARED3, EXECUTABLE3, MCP_FILE, MCP_KEYS, AUTH_ENV2, DEFAULT_EXTENSION_ROLES, NPM_NAME, SEAT_ROLE_ENV, piAgent;
1917
+ var MCP_EXTENSION, CODEMODE_EXTENSION, BUILTIN_EXTENSIONS, ADAPTER_PACKAGE, PROBE_ID, PROBE_TIMEOUT_MS, PROBE_OUTPUT_LIMIT, SHARED3, EXECUTABLE3, MCP_FILE, MCP_KEYS, AUTH_ENV2, DEFAULT_EXTENSION_ROLES, NPM_NAME, SEAT_ROLE_ENV, piAgent;
1974
1918
  var init_pi = __esm({
1975
1919
  "src/agents/pi.ts"() {
1976
1920
  "use strict";
@@ -1986,7 +1930,10 @@ var init_pi = __esm({
1986
1930
  init_mcp();
1987
1931
  init_resources();
1988
1932
  init_skills();
1989
- PACKAGE_NAME = "pi-mcp-adapter";
1933
+ MCP_EXTENSION = "builtin:mcp";
1934
+ CODEMODE_EXTENSION = "builtin:codemode";
1935
+ BUILTIN_EXTENSIONS = ["--extension", MCP_EXTENSION, "--extension", CODEMODE_EXTENSION];
1936
+ ADAPTER_PACKAGE = "pi-mcp-adapter";
1990
1937
  PROBE_ID = "paseo-room-pi-mcp-probe";
1991
1938
  PROBE_TIMEOUT_MS = 1e4;
1992
1939
  PROBE_OUTPUT_LIMIT = 1024 * 1024;
@@ -2023,7 +1970,6 @@ var init_pi = __esm({
2023
1970
  id: "pi",
2024
1971
  label: "Pi",
2025
1972
  homeEnv: "PI_CODING_AGENT_DIR",
2026
- providerEnv: { PI_MCP_CONFIG_MODE: "exclusive" },
2027
1973
  pins: {},
2028
1974
  async build(layout, roles, options) {
2029
1975
  const home = layout.agentHome.pi;
@@ -2036,20 +1982,18 @@ var init_pi = __esm({
2036
1982
  } catch {
2037
1983
  return { entries: [], checks: [fail("pi.home", `No Pi config directory at ${home}.`, "Run Pi once to initialise it, or pass --pi-home.")] };
2038
1984
  }
2039
- const resolved = await resolvePiAdapter(home);
2040
- if (!resolved.adapter) return { entries: [], checks: [resolved.check] };
2041
1985
  const extensions = await resolvePiExtensions(home, options?.piExtensions ?? [], roles);
2042
1986
  if (extensions.checks.some((check) => check.status === "fail")) {
2043
- return { entries: [], checks: [resolved.check, ...extensions.checks] };
1987
+ return { entries: [], checks: [...extensions.checks] };
2044
1988
  }
2045
1989
  const selected = [...new Set(Object.values(extensions.byRole).flat())];
2046
- const capability = await probePiMcp(binary, resolved.adapter.entry, {
1990
+ const capability = await probePiMcp(binary, {
2047
1991
  HOME: layout.home,
2048
1992
  PATH: layout.searchPath,
2049
1993
  PI_OFFLINE: "1"
2050
1994
  }, { extensions: selected });
2051
1995
  if (capability.status === "fail") {
2052
- return { entries: [], checks: [resolved.check, ...extensions.checks, selected.length === 0 ? capability : {
1996
+ return { entries: [], checks: [...extensions.checks, selected.length === 0 ? capability : {
2053
1997
  ...capability,
2054
1998
  fix: `${capability.fix ?? ""} A selected Pi extension may also be what stops Pi from starting; retry without --pi-extension to tell.`.trim()
2055
1999
  }] };
@@ -2062,7 +2006,6 @@ var init_pi = __esm({
2062
2006
  return {
2063
2007
  entries: [],
2064
2008
  checks: [
2065
- resolved.check,
2066
2009
  capability,
2067
2010
  fail(
2068
2011
  "pi.settings",
@@ -2080,7 +2023,6 @@ var init_pi = __esm({
2080
2023
  return {
2081
2024
  entries: [],
2082
2025
  checks: [
2083
- resolved.check,
2084
2026
  capability,
2085
2027
  fail(
2086
2028
  "pi.append",
@@ -2099,7 +2041,6 @@ var init_pi = __esm({
2099
2041
  return {
2100
2042
  entries: [],
2101
2043
  checks: [
2102
- resolved.check,
2103
2044
  capability,
2104
2045
  fail(
2105
2046
  "pi.mcp",
@@ -2110,7 +2051,7 @@ var init_pi = __esm({
2110
2051
  };
2111
2052
  }
2112
2053
  const conflict = paseoMcpCheck("pi.mcp", mcpPath, servers);
2113
- if (conflict) return { entries: [], checks: [resolved.check, capability, conflict] };
2054
+ if (conflict) return { entries: [], checks: [capability, conflict] };
2114
2055
  const entries = [];
2115
2056
  const credentials = [];
2116
2057
  const argv = {};
@@ -2135,8 +2076,7 @@ var init_pi = __esm({
2135
2076
  credentials.push(await piCredentialDiagnostic(layout, role, binary));
2136
2077
  argv[role] = [
2137
2078
  "--no-extensions",
2138
- "--extension",
2139
- resolved.adapter.entry,
2079
+ ...BUILTIN_EXTENSIONS,
2140
2080
  ...(extensions.byRole[role] ?? []).flatMap((entry) => ["--extension", entry]),
2141
2081
  "--no-approve",
2142
2082
  "--append-system-prompt",
@@ -2147,7 +2087,7 @@ var init_pi = __esm({
2147
2087
  return {
2148
2088
  entries,
2149
2089
  credentials,
2150
- checks: [pass("pi.home", `Pi found at ${binary} using ${home}.`), resolved.check, ...extensions.checks, capability],
2090
+ checks: [pass("pi.home", `Pi found at ${binary} using ${home}.`), ...extensions.checks, capability],
2151
2091
  binary,
2152
2092
  argv,
2153
2093
  providerEnv
@@ -2161,7 +2101,8 @@ var init_pi = __esm({
2161
2101
  import { gte, valid } from "semver";
2162
2102
  import { z as z2 } from "zod";
2163
2103
  function minimumPaseoVersion(agents, runtime = false) {
2164
- return runtime || agents.includes("pi") || agents.includes("claude") ? PI_MINIMUM_VERSION : MINIMUM_VERSION;
2104
+ if (agents.includes("pi")) return PI_MINIMUM_VERSION;
2105
+ return runtime || agents.includes("claude") ? PLUGIN_MINIMUM_VERSION : MINIMUM_VERSION;
2165
2106
  }
2166
2107
  function normalizeUrl(listen) {
2167
2108
  const match = /^(?:ws:\/\/)?([^:/]+|\[[^\]]+\]):(\d+)$/.exec(listen.trim());
@@ -2352,14 +2293,15 @@ function mergeProfiles(live, desired, drop) {
2352
2293
  });
2353
2294
  return [...kept, ...desired.filter((profile) => !seen.has(profile.id)).map((profile) => ({ ...profile }))];
2354
2295
  }
2355
- var MINIMUM_VERSION, PI_MINIMUM_VERSION, statusSchema, configSchema;
2296
+ var MINIMUM_VERSION, PLUGIN_MINIMUM_VERSION, PI_MINIMUM_VERSION, statusSchema, configSchema;
2356
2297
  var init_paseo = __esm({
2357
2298
  "src/paseo.ts"() {
2358
2299
  "use strict";
2359
2300
  init_result();
2360
2301
  init_which();
2361
2302
  MINIMUM_VERSION = "0.8.0-beta.1";
2362
- PI_MINIMUM_VERSION = "0.8.0";
2303
+ PLUGIN_MINIMUM_VERSION = "0.8.0";
2304
+ PI_MINIMUM_VERSION = "0.11.1";
2363
2305
  statusSchema = z2.object({
2364
2306
  listen: z2.string().min(1),
2365
2307
  localDaemon: z2.string().min(1),
@@ -5023,7 +4965,7 @@ async function runWizard(prompts, emit, write, options = {}, onAction) {
5023
4965
  message: `Pi seats load these extensions: ${listed}. Keep them?`,
5024
4966
  options: [
5025
4967
  { value: "keep", label: "Yes \u2014 keep loading them (recommended)" },
5026
- { value: "drop", label: "No \u2014 start Pi seats with the MCP adapter only" }
4968
+ { value: "drop", label: "No \u2014 start Pi seats with only Pi's built-in MCP" }
5027
4969
  ]
5028
4970
  });
5029
4971
  if (typeof keep === "symbol") return cancelled();