@astralyn/pi 1.4.7 → 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 (77) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/bundle/chunks/{chunk-YJTSOLP2.js → chunk-3PKXUKTB.js} +90 -90
  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-FYKNSJG6.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-PKEOKGYI.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/core/package-manager.d.ts +4 -8
  17. package/dist/core/package-manager.d.ts.map +1 -1
  18. package/dist/core/package-manager.js +11 -72
  19. package/dist/core/package-manager.js.map +1 -1
  20. package/dist/core/resource-loader.d.ts +2 -1
  21. package/dist/core/resource-loader.d.ts.map +1 -1
  22. package/dist/core/resource-loader.js +21 -24
  23. package/dist/core/resource-loader.js.map +1 -1
  24. package/dist/core/skill-invocation.d.ts +46 -0
  25. package/dist/core/skill-invocation.d.ts.map +1 -0
  26. package/dist/core/skill-invocation.js +128 -0
  27. package/dist/core/skill-invocation.js.map +1 -0
  28. package/dist/extensions/agent/settings-host.d.ts +33 -0
  29. package/dist/extensions/agent/settings-host.d.ts.map +1 -0
  30. package/dist/extensions/agent/settings-host.js +75 -0
  31. package/dist/extensions/agent/settings-host.js.map +1 -0
  32. package/dist/extensions/agent/settings.d.ts.map +1 -1
  33. package/dist/extensions/agent/settings.js +18 -7
  34. package/dist/extensions/agent/settings.js.map +1 -1
  35. package/dist/extensions/index.d.ts.map +1 -1
  36. package/dist/extensions/index.js +2 -0
  37. package/dist/extensions/index.js.map +1 -1
  38. package/dist/extensions/shell-paths/index.d.ts +8 -0
  39. package/dist/extensions/shell-paths/index.d.ts.map +1 -0
  40. package/dist/extensions/shell-paths/index.js +74 -0
  41. package/dist/extensions/shell-paths/index.js.map +1 -0
  42. package/dist/modes/interactive/chat-viewport.d.ts +5 -2
  43. package/dist/modes/interactive/chat-viewport.d.ts.map +1 -1
  44. package/dist/modes/interactive/chat-viewport.js +72 -12
  45. package/dist/modes/interactive/chat-viewport.js.map +1 -1
  46. package/dist/modes/interactive/components/config-selector.d.ts +10 -8
  47. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  48. package/dist/modes/interactive/components/config-selector.js +51 -121
  49. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  50. package/dist/modes/interactive/components/sticky-user-message.d.ts +23 -0
  51. package/dist/modes/interactive/components/sticky-user-message.d.ts.map +1 -0
  52. package/dist/modes/interactive/components/sticky-user-message.js +58 -0
  53. package/dist/modes/interactive/components/sticky-user-message.js.map +1 -0
  54. package/dist/modes/interactive/components/user-message.d.ts +9 -0
  55. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  56. package/dist/modes/interactive/components/user-message.js +51 -10
  57. package/dist/modes/interactive/components/user-message.js.map +1 -1
  58. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  59. package/dist/modes/interactive/interactive-mode.js +4 -1
  60. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  61. package/dist/modes/interactive/tool-view/chat.d.ts +3 -2
  62. package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -1
  63. package/dist/modes/interactive/tool-view/chat.js +3 -3
  64. package/dist/modes/interactive/tool-view/chat.js.map +1 -1
  65. package/dist/modes/interactive/transcript-layout.d.ts +23 -0
  66. package/dist/modes/interactive/transcript-layout.d.ts.map +1 -0
  67. package/dist/modes/interactive/transcript-layout.js +29 -0
  68. package/dist/modes/interactive/transcript-layout.js.map +1 -0
  69. package/docs/bundled/README.md +1 -0
  70. package/docs/bundled/extensions/shell-paths.md +17 -0
  71. package/docs/docs.json +4 -0
  72. package/docs/packages.md +1 -1
  73. package/docs/settings.md +1 -1
  74. package/docs/skills.md +1 -1
  75. package/docs/usage.md +1 -1
  76. package/npm-shrinkwrap.json +2 -2
  77. 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/packages.md CHANGED
@@ -216,7 +216,7 @@ Filter what a package loads using the object form in settings:
216
216
  - `+path` force-includes an exact path.
217
217
  - `-path` force-excludes an exact path.
218
218
  - Filters layer on top of the manifest. They narrow down what is already allowed.
219
- - `skillInvocationOverrides` uses package-relative skill files or directories and accepts `"model-and-user"` or `"user-only"`. It controls model visibility, not resource loading.
219
+ - `skillInvocationOverrides` uses package-relative skill files or directories and accepts `"model-and-user"` or `"user-only"`. It controls model visibility, not resource loading. A project entry for the same package, matched by package identity rather than the exact source string, layers its overrides over the global entry when it sets `"autoload": false`.
220
220
 
221
221
  ## Enable and Disable Resources
222
222
 
package/docs/settings.md CHANGED
@@ -353,7 +353,7 @@ Paths in `~/.pi/agent/settings.json` resolve relative to `~/.pi/agent`. Paths in
353
353
 
354
354
  Arrays support glob patterns and exclusions. Use `!pattern` to exclude. Use `+path` to force-include an exact path and `-path` to force-exclude an exact path.
355
355
 
356
- `skillInvocationOverrides` uses exact skill file or directory paths as keys. It changes model visibility without changing whether the skill loads; user-only skills remain available as `/skill:name`. Project values override global values. With no override, the skill's `disable-model-invocation` frontmatter applies.
356
+ `skillInvocationOverrides` uses exact skill file or directory paths as keys. Relative keys resolve against the directory of the settings file that declares them, plus its `.agents` skill roots: `~/.pi/agent` and `~/.agents` for global settings, `.pi` and the project's `.agents` directories for project settings. A key for a `SKILL.md` file wins over a key for its directory, and a later key wins over an earlier one. It changes model visibility without changing whether the skill loads, and applies to every loaded skill, including skills passed with `--skill`; user-only skills remain available as `/skill:name`. Project values override global values. With no override, the skill's `disable-model-invocation` frontmatter applies.
357
357
 
358
358
  ```json
359
359
  {
package/docs/skills.md CHANGED
@@ -103,7 +103,7 @@ For settings-based configuration, keep using the `skills` array to control loadi
103
103
  }
104
104
  ```
105
105
 
106
- Project overrides take precedence over global overrides. An explicit `"model-and-user"` also overrides author-level `disable-model-invocation`; removing the override restores the frontmatter default. Invocation overrides do not force a disabled skill to load.
106
+ Relative keys resolve against the directory of the settings file that declares them, so a project key never names a global skill at the same relative path. Project overrides take precedence over global overrides. An explicit `"model-and-user"` also overrides author-level `disable-model-invocation`; removing the override restores the frontmatter default. Invocation overrides do not force a disabled skill to load, but they apply to a skill loaded with `--skill`.
107
107
 
108
108
  Toggle skill commands via `/settings` in interactive mode or in `settings.json`:
109
109
 
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.7",
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.7",
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.7",
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": {