@pencil-agent/nano-pencil 2.0.0-beta.8 → 2.0.0

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 (241) hide show
  1. package/README.md +267 -267
  2. package/dist/build-meta.json +3 -3
  3. package/dist/core/export-html/AGENT.md +11 -11
  4. package/dist/core/export-html/template.css +971 -971
  5. package/dist/core/export-html/template.html +54 -54
  6. package/dist/core/extensions-host/index.d.ts +1 -1
  7. package/dist/core/extensions-host/loader.js +1 -1
  8. package/dist/core/extensions-host/runner.d.ts +1 -0
  9. package/dist/core/extensions-host/runner.js +2 -2
  10. package/dist/core/extensions-host/types.d.ts +17 -22
  11. package/dist/core/lib/ai/src/types.d.ts +12 -2
  12. package/dist/core/persona/persona-manager.js +5 -2
  13. package/dist/core/runtime/agent-session.js +3 -3
  14. package/dist/core/runtime/extension-core-bindings.d.ts +1 -0
  15. package/dist/core/runtime/extension-core-bindings.js +2 -2
  16. package/dist/extensions/builtin/AGENT.md +115 -115
  17. package/dist/extensions/builtin/browser/AGENT.md +17 -17
  18. package/dist/extensions/builtin/browser/agent-workspace/agent_helpers.py +12 -12
  19. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/amazon/product-search.md +198 -198
  20. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/archive-org/scraping.md +341 -341
  21. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/arxiv/scraping.md +311 -311
  22. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/arxiv-bulk/scraping.md +333 -333
  23. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/atlas/overview.md +70 -70
  24. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/booking-com/scraping.md +578 -578
  25. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/capterra/scraping.md +440 -440
  26. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/centilebrain/generate-estimates.md +110 -110
  27. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/coingecko/scraping.md +325 -325
  28. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/coinmarketcap/scraping.md +463 -463
  29. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/coursera/scraping.md +360 -360
  30. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/craigslist/scraping.md +390 -390
  31. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/crossref/scraping.md +568 -568
  32. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/dev-to/scraping.md +323 -323
  33. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/duckduckgo/scraping.md +349 -349
  34. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/ebay/scraping.md +435 -435
  35. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/etsy/scraping.md +506 -506
  36. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/eventbrite/scraping.md +363 -363
  37. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/expedia/automation.md +168 -168
  38. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/facebook/groups.md +236 -236
  39. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/facebook/pages.md +295 -295
  40. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/framer/editor.md +108 -108
  41. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/fred/scraping.md +493 -493
  42. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/g2/scraping.md +580 -580
  43. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/genius/scraping.md +511 -511
  44. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/github/repo-actions.md +65 -65
  45. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/github/scraping.md +184 -184
  46. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/glassdoor/scraping.md +543 -543
  47. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/gmail/compose.md +122 -122
  48. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/goodreads/scraping.md +461 -461
  49. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/gutenberg/scraping.md +383 -383
  50. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/hackernews/scraping.md +243 -243
  51. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/howlongtobeat/scraping.md +473 -473
  52. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/imdb/scraping.md +271 -271
  53. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/itch-io/scraping.md +436 -436
  54. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/job-boards/indeed-glassdoor.md +1021 -1021
  55. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/letterboxd/scraping.md +349 -349
  56. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/linkedin/invitation-manager.md +109 -109
  57. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/loom/folder-enumeration.md +170 -170
  58. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/macrotrends/scraping.md +537 -537
  59. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/medium/article-hydration.md +120 -120
  60. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/medium/scraping.md +414 -414
  61. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/metacritic/scraping.md +477 -477
  62. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/musicbrainz/scraping.md +478 -478
  63. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/nasa/scraping.md +339 -339
  64. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/news-aggregation/multi-source.md +205 -205
  65. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/open-library/scraping.md +472 -472
  66. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/openalex/scraping.md +470 -470
  67. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/openstreetmap/scraping.md +490 -490
  68. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/package-registries/npm-pypi.md +478 -478
  69. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/polymarket/scraping.md +234 -234
  70. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/producthunt/scraping.md +307 -307
  71. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/pubmed/scraping.md +421 -421
  72. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/quora/scraping.md +364 -364
  73. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/rawg/scraping.md +352 -352
  74. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/reddit/scraping.md +124 -124
  75. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/rest-countries/scraping.md +233 -233
  76. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/sec-edgar/scraping.md +361 -361
  77. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/README.md +36 -36
  78. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/embedded-apps.md +72 -72
  79. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/knowledge-base.md +109 -109
  80. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/polaris-inputs.md +137 -137
  81. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/soundcloud/scraping.md +362 -362
  82. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/spotify/scraping.md +339 -339
  83. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/stackoverflow/scraping.md +435 -435
  84. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/steam/scraping.md +575 -575
  85. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/substack/scraping.md +338 -338
  86. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/thetechgeeks/pricing.md +52 -52
  87. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/tiktok/upload.md +107 -107
  88. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/tradingview/scraping.md +309 -309
  89. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/trello/boards-and-lists.md +88 -88
  90. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/trustpilot/scraping.md +375 -375
  91. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/walmart/scraping.md +444 -444
  92. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/wayback-machine/scraping.md +306 -306
  93. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/weather/scraping.md +398 -398
  94. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/wellfound/scraping.md +596 -596
  95. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/world-bank/scraping.md +356 -356
  96. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/xiaohongshu/scraping.md +84 -84
  97. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/youtube/scraping.md +418 -418
  98. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/zillow/scraping.md +433 -433
  99. package/dist/extensions/builtin/browser/browser.md +73 -73
  100. package/dist/extensions/builtin/browser/install.md +142 -142
  101. package/dist/extensions/builtin/browser/interaction-skills/connection.md +48 -48
  102. package/dist/extensions/builtin/browser/interaction-skills/cookies.md +3 -3
  103. package/dist/extensions/builtin/browser/interaction-skills/cross-origin-iframes.md +3 -3
  104. package/dist/extensions/builtin/browser/interaction-skills/dialogs.md +64 -64
  105. package/dist/extensions/builtin/browser/interaction-skills/downloads.md +3 -3
  106. package/dist/extensions/builtin/browser/interaction-skills/drag-and-drop.md +3 -3
  107. package/dist/extensions/builtin/browser/interaction-skills/dropdowns.md +3 -3
  108. package/dist/extensions/builtin/browser/interaction-skills/iframes.md +3 -3
  109. package/dist/extensions/builtin/browser/interaction-skills/network-requests.md +3 -3
  110. package/dist/extensions/builtin/browser/interaction-skills/print-as-pdf.md +3 -3
  111. package/dist/extensions/builtin/browser/interaction-skills/profile-sync.md +90 -90
  112. package/dist/extensions/builtin/browser/interaction-skills/screenshots.md +17 -17
  113. package/dist/extensions/builtin/browser/interaction-skills/scrolling.md +3 -3
  114. package/dist/extensions/builtin/browser/interaction-skills/shadow-dom.md +3 -3
  115. package/dist/extensions/builtin/browser/interaction-skills/tabs.md +69 -69
  116. package/dist/extensions/builtin/browser/interaction-skills/uploads.md +1 -1
  117. package/dist/extensions/builtin/browser/interaction-skills/viewport.md +3 -3
  118. package/dist/extensions/builtin/browser/src/browser_harness/AGENT.md +15 -15
  119. package/dist/extensions/builtin/browser/src/browser_harness/__init__.py +8 -8
  120. package/dist/extensions/builtin/browser/src/browser_harness/_ipc.py +90 -90
  121. package/dist/extensions/builtin/browser/src/browser_harness/admin.py +722 -722
  122. package/dist/extensions/builtin/browser/src/browser_harness/daemon.py +328 -328
  123. package/dist/extensions/builtin/browser/src/browser_harness/helpers.py +396 -396
  124. package/dist/extensions/builtin/browser/src/browser_harness/run.py +103 -103
  125. package/dist/extensions/builtin/discipline/skills/brainstorming/SKILL.md +33 -33
  126. package/dist/extensions/builtin/discipline/skills/executing-plans/SKILL.md +25 -25
  127. package/dist/extensions/builtin/discipline/skills/finishing-development-branch/SKILL.md +25 -25
  128. package/dist/extensions/builtin/discipline/skills/receiving-code-review/SKILL.md +22 -22
  129. package/dist/extensions/builtin/discipline/skills/requesting-code-review/SKILL.md +31 -31
  130. package/dist/extensions/builtin/discipline/skills/systematic-debugging/SKILL.md +28 -28
  131. package/dist/extensions/builtin/discipline/skills/test-driven-development/SKILL.md +32 -32
  132. package/dist/extensions/builtin/discipline/skills/using-git-worktrees/SKILL.md +25 -25
  133. package/dist/extensions/builtin/discipline/skills/verification-before-completion/SKILL.md +27 -27
  134. package/dist/extensions/builtin/discipline/skills/writing-plans/SKILL.md +26 -26
  135. package/dist/extensions/builtin/goal/README.md +67 -67
  136. package/dist/extensions/builtin/goal/goal-controller.d.ts +39 -10
  137. package/dist/extensions/builtin/goal/goal-controller.js +1 -1
  138. package/dist/extensions/builtin/goal/goal-format.js +1 -1
  139. package/dist/extensions/builtin/goal/goal-prompts.d.ts +2 -0
  140. package/dist/extensions/builtin/goal/goal-prompts.js +5 -4
  141. package/dist/extensions/builtin/goal/goal-store.js +1 -1
  142. package/dist/extensions/builtin/goal/index.d.ts +1 -1
  143. package/dist/extensions/builtin/goal/index.js +10 -7
  144. package/dist/extensions/builtin/grub/README.md +112 -112
  145. package/dist/extensions/builtin/link-world/agent-workspace/README.md +16 -16
  146. package/dist/extensions/builtin/link-world/index.js +6 -6
  147. package/dist/extensions/builtin/link-world/internet-search/internet-search.md +65 -65
  148. package/dist/extensions/builtin/link-world/link-world-agent.md +82 -82
  149. package/dist/extensions/builtin/link-world/linkworld.md +313 -313
  150. package/dist/extensions/builtin/link-world/{network-routing.md → network-routing/network-routing.md} +67 -67
  151. package/dist/extensions/builtin/loop/README.md +92 -92
  152. package/dist/extensions/builtin/mcp/figma-design.md +68 -68
  153. package/dist/extensions/builtin/mcp/mcp-management.md +85 -85
  154. package/dist/extensions/builtin/plan/index.js +1 -1
  155. package/dist/extensions/builtin/recap/AGENT.md +15 -15
  156. package/dist/extensions/builtin/sal/README.md +72 -72
  157. package/dist/extensions/builtin/security-audit/README.md +289 -289
  158. package/dist/extensions/builtin/task/task-store.d.ts +4 -0
  159. package/dist/extensions/builtin/task/task-store.js +1 -1
  160. package/dist/extensions/builtin/team/AGENT.md +112 -112
  161. package/dist/extensions/builtin/team/TESTING.md +299 -299
  162. package/dist/extensions/builtin/token-save/README.md +56 -56
  163. package/dist/extensions/optional/AGENT.md +10 -10
  164. package/dist/index.d.ts +5 -30
  165. package/dist/index.js +1 -1
  166. package/dist/models.d.ts +7 -0
  167. package/dist/models.js +1 -0
  168. package/dist/modes/interactive/components/footer.js +1 -1
  169. package/dist/modes/interactive/components/task-status-panel.d.ts +36 -0
  170. package/dist/modes/interactive/components/task-status-panel.js +1 -0
  171. package/dist/modes/interactive/controllers/stream-render-controller.d.ts +7 -0
  172. package/dist/modes/interactive/controllers/stream-render-controller.js +2 -2
  173. package/dist/modes/interactive/interactive-mode.js +40 -40
  174. package/dist/modes/interactive/state/interactive-state.d.ts +2 -0
  175. package/dist/modes/interactive/state/interactive-state.js +1 -1
  176. package/dist/modes/interactive/theme/dark.json +85 -85
  177. package/dist/modes/interactive/theme/light.json +84 -84
  178. package/dist/modes/interactive/theme/theme-schema.json +335 -335
  179. package/dist/modes/interactive/theme/warm.json +81 -81
  180. package/dist/node_modules/@pencil-agent/ai/dist/cli.js +0 -0
  181. package/dist/node_modules/@pencil-agent/ai/dist/models.generated.js +1 -1
  182. package/dist/node_modules/@pencil-agent/ai/dist/providers/anthropic.js +2 -2
  183. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-completions.js +5 -5
  184. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses.js +1 -1
  185. package/dist/node_modules/@pencil-agent/ai/dist/stream.js +1 -1
  186. package/dist/packages/protocol/src/commands.d.ts +33 -0
  187. package/dist/packages/protocol/src/flags.d.ts +20 -0
  188. package/dist/packages/protocol/src/hooks.d.ts +17 -0
  189. package/dist/packages/protocol/src/hooks.js +0 -0
  190. package/dist/packages/{extension-sdk → protocol}/src/index.d.ts +7 -4
  191. package/dist/packages/protocol/src/index.js +1 -0
  192. package/dist/packages/{extension-sdk → protocol}/src/lifecycle.d.ts +15 -27
  193. package/dist/packages/protocol/src/lifecycle.js +0 -0
  194. package/dist/packages/{extension-sdk → protocol}/src/tools.d.ts +1 -1
  195. package/dist/packages/protocol/src/tools.js +0 -0
  196. package/dist/public-config.d.ts +12 -0
  197. package/dist/public-config.js +1 -0
  198. package/dist/runtime.d.ts +9 -0
  199. package/dist/runtime.js +1 -0
  200. package/dist/session-compaction.d.ts +7 -0
  201. package/dist/session-compaction.js +1 -0
  202. package/dist/session.d.ts +7 -0
  203. package/dist/session.js +1 -0
  204. package/dist/skills.d.ts +7 -0
  205. package/dist/skills.js +1 -0
  206. package/dist/tools.d.ts +7 -0
  207. package/dist/tools.js +1 -0
  208. package/docs/ACP/345/215/217/350/256/256/351/233/206/346/210/220/345/274/200/345/217/221/346/226/207/346/241/243.md +851 -0
  209. package/docs/SDK-TESTING.md +364 -0
  210. package/docs/codex-goal-command-impl.md +1055 -1055
  211. package/docs/codex-goal-vs-grub.md +500 -500
  212. package/docs/custom-provider.md +27 -27
  213. package/docs/extensions.md +27 -27
  214. package/docs/keybindings.md +27 -27
  215. package/docs/loop /351/207/215/346/236/204/345/256/214/346/210/220/346/200/273/347/273/223.md" +250 -250
  216. package/docs/loop /351/207/215/346/236/204/345/256/214/346/210/220/346/212/245/345/221/212.md" +122 -122
  217. package/docs/loop /351/207/215/346/236/204/346/226/271/346/241/210.md" +1222 -1222
  218. package/docs/loop /351/207/215/346/236/204/346/226/271/346/241/210/345/256/236/347/216/260/346/212/245/345/221/212.md" +158 -158
  219. package/docs/loop /351/207/215/346/236/204/346/226/271/346/241/210/345/257/271/346/257/224/345/210/206/346/236/220.md" +128 -128
  220. package/docs/loop /351/207/215/346/236/204/350/256/241/345/210/222.md" +320 -320
  221. package/docs/loop-usage-examples.md +214 -214
  222. package/docs/mem-core/346/212/200/346/234/257/346/226/207/346/241/243.md +593 -0
  223. package/docs/models.md +27 -27
  224. package/docs/packages.md +27 -27
  225. package/docs/pi-design-philosophy.md +457 -457
  226. package/docs/planmode.md +1987 -1987
  227. package/docs/prompt-templates.md +27 -27
  228. package/docs/providers.md +27 -27
  229. package/docs/sdk.md +27 -27
  230. package/docs/skills.md +27 -27
  231. package/docs/startup-performance-optimization.md +301 -0
  232. package/docs/themes.md +27 -27
  233. package/docs/tui.md +27 -27
  234. package/docs//350/256/244/347/237/245/345/234/260/345/233/276.md +47 -0
  235. package/package.json +190 -162
  236. package/dist/packages/extension-sdk/src/index.js +0 -1
  237. package/docs/cc-agent-design.md +0 -1297
  238. package/docs/cc-tui-design.md +0 -1333
  239. package/docs//345/257/271/346/240/207Claude-Code.md +0 -1775
  240. /package/dist/packages/{extension-sdk/src/lifecycle.js → protocol/src/commands.js} +0 -0
  241. /package/dist/packages/{extension-sdk/src/tools.js → protocol/src/flags.js} +0 -0
