@sjawhar/pi-legion-envoy 7.5.2 → 7.6.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/envoy.js +74 -25
- package/dist/legion.js +75 -26
- package/dist/skills/dispatch/SKILL.md +7 -8
- package/dist/skills/dispatch/references/issues.md +10 -0
- package/package.json +1 -1
package/dist/envoy.js
CHANGED
|
@@ -30073,6 +30073,7 @@ var ASK_URGENCIES = ["low", "med", "high", "blocking"];
|
|
|
30073
30073
|
var ASK_QUESTION_MAX = 800;
|
|
30074
30074
|
var SEARCH_QUERY_MAX = 1000;
|
|
30075
30075
|
var SEARCH_QUERY_HINT = "search with a short phrase of a few words, not a passage";
|
|
30076
|
+
var SEARCH_KIND_DEPTH = 100;
|
|
30076
30077
|
var PROJECT_KEY_PATTERN = /^[A-Z][A-Z0-9]{1,9}$/;
|
|
30077
30078
|
var ISSUE_STATUSES = [
|
|
30078
30079
|
"triage",
|
|
@@ -30408,7 +30409,7 @@ var dispatchToolSpecs = [
|
|
|
30408
30409
|
{
|
|
30409
30410
|
name: "dispatch_search",
|
|
30410
30411
|
example: { query: "astrolabe" },
|
|
30411
|
-
description: "Search every issue, document, comment, ask, and message for a keyword or phrase and get deep links. " + "Use it before creating an issue or a design document, and to find where a word was written. " + 'Websearch syntax: "quoted phrase", -excluded, OR.',
|
|
30412
|
+
description: "Search every issue, document, comment, ask, and message for a keyword or phrase and get deep links. " + "Use it before creating an issue or a design document, and to find where a word was written. " + 'Websearch syntax: "quoted phrase", -excluded, OR. ' + "Each kind of content is ranked on its own and the lists are merged, so the top holds the best " + "issue, document, ask, comment and message; an issue key searched alone lists that issue first. " + `The answer names how many results match; offset pages through them, and each kind lists at most its best ${SEARCH_KIND_DEPTH}, ` + "so narrow the query or name a project to reach the rest. Paging is exact only while the " + "corpus holds still: content added, changed, or removed between two offsets can shift rows " + "across a page boundary, so one hit can come back twice and another never.",
|
|
30412
30413
|
arguments: (z2) => ({
|
|
30413
30414
|
query: z2.string({
|
|
30414
30415
|
min: 2,
|
|
@@ -30416,7 +30417,8 @@ var dispatchToolSpecs = [
|
|
|
30416
30417
|
maxHint: SEARCH_QUERY_HINT
|
|
30417
30418
|
}).describe(`Keyword, phrase, or websearch expression; 2 to ${SEARCH_QUERY_MAX} characters.`),
|
|
30418
30419
|
project: z2.string().describe("Optional project key to search within.").optional(),
|
|
30419
|
-
limit: z2.number({ int: true, min: 1, max: 50 }).describe("Maximum results, 1-50; default 20.").optional()
|
|
30420
|
+
limit: z2.number({ int: true, min: 1, max: 50 }).describe("Maximum results, 1-50; default 20.").optional(),
|
|
30421
|
+
offset: z2.number({ int: true, min: 0 }).describe("Results to skip before the page; nonnegative integer; default 0.").optional()
|
|
30420
30422
|
}),
|
|
30421
30423
|
validation: {
|
|
30422
30424
|
check: (value) => {
|
|
@@ -32513,6 +32515,71 @@ class DispatchClient {
|
|
|
32513
32515
|
}
|
|
32514
32516
|
}
|
|
32515
32517
|
|
|
32518
|
+
// ../envoy-client/src/search-answer.ts
|
|
32519
|
+
function pageSummaryText(offset, count, total) {
|
|
32520
|
+
return `showing ${offset + 1}-${offset + count} of ${total}`;
|
|
32521
|
+
}
|
|
32522
|
+
function searchResultLine(result, baseUrl) {
|
|
32523
|
+
const href = new URL(result.href, baseUrl).toString();
|
|
32524
|
+
const { owner } = result;
|
|
32525
|
+
if (owner.kind === "document") {
|
|
32526
|
+
const reference = dispatchDocumentRef(owner.project, owner.slug);
|
|
32527
|
+
return `${reference} [document] ${owner.name} - ${result.kind}: ${snippetText(result.snippet)} -> ${href}`;
|
|
32528
|
+
}
|
|
32529
|
+
const artifactName = result.artifact ? ` ${result.artifact.name}` : "";
|
|
32530
|
+
const label = `${owner.key} [${owner.status}] ${owner.title} - ${result.kind}${artifactName}`;
|
|
32531
|
+
return `${label}: ${snippetText(result.snippet)} -> ${href}`;
|
|
32532
|
+
}
|
|
32533
|
+
function searchAnswer(search, query, offset, configUrl) {
|
|
32534
|
+
const results = search.results;
|
|
32535
|
+
const count = results.length;
|
|
32536
|
+
const lines = results.map((result) => searchResultLine(result, configUrl));
|
|
32537
|
+
const noun = count === 1 ? "result" : "results";
|
|
32538
|
+
const noResults = `No results for "${query}".`;
|
|
32539
|
+
if (typeof search.total !== "number") {
|
|
32540
|
+
if (offset !== undefined && offset > 0) {
|
|
32541
|
+
throw new Error(`Dispatch answered without a total: it predates search paging and ignored offset ${offset}, so this would be its first page again.`);
|
|
32542
|
+
}
|
|
32543
|
+
return {
|
|
32544
|
+
text: count === 0 ? noResults : [`${count} ${noun} for "${query}" (${search.took_ms} ms)`, ...lines].join(`
|
|
32545
|
+
`),
|
|
32546
|
+
details: { query, results }
|
|
32547
|
+
};
|
|
32548
|
+
}
|
|
32549
|
+
const { total, reachable, offset: pageOffset } = search;
|
|
32550
|
+
const end = pageOffset + count;
|
|
32551
|
+
const cut = reachable < total ? `Each kind lists only its best ${SEARCH_KIND_DEPTH} matches, so ${reachable} of the ${total} can be paged to; narrow the query or name a project to reach the rest.` : undefined;
|
|
32552
|
+
const details = {
|
|
32553
|
+
query,
|
|
32554
|
+
results,
|
|
32555
|
+
total,
|
|
32556
|
+
reachable,
|
|
32557
|
+
offset: pageOffset,
|
|
32558
|
+
limit: search.limit
|
|
32559
|
+
};
|
|
32560
|
+
if (count === 0) {
|
|
32561
|
+
return {
|
|
32562
|
+
text: total === 0 ? noResults : [
|
|
32563
|
+
`No results for "${query}" at offset ${pageOffset}: it matches ${total}, and the pages reach the first ${reachable}.`,
|
|
32564
|
+
...cut === undefined ? [] : [cut]
|
|
32565
|
+
].join(`
|
|
32566
|
+
`),
|
|
32567
|
+
details
|
|
32568
|
+
};
|
|
32569
|
+
}
|
|
32570
|
+
const showing = pageOffset === 0 && count === total ? "" : `${pageSummaryText(pageOffset, count, total)}, `;
|
|
32571
|
+
return {
|
|
32572
|
+
text: [
|
|
32573
|
+
`${count} ${noun} for "${query}" (${showing}${search.took_ms} ms)`,
|
|
32574
|
+
...cut === undefined ? [] : [cut],
|
|
32575
|
+
...lines,
|
|
32576
|
+
...end < reachable ? [`Next page: offset ${end}.`] : []
|
|
32577
|
+
].join(`
|
|
32578
|
+
`),
|
|
32579
|
+
details
|
|
32580
|
+
};
|
|
32581
|
+
}
|
|
32582
|
+
|
|
32516
32583
|
// ../envoy-client/src/tool-input-errors.ts
|
|
32517
32584
|
class ToolInputError extends Error {
|
|
32518
32585
|
tool;
|
|
@@ -32822,17 +32889,6 @@ function duplicateCandidates(error48) {
|
|
|
32822
32889
|
throw error48;
|
|
32823
32890
|
return error48.candidates;
|
|
32824
32891
|
}
|
|
32825
|
-
function searchResultLine(result, baseUrl) {
|
|
32826
|
-
const href = new URL(result.href, baseUrl).toString();
|
|
32827
|
-
const { owner } = result;
|
|
32828
|
-
if (owner.kind === "document") {
|
|
32829
|
-
const reference = dispatchDocumentRef(owner.project, owner.slug);
|
|
32830
|
-
return `${reference} [document] ${owner.name} - ${result.kind}: ${snippetText(result.snippet)} -> ${href}`;
|
|
32831
|
-
}
|
|
32832
|
-
const artifactName = result.artifact ? ` ${result.artifact.name}` : "";
|
|
32833
|
-
const label = `${owner.key} [${owner.status}] ${owner.title} - ${result.kind}${artifactName}`;
|
|
32834
|
-
return `${label}: ${snippetText(result.snippet)} -> ${href}`;
|
|
32835
|
-
}
|
|
32836
32892
|
function askUrgency(args) {
|
|
32837
32893
|
const value = args.urgency;
|
|
32838
32894
|
return ASK_URGENCIES.find((urgency) => urgency === value);
|
|
@@ -34031,20 +34087,13 @@ async function executeDispatchTool(input) {
|
|
|
34031
34087
|
const query = stringArg(args, "query");
|
|
34032
34088
|
const project = optionalString(args, "project");
|
|
34033
34089
|
const limit = optionalNumber(args, "limit");
|
|
34090
|
+
const offset = optionalNumber(args, "offset");
|
|
34034
34091
|
const search = await client.search(query, {
|
|
34035
34092
|
...project === undefined ? {} : { project },
|
|
34036
|
-
...limit === undefined ? {} : { limit }
|
|
34093
|
+
...limit === undefined ? {} : { limit },
|
|
34094
|
+
...offset === undefined ? {} : { offset }
|
|
34037
34095
|
});
|
|
34038
|
-
|
|
34039
|
-
const count = results.length;
|
|
34040
|
-
return {
|
|
34041
|
-
text: count === 0 ? `No results for "${query}".` : [
|
|
34042
|
-
`${count} ${count === 1 ? "result" : "results"} for "${query}" (${search.took_ms} ms)`,
|
|
34043
|
-
...results.map((result) => searchResultLine(result, configUrl))
|
|
34044
|
-
].join(`
|
|
34045
|
-
`),
|
|
34046
|
-
details: { query, results }
|
|
34047
|
-
};
|
|
34096
|
+
return searchAnswer(search, query, offset, configUrl);
|
|
34048
34097
|
}
|
|
34049
34098
|
case "dispatch_issues": {
|
|
34050
34099
|
const project = stringArg(args, "project");
|
|
@@ -34084,7 +34133,7 @@ async function executeDispatchTool(input) {
|
|
|
34084
34133
|
}));
|
|
34085
34134
|
const titles = await liveSessionTitles(client, rows.some((row) => holdsSession(row.claim)));
|
|
34086
34135
|
const isPartial = offset !== 0 || rows.length !== total;
|
|
34087
|
-
const showing = !isPartial ? "" : rows.length === 0 ? `showing 0-0 of ${total}` :
|
|
34136
|
+
const showing = !isPartial ? "" : rows.length === 0 ? `showing 0-0 of ${total}` : pageSummaryText(offset, rows.length, total);
|
|
34088
34137
|
return {
|
|
34089
34138
|
text: rows.length === 0 ? `No issues in ${project}.${isPartial ? ` (${showing})` : ""}` : [
|
|
34090
34139
|
`${rows.length} ${rows.length === 1 ? "issue" : "issues"} in ${project}` + (isPartial ? ` (${showing})` : ""),
|
package/dist/legion.js
CHANGED
|
@@ -14160,6 +14160,7 @@ var ASK_URGENCIES = ["low", "med", "high", "blocking"];
|
|
|
14160
14160
|
var ASK_QUESTION_MAX = 800;
|
|
14161
14161
|
var SEARCH_QUERY_MAX = 1000;
|
|
14162
14162
|
var SEARCH_QUERY_HINT = "search with a short phrase of a few words, not a passage";
|
|
14163
|
+
var SEARCH_KIND_DEPTH = 100;
|
|
14163
14164
|
var PROJECT_KEY_PATTERN = /^[A-Z][A-Z0-9]{1,9}$/;
|
|
14164
14165
|
var ISSUE_STATUSES = [
|
|
14165
14166
|
"triage",
|
|
@@ -14495,7 +14496,7 @@ var dispatchToolSpecs = [
|
|
|
14495
14496
|
{
|
|
14496
14497
|
name: "dispatch_search",
|
|
14497
14498
|
example: { query: "astrolabe" },
|
|
14498
|
-
description: "Search every issue, document, comment, ask, and message for a keyword or phrase and get deep links. " + "Use it before creating an issue or a design document, and to find where a word was written. " + 'Websearch syntax: "quoted phrase", -excluded, OR.',
|
|
14499
|
+
description: "Search every issue, document, comment, ask, and message for a keyword or phrase and get deep links. " + "Use it before creating an issue or a design document, and to find where a word was written. " + 'Websearch syntax: "quoted phrase", -excluded, OR. ' + "Each kind of content is ranked on its own and the lists are merged, so the top holds the best " + "issue, document, ask, comment and message; an issue key searched alone lists that issue first. " + `The answer names how many results match; offset pages through them, and each kind lists at most its best ${SEARCH_KIND_DEPTH}, ` + "so narrow the query or name a project to reach the rest. Paging is exact only while the " + "corpus holds still: content added, changed, or removed between two offsets can shift rows " + "across a page boundary, so one hit can come back twice and another never.",
|
|
14499
14500
|
arguments: (z2) => ({
|
|
14500
14501
|
query: z2.string({
|
|
14501
14502
|
min: 2,
|
|
@@ -14503,7 +14504,8 @@ var dispatchToolSpecs = [
|
|
|
14503
14504
|
maxHint: SEARCH_QUERY_HINT
|
|
14504
14505
|
}).describe(`Keyword, phrase, or websearch expression; 2 to ${SEARCH_QUERY_MAX} characters.`),
|
|
14505
14506
|
project: z2.string().describe("Optional project key to search within.").optional(),
|
|
14506
|
-
limit: z2.number({ int: true, min: 1, max: 50 }).describe("Maximum results, 1-50; default 20.").optional()
|
|
14507
|
+
limit: z2.number({ int: true, min: 1, max: 50 }).describe("Maximum results, 1-50; default 20.").optional(),
|
|
14508
|
+
offset: z2.number({ int: true, min: 0 }).describe("Results to skip before the page; nonnegative integer; default 0.").optional()
|
|
14507
14509
|
}),
|
|
14508
14510
|
validation: {
|
|
14509
14511
|
check: (value) => {
|
|
@@ -15298,6 +15300,71 @@ function dispatchChildRef(ownerRef, kind, id) {
|
|
|
15298
15300
|
return `${ownerRef}/${kind}/${id}`;
|
|
15299
15301
|
}
|
|
15300
15302
|
|
|
15303
|
+
// ../envoy-client/src/search-answer.ts
|
|
15304
|
+
function pageSummaryText(offset, count, total) {
|
|
15305
|
+
return `showing ${offset + 1}-${offset + count} of ${total}`;
|
|
15306
|
+
}
|
|
15307
|
+
function searchResultLine(result, baseUrl) {
|
|
15308
|
+
const href = new URL(result.href, baseUrl).toString();
|
|
15309
|
+
const { owner } = result;
|
|
15310
|
+
if (owner.kind === "document") {
|
|
15311
|
+
const reference = dispatchDocumentRef(owner.project, owner.slug);
|
|
15312
|
+
return `${reference} [document] ${owner.name} - ${result.kind}: ${snippetText(result.snippet)} -> ${href}`;
|
|
15313
|
+
}
|
|
15314
|
+
const artifactName = result.artifact ? ` ${result.artifact.name}` : "";
|
|
15315
|
+
const label = `${owner.key} [${owner.status}] ${owner.title} - ${result.kind}${artifactName}`;
|
|
15316
|
+
return `${label}: ${snippetText(result.snippet)} -> ${href}`;
|
|
15317
|
+
}
|
|
15318
|
+
function searchAnswer(search, query, offset, configUrl) {
|
|
15319
|
+
const results = search.results;
|
|
15320
|
+
const count = results.length;
|
|
15321
|
+
const lines = results.map((result) => searchResultLine(result, configUrl));
|
|
15322
|
+
const noun = count === 1 ? "result" : "results";
|
|
15323
|
+
const noResults = `No results for "${query}".`;
|
|
15324
|
+
if (typeof search.total !== "number") {
|
|
15325
|
+
if (offset !== undefined && offset > 0) {
|
|
15326
|
+
throw new Error(`Dispatch answered without a total: it predates search paging and ignored offset ${offset}, so this would be its first page again.`);
|
|
15327
|
+
}
|
|
15328
|
+
return {
|
|
15329
|
+
text: count === 0 ? noResults : [`${count} ${noun} for "${query}" (${search.took_ms} ms)`, ...lines].join(`
|
|
15330
|
+
`),
|
|
15331
|
+
details: { query, results }
|
|
15332
|
+
};
|
|
15333
|
+
}
|
|
15334
|
+
const { total, reachable, offset: pageOffset } = search;
|
|
15335
|
+
const end = pageOffset + count;
|
|
15336
|
+
const cut = reachable < total ? `Each kind lists only its best ${SEARCH_KIND_DEPTH} matches, so ${reachable} of the ${total} can be paged to; narrow the query or name a project to reach the rest.` : undefined;
|
|
15337
|
+
const details = {
|
|
15338
|
+
query,
|
|
15339
|
+
results,
|
|
15340
|
+
total,
|
|
15341
|
+
reachable,
|
|
15342
|
+
offset: pageOffset,
|
|
15343
|
+
limit: search.limit
|
|
15344
|
+
};
|
|
15345
|
+
if (count === 0) {
|
|
15346
|
+
return {
|
|
15347
|
+
text: total === 0 ? noResults : [
|
|
15348
|
+
`No results for "${query}" at offset ${pageOffset}: it matches ${total}, and the pages reach the first ${reachable}.`,
|
|
15349
|
+
...cut === undefined ? [] : [cut]
|
|
15350
|
+
].join(`
|
|
15351
|
+
`),
|
|
15352
|
+
details
|
|
15353
|
+
};
|
|
15354
|
+
}
|
|
15355
|
+
const showing = pageOffset === 0 && count === total ? "" : `${pageSummaryText(pageOffset, count, total)}, `;
|
|
15356
|
+
return {
|
|
15357
|
+
text: [
|
|
15358
|
+
`${count} ${noun} for "${query}" (${showing}${search.took_ms} ms)`,
|
|
15359
|
+
...cut === undefined ? [] : [cut],
|
|
15360
|
+
...lines,
|
|
15361
|
+
...end < reachable ? [`Next page: offset ${end}.`] : []
|
|
15362
|
+
].join(`
|
|
15363
|
+
`),
|
|
15364
|
+
details
|
|
15365
|
+
};
|
|
15366
|
+
}
|
|
15367
|
+
|
|
15301
15368
|
// ../envoy-client/src/tool-input-errors.ts
|
|
15302
15369
|
class ToolInputError extends Error {
|
|
15303
15370
|
tool;
|
|
@@ -15607,17 +15674,6 @@ function duplicateCandidates(error48) {
|
|
|
15607
15674
|
throw error48;
|
|
15608
15675
|
return error48.candidates;
|
|
15609
15676
|
}
|
|
15610
|
-
function searchResultLine(result, baseUrl) {
|
|
15611
|
-
const href = new URL(result.href, baseUrl).toString();
|
|
15612
|
-
const { owner } = result;
|
|
15613
|
-
if (owner.kind === "document") {
|
|
15614
|
-
const reference = dispatchDocumentRef(owner.project, owner.slug);
|
|
15615
|
-
return `${reference} [document] ${owner.name} - ${result.kind}: ${snippetText(result.snippet)} -> ${href}`;
|
|
15616
|
-
}
|
|
15617
|
-
const artifactName = result.artifact ? ` ${result.artifact.name}` : "";
|
|
15618
|
-
const label = `${owner.key} [${owner.status}] ${owner.title} - ${result.kind}${artifactName}`;
|
|
15619
|
-
return `${label}: ${snippetText(result.snippet)} -> ${href}`;
|
|
15620
|
-
}
|
|
15621
15677
|
function askUrgency(args) {
|
|
15622
15678
|
const value = args.urgency;
|
|
15623
15679
|
return ASK_URGENCIES.find((urgency) => urgency === value);
|
|
@@ -16816,20 +16872,13 @@ async function executeDispatchTool(input) {
|
|
|
16816
16872
|
const query = stringArg(args, "query");
|
|
16817
16873
|
const project = optionalString(args, "project");
|
|
16818
16874
|
const limit = optionalNumber(args, "limit");
|
|
16875
|
+
const offset = optionalNumber(args, "offset");
|
|
16819
16876
|
const search = await client.search(query, {
|
|
16820
16877
|
...project === undefined ? {} : { project },
|
|
16821
|
-
...limit === undefined ? {} : { limit }
|
|
16878
|
+
...limit === undefined ? {} : { limit },
|
|
16879
|
+
...offset === undefined ? {} : { offset }
|
|
16822
16880
|
});
|
|
16823
|
-
|
|
16824
|
-
const count = results.length;
|
|
16825
|
-
return {
|
|
16826
|
-
text: count === 0 ? `No results for "${query}".` : [
|
|
16827
|
-
`${count} ${count === 1 ? "result" : "results"} for "${query}" (${search.took_ms} ms)`,
|
|
16828
|
-
...results.map((result) => searchResultLine(result, configUrl))
|
|
16829
|
-
].join(`
|
|
16830
|
-
`),
|
|
16831
|
-
details: { query, results }
|
|
16832
|
-
};
|
|
16881
|
+
return searchAnswer(search, query, offset, configUrl);
|
|
16833
16882
|
}
|
|
16834
16883
|
case "dispatch_issues": {
|
|
16835
16884
|
const project = stringArg(args, "project");
|
|
@@ -16869,7 +16918,7 @@ async function executeDispatchTool(input) {
|
|
|
16869
16918
|
}));
|
|
16870
16919
|
const titles = await liveSessionTitles(client, rows.some((row) => holdsSession(row.claim)));
|
|
16871
16920
|
const isPartial = offset !== 0 || rows.length !== total;
|
|
16872
|
-
const showing = !isPartial ? "" : rows.length === 0 ? `showing 0-0 of ${total}` :
|
|
16921
|
+
const showing = !isPartial ? "" : rows.length === 0 ? `showing 0-0 of ${total}` : pageSummaryText(offset, rows.length, total);
|
|
16873
16922
|
return {
|
|
16874
16923
|
text: rows.length === 0 ? `No issues in ${project}.${isPartial ? ` (${showing})` : ""}` : [
|
|
16875
16924
|
`${rows.length} ${rows.length === 1 ? "issue" : "issues"} in ${project}` + (isPartial ? ` (${showing})` : ""),
|
|
@@ -17475,7 +17524,7 @@ function endInjectedUserTurns(sessionID) {
|
|
|
17475
17524
|
// package.json
|
|
17476
17525
|
var package_default = {
|
|
17477
17526
|
name: "@sjawhar/pi-legion-envoy",
|
|
17478
|
-
version: "7.
|
|
17527
|
+
version: "7.6.0",
|
|
17479
17528
|
license: "Apache-2.0",
|
|
17480
17529
|
type: "module",
|
|
17481
17530
|
omp: {
|
|
@@ -160,15 +160,14 @@ follow [Writing a spec](#writing-a-spec).
|
|
|
160
160
|
you plan, start a design document, file an issue, ask, post a finding or start work, and what to
|
|
161
161
|
do with each hit. What it leaves out:
|
|
162
162
|
```ts
|
|
163
|
-
dispatch_search({ query, project?, limit? })
|
|
163
|
+
dispatch_search({ query, project?, limit?, offset? })
|
|
164
164
|
```
|
|
165
|
-
Websearch syntax applies: `"merge queue"`, `-daemon`, `OR`.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
"no prior issue" in the spec.
|
|
165
|
+
Websearch syntax applies: `"merge queue"`, `-daemon`, `OR`. Issues, documents, asks, comments, and messages rank separately; the
|
|
166
|
+
merged page orders each kind's best in turn — issue, document, ask, comment, message — and a bare issue key ranks first. A page
|
|
167
|
+
holds `limit` hits (20 default, 50 max); the first line gives the total (`showing 1-20 of 312`); see
|
|
168
|
+
[Search paging](skill://dispatch/references/issues.md#search-paging) for more. Queries over 1,000 characters are refused: use the
|
|
169
|
+
few words `skill://dispatch-first` names, never a pasted passage. Issue hits start with the issue key; document hits start with
|
|
170
|
+
`dispatch://PROJECT/artifact/<slug>`, then the link. Cite the hit (`dispatch://KEY` or the doc ref) or say "no prior issue".
|
|
172
171
|
|
|
173
172
|
`dispatch_issue` refuses a title that near-duplicates an issue in the same project and returns the candidates (`POSSIBLE_DUPLICATE`).
|
|
174
173
|
Read them; reference the existing issue, or repeat the call with `force: true` when it is genuinely new work.
|
|
@@ -193,6 +193,16 @@ The audit finds four shapes:
|
|
|
193
193
|
Run the audit as a step of a coordinator's loop, at each checkpoint, not as a habit: these shapes
|
|
194
194
|
are found by running the check, not by noticing them.
|
|
195
195
|
|
|
196
|
+
## Search paging
|
|
197
|
+
|
|
198
|
+
`skill://dispatch` sends you here when a `dispatch_search` page is not enough: more hits remain,
|
|
199
|
+
or a kind runs out before the page does.
|
|
200
|
+
|
|
201
|
+
A page holds `limit` hits (20 by default, 50 at most); the first line names how many match
|
|
202
|
+
(`showing 1-20 of 312`), and, while more can be reached, the last line names the next `offset`.
|
|
203
|
+
Each kind lists at most its best 100, so when the result says the rest cannot be paged to, narrow
|
|
204
|
+
the query or name a `project`.
|
|
205
|
+
|
|
196
206
|
## Syncing a project's architecture model
|
|
197
207
|
|
|
198
208
|
Import a project's architecture model from its configured source repository now (a human configures the source in Settings):
|