vibeman 0.0.1 → 0.0.3
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.
- package/dist/index.js +5 -7
- package/dist/runtime/api/.tsbuildinfo +1 -1
- package/dist/runtime/api/agent/agent-service.d.ts +18 -19
- package/dist/runtime/api/agent/agent-service.js +61 -58
- package/dist/runtime/api/agent/ai-providers/claude-code-adapter.d.ts +2 -2
- package/dist/runtime/api/agent/ai-providers/claude-code-adapter.js +25 -36
- package/dist/runtime/api/agent/ai-providers/codex-cli-provider.d.ts +2 -0
- package/dist/runtime/api/agent/ai-providers/codex-cli-provider.js +109 -43
- package/dist/runtime/api/agent/ai-providers/types.d.ts +2 -0
- package/dist/runtime/api/agent/codex-cli-provider.test.js +83 -1
- package/dist/runtime/api/agent/parsers.d.ts +1 -0
- package/dist/runtime/api/agent/parsers.js +75 -8
- package/dist/runtime/api/agent/prompt-service.d.ts +14 -1
- package/dist/runtime/api/agent/prompt-service.js +123 -14
- package/dist/runtime/api/agent/prompt-service.test.js +230 -0
- package/dist/runtime/api/agent/routing-policy.d.ts +25 -42
- package/dist/runtime/api/agent/routing-policy.js +82 -132
- package/dist/runtime/api/agent/routing-policy.test.js +63 -0
- package/dist/runtime/api/api/routers/ai.d.ts +19 -7
- package/dist/runtime/api/api/routers/ai.js +9 -23
- package/dist/runtime/api/api/routers/executions.d.ts +4 -4
- package/dist/runtime/api/api/routers/executions.js +12 -21
- package/dist/runtime/api/api/routers/provider-config.d.ts +165 -0
- package/dist/runtime/api/api/routers/provider-config.js +252 -0
- package/dist/runtime/api/api/routers/tasks.d.ts +9 -9
- package/dist/runtime/api/api/routers/workflows.d.ts +23 -16
- package/dist/runtime/api/api/routers/workflows.js +30 -27
- package/dist/runtime/api/api/routers/worktrees.d.ts +4 -5
- package/dist/runtime/api/api/routers/worktrees.js +11 -11
- package/dist/runtime/api/api/trpc.d.ts +16 -16
- package/dist/runtime/api/index.js +2 -10
- package/dist/runtime/api/lib/local-config.d.ts +245 -0
- package/dist/runtime/api/lib/local-config.js +288 -0
- package/dist/runtime/api/lib/provider-detection.d.ts +59 -0
- package/dist/runtime/api/lib/provider-detection.js +244 -0
- package/dist/runtime/api/lib/server/bootstrap.d.ts +38 -0
- package/dist/runtime/api/lib/server/bootstrap.js +197 -0
- package/dist/runtime/api/lib/server/project-root.js +24 -1
- package/dist/runtime/api/lib/trpc/server.d.ts +143 -30
- package/dist/runtime/api/lib/trpc/server.js +8 -8
- package/dist/runtime/api/lib/trpc/ws-server.js +2 -2
- package/dist/runtime/api/router.d.ts +144 -31
- package/dist/runtime/api/router.js +9 -31
- package/dist/runtime/api/settings-service.js +51 -1
- package/dist/runtime/api/types/index.d.ts +8 -1
- package/dist/runtime/api/types/settings.d.ts +15 -2
- package/dist/runtime/api/workflows/vibing-orchestrator.d.ts +8 -3
- package/dist/runtime/api/workflows/vibing-orchestrator.js +214 -184
- package/dist/runtime/web/.next/BUILD_ID +1 -1
- package/dist/runtime/web/.next/app-build-manifest.json +19 -12
- package/dist/runtime/web/.next/app-path-routes-manifest.json +2 -1
- package/dist/runtime/web/.next/build-manifest.json +2 -2
- package/dist/runtime/web/.next/prerender-manifest.json +10 -10
- package/dist/runtime/web/.next/routes-manifest.json +8 -0
- package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js +1 -0
- package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js.nft.json +1 -0
- package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route_client-reference-manifest.js +1 -0
- package/dist/runtime/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/runtime/web/.next/server/app/_not-found.html +2 -2
- package/dist/runtime/web/.next/server/app/_not-found.rsc +5 -5
- package/dist/runtime/web/.next/server/app/api/health/route.js +1 -1
- package/dist/runtime/web/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js +1 -1
- package/dist/runtime/web/.next/server/app/api/images/[...path]/route_client-reference-manifest.js +1 -1
- package/dist/runtime/web/.next/server/app/api/upload/route.js +1 -1
- package/dist/runtime/web/.next/server/app/api/upload/route_client-reference-manifest.js +1 -1
- package/dist/runtime/web/.next/server/app/index.html +2 -2
- package/dist/runtime/web/.next/server/app/index.rsc +6 -6
- package/dist/runtime/web/.next/server/app/page.js +21 -21
- package/dist/runtime/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/runtime/web/.next/server/app-paths-manifest.json +2 -1
- package/dist/runtime/web/.next/server/chunks/458.js +1 -1
- package/dist/runtime/web/.next/server/pages/404.html +2 -2
- package/dist/runtime/web/.next/server/pages/500.html +1 -1
- package/dist/runtime/web/.next/server/pages-manifest.json +1 -1
- package/dist/runtime/web/.next/server/server-reference-manifest.json +1 -1
- package/dist/runtime/web/.next/static/5_15u1WQCxN1_eHZpldCv/_buildManifest.js +1 -0
- package/dist/runtime/web/.next/static/chunks/{277-0142a939f08738c3.js → 823-6f371a6e829adbba.js} +1 -1
- package/dist/runtime/web/.next/static/chunks/app/.vibeman/assets/images/[...path]/route-751c9265a65409e5.js +1 -0
- package/dist/runtime/web/.next/static/chunks/app/api/health/route-751c9265a65409e5.js +1 -0
- package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-751c9265a65409e5.js +1 -0
- package/dist/runtime/web/.next/static/chunks/app/api/upload/route-751c9265a65409e5.js +1 -0
- package/dist/runtime/web/.next/static/chunks/app/{layout-dc0cfd29075b2160.js → layout-8435322f09fd0975.js} +1 -1
- package/dist/runtime/web/.next/static/chunks/app/page-9fe7d75095b4ccec.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -1
- package/dist/runtime/api/lib/image-paste-drop-extension.d.ts +0 -26
- package/dist/runtime/api/lib/image-paste-drop-extension.js +0 -125
- package/dist/runtime/api/lib/markdown-utils.d.ts +0 -8
- package/dist/runtime/api/lib/markdown-utils.js +0 -282
- package/dist/runtime/api/lib/markdown-utils.test.js +0 -348
- package/dist/runtime/api/lib/tiptap-utils.clamp-selection.test.js +0 -27
- package/dist/runtime/api/lib/tiptap-utils.d.ts +0 -130
- package/dist/runtime/api/lib/tiptap-utils.js +0 -327
- package/dist/runtime/web/.next/static/1HR8N0rJkCvFRtbTPJMyH/_buildManifest.js +0 -1
- package/dist/runtime/web/.next/static/chunks/app/api/health/route-105a61ae865ba536.js +0 -1
- package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-105a61ae865ba536.js +0 -1
- package/dist/runtime/web/.next/static/chunks/app/api/upload/route-105a61ae865ba536.js +0 -1
- package/dist/runtime/web/.next/static/chunks/app/page-f34a8b196b18850b.js +0 -1
- /package/dist/runtime/api/{lib/markdown-utils.test.d.ts → agent/prompt-service.test.d.ts} +0 -0
- /package/dist/runtime/api/{lib/tiptap-utils.clamp-selection.test.d.ts → agent/routing-policy.test.d.ts} +0 -0
- /package/dist/runtime/web/.next/static/{1HR8N0rJkCvFRtbTPJMyH → 5_15u1WQCxN1_eHZpldCv}/_ssgManifest.js +0 -0
|
@@ -2,7 +2,7 @@ import { EventEmitter } from 'events';
|
|
|
2
2
|
import { Task, WorktreeInfo, AgentExecution, VibingPhase, QualityResults } from '../types/index.js';
|
|
3
3
|
import { TaskService } from '../tasks/task-service.js';
|
|
4
4
|
import { WorktreeService } from '../vcs/worktree-service.js';
|
|
5
|
-
import { RoutingPolicyManager, type ResolvedProvider } from './routing-policy.js';
|
|
5
|
+
import { RoutingPolicyManager, type RoutableOperation, type ResolvedProvider } from './routing-policy.js';
|
|
6
6
|
export interface AgentExecutionUpdate {
|
|
7
7
|
executionId: string;
|
|
8
8
|
status: AgentExecution['status'];
|
|
@@ -38,11 +38,6 @@ export declare class AgentService extends EventEmitter {
|
|
|
38
38
|
private getAgentConfig;
|
|
39
39
|
private initialize;
|
|
40
40
|
private setupEventForwarding;
|
|
41
|
-
/**
|
|
42
|
-
* Map core agent update to legacy format
|
|
43
|
-
* TODO: remove this later in a separate task, need to migrate the UI to handle raw message streaming
|
|
44
|
-
*/
|
|
45
|
-
private mapToLegacyUpdate;
|
|
46
41
|
/**
|
|
47
42
|
* Create a concise, human-readable line from a structured execution message
|
|
48
43
|
*/
|
|
@@ -62,8 +57,14 @@ export declare class AgentService extends EventEmitter {
|
|
|
62
57
|
qualityResults?: QualityResults;
|
|
63
58
|
lastLogs?: string[];
|
|
64
59
|
attempt?: number;
|
|
60
|
+
aiReview?: {
|
|
61
|
+
summary?: string;
|
|
62
|
+
recommendations?: string[];
|
|
63
|
+
score?: number;
|
|
64
|
+
};
|
|
65
65
|
};
|
|
66
66
|
providerOverride?: Partial<ResolvedProvider>;
|
|
67
|
+
workflowConfig?: import('../types/index.js').VibingConfig;
|
|
67
68
|
}): Promise<string>;
|
|
68
69
|
/**
|
|
69
70
|
* Build an appended system prompt with rerun context (reason, logs, failed checks)
|
|
@@ -97,13 +98,18 @@ export declare class AgentService extends EventEmitter {
|
|
|
97
98
|
type: string;
|
|
98
99
|
priority: string;
|
|
99
100
|
content: string;
|
|
101
|
+
title?: string;
|
|
100
102
|
executionId: string;
|
|
101
103
|
selectedModel?: string;
|
|
102
104
|
}>;
|
|
103
105
|
/**
|
|
104
106
|
* Perform AI code review of changes in a worktree
|
|
105
107
|
*/
|
|
106
|
-
aiReviewCode(taskId: string, reviewContext?: string,
|
|
108
|
+
aiReviewCode(taskId: string, reviewContext?: string, options?: {
|
|
109
|
+
overrides?: Partial<ResolvedProvider>;
|
|
110
|
+
executionId?: string;
|
|
111
|
+
workflowId?: string;
|
|
112
|
+
}): Promise<{
|
|
107
113
|
executionId: string;
|
|
108
114
|
reviewSummary: string;
|
|
109
115
|
recommendations: string[];
|
|
@@ -114,19 +120,11 @@ export declare class AgentService extends EventEmitter {
|
|
|
114
120
|
*/
|
|
115
121
|
aiMerge(taskId: string, options?: {
|
|
116
122
|
baseBranch?: string;
|
|
117
|
-
|
|
118
|
-
executionId
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
* Compatibility alias for aiReviewCode
|
|
122
|
-
* @deprecated Use aiReviewCode instead
|
|
123
|
-
* TODO: migrate UI to use aiReviewCode directly and remove this
|
|
124
|
-
*/
|
|
125
|
-
reviewCode(taskId: string, reviewContext?: string, overrides?: Partial<ResolvedProvider>): Promise<{
|
|
123
|
+
overrides?: Partial<ResolvedProvider>;
|
|
124
|
+
executionId?: string;
|
|
125
|
+
workflowId?: string;
|
|
126
|
+
}): Promise<{
|
|
126
127
|
executionId: string;
|
|
127
|
-
reviewSummary: string;
|
|
128
|
-
recommendations: string[];
|
|
129
|
-
qualityScore: number;
|
|
130
128
|
}>;
|
|
131
129
|
/**
|
|
132
130
|
* Get persistent execution logs
|
|
@@ -215,6 +213,7 @@ export declare class AgentService extends EventEmitter {
|
|
|
215
213
|
* Resolve provider for specific operation with failover support
|
|
216
214
|
*/
|
|
217
215
|
private resolveProviderForOperation;
|
|
216
|
+
previewProviderForOperation(operation: RoutableOperation, overrides?: Partial<ResolvedProvider>): Promise<ResolvedProvider>;
|
|
218
217
|
/**
|
|
219
218
|
* Execute with provider resolution and failover
|
|
220
219
|
*/
|
|
@@ -40,6 +40,7 @@ export class AgentService extends EventEmitter {
|
|
|
40
40
|
// TODO: need to be more granular, based on the task type and the toolset available for the AI provider
|
|
41
41
|
this.defaultTools = {
|
|
42
42
|
execute_task: fullTools,
|
|
43
|
+
quality_checks: fullTools,
|
|
43
44
|
improve_task: fullTools,
|
|
44
45
|
code_review: fullTools,
|
|
45
46
|
ai_merge: fullTools,
|
|
@@ -154,16 +155,6 @@ export class AgentService extends EventEmitter {
|
|
|
154
155
|
this.promptService = new PromptService(this.projectRoot, this.taskService);
|
|
155
156
|
// Initialize routing policy manager
|
|
156
157
|
this.routingPolicyManager = new RoutingPolicyManager();
|
|
157
|
-
// Create example policy file if needed (guarded for mocked environments)
|
|
158
|
-
try {
|
|
159
|
-
const maybePromise = this.routingPolicyManager.createExamplePolicy?.();
|
|
160
|
-
if (maybePromise && typeof maybePromise.catch === 'function') {
|
|
161
|
-
maybePromise.catch((err) => log.warn('Failed to create example policy', err, 'agent-service'));
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
catch (err) {
|
|
165
|
-
log.warn('Failed to trigger example policy creation', err, 'agent-service');
|
|
166
|
-
}
|
|
167
158
|
// Set up event forwarding
|
|
168
159
|
this.setupEventForwarding();
|
|
169
160
|
this.initialized = true;
|
|
@@ -219,23 +210,6 @@ export class AgentService extends EventEmitter {
|
|
|
219
210
|
});
|
|
220
211
|
});
|
|
221
212
|
}
|
|
222
|
-
/**
|
|
223
|
-
* Map core agent update to legacy format
|
|
224
|
-
* TODO: remove this later in a separate task, need to migrate the UI to handle raw message streaming
|
|
225
|
-
*/
|
|
226
|
-
mapToLegacyUpdate(data) {
|
|
227
|
-
const messages = this.coreAgentService
|
|
228
|
-
.getExecutionMessages(data.executionId)
|
|
229
|
-
.map((m) => this.summarizeMessage(m));
|
|
230
|
-
return {
|
|
231
|
-
executionId: data.executionId,
|
|
232
|
-
status: data.status ||
|
|
233
|
-
this.coreAgentService.getExecutionStatus(data.executionId)?.status ||
|
|
234
|
-
'running',
|
|
235
|
-
logs: messages,
|
|
236
|
-
error: data.error,
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
213
|
/**
|
|
240
214
|
* Create a concise, human-readable line from a structured execution message
|
|
241
215
|
*/
|
|
@@ -325,8 +299,8 @@ export class AgentService extends EventEmitter {
|
|
|
325
299
|
catch (error) {
|
|
326
300
|
log.error('Failed to create worktree, using main directory', error, 'agent-service');
|
|
327
301
|
}
|
|
328
|
-
// Generate task prompt
|
|
329
|
-
const prompt = await this.promptService.generateTaskPrompt(task);
|
|
302
|
+
// Generate task prompt with workflow configuration for dynamic instructions
|
|
303
|
+
const prompt = await this.promptService.generateTaskPrompt(task, options?.workflowConfig);
|
|
330
304
|
// Build system prompt - use rerun context if available, otherwise base prompt
|
|
331
305
|
let appendSystemPrompt;
|
|
332
306
|
if (options?.rerunContext) {
|
|
@@ -349,6 +323,7 @@ export class AgentService extends EventEmitter {
|
|
|
349
323
|
tools: this.defaultTools.execute_task,
|
|
350
324
|
timeout: 30 * 60 * 1000,
|
|
351
325
|
appendSystemPrompt,
|
|
326
|
+
dangerouslyBypassApprovalsAndSandbox: true,
|
|
352
327
|
executionId,
|
|
353
328
|
metadata: {
|
|
354
329
|
operation: 'execute_task',
|
|
@@ -403,6 +378,28 @@ export class AgentService extends EventEmitter {
|
|
|
403
378
|
}
|
|
404
379
|
}
|
|
405
380
|
}
|
|
381
|
+
const review = rerun.aiReview;
|
|
382
|
+
if (review) {
|
|
383
|
+
parts.push('AI code review feedback from previous attempt:');
|
|
384
|
+
if (typeof review.score === 'number') {
|
|
385
|
+
parts.push(`- Quality score: ${review.score}`);
|
|
386
|
+
}
|
|
387
|
+
if (review.summary) {
|
|
388
|
+
parts.push(`- Summary: ${review.summary}`);
|
|
389
|
+
}
|
|
390
|
+
const recs = Array.isArray(review.recommendations)
|
|
391
|
+
? review.recommendations.filter((r) => typeof r === 'string' && r.trim().length)
|
|
392
|
+
: [];
|
|
393
|
+
if (recs.length) {
|
|
394
|
+
parts.push('Recommendations:');
|
|
395
|
+
for (const item of recs.slice(0, 5)) {
|
|
396
|
+
parts.push(` * ${item}`);
|
|
397
|
+
}
|
|
398
|
+
if (recs.length > 5) {
|
|
399
|
+
parts.push(` * ...and ${recs.length - 5} more recommendations`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
406
403
|
parts.push('Instruction: Address the reasons above. Avoid repeating prior mistakes. Keep changes scoped and test thoroughly. ');
|
|
407
404
|
return parts.join('\n');
|
|
408
405
|
}
|
|
@@ -538,6 +535,7 @@ export class AgentService extends EventEmitter {
|
|
|
538
535
|
appendSystemPrompt: this.systemPrompts.improve_task,
|
|
539
536
|
tools: this.defaultTools.improve_task,
|
|
540
537
|
timeout: 5 * 60 * 1000,
|
|
538
|
+
dangerouslyBypassApprovalsAndSandbox: false,
|
|
541
539
|
executionId: finalExecutionId,
|
|
542
540
|
metadata: {
|
|
543
541
|
operation: 'improve_task',
|
|
@@ -559,7 +557,7 @@ export class AgentService extends EventEmitter {
|
|
|
559
557
|
/**
|
|
560
558
|
* Perform AI code review of changes in a worktree
|
|
561
559
|
*/
|
|
562
|
-
async aiReviewCode(taskId, reviewContext,
|
|
560
|
+
async aiReviewCode(taskId, reviewContext, options) {
|
|
563
561
|
const task = this.taskService.getTask(taskId);
|
|
564
562
|
if (!task) {
|
|
565
563
|
throw new Error(`Task ${taskId} not found`);
|
|
@@ -568,7 +566,7 @@ export class AgentService extends EventEmitter {
|
|
|
568
566
|
if (!worktree) {
|
|
569
567
|
throw new Error(`No worktree found for task ${taskId}`);
|
|
570
568
|
}
|
|
571
|
-
const executionId = generateId('review');
|
|
569
|
+
const executionId = options?.executionId ?? generateId('review');
|
|
572
570
|
try {
|
|
573
571
|
// Pre-register execution for streaming/persistence
|
|
574
572
|
if (!this.executionRegistry.has(executionId)) {
|
|
@@ -586,7 +584,7 @@ export class AgentService extends EventEmitter {
|
|
|
586
584
|
logs: [],
|
|
587
585
|
workingDirectory: this.projectRoot,
|
|
588
586
|
};
|
|
589
|
-
await this.logPersistence.startExecution(execRec);
|
|
587
|
+
await this.logPersistence.startExecution(execRec, options?.workflowId);
|
|
590
588
|
}
|
|
591
589
|
// Generate review prompt
|
|
592
590
|
const reviewPrompt = await this.promptService.generateReviewPrompt(task, worktree, reviewContext);
|
|
@@ -606,7 +604,7 @@ export class AgentService extends EventEmitter {
|
|
|
606
604
|
operation: 'ai_codereview',
|
|
607
605
|
taskId,
|
|
608
606
|
},
|
|
609
|
-
}, overrides);
|
|
607
|
+
}, options?.overrides);
|
|
610
608
|
// Parse review result
|
|
611
609
|
const review = this.parseReviewResult(result);
|
|
612
610
|
const payload = { executionId, ...review };
|
|
@@ -627,7 +625,7 @@ export class AgentService extends EventEmitter {
|
|
|
627
625
|
/**
|
|
628
626
|
* Perform AI-assisted merge of a task's worktree into the base project
|
|
629
627
|
*/
|
|
630
|
-
async aiMerge(taskId, options
|
|
628
|
+
async aiMerge(taskId, options) {
|
|
631
629
|
const task = this.taskService.getTask(taskId);
|
|
632
630
|
if (!task) {
|
|
633
631
|
throw new Error(`Task ${taskId} not found`);
|
|
@@ -636,14 +634,15 @@ export class AgentService extends EventEmitter {
|
|
|
636
634
|
if (!worktree) {
|
|
637
635
|
throw new Error(`No worktree found for task ${taskId}`);
|
|
638
636
|
}
|
|
639
|
-
const executionId = generateId('merge');
|
|
637
|
+
const executionId = options?.executionId ?? generateId('merge');
|
|
638
|
+
const workingDirectory = worktree.path || this.projectRoot;
|
|
640
639
|
try {
|
|
641
640
|
// Pre-register execution for streaming/persistence
|
|
642
641
|
if (!this.executionRegistry.has(executionId)) {
|
|
643
642
|
const startTime = new Date().toISOString();
|
|
644
643
|
this.executionRegistry.set(executionId, {
|
|
645
644
|
taskId,
|
|
646
|
-
workingDirectory
|
|
645
|
+
workingDirectory,
|
|
647
646
|
startTime,
|
|
648
647
|
});
|
|
649
648
|
const execRec = {
|
|
@@ -652,21 +651,21 @@ export class AgentService extends EventEmitter {
|
|
|
652
651
|
status: 'pending',
|
|
653
652
|
startTime,
|
|
654
653
|
logs: [],
|
|
655
|
-
workingDirectory
|
|
654
|
+
workingDirectory,
|
|
656
655
|
};
|
|
657
|
-
await this.logPersistence.startExecution(execRec);
|
|
656
|
+
await this.logPersistence.startExecution(execRec, options?.workflowId);
|
|
658
657
|
}
|
|
659
658
|
// Generate merge prompt
|
|
660
659
|
const mergePrompt = await this.promptService.generateAIMergePrompt(task, worktree, options?.baseBranch);
|
|
661
660
|
void this.logPersistence.logMessage(executionId, 'Merge prompt prepared', 'info', {
|
|
662
661
|
prompt: mergePrompt,
|
|
663
|
-
options: { workingDirectory
|
|
662
|
+
options: { workingDirectory, tools: this.defaultTools.ai_merge },
|
|
664
663
|
taskId,
|
|
665
664
|
baseBranch: options?.baseBranch,
|
|
666
665
|
});
|
|
667
666
|
// Execute merge with AI
|
|
668
667
|
await this.executeWithRouting('ai_merge', mergePrompt, {
|
|
669
|
-
workingDirectory
|
|
668
|
+
workingDirectory,
|
|
670
669
|
appendSystemPrompt: this.systemPrompts.ai_merge,
|
|
671
670
|
tools: this.defaultTools.ai_merge,
|
|
672
671
|
timeout: 15 * 60 * 1000,
|
|
@@ -676,29 +675,13 @@ export class AgentService extends EventEmitter {
|
|
|
676
675
|
taskId,
|
|
677
676
|
baseBranch: options?.baseBranch,
|
|
678
677
|
},
|
|
679
|
-
}, overrides);
|
|
680
|
-
// Ensure registry exists for lookups (no-op otherwise)
|
|
681
|
-
if (!this.executionRegistry.has(executionId)) {
|
|
682
|
-
this.executionRegistry.set(executionId, {
|
|
683
|
-
taskId,
|
|
684
|
-
workingDirectory: this.projectRoot,
|
|
685
|
-
startTime: new Date().toISOString(),
|
|
686
|
-
});
|
|
687
|
-
}
|
|
678
|
+
}, options?.overrides);
|
|
688
679
|
return { executionId };
|
|
689
680
|
}
|
|
690
681
|
catch (error) {
|
|
691
682
|
throw new Error(`AI merge failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
692
683
|
}
|
|
693
684
|
}
|
|
694
|
-
/**
|
|
695
|
-
* Compatibility alias for aiReviewCode
|
|
696
|
-
* @deprecated Use aiReviewCode instead
|
|
697
|
-
* TODO: migrate UI to use aiReviewCode directly and remove this
|
|
698
|
-
*/
|
|
699
|
-
async reviewCode(taskId, reviewContext, overrides) {
|
|
700
|
-
return this.aiReviewCode(taskId, reviewContext, overrides);
|
|
701
|
-
}
|
|
702
685
|
/**
|
|
703
686
|
* Get persistent execution logs
|
|
704
687
|
*/
|
|
@@ -814,6 +797,9 @@ export class AgentService extends EventEmitter {
|
|
|
814
797
|
async resolveProviderForOperation(operation, overrides) {
|
|
815
798
|
return await this.routingPolicyManager.resolveProviderForOperation(operation, overrides);
|
|
816
799
|
}
|
|
800
|
+
async previewProviderForOperation(operation, overrides) {
|
|
801
|
+
return await this.resolveProviderForOperation(operation, overrides);
|
|
802
|
+
}
|
|
817
803
|
/**
|
|
818
804
|
* Execute with provider resolution and failover
|
|
819
805
|
*/
|
|
@@ -828,6 +814,16 @@ export class AgentService extends EventEmitter {
|
|
|
828
814
|
workingDirectory: options.workingDirectory,
|
|
829
815
|
timeout: options.timeout,
|
|
830
816
|
};
|
|
817
|
+
// Persist a clear log line indicating chosen provider/model for this operation
|
|
818
|
+
try {
|
|
819
|
+
const execId = options?.executionId;
|
|
820
|
+
if (execId) {
|
|
821
|
+
await this.logPersistence.logMessage(execId, `Using provider: ${resolved.provider}${resolved.model ? ` (model: ${resolved.model})` : ''}`, 'info', { operation, resolved });
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
catch {
|
|
825
|
+
// best-effort logging; ignore
|
|
826
|
+
}
|
|
831
827
|
// Default maxTokens from settings when not provided (unlimited if omitted)
|
|
832
828
|
try {
|
|
833
829
|
if (executionOptions.maxTokens === undefined) {
|
|
@@ -843,8 +839,15 @@ export class AgentService extends EventEmitter {
|
|
|
843
839
|
catch {
|
|
844
840
|
// best effort; ignore if settings unavailable
|
|
845
841
|
}
|
|
846
|
-
let lastError = null;
|
|
847
842
|
const providersToTry = [resolved.provider, ...(resolved.fallbacks || [])];
|
|
843
|
+
// Ensure Codex executes with write permissions when it is in the routing set.
|
|
844
|
+
// Some overrides may omit the flag, so default it on for task execution.
|
|
845
|
+
if (operation === 'execute_task' &&
|
|
846
|
+
providersToTry.includes('codex') &&
|
|
847
|
+
executionOptions.dangerouslyBypassApprovalsAndSandbox === undefined) {
|
|
848
|
+
executionOptions.dangerouslyBypassApprovalsAndSandbox = true;
|
|
849
|
+
}
|
|
850
|
+
let lastError = null;
|
|
848
851
|
for (let i = 0; i < providersToTry.length; i++) {
|
|
849
852
|
const provider = providersToTry[i];
|
|
850
853
|
const isLastProvider = i === providersToTry.length - 1;
|
|
@@ -43,7 +43,7 @@ export declare class ClaudeCodeAdapter implements AIProvider {
|
|
|
43
43
|
*/
|
|
44
44
|
detectAvailableModels(): Promise<ModelInfo[]>;
|
|
45
45
|
/**
|
|
46
|
-
* Validate Claude Code setup
|
|
46
|
+
* Validate Claude Code setup using enhanced detection
|
|
47
47
|
*/
|
|
48
48
|
validateSetup(): Promise<ProviderStatus>;
|
|
49
49
|
/**
|
|
@@ -55,7 +55,7 @@ export declare class ClaudeCodeAdapter implements AIProvider {
|
|
|
55
55
|
*/
|
|
56
56
|
private mapToClaudeOptions;
|
|
57
57
|
/**
|
|
58
|
-
* Resolve Claude CLI executable path
|
|
58
|
+
* Resolve Claude CLI executable path using enhanced detection
|
|
59
59
|
*/
|
|
60
60
|
private getClaudeExecutablePath;
|
|
61
61
|
}
|
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
* Implements AIProvider interface for Claude Code SDK
|
|
4
4
|
*/
|
|
5
5
|
import { query } from '@anthropic-ai/claude-code';
|
|
6
|
-
import path from 'path';
|
|
7
|
-
import os from 'os';
|
|
8
6
|
import { generateId } from '../../lib/id-generator.js';
|
|
9
7
|
import { getSettingsService } from '../../settings-service.js';
|
|
8
|
+
import { getProviderDetectionService } from '../../lib/provider-detection.js';
|
|
10
9
|
/**
|
|
11
10
|
* Claude Code Adapter
|
|
12
11
|
* Wraps the Claude Code SDK to implement the AIProvider interface
|
|
@@ -21,7 +20,7 @@ export class ClaudeCodeAdapter {
|
|
|
21
20
|
* Execute a prompt using Claude Code SDK
|
|
22
21
|
*/
|
|
23
22
|
async *execute(prompt, options) {
|
|
24
|
-
const claudeOptions = this.mapToClaudeOptions(options);
|
|
23
|
+
const claudeOptions = await this.mapToClaudeOptions(options);
|
|
25
24
|
const co = claudeOptions;
|
|
26
25
|
const startTime = Date.now();
|
|
27
26
|
let sessionId;
|
|
@@ -249,30 +248,19 @@ export class ClaudeCodeAdapter {
|
|
|
249
248
|
];
|
|
250
249
|
}
|
|
251
250
|
/**
|
|
252
|
-
* Validate Claude Code setup
|
|
251
|
+
* Validate Claude Code setup using enhanced detection
|
|
253
252
|
*/
|
|
254
253
|
async validateSetup() {
|
|
255
254
|
try {
|
|
256
|
-
const
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
try {
|
|
266
|
-
execSync('claude --version', { stdio: 'ignore' });
|
|
267
|
-
}
|
|
268
|
-
catch {
|
|
269
|
-
return {
|
|
270
|
-
available: false,
|
|
271
|
-
error: 'Claude CLI not found. Please install Claude Code CLI.',
|
|
272
|
-
models: [],
|
|
273
|
-
capabilities: this.getCapabilities(),
|
|
274
|
-
};
|
|
275
|
-
}
|
|
255
|
+
const detectionService = getProviderDetectionService();
|
|
256
|
+
const result = await detectionService.detectProvider('claude-code');
|
|
257
|
+
if (!result.found) {
|
|
258
|
+
return {
|
|
259
|
+
available: false,
|
|
260
|
+
error: result.error || 'Claude CLI not found. Please install Claude Code CLI.',
|
|
261
|
+
models: [],
|
|
262
|
+
capabilities: this.getCapabilities(),
|
|
263
|
+
};
|
|
276
264
|
}
|
|
277
265
|
const models = await this.detectAvailableModels();
|
|
278
266
|
return {
|
|
@@ -307,11 +295,11 @@ export class ClaudeCodeAdapter {
|
|
|
307
295
|
/**
|
|
308
296
|
* Map ExecutionOptions to Claude Code Options
|
|
309
297
|
*/
|
|
310
|
-
mapToClaudeOptions(options) {
|
|
298
|
+
async mapToClaudeOptions(options) {
|
|
311
299
|
const claudeOptions = {
|
|
312
300
|
cwd: options?.workingDirectory || this.config.defaultWorkingDirectory || process.cwd(),
|
|
313
301
|
model: options?.model || this.config.defaultModel,
|
|
314
|
-
pathToClaudeCodeExecutable: this.getClaudeExecutablePath(),
|
|
302
|
+
pathToClaudeCodeExecutable: await this.getClaudeExecutablePath(),
|
|
315
303
|
};
|
|
316
304
|
// Map temperature
|
|
317
305
|
if (options?.temperature !== undefined) {
|
|
@@ -342,18 +330,20 @@ export class ClaudeCodeAdapter {
|
|
|
342
330
|
return claudeOptions;
|
|
343
331
|
}
|
|
344
332
|
/**
|
|
345
|
-
* Resolve Claude CLI executable path
|
|
333
|
+
* Resolve Claude CLI executable path using enhanced detection
|
|
346
334
|
*/
|
|
347
|
-
getClaudeExecutablePath() {
|
|
348
|
-
// Highest precedence: explicit
|
|
349
|
-
const envPath = process.env.VIBEMAN_CLAUDE_BIN;
|
|
350
|
-
if (envPath && envPath.trim()) {
|
|
351
|
-
return envPath.trim();
|
|
352
|
-
}
|
|
335
|
+
async getClaudeExecutablePath() {
|
|
336
|
+
// Highest precedence: explicit config option
|
|
353
337
|
if (this.config.claudeBinPath) {
|
|
354
338
|
return this.config.claudeBinPath;
|
|
355
339
|
}
|
|
356
|
-
//
|
|
340
|
+
// Use enhanced detection service
|
|
341
|
+
const detectionService = getProviderDetectionService();
|
|
342
|
+
const result = await detectionService.detectProvider('claude-code');
|
|
343
|
+
if (result.found && result.path) {
|
|
344
|
+
return result.path;
|
|
345
|
+
}
|
|
346
|
+
// Fallback: try old settings-based approach for backwards compatibility
|
|
357
347
|
const settingsBinPath = (() => {
|
|
358
348
|
try {
|
|
359
349
|
const svc = getSettingsService();
|
|
@@ -367,7 +357,6 @@ export class ClaudeCodeAdapter {
|
|
|
367
357
|
if (settingsBinPath?.trim()) {
|
|
368
358
|
return settingsBinPath.trim();
|
|
369
359
|
}
|
|
370
|
-
|
|
371
|
-
return path.join(os.homedir(), '.claude', 'local', 'claude');
|
|
360
|
+
return 'claude';
|
|
372
361
|
}
|
|
373
362
|
}
|
|
@@ -15,6 +15,8 @@ export declare class CodexCliProvider implements AIProvider {
|
|
|
15
15
|
readonly displayName = "Codex CLI";
|
|
16
16
|
constructor(config?: CodexCliConfig);
|
|
17
17
|
private resolveExecutable;
|
|
18
|
+
private normalizeReasoningEffort;
|
|
19
|
+
private resolveModelSpec;
|
|
18
20
|
execute(prompt: string, options?: ExecutionOptions): AsyncIterableIterator<ExecutionMessage>;
|
|
19
21
|
executeSync(prompt: string, options?: ExecutionOptions): Promise<{
|
|
20
22
|
id: string;
|