pi-fabric 0.111.0 → 0.112.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.
Files changed (89) hide show
  1. package/dist/agents/provider-bridge.d.ts +0 -16
  2. package/dist/agents/provider-bridge.d.ts.map +1 -1
  3. package/dist/agents/provider-bridge.js +5 -31
  4. package/dist/agents/provider-bridge.js.map +2 -2
  5. package/dist/capture/interceptor.d.ts.map +1 -1
  6. package/dist/chunks/{chunk-WHBJDTCR.js → chunk-7PPIKFT5.js} +36 -9
  7. package/dist/chunks/chunk-7PPIKFT5.js.map +7 -0
  8. package/dist/chunks/{chunk-BEP6VFL2.js → chunk-GFBOLBU2.js} +51 -32
  9. package/dist/chunks/chunk-GFBOLBU2.js.map +7 -0
  10. package/dist/chunks/chunk-GQGXQCCO.js +38 -0
  11. package/dist/chunks/chunk-GQGXQCCO.js.map +7 -0
  12. package/dist/chunks/{chunk-KP2VU5SI.js → chunk-JAEDKSU4.js} +5 -5
  13. package/dist/chunks/{chunk-XMBRW6L2.js → chunk-ORRLYFKA.js} +2 -2
  14. package/dist/chunks/{chunk-PXAICAUT.js → chunk-PBDDXBHY.js} +2 -1
  15. package/dist/chunks/chunk-PBDDXBHY.js.map +7 -0
  16. package/dist/chunks/{chunk-GYPDGW27.js → chunk-QGP7AY2R.js} +4 -2
  17. package/dist/chunks/{chunk-GYPDGW27.js.map → chunk-QGP7AY2R.js.map} +2 -2
  18. package/dist/chunks/{chunk-CXTTLBUV.js → chunk-R2XQ6AHT.js} +2 -2
  19. package/dist/chunks/{chunk-QFR36ZSK.js → chunk-R4RROLJ4.js} +23 -14
  20. package/dist/chunks/chunk-R4RROLJ4.js.map +7 -0
  21. package/dist/chunks/{chunk-DV2JZSCI.js → chunk-SPCJXN4K.js} +14 -4
  22. package/dist/chunks/{chunk-DV2JZSCI.js.map → chunk-SPCJXN4K.js.map} +2 -2
  23. package/dist/chunks/{chunk-2TJHOQGO.js → chunk-TNPZBMYC.js} +1 -4
  24. package/dist/chunks/chunk-TNPZBMYC.js.map +7 -0
  25. package/dist/chunks/{chunk-5SU3YXBS.js → chunk-UGYCAG6O.js} +1 -1
  26. package/dist/chunks/{chunk-5SU3YXBS.js.map → chunk-UGYCAG6O.js.map} +1 -1
  27. package/dist/chunks/{chunk-DSNR5U7X.js → chunk-UQWBZKAN.js} +1 -1
  28. package/dist/chunks/{chunk-S6BFCVOG.js → chunk-VYWJVAK5.js} +2 -2
  29. package/dist/chunks/{chunk-XBGOJJQW.js → chunk-WQ6LC2KK.js} +2 -2
  30. package/dist/chunks/{chunk-W5CHVJBR.js → chunk-XDZMXORT.js} +53 -7
  31. package/dist/chunks/chunk-XDZMXORT.js.map +7 -0
  32. package/dist/chunks/{chunk-3DUKKQHN.js → chunk-ZQMBS5SH.js} +5 -5
  33. package/dist/commands/fabric.d.ts +1 -1
  34. package/dist/commands/fabric.d.ts.map +1 -1
  35. package/dist/compaction/hook.d.ts +1 -1
  36. package/dist/compaction/hook.d.ts.map +1 -1
  37. package/dist/compaction/hook.js +1 -1
  38. package/dist/compaction/owner.js +2 -2
  39. package/dist/core/agent-dir.d.ts +1 -0
  40. package/dist/core/agent-dir.d.ts.map +1 -1
  41. package/dist/core/fabric-state-paths.d.ts.map +1 -1
  42. package/dist/core/host-sdk.d.ts +21 -0
  43. package/dist/core/host-sdk.d.ts.map +1 -0
  44. package/dist/core/host-sdk.js +9 -0
  45. package/dist/core/host-sdk.js.map +7 -0
  46. package/dist/extension-bootstrap.d.ts +1 -1
  47. package/dist/extension-bootstrap.js +6 -6
  48. package/dist/fabric-runtime-state.js +8 -8
  49. package/dist/index.d.ts +1 -1
  50. package/dist/index.js +6 -6
  51. package/dist/jev/client.d.ts.map +1 -1
  52. package/dist/jev/client.js +2 -2
  53. package/dist/jev/manager.d.ts.map +1 -1
  54. package/dist/jev/observation.js +2 -2
  55. package/dist/jev/validation.d.ts +34 -0
  56. package/dist/jev/validation.d.ts.map +1 -1
  57. package/dist/jev.js +5 -5
  58. package/dist/providers/jev-provider.js +5 -5
  59. package/dist/residency/host.js +4 -4
  60. package/dist/residency/pi-entry.js +4 -4
  61. package/dist/runtime/node-process-runtime.js +3 -3
  62. package/dist/runtime/quickjs-runtime.d.ts.map +1 -1
  63. package/dist/runtime/quickjs-runtime.js +2 -2
  64. package/dist/runtime/typescript-kernel.js +3 -3
  65. package/dist/ui/controller.d.ts.map +1 -1
  66. package/dist/ui/conversation-chrome.js +2 -2
  67. package/dist/ui/conversation-host.js +1 -1
  68. package/dist/ui/conversation-native-reader.js +1 -1
  69. package/dist/ui/conversation.js +6 -6
  70. package/dist/ui/dashboard.js +3 -3
  71. package/dist/ui/settings.js +1 -1
  72. package/dist/worker/result.js +517 -517
  73. package/dist/worker/result.js.map +1 -1
  74. package/docs/jev-decisions.md +6 -1
  75. package/docs/jev.md +9 -3
  76. package/package.json +1 -1
  77. package/dist/chunks/chunk-2TJHOQGO.js.map +0 -7
  78. package/dist/chunks/chunk-BEP6VFL2.js.map +0 -7
  79. package/dist/chunks/chunk-PXAICAUT.js.map +0 -7
  80. package/dist/chunks/chunk-QFR36ZSK.js.map +0 -7
  81. package/dist/chunks/chunk-W5CHVJBR.js.map +0 -7
  82. package/dist/chunks/chunk-WHBJDTCR.js.map +0 -7
  83. /package/dist/chunks/{chunk-KP2VU5SI.js.map → chunk-JAEDKSU4.js.map} +0 -0
  84. /package/dist/chunks/{chunk-XMBRW6L2.js.map → chunk-ORRLYFKA.js.map} +0 -0
  85. /package/dist/chunks/{chunk-CXTTLBUV.js.map → chunk-R2XQ6AHT.js.map} +0 -0
  86. /package/dist/chunks/{chunk-DSNR5U7X.js.map → chunk-UQWBZKAN.js.map} +0 -0
  87. /package/dist/chunks/{chunk-S6BFCVOG.js.map → chunk-VYWJVAK5.js.map} +0 -0
  88. /package/dist/chunks/{chunk-XBGOJJQW.js.map → chunk-WQ6LC2KK.js.map} +0 -0
  89. /package/dist/chunks/{chunk-3DUKKQHN.js.map → chunk-ZQMBS5SH.js.map} +0 -0
