actoviq-agent-sdk 0.4.21 → 0.4.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 (278) hide show
  1. package/README-zh.md +50 -113
  2. package/README.md +51 -164
  3. package/assets/hadamard-icon.ico +0 -0
  4. package/assets/hadamard-icon.png +0 -0
  5. package/bin/hadamard-gui.js +31 -12
  6. package/dist/src/codeIntel/codeIntelligenceService.d.ts +16 -0
  7. package/dist/src/codeIntel/codeIntelligenceService.d.ts.map +1 -1
  8. package/dist/src/codeIntel/codeIntelligenceService.js +87 -2
  9. package/dist/src/codeIntel/codeIntelligenceService.js.map +1 -1
  10. package/dist/src/codeIntel/codeIntelligenceTools.d.ts.map +1 -1
  11. package/dist/src/codeIntel/codeIntelligenceTools.js +6 -0
  12. package/dist/src/codeIntel/codeIntelligenceTools.js.map +1 -1
  13. package/dist/src/codeIntel/index.d.ts +1 -0
  14. package/dist/src/codeIntel/index.d.ts.map +1 -1
  15. package/dist/src/codeIntel/index.js +1 -0
  16. package/dist/src/codeIntel/index.js.map +1 -1
  17. package/dist/src/codeIntel/languageServerPresets.d.ts +13 -0
  18. package/dist/src/codeIntel/languageServerPresets.d.ts.map +1 -0
  19. package/dist/src/codeIntel/languageServerPresets.js +51 -0
  20. package/dist/src/codeIntel/languageServerPresets.js.map +1 -0
  21. package/dist/src/codeIntel/languageServerRegistry.d.ts +1 -0
  22. package/dist/src/codeIntel/languageServerRegistry.d.ts.map +1 -1
  23. package/dist/src/codeIntel/languageServerRegistry.js +2 -2
  24. package/dist/src/codeIntel/languageServerRegistry.js.map +1 -1
  25. package/dist/src/config/resolveRuntimeConfig.d.ts.map +1 -1
  26. package/dist/src/config/resolveRuntimeConfig.js +5 -0
  27. package/dist/src/config/resolveRuntimeConfig.js.map +1 -1
  28. package/dist/src/extensions/builtInExtensions.d.ts +61 -0
  29. package/dist/src/extensions/builtInExtensions.d.ts.map +1 -0
  30. package/dist/src/extensions/builtInExtensions.js +218 -0
  31. package/dist/src/extensions/builtInExtensions.js.map +1 -0
  32. package/dist/src/extensions/filterOutputPolicy.d.ts +21 -0
  33. package/dist/src/extensions/filterOutputPolicy.d.ts.map +1 -0
  34. package/dist/src/extensions/filterOutputPolicy.js +121 -0
  35. package/dist/src/extensions/filterOutputPolicy.js.map +1 -0
  36. package/dist/src/extensions/securityPolicy.d.ts +27 -0
  37. package/dist/src/extensions/securityPolicy.d.ts.map +1 -0
  38. package/dist/src/extensions/securityPolicy.js +238 -0
  39. package/dist/src/extensions/securityPolicy.js.map +1 -0
  40. package/dist/src/extensions/sessionCostTracker.d.ts +63 -0
  41. package/dist/src/extensions/sessionCostTracker.d.ts.map +1 -0
  42. package/dist/src/extensions/sessionCostTracker.js +213 -0
  43. package/dist/src/extensions/sessionCostTracker.js.map +1 -0
  44. package/dist/src/extensions/taskNotifications.d.ts +31 -0
  45. package/dist/src/extensions/taskNotifications.d.ts.map +1 -0
  46. package/dist/src/extensions/taskNotifications.js +50 -0
  47. package/dist/src/extensions/taskNotifications.js.map +1 -0
  48. package/dist/src/extensions/usageBar.d.ts +35 -0
  49. package/dist/src/extensions/usageBar.d.ts.map +1 -0
  50. package/dist/src/extensions/usageBar.js +67 -0
  51. package/dist/src/extensions/usageBar.js.map +1 -0
  52. package/dist/src/gui/contextRailStore.d.ts +13 -0
  53. package/dist/src/gui/contextRailStore.d.ts.map +1 -1
  54. package/dist/src/gui/contextRailStore.js +16 -0
  55. package/dist/src/gui/contextRailStore.js.map +1 -1
  56. package/dist/src/gui/electronMain.js +45 -5
  57. package/dist/src/gui/electronMain.js.map +1 -1
  58. package/dist/src/gui/guiDesignClientScript.d.ts.map +1 -1
  59. package/dist/src/gui/guiDesignClientScript.js +31 -0
  60. package/dist/src/gui/guiDesignClientScript.js.map +1 -1
  61. package/dist/src/gui/guiUsageRoutingAssets.d.ts +7 -0
  62. package/dist/src/gui/guiUsageRoutingAssets.d.ts.map +1 -0
  63. package/dist/src/gui/guiUsageRoutingAssets.js +509 -0
  64. package/dist/src/gui/guiUsageRoutingAssets.js.map +1 -0
  65. package/dist/src/gui/guiUsageRoutingHttpController.d.ts +11 -0
  66. package/dist/src/gui/guiUsageRoutingHttpController.d.ts.map +1 -0
  67. package/dist/src/gui/guiUsageRoutingHttpController.js +125 -0
  68. package/dist/src/gui/guiUsageRoutingHttpController.js.map +1 -0
  69. package/dist/src/gui/guiUsageRoutingRuntime.d.ts +36 -0
  70. package/dist/src/gui/guiUsageRoutingRuntime.d.ts.map +1 -0
  71. package/dist/src/gui/guiUsageRoutingRuntime.js +98 -0
  72. package/dist/src/gui/guiUsageRoutingRuntime.js.map +1 -0
  73. package/dist/src/gui/hadamardGui.d.ts +5 -0
  74. package/dist/src/gui/hadamardGui.d.ts.map +1 -1
  75. package/dist/src/gui/hadamardGui.js +159 -16
  76. package/dist/src/gui/hadamardGui.js.map +1 -1
  77. package/dist/src/gui/hadamardGuiAssets.d.ts.map +1 -1
  78. package/dist/src/gui/hadamardGuiAssets.js +297 -41
  79. package/dist/src/gui/hadamardGuiAssets.js.map +1 -1
  80. package/dist/src/index.d.ts +32 -2
  81. package/dist/src/index.d.ts.map +1 -1
  82. package/dist/src/index.js +16 -1
  83. package/dist/src/index.js.map +1 -1
  84. package/dist/src/keyway/electronSecretStore.d.ts +37 -0
  85. package/dist/src/keyway/electronSecretStore.d.ts.map +1 -0
  86. package/dist/src/keyway/electronSecretStore.js +105 -0
  87. package/dist/src/keyway/electronSecretStore.js.map +1 -0
  88. package/dist/src/keyway/embeddedKeyway.d.ts +34 -0
  89. package/dist/src/keyway/embeddedKeyway.d.ts.map +1 -0
  90. package/dist/src/keyway/embeddedKeyway.js +81 -0
  91. package/dist/src/keyway/embeddedKeyway.js.map +1 -0
  92. package/dist/src/keyway/keywayLoopbackGateway.d.ts +30 -0
  93. package/dist/src/keyway/keywayLoopbackGateway.d.ts.map +1 -0
  94. package/dist/src/keyway/keywayLoopbackGateway.js +71 -0
  95. package/dist/src/keyway/keywayLoopbackGateway.js.map +1 -0
  96. package/dist/src/keyway/keywayMigrationService.d.ts +44 -0
  97. package/dist/src/keyway/keywayMigrationService.d.ts.map +1 -0
  98. package/dist/src/keyway/keywayMigrationService.js +219 -0
  99. package/dist/src/keyway/keywayMigrationService.js.map +1 -0
  100. package/dist/src/keyway/keywayModelApi.d.ts +24 -0
  101. package/dist/src/keyway/keywayModelApi.d.ts.map +1 -0
  102. package/dist/src/keyway/keywayModelApi.js +106 -0
  103. package/dist/src/keyway/keywayModelApi.js.map +1 -0
  104. package/dist/src/keyway/keywayPorts.d.ts +189 -0
  105. package/dist/src/keyway/keywayPorts.d.ts.map +1 -0
  106. package/dist/src/keyway/keywayPorts.js +2 -0
  107. package/dist/src/keyway/keywayPorts.js.map +1 -0
  108. package/dist/src/keyway/keywayProviderExecutor.d.ts +30 -0
  109. package/dist/src/keyway/keywayProviderExecutor.d.ts.map +1 -0
  110. package/dist/src/keyway/keywayProviderExecutor.js +257 -0
  111. package/dist/src/keyway/keywayProviderExecutor.js.map +1 -0
  112. package/dist/src/keyway/routingComposition.d.ts +18 -0
  113. package/dist/src/keyway/routingComposition.d.ts.map +1 -0
  114. package/dist/src/keyway/routingComposition.js +19 -0
  115. package/dist/src/keyway/routingComposition.js.map +1 -0
  116. package/dist/src/keyway/usageRoutingAdminService.d.ts +86 -0
  117. package/dist/src/keyway/usageRoutingAdminService.d.ts.map +1 -0
  118. package/dist/src/keyway/usageRoutingAdminService.js +384 -0
  119. package/dist/src/keyway/usageRoutingAdminService.js.map +1 -0
  120. package/dist/src/nativeCli/crushManagedClient.d.ts +84 -0
  121. package/dist/src/nativeCli/crushManagedClient.d.ts.map +1 -0
  122. package/dist/src/nativeCli/crushManagedClient.js +978 -0
  123. package/dist/src/nativeCli/crushManagedClient.js.map +1 -0
  124. package/dist/src/nativeCli/crushNativeCliClient.d.ts +19 -0
  125. package/dist/src/nativeCli/crushNativeCliClient.d.ts.map +1 -0
  126. package/dist/src/nativeCli/crushNativeCliClient.js +243 -0
  127. package/dist/src/nativeCli/crushNativeCliClient.js.map +1 -0
  128. package/dist/src/nativeCli/keywayNativeCliAdapter.d.ts +31 -0
  129. package/dist/src/nativeCli/keywayNativeCliAdapter.d.ts.map +1 -0
  130. package/dist/src/nativeCli/keywayNativeCliAdapter.js +35 -0
  131. package/dist/src/nativeCli/keywayNativeCliAdapter.js.map +1 -0
  132. package/dist/src/nativeCli/nativeCliAuth.d.ts +24 -0
  133. package/dist/src/nativeCli/nativeCliAuth.d.ts.map +1 -0
  134. package/dist/src/nativeCli/nativeCliAuth.js +327 -0
  135. package/dist/src/nativeCli/nativeCliAuth.js.map +1 -0
  136. package/dist/src/nativeCli/nativeCliClient.d.ts +16 -0
  137. package/dist/src/nativeCli/nativeCliClient.d.ts.map +1 -0
  138. package/dist/src/nativeCli/nativeCliClient.js +575 -0
  139. package/dist/src/nativeCli/nativeCliClient.js.map +1 -0
  140. package/dist/src/nativeCli/nativeCliCodewhaleProtocol.d.ts +18 -0
  141. package/dist/src/nativeCli/nativeCliCodewhaleProtocol.d.ts.map +1 -0
  142. package/dist/src/nativeCli/nativeCliCodewhaleProtocol.js +376 -0
  143. package/dist/src/nativeCli/nativeCliCodewhaleProtocol.js.map +1 -0
  144. package/dist/src/nativeCli/nativeCliContracts.d.ts +22 -0
  145. package/dist/src/nativeCli/nativeCliContracts.d.ts.map +1 -0
  146. package/dist/src/nativeCli/nativeCliContracts.js +2 -0
  147. package/dist/src/nativeCli/nativeCliContracts.js.map +1 -0
  148. package/dist/src/nativeCli/nativeCliCursorProtocol.d.ts +7 -0
  149. package/dist/src/nativeCli/nativeCliCursorProtocol.d.ts.map +1 -0
  150. package/dist/src/nativeCli/nativeCliCursorProtocol.js +210 -0
  151. package/dist/src/nativeCli/nativeCliCursorProtocol.js.map +1 -0
  152. package/dist/src/nativeCli/nativeCliEnvironment.d.ts +3 -0
  153. package/dist/src/nativeCli/nativeCliEnvironment.d.ts.map +1 -0
  154. package/dist/src/nativeCli/nativeCliEnvironment.js +17 -0
  155. package/dist/src/nativeCli/nativeCliEnvironment.js.map +1 -0
  156. package/dist/src/nativeCli/nativeCliExecResolver.d.ts +26 -0
  157. package/dist/src/nativeCli/nativeCliExecResolver.d.ts.map +1 -0
  158. package/dist/src/nativeCli/nativeCliExecResolver.js +152 -0
  159. package/dist/src/nativeCli/nativeCliExecResolver.js.map +1 -0
  160. package/dist/src/nativeCli/nativeCliPiProtocol.d.ts +15 -0
  161. package/dist/src/nativeCli/nativeCliPiProtocol.d.ts.map +1 -0
  162. package/dist/src/nativeCli/nativeCliPiProtocol.js +329 -0
  163. package/dist/src/nativeCli/nativeCliPiProtocol.js.map +1 -0
  164. package/dist/src/nativeCli/nativeCliProcessTree.d.ts +3 -0
  165. package/dist/src/nativeCli/nativeCliProcessTree.d.ts.map +1 -0
  166. package/dist/src/nativeCli/nativeCliProcessTree.js +104 -0
  167. package/dist/src/nativeCli/nativeCliProcessTree.js.map +1 -0
  168. package/dist/src/nativeCli/reasonixAcpSession.d.ts +35 -0
  169. package/dist/src/nativeCli/reasonixAcpSession.d.ts.map +1 -0
  170. package/dist/src/nativeCli/reasonixAcpSession.js +472 -0
  171. package/dist/src/nativeCli/reasonixAcpSession.js.map +1 -0
  172. package/dist/src/nativeCli/reasonixManagedClient.d.ts +56 -0
  173. package/dist/src/nativeCli/reasonixManagedClient.d.ts.map +1 -0
  174. package/dist/src/nativeCli/reasonixManagedClient.js +293 -0
  175. package/dist/src/nativeCli/reasonixManagedClient.js.map +1 -0
  176. package/dist/src/nativeCli/reasonixNativeCliClient.d.ts +20 -0
  177. package/dist/src/nativeCli/reasonixNativeCliClient.d.ts.map +1 -0
  178. package/dist/src/nativeCli/reasonixNativeCliClient.js +317 -0
  179. package/dist/src/nativeCli/reasonixNativeCliClient.js.map +1 -0
  180. package/dist/src/parity/bridgeExecResolver.d.ts +2 -25
  181. package/dist/src/parity/bridgeExecResolver.d.ts.map +1 -1
  182. package/dist/src/parity/bridgeExecResolver.js +2 -151
  183. package/dist/src/parity/bridgeExecResolver.js.map +1 -1
  184. package/dist/src/parity/bridgeProcessTree.d.ts +2 -2
  185. package/dist/src/parity/bridgeProcessTree.d.ts.map +1 -1
  186. package/dist/src/parity/bridgeProcessTree.js +2 -82
  187. package/dist/src/parity/bridgeProcessTree.js.map +1 -1
  188. package/dist/src/parity/crushManagedClient.d.ts +2 -83
  189. package/dist/src/parity/crushManagedClient.d.ts.map +1 -1
  190. package/dist/src/parity/crushManagedClient.js +2 -977
  191. package/dist/src/parity/crushManagedClient.js.map +1 -1
  192. package/dist/src/parity/externalCliAuth.d.ts +2 -22
  193. package/dist/src/parity/externalCliAuth.d.ts.map +1 -1
  194. package/dist/src/parity/externalCliAuth.js +2 -295
  195. package/dist/src/parity/externalCliAuth.js.map +1 -1
  196. package/dist/src/parity/hadamardBridgeSdk.d.ts.map +1 -1
  197. package/dist/src/parity/hadamardBridgeSdk.js +14 -1
  198. package/dist/src/parity/hadamardBridgeSdk.js.map +1 -1
  199. package/dist/src/parity/nativeCliBridgeAdapter.d.ts +6 -0
  200. package/dist/src/parity/nativeCliBridgeAdapter.d.ts.map +1 -0
  201. package/dist/src/parity/nativeCliBridgeAdapter.js +38 -0
  202. package/dist/src/parity/nativeCliBridgeAdapter.js.map +1 -0
  203. package/dist/src/parity/reasonixAcpSession.d.ts +2 -34
  204. package/dist/src/parity/reasonixAcpSession.d.ts.map +1 -1
  205. package/dist/src/parity/reasonixAcpSession.js +2 -471
  206. package/dist/src/parity/reasonixAcpSession.js.map +1 -1
  207. package/dist/src/parity/reasonixManagedClient.d.ts +2 -55
  208. package/dist/src/parity/reasonixManagedClient.d.ts.map +1 -1
  209. package/dist/src/parity/reasonixManagedClient.js +2 -292
  210. package/dist/src/parity/reasonixManagedClient.js.map +1 -1
  211. package/dist/src/provider/openai-client.js +2 -2
  212. package/dist/src/provider/openai-client.js.map +1 -1
  213. package/dist/src/provider/openai-model-api.d.ts.map +1 -1
  214. package/dist/src/provider/openai-model-api.js +5 -1
  215. package/dist/src/provider/openai-model-api.js.map +1 -1
  216. package/dist/src/runtime/agentClient.d.ts +14 -1
  217. package/dist/src/runtime/agentClient.d.ts.map +1 -1
  218. package/dist/src/runtime/agentClient.js +60 -6
  219. package/dist/src/runtime/agentClient.js.map +1 -1
  220. package/dist/src/runtime/toolPolicyPipeline.d.ts +32 -1
  221. package/dist/src/runtime/toolPolicyPipeline.d.ts.map +1 -1
  222. package/dist/src/runtime/toolPolicyPipeline.js +43 -3
  223. package/dist/src/runtime/toolPolicyPipeline.js.map +1 -1
  224. package/dist/src/tui/hadamardTuiController.d.ts.map +1 -1
  225. package/dist/src/tui/hadamardTuiController.js +62 -8
  226. package/dist/src/tui/hadamardTuiController.js.map +1 -1
  227. package/dist/src/tui/tuiBasicCommandHandler.d.ts +4 -0
  228. package/dist/src/tui/tuiBasicCommandHandler.d.ts.map +1 -1
  229. package/dist/src/tui/tuiBasicCommandHandler.js +23 -2
  230. package/dist/src/tui/tuiBasicCommandHandler.js.map +1 -1
  231. package/dist/src/tui/tuiCatalogCommandHandler.d.ts +2 -0
  232. package/dist/src/tui/tuiCatalogCommandHandler.d.ts.map +1 -1
  233. package/dist/src/tui/tuiCatalogCommandHandler.js +10 -1
  234. package/dist/src/tui/tuiCatalogCommandHandler.js.map +1 -1
  235. package/dist/src/tui/tuiUsageRoutingRuntime.d.ts +22 -0
  236. package/dist/src/tui/tuiUsageRoutingRuntime.d.ts.map +1 -0
  237. package/dist/src/tui/tuiUsageRoutingRuntime.js +81 -0
  238. package/dist/src/tui/tuiUsageRoutingRuntime.js.map +1 -0
  239. package/dist/src/types.d.ts +16 -0
  240. package/dist/src/types.d.ts.map +1 -1
  241. package/dist/src/types.js.map +1 -1
  242. package/dist/src/ui/commandSurface.d.ts.map +1 -1
  243. package/dist/src/ui/commandSurface.js +45 -1
  244. package/dist/src/ui/commandSurface.js.map +1 -1
  245. package/dist/src/ui/extensionsCommandView.d.ts +18 -0
  246. package/dist/src/ui/extensionsCommandView.d.ts.map +1 -0
  247. package/dist/src/ui/extensionsCommandView.js +82 -0
  248. package/dist/src/ui/extensionsCommandView.js.map +1 -0
  249. package/dist/src/ui/lspCommandView.d.ts +17 -0
  250. package/dist/src/ui/lspCommandView.d.ts.map +1 -0
  251. package/dist/src/ui/lspCommandView.js +25 -0
  252. package/dist/src/ui/lspCommandView.js.map +1 -0
  253. package/dist/src/ui/usageRoutingCommand.d.ts +13 -0
  254. package/dist/src/ui/usageRoutingCommand.d.ts.map +1 -0
  255. package/dist/src/ui/usageRoutingCommand.js +224 -0
  256. package/dist/src/ui/usageRoutingCommand.js.map +1 -0
  257. package/dist/src/usage/budgetService.d.ts +28 -0
  258. package/dist/src/usage/budgetService.d.ts.map +1 -0
  259. package/dist/src/usage/budgetService.js +50 -0
  260. package/dist/src/usage/budgetService.js.map +1 -0
  261. package/dist/src/usage/contracts.d.ts +149 -0
  262. package/dist/src/usage/contracts.d.ts.map +1 -0
  263. package/dist/src/usage/contracts.js +2 -0
  264. package/dist/src/usage/contracts.js.map +1 -0
  265. package/dist/src/usage/index.d.ts +7 -0
  266. package/dist/src/usage/index.d.ts.map +1 -0
  267. package/dist/src/usage/index.js +4 -0
  268. package/dist/src/usage/index.js.map +1 -0
  269. package/dist/src/usage/usageLedger.d.ts +19 -0
  270. package/dist/src/usage/usageLedger.d.ts.map +1 -0
  271. package/dist/src/usage/usageLedger.js +389 -0
  272. package/dist/src/usage/usageLedger.js.map +1 -0
  273. package/dist/src/usage/usageQueryService.d.ts +12 -0
  274. package/dist/src/usage/usageQueryService.d.ts.map +1 -0
  275. package/dist/src/usage/usageQueryService.js +29 -0
  276. package/dist/src/usage/usageQueryService.js.map +1 -0
  277. package/package.json +14 -2
  278. package/scripts/prepare-gui-launcher.mjs +62 -0
