@trenchwork/coder 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (560) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +173 -0
  3. package/agents/trenchwork-code.rules.json +199 -0
  4. package/dist/bin/deepseek.d.ts +3 -0
  5. package/dist/bin/deepseek.d.ts.map +1 -0
  6. package/dist/bin/deepseek.js +23 -0
  7. package/dist/bin/deepseek.js.map +1 -0
  8. package/dist/capabilities/baseCapability.d.ts +72 -0
  9. package/dist/capabilities/baseCapability.d.ts.map +1 -0
  10. package/dist/capabilities/baseCapability.js +183 -0
  11. package/dist/capabilities/baseCapability.js.map +1 -0
  12. package/dist/capabilities/bashCapability.d.ts +13 -0
  13. package/dist/capabilities/bashCapability.d.ts.map +1 -0
  14. package/dist/capabilities/bashCapability.js +24 -0
  15. package/dist/capabilities/bashCapability.js.map +1 -0
  16. package/dist/capabilities/editCapability.d.ts +17 -0
  17. package/dist/capabilities/editCapability.d.ts.map +1 -0
  18. package/dist/capabilities/editCapability.js +27 -0
  19. package/dist/capabilities/editCapability.js.map +1 -0
  20. package/dist/capabilities/enhancedGitCapability.d.ts +7 -0
  21. package/dist/capabilities/enhancedGitCapability.d.ts.map +1 -0
  22. package/dist/capabilities/enhancedGitCapability.js +220 -0
  23. package/dist/capabilities/enhancedGitCapability.js.map +1 -0
  24. package/dist/capabilities/filesystemCapability.d.ts +13 -0
  25. package/dist/capabilities/filesystemCapability.d.ts.map +1 -0
  26. package/dist/capabilities/filesystemCapability.js +24 -0
  27. package/dist/capabilities/filesystemCapability.js.map +1 -0
  28. package/dist/capabilities/gitHistoryCapability.d.ts +6 -0
  29. package/dist/capabilities/gitHistoryCapability.d.ts.map +1 -0
  30. package/dist/capabilities/gitHistoryCapability.js +184 -0
  31. package/dist/capabilities/gitHistoryCapability.js.map +1 -0
  32. package/dist/capabilities/hitlCapability.d.ts +18 -0
  33. package/dist/capabilities/hitlCapability.d.ts.map +1 -0
  34. package/dist/capabilities/hitlCapability.js +29 -0
  35. package/dist/capabilities/hitlCapability.js.map +1 -0
  36. package/dist/capabilities/index.d.ts +11 -0
  37. package/dist/capabilities/index.d.ts.map +1 -0
  38. package/dist/capabilities/index.js +16 -0
  39. package/dist/capabilities/index.js.map +1 -0
  40. package/dist/capabilities/memoryCapability.d.ts +10 -0
  41. package/dist/capabilities/memoryCapability.d.ts.map +1 -0
  42. package/dist/capabilities/memoryCapability.js +22 -0
  43. package/dist/capabilities/memoryCapability.js.map +1 -0
  44. package/dist/capabilities/notebookCapability.d.ts +6 -0
  45. package/dist/capabilities/notebookCapability.d.ts.map +1 -0
  46. package/dist/capabilities/notebookCapability.js +17 -0
  47. package/dist/capabilities/notebookCapability.js.map +1 -0
  48. package/dist/capabilities/searchCapability.d.ts +19 -0
  49. package/dist/capabilities/searchCapability.d.ts.map +1 -0
  50. package/dist/capabilities/searchCapability.js +29 -0
  51. package/dist/capabilities/searchCapability.js.map +1 -0
  52. package/dist/capabilities/skillCapability.d.ts +6 -0
  53. package/dist/capabilities/skillCapability.d.ts.map +1 -0
  54. package/dist/capabilities/skillCapability.js +17 -0
  55. package/dist/capabilities/skillCapability.js.map +1 -0
  56. package/dist/capabilities/todoCapability.d.ts +11 -0
  57. package/dist/capabilities/todoCapability.d.ts.map +1 -0
  58. package/dist/capabilities/todoCapability.js +22 -0
  59. package/dist/capabilities/todoCapability.js.map +1 -0
  60. package/dist/capabilities/toolManifest.d.ts +3 -0
  61. package/dist/capabilities/toolManifest.d.ts.map +1 -0
  62. package/dist/capabilities/toolManifest.js +163 -0
  63. package/dist/capabilities/toolManifest.js.map +1 -0
  64. package/dist/capabilities/toolRegistry.d.ts +25 -0
  65. package/dist/capabilities/toolRegistry.d.ts.map +1 -0
  66. package/dist/capabilities/toolRegistry.js +150 -0
  67. package/dist/capabilities/toolRegistry.js.map +1 -0
  68. package/dist/capabilities/unifiedCodingCapability.d.ts +62 -0
  69. package/dist/capabilities/unifiedCodingCapability.d.ts.map +1 -0
  70. package/dist/capabilities/unifiedCodingCapability.js +790 -0
  71. package/dist/capabilities/unifiedCodingCapability.js.map +1 -0
  72. package/dist/capabilities/webCapability.d.ts +23 -0
  73. package/dist/capabilities/webCapability.d.ts.map +1 -0
  74. package/dist/capabilities/webCapability.js +33 -0
  75. package/dist/capabilities/webCapability.js.map +1 -0
  76. package/dist/config.d.ts +25 -0
  77. package/dist/config.d.ts.map +1 -0
  78. package/dist/config.js +181 -0
  79. package/dist/config.js.map +1 -0
  80. package/dist/contracts/agent-profiles.schema.json +25 -0
  81. package/dist/contracts/agent-schemas.json +158 -0
  82. package/dist/contracts/models.schema.json +9 -0
  83. package/dist/contracts/module-schema.json +367 -0
  84. package/dist/contracts/schemas/agent-profile.schema.json +157 -0
  85. package/dist/contracts/schemas/agent-rules.schema.json +238 -0
  86. package/dist/contracts/schemas/agent-schemas.schema.json +528 -0
  87. package/dist/contracts/schemas/agent.schema.json +90 -0
  88. package/dist/contracts/schemas/tool-selection.schema.json +174 -0
  89. package/dist/contracts/tools.schema.json +42 -0
  90. package/dist/contracts/unified-schema.json +40 -0
  91. package/dist/contracts/v1/agent.d.ts +225 -0
  92. package/dist/contracts/v1/agent.d.ts.map +1 -0
  93. package/dist/contracts/v1/agent.js +8 -0
  94. package/dist/contracts/v1/agent.js.map +1 -0
  95. package/dist/contracts/v1/agentProfileManifest.d.ts +60 -0
  96. package/dist/contracts/v1/agentProfileManifest.d.ts.map +1 -0
  97. package/dist/contracts/v1/agentProfileManifest.js +9 -0
  98. package/dist/contracts/v1/agentProfileManifest.js.map +1 -0
  99. package/dist/contracts/v1/agentRules.d.ts +60 -0
  100. package/dist/contracts/v1/agentRules.d.ts.map +1 -0
  101. package/dist/contracts/v1/agentRules.js +10 -0
  102. package/dist/contracts/v1/agentRules.js.map +1 -0
  103. package/dist/contracts/v1/provider.d.ts +149 -0
  104. package/dist/contracts/v1/provider.d.ts.map +1 -0
  105. package/dist/contracts/v1/provider.js +7 -0
  106. package/dist/contracts/v1/provider.js.map +1 -0
  107. package/dist/contracts/v1/tool.d.ts +136 -0
  108. package/dist/contracts/v1/tool.d.ts.map +1 -0
  109. package/dist/contracts/v1/tool.js +7 -0
  110. package/dist/contracts/v1/tool.js.map +1 -0
  111. package/dist/contracts/v1/toolAccess.d.ts +43 -0
  112. package/dist/contracts/v1/toolAccess.d.ts.map +1 -0
  113. package/dist/contracts/v1/toolAccess.js +9 -0
  114. package/dist/contracts/v1/toolAccess.js.map +1 -0
  115. package/dist/core/adversarial.d.ts +38 -0
  116. package/dist/core/adversarial.d.ts.map +1 -0
  117. package/dist/core/adversarial.js +106 -0
  118. package/dist/core/adversarial.js.map +1 -0
  119. package/dist/core/adversarialCorrection.d.ts +22 -0
  120. package/dist/core/adversarialCorrection.d.ts.map +1 -0
  121. package/dist/core/adversarialCorrection.js +25 -0
  122. package/dist/core/adversarialCorrection.js.map +1 -0
  123. package/dist/core/agent.d.ts +331 -0
  124. package/dist/core/agent.d.ts.map +1 -0
  125. package/dist/core/agent.js +1637 -0
  126. package/dist/core/agent.js.map +1 -0
  127. package/dist/core/agentProfileManifest.d.ts +3 -0
  128. package/dist/core/agentProfileManifest.d.ts.map +1 -0
  129. package/dist/core/agentProfileManifest.js +188 -0
  130. package/dist/core/agentProfileManifest.js.map +1 -0
  131. package/dist/core/agentProfiles.d.ts +22 -0
  132. package/dist/core/agentProfiles.d.ts.map +1 -0
  133. package/dist/core/agentProfiles.js +35 -0
  134. package/dist/core/agentProfiles.js.map +1 -0
  135. package/dist/core/agentRegistry.d.ts +111 -0
  136. package/dist/core/agentRegistry.d.ts.map +1 -0
  137. package/dist/core/agentRegistry.js +229 -0
  138. package/dist/core/agentRegistry.js.map +1 -0
  139. package/dist/core/agentRulebook.d.ts +11 -0
  140. package/dist/core/agentRulebook.d.ts.map +1 -0
  141. package/dist/core/agentRulebook.js +136 -0
  142. package/dist/core/agentRulebook.js.map +1 -0
  143. package/dist/core/agentSchemaLoader.d.ts +131 -0
  144. package/dist/core/agentSchemaLoader.d.ts.map +1 -0
  145. package/dist/core/agentSchemaLoader.js +235 -0
  146. package/dist/core/agentSchemaLoader.js.map +1 -0
  147. package/dist/core/aiErrorFixer.d.ts +57 -0
  148. package/dist/core/aiErrorFixer.d.ts.map +1 -0
  149. package/dist/core/aiErrorFixer.js +214 -0
  150. package/dist/core/aiErrorFixer.js.map +1 -0
  151. package/dist/core/bashCommandGuidance.d.ts +16 -0
  152. package/dist/core/bashCommandGuidance.d.ts.map +1 -0
  153. package/dist/core/bashCommandGuidance.js +40 -0
  154. package/dist/core/bashCommandGuidance.js.map +1 -0
  155. package/dist/core/compactionNote.d.ts +13 -0
  156. package/dist/core/compactionNote.d.ts.map +1 -0
  157. package/dist/core/compactionNote.js +13 -0
  158. package/dist/core/compactionNote.js.map +1 -0
  159. package/dist/core/constants.d.ts +31 -0
  160. package/dist/core/constants.d.ts.map +1 -0
  161. package/dist/core/constants.js +62 -0
  162. package/dist/core/constants.js.map +1 -0
  163. package/dist/core/contextManager.d.ts +271 -0
  164. package/dist/core/contextManager.d.ts.map +1 -0
  165. package/dist/core/contextManager.js +1076 -0
  166. package/dist/core/contextManager.js.map +1 -0
  167. package/dist/core/contextUsage.d.ts +28 -0
  168. package/dist/core/contextUsage.d.ts.map +1 -0
  169. package/dist/core/contextUsage.js +62 -0
  170. package/dist/core/contextUsage.js.map +1 -0
  171. package/dist/core/contextWindow.d.ts +42 -0
  172. package/dist/core/contextWindow.d.ts.map +1 -0
  173. package/dist/core/contextWindow.js +127 -0
  174. package/dist/core/contextWindow.js.map +1 -0
  175. package/dist/core/customCommands.d.ts +19 -0
  176. package/dist/core/customCommands.d.ts.map +1 -0
  177. package/dist/core/customCommands.js +85 -0
  178. package/dist/core/customCommands.js.map +1 -0
  179. package/dist/core/diffPanel.d.ts +30 -0
  180. package/dist/core/diffPanel.d.ts.map +1 -0
  181. package/dist/core/diffPanel.js +48 -0
  182. package/dist/core/diffPanel.js.map +1 -0
  183. package/dist/core/errorClassification.d.ts +44 -0
  184. package/dist/core/errorClassification.d.ts.map +1 -0
  185. package/dist/core/errorClassification.js +333 -0
  186. package/dist/core/errorClassification.js.map +1 -0
  187. package/dist/core/errors/apiKeyErrors.d.ts +11 -0
  188. package/dist/core/errors/apiKeyErrors.d.ts.map +1 -0
  189. package/dist/core/errors/apiKeyErrors.js +159 -0
  190. package/dist/core/errors/apiKeyErrors.js.map +1 -0
  191. package/dist/core/errors/errorTypes.d.ts +111 -0
  192. package/dist/core/errors/errorTypes.d.ts.map +1 -0
  193. package/dist/core/errors/errorTypes.js +345 -0
  194. package/dist/core/errors/errorTypes.js.map +1 -0
  195. package/dist/core/errors/index.d.ts +50 -0
  196. package/dist/core/errors/index.d.ts.map +1 -0
  197. package/dist/core/errors/index.js +156 -0
  198. package/dist/core/errors/index.js.map +1 -0
  199. package/dist/core/errors/networkErrors.d.ts +14 -0
  200. package/dist/core/errors/networkErrors.d.ts.map +1 -0
  201. package/dist/core/errors/networkErrors.js +53 -0
  202. package/dist/core/errors/networkErrors.js.map +1 -0
  203. package/dist/core/errors/safetyValidator.d.ts +109 -0
  204. package/dist/core/errors/safetyValidator.d.ts.map +1 -0
  205. package/dist/core/errors/safetyValidator.js +272 -0
  206. package/dist/core/errors/safetyValidator.js.map +1 -0
  207. package/dist/core/errors.d.ts +4 -0
  208. package/dist/core/errors.d.ts.map +1 -0
  209. package/dist/core/errors.js +33 -0
  210. package/dist/core/errors.js.map +1 -0
  211. package/dist/core/failureRegistry.d.ts +30 -0
  212. package/dist/core/failureRegistry.d.ts.map +1 -0
  213. package/dist/core/failureRegistry.js +74 -0
  214. package/dist/core/failureRegistry.js.map +1 -0
  215. package/dist/core/fileMentions.d.ts +40 -0
  216. package/dist/core/fileMentions.d.ts.map +1 -0
  217. package/dist/core/fileMentions.js +136 -0
  218. package/dist/core/fileMentions.js.map +1 -0
  219. package/dist/core/finalResponseFormatter.d.ts +10 -0
  220. package/dist/core/finalResponseFormatter.d.ts.map +1 -0
  221. package/dist/core/finalResponseFormatter.js +14 -0
  222. package/dist/core/finalResponseFormatter.js.map +1 -0
  223. package/dist/core/guardrails.d.ts +146 -0
  224. package/dist/core/guardrails.d.ts.map +1 -0
  225. package/dist/core/guardrails.js +361 -0
  226. package/dist/core/guardrails.js.map +1 -0
  227. package/dist/core/hitl.d.ts +119 -0
  228. package/dist/core/hitl.d.ts.map +1 -0
  229. package/dist/core/hitl.js +396 -0
  230. package/dist/core/hitl.js.map +1 -0
  231. package/dist/core/hooks.d.ts +95 -0
  232. package/dist/core/hooks.d.ts.map +1 -0
  233. package/dist/core/hooks.js +236 -0
  234. package/dist/core/hooks.js.map +1 -0
  235. package/dist/core/hostedAuth.d.ts +88 -0
  236. package/dist/core/hostedAuth.d.ts.map +1 -0
  237. package/dist/core/hostedAuth.js +219 -0
  238. package/dist/core/hostedAuth.js.map +1 -0
  239. package/dist/core/inputProtection.d.ts +122 -0
  240. package/dist/core/inputProtection.d.ts.map +1 -0
  241. package/dist/core/inputProtection.js +422 -0
  242. package/dist/core/inputProtection.js.map +1 -0
  243. package/dist/core/modelDiscovery.d.ts +102 -0
  244. package/dist/core/modelDiscovery.d.ts.map +1 -0
  245. package/dist/core/modelDiscovery.js +416 -0
  246. package/dist/core/modelDiscovery.js.map +1 -0
  247. package/dist/core/multilinePasteHandler.d.ts +35 -0
  248. package/dist/core/multilinePasteHandler.d.ts.map +1 -0
  249. package/dist/core/multilinePasteHandler.js +81 -0
  250. package/dist/core/multilinePasteHandler.js.map +1 -0
  251. package/dist/core/permissionMode.d.ts +40 -0
  252. package/dist/core/permissionMode.d.ts.map +1 -0
  253. package/dist/core/permissionMode.js +86 -0
  254. package/dist/core/permissionMode.js.map +1 -0
  255. package/dist/core/postWriteDiagnostics.d.ts +32 -0
  256. package/dist/core/postWriteDiagnostics.d.ts.map +1 -0
  257. package/dist/core/postWriteDiagnostics.js +127 -0
  258. package/dist/core/postWriteDiagnostics.js.map +1 -0
  259. package/dist/core/preferences.d.ts +66 -0
  260. package/dist/core/preferences.d.ts.map +1 -0
  261. package/dist/core/preferences.js +310 -0
  262. package/dist/core/preferences.js.map +1 -0
  263. package/dist/core/quota.d.ts +61 -0
  264. package/dist/core/quota.d.ts.map +1 -0
  265. package/dist/core/quota.js +104 -0
  266. package/dist/core/quota.js.map +1 -0
  267. package/dist/core/quotaErrors.d.ts +42 -0
  268. package/dist/core/quotaErrors.d.ts.map +1 -0
  269. package/dist/core/quotaErrors.js +86 -0
  270. package/dist/core/quotaErrors.js.map +1 -0
  271. package/dist/core/refusalDetection.d.ts +2 -0
  272. package/dist/core/refusalDetection.d.ts.map +1 -0
  273. package/dist/core/refusalDetection.js +51 -0
  274. package/dist/core/refusalDetection.js.map +1 -0
  275. package/dist/core/relativeTime.d.ts +8 -0
  276. package/dist/core/relativeTime.d.ts.map +1 -0
  277. package/dist/core/relativeTime.js +29 -0
  278. package/dist/core/relativeTime.js.map +1 -0
  279. package/dist/core/resultVerification.d.ts +48 -0
  280. package/dist/core/resultVerification.d.ts.map +1 -0
  281. package/dist/core/resultVerification.js +127 -0
  282. package/dist/core/resultVerification.js.map +1 -0
  283. package/dist/core/rewind.d.ts +14 -0
  284. package/dist/core/rewind.d.ts.map +1 -0
  285. package/dist/core/rewind.js +25 -0
  286. package/dist/core/rewind.js.map +1 -0
  287. package/dist/core/schemaValidator.d.ts +49 -0
  288. package/dist/core/schemaValidator.d.ts.map +1 -0
  289. package/dist/core/schemaValidator.js +234 -0
  290. package/dist/core/schemaValidator.js.map +1 -0
  291. package/dist/core/secretStore.d.ts +59 -0
  292. package/dist/core/secretStore.d.ts.map +1 -0
  293. package/dist/core/secretStore.js +278 -0
  294. package/dist/core/secretStore.js.map +1 -0
  295. package/dist/core/sessionStorage.d.ts +10 -0
  296. package/dist/core/sessionStorage.d.ts.map +1 -0
  297. package/dist/core/sessionStorage.js +46 -0
  298. package/dist/core/sessionStorage.js.map +1 -0
  299. package/dist/core/sessionStore.d.ts +35 -0
  300. package/dist/core/sessionStore.d.ts.map +1 -0
  301. package/dist/core/sessionStore.js +190 -0
  302. package/dist/core/sessionStore.js.map +1 -0
  303. package/dist/core/shutdown.d.ts +34 -0
  304. package/dist/core/shutdown.d.ts.map +1 -0
  305. package/dist/core/shutdown.js +186 -0
  306. package/dist/core/shutdown.js.map +1 -0
  307. package/dist/core/slashCommands.d.ts +38 -0
  308. package/dist/core/slashCommands.d.ts.map +1 -0
  309. package/dist/core/slashCommands.js +72 -0
  310. package/dist/core/slashCommands.js.map +1 -0
  311. package/dist/core/subAgentNote.d.ts +15 -0
  312. package/dist/core/subAgentNote.d.ts.map +1 -0
  313. package/dist/core/subAgentNote.js +16 -0
  314. package/dist/core/subAgentNote.js.map +1 -0
  315. package/dist/core/sudoPasswordManager.d.ts +52 -0
  316. package/dist/core/sudoPasswordManager.d.ts.map +1 -0
  317. package/dist/core/sudoPasswordManager.js +115 -0
  318. package/dist/core/sudoPasswordManager.js.map +1 -0
  319. package/dist/core/taskCompletionDetector.d.ts +117 -0
  320. package/dist/core/taskCompletionDetector.d.ts.map +1 -0
  321. package/dist/core/taskCompletionDetector.js +532 -0
  322. package/dist/core/taskCompletionDetector.js.map +1 -0
  323. package/dist/core/testFailureMonitor.d.ts +67 -0
  324. package/dist/core/testFailureMonitor.d.ts.map +1 -0
  325. package/dist/core/testFailureMonitor.js +262 -0
  326. package/dist/core/testFailureMonitor.js.map +1 -0
  327. package/dist/core/thinkingVerbs.d.ts +31 -0
  328. package/dist/core/thinkingVerbs.d.ts.map +1 -0
  329. package/dist/core/thinkingVerbs.js +58 -0
  330. package/dist/core/thinkingVerbs.js.map +1 -0
  331. package/dist/core/toolPreconditions.d.ts +34 -0
  332. package/dist/core/toolPreconditions.d.ts.map +1 -0
  333. package/dist/core/toolPreconditions.js +242 -0
  334. package/dist/core/toolPreconditions.js.map +1 -0
  335. package/dist/core/toolRuntime.d.ts +193 -0
  336. package/dist/core/toolRuntime.d.ts.map +1 -0
  337. package/dist/core/toolRuntime.js +526 -0
  338. package/dist/core/toolRuntime.js.map +1 -0
  339. package/dist/core/turnGovernor.d.ts +63 -0
  340. package/dist/core/turnGovernor.d.ts.map +1 -0
  341. package/dist/core/turnGovernor.js +94 -0
  342. package/dist/core/turnGovernor.js.map +1 -0
  343. package/dist/core/types/utilityTypes.d.ts +183 -0
  344. package/dist/core/types/utilityTypes.d.ts.map +1 -0
  345. package/dist/core/types/utilityTypes.js +273 -0
  346. package/dist/core/types/utilityTypes.js.map +1 -0
  347. package/dist/core/types.d.ts +334 -0
  348. package/dist/core/types.d.ts.map +1 -0
  349. package/dist/core/types.js +76 -0
  350. package/dist/core/types.js.map +1 -0
  351. package/dist/core/updateChecker.d.ts +148 -0
  352. package/dist/core/updateChecker.d.ts.map +1 -0
  353. package/dist/core/updateChecker.js +605 -0
  354. package/dist/core/updateChecker.js.map +1 -0
  355. package/dist/core/usage.d.ts +28 -0
  356. package/dist/core/usage.d.ts.map +1 -0
  357. package/dist/core/usage.js +77 -0
  358. package/dist/core/usage.js.map +1 -0
  359. package/dist/headless/interactiveShell.d.ts +47 -0
  360. package/dist/headless/interactiveShell.d.ts.map +1 -0
  361. package/dist/headless/interactiveShell.js +2495 -0
  362. package/dist/headless/interactiveShell.js.map +1 -0
  363. package/dist/leanAgent.d.ts +73 -0
  364. package/dist/leanAgent.d.ts.map +1 -0
  365. package/dist/leanAgent.js +177 -0
  366. package/dist/leanAgent.js.map +1 -0
  367. package/dist/plugins/providers/deepseek/index.d.ts +12 -0
  368. package/dist/plugins/providers/deepseek/index.d.ts.map +1 -0
  369. package/dist/plugins/providers/deepseek/index.js +123 -0
  370. package/dist/plugins/providers/deepseek/index.js.map +1 -0
  371. package/dist/plugins/providers/index.d.ts +2 -0
  372. package/dist/plugins/providers/index.d.ts.map +1 -0
  373. package/dist/plugins/providers/index.js +10 -0
  374. package/dist/plugins/providers/index.js.map +1 -0
  375. package/dist/providers/baseProvider.d.ts +140 -0
  376. package/dist/providers/baseProvider.d.ts.map +1 -0
  377. package/dist/providers/baseProvider.js +230 -0
  378. package/dist/providers/baseProvider.js.map +1 -0
  379. package/dist/providers/openaiChatCompletionsProvider.d.ts +70 -0
  380. package/dist/providers/openaiChatCompletionsProvider.d.ts.map +1 -0
  381. package/dist/providers/openaiChatCompletionsProvider.js +971 -0
  382. package/dist/providers/openaiChatCompletionsProvider.js.map +1 -0
  383. package/dist/providers/providerFactory.d.ts +22 -0
  384. package/dist/providers/providerFactory.d.ts.map +1 -0
  385. package/dist/providers/providerFactory.js +25 -0
  386. package/dist/providers/providerFactory.js.map +1 -0
  387. package/dist/providers/resilientProvider.d.ts +96 -0
  388. package/dist/providers/resilientProvider.d.ts.map +1 -0
  389. package/dist/providers/resilientProvider.js +251 -0
  390. package/dist/providers/resilientProvider.js.map +1 -0
  391. package/dist/runtime/agentController.d.ts +137 -0
  392. package/dist/runtime/agentController.d.ts.map +1 -0
  393. package/dist/runtime/agentController.js +784 -0
  394. package/dist/runtime/agentController.js.map +1 -0
  395. package/dist/runtime/agentHost.d.ts +61 -0
  396. package/dist/runtime/agentHost.d.ts.map +1 -0
  397. package/dist/runtime/agentHost.js +158 -0
  398. package/dist/runtime/agentHost.js.map +1 -0
  399. package/dist/runtime/agentSession.d.ts +49 -0
  400. package/dist/runtime/agentSession.d.ts.map +1 -0
  401. package/dist/runtime/agentSession.js +218 -0
  402. package/dist/runtime/agentSession.js.map +1 -0
  403. package/dist/runtime/agentSpawningWiring.d.ts +32 -0
  404. package/dist/runtime/agentSpawningWiring.d.ts.map +1 -0
  405. package/dist/runtime/agentSpawningWiring.js +114 -0
  406. package/dist/runtime/agentSpawningWiring.js.map +1 -0
  407. package/dist/runtime/node.d.ts +7 -0
  408. package/dist/runtime/node.d.ts.map +1 -0
  409. package/dist/runtime/node.js +50 -0
  410. package/dist/runtime/node.js.map +1 -0
  411. package/dist/runtime/universal.d.ts +18 -0
  412. package/dist/runtime/universal.d.ts.map +1 -0
  413. package/dist/runtime/universal.js +21 -0
  414. package/dist/runtime/universal.js.map +1 -0
  415. package/dist/shell/liveStatus.d.ts +27 -0
  416. package/dist/shell/liveStatus.d.ts.map +1 -0
  417. package/dist/shell/liveStatus.js +53 -0
  418. package/dist/shell/liveStatus.js.map +1 -0
  419. package/dist/shell/systemPrompt.d.ts +12 -0
  420. package/dist/shell/systemPrompt.d.ts.map +1 -0
  421. package/dist/shell/systemPrompt.js +16 -0
  422. package/dist/shell/systemPrompt.js.map +1 -0
  423. package/dist/shell/toolPresentation.d.ts +54 -0
  424. package/dist/shell/toolPresentation.d.ts.map +1 -0
  425. package/dist/shell/toolPresentation.js +334 -0
  426. package/dist/shell/toolPresentation.js.map +1 -0
  427. package/dist/tools/bashTools.d.ts +11 -0
  428. package/dist/tools/bashTools.d.ts.map +1 -0
  429. package/dist/tools/bashTools.js +785 -0
  430. package/dist/tools/bashTools.js.map +1 -0
  431. package/dist/tools/diffUtils.d.ts +43 -0
  432. package/dist/tools/diffUtils.d.ts.map +1 -0
  433. package/dist/tools/diffUtils.js +607 -0
  434. package/dist/tools/diffUtils.js.map +1 -0
  435. package/dist/tools/editTools.d.ts +29 -0
  436. package/dist/tools/editTools.d.ts.map +1 -0
  437. package/dist/tools/editTools.js +792 -0
  438. package/dist/tools/editTools.js.map +1 -0
  439. package/dist/tools/fileChangeTracker.d.ts +47 -0
  440. package/dist/tools/fileChangeTracker.d.ts.map +1 -0
  441. package/dist/tools/fileChangeTracker.js +154 -0
  442. package/dist/tools/fileChangeTracker.js.map +1 -0
  443. package/dist/tools/fileReadTracker.d.ts +69 -0
  444. package/dist/tools/fileReadTracker.d.ts.map +1 -0
  445. package/dist/tools/fileReadTracker.js +213 -0
  446. package/dist/tools/fileReadTracker.js.map +1 -0
  447. package/dist/tools/fileTools.d.ts +3 -0
  448. package/dist/tools/fileTools.d.ts.map +1 -0
  449. package/dist/tools/fileTools.js +389 -0
  450. package/dist/tools/fileTools.js.map +1 -0
  451. package/dist/tools/grepTools.d.ts +3 -0
  452. package/dist/tools/grepTools.d.ts.map +1 -0
  453. package/dist/tools/grepTools.js +137 -0
  454. package/dist/tools/grepTools.js.map +1 -0
  455. package/dist/tools/hitlTools.d.ts +7 -0
  456. package/dist/tools/hitlTools.d.ts.map +1 -0
  457. package/dist/tools/hitlTools.js +185 -0
  458. package/dist/tools/hitlTools.js.map +1 -0
  459. package/dist/tools/memoryTools.d.ts +27 -0
  460. package/dist/tools/memoryTools.d.ts.map +1 -0
  461. package/dist/tools/memoryTools.js +197 -0
  462. package/dist/tools/memoryTools.js.map +1 -0
  463. package/dist/tools/notebookTools.d.ts +20 -0
  464. package/dist/tools/notebookTools.d.ts.map +1 -0
  465. package/dist/tools/notebookTools.js +140 -0
  466. package/dist/tools/notebookTools.js.map +1 -0
  467. package/dist/tools/searchTools.d.ts +12 -0
  468. package/dist/tools/searchTools.d.ts.map +1 -0
  469. package/dist/tools/searchTools.js +414 -0
  470. package/dist/tools/searchTools.js.map +1 -0
  471. package/dist/tools/skillTools.d.ts +24 -0
  472. package/dist/tools/skillTools.d.ts.map +1 -0
  473. package/dist/tools/skillTools.js +140 -0
  474. package/dist/tools/skillTools.js.map +1 -0
  475. package/dist/tools/todoTools.d.ts +23 -0
  476. package/dist/tools/todoTools.d.ts.map +1 -0
  477. package/dist/tools/todoTools.js +120 -0
  478. package/dist/tools/todoTools.js.map +1 -0
  479. package/dist/tools/webTools.d.ts +26 -0
  480. package/dist/tools/webTools.d.ts.map +1 -0
  481. package/dist/tools/webTools.js +467 -0
  482. package/dist/tools/webTools.js.map +1 -0
  483. package/dist/ui/ink/App.d.ts +53 -0
  484. package/dist/ui/ink/App.d.ts.map +1 -0
  485. package/dist/ui/ink/App.js +13 -0
  486. package/dist/ui/ink/App.js.map +1 -0
  487. package/dist/ui/ink/ChatStatic.d.ts +30 -0
  488. package/dist/ui/ink/ChatStatic.d.ts.map +1 -0
  489. package/dist/ui/ink/ChatStatic.js +83 -0
  490. package/dist/ui/ink/ChatStatic.js.map +1 -0
  491. package/dist/ui/ink/InkPromptController.d.ts +321 -0
  492. package/dist/ui/ink/InkPromptController.d.ts.map +1 -0
  493. package/dist/ui/ink/InkPromptController.js +667 -0
  494. package/dist/ui/ink/InkPromptController.js.map +1 -0
  495. package/dist/ui/ink/Menu.d.ts +21 -0
  496. package/dist/ui/ink/Menu.d.ts.map +1 -0
  497. package/dist/ui/ink/Menu.js +61 -0
  498. package/dist/ui/ink/Menu.js.map +1 -0
  499. package/dist/ui/ink/Prompt.d.ts +47 -0
  500. package/dist/ui/ink/Prompt.d.ts.map +1 -0
  501. package/dist/ui/ink/Prompt.js +571 -0
  502. package/dist/ui/ink/Prompt.js.map +1 -0
  503. package/dist/ui/ink/StatusLine.d.ts +35 -0
  504. package/dist/ui/ink/StatusLine.d.ts.map +1 -0
  505. package/dist/ui/ink/StatusLine.js +66 -0
  506. package/dist/ui/ink/StatusLine.js.map +1 -0
  507. package/dist/ui/ink/pasteBuffer.d.ts +44 -0
  508. package/dist/ui/ink/pasteBuffer.d.ts.map +1 -0
  509. package/dist/ui/ink/pasteBuffer.js +73 -0
  510. package/dist/ui/ink/pasteBuffer.js.map +1 -0
  511. package/dist/ui/theme.d.ts +351 -0
  512. package/dist/ui/theme.d.ts.map +1 -0
  513. package/dist/ui/theme.js +435 -0
  514. package/dist/ui/theme.js.map +1 -0
  515. package/dist/utils/analytics.d.ts +2 -0
  516. package/dist/utils/analytics.d.ts.map +1 -0
  517. package/dist/utils/analytics.js +51 -0
  518. package/dist/utils/analytics.js.map +1 -0
  519. package/dist/utils/asyncUtils.d.ts +95 -0
  520. package/dist/utils/asyncUtils.d.ts.map +1 -0
  521. package/dist/utils/asyncUtils.js +286 -0
  522. package/dist/utils/asyncUtils.js.map +1 -0
  523. package/dist/utils/debugLogger.d.ts +6 -0
  524. package/dist/utils/debugLogger.d.ts.map +1 -0
  525. package/dist/utils/debugLogger.js +39 -0
  526. package/dist/utils/debugLogger.js.map +1 -0
  527. package/dist/utils/errorUtils.d.ts +12 -0
  528. package/dist/utils/errorUtils.d.ts.map +1 -0
  529. package/dist/utils/errorUtils.js +83 -0
  530. package/dist/utils/errorUtils.js.map +1 -0
  531. package/dist/utils/frontmatter.d.ts +10 -0
  532. package/dist/utils/frontmatter.d.ts.map +1 -0
  533. package/dist/utils/frontmatter.js +78 -0
  534. package/dist/utils/frontmatter.js.map +1 -0
  535. package/dist/utils/packageInfo.d.ts +14 -0
  536. package/dist/utils/packageInfo.d.ts.map +1 -0
  537. package/dist/utils/packageInfo.js +45 -0
  538. package/dist/utils/packageInfo.js.map +1 -0
  539. package/dist/utils/planFormatter.d.ts +34 -0
  540. package/dist/utils/planFormatter.d.ts.map +1 -0
  541. package/dist/utils/planFormatter.js +141 -0
  542. package/dist/utils/planFormatter.js.map +1 -0
  543. package/dist/utils/securityUtils.d.ts +132 -0
  544. package/dist/utils/securityUtils.d.ts.map +1 -0
  545. package/dist/utils/securityUtils.js +324 -0
  546. package/dist/utils/securityUtils.js.map +1 -0
  547. package/dist/utils/statusReporter.d.ts +6 -0
  548. package/dist/utils/statusReporter.d.ts.map +1 -0
  549. package/dist/utils/statusReporter.js +26 -0
  550. package/dist/utils/statusReporter.js.map +1 -0
  551. package/dist/workspace.d.ts +8 -0
  552. package/dist/workspace.d.ts.map +1 -0
  553. package/dist/workspace.js +135 -0
  554. package/dist/workspace.js.map +1 -0
  555. package/dist/workspace.validator.d.ts +49 -0
  556. package/dist/workspace.validator.d.ts.map +1 -0
  557. package/dist/workspace.validator.js +215 -0
  558. package/dist/workspace.validator.js.map +1 -0
  559. package/package.json +116 -0
  560. package/scripts/postinstall.cjs +56 -0
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Hooks — Claude-Code-style shell-command hooks that fire around
3
+ * tool execution. Lets users customize agent behavior without
4
+ * editing source: run a linter after every Edit, log Bash commands,
5
+ * block dangerous tools, etc.
6
+ *
7
+ * Settings file (per Claude Code convention):
8
+ * {
9
+ * "hooks": {
10
+ * "PreToolUse": [
11
+ * { "matcher": "Bash", "hooks": [{ "type": "command", "command": "/path/to/script.sh" }] }
12
+ * ],
13
+ * "PostToolUse": [ ... ]
14
+ * }
15
+ * }
16
+ *
17
+ * Loaded from (in priority order):
18
+ * 1. <workingDir>/.trenchwork/settings.json (project-local)
19
+ * 2. ~/.trenchwork/settings.json (user-global)
20
+ *
21
+ * Both load — project-local extends user-global; matchers from both
22
+ * files fire if applicable.
23
+ *
24
+ * Hook contract: the command receives a JSON envelope on stdin,
25
+ * shape:
26
+ * { event: 'PreToolUse'|'PostToolUse', toolName, toolArgs, toolResult? }
27
+ * The command exits 0 + writes a JSON response on stdout to either
28
+ * pass through or shape the result:
29
+ * {} — pass through
30
+ * { "decision": "block",
31
+ * "reason": "string" } — PreToolUse: block the tool call
32
+ * { "appendToResult": "..." } — PostToolUse: append text to the
33
+ * model-visible tool result
34
+ *
35
+ * Hooks are best-effort: a hook that times out, errors, or returns
36
+ * malformed JSON is logged and skipped — never crashes the agent.
37
+ */
38
+ import { existsSync, readFileSync } from 'node:fs';
39
+ import { homedir } from 'node:os';
40
+ import { join } from 'node:path';
41
+ import { exec, execFile } from 'node:child_process';
42
+ /**
43
+ * Read + merge settings from project-local + user-global locations.
44
+ * Returns an empty config if neither file exists. Malformed JSON is
45
+ * silently skipped (with a console.warn).
46
+ */
47
+ export function loadHooksConfig(workingDir) {
48
+ const candidates = [
49
+ join(workingDir, '.trenchwork', 'settings.json'),
50
+ join(homedir(), '.trenchwork', 'settings.json'),
51
+ ];
52
+ const merged = { hooks: {} };
53
+ for (const path of candidates) {
54
+ if (!existsSync(path))
55
+ continue;
56
+ let parsed = null;
57
+ try {
58
+ const raw = readFileSync(path, 'utf-8');
59
+ parsed = JSON.parse(raw);
60
+ }
61
+ catch (err) {
62
+ console.warn(`[hooks] Skipping malformed settings: ${path}: ${err.message}`);
63
+ continue;
64
+ }
65
+ if (!parsed?.hooks)
66
+ continue;
67
+ for (const ev of Object.keys(parsed.hooks)) {
68
+ const list = parsed.hooks[ev];
69
+ if (!Array.isArray(list))
70
+ continue;
71
+ const existing = merged.hooks[ev] ?? [];
72
+ // Shallow-validate each entry before merging so the executor
73
+ // never has to re-check shape.
74
+ const safe = list.filter((m) => m && typeof m === 'object' && Array.isArray(m.hooks));
75
+ merged.hooks[ev] = [...existing, ...safe];
76
+ }
77
+ }
78
+ return merged;
79
+ }
80
+ function matchesMatcher(matcher, toolName) {
81
+ if (!matcher || matcher === '*' || matcher === '.*')
82
+ return true;
83
+ try {
84
+ return new RegExp(`^${matcher}$`).test(toolName);
85
+ }
86
+ catch {
87
+ return matcher === toolName;
88
+ }
89
+ }
90
+ /**
91
+ * Run a single hook command with structured input. Returns the
92
+ * parsed JSON response, or null if the hook errored / timed out /
93
+ * returned malformed output. Never throws — non-fatal on purpose.
94
+ */
95
+ async function runHookCommand(cmd, input) {
96
+ const timeoutMs = Math.min(30_000, Math.max(500, cmd.timeoutMs ?? 5000));
97
+ return new Promise((resolve) => {
98
+ let settled = false;
99
+ const finish = (val) => {
100
+ if (settled)
101
+ return;
102
+ settled = true;
103
+ resolve(val);
104
+ };
105
+ // Use exec (not spawn) so the command string is interpreted by
106
+ // the platform's default shell with its native quoting rules.
107
+ // spawn('cmd.exe', ['/c', '<cmd with quotes>']) on Windows
108
+ // mishandles inner double-quotes; exec handles that internally.
109
+ // We do NOT pass exec's `timeout` option — on Windows it sends
110
+ // SIGTERM which doesn't always reliably kill child processes
111
+ // that aren't blocked on I/O (e.g. a node child sitting on a
112
+ // setTimeout). Instead we own the timeout: fire our own timer,
113
+ // resolve the promise immediately, and force-kill the process
114
+ // tree. The exec callback may still fire later but `settled`
115
+ // makes it a no-op.
116
+ const child = exec(cmd.command, { maxBuffer: 1024 * 1024, encoding: 'utf-8' }, (err, stdout, stderr) => {
117
+ if (settled)
118
+ return;
119
+ if (err && err.code) {
120
+ if (typeof stderr === 'string' && stderr.trim()) {
121
+ console.warn(`[hooks] ${cmd.command} exit ${err.code}: ${stderr.slice(0, 400)}`);
122
+ }
123
+ return finish(null);
124
+ }
125
+ const out = (typeof stdout === 'string' ? stdout : '').trim();
126
+ if (!out)
127
+ return finish({});
128
+ try {
129
+ const parsed = JSON.parse(out);
130
+ if (parsed && typeof parsed === 'object')
131
+ return finish(parsed);
132
+ return finish({});
133
+ }
134
+ catch {
135
+ // A hook that prints non-JSON is treated as pass-through.
136
+ return finish({});
137
+ }
138
+ });
139
+ // Owned timeout — kill the process tree on expiry. On Windows
140
+ // we use taskkill /T /F to clean up children of the shell wrapper;
141
+ // on POSIX, killing the negative pid of the process group does it.
142
+ const timeout = setTimeout(() => {
143
+ if (settled)
144
+ return;
145
+ console.warn(`[hooks] ${cmd.command}: timed out after ${timeoutMs}ms`);
146
+ try {
147
+ if (process.platform === 'win32' && child.pid) {
148
+ // /T = terminate child tree, /F = force. Use execFile with an
149
+ // arg array so the PID can never be interpreted as taskkill
150
+ // flags (defense-in-depth — child.pid is a number from Node so
151
+ // injection isn't reachable today, but the safer pattern is
152
+ // free here).
153
+ execFile('taskkill', ['/pid', String(child.pid), '/T', '/F'], () => { });
154
+ }
155
+ else {
156
+ child.kill('SIGKILL');
157
+ }
158
+ }
159
+ catch (_) { /* best effort */ }
160
+ finish(null);
161
+ }, timeoutMs);
162
+ timeout.unref?.();
163
+ child.on('exit', () => clearTimeout(timeout));
164
+ // A hook that errors/exits fast closes its stdin before we finish
165
+ // writing, which surfaces as an ASYNC 'error' (EPIPE) on the stream —
166
+ // not catchable by the try/catch below. Swallow it so a dead hook is
167
+ // silently skipped instead of crashing the runner with an unhandled
168
+ // stream error.
169
+ child.stdin?.on('error', () => { });
170
+ try {
171
+ child.stdin?.write(JSON.stringify(input));
172
+ child.stdin?.end();
173
+ }
174
+ catch (err) {
175
+ console.warn(`[hooks] stdin write failed: ${err.message}`);
176
+ }
177
+ });
178
+ }
179
+ /**
180
+ * Run all PreToolUse hooks matching `toolName`. Returns the FIRST
181
+ * blocking decision encountered, or null if no hook blocks.
182
+ */
183
+ export async function runPreToolUseHooks(config, toolName, toolArgs) {
184
+ const matchers = config.hooks?.PreToolUse ?? [];
185
+ for (const m of matchers) {
186
+ if (!matchesMatcher(m.matcher, toolName))
187
+ continue;
188
+ for (const cmd of m.hooks) {
189
+ const result = await runHookCommand(cmd, {
190
+ event: 'PreToolUse',
191
+ toolName,
192
+ toolArgs,
193
+ });
194
+ if (!result)
195
+ continue;
196
+ if (result['decision'] === 'block') {
197
+ return {
198
+ decision: 'block',
199
+ reason: typeof result['reason'] === 'string' ? result['reason'] : 'Blocked by hook',
200
+ };
201
+ }
202
+ }
203
+ }
204
+ return null;
205
+ }
206
+ /**
207
+ * Run all PostToolUse hooks matching `toolName`. Concatenates any
208
+ * appendToResult strings (in matcher order) so multiple hooks can
209
+ * each contribute a note.
210
+ */
211
+ export async function runPostToolUseHooks(config, toolName, toolArgs, toolResult) {
212
+ const matchers = config.hooks?.PostToolUse ?? [];
213
+ const appended = [];
214
+ for (const m of matchers) {
215
+ if (!matchesMatcher(m.matcher, toolName))
216
+ continue;
217
+ for (const cmd of m.hooks) {
218
+ const result = await runHookCommand(cmd, {
219
+ event: 'PostToolUse',
220
+ toolName,
221
+ toolArgs,
222
+ toolResult,
223
+ });
224
+ if (!result)
225
+ continue;
226
+ const append = result['appendToResult'];
227
+ if (typeof append === 'string' && append.trim()) {
228
+ appended.push(append.trim());
229
+ }
230
+ }
231
+ }
232
+ if (appended.length === 0)
233
+ return null;
234
+ return { appendToResult: appended.join('\n\n') };
235
+ }
236
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/core/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Hosted-key access — the CLIENT side of "optional sign-in unlocks hosted keys,
3
+ * or bring your own." Keys NEVER ship in this client (Project Glasswing); they
4
+ * live only in the ero.solar AWS backend, exactly like the Tavily search proxy
5
+ * already does (see src/tools/webTools.ts). Sign-in mints a short-lived token;
6
+ * the proxies validate it and use the operator keys.
7
+ *
8
+ * ── CONTRACT (the ero.solar backend implements this; this file codes against it) ──
9
+ * Sign-in (loopback OAuth, increment 2):
10
+ * open https://ero.solar/cli/login?port=<loopbackPort>&state=<csrf>
11
+ * → Google SSO → 302 http://127.0.0.1:<port>/cb?token=<jwt>&email=<e>&state=<csrf>
12
+ * DeepSeek (hosted): POST {HOSTED_DEEPSEEK_PROXY} header `Authorization: Bearer <token>`
13
+ * Tavily (hosted): the existing tavilySearch proxy, same Bearer token
14
+ * The token is short-lived and server-validated; if it 401s the CLI drops to
15
+ * "signed out" and asks the user to /login again or use their own key.
16
+ *
17
+ * THIS MODULE is state + resolution only (increment 1, fully testable). The live
18
+ * sign-in flow and the provider→proxy wiring are increment 2 (backend-gated).
19
+ */
20
+ export declare const HOSTED_LOGIN_URL = "https://ero.solar/cli/login";
21
+ export declare const HOSTED_DEEPSEEK_PROXY = "https://ero.solar/api/deepseek";
22
+ export interface HostedSession {
23
+ token: string;
24
+ email: string;
25
+ }
26
+ export type KeyMode = 'hosted' | 'own' | 'none';
27
+ export interface KeyModeStatus {
28
+ mode: KeyMode;
29
+ email: string | null;
30
+ signedIn: boolean;
31
+ ownDeepSeek: boolean;
32
+ ownTavily: boolean;
33
+ preferOwnKeys: boolean;
34
+ }
35
+ /** The active hosted session (token + email), or null when signed out. */
36
+ export declare function getHostedSession(): HostedSession | null;
37
+ /** Persist a hosted session (called by /login once the backend returns a token). */
38
+ export declare function setHostedSession(session: HostedSession): void;
39
+ /** Sign out: drop the token but keep the own/hosted preference. */
40
+ export declare function clearHostedSession(): void;
41
+ export declare function prefersOwnKeys(): boolean;
42
+ export declare function setPreferOwnKeys(value: boolean): void;
43
+ /**
44
+ * Resolve which keys are in effect. Preference order: an explicit "use my own
45
+ * keys" wins when the user actually has a DeepSeek key; otherwise a hosted
46
+ * session is used; otherwise the user's own key; otherwise nothing is set up.
47
+ */
48
+ export declare function resolveKeyMode(): KeyModeStatus;
49
+ /**
50
+ * The dim welcome/banner line that makes the active key source unmistakable —
51
+ * the user must be able to see at a glance whether they're on hosted keys or
52
+ * their own. Returns null in 'none' mode (the welcome already shows key setup).
53
+ */
54
+ export declare function keyModeLine(status?: KeyModeStatus): string | null;
55
+ /**
56
+ * Resolve the DeepSeek endpoint the provider should use. Hosted mode routes
57
+ * through the ero.solar proxy authenticated by the short-lived sign-in token
58
+ * (the real key lives only server-side, Glasswing); otherwise the user's own
59
+ * key hits the API directly. `apiKey` is '' in 'none' mode (caller errors).
60
+ */
61
+ export declare function resolveDeepSeekEndpoint(): {
62
+ apiKey: string;
63
+ baseURL: string;
64
+ mode: KeyMode;
65
+ };
66
+ export interface LoginResult {
67
+ ok: boolean;
68
+ session?: HostedSession;
69
+ error?: string;
70
+ }
71
+ /**
72
+ * Loopback-OAuth sign-in (the contract's increment 2). Starts a one-shot
73
+ * 127.0.0.1 server on an ephemeral port, opens the browser to the ero.solar
74
+ * Google-SSO login URL with that port + a CSRF state, and waits for the
75
+ * redirect back to /cb?token=&email=&state=. On match it persists the hosted
76
+ * session. The browser launch is injected (`open`) so the flow is testable
77
+ * against the REAL loopback server without a real browser.
78
+ *
79
+ * Requires the ero.solar backend (SSO + token mint + redirect) to be live; with
80
+ * no backend the browser opens to a not-yet-served endpoint and the wait times
81
+ * out — the caller surfaces that honestly.
82
+ */
83
+ export declare function loginViaLoopback(opts: {
84
+ open: (url: string) => void | Promise<void>;
85
+ timeoutMs?: number;
86
+ loginUrl?: string;
87
+ }): Promise<LoginResult>;
88
+ //# sourceMappingURL=hostedAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostedAuth.d.ts","sourceRoot":"","sources":["../../src/core/hostedAuth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAUH,eAAO,MAAM,gBAAgB,gCAAgC,CAAC;AAC9D,eAAO,MAAM,qBAAqB,mCAAmC,CAAC;AAWtE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AASD,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;CACxB;AA+BD,0EAA0E;AAC1E,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,IAAI,CAGvD;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAG7D;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAErD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,aAAa,CAa9C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,GAAE,aAAgC,GAAG,MAAM,GAAG,IAAI,CAanF;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAW5F;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,WAAW,CAAC,CAuCvB"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Hosted-key access — the CLIENT side of "optional sign-in unlocks hosted keys,
3
+ * or bring your own." Keys NEVER ship in this client (Project Glasswing); they
4
+ * live only in the ero.solar AWS backend, exactly like the Tavily search proxy
5
+ * already does (see src/tools/webTools.ts). Sign-in mints a short-lived token;
6
+ * the proxies validate it and use the operator keys.
7
+ *
8
+ * ── CONTRACT (the ero.solar backend implements this; this file codes against it) ──
9
+ * Sign-in (loopback OAuth, increment 2):
10
+ * open https://ero.solar/cli/login?port=<loopbackPort>&state=<csrf>
11
+ * → Google SSO → 302 http://127.0.0.1:<port>/cb?token=<jwt>&email=<e>&state=<csrf>
12
+ * DeepSeek (hosted): POST {HOSTED_DEEPSEEK_PROXY} header `Authorization: Bearer <token>`
13
+ * Tavily (hosted): the existing tavilySearch proxy, same Bearer token
14
+ * The token is short-lived and server-validated; if it 401s the CLI drops to
15
+ * "signed out" and asks the user to /login again or use their own key.
16
+ *
17
+ * THIS MODULE is state + resolution only (increment 1, fully testable). The live
18
+ * sign-in flow and the provider→proxy wiring are increment 2 (backend-gated).
19
+ */
20
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, rmSync } from 'node:fs';
21
+ import { createServer } from 'node:http';
22
+ import { randomBytes } from 'node:crypto';
23
+ import { homedir } from 'node:os';
24
+ import { join, resolve } from 'node:path';
25
+ import { getSecretValue } from './secretStore.js';
26
+ // Contract endpoints (the backend the user is building must match these).
27
+ export const HOSTED_LOGIN_URL = 'https://ero.solar/cli/login';
28
+ export const HOSTED_DEEPSEEK_PROXY = 'https://ero.solar/api/deepseek';
29
+ // Resolved per call (not captured at module load) so TRENCHWORK_HOME changes —
30
+ // and tests pointing at a temp dir — take effect.
31
+ function homeDir() {
32
+ return process.env['TRENCHWORK_HOME'] ? resolve(process.env['TRENCHWORK_HOME']) : join(homedir(), '.trenchwork');
33
+ }
34
+ function sessionFile() {
35
+ return join(homeDir(), 'session.json');
36
+ }
37
+ function readFile() {
38
+ // Read the on-disk session first (the future /login writes it; it also holds
39
+ // the own/hosted preference), then let env override the token+email — env
40
+ // lets tests/CI inject a session without touching disk, while still honouring
41
+ // a stored preference.
42
+ let data = {};
43
+ const file = sessionFile();
44
+ if (existsSync(file)) {
45
+ try {
46
+ const parsed = JSON.parse(readFileSync(file, 'utf8'));
47
+ if (parsed && typeof parsed === 'object')
48
+ data = parsed;
49
+ }
50
+ catch { /* corrupt → treat as empty */ }
51
+ }
52
+ const envToken = process.env['TRENCHWORK_HOSTED_TOKEN']?.trim();
53
+ if (envToken) {
54
+ data.token = envToken;
55
+ data.email = process.env['TRENCHWORK_HOSTED_EMAIL']?.trim() || 'you@hosted';
56
+ }
57
+ return data;
58
+ }
59
+ function writeFile(data) {
60
+ const file = sessionFile();
61
+ mkdirSync(homeDir(), { recursive: true, mode: 0o700 });
62
+ const tmp = `${file}.${process.pid}.tmp`;
63
+ writeFileSync(tmp, JSON.stringify(data, null, 2) + '\n', { mode: 0o600 });
64
+ renameSync(tmp, file);
65
+ }
66
+ /** The active hosted session (token + email), or null when signed out. */
67
+ export function getHostedSession() {
68
+ const f = readFile();
69
+ return f.token ? { token: f.token, email: f.email || 'you@hosted' } : null;
70
+ }
71
+ /** Persist a hosted session (called by /login once the backend returns a token). */
72
+ export function setHostedSession(session) {
73
+ const f = readFile();
74
+ writeFile({ ...f, token: session.token, email: session.email });
75
+ }
76
+ /** Sign out: drop the token but keep the own/hosted preference. */
77
+ export function clearHostedSession() {
78
+ const f = readFile();
79
+ delete f.token;
80
+ delete f.email;
81
+ if (Object.keys(f).length === 0) {
82
+ try {
83
+ rmSync(sessionFile(), { force: true });
84
+ }
85
+ catch { /* ignore */ }
86
+ return;
87
+ }
88
+ writeFile(f);
89
+ }
90
+ export function prefersOwnKeys() {
91
+ return readFile().preferOwnKeys === true;
92
+ }
93
+ export function setPreferOwnKeys(value) {
94
+ writeFile({ ...readFile(), preferOwnKeys: value });
95
+ }
96
+ /**
97
+ * Resolve which keys are in effect. Preference order: an explicit "use my own
98
+ * keys" wins when the user actually has a DeepSeek key; otherwise a hosted
99
+ * session is used; otherwise the user's own key; otherwise nothing is set up.
100
+ */
101
+ export function resolveKeyMode() {
102
+ const session = getHostedSession();
103
+ const ownDeepSeek = Boolean(getSecretValue('DEEPSEEK_API_KEY'));
104
+ const ownTavily = Boolean(getSecretValue('TAVILY_API_KEY'));
105
+ const preferOwnKeys = prefersOwnKeys();
106
+ let mode;
107
+ if (preferOwnKeys && ownDeepSeek)
108
+ mode = 'own';
109
+ else if (session)
110
+ mode = 'hosted';
111
+ else if (ownDeepSeek)
112
+ mode = 'own';
113
+ else
114
+ mode = 'none';
115
+ return { mode, email: session?.email ?? null, signedIn: Boolean(session), ownDeepSeek, ownTavily, preferOwnKeys };
116
+ }
117
+ /**
118
+ * The dim welcome/banner line that makes the active key source unmistakable —
119
+ * the user must be able to see at a glance whether they're on hosted keys or
120
+ * their own. Returns null in 'none' mode (the welcome already shows key setup).
121
+ */
122
+ export function keyModeLine(status = resolveKeyMode()) {
123
+ switch (status.mode) {
124
+ case 'hosted':
125
+ return `Signed in as ${status.email} · using hosted keys` +
126
+ (status.ownDeepSeek ? ' · /account to use your own' : '');
127
+ case 'own': {
128
+ const tav = status.ownTavily ? 'Tavily ✓' : 'Tavily (shared proxy)';
129
+ const base = `Using your own keys · DeepSeek ✓ · ${tav}`;
130
+ return status.signedIn ? `${base} · /account to use hosted` : base;
131
+ }
132
+ default:
133
+ return null;
134
+ }
135
+ }
136
+ /**
137
+ * Resolve the DeepSeek endpoint the provider should use. Hosted mode routes
138
+ * through the ero.solar proxy authenticated by the short-lived sign-in token
139
+ * (the real key lives only server-side, Glasswing); otherwise the user's own
140
+ * key hits the API directly. `apiKey` is '' in 'none' mode (caller errors).
141
+ */
142
+ export function resolveDeepSeekEndpoint() {
143
+ const status = resolveKeyMode();
144
+ if (status.mode === 'hosted') {
145
+ const session = getHostedSession();
146
+ if (session)
147
+ return { apiKey: session.token, baseURL: HOSTED_DEEPSEEK_PROXY, mode: 'hosted' };
148
+ }
149
+ const userKey = (process.env['DEEPSEEK_API_KEY'] || '').trim();
150
+ if (userKey) {
151
+ return { apiKey: userKey, baseURL: process.env['DEEPSEEK_BASE_URL'] || 'https://api.deepseek.com', mode: 'own' };
152
+ }
153
+ return { apiKey: '', baseURL: '', mode: 'none' };
154
+ }
155
+ /**
156
+ * Loopback-OAuth sign-in (the contract's increment 2). Starts a one-shot
157
+ * 127.0.0.1 server on an ephemeral port, opens the browser to the ero.solar
158
+ * Google-SSO login URL with that port + a CSRF state, and waits for the
159
+ * redirect back to /cb?token=&email=&state=. On match it persists the hosted
160
+ * session. The browser launch is injected (`open`) so the flow is testable
161
+ * against the REAL loopback server without a real browser.
162
+ *
163
+ * Requires the ero.solar backend (SSO + token mint + redirect) to be live; with
164
+ * no backend the browser opens to a not-yet-served endpoint and the wait times
165
+ * out — the caller surfaces that honestly.
166
+ */
167
+ export function loginViaLoopback(opts) {
168
+ const state = randomBytes(16).toString('hex');
169
+ const loginUrl = opts.loginUrl ?? HOSTED_LOGIN_URL;
170
+ return new Promise((resolveP) => {
171
+ let settled = false;
172
+ const finish = (result) => {
173
+ if (settled)
174
+ return;
175
+ settled = true;
176
+ clearTimeout(timer);
177
+ try {
178
+ server.close();
179
+ }
180
+ catch { /* ignore */ }
181
+ resolveP(result);
182
+ };
183
+ const server = createServer((req, res) => {
184
+ const url = new URL(req.url ?? '/', 'http://127.0.0.1');
185
+ if (url.pathname !== '/cb') {
186
+ res.writeHead(404);
187
+ res.end('not found');
188
+ return;
189
+ }
190
+ const token = url.searchParams.get('token') ?? '';
191
+ const email = url.searchParams.get('email') ?? '';
192
+ const gotState = url.searchParams.get('state') ?? '';
193
+ const okPage = '<!doctype html><meta charset="utf-8"><body style="font:16px system-ui;padding:3rem">'
194
+ + 'Signed in to Trenchwork Coder. You can close this tab and return to the terminal.</body>';
195
+ res.writeHead(200, { 'content-type': 'text/html' });
196
+ res.end(okPage);
197
+ if (gotState !== state) {
198
+ finish({ ok: false, error: 'state mismatch — sign-in rejected (possible CSRF)' });
199
+ return;
200
+ }
201
+ if (!token) {
202
+ finish({ ok: false, error: 'sign-in returned no token' });
203
+ return;
204
+ }
205
+ const session = { token, email: email || 'you@hosted' };
206
+ setHostedSession(session);
207
+ finish({ ok: true, session });
208
+ });
209
+ const timer = setTimeout(() => finish({ ok: false, error: 'timed out waiting for sign-in' }), opts.timeoutMs ?? 120_000);
210
+ server.on('error', (e) => finish({ ok: false, error: `loopback server failed: ${e.message}` }));
211
+ server.listen(0, '127.0.0.1', () => {
212
+ const addr = server.address();
213
+ const port = addr && typeof addr === 'object' ? addr.port : 0;
214
+ const url = `${loginUrl}?port=${port}&state=${state}`;
215
+ Promise.resolve(opts.open(url)).catch(() => { });
216
+ });
217
+ });
218
+ }
219
+ //# sourceMappingURL=hostedAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostedAuth.js","sourceRoot":"","sources":["../../src/core/hostedAuth.ts"],"names":[],"mappings":"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"}