@@ -1,54 +1,54 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Session Export</title>
7
- <style>
8
- {{CSS}}
9
- </style>
10
- </head>
11
- <body>
12
- <button id="hamburger" title="Open sidebar"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="none"><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><circle cx="18" cy="12" r="2.5"/><rect x="5" y="6" width="2" height="12"/><path d="M6 12h10c1 0 2 0 2-2V8"/></svg></button>
13
- <div id="sidebar-overlay"></div>
14
- <div id="app">
15
- <aside id="sidebar">
16
- <div class="sidebar-header">
17
- <div class="sidebar-controls">
18
- <input type="text" class="sidebar-search" id="tree-search" placeholder="Search...">
19
- </div>
20
- <div class="sidebar-filters">
21
- <button class="filter-btn active" data-filter="default" title="Hide settings entries">Default</button>
22
- <button class="filter-btn" data-filter="no-tools" title="Default minus tool results">No-tools</button>
23
- <button class="filter-btn" data-filter="user-only" title="Only user messages">User</button>
24
- <button class="filter-btn" data-filter="labeled-only" title="Only labeled entries">Labeled</button>
25
- <button class="filter-btn" data-filter="all" title="Show everything">All</button>
26
- <button class="sidebar-close" id="sidebar-close" title="Close">✕</button>
27
- </div>
28
- </div>
29
- <div class="tree-container" id="tree-container"></div>
30
- <div class="tree-status" id="tree-status"></div>
31
- </aside>
32
- <main id="content">
33
- <div id="header-container"></div>
34
- <div id="messages"></div>
35
- </main>
36
- <div id="image-modal" class="image-modal">
37
- <img id="modal-image" src="" alt="">
38
- </div>
39
- </div>
40
-
41
- <script id="session-data" type="application/json">{{SESSION_DATA}}</script>
42
-
43
- <!-- Vendored libraries -->
44
- <script>{{MARKED_JS}}</script>
45
-
46
- <!-- highlight.js -->
47
- <script>{{HIGHLIGHT_JS}}</script>
48
-
49
- <!-- Main application code -->
50
- <script>
51
- {{JS}}
52
- </script>
53
- </body>
54
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Session Export</title>
7
+ <style>
8
+ {{CSS}}
9
+ </style>
10
+ </head>
11
+ <body>
12
+ <button id="hamburger" title="Open sidebar"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="none"><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><circle cx="18" cy="12" r="2.5"/><rect x="5" y="6" width="2" height="12"/><path d="M6 12h10c1 0 2 0 2-2V8"/></svg></button>
13
+ <div id="sidebar-overlay"></div>
14
+ <div id="app">
15
+ <aside id="sidebar">
16
+ <div class="sidebar-header">
17
+ <div class="sidebar-controls">
18
+ <input type="text" class="sidebar-search" id="tree-search" placeholder="Search...">
19
+ </div>
20
+ <div class="sidebar-filters">
21
+ <button class="filter-btn active" data-filter="default" title="Hide settings entries">Default</button>
22
+ <button class="filter-btn" data-filter="no-tools" title="Default minus tool results">No-tools</button>
23
+ <button class="filter-btn" data-filter="user-only" title="Only user messages">User</button>
24
+ <button class="filter-btn" data-filter="labeled-only" title="Only labeled entries">Labeled</button>
25
+ <button class="filter-btn" data-filter="all" title="Show everything">All</button>
26
+ <button class="sidebar-close" id="sidebar-close" title="Close">✕</button>
27
+ </div>
28
+ </div>
29
+ <div class="tree-container" id="tree-container"></div>
30
+ <div class="tree-status" id="tree-status"></div>
31
+ </aside>
32
+ <main id="content">
33
+ <div id="header-container"></div>
34
+ <div id="messages"></div>
35
+ </main>
36
+ <div id="image-modal" class="image-modal">
37
+ <img id="modal-image" src="" alt="">
38
+ </div>
39
+ </div>
40
+
41
+ <script id="session-data" type="application/json">{{SESSION_DATA}}</script>
42
+
43
+ <!-- Vendored libraries -->
44
+ <script>{{MARKED_JS}}</script>
45
+
46
+ <!-- highlight.js -->
47
+ <script>{{HIGHLIGHT_JS}}</script>
48
+
49
+ <!-- Main application code -->
50
+ <script>
51
+ {{JS}}
52
+ </script>
53
+ </body>
54
+ </html>
@@ -8,6 +8,6 @@ export type { SlashCommandInfo, SlashCommandLocation, SlashCommandSource } from
8
8
  export { createExtensionRuntime, discoverAndLoadExtensions, loadExtensionFromFactory, loadExtensions, } from "./loader.js";
9
9
  export type { ExtensionErrorListener, ForkHandler, NavigateTreeHandler, NewSessionHandler, ShutdownHandler, SwitchSessionHandler, } from "./runner.js";
10
10
  export { ExtensionRunner } from "./runner.js";
11
- export type { AgentEndEvent, AgentResultEvent, AgentStartEvent, AgentToolResult, AgentToolUpdateCallback, AppAction, AppendEntryHandler, BashToolCallEvent, BashToolResultEvent, BeforeAgentStartEvent, BeforeAgentStartEventResult, CompactOptions, ContextEvent, ContextEventResult, ContextUsage, CustomToolCallEvent, CustomToolResultEvent, EditToolCallEvent, EditToolResultEvent, ExecOptions, ExecResult, Extension, ExtensionActions, ExtensionAPI, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionError, ExtensionEvent, ExtensionFactory, ExtensionFlag, ExtensionHandler, ExtensionRuntime, ExtensionShortcut, ExtensionUIContext, ExtensionUIDialogOptions, ExtensionWidgetOptions, FindToolCallEvent, FindToolResultEvent, GetActiveToolsHandler, GetAllToolsHandler, GetCommandsHandler, GetThinkingLevelHandler, GrepToolCallEvent, GrepToolResultEvent, InputEvent, InputEventResult, InputSource, KeybindingsManager, LoadExtensionsResult, LsToolCallEvent, LsToolResultEvent, MessageEndEvent, MessageRenderer, MessageRenderOptions, MessageStartEvent, MessageUpdateEvent, ModelSelectEvent, ModelSelectSource, ProviderConfig, ProviderModelConfig, ReadToolCallEvent, ReadToolResultEvent, RegisteredCommand, RegisteredTool, ResourcesDiscoverEvent, ResourcesDiscoverResult, SendMessageHandler, SendUserMessageHandler, SessionBeforeCompactEvent, SessionBeforeCompactResult, SessionBeforeForkEvent, SessionBeforeForkResult, SessionBeforeSwitchEvent, SessionBeforeSwitchResult, SessionBeforeTreeEvent, SessionBeforeTreeResult, SessionCompactEvent, SessionEvent, SessionForkEvent, SessionShutdownEvent, SessionStartEvent, SessionSwitchEvent, SessionTreeEvent, SetActiveToolsHandler, SetLabelHandler, SetModelHandler, SetThinkingLevelHandler, TerminalInputHandler, ToolCallEvent, ToolCallEventResult, ToolDefinition, ToolExecutionEndEvent, ToolExecutionStartEvent, ToolExecutionUpdateEvent, ToolInfo, ToolRenderResultOptions, ToolResultEvent, ToolResultEventResult, TreePreparation, TurnEndEvent, TurnStartEvent, UserBashEvent, UserBashEventResult, WidgetPlacement, WriteToolCallEvent, WriteToolResultEvent, } from "./types.js";
11
+ export type { AgentEndEvent, AgentResultEvent, AgentStartEvent, AgentToolResult, AgentToolUpdateCallback, AppAction, AppendEntryHandler, BashToolCallEvent, BashToolResultEvent, BeforeAgentStartEvent, BeforeAgentStartEventResult, CompactOptions, ContextEvent, ContextEventResult, ContextUsage, CustomToolCallEvent, CustomToolResultEvent, EditToolCallEvent, EditToolResultEvent, ExecOptions, ExecResult, Extension, ExtensionActions, ExtensionAPI, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionError, ExtensionEvent, ExtensionEventName, ExtensionFactory, ExtensionFlag, ExtensionFlagOptions, ExtensionFlagValue, ExtensionHandler, ExtensionRuntime, ExtensionShortcut, ExtensionUIContext, ExtensionUIDialogOptions, ExtensionWidgetOptions, FindToolCallEvent, FindToolResultEvent, GetActiveToolsHandler, GetAllToolsHandler, GetCommandsHandler, GetThinkingLevelHandler, GrepToolCallEvent, GrepToolResultEvent, InputEvent, InputEventResult, InputSource, KeybindingsManager, LoadExtensionsResult, LsToolCallEvent, LsToolResultEvent, MessageEndEvent, MessageRenderer, MessageRenderOptions, MessageStartEvent, MessageUpdateEvent, ModelSelectEvent, ModelSelectSource, ProviderConfig, ProviderModelConfig, ReadToolCallEvent, ReadToolResultEvent, RegisteredCommand, RegisteredTool, ResourcesDiscoverEvent, ResourcesDiscoverResult, SendMessageHandler, SendUserMessageHandler, SessionBeforeCompactEvent, SessionBeforeCompactResult, SessionBeforeForkEvent, SessionBeforeForkResult, SessionBeforeSwitchEvent, SessionBeforeSwitchResult, SessionBeforeTreeEvent, SessionBeforeTreeResult, SessionCompactEvent, SessionEvent, SessionForkEvent, SessionShutdownEvent, SessionStartEvent, SessionSwitchEvent, SessionTreeEvent, SetActiveToolsHandler, SetLabelHandler, SetModelHandler, SetThinkingLevelHandler, TerminalInputHandler, ToolCallEvent, ToolCallEventResult, ToolDefinition, ToolExecutionEndEvent, ToolExecutionStartEvent, ToolExecutionUpdateEvent, ToolInfo, ToolRenderResultOptions, ToolResultEvent, ToolResultEventResult, TreePreparation, TurnEndEvent, TurnStartEvent, UserBashEvent, UserBashEventResult, WidgetPlacement, WriteToolCallEvent, WriteToolResultEvent, } from "./types.js";
12
12
  export { isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isReadToolResult, isToolCallEventType, isWriteToolResult, } from "./types.js";