@@ -76,6 +76,10 @@ import { SqliteDurableChildStore } from '../node/sqliteDurableChildStore.js';
76
76
  import { SqliteStorageV2 } from '../storage-v2/sqliteStorage.js';
77
77
  import { emptyUsage, } from '../core/index.js';
78
78
  import { estimateCost } from '../team/pricing.js';
79
+ import { SessionCostTracker } from '../extensions/sessionCostTracker.js';
80
+ import { formatUsageBar, usageBarColorLevel } from '../extensions/usageBar.js';
81
+ import { formatTaskSettledNotification } from '../extensions/taskNotifications.js';
82
+ import { BUILT_IN_EXTENSIONS, resolveBuiltInExtensionStates, } from '../extensions/builtInExtensions.js';
79
83
  import { validateWorkflowSquad, } from '../team/workflowSquad.js';
80
84
  import { listPlanFiles, planDirFor, planFilePath, readPlanFile } from '../tools/planMode/PlanModeTools.js';
81
85
  import { isReadOnlyBashCommand } from '../runtime/bashClassification.js';
@@ -96,6 +100,8 @@ import { createUnsupportedAppUpdateController, } from '../update/appUpdateServic
96
100
  import { discoverHadamardPlugins } from '../tui/pluginCatalog.js';
97
101
  import { HADAMARD_GUI_INTERACTIVE_COMMANDS, interactiveCommandUsage, parseTeamAskArguments, } from '../ui/commandSurface.js';
