vibeman 0.0.5 → 0.0.6

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 (241) hide show
  1. package/dist/api.js +49 -0
  2. package/dist/cli.js +135 -0
  3. package/dist/ui/index-gnk6rhxs.js +9 -0
  4. package/dist/ui/index.html +10 -0
  5. package/dist/ui/index.js +2 -0
  6. package/package.json +10 -46
  7. package/README.md +0 -12
  8. package/dist/index.js +0 -114
  9. package/dist/runtime/api/.tsbuildinfo +0 -1
  10. package/dist/runtime/api/agent/agent-service.d.ts +0 -229
  11. package/dist/runtime/api/agent/agent-service.js +0 -963
  12. package/dist/runtime/api/agent/ai-providers/amp-cli-provider.d.ts +0 -38
  13. package/dist/runtime/api/agent/ai-providers/amp-cli-provider.js +0 -268
  14. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.d.ts +0 -61
  15. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.js +0 -362
  16. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.d.ts +0 -36
  17. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.js +0 -375
  18. package/dist/runtime/api/agent/ai-providers/gemini-cli-provider.d.ts +0 -24
  19. package/dist/runtime/api/agent/ai-providers/gemini-cli-provider.js +0 -291
  20. package/dist/runtime/api/agent/ai-providers/index.d.ts +0 -9
  21. package/dist/runtime/api/agent/ai-providers/index.js +0 -9
  22. package/dist/runtime/api/agent/ai-providers/types.d.ts +0 -185
  23. package/dist/runtime/api/agent/ai-providers/types.js +0 -5
  24. package/dist/runtime/api/agent/amp-cli-provider.test.d.ts +0 -1
  25. package/dist/runtime/api/agent/amp-cli-provider.test.js +0 -99
  26. package/dist/runtime/api/agent/codex-cli-provider.test.d.ts +0 -1
  27. package/dist/runtime/api/agent/codex-cli-provider.test.js +0 -172
  28. package/dist/runtime/api/agent/core-agent-service.d.ts +0 -119
  29. package/dist/runtime/api/agent/core-agent-service.js +0 -267
  30. package/dist/runtime/api/agent/parsers.d.ts +0 -16
  31. package/dist/runtime/api/agent/parsers.js +0 -308
  32. package/dist/runtime/api/agent/prompt-service.d.ts +0 -30
  33. package/dist/runtime/api/agent/prompt-service.js +0 -452
  34. package/dist/runtime/api/agent/prompt-service.test.d.ts +0 -1
  35. package/dist/runtime/api/agent/prompt-service.test.js +0 -265
  36. package/dist/runtime/api/agent/routing-policy.d.ts +0 -171
  37. package/dist/runtime/api/agent/routing-policy.js +0 -196
  38. package/dist/runtime/api/agent/routing-policy.test.d.ts +0 -1
  39. package/dist/runtime/api/agent/routing-policy.test.js +0 -63
  40. package/dist/runtime/api/api/router-helpers.d.ts +0 -32
  41. package/dist/runtime/api/api/router-helpers.js +0 -31
  42. package/dist/runtime/api/api/routers/ai.d.ts +0 -200
  43. package/dist/runtime/api/api/routers/ai.js +0 -396
  44. package/dist/runtime/api/api/routers/executions.d.ts +0 -93
  45. package/dist/runtime/api/api/routers/executions.js +0 -94
  46. package/dist/runtime/api/api/routers/git.d.ts +0 -45
  47. package/dist/runtime/api/api/routers/git.js +0 -35
  48. package/dist/runtime/api/api/routers/provider-config.d.ts +0 -199
  49. package/dist/runtime/api/api/routers/provider-config.js +0 -252
  50. package/dist/runtime/api/api/routers/settings.d.ts +0 -158
  51. package/dist/runtime/api/api/routers/settings.js +0 -129
  52. package/dist/runtime/api/api/routers/tasks.d.ts +0 -141
  53. package/dist/runtime/api/api/routers/tasks.js +0 -238
  54. package/dist/runtime/api/api/routers/workflows.d.ts +0 -275
  55. package/dist/runtime/api/api/routers/workflows.js +0 -311
  56. package/dist/runtime/api/api/routers/worktrees.d.ts +0 -101
  57. package/dist/runtime/api/api/routers/worktrees.js +0 -80
  58. package/dist/runtime/api/api/trpc.d.ts +0 -118
  59. package/dist/runtime/api/api/trpc.js +0 -34
  60. package/dist/runtime/api/index.d.ts +0 -9
  61. package/dist/runtime/api/index.js +0 -117
  62. package/dist/runtime/api/lib/id-generator.d.ts +0 -70
  63. package/dist/runtime/api/lib/id-generator.js +0 -123
  64. package/dist/runtime/api/lib/local-config.d.ts +0 -335
  65. package/dist/runtime/api/lib/local-config.js +0 -304
  66. package/dist/runtime/api/lib/logger.d.ts +0 -11
  67. package/dist/runtime/api/lib/logger.js +0 -188
  68. package/dist/runtime/api/lib/provider-detection.d.ts +0 -61
  69. package/dist/runtime/api/lib/provider-detection.js +0 -326
  70. package/dist/runtime/api/lib/server/agent-service-singleton.d.ts +0 -6
  71. package/dist/runtime/api/lib/server/agent-service-singleton.js +0 -27
  72. package/dist/runtime/api/lib/server/bootstrap.d.ts +0 -38
  73. package/dist/runtime/api/lib/server/bootstrap.js +0 -197
  74. package/dist/runtime/api/lib/server/git-service-singleton.d.ts +0 -6
  75. package/dist/runtime/api/lib/server/git-service-singleton.js +0 -47
  76. package/dist/runtime/api/lib/server/project-root.d.ts +0 -2
  77. package/dist/runtime/api/lib/server/project-root.js +0 -61
  78. package/dist/runtime/api/lib/server/task-service-singleton.d.ts +0 -7
  79. package/dist/runtime/api/lib/server/task-service-singleton.js +0 -58
  80. package/dist/runtime/api/lib/server/vibeman-info.d.ts +0 -5
  81. package/dist/runtime/api/lib/server/vibeman-info.js +0 -85
  82. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.d.ts +0 -7
  83. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.js +0 -57
  84. package/dist/runtime/api/lib/trpc/server.d.ts +0 -965
  85. package/dist/runtime/api/lib/trpc/server.js +0 -11
  86. package/dist/runtime/api/lib/trpc/ws-server.d.ts +0 -8
  87. package/dist/runtime/api/lib/trpc/ws-server.js +0 -33
  88. package/dist/runtime/api/persistence/database-service.d.ts +0 -14
  89. package/dist/runtime/api/persistence/database-service.js +0 -74
  90. package/dist/runtime/api/persistence/execution-log-persistence.d.ts +0 -90
  91. package/dist/runtime/api/persistence/execution-log-persistence.js +0 -426
  92. package/dist/runtime/api/persistence/execution-log-persistence.test.d.ts +0 -1
  93. package/dist/runtime/api/persistence/execution-log-persistence.test.js +0 -170
  94. package/dist/runtime/api/router.d.ts +0 -968
  95. package/dist/runtime/api/router.js +0 -34
  96. package/dist/runtime/api/settings-service.d.ts +0 -110
  97. package/dist/runtime/api/settings-service.js +0 -678
  98. package/dist/runtime/api/tasks/file-watcher.d.ts +0 -23
  99. package/dist/runtime/api/tasks/file-watcher.js +0 -88
  100. package/dist/runtime/api/tasks/task-file-parser.d.ts +0 -14
  101. package/dist/runtime/api/tasks/task-file-parser.js +0 -180
  102. package/dist/runtime/api/tasks/task-service.d.ts +0 -36
  103. package/dist/runtime/api/tasks/task-service.js +0 -173
  104. package/dist/runtime/api/tasks/task-updater.d.ts +0 -62
  105. package/dist/runtime/api/tasks/task-updater.js +0 -260
  106. package/dist/runtime/api/tasks/task-updater.test.d.ts +0 -1
  107. package/dist/runtime/api/tasks/task-updater.test.js +0 -303
  108. package/dist/runtime/api/types/index.d.ts +0 -186
  109. package/dist/runtime/api/types/index.js +0 -1
  110. package/dist/runtime/api/types/settings.d.ts +0 -105
  111. package/dist/runtime/api/types/settings.js +0 -2
  112. package/dist/runtime/api/types.d.ts +0 -2
  113. package/dist/runtime/api/types.js +0 -1
  114. package/dist/runtime/api/utils/env.d.ts +0 -6
  115. package/dist/runtime/api/utils/env.js +0 -12
  116. package/dist/runtime/api/utils/stripNextEnv.d.ts +0 -7
  117. package/dist/runtime/api/utils/stripNextEnv.js +0 -22
  118. package/dist/runtime/api/utils/title-slug.d.ts +0 -6
  119. package/dist/runtime/api/utils/title-slug.js +0 -77
  120. package/dist/runtime/api/utils/url.d.ts +0 -2
  121. package/dist/runtime/api/utils/url.js +0 -19
  122. package/dist/runtime/api/vcs/git-history-service.d.ts +0 -57
  123. package/dist/runtime/api/vcs/git-history-service.js +0 -228
  124. package/dist/runtime/api/vcs/git-service.d.ts +0 -136
  125. package/dist/runtime/api/vcs/git-service.js +0 -307
  126. package/dist/runtime/api/vcs/worktree-service.d.ts +0 -93
  127. package/dist/runtime/api/vcs/worktree-service.js +0 -518
  128. package/dist/runtime/api/vcs/worktree-service.test.d.ts +0 -1
  129. package/dist/runtime/api/vcs/worktree-service.test.js +0 -20
  130. package/dist/runtime/api/workflows/quality-pipeline.d.ts +0 -58
  131. package/dist/runtime/api/workflows/quality-pipeline.js +0 -401
  132. package/dist/runtime/api/workflows/vibing-orchestrator.d.ts +0 -406
  133. package/dist/runtime/api/workflows/vibing-orchestrator.js +0 -2462
  134. package/dist/runtime/api/workflows/workflow-effects.d.ts +0 -45
  135. package/dist/runtime/api/workflows/workflow-effects.js +0 -49
  136. package/dist/runtime/api/workflows/workflow-reconciler.d.ts +0 -65
  137. package/dist/runtime/api/workflows/workflow-reconciler.js +0 -226
  138. package/dist/runtime/api/workflows/workflow-reducer.d.ts +0 -26
  139. package/dist/runtime/api/workflows/workflow-reducer.js +0 -288
  140. package/dist/runtime/api/workflows/workflow-reducer.test.d.ts +0 -1
  141. package/dist/runtime/api/workflows/workflow-reducer.test.js +0 -247
  142. package/dist/runtime/api/workflows/workflow-schema.d.ts +0 -546
  143. package/dist/runtime/api/workflows/workflow-schema.js +0 -256
  144. package/dist/runtime/web/.next/BUILD_ID +0 -1
  145. package/dist/runtime/web/.next/app-build-manifest.json +0 -66
  146. package/dist/runtime/web/.next/app-path-routes-manifest.json +0 -8
  147. package/dist/runtime/web/.next/build-manifest.json +0 -33
  148. package/dist/runtime/web/.next/package.json +0 -1
  149. package/dist/runtime/web/.next/prerender-manifest.json +0 -61
  150. package/dist/runtime/web/.next/react-loadable-manifest.json +0 -8
  151. package/dist/runtime/web/.next/required-server-files.json +0 -334
  152. package/dist/runtime/web/.next/routes-manifest.json +0 -70
  153. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js +0 -1
  154. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js.nft.json +0 -1
  155. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route_client-reference-manifest.js +0 -1
  156. package/dist/runtime/web/.next/server/app/_not-found/page.js +0 -2
  157. package/dist/runtime/web/.next/server/app/_not-found/page.js.nft.json +0 -1
  158. package/dist/runtime/web/.next/server/app/_not-found/page_client-reference-manifest.js +0 -1
  159. package/dist/runtime/web/.next/server/app/_not-found.html +0 -7
  160. package/dist/runtime/web/.next/server/app/_not-found.meta +0 -8
  161. package/dist/runtime/web/.next/server/app/_not-found.rsc +0 -22
  162. package/dist/runtime/web/.next/server/app/api/health/route.js +0 -1
  163. package/dist/runtime/web/.next/server/app/api/health/route.js.nft.json +0 -1
  164. package/dist/runtime/web/.next/server/app/api/health/route_client-reference-manifest.js +0 -1
  165. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js +0 -1
  166. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js.nft.json +0 -1
  167. package/dist/runtime/web/.next/server/app/api/images/[...path]/route_client-reference-manifest.js +0 -1
  168. package/dist/runtime/web/.next/server/app/api/upload/route.js +0 -1
  169. package/dist/runtime/web/.next/server/app/api/upload/route.js.nft.json +0 -1
  170. package/dist/runtime/web/.next/server/app/api/upload/route_client-reference-manifest.js +0 -1
  171. package/dist/runtime/web/.next/server/app/index.html +0 -7
  172. package/dist/runtime/web/.next/server/app/index.meta +0 -7
  173. package/dist/runtime/web/.next/server/app/index.rsc +0 -27
  174. package/dist/runtime/web/.next/server/app/page.js +0 -112
  175. package/dist/runtime/web/.next/server/app/page.js.nft.json +0 -1
  176. package/dist/runtime/web/.next/server/app/page_client-reference-manifest.js +0 -1
  177. package/dist/runtime/web/.next/server/app-paths-manifest.json +0 -8
  178. package/dist/runtime/web/.next/server/chunks/210.js +0 -1
  179. package/dist/runtime/web/.next/server/chunks/291.js +0 -18
  180. package/dist/runtime/web/.next/server/chunks/552.js +0 -22
  181. package/dist/runtime/web/.next/server/chunks/780.js +0 -1
  182. package/dist/runtime/web/.next/server/chunks/905.js +0 -6
  183. package/dist/runtime/web/.next/server/chunks/98.js +0 -1
  184. package/dist/runtime/web/.next/server/functions-config-manifest.json +0 -4
  185. package/dist/runtime/web/.next/server/middleware-build-manifest.js +0 -1
  186. package/dist/runtime/web/.next/server/middleware-manifest.json +0 -6
  187. package/dist/runtime/web/.next/server/middleware-react-loadable-manifest.js +0 -1
  188. package/dist/runtime/web/.next/server/next-font-manifest.js +0 -1
  189. package/dist/runtime/web/.next/server/next-font-manifest.json +0 -1
  190. package/dist/runtime/web/.next/server/pages/404.html +0 -7
  191. package/dist/runtime/web/.next/server/pages/500.html +0 -1
  192. package/dist/runtime/web/.next/server/pages/_app.js +0 -1
  193. package/dist/runtime/web/.next/server/pages/_app.js.nft.json +0 -1
  194. package/dist/runtime/web/.next/server/pages/_document.js +0 -1
  195. package/dist/runtime/web/.next/server/pages/_document.js.nft.json +0 -1
  196. package/dist/runtime/web/.next/server/pages/_error.js +0 -19
  197. package/dist/runtime/web/.next/server/pages/_error.js.nft.json +0 -1
  198. package/dist/runtime/web/.next/server/pages-manifest.json +0 -6
  199. package/dist/runtime/web/.next/server/server-reference-manifest.js +0 -1
  200. package/dist/runtime/web/.next/server/server-reference-manifest.json +0 -1
  201. package/dist/runtime/web/.next/server/webpack-runtime.js +0 -1
  202. package/dist/runtime/web/.next/static/LJFZk_8tvKFN_Ee4HqUuM/_buildManifest.js +0 -1
  203. package/dist/runtime/web/.next/static/LJFZk_8tvKFN_Ee4HqUuM/_ssgManifest.js +0 -1
  204. package/dist/runtime/web/.next/static/chunks/05c91ade-7d09b2b280adffd1.js +0 -1
  205. package/dist/runtime/web/.next/static/chunks/201-51bef3fa8c832e2e.js +0 -1
  206. package/dist/runtime/web/.next/static/chunks/524-89747ed9b0294f8a.js +0 -1
  207. package/dist/runtime/web/.next/static/chunks/554-8bec6e9cca6acc67.js +0 -1
  208. package/dist/runtime/web/.next/static/chunks/764.86e9503a69d45a85.js +0 -1
  209. package/dist/runtime/web/.next/static/chunks/7ab4dc20-239138e0ae7af24a.js +0 -1
  210. package/dist/runtime/web/.next/static/chunks/905-342391e3d3a3678f.js +0 -20
  211. package/dist/runtime/web/.next/static/chunks/a8a5ce16-4edea7df2d9b544a.js +0 -79
  212. package/dist/runtime/web/.next/static/chunks/ad74d572-4c1b162e2c15acaa.js +0 -1
  213. package/dist/runtime/web/.next/static/chunks/app/.vibeman/assets/images/[...path]/route-7b752a8641f96c1f.js +0 -1
  214. package/dist/runtime/web/.next/static/chunks/app/_not-found/page-34e66b251c2b5044.js +0 -1
  215. package/dist/runtime/web/.next/static/chunks/app/api/health/route-7b752a8641f96c1f.js +0 -1
  216. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-7b752a8641f96c1f.js +0 -1
  217. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-7b752a8641f96c1f.js +0 -1
  218. package/dist/runtime/web/.next/static/chunks/app/layout-df9ac93cb02b2385.js +0 -1
  219. package/dist/runtime/web/.next/static/chunks/app/page-6610743f7de5f92a.js +0 -1
  220. package/dist/runtime/web/.next/static/chunks/c25e0690-e9b798b8de667da1.js +0 -1
  221. package/dist/runtime/web/.next/static/chunks/framework-57157ec4d37f64aa.js +0 -1
  222. package/dist/runtime/web/.next/static/chunks/main-app-156cc0c60371bd78.js +0 -1
  223. package/dist/runtime/web/.next/static/chunks/main-df25d367c47b1fec.js +0 -1
  224. package/dist/runtime/web/.next/static/chunks/pages/_app-9f629a5e1131d19f.js +0 -1
  225. package/dist/runtime/web/.next/static/chunks/pages/_error-9238238274c7efcd.js +0 -1
  226. package/dist/runtime/web/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  227. package/dist/runtime/web/.next/static/chunks/webpack-cd50e39b423d1808.js +0 -1
  228. package/dist/runtime/web/.next/static/css/2728291c68f99cb1.css +0 -3
  229. package/dist/runtime/web/.next/static/css/4fbf378a264bd4ea.css +0 -1
  230. package/dist/runtime/web/.next/static/css/521bd69cc298cd1a.css +0 -1
  231. package/dist/runtime/web/.next/static/css/537e22821e101b87.css +0 -1
  232. package/dist/runtime/web/.next/static/media/19cfc7226ec3afaa-s.woff2 +0 -0
  233. package/dist/runtime/web/.next/static/media/21350d82a1f187e9-s.woff2 +0 -0
  234. package/dist/runtime/web/.next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
  235. package/dist/runtime/web/.next/static/media/ba9851c3c22cd980-s.woff2 +0 -0
  236. package/dist/runtime/web/.next/static/media/c5fe6dc8356a8c31-s.woff2 +0 -0
  237. package/dist/runtime/web/.next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  238. package/dist/runtime/web/.next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
  239. package/dist/runtime/web/package.json +0 -65
  240. package/dist/runtime/web/server.js +0 -44
  241. 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
- }