pi2dsh 0.13.3 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +2 -0
  2. package/README.zh.md +2 -0
  3. package/dist/{analyzer-DBtUYKI1.mjs → analyzer-DPZ8LzSt.mjs} +2 -2
  4. package/dist/{analyzer-DBtUYKI1.mjs.map → analyzer-DPZ8LzSt.mjs.map} +1 -1
  5. package/dist/cli.mjs +2 -2
  6. package/dist/compat/pi-ai.d.mts +1 -1
  7. package/dist/compat/pi-ai.mjs +1 -1
  8. package/dist/compat/pi-coding-agent.mjs +1 -1
  9. package/dist/{compatibility-Bz6ZXA7F.mjs → compatibility-CP2tpyhg.mjs} +13 -1
  10. package/dist/compatibility-CP2tpyhg.mjs.map +1 -0
  11. package/dist/{credentials-oauth-CAohSLcB.mjs → credentials-oauth-Didpkkjx.mjs} +3 -3
  12. package/dist/{credentials-oauth-CAohSLcB.mjs.map → credentials-oauth-Didpkkjx.mjs.map} +1 -1
  13. package/dist/credentials-oauth.mjs +1 -1
  14. package/dist/host.d.mts +3 -1
  15. package/dist/host.d.mts.map +1 -1
  16. package/dist/host.mjs +4 -3
  17. package/dist/host.mjs.map +1 -1
  18. package/dist/index.d.mts +34 -4
  19. package/dist/index.d.mts.map +1 -1
  20. package/dist/index.mjs +117 -35
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/{pi-ai-Dh7HUxbt.mjs → pi-ai-DpqiLdPA.mjs} +7 -2
  23. package/dist/{pi-ai-Dh7HUxbt.mjs.map → pi-ai-DpqiLdPA.mjs.map} +1 -1
  24. package/dist/{pi-ai-CfokFhIL.d.mts → pi-ai-ZU5MelXy.d.mts} +7 -2
  25. package/dist/{pi-ai-CfokFhIL.d.mts.map → pi-ai-ZU5MelXy.d.mts.map} +1 -1
  26. package/dist/{pi-coding-agent-Cvez0jkF.mjs → pi-coding-agent-DK8hbJP5.mjs} +0 -0
  27. package/dist/{pi-coding-agent-Cvez0jkF.mjs.map → pi-coding-agent-DK8hbJP5.mjs.map} +1 -1
  28. package/dist/{runtime-Dd2KhoX-.mjs → runtime-Bb9Bfk4M.mjs} +61 -10
  29. package/dist/runtime-Bb9Bfk4M.mjs.map +1 -0
  30. package/dist/runtime.d.mts +15 -1
  31. package/dist/runtime.d.mts.map +1 -1
  32. package/dist/runtime.mjs +1 -1
  33. package/package.json +8 -6
  34. package/dist/compatibility-Bz6ZXA7F.mjs.map +0 -1
  35. 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-Cvez0jkF.mjs";
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-Dh7HUxbt.mjs";
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-CAohSLcB.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-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;
@@ -4201,6 +4213,16 @@ function subscribeLifecycle(ctx, state) {
4201
4213
  }
4202
4214
  async function flushPendingSessionStarts(ctx, state) {
4203
4215
  state.extensionsReady = true;
4216
+ if (state.ownerAgent !== void 0 && !state.pendingSessionStarts.has(state.ownerAgent)) {
4217
+ const owned = state.ownerAgent;
4218
+ if (!state.activeAgents.has(owned)) {
4219
+ state.activeAgents.add(owned);
4220
+ trackRuntimeSession(state, owned);
4221
+ const session = agentSession(owned);
4222
+ if (session !== void 0) state.bridge.load(session.id);
4223
+ }
4224
+ state.pendingSessionStarts.set(owned, "startup");
4225
+ }
4204
4226
  const pending = [...state.pendingSessionStarts];
4205
4227
  state.pendingSessionStarts.clear();
4206
4228
  for (const [agent, reason] of pending) await startPiSession(ctx, state, agent, reason, void 0);
@@ -4354,7 +4376,7 @@ function subscribeInterceptors(ctx, state) {
4354
4376
  };
4355
4377
  });
4356
4378
  const systemPrompt = optionalService(ctx, "systemPrompt");
