vibeman 0.0.0 → 0.0.1

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 (220) hide show
  1. package/README.md +12 -0
  2. package/dist/index.js +116 -0
  3. package/dist/runtime/api/.tsbuildinfo +1 -0
  4. package/dist/runtime/api/agent/agent-service.d.ts +226 -0
  5. package/dist/runtime/api/agent/agent-service.js +901 -0
  6. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.d.ts +61 -0
  7. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.js +373 -0
  8. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.d.ts +34 -0
  9. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.js +281 -0
  10. package/dist/runtime/api/agent/ai-providers/index.d.ts +9 -0
  11. package/dist/runtime/api/agent/ai-providers/index.js +7 -0
  12. package/dist/runtime/api/agent/ai-providers/types.d.ts +180 -0
  13. package/dist/runtime/api/agent/ai-providers/types.js +5 -0
  14. package/dist/runtime/api/agent/codex-cli-provider.test.d.ts +1 -0
  15. package/dist/runtime/api/agent/codex-cli-provider.test.js +88 -0
  16. package/dist/runtime/api/agent/core-agent-service.d.ts +119 -0
  17. package/dist/runtime/api/agent/core-agent-service.js +267 -0
  18. package/dist/runtime/api/agent/parsers.d.ts +15 -0
  19. package/dist/runtime/api/agent/parsers.js +241 -0
  20. package/dist/runtime/api/agent/prompt-service.d.ts +17 -0
  21. package/dist/runtime/api/agent/prompt-service.js +340 -0
  22. package/dist/runtime/api/agent/routing-policy.d.ts +188 -0
  23. package/dist/runtime/api/agent/routing-policy.js +246 -0
  24. package/dist/runtime/api/api/router-helpers.d.ts +32 -0
  25. package/dist/runtime/api/api/router-helpers.js +31 -0
  26. package/dist/runtime/api/api/routers/ai.d.ts +188 -0
  27. package/dist/runtime/api/api/routers/ai.js +410 -0
  28. package/dist/runtime/api/api/routers/executions.d.ts +98 -0
  29. package/dist/runtime/api/api/routers/executions.js +103 -0
  30. package/dist/runtime/api/api/routers/git.d.ts +45 -0
  31. package/dist/runtime/api/api/routers/git.js +35 -0
  32. package/dist/runtime/api/api/routers/settings.d.ts +139 -0
  33. package/dist/runtime/api/api/routers/settings.js +113 -0
  34. package/dist/runtime/api/api/routers/tasks.d.ts +141 -0
  35. package/dist/runtime/api/api/routers/tasks.js +238 -0
  36. package/dist/runtime/api/api/routers/workflows.d.ts +268 -0
  37. package/dist/runtime/api/api/routers/workflows.js +308 -0
  38. package/dist/runtime/api/api/routers/worktrees.d.ts +102 -0
  39. package/dist/runtime/api/api/routers/worktrees.js +80 -0
  40. package/dist/runtime/api/api/trpc.d.ts +118 -0
  41. package/dist/runtime/api/api/trpc.js +34 -0
  42. package/dist/runtime/api/index.d.ts +9 -0
  43. package/dist/runtime/api/index.js +125 -0
  44. package/dist/runtime/api/lib/id-generator.d.ts +70 -0
  45. package/dist/runtime/api/lib/id-generator.js +123 -0
  46. package/dist/runtime/api/lib/image-paste-drop-extension.d.ts +26 -0
  47. package/dist/runtime/api/lib/image-paste-drop-extension.js +125 -0
  48. package/dist/runtime/api/lib/logger.d.ts +11 -0
  49. package/dist/runtime/api/lib/logger.js +188 -0
  50. package/dist/runtime/api/lib/markdown-utils.d.ts +8 -0
  51. package/dist/runtime/api/lib/markdown-utils.js +282 -0
  52. package/dist/runtime/api/lib/markdown-utils.test.d.ts +1 -0
  53. package/dist/runtime/api/lib/markdown-utils.test.js +348 -0
  54. package/dist/runtime/api/lib/server/agent-service-singleton.d.ts +6 -0
  55. package/dist/runtime/api/lib/server/agent-service-singleton.js +27 -0
  56. package/dist/runtime/api/lib/server/git-service-singleton.d.ts +6 -0
  57. package/dist/runtime/api/lib/server/git-service-singleton.js +47 -0
  58. package/dist/runtime/api/lib/server/project-root.d.ts +2 -0
  59. package/dist/runtime/api/lib/server/project-root.js +38 -0
  60. package/dist/runtime/api/lib/server/task-service-singleton.d.ts +7 -0
  61. package/dist/runtime/api/lib/server/task-service-singleton.js +58 -0
  62. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.d.ts +7 -0
  63. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.js +57 -0
  64. package/dist/runtime/api/lib/tiptap-utils.clamp-selection.test.d.ts +1 -0
  65. package/dist/runtime/api/lib/tiptap-utils.clamp-selection.test.js +27 -0
  66. package/dist/runtime/api/lib/tiptap-utils.d.ts +130 -0
  67. package/dist/runtime/api/lib/tiptap-utils.js +327 -0
  68. package/dist/runtime/api/lib/trpc/client.d.ts +1 -0
  69. package/dist/runtime/api/lib/trpc/client.js +5 -0
  70. package/dist/runtime/api/lib/trpc/server.d.ts +822 -0
  71. package/dist/runtime/api/lib/trpc/server.js +11 -0
  72. package/dist/runtime/api/lib/trpc/ws-server.d.ts +8 -0
  73. package/dist/runtime/api/lib/trpc/ws-server.js +33 -0
  74. package/dist/runtime/api/persistence/database-service.d.ts +14 -0
  75. package/dist/runtime/api/persistence/database-service.js +74 -0
  76. package/dist/runtime/api/persistence/execution-log-persistence.d.ts +90 -0
  77. package/dist/runtime/api/persistence/execution-log-persistence.js +410 -0
  78. package/dist/runtime/api/persistence/execution-log-persistence.test.d.ts +1 -0
  79. package/dist/runtime/api/persistence/execution-log-persistence.test.js +170 -0
  80. package/dist/runtime/api/router.d.ts +825 -0
  81. package/dist/runtime/api/router.js +56 -0
  82. package/dist/runtime/api/settings-service.d.ts +110 -0
  83. package/dist/runtime/api/settings-service.js +611 -0
  84. package/dist/runtime/api/tasks/file-watcher.d.ts +23 -0
  85. package/dist/runtime/api/tasks/file-watcher.js +88 -0
  86. package/dist/runtime/api/tasks/task-file-parser.d.ts +13 -0
  87. package/dist/runtime/api/tasks/task-file-parser.js +161 -0
  88. package/dist/runtime/api/tasks/task-service.d.ts +36 -0
  89. package/dist/runtime/api/tasks/task-service.js +173 -0
  90. package/dist/runtime/api/types/index.d.ts +179 -0
  91. package/dist/runtime/api/types/index.js +1 -0
  92. package/dist/runtime/api/types/settings.d.ts +81 -0
  93. package/dist/runtime/api/types/settings.js +2 -0
  94. package/dist/runtime/api/types.d.ts +2 -0
  95. package/dist/runtime/api/types.js +1 -0
  96. package/dist/runtime/api/utils/env.d.ts +6 -0
  97. package/dist/runtime/api/utils/env.js +12 -0
  98. package/dist/runtime/api/utils/stripNextEnv.d.ts +7 -0
  99. package/dist/runtime/api/utils/stripNextEnv.js +22 -0
  100. package/dist/runtime/api/utils/title-slug.d.ts +6 -0
  101. package/dist/runtime/api/utils/title-slug.js +77 -0
  102. package/dist/runtime/api/utils/url.d.ts +2 -0
  103. package/dist/runtime/api/utils/url.js +19 -0
  104. package/dist/runtime/api/vcs/git-history-service.d.ts +57 -0
  105. package/dist/runtime/api/vcs/git-history-service.js +228 -0
  106. package/dist/runtime/api/vcs/git-service.d.ts +127 -0
  107. package/dist/runtime/api/vcs/git-service.js +284 -0
  108. package/dist/runtime/api/vcs/worktree-service.d.ts +93 -0
  109. package/dist/runtime/api/vcs/worktree-service.js +506 -0
  110. package/dist/runtime/api/vcs/worktree-service.test.d.ts +1 -0
  111. package/dist/runtime/api/vcs/worktree-service.test.js +20 -0
  112. package/dist/runtime/api/workflows/quality-pipeline.d.ts +58 -0
  113. package/dist/runtime/api/workflows/quality-pipeline.js +400 -0
  114. package/dist/runtime/api/workflows/vibing-orchestrator.d.ts +313 -0
  115. package/dist/runtime/api/workflows/vibing-orchestrator.js +1861 -0
  116. package/dist/runtime/web/.next/BUILD_ID +1 -0
  117. package/dist/runtime/web/.next/app-build-manifest.json +59 -0
  118. package/dist/runtime/web/.next/app-path-routes-manifest.json +7 -0
  119. package/dist/runtime/web/.next/build-manifest.json +33 -0
  120. package/dist/runtime/web/.next/package.json +1 -0
  121. package/dist/runtime/web/.next/prerender-manifest.json +61 -0
  122. package/dist/runtime/web/.next/react-loadable-manifest.json +39 -0
  123. package/dist/runtime/web/.next/required-server-files.json +334 -0
  124. package/dist/runtime/web/.next/routes-manifest.json +62 -0
  125. package/dist/runtime/web/.next/server/app/_not-found/page.js +2 -0
  126. package/dist/runtime/web/.next/server/app/_not-found/page.js.nft.json +1 -0
  127. package/dist/runtime/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  128. package/dist/runtime/web/.next/server/app/_not-found.html +7 -0
  129. package/dist/runtime/web/.next/server/app/_not-found.meta +8 -0
  130. package/dist/runtime/web/.next/server/app/_not-found.rsc +22 -0
  131. package/dist/runtime/web/.next/server/app/api/health/route.js +1 -0
  132. package/dist/runtime/web/.next/server/app/api/health/route.js.nft.json +1 -0
  133. package/dist/runtime/web/.next/server/app/api/health/route_client-reference-manifest.js +1 -0
  134. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js +1 -0
  135. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js.nft.json +1 -0
  136. package/dist/runtime/web/.next/server/app/api/images/[...path]/route_client-reference-manifest.js +1 -0
  137. package/dist/runtime/web/.next/server/app/api/upload/route.js +1 -0
  138. package/dist/runtime/web/.next/server/app/api/upload/route.js.nft.json +1 -0
  139. package/dist/runtime/web/.next/server/app/api/upload/route_client-reference-manifest.js +1 -0
  140. package/dist/runtime/web/.next/server/app/index.html +7 -0
  141. package/dist/runtime/web/.next/server/app/index.meta +7 -0
  142. package/dist/runtime/web/.next/server/app/index.rsc +27 -0
  143. package/dist/runtime/web/.next/server/app/page.js +147 -0
  144. package/dist/runtime/web/.next/server/app/page.js.nft.json +1 -0
  145. package/dist/runtime/web/.next/server/app/page_client-reference-manifest.js +1 -0
  146. package/dist/runtime/web/.next/server/app-paths-manifest.json +7 -0
  147. package/dist/runtime/web/.next/server/chunks/217.js +1 -0
  148. package/dist/runtime/web/.next/server/chunks/383.js +6 -0
  149. package/dist/runtime/web/.next/server/chunks/458.js +1 -0
  150. package/dist/runtime/web/.next/server/chunks/576.js +18 -0
  151. package/dist/runtime/web/.next/server/chunks/635.js +22 -0
  152. package/dist/runtime/web/.next/server/chunks/761.js +1 -0
  153. package/dist/runtime/web/.next/server/chunks/777.js +3 -0
  154. package/dist/runtime/web/.next/server/chunks/825.js +1 -0
  155. package/dist/runtime/web/.next/server/chunks/838.js +1 -0
  156. package/dist/runtime/web/.next/server/chunks/973.js +15 -0
  157. package/dist/runtime/web/.next/server/functions-config-manifest.json +4 -0
  158. package/dist/runtime/web/.next/server/middleware-build-manifest.js +1 -0
  159. package/dist/runtime/web/.next/server/middleware-manifest.json +6 -0
  160. package/dist/runtime/web/.next/server/middleware-react-loadable-manifest.js +1 -0
  161. package/dist/runtime/web/.next/server/next-font-manifest.js +1 -0
  162. package/dist/runtime/web/.next/server/next-font-manifest.json +1 -0
  163. package/dist/runtime/web/.next/server/pages/404.html +7 -0
  164. package/dist/runtime/web/.next/server/pages/500.html +1 -0
  165. package/dist/runtime/web/.next/server/pages/_app.js +1 -0
  166. package/dist/runtime/web/.next/server/pages/_app.js.nft.json +1 -0
  167. package/dist/runtime/web/.next/server/pages/_document.js +1 -0
  168. package/dist/runtime/web/.next/server/pages/_document.js.nft.json +1 -0
  169. package/dist/runtime/web/.next/server/pages/_error.js +19 -0
  170. package/dist/runtime/web/.next/server/pages/_error.js.nft.json +1 -0
  171. package/dist/runtime/web/.next/server/pages-manifest.json +6 -0
  172. package/dist/runtime/web/.next/server/server-reference-manifest.js +1 -0
  173. package/dist/runtime/web/.next/server/server-reference-manifest.json +1 -0
  174. package/dist/runtime/web/.next/server/webpack-runtime.js +1 -0
  175. package/dist/runtime/web/.next/static/1HR8N0rJkCvFRtbTPJMyH/_buildManifest.js +1 -0
  176. package/dist/runtime/web/.next/static/1HR8N0rJkCvFRtbTPJMyH/_ssgManifest.js +1 -0
  177. package/dist/runtime/web/.next/static/chunks/18-15c10d3288afef2e.js +1 -0
  178. package/dist/runtime/web/.next/static/chunks/1c0ca389.537bbe362e3ffbd9.js +3 -0
  179. package/dist/runtime/web/.next/static/chunks/22747d63-ad5da0c19f4cfe41.js +71 -0
  180. package/dist/runtime/web/.next/static/chunks/277-0142a939f08738c3.js +63 -0
  181. package/dist/runtime/web/.next/static/chunks/355.056c2645878a799a.js +1 -0
  182. package/dist/runtime/web/.next/static/chunks/420.a5ccf151c9e2b2f1.js +1 -0
  183. package/dist/runtime/web/.next/static/chunks/439.1be0c6242fd248d5.js +15 -0
  184. package/dist/runtime/web/.next/static/chunks/440.c52e7c0f797e22b2.js +1 -0
  185. package/dist/runtime/web/.next/static/chunks/575-e2478287c27da87b.js +1 -0
  186. package/dist/runtime/web/.next/static/chunks/691.920d88c115087314.js +1 -0
  187. package/dist/runtime/web/.next/static/chunks/765-e838910065b50c3d.js +1 -0
  188. package/dist/runtime/web/.next/static/chunks/87c73c54-09e1ba5c70e60a51.js +1 -0
  189. package/dist/runtime/web/.next/static/chunks/891cff7f.0f71fc028f87e683.js +1 -0
  190. package/dist/runtime/web/.next/static/chunks/8bb4d8db-3e2aa02b0a2384b9.js +1 -0
  191. package/dist/runtime/web/.next/static/chunks/9af238c7-271a911d4e99ab18.js +1 -0
  192. package/dist/runtime/web/.next/static/chunks/app/_not-found/page-1cb74d1cba27d0ab.js +1 -0
  193. package/dist/runtime/web/.next/static/chunks/app/api/health/route-105a61ae865ba536.js +1 -0
  194. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-105a61ae865ba536.js +1 -0
  195. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-105a61ae865ba536.js +1 -0
  196. package/dist/runtime/web/.next/static/chunks/app/layout-dc0cfd29075b2160.js +1 -0
  197. package/dist/runtime/web/.next/static/chunks/app/page-f34a8b196b18850b.js +1 -0
  198. package/dist/runtime/web/.next/static/chunks/cac567b0-5b77dd12911823cd.js +1 -0
  199. package/dist/runtime/web/.next/static/chunks/framework-2518f1345b5b2806.js +1 -0
  200. package/dist/runtime/web/.next/static/chunks/main-17665e5e39de9a8a.js +1 -0
  201. package/dist/runtime/web/.next/static/chunks/main-app-c0b0f5ba4f7f9d75.js +1 -0
  202. package/dist/runtime/web/.next/static/chunks/pages/_app-d6f6b3bbc3d81ee1.js +1 -0
  203. package/dist/runtime/web/.next/static/chunks/pages/_error-75a96cf1997cc3b9.js +1 -0
  204. package/dist/runtime/web/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  205. package/dist/runtime/web/.next/static/chunks/webpack-c8de37305b4635cf.js +1 -0
  206. package/dist/runtime/web/.next/static/css/08c950681f1a9a92.css +1 -0
  207. package/dist/runtime/web/.next/static/css/2728291c68f99cb1.css +3 -0
  208. package/dist/runtime/web/.next/static/css/521bd69cc298cd1a.css +1 -0
  209. package/dist/runtime/web/.next/static/css/537e22821e101b87.css +1 -0
  210. package/dist/runtime/web/.next/static/media/19cfc7226ec3afaa-s.woff2 +0 -0
  211. package/dist/runtime/web/.next/static/media/21350d82a1f187e9-s.woff2 +0 -0
  212. package/dist/runtime/web/.next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
  213. package/dist/runtime/web/.next/static/media/ba9851c3c22cd980-s.woff2 +0 -0
  214. package/dist/runtime/web/.next/static/media/c5fe6dc8356a8c31-s.woff2 +0 -0
  215. package/dist/runtime/web/.next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  216. package/dist/runtime/web/.next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
  217. package/dist/runtime/web/package.json +65 -0
  218. package/dist/runtime/web/server.js +44 -0
  219. package/dist/tsconfig.tsbuildinfo +1 -0
  220. package/package.json +80 -7
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Core Agent Service - Pure AI Execution Engine
3
+ * Provider-agnostic AI execution service
4
+ */
5
+ import { EventEmitter } from 'events';
6
+ import { log } from '../lib/logger.js';
7
+ import { generateId } from '../lib/id-generator.js';
8
+ /**
9
+ * Pure AI Execution Service
10
+ * Manages AI providers and executions without business logic
11
+ */
12
+ export class CoreAgentService extends EventEmitter {
13
+ constructor(config = {}) {
14
+ super();
15
+ this.providers = new Map();
16
+ this.defaultProvider = null;
17
+ this.executions = new Map();
18
+ this.config = {
19
+ executionTimeout: config.executionTimeout || 30 * 60 * 1000, // 30 minutes
20
+ ...config,
21
+ };
22
+ }
23
+ /**
24
+ * Register an AI provider
25
+ */
26
+ registerProvider(name, provider) {
27
+ this.providers.set(name, provider);
28
+ log.debug(`Registered AI provider: ${name}`, undefined, 'core-agent-service');
29
+ // Set as default if it's the first provider or matches config
30
+ if (!this.defaultProvider || name === this.config.defaultProvider) {
31
+ this.defaultProvider = name;
32
+ log.debug(`Set default provider: ${name}`, undefined, 'core-agent-service');
33
+ }
34
+ }
35
+ /**
36
+ * Set default provider
37
+ */
38
+ setDefaultProvider(name) {
39
+ if (!this.providers.has(name)) {
40
+ throw new Error(`Provider ${name} not registered`);
41
+ }
42
+ this.defaultProvider = name;
43
+ log.debug(`Changed default provider to: ${name}`, undefined, 'core-agent-service');
44
+ }
45
+ /**
46
+ * Get default provider name
47
+ */
48
+ getDefaultProvider() {
49
+ return this.defaultProvider;
50
+ }
51
+ /**
52
+ * Get provider by name
53
+ */
54
+ getProvider(name) {
55
+ return this.providers.get(name) || null;
56
+ }
57
+ /**
58
+ * Get all registered providers
59
+ */
60
+ getProviders() {
61
+ return new Map(this.providers);
62
+ }
63
+ /**
64
+ * Execute a prompt with streaming
65
+ */
66
+ async execute(request) {
67
+ // Determine which provider to use
68
+ const providerName = request.provider || this.defaultProvider;
69
+ if (!providerName) {
70
+ throw new Error('No provider specified and no default provider set');
71
+ }
72
+ const provider = this.providers.get(providerName);
73
+ if (!provider) {
74
+ throw new Error(`Provider ${providerName} not found`);
75
+ }
76
+ const executionId = request.executionId || this.generateExecutionId();
77
+ const abortController = new AbortController();
78
+ // Set timeout
79
+ const timeoutId = setTimeout(() => {
80
+ abortController.abort();
81
+ }, this.config.executionTimeout);
82
+ const execution = {
83
+ id: executionId,
84
+ provider: provider.name,
85
+ status: 'pending',
86
+ startTime: new Date().toISOString(),
87
+ messages: [],
88
+ abortController,
89
+ };
90
+ this.executions.set(executionId, execution);
91
+ // Emit execution created event
92
+ this.emit('executionCreated', { executionId, provider: execution.provider });
93
+ try {
94
+ execution.status = 'running';
95
+ this.emit('executionStarted', { executionId });
96
+ const options = {
97
+ ...request.options,
98
+ abortSignal: abortController.signal,
99
+ };
100
+ let result = '';
101
+ const messages = [];
102
+ // Execute with streaming
103
+ for await (const message of provider.execute(request.prompt, options)) {
104
+ execution.messages.push(message);
105
+ // Emit message events
106
+ this.emit('executionMessage', {
107
+ executionId,
108
+ message,
109
+ });
110
+ // Collect assistant messages
111
+ if (message.type === 'assistant') {
112
+ const content = message.content;
113
+ messages.push(content);
114
+ // Emit update for UI streaming
115
+ this.emit('executionUpdate', {
116
+ executionId,
117
+ status: execution.status,
118
+ message,
119
+ });
120
+ }
121
+ // Handle result
122
+ if (message.type === 'result') {
123
+ const resultMsg = message;
124
+ if (resultMsg.success) {
125
+ result = resultMsg.result || messages.join('\n');
126
+ execution.result = result;
127
+ execution.usage = resultMsg.usage;
128
+ }
129
+ else {
130
+ throw new Error(resultMsg.error || 'Execution failed');
131
+ }
132
+ }
133
+ }
134
+ // Mark as completed
135
+ execution.status = 'completed';
136
+ execution.endTime = new Date().toISOString();
137
+ clearTimeout(timeoutId);
138
+ // Emit completion event
139
+ this.emit('executionCompleted', {
140
+ executionId,
141
+ result,
142
+ usage: execution.usage,
143
+ });
144
+ return result;
145
+ }
146
+ catch (error) {
147
+ clearTimeout(timeoutId);
148
+ // Handle cancellation
149
+ if (abortController.signal.aborted) {
150
+ execution.status = 'cancelled';
151
+ execution.error = 'Execution cancelled';
152
+ this.emit('executionCancelled', { executionId });
153
+ }
154
+ else {
155
+ execution.status = 'failed';
156
+ execution.error = error instanceof Error ? error.message : String(error);
157
+ this.emit('executionFailed', {
158
+ executionId,
159
+ error: execution.error,
160
+ });
161
+ }
162
+ execution.endTime = new Date().toISOString();
163
+ throw error;
164
+ }
165
+ }
166
+ /**
167
+ * Get execution status
168
+ */
169
+ getExecutionStatus(executionId) {
170
+ const execution = this.executions.get(executionId);
171
+ if (!execution)
172
+ return null;
173
+ // Return copy without internal fields
174
+ const { abortController, ...publicState } = execution;
175
+ return publicState;
176
+ }
177
+ /**
178
+ * Get execution messages
179
+ */
180
+ getExecutionMessages(executionId) {
181
+ const execution = this.executions.get(executionId);
182
+ return execution ? [...execution.messages] : [];
183
+ }
184
+ /**
185
+ * Stop an execution
186
+ */
187
+ async stopExecution(executionId) {
188
+ const execution = this.executions.get(executionId);
189
+ if (!execution) {
190
+ throw new Error(`Execution ${executionId} not found`);
191
+ }
192
+ if (execution.status !== 'running') {
193
+ throw new Error(`Execution ${executionId} is not running`);
194
+ }
195
+ if (execution.abortController) {
196
+ execution.abortController.abort();
197
+ execution.status = 'cancelled';
198
+ execution.endTime = new Date().toISOString();
199
+ this.emit('executionCancelled', { executionId });
200
+ }
201
+ }
202
+ /**
203
+ * Get all executions
204
+ */
205
+ getAllExecutions() {
206
+ return Array.from(this.executions.values()).map((e) => {
207
+ const { abortController, ...publicState } = e;
208
+ return publicState;
209
+ });
210
+ }
211
+ /**
212
+ * Clear completed executions
213
+ */
214
+ clearCompletedExecutions() {
215
+ let cleared = 0;
216
+ for (const [id, execution] of this.executions) {
217
+ if (['completed', 'failed', 'cancelled'].includes(execution.status)) {
218
+ this.executions.delete(id);
219
+ cleared++;
220
+ }
221
+ }
222
+ return cleared;
223
+ }
224
+ /**
225
+ * Validate all providers
226
+ */
227
+ async validateProviders() {
228
+ const results = new Map();
229
+ for (const [name, provider] of this.providers) {
230
+ try {
231
+ const status = await provider.validateSetup();
232
+ results.set(name, status);
233
+ }
234
+ catch (error) {
235
+ results.set(name, {
236
+ available: false,
237
+ error: error instanceof Error ? error.message : String(error),
238
+ models: [],
239
+ capabilities: provider.getCapabilities(),
240
+ });
241
+ }
242
+ }
243
+ return results;
244
+ }
245
+ /**
246
+ * Get available models from all providers
247
+ */
248
+ async getAvailableModels() {
249
+ const models = [];
250
+ for (const [name, provider] of this.providers) {
251
+ try {
252
+ const providerModels = await provider.detectAvailableModels();
253
+ models.push(...providerModels);
254
+ }
255
+ catch (error) {
256
+ log.warn(`Failed to get models from provider ${name}`, error, 'core-agent-service');
257
+ }
258
+ }
259
+ return models;
260
+ }
261
+ /**
262
+ * Generate execution ID
263
+ */
264
+ generateExecutionId() {
265
+ return generateId('exec');
266
+ }
267
+ }
@@ -0,0 +1,15 @@
1
+ export declare function parseImprovementResult(result: string, originalData: {
2
+ title: string;
3
+ type: string;
4
+ priority: string;
5
+ content: string;
6
+ }): {
7
+ type: string;
8
+ priority: string;
9
+ content: string;
10
+ };
11
+ export declare function parseReviewResult(result: string): {
12
+ reviewSummary: string;
13
+ recommendations: string[];
14
+ qualityScore: number;
15
+ };
@@ -0,0 +1,241 @@
1
+ import { log } from '../lib/logger.js';
2
+ // Extract the last valid JSON object from mixed text.
3
+ // It scans for fenced ```json blocks and balanced-brace objects, then returns the last one that parses.
4
+ function extractLastValidJson(text) {
5
+ if (!text)
6
+ return null;
7
+ const candidates = [];
8
+ // 1) Fenced JSON blocks
9
+ const fencedRe = /```json\s*([\s\S]*?)\s*```/gi;
10
+ let m;
11
+ while ((m = fencedRe.exec(text)) !== null) {
12
+ if (m[1])
13
+ candidates.push(m[1]);
14
+ }
15
+ // 2) Balanced brace objects
16
+ let depth = 0;
17
+ let inStr = false;
18
+ let start = -1;
19
+ let prev = '';
20
+ for (let i = 0; i < text.length; i++) {
21
+ const ch = text[i];
22
+ if (inStr) {
23
+ if (ch === '"' && prev !== '\\')
24
+ inStr = false;
25
+ }
26
+ else {
27
+ if (ch === '"')
28
+ inStr = true;
29
+ else if (ch === '{') {
30
+ if (depth === 0)
31
+ start = i;
32
+ depth++;
33
+ }
34
+ else if (ch === '}') {
35
+ if (depth > 0)
36
+ depth--;
37
+ if (depth === 0 && start >= 0) {
38
+ candidates.push(text.slice(start, i + 1));
39
+ start = -1;
40
+ }
41
+ }
42
+ }
43
+ prev = ch;
44
+ }
45
+ for (let i = candidates.length - 1; i >= 0; i--) {
46
+ const c = candidates[i].trim();
47
+ try {
48
+ JSON.parse(c);
49
+ return c;
50
+ }
51
+ catch {
52
+ // ignore
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+ /**
58
+ * Manually parse a JSON-like structure that may have unescaped strings
59
+ * This is a fallback for when JSON.parse fails due to unescaped content
60
+ */
61
+ function parseJsonManually(jsonStr) {
62
+ try {
63
+ // Extract type and priority with simple regex (these are usually well-formed)
64
+ const typeMatch = jsonStr.match(/"type":\s*"([^"]+)"/);
65
+ const priorityMatch = jsonStr.match(/"priority":\s*"([^"]+)"/);
66
+ // For content, find the start and extract everything until the closing brace
67
+ const contentStart = jsonStr.indexOf('"content":');
68
+ if (contentStart === -1)
69
+ return null;
70
+ const contentValueStart = jsonStr.indexOf('"', contentStart + 10);
71
+ if (contentValueStart === -1)
72
+ return null;
73
+ // Find the last occurrence of "}` at the end - this marks the end of our JSON
74
+ const jsonEnd = jsonStr.lastIndexOf('}');
75
+ if (jsonEnd === -1)
76
+ return null;
77
+ // Find the quote that comes before the closing brace
78
+ // Work backwards from the closing brace to find the last quote
79
+ let contentEnd = -1;
80
+ for (let i = jsonEnd - 1; i > contentValueStart; i--) {
81
+ if (jsonStr[i] === '"') {
82
+ // Check if this quote is escaped
83
+ let backslashCount = 0;
84
+ for (let j = i - 1; j >= 0 && jsonStr[j] === '\\'; j--) {
85
+ backslashCount++;
86
+ }
87
+ // If even number of backslashes (including 0), quote is not escaped
88
+ if (backslashCount % 2 === 0) {
89
+ contentEnd = i;
90
+ break;
91
+ }
92
+ }
93
+ }
94
+ if (contentEnd === -1)
95
+ return null;
96
+ // Extract the raw content
97
+ const rawContent = jsonStr.substring(contentValueStart + 1, contentEnd);
98
+ if (typeMatch && priorityMatch && rawContent) {
99
+ // Clean up the content - unescape common escape sequences
100
+ const content = rawContent
101
+ .replace(/\\n/g, '\n')
102
+ .replace(/\\r/g, '\r')
103
+ .replace(/\\t/g, '\t')
104
+ .replace(/\\"/g, '"')
105
+ .replace(/\\\\/g, '\\');
106
+ return {
107
+ type: typeMatch[1],
108
+ priority: priorityMatch[1],
109
+ content: content,
110
+ };
111
+ }
112
+ return null;
113
+ }
114
+ catch (error) {
115
+ const errMsg = error instanceof Error ? error.message : String(error);
116
+ log.warn('Manual JSON parsing failed', { error: errMsg }, 'result-parsers');
117
+ return null;
118
+ }
119
+ }
120
+ export function parseImprovementResult(result, originalData) {
121
+ try {
122
+ const jsonBlock = extractLastValidJson(result);
123
+ if (jsonBlock) {
124
+ // Try parsing as-is first
125
+ try {
126
+ const parsed = JSON.parse(jsonBlock);
127
+ if (parsed.type && parsed.priority && parsed.content) {
128
+ // Validate type and priority values
129
+ const validTypes = ['feature', 'bug', 'chore', 'refactor', 'test', 'doc'];
130
+ const validPriorities = ['high', 'medium', 'low'];
131
+ const normalizedType = String(parsed.type).toLowerCase();
132
+ const normalizedPriority = String(parsed.priority).toLowerCase();
133
+ return {
134
+ type: validTypes.includes(normalizedType) ? normalizedType : originalData.type,
135
+ priority: validPriorities.includes(normalizedPriority)
136
+ ? normalizedPriority
137
+ : originalData.priority,
138
+ content: String(parsed.content).trim(),
139
+ };
140
+ }
141
+ }
142
+ catch (parseError) {
143
+ // If JSON parsing fails, try to fix common issues
144
+ const parseErrMsg = parseError instanceof Error ? parseError.message : String(parseError);
145
+ log.warn('Initial JSON parse failed, attempting to clean JSON', { error: parseErrMsg }, 'result-parsers');
146
+ try {
147
+ // Attempt to manually parse the JSON structure
148
+ const parsed = parseJsonManually(jsonBlock);
149
+ if (parsed && parsed.type && parsed.priority && parsed.content) {
150
+ const validTypes = ['feature', 'bug', 'chore', 'refactor', 'test', 'doc'];
151
+ const validPriorities = ['high', 'medium', 'low'];
152
+ const normalizedType = String(parsed.type).toLowerCase();
153
+ const normalizedPriority = String(parsed.priority).toLowerCase();
154
+ return {
155
+ type: validTypes.includes(normalizedType) ? normalizedType : originalData.type,
156
+ priority: validPriorities.includes(normalizedPriority)
157
+ ? normalizedPriority
158
+ : originalData.priority,
159
+ content: String(parsed.content).trim(),
160
+ };
161
+ }
162
+ }
163
+ catch (secondError) {
164
+ const secondErrMsg = secondError instanceof Error ? secondError.message : String(secondError);
165
+ log.error('JSON cleaning also failed', { error: secondErrMsg }, 'result-parsers');
166
+ }
167
+ }
168
+ }
169
+ }
170
+ catch (error) {
171
+ const errMsg = error instanceof Error ? error.message : String(error);
172
+ log.error('Failed to parse improvement result', { error: errMsg, result }, 'result-parsers');
173
+ }
174
+ return {
175
+ type: originalData.type,
176
+ priority: originalData.priority,
177
+ content: result.trim() || originalData.content,
178
+ };
179
+ }
180
+ export function parseReviewResult(result) {
181
+ try {
182
+ const jsonBlock = extractLastValidJson(result);
183
+ if (jsonBlock) {
184
+ const parsed = JSON.parse(jsonBlock);
185
+ if (parsed.reviewSummary &&
186
+ parsed.recommendations &&
187
+ (typeof parsed.qualityScore === 'number' || typeof parsed.score === 'number')) {
188
+ const score = typeof parsed.qualityScore === 'number' ? parsed.qualityScore : parsed.score;
189
+ return {
190
+ reviewSummary: String(parsed.reviewSummary),
191
+ recommendations: Array.isArray(parsed.recommendations)
192
+ ? parsed.recommendations.map((r) => String(r))
193
+ : [String(parsed.recommendations)],
194
+ qualityScore: Math.max(0, Math.min(100, Number(score))),
195
+ };
196
+ }
197
+ }
198
+ }
199
+ catch (error) {
200
+ log.error('Failed to parse review result', error, 'result-parsers');
201
+ }
202
+ // Fallback: parse simple plaintext format like
203
+ // Score: 75/100\nSummary: ...\nRecommendations:\n- item
204
+ try {
205
+ const scoreMatch = result.match(/Score\s*:\s*(\d{1,3})(?:\s*\/\s*100)?/i);
206
+ const summaryMatch = result.match(/Summary\s*:\s*([\s\S]*?)(?:\n\s*Recommendations\s*:|$)/i);
207
+ const recBlockMatch = result.match(/Recommendations\s*:\s*([\s\S]*)$/i);
208
+ const score = scoreMatch ? Math.max(0, Math.min(100, Number(scoreMatch[1]))) : 75;
209
+ const reviewSummary = summaryMatch
210
+ ? summaryMatch[1].trim()
211
+ : result.length > 200
212
+ ? result.substring(0, 200) + '...'
213
+ : result;
214
+ let recommendations = [];
215
+ if (recBlockMatch) {
216
+ const lines = recBlockMatch[1]
217
+ .split(/\r?\n/)
218
+ .map((l) => l.trim())
219
+ .filter(Boolean);
220
+ // Take bullet-like lines or fallback to one-liner
221
+ const bullets = lines
222
+ .filter((l) => /^[-*•\d]/.test(l))
223
+ .map((l) => l.replace(/^[-*•\d.)\s]+/, '').trim());
224
+ recommendations = bullets.length ? bullets : lines.slice(0, 5);
225
+ if (!recommendations.length)
226
+ recommendations = ['Review completed - see output for details'];
227
+ }
228
+ else {
229
+ recommendations = ['Review completed - see output for details'];
230
+ }
231
+ return { reviewSummary, recommendations, qualityScore: score };
232
+ }
233
+ catch {
234
+ // fall back to generic
235
+ }
236
+ return {
237
+ reviewSummary: result.length > 200 ? result.substring(0, 200) + '...' : result,
238
+ recommendations: ['Review completed - see output for details'],
239
+ qualityScore: 75,
240
+ };
241
+ }
@@ -0,0 +1,17 @@
1
+ import type { Task, WorktreeInfo } from '../types/index.js';
2
+ import type { TaskService } from '../tasks/task-service.js';
3
+ export declare class PromptService {
4
+ private projectRoot;
5
+ private taskService;
6
+ constructor(projectRoot: string, taskService: TaskService);
7
+ generateImprovementPrompt(task: Task, taskData: {
8
+ title: string;
9
+ type: string;
10
+ priority: string;
11
+ content: string;
12
+ }): Promise<string>;
13
+ generateTaskPrompt(task: Task): Promise<string>;
14
+ generateAIMergePrompt(task: Task, worktree: WorktreeInfo, baseBranch?: string): Promise<string>;
15
+ generateReviewPrompt(task: Task, worktree: WorktreeInfo, reviewContext?: string): Promise<string>;
16
+ }
17
+ export declare function getQualityChecksDetectionPrompt(): string;