98
102
  import { createAgentExecutionProjectView, createAgentExecutionRootView, } from '../ui/agentExecutionView.js';
103
+ import { runExtensionsCommandView } from '../ui/extensionsCommandView.js';
104
+ import { runLspCommandView } from '../ui/lspCommandView.js';
99
105
  import { createExternalCliAgentExecutionSnapshots } from './externalCliAgentMonitor.js';
100
106
  import { ContextRailReminderScheduler, normalizeContextRailStore, readContextRailStore, sortContextRailItems, writeContextRailStore, } from './contextRailStore.js';
101
107
  import { readWorkspaceNote, writeWorkspaceNote } from './workspaceNote.js';
@@ -116,6 +122,7 @@ import { registerGuiShellHttpController } from './guiShellHttpController.js';
116
122
  import { registerGuiChatHttpController } from './guiChatHttpController.js';
117
123
  import { rejectMismatchedGuiSession } from './guiSessionHttpGuard.js';
118
124
  import { registerGuiSettingsHttpController } from './guiSettingsHttpController.js';
125
+ import { appendGuiLedgerUsage, createGuiUsageRoutingRuntime, runGuiUsageRoutingCommand } from './guiUsageRoutingRuntime.js';
119
126
  import { registerGuiTeamHttpController } from './guiTeamHttpController.js';
