apex-code 0.5.2 → 0.6.1

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 (99) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +41 -2
  3. package/dist/core/agent-session.d.ts +37 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +264 -60
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/default-tool-names.d.ts +7 -0
  8. package/dist/core/default-tool-names.d.ts.map +1 -0
  9. package/dist/core/default-tool-names.js +14 -0
  10. package/dist/core/default-tool-names.js.map +1 -0
  11. package/dist/core/extensions/runner.d.ts.map +1 -1
  12. package/dist/core/extensions/runner.js +2 -0
  13. package/dist/core/extensions/runner.js.map +1 -1
  14. package/dist/core/extensions/types.d.ts +3 -0
  15. package/dist/core/extensions/types.d.ts.map +1 -1
  16. package/dist/core/extensions/types.js.map +1 -1
  17. package/dist/core/keybindings.d.ts +16 -1
  18. package/dist/core/keybindings.d.ts.map +1 -1
  19. package/dist/core/keybindings.js +7 -1
  20. package/dist/core/keybindings.js.map +1 -1
  21. package/dist/core/permissions/startup.d.ts +1 -1
  22. package/dist/core/permissions/startup.d.ts.map +1 -1
  23. package/dist/core/permissions/startup.js.map +1 -1
  24. package/dist/core/sdk.d.ts.map +1 -1
  25. package/dist/core/sdk.js +13 -9
  26. package/dist/core/sdk.js.map +1 -1
  27. package/dist/core/settings-manager.d.ts +4 -0
  28. package/dist/core/settings-manager.d.ts.map +1 -1
  29. package/dist/core/settings-manager.js +13 -0
  30. package/dist/core/settings-manager.js.map +1 -1
  31. package/dist/core/slash-commands.d.ts.map +1 -1
  32. package/dist/core/slash-commands.js +1 -0
  33. package/dist/core/slash-commands.js.map +1 -1
  34. package/dist/core/tools/contract.d.ts +1 -0
  35. package/dist/core/tools/contract.d.ts.map +1 -1
  36. package/dist/core/tools/contract.js.map +1 -1
  37. package/dist/core/tools/index.d.ts +1 -1
  38. package/dist/core/tools/index.d.ts.map +1 -1
  39. package/dist/core/tools/index.js.map +1 -1
  40. package/dist/core/tools/plan-present.d.ts +13 -12
  41. package/dist/core/tools/plan-present.d.ts.map +1 -1
  42. package/dist/core/tools/plan-present.js +32 -19
  43. package/dist/core/tools/plan-present.js.map +1 -1
  44. package/dist/core/tools/renderers/index.d.ts +1 -1
  45. package/dist/core/tools/renderers/index.d.ts.map +1 -1
  46. package/dist/core/tools/renderers/index.js +2 -0
  47. package/dist/core/tools/renderers/index.js.map +1 -1
  48. package/dist/core/tools/renderers/todo-write.d.ts +7 -0
  49. package/dist/core/tools/renderers/todo-write.d.ts.map +1 -0
  50. package/dist/core/tools/renderers/todo-write.js +58 -0
  51. package/dist/core/tools/renderers/todo-write.js.map +1 -0
  52. package/dist/index.d.ts +2 -2
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +1 -1
  55. package/dist/index.js.map +1 -1
  56. package/dist/modes/interactive/components/bash-execution.d.ts +13 -2
  57. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  58. package/dist/modes/interactive/components/bash-execution.js +56 -1
  59. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  60. package/dist/modes/interactive/components/error-summary.d.ts +2 -0
  61. package/dist/modes/interactive/components/error-summary.d.ts.map +1 -1
  62. package/dist/modes/interactive/components/error-summary.js +10 -0
  63. package/dist/modes/interactive/components/error-summary.js.map +1 -1
  64. package/dist/modes/interactive/components/first-use-hints.d.ts +1 -1
  65. package/dist/modes/interactive/components/first-use-hints.d.ts.map +1 -1
  66. package/dist/modes/interactive/components/first-use-hints.js +1 -0
  67. package/dist/modes/interactive/components/first-use-hints.js.map +1 -1
  68. package/dist/modes/interactive/components/footer.d.ts +6 -1
  69. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  70. package/dist/modes/interactive/components/footer.js +38 -11
  71. package/dist/modes/interactive/components/footer.js.map +1 -1
  72. package/dist/modes/interactive/components/settings-selector.d.ts +5 -0
  73. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  74. package/dist/modes/interactive/components/settings-selector.js +20 -1
  75. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  76. package/dist/modes/interactive/components/task-panel.d.ts +27 -0
  77. package/dist/modes/interactive/components/task-panel.d.ts.map +1 -0
  78. package/dist/modes/interactive/components/task-panel.js +92 -0
  79. package/dist/modes/interactive/components/task-panel.js.map +1 -0
  80. package/dist/modes/interactive/components/tool-execution.d.ts +9 -1
  81. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  82. package/dist/modes/interactive/components/tool-execution.js +81 -8
  83. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  84. package/dist/modes/interactive/components/tool-panel.d.ts +7 -0
  85. package/dist/modes/interactive/components/tool-panel.d.ts.map +1 -1
  86. package/dist/modes/interactive/components/tool-panel.js +35 -0
  87. package/dist/modes/interactive/components/tool-panel.js.map +1 -1
  88. package/dist/modes/interactive/components/turn-summary.d.ts +6 -0
  89. package/dist/modes/interactive/components/turn-summary.d.ts.map +1 -0
  90. package/dist/modes/interactive/components/turn-summary.js +12 -0
  91. package/dist/modes/interactive/components/turn-summary.js.map +1 -0
  92. package/dist/modes/interactive/interactive-mode.d.ts +10 -0
  93. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  94. package/dist/modes/interactive/interactive-mode.js +191 -22
  95. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  96. package/docs/keybindings.md +21 -2
  97. package/docs/settings.md +8 -0
  98. package/npm-shrinkwrap.json +5 -5
  99. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"tool-panel.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK3D,MAAM,iBAAiB,GAA4D;IAClF,OAAO,EAAE,EAAE,MAAM,EAAE,KAAG,EAAE,OAAO,EAAE,KAAG,EAAE,IAAI,EAAE,KAAG,EAAE,KAAK,EAAE,KAAG,EAAE;IAC7D,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;CACnE,CAAC;AAEF;;;GAGG;AACH,SAAS,cAAc,CAAC,SAAwB,EAA0C;IACzF,QAAQ,SAAS,EAAE,CAAC;QACnB,KAAK,QAAQ;YACZ,OAAO,KAAK,CAAC;QACd,KAAK,SAAS;YACb,OAAO,QAAQ,CAAC;QACjB,KAAK,MAAM;YACV,OAAO,SAAS,CAAC;QAClB,KAAK,OAAO;YACX,OAAO,OAAO,CAAC;IACjB,CAAC;AAAA,CACD;AAED;;;;;;GAMG;AACH,MAAM,YAAY,GAA4D;IAC7E,OAAO,EAAE,EAAE,MAAM,EAAE,KAAG,EAAE,OAAO,EAAE,KAAG,EAAE,IAAI,EAAE,KAAG,EAAE,KAAK,EAAE,KAAG,EAAE;IAC7D,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE;CAC3D,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,UAAkB,EAAU;IAC9D,IAAI,UAAU,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;IACzE,IAAI,UAAU,GAAG,MAAM;QAAE,OAAO,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACrE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC;AAAA,CAC3C;AAQD,SAAS,mBAAmB,CAAC,SAAwB,EAAqD;IACzG,IAAI,SAAS,KAAK,MAAM;QAAE,OAAO,eAAe,CAAC;IACjD,IAAI,SAAS,KAAK,OAAO;QAAE,OAAO,aAAa,CAAC;IAChD,OAAO,eAAe,CAAC;AAAA,CACvB;AAED,4DAA4D;AAC5D,MAAM,OAAO,kBAAkB;IACb,KAAK,CAAY;IACjB,OAAO,CAAwB;IAEhD,YAAY,KAAgB,EAAE,OAA8B,EAAE;QAC7D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAAA,CACvB;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEvC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7D,MAAM,QAAQ,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC;QACtF,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CACrB,cAAc,CAAC,SAAS,CAAC,EACzB,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,QAAQ,EAAE,CACvE,CAAC;QACF,MAAM,SAAS,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAK,CAAC,CAAC;QAC5E,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,MAAM,GACX,UAAU,GAAG,UAAU;YACtB,CAAC,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,EAAE,EAAE,CAAC,GAAG,SAAS,GAAG,KAAK,EAAE;YAC9E,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3C,mFAAmF;QACnF,0EAA0E;QAC1E,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,OAAO,SAAS,GAAG,UAAU,CAAC,MAAM,IAAI,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAAE,SAAS,EAAE,CAAC;QACtG,MAAM,UAAU,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,SAAS,GAAG,UAAU,CAAC,MAAM;YAAE,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAEvF,MAAM,UAAU,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAClD,0EAA0E;QAC1E,uEAAuE;QACvE,gEAAgE;QAChE,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,SAAS;YACtB,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC;YACzG,CAAC,CAAC,EAAE,CAAC;QACN,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;YACtD,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACjF,OAAO,KAAK,GAAG,eAAe,CAAC,GAAG,WAAW,GAAG,OAAO,GAAG,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAAA,CAC5G,CAAC,CAAC;IAAA,CACH;IAED,UAAU,GAAS;QAClB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;IAAA,CAC1B;CACD;AAED;;;;GAIG;AACH,MAAM,OAAO,uBAAuB;IAClB,KAAK,CAAY;IACjB,OAAO,CAAwB;IAEhD,YAAY,KAAgB,EAAE,OAA8B,EAAE;QAC7D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAAA,CACvB;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QAC1B,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7D,MAAM,QAAQ,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC;QACtF,MAAM,SAAS,GAAG,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAK,CAAC;QAC3D,MAAM,WAAW,GAAG,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,QAAQ,GAAG,SAAS,EAAE,CAAC;QACxG,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAEzC,IAAI,WAAW,IAAI,KAAK,EAAE,CAAC;YAC1B,OAAO,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEvC,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC7C,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC;IAAA,CACrF;IAED,UAAU,GAAS;QAClB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;IAAA,CAC1B;CACD","sourcesContent":["import { type Component, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { paintBackground, theme } from \"../theme/theme.ts\";\n\nexport type ToolLifecycle = \"queued\" | \"running\" | \"done\" | \"error\";\nexport type ToolSymbolPreset = \"unicode\" | \"ascii\";\n\nconst LIFECYCLE_SYMBOLS: Record<ToolSymbolPreset, Record<ToolLifecycle, string>> = {\n\tunicode: { queued: \"○\", running: \"◌\", done: \"✓\", error: \"✗\" },\n\tascii: { queued: \"[ ]\", running: \"[~]\", done: \"[x]\", error: \"[!]\" },\n};\n\n/**\n * Running takes the brand accent rather than `warning`. Work in progress is\n * not a caution; amber is reserved for states the user may need to act on.\n */\nfunction lifecycleColor(lifecycle: ToolLifecycle): \"dim\" | \"accent\" | \"success\" | \"error\" {\n\tswitch (lifecycle) {\n\t\tcase \"queued\":\n\t\t\treturn \"dim\";\n\t\tcase \"running\":\n\t\t\treturn \"accent\";\n\t\tcase \"done\":\n\t\t\treturn \"success\";\n\t\tcase \"error\":\n\t\t\treturn \"error\";\n\t}\n}\n\n/**\n * The status spine drawn down the left edge of a tool panel.\n *\n * It is a redundant channel over the lifecycle word in the header, so it is\n * free to lean on colour. The glyph still distinguishes work that has not\n * started from work that has, which is the distinction a glance most needs.\n */\nconst SPINE_GLYPHS: Record<ToolSymbolPreset, Record<ToolLifecycle, string>> = {\n\tunicode: { queued: \"┆\", running: \"▌\", done: \"▌\", error: \"▌\" },\n\tascii: { queued: \":\", running: \"|\", done: \"|\", error: \"|\" },\n};\n\nexport function formatToolDuration(durationMs: number): string {\n\tif (durationMs < 1000) return `${Math.max(0, Math.round(durationMs))}ms`;\n\tif (durationMs < 10_000) return `${(durationMs / 1000).toFixed(1)}s`;\n\treturn `${Math.round(durationMs / 1000)}s`;\n}\n\nexport interface ToolStatusLineOptions {\n\tlifecycle: ToolLifecycle;\n\tsymbolPreset: ToolSymbolPreset;\n\tdurationMs?: number;\n}\n\nfunction lifecycleBackground(lifecycle: ToolLifecycle): \"toolPendingBg\" | \"toolSuccessBg\" | \"toolErrorBg\" {\n\tif (lifecycle === \"done\") return \"toolSuccessBg\";\n\tif (lifecycle === \"error\") return \"toolErrorBg\";\n\treturn \"toolPendingBg\";\n}\n\n/** Prime-style flat shell for renderer-based tool calls. */\nexport class ToolPanelComponent implements Component {\n\tprivate readonly child: Component;\n\tprivate readonly options: ToolStatusLineOptions;\n\n\tconstructor(child: Component, options: ToolStatusLineOptions) {\n\t\tthis.child = child;\n\t\tthis.options = options;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width <= 0) return [];\n\t\tconst padding = Math.min(2, Math.floor((width - 1) / 2));\n\t\tconst innerWidth = Math.max(1, width - padding * 2);\n\t\tconst childLines = this.child.render(innerWidth);\n\t\tif (childLines.length === 0) return [];\n\n\t\tconst { lifecycle, symbolPreset, durationMs } = this.options;\n\t\tconst duration = durationMs === undefined ? \"\" : ` ${formatToolDuration(durationMs)}`;\n\t\tconst state = theme.fg(\n\t\t\tlifecycleColor(lifecycle),\n\t\t\t`${LIFECYCLE_SYMBOLS[symbolPreset][lifecycle]} ${lifecycle}${duration}`,\n\t\t);\n\t\tconst separator = theme.fg(\"dim\", symbolPreset === \"ascii\" ? \" - \" : \" · \");\n\t\tconst stateWidth = visibleWidth(separator) + visibleWidth(state);\n\t\tconst label = childLines[0].replace(/\\s+$/, \"\");\n\t\tconst header =\n\t\t\tstateWidth < innerWidth\n\t\t\t\t? `${truncateToWidth(label, innerWidth - stateWidth, \"\")}${separator}${state}`\n\t\t\t\t: truncateToWidth(state, innerWidth, \"\");\n\t\t// Renderers written before the panel open their body with their own blank row. The\n\t\t// panel owns that separation, so it drops theirs and inserts exactly one.\n\t\tlet bodyStart = 1;\n\t\twhile (bodyStart < childLines.length && visibleWidth(childLines[bodyStart].trim()) === 0) bodyStart++;\n\t\tconst panelLines = [header];\n\t\tif (bodyStart < childLines.length) panelLines.push(\"\", ...childLines.slice(bodyStart));\n\n\t\tconst background = lifecycleBackground(lifecycle);\n\t\t// The spine occupies the first column of the existing left padding, so it\n\t\t// marks state without costing the panel a column of content. Below two\n\t\t// columns of padding there is no room for it and it is dropped.\n\t\tconst showSpine = padding >= 1;\n\t\tconst spine = showSpine\n\t\t\t? paintBackground(theme.fg(lifecycleColor(lifecycle), SPINE_GLYPHS[symbolPreset][lifecycle]), background)\n\t\t\t: \"\";\n\t\tconst leftPadding = \" \".repeat(Math.max(0, padding - (showSpine ? 1 : 0)));\n\t\treturn panelLines.map((line) => {\n\t\t\tconst clipped = truncateToWidth(line, innerWidth, \"\");\n\t\t\tconst rightPadding = \" \".repeat(Math.max(0, innerWidth - visibleWidth(clipped)));\n\t\t\treturn spine + paintBackground(`${leftPadding}${clipped}${rightPadding}${\" \".repeat(padding)}`, background);\n\t\t});\n\t}\n\n\tinvalidate(): void {\n\t\tthis.child.invalidate?.();\n\t}\n}\n\n/**\n * Prefixes an existing public tool renderer with Apex-owned lifecycle text.\n * The wrapped renderer receives the remaining width, so its own wrapping and\n * cursor-free layout stay intact without a pi-tui hook.\n */\nexport class ToolStatusLineComponent implements Component {\n\tprivate readonly child: Component;\n\tprivate readonly options: ToolStatusLineOptions;\n\n\tconstructor(child: Component, options: ToolStatusLineOptions) {\n\t\tthis.child = child;\n\t\tthis.options = options;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width <= 0) return [];\n\t\tconst { lifecycle, symbolPreset, durationMs } = this.options;\n\t\tconst duration = durationMs === undefined ? \"\" : ` ${formatToolDuration(durationMs)}`;\n\t\tconst separator = symbolPreset === \"ascii\" ? \" | \" : \" · \";\n\t\tconst plainPrefix = `${LIFECYCLE_SYMBOLS[symbolPreset][lifecycle]} ${lifecycle}${duration}${separator}`;\n\t\tconst prefix = theme.fg(lifecycleColor(lifecycle), plainPrefix);\n\t\tconst prefixWidth = visibleWidth(prefix);\n\n\t\tif (prefixWidth >= width) {\n\t\t\treturn [truncateToWidth(prefix, width, \"\")];\n\t\t}\n\n\t\tconst childWidth = Math.max(1, width - prefixWidth);\n\t\tconst childLines = this.child.render(childWidth);\n\t\tif (childLines.length === 0) return [];\n\n\t\tconst continuation = \" \".repeat(prefixWidth);\n\t\treturn childLines.map((line, index) => (index === 0 ? prefix : continuation) + line);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.child.invalidate?.();\n\t}\n}\n"]}
