steroids-api 0.2.7

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 (328) hide show
  1. package/dist/API/src/index.d.ts +10 -0
  2. package/dist/API/src/index.d.ts.map +1 -0
  3. package/dist/API/src/index.js +130 -0
  4. package/dist/API/src/index.js.map +1 -0
  5. package/dist/API/src/routes/activity.d.ts +7 -0
  6. package/dist/API/src/routes/activity.d.ts.map +1 -0
  7. package/dist/API/src/routes/activity.js +252 -0
  8. package/dist/API/src/routes/activity.js.map +1 -0
  9. package/dist/API/src/routes/config.d.ts +7 -0
  10. package/dist/API/src/routes/config.d.ts.map +1 -0
  11. package/dist/API/src/routes/config.js +521 -0
  12. package/dist/API/src/routes/config.js.map +1 -0
  13. package/dist/API/src/routes/health.d.ts +7 -0
  14. package/dist/API/src/routes/health.d.ts.map +1 -0
  15. package/dist/API/src/routes/health.js +172 -0
  16. package/dist/API/src/routes/health.js.map +1 -0
  17. package/dist/API/src/routes/incidents.d.ts +7 -0
  18. package/dist/API/src/routes/incidents.d.ts.map +1 -0
  19. package/dist/API/src/routes/incidents.js +117 -0
  20. package/dist/API/src/routes/incidents.js.map +1 -0
  21. package/dist/API/src/routes/projects.d.ts +7 -0
  22. package/dist/API/src/routes/projects.d.ts.map +1 -0
  23. package/dist/API/src/routes/projects.js +398 -0
  24. package/dist/API/src/routes/projects.js.map +1 -0
  25. package/dist/API/src/routes/runners.d.ts +7 -0
  26. package/dist/API/src/routes/runners.d.ts.map +1 -0
  27. package/dist/API/src/routes/runners.js +242 -0
  28. package/dist/API/src/routes/runners.js.map +1 -0
  29. package/dist/API/src/routes/tasks.d.ts +7 -0
  30. package/dist/API/src/routes/tasks.d.ts.map +1 -0
  31. package/dist/API/src/routes/tasks.js +1007 -0
  32. package/dist/API/src/routes/tasks.js.map +1 -0
  33. package/dist/API/src/utils/validation.d.ts +22 -0
  34. package/dist/API/src/utils/validation.d.ts.map +1 -0
  35. package/dist/API/src/utils/validation.js +50 -0
  36. package/dist/API/src/utils/validation.js.map +1 -0
  37. package/dist/index.d.ts +10 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +184 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/routes/activity.d.ts +7 -0
  42. package/dist/routes/activity.d.ts.map +1 -0
  43. package/dist/routes/activity.js +252 -0
  44. package/dist/routes/activity.js.map +1 -0
  45. package/dist/routes/config.d.ts +7 -0
  46. package/dist/routes/config.d.ts.map +1 -0
  47. package/dist/routes/config.js +647 -0
  48. package/dist/routes/config.js.map +1 -0
  49. package/dist/routes/credit-alerts.d.ts +2 -0
  50. package/dist/routes/credit-alerts.d.ts.map +1 -0
  51. package/dist/routes/credit-alerts.js +97 -0
  52. package/dist/routes/credit-alerts.js.map +1 -0
  53. package/dist/routes/health.d.ts +7 -0
  54. package/dist/routes/health.d.ts.map +1 -0
  55. package/dist/routes/health.js +200 -0
  56. package/dist/routes/health.js.map +1 -0
  57. package/dist/routes/incidents.d.ts +7 -0
  58. package/dist/routes/incidents.d.ts.map +1 -0
  59. package/dist/routes/incidents.js +117 -0
  60. package/dist/routes/incidents.js.map +1 -0
  61. package/dist/routes/projects.d.ts +7 -0
  62. package/dist/routes/projects.d.ts.map +1 -0
  63. package/dist/routes/projects.js +643 -0
  64. package/dist/routes/projects.js.map +1 -0
  65. package/dist/routes/runners.d.ts +7 -0
  66. package/dist/routes/runners.d.ts.map +1 -0
  67. package/dist/routes/runners.js +299 -0
  68. package/dist/routes/runners.js.map +1 -0
  69. package/dist/routes/skills.d.ts +3 -0
  70. package/dist/routes/skills.d.ts.map +1 -0
  71. package/dist/routes/skills.js +109 -0
  72. package/dist/routes/skills.js.map +1 -0
  73. package/dist/routes/storage.d.ts +7 -0
  74. package/dist/routes/storage.d.ts.map +1 -0
  75. package/dist/routes/storage.js +93 -0
  76. package/dist/routes/storage.js.map +1 -0
  77. package/dist/routes/tasks.d.ts +7 -0
  78. package/dist/routes/tasks.d.ts.map +1 -0
  79. package/dist/routes/tasks.js +1145 -0
  80. package/dist/routes/tasks.js.map +1 -0
  81. package/dist/src/cleanup/invocation-logs.d.ts +30 -0
  82. package/dist/src/cleanup/invocation-logs.d.ts.map +1 -0
  83. package/dist/src/cleanup/invocation-logs.js +66 -0
  84. package/dist/src/cleanup/invocation-logs.js.map +1 -0
  85. package/dist/src/commands/loop-phases.d.ts +11 -0
  86. package/dist/src/commands/loop-phases.d.ts.map +1 -0
  87. package/dist/src/commands/loop-phases.js +304 -0
  88. package/dist/src/commands/loop-phases.js.map +1 -0
  89. package/dist/src/config/loader.d.ts +160 -0
  90. package/dist/src/config/loader.d.ts.map +1 -0
  91. package/dist/src/config/loader.js +276 -0
  92. package/dist/src/config/loader.js.map +1 -0
  93. package/dist/src/database/connection.d.ts +35 -0
  94. package/dist/src/database/connection.d.ts.map +1 -0
  95. package/dist/src/database/connection.js +197 -0
  96. package/dist/src/database/connection.js.map +1 -0
  97. package/dist/src/database/queries.d.ts +220 -0
  98. package/dist/src/database/queries.d.ts.map +1 -0
  99. package/dist/src/database/queries.js +589 -0
  100. package/dist/src/database/queries.js.map +1 -0
  101. package/dist/src/database/schema.d.ts +8 -0
  102. package/dist/src/database/schema.d.ts.map +1 -0
  103. package/dist/src/database/schema.js +184 -0
  104. package/dist/src/database/schema.js.map +1 -0
  105. package/dist/src/git/push.d.ts +26 -0
  106. package/dist/src/git/push.d.ts.map +1 -0
  107. package/dist/src/git/push.js +91 -0
  108. package/dist/src/git/push.js.map +1 -0
  109. package/dist/src/git/status.d.ts +83 -0
  110. package/dist/src/git/status.d.ts.map +1 -0
  111. package/dist/src/git/status.js +315 -0
  112. package/dist/src/git/status.js.map +1 -0
  113. package/dist/src/health/stuck-task-detector.d.ts +131 -0
  114. package/dist/src/health/stuck-task-detector.d.ts.map +1 -0
  115. package/dist/src/health/stuck-task-detector.js +233 -0
  116. package/dist/src/health/stuck-task-detector.js.map +1 -0
  117. package/dist/src/health/stuck-task-recovery.d.ts +45 -0
  118. package/dist/src/health/stuck-task-recovery.d.ts.map +1 -0
  119. package/dist/src/health/stuck-task-recovery.js +309 -0
  120. package/dist/src/health/stuck-task-recovery.js.map +1 -0
  121. package/dist/src/index.d.ts +10 -0
  122. package/dist/src/index.d.ts.map +1 -0
  123. package/dist/src/index.js +130 -0
  124. package/dist/src/index.js.map +1 -0
  125. package/dist/src/locking/queries.d.ts +116 -0
  126. package/dist/src/locking/queries.d.ts.map +1 -0
  127. package/dist/src/locking/queries.js +232 -0
  128. package/dist/src/locking/queries.js.map +1 -0
  129. package/dist/src/locking/section-lock.d.ts +74 -0
  130. package/dist/src/locking/section-lock.d.ts.map +1 -0
  131. package/dist/src/locking/section-lock.js +196 -0
  132. package/dist/src/locking/section-lock.js.map +1 -0
  133. package/dist/src/locking/task-lock.d.ts +92 -0
  134. package/dist/src/locking/task-lock.d.ts.map +1 -0
  135. package/dist/src/locking/task-lock.js +233 -0
  136. package/dist/src/locking/task-lock.js.map +1 -0
  137. package/dist/src/migrations/index.d.ts +7 -0
  138. package/dist/src/migrations/index.d.ts.map +1 -0
  139. package/dist/src/migrations/index.js +9 -0
  140. package/dist/src/migrations/index.js.map +1 -0
  141. package/dist/src/migrations/manifest.d.ts +92 -0
  142. package/dist/src/migrations/manifest.d.ts.map +1 -0
  143. package/dist/src/migrations/manifest.js +255 -0
  144. package/dist/src/migrations/manifest.js.map +1 -0
  145. package/dist/src/migrations/runner.d.ts +84 -0
  146. package/dist/src/migrations/runner.d.ts.map +1 -0
  147. package/dist/src/migrations/runner.js +338 -0
  148. package/dist/src/migrations/runner.js.map +1 -0
  149. package/dist/src/orchestrator/coder.d.ts +32 -0
  150. package/dist/src/orchestrator/coder.d.ts.map +1 -0
  151. package/dist/src/orchestrator/coder.js +170 -0
  152. package/dist/src/orchestrator/coder.js.map +1 -0
  153. package/dist/src/orchestrator/coordinator.d.ts +28 -0
  154. package/dist/src/orchestrator/coordinator.d.ts.map +1 -0
  155. package/dist/src/orchestrator/coordinator.js +252 -0
  156. package/dist/src/orchestrator/coordinator.js.map +1 -0
  157. package/dist/src/orchestrator/fallback-handler.d.ts +24 -0
  158. package/dist/src/orchestrator/fallback-handler.d.ts.map +1 -0
  159. package/dist/src/orchestrator/fallback-handler.js +280 -0
  160. package/dist/src/orchestrator/fallback-handler.js.map +1 -0
  161. package/dist/src/orchestrator/invoke.d.ts +14 -0
  162. package/dist/src/orchestrator/invoke.d.ts.map +1 -0
  163. package/dist/src/orchestrator/invoke.js +76 -0
  164. package/dist/src/orchestrator/invoke.js.map +1 -0
  165. package/dist/src/orchestrator/post-coder.d.ts +10 -0
  166. package/dist/src/orchestrator/post-coder.d.ts.map +1 -0
  167. package/dist/src/orchestrator/post-coder.js +198 -0
  168. package/dist/src/orchestrator/post-coder.js.map +1 -0
  169. package/dist/src/orchestrator/post-reviewer.d.ts +10 -0
  170. package/dist/src/orchestrator/post-reviewer.d.ts.map +1 -0
  171. package/dist/src/orchestrator/post-reviewer.js +199 -0
  172. package/dist/src/orchestrator/post-reviewer.js.map +1 -0
  173. package/dist/src/orchestrator/reviewer.d.ts +35 -0
  174. package/dist/src/orchestrator/reviewer.d.ts.map +1 -0
  175. package/dist/src/orchestrator/reviewer.js +237 -0
  176. package/dist/src/orchestrator/reviewer.js.map +1 -0
  177. package/dist/src/orchestrator/schemas.d.ts +10 -0
  178. package/dist/src/orchestrator/schemas.d.ts.map +1 -0
  179. package/dist/src/orchestrator/schemas.js +81 -0
  180. package/dist/src/orchestrator/schemas.js.map +1 -0
  181. package/dist/src/orchestrator/task-selector.d.ts +102 -0
  182. package/dist/src/orchestrator/task-selector.d.ts.map +1 -0
  183. package/dist/src/orchestrator/task-selector.js +326 -0
  184. package/dist/src/orchestrator/task-selector.js.map +1 -0
  185. package/dist/src/orchestrator/types.d.ts +74 -0
  186. package/dist/src/orchestrator/types.d.ts.map +1 -0
  187. package/dist/src/orchestrator/types.js +5 -0
  188. package/dist/src/orchestrator/types.js.map +1 -0
  189. package/dist/src/prompts/coder.d.ts +36 -0
  190. package/dist/src/prompts/coder.d.ts.map +1 -0
  191. package/dist/src/prompts/coder.js +303 -0
  192. package/dist/src/prompts/coder.js.map +1 -0
  193. package/dist/src/prompts/prompt-helpers.d.ts +51 -0
  194. package/dist/src/prompts/prompt-helpers.d.ts.map +1 -0
  195. package/dist/src/prompts/prompt-helpers.js +299 -0
  196. package/dist/src/prompts/prompt-helpers.js.map +1 -0
  197. package/dist/src/prompts/reviewer.d.ts +40 -0
  198. package/dist/src/prompts/reviewer.d.ts.map +1 -0
  199. package/dist/src/prompts/reviewer.js +416 -0
  200. package/dist/src/prompts/reviewer.js.map +1 -0
  201. package/dist/src/providers/claude.d.ts +53 -0
  202. package/dist/src/providers/claude.d.ts.map +1 -0
  203. package/dist/src/providers/claude.js +227 -0
  204. package/dist/src/providers/claude.js.map +1 -0
  205. package/dist/src/providers/codex.d.ts +53 -0
  206. package/dist/src/providers/codex.d.ts.map +1 -0
  207. package/dist/src/providers/codex.js +253 -0
  208. package/dist/src/providers/codex.js.map +1 -0
  209. package/dist/src/providers/gemini.d.ts +58 -0
  210. package/dist/src/providers/gemini.d.ts.map +1 -0
  211. package/dist/src/providers/gemini.js +240 -0
  212. package/dist/src/providers/gemini.js.map +1 -0
  213. package/dist/src/providers/interface.d.ts +185 -0
  214. package/dist/src/providers/interface.d.ts.map +1 -0
  215. package/dist/src/providers/interface.js +92 -0
  216. package/dist/src/providers/interface.js.map +1 -0
  217. package/dist/src/providers/invocation-logger.d.ts +97 -0
  218. package/dist/src/providers/invocation-logger.d.ts.map +1 -0
  219. package/dist/src/providers/invocation-logger.js +378 -0
  220. package/dist/src/providers/invocation-logger.js.map +1 -0
  221. package/dist/src/providers/openai.d.ts +53 -0
  222. package/dist/src/providers/openai.d.ts.map +1 -0
  223. package/dist/src/providers/openai.js +230 -0
  224. package/dist/src/providers/openai.js.map +1 -0
  225. package/dist/src/providers/registry.d.ts +100 -0
  226. package/dist/src/providers/registry.d.ts.map +1 -0
  227. package/dist/src/providers/registry.js +170 -0
  228. package/dist/src/providers/registry.js.map +1 -0
  229. package/dist/src/routes/activity.d.ts +7 -0
  230. package/dist/src/routes/activity.d.ts.map +1 -0
  231. package/dist/src/routes/activity.js +252 -0
  232. package/dist/src/routes/activity.js.map +1 -0
  233. package/dist/src/routes/config.d.ts +7 -0
  234. package/dist/src/routes/config.d.ts.map +1 -0
  235. package/dist/src/routes/config.js +521 -0
  236. package/dist/src/routes/config.js.map +1 -0
  237. package/dist/src/routes/health.d.ts +7 -0
  238. package/dist/src/routes/health.d.ts.map +1 -0
  239. package/dist/src/routes/health.js +172 -0
  240. package/dist/src/routes/health.js.map +1 -0
  241. package/dist/src/routes/incidents.d.ts +7 -0
  242. package/dist/src/routes/incidents.d.ts.map +1 -0
  243. package/dist/src/routes/incidents.js +117 -0
  244. package/dist/src/routes/incidents.js.map +1 -0
  245. package/dist/src/routes/projects.d.ts +7 -0
  246. package/dist/src/routes/projects.d.ts.map +1 -0
  247. package/dist/src/routes/projects.js +398 -0
  248. package/dist/src/routes/projects.js.map +1 -0
  249. package/dist/src/routes/runners.d.ts +7 -0
  250. package/dist/src/routes/runners.d.ts.map +1 -0
  251. package/dist/src/routes/runners.js +242 -0
  252. package/dist/src/routes/runners.js.map +1 -0
  253. package/dist/src/routes/tasks.d.ts +7 -0
  254. package/dist/src/routes/tasks.d.ts.map +1 -0
  255. package/dist/src/routes/tasks.js +1007 -0
  256. package/dist/src/routes/tasks.js.map +1 -0
  257. package/dist/src/runners/activity-log.d.ts +65 -0
  258. package/dist/src/runners/activity-log.d.ts.map +1 -0
  259. package/dist/src/runners/activity-log.js +140 -0
  260. package/dist/src/runners/activity-log.js.map +1 -0
  261. package/dist/src/runners/cron.d.ts +30 -0
  262. package/dist/src/runners/cron.d.ts.map +1 -0
  263. package/dist/src/runners/cron.js +333 -0
  264. package/dist/src/runners/cron.js.map +1 -0
  265. package/dist/src/runners/daemon.d.ts +71 -0
  266. package/dist/src/runners/daemon.d.ts.map +1 -0
  267. package/dist/src/runners/daemon.js +233 -0
  268. package/dist/src/runners/daemon.js.map +1 -0
  269. package/dist/src/runners/global-db.d.ts +31 -0
  270. package/dist/src/runners/global-db.d.ts.map +1 -0
  271. package/dist/src/runners/global-db.js +220 -0
  272. package/dist/src/runners/global-db.js.map +1 -0
  273. package/dist/src/runners/hang-detector.d.ts +38 -0
  274. package/dist/src/runners/hang-detector.d.ts.map +1 -0
  275. package/dist/src/runners/hang-detector.js +130 -0
  276. package/dist/src/runners/hang-detector.js.map +1 -0
  277. package/dist/src/runners/heartbeat.d.ts +39 -0
  278. package/dist/src/runners/heartbeat.d.ts.map +1 -0
  279. package/dist/src/runners/heartbeat.js +71 -0
  280. package/dist/src/runners/heartbeat.js.map +1 -0
  281. package/dist/src/runners/lock.d.ts +47 -0
  282. package/dist/src/runners/lock.d.ts.map +1 -0
  283. package/dist/src/runners/lock.js +140 -0
  284. package/dist/src/runners/lock.js.map +1 -0
  285. package/dist/src/runners/orchestrator-loop.d.ts +20 -0
  286. package/dist/src/runners/orchestrator-loop.d.ts.map +1 -0
  287. package/dist/src/runners/orchestrator-loop.js +208 -0
  288. package/dist/src/runners/orchestrator-loop.js.map +1 -0
  289. package/dist/src/runners/projects.d.ts +96 -0
  290. package/dist/src/runners/projects.d.ts.map +1 -0
  291. package/dist/src/runners/projects.js +243 -0
  292. package/dist/src/runners/projects.js.map +1 -0
  293. package/dist/src/runners/wakeup.d.ts +37 -0
  294. package/dist/src/runners/wakeup.d.ts.map +1 -0
  295. package/dist/src/runners/wakeup.js +355 -0
  296. package/dist/src/runners/wakeup.js.map +1 -0
  297. package/dist/src/utils/validation.d.ts +22 -0
  298. package/dist/src/utils/validation.d.ts.map +1 -0
  299. package/dist/src/utils/validation.js +50 -0
  300. package/dist/src/utils/validation.js.map +1 -0
  301. package/dist/utils/sqlite.d.ts +17 -0
  302. package/dist/utils/sqlite.d.ts.map +1 -0
  303. package/dist/utils/sqlite.js +27 -0
  304. package/dist/utils/sqlite.js.map +1 -0
  305. package/dist/utils/storage-cache.d.ts +33 -0
  306. package/dist/utils/storage-cache.d.ts.map +1 -0
  307. package/dist/utils/storage-cache.js +81 -0
  308. package/dist/utils/storage-cache.js.map +1 -0
  309. package/dist/utils/validation.d.ts +22 -0
  310. package/dist/utils/validation.d.ts.map +1 -0
  311. package/dist/utils/validation.js +51 -0
  312. package/dist/utils/validation.js.map +1 -0
  313. package/package.json +39 -0
  314. package/src/index.ts +199 -0
  315. package/src/routes/activity.ts +302 -0
  316. package/src/routes/config.ts +723 -0
  317. package/src/routes/credit-alerts.ts +73 -0
  318. package/src/routes/health.ts +219 -0
  319. package/src/routes/incidents.ts +131 -0
  320. package/src/routes/projects.ts +854 -0
  321. package/src/routes/runners.ts +357 -0
  322. package/src/routes/skills.ts +127 -0
  323. package/src/routes/storage.ts +108 -0
  324. package/src/routes/tasks.ts +1372 -0
  325. package/src/utils/sqlite.ts +36 -0
  326. package/src/utils/storage-cache.ts +107 -0
  327. package/src/utils/validation.ts +61 -0
  328. package/tsconfig.json +20 -0
