pi2dsh 0.12.2 → 0.12.4
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 +47 -10
- package/README.zh.md +39 -8
- package/dist/{analyzer-CEjVQKXA.mjs → analyzer-CXNbeBAe.mjs} +2 -2
- package/dist/{analyzer-CEjVQKXA.mjs.map → analyzer-CXNbeBAe.mjs.map} +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/client.js +525 -0
- package/dist/compat/pi-ai.d.mts +36 -1
- package/dist/compat/pi-ai.d.mts.map +1 -1
- package/dist/compat/pi-ai.mjs +2 -2
- package/dist/compat/pi-coding-agent.d.mts +2 -1411
- package/dist/compat/pi-coding-agent.mjs +1 -1
- package/dist/compat/pi-tui.mjs +1 -1
- package/dist/{oauth-bridge-CfyImWx4.mjs → credentials-oauth-BakY-0PA.mjs} +172 -13
- package/dist/credentials-oauth-BakY-0PA.mjs.map +1 -0
- package/dist/credentials-oauth.mjs +1 -89
- package/dist/host.mjs +4 -2
- package/dist/host.mjs.map +1 -1
- package/dist/index.d.mts +16 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/mcp-config-CZepacin.mjs +766 -0
- package/dist/mcp-config-CZepacin.mjs.map +1 -0
- package/dist/{pi-ai-Dyg4zyLZ.mjs → pi-ai-BA3V_J0V.mjs} +40 -2
- package/dist/{pi-ai-Dyg4zyLZ.mjs.map → pi-ai-BA3V_J0V.mjs.map} +1 -1
- package/dist/pi-coding-agent-B0PT23gE.d.mts +1412 -0
- package/dist/pi-coding-agent-B0PT23gE.d.mts.map +1 -0
- package/dist/{pi-coding-agent-CYnmeJEx.mjs → pi-coding-agent-D9skobb6.mjs} +0 -0
- package/dist/pi-coding-agent-D9skobb6.mjs.map +1 -0
- package/dist/{pi-tui-5CYLcj-_.mjs → pi-tui-DruSeKmd.mjs} +3 -3
- package/dist/pi-tui-DruSeKmd.mjs.map +1 -0
- package/dist/{runtime-DsPaznXJ.mjs → runtime-DH0zEUpu.mjs} +1075 -67
- package/dist/runtime-DH0zEUpu.mjs.map +1 -0
- package/dist/runtime.d.mts +594 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -1
- package/package.json +15 -4
- package/dist/compat/pi-coding-agent.d.mts.map +0 -1
- package/dist/credentials-oauth.mjs.map +0 -1
- package/dist/mcp-config-DHkfjdvX.mjs +0 -707
- package/dist/mcp-config-DHkfjdvX.mjs.map +0 -1
- package/dist/oauth-bridge-CfyImWx4.mjs.map +0 -1
- package/dist/pi-coding-agent-CYnmeJEx.mjs.map +0 -1
- package/dist/pi-tui-5CYLcj-_.mjs.map +0 -1
- package/dist/runtime-DsPaznXJ.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-config-DHkfjdvX.mjs","names":[],"sources":["../src/compatibility.ts","../src/mcp-config.ts"],"sourcesContent":["import type { CompatibilityLevel } from './types.js'\n\ninterface Rule {\n level: CompatibilityLevel\n detail: string\n}\n\nconst rule = (level: CompatibilityLevel, detail: string): Rule => ({ level, detail })\n\nexport const PI_CODING_AGENT_PACKAGES = Object.freeze([\n '@earendil-works/pi-coding-agent',\n '@mariozechner/pi-coding-agent',\n] as const)\n\nexport const PI_TUI_PACKAGES = Object.freeze([\n '@earendil-works/pi-tui',\n '@mariozechner/pi-tui',\n] as const)\n\nexport const PI_AI_PACKAGES = Object.freeze([\n '@earendil-works/pi-ai',\n '@mariozechner/pi-ai',\n] as const)\n\nconst VENDORED = 'Vendored byte-identical from Pi, so semantics match Pi exactly.'\nconst HEADLESS_COMPONENT = 'Constructible headless component with Pi-exact signatures; renders plain text, never a terminal.'\nconst VENDORED_TOOL = 'Pi\\'s built-in tool constructor, vendored byte-identical with its pure-logic closure.'\nconst EVENT_GUARD = 'Pi\\'s exact one-line tool-event guard, reimplemented verbatim.'\nconst VENDORED_SUMMARIZER = 'Vendored Pi logic; the model call fills Pi\\'s own streamFn injection point with the DSH llm bridge when the caller passes none, so summarization runs on the ONE model path. Without a mounted llm service it fails explicitly.'\n\nexport const HOST_IMPORT_RULES: Readonly<Record<string, Readonly<Record<string, Rule>>>> = Object.freeze({\n 'pi-coding-agent': Object.freeze({\n defineTool: rule('full', 'Identity helper, preserved.'),\n CONFIG_DIR_NAME: rule('partial', 'The conventional config directory name is preserved, while DSH owns the actual profile layout.'),\n DEFAULT_MAX_LINES: rule('full', VENDORED),\n DEFAULT_MAX_BYTES: rule('full', VENDORED),\n VERSION: rule('partial', 'Reports a pi2dsh compatibility marker instead of a Pi release version.'),\n CURRENT_SESSION_VERSION: rule('full', VENDORED),\n getAgentDir: rule('partial', 'Redirected to an isolated DSH-owned pi2dsh directory instead of Pi global state.'),\n getPackageDir: rule('partial', 'Resolves inside the DSH-owned pi2dsh agent directory.'),\n formatSize: rule('full', VENDORED),\n truncateHead: rule('full', VENDORED),\n truncateTail: rule('full', VENDORED),\n truncateLine: rule('full', VENDORED),\n withFileMutationQueue: rule('full', VENDORED),\n SessionManager: rule('full', `${VENDORED} Sessions live under the DSH-owned pi2dsh agent directory.`),\n parseSessionEntries: rule('full', VENDORED),\n migrateSessionEntries: rule('full', VENDORED),\n getLatestCompactionEntry: rule('full', VENDORED),\n sessionEntryToContextMessages: rule('full', VENDORED),\n buildContextEntries: rule('full', VENDORED),\n buildSessionContext: rule('full', VENDORED),\n loadEntriesFromFile: rule('full', VENDORED),\n findMostRecentSession: rule('full', VENDORED),\n getDefaultSessionDir: rule('full', VENDORED),\n assertValidSessionId: rule('full', VENDORED),\n convertToLlm: rule('full', VENDORED),\n createCustomMessage: rule('full', VENDORED),\n createBranchSummaryMessage: rule('full', VENDORED),\n createCompactionSummaryMessage: rule('full', VENDORED),\n bashExecutionToText: rule('full', VENDORED),\n estimateTokens: rule('full', VENDORED),\n calculateContextTokens: rule('full', `${VENDORED} Pi\\'s Usage-based total (an earlier reimplementation summed message estimates — same name, different meaning — and was replaced).`),\n DEFAULT_COMPACTION_SETTINGS: rule('full', VENDORED),\n serializeConversation: rule('full', VENDORED),\n shouldCompact: rule('full', `${VENDORED} The pure threshold check; DSH still owns automatic compaction scheduling.`),\n compact: rule('partial', VENDORED_SUMMARIZER),\n findCutPoint: rule('full', VENDORED),\n generateSummary: rule('partial', VENDORED_SUMMARIZER),\n generateSummaryWithUsage: rule('partial', VENDORED_SUMMARIZER),\n generateBranchSummary: rule('partial', VENDORED_SUMMARIZER),\n parseFrontmatter: rule('full', `${VENDORED} Returns Pi\\'s public { frontmatter, body } shape with YAML-parsed values (an earlier reimplementation returned { attributes } with string values and was replaced).`),\n stripFrontmatter: rule('full', VENDORED),\n copyToClipboard: rule('partial', 'Attempts the platform clipboard command (pbcopy/clip/wl-copy/xclip); resolves false when none succeeds.'),\n resizeImage: rule('partial', 'Passes images through un-resized; Pi resizes only to save tokens, so content is preserved.'),\n convertToPng: rule('partial', 'PNG input passes through; other formats fail explicitly without Pi\\'s wasm codec.'),\n getShellConfig: rule('partial', 'Standard shell detection without Pi\\'s managed-bin PATH handling.'),\n getBinDir: rule('partial', 'Reports the first PATH segment instead of Pi\\'s managed bin directory.'),\n Theme: rule('partial', 'Headless theme: styling calls return their input text unstyled.'),\n theme: rule('partial', 'A headless theme singleton; jiti-loaded Pi extensions must not rely on Pi global theme state anyway.'),\n initTheme: rule('partial', 'Accepted as a no-op; DSH surfaces own presentation.'),\n getSettingsListTheme: rule('partial', 'Returns an unstyled theme with Pi\\'s exact field shape.'),\n getSelectListTheme: rule('partial', 'Returns an unstyled theme with Pi\\'s exact field shape.'),\n getMarkdownTheme: rule('partial', 'Returns a plain-text headless theme; Pi terminal styling is intentionally discarded.'),\n getLanguageFromPath: rule('partial', 'Extension-based language detection covering common languages.'),\n highlightCode: rule('partial', 'Splits lines without terminal syntax colors.'),\n DynamicBorder: rule('full', 'Headless implementation of Pi\\'s one-line border component; pass an explicit color function as Pi itself recommends.'),\n SettingsManager: rule('partial', 'In-memory settings with Pi\\'s getter/setter surface; DSH owns real persisted configuration.'),\n InMemorySettingsStorage: rule('partial', 'In-memory storage stub honoring the withLock contract.'),\n FileSettingsStorage: rule('partial', 'Alias of the in-memory storage; DSH owns persisted settings.'),\n ModelRegistry: rule('partial', 'A local registry container; DSH llm adapters own real model routing.'),\n createEventBus: rule('full', 'Pi event-bus semantics: async handler isolation and unsubscribe functions.'),\n readStoredCredential: rule('partial', 'Reads Pi-style auth.json from the pi2dsh-owned agent directory; DSH credentials stay authoritative for DSH model calls.'),\n parseSkillBlock: rule('full', 'Pi\\'s skill_content block parser, reimplemented over the same wire shape.'),\n wrapRegisteredTool: rule('full', `${VENDORED} The runner argument is used exactly as Pi uses it (createContext + getActiveTools), which the pi2dsh projection provides.`),\n ProjectTrustStore: rule('partial', `${VENDORED} The store operates on trust.json under the caller\\'s agentDir — with the redirected getAgentDir convention that is package-visible state inside the DSH-owned pi2dsh directory. The DSH host never consults it; host trust stays a DSH decision (ctx.isProjectTrusted fails closed).`),\n DefaultResourceLoader: rule('partial', 'A headless resource loader honoring overrides, with empty discovery sets.'),\n DefaultPackageManager: rule('unsupported', 'Installing packages is owned by the DSH host and its security gates (dsh plugin add/remove behind pnpm\\'s build-script approval). Importing it is flagged at mount time (startup check); constructing it throws a structured PiCapabilityError, and doing so during entry setup marks the package unusable.'),\n ModelRuntime: rule('unsupported', 'Standalone model stacks are owned by the DSH host llm configuration; packages read the ONE directory through ctx.modelRegistry. Importing it is flagged at mount time (startup check); constructing it throws a structured PiCapabilityError, and doing so during entry setup marks the package unusable.'),\n createAgentSession: rule('partial', 'Bridged to a genuine DSH child agent through ctx.agents (a Pi model on the options routes the child); compositions without a loop factory fail explicitly.'),\n createCodingTools: rule('full', 'Pi\\'s exact tool set composed from the vendored built-in constructors.'),\n createReadOnlyTools: rule('full', 'Pi\\'s exact read-only tool set composed from the vendored built-in constructors.'),\n createBashTool: rule('full', VENDORED_TOOL),\n createReadTool: rule('full', VENDORED_TOOL),\n createEditTool: rule('full', VENDORED_TOOL),\n createWriteTool: rule('full', VENDORED_TOOL),\n createGrepTool: rule('full', VENDORED_TOOL),\n createFindTool: rule('full', VENDORED_TOOL),\n createLsTool: rule('full', VENDORED_TOOL),\n createBashToolDefinition: rule('full', VENDORED_TOOL),\n createReadToolDefinition: rule('full', VENDORED_TOOL),\n createEditToolDefinition: rule('full', VENDORED_TOOL),\n createWriteToolDefinition: rule('full', VENDORED_TOOL),\n createGrepToolDefinition: rule('full', VENDORED_TOOL),\n createFindToolDefinition: rule('full', VENDORED_TOOL),\n createLsToolDefinition: rule('full', VENDORED_TOOL),\n isToolCallEventType: rule('full', EVENT_GUARD),\n isBashToolResult: rule('full', EVENT_GUARD),\n isReadToolResult: rule('full', EVENT_GUARD),\n isEditToolResult: rule('full', EVENT_GUARD),\n isWriteToolResult: rule('full', EVENT_GUARD),\n isGrepToolResult: rule('full', EVENT_GUARD),\n isFindToolResult: rule('full', EVENT_GUARD),\n isLsToolResult: rule('full', EVENT_GUARD),\n loadSkills: rule('partial', `${VENDORED} Real directory discovery with Pi\\'s exact rules; default locations resolve through the redirected getAgentDir, i.e. inside the DSH-owned pi2dsh directory.`),\n loadSkillsFromDir: rule('full', `${VENDORED} Real directory discovery: SKILL.md roots, direct .md children, ignore files, symlink dedup, and Pi\\'s name/description validation.`),\n formatSkillsForPrompt: rule('full', 'Pi\\'s skill prompt formatter, vendored with logic unchanged.'),\n CustomEditor: rule('partial', HEADLESS_COMPONENT),\n ToolExecutionComponent: rule('partial', HEADLESS_COMPONENT),\n FooterComponent: rule('partial', HEADLESS_COMPONENT),\n BorderedLoader: rule('partial', HEADLESS_COMPONENT),\n CustomMessageComponent: rule('partial', HEADLESS_COMPONENT),\n AssistantMessageComponent: rule('partial', HEADLESS_COMPONENT),\n UserMessageComponent: rule('partial', HEADLESS_COMPONENT),\n ExtensionSelectorComponent: rule('partial', HEADLESS_COMPONENT),\n ExtensionInputComponent: rule('partial', HEADLESS_COMPONENT),\n ExtensionEditorComponent: rule('partial', HEADLESS_COMPONENT),\n SettingsSelectorComponent: rule('partial', HEADLESS_COMPONENT),\n renderDiff: rule('partial', 'Plain unified-style diff lines without terminal colors.'),\n truncateToVisualLines: rule('partial', 'Visual-line truncation backed by Pi\\'s vendored width math.'),\n keyHint: rule('partial', 'Plain-text key hint without theme styling.'),\n keyText: rule('partial', 'Plain-text key name without theme styling.'),\n rawKeyHint: rule('partial', 'Plain-text key hint without theme styling.'),\n }),\n 'pi-tui': Object.freeze({\n visibleWidth: rule('full', VENDORED),\n truncateToWidth: rule('full', VENDORED),\n wrapTextWithAnsi: rule('full', VENDORED),\n sliceByColumn: rule('full', VENDORED),\n sliceWithWidth: rule('full', VENDORED),\n stripTerminalSequences: rule('full', VENDORED),\n getOsc8LinkAtColumn: rule('full', VENDORED),\n normalizeTerminalOutput: rule('full', VENDORED),\n extractAnsiCode: rule('full', VENDORED),\n getGraphemeCellRange: rule('full', VENDORED),\n getGraphemeSegmenter: rule('full', VENDORED),\n getWordSegmenter: rule('full', VENDORED),\n applyBackgroundToLine: rule('full', VENDORED),\n isWhitespaceChar: rule('full', VENDORED),\n isPunctuationChar: rule('full', VENDORED),\n cjkBreakRegex: rule('full', VENDORED),\n PUNCTUATION_REGEX: rule('full', VENDORED),\n fuzzyMatch: rule('full', VENDORED),\n fuzzyFilter: rule('full', VENDORED),\n parseKey: rule('full', VENDORED),\n matchesKey: rule('full', VENDORED),\n isKeyRelease: rule('full', VENDORED),\n isKeyRepeat: rule('full', VENDORED),\n decodeKittyPrintable: rule('full', VENDORED),\n isKittyProtocolActive: rule('full', VENDORED),\n setKittyProtocolActive: rule('full', VENDORED),\n Key: rule('full', VENDORED),\n getKeybindings: rule('full', `${VENDORED} Bindings only match when a surface feeds terminal input, which DSH does not.`),\n setKeybindings: rule('full', VENDORED),\n KeybindingsManager: rule('full', VENDORED),\n TUI_KEYBINDINGS: rule('full', VENDORED),\n parseOsc11BackgroundColor: rule('full', VENDORED),\n parseTerminalColorSchemeReport: rule('full', VENDORED),\n renderLatex: rule('full', VENDORED),\n getPngDimensions: rule('full', VENDORED),\n getJpegDimensions: rule('full', VENDORED),\n getGifDimensions: rule('full', VENDORED),\n getWebpDimensions: rule('full', VENDORED),\n getImageDimensions: rule('full', VENDORED),\n calculateImageRows: rule('full', VENDORED),\n allocateImageId: rule('full', VENDORED),\n encodeKitty: rule('partial', `${VENDORED} No DSH surface consumes the escape sequences.`),\n encodeITerm2: rule('partial', `${VENDORED} No DSH surface consumes the escape sequences.`),\n deleteKittyImage: rule('partial', `${VENDORED} No DSH surface consumes the escape sequences.`),\n deleteAllKittyImages: rule('partial', `${VENDORED} No DSH surface consumes the escape sequences.`),\n detectCapabilities: rule('partial', `${VENDORED} Headless environments report no image protocol.`),\n getCapabilities: rule('partial', VENDORED),\n setCapabilities: rule('partial', VENDORED),\n resetCapabilitiesCache: rule('partial', VENDORED),\n getCellDimensions: rule('partial', VENDORED),\n setCellDimensions: rule('partial', VENDORED),\n hyperlink: rule('full', VENDORED),\n imageFallback: rule('full', VENDORED),\n CombinedAutocompleteProvider: rule('partial', `${VENDORED} Suggestions surface only if a DSH UI asks for them.`),\n Marked: rule('full', 'Re-exported from the same marked dependency Pi uses.'),\n CURSOR_MARKER: rule('full', 'Pi\\'s exact APC marker; vendored width math treats it as zero-width.'),\n Text: rule('partial', HEADLESS_COMPONENT),\n Spacer: rule('partial', HEADLESS_COMPONENT),\n Container: rule('partial', HEADLESS_COMPONENT),\n Box: rule('partial', HEADLESS_COMPONENT),\n Markdown: rule('partial', HEADLESS_COMPONENT),\n TruncatedText: rule('partial', HEADLESS_COMPONENT),\n Editor: rule('partial', `${HEADLESS_COMPONENT} Text editing state works; interactive keyboard flows do not.`),\n Input: rule('partial', `${HEADLESS_COMPONENT} Value state and submit/escape callbacks work; kill-ring editing does not.`),\n SelectList: rule('partial', `${HEADLESS_COMPONENT} Filtering and selection state work; keyboard interaction does not.`),\n SettingsList: rule('partial', `${HEADLESS_COMPONENT} Value updates work; keyboard interaction does not.`),\n ScrollView: rule('partial', HEADLESS_COMPONENT),\n VStack: rule('partial', HEADLESS_COMPONENT),\n HStack: rule('partial', HEADLESS_COMPONENT),\n Loader: rule('partial', HEADLESS_COMPONENT),\n CancellableLoader: rule('partial', HEADLESS_COMPONENT),\n Image: rule('partial', `${HEADLESS_COMPONENT} Renders a text placeholder; image bytes flow through DSH attachments instead.`),\n isFocusable: rule('full', 'Structural check preserved.'),\n isViewportTUI: rule('partial', 'Always false: no viewport TUI exists in DSH surfaces.'),\n }),\n 'pi-ai': Object.freeze({\n StringEnum: rule('full', 'Preserves Pi flat string-enum JSON Schema generation without loading provider SDKs.'),\n registerProvider: rule('partial', 'Recorded in a bridge-local registry; DSH llm adapters own real routing.'),\n getProviders: rule('partial', 'Returns the bridge-local registry contents.'),\n getProvider: rule('partial', 'Reads the bridge-local registry.'),\n getModel: rule('partial', 'Resolves no Pi model objects; DSH owns model routing.'),\n getModels: rule('partial', 'Returns an empty list; DSH owns model routing.'),\n complete: rule('partial', 'Real model calls through the DSH llm bridge (the host installs it at mount); without a mounted llm service the call fails explicitly. Provider SDKs are never loaded.'),\n stream: rule('partial', 'Real streaming model calls through the DSH llm bridge (the host installs it at mount); without a mounted llm service the call fails explicitly. Provider SDKs are never loaded.'),\n Type: rule('full', 'Re-exported from the same typebox dependency Pi resolves for extensions.'),\n uuidv7: rule('full', VENDORED),\n isContextOverflow: rule('full', VENDORED),\n isRecoverableLength: rule('full', VENDORED),\n isRetryableAssistantError: rule('full', VENDORED),\n contentText: rule('full', 'Pi\\'s text-block joiner, reimplemented with identical semantics.'),\n clampThinkingLevel: rule('full', 'Pi\\'s clamping walk over the extended thinking-level ladder.'),\n getSupportedThinkingLevels: rule('full', 'Pi\\'s thinkingLevelMap filter, preserved.'),\n modelsAreEqual: rule('full', 'Id+provider equality, preserved.'),\n }),\n})\n\nexport const CONTEXT_RULES: Readonly<Record<string, Rule>> = Object.freeze({\n cwd: rule('full', 'Mapped to the active DSH agent session working directory.'),\n signal: rule('full', 'Mapped to the active DSH cancellation signal when one is available.'),\n hasUI: rule('full', 'Reports whether a human can actually answer: false when no questions service is mounted, false when the service is mounted with no provider registered (the headless posture), and false inside a child agent, which DSH refuses to let ask.'),\n mode: rule('partial', 'Reports rpc mode so Pi extensions can choose their documented headless fallback.'),\n isIdle: rule('partial', 'Command contexts report idle; tool/lifecycle contexts conservatively report non-idle.'),\n isProjectTrusted: rule('partial', 'Fails closed as untrusted because DSH does not expose Pi project-trust state.'),\n hasPendingMessages: rule('full', 'Reads the DSH agent inbox — next-step plus next-turn input — which is exactly Pi\\'s steering plus follow-up queue.'),\n getContextUsage: rule('partial', 'Returns no Pi token-usage projection.'),\n getSystemPrompt: rule('full', 'Returns the system prompt currently assembled by the bridge.'),\n getSystemPromptOptions: rule('partial', 'Returns an empty Pi option projection in command contexts.'),\n waitForIdle: rule('partial', 'Mapped to the DSH agent idle boundary when available.'),\n sessionManager: rule('partial', 'A real read-only projection: DSH durable messages plus pi2dsh sidecar entries, exposed through Pi\\'s exact 14-method surface as a single-branch tree. buildContextEntries is compaction-aware — entries a compaction summarized away are gone, exactly as they are for the model — while getEntries stays the append-only log, which is the same split Pi makes.'),\n modelRegistry: rule('partial', 'A live registry over the ONE model directory — the DSH llm directory — projected exactly into Pi vocabulary; package-registered Pi-native routes keep api/baseUrl and the full Model shape through the round trip. DSH describes one model across two seams (a listing for directory membership, an exact per-route resolve for capacity) while Pi puts everything on one Model object read synchronously, so the projection joins them when the directory is read: entries carry contextWindow, maxTokens and reasoning, and a settings change re-reads them rather than serving the retired numbers. Custom gateways are HOST configuration (the official llm-pi-ai adapter\\'s settings), never a Pi-side file: Pi\\'s ~/.pi/agent/models.json is deliberately NOT read — user-facing configuration is DSH-shaped only. getProviderAuth/getApiKeyAndHeaders run Pi\\'s full credential chain for package-registered providers and the host\\'s configurable-provider + credentials seams for DSH routes. Host configuration may declare \"<route>-vision\" image-admission companions: real DSH routes that admit images, replace image blocks with explicit path-carrying notices (materialized attachment files any path-taking tool can read), and forward text-only to the original route; Pi\\'s ctx.model reports the original route for a companion selection.'),\n model: rule('partial', 'The agent\\'s real provider/model route (a setModel() override wins), enriched from the projected catalog. When the selected route is an image-admission companion, ctx.model reports the ORIGINAL route with its true modalities — the generating model is the original text-only one, which is the truth extensions branching on input modalities (a vision bridge\\'s activation check) need.'),\n scopedModels: rule('full', 'Empty, carrying Pi\\'s own meaning for empty: no model scope is configured, so every available model is usable. DSH has no model-scope concept to narrow it.'),\n hasConfiguredAuth: rule('partial', 'Configuration check on the projected registry: true when the model\\'s provider has a live route or package registration (not a key-liveness probe).'),\n thinkingLevel: rule('partial', 'Reflects the level recorded by setThinkingLevel(); applied as reasoningEffort on the next request.'),\n abort: rule('partial', 'Mapped to agent.cancel({ kind: \"hook\" }) on the live DSH agent.'),\n shutdown: rule('partial', 'Pi defines shutdown behavior as host-provided (runner.ts bindExtensions); this host absorbs the request — the user owns DSH process exit — and informs the user once. The package keeps running.'),\n compact: rule('partial', 'Pi\\'s fire-and-forget trigger, translated to DSH\\'s official manual compaction (ctx.compaction.compactNow on the live agent). onComplete receives the real summary text and the shadowed-content token estimate as tokensBefore; firstKeptEntryId is empty because the DSH log has no Pi entry ids. Without a compaction service the gap flows through Pi\\'s onError callback and the capability ledger.'),\n newSession: rule('partial', 'Really creates a DSH session (ctx.sessions.create) with parent lineage; withSession runs against a projection context bound to it, whose sendMessage/sendUserMessage/appendEntry write into THAT session rather than the one the call came from. DSH has no host-level \"current session pointer\" a plugin could move — which session the surface shows stays a host choice, announced once.'),\n fork: rule('partial', 'Really forks on DSH\\'s official prefix-fork surface (ctx.sessions.fork with lineage metadata). Anchors are durable-log entries (projected ids \"dsh-<seq>\"); Pi\\'s default position \"before\" is honored, and the boundary shrinks to the nearest completed-turn edge because DSH seeds must not split an open turn. Sidecar entries cannot anchor a fork.'),\n navigateTree: rule('partial', 'Expressed through DSH\\'s session model: the DSH tree lives BETWEEN sessions (fork lineage), not inside one log, so navigation forks at the target boundary. summarize runs Pi\\'s vendored branch summarizer over the abandoned durable slice (model call on the DSH llm bridge) and lands the summary as a branch_summary entry in the new session\\'s projection; label lands as a label entry.'),\n switchSession: rule('partial', 'Targets a LIVE DSH session by id (or a Pi-style path whose basename is \"<id>.jsonl\"); withSession runs against its projection. Switching to persisted sessions is host-owned — resume them from the DSH surface first. Which session the surface shows stays a host choice.'),\n reload: rule('partial', 'Really remounts every mounted package\\'s extension entries through a fresh loader (registrations replaced via the same-name path, event handlers reset), so edited plugin code takes effect. Skills, prompts, and themes are host-managed and reload with dsh itself.'),\n})\n\nexport const UI_CONTEXT_RULES: Readonly<Record<string, Rule>> = Object.freeze({\n notify: rule('full', 'Captured as a command result when applicable and emitted through DSH logging at the severity the caller passed (warning and error log as warnings).'),\n setStatus: rule('partial', 'Accepted as a no-op because DSH owns status presentation.'),\n setWidget: rule('partial', 'Accepted as a no-op because Pi terminal widgets cannot render in DSH.'),\n select: rule('full', 'Mapped to one native DSH userQuestions single-select request.'),\n confirm: rule('full', 'Mapped to one native DSH userQuestions Yes/No request.'),\n input: rule('full', 'Mapped to one native DSH userQuestions free-text request.'),\n editor: rule('partial', 'Mapped to one DSH userQuestions free-text request. The prefill is shown as context but is NOT editable text: the caller receives what the user typed fresh, not an edit of the prefill.'),\n custom: rule('partial', 'Resolves undefined, exactly like Pi\\'s own rpc mode; guarded fallbacks keep working.'),\n onTerminalInput: rule('partial', 'Raw terminal input is absent; feature-detected listeners remain disabled.'),\n setWorkingMessage: rule('partial', 'Accepted as a no-op; DSH owns progress presentation.'),\n setWorkingVisible: rule('partial', 'Accepted as a no-op; DSH owns progress presentation.'),\n setWorkingIndicator: rule('partial', 'Accepted as a no-op; DSH owns progress presentation.'),\n setHiddenThinkingLabel: rule('partial', 'Accepted as a no-op; DSH owns thinking presentation.'),\n setFooter: rule('partial', 'Accepted as a no-op; DSH owns footer presentation.'),\n setHeader: rule('partial', 'Accepted as a no-op; DSH owns header presentation.'),\n setTitle: rule('partial', 'Accepted as a no-op; DSH owns window titles.'),\n pasteToEditor: rule('partial', 'Appends to a per-agent editor buffer readable through getEditorText().'),\n setEditorText: rule('partial', 'Stored in a per-agent editor buffer readable through getEditorText().'),\n getEditorText: rule('partial', 'Reads the per-agent editor buffer maintained by the bridge.'),\n addAutocompleteProvider: rule('partial', 'Registration is recorded; no DSH surface requests suggestions.'),\n setEditorComponent: rule('partial', 'Registration is recorded; no DSH surface mounts a Pi editor component.'),\n getEditorComponent: rule('partial', 'Returns the recorded factory.'),\n theme: rule('partial', 'A headless theme whose styling calls return unstyled text.'),\n getAllThemes: rule('partial', 'Lists the single headless theme.'),\n getTheme: rule('partial', 'Resolves only the headless theme.'),\n setTheme: rule('partial', 'Accepts the headless theme; other names report an explicit error result.'),\n getToolsExpanded: rule('partial', 'A bridge-local presentation flag.'),\n setToolsExpanded: rule('partial', 'A bridge-local presentation flag.'),\n})\n\nexport const API_RULES: Readonly<Record<string, Rule>> = Object.freeze({\n registerTool: {\n level: 'partial',\n detail: 'Registered as a native DSH tool. Text and image results use native DSH content/attachments; unsupported JSON Schema constraints and Pi-only error details are explicitly degraded.',\n },\n unregisterTool: {\n level: 'full',\n detail: 'Disposes the exact native DSH tool registration and removes it from the migrated package registry.',\n },\n registerCommand: {\n level: 'partial',\n detail: 'Registered in ctx.commands with Pi\\'s never-throw collision semantics: a package re-registering its own name replaces it, and cross-source collisions mount under Pi\\'s numbered scheme (/name-2 — the earlier registration keeps the bare name, where Pi renumbers both). ui.notify becomes the result, while interactive Pi TUI methods fail explicitly in headless DSH.',\n },\n registerShortcut: {\n level: 'partial',\n detail: 'Registration is recorded and introspectable; DSH surfaces feed no terminal key input, so handlers never fire — the same as Pi\\'s non-TUI modes.',\n },\n registerFlag: {\n level: 'partial',\n detail: 'The declared default is available through getFlag; Pi process flags cannot be added to the DSH launcher.',\n },\n getFlag: {\n level: 'partial',\n detail: 'Returns the migrated flag default because DSH cannot register the original Pi CLI flag.',\n },\n registerProvider: {\n level: 'partial',\n detail: 'Two outcomes, by whether the provider carries its own transport. '\n + 'WITH a transport (pi-ai createProvider and friends): it becomes a real DSH llm route through llm.registerAdapter, and from then on the package\\'s own HTTP client carries the turn — its API key or OAuth token is resolved by Pi\\'s credential chain and persisted in the bridge\\'s auth.json, not by DSH credentials. '\n + 'WITHOUT one (catalog-only): the declaration is recorded and introspectable, no bridge transport is synthesized, and model calls stay on native DSH llm adapters and credentials.',\n },\n unregisterProvider: {\n level: 'partial',\n detail: 'Removes the recorded provider declaration.',\n },\n registerMessageRenderer: {\n level: 'partial',\n detail: 'Registration is accepted; DSH owns presentation, so the renderer is never invoked — matching Pi\\'s non-TUI surfaces.',\n },\n registerEntryRenderer: {\n level: 'partial',\n detail: 'Registration is accepted; DSH owns presentation, so the renderer is never invoked — matching Pi\\'s non-TUI surfaces.',\n },\n registerMarkdownTransformer: {\n level: 'partial',\n detail: 'Registration is accepted; DSH owns presentation, so the transformer is never invoked — matching Pi\\'s non-TUI surfaces.',\n },\n sendMessage: {\n level: 'partial',\n detail: 'Durable by the time it returns, as in Pi: the no-turn call appends to the session log and announces its message events immediately, so the message IS in the conversation when the call resolves. Steering and follow-up drive a turn through the agent. Pi display/details metadata awaits the custom session-entry seam.',\n },\n sendUserMessage: {\n level: 'full',\n detail: 'Mapped to native DSH steer/followup delivery with text and attachment-backed image content.',\n },\n appendEntry: {\n level: 'partial',\n detail: 'Persisted in a pi2dsh sidecar next to the DSH session and replayed on session start; DSH\\'s main log stays untouched because it has no out-of-repo plugin-event channel yet.',\n },\n setSessionName: {\n level: 'full',\n detail: 'Renames the DSH session through ctx.sessionTitle, so every DSH surface shows it and the title is pinned against automatic regeneration, and announces it through session_info_changed. A composition that mounts no title service falls back to the pi2dsh sidecar, as does a blank name (DSH requires visible characters in a title; Pi does not).',\n },\n getSessionName: {\n level: 'full',\n detail: 'Reads DSH\\'s own session title, so it agrees with what DSH displays and sees titles DSH generated itself; falls back to the sidecar when no title service is mounted.',\n },\n setLabel: {\n level: 'partial',\n detail: 'Persisted in the pi2dsh sidecar and reflected by the sessionManager projection.',\n },\n exec: {\n level: 'partial',\n detail: 'Mapped to ctx.subprocess, so the selected local/E2B provider owns execution, isolation, cancellation, and tree cleanup; output is bounded to 64 MiB per stream.',\n },\n getActiveTools: {\n level: 'partial',\n detail: 'Returns every tool visible in the current DSH agent scope, including native and migrated tools; scope-local tools follow DSH composition rules.',\n },\n getAllTools: {\n level: 'partial',\n detail: 'Returns metadata for all tools visible in the current DSH scope, without Pi-specific prompt guidelines unavailable from DSH schemas.',\n },\n setActiveTools: {\n level: 'partial',\n detail: 'Mapped to the active DSH agent scope through tools.restrict, per-agent and without mutating other agents. Names DSH does not know are skipped exactly as Pi skips them. A tool DSH does not permit restricting (a scope\\'s own registration, or a reserved transport name) cannot be deactivated at all and is reported once rather than silently left running.',\n },\n getCommands: {\n level: 'partial',\n detail: 'Returns commands registered by this migrated Pi package, not every command visible in the DSH scope.',\n },\n setModel: {\n level: 'partial',\n detail: 'Recorded as a per-agent override applied through the agent/request waterfall on the next model call; DSH remains authoritative for provider routing.',\n },\n getThinkingLevel: {\n level: 'partial',\n detail: 'Returns the level recorded by setThinkingLevel (default off).',\n },\n setThinkingLevel: {\n level: 'partial',\n detail: 'Recorded per agent and applied as reasoningEffort through the agent/request waterfall; DSH validates the effort id at the request boundary.',\n },\n events: {\n level: 'full',\n detail: 'Package-local Pi extension event-bus emit/on semantics are preserved for migrated extensions in the same bundle.',\n },\n})\n\nconst OBSERVED_NEVER_FIRES = (moment: string): Rule => ({\n level: 'partial',\n detail: `Registration is accepted; ${moment} never occurs on DSH surfaces, so the handler never fires. Loading is unaffected.`,\n})\n\nexport const EVENT_RULES: Readonly<Record<string, Rule>> = Object.freeze({\n session_start: { level: 'full', detail: 'Mapped to agent/session-start.' },\n session_shutdown: { level: 'full', detail: 'Mapped to agent disposal and plugin teardown with duplicate suppression.' },\n session_info_changed: { level: 'partial', detail: 'Fired by setSessionName() and projected from DSH session/title events.' },\n agent_start: { level: 'full', detail: 'Mapped to the DSH turn/start boundary.' },\n agent_settled: { level: 'full', detail: 'Mapped to the DSH turn/end boundary.' },\n turn_start: { level: 'full', detail: 'Fires once per MODEL CALL, as in Pi — DSH calls that a step — with turnIndex counting from zero and resetting at each new prompt.' },\n tool_execution_start: { level: 'full', detail: 'Mapped from durable tool/call events.' },\n tool_execution_end: { level: 'full', detail: 'Mapped from finalized tools/result events.' },\n tool_execution_update: {\n level: 'partial',\n detail: 'Fired from migrated Pi tools\\' own onUpdate callbacks; DSH-native tools expose no partial-result stream.',\n },\n tool_call: {\n level: 'partial',\n detail: 'Blocking is supported, in-place argument mutation reaches migrated Pi tools, and `terminate` follows Pi\\'s batch rule — the loop stops after a tool batch only when every call in it was blocked asking to stop. Mutating a DSH-native tool\\'s arguments is rejected because DSH logs arguments before policy.',\n },\n tool_result: {\n level: 'partial',\n detail: 'Text replacement and success-to-error blocking are supported; arbitrary details and error recovery are not.',\n },\n before_agent_start: {\n level: 'full',\n detail: 'Fires once per user prompt, inside the assembly of the turn it belongs to, with the real prompt text and image attachments; returned custom messages enter that same turn beside the user message, and a returned systemPrompt overrides that turn\\'s own assembly and resets at the next turn.',\n },\n agent_end: {\n level: 'partial',\n detail: 'The lifecycle boundary is mapped, but the reconstructed Pi message history is intentionally minimal.',\n },\n turn_end: {\n level: 'full',\n detail: 'Fires once per MODEL CALL, as in Pi — DSH calls that a step — carrying that call\\'s own assistant message and its own tool results, with turnIndex counting model calls from zero and resetting each prompt.',\n },\n message_start: {\n level: 'partial',\n detail: 'Durable user, assistant, and tool-result messages are mapped without Pi-specific provider metadata.',\n },\n message_end: {\n level: 'partial',\n detail: 'Durable messages are observed, but message replacement is not supported.',\n },\n message_update: {\n level: 'partial',\n detail: 'Projected from DSH assistant/chunk events with accumulated text; Pi\\'s full AgentMessage accumulation state is approximated.',\n },\n session_before_compact: {\n level: 'partial',\n detail: 'Projected from DSH compaction/start as a notification; cancel/replace cannot reach DSH\\'s compactor.',\n },\n session_compact: {\n level: 'partial',\n detail: 'Fires once per SUCCESSFUL compaction, from DSH\\'s summary event, with the summary rendered to the string Pi\\'s CompactionEntry declares. A manual compaction is identified as manual; DSH does not record which automatic trigger fired, so automatic ones report \"threshold\" and willRetry is always false.',\n },\n model_select: {\n level: 'partial',\n detail: 'Fired by setModel() and projected from request/header model changes in the durable log.',\n },\n thinking_level_select: {\n level: 'partial',\n detail: 'Fired by setThinkingLevel(); DSH-side reasoning changes surface through request/header projection.',\n },\n context: {\n level: 'partial',\n detail: 'Fires before each step with the full message projection; the transform applies to the step\\'s not-yet-entered messages (the slice packages rewrite), while already-entered history stays read-only under DSH\\'s append-only log.',\n },\n before_provider_request: {\n level: 'unsupported',\n detail: 'Provider payload mutation belongs in a native DSH LLM adapter; the handler is accepted but never fires.',\n },\n before_provider_headers: {\n level: 'unsupported',\n detail: 'Provider header mutation belongs in a native DSH LLM adapter; the handler is accepted but never fires.',\n },\n after_provider_response: {\n level: 'unsupported',\n detail: 'Provider response interception belongs in a native DSH LLM adapter; the handler is accepted but never fires.',\n },\n user_bash: OBSERVED_NEVER_FIRES('Pi\\'s ! command surface'),\n input: OBSERVED_NEVER_FIRES('raw Pi terminal input'),\n project_trust: {\n level: 'unsupported',\n detail: 'Project trust must remain owned by the DSH host; the handler is accepted but never consulted.',\n },\n resources_discover: {\n level: 'unsupported',\n detail: 'Dynamic resource discovery must be converted into DSH providers; the handler is accepted but never fires.',\n },\n session_before_switch: OBSERVED_NEVER_FIRES('Pi session switching'),\n session_before_fork: OBSERVED_NEVER_FIRES('Pi tree forking'),\n session_before_tree: OBSERVED_NEVER_FIRES('Pi session-tree navigation'),\n session_tree: OBSERVED_NEVER_FIRES('Pi session-tree navigation'),\n})\n\nexport function ruleForApi(method: string): Rule | undefined {\n return API_RULES[method]\n}\n\nexport function ruleForEvent(event: string): Rule {\n return EVENT_RULES[event] ?? {\n level: 'unsupported',\n detail: `Unknown Pi event ${JSON.stringify(event)} has no verified DSH mapping.`,\n }\n}\n\nexport function ruleForHostImport(packageName: string, importedName: string): Rule | undefined {\n const family = (PI_CODING_AGENT_PACKAGES as readonly string[]).includes(packageName)\n ? 'pi-coding-agent'\n : (PI_TUI_PACKAGES as readonly string[]).includes(packageName)\n ? 'pi-tui'\n : (PI_AI_PACKAGES as readonly string[]).includes(packageName) ? 'pi-ai' : undefined\n return family === undefined ? undefined : HOST_IMPORT_RULES[family]?.[importedName]\n}\n\nexport function ruleForContextProperty(property: string): Rule | undefined {\n return CONTEXT_RULES[property]\n}\n\nexport function ruleForUiContextProperty(property: string): Rule | undefined {\n return UI_CONTEXT_RULES[property]\n}\n","// Pi MCP configuration -> DSH mcp-client patch entries.\n//\n// Pi (via pi-mcp-adapter) reads the standard `mcpServers` files. DSH ships an\n// official MCP client (`@deepseek-ai/dsh-mcp-client`) configured through\n// cordis patch layers — so migration is config translation, not running Pi's\n// adapter code. This module reads Pi's documented six-layer precedence,\n// resolves `disabled` flags, and emits one patch entry per enabled server.\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { getAgentDir } from './compat/vendor/pi-config-shim.js'\n\ntype UnknownRecord = Record<string, unknown>\n\nexport interface PiMcpServer {\n name: string\n sourcePath: string\n transport: 'stdio' | 'streamable-http'\n command?: string\n args?: string[]\n env?: Record<string, string>\n cwd?: string\n url?: string\n headers?: Record<string, string>\n disabled: boolean\n}\n\nexport interface McpConversionWarning {\n server: string\n message: string\n}\n\nexport interface McpConversionResult {\n servers: PiMcpServer[]\n entries: UnknownRecord[]\n warnings: McpConversionWarning[]\n sources: string[]\n}\n\n/** Pi's documented config precedence, lowest to highest. */\nexport function piMcpConfigPaths(cwd: string): string[] {\n const home = homedir()\n return [\n join(home, '.config', 'mcp', 'mcp.json'),\n join(home, '.agents', 'mcp.json'),\n join(home, '.agents', 'mcp', 'mcp.json'),\n join(getAgentDir(), 'mcp.json'),\n join(cwd, '.mcp.json'),\n join(cwd, '.pi', 'mcp.json'),\n ]\n}\n\nfunction stringRecord(value: unknown): Record<string, string> | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined\n const entries = Object.entries(value).filter((entry): entry is [string, string] => typeof entry[1] === 'string')\n return entries.length === 0 ? undefined : Object.fromEntries(entries)\n}\n\nfunction parseServer(name: string, raw: unknown, sourcePath: string): PiMcpServer | undefined {\n if (typeof raw !== 'object' || raw === null) return undefined\n const record = raw as UnknownRecord\n const disabled = record.disabled === true\n if (typeof record.url === 'string') {\n return {\n name, sourcePath, transport: 'streamable-http', url: record.url,\n ...(stringRecord(record.headers) === undefined ? {} : { headers: stringRecord(record.headers)! }),\n disabled,\n }\n }\n if (typeof record.command === 'string') {\n return {\n name, sourcePath, transport: 'stdio', command: record.command,\n ...(Array.isArray(record.args) ? { args: record.args.map(String) } : {}),\n ...(stringRecord(record.env) === undefined ? {} : { env: stringRecord(record.env)! }),\n ...(typeof record.cwd === 'string' ? { cwd: record.cwd } : {}),\n disabled,\n }\n }\n return undefined\n}\n\nexport function collectPiMcpServers(cwd: string, extraPaths: string[] = []): { servers: Map<string, PiMcpServer>; sources: string[] } {\n const servers = new Map<string, PiMcpServer>()\n const sources: string[] = []\n for (const path of [...piMcpConfigPaths(cwd), ...extraPaths]) {\n if (!existsSync(path)) continue\n let parsed: unknown\n try {\n parsed = JSON.parse(readFileSync(path, 'utf8'))\n } catch {\n continue\n }\n const mcpServers = (parsed as UnknownRecord | undefined)?.mcpServers\n if (typeof mcpServers !== 'object' || mcpServers === null) continue\n sources.push(path)\n for (const [name, raw] of Object.entries(mcpServers)) {\n const record = raw as UnknownRecord | null\n const existing = servers.get(name)\n // Later (higher-precedence) layers override whole entries; a bare\n // `disabled` toggle updates the effective server from a lower layer.\n if (existing !== undefined && typeof record === 'object' && record !== null\n && record.command === undefined && record.url === undefined && typeof record.disabled === 'boolean') {\n servers.set(name, { ...existing, disabled: record.disabled, sourcePath: path })\n continue\n }\n const server = parseServer(name, raw, path)\n if (server !== undefined) servers.set(name, server)\n }\n }\n return { servers, sources }\n}\n\nconst SERVER_NAME_PATTERN = /^[A-Za-z0-9_-]{1,32}$/u\nconst ENV_REFERENCE_PATTERN = /^\\$\\{?([A-Za-z_][A-Za-z0-9_]*)\\}?$/u\nconst SECRETISH_KEY_PATTERN = /token|secret|key|password|credential/iu\n\ninterface JsExpression {\n __pi2dshJs: string\n}\n\nfunction js(expression: string): JsExpression {\n return { __pi2dshJs: expression }\n}\n\nfunction convertValueMap(\n server: string,\n kind: 'env' | 'headers',\n values: Record<string, string> | undefined,\n warnings: McpConversionWarning[],\n): Record<string, string | JsExpression> | undefined {\n if (values === undefined) return undefined\n const output: Record<string, string | JsExpression> = {}\n for (const [key, value] of Object.entries(values)) {\n const reference = ENV_REFERENCE_PATTERN.exec(value)\n if (reference !== null) {\n output[key] = js(`process.env.${reference[1]}`)\n continue\n }\n if (SECRETISH_KEY_PATTERN.test(key)) {\n warnings.push({\n server,\n message: `${kind}.${key} carries a literal value; move the secret to an environment variable and reference it as $NAME so the patch stays credential-free`,\n })\n }\n output[key] = value\n }\n return output\n}\n\nexport function convertPiMcpConfig(cwd: string, extraPaths: string[] = []): McpConversionResult {\n const { servers, sources } = collectPiMcpServers(cwd, extraPaths)\n const warnings: McpConversionWarning[] = []\n const entries: UnknownRecord[] = []\n for (const server of servers.values()) {\n if (server.disabled) {\n warnings.push({ server: server.name, message: 'skipped: disabled in Pi configuration' })\n continue\n }\n if (!SERVER_NAME_PATTERN.test(server.name)) {\n warnings.push({\n server: server.name,\n message: 'skipped: DSH serverName must match [A-Za-z0-9_-]{1,32}; rename the server in the Pi config',\n })\n continue\n }\n const config: UnknownRecord = { serverName: server.name, transport: server.transport }\n if (server.transport === 'stdio') {\n config.command = server.command\n if (server.args !== undefined) config.args = server.args\n const env = convertValueMap(server.name, 'env', server.env, warnings)\n if (env !== undefined) config.env = env\n if (server.cwd !== undefined) config.cwd = server.cwd\n } else {\n config.url = server.url\n const headers = convertValueMap(server.name, 'headers', server.headers, warnings)\n if (headers !== undefined) config.headers = headers\n }\n entries.push({ id: `mcp-${server.name}`, name: '@deepseek-ai/dsh-mcp-client', config })\n }\n return { servers: [...servers.values()], entries, warnings, sources }\n}\n\nfunction yamlScalar(value: unknown, indent: string): string {\n if (typeof value === 'object' && value !== null && '__pi2dshJs' in (value as JsExpression)) {\n return `!!js ${(value as JsExpression).__pi2dshJs}`\n }\n if (typeof value === 'string') {\n return /^[A-Za-z0-9@._\\/:-]+$/u.test(value) ? value : JSON.stringify(value)\n }\n if (Array.isArray(value)) {\n if (value.length === 0) return '[]'\n return `\\n${value.map(item => `${indent} - ${yamlScalar(item, `${indent} `)}`).join('\\n')}`\n }\n if (typeof value === 'object' && value !== null) {\n const record = value as UnknownRecord\n const keys = Object.keys(record)\n if (keys.length === 0) return '{}'\n return `\\n${keys.map(key => `${indent} ${key}: ${yamlScalar(record[key], `${indent} `)}`).join('\\n')}`\n }\n return String(value)\n}\n\n/** Render the converted entries as a cordis.patch.yml `insert` block. */\nexport function renderMcpPatch(result: McpConversionResult): string {\n if (result.entries.length === 0) return '# no enabled MCP servers found in Pi configuration\\n'\n const lines: string[] = ['- insert:']\n for (const entry of result.entries) {\n lines.push(` - id: ${String(entry.id)}`)\n lines.push(` name: '@deepseek-ai/dsh-mcp-client'`)\n lines.push(` inject: [tools]`)\n lines.push(` config:${yamlScalar(entry.config, ' ')}`)\n }\n return `${lines.join('\\n')}\\n`\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-bridge-CfyImWx4.mjs","names":["#path","#persist"],"sources":["../src/compat/vendor/pi-ai-abort.ts","../src/compat/vendor/pi-ai-credential-store.ts","../src/compat/vendor/pi-ai-diagnostics.ts","../src/compat/vendor/pi-ai-auth-resolve.ts","../src/compat/vendor/pi-oauth-adapt.ts","../src/oauth-bridge.ts"],"sourcesContent":["// @ts-nocheck — vendored Pi source (pi-ai utils/abort.js @0.84.1, MIT, see ./PI-LICENSE); unchanged.\nfunction abortReason(signal) {\n if (signal.reason !== undefined)\n return signal.reason;\n const error = new Error(\"The operation was aborted\");\n error.name = \"AbortError\";\n return error;\n}\n/** Create an operation-local signal for public APIs whose signal is optional. */\nexport function operationSignal(signal) {\n return signal ?? new AbortController().signal;\n}\n/**\n * Stop waiting for an operation when its signal aborts while continuing to\n * observe the abandoned promise so a later rejection is always handled.\n */\nexport function raceWithAbortSignal(operation, signal) {\n if (signal.aborted) {\n void operation.catch(() => { });\n return Promise.reject(abortReason(signal));\n }\n return new Promise((resolve, reject) => {\n let settled = false;\n const cleanup = () => signal.removeEventListener(\"abort\", onAbort);\n const onAbort = () => {\n if (settled)\n return;\n settled = true;\n cleanup();\n reject(abortReason(signal));\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n void operation.then((value) => {\n if (settled)\n return;\n settled = true;\n cleanup();\n resolve(value);\n }, (error) => {\n if (settled)\n return;\n settled = true;\n cleanup();\n reject(error);\n });\n if (signal.aborted)\n onAbort();\n });\n}\n//# sourceMappingURL=abort.js.map","// @ts-nocheck — vendored Pi source (pi-ai auth/credential-store.js @0.84.1, MIT, see ./PI-LICENSE); import remapped, logic unchanged.\nimport { operationSignal, raceWithAbortSignal } from './pi-ai-abort.js';\n/**\n * Default in-memory credential store. Apps inject persistent stores.\n * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.\n * Writes are serialized per provider through a promise chain.\n */\nexport class InMemoryCredentialStore {\n credentials = new Map();\n chains = new Map();\n /** Serialize tasks per provider id without releasing the chain before active work settles. */\n enqueue(providerId, task, options) {\n const signal = operationSignal(options?.signal);\n const previous = this.chains.get(providerId) ?? Promise.resolve();\n const queued = (async () => {\n await previous.catch(() => { });\n signal.throwIfAborted();\n return task();\n })();\n const tail = queued.catch(() => { });\n this.chains.set(providerId, tail);\n void tail.then(() => {\n if (this.chains.get(providerId) === tail)\n this.chains.delete(providerId);\n });\n return raceWithAbortSignal(queued, signal);\n }\n async read(providerId, options) {\n options?.signal?.throwIfAborted();\n return this.credentials.get(providerId);\n }\n async list(options) {\n options?.signal?.throwIfAborted();\n return [...this.credentials].map(([providerId, credential]) => ({ providerId, type: credential.type }));\n }\n modify(providerId, fn, options) {\n return this.enqueue(providerId, async () => {\n const current = this.credentials.get(providerId);\n const next = await fn(current);\n options?.signal?.throwIfAborted();\n if (next !== undefined)\n this.credentials.set(providerId, next);\n return next ?? current;\n }, options);\n }\n delete(providerId, options) {\n return this.enqueue(providerId, async () => {\n this.credentials.delete(providerId);\n }, options);\n }\n}\n//# sourceMappingURL=credential-store.js.map","// @ts-nocheck — vendored Pi source (pi-ai utils/diagnostics.js @0.84.1, MIT, see ./PI-LICENSE); unchanged.\nexport function formatThrownValue(value) {\n if (value instanceof Error)\n return value.message || value.name;\n if (typeof value === \"string\")\n return value;\n return String(value);\n}\nexport function extractDiagnosticError(error) {\n if (!(error instanceof Error))\n return { name: \"ThrownValue\", message: formatThrownValue(error) };\n const code = error.code;\n return {\n name: error.name || undefined,\n message: error.message || error.name,\n stack: error.stack,\n code: typeof code === \"string\" || typeof code === \"number\" ? code : undefined,\n };\n}\nexport function createAssistantMessageDiagnostic(type, error, details) {\n return { type, timestamp: Date.now(), error: extractDiagnosticError(error), details };\n}\nexport function appendAssistantMessageDiagnostic(message, diagnostic) {\n message.diagnostics = [...(message.diagnostics ?? []), diagnostic];\n}\n//# sourceMappingURL=diagnostics.js.map","// @ts-nocheck — vendored Pi source (pi-ai auth/resolve.js @0.84.1, MIT, see ./PI-LICENSE); imports remapped, logic unchanged\n// (double-checked-lock OAuth refresh with persistence, no silent env fallback).\nimport { operationSignal, raceWithAbortSignal } from './pi-ai-abort.js';\nimport { formatThrownValue } from './pi-ai-diagnostics.js';\nexport class ModelsError extends Error {\n code;\n constructor(code, message, options) {\n super(withCauseDetail(message, options?.cause), options);\n this.name = \"ModelsError\";\n this.code = code;\n }\n}\n/** Callers surface `error.message` only, so keep the underlying reason in it. */\nfunction withCauseDetail(message, cause) {\n if (cause === undefined || cause === null)\n return message;\n const detail = formatThrownValue(cause).trim();\n if (!detail || message.includes(detail))\n return message;\n return `${message}: ${detail}`;\n}\n/**\n * Auth resolution shared by the `Models` and `ImagesModels` collections.\n * A stored credential owns the provider: ambient/env is consulted only when\n * nothing is stored. No silent env fallback after a failed refresh or for a\n * credential type without a matching handler.\n */\nexport function resolveProviderAuth(provider, credentials, authContext, overrides) {\n const signal = operationSignal(overrides?.signal);\n return raceWithAbortSignal(resolveProviderAuthWithSignal(provider, credentials, authContext, overrides, signal), signal);\n}\nasync function resolveProviderAuthWithSignal(provider, credentials, authContext, overrides, signal) {\n signal.throwIfAborted();\n const requestAuthContext = overrides?.env ? overlayEnvAuthContext(authContext, overrides.env) : authContext;\n if (overrides?.apiKey !== undefined && provider.auth.apiKey) {\n return resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, {\n type: \"api_key\",\n key: overrides.apiKey,\n env: overrides.env,\n }, signal);\n }\n const stored = await readCredential(credentials, provider.id, signal);\n if (stored) {\n if (stored.type === \"oauth\" && provider.auth.oauth) {\n return resolveStoredOAuth(credentials, provider.id, provider.auth.oauth, stored, signal, overrides?.minOAuthValidityMs);\n }\n if (stored.type === \"api_key\" && provider.auth.apiKey) {\n const credential = overrides?.env ? { ...stored, env: { ...stored.env, ...overrides.env } } : stored;\n return resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, credential, signal);\n }\n return undefined;\n }\n // Ambient (env vars, AWS profiles, ADC files).\n return provider.auth.apiKey\n ? resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, undefined, signal)\n : undefined;\n}\nfunction overlayEnvAuthContext(base, env) {\n return {\n env: async (name) => env[name] || (await base.env(name)),\n fileExists: (path) => base.fileExists(path),\n };\n}\nconst DEFAULT_OAUTH_MINIMUM_VALIDITY_MS = 5 * 60 * 1000;\nconst DEFAULT_OAUTH_REFRESH_TIMEOUT_MS = 15_000;\n/**\n * OAuth resolution with double-checked locking: tokens with less than five\n * minutes remaining lock, re-check expiry under the lock, refresh once\n * globally, and persist the rotated credential before release.\n */\nasync function resolveStoredOAuth(credentials, providerId, oauth, stored, signal, minOAuthValidityMs) {\n const minimumValidityMs = Math.max(DEFAULT_OAUTH_MINIMUM_VALIDITY_MS, minOAuthValidityMs ?? 0);\n const expiresSoon = (credential) => Date.now() + minimumValidityMs >= credential.expires;\n let credential = stored;\n if (expiresSoon(credential)) {\n // Optimistic check said expired; the authoritative check runs under the lock.\n let post;\n try {\n post = await credentials.modify(providerId, async (current) => {\n if (current?.type !== \"oauth\")\n return undefined; // logged out meanwhile\n if (!expiresSoon(current))\n return undefined; // another process/request refreshed\n try {\n const refreshSignal = AbortSignal.any([\n signal,\n AbortSignal.timeout(DEFAULT_OAUTH_REFRESH_TIMEOUT_MS),\n ]);\n return await oauth.refresh(current, refreshSignal);\n }\n catch (error) {\n throw new ModelsError(\"oauth\", `OAuth refresh failed for ${providerId}`, { cause: error });\n }\n }, { signal });\n }\n catch (error) {\n if (error instanceof ModelsError)\n throw error;\n throw new ModelsError(\"auth\", `Credential store modify failed for ${providerId}`, { cause: error });\n }\n if (post?.type !== \"oauth\")\n return undefined; // logged out meanwhile\n credential = post;\n // The normal five-minute window triggers a refresh but does not impose a\n // provider contract. Explicit callers (such as bearer-token export) do\n // require the requested minimum after the refresh.\n if (minOAuthValidityMs !== undefined && expiresSoon(credential)) {\n throw new ModelsError(\"oauth\", `OAuth refresh returned a token that expires too soon for ${providerId}`);\n }\n }\n try {\n return { auth: await oauth.toAuth(credential), source: \"OAuth\" };\n }\n catch (error) {\n throw new ModelsError(\"oauth\", `OAuth auth derivation failed for ${providerId}`, { cause: error });\n }\n}\nasync function resolveApiKey(authContext, apiKey, providerId, credential, signal) {\n try {\n return await apiKey.resolve({ ctx: authContext, credential, signal });\n }\n catch (error) {\n throw new ModelsError(\"auth\", `API key auth failed for provider ${providerId}`, { cause: error });\n }\n}\nasync function readCredential(credentials, providerId, signal) {\n try {\n return await credentials.read(providerId, { signal });\n }\n catch (error) {\n throw new ModelsError(\"auth\", `Credential store read failed for ${providerId}`, { cause: error });\n }\n}\n//# sourceMappingURL=resolve.js.map","// @ts-nocheck — vendored Pi source excerpt (pi-coding-agent core/provider-composer.js adaptOAuth @0.84.1, MIT, see ./PI-LICENSE); logic unchanged.\n// The official two-generation adapter: extension oauth callbacks (onAuth/onDeviceCode/onPrompt/onSelect)\n// over the pi-ai interaction surface (prompt/notify/signal), plus refresh and toAuth->getApiKey.\nexport function adaptOAuth(config) {\n return {\n name: config.name,\n isSubscription: config.isSubscription,\n login: async (callbacks) => {\n const credential = await config.login({\n onAuth: (info) => callbacks.notify({ type: \"auth_url\", ...info }),\n onDeviceCode: (info) => callbacks.notify({ type: \"device_code\", ...info }),\n onPrompt: (prompt) => callbacks.prompt({ type: \"text\", ...prompt }),\n onProgress: (message) => callbacks.notify({ type: \"progress\", message }),\n onManualCodeInput: () => callbacks.prompt({ type: \"manual_code\", message: \"Paste the authorization code\" }),\n onSelect: (prompt) => callbacks.prompt({ type: \"select\", ...prompt }),\n signal: callbacks.signal,\n });\n return { ...credential, type: \"oauth\" };\n },\n refresh: async (credential, signal) => ({ ...(await config.refreshToken(credential, signal)), type: \"oauth\" }),\n toAuth: async (credential) => ({ apiKey: config.getApiKey(credential) }),\n };\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { mkdir, rename, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { InMemoryCredentialStore } from './compat/vendor/pi-ai-credential-store.js'\nimport { resolveProviderAuth } from './compat/vendor/pi-ai-auth-resolve.js'\nimport { adaptOAuth } from './compat/vendor/pi-oauth-adapt.js'\n\ntype UnknownRecord = Record<string, unknown>\n\n// The interactive OAuth host seam, four layers with one owner each:\n// L1 protocol — the package's own oauth.login/refreshToken/getApiKey code\n// runs verbatim (device-code, auth-code, rotation). The\n// bridge implements zero protocol.\n// L2 interaction— Pi's official adaptOAuth (vendored) turns the package's\n// callbacks into prompt/notify events; this file routes\n// those onto the Pi ui surface, which pi2dsh already maps\n// to DSH userQuestions with real waits.\n// L3 credentials— Pi's auth.json contract: one file keyed by provider id,\n// 0600, atomic replace, per-provider serialized writes\n// (the vendored InMemoryCredentialStore chain), refresh via\n// Pi's vendored double-checked-lock resolver.\n// L4 routing — resolveOAuthApiKey yields the request key for dsh-llm's\n// one-shot credential seam; tokens never enter DSH settings.\n\nexport class FileCredentialStore extends InMemoryCredentialStore {\n readonly #path: string\n\n constructor(path: string) {\n super()\n this.#path = path\n try {\n const data = JSON.parse(readFileSync(path, 'utf8')) as Record<string, UnknownRecord>\n for (const [providerId, credential] of Object.entries(data)) {\n ;(this as unknown as { credentials: Map<string, unknown> }).credentials.set(providerId, credential)\n }\n } catch {\n // Missing or unreadable auth.json starts empty, exactly like Pi.\n }\n }\n\n get path(): string {\n return this.#path\n }\n\n async #persist(): Promise<void> {\n const credentials = (this as unknown as { credentials: Map<string, unknown> }).credentials\n const data = Object.fromEntries(credentials)\n await mkdir(dirname(this.#path), { recursive: true })\n // Atomic replace so a crash mid-write never truncates the store; 0600 so\n // tokens stay owner-readable only. Same contract Pi's file store keeps.\n const temp = `${this.#path}.tmp-${process.pid}-${Math.floor(Math.random() * 1e9).toString(36)}`\n await writeFile(temp, `${JSON.stringify(data, null, 2)}\\n`, { mode: 0o600 })\n await rename(temp, this.#path)\n }\n\n override modify(providerId: string, fn: (current: unknown) => unknown, options?: UnknownRecord): Promise<unknown> {\n // The vendored per-provider chain already serializes writers; persisting\n // inside the chained task keeps disk order identical to memory order.\n return super.modify(providerId, async (current: unknown) => {\n const next = await fn(current)\n if (next !== undefined) {\n const credentials = (this as unknown as { credentials: Map<string, unknown> }).credentials\n credentials.set(providerId, next)\n await this.#persist()\n }\n return next\n }, options)\n }\n\n override delete(providerId: string, options?: UnknownRecord): Promise<void> {\n return super.delete(providerId, options).then(() => this.#persist()) as Promise<void>\n }\n}\n\nexport interface OAuthUiSurface {\n input(title: unknown, placeholder?: unknown): Promise<string | undefined>\n select(title: unknown, options: unknown[]): Promise<string | undefined>\n notify(message: unknown): void\n}\n\ninterface OAuthPromptEvent {\n type: 'text' | 'manual_code' | 'select'\n message: string\n placeholder?: string\n options?: Array<{ id: string, label: string }>\n}\n\ninterface OAuthNotifyEvent {\n type: 'auth_url' | 'device_code' | 'progress'\n url?: string\n instructions?: string\n userCode?: string\n verificationUri?: string\n message?: string\n}\n\n// The pi-ai interaction surface ({prompt, notify, signal}) over the Pi ui\n// surface pi2dsh already maps to DSH userQuestions.\nexport function oauthInteraction(ui: OAuthUiSurface, signal?: AbortSignal): {\n prompt(prompt: OAuthPromptEvent): Promise<string | undefined>\n notify(event: OAuthNotifyEvent): void\n signal: AbortSignal\n} {\n // Pi hosts always hand flows a live signal; flows attach abort listeners\n // unconditionally, so an absent caller signal becomes a never-aborting one.\n const effectiveSignal = signal ?? new AbortController().signal\n return {\n signal: effectiveSignal,\n async prompt(prompt) {\n if (prompt.type === 'select') {\n const options = prompt.options ?? []\n const picked = await ui.select(prompt.message, options.map(option => option.label))\n return options.find(option => option.label === picked)?.id ?? picked\n }\n return ui.input(prompt.message, prompt.placeholder)\n },\n notify(event) {\n if (event.type === 'auth_url') {\n ui.notify(`Open this URL to authorize: ${event.url}${event.instructions !== undefined ? `\\n${event.instructions}` : ''}`)\n } else if (event.type === 'device_code') {\n ui.notify(`Visit ${event.verificationUri} and enter code ${event.userCode}`)\n } else if (event.message !== undefined) {\n ui.notify(event.message)\n }\n },\n }\n}\n\nfunction oauthConfigOf(providerConfig: UnknownRecord | undefined): UnknownRecord | undefined {\n // Extension-generation configs carry oauth at the top level; pi-ai\n // createProvider() objects carry it under auth.oauth. Pi accepts both.\n const oauth = providerConfig?.oauth\n ?? (providerConfig?.auth as UnknownRecord | undefined)?.oauth\n return typeof oauth === 'object' && oauth !== null && typeof (oauth as UnknownRecord).login === 'function'\n ? oauth as UnknownRecord\n : undefined\n}\n\n// Pi accepts both oauth generations: pi-ai native flows carry toAuth and take\n// the interaction surface directly; extension configs carry getApiKey and go\n// through Pi's adaptOAuth (vendored). Same acceptance here.\nfunction oauthAdapterOf(oauthConfig: UnknownRecord): {\n login(interaction: unknown): Promise<UnknownRecord>\n refresh(credential: unknown, signal?: AbortSignal): Promise<UnknownRecord>\n toAuth(credential: unknown): Promise<UnknownRecord>\n} {\n if (typeof oauthConfig.toAuth === 'function') {\n return oauthConfig as never\n }\n return adaptOAuth(oauthConfig) as never\n}\n\nexport function providerSupportsOAuth(providerConfig: UnknownRecord | undefined): boolean {\n return oauthConfigOf(providerConfig) !== undefined\n}\n\n// Pi models.login semantics: find the provider's oauth surface, run the\n// package's own login through the vendored adapter, persist through the\n// store's serialized modify.\nexport async function loginPiProvider(options: {\n providerId: string\n providerName?: string\n providerConfig: UnknownRecord\n store: FileCredentialStore\n ui: OAuthUiSurface\n signal?: AbortSignal\n}): Promise<UnknownRecord> {\n const oauthConfig = oauthConfigOf(options.providerConfig)\n if (oauthConfig === undefined) {\n throw new Error(`${options.providerName ?? options.providerId} does not support oauth login`)\n }\n const adapter = oauthAdapterOf(oauthConfig)\n const credential = await adapter.login(oauthInteraction(options.ui, options.signal))\n await options.store.modify(options.providerId, async () => credential)\n return credential\n}\n\n// Pi's resolveProviderAuth over the stored credential: five-minute expiry\n// window, double-checked-lock refresh through the package's own refreshToken,\n// rotated credential persisted before release, key derived by the package's\n// own getApiKey. Returns undefined when nothing is stored.\nexport async function resolveOAuthApiKey(options: {\n providerId: string\n providerName?: string\n providerConfig: UnknownRecord\n store: FileCredentialStore\n signal?: AbortSignal\n}): Promise<string | undefined> {\n const oauthConfig = oauthConfigOf(options.providerConfig)\n if (oauthConfig === undefined) return undefined\n const provider = {\n id: options.providerId,\n name: options.providerName ?? options.providerId,\n auth: { oauth: oauthAdapterOf(oauthConfig) },\n }\n const resolved = await resolveProviderAuth(\n provider,\n options.store,\n { env: async () => undefined },\n options.signal !== undefined ? { signal: options.signal } : undefined,\n ) as { auth?: { apiKey?: string } } | undefined\n return resolved?.auth?.apiKey\n}\n\nexport async function storedOAuthCredential(store: FileCredentialStore, providerId: string): Promise<UnknownRecord | undefined> {\n const stored = await store.read(providerId, undefined) as UnknownRecord | undefined\n return stored?.type === 'oauth' ? stored : undefined\n}\n\n// Pi's FULL getProviderAuth precedence over the vendored resolver — stored\n// OAuth (double-checked-lock refresh), then stored api_key, then the\n// provider's own auth.apiKey ambient resolution (its resolve() reads env vars\n// and probes credential files through the auth context). The package's\n// resolve code runs verbatim; the bridge supplies only the context.\nexport async function resolvePiProviderAuth(options: {\n providerId: string\n providerName?: string\n providerConfig: UnknownRecord\n store: FileCredentialStore\n signal?: AbortSignal\n}): Promise<{ auth?: UnknownRecord, source?: string } | undefined> {\n const oauthConfig = oauthConfigOf(options.providerConfig)\n const declaredApiKey = (options.providerConfig.auth as UnknownRecord | undefined)?.apiKey\n if (oauthConfig === undefined && declaredApiKey === undefined) return undefined\n const auth: UnknownRecord = {}\n if (oauthConfig !== undefined) auth.oauth = oauthAdapterOf(oauthConfig)\n if (declaredApiKey !== undefined) auth.apiKey = declaredApiKey\n const provider = { id: options.providerId, name: options.providerName ?? options.providerId, auth }\n return await resolveProviderAuth(\n provider,\n options.store,\n {\n env: async (name: string) => process.env[name],\n fileExists: async (path: string) => existsSync(path),\n },\n options.signal !== undefined ? { signal: options.signal } : undefined,\n ) as { auth?: UnknownRecord, source?: string } | undefined\n}\n"],"mappings":"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"}
|