pi2dsh 0.13.3 → 0.14.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 +2 -0
- package/README.zh.md +2 -0
- package/dist/{analyzer-DBtUYKI1.mjs → analyzer-DPZ8LzSt.mjs} +2 -2
- package/dist/{analyzer-DBtUYKI1.mjs.map → analyzer-DPZ8LzSt.mjs.map} +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/compat/pi-ai.d.mts +1 -1
- package/dist/compat/pi-ai.mjs +1 -1
- package/dist/compat/pi-coding-agent.mjs +1 -1
- package/dist/{compatibility-Bz6ZXA7F.mjs → compatibility-CP2tpyhg.mjs} +13 -1
- package/dist/compatibility-CP2tpyhg.mjs.map +1 -0
- package/dist/{credentials-oauth-CAohSLcB.mjs → credentials-oauth-Didpkkjx.mjs} +3 -3
- package/dist/{credentials-oauth-CAohSLcB.mjs.map → credentials-oauth-Didpkkjx.mjs.map} +1 -1
- package/dist/credentials-oauth.mjs +1 -1
- package/dist/host.d.mts +3 -1
- package/dist/host.d.mts.map +1 -1
- package/dist/host.mjs +4 -3
- package/dist/host.mjs.map +1 -1
- package/dist/index.d.mts +34 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +117 -35
- package/dist/index.mjs.map +1 -1
- package/dist/{pi-ai-Dh7HUxbt.mjs → pi-ai-DpqiLdPA.mjs} +7 -2
- package/dist/{pi-ai-Dh7HUxbt.mjs.map → pi-ai-DpqiLdPA.mjs.map} +1 -1
- package/dist/{pi-ai-CfokFhIL.d.mts → pi-ai-ZU5MelXy.d.mts} +7 -2
- package/dist/{pi-ai-CfokFhIL.d.mts.map → pi-ai-ZU5MelXy.d.mts.map} +1 -1
- package/dist/{pi-coding-agent-Cvez0jkF.mjs → pi-coding-agent-DK8hbJP5.mjs} +0 -0
- package/dist/{pi-coding-agent-Cvez0jkF.mjs.map → pi-coding-agent-DK8hbJP5.mjs.map} +1 -1
- package/dist/{runtime-Dd2KhoX-.mjs → runtime-BiD3SeGf.mjs} +86 -13
- package/dist/runtime-BiD3SeGf.mjs.map +1 -0
- package/dist/runtime.d.mts +19 -1
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -1
- package/package.json +8 -6
- package/dist/compatibility-Bz6ZXA7F.mjs.map +0 -1
- package/dist/runtime-Dd2KhoX-.mjs.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
import { En as PiCapabilityError, F as generateBranchSummary, Tn as CapabilityLedger, b as Theme, d as ExtensionRunner, w as __runWithSubagentSessionFactory } from "./pi-coding-agent-
|
|
2
|
+
import { En as PiCapabilityError, F as generateBranchSummary, Tn as CapabilityLedger, b as Theme, d as ExtensionRunner, w as __runWithSubagentSessionFactory } from "./pi-coding-agent-DK8hbJP5.mjs";
|
|
3
3
|
import { t as getAgentDir } from "./pi-config-shim-CZ1wFzqM.mjs";
|
|
4
|
-
import { $ as isContextOverflow, Q as AssistantMessageEventStream, S as getSupportedThinkingLevels, c as builtinProviders, o as __runWithPiAiRuntime, r as __createPiAiRuntimeRegistry } from "./pi-ai-
|
|
4
|
+
import { $ as isContextOverflow, Q as AssistantMessageEventStream, S as getSupportedThinkingLevels, c as builtinProviders, o as __runWithPiAiRuntime, r as __createPiAiRuntimeRegistry } from "./pi-ai-DpqiLdPA.mjs";
|
|
5
5
|
import { W as getKeybindings } from "./pi-tui-DruSeKmd.mjs";
|
|
6
|
-
import { a as FileCredentialStore, c as providerSupportsOAuth, i as oauthCredentialRef, l as resolvePiProviderAuth, o as joinSignals, s as loginPiProvider, u as storedOAuthCredential } from "./credentials-oauth-
|
|
6
|
+
import { a as FileCredentialStore, c as providerSupportsOAuth, i as oauthCredentialRef, l as resolvePiProviderAuth, o as joinSignals, s as loginPiProvider, u as storedOAuthCredential } from "./credentials-oauth-Didpkkjx.mjs";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import { access, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
9
9
|
import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
@@ -358,6 +358,18 @@ var PiSessionBridge = class {
|
|
|
358
358
|
//#endregion
|
|
359
359
|
//#region src/subagent-bridge.ts
|
|
360
360
|
let subagentSerial = 0;
|
|
361
|
+
/**
|
|
362
|
+
* Cross-scope subscription base. Session events dispatch under the OWNING
|
|
363
|
+
* session's scope; a package instance mounted per Agent registers listeners
|
|
364
|
+
* inside its own Agent's scope and would never see a child session's events.
|
|
365
|
+
* The bridge's callbacks filter by exact session/agent identity, so they
|
|
366
|
+
* subscribe unscoped at the root context — the same posture the old
|
|
367
|
+
* host-level mount had.
|
|
368
|
+
*/
|
|
369
|
+
function unscopedEventContext(cordis) {
|
|
370
|
+
const host = cordis;
|
|
371
|
+
return host.root ?? host;
|
|
372
|
+
}
|
|
361
373
|
/** Flatten a Pi message's content to text for transcript seeding. */
|
|
362
374
|
function piMessageText(message) {
|
|
363
375
|
const content = message.content;
|
|
@@ -397,7 +409,7 @@ var PiBridgedAgentSession = class {
|
|
|
397
409
|
this.#session = handle.agent.session ?? {};
|
|
398
410
|
this.#tools = tools;
|
|
399
411
|
this.#activeToolNames = tools.map((tool) => tool?.name).filter((name) => typeof name === "string");
|
|
400
|
-
const cordis = host.cordis;
|
|
412
|
+
const cordis = unscopedEventContext(host.cordis);
|
|
401
413
|
const offEvents = cordis.on("session/event", (session, event) => {
|
|
402
414
|
if (session !== this.#session) return;
|
|
403
415
|
this.#project(event);
|
|
@@ -596,7 +608,7 @@ var PiBridgedAgentSession = class {
|
|
|
596
608
|
type: "text",
|
|
597
609
|
text: String(text)
|
|
598
610
|
}]);
|
|
599
|
-
const cordis = this.#host.cordis;
|
|
611
|
+
const cordis = unscopedEventContext(this.#host.cordis);
|
|
600
612
|
const completed = new Promise((resolve) => {
|
|
601
613
|
const off = cordis.on("session/event", (session, event) => {
|
|
602
614
|
if (session !== this.#session) return;
|
|
@@ -4013,9 +4025,7 @@ function subscribeLifecycle(ctx, state) {
|
|
|
4013
4025
|
}
|
|
4014
4026
|
}
|
|
4015
4027
|
});
|
|
4016
|
-
|
|
4017
|
-
const ownedSession = agentSession(state.ownerAgent);
|
|
4018
|
-
if (ownedSession !== void 0 ? session !== ownedSession : isSubagentOrigin(session)) return;
|
|
4028
|
+
const projectSessionEvent = (session, event) => {
|
|
4019
4029
|
const agent = [...state.activeAgents].find((candidate) => candidate.session === session);
|
|
4020
4030
|
const eventContext = contextFor(ctx, state, agent, void 0);
|
|
4021
4031
|
const type = event.type;
|
|
@@ -4162,6 +4172,14 @@ function subscribeLifecycle(ctx, state) {
|
|
|
4162
4172
|
}, eventContext);
|
|
4163
4173
|
await dispatch(state, "agent_settled", { type: "agent_settled" }, eventContext);
|
|
4164
4174
|
}).catch((error) => warn("turn end lifecycle", error));
|
|
4175
|
+
};
|
|
4176
|
+
state.projectSessionEvent = projectSessionEvent;
|
|
4177
|
+
cordis.on("session/event", (session, event) => {
|
|
4178
|
+
if (state.hostAnchor) return;
|
|
4179
|
+
const ownedSession = agentSession(state.ownerAgent);
|
|
4180
|
+
if (ownedSession !== void 0 ? session !== ownedSession : isSubagentOrigin(session)) return;
|
|
4181
|
+
if (ownedSession !== void 0 && state.sessionEventsLive !== true) return;
|
|
4182
|
+
projectSessionEvent(session, event);
|
|
4165
4183
|
});
|
|
4166
4184
|
cordis.on("agent/request", async (payload, next) => {
|
|
4167
4185
|
const config = await next();
|
|
@@ -4201,9 +4219,35 @@ function subscribeLifecycle(ctx, state) {
|
|
|
4201
4219
|
}
|
|
4202
4220
|
async function flushPendingSessionStarts(ctx, state) {
|
|
4203
4221
|
state.extensionsReady = true;
|
|
4222
|
+
if (state.ownerAgent !== void 0 && !state.pendingSessionStarts.has(state.ownerAgent)) {
|
|
4223
|
+
const owned = state.ownerAgent;
|
|
4224
|
+
if (!state.activeAgents.has(owned)) {
|
|
4225
|
+
state.activeAgents.add(owned);
|
|
4226
|
+
trackRuntimeSession(state, owned);
|
|
4227
|
+
const session = agentSession(owned);
|
|
4228
|
+
if (session !== void 0) state.bridge.load(session.id);
|
|
4229
|
+
}
|
|
4230
|
+
state.pendingSessionStarts.set(owned, "startup");
|
|
4231
|
+
}
|
|
4204
4232
|
const pending = [...state.pendingSessionStarts];
|
|
4205
4233
|
state.pendingSessionStarts.clear();
|
|
4206
4234
|
for (const [agent, reason] of pending) await startPiSession(ctx, state, agent, reason, void 0);
|
|
4235
|
+
if (state.ownerAgent !== void 0 && state.projectSessionEvent !== void 0) {
|
|
4236
|
+
const session = agentSession(state.ownerAgent);
|
|
4237
|
+
if (session !== void 0) {
|
|
4238
|
+
const events = session.events ?? [];
|
|
4239
|
+
let from = -1;
|
|
4240
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
4241
|
+
if (events[index].type === "turn/end") break;
|
|
4242
|
+
if (events[index].type === "turn/start") {
|
|
4243
|
+
from = index;
|
|
4244
|
+
break;
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4247
|
+
if (from >= 0) for (let index = from; index < events.length; index += 1) state.projectSessionEvent(session, events[index]);
|
|
4248
|
+
}
|
|
4249
|
+
state.sessionEventsLive = true;
|
|
4250
|
+
}
|
|
4207
4251
|
}
|
|
4208
4252
|
/**
|
|
4209
4253
|
* Start freshly reloaded extension handlers in every live Pi host session.
|
|
@@ -4354,7 +4398,7 @@ function subscribeInterceptors(ctx, state) {
|
|
|
4354
4398
|
};
|
|
4355
4399
|
});
|
|
4356
4400
|
const systemPrompt = optionalService(ctx, "systemPrompt");
|
|
4357
|
-
if (systemPrompt !== void 0) ctx.effect(() => systemPrompt.section({
|
|
4401
|
+
if (systemPrompt !== void 0 && !state.hostAnchor) ctx.effect(() => systemPrompt.section({
|
|
4358
4402
|
name: `pi2dsh:tool-guidance:${state.packageName ?? "pi"}`,
|
|
4359
4403
|
order: 150,
|
|
4360
4404
|
text: () => piToolPromptContribution(ctx, state)
|
|
@@ -4566,6 +4610,16 @@ function oauthStoreOf(state) {
|
|
|
4566
4610
|
}
|
|
4567
4611
|
const COMPANION_ROUTE_PREFIX = "pi2dsh-companion/";
|
|
4568
4612
|
const SHARED_HOST_STATE = /* @__PURE__ */ new WeakMap();
|
|
4613
|
+
/**
|
|
4614
|
+
* The engine's own built-in OAuth directory entries, by object identity.
|
|
4615
|
+
* They are login placeholders (no models, no transport), preloaded so
|
|
4616
|
+
* `/login <provider>` works before any package is installed — and a package
|
|
4617
|
+
* registering the SAME provider id owns the richer definition (transport,
|
|
4618
|
+
* catalog, its own flow) and must supersede the placeholder in the shared
|
|
4619
|
+
* ledger. Two PACKAGES colliding on one id still keep first-wins, matching
|
|
4620
|
+
* the route-ownership rule.
|
|
4621
|
+
*/
|
|
4622
|
+
const BUILTIN_PROVIDER_SEEDS = /* @__PURE__ */ new WeakSet();
|
|
4569
4623
|
function sharedHostStateOf(ctx) {
|
|
4570
4624
|
const key = ctx.root ?? ctx;
|
|
4571
4625
|
let shared = SHARED_HOST_STATE.get(key);
|
|
@@ -5011,6 +5065,10 @@ function registerTool(ctx, state, tool) {
|
|
|
5011
5065
|
const normalized = normalizeToolSchema(tool.parameters);
|
|
5012
5066
|
for (const warning of normalized.warnings) logger(ctx).warn(`[pi2dsh] tool ${tool.name}: ${warning}`);
|
|
5013
5067
|
state.tools.set(tool.name, tool);
|
|
5068
|
+
if (state.hostAnchor) {
|
|
5069
|
+
state.toolDisposers.set(tool.name, () => {});
|
|
5070
|
+
return;
|
|
5071
|
+
}
|
|
5014
5072
|
const definition = {
|
|
5015
5073
|
name: tool.name,
|
|
5016
5074
|
description: tool.description,
|
|
@@ -5071,6 +5129,7 @@ function currentAgent(state) {
|
|
|
5071
5129
|
}
|
|
5072
5130
|
/** Exact-Agent ownership for scoped mounts; legacy root mounts retain their old host-session rule. */
|
|
5073
5131
|
function acceptsAgent(state, agent) {
|
|
5132
|
+
if (state.hostAnchor) return false;
|
|
5074
5133
|
if (state.ownerAgent !== void 0) return agent === state.ownerAgent;
|
|
5075
5134
|
return !isSubagentOrigin(agent);
|
|
5076
5135
|
}
|
|
@@ -5316,6 +5375,7 @@ function registerCommand(ctx, state, command) {
|
|
|
5316
5375
|
return;
|
|
5317
5376
|
}
|
|
5318
5377
|
state.commands.set(command.name, command);
|
|
5378
|
+
if (state.hostAnchor) return;
|
|
5319
5379
|
const commands = ctx.get("commands");
|
|
5320
5380
|
if (commands === void 0) {
|
|
5321
5381
|
logger(ctx).warn(`[pi2dsh] command /${command.name} was not registered because this DSH composition has no ctx.commands`);
|
|
@@ -5490,7 +5550,18 @@ function createPiApi(ctx, state) {
|
|
|
5490
5550
|
const name = typeof providerOrName === "string" ? providerOrName : String(providerOrName?.id ?? providerOrName?.name ?? "unnamed");
|
|
5491
5551
|
const value = typeof providerOrName === "string" ? config ?? {} : providerOrName;
|
|
5492
5552
|
state.providers.set(name, value);
|
|
5493
|
-
|
|
5553
|
+
const sharedExisting = state.shared.providers.get(name);
|
|
5554
|
+
if (sharedExisting === void 0 || BUILTIN_PROVIDER_SEEDS.has(sharedExisting)) {
|
|
5555
|
+
state.shared.providers.set(name, value);
|
|
5556
|
+
if (sharedExisting !== void 0) {
|
|
5557
|
+
const stale = state.shared.providerRouteDisposers.get(name);
|
|
5558
|
+
if (stale !== void 0) {
|
|
5559
|
+
state.shared.providerRouteDisposers.delete(name);
|
|
5560
|
+
state.shared.providerRouteOwners.delete(name);
|
|
5561
|
+
stale();
|
|
5562
|
+
}
|
|
5563
|
+
}
|
|
5564
|
+
}
|
|
5494
5565
|
if (providerSupportsOAuth(value)) {
|
|
5495
5566
|
ensureLoginCommand(ctx, state);
|
|
5496
5567
|
logger(ctx).info(`[pi2dsh] Pi provider ${JSON.stringify(name)} supports OAuth — log in with /login ${name}`);
|
|
@@ -5782,6 +5853,7 @@ async function applyPiPackage(ctx, options) {
|
|
|
5782
5853
|
shared,
|
|
5783
5854
|
packageName: options.manifest.package.name,
|
|
5784
5855
|
ownerAgent,
|
|
5856
|
+
hostAnchor: options.hostAnchor === true,
|
|
5785
5857
|
handlers: /* @__PURE__ */ new Map(),
|
|
5786
5858
|
tools: runtimeTools,
|
|
5787
5859
|
runner: new ExtensionRunner(piToolRecords),
|
|
@@ -5848,6 +5920,7 @@ async function applyPiPackage(ctx, options) {
|
|
|
5848
5920
|
baseUrl: provider.baseUrl,
|
|
5849
5921
|
oauth: provider.auth.oauth
|
|
5850
5922
|
};
|
|
5923
|
+
BUILTIN_PROVIDER_SEEDS.add(config);
|
|
5851
5924
|
state.providers.set(provider.id, config);
|
|
5852
5925
|
if (!shared.providers.has(provider.id)) shared.providers.set(provider.id, config);
|
|
5853
5926
|
}
|
|
@@ -5857,7 +5930,7 @@ async function applyPiPackage(ctx, options) {
|
|
|
5857
5930
|
} catch (error) {
|
|
5858
5931
|
logger(ctx).warn(`[pi2dsh] could not restore the route for logged-in provider ${JSON.stringify(name)}: ${error instanceof Error ? error.message : String(error)}`);
|
|
5859
5932
|
}
|
|
5860
|
-
if (options.manifest.skillDirs.length > 0) {
|
|
5933
|
+
if (options.manifest.skillDirs.length > 0 && state.ownerAgent === void 0) {
|
|
5861
5934
|
if (ctx.get("skills") === void 0) logger(ctx).warn("[pi2dsh] migrated skills were not mounted because this DSH composition has no ctx.skills");
|
|
5862
5935
|
else {
|
|
5863
5936
|
const { apply: applyFilesystemSkills } = await import("@deepseek-ai/dsh-skill-filesystem");
|
|
@@ -6014,7 +6087,7 @@ async function applyPiPackage(ctx, options) {
|
|
|
6014
6087
|
});
|
|
6015
6088
|
const health = state.shared.capabilityLedger?.healthOf(state.packageName);
|
|
6016
6089
|
const healthSuffix = health === void 0 || health.status === "ok" ? "" : ` — ${health.status.toUpperCase()}: missing Pi capabilities ${health.gaps.join(", ")}`;
|
|
6017
|
-
logger(ctx).info(`[pi2dsh] loaded ${options.manifest.package.name}: ${state.tools.size} tools, ${state.commands.size} commands, ${options.manifest.skillDirs.length} skill roots${healthSuffix}`);
|
|
6090
|
+
logger(ctx).info(`[pi2dsh] loaded ${options.manifest.package.name}: ${state.tools.size} tools, ${state.commands.size} commands, ${options.manifest.skillDirs.length} skill roots${healthSuffix}${state.hostAnchor ? " (host anchor)" : ""}`);
|
|
6018
6091
|
}
|
|
6019
6092
|
const runtimeInternals = {
|
|
6020
6093
|
compactionReason,
|
|
@@ -6031,4 +6104,4 @@ const runtimeInternals = {
|
|
|
6031
6104
|
//#endregion
|
|
6032
6105
|
export { runtimeInternals as i, normalizeToolSchema as n, registerVisionCompanions as r, applyPiPackage as t };
|
|
6033
6106
|
|
|
6034
|
-
//# sourceMappingURL=runtime-
|
|
6107
|
+
//# sourceMappingURL=runtime-BiD3SeGf.mjs.map
|