vibeman 0.0.3 → 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 (231) 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 -80
  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 -225
  11. package/dist/runtime/api/agent/agent-service.js +0 -904
  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 -347
  16. package/dist/runtime/api/agent/ai-providers/index.d.ts +0 -9
  17. package/dist/runtime/api/agent/ai-providers/index.js +0 -7
  18. package/dist/runtime/api/agent/ai-providers/types.d.ts +0 -182
  19. package/dist/runtime/api/agent/ai-providers/types.js +0 -5
  20. package/dist/runtime/api/agent/codex-cli-provider.test.d.ts +0 -1
  21. package/dist/runtime/api/agent/codex-cli-provider.test.js +0 -170
  22. package/dist/runtime/api/agent/core-agent-service.d.ts +0 -119
  23. package/dist/runtime/api/agent/core-agent-service.js +0 -267
  24. package/dist/runtime/api/agent/parsers.d.ts +0 -16
  25. package/dist/runtime/api/agent/parsers.js +0 -308
  26. package/dist/runtime/api/agent/prompt-service.d.ts +0 -30
  27. package/dist/runtime/api/agent/prompt-service.js +0 -449
  28. package/dist/runtime/api/agent/prompt-service.test.d.ts +0 -1
  29. package/dist/runtime/api/agent/prompt-service.test.js +0 -230
  30. package/dist/runtime/api/agent/routing-policy.d.ts +0 -171
  31. package/dist/runtime/api/agent/routing-policy.js +0 -196
  32. package/dist/runtime/api/agent/routing-policy.test.d.ts +0 -1
  33. package/dist/runtime/api/agent/routing-policy.test.js +0 -63
  34. package/dist/runtime/api/api/router-helpers.d.ts +0 -32
  35. package/dist/runtime/api/api/router-helpers.js +0 -31
  36. package/dist/runtime/api/api/routers/ai.d.ts +0 -200
  37. package/dist/runtime/api/api/routers/ai.js +0 -396
  38. package/dist/runtime/api/api/routers/executions.d.ts +0 -98
  39. package/dist/runtime/api/api/routers/executions.js +0 -94
  40. package/dist/runtime/api/api/routers/git.d.ts +0 -45
  41. package/dist/runtime/api/api/routers/git.js +0 -35
  42. package/dist/runtime/api/api/routers/provider-config.d.ts +0 -165
  43. package/dist/runtime/api/api/routers/provider-config.js +0 -252
  44. package/dist/runtime/api/api/routers/settings.d.ts +0 -139
  45. package/dist/runtime/api/api/routers/settings.js +0 -113
  46. package/dist/runtime/api/api/routers/tasks.d.ts +0 -141
  47. package/dist/runtime/api/api/routers/tasks.js +0 -238
  48. package/dist/runtime/api/api/routers/workflows.d.ts +0 -275
  49. package/dist/runtime/api/api/routers/workflows.js +0 -311
  50. package/dist/runtime/api/api/routers/worktrees.d.ts +0 -101
  51. package/dist/runtime/api/api/routers/worktrees.js +0 -80
  52. package/dist/runtime/api/api/trpc.d.ts +0 -118
  53. package/dist/runtime/api/api/trpc.js +0 -34
  54. package/dist/runtime/api/index.d.ts +0 -9
  55. package/dist/runtime/api/index.js +0 -117
  56. package/dist/runtime/api/lib/id-generator.d.ts +0 -70
  57. package/dist/runtime/api/lib/id-generator.js +0 -123
  58. package/dist/runtime/api/lib/local-config.d.ts +0 -245
  59. package/dist/runtime/api/lib/local-config.js +0 -288
  60. package/dist/runtime/api/lib/logger.d.ts +0 -11
  61. package/dist/runtime/api/lib/logger.js +0 -188
  62. package/dist/runtime/api/lib/provider-detection.d.ts +0 -59
  63. package/dist/runtime/api/lib/provider-detection.js +0 -244
  64. package/dist/runtime/api/lib/server/agent-service-singleton.d.ts +0 -6
  65. package/dist/runtime/api/lib/server/agent-service-singleton.js +0 -27
  66. package/dist/runtime/api/lib/server/bootstrap.d.ts +0 -38
  67. package/dist/runtime/api/lib/server/bootstrap.js +0 -197
  68. package/dist/runtime/api/lib/server/git-service-singleton.d.ts +0 -6
  69. package/dist/runtime/api/lib/server/git-service-singleton.js +0 -47
  70. package/dist/runtime/api/lib/server/project-root.d.ts +0 -2
  71. package/dist/runtime/api/lib/server/project-root.js +0 -61
  72. package/dist/runtime/api/lib/server/task-service-singleton.d.ts +0 -7
  73. package/dist/runtime/api/lib/server/task-service-singleton.js +0 -58
  74. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.d.ts +0 -7
  75. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.js +0 -57
  76. package/dist/runtime/api/lib/trpc/client.d.ts +0 -1
  77. package/dist/runtime/api/lib/trpc/client.js +0 -5
  78. package/dist/runtime/api/lib/trpc/server.d.ts +0 -935
  79. package/dist/runtime/api/lib/trpc/server.js +0 -11
  80. package/dist/runtime/api/lib/trpc/ws-server.d.ts +0 -8
  81. package/dist/runtime/api/lib/trpc/ws-server.js +0 -33
  82. package/dist/runtime/api/persistence/database-service.d.ts +0 -14
  83. package/dist/runtime/api/persistence/database-service.js +0 -74
  84. package/dist/runtime/api/persistence/execution-log-persistence.d.ts +0 -90
  85. package/dist/runtime/api/persistence/execution-log-persistence.js +0 -410
  86. package/dist/runtime/api/persistence/execution-log-persistence.test.d.ts +0 -1
  87. package/dist/runtime/api/persistence/execution-log-persistence.test.js +0 -170
  88. package/dist/runtime/api/router.d.ts +0 -938
  89. package/dist/runtime/api/router.js +0 -34
  90. package/dist/runtime/api/settings-service.d.ts +0 -110
  91. package/dist/runtime/api/settings-service.js +0 -661
  92. package/dist/runtime/api/tasks/file-watcher.d.ts +0 -23
  93. package/dist/runtime/api/tasks/file-watcher.js +0 -88
  94. package/dist/runtime/api/tasks/task-file-parser.d.ts +0 -13
  95. package/dist/runtime/api/tasks/task-file-parser.js +0 -161
  96. package/dist/runtime/api/tasks/task-service.d.ts +0 -36
  97. package/dist/runtime/api/tasks/task-service.js +0 -173
  98. package/dist/runtime/api/types/index.d.ts +0 -186
  99. package/dist/runtime/api/types/index.js +0 -1
  100. package/dist/runtime/api/types/settings.d.ts +0 -94
  101. package/dist/runtime/api/types/settings.js +0 -2
  102. package/dist/runtime/api/types.d.ts +0 -2
  103. package/dist/runtime/api/types.js +0 -1
  104. package/dist/runtime/api/utils/env.d.ts +0 -6
  105. package/dist/runtime/api/utils/env.js +0 -12
  106. package/dist/runtime/api/utils/stripNextEnv.d.ts +0 -7
  107. package/dist/runtime/api/utils/stripNextEnv.js +0 -22
  108. package/dist/runtime/api/utils/title-slug.d.ts +0 -6
  109. package/dist/runtime/api/utils/title-slug.js +0 -77
  110. package/dist/runtime/api/utils/url.d.ts +0 -2
  111. package/dist/runtime/api/utils/url.js +0 -19
  112. package/dist/runtime/api/vcs/git-history-service.d.ts +0 -57
  113. package/dist/runtime/api/vcs/git-history-service.js +0 -228
  114. package/dist/runtime/api/vcs/git-service.d.ts +0 -127
  115. package/dist/runtime/api/vcs/git-service.js +0 -284
  116. package/dist/runtime/api/vcs/worktree-service.d.ts +0 -93
  117. package/dist/runtime/api/vcs/worktree-service.js +0 -506
  118. package/dist/runtime/api/vcs/worktree-service.test.d.ts +0 -1
  119. package/dist/runtime/api/vcs/worktree-service.test.js +0 -20
  120. package/dist/runtime/api/workflows/quality-pipeline.d.ts +0 -58
  121. package/dist/runtime/api/workflows/quality-pipeline.js +0 -400
  122. package/dist/runtime/api/workflows/vibing-orchestrator.d.ts +0 -318
  123. package/dist/runtime/api/workflows/vibing-orchestrator.js +0 -1891
  124. package/dist/runtime/web/.next/BUILD_ID +0 -1
  125. package/dist/runtime/web/.next/app-build-manifest.json +0 -66
  126. package/dist/runtime/web/.next/app-path-routes-manifest.json +0 -8
  127. package/dist/runtime/web/.next/build-manifest.json +0 -33
  128. package/dist/runtime/web/.next/package.json +0 -1
  129. package/dist/runtime/web/.next/prerender-manifest.json +0 -61
  130. package/dist/runtime/web/.next/react-loadable-manifest.json +0 -39
  131. package/dist/runtime/web/.next/required-server-files.json +0 -334
  132. package/dist/runtime/web/.next/routes-manifest.json +0 -70
  133. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js +0 -1
  134. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js.nft.json +0 -1
  135. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route_client-reference-manifest.js +0 -1
  136. package/dist/runtime/web/.next/server/app/_not-found/page.js +0 -2
  137. package/dist/runtime/web/.next/server/app/_not-found/page.js.nft.json +0 -1
  138. package/dist/runtime/web/.next/server/app/_not-found/page_client-reference-manifest.js +0 -1
  139. package/dist/runtime/web/.next/server/app/_not-found.html +0 -7
  140. package/dist/runtime/web/.next/server/app/_not-found.meta +0 -8
  141. package/dist/runtime/web/.next/server/app/_not-found.rsc +0 -22
  142. package/dist/runtime/web/.next/server/app/api/health/route.js +0 -1
  143. package/dist/runtime/web/.next/server/app/api/health/route.js.nft.json +0 -1
  144. package/dist/runtime/web/.next/server/app/api/health/route_client-reference-manifest.js +0 -1
  145. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js +0 -1
  146. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js.nft.json +0 -1
  147. package/dist/runtime/web/.next/server/app/api/images/[...path]/route_client-reference-manifest.js +0 -1
  148. package/dist/runtime/web/.next/server/app/api/upload/route.js +0 -1
  149. package/dist/runtime/web/.next/server/app/api/upload/route.js.nft.json +0 -1
  150. package/dist/runtime/web/.next/server/app/api/upload/route_client-reference-manifest.js +0 -1
  151. package/dist/runtime/web/.next/server/app/index.html +0 -7
  152. package/dist/runtime/web/.next/server/app/index.meta +0 -7
  153. package/dist/runtime/web/.next/server/app/index.rsc +0 -27
  154. package/dist/runtime/web/.next/server/app/page.js +0 -147
  155. package/dist/runtime/web/.next/server/app/page.js.nft.json +0 -1
  156. package/dist/runtime/web/.next/server/app/page_client-reference-manifest.js +0 -1
  157. package/dist/runtime/web/.next/server/app-paths-manifest.json +0 -8
  158. package/dist/runtime/web/.next/server/chunks/217.js +0 -1
  159. package/dist/runtime/web/.next/server/chunks/383.js +0 -6
  160. package/dist/runtime/web/.next/server/chunks/458.js +0 -1
  161. package/dist/runtime/web/.next/server/chunks/576.js +0 -18
  162. package/dist/runtime/web/.next/server/chunks/635.js +0 -22
  163. package/dist/runtime/web/.next/server/chunks/761.js +0 -1
  164. package/dist/runtime/web/.next/server/chunks/777.js +0 -3
  165. package/dist/runtime/web/.next/server/chunks/825.js +0 -1
  166. package/dist/runtime/web/.next/server/chunks/838.js +0 -1
  167. package/dist/runtime/web/.next/server/chunks/973.js +0 -15
  168. package/dist/runtime/web/.next/server/functions-config-manifest.json +0 -4
  169. package/dist/runtime/web/.next/server/middleware-build-manifest.js +0 -1
  170. package/dist/runtime/web/.next/server/middleware-manifest.json +0 -6
  171. package/dist/runtime/web/.next/server/middleware-react-loadable-manifest.js +0 -1
  172. package/dist/runtime/web/.next/server/next-font-manifest.js +0 -1
  173. package/dist/runtime/web/.next/server/next-font-manifest.json +0 -1
  174. package/dist/runtime/web/.next/server/pages/404.html +0 -7
  175. package/dist/runtime/web/.next/server/pages/500.html +0 -1
  176. package/dist/runtime/web/.next/server/pages/_app.js +0 -1
  177. package/dist/runtime/web/.next/server/pages/_app.js.nft.json +0 -1
  178. package/dist/runtime/web/.next/server/pages/_document.js +0 -1
  179. package/dist/runtime/web/.next/server/pages/_document.js.nft.json +0 -1
  180. package/dist/runtime/web/.next/server/pages/_error.js +0 -19
  181. package/dist/runtime/web/.next/server/pages/_error.js.nft.json +0 -1
  182. package/dist/runtime/web/.next/server/pages-manifest.json +0 -6
  183. package/dist/runtime/web/.next/server/server-reference-manifest.js +0 -1
  184. package/dist/runtime/web/.next/server/server-reference-manifest.json +0 -1
  185. package/dist/runtime/web/.next/server/webpack-runtime.js +0 -1
  186. package/dist/runtime/web/.next/static/5_15u1WQCxN1_eHZpldCv/_buildManifest.js +0 -1
  187. package/dist/runtime/web/.next/static/5_15u1WQCxN1_eHZpldCv/_ssgManifest.js +0 -1
  188. package/dist/runtime/web/.next/static/chunks/18-15c10d3288afef2e.js +0 -1
  189. package/dist/runtime/web/.next/static/chunks/1c0ca389.537bbe362e3ffbd9.js +0 -3
  190. package/dist/runtime/web/.next/static/chunks/22747d63-ad5da0c19f4cfe41.js +0 -71
  191. package/dist/runtime/web/.next/static/chunks/355.056c2645878a799a.js +0 -1
  192. package/dist/runtime/web/.next/static/chunks/420.a5ccf151c9e2b2f1.js +0 -1
  193. package/dist/runtime/web/.next/static/chunks/439.1be0c6242fd248d5.js +0 -15
  194. package/dist/runtime/web/.next/static/chunks/440.c52e7c0f797e22b2.js +0 -1
  195. package/dist/runtime/web/.next/static/chunks/575-e2478287c27da87b.js +0 -1
  196. package/dist/runtime/web/.next/static/chunks/691.920d88c115087314.js +0 -1
  197. package/dist/runtime/web/.next/static/chunks/765-e838910065b50c3d.js +0 -1
  198. package/dist/runtime/web/.next/static/chunks/823-6f371a6e829adbba.js +0 -63
  199. package/dist/runtime/web/.next/static/chunks/87c73c54-09e1ba5c70e60a51.js +0 -1
  200. package/dist/runtime/web/.next/static/chunks/891cff7f.0f71fc028f87e683.js +0 -1
  201. package/dist/runtime/web/.next/static/chunks/8bb4d8db-3e2aa02b0a2384b9.js +0 -1
  202. package/dist/runtime/web/.next/static/chunks/9af238c7-271a911d4e99ab18.js +0 -1
  203. package/dist/runtime/web/.next/static/chunks/app/.vibeman/assets/images/[...path]/route-751c9265a65409e5.js +0 -1
  204. package/dist/runtime/web/.next/static/chunks/app/_not-found/page-1cb74d1cba27d0ab.js +0 -1
  205. package/dist/runtime/web/.next/static/chunks/app/api/health/route-751c9265a65409e5.js +0 -1
  206. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-751c9265a65409e5.js +0 -1
  207. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-751c9265a65409e5.js +0 -1
  208. package/dist/runtime/web/.next/static/chunks/app/layout-8435322f09fd0975.js +0 -1
  209. package/dist/runtime/web/.next/static/chunks/app/page-9fe7d75095b4ccec.js +0 -1
  210. package/dist/runtime/web/.next/static/chunks/cac567b0-5b77dd12911823cd.js +0 -1
  211. package/dist/runtime/web/.next/static/chunks/framework-2518f1345b5b2806.js +0 -1
  212. package/dist/runtime/web/.next/static/chunks/main-17665e5e39de9a8a.js +0 -1
  213. package/dist/runtime/web/.next/static/chunks/main-app-c0b0f5ba4f7f9d75.js +0 -1
  214. package/dist/runtime/web/.next/static/chunks/pages/_app-d6f6b3bbc3d81ee1.js +0 -1
  215. package/dist/runtime/web/.next/static/chunks/pages/_error-75a96cf1997cc3b9.js +0 -1
  216. package/dist/runtime/web/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  217. package/dist/runtime/web/.next/static/chunks/webpack-c8de37305b4635cf.js +0 -1
  218. package/dist/runtime/web/.next/static/css/08c950681f1a9a92.css +0 -1
  219. package/dist/runtime/web/.next/static/css/2728291c68f99cb1.css +0 -3
  220. package/dist/runtime/web/.next/static/css/521bd69cc298cd1a.css +0 -1
  221. package/dist/runtime/web/.next/static/css/537e22821e101b87.css +0 -1
  222. package/dist/runtime/web/.next/static/media/19cfc7226ec3afaa-s.woff2 +0 -0
  223. package/dist/runtime/web/.next/static/media/21350d82a1f187e9-s.woff2 +0 -0
  224. package/dist/runtime/web/.next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
  225. package/dist/runtime/web/.next/static/media/ba9851c3c22cd980-s.woff2 +0 -0
  226. package/dist/runtime/web/.next/static/media/c5fe6dc8356a8c31-s.woff2 +0 -0
  227. package/dist/runtime/web/.next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  228. package/dist/runtime/web/.next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
  229. package/dist/runtime/web/package.json +0 -65
  230. package/dist/runtime/web/server.js +0 -44
  231. 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/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,410 +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, '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/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
