pi-fabric 0.110.2 → 0.110.3

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
@@ -156,7 +156,7 @@ See the [interface & commands reference](docs/interface.md) for every view, keyb
156
156
 
157
157
  ## Reference
158
158
 
159
- - [Configuration](docs/configuration.md): `fabric.json`, code modes, tool capture, approvals, and budgets.
159
+ - [Configuration](docs/configuration.md): `fabric.json`, code modes, tool capture, approvals, budgets, and [third-party model providers](docs/configuration.md#third-party-model-providers).
160
160
  - [Execution kernels](docs/kernels.md): exclusive TypeScript/Python selection, Monty sandboxing, CPython escape hatch, agent inheritance, and examples.
161
161
  - [Native codemode APIs](docs/codemode-parity.md): additive native tool aliases or opt-in Pi-compatible scripts, collision-safe Fabric discovery, native models/images, branch-local state, and sPTC.
162
162
  - [Prompt cache](docs/prompt-cache.md): honest cache observations and optional, time-bounded native warming leases.
@@ -0,0 +1,59 @@
1
+ import type { Provider } from "@earendil-works/pi-ai";
2
+ import type { ExtensionAPI, ProviderConfig } from "@earendil-works/pi-coding-agent";
3
+ /**
4
+ * The `provider/id` key a Pi child launched with `extensions: false` must
5
+ * resolve. The worker sets it only when it also loads this bridge with `-e`.
6
+ */
7
+ export declare const PROVIDER_BRIDGE_MODEL_ENV = "PI_FABRIC_EXTENSION_MODEL";
8
+ export interface ExtensionProviderRegistrations {
9
+ configs: Array<{
10
+ name: string;
11
+ config: ProviderConfig;
12
+ extensionPath: string;
13
+ }>;
14
+ natives: Array<{
15
+ provider: Provider;
16
+ extensionPath: string;
17
+ }>;
18
+ }
19
+ export interface ResolveExtensionProvidersOptions {
20
+ model: string;
21
+ cwd: string;
22
+ agentDir: string;
23
+ /** Extension entry files never probed (Fabric's own entries by default). */
24
+ exclude?: readonly string[];
25
+ }
26
+ type PiSdk = typeof import("@earendil-works/pi-coding-agent");
27
+ /** Split a canonical `provider/id` key at its first slash. */
28
+ export declare function parseModelKey(key: string): {
29
+ provider: string;
30
+ id: string;
31
+ } | undefined;
32
+ /**
33
+ * Probe extensions whose own path names the provider first (the usual
34
+ * `pi-<provider>-provider` package), so the common case runs one registration
35
+ * function instead of every installed extension.
36
+ */
37
+ export declare function orderProviderCandidates(paths: readonly string[], provider: string): {
38
+ named: string[];
39
+ rest: string[];
40
+ };
41
+ /** Fabric's own manifest entries: they never register chat providers. */
42
+ export declare function fabricExtensionEntries(moduleUrl?: string): string[];
43
+ /**
44
+ * Find the extension registrations that make `model` resolvable in a child
45
+ * without its other extensions. Returns `undefined` when Pi already knows the
46
+ * model (built in, models.json, or a cached catalog), so those children keep
47
+ * their exact extension-free behaviour. Throws an actionable error when no
48
+ * installed extension registers the provider.
49
+ */
50
+ export declare function resolveExtensionProviders(options: ResolveExtensionProvidersOptions, sdk?: PiSdk): Promise<ExtensionProviderRegistrations | undefined>;
51
+ /**
52
+ * Loaded with `-e` into Pi children launched with `extensions: false`. It
53
+ * registers only the requested model's provider, as its extension registered
54
+ * it, so credentials still resolve in the child through auth.json, the
55
+ * environment, or the credential store. Nothing else from that extension loads.
56
+ */
57
+ export default function fabricProviderBridge(pi: ExtensionAPI): Promise<void>;
58
+ export {};
59
+ //# sourceMappingURL=provider-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-bridge.d.ts","sourceRoot":"","sources":["../../src/agents/provider-bridge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAmB,MAAM,iCAAiC,CAAC;AAErG;;;GAGG;AACH,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AAErE,MAAM,WAAW,8BAA8B;IAC7C,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,cAAc,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChF,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,KAAK,KAAK,GAAG,cAAc,iCAAiC,CAAC,CAAC;AAE9D,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAKvF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CASrC;AAUD,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,SAAS,SAAkB,GAAG,MAAM,EAAE,CAc5E;AA0CD;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,gCAAgC,EACzC,GAAG,CAAC,EAAE,KAAK,GACV,OAAO,CAAC,8BAA8B,GAAG,SAAS,CAAC,CA4CrD;AAED;;;;;GAKG;AACH,wBAA8B,oBAAoB,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAQlF"}
@@ -0,0 +1,112 @@
1
+ // src/agents/provider-bridge.ts
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ var PROVIDER_BRIDGE_MODEL_ENV = "PI_FABRIC_EXTENSION_MODEL";
6
+ function parseModelKey(key) {
7
+ const value = key.trim();
8
+ const slash = value.indexOf("/");
9
+ if (slash <= 0 || slash === value.length - 1) return void 0;
10
+ return { provider: value.slice(0, slash), id: value.slice(slash + 1) };
11
+ }
12
+ function orderProviderCandidates(paths, provider) {
13
+ const needle = provider.toLowerCase();
14
+ const named = [];
15
+ const rest = [];
16
+ for (const candidate of paths) {
17
+ const tail = candidate.split(/[\\/]+/).filter(Boolean).slice(-3);
18
+ (tail.some((segment) => segment.toLowerCase().includes(needle)) ? named : rest).push(candidate);
19
+ }
20
+ return { named, rest };
21
+ }
22
+ var realPath = (file) => {
23
+ try {
24
+ return fs.realpathSync(file);
25
+ } catch {
26
+ return path.resolve(file);
27
+ }
28
+ };
29
+ function fabricExtensionEntries(moduleUrl = import.meta.url) {
30
+ const root = path.resolve(path.dirname(fileURLToPath(moduleUrl)), "..", "..");
31
+ try {
32
+ const manifest = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
33
+ if (manifest.name !== "pi-fabric") return [];
34
+ const entries = [manifest.main, ...Array.isArray(manifest.pi?.extensions) ? manifest.pi.extensions : []];
35
+ return entries.filter((entry) => typeof entry === "string").map((entry) => path.resolve(root, entry));
36
+ } catch {
37
+ return [];
38
+ }
39
+ }
40
+ var emptyRegistrations = () => ({ configs: [], natives: [] });
41
+ async function loadProviderRegistrations(sdk, paths, provider, options, failures) {
42
+ if (paths.length === 0) return emptyRegistrations();
43
+ const loader = new sdk.DefaultResourceLoader({
44
+ cwd: options.cwd,
45
+ agentDir: options.agentDir,
46
+ settingsManager: options.settingsManager,
47
+ noExtensions: true,
48
+ additionalExtensionPaths: [...paths],
49
+ noSkills: true,
50
+ noPromptTemplates: true,
51
+ noThemes: true,
52
+ noContextFiles: true
53
+ });
54
+ await loader.reload();
55
+ const { runtime, errors } = loader.getExtensions();
56
+ failures.push(...errors.map((error) => error.path));
57
+ return {
58
+ configs: runtime.pendingProviderRegistrations.filter((registration) => registration.name === provider).map(({ name, config, extensionPath }) => ({ name, config, extensionPath })),
59
+ natives: runtime.pendingNativeProviderRegistrations.filter((registration) => registration.provider.id === provider).map(({ provider: registered, extensionPath }) => ({ provider: registered, extensionPath }))
60
+ };
61
+ }
62
+ async function resolveExtensionProviders(options, sdk) {
63
+ const key = parseModelKey(options.model);
64
+ if (!key) return void 0;
65
+ const pi = sdk ?? await import("@earendil-works/pi-coding-agent");
66
+ const models = await pi.ModelRuntime.create({
67
+ authPath: path.join(options.agentDir, "auth.json"),
68
+ modelsPath: path.join(options.agentDir, "models.json"),
69
+ refreshOnCreate: false
70
+ });
71
+ if (models.getModel(key.provider, key.id)) return void 0;
72
+ await models.refresh({ allowNetwork: false, signal: AbortSignal.timeout(15e3) });
73
+ if (models.getModel(key.provider, key.id)) return void 0;
74
+ const untrusted = pi.SettingsManager.create(options.cwd, options.agentDir, { projectTrusted: false });
75
+ const trusted = !pi.hasTrustRequiringProjectResources(options.cwd) || (new pi.ProjectTrustStore(options.agentDir).get(options.cwd) ?? untrusted.getDefaultProjectTrust() === "always");
76
+ const settingsManager = trusted ? pi.SettingsManager.create(options.cwd, options.agentDir, { projectTrusted: true }) : untrusted;
77
+ const resolved = await new pi.DefaultPackageManager({
78
+ cwd: options.cwd,
79
+ agentDir: options.agentDir,
80
+ settingsManager
81
+ }).resolve();
82
+ const excluded = new Set((options.exclude ?? fabricExtensionEntries()).map(realPath));
83
+ const candidates = resolved.extensions.filter((resource) => resource.enabled && !resource.path.startsWith("builtin:")).map((resource) => resource.path).filter((candidate) => !excluded.has(realPath(candidate)));
84
+ const { named, rest } = orderProviderCandidates(candidates, key.provider);
85
+ const context = { cwd: options.cwd, agentDir: options.agentDir, settingsManager };
86
+ const failures = [];
87
+ for (const group of [named, rest]) {
88
+ const found = await loadProviderRegistrations(pi, group, key.provider, context, failures);
89
+ if (found.configs.length > 0 || found.natives.length > 0) return found;
90
+ }
91
+ throw new Error(
92
+ `Model "${options.model}" needs provider "${key.provider}", which is not built into Pi or defined in models.json, and no installed Pi extension registers it for this extensions: false child. Install the extension that provides it, or run the child with extensions: true.` + (failures.length > 0 ? ` Extensions that failed to load while searching: ${[...new Set(failures)].join(", ")}.` : "")
93
+ );
94
+ }
95
+ async function fabricProviderBridge(pi) {
96
+ const model = process.env[PROVIDER_BRIDGE_MODEL_ENV]?.trim();
97
+ if (!model) return;
98
+ const { getAgentDir } = await import("@earendil-works/pi-coding-agent");
99
+ const found = await resolveExtensionProviders({ model, cwd: process.cwd(), agentDir: getAgentDir() });
100
+ if (!found) return;
101
+ for (const { name, config } of found.configs) pi.registerProvider(name, config);
102
+ for (const { provider } of found.natives) pi.registerProvider(provider);
103
+ }
104
+ export {
105
+ PROVIDER_BRIDGE_MODEL_ENV,
106
+ fabricProviderBridge as default,
107
+ fabricExtensionEntries,
108
+ orderProviderCandidates,
109
+ parseModelKey,
110
+ resolveExtensionProviders
111
+ };
112
+ //# sourceMappingURL=provider-bridge.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/agents/provider-bridge.ts"],
4
+ "sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Provider } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI, ProviderConfig, SettingsManager } from \"@earendil-works/pi-coding-agent\";\n\n/**\n * The `provider/id` key a Pi child launched with `extensions: false` must\n * resolve. The worker sets it only when it also loads this bridge with `-e`.\n */\nexport const PROVIDER_BRIDGE_MODEL_ENV = \"PI_FABRIC_EXTENSION_MODEL\";\n\nexport interface ExtensionProviderRegistrations {\n configs: Array<{ name: string; config: ProviderConfig; extensionPath: string }>;\n natives: Array<{ provider: Provider; extensionPath: string }>;\n}\n\nexport interface ResolveExtensionProvidersOptions {\n model: string;\n cwd: string;\n agentDir: string;\n /** Extension entry files never probed (Fabric's own entries by default). */\n exclude?: readonly string[];\n}\n\ntype PiSdk = typeof import(\"@earendil-works/pi-coding-agent\");\n\n/** Split a canonical `provider/id` key at its first slash. */\nexport function parseModelKey(key: string): { provider: string; id: string } | undefined {\n const value = key.trim();\n const slash = value.indexOf(\"/\");\n if (slash <= 0 || slash === value.length - 1) return undefined;\n return { provider: value.slice(0, slash), id: value.slice(slash + 1) };\n}\n\n/**\n * Probe extensions whose own path names the provider first (the usual\n * `pi-<provider>-provider` package), so the common case runs one registration\n * function instead of every installed extension.\n */\nexport function orderProviderCandidates(\n paths: readonly string[],\n provider: string,\n): { named: string[]; rest: string[] } {\n const needle = provider.toLowerCase();\n const named: string[] = [];\n const rest: string[] = [];\n for (const candidate of paths) {\n const tail = candidate.split(/[\\\\/]+/).filter(Boolean).slice(-3);\n (tail.some((segment) => segment.toLowerCase().includes(needle)) ? named : rest).push(candidate);\n }\n return { named, rest };\n}\n\nconst realPath = (file: string): string => {\n try {\n return fs.realpathSync(file);\n } catch {\n return path.resolve(file);\n }\n};\n\n/** Fabric's own manifest entries: they never register chat providers. */\nexport function fabricExtensionEntries(moduleUrl = import.meta.url): string[] {\n const root = path.resolve(path.dirname(fileURLToPath(moduleUrl)), \"..\", \"..\");\n try {\n const manifest = JSON.parse(fs.readFileSync(path.join(root, \"package.json\"), \"utf8\")) as {\n name?: unknown;\n main?: unknown;\n pi?: { extensions?: unknown };\n };\n if (manifest.name !== \"pi-fabric\") return [];\n const entries = [manifest.main, ...(Array.isArray(manifest.pi?.extensions) ? manifest.pi.extensions : [])];\n return entries.filter((entry): entry is string => typeof entry === \"string\").map((entry) => path.resolve(root, entry));\n } catch {\n return [];\n }\n}\n\nconst emptyRegistrations = (): ExtensionProviderRegistrations => ({ configs: [], natives: [] });\n\n/**\n * Load extension paths with Pi's own loader into an isolated runtime and keep\n * only the requested provider's registrations. The loaded extensions are\n * discarded: their tools, commands, flags, shortcuts, renderers, and event\n * handlers never bind to the child session, and their event bus is private.\n */\nasync function loadProviderRegistrations(\n sdk: PiSdk,\n paths: readonly string[],\n provider: string,\n options: { cwd: string; agentDir: string; settingsManager: SettingsManager },\n failures: string[],\n): Promise<ExtensionProviderRegistrations> {\n if (paths.length === 0) return emptyRegistrations();\n const loader = new sdk.DefaultResourceLoader({\n cwd: options.cwd,\n agentDir: options.agentDir,\n settingsManager: options.settingsManager,\n noExtensions: true,\n additionalExtensionPaths: [...paths],\n noSkills: true,\n noPromptTemplates: true,\n noThemes: true,\n noContextFiles: true,\n });\n await loader.reload();\n const { runtime, errors } = loader.getExtensions();\n failures.push(...errors.map((error) => error.path));\n return {\n configs: runtime.pendingProviderRegistrations\n .filter((registration) => registration.name === provider)\n .map(({ name, config, extensionPath }) => ({ name, config, extensionPath })),\n natives: runtime.pendingNativeProviderRegistrations\n .filter((registration) => registration.provider.id === provider)\n .map(({ provider: registered, extensionPath }) => ({ provider: registered, extensionPath })),\n };\n}\n\n/**\n * Find the extension registrations that make `model` resolvable in a child\n * without its other extensions. Returns `undefined` when Pi already knows the\n * model (built in, models.json, or a cached catalog), so those children keep\n * their exact extension-free behaviour. Throws an actionable error when no\n * installed extension registers the provider.\n */\nexport async function resolveExtensionProviders(\n options: ResolveExtensionProvidersOptions,\n sdk?: PiSdk,\n): Promise<ExtensionProviderRegistrations | undefined> {\n const key = parseModelKey(options.model);\n if (!key) return undefined;\n const pi = sdk ?? await import(\"@earendil-works/pi-coding-agent\");\n const models = await pi.ModelRuntime.create({\n authPath: path.join(options.agentDir, \"auth.json\"),\n modelsPath: path.join(options.agentDir, \"models.json\"),\n refreshOnCreate: false,\n });\n if (models.getModel(key.provider, key.id)) return undefined;\n await models.refresh({ allowNetwork: false, signal: AbortSignal.timeout(15_000) });\n if (models.getModel(key.provider, key.id)) return undefined;\n\n // Same trust a headless child applies without consulting extension\n // project_trust handlers: those belong to the extensions left out here.\n const untrusted = pi.SettingsManager.create(options.cwd, options.agentDir, { projectTrusted: false });\n const trusted = !pi.hasTrustRequiringProjectResources(options.cwd) ||\n (new pi.ProjectTrustStore(options.agentDir).get(options.cwd) ?? untrusted.getDefaultProjectTrust() === \"always\");\n const settingsManager = trusted\n ? pi.SettingsManager.create(options.cwd, options.agentDir, { projectTrusted: true })\n : untrusted;\n const resolved = await new pi.DefaultPackageManager({\n cwd: options.cwd,\n agentDir: options.agentDir,\n settingsManager,\n }).resolve();\n const excluded = new Set((options.exclude ?? fabricExtensionEntries()).map(realPath));\n const candidates = resolved.extensions\n .filter((resource) => resource.enabled && !resource.path.startsWith(\"builtin:\"))\n .map((resource) => resource.path)\n .filter((candidate) => !excluded.has(realPath(candidate)));\n const { named, rest } = orderProviderCandidates(candidates, key.provider);\n const context = { cwd: options.cwd, agentDir: options.agentDir, settingsManager };\n const failures: string[] = [];\n for (const group of [named, rest]) {\n const found = await loadProviderRegistrations(pi, group, key.provider, context, failures);\n if (found.configs.length > 0 || found.natives.length > 0) return found;\n }\n throw new Error(\n `Model \"${options.model}\" needs provider \"${key.provider}\", which is not built into Pi or defined in models.json, ` +\n \"and no installed Pi extension registers it for this extensions: false child. \" +\n \"Install the extension that provides it, or run the child with extensions: true.\" +\n (failures.length > 0 ? ` Extensions that failed to load while searching: ${[...new Set(failures)].join(\", \")}.` : \"\"),\n );\n}\n\n/**\n * Loaded with `-e` into Pi children launched with `extensions: false`. It\n * registers only the requested model's provider, as its extension registered\n * it, so credentials still resolve in the child through auth.json, the\n * environment, or the credential store. Nothing else from that extension loads.\n */\nexport default async function fabricProviderBridge(pi: ExtensionAPI): Promise<void> {\n const model = process.env[PROVIDER_BRIDGE_MODEL_ENV]?.trim();\n if (!model) return;\n const { getAgentDir } = await import(\"@earendil-works/pi-coding-agent\");\n const found = await resolveExtensionProviders({ model, cwd: process.cwd(), agentDir: getAgentDir() });\n if (!found) return;\n for (const { name, config } of found.configs) pi.registerProvider(name, config);\n for (const { provider } of found.natives) pi.registerProvider(provider);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/dist/agents.js CHANGED
@@ -1,10 +1,10 @@
1
- import {
2
- validateAgentResult
3
- } from "./chunks/chunk-VYQV5JRT.js";
4
1
  import {
5
2
  AGENTS_ACTION_DESCRIPTORS,
6
3
  normalizeAgentRunRequest
7
4
  } from "./chunks/chunk-JJQECUUA.js";
5
+ import {
6
+ validateAgentResult
7
+ } from "./chunks/chunk-VYQV5JRT.js";
8
8
  import {
9
9
  AgentAdmission,
10
10
  assertAgentTask,
@@ -1 +1 @@
1
- {"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../../src/capture/interceptor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EAEf,cAAc,EACf,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAyB,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AASnD,MAAM,WAAW,+BAA+B;IAC9C,SAAS,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACjD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,4BAA4B;IAC3C,gBAAgB,EAAE,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAChD,OAAO,EAAE,mBAAmB,CAAC;IAC7B,aAAa,CAAC,EAAE,uBAAuB,CAAC;IAUxC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAyBD,KAAK,0BAA0B,GAAG;IAChC,SAAS,EAAE,eAAe,CAAC;CAC5B,CAAC;AAaF,eAAO,MAAM,iCAAiC,GAC5C,WAAW,MAAM,KAChB,OAAO,CAAC,0BAA0B,EAAE,CAuBtC,CAAC;AAiIF,eAAO,MAAM,4BAA4B,GACvC,SAAS,4BAA4B,KACpC,OAAO,CAAC,+BAA+B,CA0CzC,CAAC"}
1
+ {"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../../src/capture/interceptor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EAEf,cAAc,EACf,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAyB,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AASnD,MAAM,WAAW,+BAA+B;IAC9C,SAAS,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACjD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,4BAA4B;IAC3C,gBAAgB,EAAE,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAChD,OAAO,EAAE,mBAAmB,CAAC;IAC7B,aAAa,CAAC,EAAE,uBAAuB,CAAC;IAUxC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAiCD,KAAK,0BAA0B,GAAG;IAChC,SAAS,EAAE,eAAe,CAAC;CAC5B,CAAC;AAaF,eAAO,MAAM,iCAAiC,GAC5C,WAAW,MAAM,KAChB,OAAO,CAAC,0BAA0B,EAAE,CAuBtC,CAAC;AAqIF,eAAO,MAAM,4BAA4B,GACvC,SAAS,4BAA4B,KACpC,OAAO,CAAC,+BAA+B,CA0CzC,CAAC"}
@@ -561,6 +561,7 @@ import { createRequire } from "node:module";
561
561
  import path from "node:path";
562
562
  import { pathToFileURL } from "node:url";
563
563
  var HUB_SYMBOL = Symbol.for("pi-fabric.registered-tool-capture.v1");
564
+ var HOST_RUNNERS_SYMBOL = Symbol.for("pi-fabric.host-extension-runners.v1");
564
565
  var ANCHOR_SYMBOL = Symbol.for("pi-fabric.registered-tool-anchor.v1");
565
566
  var definitionDelegatesTo = (definition, target) => {
566
567
  let current = definition;
@@ -694,6 +695,10 @@ var extensionRunnerConstructors = async () => {
694
695
  constructors.add(Runner);
695
696
  }
696
697
  }
698
+ const advertised = globalThis[HOST_RUNNERS_SYMBOL];
699
+ for (const Runner of advertised instanceof Set ? advertised : []) {
700
+ if (isExtensionRunnerConstructor(Runner)) constructors.add(Runner);
701
+ }
697
702
  if (constructors.size === 0) {
698
703
  try {
699
704
  const hostModule = await import("@earendil-works/pi-coding-agent");
@@ -6597,4 +6602,4 @@ export {
6597
6602
  FABRIC_MANAGED_HOST_VERSION,
6598
6603
  createFabricExtension
6599
6604
  };
6600
- //# sourceMappingURL=chunk-6C7FX3WA.js.map
6605
+ //# sourceMappingURL=chunk-BEP6VFL2.js.map