@open-code-review/cli 2.3.0 → 2.4.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/dist/dashboard/server.js +16 -0
- package/dist/index.js +88 -3
- package/package.json +4 -4
package/dist/dashboard/server.js
CHANGED
|
@@ -35769,6 +35769,7 @@ var import_express14 = __toESM(require_express2(), 1);
|
|
|
35769
35769
|
var import_yaml = __toESM(require_dist(), 1);
|
|
35770
35770
|
import { existsSync as existsSync12, readFileSync as readFileSync8 } from "node:fs";
|
|
35771
35771
|
import { join as join16 } from "node:path";
|
|
35772
|
+
var MAX_INSTANCES_PER_PERSONA = 50;
|
|
35772
35773
|
function loadTeamConfig(ocrDir) {
|
|
35773
35774
|
const configPath = join16(ocrDir, "config.yaml");
|
|
35774
35775
|
if (!existsSync12(configPath)) {
|
|
@@ -35830,6 +35831,11 @@ function parseEntry(persona, entry) {
|
|
|
35830
35831
|
`default_team.${persona}: count must be a positive integer (got ${entry})`
|
|
35831
35832
|
);
|
|
35832
35833
|
}
|
|
35834
|
+
if (entry > MAX_INSTANCES_PER_PERSONA) {
|
|
35835
|
+
throw new Error(
|
|
35836
|
+
`default_team.${persona}: count must be <= ${MAX_INSTANCES_PER_PERSONA} (got ${entry})`
|
|
35837
|
+
);
|
|
35838
|
+
}
|
|
35833
35839
|
return Array.from({ length: entry }, () => ({}));
|
|
35834
35840
|
}
|
|
35835
35841
|
if (Array.isArray(entry)) {
|
|
@@ -35838,6 +35844,11 @@ function parseEntry(persona, entry) {
|
|
|
35838
35844
|
`default_team.${persona}: list form must contain at least one instance`
|
|
35839
35845
|
);
|
|
35840
35846
|
}
|
|
35847
|
+
if (entry.length > MAX_INSTANCES_PER_PERSONA) {
|
|
35848
|
+
throw new Error(
|
|
35849
|
+
`default_team.${persona}: list form must contain <= ${MAX_INSTANCES_PER_PERSONA} instances (got ${entry.length})`
|
|
35850
|
+
);
|
|
35851
|
+
}
|
|
35841
35852
|
return entry.map((item, idx) => parseListItem(persona, idx, item));
|
|
35842
35853
|
}
|
|
35843
35854
|
if (entry && typeof entry === "object") {
|
|
@@ -35859,6 +35870,11 @@ function parseEntry(persona, entry) {
|
|
|
35859
35870
|
`default_team.${persona}: count must be a positive integer (got ${String(count)})`
|
|
35860
35871
|
);
|
|
35861
35872
|
}
|
|
35873
|
+
if (count > MAX_INSTANCES_PER_PERSONA) {
|
|
35874
|
+
throw new Error(
|
|
35875
|
+
`default_team.${persona}: count must be <= ${MAX_INSTANCES_PER_PERSONA} (got ${count})`
|
|
35876
|
+
);
|
|
35877
|
+
}
|
|
35862
35878
|
const teamModel = readOptionalString(obj, "model", `default_team.${persona}.model`);
|
|
35863
35879
|
return Array.from({ length: count }, () => ({ teamModel }));
|
|
35864
35880
|
}
|
package/dist/index.js
CHANGED
|
@@ -30024,6 +30024,7 @@ function ensureGitignore(ocrDir) {
|
|
|
30024
30024
|
var import_yaml = __toESM(require_dist(), 1);
|
|
30025
30025
|
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
30026
30026
|
import { join as join2 } from "node:path";
|
|
30027
|
+
var MAX_INSTANCES_PER_PERSONA = 50;
|
|
30027
30028
|
function loadTeamConfig(ocrDir) {
|
|
30028
30029
|
const configPath = join2(ocrDir, "config.yaml");
|
|
30029
30030
|
if (!existsSync2(configPath)) {
|
|
@@ -30085,6 +30086,11 @@ function parseEntry(persona, entry) {
|
|
|
30085
30086
|
`default_team.${persona}: count must be a positive integer (got ${entry})`
|
|
30086
30087
|
);
|
|
30087
30088
|
}
|
|
30089
|
+
if (entry > MAX_INSTANCES_PER_PERSONA) {
|
|
30090
|
+
throw new Error(
|
|
30091
|
+
`default_team.${persona}: count must be <= ${MAX_INSTANCES_PER_PERSONA} (got ${entry})`
|
|
30092
|
+
);
|
|
30093
|
+
}
|
|
30088
30094
|
return Array.from({ length: entry }, () => ({}));
|
|
30089
30095
|
}
|
|
30090
30096
|
if (Array.isArray(entry)) {
|
|
@@ -30093,6 +30099,11 @@ function parseEntry(persona, entry) {
|
|
|
30093
30099
|
`default_team.${persona}: list form must contain at least one instance`
|
|
30094
30100
|
);
|
|
30095
30101
|
}
|
|
30102
|
+
if (entry.length > MAX_INSTANCES_PER_PERSONA) {
|
|
30103
|
+
throw new Error(
|
|
30104
|
+
`default_team.${persona}: list form must contain <= ${MAX_INSTANCES_PER_PERSONA} instances (got ${entry.length})`
|
|
30105
|
+
);
|
|
30106
|
+
}
|
|
30096
30107
|
return entry.map((item, idx) => parseListItem(persona, idx, item));
|
|
30097
30108
|
}
|
|
30098
30109
|
if (entry && typeof entry === "object") {
|
|
@@ -30114,6 +30125,11 @@ function parseEntry(persona, entry) {
|
|
|
30114
30125
|
`default_team.${persona}: count must be a positive integer (got ${String(count)})`
|
|
30115
30126
|
);
|
|
30116
30127
|
}
|
|
30128
|
+
if (count > MAX_INSTANCES_PER_PERSONA) {
|
|
30129
|
+
throw new Error(
|
|
30130
|
+
`default_team.${persona}: count must be <= ${MAX_INSTANCES_PER_PERSONA} (got ${count})`
|
|
30131
|
+
);
|
|
30132
|
+
}
|
|
30117
30133
|
const teamModel = readOptionalString(obj, "model", `default_team.${persona}.model`);
|
|
30118
30134
|
return Array.from({ length: count }, () => ({ teamModel }));
|
|
30119
30135
|
}
|
|
@@ -30206,6 +30222,71 @@ function resolveTeamComposition(team, override) {
|
|
|
30206
30222
|
}
|
|
30207
30223
|
return result;
|
|
30208
30224
|
}
|
|
30225
|
+
var REVIEWER_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
30226
|
+
function parseTeamSpec(spec, aliases = {}, defaultModel = null) {
|
|
30227
|
+
const trimmed = spec.trim();
|
|
30228
|
+
if (trimmed.length === 0) {
|
|
30229
|
+
throw new Error(
|
|
30230
|
+
"--team spec is empty; expected reviewer-id:count[,reviewer-id:count...]"
|
|
30231
|
+
);
|
|
30232
|
+
}
|
|
30233
|
+
const model = resolveModel(null, null, aliases, defaultModel);
|
|
30234
|
+
if (model !== null) assertSafeModelId(model, "--team");
|
|
30235
|
+
const seen = /* @__PURE__ */ new Set();
|
|
30236
|
+
const result = [];
|
|
30237
|
+
for (const rawEntry of trimmed.split(",")) {
|
|
30238
|
+
const entry = rawEntry.trim();
|
|
30239
|
+
if (entry.length === 0) {
|
|
30240
|
+
throw new Error(
|
|
30241
|
+
`--team has an empty entry (stray or trailing comma) in "${spec}"`
|
|
30242
|
+
);
|
|
30243
|
+
}
|
|
30244
|
+
const colon = entry.indexOf(":");
|
|
30245
|
+
if (colon === -1) {
|
|
30246
|
+
throw new Error(
|
|
30247
|
+
`--team entry "${entry}" must be "reviewer-id:count" \u2014 the :count is required`
|
|
30248
|
+
);
|
|
30249
|
+
}
|
|
30250
|
+
const persona = entry.slice(0, colon).trim();
|
|
30251
|
+
const countRaw = entry.slice(colon + 1).trim();
|
|
30252
|
+
if (!REVIEWER_ID_PATTERN.test(persona)) {
|
|
30253
|
+
throw new Error(
|
|
30254
|
+
`--team reviewer id "${persona}" is invalid; expected lowercase letters, digits, and single hyphens (e.g. principal, martin-fowler)`
|
|
30255
|
+
);
|
|
30256
|
+
}
|
|
30257
|
+
if (seen.has(persona)) {
|
|
30258
|
+
throw new Error(
|
|
30259
|
+
`--team lists "${persona}" more than once; combine its instances into a single entry (e.g. ${persona}:2)`
|
|
30260
|
+
);
|
|
30261
|
+
}
|
|
30262
|
+
if (!/^[0-9]+$/.test(countRaw)) {
|
|
30263
|
+
throw new Error(
|
|
30264
|
+
`--team count for "${persona}" must be a positive integer (got "${countRaw}")`
|
|
30265
|
+
);
|
|
30266
|
+
}
|
|
30267
|
+
const count = Number(countRaw);
|
|
30268
|
+
if (count < 1) {
|
|
30269
|
+
throw new Error(
|
|
30270
|
+
`--team count for "${persona}" must be a positive integer (got ${count})`
|
|
30271
|
+
);
|
|
30272
|
+
}
|
|
30273
|
+
if (count > MAX_INSTANCES_PER_PERSONA) {
|
|
30274
|
+
throw new Error(
|
|
30275
|
+
`--team count for "${persona}" must be <= ${MAX_INSTANCES_PER_PERSONA} (got ${count})`
|
|
30276
|
+
);
|
|
30277
|
+
}
|
|
30278
|
+
seen.add(persona);
|
|
30279
|
+
for (let i = 0; i < count; i++) {
|
|
30280
|
+
result.push({
|
|
30281
|
+
persona,
|
|
30282
|
+
instance_index: i + 1,
|
|
30283
|
+
name: `${persona}-${i + 1}`,
|
|
30284
|
+
model
|
|
30285
|
+
});
|
|
30286
|
+
}
|
|
30287
|
+
}
|
|
30288
|
+
return result;
|
|
30289
|
+
}
|
|
30209
30290
|
|
|
30210
30291
|
// src/lib/installer.ts
|
|
30211
30292
|
init_src();
|
|
@@ -30770,7 +30851,7 @@ ${hint}
|
|
|
30770
30851
|
}
|
|
30771
30852
|
|
|
30772
30853
|
// src/lib/version.ts
|
|
30773
|
-
var CLI_VERSION = true ? "2.
|
|
30854
|
+
var CLI_VERSION = true ? "2.4.0" : createRequire(import.meta.url)("../../package.json").version;
|
|
30774
30855
|
|
|
30775
30856
|
// src/lib/deps.ts
|
|
30776
30857
|
init_src();
|
|
@@ -36641,6 +36722,9 @@ function parseSessionOverride(raw) {
|
|
|
36641
36722
|
return result;
|
|
36642
36723
|
}
|
|
36643
36724
|
var resolveSubcommand = new Command("resolve").description("Resolve and print the team composition for the active workspace").option(
|
|
36725
|
+
"--team <spec>",
|
|
36726
|
+
"Session team override replacing default_team. Format: reviewer-id:count[,reviewer-id:count...] (e.g. principal:2,architect:1)"
|
|
36727
|
+
).option(
|
|
36644
36728
|
"--session-override <json>",
|
|
36645
36729
|
"JSON array of ReviewerInstance overrides applied on top of disk config"
|
|
36646
36730
|
).option("--session-override-stdin", "Read --session-override JSON from stdin").option("--json", "Emit JSON for programmatic consumption (the AI workflow uses this)").action(
|
|
@@ -36649,7 +36733,8 @@ var resolveSubcommand = new Command("resolve").description("Resolve and print th
|
|
|
36649
36733
|
requireOcrSetup(targetDir);
|
|
36650
36734
|
const ocrDir = join21(targetDir, ".ocr");
|
|
36651
36735
|
try {
|
|
36652
|
-
const { team } = loadTeamConfig(ocrDir);
|
|
36736
|
+
const { team, aliases, defaultModel } = loadTeamConfig(ocrDir);
|
|
36737
|
+
const baseTeam = options.team ? parseTeamSpec(options.team, aliases, defaultModel) : team;
|
|
36653
36738
|
let override;
|
|
36654
36739
|
if (options.sessionOverride) {
|
|
36655
36740
|
override = parseSessionOverride(options.sessionOverride);
|
|
@@ -36659,7 +36744,7 @@ var resolveSubcommand = new Command("resolve").description("Resolve and print th
|
|
|
36659
36744
|
override = parseSessionOverride(raw);
|
|
36660
36745
|
}
|
|
36661
36746
|
}
|
|
36662
|
-
const resolved = resolveTeamComposition(
|
|
36747
|
+
const resolved = resolveTeamComposition(baseTeam, override);
|
|
36663
36748
|
if (options.json) {
|
|
36664
36749
|
console.log(JSON.stringify(resolved, null, 2));
|
|
36665
36750
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-code-review/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "CLI for Open Code Review - Multi-environment setup and progress tracking",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
"ora": "^8.1.1",
|
|
46
46
|
"socket.io": "^4.8",
|
|
47
47
|
"yaml": "^2.8.3",
|
|
48
|
-
"@open-code-review/agents": "2.
|
|
48
|
+
"@open-code-review/agents": "2.4.0"
|
|
49
49
|
},
|
|
50
50
|
"publishConfig": {
|
|
51
51
|
"access": "public"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@open-code-review/
|
|
54
|
+
"@open-code-review/config": "0.0.0",
|
|
55
55
|
"@open-code-review/persistence": "0.0.0",
|
|
56
|
-
"@open-code-review/
|
|
56
|
+
"@open-code-review/platform": "0.0.0"
|
|
57
57
|
}
|
|
58
58
|
}
|