@sjawhar/pi-envoy 10.5.0 → 10.6.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/dist/dispatch.js
CHANGED
|
@@ -14033,7 +14033,8 @@ var dispatchToolSpecs = [
|
|
|
14033
14033
|
labels: z2.array(z2.string({ min: 1, max: 40 }), { max: 20 }).describe("Optional initial labels, at most 20 labels of up to 40 characters.").optional(),
|
|
14034
14034
|
priority: z2.number({ int: true, min: 0, max: 3 }).describe("Optional coarse priority: P0 is highest and P3 is lowest.").optional(),
|
|
14035
14035
|
assignee: z2.string().describe("Email of the person who answers this issue's asks (someone who has signed in to Dispatch); defaults to your owner when you act for a person, else the parent's assignee, else unassigned.").optional(),
|
|
14036
|
-
components: componentsArgument(z2).optional()
|
|
14036
|
+
components: componentsArgument(z2).optional(),
|
|
14037
|
+
repo: z2.string().describe("The repository the issue targets, owner/name, mapped to the issue's project in Settings; a child inherits its parent's when unset, and an issue with none on its parent chain takes the project's default.").optional()
|
|
14037
14038
|
})
|
|
14038
14039
|
},
|
|
14039
14040
|
{
|
|
@@ -14043,7 +14044,7 @@ var dispatchToolSpecs = [
|
|
|
14043
14044
|
status: "done",
|
|
14044
14045
|
reason: "Shipped in owner/repo#7; verified on the production dashboard."
|
|
14045
14046
|
},
|
|
14046
|
-
description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, replace the issues it is blocked by,
|
|
14047
|
+
description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, replace the issues it is blocked by, attach it to " + "architecture components, or set the repository it targets. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. A non-empty external_links is " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link; an empty external_links removes every link instead. components " + "replaces the issue's own attachment. Closing an issue " + "(status done) requires reason, the note that says why: it is posted on the issue as a " + "message, then the issue closes, because a closed issue refuses messages, comments, and " + "artifacts; reason goes only with status done. A closed issue takes only rank, components, " + "a reopening status (any status but done), and an external_links write that adds no new " + "link (so a link can move to the issue that replaced it); everything else, priority " + "included, waits for the reopen. " + "priority is yours to set and a human overrides it; rank, the board's own order, is not " + "settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
|
|
14047
14048
|
arguments: (z2) => ({
|
|
14048
14049
|
issue: z2.string().describe(ISSUE_REFERENCE),
|
|
14049
14050
|
status: z2.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
|
|
@@ -14055,15 +14056,16 @@ var dispatchToolSpecs = [
|
|
|
14055
14056
|
route: z2.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
|
|
14056
14057
|
parent: z2.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
|
|
14057
14058
|
blocked_by: z2.array(z2.string({ min: 1 }), { max: MAX_ISSUE_BLOCKERS }).describe("Replacement list of issue keys in the same project this issue waits on; [] clears it. Dispatch refuses a dependency cycle.").optional(),
|
|
14058
|
-
components: componentsArgument(z2).optional()
|
|
14059
|
+
components: componentsArgument(z2).optional(),
|
|
14060
|
+
repo: z2.string().describe("The repository the issue targets, owner/name, mapped to the issue's project in Settings; an empty string clears it, so the issue inherits its parent's or the project's default again.").optional()
|
|
14059
14061
|
}),
|
|
14060
14062
|
validation: {
|
|
14061
14063
|
check: (value) => {
|
|
14062
14064
|
const input = value;
|
|
14063
14065
|
const reasonFits = input.status === "done" ? typeof input.reason === "string" && input.reason.trim() !== "" : input.reason === undefined;
|
|
14064
|
-
return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || Array.isArray(input.blocked_by) || typeof input.components === "object" && input.components !== null);
|
|
14066
|
+
return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || Array.isArray(input.blocked_by) || typeof input.components === "object" && input.components !== null || typeof input.repo === "string");
|
|
14065
14067
|
},
|
|
14066
|
-
message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, blocked_by, or
|
|
14068
|
+
message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, blocked_by, components, or repo. " + "status done requires reason, a non-empty note saying why the issue is closing, posted on the issue before it closes because a closed issue refuses messages, comments, and artifacts; reason goes only with status done."
|
|
14067
14069
|
},
|
|
14068
14070
|
strict: true
|
|
14069
14071
|
},
|
|
@@ -16846,6 +16848,31 @@ function progressText(progress, sep) {
|
|
|
16846
16848
|
}
|
|
16847
16849
|
return parts.join(sep);
|
|
16848
16850
|
}
|
|
16851
|
+
function repositoryLine(issue2) {
|
|
16852
|
+
if (issue2.resolved_repo === undefined) {
|
|
16853
|
+
return "Repository: unknown (this Dispatch server predates repository fields; upgrade it)";
|
|
16854
|
+
}
|
|
16855
|
+
if (issue2.resolved_repo === null)
|
|
16856
|
+
return "Repository: none";
|
|
16857
|
+
if (issue2.repo !== null && issue2.repo !== undefined)
|
|
16858
|
+
return `Repository: ${issue2.repo} (own)`;
|
|
16859
|
+
return `Repository: ${issue2.resolved_repo} (inherited or project default)`;
|
|
16860
|
+
}
|
|
16861
|
+
function repositoryFieldsWarnings(issue2) {
|
|
16862
|
+
if (issue2.resolved_repo !== undefined)
|
|
16863
|
+
return {};
|
|
16864
|
+
return {
|
|
16865
|
+
warnings: [
|
|
16866
|
+
`dispatch: warning: Dispatch issue is missing resolved_repo: this Dispatch server predates repository fields, so ${issue2.key}'s repository is unknown; upgrade the server`
|
|
16867
|
+
]
|
|
16868
|
+
};
|
|
16869
|
+
}
|
|
16870
|
+
function refuseUnsavedRepository(verb, issue2, repo2) {
|
|
16871
|
+
if (repo2 === undefined || issue2.repo !== undefined)
|
|
16872
|
+
return;
|
|
16873
|
+
const lost = repo2 === "" ? "the repository was not cleared" : `${repo2} was not saved`;
|
|
16874
|
+
throw new Error(`Dispatch ${verb} ${issue2.key} without its repository: this Dispatch server predates repository fields, so ${lost}; upgrade the server`);
|
|
16875
|
+
}
|
|
16849
16876
|
function issueSummary(issue2, events, references, graph, linkBase, titles) {
|
|
16850
16877
|
const asks = issue2.open_asks;
|
|
16851
16878
|
const spec = issue2.artifacts?.find((artifact) => artifact.primary);
|
|
@@ -16872,6 +16899,7 @@ function issueSummary(issue2, events, references, graph, linkBase, titles) {
|
|
|
16872
16899
|
`Labels: ${issue2.labels.length === 0 ? "none" : issue2.labels.join(", ")}`,
|
|
16873
16900
|
componentsLine(issue2.components),
|
|
16874
16901
|
`Route: ${routeText(issue2, titles)}`,
|
|
16902
|
+
repositoryLine(issue2),
|
|
16875
16903
|
`Progress: ${progressText(issue2.progress, ", ") || "none"}`,
|
|
16876
16904
|
...specApproval === undefined ? [] : [`Spec ${specApproval.replace(/^Approval/, "approval")}`],
|
|
16877
16905
|
"External links:",
|
|
@@ -17427,6 +17455,7 @@ async function executeDispatchTool(input) {
|
|
|
17427
17455
|
const priority = optionalPriority(args, "priority");
|
|
17428
17456
|
const assignee = optionalString(args, "assignee");
|
|
17429
17457
|
const components = optionalComponents(args, "components");
|
|
17458
|
+
const repo2 = optionalString(args, "repo");
|
|
17430
17459
|
const labels = args.labels;
|
|
17431
17460
|
const blockedBy = args.blocked_by;
|
|
17432
17461
|
try {
|
|
@@ -17441,9 +17470,11 @@ async function executeDispatchTool(input) {
|
|
|
17441
17470
|
...priority === undefined ? {} : { priority },
|
|
17442
17471
|
...assignee === undefined ? {} : { assignee },
|
|
17443
17472
|
...components === undefined ? {} : { components },
|
|
17473
|
+
...repo2 === undefined ? {} : { repo: repo2 },
|
|
17444
17474
|
...Array.isArray(labels) ? { labels } : {},
|
|
17445
17475
|
actor
|
|
17446
17476
|
});
|
|
17477
|
+
refuseUnsavedRepository("created", created, repo2);
|
|
17447
17478
|
const componentGuidance = await architectureGuidance(client, created.project, created.components);
|
|
17448
17479
|
const adviceLines = [
|
|
17449
17480
|
...renderAdvice(input.tool, created.key, created.advice, {
|
|
@@ -17492,6 +17523,7 @@ async function executeDispatchTool(input) {
|
|
|
17492
17523
|
const route = optionalString(args, "route");
|
|
17493
17524
|
const parent = optionalString(args, "parent");
|
|
17494
17525
|
const components = optionalComponents(args, "components");
|
|
17526
|
+
const repo2 = optionalString(args, "repo");
|
|
17495
17527
|
const priority = optionalPriority(args, "priority");
|
|
17496
17528
|
const labels = Array.isArray(args.labels) ? args.labels : undefined;
|
|
17497
17529
|
const blockedBy = Array.isArray(args.blocked_by) ? args.blocked_by : undefined;
|
|
@@ -17531,6 +17563,7 @@ async function executeDispatchTool(input) {
|
|
|
17531
17563
|
...parent === undefined ? {} : { parent: parent === "" ? null : parent },
|
|
17532
17564
|
...blockedBy === undefined ? {} : { blocked_by: blockedBy },
|
|
17533
17565
|
...components === undefined ? {} : { components },
|
|
17566
|
+
...repo2 === undefined ? {} : { repo: repo2 === "" ? null : repo2 },
|
|
17534
17567
|
...sentLinks === undefined ? {} : { external_links: sentLinks },
|
|
17535
17568
|
actor
|
|
17536
17569
|
});
|
|
@@ -17545,6 +17578,7 @@ async function executeDispatchTool(input) {
|
|
|
17545
17578
|
throw refusalWithCode(error48, taken, landed);
|
|
17546
17579
|
throw withAccount(error48, landed);
|
|
17547
17580
|
}
|
|
17581
|
+
refuseUnsavedRepository("updated", after, repo2);
|
|
17548
17582
|
const linkCount = `(${after.external_links.length} ${after.external_links.length === 1 ? "link" : "links"})`;
|
|
17549
17583
|
const changes = [
|
|
17550
17584
|
...closingNote === undefined ? [] : [`reason posted as message ${closingNote.id} (${closingNote.ref})`],
|
|
@@ -17560,7 +17594,10 @@ async function executeDispatchTool(input) {
|
|
|
17560
17594
|
...blockedBy === undefined ? [] : [
|
|
17561
17595
|
after.blocked_by.length === 0 ? "blocked_by cleared" : `blocked by ${after.blocked_by.join(", ")}`
|
|
17562
17596
|
],
|
|
17563
|
-
...components === undefined ? [] : [componentsChange(components, after.components)]
|
|
17597
|
+
...components === undefined ? [] : [componentsChange(components, after.components)],
|
|
17598
|
+
...repo2 === undefined ? [] : [
|
|
17599
|
+
after.repo === null ? `repo cleared (resolves to ${after.resolved_repo ?? "none"})` : `repo -> ${after.repo}`
|
|
17600
|
+
]
|
|
17564
17601
|
];
|
|
17565
17602
|
const adviceLines = renderAdvice(input.tool, after.key, after.advice, {
|
|
17566
17603
|
setsStatus: status !== undefined
|
|
@@ -18255,7 +18292,8 @@ ${trailer.join(`
|
|
|
18255
18292
|
return {
|
|
18256
18293
|
text: issueSummary(read.issue, read.events, references, [...pictures2.lines, ...graph], linkBase, titles),
|
|
18257
18294
|
details: { issue: read.issue.key },
|
|
18258
|
-
...showImages(pictures2)
|
|
18295
|
+
...showImages(pictures2),
|
|
18296
|
+
...repositoryFieldsWarnings(read.issue)
|
|
18259
18297
|
};
|
|
18260
18298
|
}
|
|
18261
18299
|
default:
|
|
@@ -19170,6 +19208,10 @@ async function runDispatchCli(argv, rawEnv, io) {
|
|
|
19170
19208
|
...io.fetchImpl === undefined ? {} : { fetchImpl: io.fetchImpl }
|
|
19171
19209
|
});
|
|
19172
19210
|
text = result.text;
|
|
19211
|
+
for (const warning of result.warnings ?? []) {
|
|
19212
|
+
io.stderr(`${warning}
|
|
19213
|
+
`);
|
|
19214
|
+
}
|
|
19173
19215
|
try {
|
|
19174
19216
|
for (const image of result.images ?? []) {
|
|
19175
19217
|
const picture = writePicture(dir, image);
|
|
@@ -19209,8 +19251,17 @@ async function runDispatchCli(argv, rawEnv, io) {
|
|
|
19209
19251
|
|
|
19210
19252
|
// ../envoy-client/bin/dispatch.ts
|
|
19211
19253
|
var readText = (path2) => readFileSync4(path2 === "-" ? 0 : path2, "utf-8");
|
|
19212
|
-
|
|
19213
|
-
|
|
19254
|
+
var pending = [];
|
|
19255
|
+
var writeTo = (stream) => (text) => {
|
|
19256
|
+
const { promise: promise2, resolve: resolve2 } = Promise.withResolvers();
|
|
19257
|
+
stream.write(text, () => resolve2());
|
|
19258
|
+
pending.push(promise2);
|
|
19259
|
+
};
|
|
19260
|
+
var code = await runDispatchCli(Bun.argv.slice(2), process.env, {
|
|
19261
|
+
stdout: writeTo(process.stdout),
|
|
19262
|
+
stderr: writeTo(process.stderr),
|
|
19214
19263
|
readText,
|
|
19215
19264
|
cwd: process.cwd()
|
|
19216
|
-
})
|
|
19265
|
+
});
|
|
19266
|
+
await Promise.all(pending);
|
|
19267
|
+
process.exit(code);
|
package/dist/envoy.js
CHANGED
|
@@ -30020,7 +30020,8 @@ var dispatchToolSpecs = [
|
|
|
30020
30020
|
labels: z2.array(z2.string({ min: 1, max: 40 }), { max: 20 }).describe("Optional initial labels, at most 20 labels of up to 40 characters.").optional(),
|
|
30021
30021
|
priority: z2.number({ int: true, min: 0, max: 3 }).describe("Optional coarse priority: P0 is highest and P3 is lowest.").optional(),
|
|
30022
30022
|
assignee: z2.string().describe("Email of the person who answers this issue's asks (someone who has signed in to Dispatch); defaults to your owner when you act for a person, else the parent's assignee, else unassigned.").optional(),
|
|
30023
|
-
components: componentsArgument(z2).optional()
|
|
30023
|
+
components: componentsArgument(z2).optional(),
|
|
30024
|
+
repo: z2.string().describe("The repository the issue targets, owner/name, mapped to the issue's project in Settings; a child inherits its parent's when unset, and an issue with none on its parent chain takes the project's default.").optional()
|
|
30024
30025
|
})
|
|
30025
30026
|
},
|
|
30026
30027
|
{
|
|
@@ -30030,7 +30031,7 @@ var dispatchToolSpecs = [
|
|
|
30030
30031
|
status: "done",
|
|
30031
30032
|
reason: "Shipped in owner/repo#7; verified on the production dashboard."
|
|
30032
30033
|
},
|
|
30033
|
-
description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, replace the issues it is blocked by,
|
|
30034
|
+
description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, replace the issues it is blocked by, attach it to " + "architecture components, or set the repository it targets. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. A non-empty external_links is " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link; an empty external_links removes every link instead. components " + "replaces the issue's own attachment. Closing an issue " + "(status done) requires reason, the note that says why: it is posted on the issue as a " + "message, then the issue closes, because a closed issue refuses messages, comments, and " + "artifacts; reason goes only with status done. A closed issue takes only rank, components, " + "a reopening status (any status but done), and an external_links write that adds no new " + "link (so a link can move to the issue that replaced it); everything else, priority " + "included, waits for the reopen. " + "priority is yours to set and a human overrides it; rank, the board's own order, is not " + "settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
|
|
30034
30035
|
arguments: (z2) => ({
|
|
30035
30036
|
issue: z2.string().describe(ISSUE_REFERENCE),
|
|
30036
30037
|
status: z2.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
|
|
@@ -30042,15 +30043,16 @@ var dispatchToolSpecs = [
|
|
|
30042
30043
|
route: z2.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
|
|
30043
30044
|
parent: z2.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
|
|
30044
30045
|
blocked_by: z2.array(z2.string({ min: 1 }), { max: MAX_ISSUE_BLOCKERS }).describe("Replacement list of issue keys in the same project this issue waits on; [] clears it. Dispatch refuses a dependency cycle.").optional(),
|
|
30045
|
-
components: componentsArgument(z2).optional()
|
|
30046
|
+
components: componentsArgument(z2).optional(),
|
|
30047
|
+
repo: z2.string().describe("The repository the issue targets, owner/name, mapped to the issue's project in Settings; an empty string clears it, so the issue inherits its parent's or the project's default again.").optional()
|
|
30046
30048
|
}),
|
|
30047
30049
|
validation: {
|
|
30048
30050
|
check: (value) => {
|
|
30049
30051
|
const input = value;
|
|
30050
30052
|
const reasonFits = input.status === "done" ? typeof input.reason === "string" && input.reason.trim() !== "" : input.reason === undefined;
|
|
30051
|
-
return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || Array.isArray(input.blocked_by) || typeof input.components === "object" && input.components !== null);
|
|
30053
|
+
return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || Array.isArray(input.blocked_by) || typeof input.components === "object" && input.components !== null || typeof input.repo === "string");
|
|
30052
30054
|
},
|
|
30053
|
-
message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, blocked_by, or
|
|
30055
|
+
message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, blocked_by, components, or repo. " + "status done requires reason, a non-empty note saying why the issue is closing, posted on the issue before it closes because a closed issue refuses messages, comments, and artifacts; reason goes only with status done."
|
|
30054
30056
|
},
|
|
30055
30057
|
strict: true
|
|
30056
30058
|
},
|
|
@@ -153,7 +153,7 @@ that GitHub issue or pull request. Only `dispatch issue` with `--external` creat
|
|
|
153
153
|
`dispatch issue --external owner/repo#n --project <project> --title '<title>'` before addressing it.
|
|
154
154
|
|
|
155
155
|
Create an issue for newly tracked work with `dispatch issue --project <KEY> --title '<title>'` (`dispatch issue --help` lists `--parent`, `--spec-file`, `--label`, `--priority` and the rest).
|
|
156
|
-
Labels are optional: Dispatch trims them, preserves their case, and removes case-insensitive duplicates. `--priority` is yours on creation too — see [Priority is yours to set](skill://dispatch/references/issues.md). Set `--assignee` (the email of a person who has signed in to Dispatch) only when the human said who owns the work; otherwise the default above applies, so a child inherits its parent's assignee. It prints
|
|
156
|
+
Labels are optional: Dispatch trims them, preserves their case, and removes case-insensitive duplicates. `--priority` is yours on creation too — see [Priority is yours to set](skill://dispatch/references/issues.md). Set `--assignee` (the email of a person who has signed in to Dispatch) only when the human said who owns the work; otherwise the default above applies, so a child inherits its parent's assignee. Set `--repo <owner/name>` when the issue targets a repository other than the one it would inherit: its parent's, else the project's default; the repository must be mapped to the project in Settings, and `dispatch read` shows the one the issue resolves to on its `Repository:` line. It prints
|
|
157
157
|
the new key; creating an issue does not subscribe you to it (see [Following](#following)). Use `dispatch issue` only to create an issue; never use it to park a question. When you pass a spec,
|
|
158
158
|
follow [Writing a spec](#writing-a-spec).
|
|
159
159
|
|
|
@@ -85,12 +85,13 @@ issues you own as well as the root. An issue left at `triage` while work is unde
|
|
|
85
85
|
Waiting for the deploy lane is not a status and is never announced.
|
|
86
86
|
|
|
87
87
|
```bash
|
|
88
|
-
# PATCH /api/v1/issues/{key} — status, title, labels, priority, external links (merged by URL, or cleared by an empty list), route, parent, blocked_by
|
|
88
|
+
# PATCH /api/v1/issues/{key} — status, title, labels, priority, external links (merged by URL, or cleared by an empty list), route, parent, blocked_by, repo
|
|
89
89
|
dispatch issue-update --issue PROJ-175 --status testing
|
|
90
90
|
dispatch issue-update --issue PROJ-175 --status done --reason 'Shipped in owner/repo#7; verified on the production dashboard.'
|
|
91
91
|
dispatch issue-update --issue PROJ-175 --priority 1 # 0–3; see Priority is yours to set
|
|
92
92
|
dispatch issue-update --issue PROJ-175 --external-link https://github.com/owner/repo/pull/7
|
|
93
93
|
dispatch issue-update --issue PROJ-175 --parent PROJ-170 # same-project key; --parent '' clears it
|
|
94
|
+
dispatch issue-update --issue PROJ-175 --repo acme/widgets # mapped to the project; --repo '' clears it
|
|
94
95
|
```
|
|
95
96
|
|
|
96
97
|
Closing takes a `--reason`, and the command refuses `--status done` without one: it posts the reason on
|
|
@@ -100,9 +101,16 @@ error names the posted message; after a timeout or a server error it also says t
|
|
|
100
101
|
landed, so read the issue's status first. A retry points its reason at the posted message rather
|
|
101
102
|
than repeating it.
|
|
102
103
|
|
|
103
|
-
The three clears differ: `--clear-priority` sends null, `--parent ''
|
|
104
|
-
empty string, and `--clear-external-links` / `--clear-blocked-by` send an
|
|
105
|
-
wrong shape is a refusal either way.
|
|
104
|
+
The three clears differ: `--clear-priority` sends null, `--parent ''`, `--route ''` and
|
|
105
|
+
`--repo ''` clear with an empty string, and `--clear-external-links` / `--clear-blocked-by` send an
|
|
106
|
+
empty list. Guessing the wrong shape is a refusal either way.
|
|
107
|
+
|
|
108
|
+
An issue targets one repository: its own `--repo`, else its nearest ancestor's, else the project's
|
|
109
|
+
default (set on the Settings page), else none. A repository not mapped to the issue's project is
|
|
110
|
+
refused `REPO_NOT_MAPPED`, naming it. `dispatch read` prints the result as
|
|
111
|
+
`Repository: owner/name (own)`, `Repository: owner/name (inherited or project default)`, or
|
|
112
|
+
`Repository: none`. `Repository: unknown (…)` means the Dispatch server is older than repository
|
|
113
|
+
fields: the read still works, and a `--repo` write there fails rather than drop the repository.
|
|
106
114
|
|
|
107
115
|
Link the pull request that delivers the issue with `--external-link` when you open it; the issue page
|
|
108
116
|
renders its state and checks from that link, and `dispatch read` lists it under `External links:`.
|