13
13
  export { wrapRegisteredTool, wrapRegisteredTools, wrapToolsWithExtensions, wrapToolWithExtensions, } from "./wrapper.js";
@@ -1 +1 @@
1
- var P=Object.defineProperty;var c=(n,t)=>P(n,"name",{value:t,configurable:!0});import*as d from"node:fs";import{createRequire as T}from"node:module";import*as y from"node:os";import*as l from"node:path";import{fileURLToPath as A}from"node:url";import{createJiti as M}from"@mariozechner/jiti";import*as w from"@pencil-agent/agent-core";import*as k from"@pencil-agent/ai";import*as L from"@pencil-agent/tui";import*as F from"@sinclair/typebox";import{CONFIG_DIR_NAME as C,getAgentDir as N,isBunBinary as _}from"../../config.js";import{createEventBus as I}from"../runtime/event-bus.js";import{execCommand as R}from"../platform/exec/exec.js";async function z(){return{"@sinclair/typebox":F,"@pencil-agent/agent-core":w,"@pencil-agent/tui":L,"@pencil-agent/ai":k,"@pencil-agent/nano-pencil":await import("../../index.js")}}c(z,"getVirtualModules");const m=T(import.meta.url);let h=null;function U(){if(h)return h;const n=l.dirname(A(import.meta.url)),t=l.resolve(n,"../..","index.js"),r=m.resolve("@sinclair/typebox").replace(/[\\/]build[\\/]cjs[\\/]index\.js$/,"");return h={"@pencil-agent/nano-pencil":t,"@pencil-agent/agent-core":m.resolve("@pencil-agent/agent-core"),"@pencil-agent/tui":m.resolve("@pencil-agent/tui"),"@pencil-agent/ai":m.resolve("@pencil-agent/ai"),"@sinclair/typebox":r},h}c(U,"getAliases");const D=/[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;function J(n){return n.replace(D," ")}c(J,"normalizeUnicodeSpaces");function V(n){const t=J(n);return t.startsWith("~/")?l.join(y.homedir(),t.slice(2)):t.startsWith("~")?l.join(y.homedir(),t.slice(1)):t}c(V,"expandPath");function v(n,t){const o=V(n);return l.isAbsolute(o)?o:l.resolve(t,o)}c(v,"resolvePath");function W(){const n=c(()=>{throw new Error("Extension runtime not initialized. Action methods cannot be called during extension loading.")},"notInitialized");return{sendMessage:n,sendUserMessage:n,executeCommand:c(()=>Promise.reject(new Error("Extension runtime not initialized")),"executeCommand"),isIdle:n,appendEntry:n,setSessionName:n,getSessionName:n,setLabel:n,getActiveTools:n,getAllTools:n,setActiveTools:n,getCommands:n,setModel:c(()=>Promise.reject(new Error("Extension runtime not initialized")),"setModel"),getThinkingLevel:n,setThinkingLevel:n,flagValues:new Map,pendingProviderRegistrations:[]}}c(W,"createExtensionRuntime");function E(n,t,o,r,i){return{cwd:o,agentDir:r,on(e,s){const u=n.handlers.get(e)??[];u.push(s),n.handlers.set(e,u)},registerTool(e){n.tools.set(e.name,{definition:e,extensionPath:n.path})},registerCommand(e,s){n.commands.set(e,{name:e,...s})},registerShortcut(e,s){n.shortcuts.set(e,{shortcut:e,extensionPath:n.path,...s})},registerFlag(e,s){n.flags.set(e,{name:e,extensionPath:n.path,...s}),s.default!==void 0&&!t.flagValues.has(e)&&t.flagValues.set(e,s.default)},registerMessageRenderer(e,s){n.messageRenderers.set(e,s)},getFlag(e){if(n.flags.has(e))return t.flagValues.get(e)},sendMessage(e,s){t.sendMessage(e,s)},sendUserMessage(e,s){t.sendUserMessage(e,s)},executeCommand(e){return t.executeCommand(e)},isIdle(){return t.isIdle()},appendEntry(e,s){t.appendEntry(e,s)},setSessionName(e){t.setSessionName(e)},getSessionName(){return t.getSessionName()},setLabel(e,s){t.setLabel(e,s)},exec(e,s,u){return R(e,s,u?.cwd??o,u)},getActiveTools(){return t.getActiveTools()},getAllTools(){return t.getAllTools()},setActiveTools(e){t.setActiveTools(e)},getCommands(){return t.getCommands()},setModel(e){return t.setModel(e)},getThinkingLevel(){return t.getThinkingLevel()},setThinkingLevel(e){t.setThinkingLevel(e)},registerProvider(e,s){t.pendingProviderRegistrations.push({name:e,config:s})},events:i}}c(E,"createExtensionAPI");async function B(n){const r=await M(import.meta.url,{moduleCache:!1,..._?{virtualModules:await z(),tryNative:!1}:{alias:U()}}).import(n,{default:!0});return typeof r!="function"?void 0:r}c(B,"loadExtensionModule");function S(n,t){return{path:n,resolvedPath:t,handlers:new Map,tools:new Map,messageRenderers:new Map,commands:new Map,flags:new Map,shortcuts:new Map}}c(S,"createExtension");async function O(n,t,o,r,i){const a=v(n,t);try{const e=await B(a);if(!e)return{extension:null,error:`Extension does not export a valid factory function: ${n}`};const s=S(n,a),u=E(s,i,t,o,r);return await e(u),{extension:s,error:null}}catch(e){return{extension:null,error:`Failed to load extension: ${e instanceof Error?e.message:String(e)}`}}}c(O,"loadExtension");async function ne(n,t,o,r,i,a="<inline>"){const e=S(a,a),s=E(e,i,t,o,r);return await n(s),e}c(ne,"loadExtensionFromFactory");async function $(n,t,o,r){const i=[],a=[],e=r??I(),s=W(),u=await Promise.all(n.map(f=>O(f,t,o,e,s).then(p=>({...p,path:f}))));for(const{extension:f,error:p,path:g}of u){if(p){a.push({path:g,error:p});continue}f&&i.push(f)}return{extensions:i,errors:a,runtime:s}}c($,"loadExtensions");function j(n){try{const t=d.readFileSync(n,"utf-8"),o=JSON.parse(t);return o.nanopencil&&typeof o.nanopencil=="object"?o.nanopencil:null}catch{return null}}c(j,"readPiManifest");function q(n){return n.endsWith(".ts")||n.endsWith(".js")}c(q,"isExtensionFile");function b(n){const t=l.join(n,"package.json");if(d.existsSync(t)){const i=j(t);if(i?.extensions?.length){const a=[];for(const e of i.extensions){const s=l.resolve(n,e);d.existsSync(s)&&a.push(s)}if(a.length>0)return a}}const o=l.join(n,"index.ts"),r=l.join(n,"index.js");return d.existsSync(o)?[o]:d.existsSync(r)?[r]:null}c(b,"resolveExtensionEntries");function x(n){if(!d.existsSync(n))return[];const t=[];try{const o=d.readdirSync(n,{withFileTypes:!0});for(const r of o){const i=l.join(n,r.name);if((r.isFile()||r.isSymbolicLink())&&q(r.name)){t.push(i);continue}if(r.isDirectory()||r.isSymbolicLink()){const a=b(i);a&&t.push(...a)}}}catch{return[]}return t}c(x,"discoverExtensionsInDir");function G(n){const t=[],o=c(i=>{const a=l.join(i,"package.json");if(!d.existsSync(a))return;const e=j(a);if(e?.extensions?.length)for(const s of e.extensions){const u=l.resolve(i,s);d.existsSync(u)&&t.push(u)}},"scanPackage"),r=c(i=>{if(!d.existsSync(i))return;let a;try{a=d.readdirSync(i,{withFileTypes:!0})}catch{return}for(const e of a)if(!(!e.isDirectory()&&!e.isSymbolicLink())&&!(e.name===".bin"||e.name===".cache")&&e.name!=="@pencil-agent"){if(e.name.startsWith("@")){const s=l.join(i,e.name);let u;try{u=d.readdirSync(s,{withFileTypes:!0})}catch{continue}for(const f of u)(f.isDirectory()||f.isSymbolicLink())&&o(l.join(s,f.name));continue}o(l.join(i,e.name))}},"scanNodeModules");for(const i of n)r(l.join(i,"node_modules"));return t}c(G,"discoverNpmExtensions");async function te(n,t,o=N(),r){const i=[],a=new Set,e=c(f=>{for(const p of f){const g=l.resolve(p);a.has(g)||(a.add(g),i.push(p))}},"addPaths"),s=l.join(t,C,"extensions");e(x(s));const u=l.join(o,"extensions");e(x(u));for(const f of n){const p=v(f,t);if(d.existsSync(p)&&d.statSync(p).isDirectory()){const g=b(p);if(g){e(g);continue}e(x(p));continue}e([p])}return e(G([t,o])),$(i,t,o,r)}c(te,"discoverAndLoadExtensions");export{W as createExtensionRuntime,te as discoverAndLoadExtensions,ne as loadExtensionFromFactory,$ as loadExtensions};
1
+ var b=Object.defineProperty;var c=(n,t)=>b(n,"name",{value:t,configurable:!0});import*as d from"node:fs";import{createRequire as j}from"node:module";import*as x from"node:os";import*as l from"node:path";import{fileURLToPath as T}from"node:url";import{createJiti as _}from"@mariozechner/jiti";import*as w from"@pencil-agent/agent-core";import*as M from"@pencil-agent/ai";import*as k from"@pencil-agent/ai/env";import*as F from"@pencil-agent/ai/events";import*as L from"@pencil-agent/ai/json";import*as N from"@pencil-agent/ai/models";import*as C from"@pencil-agent/ai/oauth";import*as U from"@pencil-agent/ai/overflow";import*as I from"@pencil-agent/ai/registry";import*as R from"@pencil-agent/ai/schema";import*as D from"@pencil-agent/ai/stream";import*as B from"@pencil-agent/ai/types";import*as O from"@pencil-agent/tui";import*as z from"@sinclair/typebox";import{CONFIG_DIR_NAME as J,getAgentDir as V,isBunBinary as W}from"../../config.js";import{createEventBus as $}from"../runtime/event-bus.js";import{execCommand as Q}from"../platform/exec/exec.js";const q=["types","schema","events","models","registry","stream","env","overflow","json","oauth"],H={"@pencil-agent/ai/types":B,"@pencil-agent/ai/schema":R,"@pencil-agent/ai/events":F,"@pencil-agent/ai/models":N,"@pencil-agent/ai/registry":I,"@pencil-agent/ai/stream":D,"@pencil-agent/ai/env":k,"@pencil-agent/ai/overflow":U,"@pencil-agent/ai/json":L,"@pencil-agent/ai/oauth":C};async function G(){return{"@sinclair/typebox":z,"@pencil-agent/agent-core":w,"@pencil-agent/tui":O,"@pencil-agent/ai":M,...H,"@pencil-agent/nano-pencil":await import("../../index.js")}}c(G,"getVirtualModules");const g=j(import.meta.url);let h=null;function K(){if(h)return h;const n=l.dirname(T(import.meta.url)),t=l.resolve(n,"../..","index.js"),a=g.resolve("@sinclair/typebox").replace(/[\\/]build[\\/]cjs[\\/]index\.js$/,""),i=Object.fromEntries(q.map(r=>[`@pencil-agent/ai/${r}`,g.resolve(`@pencil-agent/ai/${r}`)]));return h={"@pencil-agent/nano-pencil":t,"@pencil-agent/agent-core":g.resolve("@pencil-agent/agent-core"),"@pencil-agent/tui":g.resolve("@pencil-agent/tui"),...i,"@pencil-agent/ai":g.resolve("@pencil-agent/ai"),"@sinclair/typebox":a},h}c(K,"getAliases");const X=/[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;function Y(n){return n.replace(X," ")}c(Y,"normalizeUnicodeSpaces");function Z(n){const t=Y(n);return t.startsWith("~/")?l.join(x.homedir(),t.slice(2)):t.startsWith("~")?l.join(x.homedir(),t.slice(1)):t}c(Z,"expandPath");function v(n,t){const o=Z(n);return l.isAbsolute(o)?o:l.resolve(t,o)}c(v,"resolvePath");function ee(){const n=c(()=>{throw new Error("Extension runtime not initialized. Action methods cannot be called during extension loading.")},"notInitialized");return{sendMessage:n,sendUserMessage:n,executeCommand:c(()=>Promise.reject(new Error("Extension runtime not initialized")),"executeCommand"),isIdle:n,clearFollowUpQueue:n,appendEntry:n,setSessionName:n,getSessionName:n,setLabel:n,getActiveTools:n,getAllTools:n,setActiveTools:n,getCommands:n,setModel:c(()=>Promise.reject(new Error("Extension runtime not initialized")),"setModel"),getThinkingLevel:n,setThinkingLevel:n,flagValues:new Map,pendingProviderRegistrations:[]}}c(ee,"createExtensionRuntime");function E(n,t,o,a,i){return{cwd:o,agentDir:a,on(e,s){const u=n.handlers.get(e)??[];u.push(s),n.handlers.set(e,u)},registerTool(e){n.tools.set(e.name,{definition:e,extensionPath:n.path})},registerCommand(e,s){n.commands.set(e,{name:e,...s})},registerShortcut(e,s){n.shortcuts.set(e,{shortcut:e,extensionPath:n.path,...s})},registerFlag(e,s){n.flags.set(e,{name:e,extensionPath:n.path,...s}),s.default!==void 0&&!t.flagValues.has(e)&&t.flagValues.set(e,s.default)},registerMessageRenderer(e,s){n.messageRenderers.set(e,s)},getFlag(e){if(n.flags.has(e))return t.flagValues.get(e)},sendMessage(e,s){t.sendMessage(e,s)},sendUserMessage(e,s){t.sendUserMessage(e,s)},executeCommand(e){return t.executeCommand(e)},isIdle(){return t.isIdle()},clearFollowUpQueue(){t.clearFollowUpQueue()},appendEntry(e,s){t.appendEntry(e,s)},setSessionName(e){t.setSessionName(e)},getSessionName(){return t.getSessionName()},setLabel(e,s){t.setLabel(e,s)},exec(e,s,u){return Q(e,s,u?.cwd??o,u)},getActiveTools(){return t.getActiveTools()},getAllTools(){return t.getAllTools()},setActiveTools(e){t.setActiveTools(e)},getCommands(){return t.getCommands()},setModel(e){return t.setModel(e)},getThinkingLevel(){return t.getThinkingLevel()},setThinkingLevel(e){t.setThinkingLevel(e)},registerProvider(e,s){t.pendingProviderRegistrations.push({name:e,config:s})},events:i}}c(E,"createExtensionAPI");async function ne(n){const a=await _(import.meta.url,{moduleCache:!1,...W?{virtualModules:await G(),tryNative:!1}:{alias:K()}}).import(n,{default:!0});return typeof a!="function"?void 0:a}c(ne,"loadExtensionModule");function S(n,t){return{path:n,resolvedPath:t,handlers:new Map,tools:new Map,messageRenderers:new Map,commands:new Map,flags:new Map,shortcuts:new Map}}c(S,"createExtension");async function te(n,t,o,a,i){const r=v(n,t);try{const e=await ne(r);if(!e)return{extension:null,error:`Extension does not export a valid factory function: ${n}`};const s=S(n,r),u=E(s,i,t,o,a);return await e(u),{extension:s,error:null}}catch(e){return{extension:null,error:`Failed to load extension: ${e instanceof Error?e.message:String(e)}`}}}c(te,"loadExtension");async function fe(n,t,o,a,i,r="<inline>"){const e=S(r,r),s=E(e,i,t,o,a);return await n(s),e}c(fe,"loadExtensionFromFactory");async function se(n,t,o,a){const i=[],r=[],e=a??$(),s=ee(),u=await Promise.all(n.map(p=>te(p,t,o,e,s).then(f=>({...f,path:p}))));for(const{extension:p,error:f,path:m}of u){if(f){r.push({path:m,error:f});continue}p&&i.push(p)}return{extensions:i,errors:r,runtime:s}}c(se,"loadExtensions");function A(n){try{const t=d.readFileSync(n,"utf-8"),o=JSON.parse(t);return o.nanopencil&&typeof o.nanopencil=="object"?o.nanopencil:null}catch{return null}}c(A,"readPiManifest");function oe(n){return n.endsWith(".ts")||n.endsWith(".js")}c(oe,"isExtensionFile");function P(n){const t=l.join(n,"package.json");if(d.existsSync(t)){const i=A(t);if(i?.extensions?.length){const r=[];for(const e of i.extensions){const s=l.resolve(n,e);d.existsSync(s)&&r.push(s)}if(r.length>0)return r}}const o=l.join(n,"index.ts"),a=l.join(n,"index.js");return d.existsSync(o)?[o]:d.existsSync(a)?[a]:null}c(P,"resolveExtensionEntries");function y(n){if(!d.existsSync(n))return[];const t=[];try{const o=d.readdirSync(n,{withFileTypes:!0});for(const a of o){const i=l.join(n,a.name);if((a.isFile()||a.isSymbolicLink())&&oe(a.name)){t.push(i);continue}if(a.isDirectory()||a.isSymbolicLink()){const r=P(i);r&&t.push(...r)}}}catch{return[]}return t}c(y,"discoverExtensionsInDir");function ie(n){const t=[],o=c(i=>{const r=l.join(i,"package.json");if(!d.existsSync(r))return;const e=A(r);if(e?.extensions?.length)for(const s of e.extensions){const u=l.resolve(i,s);d.existsSync(u)&&t.push(u)}},"scanPackage"),a=c(i=>{if(!d.existsSync(i))return;let r;try{r=d.readdirSync(i,{withFileTypes:!0})}catch{return}for(const e of r)if(!(!e.isDirectory()&&!e.isSymbolicLink())&&!(e.name===".bin"||e.name===".cache")&&e.name!=="@pencil-agent"){if(e.name.startsWith("@")){const s=l.join(i,e.name);let u;try{u=d.readdirSync(s,{withFileTypes:!0})}catch{continue}for(const p of u)(p.isDirectory()||p.isSymbolicLink())&&o(l.join(s,p.name));continue}o(l.join(i,e.name))}},"scanNodeModules");for(const i of n)a(l.join(i,"node_modules"));return t}c(ie,"discoverNpmExtensions");async function me(n,t,o=V(),a){const i=[],r=new Set,e=c(p=>{for(const f of p){const m=l.resolve(f);r.has(m)||(r.add(m),i.push(f))}},"addPaths"),s=l.join(t,J,"extensions");e(y(s));const u=l.join(o,"extensions");e(y(u));for(const p of n){const f=v(p,t);if(d.existsSync(f)&&d.statSync(f).isDirectory()){const m=P(f);if(m){e(m);continue}e(y(f));continue}e([f])}return e(ie([t,o])),se(i,t,o,a)}c(me,"discoverAndLoadExtensions");export{ee as createExtensionRuntime,me as discoverAndLoadExtensions,fe as loadExtensionFromFactory,se as loadExtensions};
@@ -76,6 +76,7 @@ export declare class ExtensionRunner {
76
76
  private isIdleFn;
77
77
  private waitForIdleFn;
78
78
  private abortFn;
79
+ private clearFollowUpQueueFn;
79
80
  private hasPendingMessagesFn;
80
81
  private getContextUsageFn;
81
82
  private compactFn;
@@ -1,3 +1,3 @@
1
- var k=Object.defineProperty;var s=(f,e)=>k(f,"name",{value:e,configurable:!0});import{theme as E}from"../../modes/interactive/theme/theme.js";import{classifyArgsSignature as v,HOOK_SAMPLE_RATES as C,runWithExtCallerContext as x}from"../platform/telemetry/index.js";const T=["interrupt","clear","exit","suspend","cycleThinkingLevel","cycleModelForward","cycleModelBackward","selectModel","selectProviderThenModel","expandTools","toggleThinking","externalEditor","followUp","submit","selectConfirm","selectCancel","copy","deleteToLineEnd"],P=s(f=>{const e={};for(const[n,t]of Object.entries(f)){const o=n,i=Array.isArray(t)?t:[t],a=T.includes(o);for(const r of i){const c=r.toLowerCase();e[c]={action:o,restrictOverride:a}}}return e},"buildBuiltinKeybindings");async function _(f){return f?.hasHandlers("session_shutdown")?(await f.emit({type:"session_shutdown"}),!0):!1}s(_,"emitSessionShutdownEvent");const p={select:s(async()=>{},"select"),confirm:s(async()=>!1,"confirm"),input:s(async()=>{},"input"),notify:s(()=>{},"notify"),onTerminalInput:s(()=>()=>{},"onTerminalInput"),setStatus:s(()=>{},"setStatus"),setWorkingMessage:s(()=>{},"setWorkingMessage"),setWidget:s(()=>{},"setWidget"),setFooter:s(()=>{},"setFooter"),setHeader:s(()=>{},"setHeader"),setTitle:s(()=>{},"setTitle"),custom:s(async()=>{},"custom"),pasteToEditor:s(()=>{},"pasteToEditor"),setEditorText:s(()=>{},"setEditorText"),getEditorText:s(()=>"","getEditorText"),editor:s(async()=>{},"editor"),openExternalEditor:s(async()=>!1,"openExternalEditor"),setEditorComponent:s(()=>{},"setEditorComponent"),get theme(){return E},getAllThemes:s(()=>[],"getAllThemes"),getTheme:s(()=>{},"getTheme"),setTheme:s(f=>({success:!1,error:"UI not available"}),"setTheme"),getToolsExpanded:s(()=>!1,"getToolsExpanded"),setToolsExpanded:s(()=>{},"setToolsExpanded")};class H{static{s(this,"ExtensionRunner")}extensions;runtime;uiContext;cwd;agentDir;sessionManager;modelRegistry;errorListeners=new Set;getModel=s(()=>{},"getModel");completeSimpleFn=s(async()=>{},"completeSimpleFn");completeSimpleWithUsageFn=s(async()=>{},"completeSimpleWithUsageFn");completeJsonFn;isIdleFn=s(()=>!0,"isIdleFn");waitForIdleFn=s(async()=>{},"waitForIdleFn");abortFn=s(()=>{},"abortFn");hasPendingMessagesFn=s(()=>!1,"hasPendingMessagesFn");getContextUsageFn=s(()=>{},"getContextUsageFn");compactFn=s(()=>{},"compactFn");getSystemPromptFn=s(()=>"","getSystemPromptFn");getSoulManagerFn=s(()=>{},"getSoulManagerFn");getSettingsFn=s(()=>({}),"getSettingsFn");getSkillsFn=s(()=>[],"getSkillsFn");newSessionHandler=s(async()=>({cancelled:!1}),"newSessionHandler");forkHandler=s(async()=>({cancelled:!1}),"forkHandler");navigateTreeHandler=s(async()=>({cancelled:!1}),"navigateTreeHandler");switchSessionHandler=s(async()=>({cancelled:!1}),"switchSessionHandler");reloadHandler=s(async()=>{},"reloadHandler");shutdownHandler=s(()=>{},"shutdownHandler");shortcutDiagnostics=[];commandDiagnostics=[];telemetrySink;_beforeAgentStartTimeoutMs=1500;get beforeAgentStartTimeoutMs(){return this._beforeAgentStartTimeoutMs??1500}beforeAgentStartTimeoutSentinel=Symbol("before_agent_start_timeout");beforeAgentStartTimeoutLastReported=new Map;constructor(e,n,t,o,i,a){this.extensions=e,this.runtime=n,this.uiContext=p,this.cwd=t,this.agentDir=o,this.sessionManager=i,this.modelRegistry=a}async withTimeout(e,n){return new Promise(t=>{const o=setTimeout(()=>t(this.beforeAgentStartTimeoutSentinel),n);Promise.resolve(e).then(i=>{clearTimeout(o),t(i)}).catch(()=>{clearTimeout(o),t(this.beforeAgentStartTimeoutSentinel)})})}reportBeforeAgentStartTimeout(e){const n=Date.now(),t=this.beforeAgentStartTimeoutLastReported.get(e)??0;n-t<6e4||(this.beforeAgentStartTimeoutLastReported.set(e,n),console.warn(`Extension before_agent_start timed out (${this.beforeAgentStartTimeoutMs}ms): ${e}`))}bindCore(e,n){this.runtime.sendMessage=e.sendMessage,this.runtime.sendUserMessage=e.sendUserMessage,this.runtime.executeCommand=e.executeCommand,this.runtime.appendEntry=e.appendEntry,this.runtime.setSessionName=e.setSessionName,this.runtime.getSessionName=e.getSessionName,this.runtime.setLabel=e.setLabel,this.runtime.getActiveTools=e.getActiveTools,this.runtime.getAllTools=e.getAllTools,this.runtime.setActiveTools=e.setActiveTools,this.runtime.getCommands=e.getCommands,this.runtime.setModel=e.setModel,this.runtime.getThinkingLevel=e.getThinkingLevel,this.runtime.setThinkingLevel=e.setThinkingLevel,this.getModel=n.getModel,this.completeSimpleFn=n.completeSimple,this.completeSimpleWithUsageFn=n.completeSimpleWithUsage,this.completeJsonFn=n.completeJson,this.isIdleFn=n.isIdle,this.runtime.isIdle=()=>this.isIdleFn(),this.abortFn=n.abort,this.hasPendingMessagesFn=n.hasPendingMessages,this.shutdownHandler=n.shutdown,this.getContextUsageFn=n.getContextUsage,this.compactFn=n.compact,this.getSystemPromptFn=n.getSystemPrompt,this.getSoulManagerFn=n.getSoulManager,this.getSettingsFn=n.getSettings,this.getSkillsFn=n.getSkills;for(const{name:t,config:o}of this.runtime.pendingProviderRegistrations)this.modelRegistry.registerProvider(t,o);this.runtime.pendingProviderRegistrations=[]}bindCommandContext(e){if(e){this.waitForIdleFn=e.waitForIdle,this.newSessionHandler=e.newSession,this.forkHandler=e.fork,this.navigateTreeHandler=e.navigateTree,this.switchSessionHandler=e.switchSession,this.reloadHandler=e.reload;return}this.waitForIdleFn=async()=>{},this.newSessionHandler=async()=>({cancelled:!1}),this.forkHandler=async()=>({cancelled:!1}),this.navigateTreeHandler=async()=>({cancelled:!1}),this.switchSessionHandler=async()=>({cancelled:!1}),this.reloadHandler=async()=>{}}setUIContext(e){this.uiContext=e??p}getUIContext(){return this.uiContext}hasUI(){return this.uiContext===p?!1:this.uiContext.__nonInteractive!==!0}getExtensionPaths(){return this.extensions.map(e=>e.path)}getAllRegisteredTools(){const e=new Map;for(const n of this.extensions)for(const t of n.tools.values())e.has(t.definition.name)||e.set(t.definition.name,t);return Array.from(e.values())}getToolDefinition(e){for(const n of this.extensions){const t=n.tools.get(e);if(t)return t.definition}}getFlags(){const e=new Map;for(const n of this.extensions)for(const[t,o]of n.flags)e.has(t)||e.set(t,o);return e}setFlagValue(e,n){this.runtime.flagValues.set(e,n)}getFlagValues(){return new Map(this.runtime.flagValues)}getShortcuts(e){this.shortcutDiagnostics=[];const n=P(e),t=new Map,o=s((i,a)=>{this.shortcutDiagnostics.push({type:"warning",message:i,path:a}),this.hasUI()||console.warn(i)},"addDiagnostic");for(const i of this.extensions)for(const[a,r]of i.shortcuts){const c=a.toLowerCase(),l=n[c];if(l?.restrictOverride===!0){o(`Extension shortcut '${a}' from ${r.extensionPath} conflicts with built-in shortcut. Skipping.`,r.extensionPath);continue}l?.restrictOverride===!1&&o(`Extension shortcut conflict: '${a}' is built-in shortcut for ${l.action} and ${r.extensionPath}. Using ${r.extensionPath}.`,r.extensionPath);const h=t.get(c);h&&o(`Extension shortcut conflict: '${a}' registered by both ${h.extensionPath} and ${r.extensionPath}. Using ${r.extensionPath}.`,r.extensionPath),t.set(c,r)}return t}getShortcutDiagnostics(){return this.shortcutDiagnostics}onError(e){return this.errorListeners.add(e),()=>this.errorListeners.delete(e)}emitError(e){for(const n of this.errorListeners)n(e)}setBeforeAgentStartTimeout(e){this._beforeAgentStartTimeoutMs=e}dispose(){this.errorListeners.clear(),this.beforeAgentStartTimeoutLastReported.clear(),this.shortcutDiagnostics=[],this.commandDiagnostics=[];for(const e of this.extensions)e.handlers.clear()}hasHandlers(e){for(const n of this.extensions){const t=n.handlers.get(e);if(t&&t.length>0)return!0}return!1}getMessageRenderer(e){for(const n of this.extensions){const t=n.messageRenderers.get(e);if(t)return t}}getRegisteredCommands(e){this.commandDiagnostics=[];const n=[],t=new Map;for(const o of this.extensions)for(const i of o.commands.values()){if(e?.has(i.name)){const r=`Extension command '${i.name}' from ${o.path} conflicts with built-in commands. Skipping.`;this.commandDiagnostics.push({type:"warning",message:r,path:o.path}),this.hasUI()||console.warn(r);continue}const a=t.get(i.name);if(a){const r=`Extension command '${i.name}' from ${o.path} conflicts with ${a}. Skipping.`;this.commandDiagnostics.push({type:"warning",message:r,path:o.path}),this.hasUI()||console.warn(r);continue}t.set(i.name,o.path),n.push(i)}return n}getCommandDiagnostics(){return this.commandDiagnostics}getRegisteredCommandsWithPaths(){const e=[];for(const n of this.extensions)for(const t of n.commands.values())e.push({command:t,extensionPath:n.path});return e}getCommand(e){for(const n of this.extensions){const t=n.commands.get(e);if(t)return t}}findCommandOwner(e){for(const n of this.extensions)if(n.commands.has(e))return n}deriveExtensionName(e){const t=(e.path||e.resolvedPath||"").replace(/\/+$/,"").split(/[\\/]/);return t[t.length-1]||"unknown"}setTelemetrySink(e){this.telemetrySink=e}writeLlmCallEvent(e){try{this.telemetrySink?.writeLlmCallEvent(e)}catch{}}invokeHookHandler(e,n,t){const o=this.deriveExtensionName(e),i={extensionName:o,callerContext:`hook:${n}`,isUserInitiated:!1};return x(i,async()=>{const a=C[n]??1;if(a<1&&Math.random()>=a)return await t();const r=new Date,c=performance.now();let l=!0,h=null;try{return await t()}catch(u){throw l=!1,h=u instanceof Error?u.constructor.name:"unknown",u}finally{try{this.telemetrySink?.writeHookEvent({extensionName:o,hookName:n,durationMs:Math.round(performance.now()-c),ok:l,errorCode:h,sampleRate:a,recordedAt:r})}catch{}}})}async invokeCommand(e,n,t,o){const i=this.getCommand(e);if(!i)return{found:!1};const a=this.findCommandOwner(e),r=a?this.deriveExtensionName(a):"unknown",c=new Date,l=performance.now();let h="ok",u=null,m;const d=v(n),y={extensionName:r,callerContext:d==="no-args"?`command:/${e}`:`command:/${e} ${d}`,isUserInitiated:!0,sessionId:o?.sessionId??null,runId:o?.runId??null,variant:o?.variant??null};try{await x(y,()=>i.handler(n,t))}catch(g){h="error",u=g instanceof Error?g.constructor.name:"unknown",m=g,this.emitError({extensionPath:`command:${e}`,event:"command",error:g instanceof Error?g.message:String(g)})}const S=Math.round(performance.now()-l),w=new Date;try{this.telemetrySink?.writeCommandEvent({extensionName:r,commandName:e,argsSignature:d,argsLength:n.length,outcome:h,errorCode:u,durationMs:S,startedAt:c,endedAt:w,sessionId:o?.sessionId??null,runId:o?.runId??null,variant:o?.variant??null})}catch{}return{found:!0}}shutdown(){this.shutdownHandler()}createContext(){const e=this.getModel;return{ui:this.uiContext,hasUI:this.hasUI(),cwd:this.cwd,agentDir:this.agentDir,sessionManager:this.sessionManager,modelRegistry:this.modelRegistry,get model(){return e()},completeSimple:s((n,t)=>this.completeSimpleFn(n,t),"completeSimple"),completeSimpleWithUsage:s((n,t)=>this.completeSimpleWithUsageFn(n,t),"completeSimpleWithUsage"),completeJson:this.completeJsonFn?(n,t,o,i)=>this.completeJsonFn(n,t,o,i):void 0,isIdle:s(()=>this.isIdleFn(),"isIdle"),abort:s(()=>this.abortFn(),"abort"),hasPendingMessages:s(()=>this.hasPendingMessagesFn(),"hasPendingMessages"),shutdown:s(()=>this.shutdownHandler(),"shutdown"),getContextUsage:s(()=>this.getContextUsageFn(),"getContextUsage"),compact:s(n=>this.compactFn(n),"compact"),getSystemPrompt:s(()=>this.getSystemPromptFn(),"getSystemPrompt"),getSoulManager:s(()=>this.getSoulManagerFn(),"getSoulManager"),getSettings:s(()=>this.getSettingsFn(),"getSettings"),getSkills:s(()=>this.getSkillsFn(),"getSkills")}}createCommandContext(){return{...this.createContext(),waitForIdle:s(()=>this.waitForIdleFn(),"waitForIdle"),newSession:s(e=>this.newSessionHandler(e),"newSession"),fork:s(e=>this.forkHandler(e),"fork"),navigateTree:s((e,n)=>this.navigateTreeHandler(e,n),"navigateTree"),switchSession:s(e=>this.switchSessionHandler(e),"switchSession"),reload:s(()=>this.reloadHandler(),"reload")}}isSessionBeforeEvent(e){return e.type==="session_before_switch"||e.type==="session_before_fork"||e.type==="session_before_compact"||e.type==="session_before_tree"}async emit(e){const n=this.createContext();let t;for(const o of this.extensions){const i=o.handlers.get(e.type);if(!(!i||i.length===0))for(const a of i)try{const r=await this.invokeHookHandler(o,e.type,()=>a(e,n));if(this.isSessionBeforeEvent(e)&&r&&(t=r,t.cancel))return t}catch(r){const c=r instanceof Error?r.message:String(r),l=r instanceof Error?r.stack:void 0;this.emitError({extensionPath:o.path,event:e.type,error:c,stack:l})}}return t}async emitToolResult(e){const n=this.createContext(),t={...e};let o=!1;for(const i of this.extensions){const a=i.handlers.get("tool_result");if(!(!a||a.length===0))for(const r of a)try{const c=await this.invokeHookHandler(i,"tool_result",()=>r(t,n));if(!c)continue;c.content!==void 0&&(t.content=c.content,o=!0),c.details!==void 0&&(t.details=c.details,o=!0),c.isError!==void 0&&(t.isError=c.isError,o=!0)}catch(c){const l=c instanceof Error?c.message:String(c),h=c instanceof Error?c.stack:void 0;this.emitError({extensionPath:i.path,event:"tool_result",error:l,stack:h})}}if(o)return{content:t.content,details:t.details,isError:t.isError}}async emitToolCall(e){const n=this.createContext();let t;for(const o of this.extensions){const i=o.handlers.get("tool_call");if(!(!i||i.length===0))for(const a of i){const r=await this.invokeHookHandler(o,"tool_call",()=>a(e,n));if(r&&(t=r,t.block))return t}}return t}async emitUserBash(e){const n=this.createContext();for(const t of this.extensions){const o=t.handlers.get("user_bash");if(!(!o||o.length===0))for(const i of o)try{const a=await this.invokeHookHandler(t,"user_bash",()=>i(e,n));if(a)return a}catch(a){const r=a instanceof Error?a.message:String(a),c=a instanceof Error?a.stack:void 0;this.emitError({extensionPath:t.path,event:"user_bash",error:r,stack:c})}}}async emitContext(e){const n=this.createContext();let t=structuredClone(e);for(const o of this.extensions){const i=o.handlers.get("context");if(!(!i||i.length===0))for(const a of i)try{const r={type:"context",messages:t},c=await this.invokeHookHandler(o,"context",()=>a(r,n));c&&c.messages&&(t=c.messages)}catch(r){const c=r instanceof Error?r.message:String(r),l=r instanceof Error?r.stack:void 0;this.emitError({extensionPath:o.path,event:"context",error:c,stack:l})}}return t}async emitBeforeAgentStart(e,n,t){const o=this.createContext(),i=[];let a=t,r=!1;for(const c of this.extensions){const l=c.handlers.get("before_agent_start");if(!(!l||l.length===0))for(const h of l)try{const u={type:"before_agent_start",prompt:e,images:n,systemPrompt:a},m=await this.withTimeout(this.invokeHookHandler(c,"before_agent_start",()=>h(u,o)),this.beforeAgentStartTimeoutMs);if(m===this.beforeAgentStartTimeoutSentinel){this.reportBeforeAgentStartTimeout(c.path);continue}if(m){const d=m;d.message&&i.push(d.message),d.systemPrompt!==void 0&&(a=d.systemPrompt,r=!0),d.appendSystemPrompt!==void 0&&(a=this.appendSystemPrompt(a,d.appendSystemPrompt),r=!0)}}catch(u){const m=u instanceof Error?u.message:String(u),d=u instanceof Error?u.stack:void 0;this.emitError({extensionPath:c.path,event:"before_agent_start",error:m,stack:d})}}if(i.length>0||r)return{messages:i.length>0?i:void 0,systemPrompt:r?a:void 0}}appendSystemPrompt(e,n){const t=n.trim();return t?`${e}
1
+ var k=Object.defineProperty;var s=(f,e)=>k(f,"name",{value:e,configurable:!0});import{theme as E}from"../../modes/interactive/theme/theme.js";import{classifyArgsSignature as F,HOOK_SAMPLE_RATES as v,runWithExtCallerContext as x}from"../platform/telemetry/index.js";const C=["interrupt","clear","exit","suspend","cycleThinkingLevel","cycleModelForward","cycleModelBackward","selectModel","selectProviderThenModel","expandTools","toggleThinking","externalEditor","followUp","submit","selectConfirm","selectCancel","copy","deleteToLineEnd"],T=s(f=>{const e={};for(const[n,t]of Object.entries(f)){const o=n,i=Array.isArray(t)?t:[t],a=C.includes(o);for(const r of i){const l=r.toLowerCase();e[l]={action:o,restrictOverride:a}}}return e},"buildBuiltinKeybindings");async function _(f){return f?.hasHandlers("session_shutdown")?(await f.emit({type:"session_shutdown"}),!0):!1}s(_,"emitSessionShutdownEvent");const p={select:s(async()=>{},"select"),confirm:s(async()=>!1,"confirm"),input:s(async()=>{},"input"),notify:s(()=>{},"notify"),onTerminalInput:s(()=>()=>{},"onTerminalInput"),setStatus:s(()=>{},"setStatus"),setWorkingMessage:s(()=>{},"setWorkingMessage"),setWidget:s(()=>{},"setWidget"),setFooter:s(()=>{},"setFooter"),setHeader:s(()=>{},"setHeader"),setTitle:s(()=>{},"setTitle"),custom:s(async()=>{},"custom"),pasteToEditor:s(()=>{},"pasteToEditor"),setEditorText:s(()=>{},"setEditorText"),getEditorText:s(()=>"","getEditorText"),editor:s(async()=>{},"editor"),openExternalEditor:s(async()=>!1,"openExternalEditor"),setEditorComponent:s(()=>{},"setEditorComponent"),get theme(){return E},getAllThemes:s(()=>[],"getAllThemes"),getTheme:s(()=>{},"getTheme"),setTheme:s(f=>({success:!1,error:"UI not available"}),"setTheme"),getToolsExpanded:s(()=>!1,"getToolsExpanded"),setToolsExpanded:s(()=>{},"setToolsExpanded")};class H{static{s(this,"ExtensionRunner")}extensions;runtime;uiContext;cwd;agentDir;sessionManager;modelRegistry;errorListeners=new Set;getModel=s(()=>{},"getModel");completeSimpleFn=s(async()=>{},"completeSimpleFn");completeSimpleWithUsageFn=s(async()=>{},"completeSimpleWithUsageFn");completeJsonFn;isIdleFn=s(()=>!0,"isIdleFn");waitForIdleFn=s(async()=>{},"waitForIdleFn");abortFn=s(()=>{},"abortFn");clearFollowUpQueueFn=s(()=>{},"clearFollowUpQueueFn");hasPendingMessagesFn=s(()=>!1,"hasPendingMessagesFn");getContextUsageFn=s(()=>{},"getContextUsageFn");compactFn=s(()=>{},"compactFn");getSystemPromptFn=s(()=>"","getSystemPromptFn");getSoulManagerFn=s(()=>{},"getSoulManagerFn");getSettingsFn=s(()=>({}),"getSettingsFn");getSkillsFn=s(()=>[],"getSkillsFn");newSessionHandler=s(async()=>({cancelled:!1}),"newSessionHandler");forkHandler=s(async()=>({cancelled:!1}),"forkHandler");navigateTreeHandler=s(async()=>({cancelled:!1}),"navigateTreeHandler");switchSessionHandler=s(async()=>({cancelled:!1}),"switchSessionHandler");reloadHandler=s(async()=>{},"reloadHandler");shutdownHandler=s(()=>{},"shutdownHandler");shortcutDiagnostics=[];commandDiagnostics=[];telemetrySink;_beforeAgentStartTimeoutMs=1500;get beforeAgentStartTimeoutMs(){return this._beforeAgentStartTimeoutMs??1500}beforeAgentStartTimeoutSentinel=Symbol("before_agent_start_timeout");beforeAgentStartTimeoutLastReported=new Map;constructor(e,n,t,o,i,a){this.extensions=e,this.runtime=n,this.uiContext=p,this.cwd=t,this.agentDir=o,this.sessionManager=i,this.modelRegistry=a}async withTimeout(e,n){return new Promise(t=>{const o=setTimeout(()=>t(this.beforeAgentStartTimeoutSentinel),n);Promise.resolve(e).then(i=>{clearTimeout(o),t(i)}).catch(()=>{clearTimeout(o),t(this.beforeAgentStartTimeoutSentinel)})})}reportBeforeAgentStartTimeout(e){const n=Date.now(),t=this.beforeAgentStartTimeoutLastReported.get(e)??0;n-t<6e4||(this.beforeAgentStartTimeoutLastReported.set(e,n),console.warn(`Extension before_agent_start timed out (${this.beforeAgentStartTimeoutMs}ms): ${e}`))}bindCore(e,n){this.runtime.sendMessage=e.sendMessage,this.runtime.sendUserMessage=e.sendUserMessage,this.runtime.executeCommand=e.executeCommand,this.runtime.appendEntry=e.appendEntry,this.runtime.setSessionName=e.setSessionName,this.runtime.getSessionName=e.getSessionName,this.runtime.setLabel=e.setLabel,this.runtime.getActiveTools=e.getActiveTools,this.runtime.getAllTools=e.getAllTools,this.runtime.setActiveTools=e.setActiveTools,this.runtime.getCommands=e.getCommands,this.runtime.setModel=e.setModel,this.runtime.getThinkingLevel=e.getThinkingLevel,this.runtime.setThinkingLevel=e.setThinkingLevel,this.getModel=n.getModel,this.completeSimpleFn=n.completeSimple,this.completeSimpleWithUsageFn=n.completeSimpleWithUsage,this.completeJsonFn=n.completeJson,this.isIdleFn=n.isIdle,this.runtime.isIdle=()=>this.isIdleFn(),this.abortFn=n.abort,this.clearFollowUpQueueFn=n.clearFollowUpQueue,this.runtime.clearFollowUpQueue=()=>this.clearFollowUpQueueFn(),this.hasPendingMessagesFn=n.hasPendingMessages,this.shutdownHandler=n.shutdown,this.getContextUsageFn=n.getContextUsage,this.compactFn=n.compact,this.getSystemPromptFn=n.getSystemPrompt,this.getSoulManagerFn=n.getSoulManager,this.getSettingsFn=n.getSettings,this.getSkillsFn=n.getSkills;for(const{name:t,config:o}of this.runtime.pendingProviderRegistrations)this.modelRegistry.registerProvider(t,o);this.runtime.pendingProviderRegistrations=[]}bindCommandContext(e){if(e){this.waitForIdleFn=e.waitForIdle,this.newSessionHandler=e.newSession,this.forkHandler=e.fork,this.navigateTreeHandler=e.navigateTree,this.switchSessionHandler=e.switchSession,this.reloadHandler=e.reload;return}this.waitForIdleFn=async()=>{},this.newSessionHandler=async()=>({cancelled:!1}),this.forkHandler=async()=>({cancelled:!1}),this.navigateTreeHandler=async()=>({cancelled:!1}),this.switchSessionHandler=async()=>({cancelled:!1}),this.reloadHandler=async()=>{}}setUIContext(e){this.uiContext=e??p}getUIContext(){return this.uiContext}hasUI(){return this.uiContext===p?!1:this.uiContext.__nonInteractive!==!0}getExtensionPaths(){return this.extensions.map(e=>e.path)}getAllRegisteredTools(){const e=new Map;for(const n of this.extensions)for(const t of n.tools.values())e.has(t.definition.name)||e.set(t.definition.name,t);return Array.from(e.values())}getToolDefinition(e){for(const n of this.extensions){const t=n.tools.get(e);if(t)return t.definition}}getFlags(){const e=new Map;for(const n of this.extensions)for(const[t,o]of n.flags)e.has(t)||e.set(t,o);return e}setFlagValue(e,n){this.runtime.flagValues.set(e,n)}getFlagValues(){return new Map(this.runtime.flagValues)}getShortcuts(e){this.shortcutDiagnostics=[];const n=T(e),t=new Map,o=s((i,a)=>{this.shortcutDiagnostics.push({type:"warning",message:i,path:a}),this.hasUI()||console.warn(i)},"addDiagnostic");for(const i of this.extensions)for(const[a,r]of i.shortcuts){const l=a.toLowerCase(),c=n[l];if(c?.restrictOverride===!0){o(`Extension shortcut '${a}' from ${r.extensionPath} conflicts with built-in shortcut. Skipping.`,r.extensionPath);continue}c?.restrictOverride===!1&&o(`Extension shortcut conflict: '${a}' is built-in shortcut for ${c.action} and ${r.extensionPath}. Using ${r.extensionPath}.`,r.extensionPath);const h=t.get(l);h&&o(`Extension shortcut conflict: '${a}' registered by both ${h.extensionPath} and ${r.extensionPath}. Using ${r.extensionPath}.`,r.extensionPath),t.set(l,r)}return t}getShortcutDiagnostics(){return this.shortcutDiagnostics}onError(e){return this.errorListeners.add(e),()=>this.errorListeners.delete(e)}emitError(e){for(const n of this.errorListeners)n(e)}setBeforeAgentStartTimeout(e){this._beforeAgentStartTimeoutMs=e}dispose(){this.errorListeners.clear(),this.beforeAgentStartTimeoutLastReported.clear(),this.shortcutDiagnostics=[],this.commandDiagnostics=[];for(const e of this.extensions)e.handlers.clear()}hasHandlers(e){for(const n of this.extensions){const t=n.handlers.get(e);if(t&&t.length>0)return!0}return!1}getMessageRenderer(e){for(const n of this.extensions){const t=n.messageRenderers.get(e);if(t)return t}}getRegisteredCommands(e){this.commandDiagnostics=[];const n=[],t=new Map;for(const o of this.extensions)for(const i of o.commands.values()){if(e?.has(i.name)){const r=`Extension command '${i.name}' from ${o.path} conflicts with built-in commands. Skipping.`;this.commandDiagnostics.push({type:"warning",message:r,path:o.path}),this.hasUI()||console.warn(r);continue}const a=t.get(i.name);if(a){const r=`Extension command '${i.name}' from ${o.path} conflicts with ${a}. Skipping.`;this.commandDiagnostics.push({type:"warning",message:r,path:o.path}),this.hasUI()||console.warn(r);continue}t.set(i.name,o.path),n.push(i)}return n}getCommandDiagnostics(){return this.commandDiagnostics}getRegisteredCommandsWithPaths(){const e=[];for(const n of this.extensions)for(const t of n.commands.values())e.push({command:t,extensionPath:n.path});return e}getCommand(e){for(const n of this.extensions){const t=n.commands.get(e);if(t)return t}}findCommandOwner(e){for(const n of this.extensions)if(n.commands.has(e))return n}deriveExtensionName(e){const t=(e.path||e.resolvedPath||"").replace(/\/+$/,"").split(/[\\/]/);return t[t.length-1]||"unknown"}setTelemetrySink(e){this.telemetrySink=e}writeLlmCallEvent(e){try{this.telemetrySink?.writeLlmCallEvent(e)}catch{}}invokeHookHandler(e,n,t){const o=this.deriveExtensionName(e),i={extensionName:o,callerContext:`hook:${n}`,isUserInitiated:!1};return x(i,async()=>{const a=v[n]??1;if(a<1&&Math.random()>=a)return await t();const r=new Date,l=performance.now();let c=!0,h=null;try{return await t()}catch(u){throw c=!1,h=u instanceof Error?u.constructor.name:"unknown",u}finally{try{this.telemetrySink?.writeHookEvent({extensionName:o,hookName:n,durationMs:Math.round(performance.now()-l),ok:c,errorCode:h,sampleRate:a,recordedAt:r})}catch{}}})}async invokeCommand(e,n,t,o){const i=this.getCommand(e);if(!i)return{found:!1};const a=this.findCommandOwner(e),r=a?this.deriveExtensionName(a):"unknown",l=new Date,c=performance.now();let h="ok",u=null,m;const d=F(n),y={extensionName:r,callerContext:d==="no-args"?`command:/${e}`:`command:/${e} ${d}`,isUserInitiated:!0,sessionId:o?.sessionId??null,runId:o?.runId??null,variant:o?.variant??null};try{await x(y,()=>i.handler(n,t))}catch(g){h="error",u=g instanceof Error?g.constructor.name:"unknown",m=g,this.emitError({extensionPath:`command:${e}`,event:"command",error:g instanceof Error?g.message:String(g)})}const S=Math.round(performance.now()-c),w=new Date;try{this.telemetrySink?.writeCommandEvent({extensionName:r,commandName:e,argsSignature:d,argsLength:n.length,outcome:h,errorCode:u,durationMs:S,startedAt:l,endedAt:w,sessionId:o?.sessionId??null,runId:o?.runId??null,variant:o?.variant??null})}catch{}return{found:!0}}shutdown(){this.shutdownHandler()}createContext(){const e=this.getModel;return{ui:this.uiContext,hasUI:this.hasUI(),cwd:this.cwd,agentDir:this.agentDir,sessionManager:this.sessionManager,modelRegistry:this.modelRegistry,get model(){return e()},completeSimple:s((n,t)=>this.completeSimpleFn(n,t),"completeSimple"),completeSimpleWithUsage:s((n,t)=>this.completeSimpleWithUsageFn(n,t),"completeSimpleWithUsage"),completeJson:this.completeJsonFn?(n,t,o,i)=>this.completeJsonFn(n,t,o,i):void 0,isIdle:s(()=>this.isIdleFn(),"isIdle"),abort:s(()=>this.abortFn(),"abort"),clearFollowUpQueue:s(()=>this.clearFollowUpQueueFn(),"clearFollowUpQueue"),hasPendingMessages:s(()=>this.hasPendingMessagesFn(),"hasPendingMessages"),shutdown:s(()=>this.shutdownHandler(),"shutdown"),getContextUsage:s(()=>this.getContextUsageFn(),"getContextUsage"),compact:s(n=>this.compactFn(n),"compact"),getSystemPrompt:s(()=>this.getSystemPromptFn(),"getSystemPrompt"),getSoulManager:s(()=>this.getSoulManagerFn(),"getSoulManager"),getSettings:s(()=>this.getSettingsFn(),"getSettings"),getSkills:s(()=>this.getSkillsFn(),"getSkills")}}createCommandContext(){return{...this.createContext(),waitForIdle:s(()=>this.waitForIdleFn(),"waitForIdle"),newSession:s(e=>this.newSessionHandler(e),"newSession"),fork:s(e=>this.forkHandler(e),"fork"),navigateTree:s((e,n)=>this.navigateTreeHandler(e,n),"navigateTree"),switchSession:s(e=>this.switchSessionHandler(e),"switchSession"),reload:s(()=>this.reloadHandler(),"reload")}}isSessionBeforeEvent(e){return e.type==="session_before_switch"||e.type==="session_before_fork"||e.type==="session_before_compact"||e.type==="session_before_tree"}async emit(e){const n=this.createContext();let t;for(const o of this.extensions){const i=o.handlers.get(e.type);if(!(!i||i.length===0))for(const a of i)try{const r=await this.invokeHookHandler(o,e.type,()=>a(e,n));if(this.isSessionBeforeEvent(e)&&r&&(t=r,t.cancel))return t}catch(r){const l=r instanceof Error?r.message:String(r),c=r instanceof Error?r.stack:void 0;this.emitError({extensionPath:o.path,event:e.type,error:l,stack:c})}}return t}async emitToolResult(e){const n=this.createContext(),t={...e};let o=!1;for(const i of this.extensions){const a=i.handlers.get("tool_result");if(!(!a||a.length===0))for(const r of a)try{const l=await this.invokeHookHandler(i,"tool_result",()=>r(t,n));if(!l)continue;l.content!==void 0&&(t.content=l.content,o=!0),l.details!==void 0&&(t.details=l.details,o=!0),l.isError!==void 0&&(t.isError=l.isError,o=!0)}catch(l){const c=l instanceof Error?l.message:String(l),h=l instanceof Error?l.stack:void 0;this.emitError({extensionPath:i.path,event:"tool_result",error:c,stack:h})}}if(o)return{content:t.content,details:t.details,isError:t.isError}}async emitToolCall(e){const n=this.createContext();let t;for(const o of this.extensions){const i=o.handlers.get("tool_call");if(!(!i||i.length===0))for(const a of i){const r=await this.invokeHookHandler(o,"tool_call",()=>a(e,n));if(r&&(t=r,t.block))return t}}return t}async emitUserBash(e){const n=this.createContext();for(const t of this.extensions){const o=t.handlers.get("user_bash");if(!(!o||o.length===0))for(const i of o)try{const a=await this.invokeHookHandler(t,"user_bash",()=>i(e,n));if(a)return a}catch(a){const r=a instanceof Error?a.message:String(a),l=a instanceof Error?a.stack:void 0;this.emitError({extensionPath:t.path,event:"user_bash",error:r,stack:l})}}}async emitContext(e){const n=this.createContext();let t=structuredClone(e);for(const o of this.extensions){const i=o.handlers.get("context");if(!(!i||i.length===0))for(const a of i)try{const r={type:"context",messages:t},l=await this.invokeHookHandler(o,"context",()=>a(r,n));l&&l.messages&&(t=l.messages)}catch(r){const l=r instanceof Error?r.message:String(r),c=r instanceof Error?r.stack:void 0;this.emitError({extensionPath:o.path,event:"context",error:l,stack:c})}}return t}async emitBeforeAgentStart(e,n,t){const o=this.createContext(),i=[];let a=t,r=!1;for(const l of this.extensions){const c=l.handlers.get("before_agent_start");if(!(!c||c.length===0))for(const h of c)try{const u={type:"before_agent_start",prompt:e,images:n,systemPrompt:a},m=await this.withTimeout(this.invokeHookHandler(l,"before_agent_start",()=>h(u,o)),this.beforeAgentStartTimeoutMs);if(m===this.beforeAgentStartTimeoutSentinel){this.reportBeforeAgentStartTimeout(l.path);continue}if(m){const d=m;d.message&&i.push(d.message),d.systemPrompt!==void 0&&(a=d.systemPrompt,r=!0),d.appendSystemPrompt!==void 0&&(a=this.appendSystemPrompt(a,d.appendSystemPrompt),r=!0)}}catch(u){const m=u instanceof Error?u.message:String(u),d=u instanceof Error?u.stack:void 0;this.emitError({extensionPath:l.path,event:"before_agent_start",error:m,stack:d})}}if(i.length>0||r)return{messages:i.length>0?i:void 0,systemPrompt:r?a:void 0}}appendSystemPrompt(e,n){const t=n.trim();return t?`${e}
2
2
 
3
- ${t}`:e}async emitResourcesDiscover(e,n){const t=this.createContext(),o=[],i=[],a=[];for(const r of this.extensions){const c=r.handlers.get("resources_discover");if(!(!c||c.length===0))for(const l of c)try{const h={type:"resources_discover",cwd:e,reason:n},m=await this.invokeHookHandler(r,"resources_discover",()=>l(h,t));m?.skillPaths?.length&&o.push(...m.skillPaths.map(d=>({path:d,extensionPath:r.path}))),m?.promptPaths?.length&&i.push(...m.promptPaths.map(d=>({path:d,extensionPath:r.path}))),m?.themePaths?.length&&a.push(...m.themePaths.map(d=>({path:d,extensionPath:r.path})))}catch(h){const u=h instanceof Error?h.message:String(h),m=h instanceof Error?h.stack:void 0;this.emitError({extensionPath:r.path,event:"resources_discover",error:u,stack:m})}}return{skillPaths:o,promptPaths:i,themePaths:a}}async emitInput(e,n,t){const o=this.createContext();let i=e,a=n;for(const r of this.extensions)for(const c of r.handlers.get("input")??[])try{const l={type:"input",text:i,images:a,source:t},h=await this.invokeHookHandler(r,"input",()=>c(l,o));if(h?.action==="handled")return h;h?.action==="transform"&&(i=h.text,a=h.images??a)}catch(l){this.emitError({extensionPath:r.path,event:"input",error:l instanceof Error?l.message:String(l),stack:l instanceof Error?l.stack:void 0})}return i!==e||a!==n?{action:"transform",text:i,images:a}:{action:"continue"}}}export{H as ExtensionRunner,_ as emitSessionShutdownEvent};
3
+ ${t}`:e}async emitResourcesDiscover(e,n){const t=this.createContext(),o=[],i=[],a=[];for(const r of this.extensions){const l=r.handlers.get("resources_discover");if(!(!l||l.length===0))for(const c of l)try{const h={type:"resources_discover",cwd:e,reason:n},m=await this.invokeHookHandler(r,"resources_discover",()=>c(h,t));m?.skillPaths?.length&&o.push(...m.skillPaths.map(d=>({path:d,extensionPath:r.path}))),m?.promptPaths?.length&&i.push(...m.promptPaths.map(d=>({path:d,extensionPath:r.path}))),m?.themePaths?.length&&a.push(...m.themePaths.map(d=>({path:d,extensionPath:r.path})))}catch(h){const u=h instanceof Error?h.message:String(h),m=h instanceof Error?h.stack:void 0;this.emitError({extensionPath:r.path,event:"resources_discover",error:u,stack:m})}}return{skillPaths:o,promptPaths:i,themePaths:a}}async emitInput(e,n,t){const o=this.createContext();let i=e,a=n;for(const r of this.extensions)for(const l of r.handlers.get("input")??[])try{const c={type:"input",text:i,images:a,source:t},h=await this.invokeHookHandler(r,"input",()=>l(c,o));if(h?.action==="handled")return h;h?.action==="transform"&&(i=h.text,a=h.images??a)}catch(c){this.emitError({extensionPath:r.path,event:"input",error:c instanceof Error?c.message:String(c),stack:c instanceof Error?c.stack:void 0})}return i!==e||a!==n?{action:"transform",text:i,images:a}:{action:"continue"}}}export{H as ExtensionRunner,_ as emitSessionShutdownEvent};
@@ -10,7 +10,7 @@ import type { AssistantMessageEventStream } from "@pencil-agent/ai/events";
10
10
  import type { OAuthCredentials, OAuthLoginCallbacks } from "@pencil-agent/ai/oauth";
11
11
  import type { AutocompleteItem, Component, EditorComponent, EditorTheme, KeyId, OverlayHandle, OverlayOptions, TUI } from "@pencil-agent/tui";
12
12
  import type { Static, TSchema } from "@sinclair/typebox";
13
- import type { ToolRuntimeDescriptor } from "@pencil-agent/extension-sdk";
13
+ import type { ArgumentCompletionContext as ProtocolArgumentCompletionContext, ExtensionCommand as ProtocolExtensionCommand, ExtensionFlag, ExtensionFlagOptions, ExtensionFlagValue, HookEventName as ProtocolHookEventName, ToolRuntimeDescriptor } from "@pencil-agent/protocol";
14
14
  import type { Theme } from "../theme-contract.js";
15
15
  import type { BashResult } from "../platform/exec/bash-executor.js";
16
16
  import type { CompactionPreparation, CompactionResult } from "../session/compaction/index.js";
@@ -222,6 +222,10 @@ export interface ExtensionContext {
222
222
  isIdle(): boolean;
223
223
  /** Abort the current agent operation */
224
224
  abort(): void;
225
+ /** Clear the agent's follow-up message queue. Useful when an extension
226
+ * transitions to a terminal state and wants to prevent stale follow-ups
227
+ * from triggering additional turns. */
228
+ clearFollowUpQueue(): void;
225
229
  /** Whether there are queued messages waiting */
226
230
  hasPendingMessages(): boolean;
227
231
  /** Gracefully shutdown NanoPencil and exit. Available in all contexts. */
@@ -640,6 +644,7 @@ export declare function isToolCallEventType<TName extends string, TInput extends
640
644
  };
641
645
  /** Union of all event types */
642
646
  export type ExtensionEvent = ResourcesDiscoverEvent | SessionEvent | ContextEvent | BeforeAgentStartEvent | AgentStartEvent | AgentEndEvent | AgentResultEvent | AgentAbortEvent | TurnStartEvent | TurnEndEvent | MessageStartEvent | MessageUpdateEvent | MessageEndEvent | ToolExecutionStartEvent | ToolExecutionUpdateEvent | ToolExecutionEndEvent | ModelSelectEvent | UserBashEvent | InputEvent | ToolCallEvent | ToolResultEvent;
647
+ export type ExtensionEventName = ProtocolHookEventName;
643
648
  export interface ContextEventResult {
644
649
  messages?: AgentMessage[];
645
650
  }
@@ -696,14 +701,8 @@ export interface MessageRenderOptions {
696
701
  expanded: boolean;
697
702
  }
698
703
  export type MessageRenderer<T = unknown> = (message: CustomMessage<T>, options: MessageRenderOptions, theme: Theme) => Component | undefined;
699
- export interface ArgumentCompletionContext {
700
- commandName: string;
701
- argumentText: string;
702
- argumentPrefix: string;
703
- tokenIndex: number;
704
- previousTokens: string[];
705
- }
706
- export interface RegisteredCommand {
704
+ export type ArgumentCompletionContext = ProtocolArgumentCompletionContext;
705
+ export interface RegisteredCommand extends ProtocolExtensionCommand<ExtensionCommandContext> {
707
706
  name: string;
708
707
  description?: string;
709
708
  getArgumentCompletions?: (argumentPrefix: string, context?: ArgumentCompletionContext) => AutocompleteItem[] | null;
@@ -760,13 +759,9 @@ export interface ExtensionAPI {
760
759
  handler: (ctx: ExtensionContext) => Promise<void> | void;
761
760
  }): void;
762
761
  /** Register a CLI flag. */
763
- registerFlag(name: string, options: {
764
- description?: string;
765
- type: "boolean" | "string";
766
- default?: boolean | string;
767
- }): void;
762
+ registerFlag(name: string, options: ExtensionFlagOptions): void;
768
763
  /** Get the value of a registered CLI flag. */
769
- getFlag(name: string): boolean | string | undefined;
764
+ getFlag(name: string): ExtensionFlagValue | undefined;
770
765
  /** Register a custom renderer for CustomMessageEntry. */
771
766
  registerMessageRenderer<T = unknown>(customType: string, renderer: MessageRenderer<T>): void;
772
767
  /** Send a custom message to the session. */
@@ -785,6 +780,9 @@ export interface ExtensionAPI {
785
780
  executeCommand(text: string): Promise<boolean>;
786
781
  /** Whether the agent is idle (not streaming). For queueing loop tasks use with sendUserMessage. */
787
782
  isIdle(): boolean;
783
+ /** Clear the agent's follow-up message queue. Prevents stale follow-ups
784
+ * from triggering additional turns after a terminal state transition. */
785
+ clearFollowUpQueue(): void;
788
786
  /** Append a custom entry to the session for state persistence (not sent to LLM). */
789
787
  appendEntry<T = unknown>(customType: string, data?: T): void;
790
788
  /** Set the session display name (shown in session selector). */
@@ -927,13 +925,7 @@ export interface RegisteredTool {
927
925
  definition: ToolDefinition;
928
926
  extensionPath: string;
929
927
  }
930
- export interface ExtensionFlag {
931
- name: string;
932
- description?: string;
933
- type: "boolean" | "string";
934
- default?: boolean | string;
935
- extensionPath: string;
936
- }
928
+ export type { ExtensionFlag, ExtensionFlagOptions, ExtensionFlagValue } from "@pencil-agent/protocol";
937
929
  export interface ExtensionShortcut {
938
930
  shortcut: KeyId;
939
931
  description?: string;
@@ -1010,6 +1002,7 @@ export interface ExtensionContextActions {
1010
1002
  }) => Promise<string | undefined>;
1011
1003
  isIdle: () => boolean;
1012
1004
  abort: () => void;
1005
+ clearFollowUpQueue: () => void;
1013
1006
  hasPendingMessages: () => boolean;
1014
1007
  shutdown: () => void;
1015
1008
  getContextUsage: () => ContextUsage | undefined;
@@ -1054,6 +1047,8 @@ export interface ExtensionCommandContextActions {
1054
1047
  export interface ExtensionRuntime extends ExtensionRuntimeState, ExtensionActions {
1055
1048
  /** Bound in runner.bindCore from ExtensionContextActions.isIdle */
1056
1049
  isIdle: () => boolean;
1050
+ /** Bound in runner.bindCore from ExtensionContextActions.clearFollowUpQueue */
1051
+ clearFollowUpQueue: () => void;
1057
1052
  }
1058
1053
  /** Loaded extension with all registered items. */
1059
1054
  export interface Extension {
@@ -25,14 +25,22 @@ export interface StreamOptions {
25
25
  signal?: AbortSignal;
26
26
  /** Retry configuration for automatic retry on retriable errors */
27
27
  retry?: {
28
- /** Maximum number of retry attempts (default: 3) */
28
+ /** Maximum number of retry attempts (default: 3). Ignored when persistentRetry is true. */
29
29
  maxRetries?: number;
30
30
  /** Base delay in ms for exponential backoff (default: 1000) */
31
31
  baseDelayMs?: number;
32
- /** Maximum delay cap in ms (default: 30000) */
32
+ /** Maximum delay cap in ms (default: 30000, or 300000 for persistentRetry) */
33
33
  maxDelayMs?: number;
34
34
  /** Whether to add jitter to avoid thundering herd (default: true) */
35
35
  jitter?: boolean;
36
+ /**
37
+ * Persistent/unattended retry mode for 429/529 overload errors.
38
+ * When true, retries indefinitely with capped backoff and periodic heartbeat yields.
39
+ * Only applies to overload errors (429, 529); other retriable errors still respect maxRetries.
40
+ */
41
+ persistentRetry?: boolean;
42
+ /** Heartbeat interval in ms during persistent retry to prevent idle timeouts (default: 30000) */
43
+ heartbeatMs?: number;
36
44
  };
37
45
  apiKey?: string;
38
46
  /**
@@ -148,6 +156,8 @@ export interface AssistantMessage {
148
156
  usage: Usage;
149
157
  stopReason: StopReason;
150
158
  errorMessage?: string;
159
+ /** HTTP response headers from the error response, if available. Used for retry-after extraction. */
160
+ errorHeaders?: Record<string, string>;
151
161
  timestamp: number;
152
162
  }
153
163
  export interface ToolResultMessage<TDetails = any> {
@@ -1,2 +1,5 @@
1
- var p=Object.defineProperty;var e=(r,t)=>p(r,"name",{value:t,configurable:!0});import{existsSync as c,readdirSync as D,readFileSync as g,mkdirSync as l,statSync as m,writeFileSync as h}from"node:fs";import{join as o,resolve as d}from"node:path";import{defaultAgentDirContext as S}from"../agent-dir/agent-dir-context.js";const f={default:"pencil"};function P(r){const t=r.trim();return t?t.replace(/[^a-zA-Z0-9_-]/g,"_"):"general"}e(P,"normalizePersonaId");class x{static{e(this,"PersonaManager")}ctx;constructor(t=S()){this.ctx=t}get personasDir(){return o(this.ctx.path,"personas")}get activePersonaStatePath(){return o(this.ctx.path,"persona.json")}ensurePersonasDir(){c(this.personasDir)||l(this.personasDir,{recursive:!0})}getPersonasDir(){return this.personasDir}getActivePersonaId(){try{if(!c(this.activePersonaStatePath))return"vex";const t=g(this.activePersonaStatePath,"utf-8"),n=JSON.parse(t);if(!n?.activePersonaId)return"vex";let i=P(String(n.activePersonaId));return f[i]&&(i=f[i],this.setActivePersonaId(i)),i}catch{return"vex"}}setActivePersonaId(t){if(this.ensurePersonasDir(),!t){try{h(this.activePersonaStatePath,JSON.stringify({},null,2),"utf-8")}catch{}return}const n=P(t),i=this.getPersonaDir(n);c(i)||l(i,{recursive:!0});const u={activePersonaId:n};h(this.activePersonaStatePath,JSON.stringify(u,null,2),"utf-8")}listPersonas(){try{return this.ensurePersonasDir(),D(this.personasDir).map(t=>P(t)).filter(t=>{const n=this.getPersonaDir(t);try{return m(n).isDirectory()}catch{return!1}}).sort((t,n)=>t.localeCompare(n))}catch{return[]}}getPersonaDir(t){const n=P(t);return o(this.personasDir,n)}getPersonaPencilPath(t){return o(this.getPersonaDir(t),"PENCIL.md")}getPersonaSkillsDir(t){return o(this.getPersonaDir(t),"skills")}getPersonaSoulDir(t){return o(this.getPersonaDir(t),"soul")}getPersonaMemoryDir(t){return o(this.getPersonaDir(t),"memory")}getPersonaMcpConfigPath(t){return o(this.getPersonaDir(t),"mcp.json")}getPersonaDescription(t){try{const n=this.getPersonaPencilPath(t);if(!c(n))return"";const i=g(n,"utf-8");for(const u of i.split(`
2
- `)){const a=u.trim();if(!(!a||a.startsWith("#")))return a.length>60?a.slice(0,57)+"...":a}return""}catch{return""}}}const s=new x;function M(){return s.getPersonasDir()}e(M,"getPersonasDir");function C(){return s.getActivePersonaId()}e(C,"getActivePersonaId");function N(r){s.setActivePersonaId(r)}e(N,"setActivePersonaId");function k(){return s.listPersonas()}e(k,"listPersonas");function w(r){return s.getPersonaDir(r)}e(w,"getPersonaDir");function z(r){return s.getPersonaPencilPath(r)}e(z,"getPersonaPencilPath");function E(r){return s.getPersonaSkillsDir(r)}e(E,"getPersonaSkillsDir");function O(r){return s.getPersonaSoulDir(r)}e(O,"getPersonaSoulDir");function j(r){return s.getPersonaMemoryDir(r)}e(j,"getPersonaMemoryDir");function J(r){return s.getPersonaMcpConfigPath(r)}e(J,"getPersonaMcpConfigPath");function _(r){return s.getPersonaDescription(r)}e(_,"getPersonaDescription");function F(r){const t=r.trim();return t&&d(t)}e(F,"toAbsolutePath");export{x as PersonaManager,C as getActivePersonaId,_ as getPersonaDescription,w as getPersonaDir,J as getPersonaMcpConfigPath,j as getPersonaMemoryDir,z as getPersonaPencilPath,E as getPersonaSkillsDir,O as getPersonaSoulDir,M as getPersonasDir,k as listPersonas,N as setActivePersonaId,F as toAbsolutePath};
1
+ var p=Object.defineProperty;var n=(e,t)=>p(e,"name",{value:t,configurable:!0});import{existsSync as a,readdirSync as D,readFileSync as f,mkdirSync as l,statSync as m,writeFileSync as g}from"node:fs";import{join as o,resolve as d}from"node:path";import{defaultAgentDirContext as v}from"../agent-dir/agent-dir-context.js";const h={default:"pencil"};function P(e){const t=e.trim();return t?t.replace(/[^a-zA-Z0-9_-]/g,"_"):"general"}n(P,"normalizePersonaId");class x{static{n(this,"PersonaManager")}ctx;constructor(t=v()){this.ctx=t}get personasDir(){return o(this.ctx.path,"personas")}get activePersonaStatePath(){return o(this.ctx.path,"persona.json")}ensurePersonasDir(){a(this.personasDir)||l(this.personasDir,{recursive:!0});const t=o(this.personasDir,"vex");if(!a(t)){l(t,{recursive:!0});const r=o(t,"PENCIL.md");a(r)||g(r,`# vex
2
+
3
+ Default persona for nanoPencil.
4
+ `,"utf-8")}}getPersonasDir(){return this.personasDir}getActivePersonaId(){try{if(!a(this.activePersonaStatePath))return"vex";const t=f(this.activePersonaStatePath,"utf-8"),r=JSON.parse(t);if(!r?.activePersonaId)return"vex";let i=P(String(r.activePersonaId));return h[i]&&(i=h[i],this.setActivePersonaId(i)),i}catch{return"vex"}}setActivePersonaId(t){if(this.ensurePersonasDir(),!t){try{g(this.activePersonaStatePath,JSON.stringify({},null,2),"utf-8")}catch{}return}const r=P(t),i=this.getPersonaDir(r);a(i)||l(i,{recursive:!0});const u={activePersonaId:r};g(this.activePersonaStatePath,JSON.stringify(u,null,2),"utf-8")}listPersonas(){try{return this.ensurePersonasDir(),D(this.personasDir).map(t=>P(t)).filter(t=>{const r=this.getPersonaDir(t);try{return m(r).isDirectory()}catch{return!1}}).sort((t,r)=>t.localeCompare(r))}catch{return[]}}getPersonaDir(t){const r=P(t);return o(this.personasDir,r)}getPersonaPencilPath(t){return o(this.getPersonaDir(t),"PENCIL.md")}getPersonaSkillsDir(t){return o(this.getPersonaDir(t),"skills")}getPersonaSoulDir(t){return o(this.getPersonaDir(t),"soul")}getPersonaMemoryDir(t){return o(this.getPersonaDir(t),"memory")}getPersonaMcpConfigPath(t){return o(this.getPersonaDir(t),"mcp.json")}getPersonaDescription(t){try{const r=this.getPersonaPencilPath(t);if(!a(r))return"";const i=f(r,"utf-8");for(const u of i.split(`
5
+ `)){const c=u.trim();if(!(!c||c.startsWith("#")))return c.length>60?c.slice(0,57)+"...":c}return""}catch{return""}}}const s=new x;function M(){return s.getPersonasDir()}n(M,"getPersonasDir");function C(){return s.getActivePersonaId()}n(C,"getActivePersonaId");function N(e){s.setActivePersonaId(e)}n(N,"setActivePersonaId");function k(){return s.listPersonas()}n(k,"listPersonas");function E(e){return s.getPersonaDir(e)}n(E,"getPersonaDir");function w(e){return s.getPersonaPencilPath(e)}n(w,"getPersonaPencilPath");function z(e){return s.getPersonaSkillsDir(e)}n(z,"getPersonaSkillsDir");function O(e){return s.getPersonaSoulDir(e)}n(O,"getPersonaSoulDir");function j(e){return s.getPersonaMemoryDir(e)}n(j,"getPersonaMemoryDir");function J(e){return s.getPersonaMcpConfigPath(e)}n(J,"getPersonaMcpConfigPath");function _(e){return s.getPersonaDescription(e)}n(_,"getPersonaDescription");function F(e){const t=e.trim();return t&&d(t)}n(F,"toAbsolutePath");export{x as PersonaManager,C as getActivePersonaId,_ as getPersonaDescription,E as getPersonaDir,J as getPersonaMcpConfigPath,j as getPersonaMemoryDir,w as getPersonaPencilPath,z as getPersonaSkillsDir,O as getPersonaSoulDir,M as getPersonasDir,k as listPersonas,N as setActivePersonaId,F as toAbsolutePath};