@pencil-agent/nano-pencil 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) 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/mcp/mcp-client.d.ts +3 -1
  7. package/dist/core/mcp/mcp-client.js +6 -6
  8. package/dist/core/mcp/mcp-config.d.ts +3 -3
  9. package/dist/core/mcp/mcp-config.js +1 -1
  10. package/dist/core/mcp/mcp-manager.d.ts +5 -1
  11. package/dist/core/mcp/mcp-manager.js +1 -1
  12. package/dist/core/platform/config/resource-loader.d.ts +2 -0
  13. package/dist/core/platform/config/resource-loader.js +2 -2
  14. package/dist/core/runtime/agent-session.d.ts +12 -0
  15. package/dist/core/runtime/agent-session.js +8 -8
  16. package/dist/core/runtime/sdk.d.ts +8 -0
  17. package/dist/core/runtime/sdk.js +1 -1
  18. package/dist/extensions/builtin/AGENT.md +115 -115
  19. package/dist/extensions/builtin/browser/AGENT.md +17 -17
  20. package/dist/extensions/builtin/browser/agent-workspace/agent_helpers.py +12 -12
  21. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/amazon/product-search.md +198 -198
  22. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/archive-org/scraping.md +341 -341
  23. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/arxiv/scraping.md +311 -311
  24. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/arxiv-bulk/scraping.md +333 -333
  25. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/atlas/overview.md +70 -70
  26. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/booking-com/scraping.md +578 -578
  27. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/capterra/scraping.md +440 -440
  28. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/centilebrain/generate-estimates.md +110 -110
  29. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/coingecko/scraping.md +325 -325
  30. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/coinmarketcap/scraping.md +463 -463
  31. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/coursera/scraping.md +360 -360
  32. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/craigslist/scraping.md +390 -390
  33. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/crossref/scraping.md +568 -568
  34. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/dev-to/scraping.md +323 -323
  35. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/duckduckgo/scraping.md +349 -349
  36. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/ebay/scraping.md +435 -435
  37. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/etsy/scraping.md +506 -506
  38. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/eventbrite/scraping.md +363 -363
  39. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/expedia/automation.md +168 -168
  40. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/facebook/groups.md +236 -236
  41. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/facebook/pages.md +295 -295
  42. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/framer/editor.md +108 -108
  43. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/fred/scraping.md +493 -493
  44. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/g2/scraping.md +580 -580
  45. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/genius/scraping.md +511 -511
  46. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/github/repo-actions.md +65 -65
  47. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/github/scraping.md +184 -184
  48. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/glassdoor/scraping.md +543 -543
  49. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/gmail/compose.md +122 -122
  50. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/goodreads/scraping.md +461 -461
  51. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/gutenberg/scraping.md +383 -383
  52. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/hackernews/scraping.md +243 -243
  53. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/howlongtobeat/scraping.md +473 -473
  54. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/imdb/scraping.md +271 -271
  55. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/itch-io/scraping.md +436 -436
  56. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/job-boards/indeed-glassdoor.md +1021 -1021
  57. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/letterboxd/scraping.md +349 -349
  58. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/linkedin/invitation-manager.md +109 -109
  59. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/loom/folder-enumeration.md +170 -170
  60. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/macrotrends/scraping.md +537 -537
  61. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/medium/article-hydration.md +120 -120
  62. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/medium/scraping.md +414 -414
  63. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/metacritic/scraping.md +477 -477
  64. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/musicbrainz/scraping.md +478 -478
  65. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/nasa/scraping.md +339 -339
  66. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/news-aggregation/multi-source.md +205 -205
  67. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/open-library/scraping.md +472 -472
  68. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/openalex/scraping.md +470 -470
  69. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/openstreetmap/scraping.md +490 -490
  70. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/package-registries/npm-pypi.md +478 -478
  71. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/polymarket/scraping.md +234 -234
  72. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/producthunt/scraping.md +307 -307
  73. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/pubmed/scraping.md +421 -421
  74. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/quora/scraping.md +364 -364
  75. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/rawg/scraping.md +352 -352
  76. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/reddit/scraping.md +124 -124
  77. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/rest-countries/scraping.md +233 -233
  78. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/sec-edgar/scraping.md +361 -361
  79. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/README.md +36 -36
  80. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/embedded-apps.md +72 -72
  81. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/knowledge-base.md +109 -109
  82. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/polaris-inputs.md +137 -137
  83. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/soundcloud/scraping.md +362 -362
  84. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/spotify/scraping.md +339 -339
  85. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/stackoverflow/scraping.md +435 -435
  86. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/steam/scraping.md +575 -575
  87. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/substack/scraping.md +338 -338
  88. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/thetechgeeks/pricing.md +52 -52
  89. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/tiktok/upload.md +107 -107
  90. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/tradingview/scraping.md +309 -309
  91. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/trello/boards-and-lists.md +88 -88
  92. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/trustpilot/scraping.md +375 -375
  93. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/walmart/scraping.md +444 -444
  94. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/wayback-machine/scraping.md +306 -306
  95. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/weather/scraping.md +398 -398
  96. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/wellfound/scraping.md +596 -596
  97. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/world-bank/scraping.md +356 -356
  98. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/xiaohongshu/scraping.md +84 -84
  99. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/youtube/scraping.md +418 -418
  100. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/zillow/scraping.md +433 -433
  101. package/dist/extensions/builtin/browser/browser.md +73 -73
  102. package/dist/extensions/builtin/browser/install.md +142 -142
  103. package/dist/extensions/builtin/browser/interaction-skills/connection.md +48 -48
  104. package/dist/extensions/builtin/browser/interaction-skills/cookies.md +3 -3
  105. package/dist/extensions/builtin/browser/interaction-skills/cross-origin-iframes.md +3 -3
  106. package/dist/extensions/builtin/browser/interaction-skills/dialogs.md +64 -64
  107. package/dist/extensions/builtin/browser/interaction-skills/downloads.md +3 -3
  108. package/dist/extensions/builtin/browser/interaction-skills/drag-and-drop.md +3 -3
  109. package/dist/extensions/builtin/browser/interaction-skills/dropdowns.md +3 -3
  110. package/dist/extensions/builtin/browser/interaction-skills/iframes.md +3 -3
  111. package/dist/extensions/builtin/browser/interaction-skills/network-requests.md +3 -3
  112. package/dist/extensions/builtin/browser/interaction-skills/print-as-pdf.md +3 -3
  113. package/dist/extensions/builtin/browser/interaction-skills/profile-sync.md +90 -90
  114. package/dist/extensions/builtin/browser/interaction-skills/screenshots.md +17 -17
  115. package/dist/extensions/builtin/browser/interaction-skills/scrolling.md +3 -3
  116. package/dist/extensions/builtin/browser/interaction-skills/shadow-dom.md +3 -3
  117. package/dist/extensions/builtin/browser/interaction-skills/tabs.md +69 -69
  118. package/dist/extensions/builtin/browser/interaction-skills/uploads.md +1 -1
  119. package/dist/extensions/builtin/browser/interaction-skills/viewport.md +3 -3
  120. package/dist/extensions/builtin/browser/src/browser_harness/AGENT.md +15 -15
  121. package/dist/extensions/builtin/browser/src/browser_harness/__init__.py +8 -8
  122. package/dist/extensions/builtin/browser/src/browser_harness/_ipc.py +90 -90
  123. package/dist/extensions/builtin/browser/src/browser_harness/admin.py +722 -722
  124. package/dist/extensions/builtin/browser/src/browser_harness/daemon.py +328 -328
  125. package/dist/extensions/builtin/browser/src/browser_harness/helpers.py +396 -396
  126. package/dist/extensions/builtin/browser/src/browser_harness/run.py +103 -103
  127. package/dist/extensions/builtin/discipline/skills/brainstorming/SKILL.md +33 -33
  128. package/dist/extensions/builtin/discipline/skills/executing-plans/SKILL.md +25 -25
  129. package/dist/extensions/builtin/discipline/skills/finishing-development-branch/SKILL.md +25 -25
  130. package/dist/extensions/builtin/discipline/skills/receiving-code-review/SKILL.md +22 -22
  131. package/dist/extensions/builtin/discipline/skills/requesting-code-review/SKILL.md +31 -31
  132. package/dist/extensions/builtin/discipline/skills/systematic-debugging/SKILL.md +28 -28
  133. package/dist/extensions/builtin/discipline/skills/test-driven-development/SKILL.md +32 -32
  134. package/dist/extensions/builtin/discipline/skills/using-git-worktrees/SKILL.md +25 -25
  135. package/dist/extensions/builtin/discipline/skills/verification-before-completion/SKILL.md +27 -27
  136. package/dist/extensions/builtin/discipline/skills/writing-plans/SKILL.md +26 -26
  137. package/dist/extensions/builtin/goal/README.md +67 -67
  138. package/dist/extensions/builtin/grub/README.md +112 -112
  139. package/dist/extensions/builtin/link-world/agent-workspace/README.md +16 -16
  140. package/dist/extensions/builtin/link-world/internet-search/internet-search.md +65 -65
  141. package/dist/extensions/builtin/link-world/link-world-agent.md +82 -82
  142. package/dist/extensions/builtin/link-world/linkworld.md +313 -313
  143. package/dist/extensions/builtin/link-world/network-routing/network-routing.md +67 -67
  144. package/dist/extensions/builtin/loop/README.md +92 -92
  145. package/dist/extensions/builtin/mcp/figma-design.md +68 -68
  146. package/dist/extensions/builtin/mcp/mcp-management.md +85 -85
  147. package/dist/extensions/builtin/recap/AGENT.md +15 -15
  148. package/dist/extensions/builtin/sal/README.md +72 -72
  149. package/dist/extensions/builtin/security-audit/README.md +289 -289
  150. package/dist/extensions/builtin/team/AGENT.md +112 -112
  151. package/dist/extensions/builtin/team/TESTING.md +299 -299
  152. package/dist/extensions/builtin/token-save/README.md +56 -56
  153. package/dist/extensions/optional/AGENT.md +10 -10
  154. package/dist/modes/interactive/interactive-mode.js +36 -36
  155. package/dist/modes/interactive/theme/dark.json +85 -85
  156. package/dist/modes/interactive/theme/light.json +84 -84
  157. package/dist/modes/interactive/theme/theme-schema.json +335 -335
  158. package/dist/modes/interactive/theme/warm.json +81 -81
  159. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop.js +3 -2
  160. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-agent-loop.js +2 -1
  161. package/dist/node_modules/@pencil-agent/ai/dist/cli.js +0 -0
  162. package/docs/cc-agent-design.md +1297 -0
  163. package/docs/cc-tui-design.md +1333 -0
  164. package/docs/codex-goal-command-impl.md +1055 -1055
  165. package/docs/codex-goal-vs-grub.md +500 -500
  166. package/docs/custom-provider.md +27 -27
  167. package/docs/extensions.md +27 -27
  168. package/docs/keybindings.md +27 -27
  169. package/docs/loop /351/207/215/346/236/204/345/256/214/346/210/220/346/200/273/347/273/223.md" +250 -250
  170. package/docs/loop /351/207/215/346/236/204/345/256/214/346/210/220/346/212/245/345/221/212.md" +122 -122
  171. package/docs/loop /351/207/215/346/236/204/346/226/271/346/241/210.md" +1222 -1222
  172. 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
  173. 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
  174. package/docs/loop /351/207/215/346/236/204/350/256/241/345/210/222.md" +320 -320
  175. package/docs/loop-usage-examples.md +214 -214
  176. package/docs/models.md +27 -27
  177. package/docs/nanoPencil-/345/255/246/344/271/240/350/256/241/345/210/222.md +170 -0
  178. package/docs/packages.md +27 -27
  179. package/docs/pi-design-philosophy.md +457 -457
  180. package/docs/planmode.md +1987 -1987
  181. package/docs/prompt-templates.md +27 -27
  182. package/docs/providers.md +27 -27
  183. package/docs/scan-report.md +3820 -0
  184. package/docs/sdk.md +27 -27
  185. package/docs/skills.md +27 -27
  186. package/docs/themes.md +27 -27
  187. package/docs/tui.md +27 -27
  188. package/docs//345/257/271/346/240/207Claude-Code.md +1775 -0
  189. package/docs//351/230/277/351/207/214/345/267/264/345/267/264/350/264/242/346/212/245/345/210/206/346/236/220/344/271/246.md +261 -0
  190. package/package.json +190 -190
  191. 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 +0 -851
  192. package/docs/SDK-TESTING.md +0 -364
  193. package/docs/mem-core/346/212/200/346/234/257/346/226/207/346/241/243.md +0 -593
  194. package/docs/startup-performance-optimization.md +0 -301
  195. package/docs//350/256/244/347/237/245/345/234/260/345/233/276.md +0 -47
