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.
Files changed (44) hide show
  1. package/README.md +47 -10
  2. package/README.zh.md +39 -8
  3. package/dist/{analyzer-CEjVQKXA.mjs → analyzer-CXNbeBAe.mjs} +2 -2
  4. package/dist/{analyzer-CEjVQKXA.mjs.map → analyzer-CXNbeBAe.mjs.map} +1 -1
  5. package/dist/cli.mjs +2 -2
  6. package/dist/client.js +525 -0
  7. package/dist/compat/pi-ai.d.mts +36 -1
  8. package/dist/compat/pi-ai.d.mts.map +1 -1
  9. package/dist/compat/pi-ai.mjs +2 -2
  10. package/dist/compat/pi-coding-agent.d.mts +2 -1411
  11. package/dist/compat/pi-coding-agent.mjs +1 -1
  12. package/dist/compat/pi-tui.mjs +1 -1
  13. package/dist/{oauth-bridge-CfyImWx4.mjs → credentials-oauth-BakY-0PA.mjs} +172 -13
  14. package/dist/credentials-oauth-BakY-0PA.mjs.map +1 -0
  15. package/dist/credentials-oauth.mjs +1 -89
  16. package/dist/host.mjs +4 -2
  17. package/dist/host.mjs.map +1 -1
  18. package/dist/index.d.mts +16 -4
  19. package/dist/index.d.mts.map +1 -1
  20. package/dist/index.mjs +3 -3
  21. package/dist/mcp-config-CZepacin.mjs +766 -0
  22. package/dist/mcp-config-CZepacin.mjs.map +1 -0
  23. package/dist/{pi-ai-Dyg4zyLZ.mjs → pi-ai-BA3V_J0V.mjs} +40 -2
  24. package/dist/{pi-ai-Dyg4zyLZ.mjs.map → pi-ai-BA3V_J0V.mjs.map} +1 -1
  25. package/dist/pi-coding-agent-B0PT23gE.d.mts +1412 -0
  26. package/dist/pi-coding-agent-B0PT23gE.d.mts.map +1 -0
  27. package/dist/{pi-coding-agent-CYnmeJEx.mjs → pi-coding-agent-D9skobb6.mjs} +0 -0
  28. package/dist/pi-coding-agent-D9skobb6.mjs.map +1 -0
  29. package/dist/{pi-tui-5CYLcj-_.mjs → pi-tui-DruSeKmd.mjs} +3 -3
  30. package/dist/pi-tui-DruSeKmd.mjs.map +1 -0
  31. package/dist/{runtime-DsPaznXJ.mjs → runtime-DH0zEUpu.mjs} +1075 -67
  32. package/dist/runtime-DH0zEUpu.mjs.map +1 -0
  33. package/dist/runtime.d.mts +594 -0
  34. package/dist/runtime.d.mts.map +1 -1
  35. package/dist/runtime.mjs +1 -1
  36. package/package.json +15 -4
  37. package/dist/compat/pi-coding-agent.d.mts.map +0 -1
  38. package/dist/credentials-oauth.mjs.map +0 -1
  39. package/dist/mcp-config-DHkfjdvX.mjs +0 -707
  40. package/dist/mcp-config-DHkfjdvX.mjs.map +0 -1
  41. package/dist/oauth-bridge-CfyImWx4.mjs.map +0 -1
  42. package/dist/pi-coding-agent-CYnmeJEx.mjs.map +0 -1
  43. package/dist/pi-tui-5CYLcj-_.mjs.map +0 -1
  44. package/dist/runtime-DsPaznXJ.mjs.map +0 -1
