pi2dsh 0.21.0 → 0.23.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 +9 -6
- package/README.zh.md +8 -5
- package/dist/{analyzer-LpQ59yjZ.mjs → analyzer-C139Y2S7.mjs} +2 -2
- package/dist/{analyzer-LpQ59yjZ.mjs.map → analyzer-C139Y2S7.mjs.map} +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/{compatibility-CsJEjhu8.mjs → compatibility-CZs3LwYn.mjs} +6 -6
- package/dist/compatibility-CZs3LwYn.mjs.map +1 -0
- package/dist/host.mjs +1 -1
- package/dist/index.d.mts +10 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +12 -5
- package/dist/index.mjs.map +1 -1
- package/dist/{runtime-CGDq6LKi.mjs → runtime-Dnk9mhrc.mjs} +72 -6
- package/dist/runtime-Dnk9mhrc.mjs.map +1 -0
- package/dist/runtime.d.mts +2 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -1
- package/package.json +12 -19
- package/dist/client.js +0 -834
- package/dist/compatibility-CsJEjhu8.mjs.map +0 -1
- package/dist/runtime-CGDq6LKi.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -199,10 +199,11 @@ it work. **This is the list to trust.**
|
|
|
199
199
|
| [`@kassing/pi-vision`](https://www.npmjs.com/package/@kassing/pi-vision) | Image analysis delegated to a vision model; image-admission companion route; analysis injected into a text-only model's turn | CLI + web | [`vision-bridge`](examples/vision-bridge/) |
|
|
200
200
|
| [`@crazygit/pi-codex-image-gen`](https://www.npmjs.com/package/@crazygit/pi-codex-image-gen) | ChatGPT/Codex OAuth → `gpt-image-2` generation; local reference-image upload through DSH approval; image edit; native attachment storage and inline Web rendering | CLI + web | [`codex-image-gen`](examples/codex-image-gen/) |
|
|
201
201
|
| [`pi-btw`](https://www.npmjs.com/package/pi-btw) | `/btw <question>` as a real child session in DSH's subagent UI; `/btw-inject`; `/btw --save`; main thread stays clean | CLI + web | [`side-conversation`](examples/side-conversation/) |
|
|
202
|
-
| [`pi-powerline-footer`](https://www.npmjs.com/package/pi-powerline-footer) | A terminal status line — model, thinking level, project, context usage — drawn
|
|
203
|
-
| [`pi-mcp-adapter`](https://www.npmjs.com/package/pi-mcp-adapter) | Original full-screen manager; stdio/Streamable HTTP/SSE; discovery, direct/proxy/scripted calls, resources, prompts, images, structured content, MCP Apps, approval, elicitation, sampling, cancellation and restart through DSH runtimes | dsh-TUI + dsh-pi-tui | [`tui-mcp`](examples/tui-mcp/) · [`pi-tui-ecosystem`](examples/pi-tui-ecosystem/) · [evidence matrix](docs/mcp-compatibility.md) |
|
|
202
|
+
| [`pi-powerline-footer`](https://www.npmjs.com/package/pi-powerline-footer) | A terminal status line — model, thinking level, project, context usage — drawn as a floating status pill in DSH web, colour included | web | [`presentation-surfaces`](examples/presentation-surfaces/) |
|
|
203
|
+
| [`pi-mcp-adapter`](https://www.npmjs.com/package/pi-mcp-adapter) | Original full-screen manager; stdio/Streamable HTTP/SSE; discovery, direct/proxy/scripted calls, resources, prompts, images, structured content, MCP Apps, approval, elicitation, sampling, cancellation and restart through DSH runtimes | CLI + web + dsh-TUI + dsh-pi-tui | [`tui-mcp`](examples/tui-mcp/) · [`mcp-at-scale`](examples/mcp-at-scale/) · [`pi-tui-ecosystem`](examples/pi-tui-ecosystem/) · [evidence matrix](docs/mcp-compatibility.md) |
|
|
204
204
|
| [`@tintinweb/pi-subagents`](https://www.npmjs.com/package/@tintinweb/pi-subagents) | The model delegates to autonomous subagents: spawn (with real host-native tools), background + completion notify, mid-run steer, wait-for-result, resume with memory, stop that stays stopped, interactive manager, and cross-restart reopen by archive identity — every child a native DSH session | CLI + dsh-TUI + dsh-pi-tui | [`subagents`](examples/subagents/) · [`pi-tui-ecosystem`](examples/pi-tui-ecosystem/) · [acceptance report](community/subagents-acceptance-report.md) |
|
|
205
205
|
| [`pi-provider-alibaba`](https://www.npmjs.com/package/pi-provider-alibaba) | Alibaba Token Plan (CN) with its plan-specific key: live catalog, cold-start dynamic model, complete tool loop and restart. The package also declares Coding/API routes, but each requires its own non-interchangeable credential | CLI + web | [`alibaba-token-plan`](examples/alibaba-token-plan/) |
|
|
206
|
+
| [`@ff-labs/pi-fff`](https://www.npmjs.com/package/@ff-labs/pi-fff) + [`pi-lens`](https://www.npmjs.com/package/pi-lens) | Code navigation for the model: `ffgrep` content search finds a marker that exists in exactly one file, and `lsp_diagnostics` reports a planted TS2322 through a real local `typescript-language-server` — both asserted from the tools’ own results in the session log | CLI + web | [`code-navigation`](examples/code-navigation/) |
|
|
206
207
|
| [`pi-vision-tool`](https://www.npmjs.com/package/pi-vision-tool) | Tool registration through a JSON-Schema shape DSH had to convert (`anyOf` → `oneOf`) | CLI + web | — |
|
|
207
208
|
| [`pi-approval-guardian`](https://www.npmjs.com/package/pi-approval-guardian) | Every tool call reviewed by a second model before execution; allow and deny both observed | CLI (bare env) | — |
|
|
208
209
|
| [`pi-hermes-memory`](https://www.npmjs.com/package/pi-hermes-memory) | Cross-session memory: written in one process, read back in a second, fresh one | CLI | — |
|
|
@@ -300,7 +301,7 @@ rather than a behaviour lands there:
|
|
|
300
301
|
│ │ │ slot registry (ui-slots) │
|
|
301
302
|
│ pi2dsh engine │ │ shell.overlay ← panel, pills │
|
|
302
303
|
│ tools · commands · models · sessions │ │ session.header.utilities ← hdr │
|
|
303
|
-
│ subagent bridge ─────────────┐ │ │
|
|
304
|
+
│ subagent bridge ─────────────┐ │ │ overlay ← widget pills/cards │
|
|
304
305
|
│ browser-state registry │ │ │ composer.dock ← working/footer │
|
|
305
306
|
│ GET /pi2dsh/browser-state ─┼── own route┼──┼─▶ all four seats, one poller │
|
|
306
307
|
└────────────────────────────────┴────────────┘ └───────────────────────────────────┘
|
|
@@ -406,8 +407,8 @@ audit states this boundary explicitly.
|
|
|
406
407
|
| [Sessions & side conversations](docs/capabilities/sessions.md) | 24 | 7 same semantics · 17 mapped, difference stated |
|
|
407
408
|
| [Models, providers, credentials](docs/capabilities/models.md) | 15 | 1 same semantics · 12 mapped, difference stated · 2 not available |
|
|
408
409
|
| [Asking the user, rendering](docs/capabilities/interaction.md) | 24 | 5 same semantics · 19 mapped, difference stated |
|
|
409
|
-
| [Project environment & resources](docs/capabilities/environment.md) | 4 |
|
|
410
|
-
| **Total** | **111** | **
|
|
410
|
+
| [Project environment & resources](docs/capabilities/environment.md) | 4 | 2 same semantics · 2 not available |
|
|
411
|
+
| **Total** | **111** | **26 same semantics · 81 mapped, difference stated · 4 not available** |
|
|
411
412
|
<!-- capability-table:end -->
|
|
412
413
|
|
|
413
414
|
Plus **203 imported symbols** from Pi's three runtime packages
|
|
@@ -445,7 +446,7 @@ project trust is a host decision. See
|
|
|
445
446
|
renderers; today those registrations are accepted but not invoked, so such a
|
|
446
447
|
note appears as a native context-injection row — the content reaches you and
|
|
447
448
|
the model, without the plugin's styling. The client half exists and takes four
|
|
448
|
-
seats (side-conversation panel, header,
|
|
449
|
+
seats (side-conversation panel, header, floating widgets, working chrome) — the card
|
|
449
450
|
renderers are what it does not draw yet.
|
|
450
451
|
|
|
451
452
|
## Examples
|
|
@@ -463,7 +464,9 @@ in one has actually been executed against a real DSH loop before landing.
|
|
|
463
464
|
| [`gateway-compat`](examples/gateway-compat/) | Private / domestic / proxy gateways that reject the `developer` role: how rc.8's official profile carries Pi compat declarations to the wire (passthrough recorder included) |
|
|
464
465
|
| [`alibaba-token-plan`](examples/alibaba-token-plan/) | Use Alibaba Cloud Model Studio Plan routes through the original Pi provider; dynamic DeepSeek model, tool loop and restart included |
|
|
465
466
|
| [`custom-gateways`](examples/custom-gateways/) | Add any OpenAI-compatible gateway the official DSH way, and every Pi plugin sees it |
|
|
467
|
+
| [`code-navigation`](examples/code-navigation/) | Give the model real code-navigation tools — fuzzy content search and language-server diagnostics on a bundled sample project, CLI and web |
|
|
466
468
|
| [`tui-mcp`](examples/tui-mcp/) | Keep dsh-TUI's native `/mcp`, add the Pi ecosystem manager as `/pi-mcp`, and exercise its complete host-influenced MCP surface through DSH runtimes |
|
|
469
|
+
| [`mcp-at-scale`](examples/mcp-at-scale/) | A real 51-tool MCP server behind the adapter's two meta-tools: bounded tool surface, lazy discovery at scale, and a timeout budget that cuts a ~120 s tool to seconds — CLI and web |
|
|
467
470
|
| [`subagents`](examples/subagents/) | The model runs a small team: delegate, background, steer mid-run, collect, resume with memory, stop for real, manage via `/pi-agents`, reopen across restarts |
|
|
468
471
|
| [`pi-tui-ecosystem`](examples/pi-tui-ecosystem/) | Run the unmodified Pi MCP manager and Pi subagent flow in `@xmoon76/dsh-pi-tui`; native `/login` and Pi OAuth providers coexist without duplicate commands |
|
|
469
472
|
|
package/README.zh.md
CHANGED
|
@@ -163,10 +163,11 @@ DSH 模型运行时的 sampling、取消与会话重启。完整证据矩阵:
|
|
|
163
163
|
| [`@kassing/pi-vision`](https://www.npmjs.com/package/@kassing/pi-vision) | 图片委托给视觉模型;贴图伴生路由;分析结果注入纯文本模型的这一轮 | CLI + Web | [`vision-bridge`](examples/vision-bridge/) |
|
|
164
164
|
| [`@crazygit/pi-codex-image-gen`](https://www.npmjs.com/package/@crazygit/pi-codex-image-gen) | ChatGPT/Codex OAuth 调 `gpt-image-2` 生图;本地参考图走 DSH 审批后上传;编辑图片;原生附件存储并在 Web 内直接显示 | CLI + Web | [`codex-image-gen`](examples/codex-image-gen/) |
|
|
165
165
|
| [`pi-btw`](https://www.npmjs.com/package/pi-btw) | `/btw <问题>` 跑成 DSH 子代理界面里的真子会话;`/btw-inject`;`/btw --save`;主会话保持干净 | CLI + Web | [`side-conversation`](examples/side-conversation/) |
|
|
166
|
-
| [`pi-powerline-footer`](https://www.npmjs.com/package/pi-powerline-footer) |
|
|
167
|
-
| [`pi-mcp-adapter`](https://www.npmjs.com/package/pi-mcp-adapter) | 完整管理界面画进 dsh-TUI;stdio/Streamable HTTP/SSE;发现、直连/代理/脚本调用、resources、prompts、图片、结构化内容、MCP Apps、审批、elicitation、sampling、取消与重启全部穿过 DSH 运行时;原生 `/mcp` 与 `/pi-mcp` 共存 | dsh-TUI | [`tui-mcp`](examples/tui-mcp/) · [证据矩阵](docs/mcp-compatibility.md) |
|
|
166
|
+
| [`pi-powerline-footer`](https://www.npmjs.com/package/pi-powerline-footer) | 终端状态条(模型、思考档位、项目、上下文用量)以浮动状态胶囊画进 DSH web,带颜色 | Web | [`presentation-surfaces`](examples/presentation-surfaces/) |
|
|
167
|
+
| [`pi-mcp-adapter`](https://www.npmjs.com/package/pi-mcp-adapter) | 完整管理界面画进 dsh-TUI;stdio/Streamable HTTP/SSE;发现、直连/代理/脚本调用、resources、prompts、图片、结构化内容、MCP Apps、审批、elicitation、sampling、取消与重启全部穿过 DSH 运行时;原生 `/mcp` 与 `/pi-mcp` 共存 | CLI + Web + dsh-TUI | [`tui-mcp`](examples/tui-mcp/) · [`mcp-at-scale`](examples/mcp-at-scale/) · [证据矩阵](docs/mcp-compatibility.md) |
|
|
168
168
|
| [`@tintinweb/pi-subagents`](https://www.npmjs.com/package/@tintinweb/pi-subagents) | 模型自己带团队:派子代理(真宿主原生工具)、后台跑+完成通知、运行中转向、等结果、带记忆续命、真停得住的打断、`/pi-agents` 管理面、跨重启按归档身份重开——每个子代理都是原生 DSH 会话 | CLI + dsh-TUI | [`subagents`](examples/subagents/) · [验收报告](community/subagents-acceptance-report.md) |
|
|
169
169
|
| [`pi-provider-alibaba`](https://www.npmjs.com/package/pi-provider-alibaba) | 阿里云 Token Plan(中国区)专属 key:实时目录、冷启动动态模型、完整工具闭环与重启均已实测;包也声明 Coding/API 路由,但必须分别使用不可混用的专属凭证 | CLI + Web | [`alibaba-token-plan`](examples/alibaba-token-plan/) |
|
|
170
|
+
| [`@ff-labs/pi-fff`](https://www.npmjs.com/package/@ff-labs/pi-fff) + [`pi-lens`](https://www.npmjs.com/package/pi-lens) | 给模型真正的代码导航工具:`ffgrep` 内容搜索找到只存在于一个文件里的标记串,`lsp_diagnostics` 经真实的本地 `typescript-language-server` 报出植入的 TS2322 —— 两条都从会话日志里工具自己的结果断言 | CLI + Web | [`code-navigation`](examples/code-navigation/) |
|
|
170
171
|
| [`pi-vision-tool`](https://www.npmjs.com/package/pi-vision-tool) | 工具注册,且带一个 DSH 需要转换的 JSON Schema 形状(`anyOf` → `oneOf`) | CLI + Web | — |
|
|
171
172
|
| [`pi-approval-guardian`](https://www.npmjs.com/package/pi-approval-guardian) | 每次工具调用先由第二个模型审批;放行与拒绝两条路都看到了 | CLI(裸环境) | — |
|
|
172
173
|
| [`pi-hermes-memory`](https://www.npmjs.com/package/pi-hermes-memory) | 跨会话记忆:一个进程写入,另一个全新进程读回 | CLI | — |
|
|
@@ -250,7 +251,7 @@ DSH 有两半,桥也有两半。上面那根柱子是服务端;浏览器壳
|
|
|
250
251
|
│ │ │ slot 注册表(ui-slots) │
|
|
251
252
|
│ pi2dsh 引擎 │ │ shell.overlay ← 浮层与 pill │
|
|
252
253
|
│ 工具 · 命令 · 模型 · 会话 │ │ header.utilities ← 头部文本 │
|
|
253
|
-
│ 子代理桥 ───────────────────┐ │ │
|
|
254
|
+
│ 子代理桥 ───────────────────┐ │ │ overlay ← widget 胶囊/卡片 │
|
|
254
255
|
│ browser-state 注册表 │ │ │ composer.dock ← working/底部 │
|
|
255
256
|
│ GET /pi2dsh/browser-state┼── 自有通路 ─┼──┼─▶ 四个座位,共用一个轮询 │
|
|
256
257
|
└───────────────────────────────┴─────────────┘ └───────────────────────────────────┘
|
|
@@ -337,8 +338,8 @@ Pi 包能碰到的每一个面,以及它落到 DSH 的什么位置。下面这
|
|
|
337
338
|
| [会话与侧边对话](docs/capabilities/sessions.md) | 24 | 7 语义一致 · 17 已映射并写明差异 |
|
|
338
339
|
| [模型、provider、凭证](docs/capabilities/models.md) | 15 | 1 语义一致 · 12 已映射并写明差异 · 2 不提供 |
|
|
339
340
|
| [向用户提问与渲染](docs/capabilities/interaction.md) | 24 | 5 语义一致 · 19 已映射并写明差异 |
|
|
340
|
-
| [项目环境与资源](docs/capabilities/environment.md) | 4 |
|
|
341
|
-
| **合计** | **111** | **
|
|
341
|
+
| [项目环境与资源](docs/capabilities/environment.md) | 4 | 2 语义一致 · 2 不提供 |
|
|
342
|
+
| **合计** | **111** | **26 语义一致 · 81 已映射并写明差异 · 4 不提供** |
|
|
342
343
|
<!-- capability-table:end -->
|
|
343
344
|
|
|
344
345
|
另外还有 Pi 三个运行时包(`pi-coding-agent`、`pi-tui`、`pi-ai`)的 **203 个
|
|
@@ -384,7 +385,9 @@ loop 上实际跑过才会进来。
|
|
|
384
385
|
| [`gateway-compat`](examples/gateway-compat/) | 私有 / 国内 / 代理网关拒收 `developer` 角色:rc.8 官方 profile 如何把 Pi compat 声明送到真实请求(附透传录制代理) |
|
|
385
386
|
| [`alibaba-token-plan`](examples/alibaba-token-plan/) | 通过原版 Pi provider 使用阿里云百炼 Plan;包含动态 DeepSeek 模型、工具闭环与重启验证 |
|
|
386
387
|
| [`custom-gateways`](examples/custom-gateways/) | 按 DSH 官方方式接任何 OpenAI 兼容网关,每个 Pi 插件都能看到它 |
|
|
388
|
+
| [`code-navigation`](examples/code-navigation/) | 给模型真正的代码导航工具——在自带样例工程上跑模糊内容搜索与语言服务器诊断,CLI 与 Web 双端 |
|
|
387
389
|
| [`tui-mcp`](examples/tui-mcp/) | 保留 dsh-TUI 原生 `/mcp`,把 Pi 生态管理面作为 `/pi-mcp` 加进来,并让完整的宿主相关 MCP 功能面穿过 DSH 运行时 |
|
|
390
|
+
| [`mcp-at-scale`](examples/mcp-at-scale/) | 真实 51 工具 MCP 服务器藏在 adapter 两个元工具后面:工具面有界、规模化懒发现、超时预算把 ~120 秒工具砍到秒级——CLI 与 Web 双端 |
|
|
388
391
|
| [`subagents`](examples/subagents/) | 模型自己带小团队:派单、后台、中途转向、收结果、带记忆续命、真停得住、`/pi-agents` 管理、跨重启重开 |
|
|
389
392
|
|
|
390
393
|
## 其它工具
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { a as PI_AI_PACKAGES, d as ruleForEvent, f as ruleForHostImport, l as ruleForApi, o as PI_CODING_AGENT_PACKAGES, p as ruleForUiContextProperty, s as PI_TUI_PACKAGES, u as ruleForContextProperty } from "./compatibility-
|
|
2
|
+
import { a as PI_AI_PACKAGES, d as ruleForEvent, f as ruleForHostImport, l as ruleForApi, o as PI_CODING_AGENT_PACKAGES, p as ruleForUiContextProperty, s as PI_TUI_PACKAGES, u as ruleForContextProperty } from "./compatibility-CZs3LwYn.mjs";
|
|
3
3
|
import { builtinModules } from "node:module";
|
|
4
4
|
import { lstat, readFile, readdir, stat } from "node:fs/promises";
|
|
5
5
|
import { basename, dirname, extname, join, relative, resolve } from "node:path";
|
|
@@ -623,4 +623,4 @@ async function analyzePackage(pkg) {
|
|
|
623
623
|
//#endregion
|
|
624
624
|
export { analyzePackage };
|
|
625
625
|
|
|
626
|
-
//# sourceMappingURL=analyzer-
|
|
626
|
+
//# sourceMappingURL=analyzer-C139Y2S7.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer-LpQ59yjZ.mjs","names":[],"sources":["../src/module-graph.ts","../src/analyzer.ts"],"sourcesContent":["import { builtinModules } from 'node:module'\nimport { lstat, readFile, readdir, stat } from 'node:fs/promises'\nimport { dirname, extname, join, relative, resolve } from 'node:path'\nimport ts from 'typescript'\n\nexport const SCRIPT_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs'])\nconst MODULE_EXTENSIONS = ['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs', '.json']\n\ninterface LocalReference {\n kind: 'module' | 'asset'\n specifier: string\n // A lazy reference is only evaluated when some feature runs, never while the\n // extension entry loads: dynamic import()/require() inside a function body,\n // or worker/data assets spawned on demand. Pi's loader therefore succeeds\n // even when a lazy target is unresolvable; problems on lazy paths surface\n // (identically under Pi and pi2dsh) only if that feature is used.\n lazy: boolean\n}\n\nexport interface LocalClosureIssue {\n file: string\n kind: LocalReference['kind']\n specifier: string\n detail: string\n lazy: boolean\n}\n\nexport interface LocalClosure {\n files: string[]\n // Files whose module-level code executes the moment the extension entry\n // loads (transitive non-lazy module edges from the entries).\n loadTimeFiles: Set<string>\n issues: LocalClosureIssue[]\n}\n\nexport function sourceKind(path: string): ts.ScriptKind {\n if (path.endsWith('.js') || path.endsWith('.mjs') || path.endsWith('.cjs')) return ts.ScriptKind.JS\n if (path.endsWith('.jsx')) return ts.ScriptKind.JSX\n if (path.endsWith('.tsx')) return ts.ScriptKind.TSX\n return ts.ScriptKind.TS\n}\n\nfunction literalModule(node: ts.Expression | undefined): string | undefined {\n return node !== undefined && (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) ? node.text : undefined\n}\n\nfunction isImportMetaUrl(node: ts.Expression | undefined): boolean {\n return node !== undefined && ts.isPropertyAccessExpression(node) && node.name.text === 'url'\n && ts.isMetaProperty(node.expression) && node.expression.keywordToken === ts.SyntaxKind.ImportKeyword\n}\n\nfunction localReferences(path: string, text: string): LocalReference[] {\n const source = ts.createSourceFile(path, text, ts.ScriptTarget.Latest, true, sourceKind(path))\n const values = new Map<string, LocalReference>()\n const createRequireNames = new Set<string>(['createRequire'])\n const requireNames = new Set<string>(['require'])\n const add = (kind: LocalReference['kind'], specifier: string, lazy: boolean): void => {\n // '#'-prefixed specifiers are Node subpath imports resolved through the\n // package's own `imports` map — package-local, not external dependencies.\n if (!specifier.startsWith('.') && !specifier.startsWith('#')) return\n const key = `${kind}:${specifier}`\n const existing = values.get(key)\n // A specifier reached both statically and lazily executes at load time.\n if (existing === undefined) values.set(key, { kind, specifier, lazy })\n else if (existing.lazy && !lazy) existing.lazy = false\n }\n function collectRequireAliases(node: ts.Node): void {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)\n && (node.moduleSpecifier.text === 'node:module' || node.moduleSpecifier.text === 'module')\n && node.importClause?.namedBindings !== undefined && ts.isNamedImports(node.importClause.namedBindings)) {\n for (const element of node.importClause.namedBindings.elements) {\n if ((element.propertyName?.text ?? element.name.text) === 'createRequire') createRequireNames.add(element.name.text)\n }\n } else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)\n && node.initializer !== undefined && ts.isCallExpression(node.initializer)\n && ts.isIdentifier(node.initializer.expression) && createRequireNames.has(node.initializer.expression.text)) {\n requireNames.add(node.name.text)\n }\n ts.forEachChild(node, collectRequireAliases)\n }\n collectRequireAliases(source)\n function visit(node: ts.Node): void {\n if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier !== undefined\n && ts.isStringLiteral(node.moduleSpecifier)) {\n add('module', node.moduleSpecifier.text, false)\n } else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference)\n && ts.isStringLiteral(node.moduleReference.expression)) {\n add('module', node.moduleReference.expression.text, false)\n } else if (ts.isCallExpression(node) && node.arguments.length > 0\n && ((node.expression.kind === ts.SyntaxKind.ImportKeyword)\n || (ts.isIdentifier(node.expression) && requireNames.has(node.expression.text)))) {\n const specifier = literalModule(node.arguments[0])\n if (specifier !== undefined) add('module', specifier, insideFunctionBody(node))\n } else if (ts.isNewExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'URL'\n && isImportMetaUrl(node.arguments?.[1])) {\n const specifier = literalModule(node.arguments?.[0])\n if (specifier !== undefined) add('asset', specifier, false)\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n return [...values.values()]\n}\n\nfunction externalPackage(specifier: string): string | undefined {\n // `bun:*` counts as a host builtin, not an npm dependency: Pi's official\n // distribution is a Bun-compiled binary, so ecosystem packages gate these\n // requires behind runtime detection and take their declared Node fallback\n // (better-sqlite3, node:sqlite) everywhere else.\n if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('#')\n || specifier.startsWith('node:') || specifier.startsWith('bun:')\n || builtinModules.includes(specifier)) return undefined\n const parts = specifier.split('/')\n return specifier.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0]\n}\n\nfunction insideTry(node: ts.Node): boolean {\n let current: ts.Node | undefined = node.parent\n while (current !== undefined) {\n if (ts.isTryStatement(current)) return true\n // Stop at function boundaries: a try in an outer function does not guard\n // an import inside a nested callback executed later.\n if (ts.isFunctionLike(current)) {\n // ...unless the whole function body IS awaited inside the try; keeping\n // this conservative check simple errs toward reporting the dependency.\n return false\n }\n current = current.parent\n }\n return false\n}\n\n// Inside any function body means the expression does not run while the module\n// itself loads — it runs when (if ever) that function is called.\nfunction insideFunctionBody(node: ts.Node): boolean {\n let current: ts.Node | undefined = node.parent\n while (current !== undefined) {\n if (ts.isFunctionLike(current)) return true\n current = current.parent\n }\n return false\n}\n\nexport interface RuntimeDependencyUse {\n name: string\n // true when every use sits on a lazy path (dynamic import/require inside a\n // function body): the module loads fine without the dependency, exactly as\n // under Pi, and only the feature that calls it needs the install.\n lazy: boolean\n}\n\nexport function runtimeExternalPackages(path: string, text: string): RuntimeDependencyUse[] {\n const source = ts.createSourceFile(path, text, ts.ScriptTarget.Latest, true, sourceKind(path))\n const packages = new Map<string, RuntimeDependencyUse>()\n const createRequireNames = new Set<string>(['createRequire'])\n const requireNames = new Set<string>(['require'])\n const add = (specifier: string, lazy: boolean): void => {\n const name = externalPackage(specifier)\n if (name === undefined || name.length === 0) return\n const existing = packages.get(name)\n if (existing === undefined) packages.set(name, { name, lazy })\n else if (existing.lazy && !lazy) existing.lazy = false\n }\n function collectRequireAliases(node: ts.Node): void {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)\n && (node.moduleSpecifier.text === 'node:module' || node.moduleSpecifier.text === 'module')\n && node.importClause?.namedBindings !== undefined && ts.isNamedImports(node.importClause.namedBindings)) {\n for (const element of node.importClause.namedBindings.elements) {\n if ((element.propertyName?.text ?? element.name.text) === 'createRequire') createRequireNames.add(element.name.text)\n }\n } else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)\n && node.initializer !== undefined && ts.isCallExpression(node.initializer)\n && ts.isIdentifier(node.initializer.expression) && createRequireNames.has(node.initializer.expression.text)) {\n requireNames.add(node.name.text)\n }\n ts.forEachChild(node, collectRequireAliases)\n }\n collectRequireAliases(source)\n function visit(node: ts.Node): void {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {\n const clause = node.importClause\n const named = clause?.namedBindings\n const namedImportsAreTypeOnly = named !== undefined && ts.isNamedImports(named)\n && named.elements.length > 0 && named.elements.every(element => element.isTypeOnly)\n if (clause === undefined || (!clause.isTypeOnly && (clause.name !== undefined || !namedImportsAreTypeOnly))) {\n add(node.moduleSpecifier.text, false)\n }\n } else if (ts.isExportDeclaration(node) && !node.isTypeOnly\n && node.moduleSpecifier !== undefined && ts.isStringLiteral(node.moduleSpecifier)) {\n add(node.moduleSpecifier.text, false)\n } else if (ts.isImportEqualsDeclaration(node) && !node.isTypeOnly\n && ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) {\n add(node.moduleReference.expression.text, false)\n } else if (ts.isCallExpression(node) && node.arguments.length > 0\n && ((node.expression.kind === ts.SyntaxKind.ImportKeyword)\n || (ts.isIdentifier(node.expression) && requireNames.has(node.expression.text)))) {\n // A dynamic import/require wrapped in try/catch is the ecosystem's\n // optional-dependency idiom (e.g. pi-harness-runtime's \"// Dynamic\n // import for Playwright (optional dependency)\") — its absence is a\n // designed degradation, not an undeclared runtime requirement.\n if (!insideTry(node)) {\n const specifier = literalModule(node.arguments[0])\n if (specifier !== undefined) add(specifier, insideFunctionBody(node))\n }\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n return [...packages.values()]\n}\n\nfunction inside(rootDir: string, path: string): boolean {\n const pathRelative = relative(rootDir, path)\n return pathRelative === '' || (pathRelative !== '..' && !pathRelative.startsWith(`..${process.platform === 'win32' ? '\\\\' : '/'}`))\n}\n\nfunction sourceAlternates(base: string): string[] {\n const extension = extname(base)\n const stem = extension.length > 0 ? base.slice(0, -extension.length) : base\n if (extension === '.js') return [`${stem}.ts`, `${stem}.tsx`]\n if (extension === '.mjs') return [`${stem}.mts`, `${stem}.ts`]\n if (extension === '.cjs') return [`${stem}.cts`, `${stem}.ts`]\n if (extension === '.jsx') return [`${stem}.tsx`, `${stem}.ts`]\n return []\n}\n\nasync function isFile(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isFile()\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false\n throw error\n }\n}\n\nfunction subpathImportTarget(rootDir: string, specifier: string, importsMap: Record<string, unknown>): string | undefined {\n const conditionValue = (value: unknown): string | undefined => {\n if (typeof value === 'string') return value\n if (typeof value !== 'object' || value === null) return undefined\n const record = value as Record<string, unknown>\n for (const condition of ['import', 'node', 'default']) {\n const candidate = conditionValue(record[condition])\n if (candidate !== undefined) return candidate\n }\n return undefined\n }\n const direct = conditionValue(importsMap[specifier])\n if (direct !== undefined) return resolve(rootDir, direct)\n for (const [pattern, value] of Object.entries(importsMap)) {\n const star = pattern.indexOf('*')\n if (star === -1) continue\n const prefix = pattern.slice(0, star)\n const suffix = pattern.slice(star + 1)\n if (!specifier.startsWith(prefix) || !specifier.endsWith(suffix)) continue\n const wildcard = specifier.slice(prefix.length, specifier.length - suffix.length)\n const target = conditionValue(value)\n if (target !== undefined) return resolve(rootDir, target.replace('*', wildcard))\n }\n return undefined\n}\n\nasync function packageImportsMap(rootDir: string): Promise<Record<string, unknown>> {\n try {\n const parsed = JSON.parse(await readFile(join(rootDir, 'package.json'), 'utf8')) as { imports?: unknown }\n return typeof parsed.imports === 'object' && parsed.imports !== null ? parsed.imports as Record<string, unknown> : {}\n } catch {\n return {}\n }\n}\n\nasync function resolveModule(fromFile: string, specifier: string, rootDir: string, importsMap: Record<string, unknown>): Promise<string> {\n if (specifier.startsWith('#')) {\n const target = subpathImportTarget(rootDir, specifier, importsMap)\n if (target === undefined) {\n throw new Error(`cannot resolve subpath import ${JSON.stringify(specifier)} through the package \"imports\" map`)\n }\n return resolveModule(fromFile, relative(dirname(fromFile), target).startsWith('.')\n ? relative(dirname(fromFile), target)\n : `./${relative(dirname(fromFile), target)}`, rootDir, importsMap)\n }\n const base = resolve(dirname(fromFile), specifier)\n const candidates = [\n base,\n ...sourceAlternates(base),\n ...(extname(base) === '' ? MODULE_EXTENSIONS.map(extension => `${base}${extension}`) : []),\n ...MODULE_EXTENSIONS.map(extension => join(base, `index${extension}`)),\n ]\n for (const candidate of [...new Set(candidates)]) {\n if (!inside(rootDir, candidate)) throw new Error(`extension import escapes the Pi package: ${specifier} from ${fromFile}`)\n if (await isFile(candidate)) return candidate\n }\n throw new Error(`cannot resolve local extension import ${JSON.stringify(specifier)} from ${fromFile}`)\n}\n\nasync function expandAsset(path: string, rootDir: string): Promise<string[]> {\n if (!inside(rootDir, path)) throw new Error(`extension asset escapes the Pi package: ${path}`)\n let info\n try {\n info = await lstat(path)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n // A `new URL('./worker.js', import.meta.url)` asset may only exist in its\n // TypeScript source form before the package builds; track the source.\n for (const alternate of sourceAlternates(path)) {\n if (await isFile(alternate)) return [alternate]\n }\n throw error\n }\n if (info.isSymbolicLink()) throw new Error(`refusing to copy symbolic link from Pi package: ${path}`)\n if (info.isFile()) return [path]\n if (!info.isDirectory()) return []\n const output: string[] = []\n for (const entry of await readdir(path)) output.push(...await expandAsset(join(path, entry), rootDir))\n return output\n}\n\nexport async function collectLocalClosure(rootDir: string, entries: readonly string[]): Promise<LocalClosure> {\n const importsMap = await packageImportsMap(rootDir)\n const graph = new Map<string, Array<{ lazy: boolean, targets: string[] }>>()\n const issues: LocalClosureIssue[] = []\n const queue = entries.map(path => resolve(path))\n // Pass 1: the full local reference graph, lazy edges included, so the\n // snapshot carries every file any feature could ever load.\n while (queue.length > 0) {\n const source = queue.shift() as string\n if (graph.has(source)) continue\n if (!inside(rootDir, source)) throw new Error(`extension source escapes the Pi package: ${source}`)\n const info = await lstat(source)\n if (info.isSymbolicLink()) throw new Error(`refusing to copy symbolic link from Pi package: ${source}`)\n if (!info.isFile()) throw new Error(`extension closure contains a non-file path: ${source}`)\n const edges: Array<{ lazy: boolean, targets: string[] }> = []\n graph.set(source, edges)\n if (!SCRIPT_EXTENSIONS.has(extname(source))) continue\n const text = await readFile(source, 'utf8')\n for (const reference of localReferences(source, text)) {\n // Worker/data assets never execute while the entry loads; the feature\n // that spawns them does, so their whole subtree is a lazy path.\n const lazy = reference.lazy || reference.kind === 'asset'\n try {\n const targets = reference.kind === 'module'\n ? [await resolveModule(source, reference.specifier, rootDir, importsMap)]\n : await expandAsset(resolve(dirname(source), reference.specifier), rootDir)\n edges.push({ lazy, targets })\n queue.push(...targets)\n } catch (error) {\n issues.push({\n file: source,\n kind: reference.kind,\n specifier: reference.specifier,\n detail: error instanceof Error ? error.message : String(error),\n lazy,\n })\n }\n }\n }\n // Pass 2: load-time reachability across non-lazy module edges only. This is\n // the set whose problems actually break `pi` (and pi2dsh) at extension load;\n // everything else fails at feature-use time, identically under both hosts.\n const loadTimeFiles = new Set<string>()\n const loadQueue = entries.map(path => resolve(path)).filter(path => graph.has(path))\n while (loadQueue.length > 0) {\n const source = loadQueue.shift() as string\n if (loadTimeFiles.has(source)) continue\n loadTimeFiles.add(source)\n for (const edge of graph.get(source) ?? []) {\n if (edge.lazy) continue\n for (const target of edge.targets) {\n if (!loadTimeFiles.has(target)) loadQueue.push(target)\n }\n }\n }\n // An issue found inside a file that itself only loads lazily cannot break\n // extension load either, however the reference is written.\n for (const issue of issues) {\n if (!loadTimeFiles.has(issue.file)) issue.lazy = true\n }\n return { files: [...graph.keys()].sort(), loadTimeFiles, issues }\n}\n","import { readFile } from 'node:fs/promises'\nimport { basename, extname, relative } from 'node:path'\nimport ts from 'typescript'\nimport {\n PI_CODING_AGENT_PACKAGES,\n PI_AI_PACKAGES,\n PI_TUI_PACKAGES,\n ruleForApi,\n ruleForContextProperty,\n ruleForEvent,\n ruleForHostImport,\n ruleForUiContextProperty,\n} from './compatibility.js'\nimport { collectLocalClosure, runtimeExternalPackages, SCRIPT_EXTENSIONS, sourceKind } from './module-graph.js'\nimport type {\n CompatibilityFinding,\n CompatibilityLevel,\n CompatibilityReport,\n ResolvedPiPackage,\n} from './types.js'\n\nfunction literalText(node: ts.Node | undefined): string | undefined {\n return node !== undefined && (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node))\n ? node.text\n : undefined\n}\n\nfunction hasModifier(node: ts.Node, kind: ts.SyntaxKind): boolean {\n return ts.canHaveModifiers(node) && ts.getModifiers(node)?.some(modifier => modifier.kind === kind) === true\n}\n\nfunction parameterIdentifier(node: ts.SignatureDeclarationBase): string | undefined {\n const parameter = node.parameters[0]\n return parameter !== undefined && ts.isIdentifier(parameter.name) ? parameter.name.text : undefined\n}\n\nfunction extensionApiReceivers(source: ts.SourceFile): Set<string> {\n const receivers = new Set<string>()\n const functions = new Map<string, ts.FunctionLikeDeclarationBase>()\n\n function index(node: ts.Node): void {\n if (ts.isFunctionDeclaration(node) && node.name !== undefined) functions.set(node.name.text, node)\n if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)\n && node.initializer !== undefined\n && (ts.isArrowFunction(node.initializer) || ts.isFunctionExpression(node.initializer))) {\n functions.set(node.name.text, node.initializer)\n }\n if (ts.isParameter(node) && node.type !== undefined\n && /(?:^|\\.)ExtensionAPI\\b/u.test(node.type.getText(source)) && ts.isIdentifier(node.name)) {\n receivers.add(node.name.text)\n }\n // Published Pi packages commonly ship JavaScript with type annotations\n // erased. `pi` is the documented ExtensionAPI parameter name throughout\n // the ecosystem, including helper functions reached from the entry point.\n if (ts.isParameter(node) && ts.isIdentifier(node.name)\n && /^(?:pi|extensionApi)$/iu.test(node.name.text)) {\n receivers.add(node.name.text)\n }\n ts.forEachChild(node, index)\n }\n index(source)\n\n for (const statement of source.statements) {\n if (ts.isFunctionDeclaration(statement)\n && hasModifier(statement, ts.SyntaxKind.ExportKeyword)\n && hasModifier(statement, ts.SyntaxKind.DefaultKeyword)) {\n const name = parameterIdentifier(statement)\n if (name !== undefined) receivers.add(name)\n }\n if (ts.isExportAssignment(statement)) {\n const expression = statement.expression\n if (ts.isArrowFunction(expression) || ts.isFunctionExpression(expression)) {\n const name = parameterIdentifier(expression)\n if (name !== undefined) receivers.add(name)\n } else if (ts.isIdentifier(expression)) {\n const candidate = functions.get(expression.text)\n if (candidate !== undefined) {\n const name = parameterIdentifier(candidate)\n if (name !== undefined) receivers.add(name)\n }\n }\n }\n if (ts.isExportDeclaration(statement) && statement.moduleSpecifier === undefined\n && statement.exportClause !== undefined && ts.isNamedExports(statement.exportClause)) {\n for (const element of statement.exportClause.elements) {\n if (element.name.text !== 'default' || element.propertyName === undefined || !ts.isIdentifier(element.propertyName)) continue\n const candidate = functions.get(element.propertyName.text)\n if (candidate !== undefined) {\n const name = parameterIdentifier(candidate)\n if (name !== undefined) receivers.add(name)\n }\n }\n }\n }\n return receivers\n}\n\nfunction extensionApiProperties(source: ts.SourceFile, receivers: ReadonlySet<string>): Set<string> {\n const properties = new Set<string>()\n function visit(node: ts.Node): void {\n if ((ts.isPropertyDeclaration(node) || ts.isParameter(node)) && ts.isIdentifier(node.name)) {\n const typed = node.type !== undefined && /(?:^|\\.)(?:Pi)?ExtensionAPI\\b/u.test(node.type.getText(source))\n if (typed || /^(?:pi|extensionApi)$/iu.test(node.name.text)) properties.add(node.name.text)\n } else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken\n && ts.isPropertyAccessExpression(node.left) && node.left.expression.kind === ts.SyntaxKind.ThisKeyword\n && ts.isIdentifier(node.right) && receivers.has(node.right.text)) {\n properties.add(node.left.name.text)\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n return properties\n}\n\nfunction enclosingFunctionName(node: ts.ParameterDeclaration): string | undefined {\n const parent = node.parent\n if (ts.isMethodDeclaration(parent) && parent.name !== undefined) return parent.name.getText()\n if ((ts.isArrowFunction(parent) || ts.isFunctionExpression(parent)) && ts.isPropertyAssignment(parent.parent)) {\n return parent.parent.name.getText()\n }\n return undefined\n}\n\nfunction extensionContextReceivers(source: ts.SourceFile): Set<string> {\n const receivers = new Set<string>()\n function visit(node: ts.Node): void {\n if (ts.isParameter(node) && ts.isIdentifier(node.name)) {\n const typedContext = node.type !== undefined\n && /(?:^|\\.)(?:Extension|ExtensionCommand|ToolExecution)Context\\b/u.test(node.type.getText(source))\n const conventionalHandlerContext = /^(?:ctx|context)$/iu.test(node.name.text)\n && /^(?:execute|handler)$/u.test(enclosingFunctionName(node) ?? '')\n if (typedContext || conventionalHandlerContext) receivers.add(node.name.text)\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n return receivers\n}\n\n// The three Pi packages whose named exports the shim audit tracks.\nconst PI_SHIMMED_PACKAGES = new Set<string>([\n ...PI_CODING_AGENT_PACKAGES,\n ...PI_TUI_PACKAGES,\n ...PI_AI_PACKAGES,\n])\n\n// Everything Pi's loader provides to extensions without a declaration —\n// exempt from the undeclared-runtime-dependency fatal, and (for typebox) not\n// subject to per-symbol shim auditing.\nconst PI_HOST_PACKAGES = new Set<string>([\n ...PI_SHIMMED_PACKAGES,\n 'typebox',\n '@sinclair/typebox',\n])\n\nfunction dependencyNames(packageJson: Record<string, unknown>): Set<string> {\n const names = new Set<string>()\n for (const field of ['dependencies', 'optionalDependencies', 'peerDependencies']) {\n const value = packageJson[field]\n if (typeof value !== 'object' || value === null || Array.isArray(value)) continue\n for (const [name, specifier] of Object.entries(value)) {\n if (typeof specifier === 'string') names.add(name)\n }\n }\n return names\n}\n\nfunction pushFinding(\n findings: CompatibilityFinding[],\n rootDir: string,\n file: string,\n source: ts.SourceFile,\n node: ts.Node,\n capability: string,\n level: CompatibilityLevel,\n detail: string,\n): void {\n const position = source.getLineAndCharacterOfPosition(node.getStart(source))\n findings.push({\n capability,\n level,\n file: relative(rootDir, file).replaceAll('\\\\', '/'),\n line: position.line + 1,\n detail,\n })\n}\n\nasync function analyzeExtension(rootDir: string, file: string): Promise<CompatibilityFinding[]> {\n const text = await readFile(file, 'utf8')\n const source = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true, sourceKind(file))\n const findings: CompatibilityFinding[] = []\n const receivers = extensionApiReceivers(source)\n const apiProperties = extensionApiProperties(source, receivers)\n const contextReceivers = extensionContextReceivers(source)\n const methodAliases = new Map<string, string>()\n const eventBusAliases = new Set<string>()\n const uiAliases = new Set<string>()\n\n function reportHostImport(packageName: string, importedName: string, node: ts.Node): void {\n const matched = ruleForHostImport(packageName, importedName)\n if (matched === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, `host-import(${packageName}:${importedName})`, 'unsupported',\n `The pi2dsh host shim does not export ${JSON.stringify(importedName)} from ${JSON.stringify(packageName)}.`,\n )\n return\n }\n pushFinding(\n findings, rootDir, file, source, node, `host-import(${packageName}:${importedName})`, matched.level, matched.detail,\n )\n }\n\n for (const statement of source.statements) {\n if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)\n && PI_SHIMMED_PACKAGES.has(statement.moduleSpecifier.text)) {\n const packageName = statement.moduleSpecifier.text\n const clause = statement.importClause\n if (clause === undefined) {\n reportHostImport(packageName, '<side-effect>', statement)\n continue\n }\n if (clause.isTypeOnly) continue\n if (clause.name !== undefined) reportHostImport(packageName, 'default', clause.name)\n if (clause.namedBindings !== undefined && ts.isNamespaceImport(clause.namedBindings)) {\n reportHostImport(packageName, '*', clause.namedBindings)\n } else if (clause.namedBindings !== undefined) {\n for (const element of clause.namedBindings.elements) {\n if (!element.isTypeOnly) reportHostImport(packageName, element.propertyName?.text ?? element.name.text, element)\n }\n }\n } else if (ts.isExportDeclaration(statement) && !statement.isTypeOnly\n && statement.moduleSpecifier !== undefined && ts.isStringLiteral(statement.moduleSpecifier)\n && PI_HOST_PACKAGES.has(statement.moduleSpecifier.text)) {\n const packageName = statement.moduleSpecifier.text\n if (statement.exportClause === undefined || ts.isNamespaceExport(statement.exportClause)) {\n reportHostImport(packageName, '*', statement)\n } else {\n for (const element of statement.exportClause.elements) {\n if (!element.isTypeOnly) reportHostImport(packageName, element.propertyName?.text ?? element.name.text, element)\n }\n }\n } else if (ts.isImportEqualsDeclaration(statement) && !statement.isTypeOnly\n && ts.isExternalModuleReference(statement.moduleReference)\n && ts.isStringLiteral(statement.moduleReference.expression)\n && PI_HOST_PACKAGES.has(statement.moduleReference.expression.text)) {\n reportHostImport(statement.moduleReference.expression.text, '*', statement)\n }\n }\n\n const declarations: ts.VariableDeclaration[] = []\n const isApiReceiver = (node: ts.Expression): boolean => ts.isIdentifier(node) && receivers.has(node.text)\n || (ts.isPropertyAccessExpression(node) && node.expression.kind === ts.SyntaxKind.ThisKeyword\n && apiProperties.has(node.name.text))\n function collectDeclarations(node: ts.Node): void {\n if (ts.isVariableDeclaration(node)) declarations.push(node)\n ts.forEachChild(node, collectDeclarations)\n }\n collectDeclarations(source)\n\n for (let pass = 0; pass < declarations.length + 1; pass += 1) {\n let changed = false\n for (const declaration of declarations) {\n const initializer = declaration.initializer\n if (initializer === undefined) continue\n if (ts.isIdentifier(declaration.name) && isApiReceiver(initializer)) {\n if (!receivers.has(declaration.name.text)) {\n receivers.add(declaration.name.text)\n changed = true\n }\n }\n if (ts.isIdentifier(declaration.name) && ts.isIdentifier(initializer) && contextReceivers.has(initializer.text)) {\n if (!contextReceivers.has(declaration.name.text)) {\n contextReceivers.add(declaration.name.text)\n changed = true\n }\n }\n if (ts.isIdentifier(declaration.name) && ts.isPropertyAccessExpression(initializer)\n && initializer.name.text === 'ui' && ts.isIdentifier(initializer.expression)\n && contextReceivers.has(initializer.expression.text) && !uiAliases.has(declaration.name.text)) {\n uiAliases.add(declaration.name.text)\n changed = true\n }\n if (ts.isIdentifier(declaration.name) && ts.isPropertyAccessExpression(initializer)\n && isApiReceiver(initializer.expression)) {\n if (initializer.name.text === 'events') {\n if (!eventBusAliases.has(declaration.name.text)) {\n eventBusAliases.add(declaration.name.text)\n changed = true\n }\n } else if (!methodAliases.has(declaration.name.text)) {\n methodAliases.set(declaration.name.text, initializer.name.text)\n changed = true\n }\n }\n if (ts.isObjectBindingPattern(declaration.name) && isApiReceiver(initializer)) {\n for (const element of declaration.name.elements) {\n if (!ts.isIdentifier(element.name)) continue\n const method = element.propertyName !== undefined && ts.isIdentifier(element.propertyName)\n ? element.propertyName.text\n : element.name.text\n if (method === 'events') {\n if (!eventBusAliases.has(element.name.text)) {\n eventBusAliases.add(element.name.text)\n changed = true\n }\n } else if (!methodAliases.has(element.name.text)) {\n methodAliases.set(element.name.text, method)\n changed = true\n }\n }\n }\n }\n if (!changed) break\n }\n\n function reportMethod(method: string, args: ts.NodeArray<ts.Expression>, node: ts.Node): void {\n if (method === 'on') {\n const event = literalText(args[0])\n if (event === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, 'on(<dynamic>)', 'unsupported',\n 'Dynamic event names cannot be audited or mapped safely.',\n )\n } else {\n const rule = ruleForEvent(event)\n pushFinding(findings, rootDir, file, source, node, `on(${event})`, rule.level, rule.detail)\n }\n return\n }\n const rule = ruleForApi(method)\n if (rule === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, method, 'unsupported',\n `Unknown ExtensionAPI method ${JSON.stringify(method)} cannot be audited or mapped safely.`,\n )\n return\n }\n pushFinding(findings, rootDir, file, source, node, method, rule.level, rule.detail)\n }\n\n function reportEventBus(method: string, node: ts.Node): void {\n const rule = ruleForApi('events')\n if ((method === 'on' || method === 'emit') && rule !== undefined) {\n pushFinding(findings, rootDir, file, source, node, `events.${method}`, rule.level, rule.detail)\n } else {\n pushFinding(\n findings, rootDir, file, source, node, `events.${method}`, 'unsupported',\n `Unknown Pi event-bus method ${JSON.stringify(method)} cannot be mapped safely.`,\n )\n }\n }\n\n function reportContext(property: string, node: ts.Node): void {\n const matched = ruleForContextProperty(property)\n if (matched === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, `ctx.${property}`, 'unsupported',\n `Unknown Pi extension-context property ${JSON.stringify(property)} cannot be audited or mapped safely.`,\n )\n } else {\n pushFinding(findings, rootDir, file, source, node, `ctx.${property}`, matched.level, matched.detail)\n }\n }\n\n function reportUiContext(property: string, node: ts.Node): void {\n const matched = ruleForUiContextProperty(property)\n if (matched === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, `ctx.ui.${property}`, 'unsupported',\n `Unknown Pi UI-context property ${JSON.stringify(property)} cannot be audited or mapped safely.`,\n )\n } else {\n pushFinding(findings, rootDir, file, source, node, `ctx.ui.${property}`, matched.level, matched.detail)\n }\n }\n\n function visit(node: ts.Node): void {\n if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {\n const method = methodAliases.get(node.expression.text)\n if (method !== undefined) reportMethod(method, node.arguments, node)\n } else if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {\n const target = node.expression.expression\n if (isApiReceiver(target)) {\n reportMethod(node.expression.name.text, node.arguments, node)\n } else if (ts.isIdentifier(target) && eventBusAliases.has(target.text)) {\n reportEventBus(node.expression.name.text, node)\n } else if (ts.isPropertyAccessExpression(target)\n && target.name.text === 'events'\n && isApiReceiver(target.expression)) {\n reportEventBus(node.expression.name.text, node)\n }\n } else if (ts.isCallExpression(node) && ts.isElementAccessExpression(node.expression)\n && isApiReceiver(node.expression.expression)) {\n const method = literalText(node.expression.argumentExpression)\n if (method === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, '<dynamic-api-method>', 'unsupported',\n 'Dynamic ExtensionAPI method access cannot be audited or mapped safely.',\n )\n } else {\n reportMethod(method, node.arguments, node)\n }\n }\n if (ts.isPropertyAccessExpression(node)) {\n const target = node.expression\n if (ts.isPropertyAccessExpression(target) && target.name.text === 'ui'\n && ts.isIdentifier(target.expression) && contextReceivers.has(target.expression.text)) {\n reportUiContext(node.name.text, node)\n } else if (ts.isIdentifier(target) && uiAliases.has(target.text)) {\n reportUiContext(node.name.text, node)\n } else if (ts.isIdentifier(target) && contextReceivers.has(target.text) && node.name.text !== 'ui') {\n reportContext(node.name.text, node)\n }\n } else if (ts.isElementAccessExpression(node) && ts.isIdentifier(node.expression)\n && contextReceivers.has(node.expression.text)) {\n const property = literalText(node.argumentExpression)\n if (property === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, 'ctx.<dynamic>', 'unsupported',\n 'Dynamic Pi extension-context access cannot be audited or mapped safely.',\n )\n } else if (property !== 'ui') {\n reportContext(property, node)\n }\n }\n ts.forEachChild(node, visit)\n }\n\n visit(source)\n return findings\n}\n\nexport async function analyzePackage(pkg: ResolvedPiPackage): Promise<CompatibilityReport> {\n const extensionClosure = await collectLocalClosure(pkg.rootDir, pkg.resources.extensions)\n const findings = (await Promise.all(\n extensionClosure.files.filter(file => SCRIPT_EXTENSIONS.has(extname(file)))\n .map(file => analyzeExtension(pkg.rootDir, file)),\n )).flat()\n\n if (pkg.resources.extensions.length > 0 && findings.length === 0) {\n findings.push({\n capability: 'static-audit',\n level: 'unsupported',\n file: pkg.resources.extensions.map(file => relative(pkg.rootDir, file).replaceAll('\\\\', '/')).join(', '),\n line: 1,\n detail: 'No ExtensionAPI use was statically proven across the local module closure; conversion fails closed instead of claiming compatibility.',\n })\n }\n for (const issue of extensionClosure.issues) {\n // Only a break on the load-time path blocks the package: Pi's own loader\n // fails the same lazy references at feature-use time, and the snapshot\n // preserves the published file layout, so behavior matches Pi exactly.\n const lazyIssue = issue.lazy || issue.kind === 'asset'\n findings.push({\n capability: `${issue.kind}(${issue.specifier})`,\n level: lazyIssue ? 'partial' : 'fatal',\n file: relative(pkg.rootDir, issue.file).replaceAll('\\\\', '/'),\n line: 1,\n detail: lazyIssue\n ? `Unresolved reference on a lazy path: ${issue.detail}. Extension load is unaffected; if the feature that evaluates it runs, it fails the same way under Pi (published file layout is preserved).`\n : `The local extension closure is incomplete: ${issue.detail}`,\n })\n }\n\n const declaredDependencies = dependencyNames(pkg.packageJson)\n for (const file of extensionClosure.files.filter(candidate => SCRIPT_EXTENSIONS.has(extname(candidate)))) {\n const text = await readFile(file, 'utf8')\n const lazyFile = !extensionClosure.loadTimeFiles.has(file)\n for (const use of runtimeExternalPackages(file, text)) {\n if (PI_HOST_PACKAGES.has(use.name) || declaredDependencies.has(use.name)) continue\n // Undeclared imports only crash extension load when they execute at load\n // time. On lazy paths (function-body dynamic imports, or files that are\n // themselves only lazily reachable) Pi degrades per-feature; mirror that.\n const lazyUse = use.lazy || lazyFile\n findings.push({\n capability: lazyUse ? `optional-lazy-dependency(${use.name})` : `undeclared-runtime-dependency(${use.name})`,\n level: lazyUse ? 'partial' : 'fatal',\n file: relative(pkg.rootDir, file).replaceAll('\\\\', '/'),\n line: 1,\n detail: lazyUse\n ? `The extension imports ${JSON.stringify(use.name)} only on a lazily-evaluated path without declaring it; the feature that needs it asks for the module at call time, exactly as under Pi (install ${use.name} to use that feature).`\n : `The extension imports ${JSON.stringify(use.name)} at load time, but the Pi package does not declare it as a dependency.`,\n })\n }\n }\n\n const resourceFinding = (file: string, capability: string, level: CompatibilityLevel, detail: string): CompatibilityFinding => ({\n capability,\n level,\n file: relative(pkg.rootDir, file).replaceAll('\\\\', '/'),\n line: 1,\n detail,\n })\n for (const file of pkg.resources.skills.filter(path => basename(path) === 'SKILL.md' || path.endsWith('.md'))) {\n findings.push(resourceFinding(file, 'skill', 'full', 'Copied as a DSH filesystem skill with its resource directory intact.'))\n }\n for (const file of pkg.resources.prompts) {\n findings.push(resourceFinding(file, 'prompt', 'full', 'Registered as a DSH slash command with Pi-compatible argument expansion.'))\n }\n for (const file of pkg.resources.themes) {\n findings.push(resourceFinding(file, 'theme', 'unsupported', 'Pi terminal themes have no effect in DSH Web or headless surfaces.'))\n }\n findings.sort((left, right) => left.file.localeCompare(right.file) || left.line - right.line || left.capability.localeCompare(right.capability))\n\n const summary: Record<CompatibilityLevel, number> = { full: 0, partial: 0, unsupported: 0, fatal: 0 }\n for (const finding of findings) summary[finding.level] += 1\n // Static analysis screens; it does not certify. Only fatal findings block a\n // bundle (it cannot be built or trusted). Everything else installs: verify\n // real behavior with the black-box run instead of trusting this verdict.\n const verdict = summary.fatal > 0 ? 'blocked' : summary.partial > 0 || summary.unsupported > 0 ? 'review' : 'ready'\n\n return {\n schemaVersion: 1,\n package: pkg.identity,\n verdict,\n summary,\n resources: {\n extensions: pkg.resources.extensions.map(file => relative(pkg.rootDir, file).replaceAll('\\\\', '/')),\n skills: pkg.resources.skills.map(file => relative(pkg.rootDir, file).replaceAll('\\\\', '/')),\n prompts: pkg.resources.prompts.map(file => relative(pkg.rootDir, file).replaceAll('\\\\', '/')),\n themes: pkg.resources.themes.map(file => relative(pkg.rootDir, file).replaceAll('\\\\', '/')),\n },\n findings,\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analyzer-C139Y2S7.mjs","names":[],"sources":["../src/module-graph.ts","../src/analyzer.ts"],"sourcesContent":["import { builtinModules } from 'node:module'\nimport { lstat, readFile, readdir, stat } from 'node:fs/promises'\nimport { dirname, extname, join, relative, resolve } from 'node:path'\nimport ts from 'typescript'\n\nexport const SCRIPT_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs'])\nconst MODULE_EXTENSIONS = ['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs', '.json']\n\ninterface LocalReference {\n kind: 'module' | 'asset'\n specifier: string\n // A lazy reference is only evaluated when some feature runs, never while the\n // extension entry loads: dynamic import()/require() inside a function body,\n // or worker/data assets spawned on demand. Pi's loader therefore succeeds\n // even when a lazy target is unresolvable; problems on lazy paths surface\n // (identically under Pi and pi2dsh) only if that feature is used.\n lazy: boolean\n}\n\nexport interface LocalClosureIssue {\n file: string\n kind: LocalReference['kind']\n specifier: string\n detail: string\n lazy: boolean\n}\n\nexport interface LocalClosure {\n files: string[]\n // Files whose module-level code executes the moment the extension entry\n // loads (transitive non-lazy module edges from the entries).\n loadTimeFiles: Set<string>\n issues: LocalClosureIssue[]\n}\n\nexport function sourceKind(path: string): ts.ScriptKind {\n if (path.endsWith('.js') || path.endsWith('.mjs') || path.endsWith('.cjs')) return ts.ScriptKind.JS\n if (path.endsWith('.jsx')) return ts.ScriptKind.JSX\n if (path.endsWith('.tsx')) return ts.ScriptKind.TSX\n return ts.ScriptKind.TS\n}\n\nfunction literalModule(node: ts.Expression | undefined): string | undefined {\n return node !== undefined && (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) ? node.text : undefined\n}\n\nfunction isImportMetaUrl(node: ts.Expression | undefined): boolean {\n return node !== undefined && ts.isPropertyAccessExpression(node) && node.name.text === 'url'\n && ts.isMetaProperty(node.expression) && node.expression.keywordToken === ts.SyntaxKind.ImportKeyword\n}\n\nfunction localReferences(path: string, text: string): LocalReference[] {\n const source = ts.createSourceFile(path, text, ts.ScriptTarget.Latest, true, sourceKind(path))\n const values = new Map<string, LocalReference>()\n const createRequireNames = new Set<string>(['createRequire'])\n const requireNames = new Set<string>(['require'])\n const add = (kind: LocalReference['kind'], specifier: string, lazy: boolean): void => {\n // '#'-prefixed specifiers are Node subpath imports resolved through the\n // package's own `imports` map — package-local, not external dependencies.\n if (!specifier.startsWith('.') && !specifier.startsWith('#')) return\n const key = `${kind}:${specifier}`\n const existing = values.get(key)\n // A specifier reached both statically and lazily executes at load time.\n if (existing === undefined) values.set(key, { kind, specifier, lazy })\n else if (existing.lazy && !lazy) existing.lazy = false\n }\n function collectRequireAliases(node: ts.Node): void {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)\n && (node.moduleSpecifier.text === 'node:module' || node.moduleSpecifier.text === 'module')\n && node.importClause?.namedBindings !== undefined && ts.isNamedImports(node.importClause.namedBindings)) {\n for (const element of node.importClause.namedBindings.elements) {\n if ((element.propertyName?.text ?? element.name.text) === 'createRequire') createRequireNames.add(element.name.text)\n }\n } else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)\n && node.initializer !== undefined && ts.isCallExpression(node.initializer)\n && ts.isIdentifier(node.initializer.expression) && createRequireNames.has(node.initializer.expression.text)) {\n requireNames.add(node.name.text)\n }\n ts.forEachChild(node, collectRequireAliases)\n }\n collectRequireAliases(source)\n function visit(node: ts.Node): void {\n if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier !== undefined\n && ts.isStringLiteral(node.moduleSpecifier)) {\n add('module', node.moduleSpecifier.text, false)\n } else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference)\n && ts.isStringLiteral(node.moduleReference.expression)) {\n add('module', node.moduleReference.expression.text, false)\n } else if (ts.isCallExpression(node) && node.arguments.length > 0\n && ((node.expression.kind === ts.SyntaxKind.ImportKeyword)\n || (ts.isIdentifier(node.expression) && requireNames.has(node.expression.text)))) {\n const specifier = literalModule(node.arguments[0])\n if (specifier !== undefined) add('module', specifier, insideFunctionBody(node))\n } else if (ts.isNewExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'URL'\n && isImportMetaUrl(node.arguments?.[1])) {\n const specifier = literalModule(node.arguments?.[0])\n if (specifier !== undefined) add('asset', specifier, false)\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n return [...values.values()]\n}\n\nfunction externalPackage(specifier: string): string | undefined {\n // `bun:*` counts as a host builtin, not an npm dependency: Pi's official\n // distribution is a Bun-compiled binary, so ecosystem packages gate these\n // requires behind runtime detection and take their declared Node fallback\n // (better-sqlite3, node:sqlite) everywhere else.\n if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('#')\n || specifier.startsWith('node:') || specifier.startsWith('bun:')\n || builtinModules.includes(specifier)) return undefined\n const parts = specifier.split('/')\n return specifier.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0]\n}\n\nfunction insideTry(node: ts.Node): boolean {\n let current: ts.Node | undefined = node.parent\n while (current !== undefined) {\n if (ts.isTryStatement(current)) return true\n // Stop at function boundaries: a try in an outer function does not guard\n // an import inside a nested callback executed later.\n if (ts.isFunctionLike(current)) {\n // ...unless the whole function body IS awaited inside the try; keeping\n // this conservative check simple errs toward reporting the dependency.\n return false\n }\n current = current.parent\n }\n return false\n}\n\n// Inside any function body means the expression does not run while the module\n// itself loads — it runs when (if ever) that function is called.\nfunction insideFunctionBody(node: ts.Node): boolean {\n let current: ts.Node | undefined = node.parent\n while (current !== undefined) {\n if (ts.isFunctionLike(current)) return true\n current = current.parent\n }\n return false\n}\n\nexport interface RuntimeDependencyUse {\n name: string\n // true when every use sits on a lazy path (dynamic import/require inside a\n // function body): the module loads fine without the dependency, exactly as\n // under Pi, and only the feature that calls it needs the install.\n lazy: boolean\n}\n\nexport function runtimeExternalPackages(path: string, text: string): RuntimeDependencyUse[] {\n const source = ts.createSourceFile(path, text, ts.ScriptTarget.Latest, true, sourceKind(path))\n const packages = new Map<string, RuntimeDependencyUse>()\n const createRequireNames = new Set<string>(['createRequire'])\n const requireNames = new Set<string>(['require'])\n const add = (specifier: string, lazy: boolean): void => {\n const name = externalPackage(specifier)\n if (name === undefined || name.length === 0) return\n const existing = packages.get(name)\n if (existing === undefined) packages.set(name, { name, lazy })\n else if (existing.lazy && !lazy) existing.lazy = false\n }\n function collectRequireAliases(node: ts.Node): void {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)\n && (node.moduleSpecifier.text === 'node:module' || node.moduleSpecifier.text === 'module')\n && node.importClause?.namedBindings !== undefined && ts.isNamedImports(node.importClause.namedBindings)) {\n for (const element of node.importClause.namedBindings.elements) {\n if ((element.propertyName?.text ?? element.name.text) === 'createRequire') createRequireNames.add(element.name.text)\n }\n } else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)\n && node.initializer !== undefined && ts.isCallExpression(node.initializer)\n && ts.isIdentifier(node.initializer.expression) && createRequireNames.has(node.initializer.expression.text)) {\n requireNames.add(node.name.text)\n }\n ts.forEachChild(node, collectRequireAliases)\n }\n collectRequireAliases(source)\n function visit(node: ts.Node): void {\n if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {\n const clause = node.importClause\n const named = clause?.namedBindings\n const namedImportsAreTypeOnly = named !== undefined && ts.isNamedImports(named)\n && named.elements.length > 0 && named.elements.every(element => element.isTypeOnly)\n if (clause === undefined || (!clause.isTypeOnly && (clause.name !== undefined || !namedImportsAreTypeOnly))) {\n add(node.moduleSpecifier.text, false)\n }\n } else if (ts.isExportDeclaration(node) && !node.isTypeOnly\n && node.moduleSpecifier !== undefined && ts.isStringLiteral(node.moduleSpecifier)) {\n add(node.moduleSpecifier.text, false)\n } else if (ts.isImportEqualsDeclaration(node) && !node.isTypeOnly\n && ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) {\n add(node.moduleReference.expression.text, false)\n } else if (ts.isCallExpression(node) && node.arguments.length > 0\n && ((node.expression.kind === ts.SyntaxKind.ImportKeyword)\n || (ts.isIdentifier(node.expression) && requireNames.has(node.expression.text)))) {\n // A dynamic import/require wrapped in try/catch is the ecosystem's\n // optional-dependency idiom (e.g. pi-harness-runtime's \"// Dynamic\n // import for Playwright (optional dependency)\") — its absence is a\n // designed degradation, not an undeclared runtime requirement.\n if (!insideTry(node)) {\n const specifier = literalModule(node.arguments[0])\n if (specifier !== undefined) add(specifier, insideFunctionBody(node))\n }\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n return [...packages.values()]\n}\n\nfunction inside(rootDir: string, path: string): boolean {\n const pathRelative = relative(rootDir, path)\n return pathRelative === '' || (pathRelative !== '..' && !pathRelative.startsWith(`..${process.platform === 'win32' ? '\\\\' : '/'}`))\n}\n\nfunction sourceAlternates(base: string): string[] {\n const extension = extname(base)\n const stem = extension.length > 0 ? base.slice(0, -extension.length) : base\n if (extension === '.js') return [`${stem}.ts`, `${stem}.tsx`]\n if (extension === '.mjs') return [`${stem}.mts`, `${stem}.ts`]\n if (extension === '.cjs') return [`${stem}.cts`, `${stem}.ts`]\n if (extension === '.jsx') return [`${stem}.tsx`, `${stem}.ts`]\n return []\n}\n\nasync function isFile(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isFile()\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false\n throw error\n }\n}\n\nfunction subpathImportTarget(rootDir: string, specifier: string, importsMap: Record<string, unknown>): string | undefined {\n const conditionValue = (value: unknown): string | undefined => {\n if (typeof value === 'string') return value\n if (typeof value !== 'object' || value === null) return undefined\n const record = value as Record<string, unknown>\n for (const condition of ['import', 'node', 'default']) {\n const candidate = conditionValue(record[condition])\n if (candidate !== undefined) return candidate\n }\n return undefined\n }\n const direct = conditionValue(importsMap[specifier])\n if (direct !== undefined) return resolve(rootDir, direct)\n for (const [pattern, value] of Object.entries(importsMap)) {\n const star = pattern.indexOf('*')\n if (star === -1) continue\n const prefix = pattern.slice(0, star)\n const suffix = pattern.slice(star + 1)\n if (!specifier.startsWith(prefix) || !specifier.endsWith(suffix)) continue\n const wildcard = specifier.slice(prefix.length, specifier.length - suffix.length)\n const target = conditionValue(value)\n if (target !== undefined) return resolve(rootDir, target.replace('*', wildcard))\n }\n return undefined\n}\n\nasync function packageImportsMap(rootDir: string): Promise<Record<string, unknown>> {\n try {\n const parsed = JSON.parse(await readFile(join(rootDir, 'package.json'), 'utf8')) as { imports?: unknown }\n return typeof parsed.imports === 'object' && parsed.imports !== null ? parsed.imports as Record<string, unknown> : {}\n } catch {\n return {}\n }\n}\n\nasync function resolveModule(fromFile: string, specifier: string, rootDir: string, importsMap: Record<string, unknown>): Promise<string> {\n if (specifier.startsWith('#')) {\n const target = subpathImportTarget(rootDir, specifier, importsMap)\n if (target === undefined) {\n throw new Error(`cannot resolve subpath import ${JSON.stringify(specifier)} through the package \"imports\" map`)\n }\n return resolveModule(fromFile, relative(dirname(fromFile), target).startsWith('.')\n ? relative(dirname(fromFile), target)\n : `./${relative(dirname(fromFile), target)}`, rootDir, importsMap)\n }\n const base = resolve(dirname(fromFile), specifier)\n const candidates = [\n base,\n ...sourceAlternates(base),\n ...(extname(base) === '' ? MODULE_EXTENSIONS.map(extension => `${base}${extension}`) : []),\n ...MODULE_EXTENSIONS.map(extension => join(base, `index${extension}`)),\n ]\n for (const candidate of [...new Set(candidates)]) {\n if (!inside(rootDir, candidate)) throw new Error(`extension import escapes the Pi package: ${specifier} from ${fromFile}`)\n if (await isFile(candidate)) return candidate\n }\n throw new Error(`cannot resolve local extension import ${JSON.stringify(specifier)} from ${fromFile}`)\n}\n\nasync function expandAsset(path: string, rootDir: string): Promise<string[]> {\n if (!inside(rootDir, path)) throw new Error(`extension asset escapes the Pi package: ${path}`)\n let info\n try {\n info = await lstat(path)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n // A `new URL('./worker.js', import.meta.url)` asset may only exist in its\n // TypeScript source form before the package builds; track the source.\n for (const alternate of sourceAlternates(path)) {\n if (await isFile(alternate)) return [alternate]\n }\n throw error\n }\n if (info.isSymbolicLink()) throw new Error(`refusing to copy symbolic link from Pi package: ${path}`)\n if (info.isFile()) return [path]\n if (!info.isDirectory()) return []\n const output: string[] = []\n for (const entry of await readdir(path)) output.push(...await expandAsset(join(path, entry), rootDir))\n return output\n}\n\nexport async function collectLocalClosure(rootDir: string, entries: readonly string[]): Promise<LocalClosure> {\n const importsMap = await packageImportsMap(rootDir)\n const graph = new Map<string, Array<{ lazy: boolean, targets: string[] }>>()\n const issues: LocalClosureIssue[] = []\n const queue = entries.map(path => resolve(path))\n // Pass 1: the full local reference graph, lazy edges included, so the\n // snapshot carries every file any feature could ever load.\n while (queue.length > 0) {\n const source = queue.shift() as string\n if (graph.has(source)) continue\n if (!inside(rootDir, source)) throw new Error(`extension source escapes the Pi package: ${source}`)\n const info = await lstat(source)\n if (info.isSymbolicLink()) throw new Error(`refusing to copy symbolic link from Pi package: ${source}`)\n if (!info.isFile()) throw new Error(`extension closure contains a non-file path: ${source}`)\n const edges: Array<{ lazy: boolean, targets: string[] }> = []\n graph.set(source, edges)\n if (!SCRIPT_EXTENSIONS.has(extname(source))) continue\n const text = await readFile(source, 'utf8')\n for (const reference of localReferences(source, text)) {\n // Worker/data assets never execute while the entry loads; the feature\n // that spawns them does, so their whole subtree is a lazy path.\n const lazy = reference.lazy || reference.kind === 'asset'\n try {\n const targets = reference.kind === 'module'\n ? [await resolveModule(source, reference.specifier, rootDir, importsMap)]\n : await expandAsset(resolve(dirname(source), reference.specifier), rootDir)\n edges.push({ lazy, targets })\n queue.push(...targets)\n } catch (error) {\n issues.push({\n file: source,\n kind: reference.kind,\n specifier: reference.specifier,\n detail: error instanceof Error ? error.message : String(error),\n lazy,\n })\n }\n }\n }\n // Pass 2: load-time reachability across non-lazy module edges only. This is\n // the set whose problems actually break `pi` (and pi2dsh) at extension load;\n // everything else fails at feature-use time, identically under both hosts.\n const loadTimeFiles = new Set<string>()\n const loadQueue = entries.map(path => resolve(path)).filter(path => graph.has(path))\n while (loadQueue.length > 0) {\n const source = loadQueue.shift() as string\n if (loadTimeFiles.has(source)) continue\n loadTimeFiles.add(source)\n for (const edge of graph.get(source) ?? []) {\n if (edge.lazy) continue\n for (const target of edge.targets) {\n if (!loadTimeFiles.has(target)) loadQueue.push(target)\n }\n }\n }\n // An issue found inside a file that itself only loads lazily cannot break\n // extension load either, however the reference is written.\n for (const issue of issues) {\n if (!loadTimeFiles.has(issue.file)) issue.lazy = true\n }\n return { files: [...graph.keys()].sort(), loadTimeFiles, issues }\n}\n","import { readFile } from 'node:fs/promises'\nimport { basename, extname, relative } from 'node:path'\nimport ts from 'typescript'\nimport {\n PI_CODING_AGENT_PACKAGES,\n PI_AI_PACKAGES,\n PI_TUI_PACKAGES,\n ruleForApi,\n ruleForContextProperty,\n ruleForEvent,\n ruleForHostImport,\n ruleForUiContextProperty,\n} from './compatibility.js'\nimport { collectLocalClosure, runtimeExternalPackages, SCRIPT_EXTENSIONS, sourceKind } from './module-graph.js'\nimport type {\n CompatibilityFinding,\n CompatibilityLevel,\n CompatibilityReport,\n ResolvedPiPackage,\n} from './types.js'\n\nfunction literalText(node: ts.Node | undefined): string | undefined {\n return node !== undefined && (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node))\n ? node.text\n : undefined\n}\n\nfunction hasModifier(node: ts.Node, kind: ts.SyntaxKind): boolean {\n return ts.canHaveModifiers(node) && ts.getModifiers(node)?.some(modifier => modifier.kind === kind) === true\n}\n\nfunction parameterIdentifier(node: ts.SignatureDeclarationBase): string | undefined {\n const parameter = node.parameters[0]\n return parameter !== undefined && ts.isIdentifier(parameter.name) ? parameter.name.text : undefined\n}\n\nfunction extensionApiReceivers(source: ts.SourceFile): Set<string> {\n const receivers = new Set<string>()\n const functions = new Map<string, ts.FunctionLikeDeclarationBase>()\n\n function index(node: ts.Node): void {\n if (ts.isFunctionDeclaration(node) && node.name !== undefined) functions.set(node.name.text, node)\n if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)\n && node.initializer !== undefined\n && (ts.isArrowFunction(node.initializer) || ts.isFunctionExpression(node.initializer))) {\n functions.set(node.name.text, node.initializer)\n }\n if (ts.isParameter(node) && node.type !== undefined\n && /(?:^|\\.)ExtensionAPI\\b/u.test(node.type.getText(source)) && ts.isIdentifier(node.name)) {\n receivers.add(node.name.text)\n }\n // Published Pi packages commonly ship JavaScript with type annotations\n // erased. `pi` is the documented ExtensionAPI parameter name throughout\n // the ecosystem, including helper functions reached from the entry point.\n if (ts.isParameter(node) && ts.isIdentifier(node.name)\n && /^(?:pi|extensionApi)$/iu.test(node.name.text)) {\n receivers.add(node.name.text)\n }\n ts.forEachChild(node, index)\n }\n index(source)\n\n for (const statement of source.statements) {\n if (ts.isFunctionDeclaration(statement)\n && hasModifier(statement, ts.SyntaxKind.ExportKeyword)\n && hasModifier(statement, ts.SyntaxKind.DefaultKeyword)) {\n const name = parameterIdentifier(statement)\n if (name !== undefined) receivers.add(name)\n }\n if (ts.isExportAssignment(statement)) {\n const expression = statement.expression\n if (ts.isArrowFunction(expression) || ts.isFunctionExpression(expression)) {\n const name = parameterIdentifier(expression)\n if (name !== undefined) receivers.add(name)\n } else if (ts.isIdentifier(expression)) {\n const candidate = functions.get(expression.text)\n if (candidate !== undefined) {\n const name = parameterIdentifier(candidate)\n if (name !== undefined) receivers.add(name)\n }\n }\n }\n if (ts.isExportDeclaration(statement) && statement.moduleSpecifier === undefined\n && statement.exportClause !== undefined && ts.isNamedExports(statement.exportClause)) {\n for (const element of statement.exportClause.elements) {\n if (element.name.text !== 'default' || element.propertyName === undefined || !ts.isIdentifier(element.propertyName)) continue\n const candidate = functions.get(element.propertyName.text)\n if (candidate !== undefined) {\n const name = parameterIdentifier(candidate)\n if (name !== undefined) receivers.add(name)\n }\n }\n }\n }\n return receivers\n}\n\nfunction extensionApiProperties(source: ts.SourceFile, receivers: ReadonlySet<string>): Set<string> {\n const properties = new Set<string>()\n function visit(node: ts.Node): void {\n if ((ts.isPropertyDeclaration(node) || ts.isParameter(node)) && ts.isIdentifier(node.name)) {\n const typed = node.type !== undefined && /(?:^|\\.)(?:Pi)?ExtensionAPI\\b/u.test(node.type.getText(source))\n if (typed || /^(?:pi|extensionApi)$/iu.test(node.name.text)) properties.add(node.name.text)\n } else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken\n && ts.isPropertyAccessExpression(node.left) && node.left.expression.kind === ts.SyntaxKind.ThisKeyword\n && ts.isIdentifier(node.right) && receivers.has(node.right.text)) {\n properties.add(node.left.name.text)\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n return properties\n}\n\nfunction enclosingFunctionName(node: ts.ParameterDeclaration): string | undefined {\n const parent = node.parent\n if (ts.isMethodDeclaration(parent) && parent.name !== undefined) return parent.name.getText()\n if ((ts.isArrowFunction(parent) || ts.isFunctionExpression(parent)) && ts.isPropertyAssignment(parent.parent)) {\n return parent.parent.name.getText()\n }\n return undefined\n}\n\nfunction extensionContextReceivers(source: ts.SourceFile): Set<string> {\n const receivers = new Set<string>()\n function visit(node: ts.Node): void {\n if (ts.isParameter(node) && ts.isIdentifier(node.name)) {\n const typedContext = node.type !== undefined\n && /(?:^|\\.)(?:Extension|ExtensionCommand|ToolExecution)Context\\b/u.test(node.type.getText(source))\n const conventionalHandlerContext = /^(?:ctx|context)$/iu.test(node.name.text)\n && /^(?:execute|handler)$/u.test(enclosingFunctionName(node) ?? '')\n if (typedContext || conventionalHandlerContext) receivers.add(node.name.text)\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n return receivers\n}\n\n// The three Pi packages whose named exports the shim audit tracks.\nconst PI_SHIMMED_PACKAGES = new Set<string>([\n ...PI_CODING_AGENT_PACKAGES,\n ...PI_TUI_PACKAGES,\n ...PI_AI_PACKAGES,\n])\n\n// Everything Pi's loader provides to extensions without a declaration —\n// exempt from the undeclared-runtime-dependency fatal, and (for typebox) not\n// subject to per-symbol shim auditing.\nconst PI_HOST_PACKAGES = new Set<string>([\n ...PI_SHIMMED_PACKAGES,\n 'typebox',\n '@sinclair/typebox',\n])\n\nfunction dependencyNames(packageJson: Record<string, unknown>): Set<string> {\n const names = new Set<string>()\n for (const field of ['dependencies', 'optionalDependencies', 'peerDependencies']) {\n const value = packageJson[field]\n if (typeof value !== 'object' || value === null || Array.isArray(value)) continue\n for (const [name, specifier] of Object.entries(value)) {\n if (typeof specifier === 'string') names.add(name)\n }\n }\n return names\n}\n\nfunction pushFinding(\n findings: CompatibilityFinding[],\n rootDir: string,\n file: string,\n source: ts.SourceFile,\n node: ts.Node,\n capability: string,\n level: CompatibilityLevel,\n detail: string,\n): void {\n const position = source.getLineAndCharacterOfPosition(node.getStart(source))\n findings.push({\n capability,\n level,\n file: relative(rootDir, file).replaceAll('\\\\', '/'),\n line: position.line + 1,\n detail,\n })\n}\n\nasync function analyzeExtension(rootDir: string, file: string): Promise<CompatibilityFinding[]> {\n const text = await readFile(file, 'utf8')\n const source = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true, sourceKind(file))\n const findings: CompatibilityFinding[] = []\n const receivers = extensionApiReceivers(source)\n const apiProperties = extensionApiProperties(source, receivers)\n const contextReceivers = extensionContextReceivers(source)\n const methodAliases = new Map<string, string>()\n const eventBusAliases = new Set<string>()\n const uiAliases = new Set<string>()\n\n function reportHostImport(packageName: string, importedName: string, node: ts.Node): void {\n const matched = ruleForHostImport(packageName, importedName)\n if (matched === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, `host-import(${packageName}:${importedName})`, 'unsupported',\n `The pi2dsh host shim does not export ${JSON.stringify(importedName)} from ${JSON.stringify(packageName)}.`,\n )\n return\n }\n pushFinding(\n findings, rootDir, file, source, node, `host-import(${packageName}:${importedName})`, matched.level, matched.detail,\n )\n }\n\n for (const statement of source.statements) {\n if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)\n && PI_SHIMMED_PACKAGES.has(statement.moduleSpecifier.text)) {\n const packageName = statement.moduleSpecifier.text\n const clause = statement.importClause\n if (clause === undefined) {\n reportHostImport(packageName, '<side-effect>', statement)\n continue\n }\n if (clause.isTypeOnly) continue\n if (clause.name !== undefined) reportHostImport(packageName, 'default', clause.name)\n if (clause.namedBindings !== undefined && ts.isNamespaceImport(clause.namedBindings)) {\n reportHostImport(packageName, '*', clause.namedBindings)\n } else if (clause.namedBindings !== undefined) {\n for (const element of clause.namedBindings.elements) {\n if (!element.isTypeOnly) reportHostImport(packageName, element.propertyName?.text ?? element.name.text, element)\n }\n }\n } else if (ts.isExportDeclaration(statement) && !statement.isTypeOnly\n && statement.moduleSpecifier !== undefined && ts.isStringLiteral(statement.moduleSpecifier)\n && PI_HOST_PACKAGES.has(statement.moduleSpecifier.text)) {\n const packageName = statement.moduleSpecifier.text\n if (statement.exportClause === undefined || ts.isNamespaceExport(statement.exportClause)) {\n reportHostImport(packageName, '*', statement)\n } else {\n for (const element of statement.exportClause.elements) {\n if (!element.isTypeOnly) reportHostImport(packageName, element.propertyName?.text ?? element.name.text, element)\n }\n }\n } else if (ts.isImportEqualsDeclaration(statement) && !statement.isTypeOnly\n && ts.isExternalModuleReference(statement.moduleReference)\n && ts.isStringLiteral(statement.moduleReference.expression)\n && PI_HOST_PACKAGES.has(statement.moduleReference.expression.text)) {\n reportHostImport(statement.moduleReference.expression.text, '*', statement)\n }\n }\n\n const declarations: ts.VariableDeclaration[] = []\n const isApiReceiver = (node: ts.Expression): boolean => ts.isIdentifier(node) && receivers.has(node.text)\n || (ts.isPropertyAccessExpression(node) && node.expression.kind === ts.SyntaxKind.ThisKeyword\n && apiProperties.has(node.name.text))\n function collectDeclarations(node: ts.Node): void {\n if (ts.isVariableDeclaration(node)) declarations.push(node)\n ts.forEachChild(node, collectDeclarations)\n }\n collectDeclarations(source)\n\n for (let pass = 0; pass < declarations.length + 1; pass += 1) {\n let changed = false\n for (const declaration of declarations) {\n const initializer = declaration.initializer\n if (initializer === undefined) continue\n if (ts.isIdentifier(declaration.name) && isApiReceiver(initializer)) {\n if (!receivers.has(declaration.name.text)) {\n receivers.add(declaration.name.text)\n changed = true\n }\n }\n if (ts.isIdentifier(declaration.name) && ts.isIdentifier(initializer) && contextReceivers.has(initializer.text)) {\n if (!contextReceivers.has(declaration.name.text)) {\n contextReceivers.add(declaration.name.text)\n changed = true\n }\n }\n if (ts.isIdentifier(declaration.name) && ts.isPropertyAccessExpression(initializer)\n && initializer.name.text === 'ui' && ts.isIdentifier(initializer.expression)\n && contextReceivers.has(initializer.expression.text) && !uiAliases.has(declaration.name.text)) {\n uiAliases.add(declaration.name.text)\n changed = true\n }\n if (ts.isIdentifier(declaration.name) && ts.isPropertyAccessExpression(initializer)\n && isApiReceiver(initializer.expression)) {\n if (initializer.name.text === 'events') {\n if (!eventBusAliases.has(declaration.name.text)) {\n eventBusAliases.add(declaration.name.text)\n changed = true\n }\n } else if (!methodAliases.has(declaration.name.text)) {\n methodAliases.set(declaration.name.text, initializer.name.text)\n changed = true\n }\n }\n if (ts.isObjectBindingPattern(declaration.name) && isApiReceiver(initializer)) {\n for (const element of declaration.name.elements) {\n if (!ts.isIdentifier(element.name)) continue\n const method = element.propertyName !== undefined && ts.isIdentifier(element.propertyName)\n ? element.propertyName.text\n : element.name.text\n if (method === 'events') {\n if (!eventBusAliases.has(element.name.text)) {\n eventBusAliases.add(element.name.text)\n changed = true\n }\n } else if (!methodAliases.has(element.name.text)) {\n methodAliases.set(element.name.text, method)\n changed = true\n }\n }\n }\n }\n if (!changed) break\n }\n\n function reportMethod(method: string, args: ts.NodeArray<ts.Expression>, node: ts.Node): void {\n if (method === 'on') {\n const event = literalText(args[0])\n if (event === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, 'on(<dynamic>)', 'unsupported',\n 'Dynamic event names cannot be audited or mapped safely.',\n )\n } else {\n const rule = ruleForEvent(event)\n pushFinding(findings, rootDir, file, source, node, `on(${event})`, rule.level, rule.detail)\n }\n return\n }\n const rule = ruleForApi(method)\n if (rule === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, method, 'unsupported',\n `Unknown ExtensionAPI method ${JSON.stringify(method)} cannot be audited or mapped safely.`,\n )\n return\n }\n pushFinding(findings, rootDir, file, source, node, method, rule.level, rule.detail)\n }\n\n function reportEventBus(method: string, node: ts.Node): void {\n const rule = ruleForApi('events')\n if ((method === 'on' || method === 'emit') && rule !== undefined) {\n pushFinding(findings, rootDir, file, source, node, `events.${method}`, rule.level, rule.detail)\n } else {\n pushFinding(\n findings, rootDir, file, source, node, `events.${method}`, 'unsupported',\n `Unknown Pi event-bus method ${JSON.stringify(method)} cannot be mapped safely.`,\n )\n }\n }\n\n function reportContext(property: string, node: ts.Node): void {\n const matched = ruleForContextProperty(property)\n if (matched === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, `ctx.${property}`, 'unsupported',\n `Unknown Pi extension-context property ${JSON.stringify(property)} cannot be audited or mapped safely.`,\n )\n } else {\n pushFinding(findings, rootDir, file, source, node, `ctx.${property}`, matched.level, matched.detail)\n }\n }\n\n function reportUiContext(property: string, node: ts.Node): void {\n const matched = ruleForUiContextProperty(property)\n if (matched === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, `ctx.ui.${property}`, 'unsupported',\n `Unknown Pi UI-context property ${JSON.stringify(property)} cannot be audited or mapped safely.`,\n )\n } else {\n pushFinding(findings, rootDir, file, source, node, `ctx.ui.${property}`, matched.level, matched.detail)\n }\n }\n\n function visit(node: ts.Node): void {\n if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {\n const method = methodAliases.get(node.expression.text)\n if (method !== undefined) reportMethod(method, node.arguments, node)\n } else if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {\n const target = node.expression.expression\n if (isApiReceiver(target)) {\n reportMethod(node.expression.name.text, node.arguments, node)\n } else if (ts.isIdentifier(target) && eventBusAliases.has(target.text)) {\n reportEventBus(node.expression.name.text, node)\n } else if (ts.isPropertyAccessExpression(target)\n && target.name.text === 'events'\n && isApiReceiver(target.expression)) {\n reportEventBus(node.expression.name.text, node)\n }\n } else if (ts.isCallExpression(node) && ts.isElementAccessExpression(node.expression)\n && isApiReceiver(node.expression.expression)) {\n const method = literalText(node.expression.argumentExpression)\n if (method === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, '<dynamic-api-method>', 'unsupported',\n 'Dynamic ExtensionAPI method access cannot be audited or mapped safely.',\n )\n } else {\n reportMethod(method, node.arguments, node)\n }\n }\n if (ts.isPropertyAccessExpression(node)) {\n const target = node.expression\n if (ts.isPropertyAccessExpression(target) && target.name.text === 'ui'\n && ts.isIdentifier(target.expression) && contextReceivers.has(target.expression.text)) {\n reportUiContext(node.name.text, node)\n } else if (ts.isIdentifier(target) && uiAliases.has(target.text)) {\n reportUiContext(node.name.text, node)\n } else if (ts.isIdentifier(target) && contextReceivers.has(target.text) && node.name.text !== 'ui') {\n reportContext(node.name.text, node)\n }\n } else if (ts.isElementAccessExpression(node) && ts.isIdentifier(node.expression)\n && contextReceivers.has(node.expression.text)) {\n const property = literalText(node.argumentExpression)\n if (property === undefined) {\n pushFinding(\n findings, rootDir, file, source, node, 'ctx.<dynamic>', 'unsupported',\n 'Dynamic Pi extension-context access cannot be audited or mapped safely.',\n )\n } else if (property !== 'ui') {\n reportContext(property, node)\n }\n }\n ts.forEachChild(node, visit)\n }\n\n visit(source)\n return findings\n}\n\nexport async function analyzePackage(pkg: ResolvedPiPackage): Promise<CompatibilityReport> {\n const extensionClosure = await collectLocalClosure(pkg.rootDir, pkg.resources.extensions)\n const findings = (await Promise.all(\n extensionClosure.files.filter(file => SCRIPT_EXTENSIONS.has(extname(file)))\n .map(file => analyzeExtension(pkg.rootDir, file)),\n )).flat()\n\n if (pkg.resources.extensions.length > 0 && findings.length === 0) {\n findings.push({\n capability: 'static-audit',\n level: 'unsupported',\n file: pkg.resources.extensions.map(file => relative(pkg.rootDir, file).replaceAll('\\\\', '/')).join(', '),\n line: 1,\n detail: 'No ExtensionAPI use was statically proven across the local module closure; conversion fails closed instead of claiming compatibility.',\n })\n }\n for (const issue of extensionClosure.issues) {\n // Only a break on the load-time path blocks the package: Pi's own loader\n // fails the same lazy references at feature-use time, and the snapshot\n // preserves the published file layout, so behavior matches Pi exactly.\n const lazyIssue = issue.lazy || issue.kind === 'asset'\n findings.push({\n capability: `${issue.kind}(${issue.specifier})`,\n level: lazyIssue ? 'partial' : 'fatal',\n file: relative(pkg.rootDir, issue.file).replaceAll('\\\\', '/'),\n line: 1,\n detail: lazyIssue\n ? `Unresolved reference on a lazy path: ${issue.detail}. Extension load is unaffected; if the feature that evaluates it runs, it fails the same way under Pi (published file layout is preserved).`\n : `The local extension closure is incomplete: ${issue.detail}`,\n })\n }\n\n const declaredDependencies = dependencyNames(pkg.packageJson)\n for (const file of extensionClosure.files.filter(candidate => SCRIPT_EXTENSIONS.has(extname(candidate)))) {\n const text = await readFile(file, 'utf8')\n const lazyFile = !extensionClosure.loadTimeFiles.has(file)\n for (const use of runtimeExternalPackages(file, text)) {\n if (PI_HOST_PACKAGES.has(use.name) || declaredDependencies.has(use.name)) continue\n // Undeclared imports only crash extension load when they execute at load\n // time. On lazy paths (function-body dynamic imports, or files that are\n // themselves only lazily reachable) Pi degrades per-feature; mirror that.\n const lazyUse = use.lazy || lazyFile\n findings.push({\n capability: lazyUse ? `optional-lazy-dependency(${use.name})` : `undeclared-runtime-dependency(${use.name})`,\n level: lazyUse ? 'partial' : 'fatal',\n file: relative(pkg.rootDir, file).replaceAll('\\\\', '/'),\n line: 1,\n detail: lazyUse\n ? `The extension imports ${JSON.stringify(use.name)} only on a lazily-evaluated path without declaring it; the feature that needs it asks for the module at call time, exactly as under Pi (install ${use.name} to use that feature).`\n : `The extension imports ${JSON.stringify(use.name)} at load time, but the Pi package does not declare it as a dependency.`,\n })\n }\n }\n\n const resourceFinding = (file: string, capability: string, level: CompatibilityLevel, detail: string): CompatibilityFinding => ({\n capability,\n level,\n file: relative(pkg.rootDir, file).replaceAll('\\\\', '/'),\n line: 1,\n detail,\n })\n for (const file of pkg.resources.skills.filter(path => basename(path) === 'SKILL.md' || path.endsWith('.md'))) {\n findings.push(resourceFinding(file, 'skill', 'full', 'Copied as a DSH filesystem skill with its resource directory intact.'))\n }\n for (const file of pkg.resources.prompts) {\n findings.push(resourceFinding(file, 'prompt', 'full', 'Registered as a DSH slash command with Pi-compatible argument expansion.'))\n }\n for (const file of pkg.resources.themes) {\n findings.push(resourceFinding(file, 'theme', 'unsupported', 'Pi terminal themes have no effect in DSH Web or headless surfaces.'))\n }\n findings.sort((left, right) => left.file.localeCompare(right.file) || left.line - right.line || left.capability.localeCompare(right.capability))\n\n const summary: Record<CompatibilityLevel, number> = { full: 0, partial: 0, unsupported: 0, fatal: 0 }\n for (const finding of findings) summary[finding.level] += 1\n // Static analysis screens; it does not certify. Only fatal findings block a\n // bundle (it cannot be built or trusted). Everything else installs: verify\n // real behavior with the black-box run instead of trusting this verdict.\n const verdict = summary.fatal > 0 ? 'blocked' : summary.partial > 0 || summary.unsupported > 0 ? 'review' : 'ready'\n\n return {\n schemaVersion: 1,\n package: pkg.identity,\n verdict,\n summary,\n resources: {\n extensions: pkg.resources.extensions.map(file => relative(pkg.rootDir, file).replaceAll('\\\\', '/')),\n skills: pkg.resources.skills.map(file => relative(pkg.rootDir, file).replaceAll('\\\\', '/')),\n prompts: pkg.resources.prompts.map(file => relative(pkg.rootDir, file).replaceAll('\\\\', '/')),\n themes: pkg.resources.themes.map(file => relative(pkg.rootDir, file).replaceAll('\\\\', '/')),\n },\n findings,\n }\n}\n"],"mappings":";;;;;;;AAKA,MAAa,oCAAoB,IAAI,IAAI;CAAC;CAAO;CAAQ;CAAQ;CAAQ;CAAO;CAAQ;CAAQ;AAAM,CAAC;AACvG,MAAM,oBAAoB;CAAC;CAAO;CAAQ;CAAQ;CAAQ;CAAO;CAAQ;CAAQ;CAAQ;AAAO;AA6BhG,SAAgB,WAAW,MAA6B;CACtD,IAAI,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,MAAM,GAAG,OAAO,GAAG,WAAW;CACjG,IAAI,KAAK,SAAS,MAAM,GAAG,OAAO,GAAG,WAAW;CAChD,IAAI,KAAK,SAAS,MAAM,GAAG,OAAO,GAAG,WAAW;CAChD,OAAO,GAAG,WAAW;AACvB;AAEA,SAAS,cAAc,MAAqD;CAC1E,OAAO,SAAS,KAAA,MAAc,GAAG,gBAAgB,IAAI,KAAK,GAAG,gCAAgC,IAAI,KAAK,KAAK,OAAO,KAAA;AACpH;AAEA,SAAS,gBAAgB,MAA0C;CACjE,OAAO,SAAS,KAAA,KAAa,GAAG,2BAA2B,IAAI,KAAK,KAAK,KAAK,SAAS,SAClF,GAAG,eAAe,KAAK,UAAU,KAAK,KAAK,WAAW,iBAAiB,GAAG,WAAW;AAC5F;AAEA,SAAS,gBAAgB,MAAc,MAAgC;CACrE,MAAM,SAAS,GAAG,iBAAiB,MAAM,MAAM,GAAG,aAAa,QAAQ,MAAM,WAAW,IAAI,CAAC;CAC7F,MAAM,yBAAS,IAAI,IAA4B;CAC/C,MAAM,qCAAqB,IAAI,IAAY,CAAC,eAAe,CAAC;CAC5D,MAAM,+BAAe,IAAI,IAAY,CAAC,SAAS,CAAC;CAChD,MAAM,OAAO,MAA8B,WAAmB,SAAwB;EAGpF,IAAI,CAAC,UAAU,WAAW,GAAG,KAAK,CAAC,UAAU,WAAW,GAAG,GAAG;EAC9D,MAAM,MAAM,GAAG,KAAK,GAAG;EACvB,MAAM,WAAW,OAAO,IAAI,GAAG;EAE/B,IAAI,aAAa,KAAA,GAAW,OAAO,IAAI,KAAK;GAAE;GAAM;GAAW;EAAK,CAAC;OAChE,IAAI,SAAS,QAAQ,CAAC,MAAM,SAAS,OAAO;CACnD;CACA,SAAS,sBAAsB,MAAqB;EAClD,IAAI,GAAG,oBAAoB,IAAI,KAAK,GAAG,gBAAgB,KAAK,eAAe,MACrE,KAAK,gBAAgB,SAAS,iBAAiB,KAAK,gBAAgB,SAAS,aAC9E,KAAK,cAAc,kBAAkB,KAAA,KAAa,GAAG,eAAe,KAAK,aAAa,aAAa,GACjG;QAAA,MAAM,WAAW,KAAK,aAAa,cAAc,UACpD,KAAK,QAAQ,cAAc,QAAQ,QAAQ,KAAK,UAAU,iBAAiB,mBAAmB,IAAI,QAAQ,KAAK,IAAI;EAAA,OAEhH,IAAI,GAAG,sBAAsB,IAAI,KAAK,GAAG,aAAa,KAAK,IAAI,KACjE,KAAK,gBAAgB,KAAA,KAAa,GAAG,iBAAiB,KAAK,WAAW,KACtE,GAAG,aAAa,KAAK,YAAY,UAAU,KAAK,mBAAmB,IAAI,KAAK,YAAY,WAAW,IAAI,GAC1G,aAAa,IAAI,KAAK,KAAK,IAAI;EAEjC,GAAG,aAAa,MAAM,qBAAqB;CAC7C;CACA,sBAAsB,MAAM;CAC5B,SAAS,MAAM,MAAqB;EAClC,KAAK,GAAG,oBAAoB,IAAI,KAAK,GAAG,oBAAoB,IAAI,MAAM,KAAK,oBAAoB,KAAA,KAC1F,GAAG,gBAAgB,KAAK,eAAe,GAC1C,IAAI,UAAU,KAAK,gBAAgB,MAAM,KAAK;OACzC,IAAI,GAAG,0BAA0B,IAAI,KAAK,GAAG,0BAA0B,KAAK,eAAe,KAC7F,GAAG,gBAAgB,KAAK,gBAAgB,UAAU,GACrD,IAAI,UAAU,KAAK,gBAAgB,WAAW,MAAM,KAAK;OACpD,IAAI,GAAG,iBAAiB,IAAI,KAAK,KAAK,UAAU,SAAS,MACzD,KAAK,WAAW,SAAS,GAAG,WAAW,iBACtC,GAAG,aAAa,KAAK,UAAU,KAAK,aAAa,IAAI,KAAK,WAAW,IAAI,IAAK;GACpF,MAAM,YAAY,cAAc,KAAK,UAAU,EAAE;GACjD,IAAI,cAAc,KAAA,GAAW,IAAI,UAAU,WAAW,mBAAmB,IAAI,CAAC;EAChF,OAAO,IAAI,GAAG,gBAAgB,IAAI,KAAK,GAAG,aAAa,KAAK,UAAU,KAAK,KAAK,WAAW,SAAS,SAC/F,gBAAgB,KAAK,YAAY,EAAE,GAAG;GACzC,MAAM,YAAY,cAAc,KAAK,YAAY,EAAE;GACnD,IAAI,cAAc,KAAA,GAAW,IAAI,SAAS,WAAW,KAAK;EAC5D;EACA,GAAG,aAAa,MAAM,KAAK;CAC7B;CACA,MAAM,MAAM;CACZ,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAC5B;AAEA,SAAS,gBAAgB,WAAuC;CAK9D,IAAI,UAAU,WAAW,GAAG,KAAK,UAAU,WAAW,GAAG,KAAK,UAAU,WAAW,GAAG,KACjF,UAAU,WAAW,OAAO,KAAK,UAAU,WAAW,MAAM,KAC5D,eAAe,SAAS,SAAS,GAAG,OAAO,KAAA;CAChD,MAAM,QAAQ,UAAU,MAAM,GAAG;CACjC,OAAO,UAAU,WAAW,GAAG,IAAI,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM;AACzE;AAEA,SAAS,UAAU,MAAwB;CACzC,IAAI,UAA+B,KAAK;CACxC,OAAO,YAAY,KAAA,GAAW;EAC5B,IAAI,GAAG,eAAe,OAAO,GAAG,OAAO;EAGvC,IAAI,GAAG,eAAe,OAAO,GAG3B,OAAO;EAET,UAAU,QAAQ;CACpB;CACA,OAAO;AACT;AAIA,SAAS,mBAAmB,MAAwB;CAClD,IAAI,UAA+B,KAAK;CACxC,OAAO,YAAY,KAAA,GAAW;EAC5B,IAAI,GAAG,eAAe,OAAO,GAAG,OAAO;EACvC,UAAU,QAAQ;CACpB;CACA,OAAO;AACT;AAUA,SAAgB,wBAAwB,MAAc,MAAsC;CAC1F,MAAM,SAAS,GAAG,iBAAiB,MAAM,MAAM,GAAG,aAAa,QAAQ,MAAM,WAAW,IAAI,CAAC;CAC7F,MAAM,2BAAW,IAAI,IAAkC;CACvD,MAAM,qCAAqB,IAAI,IAAY,CAAC,eAAe,CAAC;CAC5D,MAAM,+BAAe,IAAI,IAAY,CAAC,SAAS,CAAC;CAChD,MAAM,OAAO,WAAmB,SAAwB;EACtD,MAAM,OAAO,gBAAgB,SAAS;EACtC,IAAI,SAAS,KAAA,KAAa,KAAK,WAAW,GAAG;EAC7C,MAAM,WAAW,SAAS,IAAI,IAAI;EAClC,IAAI,aAAa,KAAA,GAAW,SAAS,IAAI,MAAM;GAAE;GAAM;EAAK,CAAC;OACxD,IAAI,SAAS,QAAQ,CAAC,MAAM,SAAS,OAAO;CACnD;CACA,SAAS,sBAAsB,MAAqB;EAClD,IAAI,GAAG,oBAAoB,IAAI,KAAK,GAAG,gBAAgB,KAAK,eAAe,MACrE,KAAK,gBAAgB,SAAS,iBAAiB,KAAK,gBAAgB,SAAS,aAC9E,KAAK,cAAc,kBAAkB,KAAA,KAAa,GAAG,eAAe,KAAK,aAAa,aAAa,GACjG;QAAA,MAAM,WAAW,KAAK,aAAa,cAAc,UACpD,KAAK,QAAQ,cAAc,QAAQ,QAAQ,KAAK,UAAU,iBAAiB,mBAAmB,IAAI,QAAQ,KAAK,IAAI;EAAA,OAEhH,IAAI,GAAG,sBAAsB,IAAI,KAAK,GAAG,aAAa,KAAK,IAAI,KACjE,KAAK,gBAAgB,KAAA,KAAa,GAAG,iBAAiB,KAAK,WAAW,KACtE,GAAG,aAAa,KAAK,YAAY,UAAU,KAAK,mBAAmB,IAAI,KAAK,YAAY,WAAW,IAAI,GAC1G,aAAa,IAAI,KAAK,KAAK,IAAI;EAEjC,GAAG,aAAa,MAAM,qBAAqB;CAC7C;CACA,sBAAsB,MAAM;CAC5B,SAAS,MAAM,MAAqB;EAClC,IAAI,GAAG,oBAAoB,IAAI,KAAK,GAAG,gBAAgB,KAAK,eAAe,GAAG;GAC5E,MAAM,SAAS,KAAK;GACpB,MAAM,QAAQ,QAAQ;GACtB,MAAM,0BAA0B,UAAU,KAAA,KAAa,GAAG,eAAe,KAAK,KACzE,MAAM,SAAS,SAAS,KAAK,MAAM,SAAS,OAAM,YAAW,QAAQ,UAAU;GACpF,IAAI,WAAW,KAAA,KAAc,CAAC,OAAO,eAAe,OAAO,SAAS,KAAA,KAAa,CAAC,0BAChF,IAAI,KAAK,gBAAgB,MAAM,KAAK;EAExC,OAAO,IAAI,GAAG,oBAAoB,IAAI,KAAK,CAAC,KAAK,cAC5C,KAAK,oBAAoB,KAAA,KAAa,GAAG,gBAAgB,KAAK,eAAe,GAChF,IAAI,KAAK,gBAAgB,MAAM,KAAK;OAC/B,IAAI,GAAG,0BAA0B,IAAI,KAAK,CAAC,KAAK,cAClD,GAAG,0BAA0B,KAAK,eAAe,KAAK,GAAG,gBAAgB,KAAK,gBAAgB,UAAU,GAC3G,IAAI,KAAK,gBAAgB,WAAW,MAAM,KAAK;OAC1C,IAAI,GAAG,iBAAiB,IAAI,KAAK,KAAK,UAAU,SAAS,MACzD,KAAK,WAAW,SAAS,GAAG,WAAW,iBACtC,GAAG,aAAa,KAAK,UAAU,KAAK,aAAa,IAAI,KAAK,WAAW,IAAI,IAK3E;OAAA,CAAC,UAAU,IAAI,GAAG;IACpB,MAAM,YAAY,cAAc,KAAK,UAAU,EAAE;IACjD,IAAI,cAAc,KAAA,GAAW,IAAI,WAAW,mBAAmB,IAAI,CAAC;GACtE;;EAEF,GAAG,aAAa,MAAM,KAAK;CAC7B;CACA,MAAM,MAAM;CACZ,OAAO,CAAC,GAAG,SAAS,OAAO,CAAC;AAC9B;AAEA,SAAS,OAAO,SAAiB,MAAuB;CACtD,MAAM,eAAe,SAAS,SAAS,IAAI;CAC3C,OAAO,iBAAiB,MAAO,iBAAiB,QAAQ,CAAC,aAAa,WAAW,KAAK,QAAQ,aAAa,UAAU,OAAO,KAAK;AACnI;AAEA,SAAS,iBAAiB,MAAwB;CAChD,MAAM,YAAY,QAAQ,IAAI;CAC9B,MAAM,OAAO,UAAU,SAAS,IAAI,KAAK,MAAM,GAAG,CAAC,UAAU,MAAM,IAAI;CACvE,IAAI,cAAc,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM,GAAG,KAAK,KAAK;CAC5D,IAAI,cAAc,QAAQ,OAAO,CAAC,GAAG,KAAK,OAAO,GAAG,KAAK,IAAI;CAC7D,IAAI,cAAc,QAAQ,OAAO,CAAC,GAAG,KAAK,OAAO,GAAG,KAAK,IAAI;CAC7D,IAAI,cAAc,QAAQ,OAAO,CAAC,GAAG,KAAK,OAAO,GAAG,KAAK,IAAI;CAC7D,OAAO,CAAC;AACV;AAEA,eAAe,OAAO,MAAgC;CACpD,IAAI;EACF,QAAQ,MAAM,KAAK,IAAI,EAAA,CAAG,OAAO;CACnC,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAAU,OAAO;EAC/D,MAAM;CACR;AACF;AAEA,SAAS,oBAAoB,SAAiB,WAAmB,YAAyD;CACxH,MAAM,kBAAkB,UAAuC;EAC7D,IAAI,OAAO,UAAU,UAAU,OAAO;EACtC,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO,KAAA;EACxD,MAAM,SAAS;EACf,KAAK,MAAM,aAAa;GAAC;GAAU;GAAQ;EAAS,GAAG;GACrD,MAAM,YAAY,eAAe,OAAO,UAAU;GAClD,IAAI,cAAc,KAAA,GAAW,OAAO;EACtC;CAEF;CACA,MAAM,SAAS,eAAe,WAAW,UAAU;CACnD,IAAI,WAAW,KAAA,GAAW,OAAO,QAAQ,SAAS,MAAM;CACxD,KAAK,MAAM,CAAC,SAAS,UAAU,OAAO,QAAQ,UAAU,GAAG;EACzD,MAAM,OAAO,QAAQ,QAAQ,GAAG;EAChC,IAAI,SAAS,IAAI;EACjB,MAAM,SAAS,QAAQ,MAAM,GAAG,IAAI;EACpC,MAAM,SAAS,QAAQ,MAAM,OAAO,CAAC;EACrC,IAAI,CAAC,UAAU,WAAW,MAAM,KAAK,CAAC,UAAU,SAAS,MAAM,GAAG;EAClE,MAAM,WAAW,UAAU,MAAM,OAAO,QAAQ,UAAU,SAAS,OAAO,MAAM;EAChF,MAAM,SAAS,eAAe,KAAK;EACnC,IAAI,WAAW,KAAA,GAAW,OAAO,QAAQ,SAAS,OAAO,QAAQ,KAAK,QAAQ,CAAC;CACjF;AAEF;AAEA,eAAe,kBAAkB,SAAmD;CAClF,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,KAAK,SAAS,cAAc,GAAG,MAAM,CAAC;EAC/E,OAAO,OAAO,OAAO,YAAY,YAAY,OAAO,YAAY,OAAO,OAAO,UAAqC,CAAC;CACtH,QAAQ;EACN,OAAO,CAAC;CACV;AACF;AAEA,eAAe,cAAc,UAAkB,WAAmB,SAAiB,YAAsD;CACvI,IAAI,UAAU,WAAW,GAAG,GAAG;EAC7B,MAAM,SAAS,oBAAoB,SAAS,WAAW,UAAU;EACjE,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,MAAM,iCAAiC,KAAK,UAAU,SAAS,EAAE,mCAAmC;EAEhH,OAAO,cAAc,UAAU,SAAS,QAAQ,QAAQ,GAAG,MAAM,CAAC,CAAC,WAAW,GAAG,IAC7E,SAAS,QAAQ,QAAQ,GAAG,MAAM,IAClC,KAAK,SAAS,QAAQ,QAAQ,GAAG,MAAM,KAAK,SAAS,UAAU;CACrE;CACA,MAAM,OAAO,QAAQ,QAAQ,QAAQ,GAAG,SAAS;CACjD,MAAM,aAAa;EACjB;EACA,GAAG,iBAAiB,IAAI;EACxB,GAAI,QAAQ,IAAI,MAAM,KAAK,kBAAkB,KAAI,cAAa,GAAG,OAAO,WAAW,IAAI,CAAC;EACxF,GAAG,kBAAkB,KAAI,cAAa,KAAK,MAAM,QAAQ,WAAW,CAAC;CACvE;CACA,KAAK,MAAM,aAAa,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,GAAG;EAChD,IAAI,CAAC,OAAO,SAAS,SAAS,GAAG,MAAM,IAAI,MAAM,4CAA4C,UAAU,QAAQ,UAAU;EACzH,IAAI,MAAM,OAAO,SAAS,GAAG,OAAO;CACtC;CACA,MAAM,IAAI,MAAM,yCAAyC,KAAK,UAAU,SAAS,EAAE,QAAQ,UAAU;AACvG;AAEA,eAAe,YAAY,MAAc,SAAoC;CAC3E,IAAI,CAAC,OAAO,SAAS,IAAI,GAAG,MAAM,IAAI,MAAM,2CAA2C,MAAM;CAC7F,IAAI;CACJ,IAAI;EACF,OAAO,MAAM,MAAM,IAAI;CACzB,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAAU,MAAM;EAG9D,KAAK,MAAM,aAAa,iBAAiB,IAAI,GAC3C,IAAI,MAAM,OAAO,SAAS,GAAG,OAAO,CAAC,SAAS;EAEhD,MAAM;CACR;CACA,IAAI,KAAK,eAAe,GAAG,MAAM,IAAI,MAAM,mDAAmD,MAAM;CACpG,IAAI,KAAK,OAAO,GAAG,OAAO,CAAC,IAAI;CAC/B,IAAI,CAAC,KAAK,YAAY,GAAG,OAAO,CAAC;CACjC,MAAM,SAAmB,CAAC;CAC1B,KAAK,MAAM,SAAS,MAAM,QAAQ,IAAI,GAAG,OAAO,KAAK,GAAG,MAAM,YAAY,KAAK,MAAM,KAAK,GAAG,OAAO,CAAC;CACrG,OAAO;AACT;AAEA,eAAsB,oBAAoB,SAAiB,SAAmD;CAC5G,MAAM,aAAa,MAAM,kBAAkB,OAAO;CAClD,MAAM,wBAAQ,IAAI,IAAyD;CAC3E,MAAM,SAA8B,CAAC;CACrC,MAAM,QAAQ,QAAQ,KAAI,SAAQ,QAAQ,IAAI,CAAC;CAG/C,OAAO,MAAM,SAAS,GAAG;EACvB,MAAM,SAAS,MAAM,MAAM;EAC3B,IAAI,MAAM,IAAI,MAAM,GAAG;EACvB,IAAI,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM,IAAI,MAAM,4CAA4C,QAAQ;EAClG,MAAM,OAAO,MAAM,MAAM,MAAM;EAC/B,IAAI,KAAK,eAAe,GAAG,MAAM,IAAI,MAAM,mDAAmD,QAAQ;EACtG,IAAI,CAAC,KAAK,OAAO,GAAG,MAAM,IAAI,MAAM,+CAA+C,QAAQ;EAC3F,MAAM,QAAqD,CAAC;EAC5D,MAAM,IAAI,QAAQ,KAAK;EACvB,IAAI,CAAC,kBAAkB,IAAI,QAAQ,MAAM,CAAC,GAAG;EAC7C,MAAM,OAAO,MAAM,SAAS,QAAQ,MAAM;EAC1C,KAAK,MAAM,aAAa,gBAAgB,QAAQ,IAAI,GAAG;GAGrD,MAAM,OAAO,UAAU,QAAQ,UAAU,SAAS;GAClD,IAAI;IACF,MAAM,UAAU,UAAU,SAAS,WAC/B,CAAC,MAAM,cAAc,QAAQ,UAAU,WAAW,SAAS,UAAU,CAAC,IACtE,MAAM,YAAY,QAAQ,QAAQ,MAAM,GAAG,UAAU,SAAS,GAAG,OAAO;IAC5E,MAAM,KAAK;KAAE;KAAM;IAAQ,CAAC;IAC5B,MAAM,KAAK,GAAG,OAAO;GACvB,SAAS,OAAO;IACd,OAAO,KAAK;KACV,MAAM;KACN,MAAM,UAAU;KAChB,WAAW,UAAU;KACrB,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;KAC7D;IACF,CAAC;GACH;EACF;CACF;CAIA,MAAM,gCAAgB,IAAI,IAAY;CACtC,MAAM,YAAY,QAAQ,KAAI,SAAQ,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAO,SAAQ,MAAM,IAAI,IAAI,CAAC;CACnF,OAAO,UAAU,SAAS,GAAG;EAC3B,MAAM,SAAS,UAAU,MAAM;EAC/B,IAAI,cAAc,IAAI,MAAM,GAAG;EAC/B,cAAc,IAAI,MAAM;EACxB,KAAK,MAAM,QAAQ,MAAM,IAAI,MAAM,KAAK,CAAC,GAAG;GAC1C,IAAI,KAAK,MAAM;GACf,KAAK,MAAM,UAAU,KAAK,SACxB,IAAI,CAAC,cAAc,IAAI,MAAM,GAAG,UAAU,KAAK,MAAM;EAEzD;CACF;CAGA,KAAK,MAAM,SAAS,QAClB,IAAI,CAAC,cAAc,IAAI,MAAM,IAAI,GAAG,MAAM,OAAO;CAEnD,OAAO;EAAE,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,KAAK;EAAG;EAAe;CAAO;AAClE;;;ACpWA,SAAS,YAAY,MAA+C;CAClE,OAAO,SAAS,KAAA,MAAc,GAAG,gBAAgB,IAAI,KAAK,GAAG,gCAAgC,IAAI,KAC7F,KAAK,OACL,KAAA;AACN;AAEA,SAAS,YAAY,MAAe,MAA8B;CAChE,OAAO,GAAG,iBAAiB,IAAI,KAAK,GAAG,aAAa,IAAI,CAAC,EAAE,MAAK,aAAY,SAAS,SAAS,IAAI,MAAM;AAC1G;AAEA,SAAS,oBAAoB,MAAuD;CAClF,MAAM,YAAY,KAAK,WAAW;CAClC,OAAO,cAAc,KAAA,KAAa,GAAG,aAAa,UAAU,IAAI,IAAI,UAAU,KAAK,OAAO,KAAA;AAC5F;AAEA,SAAS,sBAAsB,QAAoC;CACjE,MAAM,4BAAY,IAAI,IAAY;CAClC,MAAM,4BAAY,IAAI,IAA4C;CAElE,SAAS,MAAM,MAAqB;EAClC,IAAI,GAAG,sBAAsB,IAAI,KAAK,KAAK,SAAS,KAAA,GAAW,UAAU,IAAI,KAAK,KAAK,MAAM,IAAI;EACjG,IAAI,GAAG,sBAAsB,IAAI,KAAK,GAAG,aAAa,KAAK,IAAI,KAC1D,KAAK,gBAAgB,KAAA,MACpB,GAAG,gBAAgB,KAAK,WAAW,KAAK,GAAG,qBAAqB,KAAK,WAAW,IACpF,UAAU,IAAI,KAAK,KAAK,MAAM,KAAK,WAAW;EAEhD,IAAI,GAAG,YAAY,IAAI,KAAK,KAAK,SAAS,KAAA,KACrC,0BAA0B,KAAK,KAAK,KAAK,QAAQ,MAAM,CAAC,KAAK,GAAG,aAAa,KAAK,IAAI,GACzF,UAAU,IAAI,KAAK,KAAK,IAAI;EAK9B,IAAI,GAAG,YAAY,IAAI,KAAK,GAAG,aAAa,KAAK,IAAI,KAChD,0BAA0B,KAAK,KAAK,KAAK,IAAI,GAChD,UAAU,IAAI,KAAK,KAAK,IAAI;EAE9B,GAAG,aAAa,MAAM,KAAK;CAC7B;CACA,MAAM,MAAM;CAEZ,KAAK,MAAM,aAAa,OAAO,YAAY;EACzC,IAAI,GAAG,sBAAsB,SAAS,KACjC,YAAY,WAAW,GAAG,WAAW,aAAa,KAClD,YAAY,WAAW,GAAG,WAAW,cAAc,GAAG;GACzD,MAAM,OAAO,oBAAoB,SAAS;GAC1C,IAAI,SAAS,KAAA,GAAW,UAAU,IAAI,IAAI;EAC5C;EACA,IAAI,GAAG,mBAAmB,SAAS,GAAG;GACpC,MAAM,aAAa,UAAU;GAC7B,IAAI,GAAG,gBAAgB,UAAU,KAAK,GAAG,qBAAqB,UAAU,GAAG;IACzE,MAAM,OAAO,oBAAoB,UAAU;IAC3C,IAAI,SAAS,KAAA,GAAW,UAAU,IAAI,IAAI;GAC5C,OAAO,IAAI,GAAG,aAAa,UAAU,GAAG;IACtC,MAAM,YAAY,UAAU,IAAI,WAAW,IAAI;IAC/C,IAAI,cAAc,KAAA,GAAW;KAC3B,MAAM,OAAO,oBAAoB,SAAS;KAC1C,IAAI,SAAS,KAAA,GAAW,UAAU,IAAI,IAAI;IAC5C;GACF;EACF;EACA,IAAI,GAAG,oBAAoB,SAAS,KAAK,UAAU,oBAAoB,KAAA,KAClE,UAAU,iBAAiB,KAAA,KAAa,GAAG,eAAe,UAAU,YAAY,GACnF,KAAK,MAAM,WAAW,UAAU,aAAa,UAAU;GACrD,IAAI,QAAQ,KAAK,SAAS,aAAa,QAAQ,iBAAiB,KAAA,KAAa,CAAC,GAAG,aAAa,QAAQ,YAAY,GAAG;GACrH,MAAM,YAAY,UAAU,IAAI,QAAQ,aAAa,IAAI;GACzD,IAAI,cAAc,KAAA,GAAW;IAC3B,MAAM,OAAO,oBAAoB,SAAS;IAC1C,IAAI,SAAS,KAAA,GAAW,UAAU,IAAI,IAAI;GAC5C;EACF;CAEJ;CACA,OAAO;AACT;AAEA,SAAS,uBAAuB,QAAuB,WAA6C;CAClG,MAAM,6BAAa,IAAI,IAAY;CACnC,SAAS,MAAM,MAAqB;EAClC,KAAK,GAAG,sBAAsB,IAAI,KAAK,GAAG,YAAY,IAAI,MAAM,GAAG,aAAa,KAAK,IAAI,GACzE;OAAA,KAAK,SAAS,KAAA,KAAa,iCAAiC,KAAK,KAAK,KAAK,QAAQ,MAAM,CAAC,KAC3F,0BAA0B,KAAK,KAAK,KAAK,IAAI,GAAG,WAAW,IAAI,KAAK,KAAK,IAAI;EAAA,OACrF,IAAI,GAAG,mBAAmB,IAAI,KAAK,KAAK,cAAc,SAAS,GAAG,WAAW,eAC/E,GAAG,2BAA2B,KAAK,IAAI,KAAK,KAAK,KAAK,WAAW,SAAS,GAAG,WAAW,eACxF,GAAG,aAAa,KAAK,KAAK,KAAK,UAAU,IAAI,KAAK,MAAM,IAAI,GAC/D,WAAW,IAAI,KAAK,KAAK,KAAK,IAAI;EAEpC,GAAG,aAAa,MAAM,KAAK;CAC7B;CACA,MAAM,MAAM;CACZ,OAAO;AACT;AAEA,SAAS,sBAAsB,MAAmD;CAChF,MAAM,SAAS,KAAK;CACpB,IAAI,GAAG,oBAAoB,MAAM,KAAK,OAAO,SAAS,KAAA,GAAW,OAAO,OAAO,KAAK,QAAQ;CAC5F,KAAK,GAAG,gBAAgB,MAAM,KAAK,GAAG,qBAAqB,MAAM,MAAM,GAAG,qBAAqB,OAAO,MAAM,GAC1G,OAAO,OAAO,OAAO,KAAK,QAAQ;AAGtC;AAEA,SAAS,0BAA0B,QAAoC;CACrE,MAAM,4BAAY,IAAI,IAAY;CAClC,SAAS,MAAM,MAAqB;EAClC,IAAI,GAAG,YAAY,IAAI,KAAK,GAAG,aAAa,KAAK,IAAI,GAAG;GACtD,MAAM,eAAe,KAAK,SAAS,KAAA,KAC9B,iEAAiE,KAAK,KAAK,KAAK,QAAQ,MAAM,CAAC;GACpG,MAAM,6BAA6B,sBAAsB,KAAK,KAAK,KAAK,IAAI,KACvE,yBAAyB,KAAK,sBAAsB,IAAI,KAAK,EAAE;GACpE,IAAI,gBAAgB,4BAA4B,UAAU,IAAI,KAAK,KAAK,IAAI;EAC9E;EACA,GAAG,aAAa,MAAM,KAAK;CAC7B;CACA,MAAM,MAAM;CACZ,OAAO;AACT;AAGA,MAAM,sCAAsB,IAAI,IAAY;CAC1C,GAAG;CACH,GAAG;CACH,GAAG;AACL,CAAC;AAKD,MAAM,mCAAmB,IAAI,IAAY;CACvC,GAAG;CACH;CACA;AACF,CAAC;AAED,SAAS,gBAAgB,aAAmD;CAC1E,MAAM,wBAAQ,IAAI,IAAY;CAC9B,KAAK,MAAM,SAAS;EAAC;EAAgB;EAAwB;CAAkB,GAAG;EAChF,MAAM,QAAQ,YAAY;EAC1B,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;EACzE,KAAK,MAAM,CAAC,MAAM,cAAc,OAAO,QAAQ,KAAK,GAClD,IAAI,OAAO,cAAc,UAAU,MAAM,IAAI,IAAI;CAErD;CACA,OAAO;AACT;AAEA,SAAS,YACP,UACA,SACA,MACA,QACA,MACA,YACA,OACA,QACM;CACN,MAAM,WAAW,OAAO,8BAA8B,KAAK,SAAS,MAAM,CAAC;CAC3E,SAAS,KAAK;EACZ;EACA;EACA,MAAM,SAAS,SAAS,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG;EAClD,MAAM,SAAS,OAAO;EACtB;CACF,CAAC;AACH;AAEA,eAAe,iBAAiB,SAAiB,MAA+C;CAC9F,MAAM,OAAO,MAAM,SAAS,MAAM,MAAM;CACxC,MAAM,SAAS,GAAG,iBAAiB,MAAM,MAAM,GAAG,aAAa,QAAQ,MAAM,WAAW,IAAI,CAAC;CAC7F,MAAM,WAAmC,CAAC;CAC1C,MAAM,YAAY,sBAAsB,MAAM;CAC9C,MAAM,gBAAgB,uBAAuB,QAAQ,SAAS;CAC9D,MAAM,mBAAmB,0BAA0B,MAAM;CACzD,MAAM,gCAAgB,IAAI,IAAoB;CAC9C,MAAM,kCAAkB,IAAI,IAAY;CACxC,MAAM,4BAAY,IAAI,IAAY;CAElC,SAAS,iBAAiB,aAAqB,cAAsB,MAAqB;EACxF,MAAM,UAAU,kBAAkB,aAAa,YAAY;EAC3D,IAAI,YAAY,KAAA,GAAW;GACzB,YACE,UAAU,SAAS,MAAM,QAAQ,MAAM,eAAe,YAAY,GAAG,aAAa,IAAI,eACtF,wCAAwC,KAAK,UAAU,YAAY,EAAE,QAAQ,KAAK,UAAU,WAAW,EAAE,EAC3G;GACA;EACF;EACA,YACE,UAAU,SAAS,MAAM,QAAQ,MAAM,eAAe,YAAY,GAAG,aAAa,IAAI,QAAQ,OAAO,QAAQ,MAC/G;CACF;CAEA,KAAK,MAAM,aAAa,OAAO,YAC7B,IAAI,GAAG,oBAAoB,SAAS,KAAK,GAAG,gBAAgB,UAAU,eAAe,KAChF,oBAAoB,IAAI,UAAU,gBAAgB,IAAI,GAAG;EAC5D,MAAM,cAAc,UAAU,gBAAgB;EAC9C,MAAM,SAAS,UAAU;EACzB,IAAI,WAAW,KAAA,GAAW;GACxB,iBAAiB,aAAa,iBAAiB,SAAS;GACxD;EACF;EACA,IAAI,OAAO,YAAY;EACvB,IAAI,OAAO,SAAS,KAAA,GAAW,iBAAiB,aAAa,WAAW,OAAO,IAAI;EACnF,IAAI,OAAO,kBAAkB,KAAA,KAAa,GAAG,kBAAkB,OAAO,aAAa,GACjF,iBAAiB,aAAa,KAAK,OAAO,aAAa;OAClD,IAAI,OAAO,kBAAkB,KAAA,GAC7B;QAAA,MAAM,WAAW,OAAO,cAAc,UACzC,IAAI,CAAC,QAAQ,YAAY,iBAAiB,aAAa,QAAQ,cAAc,QAAQ,QAAQ,KAAK,MAAM,OAAO;EAAA;CAGrH,OAAO,IAAI,GAAG,oBAAoB,SAAS,KAAK,CAAC,UAAU,cACtD,UAAU,oBAAoB,KAAA,KAAa,GAAG,gBAAgB,UAAU,eAAe,KACvF,iBAAiB,IAAI,UAAU,gBAAgB,IAAI,GAAG;EACzD,MAAM,cAAc,UAAU,gBAAgB;EAC9C,IAAI,UAAU,iBAAiB,KAAA,KAAa,GAAG,kBAAkB,UAAU,YAAY,GACrF,iBAAiB,aAAa,KAAK,SAAS;OAE5C,KAAK,MAAM,WAAW,UAAU,aAAa,UAC3C,IAAI,CAAC,QAAQ,YAAY,iBAAiB,aAAa,QAAQ,cAAc,QAAQ,QAAQ,KAAK,MAAM,OAAO;CAGrH,OAAO,IAAI,GAAG,0BAA0B,SAAS,KAAK,CAAC,UAAU,cAC5D,GAAG,0BAA0B,UAAU,eAAe,KACtD,GAAG,gBAAgB,UAAU,gBAAgB,UAAU,KACvD,iBAAiB,IAAI,UAAU,gBAAgB,WAAW,IAAI,GACjE,iBAAiB,UAAU,gBAAgB,WAAW,MAAM,KAAK,SAAS;CAI9E,MAAM,eAAyC,CAAC;CAChD,MAAM,iBAAiB,SAAiC,GAAG,aAAa,IAAI,KAAK,UAAU,IAAI,KAAK,IAAI,KAClG,GAAG,2BAA2B,IAAI,KAAK,KAAK,WAAW,SAAS,GAAG,WAAW,eAC7E,cAAc,IAAI,KAAK,KAAK,IAAI;CACvC,SAAS,oBAAoB,MAAqB;EAChD,IAAI,GAAG,sBAAsB,IAAI,GAAG,aAAa,KAAK,IAAI;EAC1D,GAAG,aAAa,MAAM,mBAAmB;CAC3C;CACA,oBAAoB,MAAM;CAE1B,KAAK,IAAI,OAAO,GAAG,OAAO,aAAa,SAAS,GAAG,QAAQ,GAAG;EAC5D,IAAI,UAAU;EACd,KAAK,MAAM,eAAe,cAAc;GACtC,MAAM,cAAc,YAAY;GAChC,IAAI,gBAAgB,KAAA,GAAW;GAC/B,IAAI,GAAG,aAAa,YAAY,IAAI,KAAK,cAAc,WAAW,GAC5D;QAAA,CAAC,UAAU,IAAI,YAAY,KAAK,IAAI,GAAG;KACzC,UAAU,IAAI,YAAY,KAAK,IAAI;KACnC,UAAU;IACZ;;GAEF,IAAI,GAAG,aAAa,YAAY,IAAI,KAAK,GAAG,aAAa,WAAW,KAAK,iBAAiB,IAAI,YAAY,IAAI,GACxG;QAAA,CAAC,iBAAiB,IAAI,YAAY,KAAK,IAAI,GAAG;KAChD,iBAAiB,IAAI,YAAY,KAAK,IAAI;KAC1C,UAAU;IACZ;;GAEF,IAAI,GAAG,aAAa,YAAY,IAAI,KAAK,GAAG,2BAA2B,WAAW,KAC7E,YAAY,KAAK,SAAS,QAAQ,GAAG,aAAa,YAAY,UAAU,KACxE,iBAAiB,IAAI,YAAY,WAAW,IAAI,KAAK,CAAC,UAAU,IAAI,YAAY,KAAK,IAAI,GAAG;IAC/F,UAAU,IAAI,YAAY,KAAK,IAAI;IACnC,UAAU;GACZ;GACA,IAAI,GAAG,aAAa,YAAY,IAAI,KAAK,GAAG,2BAA2B,WAAW,KAC7E,cAAc,YAAY,UAAU,GAAG;IAC1C,IAAI,YAAY,KAAK,SAAS,UACxB;SAAA,CAAC,gBAAgB,IAAI,YAAY,KAAK,IAAI,GAAG;MAC/C,gBAAgB,IAAI,YAAY,KAAK,IAAI;MACzC,UAAU;KACZ;WACK,IAAI,CAAC,cAAc,IAAI,YAAY,KAAK,IAAI,GAAG;KACpD,cAAc,IAAI,YAAY,KAAK,MAAM,YAAY,KAAK,IAAI;KAC9D,UAAU;IACZ;GACF;GACA,IAAI,GAAG,uBAAuB,YAAY,IAAI,KAAK,cAAc,WAAW,GAC1E,KAAK,MAAM,WAAW,YAAY,KAAK,UAAU;IAC/C,IAAI,CAAC,GAAG,aAAa,QAAQ,IAAI,GAAG;IACpC,MAAM,SAAS,QAAQ,iBAAiB,KAAA,KAAa,GAAG,aAAa,QAAQ,YAAY,IACrF,QAAQ,aAAa,OACrB,QAAQ,KAAK;IACjB,IAAI,WAAW,UACT;SAAA,CAAC,gBAAgB,IAAI,QAAQ,KAAK,IAAI,GAAG;MAC3C,gBAAgB,IAAI,QAAQ,KAAK,IAAI;MACrC,UAAU;KACZ;WACK,IAAI,CAAC,cAAc,IAAI,QAAQ,KAAK,IAAI,GAAG;KAChD,cAAc,IAAI,QAAQ,KAAK,MAAM,MAAM;KAC3C,UAAU;IACZ;GACF;EAEJ;EACA,IAAI,CAAC,SAAS;CAChB;CAEA,SAAS,aAAa,QAAgB,MAAmC,MAAqB;EAC5F,IAAI,WAAW,MAAM;GACnB,MAAM,QAAQ,YAAY,KAAK,EAAE;GACjC,IAAI,UAAU,KAAA,GACZ,YACE,UAAU,SAAS,MAAM,QAAQ,MAAM,iBAAiB,eACxD,yDACF;QACK;IACL,MAAM,OAAO,aAAa,KAAK;IAC/B,YAAY,UAAU,SAAS,MAAM,QAAQ,MAAM,MAAM,MAAM,IAAI,KAAK,OAAO,KAAK,MAAM;GAC5F;GACA;EACF;EACA,MAAM,OAAO,WAAW,MAAM;EAC9B,IAAI,SAAS,KAAA,GAAW;GACtB,YACE,UAAU,SAAS,MAAM,QAAQ,MAAM,QAAQ,eAC/C,+BAA+B,KAAK,UAAU,MAAM,EAAE,qCACxD;GACA;EACF;EACA,YAAY,UAAU,SAAS,MAAM,QAAQ,MAAM,QAAQ,KAAK,OAAO,KAAK,MAAM;CACpF;CAEA,SAAS,eAAe,QAAgB,MAAqB;EAC3D,MAAM,OAAO,WAAW,QAAQ;EAChC,KAAK,WAAW,QAAQ,WAAW,WAAW,SAAS,KAAA,GACrD,YAAY,UAAU,SAAS,MAAM,QAAQ,MAAM,UAAU,UAAU,KAAK,OAAO,KAAK,MAAM;OAE9F,YACE,UAAU,SAAS,MAAM,QAAQ,MAAM,UAAU,UAAU,eAC3D,+BAA+B,KAAK,UAAU,MAAM,EAAE,0BACxD;CAEJ;CAEA,SAAS,cAAc,UAAkB,MAAqB;EAC5D,MAAM,UAAU,uBAAuB,QAAQ;EAC/C,IAAI,YAAY,KAAA,GACd,YACE,UAAU,SAAS,MAAM,QAAQ,MAAM,OAAO,YAAY,eAC1D,yCAAyC,KAAK,UAAU,QAAQ,EAAE,qCACpE;OAEA,YAAY,UAAU,SAAS,MAAM,QAAQ,MAAM,OAAO,YAAY,QAAQ,OAAO,QAAQ,MAAM;CAEvG;CAEA,SAAS,gBAAgB,UAAkB,MAAqB;EAC9D,MAAM,UAAU,yBAAyB,QAAQ;EACjD,IAAI,YAAY,KAAA,GACd,YACE,UAAU,SAAS,MAAM,QAAQ,MAAM,UAAU,YAAY,eAC7D,kCAAkC,KAAK,UAAU,QAAQ,EAAE,qCAC7D;OAEA,YAAY,UAAU,SAAS,MAAM,QAAQ,MAAM,UAAU,YAAY,QAAQ,OAAO,QAAQ,MAAM;CAE1G;CAEA,SAAS,MAAM,MAAqB;EAClC,IAAI,GAAG,iBAAiB,IAAI,KAAK,GAAG,aAAa,KAAK,UAAU,GAAG;GACjE,MAAM,SAAS,cAAc,IAAI,KAAK,WAAW,IAAI;GACrD,IAAI,WAAW,KAAA,GAAW,aAAa,QAAQ,KAAK,WAAW,IAAI;EACrE,OAAO,IAAI,GAAG,iBAAiB,IAAI,KAAK,GAAG,2BAA2B,KAAK,UAAU,GAAG;GACtF,MAAM,SAAS,KAAK,WAAW;GAC/B,IAAI,cAAc,MAAM,GACtB,aAAa,KAAK,WAAW,KAAK,MAAM,KAAK,WAAW,IAAI;QACvD,IAAI,GAAG,aAAa,MAAM,KAAK,gBAAgB,IAAI,OAAO,IAAI,GACnE,eAAe,KAAK,WAAW,KAAK,MAAM,IAAI;QACzC,IAAI,GAAG,2BAA2B,MAAM,KAC1C,OAAO,KAAK,SAAS,YACrB,cAAc,OAAO,UAAU,GAClC,eAAe,KAAK,WAAW,KAAK,MAAM,IAAI;EAElD,OAAO,IAAI,GAAG,iBAAiB,IAAI,KAAK,GAAG,0BAA0B,KAAK,UAAU,KAC/E,cAAc,KAAK,WAAW,UAAU,GAAG;GAC9C,MAAM,SAAS,YAAY,KAAK,WAAW,kBAAkB;GAC7D,IAAI,WAAW,KAAA,GACb,YACE,UAAU,SAAS,MAAM,QAAQ,MAAM,wBAAwB,eAC/D,wEACF;QAEA,aAAa,QAAQ,KAAK,WAAW,IAAI;EAE7C;EACA,IAAI,GAAG,2BAA2B,IAAI,GAAG;GACvC,MAAM,SAAS,KAAK;GACpB,IAAI,GAAG,2BAA2B,MAAM,KAAK,OAAO,KAAK,SAAS,QAC7D,GAAG,aAAa,OAAO,UAAU,KAAK,iBAAiB,IAAI,OAAO,WAAW,IAAI,GACpF,gBAAgB,KAAK,KAAK,MAAM,IAAI;QAC/B,IAAI,GAAG,aAAa,MAAM,KAAK,UAAU,IAAI,OAAO,IAAI,GAC7D,gBAAgB,KAAK,KAAK,MAAM,IAAI;QAC/B,IAAI,GAAG,aAAa,MAAM,KAAK,iBAAiB,IAAI,OAAO,IAAI,KAAK,KAAK,KAAK,SAAS,MAC5F,cAAc,KAAK,KAAK,MAAM,IAAI;EAEtC,OAAO,IAAI,GAAG,0BAA0B,IAAI,KAAK,GAAG,aAAa,KAAK,UAAU,KAC3E,iBAAiB,IAAI,KAAK,WAAW,IAAI,GAAG;GAC/C,MAAM,WAAW,YAAY,KAAK,kBAAkB;GACpD,IAAI,aAAa,KAAA,GACf,YACE,UAAU,SAAS,MAAM,QAAQ,MAAM,iBAAiB,eACxD,yEACF;QACK,IAAI,aAAa,MACtB,cAAc,UAAU,IAAI;EAEhC;EACA,GAAG,aAAa,MAAM,KAAK;CAC7B;CAEA,MAAM,MAAM;CACZ,OAAO;AACT;AAEA,eAAsB,eAAe,KAAsD;CACzF,MAAM,mBAAmB,MAAM,oBAAoB,IAAI,SAAS,IAAI,UAAU,UAAU;CACxF,MAAM,YAAY,MAAM,QAAQ,IAC9B,iBAAiB,MAAM,QAAO,SAAQ,kBAAkB,IAAI,QAAQ,IAAI,CAAC,CAAC,CAAC,CACxE,KAAI,SAAQ,iBAAiB,IAAI,SAAS,IAAI,CAAC,CACpD,EAAA,CAAG,KAAK;CAER,IAAI,IAAI,UAAU,WAAW,SAAS,KAAK,SAAS,WAAW,GAC7D,SAAS,KAAK;EACZ,YAAY;EACZ,OAAO;EACP,MAAM,IAAI,UAAU,WAAW,KAAI,SAAQ,SAAS,IAAI,SAAS,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;EACvG,MAAM;EACN,QAAQ;CACV,CAAC;CAEH,KAAK,MAAM,SAAS,iBAAiB,QAAQ;EAI3C,MAAM,YAAY,MAAM,QAAQ,MAAM,SAAS;EAC/C,SAAS,KAAK;GACZ,YAAY,GAAG,MAAM,KAAK,GAAG,MAAM,UAAU;GAC7C,OAAO,YAAY,YAAY;GAC/B,MAAM,SAAS,IAAI,SAAS,MAAM,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG;GAC5D,MAAM;GACN,QAAQ,YACJ,wCAAwC,MAAM,OAAO,+IACrD,8CAA8C,MAAM;EAC1D,CAAC;CACH;CAEA,MAAM,uBAAuB,gBAAgB,IAAI,WAAW;CAC5D,KAAK,MAAM,QAAQ,iBAAiB,MAAM,QAAO,cAAa,kBAAkB,IAAI,QAAQ,SAAS,CAAC,CAAC,GAAG;EACxG,MAAM,OAAO,MAAM,SAAS,MAAM,MAAM;EACxC,MAAM,WAAW,CAAC,iBAAiB,cAAc,IAAI,IAAI;EACzD,KAAK,MAAM,OAAO,wBAAwB,MAAM,IAAI,GAAG;GACrD,IAAI,iBAAiB,IAAI,IAAI,IAAI,KAAK,qBAAqB,IAAI,IAAI,IAAI,GAAG;GAI1E,MAAM,UAAU,IAAI,QAAQ;GAC5B,SAAS,KAAK;IACZ,YAAY,UAAU,4BAA4B,IAAI,KAAK,KAAK,iCAAiC,IAAI,KAAK;IAC1G,OAAO,UAAU,YAAY;IAC7B,MAAM,SAAS,IAAI,SAAS,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG;IACtD,MAAM;IACN,QAAQ,UACJ,yBAAyB,KAAK,UAAU,IAAI,IAAI,EAAE,kJAAkJ,IAAI,KAAK,0BAC7M,yBAAyB,KAAK,UAAU,IAAI,IAAI,EAAE;GACxD,CAAC;EACH;CACF;CAEA,MAAM,mBAAmB,MAAc,YAAoB,OAA2B,YAA0C;EAC9H;EACA;EACA,MAAM,SAAS,IAAI,SAAS,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG;EACtD,MAAM;EACN;CACF;CACA,KAAK,MAAM,QAAQ,IAAI,UAAU,OAAO,QAAO,SAAQ,SAAS,IAAI,MAAM,cAAc,KAAK,SAAS,KAAK,CAAC,GAC1G,SAAS,KAAK,gBAAgB,MAAM,SAAS,QAAQ,sEAAsE,CAAC;CAE9H,KAAK,MAAM,QAAQ,IAAI,UAAU,SAC/B,SAAS,KAAK,gBAAgB,MAAM,UAAU,QAAQ,0EAA0E,CAAC;CAEnI,KAAK,MAAM,QAAQ,IAAI,UAAU,QAC/B,SAAS,KAAK,gBAAgB,MAAM,SAAS,eAAe,oEAAoE,CAAC;CAEnI,SAAS,MAAM,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,KAAK,KAAK,OAAO,MAAM,QAAQ,KAAK,WAAW,cAAc,MAAM,UAAU,CAAC;CAE/I,MAAM,UAA8C;EAAE,MAAM;EAAG,SAAS;EAAG,aAAa;EAAG,OAAO;CAAE;CACpG,KAAK,MAAM,WAAW,UAAU,QAAQ,QAAQ,UAAU;CAI1D,MAAM,UAAU,QAAQ,QAAQ,IAAI,YAAY,QAAQ,UAAU,KAAK,QAAQ,cAAc,IAAI,WAAW;CAE5G,OAAO;EACL,eAAe;EACf,SAAS,IAAI;EACb;EACA;EACA,WAAW;GACT,YAAY,IAAI,UAAU,WAAW,KAAI,SAAQ,SAAS,IAAI,SAAS,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC;GAClG,QAAQ,IAAI,UAAU,OAAO,KAAI,SAAQ,SAAS,IAAI,SAAS,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC;GAC1F,SAAS,IAAI,UAAU,QAAQ,KAAI,SAAQ,SAAS,IAAI,SAAS,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC;GAC5F,QAAQ,IAAI,UAAU,OAAO,KAAI,SAAQ,SAAS,IAAI,SAAS,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC;EAC5F;EACA;CACF;AACF"}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { i as renderMcpPatch, n as convertPiMcpConfig } from "./mcp-config-C1K-IzzB.mjs";
|
|
3
3
|
import { t as resolvePiPackage } from "./source-0sA5z08z.mjs";
|
|
4
|
-
import { c as UI_CONTEXT_RULES, i as HOST_IMPORT_RULES, n as CONTEXT_RULES, r as EVENT_RULES, t as API_RULES } from "./compatibility-
|
|
4
|
+
import { c as UI_CONTEXT_RULES, i as HOST_IMPORT_RULES, n as CONTEXT_RULES, r as EVENT_RULES, t as API_RULES } from "./compatibility-CZs3LwYn.mjs";
|
|
5
5
|
import { writeFileSync } from "node:fs";
|
|
6
6
|
import { parseArgs } from "node:util";
|
|
7
7
|
//#region src/cli.ts
|
|
@@ -76,7 +76,7 @@ async function main() {
|
|
|
76
76
|
if (command !== "inspect" || source === void 0) throw new Error(`invalid command\n\n${usage()}`);
|
|
77
77
|
const pkg = await resolvePiPackage(source);
|
|
78
78
|
try {
|
|
79
|
-
const { analyzePackage } = await import("./analyzer-
|
|
79
|
+
const { analyzePackage } = await import("./analyzer-C139Y2S7.mjs");
|
|
80
80
|
const report = await analyzePackage(pkg);
|
|
81
81
|
console.log(parsed.values.json ? JSON.stringify(report, null, 2) : reportText(report));
|
|
82
82
|
if (report.verdict === "blocked") process.exitCode = 2;
|
|
@@ -83,7 +83,7 @@ const HOST_IMPORT_RULES = Object.freeze({
|
|
|
83
83
|
readStoredCredential: rule("partial", "Reads Pi-style auth.json from the pi2dsh-owned agent directory; DSH credentials stay authoritative for DSH model calls."),
|
|
84
84
|
parseSkillBlock: rule("full", "Pi's skill_content block parser, reimplemented over the same wire shape."),
|
|
85
85
|
wrapRegisteredTool: rule("full", `${VENDORED} The runner argument is used exactly as Pi uses it (createContext + getActiveTools), which the pi2dsh projection provides.`),
|
|
86
|
-
ProjectTrustStore: rule("partial", `${VENDORED} The store operates on trust.json under the caller\'s agentDir — with the redirected getAgentDir convention that is package-visible state inside the DSH-owned pi2dsh directory. The DSH host never consults it; host trust stays a DSH decision (ctx.isProjectTrusted
|
|
86
|
+
ProjectTrustStore: rule("partial", `${VENDORED} The store operates on trust.json under the caller\'s agentDir — with the redirected getAgentDir convention that is package-visible state inside the DSH-owned pi2dsh directory. The DSH host never consults it; host trust stays a DSH decision (ctx.isProjectTrusted reports it: true for an agent session's directory, fail-closed without an agent).`),
|
|
87
87
|
DefaultResourceLoader: rule("partial", "A headless resource loader honoring overrides. Extension discovery is REAL: the default-discovered set is the host's installed Pi packages (each package's declared pi extension entry, as an absolute installed path), so a creator's own filtering code — pi-subagents' extensions/exclude_extensions/ext: machinery canonicalizes by entry basename and owning-manifest npm short name — runs unchanged and selects exactly what it selects on Pi. noExtensions empties the set; additionalExtensionPaths cannot be loaded fresh on this host and surface as per-entry errors (Pi's diagnostics shape). Skills/prompts/themes/agents-files discovery stays empty."),
|
|
88
88
|
DefaultPackageManager: rule("unsupported", "Installing packages is owned by the DSH host and its security gates (dsh plugin add/remove behind pnpm's build-script approval). Importing it is flagged at mount time (startup check); constructing it throws a structured PiCapabilityError, and doing so during entry setup marks the package unusable."),
|
|
89
89
|
ModelRuntime: rule("unsupported", "Standalone model stacks are owned by the DSH host llm configuration; packages read the ONE directory through ctx.modelRegistry. Importing it is flagged at mount time (startup check); constructing it throws a structured PiCapabilityError, and doing so during entry setup marks the package unusable."),
|
|
@@ -243,10 +243,10 @@ const HOST_IMPORT_RULES = Object.freeze({
|
|
|
243
243
|
const CONTEXT_RULES = Object.freeze({
|
|
244
244
|
cwd: surface("full", "Mapped to the active DSH agent session working directory.", "Read off the live DSH agent's session; the bridge keeps no working directory of its own."),
|
|
245
245
|
signal: surface("full", "Mapped to the active DSH cancellation signal when one is available.", "The DSH cancellation signal belonging to the moment the context was built — a tool context carries its execution signal, a lifecycle context the agent's."),
|
|
246
|
-
hasUI: surface("full", "Reports whether a real interactive surface exists: true for a mounted public terminal surface (dsh-TUI tuiScenes or dsh-pi-tui piTuiExtensions) or for a DSH
|
|
247
|
-
mode: surface("full", "Reports tui whenever a full-screen custom seat exists — dsh-TUI scenes, dsh-pi-tui raw mounts, or the
|
|
246
|
+
hasUI: surface("full", "Reports whether a real interactive surface exists: true for a mounted public terminal surface (dsh-TUI tuiScenes or dsh-pi-tui piTuiExtensions) or for a live DSH question answerer; false for a genuinely headless composition and for child-agent questions that DSH refuses.", "The terminal answer comes from the capability-selected TerminalSurfaceAdapter. The question answer is generation-selected by capability: rc lines expose a provider slot, so the bridge registers a throwaway provider and reads the documented DUPLICATE_PROVIDER rejection as \"a real provider is already there\"; the 0.1.2 line replaced the slot with agent-scoped user-questions/request waterfall answerers, so the bridge lists would-be listeners through cordis Lifecycle.dispatch (a typed public member) and falls back to a recent browser contact on the presentation route. Inside a child agent only the terminal seat can make this true, because DSH refuses child-agent questions."),
|
|
247
|
+
mode: surface("full", "Reports tui whenever a full-screen custom seat exists — dsh-TUI scenes, dsh-pi-tui raw mounts, or (browserPresentation on, as the dsh-work-x suite configures) the web scene seat — and rpc otherwise. An engine-only web composition is rpc on purpose: the engine ships no web renderer, so packages degrade exactly as they do headless. Pi packages read mode as \"can I show interactive UI here?\".", "Derived from the live optional TerminalSurfaceAdapter, else from the browser half's routed scene seat — routed only under the engine's browserPresentation config (default off; the renderer is a product layer's to carry). Surface selection is by public service/capability (`tuiScenes` or `piTuiExtensions` + unstable.surface.handle), never by Pi consumer package."),
|
|
248
248
|
isIdle: surface("partial", "Command contexts report idle; tool/lifecycle contexts conservatively report non-idle.", "Derived from which context the call arrived through: a command context is outside a step, a tool or lifecycle context is inside one."),
|
|
249
|
-
isProjectTrusted: surface("
|
|
249
|
+
isProjectTrusted: surface("full", "Reports the DSH host's own trust decision: true for an agent session's working directory, false for the host anchor and detached contexts.", "Host-semantic translation, not a constant. On DSH the trust act is opening a workspace — the host already runs its own bash/edit/write in the session's directory without a further prompt — so an agent-scoped context answers true for exactly that directory. Contexts with no agent (the host anchor, detached projections) stay fail-closed. The earlier hardcoded false claimed the host actively distrusts every project — a stronger statement than DSH makes anywhere — and packages honor it literally: pi-lens disables every language-server spawn on an explicit false while treating a missing accessor as unknown-and-allowed. Pi's own ProjectTrustStore stays vendored for packages that manage their own per-path trust."),
|
|
250
250
|
hasPendingMessages: surface("full", "Reads the DSH agent inbox — next-step plus next-turn input — which is exactly Pi's steering plus follow-up queue.", "Reads the DSH agent inbox — next-step plus next-turn queues — which is the same queue sendMessage/sendUserMessage write into."),
|
|
251
251
|
getContextUsage: surface("partial", "Returns no Pi token-usage projection.", "Not synthesized. DSH accounts tokens in its own token-meter service, and a guessed Pi projection would be read as measurement."),
|
|
252
252
|
getSystemPrompt: surface("full", "Returns the system prompt currently assembled by the bridge.", "Returns the string the bridge recorded during system-prompt/assemble for the current turn. It is recorded on every assembly, before any gate, so a package that only reads the prompt still sees it."),
|
|
@@ -270,7 +270,7 @@ const CONTEXT_RULES = Object.freeze({
|
|
|
270
270
|
const UI_CONTEXT_RULES = Object.freeze({
|
|
271
271
|
notify: surface("full", "Captured as a command result when applicable and emitted through DSH logging at the severity the caller passed (warning and error log as warnings).", "Written to the DSH logger at the severity the caller passed, and returned as the command result when the call happens inside one."),
|
|
272
272
|
setStatus: surface("full", "Pi's keyed status entries render in the active DSH front door: dsh-TUI's native status line, dsh-pi-tui's public footer-status slot, or package-keyed pills in the bridge's browser half. setStatus(key, undefined) removes exactly one entry.", "The selected terminal backend owns a package/key-scoped handle: tuiStatus on dsh-TUI, or a replaceable chrome.footer.status contribution on dsh-pi-tui. Browser mode writes BrowserSurfaces by (session, package, key); the client half draws the entries from the bridge route."),
|
|
273
|
-
setWidget: surface("partial", "
|
|
273
|
+
setWidget: surface("partial", "Widgets float in DSH web's lower-right overlay stack, session-scoped: a single-line widget renders as an ambient status pill, taller content opens as a floating card on arrival and collapses to a labelled pill (diagnostics-shaped content gets product rows — file chips, severity dots, locations). setWidget(key, undefined) removes one widget. A component factory runs with a LIVE tui handle: requestRender re-renders the retained component into the same slot, and replacing or clearing the widget disposes it.", "BrowserSurfaces.setWidget keeps the rendered text per widget key; the client half presents it from the shell overlay (pill or floating card by shape), never as an in-column strip — the strip form could not be dismissed and wore the previous session's content on the new-session screen. Factories get a real driver because packages RETAIN the handle: pi-lens closes over tui and calls requestRender from later tool executions — with an undefined handle that call crashed the tool, far outside any factory-time catch."),
|
|
274
274
|
select: surface("full", "Mapped to one native DSH userQuestions single-select request. A terminal-oriented multi-line title becomes DSH's plain heading plus native detail; links render as Markdown on Web and OSC 8 in dsh-TUI without visible escape bytes.", "One native DSH UserQuestionService request carrying Pi's options as the choices. The turn really blocks until a human answers; the shared dialog projection separates title/body and selects the link encoding the active public renderer consumes."),
|
|
275
275
|
confirm: surface("full", "Mapped to one native DSH userQuestions Yes/No request. A terminal-oriented multi-line title becomes DSH's plain heading plus native detail; links render as Markdown on Web and OSC 8 in dsh-TUI without visible escape bytes.", "One native DSH UserQuestionService request with two choices, using the shared dialog projection for title/body and surface-native links."),
|
|
276
276
|
input: surface("full", "Mapped to one native DSH userQuestions free-text request. A terminal-oriented multi-line title becomes DSH's plain heading plus native detail; links render as Markdown on Web and OSC 8 in dsh-TUI without visible escape bytes.", "One native DSH UserQuestionService free-text request. The shared dialog projection preserves visible copy and link destinations, selects the active renderer's link encoding, and removes duplicate raw-link lines."),
|
|
@@ -599,4 +599,4 @@ function ruleForUiContextProperty(property) {
|
|
|
599
599
|
//#endregion
|
|
600
600
|
export { PI_AI_PACKAGES as a, UI_CONTEXT_RULES as c, ruleForEvent as d, ruleForHostImport as f, HOST_IMPORT_RULES as i, ruleForApi as l, CONTEXT_RULES as n, PI_CODING_AGENT_PACKAGES as o, ruleForUiContextProperty as p, EVENT_RULES as r, PI_TUI_PACKAGES as s, API_RULES as t, ruleForContextProperty as u };
|
|
601
601
|
|
|
602
|
-
//# sourceMappingURL=compatibility-
|
|
602
|
+
//# sourceMappingURL=compatibility-CZs3LwYn.mjs.map
|