@@ -53,22 +53,6 @@ export declare function fabricExtensionEntries(moduleUrl?: string): string[];
53
53
  * installed extension registers the provider.
54
54
  */
55
55
  export declare function resolveExtensionProviders(options: ResolveExtensionProvidersOptions, sdk?: PiSdk): Promise<ExtensionProviderRegistrations | undefined>;
56
- /**
57
- * The SDK entry of the bundled Pi CLI running this process, if it is one. The
58
- * published `pi` bin is `dist/bundle/cli.js`; its `dist/bundle/index.js` SDK
59
- * entry is built from the same chunks the CLI has already evaluated.
60
- */
61
- export declare function hostBundleSdkEntry(cliPath?: string | undefined): string | undefined;
62
- /**
63
- * The host's own SDK. Pi imports this bridge natively (it is ESM JavaScript),
64
- * so jiti's virtual modules do not apply, and a bare package import from here
65
- * evaluates the separate unbundled SDK: about 1,800 more modules in the
66
- * bundled CLI. Besides the startup cost, that CLI enables Node's compile cache,
67
- * which serializes every one of those modules on exit; with a cold cache that
68
- * held a Windows child past the worker's exit grace after it had settled.
69
- * The bundle's SDK entry shares the CLI's already loaded chunks instead.
70
- */
71
- export declare function loadHostSdk(cliPath?: string | undefined): Promise<PiSdk>;
72
56
  /**
73
57
  * Loaded with `-e` into Pi children launched with `extensions: false`. It
74
58
  * registers only the requested model's provider, as its extension registered
@@ -1 +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;AAcD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,SAAkB,GAAG,MAAM,EAAE,CAgB5E;AA0CD;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,gCAAgC,EACzC,GAAG,CAAC,EAAE,KAAK,GACV,OAAO,CAAC,8BAA8B,GAAG,SAAS,CAAC,CA4CrD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,MAAM,GAAG,SAA2B,GAAG,MAAM,GAAG,SAAS,CAiBpG;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,MAAM,GAAG,SAA2B,GAAG,OAAO,CAAC,KAAK,CAAC,CAU/F;AAED;;;;;GAKG;AACH,wBAA8B,oBAAoB,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAQlF"}
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;AAGrG;;;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;AAcD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,SAAkB,GAAG,MAAM,EAAE,CAgB5E;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"}
@@ -1,7 +1,11 @@
1
+ import {
2
+ loadHostSdk
3
+ } from "../chunks/chunk-GQGXQCCO.js";
4
+
1
5
  // src/agents/provider-bridge.ts
2
6
  import fs from "node:fs";
3
7
  import path from "node:path";
4
- import { fileURLToPath, pathToFileURL } from "node:url";
8
+ import { fileURLToPath } from "node:url";
5
9
  var PROVIDER_BRIDGE_MODEL_ENV = "PI_FABRIC_EXTENSION_MODEL";
6
10
  function parseModelKey(key) {
7
11
  const value = key.trim();
@@ -93,34 +97,6 @@ async function resolveExtensionProviders(options, sdk) {
93
97
  `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(", ")}.` : "")
94
98
  );
95
99
  }
96
- function hostBundleSdkEntry(cliPath = process.argv[1]) {
97
- if (!cliPath) return void 0;
98
- let cli;
99
- try {
100
- cli = fs.realpathSync(cliPath);
101
- } catch {
102
- return void 0;
103
- }
104
- const bundle = path.dirname(cli);
105
- if (path.basename(cli) !== "cli.js" || path.basename(bundle) !== "bundle") return void 0;
106
- const entry = path.join(bundle, "index.js");
107
- try {
108
- const manifest = JSON.parse(fs.readFileSync(path.join(bundle, "..", "..", "package.json"), "utf8"));
109
- return manifest.name === "@earendil-works/pi-coding-agent" && fs.existsSync(entry) ? entry : void 0;
110
- } catch {
111
- return void 0;
112
- }
113
- }
114
- async function loadHostSdk(cliPath = process.argv[1]) {
115
- const entry = hostBundleSdkEntry(cliPath);
116
- if (entry) {
117
- try {
118
- return await import(pathToFileURL(entry).href);
119
- } catch {
120
- }
121
- }
122
- return import("@earendil-works/pi-coding-agent");
123
- }
124
100
  async function fabricProviderBridge(pi) {
125
101
  const model = process.env[PROVIDER_BRIDGE_MODEL_ENV]?.trim();
126
102
  if (!model) return;
@@ -134,8 +110,6 @@ export {
134
110
  PROVIDER_BRIDGE_MODEL_ENV,
135
111
  fabricProviderBridge as default,
136
112
  fabricExtensionEntries,
137
- hostBundleSdkEntry,
138
- loadHostSdk,
139
113
  orderProviderCandidates,
140
114
  parseModelKey,
141
115
  resolveExtensionProviders
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/agents/provider-bridge.ts"],
4
- "sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } 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/** A manifest entry that loads a Pi package Fabric bundles (`node_modules/<package>/...`). */\nconst isBundledPackageEntry = (entry: string): boolean =>\n entry.replace(/\\\\/g, \"/\").replace(/^(?:\\.\\/)+/, \"\").startsWith(\"node_modules/\");\n\n/**\n * Fabric's own manifest entries: they never register chat providers. Entries\n * of bundled Pi packages (pi-coralbricks-provider) are not Fabric's own: they\n * stay probe candidates, so the bundled provider resolves without loading\n * Fabric's main extension.\n */\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\n .filter((entry): entry is string => typeof entry === \"string\" && !isBundledPackageEntry(entry))\n .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 * The SDK entry of the bundled Pi CLI running this process, if it is one. The\n * published `pi` bin is `dist/bundle/cli.js`; its `dist/bundle/index.js` SDK\n * entry is built from the same chunks the CLI has already evaluated.\n */\nexport function hostBundleSdkEntry(cliPath: string | undefined = process.argv[1]): string | undefined {\n if (!cliPath) return undefined;\n let cli: string;\n try {\n cli = fs.realpathSync(cliPath);\n } catch {\n return undefined;\n }\n const bundle = path.dirname(cli);\n if (path.basename(cli) !== \"cli.js\" || path.basename(bundle) !== \"bundle\") return undefined;\n const entry = path.join(bundle, \"index.js\");\n try {\n const manifest = JSON.parse(fs.readFileSync(path.join(bundle, \"..\", \"..\", \"package.json\"), \"utf8\")) as { name?: unknown };\n return manifest.name === \"@earendil-works/pi-coding-agent\" && fs.existsSync(entry) ? entry : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The host's own SDK. Pi imports this bridge natively (it is ESM JavaScript),\n * so jiti's virtual modules do not apply, and a bare package import from here\n * evaluates the separate unbundled SDK: about 1,800 more modules in the\n * bundled CLI. Besides the startup cost, that CLI enables Node's compile cache,\n * which serializes every one of those modules on exit; with a cold cache that\n * held a Windows child past the worker's exit grace after it had settled.\n * The bundle's SDK entry shares the CLI's already loaded chunks instead.\n */\nexport async function loadHostSdk(cliPath: string | undefined = process.argv[1]): Promise<PiSdk> {\n const entry = hostBundleSdkEntry(cliPath);\n if (entry) {\n try {\n return await import(pathToFileURL(entry).href) as PiSdk;\n } catch {\n // Unexpected bundle layout: fall back to the package entry.\n }\n }\n return import(\"@earendil-works/pi-coding-agent\");\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 sdk = await loadHostSdk();\n const found = await resolveExtensionProviders({ model, cwd: process.cwd(), agentDir: sdk.getAgentDir() }, sdk);\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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",
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\";\nimport { loadHostSdk } from \"../core/host-sdk.js\";\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/** A manifest entry that loads a Pi package Fabric bundles (`node_modules/<package>/...`). */\nconst isBundledPackageEntry = (entry: string): boolean =>\n entry.replace(/\\\\/g, \"/\").replace(/^(?:\\.\\/)+/, \"\").startsWith(\"node_modules/\");\n\n/**\n * Fabric's own manifest entries: they never register chat providers. Entries\n * of bundled Pi packages (pi-coralbricks-provider) are not Fabric's own: they\n * stay probe candidates, so the bundled provider resolves without loading\n * Fabric's main extension.\n */\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\n .filter((entry): entry is string => typeof entry === \"string\" && !isBundledPackageEntry(entry))\n .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 sdk = await loadHostSdk();\n const found = await resolveExtensionProviders({ model, cwd: process.cwd(), agentDir: sdk.getAgentDir() }, sdk);\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
6
  "names": []
7
7
  }
