@ai-agent-forge/agent-forge 0.88.1 → 0.88.3

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 (518) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +1 -1
  3. package/bundled-plugins/agent-loop-policy/agent-forge.json +1 -1
  4. package/bundled-plugins/agent-loop-policy/plugin.json +1 -1
  5. package/bundled-plugins/coding-tools/agent-forge.json +1 -1
  6. package/bundled-plugins/coding-tools/plugin.json +1 -1
  7. package/bundled-plugins/compaction-policy/agent-forge.json +1 -1
  8. package/bundled-plugins/compaction-policy/plugin.json +1 -1
  9. package/bundled-plugins/overflow-policy/agent-forge.json +1 -1
  10. package/bundled-plugins/overflow-policy/plugin.json +1 -1
  11. package/bundled-plugins/provider-failover/agent-forge.json +1 -1
  12. package/bundled-plugins/provider-failover/plugin.json +1 -1
  13. package/bundled-plugins/retry-policy/agent-forge.json +1 -1
  14. package/bundled-plugins/retry-policy/plugin.json +1 -1
  15. package/dist/artifacts/paged-read.d.ts +6 -1
  16. package/dist/artifacts/paged-read.d.ts.map +1 -1
  17. package/dist/artifacts/paged-read.js.map +1 -1
  18. package/dist/bundle/.build-manifest.json +283 -263
  19. package/dist/bundle/chunks/{anthropic-messages-PLAKXR73.js → anthropic-messages-3FJHRAJL.js} +2 -2
  20. package/dist/bundle/chunks/anthropic.js +1 -1
  21. package/dist/bundle/chunks/{azure-openai-responses-OUWQ2AZD.js → azure-openai-responses-GCL47IDS.js} +1 -1
  22. package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
  23. package/dist/bundle/chunks/{chunk-Z72JWUZ4.js → chunk-32YDZI4J.js} +1 -1
  24. package/dist/bundle/chunks/{chunk-AQLNTW2B.js → chunk-755VNWIF.js} +17 -16
  25. package/dist/bundle/chunks/{chunk-LZOEQITZ.js → chunk-B42Y2VME.js} +120 -104
  26. package/dist/bundle/chunks/{chunk-DRQDKNXA.js → chunk-BVVSHK6W.js} +1 -1
  27. package/dist/bundle/chunks/{chunk-6R7UI4IY.js → chunk-QDLOMKF6.js} +1 -1
  28. package/dist/bundle/chunks/{chunk-D3ARGZFR.js → chunk-V3ACW7VD.js} +3 -3
  29. package/dist/bundle/chunks/{google-generative-ai-DLII6DAT.js → google-generative-ai-6BMXWA44.js} +1 -1
  30. package/dist/bundle/chunks/{google-vertex-G7BZL7GM.js → google-vertex-6H7NLRTK.js} +1 -1
  31. package/dist/bundle/chunks/image-resize-worker.js +3 -3
  32. package/dist/bundle/chunks/{mistral-conversations-JXUK24ID.js → mistral-conversations-IXUHSFSJ.js} +1 -1
  33. package/dist/bundle/chunks/{openai-codex-responses-5GSGFIPG.js → openai-codex-responses-YHUAEVCM.js} +1 -1
  34. package/dist/bundle/chunks/openai-codex.js +1 -1
  35. package/dist/bundle/chunks/{openai-completions-EI2I6DTG.js → openai-completions-ULQCFC72.js} +1 -1
  36. package/dist/bundle/chunks/openai-responses-NLLAJDPS.js +2 -0
  37. package/dist/bundle/chunks/{openrouter-images-G4GQRUSG.js → openrouter-images-GZZQZXMS.js} +1 -1
  38. package/dist/bundle/chunks/openrouter.js +1 -1
  39. package/dist/bundle/chunks/{pi-messages-PWU2VJMR.js → pi-messages-EJTI2EJ3.js} +1 -1
  40. package/dist/bundle/chunks/virtual-modules-TQWEGNNZ.js +5 -0
  41. package/dist/bundle/cli.js +1 -1
  42. package/dist/bundle/client.js +1 -1
  43. package/dist/bundle/index.js +1 -1
  44. package/dist/bundle/rpc-entry.js +1 -1
  45. package/dist/cli/args.d.ts +0 -1
  46. package/dist/cli/args.d.ts.map +1 -1
  47. package/dist/cli/args.js +1 -4
  48. package/dist/cli/args.js.map +1 -1
  49. package/dist/cli/config-selector.d.ts.map +1 -1
  50. package/dist/cli/config-selector.js +1 -1
  51. package/dist/cli/config-selector.js.map +1 -1
  52. package/dist/cli/experimental/cli.d.ts +3 -3
  53. package/dist/cli/experimental/cli.d.ts.map +1 -1
  54. package/dist/cli/experimental/cli.js +2 -2
  55. package/dist/cli/experimental/cli.js.map +1 -1
  56. package/dist/cli/experimental/commands/agent-forge.d.ts +15 -0
  57. package/dist/cli/experimental/commands/agent-forge.d.ts.map +1 -0
  58. package/dist/cli/experimental/commands/{pi.js → agent-forge.js} +4 -4
  59. package/dist/cli/experimental/commands/agent-forge.js.map +1 -0
  60. package/dist/cli/plugin-command.d.ts.map +1 -1
  61. package/dist/cli/plugin-command.js +8 -2
  62. package/dist/cli/plugin-command.js.map +1 -1
  63. package/dist/cli/startup-ui.d.ts.map +1 -1
  64. package/dist/cli/startup-ui.js +1 -1
  65. package/dist/cli/startup-ui.js.map +1 -1
  66. package/dist/config.d.ts +4 -4
  67. package/dist/config.d.ts.map +1 -1
  68. package/dist/config.js +7 -7
  69. package/dist/config.js.map +1 -1
  70. package/dist/core/agent-forge-manifest.d.ts +7 -0
  71. package/dist/core/agent-forge-manifest.d.ts.map +1 -0
  72. package/dist/core/{pi-manifest.js → agent-forge-manifest.js} +4 -4
  73. package/dist/core/agent-forge-manifest.js.map +1 -0
  74. package/dist/core/agent-session-compaction.d.ts +1 -1
  75. package/dist/core/agent-session-compaction.d.ts.map +1 -1
  76. package/dist/core/agent-session-compaction.js +3 -3
  77. package/dist/core/agent-session-compaction.js.map +1 -1
  78. package/dist/core/agent-session-internal.d.ts +2 -0
  79. package/dist/core/agent-session-internal.d.ts.map +1 -1
  80. package/dist/core/agent-session-internal.js.map +1 -1
  81. package/dist/core/agent-session-lifecycle.d.ts.map +1 -1
  82. package/dist/core/agent-session-lifecycle.js +12 -1
  83. package/dist/core/agent-session-lifecycle.js.map +1 -1
  84. package/dist/core/agent-session-projection.d.ts.map +1 -1
  85. package/dist/core/agent-session-projection.js +3 -3
  86. package/dist/core/agent-session-projection.js.map +1 -1
  87. package/dist/core/agent-session-services.d.ts +3 -1
  88. package/dist/core/agent-session-services.d.ts.map +1 -1
  89. package/dist/core/agent-session-services.js +2 -1
  90. package/dist/core/agent-session-services.js.map +1 -1
  91. package/dist/core/agent-session-store.d.ts.map +1 -1
  92. package/dist/core/agent-session-store.js +6 -1
  93. package/dist/core/agent-session-store.js.map +1 -1
  94. package/dist/core/agent-session-tools.d.ts.map +1 -1
  95. package/dist/core/agent-session-tools.js +13 -0
  96. package/dist/core/agent-session-tools.js.map +1 -1
  97. package/dist/core/agent-session.d.ts +24 -0
  98. package/dist/core/agent-session.d.ts.map +1 -1
  99. package/dist/core/agent-session.js +58 -4
  100. package/dist/core/agent-session.js.map +1 -1
  101. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  102. package/dist/core/compaction/branch-summarization.js +1 -1
  103. package/dist/core/compaction/branch-summarization.js.map +1 -1
  104. package/dist/core/experimental.d.ts.map +1 -1
  105. package/dist/core/experimental.js +1 -3
  106. package/dist/core/experimental.js.map +1 -1
  107. package/dist/core/extensions/capability-runtime-store.d.ts +20 -1
  108. package/dist/core/extensions/capability-runtime-store.d.ts.map +1 -1
  109. package/dist/core/extensions/capability-runtime-store.js +67 -0
  110. package/dist/core/extensions/capability-runtime-store.js.map +1 -1
  111. package/dist/core/extensions/capability-runtime-types.d.ts +14 -0
  112. package/dist/core/extensions/capability-runtime-types.d.ts.map +1 -1
  113. package/dist/core/extensions/capability-runtime-types.js +7 -1
  114. package/dist/core/extensions/capability-runtime-types.js.map +1 -1
  115. package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
  116. package/dist/core/extensions/capability-runtime.js +144 -42
  117. package/dist/core/extensions/capability-runtime.js.map +1 -1
  118. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  119. package/dist/core/extensions/virtual-modules.js +6 -1
  120. package/dist/core/extensions/virtual-modules.js.map +1 -1
  121. package/dist/core/facade/coding-agent-facade.d.ts +1 -1
  122. package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
  123. package/dist/core/facade/coding-agent-facade.js +1 -1
  124. package/dist/core/facade/coding-agent-facade.js.map +1 -1
  125. package/dist/core/i18n/locales/zh-cn/cli.d.ts.map +1 -1
  126. package/dist/core/i18n/locales/zh-cn/cli.js +2 -0
  127. package/dist/core/i18n/locales/zh-cn/cli.js.map +1 -1
  128. package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts +1 -1
  129. package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts.map +1 -1
  130. package/dist/core/i18n/locales/zh-cn/core-contract-final.js +3 -3
  131. package/dist/core/i18n/locales/zh-cn/core-contract-final.js.map +1 -1
  132. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts.map +1 -1
  133. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js +1 -1
  134. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js.map +1 -1
  135. package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -1
  136. package/dist/core/i18n/locales/zh-cn/core-errors.js +1 -1
  137. package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -1
  138. package/dist/core/i18n/locales/zh-cn/index.d.ts.map +1 -1
  139. package/dist/core/i18n/locales/zh-cn/index.js +2 -0
  140. package/dist/core/i18n/locales/zh-cn/index.js.map +1 -1
  141. package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -1
  142. package/dist/core/i18n/locales/zh-cn/interactive-mode.js +5 -0
  143. package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -1
  144. package/dist/core/i18n/locales/zh-cn/session-cleanup.d.ts +7 -0
  145. package/dist/core/i18n/locales/zh-cn/session-cleanup.d.ts.map +1 -0
  146. package/dist/core/i18n/locales/zh-cn/session-cleanup.js +15 -0
  147. package/dist/core/i18n/locales/zh-cn/session-cleanup.js.map +1 -0
  148. package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts.map +1 -1
  149. package/dist/core/i18n/locales/zh-cn/slash-commands.js +1 -0
  150. package/dist/core/i18n/locales/zh-cn/slash-commands.js.map +1 -1
  151. package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts.map +1 -1
  152. package/dist/core/i18n/locales/zh-cn/tui-components-misc.js +2 -0
  153. package/dist/core/i18n/locales/zh-cn/tui-components-misc.js.map +1 -1
  154. package/dist/core/model-resolver.d.ts +2 -0
  155. package/dist/core/model-resolver.d.ts.map +1 -1
  156. package/dist/core/model-resolver.js +4 -1
  157. package/dist/core/model-resolver.js.map +1 -1
  158. package/dist/core/package-resource-collection.d.ts.map +1 -1
  159. package/dist/core/package-resource-collection.js +5 -5
  160. package/dist/core/package-resource-collection.js.map +1 -1
  161. package/dist/core/provider-composer.d.ts.map +1 -1
  162. package/dist/core/provider-composer.js +3 -3
  163. package/dist/core/provider-composer.js.map +1 -1
  164. package/dist/core/resource-loader.d.ts.map +1 -1
  165. package/dist/core/resource-loader.js +1 -1
  166. package/dist/core/resource-loader.js.map +1 -1
  167. package/dist/core/sdk.d.ts +1 -1
  168. package/dist/core/sdk.d.ts.map +1 -1
  169. package/dist/core/sdk.js +30 -8
  170. package/dist/core/sdk.js.map +1 -1
  171. package/dist/core/session-cleanup.d.ts +49 -0
  172. package/dist/core/session-cleanup.d.ts.map +1 -0
  173. package/dist/core/session-cleanup.js +159 -0
  174. package/dist/core/session-cleanup.js.map +1 -0
  175. package/dist/core/session-index.d.ts +75 -0
  176. package/dist/core/session-index.d.ts.map +1 -0
  177. package/dist/core/session-index.js +455 -0
  178. package/dist/core/session-index.js.map +1 -0
  179. package/dist/core/session-manager.d.ts +9 -0
  180. package/dist/core/session-manager.d.ts.map +1 -1
  181. package/dist/core/session-manager.js +206 -51
  182. package/dist/core/session-manager.js.map +1 -1
  183. package/dist/core/settings-manager.d.ts.map +1 -1
  184. package/dist/core/settings-manager.js +5 -10
  185. package/dist/core/settings-manager.js.map +1 -1
  186. package/dist/core/slash-commands.d.ts.map +1 -1
  187. package/dist/core/slash-commands.js +5 -0
  188. package/dist/core/slash-commands.js.map +1 -1
  189. package/dist/core/system-prompt.d.ts.map +1 -1
  190. package/dist/core/system-prompt.js +12 -1
  191. package/dist/core/system-prompt.js.map +1 -1
  192. package/dist/core/timings.d.ts.map +1 -1
  193. package/dist/core/timings.js +1 -3
  194. package/dist/core/timings.js.map +1 -1
  195. package/dist/core/tools/capability-mount.d.ts +40 -0
  196. package/dist/core/tools/capability-mount.d.ts.map +1 -0
  197. package/dist/core/tools/capability-mount.js +112 -0
  198. package/dist/core/tools/capability-mount.js.map +1 -0
  199. package/dist/core/tools/render-utils.d.ts +1 -1
  200. package/dist/core/tools/render-utils.d.ts.map +1 -1
  201. package/dist/core/tools/render-utils.js.map +1 -1
  202. package/dist/core/tools/tool-definition.d.ts +1 -1
  203. package/dist/core/tools/tool-definition.d.ts.map +1 -1
  204. package/dist/core/tools/tool-definition.js.map +1 -1
  205. package/dist/core/trace-retention.d.ts +16 -1
  206. package/dist/core/trace-retention.d.ts.map +1 -1
  207. package/dist/core/trace-retention.js +43 -20
  208. package/dist/core/trace-retention.js.map +1 -1
  209. package/dist/export-html/ansi-to-html.d.ts.map +1 -0
  210. package/dist/export-html/ansi-to-html.js.map +1 -0
  211. package/dist/{core/export-html → export-html}/index.d.ts +1 -1
  212. package/dist/export-html/index.d.ts.map +1 -0
  213. package/dist/{core/export-html → export-html}/index.js +5 -5
  214. package/dist/export-html/index.js.map +1 -0
  215. package/dist/{core/export-html → export-html}/tool-renderer.d.ts +2 -2
  216. package/dist/export-html/tool-renderer.d.ts.map +1 -0
  217. package/dist/export-html/tool-renderer.js.map +1 -0
  218. package/dist/{modes/interactive → host}/model-catalog-refresh.d.ts +1 -1
  219. package/dist/host/model-catalog-refresh.d.ts.map +1 -0
  220. package/dist/{modes/interactive → host}/model-catalog-refresh.js +1 -1
  221. package/dist/host/model-catalog-refresh.js.map +1 -0
  222. package/dist/index.d.ts +5 -5
  223. package/dist/index.d.ts.map +1 -1
  224. package/dist/index.js +12 -12
  225. package/dist/index.js.map +1 -1
  226. package/dist/main.d.ts.map +1 -1
  227. package/dist/main.js +26 -14
  228. package/dist/main.js.map +1 -1
  229. package/dist/modes/interactive/components/agents-view.d.ts.map +1 -1
  230. package/dist/modes/interactive/components/agents-view.js +1 -1
  231. package/dist/modes/interactive/components/agents-view.js.map +1 -1
  232. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  233. package/dist/modes/interactive/components/armin.js +1 -1
  234. package/dist/modes/interactive/components/armin.js.map +1 -1
  235. package/dist/modes/interactive/components/assistant-message.d.ts +6 -0
  236. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  237. package/dist/modes/interactive/components/assistant-message.js +108 -27
  238. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  239. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  240. package/dist/modes/interactive/components/bash-execution.js +1 -1
  241. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  242. package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
  243. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  244. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  245. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  246. package/dist/modes/interactive/components/branch-summary-message.js +1 -1
  247. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  248. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  249. package/dist/modes/interactive/components/compaction-summary-message.js +1 -1
  250. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  251. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  252. package/dist/modes/interactive/components/config-selector.js +1 -1
  253. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  254. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  255. package/dist/modes/interactive/components/custom-entry.js +1 -1
  256. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  257. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  258. package/dist/modes/interactive/components/custom-message.js +1 -1
  259. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  260. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  261. package/dist/modes/interactive/components/daxnuts.js +1 -1
  262. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  263. package/dist/modes/interactive/components/dialog-editor.d.ts.map +1 -1
  264. package/dist/modes/interactive/components/dialog-editor.js +1 -1
  265. package/dist/modes/interactive/components/dialog-editor.js.map +1 -1
  266. package/dist/modes/interactive/components/dialog-input.d.ts.map +1 -1
  267. package/dist/modes/interactive/components/dialog-input.js +1 -1
  268. package/dist/modes/interactive/components/dialog-input.js.map +1 -1
  269. package/dist/modes/interactive/components/dialog-selector.d.ts.map +1 -1
  270. package/dist/modes/interactive/components/dialog-selector.js +1 -1
  271. package/dist/modes/interactive/components/dialog-selector.js.map +1 -1
  272. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  273. package/dist/modes/interactive/components/diff.js +1 -1
  274. package/dist/modes/interactive/components/diff.js.map +1 -1
  275. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  276. package/dist/modes/interactive/components/dynamic-border.js +1 -1
  277. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  278. package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
  279. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/first-time-setup.js +1 -1
  281. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  282. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  283. package/dist/modes/interactive/components/footer.js +1 -1
  284. package/dist/modes/interactive/components/footer.js.map +1 -1
  285. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  286. package/dist/modes/interactive/components/keybinding-hints.js +1 -1
  287. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  288. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  289. package/dist/modes/interactive/components/login-dialog.js +1 -1
  290. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  291. package/dist/modes/interactive/components/mermaid.d.ts +1 -1
  292. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
  293. package/dist/modes/interactive/components/mermaid.js.map +1 -1
  294. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  295. package/dist/modes/interactive/components/model-selector.js +2 -2
  296. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  297. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  298. package/dist/modes/interactive/components/oauth-selector.js +1 -1
  299. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  300. package/dist/modes/interactive/components/plugin-manager-entry.d.ts.map +1 -1
  301. package/dist/modes/interactive/components/plugin-manager-entry.js +1 -1
  302. package/dist/modes/interactive/components/plugin-manager-entry.js.map +1 -1
  303. package/dist/modes/interactive/components/plugin-selection-entry.d.ts.map +1 -1
  304. package/dist/modes/interactive/components/plugin-selection-entry.js +1 -1
  305. package/dist/modes/interactive/components/plugin-selection-entry.js.map +1 -1
  306. package/dist/modes/interactive/components/queue-manager-selector.d.ts.map +1 -1
  307. package/dist/modes/interactive/components/queue-manager-selector.js +1 -1
  308. package/dist/modes/interactive/components/queue-manager-selector.js.map +1 -1
  309. package/dist/modes/interactive/components/render-types.d.ts +1 -1
  310. package/dist/modes/interactive/components/render-types.d.ts.map +1 -1
  311. package/dist/modes/interactive/components/render-types.js.map +1 -1
  312. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  313. package/dist/modes/interactive/components/scoped-models-selector.js +1 -1
  314. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  315. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  316. package/dist/modes/interactive/components/session-selector-search.js +5 -1
  317. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  318. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  319. package/dist/modes/interactive/components/session-selector.js +11 -2
  320. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  321. package/dist/modes/interactive/components/settings-selector.d.ts +1 -1
  322. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  323. package/dist/modes/interactive/components/settings-selector.js +1 -1
  324. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  325. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  326. package/dist/modes/interactive/components/settings-submenu.js +1 -1
  327. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  328. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  329. package/dist/modes/interactive/components/show-images-selector.js +1 -1
  330. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  331. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  332. package/dist/modes/interactive/components/skill-invocation-message.js +1 -1
  333. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  334. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  335. package/dist/modes/interactive/components/status-indicator.js +1 -1
  336. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  337. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  338. package/dist/modes/interactive/components/theme-selector.js +1 -1
  339. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  340. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  341. package/dist/modes/interactive/components/thinking-selector.js +1 -1
  342. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  343. package/dist/modes/interactive/components/tool-execution.d.ts +19 -0
  344. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  345. package/dist/modes/interactive/components/tool-execution.js +139 -4
  346. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  347. package/dist/modes/interactive/components/tool-run-group.d.ts +44 -0
  348. package/dist/modes/interactive/components/tool-run-group.d.ts.map +1 -0
  349. package/dist/modes/interactive/components/tool-run-group.js +121 -0
  350. package/dist/modes/interactive/components/tool-run-group.js.map +1 -0
  351. package/dist/modes/interactive/components/tree-list.d.ts.map +1 -1
  352. package/dist/modes/interactive/components/tree-list.js +1 -1
  353. package/dist/modes/interactive/components/tree-list.js.map +1 -1
  354. package/dist/modes/interactive/components/tree-render.d.ts.map +1 -1
  355. package/dist/modes/interactive/components/tree-render.js +1 -1
  356. package/dist/modes/interactive/components/tree-render.js.map +1 -1
  357. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  358. package/dist/modes/interactive/components/tree-selector.js +1 -1
  359. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  360. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  361. package/dist/modes/interactive/components/user-message-selector.js +1 -1
  362. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  363. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/user-message.js +1 -1
  365. package/dist/modes/interactive/components/user-message.js.map +1 -1
  366. package/dist/modes/interactive/components/workflow-view.d.ts.map +1 -1
  367. package/dist/modes/interactive/components/workflow-view.js +1 -1
  368. package/dist/modes/interactive/components/workflow-view.js.map +1 -1
  369. package/dist/modes/interactive/interactive-auth.d.ts +1 -1
  370. package/dist/modes/interactive/interactive-auth.d.ts.map +1 -1
  371. package/dist/modes/interactive/interactive-auth.js +1 -1
  372. package/dist/modes/interactive/interactive-auth.js.map +1 -1
  373. package/dist/modes/interactive/interactive-commands.d.ts +125 -6
  374. package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
  375. package/dist/modes/interactive/interactive-commands.js +698 -4
  376. package/dist/modes/interactive/interactive-commands.js.map +1 -1
  377. package/dist/modes/interactive/interactive-events.d.ts +174 -0
  378. package/dist/modes/interactive/interactive-events.d.ts.map +1 -0
  379. package/dist/modes/interactive/interactive-events.js +704 -0
  380. package/dist/modes/interactive/interactive-events.js.map +1 -0
  381. package/dist/modes/interactive/interactive-format.d.ts.map +1 -1
  382. package/dist/modes/interactive/interactive-format.js +1 -1
  383. package/dist/modes/interactive/interactive-format.js.map +1 -1
  384. package/dist/modes/interactive/interactive-lifecycle.d.ts +94 -0
  385. package/dist/modes/interactive/interactive-lifecycle.d.ts.map +1 -0
  386. package/dist/modes/interactive/interactive-lifecycle.js +177 -0
  387. package/dist/modes/interactive/interactive-lifecycle.js.map +1 -0
  388. package/dist/modes/interactive/interactive-mode.d.ts +254 -129
  389. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  390. package/dist/modes/interactive/interactive-mode.js +275 -2101
  391. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  392. package/dist/modes/interactive/interactive-queues.d.ts +96 -0
  393. package/dist/modes/interactive/interactive-queues.d.ts.map +1 -0
  394. package/dist/modes/interactive/interactive-queues.js +183 -0
  395. package/dist/modes/interactive/interactive-queues.js.map +1 -0
  396. package/dist/modes/interactive/interactive-selectors.d.ts +95 -5
  397. package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
  398. package/dist/modes/interactive/interactive-selectors.js +517 -6
  399. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  400. package/dist/modes/interactive/startup-services.d.ts +31 -0
  401. package/dist/modes/interactive/startup-services.d.ts.map +1 -0
  402. package/dist/modes/interactive/startup-services.js +123 -0
  403. package/dist/modes/interactive/startup-services.js.map +1 -0
  404. package/dist/modes/memory-preheat.d.ts +11 -0
  405. package/dist/modes/memory-preheat.d.ts.map +1 -0
  406. package/dist/modes/memory-preheat.js +20 -0
  407. package/dist/modes/memory-preheat.js.map +1 -0
  408. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  409. package/dist/modes/rpc/rpc-mode.js +3 -1
  410. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  411. package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
  412. package/dist/plugins/ecosystem/cli.js +6 -3
  413. package/dist/plugins/ecosystem/cli.js.map +1 -1
  414. package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts +7 -1
  415. package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
  416. package/dist/plugins/ecosystem/node-plugin-bootstrap.js +50 -3
  417. package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
  418. package/dist/plugins/ecosystem/plugin-bootstrap.d.ts +28 -16
  419. package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
  420. package/dist/plugins/ecosystem/plugin-bootstrap.js +35 -33
  421. package/dist/plugins/ecosystem/plugin-bootstrap.js.map +1 -1
  422. package/dist/profile/plugin-profiles.d.ts +1 -1
  423. package/dist/profile/plugin-profiles.d.ts.map +1 -1
  424. package/dist/profile/plugin-profiles.js +18 -0
  425. package/dist/profile/plugin-profiles.js.map +1 -1
  426. package/dist/remote/server-assembly.d.ts.map +1 -1
  427. package/dist/remote/server-assembly.js +7 -2
  428. package/dist/remote/server-assembly.js.map +1 -1
  429. package/dist/{profiles → suites}/builtin-suites.d.ts +14 -4
  430. package/dist/suites/builtin-suites.d.ts.map +1 -0
  431. package/dist/{profiles → suites}/builtin-suites.js +20 -5
  432. package/dist/suites/builtin-suites.js.map +1 -0
  433. package/dist/suites/resolved-agent-profile.d.ts.map +1 -0
  434. package/dist/suites/resolved-agent-profile.js.map +1 -0
  435. package/dist/suites/suite-lifecycle.d.ts.map +1 -0
  436. package/dist/suites/suite-lifecycle.js.map +1 -0
  437. package/dist/suites/suite-loader.d.ts.map +1 -0
  438. package/dist/suites/suite-loader.js.map +1 -0
  439. package/dist/{modes/interactive/theme → theme}/dark.json +1 -1
  440. package/dist/{modes/interactive/theme → theme}/light.json +1 -1
  441. package/dist/{modes/interactive/theme → theme}/theme-controller.d.ts +1 -1
  442. package/dist/theme/theme-controller.d.ts.map +1 -0
  443. package/dist/{modes/interactive/theme → theme}/theme-controller.js +1 -1
  444. package/dist/theme/theme-controller.js.map +1 -0
  445. package/dist/{modes/interactive/theme → theme}/theme.d.ts +1 -1
  446. package/dist/theme/theme.d.ts.map +1 -0
  447. package/dist/{modes/interactive/theme → theme}/theme.js +5 -5
  448. package/dist/theme/theme.js.map +1 -0
  449. package/docs/compaction.md +7 -7
  450. package/docs/environment-variables.md +10 -4
  451. package/docs/keybindings.md +3 -3
  452. package/docs/models.md +17 -17
  453. package/docs/packages.md +1 -1
  454. package/docs/prompt-templates.md +1 -1
  455. package/docs/rpc.md +2 -2
  456. package/docs/sdk.md +5 -5
  457. package/docs/session-format.md +3 -3
  458. package/docs/settings.md +368 -354
  459. package/docs/shell-aliases.md +1 -1
  460. package/docs/skills.md +1 -1
  461. package/docs/terminal-setup.md +17 -17
  462. package/docs/themes.md +5 -5
  463. package/docs/tmux.md +4 -4
  464. package/docs/tui.md +1 -1
  465. package/docs/windows.md +1 -1
  466. package/examples/extensions/bash-spawn-hook/index.ts +1 -1
  467. package/examples/extensions/dynamic-resources/dynamic.json +1 -1
  468. package/examples/extensions/with-deps/package-lock.json +2 -2
  469. package/examples/extensions/with-deps/package.json +1 -6
  470. package/examples/extensions/with-deps/plugin.json +1 -1
  471. package/package.json +2 -2
  472. package/dist/bundle/chunks/openai-responses-AUJQ3NWT.js +0 -2
  473. package/dist/bundle/chunks/virtual-modules-WF6WRHP7.js +0 -5
  474. package/dist/cli/experimental/commands/pi.d.ts +0 -15
  475. package/dist/cli/experimental/commands/pi.d.ts.map +0 -1
  476. package/dist/cli/experimental/commands/pi.js.map +0 -1
  477. package/dist/core/export-html/ansi-to-html.d.ts.map +0 -1
  478. package/dist/core/export-html/ansi-to-html.js.map +0 -1
  479. package/dist/core/export-html/index.d.ts.map +0 -1
  480. package/dist/core/export-html/index.js.map +0 -1
  481. package/dist/core/export-html/tool-renderer.d.ts.map +0 -1
  482. package/dist/core/export-html/tool-renderer.js.map +0 -1
  483. package/dist/core/pi-manifest.d.ts +0 -7
  484. package/dist/core/pi-manifest.d.ts.map +0 -1
  485. package/dist/core/pi-manifest.js.map +0 -1
  486. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +0 -1
  487. package/dist/modes/interactive/model-catalog-refresh.js.map +0 -1
  488. package/dist/modes/interactive/theme/theme-controller.d.ts.map +0 -1
  489. package/dist/modes/interactive/theme/theme-controller.js.map +0 -1
  490. package/dist/modes/interactive/theme/theme.d.ts.map +0 -1
  491. package/dist/modes/interactive/theme/theme.js.map +0 -1
  492. package/dist/profiles/builtin-suites.d.ts.map +0 -1
  493. package/dist/profiles/builtin-suites.js.map +0 -1
  494. package/dist/profiles/resolved-agent-profile.d.ts.map +0 -1
  495. package/dist/profiles/resolved-agent-profile.js.map +0 -1
  496. package/dist/profiles/suite-lifecycle.d.ts.map +0 -1
  497. package/dist/profiles/suite-lifecycle.js.map +0 -1
  498. package/dist/profiles/suite-loader.d.ts.map +0 -1
  499. package/dist/profiles/suite-loader.js.map +0 -1
  500. package/dist/utils/deprecation.d.ts +0 -4
  501. package/dist/utils/deprecation.d.ts.map +0 -1
  502. package/dist/utils/deprecation.js +0 -13
  503. package/dist/utils/deprecation.js.map +0 -1
  504. /package/dist/{core/export-html → export-html}/ansi-to-html.d.ts +0 -0
  505. /package/dist/{core/export-html → export-html}/ansi-to-html.js +0 -0
  506. /package/dist/{core/export-html → export-html}/template.css +0 -0
  507. /package/dist/{core/export-html → export-html}/template.html +0 -0
  508. /package/dist/{core/export-html → export-html}/template.js +0 -0
  509. /package/dist/{core/export-html → export-html}/tool-renderer.js +0 -0
  510. /package/dist/{core/export-html → export-html}/vendor/highlight.min.js +0 -0
  511. /package/dist/{core/export-html → export-html}/vendor/marked.min.js +0 -0
  512. /package/dist/{profiles → suites}/resolved-agent-profile.d.ts +0 -0
  513. /package/dist/{profiles → suites}/resolved-agent-profile.js +0 -0
  514. /package/dist/{profiles → suites}/suite-lifecycle.d.ts +0 -0
  515. /package/dist/{profiles → suites}/suite-lifecycle.js +0 -0
  516. /package/dist/{profiles → suites}/suite-loader.d.ts +0 -0
  517. /package/dist/{profiles → suites}/suite-loader.js +0 -0
  518. /package/dist/{modes/interactive/theme → theme}/theme-schema.json +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,77 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.88.3] - 2026-10-07