@@ -0,0 +1,378 @@
1
+ /**
2
+ * Invocation Logger
3
+ * Logs all LLM invocations for debugging and audit purposes
4
+ */
5
+ import { appendFileSync, existsSync, mkdirSync, writeFileSync, readdirSync, rmSync, statSync, } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ /**
8
+ * Default configuration
9
+ */
10
+ const DEFAULT_CONFIG = {
11
+ enabled: true,
12
+ logsDir: '.steroids/logs',
13
+ retentionDays: 7,
14
+ includePrompts: true,
15
+ includeResponses: true,
16
+ };
17
+ /**
18
+ * Invocation Logger
19
+ * Logs LLM invocations to disk for debugging and audit
20
+ */
21
+ export class InvocationLogger {
22
+ config;
23
+ constructor(config = {}) {
24
+ this.config = { ...DEFAULT_CONFIG, ...config };
25
+ }
26
+ /**
27
+ * Log an invocation
28
+ */
29
+ log(entry) {
30
+ if (!this.config.enabled) {
31
+ return;
32
+ }
33
+ try {
34
+ // Ensure logs directory exists
35
+ this.ensureLogsDirectory();
36
+ // Create log file path
37
+ const logFileName = this.createLogFileName(entry);
38
+ const logFilePath = join(this.config.logsDir, logFileName);
39
+ // Build log content
40
+ const logContent = this.formatLogEntry(entry);
41
+ // Write to file
42
+ writeFileSync(logFilePath, logContent, 'utf-8');
43
+ // Clean up old logs
44
+ this.cleanupOldLogs();
45
+ }
46
+ catch (error) {
47
+ // Don't fail the invocation if logging fails
48
+ console.warn(`Failed to log invocation: ${error}`);
49
+ }
50
+ }
51
+ /**
52
+ * Create log file name
53
+ */
54
+ createLogFileName(entry) {
55
+ const date = new Date(entry.timestamp);
56
+ const dateStr = date.toISOString().split('T')[0]; // YYYY-MM-DD
57
+ const timeStr = date.toISOString().split('T')[1].split('.')[0].replace(/:/g, '-'); // HH-MM-SS
58
+ const taskPart = entry.taskId ? `-${entry.taskId.substring(0, 8)}` : '';
59
+ const successPart = entry.success ? 'success' : 'failed';
60
+ // Ensure date directory exists
61
+ const dateDir = join(this.config.logsDir, dateStr);
62
+ if (!existsSync(dateDir)) {
63
+ mkdirSync(dateDir, { recursive: true });
64
+ }
65
+ return `${dateStr}/${timeStr}-${entry.role}-${entry.provider}-${successPart}${taskPart}.log`;
66
+ }
67
+ /**
68
+ * Format log entry as text
69
+ */
70
+ formatLogEntry(entry) {
71
+ const lines = [];
72
+ lines.push('='.repeat(80));
73
+ lines.push('LLM INVOCATION LOG');
74
+ lines.push('='.repeat(80));
75
+ lines.push('');
76
+ lines.push(`Timestamp: ${entry.timestamp}`);
77
+ lines.push(`Role: ${entry.role}`);
78
+ lines.push(`Provider: ${entry.provider}`);
79
+ lines.push(`Model: ${entry.model}`);
80
+ if (entry.taskId) {
81
+ lines.push(`Task ID: ${entry.taskId}`);
82
+ }
83
+ lines.push(`Duration: ${entry.duration}ms (${(entry.duration / 1000).toFixed(1)}s)`);
84
+ lines.push(`Exit Code: ${entry.exitCode}`);
85
+ lines.push(`Success: ${entry.success ? 'Yes' : 'No'}`);
86
+ lines.push(`Timed Out: ${entry.timedOut ? 'Yes' : 'No'}`);
87
+ lines.push('');
88
+ if (this.config.includePrompts && entry.prompt) {
89
+ lines.push('-'.repeat(80));
90
+ lines.push('PROMPT');
91
+ lines.push('-'.repeat(80));
92
+ lines.push(entry.prompt);
93
+ lines.push('');
94
+ }
95
+ if (this.config.includeResponses && entry.response) {
96
+ lines.push('-'.repeat(80));
97
+ lines.push('RESPONSE');
98
+ lines.push('-'.repeat(80));
99
+ lines.push(entry.response);
100
+ lines.push('');
101
+ }
102
+ if (entry.error) {
103
+ lines.push('-'.repeat(80));
104
+ lines.push('ERROR');
105
+ lines.push('-'.repeat(80));
106
+ lines.push(entry.error);
107
+ lines.push('');
108
+ }
109
+ lines.push('='.repeat(80));
110
+ return lines.join('\n');
111
+ }
112
+ /**
113
+ * Ensure logs directory exists
114
+ */
115
+ ensureLogsDirectory() {
116
+ if (!existsSync(this.config.logsDir)) {
117
+ mkdirSync(this.config.logsDir, { recursive: true });
118
+ }
119
+ }
120
+ /**
121
+ * Clean up old logs based on retention policy
122
+ */
123
+ cleanupOldLogs() {
124
+ if (this.config.retentionDays === 0) {
125
+ return; // Keep forever
126
+ }
127
+ try {
128
+ const cutoffDate = new Date();
129
+ cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);
130
+ // Iterate through date directories
131
+ const entries = readdirSync(this.config.logsDir, { withFileTypes: true });
132
+ for (const entry of entries) {
133
+ if (!entry.isDirectory()) {
134
+ continue;
135
+ }
136
+ // Check if directory name is a date (YYYY-MM-DD)
137
+ const dateMatch = entry.name.match(/^\d{4}-\d{2}-\d{2}$/);
138
+ if (!dateMatch) {
139
+ continue;
140
+ }
141
+ const dirDate = new Date(entry.name);
142
+ if (dirDate < cutoffDate) {
143
+ // Delete old directory
144
+ const dirPath = join(this.config.logsDir, entry.name);
145
+ rmSync(dirPath, { recursive: true, force: true });
146
+ }
147
+ }
148
+ }
149
+ catch (error) {
150
+ console.warn(`Failed to cleanup old logs: ${error}`);
151
+ }
152
+ }
153
+ /**
154
+ * Get all log files
155
+ */
156
+ getAllLogs() {
157
+ if (!existsSync(this.config.logsDir)) {
158
+ return [];
159
+ }
160
+ const logs = [];
161
+ try {
162
+ const entries = readdirSync(this.config.logsDir, { withFileTypes: true });
163
+ for (const entry of entries) {
164
+ if (!entry.isDirectory()) {
165
+ continue;
166
+ }
167
+ const dateDir = join(this.config.logsDir, entry.name);
168
+ const logFiles = readdirSync(dateDir).filter((f) => f.endsWith('.log'));
169
+ for (const logFile of logFiles) {
170
+ logs.push(join(dateDir, logFile));
171
+ }
172
+ }
173
+ }
174
+ catch (error) {
175
+ console.warn(`Failed to list logs: ${error}`);
176
+ }
177
+ return logs.sort();
178
+ }
179
+ /**
180
+ * Purge all logs
181
+ */
182
+ purgeAll() {
183
+ if (existsSync(this.config.logsDir)) {
184
+ try {
185
+ rmSync(this.config.logsDir, { recursive: true, force: true });
186
+ mkdirSync(this.config.logsDir, { recursive: true });
187
+ }
188
+ catch (error) {
189
+ console.warn(`Failed to purge logs: ${error}`);
190
+ }
191
+ }
192
+ }
193
+ /**
194
+ * Get total size of all logs in bytes
195
+ */
196
+ getTotalSize() {
197
+ const logs = this.getAllLogs();
198
+ let totalSize = 0;
199
+ for (const logPath of logs) {
200
+ try {
201
+ const stats = statSync(logPath);
202
+ totalSize += stats.size;
203
+ }
204
+ catch {
205
+ // Ignore errors
206
+ }
207
+ }
208
+ return totalSize;
209
+ }
210
+ }
211
+ /**
212
+ * Global invocation logger instance
213
+ */
214
+ let globalLogger = null;
215
+ /**
216
+ * Get the global invocation logger
217
+ */
218
+ export function getInvocationLogger(config) {
219
+ if (!globalLogger) {
220
+ globalLogger = new InvocationLogger(config);
221
+ }
222
+ return globalLogger;
223
+ }
224
+ /**
225
+ * Set the global invocation logger
226
+ */
227
+ export function setInvocationLogger(logger) {
228
+ globalLogger = logger;
229
+ }
230
+ /**
231
+ * Reset the global invocation logger
232
+ */
233
+ export function resetInvocationLogger() {
234
+ globalLogger = null;
235
+ }
236
+ function ensureInvocationsDir(projectPath) {
237
+ const dir = join(projectPath, '.steroids', 'invocations');
238
+ if (!existsSync(dir))
239
+ mkdirSync(dir, { recursive: true });
240
+ try {
241
+ writeFileSync(join(dir, 'README.txt'), 'Activity logs for invocations (JSONL).\n', { flag: 'wx' });
242
+ }
243
+ catch { }
244
+ return dir;
245
+ }
246
+ function appendJsonlLine(filePath, entry) {
247
+ // Best-effort logging: never fail the invocation on log I/O issues.
248
+ try {
249
+ appendFileSync(filePath, `${JSON.stringify(entry)}\n`, 'utf-8');
250
+ }
251
+ catch (error) {
252
+ console.warn(`Failed to append invocation activity log: ${error}`);
253
+ }
254
+ }
255
+ export async function logInvocation(prompt, invokeOrResult, metadata) {
256
+ const logger = getInvocationLogger();
257
+ const startedAtMs = Date.now();
258
+ const canDbLog = Boolean(metadata.taskId && metadata.projectPath) &&
259
+ (metadata.role === 'coder' || metadata.role === 'reviewer');
260
+ const projectPath = metadata.projectPath;
261
+ let invocationId = null;
262
+ let activityLogFile = null;
263
+ let dbConn = null;
264
+ const activity = (entry) => {
265
+ if (!activityLogFile)
266
+ return;
267
+ appendJsonlLine(activityLogFile, { ts: Date.now(), ...entry });
268
+ };
269
+ if (canDbLog && projectPath) {
270
+ try {
271
+ const { openDatabase } = await import('../database/connection.js');
272
+ const conn = openDatabase(projectPath);
273
+ dbConn = conn;
274
+ const insert = conn.db.prepare(`INSERT INTO task_invocations (task_id, role, provider, model, prompt, started_at_ms, status, rejection_number)
275
+ VALUES (?, ?, ?, ?, ?, ?, 'running', ?)`);
276
+ const info = insert.run(metadata.taskId, metadata.role, metadata.provider, metadata.model, prompt, startedAtMs, metadata.rejectionNumber ?? null);
277
+ invocationId = Number(info.lastInsertRowid);
278
+ const invDir = ensureInvocationsDir(projectPath);
279
+ activityLogFile = join(invDir, `${invocationId}.log`);
280
+ activity({ type: 'start', role: metadata.role, provider: metadata.provider, model: metadata.model });
281
+ }
282
+ catch (error) {
283
+ console.warn(`Failed to create running invocation record: ${error}`);
284
+ if (dbConn) {
285
+ try {
286
+ dbConn.close();
287
+ }
288
+ catch { }
289
+ }
290
+ dbConn = null;
291
+ }
292
+ }
293
+ try {
294
+ const result = typeof invokeOrResult === 'function'
295
+ ? await invokeOrResult({ onActivity: (a) => activity(a) })
296
+ : invokeOrResult;
297
+ const completedAtMs = Date.now();
298
+ const status = result.timedOut ? 'timeout' : result.success ? 'completed' : 'failed';
299
+ activity({ type: 'complete', success: result.success, duration: result.duration, exitCode: result.exitCode, timedOut: result.timedOut });
300
+ // Human-readable log (legacy: .steroids/logs) for `steroids logs`
301
+ logger.log({
302
+ timestamp: new Date(startedAtMs).toISOString(),
303
+ role: metadata.role,
304
+ provider: metadata.provider,
305
+ model: metadata.model,
306
+ taskId: metadata.taskId,
307
+ duration: result.duration,
308
+ exitCode: result.exitCode,
309
+ success: result.success,
310
+ timedOut: result.timedOut,
311
+ prompt,
312
+ response: result.stdout,
313
+ error: result.stderr || undefined,
314
+ });
315
+ if (canDbLog && dbConn && invocationId !== null) {
316
+ try {
317
+ dbConn.db.prepare(`UPDATE task_invocations
318
+ SET completed_at_ms = ?, status = ?, response = ?, error = ?, exit_code = ?, duration_ms = ?, success = ?, timed_out = ?, rejection_number = ?
319
+ WHERE id = ?`).run(completedAtMs, status, result.stdout, result.stderr || null, result.exitCode, result.duration, result.success ? 1 : 0, result.timedOut ? 1 : 0, metadata.rejectionNumber ?? null, invocationId);
320
+ }
321
+ catch (error) {
322
+ console.warn(`Failed to update invocation record: ${error}`);
323
+ }
324
+ finally {
325
+ try {
326
+ dbConn.close();
327
+ }
328
+ catch { }
329
+ }
330
+ }
331
+ return result;
332
+ }
333
+ catch (error) {
334
+ const completedAtMs = Date.now();
335
+ const durationMs = completedAtMs - startedAtMs;
336
+ const message = error instanceof Error ? error.message : String(error);
337
+ activity({ type: 'error', error: message });
338
+ // Human-readable fallback log
339
+ logger.log({
340
+ timestamp: new Date(startedAtMs).toISOString(),
341
+ role: metadata.role,
342
+ provider: metadata.provider,
343
+ model: metadata.model,
344
+ taskId: metadata.taskId,
345
+ duration: durationMs,
346
+ exitCode: 1,
347
+ success: false,
348
+ timedOut: false,
349
+ prompt,
350
+ response: '',
351
+ error: message,
352
+ });
353
+ if (canDbLog && dbConn && invocationId !== null) {
354
+ try {
355
+ dbConn.db.prepare(`UPDATE task_invocations
356
+ SET completed_at_ms = ?, status = 'failed', error = ?, exit_code = 1, duration_ms = ?, success = 0, timed_out = 0
357
+ WHERE id = ?`).run(completedAtMs, message, durationMs, invocationId);
358
+ }
359
+ catch (e) {
360
+ console.warn(`Failed to update failed invocation record: ${e}`);
361
+ }
362
+ finally {
363
+ try {
364
+ dbConn.close();
365
+ }
366
+ catch { }
367
+ }
368
+ }
369
+ else if (dbConn) {
370
+ try {
371
+ dbConn.close();
372
+ }
373
+ catch { }
374
+ }
375
+ throw error;
376
+ }
377
+ }
378
+ //# sourceMappingURL=invocation-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invocation-logger.js","sourceRoot":"","sources":["../../../../src/providers/invocation-logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * OpenAI Provider
3
+ * Implementation for OpenAI CLI
4
+ */
5
+ import { BaseAIProvider, type InvokeOptions, type InvokeResult, type ModelInfo } from './interface.js';
6
+ /**
7
+ * OpenAI Provider implementation
8
+ */
9
+ export declare class OpenAIProvider extends BaseAIProvider {
10
+ readonly name = "openai";
11
+ readonly displayName = "OpenAI";
12
+ /**
13
+ * Write prompt to a temporary file
14
+ */
15
+ private writePromptFile;
16
+ /**
17
+ * Clean up temporary prompt file
18
+ */
19
+ private cleanupPromptFile;
20
+ /**
21
+ * Get the default invocation template
22
+ */
23
+ getDefaultInvocationTemplate(): string;
24
+ /**
25
+ * Invoke OpenAI CLI with a prompt
26
+ */
27
+ invoke(prompt: string, options: InvokeOptions): Promise<InvokeResult>;
28
+ /**
29
+ * Invoke OpenAI CLI with a prompt file using the invocation template
30
+ */
31
+ private invokeWithFile;
32
+ /**
33
+ * Check if OpenAI CLI is available
34
+ */
35
+ isAvailable(): Promise<boolean>;
36
+ /**
37
+ * List available model IDs
38
+ */
39
+ listModels(): string[];
40
+ /**
41
+ * Get detailed model information
42
+ */
43
+ getModelInfo(): ModelInfo[];
44
+ /**
45
+ * Get the default model for a role
46
+ */
47
+ getDefaultModel(role: 'orchestrator' | 'coder' | 'reviewer'): string;
48
+ }
49
+ /**
50
+ * Create an OpenAI provider instance
51
+ */
52
+ export declare function createOpenAIProvider(): OpenAIProvider;
53
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../../src/providers/openai.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACL,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,gBAAgB,CAAC;AAoDxB;;GAEG;AACH,qBAAa,cAAe,SAAQ,cAAc;IAChD,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,YAAY;IAEhC;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,4BAA4B,IAAI,MAAM;IAItC;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAwB3E;;OAEG;IACH,OAAO,CAAC,cAAc;IAmFtB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAyBrC;;OAEG;IACH,UAAU,IAAI,MAAM,EAAE;IAItB;;OAEG;IACH,YAAY,IAAI,SAAS,EAAE;IAI3B;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM;CAGrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAErD"}
@@ -0,0 +1,230 @@
1
+ /**
2
+ * OpenAI Provider
3
+ * Implementation for OpenAI CLI
4
+ */
5
+ import { spawn } from 'node:child_process';
6
+ import { writeFileSync, unlinkSync, existsSync } from 'node:fs';
7
+ import { tmpdir } from 'node:os';
8
+ import { join } from 'node:path';
9
+ import { BaseAIProvider, } from './interface.js';
10
+ /**
11
+ * Available OpenAI models
12
+ */
13
+ const OPENAI_MODELS = [
14
+ {
15
+ id: 'gpt-4',
16
+ name: 'GPT-4',
17
+ recommendedFor: ['orchestrator', 'reviewer'],
18
+ supportsStreaming: true,
19
+ },
20
+ {
21
+ id: 'gpt-4-turbo',
22
+ name: 'GPT-4 Turbo',
23
+ recommendedFor: ['coder'],
24
+ supportsStreaming: true,
25
+ },
26
+ {
27
+ id: 'gpt-4o',
28
+ name: 'GPT-4o',
29
+ recommendedFor: ['coder'],
30
+ supportsStreaming: true,
31
+ },
32
+ {
33
+ id: 'gpt-3.5-turbo',
34
+ name: 'GPT-3.5 Turbo',
35
+ recommendedFor: [],
36
+ supportsStreaming: true,
37
+ },
38
+ ];
39
+ /**
40
+ * Default models per role
41
+ */
42
+ const DEFAULT_MODELS = {
43
+ orchestrator: 'gpt-4',
44
+ coder: 'gpt-4-turbo',
45
+ reviewer: 'gpt-4',
46
+ };
47
+ /**
48
+ * Default timeout in milliseconds (15 minutes)
49
+ */
50
+ const DEFAULT_TIMEOUT = 900_000;
51
+ /**
52
+ * Default invocation template for OpenAI CLI
53
+ * Uses api chat.completions.create with message from file
54
+ */
55
+ const DEFAULT_INVOCATION_TEMPLATE = '{cli} api chat.completions.create --model {model} --message "$(cat {prompt_file})"';
56
+ /**
57
+ * OpenAI Provider implementation
58
+ */
59
+ export class OpenAIProvider extends BaseAIProvider {
60
+ name = 'openai';
61
+ displayName = 'OpenAI';
62
+ /**
63
+ * Write prompt to a temporary file
64
+ */
65
+ writePromptFile(prompt) {
66
+ const tempPath = join(tmpdir(), `steroids-openai-${Date.now()}.txt`);
67
+ writeFileSync(tempPath, prompt, { mode: 0o600 });
68
+ return tempPath;
69
+ }
70
+ /**
71
+ * Clean up temporary prompt file
72
+ */
73
+ cleanupPromptFile(path) {
74
+ try {
75
+ if (existsSync(path)) {
76
+ unlinkSync(path);
77
+ }
78
+ }
79
+ catch {
80
+ // Ignore cleanup errors
81
+ }
82
+ }
83
+ /**
84
+ * Get the default invocation template
85
+ */
86
+ getDefaultInvocationTemplate() {
87
+ return DEFAULT_INVOCATION_TEMPLATE;
88
+ }
89
+ /**
90
+ * Invoke OpenAI CLI with a prompt
91
+ */
92
+ async invoke(prompt, options) {
93
+ const timeout = options.timeout ?? DEFAULT_TIMEOUT;
94
+ const cwd = options.cwd ?? process.cwd();
95
+ const streamOutput = options.streamOutput ?? true;
96
+ const onActivity = options.onActivity;
97
+ // Apply custom invocation template if provided in options
98
+ if (options.invocationTemplate) {
99
+ this.setInvocationTemplate(options.invocationTemplate);
100
+ }
101
+ // Write prompt to temp file
102
+ const promptFile = options.promptFile ?? this.writePromptFile(prompt);
103
+ const createdTempFile = !options.promptFile;
104
+ try {
105
+ return await this.invokeWithFile(promptFile, options.model, timeout, cwd, streamOutput, onActivity);
106
+ }
107
+ finally {
108
+ if (createdTempFile) {
109
+ this.cleanupPromptFile(promptFile);
110
+ }
111
+ }
112
+ }
113
+ /**
114
+ * Invoke OpenAI CLI with a prompt file using the invocation template
115
+ */
116
+ invokeWithFile(promptFile, model, timeout, cwd, streamOutput, onActivity) {
117
+ return new Promise((resolve) => {
118
+ const startTime = Date.now();
119
+ let stdout = '';
120
+ let stderr = '';
121
+ let timedOut = false;
122
+ // Build command from invocation template
123
+ const command = this.buildCommand(promptFile, model);
124
+ // Spawn using shell to handle the command template
125
+ const child = spawn(command, {
126
+ shell: true,
127
+ cwd,
128
+ stdio: ['pipe', 'pipe', 'pipe'],
129
+ });
130
+ const timeoutHandle = setTimeout(() => {
131
+ timedOut = true;
132
+ child.kill('SIGTERM');
133
+ // Force kill after 5 seconds if still running
134
+ setTimeout(() => {
135
+ if (!child.killed) {
136
+ child.kill('SIGKILL');
137
+ }
138
+ }, 5000);
139
+ }, timeout);
140
+ child.stdout?.on('data', (data) => {
141
+ const text = data.toString();
142
+ stdout += text;
143
+ onActivity?.({ type: 'output', stream: 'stdout', msg: text });
144
+ if (streamOutput) {
145
+ process.stdout.write(text);
146
+ }
147
+ });
148
+ child.stderr?.on('data', (data) => {
149
+ const text = data.toString();
150
+ stderr += text;
151
+ onActivity?.({ type: 'output', stream: 'stderr', msg: text });
152
+ if (streamOutput) {
153
+ process.stderr.write(text);
154
+ }
155
+ });
156
+ child.on('close', (code) => {
157
+ clearTimeout(timeoutHandle);
158
+ const duration = Date.now() - startTime;
159
+ resolve({
160
+ success: code === 0 && !timedOut,
161
+ exitCode: code ?? 1,
162
+ stdout,
163
+ stderr,
164
+ duration,
165
+ timedOut,
166
+ });
167
+ });
168
+ child.on('error', (error) => {
169
+ clearTimeout(timeoutHandle);
170
+ const duration = Date.now() - startTime;
171
+ resolve({
172
+ success: false,
173
+ exitCode: 1,
174
+ stdout,
175
+ stderr: error.message,
176
+ duration,
177
+ timedOut: false,
178
+ });
179
+ });
180
+ });
181
+ }
182
+ /**
183
+ * Check if OpenAI CLI is available
184
+ */
185
+ async isAvailable() {
186
+ return new Promise((resolve) => {
187
+ const cli = this.cliPath ?? 'openai';
188
+ const child = spawn('which', [cli], {
189
+ shell: true,
190
+ stdio: ['pipe', 'pipe', 'pipe'],
191
+ });
192
+ child.on('close', (code) => {
193
+ resolve(code === 0);
194
+ });
195
+ child.on('error', () => {
196
+ resolve(false);
197
+ });
198
+ // Timeout after 5 seconds
199
+ setTimeout(() => {
200
+ child.kill();
201
+ resolve(false);
202
+ }, 5000);
203
+ });
204
+ }
205
+ /**
206
+ * List available model IDs
207
+ */
208
+ listModels() {
209
+ return OPENAI_MODELS.map((m) => m.id);
210
+ }
211
+ /**
212
+ * Get detailed model information
213
+ */
214
+ getModelInfo() {
215
+ return [...OPENAI_MODELS];
216
+ }
217
+ /**
218
+ * Get the default model for a role
219
+ */
220
+ getDefaultModel(role) {
221
+ return DEFAULT_MODELS[role];
222
+ }
223
+ }
224
+ /**
225
+ * Create an OpenAI provider instance
226
+ */
227
+ export function createOpenAIProvider() {
228
+ return new OpenAIProvider();
229
+ }
230
+ //# sourceMappingURL=openai.js.map