@sjawhar/opencode-legion-envoy 0.23.2 → 0.25.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
|
@@ -13594,7 +13594,7 @@ function dispatchToolSchema(spec, z, opts) {
|
|
|
13594
13594
|
const shape = spec.arguments(z);
|
|
13595
13595
|
return spec.validation === undefined ? z.object(shape, opts) : z.refineObject(shape, spec.validation.check, spec.validation.message, opts);
|
|
13596
13596
|
}
|
|
13597
|
-
var ISSUE_REFERENCE = "An issue is a native KEY or external owner/repo#n reference; an external reference creates its native issue
|
|
13597
|
+
var ISSUE_REFERENCE = "An issue is a native KEY or external owner/repo#n reference; an external reference creates its native issue in the repository's dashboard-configured project or, failing that, the default project (DISPATCH_DEFAULT_PROJECT).";
|
|
13598
13598
|
var ASK_URGENCIES = ["low", "med", "high", "blocking"];
|
|
13599
13599
|
var DOC_EDIT_OPS = ["replace", "delete", "insert"];
|
|
13600
13600
|
var dispatchToolSpecs = [
|
|
@@ -13948,25 +13948,10 @@ var LegionDaemonApi = {
|
|
|
13948
13948
|
request: architectCapability.extend({ issue: nonEmptyString, comment: string2().optional() }),
|
|
13949
13949
|
response: object({})
|
|
13950
13950
|
},
|
|
13951
|
-
SpawnToken: {
|
|
13952
|
-
request: architectCapability.extend({ issue: nonEmptyString, role: legionRole }),
|
|
13953
|
-
response: object({ spawnToken: nonEmptyString })
|
|
13954
|
-
},
|
|
13955
13951
|
ProvisioningCredential: {
|
|
13956
13952
|
request: architectCapability.extend({ issue: nonEmptyString }),
|
|
13957
13953
|
response: object({ token: nonEmptyString })
|
|
13958
13954
|
},
|
|
13959
|
-
RoleBacking: {
|
|
13960
|
-
request: strictObject({
|
|
13961
|
-
tree: nonEmptyString,
|
|
13962
|
-
issue: nonEmptyString,
|
|
13963
|
-
role: legionRole,
|
|
13964
|
-
sessionId: nonEmptyString,
|
|
13965
|
-
agentId: nonEmptyString,
|
|
13966
|
-
spawnToken: nonEmptyString
|
|
13967
|
-
}),
|
|
13968
|
-
response: object({})
|
|
13969
|
-
},
|
|
13970
13955
|
WorkerStarted: {
|
|
13971
13956
|
request: strictObject({
|
|
13972
13957
|
tree: nonEmptyString,
|
|
@@ -14013,20 +13998,6 @@ var LegionDaemonApi = {
|
|
|
14013
13998
|
roleToken: nonEmptyString
|
|
14014
13999
|
})
|
|
14015
14000
|
},
|
|
14016
|
-
Phase: {
|
|
14017
|
-
request: strictObject({
|
|
14018
|
-
tree: nonEmptyString,
|
|
14019
|
-
issue: nonEmptyString,
|
|
14020
|
-
phase: nonEmptyString,
|
|
14021
|
-
sessionId: nonEmptyString,
|
|
14022
|
-
spawnToken: nonEmptyString
|
|
14023
|
-
}),
|
|
14024
|
-
response: object({
|
|
14025
|
-
secret: nonEmptyString,
|
|
14026
|
-
gitName: nonEmptyString,
|
|
14027
|
-
gitEmail: nonEmptyString
|
|
14028
|
-
})
|
|
14029
|
-
},
|
|
14030
14001
|
WorkerSession: {
|
|
14031
14002
|
request: strictObject({
|
|
14032
14003
|
sessionId: nonEmptyString,
|
|
@@ -14065,6 +14036,10 @@ var LegionDaemonApi = {
|
|
|
14065
14036
|
response: object({ token: nonEmptyString, appLogin: string2().endsWith("[bot]") })
|
|
14066
14037
|
}
|
|
14067
14038
|
};
|
|
14039
|
+
// ../contracts/src/repo.ts
|
|
14040
|
+
function canonicalRepo(owner, repo) {
|
|
14041
|
+
return `${owner.trim().toLowerCase()}/${repo.trim().toLowerCase().replace(/\.git$/, "")}`;
|
|
14042
|
+
}
|
|
14068
14043
|
// ../contracts/src/tool-schema.ts
|
|
14069
14044
|
function zodSchemaApi(zod) {
|
|
14070
14045
|
const api = zod;
|
|
@@ -14280,7 +14255,7 @@ function parseGitHubRemoteUrl(url) {
|
|
|
14280
14255
|
for (const pattern of GITHUB_REMOTE_PATTERNS) {
|
|
14281
14256
|
const match = trimmed.match(pattern);
|
|
14282
14257
|
if (match)
|
|
14283
|
-
return
|
|
14258
|
+
return canonicalRepo(match[1] ?? "", match[2] ?? "");
|
|
14284
14259
|
}
|
|
14285
14260
|
return null;
|
|
14286
14261
|
}
|
|
@@ -14514,6 +14489,10 @@ class DispatchClient {
|
|
|
14514
14489
|
var nativeIssueKeyPattern = /^[A-Z][A-Z0-9]{1,9}-[0-9]+$/;
|
|
14515
14490
|
var externalIssueRefPattern = /^([^/\s]+)\/([^/\s#]+)#([1-9][0-9]*)$/;
|
|
14516
14491
|
var bareIssueNumberPattern = /^[1-9][0-9]*$/;
|
|
14492
|
+
function canonicalExternalIssueRef(value) {
|
|
14493
|
+
const match = value.trim().match(externalIssueRefPattern);
|
|
14494
|
+
return match ? `${canonicalRepo(match[1] ?? "", match[2] ?? "")}#${match[3]}` : value;
|
|
14495
|
+
}
|
|
14517
14496
|
function stringArg(args, name) {
|
|
14518
14497
|
const value = args[name];
|
|
14519
14498
|
if (typeof value !== "string")
|
|
@@ -14583,7 +14562,7 @@ async function resolveIssueArguments(tool, args, cwd, env, exec) {
|
|
|
14583
14562
|
return {
|
|
14584
14563
|
args: {
|
|
14585
14564
|
...args,
|
|
14586
|
-
...issueArgument === undefined && ref?.issue !== undefined ? { issue: ref.issue } : {},
|
|
14565
|
+
...typeof issueArgument === "string" ? { issue: canonicalExternalIssueRef(issueArgument) } : issueArgument === undefined && ref?.issue !== undefined ? { issue: ref.issue } : {},
|
|
14587
14566
|
...artifactArgument === undefined && (ref?.kind === "spec" || ref?.kind === "artifact") ? { artifact: ref.id } : {},
|
|
14588
14567
|
...versionArgument === undefined && ref?.version !== undefined ? { version: ref.version } : {}
|
|
14589
14568
|
},
|
|
@@ -14594,7 +14573,7 @@ async function resolveIssueArguments(tool, args, cwd, env, exec) {
|
|
|
14594
14573
|
if (!legionIssue)
|
|
14595
14574
|
throw new Error("issue is required; supply issue or set LEGION_ISSUE");
|
|
14596
14575
|
if (nativeIssueKeyPattern.test(legionIssue) || externalIssueRefPattern.test(legionIssue)) {
|
|
14597
|
-
return { args: { ...args, issue: legionIssue }, ref: null };
|
|
14576
|
+
return { args: { ...args, issue: canonicalExternalIssueRef(legionIssue) }, ref: null };
|
|
14598
14577
|
}
|
|
14599
14578
|
if (!bareIssueNumberPattern.test(legionIssue)) {
|
|
14600
14579
|
throw new Error("LEGION_ISSUE must be a native issue key (e.g. LEGION-3), an external owner/repo#n reference, or a bare positive issue number");
|
|
@@ -14927,7 +14906,7 @@ async function ensureIssue(client, issueReference, actor) {
|
|
|
14927
14906
|
} catch (error) {
|
|
14928
14907
|
if (error instanceof DispatchServiceError && error.code === "PROJECT_UNMAPPED") {
|
|
14929
14908
|
const repository = issueReference.slice(0, issueReference.lastIndexOf("#"));
|
|
14930
|
-
throw new Error(`repository ${repository} is not mapped in
|
|
14909
|
+
throw new Error(`repository ${repository} is not mapped in repository settings and no DISPATCH_DEFAULT_PROJECT is configured`);
|
|
14931
14910
|
}
|
|
14932
14911
|
throw error;
|
|
14933
14912
|
}
|
package/package.json
CHANGED
package/skills/dispatch/SKILL.md
CHANGED
|
@@ -18,7 +18,7 @@ Every session works on an issue. Legion pre-fills `issue` from `LEGION_ISSUE`: u
|
|
|
18
18
|
such as `LEGION-3`, an external `owner/repo#n` reference, or a bare positive number (resolved
|
|
19
19
|
against the cwd repository). Otherwise pass the issue to every issue-scoped tool as its native key
|
|
20
20
|
or an external `owner/repo#n` reference. On first use, an external reference creates its native issue in the
|
|
21
|
-
project
|
|
21
|
+
project configured for that repository in Dispatch Settings, then falls back to `DISPATCH_DEFAULT_PROJECT`.
|
|
22
22
|
|
|
23
23
|
Architects create newly tracked child work with:
|
|
24
24
|
```ts
|
|
@@ -213,7 +213,7 @@ corresponding lifecycle procedure.
|
|
|
213
213
|
| `pr-closed-unmerged` | Decide from current scope whether to reopen the work, send a fresh implementer, or cancel it with a reason. Delegate the repository action to the responsible phase worker and keep ownership. |
|
|
214
214
|
| `issue-comment` | Interpret the comment in the issue's design context. Answer it, adjust the plan, or relay it via `envoy_publish` to the responsible worker's role token; scope and product decisions remain with you. |
|
|
215
215
|
| `catchup-overseer` | Verify its gates, child counts, and PR verdicts against current artifacts, then resume the applicable numbered lifecycle step. It is a current-state snapshot, not a raw-event replay. For each entry in its `phaseCompletions` (`{issue, role, summary, at}`, phases that completed while you were not live), handle it exactly as a `phase-complete` wake. |
|
|
216
|
-
| `
|
|
216
|
+
| `worker-died` | Payload `{type:"worker-died", issue, role}`. The daemon probed and retried this role's worker through `MAX_LAUNCH_FAILURES` attempts and could not confirm a boot — never a raw-event replay or a silent revive. Reassess the work and `spawn_worker` again for the role (it resumes the same agent via `--resume` if a session file survived) or reassign it if the failure looks environmental, not agent-specific. |
|
|
217
217
|
| `reopened` | Reopen the root lifecycle: inspect the reason and current artifacts, reassess scope and children, and resume at the first applicable numbered step. |
|
|
218
218
|
|
|
219
219
|
## Escalation judgment
|