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,375 +0,0 @@
1
- /**
2
- * Codex CLI Provider
3
- * Headless wrapper around the Codex CLI `codex exec` command.
4
- */
5
- import { spawn } from 'child_process';
6
- import { getSettingsService } from '../../settings-service.js';
7
- import { getProviderDetectionService } from '../../lib/provider-detection.js';
8
- import { logger } from '../../lib/logger.js';
9
- const CODEX_BASE_MODELS = [
10
- 'gpt-5.1-codex-max',
11
- 'gpt-5.1-codex',
12
- 'gpt-5.1-codex-mini',
13
- 'gpt-5.2',
14
- 'gpt-5.1',
15
- ];
16
- const CODEX_BASE_LABELS = {
17
- 'gpt-5.1-codex-max': 'gpt-5.1 Codex Max (current)',
18
- 'gpt-5.1-codex': 'gpt-5.1 Codex',
19
- 'gpt-5.1-codex-mini': 'gpt-5.1 Codex Mini',
20
- 'gpt-5.2': 'gpt-5.2',
21
- 'gpt-5.1': 'gpt-5.1',
22
- };
23
- const REASONING_SUFFIXES = [
24
- 'minimal',
25
- 'low',
26
- 'medium',
27
- 'high',
28
- 'extra',
29
- 'extra-high',
30
- 'extra_high',
31
- ];
32
- export class CodexCliProvider {
33
- constructor(config = {}) {
34
- this.config = config;
35
- this.name = 'codex';
36
- this.displayName = 'Codex CLI';
37
- }
38
- async resolveExecutable() {
39
- if (this.config.codexBinPath)
40
- return this.config.codexBinPath;
41
- // Use enhanced detection service
42
- const detectionService = getProviderDetectionService();
43
- const result = await detectionService.detectProvider('codex');
44
- if (result.found && result.path) {
45
- return result.path;
46
- }
47
- // Fallback: try old settings-based approach for backwards compatibility
48
- const settingsBinPath = (() => {
49
- try {
50
- const svc = getSettingsService();
51
- const s = svc.getSettings();
52
- return s?.agents?.providers?.codex?.binPath;
53
- }
54
- catch {
55
- return undefined;
56
- }
57
- })();
58
- if (settingsBinPath?.trim())
59
- return settingsBinPath.trim();
60
- // Default to binary name (resolve via PATH)
61
- return 'codex';
62
- }
63
- normalizeReasoningEffort(value) {
64
- if (!value)
65
- return undefined;
66
- const normalized = value.toLowerCase().replace(/\s+/g, '-');
67
- if (normalized === 'minimal')
68
- return 'low';
69
- if (normalized === 'extra-high' || normalized === 'extra_high' || normalized === 'extra') {
70
- return 'extra_high';
71
- }
72
- const allowed = ['low', 'medium', 'high'];
73
- return allowed.includes(normalized)
74
- ? normalized
75
- : undefined;
76
- }
77
- resolveModelSpec(model, fallbackEffort) {
78
- const fallback = this.normalizeReasoningEffort(fallbackEffort);
79
- if (!model) {
80
- return { reasoning: fallback };
81
- }
82
- const trimmed = model.trim();
83
- const normalized = trimmed.toLowerCase();
84
- const basePattern = CODEX_BASE_MODELS.map((m) => m.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')).join('|');
85
- const reasoningPattern = [...REASONING_SUFFIXES].join('|');
86
- const match = normalized.match(new RegExp(`^(${basePattern})(?:-(${reasoningPattern}))?$`));
87
- if (!match) {
88
- return {
89
- cliModel: trimmed,
90
- requestedModel: trimmed,
91
- reasoning: fallback,
92
- };
93
- }
94
- const baseModel = match[1];
95
- const reasoning = this.normalizeReasoningEffort(match[2]);
96
- return {
97
- cliModel: baseModel,
98
- requestedModel: trimmed,
99
- reasoning: reasoning ?? fallback,
100
- };
101
- }
102
- async *execute(prompt, options) {
103
- // Effective options
104
- const cwd = options?.workingDirectory || this.config.defaultWorkingDirectory || process.cwd();
105
- const resolvedModel = this.resolveModelSpec(options?.model || this.config.defaultModel, options?.effort);
106
- const model = resolvedModel.cliModel;
107
- const images = (options?.images || []).filter(Boolean);
108
- const reasoningEffort = resolvedModel.reasoning;
109
- const timeoutMs = options?.timeout ?? this.config.defaultTimeoutMs ?? 10 * 60 * 1000; // 10m
110
- const systemPrompt = options?.systemPrompt?.trim();
111
- const appendSystemPrompt = options?.appendSystemPrompt?.trim();
112
- const promptSegments = [];
113
- if (systemPrompt) {
114
- promptSegments.push(systemPrompt);
115
- }
116
- if (appendSystemPrompt) {
117
- promptSegments.push(appendSystemPrompt);
118
- }
119
- promptSegments.push(prompt);
120
- const effectivePrompt = promptSegments.join('\n\n');
121
- // Build argv for `codex exec` (non-interactive automation mode)
122
- const argv = ['exec', effectivePrompt];
123
- if (model) {
124
- argv.push('--model', model);
125
- }
126
- if (reasoningEffort) {
127
- argv.push('-c', `model_reasoning_effort=${reasoningEffort}`);
128
- }
129
- // Prefer spawning with cwd, but also set --cd to make Codex aware of root
130
- if (cwd) {
131
- argv.push('--cd', cwd);
132
- }
133
- if (images.length) {
134
- argv.push('--image', images.join(','));
135
- }
136
- if (options?.dangerouslyBypassApprovalsAndSandbox) {
137
- // Codex CLI >= 0.73.0 replaces the legacy bypass flag with --full-auto + sandbox selection
138
- argv.push('--full-auto');
139
- argv.push('--sandbox', 'danger-full-access');
140
- }
141
- const cmd = await this.resolveExecutable();
142
- const child = spawn(cmd, argv, {
143
- cwd,
144
- env: { ...process.env },
145
- stdio: ['ignore', 'pipe', 'pipe'],
146
- });
147
- // Emit an init/system message with effective command
148
- const init = {
149
- type: 'init',
150
- timestamp: new Date().toISOString(),
151
- sessionId: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
152
- model: resolvedModel.requestedModel || model || 'default',
153
- provider: this.name,
154
- };
155
- yield init;
156
- yield {
157
- type: 'system',
158
- timestamp: new Date().toISOString(),
159
- content: `Running: ${cmd} ${argv
160
- .map((a) => (a.includes(' ') ? '"' + a + '"' : a))
161
- .join(' ')} (cwd=${cwd})`,
162
- metadata: {
163
- provider: this.name,
164
- images,
165
- effort: reasoningEffort || options?.effort,
166
- systemPrompt,
167
- appendSystemPrompt,
168
- dangerouslyBypassApprovalsAndSandbox: !!options?.dangerouslyBypassApprovalsAndSandbox,
169
- },
170
- };
171
- let stdoutBuf = '';
172
- // let stderrBuf = '';
173
- let finished = false;
174
- let lastFlushedIndex = 0;
175
- let lineCarry = '';
176
- // Helper to push incremental stdout as assistant log lines
177
- const flushNewOutput = () => {
178
- const newChunk = stdoutBuf.slice(lastFlushedIndex);
179
- if (!newChunk)
180
- return;
181
- lastFlushedIndex = stdoutBuf.length;
182
- // Accumulate and split by line breaks, keep trailing partial
183
- lineCarry += newChunk;
184
- const parts = lineCarry.split(/\r?\n/);
185
- lineCarry = parts.pop() || '';
186
- return parts.map((l) => l.trimEnd()).filter(Boolean);
187
- };
188
- // Provider stays generic: it streams lines and returns raw stdout.
189
- // Forward parent termination via abortSignal
190
- // const abortController = new AbortController();
191
- const onAbort = () => {
192
- try {
193
- child.kill('SIGTERM');
194
- }
195
- catch {
196
- /* ignore */
197
- }
198
- // Fallback kill after short grace
199
- setTimeout(() => {
200
- if (!finished) {
201
- try {
202
- child.kill('SIGKILL');
203
- }
204
- catch {
205
- /* ignore */
206
- }
207
- }
208
- }, 3000);
209
- };
210
- if (options?.abortSignal) {
211
- if (options.abortSignal.aborted)
212
- onAbort();
213
- else
214
- options.abortSignal.addEventListener('abort', onAbort, { once: true });
215
- }
216
- // Local timeout guard
217
- const guard = setTimeout(() => {
218
- onAbort();
219
- }, timeoutMs);
220
- // Capture data into buffers
221
- child.stdout?.on('data', (data) => {
222
- stdoutBuf += data.toString('utf8');
223
- });
224
- // child.stderr?.on('data', (data: Buffer) => {
225
- // stderrBuf += data.toString('utf8');
226
- // });
227
- // Wait for process to finish
228
- // Stream logs while the process runs by polling for new output
229
- const exitPromise = new Promise((resolve) => {
230
- child.on('exit', (code, signal) => resolve({ code, signal }));
231
- });
232
- // Poll for output until the process exits
233
- let exitStatus;
234
- while (!finished) {
235
- const tick = new Promise((r) => setTimeout(r, 150));
236
- const exit = await Promise.race([exitPromise, tick]);
237
- if (exit && typeof exit.code !== 'undefined') {
238
- // Process exited; flush any remaining output before breaking
239
- const lines = flushNewOutput();
240
- if (lines && lines.length) {
241
- for (const text of lines) {
242
- yield {
243
- type: 'assistant',
244
- timestamp: new Date().toISOString(),
245
- content: text,
246
- };
247
- }
248
- }
249
- finished = true;
250
- // Record exit info for finalization
251
- exitStatus = exit;
252
- break;
253
- }
254
- // Flush incremental lines during run
255
- const lines = flushNewOutput();
256
- if (lines && lines.length) {
257
- for (const text of lines) {
258
- yield {
259
- type: 'assistant',
260
- timestamp: new Date().toISOString(),
261
- content: text,
262
- };
263
- }
264
- }
265
- }
266
- // If loop ended without capturing exit status (unlikely), await it now
267
- const exit = exitStatus ?? (await exitPromise);
268
- finished = true;
269
- clearTimeout(guard);
270
- // Flush any final carry line as a log
271
- if (lineCarry.trim()) {
272
- yield {
273
- type: 'assistant',
274
- timestamp: new Date().toISOString(),
275
- content: lineCarry.trimEnd(),
276
- };
277
- lineCarry = '';
278
- }
279
- // Compose final message
280
- const success = (exit.code ?? 1) === 0 && !exit.signal;
281
- const remainingStdout = stdoutBuf.trim();
282
- const resultMsg = {
283
- type: 'result',
284
- timestamp: new Date().toISOString(),
285
- success,
286
- // Return raw stdout as result; higher layers decide how to parse it
287
- result: success ? (remainingStdout || '').toString() : undefined,
288
- error: success
289
- ? undefined
290
- : `codex exited ${exit.signal ? 'by ' + exit.signal : 'with code ' + exit.code}`,
291
- usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
292
- };
293
- yield resultMsg;
294
- }
295
- async executeSync(prompt, options) {
296
- // Convenience: collect from execute()
297
- let content = '';
298
- const start = Date.now();
299
- const resolvedModel = this.resolveModelSpec(options?.model || this.config.defaultModel, options?.effort);
300
- for await (const msg of this.execute(prompt, options)) {
301
- if (msg.type === 'assistant' && typeof msg.content === 'string') {
302
- content += (content ? '\n' : '') + msg.content;
303
- }
304
- }
305
- return {
306
- id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
307
- provider: this.name,
308
- model: resolvedModel.requestedModel || resolvedModel.cliModel || 'default',
309
- content,
310
- usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
311
- duration: Date.now() - start,
312
- };
313
- }
314
- async detectAvailableModels() {
315
- const capabilities = ['code', 'analysis', 'tools', 'vision', 'image', 'reasoning'];
316
- const makeModel = (id, displayName) => ({
317
- id,
318
- name: id,
319
- displayName,
320
- provider: this.name,
321
- contextWindow: 256000,
322
- maxOutputTokens: 16384,
323
- capabilities,
324
- });
325
- const addReasoningVariants = (base, label) => [
326
- makeModel(base, label),
327
- makeModel(`${base}-low`, `${label} · low reasoning`),
328
- makeModel(`${base}-medium`, `${label} · medium reasoning`),
329
- makeModel(`${base}-high`, `${label} · high reasoning`),
330
- makeModel(`${base}-extra-high`, `${label} · extra-high reasoning`),
331
- ];
332
- return Object.entries(CODEX_BASE_LABELS).flatMap(([id, label]) => addReasoningVariants(id, label));
333
- }
334
- async validateSetup() {
335
- try {
336
- const detectionService = getProviderDetectionService();
337
- const result = await detectionService.detectProvider('codex');
338
- if (!result.found) {
339
- return {
340
- available: false,
341
- error: result.error ||
342
- 'Codex CLI not found. Install from https://github.com/openai/codex (see Getting Started: CLI usage).',
343
- models: [],
344
- capabilities: this.getCapabilities(),
345
- };
346
- }
347
- return {
348
- available: true,
349
- models: await this.detectAvailableModels(),
350
- capabilities: this.getCapabilities(),
351
- };
352
- }
353
- catch (error) {
354
- logger.error(error);
355
- return {
356
- available: false,
357
- error: error instanceof Error ? error.message : String(error),
358
- models: [],
359
- capabilities: this.getCapabilities(),
360
- };
361
- }
362
- }
363
- // Note: persistence of detected binary paths is handled by onboarding workflow.
364
- getCapabilities() {
365
- return {
366
- streaming: true,
367
- tools: true,
368
- functionCalling: false,
369
- vision: true,
370
- codeExecution: true,
371
- maxContextWindow: 128000,
372
- maxOutputTokens: 8192,
373
- };
374
- }
375
- }
@@ -1,24 +0,0 @@
1
- /**
2
- * Gemini CLI Provider
3
- * Headless wrapper around the Gemini CLI binary (default command `gemini`).
4
- */
5
- import { AIProvider, ExecutionMessage, ExecutionOptions, ModelInfo, ProviderCapabilities, ProviderStatus } from './types.js';
6
- export interface GeminiCliConfig {
7
- geminiBinPath?: string;
8
- defaultWorkingDirectory?: string;
9
- defaultModel?: string;
10
- defaultTimeoutMs?: number;
11
- }
12
- export declare class GeminiCliProvider implements AIProvider {
13
- private config;
14
- readonly name = "gemini";
15
- readonly displayName = "Gemini CLI";
16
- constructor(config?: GeminiCliConfig);
17
- private resolveExecutable;
18
- private normalizeReasoningEffort;
19
- private resolveModelSpec;
20
- execute(prompt: string, options?: ExecutionOptions): AsyncIterableIterator<ExecutionMessage>;
21
- detectAvailableModels(): Promise<ModelInfo[]>;
22
- validateSetup(): Promise<ProviderStatus>;
23
- getCapabilities(): ProviderCapabilities;
24
- }
@@ -1,291 +0,0 @@
1
- /**
2
- * Gemini CLI Provider
3
- * Headless wrapper around the Gemini CLI binary (default command `gemini`).
4
- */
5
- import { spawn } from 'child_process';
6
- import { getSettingsService } from '../../settings-service.js';
7
- import { getProviderDetectionService } from '../../lib/provider-detection.js';
8
- export class GeminiCliProvider {
9
- constructor(config = {}) {
10
- this.config = config;
11
- this.name = 'gemini';
12
- this.displayName = 'Gemini CLI';
13
- }
14
- async resolveExecutable() {
15
- if (this.config.geminiBinPath)
16
- return this.config.geminiBinPath;
17
- // Use enhanced detection service
18
- const detectionService = getProviderDetectionService();
19
- const result = await detectionService.detectProvider('gemini');
20
- if (result.found && result.path) {
21
- return result.path;
22
- }
23
- // Fallback: try old settings-based approach for backwards compatibility
24
- const settingsBinPath = (() => {
25
- try {
26
- const svc = getSettingsService();
27
- const s = svc.getSettings();
28
- return s?.agents?.providers?.gemini?.binPath;
29
- }
30
- catch {
31
- return undefined;
32
- }
33
- })();
34
- if (settingsBinPath?.trim())
35
- return settingsBinPath.trim();
36
- // Default to binary name (resolve via PATH)
37
- return 'gemini';
38
- }
39
- normalizeReasoningEffort(value) {
40
- if (!value)
41
- return undefined;
42
- const normalized = value.toLowerCase();
43
- if (normalized === 'minimal')
44
- return 'low';
45
- const allowed = ['low', 'medium', 'high'];
46
- return allowed.includes(normalized)
47
- ? normalized
48
- : undefined;
49
- }
50
- resolveModelSpec(model, fallbackEffort) {
51
- const fallback = this.normalizeReasoningEffort(fallbackEffort);
52
- if (!model) {
53
- return { reasoning: fallback };
54
- }
55
- const trimmed = model.trim();
56
- const normalized = trimmed.toLowerCase();
57
- // Recognize a few common Gemini model aliases; keep passthrough for others
58
- const knownPrefixes = [
59
- 'gemini-3-pro-preview',
60
- 'gemini-3-flash-preview',
61
- 'gemini-2.5-pro',
62
- 'gemini-2.5-flash',
63
- 'gemini-2.5-flash-lite',
64
- 'gemini-3',
65
- 'gemini-2.5',
66
- 'gemini',
67
- ];
68
- const isKnown = knownPrefixes.some((p) => normalized.startsWith(p));
69
- return {
70
- cliModel: isKnown ? trimmed : trimmed,
71
- requestedModel: trimmed,
72
- reasoning: fallback,
73
- };
74
- }
75
- async *execute(prompt, options) {
76
- // Effective options
77
- const cwd = options?.workingDirectory || this.config.defaultWorkingDirectory || process.cwd();
78
- const resolvedModel = this.resolveModelSpec(options?.model || this.config.defaultModel, options?.effort);
79
- const model = resolvedModel.cliModel;
80
- const images = (options?.images || []).filter(Boolean);
81
- const timeoutMs = options?.timeout ?? this.config.defaultTimeoutMs ?? 10 * 60 * 1000; // 10m
82
- const temperature = options?.temperature;
83
- const systemPrompt = options?.systemPrompt?.trim();
84
- const appendSystemPrompt = options?.appendSystemPrompt?.trim();
85
- const promptSegments = [];
86
- if (systemPrompt)
87
- promptSegments.push(systemPrompt);
88
- if (appendSystemPrompt)
89
- promptSegments.push(appendSystemPrompt);
90
- promptSegments.push(prompt);
91
- const effectivePrompt = promptSegments.join('\n\n');
92
- // Build argv for `gemini` CLI. Use a simple subcommand 'chat' with flags; passthrough prompt as arg.
93
- const argv = [];
94
- // Prefer a subcommand if used by the CLI; otherwise just supply flags
95
- // We keep it generic so detection/validation works even if CLI differs
96
- if (model) {
97
- argv.push('--model', model);
98
- }
99
- if (typeof temperature === 'number') {
100
- argv.push('--temperature', String(temperature));
101
- }
102
- if (images.length) {
103
- argv.push('--image', images.join(','));
104
- }
105
- // YOLO mode auto-approves tool calls to allow code edits without prompts
106
- argv.push('--yolo');
107
- // Push the prompt last (many CLIs accept final arg as the prompt)
108
- argv.push(effectivePrompt);
109
- const cmd = await this.resolveExecutable();
110
- const child = spawn(cmd, argv, {
111
- cwd,
112
- env: { ...process.env },
113
- stdio: ['ignore', 'pipe', 'pipe'],
114
- });
115
- // Emit an init/system message with effective command
116
- const init = {
117
- type: 'init',
118
- timestamp: new Date().toISOString(),
119
- sessionId: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
120
- model: resolvedModel.requestedModel || model || 'default',
121
- provider: this.name,
122
- };
123
- yield init;
124
- yield {
125
- type: 'system',
126
- timestamp: new Date().toISOString(),
127
- content: `Running: ${cmd} ${argv
128
- .map((a) => (a.includes(' ') ? '"' + a + '"' : a))
129
- .join(' ')} (cwd=${cwd})`,
130
- metadata: {
131
- provider: this.name,
132
- images,
133
- systemPrompt,
134
- appendSystemPrompt,
135
- },
136
- };
137
- let stdoutBuf = '';
138
- let finished = false;
139
- let lastFlushedIndex = 0;
140
- let lineCarry = '';
141
- const flushNewOutput = () => {
142
- const newChunk = stdoutBuf.slice(lastFlushedIndex);
143
- if (!newChunk)
144
- return;
145
- lastFlushedIndex = stdoutBuf.length;
146
- lineCarry += newChunk;
147
- const parts = lineCarry.split(/\r?\n/);
148
- lineCarry = parts.pop() || '';
149
- return parts.map((l) => l.trimEnd());
150
- };
151
- const onAbort = () => {
152
- try {
153
- child.kill('SIGTERM');
154
- }
155
- catch (err) {
156
- void err; // ignore if process already exited
157
- }
158
- setTimeout(() => {
159
- if (!finished) {
160
- try {
161
- child.kill('SIGKILL');
162
- }
163
- catch (err) {
164
- void err; // ignore if process already exited
165
- }
166
- }
167
- }, 3000);
168
- };
169
- if (options?.abortSignal) {
170
- if (options.abortSignal.aborted)
171
- onAbort();
172
- else
173
- options.abortSignal.addEventListener('abort', onAbort, { once: true });
174
- }
175
- const guard = setTimeout(() => onAbort(), timeoutMs);
176
- child.stdout?.on('data', (data) => {
177
- stdoutBuf += data.toString('utf8');
178
- });
179
- const exitPromise = new Promise((resolve) => {
180
- child.on('exit', (code, signal) => resolve({ code, signal }));
181
- });
182
- let exitStatus;
183
- while (!finished) {
184
- const tick = new Promise((r) => setTimeout(r, 150));
185
- const exit = await Promise.race([exitPromise, tick]);
186
- if (exit && typeof exit.code !== 'undefined') {
187
- const lines = flushNewOutput();
188
- if (lines && lines.length) {
189
- for (const text of lines) {
190
- if (!text)
191
- continue;
192
- yield { type: 'assistant', timestamp: new Date().toISOString(), content: text };
193
- }
194
- }
195
- finished = true;
196
- exitStatus = exit;
197
- break;
198
- }
199
- const lines = flushNewOutput();
200
- if (lines && lines.length) {
201
- for (const text of lines) {
202
- if (!text)
203
- continue;
204
- yield { type: 'assistant', timestamp: new Date().toISOString(), content: text };
205
- }
206
- }
207
- }
208
- const exit = exitStatus ?? (await exitPromise);
209
- finished = true;
210
- clearTimeout(guard);
211
- if (lineCarry.trim()) {
212
- yield {
213
- type: 'assistant',
214
- timestamp: new Date().toISOString(),
215
- content: lineCarry.trimEnd(),
216
- };
217
- lineCarry = '';
218
- }
219
- const success = (exit.code ?? 1) === 0 && !exit.signal;
220
- const remainingStdout = stdoutBuf.trim();
221
- const resultMsg = {
222
- type: 'result',
223
- timestamp: new Date().toISOString(),
224
- success,
225
- result: success ? (remainingStdout || '').toString() : undefined,
226
- error: success
227
- ? undefined
228
- : `gemini exited ${exit.signal ? 'by ' + exit.signal : 'with code ' + exit.code}`,
229
- usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
230
- };
231
- yield resultMsg;
232
- }
233
- async detectAvailableModels() {
234
- const capabilities = ['code', 'analysis', 'tools', 'vision', 'image', 'reasoning'];
235
- const makeModel = (id, displayName) => ({
236
- id,
237
- name: id,
238
- displayName,
239
- provider: this.name,
240
- contextWindow: 128000,
241
- maxOutputTokens: 8192,
242
- capabilities,
243
- });
244
- return [
245
- makeModel('gemini-3-pro-preview', 'Gemini 3 Pro Preview'),
246
- makeModel('gemini-3-flash-preview', 'Gemini 3 Flash Preview'),
247
- makeModel('gemini-2.5-pro', 'Gemini 2.5 Pro'),
248
- makeModel('gemini-2.5-flash', 'Gemini 2.5 Flash'),
249
- makeModel('gemini-2.5-flash-lite', 'Gemini 2.5 Flash Lite'),
250
- ];
251
- }
252
- async validateSetup() {
253
- try {
254
- const detectionService = getProviderDetectionService();
255
- const result = await detectionService.detectProvider('gemini');
256
- if (!result.found) {
257
- return {
258
- available: false,
259
- error: result.error ||
260
- 'Gemini CLI not found. Install the Gemini CLI and ensure it is available on PATH as "gemini" or set VIBEMAN_GEMINI_BIN.',
261
- models: [],
262
- capabilities: this.getCapabilities(),
263
- };
264
- }
265
- return {
266
- available: true,
267
- models: await this.detectAvailableModels(),
268
- capabilities: this.getCapabilities(),
269
- };
270
- }
271
- catch (error) {
272
- return {
273
- available: false,
274
- error: error instanceof Error ? error.message : String(error),
275
- models: [],
276
- capabilities: this.getCapabilities(),
277
- };
278
- }
279
- }
280
- getCapabilities() {
281
- return {
282
- streaming: true,
283
- tools: true,
284
- functionCalling: false,
285
- vision: true,
286
- codeExecution: true,
287
- maxContextWindow: 128000,
288
- maxOutputTokens: 8192,
289
- };
290
- }
291
- }