pi2dsh 0.6.0 → 0.6.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 +5 -0
- package/README.zh.md +4 -0
- package/dist/host.mjs +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -1
- package/dist/{runtime-xNd10ACP.mjs → runtime-CPvg87et.mjs} +17 -2
- package/dist/{runtime-xNd10ACP.mjs.map → runtime-CPvg87et.mjs.map} +1 -1
- package/dist/runtime.d.mts +8 -1
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,6 +17,11 @@ instance. Remove with `dsh plugin remove <pkg>`; upgrade the engine with
|
|
|
17
17
|
`dsh plugin add pi2dsh@latest` (your plugins are untouched), upgrade a
|
|
18
18
|
plugin with `dsh plugin add <pkg>@latest` (the engine is untouched).
|
|
19
19
|
|
|
20
|
+
If an add stops with `ERR_PNPM_IGNORED_BUILDS` (pnpm blocks dependency
|
|
21
|
+
build scripts by default), set the listed packages to `true` under
|
|
22
|
+
`allowBuilds` in the profile's `pnpm-workspace.yaml` (or run
|
|
23
|
+
`pnpm approve-builds` there), then re-run the add.
|
|
24
|
+
|
|
20
25
|
## Architecture
|
|
21
26
|
|
|
22
27
|
The bridge implements Pi's public extension surface **once**, mapping every call onto DSH's native services. A package that sticks to Pi's public API runs verbatim; capabilities with no safe mapping fail explicitly instead of faking success.
|
package/README.zh.md
CHANGED
|
@@ -16,6 +16,10 @@ dsh plugin --profile headless add pi-vision-tool
|
|
|
16
16
|
`dsh plugin add pi2dsh@latest`(插件不动),升级插件
|
|
17
17
|
`dsh plugin add <包>@latest`(引擎不动)。
|
|
18
18
|
|
|
19
|
+
如果 add 报 `ERR_PNPM_IGNORED_BUILDS`(pnpm 默认拦依赖的构建脚本):
|
|
20
|
+
在 profile 的 `pnpm-workspace.yaml` 里把列出的包在 `allowBuilds` 下设为
|
|
21
|
+
`true`(或在该目录跑 `pnpm approve-builds`),然后重跑 add。
|
|
22
|
+
|
|
19
23
|
## 架构
|
|
20
24
|
|
|
21
25
|
桥只实现**一次** Pi 的公共扩展面,把每个调用映射到 DSH 原生服务。只用公共 API 的包原样运行;无法安全映射的能力显式失败,绝不伪装成功。
|
package/dist/host.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { t as applyPiPackage } from "./runtime-
|
|
2
|
+
import { t as applyPiPackage } from "./runtime-CPvg87et.mjs";
|
|
3
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";
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/engine.ts","../src/analyzer.ts","../src/compatibility.ts","../src/generator.ts","../src/mcp-config.ts","../src/source.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/engine.ts","../src/analyzer.ts","../src/compatibility.ts","../src/generator.ts","../src/mcp-config.ts","../src/source.ts"],"mappings":";;;;;UA6BiB;;EAEf;;EAEA;;;iBAIc,gBAAgB;UAUtB;EACR;EACA;;;;;;;;iBAgBoB,0BACpB,qBACA;EAAW;EAAoB,QAAQ;IACtC,QAAQ;;cA4CE;cACA;iBAES,MAAM,KAAK,SAAS,SAAQ,eAAoB;;;iBC6ThD,eAAe,KAAK,oBAAoB,QAAQ;;;UC9a5D;EACR,OAAO;EACP;;cAKW;cAKA;cAKA;cAWA,mBAAmB,SAAS,eAAe,SAAS,eAAe;cAmNnE,eAAe,SAAS,eAAe;cA4BvC,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;;;iBC3LtC,eACpB,KAAK,mBACL,SAAS,kBACR;EAAU;EAAgB,QAAQ;EAAqB;;;;KC5UrD,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,4 +1,5 @@
|
|
|
1
1
|
|
|
2
|
+
import { n as ensureModelsJsonRoutes } from "./runtime-CPvg87et.mjs";
|
|
2
3
|
import { t as resolvePiPackage } from "./source-0sA5z08z.mjs";
|
|
3
4
|
import { applyPiHost, generateHostBundle, manifestForInstalled } from "./host.mjs";
|
|
4
5
|
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-vU1LZ7fC.mjs";
|
|
@@ -89,6 +90,7 @@ async function apply(ctx, config = {}) {
|
|
|
89
90
|
warn
|
|
90
91
|
});
|
|
91
92
|
if (packages.length === 0) {
|
|
93
|
+
await ensureModelsJsonRoutes(ctx);
|
|
92
94
|
info("[pi2dsh engine] no Pi packages installed in this profile yet — add one with: dsh plugin --profile <p> add <pi-package>");
|
|
93
95
|
return;
|
|
94
96
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/engine.ts"],"sourcesContent":["// The pi2dsh engine: ONE installed copy of the bridge that mounts every Pi\n// package the user has added to their DSH profile.\n//\n// dsh plugin --profile p add pi2dsh ← the engine (this plugin)\n// dsh plugin --profile p add @kassing/pi-vision ← plain npm dependency\n// dsh plugin --profile p add pi-vision-tool ← plain npm dependency\n//\n// DSH's plugin manager records only packages that declare `dsh.bundle` as\n// profile layers; everything else stays an ordinary dependency (\"a plain\n// library is fine\"). The engine reads the profile manifest's DIRECT\n// dependencies — every entry there was an explicit `dsh plugin add` — and\n// mounts each package that identifies as a Pi package, all through one\n// bridge instance: one model ledger, one command space, one upgrade unit.\n//\n// Discovery is manifest-driven, never a node_modules scan (the lesson from\n// Prettier 3 dropping directory-based plugin discovery): the dependency list\n// is the user's explicit intent, and package identification uses the same\n// Pi markers `resolvePiPackage` has always used (the `pi` manifest field,\n// with Pi's directory conventions as fallback).\n\nimport { readFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { applyPiHost } from './host.js'\nimport { resolvePiPackage } from './source.js'\n\nexport interface EngineConfig {\n /** Mount exactly these packages (skips discovery). */\n packages?: string[]\n /** Never mount these packages even when discovered. */\n exclude?: string[]\n}\n\n/** Locate the DSH profile root: the nearest ancestor holding cordis.yml. */\nexport function findProfileRoot(start: string): string | undefined {\n let dir = start\n for (;;) {\n if (existsSync(join(dir, 'cordis.yml')) && existsSync(join(dir, 'package.json'))) return dir\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\ninterface DiscoveredPackage {\n name: string\n dir: string\n}\n\nfunction resolveDependencyDir(profileRoot: string, name: string): string | undefined {\n // Direct dependencies of the profile live under its node_modules by name\n // (pnpm links them there); resolving by path needs no exports gymnastics.\n const dir = join(profileRoot, 'node_modules', name)\n return existsSync(join(dir, 'package.json')) ? dir : undefined\n}\n\n/**\n * The profile's direct dependencies that identify as Pi packages: not the\n * engine itself, not a `dsh.bundle` (those are DSH plugins, not Pi\n * packages), carrying either Pi's `pi` manifest field or extension sources\n * under Pi's directory conventions.\n */\nexport async function discoverProfilePiPackages(\n profileRoot: string,\n options: { exclude?: string[], warn?: (message: string) => void } = {},\n): Promise<DiscoveredPackage[]> {\n const warn = options.warn ?? (() => {})\n const excluded = new Set(options.exclude ?? [])\n const manifestText = await readFile(join(profileRoot, 'package.json'), 'utf8')\n const manifest = JSON.parse(manifestText) as { dependencies?: Record<string, string> }\n const discovered: DiscoveredPackage[] = []\n for (const name of Object.keys(manifest.dependencies ?? {})) {\n if (name === 'pi2dsh' || excluded.has(name)) continue\n const dir = resolveDependencyDir(profileRoot, name)\n if (dir === undefined) {\n warn(`[pi2dsh engine] dependency ${JSON.stringify(name)} is not installed under the profile; skipping`)\n continue\n }\n let packageJson: Record<string, unknown>\n try {\n packageJson = JSON.parse(await readFile(join(dir, 'package.json'), 'utf8')) as Record<string, unknown>\n } catch (error) {\n warn(`[pi2dsh engine] cannot read ${name}/package.json (${error instanceof Error ? error.message : String(error)}); skipping`)\n continue\n }\n // A dsh.bundle-declaring package is a DSH plugin layer, never a Pi package.\n if ((packageJson.dsh as { bundle?: unknown } | undefined)?.bundle !== undefined) continue\n if (packageJson.pi !== undefined && typeof packageJson.pi === 'object') {\n discovered.push({ name, dir })\n continue\n }\n // No `pi` field: fall back to Pi's directory conventions via the same\n // resolver every other mount path uses (a package with zero extension\n // sources is a plain library and stays unmounted).\n try {\n const pkg = await resolvePiPackage(dir)\n try {\n if (pkg.resources.extensions.length > 0) discovered.push({ name, dir })\n } finally {\n await pkg.dispose()\n }\n } catch {\n // Not resolvable as a Pi package — a plain library.\n }\n }\n return discovered\n}\n\n/** Cordis plugin surface: `dsh plugin add pi2dsh` mounts this. */\nexport const name = 'pi2dsh'\nexport const inject = ['tools', 'systemPrompt', 'commands', 'skills']\n\nexport async function apply(ctx: Context, config: EngineConfig = {}): Promise<void> {\n const log = (ctx as unknown as { logger?: { info?(m: string): void, warn?(m: string): void } }).logger\n const warn = log?.warn?.bind(log) ?? console.warn\n const info = log?.info?.bind(log) ?? console.log\n\n // The loader resolves plugins against the profile's baseUrl; that IS the\n // profile root. The ancestor walk from the installed engine is the\n // fallback for compositions without a loader (tests, hand-built hosts).\n const baseUrl = (ctx as unknown as { baseUrl?: string }).baseUrl\n const profileRoot = (baseUrl !== undefined ? findProfileRoot(fileURLToPath(new URL('.', baseUrl))) : undefined)\n ?? findProfileRoot(dirname(fileURLToPath(import.meta.url)))\n if (profileRoot === undefined) {\n throw new Error('pi2dsh engine: no DSH profile root (cordis.yml + package.json) above the installed engine — is pi2dsh installed via `dsh plugin add pi2dsh`?')\n }\n\n const packages = Array.isArray(config.packages) && config.packages.length > 0\n ? config.packages.map(name => ({ name }))\n : await discoverProfilePiPackages(profileRoot, {\n ...(Array.isArray(config.exclude) ? { exclude: config.exclude } : {}),\n warn,\n })\n if (packages.length === 0) {\n info('[pi2dsh engine] no Pi packages installed in this profile yet — add one with: dsh plugin --profile <p> add <pi-package>')\n return\n }\n info(`[pi2dsh engine] mounting ${packages.length} Pi package(s): ${packages.map(pkg => pkg.name).join(', ')}`)\n await applyPiHost(\n ctx,\n { packages: packages.map(pkg => ({ name: pkg.name })) },\n join(profileRoot, 'package.json'),\n )\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/engine.ts"],"sourcesContent":["// The pi2dsh engine: ONE installed copy of the bridge that mounts every Pi\n// package the user has added to their DSH profile.\n//\n// dsh plugin --profile p add pi2dsh ← the engine (this plugin)\n// dsh plugin --profile p add @kassing/pi-vision ← plain npm dependency\n// dsh plugin --profile p add pi-vision-tool ← plain npm dependency\n//\n// DSH's plugin manager records only packages that declare `dsh.bundle` as\n// profile layers; everything else stays an ordinary dependency (\"a plain\n// library is fine\"). The engine reads the profile manifest's DIRECT\n// dependencies — every entry there was an explicit `dsh plugin add` — and\n// mounts each package that identifies as a Pi package, all through one\n// bridge instance: one model ledger, one command space, one upgrade unit.\n//\n// Discovery is manifest-driven, never a node_modules scan (the lesson from\n// Prettier 3 dropping directory-based plugin discovery): the dependency list\n// is the user's explicit intent, and package identification uses the same\n// Pi markers `resolvePiPackage` has always used (the `pi` manifest field,\n// with Pi's directory conventions as fallback).\n\nimport { readFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { applyPiHost } from './host.js'\nimport { ensureModelsJsonRoutes } from './runtime.js'\nimport { resolvePiPackage } from './source.js'\n\nexport interface EngineConfig {\n /** Mount exactly these packages (skips discovery). */\n packages?: string[]\n /** Never mount these packages even when discovered. */\n exclude?: string[]\n}\n\n/** Locate the DSH profile root: the nearest ancestor holding cordis.yml. */\nexport function findProfileRoot(start: string): string | undefined {\n let dir = start\n for (;;) {\n if (existsSync(join(dir, 'cordis.yml')) && existsSync(join(dir, 'package.json'))) return dir\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\ninterface DiscoveredPackage {\n name: string\n dir: string\n}\n\nfunction resolveDependencyDir(profileRoot: string, name: string): string | undefined {\n // Direct dependencies of the profile live under its node_modules by name\n // (pnpm links them there); resolving by path needs no exports gymnastics.\n const dir = join(profileRoot, 'node_modules', name)\n return existsSync(join(dir, 'package.json')) ? dir : undefined\n}\n\n/**\n * The profile's direct dependencies that identify as Pi packages: not the\n * engine itself, not a `dsh.bundle` (those are DSH plugins, not Pi\n * packages), carrying either Pi's `pi` manifest field or extension sources\n * under Pi's directory conventions.\n */\nexport async function discoverProfilePiPackages(\n profileRoot: string,\n options: { exclude?: string[], warn?: (message: string) => void } = {},\n): Promise<DiscoveredPackage[]> {\n const warn = options.warn ?? (() => {})\n const excluded = new Set(options.exclude ?? [])\n const manifestText = await readFile(join(profileRoot, 'package.json'), 'utf8')\n const manifest = JSON.parse(manifestText) as { dependencies?: Record<string, string> }\n const discovered: DiscoveredPackage[] = []\n for (const name of Object.keys(manifest.dependencies ?? {})) {\n if (name === 'pi2dsh' || excluded.has(name)) continue\n const dir = resolveDependencyDir(profileRoot, name)\n if (dir === undefined) {\n warn(`[pi2dsh engine] dependency ${JSON.stringify(name)} is not installed under the profile; skipping`)\n continue\n }\n let packageJson: Record<string, unknown>\n try {\n packageJson = JSON.parse(await readFile(join(dir, 'package.json'), 'utf8')) as Record<string, unknown>\n } catch (error) {\n warn(`[pi2dsh engine] cannot read ${name}/package.json (${error instanceof Error ? error.message : String(error)}); skipping`)\n continue\n }\n // A dsh.bundle-declaring package is a DSH plugin layer, never a Pi package.\n if ((packageJson.dsh as { bundle?: unknown } | undefined)?.bundle !== undefined) continue\n if (packageJson.pi !== undefined && typeof packageJson.pi === 'object') {\n discovered.push({ name, dir })\n continue\n }\n // No `pi` field: fall back to Pi's directory conventions via the same\n // resolver every other mount path uses (a package with zero extension\n // sources is a plain library and stays unmounted).\n try {\n const pkg = await resolvePiPackage(dir)\n try {\n if (pkg.resources.extensions.length > 0) discovered.push({ name, dir })\n } finally {\n await pkg.dispose()\n }\n } catch {\n // Not resolvable as a Pi package — a plain library.\n }\n }\n return discovered\n}\n\n/** Cordis plugin surface: `dsh plugin add pi2dsh` mounts this. */\nexport const name = 'pi2dsh'\nexport const inject = ['tools', 'systemPrompt', 'commands', 'skills']\n\nexport async function apply(ctx: Context, config: EngineConfig = {}): Promise<void> {\n const log = (ctx as unknown as { logger?: { info?(m: string): void, warn?(m: string): void } }).logger\n const warn = log?.warn?.bind(log) ?? console.warn\n const info = log?.info?.bind(log) ?? console.log\n\n // The loader resolves plugins against the profile's baseUrl; that IS the\n // profile root. The ancestor walk from the installed engine is the\n // fallback for compositions without a loader (tests, hand-built hosts).\n const baseUrl = (ctx as unknown as { baseUrl?: string }).baseUrl\n const profileRoot = (baseUrl !== undefined ? findProfileRoot(fileURLToPath(new URL('.', baseUrl))) : undefined)\n ?? findProfileRoot(dirname(fileURLToPath(import.meta.url)))\n if (profileRoot === undefined) {\n throw new Error('pi2dsh engine: no DSH profile root (cordis.yml + package.json) above the installed engine — is pi2dsh installed via `dsh plugin add pi2dsh`?')\n }\n\n const packages = Array.isArray(config.packages) && config.packages.length > 0\n ? config.packages.map(name => ({ name }))\n : await discoverProfilePiPackages(profileRoot, {\n ...(Array.isArray(config.exclude) ? { exclude: config.exclude } : {}),\n warn,\n })\n if (packages.length === 0) {\n // The single-directory capability (models.json providers + companion\n // routes in the DSH picker) is the bridge's own — it works with zero\n // Pi packages installed.\n await ensureModelsJsonRoutes(ctx)\n info('[pi2dsh engine] no Pi packages installed in this profile yet — add one with: dsh plugin --profile <p> add <pi-package>')\n return\n }\n info(`[pi2dsh engine] mounting ${packages.length} Pi package(s): ${packages.map(pkg => pkg.name).join(', ')}`)\n await applyPiHost(\n ctx,\n { packages: packages.map(pkg => ({ name: pkg.name })) },\n join(profileRoot, 'package.json'),\n )\n}\n"],"mappings":"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"}
|
|
@@ -3186,6 +3186,21 @@ function sharedHostStateOf(ctx) {
|
|
|
3186
3186
|
}
|
|
3187
3187
|
return shared;
|
|
3188
3188
|
}
|
|
3189
|
+
/**
|
|
3190
|
+
* Load models.json routes for a host with NO mounted Pi package yet — the
|
|
3191
|
+
* single-directory capability (custom providers + image-admission
|
|
3192
|
+
* companions in the DSH picker) is the bridge's own, not any plugin's.
|
|
3193
|
+
* A later package mount adopts the same shared snapshot.
|
|
3194
|
+
*/
|
|
3195
|
+
async function ensureModelsJsonRoutes(ctx) {
|
|
3196
|
+
const shared = sharedHostStateOf(ctx);
|
|
3197
|
+
await reloadModelsJson(ctx, {
|
|
3198
|
+
shared,
|
|
3199
|
+
modelsJsonProviders: shared.modelsJsonProviders,
|
|
3200
|
+
companionRoutes: shared.companionRoutes,
|
|
3201
|
+
providerRouteDisposers: shared.providerRouteDisposers
|
|
3202
|
+
});
|
|
3203
|
+
}
|
|
3189
3204
|
async function reloadModelsJson(ctx, state, force = false) {
|
|
3190
3205
|
if (!force && state.shared.modelsJson !== void 0) {
|
|
3191
3206
|
state.modelsJson = state.shared.modelsJson;
|
|
@@ -3956,6 +3971,6 @@ const runtimeInternals = {
|
|
|
3956
3971
|
textBlocks
|
|
3957
3972
|
};
|
|
3958
3973
|
//#endregion
|
|
3959
|
-
export {
|
|
3974
|
+
export { runtimeInternals as i, ensureModelsJsonRoutes as n, normalizeToolSchema as r, applyPiPackage as t };
|
|
3960
3975
|
|
|
3961
|
-
//# sourceMappingURL=runtime-
|
|
3976
|
+
//# sourceMappingURL=runtime-CPvg87et.mjs.map
|