@armadra/agent 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (433) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/LICENSE +21 -0
  3. package/README.md +470 -2
  4. package/dist/agent/agent.d.ts +56 -0
  5. package/dist/agent/agent.js +129 -0
  6. package/dist/agent/loop.d.ts +51 -0
  7. package/dist/agent/loop.js +158 -0
  8. package/dist/agent/queue.d.ts +25 -0
  9. package/dist/agent/queue.js +55 -0
  10. package/dist/agent/retry.d.ts +22 -0
  11. package/dist/agent/retry.js +92 -0
  12. package/dist/agent/schema.d.ts +27 -0
  13. package/dist/agent/schema.js +186 -0
  14. package/dist/agent/session-cache.d.ts +100 -0
  15. package/dist/agent/session-cache.js +514 -0
  16. package/dist/agent/session-compaction.d.ts +49 -0
  17. package/dist/agent/session-compaction.js +251 -0
  18. package/dist/agent/session-core.d.ts +103 -0
  19. package/dist/agent/session-core.js +7 -0
  20. package/dist/agent/session-run.d.ts +55 -0
  21. package/dist/agent/session-run.js +246 -0
  22. package/dist/agent/session-state.d.ts +39 -0
  23. package/dist/agent/session-state.js +119 -0
  24. package/dist/agent/session-subagent.d.ts +54 -0
  25. package/dist/agent/session-subagent.js +157 -0
  26. package/dist/agent/session-sync.d.ts +20 -0
  27. package/dist/agent/session-sync.js +111 -0
  28. package/dist/agent/session-tools.d.ts +24 -0
  29. package/dist/agent/session-tools.js +277 -0
  30. package/dist/agent/session.d.ts +117 -0
  31. package/dist/agent/session.js +485 -0
  32. package/dist/agent/system-prompt.d.ts +49 -0
  33. package/dist/agent/system-prompt.js +121 -0
  34. package/dist/agent/tool-runner.d.ts +64 -0
  35. package/dist/agent/tool-runner.js +309 -0
  36. package/dist/agent/transform.d.ts +26 -0
  37. package/dist/agent/transform.js +171 -0
  38. package/dist/agent/types.d.ts +378 -0
  39. package/dist/agent/types.js +21 -0
  40. package/dist/ai/apis/anthropic-messages.d.ts +26 -0
  41. package/dist/ai/apis/anthropic-messages.js +214 -0
  42. package/dist/ai/apis/anthropic-request.d.ts +42 -0
  43. package/dist/ai/apis/anthropic-request.js +282 -0
  44. package/dist/ai/apis/api.d.ts +28 -0
  45. package/dist/ai/apis/api.js +102 -0
  46. package/dist/ai/apis/cache-params.d.ts +48 -0
  47. package/dist/ai/apis/cache-params.js +163 -0
  48. package/dist/ai/apis/google-generative-ai.d.ts +32 -0
  49. package/dist/ai/apis/google-generative-ai.js +249 -0
  50. package/dist/ai/apis/google-request.d.ts +40 -0
  51. package/dist/ai/apis/google-request.js +255 -0
  52. package/dist/ai/apis/openai-compat.d.ts +35 -0
  53. package/dist/ai/apis/openai-compat.js +142 -0
  54. package/dist/ai/apis/openai-completions.d.ts +28 -0
  55. package/dist/ai/apis/openai-completions.js +246 -0
  56. package/dist/ai/apis/openai-request.d.ts +35 -0
  57. package/dist/ai/apis/openai-request.js +303 -0
  58. package/dist/ai/apis/openai-responses-request.d.ts +52 -0
  59. package/dist/ai/apis/openai-responses-request.js +266 -0
  60. package/dist/ai/apis/openai-responses.d.ts +28 -0
  61. package/dist/ai/apis/openai-responses.js +304 -0
  62. package/dist/ai/apis/shared.d.ts +56 -0
  63. package/dist/ai/apis/shared.js +179 -0
  64. package/dist/ai/cache/economics.d.ts +24 -0
  65. package/dist/ai/cache/economics.js +69 -0
  66. package/dist/ai/cache/fingerprint.d.ts +17 -0
  67. package/dist/ai/cache/fingerprint.js +39 -0
  68. package/dist/ai/cache/miss.d.ts +49 -0
  69. package/dist/ai/cache/miss.js +96 -0
  70. package/dist/ai/cache/reporting.d.ts +39 -0
  71. package/dist/ai/cache/reporting.js +103 -0
  72. package/dist/ai/cache/types.d.ts +94 -0
  73. package/dist/ai/cache/types.js +19 -0
  74. package/dist/ai/cache/warmer.d.ts +94 -0
  75. package/dist/ai/cache/warmer.js +224 -0
  76. package/dist/ai/context.d.ts +35 -0
  77. package/dist/ai/context.js +114 -0
  78. package/dist/ai/cost.d.ts +21 -0
  79. package/dist/ai/cost.js +60 -0
  80. package/dist/ai/event-stream.d.ts +33 -0
  81. package/dist/ai/event-stream.js +101 -0
  82. package/dist/ai/fake/fake-provider.d.ts +68 -0
  83. package/dist/ai/fake/fake-provider.js +278 -0
  84. package/dist/ai/fake/fake-script.d.ts +69 -0
  85. package/dist/ai/fake/fake-script.js +142 -0
  86. package/dist/ai/http.d.ts +54 -0
  87. package/dist/ai/http.js +212 -0
  88. package/dist/ai/json-partial.d.ts +17 -0
  89. package/dist/ai/json-partial.js +243 -0
  90. package/dist/ai/overflow.d.ts +22 -0
  91. package/dist/ai/overflow.js +61 -0
  92. package/dist/ai/providers/auth.d.ts +71 -0
  93. package/dist/ai/providers/auth.js +202 -0
  94. package/dist/ai/providers/builtin.d.ts +23 -0
  95. package/dist/ai/providers/builtin.js +148 -0
  96. package/dist/ai/providers/catalog-data.d.ts +5 -0
  97. package/dist/ai/providers/catalog-data.js +19 -0
  98. package/dist/ai/providers/catalog.d.ts +28 -0
  99. package/dist/ai/providers/catalog.js +166 -0
  100. package/dist/ai/providers/channels.d.ts +51 -0
  101. package/dist/ai/providers/channels.js +96 -0
  102. package/dist/ai/providers/enrich.d.ts +34 -0
  103. package/dist/ai/providers/enrich.js +86 -0
  104. package/dist/ai/providers/models-dev-cache.d.ts +53 -0
  105. package/dist/ai/providers/models-dev-cache.js +147 -0
  106. package/dist/ai/providers/models-dev.d.ts +99 -0
  107. package/dist/ai/providers/models-dev.js +315 -0
  108. package/dist/ai/providers/registry.d.ts +114 -0
  109. package/dist/ai/providers/registry.js +458 -0
  110. package/dist/ai/sse.d.ts +32 -0
  111. package/dist/ai/sse.js +140 -0
  112. package/dist/ai/thinking.d.ts +42 -0
  113. package/dist/ai/thinking.js +101 -0
  114. package/dist/ai/types.d.ts +448 -0
  115. package/dist/ai/types.js +19 -0
  116. package/dist/bundle/ama-sandbox.cjs +324 -0
  117. package/dist/bundle/ama.cjs +27837 -0
  118. package/dist/bundle.d.ts +9 -0
  119. package/dist/bundle.js +15 -0
  120. package/dist/cli/args.d.ts +85 -0
  121. package/dist/cli/args.js +408 -0
  122. package/dist/cli/bootstrap.d.ts +18 -0
  123. package/dist/cli/bootstrap.js +399 -0
  124. package/dist/cli/compose-providers.d.ts +37 -0
  125. package/dist/cli/compose-providers.js +107 -0
  126. package/dist/cli/compose-session.d.ts +72 -0
  127. package/dist/cli/compose-session.js +370 -0
  128. package/dist/cli/compose-store.d.ts +24 -0
  129. package/dist/cli/compose-store.js +125 -0
  130. package/dist/cli/compose.d.ts +108 -0
  131. package/dist/cli/compose.js +221 -0
  132. package/dist/cli/default-model.d.ts +16 -0
  133. package/dist/cli/default-model.js +24 -0
  134. package/dist/cli/deps.d.ts +207 -0
  135. package/dist/cli/deps.js +12 -0
  136. package/dist/cli/exit-codes.d.ts +29 -0
  137. package/dist/cli/exit-codes.js +40 -0
  138. package/dist/cli/main.d.ts +27 -0
  139. package/dist/cli/main.js +177 -0
  140. package/dist/cli/runtime.d.ts +90 -0
  141. package/dist/cli/runtime.js +8 -0
  142. package/dist/cli/startup-screen.d.ts +15 -0
  143. package/dist/cli/startup-screen.js +56 -0
  144. package/dist/cli/startup-steps.d.ts +35 -0
  145. package/dist/cli/startup-steps.js +202 -0
  146. package/dist/cli/subcommands/auth.d.ts +12 -0
  147. package/dist/cli/subcommands/auth.js +91 -0
  148. package/dist/cli/subcommands/config.d.ts +53 -0
  149. package/dist/cli/subcommands/config.js +277 -0
  150. package/dist/cli/subcommands/context.d.ts +21 -0
  151. package/dist/cli/subcommands/context.js +42 -0
  152. package/dist/cli/subcommands/doctor.d.ts +11 -0
  153. package/dist/cli/subcommands/doctor.js +246 -0
  154. package/dist/cli/subcommands/init.d.ts +6 -0
  155. package/dist/cli/subcommands/init.js +22 -0
  156. package/dist/cli/subcommands/model-meta.d.ts +16 -0
  157. package/dist/cli/subcommands/model-meta.js +54 -0
  158. package/dist/cli/subcommands/models-cache-probe.d.ts +34 -0
  159. package/dist/cli/subcommands/models-cache-probe.js +190 -0
  160. package/dist/cli/subcommands/models-discover.d.ts +46 -0
  161. package/dist/cli/subcommands/models-discover.js +232 -0
  162. package/dist/cli/subcommands/models.d.ts +40 -0
  163. package/dist/cli/subcommands/models.js +152 -0
  164. package/dist/cli/subcommands/providers-list.d.ts +8 -0
  165. package/dist/cli/subcommands/providers-list.js +97 -0
  166. package/dist/cli/subcommands/providers-plan.d.ts +79 -0
  167. package/dist/cli/subcommands/providers-plan.js +215 -0
  168. package/dist/cli/subcommands/providers.d.ts +27 -0
  169. package/dist/cli/subcommands/providers.js +433 -0
  170. package/dist/cli/subcommands/sessions.d.ts +11 -0
  171. package/dist/cli/subcommands/sessions.js +100 -0
  172. package/dist/codemode/capability.d.ts +37 -0
  173. package/dist/codemode/capability.js +55 -0
  174. package/dist/codemode/declarations.d.ts +44 -0
  175. package/dist/codemode/declarations.js +111 -0
  176. package/dist/codemode/host-side.d.ts +59 -0
  177. package/dist/codemode/host-side.js +253 -0
  178. package/dist/codemode/modes.d.ts +23 -0
  179. package/dist/codemode/modes.js +40 -0
  180. package/dist/codemode/protocol.d.ts +91 -0
  181. package/dist/codemode/protocol.js +114 -0
  182. package/dist/codemode/sandbox-entry.d.ts +25 -0
  183. package/dist/codemode/sandbox-entry.js +323 -0
  184. package/dist/codemode/store.d.ts +26 -0
  185. package/dist/codemode/store.js +53 -0
  186. package/dist/codemode/tool.d.ts +105 -0
  187. package/dist/codemode/tool.js +283 -0
  188. package/dist/compaction/branch-summary.d.ts +30 -0
  189. package/dist/compaction/branch-summary.js +79 -0
  190. package/dist/compaction/breaker.d.ts +32 -0
  191. package/dist/compaction/breaker.js +65 -0
  192. package/dist/compaction/cut-point.d.ts +23 -0
  193. package/dist/compaction/cut-point.js +70 -0
  194. package/dist/compaction/estimate.d.ts +30 -0
  195. package/dist/compaction/estimate.js +114 -0
  196. package/dist/compaction/prune-tier.d.ts +31 -0
  197. package/dist/compaction/prune-tier.js +83 -0
  198. package/dist/compaction/serialize.d.ts +20 -0
  199. package/dist/compaction/serialize.js +115 -0
  200. package/dist/compaction/summarize-tier.d.ts +111 -0
  201. package/dist/compaction/summarize-tier.js +305 -0
  202. package/dist/config/auth-file.d.ts +39 -0
  203. package/dist/config/auth-file.js +92 -0
  204. package/dist/config/context-files.d.ts +30 -0
  205. package/dist/config/context-files.js +77 -0
  206. package/dist/config/init.d.ts +30 -0
  207. package/dist/config/init.js +92 -0
  208. package/dist/config/json-schema.d.ts +14 -0
  209. package/dist/config/json-schema.js +182 -0
  210. package/dist/config/load.d.ts +45 -0
  211. package/dist/config/load.js +97 -0
  212. package/dist/config/merge.d.ts +73 -0
  213. package/dist/config/merge.js +248 -0
  214. package/dist/config/paths.d.ts +38 -0
  215. package/dist/config/paths.js +108 -0
  216. package/dist/config/profile.d.ts +27 -0
  217. package/dist/config/profile.js +65 -0
  218. package/dist/config/schema.d.ts +34 -0
  219. package/dist/config/schema.js +476 -0
  220. package/dist/config/trust.d.ts +42 -0
  221. package/dist/config/trust.js +122 -0
  222. package/dist/config/types.d.ts +190 -0
  223. package/dist/config/types.js +29 -0
  224. package/dist/config/write.d.ts +10 -0
  225. package/dist/config/write.js +25 -0
  226. package/dist/errors.d.ts +28 -0
  227. package/dist/errors.js +30 -0
  228. package/dist/hooks/config.d.ts +49 -0
  229. package/dist/hooks/config.js +102 -0
  230. package/dist/hooks/dispatcher.d.ts +41 -0
  231. package/dist/hooks/dispatcher.js +104 -0
  232. package/dist/hooks/matcher.d.ts +22 -0
  233. package/dist/hooks/matcher.js +108 -0
  234. package/dist/hooks/protocol.d.ts +33 -0
  235. package/dist/hooks/protocol.js +240 -0
  236. package/dist/hooks/runner.d.ts +30 -0
  237. package/dist/hooks/runner.js +143 -0
  238. package/dist/hooks/types.d.ts +147 -0
  239. package/dist/hooks/types.js +20 -0
  240. package/dist/host/api-impl.d.ts +75 -0
  241. package/dist/host/api-impl.js +173 -0
  242. package/dist/host/loader.d.ts +31 -0
  243. package/dist/host/loader.js +147 -0
  244. package/dist/host/types.d.ts +169 -0
  245. package/dist/host/types.js +14 -0
  246. package/dist/host.d.ts +5 -0
  247. package/dist/host.js +4 -0
  248. package/dist/index.d.ts +41 -0
  249. package/dist/index.js +28 -0
  250. package/dist/modes/commands-core.d.ts +44 -0
  251. package/dist/modes/commands-core.js +171 -0
  252. package/dist/modes/image-input.d.ts +27 -0
  253. package/dist/modes/image-input.js +78 -0
  254. package/dist/modes/interactive/approval-dialog.d.ts +48 -0
  255. package/dist/modes/interactive/approval-dialog.js +202 -0
  256. package/dist/modes/interactive/commands.d.ts +41 -0
  257. package/dist/modes/interactive/commands.js +201 -0
  258. package/dist/modes/interactive/completion.d.ts +53 -0
  259. package/dist/modes/interactive/completion.js +157 -0
  260. package/dist/modes/interactive/interactive-mode.d.ts +46 -0
  261. package/dist/modes/interactive/interactive-mode.js +491 -0
  262. package/dist/modes/interactive/key-dispatch.d.ts +29 -0
  263. package/dist/modes/interactive/key-dispatch.js +107 -0
  264. package/dist/modes/interactive/line/line-editor.d.ts +50 -0
  265. package/dist/modes/interactive/line/line-editor.js +232 -0
  266. package/dist/modes/interactive/line/line-mode.d.ts +20 -0
  267. package/dist/modes/interactive/line/line-mode.js +218 -0
  268. package/dist/modes/interactive/line/line-render.d.ts +35 -0
  269. package/dist/modes/interactive/line/line-render.js +171 -0
  270. package/dist/modes/interactive/line/paste-state.d.ts +26 -0
  271. package/dist/modes/interactive/line/paste-state.js +72 -0
  272. package/dist/modes/interactive/message-view.d.ts +77 -0
  273. package/dist/modes/interactive/message-view.js +269 -0
  274. package/dist/modes/interactive/pickers.d.ts +42 -0
  275. package/dist/modes/interactive/pickers.js +115 -0
  276. package/dist/modes/interactive/startup-ui.d.ts +33 -0
  277. package/dist/modes/interactive/startup-ui.js +268 -0
  278. package/dist/modes/interactive/status-bar.d.ts +48 -0
  279. package/dist/modes/interactive/status-bar.js +139 -0
  280. package/dist/modes/interactive/tool-view.d.ts +95 -0
  281. package/dist/modes/interactive/tool-view.js +344 -0
  282. package/dist/modes/print/json-event.d.ts +15 -0
  283. package/dist/modes/print/json-event.js +39 -0
  284. package/dist/modes/print/print-mode.d.ts +17 -0
  285. package/dist/modes/print/print-mode.js +107 -0
  286. package/dist/modes/rpc/commands.d.ts +40 -0
  287. package/dist/modes/rpc/commands.js +263 -0
  288. package/dist/modes/rpc/jsonl.d.ts +16 -0
  289. package/dist/modes/rpc/jsonl.js +55 -0
  290. package/dist/modes/rpc/rpc-mode.d.ts +22 -0
  291. package/dist/modes/rpc/rpc-mode.js +153 -0
  292. package/dist/modes/session-report.d.ts +55 -0
  293. package/dist/modes/session-report.js +278 -0
  294. package/dist/modes/shared.d.ts +13 -0
  295. package/dist/modes/shared.js +52 -0
  296. package/dist/modes/startup-ui-text.d.ts +16 -0
  297. package/dist/modes/startup-ui-text.js +103 -0
  298. package/dist/permissions/broker.d.ts +47 -0
  299. package/dist/permissions/broker.js +107 -0
  300. package/dist/permissions/dangerous.d.ts +47 -0
  301. package/dist/permissions/dangerous.js +370 -0
  302. package/dist/permissions/pipeline.d.ts +51 -0
  303. package/dist/permissions/pipeline.js +181 -0
  304. package/dist/permissions/preview.d.ts +43 -0
  305. package/dist/permissions/preview.js +463 -0
  306. package/dist/permissions/rules.d.ts +58 -0
  307. package/dist/permissions/rules.js +249 -0
  308. package/dist/permissions/types.d.ts +100 -0
  309. package/dist/permissions/types.js +18 -0
  310. package/dist/rpc.d.ts +173 -0
  311. package/dist/rpc.js +13 -0
  312. package/dist/sdk.d.ts +98 -0
  313. package/dist/sdk.js +195 -0
  314. package/dist/session/manager.d.ts +70 -0
  315. package/dist/session/manager.js +278 -0
  316. package/dist/session/migrate.d.ts +19 -0
  317. package/dist/session/migrate.js +53 -0
  318. package/dist/session/projection.d.ts +50 -0
  319. package/dist/session/projection.js +184 -0
  320. package/dist/session/store.d.ts +47 -0
  321. package/dist/session/store.js +210 -0
  322. package/dist/session/tree.d.ts +21 -0
  323. package/dist/session/tree.js +88 -0
  324. package/dist/session/types.d.ts +201 -0
  325. package/dist/session/types.js +18 -0
  326. package/dist/skills/discover.d.ts +60 -0
  327. package/dist/skills/discover.js +160 -0
  328. package/dist/skills/expand.d.ts +35 -0
  329. package/dist/skills/expand.js +46 -0
  330. package/dist/skills/frontmatter.d.ts +27 -0
  331. package/dist/skills/frontmatter.js +157 -0
  332. package/dist/skills/index-prompt.d.ts +13 -0
  333. package/dist/skills/index-prompt.js +42 -0
  334. package/dist/skills/templates.d.ts +52 -0
  335. package/dist/skills/templates.js +177 -0
  336. package/dist/tools/bash.d.ts +49 -0
  337. package/dist/tools/bash.js +222 -0
  338. package/dist/tools/edit-fuzzy.d.ts +36 -0
  339. package/dist/tools/edit-fuzzy.js +129 -0
  340. package/dist/tools/edit.d.ts +38 -0
  341. package/dist/tools/edit.js +241 -0
  342. package/dist/tools/file-mutex.d.ts +8 -0
  343. package/dist/tools/file-mutex.js +29 -0
  344. package/dist/tools/glob.d.ts +44 -0
  345. package/dist/tools/glob.js +217 -0
  346. package/dist/tools/grep.d.ts +39 -0
  347. package/dist/tools/grep.js +179 -0
  348. package/dist/tools/ignore.d.ts +40 -0
  349. package/dist/tools/ignore.js +174 -0
  350. package/dist/tools/image-file.d.ts +31 -0
  351. package/dist/tools/image-file.js +114 -0
  352. package/dist/tools/ls.d.ts +21 -0
  353. package/dist/tools/ls.js +96 -0
  354. package/dist/tools/output-accumulator.d.ts +48 -0
  355. package/dist/tools/output-accumulator.js +106 -0
  356. package/dist/tools/paths.d.ts +20 -0
  357. package/dist/tools/paths.js +58 -0
  358. package/dist/tools/presets.d.ts +71 -0
  359. package/dist/tools/presets.js +128 -0
  360. package/dist/tools/process-tree.d.ts +35 -0
  361. package/dist/tools/process-tree.js +125 -0
  362. package/dist/tools/read.d.ts +24 -0
  363. package/dist/tools/read.js +132 -0
  364. package/dist/tools/registry.d.ts +43 -0
  365. package/dist/tools/registry.js +106 -0
  366. package/dist/tools/shell.d.ts +38 -0
  367. package/dist/tools/shell.js +91 -0
  368. package/dist/tools/task.d.ts +29 -0
  369. package/dist/tools/task.js +107 -0
  370. package/dist/tools/todo.d.ts +28 -0
  371. package/dist/tools/todo.js +107 -0
  372. package/dist/tools/truncate.d.ts +44 -0
  373. package/dist/tools/truncate.js +175 -0
  374. package/dist/tools/types.d.ts +135 -0
  375. package/dist/tools/types.js +19 -0
  376. package/dist/tools/write.d.ts +20 -0
  377. package/dist/tools/write.js +84 -0
  378. package/dist/tui/ansi.d.ts +29 -0
  379. package/dist/tui/ansi.js +420 -0
  380. package/dist/tui/component.d.ts +38 -0
  381. package/dist/tui/component.js +13 -0
  382. package/dist/tui/components/box.d.ts +26 -0
  383. package/dist/tui/components/box.js +65 -0
  384. package/dist/tui/components/container.d.ts +14 -0
  385. package/dist/tui/components/container.js +39 -0
  386. package/dist/tui/components/editor-buffer.d.ts +67 -0
  387. package/dist/tui/components/editor-buffer.js +300 -0
  388. package/dist/tui/components/editor-paste.d.ts +29 -0
  389. package/dist/tui/components/editor-paste.js +64 -0
  390. package/dist/tui/components/editor.d.ts +114 -0
  391. package/dist/tui/components/editor.js +530 -0
  392. package/dist/tui/components/key-value.d.ts +29 -0
  393. package/dist/tui/components/key-value.js +48 -0
  394. package/dist/tui/components/loader.d.ts +35 -0
  395. package/dist/tui/components/loader.js +71 -0
  396. package/dist/tui/components/markdown.d.ts +90 -0
  397. package/dist/tui/components/markdown.js +462 -0
  398. package/dist/tui/components/meter.d.ts +29 -0
  399. package/dist/tui/components/meter.js +47 -0
  400. package/dist/tui/components/overlay.d.ts +24 -0
  401. package/dist/tui/components/overlay.js +52 -0
  402. package/dist/tui/components/select-list.d.ts +57 -0
  403. package/dist/tui/components/select-list.js +179 -0
  404. package/dist/tui/components/spacer.d.ts +11 -0
  405. package/dist/tui/components/spacer.js +16 -0
  406. package/dist/tui/components/text.d.ts +30 -0
  407. package/dist/tui/components/text.js +65 -0
  408. package/dist/tui/keybindings.d.ts +66 -0
  409. package/dist/tui/keybindings.js +120 -0
  410. package/dist/tui/keys.d.ts +38 -0
  411. package/dist/tui/keys.js +275 -0
  412. package/dist/tui/stdin-buffer.d.ts +41 -0
  413. package/dist/tui/stdin-buffer.js +206 -0
  414. package/dist/tui/terminal.d.ts +79 -0
  415. package/dist/tui/terminal.js +153 -0
  416. package/dist/tui/theme.d.ts +31 -0
  417. package/dist/tui/theme.js +199 -0
  418. package/dist/tui/tui.d.ts +103 -0
  419. package/dist/tui/tui.js +363 -0
  420. package/dist/tui/vt-screen.d.ts +46 -0
  421. package/dist/tui/vt-screen.js +251 -0
  422. package/dist/tui.d.ts +30 -0
  423. package/dist/tui.js +31 -0
  424. package/dist/version.d.ts +8 -0
  425. package/dist/version.js +24 -0
  426. package/docs/codemode.md +102 -0
  427. package/docs/hooks.md +196 -0
  428. package/docs/host-api.md +161 -0
  429. package/docs/providers.md +531 -0
  430. package/docs/rpc.md +253 -0
  431. package/docs/session-format.md +119 -0
  432. package/docs/tui.md +170 -0
  433. package/package.json +101 -4