@@ -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;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"}
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;AAkLF,eAAO,MAAM,4BAA4B,GACvC,SAAS,4BAA4B,KACpC,OAAO,CAAC,+BAA+B,CA0CzC,CAAC"}
@@ -49,13 +49,38 @@ function checkRequest(value, maxBytes) {
49
49
  }
50
50
  }
51
51
  var probability = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 && v <= 1;
52
+ function reportedUsage(value) {
53
+ if (!object(value) || !object(value.usage)) return void 0;
54
+ const { input_tokens, output_tokens } = value.usage;
55
+ return [input_tokens, output_tokens].every((v) => Number.isSafeInteger(v) && v >= 0) ? { input_tokens, output_tokens } : void 0;
56
+ }
57
+ var JevBilledError = class extends Error {
58
+ constructor(message, usage) {
59
+ super(message);
60
+ this.usage = usage;
61
+ }
62
+ };
63
+ var JevInvalidResponseError = class extends JevBilledError {
64
+ };
65
+ var JEV_TRANSIENT_HTTP_STATUSES = [408, 429, 500, 502, 503, 504, 529];
66
+ var JevTransientHttpError = class extends JevBilledError {
67
+ constructor(message, usage, status, retryAfterMs) {
68
+ super(message, usage);
69
+ this.status = status;
70
+ this.retryAfterMs = retryAfterMs;
71
+ }
72
+ get guestFields() {
73
+ return { status: this.status, ...this.retryAfterMs === void 0 ? {} : { retryAfterMs: this.retryAfterMs } };
74
+ }
75
+ };
52
76
  function checkResponse(value, request) {
77
+ const message = "TypeSafe returned an invalid typed response";
78
+ const reported = reportedUsage(value);
79
+ if (!reported || !object(value)) throw new Error(message);
53
80
  const invalid = () => {
54
- throw new Error("TypeSafe returned an invalid typed response");
81
+ throw new JevInvalidResponseError(message, reported);
55
82
  };
56
- if (!object(value) || typeof value.model !== "string" || value.model.length > 128 || !object(value.answers) || !object(value.usage)) return invalid();
57
- const usage = value.usage;
58
- if (![usage.input_tokens, usage.output_tokens].every((v) => Number.isSafeInteger(v) && v >= 0)) return invalid();
83
+ if (typeof value.model !== "string" || value.model.length > 128 || !object(value.answers)) return invalid();
59
84
  if (Object.keys(value.answers).length !== Object.keys(request.questions).length) return invalid();
60
85
  const entries = [];
61
86
  for (const [id, question] of Object.entries(request.questions)) {
@@ -79,10 +104,7 @@ function checkResponse(value, request) {
79
104
  entries.push([id, { type: "score", score: a.score, confidence: a.confidence, probabilities, legend }]);
80
105
  }
81
106
  }
82
- return { model: value.model, answers: Object.fromEntries(entries), usage: {
83
- input_tokens: usage.input_tokens,
84
- output_tokens: usage.output_tokens
85
- } };
107
+ return { model: value.model, answers: Object.fromEntries(entries), usage: reported };
86
108
  }