4357
- if (systemPrompt !== void 0) ctx.effect(() => systemPrompt.section({
4379
+ if (systemPrompt !== void 0 && !state.hostAnchor) ctx.effect(() => systemPrompt.section({
4358
4380
  name: `pi2dsh:tool-guidance:${state.packageName ?? "pi"}`,
4359
4381
  order: 150,
4360
4382
  text: () => piToolPromptContribution(ctx, state)
@@ -4566,6 +4588,16 @@ function oauthStoreOf(state) {
4566
4588
  }
4567
4589
  const COMPANION_ROUTE_PREFIX = "pi2dsh-companion/";
4568
4590
  const SHARED_HOST_STATE = /* @__PURE__ */ new WeakMap();
4591
+ /**
4592
+ * The engine's own built-in OAuth directory entries, by object identity.
4593
+ * They are login placeholders (no models, no transport), preloaded so
4594
+ * `/login <provider>` works before any package is installed — and a package
4595
+ * registering the SAME provider id owns the richer definition (transport,
4596
+ * catalog, its own flow) and must supersede the placeholder in the shared
4597
+ * ledger. Two PACKAGES colliding on one id still keep first-wins, matching
4598
+ * the route-ownership rule.
4599
+ */
4600
+ const BUILTIN_PROVIDER_SEEDS = /* @__PURE__ */ new WeakSet();
4569
4601
  function sharedHostStateOf(ctx) {
4570
4602
  const key = ctx.root ?? ctx;
4571
4603
  let shared = SHARED_HOST_STATE.get(key);
@@ -5011,6 +5043,10 @@ function registerTool(ctx, state, tool) {
5011
5043
  const normalized = normalizeToolSchema(tool.parameters);
5012
5044
  for (const warning of normalized.warnings) logger(ctx).warn(`[pi2dsh] tool ${tool.name}: ${warning}`);
5013
5045
  state.tools.set(tool.name, tool);
5046
+ if (state.hostAnchor) {
5047
+ state.toolDisposers.set(tool.name, () => {});
5048
+ return;
5049
+ }
5014
5050
  const definition = {
5015
5051
  name: tool.name,
5016
5052
  description: tool.description,
@@ -5071,6 +5107,7 @@ function currentAgent(state) {
5071
5107
  }
5072
5108
  /** Exact-Agent ownership for scoped mounts; legacy root mounts retain their old host-session rule. */
5073
5109
  function acceptsAgent(state, agent) {
5110
+ if (state.hostAnchor) return false;
5074
5111
  if (state.ownerAgent !== void 0) return agent === state.ownerAgent;
5075
5112
  return !isSubagentOrigin(agent);
5076
5113
  }
@@ -5316,6 +5353,7 @@ function registerCommand(ctx, state, command) {
5316
5353
  return;
5317
5354
  }
5318
5355
  state.commands.set(command.name, command);
5356
+ if (state.hostAnchor) return;
5319
5357
  const commands = ctx.get("commands");
5320
5358
  if (commands === void 0) {
5321
5359
  logger(ctx).warn(`[pi2dsh] command /${command.name} was not registered because this DSH composition has no ctx.commands`);
@@ -5490,7 +5528,18 @@ function createPiApi(ctx, state) {
5490
5528
  const name = typeof providerOrName === "string" ? providerOrName : String(providerOrName?.id ?? providerOrName?.name ?? "unnamed");
5491
5529
  const value = typeof providerOrName === "string" ? config ?? {} : providerOrName;
5492
5530
  state.providers.set(name, value);
5493
- if (!state.shared.providers.has(name)) state.shared.providers.set(name, value);
5531
+ const sharedExisting = state.shared.providers.get(name);
5532
+ if (sharedExisting === void 0 || BUILTIN_PROVIDER_SEEDS.has(sharedExisting)) {
5533
+ state.shared.providers.set(name, value);
5534
+ if (sharedExisting !== void 0) {
5535
+ const stale = state.shared.providerRouteDisposers.get(name);
5536
+ if (stale !== void 0) {
5537
+ state.shared.providerRouteDisposers.delete(name);
5538
+ state.shared.providerRouteOwners.delete(name);
5539
+ stale();
5540
+ }
5541
+ }
5542
+ }
5494
5543
  if (providerSupportsOAuth(value)) {
5495
5544
  ensureLoginCommand(ctx, state);
5496
5545
  logger(ctx).info(`[pi2dsh] Pi provider ${JSON.stringify(name)} supports OAuth — log in with /login ${name}`);
@@ -5782,6 +5831,7 @@ async function applyPiPackage(ctx, options) {
5782
5831
  shared,
5783
5832
  packageName: options.manifest.package.name,
5784
5833
  ownerAgent,
5834
+ hostAnchor: options.hostAnchor === true,
5785
5835
  handlers: /* @__PURE__ */ new Map(),
5786
5836
  tools: runtimeTools,
5787
5837
  runner: new ExtensionRunner(piToolRecords),
@@ -5848,6 +5898,7 @@ async function applyPiPackage(ctx, options) {
5848
5898
  baseUrl: provider.baseUrl,
5849
5899
  oauth: provider.auth.oauth
5850
5900
  };
5901
+ BUILTIN_PROVIDER_SEEDS.add(config);
5851
5902
  state.providers.set(provider.id, config);
5852
5903
  if (!shared.providers.has(provider.id)) shared.providers.set(provider.id, config);
5853
5904
  }
@@ -5857,7 +5908,7 @@ async function applyPiPackage(ctx, options) {
5857
5908
  } catch (error) {
5858
5909
  logger(ctx).warn(`[pi2dsh] could not restore the route for logged-in provider ${JSON.stringify(name)}: ${error instanceof Error ? error.message : String(error)}`);
5859
5910
  }
5860
- if (options.manifest.skillDirs.length > 0) {
5911
+ if (options.manifest.skillDirs.length > 0 && state.ownerAgent === void 0) {
5861
5912
  if (ctx.get("skills") === void 0) logger(ctx).warn("[pi2dsh] migrated skills were not mounted because this DSH composition has no ctx.skills");
5862
5913
  else {
5863
5914
  const { apply: applyFilesystemSkills } = await import("@deepseek-ai/dsh-skill-filesystem");
@@ -6014,7 +6065,7 @@ async function applyPiPackage(ctx, options) {
6014
6065
  });
6015
6066
  const health = state.shared.capabilityLedger?.healthOf(state.packageName);
6016
6067
  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}`);
6068
+ 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
6069
  }
6019
6070
  const runtimeInternals = {
6020
6071
  compactionReason,
@@ -6031,4 +6082,4 @@ const runtimeInternals = {
6031
6082
  //#endregion
6032
6083
  export { runtimeInternals as i, normalizeToolSchema as n, registerVisionCompanions as r, applyPiPackage as t };
6033
6084
 
6034
- //# sourceMappingURL=runtime-Dd2KhoX-.mjs.map
6085
+ //# sourceMappingURL=runtime-Bb9Bfk4M.mjs.map