@pourkit/cli 0.0.0-next-20260703025114 → 0.0.0-next-20260703225916
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/cli.js +234 -250
- package/dist/cli.js.map +1 -1
- package/dist/e2e/run-live-e2e.js +230 -246
- package/dist/e2e/run-live-e2e.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -355,8 +355,234 @@ import { Command, Option, CommanderError } from "commander";
|
|
|
355
355
|
// shared/config.ts
|
|
356
356
|
import { existsSync, readFileSync } from "fs";
|
|
357
357
|
import { fileURLToPath } from "url";
|
|
358
|
-
import { dirname,
|
|
358
|
+
import { dirname, join, resolve } from "path";
|
|
359
359
|
import Ajv from "ajv";
|
|
360
|
+
|
|
361
|
+
// shared/config-normalization.ts
|
|
362
|
+
import { isAbsolute, normalize, sep } from "path";
|
|
363
|
+
var DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES = 3;
|
|
364
|
+
var DEFAULT_BRANCH_TEMPLATE = "pourkit/{{issue.number}}/{{issue.slug}}";
|
|
365
|
+
function applyOutputRetriesDefaults(retries) {
|
|
366
|
+
if (retries === void 0) return void 0;
|
|
367
|
+
return {
|
|
368
|
+
missingOrEmpty: retries.missingOrEmpty ?? DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function applyStageAgentDefaults(agent) {
|
|
372
|
+
return {
|
|
373
|
+
...agent,
|
|
374
|
+
outputRetries: applyOutputRetriesDefaults(agent.outputRetries)
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function assertRepoRelativePath(value, location) {
|
|
378
|
+
const normalized = normalize(value);
|
|
379
|
+
if (isAbsolute(value) || isAbsolute(normalized) || normalized === ".." || normalized.startsWith(`..${sep}`)) {
|
|
380
|
+
throw new Error(
|
|
381
|
+
`${location} must stay within the repository and be repo-relative; got "${value}"`
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
function assertBaseBranch(value, location) {
|
|
386
|
+
if (value.includes("/")) {
|
|
387
|
+
throw new Error(
|
|
388
|
+
`${location} must be a local branch name, not a remote-qualified, tag, ref, or path-like name; got "${value}"`
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
if (/^[0-9a-f]{7,40}$/i.test(value)) {
|
|
392
|
+
throw new Error(
|
|
393
|
+
`${location} must be a branch name, not a commit SHA; got "${value}"`
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
function assertStageAgentPath(agent, location) {
|
|
398
|
+
if (!agent) return;
|
|
399
|
+
assertRepoRelativePath(agent.promptTemplate, `${location}.promptTemplate`);
|
|
400
|
+
}
|
|
401
|
+
function validateConfigSemantics(input) {
|
|
402
|
+
const sandbox = input.sandbox;
|
|
403
|
+
sandbox.copyToWorktree?.forEach((entry, index) => {
|
|
404
|
+
assertRepoRelativePath(entry, `sandbox.copyToWorktree[${index}]`);
|
|
405
|
+
});
|
|
406
|
+
const targetNames = /* @__PURE__ */ new Set();
|
|
407
|
+
for (const [targetIndex, target] of input.targets.entries()) {
|
|
408
|
+
if (targetNames.has(target.name)) {
|
|
409
|
+
throw new Error(
|
|
410
|
+
`Duplicate target name "${target.name}"; target names must be unique`
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
targetNames.add(target.name);
|
|
414
|
+
assertBaseBranch(target.baseBranch, `targets[${targetIndex}].baseBranch`);
|
|
415
|
+
assertStageAgentPath(
|
|
416
|
+
target.strategy.implement.builder,
|
|
417
|
+
`targets[${targetIndex}].strategy.implement.builder`
|
|
418
|
+
);
|
|
419
|
+
assertStageAgentPath(
|
|
420
|
+
target.strategy.failureResolution,
|
|
421
|
+
`targets[${targetIndex}].strategy.failureResolution`
|
|
422
|
+
);
|
|
423
|
+
assertStageAgentPath(
|
|
424
|
+
target.strategy.review.reviewer,
|
|
425
|
+
`targets[${targetIndex}].strategy.review.reviewer`
|
|
426
|
+
);
|
|
427
|
+
assertStageAgentPath(
|
|
428
|
+
target.strategy.review.refactor,
|
|
429
|
+
`targets[${targetIndex}].strategy.review.refactor`
|
|
430
|
+
);
|
|
431
|
+
assertStageAgentPath(
|
|
432
|
+
target.strategy.issueFinalReview,
|
|
433
|
+
`targets[${targetIndex}].strategy.issueFinalReview`
|
|
434
|
+
);
|
|
435
|
+
assertStageAgentPath(
|
|
436
|
+
target.strategy.finalize.prDescriptionAgent,
|
|
437
|
+
`targets[${targetIndex}].strategy.finalize.prDescriptionAgent`
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function normalizePourkitConfig(input) {
|
|
442
|
+
const targets = input.targets.map((t) => {
|
|
443
|
+
const setupCommands = t.setupCommands?.map((cmd, i) => ({
|
|
444
|
+
command: cmd.command,
|
|
445
|
+
label: cmd.label ?? `check-${i}`
|
|
446
|
+
}));
|
|
447
|
+
const verifyLabeled = t.strategy.verify?.commands.map((cmd, i) => ({
|
|
448
|
+
command: cmd.command,
|
|
449
|
+
label: cmd.label ?? `check-${i}`
|
|
450
|
+
}));
|
|
451
|
+
return {
|
|
452
|
+
name: t.name,
|
|
453
|
+
baseBranch: t.baseBranch,
|
|
454
|
+
branchTemplate: t.branchTemplate ?? DEFAULT_BRANCH_TEMPLATE,
|
|
455
|
+
prdRun: t.prdRun,
|
|
456
|
+
setupCommands,
|
|
457
|
+
autoMerge: t.autoMerge ?? true,
|
|
458
|
+
queue: t.queue,
|
|
459
|
+
serena: t.serena,
|
|
460
|
+
strategy: {
|
|
461
|
+
type: "review-refactor-loop",
|
|
462
|
+
implement: {
|
|
463
|
+
builder: applyStageAgentDefaults(
|
|
464
|
+
t.strategy.implement.builder
|
|
465
|
+
)
|
|
466
|
+
},
|
|
467
|
+
failureResolution: {
|
|
468
|
+
agent: t.strategy.failureResolution.agent,
|
|
469
|
+
model: t.strategy.failureResolution.model,
|
|
470
|
+
variant: t.strategy.failureResolution.variant,
|
|
471
|
+
env: t.strategy.failureResolution.env,
|
|
472
|
+
promptTemplate: t.strategy.failureResolution.promptTemplate,
|
|
473
|
+
outputRetries: applyOutputRetriesDefaults(
|
|
474
|
+
t.strategy.failureResolution.outputRetries
|
|
475
|
+
),
|
|
476
|
+
maxAttemptsPerFailure: t.strategy.failureResolution.maxAttemptsPerFailure,
|
|
477
|
+
failureLimits: t.strategy.failureResolution.failureLimits
|
|
478
|
+
},
|
|
479
|
+
review: {
|
|
480
|
+
reviewer: {
|
|
481
|
+
agent: t.strategy.review.reviewer.agent,
|
|
482
|
+
model: t.strategy.review.reviewer.model,
|
|
483
|
+
variant: t.strategy.review.reviewer.variant,
|
|
484
|
+
env: t.strategy.review.reviewer.env,
|
|
485
|
+
promptTemplate: t.strategy.review.reviewer.promptTemplate,
|
|
486
|
+
outputRetries: applyOutputRetriesDefaults(
|
|
487
|
+
t.strategy.review.reviewer.outputRetries
|
|
488
|
+
),
|
|
489
|
+
criteria: t.strategy.review.reviewer.criteria,
|
|
490
|
+
includeReviewHistory: t.strategy.review.reviewer.includeReviewHistory
|
|
491
|
+
},
|
|
492
|
+
refactor: applyStageAgentDefaults(
|
|
493
|
+
t.strategy.review.refactor
|
|
494
|
+
),
|
|
495
|
+
maxIterations: t.strategy.review.maxIterations
|
|
496
|
+
},
|
|
497
|
+
...verifyLabeled ? { verify: { commands: verifyLabeled } } : {},
|
|
498
|
+
issueFinalReview: {
|
|
499
|
+
agent: t.strategy.issueFinalReview.agent,
|
|
500
|
+
model: t.strategy.issueFinalReview.model,
|
|
501
|
+
variant: t.strategy.issueFinalReview.variant,
|
|
502
|
+
env: t.strategy.issueFinalReview.env,
|
|
503
|
+
promptTemplate: t.strategy.issueFinalReview.promptTemplate,
|
|
504
|
+
outputRetries: applyOutputRetriesDefaults(
|
|
505
|
+
t.strategy.issueFinalReview.outputRetries
|
|
506
|
+
),
|
|
507
|
+
maxAttempts: t.strategy.issueFinalReview.maxAttempts
|
|
508
|
+
},
|
|
509
|
+
finalize: {
|
|
510
|
+
prDescriptionAgent: applyStageAgentDefaults(
|
|
511
|
+
t.strategy.finalize.prDescriptionAgent
|
|
512
|
+
),
|
|
513
|
+
maxAttempts: t.strategy.finalize.maxAttempts
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
});
|
|
518
|
+
const serenaConfig = input.serena;
|
|
519
|
+
const serenaDefaults = {
|
|
520
|
+
mcpUrl: serenaConfig?.mcpUrl ?? "http://localhost:9121/mcp",
|
|
521
|
+
sandboxMcpUrl: serenaConfig?.sandboxMcpUrl ?? "http://localhost:9121/mcp",
|
|
522
|
+
dataDir: serenaConfig?.dataDir ?? ".pourkit/serena/"
|
|
523
|
+
};
|
|
524
|
+
const serena = {
|
|
525
|
+
enabled: serenaConfig?.enabled ?? false,
|
|
526
|
+
required: serenaConfig?.required ?? false,
|
|
527
|
+
mcpUrl: process.env.POURKIT_SERENA_MCP_URL ?? serenaDefaults.mcpUrl,
|
|
528
|
+
sandboxMcpUrl: process.env.POURKIT_SERENA_SANDBOX_MCP_URL ?? serenaDefaults.sandboxMcpUrl,
|
|
529
|
+
dataDir: serenaDefaults.dataDir,
|
|
530
|
+
autoStart: serenaConfig?.autoStart ?? false
|
|
531
|
+
};
|
|
532
|
+
if (serena.mcpUrl.trim() === "") {
|
|
533
|
+
throw new Error("POURKIT_SERENA_MCP_URL must be a non-empty string");
|
|
534
|
+
}
|
|
535
|
+
if (serena.sandboxMcpUrl.trim() === "") {
|
|
536
|
+
throw new Error(
|
|
537
|
+
"POURKIT_SERENA_SANDBOX_MCP_URL must be a non-empty string"
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
const labels = input.labels;
|
|
541
|
+
const cleanupConfig = input.cleanup;
|
|
542
|
+
const sandboxInput = input.sandbox;
|
|
543
|
+
const checksInput = input.checks;
|
|
544
|
+
const memoryInput = input.memory;
|
|
545
|
+
return {
|
|
546
|
+
targets,
|
|
547
|
+
labels: {
|
|
548
|
+
readyForAgent: labels?.readyForAgent ?? "ready-for-agent",
|
|
549
|
+
agentInProgress: labels?.agentInProgress ?? "agent-in-progress",
|
|
550
|
+
blocked: labels?.blocked ?? "blocked",
|
|
551
|
+
prOpenAwaitingMerge: labels?.prOpenAwaitingMerge ?? "pr-open-awaiting-merge",
|
|
552
|
+
readyForHuman: labels?.readyForHuman ?? "ready-for-human",
|
|
553
|
+
needsTriage: labels?.needsTriage ?? "needs-triage"
|
|
554
|
+
},
|
|
555
|
+
sandbox: {
|
|
556
|
+
provider: sandboxInput.provider,
|
|
557
|
+
copyToWorktree: sandboxInput.copyToWorktree,
|
|
558
|
+
mounts: sandboxInput.mounts ? sandboxInput.mounts.map((m) => ({
|
|
559
|
+
hostPath: m.hostPath,
|
|
560
|
+
sandboxPath: m.sandboxPath,
|
|
561
|
+
readonly: m.readonly ?? false
|
|
562
|
+
})) : void 0,
|
|
563
|
+
env: sandboxInput.env,
|
|
564
|
+
idleTimeoutSeconds: sandboxInput.idleTimeoutSeconds,
|
|
565
|
+
forceRebuild: sandboxInput.forceRebuild
|
|
566
|
+
},
|
|
567
|
+
checks: {
|
|
568
|
+
requiredLabels: checksInput.requiredLabels,
|
|
569
|
+
allowedAuthors: checksInput.allowedAuthors,
|
|
570
|
+
checksFoundTimeoutSeconds: checksInput.checksFoundTimeoutSeconds ?? 60,
|
|
571
|
+
checksCompletionTimeoutSeconds: checksInput.checksCompletionTimeoutSeconds ?? 30 * 60,
|
|
572
|
+
pollIntervalSeconds: checksInput.pollIntervalSeconds ?? 15,
|
|
573
|
+
issueListLimit: checksInput.issueListLimit ?? 50
|
|
574
|
+
},
|
|
575
|
+
serena,
|
|
576
|
+
cleanup: {
|
|
577
|
+
enabled: cleanupConfig?.enabled ?? true,
|
|
578
|
+
worktreeRetentionDays: cleanupConfig?.worktreeRetentionDays ?? 14,
|
|
579
|
+
logRetentionDays: cleanupConfig?.logRetentionDays ?? 30
|
|
580
|
+
},
|
|
581
|
+
memory: memoryInput
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// shared/config.ts
|
|
360
586
|
var __filename = fileURLToPath(import.meta.url);
|
|
361
587
|
var __dirname = dirname(__filename);
|
|
362
588
|
function resolvePackagedAssetPath(fileName) {
|
|
@@ -386,8 +612,6 @@ function getValidator() {
|
|
|
386
612
|
}
|
|
387
613
|
return _validate;
|
|
388
614
|
}
|
|
389
|
-
var DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES = 3;
|
|
390
|
-
var DEFAULT_BRANCH_TEMPLATE = "pourkit/{{issue.number}}/{{issue.slug}}";
|
|
391
615
|
function resolveMissingOrEmptyOutputRetries(config) {
|
|
392
616
|
return config?.outputRetries?.missingOrEmpty ?? DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES;
|
|
393
617
|
}
|
|
@@ -555,98 +779,6 @@ function formatFirstAjvError(errors) {
|
|
|
555
779
|
}
|
|
556
780
|
return `${path9 || "Config"} ${error.message || "is invalid"}`;
|
|
557
781
|
}
|
|
558
|
-
function applyOutputRetriesDefaults(retries) {
|
|
559
|
-
if (retries === void 0) return void 0;
|
|
560
|
-
return {
|
|
561
|
-
missingOrEmpty: retries.missingOrEmpty ?? DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
function applyStageAgentDefaults(agent) {
|
|
565
|
-
return {
|
|
566
|
-
...agent,
|
|
567
|
-
outputRetries: applyOutputRetriesDefaults(agent.outputRetries)
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
function assertRepoRelativePath(value, location) {
|
|
571
|
-
const normalized = normalize(value);
|
|
572
|
-
if (isAbsolute(value) || isAbsolute(normalized) || normalized === ".." || normalized.startsWith(`..${sep}`)) {
|
|
573
|
-
throw new Error(
|
|
574
|
-
`${location} must stay within the repository and be repo-relative; got "${value}"`
|
|
575
|
-
);
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
function assertBaseBranch(value, location) {
|
|
579
|
-
if (value.includes("/")) {
|
|
580
|
-
throw new Error(
|
|
581
|
-
`${location} must be a local branch name, not a remote-qualified, tag, ref, or path-like name; got "${value}"`
|
|
582
|
-
);
|
|
583
|
-
}
|
|
584
|
-
if (/^[0-9a-f]{7,40}$/i.test(value)) {
|
|
585
|
-
throw new Error(
|
|
586
|
-
`${location} must be a branch name, not a commit SHA; got "${value}"`
|
|
587
|
-
);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
function assertStageAgentPath(agent, location) {
|
|
591
|
-
if (!agent) return;
|
|
592
|
-
const promptTemplate = agent.promptTemplate;
|
|
593
|
-
if (typeof promptTemplate === "string") {
|
|
594
|
-
assertRepoRelativePath(promptTemplate, `${location}.promptTemplate`);
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
function validateConfigSemantics(data) {
|
|
598
|
-
const sandbox = data.sandbox;
|
|
599
|
-
const copyToWorktree = sandbox?.copyToWorktree;
|
|
600
|
-
copyToWorktree?.forEach((entry, index) => {
|
|
601
|
-
assertRepoRelativePath(entry, `sandbox.copyToWorktree[${index}]`);
|
|
602
|
-
});
|
|
603
|
-
const targetNames = /* @__PURE__ */ new Set();
|
|
604
|
-
data.targets.forEach((target, targetIndex) => {
|
|
605
|
-
const name = target.name;
|
|
606
|
-
if (targetNames.has(name)) {
|
|
607
|
-
throw new Error(
|
|
608
|
-
`Duplicate target name "${name}"; target names must be unique`
|
|
609
|
-
);
|
|
610
|
-
}
|
|
611
|
-
targetNames.add(name);
|
|
612
|
-
assertBaseBranch(
|
|
613
|
-
target.baseBranch,
|
|
614
|
-
`targets[${targetIndex}].baseBranch`
|
|
615
|
-
);
|
|
616
|
-
const strategy = target.strategy;
|
|
617
|
-
const implement = strategy.implement;
|
|
618
|
-
const review = strategy.review;
|
|
619
|
-
const finalize = strategy.finalize;
|
|
620
|
-
assertStageAgentPath(
|
|
621
|
-
implement.builder,
|
|
622
|
-
`targets[${targetIndex}].strategy.implement.builder`
|
|
623
|
-
);
|
|
624
|
-
assertStageAgentPath(
|
|
625
|
-
strategy.conflictResolution,
|
|
626
|
-
`targets[${targetIndex}].strategy.conflictResolution`
|
|
627
|
-
);
|
|
628
|
-
assertStageAgentPath(
|
|
629
|
-
strategy.failureResolution,
|
|
630
|
-
`targets[${targetIndex}].strategy.failureResolution`
|
|
631
|
-
);
|
|
632
|
-
assertStageAgentPath(
|
|
633
|
-
review.reviewer,
|
|
634
|
-
`targets[${targetIndex}].strategy.review.reviewer`
|
|
635
|
-
);
|
|
636
|
-
assertStageAgentPath(
|
|
637
|
-
review.refactor,
|
|
638
|
-
`targets[${targetIndex}].strategy.review.refactor`
|
|
639
|
-
);
|
|
640
|
-
assertStageAgentPath(
|
|
641
|
-
strategy.issueFinalReview,
|
|
642
|
-
`targets[${targetIndex}].strategy.issueFinalReview`
|
|
643
|
-
);
|
|
644
|
-
assertStageAgentPath(
|
|
645
|
-
finalize.prDescriptionAgent,
|
|
646
|
-
`targets[${targetIndex}].strategy.finalize.prDescriptionAgent`
|
|
647
|
-
);
|
|
648
|
-
});
|
|
649
|
-
}
|
|
650
782
|
function assertKnownKeys(value, path9, knownKeys) {
|
|
651
783
|
for (const key of Object.keys(value)) {
|
|
652
784
|
if (!knownKeys.includes(key)) {
|
|
@@ -731,157 +863,9 @@ function parseConfig(raw) {
|
|
|
731
863
|
)
|
|
732
864
|
);
|
|
733
865
|
}
|
|
734
|
-
const
|
|
735
|
-
validateConfigSemantics(
|
|
736
|
-
|
|
737
|
-
(t) => {
|
|
738
|
-
const input = t;
|
|
739
|
-
const strategy = input.strategy;
|
|
740
|
-
const implement = strategy.implement;
|
|
741
|
-
const failureResolution = strategy.failureResolution;
|
|
742
|
-
const review = strategy.review;
|
|
743
|
-
const reviewReviewer = review.reviewer;
|
|
744
|
-
const reviewRefactor = review.refactor;
|
|
745
|
-
const finalize = strategy.finalize;
|
|
746
|
-
const issueFinalReview = strategy.issueFinalReview;
|
|
747
|
-
const setupCommands = input.setupCommands?.map((cmd, i) => ({
|
|
748
|
-
command: cmd.command,
|
|
749
|
-
label: cmd.label ?? `check-${i}`
|
|
750
|
-
}));
|
|
751
|
-
const verifyCommands = strategy.verify?.commands ? strategy.verify.commands : void 0;
|
|
752
|
-
const verifyLabeled = verifyCommands?.map((cmd, i) => ({
|
|
753
|
-
command: cmd.command,
|
|
754
|
-
label: cmd.label ?? `check-${i}`
|
|
755
|
-
}));
|
|
756
|
-
return {
|
|
757
|
-
name: input.name,
|
|
758
|
-
baseBranch: input.baseBranch,
|
|
759
|
-
branchTemplate: input.branchTemplate ?? DEFAULT_BRANCH_TEMPLATE,
|
|
760
|
-
prdRun: input.prdRun,
|
|
761
|
-
setupCommands,
|
|
762
|
-
autoMerge: input.autoMerge !== void 0 ? input.autoMerge : true,
|
|
763
|
-
queue: input.queue,
|
|
764
|
-
serena: input.serena,
|
|
765
|
-
strategy: {
|
|
766
|
-
type: "review-refactor-loop",
|
|
767
|
-
implement: {
|
|
768
|
-
builder: applyStageAgentDefaults(
|
|
769
|
-
implement.builder
|
|
770
|
-
)
|
|
771
|
-
},
|
|
772
|
-
failureResolution: {
|
|
773
|
-
agent: failureResolution.agent,
|
|
774
|
-
model: failureResolution.model,
|
|
775
|
-
variant: failureResolution.variant,
|
|
776
|
-
env: failureResolution.env,
|
|
777
|
-
promptTemplate: failureResolution.promptTemplate,
|
|
778
|
-
outputRetries: applyOutputRetriesDefaults(
|
|
779
|
-
failureResolution.outputRetries
|
|
780
|
-
),
|
|
781
|
-
maxAttemptsPerFailure: failureResolution.maxAttemptsPerFailure,
|
|
782
|
-
failureLimits: failureResolution.failureLimits
|
|
783
|
-
},
|
|
784
|
-
review: {
|
|
785
|
-
reviewer: {
|
|
786
|
-
agent: reviewReviewer.agent,
|
|
787
|
-
model: reviewReviewer.model,
|
|
788
|
-
variant: reviewReviewer.variant,
|
|
789
|
-
env: reviewReviewer.env,
|
|
790
|
-
promptTemplate: reviewReviewer.promptTemplate,
|
|
791
|
-
outputRetries: applyOutputRetriesDefaults(
|
|
792
|
-
reviewReviewer.outputRetries
|
|
793
|
-
),
|
|
794
|
-
criteria: reviewReviewer.criteria,
|
|
795
|
-
includeReviewHistory: reviewReviewer.includeReviewHistory
|
|
796
|
-
},
|
|
797
|
-
refactor: applyStageAgentDefaults(
|
|
798
|
-
reviewRefactor
|
|
799
|
-
),
|
|
800
|
-
maxIterations: review.maxIterations
|
|
801
|
-
},
|
|
802
|
-
...verifyLabeled ? { verify: { commands: verifyLabeled } } : {},
|
|
803
|
-
issueFinalReview: {
|
|
804
|
-
...issueFinalReview,
|
|
805
|
-
maxAttempts: issueFinalReview.maxAttempts,
|
|
806
|
-
outputRetries: applyOutputRetriesDefaults(
|
|
807
|
-
issueFinalReview.outputRetries
|
|
808
|
-
)
|
|
809
|
-
},
|
|
810
|
-
finalize: {
|
|
811
|
-
prDescriptionAgent: applyStageAgentDefaults(
|
|
812
|
-
finalize.prDescriptionAgent
|
|
813
|
-
),
|
|
814
|
-
maxAttempts: finalize.maxAttempts
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
|
-
);
|
|
820
|
-
const serenaRaw = data.serena;
|
|
821
|
-
const serenaDefaults = {
|
|
822
|
-
mcpUrl: serenaRaw?.mcpUrl ?? "http://localhost:9121/mcp",
|
|
823
|
-
sandboxMcpUrl: serenaRaw?.sandboxMcpUrl ?? "http://localhost:9121/mcp",
|
|
824
|
-
dataDir: serenaRaw?.dataDir ?? ".pourkit/serena/"
|
|
825
|
-
};
|
|
826
|
-
const serena = {
|
|
827
|
-
enabled: serenaRaw?.enabled ?? false,
|
|
828
|
-
required: serenaRaw?.required ?? false,
|
|
829
|
-
mcpUrl: process.env.POURKIT_SERENA_MCP_URL ?? serenaDefaults.mcpUrl,
|
|
830
|
-
sandboxMcpUrl: process.env.POURKIT_SERENA_SANDBOX_MCP_URL ?? serenaDefaults.sandboxMcpUrl,
|
|
831
|
-
dataDir: serenaDefaults.dataDir,
|
|
832
|
-
autoStart: serenaRaw?.autoStart ?? false
|
|
833
|
-
};
|
|
834
|
-
if (serena.mcpUrl.trim() === "") {
|
|
835
|
-
throw new Error("POURKIT_SERENA_MCP_URL must be a non-empty string");
|
|
836
|
-
}
|
|
837
|
-
if (serena.sandboxMcpUrl.trim() === "") {
|
|
838
|
-
throw new Error(
|
|
839
|
-
"POURKIT_SERENA_SANDBOX_MCP_URL must be a non-empty string"
|
|
840
|
-
);
|
|
841
|
-
}
|
|
842
|
-
const checksRaw = data.checks;
|
|
843
|
-
const labelsRaw = data.labels;
|
|
844
|
-
const cleanupRaw = data.cleanup;
|
|
845
|
-
const sandboxRaw = data.sandbox;
|
|
846
|
-
const memoryRaw = data.memory;
|
|
847
|
-
return {
|
|
848
|
-
targets,
|
|
849
|
-
labels: {
|
|
850
|
-
readyForAgent: labelsRaw?.readyForAgent ?? "ready-for-agent",
|
|
851
|
-
agentInProgress: labelsRaw?.agentInProgress ?? "agent-in-progress",
|
|
852
|
-
blocked: labelsRaw?.blocked ?? "blocked",
|
|
853
|
-
prOpenAwaitingMerge: labelsRaw?.prOpenAwaitingMerge ?? "pr-open-awaiting-merge",
|
|
854
|
-
readyForHuman: labelsRaw?.readyForHuman ?? "ready-for-human",
|
|
855
|
-
needsTriage: labelsRaw?.needsTriage ?? "needs-triage"
|
|
856
|
-
},
|
|
857
|
-
sandbox: {
|
|
858
|
-
provider: sandboxRaw?.provider ?? "docker",
|
|
859
|
-
copyToWorktree: sandboxRaw?.copyToWorktree,
|
|
860
|
-
mounts: sandboxRaw?.mounts ? sandboxRaw.mounts.map((m) => ({
|
|
861
|
-
hostPath: m.hostPath,
|
|
862
|
-
sandboxPath: m.sandboxPath,
|
|
863
|
-
readonly: m.readonly ?? false
|
|
864
|
-
})) : void 0,
|
|
865
|
-
env: sandboxRaw?.env,
|
|
866
|
-
idleTimeoutSeconds: sandboxRaw?.idleTimeoutSeconds,
|
|
867
|
-
forceRebuild: sandboxRaw?.forceRebuild
|
|
868
|
-
},
|
|
869
|
-
checks: {
|
|
870
|
-
requiredLabels: checksRaw?.requiredLabels ?? [],
|
|
871
|
-
allowedAuthors: checksRaw?.allowedAuthors ?? [],
|
|
872
|
-
checksFoundTimeoutSeconds: checksRaw?.checksFoundTimeoutSeconds ?? 60,
|
|
873
|
-
checksCompletionTimeoutSeconds: checksRaw?.checksCompletionTimeoutSeconds ?? 30 * 60,
|
|
874
|
-
pollIntervalSeconds: checksRaw?.pollIntervalSeconds ?? 15,
|
|
875
|
-
issueListLimit: checksRaw?.issueListLimit ?? 50
|
|
876
|
-
},
|
|
877
|
-
serena,
|
|
878
|
-
cleanup: {
|
|
879
|
-
enabled: cleanupRaw?.enabled ?? true,
|
|
880
|
-
worktreeRetentionDays: cleanupRaw?.worktreeRetentionDays ?? 14,
|
|
881
|
-
logRetentionDays: cleanupRaw?.logRetentionDays ?? 30
|
|
882
|
-
},
|
|
883
|
-
memory: memoryRaw
|
|
884
|
-
};
|
|
866
|
+
const input = raw;
|
|
867
|
+
validateConfigSemantics(input);
|
|
868
|
+
return normalizePourkitConfig(input);
|
|
885
869
|
}
|
|
886
870
|
function getVerificationCommands(target) {
|
|
887
871
|
return target.strategy.verify?.commands ?? [];
|
|
@@ -19343,11 +19327,11 @@ function createCliProgram(version) {
|
|
|
19343
19327
|
return program;
|
|
19344
19328
|
}
|
|
19345
19329
|
async function resolveCliVersion() {
|
|
19346
|
-
if (isPackageVersion("0.0.0-next-
|
|
19347
|
-
return "0.0.0-next-
|
|
19330
|
+
if (isPackageVersion("0.0.0-next-20260703225916")) {
|
|
19331
|
+
return "0.0.0-next-20260703225916";
|
|
19348
19332
|
}
|
|
19349
|
-
if (isReleaseVersion("0.0.0-next-
|
|
19350
|
-
return "0.0.0-next-
|
|
19333
|
+
if (isReleaseVersion("0.0.0-next-20260703225916")) {
|
|
19334
|
+
return "0.0.0-next-20260703225916";
|
|
19351
19335
|
}
|
|
19352
19336
|
try {
|
|
19353
19337
|
const root = repoRoot();
|