@@ -0,0 +1,420 @@
1
+ /**
2
+ * ANSI 与列宽工具(设计 §12.1、§12.2)。[B4]
3
+ *
4
+ * - 列宽按字素簇(grapheme)计:东亚宽字符与 emoji 占 2 列,组合字符 / 零宽字符占 0 列,
5
+ * 控制字符占 0 列;CSI / OSC / APC / DCS 等转义序列不占列。
6
+ * - 宽度表自写(零依赖):东亚宽 / 全角区段 + Unicode 属性转义(`\p{Emoji_Presentation}` 等)。
7
+ * - 所有截断 / 切片在保留 SGR 样式的同时,于末尾补 `\x1b[0m`,保证「每行末尾重置样式」。
8
+ */
9
+ export const SGR_RESET = "\x1b[0m";
10
+ const segmenter = new Intl.Segmenter(undefined, { granularity: "grapheme" });
11
+ /** 东亚宽(W)与全角(F)区段,含常见 emoji 区块;按起点升序,二分查找。 */
12
+ const WIDE_RANGES = [
13
+ [0x1100, 0x115f],
14
+ [0x231a, 0x231b],
15
+ [0x2329, 0x232a],
16
+ [0x23e9, 0x23ec],
17
+ [0x23f0, 0x23f0],
18
+ [0x23f3, 0x23f3],
19
+ [0x25fd, 0x25fe],
20
+ [0x2614, 0x2615],
21
+ [0x2648, 0x2653],
22
+ [0x267f, 0x267f],
23
+ [0x2693, 0x2693],
24
+ [0x26a1, 0x26a1],
25
+ [0x26aa, 0x26ab],
26
+ [0x26bd, 0x26be],
27
+ [0x26c4, 0x26c5],
28
+ [0x26ce, 0x26ce],
29
+ [0x26d4, 0x26d4],
30
+ [0x26ea, 0x26ea],
31
+ [0x26f2, 0x26f3],
32
+ [0x26f5, 0x26f5],
33
+ [0x26fa, 0x26fa],
34
+ [0x26fd, 0x26fd],
35
+ [0x2705, 0x2705],
36
+ [0x270a, 0x270b],
37
+ [0x2728, 0x2728],
38
+ [0x274c, 0x274c],
39
+ [0x274e, 0x274e],
40
+ [0x2753, 0x2755],
41
+ [0x2757, 0x2757],
42
+ [0x2795, 0x2797],
43
+ [0x27b0, 0x27b0],
44
+ [0x27bf, 0x27bf],
45
+ [0x2b1b, 0x2b1c],
46
+ [0x2b50, 0x2b50],
47
+ [0x2b55, 0x2b55],
48
+ [0x2e80, 0x303e],
49
+ [0x3041, 0x33ff],
50
+ [0x3400, 0x4dbf],
51
+ [0x4e00, 0x9fff],
52
+ [0xa000, 0xa4cf],
53
+ [0xa960, 0xa97f],
54
+ [0xac00, 0xd7a3],
55
+ [0xf900, 0xfaff],
56
+ [0xfe10, 0xfe19],
57
+ [0xfe30, 0xfe6f],
58
+ [0xff00, 0xff60],
59
+ [0xffe0, 0xffe6],
60
+ [0x16fe0, 0x16fe4],
61
+ [0x17000, 0x18aff],
62
+ [0x1b000, 0x1b2ff],
63
+ [0x1f004, 0x1f004],
64
+ [0x1f0cf, 0x1f0cf],
65
+ [0x1f18e, 0x1f18e],
66
+ [0x1f191, 0x1f19a],
67
+ [0x1f1e6, 0x1f1ff],
68
+ [0x1f200, 0x1f202],
69
+ [0x1f210, 0x1f23b],
70
+ [0x1f240, 0x1f248],
71
+ [0x1f250, 0x1f251],
72
+ [0x1f260, 0x1f265],
73
+ [0x1f300, 0x1f64f],
74
+ [0x1f680, 0x1f6ff],
75
+ [0x1f7e0, 0x1f7eb],
76
+ [0x1f90c, 0x1f9ff],
77
+ [0x1fa70, 0x1faff],
78
+ [0x20000, 0x2fffd],
79
+ [0x30000, 0x3fffd],
80
+ ];
81
+ function inWideTable(cp) {
82
+ let lo = 0;
83
+ let hi = WIDE_RANGES.length - 1;
84
+ while (lo <= hi) {
85
+ const mid = (lo + hi) >> 1;
86
+ const range = WIDE_RANGES[mid];
87
+ if (cp < range[0])
88
+ hi = mid - 1;
89
+ else if (cp > range[1])
90
+ lo = mid + 1;
91
+ else
92
+ return true;
93
+ }
94
+ return false;
95
+ }
96
+ const ZERO_WIDTH_RE = /^[\p{Mn}\p{Me}\p{Cf}]$/u;
97
+ const EMOJI_PRESENTATION_RE = /^\p{Emoji_Presentation}$/u;
98
+ const PICTOGRAPHIC_RE = /^\p{Extended_Pictographic}$/u;
99
+ /** 单个码点的列宽(0 / 1 / 2)。 */
100
+ export function codePointWidth(cp) {
101
+ if (cp < 0x20 || (cp >= 0x7f && cp < 0xa0))
102
+ return 0;
103
+ if (cp < 0x300)
104
+ return 1;
105
+ const ch = String.fromCodePoint(cp);
106
+ if (ZERO_WIDTH_RE.test(ch))
107
+ return 0;
108
+ if (inWideTable(cp) || EMOJI_PRESENTATION_RE.test(ch))
109
+ return 2;
110
+ return 1;
111
+ }
112
+ /** 一个字素簇的列宽:首码点决定基础宽度;VS16(U+FE0F)把文本型 emoji 升为 2 列。 */
113
+ export function graphemeWidth(grapheme) {
114
+ const first = grapheme.codePointAt(0);
115
+ if (first === undefined)
116
+ return 0;
117
+ if (grapheme.length === 1)
118
+ return codePointWidth(first);
119
+ const base = codePointWidth(first);
120
+ if (base === 0) {
121
+ // 孤立的组合字符:取后续码点中第一个非零宽者
122
+ for (const ch of grapheme) {
123
+ const w = codePointWidth(ch.codePointAt(0));
124
+ if (w > 0)
125
+ return w;
126
+ }
127
+ return 0;
128
+ }
129
+ if (base === 1 && grapheme.includes("\uFE0F")) {
130
+ const firstChar = String.fromCodePoint(first);
131
+ if (PICTOGRAPHIC_RE.test(firstChar))
132
+ return 2;
133
+ }
134
+ return base;
135
+ }
136
+ /** 从 i 起的转义序列长度;不是转义序列返回 0。未终止的序列吃到字符串末尾。 */
137
+ export function escapeLengthAt(s, i) {
138
+ if (s.charCodeAt(i) !== 0x1b)
139
+ return 0;
140
+ const next = s[i + 1];
141
+ if (next === undefined)
142
+ return 1;
143
+ if (next === "[") {
144
+ let j = i + 2;
145
+ while (j < s.length) {
146
+ const c = s.charCodeAt(j);
147
+ if (c >= 0x40 && c <= 0x7e)
148
+ return j - i + 1;
149
+ j++;
150
+ }
151
+ return s.length - i;
152
+ }
153
+ if (next === "]" || next === "_" || next === "P" || next === "^" || next === "X") {
154
+ let j = i + 2;
155
+ while (j < s.length) {
156
+ const c = s.charCodeAt(j);
157
+ if (c === 0x07)
158
+ return j - i + 1;
159
+ if (c === 0x1b && s[j + 1] === "\\")
160
+ return j - i + 2;
161
+ j++;
162
+ }
163
+ return s.length - i;
164
+ }
165
+ return 2;
166
+ }
167
+ export function stripAnsi(s) {
168
+ if (!s.includes("\x1b"))
169
+ return s;
170
+ let out = "";
171
+ let i = 0;
172
+ while (i < s.length) {
173
+ const esc = escapeLengthAt(s, i);
174
+ if (esc > 0) {
175
+ i += esc;
176
+ continue;
177
+ }
178
+ out += s[i];
179
+ i++;
180
+ }
181
+ return out;
182
+ }
183
+ function isPlainAscii(s) {
184
+ for (let i = 0; i < s.length; i++) {
185
+ const c = s.charCodeAt(i);
186
+ if (c < 0x20 || c > 0x7e)
187
+ return false;
188
+ }
189
+ return true;
190
+ }
191
+ /** 字符串(不含转义序列)的列宽。 */
192
+ function textWidth(text) {
193
+ if (isPlainAscii(text))
194
+ return text.length;
195
+ let width = 0;
196
+ for (const { segment } of segmenter.segment(text))
197
+ width += graphemeWidth(segment);
198
+ return width;
199
+ }
200
+ /** 可见列宽:跳过 ANSI 转义序列,按字素簇计宽。 */
201
+ export function visibleWidth(s) {
202
+ if (isPlainAscii(s))
203
+ return s.length;
204
+ return textWidth(stripAnsi(s));
205
+ }
206
+ function* pieces(s) {
207
+ let i = 0;
208
+ while (i < s.length) {
209
+ const esc = escapeLengthAt(s, i);
210
+ if (esc > 0) {
211
+ yield { text: s.slice(i, i + esc), width: 0, escape: true };
212
+ i += esc;
213
+ continue;
214
+ }
215
+ let j = i;
216
+ while (j < s.length && s.charCodeAt(j) !== 0x1b)
217
+ j++;
218
+ const run = s.slice(i, j);
219
+ if (isPlainAscii(run)) {
220
+ for (const ch of run)
221
+ yield { text: ch, width: 1, escape: false };
222
+ }
223
+ else {
224
+ for (const { segment } of segmenter.segment(run)) {
225
+ yield { text: segment, width: graphemeWidth(segment), escape: false };
226
+ }
227
+ }
228
+ i = j;
229
+ }
230
+ }
231
+ function isSgr(seq) {
232
+ return seq.startsWith("\x1b[") && seq.endsWith("m");
233
+ }
234
+ function isSgrReset(seq) {
235
+ return seq === "\x1b[0m" || seq === "\x1b[m";
236
+ }
237
+ /** 跟踪当前生效的 SGR 序列(遇到重置清空)。 */
238
+ class SgrState {
239
+ codes = [];
240
+ apply(seq) {
241
+ if (!isSgr(seq))
242
+ return;
243
+ if (isSgrReset(seq))
244
+ this.codes = [];
245
+ else
246
+ this.codes.push(seq);
247
+ }
248
+ get active() {
249
+ return this.codes.join("");
250
+ }
251
+ get any() {
252
+ return this.codes.length > 0;
253
+ }
254
+ }
255
+ /** 截断到不超过 width 列;超出时以 ellipsis 结尾;含样式时末尾补重置。 */
256
+ export function truncateToWidth(s, width, ellipsis = "…") {
257
+ if (width <= 0)
258
+ return "";
259
+ if (visibleWidth(s) <= width)
260
+ return s;
261
+ const ellWidth = visibleWidth(ellipsis);
262
+ const budget = ellWidth > width ? width : width - ellWidth;
263
+ let out = "";
264
+ let used = 0;
265
+ let styled = false;
266
+ for (const piece of pieces(s)) {
267
+ if (piece.escape) {
268
+ out += piece.text;
269
+ if (isSgr(piece.text))
270
+ styled = true;
271
+ continue;
272
+ }
273
+ if (used + piece.width > budget)
274
+ break;
275
+ out += piece.text;
276
+ used += piece.width;
277
+ }
278
+ if (ellWidth <= width)
279
+ out += ellipsis;
280
+ return styled ? out + SGR_RESET : out;
281
+ }
282
+ /**
283
+ * 取 [start, end) 列区间。开头补上 start 处生效的 SGR,末尾补重置;
284
+ * 被边界切开的宽字符用空格代替,保证结果恰好占 end - start 列(不足时按原内容)。
285
+ */
286
+ export function sliceByColumn(s, start, end) {
287
+ if (end <= start)
288
+ return "";
289
+ const state = new SgrState();
290
+ let out = "";
291
+ let col = 0;
292
+ let started = false;
293
+ let styled = false;
294
+ for (const piece of pieces(s)) {
295
+ if (piece.escape) {
296
+ if (!started && (col < start || isSgr(piece.text)))
297
+ state.apply(piece.text);
298
+ else if (col < end) {
299
+ out += piece.text;
300
+ if (isSgr(piece.text))
301
+ styled = true;
302
+ }
303
+ continue;
304
+ }
305
+ const next = col + piece.width;
306
+ if (next <= start) {
307
+ col = next;
308
+ continue;
309
+ }
310
+ if (col >= end)
311
+ break;
312
+ if (!started) {
313
+ started = true;
314
+ if (state.any) {
315
+ out = state.active + out;
316
+ styled = true;
317
+ }
318
+ }
319
+ if (col < start || next > end) {
320
+ // 宽字符跨边界:只保留落在区间内的列,用空格填充
321
+ const inside = Math.min(next, end) - Math.max(col, start);
322
+ out += " ".repeat(inside);
323
+ }
324
+ else {
325
+ out += piece.text;
326
+ }
327
+ col = next;
328
+ }
329
+ return styled ? out + SGR_RESET : out;
330
+ }
331
+ /** 右侧补空格到 width 列(已超出则原样返回)。 */
332
+ export function padToWidth(s, width) {
333
+ const w = visibleWidth(s);
334
+ return w >= width ? s : s + " ".repeat(width - w);
335
+ }
336
+ /** 自动换行:按空白断词,超长词按字素断开;样式跨行延续(行尾重置、下一行开头恢复)。 */
337
+ export function wrapTextWithAnsi(text, width) {
338
+ if (width <= 0)
339
+ return [""];
340
+ const result = [];
341
+ const state = new SgrState();
342
+ for (const logical of text.split("\n")) {
343
+ wrapLogicalLine(logical, width, state, result);
344
+ }
345
+ return result;
346
+ }
347
+ function wrapLogicalLine(line, width, state, out) {
348
+ let current = state.active;
349
+ let currentWidth = 0;
350
+ let styledLine = state.any;
351
+ let pendingSpace = "";
352
+ let pendingSpaceWidth = 0;
353
+ let word = [];
354
+ let wordWidth = 0;
355
+ const flushLine = () => {
356
+ out.push(styledLine ? current + SGR_RESET : current);
357
+ current = state.active;
358
+ currentWidth = 0;
359
+ styledLine = state.any;
360
+ };
361
+ const appendPiece = (piece) => {
362
+ if (piece.escape) {
363
+ state.apply(piece.text);
364
+ if (isSgr(piece.text))
365
+ styledLine = true;
366
+ }
367
+ current += piece.text;
368
+ currentWidth += piece.width;
369
+ };
370
+ const flushWord = () => {
371
+ if (word.length === 0)
372
+ return;
373
+ // 放不下且整词不超过一行:换行再放;超过一行的长词直接在当前行开始硬断
374
+ const fits = currentWidth + pendingSpaceWidth + wordWidth <= width;
375
+ if (currentWidth > 0 && !fits && wordWidth <= width) {
376
+ flushLine();
377
+ pendingSpace = "";
378
+ pendingSpaceWidth = 0;
379
+ }
380
+ if (currentWidth > 0 || pendingSpaceWidth > 0) {
381
+ if (currentWidth + pendingSpaceWidth <= width) {
382
+ current += pendingSpace;
383
+ currentWidth += pendingSpaceWidth;
384
+ }
385
+ }
386
+ pendingSpace = "";
387
+ pendingSpaceWidth = 0;
388
+ for (const piece of word) {
389
+ if (!piece.escape && currentWidth + piece.width > width && currentWidth > 0)
390
+ flushLine();
391
+ appendPiece(piece);
392
+ }
393
+ word = [];
394
+ wordWidth = 0;
395
+ };
396
+ for (const piece of pieces(line)) {
397
+ if (piece.escape) {
398
+ word.push(piece);
399
+ continue;
400
+ }
401
+ if (piece.text === " ") {
402
+ flushWord();
403
+ pendingSpace += " ";
404
+ pendingSpaceWidth += 1;
405
+ continue;
406
+ }
407
+ if (piece.width === 2) {
408
+ // 宽字符(中日韩、emoji)之间都可断行
409
+ flushWord();
410
+ word.push(piece);
411
+ wordWidth = 2;
412
+ flushWord();
413
+ continue;
414
+ }
415
+ word.push(piece);
416
+ wordWidth += piece.width;
417
+ }
418
+ flushWord();
419
+ flushLine();
420
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * TUI 组件模型契约(设计 §12.1、§12.7)。[B0] 契约文件,组件库实现归 B4。
3
+ *
4
+ * 补全与偏差:
5
+ * - 设计的 `Theme` 写作 `bg(...)` 与 `bold/dim/italic/underline(s)`,此处展开为完整签名。
6
+ * - `SemanticColor` 取 §12.7 的 11 个语义色名。
7
+ * - 补全 `CURSOR_MARKER` 常量与 `isFocusable()` 判别函数(B4 的 tui.ts 与 B7 都要用)。
8
+ */
9
+ /** APC 序列;获焦组件在光标处输出它,TUI 据此摆硬件光标并在输出前剔除。 */
10
+ export declare const CURSOR_MARKER = "\u001B_ama:c\u0007";
11
+ export interface Component {
12
+ /** 每行可见宽 ≤ width;每行末尾重置样式。 */
13
+ render(width: number): string[];
14
+ /** 焦点组件收原始键数据。 */
15
+ handleInput?(data: string): void;
16
+ /** 主题 / 状态变化时清缓存。 */
17
+ invalidate(): void;
18
+ }
19
+ export interface Focusable {
20
+ focused: boolean;
21
+ }
22
+ export declare function isFocusable(component: Component): component is Component & Focusable;
23
+ export type SemanticColor = "text" | "dim" | "accent" | "success" | "warning" | "error" | "user" | "assistant" | "tool" | "border" | "code";
24
+ /** 0 = 无色(NO_COLOR);16_777_216 = truecolor。 */
25
+ export type ColorDepth = 0 | 16 | 256 | 16_777_216;
26
+ export interface ThemeCapabilities {
27
+ colors: ColorDepth;
28
+ }
29
+ export interface Theme {
30
+ readonly name: string;
31
+ fg(color: SemanticColor, text: string): string;
32
+ bg(color: SemanticColor, text: string): string;
33
+ bold(text: string): string;
34
+ dim(text: string): string;
35
+ italic(text: string): string;
36
+ underline(text: string): string;
37
+ readonly caps: ThemeCapabilities;
38
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * TUI 组件模型契约(设计 §12.1、§12.7)。[B0] 契约文件,组件库实现归 B4。
3
+ *
4
+ * 补全与偏差:
5
+ * - 设计的 `Theme` 写作 `bg(...)` 与 `bold/dim/italic/underline(s)`,此处展开为完整签名。
6
+ * - `SemanticColor` 取 §12.7 的 11 个语义色名。
7
+ * - 补全 `CURSOR_MARKER` 常量与 `isFocusable()` 判别函数(B4 的 tui.ts 与 B7 都要用)。
8
+ */
9
+ /** APC 序列;获焦组件在光标处输出它,TUI 据此摆硬件光标并在输出前剔除。 */
10
+ export const CURSOR_MARKER = "\x1b_ama:c\x07";
11
+ export function isFocusable(component) {
12
+ return typeof component.focused === "boolean";
13
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * 边框 / 内边距容器(设计 §12.1)。[B4]
3
+ *
4
+ * 子组件按内宽渲染后加圆角边框(可选标题,嵌在上边框)与内边距;宽度不足 4 列时退化为只加内边距。
5
+ * 焦点与键输入透传给子组件,所以可以直接把 `Box(SelectList)` 交给 `showOverlay`。
6
+ */
7
+ import { type Component, type Theme } from "../component.js";
8
+ export interface BoxOptions {
9
+ border?: boolean;
10
+ paddingX?: number;
11
+ paddingY?: number;
12
+ title?: string;
13
+ theme?: Theme;
14
+ }
15
+ export declare class Box implements Component {
16
+ readonly child: Component;
17
+ private readonly options;
18
+ constructor(child: Component, options?: BoxOptions);
19
+ /** 焦点与输入透传给子组件(覆盖层里常用 Box 包一层)。 */
20
+ get focused(): boolean;
21
+ set focused(value: boolean);
22
+ handleInput(data: string): void;
23
+ render(width: number): string[];
24
+ private topBorder;
25
+ invalidate(): void;
26
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * 边框 / 内边距容器(设计 §12.1)。[B4]
3
+ *
4
+ * 子组件按内宽渲染后加圆角边框(可选标题,嵌在上边框)与内边距;宽度不足 4 列时退化为只加内边距。
5
+ * 焦点与键输入透传给子组件,所以可以直接把 `Box(SelectList)` 交给 `showOverlay`。
6
+ */
7
+ import { isFocusable } from "../component.js";
8
+ import { padToWidth, truncateToWidth, visibleWidth } from "../ansi.js";
9
+ export class Box {
10
+ child;
11
+ options;
12
+ constructor(child, options = {}) {
13
+ this.child = child;
14
+ this.options = options;
15
+ }
16
+ /** 焦点与输入透传给子组件(覆盖层里常用 Box 包一层)。 */
17
+ get focused() {
18
+ return isFocusable(this.child) ? this.child.focused : false;
19
+ }
20
+ set focused(value) {
21
+ if (isFocusable(this.child))
22
+ this.child.focused = value;
23
+ }
24
+ handleInput(data) {
25
+ this.child.handleInput?.(data);
26
+ }
27
+ render(width) {
28
+ const border = this.options.border !== false && width >= 4;
29
+ const padX = this.options.paddingX ?? 1;
30
+ const padY = this.options.paddingY ?? 0;
31
+ const frame = border ? 2 : 0;
32
+ const inner = Math.max(1, width - frame - padX * 2);
33
+ const body = this.child.render(inner);
34
+ const color = (s) => this.options.theme ? this.options.theme.fg("border", s) : s;
35
+ const pad = " ".repeat(padX);
36
+ const contentWidth = Math.max(0, width - frame);
37
+ const rows = [];
38
+ const emptyRow = " ".repeat(contentWidth);
39
+ for (let i = 0; i < padY; i++)
40
+ rows.push(emptyRow);
41
+ for (const line of body) {
42
+ rows.push(padToWidth(pad + truncateToWidth(line, inner), contentWidth));
43
+ }
44
+ for (let i = 0; i < padY; i++)
45
+ rows.push(emptyRow);
46
+ if (!border)
47
+ return rows;
48
+ const lines = [this.topBorder(width, color)];
49
+ for (const row of rows)
50
+ lines.push(color("│") + row + color("│"));
51
+ lines.push(color("╰" + "─".repeat(width - 2) + "╯"));
52
+ return lines;
53
+ }
54
+ topBorder(width, color) {
55
+ const title = this.options.title;
56
+ if (title === undefined || title === "")
57
+ return color("╭" + "─".repeat(width - 2) + "╮");
58
+ const label = truncateToWidth(` ${title} `, width - 4);
59
+ const rest = Math.max(0, width - 3 - visibleWidth(label));
60
+ return color("╭─") + label + color("─".repeat(rest) + "╮");
61
+ }
62
+ invalidate() {
63
+ this.child.invalidate();
64
+ }
65
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 纵向容器(设计 §12.1):子组件的行按顺序拼接;无布局引擎。[B4]
3
+ */
4
+ import type { Component } from "../component.js";
5
+ export declare class Container implements Component {
6
+ readonly children: Component[];
7
+ addChild(child: Component): void;
8
+ /** 插到 before 之前;before 不在容器内则追加到末尾。 */
9
+ insertBefore(child: Component, before: Component): void;
10
+ removeChild(child: Component): boolean;
11
+ clear(): void;
12
+ render(width: number): string[];
13
+ invalidate(): void;
14
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * 纵向容器(设计 §12.1):子组件的行按顺序拼接;无布局引擎。[B4]
3
+ */
4
+ export class Container {
5
+ children = [];
6
+ addChild(child) {
7
+ this.children.push(child);
8
+ }
9
+ /** 插到 before 之前;before 不在容器内则追加到末尾。 */
10
+ insertBefore(child, before) {
11
+ const index = this.children.indexOf(before);
12
+ if (index === -1)
13
+ this.children.push(child);
14
+ else
15
+ this.children.splice(index, 0, child);
16
+ }
17
+ removeChild(child) {
18
+ const index = this.children.indexOf(child);
19
+ if (index === -1)
20
+ return false;
21
+ this.children.splice(index, 1);
22
+ return true;
23
+ }
24
+ clear() {
25
+ this.children.length = 0;
26
+ }
27
+ render(width) {
28
+ const lines = [];
29
+ for (const child of this.children) {
30
+ for (const line of child.render(width))
31
+ lines.push(line);
32
+ }
33
+ return lines;
34
+ }
35
+ invalidate() {
36
+ for (const child of this.children)
37
+ child.invalidate();
38
+ }
39
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * 编辑器文本缓冲(设计 §12.4):行 / 光标 / 撤销栈(50 步)/ 单词导航 / 不可分割段。[B4]
3
+ *
4
+ * - 光标列是该行内的 UTF-16 下标,移动与删除按字素簇进行(emoji、组合字符不会被切开)。
5
+ * - 不可分割段(大粘贴折叠标记)由 `atomic` 回调按行给出区间:光标不会停在段内,
6
+ * 退格 / 删除 / 删词把整段一起删掉,单词导航把整段当作一个词。
7
+ * - 撤销:每次编辑前存快照;连续输入同类字符合并为一步;上限 50 步。
8
+ * - 不做选区(无鼠标、无 kill ring,§12.9)。
9
+ */
10
+ export interface Position {
11
+ line: number;
12
+ col: number;
13
+ }
14
+ export type AtomicRanges = (line: string) => ReadonlyArray<readonly [number, number]>;
15
+ export interface EditorBufferOptions {
16
+ undoLimit?: number;
17
+ atomic?: AtomicRanges;
18
+ }
19
+ export declare class EditorBuffer {
20
+ private lines;
21
+ private cur;
22
+ private undoStack;
23
+ private lastKind;
24
+ private readonly undoLimit;
25
+ private readonly atomic;
26
+ constructor(options?: EditorBufferOptions);
27
+ get cursor(): Position;
28
+ getLines(): readonly string[];
29
+ getText(): string;
30
+ isEmpty(): boolean;
31
+ get undoDepth(): number;
32
+ /** 替换全部文本,光标到末尾。recordUndo=false 时不进撤销栈(历史浏览、提交清空)。 */
33
+ setText(text: string, recordUndo?: boolean): void;
34
+ /** 清空并丢弃撤销历史。 */
35
+ reset(): void;
36
+ setCursor(pos: Position): void;
37
+ /** 插入文本(可含换行)。 */
38
+ insert(text: string): void;
39
+ newLine(): void;
40
+ backspace(): void;
41
+ deleteForward(): void;
42
+ moveLeft(): void;
43
+ moveRight(): void;
44
+ moveLineStart(): void;
45
+ moveLineEnd(): void;
46
+ moveWordLeft(): void;
47
+ moveWordRight(): void;
48
+ deleteWordBackward(): void;
49
+ deleteWordForward(): void;
50
+ deleteToLineStart(): void;
51
+ deleteToLineEnd(): void;
52
+ undo(): boolean;
53
+ /** 光标所在行内、光标前的文本(补全提供者用)。 */
54
+ textBeforeCursor(): string;
55
+ /** 把当前行 [from, cursor) 替换为 text(补全接受)。 */
56
+ replaceBeforeCursor(from: number, text: string): void;
57
+ private deleteRange;
58
+ private snapshot;
59
+ private atomicAt;
60
+ private snapOutOfAtomic;
61
+ /** 光标左侧的停靠点(字素簇或整段不可分割段)。 */
62
+ private prevStop;
63
+ private nextStop;
64
+ private classAt;
65
+ private wordStartBefore;
66
+ private wordEndAfter;
67
+ }