@bouncesecurity/aghast 0.4.4 → 0.5.0
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/config/prompts/general-vuln-discovery.md +7 -3
- package/dist/build-config.d.ts +15 -0
- package/dist/build-config.d.ts.map +1 -0
- package/dist/build-config.js +568 -0
- package/dist/build-config.js.map +1 -0
- package/dist/check-library.d.ts.map +1 -1
- package/dist/check-library.js +4 -1
- package/dist/check-library.js.map +1 -1
- package/dist/check-types.d.ts +1 -1
- package/dist/check-types.d.ts.map +1 -1
- package/dist/claude-code-provider.d.ts +6 -4
- package/dist/claude-code-provider.d.ts.map +1 -1
- package/dist/claude-code-provider.js +86 -51
- package/dist/claude-code-provider.js.map +1 -1
- package/dist/cli.js +8 -2
- package/dist/cli.js.map +1 -1
- package/dist/colors.js +4 -4
- package/dist/colors.js.map +1 -1
- package/dist/defaults.d.ts +21 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +21 -0
- package/dist/defaults.js.map +1 -0
- package/dist/discoveries/openant-discovery.d.ts.map +1 -1
- package/dist/discoveries/openant-discovery.js +3 -2
- package/dist/discoveries/openant-discovery.js.map +1 -1
- package/dist/discoveries/sarif-discovery.d.ts.map +1 -1
- package/dist/discoveries/sarif-discovery.js +2 -1
- package/dist/discoveries/sarif-discovery.js.map +1 -1
- package/dist/discoveries/semgrep-discovery.d.ts.map +1 -1
- package/dist/discoveries/semgrep-discovery.js +11 -2
- package/dist/discoveries/semgrep-discovery.js.map +1 -1
- package/dist/discovery.d.ts +8 -2
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +8 -0
- package/dist/discovery.js.map +1 -1
- package/dist/error-codes.d.ts +2 -1
- package/dist/error-codes.d.ts.map +1 -1
- package/dist/error-codes.js +8 -3
- package/dist/error-codes.js.map +1 -1
- package/dist/formatters/types.d.ts +1 -1
- package/dist/formatters/types.js +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -78
- package/dist/index.js.map +1 -1
- package/dist/logging.d.ts.map +1 -1
- package/dist/logging.js +36 -9
- package/dist/logging.js.map +1 -1
- package/dist/{mock-ai-provider.d.ts → mock-agent-provider.d.ts} +5 -5
- package/dist/mock-agent-provider.d.ts.map +1 -0
- package/dist/{mock-ai-provider.js → mock-agent-provider.js} +3 -3
- package/dist/mock-agent-provider.js.map +1 -0
- package/dist/new-check.js +2 -2
- package/dist/new-check.js.map +1 -1
- package/dist/opencode-provider.d.ts +65 -0
- package/dist/opencode-provider.d.ts.map +1 -0
- package/dist/opencode-provider.js +541 -0
- package/dist/opencode-provider.js.map +1 -0
- package/dist/prompt-template.d.ts.map +1 -1
- package/dist/prompt-template.js +2 -1
- package/dist/prompt-template.js.map +1 -1
- package/dist/provider-registry.d.ts +6 -6
- package/dist/provider-registry.d.ts.map +1 -1
- package/dist/provider-registry.js +6 -4
- package/dist/provider-registry.js.map +1 -1
- package/dist/provider-utils.d.ts +52 -0
- package/dist/provider-utils.d.ts.map +1 -0
- package/dist/provider-utils.js +40 -0
- package/dist/provider-utils.js.map +1 -0
- package/dist/response-parser.d.ts +8 -6
- package/dist/response-parser.d.ts.map +1 -1
- package/dist/response-parser.js +8 -6
- package/dist/response-parser.js.map +1 -1
- package/dist/runtime-config.d.ts +4 -4
- package/dist/runtime-config.d.ts.map +1 -1
- package/dist/runtime-config.js +15 -8
- package/dist/runtime-config.js.map +1 -1
- package/dist/scan-runner.d.ts +4 -4
- package/dist/scan-runner.d.ts.map +1 -1
- package/dist/scan-runner.js +99 -42
- package/dist/scan-runner.js.map +1 -1
- package/dist/types.d.ts +34 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -3
- package/dist/types.js.map +1 -1
- package/package.json +5 -3
- package/dist/mock-ai-provider.d.ts.map +0 -1
- package/dist/mock-ai-provider.js.map +0 -1
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode agent provider implementation.
|
|
3
|
+
* Uses @opencode-ai/sdk v2 API to delegate to any LLM provider supported by OpenCode.
|
|
4
|
+
*
|
|
5
|
+
* Progress logging: at trace level, a 1-second poller fetches session messages to
|
|
6
|
+
* log tool calls and text parts in real-time while session.prompt() blocks.
|
|
7
|
+
*/
|
|
8
|
+
import { exec } from 'node:child_process';
|
|
9
|
+
import { existsSync, rmSync } from 'node:fs';
|
|
10
|
+
import { rm as rmAsync } from 'node:fs/promises';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
import { promisify } from 'node:util';
|
|
13
|
+
import { FatalProviderError } from './types.js';
|
|
14
|
+
import { parseAgentResponse } from './response-parser.js';
|
|
15
|
+
import { OUTPUT_SCHEMA } from './provider-utils.js';
|
|
16
|
+
import { logProgress, logDebug, logDebugFull, createTimer, getLogLevel } from './logging.js';
|
|
17
|
+
const execAsync = promisify(exec);
|
|
18
|
+
const TAG = 'opencode-provider';
|
|
19
|
+
const DEFAULT_OPENCODE_MODEL = 'opencode/big-pickle';
|
|
20
|
+
const HEARTBEAT_INTERVAL_MS = 15000;
|
|
21
|
+
const TRACE_POLL_MS = 1000;
|
|
22
|
+
const CLOSE_TIMEOUT_MS = 5000;
|
|
23
|
+
/**
|
|
24
|
+
* Parse a "providerID/modelID" string into its components.
|
|
25
|
+
* Falls back to the default if not provided.
|
|
26
|
+
*/
|
|
27
|
+
function parseModelString(model) {
|
|
28
|
+
const raw = model ?? DEFAULT_OPENCODE_MODEL;
|
|
29
|
+
const slashIdx = raw.indexOf('/');
|
|
30
|
+
if (slashIdx === -1) {
|
|
31
|
+
throw new Error(`Invalid model format "${raw}" for opencode provider. Expected "providerID/modelID" (e.g. "anthropic/claude-sonnet-4-20250514").`);
|
|
32
|
+
}
|
|
33
|
+
return { providerID: raw.slice(0, slashIdx), modelID: raw.slice(slashIdx + 1) };
|
|
34
|
+
}
|
|
35
|
+
/** Verify that the opencode binary is installed and runnable. */
|
|
36
|
+
function verifyOpenCodeInstalled() {
|
|
37
|
+
// Use `exec` (single command string, always uses shell) instead of `execFile` with
|
|
38
|
+
// shell:true + args array. The latter triggers DEP0190 on Node 22+; the former does not.
|
|
39
|
+
// Shell is required on Windows to invoke opencode's .cmd wrapper — spawning .cmd
|
|
40
|
+
// directly is blocked by the CVE-2024-27980 mitigation. No user input is interpolated
|
|
41
|
+
// into the command, so there is no injection surface.
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
exec('opencode --version', (error, stdout, stderr) => {
|
|
44
|
+
if (error) {
|
|
45
|
+
// `exec` routes both "spawn failed" (binary not on PATH) and "ran but exited
|
|
46
|
+
// non-zero" (e.g. corrupt config, permission issue) through the same error
|
|
47
|
+
// callback. We can't tell the two apart reliably cross-platform, so the
|
|
48
|
+
// message has to cover both possibilities — otherwise a user with a broken
|
|
49
|
+
// install is sent on a wild goose chase reinstalling an already-present binary.
|
|
50
|
+
const detail = (stderr || stdout || error.message).toString().trim();
|
|
51
|
+
const suffix = detail ? ` Details: ${detail}` : '';
|
|
52
|
+
reject(new Error(`OpenCode is required for the 'opencode' agent provider but \`opencode --version\` failed. ` +
|
|
53
|
+
`Either OpenCode is not installed (get it from https://opencode.ai) or the installed binary returned an error.${suffix}`));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
resolve();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
export class OpenCodeProvider {
|
|
61
|
+
providerID = '';
|
|
62
|
+
modelID = '';
|
|
63
|
+
_client;
|
|
64
|
+
_server;
|
|
65
|
+
debugEnabled = false;
|
|
66
|
+
cleanedUp = false;
|
|
67
|
+
signalHandler;
|
|
68
|
+
/** Refcount of project markers we created, keyed by absolute repositoryPath.
|
|
69
|
+
* An entry exists ONLY when we created the marker — we never track pre-existing `.git`. */
|
|
70
|
+
createdMarkers = new Map();
|
|
71
|
+
/** FIFO async mutex serializing mutations to createdMarkers. Guards against races
|
|
72
|
+
* between the N parallel executeCheck calls that share one repositoryPath. */
|
|
73
|
+
markerMutex = Promise.resolve();
|
|
74
|
+
/** Skip project-marker logic when a mock client was injected (tests use fake paths). */
|
|
75
|
+
skipProjectMarker;
|
|
76
|
+
constructor(options) {
|
|
77
|
+
if (options?._client) {
|
|
78
|
+
this._client = options._client;
|
|
79
|
+
}
|
|
80
|
+
this.skipProjectMarker = !!options?._client;
|
|
81
|
+
}
|
|
82
|
+
checkPrerequisites() {
|
|
83
|
+
// OpenCode manages its own credentials — no env var prerequisites to check.
|
|
84
|
+
}
|
|
85
|
+
async initialize(config) {
|
|
86
|
+
const parsed = parseModelString(config.model);
|
|
87
|
+
this.providerID = parsed.providerID;
|
|
88
|
+
this.modelID = parsed.modelID;
|
|
89
|
+
// Skip server startup if a mock client was injected via constructor
|
|
90
|
+
if (this._client) {
|
|
91
|
+
logDebug(TAG, 'Using injected client (test mode)');
|
|
92
|
+
await this.validateModel();
|
|
93
|
+
logDebug(TAG, `Provider initialized with model ${this.providerID}/${this.modelID}`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// Verify opencode binary is installed
|
|
97
|
+
await verifyOpenCodeInstalled();
|
|
98
|
+
const { createOpencode } = await import('@opencode-ai/sdk/v2');
|
|
99
|
+
logProgress(TAG, 'Starting OpenCode server...');
|
|
100
|
+
const opencode = await createOpencode({
|
|
101
|
+
port: 0,
|
|
102
|
+
});
|
|
103
|
+
this._client = opencode.client;
|
|
104
|
+
this._server = opencode.server;
|
|
105
|
+
logProgress(TAG, `OpenCode server started at ${this._server.url}`);
|
|
106
|
+
// Register signal handlers for cleanup on unexpected exit.
|
|
107
|
+
// SIGHUP catches terminal-window-close (sent as SIGHUP on Unix; Node maps
|
|
108
|
+
// Windows CTRL_CLOSE_EVENT to the same event) — critical for cleaning up the
|
|
109
|
+
// transient .git marker when a user closes their terminal mid-scan.
|
|
110
|
+
this.signalHandler = () => {
|
|
111
|
+
this.cleanupSync();
|
|
112
|
+
process.exit(1);
|
|
113
|
+
};
|
|
114
|
+
process.on('SIGINT', this.signalHandler);
|
|
115
|
+
process.on('SIGTERM', this.signalHandler);
|
|
116
|
+
process.on('SIGHUP', this.signalHandler);
|
|
117
|
+
if (process.platform === 'win32') {
|
|
118
|
+
process.on('SIGBREAK', this.signalHandler);
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
await this.validateModel();
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
this.cleanupSync();
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
logDebug(TAG, `Provider initialized with model ${this.providerID}/${this.modelID}`);
|
|
128
|
+
}
|
|
129
|
+
async validateModel() {
|
|
130
|
+
const client = this._client;
|
|
131
|
+
const result = await client.config.providers();
|
|
132
|
+
const data = result.data;
|
|
133
|
+
const providers = data?.providers ?? [];
|
|
134
|
+
const provider = providers.find(p => p.id === this.providerID);
|
|
135
|
+
if (!provider) {
|
|
136
|
+
const available = providers.map(p => p.id).join(', ') || '(none)';
|
|
137
|
+
throw new FatalProviderError(`OpenCode provider "${this.providerID}" not found. Available providers: ${available}. Run 'opencode' and use /connect to configure providers.`);
|
|
138
|
+
}
|
|
139
|
+
const models = provider.models ? Object.keys(provider.models) : [];
|
|
140
|
+
if (models.length > 0 && !models.includes(this.modelID)) {
|
|
141
|
+
const available = models.map(m => `${this.providerID}/${m}`).join(', ');
|
|
142
|
+
throw new FatalProviderError(`Model "${this.modelID}" not found for provider "${this.providerID}". Available models: ${available}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async listModels() {
|
|
146
|
+
if (!this._client) {
|
|
147
|
+
throw new Error('OpenCode provider not initialized — call initialize() first');
|
|
148
|
+
}
|
|
149
|
+
const result = await this._client.config.providers();
|
|
150
|
+
const data = result.data;
|
|
151
|
+
const providers = data?.providers ?? [];
|
|
152
|
+
const out = [];
|
|
153
|
+
for (const provider of providers) {
|
|
154
|
+
const models = provider.models ?? {};
|
|
155
|
+
for (const [modelID, model] of Object.entries(models)) {
|
|
156
|
+
out.push({
|
|
157
|
+
id: `${provider.id}/${modelID}`,
|
|
158
|
+
label: model.name ?? modelID,
|
|
159
|
+
description: provider.name,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
getModelName() {
|
|
166
|
+
return `${this.providerID}/${this.modelID}`;
|
|
167
|
+
}
|
|
168
|
+
setModel(model) {
|
|
169
|
+
const parsed = parseModelString(model);
|
|
170
|
+
this.providerID = parsed.providerID;
|
|
171
|
+
this.modelID = parsed.modelID;
|
|
172
|
+
}
|
|
173
|
+
enableDebug() {
|
|
174
|
+
this.debugEnabled = true;
|
|
175
|
+
}
|
|
176
|
+
/** Run `fn` under an async FIFO mutex so refcount mutations and fs ops don't race. */
|
|
177
|
+
async withMarkerLock(fn) {
|
|
178
|
+
const prev = this.markerMutex;
|
|
179
|
+
let release;
|
|
180
|
+
this.markerMutex = new Promise((r) => { release = r; });
|
|
181
|
+
await prev;
|
|
182
|
+
try {
|
|
183
|
+
return await fn();
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
release();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/** Ensure `.git` exists at repositoryPath so OpenCode treats it as the project root.
|
|
190
|
+
* No-op if a `.git` already exists (whether directory or file) — we never touch
|
|
191
|
+
* pre-existing markers. If we create it, track it via refcount so concurrent
|
|
192
|
+
* targets with the same path coordinate correctly. Non-fatal on failure:
|
|
193
|
+
* falls through to whatever OpenCode does by default (walk up to parent repo),
|
|
194
|
+
* which is what the user saw before this fix. */
|
|
195
|
+
async ensureProjectMarker(repositoryPath) {
|
|
196
|
+
if (this.skipProjectMarker)
|
|
197
|
+
return;
|
|
198
|
+
await this.withMarkerLock(async () => {
|
|
199
|
+
const existing = this.createdMarkers.get(repositoryPath);
|
|
200
|
+
if (existing !== undefined) {
|
|
201
|
+
this.createdMarkers.set(repositoryPath, existing + 1);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (existsSync(join(repositoryPath, '.git'))) {
|
|
205
|
+
// Pre-existing — not ours, no refcount. OpenCode will use this naturally.
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const gitPath = join(repositoryPath, '.git');
|
|
209
|
+
// Record BEFORE running git init. If SIGINT/SIGHUP fires while git init is
|
|
210
|
+
// running — or in the race window between init completing and the set() call
|
|
211
|
+
// — the sync cleanup handler iterates createdMarkers and rmSync's whatever's
|
|
212
|
+
// at gitPath. rmSync with { force: true } is lenient on ENOENT, so recording
|
|
213
|
+
// before a would-be-nonexistent path is safe.
|
|
214
|
+
this.createdMarkers.set(repositoryPath, 1);
|
|
215
|
+
try {
|
|
216
|
+
await execAsync('git init -q', { cwd: repositoryPath });
|
|
217
|
+
// Info-level: we are touching the user's filesystem. They should see it without --debug.
|
|
218
|
+
logProgress(TAG, `Created transient ${gitPath} so OpenCode treats this directory as its project root. ` +
|
|
219
|
+
`Will be removed when the scan finishes.`);
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
// Init failed — remove the phantom refcount so release doesn't try to rm a
|
|
223
|
+
// non-existent .git (harmless but produces a confusing warning log).
|
|
224
|
+
this.createdMarkers.delete(repositoryPath);
|
|
225
|
+
logProgress(TAG, `Warning: could not create project marker at ${gitPath}: ${err instanceof Error ? err.message : String(err)}. ` +
|
|
226
|
+
`File reads may resolve against the nearest ancestor .git instead, which can cause ENOENT errors.`);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
/** Release one reference to a project marker. When refcount hits zero, remove it.
|
|
231
|
+
* Pre-existing (non-ours) markers are ignored. */
|
|
232
|
+
async releaseProjectMarker(repositoryPath) {
|
|
233
|
+
if (this.skipProjectMarker)
|
|
234
|
+
return;
|
|
235
|
+
await this.withMarkerLock(async () => {
|
|
236
|
+
const count = this.createdMarkers.get(repositoryPath);
|
|
237
|
+
if (count === undefined)
|
|
238
|
+
return;
|
|
239
|
+
if (count > 1) {
|
|
240
|
+
this.createdMarkers.set(repositoryPath, count - 1);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
this.createdMarkers.delete(repositoryPath);
|
|
244
|
+
const gitPath = join(repositoryPath, '.git');
|
|
245
|
+
try {
|
|
246
|
+
await rmAsync(gitPath, { recursive: true, force: true });
|
|
247
|
+
// Removal is the symmetric cleanup — debug is fine, users don't need to see it at info.
|
|
248
|
+
logDebug(TAG, `Removed transient project marker at ${gitPath}`);
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
// Failure to remove leaves state on the filesystem — surface at info.
|
|
252
|
+
logProgress(TAG, `Warning: could not remove transient project marker at ${gitPath}: ${err instanceof Error ? err.message : String(err)}. ` +
|
|
253
|
+
`You may need to remove it manually.`);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
/** Synchronously wipe all markers we created. Used by signal handlers where
|
|
258
|
+
* async cleanup is unsafe. Does NOT acquire the mutex — signal handlers run
|
|
259
|
+
* between event loop ticks, so we observe a consistent map snapshot. */
|
|
260
|
+
cleanupMarkersSync() {
|
|
261
|
+
for (const [path] of this.createdMarkers) {
|
|
262
|
+
try {
|
|
263
|
+
rmSync(join(path, '.git'), { recursive: true, force: true });
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
// Best-effort in signal handler — process is about to exit anyway.
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
this.createdMarkers.clear();
|
|
270
|
+
}
|
|
271
|
+
async executeCheck(instructions, repositoryPath, logPrefix, _options) {
|
|
272
|
+
if (!this._client) {
|
|
273
|
+
throw new Error('OpenCode provider not initialized — call initialize() first');
|
|
274
|
+
}
|
|
275
|
+
// Ensure OpenCode treats repositoryPath as its project root. Without this, when
|
|
276
|
+
// repositoryPath is a subdirectory of some other git repo, OpenCode walks up to
|
|
277
|
+
// the ancestor .git and resolves all Read-tool paths relative to THAT directory,
|
|
278
|
+
// causing ENOENT for every target file. This creates a transient `.git` marker
|
|
279
|
+
// we remove when the scan finishes (refcounted across parallel targets).
|
|
280
|
+
await this.ensureProjectMarker(repositoryPath);
|
|
281
|
+
try {
|
|
282
|
+
return await this.executeCheckInner(instructions, repositoryPath, logPrefix);
|
|
283
|
+
}
|
|
284
|
+
finally {
|
|
285
|
+
await this.releaseProjectMarker(repositoryPath);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async executeCheckInner(instructions, repositoryPath, logPrefix) {
|
|
289
|
+
const client = this._client;
|
|
290
|
+
const timer = createTimer();
|
|
291
|
+
const prefix = logPrefix ? `${logPrefix} ` : '';
|
|
292
|
+
// Create an isolated session for this check
|
|
293
|
+
logDebug(TAG, `${prefix}Creating session for check (cwd=${repositoryPath})`);
|
|
294
|
+
const sessionResult = await client.session.create({
|
|
295
|
+
title: 'aghast security check',
|
|
296
|
+
directory: repositoryPath,
|
|
297
|
+
});
|
|
298
|
+
const sessionId = sessionResult.data?.id;
|
|
299
|
+
if (!sessionId) {
|
|
300
|
+
throw new Error('Failed to create OpenCode session — no session ID returned');
|
|
301
|
+
}
|
|
302
|
+
logDebug(TAG, `${prefix}Session created: ${sessionId}`);
|
|
303
|
+
logDebug(TAG, `${prefix}Starting query: model=${this.providerID}/${this.modelID}, promptLen=${instructions.length}`);
|
|
304
|
+
if (this.debugEnabled) {
|
|
305
|
+
logDebugFull(TAG, `${prefix}Full prompt sent to AI`, instructions);
|
|
306
|
+
}
|
|
307
|
+
// At trace level, poll session messages every second for real-time progress.
|
|
308
|
+
// session.prompt() blocks, but setInterval callbacks run during the await.
|
|
309
|
+
let toolCallCount = 0;
|
|
310
|
+
let lastLoggedPartCount = 0;
|
|
311
|
+
let lastActivityTime = Date.now();
|
|
312
|
+
const logLevel = getLogLevel();
|
|
313
|
+
const isDebugOrTrace = logLevel === 'debug' || logLevel === 'trace';
|
|
314
|
+
const progressInterval = isDebugOrTrace ? setInterval(async () => {
|
|
315
|
+
try {
|
|
316
|
+
const messagesResult = await client.session.messages({
|
|
317
|
+
sessionID: sessionId,
|
|
318
|
+
directory: repositoryPath,
|
|
319
|
+
});
|
|
320
|
+
const messages = messagesResult.data ?? [];
|
|
321
|
+
const assistantMsg = [...messages].reverse().find((m) => m.info.role === 'assistant');
|
|
322
|
+
if (!assistantMsg)
|
|
323
|
+
return;
|
|
324
|
+
const parts = assistantMsg.parts;
|
|
325
|
+
if (parts.length <= lastLoggedPartCount)
|
|
326
|
+
return;
|
|
327
|
+
for (let i = lastLoggedPartCount; i < parts.length; i++) {
|
|
328
|
+
const part = parts[i];
|
|
329
|
+
lastActivityTime = Date.now();
|
|
330
|
+
if (part.type === 'tool') {
|
|
331
|
+
const state = part.state;
|
|
332
|
+
const toolName = part.tool ?? 'unknown';
|
|
333
|
+
const inputPreview = previewJSON(state?.input, 200);
|
|
334
|
+
if (state?.status === 'running') {
|
|
335
|
+
toolCallCount++;
|
|
336
|
+
logDebug(TAG, `${prefix}Tool[${toolCallCount}]: ${toolName} ${inputPreview} (${timer.elapsedStr()})`);
|
|
337
|
+
}
|
|
338
|
+
else if (state?.status === 'completed') {
|
|
339
|
+
logDebug(TAG, `${prefix}Tool done: ${toolName} (${timer.elapsedStr()})`);
|
|
340
|
+
}
|
|
341
|
+
else if (state?.status === 'error') {
|
|
342
|
+
// Tools can transition running → error between polls, so the "running" log
|
|
343
|
+
// line may never fire for this tool. Always include the input so the user
|
|
344
|
+
// can see what was being attempted, plus the error message from the SDK.
|
|
345
|
+
const errorMsg = state.error ?? '(no error message)';
|
|
346
|
+
const errorPreview = errorMsg.length > 300 ? errorMsg.slice(0, 300) + '...' : errorMsg;
|
|
347
|
+
logDebug(TAG, `${prefix}Tool error: ${toolName} ${inputPreview} → ${errorPreview} (${timer.elapsedStr()})`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
else if (part.type === 'text' && part.text) {
|
|
351
|
+
const preview = part.text.length > 150 ? part.text.slice(0, 150) + '...' : part.text;
|
|
352
|
+
logDebug(TAG, `${prefix}Text: ${preview}`);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
lastLoggedPartCount = parts.length;
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
// Polling failure is non-fatal
|
|
359
|
+
}
|
|
360
|
+
}, TRACE_POLL_MS) : undefined;
|
|
361
|
+
// Heartbeat timer (all log levels)
|
|
362
|
+
const heartbeatInterval = setInterval(() => {
|
|
363
|
+
const silentSeconds = Math.round((Date.now() - lastActivityTime) / 1000);
|
|
364
|
+
if (silentSeconds >= HEARTBEAT_INTERVAL_MS / 1000) {
|
|
365
|
+
logDebug(TAG, `${prefix}Still waiting... (${timer.elapsedStr()})`);
|
|
366
|
+
}
|
|
367
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
368
|
+
let promptResult;
|
|
369
|
+
try {
|
|
370
|
+
promptResult = await client.session.prompt({
|
|
371
|
+
sessionID: sessionId,
|
|
372
|
+
model: { providerID: this.providerID, modelID: this.modelID },
|
|
373
|
+
parts: [{ type: 'text', text: instructions }],
|
|
374
|
+
format: {
|
|
375
|
+
type: 'json_schema',
|
|
376
|
+
schema: OUTPUT_SCHEMA,
|
|
377
|
+
},
|
|
378
|
+
directory: repositoryPath,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
finally {
|
|
382
|
+
if (progressInterval)
|
|
383
|
+
clearInterval(progressInterval);
|
|
384
|
+
clearInterval(heartbeatInterval);
|
|
385
|
+
}
|
|
386
|
+
const info = promptResult.data?.info;
|
|
387
|
+
const parts = promptResult.data?.parts;
|
|
388
|
+
// Check for errors on the assistant message
|
|
389
|
+
if (info?.error) {
|
|
390
|
+
const err = info.error;
|
|
391
|
+
const errName = err.name;
|
|
392
|
+
const errMsg = 'data' in err && err.data && typeof err.data === 'object' && 'message' in err.data
|
|
393
|
+
? String(err.data.message)
|
|
394
|
+
: errName;
|
|
395
|
+
// StructuredOutputError: model doesn't support JSON schema output.
|
|
396
|
+
// Fall through to text-based parsing instead of failing.
|
|
397
|
+
if (errName === 'StructuredOutputError') {
|
|
398
|
+
logDebug(TAG, `${prefix}Model does not support structured output — falling back to text parsing`);
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
if (errName === 'ProviderAuthError') {
|
|
402
|
+
throw new FatalProviderError(`OpenCode authentication failed: ${errMsg}. Run 'opencode' and use /connect to configure credentials.`);
|
|
403
|
+
}
|
|
404
|
+
if (errName === 'APIError' && /rate.?limit|429/i.test(errMsg)) {
|
|
405
|
+
throw new FatalProviderError(`OpenCode rate limit reached: ${errMsg}`);
|
|
406
|
+
}
|
|
407
|
+
throw new Error(`OpenCode AI error (${errName}): ${errMsg}`);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
// Extract token usage
|
|
411
|
+
let tokenUsage;
|
|
412
|
+
if (!info?.tokens) {
|
|
413
|
+
logDebug(TAG, `${prefix}Token usage not reported by provider`);
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
const tokens = info.tokens;
|
|
417
|
+
const inputTokens = tokens.input ?? 0;
|
|
418
|
+
const outputTokens = tokens.output ?? 0;
|
|
419
|
+
tokenUsage = { inputTokens, outputTokens, totalTokens: inputTokens + outputTokens };
|
|
420
|
+
logDebug(TAG, `${prefix}Token usage: ${tokenUsage.inputTokens} in, ${tokenUsage.outputTokens} out`);
|
|
421
|
+
}
|
|
422
|
+
// Try structured output first (v2 API: info.structured)
|
|
423
|
+
if (info?.structured) {
|
|
424
|
+
const structuredOutput = info.structured;
|
|
425
|
+
logDebug(TAG, `${prefix}Structured output: ${structuredOutput.issues?.length ?? 0} issues`);
|
|
426
|
+
logProgress(TAG, `${prefix}Completed in ${timer.elapsedStr()} (${toolCallCount} tool calls)`);
|
|
427
|
+
const rawText = extractTextFromParts(parts);
|
|
428
|
+
return { raw: rawText, parsed: structuredOutput, tokenUsage };
|
|
429
|
+
}
|
|
430
|
+
// Fallback: extract text from response parts and parse with response-parser
|
|
431
|
+
const rawText = extractTextFromParts(parts);
|
|
432
|
+
logDebug(TAG, `${prefix}No structured output — falling back to text parsing (${rawText.length} chars)`);
|
|
433
|
+
if (this.debugEnabled) {
|
|
434
|
+
logDebugFull(TAG, `${prefix}Full AI response`, rawText);
|
|
435
|
+
}
|
|
436
|
+
if (!rawText) {
|
|
437
|
+
throw new Error('OpenCode AI returned no text response');
|
|
438
|
+
}
|
|
439
|
+
const parsed = parseAgentResponse(rawText);
|
|
440
|
+
if (parsed) {
|
|
441
|
+
logDebug(TAG, `${prefix}Parsed ${parsed.issues.length} issues from text response`);
|
|
442
|
+
}
|
|
443
|
+
logProgress(TAG, `${prefix}Completed in ${timer.elapsedStr()} (${toolCallCount} tool calls)`);
|
|
444
|
+
return { raw: rawText, parsed: parsed ?? undefined, tokenUsage };
|
|
445
|
+
}
|
|
446
|
+
async validateConfig() {
|
|
447
|
+
return !!this._client;
|
|
448
|
+
}
|
|
449
|
+
/** Synchronous cleanup for signal handlers (best-effort). */
|
|
450
|
+
cleanupSync() {
|
|
451
|
+
if (this.cleanedUp)
|
|
452
|
+
return;
|
|
453
|
+
this.cleanedUp = true;
|
|
454
|
+
// Remove signal handlers so cleanup() (called later via build-config's finally,
|
|
455
|
+
// or by a caller after initialize() throws) doesn't no-op and leave them installed.
|
|
456
|
+
if (this.signalHandler) {
|
|
457
|
+
process.removeListener('SIGINT', this.signalHandler);
|
|
458
|
+
process.removeListener('SIGTERM', this.signalHandler);
|
|
459
|
+
process.removeListener('SIGHUP', this.signalHandler);
|
|
460
|
+
if (process.platform === 'win32') {
|
|
461
|
+
process.removeListener('SIGBREAK', this.signalHandler);
|
|
462
|
+
}
|
|
463
|
+
this.signalHandler = undefined;
|
|
464
|
+
}
|
|
465
|
+
// Wipe any transient .git markers we created before exiting.
|
|
466
|
+
this.cleanupMarkersSync();
|
|
467
|
+
if (this._server) {
|
|
468
|
+
try {
|
|
469
|
+
this._server.close();
|
|
470
|
+
}
|
|
471
|
+
catch {
|
|
472
|
+
// Best-effort in signal handler
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
async cleanup() {
|
|
477
|
+
if (this.cleanedUp)
|
|
478
|
+
return;
|
|
479
|
+
this.cleanedUp = true;
|
|
480
|
+
// Remove signal handlers
|
|
481
|
+
if (this.signalHandler) {
|
|
482
|
+
process.removeListener('SIGINT', this.signalHandler);
|
|
483
|
+
process.removeListener('SIGTERM', this.signalHandler);
|
|
484
|
+
process.removeListener('SIGHUP', this.signalHandler);
|
|
485
|
+
if (process.platform === 'win32') {
|
|
486
|
+
process.removeListener('SIGBREAK', this.signalHandler);
|
|
487
|
+
}
|
|
488
|
+
this.signalHandler = undefined;
|
|
489
|
+
}
|
|
490
|
+
// Force-remove any markers still tracked (normally refcount already brought them
|
|
491
|
+
// to zero via releaseProjectMarker; this covers the case where executeCheck threw
|
|
492
|
+
// before reaching its finally block).
|
|
493
|
+
for (const [path] of this.createdMarkers) {
|
|
494
|
+
try {
|
|
495
|
+
await rmAsync(join(path, '.git'), { recursive: true, force: true });
|
|
496
|
+
}
|
|
497
|
+
catch (err) {
|
|
498
|
+
logDebug(TAG, `Failed to remove marker at ${path} during cleanup: ${err instanceof Error ? err.message : String(err)}`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
this.createdMarkers.clear();
|
|
502
|
+
if (this._server) {
|
|
503
|
+
logProgress(TAG, 'Stopping OpenCode server...');
|
|
504
|
+
try {
|
|
505
|
+
await Promise.race([
|
|
506
|
+
Promise.resolve(this._server.close()),
|
|
507
|
+
new Promise((resolve) => setTimeout(() => {
|
|
508
|
+
logDebug(TAG, `Server close timed out after ${CLOSE_TIMEOUT_MS}ms`);
|
|
509
|
+
resolve();
|
|
510
|
+
}, CLOSE_TIMEOUT_MS)),
|
|
511
|
+
]);
|
|
512
|
+
}
|
|
513
|
+
catch (err) {
|
|
514
|
+
logDebug(TAG, `Error stopping OpenCode server: ${err}`);
|
|
515
|
+
}
|
|
516
|
+
this._server = undefined;
|
|
517
|
+
this._client = undefined;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Extract text content from an array of response parts.
|
|
523
|
+
*/
|
|
524
|
+
/** JSON-stringify a value and truncate to `maxLen` characters for log output. */
|
|
525
|
+
function previewJSON(value, maxLen) {
|
|
526
|
+
if (value === undefined)
|
|
527
|
+
return '';
|
|
528
|
+
const str = JSON.stringify(value);
|
|
529
|
+
if (str === undefined)
|
|
530
|
+
return '';
|
|
531
|
+
return str.length > maxLen ? str.slice(0, maxLen) + '...' : str;
|
|
532
|
+
}
|
|
533
|
+
function extractTextFromParts(parts) {
|
|
534
|
+
if (!parts)
|
|
535
|
+
return '';
|
|
536
|
+
return parts
|
|
537
|
+
.filter((p) => p.type === 'text' && typeof p.text === 'string')
|
|
538
|
+
.map((p) => p.text)
|
|
539
|
+
.join('\n');
|
|
540
|
+
}
|
|
541
|
+
//# sourceMappingURL=opencode-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode-provider.js","sourceRoot":"","sources":["../src/opencode-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-template.d.ts","sourceRoot":"","sources":["../src/prompt-template.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"prompt-template.d.ts","sourceRoot":"","sources":["../src/prompt-template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA4BH;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,iBAAiB,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGxH"}
|
package/dist/prompt-template.js
CHANGED
|
@@ -6,10 +6,11 @@ import { readFile } from 'node:fs/promises';
|
|
|
6
6
|
import { existsSync } from 'node:fs';
|
|
7
7
|
import { resolve, dirname } from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
|
+
import { DEFAULT_GENERIC_PROMPT } from './defaults.js';
|
|
9
10
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
const DEFAULT_PROMPTS_DIR = resolve(__dirname, '..', 'config', 'prompts');
|
|
11
12
|
function getGenericPromptPath(configDir, genericPrompt) {
|
|
12
|
-
const filename = genericPrompt ??
|
|
13
|
+
const filename = genericPrompt ?? DEFAULT_GENERIC_PROMPT;
|
|
13
14
|
if (filename.includes('/') || filename.includes('\\') || filename.includes('..')) {
|
|
14
15
|
throw new Error(`Invalid generic prompt filename: must not contain path separators or "..". Got: "${filename}"`);
|
|
15
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-template.js","sourceRoot":"","sources":["../src/prompt-template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"prompt-template.js","sourceRoot":"","sources":["../src/prompt-template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,mBAAmB,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAE1E,SAAS,oBAAoB,CAAC,SAAkB,EAAE,aAAsB;IACtE,MAAM,QAAQ,GAAG,aAAa,IAAI,sBAAsB,CAAC;IACzD,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjF,MAAM,IAAI,KAAK,CACb,oFAAoF,QAAQ,GAAG,CAChG,CAAC;IACJ,CAAC;IACD,8DAA8D;IAC9D,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,gBAAgB,GAAG,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACjE,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACjC,OAAO,gBAAgB,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,iBAAyB,EAAE,SAAkB,EAAE,aAAsB;IACrG,MAAM,oBAAoB,GAAG,MAAM,QAAQ,CAAC,oBAAoB,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC;IACrG,OAAO,oBAAoB,GAAG,iBAAiB,CAAC;AAClD,CAAC"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Agent Provider Registry.
|
|
3
3
|
*
|
|
4
4
|
* Allows providers to be registered by name and resolved at runtime.
|
|
5
|
-
* Adding a new provider requires only implementing the
|
|
5
|
+
* Adding a new provider requires only implementing the AgentProvider interface
|
|
6
6
|
* and calling registerProvider.
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
9
|
-
export type ProviderFactory = () =>
|
|
8
|
+
import type { AgentProvider } from './types.js';
|
|
9
|
+
export type ProviderFactory = () => AgentProvider;
|
|
10
10
|
export declare function registerProvider(name: string, factory: ProviderFactory): void;
|
|
11
|
-
export declare function createProviderByName(name: string):
|
|
11
|
+
export declare function createProviderByName(name: string): AgentProvider;
|
|
12
12
|
export declare function getProviderNames(): string[];
|
|
13
|
-
/** Default provider name — used as fallback in CLI when
|
|
13
|
+
/** Default provider name — used as fallback in CLI when agent provider / runtime config not set. */
|
|
14
14
|
export declare const DEFAULT_PROVIDER_NAME = "claude-code";
|
|
15
15
|
//# sourceMappingURL=provider-registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-registry.d.ts","sourceRoot":"","sources":["../src/provider-registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"provider-registry.d.ts","sourceRoot":"","sources":["../src/provider-registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,MAAM,MAAM,eAAe,GAAG,MAAM,aAAa,CAAC;AAIlD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAE7E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAQhE;AAED,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED,oGAAoG;AACpG,eAAO,MAAM,qBAAqB,gBAAgB,CAAC"}
|