package/dist/client.js ADDED
@@ -0,0 +1,525 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "pi2dsh",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let react = require("react");
8
+ //#region src/ansi.ts
9
+ /** The 8 base ANSI colours, in SGR order, as CSS. */
10
+ const BASE = [
11
+ "#000000",
12
+ "#cd3131",
13
+ "#0dbc79",
14
+ "#e5e510",
15
+ "#2472c8",
16
+ "#bc3fbc",
17
+ "#11a8cd",
18
+ "#e5e5e5"
19
+ ];
20
+ /** Their bright variants (SGR 90-97 / 100-107). */
21
+ const BRIGHT = [
22
+ "#666666",
23
+ "#f14c4c",
24
+ "#23d18b",
25
+ "#f5f543",
26
+ "#3b8eea",
27
+ "#d670d6",
28
+ "#29b8db",
29
+ "#ffffff"
30
+ ];
31
+ /**
32
+ * Resolve one xterm-256 index to CSS.
33
+ * @param index - the palette index (0-255).
34
+ * @returns a CSS colour.
35
+ */
36
+ function ansi256(index) {
37
+ if (index < 8) return BASE[index];
38
+ if (index < 16) return BRIGHT[index - 8];
39
+ if (index < 232) {
40
+ const step = (value) => value === 0 ? 0 : value * 40 + 55;
41
+ const rest = index - 16;
42
+ return `rgb(${step(Math.floor(rest / 36))}, ${step(Math.floor(rest / 6) % 6)}, ${step(rest % 6)})`;
43
+ }
44
+ const grey = (index - 232) * 10 + 8;
45
+ return `rgb(${grey}, ${grey}, ${grey})`;
46
+ }
47
+ const SGR = String.raw`\[([0-9;]*)m`;
48
+ /**
49
+ * Split text into styled runs.
50
+ *
51
+ * Unrecognised escapes are dropped rather than printed — a code this does not
52
+ * model is still not something a reader should see as text. Text with no
53
+ * escapes comes back as a single unstyled run, so callers need no special case.
54
+ * @param text - possibly carrying SGR escapes.
55
+ * @returns the runs, in order; empty only for empty input.
56
+ */
57
+ function parseAnsi(text) {
58
+ const pattern = new RegExp(SGR, "gu");
59
+ const runs = [];
60
+ let style = {};
61
+ let at = 0;
62
+ const push = (piece) => {
63
+ if (piece.length > 0) runs.push({
64
+ text: piece,
65
+ style: { ...style }
66
+ });
67
+ };
68
+ for (let match = pattern.exec(text); match !== null; match = pattern.exec(text)) {
69
+ push(text.slice(at, match.index));
70
+ at = match.index + match[0].length;
71
+ const codes = (match[1] ?? "").split(";").filter((part) => part !== "").map(Number);
72
+ if (codes.length === 0) style = {};
73
+ for (let index = 0; index < codes.length; index += 1) {
74
+ const code = codes[index];
75
+ if (code === 0) style = {};
76
+ else if (code === 1) style.fontWeight = "bold";
77
+ else if (code === 2) style.opacity = "0.7";
78
+ else if (code === 3) style.fontStyle = "italic";
79
+ else if (code === 4) style.textDecoration = "underline";
80
+ else if (code === 39) delete style.color;
81
+ else if (code === 49) delete style.backgroundColor;
82
+ else if (code >= 30 && code <= 37) style.color = BASE[code - 30];
83
+ else if (code >= 90 && code <= 97) style.color = BRIGHT[code - 90];
84
+ else if (code >= 40 && code <= 47) style.backgroundColor = BASE[code - 40];
85
+ else if (code >= 100 && code <= 107) style.backgroundColor = BRIGHT[code - 100];
86
+ else if (code === 38 || code === 48) {
87
+ const property = code === 38 ? "color" : "backgroundColor";
88
+ const kind = codes[index + 1];
89
+ if (kind === 5 && codes.length > index + 2) {
90
+ style[property] = ansi256(codes[index + 2]);
91
+ index += 2;
92
+ } else if (kind === 2 && codes.length > index + 4) {
93
+ style[property] = `rgb(${codes[index + 2]}, ${codes[index + 3]}, ${codes[index + 4]})`;
94
+ index += 4;
95
+ }
96
+ }
97
+ }
98
+ }
99
+ push(text.slice(at));
100
+ return runs;
101
+ }
102
+ /**
103
+ * Whether text carries any SGR escape.
104
+ * @param text - the text to check.
105
+ * @returns true when at least one escape is present.
106
+ */
107
+ function hasAnsi(text) {
108
+ return new RegExp(SGR, "u").test(text);
109
+ }
110
+ //#endregion
111
+ //#region src/client.ts
112
+ /** Services this half needs before it can take a seat. */
113
+ const inject = ["slots", "inputTriggers"];
114
+ const POLL_MS = 1e3;
115
+ const EMPTY = {
116
+ threads: [],
117
+ surfaces: [],
118
+ entries: []
119
+ };
120
+ /**
121
+ * One poller per session, shared by every seat this package takes.
122
+ *
123
+ * Four components read the same payload; four independent timers would be four
124
+ * requests a second for one answer.
125
+ */
126
+ const subscribers = /* @__PURE__ */ new Map();
127
+ const latest = /* @__PURE__ */ new Map();
128
+ const timers = /* @__PURE__ */ new Map();
129
+ /**
130
+ * Subscribe to one session's browser state.
131
+ * @param session - session id to poll for.
132
+ * @param notify - called with each payload, and immediately with the last one.
133
+ * @returns an unsubscribe function that stops the timer with the last reader.
134
+ */
135
+ function watch(session, notify) {
136
+ const readers = subscribers.get(session) ?? /* @__PURE__ */ new Set();
137
+ readers.add(notify);
138
+ subscribers.set(session, readers);
139
+ const cached = latest.get(session);
140
+ if (cached !== void 0) notify(cached);
141
+ if (!timers.has(session)) {
142
+ const poll = async () => {
143
+ try {
144
+ const response = await fetch(`/pi2dsh/browser-state?session=${encodeURIComponent(session)}`);
145
+ if (!response.ok) return;
146
+ const payload = await response.json();
147
+ const state = {
148
+ threads: Array.isArray(payload.threads) ? payload.threads : [],
149
+ surfaces: Array.isArray(payload.surfaces) ? payload.surfaces : [],
150
+ entries: Array.isArray(payload.entries) ? payload.entries : [],
151
+ ...payload.draft === void 0 ? {} : { draft: payload.draft }
152
+ };
153
+ latest.set(session, state);
154
+ for (const reader of subscribers.get(session) ?? []) reader(state);
155
+ } catch {}
156
+ };
157
+ poll();
158
+ timers.set(session, window.setInterval(() => {
159
+ poll();
160
+ }, POLL_MS));
161
+ }
162
+ return () => {
163
+ const live = subscribers.get(session);
164
+ if (live === void 0) return;
165
+ live.delete(notify);
166
+ if (live.size > 0) return;
167
+ subscribers.delete(session);
168
+ const timer = timers.get(session);
169
+ if (timer !== void 0) window.clearInterval(timer);
170
+ timers.delete(session);
171
+ latest.delete(session);
172
+ };
173
+ }
174
+ /**
175
+ * React binding for {@link watch}.
176
+ * @param session - session id, or undefined while none is selected.
177
+ * @returns the latest payload for that session.
178
+ */
179
+ function useBrowserState(session) {
180
+ const [state, setState] = (0, react.useState)(EMPTY);
181
+ (0, react.useEffect)(() => {
182
+ if (session === void 0 || session === "") {
183
+ setState(EMPTY);
184
+ return;
185
+ }
186
+ return watch(session, setState);
187
+ }, [session]);
188
+ return state;
189
+ }
190
+ /** The working keys Pi's setWorkingVisible gates: hidden while hidden. */
191
+ const WORKING_KEYS = [
192
+ "workingMessage",
193
+ "workingIndicator",
194
+ "hiddenThinkingLabel"
195
+ ];
196
+ /** Every value packages have set for one simple surface, in package order. */
197
+ function valuesFor(surfaces, key) {
198
+ const out = [];
199
+ for (const surface of surfaces) {
200
+ if (WORKING_KEYS.includes(key) && !surface.workingVisible) continue;
201
+ const text = surface.values[key];
202
+ if (text !== void 0) out.push({
203
+ owner: surface.package ?? "pi",
204
+ text
205
+ });
206
+ }
207
+ return out;
208
+ }
209
+ /** Every status entry, package by package, then key, in registration order. */
210
+ function statusesFor(surfaces) {
211
+ const out = [];
212
+ for (const surface of surfaces) for (const [key, text] of Object.entries(surface.statuses)) out.push({
213
+ owner: surface.package ?? "pi",
214
+ key,
215
+ text
216
+ });
217
+ return out;
218
+ }
219
+ /** Every widget, package by package, then key, in registration order. */
220
+ function widgetsFor(surfaces) {
221
+ const out = [];
222
+ for (const surface of surfaces) for (const [key, text] of Object.entries(surface.widgets)) out.push({
223
+ owner: surface.package ?? "pi",
224
+ key,
225
+ text
226
+ });
227
+ return out;
228
+ }
229
+ const styles = {
230
+ panel: {
231
+ position: "fixed",
232
+ right: "20px",
233
+ bottom: "108px",
234
+ zIndex: 40,
235
+ width: "340px",
236
+ maxHeight: "48vh",
237
+ display: "flex",
238
+ flexDirection: "column",
239
+ pointerEvents: "auto",
240
+ overflow: "hidden",
241
+ borderRadius: "12px",
242
+ border: "1px solid rgba(120,120,130,0.28)",
243
+ background: "var(--dsh-color-bg-elevated, rgba(24,24,27,0.96))",
244
+ color: "var(--dsh-color-text, #fafafa)",
245
+ boxShadow: "0 12px 32px rgba(0,0,0,0.32)",
246
+ font: "400 13px/1.55 system-ui, -apple-system, sans-serif"
247
+ },
248
+ header: {
249
+ display: "flex",
250
+ alignItems: "center",
251
+ justifyContent: "space-between",
252
+ gap: "8px",
253
+ padding: "10px 12px",
254
+ borderBottom: "1px solid rgba(120,120,130,0.22)",
255
+ fontWeight: 500,
256
+ fontSize: "12px",
257
+ letterSpacing: "0.01em"
258
+ },
259
+ badge: {
260
+ opacity: .6,
261
+ fontWeight: 400
262
+ },
263
+ body: {
264
+ padding: "10px 12px",
265
+ overflowY: "auto",
266
+ display: "flex",
267
+ flexDirection: "column",
268
+ gap: "10px"
269
+ },
270
+ role: {
271
+ fontSize: "11px",
272
+ textTransform: "uppercase",
273
+ letterSpacing: "0.06em",
274
+ opacity: .55
275
+ },
276
+ text: {
277
+ whiteSpace: "pre-wrap",
278
+ wordBreak: "break-word"
279
+ },
280
+ close: {
281
+ cursor: "pointer",
282
+ opacity: .55,
283
+ background: "none",
284
+ border: "none",
285
+ color: "inherit",
286
+ font: "inherit"
287
+ },
288
+ pillStack: {
289
+ position: "fixed",
290
+ right: "20px",
291
+ bottom: "20px",
292
+ zIndex: 39,
293
+ display: "flex",
294
+ flexDirection: "column",
295
+ alignItems: "flex-end",
296
+ gap: "6px",
297
+ pointerEvents: "none"
298
+ },
299
+ pill: {
300
+ pointerEvents: "auto",
301
+ padding: "5px 10px",
302
+ borderRadius: "999px",
303
+ background: "var(--dsh-color-bg-elevated, rgba(24,24,27,0.92))",
304
+ color: "var(--dsh-color-text, #fafafa)",
305
+ border: "1px solid rgba(120,120,130,0.28)",
306
+ font: "500 11px/1.4 system-ui, sans-serif",
307
+ whiteSpace: "pre-wrap"
308
+ },
309
+ inline: {
310
+ font: "400 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace",
311
+ whiteSpace: "pre-wrap",
312
+ opacity: .85
313
+ },
314
+ strip: {
315
+ display: "flex",
316
+ flexDirection: "column",
317
+ gap: "4px",
318
+ padding: "4px 2px"
319
+ }
320
+ };
321
+ /**
322
+ * The frame-wide seat: the side-conversation panel, plus whatever packages
323
+ * pinned frame-wide — transient title and Pi's status entries, as pills.
324
+ * @param props - the global standard kit every root slot component receives.
325
+ */
326
+ function OverlaySurfaces({ useSessions }) {
327
+ const { threads, surfaces } = useBrowserState(useSessions((state) => state.current));
328
+ const [dismissed, setDismissed] = (0, react.useState)([]);
329
+ const shown = threads.filter((thread) => !dismissed.includes(thread.id));
330
+ const pills = [...valuesFor(surfaces, "title").map((entry) => ({
331
+ ...entry,
332
+ key: "title"
333
+ })), ...statusesFor(surfaces)];
334
+ if (shown.length === 0 && pills.length === 0) return null;
335
+ return (0, react.createElement)("div", null, pills.length === 0 ? null : (0, react.createElement)("div", {
336
+ style: styles.pillStack,
337
+ "data-pi2dsh": "pills"
338
+ }, ...pills.map((pill, index) => (0, react.createElement)("div", {
339
+ key: `${pill.owner}-${pill.key}-${index}`,
340
+ style: styles.pill,
341
+ title: pill.owner
342
+ }, ansiText(pill.text)))), shown.length === 0 ? null : (0, react.createElement)("div", {
343
+ "data-pi2dsh": "side-panel",
344
+ style: styles.panel
345
+ }, ...shown.map((thread) => (0, react.createElement)("div", {
346
+ key: thread.id,
347
+ style: { display: "contents" }
348
+ }, (0, react.createElement)("div", { style: styles.header }, (0, react.createElement)("span", null, thread.label), (0, react.createElement)("span", { style: styles.badge }, thread.running ? "running" : `${thread.messages.length} msg`), (0, react.createElement)("button", {
349
+ style: styles.close,
350
+ title: "Hide",
351
+ onClick: () => setDismissed((list) => [...list, thread.id])
352
+ }, "×")), (0, react.createElement)("div", { style: styles.body }, ...thread.messages.map((message, index) => (0, react.createElement)("div", { key: index }, (0, react.createElement)("div", { style: styles.role }, message.role), (0, react.createElement)("div", { style: styles.text }, message.text))))))));
353
+ }
354
+ /**
355
+ * One session-scoped seat rendering a set of surfaces as text.
356
+ * @param marker - the data-pi2dsh value, so an e2e run can address the seat.
357
+ * @param valueKeys - which simple value surfaces this seat shows.
358
+ * @param opts - whether the seat also shows widgets (keyed string arrays).
359
+ * @returns a slot component.
360
+ */
361
+ /**
362
+ * Render text that may carry ANSI colour into styled spans.
363
+ *
364
+ * Parsing lives in ./ansi.js so it can be tested without a DOM; this half
365
+ * only turns runs into elements. Text with no escapes returns as a plain
366
+ * string, so the common case adds no wrappers.
367
+ * @param text - the seat text, possibly with SGR escapes.
368
+ * @returns react children.
369
+ */
370
+ function ansiText(text) {
371
+ if (!hasAnsi(text)) return text;
372
+ return parseAnsi(text).map((run, index) => Object.keys(run.style).length === 0 ? run.text : (0, react.createElement)("span", {
373
+ key: `ansi-${index}`,
374
+ style: run.style
375
+ }, run.text));
376
+ }
377
+ function textSeat(marker, valueKeys, opts = {}) {
378
+ return function TextSeat({ sessionId }) {
379
+ const { surfaces } = useBrowserState(sessionId);
380
+ const entries = [...valueKeys.flatMap((key) => valuesFor(surfaces, key)), ...opts.widgets === true ? widgetsFor(surfaces) : []];
381
+ if (entries.length === 0) return null;
382
+ return (0, react.createElement)("div", {
383
+ "data-pi2dsh": marker,
384
+ style: styles.strip
385
+ }, ...entries.map((entry, index) => (0, react.createElement)("div", {
386
+ key: `${entry.owner}-${index}`,
387
+ style: styles.inline,
388
+ title: entry.owner
389
+ }, ansiText(entry.text))));
390
+ };
391
+ }
392
+ /**
393
+ * Custom entries a package appended and renders itself.
394
+ *
395
+ * They live in pi2dsh's sidecar, not DSH's durable log — the host has no
396
+ * channel for event types declared outside the harness — so the host's own
397
+ * conversation view cannot show them. This seat is where a package's own
398
+ * entries become visible, drawn by the package's registered renderer.
399
+ * @param props - the session standard kit.
400
+ * @returns the entry strip, or null when the package appended none.
401
+ */
402
+ function EntryStrip({ sessionId }) {
403
+ const { entries } = useBrowserState(sessionId);
404
+ if (entries.length === 0) return null;
405
+ return (0, react.createElement)("div", {
406
+ "data-pi2dsh": "entries",
407
+ style: styles.strip
408
+ }, ...entries.map((entry) => (0, react.createElement)("div", {
409
+ key: entry.id,
410
+ style: styles.inline,
411
+ title: `${entry.package ?? "pi"} · ${entry.customType}`
412
+ }, ansiText(entry.text))));
413
+ }
414
+ /**
415
+ * The composer half of Pi's editor calls.
416
+ *
417
+ * `inputActions` is part of the session standard kit — every session-scoped
418
+ * slot component receives it — so a package's `setEditorText`/`pasteToEditor`
419
+ * reaches the real composer instead of a buffer nobody reads. The traffic is
420
+ * two-way on purpose: the live draft is reported back so a package's
421
+ * `getEditorText` reads what the user actually has, not only its own last
422
+ * write.
423
+ * @param props - the session standard kit (state hook plus input actions).
424
+ * @returns nothing rendered; this seat exists for the effects.
425
+ */
426
+ function ComposerBridge({ sessionId, useInput, inputActions }) {
427
+ const { draft } = useBrowserState(sessionId);
428
+ const live = useInput === void 0 ? "" : useInput((state) => state.draft);
429
+ const [appliedRev, setAppliedRev] = (0, react.useState)(0);
430
+ (0, react.useEffect)(() => {
431
+ if (draft === void 0 || inputActions === void 0) return;
432
+ if (draft.rev <= appliedRev) return;
433
+ setAppliedRev(draft.rev);
434
+ inputActions.setDraft(draft.text);
435
+ }, [
436
+ draft?.rev,
437
+ draft?.text,
438
+ inputActions,
439
+ appliedRev
440
+ ]);
441
+ (0, react.useEffect)(() => {
442
+ if (sessionId === void 0 || sessionId === "") return;
443
+ fetch("/pi2dsh/editor-draft", {
444
+ method: "POST",
445
+ headers: { "content-type": "application/json" },
446
+ body: JSON.stringify({
447
+ session: sessionId,
448
+ draft: live
449
+ })
450
+ }).catch(() => {});
451
+ }, [sessionId, live]);
452
+ return null;
453
+ }
454
+ /**
455
+ * Client plugin body: take the seats this package draws into.
456
+ * @param ctx - client root context.
457
+ */
458
+ function apply(ctx) {
459
+ ctx.inject(["inputTriggers"], (scope) => {
460
+ const triggers = scope.inputTriggers;
461
+ if (triggers === void 0) return;
462
+ triggers.registerSource({
463
+ trigger: "@",
464
+ name: "pi2dsh",
465
+ order: 50,
466
+ candidates: async (_session, req) => {
467
+ try {
468
+ const response = await fetch(`/pi2dsh/completions?trigger=${encodeURIComponent("@")}&query=${encodeURIComponent(req.query)}`, { signal: req.signal });
469
+ if (!response.ok) return [];
470
+ return ((await response.json()).items ?? []).map((item) => ({
471
+ name: item.value,
472
+ ...item.description === void 0 ? {} : { description: item.description }
473
+ }));
474
+ } catch {
475
+ return [];
476
+ }
477
+ },
478
+ onPick: (pick) => ({ text: pick.candidate.name })
479
+ });
480
+ });
481
+ ctx.inject(["slots"], (scope) => {
482
+ scope.slots.inject("shell.overlay", () => scope.slots.register({
483
+ name: "shell.overlay",
484
+ id: "pi2dsh-overlay",
485
+ order: 1
486
+ }, OverlaySurfaces));
487
+ scope.slots.inject("conversation.session.header.utilities", () => scope.slots.register({
488
+ name: "conversation.session.header.utilities",
489
+ id: "pi2dsh-header",
490
+ order: 1
491
+ }, textSeat("header", ["header"])));
492
+ scope.slots.inject("conversation.input.dock", () => scope.slots.register({
493
+ name: "conversation.input.dock",
494
+ id: "pi2dsh-dock",
495
+ order: 1
496
+ }, textSeat("dock", [], { widgets: true })));
497
+ scope.slots.inject("conversation.chat.turnTail", () => scope.slots.register({
498
+ name: "conversation.chat.turnTail",
499
+ id: "pi2dsh-entries",
500
+ order: 1,
501
+ select: () => ({})
502
+ }, EntryStrip));
503
+ scope.slots.inject("conversation.input.dock", () => scope.slots.register({
504
+ name: "conversation.input.dock",
505
+ id: "pi2dsh-composer-bridge",
506
+ order: 2
507
+ }, ComposerBridge));
508
+ scope.slots.inject("conversation.composer.dock", () => scope.slots.register({
509
+ name: "conversation.composer.dock",
510
+ id: "pi2dsh-working",
511
+ order: 1
512
+ }, textSeat("working", [
513
+ "footer",
514
+ "workingMessage",
515
+ "workingIndicator",
516
+ "hiddenThinkingLabel"
517
+ ])));
518
+ });
519
+ }
520
+ //#endregion
521
+ exports.apply = apply;
522
+ exports.inject = inject;
523
+ return module.exports;
524
+ }
525
+ });
@@ -278,6 +278,9 @@ declare function registerProvider(name: string, provider: unknown): void;
278
278
  declare function getProviders(): string[];
