@akagilnc/pi-workflow-roles 0.1.5241 → 0.1.5245
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/README.md +2 -3
- package/README.zh-CN.md +2 -3
- package/dist/acp-host/production-host.js +442 -3070
- package/dist/collector-config.js +0 -1
- package/dist/headless-host/production-host.js +443 -3071
- package/dist/migrate-book-topology.js +40 -107
- package/dist/package-contracts/collector-output.js +1 -90
- package/dist/package-contracts/terminating-tools.js +2 -2
- package/dist/packaged-role-registry.js +8 -11
- package/dist/public-cli/invocation.js +2 -22
- package/dist/public-cli/main.js +252 -698
- package/dist/public-cli/option-definitions.js +4 -19
- package/dist/public-cli/settlement.js +2 -79
- package/package.json +1 -1
- package/resources/collector-bot-handbook.md +4 -2
- package/src/collector-config.ts +0 -1
- package/src/collector-role.ts +40 -535
- package/src/collector-tool-schemas.ts +7 -117
- package/src/gh-api-runner.ts +102 -0
- package/src/package-contracts/collector-output.ts +15 -174
- package/src/package-contracts/terminating-tools.ts +0 -2
- package/src/packaged-role-registry.ts +7 -10
- package/src/public-cli/invocation.ts +3 -27
- package/src/public-cli/option-definitions.ts +4 -19
- package/src/public-cli/settlement.ts +3 -102
- package/src/role-runtime-dependencies.ts +0 -4
- package/src/role-runtime.ts +16 -98
- package/src/ticket-snapshot.ts +1 -1
- package/dist/collector-evidence.js +0 -319
- package/dist/collector-github.js +0 -725
- package/dist/collector-identity.js +0 -92
- package/dist/collector-ledger.js +0 -888
- package/dist/collector-target.js +0 -169
- package/src/collector-evidence.ts +0 -466
- package/src/collector-github.ts +0 -1032
- package/src/collector-handbook.ts +0 -194
- package/src/collector-identity.ts +0 -151
- package/src/collector-ledger.ts +0 -1186
- package/src/collector-target.ts +0 -207
|
@@ -206,1960 +206,6 @@ var init_collector_output = __esm({
|
|
|
206
206
|
}
|
|
207
207
|
});
|
|
208
208
|
|
|
209
|
-
// src/collector-evidence.ts
|
|
210
|
-
import { createHash } from "node:crypto";
|
|
211
|
-
function createSystemCollectorClock() {
|
|
212
|
-
const start = process.hrtime.bigint();
|
|
213
|
-
return {
|
|
214
|
-
wallNow: () => /* @__PURE__ */ new Date(),
|
|
215
|
-
monoNow: () => Number(process.hrtime.bigint() - start) / 1e6,
|
|
216
|
-
sleep: (ms, signal) => new Promise((resolve22, reject) => {
|
|
217
|
-
if (signal?.aborted) {
|
|
218
|
-
reject(signal.reason ?? new Error("aborted"));
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
const timer = setTimeout(resolve22, ms);
|
|
222
|
-
const onAbort = () => {
|
|
223
|
-
clearTimeout(timer);
|
|
224
|
-
reject(signal?.reason ?? new Error("aborted"));
|
|
225
|
-
};
|
|
226
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
227
|
-
})
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
function sha256Text(text) {
|
|
231
|
-
return createHash("sha256").update(text, "utf8").digest("hex");
|
|
232
|
-
}
|
|
233
|
-
function computeWindowRelation(authoritativeTime, activationTime, deadlineTime) {
|
|
234
|
-
if (authoritativeTime === void 0 || authoritativeTime === null || authoritativeTime.length === 0) {
|
|
235
|
-
return "uncertain";
|
|
236
|
-
}
|
|
237
|
-
const ms = Date.parse(authoritativeTime);
|
|
238
|
-
if (!Number.isFinite(ms)) return "uncertain";
|
|
239
|
-
const activationMs = activationTime.getTime();
|
|
240
|
-
const deadlineMs = deadlineTime.getTime();
|
|
241
|
-
if (ms < activationMs) return "before";
|
|
242
|
-
if (ms <= deadlineMs) return "within";
|
|
243
|
-
return "after";
|
|
244
|
-
}
|
|
245
|
-
function stableId(kind, githubId) {
|
|
246
|
-
return `${kind}:${githubId}`;
|
|
247
|
-
}
|
|
248
|
-
function versionDigest(parts) {
|
|
249
|
-
return sha256Text(JSON.stringify(parts));
|
|
250
|
-
}
|
|
251
|
-
function evidenceIdFor(kind, versionId) {
|
|
252
|
-
return sha256Text(`${kind}:${versionId}`).slice(0, 16);
|
|
253
|
-
}
|
|
254
|
-
function normalizeAuthenticatedUserEvidence(user, observedAt) {
|
|
255
|
-
const login = user.login.toLowerCase();
|
|
256
|
-
const rawId = user.raw?.id;
|
|
257
|
-
const stableNumericOrStringId = typeof rawId === "number" || typeof rawId === "string" ? rawId : void 0;
|
|
258
|
-
const retainedRaw = { login };
|
|
259
|
-
if (stableNumericOrStringId !== void 0) {
|
|
260
|
-
retainedRaw.id = stableNumericOrStringId;
|
|
261
|
-
}
|
|
262
|
-
const contentDigest = versionDigest({
|
|
263
|
-
login,
|
|
264
|
-
...stableNumericOrStringId !== void 0 ? { id: stableNumericOrStringId } : {}
|
|
265
|
-
});
|
|
266
|
-
const versionId = `user:${login}:${contentDigest.slice(0, 12)}`;
|
|
267
|
-
return {
|
|
268
|
-
evidenceId: evidenceIdFor("authenticated_user", versionId),
|
|
269
|
-
kind: "authenticated_user",
|
|
270
|
-
stableGitHubId: stableId("user", login),
|
|
271
|
-
versionId,
|
|
272
|
-
contentDigest,
|
|
273
|
-
authorLogin: login,
|
|
274
|
-
firstObservedAt: observedAt,
|
|
275
|
-
raw: retainedRaw
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
function normalizePullRequestEvidence(pr, observedAt) {
|
|
279
|
-
const contentDigest = versionDigest({
|
|
280
|
-
number: pr.number,
|
|
281
|
-
state: pr.state,
|
|
282
|
-
headOid: pr.headOid,
|
|
283
|
-
createdAt: pr.createdAt ?? null,
|
|
284
|
-
updatedAt: pr.updatedAt ?? null,
|
|
285
|
-
htmlUrl: pr.url
|
|
286
|
-
});
|
|
287
|
-
const versionId = `pr:${pr.number}:${contentDigest.slice(0, 12)}`;
|
|
288
|
-
return {
|
|
289
|
-
evidenceId: evidenceIdFor("pull_request", versionId),
|
|
290
|
-
kind: "pull_request",
|
|
291
|
-
stableGitHubId: stableId("pr", pr.number),
|
|
292
|
-
versionId,
|
|
293
|
-
contentDigest,
|
|
294
|
-
state: pr.state,
|
|
295
|
-
commitOid: pr.headOid,
|
|
296
|
-
htmlUrl: pr.url,
|
|
297
|
-
// Version clock stays updatedAt. Create success for the wait window is snapshot.prCreatedAt only (#678).
|
|
298
|
-
authoritativeTime: pr.updatedAt ?? null,
|
|
299
|
-
firstObservedAt: observedAt,
|
|
300
|
-
raw: pr.raw
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
function normalizeReviewEvidence(review, observedAt) {
|
|
304
|
-
const authorLogin = review.userLogin === null || review.userLogin === void 0 ? void 0 : review.userLogin.toLowerCase();
|
|
305
|
-
const contentDigest = versionDigest({
|
|
306
|
-
id: review.id,
|
|
307
|
-
state: review.state,
|
|
308
|
-
body: review.body,
|
|
309
|
-
commitId: review.commitId,
|
|
310
|
-
submittedAt: review.submittedAt,
|
|
311
|
-
htmlUrl: review.htmlUrl,
|
|
312
|
-
userLogin: authorLogin ?? null,
|
|
313
|
-
machineIdentity: review.machineIdentity ?? null
|
|
314
|
-
});
|
|
315
|
-
const versionId = `review:${review.id}:${contentDigest.slice(0, 12)}`;
|
|
316
|
-
return {
|
|
317
|
-
evidenceId: evidenceIdFor("review", versionId),
|
|
318
|
-
kind: "review",
|
|
319
|
-
stableGitHubId: stableId("review", review.id),
|
|
320
|
-
githubId: review.id,
|
|
321
|
-
machineIdentity: review.machineIdentity ?? null,
|
|
322
|
-
versionId,
|
|
323
|
-
contentDigest,
|
|
324
|
-
...authorLogin === void 0 ? {} : { authorLogin },
|
|
325
|
-
state: review.state,
|
|
326
|
-
body: review.body,
|
|
327
|
-
commitOid: review.commitId,
|
|
328
|
-
htmlUrl: review.htmlUrl,
|
|
329
|
-
// Submission metadata only; ledger history assigns authoritativeTime.
|
|
330
|
-
submittedAt: review.submittedAt,
|
|
331
|
-
authoritativeTime: review.submittedAt,
|
|
332
|
-
firstObservedAt: observedAt,
|
|
333
|
-
raw: review.raw
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
function normalizePullRequestReactionEvidence(reaction, observedAt) {
|
|
337
|
-
const authorLogin = reaction.userLogin?.toLowerCase();
|
|
338
|
-
const contentDigest = versionDigest({
|
|
339
|
-
id: reaction.id,
|
|
340
|
-
content: reaction.content,
|
|
341
|
-
createdAt: reaction.createdAt,
|
|
342
|
-
machineIdentity: reaction.machineIdentity ?? null
|
|
343
|
-
});
|
|
344
|
-
const versionId = `reaction:${reaction.id}:${contentDigest.slice(0, 12)}`;
|
|
345
|
-
return {
|
|
346
|
-
evidenceId: evidenceIdFor("reaction", versionId),
|
|
347
|
-
kind: "reaction",
|
|
348
|
-
stableGitHubId: stableId("reaction", reaction.id),
|
|
349
|
-
githubId: reaction.id,
|
|
350
|
-
machineIdentity: reaction.machineIdentity ?? null,
|
|
351
|
-
versionId,
|
|
352
|
-
contentDigest,
|
|
353
|
-
...authorLogin === void 0 ? {} : { authorLogin },
|
|
354
|
-
body: reaction.content,
|
|
355
|
-
authoritativeTime: reaction.createdAt,
|
|
356
|
-
firstObservedAt: observedAt,
|
|
357
|
-
raw: reaction.raw
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
function normalizeIssueCommentEvidence(comment, observedAt) {
|
|
361
|
-
const authorLogin = comment.userLogin === null || comment.userLogin === void 0 ? void 0 : comment.userLogin.toLowerCase();
|
|
362
|
-
const contentDigest = versionDigest({
|
|
363
|
-
id: comment.id,
|
|
364
|
-
body: comment.body,
|
|
365
|
-
updatedAt: comment.updatedAt,
|
|
366
|
-
userLogin: authorLogin ?? null,
|
|
367
|
-
machineIdentity: comment.machineIdentity ?? null,
|
|
368
|
-
htmlUrl: comment.htmlUrl
|
|
369
|
-
});
|
|
370
|
-
const versionId = `issue_comment:${comment.id}:${contentDigest.slice(0, 12)}`;
|
|
371
|
-
return {
|
|
372
|
-
evidenceId: evidenceIdFor("issue_comment", versionId),
|
|
373
|
-
kind: "issue_comment",
|
|
374
|
-
stableGitHubId: stableId("issue_comment", comment.id),
|
|
375
|
-
githubId: comment.id,
|
|
376
|
-
machineIdentity: comment.machineIdentity ?? null,
|
|
377
|
-
versionId,
|
|
378
|
-
contentDigest,
|
|
379
|
-
...authorLogin === void 0 ? {} : { authorLogin },
|
|
380
|
-
body: comment.body,
|
|
381
|
-
htmlUrl: comment.htmlUrl,
|
|
382
|
-
authoritativeTime: comment.updatedAt ?? null,
|
|
383
|
-
firstObservedAt: observedAt,
|
|
384
|
-
raw: comment.raw
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
function normalizeReviewCommentEvidence(comment, observedAt) {
|
|
388
|
-
const authorLogin = comment.userLogin === null || comment.userLogin === void 0 ? void 0 : comment.userLogin.toLowerCase();
|
|
389
|
-
const contentDigest = versionDigest({
|
|
390
|
-
id: comment.id,
|
|
391
|
-
body: comment.body,
|
|
392
|
-
path: comment.path,
|
|
393
|
-
line: comment.line,
|
|
394
|
-
originalLine: comment.originalLine,
|
|
395
|
-
side: comment.side,
|
|
396
|
-
position: comment.position,
|
|
397
|
-
updatedAt: comment.updatedAt,
|
|
398
|
-
commitId: comment.commitId,
|
|
399
|
-
pullRequestReviewId: comment.pullRequestReviewId,
|
|
400
|
-
userLogin: authorLogin ?? null,
|
|
401
|
-
machineIdentity: comment.machineIdentity ?? null,
|
|
402
|
-
htmlUrl: comment.htmlUrl
|
|
403
|
-
});
|
|
404
|
-
const versionId = `review_comment:${comment.id}:${contentDigest.slice(0, 12)}`;
|
|
405
|
-
return {
|
|
406
|
-
evidenceId: evidenceIdFor("review_comment", versionId),
|
|
407
|
-
kind: "review_comment",
|
|
408
|
-
stableGitHubId: stableId("review_comment", comment.id),
|
|
409
|
-
githubId: comment.id,
|
|
410
|
-
machineIdentity: comment.machineIdentity ?? null,
|
|
411
|
-
versionId,
|
|
412
|
-
contentDigest,
|
|
413
|
-
...authorLogin === void 0 ? {} : { authorLogin },
|
|
414
|
-
body: comment.body,
|
|
415
|
-
commitOid: comment.commitId,
|
|
416
|
-
htmlUrl: comment.htmlUrl,
|
|
417
|
-
path: comment.path,
|
|
418
|
-
line: comment.line,
|
|
419
|
-
originalLine: comment.originalLine,
|
|
420
|
-
side: comment.side,
|
|
421
|
-
position: comment.position,
|
|
422
|
-
pullRequestReviewId: comment.pullRequestReviewId,
|
|
423
|
-
authoritativeTime: comment.updatedAt ?? null,
|
|
424
|
-
firstObservedAt: observedAt,
|
|
425
|
-
raw: comment.raw
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
function applyEvidenceVersionHistory(pending, priorEvidence, cutoff) {
|
|
429
|
-
const versionsByStable = /* @__PURE__ */ new Map();
|
|
430
|
-
const add = (stableIdValue, versionId) => {
|
|
431
|
-
let set = versionsByStable.get(stableIdValue);
|
|
432
|
-
if (set === void 0) {
|
|
433
|
-
set = /* @__PURE__ */ new Set();
|
|
434
|
-
versionsByStable.set(stableIdValue, set);
|
|
435
|
-
}
|
|
436
|
-
set.add(versionId);
|
|
437
|
-
};
|
|
438
|
-
for (const record4 of priorEvidence) {
|
|
439
|
-
if (record4.stableGitHubId !== void 0) {
|
|
440
|
-
add(record4.stableGitHubId, record4.versionId);
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
const priorByVersionId = /* @__PURE__ */ new Map();
|
|
444
|
-
for (const record4 of priorEvidence) {
|
|
445
|
-
priorByVersionId.set(record4.versionId, record4);
|
|
446
|
-
}
|
|
447
|
-
for (const record4 of pending) {
|
|
448
|
-
if (record4.stableGitHubId === void 0) continue;
|
|
449
|
-
const priorVersions = versionsByStable.get(record4.stableGitHubId) ?? /* @__PURE__ */ new Set();
|
|
450
|
-
const isNewVersion = !priorVersions.has(record4.versionId);
|
|
451
|
-
const hadEarlierDistinctVersion = [...priorVersions].some(
|
|
452
|
-
(versionId) => versionId !== record4.versionId
|
|
453
|
-
);
|
|
454
|
-
if (record4.kind === "review") {
|
|
455
|
-
if (!isNewVersion) {
|
|
456
|
-
const prior = priorByVersionId.get(record4.versionId);
|
|
457
|
-
if (prior !== void 0) {
|
|
458
|
-
record4.authoritativeTime = prior.authoritativeTime ?? null;
|
|
459
|
-
}
|
|
460
|
-
} else if (hadEarlierDistinctVersion) {
|
|
461
|
-
record4.authoritativeTime = null;
|
|
462
|
-
} else {
|
|
463
|
-
const { deadlineMono, firstObservedMono } = cutoff;
|
|
464
|
-
if (!Number.isFinite(deadlineMono) || !Number.isFinite(firstObservedMono) || firstObservedMono > deadlineMono) {
|
|
465
|
-
record4.authoritativeTime = null;
|
|
466
|
-
} else {
|
|
467
|
-
record4.authoritativeTime = record4.submittedAt ?? null;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
} else if (record4.kind === "issue_comment" || record4.kind === "review_comment") {
|
|
471
|
-
if (record4.authoritativeTime === void 0 || record4.authoritativeTime === "") {
|
|
472
|
-
record4.authoritativeTime = null;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
if (isNewVersion) {
|
|
476
|
-
add(record4.stableGitHubId, record4.versionId);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
function measureNormalizedBytes(records) {
|
|
481
|
-
return Buffer.byteLength(JSON.stringify(records), "utf8");
|
|
482
|
-
}
|
|
483
|
-
function assignWindowRelations(records, activationTime, deadlineTime) {
|
|
484
|
-
if (activationTime === void 0 || deadlineTime === void 0) return;
|
|
485
|
-
for (const record4 of records) {
|
|
486
|
-
if (record4.kind === "review" || record4.kind === "issue_comment" || record4.kind === "review_comment" || record4.kind === "pull_request") {
|
|
487
|
-
record4.windowRelation = computeWindowRelation(
|
|
488
|
-
record4.authoritativeTime,
|
|
489
|
-
activationTime,
|
|
490
|
-
deadlineTime
|
|
491
|
-
);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
var COLLECTOR_DEFAULT_WAIT_WINDOW_MS;
|
|
496
|
-
var init_collector_evidence = __esm({
|
|
497
|
-
"src/collector-evidence.ts"() {
|
|
498
|
-
"use strict";
|
|
499
|
-
COLLECTOR_DEFAULT_WAIT_WINDOW_MS = 10 * 60 * 1e3;
|
|
500
|
-
}
|
|
501
|
-
});
|
|
502
|
-
|
|
503
|
-
// src/collector-config.ts
|
|
504
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
505
|
-
import { readFile } from "node:fs/promises";
|
|
506
|
-
function fail(message, cause) {
|
|
507
|
-
throw new Error(message, cause === void 0 ? void 0 : { cause });
|
|
508
|
-
}
|
|
509
|
-
function conservativeAscii(input) {
|
|
510
|
-
for (let i = 0; i < input.length; i += 1) {
|
|
511
|
-
const code = input.charCodeAt(i);
|
|
512
|
-
if (code <= 31 || code === 127 || code > 127) return false;
|
|
513
|
-
}
|
|
514
|
-
return true;
|
|
515
|
-
}
|
|
516
|
-
function parseCollectorRepository(raw) {
|
|
517
|
-
if (typeof raw !== "string" || raw.trim() !== raw || raw.length === 0) fail("Collector repository must be a string owner/repo");
|
|
518
|
-
if (!conservativeAscii(raw) || raw.includes("://") || /[?#@%\\ ]/.test(raw)) fail("Collector repository rejects URL syntax and non-identity bytes");
|
|
519
|
-
const parts = raw.split("/");
|
|
520
|
-
if (parts.length !== 2) fail("Collector repository must contain exactly one '/' separating owner and repo");
|
|
521
|
-
const [ownerDisplay, repoDisplay] = parts;
|
|
522
|
-
if (!COLLECTOR_OWNER_PATTERN.test(ownerDisplay) || !COLLECTOR_REPO_PATTERN.test(repoDisplay)) fail("Collector repository does not match the conservative owner/repo grammar");
|
|
523
|
-
const owner = ownerDisplay.toLowerCase();
|
|
524
|
-
const repo = repoDisplay.toLowerCase();
|
|
525
|
-
return { display: raw, canonical: `${owner}/${repo}`, owner, repo };
|
|
526
|
-
}
|
|
527
|
-
function parseCollectorPrNumber(raw) {
|
|
528
|
-
if (typeof raw === "string" && !/^[1-9][0-9]*$/.test(raw)) fail("Collector pull request number must be a positive safe integer string");
|
|
529
|
-
if (typeof raw !== "string" && typeof raw !== "number") fail("Collector pull request number is required");
|
|
530
|
-
const value = Number(raw);
|
|
531
|
-
if (!Number.isSafeInteger(value) || value < 1) fail("Collector pull request number must be a positive safe integer");
|
|
532
|
-
return value;
|
|
533
|
-
}
|
|
534
|
-
function record(value) {
|
|
535
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
536
|
-
}
|
|
537
|
-
function canonicalManifest(requests) {
|
|
538
|
-
return `${JSON.stringify({ requests: requests.map((request) => ({ id: request.id, body: request.requestBody })) })}
|
|
539
|
-
`;
|
|
540
|
-
}
|
|
541
|
-
function emptyCollectorManifest() {
|
|
542
|
-
const canonicalJson2 = canonicalManifest([]);
|
|
543
|
-
return { requests: [], canonicalJson: canonicalJson2, digest: createHash2("sha256").update(canonicalJson2).digest("hex") };
|
|
544
|
-
}
|
|
545
|
-
async function loadCollectorManifest(path) {
|
|
546
|
-
let bytes;
|
|
547
|
-
try {
|
|
548
|
-
bytes = await readFile(path);
|
|
549
|
-
} catch (error) {
|
|
550
|
-
fail(`Collector request manifest is unreadable at ${path}`, error);
|
|
551
|
-
}
|
|
552
|
-
let parsed;
|
|
553
|
-
try {
|
|
554
|
-
parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
555
|
-
} catch (error) {
|
|
556
|
-
fail("Collector request manifest must be UTF-8 JSON", error);
|
|
557
|
-
}
|
|
558
|
-
if (!record(parsed)) fail("Collector request manifest must be an object");
|
|
559
|
-
const rawRequests = parsed.requests ?? [];
|
|
560
|
-
if (!Array.isArray(rawRequests)) fail("Collector request manifest requests must be an array");
|
|
561
|
-
const requests = [];
|
|
562
|
-
const ids = /* @__PURE__ */ new Set();
|
|
563
|
-
for (const [index, item] of rawRequests.entries()) {
|
|
564
|
-
if (!record(item) || typeof item.id !== "string" || item.id.length === 0 || typeof item.body !== "string" || item.body.trim() === "") fail(`Collector request manifest requests[${index}] is invalid`);
|
|
565
|
-
if (ids.has(item.id)) fail(`Collector request manifest has duplicate request id "${item.id}"`);
|
|
566
|
-
ids.add(item.id);
|
|
567
|
-
requests.push({ id: item.id, requestBody: item.body });
|
|
568
|
-
}
|
|
569
|
-
const canonicalJson2 = canonicalManifest(requests);
|
|
570
|
-
return { requests, canonicalJson: canonicalJson2, digest: createHash2("sha256").update(canonicalJson2).digest("hex"), sourcePath: path };
|
|
571
|
-
}
|
|
572
|
-
var COLLECTOR_OWNER_PATTERN, COLLECTOR_REPO_PATTERN;
|
|
573
|
-
var init_collector_config = __esm({
|
|
574
|
-
"src/collector-config.ts"() {
|
|
575
|
-
"use strict";
|
|
576
|
-
COLLECTOR_OWNER_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/;
|
|
577
|
-
COLLECTOR_REPO_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,98}[A-Za-z0-9])?$/;
|
|
578
|
-
}
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
// src/collector-github.ts
|
|
582
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
583
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
584
|
-
function isRecord(value) {
|
|
585
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
586
|
-
}
|
|
587
|
-
function requireString(value, label) {
|
|
588
|
-
if (typeof value !== "string") {
|
|
589
|
-
throw new Error(`GitHub payload missing string ${label}`);
|
|
590
|
-
}
|
|
591
|
-
return value;
|
|
592
|
-
}
|
|
593
|
-
function requireNumber(value, label) {
|
|
594
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
595
|
-
throw new Error(`GitHub payload missing number ${label}`);
|
|
596
|
-
}
|
|
597
|
-
return value;
|
|
598
|
-
}
|
|
599
|
-
function optionalString(value) {
|
|
600
|
-
return typeof value === "string" ? value : null;
|
|
601
|
-
}
|
|
602
|
-
function parseLinkNext(linkHeader) {
|
|
603
|
-
if (linkHeader === void 0 || linkHeader.length === 0) return void 0;
|
|
604
|
-
for (const part of linkHeader.split(",")) {
|
|
605
|
-
const match = part.trim().match(/^<([^>]+)>\s*;\s*rel="next"$/i);
|
|
606
|
-
if (match?.[1]) return match[1];
|
|
607
|
-
}
|
|
608
|
-
return void 0;
|
|
609
|
-
}
|
|
610
|
-
function parseJson(text, label) {
|
|
611
|
-
try {
|
|
612
|
-
return JSON.parse(text);
|
|
613
|
-
} catch (error) {
|
|
614
|
-
throw new Error(`GitHub ${label} returned malformed JSON`, { cause: error });
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
function parsePullRequestNumberList(raw, label) {
|
|
618
|
-
if (!Array.isArray(raw)) {
|
|
619
|
-
throw new Error(`GitHub ${label} payload is not a list`);
|
|
620
|
-
}
|
|
621
|
-
const numbers = [];
|
|
622
|
-
for (const item of raw) {
|
|
623
|
-
if (!isRecord(item)) {
|
|
624
|
-
throw new Error(`GitHub ${label} payload contains a non-object pull request entry`);
|
|
625
|
-
}
|
|
626
|
-
try {
|
|
627
|
-
numbers.push(parseCollectorPrNumber(item["number"]));
|
|
628
|
-
} catch (error) {
|
|
629
|
-
throw new Error(`GitHub ${label} payload contains an invalid pull request number`, {
|
|
630
|
-
cause: error
|
|
631
|
-
});
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
return numbers;
|
|
635
|
-
}
|
|
636
|
-
async function listPullRequestNumbersByHead(runner, input) {
|
|
637
|
-
const head = `${input.headOwner}:${input.headRef}`;
|
|
638
|
-
const path = `/repos/${input.owner}/${input.repo}/pulls?head=${encodeURIComponent(head)}&state=all&per_page=100`;
|
|
639
|
-
const response = await runner(
|
|
640
|
-
["api", "--hostname", "github.com", "--include", "-X", "GET", path],
|
|
641
|
-
input.signal === void 0 ? {} : { signal: input.signal }
|
|
642
|
-
);
|
|
643
|
-
if (response.status < 200 || response.status >= 300) {
|
|
644
|
-
throw new Error(`GitHub ${path} failed with HTTP ${response.status}`, {
|
|
645
|
-
cause: {
|
|
646
|
-
endpoint: path,
|
|
647
|
-
status: response.status,
|
|
648
|
-
headers: response.headers,
|
|
649
|
-
body: response.bodyText
|
|
650
|
-
}
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
return parsePullRequestNumberList(parseJson(response.bodyText, path), path);
|
|
654
|
-
}
|
|
655
|
-
async function listPullRequestNumbersByCommit(runner, input) {
|
|
656
|
-
const path = `/repos/${input.owner}/${input.repo}/commits/${encodeURIComponent(input.commitSha)}/pulls`;
|
|
657
|
-
const response = await runner(
|
|
658
|
-
["api", "--hostname", "github.com", "--include", "-X", "GET", path],
|
|
659
|
-
input.signal === void 0 ? {} : { signal: input.signal }
|
|
660
|
-
);
|
|
661
|
-
if (response.status < 200 || response.status >= 300) {
|
|
662
|
-
throw new Error(`GitHub ${path} failed with HTTP ${response.status}`, {
|
|
663
|
-
cause: {
|
|
664
|
-
endpoint: path,
|
|
665
|
-
status: response.status,
|
|
666
|
-
headers: response.headers,
|
|
667
|
-
body: response.bodyText
|
|
668
|
-
}
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
return parsePullRequestNumberList(parseJson(response.bodyText, path), path);
|
|
672
|
-
}
|
|
673
|
-
async function listPullRequestNumbersByTicket(runner, input) {
|
|
674
|
-
const issuePath = `/repos/${input.owner}/${input.repo}/issues/${input.ticketNumber}`;
|
|
675
|
-
const issueResponse = await runner(
|
|
676
|
-
["api", "--hostname", "github.com", "--include", "-X", "GET", issuePath],
|
|
677
|
-
input.signal === void 0 ? {} : { signal: input.signal }
|
|
678
|
-
);
|
|
679
|
-
if (issueResponse.status === 404) return [];
|
|
680
|
-
if (issueResponse.status < 200 || issueResponse.status >= 300) {
|
|
681
|
-
throw new Error(`GitHub ${issuePath} failed with HTTP ${issueResponse.status}`, {
|
|
682
|
-
cause: {
|
|
683
|
-
endpoint: issuePath,
|
|
684
|
-
status: issueResponse.status,
|
|
685
|
-
headers: issueResponse.headers,
|
|
686
|
-
body: issueResponse.bodyText
|
|
687
|
-
}
|
|
688
|
-
});
|
|
689
|
-
}
|
|
690
|
-
const issueRaw = parseJson(issueResponse.bodyText, issuePath);
|
|
691
|
-
if (!isRecord(issueRaw)) {
|
|
692
|
-
throw new Error(`GitHub ${issuePath} payload is not an object`);
|
|
693
|
-
}
|
|
694
|
-
if (Object.hasOwn(issueRaw, "pull_request")) {
|
|
695
|
-
return [parseCollectorPrNumber(issueRaw["number"] ?? input.ticketNumber)];
|
|
696
|
-
}
|
|
697
|
-
const query = `query($owner: String!, $repo: String!, $number: Int!) {
|
|
698
|
-
repository(owner: $owner, name: $repo) {
|
|
699
|
-
issue(number: $number) {
|
|
700
|
-
closedByPullRequestsReferences(first: 50) { nodes { number } }
|
|
701
|
-
timelineItems(first: 100, itemTypes: [CROSS_REFERENCED_EVENT, CONNECTED_EVENT]) {
|
|
702
|
-
nodes {
|
|
703
|
-
__typename
|
|
704
|
-
... on CrossReferencedEvent {
|
|
705
|
-
source { ... on PullRequest { number } }
|
|
706
|
-
}
|
|
707
|
-
... on ConnectedEvent {
|
|
708
|
-
subject { ... on PullRequest { number } }
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
}`;
|
|
715
|
-
const args = [
|
|
716
|
-
"api",
|
|
717
|
-
"graphql",
|
|
718
|
-
"--hostname",
|
|
719
|
-
"github.com",
|
|
720
|
-
"--include",
|
|
721
|
-
"-f",
|
|
722
|
-
`query=${query}`,
|
|
723
|
-
"-f",
|
|
724
|
-
`owner=${input.owner}`,
|
|
725
|
-
"-f",
|
|
726
|
-
`repo=${input.repo}`,
|
|
727
|
-
"-F",
|
|
728
|
-
`number=${input.ticketNumber}`
|
|
729
|
-
];
|
|
730
|
-
const gqlResponse = await runner(
|
|
731
|
-
args,
|
|
732
|
-
input.signal === void 0 ? {} : { signal: input.signal }
|
|
733
|
-
);
|
|
734
|
-
if (gqlResponse.status < 200 || gqlResponse.status >= 300) {
|
|
735
|
-
throw new Error(`GitHub GraphQL issue\u2192PR failed with HTTP ${gqlResponse.status}`, {
|
|
736
|
-
cause: {
|
|
737
|
-
endpoint: "graphql",
|
|
738
|
-
status: gqlResponse.status,
|
|
739
|
-
headers: gqlResponse.headers,
|
|
740
|
-
body: gqlResponse.bodyText
|
|
741
|
-
}
|
|
742
|
-
});
|
|
743
|
-
}
|
|
744
|
-
let payload;
|
|
745
|
-
try {
|
|
746
|
-
payload = JSON.parse(gqlResponse.bodyText);
|
|
747
|
-
} catch (error) {
|
|
748
|
-
throw new Error("GitHub GraphQL issue\u2192PR returned malformed JSON", { cause: error });
|
|
749
|
-
}
|
|
750
|
-
if (!isRecord(payload)) {
|
|
751
|
-
throw new Error("GitHub GraphQL issue\u2192PR payload is not an object");
|
|
752
|
-
}
|
|
753
|
-
if (payload.errors !== void 0) {
|
|
754
|
-
throw new Error(`GitHub GraphQL issue\u2192PR errors: ${JSON.stringify(payload.errors).slice(0, 600)}`, {
|
|
755
|
-
cause: { body: gqlResponse.bodyText, errors: payload.errors }
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
const data = payload.data;
|
|
759
|
-
if (!isRecord(data)) return [];
|
|
760
|
-
const repository = data["repository"];
|
|
761
|
-
if (!isRecord(repository)) return [];
|
|
762
|
-
const issue = repository["issue"];
|
|
763
|
-
if (!isRecord(issue)) return [];
|
|
764
|
-
const numbers = [];
|
|
765
|
-
const closedBy = issue["closedByPullRequestsReferences"];
|
|
766
|
-
if (isRecord(closedBy) && Array.isArray(closedBy["nodes"])) {
|
|
767
|
-
for (const node of closedBy["nodes"]) {
|
|
768
|
-
if (isRecord(node) && typeof node["number"] === "number") {
|
|
769
|
-
numbers.push(parseCollectorPrNumber(node["number"]));
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
const timeline = issue["timelineItems"];
|
|
774
|
-
if (isRecord(timeline) && Array.isArray(timeline["nodes"])) {
|
|
775
|
-
for (const node of timeline["nodes"]) {
|
|
776
|
-
if (!isRecord(node)) continue;
|
|
777
|
-
const source = node["source"];
|
|
778
|
-
if (isRecord(source) && typeof source["number"] === "number") {
|
|
779
|
-
numbers.push(parseCollectorPrNumber(source["number"]));
|
|
780
|
-
}
|
|
781
|
-
const subject = node["subject"];
|
|
782
|
-
if (isRecord(subject) && typeof subject["number"] === "number") {
|
|
783
|
-
numbers.push(parseCollectorPrNumber(subject["number"]));
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
return [...new Set(numbers)];
|
|
788
|
-
}
|
|
789
|
-
function commentFailureCause(error) {
|
|
790
|
-
return {
|
|
791
|
-
name: error instanceof Error ? error.name : typeof error,
|
|
792
|
-
message: error instanceof Error ? error.message : String(error),
|
|
793
|
-
evidenceId: `github-comment-failure-${++commentFailureEvidence}`
|
|
794
|
-
};
|
|
795
|
-
}
|
|
796
|
-
function requireUserLogin(raw) {
|
|
797
|
-
if (!isRecord(raw) || typeof raw["login"] !== "string") {
|
|
798
|
-
throw new Error("GitHub payload missing user.login");
|
|
799
|
-
}
|
|
800
|
-
return raw["login"];
|
|
801
|
-
}
|
|
802
|
-
function optionalUserLogin(raw) {
|
|
803
|
-
if (raw === null) return null;
|
|
804
|
-
if (!isRecord(raw) || typeof raw["login"] !== "string") {
|
|
805
|
-
throw new Error("GitHub payload missing user.login");
|
|
806
|
-
}
|
|
807
|
-
return raw["login"];
|
|
808
|
-
}
|
|
809
|
-
function machineIdentity(raw) {
|
|
810
|
-
const user = raw["user"];
|
|
811
|
-
if (!isRecord(user) || typeof user["type"] !== "string" || typeof user["id"] !== "number") {
|
|
812
|
-
return null;
|
|
813
|
-
}
|
|
814
|
-
const app = raw["performed_via_github_app"];
|
|
815
|
-
const appId = isRecord(app) && typeof app["id"] === "number" ? app["id"] : void 0;
|
|
816
|
-
return {
|
|
817
|
-
userType: user["type"],
|
|
818
|
-
userId: user["id"],
|
|
819
|
-
...appId === void 0 ? {} : { appId }
|
|
820
|
-
};
|
|
821
|
-
}
|
|
822
|
-
function normalizePullRequest(raw) {
|
|
823
|
-
if (!isRecord(raw)) throw new Error("GitHub pull request payload must be an object");
|
|
824
|
-
const head = raw["head"];
|
|
825
|
-
if (!isRecord(head) || typeof head["sha"] !== "string" || head["sha"].length === 0) {
|
|
826
|
-
throw new Error("GitHub pull request payload missing head.sha");
|
|
827
|
-
}
|
|
828
|
-
const number = requireNumber(raw["number"], "number");
|
|
829
|
-
const mergedFlag = raw["merged"] === true || typeof raw["merged_at"] === "string" && raw["merged_at"].length > 0;
|
|
830
|
-
const rawState = requireString(raw["state"], "state").toUpperCase();
|
|
831
|
-
const state = mergedFlag ? "MERGED" : rawState;
|
|
832
|
-
const htmlUrl = typeof raw["html_url"] === "string" ? raw["html_url"] : `https://github.com/unknown/unknown/pull/${number}`;
|
|
833
|
-
return {
|
|
834
|
-
number,
|
|
835
|
-
state,
|
|
836
|
-
headOid: head["sha"],
|
|
837
|
-
...typeof raw["created_at"] === "string" ? { createdAt: raw["created_at"] } : {},
|
|
838
|
-
...typeof raw["updated_at"] === "string" ? { updatedAt: raw["updated_at"] } : {},
|
|
839
|
-
url: htmlUrl,
|
|
840
|
-
raw
|
|
841
|
-
};
|
|
842
|
-
}
|
|
843
|
-
function normalizePullRequestReaction(raw) {
|
|
844
|
-
if (!isRecord(raw)) throw new Error("GitHub reaction payload must be an object");
|
|
845
|
-
return {
|
|
846
|
-
id: requireNumber(raw["id"], "reaction.id"),
|
|
847
|
-
userLogin: optionalUserLogin(raw["user"]),
|
|
848
|
-
machineIdentity: machineIdentity(raw),
|
|
849
|
-
content: requireString(raw["content"], "reaction.content"),
|
|
850
|
-
createdAt: requireString(raw["created_at"], "reaction.created_at"),
|
|
851
|
-
raw
|
|
852
|
-
};
|
|
853
|
-
}
|
|
854
|
-
function normalizeReview(raw) {
|
|
855
|
-
if (!isRecord(raw)) throw new Error("GitHub review payload must be an object");
|
|
856
|
-
return {
|
|
857
|
-
id: requireNumber(raw["id"], "review.id"),
|
|
858
|
-
...typeof raw["node_id"] === "string" ? { nodeId: raw["node_id"] } : {},
|
|
859
|
-
userLogin: optionalUserLogin(raw["user"]),
|
|
860
|
-
machineIdentity: machineIdentity(raw),
|
|
861
|
-
state: requireString(raw["state"], "review.state").toUpperCase(),
|
|
862
|
-
body: typeof raw["body"] === "string" ? raw["body"] : "",
|
|
863
|
-
commitId: optionalString(raw["commit_id"]),
|
|
864
|
-
submittedAt: optionalString(raw["submitted_at"]),
|
|
865
|
-
htmlUrl: typeof raw["html_url"] === "string" ? raw["html_url"] : "",
|
|
866
|
-
raw
|
|
867
|
-
};
|
|
868
|
-
}
|
|
869
|
-
function normalizeIssueComment(raw) {
|
|
870
|
-
if (!isRecord(raw)) throw new Error("GitHub issue comment payload must be an object");
|
|
871
|
-
return {
|
|
872
|
-
id: requireNumber(raw["id"], "comment.id"),
|
|
873
|
-
userLogin: optionalUserLogin(raw["user"]),
|
|
874
|
-
machineIdentity: machineIdentity(raw),
|
|
875
|
-
body: typeof raw["body"] === "string" ? raw["body"] : "",
|
|
876
|
-
createdAt: requireString(raw["created_at"], "comment.created_at"),
|
|
877
|
-
updatedAt: requireString(raw["updated_at"], "comment.updated_at"),
|
|
878
|
-
htmlUrl: typeof raw["html_url"] === "string" ? raw["html_url"] : "",
|
|
879
|
-
raw
|
|
880
|
-
};
|
|
881
|
-
}
|
|
882
|
-
function normalizeReviewComment(raw) {
|
|
883
|
-
if (!isRecord(raw)) throw new Error("GitHub review comment payload must be an object");
|
|
884
|
-
return {
|
|
885
|
-
id: requireNumber(raw["id"], "review_comment.id"),
|
|
886
|
-
pullRequestReviewId: typeof raw["pull_request_review_id"] === "number" ? raw["pull_request_review_id"] : null,
|
|
887
|
-
userLogin: optionalUserLogin(raw["user"]),
|
|
888
|
-
machineIdentity: machineIdentity(raw),
|
|
889
|
-
body: typeof raw["body"] === "string" ? raw["body"] : "",
|
|
890
|
-
path: requireString(raw["path"], "review_comment.path"),
|
|
891
|
-
line: typeof raw["line"] === "number" ? raw["line"] : null,
|
|
892
|
-
originalLine: typeof raw["original_line"] === "number" ? raw["original_line"] : null,
|
|
893
|
-
side: optionalString(raw["side"]),
|
|
894
|
-
position: typeof raw["position"] === "number" ? raw["position"] : null,
|
|
895
|
-
originalPosition: typeof raw["original_position"] === "number" ? raw["original_position"] : null,
|
|
896
|
-
commitId: optionalString(raw["commit_id"]),
|
|
897
|
-
originalCommitId: optionalString(raw["original_commit_id"]),
|
|
898
|
-
createdAt: requireString(raw["created_at"], "review_comment.created_at"),
|
|
899
|
-
updatedAt: requireString(raw["updated_at"], "review_comment.updated_at"),
|
|
900
|
-
htmlUrl: typeof raw["html_url"] === "string" ? raw["html_url"] : "",
|
|
901
|
-
raw
|
|
902
|
-
};
|
|
903
|
-
}
|
|
904
|
-
function createGhApiRunner(options = {}) {
|
|
905
|
-
const spawnImpl = options.spawnImpl ?? spawn2;
|
|
906
|
-
return async (args, runOptions = {}) => {
|
|
907
|
-
return await new Promise((resolve22, reject) => {
|
|
908
|
-
const signal = runOptions.signal;
|
|
909
|
-
if (signal?.aborted) {
|
|
910
|
-
reject(signal.reason ?? new Error("aborted"));
|
|
911
|
-
return;
|
|
912
|
-
}
|
|
913
|
-
const child = spawnImpl("gh", args, {
|
|
914
|
-
env: options.env ?? process.env,
|
|
915
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
916
|
-
});
|
|
917
|
-
let stdout = "";
|
|
918
|
-
let stderr = "";
|
|
919
|
-
let settled = false;
|
|
920
|
-
const settle = (fn) => {
|
|
921
|
-
if (settled) return;
|
|
922
|
-
settled = true;
|
|
923
|
-
if (signal !== void 0) {
|
|
924
|
-
signal.removeEventListener("abort", onAbort);
|
|
925
|
-
}
|
|
926
|
-
fn();
|
|
927
|
-
};
|
|
928
|
-
const onAbort = () => {
|
|
929
|
-
try {
|
|
930
|
-
child.kill("SIGTERM");
|
|
931
|
-
} catch (error) {
|
|
932
|
-
settle(() => reject(error));
|
|
933
|
-
return;
|
|
934
|
-
}
|
|
935
|
-
settle(() => {
|
|
936
|
-
reject(signal?.reason ?? new Error("aborted"));
|
|
937
|
-
});
|
|
938
|
-
};
|
|
939
|
-
if (signal !== void 0) {
|
|
940
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
941
|
-
}
|
|
942
|
-
child.stdout.setEncoding("utf8").on("data", (chunk) => {
|
|
943
|
-
stdout += chunk;
|
|
944
|
-
});
|
|
945
|
-
child.stderr.setEncoding("utf8").on("data", (chunk) => {
|
|
946
|
-
stderr += chunk;
|
|
947
|
-
});
|
|
948
|
-
child.on("error", (error) => {
|
|
949
|
-
settle(() => reject(error));
|
|
950
|
-
});
|
|
951
|
-
child.stdin.on("error", (error) => {
|
|
952
|
-
settle(() => {
|
|
953
|
-
if (signal?.aborted) {
|
|
954
|
-
reject(signal.reason ?? new Error("aborted"));
|
|
955
|
-
return;
|
|
956
|
-
}
|
|
957
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
958
|
-
reject(Object.assign(err, { ambiguousGhFailure: true }));
|
|
959
|
-
});
|
|
960
|
-
});
|
|
961
|
-
if (runOptions.stdin !== void 0) {
|
|
962
|
-
child.stdin.write(runOptions.stdin);
|
|
963
|
-
}
|
|
964
|
-
child.stdin.end();
|
|
965
|
-
child.on("close", (code, signal2) => {
|
|
966
|
-
settle(() => {
|
|
967
|
-
const match = stdout.match(/^HTTP\/[\d.]+\s+(\d+)[^\n]*\r?\n([\s\S]*?)\r?\n\r?\n([\s\S]*)$/);
|
|
968
|
-
if (match) {
|
|
969
|
-
const status = Number(match[1]);
|
|
970
|
-
const headerText = match[2] ?? "";
|
|
971
|
-
const bodyText = match[3] ?? "";
|
|
972
|
-
const headers = {};
|
|
973
|
-
for (const line2 of headerText.split(/\r?\n/)) {
|
|
974
|
-
const idx = line2.indexOf(":");
|
|
975
|
-
if (idx === -1) continue;
|
|
976
|
-
const name = line2.slice(0, idx).trim().toLowerCase();
|
|
977
|
-
const value = line2.slice(idx + 1).trim();
|
|
978
|
-
headers[name] = value;
|
|
979
|
-
}
|
|
980
|
-
resolve22({ status, headers, bodyText });
|
|
981
|
-
return;
|
|
982
|
-
}
|
|
983
|
-
if (code === 0) {
|
|
984
|
-
resolve22({ status: 200, headers: {}, bodyText: stdout });
|
|
985
|
-
return;
|
|
986
|
-
}
|
|
987
|
-
const failure2 = new Error(
|
|
988
|
-
`gh api failed without a parseable HTTP response (code=${String(code)}): ${stderr || stdout}`,
|
|
989
|
-
{ cause: { code, signal: signal2, stderr, stdout } }
|
|
990
|
-
);
|
|
991
|
-
reject(Object.assign(failure2, { ambiguousGhFailure: true, stderr, stdout, code, signal: signal2 }));
|
|
992
|
-
});
|
|
993
|
-
});
|
|
994
|
-
});
|
|
995
|
-
};
|
|
996
|
-
}
|
|
997
|
-
function createGhCollectorGitHubTransport(runner = createGhApiRunner()) {
|
|
998
|
-
const hostnameArgs = ["api", "--hostname", "github.com", "--include"];
|
|
999
|
-
async function apiGet(path, signal) {
|
|
1000
|
-
return await runner(
|
|
1001
|
-
[...hostnameArgs, "-X", "GET", path],
|
|
1002
|
-
signal === void 0 ? {} : { signal }
|
|
1003
|
-
);
|
|
1004
|
-
}
|
|
1005
|
-
async function paginate(path, mapItem, options = {}) {
|
|
1006
|
-
const { signal, retainPage } = options;
|
|
1007
|
-
const items = [];
|
|
1008
|
-
const pages = [];
|
|
1009
|
-
let nextPath = path;
|
|
1010
|
-
let page = 1;
|
|
1011
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1012
|
-
while (nextPath !== void 0) {
|
|
1013
|
-
if (signal?.aborted) {
|
|
1014
|
-
throw signal.reason ?? new Error("aborted");
|
|
1015
|
-
}
|
|
1016
|
-
if (seen.has(nextPath)) {
|
|
1017
|
-
throw new Error(`GitHub pagination repeated page: ${nextPath}`);
|
|
1018
|
-
}
|
|
1019
|
-
seen.add(nextPath);
|
|
1020
|
-
const response = await apiGet(nextPath, signal);
|
|
1021
|
-
const diagnostics = {
|
|
1022
|
-
path: nextPath,
|
|
1023
|
-
page,
|
|
1024
|
-
status: response.status,
|
|
1025
|
-
itemCount: 0,
|
|
1026
|
-
...response.headers["link"] === void 0 ? {} : { linkHeader: response.headers["link"] }
|
|
1027
|
-
};
|
|
1028
|
-
if (response.status === 429) {
|
|
1029
|
-
throw Object.assign(
|
|
1030
|
-
new Error(`GitHub API rate limited on ${nextPath} (HTTP 429)`),
|
|
1031
|
-
{ githubStatus: 429, page: diagnostics }
|
|
1032
|
-
);
|
|
1033
|
-
}
|
|
1034
|
-
if (response.status < 200 || response.status >= 300) {
|
|
1035
|
-
throw Object.assign(
|
|
1036
|
-
new Error(`GitHub API ${nextPath} failed with HTTP ${response.status}`),
|
|
1037
|
-
{ githubStatus: response.status, page: diagnostics }
|
|
1038
|
-
);
|
|
1039
|
-
}
|
|
1040
|
-
const parsed = parseJson(response.bodyText, nextPath);
|
|
1041
|
-
if (!Array.isArray(parsed)) {
|
|
1042
|
-
throw new Error(`GitHub API ${nextPath} did not return a JSON array`);
|
|
1043
|
-
}
|
|
1044
|
-
diagnostics.itemCount = parsed.length;
|
|
1045
|
-
pages.push(diagnostics);
|
|
1046
|
-
const pageItems = parsed.map((entry) => mapItem(entry));
|
|
1047
|
-
retainPage?.(pageItems);
|
|
1048
|
-
for (const item of pageItems) items.push(item);
|
|
1049
|
-
const nextUrl = parseLinkNext(response.headers["link"]);
|
|
1050
|
-
if (nextUrl === void 0) {
|
|
1051
|
-
nextPath = void 0;
|
|
1052
|
-
} else {
|
|
1053
|
-
if (nextUrl.startsWith("/")) {
|
|
1054
|
-
nextPath = nextUrl;
|
|
1055
|
-
} else {
|
|
1056
|
-
const url = new URL(nextUrl);
|
|
1057
|
-
if (url.hostname !== "api.github.com" && url.hostname !== "github.com") {
|
|
1058
|
-
throw new Error(`unexpected pagination host ${url.hostname}`);
|
|
1059
|
-
}
|
|
1060
|
-
nextPath = `${url.pathname}${url.search}`;
|
|
1061
|
-
if (nextPath.startsWith("/api/v3/")) {
|
|
1062
|
-
nextPath = nextPath.slice("/api/v3".length);
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
page += 1;
|
|
1067
|
-
}
|
|
1068
|
-
return { items, pages };
|
|
1069
|
-
}
|
|
1070
|
-
return {
|
|
1071
|
-
async getAuthenticatedUser(options = {}) {
|
|
1072
|
-
const response = await apiGet("/user", options.signal);
|
|
1073
|
-
if (response.status < 200 || response.status >= 300) {
|
|
1074
|
-
throw new Error(`GitHub /user failed with HTTP ${response.status}`, { cause: { endpoint: "/user", status: response.status, headers: response.headers, body: response.bodyText } });
|
|
1075
|
-
}
|
|
1076
|
-
const raw = parseJson(response.bodyText, "/user");
|
|
1077
|
-
return { login: requireUserLogin(raw).toLowerCase(), raw };
|
|
1078
|
-
},
|
|
1079
|
-
async getPullRequest(input) {
|
|
1080
|
-
const path = `/repos/${input.owner}/${input.repo}/pulls/${input.prNumber}`;
|
|
1081
|
-
const response = await apiGet(path, input.signal);
|
|
1082
|
-
if (response.status < 200 || response.status >= 300) {
|
|
1083
|
-
throw new Error(`GitHub ${path} failed with HTTP ${response.status}`, { cause: { endpoint: path, status: response.status, headers: response.headers, body: response.bodyText } });
|
|
1084
|
-
}
|
|
1085
|
-
return normalizePullRequest(parseJson(response.bodyText, path));
|
|
1086
|
-
},
|
|
1087
|
-
async listPullRequestReviews(input) {
|
|
1088
|
-
const path = `/repos/${input.owner}/${input.repo}/pulls/${input.prNumber}/reviews?per_page=100`;
|
|
1089
|
-
return await paginate(path, normalizeReview, {
|
|
1090
|
-
...input.signal === void 0 ? {} : { signal: input.signal },
|
|
1091
|
-
...input.retainPage === void 0 ? {} : { retainPage: input.retainPage }
|
|
1092
|
-
});
|
|
1093
|
-
},
|
|
1094
|
-
async listPullRequestReactions(input) {
|
|
1095
|
-
const path = `/repos/${input.owner}/${input.repo}/issues/${input.prNumber}/reactions?per_page=100`;
|
|
1096
|
-
return await paginate(path, normalizePullRequestReaction, {
|
|
1097
|
-
...input.signal === void 0 ? {} : { signal: input.signal },
|
|
1098
|
-
...input.retainPage === void 0 ? {} : { retainPage: input.retainPage }
|
|
1099
|
-
});
|
|
1100
|
-
},
|
|
1101
|
-
async listIssueComments(input) {
|
|
1102
|
-
const path = `/repos/${input.owner}/${input.repo}/issues/${input.prNumber}/comments?per_page=100`;
|
|
1103
|
-
return await paginate(path, normalizeIssueComment, {
|
|
1104
|
-
...input.signal === void 0 ? {} : { signal: input.signal },
|
|
1105
|
-
...input.retainPage === void 0 ? {} : { retainPage: input.retainPage }
|
|
1106
|
-
});
|
|
1107
|
-
},
|
|
1108
|
-
async listReviewComments(input) {
|
|
1109
|
-
const path = `/repos/${input.owner}/${input.repo}/pulls/${input.prNumber}/comments?per_page=100`;
|
|
1110
|
-
return await paginate(path, normalizeReviewComment, {
|
|
1111
|
-
...input.signal === void 0 ? {} : { signal: input.signal },
|
|
1112
|
-
...input.retainPage === void 0 ? {} : { retainPage: input.retainPage }
|
|
1113
|
-
});
|
|
1114
|
-
},
|
|
1115
|
-
async createIssueComment(input) {
|
|
1116
|
-
const path = `/repos/${input.owner}/${input.repo}/issues/${input.prNumber}/comments`;
|
|
1117
|
-
try {
|
|
1118
|
-
const response = await runner(
|
|
1119
|
-
[...hostnameArgs, "-X", "POST", path, "--input", "-"],
|
|
1120
|
-
input.signal === void 0 ? { stdin: JSON.stringify({ body: input.body }) } : { stdin: JSON.stringify({ body: input.body }), signal: input.signal }
|
|
1121
|
-
);
|
|
1122
|
-
if (response.status >= 200 && response.status < 300) {
|
|
1123
|
-
try {
|
|
1124
|
-
return {
|
|
1125
|
-
kind: "success",
|
|
1126
|
-
comment: normalizeIssueComment(parseJson(response.bodyText, path))
|
|
1127
|
-
};
|
|
1128
|
-
} catch (error) {
|
|
1129
|
-
const cause = commentFailureCause(error);
|
|
1130
|
-
return { kind: "ambiguous_loss", diagnostics: cause.message, cause };
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
return {
|
|
1134
|
-
kind: "rejected",
|
|
1135
|
-
status: response.status,
|
|
1136
|
-
diagnostics: `HTTP ${response.status}: ${response.bodyText.slice(0, 500)}`
|
|
1137
|
-
};
|
|
1138
|
-
} catch (error) {
|
|
1139
|
-
if (input.signal?.aborted) {
|
|
1140
|
-
throw error;
|
|
1141
|
-
}
|
|
1142
|
-
if (isRecord(error) && error["ambiguousGhFailure"] === true) {
|
|
1143
|
-
const cause = commentFailureCause(error);
|
|
1144
|
-
return { kind: "ambiguous_loss", diagnostics: cause.message, cause };
|
|
1145
|
-
}
|
|
1146
|
-
if (isRecord(error) && error["name"] === "AbortError") {
|
|
1147
|
-
throw error;
|
|
1148
|
-
}
|
|
1149
|
-
throw error;
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
};
|
|
1153
|
-
}
|
|
1154
|
-
function buildCollectorRequestMarker(input) {
|
|
1155
|
-
const prefix = input.manifestDigest.slice(0, 12);
|
|
1156
|
-
const requestMarkerId = createHash3("sha256").update(input.requestId).digest("hex");
|
|
1157
|
-
return `<!-- ak-collector:v1 manifest=${prefix} request=${requestMarkerId} head=${input.headOid} -->`;
|
|
1158
|
-
}
|
|
1159
|
-
function buildCollectorRequestBody(input) {
|
|
1160
|
-
const marker = buildCollectorRequestMarker(input);
|
|
1161
|
-
const body = input.configuredBody.endsWith("\n") ? `${input.configuredBody}${marker}
|
|
1162
|
-
` : `${input.configuredBody}
|
|
1163
|
-
${marker}
|
|
1164
|
-
`;
|
|
1165
|
-
return { body, marker };
|
|
1166
|
-
}
|
|
1167
|
-
var commentFailureEvidence;
|
|
1168
|
-
var init_collector_github = __esm({
|
|
1169
|
-
"src/collector-github.ts"() {
|
|
1170
|
-
"use strict";
|
|
1171
|
-
init_collector_config();
|
|
1172
|
-
commentFailureEvidence = 0;
|
|
1173
|
-
}
|
|
1174
|
-
});
|
|
1175
|
-
|
|
1176
|
-
// src/readable-gate-item.ts
|
|
1177
|
-
var readable_gate_item_exports = {};
|
|
1178
|
-
__export(readable_gate_item_exports, {
|
|
1179
|
-
joinReadableGateItems: () => joinReadableGateItems,
|
|
1180
|
-
readableGateItem: () => readableGateItem
|
|
1181
|
-
});
|
|
1182
|
-
function readableGateItem(value) {
|
|
1183
|
-
return typeof value === "string" ? value : JSON.stringify(value);
|
|
1184
|
-
}
|
|
1185
|
-
function joinReadableGateItems(items, separator = "; ") {
|
|
1186
|
-
return items.map(readableGateItem).join(separator);
|
|
1187
|
-
}
|
|
1188
|
-
var init_readable_gate_item = __esm({
|
|
1189
|
-
"src/readable-gate-item.ts"() {
|
|
1190
|
-
"use strict";
|
|
1191
|
-
}
|
|
1192
|
-
});
|
|
1193
|
-
|
|
1194
|
-
// src/submission-errors.ts
|
|
1195
|
-
function serializeReceipt(receipt) {
|
|
1196
|
-
return readableGateItem(receipt);
|
|
1197
|
-
}
|
|
1198
|
-
function gatekeeperNonPassMessage(result) {
|
|
1199
|
-
if (result.status === "continue") {
|
|
1200
|
-
return serializeReceipt(result.receipt);
|
|
1201
|
-
}
|
|
1202
|
-
if (result.status === "transport_failure") {
|
|
1203
|
-
const head = `\u95E8\u4E0B\u7701 ${result.status}\uFF08${result.stage}\uFF09\uFF1A${result.reason}`;
|
|
1204
|
-
return result.submission === void 0 ? head : `${head}
|
|
1205
|
-
${serializeReceipt(result.submission)}`;
|
|
1206
|
-
}
|
|
1207
|
-
return `\u95E8\u4E0B\u7701 ${result.status}\uFF08${result.stage}\uFF09\uFF1A${result.reason}`;
|
|
1208
|
-
}
|
|
1209
|
-
function unreadableDiscriminatorNotice(field, received) {
|
|
1210
|
-
if (received === void 0) return `\u8BFB\u4E0D\u51FA ${field}`;
|
|
1211
|
-
return `\u8BFB\u4E0D\u51FA ${field}\uFF1A${readableGateItem(received)}`;
|
|
1212
|
-
}
|
|
1213
|
-
function receivedDiscriminator(receipt, field) {
|
|
1214
|
-
if (receipt === null || typeof receipt !== "object" || Array.isArray(receipt)) return void 0;
|
|
1215
|
-
if (!Object.hasOwn(receipt, field)) return void 0;
|
|
1216
|
-
return receipt[field];
|
|
1217
|
-
}
|
|
1218
|
-
var GatekeeperDecisionError, WorkerCommitReminderError, WorkerPrefixReminderError, WorkerUnfinishedReasonReminderError, ParentQueueReaskError;
|
|
1219
|
-
var init_submission_errors = __esm({
|
|
1220
|
-
"src/submission-errors.ts"() {
|
|
1221
|
-
"use strict";
|
|
1222
|
-
init_readable_gate_item();
|
|
1223
|
-
GatekeeperDecisionError = class extends Error {
|
|
1224
|
-
result;
|
|
1225
|
-
constructor(result, message) {
|
|
1226
|
-
super(message ?? gatekeeperNonPassMessage(result));
|
|
1227
|
-
this.name = "GatekeeperDecisionError";
|
|
1228
|
-
this.result = result;
|
|
1229
|
-
}
|
|
1230
|
-
};
|
|
1231
|
-
WorkerCommitReminderError = class extends Error {
|
|
1232
|
-
code = "worker_commit_reminder";
|
|
1233
|
-
constructor() {
|
|
1234
|
-
super("\u672A\u89C2\u5BDF\u5230 commit");
|
|
1235
|
-
this.name = "WorkerCommitReminderError";
|
|
1236
|
-
}
|
|
1237
|
-
};
|
|
1238
|
-
WorkerPrefixReminderError = class extends Error {
|
|
1239
|
-
code = "worker_prefix_reminder";
|
|
1240
|
-
constructor() {
|
|
1241
|
-
super("\u89C2\u5BDF\u5230\u7F3A\u524D\u7F00 commit");
|
|
1242
|
-
this.name = "WorkerPrefixReminderError";
|
|
1243
|
-
}
|
|
1244
|
-
};
|
|
1245
|
-
WorkerUnfinishedReasonReminderError = class extends Error {
|
|
1246
|
-
code = "worker_unfinished_reason_reminder";
|
|
1247
|
-
constructor() {
|
|
1248
|
-
super("\u672C\u6B21 unfinished \u56DE\u6267\u672A\u542B reason\uFF1B\u672C\u63A5\u7F1D\u7F3A\u7531\u81F3\u591A\u6253\u56DE\u4E24\u6B21\u3002");
|
|
1249
|
-
this.name = "WorkerUnfinishedReasonReminderError";
|
|
1250
|
-
}
|
|
1251
|
-
};
|
|
1252
|
-
ParentQueueReaskError = class extends Error {
|
|
1253
|
-
code = "parent_queue_reask";
|
|
1254
|
-
constructor(message) {
|
|
1255
|
-
super(message);
|
|
1256
|
-
this.name = "ParentQueueReaskError";
|
|
1257
|
-
}
|
|
1258
|
-
};
|
|
1259
|
-
}
|
|
1260
|
-
});
|
|
1261
|
-
|
|
1262
|
-
// src/submission-correctable-error.ts
|
|
1263
|
-
function isCorrectableSubmissionError(error) {
|
|
1264
|
-
return error instanceof CorrectableSubmissionError;
|
|
1265
|
-
}
|
|
1266
|
-
function isCorrectableExecuteError(error) {
|
|
1267
|
-
return isCorrectableSubmissionError(error) || error instanceof GatekeeperDecisionError || error instanceof ParentQueueReaskError || error instanceof WorkerCommitReminderError || error instanceof WorkerPrefixReminderError || error instanceof WorkerUnfinishedReasonReminderError;
|
|
1268
|
-
}
|
|
1269
|
-
function projectCorrectableExecuteRejection(error) {
|
|
1270
|
-
const diagnostic = error instanceof Error ? error.message : String(error);
|
|
1271
|
-
if (error instanceof GatekeeperDecisionError) {
|
|
1272
|
-
return { diagnostic, details: { ...error.result } };
|
|
1273
|
-
}
|
|
1274
|
-
if (error instanceof WorkerCommitReminderError || error instanceof WorkerPrefixReminderError || error instanceof WorkerUnfinishedReasonReminderError) {
|
|
1275
|
-
return { diagnostic, details: { code: error.code } };
|
|
1276
|
-
}
|
|
1277
|
-
if (typeof error.code === "string") {
|
|
1278
|
-
return { diagnostic, details: { code: error.code } };
|
|
1279
|
-
}
|
|
1280
|
-
return {
|
|
1281
|
-
diagnostic,
|
|
1282
|
-
details: {
|
|
1283
|
-
code: error instanceof Error && error.name ? error.name : "correctable-submission-error"
|
|
1284
|
-
}
|
|
1285
|
-
};
|
|
1286
|
-
}
|
|
1287
|
-
var correctableSubmissionErrorBrand, CorrectableSubmissionError;
|
|
1288
|
-
var init_submission_correctable_error = __esm({
|
|
1289
|
-
"src/submission-correctable-error.ts"() {
|
|
1290
|
-
"use strict";
|
|
1291
|
-
init_submission_errors();
|
|
1292
|
-
correctableSubmissionErrorBrand = /* @__PURE__ */ Symbol("ak-roles.correctable-submission-error");
|
|
1293
|
-
CorrectableSubmissionError = class extends Error {
|
|
1294
|
-
[correctableSubmissionErrorBrand] = true;
|
|
1295
|
-
};
|
|
1296
|
-
}
|
|
1297
|
-
});
|
|
1298
|
-
|
|
1299
|
-
// src/collector-identity.ts
|
|
1300
|
-
var CollectorUnknownEvidenceError, CollectorNonOpenRequestError, CollectorWaitWindowClosedError;
|
|
1301
|
-
var init_collector_identity = __esm({
|
|
1302
|
-
"src/collector-identity.ts"() {
|
|
1303
|
-
"use strict";
|
|
1304
|
-
init_submission_correctable_error();
|
|
1305
|
-
CollectorUnknownEvidenceError = class extends CorrectableSubmissionError {
|
|
1306
|
-
constructor(evidenceId) {
|
|
1307
|
-
super(`\u672A\u5728\u672C\u5C40\u5DF2\u89C2\u6D4B\u6750\u6599\u4E2D\u627E\u5230 evidenceId ${evidenceId}\uFF1B\u8BF7\u7528 observe \u8FD4\u56DE\u7684\u6307\u9488\u91CD\u8BD5\u3002`);
|
|
1308
|
-
this.name = "CollectorUnknownEvidenceError";
|
|
1309
|
-
}
|
|
1310
|
-
};
|
|
1311
|
-
CollectorNonOpenRequestError = class extends CorrectableSubmissionError {
|
|
1312
|
-
constructor(prState) {
|
|
1313
|
-
super(`\u901A\u8FDB\u53F8\u8BF7\u6C42\u8981\u6C42 OPEN \u72B6\u6001\u7684 PR \u5FEB\u7167\uFF1B\u5F53\u524D\u4E3A ${prState}\uFF0C\u4E0D\u518D\u89E6\u53D1\u65B0\u8BC4\u5BA1\uFF0C\u8BF7\u76F4\u63A5\u4EA4\u56DE\u5DF2\u6709\u6750\u6599`);
|
|
1314
|
-
this.name = "CollectorNonOpenRequestError";
|
|
1315
|
-
}
|
|
1316
|
-
};
|
|
1317
|
-
CollectorWaitWindowClosedError = class extends CorrectableSubmissionError {
|
|
1318
|
-
constructor(action) {
|
|
1319
|
-
super(
|
|
1320
|
-
action === "request" ? "\u901A\u8FDB\u53F8\u8BF7\u6C42\u4E0D\u5728\u8D44\u683C\u622A\u6B62\u524D" : action === "wait-before-open" ? "\u901A\u8FDB\u53F8\u7B49\u5F85\u9700\u8981\u5148\u5728\u5DE5\u4F5C\u6B65\u9AA4\u5F00\u542F\u7B49\u5F85\u7A97\uFF08\u65B0\u5EFA PR \u7528\u521B\u5EFA\u6210\u529F\u65F6\u523B\uFF1B\u5DF2\u6709 PR \u5728\u89E6\u53D1\u9636\u6BB5\u7ED3\u675F\u540E\u5F00\u542F\uFF09" : "\u901A\u8FDB\u53F8\u7B49\u5F85\u4E0D\u5728\u8D44\u683C\u622A\u6B62\u524D"
|
|
1321
|
-
);
|
|
1322
|
-
this.name = "CollectorWaitWindowClosedError";
|
|
1323
|
-
}
|
|
1324
|
-
};
|
|
1325
|
-
}
|
|
1326
|
-
});
|
|
1327
|
-
|
|
1328
|
-
// src/collector-ledger.ts
|
|
1329
|
-
function projectObserveContextView(modelView) {
|
|
1330
|
-
return modelView;
|
|
1331
|
-
}
|
|
1332
|
-
function isOperationalTool(name) {
|
|
1333
|
-
return COLLECTOR_OPERATIONAL_TOOLS.includes(name);
|
|
1334
|
-
}
|
|
1335
|
-
function resolveWaitWindowMs(raw) {
|
|
1336
|
-
if (raw === void 0) return COLLECTOR_DEFAULT_WAIT_WINDOW_MS;
|
|
1337
|
-
if (!Number.isSafeInteger(raw) || raw < 1) {
|
|
1338
|
-
throw new Error("\u901A\u8FDB\u53F8 waitWindowMs \u987B\u4E3A\u6B63\u5B89\u5168\u6574\u6570\u6BEB\u79D2");
|
|
1339
|
-
}
|
|
1340
|
-
return raw;
|
|
1341
|
-
}
|
|
1342
|
-
function createCollectorLedger(input, options) {
|
|
1343
|
-
const config = {
|
|
1344
|
-
repository: input.repository,
|
|
1345
|
-
prNumber: input.prNumber,
|
|
1346
|
-
manifest: input.manifest,
|
|
1347
|
-
waitWindowMs: resolveWaitWindowMs(input.waitWindowMs)
|
|
1348
|
-
};
|
|
1349
|
-
const clock = options?.clock;
|
|
1350
|
-
const journal = options?.journal;
|
|
1351
|
-
let fatal = false;
|
|
1352
|
-
let fatalReason;
|
|
1353
|
-
let outputCandidate = false;
|
|
1354
|
-
let pendingOutputCallId;
|
|
1355
|
-
let sessionReady = false;
|
|
1356
|
-
let activationTime;
|
|
1357
|
-
let deadlineTime;
|
|
1358
|
-
let activationMono;
|
|
1359
|
-
let deadlineMono;
|
|
1360
|
-
let requesterLogin;
|
|
1361
|
-
let latestCompleteSnapshotId;
|
|
1362
|
-
let finalObservationRequired = false;
|
|
1363
|
-
let finalObservationCompleted = false;
|
|
1364
|
-
let activeOperationalCallId;
|
|
1365
|
-
let mutationGeneration = 0;
|
|
1366
|
-
let observedGeneration = 0;
|
|
1367
|
-
const evidenceById = /* @__PURE__ */ new Map();
|
|
1368
|
-
const evidenceByVersion = /* @__PURE__ */ new Map();
|
|
1369
|
-
const snapshots = [];
|
|
1370
|
-
const attempts = [];
|
|
1371
|
-
const attemptKeys = /* @__PURE__ */ new Set();
|
|
1372
|
-
const waits = [];
|
|
1373
|
-
const transportFailures = [];
|
|
1374
|
-
const latchFatal = (reason, cause) => {
|
|
1375
|
-
fatal = true;
|
|
1376
|
-
fatalReason = reason;
|
|
1377
|
-
const error = new Error(reason, cause === void 0 ? void 0 : { cause });
|
|
1378
|
-
Object.assign(error, { collectorFatal: true });
|
|
1379
|
-
return error;
|
|
1380
|
-
};
|
|
1381
|
-
const assertNotFatal = () => {
|
|
1382
|
-
if (fatal) throw new Error(fatalReason ?? "\u901A\u8FDB\u53F8\u81F4\u547D\u72B6\u6001");
|
|
1383
|
-
};
|
|
1384
|
-
const storeEvidence = (record4) => {
|
|
1385
|
-
const existingId = evidenceByVersion.get(record4.versionId);
|
|
1386
|
-
if (existingId !== void 0) {
|
|
1387
|
-
return evidenceById.get(existingId) ?? record4;
|
|
1388
|
-
}
|
|
1389
|
-
evidenceByVersion.set(record4.versionId, record4.evidenceId);
|
|
1390
|
-
evidenceById.set(record4.evidenceId, record4);
|
|
1391
|
-
return record4;
|
|
1392
|
-
};
|
|
1393
|
-
const monoNowOrThrow = (clock2) => clock2.monoNow();
|
|
1394
|
-
const pastCutoff = (clock2) => {
|
|
1395
|
-
if (deadlineMono === void 0) return false;
|
|
1396
|
-
return monoNowOrThrow(clock2) >= deadlineMono;
|
|
1397
|
-
};
|
|
1398
|
-
const remainingMs = (clock2) => {
|
|
1399
|
-
if (deadlineMono === void 0) return config.waitWindowMs;
|
|
1400
|
-
return Math.max(0, deadlineMono - monoNowOrThrow(clock2));
|
|
1401
|
-
};
|
|
1402
|
-
const prIdentity = (pr) => `${pr.state}|${pr.headOid}|${pr.updatedAt ?? ""}`;
|
|
1403
|
-
const requireBoundPr = () => {
|
|
1404
|
-
if (config.prNumber === void 0) {
|
|
1405
|
-
throw new Error("\u901A\u8FDB\u53F8 PR \u76EE\u6807\u672A\u7ED1\u5B9A");
|
|
1406
|
-
}
|
|
1407
|
-
return config.prNumber;
|
|
1408
|
-
};
|
|
1409
|
-
const fetchObserveSurfaces = async (transport, observedAt, signal) => {
|
|
1410
|
-
const owner = config.repository.owner;
|
|
1411
|
-
const repo = config.repository.repo;
|
|
1412
|
-
const prNumber = requireBoundPr();
|
|
1413
|
-
const signalOpt = signal === void 0 ? {} : { signal };
|
|
1414
|
-
const user = await transport.getAuthenticatedUser(signalOpt);
|
|
1415
|
-
const prInitial = await transport.getPullRequest({
|
|
1416
|
-
owner,
|
|
1417
|
-
repo,
|
|
1418
|
-
prNumber,
|
|
1419
|
-
...signalOpt
|
|
1420
|
-
});
|
|
1421
|
-
const reviews = await transport.listPullRequestReviews({
|
|
1422
|
-
owner,
|
|
1423
|
-
repo,
|
|
1424
|
-
prNumber,
|
|
1425
|
-
...signalOpt
|
|
1426
|
-
});
|
|
1427
|
-
const reactions = transport.listPullRequestReactions === void 0 ? { items: [], pages: [] } : await transport.listPullRequestReactions({ owner, repo, prNumber, ...signalOpt });
|
|
1428
|
-
const issueComments = await transport.listIssueComments({
|
|
1429
|
-
owner,
|
|
1430
|
-
repo,
|
|
1431
|
-
prNumber,
|
|
1432
|
-
...signalOpt
|
|
1433
|
-
});
|
|
1434
|
-
const reviewComments = await transport.listReviewComments({
|
|
1435
|
-
owner,
|
|
1436
|
-
repo,
|
|
1437
|
-
prNumber,
|
|
1438
|
-
...signalOpt
|
|
1439
|
-
});
|
|
1440
|
-
const prTerminal = await transport.getPullRequest({
|
|
1441
|
-
owner,
|
|
1442
|
-
repo,
|
|
1443
|
-
prNumber,
|
|
1444
|
-
...signalOpt
|
|
1445
|
-
});
|
|
1446
|
-
return { user, prInitial, reviews, reactions, issueComments, reviewComments, prTerminal };
|
|
1447
|
-
};
|
|
1448
|
-
const appendJournal = (customType, data) => {
|
|
1449
|
-
journal?.append(customType, data);
|
|
1450
|
-
};
|
|
1451
|
-
const bindDeadlineMonoFromWall = () => {
|
|
1452
|
-
if (clock === void 0 || activationTime === void 0 || deadlineTime === void 0) return;
|
|
1453
|
-
const wallNow = clock.wallNow().getTime();
|
|
1454
|
-
const monoNow = clock.monoNow();
|
|
1455
|
-
activationMono = monoNow - (wallNow - activationTime.getTime());
|
|
1456
|
-
deadlineMono = monoNow + (deadlineTime.getTime() - wallNow);
|
|
1457
|
-
};
|
|
1458
|
-
const rebindSnapshotCompletedMono = (snapshot) => {
|
|
1459
|
-
const copy = { ...snapshot, evidenceIds: [...snapshot.evidenceIds] };
|
|
1460
|
-
if (deadlineTime !== void 0 && deadlineMono !== void 0 && copy.completedAt !== void 0) {
|
|
1461
|
-
const completedWall = new Date(copy.completedAt).getTime();
|
|
1462
|
-
copy.completedMono = deadlineMono + (completedWall - deadlineTime.getTime());
|
|
1463
|
-
}
|
|
1464
|
-
return copy;
|
|
1465
|
-
};
|
|
1466
|
-
const commitActivationWindow = (nextActivation, nextDeadline) => {
|
|
1467
|
-
if (activationTime !== void 0) return;
|
|
1468
|
-
sessionReady = true;
|
|
1469
|
-
activationTime = nextActivation;
|
|
1470
|
-
deadlineTime = nextDeadline;
|
|
1471
|
-
bindDeadlineMonoFromWall();
|
|
1472
|
-
};
|
|
1473
|
-
const recoverAmbiguousRequestLosses = (snapshotId, observedRecords) => {
|
|
1474
|
-
for (const failure2 of transportFailures) {
|
|
1475
|
-
if (failure2.recovered || failure2.kind !== "ambiguous_request_loss") continue;
|
|
1476
|
-
if (failure2.marker === void 0 || failure2.requestId === void 0) continue;
|
|
1477
|
-
const found = observedRecords.find(
|
|
1478
|
-
(record4) => record4.kind === "issue_comment" && record4.authorLogin === requesterLogin && typeof record4.body === "string" && record4.body.includes(failure2.marker)
|
|
1479
|
-
);
|
|
1480
|
-
if (found === void 0) continue;
|
|
1481
|
-
failure2.recovered = true;
|
|
1482
|
-
const attempt = attempts.find(
|
|
1483
|
-
(item) => item.status === "ambiguous_loss" && item.requestId === failure2.requestId && item.marker === failure2.marker
|
|
1484
|
-
);
|
|
1485
|
-
if (attempt !== void 0) {
|
|
1486
|
-
attempt.status = "recovered";
|
|
1487
|
-
attempt.commentEvidenceId = found.evidenceId;
|
|
1488
|
-
attempt.recoverySnapshotId = snapshotId;
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
|
-
};
|
|
1492
|
-
const finalizeObservedSnapshot = (snapshot) => {
|
|
1493
|
-
if (requesterLogin === void 0) {
|
|
1494
|
-
for (const id of snapshot.evidenceIds) {
|
|
1495
|
-
const record4 = evidenceById.get(id);
|
|
1496
|
-
if (record4?.kind === "authenticated_user" && record4.authorLogin !== void 0) {
|
|
1497
|
-
requesterLogin = record4.authorLogin.toLowerCase();
|
|
1498
|
-
break;
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
|
-
const stored = rebindSnapshotCompletedMono(snapshot);
|
|
1503
|
-
snapshots.push(stored);
|
|
1504
|
-
latestCompleteSnapshotId = stored.snapshotId;
|
|
1505
|
-
const observedRecords = stored.evidenceIds.flatMap((id) => {
|
|
1506
|
-
const record4 = evidenceById.get(id);
|
|
1507
|
-
return record4 === void 0 ? [] : [record4];
|
|
1508
|
-
});
|
|
1509
|
-
recoverAmbiguousRequestLosses(stored.snapshotId, observedRecords);
|
|
1510
|
-
observedGeneration = mutationGeneration;
|
|
1511
|
-
if (finalObservationRequired && stored.completedMono !== void 0 && deadlineMono !== void 0 && stored.completedMono >= deadlineMono) {
|
|
1512
|
-
finalObservationCompleted = true;
|
|
1513
|
-
} else if (clock !== void 0 && deadlineMono !== void 0 && clock.monoNow() >= deadlineMono && stored.completedMono !== void 0 && stored.completedMono >= deadlineMono) {
|
|
1514
|
-
finalObservationRequired = true;
|
|
1515
|
-
finalObservationCompleted = true;
|
|
1516
|
-
}
|
|
1517
|
-
return stored;
|
|
1518
|
-
};
|
|
1519
|
-
const commitObservedSnapshot = (snapshot, evidenceRecords) => {
|
|
1520
|
-
for (const record4 of evidenceRecords) {
|
|
1521
|
-
storeEvidence(record4);
|
|
1522
|
-
}
|
|
1523
|
-
return finalizeObservedSnapshot(snapshot);
|
|
1524
|
-
};
|
|
1525
|
-
const commitRequestAttempt = (attempt, attemptKey, commentEvidence) => {
|
|
1526
|
-
if (commentEvidence !== void 0) {
|
|
1527
|
-
storeEvidence(commentEvidence);
|
|
1528
|
-
}
|
|
1529
|
-
const existing = attempts.find((item) => item.attemptId === attempt.attemptId);
|
|
1530
|
-
if (existing === void 0) {
|
|
1531
|
-
attempts.push({ ...attempt });
|
|
1532
|
-
attemptKeys.add(attemptKey);
|
|
1533
|
-
} else {
|
|
1534
|
-
Object.assign(existing, attempt);
|
|
1535
|
-
}
|
|
1536
|
-
if (attempt.status === "ambiguous_loss" && !transportFailures.some((failure2) => failure2.requestId === attempt.requestId && failure2.observedHead === attempt.observedHead)) {
|
|
1537
|
-
transportFailures.push({
|
|
1538
|
-
failureId: sha256Text(`loss:${attempt.attemptId}`).slice(0, 16),
|
|
1539
|
-
kind: "ambiguous_request_loss",
|
|
1540
|
-
message: attempt.responseDiagnostics ?? "ambiguous request loss",
|
|
1541
|
-
requestId: attempt.requestId,
|
|
1542
|
-
observedHead: attempt.observedHead,
|
|
1543
|
-
marker: attempt.marker,
|
|
1544
|
-
recovered: false
|
|
1545
|
-
});
|
|
1546
|
-
}
|
|
1547
|
-
if (attempt.status === "succeeded" || attempt.status === "ambiguous_loss") {
|
|
1548
|
-
mutationGeneration += 1;
|
|
1549
|
-
finalObservationCompleted = false;
|
|
1550
|
-
}
|
|
1551
|
-
};
|
|
1552
|
-
const commitWaitRecord = (wait) => {
|
|
1553
|
-
waits.push({ ...wait });
|
|
1554
|
-
if (wait.cutoffReached) finalObservationRequired = true;
|
|
1555
|
-
mutationGeneration += 1;
|
|
1556
|
-
finalObservationCompleted = false;
|
|
1557
|
-
};
|
|
1558
|
-
const replayDossierEntries = (entries) => {
|
|
1559
|
-
const orderedEntries = Array.from(entries);
|
|
1560
|
-
const finalRequestStatus = /* @__PURE__ */ new Map();
|
|
1561
|
-
for (const raw of orderedEntries) {
|
|
1562
|
-
if (typeof raw !== "object" || raw === null) continue;
|
|
1563
|
-
const entry = raw;
|
|
1564
|
-
if (entry.type !== "custom" || entry.customType !== COLLECTOR_REQUEST_ENTRY_TYPE || typeof entry.data !== "object" || entry.data === null) continue;
|
|
1565
|
-
const attempt = entry.data.attempt;
|
|
1566
|
-
if (attempt?.attemptId !== void 0) finalRequestStatus.set(attempt.attemptId, attempt.status);
|
|
1567
|
-
}
|
|
1568
|
-
for (const raw of orderedEntries) {
|
|
1569
|
-
if (typeof raw !== "object" || raw === null) continue;
|
|
1570
|
-
const entry = raw;
|
|
1571
|
-
if (entry.type !== "custom" || typeof entry.data !== "object" || entry.data === null) continue;
|
|
1572
|
-
const data = entry.data;
|
|
1573
|
-
if (entry.customType === COLLECTOR_ACTIVATION_ENTRY_TYPE) {
|
|
1574
|
-
if (typeof data.activationTime === "string" && typeof data.deadlineTime === "string") {
|
|
1575
|
-
commitActivationWindow(new Date(data.activationTime), new Date(data.deadlineTime));
|
|
1576
|
-
} else if (data.sessionReady === true) {
|
|
1577
|
-
sessionReady = true;
|
|
1578
|
-
}
|
|
1579
|
-
continue;
|
|
1580
|
-
}
|
|
1581
|
-
if (entry.customType === COLLECTOR_SNAPSHOT_ENTRY_TYPE) {
|
|
1582
|
-
const snapshot = data.snapshot;
|
|
1583
|
-
if (snapshot?.snapshotId === void 0 || !Array.isArray(data.evidence)) continue;
|
|
1584
|
-
commitObservedSnapshot(snapshot, data.evidence);
|
|
1585
|
-
continue;
|
|
1586
|
-
}
|
|
1587
|
-
if (entry.customType === COLLECTOR_REQUEST_ENTRY_TYPE) {
|
|
1588
|
-
const attempt = data.attempt;
|
|
1589
|
-
if (attempt?.attemptId === void 0) continue;
|
|
1590
|
-
const attemptKey = typeof data.attemptKey === "string" ? data.attemptKey : [config.repository.canonical, String(config.prNumber), attempt.observedHead, attempt.requestId].join("|");
|
|
1591
|
-
const commentEvidence = data.commentEvidence;
|
|
1592
|
-
const replayAttempt = attempt.status === "started" && finalRequestStatus.get(attempt.attemptId) === "started" ? {
|
|
1593
|
-
...attempt,
|
|
1594
|
-
status: "ambiguous_loss",
|
|
1595
|
-
responseDiagnostics: "request interrupted after dispatch before completion was recorded"
|
|
1596
|
-
} : attempt;
|
|
1597
|
-
commitRequestAttempt(replayAttempt, attemptKey, commentEvidence);
|
|
1598
|
-
continue;
|
|
1599
|
-
}
|
|
1600
|
-
if (entry.customType === COLLECTOR_WAIT_ENTRY_TYPE) {
|
|
1601
|
-
const wait = data.waitRecord;
|
|
1602
|
-
if (wait?.waitId === void 0) continue;
|
|
1603
|
-
commitWaitRecord(wait);
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
};
|
|
1607
|
-
if (options?.dossierEntries !== void 0) {
|
|
1608
|
-
replayDossierEntries(options.dossierEntries);
|
|
1609
|
-
}
|
|
1610
|
-
if (clock !== void 0 && deadlineMono !== void 0 && clock.monoNow() >= deadlineMono) {
|
|
1611
|
-
finalObservationRequired = true;
|
|
1612
|
-
const lastSnap = snapshots.find((item) => item.snapshotId === latestCompleteSnapshotId);
|
|
1613
|
-
if (lastSnap?.completedMono !== void 0 && lastSnap.completedMono >= deadlineMono) {
|
|
1614
|
-
finalObservationCompleted = true;
|
|
1615
|
-
}
|
|
1616
|
-
}
|
|
1617
|
-
const ledger = {
|
|
1618
|
-
get config() {
|
|
1619
|
-
return config;
|
|
1620
|
-
},
|
|
1621
|
-
get fatal() {
|
|
1622
|
-
return fatal;
|
|
1623
|
-
},
|
|
1624
|
-
get fatalReason() {
|
|
1625
|
-
return fatalReason;
|
|
1626
|
-
},
|
|
1627
|
-
get outputCandidate() {
|
|
1628
|
-
return outputCandidate || pendingOutputCallId !== void 0;
|
|
1629
|
-
},
|
|
1630
|
-
get activationRecorded() {
|
|
1631
|
-
return sessionReady;
|
|
1632
|
-
},
|
|
1633
|
-
get activationTime() {
|
|
1634
|
-
return activationTime;
|
|
1635
|
-
},
|
|
1636
|
-
get deadlineTime() {
|
|
1637
|
-
return deadlineTime;
|
|
1638
|
-
},
|
|
1639
|
-
get activationMono() {
|
|
1640
|
-
return activationMono;
|
|
1641
|
-
},
|
|
1642
|
-
get deadlineMono() {
|
|
1643
|
-
return deadlineMono;
|
|
1644
|
-
},
|
|
1645
|
-
get requesterLogin() {
|
|
1646
|
-
return requesterLogin;
|
|
1647
|
-
},
|
|
1648
|
-
get latestCompleteSnapshotId() {
|
|
1649
|
-
return latestCompleteSnapshotId;
|
|
1650
|
-
},
|
|
1651
|
-
get finalObservationRequired() {
|
|
1652
|
-
return finalObservationRequired;
|
|
1653
|
-
},
|
|
1654
|
-
get finalObservationCompleted() {
|
|
1655
|
-
return finalObservationCompleted;
|
|
1656
|
-
},
|
|
1657
|
-
get unresolvedTransportFailure() {
|
|
1658
|
-
return transportFailures.some((failure2) => !failure2.recovered);
|
|
1659
|
-
},
|
|
1660
|
-
get mutationGeneration() {
|
|
1661
|
-
return mutationGeneration;
|
|
1662
|
-
},
|
|
1663
|
-
get observedGeneration() {
|
|
1664
|
-
return observedGeneration;
|
|
1665
|
-
},
|
|
1666
|
-
latchFatal,
|
|
1667
|
-
assertNotFatal,
|
|
1668
|
-
recordActivation(_clock) {
|
|
1669
|
-
assertNotFatal();
|
|
1670
|
-
if (sessionReady) return;
|
|
1671
|
-
sessionReady = true;
|
|
1672
|
-
appendJournal(COLLECTOR_ACTIVATION_ENTRY_TYPE, {
|
|
1673
|
-
sessionReady: true
|
|
1674
|
-
});
|
|
1675
|
-
},
|
|
1676
|
-
openWaitWindow(clock2, options2) {
|
|
1677
|
-
assertNotFatal();
|
|
1678
|
-
if (!sessionReady) {
|
|
1679
|
-
throw latchFatal("\u901A\u8FDB\u53F8\u5F00\u542F\u7B49\u5F85\u7A97\u9700\u8981\u5148\u6FC0\u6D3B\u4F1A\u8BDD");
|
|
1680
|
-
}
|
|
1681
|
-
if (activationTime !== void 0) return;
|
|
1682
|
-
const startedAt = options2?.startedAt ?? clock2.wallNow();
|
|
1683
|
-
if (!(startedAt instanceof Date) || Number.isNaN(startedAt.getTime())) {
|
|
1684
|
-
throw new Error("\u901A\u8FDB\u53F8\u7B49\u5F85\u7A97 startedAt \u987B\u4E3A\u6709\u6548\u65F6\u95F4");
|
|
1685
|
-
}
|
|
1686
|
-
const nextDeadline = new Date(startedAt.getTime() + config.waitWindowMs);
|
|
1687
|
-
activationTime = startedAt;
|
|
1688
|
-
deadlineTime = nextDeadline;
|
|
1689
|
-
const wallNow = clock2.wallNow().getTime();
|
|
1690
|
-
const monoNow = clock2.monoNow();
|
|
1691
|
-
activationMono = monoNow - (wallNow - startedAt.getTime());
|
|
1692
|
-
deadlineMono = monoNow + (nextDeadline.getTime() - wallNow);
|
|
1693
|
-
appendJournal(COLLECTOR_ACTIVATION_ENTRY_TYPE, {
|
|
1694
|
-
activationTime: activationTime.toISOString(),
|
|
1695
|
-
deadlineTime: deadlineTime.toISOString(),
|
|
1696
|
-
waitWindowMs: config.waitWindowMs
|
|
1697
|
-
});
|
|
1698
|
-
},
|
|
1699
|
-
recordOutputCandidate() {
|
|
1700
|
-
assertNotFatal();
|
|
1701
|
-
outputCandidate = true;
|
|
1702
|
-
},
|
|
1703
|
-
bindTarget(prNumber) {
|
|
1704
|
-
assertNotFatal();
|
|
1705
|
-
config.prNumber = prNumber;
|
|
1706
|
-
appendJournal("ak-collector-target-bound", {
|
|
1707
|
-
prNumber,
|
|
1708
|
-
repository: config.repository.canonical
|
|
1709
|
-
});
|
|
1710
|
-
},
|
|
1711
|
-
beginOperational(toolName, toolCallId) {
|
|
1712
|
-
assertNotFatal();
|
|
1713
|
-
if (toolName === COLLECTOR_OUTPUT_TOOL) {
|
|
1714
|
-
pendingOutputCallId = toolCallId;
|
|
1715
|
-
return;
|
|
1716
|
-
}
|
|
1717
|
-
if (activeOperationalCallId === toolCallId) {
|
|
1718
|
-
return;
|
|
1719
|
-
}
|
|
1720
|
-
if (activeOperationalCallId !== void 0) {
|
|
1721
|
-
throw latchFatal("\u901A\u8FDB\u53F8\u64CD\u4F5C\u8C03\u7528\u5DF2\u5728\u8FDB\u884C");
|
|
1722
|
-
}
|
|
1723
|
-
if (!isOperationalTool(toolName)) {
|
|
1724
|
-
throw latchFatal(`\u672A\u77E5\u901A\u8FDB\u53F8\u5DE5\u5177 ${toolName}`);
|
|
1725
|
-
}
|
|
1726
|
-
activeOperationalCallId = toolCallId;
|
|
1727
|
-
},
|
|
1728
|
-
completeOperational(toolCallId) {
|
|
1729
|
-
if (pendingOutputCallId === toolCallId) {
|
|
1730
|
-
pendingOutputCallId = void 0;
|
|
1731
|
-
}
|
|
1732
|
-
if (activeOperationalCallId === toolCallId) {
|
|
1733
|
-
activeOperationalCallId = void 0;
|
|
1734
|
-
}
|
|
1735
|
-
},
|
|
1736
|
-
noteCutoffObserved() {
|
|
1737
|
-
finalObservationRequired = true;
|
|
1738
|
-
},
|
|
1739
|
-
assertOutputObservationLaw(clock2) {
|
|
1740
|
-
assertNotFatal();
|
|
1741
|
-
if (activationTime === void 0 || deadlineTime === void 0 || deadlineMono === void 0) {
|
|
1742
|
-
throw new Error("\u901A\u8FDB\u53F8\u56DE\u6267\u9700\u8981\u6FC0\u6D3B\u65F6\u95F4\u7EBF");
|
|
1743
|
-
}
|
|
1744
|
-
if (latestCompleteSnapshotId === void 0) {
|
|
1745
|
-
throw new Error("\u901A\u8FDB\u53F8\u56DE\u6267\u9700\u8981\u5B8C\u6574\u7EC8\u5C40\u5FEB\u7167");
|
|
1746
|
-
}
|
|
1747
|
-
if (observedGeneration !== mutationGeneration) {
|
|
1748
|
-
throw new Error(
|
|
1749
|
-
"\u901A\u8FDB\u53F8\u56DE\u6267\u8981\u6C42\u5728\u6700\u8FD1 request/wait \u53D8\u66F4\u540E\u5B8C\u6210\u4E00\u6B21 observe"
|
|
1750
|
-
);
|
|
1751
|
-
}
|
|
1752
|
-
const snapshot = snapshots.find((item) => item.snapshotId === latestCompleteSnapshotId);
|
|
1753
|
-
if (snapshot === void 0 || !snapshot.complete) {
|
|
1754
|
-
throw new Error("\u901A\u8FDB\u53F8\u7EC8\u5C40\u5FEB\u7167\u7F3A\u5931\u6216\u4E0D\u5B8C\u6574");
|
|
1755
|
-
}
|
|
1756
|
-
const mono = monoNowOrThrow(clock2);
|
|
1757
|
-
const atOrAfterCutoff = mono >= deadlineMono;
|
|
1758
|
-
if (atOrAfterCutoff) {
|
|
1759
|
-
finalObservationRequired = true;
|
|
1760
|
-
if (snapshot.completedMono === void 0 || snapshot.completedMono < deadlineMono) {
|
|
1761
|
-
throw new Error(
|
|
1762
|
-
"\u901A\u8FDB\u53F8\u622A\u6B62\u65F6/\u540E\u56DE\u6267\u8981\u6C42\u4E0D\u65E9\u4E8E\u622A\u6B62\u5B8C\u6210\u7684\u5B8C\u6574\u89C2\u5BDF"
|
|
1763
|
-
);
|
|
1764
|
-
}
|
|
1765
|
-
finalObservationCompleted = true;
|
|
1766
|
-
}
|
|
1767
|
-
},
|
|
1768
|
-
async observe(transport, clock2, signal) {
|
|
1769
|
-
assertNotFatal();
|
|
1770
|
-
if (!sessionReady) {
|
|
1771
|
-
throw latchFatal("\u901A\u8FDB\u53F8\u89C2\u5BDF\u9700\u8981\u6FC0\u6D3B");
|
|
1772
|
-
}
|
|
1773
|
-
if (signal?.aborted) {
|
|
1774
|
-
const abortMessage = signal.reason instanceof Error ? signal.reason.message : String(signal.reason ?? "\u5DF2\u4E2D\u6B62");
|
|
1775
|
-
throw latchFatal(`\u901A\u8FDB\u53F8\u89C2\u5BDF\u5931\u8D25\uFF1A${abortMessage}`, signal.reason);
|
|
1776
|
-
}
|
|
1777
|
-
const observedAt = clock2.wallNow().toISOString();
|
|
1778
|
-
const cutoff = pastCutoff(clock2);
|
|
1779
|
-
if (cutoff) {
|
|
1780
|
-
finalObservationRequired = true;
|
|
1781
|
-
}
|
|
1782
|
-
let surfaces;
|
|
1783
|
-
try {
|
|
1784
|
-
surfaces = await fetchObserveSurfaces(transport, observedAt, signal);
|
|
1785
|
-
if (prIdentity(surfaces.prInitial) !== prIdentity(surfaces.prTerminal)) {
|
|
1786
|
-
surfaces = await fetchObserveSurfaces(transport, observedAt, signal);
|
|
1787
|
-
if (prIdentity(surfaces.prInitial) !== prIdentity(surfaces.prTerminal)) {
|
|
1788
|
-
throw new Error(
|
|
1789
|
-
`PR \u8EAB\u4EFD\u5728 observe \u62EC\u5F27\u91CD\u8BD5\u540E\u4ECD\u6F02\u79FB\uFF08${prIdentity(surfaces.prInitial)} \u2192 ${prIdentity(surfaces.prTerminal)}\uFF09`
|
|
1790
|
-
);
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1793
|
-
} catch (error) {
|
|
1794
|
-
const message = error instanceof Error ? error.message : "\u672A\u77E5\u5931\u8D25";
|
|
1795
|
-
throw latchFatal(`\u901A\u8FDB\u53F8\u89C2\u5BDF\u5931\u8D25\uFF1A${message}`, error);
|
|
1796
|
-
}
|
|
1797
|
-
const firstObservedAt = clock2.wallNow().toISOString();
|
|
1798
|
-
const firstObservedMono = monoNowOrThrow(clock2);
|
|
1799
|
-
const pr = surfaces.prTerminal;
|
|
1800
|
-
const { user, reviews, reactions, issueComments, reviewComments } = surfaces;
|
|
1801
|
-
requesterLogin = user.login.toLowerCase();
|
|
1802
|
-
const pageDiagnostics = [
|
|
1803
|
-
...reviews.pages,
|
|
1804
|
-
...reactions.pages,
|
|
1805
|
-
...issueComments.pages,
|
|
1806
|
-
...reviewComments.pages
|
|
1807
|
-
];
|
|
1808
|
-
const pendingRecords = [];
|
|
1809
|
-
pendingRecords.push(normalizeAuthenticatedUserEvidence(user, firstObservedAt));
|
|
1810
|
-
pendingRecords.push(normalizePullRequestEvidence(pr, firstObservedAt));
|
|
1811
|
-
for (const review of reviews.items) {
|
|
1812
|
-
pendingRecords.push(normalizeReviewEvidence(review, firstObservedAt));
|
|
1813
|
-
}
|
|
1814
|
-
for (const reaction of reactions.items) {
|
|
1815
|
-
pendingRecords.push(normalizePullRequestReactionEvidence(reaction, firstObservedAt));
|
|
1816
|
-
}
|
|
1817
|
-
for (const comment of issueComments.items) {
|
|
1818
|
-
pendingRecords.push(normalizeIssueCommentEvidence(comment, firstObservedAt));
|
|
1819
|
-
}
|
|
1820
|
-
for (const comment of reviewComments.items) {
|
|
1821
|
-
pendingRecords.push(normalizeReviewCommentEvidence(comment, firstObservedAt));
|
|
1822
|
-
}
|
|
1823
|
-
applyEvidenceVersionHistory(
|
|
1824
|
-
pendingRecords,
|
|
1825
|
-
[...evidenceById.values()],
|
|
1826
|
-
{ deadlineMono, firstObservedMono }
|
|
1827
|
-
);
|
|
1828
|
-
assignWindowRelations(pendingRecords, activationTime, deadlineTime);
|
|
1829
|
-
const normalizedByteLength = measureNormalizedBytes(pendingRecords);
|
|
1830
|
-
const storedIds = [];
|
|
1831
|
-
for (const record4 of pendingRecords) {
|
|
1832
|
-
const stored = storeEvidence(record4);
|
|
1833
|
-
storedIds.push(stored.evidenceId);
|
|
1834
|
-
}
|
|
1835
|
-
const storedRecords = storedIds.map((id) => {
|
|
1836
|
-
const stored = evidenceById.get(id);
|
|
1837
|
-
if (stored === void 0) {
|
|
1838
|
-
throw latchFatal(`\u901A\u8FDB\u53F8\u89C2\u5BDF\u4E22\u5931\u5DF2\u5B58\u8BC1\u636E ${id}`);
|
|
1839
|
-
}
|
|
1840
|
-
return stored;
|
|
1841
|
-
});
|
|
1842
|
-
const completedAt = clock2.wallNow().toISOString();
|
|
1843
|
-
const completedMono = clock2.monoNow();
|
|
1844
|
-
const snapshotId = sha256Text(
|
|
1845
|
-
`${completedAt}:${pr.headOid}:${storedIds.join(",")}`
|
|
1846
|
-
).slice(0, 16);
|
|
1847
|
-
const snapshot = {
|
|
1848
|
-
snapshotId,
|
|
1849
|
-
observedAt,
|
|
1850
|
-
completedAt,
|
|
1851
|
-
completedMono,
|
|
1852
|
-
host: "github.com",
|
|
1853
|
-
repository: config.repository.canonical,
|
|
1854
|
-
prNumber: requireBoundPr(),
|
|
1855
|
-
prState: pr.state,
|
|
1856
|
-
headOid: pr.headOid,
|
|
1857
|
-
...pr.createdAt === void 0 ? {} : { prCreatedAt: pr.createdAt },
|
|
1858
|
-
complete: true,
|
|
1859
|
-
evidenceIds: storedIds,
|
|
1860
|
-
pageDiagnostics,
|
|
1861
|
-
normalizedByteLength
|
|
1862
|
-
};
|
|
1863
|
-
if (cutoff) {
|
|
1864
|
-
finalObservationRequired = true;
|
|
1865
|
-
}
|
|
1866
|
-
const committed = finalizeObservedSnapshot(snapshot);
|
|
1867
|
-
appendJournal(COLLECTOR_SNAPSHOT_ENTRY_TYPE, {
|
|
1868
|
-
snapshot: committed,
|
|
1869
|
-
evidence: committed.evidenceIds.flatMap((id) => {
|
|
1870
|
-
const record4 = evidenceById.get(id);
|
|
1871
|
-
return record4 === void 0 ? [] : [record4];
|
|
1872
|
-
})
|
|
1873
|
-
});
|
|
1874
|
-
const modelView = buildObserveModelView({
|
|
1875
|
-
snapshot: committed,
|
|
1876
|
-
records: committed.evidenceIds.flatMap((id) => {
|
|
1877
|
-
const record4 = evidenceById.get(id);
|
|
1878
|
-
return record4 === void 0 ? [] : [record4];
|
|
1879
|
-
}),
|
|
1880
|
-
requesterLogin,
|
|
1881
|
-
attempts
|
|
1882
|
-
});
|
|
1883
|
-
return {
|
|
1884
|
-
snapshot: committed,
|
|
1885
|
-
modelView,
|
|
1886
|
-
contextView: projectObserveContextView(modelView)
|
|
1887
|
-
};
|
|
1888
|
-
},
|
|
1889
|
-
async request(input2, transport, clock2, signal) {
|
|
1890
|
-
assertNotFatal();
|
|
1891
|
-
if (!sessionReady) {
|
|
1892
|
-
throw latchFatal("\u901A\u8FDB\u53F8\u8BF7\u6C42\u9700\u8981\u6FC0\u6D3B");
|
|
1893
|
-
}
|
|
1894
|
-
if (ledger.unresolvedTransportFailure) {
|
|
1895
|
-
throw latchFatal("\u901A\u8FDB\u53F8\u8BF7\u6C42\u65F6\u5B58\u5728\u672A\u6062\u590D\u7684\u4F20\u8F93\u5931\u8D25");
|
|
1896
|
-
}
|
|
1897
|
-
if (typeof input2.requestId !== "string") {
|
|
1898
|
-
throw new Error("\u901A\u8FDB\u53F8 requestId \u987B\u4E3A\u5B57\u7B26\u4E32");
|
|
1899
|
-
}
|
|
1900
|
-
const requestId = input2.requestId.trim();
|
|
1901
|
-
if (requestId.length === 0) {
|
|
1902
|
-
throw new Error("\u901A\u8FDB\u53F8 requestId \u987B\u4E3A\u975E\u7A7A\uFF08\u9996\u5C3E\u7A7A\u767D\u4E0D\u6784\u6210\u8EAB\u4EFD\uFF09");
|
|
1903
|
-
}
|
|
1904
|
-
const configured = config.manifest.requests.find((item) => item.id === requestId);
|
|
1905
|
-
const roleBody = typeof input2.body === "string" ? input2.body : void 0;
|
|
1906
|
-
if (configured === void 0) {
|
|
1907
|
-
if (roleBody === void 0 || roleBody.trim().length === 0) {
|
|
1908
|
-
throw new Error(
|
|
1909
|
-
`\u672A\u77E5\u901A\u8FDB\u53F8 requestId "${requestId}" \u4E14\u672A\u63D0\u4F9B body\uFF1B\u8BF7\u63D0\u4EA4\u89D2\u8272\u5224\u5B9A\u7684\u8BF7\u6C42\u6B63\u6587\u6216\u4F7F\u7528 request-manifest`
|
|
1910
|
-
);
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
|
-
const snapshot = snapshots.find((item) => item.snapshotId === input2.snapshotId);
|
|
1914
|
-
if (snapshot === void 0) {
|
|
1915
|
-
throw new Error(`\u672A\u77E5\u901A\u8FDB\u53F8 snapshotId "${input2.snapshotId}"`);
|
|
1916
|
-
}
|
|
1917
|
-
if (snapshot.snapshotId !== latestCompleteSnapshotId) {
|
|
1918
|
-
throw new Error("\u901A\u8FDB\u53F8\u8BF7\u6C42\u8981\u6C42\u6700\u65B0\u5B8C\u6574\u5FEB\u7167");
|
|
1919
|
-
}
|
|
1920
|
-
if (snapshot.prState !== "OPEN") {
|
|
1921
|
-
throw new CollectorNonOpenRequestError(snapshot.prState);
|
|
1922
|
-
}
|
|
1923
|
-
if (pastCutoff(clock2)) {
|
|
1924
|
-
finalObservationRequired = true;
|
|
1925
|
-
throw new CollectorWaitWindowClosedError("request");
|
|
1926
|
-
}
|
|
1927
|
-
const configuredBody = configured?.requestBody ?? roleBody;
|
|
1928
|
-
const { body, marker } = buildCollectorRequestBody({
|
|
1929
|
-
configuredBody,
|
|
1930
|
-
manifestDigest: config.manifest.digest,
|
|
1931
|
-
requestId,
|
|
1932
|
-
headOid: snapshot.headOid
|
|
1933
|
-
});
|
|
1934
|
-
const existingMarker = snapshot.evidenceIds.some((id) => {
|
|
1935
|
-
const record4 = evidenceById.get(id);
|
|
1936
|
-
return record4?.kind === "issue_comment" && record4.authorLogin === requesterLogin && typeof record4.body === "string" && record4.body.includes(marker);
|
|
1937
|
-
});
|
|
1938
|
-
if (existingMarker) {
|
|
1939
|
-
throw new Error(
|
|
1940
|
-
`\u901A\u8FDB\u53F8\u5728\u6B64 HEAD \u5DF2\u6709\u540C marker \u7684\u5DF2\u8BA4\u8BC1\u8BF7\u6C42 "${requestId}"`
|
|
1941
|
-
);
|
|
1942
|
-
}
|
|
1943
|
-
const boundPr = requireBoundPr();
|
|
1944
|
-
const attemptKey = [
|
|
1945
|
-
config.repository.canonical,
|
|
1946
|
-
String(boundPr),
|
|
1947
|
-
snapshot.headOid,
|
|
1948
|
-
requestId
|
|
1949
|
-
].join("|");
|
|
1950
|
-
if (attemptKeys.has(attemptKey)) {
|
|
1951
|
-
throw new Error(
|
|
1952
|
-
`\u901A\u8FDB\u53F8\u8FDB\u7A0B\u5185\u8BF7\u6C42 "${requestId}" \u5728 HEAD ${snapshot.headOid} \u7684 attempt \u5DF2\u7528`
|
|
1953
|
-
);
|
|
1954
|
-
}
|
|
1955
|
-
const startedAt = clock2.wallNow().toISOString();
|
|
1956
|
-
const attemptId = sha256Text(`${attemptKey}:${startedAt}`).slice(0, 16);
|
|
1957
|
-
const attempt = {
|
|
1958
|
-
attemptId,
|
|
1959
|
-
requestId,
|
|
1960
|
-
observedHead: snapshot.headOid,
|
|
1961
|
-
snapshotId: snapshot.snapshotId,
|
|
1962
|
-
marker,
|
|
1963
|
-
body,
|
|
1964
|
-
startedAt,
|
|
1965
|
-
status: "started"
|
|
1966
|
-
};
|
|
1967
|
-
commitRequestAttempt(attempt, attemptKey, void 0);
|
|
1968
|
-
appendJournal(COLLECTOR_REQUEST_ENTRY_TYPE, {
|
|
1969
|
-
attempt: { ...attempt },
|
|
1970
|
-
attemptKey
|
|
1971
|
-
});
|
|
1972
|
-
const result = await transport.createIssueComment({
|
|
1973
|
-
owner: config.repository.owner,
|
|
1974
|
-
repo: config.repository.repo,
|
|
1975
|
-
prNumber: boundPr,
|
|
1976
|
-
body,
|
|
1977
|
-
...signal === void 0 ? {} : { signal }
|
|
1978
|
-
});
|
|
1979
|
-
const journalRequest = (commentEvidence) => {
|
|
1980
|
-
const attemptKey2 = [
|
|
1981
|
-
config.repository.canonical,
|
|
1982
|
-
String(config.prNumber),
|
|
1983
|
-
attempt.observedHead,
|
|
1984
|
-
attempt.requestId
|
|
1985
|
-
].join("|");
|
|
1986
|
-
appendJournal(COLLECTOR_REQUEST_ENTRY_TYPE, {
|
|
1987
|
-
attempt: { ...attempt },
|
|
1988
|
-
attemptKey: attemptKey2,
|
|
1989
|
-
commentEvidence
|
|
1990
|
-
});
|
|
1991
|
-
};
|
|
1992
|
-
if (result.kind === "success") {
|
|
1993
|
-
const record4 = normalizeIssueCommentEvidence(result.comment, startedAt);
|
|
1994
|
-
attempt.status = "succeeded";
|
|
1995
|
-
attempt.commentEvidenceId = record4.evidenceId;
|
|
1996
|
-
commitRequestAttempt(attempt, attemptKey, record4);
|
|
1997
|
-
journalRequest(record4);
|
|
1998
|
-
return {
|
|
1999
|
-
status: "succeeded",
|
|
2000
|
-
attemptId,
|
|
2001
|
-
requestId,
|
|
2002
|
-
observedHead: snapshot.headOid,
|
|
2003
|
-
marker,
|
|
2004
|
-
commentEvidenceId: record4.evidenceId
|
|
2005
|
-
};
|
|
2006
|
-
}
|
|
2007
|
-
if (result.kind === "ambiguous_loss") {
|
|
2008
|
-
attempt.status = "ambiguous_loss";
|
|
2009
|
-
attempt.responseDiagnostics = result.diagnostics;
|
|
2010
|
-
commitRequestAttempt(attempt, attemptKey, void 0);
|
|
2011
|
-
journalRequest(void 0);
|
|
2012
|
-
return {
|
|
2013
|
-
status: "ambiguous_loss",
|
|
2014
|
-
attemptId,
|
|
2015
|
-
requestId,
|
|
2016
|
-
observedHead: snapshot.headOid,
|
|
2017
|
-
marker,
|
|
2018
|
-
diagnostics: result.diagnostics
|
|
2019
|
-
};
|
|
2020
|
-
}
|
|
2021
|
-
attempt.status = "rejected";
|
|
2022
|
-
attempt.responseDiagnostics = result.diagnostics;
|
|
2023
|
-
commitRequestAttempt(attempt, attemptKey, void 0);
|
|
2024
|
-
journalRequest(void 0);
|
|
2025
|
-
throw latchFatal(`\u901A\u8FDB\u53F8\u8BF7\u6C42\u88AB\u62D2\uFF1A${result.diagnostics}`);
|
|
2026
|
-
},
|
|
2027
|
-
async wait(input2, clock2, signal) {
|
|
2028
|
-
assertNotFatal();
|
|
2029
|
-
if (!sessionReady) {
|
|
2030
|
-
throw latchFatal("\u901A\u8FDB\u53F8\u7B49\u5F85\u9700\u8981\u6FC0\u6D3B");
|
|
2031
|
-
}
|
|
2032
|
-
if (activationTime === void 0 || deadlineTime === void 0) {
|
|
2033
|
-
throw new CollectorWaitWindowClosedError("wait-before-open");
|
|
2034
|
-
}
|
|
2035
|
-
if (pastCutoff(clock2)) {
|
|
2036
|
-
finalObservationRequired = true;
|
|
2037
|
-
throw new CollectorWaitWindowClosedError("wait");
|
|
2038
|
-
}
|
|
2039
|
-
const remaining = remainingMs(clock2);
|
|
2040
|
-
const effectiveMs = Math.min(input2.durationMs, remaining);
|
|
2041
|
-
const startedAt = clock2.wallNow().toISOString();
|
|
2042
|
-
const waitId = sha256Text(`wait:${startedAt}:${effectiveMs}`).slice(0, 16);
|
|
2043
|
-
await clock2.sleep(effectiveMs, signal);
|
|
2044
|
-
const endedAt = clock2.wallNow().toISOString();
|
|
2045
|
-
const cutoffReached = pastCutoff(clock2);
|
|
2046
|
-
const record4 = {
|
|
2047
|
-
waitId,
|
|
2048
|
-
requestedMs: input2.durationMs,
|
|
2049
|
-
effectiveMs,
|
|
2050
|
-
startedAt,
|
|
2051
|
-
endedAt,
|
|
2052
|
-
cutoffReached
|
|
2053
|
-
};
|
|
2054
|
-
commitWaitRecord(record4);
|
|
2055
|
-
appendJournal(COLLECTOR_WAIT_ENTRY_TYPE, {
|
|
2056
|
-
waitRecord: record4
|
|
2057
|
-
});
|
|
2058
|
-
return {
|
|
2059
|
-
waitId,
|
|
2060
|
-
requestedMs: input2.durationMs,
|
|
2061
|
-
effectiveMs,
|
|
2062
|
-
cutoffReached,
|
|
2063
|
-
remainingMsAfter: remainingMs(clock2)
|
|
2064
|
-
};
|
|
2065
|
-
},
|
|
2066
|
-
getSnapshot(snapshotId) {
|
|
2067
|
-
return snapshots.find((item) => item.snapshotId === snapshotId);
|
|
2068
|
-
},
|
|
2069
|
-
getEvidence(evidenceId) {
|
|
2070
|
-
return evidenceById.get(evidenceId);
|
|
2071
|
-
},
|
|
2072
|
-
allEvidence() {
|
|
2073
|
-
return [...evidenceById.values()];
|
|
2074
|
-
},
|
|
2075
|
-
allSnapshots() {
|
|
2076
|
-
return [...snapshots];
|
|
2077
|
-
},
|
|
2078
|
-
requestAttempts() {
|
|
2079
|
-
return [...attempts];
|
|
2080
|
-
},
|
|
2081
|
-
waits() {
|
|
2082
|
-
return [...waits];
|
|
2083
|
-
},
|
|
2084
|
-
transportFailures() {
|
|
2085
|
-
return [...transportFailures];
|
|
2086
|
-
},
|
|
2087
|
-
requestById(requestId) {
|
|
2088
|
-
return config.manifest.requests.find((request) => request.id === requestId);
|
|
2089
|
-
}
|
|
2090
|
-
};
|
|
2091
|
-
return ledger;
|
|
2092
|
-
}
|
|
2093
|
-
function projectEvidenceEntryView(record4) {
|
|
2094
|
-
return {
|
|
2095
|
-
evidenceId: record4.evidenceId,
|
|
2096
|
-
kind: record4.kind,
|
|
2097
|
-
authorLogin: record4.authorLogin,
|
|
2098
|
-
state: record4.state,
|
|
2099
|
-
body: record4.body,
|
|
2100
|
-
commitOid: record4.commitOid,
|
|
2101
|
-
htmlUrl: record4.htmlUrl,
|
|
2102
|
-
path: record4.path,
|
|
2103
|
-
// Single display fallback: current line, else originalLine.
|
|
2104
|
-
line: record4.line ?? record4.originalLine,
|
|
2105
|
-
side: record4.side,
|
|
2106
|
-
authoritativeTime: record4.authoritativeTime,
|
|
2107
|
-
windowRelation: record4.windowRelation,
|
|
2108
|
-
pullRequestReviewId: record4.pullRequestReviewId
|
|
2109
|
-
};
|
|
2110
|
-
}
|
|
2111
|
-
function buildObserveModelView(input) {
|
|
2112
|
-
const relevant = input.records;
|
|
2113
|
-
return {
|
|
2114
|
-
snapshotId: input.snapshot.snapshotId,
|
|
2115
|
-
observedAt: input.snapshot.observedAt,
|
|
2116
|
-
completedAt: input.snapshot.completedAt,
|
|
2117
|
-
prState: input.snapshot.prState,
|
|
2118
|
-
headOid: input.snapshot.headOid,
|
|
2119
|
-
...input.snapshot.prCreatedAt === void 0 ? {} : { prCreatedAt: input.snapshot.prCreatedAt },
|
|
2120
|
-
complete: input.snapshot.complete,
|
|
2121
|
-
evidence: relevant.map((record4) => projectEvidenceEntryView(record4)),
|
|
2122
|
-
requestAttempts: input.attempts.map((attempt) => ({
|
|
2123
|
-
attemptId: attempt.attemptId,
|
|
2124
|
-
requestId: attempt.requestId,
|
|
2125
|
-
observedHead: attempt.observedHead,
|
|
2126
|
-
status: attempt.status,
|
|
2127
|
-
marker: attempt.marker,
|
|
2128
|
-
recoverySnapshotId: attempt.recoverySnapshotId
|
|
2129
|
-
}))
|
|
2130
|
-
};
|
|
2131
|
-
}
|
|
2132
|
-
var COLLECTOR_OBSERVE_TOOL, COLLECTOR_READ_TOOL, COLLECTOR_REQUEST_TOOL, COLLECTOR_WAIT_TOOL, COLLECTOR_OPEN_WAIT_WINDOW_TOOL, COLLECTOR_BIND_TARGET_TOOL, COLLECTOR_HANDBOOK_WRITE_TOOL, COLLECTOR_OPERATIONAL_TOOLS, COLLECTOR_ACTIVATION_ENTRY_TYPE, COLLECTOR_SNAPSHOT_ENTRY_TYPE, COLLECTOR_REQUEST_ENTRY_TYPE, COLLECTOR_WAIT_ENTRY_TYPE;
|
|
2133
|
-
var init_collector_ledger = __esm({
|
|
2134
|
-
"src/collector-ledger.ts"() {
|
|
2135
|
-
"use strict";
|
|
2136
|
-
init_collector_evidence();
|
|
2137
|
-
init_collector_github();
|
|
2138
|
-
init_collector_identity();
|
|
2139
|
-
init_collector_output();
|
|
2140
|
-
COLLECTOR_OBSERVE_TOOL = "ak_collector_observe";
|
|
2141
|
-
COLLECTOR_READ_TOOL = "ak_collector_read";
|
|
2142
|
-
COLLECTOR_REQUEST_TOOL = "ak_collector_request";
|
|
2143
|
-
COLLECTOR_WAIT_TOOL = "ak_collector_wait";
|
|
2144
|
-
COLLECTOR_OPEN_WAIT_WINDOW_TOOL = "ak_collector_open_wait_window";
|
|
2145
|
-
COLLECTOR_BIND_TARGET_TOOL = "ak_collector_bind_target";
|
|
2146
|
-
COLLECTOR_HANDBOOK_WRITE_TOOL = "ak_collector_handbook_write";
|
|
2147
|
-
COLLECTOR_OPERATIONAL_TOOLS = [
|
|
2148
|
-
COLLECTOR_BIND_TARGET_TOOL,
|
|
2149
|
-
COLLECTOR_OBSERVE_TOOL,
|
|
2150
|
-
COLLECTOR_READ_TOOL,
|
|
2151
|
-
COLLECTOR_REQUEST_TOOL,
|
|
2152
|
-
COLLECTOR_OPEN_WAIT_WINDOW_TOOL,
|
|
2153
|
-
COLLECTOR_WAIT_TOOL,
|
|
2154
|
-
COLLECTOR_HANDBOOK_WRITE_TOOL
|
|
2155
|
-
];
|
|
2156
|
-
COLLECTOR_ACTIVATION_ENTRY_TYPE = "ak-collector-activation";
|
|
2157
|
-
COLLECTOR_SNAPSHOT_ENTRY_TYPE = "ak-collector-snapshot";
|
|
2158
|
-
COLLECTOR_REQUEST_ENTRY_TYPE = "ak-collector-request";
|
|
2159
|
-
COLLECTOR_WAIT_ENTRY_TYPE = "ak-collector-wait";
|
|
2160
|
-
}
|
|
2161
|
-
});
|
|
2162
|
-
|
|
2163
209
|
// src/open-tool-schema.ts
|
|
2164
210
|
import { Type } from "typebox";
|
|
2165
211
|
function described(name, schema) {
|
|
@@ -2497,27 +543,27 @@ function causeMessage(cause) {
|
|
|
2497
543
|
return String(cause);
|
|
2498
544
|
}
|
|
2499
545
|
}
|
|
2500
|
-
function
|
|
546
|
+
function fail(cause) {
|
|
2501
547
|
throw new FixerPacketValidationError(cause);
|
|
2502
548
|
}
|
|
2503
549
|
function parseFailure(value) {
|
|
2504
|
-
if (!Array.isArray(value))
|
|
550
|
+
if (!Array.isArray(value)) fail(new Error("Fixer prerequisites must be a JSON array"));
|
|
2505
551
|
for (const entry of value) {
|
|
2506
552
|
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
2507
|
-
|
|
553
|
+
fail(new Error("Fixer prerequisite entry must be an object with id and requirement fields"));
|
|
2508
554
|
}
|
|
2509
555
|
const keys = Object.keys(entry);
|
|
2510
556
|
if (keys.length !== 2 || !keys.includes("id") || !keys.includes("requirement")) {
|
|
2511
|
-
|
|
557
|
+
fail(new Error("Fixer prerequisite entry fields must be exactly id and requirement"));
|
|
2512
558
|
}
|
|
2513
559
|
if (typeof entry.id !== "string" || !new RegExp(FIXER_PREREQUISITE_ID_PATTERN).test(entry.id)) {
|
|
2514
|
-
|
|
560
|
+
fail(new Error(`Fixer prerequisite id violates pattern ${FIXER_PREREQUISITE_ID_PATTERN}`));
|
|
2515
561
|
}
|
|
2516
562
|
if (typeof entry.requirement !== "string" || !/\S/.test(entry.requirement)) {
|
|
2517
|
-
|
|
563
|
+
fail(new Error("Fixer prerequisite requirement must be nonblank"));
|
|
2518
564
|
}
|
|
2519
565
|
}
|
|
2520
|
-
|
|
566
|
+
fail(new Error("Fixer prerequisites violate the attachment schema"));
|
|
2521
567
|
}
|
|
2522
568
|
function validateFixerPrerequisites(value) {
|
|
2523
569
|
if (!Value.Check(fixerPrerequisitesSchema, value)) parseFailure(value);
|
|
@@ -2525,7 +571,7 @@ function validateFixerPrerequisites(value) {
|
|
|
2525
571
|
const ids = /* @__PURE__ */ new Set();
|
|
2526
572
|
const prerequisites = entries.map((entry) => {
|
|
2527
573
|
if (ids.has(entry.id)) {
|
|
2528
|
-
|
|
574
|
+
fail(new Error(`Fixer prerequisites contain duplicate id: ${entry.id}`));
|
|
2529
575
|
}
|
|
2530
576
|
ids.add(entry.id);
|
|
2531
577
|
return Object.freeze({ id: entry.id, requirement: entry.requirement });
|
|
@@ -2537,7 +583,7 @@ function parseFixerPrerequisites(source) {
|
|
|
2537
583
|
try {
|
|
2538
584
|
decoded = JSON.parse(source);
|
|
2539
585
|
} catch (error) {
|
|
2540
|
-
|
|
586
|
+
fail(error);
|
|
2541
587
|
}
|
|
2542
588
|
return validateFixerPrerequisites(decoded);
|
|
2543
589
|
}
|
|
@@ -2716,7 +762,7 @@ var init_exact_utf8 = __esm({
|
|
|
2716
762
|
|
|
2717
763
|
// src/merger-contracts.ts
|
|
2718
764
|
import { Type as Type9 } from "typebox";
|
|
2719
|
-
function
|
|
765
|
+
function fail2(message = "Merger input violates its exact contract") {
|
|
2720
766
|
throw new MergerInputContractError(message);
|
|
2721
767
|
}
|
|
2722
768
|
function deepFreeze(value) {
|
|
@@ -2727,18 +773,18 @@ function deepFreeze(value) {
|
|
|
2727
773
|
return value;
|
|
2728
774
|
}
|
|
2729
775
|
function readMaterial(value, label) {
|
|
2730
|
-
if (!
|
|
776
|
+
if (!record(value) || typeof value.bytesBase64 !== "string") fail2(`Merger ${label} material is malformed`);
|
|
2731
777
|
exactUtf8(Buffer.from(value.bytesBase64, "base64"), `Merger ${label} material`);
|
|
2732
778
|
return { bytesBase64: value.bytesBase64, sha256: typeof value.sha256 === "string" ? value.sha256 : "" };
|
|
2733
779
|
}
|
|
2734
780
|
function validateMergerInput(value) {
|
|
2735
|
-
if (!
|
|
2736
|
-
if (!
|
|
781
|
+
if (!record(value) || blank(value.attemptId)) fail2("Merger input requires a non-empty attemptId for accounting");
|
|
782
|
+
if (!record(value.materials)) fail2("Merger materials are missing");
|
|
2737
783
|
const materials = { task: readMaterial(value.materials.task, "task"), authority: readMaterial(value.materials.authority, "authority"), targetIntent: readMaterial(value.materials.targetIntent, "targetIntent"), sourceIntent: readMaterial(value.materials.sourceIntent, "sourceIntent") };
|
|
2738
|
-
const authorizedChecks = Array.isArray(value.authorizedChecks) ? value.authorizedChecks.filter((check) =>
|
|
784
|
+
const authorizedChecks = Array.isArray(value.authorizedChecks) ? value.authorizedChecks.filter((check) => record(check)).map((c) => ({ name: asString(c.name), argv: asStringArray(c.argv).filter((a) => a.trim().length > 0) })).filter((c) => c.name.trim().length > 0 && c.argv.length > 0) : [];
|
|
2739
785
|
return deepFreeze(structuredClone({ attemptId: value.attemptId.trim(), targetObjectId: asString(value.targetObjectId), sourceObjectId: asString(value.sourceObjectId), materials, expectedConflictPaths: asStringArray(value.expectedConflictPaths), resolutionScope: asStringArray(value.resolutionScope), authorizedChecks }));
|
|
2740
786
|
}
|
|
2741
|
-
var materialSchema, checkSchema, mergerInputSchema, MERGER_STATUS_DESCRIPTION, mergerOutputVariants, mergerOutputSchema, MERGER_OUTPUT_TOOL_NAME,
|
|
787
|
+
var materialSchema, checkSchema, mergerInputSchema, MERGER_STATUS_DESCRIPTION, mergerOutputVariants, mergerOutputSchema, MERGER_OUTPUT_TOOL_NAME, record, blank, MergerInputContractError, asString, asStringArray;
|
|
2742
788
|
var init_merger_contracts = __esm({
|
|
2743
789
|
"src/merger-contracts.ts"() {
|
|
2744
790
|
"use strict";
|
|
@@ -2763,7 +809,7 @@ var init_merger_contracts = __esm({
|
|
|
2763
809
|
]);
|
|
2764
810
|
mergerOutputSchema = withTerminatingOutputDeclarations(openToolObjectFromUnion(mergerOutputVariants));
|
|
2765
811
|
MERGER_OUTPUT_TOOL_NAME = "ak_merger_output";
|
|
2766
|
-
|
|
812
|
+
record = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2767
813
|
blank = (v) => typeof v !== "string" || v.trim().length === 0;
|
|
2768
814
|
MergerInputContractError = class extends Error {
|
|
2769
815
|
constructor(message = "Merger input violates its exact contract") {
|
|
@@ -2856,7 +902,7 @@ var init_auditor_output = __esm({
|
|
|
2856
902
|
});
|
|
2857
903
|
|
|
2858
904
|
// src/ticket-provenance-contracts.ts
|
|
2859
|
-
function
|
|
905
|
+
function isRecord(value) {
|
|
2860
906
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2861
907
|
}
|
|
2862
908
|
function positiveInteger(value) {
|
|
@@ -2868,7 +914,7 @@ function positiveInteger(value) {
|
|
|
2868
914
|
return void 0;
|
|
2869
915
|
}
|
|
2870
916
|
function projectBound(value) {
|
|
2871
|
-
if (!
|
|
917
|
+
if (!isRecord(value)) return void 0;
|
|
2872
918
|
const id = typeof value.id === "string" && value.id !== "" ? value.id : void 0;
|
|
2873
919
|
const line2 = positiveInteger(value.line);
|
|
2874
920
|
if (id === void 0 && line2 === void 0) return void 0;
|
|
@@ -2879,13 +925,13 @@ function projectTicketProvenanceSessions(value) {
|
|
|
2879
925
|
if (value.length === 0) return [];
|
|
2880
926
|
const sessions = [];
|
|
2881
927
|
for (const raw of value) {
|
|
2882
|
-
if (!
|
|
928
|
+
if (!isRecord(raw)) return void 0;
|
|
2883
929
|
const path = raw.path;
|
|
2884
930
|
if (typeof path !== "string" || path.trim() === "") return void 0;
|
|
2885
931
|
if (!Array.isArray(raw.ranges) || raw.ranges.length === 0) return void 0;
|
|
2886
932
|
const ranges = [];
|
|
2887
933
|
for (const rawRange of raw.ranges) {
|
|
2888
|
-
if (!
|
|
934
|
+
if (!isRecord(rawRange)) return void 0;
|
|
2889
935
|
const from = projectBound(rawRange.from);
|
|
2890
936
|
const to = projectBound(rawRange.to);
|
|
2891
937
|
if (from === void 0 || to === void 0) return void 0;
|
|
@@ -2914,7 +960,7 @@ __export(run_ticket_number_exports, {
|
|
|
2914
960
|
readRunTicketNumber: () => readRunTicketNumber,
|
|
2915
961
|
requireSafePositiveTicketNumber: () => requireSafePositiveTicketNumber
|
|
2916
962
|
});
|
|
2917
|
-
import { readFile
|
|
963
|
+
import { readFile } from "node:fs/promises";
|
|
2918
964
|
import { join as join2 } from "node:path";
|
|
2919
965
|
function isEnoent(error) {
|
|
2920
966
|
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
@@ -2944,7 +990,7 @@ function ticketFromRecord(record4) {
|
|
|
2944
990
|
}
|
|
2945
991
|
async function readJsonObject(path) {
|
|
2946
992
|
try {
|
|
2947
|
-
const raw = JSON.parse(await
|
|
993
|
+
const raw = JSON.parse(await readFile(path, "utf8"));
|
|
2948
994
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
2949
995
|
return void 0;
|
|
2950
996
|
}
|
|
@@ -3290,7 +1336,6 @@ var init_packaged_role_registry = __esm({
|
|
|
3290
1336
|
"src/packaged-role-registry.ts"() {
|
|
3291
1337
|
"use strict";
|
|
3292
1338
|
init_collector_output();
|
|
3293
|
-
init_collector_ledger();
|
|
3294
1339
|
init_gatekeeper_output();
|
|
3295
1340
|
init_navigator_output();
|
|
3296
1341
|
init_judge_output();
|
|
@@ -3486,23 +1531,18 @@ var init_packaged_role_registry = __esm({
|
|
|
3486
1531
|
]
|
|
3487
1532
|
},
|
|
3488
1533
|
// ak-collector-repo is GitHub owner/repo identity, not a local material path (#438).
|
|
1534
|
+
// #1088: seat + request-manifest kept; code no longer collects — LLM uses host CLI.
|
|
3489
1535
|
{
|
|
3490
1536
|
role: "collector",
|
|
3491
1537
|
inCallAutoResume: false,
|
|
3492
1538
|
presentSettled: "always",
|
|
3493
1539
|
summonResume: false,
|
|
3494
1540
|
admission: "collect-target",
|
|
3495
|
-
/** Public no_receipt projects a durable bind-target rejection. */
|
|
3496
|
-
projectTargetBindRejection: true,
|
|
3497
1541
|
sameParent: "none",
|
|
3498
1542
|
phases: [null],
|
|
3499
1543
|
bareCommand: false,
|
|
3500
1544
|
outputTool: COLLECTOR_OUTPUT_TOOL,
|
|
3501
|
-
settlement: "
|
|
3502
|
-
/** #633: a prior wait-tool residual must not mask this attempt. */
|
|
3503
|
-
residualScan: "current-attempt",
|
|
3504
|
-
residualTool: COLLECTOR_WAIT_TOOL,
|
|
3505
|
-
runnerFailure: "collector-known-first",
|
|
1545
|
+
settlement: "sealed",
|
|
3506
1546
|
artifactFace: {
|
|
3507
1547
|
evidenceRole: true,
|
|
3508
1548
|
leaves: [
|
|
@@ -3517,11 +1557,14 @@ var init_packaged_role_registry = __esm({
|
|
|
3517
1557
|
activationFlags: [
|
|
3518
1558
|
{ field: "repo", from: "repository.display", flag: "ak-collector-repo" },
|
|
3519
1559
|
{ field: "pr", from: "prNumber", text: true, flag: "ak-collector-pr" },
|
|
3520
|
-
{ field: "requestManifestPath", flag: "ak-collector-request-manifest" }
|
|
3521
|
-
{ field: "waitMs", from: "waitWindowMs", text: true, flag: "ak-collector-wait-ms" }
|
|
1560
|
+
{ field: "requestManifestPath", flag: "ak-collector-request-manifest" }
|
|
3522
1561
|
],
|
|
3523
1562
|
activationStage: "load-and-install",
|
|
3524
|
-
sessionMaterials: [
|
|
1563
|
+
sessionMaterials: [
|
|
1564
|
+
"CLAUDE.md",
|
|
1565
|
+
"souls/collector.md",
|
|
1566
|
+
"resources/collector-bot-handbook.md"
|
|
1567
|
+
]
|
|
3525
1568
|
},
|
|
3526
1569
|
{
|
|
3527
1570
|
role: "doctor",
|
|
@@ -4340,15 +2383,15 @@ var init_sitian_appender = __esm({
|
|
|
4340
2383
|
|
|
4341
2384
|
// src/sitian-reader.ts
|
|
4342
2385
|
import { existsSync } from "node:fs";
|
|
4343
|
-
import { readFile as
|
|
4344
|
-
function
|
|
2386
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
2387
|
+
function isRecord2(value) {
|
|
4345
2388
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4346
2389
|
}
|
|
4347
2390
|
async function readSitianRecords(recordFile) {
|
|
4348
2391
|
if (!existsSync(recordFile)) {
|
|
4349
2392
|
return { records: [], diagnostics: [] };
|
|
4350
2393
|
}
|
|
4351
|
-
const text = await
|
|
2394
|
+
const text = await readFile2(recordFile, "utf8");
|
|
4352
2395
|
const lines = text.split("\n");
|
|
4353
2396
|
const records = [];
|
|
4354
2397
|
const diagnostics = [];
|
|
@@ -4357,7 +2400,7 @@ async function readSitianRecords(recordFile) {
|
|
|
4357
2400
|
if (!line2.trim()) continue;
|
|
4358
2401
|
try {
|
|
4359
2402
|
const parsed = JSON.parse(line2);
|
|
4360
|
-
if (
|
|
2403
|
+
if (isRecord2(parsed)) {
|
|
4361
2404
|
records.push(parsed);
|
|
4362
2405
|
} else {
|
|
4363
2406
|
const typeDesc = parsed === null ? "null" : Array.isArray(parsed) ? "array" : typeof parsed;
|
|
@@ -4490,7 +2533,7 @@ __export(run_terminal_artifacts_exports, {
|
|
|
4490
2533
|
readRunTerminalArtifact: () => readRunTerminalArtifact,
|
|
4491
2534
|
runIdFromRunDirectory: () => runIdFromRunDirectory
|
|
4492
2535
|
});
|
|
4493
|
-
import { readdir as readdir2, readFile as
|
|
2536
|
+
import { readdir as readdir2, readFile as readFile3 } from "node:fs/promises";
|
|
4494
2537
|
import { basename as basename3, dirname as dirname4, join as join6 } from "node:path";
|
|
4495
2538
|
function isMissingPathError2(error) {
|
|
4496
2539
|
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
@@ -4498,14 +2541,14 @@ function isMissingPathError2(error) {
|
|
|
4498
2541
|
function errorText2(error) {
|
|
4499
2542
|
return error instanceof Error ? error.message : String(error);
|
|
4500
2543
|
}
|
|
4501
|
-
function
|
|
2544
|
+
function isRecord3(value) {
|
|
4502
2545
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4503
2546
|
}
|
|
4504
2547
|
function readUsableTerminalArtifactBody(body) {
|
|
4505
2548
|
if (body === null) {
|
|
4506
2549
|
return { ok: false, reason: "terminal artifact JSON value is null" };
|
|
4507
2550
|
}
|
|
4508
|
-
if (!
|
|
2551
|
+
if (!isRecord3(body)) {
|
|
4509
2552
|
return {
|
|
4510
2553
|
ok: false,
|
|
4511
2554
|
reason: `terminal artifact JSON value is not a typed object (${Array.isArray(body) ? "array" : typeof body})`
|
|
@@ -4522,7 +2565,7 @@ function readUsableTerminalArtifactBody(body) {
|
|
|
4522
2565
|
async function readTerminalArtifactAtPath(path, file) {
|
|
4523
2566
|
let raw;
|
|
4524
2567
|
try {
|
|
4525
|
-
raw = await
|
|
2568
|
+
raw = await readFile3(path, "utf8");
|
|
4526
2569
|
} catch (error) {
|
|
4527
2570
|
if (isMissingPathError2(error)) return void 0;
|
|
4528
2571
|
return {
|
|
@@ -4677,7 +2720,7 @@ var init_cli_errors = __esm({
|
|
|
4677
2720
|
});
|
|
4678
2721
|
|
|
4679
2722
|
// src/typed-provider-http.ts
|
|
4680
|
-
import { readFile as
|
|
2723
|
+
import { readFile as readFile4, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
4681
2724
|
import { join as join7 } from "node:path";
|
|
4682
2725
|
function typedProviderHttpPath(runDirectory) {
|
|
4683
2726
|
return join7(runDirectory, TYPED_HTTP_FILE);
|
|
@@ -4711,31 +2754,109 @@ async function recordTypedProviderHttpStatus(runDirectory, observation) {
|
|
|
4711
2754
|
async function readLatestTypedProviderHttpObservation(runDirectory) {
|
|
4712
2755
|
let text;
|
|
4713
2756
|
try {
|
|
4714
|
-
text = await
|
|
2757
|
+
text = await readFile4(typedProviderHttpPath(runDirectory), "utf8");
|
|
2758
|
+
} catch (error) {
|
|
2759
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
2760
|
+
return void 0;
|
|
2761
|
+
}
|
|
2762
|
+
throw error;
|
|
2763
|
+
}
|
|
2764
|
+
const raw = JSON.parse(text);
|
|
2765
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
2766
|
+
throw new Error("typed provider HTTP observation must be a JSON object");
|
|
2767
|
+
}
|
|
2768
|
+
const record4 = raw;
|
|
2769
|
+
if (typeof record4.httpStatus !== "number") {
|
|
2770
|
+
throw new Error("typed provider HTTP observation missing numeric httpStatus");
|
|
2771
|
+
}
|
|
2772
|
+
if (typeof record4.provider !== "string" || record4.provider.trim() === "") {
|
|
2773
|
+
throw new Error("typed provider HTTP observation missing non-empty provider");
|
|
2774
|
+
}
|
|
2775
|
+
return { httpStatus: record4.httpStatus, provider: record4.provider };
|
|
2776
|
+
}
|
|
2777
|
+
var TYPED_HTTP_FILE;
|
|
2778
|
+
var init_typed_provider_http = __esm({
|
|
2779
|
+
"src/typed-provider-http.ts"() {
|
|
2780
|
+
"use strict";
|
|
2781
|
+
TYPED_HTTP_FILE = "typed-provider-http.json";
|
|
2782
|
+
}
|
|
2783
|
+
});
|
|
2784
|
+
|
|
2785
|
+
// src/collector-config.ts
|
|
2786
|
+
import { createHash } from "node:crypto";
|
|
2787
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
2788
|
+
function fail3(message, cause) {
|
|
2789
|
+
throw new Error(message, cause === void 0 ? void 0 : { cause });
|
|
2790
|
+
}
|
|
2791
|
+
function conservativeAscii(input) {
|
|
2792
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
2793
|
+
const code = input.charCodeAt(i);
|
|
2794
|
+
if (code <= 31 || code === 127 || code > 127) return false;
|
|
2795
|
+
}
|
|
2796
|
+
return true;
|
|
2797
|
+
}
|
|
2798
|
+
function parseCollectorRepository(raw) {
|
|
2799
|
+
if (typeof raw !== "string" || raw.trim() !== raw || raw.length === 0) fail3("Collector repository must be a string owner/repo");
|
|
2800
|
+
if (!conservativeAscii(raw) || raw.includes("://") || /[?#@%\\ ]/.test(raw)) fail3("Collector repository rejects URL syntax and non-identity bytes");
|
|
2801
|
+
const parts = raw.split("/");
|
|
2802
|
+
if (parts.length !== 2) fail3("Collector repository must contain exactly one '/' separating owner and repo");
|
|
2803
|
+
const [ownerDisplay, repoDisplay] = parts;
|
|
2804
|
+
if (!COLLECTOR_OWNER_PATTERN.test(ownerDisplay) || !COLLECTOR_REPO_PATTERN.test(repoDisplay)) fail3("Collector repository does not match the conservative owner/repo grammar");
|
|
2805
|
+
const owner = ownerDisplay.toLowerCase();
|
|
2806
|
+
const repo = repoDisplay.toLowerCase();
|
|
2807
|
+
return { display: raw, canonical: `${owner}/${repo}`, owner, repo };
|
|
2808
|
+
}
|
|
2809
|
+
function parseCollectorPrNumber(raw) {
|
|
2810
|
+
if (typeof raw === "string" && !/^[1-9][0-9]*$/.test(raw)) fail3("Collector pull request number must be a positive safe integer string");
|
|
2811
|
+
if (typeof raw !== "string" && typeof raw !== "number") fail3("Collector pull request number is required");
|
|
2812
|
+
const value = Number(raw);
|
|
2813
|
+
if (!Number.isSafeInteger(value) || value < 1) fail3("Collector pull request number must be a positive safe integer");
|
|
2814
|
+
return value;
|
|
2815
|
+
}
|
|
2816
|
+
function record2(value) {
|
|
2817
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2818
|
+
}
|
|
2819
|
+
function canonicalManifest(requests) {
|
|
2820
|
+
return `${JSON.stringify({ requests: requests.map((request) => ({ id: request.id, body: request.requestBody })) })}
|
|
2821
|
+
`;
|
|
2822
|
+
}
|
|
2823
|
+
function emptyCollectorManifest() {
|
|
2824
|
+
const canonicalJson2 = canonicalManifest([]);
|
|
2825
|
+
return { requests: [], canonicalJson: canonicalJson2, digest: createHash("sha256").update(canonicalJson2).digest("hex") };
|
|
2826
|
+
}
|
|
2827
|
+
async function loadCollectorManifest(path) {
|
|
2828
|
+
let bytes;
|
|
2829
|
+
try {
|
|
2830
|
+
bytes = await readFile5(path);
|
|
4715
2831
|
} catch (error) {
|
|
4716
|
-
|
|
4717
|
-
return void 0;
|
|
4718
|
-
}
|
|
4719
|
-
throw error;
|
|
4720
|
-
}
|
|
4721
|
-
const raw = JSON.parse(text);
|
|
4722
|
-
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
4723
|
-
throw new Error("typed provider HTTP observation must be a JSON object");
|
|
2832
|
+
fail3(`Collector request manifest is unreadable at ${path}`, error);
|
|
4724
2833
|
}
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
2834
|
+
let parsed;
|
|
2835
|
+
try {
|
|
2836
|
+
parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
2837
|
+
} catch (error) {
|
|
2838
|
+
fail3("Collector request manifest must be UTF-8 JSON", error);
|
|
4728
2839
|
}
|
|
4729
|
-
if (
|
|
4730
|
-
|
|
2840
|
+
if (!record2(parsed)) fail3("Collector request manifest must be an object");
|
|
2841
|
+
const rawRequests = parsed.requests ?? [];
|
|
2842
|
+
if (!Array.isArray(rawRequests)) fail3("Collector request manifest requests must be an array");
|
|
2843
|
+
const requests = [];
|
|
2844
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2845
|
+
for (const [index, item] of rawRequests.entries()) {
|
|
2846
|
+
if (!record2(item) || typeof item.id !== "string" || item.id.length === 0 || typeof item.body !== "string" || item.body.trim() === "") fail3(`Collector request manifest requests[${index}] is invalid`);
|
|
2847
|
+
if (ids.has(item.id)) fail3(`Collector request manifest has duplicate request id "${item.id}"`);
|
|
2848
|
+
ids.add(item.id);
|
|
2849
|
+
requests.push({ id: item.id, requestBody: item.body });
|
|
4731
2850
|
}
|
|
4732
|
-
|
|
2851
|
+
const canonicalJson2 = canonicalManifest(requests);
|
|
2852
|
+
return { requests, canonicalJson: canonicalJson2, digest: createHash("sha256").update(canonicalJson2).digest("hex"), sourcePath: path };
|
|
4733
2853
|
}
|
|
4734
|
-
var
|
|
4735
|
-
var
|
|
4736
|
-
"src/
|
|
2854
|
+
var COLLECTOR_OWNER_PATTERN, COLLECTOR_REPO_PATTERN;
|
|
2855
|
+
var init_collector_config = __esm({
|
|
2856
|
+
"src/collector-config.ts"() {
|
|
4737
2857
|
"use strict";
|
|
4738
|
-
|
|
2858
|
+
COLLECTOR_OWNER_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/;
|
|
2859
|
+
COLLECTOR_REPO_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,98}[A-Za-z0-9])?$/;
|
|
4739
2860
|
}
|
|
4740
2861
|
});
|
|
4741
2862
|
|
|
@@ -4790,6 +2911,92 @@ var init_auditor_dossier_tool = __esm({
|
|
|
4790
2911
|
}
|
|
4791
2912
|
});
|
|
4792
2913
|
|
|
2914
|
+
// src/readable-gate-item.ts
|
|
2915
|
+
var readable_gate_item_exports = {};
|
|
2916
|
+
__export(readable_gate_item_exports, {
|
|
2917
|
+
joinReadableGateItems: () => joinReadableGateItems,
|
|
2918
|
+
readableGateItem: () => readableGateItem
|
|
2919
|
+
});
|
|
2920
|
+
function readableGateItem(value) {
|
|
2921
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
2922
|
+
}
|
|
2923
|
+
function joinReadableGateItems(items, separator = "; ") {
|
|
2924
|
+
return items.map(readableGateItem).join(separator);
|
|
2925
|
+
}
|
|
2926
|
+
var init_readable_gate_item = __esm({
|
|
2927
|
+
"src/readable-gate-item.ts"() {
|
|
2928
|
+
"use strict";
|
|
2929
|
+
}
|
|
2930
|
+
});
|
|
2931
|
+
|
|
2932
|
+
// src/submission-errors.ts
|
|
2933
|
+
function serializeReceipt(receipt) {
|
|
2934
|
+
return readableGateItem(receipt);
|
|
2935
|
+
}
|
|
2936
|
+
function gatekeeperNonPassMessage(result) {
|
|
2937
|
+
if (result.status === "continue") {
|
|
2938
|
+
return serializeReceipt(result.receipt);
|
|
2939
|
+
}
|
|
2940
|
+
if (result.status === "transport_failure") {
|
|
2941
|
+
const head = `\u95E8\u4E0B\u7701 ${result.status}\uFF08${result.stage}\uFF09\uFF1A${result.reason}`;
|
|
2942
|
+
return result.submission === void 0 ? head : `${head}
|
|
2943
|
+
${serializeReceipt(result.submission)}`;
|
|
2944
|
+
}
|
|
2945
|
+
return `\u95E8\u4E0B\u7701 ${result.status}\uFF08${result.stage}\uFF09\uFF1A${result.reason}`;
|
|
2946
|
+
}
|
|
2947
|
+
function unreadableDiscriminatorNotice(field, received) {
|
|
2948
|
+
if (received === void 0) return `\u8BFB\u4E0D\u51FA ${field}`;
|
|
2949
|
+
return `\u8BFB\u4E0D\u51FA ${field}\uFF1A${readableGateItem(received)}`;
|
|
2950
|
+
}
|
|
2951
|
+
function receivedDiscriminator(receipt, field) {
|
|
2952
|
+
if (receipt === null || typeof receipt !== "object" || Array.isArray(receipt)) return void 0;
|
|
2953
|
+
if (!Object.hasOwn(receipt, field)) return void 0;
|
|
2954
|
+
return receipt[field];
|
|
2955
|
+
}
|
|
2956
|
+
var GatekeeperDecisionError, WorkerCommitReminderError, WorkerPrefixReminderError, WorkerUnfinishedReasonReminderError, ParentQueueReaskError;
|
|
2957
|
+
var init_submission_errors = __esm({
|
|
2958
|
+
"src/submission-errors.ts"() {
|
|
2959
|
+
"use strict";
|
|
2960
|
+
init_readable_gate_item();
|
|
2961
|
+
GatekeeperDecisionError = class extends Error {
|
|
2962
|
+
result;
|
|
2963
|
+
constructor(result, message) {
|
|
2964
|
+
super(message ?? gatekeeperNonPassMessage(result));
|
|
2965
|
+
this.name = "GatekeeperDecisionError";
|
|
2966
|
+
this.result = result;
|
|
2967
|
+
}
|
|
2968
|
+
};
|
|
2969
|
+
WorkerCommitReminderError = class extends Error {
|
|
2970
|
+
code = "worker_commit_reminder";
|
|
2971
|
+
constructor() {
|
|
2972
|
+
super("\u672A\u89C2\u5BDF\u5230 commit");
|
|
2973
|
+
this.name = "WorkerCommitReminderError";
|
|
2974
|
+
}
|
|
2975
|
+
};
|
|
2976
|
+
WorkerPrefixReminderError = class extends Error {
|
|
2977
|
+
code = "worker_prefix_reminder";
|
|
2978
|
+
constructor() {
|
|
2979
|
+
super("\u89C2\u5BDF\u5230\u7F3A\u524D\u7F00 commit");
|
|
2980
|
+
this.name = "WorkerPrefixReminderError";
|
|
2981
|
+
}
|
|
2982
|
+
};
|
|
2983
|
+
WorkerUnfinishedReasonReminderError = class extends Error {
|
|
2984
|
+
code = "worker_unfinished_reason_reminder";
|
|
2985
|
+
constructor() {
|
|
2986
|
+
super("\u672C\u6B21 unfinished \u56DE\u6267\u672A\u542B reason\uFF1B\u672C\u63A5\u7F1D\u7F3A\u7531\u81F3\u591A\u6253\u56DE\u4E24\u6B21\u3002");
|
|
2987
|
+
this.name = "WorkerUnfinishedReasonReminderError";
|
|
2988
|
+
}
|
|
2989
|
+
};
|
|
2990
|
+
ParentQueueReaskError = class extends Error {
|
|
2991
|
+
code = "parent_queue_reask";
|
|
2992
|
+
constructor(message) {
|
|
2993
|
+
super(message);
|
|
2994
|
+
this.name = "ParentQueueReaskError";
|
|
2995
|
+
}
|
|
2996
|
+
};
|
|
2997
|
+
}
|
|
2998
|
+
});
|
|
2999
|
+
|
|
4793
3000
|
// src/gatekeeper-role.ts
|
|
4794
3001
|
function gateSeatLabel(stage) {
|
|
4795
3002
|
return packagedGateStageLabel(stage) ?? stage;
|
|
@@ -5103,10 +3310,10 @@ __export(session_assistant_usage_exports, {
|
|
|
5103
3310
|
});
|
|
5104
3311
|
import { join as join9 } from "node:path";
|
|
5105
3312
|
async function readAssistantUsageFromSessionFile(sessionFile) {
|
|
5106
|
-
const { readFile:
|
|
3313
|
+
const { readFile: readFile25 } = await import("node:fs/promises");
|
|
5107
3314
|
let text;
|
|
5108
3315
|
try {
|
|
5109
|
-
text = await
|
|
3316
|
+
text = await readFile25(sessionFile, "utf8");
|
|
5110
3317
|
} catch (error) {
|
|
5111
3318
|
if (error?.code === "ENOENT") return void 0;
|
|
5112
3319
|
throw error;
|
|
@@ -5399,7 +3606,7 @@ __export(role_turn_host_exports, {
|
|
|
5399
3606
|
createPiRoleTurnHost: () => createPiRoleTurnHost,
|
|
5400
3607
|
resolveInternalRoleEntrypoint: () => resolveInternalRoleEntrypoint
|
|
5401
3608
|
});
|
|
5402
|
-
import { execFile, spawn as
|
|
3609
|
+
import { execFile, spawn as spawn2 } from "node:child_process";
|
|
5403
3610
|
import { constants } from "node:fs";
|
|
5404
3611
|
import { access, appendFile, readFile as readFile6, realpath } from "node:fs/promises";
|
|
5405
3612
|
import { delimiter, dirname as dirname6, isAbsolute as isAbsolute3, join as join12, resolve as resolve4 } from "node:path";
|
|
@@ -5509,7 +3716,7 @@ function createDefaultPiSpawnRunner(options) {
|
|
|
5509
3716
|
const command = spawnOptions.env.PI_BINARY ?? "pi";
|
|
5510
3717
|
const piIdentity = await selectedPiIdentity(command, spawnOptions.cwd, spawnOptions.env);
|
|
5511
3718
|
return await new Promise((resolveResult, reject) => {
|
|
5512
|
-
const child =
|
|
3719
|
+
const child = spawn2(piIdentity.executable, [...args], {
|
|
5513
3720
|
cwd: spawnOptions.cwd,
|
|
5514
3721
|
env: spawnOptions.env,
|
|
5515
3722
|
stdio: ["pipe", "ignore", "pipe"]
|
|
@@ -5805,9 +4012,9 @@ var init_host_descriptions = __esm({
|
|
|
5805
4012
|
});
|
|
5806
4013
|
|
|
5807
4014
|
// src/sha256.ts
|
|
5808
|
-
import { createHash as
|
|
4015
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
5809
4016
|
function sha256Hex(bytes) {
|
|
5810
|
-
return
|
|
4017
|
+
return createHash2("sha256").update(bytes).digest("hex");
|
|
5811
4018
|
}
|
|
5812
4019
|
var init_sha256 = __esm({
|
|
5813
4020
|
"src/sha256.ts"() {
|
|
@@ -5815,6 +4022,43 @@ var init_sha256 = __esm({
|
|
|
5815
4022
|
}
|
|
5816
4023
|
});
|
|
5817
4024
|
|
|
4025
|
+
// src/submission-correctable-error.ts
|
|
4026
|
+
function isCorrectableSubmissionError(error) {
|
|
4027
|
+
return error instanceof CorrectableSubmissionError;
|
|
4028
|
+
}
|
|
4029
|
+
function isCorrectableExecuteError(error) {
|
|
4030
|
+
return isCorrectableSubmissionError(error) || error instanceof GatekeeperDecisionError || error instanceof ParentQueueReaskError || error instanceof WorkerCommitReminderError || error instanceof WorkerPrefixReminderError || error instanceof WorkerUnfinishedReasonReminderError;
|
|
4031
|
+
}
|
|
4032
|
+
function projectCorrectableExecuteRejection(error) {
|
|
4033
|
+
const diagnostic = error instanceof Error ? error.message : String(error);
|
|
4034
|
+
if (error instanceof GatekeeperDecisionError) {
|
|
4035
|
+
return { diagnostic, details: { ...error.result } };
|
|
4036
|
+
}
|
|
4037
|
+
if (error instanceof WorkerCommitReminderError || error instanceof WorkerPrefixReminderError || error instanceof WorkerUnfinishedReasonReminderError) {
|
|
4038
|
+
return { diagnostic, details: { code: error.code } };
|
|
4039
|
+
}
|
|
4040
|
+
if (typeof error.code === "string") {
|
|
4041
|
+
return { diagnostic, details: { code: error.code } };
|
|
4042
|
+
}
|
|
4043
|
+
return {
|
|
4044
|
+
diagnostic,
|
|
4045
|
+
details: {
|
|
4046
|
+
code: error instanceof Error && error.name ? error.name : "correctable-submission-error"
|
|
4047
|
+
}
|
|
4048
|
+
};
|
|
4049
|
+
}
|
|
4050
|
+
var correctableSubmissionErrorBrand, CorrectableSubmissionError;
|
|
4051
|
+
var init_submission_correctable_error = __esm({
|
|
4052
|
+
"src/submission-correctable-error.ts"() {
|
|
4053
|
+
"use strict";
|
|
4054
|
+
init_submission_errors();
|
|
4055
|
+
correctableSubmissionErrorBrand = /* @__PURE__ */ Symbol("ak-roles.correctable-submission-error");
|
|
4056
|
+
CorrectableSubmissionError = class extends Error {
|
|
4057
|
+
[correctableSubmissionErrorBrand] = true;
|
|
4058
|
+
};
|
|
4059
|
+
}
|
|
4060
|
+
});
|
|
4061
|
+
|
|
5818
4062
|
// src/package-contracts/terminating-tools.ts
|
|
5819
4063
|
function isTerminatingToolName(name) {
|
|
5820
4064
|
return TERMINATING_TOOL_NAMES.includes(name);
|
|
@@ -6020,11 +4264,6 @@ var init_doctor_evidence = __esm({
|
|
|
6020
4264
|
});
|
|
6021
4265
|
|
|
6022
4266
|
// src/public-cli/github-remote.ts
|
|
6023
|
-
function ownerFromGitHubRemoteUrl(remoteUrl) {
|
|
6024
|
-
const ownerRepo = ownerRepoFromGitHubRemoteUrl(remoteUrl);
|
|
6025
|
-
if (ownerRepo === void 0) return void 0;
|
|
6026
|
-
return ownerRepo.split("/")[0].toLowerCase();
|
|
6027
|
-
}
|
|
6028
4267
|
function ownerRepoFromGitHubRemoteUrl(remoteUrl) {
|
|
6029
4268
|
const trimmed = remoteUrl.trim();
|
|
6030
4269
|
const scp = /^git@github\.com:([^/\s]+)\/([^/\s]+?)(?:\.git)?$/i.exec(trimmed);
|
|
@@ -6058,143 +4297,6 @@ var init_github_remote = __esm({
|
|
|
6058
4297
|
}
|
|
6059
4298
|
});
|
|
6060
4299
|
|
|
6061
|
-
// src/collector-target.ts
|
|
6062
|
-
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
6063
|
-
function ambiguousTarget(detail, cause) {
|
|
6064
|
-
throw new CliUsageError(
|
|
6065
|
-
`collector target is ambiguous: ${detail}; pass an explicit --pr`,
|
|
6066
|
-
cause === void 0 ? void 0 : { cause }
|
|
6067
|
-
);
|
|
6068
|
-
}
|
|
6069
|
-
function gitFailure(detail, cause) {
|
|
6070
|
-
throw new Error(`collector git failed: ${detail}`, {
|
|
6071
|
-
cause: cause instanceof Error ? cause : new Error(String(cause))
|
|
6072
|
-
});
|
|
6073
|
-
}
|
|
6074
|
-
function gitText(projectRoot, args) {
|
|
6075
|
-
return execFileSync2("git", [...args], {
|
|
6076
|
-
cwd: projectRoot,
|
|
6077
|
-
encoding: "utf8",
|
|
6078
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
6079
|
-
}).trim();
|
|
6080
|
-
}
|
|
6081
|
-
function isGitConfigMissing(error) {
|
|
6082
|
-
if (typeof error !== "object" || error === null) return false;
|
|
6083
|
-
const status = error.status;
|
|
6084
|
-
return status === 1;
|
|
6085
|
-
}
|
|
6086
|
-
function readCurrentBranch(projectRoot) {
|
|
6087
|
-
try {
|
|
6088
|
-
return gitText(projectRoot, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
6089
|
-
} catch (error) {
|
|
6090
|
-
gitFailure("cannot read current git branch", error);
|
|
6091
|
-
}
|
|
6092
|
-
}
|
|
6093
|
-
function readHeadSha(projectRoot) {
|
|
6094
|
-
try {
|
|
6095
|
-
return gitText(projectRoot, ["rev-parse", "HEAD"]);
|
|
6096
|
-
} catch (error) {
|
|
6097
|
-
gitFailure("cannot read current HEAD", error);
|
|
6098
|
-
}
|
|
6099
|
-
}
|
|
6100
|
-
function headRefFromMerge(merge) {
|
|
6101
|
-
const trimmed = merge.trim();
|
|
6102
|
-
if (trimmed.length === 0) return void 0;
|
|
6103
|
-
if (trimmed.startsWith("refs/heads/")) {
|
|
6104
|
-
const ref = trimmed.slice("refs/heads/".length);
|
|
6105
|
-
return ref.length > 0 ? ref : void 0;
|
|
6106
|
-
}
|
|
6107
|
-
if (trimmed.startsWith("refs/")) return void 0;
|
|
6108
|
-
return trimmed;
|
|
6109
|
-
}
|
|
6110
|
-
function readUpstreamHeadBinding(projectRoot, branch) {
|
|
6111
|
-
let remote;
|
|
6112
|
-
try {
|
|
6113
|
-
remote = gitText(projectRoot, ["config", "--get", `branch.${branch}.remote`]);
|
|
6114
|
-
} catch (error) {
|
|
6115
|
-
if (isGitConfigMissing(error)) remote = void 0;
|
|
6116
|
-
else gitFailure(`cannot read branch.${branch}.remote`, error);
|
|
6117
|
-
}
|
|
6118
|
-
if (remote === void 0 || remote.length === 0) return void 0;
|
|
6119
|
-
let merge;
|
|
6120
|
-
try {
|
|
6121
|
-
merge = gitText(projectRoot, ["config", "--get", `branch.${branch}.merge`]);
|
|
6122
|
-
} catch (error) {
|
|
6123
|
-
if (isGitConfigMissing(error)) merge = void 0;
|
|
6124
|
-
else gitFailure(`cannot read branch.${branch}.merge`, error);
|
|
6125
|
-
}
|
|
6126
|
-
if (merge === void 0 || merge.length === 0) return void 0;
|
|
6127
|
-
const headRef = headRefFromMerge(merge);
|
|
6128
|
-
if (headRef === void 0) return void 0;
|
|
6129
|
-
let remoteUrl;
|
|
6130
|
-
try {
|
|
6131
|
-
remoteUrl = gitText(projectRoot, ["remote", "get-url", remote]);
|
|
6132
|
-
} catch (error) {
|
|
6133
|
-
gitFailure(`cannot read remote URL for ${remote}`, error);
|
|
6134
|
-
}
|
|
6135
|
-
const headOwner = ownerFromGitHubRemoteUrl(remoteUrl);
|
|
6136
|
-
if (headOwner === void 0) return void 0;
|
|
6137
|
-
return { headOwner, headRef };
|
|
6138
|
-
}
|
|
6139
|
-
async function resolveCollectorTarget(input) {
|
|
6140
|
-
if (input.explicitPrNumber !== void 0) {
|
|
6141
|
-
return { kind: "bound", prNumber: input.explicitPrNumber };
|
|
6142
|
-
}
|
|
6143
|
-
const branch = readCurrentBranch(input.projectRoot);
|
|
6144
|
-
const detached = branch.length === 0 || branch === "HEAD";
|
|
6145
|
-
const runner = createGhApiRunner();
|
|
6146
|
-
const { owner, repo } = input.repository;
|
|
6147
|
-
const numbers = [];
|
|
6148
|
-
if (!detached) {
|
|
6149
|
-
const headSha = readHeadSha(input.projectRoot);
|
|
6150
|
-
const upstream = readUpstreamHeadBinding(input.projectRoot, branch);
|
|
6151
|
-
if (upstream !== void 0) {
|
|
6152
|
-
numbers.push(
|
|
6153
|
-
...await listPullRequestNumbersByHead(runner, {
|
|
6154
|
-
owner,
|
|
6155
|
-
repo,
|
|
6156
|
-
headOwner: upstream.headOwner,
|
|
6157
|
-
headRef: upstream.headRef
|
|
6158
|
-
})
|
|
6159
|
-
);
|
|
6160
|
-
}
|
|
6161
|
-
numbers.push(
|
|
6162
|
-
...await listPullRequestNumbersByCommit(runner, {
|
|
6163
|
-
owner,
|
|
6164
|
-
repo,
|
|
6165
|
-
commitSha: headSha
|
|
6166
|
-
})
|
|
6167
|
-
);
|
|
6168
|
-
} else {
|
|
6169
|
-
const headSha = readHeadSha(input.projectRoot);
|
|
6170
|
-
numbers.push(
|
|
6171
|
-
...await listPullRequestNumbersByCommit(runner, {
|
|
6172
|
-
owner,
|
|
6173
|
-
repo,
|
|
6174
|
-
commitSha: headSha
|
|
6175
|
-
})
|
|
6176
|
-
);
|
|
6177
|
-
}
|
|
6178
|
-
const unique = [...new Set(numbers)];
|
|
6179
|
-
if (unique.length === 1) {
|
|
6180
|
-
return { kind: "bound", prNumber: unique[0] };
|
|
6181
|
-
}
|
|
6182
|
-
if (unique.length > 1) {
|
|
6183
|
-
ambiguousTarget(
|
|
6184
|
-
`multiple PRs associated with context: ${unique.join(", ")}`
|
|
6185
|
-
);
|
|
6186
|
-
}
|
|
6187
|
-
return { kind: "unbound" };
|
|
6188
|
-
}
|
|
6189
|
-
var init_collector_target = __esm({
|
|
6190
|
-
"src/collector-target.ts"() {
|
|
6191
|
-
"use strict";
|
|
6192
|
-
init_collector_github();
|
|
6193
|
-
init_cli_errors();
|
|
6194
|
-
init_github_remote();
|
|
6195
|
-
}
|
|
6196
|
-
});
|
|
6197
|
-
|
|
6198
4300
|
// src/git-object-id.ts
|
|
6199
4301
|
function isFullGitObjectId(value) {
|
|
6200
4302
|
return typeof value === "string" && FULL_GIT_OBJECT_ID_RE.test(value);
|
|
@@ -6307,7 +4409,7 @@ var init_merger_git_state = __esm({
|
|
|
6307
4409
|
|
|
6308
4410
|
// src/ledger-session-read.ts
|
|
6309
4411
|
import { readFile as readFile9 } from "node:fs/promises";
|
|
6310
|
-
function
|
|
4412
|
+
function isRecord4(value) {
|
|
6311
4413
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6312
4414
|
}
|
|
6313
4415
|
async function readLedgerSessionJsonlLines(path) {
|
|
@@ -6332,7 +4434,7 @@ async function readLedgerSessionJsonlLines(path) {
|
|
|
6332
4434
|
});
|
|
6333
4435
|
continue;
|
|
6334
4436
|
}
|
|
6335
|
-
if (!
|
|
4437
|
+
if (!isRecord4(row)) {
|
|
6336
4438
|
const kind = row === null ? "null" : Array.isArray(row) ? "array" : typeof row;
|
|
6337
4439
|
out.push({
|
|
6338
4440
|
line: lineNumber,
|
|
@@ -6385,7 +4487,7 @@ function extractSessionModelSequence(rows) {
|
|
|
6385
4487
|
if (row.type === "model_change" && typeof row.modelId === "string") {
|
|
6386
4488
|
push(row.modelId);
|
|
6387
4489
|
}
|
|
6388
|
-
const message =
|
|
4490
|
+
const message = isRecord4(row.message) ? row.message : void 0;
|
|
6389
4491
|
if (message?.role === "assistant" && typeof message.model === "string") {
|
|
6390
4492
|
push(message.model);
|
|
6391
4493
|
}
|
|
@@ -6401,11 +4503,11 @@ function extractSessionToolIntervals(rows) {
|
|
|
6401
4503
|
const openById = /* @__PURE__ */ new Map();
|
|
6402
4504
|
for (const row of rows) {
|
|
6403
4505
|
const rowTimestamp = typeof row.timestamp === "string" ? row.timestamp : void 0;
|
|
6404
|
-
const message =
|
|
4506
|
+
const message = isRecord4(row.message) ? row.message : void 0;
|
|
6405
4507
|
if (message?.role === "assistant" && Array.isArray(message.content)) {
|
|
6406
4508
|
const callTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
|
|
6407
4509
|
for (const part of message.content) {
|
|
6408
|
-
if (!
|
|
4510
|
+
if (!isRecord4(part) || part.type !== "toolCall") continue;
|
|
6409
4511
|
if (typeof part.id !== "string" || part.id.length === 0) {
|
|
6410
4512
|
throw new Error("toolCall frame missing string id");
|
|
6411
4513
|
}
|
|
@@ -6418,7 +4520,7 @@ function extractSessionToolIntervals(rows) {
|
|
|
6418
4520
|
if (openById.has(part.id)) {
|
|
6419
4521
|
throw new Error(`duplicate toolCall id ${part.id}`);
|
|
6420
4522
|
}
|
|
6421
|
-
const args =
|
|
4523
|
+
const args = isRecord4(part.arguments) ? part.arguments : void 0;
|
|
6422
4524
|
const command = part.name === "bash" && args !== void 0 && typeof args.command === "string" ? bashCommandFirstLine(args.command) : void 0;
|
|
6423
4525
|
const interval = {
|
|
6424
4526
|
toolCallId: part.id,
|
|
@@ -6502,7 +4604,7 @@ var init_ledger_session_read = __esm({
|
|
|
6502
4604
|
});
|
|
6503
4605
|
|
|
6504
4606
|
// src/session-dialogue.ts
|
|
6505
|
-
function
|
|
4607
|
+
function isRecord5(value) {
|
|
6506
4608
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6507
4609
|
}
|
|
6508
4610
|
function nativeEventId(row) {
|
|
@@ -6512,7 +4614,7 @@ function nativeEventId(row) {
|
|
|
6512
4614
|
}
|
|
6513
4615
|
for (const nestKey of ["message", "payload"]) {
|
|
6514
4616
|
const nested = row[nestKey];
|
|
6515
|
-
if (!
|
|
4617
|
+
if (!isRecord5(nested)) continue;
|
|
6516
4618
|
for (const key of ["uuid", "id"]) {
|
|
6517
4619
|
const value = nested[key];
|
|
6518
4620
|
if (typeof value === "string" && value !== "") return value;
|
|
@@ -6525,19 +4627,19 @@ function textParts(content) {
|
|
|
6525
4627
|
if (!Array.isArray(content)) return [];
|
|
6526
4628
|
const out = [];
|
|
6527
4629
|
for (const part of content) {
|
|
6528
|
-
if (!
|
|
4630
|
+
if (!isRecord5(part) || !SPEAKER_TEXT_PART_TYPES.has(String(part.type))) continue;
|
|
6529
4631
|
const text = part.text;
|
|
6530
4632
|
if (typeof text === "string" && text !== "") out.push(text);
|
|
6531
4633
|
}
|
|
6532
4634
|
return out;
|
|
6533
4635
|
}
|
|
6534
4636
|
function responseItemMessage(row) {
|
|
6535
|
-
if (row.type !== "response_item" || !
|
|
4637
|
+
if (row.type !== "response_item" || !isRecord5(row.payload)) return void 0;
|
|
6536
4638
|
if (row.payload.type !== "message") return void 0;
|
|
6537
4639
|
return row.payload;
|
|
6538
4640
|
}
|
|
6539
4641
|
function messageBody(row) {
|
|
6540
|
-
if (
|
|
4642
|
+
if (isRecord5(row.message)) return row.message;
|
|
6541
4643
|
return responseItemMessage(row);
|
|
6542
4644
|
}
|
|
6543
4645
|
function speakerOf(message) {
|
|
@@ -6547,7 +4649,7 @@ function speakerOf(message) {
|
|
|
6547
4649
|
}
|
|
6548
4650
|
function codexContentItemKinds(message) {
|
|
6549
4651
|
const pass = message.internal_chat_message_metadata_passthrough;
|
|
6550
|
-
if (!
|
|
4652
|
+
if (!isRecord5(pass) || !Array.isArray(pass.content_item_kinds)) return void 0;
|
|
6551
4653
|
const kinds = [];
|
|
6552
4654
|
for (const kind of pass.content_item_kinds) {
|
|
6553
4655
|
if (typeof kind === "string" && kind !== "") kinds.push(kind);
|
|
@@ -6576,7 +4678,7 @@ function isFixedNonOwnerEnqueueShape(content) {
|
|
|
6576
4678
|
return hasFixedOpenTagPrefix(content, TASK_NOTIFICATION_OPEN_TAG);
|
|
6577
4679
|
}
|
|
6578
4680
|
function materializationOriginKind(row) {
|
|
6579
|
-
if (!
|
|
4681
|
+
if (!isRecord5(row.origin)) return void 0;
|
|
6580
4682
|
const kind = row.origin.kind;
|
|
6581
4683
|
return typeof kind === "string" && kind !== "" ? kind : void 0;
|
|
6582
4684
|
}
|
|
@@ -7658,13 +5760,12 @@ var init_option_definitions = __esm({
|
|
|
7658
5760
|
canonical: "--pr",
|
|
7659
5761
|
aliases: [],
|
|
7660
5762
|
valueMetavar: "number",
|
|
7661
|
-
// #676 D1: optional when context uniquely determines the PR; ambiguous → require explicit.
|
|
7662
5763
|
required: false,
|
|
7663
5764
|
repeatable: false,
|
|
7664
5765
|
form: "option",
|
|
7665
5766
|
description: {
|
|
7666
|
-
en: "Positive GitHub pull request number. Optional when
|
|
7667
|
-
zh: "\u6B63\u6574\u6570 GitHub PR \u53F7\u3002\
|
|
5767
|
+
en: "Positive GitHub pull request number. Optional when the Collector role locates the PR via host CLI from task materials.",
|
|
5768
|
+
zh: "\u6B63\u6574\u6570 GitHub PR \u53F7\u3002\u53EF\u9009\uFF1B\u7701\u7565\u65F6\u7531\u901A\u8FDB\u53F8\u7ECF\u5BBF\u4E3B CLI \u4ECE\u4EFB\u52A1\u6750\u6599\u81EA\u884C\u5B9A\u4F4D\u3002"
|
|
7668
5769
|
}
|
|
7669
5770
|
},
|
|
7670
5771
|
{
|
|
@@ -7691,22 +5792,8 @@ var init_option_definitions = __esm({
|
|
|
7691
5792
|
repeatable: false,
|
|
7692
5793
|
form: "option",
|
|
7693
5794
|
description: {
|
|
7694
|
-
en: "Optional request manifest JSON path ({requests:[{id,body}]}).
|
|
7695
|
-
zh: "\u53EF\u9009 request manifest JSON \u8DEF\u5F84\uFF08{requests:[{id,body}]}\uFF09\u3002\
|
|
7696
|
-
}
|
|
7697
|
-
},
|
|
7698
|
-
{
|
|
7699
|
-
id: "wait-ms",
|
|
7700
|
-
owner: "collector",
|
|
7701
|
-
canonical: "--wait-ms",
|
|
7702
|
-
aliases: [],
|
|
7703
|
-
valueMetavar: "ms",
|
|
7704
|
-
required: false,
|
|
7705
|
-
repeatable: false,
|
|
7706
|
-
form: "option",
|
|
7707
|
-
description: {
|
|
7708
|
-
en: "Wait-window duration in milliseconds after the work step opens (default 600000 = 10 minutes). Does not require a code change to adjust.",
|
|
7709
|
-
zh: "\u5DE5\u4F5C\u6B65\u9AA4\u5F00\u542F\u540E\u7684\u7B49\u5F85\u7A97\u65F6\u957F\uFF08\u6BEB\u79D2\uFF1B\u9ED8\u8BA4 600000\uFF1D\u5341\u5206\u949F\uFF09\u3002\u6539\u914D\u7F6E\u5373\u53EF\uFF0C\u65E0\u9700\u6539\u4EE3\u7801\u3002"
|
|
5795
|
+
en: "Optional request manifest JSON path ({requests:[{id,body}]}). Parsed for semantics and passed to the Collector as materials \u2014 not a machine collection directive.",
|
|
5796
|
+
zh: "\u53EF\u9009 request manifest JSON \u8DEF\u5F84\uFF08{requests:[{id,body}]}\uFF09\u3002\u6309\u8BED\u4E49\u89E3\u6790\u540E\u4F5C\u4E3A\u6750\u6599\u9012\u7ED9\u901A\u8FDB\u53F8\uFF0C\u4E0D\u662F\u673A\u5668\u4EE3\u6536 finding \u7684\u6307\u4EE4\u3002"
|
|
7710
5797
|
}
|
|
7711
5798
|
}
|
|
7712
5799
|
];
|
|
@@ -8162,7 +6249,7 @@ var init_option_definitions = __esm({
|
|
|
8162
6249
|
});
|
|
8163
6250
|
|
|
8164
6251
|
// src/public-cli/invocation.ts
|
|
8165
|
-
import { execFileSync as
|
|
6252
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
8166
6253
|
import { existsSync as existsSync3 } from "node:fs";
|
|
8167
6254
|
import {
|
|
8168
6255
|
lstat as lstat3,
|
|
@@ -8562,17 +6649,6 @@ function assignPublicSeatOption(owner, taken, fields) {
|
|
|
8562
6649
|
case "request-manifest":
|
|
8563
6650
|
fields.requestManifestPath = requireOptionPath(taken.def.canonical, value);
|
|
8564
6651
|
return;
|
|
8565
|
-
case "wait-ms": {
|
|
8566
|
-
if (value === void 0 || !/^[1-9]\d*$/.test(value.trim())) {
|
|
8567
|
-
throw new CliUsageError("--wait-ms requires a positive safe-integer millisecond value");
|
|
8568
|
-
}
|
|
8569
|
-
const parsed = Number(value.trim());
|
|
8570
|
-
if (!Number.isSafeInteger(parsed) || parsed < 1) {
|
|
8571
|
-
throw new CliUsageError("--wait-ms requires a positive safe-integer millisecond value");
|
|
8572
|
-
}
|
|
8573
|
-
fields.waitWindowMs = parsed;
|
|
8574
|
-
return;
|
|
8575
|
-
}
|
|
8576
6652
|
case "issue": {
|
|
8577
6653
|
if (value === void 0 || value.trim() === "") {
|
|
8578
6654
|
throw new CliUsageError("doctor --issue requires a positive integer");
|
|
@@ -8669,7 +6745,6 @@ function parsePublicSeatArgv(owner, args) {
|
|
|
8669
6745
|
...fields.prNumber === void 0 ? {} : { prNumber: fields.prNumber },
|
|
8670
6746
|
...fields.repo === void 0 ? {} : { repo: fields.repo },
|
|
8671
6747
|
...fields.requestManifestPath === void 0 ? {} : { requestManifestPath: fields.requestManifestPath },
|
|
8672
|
-
...fields.waitWindowMs === void 0 ? {} : { waitWindowMs: fields.waitWindowMs },
|
|
8673
6748
|
...fields.issueNumber === void 0 ? {} : { issueNumber: fields.issueNumber },
|
|
8674
6749
|
...fields.runs === void 0 ? {} : { runs: fields.runs },
|
|
8675
6750
|
...fields.sourceRun === void 0 ? {} : { sourceRun: fields.sourceRun },
|
|
@@ -9029,23 +7104,16 @@ async function admitPublicRole(role, parsed, env, override) {
|
|
|
9029
7104
|
attachmentPaths,
|
|
9030
7105
|
...project,
|
|
9031
7106
|
placedFields: async (placed) => {
|
|
9032
|
-
const target = await resolveCollectorTarget({
|
|
9033
|
-
projectRoot,
|
|
9034
|
-
repository,
|
|
9035
|
-
...explicitPrNumber === void 0 ? {} : { explicitPrNumber }
|
|
9036
|
-
});
|
|
9037
|
-
const prNumber = target.kind === "bound" ? target.prNumber : void 0;
|
|
9038
7107
|
let requestManifestPath;
|
|
9039
7108
|
if (manifestCanonicalJson !== void 0) {
|
|
9040
7109
|
requestManifestPath = join15(placed.runDirectory, "request-manifest.json");
|
|
9041
7110
|
await writeFile3(requestManifestPath, manifestCanonicalJson, "utf8");
|
|
9042
7111
|
}
|
|
9043
7112
|
return {
|
|
9044
|
-
...
|
|
7113
|
+
...explicitPrNumber === void 0 ? {} : { prNumber: explicitPrNumber },
|
|
9045
7114
|
repository: repository.canonical,
|
|
9046
7115
|
repositoryDisplay: repository.display,
|
|
9047
7116
|
...requestManifestPath === void 0 ? {} : { requestManifestPath },
|
|
9048
|
-
...parsed.waitWindowMs === void 0 ? {} : { waitWindowMs: parsed.waitWindowMs },
|
|
9049
7117
|
manifestDigest
|
|
9050
7118
|
};
|
|
9051
7119
|
}
|
|
@@ -9499,7 +7567,7 @@ function parseRepoOption(raw) {
|
|
|
9499
7567
|
function resolveGitHubRemoteRepository(projectRoot) {
|
|
9500
7568
|
let remoteUrl;
|
|
9501
7569
|
try {
|
|
9502
|
-
remoteUrl =
|
|
7570
|
+
remoteUrl = execFileSync2("git", ["remote", "get-url", "origin"], {
|
|
9503
7571
|
cwd: projectRoot,
|
|
9504
7572
|
encoding: "utf8",
|
|
9505
7573
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -9643,11 +7711,11 @@ function parseAnalystCohortIssueToken(raw, flag) {
|
|
|
9643
7711
|
`${flag} requires a comma-separated list of N or book:N`
|
|
9644
7712
|
);
|
|
9645
7713
|
}
|
|
9646
|
-
const
|
|
9647
|
-
if (
|
|
9648
|
-
const rhs = trimmed.slice(
|
|
7714
|
+
const sep6 = trimmed.lastIndexOf(":");
|
|
7715
|
+
if (sep6 > 0) {
|
|
7716
|
+
const rhs = trimmed.slice(sep6 + 1);
|
|
9649
7717
|
if (ANALYST_TICKET_NUMBER_PATTERN.test(rhs)) {
|
|
9650
|
-
const bookKey = trimmed.slice(0,
|
|
7718
|
+
const bookKey = trimmed.slice(0, sep6);
|
|
9651
7719
|
if (bookKey.trim() === "") {
|
|
9652
7720
|
throw new CliUsageError(
|
|
9653
7721
|
`${flag} book:N requires a non-empty book key, got ${raw}`
|
|
@@ -9851,7 +7919,6 @@ var init_invocation = __esm({
|
|
|
9851
7919
|
init_doctor_evidence();
|
|
9852
7920
|
init_diarist_contracts();
|
|
9853
7921
|
init_collector_config();
|
|
9854
|
-
init_collector_target();
|
|
9855
7922
|
init_github_remote();
|
|
9856
7923
|
init_fixer_packet();
|
|
9857
7924
|
init_merger_git_state();
|
|
@@ -10757,7 +8824,7 @@ var init_host_providers = __esm({
|
|
|
10757
8824
|
// src/analyst-gate-cycles-read.ts
|
|
10758
8825
|
import { readdir as readdir4 } from "node:fs/promises";
|
|
10759
8826
|
import { join as join20 } from "node:path";
|
|
10760
|
-
function
|
|
8827
|
+
function isRecord6(value) {
|
|
10761
8828
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10762
8829
|
}
|
|
10763
8830
|
function isParentAttemptBindingRow(row) {
|
|
@@ -10787,7 +8854,7 @@ function isGateTerminatingToolName(toolName) {
|
|
|
10787
8854
|
function acceptedGateReceiptIds(rows) {
|
|
10788
8855
|
const accepted = /* @__PURE__ */ new Set();
|
|
10789
8856
|
for (const row of rows) {
|
|
10790
|
-
const message =
|
|
8857
|
+
const message = isRecord6(row.message) ? row.message : void 0;
|
|
10791
8858
|
if (message?.role !== "toolResult") continue;
|
|
10792
8859
|
if (typeof message.toolCallId !== "string" || message.toolCallId.length === 0) continue;
|
|
10793
8860
|
if (message.isError === false) accepted.add(message.toolCallId);
|
|
@@ -10822,7 +8889,7 @@ function nearestAttemptBindingBefore(rows, beforeIndex) {
|
|
|
10822
8889
|
for (let i = beforeIndex - 1; i >= 0; i -= 1) {
|
|
10823
8890
|
const row = rows[i];
|
|
10824
8891
|
if (!isParentAttemptBindingRow(row)) continue;
|
|
10825
|
-
if (!
|
|
8892
|
+
if (!isRecord6(row.data) || !isRecord6(row.data.parent)) continue;
|
|
10826
8893
|
const id = row.data.parent.attemptEntryId;
|
|
10827
8894
|
const sessionFile = row.data.parent.sessionFile;
|
|
10828
8895
|
return {
|
|
@@ -10837,10 +8904,10 @@ function extractAllAcceptedGateToolCalls(rows) {
|
|
|
10837
8904
|
const out = [];
|
|
10838
8905
|
for (let rowIndex = 0; rowIndex < rows.length; rowIndex += 1) {
|
|
10839
8906
|
const row = rows[rowIndex];
|
|
10840
|
-
const message =
|
|
8907
|
+
const message = isRecord6(row.message) ? row.message : void 0;
|
|
10841
8908
|
if (message?.role !== "assistant" || !Array.isArray(message.content)) continue;
|
|
10842
8909
|
for (const part of message.content) {
|
|
10843
|
-
if (!
|
|
8910
|
+
if (!isRecord6(part) || part.type !== "toolCall") continue;
|
|
10844
8911
|
if (typeof part.id !== "string" || part.id.length === 0) continue;
|
|
10845
8912
|
if (typeof part.name !== "string" || part.name.length === 0) continue;
|
|
10846
8913
|
if (!isGateTerminatingToolName(part.name)) continue;
|
|
@@ -10848,7 +8915,7 @@ function extractAllAcceptedGateToolCalls(rows) {
|
|
|
10848
8915
|
const binding = nearestAttemptBindingBefore(rows, rowIndex);
|
|
10849
8916
|
out.push({
|
|
10850
8917
|
toolName: part.name,
|
|
10851
|
-
args:
|
|
8918
|
+
args: isRecord6(part.arguments) ? part.arguments : void 0,
|
|
10852
8919
|
accepted: true,
|
|
10853
8920
|
rowIndex,
|
|
10854
8921
|
...binding
|
|
@@ -10971,17 +9038,17 @@ function pairGateRounds(volumes) {
|
|
|
10971
9038
|
return rounds.sort((a, b) => a.officerStartedAt.localeCompare(b.officerStartedAt)).map((round, index) => ({ ...round, roundIndex: index + 1 }));
|
|
10972
9039
|
}
|
|
10973
9040
|
async function resolveOfficerSessionFromPointerFile(pointerPath) {
|
|
10974
|
-
const { readFile:
|
|
9041
|
+
const { readFile: readFile25 } = await import("node:fs/promises");
|
|
10975
9042
|
let raw;
|
|
10976
9043
|
try {
|
|
10977
|
-
raw = JSON.parse(await
|
|
9044
|
+
raw = JSON.parse(await readFile25(pointerPath, "utf8"));
|
|
10978
9045
|
} catch (error) {
|
|
10979
9046
|
throw new Error(
|
|
10980
9047
|
`direct officer run pointer unreadable in ${pointerPath}: ${error instanceof Error ? error.message : String(error)}`,
|
|
10981
9048
|
{ cause: error }
|
|
10982
9049
|
);
|
|
10983
9050
|
}
|
|
10984
|
-
if (!
|
|
9051
|
+
if (!isRecord6(raw) || raw.kind !== "direct-officer-run-pointer" || raw.version !== 1) {
|
|
10985
9052
|
throw new Error(`direct officer run pointer has unknown shape in ${pointerPath}`);
|
|
10986
9053
|
}
|
|
10987
9054
|
const sessionFile = raw.sessionFile;
|
|
@@ -11340,11 +9407,11 @@ function reportEngineDetourCall(input) {
|
|
|
11340
9407
|
recordPointer: pointer
|
|
11341
9408
|
};
|
|
11342
9409
|
}
|
|
11343
|
-
function
|
|
9410
|
+
function isRecord7(value) {
|
|
11344
9411
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11345
9412
|
}
|
|
11346
9413
|
function callFactFromSitianPayload(payload, pointer) {
|
|
11347
|
-
if (!
|
|
9414
|
+
if (!isRecord7(payload)) return void 0;
|
|
11348
9415
|
if (payload.tool !== ENGINE_DETOUR_TOOL_NAME) return void 0;
|
|
11349
9416
|
if (typeof payload.toolCallId !== "string" || payload.toolCallId.length === 0) {
|
|
11350
9417
|
return void 0;
|
|
@@ -11361,11 +9428,11 @@ function callFactFromSitianPayload(payload, pointer) {
|
|
|
11361
9428
|
};
|
|
11362
9429
|
}
|
|
11363
9430
|
function invocationScopeIdOfRecord(record4) {
|
|
11364
|
-
if (
|
|
9431
|
+
if (isRecord7(record4.subject)) {
|
|
11365
9432
|
const fromSubject = record4.subject.invocationScopeId;
|
|
11366
9433
|
if (typeof fromSubject === "string" && fromSubject.length > 0) return fromSubject;
|
|
11367
9434
|
}
|
|
11368
|
-
if (
|
|
9435
|
+
if (isRecord7(record4.payload)) {
|
|
11369
9436
|
const fromPayload = record4.payload.invocationScopeId;
|
|
11370
9437
|
if (typeof fromPayload === "string" && fromPayload.length > 0) return fromPayload;
|
|
11371
9438
|
}
|
|
@@ -11426,7 +9493,7 @@ function readInvocationRecord(runDirectory) {
|
|
|
11426
9493
|
const raw = JSON.parse(
|
|
11427
9494
|
readFileSync2(join23(runDirectory, "invocation.json"), "utf8")
|
|
11428
9495
|
);
|
|
11429
|
-
return
|
|
9496
|
+
return isRecord7(raw) ? raw : void 0;
|
|
11430
9497
|
} catch (error) {
|
|
11431
9498
|
if (error?.code === "ENOENT") return void 0;
|
|
11432
9499
|
throw error;
|
|
@@ -11439,7 +9506,7 @@ async function readInvocationEngineMounted(runDirectory) {
|
|
|
11439
9506
|
}
|
|
11440
9507
|
function withEngineDetourToolUsageFact(outcome, usage) {
|
|
11441
9508
|
if (usage === void 0) return outcome;
|
|
11442
|
-
const prior =
|
|
9509
|
+
const prior = isRecord7(outcome.decisiveFacts) ? outcome.decisiveFacts : {};
|
|
11443
9510
|
return {
|
|
11444
9511
|
...outcome,
|
|
11445
9512
|
decisiveFacts: {
|
|
@@ -11509,13 +9576,13 @@ function resolveAuditDossier(source) {
|
|
|
11509
9576
|
}
|
|
11510
9577
|
return { status: "ok", runDirectory };
|
|
11511
9578
|
}
|
|
11512
|
-
function
|
|
9579
|
+
function isRecord8(value) {
|
|
11513
9580
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11514
9581
|
}
|
|
11515
9582
|
function readDoctorAuditSubjects(context) {
|
|
11516
9583
|
const entries = context.sessionManager.getEntries?.() ?? [];
|
|
11517
9584
|
for (const entry of entries) {
|
|
11518
|
-
if (
|
|
9585
|
+
if (isRecord8(entry) && entry.type === "custom" && entry.customType === DOCTOR_CANDIDATE_ENTRY_TYPE) {
|
|
11519
9586
|
return { status: "ok" };
|
|
11520
9587
|
}
|
|
11521
9588
|
}
|
|
@@ -11759,11 +9826,11 @@ var init_navigator_invocation_identity = __esm({
|
|
|
11759
9826
|
});
|
|
11760
9827
|
|
|
11761
9828
|
// src/receipt-delivery-policy.ts
|
|
11762
|
-
function
|
|
9829
|
+
function isRecord9(value) {
|
|
11763
9830
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11764
9831
|
}
|
|
11765
9832
|
function parseNoReceiptLifecycleFacts(input) {
|
|
11766
|
-
if (!
|
|
9833
|
+
if (!isRecord9(input) || typeof input.terminalToolCalled !== "boolean" || input.deliveryTurns !== RECEIPT_DELIVERY_TURN_LIMIT || input.sessionCompletion !== "settled-without-accepted-receipt" || input.acceptedReceipt !== false || typeof input.runPointer !== "string" || input.runPointer.trim() === "" || typeof input.attemptPointer !== "string" || input.attemptPointer.trim() === "" || !Array.isArray(input.rejectedReceipts) || !input.rejectedReceipts.every((item) => isRecord9(item) && typeof item.reason === "string")) {
|
|
11767
9834
|
throw new TypeError("malformed no-receipt lifecycle facts");
|
|
11768
9835
|
}
|
|
11769
9836
|
return {
|
|
@@ -11869,7 +9936,6 @@ __export(settlement_exports, {
|
|
|
11869
9936
|
controlledFailureInputFromResolution: () => controlledFailureInputFromResolution,
|
|
11870
9937
|
exitCodeForTerminalOutcome: () => exitCodeForTerminalOutcome,
|
|
11871
9938
|
explicitInternalKnownFailureClassificationInput: () => explicitInternalKnownFailureClassificationInput,
|
|
11872
|
-
extractCollectorInfrastructureFailure: () => extractCollectorInfrastructureFailure,
|
|
11873
9939
|
extractEngineDetourInfrastructureFailure: () => extractEngineDetourInfrastructureFailure,
|
|
11874
9940
|
extractGateFactFromSessionDirectory: () => extractGateFactFromSessionDirectory,
|
|
11875
9941
|
extractNavigatorFact: () => extractNavigatorFact,
|
|
@@ -11890,7 +9956,6 @@ __export(settlement_exports, {
|
|
|
11890
9956
|
publishedFailureErrorPath: () => publishedFailureErrorPath,
|
|
11891
9957
|
raceNavigatorGrace: () => raceNavigatorGrace,
|
|
11892
9958
|
readBoundSessionEntries: () => readBoundSessionEntries,
|
|
11893
|
-
readCollectorInfrastructureFailure: () => readCollectorInfrastructureFailure,
|
|
11894
9959
|
readEngineDetourInfrastructureFailure: () => readEngineDetourInfrastructureFailure,
|
|
11895
9960
|
readSessionProviderStop: () => readSessionProviderStop,
|
|
11896
9961
|
recordedSubmissionPayloads: () => recordedSubmissionPayloads,
|
|
@@ -12388,7 +10453,7 @@ async function readSitianRetainedAuditorProviderStop(sessionFile) {
|
|
|
12388
10453
|
const { records } = await readSitianRecords(recordFile);
|
|
12389
10454
|
for (let i = records.length - 1; i >= 0; i -= 1) {
|
|
12390
10455
|
const payload = records[i]?.payload;
|
|
12391
|
-
if (!
|
|
10456
|
+
if (!isRecord10(payload) || !isRecord10(payload.response)) continue;
|
|
12392
10457
|
if (typeof payload.type === "string") continue;
|
|
12393
10458
|
const stop = sessionProviderStopFromAssistant(payload.response);
|
|
12394
10459
|
if (stop !== void 0) return stop;
|
|
@@ -12438,7 +10503,7 @@ async function loadBoundAuditorVolumes(sessionFile) {
|
|
|
12438
10503
|
throw sessionReadFailure(error, "failed to read discovered auditor session");
|
|
12439
10504
|
}
|
|
12440
10505
|
const header = entries.find((entry) => entry.type === "session");
|
|
12441
|
-
if (!
|
|
10506
|
+
if (!isRecord10(header)) continue;
|
|
12442
10507
|
const bindingIndexes = [];
|
|
12443
10508
|
for (let i = 0; i < entries.length; i += 1) {
|
|
12444
10509
|
const entry = entries[i];
|
|
@@ -12452,7 +10517,7 @@ async function loadBoundAuditorVolumes(sessionFile) {
|
|
|
12452
10517
|
end: idx + 1 < bindingIndexes.length ? bindingIndexes[idx + 1] : entries.length
|
|
12453
10518
|
})) : [{ entry: void 0, start: 0, end: entries.length }];
|
|
12454
10519
|
for (const { entry: bindingEntry, start, end } of bindingPasses) {
|
|
12455
|
-
const bindingParent = bindingEntry !== void 0 &&
|
|
10520
|
+
const bindingParent = bindingEntry !== void 0 && isRecord10(bindingEntry.data) && isRecord10(bindingEntry.data.parent) ? bindingEntry.data.parent : void 0;
|
|
12456
10521
|
const attemptEntryId = typeof bindingParent?.attemptEntryId === "string" ? bindingParent.attemptEntryId : void 0;
|
|
12457
10522
|
const boundSessionFile = typeof bindingParent?.sessionFile === "string" ? bindingParent.sessionFile : typeof header.parentSession === "string" ? header.parentSession : void 0;
|
|
12458
10523
|
if (boundSessionFile !== sessionFile) continue;
|
|
@@ -12476,12 +10541,12 @@ function complianceFailureFromAuditorVolumes(volumes) {
|
|
|
12476
10541
|
if (stop === void 0) continue;
|
|
12477
10542
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
12478
10543
|
const entry = entries[i];
|
|
12479
|
-
if (entry?.type !== "custom" || entry.customType !== AUDITOR_COMPLIANCE_FAILURE_ENTRY_TYPE || !
|
|
12480
|
-
const parent =
|
|
12481
|
-
const failure2 =
|
|
10544
|
+
if (entry?.type !== "custom" || entry.customType !== AUDITOR_COMPLIANCE_FAILURE_ENTRY_TYPE || !isRecord10(entry.data)) continue;
|
|
10545
|
+
const parent = isRecord10(entry.data.parent) ? entry.data.parent : void 0;
|
|
10546
|
+
const failure2 = isRecord10(entry.data.failure) ? entry.data.failure : void 0;
|
|
12482
10547
|
if (parent?.sessionId !== parentId || parent.sessionFile !== sessionFile || parent.attemptEntryId !== attemptEntryId) continue;
|
|
12483
10548
|
if (failure2 === void 0) continue;
|
|
12484
|
-
const identity =
|
|
10549
|
+
const identity = isRecord10(failure2.identity) ? failure2.identity : void 0;
|
|
12485
10550
|
const typedCause = failure2.cause === "provider" || failure2.cause === "activation" || failure2.cause === "session" || failure2.cause === "output" || failure2.cause === "timeout" ? failure2.cause : void 0;
|
|
12486
10551
|
return {
|
|
12487
10552
|
...typedCause === void 0 ? {} : { cause: typedCause },
|
|
@@ -12490,7 +10555,7 @@ function complianceFailureFromAuditorVolumes(volumes) {
|
|
|
12490
10555
|
...typeof identity.code === "string" || typeof identity.code === "number" ? { code: identity.code } : {}
|
|
12491
10556
|
} },
|
|
12492
10557
|
...typeof failure2.diagnostic === "string" ? { diagnostic: failure2.diagnostic } : {},
|
|
12493
|
-
...
|
|
10558
|
+
...isRecord10(failure2.details) ? { details: failure2.details } : {}
|
|
12494
10559
|
};
|
|
12495
10560
|
}
|
|
12496
10561
|
}
|
|
@@ -12537,9 +10602,9 @@ function typedFailedTerminatingToolKnownFailure(entries) {
|
|
|
12537
10602
|
if (classification.kind !== "infrastructure") continue;
|
|
12538
10603
|
if (typeof message.toolCallId !== "string" || typeof message.toolName !== "string") continue;
|
|
12539
10604
|
if (boundRoleToolCallForResult(attemptEntries, i, message, message.toolName) === void 0) continue;
|
|
12540
|
-
const textPart = Array.isArray(message.content) ? message.content.find((part) =>
|
|
12541
|
-
const diagnostic =
|
|
12542
|
-
const details =
|
|
10605
|
+
const textPart = Array.isArray(message.content) ? message.content.find((part) => isRecord10(part) && part.type === "text" && typeof part.text === "string") : void 0;
|
|
10606
|
+
const diagnostic = isRecord10(textPart) ? textPart.text : void 0;
|
|
10607
|
+
const details = isRecord10(message.details) ? message.details : classification.fact;
|
|
12543
10608
|
return {
|
|
12544
10609
|
cause: "activation",
|
|
12545
10610
|
identity: { name: message.toolName, code: message.toolCallId },
|
|
@@ -12676,7 +10741,7 @@ function controlledFailureInputFromResolution(resolution) {
|
|
|
12676
10741
|
} : {}
|
|
12677
10742
|
};
|
|
12678
10743
|
}
|
|
12679
|
-
function
|
|
10744
|
+
function isRecord10(value) {
|
|
12680
10745
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12681
10746
|
}
|
|
12682
10747
|
function toolResultText(message) {
|
|
@@ -12686,25 +10751,9 @@ function toolResultText(message) {
|
|
|
12686
10751
|
return content.map((part) => {
|
|
12687
10752
|
if (typeof part === "object" && part !== null && !Array.isArray(part) && typeof part.text === "string") {
|
|
12688
10753
|
return part.text;
|
|
12689
|
-
}
|
|
12690
|
-
return "";
|
|
12691
|
-
}).join("").trim();
|
|
12692
|
-
}
|
|
12693
|
-
function extractCollectorTargetBindRejection(entries) {
|
|
12694
|
-
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
12695
|
-
const entry = entries[i];
|
|
12696
|
-
if (entry?.type !== "message") continue;
|
|
12697
|
-
const message = entry.message;
|
|
12698
|
-
if (message?.role !== "toolResult") continue;
|
|
12699
|
-
if (message.toolName !== COLLECTOR_BIND_TARGET_TOOL) continue;
|
|
12700
|
-
if (message.isError !== true) return void 0;
|
|
12701
|
-
const diagnostic = toolResultText(message);
|
|
12702
|
-
if (diagnostic.length === 0) return void 0;
|
|
12703
|
-
const details = message.details;
|
|
12704
|
-
const code = isRecord11(details) && typeof details.code === "string" && details.code.trim() !== "" ? details.code : void 0;
|
|
12705
|
-
return code === void 0 ? { diagnostic } : { diagnostic, code };
|
|
12706
|
-
}
|
|
12707
|
-
return void 0;
|
|
10754
|
+
}
|
|
10755
|
+
return "";
|
|
10756
|
+
}).join("").trim();
|
|
12708
10757
|
}
|
|
12709
10758
|
function boundErroredToolCandidate(entries, resultIndex, message, toolName) {
|
|
12710
10759
|
if (message.toolName !== toolName || message.isError !== true) return void 0;
|
|
@@ -12746,21 +10795,6 @@ async function readInfrastructureToolFailure(sessionFile, spec, options = {}) {
|
|
|
12746
10795
|
return void 0;
|
|
12747
10796
|
}
|
|
12748
10797
|
}
|
|
12749
|
-
function extractCollectorInfrastructureFailure(entries) {
|
|
12750
|
-
return extractInfrastructureToolFailure(
|
|
12751
|
-
entries,
|
|
12752
|
-
COLLECTOR_INFRASTRUCTURE_FAILURE_SPEC
|
|
12753
|
-
);
|
|
12754
|
-
}
|
|
12755
|
-
async function readCollectorInfrastructureFailure(sessionFile) {
|
|
12756
|
-
return readInfrastructureToolFailure(
|
|
12757
|
-
sessionFile,
|
|
12758
|
-
COLLECTOR_INFRASTRUCTURE_FAILURE_SPEC,
|
|
12759
|
-
// Multi-attempt resume: only a current-attempt infrastructure failure
|
|
12760
|
-
// may preempt the current failure cause (#633).
|
|
12761
|
-
{ currentAttemptOnly: true }
|
|
12762
|
-
);
|
|
12763
|
-
}
|
|
12764
10798
|
function extractEngineDetourInfrastructureFailure(entries) {
|
|
12765
10799
|
return extractInfrastructureToolFailure(
|
|
12766
10800
|
entries,
|
|
@@ -12802,7 +10836,7 @@ function boundRoleToolCallForResult(entries, resultIndex, message, outputToolNam
|
|
|
12802
10836
|
const candidateMessage = entries[index]?.message;
|
|
12803
10837
|
if (candidateMessage?.role === "assistant" && Array.isArray(candidateMessage.content)) {
|
|
12804
10838
|
for (const part of candidateMessage.content) {
|
|
12805
|
-
if (!
|
|
10839
|
+
if (!isRecord10(part) || part.type !== "toolCall" || part.id !== callId) {
|
|
12806
10840
|
continue;
|
|
12807
10841
|
}
|
|
12808
10842
|
if (part.name !== outputToolName) return void 0;
|
|
@@ -12873,7 +10907,7 @@ function parseNavigatorAttendanceDetails(details) {
|
|
|
12873
10907
|
if (typeof details.prose === "string" && details.prose.trim() !== "") {
|
|
12874
10908
|
prose = details.prose;
|
|
12875
10909
|
} else {
|
|
12876
|
-
const next =
|
|
10910
|
+
const next = isRecord10(details.next) && typeof details.next.role === "string" ? details.next.role : void 0;
|
|
12877
10911
|
const reason = typeof details.reason === "string" && details.reason.trim() !== "" ? details.reason : void 0;
|
|
12878
10912
|
const command = typeof details.command === "string" && details.command.trim() !== "" ? details.command : void 0;
|
|
12879
10913
|
if (reason !== void 0 && next !== void 0) {
|
|
@@ -12982,7 +11016,7 @@ function detourGateContext(admitted, scope) {
|
|
|
12982
11016
|
}
|
|
12983
11017
|
async function withOptionalGateProjection(base, sessionDirectory, gateContext = {}) {
|
|
12984
11018
|
const secondaryEvidence = base.roleOutcome.kind === "failure" ? base.roleOutcome.decisiveFacts.secondaryEvidence : void 0;
|
|
12985
|
-
const skipGate =
|
|
11019
|
+
const skipGate = isRecord10(secondaryEvidence) && secondaryEvidence.kind === "role_infrastructure_failure" && packagedSkipsGateOnInfrastructureStage(secondaryEvidence.stage);
|
|
12986
11020
|
let next = base;
|
|
12987
11021
|
if (!skipGate) {
|
|
12988
11022
|
const gate = await extractGateFactFromSessionDirectory(sessionDirectory, gateContext);
|
|
@@ -12995,7 +11029,7 @@ function routePlaybookFailureMessage(entries) {
|
|
|
12995
11029
|
const entry = entries[i];
|
|
12996
11030
|
if (entry?.type !== "custom" || entry.customType !== NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY) continue;
|
|
12997
11031
|
const data = entry.data;
|
|
12998
|
-
if (!
|
|
11032
|
+
if (!isRecord10(data) || typeof data.message !== "string" || data.message.trim() === "") return void 0;
|
|
12999
11033
|
return data.message;
|
|
13000
11034
|
}
|
|
13001
11035
|
return void 0;
|
|
@@ -13042,7 +11076,7 @@ function extractNavigatorAttendanceFact(entries) {
|
|
|
13042
11076
|
const entry = entries[i];
|
|
13043
11077
|
if (entry?.type === "custom_message" && entry.customType === "ak-navigator-attendance") {
|
|
13044
11078
|
const details = entry.message?.details ?? entry.details;
|
|
13045
|
-
if (!
|
|
11079
|
+
if (!isRecord10(details)) {
|
|
13046
11080
|
return {
|
|
13047
11081
|
disposition: "unavailable",
|
|
13048
11082
|
source: "unknown",
|
|
@@ -13193,7 +11227,7 @@ async function settleSealedAcceptedOrToolResidual(admitted, authority, scope, ro
|
|
|
13193
11227
|
const residual = boundErroredToolCandidate(entries, index, message, residualToolName);
|
|
13194
11228
|
if (residual === void 0) continue;
|
|
13195
11229
|
const candidate = residual.candidate;
|
|
13196
|
-
const details =
|
|
11230
|
+
const details = isRecord10(candidate) ? candidate : { candidate };
|
|
13197
11231
|
const failed = await settleFailureTerminalResult(
|
|
13198
11232
|
admitted,
|
|
13199
11233
|
{
|
|
@@ -13268,7 +11302,7 @@ function extractDoctorCandidateFacts(entries) {
|
|
|
13268
11302
|
continue;
|
|
13269
11303
|
}
|
|
13270
11304
|
const data = entry.data;
|
|
13271
|
-
if (!
|
|
11305
|
+
if (!isRecord10(data)) return {};
|
|
13272
11306
|
return {
|
|
13273
11307
|
...data.cost === void 0 ? {} : { cost: data.cost },
|
|
13274
11308
|
...data.auditNoReceipt === void 0 ? {} : { auditNoReceipt: data.auditNoReceipt }
|
|
@@ -13353,7 +11387,7 @@ async function settleLawfulSeatAcceptedTerminalResult(admitted, authority, spec,
|
|
|
13353
11387
|
let residual;
|
|
13354
11388
|
for (let index = entries.length - 1; index >= scanStart; index -= 1) {
|
|
13355
11389
|
const entry = entries[index];
|
|
13356
|
-
if (entry?.type === "custom" && entry.customType === "ak-role-submission-closure" &&
|
|
11390
|
+
if (entry?.type === "custom" && entry.customType === "ak-role-submission-closure" && isRecord10(entry.data) && entry.data.toolName === spec.toolName && classifyPackagedRoleTerminalResult(entry.data).kind === "accepted") {
|
|
13357
11391
|
thisAttemptHasSeatSuccess = true;
|
|
13358
11392
|
}
|
|
13359
11393
|
const message = entries[index]?.message;
|
|
@@ -13393,7 +11427,7 @@ async function settleLawfulSeatAcceptedTerminalResult(admitted, authority, spec,
|
|
|
13393
11427
|
);
|
|
13394
11428
|
}
|
|
13395
11429
|
if (residual !== void 0) {
|
|
13396
|
-
const details =
|
|
11430
|
+
const details = isRecord10(residual.candidate) ? residual.candidate : { candidate: residual.candidate };
|
|
13397
11431
|
const failed = await settleFailureTerminalResult(
|
|
13398
11432
|
admitted,
|
|
13399
11433
|
{
|
|
@@ -13443,7 +11477,7 @@ function countersignTerminalFromEntries(entries) {
|
|
|
13443
11477
|
return void 0;
|
|
13444
11478
|
}
|
|
13445
11479
|
function withCountersignTerminalFact(roleOutcome, officer) {
|
|
13446
|
-
const prior = roleOutcome.decisiveFacts !== void 0 &&
|
|
11480
|
+
const prior = roleOutcome.decisiveFacts !== void 0 && isRecord10(roleOutcome.decisiveFacts) ? roleOutcome.decisiveFacts : {};
|
|
13447
11481
|
return {
|
|
13448
11482
|
...roleOutcome,
|
|
13449
11483
|
decisiveFacts: {
|
|
@@ -13456,7 +11490,7 @@ function acceptedSecretariatDefinesOfficerProjection(roleOutcome) {
|
|
|
13456
11490
|
const payloads = roleOutcome.payloads ?? [];
|
|
13457
11491
|
for (let index = payloads.length - 1; index >= 0; index -= 1) {
|
|
13458
11492
|
const payload = payloads[index];
|
|
13459
|
-
if (!
|
|
11493
|
+
if (!isRecord10(payload)) continue;
|
|
13460
11494
|
const status = payload.secretariatStatus;
|
|
13461
11495
|
if (typeof status !== "string") continue;
|
|
13462
11496
|
return status === "converged";
|
|
@@ -13684,17 +11718,6 @@ async function settleFailureTerminalResult(admitted, failure2, authority, option
|
|
|
13684
11718
|
}
|
|
13685
11719
|
if (facts !== void 0 && facts.runPointer === admitted.runDirectory && facts.attemptPointer === `current:${admitted.runDirectory}`) {
|
|
13686
11720
|
let decisiveFacts2 = facts;
|
|
13687
|
-
if (packagedProjectsTargetBindRejection(admitted.role)) {
|
|
13688
|
-
const bindRejection = extractCollectorTargetBindRejection(entries.slice(attemptStart));
|
|
13689
|
-
if (bindRejection !== void 0) {
|
|
13690
|
-
decisiveFacts2 = {
|
|
13691
|
-
...facts,
|
|
13692
|
-
targetBindRejected: true,
|
|
13693
|
-
targetBindDiagnostic: bindRejection.diagnostic,
|
|
13694
|
-
...bindRejection.code === void 0 ? {} : { targetBindCode: bindRejection.code }
|
|
13695
|
-
};
|
|
13696
|
-
}
|
|
13697
|
-
}
|
|
13698
11721
|
await clearOppositeTerminalArtifactFace(admitted.runDirectory);
|
|
13699
11722
|
return withOptionalGateProjection(
|
|
13700
11723
|
{
|
|
@@ -13829,7 +11852,7 @@ function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep2
|
|
|
13829
11852
|
});
|
|
13830
11853
|
});
|
|
13831
11854
|
}
|
|
13832
|
-
var privateFailureErrorPaths, NAVIGATOR_POST_ROLE_GRACE_MS,
|
|
11855
|
+
var privateFailureErrorPaths, NAVIGATOR_POST_ROLE_GRACE_MS, ENGINE_DETOUR_INFRASTRUCTURE_FAILURE_SPEC, RUNNER_FAILURE_POLICY, ATTEMPT_HISTORY_ENTRY_TYPE, EMPTY_ARTIFACT_FACE;
|
|
13833
11856
|
var init_settlement = __esm({
|
|
13834
11857
|
"src/public-cli/settlement.ts"() {
|
|
13835
11858
|
"use strict";
|
|
@@ -13842,11 +11865,9 @@ var init_settlement = __esm({
|
|
|
13842
11865
|
init_serialize_thrown_value();
|
|
13843
11866
|
init_run_lifecycle();
|
|
13844
11867
|
init_compliance_transport();
|
|
13845
|
-
init_collector_ledger();
|
|
13846
11868
|
init_engine_detour();
|
|
13847
11869
|
init_engine_detour_usage();
|
|
13848
11870
|
init_judge_output();
|
|
13849
|
-
init_collector_output();
|
|
13850
11871
|
init_worker_output();
|
|
13851
11872
|
init_doctor_contracts();
|
|
13852
11873
|
init_dossier_resolution();
|
|
@@ -13862,20 +11883,6 @@ var init_settlement = __esm({
|
|
|
13862
11883
|
init_terminal();
|
|
13863
11884
|
privateFailureErrorPaths = /* @__PURE__ */ new WeakMap();
|
|
13864
11885
|
NAVIGATOR_POST_ROLE_GRACE_MS = 1e4;
|
|
13865
|
-
COLLECTOR_INFRASTRUCTURE_TOOLS = /* @__PURE__ */ new Set([
|
|
13866
|
-
COLLECTOR_OBSERVE_TOOL,
|
|
13867
|
-
COLLECTOR_READ_TOOL,
|
|
13868
|
-
COLLECTOR_REQUEST_TOOL,
|
|
13869
|
-
COLLECTOR_WAIT_TOOL
|
|
13870
|
-
]);
|
|
13871
|
-
COLLECTOR_INFRASTRUCTURE_FAILURE_SPEC = {
|
|
13872
|
-
matchTool: (toolName) => COLLECTOR_INFRASTRUCTURE_TOOLS.has(toolName),
|
|
13873
|
-
cause: "activation",
|
|
13874
|
-
identityName: "CollectorInfrastructureError",
|
|
13875
|
-
// read alone has a correctable rejection mode (unknown/non-openable pointers);
|
|
13876
|
-
// only its typed infrastructure-failure fact counts as a real host failure.
|
|
13877
|
-
requireInfrastructureFact: (toolName) => toolName === COLLECTOR_READ_TOOL
|
|
13878
|
-
};
|
|
13879
11886
|
ENGINE_DETOUR_INFRASTRUCTURE_FAILURE_SPEC = {
|
|
13880
11887
|
matchTool: (toolName) => toolName === ENGINE_DETOUR_TOOL_NAME,
|
|
13881
11888
|
cause: "output",
|
|
@@ -13889,10 +11896,6 @@ var init_settlement = __esm({
|
|
|
13889
11896
|
"engine-detour-record-first": {
|
|
13890
11897
|
read: readEngineDetourInfrastructureFailure,
|
|
13891
11898
|
rank: "record-first"
|
|
13892
|
-
},
|
|
13893
|
-
"collector-known-first": {
|
|
13894
|
-
read: readCollectorInfrastructureFailure,
|
|
13895
|
-
rank: "known-first"
|
|
13896
11899
|
}
|
|
13897
11900
|
};
|
|
13898
11901
|
ATTEMPT_HISTORY_ENTRY_TYPE = "ak_run_attempt_history";
|
|
@@ -16190,11 +14193,11 @@ var init_turn_request = __esm({
|
|
|
16190
14193
|
});
|
|
16191
14194
|
|
|
16192
14195
|
// src/public-cli/countersign-run.ts
|
|
16193
|
-
function
|
|
14196
|
+
function isRecord11(value) {
|
|
16194
14197
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16195
14198
|
}
|
|
16196
14199
|
function isEscalatePayload(payload) {
|
|
16197
|
-
if (!
|
|
14200
|
+
if (!isRecord11(payload)) return false;
|
|
16198
14201
|
return payload.status === "escalate";
|
|
16199
14202
|
}
|
|
16200
14203
|
function courtDiaristPayloadRows(roleOutcome, submissions) {
|
|
@@ -17804,7 +15807,7 @@ function isMissingPathError6(error) {
|
|
|
17804
15807
|
function errorText3(error) {
|
|
17805
15808
|
return error instanceof Error ? error.message : String(error);
|
|
17806
15809
|
}
|
|
17807
|
-
function
|
|
15810
|
+
function isRecord12(value) {
|
|
17808
15811
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17809
15812
|
}
|
|
17810
15813
|
async function readExistingRunLifecycleState(runDirectory) {
|
|
@@ -17861,7 +15864,7 @@ async function readInvocationScopeFields(runDirectory) {
|
|
|
17861
15864
|
throw error;
|
|
17862
15865
|
}
|
|
17863
15866
|
const parsed = JSON.parse(raw);
|
|
17864
|
-
if (!
|
|
15867
|
+
if (!isRecord12(parsed)) return void 0;
|
|
17865
15868
|
if (typeof parsed.projectRoot !== "string" || parsed.projectRoot.trim() === "") {
|
|
17866
15869
|
return void 0;
|
|
17867
15870
|
}
|
|
@@ -17890,7 +15893,7 @@ async function resolveSessionFile(runDirectory) {
|
|
|
17890
15893
|
try {
|
|
17891
15894
|
const raw = await readFile18(join33(runDirectory, "invocation.json"), "utf8");
|
|
17892
15895
|
const parsed = JSON.parse(raw);
|
|
17893
|
-
if (
|
|
15896
|
+
if (isRecord12(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.trim() !== "") {
|
|
17894
15897
|
return parsed.sessionFile;
|
|
17895
15898
|
}
|
|
17896
15899
|
} catch (error) {
|
|
@@ -18228,7 +16231,7 @@ var init_analyst_ledger = __esm({
|
|
|
18228
16231
|
});
|
|
18229
16232
|
|
|
18230
16233
|
// src/analyst-metric-families/acceptance-success-rework.ts
|
|
18231
|
-
function
|
|
16234
|
+
function isRecord13(value) {
|
|
18232
16235
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18233
16236
|
}
|
|
18234
16237
|
function wallMsFromSpan(span) {
|
|
@@ -18237,21 +16240,21 @@ function wallMsFromSpan(span) {
|
|
|
18237
16240
|
function findCollectorGroups(body) {
|
|
18238
16241
|
if (Array.isArray(body.groups)) return body.groups;
|
|
18239
16242
|
const receipt = body.receipt;
|
|
18240
|
-
if (
|
|
16243
|
+
if (isRecord13(receipt) && Array.isArray(receipt.groups)) return receipt.groups;
|
|
18241
16244
|
const outcome = body.outcome;
|
|
18242
|
-
if (
|
|
16245
|
+
if (isRecord13(outcome)) {
|
|
18243
16246
|
const facts = outcome.decisiveFacts;
|
|
18244
|
-
if (
|
|
16247
|
+
if (isRecord13(facts) && Array.isArray(facts.groups)) return facts.groups;
|
|
18245
16248
|
}
|
|
18246
16249
|
return void 0;
|
|
18247
16250
|
}
|
|
18248
16251
|
function extractStatus(body) {
|
|
18249
16252
|
const outcome = body.outcome;
|
|
18250
|
-
if (
|
|
16253
|
+
if (isRecord13(outcome) && typeof outcome.status === "string" && outcome.status.trim() !== "") {
|
|
18251
16254
|
return outcome.status;
|
|
18252
16255
|
}
|
|
18253
16256
|
const receipt = body.receipt;
|
|
18254
|
-
if (
|
|
16257
|
+
if (isRecord13(receipt) && typeof receipt.status === "string" && receipt.status.trim() !== "") {
|
|
18255
16258
|
return receipt.status;
|
|
18256
16259
|
}
|
|
18257
16260
|
if (typeof body.status === "string" && body.status.trim() !== "") {
|
|
@@ -18877,15 +16880,15 @@ var init_leg_wall_clock = __esm({
|
|
|
18877
16880
|
});
|
|
18878
16881
|
|
|
18879
16882
|
// src/analyst-metric-families/round-timeline.ts
|
|
18880
|
-
function
|
|
16883
|
+
function isRecord14(value) {
|
|
18881
16884
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18882
16885
|
}
|
|
18883
16886
|
function wallMsFromSpan2(startedAt, endedAt) {
|
|
18884
16887
|
return Date.parse(endedAt) - Date.parse(startedAt);
|
|
18885
16888
|
}
|
|
18886
16889
|
function readClassCount(body) {
|
|
18887
|
-
if (!
|
|
18888
|
-
if (!
|
|
16890
|
+
if (!isRecord14(body.outcome)) return void 0;
|
|
16891
|
+
if (!isRecord14(body.outcome.decisiveFacts)) return void 0;
|
|
18889
16892
|
const classCount = body.outcome.decisiveFacts.classCount;
|
|
18890
16893
|
if (typeof classCount !== "number" || !Number.isFinite(classCount)) {
|
|
18891
16894
|
return void 0;
|
|
@@ -19029,7 +17032,7 @@ var init_analyst_metric_family = __esm({
|
|
|
19029
17032
|
});
|
|
19030
17033
|
|
|
19031
17034
|
// src/analyst-page.ts
|
|
19032
|
-
import { createHash as
|
|
17035
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
19033
17036
|
import { dirname as dirname21, join as join34 } from "node:path";
|
|
19034
17037
|
function analystIssuePageKey(address) {
|
|
19035
17038
|
const parts = ["book", address.bookKey];
|
|
@@ -19038,7 +17041,7 @@ function analystIssuePageKey(address) {
|
|
|
19038
17041
|
} else if (address.scopeRootIdentity !== void 0) {
|
|
19039
17042
|
parts.push("root", physicalPathIdentity(address.scopeRootIdentity));
|
|
19040
17043
|
}
|
|
19041
|
-
return
|
|
17044
|
+
return createHash3("sha256").update(parts.join("\0")).digest("hex").slice(0, 32);
|
|
19042
17045
|
}
|
|
19043
17046
|
function analystIssuePagePath(ledgerHome, address) {
|
|
19044
17047
|
return join34(ledgerHome, "analyst", "issues", `${analystIssuePageKey(address)}.json`);
|
|
@@ -22875,8 +20878,8 @@ var init_submission_ledger = __esm({
|
|
|
22875
20878
|
});
|
|
22876
20879
|
|
|
22877
20880
|
// src/archivist-record-topology.ts
|
|
22878
|
-
import { createHash as
|
|
22879
|
-
import { join as
|
|
20881
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
20882
|
+
import { join as join41 } from "node:path";
|
|
22880
20883
|
function resolveNavigatorWorkSubjectPlacement(input) {
|
|
22881
20884
|
let ledgerHome;
|
|
22882
20885
|
if (input.parentSessionFile !== void 0 && input.parentSessionFile.length > 0) {
|
|
@@ -22886,10 +20889,10 @@ function resolveNavigatorWorkSubjectPlacement(input) {
|
|
|
22886
20889
|
}
|
|
22887
20890
|
}
|
|
22888
20891
|
ledgerHome ??= resolveActivationLedgerHome(input.home);
|
|
22889
|
-
const digest =
|
|
20892
|
+
const digest = createHash4("sha256").update(input.subject).digest("hex").slice(0, 32);
|
|
22890
20893
|
return {
|
|
22891
20894
|
ledgerHome,
|
|
22892
|
-
sessionDir:
|
|
20895
|
+
sessionDir: join41(
|
|
22893
20896
|
activationBookDirectory(ledgerHome, resolveBookKeyFromGit(input.cwd)),
|
|
22894
20897
|
NAVIGATOR_RECORD_KIND,
|
|
22895
20898
|
digest
|
|
@@ -22961,10 +20964,10 @@ import {
|
|
|
22961
20964
|
statSync as statSync7,
|
|
22962
20965
|
writeFileSync as writeFileSync3
|
|
22963
20966
|
} from "node:fs";
|
|
22964
|
-
import { dirname as dirname23, resolve as resolve17, join as
|
|
20967
|
+
import { dirname as dirname23, resolve as resolve17, join as join42 } from "node:path";
|
|
22965
20968
|
import { StringDecoder } from "node:string_decoder";
|
|
22966
20969
|
function readCurrentSession(sessionDir) {
|
|
22967
|
-
const ledger =
|
|
20970
|
+
const ledger = join42(sessionDir, CURRENT_SESSION_LEDGER);
|
|
22968
20971
|
try {
|
|
22969
20972
|
const value = JSON.parse(readFileSync4(ledger, "utf8"));
|
|
22970
20973
|
if (typeof value !== "object" || value === null || typeof value.sessionFile !== "string" || value.sessionFile.length === 0) {
|
|
@@ -22979,7 +20982,7 @@ function readCurrentSession(sessionDir) {
|
|
|
22979
20982
|
}
|
|
22980
20983
|
}
|
|
22981
20984
|
function writeCurrentSession(sessionDir, sessionFile) {
|
|
22982
|
-
const ledger =
|
|
20985
|
+
const ledger = join42(sessionDir, CURRENT_SESSION_LEDGER);
|
|
22983
20986
|
try {
|
|
22984
20987
|
writeFileSync3(ledger, `${JSON.stringify({ sessionFile })}
|
|
22985
20988
|
`, { flag: "wx" });
|
|
@@ -22995,7 +20998,7 @@ function isCurrentSessionClaimRace(error) {
|
|
|
22995
20998
|
return errnoCode(error.cause) === "EEXIST";
|
|
22996
20999
|
}
|
|
22997
21000
|
function currentSessionLedgerPath(sessionDir) {
|
|
22998
|
-
return
|
|
21001
|
+
return join42(sessionDir, CURRENT_SESSION_LEDGER);
|
|
22999
21002
|
}
|
|
23000
21003
|
function readBoundedSessionHeader(filePath) {
|
|
23001
21004
|
const fd = openSync2(filePath, "r");
|
|
@@ -23082,7 +21085,7 @@ function mostRecentNavigatorSessionFile(sessionDir, cwd) {
|
|
|
23082
21085
|
const matched = [];
|
|
23083
21086
|
for (const name of names) {
|
|
23084
21087
|
if (!name.endsWith(".jsonl")) continue;
|
|
23085
|
-
const filePath =
|
|
21088
|
+
const filePath = join42(absoluteSessionDir, name);
|
|
23086
21089
|
let st;
|
|
23087
21090
|
try {
|
|
23088
21091
|
st = statSync7(filePath);
|
|
@@ -23194,7 +21197,7 @@ function createRecordSessionOpen(options, host = piRecordSessionHost) {
|
|
|
23194
21197
|
if (!physicallyContainedIn(ledgerHome, parentResolved)) {
|
|
23195
21198
|
throw new Error("Durable record ownership requires a parent session inside the ledger home");
|
|
23196
21199
|
}
|
|
23197
|
-
sessionDir =
|
|
21200
|
+
sessionDir = join42(dirname23(parentResolved), options.kind);
|
|
23198
21201
|
parentSession = parentFile;
|
|
23199
21202
|
mayResumeSameNest = options.kind === WORKER_SUBMISSION_GATE_KIND;
|
|
23200
21203
|
}
|
|
@@ -23265,17 +21268,16 @@ init_packaged_role_registry();
|
|
|
23265
21268
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
23266
21269
|
import { appendFile as appendFile3, mkdir as mkdir5, writeFile as writeFile10 } from "node:fs/promises";
|
|
23267
21270
|
import { createServer } from "node:net";
|
|
23268
|
-
import { dirname as dirname25, join as
|
|
21271
|
+
import { dirname as dirname25, join as join45 } from "node:path";
|
|
23269
21272
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
23270
21273
|
|
|
23271
21274
|
// src/role-runtime.ts
|
|
23272
21275
|
init_host_contracts();
|
|
23273
21276
|
init_sitian_facade();
|
|
23274
21277
|
init_submission_ledger();
|
|
23275
|
-
init_collector_ledger();
|
|
23276
21278
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
23277
21279
|
import { readFileSync as readFileSync6, writeSync as writeSync2 } from "node:fs";
|
|
23278
|
-
import { join as
|
|
21280
|
+
import { join as join44 } from "node:path";
|
|
23279
21281
|
import { Value as Value4 } from "typebox/value";
|
|
23280
21282
|
|
|
23281
21283
|
// src/activation-trace.ts
|
|
@@ -23592,96 +21594,19 @@ init_receipt_delivery_policy();
|
|
|
23592
21594
|
|
|
23593
21595
|
// src/collector-role.ts
|
|
23594
21596
|
init_collector_config();
|
|
23595
|
-
|
|
23596
|
-
init_collector_github();
|
|
23597
|
-
|
|
23598
|
-
// src/collector-handbook.ts
|
|
23599
|
-
init_atomic_write();
|
|
23600
|
-
init_activation_ledger_topology();
|
|
23601
|
-
import { readFile as readFile22 } from "node:fs/promises";
|
|
23602
|
-
import { join as join40, sep as sep6 } from "node:path";
|
|
21597
|
+
init_collector_output();
|
|
23603
21598
|
|
|
23604
21599
|
// src/collector-tool-schemas.ts
|
|
23605
21600
|
init_open_tool_schema();
|
|
23606
21601
|
init_terminating_infrastructure();
|
|
23607
21602
|
import { Type as Type14 } from "typebox";
|
|
23608
|
-
var collectorObserveArgsSchema = Type14.Object({}, { additionalProperties: true });
|
|
23609
|
-
var collectorRequestArgsSchema = Type14.Object({
|
|
23610
|
-
requestId: Type14.String({
|
|
23611
|
-
minLength: 1,
|
|
23612
|
-
description: "\u8BF7\u6C42\u8EAB\u4EFD\uFF08\u914D\u7F6E id \u6216\u89D2\u8272\u5224\u5B9A\u7684\u7A33\u5B9A id\uFF1B\u9996\u5C3E\u65E0\u7A7A\u767D\uFF09"
|
|
23613
|
-
}),
|
|
23614
|
-
snapshotId: Type14.String({ minLength: 1, description: "\u6700\u65B0\u7559\u5B58\u89C2\u5BDF\u5FEB\u7167" }),
|
|
23615
|
-
// #836 r16 class 3: body.minLength deleted — manifest-configured requestId
|
|
23616
|
-
// ignores body, and the unknown-requestId non-empty condition is a real
|
|
23617
|
-
// branch in src/collector-ledger.ts:922-951, not a provider shape gate.
|
|
23618
|
-
body: Type14.Optional(Type14.String({
|
|
23619
|
-
description: "\u89D2\u8272\u5224\u5B9A\u7684\u8BF7\u6C42\u6B63\u6587\uFF1Brequest-manifest \u672A\u6536\u5F55\u8BE5 requestId \u65F6\u5FC5\u586B"
|
|
23620
|
-
}))
|
|
23621
|
-
}, { additionalProperties: true });
|
|
23622
|
-
var COLLECTOR_HANDBOOK_MAX_BYTES = 64 * 1024;
|
|
23623
|
-
var collectorHandbookWriteArgsSchema = Type14.Object({
|
|
23624
|
-
scope: Type14.Union([
|
|
23625
|
-
Type14.Literal("general"),
|
|
23626
|
-
Type14.Literal("repo")
|
|
23627
|
-
], { description: "general\uFF1D\u901A\u7528\u624B\u518C\uFF1Brepo\uFF1D\u5F53\u524D\u4ED3\u5E93\u5DEE\u5F02" }),
|
|
23628
|
-
body: Type14.String({
|
|
23629
|
-
description: `\u624B\u518C\u5168\u6587\uFF08opaque \u5DE5\u4F5C\u8BB0\u5FC6\uFF1B\u6574\u4EFD\u66FF\u6362\uFF1BUTF-8 \u81F3\u591A ${COLLECTOR_HANDBOOK_MAX_BYTES} \u5B57\u8282\uFF09`
|
|
23630
|
-
})
|
|
23631
|
-
}, { additionalProperties: true });
|
|
23632
|
-
var collectorReadArgsSchema = Type14.Object({
|
|
23633
|
-
evidenceId: Type14.String({ minLength: 1, description: "observe \u8FD4\u56DE\u7684\u6750\u6599\u8BC1\u636E id\uFF08evidenceId\uFF09" })
|
|
23634
|
-
}, { additionalProperties: true });
|
|
23635
|
-
var collectorWaitArgsSchema = Type14.Object({
|
|
23636
|
-
durationMs: Type14.Integer({
|
|
23637
|
-
minimum: 1,
|
|
23638
|
-
description: "\u7B49\u5F85\u6BEB\u79D2\uFF1B\u5B9E\u9645\u7761\u7720\u4E0D\u8D85\u8FC7\u5269\u4F59\u7B49\u5F85\u7A97\uFF08#678\uFF1B\u65E0\u5305\u5185\u5355\u6B21\u4EFB\u610F\u4E0A\u9650\uFF09"
|
|
23639
|
-
})
|
|
23640
|
-
}, { additionalProperties: true });
|
|
23641
|
-
var collectorOpenWaitWindowArgsSchema = Type14.Object({
|
|
23642
|
-
startedAt: Type14.Optional(Type14.String({
|
|
23643
|
-
description: "\u7B49\u5F85\u7A97\u8D77\u70B9 ISO \u65F6\u95F4\uFF1B\u65B0\u5EFA PR \u7528\u521B\u5EFA\u6210\u529F\u65F6\u523B\uFF1B\u7701\u7565\uFF1D\u73B0\u5728\uFF08\u89E6\u53D1\u9636\u6BB5\u7ED3\u675F\uFF09"
|
|
23644
|
-
}))
|
|
23645
|
-
}, { additionalProperties: true });
|
|
23646
|
-
var collectorBindTargetArgsSchema = Type14.Object({
|
|
23647
|
-
prNumber: Type14.Optional(Type14.Unknown({
|
|
23648
|
-
description: "\u672C\u4ED3 PR \u53F7\uFF08\u6B63\u6574\u6570\uFF09\u3002"
|
|
23649
|
-
})),
|
|
23650
|
-
issueNumber: Type14.Optional(Type14.Unknown({
|
|
23651
|
-
description: "\u672C\u4ED3 issue \u53F7\uFF08\u6B63\u6574\u6570\uFF09\u3002"
|
|
23652
|
-
}))
|
|
23653
|
-
}, { additionalProperties: true });
|
|
23654
|
-
var collectorFindingItemDeclaration = (() => {
|
|
23655
|
-
const item = Type14.Object(
|
|
23656
|
-
{
|
|
23657
|
-
evidenceId: Type14.Unknown({
|
|
23658
|
-
description: "observe \u8FD4\u56DE\u7684\u6750\u6599\u6307\u9488\uFF08\u5FC5\u586B\u8BED\u4E49\uFF09"
|
|
23659
|
-
}),
|
|
23660
|
-
category: Type14.Unknown({
|
|
23661
|
-
description: "\u7B80\u77ED\u5F52\u7C7B\u6807\u7B7E\uFF0C\u4E0D\u662F\u6458\u8981"
|
|
23662
|
-
}),
|
|
23663
|
-
summary: Type14.Unknown({
|
|
23664
|
-
description: "\u54EA\u4E2A bot\u3001\u4EC0\u4E48\u95EE\u9898\u7684\u6458\u8981\uFF1B\u4E0D\u8A8A\u6284\u6B63\u6587"
|
|
23665
|
-
})
|
|
23666
|
-
},
|
|
23667
|
-
{
|
|
23668
|
-
additionalProperties: true,
|
|
23669
|
-
description: "\u5355\u6761 finding \u6307\u9488\uFF1AevidenceId\uFF0C\u4EE5\u53CA\u53EF\u9009 category\u3001summary\u3002"
|
|
23670
|
-
}
|
|
23671
|
-
);
|
|
23672
|
-
item.required = [];
|
|
23673
|
-
return item;
|
|
23674
|
-
})();
|
|
23675
21603
|
var collectorOutputBaseSchema = openToolObject(
|
|
23676
21604
|
Type14.Object({
|
|
23677
|
-
|
|
23678
|
-
|
|
23679
|
-
findings: Type14.Unsafe({
|
|
23680
|
-
description: "\u672C\u6B21\u6536\u96C6\u5230\u7684\u9010\u6761 findings \u6307\u9488\u3002",
|
|
23681
|
-
items: collectorFindingItemDeclaration
|
|
21605
|
+
groups: Type14.Unsafe({
|
|
21606
|
+
description: "\u6309\u673A\u5668\u8EAB\u4EFD\u5F52\u7EC4\u7684\u51FA\u5E2D\u3001\u6750\u6599\u4E0E\u9010\u6761 findings\uFF08LLM \u81EA\u884C\u4ECE\u5BBF\u4E3B CLI \u53D6\u8BC1\u6574\u7406\uFF1B\u4EE3\u7801\u4E0D\u4EE3\u6536\u4E0D\u5F52\u5E76\uFF09\u3002"
|
|
23682
21607
|
}),
|
|
23683
21608
|
unfinishedReasons: Type14.Unknown({
|
|
23684
|
-
description: "\u672A\u5B8C\u6210\u539F\u56E0\u3002"
|
|
21609
|
+
description: "\u672A\u5B8C\u6210\u539F\u56E0\uFF1B\u53D6\u8BC1\u53D7\u9650\u65F6\u5982\u5B9E\u62A5\u544A\u3002"
|
|
23685
21610
|
})
|
|
23686
21611
|
})
|
|
23687
21612
|
);
|
|
@@ -23689,146 +21614,9 @@ var collectorOutputArgsSchema = withTerminatingOutputDeclarations(
|
|
|
23689
21614
|
collectorOutputBaseSchema
|
|
23690
21615
|
);
|
|
23691
21616
|
|
|
23692
|
-
// src/collector-handbook.ts
|
|
23693
|
-
function resolveCollectorHandbookRoot(sessionPath) {
|
|
23694
|
-
if (typeof sessionPath !== "string" || sessionPath.trim().length === 0) {
|
|
23695
|
-
throw new Error("\u901A\u8FDB\u53F8\u624B\u518C\u8981\u6C42\u975E\u7A7A session \u8DEF\u5F84\uFF0C\u4E14\u4F4D\u4E8E books/<bookKey>/");
|
|
23696
|
-
}
|
|
23697
|
-
const segments = sessionPath.split(sep6);
|
|
23698
|
-
let bookKey;
|
|
23699
|
-
for (let i = 0; i + 3 < segments.length; i += 1) {
|
|
23700
|
-
if (segments[i] === ".ak-roles" && segments[i + 1] === "books") {
|
|
23701
|
-
const candidate = segments[i + 2];
|
|
23702
|
-
if (candidate.length > 0) {
|
|
23703
|
-
bookKey = candidate;
|
|
23704
|
-
break;
|
|
23705
|
-
}
|
|
23706
|
-
}
|
|
23707
|
-
}
|
|
23708
|
-
if (bookKey === void 0) {
|
|
23709
|
-
throw new Error(
|
|
23710
|
-
`\u901A\u8FDB\u53F8\u624B\u518C\u8981\u6C42 session \u4F4D\u4E8E books/<bookKey>/\uFF1B\u6536\u5230 ${sessionPath}`
|
|
23711
|
-
);
|
|
23712
|
-
}
|
|
23713
|
-
if (bookKey === "." || bookKey === "..") {
|
|
23714
|
-
throw new Error(`\u901A\u8FDB\u53F8\u624B\u518C\u62D2\u7EDD\u4E0D\u5B89\u5168 bookKey ${JSON.stringify(bookKey)}`);
|
|
23715
|
-
}
|
|
23716
|
-
const ledgerHome = resolveActivationLedgerHomeForPath(sessionPath);
|
|
23717
|
-
const root = join40(activationBookDirectory(ledgerHome, bookKey), "collector-handbook");
|
|
23718
|
-
return { ledgerHome, bookKey, root };
|
|
23719
|
-
}
|
|
23720
|
-
function collectorHandbookRepoFileName(repositoryCanonical) {
|
|
23721
|
-
if (!/^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/.test(repositoryCanonical)) {
|
|
23722
|
-
throw new Error(
|
|
23723
|
-
`\u901A\u8FDB\u53F8\u624B\u518C\u4ED3\u5E93\u6587\u4EF6\u8981\u6C42\u89C4\u8303 owner/repo\uFF0C\u6536\u5230 ${JSON.stringify(repositoryCanonical)}`
|
|
23724
|
-
);
|
|
23725
|
-
}
|
|
23726
|
-
return `${repositoryCanonical.replaceAll("/", "__")}.md`;
|
|
23727
|
-
}
|
|
23728
|
-
function createCollectorHandbookStore(input) {
|
|
23729
|
-
const generalPath = join40(input.handbookRoot, "general.md");
|
|
23730
|
-
const repoDir = join40(input.handbookRoot, "repos");
|
|
23731
|
-
const repoPath = join40(repoDir, collectorHandbookRepoFileName(input.repositoryCanonical));
|
|
23732
|
-
const assertHandbookBudget = (body, label) => {
|
|
23733
|
-
const byteLength = Buffer.byteLength(body, "utf8");
|
|
23734
|
-
if (byteLength > COLLECTOR_HANDBOOK_MAX_BYTES) {
|
|
23735
|
-
throw new Error(
|
|
23736
|
-
`\u901A\u8FDB\u53F8\u624B\u518C${label} UTF-8 \u81F3\u591A ${COLLECTOR_HANDBOOK_MAX_BYTES} \u5B57\u8282\uFF0C\u6536\u5230 ${byteLength}`
|
|
23737
|
-
);
|
|
23738
|
-
}
|
|
23739
|
-
return byteLength;
|
|
23740
|
-
};
|
|
23741
|
-
const readOptional = async (path, parentDir2) => {
|
|
23742
|
-
ensureRealDirectoryTree(input.ledgerHome, parentDir2);
|
|
23743
|
-
assertLedgerFileInsideHome(path, input.ledgerHome);
|
|
23744
|
-
try {
|
|
23745
|
-
const body = await readFile22(path, "utf8");
|
|
23746
|
-
assertHandbookBudget(body, "\u6B63\u6587");
|
|
23747
|
-
return body;
|
|
23748
|
-
} catch (error) {
|
|
23749
|
-
if (isNotFound(error)) return void 0;
|
|
23750
|
-
throw error;
|
|
23751
|
-
}
|
|
23752
|
-
};
|
|
23753
|
-
return {
|
|
23754
|
-
root: input.handbookRoot,
|
|
23755
|
-
repositoryCanonical: input.repositoryCanonical,
|
|
23756
|
-
async read() {
|
|
23757
|
-
const bookGeneral = await readOptional(generalPath, input.handbookRoot);
|
|
23758
|
-
const bookRepo = await readOptional(repoPath, repoDir);
|
|
23759
|
-
if (bookGeneral !== void 0) {
|
|
23760
|
-
return {
|
|
23761
|
-
general: bookGeneral,
|
|
23762
|
-
repo: bookRepo ?? "",
|
|
23763
|
-
generalSource: "book",
|
|
23764
|
-
repoSource: bookRepo === void 0 ? "empty" : "book",
|
|
23765
|
-
generalPath,
|
|
23766
|
-
repoPath
|
|
23767
|
-
};
|
|
23768
|
-
}
|
|
23769
|
-
const seed = input.seedGeneral;
|
|
23770
|
-
if (typeof seed === "string" && seed.length > 0) {
|
|
23771
|
-
assertHandbookBudget(seed, "\u6B63\u6587");
|
|
23772
|
-
return {
|
|
23773
|
-
general: seed,
|
|
23774
|
-
repo: bookRepo ?? "",
|
|
23775
|
-
generalSource: "seed",
|
|
23776
|
-
repoSource: bookRepo === void 0 ? "empty" : "book",
|
|
23777
|
-
generalPath,
|
|
23778
|
-
repoPath
|
|
23779
|
-
};
|
|
23780
|
-
}
|
|
23781
|
-
return {
|
|
23782
|
-
general: "",
|
|
23783
|
-
repo: bookRepo ?? "",
|
|
23784
|
-
generalSource: "empty",
|
|
23785
|
-
repoSource: bookRepo === void 0 ? "empty" : "book",
|
|
23786
|
-
generalPath,
|
|
23787
|
-
repoPath
|
|
23788
|
-
};
|
|
23789
|
-
},
|
|
23790
|
-
async write(scope, body) {
|
|
23791
|
-
const byteLength = assertHandbookBudget(body, "\u6B63\u6587");
|
|
23792
|
-
ensureRealDirectoryTree(input.ledgerHome, input.handbookRoot);
|
|
23793
|
-
const path = scope === "general" ? generalPath : repoPath;
|
|
23794
|
-
if (scope === "repo") {
|
|
23795
|
-
ensureRealDirectoryTree(input.ledgerHome, repoDir);
|
|
23796
|
-
}
|
|
23797
|
-
assertLedgerFileInsideHome(path, input.ledgerHome);
|
|
23798
|
-
await writeFileAtomically(path, body);
|
|
23799
|
-
return {
|
|
23800
|
-
scope,
|
|
23801
|
-
path,
|
|
23802
|
-
byteLength
|
|
23803
|
-
};
|
|
23804
|
-
}
|
|
23805
|
-
};
|
|
23806
|
-
}
|
|
23807
|
-
function isNotFound(error) {
|
|
23808
|
-
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
23809
|
-
}
|
|
23810
|
-
|
|
23811
21617
|
// src/collector-role.ts
|
|
23812
|
-
|
|
23813
|
-
|
|
23814
|
-
init_collector_identity();
|
|
23815
|
-
init_collector_identity();
|
|
23816
|
-
var CollectorTargetBindError = class extends CorrectableSubmissionError {
|
|
23817
|
-
constructor(message) {
|
|
23818
|
-
super(message);
|
|
23819
|
-
this.name = "CollectorTargetBindError";
|
|
23820
|
-
}
|
|
23821
|
-
};
|
|
23822
|
-
var COLLECTOR_REQUIRED_TOOLS = [
|
|
23823
|
-
COLLECTOR_BIND_TARGET_TOOL,
|
|
23824
|
-
COLLECTOR_OBSERVE_TOOL,
|
|
23825
|
-
COLLECTOR_READ_TOOL,
|
|
23826
|
-
COLLECTOR_REQUEST_TOOL,
|
|
23827
|
-
COLLECTOR_OPEN_WAIT_WINDOW_TOOL,
|
|
23828
|
-
COLLECTOR_WAIT_TOOL,
|
|
23829
|
-
COLLECTOR_HANDBOOK_WRITE_TOOL,
|
|
23830
|
-
COLLECTOR_OUTPUT_TOOL
|
|
23831
|
-
];
|
|
21618
|
+
var COLLECTOR_REQUIRED_TOOLS = [COLLECTOR_OUTPUT_TOOL];
|
|
21619
|
+
var COLLECTOR_CONSTRUCTION_TOOLS = Object.freeze(["write", "edit"]);
|
|
23832
21620
|
var COLLECTOR_TRANSPORT_FLAGS = Object.freeze([
|
|
23833
21621
|
Object.freeze({
|
|
23834
21622
|
name: "ak-collector-repo",
|
|
@@ -23840,87 +21628,49 @@ var COLLECTOR_TRANSPORT_FLAGS = Object.freeze([
|
|
|
23840
21628
|
Object.freeze({
|
|
23841
21629
|
name: "ak-collector-pr",
|
|
23842
21630
|
definition: Object.freeze({
|
|
23843
|
-
description: "Optional positive safe-integer pull request number for Collector. Omit when the role will
|
|
21631
|
+
description: "Optional positive safe-integer pull request number for Collector. Omit when the role will locate the PR via host CLI.",
|
|
23844
21632
|
type: "string"
|
|
23845
21633
|
})
|
|
23846
21634
|
}),
|
|
23847
21635
|
Object.freeze({
|
|
23848
21636
|
name: "ak-collector-request-manifest",
|
|
23849
21637
|
definition: Object.freeze({
|
|
23850
|
-
description: "Path to the Collector v1 request manifest JSON file.",
|
|
23851
|
-
type: "string"
|
|
23852
|
-
})
|
|
23853
|
-
}),
|
|
23854
|
-
Object.freeze({
|
|
23855
|
-
name: "ak-collector-wait-ms",
|
|
23856
|
-
definition: Object.freeze({
|
|
23857
|
-
description: `Collector wait-window duration in milliseconds (default ${COLLECTOR_DEFAULT_WAIT_WINDOW_MS}). Caller-configurable; opens at a work step, not session start (#678 D4).`,
|
|
21638
|
+
description: "Path to the Collector v1 request manifest JSON file (caller guidance; not a machine collection directive).",
|
|
23858
21639
|
type: "string"
|
|
23859
21640
|
})
|
|
23860
21641
|
})
|
|
23861
21642
|
]);
|
|
23862
|
-
var observeSchema = collectorObserveArgsSchema;
|
|
23863
|
-
var readSchema = collectorReadArgsSchema;
|
|
23864
|
-
var requestSchema = collectorRequestArgsSchema;
|
|
23865
|
-
var openWaitWindowSchema = collectorOpenWaitWindowArgsSchema;
|
|
23866
|
-
var waitSchema = collectorWaitArgsSchema;
|
|
23867
|
-
var bindSchema = collectorBindTargetArgsSchema;
|
|
23868
|
-
var handbookWriteSchema = collectorHandbookWriteArgsSchema;
|
|
23869
21643
|
var outputSchema = collectorOutputArgsSchema;
|
|
23870
|
-
function parseWaitWindowMsFlag(raw) {
|
|
23871
|
-
if (raw === void 0 || raw === null || raw === "") return COLLECTOR_DEFAULT_WAIT_WINDOW_MS;
|
|
23872
|
-
if (typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 1) return raw;
|
|
23873
|
-
if (typeof raw === "string" && /^[1-9]\d*$/.test(raw.trim())) {
|
|
23874
|
-
const value = Number(raw.trim());
|
|
23875
|
-
if (Number.isSafeInteger(value) && value >= 1) return value;
|
|
23876
|
-
}
|
|
23877
|
-
throw new Error("Collector --ak-collector-wait-ms must be a positive safe-integer millisecond string");
|
|
23878
|
-
}
|
|
23879
21644
|
function buildMethodContext(activation) {
|
|
23880
|
-
const pr = activation.ledger.config.prNumber;
|
|
23881
|
-
const handbook = activation.handbookView;
|
|
23882
21645
|
const lines = [
|
|
23883
21646
|
"<collector_method>",
|
|
23884
21647
|
`host: github.com`,
|
|
23885
21648
|
`repository: ${activation.repository.canonical}`,
|
|
23886
|
-
`prNumber: ${
|
|
23887
|
-
`waitWindowMs: ${String(activation.ledger.config.waitWindowMs)}`,
|
|
21649
|
+
`prNumber: ${activation.prNumber === void 0 ? "\u672A\u7ED1\u5B9A" : String(activation.prNumber)}`,
|
|
23888
21650
|
`requests: ${JSON.stringify(activation.manifest.requests.map((request) => ({ id: request.id })))}`,
|
|
23889
|
-
`
|
|
23890
|
-
`handbookRepoSource: ${handbook.repoSource}`,
|
|
21651
|
+
`manifestDigest: ${activation.manifest.digest}`,
|
|
23891
21652
|
"</collector_method>"
|
|
23892
21653
|
];
|
|
23893
|
-
if (
|
|
21654
|
+
if (activation.manifest.requests.length > 0) {
|
|
23894
21655
|
const payload = JSON.stringify({
|
|
23895
|
-
|
|
23896
|
-
|
|
23897
|
-
|
|
23898
|
-
|
|
23899
|
-
repository: activation.repository.canonical
|
|
21656
|
+
requests: activation.manifest.requests.map((request) => ({
|
|
21657
|
+
id: request.id,
|
|
21658
|
+
body: request.requestBody
|
|
21659
|
+
}))
|
|
23900
21660
|
}).replaceAll("<", "\\u003c");
|
|
23901
|
-
lines.push("", "<
|
|
21661
|
+
lines.push("", "<collector_request_manifest>", payload, "</collector_request_manifest>");
|
|
23902
21662
|
}
|
|
23903
21663
|
return lines.join("\n");
|
|
23904
21664
|
}
|
|
23905
|
-
function
|
|
23906
|
-
if (raw === void 0 || raw === null) return void 0;
|
|
23907
|
-
if (typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 1) return raw;
|
|
23908
|
-
if (typeof raw === "string" && /^[1-9]\d*$/.test(raw.trim())) {
|
|
23909
|
-
const value = Number(raw.trim());
|
|
23910
|
-
if (Number.isSafeInteger(value)) return value;
|
|
23911
|
-
}
|
|
23912
|
-
throw new CollectorTargetBindError(`\u901A\u8FDB\u53F8\u7ED1\u5B9A ${label} \u987B\u4E3A\u6B63\u5B89\u5168\u6574\u6570`);
|
|
23913
|
-
}
|
|
23914
|
-
function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
21665
|
+
function createCollectorRoleRuntime(pi, dependencies) {
|
|
23915
21666
|
let toolsRegistered = false;
|
|
23916
21667
|
return {
|
|
23917
|
-
async activate(
|
|
21668
|
+
async activate(_ctx) {
|
|
23918
21669
|
const soul = (await dependencies.loadSoul()).trim();
|
|
23919
21670
|
if (soul.length === 0) throw new Error("Collector soul is empty");
|
|
23920
21671
|
const repoFlag = pi.getFlag("ak-collector-repo");
|
|
23921
21672
|
const prFlag = pi.getFlag("ak-collector-pr");
|
|
23922
21673
|
const requestManifestFlag = pi.getFlag("ak-collector-request-manifest");
|
|
23923
|
-
const waitMsFlag = pi.getFlag("ak-collector-wait-ms");
|
|
23924
21674
|
if (typeof repoFlag !== "string" || repoFlag.trim().length === 0) {
|
|
23925
21675
|
throw new Error("Collector requires --ak-collector-repo");
|
|
23926
21676
|
}
|
|
@@ -23932,36 +21682,11 @@ function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
|
23932
21682
|
prNumber = parseCollectorPrNumber(prFlag);
|
|
23933
21683
|
}
|
|
23934
21684
|
const manifest = typeof requestManifestFlag === "string" && requestManifestFlag.trim().length > 0 ? await loadCollectorManifest(requestManifestFlag) : emptyCollectorManifest();
|
|
23935
|
-
const waitWindowMs = parseWaitWindowMsFlag(waitMsFlag);
|
|
23936
|
-
const clock = dependencies.createClock?.() ?? createSystemCollectorClock();
|
|
23937
|
-
const transport = dependencies.createTransport();
|
|
23938
|
-
const ledger = dependencies.createLedger(
|
|
23939
|
-
{ repository, prNumber, manifest, waitWindowMs },
|
|
23940
|
-
clock,
|
|
23941
|
-
ctx
|
|
23942
|
-
);
|
|
23943
|
-
const sessionPath = ctx.sessionManager?.getSessionFile?.() ?? ctx.sessionManager?.getSessionDir?.();
|
|
23944
|
-
if (typeof sessionPath !== "string" || sessionPath.length === 0) {
|
|
23945
|
-
throw new Error("\u901A\u8FDB\u53F8\u624B\u518C\u8981\u6C42 session \u8DEF\u5F84\u4F4D\u4E8E books/<bookKey>/");
|
|
23946
|
-
}
|
|
23947
|
-
const placement = resolveCollectorHandbookRoot(sessionPath);
|
|
23948
|
-
const seedGeneral = dependencies.loadHandbookSeed === void 0 ? void 0 : (await dependencies.loadHandbookSeed()).trim();
|
|
23949
|
-
const handbook = createCollectorHandbookStore({
|
|
23950
|
-
ledgerHome: placement.ledgerHome,
|
|
23951
|
-
handbookRoot: placement.root,
|
|
23952
|
-
repositoryCanonical: repository.canonical,
|
|
23953
|
-
...seedGeneral === void 0 || seedGeneral.length === 0 ? {} : { seedGeneral }
|
|
23954
|
-
});
|
|
23955
|
-
const handbookView = await handbook.read();
|
|
23956
21685
|
return {
|
|
23957
21686
|
soul,
|
|
23958
21687
|
repository,
|
|
23959
|
-
|
|
23960
|
-
|
|
23961
|
-
transport,
|
|
23962
|
-
clock,
|
|
23963
|
-
handbook,
|
|
23964
|
-
handbookView
|
|
21688
|
+
prNumber,
|
|
21689
|
+
manifest
|
|
23965
21690
|
};
|
|
23966
21691
|
},
|
|
23967
21692
|
assembleMaterials(activation, baseSystemPrompt) {
|
|
@@ -23975,335 +21700,32 @@ function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
|
23975
21700
|
buildMethodContext(activation)
|
|
23976
21701
|
].join("\n");
|
|
23977
21702
|
},
|
|
23978
|
-
onToolCall(
|
|
23979
|
-
if (
|
|
21703
|
+
onToolCall(_activation, event) {
|
|
21704
|
+
if (COLLECTOR_CONSTRUCTION_TOOLS.includes(event.toolName)) {
|
|
23980
21705
|
return {
|
|
23981
21706
|
block: true,
|
|
23982
|
-
reason:
|
|
21707
|
+
reason: `\u901A\u8FDB\u53F8\u4E3A\u6536\u8BC1\u5E2D\uFF0C\u7981\u7528\u65BD\u5DE5\u5DE5\u5177 ${event.toolName}`
|
|
23983
21708
|
};
|
|
23984
21709
|
}
|
|
23985
|
-
if (event.toolName === COLLECTOR_OUTPUT_TOOL) {
|
|
23986
|
-
activation.ledger.beginOperational(COLLECTOR_OUTPUT_TOOL, event.toolCallId);
|
|
23987
|
-
}
|
|
23988
21710
|
return void 0;
|
|
23989
21711
|
},
|
|
23990
|
-
onToolResult(activation, event) {
|
|
23991
|
-
activation.ledger.completeOperational(event.toolCallId);
|
|
23992
|
-
},
|
|
23993
21712
|
registerBusinessTools(getActivation) {
|
|
23994
21713
|
if (toolsRegistered) return;
|
|
23995
21714
|
toolsRegistered = true;
|
|
23996
|
-
pi.registerTool({
|
|
23997
|
-
name: COLLECTOR_BIND_TARGET_TOOL,
|
|
23998
|
-
label: "\u901A\u8FDB\u53F8\u8BA4\u7968\u7ED1\u5B9A",
|
|
23999
|
-
description: "\u7ED1\u5B9A\u672C\u4ED3\u552F\u4E00 PR \u76EE\u6807\u3002",
|
|
24000
|
-
promptSnippet: "\u7ED1\u5B9A\u89D2\u8272\u5224\u5B9A\u7684 issue/PR \u76EE\u6807",
|
|
24001
|
-
parameters: bindSchema,
|
|
24002
|
-
async execute(toolCallId, params, _signal, _onUpdate, ctx) {
|
|
24003
|
-
const activation = getActivation();
|
|
24004
|
-
if (activation === void 0) throw new Error("\u901A\u8FDB\u53F8\u672A\u6FC0\u6D3B");
|
|
24005
|
-
try {
|
|
24006
|
-
activation.ledger.beginOperational(COLLECTOR_BIND_TARGET_TOOL, toolCallId);
|
|
24007
|
-
const prNumber = parsePositiveTicket(params.prNumber, "prNumber");
|
|
24008
|
-
const issueNumber = parsePositiveTicket(params.issueNumber, "issueNumber");
|
|
24009
|
-
if (prNumber === void 0 && issueNumber === void 0) {
|
|
24010
|
-
throw new CollectorTargetBindError(
|
|
24011
|
-
"\u901A\u8FDB\u53F8\u7ED1\u5B9A\u987B\u7531\u89D2\u8272\u5224\u5B9A prNumber \u4E0E/\u6216 issueNumber"
|
|
24012
|
-
);
|
|
24013
|
-
}
|
|
24014
|
-
let bound = prNumber;
|
|
24015
|
-
let associated = [];
|
|
24016
|
-
if (issueNumber !== void 0) {
|
|
24017
|
-
associated = await listPullRequestNumbersByTicket(createGhApiRunner(), {
|
|
24018
|
-
owner: activation.repository.owner,
|
|
24019
|
-
repo: activation.repository.repo,
|
|
24020
|
-
ticketNumber: issueNumber
|
|
24021
|
-
});
|
|
24022
|
-
if (bound === void 0 && associated.length === 1) {
|
|
24023
|
-
bound = associated[0];
|
|
24024
|
-
}
|
|
24025
|
-
}
|
|
24026
|
-
if (bound === void 0) {
|
|
24027
|
-
return {
|
|
24028
|
-
content: [{
|
|
24029
|
-
type: "text",
|
|
24030
|
-
text: JSON.stringify({
|
|
24031
|
-
bound: false,
|
|
24032
|
-
repository: activation.repository.canonical,
|
|
24033
|
-
prNumber: prNumber ?? null,
|
|
24034
|
-
issueNumber: issueNumber ?? null,
|
|
24035
|
-
associated
|
|
24036
|
-
})
|
|
24037
|
-
}],
|
|
24038
|
-
details: {
|
|
24039
|
-
bound: false,
|
|
24040
|
-
repository: activation.repository.canonical,
|
|
24041
|
-
prNumber: prNumber ?? null,
|
|
24042
|
-
issueNumber: issueNumber ?? null,
|
|
24043
|
-
associated
|
|
24044
|
-
}
|
|
24045
|
-
};
|
|
24046
|
-
}
|
|
24047
|
-
activation.ledger.bindTarget(bound);
|
|
24048
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24049
|
-
return {
|
|
24050
|
-
content: [{
|
|
24051
|
-
type: "text",
|
|
24052
|
-
text: `\u76EE\u6807\u5DF2\u7ED1\u5B9A\uFF1A${activation.repository.canonical}#${bound}`
|
|
24053
|
-
}],
|
|
24054
|
-
details: {
|
|
24055
|
-
bound: true,
|
|
24056
|
-
repository: activation.repository.canonical,
|
|
24057
|
-
prNumber: bound,
|
|
24058
|
-
issueNumber: issueNumber ?? null,
|
|
24059
|
-
associated
|
|
24060
|
-
}
|
|
24061
|
-
};
|
|
24062
|
-
} catch (error) {
|
|
24063
|
-
if (isCorrectableExecuteError(error)) throw error;
|
|
24064
|
-
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
24065
|
-
} finally {
|
|
24066
|
-
try {
|
|
24067
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24068
|
-
} catch {
|
|
24069
|
-
}
|
|
24070
|
-
}
|
|
24071
|
-
}
|
|
24072
|
-
});
|
|
24073
|
-
pi.registerTool({
|
|
24074
|
-
name: COLLECTOR_OBSERVE_TOOL,
|
|
24075
|
-
label: "\u901A\u8FDB\u53F8\u89C2\u5BDF",
|
|
24076
|
-
description: "\u6293\u53D6\u914D\u7F6E\u76EE\u6807\u7684 GitHub PR \u8BC1\u636E\u3002",
|
|
24077
|
-
promptSnippet: "\u6293\u53D6\u914D\u7F6E\u76EE\u6807 PR \u8BC1\u636E",
|
|
24078
|
-
parameters: observeSchema,
|
|
24079
|
-
async execute(toolCallId, _params, signal, _onUpdate, ctx) {
|
|
24080
|
-
const activation = getActivation();
|
|
24081
|
-
if (activation === void 0) throw new Error("\u901A\u8FDB\u53F8\u672A\u6FC0\u6D3B");
|
|
24082
|
-
try {
|
|
24083
|
-
activation.ledger.beginOperational(COLLECTOR_OBSERVE_TOOL, toolCallId);
|
|
24084
|
-
const { snapshot, contextView } = await activation.ledger.observe(
|
|
24085
|
-
activation.transport,
|
|
24086
|
-
activation.clock,
|
|
24087
|
-
signal
|
|
24088
|
-
);
|
|
24089
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24090
|
-
return {
|
|
24091
|
-
content: [{
|
|
24092
|
-
type: "text",
|
|
24093
|
-
text: JSON.stringify(contextView)
|
|
24094
|
-
}],
|
|
24095
|
-
details: contextView
|
|
24096
|
-
};
|
|
24097
|
-
} catch (error) {
|
|
24098
|
-
if (isCorrectableExecuteError(error)) throw error;
|
|
24099
|
-
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
24100
|
-
}
|
|
24101
|
-
}
|
|
24102
|
-
});
|
|
24103
|
-
pi.registerTool({
|
|
24104
|
-
name: COLLECTOR_READ_TOOL,
|
|
24105
|
-
label: "\u901A\u8FDB\u53F8\u5F00\u5377",
|
|
24106
|
-
description: "\u6309 evidenceId \u5F00\u5377\u8BFB\u53D6\u4E00\u6761\u5DF2\u89C2\u6D4B\u6750\u6599\u7684\u5168\u91CF\u6B63\u6587\u4E0E\u6307\u9488\u3002",
|
|
24107
|
-
promptSnippet: "\u6309\u6307\u9488\u5F00\u5377\u8BFB\u6750\u6599",
|
|
24108
|
-
parameters: readSchema,
|
|
24109
|
-
async execute(toolCallId, params, _signal, _onUpdate, ctx) {
|
|
24110
|
-
const activation = getActivation();
|
|
24111
|
-
if (activation === void 0) throw new Error("\u901A\u8FDB\u53F8\u672A\u6FC0\u6D3B");
|
|
24112
|
-
try {
|
|
24113
|
-
activation.ledger.beginOperational(COLLECTOR_READ_TOOL, toolCallId);
|
|
24114
|
-
const record4 = activation.ledger.getEvidence(params.evidenceId);
|
|
24115
|
-
if (record4 === void 0 || record4.kind !== "review" && record4.kind !== "issue_comment" && record4.kind !== "review_comment" && record4.kind !== "reaction" || typeof record4.body !== "string") {
|
|
24116
|
-
throw new CollectorUnknownEvidenceError(params.evidenceId);
|
|
24117
|
-
}
|
|
24118
|
-
const material = projectEvidenceEntryView(record4);
|
|
24119
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24120
|
-
return {
|
|
24121
|
-
content: [{
|
|
24122
|
-
type: "text",
|
|
24123
|
-
text: JSON.stringify(material)
|
|
24124
|
-
}],
|
|
24125
|
-
details: material
|
|
24126
|
-
};
|
|
24127
|
-
} catch (error) {
|
|
24128
|
-
if (isCorrectableExecuteError(error)) throw error;
|
|
24129
|
-
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
24130
|
-
}
|
|
24131
|
-
}
|
|
24132
|
-
});
|
|
24133
|
-
pi.registerTool({
|
|
24134
|
-
name: COLLECTOR_REQUEST_TOOL,
|
|
24135
|
-
label: "\u901A\u8FDB\u53F8\u8BF7\u6C42",
|
|
24136
|
-
description: "\u53D1\u4E00\u6B21\u8BF7\u6C42\u3002",
|
|
24137
|
-
promptSnippet: "\u53D1\u4E00\u6B21\u8BC4\u5BA1\u8BF7\u6C42",
|
|
24138
|
-
parameters: requestSchema,
|
|
24139
|
-
async execute(toolCallId, params, signal, _onUpdate, ctx) {
|
|
24140
|
-
const activation = getActivation();
|
|
24141
|
-
if (activation === void 0) throw new Error("\u901A\u8FDB\u53F8\u672A\u6FC0\u6D3B");
|
|
24142
|
-
try {
|
|
24143
|
-
activation.ledger.beginOperational(COLLECTOR_REQUEST_TOOL, toolCallId);
|
|
24144
|
-
const details = await activation.ledger.request(
|
|
24145
|
-
{
|
|
24146
|
-
requestId: params.requestId,
|
|
24147
|
-
snapshotId: params.snapshotId,
|
|
24148
|
-
...typeof params.body === "string" ? { body: params.body } : {}
|
|
24149
|
-
},
|
|
24150
|
-
activation.transport,
|
|
24151
|
-
activation.clock,
|
|
24152
|
-
signal
|
|
24153
|
-
);
|
|
24154
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24155
|
-
return {
|
|
24156
|
-
content: [{
|
|
24157
|
-
type: "text",
|
|
24158
|
-
text: `\u8BF7\u6C42\u5C1D\u8BD5\u5DF2\u8BB0\u5F55\uFF1Arequest ${params.requestId}`
|
|
24159
|
-
}],
|
|
24160
|
-
details
|
|
24161
|
-
};
|
|
24162
|
-
} catch (error) {
|
|
24163
|
-
if (isCorrectableExecuteError(error)) throw error;
|
|
24164
|
-
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
24165
|
-
}
|
|
24166
|
-
}
|
|
24167
|
-
});
|
|
24168
|
-
pi.registerTool({
|
|
24169
|
-
name: COLLECTOR_HANDBOOK_WRITE_TOOL,
|
|
24170
|
-
label: "\u901A\u8FDB\u53F8\u624B\u518C\u5199\u5165",
|
|
24171
|
-
description: "\u5199\u5165\u901A\u7528\u624B\u518C\u6216\u5F53\u524D\u4ED3\u5E93\u5DEE\u5F02\u5168\u6587\uFF08\u6574\u4EFD\u66FF\u6362\uFF09\u3002",
|
|
24172
|
-
promptSnippet: "\u66F4\u65B0 bot \u624B\u518C",
|
|
24173
|
-
parameters: handbookWriteSchema,
|
|
24174
|
-
async execute(toolCallId, params, _signal, _onUpdate, ctx) {
|
|
24175
|
-
const activation = getActivation();
|
|
24176
|
-
if (activation === void 0) throw new Error("\u901A\u8FDB\u53F8\u672A\u6FC0\u6D3B");
|
|
24177
|
-
try {
|
|
24178
|
-
activation.ledger.beginOperational(COLLECTOR_HANDBOOK_WRITE_TOOL, toolCallId);
|
|
24179
|
-
const details = await activation.handbook.write(params.scope, params.body);
|
|
24180
|
-
activation.handbookView = await activation.handbook.read();
|
|
24181
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24182
|
-
return {
|
|
24183
|
-
content: [{
|
|
24184
|
-
type: "text",
|
|
24185
|
-
text: `\u624B\u518C\u5DF2\u5199\u5165\uFF1A${details.scope}`
|
|
24186
|
-
}],
|
|
24187
|
-
details: {
|
|
24188
|
-
scope: details.scope,
|
|
24189
|
-
path: details.path,
|
|
24190
|
-
byteLength: details.byteLength,
|
|
24191
|
-
generalSource: activation.handbookView.generalSource,
|
|
24192
|
-
repoSource: activation.handbookView.repoSource
|
|
24193
|
-
}
|
|
24194
|
-
};
|
|
24195
|
-
} catch (error) {
|
|
24196
|
-
if (isCorrectableExecuteError(error)) throw error;
|
|
24197
|
-
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
24198
|
-
} finally {
|
|
24199
|
-
try {
|
|
24200
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24201
|
-
} catch {
|
|
24202
|
-
}
|
|
24203
|
-
}
|
|
24204
|
-
}
|
|
24205
|
-
});
|
|
24206
|
-
pi.registerTool({
|
|
24207
|
-
name: COLLECTOR_OPEN_WAIT_WINDOW_TOOL,
|
|
24208
|
-
label: "\u901A\u8FDB\u53F8\u5F00\u542F\u7B49\u5F85\u7A97",
|
|
24209
|
-
description: "\u5728\u5DE5\u4F5C\u6B65\u9AA4\u4E0A\u5F00\u542F\u7B49\u5F85\u7A97\uFF1A\u65B0\u5EFA\u5E76\u81EA\u52A8\u89E6\u53D1\u7684 PR \u4F20\u521B\u5EFA\u6210\u529F\u65F6\u523B\uFF1B\u5DF2\u6709 PR \u5728\u89E6\u53D1\u9636\u6BB5\u7ED3\u675F\u540E\u7701\u7565 startedAt\uFF08=\u73B0\u5728\uFF09\u3002\u7A97\u957F\u7531\u4F7F\u7528\u65B9\u914D\u7F6E\uFF0C\u9ED8\u8BA4\u5341\u5206\u949F\uFF1B\u5F00\u542F\u540E\u4E0D\u56E0 PR \u66F4\u65B0\u91CD\u7F6E\u3002",
|
|
24210
|
-
promptSnippet: "\u6309\u5DE5\u4F5C\u6B65\u9AA4\u5F00\u542F\u7B49\u5F85\u7A97",
|
|
24211
|
-
parameters: openWaitWindowSchema,
|
|
24212
|
-
async execute(toolCallId, params, _signal, _onUpdate, ctx) {
|
|
24213
|
-
const activation = getActivation();
|
|
24214
|
-
if (activation === void 0) throw new Error("\u901A\u8FDB\u53F8\u672A\u6FC0\u6D3B");
|
|
24215
|
-
try {
|
|
24216
|
-
activation.ledger.beginOperational(COLLECTOR_OPEN_WAIT_WINDOW_TOOL, toolCallId);
|
|
24217
|
-
let startedAt;
|
|
24218
|
-
if (typeof params.startedAt === "string" && params.startedAt.trim().length > 0) {
|
|
24219
|
-
const parsed = new Date(params.startedAt);
|
|
24220
|
-
if (Number.isNaN(parsed.getTime())) {
|
|
24221
|
-
throw new Error("\u901A\u8FDB\u53F8\u7B49\u5F85\u7A97 startedAt \u987B\u4E3A\u6709\u6548 ISO \u65F6\u95F4");
|
|
24222
|
-
}
|
|
24223
|
-
startedAt = parsed;
|
|
24224
|
-
}
|
|
24225
|
-
activation.ledger.openWaitWindow(
|
|
24226
|
-
activation.clock,
|
|
24227
|
-
startedAt === void 0 ? void 0 : { startedAt }
|
|
24228
|
-
);
|
|
24229
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24230
|
-
return {
|
|
24231
|
-
content: [{
|
|
24232
|
-
type: "text",
|
|
24233
|
-
text: "\u7B49\u5F85\u7A97\u5DF2\u5F00\u542F"
|
|
24234
|
-
}],
|
|
24235
|
-
details: {
|
|
24236
|
-
activationTime: activation.ledger.activationTime?.toISOString(),
|
|
24237
|
-
deadlineTime: activation.ledger.deadlineTime?.toISOString(),
|
|
24238
|
-
waitWindowMs: activation.ledger.config.waitWindowMs
|
|
24239
|
-
}
|
|
24240
|
-
};
|
|
24241
|
-
} catch (error) {
|
|
24242
|
-
if (isCorrectableExecuteError(error)) throw error;
|
|
24243
|
-
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
24244
|
-
} finally {
|
|
24245
|
-
try {
|
|
24246
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24247
|
-
} catch {
|
|
24248
|
-
}
|
|
24249
|
-
}
|
|
24250
|
-
}
|
|
24251
|
-
});
|
|
24252
|
-
pi.registerTool({
|
|
24253
|
-
name: COLLECTOR_WAIT_TOOL,
|
|
24254
|
-
label: "\u901A\u8FDB\u53F8\u7B49\u5F85",
|
|
24255
|
-
description: "\u7B49\u5F85\u3002\u5B9E\u9645\u7761\u7720\u4E0D\u8D85\u8FC7\u5269\u4F59\u7B49\u5F85\u7A97\u3002",
|
|
24256
|
-
promptSnippet: "\u7B49\u5F85\u7A97\u5185\u7B49\u5F85",
|
|
24257
|
-
parameters: waitSchema,
|
|
24258
|
-
async execute(toolCallId, params, signal, _onUpdate, ctx) {
|
|
24259
|
-
const activation = getActivation();
|
|
24260
|
-
if (activation === void 0) throw new Error("\u901A\u8FDB\u53F8\u672A\u6FC0\u6D3B");
|
|
24261
|
-
try {
|
|
24262
|
-
activation.ledger.beginOperational(COLLECTOR_WAIT_TOOL, toolCallId);
|
|
24263
|
-
const details = await activation.ledger.wait(
|
|
24264
|
-
params,
|
|
24265
|
-
activation.clock,
|
|
24266
|
-
signal
|
|
24267
|
-
);
|
|
24268
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24269
|
-
return {
|
|
24270
|
-
content: [{
|
|
24271
|
-
type: "text",
|
|
24272
|
-
text: `\u5DF2\u7B49\u5F85 ${String(details.effectiveMs)}ms`
|
|
24273
|
-
}],
|
|
24274
|
-
details
|
|
24275
|
-
};
|
|
24276
|
-
} catch (error) {
|
|
24277
|
-
if (isCorrectableExecuteError(error)) throw error;
|
|
24278
|
-
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
24279
|
-
}
|
|
24280
|
-
}
|
|
24281
|
-
});
|
|
24282
21715
|
pi.registerTool({
|
|
24283
21716
|
name: COLLECTOR_OUTPUT_TOOL,
|
|
24284
21717
|
label: "\u901A\u8FDB\u53F8\u8F93\u51FA",
|
|
24285
21718
|
description: "\u63D0\u4EA4\u901A\u8FDB\u53F8\u56DE\u6267\u3002",
|
|
24286
21719
|
promptSnippet: "\u63D0\u4EA4\u901A\u8FDB\u53F8\u56DE\u6267",
|
|
24287
21720
|
parameters: outputSchema,
|
|
24288
|
-
async execute(
|
|
21721
|
+
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
24289
21722
|
const activation = getActivation();
|
|
24290
21723
|
if (activation === void 0) throw new Error("\u901A\u8FDB\u53F8\u672A\u6FC0\u6D3B");
|
|
24291
|
-
|
|
24292
|
-
|
|
24293
|
-
|
|
24294
|
-
|
|
24295
|
-
|
|
24296
|
-
details: params,
|
|
24297
|
-
terminate: true
|
|
24298
|
-
};
|
|
24299
|
-
} catch (error) {
|
|
24300
|
-
if (error instanceof Error && error.collectorFatal === true) {
|
|
24301
|
-
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
24302
|
-
}
|
|
24303
|
-
throw error;
|
|
24304
|
-
} finally {
|
|
24305
|
-
activation.ledger.completeOperational(toolCallId);
|
|
24306
|
-
}
|
|
21724
|
+
return {
|
|
21725
|
+
content: [],
|
|
21726
|
+
details: params,
|
|
21727
|
+
terminate: true
|
|
21728
|
+
};
|
|
24307
21729
|
}
|
|
24308
21730
|
});
|
|
24309
21731
|
}
|
|
@@ -24740,7 +22162,7 @@ var AUDITOR_TOOL_SPEC = {
|
|
|
24740
22162
|
};
|
|
24741
22163
|
|
|
24742
22164
|
// src/navigator-attendance.ts
|
|
24743
|
-
import { createHash as
|
|
22165
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
24744
22166
|
init_navigator_invocation_identity();
|
|
24745
22167
|
init_packaged_role_registry();
|
|
24746
22168
|
init_activation_ledger_topology();
|
|
@@ -24945,11 +22367,11 @@ init_packaged_role_registry();
|
|
|
24945
22367
|
// src/navigator-work-base.ts
|
|
24946
22368
|
init_atomic_write();
|
|
24947
22369
|
import { existsSync as existsSync10, realpathSync as realpathSync3 } from "node:fs";
|
|
24948
|
-
import { readFile as
|
|
24949
|
-
import { basename as basename10, dirname as dirname22, join as
|
|
22370
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
22371
|
+
import { basename as basename10, dirname as dirname22, join as join40, resolve as resolve16 } from "node:path";
|
|
24950
22372
|
var NAVIGATOR_WORK_CONTEXT_BASENAME = "work-context.json";
|
|
24951
22373
|
function navigatorWorkContextFile(sessionDir) {
|
|
24952
|
-
return
|
|
22374
|
+
return join40(sessionDir, NAVIGATOR_WORK_CONTEXT_BASENAME);
|
|
24953
22375
|
}
|
|
24954
22376
|
function isNavigatorWorkContextFile(path) {
|
|
24955
22377
|
const resolved = resolve16(path);
|
|
@@ -24974,7 +22396,7 @@ async function persistNavigatorWorkBase(sessionDir, body) {
|
|
|
24974
22396
|
const next = `${JSON.stringify({ subject: body.subject, authority: body.authority })}
|
|
24975
22397
|
`;
|
|
24976
22398
|
try {
|
|
24977
|
-
const current = await
|
|
22399
|
+
const current = await readFile22(path, "utf8");
|
|
24978
22400
|
if (current === next) return path;
|
|
24979
22401
|
} catch (error) {
|
|
24980
22402
|
if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
|
|
@@ -24989,7 +22411,7 @@ async function readNavigatorWorkBase(path) {
|
|
|
24989
22411
|
if (canonical === void 0) return void 0;
|
|
24990
22412
|
let text;
|
|
24991
22413
|
try {
|
|
24992
|
-
text = await
|
|
22414
|
+
text = await readFile22(canonical, "utf8");
|
|
24993
22415
|
} catch (error) {
|
|
24994
22416
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
24995
22417
|
return void 0;
|
|
@@ -25301,7 +22723,7 @@ function navigatorSubjectKey(subjectRoot, subject, provenance = "role_input") {
|
|
|
25301
22723
|
if (provenance === "placeholder") return subjectRoot;
|
|
25302
22724
|
const normalized = subject.trim().replace(/\s+/g, " ");
|
|
25303
22725
|
if (normalized === "") return subjectRoot;
|
|
25304
|
-
return `${subjectRoot}#${
|
|
22726
|
+
return `${subjectRoot}#${createHash5("sha256").update(normalized).digest("hex").slice(0, 32)}`;
|
|
25305
22727
|
}
|
|
25306
22728
|
function navigatorSubjectKeyForInput(subjectRoot, reference, cwd = process.cwd()) {
|
|
25307
22729
|
if (issueRoot(subjectRoot) !== void 0 || !subjectRoot.includes("/.ak/work/")) return subjectRoot;
|
|
@@ -25789,7 +23211,7 @@ init_submission_errors();
|
|
|
25789
23211
|
init_worker_submission_contracts();
|
|
25790
23212
|
init_submission_errors();
|
|
25791
23213
|
init_worker_submission_contracts();
|
|
25792
|
-
import { execFileSync as
|
|
23214
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
25793
23215
|
import { existsSync as existsSync14, lstatSync as lstatSync3, readdirSync as readdirSync4, readFileSync as readFileSync5, rmdirSync, rmSync as rmSync2 } from "node:fs";
|
|
25794
23216
|
import { resolve as resolve19 } from "node:path";
|
|
25795
23217
|
var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
|
|
@@ -25802,7 +23224,7 @@ var HOOK_FILE = "reference-transaction";
|
|
|
25802
23224
|
var PLATFORM_PREFIX = /^[A-Za-z][A-Za-z0-9_-]*:/;
|
|
25803
23225
|
var UNFINISHED_REASON_BOUNCE_LIMIT = 2;
|
|
25804
23226
|
function git2(cwd, args) {
|
|
25805
|
-
return
|
|
23227
|
+
return execFileSync3("git", args, {
|
|
25806
23228
|
cwd,
|
|
25807
23229
|
encoding: "utf8",
|
|
25808
23230
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -25810,7 +23232,7 @@ function git2(cwd, args) {
|
|
|
25810
23232
|
}).trim();
|
|
25811
23233
|
}
|
|
25812
23234
|
function gitFile(file, args) {
|
|
25813
|
-
return
|
|
23235
|
+
return execFileSync3("git", ["config", "--file", file, ...args], {
|
|
25814
23236
|
encoding: "utf8",
|
|
25815
23237
|
stdio: ["ignore", "pipe", "pipe"],
|
|
25816
23238
|
env: { ...process.env, GIT_DIR: void 0, GIT_WORK_TREE: void 0, GIT_COMMON_DIR: void 0 }
|
|
@@ -25886,7 +23308,7 @@ function uninstallPackageWorkerHooks(cwd) {
|
|
|
25886
23308
|
rmOwnedDir(resolve19(gitDir, HOOKS_DIR));
|
|
25887
23309
|
}
|
|
25888
23310
|
}
|
|
25889
|
-
function
|
|
23311
|
+
function isRecord15(value) {
|
|
25890
23312
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25891
23313
|
}
|
|
25892
23314
|
function unfinishedReasonPresent(details) {
|
|
@@ -25902,7 +23324,7 @@ function readGateState(session) {
|
|
|
25902
23324
|
if (entry.type !== "custom") continue;
|
|
25903
23325
|
if (entry.customType === WORKER_COMMIT_BASELINE_ENTRY_TYPE) {
|
|
25904
23326
|
const data = entry.data;
|
|
25905
|
-
if (
|
|
23327
|
+
if (isRecord15(data) && (data.head === null || typeof data.head === "string")) {
|
|
25906
23328
|
baseline = data.head;
|
|
25907
23329
|
}
|
|
25908
23330
|
} else if (entry.customType === WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE) {
|
|
@@ -25928,11 +23350,11 @@ function reliableWindow(cwd, baseline, head) {
|
|
|
25928
23350
|
const raw = git2(cwd, ["log", "--format=%P%x1e%s", range]);
|
|
25929
23351
|
if (raw.length === 0) return [];
|
|
25930
23352
|
return raw.split("\n").flatMap((line2) => {
|
|
25931
|
-
const
|
|
25932
|
-
if (
|
|
23353
|
+
const sep6 = line2.indexOf("");
|
|
23354
|
+
if (sep6 < 0) return [];
|
|
25933
23355
|
return [{
|
|
25934
|
-
subject: line2.slice(
|
|
25935
|
-
merge: line2.slice(0,
|
|
23356
|
+
subject: line2.slice(sep6 + 1),
|
|
23357
|
+
merge: line2.slice(0, sep6).trim().includes(" ")
|
|
25936
23358
|
}];
|
|
25937
23359
|
});
|
|
25938
23360
|
}
|
|
@@ -26095,11 +23517,11 @@ var FIXER_PHASES = ["plan", "apply"];
|
|
|
26095
23517
|
function isWorkerPhase(value) {
|
|
26096
23518
|
return typeof value === "string" && FIXER_PHASES.includes(value);
|
|
26097
23519
|
}
|
|
26098
|
-
function
|
|
23520
|
+
function isRecord16(value) {
|
|
26099
23521
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26100
23522
|
}
|
|
26101
23523
|
function workerStatusOf(output) {
|
|
26102
|
-
return
|
|
23524
|
+
return isRecord16(output) && typeof output.status === "string" ? output.status : void 0;
|
|
26103
23525
|
}
|
|
26104
23526
|
function deepFreeze2(value) {
|
|
26105
23527
|
if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
|
|
@@ -26785,7 +24207,7 @@ function readDiaristTicketAssertion(submitted) {
|
|
|
26785
24207
|
function readRoleRunCoordinates(ctx, label) {
|
|
26786
24208
|
const runDirectory = runDirectoryFromHostContext(ctx);
|
|
26787
24209
|
if (runDirectory === void 0) throw new Error(`${label} requires AK_ROLE_RUN_DIR`);
|
|
26788
|
-
const admittedPath =
|
|
24210
|
+
const admittedPath = join44(runDirectory, "admitted-request.json");
|
|
26789
24211
|
const admitted = JSON.parse(readFileSync6(admittedPath, "utf8"));
|
|
26790
24212
|
if (typeof admitted.projectRoot !== "string" || admitted.projectRoot.trim() === "") {
|
|
26791
24213
|
throw new Error(`${label} admitted-request missing projectRoot (${admittedPath})`);
|
|
@@ -27097,10 +24519,6 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27097
24519
|
};
|
|
27098
24520
|
}
|
|
27099
24521
|
if (activeCollector !== void 0 && selectedRole === role) {
|
|
27100
|
-
if (!collectorFirstDispatchDone) {
|
|
27101
|
-
collectorFirstDispatchDone = true;
|
|
27102
|
-
activeCollector.ledger.recordActivation(activeCollector.clock);
|
|
27103
|
-
}
|
|
27104
24522
|
return {
|
|
27105
24523
|
systemPrompt: collectorBusiness.assembleMaterials(activeCollector, event.systemPrompt)
|
|
27106
24524
|
};
|
|
@@ -27141,9 +24559,6 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27141
24559
|
roleHost.on("tool_result", async (event) => {
|
|
27142
24560
|
const role = selectedRole;
|
|
27143
24561
|
if (role === void 0) return;
|
|
27144
|
-
if (activeCollector !== void 0 && selectedRole === roleHost.getFlag(ROLE_FLAG.name)) {
|
|
27145
|
-
collectorBusiness.onToolResult(activeCollector, event);
|
|
27146
|
-
}
|
|
27147
24562
|
const pendingInfra = pendingInfrastructureFailures.get(event.toolCallId);
|
|
27148
24563
|
const isRoleInfrastructureFailure = pendingInfra !== void 0;
|
|
27149
24564
|
if (pendingInfra !== void 0) pendingInfrastructureFailures.delete(event.toolCallId);
|
|
@@ -27278,11 +24693,6 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27278
24693
|
priorFetch = void 0;
|
|
27279
24694
|
fetchWrapped = false;
|
|
27280
24695
|
}
|
|
27281
|
-
if (activeCollector !== void 0 && activeCollector.ledger.fatal) {
|
|
27282
|
-
if (process.exitCode === void 0 || process.exitCode === 0) {
|
|
27283
|
-
process.exitCode = 1;
|
|
27284
|
-
}
|
|
27285
|
-
}
|
|
27286
24696
|
const presentation = pendingNavigatorPresentation;
|
|
27287
24697
|
pendingNavigatorPresentation = void 0;
|
|
27288
24698
|
if (presentation !== void 0) {
|
|
@@ -27414,41 +24824,16 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27414
24824
|
}
|
|
27415
24825
|
});
|
|
27416
24826
|
let activeCollector;
|
|
27417
|
-
let collectorFirstDispatchDone = false;
|
|
27418
24827
|
const collectorBusiness = createCollectorRoleRuntime(
|
|
27419
24828
|
roleHost,
|
|
27420
24829
|
{
|
|
27421
|
-
loadSoul: () => requireRoleSoul("collector")
|
|
27422
|
-
|
|
27423
|
-
if (dependencies.createCollectorTransport === void 0) {
|
|
27424
|
-
throw new Error("Collector GitHub transport is not configured");
|
|
27425
|
-
}
|
|
27426
|
-
return dependencies.createCollectorTransport();
|
|
27427
|
-
},
|
|
27428
|
-
createLedger(config, collectorClock, context) {
|
|
27429
|
-
const append = context.sessionManager?.appendCustomEntry;
|
|
27430
|
-
return createCollectorLedger(config, {
|
|
27431
|
-
clock: collectorClock,
|
|
27432
|
-
...append === void 0 ? {} : {
|
|
27433
|
-
journal: {
|
|
27434
|
-
append(customType, data) {
|
|
27435
|
-
context.sessionManager?.appendCustomEntry?.(customType, data);
|
|
27436
|
-
}
|
|
27437
|
-
}
|
|
27438
|
-
},
|
|
27439
|
-
dossierEntries: context.sessionManager?.getEntries?.() ?? []
|
|
27440
|
-
});
|
|
27441
|
-
},
|
|
27442
|
-
...dependencies.createCollectorClock === void 0 ? {} : { createClock: dependencies.createCollectorClock },
|
|
27443
|
-
...dependencies.loadCollectorHandbookSeed === void 0 ? {} : { loadHandbookSeed: dependencies.loadCollectorHandbookSeed }
|
|
27444
|
-
},
|
|
27445
|
-
hostActions
|
|
24830
|
+
loadSoul: () => requireRoleSoul("collector")
|
|
24831
|
+
}
|
|
27446
24832
|
);
|
|
27447
24833
|
let collectorToolCallRegistered = false;
|
|
27448
24834
|
const collector = {
|
|
27449
24835
|
async activate(context, event) {
|
|
27450
24836
|
activeCollector = void 0;
|
|
27451
|
-
collectorFirstDispatchDone = false;
|
|
27452
24837
|
if (context.mode !== "print" && context.mode !== "json") {
|
|
27453
24838
|
throw new Error(
|
|
27454
24839
|
`Collector supports only print or json mode (got ${context.mode})`
|
|
@@ -27482,16 +24867,19 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27482
24867
|
throw new Error(`Collector required tool name collision: ${required}`);
|
|
27483
24868
|
}
|
|
27484
24869
|
}
|
|
27485
|
-
roleHost.
|
|
24870
|
+
const priorActive = roleHost.getActiveTools();
|
|
24871
|
+
const hostSurface = (priorActive.length > 0 ? priorActive : allTools.map((tool) => tool.name)).filter((name) => !COLLECTOR_CONSTRUCTION_TOOLS.includes(name));
|
|
24872
|
+
const nextActive = [.../* @__PURE__ */ new Set([...hostSurface, ...COLLECTOR_REQUIRED_TOOLS])];
|
|
24873
|
+
roleHost.setActiveTools(nextActive);
|
|
27486
24874
|
const active = new Set(roleHost.getActiveTools());
|
|
27487
24875
|
for (const required of COLLECTOR_REQUIRED_TOOLS) {
|
|
27488
24876
|
if (!active.has(required)) {
|
|
27489
24877
|
throw new Error(`Collector failed to activate required tool ${required}`);
|
|
27490
24878
|
}
|
|
27491
24879
|
}
|
|
27492
|
-
for (const name of
|
|
27493
|
-
if (
|
|
27494
|
-
throw new Error(`Collector
|
|
24880
|
+
for (const name of COLLECTOR_CONSTRUCTION_TOOLS) {
|
|
24881
|
+
if (active.has(name)) {
|
|
24882
|
+
throw new Error(`Collector must not activate construction tool ${name}`);
|
|
27495
24883
|
}
|
|
27496
24884
|
}
|
|
27497
24885
|
if (!collectorToolCallRegistered) {
|
|
@@ -27499,20 +24887,10 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27499
24887
|
roleHost.on("tool_call", (toolEvent) => {
|
|
27500
24888
|
const liveRole = roleHost.getFlag(ROLE_FLAG.name);
|
|
27501
24889
|
if (activeCollector === void 0 || selectedRole === void 0 || selectedRole !== liveRole) return;
|
|
27502
|
-
if (!COLLECTOR_REQUIRED_TOOLS.includes(toolEvent.toolName)) {
|
|
27503
|
-
return {
|
|
27504
|
-
block: true,
|
|
27505
|
-
reason: `\u901A\u8FDB\u53F8\u7981\u7528\u5DE5\u5177 ${toolEvent.toolName}`
|
|
27506
|
-
};
|
|
27507
|
-
}
|
|
27508
24890
|
return collectorBusiness.onToolCall(activeCollector, toolEvent);
|
|
27509
24891
|
});
|
|
27510
24892
|
}
|
|
27511
|
-
|
|
27512
|
-
if (activation.ledger.activationRecorded) {
|
|
27513
|
-
collectorFirstDispatchDone = true;
|
|
27514
|
-
}
|
|
27515
|
-
activeCollector = activation;
|
|
24893
|
+
activeCollector = await collectorBusiness.activate(context);
|
|
27516
24894
|
}
|
|
27517
24895
|
};
|
|
27518
24896
|
const clock = dependencies.activationClock ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
@@ -27562,7 +24940,6 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27562
24940
|
roleReferenceMaterials = "";
|
|
27563
24941
|
activeReviewerParent = void 0;
|
|
27564
24942
|
activeCollector = void 0;
|
|
27565
|
-
collectorFirstDispatchDone = false;
|
|
27566
24943
|
receiptDelivery = createReceiptDeliveryPolicy();
|
|
27567
24944
|
noReceiptRecorded = false;
|
|
27568
24945
|
pendingNavigatorPresentation = void 0;
|
|
@@ -27745,7 +25122,7 @@ async function prepareRoleEnvelope(options) {
|
|
|
27745
25122
|
const hostAbort = new AbortController();
|
|
27746
25123
|
const runId = request.runDirectory.split("/").filter(Boolean).at(-1) ?? randomUUID9();
|
|
27747
25124
|
await mkdir5(request.runDirectory, { recursive: true });
|
|
27748
|
-
let sessionFile = options.sessionFile ??
|
|
25125
|
+
let sessionFile = options.sessionFile ?? join45(request.runDirectory, "session", "session.jsonl");
|
|
27749
25126
|
await mkdir5(dirname25(sessionFile), { recursive: true });
|
|
27750
25127
|
if (request.continuation.kind !== "resume") {
|
|
27751
25128
|
try {
|
|
@@ -28262,15 +25639,13 @@ async function prepareRoleEnvelope(options) {
|
|
|
28262
25639
|
}
|
|
28263
25640
|
|
|
28264
25641
|
// src/role-runtime-dependencies.ts
|
|
28265
|
-
|
|
25642
|
+
import { readFile as readFile24 } from "node:fs/promises";
|
|
28266
25643
|
init_doctor_evidence();
|
|
28267
|
-
import { readFile as readFile25 } from "node:fs/promises";
|
|
28268
|
-
import { join as join47 } from "node:path";
|
|
28269
25644
|
|
|
28270
25645
|
// src/navigator-work-context.ts
|
|
28271
25646
|
init_doctor_evidence();
|
|
28272
25647
|
init_host_contracts();
|
|
28273
|
-
import { readFile as
|
|
25648
|
+
import { readFile as readFile23 } from "node:fs/promises";
|
|
28274
25649
|
import { resolve as resolve20 } from "node:path";
|
|
28275
25650
|
init_notary_source_run();
|
|
28276
25651
|
init_packaged_role_registry();
|
|
@@ -28284,7 +25659,7 @@ function navigatorInputReference(getFlag, role) {
|
|
|
28284
25659
|
async function loadNavigatorWorkContext(options) {
|
|
28285
25660
|
const reference = navigatorInputReference(options.getFlag, options.role);
|
|
28286
25661
|
const subjectMode = packagedNavigatorSubject(options.role);
|
|
28287
|
-
const input = reference === void 0 || subjectMode === "case" || subjectMode === "source-run" ? void 0 : await
|
|
25662
|
+
const input = reference === void 0 || subjectMode === "case" || subjectMode === "source-run" ? void 0 : await readFile23(reference, "utf8");
|
|
28288
25663
|
const subjectRoot = subjectPath(reference ?? options.context.sessionManager.getSessionDir(), options.context.cwd);
|
|
28289
25664
|
let subjectKey = reference === void 0 ? subjectRoot : navigatorSubjectKeyForInput(subjectRoot, reference, options.context.cwd);
|
|
28290
25665
|
let subject = input ?? `work subject: ${subjectKey}`;
|
|
@@ -28341,7 +25716,7 @@ async function loadNavigatorWorkContext(options) {
|
|
|
28341
25716
|
let authorityMaterial;
|
|
28342
25717
|
for (const path of authorityFiles) {
|
|
28343
25718
|
try {
|
|
28344
|
-
const content = await
|
|
25719
|
+
const content = await readFile23(path, "utf8");
|
|
28345
25720
|
if (content.trim() !== "") {
|
|
28346
25721
|
authorityMaterial = content;
|
|
28347
25722
|
break;
|
|
@@ -28378,19 +25753,16 @@ function loadRegisteredRoleSoul(role) {
|
|
|
28378
25753
|
return usesSubjectSoul(role) ? loadAuditorSoulFromSubjectInput() : loadMainRoleSessionMaterials(role);
|
|
28379
25754
|
}
|
|
28380
25755
|
function createRoleRuntimeDependencies(packageRoot) {
|
|
28381
|
-
const collectorHandbookSeedPath = join47(packageRoot, "resources/collector-bot-handbook.md");
|
|
28382
25756
|
const navigatorSessionFactory = createNativeNavigatorSessionFactory();
|
|
28383
25757
|
return {
|
|
28384
25758
|
packageRoot,
|
|
28385
25759
|
loadRoleReferenceMaterials: loadPackagedRoleReferenceMaterials,
|
|
28386
25760
|
loadRoleSoul: loadRegisteredRoleSoul,
|
|
28387
|
-
loadFixPacket: (path) =>
|
|
28388
|
-
loadCoderTask: (path) =>
|
|
28389
|
-
loadCollectorHandbookSeed: () => readFile25(collectorHandbookSeedPath, "utf8"),
|
|
28390
|
-
createCollectorTransport: () => createGhCollectorGitHubTransport(),
|
|
25761
|
+
loadFixPacket: (path) => readFile24(path, "utf8"),
|
|
25762
|
+
loadCoderTask: (path) => readFile24(path, "utf8"),
|
|
28391
25763
|
loadDoctorCase,
|
|
28392
25764
|
loadNotarySourceRun: loadNotarySourceRunLocator,
|
|
28393
|
-
loadMergerInput: async (path) => JSON.parse(await
|
|
25765
|
+
loadMergerInput: async (path) => JSON.parse(await readFile24(path, "utf8")),
|
|
28394
25766
|
loadNavigatorWorkContext: (options) => loadNavigatorWorkContext({
|
|
28395
25767
|
context: options.context,
|
|
28396
25768
|
role: options.role,
|
|
@@ -28415,9 +25787,9 @@ function createRoleRuntimeDependencies(packageRoot) {
|
|
|
28415
25787
|
init_session_identity();
|
|
28416
25788
|
|
|
28417
25789
|
// src/acp-host/description.ts
|
|
28418
|
-
import { join as
|
|
25790
|
+
import { join as join46 } from "node:path";
|
|
28419
25791
|
function resolveAcpBinary(description, operatorHome) {
|
|
28420
|
-
return
|
|
25792
|
+
return join46(operatorHome, ...description.binaryFromHome);
|
|
28421
25793
|
}
|
|
28422
25794
|
function acpStdioArgs(description, model, seat) {
|
|
28423
25795
|
const { prefix, suffix, modelFlag, thinkingFlag } = description.argv;
|
|
@@ -28436,8 +25808,8 @@ function acpModelId(modelPassing, model) {
|
|
|
28436
25808
|
}
|
|
28437
25809
|
|
|
28438
25810
|
// src/acp-host/role-turn-host.ts
|
|
28439
|
-
import { join as
|
|
28440
|
-
import { spawn as
|
|
25811
|
+
import { join as join47 } from "node:path";
|
|
25812
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
28441
25813
|
import { createInterface } from "node:readline";
|
|
28442
25814
|
|
|
28443
25815
|
// src/external-host-turn-loop.ts
|
|
@@ -28620,7 +25992,7 @@ function acpError(code, message, cause) {
|
|
|
28620
25992
|
return Object.assign(new Error(message, cause === void 0 ? void 0 : { cause }), { code });
|
|
28621
25993
|
}
|
|
28622
25994
|
function connectAcpStdio(options) {
|
|
28623
|
-
const child =
|
|
25995
|
+
const child = spawn3(options.binary, [...options.args], { cwd: options.cwd, env: options.env, stdio: ["pipe", "pipe", "pipe"] });
|
|
28624
25996
|
const pending = /* @__PURE__ */ new Map();
|
|
28625
25997
|
const notificationHandlers = [];
|
|
28626
25998
|
if (options.onNotification !== void 0) notificationHandlers.push(options.onNotification);
|
|
@@ -28883,7 +26255,7 @@ function createAcpRoleTurnHost(config) {
|
|
|
28883
26255
|
host: config.hostName,
|
|
28884
26256
|
sessionId,
|
|
28885
26257
|
cwd: request.cwd,
|
|
28886
|
-
sessionDirectory:
|
|
26258
|
+
sessionDirectory: join47(request.runDirectory, "session"),
|
|
28887
26259
|
sessionParent,
|
|
28888
26260
|
continuation: request.continuation,
|
|
28889
26261
|
...request.model !== void 0 ? { model: request.model } : {},
|
|
@@ -28903,12 +26275,12 @@ function createAcpRoleTurnHost(config) {
|
|
|
28903
26275
|
// src/acp-host/seat-profile-soul.ts
|
|
28904
26276
|
import { constants as constants3 } from "node:fs";
|
|
28905
26277
|
import { access as access3, copyFile, lstat as lstat8, mkdir as mkdir6, readlink, symlink as symlink2, unlink as unlink6 } from "node:fs/promises";
|
|
28906
|
-
import { dirname as dirname26, join as
|
|
26278
|
+
import { dirname as dirname26, join as join48, relative as relative3, resolve as resolve21 } from "node:path";
|
|
28907
26279
|
function seatProfileName(spec, role) {
|
|
28908
26280
|
return `${spec.namePrefix}${role}`;
|
|
28909
26281
|
}
|
|
28910
26282
|
function packageRoleSoulPath(packageRoot, role) {
|
|
28911
|
-
return
|
|
26283
|
+
return join48(packageRoot, "souls", `${role}.md`);
|
|
28912
26284
|
}
|
|
28913
26285
|
async function pathExists2(path) {
|
|
28914
26286
|
try {
|
|
@@ -28925,16 +26297,16 @@ async function ensureSeatProfileSoul(options) {
|
|
|
28925
26297
|
if (!await pathExists2(soulTarget)) {
|
|
28926
26298
|
throw new Error(`packaged role soul missing: ${soulTarget}`);
|
|
28927
26299
|
}
|
|
28928
|
-
const profilesRoot =
|
|
28929
|
-
const profileDir =
|
|
26300
|
+
const profilesRoot = join48(operatorHome, ...spec.profilesRootFromHome);
|
|
26301
|
+
const profileDir = join48(profilesRoot, profileName);
|
|
28930
26302
|
const hostRoot = dirname26(profilesRoot);
|
|
28931
|
-
const soulPath =
|
|
26303
|
+
const soulPath = join48(profileDir, spec.soulFileName);
|
|
28932
26304
|
if (!await pathExists2(profileDir)) {
|
|
28933
26305
|
await mkdir6(profileDir, { recursive: true });
|
|
28934
26306
|
for (const name of ["auth.json", ".env", "config.yaml"]) {
|
|
28935
|
-
const source =
|
|
26307
|
+
const source = join48(hostRoot, name);
|
|
28936
26308
|
if (!await pathExists2(source)) continue;
|
|
28937
|
-
await copyFile(source,
|
|
26309
|
+
await copyFile(source, join48(profileDir, name));
|
|
28938
26310
|
}
|
|
28939
26311
|
} else {
|
|
28940
26312
|
await mkdir6(profileDir, { recursive: true });
|