@@ -1,15 +1,15 @@
1
- var A=Object.defineProperty;var n=(a,e)=>A(a,"name",{value:e,configurable:!0});import{appendFileSync as E,readFileSync as v}from"node:fs";import{homedir as k}from"node:os";import{basename as L,dirname as P,join as _}from"node:path";import{isContextOverflow as T}from"@pencil-agent/ai/overflow";import{resetApiProviders as I}from"@pencil-agent/ai/registry";import{getDocsPath as C}from"../../config.js";import{stripFrontmatter as F}from"../../utils/frontmatter.js";import{calculateContextTokens as b,collectEntriesForBranchSummary as N,estimateContextTokens as U,shouldCompact as B}from"../session/compaction/index.js";import{ToolOrchestrator as O}from"../tools/orchestrator.js";import{DEFAULT_THINKING_LEVEL as D}from"../platform/config/defaults.js";import{createExtensionTelemetrySink as $}from"../platform/telemetry/index.js";import{ExtensionRunner as j}from"../extensions-host/index.js";import{expandPromptTemplate as f}from"../prompt/prompt-templates.js";import{getLatestCompactionEntry as y}from"../session/session-manager.js";import{t as W}from"../platform/i18n/index.js";import{toSoulContext as w,extractSessionContext as S}from"../soul-integration.js";import{createDefaultRuntimeTools as H}from"./default-tools.js";import{BashRunner as K}from"./bash-runner.js";import{Listeners as V}from"../platform/listeners.js";import{ModelController as q}from"./model-controller.js";import{CompactionController as Q}from"./compaction-controller.js";import{SessionLifecycleController as G}from"./session-lifecycle-controller.js";import{SessionTreeController as X}from"./session-tree-controller.js";import{ToolRuntimeController as z}from"./tool-runtime-controller.js";import{buildRuntimeSystemPrompt as J,getActiveBaseToolNames as Y}from"./prompt-assembly.js";import{exportSessionHtml as Z,getLastAssistantText as ee}from"./export-bridge.js";import{ExtensionEventBridge as te}from"./event-bridge.js";import{bindExtensionCore as se}from"./extension-core-bindings.js";import{buildSessionSlashCommands as ne}from"./slash-command-catalog.js";import{RetryCoordinator as oe}from"./retry-coordinator.js";import{createLogger as ie}from"../platform/utils/logger.js";import{createAgentTool as re,createTaskToolAlias as ae,createSendMessageTool as le,AGENT_TOOL_NAME as x,TASK_TOOL_NAME as he,SEND_MESSAGE_TOOL_NAME as M}from"../sub-agent/index.js";import{CycleModelError as ze}from"./model-controller.js";function qe(a){const e=a.match(/^<skill name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill>(?:\n\n([\s\S]+))?$/);return e?{name:e[1],location:e[2],content:e[3],userMessage:e[4]?.trim()||void 0}:null}n(qe,"parseSkillBlock");function R(a,e){const t=new Set(e.content.filter(o=>o.type==="toolCall").map(o=>o.id));let s=a.length;for(;s>0&&ge(a[s-1],t);)s--;return s>0&&ce(a[s-1],e)&&s--,a.slice(0,s)}n(R,"pruneRecoverableErrorTail");function ge(a,e){return a.role==="toolResult"&&e.has(a.toolCallId)}n(ge,"isRecoverableTailToolResult");function ce(a,e){return a.role==="assistant"&&a.stopReason===e.stopReason&&a.timestamp===e.timestamp&&a.provider===e.provider&&a.model===e.model&&a.api===e.api&&a.errorMessage===e.errorMessage}n(ce,"isSameRecoverableAssistantMessage");function me(a){switch(a.type){case"agent_start":return{type:"sub_agent_start",subAgentId:a.subAgentId,agentType:a.agentType,description:a.description,isAsync:a.isAsync};case"tool_start":return{type:"sub_agent_tool_start",subAgentId:a.subAgentId,toolName:a.toolName};case"tool_end":return{type:"sub_agent_tool_end",subAgentId:a.subAgentId,toolName:a.toolName,isError:a.isError};case"agent_end":return{type:"sub_agent_end",subAgentId:a.subAgentId,success:a.success};default:return}}n(me,"mapSubAgentEvent");class Qe{static{n(this,"AgentSession")}agent;sessionManager;settingsManager;agentCtx;_scopedModels;_unsubscribeAgent;_detachExternalAbort;_listeners=new V;_steeringMessages=[];_followUpMessages=[];_pendingNextTurnMessages=[];_retryCoordinator;_logger;_bashRunner;_extensionRunner=void 0;_slashCommandExecutor=void 0;_extensionEventBridge;_resourceLoader;_theme;_dbg(e){if(process.env.NANOPENCIL_DEBUG_SESSION==="1")try{const t=_(k(),".nanopencil","agent","nanopencil-debug.log");E(t,`[${new Date().toISOString()}] [session] ${e}
2
- `)}catch{}}_customTools;_staticCustomTools;_mcpToolsFactory;_soulManagerFactory;_baseToolRegistry=new Map;_agentTool;_createSessionFactory;_cwd;_extensionRunnerRef;_soulManager;_lastSoulInjection;_initialActiveToolNames;_baseToolsOverride;_extensionUIContext;_extensionCommandContextActions;_extensionShutdownHandler;_extensionErrorListener;_extensionErrorUnsubscriber;_modelRegistry;_agentDir;_baseSystemPrompt="";_modelController;_compactionController;_sessionTreeController;_lifecycleController;_toolOrchestrator;_toolRuntimeController;constructor(e){if(this.agent=e.agent,this.sessionManager=e.sessionManager,this.settingsManager=e.settingsManager,this.agentCtx=e.agentCtx,this._scopedModels=e.scopedModels??[],this._resourceLoader=e.resourceLoader,this._theme=e.theme,this._bashRunner=new K({getCwd:n(()=>this._cwd,"getCwd"),getShellCommandPrefix:n(()=>this.settingsManager.getShellCommandPrefix(),"getShellCommandPrefix"),appendToAgent:n(t=>this.agent.appendMessage(t),"appendToAgent"),appendToSession:n(t=>this.sessionManager.appendMessage(t),"appendToSession"),isStreaming:n(()=>this.isStreaming,"isStreaming")}),this._staticCustomTools=e.customTools??[],this._mcpToolsFactory=e.mcpToolsFactory,this._soulManagerFactory=e.soulManagerFactory,this._customTools=[...this._staticCustomTools,...e.initialMcpTools??[]],this._initialActiveToolNames=e.initialActiveToolNames,this._toolOrchestrator=new O({customTools:this._customTools,initialActiveToolNames:this._initialActiveToolNames,getExtensionTools:n(()=>new Map((this._extensionRunner?.getAllRegisteredTools()??[]).map(t=>[t.definition.name,t.definition])),"getExtensionTools")}),this._toolRuntimeController=new z(this._toolOrchestrator),this._cwd=e.cwd,this._agentDir=e.agentDir,this._modelRegistry=e.modelRegistry,this._extensionRunnerRef=e.extensionRunnerRef,this._soulManager=e.soulManager,this._baseToolsOverride=e.baseToolsOverride,this._createSessionFactory=e.createSession,this._extensionEventBridge=new te({getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner")}),this._modelController=new q({getModel:n(()=>this.model,"getModel"),getThinkingLevel:n(()=>this.thinkingLevel,"getThinkingLevel"),getScopedModels:n(()=>this._scopedModels,"getScopedModels"),setAgentModel:n(t=>this.agent.setModel(t),"setAgentModel"),setAgentThinkingLevel:n(t=>this.agent.setThinkingLevel(t),"setAgentThinkingLevel"),setAgentLoopFramework:n(t=>this.agent.setAgentLoopFramework(t),"setAgentLoopFramework"),setLoopPolicy:n(t=>this.agent.setLoopPolicy(t),"setLoopPolicy"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getApiKeyForProvider:n(t=>this._modelRegistry.getApiKeyForProvider(t),"getApiKeyForProvider"),getAvailableModels:n(()=>this._modelRegistry.getAvailableAsync(),"getAvailableModels"),getAuthCredential:n(t=>this._modelRegistry.authStorage.get(t),"getAuthCredential"),appendModelChange:n((t,s)=>this.sessionManager.appendModelChange(t,s),"appendModelChange"),appendThinkingLevelChange:n(t=>this.sessionManager.appendThinkingLevelChange(t),"appendThinkingLevelChange"),setDefaultModelAndProvider:n((t,s)=>this.settingsManager.setDefaultModelAndProvider(t,s),"setDefaultModelAndProvider"),setDefaultThinkingLevel:n(t=>this.settingsManager.setDefaultThinkingLevel(t),"setDefaultThinkingLevel"),emitModelSelect:n(async({model:t,previousModel:s,source:o})=>{this._extensionRunner&&await this._extensionRunner.emit({type:"model_select",model:t,previousModel:s,source:o})},"emitModelSelect")}),this._compactionController=new Q({getModel:n(()=>this.model,"getModel"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),getBranch:n(()=>this.sessionManager.getBranch(),"getBranch"),getEntries:n(()=>this.sessionManager.getEntries(),"getEntries"),getCompactionSettings:n(()=>this.settingsManager.getCompactionSettings(),"getCompactionSettings"),appendCompaction:n((t,s,o,r,i)=>this.sessionManager.appendCompaction(t,s,o,r,i),"appendCompaction"),applyCompactedMessages:n(()=>{const t=this.sessionManager.buildSessionContext();return this.agent.replaceMessages(t.messages),t.messages},"applyCompactedMessages"),logInfo:n((t,s)=>this._logger.info(t,s),"logInfo"),disconnectFromAgent:n(()=>this._disconnectFromAgent(),"disconnectFromAgent"),reconnectToAgent:n(()=>this._reconnectToAgent(),"reconnectToAgent"),abortAgent:n(()=>this.abort(),"abortAgent"),emitAutoCompactionStart:n(t=>this._emit({type:"auto_compaction_start",reason:t}),"emitAutoCompactionStart"),emitAutoCompactionEnd:n(t=>this._emit({type:"auto_compaction_end",...t}),"emitAutoCompactionEnd"),getAutoCompactionEnabled:n(()=>this.settingsManager.getCompactionEnabled(),"getAutoCompactionEnabled"),setAutoCompactionEnabled:n(t=>this.settingsManager.setCompactionEnabled(t),"setAutoCompactionEnabled")}),this._sessionTreeController=new X({getModel:n(()=>this.model,"getModel"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),getLeafId:n(()=>this.sessionManager.getLeafId(),"getLeafId"),getEntry:n(t=>this.sessionManager.getEntry(t),"getEntry"),collectBranchSummaryEntries:n((t,s)=>N(this.sessionManager,t,s),"collectBranchSummaryEntries"),getBranchSummaryReserveTokens:n(()=>this.settingsManager.getBranchSummarySettings().reserveTokens,"getBranchSummaryReserveTokens"),branchWithSummary:n((t,s,o,r)=>this.sessionManager.branchWithSummary(t,s,o,r),"branchWithSummary"),appendLabelChange:n((t,s)=>this.sessionManager.appendLabelChange(t,s),"appendLabelChange"),resetLeaf:n(()=>this.sessionManager.resetLeaf(),"resetLeaf"),branch:n(t=>this.sessionManager.branch(t),"branch"),rebuildAgentMessages:n(()=>{const t=this.sessionManager.buildSessionContext();this.agent.replaceMessages(t.messages)},"rebuildAgentMessages"),extractUserMessageText:n(t=>this._extractUserMessageText(t),"extractUserMessageText")}),this._lifecycleController=new G({getSessionFile:n(()=>this.sessionManager.getSessionFile(),"getSessionFile"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),disconnectFromAgent:n(()=>this._disconnectFromAgent(),"disconnectFromAgent"),reconnectToAgent:n(()=>this._reconnectToAgent(),"reconnectToAgent"),abortAgent:n(()=>this.abort(),"abortAgent"),resetAgent:n(()=>this.agent.reset(),"resetAgent"),syncAgentSessionId:n(()=>{this.agent.sessionId=this.sessionManager.getSessionId()},"syncAgentSessionId"),clearPendingQueues:n(()=>{this._steeringMessages=[],this._followUpMessages=[],this._pendingNextTurnMessages=[]},"clearPendingQueues"),clearPendingNextTurnMessages:n(()=>{this._pendingNextTurnMessages=[]},"clearPendingNextTurnMessages"),sessionNewSession:n(t=>this.sessionManager.newSession({parentSession:t}),"sessionNewSession"),sessionSetFile:n(t=>this.sessionManager.setSessionFile(t),"sessionSetFile"),sessionCreateBranchedSession:n(t=>this.sessionManager.createBranchedSession(t),"sessionCreateBranchedSession"),getEntry:n(t=>this.sessionManager.getEntry(t),"getEntry"),buildSessionContext:n(()=>this.sessionManager.buildSessionContext(),"buildSessionContext"),replaceAgentMessages:n(t=>this.agent.replaceMessages(t),"replaceAgentMessages"),appendThinkingLevelChange:n(t=>this.sessionManager.appendThinkingLevelChange(t),"appendThinkingLevelChange"),getThinkingLevel:n(()=>this.thinkingLevel,"getThinkingLevel"),getBranch:n(()=>this.sessionManager.getBranch(),"getBranch"),getDefaultThinkingLevel:n(()=>this.settingsManager.getDefaultThinkingLevel()??D,"getDefaultThinkingLevel"),getAvailableModels:n(()=>this._modelRegistry.getAvailable(),"getAvailableModels"),restoreModel:n(t=>this._modelController.restoreModel(t),"restoreModel"),restoreThinkingLevel:n(t=>this._modelController.restoreThinkingLevel(t),"restoreThinkingLevel"),runSetup:n(t=>t(this.sessionManager),"runSetup"),extractUserMessageText:n(t=>this._extractUserMessageText(t),"extractUserMessageText")}),this.agent.setModelErrorRecovery(t=>this._recoverModelErrorInLoop(t)),this._unsubscribeAgent=this.agent.subscribe(this._handleAgentEvent),e.signal){const t=n(()=>{this.abort()},"externalAbortHandler");e.signal.addEventListener("abort",t,{once:!0}),this._detachExternalAbort=()=>{e.signal?.removeEventListener("abort",t)}}this._buildRuntime({activeToolNames:this._initialActiveToolNames,includeAllExtensionTools:!0}),this._retryCoordinator=new oe(this._createRetryHost()),this._logger=ie({sessionId:this.sessionManager.getSessionId(),component:"agent-session"})}get modelRegistry(){return this._modelRegistry}get cwd(){return this._cwd}get agentDir(){return this._agentDir}getSlashCommands(){return ne({promptTemplates:this.promptTemplates,resourceLoader:this._resourceLoader,extensionRunner:this._extensionRunner},W)}async tryExecuteExtensionCommand(e){return this._tryExecuteExtensionCommand(e)}async executeSlashCommand(e){return e.startsWith("/")?this._slashCommandExecutor&&await this._slashCommandExecutor(e)?!0:this._tryExecuteExtensionCommand(e):!1}setSlashCommandExecutor(e){this._slashCommandExecutor=e}_emit(e){this._listeners.emit(e)}_lastAssistantMessage=void 0;_handleAgentEvent=n(async e=>{if(e.type==="message_start"&&e.message.role==="user"){const t=this._getUserMessageText(e.message);if(t){const s=this._steeringMessages.indexOf(t);if(s!==-1)this._steeringMessages.splice(s,1);else{const o=this._followUpMessages.indexOf(t);o!==-1&&this._followUpMessages.splice(o,1)}}}if(e.type==="message_update")this._emit(e),this._extensionEventBridge.emitExtensionEvent(e).catch(t=>{this._logger.error("[extension] message_update event error",{error:t})});else{const t=this._extensionEventBridge.emitExtensionEvent(e);this._emit(e),await t}if(e.type==="message_end"&&(e.message.role==="custom"?this.sessionManager.appendCustomMessageEntry(e.message.customType,e.message.content,e.message.display,e.message.details):(e.message.role==="user"||e.message.role==="assistant"||e.message.role==="toolResult")&&this.sessionManager.appendMessage(e.message),e.message.role==="assistant"&&(this._lastAssistantMessage=e.message,e.message.stopReason!=="error"&&this._retryCoordinator.onSuccess())),e.type==="agent_end"&&this._lastAssistantMessage){const t=this._lastAssistantMessage;if(this._lastAssistantMessage=void 0,this._retryCoordinator.isRetryableError(t)&&await this._retryCoordinator.handleError(t))return;if(await this._checkCompaction(t),this._soulManager){const s=t.stopReason==="error"?"failure":"success",o=this._cwd.split(/[/\\]/).pop()||"unknown",{tags:r,complexity:i,toolUsage:c}=S(this.state.messages,this._cwd),g=w(o,r,i,c),l=r[0]||o;(async()=>{try{await this._soulManager.recordInteraction(g,s,"turn"),await this._soulManager.updateExpertise(l,r,s==="success")}catch(m){this._logger.warn("[soul] recordInteraction/updateExpertise failed",{error:m})}})()}}e.type==="agent_end"&&this._extensionRunner&&this._extensionRunner.emit({type:"agent_end",messages:e.messages}).catch(t=>{this._logger.error("[extension] agent_end event error",{error:t})})},"_handleAgentEvent");_getUserMessageText(e){if(e.role!=="user")return"";const t=e.content;return typeof t=="string"?t:t.filter(o=>o.type==="text").map(o=>o.text).join("")}_findLastAssistantMessage(){const e=this.agent.state.messages;for(let t=e.length-1;t>=0;t--){const s=e[t];if(s.role==="assistant")return s}}subscribe(e){return this._listeners.add(e)}_disconnectFromAgent(){this._unsubscribeAgent&&(this._unsubscribeAgent(),this._unsubscribeAgent=void 0)}_reconnectToAgent(){this._unsubscribeAgent||(this._unsubscribeAgent=this.agent.subscribe(this._handleAgentEvent))}dispose(){this._disconnectFromAgent(),this._extensionRunner?.dispose(),this._listeners.clear(),this._detachExternalAbort&&(this._detachExternalAbort(),this._detachExternalAbort=void 0)}get state(){return this.agent.state}get model(){return this.agent.state.model}get thinkingLevel(){return this.agent.state.thinkingLevel}get agentLoopFramework(){return this.agent.agentLoopFramework}get isStreaming(){return this.agent.state.isStreaming}get systemPrompt(){return this.agent.state.systemPrompt}get soulManager(){return this._soulManager}get retryAttempt(){return this._retryCoordinator.attempt}getActiveToolNames(){return this.agent.state.tools.map(e=>e.name)}getAllTools(){return this._toolOrchestrator.getAllTools()}setActiveToolsByName(e){const{tools:t,validToolNames:s}=this._toolOrchestrator.setActiveToolsByName(e);this.agent.setTools(t),this._baseSystemPrompt=this._rebuildSystemPrompt(s),this.agent.setSystemPrompt(this._baseSystemPrompt)}get isCompacting(){return this._compactionController.isCompacting}get messages(){return this.agent.state.messages}get steeringMode(){return this.agent.getSteeringMode()}get followUpMode(){return this.agent.getFollowUpMode()}get sessionFile(){return this.sessionManager.getSessionFile()}get sessionId(){return this.sessionManager.getSessionId()}get sessionName(){return this.sessionManager.getSessionName()}get scopedModels(){return this._scopedModels}setScopedModels(e){this._scopedModels=e}get promptTemplates(){return this._resourceLoader.getPrompts().prompts}_rebuildSystemPrompt(e,t){return J({cwd:this._cwd,resourceLoader:this._resourceLoader,toolNames:e,baseToolRegistry:this._baseToolRegistry,soulInjection:t?.soulInjection??this._lastSoulInjection})}_getActiveBaseToolNames(){return Y(this.getActiveToolNames(),this._baseToolRegistry)}async _generateSoulInjection(){if(!this._soulManager){this._lastSoulInjection=void 0;return}try{const e=this._cwd.split(/[/\\]/).pop()||"unknown",{tags:t,complexity:s,toolUsage:o}=S(this.state.messages,this._cwd),r=await this._soulManager.generateInjection(w(e,t,s,o));return this._lastSoulInjection=typeof r=="string"&&r.trim().length>0?r:void 0,this._lastSoulInjection}catch(e){return this._emit({type:"sdk:error",source:"soul",error:e}),this._lastSoulInjection}}async prompt(e,t){const s=t?.expandPromptTemplates??!0;if(this._dbg(`prompt: "${e.slice(0,80)}" isStreaming=${this.isStreaming} hasModel=${!!this.model}`),s&&e.startsWith("/")){const u=await this.executeSlashCommand(e);if(this._dbg(`prompt: slash handled=${u}`),u)return}let o=e,r=t?.images;if(this._extensionRunner?.hasHandlers("input")){const u=await this._extensionRunner.emitInput(o,r,t?.source??"interactive");if(u.action==="handled")return;u.action==="transform"&&(o=u.text,r=u.images??r)}let i=o;if(s&&(i=this._expandSkillCommand(i),i=f(i,[...this.promptTemplates])),this.isStreaming){if(!t?.streamingBehavior)throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");t.streamingBehavior==="followUp"?await this._queueFollowUp(i,r):await this._queueSteer(i,r);return}if(this._bashRunner.flushPending(),!this.model)throw new Error(`No model selected.
1
+ var E=Object.defineProperty;var n=(a,e)=>E(a,"name",{value:e,configurable:!0});import{appendFileSync as v,readFileSync as k}from"node:fs";import{homedir as L}from"node:os";import{basename as P,dirname as I,join as f}from"node:path";import{isContextOverflow as b}from"@pencil-agent/ai/overflow";import{resetApiProviders as F}from"@pencil-agent/ai/registry";import{getDocsPath as C}from"../../config.js";import{stripFrontmatter as N}from"../../utils/frontmatter.js";import{calculateContextTokens as w,collectEntriesForBranchSummary as U,estimateContextTokens as B,shouldCompact as D}from"../session/compaction/index.js";import{ToolOrchestrator as O}from"../tools/orchestrator.js";import{DEFAULT_THINKING_LEVEL as $}from"../platform/config/defaults.js";import{createExtensionTelemetrySink as j}from"../platform/telemetry/index.js";import{ExtensionRunner as W}from"../extensions-host/index.js";import{expandPromptTemplate as y}from"../prompt/prompt-templates.js";import{getLatestCompactionEntry as x}from"../session/session-manager.js";import{t as H}from"../platform/i18n/index.js";import{toSoulContext as S,extractSessionContext as R}from"../soul-integration.js";import{createDefaultRuntimeTools as K}from"./default-tools.js";import{BashRunner as V}from"./bash-runner.js";import{Listeners as q}from"../platform/listeners.js";import{ModelController as Q}from"./model-controller.js";import{CompactionController as G}from"./compaction-controller.js";import{SessionLifecycleController as X}from"./session-lifecycle-controller.js";import{SessionTreeController as z}from"./session-tree-controller.js";import{ToolRuntimeController as J}from"./tool-runtime-controller.js";import{buildRuntimeSystemPrompt as Y,getActiveBaseToolNames as Z}from"./prompt-assembly.js";import{exportSessionHtml as ee,getLastAssistantText as te}from"./export-bridge.js";import{ExtensionEventBridge as se}from"./event-bridge.js";import{bindExtensionCore as ne}from"./extension-core-bindings.js";import{buildSessionSlashCommands as oe}from"./slash-command-catalog.js";import{RetryCoordinator as ie}from"./retry-coordinator.js";import{createLogger as re}from"../platform/utils/logger.js";import{createAgentTool as ae,createTaskToolAlias as le,createSendMessageTool as he,AGENT_TOOL_NAME as M,TASK_TOOL_NAME as ge,SEND_MESSAGE_TOOL_NAME as T}from"../sub-agent/index.js";import{CycleModelError as Je}from"./model-controller.js";function Qe(a){const e=a.match(/^<skill name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill>(?:\n\n([\s\S]+))?$/);return e?{name:e[1],location:e[2],content:e[3],userMessage:e[4]?.trim()||void 0}:null}n(Qe,"parseSkillBlock");function A(a,e){const t=new Set(e.content.filter(o=>o.type==="toolCall").map(o=>o.id));let s=a.length;for(;s>0&&ce(a[s-1],t);)s--;return s>0&&me(a[s-1],e)&&s--,a.slice(0,s)}n(A,"pruneRecoverableErrorTail");function ce(a,e){return a.role==="toolResult"&&e.has(a.toolCallId)}n(ce,"isRecoverableTailToolResult");function me(a,e){return a.role==="assistant"&&a.stopReason===e.stopReason&&a.timestamp===e.timestamp&&a.provider===e.provider&&a.model===e.model&&a.api===e.api&&a.errorMessage===e.errorMessage}n(me,"isSameRecoverableAssistantMessage");function ue(a){switch(a.type){case"agent_start":return{type:"sub_agent_start",subAgentId:a.subAgentId,agentType:a.agentType,description:a.description,isAsync:a.isAsync};case"tool_start":return{type:"sub_agent_tool_start",subAgentId:a.subAgentId,toolName:a.toolName};case"tool_end":return{type:"sub_agent_tool_end",subAgentId:a.subAgentId,toolName:a.toolName,isError:a.isError};case"agent_end":return{type:"sub_agent_end",subAgentId:a.subAgentId,success:a.success};default:return}}n(ue,"mapSubAgentEvent");class Ge{static{n(this,"AgentSession")}agent;sessionManager;settingsManager;agentCtx;_scopedModels;_unsubscribeAgent;_detachExternalAbort;_listeners=new q;_steeringMessages=[];_followUpMessages=[];_pendingNextTurnMessages=[];_retryCoordinator;_logger;_bashRunner;_extensionRunner=void 0;_slashCommandExecutor=void 0;_extensionEventBridge;_resourceLoader;_theme;_debugLevel="off";_dbg(e){if(process.env.NANOPENCIL_DEBUG_SESSION==="1")try{const t=f(L(),".nanopencil","agent","nanopencil-debug.log");v(t,`[${new Date().toISOString()}] [session] ${e}
2
+ `)}catch{}}_customTools;_staticCustomTools;_mcpToolsFactory;_soulManagerFactory;_baseToolRegistry=new Map;_agentTool;_createSessionFactory;_cwd;_extensionRunnerRef;_soulManager;_lastSoulInjection;_initialActiveToolNames;_baseToolsOverride;_extensionUIContext;_extensionCommandContextActions;_extensionShutdownHandler;_extensionErrorListener;_extensionErrorUnsubscriber;_modelRegistry;_agentDir;_baseSystemPrompt="";_modelController;_compactionController;_sessionTreeController;_lifecycleController;_toolOrchestrator;_toolRuntimeController;constructor(e){if(this.agent=e.agent,this.sessionManager=e.sessionManager,this.settingsManager=e.settingsManager,this.agentCtx=e.agentCtx,this._scopedModels=e.scopedModels??[],this._resourceLoader=e.resourceLoader,this._theme=e.theme,this._debugLevel=e.debugLevel??"off",this._bashRunner=new V({getCwd:n(()=>this._cwd,"getCwd"),getShellCommandPrefix:n(()=>this.settingsManager.getShellCommandPrefix(),"getShellCommandPrefix"),appendToAgent:n(t=>this.agent.appendMessage(t),"appendToAgent"),appendToSession:n(t=>this.sessionManager.appendMessage(t),"appendToSession"),isStreaming:n(()=>this.isStreaming,"isStreaming")}),this._staticCustomTools=e.customTools??[],this._mcpToolsFactory=e.mcpToolsFactory,this._soulManagerFactory=e.soulManagerFactory,this._customTools=[...this._staticCustomTools,...e.initialMcpTools??[]],this._initialActiveToolNames=e.initialActiveToolNames,this._toolOrchestrator=new O({customTools:this._customTools,initialActiveToolNames:this._initialActiveToolNames,getExtensionTools:n(()=>new Map((this._extensionRunner?.getAllRegisteredTools()??[]).map(t=>[t.definition.name,t.definition])),"getExtensionTools")}),this._toolRuntimeController=new J(this._toolOrchestrator),this._cwd=e.cwd,this._agentDir=e.agentDir,this._modelRegistry=e.modelRegistry,this._extensionRunnerRef=e.extensionRunnerRef,this._soulManager=e.soulManager,this._baseToolsOverride=e.baseToolsOverride,this._createSessionFactory=e.createSession,this._extensionEventBridge=new se({getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner")}),this._modelController=new Q({getModel:n(()=>this.model,"getModel"),getThinkingLevel:n(()=>this.thinkingLevel,"getThinkingLevel"),getScopedModels:n(()=>this._scopedModels,"getScopedModels"),setAgentModel:n(t=>this.agent.setModel(t),"setAgentModel"),setAgentThinkingLevel:n(t=>this.agent.setThinkingLevel(t),"setAgentThinkingLevel"),setAgentLoopFramework:n(t=>this.agent.setAgentLoopFramework(t),"setAgentLoopFramework"),setLoopPolicy:n(t=>this.agent.setLoopPolicy(t),"setLoopPolicy"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getApiKeyForProvider:n(t=>this._modelRegistry.getApiKeyForProvider(t),"getApiKeyForProvider"),getAvailableModels:n(()=>this._modelRegistry.getAvailableAsync(),"getAvailableModels"),getAuthCredential:n(t=>this._modelRegistry.authStorage.get(t),"getAuthCredential"),appendModelChange:n((t,s)=>this.sessionManager.appendModelChange(t,s),"appendModelChange"),appendThinkingLevelChange:n(t=>this.sessionManager.appendThinkingLevelChange(t),"appendThinkingLevelChange"),setDefaultModelAndProvider:n((t,s)=>this.settingsManager.setDefaultModelAndProvider(t,s),"setDefaultModelAndProvider"),setDefaultThinkingLevel:n(t=>this.settingsManager.setDefaultThinkingLevel(t),"setDefaultThinkingLevel"),emitModelSelect:n(async({model:t,previousModel:s,source:o})=>{this._extensionRunner&&await this._extensionRunner.emit({type:"model_select",model:t,previousModel:s,source:o})},"emitModelSelect")}),this._compactionController=new G({getModel:n(()=>this.model,"getModel"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),getBranch:n(()=>this.sessionManager.getBranch(),"getBranch"),getEntries:n(()=>this.sessionManager.getEntries(),"getEntries"),getCompactionSettings:n(()=>this.settingsManager.getCompactionSettings(),"getCompactionSettings"),appendCompaction:n((t,s,o,r,i)=>this.sessionManager.appendCompaction(t,s,o,r,i),"appendCompaction"),applyCompactedMessages:n(()=>{const t=this.sessionManager.buildSessionContext();return this.agent.replaceMessages(t.messages),t.messages},"applyCompactedMessages"),logInfo:n((t,s)=>this._logger.info(t,s),"logInfo"),disconnectFromAgent:n(()=>this._disconnectFromAgent(),"disconnectFromAgent"),reconnectToAgent:n(()=>this._reconnectToAgent(),"reconnectToAgent"),abortAgent:n(()=>this.abort(),"abortAgent"),emitAutoCompactionStart:n(t=>this._emit({type:"auto_compaction_start",reason:t}),"emitAutoCompactionStart"),emitAutoCompactionEnd:n(t=>this._emit({type:"auto_compaction_end",...t}),"emitAutoCompactionEnd"),getAutoCompactionEnabled:n(()=>this.settingsManager.getCompactionEnabled(),"getAutoCompactionEnabled"),setAutoCompactionEnabled:n(t=>this.settingsManager.setCompactionEnabled(t),"setAutoCompactionEnabled")}),this._sessionTreeController=new z({getModel:n(()=>this.model,"getModel"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),getLeafId:n(()=>this.sessionManager.getLeafId(),"getLeafId"),getEntry:n(t=>this.sessionManager.getEntry(t),"getEntry"),collectBranchSummaryEntries:n((t,s)=>U(this.sessionManager,t,s),"collectBranchSummaryEntries"),getBranchSummaryReserveTokens:n(()=>this.settingsManager.getBranchSummarySettings().reserveTokens,"getBranchSummaryReserveTokens"),branchWithSummary:n((t,s,o,r)=>this.sessionManager.branchWithSummary(t,s,o,r),"branchWithSummary"),appendLabelChange:n((t,s)=>this.sessionManager.appendLabelChange(t,s),"appendLabelChange"),resetLeaf:n(()=>this.sessionManager.resetLeaf(),"resetLeaf"),branch:n(t=>this.sessionManager.branch(t),"branch"),rebuildAgentMessages:n(()=>{const t=this.sessionManager.buildSessionContext();this.agent.replaceMessages(t.messages)},"rebuildAgentMessages"),extractUserMessageText:n(t=>this._extractUserMessageText(t),"extractUserMessageText")}),this._lifecycleController=new X({getSessionFile:n(()=>this.sessionManager.getSessionFile(),"getSessionFile"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),disconnectFromAgent:n(()=>this._disconnectFromAgent(),"disconnectFromAgent"),reconnectToAgent:n(()=>this._reconnectToAgent(),"reconnectToAgent"),abortAgent:n(()=>this.abort(),"abortAgent"),resetAgent:n(()=>this.agent.reset(),"resetAgent"),syncAgentSessionId:n(()=>{this.agent.sessionId=this.sessionManager.getSessionId()},"syncAgentSessionId"),clearPendingQueues:n(()=>{this._steeringMessages=[],this._followUpMessages=[],this._pendingNextTurnMessages=[]},"clearPendingQueues"),clearPendingNextTurnMessages:n(()=>{this._pendingNextTurnMessages=[]},"clearPendingNextTurnMessages"),sessionNewSession:n(t=>this.sessionManager.newSession({parentSession:t}),"sessionNewSession"),sessionSetFile:n(t=>this.sessionManager.setSessionFile(t),"sessionSetFile"),sessionCreateBranchedSession:n(t=>this.sessionManager.createBranchedSession(t),"sessionCreateBranchedSession"),getEntry:n(t=>this.sessionManager.getEntry(t),"getEntry"),buildSessionContext:n(()=>this.sessionManager.buildSessionContext(),"buildSessionContext"),replaceAgentMessages:n(t=>this.agent.replaceMessages(t),"replaceAgentMessages"),appendThinkingLevelChange:n(t=>this.sessionManager.appendThinkingLevelChange(t),"appendThinkingLevelChange"),getThinkingLevel:n(()=>this.thinkingLevel,"getThinkingLevel"),getBranch:n(()=>this.sessionManager.getBranch(),"getBranch"),getDefaultThinkingLevel:n(()=>this.settingsManager.getDefaultThinkingLevel()??$,"getDefaultThinkingLevel"),getAvailableModels:n(()=>this._modelRegistry.getAvailable(),"getAvailableModels"),restoreModel:n(t=>this._modelController.restoreModel(t),"restoreModel"),restoreThinkingLevel:n(t=>this._modelController.restoreThinkingLevel(t),"restoreThinkingLevel"),runSetup:n(t=>t(this.sessionManager),"runSetup"),extractUserMessageText:n(t=>this._extractUserMessageText(t),"extractUserMessageText")}),this.agent.setModelErrorRecovery(t=>this._recoverModelErrorInLoop(t)),this._unsubscribeAgent=this.agent.subscribe(this._handleAgentEvent),e.signal){const t=n(()=>{this.abort()},"externalAbortHandler");e.signal.addEventListener("abort",t,{once:!0}),this._detachExternalAbort=()=>{e.signal?.removeEventListener("abort",t)}}this._buildRuntime({activeToolNames:this._initialActiveToolNames,includeAllExtensionTools:!0}),this._retryCoordinator=new ie(this._createRetryHost()),this._logger=re({sessionId:this.sessionManager.getSessionId(),component:"agent-session"}),this._emitDebug("basic","session","session_created",{sessionId:this.sessionManager.getSessionId()})}get modelRegistry(){return this._modelRegistry}get cwd(){return this._cwd}get agentDir(){return this._agentDir}getSlashCommands(){return oe({promptTemplates:this.promptTemplates,resourceLoader:this._resourceLoader,extensionRunner:this._extensionRunner},H)}async tryExecuteExtensionCommand(e){return this._tryExecuteExtensionCommand(e)}async executeSlashCommand(e){return e.startsWith("/")?this._slashCommandExecutor&&await this._slashCommandExecutor(e)?!0:this._tryExecuteExtensionCommand(e):!1}setSlashCommandExecutor(e){this._slashCommandExecutor=e}_emit(e){this._listeners.emit(e)}_emitDebug(e,t,s,o){this._debugLevel!=="off"&&(e==="verbose"&&this._debugLevel!=="verbose"||this._emit({type:"debug",level:e,source:t,message:s,data:o,timestamp:Date.now()}))}_lastAssistantMessage=void 0;_handleAgentEvent=n(async e=>{if(e.type==="message_start"&&e.message.role==="user"){const t=this._getUserMessageText(e.message);if(t){const s=this._steeringMessages.indexOf(t);if(s!==-1)this._steeringMessages.splice(s,1);else{const o=this._followUpMessages.indexOf(t);o!==-1&&this._followUpMessages.splice(o,1)}}}if(e.type==="message_update")this._emit(e),this._extensionEventBridge.emitExtensionEvent(e).catch(t=>{this._logger.error("[extension] message_update event error",{error:t})});else{const t=this._extensionEventBridge.emitExtensionEvent(e);this._emit(e),await t}if(e.type==="tool_execution_start"?this._emitDebug("verbose","tool","tool_start",{toolName:e.toolName,toolCallId:e.toolCallId}):e.type==="tool_execution_end"&&this._emitDebug("verbose","tool","tool_end",{toolName:e.toolName,isError:e.isError}),e.type==="message_end"&&(e.message.role==="custom"?this.sessionManager.appendCustomMessageEntry(e.message.customType,e.message.content,e.message.display,e.message.details):(e.message.role==="user"||e.message.role==="assistant"||e.message.role==="toolResult")&&this.sessionManager.appendMessage(e.message),e.message.role==="assistant"&&(this._lastAssistantMessage=e.message,e.message.stopReason!=="error"&&this._retryCoordinator.onSuccess())),e.type==="agent_end"&&this._lastAssistantMessage){const t=this._lastAssistantMessage;if(this._lastAssistantMessage=void 0,this._retryCoordinator.isRetryableError(t)&&await this._retryCoordinator.handleError(t))return;if(await this._checkCompaction(t),this._soulManager){const s=t.stopReason==="error"?"failure":"success",o=this._cwd.split(/[/\\]/).pop()||"unknown",{tags:r,complexity:i,toolUsage:l}=R(this.state.messages,this._cwd),m=S(o,r,i,l),g=r[0]||o;(async()=>{try{await this._soulManager.recordInteraction(m,s,"turn"),await this._soulManager.updateExpertise(g,r,s==="success")}catch(c){this._logger.warn("[soul] recordInteraction/updateExpertise failed",{error:c})}})()}}e.type==="agent_end"&&this._extensionRunner&&this._extensionRunner.emit({type:"agent_end",messages:e.messages}).catch(t=>{this._logger.error("[extension] agent_end event error",{error:t})})},"_handleAgentEvent");_getUserMessageText(e){if(e.role!=="user")return"";const t=e.content;return typeof t=="string"?t:t.filter(o=>o.type==="text").map(o=>o.text).join("")}_findLastAssistantMessage(){const e=this.agent.state.messages;for(let t=e.length-1;t>=0;t--){const s=e[t];if(s.role==="assistant")return s}}subscribe(e){return this._listeners.add(e)}_disconnectFromAgent(){this._unsubscribeAgent&&(this._unsubscribeAgent(),this._unsubscribeAgent=void 0)}_reconnectToAgent(){this._unsubscribeAgent||(this._unsubscribeAgent=this.agent.subscribe(this._handleAgentEvent))}dispose(){this._disconnectFromAgent(),this._extensionRunner?.dispose(),this._listeners.clear(),this._detachExternalAbort&&(this._detachExternalAbort(),this._detachExternalAbort=void 0)}get state(){return this.agent.state}get model(){return this.agent.state.model}get thinkingLevel(){return this.agent.state.thinkingLevel}get agentLoopFramework(){return this.agent.agentLoopFramework}get isStreaming(){return this.agent.state.isStreaming}get systemPrompt(){return this.agent.state.systemPrompt}get soulManager(){return this._soulManager}get retryAttempt(){return this._retryCoordinator.attempt}getActiveToolNames(){return this.agent.state.tools.map(e=>e.name)}getAllTools(){return this._toolOrchestrator.getAllTools()}setActiveToolsByName(e){const{tools:t,validToolNames:s}=this._toolOrchestrator.setActiveToolsByName(e);this.agent.setTools(t),this._baseSystemPrompt=this._rebuildSystemPrompt(s),this.agent.setSystemPrompt(this._baseSystemPrompt)}get isCompacting(){return this._compactionController.isCompacting}get messages(){return this.agent.state.messages}get steeringMode(){return this.agent.getSteeringMode()}get followUpMode(){return this.agent.getFollowUpMode()}get sessionFile(){return this.sessionManager.getSessionFile()}get sessionId(){return this.sessionManager.getSessionId()}get sessionName(){return this.sessionManager.getSessionName()}get scopedModels(){return this._scopedModels}setScopedModels(e){this._scopedModels=e}get promptTemplates(){return this._resourceLoader.getPrompts().prompts}_rebuildSystemPrompt(e,t){return Y({cwd:this._cwd,resourceLoader:this._resourceLoader,toolNames:e,baseToolRegistry:this._baseToolRegistry,soulInjection:t?.soulInjection??this._lastSoulInjection})}_getActiveBaseToolNames(){return Z(this.getActiveToolNames(),this._baseToolRegistry)}async _generateSoulInjection(){if(!this._soulManager){this._lastSoulInjection=void 0;return}try{const e=this._cwd.split(/[/\\]/).pop()||"unknown",{tags:t,complexity:s,toolUsage:o}=R(this.state.messages,this._cwd),r=await this._soulManager.generateInjection(S(e,t,s,o));return this._lastSoulInjection=typeof r=="string"&&r.trim().length>0?r:void 0,this._lastSoulInjection}catch(e){return this._emit({type:"sdk:error",source:"soul",error:e}),this._lastSoulInjection}}async prompt(e,t){const s=performance.now(),o=t?.expandPromptTemplates??!0;if(this._dbg(`prompt: "${e.slice(0,80)}" isStreaming=${this.isStreaming} hasModel=${!!this.model}`),o&&e.startsWith("/")){const u=await this.executeSlashCommand(e);if(this._dbg(`prompt: slash handled=${u}`),u)return}let r=e,i=t?.images;if(this._extensionRunner?.hasHandlers("input")){const u=await this._extensionRunner.emitInput(r,i,t?.source??"interactive");if(u.action==="handled")return;u.action==="transform"&&(r=u.text,i=u.images??i)}let l=r;if(o&&(l=this._expandSkillCommand(l),l=y(l,[...this.promptTemplates])),this.isStreaming){if(!t?.streamingBehavior)throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");t.streamingBehavior==="followUp"?await this._queueFollowUp(l,i):await this._queueSteer(l,i);return}if(this._bashRunner.flushPending(),!this.model)throw new Error(`No model selected.
3
3
 
4
- Use /login or set an API key environment variable. See ${_(C(),"providers.md")}
4
+ Use /login or set an API key environment variable. See ${f(C(),"providers.md")}
5
5
 
6
6
  Then use /model to select a model.`);if(!await this._modelRegistry.getApiKey(this.model))throw this._modelRegistry.isUsingOAuth(this.model)?new Error(`Authentication failed for "${this.model.provider}". Credentials may have expired or network is unavailable. Run '/login ${this.model.provider}' to re-authenticate.`):new Error(`No API key found for ${this.model.provider}.
7
7
 
8
- Use /login or set an API key environment variable. See ${_(C(),"providers.md")}`);const g=this._findLastAssistantMessage();g&&await this._checkCompaction(g,!1);const l=[],m=[{type:"text",text:i}];r&&m.push(...r),l.push({role:"user",content:m,timestamp:Date.now()});for(const u of this._pendingNextTurnMessages)l.push(u);this._pendingNextTurnMessages=[];const h=this._getActiveBaseToolNames(),d=await this._generateSoulInjection();if(this._baseSystemPrompt=this._rebuildSystemPrompt(h,{soulInjection:d}),this._extensionRunner){const u=await this._extensionRunner.emitBeforeAgentStart(i,r,this._baseSystemPrompt);if(u?.messages)for(const p of u.messages)l.push({role:"custom",customType:p.customType,content:p.content,display:p.display,details:p.details,timestamp:Date.now()});u?.systemPrompt?this.agent.setSystemPrompt(u.systemPrompt):this.agent.setSystemPrompt(this._baseSystemPrompt)}else this.agent.setSystemPrompt(this._baseSystemPrompt);this._dbg(`calling agent.prompt with ${l.length} message(s)`),await this.agent.prompt(l),this._dbg("agent.prompt returned"),await this.waitForRetry()}async _tryExecuteExtensionCommand(e){if(!this._extensionRunner)return!1;const t=e.indexOf(" "),s=t===-1?e.slice(1):e.slice(1,t),o=t===-1?"":e.slice(t+1),r=this._extensionRunner.createCommandContext();return(await this._extensionRunner.invokeCommand(s,o,r,{sessionId:this.sessionManager.getSessionId()})).found}_expandSkillCommand(e){if(!e.startsWith("/skill:"))return e;const t=e.indexOf(" "),s=t===-1?e.slice(7):e.slice(7,t),o=t===-1?"":e.slice(t+1).trim(),r=this.resourceLoader.getSkills().skills.find(i=>i.name===s);if(!r)return e;try{const i=v(r.filePath,"utf-8"),c=F(i).trim(),g=`<skill name="${r.name}" location="${r.filePath}">
8
+ Use /login or set an API key environment variable. See ${f(C(),"providers.md")}`);const g=this._findLastAssistantMessage();g&&await this._checkCompaction(g,!1);const c=[],h=[{type:"text",text:l}];i&&h.push(...i),c.push({role:"user",content:h,timestamp:Date.now()});for(const u of this._pendingNextTurnMessages)c.push(u);this._pendingNextTurnMessages=[];const d=this._getActiveBaseToolNames(),_=await this._generateSoulInjection();if(this._baseSystemPrompt=this._rebuildSystemPrompt(d,{soulInjection:_}),this._extensionRunner){const u=await this._extensionRunner.emitBeforeAgentStart(l,i,this._baseSystemPrompt);if(u?.messages)for(const p of u.messages)c.push({role:"custom",customType:p.customType,content:p.content,display:p.display,details:p.details,timestamp:Date.now()});u?.systemPrompt?this.agent.setSystemPrompt(u.systemPrompt):this.agent.setSystemPrompt(this._baseSystemPrompt)}else this.agent.setSystemPrompt(this._baseSystemPrompt);this._dbg(`calling agent.prompt with ${c.length} message(s)`),await this.agent.prompt(c),this._dbg(`agent.prompt returned (${(performance.now()-s).toFixed(0)}ms)`),await this.waitForRetry()}async _tryExecuteExtensionCommand(e){if(!this._extensionRunner)return!1;const t=e.indexOf(" "),s=t===-1?e.slice(1):e.slice(1,t),o=t===-1?"":e.slice(t+1),r=this._extensionRunner.createCommandContext();return(await this._extensionRunner.invokeCommand(s,o,r,{sessionId:this.sessionManager.getSessionId()})).found}_expandSkillCommand(e){if(!e.startsWith("/skill:"))return e;const t=e.indexOf(" "),s=t===-1?e.slice(7):e.slice(7,t),o=t===-1?"":e.slice(t+1).trim(),r=this.resourceLoader.getSkills().skills.find(i=>i.name===s);if(!r)return e;try{const i=k(r.filePath,"utf-8"),l=N(i).trim(),m=`<skill name="${r.name}" location="${r.filePath}">
9
9
  References are relative to ${r.baseDir}.
10
10
 
11
- ${c}
12
- </skill>`;return o?`${g}
11
+ ${l}
12
+ </skill>`;return o?`${m}
13
13
 
14
- ${o}`:g}catch(i){return this._extensionRunner?.emitError({extensionPath:r.filePath,event:"skill_expansion",error:i instanceof Error?i.message:String(i)}),e}}async steer(e,t){e.startsWith("/")&&this._throwIfExtensionCommand(e);let s=this._expandSkillCommand(e);s=f(s,[...this.promptTemplates]),await this._queueSteer(s,t)}async followUp(e,t){e.startsWith("/")&&this._throwIfExtensionCommand(e);let s=this._expandSkillCommand(e);s=f(s,[...this.promptTemplates]),await this._queueFollowUp(s,t)}async _queueSteer(e,t){this._steeringMessages.push(e);const s=[{type:"text",text:e}];t&&s.push(...t),this.agent.steer({role:"user",content:s,timestamp:Date.now()})}async _queueFollowUp(e,t){this._followUpMessages.push(e);const s=[{type:"text",text:e}];t&&s.push(...t),this.agent.followUp({role:"user",content:s,timestamp:Date.now()})}_throwIfExtensionCommand(e){if(!this._extensionRunner)return;const t=e.indexOf(" "),s=t===-1?e.slice(1):e.slice(1,t);if(this._extensionRunner.getCommand(s))throw new Error(`Extension command "/${s}" cannot be queued. Use prompt() or execute the command when not streaming.`)}async sendCustomMessage(e,t){const s={role:"custom",customType:e.customType,content:e.content,display:e.display,details:e.details,timestamp:Date.now()};t?.deliverAs==="nextTurn"?this._pendingNextTurnMessages.push(s):this.isStreaming?t?.deliverAs==="followUp"?this.agent.followUp(s):this.agent.steer(s):t?.triggerTurn?await this.agent.prompt(s):(this.agent.appendMessage(s),this.sessionManager.appendCustomMessageEntry(e.customType,e.content,e.display,e.details),this._emit({type:"message_start",message:s}),this._emit({type:"message_end",message:s}))}async sendUserMessage(e,t){let s,o;if(typeof e=="string")s=e;else{const r=[];o=[];for(const i of e)i.type==="text"?r.push(i.text):i.type==="image"&&o.push(i);s=r.join(`
15
- `),o.length===0&&(o=void 0)}await this.prompt(s,{expandPromptTemplates:!1,streamingBehavior:t?.deliverAs,images:o,source:"extension"})}clearQueue(){const e=[...this._steeringMessages],t=[...this._followUpMessages];return this._steeringMessages=[],this._followUpMessages=[],this.agent.clearAllQueues(),{steering:e,followUp:t}}get pendingMessageCount(){return this._steeringMessages.length+this._followUpMessages.length}getSteeringMessages(){return this._steeringMessages}getFollowUpMessages(){return this._followUpMessages}get resourceLoader(){return this._resourceLoader}async abort(){this.abortRetry(),this.agent.abort(),await this.agent.waitForIdle(),this._extensionRunner?.emit({type:"agent_abort"})}async newSession(e){return this._lifecycleController.newSession(e)}async setModel(e){await this._modelController.setModel(e)}async cycleModel(e="forward"){return this._modelController.cycleModel(e)}setThinkingLevel(e){this._modelController.setThinkingLevel(e)}setAgentLoopFramework(e){this._modelController.setAgentLoopFramework(e)}setLoopPolicy(e){this._modelController.setLoopPolicy(e)}cycleThinkingLevel(){return this._modelController.cycleThinkingLevel()}getAvailableThinkingLevels(){return this._modelController.getAvailableThinkingLevels()}supportsXhighThinking(){return this._modelController.supportsXhighThinking()}supportsThinking(){return this._modelController.supportsThinking()}setSteeringMode(e){this.agent.setSteeringMode(e),this.settingsManager.setSteeringMode(e)}setFollowUpMode(e){this.agent.setFollowUpMode(e),this.settingsManager.setFollowUpMode(e)}async compact(e){return this._compactionController.compact(e)}abortCompaction(){this._compactionController.abort()}abortBranchSummary(){this._sessionTreeController.abortBranchSummary()}async _checkCompaction(e,t=!0){const s=this.settingsManager.getCompactionSettings();if(!s.enabled||t&&e.stopReason==="aborted")return;const o=this.model?.contextWindow??0,r=this.model&&e.provider===this.model.provider&&e.model===this.model.id,i=y(this.sessionManager.getBranch()),c=i!==null&&e.timestamp<new Date(i.timestamp).getTime();if(r&&!c&&T(e,o)){const l=this.agent.state.messages;l.length>0&&l[l.length-1].role==="assistant"&&this.agent.replaceMessages(l.slice(0,-1)),await this._runAutoCompaction("overflow",!0);return}if(e.stopReason==="error")return;const g=b(e.usage);B(g,o,s)&&await this._runAutoCompaction("threshold",!1)}async _recoverModelErrorInLoop(e){const t=this.settingsManager.getCompactionSettings();if(e.message.role!=="assistant")return{action:"stop"};const s=e.message;if(e.errorSubtype!=="context_overflow"){if(!this._retryCoordinator.isRetryableError(s))return{action:"stop"};if(!await this._retryCoordinator.handleErrorInLoop(s))return{action:"stop"};const h=R(this.agent.state.messages,s);return this.agent.replaceMessages(h),{action:"retry",messages:h,transition:{reason:"model_error_recovery",subtype:e.errorSubtype,attempt:e.attempt}}}if(!t.enabled)return{action:"stop"};const o=this.model?.contextWindow??0;if(!(this.model&&s.provider===this.model.provider&&s.model===this.model.id)||!T(s,o))return{action:"stop"};const i=y(this.sessionManager.getBranch());if(i!==null&&s.timestamp<new Date(i.timestamp).getTime())return{action:"stop"};const g=this.agent.state.messages;this.agent.replaceMessages(R(g,s));const l=await this._runAutoCompaction("overflow",!0,{triggerContinue:!1});return l?{action:"retry",messages:l,transition:{reason:"model_error_recovery",subtype:e.errorSubtype,attempt:e.attempt}}:{action:"stop"}}async _runAutoCompaction(e,t,s){const o=s?.triggerContinue??!0,r=await this._compactionController.runAuto(e,t);if(r!==void 0){if(t&&o){const i=this.agent.state.messages,c=i[i.length-1];c?.role==="assistant"&&c.stopReason==="error"&&this.agent.replaceMessages(i.slice(0,-1)),setTimeout(()=>{this.agent.continue().catch(()=>{})},100)}else!t&&this.agent.hasQueuedMessages()&&setTimeout(()=>{this.agent.continue().catch(()=>{})},100);return r}}setAutoCompactionEnabled(e){this._compactionController.setAutoCompactionEnabled(e)}get autoCompactionEnabled(){return this._compactionController.autoCompactionEnabled}async bindExtensions(e){e.uiContext!==void 0&&(this._extensionUIContext=e.uiContext),e.commandContextActions!==void 0&&(this._extensionCommandContextActions=e.commandContextActions),e.shutdownHandler!==void 0&&(this._extensionShutdownHandler=e.shutdownHandler),e.onError!==void 0&&(this._extensionErrorListener=e.onError),this._extensionRunner&&(this._applyExtensionBindings(this._extensionRunner),await this._extensionRunner.emit({type:"session_start"}),await this.extendResourcesFromExtensions("startup"))}async extendResourcesFromExtensions(e){if(!this._extensionRunner?.hasHandlers("resources_discover"))return;const{skillPaths:t,promptPaths:s,themePaths:o}=await this._extensionRunner.emitResourcesDiscover(this._cwd,e);if(t.length===0&&s.length===0&&o.length===0)return;const r={skillPaths:this.buildExtensionResourcePaths(t),promptPaths:this.buildExtensionResourcePaths(s),themePaths:this.buildExtensionResourcePaths(o)};this._resourceLoader.extendResources(r),this._baseSystemPrompt=this._rebuildSystemPrompt(this.getActiveToolNames()),this.agent.setSystemPrompt(this._baseSystemPrompt)}buildExtensionResourcePaths(e){return e.map(t=>{const s=this.getExtensionSourceLabel(t.extensionPath),o=t.extensionPath.startsWith("<")?void 0:P(t.extensionPath);return{path:t.path,metadata:{source:s,scope:"temporary",origin:"top-level",baseDir:o}}})}getExtensionSourceLabel(e){return e.startsWith("<")?`extension:${e.replace(/[<>]/g,"")}`:`extension:${L(e).replace(/\.(ts|js)$/,"")}`}_applyExtensionBindings(e){e.setUIContext(this._extensionUIContext),e.bindCommandContext(this._extensionCommandContextActions),this._extensionErrorUnsubscriber?.(),this._extensionErrorUnsubscriber=this._extensionErrorListener?e.onError(this._extensionErrorListener):void 0}_bindExtensionCore(e){const t=this;se(e,{promptTemplates:this.promptTemplates,resourceLoader:this._resourceLoader,modelRegistry:this.modelRegistry,sessionManager:this.sessionManager,settingsManager:this.settingsManager,shutdownHandler:this._extensionShutdownHandler,soulManager:this._soulManager,get model(){return t.model},get thinkingLevel(){return t.thinkingLevel},get isStreaming(){return t.isStreaming},get pendingMessageCount(){return t.pendingMessageCount},get systemPrompt(){return t.systemPrompt},sendCustomMessage:n((s,o)=>this.sendCustomMessage(s,o),"sendCustomMessage"),sendUserMessage:n((s,o)=>this.sendUserMessage(s,o),"sendUserMessage"),executeSlashCommand:n(s=>this.executeSlashCommand(s),"executeSlashCommand"),getActiveToolNames:n(()=>this.getActiveToolNames(),"getActiveToolNames"),getAllTools:n(()=>this.getAllTools(),"getAllTools"),setActiveToolsByName:n(s=>this.setActiveToolsByName(s),"setActiveToolsByName"),setModel:n(s=>this.setModel(s),"setModel"),setThinkingLevel:n(s=>this.setThinkingLevel(s),"setThinkingLevel"),abort:n(()=>this.abort(),"abort"),clearFollowUpQueue:n(()=>{this.agent.clearFollowUpQueue(),this._followUpMessages=[]},"clearFollowUpQueue"),getContextUsage:n(()=>this.getContextUsage(),"getContextUsage"),compact:n(s=>this.compact(s),"compact")})}_buildRuntime(e){const t=this._baseToolsOverride?this._baseToolsOverride:H(this._cwd,this.settingsManager);this._baseToolRegistry=new Map(Object.entries(t).map(([m,h])=>[m,h]));const s=this._resourceLoader.getExtensions();if(e.flagValues)for(const[m,h]of e.flagValues)s.runtime.flagValues.set(m,h);const o=s.extensions.length>0,r=this._customTools.length>0;this._extensionRunner=o||r?new j(s.extensions,s.runtime,this._cwd,this._agentDir,this.sessionManager,this._modelRegistry):void 0,this._extensionRunnerRef&&(this._extensionRunnerRef.current=this._extensionRunner),this._extensionRunner&&(this._bindExtensionCore(this._extensionRunner),this._applyExtensionBindings(this._extensionRunner),this._extensionRunner.setTelemetrySink($({workspaceRoot:this._cwd})));const i=this._toolRuntimeController.build({baseTools:this._baseToolRegistry,baseToolsOverride:this._baseToolsOverride,customTools:this._customTools,activeToolNames:e.activeToolNames,includeAllExtensionTools:e.includeAllExtensionTools,extensionRunner:this._extensionRunner}),c=n(m=>{const h=me(m);h&&this._emit(h)},"onSubAgentEvent");this._agentTool=re({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory,onSubAgentEvent:c}),i.activeTools.push(this._agentTool),this._toolOrchestrator.registerTool(x,this._agentTool);const g=ae({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory,onSubAgentEvent:c});i.activeTools.push(g),this._toolOrchestrator.registerTool(he,g);const l=le({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory});i.activeTools.push(l),this._toolOrchestrator.registerTool(M,l),i.systemPromptToolNames.includes(x)||i.systemPromptToolNames.push(x),i.systemPromptToolNames.includes(M)||i.systemPromptToolNames.push(M),this.agent.setTools(i.activeTools),this._baseSystemPrompt=this._rebuildSystemPrompt(i.systemPromptToolNames),this.agent.setSystemPrompt(this._baseSystemPrompt)}async _refreshMcpTools(){if(!this._mcpToolsFactory)return 0;try{const e=await this._mcpToolsFactory();return this._customTools=[...this._staticCustomTools,...e],e.length}catch(e){this._emit({type:"sdk:error",source:"mcp",error:e});const t=this._customTools.filter(s=>s.name.startsWith("mcp_"));return this._customTools=[...this._staticCustomTools,...t],t.length}}async warmupMcpTools(){if(this._mcpToolsFactory)try{const e=await this._refreshMcpTools();this._buildRuntime({activeToolNames:this.getActiveToolNames(),flagValues:this._extensionRunner?.getFlagValues(),includeAllExtensionTools:!0}),this._emit({type:"sdk:mcp_ready",toolCount:e})}catch(e){this._emit({type:"sdk:error",source:"mcp",error:e})}}async reload(){const e=this._extensionRunner?.getFlagValues();if(await this._extensionRunner?.emit({type:"session_shutdown"}),this.settingsManager.reload(),I(),await this._resourceLoader.reload(),await this._refreshMcpTools(),this._soulManagerFactory)try{this._soulManager=await this._soulManagerFactory(),this._lastSoulInjection=void 0}catch(s){this._emit({type:"sdk:error",source:"soul",error:s})}this._buildRuntime({activeToolNames:this.getActiveToolNames(),flagValues:e,includeAllExtensionTools:!0});const t=this._extensionUIContext||this._extensionCommandContextActions||this._extensionShutdownHandler||this._extensionErrorListener;this._extensionRunner&&t&&(await this._extensionRunner.emit({type:"session_start"}),await this.extendResourcesFromExtensions("reload"))}_createRetryHost(){return{getContextWindow:n(()=>this.model?.contextWindow??0,"getContextWindow"),getRetrySettings:n(()=>this.settingsManager.getRetrySettings(),"getRetrySettings"),removeLastAssistantMessage:n(()=>{const e=this.agent.state.messages;e.length>0&&e[e.length-1].role==="assistant"&&this.agent.replaceMessages(e.slice(0,-1))},"removeLastAssistantMessage"),triggerContinue:n(()=>{setTimeout(()=>{this.agent.continue().catch(()=>{})},0)},"triggerContinue"),emitEvent:n(e=>{this._emit(e)},"emitEvent")}}abortRetry(){this._retryCoordinator.abort()}async waitForRetry(){await this._retryCoordinator.waitForCompletion()}get isRetrying(){return this._retryCoordinator.isActive}get autoRetryEnabled(){return this.settingsManager.getRetryEnabled()}setAutoRetryEnabled(e){this.settingsManager.setRetryEnabled(e)}async executeBash(e,t,s){return this._bashRunner.execute(e,t,s)}recordBashResult(e,t,s){this._bashRunner.recordResult(e,t,s)}abortBash(){this._bashRunner.abort()}get isBashRunning(){return this._bashRunner.isRunning}get hasPendingBashMessages(){return this._bashRunner.hasPending}async switchSession(e){return this._lifecycleController.switchSession(e)}setSessionName(e){this.sessionManager.appendSessionInfo(e)}async fork(e){return this._lifecycleController.fork(e)}async navigateTree(e,t={}){return this._sessionTreeController.navigateTree(e,t)}getUserMessagesForForking(){const e=this.sessionManager.getEntries(),t=[];for(const s of e){if(s.type!=="message"||s.message.role!=="user")continue;const o=this._extractUserMessageText(s.message.content);o&&t.push({entryId:s.id,text:o})}return t}_extractUserMessageText(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(t=>t.type==="text").map(t=>t.text).join(""):""}getSessionStats(){const e=this.state,t=e.messages.filter(h=>h.role==="user").length,s=e.messages.filter(h=>h.role==="assistant").length,o=e.messages.filter(h=>h.role==="toolResult").length;let r=0,i=0,c=0,g=0,l=0,m=0;for(const h of e.messages)if(h.role==="assistant"){const d=h;r+=d.content.filter(u=>u.type==="toolCall").length,i+=d.usage.input,c+=d.usage.output,g+=d.usage.cacheRead,l+=d.usage.cacheWrite,m+=d.usage.cost.total}return{sessionFile:this.sessionFile,sessionId:this.sessionId,userMessages:t,assistantMessages:s,toolCalls:r,toolResults:o,totalMessages:e.messages.length,tokens:{input:i,output:c,cacheRead:g,cacheWrite:l,total:i+c+g+l},cost:m}}getContextUsage(){const e=this.model;if(!e)return;const t=e.contextWindow??0;if(t<=0)return;const s=this.sessionManager.getBranch(),o=y(s);if(o){const c=s.lastIndexOf(o);let g=!1;for(let l=s.length-1;l>c;l--){const m=s[l];if(m.type==="message"&&m.message.role==="assistant"){const h=m.message;if(h.stopReason!=="aborted"&&h.stopReason!=="error"){b(h.usage)>0&&(g=!0);break}}}if(!g)return{tokens:null,contextWindow:t,percent:null}}const r=U(this.messages),i=r.tokens/t*100;return{tokens:r.tokens,contextWindow:t,percent:i}}async exportToHtml(e){return await Z({sessionManager:this.sessionManager,state:this.state,outputPath:e,themeName:this.settingsManager.getTheme(),extensionRunner:this._extensionRunner,theme:this._theme})}getLastAssistantText(){return ee(this.messages)}hasExtensionHandlers(e){return this._extensionRunner?.hasHandlers(e)??!1}get extensionRunner(){return this._extensionRunner}}export{Qe as AgentSession,ze as CycleModelError,qe as parseSkillBlock,R as pruneRecoverableErrorTail};
14
+ ${o}`:m}catch(i){return this._extensionRunner?.emitError({extensionPath:r.filePath,event:"skill_expansion",error:i instanceof Error?i.message:String(i)}),e}}async steer(e,t){e.startsWith("/")&&this._throwIfExtensionCommand(e);let s=this._expandSkillCommand(e);s=y(s,[...this.promptTemplates]),await this._queueSteer(s,t)}async followUp(e,t){e.startsWith("/")&&this._throwIfExtensionCommand(e);let s=this._expandSkillCommand(e);s=y(s,[...this.promptTemplates]),await this._queueFollowUp(s,t)}async _queueSteer(e,t){this._steeringMessages.push(e);const s=[{type:"text",text:e}];t&&s.push(...t),this.agent.steer({role:"user",content:s,timestamp:Date.now()})}async _queueFollowUp(e,t){this._followUpMessages.push(e);const s=[{type:"text",text:e}];t&&s.push(...t),this.agent.followUp({role:"user",content:s,timestamp:Date.now()})}_throwIfExtensionCommand(e){if(!this._extensionRunner)return;const t=e.indexOf(" "),s=t===-1?e.slice(1):e.slice(1,t);if(this._extensionRunner.getCommand(s))throw new Error(`Extension command "/${s}" cannot be queued. Use prompt() or execute the command when not streaming.`)}async sendCustomMessage(e,t){const s={role:"custom",customType:e.customType,content:e.content,display:e.display,details:e.details,timestamp:Date.now()};t?.deliverAs==="nextTurn"?this._pendingNextTurnMessages.push(s):this.isStreaming?t?.deliverAs==="followUp"?this.agent.followUp(s):this.agent.steer(s):t?.triggerTurn?await this.agent.prompt(s):(this.agent.appendMessage(s),this.sessionManager.appendCustomMessageEntry(e.customType,e.content,e.display,e.details),this._emit({type:"message_start",message:s}),this._emit({type:"message_end",message:s}))}async sendUserMessage(e,t){let s,o;if(typeof e=="string")s=e;else{const r=[];o=[];for(const i of e)i.type==="text"?r.push(i.text):i.type==="image"&&o.push(i);s=r.join(`
15
+ `),o.length===0&&(o=void 0)}await this.prompt(s,{expandPromptTemplates:!1,streamingBehavior:t?.deliverAs,images:o,source:"extension"})}clearQueue(){const e=[...this._steeringMessages],t=[...this._followUpMessages];return this._steeringMessages=[],this._followUpMessages=[],this.agent.clearAllQueues(),{steering:e,followUp:t}}get pendingMessageCount(){return this._steeringMessages.length+this._followUpMessages.length}getSteeringMessages(){return this._steeringMessages}getFollowUpMessages(){return this._followUpMessages}get resourceLoader(){return this._resourceLoader}async abort(){this.abortRetry(),this.agent.abort(),await this.agent.waitForIdle(),this._extensionRunner?.emit({type:"agent_abort"})}async newSession(e){return this._lifecycleController.newSession(e)}async setModel(e){await this._modelController.setModel(e),this._emitDebug("basic","model","model_change",{provider:e.api,modelId:e.id})}async cycleModel(e="forward"){const t=await this._modelController.cycleModel(e);return t&&this._emitDebug("basic","model","model_cycle",{direction:e,provider:t.model.api,modelId:t.model.id}),t}setThinkingLevel(e){this._modelController.setThinkingLevel(e)}setAgentLoopFramework(e){this._modelController.setAgentLoopFramework(e)}setLoopPolicy(e){this._modelController.setLoopPolicy(e)}cycleThinkingLevel(){return this._modelController.cycleThinkingLevel()}getAvailableThinkingLevels(){return this._modelController.getAvailableThinkingLevels()}supportsXhighThinking(){return this._modelController.supportsXhighThinking()}supportsThinking(){return this._modelController.supportsThinking()}setSteeringMode(e){this.agent.setSteeringMode(e),this.settingsManager.setSteeringMode(e)}setFollowUpMode(e){this.agent.setFollowUpMode(e),this.settingsManager.setFollowUpMode(e)}async compact(e){return this._compactionController.compact(e)}abortCompaction(){this._compactionController.abort()}abortBranchSummary(){this._sessionTreeController.abortBranchSummary()}async _checkCompaction(e,t=!0){const s=this.settingsManager.getCompactionSettings();if(!s.enabled||t&&e.stopReason==="aborted")return;const o=this.model?.contextWindow??0,r=this.model&&e.provider===this.model.provider&&e.model===this.model.id,i=x(this.sessionManager.getBranch()),l=i!==null&&e.timestamp<new Date(i.timestamp).getTime();if(r&&!l&&b(e,o)){const g=this.agent.state.messages;g.length>0&&g[g.length-1].role==="assistant"&&this.agent.replaceMessages(g.slice(0,-1)),await this._runAutoCompaction("overflow",!0);return}if(e.stopReason==="error")return;const m=w(e.usage);D(m,o,s)&&await this._runAutoCompaction("threshold",!1)}async _recoverModelErrorInLoop(e){const t=this.settingsManager.getCompactionSettings();if(e.message.role!=="assistant")return{action:"stop"};const s=e.message;if(e.errorSubtype!=="context_overflow"){if(!this._retryCoordinator.isRetryableError(s))return{action:"stop"};if(!await this._retryCoordinator.handleErrorInLoop(s))return{action:"stop"};const h=A(this.agent.state.messages,s);return this.agent.replaceMessages(h),{action:"retry",messages:h,transition:{reason:"model_error_recovery",subtype:e.errorSubtype,attempt:e.attempt}}}if(!t.enabled)return{action:"stop"};const o=this.model?.contextWindow??0;if(!(this.model&&s.provider===this.model.provider&&s.model===this.model.id)||!b(s,o))return{action:"stop"};const i=x(this.sessionManager.getBranch());if(i!==null&&s.timestamp<new Date(i.timestamp).getTime())return{action:"stop"};const m=this.agent.state.messages;this.agent.replaceMessages(A(m,s));const g=await this._runAutoCompaction("overflow",!0,{triggerContinue:!1});return g?{action:"retry",messages:g,transition:{reason:"model_error_recovery",subtype:e.errorSubtype,attempt:e.attempt}}:{action:"stop"}}async _runAutoCompaction(e,t,s){const o=s?.triggerContinue??!0,r=await this._compactionController.runAuto(e,t);if(r!==void 0){if(t&&o){const i=this.agent.state.messages,l=i[i.length-1];l?.role==="assistant"&&l.stopReason==="error"&&this.agent.replaceMessages(i.slice(0,-1)),setTimeout(()=>{this.agent.continue().catch(()=>{})},100)}else!t&&this.agent.hasQueuedMessages()&&setTimeout(()=>{this.agent.continue().catch(()=>{})},100);return r}}setAutoCompactionEnabled(e){this._compactionController.setAutoCompactionEnabled(e)}get autoCompactionEnabled(){return this._compactionController.autoCompactionEnabled}async bindExtensions(e){e.uiContext!==void 0&&(this._extensionUIContext=e.uiContext),e.commandContextActions!==void 0&&(this._extensionCommandContextActions=e.commandContextActions),e.shutdownHandler!==void 0&&(this._extensionShutdownHandler=e.shutdownHandler),e.onError!==void 0&&(this._extensionErrorListener=e.onError),this._extensionRunner&&(this._applyExtensionBindings(this._extensionRunner),await this._extensionRunner.emit({type:"session_start"}),await this.extendResourcesFromExtensions("startup")),this._emitDebug("basic","extension","extensions_bound")}async extendResourcesFromExtensions(e){if(!this._extensionRunner?.hasHandlers("resources_discover"))return;const{skillPaths:t,promptPaths:s,themePaths:o}=await this._extensionRunner.emitResourcesDiscover(this._cwd,e);if(t.length===0&&s.length===0&&o.length===0)return;const r={skillPaths:this.buildExtensionResourcePaths(t),promptPaths:this.buildExtensionResourcePaths(s),themePaths:this.buildExtensionResourcePaths(o)};this._resourceLoader.extendResources(r),this._baseSystemPrompt=this._rebuildSystemPrompt(this.getActiveToolNames()),this.agent.setSystemPrompt(this._baseSystemPrompt)}buildExtensionResourcePaths(e){return e.map(t=>{const s=this.getExtensionSourceLabel(t.extensionPath),o=t.extensionPath.startsWith("<")?void 0:I(t.extensionPath);return{path:t.path,metadata:{source:s,scope:"temporary",origin:"top-level",baseDir:o}}})}getExtensionSourceLabel(e){return e.startsWith("<")?`extension:${e.replace(/[<>]/g,"")}`:`extension:${P(e).replace(/\.(ts|js)$/,"")}`}_applyExtensionBindings(e){e.setUIContext(this._extensionUIContext),e.bindCommandContext(this._extensionCommandContextActions),this._extensionErrorUnsubscriber?.(),this._extensionErrorUnsubscriber=this._extensionErrorListener?e.onError(this._extensionErrorListener):void 0}_bindExtensionCore(e){const t=this;ne(e,{promptTemplates:this.promptTemplates,resourceLoader:this._resourceLoader,modelRegistry:this.modelRegistry,sessionManager:this.sessionManager,settingsManager:this.settingsManager,shutdownHandler:this._extensionShutdownHandler,soulManager:this._soulManager,get model(){return t.model},get thinkingLevel(){return t.thinkingLevel},get isStreaming(){return t.isStreaming},get pendingMessageCount(){return t.pendingMessageCount},get systemPrompt(){return t.systemPrompt},sendCustomMessage:n((s,o)=>this.sendCustomMessage(s,o),"sendCustomMessage"),sendUserMessage:n((s,o)=>this.sendUserMessage(s,o),"sendUserMessage"),executeSlashCommand:n(s=>this.executeSlashCommand(s),"executeSlashCommand"),getActiveToolNames:n(()=>this.getActiveToolNames(),"getActiveToolNames"),getAllTools:n(()=>this.getAllTools(),"getAllTools"),setActiveToolsByName:n(s=>this.setActiveToolsByName(s),"setActiveToolsByName"),setModel:n(s=>this.setModel(s),"setModel"),setThinkingLevel:n(s=>this.setThinkingLevel(s),"setThinkingLevel"),abort:n(()=>this.abort(),"abort"),clearFollowUpQueue:n(()=>{this.agent.clearFollowUpQueue(),this._followUpMessages=[]},"clearFollowUpQueue"),getContextUsage:n(()=>this.getContextUsage(),"getContextUsage"),compact:n(s=>this.compact(s),"compact")})}_buildRuntime(e){const t=this._baseToolsOverride?this._baseToolsOverride:K(this._cwd,this.settingsManager);this._baseToolRegistry=new Map(Object.entries(t).map(([c,h])=>[c,h]));const s=this._resourceLoader.getExtensions();if(e.flagValues)for(const[c,h]of e.flagValues)s.runtime.flagValues.set(c,h);const o=s.extensions.length>0,r=this._customTools.length>0;this._extensionRunner=o||r?new W(s.extensions,s.runtime,this._cwd,this._agentDir,this.sessionManager,this._modelRegistry):void 0,this._extensionRunnerRef&&(this._extensionRunnerRef.current=this._extensionRunner),this._extensionRunner&&(this._bindExtensionCore(this._extensionRunner),this._applyExtensionBindings(this._extensionRunner),this._extensionRunner.setTelemetrySink(j({workspaceRoot:this._cwd})));const i=this._toolRuntimeController.build({baseTools:this._baseToolRegistry,baseToolsOverride:this._baseToolsOverride,customTools:this._customTools,activeToolNames:e.activeToolNames,includeAllExtensionTools:e.includeAllExtensionTools,extensionRunner:this._extensionRunner}),l=n(c=>{const h=ue(c);h&&this._emit(h)},"onSubAgentEvent");this._agentTool=ae({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory,onSubAgentEvent:l}),i.activeTools.push(this._agentTool),this._toolOrchestrator.registerTool(M,this._agentTool);const m=le({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory,onSubAgentEvent:l});i.activeTools.push(m),this._toolOrchestrator.registerTool(ge,m);const g=he({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory});i.activeTools.push(g),this._toolOrchestrator.registerTool(T,g),i.systemPromptToolNames.includes(M)||i.systemPromptToolNames.push(M),i.systemPromptToolNames.includes(T)||i.systemPromptToolNames.push(T),this.agent.setTools(i.activeTools),this._baseSystemPrompt=this._rebuildSystemPrompt(i.systemPromptToolNames),this.agent.setSystemPrompt(this._baseSystemPrompt)}async _refreshMcpTools(){if(!this._mcpToolsFactory)return 0;try{const e=await this._mcpToolsFactory();return this._customTools=[...this._staticCustomTools,...e],e.length}catch(e){this._emit({type:"sdk:error",source:"mcp",error:e});const t=this._customTools.filter(s=>s.name.startsWith("mcp_"));return this._customTools=[...this._staticCustomTools,...t],t.length}}async warmupMcpTools(){if(this._mcpToolsFactory)try{const e=await this._refreshMcpTools();this._buildRuntime({activeToolNames:this.getActiveToolNames(),flagValues:this._extensionRunner?.getFlagValues(),includeAllExtensionTools:!0}),this._emit({type:"sdk:mcp_ready",toolCount:e}),this._emitDebug("basic","mcp","mcp_warmup_complete",{toolCount:e})}catch(e){this._emit({type:"sdk:error",source:"mcp",error:e})}}async reload(){this._emitDebug("basic","resource","reload_start");const e=this._extensionRunner?.getFlagValues();if(await this._extensionRunner?.emit({type:"session_shutdown"}),this.settingsManager.reload(),F(),await this._resourceLoader.reload(),await this._refreshMcpTools(),this._soulManagerFactory)try{this._soulManager=await this._soulManagerFactory(),this._lastSoulInjection=void 0}catch(s){this._emit({type:"sdk:error",source:"soul",error:s})}this._buildRuntime({activeToolNames:this.getActiveToolNames(),flagValues:e,includeAllExtensionTools:!0});const t=this._extensionUIContext||this._extensionCommandContextActions||this._extensionShutdownHandler||this._extensionErrorListener;this._extensionRunner&&t&&(await this._extensionRunner.emit({type:"session_start"}),await this.extendResourcesFromExtensions("reload")),this._emitDebug("basic","resource","reload_end")}_createRetryHost(){return{getContextWindow:n(()=>this.model?.contextWindow??0,"getContextWindow"),getRetrySettings:n(()=>this.settingsManager.getRetrySettings(),"getRetrySettings"),removeLastAssistantMessage:n(()=>{const e=this.agent.state.messages;e.length>0&&e[e.length-1].role==="assistant"&&this.agent.replaceMessages(e.slice(0,-1))},"removeLastAssistantMessage"),triggerContinue:n(()=>{setTimeout(()=>{this.agent.continue().catch(()=>{})},0)},"triggerContinue"),emitEvent:n(e=>{this._emit(e)},"emitEvent")}}abortRetry(){this._retryCoordinator.abort()}async waitForRetry(){await this._retryCoordinator.waitForCompletion()}get isRetrying(){return this._retryCoordinator.isActive}get autoRetryEnabled(){return this.settingsManager.getRetryEnabled()}setAutoRetryEnabled(e){this.settingsManager.setRetryEnabled(e)}async executeBash(e,t,s){return this._bashRunner.execute(e,t,s)}recordBashResult(e,t,s){this._bashRunner.recordResult(e,t,s)}abortBash(){this._bashRunner.abort()}get isBashRunning(){return this._bashRunner.isRunning}get hasPendingBashMessages(){return this._bashRunner.hasPending}async switchSession(e){return this._lifecycleController.switchSession(e)}setSessionName(e){this.sessionManager.appendSessionInfo(e)}async fork(e){return this._lifecycleController.fork(e)}async navigateTree(e,t={}){return this._sessionTreeController.navigateTree(e,t)}getUserMessagesForForking(){const e=this.sessionManager.getEntries(),t=[];for(const s of e){if(s.type!=="message"||s.message.role!=="user")continue;const o=this._extractUserMessageText(s.message.content);o&&t.push({entryId:s.id,text:o})}return t}_extractUserMessageText(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(t=>t.type==="text").map(t=>t.text).join(""):""}getSessionStats(){const e=this.state,t=e.messages.filter(h=>h.role==="user").length,s=e.messages.filter(h=>h.role==="assistant").length,o=e.messages.filter(h=>h.role==="toolResult").length;let r=0,i=0,l=0,m=0,g=0,c=0;for(const h of e.messages)if(h.role==="assistant"){const d=h;r+=d.content.filter(_=>_.type==="toolCall").length,i+=d.usage.input,l+=d.usage.output,m+=d.usage.cacheRead,g+=d.usage.cacheWrite,c+=d.usage.cost.total}return{sessionFile:this.sessionFile,sessionId:this.sessionId,userMessages:t,assistantMessages:s,toolCalls:r,toolResults:o,totalMessages:e.messages.length,tokens:{input:i,output:l,cacheRead:m,cacheWrite:g,total:i+l+m+g},cost:c}}getContextUsage(){const e=this.model;if(!e)return;const t=e.contextWindow??0;if(t<=0)return;const s=this.sessionManager.getBranch(),o=x(s);if(o){const l=s.lastIndexOf(o);let m=!1;for(let g=s.length-1;g>l;g--){const c=s[g];if(c.type==="message"&&c.message.role==="assistant"){const h=c.message;if(h.stopReason!=="aborted"&&h.stopReason!=="error"){w(h.usage)>0&&(m=!0);break}}}if(!m)return{tokens:null,contextWindow:t,percent:null}}const r=B(this.messages),i=r.tokens/t*100;return{tokens:r.tokens,contextWindow:t,percent:i}}async exportToHtml(e){return await ee({sessionManager:this.sessionManager,state:this.state,outputPath:e,themeName:this.settingsManager.getTheme(),extensionRunner:this._extensionRunner,theme:this._theme})}getLastAssistantText(){return te(this.messages)}hasExtensionHandlers(e){return this._extensionRunner?.hasHandlers(e)??!1}get extensionRunner(){return this._extensionRunner}}export{Ge as AgentSession,Je as CycleModelError,Qe as parseSkillBlock,A as pruneRecoverableErrorTail};
@@ -84,6 +84,14 @@ export interface CreateAgentSessionOptions extends SoulOptionsContract {
84
84
  deferMcpInit?: boolean;
85
85
  /** Resource loader. When omitted, DefaultResourceLoader is used. */
86
86
  resourceLoader?: ResourceLoader;
87
+ /** Additional directories to search for skills. Appended to default paths. */
88
+ additionalSkillPaths?: string[];
89
+ /** Additional directories to search for AGENT.md/CLAUDE.md context files. */
90
+ additionalAgentDirs?: string[];
91
+ /** Custom MCP config file path. Overrides default agentDir/mcp.json. */
92
+ mcpConfigPath?: string;
93
+ /** Debug event verbosity level. "off" = none, "basic" = lifecycle, "verbose" = all. Default: "off" */
94
+ debugLevel?: "off" | "basic" | "verbose";
87
95
  /** Session manager. Default: SessionManager.create(cwd) */
88
96
  sessionManager?: SessionManager;
89
97
  /** Settings manager. Default: SettingsManager.create(cwd, agentDir) */
@@ -1 +1 @@
1
- var Q=Object.defineProperty;var n=(e,s)=>Q(e,"name",{value:s,configurable:!0});import{join as E}from"node:path";import{Agent as X}from"@pencil-agent/agent-core";import{getAgentDir as Y,getDocsPath as Z}from"../../config.js";import{AgentSession as ee}from"./agent-session.js";import{AuthStorage as te}from"../platform/config/auth-storage.js";import{DEFAULT_THINKING_LEVEL as B}from"../platform/config/defaults.js";import{convertToLlm as oe}from"../messages.js";import{MCPManager as re}from"../mcp/mcp-manager.js";import{registerFigmaMcpOAuthProvider as ne}from"../mcp/figma-auth.js";import{ModelRegistry as le}from"../model-registry.js";import{findInitialModel as ae}from"../model-resolver.js";import{DefaultResourceLoader as ie}from"../platform/config/resource-loader.js";import{SessionManager as se}from"../session/session-manager.js";import{SettingsManager as F}from"../platform/config/settings-manager.js";import{defaultAgentDirContext as ce}from"../agent-dir/agent-dir-context.js";import{time as y}from"../platform/timings.js";import{isSoulEnabled as de,createSoulManager as z}from"../soul-integration.js";import{allTools as O,bashTool as ge,codingTools as me,createBashTool as ue,createCodingTools as fe,createEditTool as pe,createFindTool as he,createGrepTool as Te,createLsTool as ye,createReadOnlyTools as ve,createReadTool as xe,createWriteTool as Me,editTool as Se,findTool as we,grepTool as ke,lsTool as Pe,readOnlyTools as Ce,readTool as Ae,writeTool as Le}from"../tools/index.js";const be={error:n(()=>{},"error"),warn:n(()=>{},"warn"),info:n(()=>{},"info")},Re={error:n((e,...s)=>console.error(e,...s),"error"),warn:n((e,...s)=>console.warn(e,...s),"warn"),info:n((e,...s)=>console.log(e,...s),"info")};function $e(e,s,k){if(e instanceof F)return e;const a=F.create(s,k);if(!e||typeof e!="object"||typeof e.getSettings!="function")return a;const g=a;for(const c of Object.keys(e)){const p=e[c];typeof p=="function"&&(g[c]=p.bind(e))}return a}n($e,"normalizeSettingsManager");function Ye(){return Y()}n(Ye,"getDefaultAgentDir");async function Ie(e={}){ne();const s=typeof import.meta.url=="string"&&import.meta.url.includes("node_modules"),k=process.env.NODE_ENV==="production"||process.env.NODE_ENV!=="development"&&s,a=e.silent?be:e.logger??Re,g=e.cwd??process.cwd(),c=e.agentCtx??ce(),p=e.agentDir??c.path;let v=e.resourceLoader;const r=$e(e.settingsManager,g,c),N=r.getSettings().locale??"en",{setLocale:j}=await import("../platform/i18n/index.js");j(N);const _=e.authStorage??te.create(c),U=E(p,"models.json"),h=e.modelRegistry??new le(_,U),m=e.sessionManager??se.create(g,void 0,c);v||(v=new ie({cwd:g,agentDir:p,settingsManager:r,agentCtx:c}),await v.reload(),y("resourceLoader.reload"));const d=m.buildSessionContext(),w=d.messages.length>0,L=m.getBranch().some(t=>t.type==="thinking_level_change");let l=e.model,x;if(!l&&w&&d.model){const t=h.find(d.model.provider,d.model.modelId);t&&await h.getApiKey(t)&&(l=t),l||(x=`Could not restore model ${d.model.provider}/${d.model.modelId}`)}l||(l=(await ae({scopedModels:[],isContinuing:w,defaultProvider:r.getDefaultProvider(),defaultModelId:r.getDefaultModel(),defaultThinkingLevel:r.getDefaultThinkingLevel(),modelRegistry:h})).model,l?x&&(x+=`. Using ${l.provider}/${l.id}`):x=`No models available. Use /login or set an API key environment variable. See ${E(Z(),"providers.md")}. Then use /model to select a model.`);let u;e.thinkingLevel!==void 0?u=e.thinkingLevel:w?u=L?d.thinkingLevel:r.getDefaultThinkingLevel()??B:u=r.getDefaultThinkingLevel()??B,(!l||!l.reasoning)&&(u="off");const H=["read","bash","edit","write"],K=e.tools?e.tools.map(t=>t.name).filter(t=>t in O):H;let M;const V=n(t=>{const o=oe(t);return r.getBlockImages()?o.map(i=>{if(i.role==="user"||i.role==="toolResult"){const T=i.content;if(Array.isArray(T)&&T.some(C=>C.type==="image")){const C=T.map(S=>S.type==="image"?{type:"text",text:"Image reading is disabled."}:S).filter((S,A,D)=>!(S.type==="text"&&S.text==="Image reading is disabled."&&A>0&&D[A-1].type==="text"&&D[A-1].text==="Image reading is disabled."));return{...i,content:C}}}return i}):o},"convertToLlmWithBlockImages"),b={};M=new X({initialState:{systemPrompt:"",model:l,thinkingLevel:u,tools:[]},convertToLlm:V,sessionId:m.getSessionId(),transformContext:n(async t=>{const o=b.current;return o?o.emitContext(t):t},"transformContext"),steeringMode:r.getSteeringMode(),followUpMode:r.getFollowUpMode(),transport:r.getTransport(),agentLoopFramework:e.agentLoopFramework??r.getAgentLoopFramework(),thinkingBudgets:r.getThinkingBudgets(),maxRetryDelayMs:r.getRetrySettings().maxDelayMs,maxToolResultBatchSizeChars:e.maxToolResultBatchSizeChars??e.loopPolicy?.maxToolResultBatchSizeChars??r.getAgentLoopSettings().maxToolResultBatchSizeChars,maxToolConcurrency:e.maxToolConcurrency??e.loopPolicy?.maxToolConcurrency,maxTurnsPerPrompt:e.maxTurnsPerPrompt??e.loopPolicy?.maxTurnsPerPrompt,maxToolCallsPerPrompt:e.maxToolCallsPerPrompt??e.loopPolicy?.maxToolCallsPerPrompt,outputTokenBudget:e.outputTokenBudget??e.loopPolicy?.outputTokenBudget,maxOutputTokenRecoveryAttempts:e.maxOutputTokenRecoveryAttempts??e.loopPolicy?.maxOutputTokenRecoveryAttempts,maxModelErrorRecoveryAttempts:e.maxModelErrorRecoveryAttempts??e.loopPolicy?.maxModelErrorRecoveryAttempts,maxStopHookContinuations:e.maxStopHookContinuations??e.loopPolicy?.maxStopHookContinuations,getApiKey:n(async t=>{const o=t||M.state.model?.provider;if(!o)throw new Error("No model selected");const i=await h.getApiKeyForProvider(o);if(!i){const T=M.state.model;throw T&&h.isUsingOAuth(T)?new Error(`Authentication failed for "${o}". Credentials may have expired or network is unavailable. Run '/login ${o}' to re-authenticate.`):new Error(`No API key found for "${o}". Set an API key environment variable or run '/login ${o}'.`)}return i},"getApiKey")}),w?(M.replaceMessages(d.messages),L||m.appendThinkingLevelChange(u)):(l&&m.appendModelChange(l.provider,l.id),m.appendThinkingLevelChange(u)),y("agent.construct");let f;const W=[],G=e.customTools??[];let R;e.enableMCP&&(process.once("exit",()=>f?.dispose()),R=n(async()=>{try{f?.dispose()}catch{}f=new re,f.setWorkingDir(g),await f.initialize(),y("mcp.initialize");const t=f.getStatus();if(k){const o=t.startedServers,i=t.failedServers;o.length>0&&a.info(`MCP: ${o.length} server(s) ready (${o.join(", ")})`),i.length>0&&a.warn(`MCP: ${i.length} failed (${i.join(", ")})`)}else if(t.toolCount===0){const o=t.failedServers.length>0?` failed=${t.failedServers.join(",")}`:"";a.warn(`MCP enabled but no tools loaded (enabled=${t.enabledServers.length}, started=${t.startedServers.length}, tools=0).${o}`)}else a.info(`MCP tools loaded: ${t.toolCount}`),t.failedServers.length>0&&a.warn(`MCP: ${t.failedServers.length} server(s) failed to start (${t.failedServers.join(", ")}); tools from other servers are still available.`);return f.getTools()},"mcpToolsFactory"));let P,$;if(de(e)){try{const t=await z(c);t?(P=t,await t.initialize(),y("soul.initialize")):a.warn("Soul not available (nanosoul package not installed). Skipping...")}catch(t){a.warn(`Failed to initialize Soul: ${t}`)}$=n(async()=>{try{const t=await z(c);return t?(await t.initialize(),y("soul.initialize"),t):null}catch(t){return a.warn(`Failed to refresh Soul: ${t}`),null}},"soulManagerFactory")}const I=new ee({agent:M,sessionManager:m,settingsManager:r,cwd:g,agentDir:p,agentCtx:c,scopedModels:e.scopedModels,resourceLoader:v,customTools:G,initialMcpTools:W,mcpToolsFactory:R,modelRegistry:h,initialActiveToolNames:K,extensionRunnerRef:b,soulManager:P,soulManagerFactory:$,signal:e.signal,theme:e.theme,createSession:Ie});y("session.construct"),e.enableMCP&&!e.deferMcpInit&&await I.warmupMcpTools();const q=v.getExtensions();return{session:I,extensionsResult:q,modelFallbackMessage:x,soulManager:P}}n(Ie,"createAgentSession");export{O as allBuiltInTools,ge as bashTool,me as codingTools,Ie as createAgentSession,ue as createBashTool,fe as createCodingTools,pe as createEditTool,he as createFindTool,Te as createGrepTool,ye as createLsTool,ve as createReadOnlyTools,xe as createReadTool,Me as createWriteTool,Re as defaultLogger,Se as editTool,we as findTool,ke as grepTool,Pe as lsTool,Ce as readOnlyTools,Ae as readTool,be as silentLogger,Le as writeTool};
1
+ var Q=Object.defineProperty;var n=(e,s)=>Q(e,"name",{value:s,configurable:!0});import{join as E}from"node:path";import{Agent as X}from"@pencil-agent/agent-core";import{getAgentDir as Y,getDocsPath as Z}from"../../config.js";import{AgentSession as ee}from"./agent-session.js";import{AuthStorage as te}from"../platform/config/auth-storage.js";import{DEFAULT_THINKING_LEVEL as B}from"../platform/config/defaults.js";import{convertToLlm as oe}from"../messages.js";import{MCPManager as re}from"../mcp/mcp-manager.js";import{registerFigmaMcpOAuthProvider as ne}from"../mcp/figma-auth.js";import{ModelRegistry as le}from"../model-registry.js";import{findInitialModel as ae}from"../model-resolver.js";import{DefaultResourceLoader as ie}from"../platform/config/resource-loader.js";import{SessionManager as se}from"../session/session-manager.js";import{SettingsManager as F}from"../platform/config/settings-manager.js";import{defaultAgentDirContext as ce}from"../agent-dir/agent-dir-context.js";import{time as v}from"../platform/timings.js";import{isSoulEnabled as de,createSoulManager as z}from"../soul-integration.js";import{allTools as O,bashTool as ge,codingTools as me,createBashTool as ue,createCodingTools as fe,createEditTool as pe,createFindTool as he,createGrepTool as Te,createLsTool as ve,createReadOnlyTools as ye,createReadTool as xe,createWriteTool as Se,editTool as Me,findTool as Pe,grepTool as we,lsTool as ke,readOnlyTools as Ce,readTool as Ae,writeTool as Le}from"../tools/index.js";const be={error:n(()=>{},"error"),warn:n(()=>{},"warn"),info:n(()=>{},"info")},Re={error:n((e,...s)=>console.error(e,...s),"error"),warn:n((e,...s)=>console.warn(e,...s),"warn"),info:n((e,...s)=>console.log(e,...s),"info")};function $e(e,s,w){if(e instanceof F)return e;const a=F.create(s,w);if(!e||typeof e!="object"||typeof e.getSettings!="function")return a;const g=a;for(const c of Object.keys(e)){const p=e[c];typeof p=="function"&&(g[c]=p.bind(e))}return a}n($e,"normalizeSettingsManager");function Ye(){return Y()}n(Ye,"getDefaultAgentDir");async function De(e={}){ne();const s=typeof import.meta.url=="string"&&import.meta.url.includes("node_modules"),w=process.env.NODE_ENV==="production"||process.env.NODE_ENV!=="development"&&s,a=e.silent?be:e.logger??Re,g=e.cwd??process.cwd(),c=e.agentCtx??ce(),p=e.agentDir??c.path;let y=e.resourceLoader;const r=$e(e.settingsManager,g,c),N=r.getSettings().locale??"en",{setLocale:j}=await import("../platform/i18n/index.js");j(N);const _=e.authStorage??te.create(c),U=E(p,"models.json"),h=e.modelRegistry??new le(_,U),m=e.sessionManager??se.create(g,void 0,c);y||(y=new ie({cwd:g,agentDir:p,settingsManager:r,agentCtx:c,additionalSkillPaths:e.additionalSkillPaths,additionalAgentDirs:e.additionalAgentDirs}),await y.reload(),v("resourceLoader.reload"));const d=m.buildSessionContext(),P=d.messages.length>0,L=m.getBranch().some(t=>t.type==="thinking_level_change");let l=e.model,x;if(!l&&P&&d.model){const t=h.find(d.model.provider,d.model.modelId);t&&await h.getApiKey(t)&&(l=t),l||(x=`Could not restore model ${d.model.provider}/${d.model.modelId}`)}l||(l=(await ae({scopedModels:[],isContinuing:P,defaultProvider:r.getDefaultProvider(),defaultModelId:r.getDefaultModel(),defaultThinkingLevel:r.getDefaultThinkingLevel(),modelRegistry:h})).model,l?x&&(x+=`. Using ${l.provider}/${l.id}`):x=`No models available. Use /login or set an API key environment variable. See ${E(Z(),"providers.md")}. Then use /model to select a model.`);let u;e.thinkingLevel!==void 0?u=e.thinkingLevel:P?u=L?d.thinkingLevel:r.getDefaultThinkingLevel()??B:u=r.getDefaultThinkingLevel()??B,(!l||!l.reasoning)&&(u="off");const H=["read","bash","edit","write"],K=e.tools?e.tools.map(t=>t.name).filter(t=>t in O):H;let S;const V=n(t=>{const o=oe(t);return r.getBlockImages()?o.map(i=>{if(i.role==="user"||i.role==="toolResult"){const T=i.content;if(Array.isArray(T)&&T.some(C=>C.type==="image")){const C=T.map(M=>M.type==="image"?{type:"text",text:"Image reading is disabled."}:M).filter((M,A,I)=>!(M.type==="text"&&M.text==="Image reading is disabled."&&A>0&&I[A-1].type==="text"&&I[A-1].text==="Image reading is disabled."));return{...i,content:C}}}return i}):o},"convertToLlmWithBlockImages"),b={};S=new X({initialState:{systemPrompt:"",model:l,thinkingLevel:u,tools:[]},convertToLlm:V,sessionId:m.getSessionId(),transformContext:n(async t=>{const o=b.current;return o?o.emitContext(t):t},"transformContext"),steeringMode:r.getSteeringMode(),followUpMode:r.getFollowUpMode(),transport:r.getTransport(),agentLoopFramework:e.agentLoopFramework??r.getAgentLoopFramework(),thinkingBudgets:r.getThinkingBudgets(),maxRetryDelayMs:r.getRetrySettings().maxDelayMs,maxToolResultBatchSizeChars:e.maxToolResultBatchSizeChars??e.loopPolicy?.maxToolResultBatchSizeChars??r.getAgentLoopSettings().maxToolResultBatchSizeChars,maxToolConcurrency:e.maxToolConcurrency??e.loopPolicy?.maxToolConcurrency,maxTurnsPerPrompt:e.maxTurnsPerPrompt??e.loopPolicy?.maxTurnsPerPrompt,maxToolCallsPerPrompt:e.maxToolCallsPerPrompt??e.loopPolicy?.maxToolCallsPerPrompt,outputTokenBudget:e.outputTokenBudget??e.loopPolicy?.outputTokenBudget,maxOutputTokenRecoveryAttempts:e.maxOutputTokenRecoveryAttempts??e.loopPolicy?.maxOutputTokenRecoveryAttempts,maxModelErrorRecoveryAttempts:e.maxModelErrorRecoveryAttempts??e.loopPolicy?.maxModelErrorRecoveryAttempts,maxStopHookContinuations:e.maxStopHookContinuations??e.loopPolicy?.maxStopHookContinuations,getApiKey:n(async t=>{const o=t||S.state.model?.provider;if(!o)throw new Error("No model selected");const i=await h.getApiKeyForProvider(o);if(!i){const T=S.state.model;throw T&&h.isUsingOAuth(T)?new Error(`Authentication failed for "${o}". Credentials may have expired or network is unavailable. Run '/login ${o}' to re-authenticate.`):new Error(`No API key found for "${o}". Set an API key environment variable or run '/login ${o}'.`)}return i},"getApiKey")}),P?(S.replaceMessages(d.messages),L||m.appendThinkingLevelChange(u)):(l&&m.appendModelChange(l.provider,l.id),m.appendThinkingLevelChange(u)),v("agent.construct");let f;const W=[],G=e.customTools??[];let R;e.enableMCP&&(process.once("exit",()=>f?.dispose()),R=n(async()=>{try{f?.dispose()}catch{}f=new re({mcpConfigPath:e.mcpConfigPath}),f.setWorkingDir(g),await f.initialize(),v("mcp.initialize");const t=f.getStatus();if(w){const o=t.startedServers,i=t.failedServers;o.length>0&&a.info(`MCP: ${o.length} server(s) ready (${o.join(", ")})`),i.length>0&&a.warn(`MCP: ${i.length} failed (${i.join(", ")})`)}else if(t.toolCount===0){const o=t.failedServers.length>0?` failed=${t.failedServers.join(",")}`:"";a.warn(`MCP enabled but no tools loaded (enabled=${t.enabledServers.length}, started=${t.startedServers.length}, tools=0).${o}`)}else a.info(`MCP tools loaded: ${t.toolCount}`),t.failedServers.length>0&&a.warn(`MCP: ${t.failedServers.length} server(s) failed to start (${t.failedServers.join(", ")}); tools from other servers are still available.`);return f.getTools()},"mcpToolsFactory"));let k,$;if(de(e)){try{const t=await z(c);t?(k=t,await t.initialize(),v("soul.initialize")):a.warn("Soul not available (nanosoul package not installed). Skipping...")}catch(t){a.warn(`Failed to initialize Soul: ${t}`)}$=n(async()=>{try{const t=await z(c);return t?(await t.initialize(),v("soul.initialize"),t):null}catch(t){return a.warn(`Failed to refresh Soul: ${t}`),null}},"soulManagerFactory")}const D=new ee({agent:S,sessionManager:m,settingsManager:r,cwd:g,agentDir:p,agentCtx:c,scopedModels:e.scopedModels,resourceLoader:y,customTools:G,initialMcpTools:W,mcpToolsFactory:R,modelRegistry:h,initialActiveToolNames:K,extensionRunnerRef:b,soulManager:k,soulManagerFactory:$,signal:e.signal,theme:e.theme,createSession:De,debugLevel:e.debugLevel});v("session.construct"),e.enableMCP&&!e.deferMcpInit&&await D.warmupMcpTools();const q=y.getExtensions();return{session:D,extensionsResult:q,modelFallbackMessage:x,soulManager:k}}n(De,"createAgentSession");export{O as allBuiltInTools,ge as bashTool,me as codingTools,De as createAgentSession,ue as createBashTool,fe as createCodingTools,pe as createEditTool,he as createFindTool,Te as createGrepTool,ve as createLsTool,ye as createReadOnlyTools,xe as createReadTool,Se as createWriteTool,Re as defaultLogger,Me as editTool,Pe as findTool,we as grepTool,ke as lsTool,Ce as readOnlyTools,Ae as readTool,be as silentLogger,Le as writeTool};
@@ -1,115 +1,115 @@
1
- # extensions/builtin/
2
-
3
- > P2 | Parent: ../AGENT.md
4
-
5
- Member List
6
- diagnostics/index.ts: Diagnostics extension entry, subscribes to diagnostic:event, buffers session-local diagnostic records, prompts only after threshold at agent_end, registers /report-issue
7
- goal/index.ts: Goal extension entry, per-thread GoalController, /goal command and goal subcommand autocomplete, get_goal/create_goal/update_goal tools, turn/account lifecycle hooks, idle-continuation prompt dispatch, GOAL_MESSAGE_TYPE renderer, session_start/shutdown hooks, persistent per-thread status footer indicator
8
- goal/goal-types.ts: ThreadGoalStatus enum (active/paused/blocked/usage_limited/budget_limited/complete), ThreadGoal record, GoalSetMode, GoalAccountingMode, GoalTurnAccounting, GoalControllerState, validation constants
9
- goal/goal-store.ts: GoalStore JSON-file persistence layer; get/replace/insert/update/delete/account_usage primitives, atomic temp-file rename, status-filtered accounting modes, budget-limit auto-downgrade
10
- goal/goal-format.ts: formatGoalElapsedSeconds, formatTokens, goalStatusLabel, goalUsageSummary, goalSummaryLines, goalStatusIndicator, shouldConfirmBeforeReplacing, editedGoalStatus, validateObjective, validateBudget
11
- goal/goal-prompts.ts: buildContinuationPrompt, buildBudgetLimitPrompt, buildObjectiveUpdatedPrompt - three steering templates mirroring codex-rs prompts/templates/goals/*
12
- goal/goal-controller.ts: GoalController class, per-thread mutex, on_turn_start/on_token_usage/on_tool_finish/on_turn_end/on_turn_abort/on_turn_error/on_usage_limit hooks, idle continuation followUp injection, blocked-signal escalation counter, budget-limit steering emission
13
- goal/goal-tools.ts: get_goal/create_goal/update_goal LLM tool factories, TypeBox parameter schemas, host singleton for controller lookup, renderGoalResponse formatter
14
- goal/goal-parser.ts: parseGoalCommand, buildGoalHelp, getGoalArgumentCompletions for /goal subcommand autocomplete
15
- goal/goal-command.ts: runGoalCommand handler for /goal show/clear/edit/pause/resume/set with ConfirmIfExists dialog, multi-line summary renderer
16
- goal/README.md: Goal extension documentation - usage, LLM tools, lifecycle, persistence, status indicator, file-by-file architecture
17
- diagnostics/types.ts: Diagnostic event/report type contract and diagnostic:event channel name
18
- diagnostics/diagnostic-buffer.ts: DiagnosticBuffer, event coercion, fingerprint dedupe, prompt gating
19
- diagnostics/reporter.ts: User-approved InsForge pencil_issue_events reporter, configured via NANOPENCIL_ISSUE_* env vars
20
- diagnostics/redaction.ts: Diagnostic message normalization and secret/path redaction helpers
21
- browser/index.ts: Browser Harness extension entry, registers browser/browser_admin tools, /browser command, Browser Harness resource discovery, project-local browser workspace seeding; opt-in since P6/EV03 despite physical source staying under builtin pending Q2 physical/package decision
22
- browser/browser.md: Browser Harness day-to-day skill instructions for NanoPencil tool use and workspace contribution
23
- browser/install.md: Browser Harness setup and troubleshooting instructions, exposed as a skill resource
24
- browser/src/browser_harness/: Vendored Browser Harness Python package, CDP daemon, IPC bridge, admin commands, and helper functions
25
- browser/interaction-skills/: Reusable Browser Harness mechanics guides for browser interactions
26
- browser/agent-workspace/: Seed workspace copied to .nanopencil/browser-workspace for editable helpers and domain skills
27
- discipline/index.ts: Engineering discipline extension entry, registers skill tool, default workflow skills, and lightweight before_agent_start bootstrap prompt
28
- discipline/skills/: Built-in engineering workflow skills for brainstorming, debugging, TDD, verification, planning, code review, worktrees, and branch finishing
29
- idle-think/index.ts: IdleThink extension entry, session lifecycle registration, activity tracking, and persistent insight prompt injection
30
- idle-think/idle-think-runtime.ts: IdleThink runtime boundary - state, budget reset, interval ownership, abort cleanup, exploration orchestration, insight persistence, and diagnostic reporting
31
- idle-think/thinker.ts: IdleThink read-only SubAgent exploration runner, project context collection, network capability detection, and exploration prompt construction
32
- idle-think/insights.ts: IdleThink nanomem-backed project-scoped insight storage and system prompt injection
33
- idle-think/curiosity.ts: IdleThink curiosity queue persistence, topic selection, dedupe, and explored-topic pruning
34
- link-world/index.ts: Internet access integration entry, registers link_world_admin/link_world_exec/web_search/web_fetch tools, /link-world status/doctor/version/install commands, and bundled internet-search resources
35
- link-world/link-world-agent.md: Agent-facing skill that tells models to prefer web_search/web_fetch and link_world_admin/link_world_exec over bash for internet tasks
36
- link-world/network-routing.md: Routing skill that tells models when to use web_search/web_fetch/link-world versus browser automation
37
- link-world/agent-workspace/: Seed workspace copied to .nanopencil/link-world-workspace for project-local domain skills and notes
38
- mcp/index.ts: MCP protocol integration extension, MCP guidance resources
39
- presence/index.ts: AI-driven opening + idle presence lines, git/cwd snapshot, systemPrompt injection of recent presence lines, timers/debounce/idle in-flight lock, settings.presence.enabled guard, PRESENCE_MESSAGE_TYPE renderer
40
- presence/presence-memory.ts: Presence memory boundary - NanoMem directory/project discovery, memory-derived locale detection, randomized preference/lesson highlight selection for greeting prompts
41
- plan/index.ts: Plan Mode extension entry, /plan /plan:validate /plan:approve commands, EnterPlanMode/ExitPlanMode tools, permission gating, TUI status/widget, workflow prompt injection
42
- plan/types.ts: Plan mode types, persisted state payload, attachment variants, permission result model
43
- plan/plan-file-manager.ts: Plan file path management, slug generation, settings-aware plans directory, plan state hydration/serialization, resume/fork copy helpers
44
- plan/plan-permissions.ts: Plan mode tool permission gating, exact plan-file write checks, read-only bash allowlist, agent/tool blocking policy
45
- plan/plan-workflow-prompt.ts: Plan mode full/sparse workflow prompt, reentry prompt, exit prompt, EnterPlanMode/ExitPlanMode tool result text
46
- plan/enter-plan-mode-tool.ts: EnterPlanMode tool for model-initiated plan mode entry and UI state activation
47
- plan/exit-plan-mode-tool.ts: ExitPlanMode tool for user-approved plan mode exit, validation, teammate approval, UI cleanup
48
- plan/plan-agents.ts: Explore/Plan subagent prompt helpers and read-only tool list for plan mode
49
- plan/plan-validation.ts: Plan structure validation for Context, Approach, Files/Changes, and Verification sections
50
- plan/teammate-approval.ts: Teammate plan approval mailbox integration and approval/waiting message formatting
51
- subagent/index.ts: SubAgent extension entry, /subagent:/subagent:run/:stop/:status/:report/:apply commands, SUBAGENT_MESSAGE_TYPE renderer
52
- subagent/subagent-parser.ts: SubAgent command parsing, parseSubAgentCommand/buildSubAgentHelp
53
- subagent/subagent-runner.ts: SubAgent orchestration — research (read-only) and implement (isolated worktree) roles, diff preview and apply flow
54
- subagent/subagent-types.ts: SubAgent extension types — SubAgentPhase, SubAgentWorkerInfo, SubAgentRunState, SubAgentRunReport
55
- interview/index.ts: Requirement clarification extension entry, /interview and /grill-me commands, interview tool registration, custom message renderers, lightweight before_agent_start hook
56
- interview/interview-runtime.ts: Interview probe/runtime boundary - synchronous prompt heuristics, workspace context collection, LLM probe coercion, UI follow-up loop, refined intent injection text
57
- security-audit/interface.ts: Security audit interface, SecurityCheckResult/AuditEvent/SecurityEngine
58
- security-audit/index.ts: Security extension entry, audit logging and dangerous pattern detection
59
- security-audit/engine/interceptor.ts: Request/response interception, InterceptorResult confirmation flow
60
- security-audit/engine/logger.ts: Security event logging, JSON file audit trail
61
- security-audit/engine/detector.ts: Vulnerability detection, pattern matching for dangerous commands
62
- soul/index.ts: AI personality evolution extension, persistent personality across sessions
63
- grub/index.ts: Grub extension entry - autonomous iterative task runner, /grub command, dual-phase prompt injection, feature-list guard dispatch, GRUB_MESSAGE_TYPE renderer
64
- grub/grub-controller.ts: GrubController - drives autonomous grub iterations, durable GrubTaskState, initializer baseline capture, feature-list mutation validation
65
- grub/grub-decision.ts: Grub assistant protocol parser, extracts validated loop-state decisions from assistant text
66
- grub/grub-parser.ts: Grub command parsing, parseGrubCommand/buildGrubHelp
67
- grub/grub-prompts.ts: Grub prompt construction boundary, initializer/coding system prompts and per-task dispatch prompts
68
- grub/grub-harness.ts: Grub harness artifact boundary, .grub/<id>/ feature-list/progress-log/init.sh creation
69
- grub/grub-format.ts: Grub user-facing status/result formatter for readable TUI messages
70
- grub/grub-turn.ts: Grub turn-end coordinator, parsing assistant output, checklist gates, retry/terminal update events
71
- grub/grub-i18n.ts: Grub localization helper, English/Chinese prompts and TUI strings
72
- grub/grub-feature-list.ts: feature-list.json IO, initializer skeleton, legacy checklist migration, passes/evidence-only diff validation
73
- grub/grub-persistence.ts: Cross-session .grub/<id>/state.json persistence, active task discovery, stale harness pruning
74
- grub/grub-types.ts: Grub types, GrubStatus/GrubDecisionStatus/GrubDecision/GrubTaskState/GrubTaskSnapshot/FeatureList/PersistedGrubState
75
- grub/README.md: Grub extension documentation - autonomous "keep digging until done" runner without default git commits
76
- loop/index.ts: Loop extension entry - session-scoped recurring prompt/command scheduler with pause/resume/run-now/max-runs/quiet, /loop command + LOOP_MESSAGE_TYPE renderer
77
- loop/scheduler-controller.ts: SchedulerController - in-memory recurring task store with pause/resume/run-now/max-runs, MAX_SCHEDULED_TASKS=50
78
- loop/scheduler-parser.ts: Loop command parsing with flags/subcommands, parseSchedulerCommand/parseDurationSpec/buildSchedulerHelp, --name/--max/--quiet
79
- loop/scheduler-types.ts: Scheduled loop types, LoopPayloadKind/ScheduledLoopTask/LoopStartSpec/ParsedSchedulerCommand
80
- loop/README.md: Loop extension documentation - recurring scheduler usage and flags
81
- sal/index.ts: SAL extension entry, enabled by default, registers flags, /sal:* commands, lifecycle hooks including agent_result, terrain snapshot refresh, eval event emission, and stale-run cleanup scheduling; delegates config, context, runtime contracts, and tool_trace analytics to focused SAL modules
82
- sal/sal-config.ts: SAL build metadata, eval environment constants, credential loading, truthy parsing, stale-cleanup/A-B flag resolution, experiment id normalization, and sidecar directory resolution
83
- sal/sal-context.ts: SAL anchor system-prompt injection formatting plus A/B sidecar turn-record persistence
84
- sal/sal-runtime.ts: SAL shared BuildMeta/TurnState/SalRuntime contracts used across config, context, trace, and entry modules, including per-turn loop outcome state
85
- sal/sal-trace.ts: SAL tool path extraction, task intent inference, and bounded tool_trace payload construction with loop outcome summary
86
- sal/terrain.ts: TerrainSnapshot/TerrainNode/TerrainEdge model, buildTerrainIndex(), checkDipCoverage(), isSnapshotStale(), moduleIdForPath(), parses P2 AGENT.md and P3 file headers
87
- sal/anchors.ts: StructuralAnchor/AnchorResolution model, locateTask(), locateAction(), evidence-driven scoring with tunable SalWeights, CJK bigram tokenization
88
- sal/weights.ts: SalWeights interface, SAL_DEFAULT_WEIGHTS, loadSalWeights() reads sal-config.json from workspace or .memory-experiments/sal/
89
- sal/eval/index.ts: createEvalSink() factory + barrel re-exports; adapter selection via options.adapter or endpoint scheme inference (http(s)→insforge, file://|/|./|../→jsonl, missing→noop); ONLY entry point SAL imports from
90
- sal/eval/types.ts: EvalSink interface, EvalEventEnvelope/EvalEventType (run_start/run_end/turn_anchor), EvalAdapterId ("insforge"|"jsonl"|"noop"), CreateEvalSinkOptions with optional onDiagnostic callback, createEvalEvent factory; zero-dependency type surface
91
- sal/eval/noop-sink.ts: noopSink — silent EvalSink used when eval disabled or no adapter configured
92
- sal/eval/insforge-sink.ts: InsForgeEvalSink — PostgREST adapter, routes run_start→eval_runs INSERT (merge-duplicates) with legacy-schema fallback, writes turn_anchor/tool_trace/memory_recalls/run_end only after parent run confirmation, tool_trace→eval_tool_traces with PGRST204 fallback, memory_recalls→eval_memory_recalls batch INSERT, run_end→eval_runs PATCH; allowSelfSigned TLS option logs only in development runtime, batching with default 2000ms interval
93
- sal/eval/jsonl-sink.ts: JsonlEvalSink — append-only filesystem adapter, one JSON object per line, accepts file:// URLs or plain paths, auto-creates parent dir, batched writes
94
- sal/README.md: SAL extension usage, sidecar output layout, weights override, pluggability contract
95
- team/index.ts: AgentTeam extension entry, /team <task>, /team:spawn/:preset/:send/:status/:progress/:psyche/:dashboard/:task/:mail/:allow-path/:stop/:terminate/:approve/:mode command registration and dispatch
96
- team/team-ui.ts: AgentTeam message renderer, list/status/task formatting, dashboard visibility/timer ownership, realtime observer, speaker-stream emission helpers
97
- team/team-types.ts: TeammateRole/TeammateMode/TeammateStatus/TeamTask/HarnessState/PsycheWeights/TeamUtterance/Handoff/LeaderPlan/AgentLiveView/TeammateIdentity/PersistedTeammate/TeamSpawnSpec/TeamSendResult types
98
- team/team-state-store.ts: TeamStateStore class - durable teammate persistence via JSON files in <agentDir>/teams/
99
- team/team-parser.ts: Team command parser - parseTeamCommand/buildTeamHelp for /team:* subcommands
100
- team/team-runtime.ts: TeamRuntime class - teammate registry, stable internal labels plus visible teammate names, per-teammate send queue, lifecycle, durable tasks, mailbox + permission + transcript wiring
101
- team/team-runtime-helpers.ts: TeamRuntime helper boundary - teammate prompt construction, harness turn preparation, live event projection, tool selection, path guards, label/role/text helpers
102
- team/team-orchestrator.ts: Leader orchestration helpers - plan building, speaker utterance creation, @mention parsing, and handoff execution
103
- team/team-task-store.ts: TeamTaskStore class - durable shared task list in <storageDir>/tasks.json
104
- team/team-harness.ts: Harness protocol helpers - context files, phase instructions, checkpoint/revert, feature validation
105
- team/team-presets.ts: Preset definitions and executor - solo/duo/squad spawning, model-assisted auto team selection, heuristic fallback
106
- team/team-dashboard.ts: Text dashboard/status rendering - teammate workbench cards, current task, last utterance, progress bars, footer summary
107
- team/team-psyche.ts: Psyche prompt layer - role/phase weighted Id/Ego/Superego prompt construction
108
- team/team-permissions.ts: PermissionStore - pending permission request queue, approve/deny, path allowlists
109
- team/team-mailbox.ts: TeamMailbox - typed JSONL-backed append-only message log for leader↔teammate and teammate↔teammate
110
- team/team-transcript.ts: TeamTranscriptWriter - per-teammate JSONL transcripts
111
- team/TESTING.md: Manual & smoke-test guide for Phase B AgentTeam
112
-
113
- Rule: Members complete, one item per line, parent links valid, precise terms first
114
-
115
- [COVENANT]: Update this file header on changes and verify against parent AGENT.md
1
+ # extensions/builtin/
2
+
3
+ > P2 | Parent: ../AGENT.md
4
+
5
+ Member List
6
+ diagnostics/index.ts: Diagnostics extension entry, subscribes to diagnostic:event, buffers session-local diagnostic records, prompts only after threshold at agent_end, registers /report-issue
7
+ goal/index.ts: Goal extension entry, per-thread GoalController, /goal command and goal subcommand autocomplete, get_goal/create_goal/update_goal tools, turn/account lifecycle hooks, idle-continuation prompt dispatch, GOAL_MESSAGE_TYPE renderer, session_start/shutdown hooks, persistent per-thread status footer indicator
8
+ goal/goal-types.ts: ThreadGoalStatus enum (active/paused/blocked/usage_limited/budget_limited/complete), ThreadGoal record, GoalSetMode, GoalAccountingMode, GoalTurnAccounting, GoalControllerState, validation constants
9
+ goal/goal-store.ts: GoalStore JSON-file persistence layer; get/replace/insert/update/delete/account_usage primitives, atomic temp-file rename, status-filtered accounting modes, budget-limit auto-downgrade
10
+ goal/goal-format.ts: formatGoalElapsedSeconds, formatTokens, goalStatusLabel, goalUsageSummary, goalSummaryLines, goalStatusIndicator, shouldConfirmBeforeReplacing, editedGoalStatus, validateObjective, validateBudget
11
+ goal/goal-prompts.ts: buildContinuationPrompt, buildBudgetLimitPrompt, buildObjectiveUpdatedPrompt - three steering templates mirroring codex-rs prompts/templates/goals/*
12
+ goal/goal-controller.ts: GoalController class, per-thread mutex, on_turn_start/on_token_usage/on_tool_finish/on_turn_end/on_turn_abort/on_turn_error/on_usage_limit hooks, idle continuation followUp injection, blocked-signal escalation counter, budget-limit steering emission
13
+ goal/goal-tools.ts: get_goal/create_goal/update_goal LLM tool factories, TypeBox parameter schemas, host singleton for controller lookup, renderGoalResponse formatter
14
+ goal/goal-parser.ts: parseGoalCommand, buildGoalHelp, getGoalArgumentCompletions for /goal subcommand autocomplete
15
+ goal/goal-command.ts: runGoalCommand handler for /goal show/clear/edit/pause/resume/set with ConfirmIfExists dialog, multi-line summary renderer
16
+ goal/README.md: Goal extension documentation - usage, LLM tools, lifecycle, persistence, status indicator, file-by-file architecture
17
+ diagnostics/types.ts: Diagnostic event/report type contract and diagnostic:event channel name
18
+ diagnostics/diagnostic-buffer.ts: DiagnosticBuffer, event coercion, fingerprint dedupe, prompt gating
19
+ diagnostics/reporter.ts: User-approved InsForge pencil_issue_events reporter, configured via NANOPENCIL_ISSUE_* env vars
20
+ diagnostics/redaction.ts: Diagnostic message normalization and secret/path redaction helpers
21
+ browser/index.ts: Browser Harness extension entry, registers browser/browser_admin tools, /browser command, Browser Harness resource discovery, project-local browser workspace seeding; opt-in since P6/EV03 despite physical source staying under builtin pending Q2 physical/package decision
22
+ browser/browser.md: Browser Harness day-to-day skill instructions for NanoPencil tool use and workspace contribution
23
+ browser/install.md: Browser Harness setup and troubleshooting instructions, exposed as a skill resource
24
+ browser/src/browser_harness/: Vendored Browser Harness Python package, CDP daemon, IPC bridge, admin commands, and helper functions
25
+ browser/interaction-skills/: Reusable Browser Harness mechanics guides for browser interactions
26
+ browser/agent-workspace/: Seed workspace copied to .nanopencil/browser-workspace for editable helpers and domain skills
27
+ discipline/index.ts: Engineering discipline extension entry, registers skill tool, default workflow skills, and lightweight before_agent_start bootstrap prompt
28
+ discipline/skills/: Built-in engineering workflow skills for brainstorming, debugging, TDD, verification, planning, code review, worktrees, and branch finishing
29
+ idle-think/index.ts: IdleThink extension entry, session lifecycle registration, activity tracking, and persistent insight prompt injection
30
+ idle-think/idle-think-runtime.ts: IdleThink runtime boundary - state, budget reset, interval ownership, abort cleanup, exploration orchestration, insight persistence, and diagnostic reporting
31
+ idle-think/thinker.ts: IdleThink read-only SubAgent exploration runner, project context collection, network capability detection, and exploration prompt construction
32
+ idle-think/insights.ts: IdleThink nanomem-backed project-scoped insight storage and system prompt injection
33
+ idle-think/curiosity.ts: IdleThink curiosity queue persistence, topic selection, dedupe, and explored-topic pruning
34
+ link-world/index.ts: Internet access integration entry, registers link_world_admin/link_world_exec/web_search/web_fetch tools, /link-world status/doctor/version/install commands, and bundled internet-search resources
35
+ link-world/link-world-agent.md: Agent-facing skill that tells models to prefer web_search/web_fetch and link_world_admin/link_world_exec over bash for internet tasks
36
+ link-world/network-routing.md: Routing skill that tells models when to use web_search/web_fetch/link-world versus browser automation
37
+ link-world/agent-workspace/: Seed workspace copied to .nanopencil/link-world-workspace for project-local domain skills and notes
38
+ mcp/index.ts: MCP protocol integration extension, MCP guidance resources
39
+ presence/index.ts: AI-driven opening + idle presence lines, git/cwd snapshot, systemPrompt injection of recent presence lines, timers/debounce/idle in-flight lock, settings.presence.enabled guard, PRESENCE_MESSAGE_TYPE renderer
40
+ presence/presence-memory.ts: Presence memory boundary - NanoMem directory/project discovery, memory-derived locale detection, randomized preference/lesson highlight selection for greeting prompts
41
+ plan/index.ts: Plan Mode extension entry, /plan /plan:validate /plan:approve commands, EnterPlanMode/ExitPlanMode tools, permission gating, TUI status/widget, workflow prompt injection
42
+ plan/types.ts: Plan mode types, persisted state payload, attachment variants, permission result model
43
+ plan/plan-file-manager.ts: Plan file path management, slug generation, settings-aware plans directory, plan state hydration/serialization, resume/fork copy helpers
44
+ plan/plan-permissions.ts: Plan mode tool permission gating, exact plan-file write checks, read-only bash allowlist, agent/tool blocking policy
45
+ plan/plan-workflow-prompt.ts: Plan mode full/sparse workflow prompt, reentry prompt, exit prompt, EnterPlanMode/ExitPlanMode tool result text
46
+ plan/enter-plan-mode-tool.ts: EnterPlanMode tool for model-initiated plan mode entry and UI state activation
47
+ plan/exit-plan-mode-tool.ts: ExitPlanMode tool for user-approved plan mode exit, validation, teammate approval, UI cleanup
48
+ plan/plan-agents.ts: Explore/Plan subagent prompt helpers and read-only tool list for plan mode
49
+ plan/plan-validation.ts: Plan structure validation for Context, Approach, Files/Changes, and Verification sections
50
+ plan/teammate-approval.ts: Teammate plan approval mailbox integration and approval/waiting message formatting
51
+ subagent/index.ts: SubAgent extension entry, /subagent:/subagent:run/:stop/:status/:report/:apply commands, SUBAGENT_MESSAGE_TYPE renderer
52
+ subagent/subagent-parser.ts: SubAgent command parsing, parseSubAgentCommand/buildSubAgentHelp
53
+ subagent/subagent-runner.ts: SubAgent orchestration — research (read-only) and implement (isolated worktree) roles, diff preview and apply flow
54
+ subagent/subagent-types.ts: SubAgent extension types — SubAgentPhase, SubAgentWorkerInfo, SubAgentRunState, SubAgentRunReport
55
+ interview/index.ts: Requirement clarification extension entry, /interview and /grill-me commands, interview tool registration, custom message renderers, lightweight before_agent_start hook
56
+ interview/interview-runtime.ts: Interview probe/runtime boundary - synchronous prompt heuristics, workspace context collection, LLM probe coercion, UI follow-up loop, refined intent injection text
57
+ security-audit/interface.ts: Security audit interface, SecurityCheckResult/AuditEvent/SecurityEngine
58
+ security-audit/index.ts: Security extension entry, audit logging and dangerous pattern detection
59
+ security-audit/engine/interceptor.ts: Request/response interception, InterceptorResult confirmation flow
60
+ security-audit/engine/logger.ts: Security event logging, JSON file audit trail
61
+ security-audit/engine/detector.ts: Vulnerability detection, pattern matching for dangerous commands
62
+ soul/index.ts: AI personality evolution extension, persistent personality across sessions
63
+ grub/index.ts: Grub extension entry - autonomous iterative task runner, /grub command, dual-phase prompt injection, feature-list guard dispatch, GRUB_MESSAGE_TYPE renderer
64
+ grub/grub-controller.ts: GrubController - drives autonomous grub iterations, durable GrubTaskState, initializer baseline capture, feature-list mutation validation
65
+ grub/grub-decision.ts: Grub assistant protocol parser, extracts validated loop-state decisions from assistant text
66
+ grub/grub-parser.ts: Grub command parsing, parseGrubCommand/buildGrubHelp
67
+ grub/grub-prompts.ts: Grub prompt construction boundary, initializer/coding system prompts and per-task dispatch prompts
68
+ grub/grub-harness.ts: Grub harness artifact boundary, .grub/<id>/ feature-list/progress-log/init.sh creation
69
+ grub/grub-format.ts: Grub user-facing status/result formatter for readable TUI messages
70
+ grub/grub-turn.ts: Grub turn-end coordinator, parsing assistant output, checklist gates, retry/terminal update events
71
+ grub/grub-i18n.ts: Grub localization helper, English/Chinese prompts and TUI strings
72
+ grub/grub-feature-list.ts: feature-list.json IO, initializer skeleton, legacy checklist migration, passes/evidence-only diff validation
73
+ grub/grub-persistence.ts: Cross-session .grub/<id>/state.json persistence, active task discovery, stale harness pruning
74
+ grub/grub-types.ts: Grub types, GrubStatus/GrubDecisionStatus/GrubDecision/GrubTaskState/GrubTaskSnapshot/FeatureList/PersistedGrubState
75
+ grub/README.md: Grub extension documentation - autonomous "keep digging until done" runner without default git commits
76
+ loop/index.ts: Loop extension entry - session-scoped recurring prompt/command scheduler with pause/resume/run-now/max-runs/quiet, /loop command + LOOP_MESSAGE_TYPE renderer
77
+ loop/scheduler-controller.ts: SchedulerController - in-memory recurring task store with pause/resume/run-now/max-runs, MAX_SCHEDULED_TASKS=50
78
+ loop/scheduler-parser.ts: Loop command parsing with flags/subcommands, parseSchedulerCommand/parseDurationSpec/buildSchedulerHelp, --name/--max/--quiet
79
+ loop/scheduler-types.ts: Scheduled loop types, LoopPayloadKind/ScheduledLoopTask/LoopStartSpec/ParsedSchedulerCommand
80
+ loop/README.md: Loop extension documentation - recurring scheduler usage and flags
81
+ sal/index.ts: SAL extension entry, enabled by default, registers flags, /sal:* commands, lifecycle hooks including agent_result, terrain snapshot refresh, eval event emission, and stale-run cleanup scheduling; delegates config, context, runtime contracts, and tool_trace analytics to focused SAL modules
82
+ sal/sal-config.ts: SAL build metadata, eval environment constants, credential loading, truthy parsing, stale-cleanup/A-B flag resolution, experiment id normalization, and sidecar directory resolution
83
+ sal/sal-context.ts: SAL anchor system-prompt injection formatting plus A/B sidecar turn-record persistence
84
+ sal/sal-runtime.ts: SAL shared BuildMeta/TurnState/SalRuntime contracts used across config, context, trace, and entry modules, including per-turn loop outcome state
85
+ sal/sal-trace.ts: SAL tool path extraction, task intent inference, and bounded tool_trace payload construction with loop outcome summary
86
+ sal/terrain.ts: TerrainSnapshot/TerrainNode/TerrainEdge model, buildTerrainIndex(), checkDipCoverage(), isSnapshotStale(), moduleIdForPath(), parses P2 AGENT.md and P3 file headers
87
+ sal/anchors.ts: StructuralAnchor/AnchorResolution model, locateTask(), locateAction(), evidence-driven scoring with tunable SalWeights, CJK bigram tokenization
88
+ sal/weights.ts: SalWeights interface, SAL_DEFAULT_WEIGHTS, loadSalWeights() reads sal-config.json from workspace or .memory-experiments/sal/
89
+ sal/eval/index.ts: createEvalSink() factory + barrel re-exports; adapter selection via options.adapter or endpoint scheme inference (http(s)→insforge, file://|/|./|../→jsonl, missing→noop); ONLY entry point SAL imports from
90
+ sal/eval/types.ts: EvalSink interface, EvalEventEnvelope/EvalEventType (run_start/run_end/turn_anchor), EvalAdapterId ("insforge"|"jsonl"|"noop"), CreateEvalSinkOptions with optional onDiagnostic callback, createEvalEvent factory; zero-dependency type surface
91
+ sal/eval/noop-sink.ts: noopSink — silent EvalSink used when eval disabled or no adapter configured
92
+ sal/eval/insforge-sink.ts: InsForgeEvalSink — PostgREST adapter, routes run_start→eval_runs INSERT (merge-duplicates) with legacy-schema fallback, writes turn_anchor/tool_trace/memory_recalls/run_end only after parent run confirmation, tool_trace→eval_tool_traces with PGRST204 fallback, memory_recalls→eval_memory_recalls batch INSERT, run_end→eval_runs PATCH; allowSelfSigned TLS option logs only in development runtime, batching with default 2000ms interval
93
+ sal/eval/jsonl-sink.ts: JsonlEvalSink — append-only filesystem adapter, one JSON object per line, accepts file:// URLs or plain paths, auto-creates parent dir, batched writes
94
+ sal/README.md: SAL extension usage, sidecar output layout, weights override, pluggability contract
95
+ team/index.ts: AgentTeam extension entry, /team <task>, /team:spawn/:preset/:send/:status/:progress/:psyche/:dashboard/:task/:mail/:allow-path/:stop/:terminate/:approve/:mode command registration and dispatch
96
+ team/team-ui.ts: AgentTeam message renderer, list/status/task formatting, dashboard visibility/timer ownership, realtime observer, speaker-stream emission helpers
97
+ team/team-types.ts: TeammateRole/TeammateMode/TeammateStatus/TeamTask/HarnessState/PsycheWeights/TeamUtterance/Handoff/LeaderPlan/AgentLiveView/TeammateIdentity/PersistedTeammate/TeamSpawnSpec/TeamSendResult types
98
+ team/team-state-store.ts: TeamStateStore class - durable teammate persistence via JSON files in <agentDir>/teams/
99
+ team/team-parser.ts: Team command parser - parseTeamCommand/buildTeamHelp for /team:* subcommands
100
+ team/team-runtime.ts: TeamRuntime class - teammate registry, stable internal labels plus visible teammate names, per-teammate send queue, lifecycle, durable tasks, mailbox + permission + transcript wiring
101
+ team/team-runtime-helpers.ts: TeamRuntime helper boundary - teammate prompt construction, harness turn preparation, live event projection, tool selection, path guards, label/role/text helpers
102
+ team/team-orchestrator.ts: Leader orchestration helpers - plan building, speaker utterance creation, @mention parsing, and handoff execution
103
+ team/team-task-store.ts: TeamTaskStore class - durable shared task list in <storageDir>/tasks.json
104
+ team/team-harness.ts: Harness protocol helpers - context files, phase instructions, checkpoint/revert, feature validation
105
+ team/team-presets.ts: Preset definitions and executor - solo/duo/squad spawning, model-assisted auto team selection, heuristic fallback
106
+ team/team-dashboard.ts: Text dashboard/status rendering - teammate workbench cards, current task, last utterance, progress bars, footer summary
107
+ team/team-psyche.ts: Psyche prompt layer - role/phase weighted Id/Ego/Superego prompt construction
108
+ team/team-permissions.ts: PermissionStore - pending permission request queue, approve/deny, path allowlists
109
+ team/team-mailbox.ts: TeamMailbox - typed JSONL-backed append-only message log for leader↔teammate and teammate↔teammate
110
+ team/team-transcript.ts: TeamTranscriptWriter - per-teammate JSONL transcripts
111
+ team/TESTING.md: Manual & smoke-test guide for Phase B AgentTeam
112
+
113
+ Rule: Members complete, one item per line, parent links valid, precise terms first
114
+
115
+ [COVENANT]: Update this file header on changes and verify against parent AGENT.md
@@ -1,17 +1,17 @@
1
- # extensions/builtin/browser/
2
-
3
- > P2 | Parent: ../AGENT.md
4
-
5
- Member List
6
- index.ts: Browser Harness extension entry, registers browser/browser_admin tools, /browser command, Browser Harness resource discovery for core/interaction/domain skills, project-local browser workspace seeding; loaded only through explicit extension config/CLI opt-in since P6/EV03
7
- browser.md: Browser Harness day-to-day skill instructions for NanoPencil tool use and workspace contribution
8
- install.md: Browser Harness setup and troubleshooting instructions, exposed as a skill resource
9
- src/browser_harness/: Vendored Browser Harness Python package, CDP daemon, IPC bridge, admin commands, and helper functions
10
- src/browser_harness/AGENT.md: P2 module map for the vendored Browser Harness Python package
11
- interaction-skills/: Reusable Browser Harness mechanics guides for tabs, screenshots, iframes, cookies, uploads, dialogs, scrolling, and related browser interactions
12
- agent-workspace/: Seed workspace copied to .nanopencil/browser-workspace for editable helpers and domain skills
13
- .env.example: Browser Harness environment variable template for Browser Use cloud integration
14
-
15
- Rule: Members complete, one item per line, parent links valid, precise terms first
16
-
17
- [COVENANT]: Update this file header on changes and verify against parent AGENT.md
1
+ # extensions/builtin/browser/
2
+
3
+ > P2 | Parent: ../AGENT.md
4
+
5
+ Member List
6
+ index.ts: Browser Harness extension entry, registers browser/browser_admin tools, /browser command, Browser Harness resource discovery for core/interaction/domain skills, project-local browser workspace seeding; loaded only through explicit extension config/CLI opt-in since P6/EV03
7
+ browser.md: Browser Harness day-to-day skill instructions for NanoPencil tool use and workspace contribution
8
+ install.md: Browser Harness setup and troubleshooting instructions, exposed as a skill resource
9
+ src/browser_harness/: Vendored Browser Harness Python package, CDP daemon, IPC bridge, admin commands, and helper functions
10
+ src/browser_harness/AGENT.md: P2 module map for the vendored Browser Harness Python package
11
+ interaction-skills/: Reusable Browser Harness mechanics guides for tabs, screenshots, iframes, cookies, uploads, dialogs, scrolling, and related browser interactions
12
+ agent-workspace/: Seed workspace copied to .nanopencil/browser-workspace for editable helpers and domain skills
13
+ .env.example: Browser Harness environment variable template for Browser Use cloud integration
14
+
15
+ Rule: Members complete, one item per line, parent links valid, precise terms first
16
+
17
+ [COVENANT]: Update this file header on changes and verify against parent AGENT.md