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,678 +0,0 @@
1
- /**
2
- * Settings Service - Centralized configuration management
3
- *
4
- * Provides persistent storage and validation for application settings
5
- * with atomic write operations and schema validation using Zod.
6
- */
7
- import { EventEmitter } from 'events';
8
- import fs from 'fs/promises';
9
- import path from 'path';
10
- import { z } from 'zod';
11
- import { log } from './lib/logger.js';
12
- import { getProjectRoot } from './lib/server/project-root.js';
13
- // Zod schema for validation
14
- const CLAUDE_ALLOWED_MODELS = [
15
- 'claude-sonnet-4-20250514',
16
- 'claude-opus-4-1-20250805',
17
- 'claude-3-5-haiku-20241022',
18
- ];
19
- const CODEX_BASE_MODELS = [
20
- 'gpt-5.1-codex-max',
21
- 'gpt-5.1-codex',
22
- 'gpt-5.1-codex-mini',
23
- 'gpt-5.2',
24
- 'gpt-5.1',
25
- ];
26
- const CODEX_REASONING_SUFFIXES = ['low', 'medium', 'high', 'extra-high'];
27
- const CODEX_ALLOWED_MODELS = [
28
- ...CODEX_BASE_MODELS,
29
- ...CODEX_BASE_MODELS.flatMap((base) => CODEX_REASONING_SUFFIXES.map((suffix) => `${base}-${suffix}`)),
30
- ];
31
- const GEMINI_ALLOWED_MODELS = [
32
- 'gemini-3-pro-preview',
33
- 'gemini-3-flash-preview',
34
- 'gemini-2.5-pro',
35
- 'gemini-2.5-flash',
36
- 'gemini-2.5-flash-lite',
37
- ];
38
- const AUTO_ALLOWED_MODELS = ['auto'];
39
- const MODEL_ENUM = [
40
- ...CLAUDE_ALLOWED_MODELS,
41
- ...CODEX_ALLOWED_MODELS,
42
- ...GEMINI_ALLOWED_MODELS,
43
- ...AUTO_ALLOWED_MODELS,
44
- ];
45
- const ROUTABLE_OPERATIONS = [
46
- 'execute_task',
47
- 'quality_checks',
48
- 'ai_codereview',
49
- 'ai_merge',
50
- 'improve_task',
51
- ];
52
- const RoutingOperationSchema = z.object({
53
- provider: z.string(),
54
- model: z.string().optional(),
55
- options: z
56
- .object({
57
- temperature: z.number().min(0).max(2).optional(),
58
- maxTokens: z.number().positive().optional(),
59
- tools: z.array(z.string()).optional(),
60
- })
61
- .optional(),
62
- fallback: z.array(z.string()).optional(),
63
- });
64
- const RoutingPolicySettingsSchema = z
65
- .object({
66
- defaultProvider: z.enum(['claude-code', 'codex', 'gemini', 'amp']).optional(),
67
- operations: z.record(z.enum(ROUTABLE_OPERATIONS), RoutingOperationSchema).optional(),
68
- })
69
- .optional();
70
- const VibemanSettingsSchema = z.object({
71
- agents: z.object({
72
- defaultProvider: z.enum(['claude-code', 'codex', 'gemini', 'amp']),
73
- codingAgent: z.object({
74
- provider: z.enum(['claude-code', 'codex', 'gemini', 'amp']),
75
- model: z.enum(MODEL_ENUM),
76
- maxTokens: z.number().min(256).max(10000000000000).optional(),
77
- }),
78
- judgeAgent: z.object({
79
- provider: z.enum(['claude-code', 'codex', 'gemini', 'amp']),
80
- model: z.enum(MODEL_ENUM),
81
- maxTokens: z.number().min(256).max(10000000000000).optional(),
82
- reviewThresholdScore: z.number().min(0).max(100),
83
- }),
84
- defaultPrompts: z.object({
85
- systemPrompt: z.string().min(10),
86
- taskPrompt: z.string().min(10),
87
- }),
88
- // Note: Provider binary paths are now stored in local config (.vibeman/.local/)
89
- // This field is kept for backwards compatibility but deprecated
90
- providers: z
91
- .object({
92
- claudeCode: z.object({ binPath: z.string().min(1).optional() }).optional(),
93
- codex: z.object({ binPath: z.string().min(1).optional() }).optional(),
94
- gemini: z.object({ binPath: z.string().min(1).optional() }).optional(),
95
- amp: z.object({ binPath: z.string().min(1).optional() }).optional(),
96
- })
97
- .optional(),
98
- routingPolicy: RoutingPolicySettingsSchema,
99
- }),
100
- defaultWorkflow: z.object({
101
- autoQualityChecks: z.boolean(),
102
- requireHumanApproval: z.boolean(),
103
- aiCodeReview: z.boolean(),
104
- maxImplementationAttempts: z.number().min(1).max(10),
105
- autoCommit: z.boolean(),
106
- }),
107
- quality: z
108
- .object({
109
- checks: z.array(z.object({
110
- name: z.string().min(1),
111
- command: z.string().min(1),
112
- args: z.array(z.string()).optional(),
113
- timeout: z
114
- .number()
115
- .min(1000)
116
- .max(10 * 60 * 1000)
117
- .optional(),
118
- enabled: z.boolean().optional(),
119
- })),
120
- })
121
- .optional(),
122
- development: z.object({
123
- vibeDir: z.string().min(1).optional(),
124
- git: z.object({
125
- defaultBranch: z.string().min(1),
126
- worktreePath: z.string().min(1).optional(),
127
- }),
128
- editor: z
129
- .object({
130
- type: z.enum(['vscode', 'cursor', 'vim', 'custom']).optional(),
131
- command: z.string().min(1).optional(),
132
- args: z.array(z.string()).optional(),
133
- name: z.string().min(1).optional(),
134
- openFileCommand: z.array(z.string()).optional(),
135
- openFolderCommand: z.array(z.string()).optional(),
136
- })
137
- .optional(),
138
- terminal: z
139
- .object({
140
- type: z.enum(['system', 'iterm2', 'warp', 'custom']).optional(),
141
- command: z.string().min(1).optional(),
142
- args: z.array(z.string()).optional(),
143
- name: z.string().min(1).optional(),
144
- openCommand: z.array(z.string()).optional(),
145
- })
146
- .optional(),
147
- }),
148
- server: z.object({
149
- port: z.number().min(3000).max(65535),
150
- host: z.string().min(1),
151
- autoOpenBrowser: z.boolean(),
152
- }),
153
- });
154
- // Default settings
155
- const DEFAULT_SETTINGS = {
156
- agents: {
157
- defaultProvider: 'claude-code',
158
- codingAgent: {
159
- provider: 'claude-code',
160
- model: 'claude-sonnet-4-20250514',
161
- },
162
- judgeAgent: {
163
- provider: 'claude-code',
164
- model: 'claude-sonnet-4-20250514',
165
- reviewThresholdScore: 70,
166
- },
167
- defaultPrompts: {
168
- systemPrompt: 'You are a senior software engineer assistant. Follow best practices and write clean, maintainable code.',
169
- taskPrompt: 'Please implement the following task with attention to quality and testing.',
170
- },
171
- providers: {},
172
- routingPolicy: {
173
- defaultProvider: 'claude-code',
174
- operations: {},
175
- },
176
- },
177
- defaultWorkflow: {
178
- autoQualityChecks: true,
179
- requireHumanApproval: true,
180
- aiCodeReview: true,
181
- maxImplementationAttempts: 3,
182
- autoCommit: false,
183
- },
184
- quality: {
185
- checks: [],
186
- },
187
- development: {
188
- git: {
189
- defaultBranch: 'main',
190
- },
191
- editor: {
192
- type: 'vscode',
193
- command: 'code',
194
- args: [],
195
- name: 'Visual Studio Code',
196
- openFileCommand: ['code', '${file}'],
197
- openFolderCommand: ['code', '${folder}'],
198
- },
199
- terminal: {
200
- type: 'system',
201
- command: process.platform === 'darwin'
202
- ? 'open'
203
- : process.platform === 'win32'
204
- ? 'cmd'
205
- : 'gnome-terminal',
206
- args: process.platform === 'darwin' ? ['-a', 'Terminal'] : [],
207
- name: process.platform === 'darwin'
208
- ? 'Terminal'
209
- : process.platform === 'win32'
210
- ? 'Command Prompt'
211
- : 'Terminal',
212
- openCommand: process.platform === 'darwin'
213
- ? ['open', '-a', 'Terminal', '${cwd}']
214
- : process.platform === 'win32'
215
- ? ['cmd', '/c', 'start', 'cmd', '/k', 'cd', '/d', '${cwd}']
216
- : ['gnome-terminal', '--working-directory=${cwd}'],
217
- },
218
- },
219
- server: {
220
- port: 6969,
221
- host: 'localhost',
222
- autoOpenBrowser: true,
223
- },
224
- };
225
- export class SettingsService extends EventEmitter {
226
- constructor(config = {}) {
227
- super();
228
- this.settings = { ...DEFAULT_SETTINGS };
229
- this.initialized = false;
230
- const settingsDir = config.settingsDir ?? '.vibeman/.local';
231
- const settingsFileName = config.settingsFileName ?? 'settings.json';
232
- // Resolve settings path relative to the repo project root (not package CWD)
233
- const projectRoot = getProjectRoot();
234
- this.settingsPath = path.join(projectRoot, settingsDir, settingsFileName);
235
- }
236
- /**
237
- * Initialize the settings service
238
- */
239
- async initialize() {
240
- if (this.initialized)
241
- return;
242
- try {
243
- await this.ensureSettingsDirectory();
244
- await this.loadSettings();
245
- this.initialized = true;
246
- log.info('Settings service initialized', { settingsPath: this.settingsPath }, 'settings-service');
247
- }
248
- catch (error) {
249
- log.error('Failed to initialize settings service', error, 'settings-service');
250
- throw error;
251
- }
252
- }
253
- /**
254
- * Get all current settings
255
- */
256
- getSettings() {
257
- return { ...this.settings };
258
- }
259
- /**
260
- * Get a specific setting by path
261
- */
262
- getSetting(path) {
263
- let current = this.settings;
264
- for (const key of path) {
265
- if (current && typeof current === 'object' && key in current) {
266
- current = current[key];
267
- }
268
- else {
269
- return undefined;
270
- }
271
- }
272
- return current;
273
- }
274
- /**
275
- * Update settings with validation
276
- */
277
- async updateSettings(updates) {
278
- // Create a copy to test updates
279
- const testSettings = JSON.parse(JSON.stringify(this.settings));
280
- const errors = [];
281
- // Apply all updates to test copy
282
- for (const update of updates) {
283
- try {
284
- this.applySingleUpdate(testSettings, update.path, update.value);
285
- }
286
- catch (error) {
287
- errors.push({
288
- path: update.path,
289
- message: error instanceof Error ? error.message : 'Invalid update',
290
- });
291
- }
292
- }
293
- // Validate the entire updated settings object
294
- try {
295
- const validated = VibemanSettingsSchema.parse(testSettings);
296
- if (errors.length === 0) {
297
- // Apply updates to actual settings
298
- this.settings = validated;
299
- await this.saveSettings();
300
- // Emit change events
301
- for (const update of updates) {
302
- this.emit('settingChanged', {
303
- path: update.path,
304
- oldValue: this.getSetting(update.path),
305
- newValue: update.value,
306
- });
307
- }
308
- this.emit('settingsUpdated', this.settings);
309
- return { success: true, errors: [] };
310
- }
311
- }
312
- catch (validationError) {
313
- if (validationError instanceof z.ZodError) {
314
- for (const issue of validationError.issues) {
315
- errors.push({
316
- path: issue.path.map(String),
317
- message: issue.message,
318
- expected: 'Valid value according to schema',
319
- });
320
- }
321
- }
322
- else {
323
- errors.push({
324
- path: [],
325
- message: validationError instanceof Error ? validationError.message : 'Validation failed',
326
- });
327
- }
328
- }
329
- return { success: false, errors };
330
- }
331
- /**
332
- * Reset settings to defaults
333
- */
334
- async resetToDefaults() {
335
- this.settings = { ...DEFAULT_SETTINGS };
336
- await this.saveSettings();
337
- this.emit('settingsReset', this.settings);
338
- log.info('Settings reset to defaults', undefined, 'settings-service');
339
- }
340
- /**
341
- * Validate settings schema
342
- */
343
- validateSettings(settings) {
344
- try {
345
- VibemanSettingsSchema.parse(settings);
346
- return { valid: true, errors: [] };
347
- }
348
- catch (error) {
349
- const errors = [];
350
- if (error instanceof z.ZodError) {
351
- for (const issue of error.issues) {
352
- errors.push({
353
- path: issue.path.map(String),
354
- message: issue.message,
355
- expected: 'Valid value according to schema',
356
- });
357
- }
358
- }
359
- else {
360
- errors.push({
361
- path: [],
362
- message: error instanceof Error ? error.message : 'Validation failed',
363
- });
364
- }
365
- return { valid: false, errors };
366
- }
367
- }
368
- /**
369
- * Get settings file information
370
- */
371
- async getSettingsInfo() {
372
- return {
373
- path: this.settingsPath,
374
- exists: await this.fileExists(this.settingsPath),
375
- };
376
- }
377
- /**
378
- * Get predefined editor configurations
379
- */
380
- getEditorPresets() {
381
- return {
382
- vscode: {
383
- type: 'vscode',
384
- command: 'code',
385
- name: 'Visual Studio Code',
386
- openFileCommand: ['code', '${file}'],
387
- openFolderCommand: ['code', '${folder}'],
388
- },
389
- cursor: {
390
- type: 'cursor',
391
- command: 'cursor',
392
- name: 'Cursor',
393
- openFileCommand: ['cursor', '${file}'],
394
- openFolderCommand: ['cursor', '${folder}'],
395
- },
396
- vim: {
397
- type: 'vim',
398
- command: 'vim',
399
- name: 'Vim',
400
- openFileCommand: ['vim', '${file}'],
401
- openFolderCommand: ['vim', '${folder}'],
402
- },
403
- };
404
- }
405
- /**
406
- * Get predefined terminal configurations
407
- */
408
- getTerminalPresets() {
409
- const platform = process.platform;
410
- return {
411
- system: {
412
- type: 'system',
413
- command: platform === 'darwin' ? 'open' : platform === 'win32' ? 'cmd' : 'gnome-terminal',
414
- args: platform === 'darwin' ? ['-a', 'Terminal'] : [],
415
- name: platform === 'darwin' ? 'Terminal' : platform === 'win32' ? 'Command Prompt' : 'Terminal',
416
- openCommand: platform === 'darwin'
417
- ? ['open', '-a', 'Terminal', '${cwd}']
418
- : platform === 'win32'
419
- ? ['cmd', '/c', 'start', 'cmd', '/k', 'cd', '/d', '${cwd}']
420
- : ['gnome-terminal', '--working-directory=${cwd}'],
421
- },
422
- iterm2: {
423
- type: 'iterm2',
424
- command: 'open',
425
- args: ['-a', 'iTerm'],
426
- name: 'iTerm2',
427
- openCommand: ['open', '-a', 'iTerm', '${cwd}'],
428
- },
429
- warp: {
430
- type: 'warp',
431
- command: 'open',
432
- args: ['-a', 'Warp'],
433
- name: 'Warp',
434
- openCommand: ['open', '-a', 'Warp', '${cwd}'],
435
- },
436
- };
437
- }
438
- /**
439
- * Apply editor preset configuration
440
- */
441
- async applyEditorPreset(presetName) {
442
- const presets = this.getEditorPresets();
443
- const preset = presets[presetName];
444
- if (!preset) {
445
- return {
446
- success: false,
447
- errors: [
448
- { path: ['development', 'editor'], message: `Unknown editor preset: ${presetName}` },
449
- ],
450
- };
451
- }
452
- return this.updateSettings([
453
- {
454
- path: ['development', 'editor'],
455
- value: preset,
456
- },
457
- ]);
458
- }
459
- /**
460
- * Apply terminal preset configuration
461
- */
462
- async applyTerminalPreset(presetName) {
463
- const presets = this.getTerminalPresets();
464
- const preset = presets[presetName];
465
- if (!preset) {
466
- return {
467
- success: false,
468
- errors: [
469
- { path: ['development', 'terminal'], message: `Unknown terminal preset: ${presetName}` },
470
- ],
471
- };
472
- }
473
- return this.updateSettings([
474
- {
475
- path: ['development', 'terminal'],
476
- value: preset,
477
- },
478
- ]);
479
- }
480
- /**
481
- * Generate command to open a file with the configured editor
482
- */
483
- getOpenFileCommand(filePath) {
484
- const editor = this.settings.development?.editor;
485
- if (!editor?.openFileCommand)
486
- return null;
487
- return editor.openFileCommand.map((arg) => arg.replace('${file}', filePath));
488
- }
489
- /**
490
- * Generate command to open a folder with the configured editor
491
- */
492
- getOpenFolderCommand(folderPath) {
493
- const editor = this.settings.development?.editor;
494
- if (!editor?.openFolderCommand)
495
- return null;
496
- return editor.openFolderCommand.map((arg) => arg.replace('${folder}', folderPath));
497
- }
498
- /**
499
- * Generate command to open terminal in specific directory
500
- */
501
- getOpenTerminalCommand(cwd) {
502
- const terminal = this.settings.development?.terminal;
503
- if (!terminal?.openCommand)
504
- return null;
505
- return terminal.openCommand.map((arg) => arg.replace('${cwd}', cwd));
506
- }
507
- /**
508
- * Validate if editor is available on system
509
- */
510
- async validateEditorAvailability() {
511
- const editor = this.settings.development?.editor;
512
- if (!editor?.command) {
513
- return { available: false, error: 'No editor command configured' };
514
- }
515
- try {
516
- const { exec } = await import('child_process');
517
- const { promisify } = await import('util');
518
- const execAsync = promisify(exec);
519
- // Try to get version or check if command exists
520
- await execAsync(`which ${editor.command}`, { timeout: 5000 });
521
- return { available: true };
522
- }
523
- catch {
524
- return {
525
- available: false,
526
- error: `Editor command '${editor.command}' not found in PATH`,
527
- };
528
- }
529
- }
530
- /**
531
- * Validate if terminal is available on system
532
- */
533
- async validateTerminalAvailability() {
534
- const terminal = this.settings.development?.terminal;
535
- if (!terminal?.command) {
536
- return { available: false, error: 'No terminal command configured' };
537
- }
538
- try {
539
- const { exec } = await import('child_process');
540
- const { promisify } = await import('util');
541
- const execAsync = promisify(exec);
542
- // Try to check if command exists
543
- await execAsync(`which ${terminal.command}`, { timeout: 5000 });
544
- return { available: true };
545
- }
546
- catch {
547
- return {
548
- available: false,
549
- error: `Terminal command '${terminal.command}' not found in PATH`,
550
- };
551
- }
552
- }
553
- // Private methods
554
- async ensureSettingsDirectory() {
555
- const settingsDir = path.dirname(this.settingsPath);
556
- try {
557
- await fs.access(settingsDir);
558
- }
559
- catch {
560
- await fs.mkdir(settingsDir, { recursive: true });
561
- log.info('Created settings directory', { settingsDir }, 'settings-service');
562
- }
563
- }
564
- async loadSettings() {
565
- try {
566
- await fs.access(this.settingsPath);
567
- const data = await fs.readFile(this.settingsPath, 'utf-8');
568
- const parsed = JSON.parse(data);
569
- // Validate and merge with defaults
570
- const validated = VibemanSettingsSchema.parse(parsed);
571
- this.settings = this.mergeWithDefaults(validated);
572
- log.info('Settings loaded from file', { settingsPath: this.settingsPath }, 'settings-service');
573
- }
574
- catch (error) {
575
- log.info('Settings file not found or invalid, using defaults', { error: String(error) }, 'settings-service');
576
- this.settings = { ...DEFAULT_SETTINGS };
577
- await this.saveSettings();
578
- }
579
- }
580
- async saveSettings() {
581
- const data = JSON.stringify(this.settings, null, 2);
582
- await fs.writeFile(this.settingsPath, data, 'utf-8');
583
- log.debug('Settings saved to file', { settingsPath: this.settingsPath }, 'settings-service');
584
- }
585
- async fileExists(filePath) {
586
- try {
587
- await fs.access(filePath);
588
- return true;
589
- }
590
- catch {
591
- return false;
592
- }
593
- }
594
- mergeWithDefaults(settings) {
595
- // Deep merge settings with defaults to handle missing properties
596
- return {
597
- ...DEFAULT_SETTINGS,
598
- ...settings,
599
- agents: {
600
- ...DEFAULT_SETTINGS.agents,
601
- ...settings.agents,
602
- codingAgent: {
603
- ...DEFAULT_SETTINGS.agents.codingAgent,
604
- ...settings.agents?.codingAgent,
605
- },
606
- judgeAgent: {
607
- ...DEFAULT_SETTINGS.agents.judgeAgent,
608
- ...settings.agents?.judgeAgent,
609
- },
610
- providers: {
611
- ...(DEFAULT_SETTINGS.agents.providers ?? {}),
612
- ...(settings.agents?.providers ?? {}),
613
- },
614
- defaultPrompts: {
615
- ...DEFAULT_SETTINGS.agents.defaultPrompts,
616
- ...settings.agents?.defaultPrompts,
617
- },
618
- routingPolicy: {
619
- ...DEFAULT_SETTINGS.agents.routingPolicy,
620
- ...settings.agents?.routingPolicy,
621
- operations: {
622
- ...(DEFAULT_SETTINGS.agents.routingPolicy?.operations ?? {}),
623
- ...(settings.agents?.routingPolicy?.operations ?? {}),
624
- },
625
- },
626
- },
627
- defaultWorkflow: {
628
- ...DEFAULT_SETTINGS.defaultWorkflow,
629
- ...settings.defaultWorkflow,
630
- },
631
- quality: {
632
- ...DEFAULT_SETTINGS.quality,
633
- ...settings.quality,
634
- checks: (settings.quality?.checks ?? DEFAULT_SETTINGS.quality?.checks),
635
- },
636
- development: {
637
- ...DEFAULT_SETTINGS.development,
638
- ...settings.development,
639
- git: {
640
- ...DEFAULT_SETTINGS.development.git,
641
- ...settings.development?.git,
642
- },
643
- editor: {
644
- ...DEFAULT_SETTINGS.development.editor,
645
- ...settings.development?.editor,
646
- },
647
- terminal: {
648
- ...DEFAULT_SETTINGS.development.terminal,
649
- ...settings.development?.terminal,
650
- },
651
- },
652
- server: {
653
- ...DEFAULT_SETTINGS.server,
654
- ...settings.server,
655
- },
656
- };
657
- }
658
- applySingleUpdate(target, path, value) {
659
- if (path.length === 0) {
660
- throw new Error('Empty path not allowed');
661
- }
662
- if (path.length === 1) {
663
- target[path[0]] = value;
664
- return;
665
- }
666
- const [head, ...tail] = path;
667
- if (!target[head] || typeof target[head] !== 'object') {
668
- target[head] = {};
669
- }
670
- this.applySingleUpdate(target[head], tail, value);
671
- }
672
- }
673
- // Singleton instance
674
- let settingsService = null;
675
- export function getSettingsService(config) {
676
- settingsService ?? (settingsService = new SettingsService(config));
677
- return settingsService;
678
- }
@@ -1,23 +0,0 @@
1
- import { EventEmitter } from 'events';
2
- export interface FileWatcherOptions {
3
- recursive?: boolean;
4
- debounceMs?: number;
5
- fileFilter?: (filename: string) => boolean;
6
- }
7
- export interface FileChangeEvent {
8
- type: 'created' | 'updated' | 'deleted';
9
- filename: string;
10
- fullPath: string;
11
- }
12
- export declare class FileWatcher extends EventEmitter {
13
- private watcher;
14
- private watchDir;
15
- private options;
16
- private pendingChanges;
17
- constructor(watchDir: string, options?: FileWatcherOptions);
18
- start(): void;
19
- stop(): void;
20
- private debounceFileChange;
21
- private handleFileChange;
22
- private fileExists;
23
- }