@sjawhar/opencode-legion-envoy 4.1.1 → 5.0.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/src/server.js
CHANGED
|
@@ -14394,168 +14394,6 @@ var EnvelopeSchema = exports_external.object({
|
|
|
14394
14394
|
});
|
|
14395
14395
|
var MINTED_DEDUPE_KEY_PATTERN = "^(?:envoy\\.role\\.forward\\.)?(?:publish|agent\\.[^.]+)\\.(?:[0-9a-f]{32}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$";
|
|
14396
14396
|
var mintedDedupeKey = new RegExp(MINTED_DEDUPE_KEY_PATTERN);
|
|
14397
|
-
// ../contracts/src/handoff-schema.ts
|
|
14398
|
-
var HANDOFF_SCHEMA_VERSION = 1;
|
|
14399
|
-
var HANDOFF_PHASES = ["architect", "plan", "implement", "test", "review"];
|
|
14400
|
-
var PLAN_REVIEW_MAX_ROUNDS = 3;
|
|
14401
|
-
var PLAN_REVIEW_VERDICTS = ["approved", "rejected", "failed"];
|
|
14402
|
-
var isoTimestamp = exports_external.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
|
|
14403
|
-
var handoffPhase = exports_external.enum(HANDOFF_PHASES);
|
|
14404
|
-
var nonEmpty = exports_external.string().trim().min(1);
|
|
14405
|
-
var proofSchema = exports_external.object({
|
|
14406
|
-
criterion: nonEmpty,
|
|
14407
|
-
surface: nonEmpty,
|
|
14408
|
-
command: nonEmpty,
|
|
14409
|
-
observed: nonEmpty,
|
|
14410
|
-
headSha: nonEmpty,
|
|
14411
|
-
negativeControl: nonEmpty
|
|
14412
|
-
}).passthrough();
|
|
14413
|
-
var routingHintsSchema = exports_external.object({
|
|
14414
|
-
skipArchitect: exports_external.boolean().optional(),
|
|
14415
|
-
complexity: exports_external.enum(["trivial", "small", "medium", "large"]).optional(),
|
|
14416
|
-
estimatedImplementers: exports_external.number().optional()
|
|
14417
|
-
}).passthrough().optional();
|
|
14418
|
-
var baseHandoffSchema = exports_external.object({
|
|
14419
|
-
schemaVersion: exports_external.literal(HANDOFF_SCHEMA_VERSION),
|
|
14420
|
-
phase: handoffPhase,
|
|
14421
|
-
completed: isoTimestamp,
|
|
14422
|
-
learningsInjected: exports_external.array(exports_external.string()).optional(),
|
|
14423
|
-
learningsHelpful: exports_external.array(exports_external.string()).optional()
|
|
14424
|
-
}).passthrough();
|
|
14425
|
-
var architectSchema = baseHandoffSchema.extend({
|
|
14426
|
-
phase: exports_external.literal("architect"),
|
|
14427
|
-
scope: exports_external.enum(["trivial", "small", "medium", "large"]).optional(),
|
|
14428
|
-
components: exports_external.array(exports_external.string()).optional(),
|
|
14429
|
-
subIssues: exports_external.array(exports_external.string()).optional(),
|
|
14430
|
-
routingHints: routingHintsSchema,
|
|
14431
|
-
concerns: exports_external.array(exports_external.string()).optional()
|
|
14432
|
-
});
|
|
14433
|
-
var requiredSkillsSchema = exports_external.object({
|
|
14434
|
-
implement: exports_external.array(exports_external.string()).optional(),
|
|
14435
|
-
test: exports_external.array(exports_external.string()).optional(),
|
|
14436
|
-
review: exports_external.array(exports_external.string()).optional()
|
|
14437
|
-
}).passthrough().optional();
|
|
14438
|
-
var gapAnalysisSchema = exports_external.object({
|
|
14439
|
-
findings: exports_external.array(exports_external.object({ finding: exports_external.string(), answer: exports_external.string() }).passthrough()).optional(),
|
|
14440
|
-
error: exports_external.string().optional()
|
|
14441
|
-
}).passthrough().optional();
|
|
14442
|
-
var planReviewSchema = exports_external.object({
|
|
14443
|
-
verdict: exports_external.enum(PLAN_REVIEW_VERDICTS),
|
|
14444
|
-
rounds: exports_external.number(),
|
|
14445
|
-
remainingIssues: exports_external.array(exports_external.object({ issue: exports_external.string(), evidence: exports_external.string() }).passthrough()).optional(),
|
|
14446
|
-
error: exports_external.string().optional()
|
|
14447
|
-
}).passthrough().optional();
|
|
14448
|
-
var planSchema = baseHandoffSchema.extend({
|
|
14449
|
-
phase: exports_external.literal("plan"),
|
|
14450
|
-
taskCount: exports_external.number().optional(),
|
|
14451
|
-
independentTasks: exports_external.number().optional(),
|
|
14452
|
-
routingHints: routingHintsSchema,
|
|
14453
|
-
concerns: exports_external.array(exports_external.string()).optional(),
|
|
14454
|
-
workflowRecommendation: exports_external.string().optional(),
|
|
14455
|
-
requiredSkills: requiredSkillsSchema,
|
|
14456
|
-
gapAnalysis: gapAnalysisSchema,
|
|
14457
|
-
planReview: planReviewSchema
|
|
14458
|
-
});
|
|
14459
|
-
var implementSchema = baseHandoffSchema.extend({
|
|
14460
|
-
phase: exports_external.literal("implement"),
|
|
14461
|
-
filesChanged: exports_external.array(exports_external.string()).optional(),
|
|
14462
|
-
proof: exports_external.array(proofSchema).min(1),
|
|
14463
|
-
trickyParts: exports_external.array(exports_external.string()).optional(),
|
|
14464
|
-
deviations: exports_external.array(exports_external.string()).optional(),
|
|
14465
|
-
openQuestions: exports_external.array(exports_external.string()).optional(),
|
|
14466
|
-
subPlanningNeeded: exports_external.boolean().optional(),
|
|
14467
|
-
discoveredComplexity: exports_external.array(exports_external.string()).optional(),
|
|
14468
|
-
suggestedSubWorkers: exports_external.number().optional()
|
|
14469
|
-
});
|
|
14470
|
-
var testSchema = baseHandoffSchema.extend({
|
|
14471
|
-
phase: exports_external.literal("test"),
|
|
14472
|
-
passed: exports_external.number().optional(),
|
|
14473
|
-
failed: exports_external.number().optional(),
|
|
14474
|
-
failures: exports_external.array(exports_external.object({ criterion: exports_external.string(), evidence: exports_external.string() }).passthrough()).optional(),
|
|
14475
|
-
implementerProof: exports_external.object({ verdict: exports_external.enum(["verified", "rejected"]), how: nonEmpty }).passthrough(),
|
|
14476
|
-
proof: exports_external.array(proofSchema).min(1).optional(),
|
|
14477
|
-
documentationFeedback: exports_external.string().optional(),
|
|
14478
|
-
observations: exports_external.array(exports_external.string()).optional()
|
|
14479
|
-
}).refine((handoff) => (handoff.failures?.length ?? 0) > 0 || (handoff.failed ?? 0) > 0 || (handoff.proof?.length ?? 0) > 0, {
|
|
14480
|
-
path: ["proof"],
|
|
14481
|
-
message: "a passing test handoff needs the tester's own production-like proof"
|
|
14482
|
-
}).refine((handoff) => (handoff.failed ?? 0) === 0 || (handoff.failures?.length ?? 0) > 0, {
|
|
14483
|
-
path: ["failures"],
|
|
14484
|
-
message: "a test handoff that reports failed > 0 records at least one failure"
|
|
14485
|
-
}).refine((handoff) => handoff.implementerProof.verdict !== "rejected" || (handoff.failures?.length ?? 0) > 0, {
|
|
14486
|
-
path: ["failures"],
|
|
14487
|
-
message: "a rejected implementer proof is a recorded failure"
|
|
14488
|
-
});
|
|
14489
|
-
var reviewSchema = baseHandoffSchema.extend({
|
|
14490
|
-
phase: exports_external.literal("review"),
|
|
14491
|
-
critical: exports_external.number().optional(),
|
|
14492
|
-
important: exports_external.number().optional(),
|
|
14493
|
-
minor: exports_external.number().optional(),
|
|
14494
|
-
verdict: exports_external.enum(["approved", "changes_requested"]).optional(),
|
|
14495
|
-
keyFindings: exports_external.array(exports_external.object({ severity: exports_external.string(), file: exports_external.string(), description: exports_external.string() }).passthrough()).optional()
|
|
14496
|
-
});
|
|
14497
|
-
var nonEmptySkillList = exports_external.array(nonEmpty).min(1);
|
|
14498
|
-
var recorded = (shape, whatToRecord) => exports_external.object(shape, {
|
|
14499
|
-
error: (issue2) => issue2.input === undefined ? `missing \u2014 record ${whatToRecord}` : undefined
|
|
14500
|
-
}).passthrough();
|
|
14501
|
-
var gapAnalysisWriteSchema = recorded({
|
|
14502
|
-
findings: exports_external.array(exports_external.object({ finding: nonEmpty, answer: nonEmpty }).passthrough()).optional(),
|
|
14503
|
-
error: nonEmpty.optional()
|
|
14504
|
-
}, "the gap analyst's `findings`, each with how the plan answers it (`[]` when it found none), or its failed call's `error`").refine((analysis) => analysis.findings === undefined !== (analysis.error === undefined), {
|
|
14505
|
-
message: "record exactly one of `findings` or the failed call's `error`"
|
|
14506
|
-
});
|
|
14507
|
-
var planReviewWriteSchema = recorded({
|
|
14508
|
-
verdict: exports_external.enum(PLAN_REVIEW_VERDICTS),
|
|
14509
|
-
rounds: exports_external.number().int().min(1).max(PLAN_REVIEW_MAX_ROUNDS),
|
|
14510
|
-
remainingIssues: exports_external.array(exports_external.object({ issue: nonEmpty, evidence: nonEmpty }).passthrough()).optional(),
|
|
14511
|
-
error: nonEmpty.optional()
|
|
14512
|
-
}, "the plan review's `verdict` and `rounds`, with `remainingIssues` when it was rejected or `error` when a review's call failed").superRefine((review, ctx) => {
|
|
14513
|
-
const remaining = review.remainingIssues?.length ?? 0;
|
|
14514
|
-
if (review.verdict === "rejected" && remaining === 0) {
|
|
14515
|
-
ctx.addIssue({
|
|
14516
|
-
code: "custom",
|
|
14517
|
-
path: ["remainingIssues"],
|
|
14518
|
-
message: "a rejected review records the blocking issues its last round named"
|
|
14519
|
-
});
|
|
14520
|
-
}
|
|
14521
|
-
if (review.verdict === "rejected" && review.rounds < PLAN_REVIEW_MAX_ROUNDS) {
|
|
14522
|
-
ctx.addIssue({
|
|
14523
|
-
code: "custom",
|
|
14524
|
-
path: ["rounds"],
|
|
14525
|
-
message: `a review still rejecting after ${review.rounds} of ${PLAN_REVIEW_MAX_ROUNDS} rounds is revised and reviewed again, not recorded`
|
|
14526
|
-
});
|
|
14527
|
-
}
|
|
14528
|
-
if (review.verdict === "approved" && remaining > 0) {
|
|
14529
|
-
ctx.addIssue({
|
|
14530
|
-
code: "custom",
|
|
14531
|
-
path: ["remainingIssues"],
|
|
14532
|
-
message: "an approved review leaves no blocking issue standing"
|
|
14533
|
-
});
|
|
14534
|
-
}
|
|
14535
|
-
if (review.verdict === "failed" !== (review.error !== undefined)) {
|
|
14536
|
-
ctx.addIssue({
|
|
14537
|
-
code: "custom",
|
|
14538
|
-
path: ["error"],
|
|
14539
|
-
message: "a failed review records its call's error, and only a failed review does"
|
|
14540
|
-
});
|
|
14541
|
-
}
|
|
14542
|
-
});
|
|
14543
|
-
var planWriteSchema = planSchema.extend({
|
|
14544
|
-
requiredSkills: exports_external.object({
|
|
14545
|
-
implement: nonEmptySkillList,
|
|
14546
|
-
test: nonEmptySkillList,
|
|
14547
|
-
review: nonEmptySkillList
|
|
14548
|
-
}).passthrough(),
|
|
14549
|
-
gapAnalysis: gapAnalysisWriteSchema,
|
|
14550
|
-
planReview: planReviewWriteSchema
|
|
14551
|
-
});
|
|
14552
|
-
var phaseHandoffSchema = exports_external.discriminatedUnion("phase", [
|
|
14553
|
-
architectSchema,
|
|
14554
|
-
planSchema,
|
|
14555
|
-
implementSchema,
|
|
14556
|
-
testSchema,
|
|
14557
|
-
reviewSchema
|
|
14558
|
-
]);
|
|
14559
14397
|
// ../contracts/src/subject.ts
|
|
14560
14398
|
var AGENT_TOPIC_PREFIX = "notifications.agent.";
|
|
14561
14399
|
var DISPATCH_TOPIC_PREFIX = "notifications.dispatch.";
|
|
@@ -14570,283 +14408,6 @@ function dispatchDocumentSubject(project, slug, type) {
|
|
|
14570
14408
|
function agentSubject(session) {
|
|
14571
14409
|
return `${AGENT_TOPIC_PREFIX}${session}`;
|
|
14572
14410
|
}
|
|
14573
|
-
|
|
14574
|
-
// ../contracts/src/legion-roles.ts
|
|
14575
|
-
var LEGION_ROLES = [
|
|
14576
|
-
"architect",
|
|
14577
|
-
"planner",
|
|
14578
|
-
"implementer",
|
|
14579
|
-
"tester",
|
|
14580
|
-
"reviewer",
|
|
14581
|
-
"merger"
|
|
14582
|
-
];
|
|
14583
|
-
|
|
14584
|
-
// ../contracts/src/legion-daemon-api.ts
|
|
14585
|
-
var nonEmptyString = exports_external.string().min(1);
|
|
14586
|
-
var appLogin = exports_external.string().regex(/^[^[\]]+\[bot\]$/);
|
|
14587
|
-
var legionRole = exports_external.enum(LEGION_ROLES);
|
|
14588
|
-
var requiredUnknown = exports_external.unknown().refine((value) => value !== undefined, {
|
|
14589
|
-
message: "Required"
|
|
14590
|
-
});
|
|
14591
|
-
var architectCapability = exports_external.strictObject({
|
|
14592
|
-
tree: nonEmptyString,
|
|
14593
|
-
sessionId: nonEmptyString,
|
|
14594
|
-
secret: nonEmptyString
|
|
14595
|
-
});
|
|
14596
|
-
var controllerIssue = exports_external.strictObject({
|
|
14597
|
-
secret: nonEmptyString,
|
|
14598
|
-
issue: nonEmptyString
|
|
14599
|
-
});
|
|
14600
|
-
var TREE_STATUSES = ["queued", "active", "lingering", "dead", "launch-failed", "closed"];
|
|
14601
|
-
var stateTmuxLocator = exports_external.strictObject({
|
|
14602
|
-
runtime: exports_external.literal("tmux"),
|
|
14603
|
-
tmuxSession: nonEmptyString,
|
|
14604
|
-
tmuxWindowId: nonEmptyString,
|
|
14605
|
-
tmuxPaneId: nonEmptyString.optional()
|
|
14606
|
-
});
|
|
14607
|
-
var stateK8sLocator = exports_external.strictObject({
|
|
14608
|
-
runtime: exports_external.literal("kubernetes"),
|
|
14609
|
-
namespace: nonEmptyString,
|
|
14610
|
-
podName: nonEmptyString,
|
|
14611
|
-
podUid: nonEmptyString,
|
|
14612
|
-
pvcName: nonEmptyString
|
|
14613
|
-
});
|
|
14614
|
-
var stateLocator = exports_external.discriminatedUnion("runtime", [stateTmuxLocator, stateK8sLocator]);
|
|
14615
|
-
var stateTreeLocator = exports_external.discriminatedUnion("runtime", [
|
|
14616
|
-
stateTmuxLocator.extend({ ompSessionFile: nonEmptyString.optional() }),
|
|
14617
|
-
stateK8sLocator.extend({ ompSessionFile: nonEmptyString.optional() })
|
|
14618
|
-
]);
|
|
14619
|
-
var stateExternalControllerLocator = exports_external.strictObject({
|
|
14620
|
-
runtime: exports_external.literal("kubernetes"),
|
|
14621
|
-
external: exports_external.literal(true),
|
|
14622
|
-
sessionId: nonEmptyString,
|
|
14623
|
-
registeredAt: exports_external.number().int().nonnegative()
|
|
14624
|
-
});
|
|
14625
|
-
var stateIssue = exports_external.strictObject({
|
|
14626
|
-
key: nonEmptyString,
|
|
14627
|
-
title: exports_external.string(),
|
|
14628
|
-
status: exports_external.enum(ISSUE_STATUSES).optional(),
|
|
14629
|
-
children: exports_external.array(nonEmptyString),
|
|
14630
|
-
parent: nonEmptyString.optional(),
|
|
14631
|
-
lastAppliedSeq: exports_external.number().int().nonnegative().optional()
|
|
14632
|
-
});
|
|
14633
|
-
var stateWorkspaceLost = exports_external.strictObject({
|
|
14634
|
-
at: nonEmptyString,
|
|
14635
|
-
generation: exports_external.number().int().nonnegative(),
|
|
14636
|
-
fromRef: nonEmptyString,
|
|
14637
|
-
previousSessionId: nonEmptyString.optional()
|
|
14638
|
-
});
|
|
14639
|
-
var stateTree = exports_external.strictObject({
|
|
14640
|
-
status: exports_external.enum(TREE_STATUSES),
|
|
14641
|
-
generation: exports_external.number().int().nonnegative(),
|
|
14642
|
-
launchFailures: exports_external.number().int().nonnegative(),
|
|
14643
|
-
readyConfirmedAt: exports_external.number().optional(),
|
|
14644
|
-
locator: stateTreeLocator.optional(),
|
|
14645
|
-
workspaceLost: stateWorkspaceLost.optional()
|
|
14646
|
-
});
|
|
14647
|
-
var stateGate = exports_external.strictObject({
|
|
14648
|
-
artifactId: nonEmptyString,
|
|
14649
|
-
latestVersion: exports_external.number().int().positive(),
|
|
14650
|
-
approvedVersion: exports_external.number().int().positive().optional()
|
|
14651
|
-
});
|
|
14652
|
-
var stateRole = exports_external.strictObject({
|
|
14653
|
-
role: nonEmptyString,
|
|
14654
|
-
issue: nonEmptyString.optional(),
|
|
14655
|
-
generation: exports_external.number().int().nonnegative().optional(),
|
|
14656
|
-
sessionId: nonEmptyString.optional(),
|
|
14657
|
-
readyConfirmedAt: exports_external.number().optional(),
|
|
14658
|
-
launchFailures: exports_external.number().int().nonnegative().optional(),
|
|
14659
|
-
locator: stateLocator.optional(),
|
|
14660
|
-
workspaceLost: stateWorkspaceLost.optional()
|
|
14661
|
-
});
|
|
14662
|
-
var stateQueuedWorkerIdentity = {
|
|
14663
|
-
roleToken: nonEmptyString,
|
|
14664
|
-
issue: nonEmptyString,
|
|
14665
|
-
role: nonEmptyString
|
|
14666
|
-
};
|
|
14667
|
-
var stateQueuedWorker = exports_external.union([
|
|
14668
|
-
exports_external.strictObject(stateQueuedWorkerIdentity),
|
|
14669
|
-
exports_external.strictObject({
|
|
14670
|
-
...stateQueuedWorkerIdentity,
|
|
14671
|
-
kind: exports_external.enum(["assignment", "catchup"]),
|
|
14672
|
-
queuedAt: nonEmptyString
|
|
14673
|
-
})
|
|
14674
|
-
]);
|
|
14675
|
-
var LegionDaemonApi = {
|
|
14676
|
-
State: {
|
|
14677
|
-
response: exports_external.strictObject({
|
|
14678
|
-
project: nonEmptyString,
|
|
14679
|
-
version: exports_external.number().int(),
|
|
14680
|
-
issues: exports_external.record(exports_external.string(), stateIssue),
|
|
14681
|
-
trees: exports_external.record(exports_external.string(), stateTree),
|
|
14682
|
-
admission: exports_external.strictObject({
|
|
14683
|
-
cap: exports_external.number().int().nonnegative(),
|
|
14684
|
-
active: exports_external.array(nonEmptyString),
|
|
14685
|
-
queue: exports_external.array(nonEmptyString)
|
|
14686
|
-
}),
|
|
14687
|
-
gates: exports_external.record(exports_external.string(), stateGate),
|
|
14688
|
-
controllerLocator: exports_external.union([stateTreeLocator, stateExternalControllerLocator]).optional(),
|
|
14689
|
-
roles: exports_external.record(exports_external.string(), stateRole),
|
|
14690
|
-
controllerPendingNotices: exports_external.number().int().nonnegative(),
|
|
14691
|
-
pendingStatusWrites: exports_external.array(nonEmptyString),
|
|
14692
|
-
workerAdmission: exports_external.strictObject({ queue: exports_external.array(stateQueuedWorker) })
|
|
14693
|
-
})
|
|
14694
|
-
},
|
|
14695
|
-
ControllerReady: {
|
|
14696
|
-
request: exports_external.strictObject({
|
|
14697
|
-
secret: nonEmptyString,
|
|
14698
|
-
sessionId: nonEmptyString,
|
|
14699
|
-
ompSessionFile: nonEmptyString.optional(),
|
|
14700
|
-
pluginVersion: nonEmptyString
|
|
14701
|
-
}),
|
|
14702
|
-
response: exports_external.object({})
|
|
14703
|
-
},
|
|
14704
|
-
ControllerSecret: {
|
|
14705
|
-
request: exports_external.strictObject({}),
|
|
14706
|
-
response: exports_external.object({ secret: nonEmptyString })
|
|
14707
|
-
},
|
|
14708
|
-
ProcessStarted: {
|
|
14709
|
-
request: exports_external.strictObject({
|
|
14710
|
-
tree: nonEmptyString,
|
|
14711
|
-
generation: exports_external.number().int(),
|
|
14712
|
-
rootSessionId: nonEmptyString,
|
|
14713
|
-
agentId: nonEmptyString,
|
|
14714
|
-
bootToken: nonEmptyString,
|
|
14715
|
-
ompSessionFile: nonEmptyString,
|
|
14716
|
-
pluginVersion: nonEmptyString
|
|
14717
|
-
}),
|
|
14718
|
-
response: exports_external.object({
|
|
14719
|
-
roleTokens: exports_external.record(exports_external.string(), exports_external.string()),
|
|
14720
|
-
controlSubject: nonEmptyString,
|
|
14721
|
-
gates: exports_external.object({
|
|
14722
|
-
design: exports_external.enum(["root-issues", "off"])
|
|
14723
|
-
}).optional(),
|
|
14724
|
-
secret: nonEmptyString
|
|
14725
|
-
})
|
|
14726
|
-
},
|
|
14727
|
-
ProcessReady: {
|
|
14728
|
-
request: architectCapability.extend({ generation: exports_external.number().int() }),
|
|
14729
|
-
response: exports_external.object({})
|
|
14730
|
-
},
|
|
14731
|
-
ProcessExit: {
|
|
14732
|
-
request: architectCapability.extend({ generation: exports_external.number().int() }),
|
|
14733
|
-
response: exports_external.object({})
|
|
14734
|
-
},
|
|
14735
|
-
WaveRelease: {
|
|
14736
|
-
request: architectCapability.extend({ issues: exports_external.array(nonEmptyString).optional() }),
|
|
14737
|
-
response: exports_external.object({ released: exports_external.array(nonEmptyString) })
|
|
14738
|
-
},
|
|
14739
|
-
Escalate: {
|
|
14740
|
-
request: architectCapability.extend({
|
|
14741
|
-
kind: exports_external.enum(["re-file", "capacity", "cross-tree"]),
|
|
14742
|
-
context: requiredUnknown
|
|
14743
|
-
}),
|
|
14744
|
-
response: exports_external.object({})
|
|
14745
|
-
},
|
|
14746
|
-
ProvisioningCredential: {
|
|
14747
|
-
request: architectCapability.extend({ issue: nonEmptyString }),
|
|
14748
|
-
response: exports_external.object({ token: nonEmptyString })
|
|
14749
|
-
},
|
|
14750
|
-
WorkerStarted: {
|
|
14751
|
-
request: exports_external.strictObject({
|
|
14752
|
-
tree: nonEmptyString,
|
|
14753
|
-
issue: nonEmptyString,
|
|
14754
|
-
role: legionRole,
|
|
14755
|
-
bootToken: nonEmptyString,
|
|
14756
|
-
sessionId: nonEmptyString,
|
|
14757
|
-
agentId: nonEmptyString,
|
|
14758
|
-
ompSessionFile: nonEmptyString,
|
|
14759
|
-
pluginVersion: nonEmptyString
|
|
14760
|
-
}),
|
|
14761
|
-
response: exports_external.object({
|
|
14762
|
-
roleToken: nonEmptyString,
|
|
14763
|
-
secret: nonEmptyString,
|
|
14764
|
-
gitName: nonEmptyString,
|
|
14765
|
-
gitEmail: nonEmptyString
|
|
14766
|
-
})
|
|
14767
|
-
},
|
|
14768
|
-
WorkerReady: {
|
|
14769
|
-
request: exports_external.strictObject({
|
|
14770
|
-
tree: nonEmptyString,
|
|
14771
|
-
issue: nonEmptyString,
|
|
14772
|
-
role: legionRole,
|
|
14773
|
-
sessionId: nonEmptyString,
|
|
14774
|
-
generation: exports_external.number().int().nonnegative(),
|
|
14775
|
-
secret: nonEmptyString
|
|
14776
|
-
}),
|
|
14777
|
-
response: exports_external.object({})
|
|
14778
|
-
},
|
|
14779
|
-
PhaseComplete: {
|
|
14780
|
-
request: exports_external.strictObject({
|
|
14781
|
-
grantId: nonEmptyString,
|
|
14782
|
-
summary: nonEmptyString
|
|
14783
|
-
}),
|
|
14784
|
-
response: exports_external.object({})
|
|
14785
|
-
},
|
|
14786
|
-
SpawnWorker: {
|
|
14787
|
-
request: architectCapability.extend({
|
|
14788
|
-
issue: nonEmptyString,
|
|
14789
|
-
role: legionRole,
|
|
14790
|
-
task: nonEmptyString,
|
|
14791
|
-
requestId: exports_external.uuid()
|
|
14792
|
-
}),
|
|
14793
|
-
response: exports_external.object({
|
|
14794
|
-
status: exports_external.enum(["spawned", "resumed", "queued"]),
|
|
14795
|
-
roleToken: nonEmptyString
|
|
14796
|
-
})
|
|
14797
|
-
},
|
|
14798
|
-
WorkerSession: {
|
|
14799
|
-
request: exports_external.strictObject({
|
|
14800
|
-
sessionId: nonEmptyString,
|
|
14801
|
-
recoveryToken: nonEmptyString
|
|
14802
|
-
}),
|
|
14803
|
-
response: exports_external.object({
|
|
14804
|
-
tree: nonEmptyString,
|
|
14805
|
-
issue: nonEmptyString,
|
|
14806
|
-
role: legionRole,
|
|
14807
|
-
secret: nonEmptyString
|
|
14808
|
-
})
|
|
14809
|
-
},
|
|
14810
|
-
IssueStatus: {
|
|
14811
|
-
request: controllerIssue.extend({
|
|
14812
|
-
status: exports_external.enum(ISSUE_STATUSES),
|
|
14813
|
-
tree: nonEmptyString.optional(),
|
|
14814
|
-
sessionId: nonEmptyString.optional()
|
|
14815
|
-
}),
|
|
14816
|
-
response: exports_external.object({})
|
|
14817
|
-
},
|
|
14818
|
-
GatesRegister: {
|
|
14819
|
-
request: architectCapability.extend({
|
|
14820
|
-
issue: nonEmptyString,
|
|
14821
|
-
artifactId: exports_external.uuid(),
|
|
14822
|
-
version: exports_external.number().int().positive()
|
|
14823
|
-
}),
|
|
14824
|
-
response: exports_external.object({})
|
|
14825
|
-
},
|
|
14826
|
-
Grant: {
|
|
14827
|
-
request: exports_external.union([
|
|
14828
|
-
exports_external.strictObject({
|
|
14829
|
-
sessionId: nonEmptyString,
|
|
14830
|
-
secret: nonEmptyString,
|
|
14831
|
-
tree: nonEmptyString,
|
|
14832
|
-
issue: nonEmptyString
|
|
14833
|
-
}),
|
|
14834
|
-
exports_external.strictObject({ sessionId: nonEmptyString, secret: nonEmptyString })
|
|
14835
|
-
]),
|
|
14836
|
-
response: exports_external.object({ grantId: nonEmptyString, expiresAt: nonEmptyString })
|
|
14837
|
-
},
|
|
14838
|
-
GitHubToken: {
|
|
14839
|
-
request: exports_external.strictObject({ grantId: nonEmptyString }),
|
|
14840
|
-
response: exports_external.object({
|
|
14841
|
-
token: nonEmptyString,
|
|
14842
|
-
appLogin: exports_external.string().endsWith("[bot]"),
|
|
14843
|
-
legionAppLogins: exports_external.object({ implement: appLogin, review: appLogin }).optional()
|
|
14844
|
-
})
|
|
14845
|
-
},
|
|
14846
|
-
GitCredential: {
|
|
14847
|
-
request: exports_external.strictObject({ grantId: nonEmptyString })
|
|
14848
|
-
}
|
|
14849
|
-
};
|
|
14850
14411
|
// ../contracts/src/repo.ts
|
|
14851
14412
|
function canonicalRepo(owner, repo) {
|
|
14852
14413
|
return `${owner.trim().toLowerCase()}/${repo.trim().toLowerCase().replace(/\.git$/, "")}`;
|
package/package.json
CHANGED
|
@@ -125,12 +125,10 @@ committed predecessor handoffs in lifecycle order from `$LEGION_WORKSPACE/.legio
|
|
|
125
125
|
4. `test.json`
|
|
126
126
|
5. `review.json`
|
|
127
127
|
|
|
128
|
-
Read only files that precede the assigned phase.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
Undeclared fields pass validation untouched and reach the next worker; a declared field of the
|
|
133
|
-
wrong type fails the whole file, so the `legion` tool's `handoff_read` returns null for that phase.
|
|
128
|
+
Read only files that precede the assigned phase. Each was held to its phase's rules when it was
|
|
129
|
+
written (`handoff_write`, in the completion gate below): fields the phase does not declare passed
|
|
130
|
+
untouched and reach the next worker. The `legion` tool's `handoff_read` returns each file as it
|
|
131
|
+
stands in the workspace.
|
|
134
132
|
Write the phase-specific fields the next phase and the architect need, consistent with what
|
|
135
133
|
predecessor phases already wrote. The durable copy lives in
|
|
136
134
|
`$LEGION_WORKSPACE/.legion/<phase>.json`. If a committed handoff conflicts with memory or a prior
|
|
@@ -13,7 +13,8 @@ reviewer on every re-review, the merger before READY. Every path it cites is in
|
|
|
13
13
|
`Accepted:` — the opener's own follow-up included — leaves the thread open, because resolution
|
|
14
14
|
considers only the newest comment). The review App can reply on a thread but cannot resolve it:
|
|
15
15
|
GitHub grants resolving a review thread to the pull request's author, and the implementer opens
|
|
16
|
-
every Legion pull request (`
|
|
16
|
+
every Legion pull request (`docs/site/src/content/docs/legion/running-legion.md`, "The two
|
|
17
|
+
GitHub Apps").
|
|
17
18
|
When `LEGION_GRANT_FILE` or `LEGION_GRANT` is set, use `legion threads resolve --pr <number> --repo <owner>/<repo>`.
|
|
18
19
|
When neither is set, add `--gh` to that command, which applies the fallback's rule below through
|
|
19
20
|
your own `gh`; where no `legion` command is installed, use `gh api graphql` with the session's
|