@astralyn/pi 1.4.8 → 1.4.9

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 (51) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/bundle/chunks/{chunk-I2COK45I.js → chunk-3PKXUKTB.js} +10 -10
  3. package/dist/bundle/chunks/{chunk-FODCTZXW.js → chunk-BAGHIP5J.js} +2 -2
  4. package/dist/bundle/chunks/{chunk-PU2IWWXV.js → chunk-DLVLAQEG.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-5VIOGR76.js → chunk-F66AY3WR.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-MG5XDTXV.js → chunk-LPF7HQ3S.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-RO2VH6UZ.js → chunk-R267VV5T.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-RLNMABLM.js → chunk-RVKT7OUB.js} +1 -1
  9. package/dist/bundle/chunks/{cli-MEL7SGJD.js → cli-MBFCFGI2.js} +1 -1
  10. package/dist/bundle/chunks/{execute-4CWRNHPO.js → execute-P22VMM2H.js} +1 -1
  11. package/dist/bundle/chunks/{runtime-R3X67XMR.js → runtime-3RPOJS5T.js} +1 -1
  12. package/dist/bundle/chunks/{virtual-modules-BBLD7YLS.js → virtual-modules-VKMBQTR2.js} +1 -1
  13. package/dist/bundle/cli.js +1 -1
  14. package/dist/bundle/index.js +1 -1
  15. package/dist/bundle/rpc-entry.js +1 -1
  16. package/dist/extensions/index.d.ts.map +1 -1
  17. package/dist/extensions/index.js +2 -0
  18. package/dist/extensions/index.js.map +1 -1
  19. package/dist/extensions/shell-paths/index.d.ts +8 -0
  20. package/dist/extensions/shell-paths/index.d.ts.map +1 -0
  21. package/dist/extensions/shell-paths/index.js +74 -0
  22. package/dist/extensions/shell-paths/index.js.map +1 -0
  23. package/dist/modes/interactive/chat-viewport.d.ts +5 -2
  24. package/dist/modes/interactive/chat-viewport.d.ts.map +1 -1
  25. package/dist/modes/interactive/chat-viewport.js +72 -12
  26. package/dist/modes/interactive/chat-viewport.js.map +1 -1
  27. package/dist/modes/interactive/components/sticky-user-message.d.ts +23 -0
  28. package/dist/modes/interactive/components/sticky-user-message.d.ts.map +1 -0
  29. package/dist/modes/interactive/components/sticky-user-message.js +58 -0
  30. package/dist/modes/interactive/components/sticky-user-message.js.map +1 -0
  31. package/dist/modes/interactive/components/user-message.d.ts +9 -0
  32. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  33. package/dist/modes/interactive/components/user-message.js +51 -10
  34. package/dist/modes/interactive/components/user-message.js.map +1 -1
  35. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  36. package/dist/modes/interactive/interactive-mode.js +4 -1
  37. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  38. package/dist/modes/interactive/tool-view/chat.d.ts +3 -2
  39. package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -1
  40. package/dist/modes/interactive/tool-view/chat.js +3 -3
  41. package/dist/modes/interactive/tool-view/chat.js.map +1 -1
  42. package/dist/modes/interactive/transcript-layout.d.ts +23 -0
  43. package/dist/modes/interactive/transcript-layout.d.ts.map +1 -0
  44. package/dist/modes/interactive/transcript-layout.js +29 -0
  45. package/dist/modes/interactive/transcript-layout.js.map +1 -0
  46. package/docs/bundled/README.md +1 -0
  47. package/docs/bundled/extensions/shell-paths.md +17 -0
  48. package/docs/docs.json +4 -0
  49. package/docs/usage.md +1 -1
  50. package/npm-shrinkwrap.json +2 -2
  51. package/package.json +1 -1
@@ -1,12 +1,13 @@
1
- import { Container } from "@earendil-works/pi-tui";
1
+ import type { Container } from "@earendil-works/pi-tui";
2
2
  import { ToolExecutionComponent } from "../components/tool-execution.ts";
3
+ import { TranscriptLayoutContainer } from "../transcript-layout.ts";
3
4
  /**
4
5
  * Chat container that keeps tool blocks compact and disposes them with the chat.
5
6
  *
6
7
  * Single-line tools read as one compact list; a multiline tool leaves a blank line before the
7
8
  * next tool. Clearing the chat disposes its tool rows, so renderer timers never outlive them.
8
9
  */
