@lotagate/cli 0.1.20 → 0.1.22

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 (490) hide show
  1. package/dist/application/agent/agent-history.d.ts +3 -0
  2. package/dist/application/agent/agent-history.js +81 -0
  3. package/dist/application/agent/agent-input-context.d.ts +9 -0
  4. package/dist/application/agent/agent-input-context.js +12 -0
  5. package/dist/application/agent/agent-limit.d.ts +3 -0
  6. package/dist/application/agent/agent-limit.js +12 -0
  7. package/dist/application/agent/agent-run-tracker.d.ts +30 -0
  8. package/dist/application/agent/agent-run-tracker.js +68 -0
  9. package/dist/application/agent/agent-session-store.d.ts +19 -0
  10. package/dist/application/agent/agent-session-store.js +74 -0
  11. package/dist/application/agent/capability-profile.d.ts +37 -0
  12. package/dist/application/agent/capability-profile.js +13 -0
  13. package/dist/application/agent/cli-agent-execution-service.d.ts +81 -0
  14. package/dist/application/agent/cli-agent-execution-service.js +279 -0
  15. package/dist/application/agent/context-compaction-persistence.d.ts +8 -0
  16. package/dist/application/agent/context-compaction-persistence.js +27 -0
  17. package/dist/application/agent/context-compaction.d.ts +20 -0
  18. package/dist/application/agent/context-compaction.js +114 -0
  19. package/dist/application/agent/prompt-data-safety.d.ts +14 -0
  20. package/dist/application/agent/prompt-data-safety.js +38 -0
  21. package/dist/application/agent/safe-system-prompt.d.ts +3 -0
  22. package/dist/application/agent/safe-system-prompt.js +19 -0
  23. package/dist/application/agent/scoped-tool-executor.d.ts +13 -0
  24. package/dist/application/agent/scoped-tool-executor.js +32 -0
  25. package/dist/application/agent/system-prompt-builder.d.ts +14 -0
  26. package/dist/application/agent/system-prompt-builder.js +199 -0
  27. package/dist/application/agent/tool-catalog.d.ts +14 -0
  28. package/dist/application/agent/tool-catalog.js +30 -0
  29. package/dist/application/agent/tool-display.d.ts +6 -0
  30. package/dist/application/agent/tool-display.js +59 -0
  31. package/dist/application/agent/tool-hook-lifecycle.d.ts +19 -0
  32. package/dist/application/agent/tool-hook-lifecycle.js +85 -0
  33. package/dist/application/auth/authentication-service.d.ts +20 -0
  34. package/dist/application/auth/authentication-service.js +44 -0
  35. package/dist/application/chat/chat-service.d.ts +12 -0
  36. package/dist/application/chat/chat-service.js +19 -0
  37. package/dist/application/chat/pending-attachment-store.d.ts +12 -0
  38. package/dist/application/chat/pending-attachment-store.js +28 -0
  39. package/dist/application/commands/application-command-executor.d.ts +20 -0
  40. package/dist/application/commands/application-command-executor.js +66 -0
  41. package/dist/application/commands/cli-args.d.ts +6 -0
  42. package/dist/application/commands/cli-args.js +43 -0
  43. package/dist/application/commands/cli-command-services.d.ts +16 -0
  44. package/dist/application/commands/cli-command-services.js +405 -0
  45. package/dist/application/commands/command-catalog.d.ts +6 -0
  46. package/dist/application/commands/command-catalog.js +159 -0
  47. package/dist/application/commands/command-contract.d.ts +58 -0
  48. package/dist/application/commands/command-contract.js +1 -0
  49. package/dist/application/commands/command-hints.d.ts +9 -0
  50. package/dist/application/commands/command-hints.js +17 -0
  51. package/dist/application/commands/command-output.d.ts +4 -0
  52. package/dist/application/commands/command-output.js +1 -0
  53. package/dist/application/commands/command-parser.d.ts +10 -0
  54. package/dist/application/commands/command-parser.js +155 -0
  55. package/dist/application/commands/command-presentation.d.ts +7 -0
  56. package/dist/application/commands/command-presentation.js +131 -0
  57. package/dist/application/commands/command-registry.d.ts +11 -0
  58. package/dist/application/commands/command-registry.js +64 -0
  59. package/dist/application/commands/command-runtime.d.ts +2 -0
  60. package/dist/application/commands/command-runtime.js +3 -0
  61. package/dist/application/commands/goal-command-handlers.d.ts +3 -0
  62. package/dist/application/commands/goal-command-handlers.js +120 -0
  63. package/dist/application/commands/media-command-handlers.d.ts +9 -0
  64. package/dist/application/commands/media-command-handlers.js +307 -0
  65. package/dist/application/commands/media-command-output.d.ts +11 -0
  66. package/dist/application/commands/media-command-output.js +8 -0
  67. package/dist/application/commands/runtime-command-handlers.d.ts +7 -0
  68. package/dist/application/commands/runtime-command-handlers.js +177 -0
  69. package/dist/application/commands/stream-output.d.ts +4 -0
  70. package/dist/application/commands/stream-output.js +10 -0
  71. package/dist/application/commands/utility-commands.d.ts +6 -0
  72. package/dist/application/commands/utility-commands.js +81 -0
  73. package/dist/application/config/execution-config.d.ts +4 -0
  74. package/dist/application/config/execution-config.js +6 -0
  75. package/dist/application/extensions/extension-list-contract.d.ts +13 -0
  76. package/dist/application/extensions/extension-list-contract.js +1 -0
  77. package/dist/application/extensions/extension-list-formatters.d.ts +31 -0
  78. package/dist/application/extensions/extension-list-formatters.js +98 -0
  79. package/dist/application/extensions/extension-list-output.d.ts +3 -0
  80. package/dist/application/extensions/extension-list-output.js +7 -0
  81. package/dist/application/extensions/plugin-contribution-registry.d.ts +15 -0
  82. package/dist/application/extensions/plugin-contribution-registry.js +80 -0
  83. package/dist/application/extensions/skill-scope-store.d.ts +23 -0
  84. package/dist/application/extensions/skill-scope-store.js +33 -0
  85. package/dist/application/formatting/compact-number.d.ts +2 -0
  86. package/dist/application/formatting/compact-number.js +18 -0
  87. package/dist/application/formatting/compact-table.d.ts +22 -0
  88. package/dist/application/formatting/compact-table.js +49 -0
  89. package/dist/application/media/video-operation-poller.d.ts +5 -0
  90. package/dist/application/media/video-operation-poller.js +42 -0
  91. package/dist/application/model/cached-model-catalog.d.ts +13 -0
  92. package/dist/application/model/cached-model-catalog.js +31 -0
  93. package/dist/application/model/initial-model-selection.d.ts +10 -0
  94. package/dist/application/model/initial-model-selection.js +11 -0
  95. package/dist/application/model/model-catalog-service.d.ts +6 -0
  96. package/dist/application/model/model-catalog-service.js +13 -0
  97. package/dist/application/model/model-context-window.d.ts +3 -0
  98. package/dist/application/model/model-context-window.js +23 -0
  99. package/dist/application/orchestration/cli-subagent-service.d.ts +70 -0
  100. package/dist/application/orchestration/cli-subagent-service.js +328 -0
  101. package/dist/application/orchestration/cli-turn-event-projector.d.ts +12 -0
  102. package/dist/application/orchestration/cli-turn-event-projector.js +81 -0
  103. package/dist/application/orchestration/cli-turn-events.d.ts +76 -0
  104. package/dist/application/orchestration/cli-turn-events.js +39 -0
  105. package/dist/application/orchestration/cli-turn-persistence.d.ts +6 -0
  106. package/dist/application/orchestration/cli-turn-persistence.js +14 -0
  107. package/dist/application/orchestration/goal-evaluator.d.ts +18 -0
  108. package/dist/application/orchestration/goal-evaluator.js +88 -0
  109. package/dist/application/orchestration/goal-input.d.ts +3 -0
  110. package/dist/application/orchestration/goal-input.js +19 -0
  111. package/dist/application/orchestration/goal-output.d.ts +2 -0
  112. package/dist/application/orchestration/goal-output.js +11 -0
  113. package/dist/application/orchestration/goal-runner.d.ts +22 -0
  114. package/dist/application/orchestration/goal-runner.js +153 -0
  115. package/dist/application/orchestration/goal-usage.d.ts +9 -0
  116. package/dist/application/orchestration/goal-usage.js +19 -0
  117. package/dist/application/orchestration/headless-agent-turn.d.ts +32 -0
  118. package/dist/application/orchestration/headless-agent-turn.js +82 -0
  119. package/dist/application/orchestration/plan-generator.d.ts +7 -0
  120. package/dist/application/orchestration/plan-generator.js +34 -0
  121. package/dist/application/orchestration/subagent-coordinator.d.ts +33 -0
  122. package/dist/application/orchestration/subagent-coordinator.js +28 -0
  123. package/dist/application/orchestration/subagent-handoff.d.ts +2 -0
  124. package/dist/application/orchestration/subagent-handoff.js +68 -0
  125. package/dist/application/orchestration/subagent-tool-executor.d.ts +12 -0
  126. package/dist/application/orchestration/subagent-tool-executor.js +93 -0
  127. package/dist/application/orchestration/task-assessment.d.ts +4 -0
  128. package/dist/application/orchestration/task-assessment.js +35 -0
  129. package/dist/application/orchestration/task-graph.d.ts +13 -0
  130. package/dist/application/orchestration/task-graph.js +56 -0
  131. package/dist/application/orchestration/task-scheduler.d.ts +18 -0
  132. package/dist/application/orchestration/task-scheduler.js +88 -0
  133. package/dist/application/project/project-trust-service.d.ts +13 -0
  134. package/dist/application/project/project-trust-service.js +74 -0
  135. package/dist/application/protocol/browser-host-tool-executor.d.ts +41 -0
  136. package/dist/application/protocol/browser-host-tool-executor.js +88 -0
  137. package/dist/application/protocol/desktop-agent-command.d.ts +9 -0
  138. package/dist/application/protocol/desktop-agent-command.js +663 -0
  139. package/dist/application/protocol/desktop-attachment-store.d.ts +16 -0
  140. package/dist/application/protocol/desktop-attachment-store.js +82 -0
  141. package/dist/application/protocol/desktop-command-catalog.d.ts +2 -0
  142. package/dist/application/protocol/desktop-command-catalog.js +19 -0
  143. package/dist/application/protocol/desktop-command-contract.d.ts +22 -0
  144. package/dist/application/protocol/desktop-command-contract.js +3 -0
  145. package/dist/application/protocol/desktop-command-executor.d.ts +16 -0
  146. package/dist/application/protocol/desktop-command-executor.js +47 -0
  147. package/dist/application/protocol/desktop-command-output.d.ts +15 -0
  148. package/dist/application/protocol/desktop-command-output.js +24 -0
  149. package/dist/application/protocol/desktop-execution-policy.d.ts +17 -0
  150. package/dist/application/protocol/desktop-execution-policy.js +49 -0
  151. package/dist/application/protocol/desktop-host-tool-executor.d.ts +57 -0
  152. package/dist/application/protocol/desktop-host-tool-executor.js +53 -0
  153. package/dist/application/protocol/desktop-orchestration-events.d.ts +5 -0
  154. package/dist/application/protocol/desktop-orchestration-events.js +37 -0
  155. package/dist/application/protocol/json-line-writer.d.ts +9 -0
  156. package/dist/application/protocol/json-line-writer.js +19 -0
  157. package/dist/application/protocol/jsonl-agent-command.d.ts +3 -0
  158. package/dist/application/protocol/jsonl-agent-command.js +97 -0
  159. package/dist/application/protocol/jsonl-protocol.d.ts +52 -0
  160. package/dist/application/protocol/jsonl-protocol.js +170 -0
  161. package/dist/application/security/desktop-tool-scope-policy.d.ts +3 -0
  162. package/dist/application/security/desktop-tool-scope-policy.js +52 -0
  163. package/dist/application/security/tool-action-risk-analyzer.d.ts +13 -0
  164. package/dist/application/security/tool-action-risk-analyzer.js +64 -0
  165. package/dist/application/security/tool-approval-service.d.ts +35 -0
  166. package/dist/application/security/tool-approval-service.js +97 -0
  167. package/dist/application/security/tool-risk-classifier.d.ts +11 -0
  168. package/dist/application/security/tool-risk-classifier.js +65 -0
  169. package/dist/application/security/workspace-permission-policy.d.ts +10 -0
  170. package/dist/application/security/workspace-permission-policy.js +50 -0
  171. package/dist/application/session/project-session-access.d.ts +8 -0
  172. package/dist/application/session/project-session-access.js +19 -0
  173. package/dist/application/session/session-compaction-service.d.ts +10 -0
  174. package/dist/application/session/session-compaction-service.js +43 -0
  175. package/dist/application/session/session-turn-lifecycle.d.ts +5 -0
  176. package/dist/application/session/session-turn-lifecycle.js +31 -0
  177. package/dist/application/workspace/workspace-file-index.d.ts +15 -0
  178. package/dist/application/workspace/workspace-file-index.js +60 -0
  179. package/dist/application/workspace/workspace-file-reference-resolver.d.ts +14 -0
  180. package/dist/application/workspace/workspace-file-reference-resolver.js +123 -0
  181. package/dist/application/workspace/workspace-instruction-loader.d.ts +8 -0
  182. package/dist/application/workspace/workspace-instruction-loader.js +55 -0
  183. package/dist/bootstrap/composition-root.d.ts +6 -0
  184. package/dist/bootstrap/composition-root.js +4 -0
  185. package/dist/bootstrap/global-cli-options.d.ts +6 -0
  186. package/dist/bootstrap/global-cli-options.js +29 -0
  187. package/dist/bootstrap/native-devtools-stub.d.ts +10 -0
  188. package/dist/bootstrap/native-devtools-stub.js +10 -0
  189. package/dist/bootstrap/native-entry.d.ts +1 -0
  190. package/dist/bootstrap/native-entry.js +6 -0
  191. package/dist/bootstrap/native-tiktoken.d.ts +4 -0
  192. package/dist/bootstrap/native-tiktoken.js +5 -0
  193. package/dist/bootstrap/runtime-factory.d.ts +35 -0
  194. package/dist/bootstrap/runtime-factory.js +44 -0
  195. package/dist/bootstrap/shutdown-manager.d.ts +10 -0
  196. package/dist/bootstrap/shutdown-manager.js +14 -0
  197. package/dist/bootstrap/startup-sequence.d.ts +5 -0
  198. package/dist/bootstrap/startup-sequence.js +10 -0
  199. package/dist/domain/auth/auth-profile.d.ts +14 -0
  200. package/dist/domain/auth/auth-profile.js +39 -0
  201. package/dist/domain/config/config-schema.d.ts +17 -0
  202. package/dist/domain/config/config-schema.js +105 -0
  203. package/dist/domain/errors/cli-command-hint.d.ts +5 -0
  204. package/dist/domain/errors/cli-command-hint.js +1 -0
  205. package/dist/domain/errors/cli-error.d.ts +35 -0
  206. package/dist/domain/errors/cli-error.js +129 -0
  207. package/dist/domain/errors/error-codes.d.ts +46 -0
  208. package/dist/domain/errors/error-codes.js +45 -0
  209. package/dist/domain/extensions/extension-scope.d.ts +3 -0
  210. package/dist/domain/extensions/extension-scope.js +23 -0
  211. package/dist/domain/extensions/extension-state.d.ts +5 -0
  212. package/dist/domain/extensions/extension-state.js +11 -0
  213. package/dist/domain/extensions/hook-manifest.d.ts +10 -0
  214. package/dist/domain/extensions/hook-manifest.js +23 -0
  215. package/dist/domain/extensions/mcp-config.d.ts +18 -0
  216. package/dist/domain/extensions/mcp-config.js +111 -0
  217. package/dist/domain/extensions/plugin-manifest.d.ts +11 -0
  218. package/dist/domain/extensions/plugin-manifest.js +43 -0
  219. package/dist/domain/extensions/skill-manifest.d.ts +10 -0
  220. package/dist/domain/extensions/skill-manifest.js +51 -0
  221. package/dist/domain/filesystem/file-change-diff.d.ts +21 -0
  222. package/dist/domain/filesystem/file-change-diff.js +60 -0
  223. package/dist/domain/media/gateway-media-contract.d.ts +23 -0
  224. package/dist/domain/media/gateway-media-contract.js +163 -0
  225. package/dist/domain/media/media-contract.d.ts +28 -0
  226. package/dist/domain/media/media-contract.js +1 -0
  227. package/dist/domain/media/media-execution-policy.d.ts +9 -0
  228. package/dist/domain/media/media-execution-policy.js +31 -0
  229. package/dist/domain/orchestration/goal.d.ts +58 -0
  230. package/dist/domain/orchestration/goal.js +113 -0
  231. package/dist/domain/orchestration/subagent-identity.d.ts +2 -0
  232. package/dist/domain/orchestration/subagent-identity.js +8 -0
  233. package/dist/domain/orchestration/subagent.d.ts +33 -0
  234. package/dist/domain/orchestration/subagent.js +1 -0
  235. package/dist/domain/orchestration/task.d.ts +31 -0
  236. package/dist/domain/orchestration/task.js +1 -0
  237. package/dist/domain/project/project-identity.d.ts +6 -0
  238. package/dist/domain/project/project-identity.js +4 -0
  239. package/dist/domain/runtime/assistant-delta-normalizer.d.ts +11 -0
  240. package/dist/domain/runtime/assistant-delta-normalizer.js +19 -0
  241. package/dist/domain/runtime/resource-limits.d.ts +60 -0
  242. package/dist/domain/runtime/resource-limits.js +60 -0
  243. package/dist/domain/session/attachment.d.ts +13 -0
  244. package/dist/domain/session/attachment.js +1 -0
  245. package/dist/domain/session/session-schema.d.ts +6 -0
  246. package/dist/domain/session/session-schema.js +28 -0
  247. package/dist/domain/session/session.d.ts +27 -0
  248. package/dist/domain/session/session.js +1 -0
  249. package/dist/domain/settings/settings-document.d.ts +8 -0
  250. package/dist/domain/settings/settings-document.js +36 -0
  251. package/dist/domain/validation/record-schema.d.ts +4 -0
  252. package/dist/domain/validation/record-schema.js +9 -0
  253. package/dist/domain/workspace/workspace-settings.d.ts +12 -0
  254. package/dist/domain/workspace/workspace-settings.js +44 -0
  255. package/dist/infrastructure/agent-sdk/agent-instance-factory.d.ts +22 -0
  256. package/dist/infrastructure/agent-sdk/agent-instance-factory.js +31 -0
  257. package/dist/infrastructure/agent-sdk/tool-calling-model-client.d.ts +11 -0
  258. package/dist/infrastructure/agent-sdk/tool-calling-model-client.js +447 -0
  259. package/dist/infrastructure/cache/cache-policy.d.ts +7 -0
  260. package/dist/infrastructure/cache/cache-policy.js +18 -0
  261. package/dist/infrastructure/cache/file-cache-store.d.ts +17 -0
  262. package/dist/infrastructure/cache/file-cache-store.js +121 -0
  263. package/dist/infrastructure/clipboard/clipboard-adapter-factory.d.ts +11 -0
  264. package/dist/infrastructure/clipboard/clipboard-adapter-factory.js +98 -0
  265. package/dist/infrastructure/clipboard/clipboard-policy.d.ts +8 -0
  266. package/dist/infrastructure/clipboard/clipboard-policy.js +19 -0
  267. package/dist/infrastructure/clipboard/clipboard-text-adapter-factory.d.ts +10 -0
  268. package/dist/infrastructure/clipboard/clipboard-text-adapter-factory.js +94 -0
  269. package/dist/infrastructure/clipboard/image-normalizer.d.ts +12 -0
  270. package/dist/infrastructure/clipboard/image-normalizer.js +78 -0
  271. package/dist/infrastructure/clipboard/windows-clipboard-adapter.d.ts +7 -0
  272. package/dist/infrastructure/clipboard/windows-clipboard-adapter.js +66 -0
  273. package/dist/infrastructure/clipboard/windows-clipboard-text-adapter.d.ts +7 -0
  274. package/dist/infrastructure/clipboard/windows-clipboard-text-adapter.js +70 -0
  275. package/dist/infrastructure/config/config-loader.d.ts +19 -0
  276. package/dist/infrastructure/config/config-loader.js +76 -0
  277. package/dist/infrastructure/config/environment-values.d.ts +2 -0
  278. package/dist/infrastructure/config/environment-values.js +7 -0
  279. package/dist/infrastructure/credentials/composite-credential-store.d.ts +11 -0
  280. package/dist/infrastructure/credentials/composite-credential-store.js +32 -0
  281. package/dist/infrastructure/credentials/encrypted-file-credential-store.d.ts +17 -0
  282. package/dist/infrastructure/credentials/encrypted-file-credential-store.js +181 -0
  283. package/dist/infrastructure/credentials/environment-credential-store.d.ts +11 -0
  284. package/dist/infrastructure/credentials/environment-credential-store.js +37 -0
  285. package/dist/infrastructure/credentials/secret-input.d.ts +7 -0
  286. package/dist/infrastructure/credentials/secret-input.js +44 -0
  287. package/dist/infrastructure/extensions/composite-mcp-config-store.d.ts +9 -0
  288. package/dist/infrastructure/extensions/composite-mcp-config-store.js +10 -0
  289. package/dist/infrastructure/extensions/extension-directory-reader.d.ts +2 -0
  290. package/dist/infrastructure/extensions/extension-directory-reader.js +15 -0
  291. package/dist/infrastructure/extensions/extension-source-resolver.d.ts +6 -0
  292. package/dist/infrastructure/extensions/extension-source-resolver.js +126 -0
  293. package/dist/infrastructure/extensions/file-mcp-config-store.d.ts +15 -0
  294. package/dist/infrastructure/extensions/file-mcp-config-store.js +66 -0
  295. package/dist/infrastructure/extensions/hook-runtime.d.ts +18 -0
  296. package/dist/infrastructure/extensions/hook-runtime.js +66 -0
  297. package/dist/infrastructure/extensions/mcp-runtime.d.ts +12 -0
  298. package/dist/infrastructure/extensions/mcp-runtime.js +52 -0
  299. package/dist/infrastructure/extensions/plugin-discovery.d.ts +5 -0
  300. package/dist/infrastructure/extensions/plugin-discovery.js +52 -0
  301. package/dist/infrastructure/extensions/plugin-manager.d.ts +26 -0
  302. package/dist/infrastructure/extensions/plugin-manager.js +139 -0
  303. package/dist/infrastructure/extensions/skill-discovery.d.ts +4 -0
  304. package/dist/infrastructure/extensions/skill-discovery.js +29 -0
  305. package/dist/infrastructure/extensions/skill-installer.d.ts +8 -0
  306. package/dist/infrastructure/extensions/skill-installer.js +88 -0
  307. package/dist/infrastructure/extensions/skill-manager.d.ts +22 -0
  308. package/dist/infrastructure/extensions/skill-manager.js +67 -0
  309. package/dist/infrastructure/extensions/skill-roots.d.ts +19 -0
  310. package/dist/infrastructure/extensions/skill-roots.js +25 -0
  311. package/dist/infrastructure/extensions/skill-tool-executor.d.ts +18 -0
  312. package/dist/infrastructure/extensions/skill-tool-executor.js +53 -0
  313. package/dist/infrastructure/filesystem/atomic-file-store.d.ts +12 -0
  314. package/dist/infrastructure/filesystem/atomic-file-store.js +106 -0
  315. package/dist/infrastructure/filesystem/bounded-file-reader.d.ts +6 -0
  316. package/dist/infrastructure/filesystem/bounded-file-reader.js +24 -0
  317. package/dist/infrastructure/filesystem/bounded-json-reader.d.ts +1 -0
  318. package/dist/infrastructure/filesystem/bounded-json-reader.js +7 -0
  319. package/dist/infrastructure/filesystem/fs-errors.d.ts +2 -0
  320. package/dist/infrastructure/filesystem/fs-errors.js +6 -0
  321. package/dist/infrastructure/filesystem/gateway-media-input-reader.d.ts +12 -0
  322. package/dist/infrastructure/filesystem/gateway-media-input-reader.js +49 -0
  323. package/dist/infrastructure/filesystem/local-filesystem-tool-executor.d.ts +21 -0
  324. package/dist/infrastructure/filesystem/local-filesystem-tool-executor.js +176 -0
  325. package/dist/infrastructure/filesystem/path-resolver.d.ts +20 -0
  326. package/dist/infrastructure/filesystem/path-resolver.js +119 -0
  327. package/dist/infrastructure/filesystem/workspace-media-artifact-store.d.ts +13 -0
  328. package/dist/infrastructure/filesystem/workspace-media-artifact-store.js +152 -0
  329. package/dist/infrastructure/logging/daily-rotating-file-writer.d.ts +20 -0
  330. package/dist/infrastructure/logging/daily-rotating-file-writer.js +75 -0
  331. package/dist/infrastructure/logging/log-redactor.d.ts +2 -0
  332. package/dist/infrastructure/logging/log-redactor.js +26 -0
  333. package/dist/infrastructure/logging/logging-policy.d.ts +6 -0
  334. package/dist/infrastructure/logging/logging-policy.js +6 -0
  335. package/dist/infrastructure/logging/structured-logger.d.ts +24 -0
  336. package/dist/infrastructure/logging/structured-logger.js +40 -0
  337. package/dist/infrastructure/network/safe-media-downloader.d.ts +23 -0
  338. package/dist/infrastructure/network/safe-media-downloader.js +239 -0
  339. package/dist/infrastructure/platform/host-platform.d.ts +14 -0
  340. package/dist/infrastructure/platform/host-platform.js +23 -0
  341. package/dist/infrastructure/platform/host-process.d.ts +17 -0
  342. package/dist/infrastructure/platform/host-process.js +116 -0
  343. package/dist/infrastructure/platform/platform-paths.d.ts +25 -0
  344. package/dist/infrastructure/platform/platform-paths.js +33 -0
  345. package/dist/infrastructure/project/file-project-trust-store.d.ts +12 -0
  346. package/dist/infrastructure/project/file-project-trust-store.js +59 -0
  347. package/dist/infrastructure/sdk/chat-completion-adapter.d.ts +8 -0
  348. package/dist/infrastructure/sdk/chat-completion-adapter.js +115 -0
  349. package/dist/infrastructure/sdk/lotagate-client-factory.d.ts +3 -0
  350. package/dist/infrastructure/sdk/lotagate-client-factory.js +8 -0
  351. package/dist/infrastructure/sdk/model-catalog-adapter.d.ts +19 -0
  352. package/dist/infrastructure/sdk/model-catalog-adapter.js +28 -0
  353. package/dist/infrastructure/sdk/sdk-media-gateway-client.d.ts +20 -0
  354. package/dist/infrastructure/sdk/sdk-media-gateway-client.js +97 -0
  355. package/dist/infrastructure/sessions/file-goal-store.d.ts +21 -0
  356. package/dist/infrastructure/sessions/file-goal-store.js +160 -0
  357. package/dist/infrastructure/sessions/file-session-store.d.ts +48 -0
  358. package/dist/infrastructure/sessions/file-session-store.js +525 -0
  359. package/dist/infrastructure/sessions/project-session-paths.d.ts +17 -0
  360. package/dist/infrastructure/sessions/project-session-paths.js +41 -0
  361. package/dist/infrastructure/sessions/session-index.d.ts +16 -0
  362. package/dist/infrastructure/sessions/session-index.js +84 -0
  363. package/dist/infrastructure/sessions/session-journal.d.ts +22 -0
  364. package/dist/infrastructure/sessions/session-journal.js +137 -0
  365. package/dist/infrastructure/sessions/subagent-journal-store.d.ts +28 -0
  366. package/dist/infrastructure/sessions/subagent-journal-store.js +30 -0
  367. package/dist/infrastructure/shell/shell-tool-executor.d.ts +17 -0
  368. package/dist/infrastructure/shell/shell-tool-executor.js +115 -0
  369. package/dist/infrastructure/tokens/tiktoken-token-estimator.d.ts +18 -0
  370. package/dist/infrastructure/tokens/tiktoken-token-estimator.js +48 -0
  371. package/dist/infrastructure/workspace/workspace-settings-store.d.ts +9 -0
  372. package/dist/infrastructure/workspace/workspace-settings-store.js +75 -0
  373. package/dist/main.d.ts +7 -0
  374. package/dist/main.js +66 -0
  375. package/dist/ports/cache-store.d.ts +10 -0
  376. package/dist/ports/cache-store.js +1 -0
  377. package/dist/ports/chat-model.d.ts +30 -0
  378. package/dist/ports/chat-model.js +1 -0
  379. package/dist/ports/clipboard-adapter.d.ts +7 -0
  380. package/dist/ports/clipboard-adapter.js +1 -0
  381. package/dist/ports/clipboard-text-adapter.d.ts +3 -0
  382. package/dist/ports/clipboard-text-adapter.js +1 -0
  383. package/dist/ports/credential-store.d.ts +7 -0
  384. package/dist/ports/credential-store.js +1 -0
  385. package/dist/ports/goal-store.d.ts +12 -0
  386. package/dist/ports/goal-store.js +1 -0
  387. package/dist/ports/logger.d.ts +8 -0
  388. package/dist/ports/logger.js +1 -0
  389. package/dist/ports/media-gateway-client.d.ts +54 -0
  390. package/dist/ports/media-gateway-client.js +1 -0
  391. package/dist/ports/model-diagnostics.d.ts +17 -0
  392. package/dist/ports/model-diagnostics.js +1 -0
  393. package/dist/ports/project-trust-store.d.ts +12 -0
  394. package/dist/ports/project-trust-store.js +1 -0
  395. package/dist/ports/session-store.d.ts +58 -0
  396. package/dist/ports/session-store.js +1 -0
  397. package/dist/ports/subagent-lifecycle.d.ts +31 -0
  398. package/dist/ports/subagent-lifecycle.js +1 -0
  399. package/dist/ports/tool-activity.d.ts +13 -0
  400. package/dist/ports/tool-activity.js +1 -0
  401. package/dist/presentation/themes/theme.d.ts +19 -0
  402. package/dist/presentation/themes/theme.js +8 -0
  403. package/dist/presentation/tui/agent-initialization-renderer.d.ts +4 -0
  404. package/dist/presentation/tui/agent-initialization-renderer.js +37 -0
  405. package/dist/presentation/tui/context-display.d.ts +21 -0
  406. package/dist/presentation/tui/context-display.js +33 -0
  407. package/dist/presentation/tui/formatters.d.ts +6 -0
  408. package/dist/presentation/tui/formatters.js +60 -0
  409. package/dist/presentation/tui/ink/choice-window.d.ts +5 -0
  410. package/dist/presentation/tui/ink/choice-window.js +5 -0
  411. package/dist/presentation/tui/ink/components/activity-entry.d.ts +6 -0
  412. package/dist/presentation/tui/ink/components/activity-entry.js +16 -0
  413. package/dist/presentation/tui/ink/components/activity-status.d.ts +10 -0
  414. package/dist/presentation/tui/ink/components/activity-status.js +21 -0
  415. package/dist/presentation/tui/ink/components/choice-modal.d.ts +11 -0
  416. package/dist/presentation/tui/ink/components/choice-modal.js +29 -0
  417. package/dist/presentation/tui/ink/components/composer.d.ts +40 -0
  418. package/dist/presentation/tui/ink/components/composer.js +271 -0
  419. package/dist/presentation/tui/ink/components/file-diff.d.ts +6 -0
  420. package/dist/presentation/tui/ink/components/file-diff.js +34 -0
  421. package/dist/presentation/tui/ink/components/modal.d.ts +8 -0
  422. package/dist/presentation/tui/ink/components/modal.js +110 -0
  423. package/dist/presentation/tui/ink/components/shimmer-text.d.ts +6 -0
  424. package/dist/presentation/tui/ink/components/shimmer-text.js +9 -0
  425. package/dist/presentation/tui/ink/components/subagent-activity.d.ts +11 -0
  426. package/dist/presentation/tui/ink/components/subagent-activity.js +61 -0
  427. package/dist/presentation/tui/ink/components/transcript.d.ts +39 -0
  428. package/dist/presentation/tui/ink/components/transcript.js +121 -0
  429. package/dist/presentation/tui/ink/components/welcome-panel.d.ts +6 -0
  430. package/dist/presentation/tui/ink/components/welcome-panel.js +20 -0
  431. package/dist/presentation/tui/ink/lotagate-tui.d.ts +6 -0
  432. package/dist/presentation/tui/ink/lotagate-tui.js +136 -0
  433. package/dist/presentation/tui/ink/markdown-inline-renderer.d.ts +4 -0
  434. package/dist/presentation/tui/ink/markdown-inline-renderer.js +20 -0
  435. package/dist/presentation/tui/ink/markdown-inline.d.ts +13 -0
  436. package/dist/presentation/tui/ink/markdown-inline.js +91 -0
  437. package/dist/presentation/tui/ink/markdown-message.d.ts +6 -0
  438. package/dist/presentation/tui/ink/markdown-message.js +66 -0
  439. package/dist/presentation/tui/ink/markdown-table.d.ts +16 -0
  440. package/dist/presentation/tui/ink/markdown-table.js +77 -0
  441. package/dist/presentation/tui/ink/tui-bridge.d.ts +195 -0
  442. package/dist/presentation/tui/ink/tui-bridge.js +289 -0
  443. package/dist/presentation/tui/terminal-capabilities.d.ts +15 -0
  444. package/dist/presentation/tui/terminal-capabilities.js +7 -0
  445. package/dist/presentation/tui/terminal-mouse.d.ts +5 -0
  446. package/dist/presentation/tui/terminal-mouse.js +19 -0
  447. package/dist/presentation/tui/terminal-screen.d.ts +10 -0
  448. package/dist/presentation/tui/terminal-screen.js +23 -0
  449. package/dist/presentation/tui/tui-agent-event-runner.d.ts +24 -0
  450. package/dist/presentation/tui/tui-agent-event-runner.js +69 -0
  451. package/dist/presentation/tui/tui-application-contract.d.ts +10 -0
  452. package/dist/presentation/tui/tui-application-contract.js +8 -0
  453. package/dist/presentation/tui/tui-application.d.ts +62 -0
  454. package/dist/presentation/tui/tui-application.js +675 -0
  455. package/dist/presentation/tui/tui-attachment-input.d.ts +2 -0
  456. package/dist/presentation/tui/tui-attachment-input.js +5 -0
  457. package/dist/presentation/tui/tui-clipboard-paste-handlers.d.ts +11 -0
  458. package/dist/presentation/tui/tui-clipboard-paste-handlers.js +25 -0
  459. package/dist/presentation/tui/tui-command-context.d.ts +3 -0
  460. package/dist/presentation/tui/tui-command-context.js +1 -0
  461. package/dist/presentation/tui/tui-command-executor.d.ts +38 -0
  462. package/dist/presentation/tui/tui-command-executor.js +214 -0
  463. package/dist/presentation/tui/tui-command-host-factory.d.ts +40 -0
  464. package/dist/presentation/tui/tui-command-host-factory.js +23 -0
  465. package/dist/presentation/tui/tui-context-compaction.d.ts +5 -0
  466. package/dist/presentation/tui/tui-context-compaction.js +22 -0
  467. package/dist/presentation/tui/tui-context-service.d.ts +34 -0
  468. package/dist/presentation/tui/tui-context-service.js +126 -0
  469. package/dist/presentation/tui/tui-file-suggestions.d.ts +3 -0
  470. package/dist/presentation/tui/tui-file-suggestions.js +8 -0
  471. package/dist/presentation/tui/tui-goal-controller.d.ts +14 -0
  472. package/dist/presentation/tui/tui-goal-controller.js +52 -0
  473. package/dist/presentation/tui/tui-initial-model.d.ts +3 -0
  474. package/dist/presentation/tui/tui-initial-model.js +28 -0
  475. package/dist/presentation/tui/tui-lifecycle-actions.d.ts +13 -0
  476. package/dist/presentation/tui/tui-lifecycle-actions.js +45 -0
  477. package/dist/presentation/tui/tui-manual-compaction.d.ts +18 -0
  478. package/dist/presentation/tui/tui-manual-compaction.js +31 -0
  479. package/dist/presentation/tui/tui-media-model-selection.d.ts +12 -0
  480. package/dist/presentation/tui/tui-media-model-selection.js +38 -0
  481. package/dist/presentation/tui/tui-prompt-dispatcher.d.ts +16 -0
  482. package/dist/presentation/tui/tui-prompt-dispatcher.js +38 -0
  483. package/dist/presentation/tui/tui-skill-controller.d.ts +11 -0
  484. package/dist/presentation/tui/tui-skill-controller.js +13 -0
  485. package/dist/presentation/tui/tui-tool-approval.d.ts +22 -0
  486. package/dist/presentation/tui/tui-tool-approval.js +73 -0
  487. package/dist/version.d.ts +1 -0
  488. package/dist/version.js +1 -0
  489. package/package.json +9 -8
  490. package/scripts/install-native.mjs +11 -11
