vibeman 0.0.5 → 0.0.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 (239) hide show
  1. package/dist/api.js +43 -0
  2. package/dist/index.js +227 -104
  3. package/dist/ui/assets/index-C_kQPI1m.js +9 -0
  4. package/dist/ui/index.html +12 -0
  5. package/package.json +13 -46
  6. package/README.md +0 -12
  7. package/dist/runtime/api/.tsbuildinfo +0 -1
  8. package/dist/runtime/api/agent/agent-service.d.ts +0 -229
  9. package/dist/runtime/api/agent/agent-service.js +0 -963
  10. package/dist/runtime/api/agent/ai-providers/amp-cli-provider.d.ts +0 -38
  11. package/dist/runtime/api/agent/ai-providers/amp-cli-provider.js +0 -268
  12. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.d.ts +0 -61
  13. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.js +0 -362
  14. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.d.ts +0 -36
  15. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.js +0 -375
  16. package/dist/runtime/api/agent/ai-providers/gemini-cli-provider.d.ts +0 -24
  17. package/dist/runtime/api/agent/ai-providers/gemini-cli-provider.js +0 -291
  18. package/dist/runtime/api/agent/ai-providers/index.d.ts +0 -9
  19. package/dist/runtime/api/agent/ai-providers/index.js +0 -9
  20. package/dist/runtime/api/agent/ai-providers/types.d.ts +0 -185
  21. package/dist/runtime/api/agent/ai-providers/types.js +0 -5
  22. package/dist/runtime/api/agent/amp-cli-provider.test.d.ts +0 -1
  23. package/dist/runtime/api/agent/amp-cli-provider.test.js +0 -99
  24. package/dist/runtime/api/agent/codex-cli-provider.test.d.ts +0 -1
  25. package/dist/runtime/api/agent/codex-cli-provider.test.js +0 -172
  26. package/dist/runtime/api/agent/core-agent-service.d.ts +0 -119
  27. package/dist/runtime/api/agent/core-agent-service.js +0 -267
  28. package/dist/runtime/api/agent/parsers.d.ts +0 -16
  29. package/dist/runtime/api/agent/parsers.js +0 -308
  30. package/dist/runtime/api/agent/prompt-service.d.ts +0 -30
  31. package/dist/runtime/api/agent/prompt-service.js +0 -452
  32. package/dist/runtime/api/agent/prompt-service.test.d.ts +0 -1
  33. package/dist/runtime/api/agent/prompt-service.test.js +0 -265
  34. package/dist/runtime/api/agent/routing-policy.d.ts +0 -171
  35. package/dist/runtime/api/agent/routing-policy.js +0 -196
  36. package/dist/runtime/api/agent/routing-policy.test.d.ts +0 -1
  37. package/dist/runtime/api/agent/routing-policy.test.js +0 -63
  38. package/dist/runtime/api/api/router-helpers.d.ts +0 -32
  39. package/dist/runtime/api/api/router-helpers.js +0 -31
  40. package/dist/runtime/api/api/routers/ai.d.ts +0 -200
  41. package/dist/runtime/api/api/routers/ai.js +0 -396
  42. package/dist/runtime/api/api/routers/executions.d.ts +0 -93
  43. package/dist/runtime/api/api/routers/executions.js +0 -94
  44. package/dist/runtime/api/api/routers/git.d.ts +0 -45
  45. package/dist/runtime/api/api/routers/git.js +0 -35
  46. package/dist/runtime/api/api/routers/provider-config.d.ts +0 -199
  47. package/dist/runtime/api/api/routers/provider-config.js +0 -252
  48. package/dist/runtime/api/api/routers/settings.d.ts +0 -158
  49. package/dist/runtime/api/api/routers/settings.js +0 -129
  50. package/dist/runtime/api/api/routers/tasks.d.ts +0 -141
  51. package/dist/runtime/api/api/routers/tasks.js +0 -238
  52. package/dist/runtime/api/api/routers/workflows.d.ts +0 -275
  53. package/dist/runtime/api/api/routers/workflows.js +0 -311
  54. package/dist/runtime/api/api/routers/worktrees.d.ts +0 -101
  55. package/dist/runtime/api/api/routers/worktrees.js +0 -80
  56. package/dist/runtime/api/api/trpc.d.ts +0 -118
  57. package/dist/runtime/api/api/trpc.js +0 -34
  58. package/dist/runtime/api/index.d.ts +0 -9
  59. package/dist/runtime/api/index.js +0 -117
  60. package/dist/runtime/api/lib/id-generator.d.ts +0 -70
  61. package/dist/runtime/api/lib/id-generator.js +0 -123
  62. package/dist/runtime/api/lib/local-config.d.ts +0 -335
  63. package/dist/runtime/api/lib/local-config.js +0 -304
  64. package/dist/runtime/api/lib/logger.d.ts +0 -11
  65. package/dist/runtime/api/lib/logger.js +0 -188
  66. package/dist/runtime/api/lib/provider-detection.d.ts +0 -61
  67. package/dist/runtime/api/lib/provider-detection.js +0 -326
  68. package/dist/runtime/api/lib/server/agent-service-singleton.d.ts +0 -6
  69. package/dist/runtime/api/lib/server/agent-service-singleton.js +0 -27
  70. package/dist/runtime/api/lib/server/bootstrap.d.ts +0 -38
  71. package/dist/runtime/api/lib/server/bootstrap.js +0 -197
  72. package/dist/runtime/api/lib/server/git-service-singleton.d.ts +0 -6
  73. package/dist/runtime/api/lib/server/git-service-singleton.js +0 -47
  74. package/dist/runtime/api/lib/server/project-root.d.ts +0 -2
  75. package/dist/runtime/api/lib/server/project-root.js +0 -61
  76. package/dist/runtime/api/lib/server/task-service-singleton.d.ts +0 -7
  77. package/dist/runtime/api/lib/server/task-service-singleton.js +0 -58
  78. package/dist/runtime/api/lib/server/vibeman-info.d.ts +0 -5
  79. package/dist/runtime/api/lib/server/vibeman-info.js +0 -85
  80. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.d.ts +0 -7
  81. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.js +0 -57
  82. package/dist/runtime/api/lib/trpc/server.d.ts +0 -965
  83. package/dist/runtime/api/lib/trpc/server.js +0 -11
  84. package/dist/runtime/api/lib/trpc/ws-server.d.ts +0 -8
  85. package/dist/runtime/api/lib/trpc/ws-server.js +0 -33
  86. package/dist/runtime/api/persistence/database-service.d.ts +0 -14
  87. package/dist/runtime/api/persistence/database-service.js +0 -74
  88. package/dist/runtime/api/persistence/execution-log-persistence.d.ts +0 -90
  89. package/dist/runtime/api/persistence/execution-log-persistence.js +0 -426
  90. package/dist/runtime/api/persistence/execution-log-persistence.test.d.ts +0 -1
  91. package/dist/runtime/api/persistence/execution-log-persistence.test.js +0 -170
  92. package/dist/runtime/api/router.d.ts +0 -968
  93. package/dist/runtime/api/router.js +0 -34
  94. package/dist/runtime/api/settings-service.d.ts +0 -110
  95. package/dist/runtime/api/settings-service.js +0 -678
  96. package/dist/runtime/api/tasks/file-watcher.d.ts +0 -23
  97. package/dist/runtime/api/tasks/file-watcher.js +0 -88
  98. package/dist/runtime/api/tasks/task-file-parser.d.ts +0 -14
  99. package/dist/runtime/api/tasks/task-file-parser.js +0 -180
  100. package/dist/runtime/api/tasks/task-service.d.ts +0 -36
  101. package/dist/runtime/api/tasks/task-service.js +0 -173
  102. package/dist/runtime/api/tasks/task-updater.d.ts +0 -62
  103. package/dist/runtime/api/tasks/task-updater.js +0 -260
  104. package/dist/runtime/api/tasks/task-updater.test.d.ts +0 -1
  105. package/dist/runtime/api/tasks/task-updater.test.js +0 -303
  106. package/dist/runtime/api/types/index.d.ts +0 -186
  107. package/dist/runtime/api/types/index.js +0 -1
  108. package/dist/runtime/api/types/settings.d.ts +0 -105
  109. package/dist/runtime/api/types/settings.js +0 -2
  110. package/dist/runtime/api/types.d.ts +0 -2
  111. package/dist/runtime/api/types.js +0 -1
  112. package/dist/runtime/api/utils/env.d.ts +0 -6
  113. package/dist/runtime/api/utils/env.js +0 -12
  114. package/dist/runtime/api/utils/stripNextEnv.d.ts +0 -7
  115. package/dist/runtime/api/utils/stripNextEnv.js +0 -22
  116. package/dist/runtime/api/utils/title-slug.d.ts +0 -6
  117. package/dist/runtime/api/utils/title-slug.js +0 -77
  118. package/dist/runtime/api/utils/url.d.ts +0 -2
  119. package/dist/runtime/api/utils/url.js +0 -19
  120. package/dist/runtime/api/vcs/git-history-service.d.ts +0 -57
  121. package/dist/runtime/api/vcs/git-history-service.js +0 -228
  122. package/dist/runtime/api/vcs/git-service.d.ts +0 -136
  123. package/dist/runtime/api/vcs/git-service.js +0 -307
  124. package/dist/runtime/api/vcs/worktree-service.d.ts +0 -93
  125. package/dist/runtime/api/vcs/worktree-service.js +0 -518
  126. package/dist/runtime/api/vcs/worktree-service.test.d.ts +0 -1
  127. package/dist/runtime/api/vcs/worktree-service.test.js +0 -20
  128. package/dist/runtime/api/workflows/quality-pipeline.d.ts +0 -58
  129. package/dist/runtime/api/workflows/quality-pipeline.js +0 -401
  130. package/dist/runtime/api/workflows/vibing-orchestrator.d.ts +0 -406
  131. package/dist/runtime/api/workflows/vibing-orchestrator.js +0 -2462
  132. package/dist/runtime/api/workflows/workflow-effects.d.ts +0 -45
  133. package/dist/runtime/api/workflows/workflow-effects.js +0 -49
  134. package/dist/runtime/api/workflows/workflow-reconciler.d.ts +0 -65
  135. package/dist/runtime/api/workflows/workflow-reconciler.js +0 -226
  136. package/dist/runtime/api/workflows/workflow-reducer.d.ts +0 -26
  137. package/dist/runtime/api/workflows/workflow-reducer.js +0 -288
  138. package/dist/runtime/api/workflows/workflow-reducer.test.d.ts +0 -1
  139. package/dist/runtime/api/workflows/workflow-reducer.test.js +0 -247
  140. package/dist/runtime/api/workflows/workflow-schema.d.ts +0 -546
  141. package/dist/runtime/api/workflows/workflow-schema.js +0 -256
  142. package/dist/runtime/web/.next/BUILD_ID +0 -1
  143. package/dist/runtime/web/.next/app-build-manifest.json +0 -66
  144. package/dist/runtime/web/.next/app-path-routes-manifest.json +0 -8
  145. package/dist/runtime/web/.next/build-manifest.json +0 -33
  146. package/dist/runtime/web/.next/package.json +0 -1
  147. package/dist/runtime/web/.next/prerender-manifest.json +0 -61
  148. package/dist/runtime/web/.next/react-loadable-manifest.json +0 -8
  149. package/dist/runtime/web/.next/required-server-files.json +0 -334
  150. package/dist/runtime/web/.next/routes-manifest.json +0 -70
  151. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js +0 -1
  152. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js.nft.json +0 -1
  153. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route_client-reference-manifest.js +0 -1
  154. package/dist/runtime/web/.next/server/app/_not-found/page.js +0 -2
  155. package/dist/runtime/web/.next/server/app/_not-found/page.js.nft.json +0 -1
  156. package/dist/runtime/web/.next/server/app/_not-found/page_client-reference-manifest.js +0 -1
  157. package/dist/runtime/web/.next/server/app/_not-found.html +0 -7
  158. package/dist/runtime/web/.next/server/app/_not-found.meta +0 -8
  159. package/dist/runtime/web/.next/server/app/_not-found.rsc +0 -22
  160. package/dist/runtime/web/.next/server/app/api/health/route.js +0 -1
  161. package/dist/runtime/web/.next/server/app/api/health/route.js.nft.json +0 -1
  162. package/dist/runtime/web/.next/server/app/api/health/route_client-reference-manifest.js +0 -1
  163. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js +0 -1
  164. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js.nft.json +0 -1
  165. package/dist/runtime/web/.next/server/app/api/images/[...path]/route_client-reference-manifest.js +0 -1
  166. package/dist/runtime/web/.next/server/app/api/upload/route.js +0 -1
  167. package/dist/runtime/web/.next/server/app/api/upload/route.js.nft.json +0 -1
  168. package/dist/runtime/web/.next/server/app/api/upload/route_client-reference-manifest.js +0 -1
  169. package/dist/runtime/web/.next/server/app/index.html +0 -7
  170. package/dist/runtime/web/.next/server/app/index.meta +0 -7
  171. package/dist/runtime/web/.next/server/app/index.rsc +0 -27
  172. package/dist/runtime/web/.next/server/app/page.js +0 -112
  173. package/dist/runtime/web/.next/server/app/page.js.nft.json +0 -1
  174. package/dist/runtime/web/.next/server/app/page_client-reference-manifest.js +0 -1
  175. package/dist/runtime/web/.next/server/app-paths-manifest.json +0 -8
  176. package/dist/runtime/web/.next/server/chunks/210.js +0 -1
  177. package/dist/runtime/web/.next/server/chunks/291.js +0 -18
  178. package/dist/runtime/web/.next/server/chunks/552.js +0 -22
  179. package/dist/runtime/web/.next/server/chunks/780.js +0 -1
  180. package/dist/runtime/web/.next/server/chunks/905.js +0 -6
  181. package/dist/runtime/web/.next/server/chunks/98.js +0 -1
  182. package/dist/runtime/web/.next/server/functions-config-manifest.json +0 -4
  183. package/dist/runtime/web/.next/server/middleware-build-manifest.js +0 -1
  184. package/dist/runtime/web/.next/server/middleware-manifest.json +0 -6
  185. package/dist/runtime/web/.next/server/middleware-react-loadable-manifest.js +0 -1
  186. package/dist/runtime/web/.next/server/next-font-manifest.js +0 -1
  187. package/dist/runtime/web/.next/server/next-font-manifest.json +0 -1
  188. package/dist/runtime/web/.next/server/pages/404.html +0 -7
  189. package/dist/runtime/web/.next/server/pages/500.html +0 -1
  190. package/dist/runtime/web/.next/server/pages/_app.js +0 -1
  191. package/dist/runtime/web/.next/server/pages/_app.js.nft.json +0 -1
  192. package/dist/runtime/web/.next/server/pages/_document.js +0 -1
  193. package/dist/runtime/web/.next/server/pages/_document.js.nft.json +0 -1
  194. package/dist/runtime/web/.next/server/pages/_error.js +0 -19
  195. package/dist/runtime/web/.next/server/pages/_error.js.nft.json +0 -1
  196. package/dist/runtime/web/.next/server/pages-manifest.json +0 -6
  197. package/dist/runtime/web/.next/server/server-reference-manifest.js +0 -1
  198. package/dist/runtime/web/.next/server/server-reference-manifest.json +0 -1
  199. package/dist/runtime/web/.next/server/webpack-runtime.js +0 -1
  200. package/dist/runtime/web/.next/static/LJFZk_8tvKFN_Ee4HqUuM/_buildManifest.js +0 -1
  201. package/dist/runtime/web/.next/static/LJFZk_8tvKFN_Ee4HqUuM/_ssgManifest.js +0 -1
  202. package/dist/runtime/web/.next/static/chunks/05c91ade-7d09b2b280adffd1.js +0 -1
  203. package/dist/runtime/web/.next/static/chunks/201-51bef3fa8c832e2e.js +0 -1
  204. package/dist/runtime/web/.next/static/chunks/524-89747ed9b0294f8a.js +0 -1
  205. package/dist/runtime/web/.next/static/chunks/554-8bec6e9cca6acc67.js +0 -1
  206. package/dist/runtime/web/.next/static/chunks/764.86e9503a69d45a85.js +0 -1
  207. package/dist/runtime/web/.next/static/chunks/7ab4dc20-239138e0ae7af24a.js +0 -1
  208. package/dist/runtime/web/.next/static/chunks/905-342391e3d3a3678f.js +0 -20
  209. package/dist/runtime/web/.next/static/chunks/a8a5ce16-4edea7df2d9b544a.js +0 -79
  210. package/dist/runtime/web/.next/static/chunks/ad74d572-4c1b162e2c15acaa.js +0 -1
  211. package/dist/runtime/web/.next/static/chunks/app/.vibeman/assets/images/[...path]/route-7b752a8641f96c1f.js +0 -1
  212. package/dist/runtime/web/.next/static/chunks/app/_not-found/page-34e66b251c2b5044.js +0 -1
  213. package/dist/runtime/web/.next/static/chunks/app/api/health/route-7b752a8641f96c1f.js +0 -1
  214. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-7b752a8641f96c1f.js +0 -1
  215. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-7b752a8641f96c1f.js +0 -1
  216. package/dist/runtime/web/.next/static/chunks/app/layout-df9ac93cb02b2385.js +0 -1
  217. package/dist/runtime/web/.next/static/chunks/app/page-6610743f7de5f92a.js +0 -1
  218. package/dist/runtime/web/.next/static/chunks/c25e0690-e9b798b8de667da1.js +0 -1
  219. package/dist/runtime/web/.next/static/chunks/framework-57157ec4d37f64aa.js +0 -1
  220. package/dist/runtime/web/.next/static/chunks/main-app-156cc0c60371bd78.js +0 -1
  221. package/dist/runtime/web/.next/static/chunks/main-df25d367c47b1fec.js +0 -1
  222. package/dist/runtime/web/.next/static/chunks/pages/_app-9f629a5e1131d19f.js +0 -1
  223. package/dist/runtime/web/.next/static/chunks/pages/_error-9238238274c7efcd.js +0 -1
  224. package/dist/runtime/web/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  225. package/dist/runtime/web/.next/static/chunks/webpack-cd50e39b423d1808.js +0 -1
  226. package/dist/runtime/web/.next/static/css/2728291c68f99cb1.css +0 -3
  227. package/dist/runtime/web/.next/static/css/4fbf378a264bd4ea.css +0 -1
  228. package/dist/runtime/web/.next/static/css/521bd69cc298cd1a.css +0 -1
  229. package/dist/runtime/web/.next/static/css/537e22821e101b87.css +0 -1
  230. package/dist/runtime/web/.next/static/media/19cfc7226ec3afaa-s.woff2 +0 -0
  231. package/dist/runtime/web/.next/static/media/21350d82a1f187e9-s.woff2 +0 -0
  232. package/dist/runtime/web/.next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
  233. package/dist/runtime/web/.next/static/media/ba9851c3c22cd980-s.woff2 +0 -0
  234. package/dist/runtime/web/.next/static/media/c5fe6dc8356a8c31-s.woff2 +0 -0
  235. package/dist/runtime/web/.next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  236. package/dist/runtime/web/.next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
  237. package/dist/runtime/web/package.json +0 -65
  238. package/dist/runtime/web/server.js +0 -44
  239. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,11 +0,0 @@