87
109
  var schemaKeys = /* @__PURE__ */ new Set(["type", "properties", "required", "additionalProperties", "items", "enum", "const", "anyOf", "oneOf", "allOf", "minimum", "maximum", "minLength", "maxLength", "minItems", "maxItems", "minProperties", "maxProperties", "description", "title"]);
88
110
  function checkSchema(schema) {
@@ -118,8 +140,13 @@ export {
118
140
  jsonText,
119
141
  object,
120
142
  checkRequest,
143
+ reportedUsage,
144
+ JevBilledError,
145
+ JevInvalidResponseError,
146
+ JEV_TRANSIENT_HTTP_STATUSES,
147
+ JevTransientHttpError,
121
148
  checkResponse,
122
149
  checkSchema,
123
150
  checkValue
124
151
  };
125
- //# sourceMappingURL=chunk-WHBJDTCR.js.map
152
+ //# sourceMappingURL=chunk-7PPIKFT5.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/jev/validation.ts"],
4
+ "sourcesContent": ["import { Value } from \"typebox/value\";\nimport { isJevModelId } from \"./routes.js\";\nimport type { JevJson, JevRequest, JevResponse, JevAnswer } from \"./types.js\";\n\nexport function jsonText(value: unknown, maxBytes: number, label: string): string {\n let nodes = 0;\n const visit = (v: unknown, depth: number): void => {\n if (++nodes > 100_000 || depth > 32) throw new Error(`${label} exceeds JSON complexity limits`);\n if (v === null || typeof v === \"string\" || typeof v === \"boolean\") return;\n if (typeof v === \"number\" && Number.isFinite(v)) return;\n if (Array.isArray(v)) { for (const item of v) visit(item, depth + 1); return; }\n if (typeof v === \"object\" && v !== null && Object.getPrototypeOf(v) === Object.prototype) {\n for (const item of Object.values(v)) visit(item, depth + 1);\n return;\n }\n throw new Error(`${label} must contain only finite JSON values`);\n };\n visit(value, 0);\n const text = JSON.stringify(value);\n if (Buffer.byteLength(text) > maxBytes) throw new Error(`${label} exceeds ${maxBytes} bytes`);\n return text;\n}\nexport const object = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst description = (v: unknown): boolean => typeof v === \"string\" || object(v) || Array.isArray(v);\nconst keysOnly = (v: Record<string, unknown>, keys: string[]) => Object.keys(v).every(k => keys.includes(k));\n\nexport function checkRequest(value: unknown, maxBytes: number): asserts value is JevRequest {\n jsonText(value, maxBytes, \"Jev request\");\n if (!object(value) || !keysOnly(value, [\"state\", \"questions\", \"model\"]) || !description(value.state) ||\n !object(value.questions) || Object.keys(value.questions).length < 1 || Object.keys(value.questions).length > 128 ||\n (value.model !== undefined && (typeof value.model !== \"string\" || !isJevModelId(value.model)))) {\n throw new Error(\"Invalid Jev request: provide state, 1\u2013128 questions, and an optional model ID\");\n }\n for (const [id, q] of Object.entries(value.questions)) {\n if (!id || id.length > 128 || !object(q) || !keysOnly(q, [\"type\", \"instructions\", \"criteria\"]) || !description(q.instructions))\n throw new Error(\"Invalid Jev question: each question needs a type and complete instructions\");\n if (q.type === \"choice\") {\n if (!object(q.criteria) || Object.keys(q.criteria).length < 1 || Object.keys(q.criteria).length > 255 ||\n !Object.entries(q.criteria).every(([key, v]) => key.length > 0 && key.length <= 256 && (v === null || description(v))))\n throw new Error(\"Choice requires 1\u2013255 named options with descriptions or null\");\n } else if (q.type === \"score\") {\n if (!Array.isArray(q.criteria) || q.criteria.length < 2 || q.criteria.length > 10 || !q.criteria.every(description))\n throw new Error(\"Score requires 2\u201310 ordered descriptive levels\");\n } else if (q.type === \"noul\") {\n if (q.criteria !== undefined && (!object(q.criteria) || !keysOnly(q.criteria, [\"true\", \"false\"]) || !Object.values(q.criteria).every(description)))\n throw new Error(\"Noul criteria may describe true and false only\");\n } else throw new Error(\"Jev supports choice, score, and noul\u2014not free-text generation\");\n }\n}\nconst probability = (v: unknown): v is number => typeof v === \"number\" && Number.isFinite(v) && v >= 0 && v <= 1;\nexport interface JevUsage { input_tokens: number; output_tokens: number }\n/** Well-formed reported usage, or undefined. Never treats missing usage as zero. */\nexport function reportedUsage(value: unknown): JevUsage | undefined {\n if (!object(value) || !object(value.usage)) return undefined;\n const { input_tokens, output_tokens } = value.usage;\n return [input_tokens, output_tokens].every(v => Number.isSafeInteger(v) && (v as number) >= 0)\n ? { input_tokens: input_tokens as number, output_tokens: output_tokens as number } : undefined;\n}\n/**\n * A failed evaluation whose cost is known. A program bills `usage` and may\n * keep evaluating; every other failure is unknown usage and closes inference.\n */\nexport class JevBilledError extends Error {\n constructor(message: string, readonly usage: JevUsage) { super(message); }\n}\n/**\n * A typed response whose answers are unusable but whose usage is well formed.\n * The answers are never surfaced; the reported usage is still billed against\n * the caller's budget. Responses without valid usage throw a plain Error.\n */\nexport class JevInvalidResponseError extends JevBilledError {}\n/** HTTP statuses a received Jev response may carry that justify a later retry. */\nexport const JEV_TRANSIENT_HTTP_STATUSES: readonly number[] = [408, 429, 500, 502, 503, 504, 529];\n/**\n * A received transient HTTP error. `usage` is the error body's reported usage,\n * or the fixed cost: the request body's UTF-8 bytes as input tokens, 0 output.\n * `guestFields` crosses into the program's error object; the body never does.\n */\nexport class JevTransientHttpError extends JevBilledError {\n constructor(message: string, usage: JevUsage, readonly status: number, readonly retryAfterMs: number | undefined) { super(message, usage); }\n get guestFields(): Record<string, number> {\n return { status: this.status, ...(this.retryAfterMs === undefined ? {} : { retryAfterMs: this.retryAfterMs }) };\n }\n}\nexport function checkResponse(value: unknown, request: JevRequest): JevResponse {\n const message = \"TypeSafe returned an invalid typed response\";\n const reported = reportedUsage(value);\n if (!reported || !object(value)) throw new Error(message);\n const invalid = (): never => { throw new JevInvalidResponseError(message, reported); };\n if (typeof value.model !== \"string\" || value.model.length > 128 || !object(value.answers)) return invalid();\n if (Object.keys(value.answers).length !== Object.keys(request.questions).length) return invalid();\n const entries: Array<[string, JevAnswer]> = [];\n for (const [id, question] of Object.entries(request.questions)) {\n const a = Object.hasOwn(value.answers, id) ? value.answers[id] : undefined;\n if (!object(a) || a.type !== question.type) return invalid();\n if (question.type === \"noul\") {\n if (!probability(a.noul)) return invalid();\n entries.push([id, { type: \"noul\", noul: a.noul }]);\n continue;\n }\n const keys = question.type === \"choice\" ? Object.keys(question.criteria) : question.criteria.map((_, i) => String(i));\n const p = a.probabilities;\n if (!probability(a.confidence) || !object(p) || Object.keys(p).length !== keys.length ||\n !keys.every(k => Object.hasOwn(p, k) && probability(p[k])) ||\n Math.abs(Object.values(p).reduce<number>((sum, v) => sum + (v as number), 0) - 1) > 0.02) return invalid();\n const probabilities = Object.fromEntries(keys.map(k => [k, p[k] as number]));\n if (question.type === \"choice\") {\n if (typeof a.choice !== \"string\" || !Object.hasOwn(question.criteria, a.choice)) return invalid();\n entries.push([id, { type: \"choice\", choice: a.choice, confidence: a.confidence, probabilities }]);\n } else {\n if (typeof a.score !== \"number\" || !Number.isFinite(a.score) || a.score < 0 || a.score > keys.length - 1) return invalid();\n // Rubrics come from the request, not arbitrary server-produced content.\n const legend = Object.fromEntries(question.criteria.map((level, i) => [String(i), level]));\n entries.push([id, { type: \"score\", score: a.score, confidence: a.confidence, probabilities, legend }]);\n }\n }\n return { model: value.model, answers: Object.fromEntries(entries), usage: reported };\n}\n\nconst schemaKeys = new Set([\"type\", \"properties\", \"required\", \"additionalProperties\", \"items\", \"enum\", \"const\", \"anyOf\", \"oneOf\", \"allOf\", \"minimum\", \"maximum\", \"minLength\", \"maxLength\", \"minItems\", \"maxItems\", \"minProperties\", \"maxProperties\", \"description\", \"title\"]);\nexport function checkSchema(schema: unknown): asserts schema is Record<string, unknown> {\n jsonText(schema, 16_384, \"Program schema\");\n let nodes = 0;\n const visit = (s: unknown, depth: number): void => {\n if (!object(s) || ++nodes > 128 || depth > 12 || Object.keys(s).some(k => !schemaKeys.has(k)))\n throw new Error(\"Unsupported program schema; use the documented bounded JSON Schema subset (no references or regexes)\");\n if (s.type !== undefined && ![\"object\", \"array\", \"string\", \"number\", \"integer\", \"boolean\", \"null\"].includes(s.type as string)) throw new Error(\"Invalid schema type\");\n if (s.properties !== undefined) {\n if (!object(s.properties)) throw new Error(\"Schema properties must be an object\");\n Object.values(s.properties).forEach(v => visit(v, depth + 1));\n }\n if (s.required !== undefined && (!Array.isArray(s.required) || !s.required.every(v => typeof v === \"string\"))) throw new Error(\"Schema required must be a string array\");\n if (s.additionalProperties !== undefined && typeof s.additionalProperties !== \"boolean\") visit(s.additionalProperties, depth + 1);\n if (s.items !== undefined) visit(s.items, depth + 1);\n for (const k of [\"anyOf\", \"oneOf\", \"allOf\"]) if (s[k] !== undefined) {\n if (!Array.isArray(s[k]) || s[k].length < 1 || s[k].length > 16) throw new Error(\"Invalid schema alternatives\");\n s[k].forEach(v => visit(v, depth + 1));\n }\n for (const k of [\"minimum\", \"maximum\", \"minLength\", \"maxLength\", \"minItems\", \"maxItems\", \"minProperties\", \"maxProperties\"])\n if (s[k] !== undefined && (typeof s[k] !== \"number\" || !Number.isFinite(s[k]) || (!['minimum', 'maximum'].includes(k) && (!Number.isSafeInteger(s[k]) || s[k] < 0)))) throw new Error(\"Invalid schema bound\");\n if (s.enum !== undefined && (!Array.isArray(s.enum) || s.enum.length === 0 || s.enum.length > 256)) throw new Error(\"Invalid schema enum\");\n };\n visit(schema, 0);\n}\nexport function checkValue(schema: Record<string, unknown>, value: unknown, label: string): asserts value is JevJson {\n jsonText(value, 32_768, label);\n if (!Value.Check(schema, value)) throw new Error(`${label} does not match its declared schema`);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -28,6 +28,9 @@ import {
28
28
  safeTerminalText,
29
29
  singleCallProgressLine
30
30
  } from "./chunk-U2UBUKNQ.js";
31
+ import {
32
+ FabricModelSelector
33
+ } from "./chunk-J7ZQERKA.js";
31
34
  import {
32
35
  configureHighlighting,
33
36
  highlightCode,
@@ -38,9 +41,6 @@ import {
38
41
  isActiveStatus,
39
42
  orderAgentsByCreation
40
43
  } from "./chunk-UTOBAZ5T.js";
41
- import {
42
- FabricModelSelector
43
- } from "./chunk-J7ZQERKA.js";
44
44
  import {
45
45
  buildModelSource
46
46
  } from "./chunk-CQFP2RCP.js";
@@ -83,7 +83,7 @@ import {
83
83
  resolveFabricIdentity,
84
84
  setModelSafely,
85
85
  withTrajectoryRearmDirective
86
- } from "./chunk-GYPDGW27.js";
86
+ } from "./chunk-QGP7AY2R.js";
87
87
  import {
88
88
  AgentTranscriptReader,
89
89
  countNewlines,
@@ -113,13 +113,13 @@ import {
113
113
  buildPeerCards,
114
114
  readChildToolAllowlist
115
115
  } from "./chunk-PYFJW3HC.js";
116
+ import {
117
+ resolveAgentDir
118
+ } from "./chunk-PBDDXBHY.js";
116
119
  import {
117
120
  closeScratch,
118
121
  createScratch
119
122
  } from "./chunk-5XBYFSI5.js";
120
- import {
121
- resolveAgentDir
122
- } from "./chunk-PXAICAUT.js";
123
123
  import {
124
124
  DEFAULT_FABRIC_CONFIG,
125
125
  NO_FOREGROUND,
@@ -138,7 +138,7 @@ import {
138
138
  fabricExecTitleHintCached,
139
139
  normalizeRunDisplay,
140
140
  registerCompactionHook
141
- } from "./chunk-2TJHOQGO.js";
141
+ } from "./chunk-TNPZBMYC.js";
142
142
  import {
143
143
  fabricWriteBindings
144
144
  } from "./chunk-SZUXWOO7.js";
@@ -160,7 +160,7 @@ import {
160
160
  ApprovalController,
161
161
  FabricAutoApprovalClassifier,
162
162
  FabricSessionApprovals
163
- } from "./chunk-DSNR5U7X.js";
163
+ } from "./chunk-UQWBZKAN.js";
164
164
  import {
165
165
  getActiveRepairCompiler,
166
166
  setActiveCompiledSurface
@@ -675,30 +675,52 @@ var entryRealmPackageRoot = () => {
675
675
  }
676
676
  return void 0;
677
677
  };
678
+ var realPath = (file) => {
679
+ try {
680
+ return realpathSync(file);
681
+ } catch {
682
+ return file;
683
+ }
684
+ };
685
+ var isWithin = (directory, file) => {
686
+ const relative = path.relative(directory, file);
687
+ return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative);
688
+ };
689
+ var exportedExtensionRunner = async (entry) => {
690
+ try {
691
+ const module = await import(pathToFileURL(entry).href);
692
+ return isExtensionRunnerConstructor(module.ExtensionRunner) ? [module.ExtensionRunner] : [];
693
+ } catch {
694
+ return [];
695
+ }
696
+ };
697
+ var packageExtensionRunnerConstructors = async (packageRoot, entry) => {
698
+ const distDirectory = path.join(packageRoot, "dist");
699
+ const bundleDirectory = path.join(distDirectory, "bundle");
700
+ if (entry && isWithin(bundleDirectory, entry)) {
701
+ const bundled = await exportedExtensionRunner(path.join(bundleDirectory, "index.js"));
702
+ return bundled.length > 0 ? bundled : bundleExtensionRunnerConstructors(bundleDirectory);
703
+ }
704
+ const unbundled = await exportedExtensionRunner(path.join(distDirectory, "index.js"));
705
+ if (entry && isWithin(distDirectory, entry)) return unbundled;
706
+ return [...unbundled, ...await bundleExtensionRunnerConstructors(bundleDirectory)];
707
+ };
678
708
  var extensionRunnerConstructors = async () => {
679
709
  const constructors = /* @__PURE__ */ new Set();
710
+ const advertised = globalThis[HOST_RUNNERS_SYMBOL];
711
+ for (const Runner of advertised instanceof Set ? advertised : []) {
712
+ if (isExtensionRunnerConstructor(Runner)) constructors.add(Runner);
713
+ }
714
+ if (constructors.size > 0) return [...constructors];
680
715
  const packageRoots = new Set(
681
- [process.env.PI_PACKAGE_DIR, hostPackageRoot(), entryRealmPackageRoot()].filter(
682
- (root) => typeof root === "string" && Boolean(root)
683
- )
716
+ [process.env.PI_PACKAGE_DIR, hostPackageRoot(), entryRealmPackageRoot()].filter((root) => typeof root === "string" && Boolean(root)).map(realPath)
684
717
  );
718
+ const entry = process.argv[1] ? realPath(process.argv[1]) : void 0;
685
719
  for (const packageRoot of packageRoots) {
686
- try {
687
- const hostEntry = path.join(packageRoot, "dist", "index.js");
688
- const hostModule = await import(pathToFileURL(hostEntry).href);
689
- if (hostModule.ExtensionRunner) constructors.add(hostModule.ExtensionRunner);
690
- } catch {
691
- }
692
- for (const Runner of await bundleExtensionRunnerConstructors(
693
- path.join(packageRoot, "dist", "bundle")
694
- )) {
720
+ for (const Runner of await packageExtensionRunnerConstructors(packageRoot, entry)) {
695
721
  constructors.add(Runner);
696
722
  }
697
723
  }
698
- const advertised = globalThis[HOST_RUNNERS_SYMBOL];
699
- for (const Runner of advertised instanceof Set ? advertised : []) {
700
- if (isExtensionRunnerConstructor(Runner)) constructors.add(Runner);
701
- }
702
724
  if (constructors.size === 0) {
703
725
  try {
704
726
  const hostModule = await import("@earendil-works/pi-coding-agent");
@@ -747,9 +769,6 @@ var installRegisteredToolCapture = async (options) => {
747
769
  };
748
770
  };
749
771
 
750
- // src/commands/fabric.ts
751
- import "@earendil-works/pi-coding-agent";
752
-
753
772
  // src/prewalk/arm.ts
754
773
  var armFabricPrewalkSession = async (state, context, pi, input) => {
755
774
  const { prewalk } = state.config;
@@ -4338,7 +4357,6 @@ var piHostCompatibilityWarning = (version = detectPiHostVersion()) => {
4338
4357
 
4339
4358
  // src/ui/controller.ts
4340
4359
  import path9 from "node:path";
4341
- import * as piConversationHost from "@earendil-works/pi-coding-agent";
4342
4360
 
4343
4361
  // src/ui/snapshot.ts
4344
4362
  import { isDeepStrictEqual } from "node:util";
@@ -5061,9 +5079,10 @@ var FabricUiController = class {
5061
5079
  this.#conversationOpen = true;
5062
5080
  const epoch = this.#epoch;
5063
5081
  try {
5064
- const { initializeConversationHost } = await import("../ui/conversation-host.js");
5082
+ const [{ initializeConversationHost }, { loadHostSdk }] = await Promise.all([import("../ui/conversation-host.js"), import("../core/host-sdk.js")]);
5083
+ const conversationHost = await loadHostSdk();
5065
5084
  if (epoch !== this.#epoch) return;
5066
- initializeConversationHost(piConversationHost);
5085
+ initializeConversationHost(conversationHost);
5067
5086
  const [{ FabricConversationView, FabricConversationState }, { conversationTargets, resolveConversationTarget }, { readConversationAppearance }, { NativeConversationReader }, { imageSafeCustom }] = await Promise.all([import("../ui/conversation.js"), import("../ui/conversation-targets.js"), import("../ui/conversation-chrome.js"), import("../ui/conversation-native-reader.js"), import("../ui/image-overlays.js")]);
5068
5087
  if (epoch !== this.#epoch) return;
5069
5088
  this.#refresh();
@@ -6602,4 +6621,4 @@ export {
6602
6621
  FABRIC_MANAGED_HOST_VERSION,
6603
6622
  createFabricExtension
6604
6623
  };
6605
- //# sourceMappingURL=chunk-BEP6VFL2.js.map
6624
+ //# sourceMappingURL=chunk-GFBOLBU2.js.map