@akagilnc/pi-workflow-roles 0.1.5241 → 0.1.5252
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 +482 -3141
- package/dist/collector-config.js +0 -1
- package/dist/headless-host/production-host.js +590 -3249
- package/dist/migrate-book-topology.js +40 -107
- package/dist/navigator-invocation-identity.js +0 -57
- 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 +256 -749
- package/dist/public-cli/option-definitions.js +4 -19
- package/dist/public-cli/settlement.js +12 -138
- 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/navigator-invocation-identity.ts +4 -121
- 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 +11 -177
- package/src/role-runtime-dependencies.ts +0 -4
- package/src/role-runtime.ts +39 -103
- 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,7 +2754,7 @@ 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");
|
|
4715
2758
|
} catch (error) {
|
|
4716
2759
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
4717
2760
|
return void 0;
|
|
@@ -4739,6 +2782,84 @@ var init_typed_provider_http = __esm({
|
|
|
4739
2782
|
}
|
|
4740
2783
|
});
|
|
4741
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);
|
|
2831
|
+
} catch (error) {
|
|
2832
|
+
fail3(`Collector request manifest is unreadable at ${path}`, error);
|
|
2833
|
+
}
|
|
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);
|
|
2839
|
+
}
|
|
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 });
|
|
2850
|
+
}
|
|
2851
|
+
const canonicalJson2 = canonicalManifest(requests);
|
|
2852
|
+
return { requests, canonicalJson: canonicalJson2, digest: createHash("sha256").update(canonicalJson2).digest("hex"), sourcePath: path };
|
|
2853
|
+
}
|
|
2854
|
+
var COLLECTOR_OWNER_PATTERN, COLLECTOR_REPO_PATTERN;
|
|
2855
|
+
var init_collector_config = __esm({
|
|
2856
|
+
"src/collector-config.ts"() {
|
|
2857
|
+
"use strict";
|
|
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])?$/;
|
|
2860
|
+
}
|
|
2861
|
+
});
|
|
2862
|
+
|
|
4742
2863
|
// src/auditor-dossier-tool.ts
|
|
4743
2864
|
var auditor_dossier_tool_exports = {};
|
|
4744
2865
|
__export(auditor_dossier_tool_exports, {
|
|
@@ -4753,40 +2874,126 @@ function auditorRunDirectory(context) {
|
|
|
4753
2874
|
if (sessionFile === void 0) return void 0;
|
|
4754
2875
|
return resolve3(dirname5(dirname5(sessionFile)));
|
|
4755
2876
|
}
|
|
4756
|
-
function createAuditorDossierTool(runDirectory) {
|
|
4757
|
-
return {
|
|
4758
|
-
name: AUDITOR_DOSSIER_TOOL_NAME,
|
|
4759
|
-
description: "\u5B9A\u4F4D\u672C\u5BA1\u8BA1\u5E2D\u7ED1\u5B9A\u7684 run \u5377\u5B97\u53CA\u5176\u8BC1\u636E\u5165\u53E3\u3002",
|
|
4760
|
-
// #836 r16 class 3: execute() ignores `_params` entirely — a closed root
|
|
4761
|
-
// only rejects the role for saying more.
|
|
4762
|
-
parameters: Type10.Object({}, { additionalProperties: true }),
|
|
4763
|
-
async execute(_id, _params) {
|
|
4764
|
-
if (runDirectory === void 0) {
|
|
4765
|
-
return {
|
|
4766
|
-
content: [{ type: "text", text: "\u672C\u5BA1\u8BA1\u5E2D\u65E0\u7ED1\u5B9A run \u5377\u5B97\u8BB0\u5F55\u3002" }],
|
|
4767
|
-
details: void 0
|
|
4768
|
-
};
|
|
4769
|
-
}
|
|
4770
|
-
const details = {
|
|
4771
|
-
runDirectory,
|
|
4772
|
-
admittedRequest: join8(runDirectory, "admitted-request.json"),
|
|
4773
|
-
parentSessionCandidate: join8(runDirectory, "session", "session.jsonl"),
|
|
4774
|
-
attachments: join8(runDirectory, "attachments"),
|
|
4775
|
-
artifacts: roleRunArtifactsDirectory(runDirectory)
|
|
4776
|
-
};
|
|
4777
|
-
return {
|
|
4778
|
-
content: [{ type: "text", text: JSON.stringify(details) }],
|
|
4779
|
-
details
|
|
4780
|
-
};
|
|
4781
|
-
}
|
|
4782
|
-
};
|
|
2877
|
+
function createAuditorDossierTool(runDirectory) {
|
|
2878
|
+
return {
|
|
2879
|
+
name: AUDITOR_DOSSIER_TOOL_NAME,
|
|
2880
|
+
description: "\u5B9A\u4F4D\u672C\u5BA1\u8BA1\u5E2D\u7ED1\u5B9A\u7684 run \u5377\u5B97\u53CA\u5176\u8BC1\u636E\u5165\u53E3\u3002",
|
|
2881
|
+
// #836 r16 class 3: execute() ignores `_params` entirely — a closed root
|
|
2882
|
+
// only rejects the role for saying more.
|
|
2883
|
+
parameters: Type10.Object({}, { additionalProperties: true }),
|
|
2884
|
+
async execute(_id, _params) {
|
|
2885
|
+
if (runDirectory === void 0) {
|
|
2886
|
+
return {
|
|
2887
|
+
content: [{ type: "text", text: "\u672C\u5BA1\u8BA1\u5E2D\u65E0\u7ED1\u5B9A run \u5377\u5B97\u8BB0\u5F55\u3002" }],
|
|
2888
|
+
details: void 0
|
|
2889
|
+
};
|
|
2890
|
+
}
|
|
2891
|
+
const details = {
|
|
2892
|
+
runDirectory,
|
|
2893
|
+
admittedRequest: join8(runDirectory, "admitted-request.json"),
|
|
2894
|
+
parentSessionCandidate: join8(runDirectory, "session", "session.jsonl"),
|
|
2895
|
+
attachments: join8(runDirectory, "attachments"),
|
|
2896
|
+
artifacts: roleRunArtifactsDirectory(runDirectory)
|
|
2897
|
+
};
|
|
2898
|
+
return {
|
|
2899
|
+
content: [{ type: "text", text: JSON.stringify(details) }],
|
|
2900
|
+
details
|
|
2901
|
+
};
|
|
2902
|
+
}
|
|
2903
|
+
};
|
|
2904
|
+
}
|
|
2905
|
+
var AUDITOR_DOSSIER_TOOL_NAME;
|
|
2906
|
+
var init_auditor_dossier_tool = __esm({
|
|
2907
|
+
"src/auditor-dossier-tool.ts"() {
|
|
2908
|
+
"use strict";
|
|
2909
|
+
init_role_run_placement();
|
|
2910
|
+
AUDITOR_DOSSIER_TOOL_NAME = "ak_get_run_dossier";
|
|
2911
|
+
}
|
|
2912
|
+
});
|
|
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)}`;
|
|
4783
2950
|
}
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
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"() {
|
|
4787
2959
|
"use strict";
|
|
4788
|
-
|
|
4789
|
-
|
|
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
|
+
};
|
|
4790
2997
|
}
|
|
4791
2998
|
});
|
|
4792
2999
|
|
|
@@ -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) {
|
|
@@ -12690,22 +10755,6 @@ function toolResultText(message) {
|
|
|
12690
10755
|
return "";
|
|
12691
10756
|
}).join("").trim();
|
|
12692
10757
|
}
|
|
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;
|
|
12708
|
-
}
|
|
12709
10758
|
function boundErroredToolCandidate(entries, resultIndex, message, toolName) {
|
|
12710
10759
|
if (message.toolName !== toolName || message.isError !== true) return void 0;
|
|
12711
10760
|
const bound = boundRoleToolCallForResult(entries, resultIndex, message, toolName);
|
|
@@ -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;
|
|
@@ -12860,11 +10894,6 @@ async function appendRunAttemptHistory(source, outcome) {
|
|
|
12860
10894
|
} catch {
|
|
12861
10895
|
}
|
|
12862
10896
|
}
|
|
12863
|
-
function navigatorAttendanceCorrelatedWithBoundMarker(details, attendanceIndex, terminalIndex, marker) {
|
|
12864
|
-
if (attendanceIndex <= terminalIndex) return false;
|
|
12865
|
-
if (details.invocationId !== marker.invocationId) return false;
|
|
12866
|
-
return true;
|
|
12867
|
-
}
|
|
12868
10897
|
function parseNavigatorAttendanceDetails(details) {
|
|
12869
10898
|
const disposition = details.disposition;
|
|
12870
10899
|
const advisoryDiagnostic = typeof details.routePlaybookReadFailure === "string" ? { advisoryDiagnostic: details.routePlaybookReadFailure } : {};
|
|
@@ -12873,7 +10902,7 @@ function parseNavigatorAttendanceDetails(details) {
|
|
|
12873
10902
|
if (typeof details.prose === "string" && details.prose.trim() !== "") {
|
|
12874
10903
|
prose = details.prose;
|
|
12875
10904
|
} else {
|
|
12876
|
-
const next =
|
|
10905
|
+
const next = isRecord10(details.next) && typeof details.next.role === "string" ? details.next.role : void 0;
|
|
12877
10906
|
const reason = typeof details.reason === "string" && details.reason.trim() !== "" ? details.reason : void 0;
|
|
12878
10907
|
const command = typeof details.command === "string" && details.command.trim() !== "" ? details.command : void 0;
|
|
12879
10908
|
if (reason !== void 0 && next !== void 0) {
|
|
@@ -12982,7 +11011,7 @@ function detourGateContext(admitted, scope) {
|
|
|
12982
11011
|
}
|
|
12983
11012
|
async function withOptionalGateProjection(base, sessionDirectory, gateContext = {}) {
|
|
12984
11013
|
const secondaryEvidence = base.roleOutcome.kind === "failure" ? base.roleOutcome.decisiveFacts.secondaryEvidence : void 0;
|
|
12985
|
-
const skipGate =
|
|
11014
|
+
const skipGate = isRecord10(secondaryEvidence) && secondaryEvidence.kind === "role_infrastructure_failure" && packagedSkipsGateOnInfrastructureStage(secondaryEvidence.stage);
|
|
12986
11015
|
let next = base;
|
|
12987
11016
|
if (!skipGate) {
|
|
12988
11017
|
const gate = await extractGateFactFromSessionDirectory(sessionDirectory, gateContext);
|
|
@@ -12995,7 +11024,7 @@ function routePlaybookFailureMessage(entries) {
|
|
|
12995
11024
|
const entry = entries[i];
|
|
12996
11025
|
if (entry?.type !== "custom" || entry.customType !== NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY) continue;
|
|
12997
11026
|
const data = entry.data;
|
|
12998
|
-
if (!
|
|
11027
|
+
if (!isRecord10(data) || typeof data.message !== "string" || data.message.trim() === "") return void 0;
|
|
12999
11028
|
return data.message;
|
|
13000
11029
|
}
|
|
13001
11030
|
return void 0;
|
|
@@ -13010,59 +11039,17 @@ function extractNavigatorAttendanceFact(entries) {
|
|
|
13010
11039
|
const terminal = findLatestDurablePackagedRoleTerminal(entries);
|
|
13011
11040
|
if (terminal === void 0) {
|
|
13012
11041
|
return {
|
|
13013
|
-
disposition: "unavailable",
|
|
13014
|
-
source: "unknown",
|
|
13015
|
-
reason: "Navigator attendance has no durable packaged role terminal"
|
|
13016
|
-
};
|
|
13017
|
-
}
|
|
13018
|
-
let
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
|
|
13024
|
-
}
|
|
13025
|
-
}
|
|
13026
|
-
if (markerIndex < 0) {
|
|
13027
|
-
return {
|
|
13028
|
-
disposition: "unavailable",
|
|
13029
|
-
source: "unknown",
|
|
13030
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
13031
|
-
};
|
|
13032
|
-
}
|
|
13033
|
-
const marker = parseInvocationMarkerIdentity(entries[markerIndex]?.data);
|
|
13034
|
-
if (marker === void 0) {
|
|
13035
|
-
return {
|
|
13036
|
-
disposition: "unavailable",
|
|
13037
|
-
source: "unknown",
|
|
13038
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
13039
|
-
};
|
|
13040
|
-
}
|
|
13041
|
-
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
13042
|
-
const entry = entries[i];
|
|
13043
|
-
if (entry?.type === "custom_message" && entry.customType === "ak-navigator-attendance") {
|
|
13044
|
-
const details = entry.message?.details ?? entry.details;
|
|
13045
|
-
if (!isRecord11(details)) {
|
|
13046
|
-
return {
|
|
13047
|
-
disposition: "unavailable",
|
|
13048
|
-
source: "unknown",
|
|
13049
|
-
reason: "Navigator attendance is unparseable"
|
|
13050
|
-
};
|
|
13051
|
-
}
|
|
13052
|
-
if (!navigatorAttendanceCorrelatedWithBoundMarker(
|
|
13053
|
-
details,
|
|
13054
|
-
i,
|
|
13055
|
-
terminal.index,
|
|
13056
|
-
marker
|
|
13057
|
-
)) {
|
|
13058
|
-
return {
|
|
13059
|
-
disposition: "unavailable",
|
|
13060
|
-
source: "unknown",
|
|
13061
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
13062
|
-
};
|
|
13063
|
-
}
|
|
13064
|
-
return parseNavigatorAttendanceDetails(details);
|
|
13065
|
-
}
|
|
11042
|
+
disposition: "unavailable",
|
|
11043
|
+
source: "unknown",
|
|
11044
|
+
reason: "Navigator attendance has no durable packaged role terminal"
|
|
11045
|
+
};
|
|
11046
|
+
}
|
|
11047
|
+
for (let i = terminal.index; i < entries.length; i += 1) {
|
|
11048
|
+
const entry = entries[i];
|
|
11049
|
+
if (entry?.type !== "custom" || entry.customType !== "ak-role-submission-closure") continue;
|
|
11050
|
+
const details = isRecord10(entry.data) ? entry.data.navigator : void 0;
|
|
11051
|
+
if (!isRecord10(details)) break;
|
|
11052
|
+
return parseNavigatorAttendanceDetails(details);
|
|
13066
11053
|
}
|
|
13067
11054
|
return {
|
|
13068
11055
|
disposition: "unavailable",
|
|
@@ -13193,7 +11180,7 @@ async function settleSealedAcceptedOrToolResidual(admitted, authority, scope, ro
|
|
|
13193
11180
|
const residual = boundErroredToolCandidate(entries, index, message, residualToolName);
|
|
13194
11181
|
if (residual === void 0) continue;
|
|
13195
11182
|
const candidate = residual.candidate;
|
|
13196
|
-
const details =
|
|
11183
|
+
const details = isRecord10(candidate) ? candidate : { candidate };
|
|
13197
11184
|
const failed = await settleFailureTerminalResult(
|
|
13198
11185
|
admitted,
|
|
13199
11186
|
{
|
|
@@ -13268,7 +11255,7 @@ function extractDoctorCandidateFacts(entries) {
|
|
|
13268
11255
|
continue;
|
|
13269
11256
|
}
|
|
13270
11257
|
const data = entry.data;
|
|
13271
|
-
if (!
|
|
11258
|
+
if (!isRecord10(data)) return {};
|
|
13272
11259
|
return {
|
|
13273
11260
|
...data.cost === void 0 ? {} : { cost: data.cost },
|
|
13274
11261
|
...data.auditNoReceipt === void 0 ? {} : { auditNoReceipt: data.auditNoReceipt }
|
|
@@ -13353,7 +11340,7 @@ async function settleLawfulSeatAcceptedTerminalResult(admitted, authority, spec,
|
|
|
13353
11340
|
let residual;
|
|
13354
11341
|
for (let index = entries.length - 1; index >= scanStart; index -= 1) {
|
|
13355
11342
|
const entry = entries[index];
|
|
13356
|
-
if (entry?.type === "custom" && entry.customType === "ak-role-submission-closure" &&
|
|
11343
|
+
if (entry?.type === "custom" && entry.customType === "ak-role-submission-closure" && isRecord10(entry.data) && entry.data.toolName === spec.toolName && classifyPackagedRoleTerminalResult(entry.data).kind === "accepted") {
|
|
13357
11344
|
thisAttemptHasSeatSuccess = true;
|
|
13358
11345
|
}
|
|
13359
11346
|
const message = entries[index]?.message;
|
|
@@ -13393,7 +11380,7 @@ async function settleLawfulSeatAcceptedTerminalResult(admitted, authority, spec,
|
|
|
13393
11380
|
);
|
|
13394
11381
|
}
|
|
13395
11382
|
if (residual !== void 0) {
|
|
13396
|
-
const details =
|
|
11383
|
+
const details = isRecord10(residual.candidate) ? residual.candidate : { candidate: residual.candidate };
|
|
13397
11384
|
const failed = await settleFailureTerminalResult(
|
|
13398
11385
|
admitted,
|
|
13399
11386
|
{
|
|
@@ -13443,7 +11430,7 @@ function countersignTerminalFromEntries(entries) {
|
|
|
13443
11430
|
return void 0;
|
|
13444
11431
|
}
|
|
13445
11432
|
function withCountersignTerminalFact(roleOutcome, officer) {
|
|
13446
|
-
const prior = roleOutcome.decisiveFacts !== void 0 &&
|
|
11433
|
+
const prior = roleOutcome.decisiveFacts !== void 0 && isRecord10(roleOutcome.decisiveFacts) ? roleOutcome.decisiveFacts : {};
|
|
13447
11434
|
return {
|
|
13448
11435
|
...roleOutcome,
|
|
13449
11436
|
decisiveFacts: {
|
|
@@ -13456,7 +11443,7 @@ function acceptedSecretariatDefinesOfficerProjection(roleOutcome) {
|
|
|
13456
11443
|
const payloads = roleOutcome.payloads ?? [];
|
|
13457
11444
|
for (let index = payloads.length - 1; index >= 0; index -= 1) {
|
|
13458
11445
|
const payload = payloads[index];
|
|
13459
|
-
if (!
|
|
11446
|
+
if (!isRecord10(payload)) continue;
|
|
13460
11447
|
const status = payload.secretariatStatus;
|
|
13461
11448
|
if (typeof status !== "string") continue;
|
|
13462
11449
|
return status === "converged";
|
|
@@ -13684,17 +11671,6 @@ async function settleFailureTerminalResult(admitted, failure2, authority, option
|
|
|
13684
11671
|
}
|
|
13685
11672
|
if (facts !== void 0 && facts.runPointer === admitted.runDirectory && facts.attemptPointer === `current:${admitted.runDirectory}`) {
|
|
13686
11673
|
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
11674
|
await clearOppositeTerminalArtifactFace(admitted.runDirectory);
|
|
13699
11675
|
return withOptionalGateProjection(
|
|
13700
11676
|
{
|
|
@@ -13829,7 +11805,7 @@ function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep2
|
|
|
13829
11805
|
});
|
|
13830
11806
|
});
|
|
13831
11807
|
}
|
|
13832
|
-
var privateFailureErrorPaths, NAVIGATOR_POST_ROLE_GRACE_MS,
|
|
11808
|
+
var privateFailureErrorPaths, NAVIGATOR_POST_ROLE_GRACE_MS, ENGINE_DETOUR_INFRASTRUCTURE_FAILURE_SPEC, RUNNER_FAILURE_POLICY, ATTEMPT_HISTORY_ENTRY_TYPE, EMPTY_ARTIFACT_FACE;
|
|
13833
11809
|
var init_settlement = __esm({
|
|
13834
11810
|
"src/public-cli/settlement.ts"() {
|
|
13835
11811
|
"use strict";
|
|
@@ -13842,11 +11818,9 @@ var init_settlement = __esm({
|
|
|
13842
11818
|
init_serialize_thrown_value();
|
|
13843
11819
|
init_run_lifecycle();
|
|
13844
11820
|
init_compliance_transport();
|
|
13845
|
-
init_collector_ledger();
|
|
13846
11821
|
init_engine_detour();
|
|
13847
11822
|
init_engine_detour_usage();
|
|
13848
11823
|
init_judge_output();
|
|
13849
|
-
init_collector_output();
|
|
13850
11824
|
init_worker_output();
|
|
13851
11825
|
init_doctor_contracts();
|
|
13852
11826
|
init_dossier_resolution();
|
|
@@ -13862,20 +11836,6 @@ var init_settlement = __esm({
|
|
|
13862
11836
|
init_terminal();
|
|
13863
11837
|
privateFailureErrorPaths = /* @__PURE__ */ new WeakMap();
|
|
13864
11838
|
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
11839
|
ENGINE_DETOUR_INFRASTRUCTURE_FAILURE_SPEC = {
|
|
13880
11840
|
matchTool: (toolName) => toolName === ENGINE_DETOUR_TOOL_NAME,
|
|
13881
11841
|
cause: "output",
|
|
@@ -13889,10 +11849,6 @@ var init_settlement = __esm({
|
|
|
13889
11849
|
"engine-detour-record-first": {
|
|
13890
11850
|
read: readEngineDetourInfrastructureFailure,
|
|
13891
11851
|
rank: "record-first"
|
|
13892
|
-
},
|
|
13893
|
-
"collector-known-first": {
|
|
13894
|
-
read: readCollectorInfrastructureFailure,
|
|
13895
|
-
rank: "known-first"
|
|
13896
11852
|
}
|
|
13897
11853
|
};
|
|
13898
11854
|
ATTEMPT_HISTORY_ENTRY_TYPE = "ak_run_attempt_history";
|
|
@@ -16190,11 +14146,11 @@ var init_turn_request = __esm({
|
|
|
16190
14146
|
});
|
|
16191
14147
|
|
|
16192
14148
|
// src/public-cli/countersign-run.ts
|
|
16193
|
-
function
|
|
14149
|
+
function isRecord11(value) {
|
|
16194
14150
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16195
14151
|
}
|
|
16196
14152
|
function isEscalatePayload(payload) {
|
|
16197
|
-
if (!
|
|
14153
|
+
if (!isRecord11(payload)) return false;
|
|
16198
14154
|
return payload.status === "escalate";
|
|
16199
14155
|
}
|
|
16200
14156
|
function courtDiaristPayloadRows(roleOutcome, submissions) {
|
|
@@ -17804,7 +15760,7 @@ function isMissingPathError6(error) {
|
|
|
17804
15760
|
function errorText3(error) {
|
|
17805
15761
|
return error instanceof Error ? error.message : String(error);
|
|
17806
15762
|
}
|
|
17807
|
-
function
|
|
15763
|
+
function isRecord12(value) {
|
|
17808
15764
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17809
15765
|
}
|
|
17810
15766
|
async function readExistingRunLifecycleState(runDirectory) {
|
|
@@ -17861,7 +15817,7 @@ async function readInvocationScopeFields(runDirectory) {
|
|
|
17861
15817
|
throw error;
|
|
17862
15818
|
}
|
|
17863
15819
|
const parsed = JSON.parse(raw);
|
|
17864
|
-
if (!
|
|
15820
|
+
if (!isRecord12(parsed)) return void 0;
|
|
17865
15821
|
if (typeof parsed.projectRoot !== "string" || parsed.projectRoot.trim() === "") {
|
|
17866
15822
|
return void 0;
|
|
17867
15823
|
}
|
|
@@ -17890,7 +15846,7 @@ async function resolveSessionFile(runDirectory) {
|
|
|
17890
15846
|
try {
|
|
17891
15847
|
const raw = await readFile18(join33(runDirectory, "invocation.json"), "utf8");
|
|
17892
15848
|
const parsed = JSON.parse(raw);
|
|
17893
|
-
if (
|
|
15849
|
+
if (isRecord12(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.trim() !== "") {
|
|
17894
15850
|
return parsed.sessionFile;
|
|
17895
15851
|
}
|
|
17896
15852
|
} catch (error) {
|
|
@@ -18228,7 +16184,7 @@ var init_analyst_ledger = __esm({
|
|
|
18228
16184
|
});
|
|
18229
16185
|
|
|
18230
16186
|
// src/analyst-metric-families/acceptance-success-rework.ts
|
|
18231
|
-
function
|
|
16187
|
+
function isRecord13(value) {
|
|
18232
16188
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18233
16189
|
}
|
|
18234
16190
|
function wallMsFromSpan(span) {
|
|
@@ -18237,21 +16193,21 @@ function wallMsFromSpan(span) {
|
|
|
18237
16193
|
function findCollectorGroups(body) {
|
|
18238
16194
|
if (Array.isArray(body.groups)) return body.groups;
|
|
18239
16195
|
const receipt = body.receipt;
|
|
18240
|
-
if (
|
|
16196
|
+
if (isRecord13(receipt) && Array.isArray(receipt.groups)) return receipt.groups;
|
|
18241
16197
|
const outcome = body.outcome;
|
|
18242
|
-
if (
|
|
16198
|
+
if (isRecord13(outcome)) {
|
|
18243
16199
|
const facts = outcome.decisiveFacts;
|
|
18244
|
-
if (
|
|
16200
|
+
if (isRecord13(facts) && Array.isArray(facts.groups)) return facts.groups;
|
|
18245
16201
|
}
|
|
18246
16202
|
return void 0;
|
|
18247
16203
|
}
|
|
18248
16204
|
function extractStatus(body) {
|
|
18249
16205
|
const outcome = body.outcome;
|
|
18250
|
-
if (
|
|
16206
|
+
if (isRecord13(outcome) && typeof outcome.status === "string" && outcome.status.trim() !== "") {
|
|
18251
16207
|
return outcome.status;
|
|
18252
16208
|
}
|
|
18253
16209
|
const receipt = body.receipt;
|
|
18254
|
-
if (
|
|
16210
|
+
if (isRecord13(receipt) && typeof receipt.status === "string" && receipt.status.trim() !== "") {
|
|
18255
16211
|
return receipt.status;
|
|
18256
16212
|
}
|
|
18257
16213
|
if (typeof body.status === "string" && body.status.trim() !== "") {
|
|
@@ -18877,15 +16833,15 @@ var init_leg_wall_clock = __esm({
|
|
|
18877
16833
|
});
|
|
18878
16834
|
|
|
18879
16835
|
// src/analyst-metric-families/round-timeline.ts
|
|
18880
|
-
function
|
|
16836
|
+
function isRecord14(value) {
|
|
18881
16837
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18882
16838
|
}
|
|
18883
16839
|
function wallMsFromSpan2(startedAt, endedAt) {
|
|
18884
16840
|
return Date.parse(endedAt) - Date.parse(startedAt);
|
|
18885
16841
|
}
|
|
18886
16842
|
function readClassCount(body) {
|
|
18887
|
-
if (!
|
|
18888
|
-
if (!
|
|
16843
|
+
if (!isRecord14(body.outcome)) return void 0;
|
|
16844
|
+
if (!isRecord14(body.outcome.decisiveFacts)) return void 0;
|
|
18889
16845
|
const classCount = body.outcome.decisiveFacts.classCount;
|
|
18890
16846
|
if (typeof classCount !== "number" || !Number.isFinite(classCount)) {
|
|
18891
16847
|
return void 0;
|
|
@@ -19029,7 +16985,7 @@ var init_analyst_metric_family = __esm({
|
|
|
19029
16985
|
});
|
|
19030
16986
|
|
|
19031
16987
|
// src/analyst-page.ts
|
|
19032
|
-
import { createHash as
|
|
16988
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
19033
16989
|
import { dirname as dirname21, join as join34 } from "node:path";
|
|
19034
16990
|
function analystIssuePageKey(address) {
|
|
19035
16991
|
const parts = ["book", address.bookKey];
|
|
@@ -19038,7 +16994,7 @@ function analystIssuePageKey(address) {
|
|
|
19038
16994
|
} else if (address.scopeRootIdentity !== void 0) {
|
|
19039
16995
|
parts.push("root", physicalPathIdentity(address.scopeRootIdentity));
|
|
19040
16996
|
}
|
|
19041
|
-
return
|
|
16997
|
+
return createHash3("sha256").update(parts.join("\0")).digest("hex").slice(0, 32);
|
|
19042
16998
|
}
|
|
19043
16999
|
function analystIssuePagePath(ledgerHome, address) {
|
|
19044
17000
|
return join34(ledgerHome, "analyst", "issues", `${analystIssuePageKey(address)}.json`);
|
|
@@ -22875,8 +20831,8 @@ var init_submission_ledger = __esm({
|
|
|
22875
20831
|
});
|
|
22876
20832
|
|
|
22877
20833
|
// src/archivist-record-topology.ts
|
|
22878
|
-
import { createHash as
|
|
22879
|
-
import { join as
|
|
20834
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
20835
|
+
import { join as join41 } from "node:path";
|
|
22880
20836
|
function resolveNavigatorWorkSubjectPlacement(input) {
|
|
22881
20837
|
let ledgerHome;
|
|
22882
20838
|
if (input.parentSessionFile !== void 0 && input.parentSessionFile.length > 0) {
|
|
@@ -22886,10 +20842,10 @@ function resolveNavigatorWorkSubjectPlacement(input) {
|
|
|
22886
20842
|
}
|
|
22887
20843
|
}
|
|
22888
20844
|
ledgerHome ??= resolveActivationLedgerHome(input.home);
|
|
22889
|
-
const digest =
|
|
20845
|
+
const digest = createHash4("sha256").update(input.subject).digest("hex").slice(0, 32);
|
|
22890
20846
|
return {
|
|
22891
20847
|
ledgerHome,
|
|
22892
|
-
sessionDir:
|
|
20848
|
+
sessionDir: join41(
|
|
22893
20849
|
activationBookDirectory(ledgerHome, resolveBookKeyFromGit(input.cwd)),
|
|
22894
20850
|
NAVIGATOR_RECORD_KIND,
|
|
22895
20851
|
digest
|
|
@@ -22961,10 +20917,10 @@ import {
|
|
|
22961
20917
|
statSync as statSync7,
|
|
22962
20918
|
writeFileSync as writeFileSync3
|
|
22963
20919
|
} from "node:fs";
|
|
22964
|
-
import { dirname as dirname23, resolve as resolve17, join as
|
|
20920
|
+
import { dirname as dirname23, resolve as resolve17, join as join42 } from "node:path";
|
|
22965
20921
|
import { StringDecoder } from "node:string_decoder";
|
|
22966
20922
|
function readCurrentSession(sessionDir) {
|
|
22967
|
-
const ledger =
|
|
20923
|
+
const ledger = join42(sessionDir, CURRENT_SESSION_LEDGER);
|
|
22968
20924
|
try {
|
|
22969
20925
|
const value = JSON.parse(readFileSync4(ledger, "utf8"));
|
|
22970
20926
|
if (typeof value !== "object" || value === null || typeof value.sessionFile !== "string" || value.sessionFile.length === 0) {
|
|
@@ -22979,7 +20935,7 @@ function readCurrentSession(sessionDir) {
|
|
|
22979
20935
|
}
|
|
22980
20936
|
}
|
|
22981
20937
|
function writeCurrentSession(sessionDir, sessionFile) {
|
|
22982
|
-
const ledger =
|
|
20938
|
+
const ledger = join42(sessionDir, CURRENT_SESSION_LEDGER);
|
|
22983
20939
|
try {
|
|
22984
20940
|
writeFileSync3(ledger, `${JSON.stringify({ sessionFile })}
|
|
22985
20941
|
`, { flag: "wx" });
|
|
@@ -22995,7 +20951,7 @@ function isCurrentSessionClaimRace(error) {
|
|
|
22995
20951
|
return errnoCode(error.cause) === "EEXIST";
|
|
22996
20952
|
}
|
|
22997
20953
|
function currentSessionLedgerPath(sessionDir) {
|
|
22998
|
-
return
|
|
20954
|
+
return join42(sessionDir, CURRENT_SESSION_LEDGER);
|
|
22999
20955
|
}
|
|
23000
20956
|
function readBoundedSessionHeader(filePath) {
|
|
23001
20957
|
const fd = openSync2(filePath, "r");
|
|
@@ -23082,7 +21038,7 @@ function mostRecentNavigatorSessionFile(sessionDir, cwd) {
|
|
|
23082
21038
|
const matched = [];
|
|
23083
21039
|
for (const name of names) {
|
|
23084
21040
|
if (!name.endsWith(".jsonl")) continue;
|
|
23085
|
-
const filePath =
|
|
21041
|
+
const filePath = join42(absoluteSessionDir, name);
|
|
23086
21042
|
let st;
|
|
23087
21043
|
try {
|
|
23088
21044
|
st = statSync7(filePath);
|
|
@@ -23194,7 +21150,7 @@ function createRecordSessionOpen(options, host = piRecordSessionHost) {
|
|
|
23194
21150
|
if (!physicallyContainedIn(ledgerHome, parentResolved)) {
|
|
23195
21151
|
throw new Error("Durable record ownership requires a parent session inside the ledger home");
|
|
23196
21152
|
}
|
|
23197
|
-
sessionDir =
|
|
21153
|
+
sessionDir = join42(dirname23(parentResolved), options.kind);
|
|
23198
21154
|
parentSession = parentFile;
|
|
23199
21155
|
mayResumeSameNest = options.kind === WORKER_SUBMISSION_GATE_KIND;
|
|
23200
21156
|
}
|
|
@@ -23265,17 +21221,16 @@ init_packaged_role_registry();
|
|
|
23265
21221
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
23266
21222
|
import { appendFile as appendFile3, mkdir as mkdir5, writeFile as writeFile10 } from "node:fs/promises";
|
|
23267
21223
|
import { createServer } from "node:net";
|
|
23268
|
-
import { dirname as dirname25, join as
|
|
21224
|
+
import { dirname as dirname25, join as join45 } from "node:path";
|
|
23269
21225
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
23270
21226
|
|
|
23271
21227
|
// src/role-runtime.ts
|
|
23272
21228
|
init_host_contracts();
|
|
23273
21229
|
init_sitian_facade();
|
|
23274
21230
|
init_submission_ledger();
|
|
23275
|
-
init_collector_ledger();
|
|
23276
21231
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
23277
21232
|
import { readFileSync as readFileSync6, writeSync as writeSync2 } from "node:fs";
|
|
23278
|
-
import { join as
|
|
21233
|
+
import { join as join44 } from "node:path";
|
|
23279
21234
|
import { Value as Value4 } from "typebox/value";
|
|
23280
21235
|
|
|
23281
21236
|
// src/activation-trace.ts
|
|
@@ -23592,96 +21547,19 @@ init_receipt_delivery_policy();
|
|
|
23592
21547
|
|
|
23593
21548
|
// src/collector-role.ts
|
|
23594
21549
|
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";
|
|
21550
|
+
init_collector_output();
|
|
23603
21551
|
|
|
23604
21552
|
// src/collector-tool-schemas.ts
|
|
23605
21553
|
init_open_tool_schema();
|
|
23606
21554
|
init_terminating_infrastructure();
|
|
23607
21555
|
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
21556
|
var collectorOutputBaseSchema = openToolObject(
|
|
23676
21557
|
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
|
|
21558
|
+
groups: Type14.Unsafe({
|
|
21559
|
+
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
21560
|
}),
|
|
23683
21561
|
unfinishedReasons: Type14.Unknown({
|
|
23684
|
-
description: "\u672A\u5B8C\u6210\u539F\u56E0\u3002"
|
|
21562
|
+
description: "\u672A\u5B8C\u6210\u539F\u56E0\uFF1B\u53D6\u8BC1\u53D7\u9650\u65F6\u5982\u5B9E\u62A5\u544A\u3002"
|
|
23685
21563
|
})
|
|
23686
21564
|
})
|
|
23687
21565
|
);
|
|
@@ -23689,146 +21567,9 @@ var collectorOutputArgsSchema = withTerminatingOutputDeclarations(
|
|
|
23689
21567
|
collectorOutputBaseSchema
|
|
23690
21568
|
);
|
|
23691
21569
|
|
|
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
21570
|
// 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
|
-
];
|
|
21571
|
+
var COLLECTOR_REQUIRED_TOOLS = [COLLECTOR_OUTPUT_TOOL];
|
|
21572
|
+
var COLLECTOR_CONSTRUCTION_TOOLS = Object.freeze(["write", "edit"]);
|
|
23832
21573
|
var COLLECTOR_TRANSPORT_FLAGS = Object.freeze([
|
|
23833
21574
|
Object.freeze({
|
|
23834
21575
|
name: "ak-collector-repo",
|
|
@@ -23840,87 +21581,49 @@ var COLLECTOR_TRANSPORT_FLAGS = Object.freeze([
|
|
|
23840
21581
|
Object.freeze({
|
|
23841
21582
|
name: "ak-collector-pr",
|
|
23842
21583
|
definition: Object.freeze({
|
|
23843
|
-
description: "Optional positive safe-integer pull request number for Collector. Omit when the role will
|
|
21584
|
+
description: "Optional positive safe-integer pull request number for Collector. Omit when the role will locate the PR via host CLI.",
|
|
23844
21585
|
type: "string"
|
|
23845
21586
|
})
|
|
23846
21587
|
}),
|
|
23847
21588
|
Object.freeze({
|
|
23848
21589
|
name: "ak-collector-request-manifest",
|
|
23849
21590
|
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).`,
|
|
21591
|
+
description: "Path to the Collector v1 request manifest JSON file (caller guidance; not a machine collection directive).",
|
|
23858
21592
|
type: "string"
|
|
23859
21593
|
})
|
|
23860
21594
|
})
|
|
23861
21595
|
]);
|
|
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
21596
|
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
21597
|
function buildMethodContext(activation) {
|
|
23880
|
-
const pr = activation.ledger.config.prNumber;
|
|
23881
|
-
const handbook = activation.handbookView;
|
|
23882
21598
|
const lines = [
|
|
23883
21599
|
"<collector_method>",
|
|
23884
21600
|
`host: github.com`,
|
|
23885
21601
|
`repository: ${activation.repository.canonical}`,
|
|
23886
|
-
`prNumber: ${
|
|
23887
|
-
`waitWindowMs: ${String(activation.ledger.config.waitWindowMs)}`,
|
|
21602
|
+
`prNumber: ${activation.prNumber === void 0 ? "\u672A\u7ED1\u5B9A" : String(activation.prNumber)}`,
|
|
23888
21603
|
`requests: ${JSON.stringify(activation.manifest.requests.map((request) => ({ id: request.id })))}`,
|
|
23889
|
-
`
|
|
23890
|
-
`handbookRepoSource: ${handbook.repoSource}`,
|
|
21604
|
+
`manifestDigest: ${activation.manifest.digest}`,
|
|
23891
21605
|
"</collector_method>"
|
|
23892
21606
|
];
|
|
23893
|
-
if (
|
|
21607
|
+
if (activation.manifest.requests.length > 0) {
|
|
23894
21608
|
const payload = JSON.stringify({
|
|
23895
|
-
|
|
23896
|
-
|
|
23897
|
-
|
|
23898
|
-
|
|
23899
|
-
repository: activation.repository.canonical
|
|
21609
|
+
requests: activation.manifest.requests.map((request) => ({
|
|
21610
|
+
id: request.id,
|
|
21611
|
+
body: request.requestBody
|
|
21612
|
+
}))
|
|
23900
21613
|
}).replaceAll("<", "\\u003c");
|
|
23901
|
-
lines.push("", "<
|
|
21614
|
+
lines.push("", "<collector_request_manifest>", payload, "</collector_request_manifest>");
|
|
23902
21615
|
}
|
|
23903
21616
|
return lines.join("\n");
|
|
23904
21617
|
}
|
|
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) {
|
|
21618
|
+
function createCollectorRoleRuntime(pi, dependencies) {
|
|
23915
21619
|
let toolsRegistered = false;
|
|
23916
21620
|
return {
|
|
23917
|
-
async activate(
|
|
21621
|
+
async activate(_ctx) {
|
|
23918
21622
|
const soul = (await dependencies.loadSoul()).trim();
|
|
23919
21623
|
if (soul.length === 0) throw new Error("Collector soul is empty");
|
|
23920
21624
|
const repoFlag = pi.getFlag("ak-collector-repo");
|
|
23921
21625
|
const prFlag = pi.getFlag("ak-collector-pr");
|
|
23922
21626
|
const requestManifestFlag = pi.getFlag("ak-collector-request-manifest");
|
|
23923
|
-
const waitMsFlag = pi.getFlag("ak-collector-wait-ms");
|
|
23924
21627
|
if (typeof repoFlag !== "string" || repoFlag.trim().length === 0) {
|
|
23925
21628
|
throw new Error("Collector requires --ak-collector-repo");
|
|
23926
21629
|
}
|
|
@@ -23932,36 +21635,11 @@ function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
|
23932
21635
|
prNumber = parseCollectorPrNumber(prFlag);
|
|
23933
21636
|
}
|
|
23934
21637
|
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
21638
|
return {
|
|
23957
21639
|
soul,
|
|
23958
21640
|
repository,
|
|
23959
|
-
|
|
23960
|
-
|
|
23961
|
-
transport,
|
|
23962
|
-
clock,
|
|
23963
|
-
handbook,
|
|
23964
|
-
handbookView
|
|
21641
|
+
prNumber,
|
|
21642
|
+
manifest
|
|
23965
21643
|
};
|
|
23966
21644
|
},
|
|
23967
21645
|
assembleMaterials(activation, baseSystemPrompt) {
|
|
@@ -23975,335 +21653,32 @@ function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
|
23975
21653
|
buildMethodContext(activation)
|
|
23976
21654
|
].join("\n");
|
|
23977
21655
|
},
|
|
23978
|
-
onToolCall(
|
|
23979
|
-
if (
|
|
21656
|
+
onToolCall(_activation, event) {
|
|
21657
|
+
if (COLLECTOR_CONSTRUCTION_TOOLS.includes(event.toolName)) {
|
|
23980
21658
|
return {
|
|
23981
21659
|
block: true,
|
|
23982
|
-
reason:
|
|
21660
|
+
reason: `\u901A\u8FDB\u53F8\u4E3A\u6536\u8BC1\u5E2D\uFF0C\u7981\u7528\u65BD\u5DE5\u5DE5\u5177 ${event.toolName}`
|
|
23983
21661
|
};
|
|
23984
21662
|
}
|
|
23985
|
-
if (event.toolName === COLLECTOR_OUTPUT_TOOL) {
|
|
23986
|
-
activation.ledger.beginOperational(COLLECTOR_OUTPUT_TOOL, event.toolCallId);
|
|
23987
|
-
}
|
|
23988
21663
|
return void 0;
|
|
23989
21664
|
},
|
|
23990
|
-
onToolResult(activation, event) {
|
|
23991
|
-
activation.ledger.completeOperational(event.toolCallId);
|
|
23992
|
-
},
|
|
23993
21665
|
registerBusinessTools(getActivation) {
|
|
23994
21666
|
if (toolsRegistered) return;
|
|
23995
21667
|
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
21668
|
pi.registerTool({
|
|
24283
21669
|
name: COLLECTOR_OUTPUT_TOOL,
|
|
24284
21670
|
label: "\u901A\u8FDB\u53F8\u8F93\u51FA",
|
|
24285
21671
|
description: "\u63D0\u4EA4\u901A\u8FDB\u53F8\u56DE\u6267\u3002",
|
|
24286
21672
|
promptSnippet: "\u63D0\u4EA4\u901A\u8FDB\u53F8\u56DE\u6267",
|
|
24287
21673
|
parameters: outputSchema,
|
|
24288
|
-
async execute(
|
|
21674
|
+
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
24289
21675
|
const activation = getActivation();
|
|
24290
21676
|
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
|
-
}
|
|
21677
|
+
return {
|
|
21678
|
+
content: [],
|
|
21679
|
+
details: params,
|
|
21680
|
+
terminate: true
|
|
21681
|
+
};
|
|
24307
21682
|
}
|
|
24308
21683
|
});
|
|
24309
21684
|
}
|
|
@@ -24740,7 +22115,7 @@ var AUDITOR_TOOL_SPEC = {
|
|
|
24740
22115
|
};
|
|
24741
22116
|
|
|
24742
22117
|
// src/navigator-attendance.ts
|
|
24743
|
-
import { createHash as
|
|
22118
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
24744
22119
|
init_navigator_invocation_identity();
|
|
24745
22120
|
init_packaged_role_registry();
|
|
24746
22121
|
init_activation_ledger_topology();
|
|
@@ -24945,11 +22320,11 @@ init_packaged_role_registry();
|
|
|
24945
22320
|
// src/navigator-work-base.ts
|
|
24946
22321
|
init_atomic_write();
|
|
24947
22322
|
import { existsSync as existsSync10, realpathSync as realpathSync3 } from "node:fs";
|
|
24948
|
-
import { readFile as
|
|
24949
|
-
import { basename as basename10, dirname as dirname22, join as
|
|
22323
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
22324
|
+
import { basename as basename10, dirname as dirname22, join as join40, resolve as resolve16 } from "node:path";
|
|
24950
22325
|
var NAVIGATOR_WORK_CONTEXT_BASENAME = "work-context.json";
|
|
24951
22326
|
function navigatorWorkContextFile(sessionDir) {
|
|
24952
|
-
return
|
|
22327
|
+
return join40(sessionDir, NAVIGATOR_WORK_CONTEXT_BASENAME);
|
|
24953
22328
|
}
|
|
24954
22329
|
function isNavigatorWorkContextFile(path) {
|
|
24955
22330
|
const resolved = resolve16(path);
|
|
@@ -24974,7 +22349,7 @@ async function persistNavigatorWorkBase(sessionDir, body) {
|
|
|
24974
22349
|
const next = `${JSON.stringify({ subject: body.subject, authority: body.authority })}
|
|
24975
22350
|
`;
|
|
24976
22351
|
try {
|
|
24977
|
-
const current = await
|
|
22352
|
+
const current = await readFile22(path, "utf8");
|
|
24978
22353
|
if (current === next) return path;
|
|
24979
22354
|
} catch (error) {
|
|
24980
22355
|
if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
|
|
@@ -24989,7 +22364,7 @@ async function readNavigatorWorkBase(path) {
|
|
|
24989
22364
|
if (canonical === void 0) return void 0;
|
|
24990
22365
|
let text;
|
|
24991
22366
|
try {
|
|
24992
|
-
text = await
|
|
22367
|
+
text = await readFile22(canonical, "utf8");
|
|
24993
22368
|
} catch (error) {
|
|
24994
22369
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
24995
22370
|
return void 0;
|
|
@@ -25301,7 +22676,7 @@ function navigatorSubjectKey(subjectRoot, subject, provenance = "role_input") {
|
|
|
25301
22676
|
if (provenance === "placeholder") return subjectRoot;
|
|
25302
22677
|
const normalized = subject.trim().replace(/\s+/g, " ");
|
|
25303
22678
|
if (normalized === "") return subjectRoot;
|
|
25304
|
-
return `${subjectRoot}#${
|
|
22679
|
+
return `${subjectRoot}#${createHash5("sha256").update(normalized).digest("hex").slice(0, 32)}`;
|
|
25305
22680
|
}
|
|
25306
22681
|
function navigatorSubjectKeyForInput(subjectRoot, reference, cwd = process.cwd()) {
|
|
25307
22682
|
if (issueRoot(subjectRoot) !== void 0 || !subjectRoot.includes("/.ak/work/")) return subjectRoot;
|
|
@@ -25789,7 +23164,7 @@ init_submission_errors();
|
|
|
25789
23164
|
init_worker_submission_contracts();
|
|
25790
23165
|
init_submission_errors();
|
|
25791
23166
|
init_worker_submission_contracts();
|
|
25792
|
-
import { execFileSync as
|
|
23167
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
25793
23168
|
import { existsSync as existsSync14, lstatSync as lstatSync3, readdirSync as readdirSync4, readFileSync as readFileSync5, rmdirSync, rmSync as rmSync2 } from "node:fs";
|
|
25794
23169
|
import { resolve as resolve19 } from "node:path";
|
|
25795
23170
|
var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
|
|
@@ -25802,7 +23177,7 @@ var HOOK_FILE = "reference-transaction";
|
|
|
25802
23177
|
var PLATFORM_PREFIX = /^[A-Za-z][A-Za-z0-9_-]*:/;
|
|
25803
23178
|
var UNFINISHED_REASON_BOUNCE_LIMIT = 2;
|
|
25804
23179
|
function git2(cwd, args) {
|
|
25805
|
-
return
|
|
23180
|
+
return execFileSync3("git", args, {
|
|
25806
23181
|
cwd,
|
|
25807
23182
|
encoding: "utf8",
|
|
25808
23183
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -25810,7 +23185,7 @@ function git2(cwd, args) {
|
|
|
25810
23185
|
}).trim();
|
|
25811
23186
|
}
|
|
25812
23187
|
function gitFile(file, args) {
|
|
25813
|
-
return
|
|
23188
|
+
return execFileSync3("git", ["config", "--file", file, ...args], {
|
|
25814
23189
|
encoding: "utf8",
|
|
25815
23190
|
stdio: ["ignore", "pipe", "pipe"],
|
|
25816
23191
|
env: { ...process.env, GIT_DIR: void 0, GIT_WORK_TREE: void 0, GIT_COMMON_DIR: void 0 }
|
|
@@ -25886,7 +23261,7 @@ function uninstallPackageWorkerHooks(cwd) {
|
|
|
25886
23261
|
rmOwnedDir(resolve19(gitDir, HOOKS_DIR));
|
|
25887
23262
|
}
|
|
25888
23263
|
}
|
|
25889
|
-
function
|
|
23264
|
+
function isRecord15(value) {
|
|
25890
23265
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25891
23266
|
}
|
|
25892
23267
|
function unfinishedReasonPresent(details) {
|
|
@@ -25902,7 +23277,7 @@ function readGateState(session) {
|
|
|
25902
23277
|
if (entry.type !== "custom") continue;
|
|
25903
23278
|
if (entry.customType === WORKER_COMMIT_BASELINE_ENTRY_TYPE) {
|
|
25904
23279
|
const data = entry.data;
|
|
25905
|
-
if (
|
|
23280
|
+
if (isRecord15(data) && (data.head === null || typeof data.head === "string")) {
|
|
25906
23281
|
baseline = data.head;
|
|
25907
23282
|
}
|
|
25908
23283
|
} else if (entry.customType === WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE) {
|
|
@@ -25928,11 +23303,11 @@ function reliableWindow(cwd, baseline, head) {
|
|
|
25928
23303
|
const raw = git2(cwd, ["log", "--format=%P%x1e%s", range]);
|
|
25929
23304
|
if (raw.length === 0) return [];
|
|
25930
23305
|
return raw.split("\n").flatMap((line2) => {
|
|
25931
|
-
const
|
|
25932
|
-
if (
|
|
23306
|
+
const sep6 = line2.indexOf("");
|
|
23307
|
+
if (sep6 < 0) return [];
|
|
25933
23308
|
return [{
|
|
25934
|
-
subject: line2.slice(
|
|
25935
|
-
merge: line2.slice(0,
|
|
23309
|
+
subject: line2.slice(sep6 + 1),
|
|
23310
|
+
merge: line2.slice(0, sep6).trim().includes(" ")
|
|
25936
23311
|
}];
|
|
25937
23312
|
});
|
|
25938
23313
|
}
|
|
@@ -26095,11 +23470,11 @@ var FIXER_PHASES = ["plan", "apply"];
|
|
|
26095
23470
|
function isWorkerPhase(value) {
|
|
26096
23471
|
return typeof value === "string" && FIXER_PHASES.includes(value);
|
|
26097
23472
|
}
|
|
26098
|
-
function
|
|
23473
|
+
function isRecord16(value) {
|
|
26099
23474
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26100
23475
|
}
|
|
26101
23476
|
function workerStatusOf(output) {
|
|
26102
|
-
return
|
|
23477
|
+
return isRecord16(output) && typeof output.status === "string" ? output.status : void 0;
|
|
26103
23478
|
}
|
|
26104
23479
|
function deepFreeze2(value) {
|
|
26105
23480
|
if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
|
|
@@ -26606,8 +23981,15 @@ async function projectClosedSubmissionLifecycle(closed, context, phase, recordAc
|
|
|
26606
23981
|
isError: false,
|
|
26607
23982
|
details: closed.accepted
|
|
26608
23983
|
};
|
|
26609
|
-
|
|
26610
|
-
|
|
23984
|
+
let navigator;
|
|
23985
|
+
try {
|
|
23986
|
+
navigator = await settle(publicNavigatorSettlement(closed.role, phase, closure));
|
|
23987
|
+
} finally {
|
|
23988
|
+
context.sessionManager.appendCustomEntry?.("ak-role-submission-closure", {
|
|
23989
|
+
...closure,
|
|
23990
|
+
...navigator === void 0 ? {} : { navigator }
|
|
23991
|
+
});
|
|
23992
|
+
}
|
|
26611
23993
|
}
|
|
26612
23994
|
function createFiledOfficerRuntime(roleHost, spec, dependencies) {
|
|
26613
23995
|
let soul;
|
|
@@ -26785,7 +24167,7 @@ function readDiaristTicketAssertion(submitted) {
|
|
|
26785
24167
|
function readRoleRunCoordinates(ctx, label) {
|
|
26786
24168
|
const runDirectory = runDirectoryFromHostContext(ctx);
|
|
26787
24169
|
if (runDirectory === void 0) throw new Error(`${label} requires AK_ROLE_RUN_DIR`);
|
|
26788
|
-
const admittedPath =
|
|
24170
|
+
const admittedPath = join44(runDirectory, "admitted-request.json");
|
|
26789
24171
|
const admitted = JSON.parse(readFileSync6(admittedPath, "utf8"));
|
|
26790
24172
|
if (typeof admitted.projectRoot !== "string" || admitted.projectRoot.trim() === "") {
|
|
26791
24173
|
throw new Error(`${label} admitted-request missing projectRoot (${admittedPath})`);
|
|
@@ -26966,6 +24348,8 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
26966
24348
|
let activeReviewerParent;
|
|
26967
24349
|
let navigatorAttendance;
|
|
26968
24350
|
let pendingNavigatorPresentation;
|
|
24351
|
+
let navigatorActivation = 0;
|
|
24352
|
+
let navigatorDeliveryClosed = false;
|
|
26969
24353
|
let pendingNavigatorSettlement;
|
|
26970
24354
|
let navigatorWorkContext;
|
|
26971
24355
|
let navigatorSessionParent;
|
|
@@ -27018,6 +24402,7 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27018
24402
|
void settlePromise.catch(() => void 0);
|
|
27019
24403
|
const raced = await raceNavigatorGrace(settlePromise, NAVIGATOR_POST_ROLE_GRACE_MS);
|
|
27020
24404
|
if (raced.status !== "timeout") return;
|
|
24405
|
+
navigatorDeliveryClosed = true;
|
|
27021
24406
|
if (pendingNavigatorPresentation === void 0) {
|
|
27022
24407
|
const report = {
|
|
27023
24408
|
disposition: "unavailable",
|
|
@@ -27042,6 +24427,7 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27042
24427
|
})();
|
|
27043
24428
|
pendingNavigatorSettlement = pending;
|
|
27044
24429
|
await pending;
|
|
24430
|
+
return pendingNavigatorPresentation?.event;
|
|
27045
24431
|
};
|
|
27046
24432
|
projectClosedSubmission = async (closed, context) => projectClosedSubmissionLifecycle(
|
|
27047
24433
|
closed,
|
|
@@ -27097,10 +24483,6 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27097
24483
|
};
|
|
27098
24484
|
}
|
|
27099
24485
|
if (activeCollector !== void 0 && selectedRole === role) {
|
|
27100
|
-
if (!collectorFirstDispatchDone) {
|
|
27101
|
-
collectorFirstDispatchDone = true;
|
|
27102
|
-
activeCollector.ledger.recordActivation(activeCollector.clock);
|
|
27103
|
-
}
|
|
27104
24486
|
return {
|
|
27105
24487
|
systemPrompt: collectorBusiness.assembleMaterials(activeCollector, event.systemPrompt)
|
|
27106
24488
|
};
|
|
@@ -27141,9 +24523,6 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27141
24523
|
roleHost.on("tool_result", async (event) => {
|
|
27142
24524
|
const role = selectedRole;
|
|
27143
24525
|
if (role === void 0) return;
|
|
27144
|
-
if (activeCollector !== void 0 && selectedRole === roleHost.getFlag(ROLE_FLAG.name)) {
|
|
27145
|
-
collectorBusiness.onToolResult(activeCollector, event);
|
|
27146
|
-
}
|
|
27147
24526
|
const pendingInfra = pendingInfrastructureFailures.get(event.toolCallId);
|
|
27148
24527
|
const isRoleInfrastructureFailure = pendingInfra !== void 0;
|
|
27149
24528
|
if (pendingInfra !== void 0) pendingInfrastructureFailures.delete(event.toolCallId);
|
|
@@ -27278,11 +24657,6 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27278
24657
|
priorFetch = void 0;
|
|
27279
24658
|
fetchWrapped = false;
|
|
27280
24659
|
}
|
|
27281
|
-
if (activeCollector !== void 0 && activeCollector.ledger.fatal) {
|
|
27282
|
-
if (process.exitCode === void 0 || process.exitCode === 0) {
|
|
27283
|
-
process.exitCode = 1;
|
|
27284
|
-
}
|
|
27285
|
-
}
|
|
27286
24660
|
const presentation = pendingNavigatorPresentation;
|
|
27287
24661
|
pendingNavigatorPresentation = void 0;
|
|
27288
24662
|
if (presentation !== void 0) {
|
|
@@ -27414,41 +24788,16 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27414
24788
|
}
|
|
27415
24789
|
});
|
|
27416
24790
|
let activeCollector;
|
|
27417
|
-
let collectorFirstDispatchDone = false;
|
|
27418
24791
|
const collectorBusiness = createCollectorRoleRuntime(
|
|
27419
24792
|
roleHost,
|
|
27420
24793
|
{
|
|
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
|
|
24794
|
+
loadSoul: () => requireRoleSoul("collector")
|
|
24795
|
+
}
|
|
27446
24796
|
);
|
|
27447
24797
|
let collectorToolCallRegistered = false;
|
|
27448
24798
|
const collector = {
|
|
27449
24799
|
async activate(context, event) {
|
|
27450
24800
|
activeCollector = void 0;
|
|
27451
|
-
collectorFirstDispatchDone = false;
|
|
27452
24801
|
if (context.mode !== "print" && context.mode !== "json") {
|
|
27453
24802
|
throw new Error(
|
|
27454
24803
|
`Collector supports only print or json mode (got ${context.mode})`
|
|
@@ -27482,16 +24831,19 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27482
24831
|
throw new Error(`Collector required tool name collision: ${required}`);
|
|
27483
24832
|
}
|
|
27484
24833
|
}
|
|
27485
|
-
roleHost.
|
|
24834
|
+
const priorActive = roleHost.getActiveTools();
|
|
24835
|
+
const hostSurface = (priorActive.length > 0 ? priorActive : allTools.map((tool) => tool.name)).filter((name) => !COLLECTOR_CONSTRUCTION_TOOLS.includes(name));
|
|
24836
|
+
const nextActive = [.../* @__PURE__ */ new Set([...hostSurface, ...COLLECTOR_REQUIRED_TOOLS])];
|
|
24837
|
+
roleHost.setActiveTools(nextActive);
|
|
27486
24838
|
const active = new Set(roleHost.getActiveTools());
|
|
27487
24839
|
for (const required of COLLECTOR_REQUIRED_TOOLS) {
|
|
27488
24840
|
if (!active.has(required)) {
|
|
27489
24841
|
throw new Error(`Collector failed to activate required tool ${required}`);
|
|
27490
24842
|
}
|
|
27491
24843
|
}
|
|
27492
|
-
for (const name of
|
|
27493
|
-
if (
|
|
27494
|
-
throw new Error(`Collector
|
|
24844
|
+
for (const name of COLLECTOR_CONSTRUCTION_TOOLS) {
|
|
24845
|
+
if (active.has(name)) {
|
|
24846
|
+
throw new Error(`Collector must not activate construction tool ${name}`);
|
|
27495
24847
|
}
|
|
27496
24848
|
}
|
|
27497
24849
|
if (!collectorToolCallRegistered) {
|
|
@@ -27499,20 +24851,10 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27499
24851
|
roleHost.on("tool_call", (toolEvent) => {
|
|
27500
24852
|
const liveRole = roleHost.getFlag(ROLE_FLAG.name);
|
|
27501
24853
|
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
24854
|
return collectorBusiness.onToolCall(activeCollector, toolEvent);
|
|
27509
24855
|
});
|
|
27510
24856
|
}
|
|
27511
|
-
|
|
27512
|
-
if (activation.ledger.activationRecorded) {
|
|
27513
|
-
collectorFirstDispatchDone = true;
|
|
27514
|
-
}
|
|
27515
|
-
activeCollector = activation;
|
|
24857
|
+
activeCollector = await collectorBusiness.activate(context);
|
|
27516
24858
|
}
|
|
27517
24859
|
};
|
|
27518
24860
|
const clock = dependencies.activationClock ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
@@ -27562,10 +24904,11 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27562
24904
|
roleReferenceMaterials = "";
|
|
27563
24905
|
activeReviewerParent = void 0;
|
|
27564
24906
|
activeCollector = void 0;
|
|
27565
|
-
collectorFirstDispatchDone = false;
|
|
27566
24907
|
receiptDelivery = createReceiptDeliveryPolicy();
|
|
27567
24908
|
noReceiptRecorded = false;
|
|
27568
24909
|
pendingNavigatorPresentation = void 0;
|
|
24910
|
+
navigatorActivation += 1;
|
|
24911
|
+
navigatorDeliveryClosed = false;
|
|
27569
24912
|
pendingNavigatorSettlement = void 0;
|
|
27570
24913
|
pendingInfrastructureFailures.clear();
|
|
27571
24914
|
pendingSubmissionNonPassByToolCallId.clear();
|
|
@@ -27661,6 +25004,7 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27661
25004
|
} catch {
|
|
27662
25005
|
}
|
|
27663
25006
|
}
|
|
25007
|
+
const activation = navigatorActivation;
|
|
27664
25008
|
navigatorAttendance = await dependencies.createNavigatorAttendance({
|
|
27665
25009
|
context: ctx,
|
|
27666
25010
|
role: entry.role,
|
|
@@ -27671,7 +25015,9 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
27671
25015
|
invocationId,
|
|
27672
25016
|
...contextError === void 0 ? {} : { contextError },
|
|
27673
25017
|
onEvent: (navigatorEvent, report) => {
|
|
27674
|
-
|
|
25018
|
+
if (activation === navigatorActivation && !navigatorDeliveryClosed) {
|
|
25019
|
+
pendingNavigatorPresentation = { event: navigatorEvent, report };
|
|
25020
|
+
}
|
|
27675
25021
|
}
|
|
27676
25022
|
});
|
|
27677
25023
|
if (navigatorWorkContext.contextError === void 0 && navigatorWorkContext.subjectProvenance !== "placeholder") {
|
|
@@ -27745,7 +25091,7 @@ async function prepareRoleEnvelope(options) {
|
|
|
27745
25091
|
const hostAbort = new AbortController();
|
|
27746
25092
|
const runId = request.runDirectory.split("/").filter(Boolean).at(-1) ?? randomUUID9();
|
|
27747
25093
|
await mkdir5(request.runDirectory, { recursive: true });
|
|
27748
|
-
let sessionFile = options.sessionFile ??
|
|
25094
|
+
let sessionFile = options.sessionFile ?? join45(request.runDirectory, "session", "session.jsonl");
|
|
27749
25095
|
await mkdir5(dirname25(sessionFile), { recursive: true });
|
|
27750
25096
|
if (request.continuation.kind !== "resume") {
|
|
27751
25097
|
try {
|
|
@@ -28262,15 +25608,13 @@ async function prepareRoleEnvelope(options) {
|
|
|
28262
25608
|
}
|
|
28263
25609
|
|
|
28264
25610
|
// src/role-runtime-dependencies.ts
|
|
28265
|
-
|
|
25611
|
+
import { readFile as readFile24 } from "node:fs/promises";
|
|
28266
25612
|
init_doctor_evidence();
|
|
28267
|
-
import { readFile as readFile25 } from "node:fs/promises";
|
|
28268
|
-
import { join as join47 } from "node:path";
|
|
28269
25613
|
|
|
28270
25614
|
// src/navigator-work-context.ts
|
|
28271
25615
|
init_doctor_evidence();
|
|
28272
25616
|
init_host_contracts();
|
|
28273
|
-
import { readFile as
|
|
25617
|
+
import { readFile as readFile23 } from "node:fs/promises";
|
|
28274
25618
|
import { resolve as resolve20 } from "node:path";
|
|
28275
25619
|
init_notary_source_run();
|
|
28276
25620
|
init_packaged_role_registry();
|
|
@@ -28284,7 +25628,7 @@ function navigatorInputReference(getFlag, role) {
|
|
|
28284
25628
|
async function loadNavigatorWorkContext(options) {
|
|
28285
25629
|
const reference = navigatorInputReference(options.getFlag, options.role);
|
|
28286
25630
|
const subjectMode = packagedNavigatorSubject(options.role);
|
|
28287
|
-
const input = reference === void 0 || subjectMode === "case" || subjectMode === "source-run" ? void 0 : await
|
|
25631
|
+
const input = reference === void 0 || subjectMode === "case" || subjectMode === "source-run" ? void 0 : await readFile23(reference, "utf8");
|
|
28288
25632
|
const subjectRoot = subjectPath(reference ?? options.context.sessionManager.getSessionDir(), options.context.cwd);
|
|
28289
25633
|
let subjectKey = reference === void 0 ? subjectRoot : navigatorSubjectKeyForInput(subjectRoot, reference, options.context.cwd);
|
|
28290
25634
|
let subject = input ?? `work subject: ${subjectKey}`;
|
|
@@ -28341,7 +25685,7 @@ async function loadNavigatorWorkContext(options) {
|
|
|
28341
25685
|
let authorityMaterial;
|
|
28342
25686
|
for (const path of authorityFiles) {
|
|
28343
25687
|
try {
|
|
28344
|
-
const content = await
|
|
25688
|
+
const content = await readFile23(path, "utf8");
|
|
28345
25689
|
if (content.trim() !== "") {
|
|
28346
25690
|
authorityMaterial = content;
|
|
28347
25691
|
break;
|
|
@@ -28378,19 +25722,16 @@ function loadRegisteredRoleSoul(role) {
|
|
|
28378
25722
|
return usesSubjectSoul(role) ? loadAuditorSoulFromSubjectInput() : loadMainRoleSessionMaterials(role);
|
|
28379
25723
|
}
|
|
28380
25724
|
function createRoleRuntimeDependencies(packageRoot) {
|
|
28381
|
-
const collectorHandbookSeedPath = join47(packageRoot, "resources/collector-bot-handbook.md");
|
|
28382
25725
|
const navigatorSessionFactory = createNativeNavigatorSessionFactory();
|
|
28383
25726
|
return {
|
|
28384
25727
|
packageRoot,
|
|
28385
25728
|
loadRoleReferenceMaterials: loadPackagedRoleReferenceMaterials,
|
|
28386
25729
|
loadRoleSoul: loadRegisteredRoleSoul,
|
|
28387
|
-
loadFixPacket: (path) =>
|
|
28388
|
-
loadCoderTask: (path) =>
|
|
28389
|
-
loadCollectorHandbookSeed: () => readFile25(collectorHandbookSeedPath, "utf8"),
|
|
28390
|
-
createCollectorTransport: () => createGhCollectorGitHubTransport(),
|
|
25730
|
+
loadFixPacket: (path) => readFile24(path, "utf8"),
|
|
25731
|
+
loadCoderTask: (path) => readFile24(path, "utf8"),
|
|
28391
25732
|
loadDoctorCase,
|
|
28392
25733
|
loadNotarySourceRun: loadNotarySourceRunLocator,
|
|
28393
|
-
loadMergerInput: async (path) => JSON.parse(await
|
|
25734
|
+
loadMergerInput: async (path) => JSON.parse(await readFile24(path, "utf8")),
|
|
28394
25735
|
loadNavigatorWorkContext: (options) => loadNavigatorWorkContext({
|
|
28395
25736
|
context: options.context,
|
|
28396
25737
|
role: options.role,
|
|
@@ -28415,9 +25756,9 @@ function createRoleRuntimeDependencies(packageRoot) {
|
|
|
28415
25756
|
init_session_identity();
|
|
28416
25757
|
|
|
28417
25758
|
// src/acp-host/description.ts
|
|
28418
|
-
import { join as
|
|
25759
|
+
import { join as join46 } from "node:path";
|
|
28419
25760
|
function resolveAcpBinary(description, operatorHome) {
|
|
28420
|
-
return
|
|
25761
|
+
return join46(operatorHome, ...description.binaryFromHome);
|
|
28421
25762
|
}
|
|
28422
25763
|
function acpStdioArgs(description, model, seat) {
|
|
28423
25764
|
const { prefix, suffix, modelFlag, thinkingFlag } = description.argv;
|
|
@@ -28436,8 +25777,8 @@ function acpModelId(modelPassing, model) {
|
|
|
28436
25777
|
}
|
|
28437
25778
|
|
|
28438
25779
|
// src/acp-host/role-turn-host.ts
|
|
28439
|
-
import { join as
|
|
28440
|
-
import { spawn as
|
|
25780
|
+
import { join as join47 } from "node:path";
|
|
25781
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
28441
25782
|
import { createInterface } from "node:readline";
|
|
28442
25783
|
|
|
28443
25784
|
// src/external-host-turn-loop.ts
|
|
@@ -28620,7 +25961,7 @@ function acpError(code, message, cause) {
|
|
|
28620
25961
|
return Object.assign(new Error(message, cause === void 0 ? void 0 : { cause }), { code });
|
|
28621
25962
|
}
|
|
28622
25963
|
function connectAcpStdio(options) {
|
|
28623
|
-
const child =
|
|
25964
|
+
const child = spawn3(options.binary, [...options.args], { cwd: options.cwd, env: options.env, stdio: ["pipe", "pipe", "pipe"] });
|
|
28624
25965
|
const pending = /* @__PURE__ */ new Map();
|
|
28625
25966
|
const notificationHandlers = [];
|
|
28626
25967
|
if (options.onNotification !== void 0) notificationHandlers.push(options.onNotification);
|
|
@@ -28883,7 +26224,7 @@ function createAcpRoleTurnHost(config) {
|
|
|
28883
26224
|
host: config.hostName,
|
|
28884
26225
|
sessionId,
|
|
28885
26226
|
cwd: request.cwd,
|
|
28886
|
-
sessionDirectory:
|
|
26227
|
+
sessionDirectory: join47(request.runDirectory, "session"),
|
|
28887
26228
|
sessionParent,
|
|
28888
26229
|
continuation: request.continuation,
|
|
28889
26230
|
...request.model !== void 0 ? { model: request.model } : {},
|
|
@@ -28903,12 +26244,12 @@ function createAcpRoleTurnHost(config) {
|
|
|
28903
26244
|
// src/acp-host/seat-profile-soul.ts
|
|
28904
26245
|
import { constants as constants3 } from "node:fs";
|
|
28905
26246
|
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
|
|
26247
|
+
import { dirname as dirname26, join as join48, relative as relative3, resolve as resolve21 } from "node:path";
|
|
28907
26248
|
function seatProfileName(spec, role) {
|
|
28908
26249
|
return `${spec.namePrefix}${role}`;
|
|
28909
26250
|
}
|
|
28910
26251
|
function packageRoleSoulPath(packageRoot, role) {
|
|
28911
|
-
return
|
|
26252
|
+
return join48(packageRoot, "souls", `${role}.md`);
|
|
28912
26253
|
}
|
|
28913
26254
|
async function pathExists2(path) {
|
|
28914
26255
|
try {
|
|
@@ -28925,16 +26266,16 @@ async function ensureSeatProfileSoul(options) {
|
|
|
28925
26266
|
if (!await pathExists2(soulTarget)) {
|
|
28926
26267
|
throw new Error(`packaged role soul missing: ${soulTarget}`);
|
|
28927
26268
|
}
|
|
28928
|
-
const profilesRoot =
|
|
28929
|
-
const profileDir =
|
|
26269
|
+
const profilesRoot = join48(operatorHome, ...spec.profilesRootFromHome);
|
|
26270
|
+
const profileDir = join48(profilesRoot, profileName);
|
|
28930
26271
|
const hostRoot = dirname26(profilesRoot);
|
|
28931
|
-
const soulPath =
|
|
26272
|
+
const soulPath = join48(profileDir, spec.soulFileName);
|
|
28932
26273
|
if (!await pathExists2(profileDir)) {
|
|
28933
26274
|
await mkdir6(profileDir, { recursive: true });
|
|
28934
26275
|
for (const name of ["auth.json", ".env", "config.yaml"]) {
|
|
28935
|
-
const source =
|
|
26276
|
+
const source = join48(hostRoot, name);
|
|
28936
26277
|
if (!await pathExists2(source)) continue;
|
|
28937
|
-
await copyFile(source,
|
|
26278
|
+
await copyFile(source, join48(profileDir, name));
|
|
28938
26279
|
}
|
|
28939
26280
|
} else {
|
|
28940
26281
|
await mkdir6(profileDir, { recursive: true });
|