@codeledger/harness 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Intelligent Context AI, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ Note: This license applies to the CLI wrapper, types, repository scanning,
26
+ instrumentation, harness, and report packages (the "Plugin"). The scoring
27
+ engine (packages/core-engine/bin/) is licensed separately under LICENSE-CORE.
@@ -0,0 +1,7 @@
1
+ import type { AgentRunOptions, GenericAgentRunResult } from '@codeledger/types';
2
+ import type { AgentAdapter } from './types.js';
3
+ export declare class GenericAdapter implements AgentAdapter {
4
+ name: string;
5
+ run(opts: AgentRunOptions): Promise<GenericAgentRunResult>;
6
+ }
7
+ //# sourceMappingURL=generic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../src/adapters/generic.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAEhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAS/C,qBAAa,cAAe,YAAW,YAAY;IACjD,IAAI,SAAa;IAEX,GAAG,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAiEjE"}
@@ -0,0 +1,70 @@
1
+ import { writeFileSync, mkdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { execCommandAsync } from '@codeledger/instrument';
4
+ import { injectIntoPrompt, renderBundleMarkdown, writeFileDropBundle } from '../injection.js';
5
+ /** Shell-escape a string for safe interpolation into sh -c commands */
6
+ function shellEscape(s) {
7
+ // Wrap in single quotes; escape embedded single quotes
8
+ return "'" + s.replace(/'/g, "'\\''") + "'";
9
+ }
10
+ export class GenericAdapter {
11
+ name = 'generic';
12
+ async run(opts) {
13
+ if (!opts.agent_cmd) {
14
+ throw new Error('Generic adapter requires --agentCmd');
15
+ }
16
+ const logsDir = join(opts.worktree_path, '.codeledger', 'logs');
17
+ mkdirSync(logsDir, { recursive: true });
18
+ // Build the prompt file
19
+ const promptDir = join(opts.worktree_path, '.codeledger', 'prompts');
20
+ mkdirSync(promptDir, { recursive: true });
21
+ const promptFile = join(promptDir, 'task-prompt.md');
22
+ let promptContent;
23
+ let bundlePath = null;
24
+ if (opts.mode.context_injection === 'on' && opts.bundle) {
25
+ const md = opts.bundle_markdown ?? renderBundleMarkdown(opts.bundle);
26
+ const injectionMode = opts.mode.injection_mode ?? 'prompt_prepend';
27
+ if (injectionMode === 'prompt_prepend') {
28
+ promptContent = injectIntoPrompt(opts.scenario.task.prompt, md);
29
+ }
30
+ else if (injectionMode === 'file_drop') {
31
+ promptContent = opts.scenario.task.prompt;
32
+ const dropPath = '.codeledger/active-bundle.md';
33
+ bundlePath = writeFileDropBundle(opts.worktree_path, md, dropPath);
34
+ }
35
+ else {
36
+ promptContent = opts.scenario.task.prompt;
37
+ }
38
+ // Also write bundle markdown separately for reference
39
+ const bundleMdPath = join(promptDir, 'bundle.md');
40
+ writeFileSync(bundleMdPath, md);
41
+ if (!bundlePath)
42
+ bundlePath = bundleMdPath;
43
+ }
44
+ else {
45
+ // without_codeledger: prompt only — NO bundle
46
+ promptContent = opts.scenario.task.prompt;
47
+ }
48
+ writeFileSync(promptFile, promptContent);
49
+ // Substitute placeholders in agent command (shell-escape paths)
50
+ let cmd = opts.agent_cmd;
51
+ cmd = cmd.replace(/\{promptFile\}/g, shellEscape(promptFile));
52
+ cmd = cmd.replace(/\{repoRoot\}/g, shellEscape(opts.worktree_path));
53
+ cmd = cmd.replace(/\{bundlePath\}/g, shellEscape(bundlePath ?? ''));
54
+ const stdoutLog = join(logsDir, 'agent-stdout.log');
55
+ const stderrLog = join(logsDir, 'agent-stderr.log');
56
+ const result = await execCommandAsync(cmd, {
57
+ cwd: opts.worktree_path,
58
+ timeout: (opts.guided_timeout_sec ?? 1800) * 1000,
59
+ stdoutLog,
60
+ stderrLog,
61
+ });
62
+ return {
63
+ exit_code: result.exit_code,
64
+ duration_ms: result.duration_ms,
65
+ stdout_path: stdoutLog,
66
+ stderr_path: stderrLog,
67
+ };
68
+ }
69
+ }
70
+ //# sourceMappingURL=generic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/adapters/generic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { AgentRunOptions, GenericAgentRunResult } from '@codeledger/types';
2
+ import type { AgentAdapter } from './types.js';
3
+ export declare class GuidedAdapter implements AgentAdapter {
4
+ name: string;
5
+ run(opts: AgentRunOptions): Promise<GenericAgentRunResult>;
6
+ }
7
+ //# sourceMappingURL=guided.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guided.d.ts","sourceRoot":"","sources":["../../src/adapters/guided.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,qBAAa,aAAc,YAAW,YAAY;IAChD,IAAI,SAAY;IAEV,GAAG,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAuCjE"}
@@ -0,0 +1,60 @@
1
+ import { createInterface } from 'node:readline';
2
+ import { renderBundleMarkdown } from '../injection.js';
3
+ export class GuidedAdapter {
4
+ name = 'guided';
5
+ async run(opts) {
6
+ const start = Date.now();
7
+ console.log('\n' + '='.repeat(60));
8
+ console.log('GUIDED MODE — Follow the instructions below');
9
+ console.log('='.repeat(60));
10
+ if (opts.mode.context_injection === 'on' && opts.bundle) {
11
+ const md = opts.bundle_markdown ?? renderBundleMarkdown(opts.bundle);
12
+ console.log('\n📦 CONTEXT BUNDLE (paste this into your agent):');
13
+ console.log('-'.repeat(40));
14
+ console.log(md);
15
+ console.log('-'.repeat(40));
16
+ }
17
+ console.log('\n📝 TASK PROMPT:');
18
+ console.log('-'.repeat(40));
19
+ console.log(opts.scenario.task.prompt);
20
+ console.log('-'.repeat(40));
21
+ console.log(`\n📁 Open this directory in your agent: ${opts.worktree_path}`);
22
+ console.log('\nPaste the above prompt into your agent and complete the task.');
23
+ const timeoutSec = opts.guided_timeout_sec ?? 600;
24
+ console.log(`\nPress Enter when done (timeout: ${timeoutSec}s)...`);
25
+ await waitForEnterOrTimeout(timeoutSec);
26
+ const durationMs = Date.now() - start;
27
+ console.log('\n✅ Guided session complete. Running acceptance commands...');
28
+ return {
29
+ exit_code: 0,
30
+ duration_ms: durationMs,
31
+ stdout_path: null,
32
+ stderr_path: null,
33
+ };
34
+ }
35
+ }
36
+ function waitForEnterOrTimeout(timeoutSec) {
37
+ return new Promise((resolve) => {
38
+ const rl = createInterface({
39
+ input: process.stdin,
40
+ output: process.stdout,
41
+ });
42
+ let settled = false;
43
+ const settle = () => {
44
+ if (settled)
45
+ return;
46
+ settled = true;
47
+ clearTimeout(timer);
48
+ rl.close();
49
+ resolve();
50
+ };
51
+ const timer = setTimeout(() => {
52
+ console.log('\n⏰ Timeout reached.');
53
+ settle();
54
+ }, timeoutSec * 1000);
55
+ rl.once('line', () => settle());
56
+ // Resolve if stdin closes unexpectedly (piped input ends, terminal disconnects)
57
+ rl.once('close', () => settle());
58
+ });
59
+ }
60
+ //# sourceMappingURL=guided.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guided.js","sourceRoot":"","sources":["../../src/adapters/guided.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,OAAO,aAAa;IACxB,IAAI,GAAG,QAAQ,CAAC;IAEhB,KAAK,CAAC,GAAG,CAAC,IAAqB;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAE5B,IAAI,IAAI,CAAC,IAAI,CAAC,iBAAiB,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACxD,MAAM,EAAE,GAAG,IAAI,CAAC,eAAe,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;YACjE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAE5B,OAAO,CAAC,GAAG,CAAC,2CAA2C,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;QAE/E,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,IAAI,GAAG,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,qCAAqC,UAAU,OAAO,CAAC,CAAC;QAEpE,MAAM,qBAAqB,CAAC,UAAU,CAAC,CAAC;QAExC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAEtC,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;QAE3E,OAAO;YACL,SAAS,EAAE,CAAC;YACZ,WAAW,EAAE,UAAU;YACvB,WAAW,EAAE,IAAI;YACjB,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;CACF;AAED,SAAS,qBAAqB,CAAC,UAAkB;IAC/C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,eAAe,CAAC;YACzB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QAEH,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QAEF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACpC,MAAM,EAAE,CAAC;QACX,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,CAAC;QAEtB,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QAEhC,gFAAgF;QAChF,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { AgentRunOptions, GenericAgentRunResult } from '@codeledger/types';
2
+ export interface AgentAdapter {
3
+ name: string;
4
+ run(opts: AgentRunOptions): Promise<GenericAgentRunResult>;
5
+ }
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAEhF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC5D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import type { BenchmarkReport } from '@codeledger/types';
2
+ import { type RunOptions } from './scenario-runner.js';
3
+ export interface CompareOptions extends RunOptions {
4
+ repeats: number;
5
+ }
6
+ export declare function compareScenario(opts: CompareOptions): Promise<BenchmarkReport>;
7
+ //# sourceMappingURL=comparator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparator.d.ts","sourceRoot":"","sources":["../src/comparator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAKpE,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,eAAe,CAAC,CA8C1B"}
@@ -0,0 +1,135 @@
1
+ import { getShortRef, isRepoDirty } from '@codeledger/instrument';
2
+ import { runScenario } from './scenario-runner.js';
3
+ import { readFileSync } from 'node:fs';
4
+ import { basename } from 'node:path';
5
+ export async function compareScenario(opts) {
6
+ const allRuns = [];
7
+ for (let repeat = 1; repeat <= opts.repeats; repeat++) {
8
+ console.log(`\n${'═'.repeat(60)}`);
9
+ console.log(`REPEAT ${repeat} of ${opts.repeats}`);
10
+ console.log('═'.repeat(60));
11
+ const { repeats: _repeats, ...runOpts } = opts;
12
+ const runs = await runScenario(runOpts);
13
+ for (const run of runs) {
14
+ allRuns.push({
15
+ ...run,
16
+ repeat,
17
+ metrics: {
18
+ ...run.metrics,
19
+ attempt_number: repeat,
20
+ },
21
+ });
22
+ }
23
+ }
24
+ // Load scenario for metadata
25
+ let scenario;
26
+ try {
27
+ scenario = JSON.parse(readFileSync(opts.scenarioPath, 'utf-8'));
28
+ }
29
+ catch {
30
+ throw new Error(`Failed to parse scenario at ${opts.scenarioPath}. Ensure it contains valid JSON.`);
31
+ }
32
+ const gitRef = getShortRef(opts.cwd);
33
+ const dirty = isRepoDirty(opts.cwd);
34
+ const aggregate = computeAggregate(allRuns);
35
+ return {
36
+ scenario_id: scenario.id,
37
+ repo: {
38
+ name: basename(opts.cwd),
39
+ git_ref: gitRef,
40
+ dirty,
41
+ },
42
+ runs: allRuns,
43
+ aggregate,
44
+ };
45
+ }
46
+ function computeAggregate(runs) {
47
+ const withoutRuns = runs.filter((r) => r.mode === 'without_codeledger');
48
+ const withRuns = runs.filter((r) => r.mode === 'with_codeledger');
49
+ const avgDurationWithout = avg(withoutRuns.map((r) => r.metrics.duration_sec));
50
+ const avgDurationWith = avg(withRuns.map((r) => r.metrics.duration_sec));
51
+ const avgFilesWithout = avg(withoutRuns.map((r) => r.metrics.files_read_count));
52
+ const avgFilesWith = avg(withRuns.map((r) => r.metrics.files_read_count));
53
+ const avgIterWithout = avg(withoutRuns.map((r) => r.metrics.iterations));
54
+ const avgIterWith = avg(withRuns.map((r) => r.metrics.iterations));
55
+ const avgTokensWithout = avg(withoutRuns.map((r) => r.metrics.token_estimate));
56
+ const avgTokensWith = avg(withRuns.map((r) => r.metrics.token_estimate));
57
+ const successRateWithout = successRate(withoutRuns);
58
+ const successRateWith = successRate(withRuns);
59
+ const acceptedDurationWithout = withoutRuns
60
+ .filter((r) => r.metrics.accepted)
61
+ .map((r) => r.metrics.duration_ms_total);
62
+ const acceptedDurationWith = withRuns
63
+ .filter((r) => r.metrics.accepted)
64
+ .map((r) => r.metrics.duration_ms_total);
65
+ const medianWithout = median(acceptedDurationWithout);
66
+ const medianWith = median(acceptedDurationWith);
67
+ const attemptsWithout = attemptsUntilSuccess(withoutRuns);
68
+ const attemptsWith = attemptsUntilSuccess(withRuns);
69
+ return {
70
+ delta: {
71
+ duration_sec_pct: pctChange(avgDurationWithout, avgDurationWith),
72
+ files_read_pct: pctChange(avgFilesWithout, avgFilesWith),
73
+ iterations_pct: pctChange(avgIterWithout, avgIterWith),
74
+ token_estimate_pct: pctChange(avgTokensWithout, avgTokensWith),
75
+ success_rate_delta: round(successRateWith - successRateWithout),
76
+ },
77
+ outcomes: {
78
+ acceptance_rate_without: round(successRateWithout * 100),
79
+ acceptance_rate_with: round(successRateWith * 100),
80
+ acceptance_rate_uplift_pct: round((successRateWith - successRateWithout) * 100),
81
+ median_time_to_acceptance_ms_without: medianWithout,
82
+ median_time_to_acceptance_ms_with: medianWith,
83
+ time_to_acceptance_reduction_pct: pctReductionNullable(medianWithout, medianWith),
84
+ attempts_until_success_without: attemptsWithout,
85
+ attempts_until_success_with: attemptsWith,
86
+ attempts_reduction_pct: pctReductionNullable(attemptsWithout, attemptsWith),
87
+ },
88
+ };
89
+ }
90
+ function avg(values) {
91
+ if (values.length === 0)
92
+ return 0;
93
+ return values.reduce((a, b) => a + b, 0) / values.length;
94
+ }
95
+ function median(values) {
96
+ if (values.length === 0)
97
+ return null;
98
+ const sorted = [...values].sort((a, b) => a - b);
99
+ const mid = Math.floor(sorted.length / 2);
100
+ if (sorted.length % 2 === 0) {
101
+ return Math.round((sorted[mid - 1] + sorted[mid]) / 2);
102
+ }
103
+ return sorted[mid];
104
+ }
105
+ function pctChange(baseline, compare) {
106
+ if (baseline === 0) {
107
+ // Both zero means no change; otherwise the change is undefined — use
108
+ // null-coalesced sentinel so consumers can detect the edge case.
109
+ return compare === 0 ? 0 : Infinity;
110
+ }
111
+ return round(((compare - baseline) / baseline) * 100);
112
+ }
113
+ function pctReductionNullable(baseline, compare) {
114
+ if (baseline === null || compare === null || baseline === 0)
115
+ return null;
116
+ return round(((baseline - compare) / baseline) * 100);
117
+ }
118
+ function attemptsUntilSuccess(runs) {
119
+ const sorted = [...runs].sort((a, b) => a.repeat - b.repeat);
120
+ for (const run of sorted) {
121
+ if (run.metrics.accepted)
122
+ return run.repeat;
123
+ }
124
+ return null;
125
+ }
126
+ function successRate(runs) {
127
+ if (runs.length === 0)
128
+ return 0;
129
+ const passed = runs.filter((r) => r.metrics.accepted).length;
130
+ return passed / runs.length;
131
+ }
132
+ function round(n) {
133
+ return Math.round(n * 10) / 10;
134
+ }
135
+ //# sourceMappingURL=comparator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparator.js","sourceRoot":"","sources":["../src/comparator.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAmB,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAOrC,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAoB;IAEpB,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAE5B,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;QAExC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC;gBACX,GAAG,GAAG;gBACN,MAAM;gBACN,OAAO,EAAE;oBACP,GAAG,GAAG,CAAC,OAAO;oBACd,cAAc,EAAE,MAAM;iBACvB;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAa,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,YAAY,kCAAkC,CAAC,CAAC;IACtG,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEpC,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE5C,OAAO;QACL,WAAW,EAAE,QAAQ,CAAC,EAAE;QACxB,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;YACxB,OAAO,EAAE,MAAM;YACf,KAAK;SACN;QACD,IAAI,EAAE,OAAO;QACb,SAAS;KACV,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAiB;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,oBAAoB,CAAC,CAAC;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC;IAElE,MAAM,kBAAkB,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/E,MAAM,eAAe,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAEzE,MAAM,eAAe,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAChF,MAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAE1E,MAAM,cAAc,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAEnE,MAAM,gBAAgB,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IAC/E,MAAM,aAAa,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IAEzE,MAAM,kBAAkB,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,eAAe,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAE9C,MAAM,uBAAuB,GAAG,WAAW;SACxC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC3C,MAAM,oBAAoB,GAAG,QAAQ;SAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAE3C,MAAM,aAAa,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAEhD,MAAM,eAAe,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAEpD,OAAO;QACL,KAAK,EAAE;YACL,gBAAgB,EAAE,SAAS,CAAC,kBAAkB,EAAE,eAAe,CAAC;YAChE,cAAc,EAAE,SAAS,CAAC,eAAe,EAAE,YAAY,CAAC;YACxD,cAAc,EAAE,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC;YACtD,kBAAkB,EAAE,SAAS,CAAC,gBAAgB,EAAE,aAAa,CAAC;YAC9D,kBAAkB,EAAE,KAAK,CAAC,eAAe,GAAG,kBAAkB,CAAC;SAChE;QACD,QAAQ,EAAE;YACR,uBAAuB,EAAE,KAAK,CAAC,kBAAkB,GAAG,GAAG,CAAC;YACxD,oBAAoB,EAAE,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC;YAClD,0BAA0B,EAAE,KAAK,CAAC,CAAC,eAAe,GAAG,kBAAkB,CAAC,GAAG,GAAG,CAAC;YAC/E,oCAAoC,EAAE,aAAa;YACnD,iCAAiC,EAAE,UAAU;YAC7C,gCAAgC,EAAE,oBAAoB,CAAC,aAAa,EAAE,UAAU,CAAC;YACjF,8BAA8B,EAAE,eAAe;YAC/C,2BAA2B,EAAE,YAAY;YACzC,sBAAsB,EAAE,oBAAoB,CAAC,eAAe,EAAE,YAAY,CAAC;SAC5E;KACF,CAAC;AACJ,CAAC;AAED,SAAS,GAAG,CAAC,MAAgB;IAC3B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;AAC3D,CAAC;AAED,SAAS,MAAM,CAAC,MAAgB;IAC9B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAE,GAAG,MAAM,CAAC,GAAG,CAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAE,CAAC;AACtB,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB,EAAE,OAAe;IAClD,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,qEAAqE;QACrE,iEAAiE;QACjE,OAAO,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACtC,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,oBAAoB,CAC3B,QAAuB,EACvB,OAAsB;IAEtB,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzE,OAAO,KAAK,CAAC,CAAC,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAiB;IAC7C,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7D,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,IAAiB;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IAC7D,OAAO,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AAC9B,CAAC;AAED,SAAS,KAAK,CAAC,CAAS;IACtB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,10 @@
1
+ export { renderBundleMarkdown, injectIntoPrompt, writeFileDropBundle } from './injection.js';
2
+ export { GenericAdapter } from './adapters/generic.js';
3
+ export { GuidedAdapter } from './adapters/guided.js';
4
+ export type { AgentAdapter } from './adapters/types.js';
5
+ export { createWorktree, cleanupAllWorktrees } from './worktree.js';
6
+ export { runScenario } from './scenario-runner.js';
7
+ export type { RunOptions, SingleRunResult } from './scenario-runner.js';
8
+ export { compareScenario } from './comparator.js';
9
+ export type { CompareOptions } from './comparator.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { renderBundleMarkdown, injectIntoPrompt, writeFileDropBundle } from './injection.js';
2
+ export { GenericAdapter } from './adapters/generic.js';
3
+ export { GuidedAdapter } from './adapters/guided.js';
4
+ export { createWorktree, cleanupAllWorktrees } from './worktree.js';
5
+ export { runScenario } from './scenario-runner.js';
6
+ export { compareScenario } from './comparator.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ContextBundle } from '@codeledger/types';
2
+ export declare function renderBundleMarkdown(bundle: ContextBundle): string;
3
+ export declare function injectIntoPrompt(taskText: string, bundleMarkdown: string): string;
4
+ export declare function writeFileDropBundle(worktreePath: string, bundleMarkdown: string, dropPath: string): string;
5
+ //# sourceMappingURL=injection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injection.d.ts","sourceRoot":"","sources":["../src/injection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAoGlE;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,MAAM,CAER;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,GACf,MAAM,CAgBR"}
@@ -0,0 +1,107 @@
1
+ import { writeFileSync, mkdirSync } from 'node:fs';
2
+ import { dirname, resolve, relative } from 'node:path';
3
+ export function renderBundleMarkdown(bundle) {
4
+ const lines = [];
5
+ lines.push('# Context Bundle (generated by CodeLedger)');
6
+ lines.push('');
7
+ lines.push(`**Task:** ${bundle.task}`);
8
+ lines.push(`**Files:** ${bundle.files.length} | **Tokens:** ~${bundle.total_tokens}`);
9
+ // Confidence assessment
10
+ if (bundle.confidence) {
11
+ const c = bundle.confidence;
12
+ const icon = c.level === 'high' ? 'HIGH' : c.level === 'medium' ? 'MEDIUM' : 'LOW';
13
+ lines.push(`**Confidence:** ${icon} (${c.score})`);
14
+ if (c.level !== 'high' && c.reasons.length > 0) {
15
+ for (const reason of c.reasons) {
16
+ lines.push(` - ${reason}`);
17
+ }
18
+ }
19
+ }
20
+ lines.push('');
21
+ // Separate full files, stubs, and their sections
22
+ const fullFiles = bundle.files.filter((f) => !f.is_stub);
23
+ const stubs = bundle.files.filter((f) => f.is_stub);
24
+ lines.push('## Relevant Files (ranked by score)');
25
+ lines.push('');
26
+ for (let i = 0; i < fullFiles.length; i++) {
27
+ const f = fullFiles[i];
28
+ const reasons = f.reasons.join(', ');
29
+ lines.push(`${i + 1}. \`${f.path}\` — ${reasons} (score: ${f.score.toFixed(3)})`);
30
+ }
31
+ lines.push('');
32
+ lines.push('## Excerpts');
33
+ lines.push('');
34
+ for (const f of fullFiles) {
35
+ if (!f.content)
36
+ continue;
37
+ lines.push(`### ${f.path}`);
38
+ if (f.excerpt_spans) {
39
+ const spanDesc = f.excerpt_spans
40
+ .map((s) => `L${s.start_line}–${s.end_line}`)
41
+ .join(', ');
42
+ lines.push(`*Excerpts: ${spanDesc}*`);
43
+ }
44
+ // Deprecation warnings inline
45
+ if (f.deprecation_warnings && f.deprecation_warnings.length > 0) {
46
+ lines.push('');
47
+ lines.push('> **Deprecation warnings:**');
48
+ for (const w of f.deprecation_warnings) {
49
+ lines.push(`> - L${w.line}: \`${w.matched}\` — ${w.message}`);
50
+ }
51
+ }
52
+ lines.push('');
53
+ lines.push('```');
54
+ lines.push(f.content);
55
+ lines.push('```');
56
+ lines.push('');
57
+ }
58
+ // Interface stubs section
59
+ if (stubs.length > 0) {
60
+ lines.push('## Interface Stubs (adjacent dependencies)');
61
+ lines.push('');
62
+ lines.push('*These files are imported by bundle files but were not selected. Only exported type signatures are shown.*');
63
+ lines.push('');
64
+ for (const s of stubs) {
65
+ if (!s.content)
66
+ continue;
67
+ lines.push(`### ${s.path} *(stub)*`);
68
+ lines.push('');
69
+ lines.push('```');
70
+ lines.push(s.content);
71
+ lines.push('```');
72
+ lines.push('');
73
+ }
74
+ }
75
+ // Explain section (per-file scoring breakdown)
76
+ if (bundle.explain) {
77
+ lines.push('## Scoring Breakdown (--explain)');
78
+ lines.push('');
79
+ lines.push('| File | keyword | centrality | churn | recent | test | size_pen | success | fail | err_infra | total |');
80
+ lines.push('|------|---------|------------|-------|--------|------|----------|---------|------|-----------|-------|');
81
+ for (const f of fullFiles) {
82
+ const feat = bundle.explain[f.path];
83
+ if (!feat)
84
+ continue;
85
+ lines.push(`| \`${f.path}\` | ${feat.keyword.toFixed(2)} | ${feat.centrality.toFixed(2)} | ${feat.churn.toFixed(2)} | ${feat.recent_touch.toFixed(2)} | ${feat.test_relevance.toFixed(2)} | ${feat.size_penalty.toFixed(2)} | ${feat.success_prior.toFixed(2)} | ${feat.fail_prior.toFixed(2)} | ${feat.error_infrastructure.toFixed(2)} | ${f.score.toFixed(3)} |`);
86
+ }
87
+ lines.push('');
88
+ }
89
+ return lines.join('\n');
90
+ }
91
+ export function injectIntoPrompt(taskText, bundleMarkdown) {
92
+ return `${bundleMarkdown}\n---\n# Task\n${taskText}\n`;
93
+ }
94
+ export function writeFileDropBundle(worktreePath, bundleMarkdown, dropPath) {
95
+ const fullPath = resolve(worktreePath, dropPath);
96
+ const resolvedRoot = resolve(worktreePath);
97
+ // Prevent path traversal — resolved path must stay within the worktree
98
+ const rel = relative(resolvedRoot, fullPath);
99
+ if (rel.startsWith('..') || resolve(resolvedRoot, rel) !== fullPath) {
100
+ throw new Error(`Refusing to write bundle: dropPath "${dropPath}" resolves outside the worktree.`);
101
+ }
102
+ const dir = dirname(fullPath);
103
+ mkdirSync(dir, { recursive: true });
104
+ writeFileSync(fullPath, bundleMarkdown);
105
+ return fullPath;
106
+ }
107
+ //# sourceMappingURL=injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injection.js","sourceRoot":"","sources":["../src/injection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { ScenarioMode, ContextBundle, GenericAgentRunResult, Metrics, CommandResult, ReportRun, InjectionProof, InjectionMode } from '@codeledger/types';
2
+ export interface RunOptions {
3
+ scenarioPath: string;
4
+ cwd: string;
5
+ agentCmd?: string;
6
+ agentCmdWithout?: string;
7
+ agentCmdWith?: string;
8
+ guided?: boolean;
9
+ force?: boolean;
10
+ useWorktree?: boolean;
11
+ keepWorktree?: boolean;
12
+ worktreeRoot?: string;
13
+ injectionOverride?: InjectionMode;
14
+ guidedTimeoutSec?: number;
15
+ }
16
+ export interface SingleRunResult {
17
+ mode: ScenarioMode;
18
+ agentResult: GenericAgentRunResult;
19
+ acceptanceResults: CommandResult[];
20
+ metrics: Metrics;
21
+ bundle: ContextBundle | null;
22
+ injectionProof: InjectionProof | null;
23
+ }
24
+ export declare function runScenario(opts: RunOptions): Promise<ReportRun[]>;
25
+ export declare function selectAgentCmdForMode(modeName: string, opts: Pick<RunOptions, 'agentCmd' | 'agentCmdWithout' | 'agentCmdWith'>): string | undefined;
26
+ //# sourceMappingURL=scenario-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenario-runner.d.ts","sourceRoot":"","sources":["../src/scenario-runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,YAAY,EAGZ,aAAa,EACb,qBAAqB,EACrB,OAAO,EACP,aAAa,EAEb,SAAS,EACT,cAAc,EACd,aAAa,EACd,MAAM,mBAAmB,CAAC;AAgB3B,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,aAAa,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,WAAW,EAAE,qBAAqB,CAAC;IACnC,iBAAiB,EAAE,aAAa,EAAE,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;CACvC;AAsCD,wBAAsB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAwSxE;AAYD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,iBAAiB,GAAG,cAAc,CAAC,GACtE,MAAM,GAAG,SAAS,CAUpB"}