1
- import { createRouter } from '../../router.js';
2
- import { bootstrap, getBootstrappedTaskService, getBootstrappedGitService, getBootstrappedVibingOrchestrator, } from '../server/bootstrap.js';
3
- // Build the application router for use by the standalone API server.
4
- // Note: This module no longer starts any WebSocket servers automatically.
5
- // Services must be bootstrapped before calling this.
6
- // Ensure bootstrap is complete before creating router
7
- await bootstrap();
8
- const taskService = getBootstrappedTaskService();
9
- const gitService = getBootstrappedGitService();
10
- const workflowOrchestrator = getBootstrappedVibingOrchestrator();
11
- export const appRouter = createRouter(taskService, gitService, workflowOrchestrator);
@@ -1,8 +0,0 @@
1
- import type { AppRouter } from './server.js';
2
- declare global {
3
- var __VIBEMAN_WSS__: {
4
- started: boolean;
5
- } | undefined;
6
- }
7
- export declare function startTRPCWebSocketServer(router: AppRouter): void;
8
- export {};
@@ -1,33 +0,0 @@
1
- import { applyWSSHandler } from '@trpc/server/adapters/ws';
2
- import { WebSocketServer } from 'ws';
3
- import { getTaskService } from '../server/task-service-singleton.js';
4
- export function startTRPCWebSocketServer(router) {
5
- if (typeof global.__VIBEMAN_WSS__ === 'object' && global.__VIBEMAN_WSS__?.started) {
6
- return; // already started
7
- }
8
- // Decide WS port: (+1) from HTTP port
9
- const httpPort = Number(process.env.PORT || 3000);
10
- const wsPort = httpPort + 1;
11
- try {
12
- const wss = new WebSocketServer({ port: wsPort, path: '/api/trpc' });
13
- // Handle binding errors gracefully (e.g., EADDRINUSE across HMR workers)
14
- wss.on('error', (err) => {
15
- const code = (err && err.code) || '';
16
- if (code === 'EADDRINUSE') {
17
- console.warn(`[vibeman] WS port ${wsPort} in use; skipping secondary start.`);
18
- }
19
- else {
20
- console.warn('[vibeman] WS server error:', err);
21
- }
22
- });
23
- wss.on('listening', () => {
24
- const createContext = () => ({ taskService: getTaskService() });
25
- applyWSSHandler({ wss, router, createContext });
26
- console.log(`📡 tRPC WebSocket listening ws://localhost:${wsPort}/api/trpc`);
27
- global.__VIBEMAN_WSS__ = { started: true };
28
- });
29
- }
30
- catch (err) {
31
- console.warn('[vibeman] WS server not started:', err instanceof Error ? err.message : err);
32
- }
33
- }
@@ -1,14 +0,0 @@
1
- export declare class DatabaseService<T extends object> {
2
- private filePath;
3
- private dbPromise;
4
- constructor(filePath: string);
5
- private ensureDir;
6
- private getDb;
7
- getAll(): Promise<Record<string, T>>;
8
- setAll(value: Record<string, T>): Promise<void>;
9
- get(id: string): Promise<T | undefined>;
10
- set(id: string, value: T): Promise<void>;
11
- delete(id: string): Promise<void>;
12
- clear(): Promise<void>;
13
- getFilePath(): string;
14
- }
@@ -1,74 +0,0 @@
1
- import { promises as fs } from 'fs';
2
- import path from 'path';
3
- import { JSONFilePreset } from 'lowdb/node';
4
- // A tiny generic wrapper around lowdb that stores a single
5
- // object map `{ [id: string]: T }` in a JSON file.
6
- // No domain/business logic here — just generic CRUD helpers.
7
- export class DatabaseService {
8
- constructor(filePath) {
9
- this.dbPromise = null;
10
- // If filePath is absolute, use it as-is; otherwise resolve relative to cwd
11
- this.filePath = path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath);
12
- }
13
- async ensureDir() {
14
- const dir = path.dirname(this.filePath);
15
- try {
16
- await fs.access(dir);
17
- }
18
- catch {
19
- await fs.mkdir(dir, { recursive: true });
20
- }
21
- }
22
- async getDb() {
23
- if (!this.dbPromise) {
24
- await this.ensureDir();
25
- this.dbPromise = (async () => {
26
- const db = await JSONFilePreset(this.filePath, {});
27
- // Lightweight migration: if file accidentally has array shape, convert to id map
28
- const raw = db.data;
29
- if (Array.isArray(raw)) {
30
- const migrated = {};
31
- for (const item of raw) {
32
- if (item && typeof item.id === 'string')
33
- migrated[item.id] = item;
34
- }
35
- db.data = migrated;
36
- await db.write();
37
- }
38
- return db;
39
- })();
40
- }
41
- return this.dbPromise;
42
- }
43
- async getAll() {
44
- const db = await this.getDb();
45
- return { ...db.data };
46
- }
47
- async setAll(value) {
48
- const db = await this.getDb();
49
- db.data = { ...value };
50
- await db.write();
51
- }
52
- async get(id) {
53
- const db = await this.getDb();
54
- return db.data[id];
55
- }
56
- async set(id, value) {
57
- const db = await this.getDb();
58
- db.data[id] = value;
59
- await db.write();
60
- }
61
- async delete(id) {
62
- const db = await this.getDb();
63
- delete db.data[id];
64
- await db.write();
65
- }
66
- async clear() {
67
- const db = await this.getDb();
68
- db.data = {};
69
- await db.write();
70
- }
71
- getFilePath() {
72
- return this.filePath;
73
- }
74
- }
@@ -1,90 +0,0 @@
1
- import type { AgentExecution } from '../types/index.js';
2
- export interface ExecutionLogEntry {
3
- timestamp: string;
4
- level: 'info' | 'warn' | 'error';
5
- message: string;
6
- data?: Record<string, unknown>;
7
- }
8
- export interface ExecutionMetadata {
9
- executionId: string;
10
- taskId: string;
11
- workflowId?: string;
12
- startTime: string;
13
- endTime?: string;
14
- status: AgentExecution['status'];
15
- error?: string;
16
- worktreePath?: string;
17
- }
18
- export interface ExecutionIndexEntry {
19
- executionId: string;
20
- taskId: string;
21
- workflowId?: string;
22
- status: AgentExecution['status'];
23
- startTime: string;
24
- endTime?: string;
25
- dirPath: string;
26
- }
27
- export declare class ExecutionLogPersistence {
28
- private dataDir;
29
- private logsDir;
30
- private indexDb;
31
- constructor();
32
- /**
33
- * Ensure logs directory exists
34
- */
35
- private ensureLogsDir;
36
- /**
37
- * Get execution log directory path, grouped by task ID
38
- * .vibeman/.local/execution-logs/{taskId}/{executionId-YYYYMMDD_HHMMSS}/
39
- */
40
- private getExecutionDirFor;
41
- /**
42
- * Get existing execution directory (for reading)
43
- */
44
- private findExecutionDir;
45
- /**
46
- * Start logging for an execution
47
- */
48
- startExecution(execution: AgentExecution, workflowId?: string): Promise<void>;
49
- /**
50
- * Append a log entry
51
- */
52
- appendLog(executionId: string, entry: ExecutionLogEntry): Promise<void>;
53
- /**
54
- * Log a simple message
55
- */
56
- logMessage(executionId: string, message: string, level?: ExecutionLogEntry['level'], data?: Record<string, unknown>): Promise<void>;
57
- /**
58
- * Complete execution and update metadata
59
- */
60
- completeExecution(executionId: string, status: AgentExecution['status'], error?: string): Promise<void>;
61
- /**
62
- * Read execution logs
63
- */
64
- readExecutionLogs(executionId: string): Promise<{
65
- metadata: ExecutionMetadata | null;
66
- logs: ExecutionLogEntry[];
67
- }>;
68
- /**
69
- * List all executions with metadata
70
- */
71
- listExecutions(): Promise<ExecutionMetadata[]>;
72
- /**
73
- * Clean up old execution logs
74
- */
75
- cleanupOldLogs(maxAgeDays?: number): Promise<number>;
76
- /**
77
- * Remove execution logs for a specific task
78
- */
79
- removeExecutionsByTask(taskId: string): Promise<number>;
80
- /**
81
- * Get execution log statistics
82
- */
83
- getStats(): Promise<{
84
- total: number;
85
- byStatus: Record<string, number>;
86
- totalLogFiles: number;
87
- oldestExecution?: string;
88
- newestExecution?: string;
89
- }>;
90
- }
@@ -1,426 +0,0 @@
1
- import { promises as fs } from 'fs';
2
- import path from 'path';
3
- import { log } from '../lib/logger.js';
4
- import { DatabaseService } from './database-service.js';
5
- import { getVibeDir } from '../lib/server/project-root.js';
6
- export class ExecutionLogPersistence {
7
- constructor() {
8
- this.dataDir = getVibeDir();
9
- this.logsDir = path.join(this.dataDir, '.local/execution-logs');
10
- this.indexDb = new DatabaseService(path.join(this.logsDir, 'index.json'));
11
- }
12
- /**
13
- * Ensure logs directory exists
14
- */
15
- async ensureLogsDir() {
16
- try {
17
- await fs.access(this.logsDir);
18
- }
19
- catch {
20
- await fs.mkdir(this.logsDir, { recursive: true });
21
- }
22
- }
23
- /**
24
- * Get execution log directory path, grouped by task ID
25
- * .vibeman/.local/execution-logs/{taskId}/{executionId-YYYYMMDD_HHMMSS}/
26
- */
27
- getExecutionDirFor(execution) {
28
- const timestamp = new Date()
29
- .toISOString()
30
- .replace(/[-:]/g, '')
31
- .replace(/\..+/, '')
32
- .replace('T', '_');
33
- const safeTask = String(execution.taskId).replace(/[^\w.-]+/g, '_');
34
- const name = `${execution.id}-${timestamp}`;
35
- return path.join(this.logsDir, safeTask, name);
36
- }
37
- /**
38
- * Get existing execution directory (for reading)
39
- */
40
- async findExecutionDir(executionId) {
41
- try {
42
- await this.ensureLogsDir();
43
- // Prefer index lookup (non-throwing)
44
- const idx = await this.indexDb.get(executionId).catch(() => undefined);
45
- if (idx?.dirPath) {
46
- try {
47
- const stats = await fs.stat(idx.dirPath);
48
- if (stats.isDirectory()) {
49
- return idx.dirPath;
50
- }
51
- log.debug('Removing stale execution index entry (not a directory)', { executionId, dirPath: idx.dirPath }, 'execution-log-persistence:findExecutionDir');
52
- }
53
- catch (error) {
54
- if (error && error.code !== 'ENOENT') {
55
- log.error('Failed to access execution directory from index', error, 'execution-log-persistence:findExecutionDir');
56
- return idx.dirPath;
57
- }
58
- log.debug('Removing stale execution index entry (missing directory)', { executionId, dirPath: idx.dirPath }, 'execution-log-persistence:findExecutionDir');
59
- }
60
- await this.indexDb.delete(executionId).catch((deleteError) => {
61
- log.error('Failed to delete stale execution index entry', deleteError, 'execution-log-persistence:findExecutionDir');
62
- });
63
- }
64
- // Walk task directories
65
- const taskDirs = await fs.readdir(this.logsDir, { withFileTypes: true });
66
- for (const taskEntry of taskDirs) {
67
- if (!taskEntry.isDirectory())
68
- continue;
69
- const taskPath = path.join(this.logsDir, taskEntry.name);
70
- const execDirs = await fs.readdir(taskPath, { withFileTypes: true });
71
- for (const ed of execDirs) {
72
- if (ed.isDirectory() && ed.name.includes(executionId)) {
73
- return path.join(taskPath, ed.name);
74
- }
75
- }
76
- }
77
- }
78
- catch (error) {
79
- log.error('Failed to find execution directory', error, 'execution-log-persistence:findExecutionDir');
80
- }
81
- return null;
82
- }
83
- /**
84
- * Start logging for an execution
85
- */
86
- async startExecution(execution, workflowId) {
87
- try {
88
- await this.ensureLogsDir();
89
- const executionDir = this.getExecutionDirFor(execution);
90
- await fs.mkdir(executionDir, { recursive: true });
91
- // Save metadata
92
- const metadata = {
93
- executionId: execution.id,
94
- taskId: execution.taskId,
95
- workflowId,
96
- startTime: execution.startTime,
97
- status: execution.status,
98
- worktreePath: execution.worktree?.path,
99
- };
100
- await fs.writeFile(path.join(executionDir, 'metadata.json'), JSON.stringify(metadata, null, 2));
101
- // Update index (best-effort)
102
- try {
103
- await this.indexDb.set(execution.id, {
104
- executionId: execution.id,
105
- taskId: execution.taskId,
106
- workflowId,
107
- status: execution.status,
108
- startTime: execution.startTime,
109
- dirPath: executionDir,
110
- });
111
- }
112
- catch (error) {
113
- log.error('Failed to update execution index on start', error, 'execution-log-persistence:startExecution');
114
- }
115
- // Update latest symlink per task (best-effort)
116
- try {
117
- const taskDir = path.dirname(executionDir);
118
- const latestLink = path.join(taskDir, 'latest');
119
- // Remove existing symlink if any (ignore if missing)
120
- await fs.unlink(latestLink).catch(() => undefined);
121
- await fs.symlink(executionDir, latestLink);
122
- }
123
- catch (error) {
124
- log.warn('Failed to update latest symlink', error, 'execution-log-persistence:startExecution');
125
- }
126
- // Create initial log file
127
- const initialLog = {
128
- timestamp: new Date().toISOString(),
129
- level: 'info',
130
- message: `Execution started for task ${execution.taskId}`,
131
- data: {
132
- executionId: execution.id,
133
- taskId: execution.taskId,
134
- workingDirectory: execution.workingDirectory,
135
- },
136
- };
137
- await this.appendLog(execution.id, initialLog);
138
- }
139
- catch (error) {
140
- log.error(`Failed to start execution logging for ${execution.id}`, error, 'execution-log-persistence:startExecution');
141
- }
142
- }
143
- /**
144
- * Append a log entry
145
- */
146
- async appendLog(executionId, entry) {
147
- try {
148
- const executionDir = await this.findExecutionDir(executionId);
149
- if (!executionDir)
150
- return;
151
- const logLine = JSON.stringify(entry) + '\n';
152
- await fs.appendFile(path.join(executionDir, 'execution.log'), logLine);
153
- }
154
- catch (error) {
155
- log.error(`Failed to append log for ${executionId}`, error, 'execution-log-persistence:appendLog');
156
- }
157
- }
158
- /**
159
- * Log a simple message
160
- */
161
- async logMessage(executionId, message, level = 'info', data) {
162
- const entry = {
163
- timestamp: new Date().toISOString(),
164
- level,
165
- message,
166
- data,
167
- };
168
- await this.appendLog(executionId, entry);
169
- }
170
- /**
171
- * Complete execution and update metadata
172
- */
173
- async completeExecution(executionId, status, error) {
174
- try {
175
- const executionDir = await this.findExecutionDir(executionId);
176
- if (!executionDir)
177
- return;
178
- // Update metadata
179
- const metadataPath = path.join(executionDir, 'metadata.json');
180
- try {
181
- const existingMetadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
182
- existingMetadata.endTime = new Date().toISOString();
183
- existingMetadata.status = status;
184
- if (error)
185
- existingMetadata.error = error;
186
- await fs.writeFile(metadataPath, JSON.stringify(existingMetadata, null, 2));
187
- }
188
- catch (metaError) {
189
- log.error('Failed to update execution metadata', metaError, 'execution-log-persistence:completeExecution');
190
- }
191
- // Final log entry
192
- const finalLog = {
193
- timestamp: new Date().toISOString(),
194
- level: status === 'completed' ? 'info' : 'error',
195
- message: `Execution ${status}${error ? `: ${error}` : ''}`,
196
- data: { executionId, status, error },
197
- };
198
- await this.appendLog(executionId, finalLog);
199
- // Update index with status/endTime (best-effort)
200
- try {
201
- const metaPath = path.join(executionDir, 'metadata.json');
202
- const md = JSON.parse(await fs.readFile(metaPath, 'utf-8'));
203
- await this.indexDb.set(executionId, {
204
- executionId,
205
- taskId: md.taskId,
206
- workflowId: md.workflowId,
207
- status: md.status,
208
- startTime: md.startTime,
209
- endTime: md.endTime,
210
- dirPath: executionDir,
211
- });
212
- }
213
- catch (error) {
214
- log.error('Failed to update execution index on complete', error, 'execution-log-persistence:completeExecution');
215
- }
216
- }
217
- catch (error) {
218
- log.error(`Failed to complete execution logging for ${executionId}`, error, 'execution-log-persistence:completeExecution');
219
- }
220
- }
221
- /**
222
- * Read execution logs
223
- */
224
- async readExecutionLogs(executionId) {
225
- try {
226
- const executionDir = await this.findExecutionDir(executionId);
227
- if (!executionDir) {
228
- return { metadata: null, logs: [] };
229
- }
230
- // Read metadata
231
- let metadata = null;
232
- try {
233
- const metadataContent = await fs.readFile(path.join(executionDir, 'metadata.json'), 'utf-8');
234
- metadata = JSON.parse(metadataContent);
235
- }
236
- catch (error) {
237
- if (error && error.code === 'ENOENT') {
238
- // Expected when metadata was pruned or not yet written; return null without error noise
239
- log.debug('Execution metadata not found (ENOENT)', { executionId, executionDir }, 'execution-log-persistence:readExecutionLogs');
240
- metadata = null;
241
- }
242
- else {
243
- log.error('Failed to read execution metadata', error, 'execution-log-persistence:readExecutionLogs');
244
- }
245
- }
246
- // Read logs
247
- const logs = [];
248
- try {
249
- const logContent = await fs.readFile(path.join(executionDir, 'execution.log'), 'utf-8');
250
- for (const line of logContent.trim().split('\n')) {
251
- if (line) {
252
- try {
253
- logs.push(JSON.parse(line));
254
- }
255
- catch {
256
- // Skip malformed log lines
257
- }
258
- }
259
- }
260
- }
261
- catch (error) {
262
- if (error && error.code === 'ENOENT') {
263
- // No log file yet; treat as empty without logging error
264
- log.debug('Execution log file not found (ENOENT)', { executionId, executionDir }, 'execution-log-persistence:readExecutionLogs');
265
- }
266
- else {
267
- log.error('Failed to read execution logs', error, 'execution-log-persistence:readExecutionLogs');
268
- }
269
- }
270
- return { metadata, logs };
271
- }
272
- catch (error) {
273
- log.error(`Failed to read execution logs for ${executionId}`, error, 'execution-log-persistence:readExecutionLogs');
274
- return { metadata: null, logs: [] };
275
- }
276
- }
277
- /**
278
- * List all executions with metadata
279
- */
280
- async listExecutions() {
281
- try {
282
- await this.ensureLogsDir();
283
- const executions = [];
284
- // Iterate task directories and collect metadata
285
- const taskDirs = await fs.readdir(this.logsDir, { withFileTypes: true });
286
- for (const taskEntry of taskDirs) {
287
- if (!taskEntry.isDirectory())
288
- continue;
289
- const taskPath = path.join(this.logsDir, taskEntry.name);
290
- let execDirs = [];
291
- try {
292
- execDirs = await fs.readdir(taskPath, { withFileTypes: true });
293
- }
294
- catch {
295
- execDirs = [];
296
- }
297
- for (const ed of execDirs) {
298
- if (!ed.isDirectory())
299
- continue;
300
- try {
301
- const metadataPath = path.join(taskPath, ed.name, 'metadata.json');
302
- const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
303
- executions.push(metadata);
304
- }
305
- catch {
306
- // skip invalid dirs
307
- }
308
- }
309
- }
310
- // Sort by start time (most recent first)
311
- return executions.sort((a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime());
312
- }
313
- catch (error) {
314
- log.error('Failed to list executions', error, 'execution-log-persistence:listExecutions');
315
- return [];
316
- }
317
- }
318
- /**
319
- * Clean up old execution logs
320
- */
321
- async cleanupOldLogs(maxAgeDays = 30) {
322
- try {
323
- const executions = await this.listExecutions();
324
- const cutoffTime = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
325
- let removedCount = 0;
326
- for (const execution of executions) {
327
- const executionTime = new Date(execution.endTime || execution.startTime).getTime();
328
- if (executionTime < cutoffTime &&
329
- ['completed', 'failed', 'cancelled'].includes(execution.status)) {
330
- const executionDir = await this.findExecutionDir(execution.executionId);
331
- if (executionDir) {
332
- try {
333
- await fs.rm(executionDir, { recursive: true, force: true });
334
- removedCount++;
335
- // Remove from index (non-throwing)
336
- await this.indexDb.delete(execution.executionId).catch(() => undefined);
337
- }
338
- catch (error) {
339
- log.error(`Failed to remove execution log directory ${executionDir}`, error, 'execution-log-persistence:cleanupOldLogs');
340
- }
341
- }
342
- }
343
- }
344
- if (removedCount > 0) {
345
- log.warn(`Cleaned up ${removedCount} old execution logs`, { removedCount, maxAgeDays }, 'execution-log-persistence:cleanupOldLogs');
346
- }
347
- return removedCount;
348
- }
349
- catch (error) {
350
- log.error('Failed to cleanup old logs', error, 'execution-log-persistence:cleanupOldLogs');
351
- return 0;
352
- }
353
- }
354
- /**
355
- * Remove execution logs for a specific task
356
- */
357
- async removeExecutionsByTask(taskId) {
358
- try {
359
- const executions = await this.listExecutions();
360
- let removedCount = 0;
361
- for (const execution of executions) {
362
- if (execution.taskId === taskId) {
363
- const executionDir = await this.findExecutionDir(execution.executionId);
364
- if (executionDir) {
365
- try {
366
- await fs.rm(executionDir, { recursive: true, force: true });
367
- removedCount++;
368
- await this.indexDb.delete(execution.executionId).catch(() => undefined);
369
- }
370
- catch (error) {
371
- log.error(`Failed to remove execution log directory ${executionDir}`, error, 'execution-log-persistence:cleanupOldLogs');
372
- }
373
- }
374
- }
375
- }
376
- if (removedCount > 0) {
377
- log.warn(`Removed ${removedCount} execution logs for task ${taskId}`, { removedCount, taskId }, 'execution-log-persistence:removeExecutionsByTask');
378
- }
379
- return removedCount;
380
- }
381
- catch (error) {
382
- log.error(`Failed to remove executions for task ${taskId}`, error, 'execution-log-persistence:removeExecutionsByTask');
383
- return 0;
384
- }
385
- }
386
- /**
387
- * Get execution log statistics
388
- */
389
- async getStats() {
390
- try {
391
- const executions = await this.listExecutions();
392
- const stats = {
393
- total: executions.length,
394
- byStatus: {},
395
- totalLogFiles: executions.length,
396
- oldestExecution: undefined,
397
- newestExecution: undefined,
398
- };
399
- let oldest = null;
400
- let newest = null;
401
- for (const execution of executions) {
402
- // Count by status
403
- stats.byStatus[execution.status] = (stats.byStatus[execution.status] || 0) + 1;
404
- // Find oldest/newest
405
- const startTime = new Date(execution.startTime);
406
- if (!oldest || startTime < oldest) {
407
- oldest = startTime;
408
- stats.oldestExecution = execution.executionId;
409
- }
410
- if (!newest || startTime > newest) {
411
- newest = startTime;
412
- stats.newestExecution = execution.executionId;
413
- }
414
- }
415
- return stats;
416
- }
417
- catch (error) {
418
- log.error('Failed to get execution log stats', error, 'execution-log-persistence:getStats');
419
- return {
420
- total: 0,
421
- byStatus: {},
422
- totalLogFiles: 0,
423
- };
424
- }
425
- }
426
- }