pi2dsh 0.2.0 → 0.3.1
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 +44 -19
- package/README.zh.md +44 -19
- package/dist/build-DsGYAgiT.mjs +4416 -0
- package/dist/build-DsGYAgiT.mjs.map +1 -0
- package/dist/cli.mjs +2 -2
- package/dist/compat/pi-ai.d.mts +195 -2435
- package/dist/compat/pi-ai.d.mts.map +1 -1
- package/dist/compat/pi-ai.mjs +3 -4668
- package/dist/compat/pi-coding-agent.d.mts +333 -14
- package/dist/compat/pi-coding-agent.d.mts.map +1 -1
- package/dist/compat/pi-coding-agent.mjs +2 -2
- package/dist/compat/pi-tui.mjs +1 -3620
- package/dist/credentials-oauth.d.mts +27 -0
- package/dist/credentials-oauth.d.mts.map +1 -0
- package/dist/credentials-oauth.mjs +91 -0
- package/dist/credentials-oauth.mjs.map +1 -0
- package/dist/host.mjs +4 -2
- package/dist/host.mjs.map +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{mcp-config-jL9w70It.mjs → mcp-config-gqg7GJEE.mjs} +115 -51
- package/dist/mcp-config-gqg7GJEE.mjs.map +1 -0
- package/dist/oauth-bridge-BpPrppjR.mjs +359 -0
- package/dist/oauth-bridge-BpPrppjR.mjs.map +1 -0
- package/dist/pi-ai-CWFlgigJ.mjs +2947 -0
- package/dist/pi-ai-CWFlgigJ.mjs.map +1 -0
- package/dist/pi-coding-agent-Z1hTs61i.mjs +5203 -0
- package/dist/pi-coding-agent-Z1hTs61i.mjs.map +1 -0
- package/dist/pi-tui-5CYLcj-_.mjs +4512 -0
- package/dist/pi-tui-5CYLcj-_.mjs.map +1 -0
- package/dist/pi-types-BLt46jaf.d.mts +2494 -0
- package/dist/pi-types-BLt46jaf.d.mts.map +1 -0
- package/dist/{rolldown-runtime-C2Q2p085.mjs → rolldown-runtime-D-uZhY3_.mjs} +3 -2
- package/dist/{runtime-D84Hv_3m.mjs → runtime-6DefpI6h.mjs} +344 -23
- package/dist/runtime-6DefpI6h.mjs.map +1 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -1
- package/dist/{source-D7Ir-rPT.mjs → source-0sA5z08z.mjs} +6 -2
- package/dist/source-0sA5z08z.mjs.map +1 -0
- package/package.json +14 -1
- package/dist/compat/pi-ai.mjs.map +0 -1
- package/dist/compat/pi-tui.mjs.map +0 -1
- package/dist/mcp-config-jL9w70It.mjs.map +0 -1
- package/dist/pi-coding-agent-Dsg6_0ua.mjs +0 -2060
- package/dist/pi-coding-agent-Dsg6_0ua.mjs.map +0 -1
- package/dist/pi-tui-utils-CcaVtm-3.mjs +0 -895
- package/dist/pi-tui-utils-CcaVtm-3.mjs.map +0 -1
- package/dist/pi-types-KazmR2O5.d.mts +0 -62
- package/dist/pi-types-KazmR2O5.d.mts.map +0 -1
- package/dist/pi-uuid-Db8ShZsK.mjs +0 -47
- package/dist/pi-uuid-Db8ShZsK.mjs.map +0 -1
- package/dist/runtime-D84Hv_3m.mjs.map +0 -1
- package/dist/source-D7Ir-rPT.mjs.map +0 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
import { CredentialInfo, CredentialProvider, CredentialRef, ResolvedCredential } from "@deepseek-ai/dsh-credentials";
|
|
3
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
4
|
+
//#region src/credentials-oauth.d.ts
|
|
5
|
+
type UnknownRecord = Record<string, unknown>;
|
|
6
|
+
declare function oauthCredentialRef(providerId: string): string;
|
|
7
|
+
interface PiOAuthCredentialProviderOptions {
|
|
8
|
+
/** Path to the Pi-format auth.json; defaults to `$agentDir/auth.json`. */
|
|
9
|
+
authPath?: string;
|
|
10
|
+
/** Additional provider configs (id → config with an oauth block), e.g. from packages that registered providers. */
|
|
11
|
+
providers?: ReadonlyMap<string, UnknownRecord>;
|
|
12
|
+
}
|
|
13
|
+
declare class PiOAuthCredentialProvider extends CredentialProvider {
|
|
14
|
+
private readonly oauthStore;
|
|
15
|
+
private readonly extraProviders;
|
|
16
|
+
constructor(ctx: Context, options?: PiOAuthCredentialProviderOptions);
|
|
17
|
+
private oauthConfigFor;
|
|
18
|
+
resolve(ref: CredentialRef): Promise<ResolvedCredential | undefined>;
|
|
19
|
+
describe(ref: CredentialRef): Promise<CredentialInfo>;
|
|
20
|
+
set(ref: CredentialRef, _value: string): Promise<void>;
|
|
21
|
+
unset(ref: CredentialRef): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
declare const name = "pi2dsh-credentials-oauth";
|
|
24
|
+
declare function apply(ctx: Context, config?: PiOAuthCredentialProviderOptions): void;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { PiOAuthCredentialProvider, PiOAuthCredentialProviderOptions, apply, name, oauthCredentialRef };
|
|
27
|
+
//# sourceMappingURL=credentials-oauth.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials-oauth.d.mts","names":[],"sources":["../src/credentials-oauth.ts"],"mappings":";;;;KAOK,gBAAgB;iBAgBL,mBAAmB;UASlB;;EAEf;;EAEA,YAAY,oBAAoB;;cAGrB,kCAAkC;mBAC5B;mBACA;EAEL,YAAA,KAAK,SAAS,UAAS;UAM3B;EAQF,QAAQ,KAAK,gBAAgB,QAAQ;EAiBrC,SAAS,KAAK,gBAAgB,QAAQ;EAUtC,IAAI,KAAK,eAAe,iBAAiB;EAIzC,MAAM,KAAK,gBAAgB;;cAUtB;iBAEG,MAAM,KAAK,SAAS,SAAQ"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
|
|
2
|
+
import { t as getAgentDir } from "./pi-config-shim-CZ1wFzqM.mjs";
|
|
3
|
+
import "./pi-coding-agent-Z1hTs61i.mjs";
|
|
4
|
+
import { a as storedOAuthCredential, i as resolveOAuthApiKey, r as providerSupportsOAuth, t as FileCredentialStore } from "./oauth-bridge-BpPrppjR.mjs";
|
|
5
|
+
import { r as builtinProviders } from "./pi-ai-CWFlgigJ.mjs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { CredentialProvider } from "@deepseek-ai/dsh-credentials";
|
|
8
|
+
//#region src/credentials-oauth.ts
|
|
9
|
+
const OAUTH_REF_PREFIX = "PI2DSH_OAUTH_";
|
|
10
|
+
function oauthCredentialRef(providerId) {
|
|
11
|
+
return `${OAUTH_REF_PREFIX}${providerId.toUpperCase().replaceAll("-", "_")}`;
|
|
12
|
+
}
|
|
13
|
+
function providerIdOfRef(ref) {
|
|
14
|
+
if (!ref.startsWith(OAUTH_REF_PREFIX)) return void 0;
|
|
15
|
+
return ref.slice(13).toLowerCase().replaceAll("_", "-");
|
|
16
|
+
}
|
|
17
|
+
var PiOAuthCredentialProvider = class extends CredentialProvider {
|
|
18
|
+
oauthStore;
|
|
19
|
+
extraProviders;
|
|
20
|
+
constructor(ctx, options = {}) {
|
|
21
|
+
super(ctx);
|
|
22
|
+
this.oauthStore = new FileCredentialStore(options.authPath ?? join(getAgentDir(), "auth.json"));
|
|
23
|
+
this.extraProviders = options.providers ?? /* @__PURE__ */ new Map();
|
|
24
|
+
}
|
|
25
|
+
oauthConfigFor(providerId) {
|
|
26
|
+
const registered = this.extraProviders.get(providerId);
|
|
27
|
+
if (providerSupportsOAuth(registered)) return registered;
|
|
28
|
+
const builtin = builtinProviders().find((provider) => provider.id === providerId);
|
|
29
|
+
if (builtin === void 0) return void 0;
|
|
30
|
+
return {
|
|
31
|
+
name: builtin.name,
|
|
32
|
+
baseUrl: builtin.baseUrl,
|
|
33
|
+
oauth: builtin.auth.oauth
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async resolve(ref) {
|
|
37
|
+
const providerId = providerIdOfRef(String(ref));
|
|
38
|
+
if (providerId === void 0) {
|
|
39
|
+
const value = process.env[String(ref)];
|
|
40
|
+
return value !== void 0 && value.length > 0 ? {
|
|
41
|
+
value,
|
|
42
|
+
source: "env"
|
|
43
|
+
} : void 0;
|
|
44
|
+
}
|
|
45
|
+
const config = this.oauthConfigFor(providerId);
|
|
46
|
+
if (config === void 0) return void 0;
|
|
47
|
+
const value = await resolveOAuthApiKey({
|
|
48
|
+
providerId,
|
|
49
|
+
providerName: typeof config.name === "string" ? config.name : providerId,
|
|
50
|
+
providerConfig: config,
|
|
51
|
+
store: this.oauthStore
|
|
52
|
+
});
|
|
53
|
+
return value !== void 0 && value.length > 0 ? {
|
|
54
|
+
value,
|
|
55
|
+
source: "pi-oauth"
|
|
56
|
+
} : void 0;
|
|
57
|
+
}
|
|
58
|
+
async describe(ref) {
|
|
59
|
+
const providerId = providerIdOfRef(String(ref));
|
|
60
|
+
if (providerId === void 0) {
|
|
61
|
+
const value = process.env[String(ref)];
|
|
62
|
+
return {
|
|
63
|
+
configured: value !== void 0 && value.length > 0,
|
|
64
|
+
...value ? { source: "env" } : {},
|
|
65
|
+
writable: false
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const stored = await storedOAuthCredential(this.oauthStore, providerId);
|
|
69
|
+
return {
|
|
70
|
+
configured: stored !== void 0,
|
|
71
|
+
...stored !== void 0 ? { source: "pi-oauth" } : {},
|
|
72
|
+
writable: false
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async set(ref, _value) {
|
|
76
|
+
throw new Error(`credential ${String(ref)} is read-only here: OAuth tokens are managed by /login, environment values by the shell`);
|
|
77
|
+
}
|
|
78
|
+
async unset(ref) {
|
|
79
|
+
const providerId = providerIdOfRef(String(ref));
|
|
80
|
+
if (providerId === void 0) throw new Error(`credential ${String(ref)} is read-only here: environment values are managed by the shell`);
|
|
81
|
+
await this.oauthStore.delete(providerId, void 0);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const name = "pi2dsh-credentials-oauth";
|
|
85
|
+
function apply(ctx, config = {}) {
|
|
86
|
+
new PiOAuthCredentialProvider(ctx, config);
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { PiOAuthCredentialProvider, apply, name, oauthCredentialRef };
|
|
90
|
+
|
|
91
|
+
//# sourceMappingURL=credentials-oauth.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials-oauth.mjs","names":[],"sources":["../src/credentials-oauth.ts"],"sourcesContent":["import { join } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { CredentialProvider, type CredentialInfo, type CredentialRef, type ResolvedCredential } from '@deepseek-ai/dsh-credentials'\nimport { FileCredentialStore, providerSupportsOAuth, resolveOAuthApiKey, storedOAuthCredential } from './oauth-bridge.js'\nimport { builtinProviders } from './compat/pi-ai.js'\nimport { getAgentDir } from './compat/pi-coding-agent.js'\n\ntype UnknownRecord = Record<string, unknown>\n\n// L4 of the OAuth host seam: a standard dsh-credentials provider that serves\n// Pi OAuth tokens to DSH's native LLM request path. A route configured as\n// `apiKeyEnv: PI2DSH_OAUTH_OPENAI_CODEX` resolves per request through this\n// provider — Pi's double-checked-lock refresh runs on every resolution, so a\n// rotated token reaches the next model call with no restart, exactly the\n// per-operation semantics the credentials seam demands. Every other reference\n// falls through to the process environment, so one provider instance serves a\n// whole composition.\n//\n// Reference convention: PI2DSH_OAUTH_<PROVIDER_ID> where the provider id is\n// upper-cased with `-` as `_` (openai-codex → PI2DSH_OAUTH_OPENAI_CODEX).\n\nconst OAUTH_REF_PREFIX = 'PI2DSH_OAUTH_'\n\nexport function oauthCredentialRef(providerId: string): string {\n return `${OAUTH_REF_PREFIX}${providerId.toUpperCase().replaceAll('-', '_')}`\n}\n\nfunction providerIdOfRef(ref: string): string | undefined {\n if (!ref.startsWith(OAUTH_REF_PREFIX)) return undefined\n return ref.slice(OAUTH_REF_PREFIX.length).toLowerCase().replaceAll('_', '-')\n}\n\nexport interface PiOAuthCredentialProviderOptions {\n /** Path to the Pi-format auth.json; defaults to `$agentDir/auth.json`. */\n authPath?: string\n /** Additional provider configs (id → config with an oauth block), e.g. from packages that registered providers. */\n providers?: ReadonlyMap<string, UnknownRecord>\n}\n\nexport class PiOAuthCredentialProvider extends CredentialProvider {\n private readonly oauthStore: FileCredentialStore\n private readonly extraProviders: ReadonlyMap<string, UnknownRecord>\n\n constructor(ctx: Context, options: PiOAuthCredentialProviderOptions = {}) {\n super(ctx)\n this.oauthStore = new FileCredentialStore(options.authPath ?? join(getAgentDir(), 'auth.json'))\n this.extraProviders = options.providers ?? new Map()\n }\n\n private oauthConfigFor(providerId: string): UnknownRecord | undefined {\n const registered = this.extraProviders.get(providerId)\n if (providerSupportsOAuth(registered)) return registered\n const builtin = builtinProviders().find(provider => provider.id === providerId)\n if (builtin === undefined) return undefined\n return { name: builtin.name, baseUrl: builtin.baseUrl, oauth: builtin.auth.oauth }\n }\n\n async resolve(ref: CredentialRef): Promise<ResolvedCredential | undefined> {\n const providerId = providerIdOfRef(String(ref))\n if (providerId === undefined) {\n const value = process.env[String(ref)]\n return value !== undefined && value.length > 0 ? { value, source: 'env' } : undefined\n }\n const config = this.oauthConfigFor(providerId)\n if (config === undefined) return undefined\n const value = await resolveOAuthApiKey({\n providerId,\n providerName: typeof config.name === 'string' ? config.name : providerId,\n providerConfig: config,\n store: this.oauthStore,\n })\n return value !== undefined && value.length > 0 ? { value, source: 'pi-oauth' } : undefined\n }\n\n async describe(ref: CredentialRef): Promise<CredentialInfo> {\n const providerId = providerIdOfRef(String(ref))\n if (providerId === undefined) {\n const value = process.env[String(ref)]\n return { configured: value !== undefined && value.length > 0, ...(value ? { source: 'env' } : {}), writable: false }\n }\n const stored = await storedOAuthCredential(this.oauthStore, providerId)\n return { configured: stored !== undefined, ...(stored !== undefined ? { source: 'pi-oauth' } : {}), writable: false }\n }\n\n async set(ref: CredentialRef, _value: string): Promise<void> {\n throw new Error(`credential ${String(ref)} is read-only here: OAuth tokens are managed by /login, environment values by the shell`)\n }\n\n async unset(ref: CredentialRef): Promise<void> {\n const providerId = providerIdOfRef(String(ref))\n if (providerId === undefined) {\n throw new Error(`credential ${String(ref)} is read-only here: environment values are managed by the shell`)\n }\n // Logging out is a legitimate unset: drop the stored token.\n await this.oauthStore.delete(providerId, undefined)\n }\n}\n\nexport const name = 'pi2dsh-credentials-oauth'\n\nexport function apply(ctx: Context, config: PiOAuthCredentialProviderOptions = {}): void {\n // The Service constructor registers itself as ctx.credentials.\n void new PiOAuthCredentialProvider(ctx, config)\n}\n"],"mappings":";;;;;;;;AAqBA,MAAM,mBAAmB;AAEzB,SAAgB,mBAAmB,YAA4B;CAC7D,OAAO,GAAG,mBAAmB,WAAW,YAAY,CAAC,CAAC,WAAW,KAAK,GAAG;AAC3E;AAEA,SAAS,gBAAgB,KAAiC;CACxD,IAAI,CAAC,IAAI,WAAW,gBAAgB,GAAG,OAAO,KAAA;CAC9C,OAAO,IAAI,MAAM,EAAuB,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,KAAK,GAAG;AAC7E;AASA,IAAa,4BAAb,cAA+C,mBAAmB;CAChE;CACA;CAEA,YAAY,KAAc,UAA4C,CAAC,GAAG;EACxE,MAAM,GAAG;EACT,KAAK,aAAa,IAAI,oBAAoB,QAAQ,YAAY,KAAK,YAAY,GAAG,WAAW,CAAC;EAC9F,KAAK,iBAAiB,QAAQ,6BAAa,IAAI,IAAI;CACrD;CAEA,eAAuB,YAA+C;EACpE,MAAM,aAAa,KAAK,eAAe,IAAI,UAAU;EACrD,IAAI,sBAAsB,UAAU,GAAG,OAAO;EAC9C,MAAM,UAAU,iBAAiB,CAAC,CAAC,MAAK,aAAY,SAAS,OAAO,UAAU;EAC9E,IAAI,YAAY,KAAA,GAAW,OAAO,KAAA;EAClC,OAAO;GAAE,MAAM,QAAQ;GAAM,SAAS,QAAQ;GAAS,OAAO,QAAQ,KAAK;EAAM;CACnF;CAEA,MAAM,QAAQ,KAA6D;EACzE,MAAM,aAAa,gBAAgB,OAAO,GAAG,CAAC;EAC9C,IAAI,eAAe,KAAA,GAAW;GAC5B,MAAM,QAAQ,QAAQ,IAAI,OAAO,GAAG;GACpC,OAAO,UAAU,KAAA,KAAa,MAAM,SAAS,IAAI;IAAE;IAAO,QAAQ;GAAM,IAAI,KAAA;EAC9E;EACA,MAAM,SAAS,KAAK,eAAe,UAAU;EAC7C,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;EACjC,MAAM,QAAQ,MAAM,mBAAmB;GACrC;GACA,cAAc,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;GAC9D,gBAAgB;GAChB,OAAO,KAAK;EACd,CAAC;EACD,OAAO,UAAU,KAAA,KAAa,MAAM,SAAS,IAAI;GAAE;GAAO,QAAQ;EAAW,IAAI,KAAA;CACnF;CAEA,MAAM,SAAS,KAA6C;EAC1D,MAAM,aAAa,gBAAgB,OAAO,GAAG,CAAC;EAC9C,IAAI,eAAe,KAAA,GAAW;GAC5B,MAAM,QAAQ,QAAQ,IAAI,OAAO,GAAG;GACpC,OAAO;IAAE,YAAY,UAAU,KAAA,KAAa,MAAM,SAAS;IAAG,GAAI,QAAQ,EAAE,QAAQ,MAAM,IAAI,CAAC;IAAI,UAAU;GAAM;EACrH;EACA,MAAM,SAAS,MAAM,sBAAsB,KAAK,YAAY,UAAU;EACtE,OAAO;GAAE,YAAY,WAAW,KAAA;GAAW,GAAI,WAAW,KAAA,IAAY,EAAE,QAAQ,WAAW,IAAI,CAAC;GAAI,UAAU;EAAM;CACtH;CAEA,MAAM,IAAI,KAAoB,QAA+B;EAC3D,MAAM,IAAI,MAAM,cAAc,OAAO,GAAG,EAAE,wFAAwF;CACpI;CAEA,MAAM,MAAM,KAAmC;EAC7C,MAAM,aAAa,gBAAgB,OAAO,GAAG,CAAC;EAC9C,IAAI,eAAe,KAAA,GACjB,MAAM,IAAI,MAAM,cAAc,OAAO,GAAG,EAAE,gEAAgE;EAG5G,MAAM,KAAK,WAAW,OAAO,YAAY,KAAA,CAAS;CACpD;AACF;AAEA,MAAa,OAAO;AAEpB,SAAgB,MAAM,KAAc,SAA2C,CAAC,GAAS;CAEvF,IAAS,0BAA0B,KAAK,MAAM;AAChD"}
|
package/dist/host.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import { t as applyPiPackage } from "./runtime-
|
|
3
|
-
import { t as resolvePiPackage } from "./source-
|
|
2
|
+
import { t as applyPiPackage } from "./runtime-6DefpI6h.mjs";
|
|
3
|
+
import { t as resolvePiPackage } from "./source-0sA5z08z.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { cp, mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
6
6
|
import { basename, dirname, join, relative } from "node:path";
|
|
@@ -157,6 +157,8 @@ async function generateHostBundle(options) {
|
|
|
157
157
|
marked: "^16.4.1",
|
|
158
158
|
typebox: "^1.0.4",
|
|
159
159
|
tinyglobby: "^0.2.15",
|
|
160
|
+
"cross-spawn": "^7.0.6",
|
|
161
|
+
diff: "^9.0.0",
|
|
160
162
|
"@deepseek-ai/dsh-skill-filesystem": "^0.1.0-rc.6"
|
|
161
163
|
},
|
|
162
164
|
peerDependencies: {
|
package/dist/host.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.mjs","names":[],"sources":["../src/host.ts"],"sourcesContent":["// PiHostOnDSH: one DSH plugin that hosts unmodified Pi packages.\n//\n// Instead of converting each package into a vendored bundle, the host bundle\n// declares Pi packages as ordinary npm dependencies; DSH's plugin manager\n// (pnpm) installs them, and at load time this module resolves each installed\n// package, discovers its Pi entry points, and mounts it through the same\n// package-agnostic runtime as converted bundles. One host, any package —\n// there is deliberately no per-package branching here.\n\nimport { readdir, readFile, stat, writeFile, mkdir, cp } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, join, relative } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { applyPiPackage } from './runtime.js'\nimport { resolvePiPackage } from './source.js'\nimport type { GeneratedRuntimeManifest, ResolvedPiPackage } from './types.js'\n\ntype UnknownRecord = Record<string, unknown>\n\nexport interface PiHostPackageSpec {\n /** npm package name as installed in the host bundle's node_modules. */\n name: string\n /** Optional per-package config forwarded to the runtime. */\n config?: UnknownRecord\n}\n\nexport interface PiHostConfig {\n packages: Array<string | PiHostPackageSpec>\n}\n\nfunction parseFrontmatter(text: string): { attributes: Record<string, string>; body: string } {\n const normalized = text.replace(/\\r\\n?/gu, '\\n')\n if (!normalized.startsWith('---')) return { attributes: {}, body: normalized }\n const endIndex = normalized.indexOf('\\n---', 3)\n if (endIndex === -1) return { attributes: {}, body: normalized }\n const attributes: Record<string, string> = {}\n for (const line of normalized.slice(4, endIndex).split('\\n')) {\n const separator = line.indexOf(':')\n if (separator === -1) continue\n const key = line.slice(0, separator).trim()\n let value = line.slice(separator + 1).trim()\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1)\n }\n if (key.length > 0) attributes[key] = value\n }\n return { attributes, body: normalized.slice(endIndex + 4).trim() }\n}\n\n/** Build a runtime manifest in place over an installed Pi package directory. */\nexport async function manifestForInstalled(pkg: ResolvedPiPackage): Promise<GeneratedRuntimeManifest> {\n const relativeTo = (file: string): string => relative(pkg.rootDir, file).replaceAll('\\\\', '/')\n\n const skillDirs = new Set<string>()\n for (const file of pkg.resources.skills) {\n // <dir>/<name>/SKILL.md contributes <dir>; a flat <dir>/<name>.md contributes <dir>.\n skillDirs.add(relativeTo(basename(file) === 'SKILL.md' ? dirname(dirname(file)) : dirname(file)))\n }\n\n const prompts: GeneratedRuntimeManifest['prompts'] = []\n const promptNames = new Set<string>()\n for (const source of pkg.resources.prompts) {\n const name = basename(source, '.md').toLowerCase().replace(/[^a-z0-9_-]+/gu, '-')\n if (promptNames.has(name)) throw new Error(`prompt command name collision in ${pkg.identity.name}: ${name}`)\n promptNames.add(name)\n const { attributes, body } = parseFrontmatter(await readFile(source, 'utf8'))\n const firstLine = body.split(/\\r?\\n/u).map(line => line.trim()).find(Boolean)\n prompts.push({\n name,\n description: attributes.description ?? firstLine ?? `Run migrated Pi prompt ${name}`,\n ...(attributes['argument-hint'] !== undefined ? { argumentHint: attributes['argument-hint'] } : {}),\n path: relativeTo(source),\n })\n }\n\n return {\n schemaVersion: 1,\n package: pkg.identity,\n extensions: pkg.resources.extensions.map(relativeTo),\n skillDirs: [...skillDirs].sort(),\n prompts,\n }\n}\n\nfunction normalizeSpecs(config: PiHostConfig): PiHostPackageSpec[] {\n const packages = Array.isArray(config?.packages) ? config.packages : []\n return packages.map(spec => (typeof spec === 'string' ? { name: spec } : spec))\n .filter(spec => typeof spec?.name === 'string' && spec.name.length > 0)\n}\n\nfunction resolveInstalledDir(anchor: string, packageName: string): string {\n const require = createRequire(anchor)\n return dirname(require.resolve(`${packageName}/package.json`))\n}\n\n/**\n * Mount every configured Pi package from the host bundle's own node_modules.\n * Packages that fail to mount report their error and do not take down the\n * host or their siblings — matching Pi's own per-extension error isolation.\n */\nexport async function applyPiHost(ctx: Context, config: PiHostConfig, anchor?: string): Promise<void> {\n const anchorPath = anchor ?? fileURLToPath(import.meta.url)\n const errors: Array<{ name: string; error: string }> = []\n for (const spec of normalizeSpecs(config)) {\n try {\n const dir = resolveInstalledDir(anchorPath, spec.name)\n const pkg = await resolvePiPackage(dir)\n try {\n const manifest = await manifestForInstalled(pkg)\n await applyPiPackage(ctx, {\n rootUrl: pathToFileURL(`${pkg.rootDir}/`),\n manifest,\n ...(spec.config === undefined ? {} : { config: spec.config }),\n })\n } finally {\n await pkg.dispose()\n }\n } catch (error) {\n errors.push({ name: spec.name, error: error instanceof Error ? error.message : String(error) })\n }\n }\n for (const failure of errors) {\n const log = (ctx as unknown as { logger?: { warn?(message: string): void } }).logger\n const warn = log?.warn?.bind(log) ?? console.warn\n warn(`[pi2dsh host] failed to mount ${failure.name}: ${failure.error}`)\n }\n if (errors.length > 0 && errors.length === normalizeSpecs(config).length) {\n throw new Error(`pi2dsh host mounted no packages; first failure: ${errors[0]!.name}: ${errors[0]!.error}`)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Host bundle generation\n// ---------------------------------------------------------------------------\n\nexport interface HostBundleOptions {\n outDir: string\n /** npm specs, e.g. \"@narumitw/pi-lsp@0.49.4\" or \"pi-ask-user\". */\n packages: string[]\n bundleName?: string\n}\n\nfunction splitSpec(spec: string): { name: string; range: string } {\n const at = spec.lastIndexOf('@')\n if (at > 0) return { name: spec.slice(0, at), range: spec.slice(at + 1) }\n return { name: spec, range: '*' }\n}\n\nasync function firstExisting(paths: string[]): Promise<string> {\n for (const path of paths) {\n try {\n await stat(path)\n return path\n } catch {\n // Try the next layout.\n }\n }\n throw new Error(`cannot locate pi2dsh runtime artifact; tried: ${paths.join(', ')}`)\n}\n\nasync function copyEmbeddedHostRuntime(outDir: string): Promise<void> {\n const moduleDir = dirname(fileURLToPath(import.meta.url))\n const hostSource = await firstExisting([\n join(moduleDir, 'host.mjs'),\n join(moduleDir, '../dist/host.mjs'),\n ])\n const distRoot = dirname(hostSource)\n const targetRoot = join(outDir, 'runtime')\n await mkdir(join(targetRoot, 'compat', 'vendor'), { recursive: true })\n for (const entry of await readdir(distRoot)) {\n if (entry.endsWith('.mjs') || entry.endsWith('.d.mts')) {\n await cp(join(distRoot, entry), join(targetRoot, entry))\n }\n }\n for (const sub of ['compat', join('compat', 'vendor')]) {\n const dir = join(distRoot, sub)\n try {\n for (const entry of await readdir(dir)) {\n if (entry.endsWith('.mjs')) await cp(join(dir, entry), join(targetRoot, sub, entry))\n }\n } catch {\n // dist layout without that subdirectory\n }\n }\n}\n\nexport async function generateHostBundle(options: HostBundleOptions): Promise<{ outDir: string; packageName: string }> {\n const specs = options.packages.map(splitSpec)\n if (specs.length === 0) throw new Error('host bundle requires at least one Pi package spec')\n const packageName = options.bundleName ?? 'dsh-pi-host'\n await mkdir(options.outDir, { recursive: true })\n await copyEmbeddedHostRuntime(options.outDir)\n\n const packageJson = {\n name: packageName,\n version: '0.1.0',\n description: `pi2dsh host bundle mounting ${specs.map(spec => spec.name).join(', ')} as native DSH plugins`,\n type: 'module',\n main: './index.js',\n files: ['index.js', 'cordis.patch.yml', 'runtime', 'PI2DSH-LICENSE', 'README.md'],\n dependencies: {\n ...Object.fromEntries(specs.map(spec => [spec.name, spec.range])),\n jiti: '^2.7.0',\n 'get-east-asian-width': '^1.6.0',\n marked: '^16.4.1',\n typebox: '^1.0.4',\n tinyglobby: '^0.2.15',\n '@deepseek-ai/dsh-skill-filesystem': '^0.1.0-rc.6',\n },\n peerDependencies: {\n '@deepseek-ai/dsh-llm': '^0.1.0-rc.6',\n '@deepseek-ai/dsh-system-prompt': '^0.1.0-rc.6',\n },\n keywords: ['dsh-plugin', 'deepseek-harness', 'pi-package', 'pi2dsh', 'pi-host'],\n license: 'MIT',\n dsh: { bundle: { patch: './cordis.patch.yml' } },\n }\n await writeFile(join(options.outDir, 'package.json'), `${JSON.stringify(packageJson, null, 2)}\\n`)\n\n const hostConfig: PiHostConfig = { packages: specs.map(spec => spec.name) }\n const indexSource = `import { applyPiHost } from './runtime/host.mjs'\\n\\n`\n + `export const name = ${JSON.stringify(packageName)}\\n`\n + `export const inject = ${JSON.stringify(['tools', 'systemPrompt', 'commands', 'skills'])}\\n\\n`\n + `const hostConfig = ${JSON.stringify(hostConfig, null, 2)}\\n\\n`\n + `export async function apply(ctx, config = {}) {\\n`\n + ` await applyPiHost(ctx, { ...hostConfig, ...config }, new URL(import.meta.url).pathname)\\n`\n + `}\\n`\n await writeFile(join(options.outDir, 'index.js'), indexSource)\n\n await writeFile(join(options.outDir, 'cordis.patch.yml'),\n `- insert:\\n - id: ${packageName}\\n name: ${JSON.stringify(packageName)}\\n`)\n\n const licenseSource = await firstExisting([\n join(dirname(fileURLToPath(import.meta.url)), 'compat/vendor/PI-LICENSE'),\n join(dirname(fileURLToPath(import.meta.url)), '../src/compat/vendor/PI-LICENSE'),\n ])\n await cp(licenseSource, join(options.outDir, 'PI2DSH-LICENSE'))\n\n await writeFile(join(options.outDir, 'README.md'),\n `# ${packageName}\\n\\n`\n + `A [pi2dsh](https://github.com/weijiafu14/pi2dsh) host bundle. The Pi packages below are installed as ordinary npm dependencies and mounted at load time — no per-package conversion, no vendored source snapshots.\\n\\n`\n + specs.map(spec => `- \\`${spec.name}@${spec.range}\\`\\n`).join('')\n + `\\nInstall:\\n\\n\\`\\`\\`sh\\ndsh plugin --profile headless add file:$PWD\\ndsh --profile headless --dump-config\\n\\`\\`\\`\\n`\n + `\\nThe packages execute their original Pi extension source inside the pi2dsh Host ABI; install only sources you trust. Run \\`pi2dsh inspect <package>\\` for each package's compatibility report.\\n`)\n\n return { outDir: options.outDir, packageName }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"host.mjs","names":[],"sources":["../src/host.ts"],"sourcesContent":["// PiHostOnDSH: one DSH plugin that hosts unmodified Pi packages.\n//\n// Instead of converting each package into a vendored bundle, the host bundle\n// declares Pi packages as ordinary npm dependencies; DSH's plugin manager\n// (pnpm) installs them, and at load time this module resolves each installed\n// package, discovers its Pi entry points, and mounts it through the same\n// package-agnostic runtime as converted bundles. One host, any package —\n// there is deliberately no per-package branching here.\n\nimport { readdir, readFile, stat, writeFile, mkdir, cp } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, join, relative } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { applyPiPackage } from './runtime.js'\nimport { resolvePiPackage } from './source.js'\nimport type { GeneratedRuntimeManifest, ResolvedPiPackage } from './types.js'\n\ntype UnknownRecord = Record<string, unknown>\n\nexport interface PiHostPackageSpec {\n /** npm package name as installed in the host bundle's node_modules. */\n name: string\n /** Optional per-package config forwarded to the runtime. */\n config?: UnknownRecord\n}\n\nexport interface PiHostConfig {\n packages: Array<string | PiHostPackageSpec>\n}\n\nfunction parseFrontmatter(text: string): { attributes: Record<string, string>; body: string } {\n const normalized = text.replace(/\\r\\n?/gu, '\\n')\n if (!normalized.startsWith('---')) return { attributes: {}, body: normalized }\n const endIndex = normalized.indexOf('\\n---', 3)\n if (endIndex === -1) return { attributes: {}, body: normalized }\n const attributes: Record<string, string> = {}\n for (const line of normalized.slice(4, endIndex).split('\\n')) {\n const separator = line.indexOf(':')\n if (separator === -1) continue\n const key = line.slice(0, separator).trim()\n let value = line.slice(separator + 1).trim()\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1)\n }\n if (key.length > 0) attributes[key] = value\n }\n return { attributes, body: normalized.slice(endIndex + 4).trim() }\n}\n\n/** Build a runtime manifest in place over an installed Pi package directory. */\nexport async function manifestForInstalled(pkg: ResolvedPiPackage): Promise<GeneratedRuntimeManifest> {\n const relativeTo = (file: string): string => relative(pkg.rootDir, file).replaceAll('\\\\', '/')\n\n const skillDirs = new Set<string>()\n for (const file of pkg.resources.skills) {\n // <dir>/<name>/SKILL.md contributes <dir>; a flat <dir>/<name>.md contributes <dir>.\n skillDirs.add(relativeTo(basename(file) === 'SKILL.md' ? dirname(dirname(file)) : dirname(file)))\n }\n\n const prompts: GeneratedRuntimeManifest['prompts'] = []\n const promptNames = new Set<string>()\n for (const source of pkg.resources.prompts) {\n const name = basename(source, '.md').toLowerCase().replace(/[^a-z0-9_-]+/gu, '-')\n if (promptNames.has(name)) throw new Error(`prompt command name collision in ${pkg.identity.name}: ${name}`)\n promptNames.add(name)\n const { attributes, body } = parseFrontmatter(await readFile(source, 'utf8'))\n const firstLine = body.split(/\\r?\\n/u).map(line => line.trim()).find(Boolean)\n prompts.push({\n name,\n description: attributes.description ?? firstLine ?? `Run migrated Pi prompt ${name}`,\n ...(attributes['argument-hint'] !== undefined ? { argumentHint: attributes['argument-hint'] } : {}),\n path: relativeTo(source),\n })\n }\n\n return {\n schemaVersion: 1,\n package: pkg.identity,\n extensions: pkg.resources.extensions.map(relativeTo),\n skillDirs: [...skillDirs].sort(),\n prompts,\n }\n}\n\nfunction normalizeSpecs(config: PiHostConfig): PiHostPackageSpec[] {\n const packages = Array.isArray(config?.packages) ? config.packages : []\n return packages.map(spec => (typeof spec === 'string' ? { name: spec } : spec))\n .filter(spec => typeof spec?.name === 'string' && spec.name.length > 0)\n}\n\nfunction resolveInstalledDir(anchor: string, packageName: string): string {\n const require = createRequire(anchor)\n return dirname(require.resolve(`${packageName}/package.json`))\n}\n\n/**\n * Mount every configured Pi package from the host bundle's own node_modules.\n * Packages that fail to mount report their error and do not take down the\n * host or their siblings — matching Pi's own per-extension error isolation.\n */\nexport async function applyPiHost(ctx: Context, config: PiHostConfig, anchor?: string): Promise<void> {\n const anchorPath = anchor ?? fileURLToPath(import.meta.url)\n const errors: Array<{ name: string; error: string }> = []\n for (const spec of normalizeSpecs(config)) {\n try {\n const dir = resolveInstalledDir(anchorPath, spec.name)\n const pkg = await resolvePiPackage(dir)\n try {\n const manifest = await manifestForInstalled(pkg)\n await applyPiPackage(ctx, {\n rootUrl: pathToFileURL(`${pkg.rootDir}/`),\n manifest,\n ...(spec.config === undefined ? {} : { config: spec.config }),\n })\n } finally {\n await pkg.dispose()\n }\n } catch (error) {\n errors.push({ name: spec.name, error: error instanceof Error ? error.message : String(error) })\n }\n }\n for (const failure of errors) {\n const log = (ctx as unknown as { logger?: { warn?(message: string): void } }).logger\n const warn = log?.warn?.bind(log) ?? console.warn\n warn(`[pi2dsh host] failed to mount ${failure.name}: ${failure.error}`)\n }\n if (errors.length > 0 && errors.length === normalizeSpecs(config).length) {\n throw new Error(`pi2dsh host mounted no packages; first failure: ${errors[0]!.name}: ${errors[0]!.error}`)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Host bundle generation\n// ---------------------------------------------------------------------------\n\nexport interface HostBundleOptions {\n outDir: string\n /** npm specs, e.g. \"@narumitw/pi-lsp@0.49.4\" or \"pi-ask-user\". */\n packages: string[]\n bundleName?: string\n}\n\nfunction splitSpec(spec: string): { name: string; range: string } {\n const at = spec.lastIndexOf('@')\n if (at > 0) return { name: spec.slice(0, at), range: spec.slice(at + 1) }\n return { name: spec, range: '*' }\n}\n\nasync function firstExisting(paths: string[]): Promise<string> {\n for (const path of paths) {\n try {\n await stat(path)\n return path\n } catch {\n // Try the next layout.\n }\n }\n throw new Error(`cannot locate pi2dsh runtime artifact; tried: ${paths.join(', ')}`)\n}\n\nasync function copyEmbeddedHostRuntime(outDir: string): Promise<void> {\n const moduleDir = dirname(fileURLToPath(import.meta.url))\n const hostSource = await firstExisting([\n join(moduleDir, 'host.mjs'),\n join(moduleDir, '../dist/host.mjs'),\n ])\n const distRoot = dirname(hostSource)\n const targetRoot = join(outDir, 'runtime')\n await mkdir(join(targetRoot, 'compat', 'vendor'), { recursive: true })\n for (const entry of await readdir(distRoot)) {\n if (entry.endsWith('.mjs') || entry.endsWith('.d.mts')) {\n await cp(join(distRoot, entry), join(targetRoot, entry))\n }\n }\n for (const sub of ['compat', join('compat', 'vendor')]) {\n const dir = join(distRoot, sub)\n try {\n for (const entry of await readdir(dir)) {\n if (entry.endsWith('.mjs')) await cp(join(dir, entry), join(targetRoot, sub, entry))\n }\n } catch {\n // dist layout without that subdirectory\n }\n }\n}\n\nexport async function generateHostBundle(options: HostBundleOptions): Promise<{ outDir: string; packageName: string }> {\n const specs = options.packages.map(splitSpec)\n if (specs.length === 0) throw new Error('host bundle requires at least one Pi package spec')\n const packageName = options.bundleName ?? 'dsh-pi-host'\n await mkdir(options.outDir, { recursive: true })\n await copyEmbeddedHostRuntime(options.outDir)\n\n const packageJson = {\n name: packageName,\n version: '0.1.0',\n description: `pi2dsh host bundle mounting ${specs.map(spec => spec.name).join(', ')} as native DSH plugins`,\n type: 'module',\n main: './index.js',\n files: ['index.js', 'cordis.patch.yml', 'runtime', 'PI2DSH-LICENSE', 'README.md'],\n dependencies: {\n ...Object.fromEntries(specs.map(spec => [spec.name, spec.range])),\n jiti: '^2.7.0',\n 'get-east-asian-width': '^1.6.0',\n marked: '^16.4.1',\n typebox: '^1.0.4',\n tinyglobby: '^0.2.15',\n // The vendored Pi built-in tool constructors spawn through cross-spawn\n // and diff exactly as Pi does — same runtime set the convert bundle\n // carries (generator.ts keeps the sibling list).\n 'cross-spawn': '^7.0.6',\n diff: '^9.0.0',\n '@deepseek-ai/dsh-skill-filesystem': '^0.1.0-rc.6',\n },\n peerDependencies: {\n '@deepseek-ai/dsh-llm': '^0.1.0-rc.6',\n '@deepseek-ai/dsh-system-prompt': '^0.1.0-rc.6',\n },\n keywords: ['dsh-plugin', 'deepseek-harness', 'pi-package', 'pi2dsh', 'pi-host'],\n license: 'MIT',\n dsh: { bundle: { patch: './cordis.patch.yml' } },\n }\n await writeFile(join(options.outDir, 'package.json'), `${JSON.stringify(packageJson, null, 2)}\\n`)\n\n const hostConfig: PiHostConfig = { packages: specs.map(spec => spec.name) }\n const indexSource = `import { applyPiHost } from './runtime/host.mjs'\\n\\n`\n + `export const name = ${JSON.stringify(packageName)}\\n`\n + `export const inject = ${JSON.stringify(['tools', 'systemPrompt', 'commands', 'skills'])}\\n\\n`\n + `const hostConfig = ${JSON.stringify(hostConfig, null, 2)}\\n\\n`\n + `export async function apply(ctx, config = {}) {\\n`\n + ` await applyPiHost(ctx, { ...hostConfig, ...config }, new URL(import.meta.url).pathname)\\n`\n + `}\\n`\n await writeFile(join(options.outDir, 'index.js'), indexSource)\n\n await writeFile(join(options.outDir, 'cordis.patch.yml'),\n `- insert:\\n - id: ${packageName}\\n name: ${JSON.stringify(packageName)}\\n`)\n\n const licenseSource = await firstExisting([\n join(dirname(fileURLToPath(import.meta.url)), 'compat/vendor/PI-LICENSE'),\n join(dirname(fileURLToPath(import.meta.url)), '../src/compat/vendor/PI-LICENSE'),\n ])\n await cp(licenseSource, join(options.outDir, 'PI2DSH-LICENSE'))\n\n await writeFile(join(options.outDir, 'README.md'),\n `# ${packageName}\\n\\n`\n + `A [pi2dsh](https://github.com/weijiafu14/pi2dsh) host bundle. The Pi packages below are installed as ordinary npm dependencies and mounted at load time — no per-package conversion, no vendored source snapshots.\\n\\n`\n + specs.map(spec => `- \\`${spec.name}@${spec.range}\\`\\n`).join('')\n + `\\nInstall:\\n\\n\\`\\`\\`sh\\ndsh plugin --profile headless add file:$PWD\\ndsh --profile headless --dump-config\\n\\`\\`\\`\\n`\n + `\\nThe packages execute their original Pi extension source inside the pi2dsh Host ABI; install only sources you trust. Run \\`pi2dsh inspect <package>\\` for each package's compatibility report.\\n`)\n\n return { outDir: options.outDir, packageName }\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/analyzer.ts","../src/compatibility.ts","../src/generator.ts","../src/mcp-config.ts","../src/source.ts"],"mappings":";;;;iBAgbsB,eAAe,KAAK,oBAAoB,QAAQ;;;UC9a5D;EACR,OAAO;EACP;;cAKW;cAKA;cAKA;cASA,mBAAmB,SAAS,eAAe,SAAS,eAAe;cAoMnE,eAAe,SAAS,eAAe;cA2BvC,kBAAkB,SAAS,eAAe;cA+B1C,WAAW,SAAS,eAAe;cAgHnC,aAAa,SAAS,eAAe;iBA6FlC,WAAW,iBAAiB;iBAI5B,aAAa,gBAAgB;iBAO7B,kBAAkB,qBAAqB,uBAAuB;iBAS9D,uBAAuB,mBAAmB;iBAI1C,yBAAyB,mBAAmB;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/analyzer.ts","../src/compatibility.ts","../src/generator.ts","../src/mcp-config.ts","../src/source.ts"],"mappings":";;;;iBAgbsB,eAAe,KAAK,oBAAoB,QAAQ;;;UC9a5D;EACR,OAAO;EACP;;cAKW;cAKA;cAKA;cASA,mBAAmB,SAAS,eAAe,SAAS,eAAe;cAoMnE,eAAe,SAAS,eAAe;cA2BvC,kBAAkB,SAAS,eAAe;cA+B1C,WAAW,SAAS,eAAe;cAgHnC,aAAa,SAAS,eAAe;iBA6FlC,WAAW,iBAAiB;iBAI5B,aAAa,gBAAgB;iBAO7B,kBAAkB,qBAAqB,uBAAuB;iBAS9D,uBAAuB,mBAAmB;iBAI1C,yBAAyB,mBAAmB;;;iBC/KtC,eACpB,KAAK,mBACL,SAAS,kBACR;EAAU;EAAgB,QAAQ;EAAqB;;;;KCtUrD,gBAAgB;UAEJ;EACf;EACA;EACA;EACA;EACA;EACA,MAAM;EACN;EACA;EACA,UAAU;EACV;;UAGe;EACf;EACA;;UAGe;EACf,SAAS;EACT,SAAS;EACT,UAAU;EACV;;iBA6Cc,oBAAoB,aAAa;EAA8B,SAAS,YAAY;EAAc;;iBAoElG,mBAAmB,aAAa,wBAA4B;;iBAsD5D,eAAe,QAAQ;;;iBC5EjB,iBAAiB,gBAAgB,eAAsB,QAAQ"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { _ as ruleForHostImport, a as analyzePackage, c as EVENT_RULES, d as PI_CODING_AGENT_PACKAGES, f as PI_TUI_PACKAGES, g as ruleForEvent, h as ruleForContextProperty, i as generateBundle, l as HOST_IMPORT_RULES, m as ruleForApi, n as convertPiMcpConfig, o as API_RULES, p as UI_CONTEXT_RULES, r as renderMcpPatch, s as CONTEXT_RULES, t as collectPiMcpServers, u as PI_AI_PACKAGES, v as ruleForUiContextProperty } from "./mcp-config-
|
|
3
|
-
import { t as resolvePiPackage } from "./source-
|
|
2
|
+
import { _ as ruleForHostImport, a as analyzePackage, c as EVENT_RULES, d as PI_CODING_AGENT_PACKAGES, f as PI_TUI_PACKAGES, g as ruleForEvent, h as ruleForContextProperty, i as generateBundle, l as HOST_IMPORT_RULES, m as ruleForApi, n as convertPiMcpConfig, o as API_RULES, p as UI_CONTEXT_RULES, r as renderMcpPatch, s as CONTEXT_RULES, t as collectPiMcpServers, u as PI_AI_PACKAGES, v as ruleForUiContextProperty } from "./mcp-config-gqg7GJEE.mjs";
|
|
3
|
+
import { t as resolvePiPackage } from "./source-0sA5z08z.mjs";
|
|
4
4
|
import { applyPiHost, generateHostBundle, manifestForInstalled } from "./host.mjs";
|
|
5
5
|
export { API_RULES, CONTEXT_RULES, EVENT_RULES, HOST_IMPORT_RULES, PI_AI_PACKAGES, PI_CODING_AGENT_PACKAGES, PI_TUI_PACKAGES, UI_CONTEXT_RULES, analyzePackage, applyPiHost, collectPiMcpServers, convertPiMcpConfig, generateBundle, generateHostBundle, manifestForInstalled, renderMcpPatch, resolvePiPackage, ruleForApi, ruleForContextProperty, ruleForEvent, ruleForHostImport, ruleForUiContextProperty };
|
|
@@ -555,11 +555,16 @@ function localReferences(path, text) {
|
|
|
555
555
|
const values = /* @__PURE__ */ new Map();
|
|
556
556
|
const createRequireNames = /* @__PURE__ */ new Set(["createRequire"]);
|
|
557
557
|
const requireNames = /* @__PURE__ */ new Set(["require"]);
|
|
558
|
-
const add = (kind, specifier) => {
|
|
559
|
-
if (specifier.startsWith(".")
|
|
558
|
+
const add = (kind, specifier, lazy) => {
|
|
559
|
+
if (!specifier.startsWith(".") && !specifier.startsWith("#")) return;
|
|
560
|
+
const key = `${kind}:${specifier}`;
|
|
561
|
+
const existing = values.get(key);
|
|
562
|
+
if (existing === void 0) values.set(key, {
|
|
560
563
|
kind,
|
|
561
|
-
specifier
|
|
564
|
+
specifier,
|
|
565
|
+
lazy
|
|
562
566
|
});
|
|
567
|
+
else if (existing.lazy && !lazy) existing.lazy = false;
|
|
563
568
|
};
|
|
564
569
|
function collectRequireAliases(node) {
|
|
565
570
|
if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier) && (node.moduleSpecifier.text === "node:module" || node.moduleSpecifier.text === "module") && node.importClause?.namedBindings !== void 0 && ts.isNamedImports(node.importClause.namedBindings)) {
|
|
@@ -569,14 +574,14 @@ function localReferences(path, text) {
|
|
|
569
574
|
}
|
|
570
575
|
collectRequireAliases(source);
|
|
571
576
|
function visit(node) {
|
|
572
|
-
if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier !== void 0 && ts.isStringLiteral(node.moduleSpecifier)) add("module", node.moduleSpecifier.text);
|
|
573
|
-
else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) add("module", node.moduleReference.expression.text);
|
|
577
|
+
if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier !== void 0 && ts.isStringLiteral(node.moduleSpecifier)) add("module", node.moduleSpecifier.text, false);
|
|
578
|
+
else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) add("module", node.moduleReference.expression.text, false);
|
|
574
579
|
else if (ts.isCallExpression(node) && node.arguments.length > 0 && (node.expression.kind === ts.SyntaxKind.ImportKeyword || ts.isIdentifier(node.expression) && requireNames.has(node.expression.text))) {
|
|
575
580
|
const specifier = literalModule(node.arguments[0]);
|
|
576
|
-
if (specifier !== void 0) add("module", specifier);
|
|
581
|
+
if (specifier !== void 0) add("module", specifier, insideFunctionBody(node));
|
|
577
582
|
} else if (ts.isNewExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "URL" && isImportMetaUrl(node.arguments?.[1])) {
|
|
578
583
|
const specifier = literalModule(node.arguments?.[0]);
|
|
579
|
-
if (specifier !== void 0) add("asset", specifier);
|
|
584
|
+
if (specifier !== void 0) add("asset", specifier, false);
|
|
580
585
|
}
|
|
581
586
|
ts.forEachChild(node, visit);
|
|
582
587
|
}
|
|
@@ -584,18 +589,41 @@ function localReferences(path, text) {
|
|
|
584
589
|
return [...values.values()];
|
|
585
590
|
}
|
|
586
591
|
function externalPackage(specifier) {
|
|
587
|
-
if (specifier.startsWith(".") || specifier.startsWith("/") || specifier.startsWith("#") || specifier.startsWith("node:") || builtinModules.includes(specifier)) return void 0;
|
|
592
|
+
if (specifier.startsWith(".") || specifier.startsWith("/") || specifier.startsWith("#") || specifier.startsWith("node:") || specifier.startsWith("bun:") || builtinModules.includes(specifier)) return void 0;
|
|
588
593
|
const parts = specifier.split("/");
|
|
589
594
|
return specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0];
|
|
590
595
|
}
|
|
596
|
+
function insideTry(node) {
|
|
597
|
+
let current = node.parent;
|
|
598
|
+
while (current !== void 0) {
|
|
599
|
+
if (ts.isTryStatement(current)) return true;
|
|
600
|
+
if (ts.isFunctionLike(current)) return false;
|
|
601
|
+
current = current.parent;
|
|
602
|
+
}
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
function insideFunctionBody(node) {
|
|
606
|
+
let current = node.parent;
|
|
607
|
+
while (current !== void 0) {
|
|
608
|
+
if (ts.isFunctionLike(current)) return true;
|
|
609
|
+
current = current.parent;
|
|
610
|
+
}
|
|
611
|
+
return false;
|
|
612
|
+
}
|
|
591
613
|
function runtimeExternalPackages(path, text) {
|
|
592
614
|
const source = ts.createSourceFile(path, text, ts.ScriptTarget.Latest, true, sourceKind(path));
|
|
593
|
-
const packages = /* @__PURE__ */ new
|
|
615
|
+
const packages = /* @__PURE__ */ new Map();
|
|
594
616
|
const createRequireNames = /* @__PURE__ */ new Set(["createRequire"]);
|
|
595
617
|
const requireNames = /* @__PURE__ */ new Set(["require"]);
|
|
596
|
-
const add = (specifier) => {
|
|
618
|
+
const add = (specifier, lazy) => {
|
|
597
619
|
const name = externalPackage(specifier);
|
|
598
|
-
if (name
|
|
620
|
+
if (name === void 0 || name.length === 0) return;
|
|
621
|
+
const existing = packages.get(name);
|
|
622
|
+
if (existing === void 0) packages.set(name, {
|
|
623
|
+
name,
|
|
624
|
+
lazy
|
|
625
|
+
});
|
|
626
|
+
else if (existing.lazy && !lazy) existing.lazy = false;
|
|
599
627
|
};
|
|
600
628
|
function collectRequireAliases(node) {
|
|
601
629
|
if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier) && (node.moduleSpecifier.text === "node:module" || node.moduleSpecifier.text === "module") && node.importClause?.namedBindings !== void 0 && ts.isNamedImports(node.importClause.namedBindings)) {
|
|
@@ -609,17 +637,19 @@ function runtimeExternalPackages(path, text) {
|
|
|
609
637
|
const clause = node.importClause;
|
|
610
638
|
const named = clause?.namedBindings;
|
|
611
639
|
const namedImportsAreTypeOnly = named !== void 0 && ts.isNamedImports(named) && named.elements.length > 0 && named.elements.every((element) => element.isTypeOnly);
|
|
612
|
-
if (clause === void 0 || !clause.isTypeOnly && (clause.name !== void 0 || !namedImportsAreTypeOnly)) add(node.moduleSpecifier.text);
|
|
613
|
-
} else if (ts.isExportDeclaration(node) && !node.isTypeOnly && node.moduleSpecifier !== void 0 && ts.isStringLiteral(node.moduleSpecifier)) add(node.moduleSpecifier.text);
|
|
614
|
-
else if (ts.isImportEqualsDeclaration(node) && !node.isTypeOnly && ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) add(node.moduleReference.expression.text);
|
|
640
|
+
if (clause === void 0 || !clause.isTypeOnly && (clause.name !== void 0 || !namedImportsAreTypeOnly)) add(node.moduleSpecifier.text, false);
|
|
641
|
+
} else if (ts.isExportDeclaration(node) && !node.isTypeOnly && node.moduleSpecifier !== void 0 && ts.isStringLiteral(node.moduleSpecifier)) add(node.moduleSpecifier.text, false);
|
|
642
|
+
else if (ts.isImportEqualsDeclaration(node) && !node.isTypeOnly && ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) add(node.moduleReference.expression.text, false);
|
|
615
643
|
else if (ts.isCallExpression(node) && node.arguments.length > 0 && (node.expression.kind === ts.SyntaxKind.ImportKeyword || ts.isIdentifier(node.expression) && requireNames.has(node.expression.text))) {
|
|
616
|
-
|
|
617
|
-
|
|
644
|
+
if (!insideTry(node)) {
|
|
645
|
+
const specifier = literalModule(node.arguments[0]);
|
|
646
|
+
if (specifier !== void 0) add(specifier, insideFunctionBody(node));
|
|
647
|
+
}
|
|
618
648
|
}
|
|
619
649
|
ts.forEachChild(node, visit);
|
|
620
650
|
}
|
|
621
651
|
visit(source);
|
|
622
|
-
return [...packages];
|
|
652
|
+
return [...packages.values()];
|
|
623
653
|
}
|
|
624
654
|
function inside(rootDir, path) {
|
|
625
655
|
const pathRelative = relative(rootDir, path);
|
|
@@ -714,34 +744,56 @@ async function expandAsset(path, rootDir) {
|
|
|
714
744
|
return output;
|
|
715
745
|
}
|
|
716
746
|
async function collectLocalClosure(rootDir, entries) {
|
|
717
|
-
const queue = entries.map((path) => resolve(path));
|
|
718
|
-
const closure = /* @__PURE__ */ new Set();
|
|
719
|
-
const issues = [];
|
|
720
747
|
const importsMap = await packageImportsMap(rootDir);
|
|
748
|
+
const graph = /* @__PURE__ */ new Map();
|
|
749
|
+
const issues = [];
|
|
750
|
+
const queue = entries.map((path) => resolve(path));
|
|
721
751
|
while (queue.length > 0) {
|
|
722
752
|
const source = queue.shift();
|
|
723
|
-
if (
|
|
753
|
+
if (graph.has(source)) continue;
|
|
724
754
|
if (!inside(rootDir, source)) throw new Error(`extension source escapes the Pi package: ${source}`);
|
|
725
755
|
const info = await lstat(source);
|
|
726
756
|
if (info.isSymbolicLink()) throw new Error(`refusing to copy symbolic link from Pi package: ${source}`);
|
|
727
757
|
if (!info.isFile()) throw new Error(`extension closure contains a non-file path: ${source}`);
|
|
728
|
-
|
|
758
|
+
const edges = [];
|
|
759
|
+
graph.set(source, edges);
|
|
729
760
|
if (!SCRIPT_EXTENSIONS.has(extname(source))) continue;
|
|
730
761
|
const text = await readFile(source, "utf8");
|
|
731
|
-
for (const reference of localReferences(source, text))
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
})
|
|
762
|
+
for (const reference of localReferences(source, text)) {
|
|
763
|
+
const lazy = reference.lazy || reference.kind === "asset";
|
|
764
|
+
try {
|
|
765
|
+
const targets = reference.kind === "module" ? [await resolveModule(source, reference.specifier, rootDir, importsMap)] : await expandAsset(resolve(dirname(source), reference.specifier), rootDir);
|
|
766
|
+
edges.push({
|
|
767
|
+
lazy,
|
|
768
|
+
targets
|
|
769
|
+
});
|
|
770
|
+
queue.push(...targets);
|
|
771
|
+
} catch (error) {
|
|
772
|
+
issues.push({
|
|
773
|
+
file: source,
|
|
774
|
+
kind: reference.kind,
|
|
775
|
+
specifier: reference.specifier,
|
|
776
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
777
|
+
lazy
|
|
778
|
+
});
|
|
779
|
+
}
|
|
741
780
|
}
|
|
742
781
|
}
|
|
782
|
+
const loadTimeFiles = /* @__PURE__ */ new Set();
|
|
783
|
+
const loadQueue = entries.map((path) => resolve(path)).filter((path) => graph.has(path));
|
|
784
|
+
while (loadQueue.length > 0) {
|
|
785
|
+
const source = loadQueue.shift();
|
|
786
|
+
if (loadTimeFiles.has(source)) continue;
|
|
787
|
+
loadTimeFiles.add(source);
|
|
788
|
+
for (const edge of graph.get(source) ?? []) {
|
|
789
|
+
if (edge.lazy) continue;
|
|
790
|
+
for (const target of edge.targets) if (!loadTimeFiles.has(target)) loadQueue.push(target);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
for (const issue of issues) if (!loadTimeFiles.has(issue.file)) issue.lazy = true;
|
|
743
794
|
return {
|
|
744
|
-
files: [...
|
|
795
|
+
files: [...graph.keys()].sort(),
|
|
796
|
+
loadTimeFiles,
|
|
745
797
|
issues
|
|
746
798
|
};
|
|
747
799
|
}
|
|
@@ -1021,24 +1073,29 @@ async function analyzePackage(pkg) {
|
|
|
1021
1073
|
line: 1,
|
|
1022
1074
|
detail: "No ExtensionAPI use was statically proven across the local module closure; conversion fails closed instead of claiming compatibility."
|
|
1023
1075
|
});
|
|
1024
|
-
for (const issue of extensionClosure.issues)
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1076
|
+
for (const issue of extensionClosure.issues) {
|
|
1077
|
+
const lazyIssue = issue.lazy || issue.kind === "asset";
|
|
1078
|
+
findings.push({
|
|
1079
|
+
capability: `${issue.kind}(${issue.specifier})`,
|
|
1080
|
+
level: lazyIssue ? "partial" : "fatal",
|
|
1081
|
+
file: relative(pkg.rootDir, issue.file).replaceAll("\\", "/"),
|
|
1082
|
+
line: 1,
|
|
1083
|
+
detail: lazyIssue ? `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).` : `The local extension closure is incomplete: ${issue.detail}`
|
|
1084
|
+
});
|
|
1085
|
+
}
|
|
1031
1086
|
const declaredDependencies = dependencyNames(pkg.packageJson);
|
|
1032
1087
|
for (const file of extensionClosure.files.filter((candidate) => SCRIPT_EXTENSIONS.has(extname(candidate)))) {
|
|
1033
1088
|
const text = await readFile(file, "utf8");
|
|
1034
|
-
|
|
1035
|
-
|
|
1089
|
+
const lazyFile = !extensionClosure.loadTimeFiles.has(file);
|
|
1090
|
+
for (const use of runtimeExternalPackages(file, text)) {
|
|
1091
|
+
if (PI_HOST_PACKAGES.has(use.name) || declaredDependencies.has(use.name)) continue;
|
|
1092
|
+
const lazyUse = use.lazy || lazyFile;
|
|
1036
1093
|
findings.push({
|
|
1037
|
-
capability: `undeclared-runtime-dependency(${
|
|
1038
|
-
level: "fatal",
|
|
1094
|
+
capability: lazyUse ? `optional-lazy-dependency(${use.name})` : `undeclared-runtime-dependency(${use.name})`,
|
|
1095
|
+
level: lazyUse ? "partial" : "fatal",
|
|
1039
1096
|
file: relative(pkg.rootDir, file).replaceAll("\\", "/"),
|
|
1040
1097
|
line: 1,
|
|
1041
|
-
detail: `The extension imports ${JSON.stringify(
|
|
1098
|
+
detail: lazyUse ? `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).` : `The extension imports ${JSON.stringify(use.name)} at load time, but the Pi package does not declare it as a dependency.`
|
|
1042
1099
|
});
|
|
1043
1100
|
}
|
|
1044
1101
|
}
|
|
@@ -1129,11 +1186,12 @@ async function copyExtensions(pkg, outDir) {
|
|
|
1129
1186
|
const copied = [];
|
|
1130
1187
|
const runtimePackages = /* @__PURE__ */ new Set();
|
|
1131
1188
|
const closure = await collectLocalClosure(pkg.rootDir, pkg.resources.extensions);
|
|
1132
|
-
|
|
1189
|
+
for (const issue of closure.issues) console.warn(`pi2dsh: unresolved ${issue.kind} reference ${JSON.stringify(issue.specifier)} from ${relative(pkg.rootDir, issue.file)} (${issue.lazy ? "lazy path — fails at feature use, as under Pi" : "load-time path"})`);
|
|
1133
1190
|
for (const source of closure.files) {
|
|
1134
1191
|
if (SCRIPT_EXTENSIONS.has(extname(source))) {
|
|
1135
1192
|
const text = await readFile(source, "utf8");
|
|
1136
|
-
|
|
1193
|
+
const lazyFile = !closure.loadTimeFiles.has(source);
|
|
1194
|
+
for (const use of runtimeExternalPackages(source, text)) if (!use.lazy && !lazyFile || use.name in stringRecord$1(pkg.packageJson.dependencies)) runtimePackages.add(use.name);
|
|
1137
1195
|
}
|
|
1138
1196
|
const targetRelative = `vendor/${relative(pkg.rootDir, source).replaceAll("\\", "/")}`;
|
|
1139
1197
|
const target = join(outDir, targetRelative);
|
|
@@ -1141,14 +1199,16 @@ async function copyExtensions(pkg, outDir) {
|
|
|
1141
1199
|
await cp(source, target, { dereference: false });
|
|
1142
1200
|
if (pkg.resources.extensions.map((entry) => resolve(entry)).includes(source)) copied.push(targetRelative);
|
|
1143
1201
|
}
|
|
1202
|
+
const skillScriptPackages = /* @__PURE__ */ new Set();
|
|
1144
1203
|
for (const source of pkg.resources.skills) {
|
|
1145
1204
|
if (!SCRIPT_EXTENSIONS.has(extname(source))) continue;
|
|
1146
1205
|
const text = await readFile(source, "utf8");
|
|
1147
|
-
for (const
|
|
1206
|
+
for (const use of runtimeExternalPackages(source, text)) skillScriptPackages.add(use.name);
|
|
1148
1207
|
}
|
|
1149
1208
|
return {
|
|
1150
1209
|
entries: copied,
|
|
1151
|
-
runtimePackages
|
|
1210
|
+
runtimePackages,
|
|
1211
|
+
skillScriptPackages
|
|
1152
1212
|
};
|
|
1153
1213
|
}
|
|
1154
1214
|
async function copySkills(pkg, outDir) {
|
|
@@ -1230,7 +1290,9 @@ function generatedPackageJson(pkg, generatedName, runtimeSpec, runtimePackages,
|
|
|
1230
1290
|
jiti: "^2.7.0",
|
|
1231
1291
|
"get-east-asian-width": "^1.6.0",
|
|
1232
1292
|
marked: "^16.4.1",
|
|
1233
|
-
typebox: "^1.0.4"
|
|
1293
|
+
typebox: "^1.0.4",
|
|
1294
|
+
"cross-spawn": "^7.0.6",
|
|
1295
|
+
diff: "^9.0.0"
|
|
1234
1296
|
} : {},
|
|
1235
1297
|
...hasSkills ? { "@deepseek-ai/dsh-skill-filesystem": "^0.1.0-rc.6" } : {},
|
|
1236
1298
|
...runtimeSpec !== void 0 ? { pi2dsh: runtimeSpec } : {}
|
|
@@ -1342,6 +1404,8 @@ async function generateBundle(pkg, options) {
|
|
|
1342
1404
|
};
|
|
1343
1405
|
const runtimeSpec = options.runtimeSpec;
|
|
1344
1406
|
if (runtimeSpec === void 0) await copyEmbeddedRuntime(outDir);
|
|
1407
|
+
const optionalSkillDeps = [...extensionSnapshot.skillScriptPackages].filter((name) => !SHIMMED_PI_HOST_PACKAGES.has(name) && !(name in stringRecord$1(pkg.packageJson.dependencies)));
|
|
1408
|
+
if (optionalSkillDeps.length > 0) console.warn(`pi2dsh: skill helper scripts reference ${optionalSkillDeps.join(", ")}; install them only if you use those skills`);
|
|
1345
1409
|
await Promise.all([
|
|
1346
1410
|
writeFile(join(outDir, "package.json"), `${JSON.stringify(generatedPackageJson(pkg, packageName, runtimeSpec, extensionSnapshot.runtimePackages, skillDirs.length > 0), null, 2)}\n`),
|
|
1347
1411
|
writeFile(join(outDir, "pi2dsh.manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`),
|
|
@@ -1532,4 +1596,4 @@ function renderMcpPatch(result) {
|
|
|
1532
1596
|
//#endregion
|
|
1533
1597
|
export { ruleForHostImport as _, analyzePackage as a, EVENT_RULES as c, PI_CODING_AGENT_PACKAGES as d, PI_TUI_PACKAGES as f, ruleForEvent as g, ruleForContextProperty as h, generateBundle as i, HOST_IMPORT_RULES as l, ruleForApi as m, convertPiMcpConfig as n, API_RULES as o, UI_CONTEXT_RULES as p, renderMcpPatch as r, CONTEXT_RULES as s, collectPiMcpServers as t, PI_AI_PACKAGES as u, ruleForUiContextProperty as v };
|
|
1534
1598
|
|
|
1535
|
-
//# sourceMappingURL=mcp-config-
|
|
1599
|
+
//# sourceMappingURL=mcp-config-gqg7GJEE.mjs.map
|