6
+
7
+ ### Breaking Changes
8
+
9
+ - `CapabilityRuntime` gained a required member `hasLifecycleSubscribers(type, version)`: whether the registration map currently holds at least one lifecycle registration for the event key (owner activity is still rechecked at delivery). Structural implementers of this exported interface must add the member; in-repo `createCapabilityRuntime` is the only implementation and plugins only consume the interface, so external structural implementers are the affected surface.
10
+
11
+ ### Changed
12
+
13
+ - Tool result cards now carry a per-item display budget (M2, docs/design/终端输出模式设计.md §3.2, ruling 2026-10-07): a `BoundedResultView` wraps every result renderer component (third-party plugin renderers included) plus the definition-less generic fallback, capping the rendered output at 400 visual lines — head plus the last 100 lines survive and the middle collapses to one hint line naming the omitted count (and the `fullOutputPath` reference when the tool's details carry one). The ctrl+o expanded view is capped by the same budget, so expansion is no longer an unbounded-output escape hatch; renderer contracts are untouched (`renderResult` still receives the raw `expanded` value and `lastComponent` gets the unwrapped child), and error results stay exempt (error visibility beats compactness). Small outputs render byte-for-byte unchanged. Covered by `test/tool-execution-component.test.ts` (M2 block).
14
+ - Trace files now default to 14-day retention plus a per-directory cap of 500 files (M6 default retention, docs/design/会话轨迹与日志设计.md §6, ruling 2026-10-07): the startup sweep in main.ts runs by default and removes expired `*.trace.jsonl` files plus, per swept directory, the oldest-by-mtime survivors beyond the cap (age retention always wins a file over the cap — no double removal). `AGENT_FORGE_TRACE_MAX_AGE_DAYS` and the new `AGENT_FORGE_TRACE_MAX_FILES` override the defaults; an explicit `0` disables the respective mechanism (restoring keep-forever), an invalid value falls back to the default (previously: forever). Scope is unchanged: only the default sessions root (root + one level), never session files or custom `--session-dir`.
15
+ - `output.put` resident artifact buffers are capped at 1 MiB (`OUTPUT_ARTIFACT_MAX_BUFFER_BYTES`, M4 double-layer limit, docs/design/终端输出模式设计.md 缓冲上限契约): buffering stops once the ceiling is exceeded while the `AsyncIterable` is still fully consumed (an early return would backpressure the producer — excess data is only dropped), and the resident view becomes head + ASCII marker (`\n[agent-forge artifact truncated: {N} bytes omitted]\n`) + the final 64 KiB of the completed stream, never exceeding the cap. `ref.sizeBytes`/`ref.truncated` are now runtime-computed (`sizeBytes` is always the original total including dropped bytes; caller-provided values are overridden), and the `onOutputArtifactCommit` observer intentionally receives the truncated resident view, so durable mirrors persist the truncated view (the bash tool collection layer keeps its own hard cap plus the `fullOutputPath` full spill, unaffected). Under-cap puts are byte-for-byte unchanged. Covered by `test/output-artifact-buffer-cap.test.ts`.
16
+ - `model.stream` lifecycle dispatch is subscriber-gated: `dispatchModelStreamLifecycle` checks `hasLifecycleSubscribers` before the per-stream sequence increment, so with zero subscribers no per-delta envelope snapshot, clones, or dispatch happen and no sequence number is consumed — a late subscriber observes a contiguous stream starting at 1 (docs/design/插件基础能力设计.md §model.stream). With the bundled observability plugin attached (default), a subscriber is always present and the dispatch path is unchanged.
17
+ - The four process-level diagnostic containers exposed through the inspector are now bounded, evicting oldest-first on overflow (docs/design/插件基础能力设计.md §8.3): `operations` 1024 (a `running` entry is never evicted because `reportOperationStep` rejects steps for non-running ids; when every entry is running the insert proceeds above the limit and the size stays at that high-water mark, since statuses have no terminal-state removal path), `spans` 1024 (terminal spans evicted first; when all are running it falls back to the oldest in insertion order, and a later `annotate`/`end` on an evicted span throws "not available"), `logs` 1000, `pluginRejections` 128.
18
+ - Streaming assistant messages re-render incrementally: `AssistantMessageComponent.updateContent` diffs the rendered segment sequence and reuses unchanged prefix component instances (setText on the growing tail block), so a streaming frame no longer clears and rebuilds the whole message — per-frame cost drops from O(all blocks) to O(changed blocks) and the markdown token/line caches hit across frames instead of missing on every fresh instance. An `isStreaming` flip (turn end) still rebuilds fully, preserving the D-083 streaming/final transform split; terminal output is identical. Characterization tests pin the old streaming/thinking-collapse behavior.
19
+
20
+ ### Fixed
21
+
22
+ - The host module supply contract now covers the root `@agent-forge/protocol` specifier: the memory plugin's inference client/protocol modules import it bare, and the jiti VIRTUAL_MODULES table only supplied the `protocol/subagent` subpath — in the install-store shape (no host node_modules) the bare import failed, the memory plugin was silently rejected on load (D-028), and zero memory tools registered. The boundary checker's host-supplied specifier list gains the same root so the three supply places stay synchronized (`test/host-module-supply.test.ts`).
23
+ - `SessionManager` no longer copies `fileEntries` and `byId` on every append: `_appendEntry` rolls a failed storage write back in place (pop the pushed entry + conditional `byId` delete) instead of restoring an O(n) snapshot per append (O(n²) accumulation over a long session). Covered by deterministic failure-injection tests for a failed append and a failed first flush.
24
+
25
+ ## [0.88.2] - 2026-10-05
26
+
27
+ ### Breaking Changes
28
+
29
+ - pi 品牌除名收口(用户裁决 2026-10-05):环境变量只认 `AGENT_FORGE_*`,删除 `PI_TIMING` / `PI_EXPERIMENTAL` / `PI_CLEAR_ON_SHRINK` / `PI_HARDWARE_CURSOR` 的 legacy fallback 读取;package.json 包资源 manifest 键由 `pi`(`pi.skills` / `pi.prompts` / `pi.themes`)改为 `agent-forge`,旧键不再读取(`readPiManifest` → `readAgentForgeManifest`,`pi-manifest.ts` → `agent-forge-manifest.ts`);experimental CLI 根命令 `pi` 更名 `agent-forge`(`PiCommand` → `AgentForgeCommand`,`runPi` → `runAgentForge`)。
30
+
31
+ ### Added
32
+
33
+ - Plugin on-demand activation (插件按需挂载与能力手册设计): capability manifests may declare `activation: "on-demand"`, a one-line `description`, and an optional `manual` path. On-demand plugins register their tools but keep them out of the initial active surface; the system prompt carries a mountable-capabilities card per still-deferred plugin, and the new built-in `capability_mount` tool activates the full tool set (next request) and returns the plugin's AI manual, while `capability_unmount` removes only the schema (runtime state follows the plugin's own idle timeout; session teardown clears all mounts). The framework never unmounts automatically — default `activation` stays `always`, so existing and third-party plugins are unaffected (user ruling 2026-10-05 "临时/常驻分级、渐进式按需加载"). First batch on-demand (7): browser-playwright, the four desktop plugins, subagent-delegate, and image-generation — each ships an AI `MANUAL.md` and joins the package `files` whitelist. Deployment semantics: activation reads the install-store copy, so manifest changes require a `plugin install` re-run. Known defect (logged, workaround verified): local-directory installs package the tree inconsistently and may include `tsconfig.json`, whose repo-relative `extends` breaks jiti loading in the store; installing the `npm pack` tarball (files whitelist) is clean. Covered by `test/capability-mount.test.ts` and verified against a real grok-4.7 session: the model mounted the capability itself before any browser call, and a non-browser session sent zero browser tool schemas.
34
+
35
+ ### Fixed
36
+
37
+ - desktop-windows-input: key and no-target type actions now post through the real keyboard queue (`keybd_event`): named keys and Ctrl/Alt/Shift combinations go as virtual-key events, no-target `type` is typed as VK_PACKET unicode events addressed at the current focus. Previously `key` sent WM_CHAR window messages to the target window (so `Enter` typed the letters R-E-T-U-R-N) and `WScript.SendKeys` handled the rest; neither reaches UIA-invisible surfaces. The native file-picker flow (coordinate click to open the dialog → foreground type the path → Enter) was verified end-to-end against a real Chrome dialog, which UIA cannot enumerate at all (both TreeWalker and FindAll top-level scans miss it; Win32 EnumWindows sees it).
38
+ - Custom `--session-id` values (non-UUID short ids like `mount-test-13`) could not delegate subagents: the subagent mailbox and session-lineage addressing gate rejected any id outside the UUID/`st:` shapes, so the whole delegation failed with "mailbox owner id is not a session id" (macCRM dogfood 2026-10-05, the model itself traced the cause to `session-lineage.ts`). Addressing safety only requires a single path-safe segment; `isAgentSessionId` now also accepts `[A-Za-z0-9][A-Za-z0-9._-]*` except `.`/`..`, and the shape tests cover the custom-id family.
39
+ - `--rebind-suite` now actually works on `--session` resume: the flag was collected in `main.ts` but dropped on the `createAgentSessionFromServices` hop, so the sdk suite-binding guard still rejected the resume (macCRM dogfood 2026-10-04, reproduced on Windows too). It is forwarded through `CreateAgentSessionFromServicesOptions` and covered by a regression test.
40
+ - `plugin install` failures surface the installer's real message instead of the bare "The plugin installer operation failed" code (e.g. a missing `dist/entry.js` in the source directory now says so).
41
+ - Suite `capabilities` declaring a bundled-channel plugin (e.g. `agent-forge.plugin.provider-failover`) no longer warn "has no installed active plugin": bundled plugins ship with the host and load without an install-store entry, and the warning now knows that.
42
+ - browser-playwright: internal in-page scripts (performance collection, localStorage get/set/clear) are now passed to `page.evaluate` as function objects. Passing the equivalent `() => ...` arrow *string* is silently wrong on real Playwright — the string is evaluated as an expression, the resulting function object serializes to `undefined`, which crashed `browser_performance` with "Cannot read properties of undefined (reading 'paints')" and made the three `browser_storage` localStorage actions no-ops (macCRM dogfood 2026-10-05, verified against real Chromium). `browser_evaluate` docs now steer multi-statement logic to IIFE strings.
43
+ - browser-playwright: `browser_setup` no longer crashes with "Cannot read properties of undefined (reading 'options')" — the capability extracted `runtime.setup` into a local before calling it, dropping `this` on the production class runtime (closure-shaped test mocks never read `this`, so 73 deterministic tests stayed green; first-install dogfood 2026-10-05). A class-shaped runtime regression test now pins the call path, and `browser_setup` was verified end-to-end on a fresh host: AI gets the structured guidance, self-installs Playwright + Chromium through `browser_setup`, and continues the page task in the same session.
44
+ - browser-playwright: browser-binary lookup and install now share one directory. `browser_setup` installs Chromium into `<agentDir>/browser-deps/browsers` (isolated via `PLAYWRIGHT_BROWSERS_PATH`), but launch silently looked in the shared OS cache, so a fresh host with no cache failed with the install guidance even right after a successful setup. `connect()` now defaults `PLAYWRIGHT_BROWSERS_PATH` to the same isolated directory (never overriding an explicit user setting), and the manual-install guidance command pins the same path.
45
+ - browser-playwright: `browser_drag` no longer times out on pages using `setPointerCapture` (the standard drag idiom): after `mouse.down` the tool now moves to the target by geometry (`boundingBox` + stepped `mouse.move`) instead of `locator.hover()`, whose hit-target check is defeated by pointer capture retargeting events to the source element. `browser_locator_action` `scroll` now parks the cursor over the target element before wheeling — the wheel delta used to land on whatever container the mouse happened to hover, so scrolling an explicit container silently scrolled something else. Found by a 43-assertion business-effect matrix against a purpose-built test page; both sequences are pinned in the mock tests.
46
+
47
+ ### Added
48
+
49
+ - Visual baseline roles join the factory suite (factory contents revision 7,
50
+ 2026-10-04 user ruling "术有专攻、角色隔离"): `design-proposer` and
51
+ `visual-reviewer` join the factory role seeds and the default
52
+ `associations.roles` of both builtin suites, so the design-proposal and
53
+ visual-review roles are visible out of the box (dispatch stays an explicit
54
+ `role` choice; role files are disk-only and seeds never overwrite user
55
+ edits). Workspaces provisioned at revision 6 receive the upgrade-proposal
56
+ diagnostic and adopt via `--suite-reset`. See
57
+ `docs/plans/视觉保底角色设计注记.md`.
58
+
59
+ - macOS desktop plugin profiles and packages: three new builtin plugin profiles (`desktop-observe-macos`, `desktop-control-macos`, `desktop-qa-macos`) resolve the two new self-contained plugin packages `plugins/desktop-macos-observe` (`agent-forge.plugin.desktop-macos-observe`, read-only `desktop_probe`/`desktop_session_open`/`desktop_observe`/`desktop_reobserve`/`desktop_session_stop` over a JXA osascript Accessibility driver, source `macos-ax`) and `plugins/desktop-macos-input` (`agent-forge.plugin.desktop-macos-input`, bounded `desktop_execute` with click-only coordinate targets, no replay, shared `needs_user` gate). Both declare `platform.os: ["macos"]`, report fail-closed `unsupported` with probe reason `accessibility-permission-required` without an Accessibility grant, and stay separate profiles from the Windows desktop trio (a profile with an installed-but-platform-unavailable plugin is blocked wholesale by the resolver). Real darwin behavior is contract-tested with an injected fake `spawnSync`; on a real macOS host (app-mac-host, macOS 15.7.5, 2026-10-04) the deterministic suites pass, the driver's app location was fixed from by-name `Application('systemEvents')` to by-bundle-id `Application('com.apple.systemevents')` (by-name resolution fails under SSH launchd sessions), and the real-host cases now `ctx.skip(reason)` instead of silently passing when the probe reports unavailable. With `/usr/bin/osascript` granted Accessibility (TCC judges the calling binary itself, not sshd), the full real-injection suite on a TextEdit fixture passed on app-mac-host: type, key(BACKSPACE), control click, coordinate click, and focus all really injected and were re-observed.
60
+
61
+ - Session metadata index (`session-index.json` in the agent dir): `SessionManager.listAll`'s default-layout branch is now served by a single-file JSON projection of session metadata (name/cwd/created/modified/message count/first message, no transcript text), written on first flush, rename, fork/branch, and selector deletion, and throttled (10s) for in-flight appends — cross-project resume listing is instant on the index-hit path instead of re-reading every session header. Index entries split relations (`file`/`dir`/`id`/`cwd`, reconciled against readdir) from content cache validated by a `file_mtime_ms` token: cache fields are trusted only while the file's stat mtime is unchanged, and refreshed by re-reading the file when it differs (write hooks are warm-up optimization, never correctness); project rows hold dir/cwd only with last-activity derived at serve time. The index is a projection, never the source of truth: missing, corrupt (JSON-level or field-level), or version-mismatched indexes rebuild from the existing full scan, so drift self-heals without user-visible errors. Accepted visible change (设计 `docs/design/会话索引.md` §5): All-scope search matches name/first message/id/cwd only — full-text search stays on the current-directory scope.
62
+
63
+ - `/clean-sessions [days]` interactive command (single text-command entry point, no keybinding; 设计 `docs/design/会话索引.md` §7): deletes session files untouched for N days (default 7, positive-integer argument, usage echoed on invalid input) to keep session storage from filling the disk. Scanning stats every `*.jsonl` under all project directories of the default sessions root including `_agents/` (trace/guard sidecars excluded; the index cache is never trusted for this disk-reclaim decision), then runs a two-phase flow — preview of hit count, total size, and cutoff time, confirmation through the host dialog, then deletion of each hit with its paired `*.trace.jsonl` and `*.jsonl.guard`, index-entry removal, and emptied project directories — reporting deleted count and freed bytes. Zero hits report directly without entering confirmation.
64
+
65
+ ### Changed
66
+
67
+ - TUI transcript silencing (D-083, 设计 `docs/design/终端输出模式设计.md` §3): interactive mode's transcript is now quiet by default — one assistant turn's tool calls merge into a single dim marker line (`⏺ bash` while running, `⏺ 3 个工具`/`⏺ 3 tools` when done; the sole tool keeps its name), with an error-colored failure count appended when any result was an error (`· 1 个失败`). Thinking blocks stay fully visible while streaming, then collapse to one dim line (`✻ 思考`/`✻ thinking`); `hideThinkingBlock` hides even that line. `Ctrl+O` (`app.tools.expand`, unchanged key) enters detail mode: per-tool full cards and full thinking text. Quiet rendering skips child tool components entirely (no kv arg lines, no result previews, no "(ctrl+o to expand)" meta hints); session records and tool results are untouched. Tool rendering contracts (`ToolExecutionComponent`, plugin `renderCall`/`renderResult`) are unchanged — only the transcript assembly (streaming and session-restore paths) groups per turn.
68
+ - TUI quiet transcript follow-up (D-083 增补): a failing turn's marker now carries the failing result's first output line (single line, error color) under the `· N failed` count, and tool-result images (desktop/browser screenshots) render under the marker in quiet mode — both are user-visible conclusions, so neither stays hidden behind a global ctrl+o expansion. Text cards stay hidden; plugin render contracts unchanged.
69
+ - Startup plugin bootstrap now realigns factory-listed first-party plugins automatically instead of warning (2026-10-04 install-and-use ruling, 设计 `插件独立分发与启动装配设计.md` §1 G5 例外 + §4.4): an active installation whose version misses the factory range (`^framework version`) is upgraded in place at startup — previously it only produced a `range_not_satisfied` diagnostic with a manual `plugin install`/`update --all` command, leaving every CLI upgrade one manual step away from a working tool surface. The `range_not_satisfied` diagnostic code, the `diagnosed` action status, and the `degraded` aggregate status are removed accordingly; aligned entries report `installed` with reason `range_aligned`, failures report `align_failed` with a "next startup retries automatically" diagnostic, and `AGENT_FORGE_PLUGIN_BOOTSTRAP=off` plus the offline posture gate still skip the whole run. Download failures retry 3 times with exponential backoff at the node wiring layer (the decision loop stays pure), and each install/align/failure now renders one stderr progress line (`{pluginId}: installed {version}` / install-failed with retry note, i18n'd) so a fresh install or upgrade shows live state instead of silence; fully-satisfied startups stay silent. `plugin install` of a factory plugin now prints "restart agent-forge to load it" instead of directing users to edit suite.json (factory plugins resolve through the suite's `builtin.*` capability aliases that default suites already declare).
70
+ - Memory factory default flips off → light (user ruling 2026-10-05 "默认值按主流编程助手来、别默认关闭"): an unconfigured session now assembles the memory family (`memory_write`/`memory_recall`/`memory_list`/`memory_forget`, auto recall, bash error lessons) through the bundled memory package, matching mainstream coding assistants that ship memory enabled. Explicit `off` (settings `memory.mode`, env `AGENT_FORGE_MEMORY_MODE`, or the SDK `memoryCapability.mode` option) restores the previous privacy-first face, and invalid string values still fail closed to off with the same one-line diagnostics. Type-invalid `memoryMode`/`memorySettingsMode` config values now fail closed to off explicitly in the plugin entry instead of silently leaning on the old off default. The resolution chain (explicit > env > settings > legacy alias > default) is mirrored point by point between `resolveSdkMemoryMode` and the plugin's `resolveMemoryMode`; the golden default-session contract, the memory gating suite, and the default-value registry (`docs/design/产品默认值清单.md`) are re-pinned in the same change.
71
+ - Memory model downloads now run as a background preheat that never blocks a prompt (2026-10-05 user ruling 「后台预热、不阻塞提问」): interactive mode kicks the one-time download right after session bind through the public `memory_enable` tool face — missing models start downloading immediately (progress in the plugin log), models already present settle in seconds, declined/absent memory is a no-op. Recall during an in-flight load returns a warming unavailable packet instead of awaiting the download (the old behavior silently blocked the first prompt's auto-recall for the whole download). Plugin-side controls ship in `plugins/memory`: `/memory` shows status, `/memory off` persists a decline (suppressing only the factory-default tier; explicit `memory.mode` re-enables and the preheat re-arms next session), `/memory retry` re-runs after a failure, and the AI-facing `memory_enable` tool shares the same closures.
72
+ - Custom models.json models now default to `reasoning: true`, `maxTokens: 32768`, and `contextWindow: 256000` (user rulings 2026-10-05 "reasoning 默认 false 没有思考不合适" and "默认值按主流编程助手来、往大设置"): a minimal `{"id": ...}` entry gets thinking enabled at the default `medium` level instead of silently never thinking, and the window default no longer sits below mainstream 200K+ models (which triggered premature compaction). For models without thinking support, set `reasoning: false` explicitly — a wrongly-`true` model fails visibly (server rejects `reasoning_effort`) instead of the old silent capability loss; a true window below the default compacts late, caught by overflow detection. The `maxTokens` default moves 16384 → 32768 because reasoning models bill hidden thinking tokens against that budget and the docs already required ≥32768 for them. `cost` (all zero) default is unchanged; the values are registered in `docs/design/产品默认值清单.md`.
73
+
74
+ ## [0.88.1] - 2026-10-04
75
+
5
76
  ## [0.88.1] - 2026-10-04
6
77
 
7
78
  ### Breaking Changes
package/README.md CHANGED
@@ -342,7 +342,7 @@ Create a plugin directory under `~/.agent-forge/agent/plugins/` or `.agent-forge
342
342
  }
343
343
  ```
344
344
 
345
- Capability plugin manifests are validated before loading. See [examples/extensions/](examples/extensions/) for MCP, CLI bridge, Goal/Plan and multi-Agent templates. The pre-plugin `pi` package manifest is supported only as legacy compatibility and is not the recommended extension path.
345
+ Capability plugin manifests are validated before loading. See [examples/extensions/](examples/extensions/) for MCP, CLI bridge, Goal/Plan and multi-Agent templates. Package resource manifests are declared under the `agent-forge` key of a package.json; capability plugins via `plugin.json` are the recommended extension path.
346
346
 
347
347
  See [docs/packages.md](docs/packages.md).
348
348
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageFormatVersion": 1,
3
3
  "id": "agent-forge.plugin.agent-loop-policy",
4
- "pluginVersion": "0.88.1",
4
+ "pluginVersion": "0.88.3",
5
5
  "apiVersion": "1",
6
6
  "minHostVersion": "0.88.0",
7
7
  "platform": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "agent-forge.plugin.agent-loop-policy",
3
- "version": "0.88.1",
3
+ "version": "0.88.3",
4
4
  "apiVersion": "1-draft",
5
5
  "entry": "./dist/entry.js",
6
6
  "hostVersion": ">=0.88.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageFormatVersion": 1,
3
3
  "id": "agent-forge.plugin.coding-tools",
4
- "pluginVersion": "0.88.1",
4
+ "pluginVersion": "0.88.3",
5
5
  "apiVersion": "1",
6
6
  "minHostVersion": "0.88.0",
7
7
  "platform": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "agent-forge.plugin.coding-tools",
3
- "version": "0.88.1",
3
+ "version": "0.88.3",
4
4
  "apiVersion": "1-draft",
5
5
  "entry": "./dist/entry.js",
6
6
  "hostVersion": ">=0.88.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageFormatVersion": 1,
3
3
  "id": "agent-forge.plugin.compaction-policy",
4
- "pluginVersion": "0.88.1",
4
+ "pluginVersion": "0.88.3",
5
5
  "apiVersion": "1",
6
6
  "minHostVersion": "0.88.0",
7
7
  "platform": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "agent-forge.plugin.compaction-policy",
3
- "version": "0.88.1",
3
+ "version": "0.88.3",
4
4
  "apiVersion": "1-draft",
5
5
  "entry": "./dist/entry.js",
6
6
  "hostVersion": ">=0.88.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageFormatVersion": 1,
3
3
  "id": "agent-forge.plugin.overflow-policy",
4
- "pluginVersion": "0.88.1",
4
+ "pluginVersion": "0.88.3",
5
5
  "apiVersion": "1",
6
6
  "minHostVersion": "0.88.0",
7
7
  "platform": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "agent-forge.plugin.overflow-policy",
3
- "version": "0.88.1",
3
+ "version": "0.88.3",
4
4
  "apiVersion": "1-draft",
5
5
  "entry": "./dist/entry.js",
6
6
  "hostVersion": ">=0.88.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageFormatVersion": 1,
3
3
  "id": "agent-forge.plugin.provider-failover",
4
- "pluginVersion": "0.88.1",
4
+ "pluginVersion": "0.88.3",
5
5
  "apiVersion": "1",
6
6
  "minHostVersion": "0.88.0",
7
7
  "platform": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "agent-forge.plugin.provider-failover",
3
- "version": "0.88.1",
3
+ "version": "0.88.3",
4
4
  "apiVersion": "1-draft",
5
5
  "entry": "./dist/entry.js",
6
6
  "hostVersion": ">=0.88.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageFormatVersion": 1,
3
3
  "id": "agent-forge.plugin.retry-policy",
4
- "pluginVersion": "0.88.1",
4
+ "pluginVersion": "0.88.3",
5
5
  "apiVersion": "1",
6
6
  "minHostVersion": "0.88.0",
7
7
  "platform": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "agent-forge.plugin.retry-policy",
3
- "version": "0.88.1",
3
+ "version": "0.88.3",
4
4
  "apiVersion": "1-draft",
5
5
  "entry": "./dist/entry.js",
6
6
  "hostVersion": ">=0.88.0",
@@ -4,7 +4,12 @@
4
4
  *
5
5
  * `planArtifactPages` derives a deterministic page directory from the
6
6
  * artifact's stat size; `readArtifactPage` serves one page by slicing the
7
- * 2.6a store's read. Every unavailability (ended lifecycle, cross-session
7
+ * 2.6a store's read. Store contract this pager depends on: `stat().sizeBytes`
8
+ * MUST equal the byte length `read` serves. A store exposing a runtime-capped
9
+ * resident view (see OUTPUT_ARTIFACT_MAX_BUFFER_BYTES) keeps that invariant by
10
+ * statting with the resident length, not the original total — planning pages
11
+ * from a stat larger than the served bytes would produce silent empty tail
12
+ * pages here. Every unavailability (ended lifecycle, cross-session
8
13
  * read, unknown id, invalid page size) is a structured `unavailable`
9
14
  * result — never a crash and never a silent empty page. No new Agent
10
15
  * business API is introduced; the 2.6a store remains the only bytes source.
@@ -1 +1 @@
1
- {"version":3,"file":"paged-read.d.ts","sourceRoot":"","sources":["../../src/artifacts/paged-read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,kBAAkB,GAC3B;IACA,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,4BAA4B,EAAE,CAAC;CACvD,GACD;IAAE,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,MAAM,MAAM,kBAAkB,GAC3B;IACA,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC5B,GACD;IAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,EACpC,KAAK,EAAE;IAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC/D,kBAAkB,CAkBpB;AAED,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAC,EAC7C,KAAK,EAAE;IACN,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B,GACC,kBAAkB,CAgCpB","sourcesContent":["/**\n * Paged artifact reading (3.5c) — expands large artifacts through reference\n * pages instead of one unbounded read.\n *\n * `planArtifactPages` derives a deterministic page directory from the\n * artifact's stat size; `readArtifactPage` serves one page by slicing the\n * 2.6a store's read. Every unavailability (ended lifecycle, cross-session\n * read, unknown id, invalid page size) is a structured `unavailable`\n * result — never a crash and never a silent empty page. No new Agent\n * business API is introduced; the 2.6a store remains the only bytes source.\n */\nimport type { ArtifactStoreV1 } from \"./artifact-store.ts\";\n\nexport interface ArtifactPageDirectoryEntryV1 {\n\treadonly index: number;\n\treadonly offset: number;\n\treadonly size: number;\n}\n\nexport type ArtifactPagePlanV1 =\n\t| {\n\t\t\treadonly status: \"planned\";\n\t\t\treadonly totalBytes: number;\n\t\t\treadonly pageSize: number;\n\t\t\treadonly pages: readonly ArtifactPageDirectoryEntryV1[];\n\t }\n\t| { readonly status: \"invalid_page_size\"; readonly pageSize: number }\n\t| { readonly status: \"unavailable\"; readonly reason: string };\n\nexport type ArtifactPageReadV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly index: number;\n\t\t\treadonly offset: number;\n\t\t\treadonly bytes: Uint8Array;\n\t\t\treadonly hasMore: boolean;\n\t\t\treadonly nextOffset?: number;\n\t }\n\t| { readonly status: \"unavailable\"; readonly reason: string };\n\nexport function planArtifactPages(\n\tstore: Pick<ArtifactStoreV1, \"stat\">,\n\tinput: { readonly artifactId: string; readonly pageSize: number },\n): ArtifactPagePlanV1 {\n\tif (!Number.isSafeInteger(input.pageSize) || input.pageSize < 1) {\n\t\treturn { status: \"invalid_page_size\", pageSize: input.pageSize };\n\t}\n\tconst stat = store.stat(input.artifactId);\n\tif (!stat) return { status: \"unavailable\", reason: `Artifact not found: ${input.artifactId}` };\n\tif (stat.state === \"ended\") {\n\t\treturn {\n\t\t\tstatus: \"unavailable\",\n\t\t\treason: `Artifact ${input.artifactId} lifecycle has ended: ${stat.endReason ?? \"ended\"}`,\n\t\t};\n\t}\n\tconst totalBytes = stat.sizeBytes ?? 0;\n\tconst pages: ArtifactPageDirectoryEntryV1[] = [];\n\tfor (let offset = 0; offset < totalBytes; offset += input.pageSize) {\n\t\tpages.push({ index: pages.length, offset, size: Math.min(input.pageSize, totalBytes - offset) });\n\t}\n\treturn { status: \"planned\", totalBytes, pageSize: input.pageSize, pages: Object.freeze(pages) };\n}\n\nexport function readArtifactPage(\n\tstore: Pick<ArtifactStoreV1, \"read\" | \"stat\">,\n\tinput: {\n\t\treadonly artifactId: string;\n\t\treadonly sessionId: string;\n\t\treadonly index: number;\n\t\treadonly pageSize: number;\n\t},\n): ArtifactPageReadV1 {\n\tif (!Number.isSafeInteger(input.pageSize) || input.pageSize < 1) {\n\t\treturn { status: \"unavailable\", reason: `Invalid page size: ${input.pageSize}` };\n\t}\n\tconst plan = planArtifactPages(store, { artifactId: input.artifactId, pageSize: input.pageSize });\n\tif (plan.status !== \"planned\")\n\t\treturn {\n\t\t\tstatus: \"unavailable\",\n\t\t\t// v8 ignore next -- pageSize 已在入口校验,plan 不可能返回 invalid_page_size\n\t\t\treason: plan.status === \"unavailable\" ? plan.reason : `Invalid page size: ${plan.pageSize}`,\n\t\t};\n\tconst page = plan.pages[input.index];\n\tif (!page) {\n\t\treturn { status: \"unavailable\", reason: `Page ${input.index} is outside the plan (${plan.pages.length} pages)` };\n\t}\n\tlet bytes: Uint8Array;\n\ttry {\n\t\tbytes = store.read({ artifactId: input.artifactId, sessionId: input.sessionId }).bytes;\n\t} catch (error) {\n\t\treturn { status: \"unavailable\", reason: error instanceof Error ? error.message : String(error) };\n\t}\n\tconst slice = bytes.slice(page.offset, page.offset + page.size);\n\tconst nextOffset = page.offset + page.size;\n\tconst hasMore = nextOffset < plan.totalBytes;\n\treturn {\n\t\tstatus: \"ok\",\n\t\tindex: page.index,\n\t\toffset: page.offset,\n\t\tbytes: slice,\n\t\thasMore,\n\t\t...(hasMore ? { nextOffset } : {}),\n\t};\n}\n"]}
1
+ {"version":3,"file":"paged-read.d.ts","sourceRoot":"","sources":["../../src/artifacts/paged-read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,kBAAkB,GAC3B;IACA,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,4BAA4B,EAAE,CAAC;CACvD,GACD;IAAE,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,MAAM,MAAM,kBAAkB,GAC3B;IACA,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC5B,GACD;IAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,EACpC,KAAK,EAAE;IAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC/D,kBAAkB,CAkBpB;AAED,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAC,EAC7C,KAAK,EAAE;IACN,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B,GACC,kBAAkB,CAgCpB","sourcesContent":["/**\n * Paged artifact reading (3.5c) — expands large artifacts through reference\n * pages instead of one unbounded read.\n *\n * `planArtifactPages` derives a deterministic page directory from the\n * artifact's stat size; `readArtifactPage` serves one page by slicing the\n * 2.6a store's read. Store contract this pager depends on: `stat().sizeBytes`\n * MUST equal the byte length `read` serves. A store exposing a runtime-capped\n * resident view (see OUTPUT_ARTIFACT_MAX_BUFFER_BYTES) keeps that invariant by\n * statting with the resident length, not the original total — planning pages\n * from a stat larger than the served bytes would produce silent empty tail\n * pages here. Every unavailability (ended lifecycle, cross-session\n * read, unknown id, invalid page size) is a structured `unavailable`\n * result — never a crash and never a silent empty page. No new Agent\n * business API is introduced; the 2.6a store remains the only bytes source.\n */\nimport type { ArtifactStoreV1 } from \"./artifact-store.ts\";\n\nexport interface ArtifactPageDirectoryEntryV1 {\n\treadonly index: number;\n\treadonly offset: number;\n\treadonly size: number;\n}\n\nexport type ArtifactPagePlanV1 =\n\t| {\n\t\t\treadonly status: \"planned\";\n\t\t\treadonly totalBytes: number;\n\t\t\treadonly pageSize: number;\n\t\t\treadonly pages: readonly ArtifactPageDirectoryEntryV1[];\n\t }\n\t| { readonly status: \"invalid_page_size\"; readonly pageSize: number }\n\t| { readonly status: \"unavailable\"; readonly reason: string };\n\nexport type ArtifactPageReadV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly index: number;\n\t\t\treadonly offset: number;\n\t\t\treadonly bytes: Uint8Array;\n\t\t\treadonly hasMore: boolean;\n\t\t\treadonly nextOffset?: number;\n\t }\n\t| { readonly status: \"unavailable\"; readonly reason: string };\n\nexport function planArtifactPages(\n\tstore: Pick<ArtifactStoreV1, \"stat\">,\n\tinput: { readonly artifactId: string; readonly pageSize: number },\n): ArtifactPagePlanV1 {\n\tif (!Number.isSafeInteger(input.pageSize) || input.pageSize < 1) {\n\t\treturn { status: \"invalid_page_size\", pageSize: input.pageSize };\n\t}\n\tconst stat = store.stat(input.artifactId);\n\tif (!stat) return { status: \"unavailable\", reason: `Artifact not found: ${input.artifactId}` };\n\tif (stat.state === \"ended\") {\n\t\treturn {\n\t\t\tstatus: \"unavailable\",\n\t\t\treason: `Artifact ${input.artifactId} lifecycle has ended: ${stat.endReason ?? \"ended\"}`,\n\t\t};\n\t}\n\tconst totalBytes = stat.sizeBytes ?? 0;\n\tconst pages: ArtifactPageDirectoryEntryV1[] = [];\n\tfor (let offset = 0; offset < totalBytes; offset += input.pageSize) {\n\t\tpages.push({ index: pages.length, offset, size: Math.min(input.pageSize, totalBytes - offset) });\n\t}\n\treturn { status: \"planned\", totalBytes, pageSize: input.pageSize, pages: Object.freeze(pages) };\n}\n\nexport function readArtifactPage(\n\tstore: Pick<ArtifactStoreV1, \"read\" | \"stat\">,\n\tinput: {\n\t\treadonly artifactId: string;\n\t\treadonly sessionId: string;\n\t\treadonly index: number;\n\t\treadonly pageSize: number;\n\t},\n): ArtifactPageReadV1 {\n\tif (!Number.isSafeInteger(input.pageSize) || input.pageSize < 1) {\n\t\treturn { status: \"unavailable\", reason: `Invalid page size: ${input.pageSize}` };\n\t}\n\tconst plan = planArtifactPages(store, { artifactId: input.artifactId, pageSize: input.pageSize });\n\tif (plan.status !== \"planned\")\n\t\treturn {\n\t\t\tstatus: \"unavailable\",\n\t\t\t// v8 ignore next -- pageSize 已在入口校验,plan 不可能返回 invalid_page_size\n\t\t\treason: plan.status === \"unavailable\" ? plan.reason : `Invalid page size: ${plan.pageSize}`,\n\t\t};\n\tconst page = plan.pages[input.index];\n\tif (!page) {\n\t\treturn { status: \"unavailable\", reason: `Page ${input.index} is outside the plan (${plan.pages.length} pages)` };\n\t}\n\tlet bytes: Uint8Array;\n\ttry {\n\t\tbytes = store.read({ artifactId: input.artifactId, sessionId: input.sessionId }).bytes;\n\t} catch (error) {\n\t\treturn { status: \"unavailable\", reason: error instanceof Error ? error.message : String(error) };\n\t}\n\tconst slice = bytes.slice(page.offset, page.offset + page.size);\n\tconst nextOffset = page.offset + page.size;\n\tconst hasMore = nextOffset < plan.totalBytes;\n\treturn {\n\t\tstatus: \"ok\",\n\t\tindex: page.index,\n\t\toffset: page.offset,\n\t\tbytes: slice,\n\t\thasMore,\n\t\t...(hasMore ? { nextOffset } : {}),\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"paged-read.js","sourceRoot":"","sources":["../../src/artifacts/paged-read.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Paged artifact reading (3.5c) — expands large artifacts through reference\n * pages instead of one unbounded read.\n *\n * `planArtifactPages` derives a deterministic page directory from the\n * artifact's stat size; `readArtifactPage` serves one page by slicing the\n * 2.6a store's read. Every unavailability (ended lifecycle, cross-session\n * read, unknown id, invalid page size) is a structured `unavailable`\n * result — never a crash and never a silent empty page. No new Agent\n * business API is introduced; the 2.6a store remains the only bytes source.\n */\nimport type { ArtifactStoreV1 } from \"./artifact-store.ts\";\n\nexport interface ArtifactPageDirectoryEntryV1 {\n\treadonly index: number;\n\treadonly offset: number;\n\treadonly size: number;\n}\n\nexport type ArtifactPagePlanV1 =\n\t| {\n\t\t\treadonly status: \"planned\";\n\t\t\treadonly totalBytes: number;\n\t\t\treadonly pageSize: number;\n\t\t\treadonly pages: readonly ArtifactPageDirectoryEntryV1[];\n\t }\n\t| { readonly status: \"invalid_page_size\"; readonly pageSize: number }\n\t| { readonly status: \"unavailable\"; readonly reason: string };\n\nexport type ArtifactPageReadV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly index: number;\n\t\t\treadonly offset: number;\n\t\t\treadonly bytes: Uint8Array;\n\t\t\treadonly hasMore: boolean;\n\t\t\treadonly nextOffset?: number;\n\t }\n\t| { readonly status: \"unavailable\"; readonly reason: string };\n\nexport function planArtifactPages(\n\tstore: Pick<ArtifactStoreV1, \"stat\">,\n\tinput: { readonly artifactId: string; readonly pageSize: number },\n): ArtifactPagePlanV1 {\n\tif (!Number.isSafeInteger(input.pageSize) || input.pageSize < 1) {\n\t\treturn { status: \"invalid_page_size\", pageSize: input.pageSize };\n\t}\n\tconst stat = store.stat(input.artifactId);\n\tif (!stat) return { status: \"unavailable\", reason: `Artifact not found: ${input.artifactId}` };\n\tif (stat.state === \"ended\") {\n\t\treturn {\n\t\t\tstatus: \"unavailable\",\n\t\t\treason: `Artifact ${input.artifactId} lifecycle has ended: ${stat.endReason ?? \"ended\"}`,\n\t\t};\n\t}\n\tconst totalBytes = stat.sizeBytes ?? 0;\n\tconst pages: ArtifactPageDirectoryEntryV1[] = [];\n\tfor (let offset = 0; offset < totalBytes; offset += input.pageSize) {\n\t\tpages.push({ index: pages.length, offset, size: Math.min(input.pageSize, totalBytes - offset) });\n\t}\n\treturn { status: \"planned\", totalBytes, pageSize: input.pageSize, pages: Object.freeze(pages) };\n}\n\nexport function readArtifactPage(\n\tstore: Pick<ArtifactStoreV1, \"read\" | \"stat\">,\n\tinput: {\n\t\treadonly artifactId: string;\n\t\treadonly sessionId: string;\n\t\treadonly index: number;\n\t\treadonly pageSize: number;\n\t},\n): ArtifactPageReadV1 {\n\tif (!Number.isSafeInteger(input.pageSize) || input.pageSize < 1) {\n\t\treturn { status: \"unavailable\", reason: `Invalid page size: ${input.pageSize}` };\n\t}\n\tconst plan = planArtifactPages(store, { artifactId: input.artifactId, pageSize: input.pageSize });\n\tif (plan.status !== \"planned\")\n\t\treturn {\n\t\t\tstatus: \"unavailable\",\n\t\t\t// v8 ignore next -- pageSize 已在入口校验,plan 不可能返回 invalid_page_size\n\t\t\treason: plan.status === \"unavailable\" ? plan.reason : `Invalid page size: ${plan.pageSize}`,\n\t\t};\n\tconst page = plan.pages[input.index];\n\tif (!page) {\n\t\treturn { status: \"unavailable\", reason: `Page ${input.index} is outside the plan (${plan.pages.length} pages)` };\n\t}\n\tlet bytes: Uint8Array;\n\ttry {\n\t\tbytes = store.read({ artifactId: input.artifactId, sessionId: input.sessionId }).bytes;\n\t} catch (error) {\n\t\treturn { status: \"unavailable\", reason: error instanceof Error ? error.message : String(error) };\n\t}\n\tconst slice = bytes.slice(page.offset, page.offset + page.size);\n\tconst nextOffset = page.offset + page.size;\n\tconst hasMore = nextOffset < plan.totalBytes;\n\treturn {\n\t\tstatus: \"ok\",\n\t\tindex: page.index,\n\t\toffset: page.offset,\n\t\tbytes: slice,\n\t\thasMore,\n\t\t...(hasMore ? { nextOffset } : {}),\n\t};\n}\n"]}
1
+ {"version":3,"file":"paged-read.js","sourceRoot":"","sources":["../../src/artifacts/paged-read.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Paged artifact reading (3.5c) — expands large artifacts through reference\n * pages instead of one unbounded read.\n *\n * `planArtifactPages` derives a deterministic page directory from the\n * artifact's stat size; `readArtifactPage` serves one page by slicing the\n * 2.6a store's read. Store contract this pager depends on: `stat().sizeBytes`\n * MUST equal the byte length `read` serves. A store exposing a runtime-capped\n * resident view (see OUTPUT_ARTIFACT_MAX_BUFFER_BYTES) keeps that invariant by\n * statting with the resident length, not the original total — planning pages\n * from a stat larger than the served bytes would produce silent empty tail\n * pages here. Every unavailability (ended lifecycle, cross-session\n * read, unknown id, invalid page size) is a structured `unavailable`\n * result — never a crash and never a silent empty page. No new Agent\n * business API is introduced; the 2.6a store remains the only bytes source.\n */\nimport type { ArtifactStoreV1 } from \"./artifact-store.ts\";\n\nexport interface ArtifactPageDirectoryEntryV1 {\n\treadonly index: number;\n\treadonly offset: number;\n\treadonly size: number;\n}\n\nexport type ArtifactPagePlanV1 =\n\t| {\n\t\t\treadonly status: \"planned\";\n\t\t\treadonly totalBytes: number;\n\t\t\treadonly pageSize: number;\n\t\t\treadonly pages: readonly ArtifactPageDirectoryEntryV1[];\n\t }\n\t| { readonly status: \"invalid_page_size\"; readonly pageSize: number }\n\t| { readonly status: \"unavailable\"; readonly reason: string };\n\nexport type ArtifactPageReadV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly index: number;\n\t\t\treadonly offset: number;\n\t\t\treadonly bytes: Uint8Array;\n\t\t\treadonly hasMore: boolean;\n\t\t\treadonly nextOffset?: number;\n\t }\n\t| { readonly status: \"unavailable\"; readonly reason: string };\n\nexport function planArtifactPages(\n\tstore: Pick<ArtifactStoreV1, \"stat\">,\n\tinput: { readonly artifactId: string; readonly pageSize: number },\n): ArtifactPagePlanV1 {\n\tif (!Number.isSafeInteger(input.pageSize) || input.pageSize < 1) {\n\t\treturn { status: \"invalid_page_size\", pageSize: input.pageSize };\n\t}\n\tconst stat = store.stat(input.artifactId);\n\tif (!stat) return { status: \"unavailable\", reason: `Artifact not found: ${input.artifactId}` };\n\tif (stat.state === \"ended\") {\n\t\treturn {\n\t\t\tstatus: \"unavailable\",\n\t\t\treason: `Artifact ${input.artifactId} lifecycle has ended: ${stat.endReason ?? \"ended\"}`,\n\t\t};\n\t}\n\tconst totalBytes = stat.sizeBytes ?? 0;\n\tconst pages: ArtifactPageDirectoryEntryV1[] = [];\n\tfor (let offset = 0; offset < totalBytes; offset += input.pageSize) {\n\t\tpages.push({ index: pages.length, offset, size: Math.min(input.pageSize, totalBytes - offset) });\n\t}\n\treturn { status: \"planned\", totalBytes, pageSize: input.pageSize, pages: Object.freeze(pages) };\n}\n\nexport function readArtifactPage(\n\tstore: Pick<ArtifactStoreV1, \"read\" | \"stat\">,\n\tinput: {\n\t\treadonly artifactId: string;\n\t\treadonly sessionId: string;\n\t\treadonly index: number;\n\t\treadonly pageSize: number;\n\t},\n): ArtifactPageReadV1 {\n\tif (!Number.isSafeInteger(input.pageSize) || input.pageSize < 1) {\n\t\treturn { status: \"unavailable\", reason: `Invalid page size: ${input.pageSize}` };\n\t}\n\tconst plan = planArtifactPages(store, { artifactId: input.artifactId, pageSize: input.pageSize });\n\tif (plan.status !== \"planned\")\n\t\treturn {\n\t\t\tstatus: \"unavailable\",\n\t\t\t// v8 ignore next -- pageSize 已在入口校验,plan 不可能返回 invalid_page_size\n\t\t\treason: plan.status === \"unavailable\" ? plan.reason : `Invalid page size: ${plan.pageSize}`,\n\t\t};\n\tconst page = plan.pages[input.index];\n\tif (!page) {\n\t\treturn { status: \"unavailable\", reason: `Page ${input.index} is outside the plan (${plan.pages.length} pages)` };\n\t}\n\tlet bytes: Uint8Array;\n\ttry {\n\t\tbytes = store.read({ artifactId: input.artifactId, sessionId: input.sessionId }).bytes;\n\t} catch (error) {\n\t\treturn { status: \"unavailable\", reason: error instanceof Error ? error.message : String(error) };\n\t}\n\tconst slice = bytes.slice(page.offset, page.offset + page.size);\n\tconst nextOffset = page.offset + page.size;\n\tconst hasMore = nextOffset < plan.totalBytes;\n\treturn {\n\t\tstatus: \"ok\",\n\t\tindex: page.index,\n\t\toffset: page.offset,\n\t\tbytes: slice,\n\t\thasMore,\n\t\t...(hasMore ? { nextOffset } : {}),\n\t};\n}\n"]}