@@ -0,0 +1,21 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text, useAnimation } from 'ink';
3
+ import { DARK_THEME as palette } from '../../../themes/theme.js';
4
+ import { ShimmerText } from './shimmer-text.js';
5
+ export function ActivityStatus({ status, activityStartedAt, elapsedMs, usage, paused = false }) {
6
+ const active = status !== 'Done' && status !== 'Cancelled' && status !== 'Failed';
7
+ const animation = useAnimation({ interval: 120, isActive: active && !paused });
8
+ const elapsed = active && activityStartedAt !== undefined ? Math.max(elapsedMs ?? 0, Date.now() - activityStartedAt) : elapsedMs ?? 0;
9
+ const details = [formatDuration(elapsed)];
10
+ const outputTokens = usage?.completionTokens ?? usage?.totalTokens;
11
+ if (outputTokens !== undefined)
12
+ details.push(`${usage?.estimated === true ? '~' : ''}${outputTokens} output tokens`);
13
+ if (active)
14
+ details.push('Esc cancel');
15
+ const indicator = active ? ['◐', '◓', '◑', '◒'][animation.frame % 4] ?? '◐' : '●';
16
+ const color = status === 'Failed' ? palette.error : active ? palette.warning : palette.success;
17
+ return _jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: color, children: [indicator, " "] }), _jsx(ShimmerText, { value: status, active: active && !paused, frame: animation.frame }), _jsxs(Text, { color: palette.muted, children: [" ", details.join(' · ')] })] });
18
+ }
19
+ function formatDuration(milliseconds) {
20
+ return milliseconds < 1000 ? `${milliseconds}ms` : `${(milliseconds / 1000).toFixed(1)}s`;
21
+ }
@@ -0,0 +1,11 @@
1
+ import type { JSX } from 'react';
2
+ import type { InkTuiBridge, TuiChoice } from '../tui-bridge.js';
3
+ export interface ChoiceModalProps {
4
+ bridge: InkTuiBridge;
5
+ title: string;
6
+ choices: readonly TuiChoice[];
7
+ currentValue?: string;
8
+ detail?: string;
9
+ borderColor?: string;
10
+ }
11
+ export declare function ChoiceModal({ bridge, title, choices, currentValue, detail, borderColor }: ChoiceModalProps): JSX.Element;
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ import { DARK_THEME as palette } from '../../../themes/theme.js';
5
+ import { choiceWindow } from '../choice-window.js';
6
+ export function ChoiceModal({ bridge, title, choices, currentValue, detail, borderColor = palette.accent }) {
7
+ const initial = choices.findIndex((choice) => choice.value === currentValue);
8
+ const [selected, setSelected] = useState(Math.max(0, initial));
9
+ const window = choiceWindow(choices, selected, 8);
10
+ useInput((input, key) => {
11
+ if (key.upArrow)
12
+ setSelected((current) => Math.max(0, current - 1));
13
+ else if (key.downArrow)
14
+ setSelected((current) => Math.min(Math.max(0, choices.length - 1), current + 1));
15
+ else if (key.return)
16
+ bridge.resolveActiveModal(choices[selected]?.value);
17
+ else if (input.toLowerCase() === 'y' && choices.some((choice) => choice.value === 'allow'))
18
+ bridge.resolveActiveModal('allow');
19
+ else if (input.toLowerCase() === 'n' && choices.some((choice) => choice.value === 'deny'))
20
+ bridge.resolveActiveModal('deny');
21
+ else if (key.escape || input === 'q')
22
+ bridge.resolveActiveModal(undefined);
23
+ });
24
+ return _jsxs(Box, { borderStyle: "double", borderColor: borderColor, flexDirection: "column", marginTop: 1, paddingX: 1, children: [_jsx(Text, { bold: true, color: palette.text, children: "Action required" }), _jsx(Text, { color: palette.text, children: title }), detail !== undefined && _jsx(Text, { color: palette.muted, children: detail }), window.entries.map((choice, index) => {
25
+ const active = window.start + index === selected;
26
+ const activeBackground = active ? { backgroundColor: palette.selection } : {};
27
+ return _jsxs(Box, { width: "100%", alignSelf: "stretch", flexDirection: "row", ...activeBackground, children: [_jsx(Text, { color: active ? palette.accent : palette.muted, ...activeBackground, children: "\u203A " }), _jsx(Text, { color: palette.text, ...activeBackground, children: choice.label }), choice.description !== undefined && _jsxs(Text, { color: palette.muted, ...activeBackground, children: [" ", choice.description] })] }, choice.value);
28
+ }), _jsx(Text, { color: palette.muted, children: "\u2191\u2193 navigate \u00B7 Enter select \u00B7 Esc cancel" })] });
29
+ }
@@ -0,0 +1,40 @@
1
+ import type { JSX } from 'react';
2
+ import type { Attachment } from '../../../../domain/session/attachment.js';
3
+ import type { InkTuiBridge, TuiChoice } from '../tui-bridge.js';
4
+ export interface ComposerCursorPosition {
5
+ x: number;
6
+ y: number;
7
+ }
8
+ interface ComposerInputLayout {
9
+ x: number;
10
+ y: number;
11
+ width: number;
12
+ }
13
+ export declare function calculateComposerCursorPosition({ layout, value, cursor, terminalRows }: {
14
+ layout: ComposerInputLayout;
15
+ value: string;
16
+ cursor: number;
17
+ terminalRows?: number;
18
+ }): ComposerCursorPosition | undefined;
19
+ export declare function Composer({ bridge, enabled, activeRun, visible, clearBlockedUntil, footerNotice, contextUsage, attachments, fileChoices, onLayoutRowsChange }: {
20
+ bridge: InkTuiBridge;
21
+ enabled: boolean;
22
+ activeRun: boolean;
23
+ visible?: boolean;
24
+ clearBlockedUntil?: number;
25
+ footerNotice?: string;
26
+ contextUsage?: {
27
+ usedTokens: number;
28
+ contextWindow?: number;
29
+ };
30
+ attachments: readonly Attachment[];
31
+ fileChoices: readonly TuiChoice[];
32
+ onLayoutRowsChange?: (rows: number) => void;
33
+ }): JSX.Element | null;
34
+ export interface AtFileReference {
35
+ start: number;
36
+ query: string;
37
+ }
38
+ /** Returns the active unquoted @workspace-file token immediately before the cursor. */
39
+ export declare function atFileReference(value: string, cursor: number): AtFileReference | undefined;
40
+ export {};
@@ -0,0 +1,271 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useLayoutEffect, useRef, useState } from 'react';
3
+ import { Box, Text, measureElement, useCursor, useInput, usePaste, useStdout } from 'ink';
4
+ import { formatContextUsage, terminalTextWidth } from '../../formatters.js';
5
+ import { DARK_THEME as palette } from '../../../themes/theme.js';
6
+ import { AttachmentChip } from './transcript.js';
7
+ import { isMouseSequence } from '../../terminal-mouse.js';
8
+ import { commandSuggestions } from '../../../../application/commands/command-presentation.js';
9
+ import { parseCommandInvocation, tokenizeCommandInput } from '../../../../application/commands/command-parser.js';
10
+ import { COMMAND_REGISTRY } from '../../../../application/commands/command-runtime.js';
11
+ const INPUT_CONTENT_OFFSET = 4;
12
+ export function calculateComposerCursorPosition({ layout, value, cursor, terminalRows }) {
13
+ const beforeCursor = value.slice(0, cursor).split('\n');
14
+ const contentWidth = Math.max(1, layout.width - (INPUT_CONTENT_OFFSET + 2));
15
+ const completedRows = beforeCursor.slice(0, -1).reduce((rows, line) => rows + Math.max(1, Math.ceil(terminalTextWidth(line) / contentWidth)), 0);
16
+ const activeLineWidth = terminalTextWidth(beforeCursor.at(-1) ?? '');
17
+ const y = layout.y + 1 + completedRows + Math.floor(activeLineWidth / contentWidth);
18
+ if (terminalRows !== undefined && (y < 0 || y >= terminalRows))
19
+ return undefined;
20
+ return { x: layout.x + INPUT_CONTENT_OFFSET + (activeLineWidth % contentWidth), y };
21
+ }
22
+ export function Composer({ bridge, enabled, activeRun, visible = true, clearBlockedUntil, footerNotice, contextUsage, attachments, fileChoices, onLayoutRowsChange }) {
23
+ const [value, setValue] = useState('');
24
+ const [cursor, setCursor] = useState(0);
25
+ const [selected, setSelected] = useState(0);
26
+ const [clearHint, setClearHint] = useState();
27
+ const clearTimer = useRef(undefined);
28
+ const clearArmed = useRef(false);
29
+ const valueRef = useRef('');
30
+ const cursorRef = useRef(0);
31
+ const selectedCommandRef = useRef(undefined);
32
+ const inputRef = useRef(null);
33
+ const [inputMetrics, setInputMetrics] = useState({ left: 0, top: 0, width: 0, hasMeasured: false });
34
+ const { setCursorPosition: setInkCursorPosition } = useCursor();
35
+ const { stdout } = useStdout();
36
+ const suggestions = value.startsWith('/') && !value.includes('\n') && selectedCommandRef.current !== value
37
+ ? commandSuggestions(value, COMMAND_REGISTRY, 'tui').slice(0, 8)
38
+ : [];
39
+ const fileReference = atFileReference(value, cursor);
40
+ const fileSuggestions = fileReference === undefined ? [] : fileChoices.filter((choice) => choice.value.slice(1).toLowerCase().includes(fileReference.query.toLowerCase())).slice(0, 8);
41
+ const choices = suggestions.length > 0 ? suggestions : fileSuggestions;
42
+ const dismissClearPrompt = () => {
43
+ clearArmed.current = false;
44
+ setClearHint(undefined);
45
+ if (clearTimer.current !== undefined)
46
+ clearTimeout(clearTimer.current);
47
+ clearTimer.current = undefined;
48
+ };
49
+ const updateDraft = (nextValue, nextCursor) => {
50
+ valueRef.current = nextValue;
51
+ cursorRef.current = nextCursor;
52
+ setValue(nextValue);
53
+ setCursor(nextCursor);
54
+ };
55
+ const clearSelectedCommand = () => {
56
+ selectedCommandRef.current = undefined;
57
+ };
58
+ const chooseCommand = (choice) => {
59
+ updateDraft(choice.value, choice.value.length);
60
+ selectedCommandRef.current = choice.value;
61
+ setSelected(0);
62
+ };
63
+ const insert = (text) => {
64
+ const normalized = text.replace(/\r\n?/gu, '\n');
65
+ if (normalized.length === 0)
66
+ return;
67
+ dismissClearPrompt();
68
+ clearSelectedCommand();
69
+ const current = valueRef.current;
70
+ const position = cursorRef.current;
71
+ updateDraft(`${current.slice(0, position)}${normalized}${current.slice(position)}`, position + normalized.length);
72
+ };
73
+ const applyFileChoice = (choice) => {
74
+ if (fileReference === undefined)
75
+ return;
76
+ clearSelectedCommand();
77
+ const current = valueRef.current;
78
+ updateDraft(`${current.slice(0, fileReference.start)}${choice.value} ${current.slice(cursorRef.current)}`, fileReference.start + choice.value.length + 1);
79
+ setSelected(0);
80
+ };
81
+ const erase = () => {
82
+ const position = cursorRef.current;
83
+ if (position === 0)
84
+ return;
85
+ dismissClearPrompt();
86
+ clearSelectedCommand();
87
+ const current = valueRef.current;
88
+ updateDraft(`${current.slice(0, position - 1)}${current.slice(position)}`, position - 1);
89
+ };
90
+ const submit = () => {
91
+ const trimmed = valueRef.current.trim();
92
+ if (trimmed.length > 0) {
93
+ dismissClearPrompt();
94
+ clearSelectedCommand();
95
+ updateDraft('', 0);
96
+ setSelected(0);
97
+ void bridge.submit(trimmed);
98
+ }
99
+ };
100
+ const clearDraft = () => {
101
+ dismissClearPrompt();
102
+ updateDraft('', 0);
103
+ setSelected(0);
104
+ bridge.clearAttachments();
105
+ };
106
+ const armClearPrompt = () => {
107
+ clearArmed.current = true;
108
+ setClearHint('Press Esc again to clear text and references.');
109
+ if (clearTimer.current !== undefined)
110
+ clearTimeout(clearTimer.current);
111
+ clearTimer.current = setTimeout(() => {
112
+ clearArmed.current = false;
113
+ setClearHint(undefined);
114
+ clearTimer.current = undefined;
115
+ }, 1500);
116
+ };
117
+ useInput((input, key) => {
118
+ if (!enabled)
119
+ return;
120
+ if (isMouseSequence(input))
121
+ return;
122
+ if (key.escape || input === '\u001b') {
123
+ if (activeRun || (clearBlockedUntil !== undefined && clearBlockedUntil > Date.now()))
124
+ return;
125
+ if (value.length === 0 && attachments.length === 0)
126
+ return;
127
+ if (clearArmed.current)
128
+ clearDraft();
129
+ else
130
+ armClearPrompt();
131
+ return;
132
+ }
133
+ if (key.meta && input.toLowerCase() === 'v') {
134
+ void bridge.pasteImage().catch(() => undefined);
135
+ return;
136
+ }
137
+ if (key.ctrl && input.toLowerCase() === 'v') {
138
+ void bridge.pasteText().then((text) => { if (text !== undefined)
139
+ insert(text); }).catch(() => undefined);
140
+ return;
141
+ }
142
+ if (key.return && key.shift) {
143
+ insert('\n');
144
+ return;
145
+ }
146
+ if (key.return) {
147
+ const choice = choices[selected];
148
+ if (suggestions.length > 0 && choice !== undefined && choice.value !== value) {
149
+ chooseCommand(choice);
150
+ return;
151
+ }
152
+ if (isCompleteTuiCommand(value)) {
153
+ submit();
154
+ return;
155
+ }
156
+ if (choice !== undefined && fileSuggestions.length > 0)
157
+ applyFileChoice(choice);
158
+ else
159
+ submit();
160
+ return;
161
+ }
162
+ if (key.tab && choices[selected] !== undefined) {
163
+ const choice = choices[selected];
164
+ if (choice !== undefined) {
165
+ if (suggestions.length > 0)
166
+ chooseCommand(choice);
167
+ else
168
+ applyFileChoice(choice);
169
+ }
170
+ return;
171
+ }
172
+ if (key.upArrow && choices.length > 0) {
173
+ setSelected((current) => Math.max(0, current - 1));
174
+ return;
175
+ }
176
+ if (key.downArrow && choices.length > 0) {
177
+ setSelected((current) => Math.min(choices.length - 1, current + 1));
178
+ return;
179
+ }
180
+ if (key.leftArrow) {
181
+ clearSelectedCommand();
182
+ const nextCursor = Math.max(0, cursorRef.current - 1);
183
+ cursorRef.current = nextCursor;
184
+ setCursor(nextCursor);
185
+ return;
186
+ }
187
+ if (key.rightArrow) {
188
+ clearSelectedCommand();
189
+ const nextCursor = Math.min(valueRef.current.length, cursorRef.current + 1);
190
+ cursorRef.current = nextCursor;
191
+ setCursor(nextCursor);
192
+ return;
193
+ }
194
+ if (key.backspace || key.delete) {
195
+ erase();
196
+ return;
197
+ }
198
+ if (!key.ctrl && !key.meta && input.length > 0)
199
+ insert(input);
200
+ }, { isActive: enabled });
201
+ usePaste((text) => { if (enabled)
202
+ insert(text); }, { isActive: enabled });
203
+ useEffect(() => () => {
204
+ if (clearTimer.current !== undefined)
205
+ clearTimeout(clearTimer.current);
206
+ }, []);
207
+ const lines = value.split('\n');
208
+ const inputWidth = inputMetrics.hasMeasured ? inputMetrics.width : Math.max(40, stdout.columns ?? 80);
209
+ const inputContentWidth = Math.max(1, inputWidth - (INPUT_CONTENT_OFFSET + 2));
210
+ const inputRows = lines.reduce((rows, line) => rows + Math.max(1, Math.ceil(terminalTextWidth(line) / inputContentWidth)), 0);
211
+ const layoutRows = calculateComposerRows({ attachmentCount: attachments.length, inputRows, hasClearHint: clearHint !== undefined, hasFooterNotice: footerNotice !== undefined, choiceCount: choices.length });
212
+ useLayoutEffect(() => {
213
+ onLayoutRowsChange?.(layoutRows + 1);
214
+ }, [layoutRows, onLayoutRowsChange]);
215
+ useLayoutEffect(() => {
216
+ const input = inputRef.current;
217
+ if (input === null) {
218
+ setInputMetrics((current) => current.hasMeasured ? { left: 0, top: 0, width: 0, hasMeasured: false } : current);
219
+ return;
220
+ }
221
+ const measured = measureElement(input);
222
+ setInputMetrics((current) => current.left === measured.x && current.top === measured.y && current.width === measured.width && current.hasMeasured
223
+ ? current
224
+ : { left: measured.x, top: measured.y, width: measured.width, hasMeasured: true });
225
+ });
226
+ const cursorPosition = enabled && visible && inputMetrics.hasMeasured
227
+ ? calculateComposerCursorPosition({ layout: { x: inputMetrics.left, y: inputMetrics.top, width: inputMetrics.width }, value, cursor, terminalRows: stdout.rows })
228
+ : undefined;
229
+ setInkCursorPosition(cursorPosition);
230
+ if (!visible)
231
+ return null;
232
+ return _jsxs(Box, { width: "100%", flexDirection: "column", marginTop: 1, children: [attachments.map((attachment) => _jsx(AttachmentChip, { attachment: attachment }, attachment.id)), _jsx(Box, { ref: inputRef, width: "100%", borderStyle: "round", borderColor: enabled ? palette.accent : palette.border, flexDirection: "column", paddingX: 1, children: _jsxs(Box, { children: [_jsx(Text, { color: palette.accent, children: "\u203A " }), _jsx(Text, { wrap: "wrap", color: value.length === 0 ? palette.muted : palette.text, children: value.length === 0 ? 'Ask LotaGate to work on this project…' : renderInputValue(lines.join('\n')) })] }) }), _jsxs(Box, { paddingX: 1, justifyContent: "space-between", children: [_jsx(Text, { color: palette.muted, dimColor: true, children: "Enter send \u00B7 Shift+Enter newline \u00B7 / commands \u00B7 @ files \u00B7 Ctrl+V text \u00B7 Alt+V image" }), contextUsage !== undefined && _jsx(Text, { color: palette.muted, dimColor: true, children: formatContextUsage(contextUsage.usedTokens, contextUsage.contextWindow) })] }), clearHint !== undefined && _jsx(Box, { paddingX: 1, children: _jsx(Text, { color: palette.muted, dimColor: true, children: clearHint }) }), footerNotice !== undefined && _jsx(Box, { paddingX: 1, children: _jsx(Text, { color: palette.muted, dimColor: true, children: footerNotice }) }), choices.length > 0 && _jsx(Box, { borderStyle: "round", borderColor: palette.border, flexDirection: "column", paddingX: 1, children: choices.map((choice, index) => _jsxs(Box, { ...(index === selected ? { backgroundColor: palette.selection } : {}), children: [_jsx(Text, { color: index === selected ? palette.accent : palette.muted, children: "\u203A " }), _jsxs(Text, { color: choice.kind === 'directory' ? palette.warning : palette.text, children: [choice.kind === 'directory' ? '▸ ' : '', choice.label] }), _jsxs(Text, { color: palette.muted, children: [" ", choice.description] })] }, choice.value)) })] });
233
+ }
234
+ function isCompleteTuiCommand(value) {
235
+ if (!value.startsWith('/') || value.includes('\n'))
236
+ return false;
237
+ try {
238
+ parseCommandInvocation(tokenizeCommandInput(value.trimStart().slice(1)), 'tui', COMMAND_REGISTRY);
239
+ return true;
240
+ }
241
+ catch {
242
+ return false;
243
+ }
244
+ }
245
+ function calculateComposerRows({ attachmentCount, inputRows, hasClearHint, hasFooterNotice, choiceCount }) {
246
+ const attachmentRows = attachmentCount * 2;
247
+ const inputBoxRows = Math.max(1, inputRows) + 2;
248
+ const suggestionRows = choiceCount > 0 ? choiceCount + 2 : 0;
249
+ return attachmentRows + inputBoxRows + 1 + (hasClearHint ? 1 : 0) + (hasFooterNotice ? 1 : 0) + suggestionRows;
250
+ }
251
+ function renderInputValue(value) {
252
+ const parts = value.split(/(@[^\s@]+|https?:\/\/[^\s]+|\/[A-Za-z][\w-]*)/gu);
253
+ return parts.filter((part) => part.length > 0).map((part, index) => {
254
+ if (part.startsWith('@'))
255
+ return _jsx(Text, { color: palette.accent, children: part }, index);
256
+ if (/^https?:\/\//u.test(part))
257
+ return _jsx(Text, { color: palette.link, underline: true, children: part }, index);
258
+ if (/^\/[A-Za-z][\w-]*$/u.test(part))
259
+ return _jsx(Text, { color: palette.accent, children: part }, index);
260
+ return _jsx(Text, { children: part }, index);
261
+ });
262
+ }
263
+ /** Returns the active unquoted @workspace-file token immediately before the cursor. */
264
+ export function atFileReference(value, cursor) {
265
+ const beforeCursor = value.slice(0, cursor);
266
+ const match = /(?:^|\s)@([^\s@]*)$/u.exec(beforeCursor);
267
+ if (match === null)
268
+ return undefined;
269
+ const query = match[1] ?? '';
270
+ return { start: cursor - query.length - 1, query };
271
+ }
@@ -0,0 +1,6 @@
1
+ import type { JSX } from 'react';
2
+ import type { FileChangeDiff } from '../../../../domain/filesystem/file-change-diff.js';
3
+ export declare function FileDiff({ change }: {
4
+ change: FileChangeDiff;
5
+ }): JSX.Element;
6
+ export declare function fileDiffRowCount(change: FileChangeDiff, columns: number): number;
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Box, Text, useStdout } from 'ink';
3
+ import { DARK_THEME as palette } from '../../../themes/theme.js';
4
+ import { truncateTerminalText, wrapTerminalText } from '../../formatters.js';
5
+ export function FileDiff({ change }) {
6
+ const { stdout } = useStdout();
7
+ const cardWidth = Math.max(20, (stdout.columns ?? 80) - 4);
8
+ const lineNumberWidth = getLineNumberWidth(change.lines);
9
+ return _jsxs(Box, { flexDirection: "column", marginBottom: 1, borderStyle: "round", borderColor: palette.border, paddingX: 1, children: [_jsxs(Text, { color: palette.text, children: [_jsx(Text, { color: palette.accent, children: "\u25A3" }), " ", _jsx(Text, { bold: true, children: "Updated" }), " ", _jsx(Text, { color: palette.muted, children: truncateTerminalText(change.path, Math.max(1, cardWidth - 30)) }), " ", _jsx(Text, { color: palette.muted, children: " \u00B7 " }), _jsxs(Text, { color: palette.success, children: ["+", change.additions] }), _jsx(Text, { color: palette.muted, children: " " }), _jsxs(Text, { color: palette.error, children: ["-", change.deletions] })] }), _jsx(Text, { color: palette.muted, children: " Workspace change" }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: change.lines.map((line, index) => _jsx(DiffLine, { line: line, lineNumberWidth: lineNumberWidth, textWidth: Math.max(1, cardWidth - (lineNumberWidth * 2 + 8)) }, `${index}-${line.kind}`)) }), change.truncated && _jsx(Text, { color: palette.muted, children: " \u2026 diff truncated for display" })] });
10
+ }
11
+ export function fileDiffRowCount(change, columns) {
12
+ const cardWidth = Math.max(20, columns - 4);
13
+ const lineNumberWidth = getLineNumberWidth(change.lines);
14
+ const textWidth = Math.max(1, cardWidth - (lineNumberWidth * 2 + 8));
15
+ const contentRows = change.lines.reduce((total, line) => total + wrapTerminalText(line.text.length === 0 ? ' ' : line.text, textWidth).length, 0);
16
+ return contentRows + 3 + (change.truncated ? 1 : 0);
17
+ }
18
+ function DiffLine({ line, lineNumberWidth, textWidth }) {
19
+ const isAddition = line.kind === 'addition';
20
+ const isDeletion = line.kind === 'deletion';
21
+ const color = isAddition ? palette.success : isDeletion ? palette.error : palette.text;
22
+ const backgroundColor = isAddition ? palette.diffAdded : isDeletion ? palette.diffRemoved : undefined;
23
+ const marker = line.kind === 'addition' ? '+' : line.kind === 'deletion' ? '-' : ' ';
24
+ const oldNumber = line.oldLine === undefined ? ' '.repeat(lineNumberWidth) : String(line.oldLine).padStart(lineNumberWidth, ' ');
25
+ const newNumber = line.newLine === undefined ? ' '.repeat(lineNumberWidth) : String(line.newLine).padStart(lineNumberWidth, ' ');
26
+ const rows = wrapTerminalText(line.text.length === 0 ? ' ' : line.text, textWidth);
27
+ return _jsx(Box, { flexDirection: "column", backgroundColor: backgroundColor, paddingX: 1, children: rows.map((row, index) => _jsxs(Box, { flexDirection: "row", children: [index === 0
28
+ ? _jsxs(_Fragment, { children: [_jsxs(Text, { color: palette.muted, children: [oldNumber, " ", newNumber, " "] }), _jsxs(Text, { color: color, bold: isAddition || isDeletion, children: [marker, " "] })] })
29
+ : _jsxs(Text, { color: palette.muted, children: [' '.repeat(lineNumberWidth * 2 + 3), " "] }), _jsx(Text, { color: color, bold: index === 0 && (isAddition || isDeletion), children: row })] }, `${index}-${row}`)) });
30
+ }
31
+ function getLineNumberWidth(lines) {
32
+ const largest = lines.reduce((maximum, line) => Math.max(maximum, line.oldLine ?? 0, line.newLine ?? 0), 0);
33
+ return Math.max(2, String(largest).length);
34
+ }
@@ -0,0 +1,8 @@
1
+ import type { JSX } from 'react';
2
+ import type { InkTuiBridge, TuiModal } from '../tui-bridge.js';
3
+ export declare function Modal({ bridge, modal, onLayoutRowsChange }: {
4
+ bridge: InkTuiBridge;
5
+ modal?: TuiModal;
6
+ onLayoutRowsChange?: (rows: number) => void;
7
+ }): JSX.Element | null;
8
+ export declare function estimateModalRows(modal: TuiModal): number;
@@ -0,0 +1,110 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useLayoutEffect, useRef, useState } from 'react';
3
+ import { Box, Text, useBoxMetrics, useInput, usePaste } from 'ink';
4
+ import { DARK_THEME as palette } from '../../../themes/theme.js';
5
+ import { ChoiceModal } from './choice-modal.js';
6
+ export function Modal({ bridge, modal, onLayoutRowsChange }) {
7
+ const modalRef = useRef(null);
8
+ const modalMetrics = useBoxMetrics(modalRef);
9
+ useLayoutEffect(() => {
10
+ if (modalMetrics.hasMeasured)
11
+ onLayoutRowsChange?.(modalMetrics.height);
12
+ }, [modalMetrics.height, modalMetrics.hasMeasured, onLayoutRowsChange]);
13
+ if (modal === undefined)
14
+ return null;
15
+ const content = modal.kind === 'choice'
16
+ ? _jsx(ChoiceModal, { bridge: bridge, title: modal.title, choices: modal.choices, ...(modal.currentValue === undefined ? {} : { currentValue: modal.currentValue }), ...(modal.detail === undefined ? {} : { detail: modal.detail }) })
17
+ : modal.kind === 'secret'
18
+ ? _jsx(SecretModal, { bridge: bridge, label: modal.label })
19
+ : modal.kind === 'approval'
20
+ ? _jsx(ApprovalModal, { bridge: bridge, toolName: modal.toolName, ...(modal.detail === undefined ? {} : { detail: modal.detail }) })
21
+ : modal.kind === 'subagent'
22
+ ? _jsx(SubagentDetailModal, { bridge: bridge, subagent: modal.subagent })
23
+ : _jsx(DecisionContent, { bridge: bridge, modal: modal });
24
+ return _jsx(Box, { ref: modalRef, width: "100%", flexDirection: "column", children: content });
25
+ }
26
+ export function estimateModalRows(modal) {
27
+ if (modal.kind === 'choice')
28
+ return Math.min(8, modal.choices.length) + (modal.detail === undefined ? 5 : 6);
29
+ if (modal.kind === 'approval')
30
+ return 8 + (modal.detail === undefined ? 0 : 1);
31
+ if (modal.kind === 'secret')
32
+ return 6;
33
+ if (modal.kind === 'subagent')
34
+ return 10;
35
+ if (modal.kind === 'trust')
36
+ return 6;
37
+ return Math.min(8, modal.plan.tasks.length) + 6;
38
+ }
39
+ function DecisionContent({ bridge, modal }) {
40
+ const title = modal.kind === 'trust' ? 'Trust this workspace?' : `Approve plan · ${modal.plan.tasks.length} tasks`;
41
+ const detail = modal.kind === 'trust' ? 'Local tools, MCP, and extensions remain disabled until you grant trust.' : modal.plan.tasks.map((task, index) => `${index + 1}. ${task.title}`).join('\n');
42
+ return _jsx(DecisionModal, { title: title, detail: detail, onDecision: (accepted) => bridge.resolveActiveModal(accepted) });
43
+ }
44
+ function DialogFrame({ children, title = 'Action required' }) {
45
+ return _jsxs(Box, { borderStyle: "double", borderColor: palette.accent, flexDirection: "column", marginTop: 1, paddingX: 1, children: [_jsx(Text, { bold: true, color: palette.text, children: title }), children] });
46
+ }
47
+ function SubagentDetailModal({ bridge, subagent }) {
48
+ useInput((input, key) => {
49
+ if (key.return || key.escape || input === '\u001b' || input.toLowerCase() === 'q')
50
+ bridge.closeSubagentDetails();
51
+ });
52
+ const handoff = subagent.handoff;
53
+ return _jsxs(DialogFrame, { title: `Subagent handoff · ${subagent.displayName}`, children: [_jsx(Text, { color: palette.text, children: subagent.task }), _jsxs(Text, { color: palette.muted, children: [subagent.mode, " \u00B7 ", subagent.status, " \u00B7 ", subagent.model] }), handoff === undefined
54
+ ? _jsx(Text, { color: palette.muted, children: "Handoff is available when this subagent completes." })
55
+ : _jsxs(Box, { flexDirection: "column", children: [_jsx(DetailSection, { label: "Summary", values: [handoff.summary] }), _jsx(DetailSection, { label: "Files inspected", values: handoff.filesInspected }), _jsx(DetailSection, { label: "Files changed", values: handoff.filesChanged }), _jsx(DetailSection, { label: "Commands run", values: handoff.commandsRun }), _jsx(DetailSection, { label: "Verification", values: handoff.verification }), _jsx(DetailSection, { label: "Warnings", values: handoff.warnings })] }), _jsx(Text, { color: palette.accent, children: "Enter / Esc / Q close" })] });
56
+ }
57
+ function DetailSection({ label, values }) {
58
+ return _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, color: palette.accent, children: label }), _jsx(Text, { color: palette.muted, wrap: "wrap", children: values.length === 0 ? 'None' : values.map((value) => `• ${safeDetail(value)}`).join('\n') })] });
59
+ }
60
+ function safeDetail(value) {
61
+ const redacted = value.replace(/Bearer\s+[^\s]+/giu, 'Bearer [REDACTED]').replace(/sk-[A-Za-z0-9_-]{8,}/gu, '[REDACTED]');
62
+ return redacted.length <= 500 ? redacted : `${redacted.slice(0, 497)}...`;
63
+ }
64
+ function DecisionModal({ title, detail, onDecision }) {
65
+ useInput((input, key) => {
66
+ if (key.return || input.toLowerCase() === 'y')
67
+ onDecision(true);
68
+ else if (key.escape || input.toLowerCase() === 'n')
69
+ onDecision(false);
70
+ });
71
+ return _jsxs(DialogFrame, { children: [_jsx(Text, { color: palette.text, children: title }), _jsx(Text, { color: palette.muted, children: detail }), _jsx(Text, { color: palette.accent, children: "Enter / Y approve \u00B7 Esc / N cancel" })] });
72
+ }
73
+ function ApprovalModal({ bridge, toolName, detail }) {
74
+ return _jsx(ChoiceModal, { bridge: bridge, title: `Approval · ${approvalTitle(toolName)}`, choices: [
75
+ { value: 'allow', label: 'Allow', description: 'Run this tool action' },
76
+ { value: 'deny', label: 'Deny', description: 'Block this tool action' },
77
+ ], ...(detail === undefined ? {} : { detail: compactDetail(detail) }), borderColor: palette.warning });
78
+ }
79
+ function approvalTitle(toolName) {
80
+ if (toolName === 'shell.exec')
81
+ return 'Shell command';
82
+ if (toolName === 'filesystem.write')
83
+ return 'File write';
84
+ return 'Tool action';
85
+ }
86
+ function compactDetail(detail) {
87
+ const value = detail.trim();
88
+ if (value.startsWith('Write workspace file: '))
89
+ return `write ${value.slice('Write workspace file: '.length)}`;
90
+ if (value.startsWith('Run command: '))
91
+ return `run ${value.slice('Run command: '.length)}`;
92
+ if (value.startsWith('This '))
93
+ return value.replace(/^This /u, '').replace(/ operation may change workspace or external state\.$/u, '');
94
+ return value;
95
+ }
96
+ function SecretModal({ bridge, label }) {
97
+ const [value, setValue] = useState('');
98
+ useInput((input, key) => {
99
+ if (key.return)
100
+ bridge.resolveActiveModal(value.trim() || undefined);
101
+ else if (key.escape)
102
+ bridge.resolveActiveModal(undefined);
103
+ else if (key.backspace || key.delete)
104
+ setValue((current) => current.slice(0, -1));
105
+ else if (!key.ctrl && !key.meta && input.length > 0)
106
+ setValue((current) => `${current}${input}`);
107
+ });
108
+ usePaste((text) => setValue((current) => `${current}${text.replace(/[\r\n]/gu, '')}`));
109
+ return _jsxs(DialogFrame, { children: [_jsx(Text, { color: palette.text, children: label }), _jsx(Text, { color: palette.accent, children: `> ${'•'.repeat(value.length)}▌` }), _jsx(Text, { color: palette.muted, children: "Enter save \u00B7 Esc cancel" })] });
110
+ }
@@ -0,0 +1,6 @@
1
+ import type { JSX } from 'react';
2
+ export declare function ShimmerText({ value, active, frame }: {
3
+ value: string;
4
+ active: boolean;
5
+ frame: number;
6
+ }): JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Text } from 'ink';
3
+ import { DARK_THEME as palette } from '../../../themes/theme.js';
4
+ export function ShimmerText({ value, active, frame }) {
5
+ if (!active || value.length === 0)
6
+ return _jsx(Text, { color: palette.text, children: value });
7
+ const highlight = frame % [...value].length;
8
+ return _jsx(Text, { color: palette.muted, children: [...value].map((character, index) => _jsx(Text, { color: index === highlight ? palette.text : palette.muted, bold: index === highlight, children: character }, `${index}-${character}`)) });
9
+ }
@@ -0,0 +1,11 @@
1
+ import type { JSX } from 'react';
2
+ import type { TuiSubagent } from '../tui-bridge.js';
3
+ export declare function SubagentCreatedEntry({ subagent }: {
4
+ subagent: TuiSubagent;
5
+ }): JSX.Element;
6
+ export declare function visibleSubagents(subagents: readonly TuiSubagent[]): readonly TuiSubagent[];
7
+ export declare function SubagentActivity({ subagents, selectedId, paused }: {
8
+ subagents: readonly TuiSubagent[];
9
+ selectedId?: string;
10
+ paused?: boolean;
11
+ }): JSX.Element | null;
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useAnimation } from 'ink';
3
+ import { DARK_THEME as palette } from '../../../themes/theme.js';
4
+ const MAX_VISIBLE_ACTIVE = 5;
5
+ export function SubagentCreatedEntry({ subagent }) {
6
+ return _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: palette.accent, children: ["\u25CC ", _jsx(Text, { bold: true, children: "Created agent" }), " ", _jsxs(Text, { color: palette.muted, children: ["\u00B7 ", displayTitle(subagent)] })] }), _jsxs(Text, { color: palette.muted, children: [" ", subagent.mode, subagent.background ? ' · background' : ''] })] });
7
+ }
8
+ export function visibleSubagents(subagents) {
9
+ return subagents.filter(isActive).sort(byRecent).slice(0, MAX_VISIBLE_ACTIVE);
10
+ }
11
+ export function SubagentActivity({ subagents, selectedId, paused = false }) {
12
+ const active = subagents.filter(isActive);
13
+ const { frame } = useAnimation({ interval: 250, isActive: active.length > 0 && !paused });
14
+ const visible = visibleSubagents(subagents);
15
+ if (visible.length === 0)
16
+ return null;
17
+ return _jsxs(Box, { borderStyle: "round", borderColor: palette.border, flexDirection: "column", marginBottom: 1, paddingX: 1, children: [_jsxs(Text, { color: palette.text, children: [_jsx(Text, { bold: true, children: "Subagents" }), _jsx(Text, { color: palette.muted, children: active.length === 0 ? '' : ` · ${active.length} working` })] }), visible.map((subagent) => _jsx(SubagentRow, { subagent: subagent, selected: subagent.id === selectedId, frame: frame }, subagent.id)), active.length > MAX_VISIBLE_ACTIVE && _jsxs(Text, { color: palette.muted, children: [" and ", active.length - MAX_VISIBLE_ACTIVE, " other subagents working"] }), _jsx(Text, { color: palette.muted, dimColor: true, children: "Ctrl+J/K select \u00B7 Ctrl+O handoff" })] });
18
+ }
19
+ function SubagentRow({ subagent, selected, frame }) {
20
+ const color = statusColor(subagent.status);
21
+ const elapsed = subagent.status === 'running' || subagent.status === 'queued'
22
+ ? Date.now() - subagent.createdAt
23
+ : subagent.durationMs ?? subagent.updatedAt - subagent.createdAt;
24
+ return _jsxs(Box, { backgroundColor: selected ? palette.selection : undefined, flexDirection: "column", marginTop: 1, paddingX: selected ? 1 : 0, children: [_jsxs(Text, { color: color, children: [indicator(subagent.status, frame), " ", _jsx(Text, { bold: true, children: displayTitle(subagent) })] }), _jsxs(Text, { color: palette.muted, children: [" ", subagent.mode, " \u00B7 ", subagent.status, " \u00B7 ", formatDuration(elapsed)] }), subagent.lastAction !== undefined && _jsxs(Text, { color: palette.muted, wrap: "truncate", children: [" ", subagent.lastAction.label] })] });
25
+ }
26
+ function isActive(subagent) {
27
+ return subagent.status === 'queued' || subagent.status === 'running';
28
+ }
29
+ function byRecent(left, right) {
30
+ return right.updatedAt - left.updatedAt;
31
+ }
32
+ function displayTitle(subagent) {
33
+ return `${subagent.displayName} · ${shortTask(subagent.task)}`;
34
+ }
35
+ function shortTask(value) {
36
+ const normalized = value.replace(/\s+/gu, ' ').trim();
37
+ return normalized.length <= 56 ? normalized : `${normalized.slice(0, 53)}...`;
38
+ }
39
+ function statusColor(status) {
40
+ if (status === 'completed')
41
+ return palette.success;
42
+ if (status === 'completed_with_warning')
43
+ return palette.warning;
44
+ if (status === 'failed' || status === 'cancelled')
45
+ return palette.error;
46
+ return status === 'queued' ? palette.muted : palette.warning;
47
+ }
48
+ function indicator(status, frame) {
49
+ if (status === 'completed')
50
+ return '✓';
51
+ if (status === 'completed_with_warning')
52
+ return '⚠';
53
+ if (status === 'failed' || status === 'cancelled')
54
+ return '!';
55
+ if (status === 'queued')
56
+ return '◌';
57
+ return ['◐', '◓', '◑', '◒'][frame % 4] ?? '◐';
58
+ }
59
+ function formatDuration(milliseconds) {
60
+ return milliseconds < 1000 ? `${Math.max(0, milliseconds)}ms` : `${(milliseconds / 1000).toFixed(1)}s`;
61
+ }