- return idx.dirPath;
47
- }
48
- // Walk task directories
49
- const taskDirs = await fs.readdir(this.logsDir, { withFileTypes: true });
50
- for (const taskEntry of taskDirs) {
51
- if (!taskEntry.isDirectory())
52
- continue;
53
- const taskPath = path.join(this.logsDir, taskEntry.name);
54
- const execDirs = await fs.readdir(taskPath, { withFileTypes: true });
55
- for (const ed of execDirs) {
56
- if (ed.isDirectory() && ed.name.includes(executionId)) {
57
- return path.join(taskPath, ed.name);
58
- }
59
- }
60
- }
61
- }
62
- catch (error) {
63
- log.error('Failed to find execution directory', error, 'execution-log-persistence:findExecutionDir');
64
- }
65
- return null;
66
- }
67
- /**
68
- * Start logging for an execution
69
- */
70
- async startExecution(execution, workflowId) {
71
- try {
72
- await this.ensureLogsDir();
73
- const executionDir = this.getExecutionDirFor(execution);
74
- await fs.mkdir(executionDir, { recursive: true });
75
- // Save metadata
76
- const metadata = {
77
- executionId: execution.id,
78
- taskId: execution.taskId,
79
- workflowId,
80
- startTime: execution.startTime,
81
- status: execution.status,
82
- worktreePath: execution.worktree?.path,
83
- };
84
- await fs.writeFile(path.join(executionDir, 'metadata.json'), JSON.stringify(metadata, null, 2));
85
- // Update index (best-effort)
86
- try {
87
- await this.indexDb.set(execution.id, {
88
- executionId: execution.id,
89
- taskId: execution.taskId,
90
- workflowId,
91
- status: execution.status,
92
- startTime: execution.startTime,
93
- dirPath: executionDir,
94
- });
95
- }
96
- catch (error) {
97
- log.error('Failed to update execution index on start', error, 'execution-log-persistence:startExecution');
98
- }
99
- // Update latest symlink per task (best-effort)
100
- try {
101
- const taskDir = path.dirname(executionDir);
102
- const latestLink = path.join(taskDir, 'latest');
103
- // Remove existing symlink if any (ignore if missing)
104
- await fs.unlink(latestLink).catch(() => undefined);
105
- await fs.symlink(executionDir, latestLink);
106
- }
107
- catch (error) {
108
- log.warn('Failed to update latest symlink', error, 'execution-log-persistence:startExecution');
109
- }
110
- // Create initial log file
111
- const initialLog = {
112
- timestamp: new Date().toISOString(),
113
- level: 'info',
114
- message: `Execution started for task ${execution.taskId}`,
115
- data: {
116
- executionId: execution.id,
117
- taskId: execution.taskId,
118
- workingDirectory: execution.workingDirectory,
119
- },
120
- };
121
- await this.appendLog(execution.id, initialLog);
122
- }
123
- catch (error) {
124
- log.error(`Failed to start execution logging for ${execution.id}`, error, 'execution-log-persistence:startExecution');
125
- }
126
- }
127
- /**
128
- * Append a log entry
129
- */
130
- async appendLog(executionId, entry) {
131
- try {
132
- const executionDir = await this.findExecutionDir(executionId);
133
- if (!executionDir)
134
- return;
135
- const logLine = JSON.stringify(entry) + '\n';
136
- await fs.appendFile(path.join(executionDir, 'execution.log'), logLine);
137
- }
138
- catch (error) {
139
- log.error(`Failed to append log for ${executionId}`, error, 'execution-log-persistence:appendLog');
140
- }
141
- }
142
- /**
143
- * Log a simple message
144
- */
145
- async logMessage(executionId, message, level = 'info', data) {
146
- const entry = {
147
- timestamp: new Date().toISOString(),
148
- level,
149
- message,
150
- data,
151
- };
152
- await this.appendLog(executionId, entry);
153
- }
154
- /**
155
- * Complete execution and update metadata
156
- */
157
- async completeExecution(executionId, status, error) {
158
- try {
159
- const executionDir = await this.findExecutionDir(executionId);
160
- if (!executionDir)
161
- return;
162
- // Update metadata
163
- const metadataPath = path.join(executionDir, 'metadata.json');
164
- try {
165
- const existingMetadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
166
- existingMetadata.endTime = new Date().toISOString();
167
- existingMetadata.status = status;
168
- if (error)
169
- existingMetadata.error = error;
170
- await fs.writeFile(metadataPath, JSON.stringify(existingMetadata, null, 2));
171
- }
172
- catch (metaError) {
173
- log.error('Failed to update execution metadata', metaError, 'execution-log-persistence:completeExecution');
174
- }
175
- // Final log entry
176
- const finalLog = {
177
- timestamp: new Date().toISOString(),
178
- level: status === 'completed' ? 'info' : 'error',
179
- message: `Execution ${status}${error ? `: ${error}` : ''}`,
180
- data: { executionId, status, error },
181
- };
182
- await this.appendLog(executionId, finalLog);
183
- // Update index with status/endTime (best-effort)
184
- try {
185
- const metaPath = path.join(executionDir, 'metadata.json');
186
- const md = JSON.parse(await fs.readFile(metaPath, 'utf-8'));
187
- await this.indexDb.set(executionId, {
188
- executionId,
189
- taskId: md.taskId,
190
- workflowId: md.workflowId,
191
- status: md.status,
192
- startTime: md.startTime,
193
- endTime: md.endTime,
194
- dirPath: executionDir,
195
- });
196
- }
197
- catch (error) {
198
- log.error('Failed to update execution index on complete', error, 'execution-log-persistence:completeExecution');
199
- }
200
- }
201
- catch (error) {
202
- log.error(`Failed to complete execution logging for ${executionId}`, error, 'execution-log-persistence:completeExecution');
203
- }
204
- }
205
- /**
206
- * Read execution logs
207
- */
208
- async readExecutionLogs(executionId) {
209
- try {
210
- const executionDir = await this.findExecutionDir(executionId);
211
- if (!executionDir) {
212
- return { metadata: null, logs: [] };
213
- }
214
- // Read metadata
215
- let metadata = null;
216
- try {
217
- const metadataContent = await fs.readFile(path.join(executionDir, 'metadata.json'), 'utf-8');
218
- metadata = JSON.parse(metadataContent);
219
- }
220
- catch (error) {
221
- if (error && error.code === 'ENOENT') {
222
- // Expected when metadata was pruned or not yet written; return null without error noise
223
- log.debug('Execution metadata not found (ENOENT)', { executionId, executionDir }, 'execution-log-persistence:readExecutionLogs');
224
- metadata = null;
225
- }
226
- else {
227
- log.error('Failed to read execution metadata', error, 'execution-log-persistence:readExecutionLogs');
228
- }
229
- }
230
- // Read logs
231
- const logs = [];
232
- try {
233
- const logContent = await fs.readFile(path.join(executionDir, 'execution.log'), 'utf-8');
234
- for (const line of logContent.trim().split('\n')) {
235
- if (line) {
236
- try {
237
- logs.push(JSON.parse(line));
238
- }
239
- catch {
240
- // Skip malformed log lines
241
- }
242
- }
243
- }
244
- }
245
- catch (error) {
246
- if (error && error.code === 'ENOENT') {
247
- // No log file yet; treat as empty without logging error
248
- log.debug('Execution log file not found (ENOENT)', { executionId, executionDir }, 'execution-log-persistence:readExecutionLogs');
249
- }
250
- else {
251
- log.error('Failed to read execution logs', error, 'execution-log-persistence:readExecutionLogs');
252
- }
253
- }
254
- return { metadata, logs };
255
- }
256
- catch (error) {
257
- log.error(`Failed to read execution logs for ${executionId}`, error, 'execution-log-persistence:readExecutionLogs');
258
- return { metadata: null, logs: [] };
259
- }
260
- }
261
- /**
262
- * List all executions with metadata
263
- */
264
- async listExecutions() {
265
- try {
266
- await this.ensureLogsDir();
267
- const executions = [];
268
- // Iterate task directories and collect metadata
269
- const taskDirs = await fs.readdir(this.logsDir, { withFileTypes: true });
270
- for (const taskEntry of taskDirs) {
271
- if (!taskEntry.isDirectory())
272
- continue;
273
- const taskPath = path.join(this.logsDir, taskEntry.name);
274
- let execDirs = [];
275
- try {
276
- execDirs = await fs.readdir(taskPath, { withFileTypes: true });
277
- }
278
- catch {
279
- execDirs = [];
280
- }
281
- for (const ed of execDirs) {
282
- if (!ed.isDirectory())
283
- continue;
284
- try {
285
- const metadataPath = path.join(taskPath, ed.name, 'metadata.json');
286
- const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
287
- executions.push(metadata);
288
- }
289
- catch {
290
- // skip invalid dirs
291
- }
292
- }
293
- }
294
- // Sort by start time (most recent first)
295
- return executions.sort((a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime());
296
- }
297
- catch (error) {
298
- log.error('Failed to list executions', error, 'execution-log-persistence:listExecutions');
299
- return [];
300
- }
301
- }
302
- /**
303
- * Clean up old execution logs
304
- */
305
- async cleanupOldLogs(maxAgeDays = 30) {
306
- try {
307
- const executions = await this.listExecutions();
308
- const cutoffTime = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
309
- let removedCount = 0;
310
- for (const execution of executions) {
311
- const executionTime = new Date(execution.endTime || execution.startTime).getTime();
312
- if (executionTime < cutoffTime &&
313
- ['completed', 'failed', 'cancelled'].includes(execution.status)) {
314
- const executionDir = await this.findExecutionDir(execution.executionId);
315
- if (executionDir) {
316
- try {
317
- await fs.rm(executionDir, { recursive: true, force: true });
318
- removedCount++;
319
- // Remove from index (non-throwing)
320
- await this.indexDb.delete(execution.executionId).catch(() => undefined);
321
- }
322
- catch (error) {
323
- log.error(`Failed to remove execution log directory ${executionDir}`, error, 'execution-log-persistence:cleanupOldLogs');
324
- }
325
- }
326
- }
327
- }
328
- if (removedCount > 0) {
329
- log.warn(`Cleaned up ${removedCount} old execution logs`, { removedCount, maxAgeDays }, 'execution-log-persistence:cleanupOldLogs');
330
- }
331
- return removedCount;
332
- }
333
- catch (error) {
334
- log.error('Failed to cleanup old logs', error, 'execution-log-persistence:cleanupOldLogs');
335
- return 0;
336
- }
337
- }
338
- /**
339
- * Remove execution logs for a specific task
340
- */
341
- async removeExecutionsByTask(taskId) {
342
- try {
343
- const executions = await this.listExecutions();
344
- let removedCount = 0;
345
- for (const execution of executions) {
346
- if (execution.taskId === taskId) {
347
- const executionDir = await this.findExecutionDir(execution.executionId);
348
- if (executionDir) {
349
- try {
350
- await fs.rm(executionDir, { recursive: true, force: true });
351
- removedCount++;
352
- await this.indexDb.delete(execution.executionId).catch(() => undefined);
353
- }
354
- catch (error) {
355
- log.error(`Failed to remove execution log directory ${executionDir}`, error, 'execution-log-persistence:cleanupOldLogs');
356
- }
357
- }
358
- }
359
- }
360
- if (removedCount > 0) {
361
- log.warn(`Removed ${removedCount} execution logs for task ${taskId}`, { removedCount, taskId }, 'execution-log-persistence:removeExecutionsByTask');
362
- }
363
- return removedCount;
364
- }
365
- catch (error) {
366
- log.error(`Failed to remove executions for task ${taskId}`, error, 'execution-log-persistence:removeExecutionsByTask');
367
- return 0;
368
- }
369
- }
370
- /**
371
- * Get execution log statistics
372
- */
373
- async getStats() {
374
- try {
375
- const executions = await this.listExecutions();
376
- const stats = {
377
- total: executions.length,
378
- byStatus: {},
379
- totalLogFiles: executions.length,
380
- oldestExecution: undefined,
381
- newestExecution: undefined,
382
- };
383
- let oldest = null;
384
- let newest = null;
385
- for (const execution of executions) {
386
- // Count by status
387
- stats.byStatus[execution.status] = (stats.byStatus[execution.status] || 0) + 1;
388
- // Find oldest/newest
389
- const startTime = new Date(execution.startTime);
390
- if (!oldest || startTime < oldest) {
391
- oldest = startTime;
392
- stats.oldestExecution = execution.executionId;
393
- }
394
- if (!newest || startTime > newest) {
395
- newest = startTime;
396
- stats.newestExecution = execution.executionId;
397
- }
398
- }
399
- return stats;
400
- }
401
- catch (error) {
402
- log.error('Failed to get execution log stats', error, 'execution-log-persistence:getStats');
403
- return {
404
- total: 0,
405
- byStatus: {},
406
- totalLogFiles: 0,
407
- };
408
- }
409
- }
410
- }