120
127
  import { registerGuiAgentHttpController } from './guiAgentHttpController.js';
121
128
  import { registerGuiReferenceHttpController } from './guiReferenceHttpController.js';
@@ -1760,6 +1767,24 @@ export async function startHadamardGuiServer(options = {}) {
1760
1767
  await railReminderScheduler.sync(targetWorkDir, homeDir, store);
1761
1768
  }
1762
1769
  await syncRailReminders().catch(() => undefined);
1770
+ // notifications extension: push background-task settlements into the rail
1771
+ // notification channel (drained into /api/state and /api/rail-live).
1772
+ // Enablement is checked at fire time so toggling applies immediately.
1773
+ let unsubscribeTaskNotifications = null;
1774
+ function subscribeSdkTaskNotifications() {
1775
+ unsubscribeTaskNotifications?.();
1776
+ unsubscribeTaskNotifications = sdk?.onBackgroundTaskSettled(task => {
1777
+ if (!sdk?.builtInExtensions.isEnabled('notifications'))
1778
+ return;
1779
+ const notification = formatTaskSettledNotification(task);
1780
+ railReminderScheduler.enqueueNotification({
1781
+ title: notification.title,
1782
+ text: notification.body || notification.title,
1783
+ kind: 'task',
1784
+ });
1785
+ }) ?? null;
1786
+ }
1787
+ subscribeSdkTaskNotifications();
1763
1788
  const pendingPermissions = new Map();