1
+ {"version":3,"file":"tool-panel.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-panel.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { stripAnsi } from \"../../../utils/ansi.ts\";\nimport { paintBackground, theme } from \"../theme/theme.ts\";\n\nexport type ToolLifecycle = \"queued\" | \"running\" | \"done\" | \"error\";\nexport type ToolSymbolPreset = \"unicode\" | \"ascii\";\n\nconst LIFECYCLE_SYMBOLS: Record<ToolSymbolPreset, Record<ToolLifecycle, string>> = {\n\tunicode: { queued: \"○\", running: \"◌\", done: \"✓\", error: \"✗\" },\n\tascii: { queued: \"[ ]\", running: \"[~]\", done: \"[x]\", error: \"[!]\" },\n};\n\n/**\n * Running takes the brand accent rather than `warning`. Work in progress is\n * not a caution; amber is reserved for states the user may need to act on.\n */\nfunction lifecycleColor(lifecycle: ToolLifecycle): \"dim\" | \"accent\" | \"success\" | \"error\" {\n\tswitch (lifecycle) {\n\t\tcase \"queued\":\n\t\t\treturn \"dim\";\n\t\tcase \"running\":\n\t\t\treturn \"accent\";\n\t\tcase \"done\":\n\t\t\treturn \"success\";\n\t\tcase \"error\":\n\t\t\treturn \"error\";\n\t}\n}\n\n/**\n * The status spine drawn down the left edge of a tool panel.\n *\n * It is a redundant channel over the lifecycle word in the header, so it is\n * free to lean on colour. The glyph still distinguishes work that has not\n * started from work that has, which is the distinction a glance most needs.\n */\nconst SPINE_GLYPHS: Record<ToolSymbolPreset, Record<ToolLifecycle, string>> = {\n\tunicode: { queued: \"┆\", running: \"▌\", done: \"▌\", error: \"▌\" },\n\tascii: { queued: \":\", running: \"|\", done: \"|\", error: \"|\" },\n};\n\nexport function formatToolDuration(durationMs: number): string {\n\tif (durationMs < 1000) return `${Math.max(0, Math.round(durationMs))}ms`;\n\tif (durationMs < 10_000) return `${(durationMs / 1000).toFixed(1)}s`;\n\treturn `${Math.round(durationMs / 1000)}s`;\n}\n\nexport interface ToolStatusLineOptions {\n\tlifecycle: ToolLifecycle;\n\tsymbolPreset: ToolSymbolPreset;\n\tdurationMs?: number;\n}\n\nfunction lifecycleBackground(lifecycle: ToolLifecycle): \"toolPendingBg\" | \"toolSuccessBg\" | \"toolErrorBg\" {\n\tif (lifecycle === \"done\") return \"toolSuccessBg\";\n\tif (lifecycle === \"error\") return \"toolErrorBg\";\n\treturn \"toolPendingBg\";\n}\n\n/** Prime-style flat shell for renderer-based tool calls. */\nexport class ToolPanelComponent implements Component {\n\tprivate readonly child: Component;\n\tprivate readonly options: ToolStatusLineOptions;\n\n\tconstructor(child: Component, options: ToolStatusLineOptions) {\n\t\tthis.child = child;\n\t\tthis.options = options;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width <= 0) return [];\n\t\tconst padding = Math.min(2, Math.floor((width - 1) / 2));\n\t\tconst innerWidth = Math.max(1, width - padding * 2);\n\t\tconst childLines = this.child.render(innerWidth);\n\t\tif (childLines.length === 0) return [];\n\n\t\tconst { lifecycle, symbolPreset, durationMs } = this.options;\n\t\tconst duration = durationMs === undefined ? \"\" : ` ${formatToolDuration(durationMs)}`;\n\t\tconst state = theme.fg(\n\t\t\tlifecycleColor(lifecycle),\n\t\t\t`${LIFECYCLE_SYMBOLS[symbolPreset][lifecycle]} ${lifecycle}${duration}`,\n\t\t);\n\t\tconst separator = theme.fg(\"dim\", symbolPreset === \"ascii\" ? \" - \" : \" · \");\n\t\tconst stateWidth = visibleWidth(separator) + visibleWidth(state);\n\t\tconst label = childLines[0].replace(/\\s+$/, \"\");\n\t\tconst header =\n\t\t\tstateWidth < innerWidth\n\t\t\t\t? `${truncateToWidth(label, innerWidth - stateWidth, \"\")}${separator}${state}`\n\t\t\t\t: truncateToWidth(state, innerWidth, \"\");\n\t\t// Renderers written before the panel open their body with their own blank row. The\n\t\t// panel owns that separation, so it drops theirs and inserts exactly one.\n\t\tlet bodyStart = 1;\n\t\twhile (bodyStart < childLines.length && visibleWidth(childLines[bodyStart].trim()) === 0) bodyStart++;\n\t\tconst panelLines = [header];\n\t\tif (bodyStart < childLines.length) panelLines.push(\"\", ...childLines.slice(bodyStart));\n\n\t\tconst background = lifecycleBackground(lifecycle);\n\t\t// The spine occupies the first column of the existing left padding, so it\n\t\t// marks state without costing the panel a column of content. Below two\n\t\t// columns of padding there is no room for it and it is dropped.\n\t\tconst showSpine = padding >= 1;\n\t\tconst spine = showSpine\n\t\t\t? paintBackground(theme.fg(lifecycleColor(lifecycle), SPINE_GLYPHS[symbolPreset][lifecycle]), background)\n\t\t\t: \"\";\n\t\tconst leftPadding = \" \".repeat(Math.max(0, padding - (showSpine ? 1 : 0)));\n\t\treturn panelLines.map((line) => {\n\t\t\tconst clipped = truncateToWidth(line, innerWidth, \"\");\n\t\t\tconst rightPadding = \" \".repeat(Math.max(0, innerWidth - visibleWidth(clipped)));\n\t\t\treturn spine + paintBackground(`${leftPadding}${clipped}${rightPadding}${\" \".repeat(padding)}`, background);\n\t\t});\n\t}\n\n\tinvalidate(): void {\n\t\tthis.child.invalidate?.();\n\t}\n}\n\n/**\n * Prefixes an existing public tool renderer with Apex-owned lifecycle text.\n * The wrapped renderer receives the remaining width, so its own wrapping and\n * cursor-free layout stay intact without a pi-tui hook.\n */\nexport class ToolStatusLineComponent implements Component {\n\tprivate readonly child: Component;\n\tprivate readonly options: ToolStatusLineOptions;\n\n\tconstructor(child: Component, options: ToolStatusLineOptions) {\n\t\tthis.child = child;\n\t\tthis.options = options;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width <= 0) return [];\n\t\tconst { lifecycle, symbolPreset, durationMs } = this.options;\n\t\tconst duration = durationMs === undefined ? \"\" : ` ${formatToolDuration(durationMs)}`;\n\t\tconst separator = symbolPreset === \"ascii\" ? \" | \" : \" · \";\n\t\tconst plainPrefix = `${LIFECYCLE_SYMBOLS[symbolPreset][lifecycle]} ${lifecycle}${duration}${separator}`;\n\t\tconst prefix = theme.fg(lifecycleColor(lifecycle), plainPrefix);\n\t\tconst prefixWidth = visibleWidth(prefix);\n\n\t\tif (prefixWidth >= width) {\n\t\t\treturn [truncateToWidth(prefix, width, \"\")];\n\t\t}\n\n\t\tconst childWidth = Math.max(1, width - prefixWidth);\n\t\tconst childLines = this.child.render(childWidth);\n\t\tif (childLines.length === 0) return [];\n\n\t\tconst continuation = \" \".repeat(prefixWidth);\n\t\treturn childLines.map((line, index) => (index === 0 ? prefix : continuation) + line);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.child.invalidate?.();\n\t}\n}\n\nexport interface CompactOperationRowOptions extends ToolStatusLineOptions {\n\tlabel: string;\n\tsummary?: string;\n}\n\nexport function countOutputLines(output: string): number {\n\tif (!output) return 0;\n\tconst lines = output.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n\treturn lines.length - (lines.at(-1) === \"\" ? 1 : 0);\n}\n\n/** One physical row, with no panel decoration or spacing between operations. */\nexport function renderCompactOperationRow(options: CompactOperationRowOptions, width: number): string[] {\n\tif (width <= 0) return [];\n\tconst singleLine = (text: string) =>\n\t\tstripAnsi(text)\n\t\t\t.replace(/\\p{Cc}/gu, \" \")\n\t\t\t.replace(/ +/g, \" \")\n\t\t\t.trim();\n\tconst { lifecycle, symbolPreset, durationMs } = options;\n\tconst status = theme.fg(lifecycleColor(lifecycle), LIFECYCLE_SYMBOLS[symbolPreset][lifecycle]);\n\tconst prefix = `${status} `;\n\tconst prefixWidth = visibleWidth(prefix);\n\tif (prefixWidth >= width) return [truncateToWidth(status, width, \"\")];\n\tconst separator = symbolPreset === \"ascii\" ? \" - \" : \" · \";\n\tconst duration = durationMs === undefined ? \"\" : formatToolDuration(durationMs);\n\tconst metadata = singleLine([lifecycle, options.summary, duration].filter(Boolean).join(separator));\n\tconst label = singleLine(options.label);\n\tconst available = width - prefixWidth - visibleWidth(separator);\n\tif (available < 2) return [truncateToWidth(`${prefix}${label}`, width, \"\")];\n\t// Preserve state and diagnostics even when a path or command fills the row.\n\tconst minimumLabel = Math.min(\n\t\tvisibleWidth(label),\n\t\tMath.max(1, Math.floor(available * (lifecycle === \"error\" ? 0.3 : 0.5))),\n\t);\n\tconst metadataWidth = Math.min(visibleWidth(metadata), available - minimumLabel);\n\tconst clippedMetadata = truncateToWidth(metadata, metadataWidth, \"\");\n\tconst clippedLabel = truncateToWidth(label, available - visibleWidth(clippedMetadata), \"\").trimEnd();\n\treturn [`${prefix}${clippedLabel}${theme.fg(\"muted\", separator + clippedMetadata)}`];\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import { Text } from "@earendil-works/pi-tui";
2
+ export type TurnSummaryOutcome = "completed" | "aborted";
3
+ export declare class TurnSummaryComponent extends Text {
4
+ constructor(elapsedMs: number, outcome: TurnSummaryOutcome);
5
+ }
6
+ //# sourceMappingURL=turn-summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-summary.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/turn-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAG9C,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,SAAS,CAAC;AAEzD,qBAAa,oBAAqB,SAAQ,IAAI;IAC7C,YAAY,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAMzD;CACD","sourcesContent":["import { Text } from \"@earendil-works/pi-tui\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport type TurnSummaryOutcome = \"completed\" | \"aborted\";\n\nexport class TurnSummaryComponent extends Text {\n\tconstructor(elapsedMs: number, outcome: TurnSummaryOutcome) {\n\t\tconst seconds = Math.floor(elapsedMs / 1000);\n\t\tconst minutes = Math.floor(seconds / 60);\n\t\tconst duration = minutes > 0 ? `${minutes}m ${seconds % 60}s` : `${seconds}s`;\n\t\tconst label = outcome === \"aborted\" ? \"Interrupted after\" : \"Worked for\";\n\t\tsuper(seconds < 1 ? \"\" : theme.fg(\"dim\", `${label} ${duration}`), 1, 0);\n\t}\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import { Text } from "@earendil-works/pi-tui";
2
+ import { theme } from "../theme/theme.js";
3
+ export class TurnSummaryComponent extends Text {
4
+ constructor(elapsedMs, outcome) {
5
+ const seconds = Math.floor(elapsedMs / 1000);
6
+ const minutes = Math.floor(seconds / 60);
7
+ const duration = minutes > 0 ? `${minutes}m ${seconds % 60}s` : `${seconds}s`;
8
+ const label = outcome === "aborted" ? "Interrupted after" : "Worked for";
9
+ super(seconds < 1 ? "" : theme.fg("dim", `${label} ${duration}`), 1, 0);
10
+ }
11
+ }
12
+ //# sourceMappingURL=turn-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-summary.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/turn-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAI1C,MAAM,OAAO,oBAAqB,SAAQ,IAAI;IAC7C,YAAY,SAAiB,EAAE,OAA2B,EAAE;QAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,OAAO,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC;QAC9E,MAAM,KAAK,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,YAAY,CAAC;QACzE,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAAA,CACxE;CACD","sourcesContent":["import { Text } from \"@earendil-works/pi-tui\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport type TurnSummaryOutcome = \"completed\" | \"aborted\";\n\nexport class TurnSummaryComponent extends Text {\n\tconstructor(elapsedMs: number, outcome: TurnSummaryOutcome) {\n\t\tconst seconds = Math.floor(elapsedMs / 1000);\n\t\tconst minutes = Math.floor(seconds / 60);\n\t\tconst duration = minutes > 0 ? `${minutes}m ${seconds % 60}s` : `${seconds}s`;\n\t\tconst label = outcome === \"aborted\" ? \"Interrupted after\" : \"Worked for\";\n\t\tsuper(seconds < 1 ? \"\" : theme.fg(\"dim\", `${label} ${duration}`), 1, 0);\n\t}\n}\n"]}
@@ -68,6 +68,8 @@ export declare class InteractiveMode {
68
68
  private runtimeHost;
69
69
  /** Settled once the most recent /settings permission-mode write has hit disk. */
70
70
  private pendingPermissionModeWrite;
71
+ private pendingPermissionModeCycle;
72
+ private permissionModeCycleGeneration;
71
73
  private renderer;
72
74
  private ui;
73
75
  private mainScreenRenderState;
@@ -147,6 +149,7 @@ export declare class InteractiveMode {
147
149
  private retriedAttempt?;
148
150
  /** Set when the user presses Escape during a retry wait, which is the only way to cancel one. */
149
151
  private retryCancelled;
152
+ private turnStartedAt?;
150
153
  private compactionQueuedMessages;
151
154
  private shutdownRequested;
152
155
  /** The `/bug` hint is shown at most once per session so error output stays readable. */
@@ -158,6 +161,8 @@ export declare class InteractiveMode {
158
161
  private extensionWidgetsAbove;
159
162
  private extensionWidgetsBelow;
160
163
  private widgetContainerAbove;
164
+ private extensionWidgetContainerAbove;
165
+ private taskPanel;
161
166
  private widgetContainerBelow;
162
167
  private customFooter;
163
168
  private headerContainer;
@@ -304,6 +309,7 @@ export declare class InteractiveMode {
304
309
  private clearExtensionWidgets;
305
310
  private resetExtensionUI;
306
311
  private static readonly MAX_WIDGET_LINES;
312
+ private toggleTaskPanel;
307
313
  /**
308
314
  * Render all extension widgets to the widget container.
309
315
  */
@@ -379,6 +385,7 @@ export declare class InteractiveMode {
379
385
  private setupEditorSubmitHandler;
380
386
  private subscribeToAgent;
381
387
  private handleEvent;
388
+ private finishTurnSummary;
382
389
  /** Extract text content from a user message */
383
390
  private getUserMessageText;
384
391
  /** Show a managed-tool status update in the chat. */
@@ -458,6 +465,7 @@ export declare class InteractiveMode {
458
465
  * remembering to set every axis.
459
466
  */
460
467
  private adoptChatDetail;
468
+ private toggleLatestOperation;
461
469
  /** The expand key. A level the user picks is saved, so the next session opens at it. */
462
470
  private cycleChatDetail;
463
471
  private chooseChatDetail;
@@ -515,7 +523,9 @@ export declare class InteractiveMode {
515
523
  */
516
524
  private showSelector;
517
525
  private refreshFooterPermissionMode;
526
+ private cyclePermissionMode;
518
527
  private applyPermissionMode;
528
+ private setTaskListToolDefault;
519
529
  private showSettingsSelector;
520
530
  private handleThinkingCommand;
521
531
  private selectThinkingLevel;