@open330/oac 2026.4.3 → 2026.220.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/CHANGELOG.md +115 -0
- package/README.md +2 -2
- package/dist/{chunk-YWIB3TRI.js → chunk-6A37SKAJ.js} +15 -2
- package/dist/chunk-6A37SKAJ.js.map +1 -0
- package/dist/{chunk-ZRYAHZQJ.js → chunk-7C7SC4TZ.js} +1 -1
- package/dist/{chunk-XUW3XWTX.js → chunk-7Y4LZUDP.js} +89 -121
- package/dist/chunk-7Y4LZUDP.js.map +1 -0
- package/dist/{chunk-CJAJ4MBO.js → chunk-OS3XDHOJ.js} +57 -18
- package/dist/chunk-OS3XDHOJ.js.map +1 -0
- package/dist/{chunk-HDMLNOND.js → chunk-OTPXGXO7.js} +44 -18
- package/dist/chunk-OTPXGXO7.js.map +1 -0
- package/dist/{chunk-7FWC3Z4W.js → chunk-QPVNC7S4.js} +479 -196
- package/dist/chunk-QPVNC7S4.js.map +1 -0
- package/dist/cli/cli.js +6 -6
- package/dist/cli/index.js +6 -6
- package/dist/completion/index.js +4 -8
- package/dist/completion/index.js.map +1 -1
- package/dist/core/index.d.ts +16 -1
- package/dist/core/index.js +8 -4
- package/dist/dashboard/index.js +33 -24
- package/dist/dashboard/index.js.map +1 -1
- package/dist/discovery/index.d.ts +18 -2
- package/dist/discovery/index.js +4 -2
- package/dist/execution/index.d.ts +45 -1
- package/dist/execution/index.js +7 -3
- package/dist/repo/index.d.ts +2 -2
- package/dist/repo/index.js +1 -1
- package/dist/{types-CYCwgojB.d.ts → types-3_IAAxh5.d.ts} +1 -0
- package/docs/config-reference.md +271 -0
- package/docs/multi-agent-support-technical-spec.md +312 -0
- package/package.json +23 -18
- package/dist/chunk-7FWC3Z4W.js.map +0 -1
- package/dist/chunk-CJAJ4MBO.js.map +0 -1
- package/dist/chunk-HDMLNOND.js.map +0 -1
- package/dist/chunk-XUW3XWTX.js.map +0 -1
- package/dist/chunk-YWIB3TRI.js.map +0 -1
- /package/dist/{chunk-ZRYAHZQJ.js.map → chunk-7C7SC4TZ.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cloneRepo,
|
|
3
3
|
resolveRepo
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-OS3XDHOJ.js";
|
|
5
5
|
import {
|
|
6
6
|
CompositeScanner,
|
|
7
7
|
GitHubIssuesScanner,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
TestGapScanner,
|
|
10
10
|
TodoScanner,
|
|
11
11
|
analyzeCodebase,
|
|
12
|
+
buildScanners,
|
|
12
13
|
createBacklog,
|
|
13
14
|
getPendingEpics,
|
|
14
15
|
groupFindingsIntoEpics,
|
|
@@ -19,7 +20,7 @@ import {
|
|
|
19
20
|
persistContext,
|
|
20
21
|
rankTasks,
|
|
21
22
|
updateBacklog
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-OTPXGXO7.js";
|
|
23
24
|
import {
|
|
24
25
|
buildEpicExecutionPlan,
|
|
25
26
|
buildExecutionPlan,
|
|
@@ -27,17 +28,20 @@ import {
|
|
|
27
28
|
estimateTokens
|
|
28
29
|
} from "./chunk-5GAUWC3L.js";
|
|
29
30
|
import {
|
|
30
|
-
|
|
31
|
-
CodexAdapter,
|
|
31
|
+
adapterRegistry,
|
|
32
32
|
createSandbox,
|
|
33
33
|
epicAsTask,
|
|
34
34
|
executeTask
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-QPVNC7S4.js";
|
|
36
36
|
import {
|
|
37
37
|
UNLIMITED_BUDGET,
|
|
38
38
|
createEventBus,
|
|
39
39
|
loadConfig
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-7C7SC4TZ.js";
|
|
41
|
+
import {
|
|
42
|
+
isRecord,
|
|
43
|
+
truncate
|
|
44
|
+
} from "./chunk-6A37SKAJ.js";
|
|
41
45
|
import {
|
|
42
46
|
contributionLogSchema,
|
|
43
47
|
writeContributionLog
|
|
@@ -51,7 +55,7 @@ import Table from "cli-table3";
|
|
|
51
55
|
import { Command as Command2 } from "commander";
|
|
52
56
|
|
|
53
57
|
// src/cli/github-auth.ts
|
|
54
|
-
import { execFileSync } from "child_process";
|
|
58
|
+
import { execFileSync, spawnSync } from "child_process";
|
|
55
59
|
function ensureGitHubAuth() {
|
|
56
60
|
const githubToken = process.env.GITHUB_TOKEN?.trim();
|
|
57
61
|
if (githubToken) {
|
|
@@ -79,24 +83,12 @@ function ensureGitHubAuth() {
|
|
|
79
83
|
}
|
|
80
84
|
function checkGitHubScopes(required = ["repo"]) {
|
|
81
85
|
try {
|
|
82
|
-
const
|
|
86
|
+
const result = spawnSync("gh", ["auth", "status"], {
|
|
83
87
|
timeout: 5e3,
|
|
84
88
|
encoding: "utf-8",
|
|
85
|
-
// Merge stderr into stdout so we can read scope info
|
|
86
89
|
stdio: ["ignore", "pipe", "pipe"]
|
|
87
90
|
});
|
|
88
|
-
|
|
89
|
-
if (!combined.includes("Token scopes")) {
|
|
90
|
-
try {
|
|
91
|
-
combined = execFileSync("sh", ["-c", "gh auth status 2>&1"], {
|
|
92
|
-
timeout: 5e3,
|
|
93
|
-
encoding: "utf-8",
|
|
94
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
95
|
-
});
|
|
96
|
-
} catch {
|
|
97
|
-
return [];
|
|
98
|
-
}
|
|
99
|
-
}
|
|
91
|
+
const combined = `${result.stdout ?? ""}${result.stderr ?? ""}`;
|
|
100
92
|
const scopeLine = combined.match(/Token scopes:\s*(.+)/);
|
|
101
93
|
if (!scopeLine) return [];
|
|
102
94
|
const scopes = scopeLine[1].split(",").map((s) => s.trim().replace(/^'|'$/g, ""));
|
|
@@ -110,14 +102,15 @@ function checkGitHubScopes(required = ["repo"]) {
|
|
|
110
102
|
import chalk, { Chalk } from "chalk";
|
|
111
103
|
import "commander";
|
|
112
104
|
import ora from "ora";
|
|
105
|
+
import PQueue from "p-queue";
|
|
113
106
|
|
|
114
107
|
// src/cli/config-loader.ts
|
|
115
108
|
import { constants as fsConstants } from "fs";
|
|
116
109
|
import { access, readFile } from "fs/promises";
|
|
117
110
|
import { resolve } from "path";
|
|
118
111
|
import { pathToFileURL } from "url";
|
|
119
|
-
var
|
|
120
|
-
var
|
|
112
|
+
var DEFINE_CONFIG_IMPORT = /@(?:open330\/oac(?:-core)?|oac\/core)/;
|
|
113
|
+
var DEFINE_CONFIG_IMPORT_LINE = /^\s*import\s*\{\s*defineConfig\s*\}\s*from\s*["']@(?:open330\/oac(?:-core)?|oac\/core)["'];\s*$/m;
|
|
121
114
|
var LEGACY_DEFINE_CONFIG_EXPORT = /export\s+default\s+defineConfig\s*\(/;
|
|
122
115
|
async function loadOptionalConfigFile(configPath, options = {}) {
|
|
123
116
|
const absolutePath = resolve(options.cwd ?? process.cwd(), configPath);
|
|
@@ -161,16 +154,16 @@ function shouldTryLegacyDefineConfigFallback(error) {
|
|
|
161
154
|
if (!(error instanceof Error)) {
|
|
162
155
|
return false;
|
|
163
156
|
}
|
|
164
|
-
return
|
|
157
|
+
return DEFINE_CONFIG_IMPORT.test(error.message);
|
|
165
158
|
}
|
|
166
159
|
function transformLegacyDefineConfigSource(source) {
|
|
167
|
-
if (!
|
|
160
|
+
if (!DEFINE_CONFIG_IMPORT_LINE.test(source)) {
|
|
168
161
|
return null;
|
|
169
162
|
}
|
|
170
163
|
if (!LEGACY_DEFINE_CONFIG_EXPORT.test(source)) {
|
|
171
164
|
return null;
|
|
172
165
|
}
|
|
173
|
-
return source.replace(
|
|
166
|
+
return source.replace(DEFINE_CONFIG_IMPORT_LINE, "").replace(LEGACY_DEFINE_CONFIG_EXPORT, "export default (");
|
|
174
167
|
}
|
|
175
168
|
async function importCandidate(moduleSpecifier) {
|
|
176
169
|
const imported = await import(moduleSpecifier);
|
|
@@ -217,12 +210,6 @@ function parseInteger(value) {
|
|
|
217
210
|
function formatInteger(value) {
|
|
218
211
|
return new Intl.NumberFormat("en-US").format(value);
|
|
219
212
|
}
|
|
220
|
-
function truncate(value, maxLength) {
|
|
221
|
-
if (value.length <= maxLength) {
|
|
222
|
-
return value;
|
|
223
|
-
}
|
|
224
|
-
return `${value.slice(0, Math.max(0, maxLength - 3))}...`;
|
|
225
|
-
}
|
|
226
213
|
async function loadOptionalConfig(configPath, verbose, ui) {
|
|
227
214
|
return loadOptionalConfigFile(configPath, {
|
|
228
215
|
onWarning: verbose ? (message) => {
|
|
@@ -263,13 +250,16 @@ function resolveBudget(tokensOption, config) {
|
|
|
263
250
|
async function estimateTaskMap(tasks, providerId, onProgress) {
|
|
264
251
|
let completed = 0;
|
|
265
252
|
const total = tasks.length;
|
|
253
|
+
const queue = new PQueue({ concurrency: 10 });
|
|
266
254
|
const entries = await Promise.all(
|
|
267
|
-
tasks.map(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
255
|
+
tasks.map(
|
|
256
|
+
(task) => queue.add(async () => {
|
|
257
|
+
const estimate = await estimateTokens(task, providerId);
|
|
258
|
+
completed += 1;
|
|
259
|
+
onProgress?.(completed, total);
|
|
260
|
+
return [task.id, estimate];
|
|
261
|
+
})
|
|
262
|
+
)
|
|
273
263
|
);
|
|
274
264
|
return new Map(entries);
|
|
275
265
|
}
|
|
@@ -382,14 +372,7 @@ function normalizeOutputFormat(value) {
|
|
|
382
372
|
throw new Error(`Unsupported --format value "${value}". Use "table" or "json".`);
|
|
383
373
|
}
|
|
384
374
|
function buildScannerList(config, hasGitHubAuth) {
|
|
385
|
-
|
|
386
|
-
const lint = config?.discovery.scanners.lint ?? true;
|
|
387
|
-
const todo = config?.discovery.scanners.todo ?? true;
|
|
388
|
-
if (lint) scanners.push(new LintScanner());
|
|
389
|
-
if (todo) scanners.push(new TodoScanner());
|
|
390
|
-
scanners.push(new TestGapScanner());
|
|
391
|
-
if (hasGitHubAuth) scanners.push(new GitHubIssuesScanner());
|
|
392
|
-
return scanners;
|
|
375
|
+
return buildScanners(config, hasGitHubAuth).instances;
|
|
393
376
|
}
|
|
394
377
|
|
|
395
378
|
// src/cli/commands/completion.ts
|
|
@@ -598,6 +581,16 @@ async function runDoctorChecks() {
|
|
|
598
581
|
status: codexResult.ok ? "pass" : "fail",
|
|
599
582
|
message: codexResult.ok ? void 0 : explainCommandFailure("codex", codexResult)
|
|
600
583
|
});
|
|
584
|
+
const opencodeResult = await runCommand("opencode", ["--version"]);
|
|
585
|
+
const opencodeVersion = extractVersion(opencodeResult.stdout) ?? "--";
|
|
586
|
+
checks.push({
|
|
587
|
+
id: "opencode",
|
|
588
|
+
name: "OpenCode CLI",
|
|
589
|
+
requirement: "installed",
|
|
590
|
+
value: opencodeVersion,
|
|
591
|
+
status: opencodeResult.ok ? "pass" : "fail",
|
|
592
|
+
message: opencodeResult.ok ? void 0 : explainCommandFailure("opencode", opencodeResult)
|
|
593
|
+
});
|
|
601
594
|
return checks;
|
|
602
595
|
}
|
|
603
596
|
async function checkGithubAuth() {
|
|
@@ -709,7 +702,7 @@ async function runCommand(command, args) {
|
|
|
709
702
|
});
|
|
710
703
|
return {
|
|
711
704
|
ok: result.exitCode === 0,
|
|
712
|
-
exitCode: result.exitCode,
|
|
705
|
+
exitCode: result.exitCode ?? null,
|
|
713
706
|
stdout: result.stdout,
|
|
714
707
|
stderr: result.stderr
|
|
715
708
|
};
|
|
@@ -780,15 +773,15 @@ function createExplainCommand() {
|
|
|
780
773
|
console.log(` ${ui.blue("Scope:")} ${epic.scope}`);
|
|
781
774
|
console.log(` ${ui.blue("Priority:")} ${epic.priority}`);
|
|
782
775
|
console.log(` ${ui.blue("Status:")} ${epic.status}`);
|
|
783
|
-
console.log(` ${ui.blue("Tasks:")} ${epic.
|
|
776
|
+
console.log(` ${ui.blue("Tasks:")} ${epic.subtasks.length}`);
|
|
784
777
|
console.log("");
|
|
785
778
|
console.log(ui.dim("Description:"));
|
|
786
779
|
console.log(` ${epic.description}`);
|
|
787
|
-
if (epic.
|
|
780
|
+
if (epic.subtasks.length > 0) {
|
|
788
781
|
console.log("");
|
|
789
782
|
console.log(ui.dim("Task IDs:"));
|
|
790
|
-
for (const
|
|
791
|
-
console.log(` - ${
|
|
783
|
+
for (const subtask of epic.subtasks) {
|
|
784
|
+
console.log(` - ${subtask.id}`);
|
|
792
785
|
}
|
|
793
786
|
}
|
|
794
787
|
}
|
|
@@ -854,7 +847,7 @@ function printAvailableIds(ui, context, backlog) {
|
|
|
854
847
|
|
|
855
848
|
// src/cli/commands/init.ts
|
|
856
849
|
import { constants as fsConstants2 } from "fs";
|
|
857
|
-
import { access as access2, mkdir, writeFile } from "fs/promises";
|
|
850
|
+
import { access as access2, mkdir, readFile as readFile2, writeFile } from "fs/promises";
|
|
858
851
|
import { resolve as resolve3 } from "path";
|
|
859
852
|
import { checkbox, confirm, input } from "@inquirer/prompts";
|
|
860
853
|
import { Command as Command6 } from "commander";
|
|
@@ -919,6 +912,7 @@ async function runMinimalInit(options, globalOptions, ui) {
|
|
|
919
912
|
});
|
|
920
913
|
await writeFile(configPath, configContent, "utf8");
|
|
921
914
|
await mkdir(trackingDirectory, { recursive: true });
|
|
915
|
+
await ensureGitignoreEntry(process.cwd(), ".oac/");
|
|
922
916
|
const summary = {
|
|
923
917
|
configPath,
|
|
924
918
|
trackingDirectory,
|
|
@@ -947,7 +941,7 @@ async function runInteractiveInit(globalOptions, ui) {
|
|
|
947
941
|
choices: [
|
|
948
942
|
{ name: "Claude Code", value: "claude-code", checked: true },
|
|
949
943
|
{ name: "Codex CLI", value: "codex" },
|
|
950
|
-
{ name: "OpenCode
|
|
944
|
+
{ name: "OpenCode", value: "opencode" }
|
|
951
945
|
],
|
|
952
946
|
validate: (value) => value.length > 0 ? true : "Select at least one provider to continue."
|
|
953
947
|
});
|
|
@@ -1007,6 +1001,7 @@ async function runInteractiveInit(globalOptions, ui) {
|
|
|
1007
1001
|
});
|
|
1008
1002
|
await writeFile(configPath, configContent, "utf8");
|
|
1009
1003
|
await mkdir(trackingDirectory, { recursive: true });
|
|
1004
|
+
await ensureGitignoreEntry(process.cwd(), ".oac/");
|
|
1010
1005
|
const summary = {
|
|
1011
1006
|
configPath,
|
|
1012
1007
|
trackingDirectory,
|
|
@@ -1082,9 +1077,23 @@ async function pathExists2(path) {
|
|
|
1082
1077
|
return false;
|
|
1083
1078
|
}
|
|
1084
1079
|
}
|
|
1080
|
+
async function ensureGitignoreEntry(dir, entry) {
|
|
1081
|
+
const gitignorePath = resolve3(dir, ".gitignore");
|
|
1082
|
+
let content = "";
|
|
1083
|
+
try {
|
|
1084
|
+
content = await readFile2(gitignorePath, "utf8");
|
|
1085
|
+
} catch {
|
|
1086
|
+
}
|
|
1087
|
+
if (content.split("\n").some((line) => line.trim() === entry)) {
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
const separator = content.length > 0 && !content.endsWith("\n") ? "\n" : "";
|
|
1091
|
+
await writeFile(gitignorePath, `${content}${separator}${entry}
|
|
1092
|
+
`, "utf8");
|
|
1093
|
+
}
|
|
1085
1094
|
|
|
1086
1095
|
// src/cli/commands/leaderboard.ts
|
|
1087
|
-
import { readFile as
|
|
1096
|
+
import { readFile as readFile3, readdir } from "fs/promises";
|
|
1088
1097
|
import { resolve as resolve4 } from "path";
|
|
1089
1098
|
import Table2 from "cli-table3";
|
|
1090
1099
|
import { Command as Command7 } from "commander";
|
|
@@ -1144,7 +1153,7 @@ Examples:
|
|
|
1144
1153
|
async function loadLeaderboardEntries(repoPath) {
|
|
1145
1154
|
const leaderboardPath = resolve4(repoPath, ".oac", "leaderboard.json");
|
|
1146
1155
|
try {
|
|
1147
|
-
const leaderboardRaw = await
|
|
1156
|
+
const leaderboardRaw = await readFile3(leaderboardPath, "utf8");
|
|
1148
1157
|
const leaderboardPayload = JSON.parse(leaderboardRaw);
|
|
1149
1158
|
return parseStoredLeaderboardEntries(leaderboardPayload);
|
|
1150
1159
|
} catch (error) {
|
|
@@ -1204,7 +1213,7 @@ async function readContributionLogs(repoPath) {
|
|
|
1204
1213
|
fileNames.map(async (fileName) => {
|
|
1205
1214
|
const filePath = resolve4(contributionsPath, fileName);
|
|
1206
1215
|
try {
|
|
1207
|
-
const content = await
|
|
1216
|
+
const content = await readFile3(filePath, "utf8");
|
|
1208
1217
|
const payload = JSON.parse(content);
|
|
1209
1218
|
const parsed = contributionLogSchema.safeParse(payload);
|
|
1210
1219
|
return parsed.success ? parsed.data : null;
|
|
@@ -1270,9 +1279,6 @@ function sortValue(entry, field) {
|
|
|
1270
1279
|
}
|
|
1271
1280
|
return entry.totalPRsCreated;
|
|
1272
1281
|
}
|
|
1273
|
-
function isRecord(value) {
|
|
1274
|
-
return typeof value === "object" && value !== null;
|
|
1275
|
-
}
|
|
1276
1282
|
function isFileNotFoundError(error) {
|
|
1277
1283
|
if (!isRecord(error)) {
|
|
1278
1284
|
return false;
|
|
@@ -1281,7 +1287,7 @@ function isFileNotFoundError(error) {
|
|
|
1281
1287
|
}
|
|
1282
1288
|
|
|
1283
1289
|
// src/cli/commands/log.ts
|
|
1284
|
-
import { readFile as
|
|
1290
|
+
import { readFile as readFile4, readdir as readdir2 } from "fs/promises";
|
|
1285
1291
|
import { resolve as resolve5 } from "path";
|
|
1286
1292
|
import Table3 from "cli-table3";
|
|
1287
1293
|
import { Command as Command8 } from "commander";
|
|
@@ -1357,7 +1363,7 @@ async function readContributionLogs2(repoPath) {
|
|
|
1357
1363
|
files.map(async (fileName) => {
|
|
1358
1364
|
const filePath = resolve5(contributionsPath, fileName);
|
|
1359
1365
|
try {
|
|
1360
|
-
const content = await
|
|
1366
|
+
const content = await readFile4(filePath, "utf8");
|
|
1361
1367
|
const payload = JSON.parse(content);
|
|
1362
1368
|
const parsed = contributionLogSchema.safeParse(payload);
|
|
1363
1369
|
return parsed.success ? parsed.data : null;
|
|
@@ -1547,7 +1553,7 @@ import { randomUUID } from "crypto";
|
|
|
1547
1553
|
|
|
1548
1554
|
// src/cli/commands/run/epic.ts
|
|
1549
1555
|
import Table6 from "cli-table3";
|
|
1550
|
-
import
|
|
1556
|
+
import PQueue3 from "p-queue";
|
|
1551
1557
|
|
|
1552
1558
|
// src/cli/commands/run/pr.ts
|
|
1553
1559
|
import { execa } from "execa";
|
|
@@ -1672,7 +1678,7 @@ async function createPullRequest(input2) {
|
|
|
1672
1678
|
// src/cli/commands/run/task.ts
|
|
1673
1679
|
import Table5 from "cli-table3";
|
|
1674
1680
|
import { execa as execa2 } from "execa";
|
|
1675
|
-
import
|
|
1681
|
+
import PQueue2 from "p-queue";
|
|
1676
1682
|
async function discoverTasks(ctx, options, config, ghToken, resolvedRepo) {
|
|
1677
1683
|
const scannerSelection = selectScannersFromConfig2(config, Boolean(ghToken));
|
|
1678
1684
|
const minPriority = config?.discovery.minPriority ?? 20;
|
|
@@ -1795,7 +1801,7 @@ async function executePlan(ctx, params) {
|
|
|
1795
1801
|
`Executing ${plan.selectedTasks.length} planned task(s)...`
|
|
1796
1802
|
);
|
|
1797
1803
|
let completedCount = 0;
|
|
1798
|
-
const taskQueue = new
|
|
1804
|
+
const taskQueue = new PQueue2({ concurrency });
|
|
1799
1805
|
const executedTasks = await Promise.all(
|
|
1800
1806
|
plan.selectedTasks.map(
|
|
1801
1807
|
(entry) => taskQueue.add(async () => {
|
|
@@ -1820,7 +1826,7 @@ async function executePlan(ctx, params) {
|
|
|
1820
1826
|
);
|
|
1821
1827
|
executionSpinner?.succeed("Execution stage finished");
|
|
1822
1828
|
const completionSpinner = createSpinner(ctx.suppressOutput, "Completing task outputs...");
|
|
1823
|
-
const completionQueue = new
|
|
1829
|
+
const completionQueue = new PQueue2({ concurrency });
|
|
1824
1830
|
const completedTasks = await Promise.all(
|
|
1825
1831
|
executedTasks.map(
|
|
1826
1832
|
(result) => completionQueue.add(async () => {
|
|
@@ -1891,33 +1897,8 @@ function printFinalSummary(ctx, params) {
|
|
|
1891
1897
|
}
|
|
1892
1898
|
}
|
|
1893
1899
|
function selectScannersFromConfig2(config, hasGitHubAuth) {
|
|
1894
|
-
const
|
|
1895
|
-
|
|
1896
|
-
enabled.push("lint");
|
|
1897
|
-
}
|
|
1898
|
-
if (config?.discovery.scanners.todo !== false) {
|
|
1899
|
-
enabled.push("todo");
|
|
1900
|
-
}
|
|
1901
|
-
if (config?.discovery.scanners.testGap !== false) {
|
|
1902
|
-
enabled.push("test-gap");
|
|
1903
|
-
}
|
|
1904
|
-
if (hasGitHubAuth) {
|
|
1905
|
-
enabled.push("github-issues");
|
|
1906
|
-
}
|
|
1907
|
-
if (enabled.length === 0) {
|
|
1908
|
-
enabled.push("lint", "todo", "test-gap");
|
|
1909
|
-
}
|
|
1910
|
-
const uniqueEnabled = [...new Set(enabled)];
|
|
1911
|
-
const scannerInstances = uniqueEnabled.map((scannerName) => {
|
|
1912
|
-
if (scannerName === "lint") return new LintScanner();
|
|
1913
|
-
if (scannerName === "github-issues") return new GitHubIssuesScanner();
|
|
1914
|
-
if (scannerName === "test-gap") return new TestGapScanner();
|
|
1915
|
-
return new TodoScanner();
|
|
1916
|
-
});
|
|
1917
|
-
return {
|
|
1918
|
-
enabled: uniqueEnabled,
|
|
1919
|
-
scanner: new CompositeScanner(scannerInstances)
|
|
1920
|
-
};
|
|
1900
|
+
const { names, composite } = buildScanners(config, hasGitHubAuth);
|
|
1901
|
+
return { enabled: names, scanner: composite };
|
|
1921
1902
|
}
|
|
1922
1903
|
async function executeWithAgent(input2) {
|
|
1923
1904
|
const startedAt = Date.now();
|
|
@@ -2000,15 +1981,12 @@ Automated contribution by OAC using Codex CLI.`],
|
|
|
2000
1981
|
}
|
|
2001
1982
|
}
|
|
2002
1983
|
async function resolveAdapter(providerId) {
|
|
2003
|
-
const normalizedId = providerId
|
|
2004
|
-
const
|
|
2005
|
-
codex: () => new CodexAdapter(),
|
|
2006
|
-
"claude-code": () => new ClaudeCodeAdapter()
|
|
2007
|
-
};
|
|
2008
|
-
const factory = adapters[normalizedId];
|
|
1984
|
+
const normalizedId = adapterRegistry.resolveId(providerId);
|
|
1985
|
+
const factory = adapterRegistry.get(providerId);
|
|
2009
1986
|
if (!factory) {
|
|
1987
|
+
const supported = adapterRegistry.registeredIds().join(", ");
|
|
2010
1988
|
throw new Error(
|
|
2011
|
-
`Unknown provider "${providerId}". Supported providers:
|
|
1989
|
+
`Unknown provider "${providerId}". Supported providers: ${supported}.
|
|
2012
1990
|
Run \`oac doctor\` to check your environment setup.`
|
|
2013
1991
|
);
|
|
2014
1992
|
}
|
|
@@ -2016,7 +1994,7 @@ Run \`oac doctor\` to check your environment setup.`
|
|
|
2016
1994
|
const availability = await adapter.checkAvailability();
|
|
2017
1995
|
if (!availability.available) {
|
|
2018
1996
|
throw new Error(
|
|
2019
|
-
`Agent CLI "${normalizedId}" is not available: ${availability.
|
|
1997
|
+
`Agent CLI "${normalizedId}" is not available: ${availability.error ?? "unknown reason"}.
|
|
2020
1998
|
Install the ${normalizedId} CLI or switch providers.
|
|
2021
1999
|
Run \`oac doctor\` for setup instructions.`
|
|
2022
2000
|
);
|
|
@@ -2254,14 +2232,7 @@ async function tryLoadOrAnalyzeEpics(ctx, params) {
|
|
|
2254
2232
|
return getPendingEpics(backlog);
|
|
2255
2233
|
}
|
|
2256
2234
|
function buildScannerList2(config, hasGitHubAuth) {
|
|
2257
|
-
|
|
2258
|
-
if (config?.discovery.scanners.lint !== false) scanners.push(new LintScanner());
|
|
2259
|
-
if (config?.discovery.scanners.todo !== false) scanners.push(new TodoScanner());
|
|
2260
|
-
if (config?.discovery.scanners.testGap !== false) {
|
|
2261
|
-
scanners.push(new TestGapScanner());
|
|
2262
|
-
}
|
|
2263
|
-
if (hasGitHubAuth) scanners.push(new GitHubIssuesScanner());
|
|
2264
|
-
return scanners;
|
|
2235
|
+
return buildScanners(config, hasGitHubAuth).instances;
|
|
2265
2236
|
}
|
|
2266
2237
|
function makeStubEstimate(taskId, providerId, tokens) {
|
|
2267
2238
|
return {
|
|
@@ -2348,7 +2319,7 @@ async function runEpicPipeline(ctx, params) {
|
|
|
2348
2319
|
ctx.suppressOutput,
|
|
2349
2320
|
`Executing ${epicTotal} epic(s)...`
|
|
2350
2321
|
);
|
|
2351
|
-
const epicQueue = new
|
|
2322
|
+
const epicQueue = new PQueue3({ concurrency });
|
|
2352
2323
|
const allTaskResults = await Promise.all(
|
|
2353
2324
|
epicPlan.selectedEpics.map(
|
|
2354
2325
|
(entry) => epicQueue.add(async () => {
|
|
@@ -2496,7 +2467,7 @@ function renderEpicPlanTable(ui, plan, budget) {
|
|
|
2496
2467
|
}
|
|
2497
2468
|
|
|
2498
2469
|
// src/cli/commands/run/retry.ts
|
|
2499
|
-
import { readFile as
|
|
2470
|
+
import { readFile as readFile5, readdir as readdir3 } from "fs/promises";
|
|
2500
2471
|
import { resolve as resolve6 } from "path";
|
|
2501
2472
|
async function readMostRecentContributionLog(repoPath) {
|
|
2502
2473
|
const contributionsPath = resolve6(repoPath, ".oac", "contributions");
|
|
@@ -2509,7 +2480,7 @@ async function readMostRecentContributionLog(repoPath) {
|
|
|
2509
2480
|
}
|
|
2510
2481
|
for (const fileName of entries) {
|
|
2511
2482
|
try {
|
|
2512
|
-
const content = await
|
|
2483
|
+
const content = await readFile5(resolve6(contributionsPath, fileName), "utf8");
|
|
2513
2484
|
const parsed = contributionLogSchema.safeParse(JSON.parse(content));
|
|
2514
2485
|
if (parsed.success) return parsed.data;
|
|
2515
2486
|
} catch {
|
|
@@ -2967,7 +2938,7 @@ function parseCsv(value) {
|
|
|
2967
2938
|
}
|
|
2968
2939
|
|
|
2969
2940
|
// src/cli/commands/status.ts
|
|
2970
|
-
import { readFile as
|
|
2941
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
2971
2942
|
import { resolve as resolve7 } from "path";
|
|
2972
2943
|
import { Command as Command12 } from "commander";
|
|
2973
2944
|
var WATCH_INTERVAL_MS = 2e3;
|
|
@@ -3009,7 +2980,7 @@ Examples:
|
|
|
3009
2980
|
async function readRunStatus(repoPath) {
|
|
3010
2981
|
const statusPath = resolve7(repoPath, ".oac", "status.json");
|
|
3011
2982
|
try {
|
|
3012
|
-
const raw = await
|
|
2983
|
+
const raw = await readFile6(statusPath, "utf8");
|
|
3013
2984
|
const payload = JSON.parse(raw);
|
|
3014
2985
|
return parseRunStatus(payload);
|
|
3015
2986
|
} catch (error) {
|
|
@@ -3020,7 +2991,7 @@ async function readRunStatus(repoPath) {
|
|
|
3020
2991
|
}
|
|
3021
2992
|
}
|
|
3022
2993
|
function parseRunStatus(payload) {
|
|
3023
|
-
if (!
|
|
2994
|
+
if (!isRecord(payload)) {
|
|
3024
2995
|
throw new Error("Invalid .oac/status.json format.");
|
|
3025
2996
|
}
|
|
3026
2997
|
const runId = payload.runId;
|
|
@@ -3038,7 +3009,7 @@ function parseRunStatus(payload) {
|
|
|
3038
3009
|
};
|
|
3039
3010
|
}
|
|
3040
3011
|
function parseRunStatusTask(task, index) {
|
|
3041
|
-
if (!
|
|
3012
|
+
if (!isRecord(task)) {
|
|
3042
3013
|
throw new Error(`Invalid task at index ${String(index)} in .oac/status.json.`);
|
|
3043
3014
|
}
|
|
3044
3015
|
const taskId = task.taskId;
|
|
@@ -3126,11 +3097,8 @@ function formatTaskList(tasks) {
|
|
|
3126
3097
|
}
|
|
3127
3098
|
return tasks.map((task) => `${task.taskId} (${task.title})`).join(", ");
|
|
3128
3099
|
}
|
|
3129
|
-
function isRecord2(value) {
|
|
3130
|
-
return typeof value === "object" && value !== null;
|
|
3131
|
-
}
|
|
3132
3100
|
function isFileNotFoundError3(error) {
|
|
3133
|
-
if (!
|
|
3101
|
+
if (!isRecord(error)) {
|
|
3134
3102
|
return false;
|
|
3135
3103
|
}
|
|
3136
3104
|
return error.code === "ENOENT";
|
|
@@ -3151,7 +3119,7 @@ function registerCommands(program) {
|
|
|
3151
3119
|
program.addCommand(createExplainCommand());
|
|
3152
3120
|
}
|
|
3153
3121
|
async function createCliProgram() {
|
|
3154
|
-
const version = true ? "2026.
|
|
3122
|
+
const version = true ? "2026.220.1" : "0.0.0";
|
|
3155
3123
|
const program = new Command13();
|
|
3156
3124
|
program.name("oac").description("Open Agent Contribution CLI").version(version).option("--config <path>", "Config file path", "oac.config.ts").option("--verbose", "Enable verbose logging", false).option("--quiet", "Suppress non-error output", false).option("--json", "Output machine-readable JSON", false).option("--no-color", "Disable ANSI colors");
|
|
3157
3125
|
registerCommands(program);
|
|
@@ -3181,4 +3149,4 @@ export {
|
|
|
3181
3149
|
createCliProgram,
|
|
3182
3150
|
runCli
|
|
3183
3151
|
};
|
|
3184
|
-
//# sourceMappingURL=chunk-
|
|
3152
|
+
//# sourceMappingURL=chunk-7Y4LZUDP.js.map
|