279
279
  declare function getProvider(name: string): unknown;
280
280
  declare function getModel(_provider: string, _id: string): undefined;
281
+ declare const getBuiltinModels: (provider?: string) => unknown[];
282
+ declare const getBuiltinModel: (provider: string, id: string) => undefined;
283
+ declare const getBuiltinProviders: () => string[];
281
284
  declare function getModels(_provider?: string): unknown[];
282
285
  declare function builtinProviders(): Array<{
283
286
  id: string;
@@ -311,6 +314,38 @@ declare function __setPiAiLlmBridge(bridge: PiAiLlmBridge | undefined): void;
311
314
  declare function __getPiAiLlmBridge(): PiAiLlmBridge | undefined;
312
315
  declare function complete(model: UnknownRecord, context: UnknownRecord, options?: UnknownRecord): Promise<unknown>;
313
316
  declare function stream(model: UnknownRecord, context: UnknownRecord, options?: UnknownRecord): unknown;
317
+ /**
318
+ * Pi's per-protocol transport factories.
319
+ *
320
+ * Pi ships one factory per wire protocol (`pi-ai/compat`), and a gateway
321
+ * package's most common shape is to take the standard one for its protocol and
322
+ * hand it to `registerProvider`. Without these names such a package throws at
323
+ * import — `openAICompletionsApi is not a function` — and the whole package
324
+ * fails to mount, which reads as "the plugin is broken" rather than "the bridge
325
+ * is missing an export".
326
+ *
327
+ * The provider each returns is not a wire client: its stream is the same DSH
328
+ * llm route `complete()` and `stream()` already run on, so every model call in
329
+ * this process keeps going through the one directory and the one path. Without
330
+ * a mounted llm service it fails loud rather than reaching a provider SDK.
331
+ * @param api - the protocol id this factory serves.
332
+ * @returns a provider carrying that protocol's id and the routed stream.
333
+ */
334
+ declare function routedApi(api: string): {
335
+ api: string;
336
+ stream: PiAiLlmBridge;
337
+ streamSimple: PiAiLlmBridge;
338
+ };
339
+ declare const anthropicMessagesApi: () => ReturnType<typeof routedApi>;
340
+ declare const openAICompletionsApi: () => ReturnType<typeof routedApi>;
341
+ declare const openAIResponsesApi: () => ReturnType<typeof routedApi>;
342
+ declare const openAICodexResponsesApi: () => ReturnType<typeof routedApi>;
343
+ declare const azureOpenAIResponsesApi: () => ReturnType<typeof routedApi>;
344
+ declare const googleGenerativeAIApi: () => ReturnType<typeof routedApi>;
345
+ declare const googleVertexApi: () => ReturnType<typeof routedApi>;
346
+ declare const mistralConversationsApi: () => ReturnType<typeof routedApi>;
347
+ declare const bedrockConverseStreamApi: () => ReturnType<typeof routedApi>;
348
+ declare const piMessagesApi: () => ReturnType<typeof routedApi>;
314
349
  interface StringEnumOptions<T extends readonly string[]> {
315
350
  description?: string;
316
351
  default?: T[number];
@@ -322,5 +357,5 @@ declare function StringEnum<T extends readonly string[]>(values: T, options?: St
322
357
  default?: T[number];
323
358
  };
324
359
  //#endregion
325
- export { type AgentMessage, Api, type AssistantMessage, AssistantMessageEventStream, type ImageContent, type Message, Model, ModelThinkingLevel, ModelsError, type Static, StringEnum, StringEnumOptions, type TSchema, type TextContent, type ThinkingContent, ThinkingLevel, ThinkingLevelMap, type ToolCallContent, type ToolResultMessage, Type, type Usage, type UserMessage, __getPiAiLlmBridge, __setPiAiLlmBridge, anthropicOAuth, builtinProviders, clampThinkingLevel, complete, contentText, createProvider, generatePKCE, getApiProvider, getApiProviders, getModel, getModels, getProvider, getProviders, getSupportedThinkingLevels, githubCopilotOAuth, isContextOverflow, isRecoverableLength, isRetryableAssistantError, kimiCodingOAuth, lazyApi, lazyStream, loadAnthropicOAuth, loadGitHubCopilotOAuth, loadKimiCodingOAuth, loadOpenAICodexOAuth, modelsAreEqual, openaiCodexOAuth, pollOAuthDeviceCodeFlow, registerApiProvider, registerProvider, stream, unregisterApiProviders, uuidv7 };
360
+ export { type AgentMessage, Api, type AssistantMessage, AssistantMessageEventStream, type ImageContent, type Message, Model, ModelThinkingLevel, ModelsError, type Static, StringEnum, StringEnumOptions, type TSchema, type TextContent, type ThinkingContent, ThinkingLevel, ThinkingLevelMap, type ToolCallContent, type ToolResultMessage, Type, type Usage, type UserMessage, __getPiAiLlmBridge, __setPiAiLlmBridge, anthropicMessagesApi, anthropicOAuth, azureOpenAIResponsesApi, bedrockConverseStreamApi, builtinProviders, clampThinkingLevel, complete, contentText, createProvider, generatePKCE, getApiProvider, getApiProviders, getBuiltinModel, getBuiltinModels, getBuiltinProviders, getModel, getModels, getProvider, getProviders, getSupportedThinkingLevels, githubCopilotOAuth, googleGenerativeAIApi, googleVertexApi, isContextOverflow, isRecoverableLength, isRetryableAssistantError, kimiCodingOAuth, lazyApi, lazyStream, loadAnthropicOAuth, loadGitHubCopilotOAuth, loadKimiCodingOAuth, loadOpenAICodexOAuth, mistralConversationsApi, modelsAreEqual, openAICodexResponsesApi, openAICompletionsApi, openAIResponsesApi, openaiCodexOAuth, piMessagesApi, pollOAuthDeviceCodeFlow, registerApiProvider, registerProvider, stream, unregisterApiProviders, uuidv7 };
326
361
  //# sourceMappingURL=pi-ai.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pi-ai.d.mts","names":[],"sources":["../../src/compat/vendor/pi-ai-overflow.ts","../../src/compat/vendor/pi-ai-retry.ts","../../src/compat/vendor/pi-uuid.ts","../../src/compat/vendor/pi-ai-provider.ts","../../src/compat/vendor/pi-ai-event-stream.ts","../../src/compat/vendor/pi-ai-lazy.ts","../../src/compat/vendor/pi-oauth-flows/openai-codex.ts","../../src/compat/vendor/pi-oauth-flows/anthropic.ts","../../src/compat/vendor/pi-oauth-flows/github-copilot.ts","../../src/compat/vendor/pi-oauth-flows/kimi-coding.ts","../../src/compat/vendor/pi-oauth-flows/pkce.ts","../../src/compat/vendor/pi-oauth-flows/device-code.ts","../../src/compat/pi-ai.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsIgB,kBAAkB,SAAS,kBAAkB;;;;;;;iBAqC7C,oBAAoB,SAAS,kBAAkB;;;;;;;;;;;;iBCoD/C,0BAA0B,SAAS;;;;iBChNnC;;;cCLH,oBAAoB;EAC7B;EACY,YAAA,WAAM,cAAS;;;;;;;;iBAYf,eAAe;;;;;;;oCAAf;;;;;;;cCtBH;EACT;EACA;EACA;EACA,oBAAkB;EAClB;EACA;EACA;EACY,YAAA,iBAAY;EAOxB,KAAK;EAgBL,IAAI;GAWI,OAAO,kBAAc;EAgB7B,UAAM;;cAIG,oCAAoC;EAAA;;;;;;;;;iBC5BjC,WAAW,YAAO,aAAK;iBAWvB,QAAQ,WAAM;sDAAd;4DAAA;;;;cC2XH;;;;;;;;;;;;;;;;;;;;;;;iBC7OE,eAAe,mBAAW;;;;;;cA+G5B;;;;;;;;;;;;;;;;iBCvBE,mBAAmB,mBAAW;;;;;;;;cAoChC;;;;;;;;;;;;;;;;;;;;iBC7EE,gBAAgB,mBAAW;;;;;;cAa7B;;;;;;;;;;;;;;;;;;;;;;;iBCrOS,gBAAY;;;;;;iBCOZ,wBAAwB,eAAO;;;KCDzC;KACA,6BAA6B;KAC7B,mBAAmB,QAAQ,OAAO;KAClC;UAEK,MAAM,aAAa,MAAM;EACxC;EACA;EACA,MAAM;EACN;EACA;EACA;EACA,mBAAmB;EACnB;EACA;EACA;GACC;;iBAKa,2BAA2B,aAAa,KAAK,OAAO,MAAM,QAAQ;iBASlE,mBAAmB,aAAa,KAC9C,OAAO,MAAM,OACb,OAAO,qBACN;iBAgBa,eAAe,aAAa,KAC1C,GAAG,MAAM,0BACT,GAAG,MAAM;UAMD;EACR;EACA;GACC;;iBAGa,YAAY,2BAA2B,kBAAkB;iBAazD,iBAAiB,cAAc;iBAM/B;iBAIA,YAAY;iBAIZ,SAAS,mBAAmB;iBAI5B,UAAU;iBAmCV,oBAAoB;EAAQ;EAAY;EAAc;EAAa;EAAiB;EAAiB;IAAQ;;;cAYhH,4BAAiC;cACjC,0BAA+B;cAC/B,8BAAmC;cACnC,2BAAgC;UASnC;EACR;EACA,YAAY;EACZ,kBAAkB;;iBAaJ,oBAAoB,UAAU,mBAAmB;iBAWjD,eAAe,cAAc;iBAI7B,mBAAmB;iBAInB,uBAAuB;KAUlC,iBAAiB,OAAO,eAAe,SAAS,eAAe,SAAS;EAC3E,UAAU;GACT,OAAO,kBAAkB;;KAGvB,gBAAgB;iBAIL,mBAAmB,QAAQ;iBAS3B,sBAAsB;iBAWhB,SAAS,OAAO,eAAe,SAAS,eAAe,UAAU,gBAAgB;iBAOvF,OAAO,OAAO,eAAe,SAAS,eAAe,UAAU;UAI9D,kBAAkB;EACjC;EACA,UAAU;;iBAGI,WAAW,6BACzB,QAAQ,GACR,UAAS,kBAAkB;EACxB;EAAgB,MAAM;EAAG;EAAsB,UAAU"}
1
+ {"version":3,"file":"pi-ai.d.mts","names":[],"sources":["../../src/compat/vendor/pi-ai-overflow.ts","../../src/compat/vendor/pi-ai-retry.ts","../../src/compat/vendor/pi-uuid.ts","../../src/compat/vendor/pi-ai-provider.ts","../../src/compat/vendor/pi-ai-event-stream.ts","../../src/compat/vendor/pi-ai-lazy.ts","../../src/compat/vendor/pi-oauth-flows/openai-codex.ts","../../src/compat/vendor/pi-oauth-flows/anthropic.ts","../../src/compat/vendor/pi-oauth-flows/github-copilot.ts","../../src/compat/vendor/pi-oauth-flows/kimi-coding.ts","../../src/compat/vendor/pi-oauth-flows/pkce.ts","../../src/compat/vendor/pi-oauth-flows/device-code.ts","../../src/compat/pi-ai.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsIgB,kBAAkB,SAAS,kBAAkB;;;;;;;iBAqC7C,oBAAoB,SAAS,kBAAkB;;;;;;;;;;;;iBCoD/C,0BAA0B,SAAS;;;;iBChNnC;;;cCLH,oBAAoB;EAC7B;EACY,YAAA,WAAM,cAAS;;;;;;;;iBAYf,eAAe;;;;;;;oCAAf;;;;;;;cCtBH;EACT;EACA;EACA;EACA,oBAAkB;EAClB;EACA;EACA;EACY,YAAA,iBAAY;EAOxB,KAAK;EAgBL,IAAI;GAWI,OAAO,kBAAc;EAgB7B,UAAM;;cAIG,oCAAoC;EAAA;;;;;;;;;iBC5BjC,WAAW,YAAO,aAAK;iBAWvB,QAAQ,WAAM;sDAAd;4DAAA;;;;cC2XH;;;;;;;;;;;;;;;;;;;;;;;iBC7OE,eAAe,mBAAW;;;;;;cA+G5B;;;;;;;;;;;;;;;;iBCvBE,mBAAmB,mBAAW;;;;;;;;cAoChC;;;;;;;;;;;;;;;;;;;;iBC7EE,gBAAgB,mBAAW;;;;;;cAa7B;;;;;;;;;;;;;;;;;;;;;;;iBCrOS,gBAAY;;;;;;iBCOZ,wBAAwB,eAAO;;;KCDzC;KACA,6BAA6B;KAC7B,mBAAmB,QAAQ,OAAO;KAClC;UAEK,MAAM,aAAa,MAAM;EACxC;EACA;EACA,MAAM;EACN;EACA;EACA;EACA,mBAAmB;EACnB;EACA;EACA;GACC;;iBAKa,2BAA2B,aAAa,KAAK,OAAO,MAAM,QAAQ;iBASlE,mBAAmB,aAAa,KAC9C,OAAO,MAAM,OACb,OAAO,qBACN;iBAgBa,eAAe,aAAa,KAC1C,GAAG,MAAM,0BACT,GAAG,MAAM;UAMD;EACR;EACA;GACC;;iBAGa,YAAY,2BAA2B,kBAAkB;iBAazD,iBAAiB,cAAc;iBAM/B;iBAIA,YAAY;iBAIZ,SAAS,mBAAmB;cAQ/B,mBAAoB;cACpB,kBAAmB,kBAAkB;cACrC;iBAEG,UAAU;iBAmCV,oBAAoB;EAAQ;EAAY;EAAc;EAAa;EAAiB;EAAiB;IAAQ;;;cAYhH,4BAAiC;cACjC,0BAA+B;cAC/B,8BAAmC;cACnC,2BAAgC;UASnC;EACR;EACA,YAAY;EACZ,kBAAkB;;iBAaJ,oBAAoB,UAAU,mBAAmB;iBAWjD,eAAe,cAAc;iBAI7B,mBAAmB;iBAInB,uBAAuB;KAUlC,iBAAiB,OAAO,eAAe,SAAS,eAAe,SAAS;EAC3E,UAAU;GACT,OAAO,kBAAkB;;KAGvB,gBAAgB;iBAIL,mBAAmB,QAAQ;iBAS3B,sBAAsB;iBAWhB,SAAS,OAAO,eAAe,SAAS,eAAe,UAAU,gBAAgB;iBAOvF,OAAO,OAAO,eAAe,SAAS,eAAe,UAAU;;;;;;;;;;;;;;;;;;iBAqBtE,UAAU;EAAgB;EAAa,QAAQ;EAAe,cAAc;;cAKxE,4BAA2B,kBAAkB;cAC7C,4BAA2B,kBAAkB;cAC7C,0BAAyB,kBAAkB;cAC3C,+BAA8B,kBAAkB;cAChD,+BAA8B,kBAAkB;cAChD,6BAA4B,kBAAkB;cAC9C,uBAAsB,kBAAkB;cACxC,+BAA8B,kBAAkB;cAChD,gCAA+B,kBAAkB;cACjD,qBAAoB,kBAAkB;UAElC,kBAAkB;EACjC;EACA,UAAU;;iBAGI,WAAW,6BACzB,QAAQ,GACR,UAAS,kBAAkB;EACxB;EAAgB,MAAM;EAAG;EAAsB,UAAU"}
@@ -1,3 +1,3 @@
1
1
 
2
- import { A as pollOAuthDeviceCodeFlow, B as uuidv7, C as stream, D as anthropicOAuth, E as githubCopilotOAuth, F as AssistantMessageEventStream, I as isContextOverflow, L as isRecoverableLength, M as createProvider, N as lazyApi, O as openaiCodexOAuth, P as lazyStream, R as isRetryableAssistantError, S as registerProvider, T as kimiCodingOAuth, _ as loadGitHubCopilotOAuth, a as builtinProviders, b as modelsAreEqual, c as contentText, d as getModel, f as getModels, g as loadAnthropicOAuth, h as getSupportedThinkingLevels, i as __setPiAiLlmBridge, j as ModelsError, k as generatePKCE, l as getApiProvider, m as getProviders, n as Type, o as clampThinkingLevel, p as getProvider, r as __getPiAiLlmBridge, s as complete, t as StringEnum, u as getApiProviders, v as loadKimiCodingOAuth, w as unregisterApiProviders, x as registerApiProvider, y as loadOpenAICodexOAuth } from "../pi-ai-Dyg4zyLZ.mjs";
3
- export { AssistantMessageEventStream, ModelsError, StringEnum, Type, __getPiAiLlmBridge, __setPiAiLlmBridge, anthropicOAuth, builtinProviders, clampThinkingLevel, complete, contentText, createProvider, generatePKCE, getApiProvider, getApiProviders, getModel, getModels, getProvider, getProviders, getSupportedThinkingLevels, githubCopilotOAuth, isContextOverflow, isRecoverableLength, isRetryableAssistantError, kimiCodingOAuth, lazyApi, lazyStream, loadAnthropicOAuth, loadGitHubCopilotOAuth, loadKimiCodingOAuth, loadOpenAICodexOAuth, modelsAreEqual, openaiCodexOAuth, pollOAuthDeviceCodeFlow, registerApiProvider, registerProvider, stream, unregisterApiProviders, uuidv7 };
2
+ import { $ as uuidv7, A as openAICodexResponsesApi, B as anthropicOAuth, C as googleVertexApi, D as loadOpenAICodexOAuth, E as loadKimiCodingOAuth, F as registerProvider, G as createProvider, H as generatePKCE, I as stream, J as AssistantMessageEventStream, K as lazyApi, L as unregisterApiProviders, M as openAIResponsesApi, N as piMessagesApi, O as mistralConversationsApi, P as registerApiProvider, R as kimiCodingOAuth, S as googleGenerativeAIApi, T as loadGitHubCopilotOAuth, U as pollOAuthDeviceCodeFlow, V as openaiCodexOAuth, W as ModelsError, X as isRecoverableLength, Y as isContextOverflow, Z as isRetryableAssistantError, _ as getModel, a as anthropicMessagesApi, b as getProviders, c as builtinProviders, d as contentText, f as getApiProvider, g as getBuiltinProviders, h as getBuiltinModels, i as __setPiAiLlmBridge, j as openAICompletionsApi, k as modelsAreEqual, l as clampThinkingLevel, m as getBuiltinModel, n as Type, o as azureOpenAIResponsesApi, p as getApiProviders, q as lazyStream, r as __getPiAiLlmBridge, s as bedrockConverseStreamApi, t as StringEnum, u as complete, v as getModels, w as loadAnthropicOAuth, x as getSupportedThinkingLevels, y as getProvider, z as githubCopilotOAuth } from "../pi-ai-BA3V_J0V.mjs";
3
+ export { AssistantMessageEventStream, ModelsError, StringEnum, Type, __getPiAiLlmBridge, __setPiAiLlmBridge, anthropicMessagesApi, anthropicOAuth, azureOpenAIResponsesApi, bedrockConverseStreamApi, builtinProviders, clampThinkingLevel, complete, contentText, createProvider, generatePKCE, getApiProvider, getApiProviders, getBuiltinModel, getBuiltinModels, getBuiltinProviders, getModel, getModels, getProvider, getProviders, getSupportedThinkingLevels, githubCopilotOAuth, googleGenerativeAIApi, googleVertexApi, isContextOverflow, isRecoverableLength, isRetryableAssistantError, kimiCodingOAuth, lazyApi, lazyStream, loadAnthropicOAuth, loadGitHubCopilotOAuth, loadKimiCodingOAuth, loadOpenAICodexOAuth, mistralConversationsApi, modelsAreEqual, openAICodexResponsesApi, openAICompletionsApi, openAIResponsesApi, openaiCodexOAuth, piMessagesApi, pollOAuthDeviceCodeFlow, registerApiProvider, registerProvider, stream, unregisterApiProviders, uuidv7 };