1764
1789
  // Terminal engine (plan phase 3). node-pty is probed once; terminalCapable
1765
1790
  // tells the renderer whether to show the terminal tab (false hides it even when
@@ -1785,6 +1810,7 @@ export async function startHadamardGuiServer(options = {}) {
1785
1810
  // to reference the same model.
1786
1811
  let activeAgentSelectionName = null;
1787
1812
  let activeBridgeModelApi = null;
1813
+ let activeKeywayRouteAlias = null;
1788
1814
  let bridgeModelLabel = null;
1789
1815
  const externalCliRuntimeManager = options.externalCliRuntimeManager
1790
1816
  ?? new ExternalCliRuntimeManager();
@@ -1903,14 +1929,22 @@ export async function startHadamardGuiServer(options = {}) {
1903
1929
  let totalInputTokens = 0;
1904
1930
  let totalOutputTokens = 0;
1905
1931
  let totalCostUsd = 0;
1932
+ // costTracker extension: per-model accumulation + durable JSONL ledger
1933
+ // (mirrors the TUI). Token totals always count; cost + ledger are gated.
1934
+ const costTracker = new SessionCostTracker(resolveGuiHomeDir());
1935
+ // usageBar extension: live context estimate from the last request.started.
1936
+ let lastContextTokenEstimate;
1906
1937
  const configUsage = new Map();
1907
- function recordUsage(model, usage) {
1938
+ function recordUsage(model, usage, runId) {
1908
1939
  const inT = usage?.input_tokens ?? 0;
1909
1940
  const outT = usage?.output_tokens ?? 0;
1910
1941
  totalInputTokens += inT;
1911
1942
  totalOutputTokens += outT;
1912
- const cost = estimateCost(model, inT, outT, resolveGuiHomeDir());
1913
- totalCostUsd = cost === null ? null : (totalCostUsd === null ? cost : totalCostUsd + cost);
1943
+ if (sdk?.builtInExtensions.isEnabled('costTracker')) {
1944
+ costTracker.record(model, usage ?? {}, { sessionId: session?.id, runId, configurationId: activeBridgeConfig?.name, source: bridgeMode ? 'bridge' : 'hadamard' });
1945
+ const cost = estimateCost(model, inT, outT, resolveGuiHomeDir());
1946
+ totalCostUsd = cost === null ? null : (totalCostUsd === null ? cost : totalCostUsd + cost);
1947
+ }
1914
1948
  if (bridgeMode && activeBridgeConfig) {
1915
1949
  const rec = configUsage.get(activeBridgeConfig.name) ?? { inputTokens: 0, outputTokens: 0, turns: 0 };
1916
1950
  rec.inputTokens += inT;
@@ -1926,6 +1960,32 @@ export async function startHadamardGuiServer(options = {}) {
1926
1960
  const cost = estimateCost(cfg.model, rec.inputTokens, rec.outputTokens, resolveGuiHomeDir());
1927
1961
  return cost !== null ? `$${cost.toFixed(4)}` : null;
1928
1962
  }
1963
+ // usageBar extension: pre-formatted statusbar widget (renderer just paints it).
1964
+ function usageBarState() {
1965
+ if (!sdk?.builtInExtensions.isEnabled('usageBar'))
1966
+ return {};
1967
+ const contextWindowTokens = currentContextWindow()
1968
+ ?? sdk.config.compact.contextWindowTokens
1969
+ ?? 200_000;
1970
+ const contextUsedTokens = lastContextTokenEstimate ?? 0;
1971
+ const pct = contextWindowTokens > 0
1972
+ ? Math.min(100, Math.round((contextUsedTokens / contextWindowTokens) * 100))
1973
+ : 0;
1974
+ return {
1975
+ usageBarText: formatUsageBar({
1976
+ contextUsedTokens,
1977
+ contextWindowTokens,
1978
+ ...(sdk.builtInExtensions.isEnabled('costTracker') && totalCostUsd !== null
1979
+ ? { sessionCostUsd: totalCostUsd }
1980
+ : {}),
1981
+ inputTokens: totalInputTokens,
1982
+ outputTokens: totalOutputTokens,
1983
+ }),
1984
+ usageBarLevel: usageBarColorLevel(pct),
1985
+ contextUsedTokens,
1986
+ contextWindowTokens,
1987
+ };
1988
+ }
1929
1989
  let heavyStateCache = null;
1930
1990
  const invalidateHeavyState = () => {
1931
1991
  heavyStateCache = null;
@@ -1937,15 +1997,28 @@ export async function startHadamardGuiServer(options = {}) {
1937
1997
  try {
1938
1998
  // When recovering from a no-credential state the session is a stub (id: ''),
1939
1999
  // so create a fresh session instead of trying to resume an empty id.
1940
- session = needsCredentials
1941
- ? await nextSdk.createSession({ model: options.model, permissionMode })
1942
- : await nextSdk.resumeSession(session.id, {
1943
- model: options.model,
1944
- permissionMode: options.permissionMode,
1945
- });
2000
+ if (needsCredentials) {
2001
+ session = await nextSdk.createSession({ model: options.model, permissionMode });
2002
+ }
2003
+ else {
2004
+ try {
2005
+ session = await nextSdk.resumeSession(session.id, {
2006
+ model: options.model,
2007
+ permissionMode: options.permissionMode,
2008
+ });
2009
+ }
2010
+ catch (error) {
2011
+ if (error?.code !== 'SESSION_NOT_FOUND')
2012
+ throw error;
2013
+ // Empty sessions are intentionally not persisted. A settings reload
2014
+ // must still apply immediately while the untouched chat is open.
2015
+ session = await nextSdk.createSession({ model: options.model, permissionMode });
2016
+ }
2017
+ }
1946
2018
  toolMetadata = await nextSdk.listToolMetadata();
1947
2019
  sdk = nextSdk;
1948
2020
  needsCredentials = false;
2021
+ subscribeSdkTaskNotifications();
1949
2022
  await restoreSessionRuntimeSelection();
1950
2023
  }
1951
2024
  catch (error) {
@@ -2525,6 +2598,9 @@ export async function startHadamardGuiServer(options = {}) {
2525
2598
  : await listArchivedSessionsForWorkDir(workDir, homeDir);
2526
2599
  const railStore = await readContextRailStore(workDir, homeDir);
2527
2600
  const activeProject = heavy.projects.find(project => project.active);
2601
+ const extensionStates = sdk?.builtInExtensions.list()
2602
+ ?? resolveBuiltInExtensionStates(store?.raw);
2603
+ const extensionStateById = new Map(extensionStates.map(item => [item.id, item]));
2528
2604
  return {
2529
2605
  workDir,
2530
2606
  platform: process.platform,
@@ -2581,6 +2657,23 @@ export async function startHadamardGuiServer(options = {}) {
2581
2657
  apiKey: env.HADAMARD_API_KEY ?? env.HADAMARD_AUTH_TOKEN ?? '',
2582
2658
  apiKeyMasked: maskApiKey(env.HADAMARD_API_KEY ?? env.HADAMARD_AUTH_TOKEN ?? ''),
2583
2659
  preferences: store ? readGuiPreferences(store.raw) : DEFAULT_GUI_PREFERENCES,
2660
+ extensions: BUILT_IN_EXTENSIONS.map(definition => ({
2661
+ id: definition.id,
2662
+ title: definition.title,
2663
+ description: definition.description,
2664
+ kind: definition.kind,
2665
+ defaultEnabled: definition.defaultEnabled,
2666
+ enabled: extensionStateById.get(definition.id)?.enabled ?? definition.defaultEnabled,
2667
+ })),
2668
+ autoDetectLanguageServers: sdk?.config.autoDetectLanguageServers
2669
+ ?? (typeof store?.raw.autoDetectLanguageServers === 'boolean'
2670
+ ? store.raw.autoDetectLanguageServers
2671
+ : true),
2672
+ languageServers: (sdk?.config.languageServers ?? []).map(server => ({
2673
+ id: server.id,
2674
+ languages: [...server.languages],
2675
+ command: server.command,
2676
+ })),
2584
2677
  browser: readHadamardBrowserSettings(store?.raw ?? {}),
2585
2678
  bridge: store?.raw?.bridge ?? {},
2586
2679
  sandbox: sdk
@@ -2597,7 +2690,7 @@ export async function startHadamardGuiServer(options = {}) {
2597
2690
  },
2598
2691
  bridgeState: {
2599
2692
  mode: bridgeMode,
2600
- enabled: bridgeModeEnabled,
2693
+ enabled: bridgeModeEnabled, activeKeywayRouteAlias,
2601
2694
  activeConfig: activeBridgeConfig
2602
2695
  ? {
2603
2696
  name: activeBridgeConfig.name,
@@ -2705,6 +2798,7 @@ export async function startHadamardGuiServer(options = {}) {
2705
2798
  costUsd: configCost(cfgName, rec),
2706
2799
  })),
2707
2800
  },
2801
+ ...usageBarState(),
2708
2802
  ...liveRunState(),
2709
2803
  terminalCapable,
2710
2804
  railItems: sortContextRailItems(railStore.items),
@@ -2801,6 +2895,23 @@ export async function startHadamardGuiServer(options = {}) {
2801
2895
  allowEvaluate: browserBody.allowEvaluate === true,
2802
2896
  });
2803
2897
  }
2898
+ if (typeof body.autoDetectLanguageServers === 'boolean') {
2899
+ raw.autoDetectLanguageServers = body.autoDetectLanguageServers;
2900
+ }
2901
+ if (isPlainRecord(body.extensions)) {
2902
+ const existingExtensions = isPlainRecord(raw.extensions) ? { ...raw.extensions } : {};
2903
+ for (const definition of BUILT_IN_EXTENSIONS) {
2904
+ const requested = body.extensions[definition.id];
2905
+ if (!isPlainRecord(requested) || typeof requested.enabled !== 'boolean')
2906
+ continue;
2907
+ const existingValue = existingExtensions[definition.id];
2908
+ const existing = isPlainRecord(existingValue)
2909
+ ? { ...existingValue }
2910
+ : {};
2911
+ existingExtensions[definition.id] = { ...existing, enabled: requested.enabled };
2912
+ }
2913
+ raw.extensions = existingExtensions;
2914
+ }
2804
2915
  const preferences = isPlainRecord(body.preferences)
2805
2916
  ? readGuiPreferences({ gui: body.preferences })
2806
2917
  : readGuiPreferences(raw);
@@ -3506,7 +3617,7 @@ export async function startHadamardGuiServer(options = {}) {
3506
3617
  }
3507
3618
  const result = await stream.result;
3508
3619
  desc.status = 'done';
3509
- recordUsage(desc.model ?? session.model, result.usage);
3620
+ recordUsage(desc.model ?? session.model, result.usage, result.runId);
3510
3621
  return result.text ?? '';
3511
3622
  }
3512
3623
  catch (error) {
@@ -3649,7 +3760,7 @@ export async function startHadamardGuiServer(options = {}) {
3649
3760
  try {
3650
3761
  let routed;
3651
3762
  const configActive = !!activeBridgeConfig;
3652
- const effectiveBridgeMode = bridgeMode && bridgeModeEnabled;
3763
+ const effectiveBridgeMode = bridgeMode && (bridgeModeEnabled || Boolean(activeKeywayRouteAlias));
3653
3764
  if (activeRouter && !effectiveBridgeMode && !configActive) {
3654
3765
  const decision = await resolveRoutedRun(activeRouter, input, runAbort.signal, {
3655
3766
  projectDir: workDir,
@@ -3700,7 +3811,7 @@ export async function startHadamardGuiServer(options = {}) {
3700
3811
  events.push({ type: 'command.result', title: `Automation result - ${task.name}`, text });
3701
3812
  }
3702
3813
  const effectiveModel = hadamardModel ?? routed?.model ?? activeBridgeModelApi?.model ?? session.model;
3703
- recordUsage(effectiveModel, result.usage);
3814
+ recordUsage(effectiveModel, result.usage, result.runId);
3704
3815
  if (result.usage) {
3705
3816
  desc.tokenUsage = {
3706
3817
  input: result.usage.input_tokens ?? 0,
@@ -3736,6 +3847,7 @@ export async function startHadamardGuiServer(options = {}) {
3736
3847
  // it; streamRun injects {model, modelApi} per-run on the SAME session, so
3737
3848
  // context survives switching bridge↔hadamard. No child process anywhere.
3738
3849
  async function activateBridgeConfig(config) {
3850
+ activeKeywayRouteAlias = null;
3739
3851
  if (!bridgeModeEnabled) {
3740
3852
  throw new GuiRuntimeMutationConflictError('Bridge mode is disabled. Enable it from the main Configuration tab before selecting a bridge config.');
3741
3853
  }
@@ -3780,6 +3892,7 @@ export async function startHadamardGuiServer(options = {}) {
3780
3892
  activeBridgeConfig = null;
3781
3893
  activeAgentSelectionName = null;
3782
3894
  activeBridgeModelApi = null;
3895
+ activeKeywayRouteAlias = null;
3783
3896
  bridgeModelLabel = null;
3784
3897
  // session context stays intact — switching back to the default provider.
3785
3898
  }
@@ -4283,6 +4396,9 @@ export async function startHadamardGuiServer(options = {}) {
4283
4396
  const spaceIndex = raw.indexOf(' ');
4284
4397
  const name = (spaceIndex === -1 ? raw.slice(1) : raw.slice(1, spaceIndex)).toLowerCase();
4285
4398
  const args = spaceIndex === -1 ? '' : raw.slice(spaceIndex + 1).trim();
4399
+ const usageRoutingResult = await runGuiUsageRoutingCommand(usageRoutingRuntime.admin, name, args, usageRoutingRuntime.activateRoute);
4400
+ if (usageRoutingResult)
4401
+ return [usageRoutingResult];
4286
4402
  switch (name) {
4287
4403
  case 'help':
4288
4404
  return [{
@@ -4689,6 +4805,26 @@ export async function startHadamardGuiServer(options = {}) {
4689
4805
  return [{ type: 'error', message: error instanceof Error ? error.message : String(error) }];
4690
4806
  }
4691
4807
  }
4808
+ case 'extensions': {
4809
+ if (!sdk)
4810
+ return [{ type: 'error', message: 'Extensions require a configured Hadamard provider.' }];
4811
+ try {
4812
+ const result = await runExtensionsCommandView(sdk.builtInExtensions, args);
4813
+ return [
4814
+ { type: 'command.result', title: 'Extensions', text: result.message, items: result.items },
4815
+ ...(args.trim() ? [{ type: 'state' }] : []),
4816
+ ];
4817
+ }
4818
+ catch (error) {
4819
+ return [{ type: 'error', message: error instanceof Error ? error.message : String(error) }];
4820
+ }
4821
+ }
4822
+ case 'lsp': {
4823
+ if (!sdk)
4824
+ return [{ type: 'error', message: 'Language server status requires a configured Hadamard provider.' }];
4825
+ const result = await runLspCommandView(sdk.codeIntelligence);
4826
+ return [{ type: 'command.result', title: 'Language servers', text: result.message, items: result.items }];
4827
+ }
4692
4828
  case 'automation': {
4693
4829
  if (args === 'new') {
4694
4830
  return [{ type: 'notice', message: 'Open Automation and select New task.' }];
@@ -5283,6 +5419,7 @@ export async function startHadamardGuiServer(options = {}) {
5283
5419
  lines.push(` ${cfgName}${star} — ${rec.turns} turns, ${(rec.inputTokens + rec.outputTokens).toLocaleString()} tokens${cost ? ', ' + cost : ''}`);
5284
5420
  }
5285
5421
  }
5422
+ await appendGuiLedgerUsage(lines, !!sdk?.builtInExtensions.isEnabled('costTracker'), resolveGuiHomeDir());
5286
5423
  return [{ type: 'command.result', title: 'Usage', text: lines.join('\n') }];
5287
5424
  }
5288
5425
  case 'doctor': {
@@ -6160,6 +6297,7 @@ export async function startHadamardGuiServer(options = {}) {
6160
6297
  const runBridgeMode = bridgeMode;
6161
6298
  const runBridgeConfig = activeBridgeConfig;
6162
6299
  const runBridgeModelApi = activeBridgeModelApi;
6300
+ const runKeywayRouteAlias = activeKeywayRouteAlias;
6163
6301
  const runRouter = activeRouter;
6164
6302
  const runAgentOptions = currentEffectiveAgentRunOptions();
6165
6303
  const runTools = currentRunTools();
@@ -6397,8 +6535,8 @@ export async function startHadamardGuiServer(options = {}) {
6397
6535
  stream = createExternalCliAgentStream(input, externalCliConfig, runId, runAbort.signal, runSession, runWorkDir);
6398
6536
  }
6399
6537
  else if (runBridgeMode && runBridgeModelApi) {
6400
- const bridgeName = runBridgeConfig?.name ?? 'bridge';
6401
- send({ type: 'notice', message: `bridge -> ${bridgeName} (${runBridgeModelApi.model})` });
6538
+ const routeLabel = runKeywayRouteAlias ? `keyway route ${runKeywayRouteAlias}` : `bridge ${runBridgeConfig?.name ?? 'bridge'}`;
6539
+ send({ type: 'notice', message: `${routeLabel} -> ${runBridgeModelApi.model}` });
6402
6540
  stream = runSession.stream(expandImageRefs(input, runWorkDir), {
6403
6541
  ...effectiveAgentOptions,
6404
6542
  signal: withAgentRunTimeout(runAbort.signal),
@@ -6433,6 +6571,9 @@ export async function startHadamardGuiServer(options = {}) {
6433
6571
  const toolCallInputs = new Map();
6434
6572
  for await (const event of stream) {
6435
6573
  forwardAgentEvent(event, send, runId);
6574
+ if (event.type === 'request.started' && typeof event.requestTokenEstimate === 'number') {
6575
+ lastContextTokenEstimate = event.requestTokenEstimate;
6576
+ }
6436
6577
  if (event.type === 'error')
6437
6578
  errorEventSeen = true;
6438
6579
  if (event.type === 'tool.call') {
@@ -6475,7 +6616,7 @@ export async function startHadamardGuiServer(options = {}) {
6475
6616
  ?? routed?.model
6476
6617
  ?? runBridgeModelApi?.model
6477
6618
  ?? runSession.model;
6478
- recordUsage(effectiveModel, result.usage);
6619
+ recordUsage(effectiveModel, result.usage, result.runId);
6479
6620
  desc.status = 'done';
6480
6621
  const runUsage = result.usage;
6481
6622
  if (runUsage)
@@ -7102,6 +7243,7 @@ export async function startHadamardGuiServer(options = {}) {
7102
7243
  body: runtimeMutationErrorBody(error),
7103
7244
  }),
7104
7245
  });
7246
+ const usageRoutingRuntime = await createGuiUsageRoutingRuntime({ router: httpRouter, homeDir: resolveGuiHomeDir(), workDir, secretStore: options.keywaySecretStore, admin: options.usageRoutingAdmin, onRouteSelected: selection => withRuntimeMutation(async () => { disableBridge(); activeRouter = null; routedModelLabel = null; activeBridgeModelApi = { model: selection.model, modelApi: selection.modelApi, maxTokens: 32000 }; bridgeModelLabel = selection.model; bridgeMode = true; activeKeywayRouteAlias = selection.routeAlias; await persistSessionRuntimeMetadata(); }) });
7105
7247
  function parseDeleteStrategy(raw) {
7106
7248
  if (!isPlainRecord(raw))
7107
7249
  return { type: 'leave' };
@@ -10168,6 +10310,7 @@ export async function startHadamardGuiServer(options = {}) {
10168
10310
  await automationScheduler.dispose();
10169
10311
  terminalManager.closeAll();
10170
10312
  await externalCliRuntimeManager.close().catch(() => undefined);
10313
+ await usageRoutingRuntime?.close();
10171
10314
  if (sdk) {
10172
10315
  for (let attempt = 1; attempt <= 2; attempt += 1) {
10173
10316
  try {