9
- export declare class ToolChatContainer extends Container {
10
+ export declare class ToolChatContainer extends TranscriptLayoutContainer {
10
11
  render(width: number): string[];
11
12
  clear(): void;
12
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/tool-view/chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AASzE;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IACtC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IA0B/B,KAAK,IAAI,IAAI;CAItB;AAED,0EAA0E;AAC1E,qBAAa,cAAe,SAAQ,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC;IAC7D,KAAK,IAAI,IAAI;CAItB;AAED,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAErD"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/tool-view/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AASpE;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,yBAAyB;IACtD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IA0B/B,KAAK,IAAI,IAAI;CAItB;AAED,0EAA0E;AAC1E,qBAAa,cAAe,SAAQ,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC;IAC7D,KAAK,IAAI,IAAI;CAItB;AAED,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAErD"}
@@ -1,6 +1,6 @@
1
- import { Container } from "@earendil-works/pi-tui";
2
1
  import { stripAnsi } from "../../../utils/ansi.js";
3
2
  import { ToolExecutionComponent } from "../components/tool-execution.js";
3
+ import { TranscriptLayoutContainer } from "../transcript-layout.js";
4
4
  function disposeAll(components) {
5
5
  for (const component of components) {
6
6
  const disposable = component;
@@ -14,7 +14,7 @@ function disposeAll(components) {
14
14
  * Single-line tools read as one compact list; a multiline tool leaves a blank line before the
15
15
  * next tool. Clearing the chat disposes its tool rows, so renderer timers never outlive them.
16
16
  */
17
- export class ToolChatContainer extends Container {
17
+ export class ToolChatContainer extends TranscriptLayoutContainer {
18
18
  render(width) {
19
19
  let previous;
20
20
  let previousHeight = 0;
@@ -36,7 +36,7 @@ export class ToolChatContainer extends Container {
36
36
  }
37
37
  previous = child;
38
38
  }
39
- // Keep Container's mouse layout in sync with the final spacing.
39
+ // Record child rows after the final tool spacing is known.
40
40
  return super.render(width);
41
41
  }
42
42
  clear() {
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../../src/modes/interactive/tool-view/chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,SAAS,UAAU,CAAC,UAA6B;IAChD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,MAAM,UAAU,GAAG,SAAqC,CAAC;QACzD,IAAI,OAAO,UAAU,CAAC,OAAO,KAAK,UAAU;YAAE,UAAU,CAAC,OAAO,EAAE,CAAC;IACpE,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,iBAAkB,SAAQ,SAAS;IACtC,MAAM,CAAC,KAAa;QAC5B,IAAI,QAA+B,CAAC;QACpC,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,IAAI,KAAK,YAAY,sBAAsB,EAAE,CAAC;gBAC7C,uFAAuF;gBACvF,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBACvB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC3E,IAAI,KAAK,KAAK,CAAC,CAAC;oBAAE,SAAS;gBAC3B,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;gBAC5E,KAAK,CAAC,aAAa,CAClB,QAAQ,YAAY,sBAAsB;oBACzC,CAAC,CAAC,cAAc,GAAG,CAAC;wBACnB,CAAC,CAAC,kBAAkB;wBACpB,CAAC,CAAC,SAAS;oBACZ,CAAC,CAAC,UAAU,CACb,CAAC;gBACF,cAAc,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;YACvC,CAAC;YACD,QAAQ,GAAG,KAAK,CAAC;QAClB,CAAC;QACD,gEAAgE;QAChE,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEQ,KAAK;QACb,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,KAAK,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACD;AAED,0EAA0E;AAC1E,MAAM,OAAO,cAAe,SAAQ,GAAmC;IAC7D,KAAK;QACb,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1B,KAAK,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACD;AAED,sFAAsF;AACtF,MAAM,UAAU,eAAe,CAAC,IAAe;IAC9C,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC","sourcesContent":["import { type Component, Container } from \"@earendil-works/pi-tui\";\nimport { stripAnsi } from \"../../../utils/ansi.ts\";\nimport { ToolExecutionComponent } from \"../components/tool-execution.ts\";\n\nfunction disposeAll(components: Iterable<unknown>): void {\n\tfor (const component of components) {\n\t\tconst disposable = component as { dispose?: () => void };\n\t\tif (typeof disposable.dispose === \"function\") disposable.dispose();\n\t}\n}\n\n/**\n * Chat container that keeps tool blocks compact and disposes them with the chat.\n *\n * Single-line tools read as one compact list; a multiline tool leaves a blank line before the\n * next tool. Clearing the chat disposes its tool rows, so renderer timers never outlive them.\n */\nexport class ToolChatContainer extends Container {\n\toverride render(width: number): string[] {\n\t\tlet previous: Component | undefined;\n\t\tlet previousHeight = 0;\n\t\tfor (const child of this.children) {\n\t\t\tif (child instanceof ToolExecutionComponent) {\n\t\t\t\t// Measure at this width without external spacing, including wrapped titles and images.\n\t\t\t\tchild.setLeadingGap(0);\n\t\t\t\tconst lines = child.render(width);\n\t\t\t\tconst start = lines.findIndex((line) => stripAnsi(line).trim().length > 0);\n\t\t\t\tif (start === -1) continue;\n\t\t\t\tconst { afterTool, afterMultilineTool, afterOther } = child.getToolRowGap();\n\t\t\t\tchild.setLeadingGap(\n\t\t\t\t\tprevious instanceof ToolExecutionComponent\n\t\t\t\t\t\t? previousHeight > 1\n\t\t\t\t\t\t\t? afterMultilineTool\n\t\t\t\t\t\t\t: afterTool\n\t\t\t\t\t\t: afterOther,\n\t\t\t\t);\n\t\t\t\tpreviousHeight = lines.length - start;\n\t\t\t}\n\t\t\tprevious = child;\n\t\t}\n\t\t// Keep Container's mouse layout in sync with the final spacing.\n\t\treturn super.render(width);\n\t}\n\n\toverride clear(): void {\n\t\tdisposeAll(this.children);\n\t\tsuper.clear();\n\t}\n}\n\n/** Pending tool rows by call ID; clear() disposes the rows it forgets. */\nexport class PendingToolMap extends Map<string, ToolExecutionComponent> {\n\toverride clear(): void {\n\t\tdisposeAll(this.values());\n\t\tsuper.clear();\n\t}\n}\n\n/** Dispose every row still shown, for mode shutdown where the chat is not cleared. */\nexport function disposeChatRows(chat: Container): void {\n\tdisposeAll(chat.children);\n}\n"]}
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../../src/modes/interactive/tool-view/chat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,SAAS,UAAU,CAAC,UAA6B;IAChD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,MAAM,UAAU,GAAG,SAAqC,CAAC;QACzD,IAAI,OAAO,UAAU,CAAC,OAAO,KAAK,UAAU;YAAE,UAAU,CAAC,OAAO,EAAE,CAAC;IACpE,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,iBAAkB,SAAQ,yBAAyB;IACtD,MAAM,CAAC,KAAa;QAC5B,IAAI,QAA+B,CAAC;QACpC,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,IAAI,KAAK,YAAY,sBAAsB,EAAE,CAAC;gBAC7C,uFAAuF;gBACvF,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBACvB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC3E,IAAI,KAAK,KAAK,CAAC,CAAC;oBAAE,SAAS;gBAC3B,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;gBAC5E,KAAK,CAAC,aAAa,CAClB,QAAQ,YAAY,sBAAsB;oBACzC,CAAC,CAAC,cAAc,GAAG,CAAC;wBACnB,CAAC,CAAC,kBAAkB;wBACpB,CAAC,CAAC,SAAS;oBACZ,CAAC,CAAC,UAAU,CACb,CAAC;gBACF,cAAc,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;YACvC,CAAC;YACD,QAAQ,GAAG,KAAK,CAAC;QAClB,CAAC;QACD,2DAA2D;QAC3D,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEQ,KAAK;QACb,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,KAAK,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACD;AAED,0EAA0E;AAC1E,MAAM,OAAO,cAAe,SAAQ,GAAmC;IAC7D,KAAK;QACb,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1B,KAAK,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACD;AAED,sFAAsF;AACtF,MAAM,UAAU,eAAe,CAAC,IAAe;IAC9C,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC","sourcesContent":["import type { Component, Container } from \"@earendil-works/pi-tui\";\nimport { stripAnsi } from \"../../../utils/ansi.ts\";\nimport { ToolExecutionComponent } from \"../components/tool-execution.ts\";\nimport { TranscriptLayoutContainer } from \"../transcript-layout.ts\";\n\nfunction disposeAll(components: Iterable<unknown>): void {\n\tfor (const component of components) {\n\t\tconst disposable = component as { dispose?: () => void };\n\t\tif (typeof disposable.dispose === \"function\") disposable.dispose();\n\t}\n}\n\n/**\n * Chat container that keeps tool blocks compact and disposes them with the chat.\n *\n * Single-line tools read as one compact list; a multiline tool leaves a blank line before the\n * next tool. Clearing the chat disposes its tool rows, so renderer timers never outlive them.\n */\nexport class ToolChatContainer extends TranscriptLayoutContainer {\n\toverride render(width: number): string[] {\n\t\tlet previous: Component | undefined;\n\t\tlet previousHeight = 0;\n\t\tfor (const child of this.children) {\n\t\t\tif (child instanceof ToolExecutionComponent) {\n\t\t\t\t// Measure at this width without external spacing, including wrapped titles and images.\n\t\t\t\tchild.setLeadingGap(0);\n\t\t\t\tconst lines = child.render(width);\n\t\t\t\tconst start = lines.findIndex((line) => stripAnsi(line).trim().length > 0);\n\t\t\t\tif (start === -1) continue;\n\t\t\t\tconst { afterTool, afterMultilineTool, afterOther } = child.getToolRowGap();\n\t\t\t\tchild.setLeadingGap(\n\t\t\t\t\tprevious instanceof ToolExecutionComponent\n\t\t\t\t\t\t? previousHeight > 1\n\t\t\t\t\t\t\t? afterMultilineTool\n\t\t\t\t\t\t\t: afterTool\n\t\t\t\t\t\t: afterOther,\n\t\t\t\t);\n\t\t\t\tpreviousHeight = lines.length - start;\n\t\t\t}\n\t\t\tprevious = child;\n\t\t}\n\t\t// Record child rows after the final tool spacing is known.\n\t\treturn super.render(width);\n\t}\n\n\toverride clear(): void {\n\t\tdisposeAll(this.children);\n\t\tsuper.clear();\n\t}\n}\n\n/** Pending tool rows by call ID; clear() disposes the rows it forgets. */\nexport class PendingToolMap extends Map<string, ToolExecutionComponent> {\n\toverride clear(): void {\n\t\tdisposeAll(this.values());\n\t\tsuper.clear();\n\t}\n}\n\n/** Dispose every row still shown, for mode shutdown where the chat is not cleared. */\nexport function disposeChatRows(chat: Container): void {\n\tdisposeAll(chat.children);\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import { type Component, Container } from "@earendil-works/pi-tui";
2
+ export interface TranscriptLayoutChild {
3
+ readonly component: Component;
4
+ readonly row: number;
5
+ readonly height: number;
6
+ }
7
+ export interface TranscriptLayout {
8
+ readonly width: number;
9
+ readonly children: readonly TranscriptLayoutChild[];
10
+ }
11
+ /**
12
+ * A container that exposes the rows it has already rendered for transcript anchors.
13
+ *
14
+ * Mouse dispatch intentionally keeps using Container's fallback measurement. The
15
+ * layout is observational and never changes rendering or hit-testing behavior.
16
+ */
17
+ export declare class TranscriptLayoutContainer extends Container {
18
+ private renderedLayout;
19
+ getRenderedLayout(): TranscriptLayout | undefined;
20
+ clear(): void;
21
+ render(width: number): string[];
22
+ }
23
+ //# sourceMappingURL=transcript-layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-layout.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/transcript-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnE,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACpD;AAED;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,SAAS;IACvD,OAAO,CAAC,cAAc,CAA+B;IAErD,iBAAiB,IAAI,gBAAgB,GAAG,SAAS;IAIxC,KAAK,IAAI,IAAI;IAKb,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAWxC"}
@@ -0,0 +1,29 @@
1
+ import { Container } from "@earendil-works/pi-tui";
2
+ /**
3
+ * A container that exposes the rows it has already rendered for transcript anchors.
4
+ *
5
+ * Mouse dispatch intentionally keeps using Container's fallback measurement. The
6
+ * layout is observational and never changes rendering or hit-testing behavior.
7
+ */
8
+ export class TranscriptLayoutContainer extends Container {
9
+ getRenderedLayout() {
10
+ return this.renderedLayout;
11
+ }
12
+ clear() {
13
+ this.renderedLayout = undefined;
14
+ super.clear();
15
+ }
16
+ render(width) {
17
+ const lines = [];
18
+ const children = [];
19
+ for (const component of this.children) {
20
+ const childLines = component.render(width);
21
+ children.push({ component, row: lines.length, height: childLines.length });
22
+ for (const line of childLines)
23
+ lines.push(line);
24
+ }
25
+ this.renderedLayout = { width, children };
26
+ return lines;
27
+ }
28
+ }
29
+ //# sourceMappingURL=transcript-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-layout.js","sourceRoot":"","sources":["../../../src/modes/interactive/transcript-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAanE;;;;;GAKG;AACH,MAAM,OAAO,yBAA0B,SAAQ,SAAS;IAGvD,iBAAiB;QAChB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC5B,CAAC;IAEQ,KAAK;QACb,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAChC,KAAK,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAEQ,MAAM,CAAC,KAAa;QAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAA4B,EAAE,CAAC;QAC7C,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3E,KAAK,MAAM,IAAI,IAAI,UAAU;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,CAAC,cAAc,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACd,CAAC;CACD","sourcesContent":["import { type Component, Container } from \"@earendil-works/pi-tui\";\n\nexport interface TranscriptLayoutChild {\n\treadonly component: Component;\n\treadonly row: number;\n\treadonly height: number;\n}\n\nexport interface TranscriptLayout {\n\treadonly width: number;\n\treadonly children: readonly TranscriptLayoutChild[];\n}\n\n/**\n * A container that exposes the rows it has already rendered for transcript anchors.\n *\n * Mouse dispatch intentionally keeps using Container's fallback measurement. The\n * layout is observational and never changes rendering or hit-testing behavior.\n */\nexport class TranscriptLayoutContainer extends Container {\n\tprivate renderedLayout: TranscriptLayout | undefined;\n\n\tgetRenderedLayout(): TranscriptLayout | undefined {\n\t\treturn this.renderedLayout;\n\t}\n\n\toverride clear(): void {\n\t\tthis.renderedLayout = undefined;\n\t\tsuper.clear();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst children: TranscriptLayoutChild[] = [];\n\t\tfor (const component of this.children) {\n\t\t\tconst childLines = component.render(width);\n\t\t\tchildren.push({ component, row: lines.length, height: childLines.length });\n\t\t\tfor (const line of childLines) lines.push(line);\n\t\t}\n\t\tthis.renderedLayout = { width, children };\n\t\treturn lines;\n\t}\n}\n"]}
@@ -27,6 +27,7 @@ The following extensions are additions maintained by `@astralyn/pi`:
27
27
  | [Provider](extensions/provider.md) | `/provider` | Edit models.json providers: connection, API type, and models |
28
28
  | [Statusline](extensions/statusline.md) | Footer status | Show concise extension-managed activity state |
29
29
  | [Search](extensions/search.md) | `code_search`, `web_search` | Devin-driven semantic code search and web search with one shared key |
30
+ | [Shell paths](extensions/shell-paths.md) | File tools | Resolve bash mount paths such as `/tmp` on Windows |
30
31
  | [Tasks](tasks.md) | `tasks`, `/tasks` | Inspect and control native shell and extension-owned executions |
31
32
 
32
33
  All bundled extensions use the public Extension API. Enable or disable them in `pi config` or through `builtin:<name>` entries in [settings](../settings.md#codemode-and-tool-selection). `--no-extensions` disables them; `-e builtin:<name>` loads one explicitly.
@@ -0,0 +1,17 @@
1
+ # Shell paths
2
+
3
+ On Windows, the `bash` tool runs Git Bash, MSYS2, or Cygwin, which name files through their own mount table. A model that works in `/tmp/build` with `bash` and then calls `read /tmp/build/log.txt` would otherwise reach `C:\tmp\build\log.txt` on the current drive instead of the directory bash used.
4
+
5
+ This extension resolves such paths for the `read`, `write`, `edit`, `ls`, `grep`, and `find` tools the way bash does:
6
+
7
+ | Path from bash | Resolves to (Git for Windows defaults) |
8
+ |---|---|
9
+ | `/tmp/build/log.txt` | `C:\Users\<you>\AppData\Local\Temp\build\log.txt` |
10
+ | `/usr/bin/bash.exe` | `C:\Program Files\Git\usr\bin\bash.exe` |
11
+ | `/etc/gitconfig` | `C:\Program Files\Git\etc\gitconfig` |
12
+
13
+ The first such call reads the mount table from the configured shell (`shellPath` or the detected bash) with `mount`, so custom `fstab` entries and non-default installations resolve correctly. Bash maps `/tmp` to the user's temp directory even when Pi runs with a different `TEMP`.
14
+
15
+ Drive paths such as `/c/Users/...`, `/cygdrive/c/...`, and `/mnt/c/...` work without this extension. Windows paths, relative paths, UNC paths, and paths on other platforms are left unchanged. Legacy WSL bash (`System32\bash.exe`) is skipped because its mounts live inside the Linux filesystem.
16
+
17
+ Disable `builtin:shell-paths` to resolve these paths against the current drive root instead.
package/docs/docs.json CHANGED
@@ -104,6 +104,10 @@
104
104
  "title": "Search",
105
105
  "path": "bundled/extensions/search.md"
106
106
  },
107
+ {
108
+ "title": "Shell paths",
109
+ "path": "bundled/extensions/shell-paths.md"
110
+ },
107
111
  {
108
112
  "title": "Bundled themes",
109
113
  "path": "bundled/themes.md"
package/docs/usage.md CHANGED
@@ -264,7 +264,7 @@ pi --no-extensions -e ./my-extension.ts
264
264
  | `-h`, `--help` | Show help |
265
265
  | `-v`, `--version` | Show version |
266
266
 
267
- In `fullscreen` mode, the transcript scrolls inside the terminal viewport while queued messages, working status, extension widgets, editor, and footer remain fixed at the bottom. Mouse/trackpad input scrolls the region under the pointer; keyboard viewport actions always remain available. Inline images work in terminals that support the Kitty graphics protocol, including Kitty and Ghostty. In iTerm2 they render as text placeholders because its inline-image protocol cannot delete or crop placements during application-owned scrolling. In `regular` mode, pi uses the main screen and terminal-owned scrollback, and iTerm2 inline images continue to render normally. See [Terminal setup](terminal-setup.md) for terminal-specific settings and workarounds.
267
+ In `fullscreen` mode, the transcript scrolls inside the terminal viewport while queued messages, working status, extension widgets, editor, and footer remain fixed at the bottom. When a user message's first line scrolls above the viewport, a subdued one-line summary appears at the top; click it to scroll back to that message. Mouse/trackpad input scrolls the region under the pointer; keyboard viewport actions always remain available. Inline images work in terminals that support the Kitty graphics protocol, including Kitty and Ghostty. In iTerm2 they render as text placeholders because its inline-image protocol cannot delete or crop placements during application-owned scrolling. In `regular` mode, pi uses the main screen and terminal-owned scrollback, and iTerm2 inline images continue to render normally. See [Terminal setup](terminal-setup.md) for terminal-specific settings and workarounds.
268
268
 
269
269
  Set **TUI mode** in `/settings` to switch between `regular` and `fullscreen` immediately and choose the default for future sessions. **Fullscreen exit output** controls whether exiting fullscreen prints the final transcript or restores the previous screen and prints only the session resume hint.
270
270
 
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@astralyn/pi",
3
- "version": "1.4.8",
3
+ "version": "1.4.9",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@astralyn/pi",
9
- "version": "1.4.8",
9
+ "version": "1.4.9",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@earendil-works/pi-agent-core": "1.4.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astralyn/pi",
3
- "version": "1.4.8",
3
+ "version": "1.4.9",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {