@gitroll/tacitt-cli 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-setup-B8DAiQ6Z.mjs → agent-setup-CQRWVUWR.mjs} +1 -1
- package/dist/agent-setup-worker.mjs +4 -4
- package/dist/cli.mjs +66 -9
- package/dist/codex-title-worker.mjs +1 -1
- package/dist/configured-preview-worker.mjs +4 -4
- package/dist/configured-session-worker.mjs +25 -4
- package/dist/{heap-BHcvxWCw.mjs → heap-BaTNC9kf.mjs} +45 -3
- package/dist/inspection-worker.mjs +3 -3
- package/dist/job-DrcpSL_9.mjs +615 -0
- package/dist/{model-BJdTLNjT.mjs → model-D7UnGeag.mjs} +1 -1
- package/dist/operation-executor.mjs +2 -2
- package/dist/preview-worker.mjs +1 -1
- package/dist/{query-BA0XCwnR.mjs → query-ByD0Rp_o.mjs} +391 -551
- package/dist/{run-BeLHsZWb.mjs → run-3UIkr7GZ.mjs} +2 -2
- package/dist/session-process.mjs +6 -1
- package/dist/{src-k0Ya1Bri.mjs → src-CmP73EcD.mjs} +510 -161
- package/dist/{src-B5SArpVY.mjs → src-DES7hBAP.mjs} +17 -5
- package/dist/{src-CC95LYYp.mjs → src-DNn7SifS.mjs} +763 -528
- package/dist/store-database-worker.mjs +1 -1
- package/dist/web/assets/index-BkuUI3Eu.js +67 -0
- package/dist/web/assets/index-Clg6Pfv_.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/skills/tacitt/SKILL.md +8 -6
- package/skills/tacitt/references/commands.md +14 -9
- package/skills/tacitt/references/journey.md +10 -6
- package/skills/tacitt/references/send.md +1 -1
- package/skills/tacitt/scripts/INDEX.md +6 -2
- package/skills/tacitt/scripts/journey-card-consolidation.mjs +90 -4
- package/skills/tacitt/scripts/journey-card-values.d.mts +17 -0
- package/skills/tacitt/scripts/journey-card-values.mjs +116 -0
- package/skills/tacitt/scripts/journey-classification.mjs +6 -2
- package/skills/tacitt/scripts/journey-panel-host.d.mts +9 -0
- package/skills/tacitt/scripts/journey-panel-host.mjs +56 -0
- package/skills/tacitt/scripts/journey-state.mjs +10 -4
- package/skills/tacitt/scripts/journey-tasks.mjs +1 -1
- package/skills/tacitt/scripts/journey.d.mts +2 -0
- package/skills/tacitt/scripts/journey.mjs +120 -53
- package/skills/tacitt/scripts/review-stream-client.mjs +1 -1
- package/dist/job-J3NFw3MH.mjs +0 -194
- package/dist/web/assets/index-Bjos73wK.js +0 -67
- package/dist/web/assets/index-Bl4C2b2_.css +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Bn as validatePlan, Cn as sessionNonce, Dn as entityDictionaryVersion, En as cleanupImplementationVersion, Fn as frameRecords, Gn as detectStatic, H as codePointLength, Hn as defaultLimits, Ht as ApplicationError, In as retainedMainTextNodes, Jn as jsonSpans, Jt as reviewFamilies, Ln as validateProfile, Nn as nativeText, On as nativeParserVersion, Pn as transformRecords, Qt as sourceSnapshotId, Sn as createReplacementKey, Tn as parseNativeRecord, Un as recordPointerLimits, V as bDigest, Wn as resolveLimits, Wt as safeCode, Xn as createEntityMatcher, Xt as sourceKey, Yn as agentContextLocation, an as withMandatoryCustomTerms, c as textDigest, cn as mainReviewRole, dn as renderNative, fn as createSessionPreparation, gn as createDetectionSummary, in as nativeSourceIdentitySchema, ir as isProcessingCode, j as bDuplicateShift, jn as nativeField, k as bBindingCap, kn as redactionImplementationVersion, ln as reviewRoles, nr as ProcessingError, o as reviewDigest, on as processNativeRecord, pn as bindInspection, qt as familySelected, rr as fail$1, sn as projectNativeReviewInput, tr as defaultDetectionLimits, un as createSentenceContext, vn as walkNativeFields, wn as projectNativeRecord, x as createBAnalysisUnits, zn as buildPlan } from "./locate-U3-nkird.mjs";
|
|
1
|
+
import { Bn as validatePlan, Cn as sessionNonce, Dn as entityDictionaryVersion, En as cleanupImplementationVersion, Fn as frameRecords, Gn as detectStatic, H as codePointLength, Hn as defaultLimits, Ht as ApplicationError, In as retainedMainTextNodes, Jn as jsonSpans, Jt as reviewFamilies, Ln as validateProfile, Mn as nativeItems, Nn as nativeText, On as nativeParserVersion, Pn as transformRecords, Qt as sourceSnapshotId, Sn as createReplacementKey, Tn as parseNativeRecord, Un as recordPointerLimits, V as bDigest, Wn as resolveLimits, Wt as safeCode, Xn as createEntityMatcher, Xt as sourceKey, Yn as agentContextLocation, an as withMandatoryCustomTerms, c as textDigest, cn as mainReviewRole, dn as renderNative, fn as createSessionPreparation, gn as createDetectionSummary, in as nativeSourceIdentitySchema, ir as isProcessingCode, j as bDuplicateShift, jn as nativeField, k as bBindingCap, kn as redactionImplementationVersion, ln as reviewRoles, nr as ProcessingError, o as reviewDigest, on as processNativeRecord, pn as bindInspection, qt as familySelected, rr as fail$1, sn as projectNativeReviewInput, tr as defaultDetectionLimits, un as createSentenceContext, vn as walkNativeFields, wn as projectNativeRecord, x as createBAnalysisUnits, zn as buildPlan } from "./locate-U3-nkird.mjs";
|
|
2
2
|
import { t as createZstdFrameCheck } from "./frame-waS5FnN5.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { An as bContainment, Dt as metadataProcessingVersion, F as withSourceEvidence, I as agentSetupKey, Mr as agentSourceSchema, P as sourceIdentityEvidence, Pn as bWordBounded, ai as sourceChangePolicy, fi as staticCatalogRef, it as defaultAgentSetupInclusion, jn as bExceptionRanges, jr as agentSourcePathSegment, rt as classifyAgentSetup, si as approvedTreatmentSchema, ur as resolveSourceSelection } from "./src-DNn7SifS.mjs";
|
|
4
4
|
import { constants } from "node:fs";
|
|
5
5
|
import { link, lstat, mkdir, open, readFile, readdir, realpath, rm, rmdir, stat, unlink } from "node:fs/promises";
|
|
6
6
|
import { execFile, fork, spawn } from "node:child_process";
|
|
@@ -16,6 +16,7 @@ import "node:perf_hooks";
|
|
|
16
16
|
import { availableParallelism, platform, tmpdir, totalmem } from "node:os";
|
|
17
17
|
import { pipeline } from "node:stream/promises";
|
|
18
18
|
import { constants as constants$1, createZstdDecompress } from "node:zlib";
|
|
19
|
+
import { parse } from "@decimalturn/toml-patch";
|
|
19
20
|
//#region packages/file-privacy/src/windows/descriptor.ts
|
|
20
21
|
const system = "S-1-5-18";
|
|
21
22
|
const administrators = "S-1-5-32-544";
|
|
@@ -678,10 +679,16 @@ const chooseFinal = async (directory, start = 0) => {
|
|
|
678
679
|
}
|
|
679
680
|
return fail("ARTIFACT_LIMIT");
|
|
680
681
|
};
|
|
681
|
-
|
|
682
|
+
/**
|
|
683
|
+
* `onPath` receives the temporary path before the file exists, so an owner that stops this
|
|
684
|
+
* process mid-call can remove it. On Windows the privacy checks after creation take ACL helper
|
|
685
|
+
* round trips, so a name reported only afterwards could leave an unreported file.
|
|
686
|
+
*/
|
|
687
|
+
const createTemporary = async (options, onPath) => {
|
|
682
688
|
const directory = await outputDirectory(options);
|
|
683
689
|
const finalPath = await chooseFinal(directory);
|
|
684
690
|
const tempPath = join(directory, `.sess-pilot-${randomUUID()}.part`);
|
|
691
|
+
onPath?.(tempPath);
|
|
685
692
|
const handle = await openPrivateFile(tempPath, constants.O_CREAT | constants.O_EXCL | constants.O_RDWR | constants.O_NOFOLLOW, 384);
|
|
686
693
|
try {
|
|
687
694
|
const value = await handle.stat({ bigint: true });
|
|
@@ -729,6 +736,13 @@ const removeSpools = async (directory, temporary) => {
|
|
|
729
736
|
else if (!name.endsWith(".parallel") && value.isFile()) await unlink(path);
|
|
730
737
|
}
|
|
731
738
|
};
|
|
739
|
+
/**
|
|
740
|
+
* Removes the `<temp>.<uuid>.<kind>` spools beside each temporary file a stopped packaging child
|
|
741
|
+
* named (ADR 0228); the child's own cleanup never ran. Other named files are left to their owner.
|
|
742
|
+
*/
|
|
743
|
+
const removeNamedTemporarySpools = async (paths) => {
|
|
744
|
+
for (const path of paths) if (/\.sess-pilot-[a-f0-9-]{36}\.part$/.test(basename(path))) await removeSpools(dirname(path), { tempPath: path });
|
|
745
|
+
};
|
|
732
746
|
//#endregion
|
|
733
747
|
//#region packages/artifact/src/file/reader.ts
|
|
734
748
|
var FileReader = class extends Reader {
|
|
@@ -818,9 +832,9 @@ const readMetadata = async (entry, signal, maximumBytes = metadataLimitBytes) =>
|
|
|
818
832
|
};
|
|
819
833
|
//#endregion
|
|
820
834
|
//#region packages/artifact/src/manifest/fields.ts
|
|
821
|
-
const isRecord$
|
|
822
|
-
const record = (value) => {
|
|
823
|
-
if (!isRecord$
|
|
835
|
+
const isRecord$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
836
|
+
const record$1 = (value) => {
|
|
837
|
+
if (!isRecord$2(value)) return fail("ARTIFACT_INVALID_MANIFEST");
|
|
824
838
|
return value;
|
|
825
839
|
};
|
|
826
840
|
const string = (value) => {
|
|
@@ -847,7 +861,7 @@ const keys = (value, expected) => {
|
|
|
847
861
|
//#endregion
|
|
848
862
|
//#region packages/artifact/src/manifest/parse.ts
|
|
849
863
|
const parseCounts = (value) => {
|
|
850
|
-
const item = record(value);
|
|
864
|
+
const item = record$1(value);
|
|
851
865
|
keys(item, [
|
|
852
866
|
"workspaces",
|
|
853
867
|
"sessions",
|
|
@@ -1073,7 +1087,7 @@ const nativeId = (value) => {
|
|
|
1073
1087
|
};
|
|
1074
1088
|
const nullableId = (value) => value === null ? null : nativeId(value);
|
|
1075
1089
|
const parsePosition = (value) => {
|
|
1076
|
-
const item = record(value);
|
|
1090
|
+
const item = record$1(value);
|
|
1077
1091
|
keys(item, ["kind", "value"]);
|
|
1078
1092
|
const kind = item["kind"];
|
|
1079
1093
|
if (kind === "unknown" && item["value"] === null) return {
|
|
@@ -1102,7 +1116,7 @@ const parsePosition = (value) => {
|
|
|
1102
1116
|
return fail("ARTIFACT_INVALID_MANIFEST");
|
|
1103
1117
|
};
|
|
1104
1118
|
const parseFork = (value) => {
|
|
1105
|
-
const item = record(value);
|
|
1119
|
+
const item = record$1(value);
|
|
1106
1120
|
keys(item, ["parentSessionId", "position"]);
|
|
1107
1121
|
return {
|
|
1108
1122
|
parentSessionId: nativeId(item["parentSessionId"]),
|
|
@@ -1111,7 +1125,7 @@ const parseFork = (value) => {
|
|
|
1111
1125
|
};
|
|
1112
1126
|
/** Relationships are explicit native metadata; names never determine roles. */
|
|
1113
1127
|
const parseNativeIdentity = (value) => {
|
|
1114
|
-
const item = record(value);
|
|
1128
|
+
const item = record$1(value);
|
|
1115
1129
|
keys(item, [
|
|
1116
1130
|
"role",
|
|
1117
1131
|
"sessionId",
|
|
@@ -1130,7 +1144,7 @@ const parseNativeIdentity = (value) => {
|
|
|
1130
1144
|
};
|
|
1131
1145
|
};
|
|
1132
1146
|
const parseNativeRelation = (value) => {
|
|
1133
|
-
const item = record(value);
|
|
1147
|
+
const item = record$1(value);
|
|
1134
1148
|
const kind = item["kind"];
|
|
1135
1149
|
if (kind === "call" || kind === "result") {
|
|
1136
1150
|
keys(item, ["kind", "callId"]);
|
|
@@ -1415,7 +1429,7 @@ function parseWorkspaceConfiguration(input, expectedDigest) {
|
|
|
1415
1429
|
/** The talent-platform `challengeIdSchema`; an identifier outside it would fail the upload. */
|
|
1416
1430
|
const challengeIdPattern = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/;
|
|
1417
1431
|
const markerLimitBytes = 4096;
|
|
1418
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1432
|
+
const isRecord$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1419
1433
|
const isAbsent = (error) => error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
1420
1434
|
/** One fixed line; never the path, the file content or the native error message. */
|
|
1421
1435
|
function ignored(code) {
|
|
@@ -1468,7 +1482,7 @@ async function readChallengeId(workspacePath, signal) {
|
|
|
1468
1482
|
} catch {
|
|
1469
1483
|
return ignored("CHALLENGE_MARKER_INVALID");
|
|
1470
1484
|
}
|
|
1471
|
-
if (!isRecord(marker)) return ignored("CHALLENGE_MARKER_INVALID");
|
|
1485
|
+
if (!isRecord$1(marker)) return ignored("CHALLENGE_MARKER_INVALID");
|
|
1472
1486
|
const challengeId = marker["challengeId"];
|
|
1473
1487
|
return marker["version"] === 1 && typeof challengeId === "string" && challengeIdPattern.test(challengeId) ? challengeId : ignored("CHALLENGE_MARKER_INVALID");
|
|
1474
1488
|
}
|
|
@@ -1477,7 +1491,7 @@ async function readChallengeId(workspacePath, signal) {
|
|
|
1477
1491
|
const uuid$3 = /^[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}$/;
|
|
1478
1492
|
const digest$6 = /^[a-f0-9]{64}$/;
|
|
1479
1493
|
function parseConfiguredWork(value) {
|
|
1480
|
-
const item = record(value);
|
|
1494
|
+
const item = record$1(value);
|
|
1481
1495
|
keys(item, [
|
|
1482
1496
|
"id",
|
|
1483
1497
|
"metadataPath",
|
|
@@ -1493,7 +1507,7 @@ function parseConfiguredWork(value) {
|
|
|
1493
1507
|
};
|
|
1494
1508
|
}
|
|
1495
1509
|
function parseConfiguredSourceWorkspace(value) {
|
|
1496
|
-
const item = record(value);
|
|
1510
|
+
const item = record$1(value);
|
|
1497
1511
|
keys(item, [
|
|
1498
1512
|
"id",
|
|
1499
1513
|
"metadataPath",
|
|
@@ -1513,7 +1527,7 @@ function parseConfiguredSourceWorkspace(value) {
|
|
|
1513
1527
|
};
|
|
1514
1528
|
}
|
|
1515
1529
|
function parseConfiguredWorkMetadata(value) {
|
|
1516
|
-
const item = record(value);
|
|
1530
|
+
const item = record$1(value);
|
|
1517
1531
|
keys(item, [
|
|
1518
1532
|
"version",
|
|
1519
1533
|
"id",
|
|
@@ -1532,7 +1546,7 @@ function parseConfiguredWorkMetadata(value) {
|
|
|
1532
1546
|
}
|
|
1533
1547
|
/** Physical hashes are never synthesized from a logical Work identity. */
|
|
1534
1548
|
function validateConfiguredSourceMetadata(value, expected) {
|
|
1535
|
-
const item = record(value);
|
|
1549
|
+
const item = record$1(value);
|
|
1536
1550
|
keys(item, [
|
|
1537
1551
|
"version",
|
|
1538
1552
|
"title",
|
|
@@ -1563,7 +1577,7 @@ function digestString(value) {
|
|
|
1563
1577
|
return result;
|
|
1564
1578
|
}
|
|
1565
1579
|
function parseConfiguredEntry(value) {
|
|
1566
|
-
const item = record(value);
|
|
1580
|
+
const item = record$1(value);
|
|
1567
1581
|
keys(item, [
|
|
1568
1582
|
"entryPath",
|
|
1569
1583
|
"kind",
|
|
@@ -1584,7 +1598,7 @@ function parseConfiguredEntry(value) {
|
|
|
1584
1598
|
};
|
|
1585
1599
|
}
|
|
1586
1600
|
function parseConfiguredPart(value) {
|
|
1587
|
-
const item = record(value);
|
|
1601
|
+
const item = record$1(value);
|
|
1588
1602
|
keys(item, [
|
|
1589
1603
|
"id",
|
|
1590
1604
|
"sourceId",
|
|
@@ -1596,7 +1610,7 @@ function parseConfiguredPart(value) {
|
|
|
1596
1610
|
"retainedRecordCount",
|
|
1597
1611
|
"equivalence"
|
|
1598
1612
|
]);
|
|
1599
|
-
const source = record(item["source"]);
|
|
1613
|
+
const source = record$1(item["source"]);
|
|
1600
1614
|
keys(source, [
|
|
1601
1615
|
"representation",
|
|
1602
1616
|
"byteLength",
|
|
@@ -1621,7 +1635,7 @@ function parseConfiguredPart(value) {
|
|
|
1621
1635
|
};
|
|
1622
1636
|
}
|
|
1623
1637
|
function session$1(value) {
|
|
1624
|
-
const item = record(value);
|
|
1638
|
+
const item = record$1(value);
|
|
1625
1639
|
keys(item, [
|
|
1626
1640
|
"id",
|
|
1627
1641
|
"workspaceId",
|
|
@@ -1644,7 +1658,7 @@ function session$1(value) {
|
|
|
1644
1658
|
};
|
|
1645
1659
|
}
|
|
1646
1660
|
function exclusion$1(value) {
|
|
1647
|
-
const item = record(value);
|
|
1661
|
+
const item = record$1(value);
|
|
1648
1662
|
keys(item, [
|
|
1649
1663
|
"sessionId",
|
|
1650
1664
|
"sourceId",
|
|
@@ -1659,7 +1673,7 @@ function exclusion$1(value) {
|
|
|
1659
1673
|
};
|
|
1660
1674
|
}
|
|
1661
1675
|
function parseConfiguredManifest(text) {
|
|
1662
|
-
const item = record(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
1676
|
+
const item = record$1(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
1663
1677
|
keys(item, [
|
|
1664
1678
|
"format",
|
|
1665
1679
|
"formatVersion",
|
|
@@ -1686,11 +1700,11 @@ function parseConfiguredManifest(text) {
|
|
|
1686
1700
|
]);
|
|
1687
1701
|
const challengeId = item["challengeId"] === void 0 ? null : string(item["challengeId"]);
|
|
1688
1702
|
if (challengeId !== null && !challengeIdPattern.test(challengeId)) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1689
|
-
const producer = record(item["producer"]);
|
|
1703
|
+
const producer = record$1(item["producer"]);
|
|
1690
1704
|
keys(producer, ["name", "version"]);
|
|
1691
|
-
const adapters = record(item["adapterVersions"]);
|
|
1705
|
+
const adapters = record$1(item["adapterVersions"]);
|
|
1692
1706
|
keys(adapters, ["claude", "codex"]);
|
|
1693
|
-
const setup = record(item["agentSetup"]);
|
|
1707
|
+
const setup = record$1(item["agentSetup"]);
|
|
1694
1708
|
keys(setup, ["version", "files"]);
|
|
1695
1709
|
const configurationDigest = digestString(item["configurationDigest"]);
|
|
1696
1710
|
return {
|
|
@@ -1717,7 +1731,7 @@ function parseConfiguredManifest(text) {
|
|
|
1717
1731
|
configurationDigest,
|
|
1718
1732
|
configuration: parseWorkspaceConfiguration(item["configuration"], configurationDigest),
|
|
1719
1733
|
sourceScope: array(item["sourceScope"], (value) => {
|
|
1720
|
-
const source = record(value);
|
|
1734
|
+
const source = record$1(value);
|
|
1721
1735
|
keys(source, ["sessionId", "sourceId"]);
|
|
1722
1736
|
return {
|
|
1723
1737
|
sessionId: string(source["sessionId"]),
|
|
@@ -1729,7 +1743,7 @@ function parseConfiguredManifest(text) {
|
|
|
1729
1743
|
agentSetup: {
|
|
1730
1744
|
version: literal(setup["version"], 1),
|
|
1731
1745
|
files: array(setup["files"], (value) => {
|
|
1732
|
-
const file = record(value);
|
|
1746
|
+
const file = record$1(value);
|
|
1733
1747
|
keys(file, [
|
|
1734
1748
|
"id",
|
|
1735
1749
|
"category",
|
|
@@ -1845,7 +1859,7 @@ const digestPattern = /^[a-f0-9]{64}$/;
|
|
|
1845
1859
|
const sessionIdPattern = /^s[0-9]{6}$/;
|
|
1846
1860
|
const sourceIdPattern = /^src[0-9]{6}$/;
|
|
1847
1861
|
function description(value) {
|
|
1848
|
-
const item = record(value);
|
|
1862
|
+
const item = record$1(value);
|
|
1849
1863
|
const kind = item["kind"];
|
|
1850
1864
|
const representation = item["representation"];
|
|
1851
1865
|
if (kind !== "data" && kind !== "facts" && kind !== "metadata" && kind !== "agent-setup" || representation !== "json" && representation !== "jsonl" && representation !== "jsonl.zst") return fail("ARTIFACT_INVALID_MANIFEST");
|
|
@@ -1861,16 +1875,16 @@ function description(value) {
|
|
|
1861
1875
|
};
|
|
1862
1876
|
}
|
|
1863
1877
|
function checkWorkspaceManifest(text, entries, bundleId, expectedPathHash, summary) {
|
|
1864
|
-
const manifest = record(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
1878
|
+
const manifest = record$1(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
1865
1879
|
const treatment = manifest["contentTreatment"];
|
|
1866
1880
|
const configured = treatment === "configured";
|
|
1867
1881
|
const configuredManifest = configured ? parseConfiguredManifest(text) : null;
|
|
1868
1882
|
if (configuredManifest) validateConfiguredManifest(configuredManifest);
|
|
1869
|
-
const sourceWorkspaces = configuredManifest?.sourceWorkspaces ?? [record(manifest["workspace"])];
|
|
1883
|
+
const sourceWorkspaces = configuredManifest?.sourceWorkspaces ?? [record$1(manifest["workspace"])];
|
|
1870
1884
|
const workspaceIds = new Set(sourceWorkspaces.map((workspace) => string(workspace["id"])));
|
|
1871
1885
|
if (literal(manifest["format"], "sess-pilot-workspace-bundle") !== "sess-pilot-workspace-bundle" || manifest["formatVersion"] !== (configured ? 5 : 3) || string(manifest["bundleId"]) !== bundleId || summary.bundleId !== bundleId || treatment !== "original" && treatment !== "legacy-plan" && treatment !== "configured") fail("ARTIFACT_INVALID_MANIFEST");
|
|
1872
1886
|
if (!configured) {
|
|
1873
|
-
const workspace = record(manifest["workspace"]);
|
|
1887
|
+
const workspace = record$1(manifest["workspace"]);
|
|
1874
1888
|
keys(workspace, [
|
|
1875
1889
|
"id",
|
|
1876
1890
|
"metadataPath",
|
|
@@ -1880,7 +1894,7 @@ function checkWorkspaceManifest(text, entries, bundleId, expectedPathHash, summa
|
|
|
1880
1894
|
if (workspace["id"] !== "w000001" || pathHash !== null && !digestPattern.test(pathHash) || pathHash !== expectedPathHash || workspace["metadataPath"] !== "workspace/metadata.json") fail("ARTIFACT_INVALID_MANIFEST");
|
|
1881
1895
|
} else if ((sourceWorkspaces.length === 1 ? sourceWorkspaces[0]?.["pathHash"] : null) !== expectedPathHash) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1882
1896
|
const counts = parseCounts(manifest["counts"]);
|
|
1883
|
-
const sessions = array(manifest["sessions"], record);
|
|
1897
|
+
const sessions = array(manifest["sessions"], record$1);
|
|
1884
1898
|
if (counts.workspaces !== sourceWorkspaces.length || sessions.length === 0 || sessions.length !== summary.sessions.length || !countsEqual(counts, summary.counts)) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1885
1899
|
const descriptions = /* @__PURE__ */ new Map();
|
|
1886
1900
|
for (const item of array(manifest["entries"], description)) {
|
|
@@ -1899,10 +1913,10 @@ function checkWorkspaceManifest(text, entries, bundleId, expectedPathHash, summa
|
|
|
1899
1913
|
for (const workspace of configuredManifest.sourceWorkspaces) requireEntry(workspace.metadataPath, "metadata", "json");
|
|
1900
1914
|
} else requireEntry("workspace/metadata.json", "metadata", "json");
|
|
1901
1915
|
if (configured) {
|
|
1902
|
-
const setup = record(manifest["agentSetup"]);
|
|
1916
|
+
const setup = record$1(manifest["agentSetup"]);
|
|
1903
1917
|
keys(setup, ["version", "files"]);
|
|
1904
1918
|
if (setup["version"] !== 1) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1905
|
-
for (const [index, value] of array(setup["files"], record).entries()) {
|
|
1919
|
+
for (const [index, value] of array(setup["files"], record$1).entries()) {
|
|
1906
1920
|
keys(value, [
|
|
1907
1921
|
"id",
|
|
1908
1922
|
"category",
|
|
@@ -1939,7 +1953,7 @@ function checkWorkspaceManifest(text, entries, bundleId, expectedPathHash, summa
|
|
|
1939
1953
|
if (rawSession["metadataPath"] !== metadataPath) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1940
1954
|
requireEntry(metadataPath, "metadata", "json");
|
|
1941
1955
|
}
|
|
1942
|
-
const sessionParts = array(rawSession["parts"], record);
|
|
1956
|
+
const sessionParts = array(rawSession["parts"], record$1);
|
|
1943
1957
|
if (sessionParts.length === 0 || sessionParts.length !== expected.sources.length) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1944
1958
|
for (const [partIndex, part] of sessionParts.entries()) {
|
|
1945
1959
|
const source = expected.sources[partIndex] ?? fail("ARTIFACT_INVALID_MANIFEST");
|
|
@@ -1949,7 +1963,7 @@ function checkWorkspaceManifest(text, entries, bundleId, expectedPathHash, summa
|
|
|
1949
1963
|
admitted.set(sourceId, id);
|
|
1950
1964
|
if (configured) {
|
|
1951
1965
|
if (source.native === null || !isDeepStrictEqual(parseNativeIdentity(part["native"]), source.native)) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1952
|
-
const sourceFacts = record(part["source"]);
|
|
1966
|
+
const sourceFacts = record$1(part["source"]);
|
|
1953
1967
|
sourceBytes += integer(sourceFacts["byteLength"]);
|
|
1954
1968
|
const data = `sessions/${id}/parts/${partId}.jsonl`;
|
|
1955
1969
|
const facts = `sessions/${id}/facts/${partId}.jsonl`;
|
|
@@ -1964,21 +1978,21 @@ function checkWorkspaceManifest(text, entries, bundleId, expectedPathHash, summa
|
|
|
1964
1978
|
const data = `sessions/${id}/parts/${partId}.${representation}`;
|
|
1965
1979
|
if (part["entryPath"] !== data) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1966
1980
|
requireEntry(data, "data", representation);
|
|
1967
|
-
sourceBytes += part["source"] === void 0 ? integer(part["byteLength"]) : integer(record(part["source"])["byteLength"]);
|
|
1981
|
+
sourceBytes += part["source"] === void 0 ? integer(part["byteLength"]) : integer(record$1(part["source"])["byteLength"]);
|
|
1968
1982
|
}
|
|
1969
1983
|
parts++;
|
|
1970
1984
|
}
|
|
1971
1985
|
}
|
|
1972
1986
|
if (parts !== counts.parts || sourceBytes !== counts.sourceBytes || referenced.size !== descriptions.size) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1973
1987
|
const scope = /* @__PURE__ */ new Map();
|
|
1974
|
-
for (const item of array(manifest["sourceScope"], record)) {
|
|
1988
|
+
for (const item of array(manifest["sourceScope"], record$1)) {
|
|
1975
1989
|
const sourceId = string(item["sourceId"]);
|
|
1976
1990
|
const sessionId = string(item["sessionId"]);
|
|
1977
1991
|
if (!sourceIdPattern.test(sourceId) || !sessionIdPattern.test(sessionId) || scope.has(sourceId)) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1978
1992
|
scope.set(sourceId, sessionId);
|
|
1979
1993
|
}
|
|
1980
1994
|
const excluded = /* @__PURE__ */ new Set();
|
|
1981
|
-
for (const item of array(manifest["exclusions"], record)) {
|
|
1995
|
+
for (const item of array(manifest["exclusions"], record$1)) {
|
|
1982
1996
|
const sourceId = string(item["sourceId"]);
|
|
1983
1997
|
if (scope.get(sourceId) !== item["sessionId"] || excluded.has(sourceId)) fail("ARTIFACT_INVALID_MANIFEST");
|
|
1984
1998
|
excluded.add(sourceId);
|
|
@@ -2052,7 +2066,7 @@ async function checkWrittenWorkspaceBundle(path, identity, expectedManifestText,
|
|
|
2052
2066
|
//#endregion
|
|
2053
2067
|
//#region packages/artifact/src/collection/companion.ts
|
|
2054
2068
|
function companionManifest(primaryText, primary, entries) {
|
|
2055
|
-
const manifest = record(strictJson(primaryText, manifestLimitBytes, manifestNodeLimit));
|
|
2069
|
+
const manifest = record$1(strictJson(primaryText, manifestLimitBytes, manifestNodeLimit));
|
|
2056
2070
|
if (manifest["formatVersion"] !== 5 || manifest["companionVersion"] !== 3 || manifest["contentTreatment"] !== "configured") return fail("ARTIFACT_INVALID_MANIFEST");
|
|
2057
2071
|
return JSON.stringify({
|
|
2058
2072
|
format: "sess-pilot-workspace-companion",
|
|
@@ -2067,7 +2081,7 @@ function companionManifest(primaryText, primary, entries) {
|
|
|
2067
2081
|
});
|
|
2068
2082
|
}
|
|
2069
2083
|
function checkCompanionManifest(text, entries, primaryText, primary) {
|
|
2070
|
-
const value = record(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
2084
|
+
const value = record$1(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
2071
2085
|
keys(value, [
|
|
2072
2086
|
"format",
|
|
2073
2087
|
"formatVersion",
|
|
@@ -2079,12 +2093,12 @@ function checkCompanionManifest(text, entries, primaryText, primary) {
|
|
|
2079
2093
|
literal(value["format"], "sess-pilot-workspace-companion");
|
|
2080
2094
|
literal(value["formatVersion"], 1);
|
|
2081
2095
|
literal(value["companionVersion"], 3);
|
|
2082
|
-
const descriptions = array(value["entries"], record);
|
|
2083
|
-
const expected = record(strictJson(companionManifest(primaryText, primary, descriptions), manifestLimitBytes, manifestNodeLimit));
|
|
2096
|
+
const descriptions = array(value["entries"], record$1);
|
|
2097
|
+
const expected = record$1(strictJson(companionManifest(primaryText, primary, descriptions), manifestLimitBytes, manifestNodeLimit));
|
|
2084
2098
|
if (!isDeepStrictEqual(value, expected)) fail("ARTIFACT_INVALID_MANIFEST");
|
|
2085
2099
|
const paths = /* @__PURE__ */ new Set();
|
|
2086
|
-
const primaryManifest = record(strictJson(primaryText, manifestLimitBytes, manifestNodeLimit));
|
|
2087
|
-
const parts = array(primaryManifest["sessions"], record).flatMap((session) => array(session["parts"], record));
|
|
2100
|
+
const primaryManifest = record$1(strictJson(primaryText, manifestLimitBytes, manifestNodeLimit));
|
|
2101
|
+
const parts = array(primaryManifest["sessions"], record$1).flatMap((session) => array(session["parts"], record$1));
|
|
2088
2102
|
for (const part of parts) {
|
|
2089
2103
|
const path = string(part["factsPath"]);
|
|
2090
2104
|
if (paths.has(path)) fail("ARTIFACT_INVALID_MANIFEST");
|
|
@@ -2208,7 +2222,7 @@ const roles = [
|
|
|
2208
2222
|
];
|
|
2209
2223
|
const parseRole = (value) => roles.find((role) => role === value) ?? fail("ARTIFACT_INVALID_MANIFEST");
|
|
2210
2224
|
const parseBody = (value) => {
|
|
2211
|
-
const item = record(value);
|
|
2225
|
+
const item = record$1(value);
|
|
2212
2226
|
keys(item, [
|
|
2213
2227
|
"bodyId",
|
|
2214
2228
|
"fieldId",
|
|
@@ -2258,7 +2272,7 @@ function sampleLocations(bodies, fields, locations) {
|
|
|
2258
2272
|
return synthetic;
|
|
2259
2273
|
}
|
|
2260
2274
|
const measured$1 = (value, parse) => {
|
|
2261
|
-
const item = record(value);
|
|
2275
|
+
const item = record$1(value);
|
|
2262
2276
|
const state = item["state"];
|
|
2263
2277
|
keys(item, [
|
|
2264
2278
|
"state",
|
|
@@ -2282,8 +2296,8 @@ const measured$1 = (value, parse) => {
|
|
|
2282
2296
|
};
|
|
2283
2297
|
return fail("ARTIFACT_INVALID_MANIFEST");
|
|
2284
2298
|
};
|
|
2285
|
-
const patch$
|
|
2286
|
-
const item = record(value);
|
|
2299
|
+
const patch$2 = (value) => {
|
|
2300
|
+
const item = record$1(value);
|
|
2287
2301
|
keys(item, [
|
|
2288
2302
|
"grammarVersion",
|
|
2289
2303
|
"basis",
|
|
@@ -2302,7 +2316,7 @@ const patch$1 = (value) => {
|
|
|
2302
2316
|
};
|
|
2303
2317
|
};
|
|
2304
2318
|
const parseFacts = (value) => {
|
|
2305
|
-
const item = record(value);
|
|
2319
|
+
const item = record$1(value);
|
|
2306
2320
|
const optional = [
|
|
2307
2321
|
"decodedUtf8Bytes",
|
|
2308
2322
|
"logicalLines",
|
|
@@ -2325,7 +2339,7 @@ const parseFacts = (value) => {
|
|
|
2325
2339
|
extractorVersion: literal(item["extractorVersion"], "native-retention-v1"),
|
|
2326
2340
|
...Object.hasOwn(item, "decodedUtf8Bytes") ? { decodedUtf8Bytes: measured$1(item["decodedUtf8Bytes"], integer) } : {},
|
|
2327
2341
|
...Object.hasOwn(item, "logicalLines") ? { logicalLines: measured$1(item["logicalLines"], integer) } : {},
|
|
2328
|
-
...Object.hasOwn(item, "patchDelta") ? { patchDelta: measured$1(item["patchDelta"], patch$
|
|
2342
|
+
...Object.hasOwn(item, "patchDelta") ? { patchDelta: measured$1(item["patchDelta"], patch$2) } : {}
|
|
2329
2343
|
};
|
|
2330
2344
|
};
|
|
2331
2345
|
/** IDs address original nodes, never mutable output positions. */
|
|
@@ -2630,7 +2644,7 @@ async function verifyConfiguredPart(part, entries, descriptions, signal) {
|
|
|
2630
2644
|
//#region packages/artifact/src/read/configured/workspace.ts
|
|
2631
2645
|
/** Public primary facts are parsed independently; no source file is opened. */
|
|
2632
2646
|
function workspaceSummary(text) {
|
|
2633
|
-
const manifest = record(parseConfiguredManifest(text));
|
|
2647
|
+
const manifest = record$1(parseConfiguredManifest(text));
|
|
2634
2648
|
if (manifest["contentTreatment"] !== "configured" || manifest["formatVersion"] !== 5 || manifest["companionVersion"] !== 3) return fail("ARTIFACT_INVALID_MANIFEST");
|
|
2635
2649
|
return {
|
|
2636
2650
|
format: "sess-pilot-workspace-summary",
|
|
@@ -2638,7 +2652,7 @@ function workspaceSummary(text) {
|
|
|
2638
2652
|
bundleId: string(manifest["bundleId"]),
|
|
2639
2653
|
counts: parseCounts(manifest["counts"]),
|
|
2640
2654
|
sessions: array(manifest["sessions"], (value) => {
|
|
2641
|
-
const session = record(value);
|
|
2655
|
+
const session = record$1(value);
|
|
2642
2656
|
const harness = session["harness"];
|
|
2643
2657
|
if (harness !== "claude" && harness !== "codex") return fail("ARTIFACT_INVALID_MANIFEST");
|
|
2644
2658
|
return {
|
|
@@ -2668,7 +2682,7 @@ async function readPrimaryMetadata(primaryEntries, primaryText, signal, only) {
|
|
|
2668
2682
|
if (description.representation !== "jsonl" && (!only || only.has(description.entryPath))) {
|
|
2669
2683
|
const text = await readMetadata(entry, signal);
|
|
2670
2684
|
if (createHash("sha256").update(text).digest("hex") !== description.sha256) fail("ARTIFACT_INVALID_ARCHIVE");
|
|
2671
|
-
const metadata = record(strictJson(text, metadataLimitBytes));
|
|
2685
|
+
const metadata = record$1(strictJson(text, metadataLimitBytes));
|
|
2672
2686
|
if (description.entryPath === manifest.work.metadataPath) {
|
|
2673
2687
|
if (parseConfiguredWorkMetadata(metadata).id !== manifest.work.id) fail("ARTIFACT_INVALID_MANIFEST");
|
|
2674
2688
|
}
|
|
@@ -2677,7 +2691,7 @@ async function readPrimaryMetadata(primaryEntries, primaryText, signal, only) {
|
|
|
2677
2691
|
if (description.entryPath.startsWith("sessions/")) {
|
|
2678
2692
|
keys(metadata, ["version", "session"]);
|
|
2679
2693
|
if (metadata["version"] !== 3) fail("ARTIFACT_INVALID_MANIFEST");
|
|
2680
|
-
const session = record(metadata["session"]);
|
|
2694
|
+
const session = record$1(metadata["session"]);
|
|
2681
2695
|
keys(session, [
|
|
2682
2696
|
"id",
|
|
2683
2697
|
"harness",
|
|
@@ -2702,11 +2716,11 @@ async function readPrimaryMetadata(primaryEntries, primaryText, signal, only) {
|
|
|
2702
2716
|
async function readConfiguredWorkspacePair(primaryEntries, primaryText, companionEntries, companionText, primary, signal, only) {
|
|
2703
2717
|
const { summary } = await readPrimaryMetadata(primaryEntries, primaryText, signal, only);
|
|
2704
2718
|
checkCompanionManifest(companionText, companionEntries, primaryText, primary);
|
|
2705
|
-
const manifest = record(strictJson(primaryText, manifestLimitBytes, manifestNodeLimit));
|
|
2706
|
-
const companion = record(strictJson(companionText, manifestLimitBytes, manifestNodeLimit));
|
|
2719
|
+
const manifest = record$1(strictJson(primaryText, manifestLimitBytes, manifestNodeLimit));
|
|
2720
|
+
const companion = record$1(strictJson(companionText, manifestLimitBytes, manifestNodeLimit));
|
|
2707
2721
|
const descriptions = new Map([...array(manifest["entries"], parseConfiguredEntry), ...array(companion["entries"], parseConfiguredEntry)].map((entry) => [entry.entryPath, entry]));
|
|
2708
2722
|
const entries = new Map([...primaryEntries, ...[...companionEntries].filter(([path]) => path !== "manifest.json")]);
|
|
2709
|
-
for (const session of array(manifest["sessions"], record)) for (const part of array(session["parts"], parseConfiguredPart)) if (!only || only.has(part.dataPath)) await verifyConfiguredPart(part, entries, descriptions, signal);
|
|
2723
|
+
for (const session of array(manifest["sessions"], record$1)) for (const part of array(session["parts"], parseConfiguredPart)) if (!only || only.has(part.dataPath)) await verifyConfiguredPart(part, entries, descriptions, signal);
|
|
2710
2724
|
return summary;
|
|
2711
2725
|
}
|
|
2712
2726
|
//#endregion
|
|
@@ -3294,6 +3308,7 @@ async function createSessionArchiveSpool(temporary, signal, options = {}) {
|
|
|
3294
3308
|
checkAbort(signal);
|
|
3295
3309
|
const path = options.directory === void 0 ? `${temporary.tempPath}.${randomUUID()}.session` : `${options.directory}/${randomUUID()}.session`;
|
|
3296
3310
|
let handle;
|
|
3311
|
+
if (options.keepPath === true) options.onPath?.(path);
|
|
3297
3312
|
try {
|
|
3298
3313
|
handle = await (options.directory === void 0 ? openPrivateFile : open)(path, constants.O_CREAT | constants.O_EXCL | constants.O_RDWR | constants.O_NOFOLLOW, 384);
|
|
3299
3314
|
if (options.keepPath !== true) await unlink(path);
|
|
@@ -4715,6 +4730,277 @@ function createInspectionProcessor(processing) {
|
|
|
4715
4730
|
} };
|
|
4716
4731
|
}
|
|
4717
4732
|
//#endregion
|
|
4733
|
+
//#region packages/artifact/src/agent-sources/model.ts
|
|
4734
|
+
function isRecord(value) {
|
|
4735
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4736
|
+
}
|
|
4737
|
+
function record(value) {
|
|
4738
|
+
return isRecord(value) ? value : {};
|
|
4739
|
+
}
|
|
4740
|
+
function publicName(value) {
|
|
4741
|
+
return typeof value === "string" && /^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,199}$/.test(value);
|
|
4742
|
+
}
|
|
4743
|
+
function repository(value) {
|
|
4744
|
+
if (typeof value !== "string") return false;
|
|
4745
|
+
const segments = value.split("/");
|
|
4746
|
+
return segments.length === 2 && segments.every((part) => part.length <= 100 && agentSourcePathSegment(part));
|
|
4747
|
+
}
|
|
4748
|
+
function repoPath(value) {
|
|
4749
|
+
return value.length <= 500 && value.split("/").every(agentSourcePathSegment);
|
|
4750
|
+
}
|
|
4751
|
+
//#endregion
|
|
4752
|
+
//#region packages/artifact/src/agent-sources/mcp.ts
|
|
4753
|
+
/** Only direct npx invocation has npm provenance; never preserve its arguments. */
|
|
4754
|
+
function npmPackage(value) {
|
|
4755
|
+
const entry = record(value);
|
|
4756
|
+
if (entry["command"] !== "npx" || entry["url"] !== void 0 || entry["type"] !== void 0 && entry["type"] !== "stdio") return void 0;
|
|
4757
|
+
const args = entry["args"];
|
|
4758
|
+
if (!Array.isArray(args) || !args.every((arg) => typeof arg === "string")) return void 0;
|
|
4759
|
+
if (args.some((arg) => /registry|userconfig/i.test(arg)) || Object.keys(record(entry["env"])).some((key) => /registry|userconfig/i.test(key))) return void 0;
|
|
4760
|
+
let position = 0;
|
|
4761
|
+
while (args[position] === "-y" || args[position] === "--yes" || args[position] === "--no") position++;
|
|
4762
|
+
const candidate = args[position];
|
|
4763
|
+
if (candidate === void 0) return void 0;
|
|
4764
|
+
const name = /^((?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*)(?:@[a-zA-Z0-9][a-zA-Z0-9._~^*-]*)?$/.exec(candidate)?.[1];
|
|
4765
|
+
return name !== void 0 && name.length <= 214 ? name : void 0;
|
|
4766
|
+
}
|
|
4767
|
+
function mcpCandidates(value, names) {
|
|
4768
|
+
const output = [];
|
|
4769
|
+
for (const [name, entry] of Object.entries(record(value)).slice(0, 500)) {
|
|
4770
|
+
if (!publicName(name) || !names.has(name)) continue;
|
|
4771
|
+
const packageName = npmPackage(entry);
|
|
4772
|
+
if (packageName) output.push({
|
|
4773
|
+
kind: "mcp",
|
|
4774
|
+
name,
|
|
4775
|
+
source: {
|
|
4776
|
+
type: "npm",
|
|
4777
|
+
package: packageName
|
|
4778
|
+
}
|
|
4779
|
+
});
|
|
4780
|
+
}
|
|
4781
|
+
return output;
|
|
4782
|
+
}
|
|
4783
|
+
//#endregion
|
|
4784
|
+
//#region packages/artifact/src/agent-sources/read.ts
|
|
4785
|
+
/** Optional enrichment treats missing, malformed and unreadable config as omissions. */
|
|
4786
|
+
async function readText(path) {
|
|
4787
|
+
try {
|
|
4788
|
+
const file = await open(path, constants.O_RDONLY | constants.O_NONBLOCK);
|
|
4789
|
+
try {
|
|
4790
|
+
const info = await file.stat();
|
|
4791
|
+
if (!info.isFile() || info.size > 1048576) return void 0;
|
|
4792
|
+
const buffer = Buffer.alloc(1048577);
|
|
4793
|
+
const { bytesRead } = await file.read(buffer, 0, buffer.length, 0);
|
|
4794
|
+
return bytesRead <= 1048576 ? buffer.subarray(0, bytesRead).toString("utf8") : void 0;
|
|
4795
|
+
} finally {
|
|
4796
|
+
await file.close();
|
|
4797
|
+
}
|
|
4798
|
+
} catch {
|
|
4799
|
+
return;
|
|
4800
|
+
}
|
|
4801
|
+
}
|
|
4802
|
+
async function readJson(path) {
|
|
4803
|
+
const text = await readText(path);
|
|
4804
|
+
if (text === void 0) return void 0;
|
|
4805
|
+
try {
|
|
4806
|
+
return JSON.parse(text);
|
|
4807
|
+
} catch {
|
|
4808
|
+
return;
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
//#endregion
|
|
4812
|
+
//#region packages/artifact/src/agent-sources/plugins.ts
|
|
4813
|
+
async function skillsAt(root) {
|
|
4814
|
+
try {
|
|
4815
|
+
const entries = await readdir(join(root, "skills"), { withFileTypes: true });
|
|
4816
|
+
const result = [];
|
|
4817
|
+
for (const entry of entries.slice(0, 500)) {
|
|
4818
|
+
if (!entry.isDirectory() || !repoPath(entry.name)) continue;
|
|
4819
|
+
const path = `skills/${entry.name}/SKILL.md`;
|
|
4820
|
+
const text = await readText(join(root, path));
|
|
4821
|
+
const frontmatter = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text ?? "")?.[1];
|
|
4822
|
+
const name = /^name:\s*["']?([a-zA-Z0-9][a-zA-Z0-9_.:-]*)["']?\s*$/m.exec(frontmatter ?? "")?.[1];
|
|
4823
|
+
if (name && publicName(name)) result.push({
|
|
4824
|
+
name,
|
|
4825
|
+
path
|
|
4826
|
+
});
|
|
4827
|
+
}
|
|
4828
|
+
return result;
|
|
4829
|
+
} catch {
|
|
4830
|
+
return [];
|
|
4831
|
+
}
|
|
4832
|
+
}
|
|
4833
|
+
async function pluginCandidates(home, workspacePath, skills, mcps) {
|
|
4834
|
+
const base = join(home, ".claude", "plugins");
|
|
4835
|
+
const installed = record(record(await readJson(join(base, "installed_plugins.json")))["plugins"]);
|
|
4836
|
+
const marketplaces = record(await readJson(join(base, "known_marketplaces.json")));
|
|
4837
|
+
const personalAndProject = new Set((await Promise.all([skillsAt(join(home, ".claude")), skillsAt(join(workspacePath, ".claude"))])).flat().map((skill) => skill.name));
|
|
4838
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
4839
|
+
const bareCandidates = /* @__PURE__ */ new Set();
|
|
4840
|
+
const output = [];
|
|
4841
|
+
for (const [key, entries] of Object.entries(installed).slice(0, 128)) {
|
|
4842
|
+
const [plugin, marketplace, extra] = key.split("@");
|
|
4843
|
+
if (!plugin || !marketplace || extra !== void 0 || !publicName(plugin)) continue;
|
|
4844
|
+
const market = record(marketplaces[marketplace]);
|
|
4845
|
+
const marketSource = record(market["source"]);
|
|
4846
|
+
const location = market["installLocation"];
|
|
4847
|
+
const catalog = typeof location === "string" ? record(await readJson(join(location, ".claude-plugin", "marketplace.json")))["plugins"] : void 0;
|
|
4848
|
+
const catalogEntry = Array.isArray(catalog) ? catalog.find((item) => record(item)["name"] === plugin) : void 0;
|
|
4849
|
+
const descriptor = record(catalogEntry);
|
|
4850
|
+
const source = record(descriptor["source"]);
|
|
4851
|
+
const relativeSource = descriptor["source"];
|
|
4852
|
+
const prefix = typeof relativeSource === "string" && relativeSource.startsWith("./") && repoPath(relativeSource.slice(2)) ? relativeSource.slice(2) : void 0;
|
|
4853
|
+
const repo = source["source"] === "github" ? source["repo"] : catalogEntry !== void 0 && (relativeSource === void 0 || prefix !== void 0) && (marketSource["source"] === void 0 || marketSource["source"] === "github") ? marketSource["repo"] : void 0;
|
|
4854
|
+
if (!Array.isArray(entries)) continue;
|
|
4855
|
+
const rank = (value) => {
|
|
4856
|
+
const entry = record(value);
|
|
4857
|
+
const scope = entry["scope"];
|
|
4858
|
+
if (scope === "local" || scope === "project") {
|
|
4859
|
+
const projectPath = entry["projectPath"];
|
|
4860
|
+
if (typeof projectPath !== "string" || resolve(projectPath) !== resolve(workspacePath)) return -1;
|
|
4861
|
+
return scope === "local" ? 3 : 2;
|
|
4862
|
+
}
|
|
4863
|
+
return scope === void 0 || scope === "user" ? 1 : -1;
|
|
4864
|
+
};
|
|
4865
|
+
const selected = entries.slice(0, 8).filter((entry) => rank(entry) >= 0).sort((left, right) => rank(right) - rank(left)).slice(0, 1);
|
|
4866
|
+
for (const raw of selected) {
|
|
4867
|
+
const entry = record(raw);
|
|
4868
|
+
const root = entry["installPath"];
|
|
4869
|
+
if (typeof root !== "string") continue;
|
|
4870
|
+
const pluginMcp = record(await readJson(join(root, ".mcp.json")));
|
|
4871
|
+
const servers = record(pluginMcp["mcpServers"] ?? pluginMcp);
|
|
4872
|
+
output.push(...mcpCandidates(servers, mcps));
|
|
4873
|
+
for (const [server, configuration] of Object.entries(servers).slice(0, 500)) {
|
|
4874
|
+
const alias = `plugin_${plugin}_${server}`;
|
|
4875
|
+
if (mcps.has(alias)) output.push(...mcpCandidates({ [alias]: configuration }, mcps));
|
|
4876
|
+
}
|
|
4877
|
+
const directSource = record(entry["source"]);
|
|
4878
|
+
const candidateRepo = directSource["source"] === "github" ? directSource["repo"] : entry["source"] === void 0 ? repo : void 0;
|
|
4879
|
+
const installedSkills = await skillsAt(root);
|
|
4880
|
+
for (const skill of installedSkills) {
|
|
4881
|
+
const owners = definitions.get(skill.name) ?? /* @__PURE__ */ new Set();
|
|
4882
|
+
owners.add(key);
|
|
4883
|
+
definitions.set(skill.name, owners);
|
|
4884
|
+
}
|
|
4885
|
+
if (!repository(candidateRepo)) continue;
|
|
4886
|
+
const commit = entry["gitCommitSha"];
|
|
4887
|
+
for (const skill of installedSkills) for (const name of [`${plugin}:${skill.name}`, skill.name]) {
|
|
4888
|
+
if (!skills.has(name)) continue;
|
|
4889
|
+
const path = directSource["source"] === "github" || source["source"] === "github" ? skill.path : prefix ? `${prefix}/${skill.path}` : void 0;
|
|
4890
|
+
const candidate = {
|
|
4891
|
+
kind: "skill",
|
|
4892
|
+
name,
|
|
4893
|
+
source: {
|
|
4894
|
+
type: "github",
|
|
4895
|
+
repo: candidateRepo,
|
|
4896
|
+
...path === void 0 ? {} : { path },
|
|
4897
|
+
...typeof commit === "string" && /^[a-fA-F0-9]{40}$/.test(commit) ? { commit } : {}
|
|
4898
|
+
}
|
|
4899
|
+
};
|
|
4900
|
+
output.push(candidate);
|
|
4901
|
+
if (name === skill.name) bareCandidates.add(candidate);
|
|
4902
|
+
}
|
|
4903
|
+
}
|
|
4904
|
+
}
|
|
4905
|
+
return output.filter((item) => !bareCandidates.has(item) || definitions.get(item.name)?.size === 1 && !personalAndProject.has(item.name)).slice(0, 500);
|
|
4906
|
+
}
|
|
4907
|
+
//#endregion
|
|
4908
|
+
//#region packages/artifact/src/agent-sources/index.ts
|
|
4909
|
+
/** Collection-time candidates stay local until anonymous upload-time admission. */
|
|
4910
|
+
async function collectAgentSourceCandidates(options) {
|
|
4911
|
+
const skills = new Set(options.skills.slice(0, 500));
|
|
4912
|
+
const mcps = new Set(options.mcps.slice(0, 500));
|
|
4913
|
+
if (skills.size === 0 && mcps.size === 0) return [];
|
|
4914
|
+
const output = [];
|
|
4915
|
+
if (options.harness !== "codex") {
|
|
4916
|
+
const user = record(await readJson(join(options.userHome, ".claude.json")));
|
|
4917
|
+
const project = record(await readJson(join(options.workspacePath, ".mcp.json")));
|
|
4918
|
+
const local = record(record(user["projects"])[options.workspacePath]);
|
|
4919
|
+
const servers = {
|
|
4920
|
+
...record(user["mcpServers"]),
|
|
4921
|
+
...record(project["mcpServers"]),
|
|
4922
|
+
...record(local["mcpServers"])
|
|
4923
|
+
};
|
|
4924
|
+
const plugins = await pluginCandidates(options.userHome, options.workspacePath, skills, mcps);
|
|
4925
|
+
output.push(...plugins.filter((item) => item.kind !== "mcp" || !(item.name in servers)));
|
|
4926
|
+
output.push(...mcpCandidates(servers, mcps));
|
|
4927
|
+
}
|
|
4928
|
+
const toml = options.harness === "claude" ? void 0 : await readText(join(options.userHome, ".codex", "config.toml"));
|
|
4929
|
+
if (toml !== void 0) try {
|
|
4930
|
+
output.push(...mcpCandidates(record(parse(toml))["mcp_servers"], mcps));
|
|
4931
|
+
} catch {}
|
|
4932
|
+
const customRegistry = (await Promise.all([readText(join(options.workspacePath, ".npmrc")), readText(join(options.userHome, ".npmrc"))])).some((text) => text?.split(/\r?\n/u).some((line) => /^\s*(?:@[^:=\s]+:)?registry\s*=/iu.test(line)));
|
|
4933
|
+
const privateTerms = [basename(options.userHome), ...options.customTerms ?? []].map((term) => term.normalize("NFC").toLowerCase()).filter(Boolean);
|
|
4934
|
+
const admitted = output.filter((item) => !(customRegistry && item.source.type === "npm") && ![item.name, ...item.source.type === "github" ? [item.source.repo, item.source.path ?? ""] : [item.source.package]].some((value) => privateTerms.some((term) => value.normalize("NFC").toLowerCase().includes(term))));
|
|
4935
|
+
return [...new Map(admitted.map((item) => [`${item.kind}:${item.name}`, item])).values()].slice(0, 500);
|
|
4936
|
+
}
|
|
4937
|
+
//#endregion
|
|
4938
|
+
//#region packages/artifact/src/configured/session/agent-sources.ts
|
|
4939
|
+
/** Recognized call positions only: arbitrary prose and tool results never establish usage. */
|
|
4940
|
+
function createAgentSourceCollector(harness) {
|
|
4941
|
+
const skills = /* @__PURE__ */ new Set();
|
|
4942
|
+
const mcps = /* @__PURE__ */ new Set();
|
|
4943
|
+
const add = (set, name) => {
|
|
4944
|
+
if (name && set.size < 500 && /^[A-Za-z0-9_][A-Za-z0-9_.:-]{0,199}$/u.test(name)) set.add(name);
|
|
4945
|
+
};
|
|
4946
|
+
const mcp = (name) => {
|
|
4947
|
+
if (!name?.startsWith("mcp__")) return;
|
|
4948
|
+
const server = name.slice(5).split("__")[0];
|
|
4949
|
+
if (server && /^[A-Za-z0-9_-]+$/u.test(server)) add(mcps, server);
|
|
4950
|
+
};
|
|
4951
|
+
return {
|
|
4952
|
+
add(root) {
|
|
4953
|
+
const type = nativeText(nativeField(root, "type"));
|
|
4954
|
+
if (harness === "claude" && type === "assistant") {
|
|
4955
|
+
const message = nativeField(root, "message");
|
|
4956
|
+
const role = nativeText(nativeField(message, "role"));
|
|
4957
|
+
if (role !== void 0 && role !== "assistant") return;
|
|
4958
|
+
for (const item of nativeItems(nativeField(message, "content"))) {
|
|
4959
|
+
if (nativeText(nativeField(item, "type")) !== "tool_use") continue;
|
|
4960
|
+
const name = nativeText(nativeField(item, "name"));
|
|
4961
|
+
if (name === "Skill") add(skills, nativeText(nativeField(nativeField(item, "input"), "skill")));
|
|
4962
|
+
else mcp(name);
|
|
4963
|
+
}
|
|
4964
|
+
}
|
|
4965
|
+
if (harness === "codex") {
|
|
4966
|
+
const payload = nativeField(root, "payload");
|
|
4967
|
+
const payloadType = nativeText(nativeField(payload, "type"));
|
|
4968
|
+
if (type === "response_item" && payloadType === "function_call") {
|
|
4969
|
+
mcp(nativeText(nativeField(payload, "name")));
|
|
4970
|
+
mcp(nativeText(nativeField(payload, "namespace")));
|
|
4971
|
+
}
|
|
4972
|
+
if (type === "event_msg" && payloadType === "mcp_tool_call_begin") add(mcps, nativeText(nativeField(nativeField(payload, "invocation"), "server")));
|
|
4973
|
+
}
|
|
4974
|
+
},
|
|
4975
|
+
names: () => ({
|
|
4976
|
+
skills: [...skills],
|
|
4977
|
+
mcps: [...mcps]
|
|
4978
|
+
})
|
|
4979
|
+
};
|
|
4980
|
+
}
|
|
4981
|
+
async function collectSessionAgentSources(request, names) {
|
|
4982
|
+
const userHome = request.processing.environment.userHome;
|
|
4983
|
+
if (!userHome || !request.workspace.path || names.skills.length === 0 && names.mcps.length === 0) return [];
|
|
4984
|
+
try {
|
|
4985
|
+
const candidates = await collectAgentSourceCandidates({
|
|
4986
|
+
userHome,
|
|
4987
|
+
harness: request.session.harness,
|
|
4988
|
+
customTerms: request.processing.customTerms?.terms ?? [],
|
|
4989
|
+
workspacePath: request.workspace.path,
|
|
4990
|
+
...names
|
|
4991
|
+
});
|
|
4992
|
+
const items = [];
|
|
4993
|
+
for (const candidate of candidates) {
|
|
4994
|
+
const parsed = agentSourceSchema.safeParse(candidate);
|
|
4995
|
+
if (parsed.success) items.push(parsed.data);
|
|
4996
|
+
}
|
|
4997
|
+
return items.slice(0, 500);
|
|
4998
|
+
} catch {
|
|
4999
|
+
console.error("AGENT_SOURCES_COLLECTION_UNAVAILABLE");
|
|
5000
|
+
return [];
|
|
5001
|
+
}
|
|
5002
|
+
}
|
|
5003
|
+
//#endregion
|
|
4718
5004
|
//#region packages/artifact/src/configured/masks/text.ts
|
|
4719
5005
|
/** Generated title input is local metadata, not an asserted location inside a captured native row. */
|
|
4720
5006
|
function titleMasks(input, output) {
|
|
@@ -4914,8 +5200,12 @@ async function prepareConfiguredSession(request) {
|
|
|
4914
5200
|
const metadata = metadataRoot(request, owner.limits);
|
|
4915
5201
|
const gitIdentity = await prepareGit(request, owner.signal, owner.preparation);
|
|
4916
5202
|
const agentSetup = request.collectAgentSetup ? createAgentSetupCollector(request) : void 0;
|
|
5203
|
+
const agentSources = request.collectAgentSetup ? createAgentSourceCollector(request.session.harness) : void 0;
|
|
4917
5204
|
let images = 0;
|
|
4918
|
-
const snapshots = await prepareSources(request, owner, metadata,
|
|
5205
|
+
const snapshots = await prepareSources(request, owner, metadata, (root) => {
|
|
5206
|
+
agentSetup?.add(root);
|
|
5207
|
+
agentSources?.add(root);
|
|
5208
|
+
}, (count) => {
|
|
4919
5209
|
images += count;
|
|
4920
5210
|
});
|
|
4921
5211
|
owner.seal();
|
|
@@ -4982,6 +5272,7 @@ async function prepareConfiguredSession(request) {
|
|
|
4982
5272
|
...processedMetadata.masks === void 0 ? {} : { metadataMasks: processedMetadata.masks },
|
|
4983
5273
|
sources: Object.freeze(sources),
|
|
4984
5274
|
agentSetup: Object.freeze(setup),
|
|
5275
|
+
...agentSources ? { agentSources: await collectSessionAgentSources(request, agentSources.names()) } : {},
|
|
4985
5276
|
images
|
|
4986
5277
|
});
|
|
4987
5278
|
await owner.close();
|
|
@@ -5005,10 +5296,10 @@ async function prepareConfiguredSession(request) {
|
|
|
5005
5296
|
//#region packages/artifact/src/collection/producer/session-metadata.ts
|
|
5006
5297
|
/** Validate the session-only shape already projected before configured processing. */
|
|
5007
5298
|
function sessionMetadata(metadata) {
|
|
5008
|
-
const root = record(strictJson(metadata, metadataLimitBytes));
|
|
5299
|
+
const root = record$1(strictJson(metadata, metadataLimitBytes));
|
|
5009
5300
|
keys(root, ["version", "session"]);
|
|
5010
5301
|
literal(root["version"], 3);
|
|
5011
|
-
const session = record(root["session"]);
|
|
5302
|
+
const session = record$1(root["session"]);
|
|
5012
5303
|
const compact = JSON.stringify({
|
|
5013
5304
|
version: 3,
|
|
5014
5305
|
session
|
|
@@ -5615,7 +5906,7 @@ function boundedHash(value) {
|
|
|
5615
5906
|
return result;
|
|
5616
5907
|
}
|
|
5617
5908
|
function parseIdentityMap(value) {
|
|
5618
|
-
const input = record(value);
|
|
5909
|
+
const input = record$1(value);
|
|
5619
5910
|
keys(input, [
|
|
5620
5911
|
"format",
|
|
5621
5912
|
"formatVersion",
|
|
@@ -5624,7 +5915,7 @@ function parseIdentityMap(value) {
|
|
|
5624
5915
|
]);
|
|
5625
5916
|
const bundleId = string(input["bundleId"]);
|
|
5626
5917
|
validBundleId(bundleId);
|
|
5627
|
-
const workspace = record(input["workspace"]);
|
|
5918
|
+
const workspace = record$1(input["workspace"]);
|
|
5628
5919
|
keys(workspace, [
|
|
5629
5920
|
"path",
|
|
5630
5921
|
"pathHash",
|
|
@@ -5638,7 +5929,7 @@ function parseIdentityMap(value) {
|
|
|
5638
5929
|
if (!Array.isArray(rawRemotes)) return fail("ARTIFACT_INVALID_MANIFEST");
|
|
5639
5930
|
if (rawRemotes.length > maximumRemotes) fail("ARTIFACT_METADATA_LIMIT");
|
|
5640
5931
|
const remotes = rawRemotes.map((entry) => {
|
|
5641
|
-
const remote = record(entry);
|
|
5932
|
+
const remote = record$1(entry);
|
|
5642
5933
|
keys(remote, ["url", "hash"]);
|
|
5643
5934
|
return {
|
|
5644
5935
|
url: boundedLocator(remote["url"]),
|
|
@@ -6345,7 +6636,7 @@ const pointer$3 = (value) => {
|
|
|
6345
6636
|
return text;
|
|
6346
6637
|
};
|
|
6347
6638
|
const range$2 = (value) => {
|
|
6348
|
-
const v = record(value);
|
|
6639
|
+
const v = record$1(value);
|
|
6349
6640
|
keys(v, ["start", "end"]);
|
|
6350
6641
|
const start = integer(v["start"]), end = integer(v["end"]);
|
|
6351
6642
|
if (end <= start) fail("ARTIFACT_INVALID_MANIFEST");
|
|
@@ -6371,7 +6662,7 @@ function rowRanges(value, fields) {
|
|
|
6371
6662
|
});
|
|
6372
6663
|
}
|
|
6373
6664
|
function mask(value) {
|
|
6374
|
-
const v = record(value);
|
|
6665
|
+
const v = record$1(value);
|
|
6375
6666
|
keys(v, [
|
|
6376
6667
|
"inputRange",
|
|
6377
6668
|
"outputRange",
|
|
@@ -6380,9 +6671,9 @@ function mask(value) {
|
|
|
6380
6671
|
"node",
|
|
6381
6672
|
"ruleId"
|
|
6382
6673
|
]);
|
|
6383
|
-
const node = record(v["node"]);
|
|
6674
|
+
const node = record$1(v["node"]);
|
|
6384
6675
|
keys(node, ["id", "version"]);
|
|
6385
|
-
const output = record(v["outputRange"]);
|
|
6676
|
+
const output = record$1(v["outputRange"]);
|
|
6386
6677
|
keys(output, ["start", "end"]);
|
|
6387
6678
|
const start = integer(output["start"]), end = integer(output["end"]);
|
|
6388
6679
|
const replacement = string(v["replacement"]);
|
|
@@ -6403,7 +6694,7 @@ function mask(value) {
|
|
|
6403
6694
|
};
|
|
6404
6695
|
}
|
|
6405
6696
|
function field(value) {
|
|
6406
|
-
const v = record(value);
|
|
6697
|
+
const v = record$1(value);
|
|
6407
6698
|
keys(v, [
|
|
6408
6699
|
"pointer",
|
|
6409
6700
|
"cleanedPointer",
|
|
@@ -6446,7 +6737,7 @@ function field(value) {
|
|
|
6446
6737
|
return result;
|
|
6447
6738
|
}
|
|
6448
6739
|
function parsePrivateReviewRow(text) {
|
|
6449
|
-
const v = record(strictJson(text, 67108864));
|
|
6740
|
+
const v = record$1(strictJson(text, 67108864));
|
|
6450
6741
|
keys(v, [
|
|
6451
6742
|
"entryPath",
|
|
6452
6743
|
"recordIndex",
|
|
@@ -6472,7 +6763,7 @@ function parsePrivateReviewRow(text) {
|
|
|
6472
6763
|
};
|
|
6473
6764
|
}
|
|
6474
6765
|
function parsePrivateReviewManifest(text, entries, primary) {
|
|
6475
|
-
const v = record(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
6766
|
+
const v = record$1(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
6476
6767
|
keys(v, [
|
|
6477
6768
|
"format",
|
|
6478
6769
|
"version",
|
|
@@ -6482,11 +6773,11 @@ function parsePrivateReviewManifest(text, entries, primary) {
|
|
|
6482
6773
|
"entries",
|
|
6483
6774
|
"rows"
|
|
6484
6775
|
]);
|
|
6485
|
-
const bound = record(v["primary"]);
|
|
6776
|
+
const bound = record$1(v["primary"]);
|
|
6486
6777
|
keys(bound, ["sha256", "archiveBytes"]);
|
|
6487
6778
|
if (v["bundleId"] !== primary.manifest.bundleId || v["workId"] !== primary.manifest.work.id || bound["sha256"] !== primary.sha256 || bound["archiveBytes"] !== primary.archiveBytes) fail("ARTIFACT_PROCESSING_MISMATCH");
|
|
6488
6779
|
const descriptions = array(v["entries"], (value) => {
|
|
6489
|
-
const e = record(value);
|
|
6780
|
+
const e = record$1(value);
|
|
6490
6781
|
keys(e, [
|
|
6491
6782
|
"entryPath",
|
|
6492
6783
|
"kind",
|
|
@@ -7713,7 +8004,7 @@ function createMaskContexts() {
|
|
|
7713
8004
|
/** Resolves a stored context of the next row read; a reference must name an earlier one. */
|
|
7714
8005
|
read(row, inputSha256, value) {
|
|
7715
8006
|
enter(row);
|
|
7716
|
-
const data = record(value);
|
|
8007
|
+
const data = record$1(value);
|
|
7717
8008
|
const start = integer(data["start"]);
|
|
7718
8009
|
if (!Object.hasOwn(data, "text")) {
|
|
7719
8010
|
keys(data, ["start", "end"]);
|
|
@@ -7741,7 +8032,7 @@ const hash$3 = (value) => {
|
|
|
7741
8032
|
return text;
|
|
7742
8033
|
};
|
|
7743
8034
|
const range$1 = (value) => {
|
|
7744
|
-
const data = record(value);
|
|
8035
|
+
const data = record$1(value);
|
|
7745
8036
|
keys(data, ["start", "end"]);
|
|
7746
8037
|
const start = integer(data["start"]);
|
|
7747
8038
|
const end = integer(data["end"]);
|
|
@@ -7758,7 +8049,7 @@ const pointer$2 = (value) => {
|
|
|
7758
8049
|
};
|
|
7759
8050
|
/** Parses one row in ledger order; `contexts` resolves context references (ADR 0084). */
|
|
7760
8051
|
function parsePrivateMaskRow(text, contexts) {
|
|
7761
|
-
const row = record(strictJson(text, 33554432));
|
|
8052
|
+
const row = record$1(strictJson(text, 33554432));
|
|
7762
8053
|
keys(row, [
|
|
7763
8054
|
"entryPath",
|
|
7764
8055
|
"recordIndex",
|
|
@@ -7767,7 +8058,7 @@ function parsePrivateMaskRow(text, contexts) {
|
|
|
7767
8058
|
"archiveSessionId",
|
|
7768
8059
|
"mask"
|
|
7769
8060
|
]);
|
|
7770
|
-
const item = record(row["mask"]);
|
|
8061
|
+
const item = record$1(row["mask"]);
|
|
7771
8062
|
keys(item, [
|
|
7772
8063
|
"inputRange",
|
|
7773
8064
|
"outputRange",
|
|
@@ -7784,7 +8075,7 @@ function parsePrivateMaskRow(text, contexts) {
|
|
|
7784
8075
|
"outputSha256",
|
|
7785
8076
|
"context"
|
|
7786
8077
|
]);
|
|
7787
|
-
const node = record(item["node"]);
|
|
8078
|
+
const node = record$1(item["node"]);
|
|
7788
8079
|
keys(node, ["id", "version"]);
|
|
7789
8080
|
const entryPath = string(row["entryPath"]);
|
|
7790
8081
|
const recordIndex = integer(row["recordIndex"]);
|
|
@@ -7829,7 +8120,7 @@ function parsePrivateMaskRow(text, contexts) {
|
|
|
7829
8120
|
};
|
|
7830
8121
|
}
|
|
7831
8122
|
function parsePrivateMaskManifest(text, entries, primary) {
|
|
7832
|
-
const data = record(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
8123
|
+
const data = record$1(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
7833
8124
|
keys(data, [
|
|
7834
8125
|
"format",
|
|
7835
8126
|
"version",
|
|
@@ -7840,11 +8131,11 @@ function parsePrivateMaskManifest(text, entries, primary) {
|
|
|
7840
8131
|
"entries",
|
|
7841
8132
|
"rows"
|
|
7842
8133
|
]);
|
|
7843
|
-
const binding = record(data["primary"]);
|
|
8134
|
+
const binding = record$1(data["primary"]);
|
|
7844
8135
|
keys(binding, ["sha256", "archiveBytes"]);
|
|
7845
8136
|
if (data["bundleId"] !== primary.manifest.bundleId || data["workId"] !== primary.manifest.work.id || binding["sha256"] !== primary.sha256 || binding["archiveBytes"] !== primary.archiveBytes) return fail("ARTIFACT_PROCESSING_MISMATCH");
|
|
7846
8137
|
const descriptions = array(data["entries"], (value) => {
|
|
7847
|
-
const entry = record(value);
|
|
8138
|
+
const entry = record$1(value);
|
|
7848
8139
|
keys(entry, [
|
|
7849
8140
|
"entryPath",
|
|
7850
8141
|
"kind",
|
|
@@ -7911,7 +8202,7 @@ function maskHash(value) {
|
|
|
7911
8202
|
return text;
|
|
7912
8203
|
}
|
|
7913
8204
|
function maskRange(value) {
|
|
7914
|
-
const data = record(value);
|
|
8205
|
+
const data = record$1(value);
|
|
7915
8206
|
keys(data, ["start", "end"]);
|
|
7916
8207
|
const result = {
|
|
7917
8208
|
start: integer(data["start"]),
|
|
@@ -7926,7 +8217,7 @@ function pointer$1(value) {
|
|
|
7926
8217
|
return text;
|
|
7927
8218
|
}
|
|
7928
8219
|
function semantic(value, scope, contexts) {
|
|
7929
|
-
const data = record(value);
|
|
8220
|
+
const data = record$1(value);
|
|
7930
8221
|
keys(data, [
|
|
7931
8222
|
"pointer",
|
|
7932
8223
|
"inputSha256",
|
|
@@ -7953,7 +8244,7 @@ function semantic(value, scope, contexts) {
|
|
|
7953
8244
|
}
|
|
7954
8245
|
/** Parses one row in ledger order; `contexts` resolves static context references (ADR 0084). */
|
|
7955
8246
|
function parseFinalMaskRow(text, contexts) {
|
|
7956
|
-
const data = record(strictJson(text, 33554432));
|
|
8247
|
+
const data = record$1(strictJson(text, 33554432));
|
|
7957
8248
|
keys(data, [
|
|
7958
8249
|
"entryPath",
|
|
7959
8250
|
"recordIndex",
|
|
@@ -7968,7 +8259,7 @@ function parseFinalMaskRow(text, contexts) {
|
|
|
7968
8259
|
const subject = data["subject"];
|
|
7969
8260
|
if (subject !== "key" && subject !== "value") return fail("ARTIFACT_INVALID_MANIFEST");
|
|
7970
8261
|
const contributors = array(data["contributors"], (value) => {
|
|
7971
|
-
const item = record(value);
|
|
8262
|
+
const item = record$1(value);
|
|
7972
8263
|
keys(item, [
|
|
7973
8264
|
"id",
|
|
7974
8265
|
"kind",
|
|
@@ -8017,7 +8308,7 @@ function parseFinalMaskRow(text, contexts) {
|
|
|
8017
8308
|
//#endregion
|
|
8018
8309
|
//#region packages/artifact/src/configured/masks/final/manifest.ts
|
|
8019
8310
|
function categories(value) {
|
|
8020
|
-
const item = record(value);
|
|
8311
|
+
const item = record$1(value);
|
|
8021
8312
|
keys(item, [
|
|
8022
8313
|
"identity",
|
|
8023
8314
|
"credentials",
|
|
@@ -8032,7 +8323,7 @@ function categories(value) {
|
|
|
8032
8323
|
};
|
|
8033
8324
|
}
|
|
8034
8325
|
function maskSummary(value) {
|
|
8035
|
-
const data = record(value);
|
|
8326
|
+
const data = record$1(value);
|
|
8036
8327
|
keys(data, [
|
|
8037
8328
|
"occurrences",
|
|
8038
8329
|
"contributors",
|
|
@@ -8050,7 +8341,7 @@ function maskSummariesEqual(a, b) {
|
|
|
8050
8341
|
return a.occurrences === b.occurrences && a.contributors === b.contributors && a.categories.identity === b.categories.identity && a.categories.credentials === b.categories.credentials && a.categories.internal === b.categories.internal && a.categories.private === b.categories.private;
|
|
8051
8342
|
}
|
|
8052
8343
|
function parseFinalMaskManifest(text, entries, primary) {
|
|
8053
|
-
const data = record(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
8344
|
+
const data = record$1(strictJson(text, manifestLimitBytes, manifestNodeLimit));
|
|
8054
8345
|
keys(data, [
|
|
8055
8346
|
"format",
|
|
8056
8347
|
"version",
|
|
@@ -8064,13 +8355,13 @@ function parseFinalMaskManifest(text, entries, primary) {
|
|
|
8064
8355
|
"entries",
|
|
8065
8356
|
"summary"
|
|
8066
8357
|
]);
|
|
8067
|
-
const binding = record(data["primary"]);
|
|
8358
|
+
const binding = record$1(data["primary"]);
|
|
8068
8359
|
keys(binding, ["sha256", "archiveBytes"]);
|
|
8069
8360
|
if (data["bundleId"] !== primary.manifest.bundleId || data["workId"] !== primary.manifest.work.id || binding["sha256"] !== primary.sha256 || binding["archiveBytes"] !== primary.archiveBytes) fail("ARTIFACT_PROCESSING_MISMATCH");
|
|
8070
8361
|
const expected = new Set(primary.manifest.entries.map((entry) => `${entry.entryPath}.masks.jsonl`));
|
|
8071
8362
|
let total = emptyMaskSummary();
|
|
8072
8363
|
const descriptions = array(data["entries"], (value) => {
|
|
8073
|
-
const row = record(value);
|
|
8364
|
+
const row = record$1(value);
|
|
8074
8365
|
keys(row, [
|
|
8075
8366
|
"entryPath",
|
|
8076
8367
|
"kind",
|
|
@@ -8936,7 +9227,7 @@ async function rewriteConfiguredOutput(request, handle, signal = new AbortContro
|
|
|
8936
9227
|
archiveBytes: primaryResult.archiveBytes
|
|
8937
9228
|
};
|
|
8938
9229
|
const finalMaskLedger = await masks?.finish(changed, finalPrimary, { rows: request.shards === void 0 });
|
|
8939
|
-
const companionValue = record(strictJson(companion.manifestText, manifestLimitBytes, manifestNodeLimit));
|
|
9230
|
+
const companionValue = record$1(strictJson(companion.manifestText, manifestLimitBytes, manifestNodeLimit));
|
|
8940
9231
|
const companionEntries = [];
|
|
8941
9232
|
for (const description of array(companionValue["entries"], parseConfiguredEntry)) {
|
|
8942
9233
|
const entry = companion.entries.get(description.entryPath) ?? fail("ARTIFACT_INVALID_ARCHIVE");
|
|
@@ -8996,17 +9287,16 @@ async function privateJourneyDirectory(path) {
|
|
|
8996
9287
|
//#region packages/artifact/src/configured/journey/output.ts
|
|
8997
9288
|
/**
|
|
8998
9289
|
* The same checked private publication used for bases, with a fresh immutable output ID.
|
|
8999
|
-
* `onPath` names each file this call may leave behind: a temporary file
|
|
9000
|
-
* one before it is linked, so a packaging worker's owner can remove them when it stops
|
|
9001
|
-
* mid-write (ADR 0181).
|
|
9290
|
+
* `onPath` names each file this call may leave behind: a temporary file before it is created, a
|
|
9291
|
+
* published one before it is linked, so a packaging worker's owner can remove them when it stops
|
|
9292
|
+
* the worker mid-write (ADR 0181).
|
|
9002
9293
|
*/
|
|
9003
9294
|
async function writeLogicalJourneyOutput(request, signal, onPath) {
|
|
9004
9295
|
const directory = await privateJourneyDirectory(request.directory);
|
|
9005
9296
|
const primary = await createTemporary({
|
|
9006
9297
|
outputDir: directory,
|
|
9007
9298
|
keepTemp: false
|
|
9008
|
-
});
|
|
9009
|
-
onPath?.(primary.temporary.tempPath);
|
|
9299
|
+
}, onPath);
|
|
9010
9300
|
let companion;
|
|
9011
9301
|
let masks;
|
|
9012
9302
|
const cleanup = createCleanup(), linked = [];
|
|
@@ -9016,15 +9306,11 @@ async function writeLogicalJourneyOutput(request, signal, onPath) {
|
|
|
9016
9306
|
companion = await createTemporary({
|
|
9017
9307
|
outputDir: directory,
|
|
9018
9308
|
keepTemp: false
|
|
9019
|
-
});
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
keepTemp: false
|
|
9025
|
-
});
|
|
9026
|
-
onPath?.(masks.temporary.tempPath);
|
|
9027
|
-
}
|
|
9309
|
+
}, onPath);
|
|
9310
|
+
if (request.maskEvidence) masks = await createTemporary({
|
|
9311
|
+
outputDir: directory,
|
|
9312
|
+
keepTemp: false
|
|
9313
|
+
}, onPath);
|
|
9028
9314
|
const written = await rewriteConfiguredOutput({
|
|
9029
9315
|
...request,
|
|
9030
9316
|
bundleId,
|
|
@@ -9300,6 +9586,14 @@ function isResult(value) {
|
|
|
9300
9586
|
};
|
|
9301
9587
|
return file("primary") && file("ledger") && typeof pieces === "object" && pieces !== null && Array.isArray(Reflect.get(pieces, "entries")) && Array.isArray(Reflect.get(pieces, "maskEntries")) && Array.isArray(Reflect.get(value, "tokens")) && typeof Reflect.get(value, "tokensComplete") === "boolean";
|
|
9302
9588
|
}
|
|
9589
|
+
if (Reflect.get(value, "kind") === "journey-base") {
|
|
9590
|
+
const base = Reflect.get(value, "base");
|
|
9591
|
+
const file = (key) => {
|
|
9592
|
+
const item = typeof base === "object" && base !== null ? Reflect.get(base, key) : void 0;
|
|
9593
|
+
return typeof item === "object" && item !== null && typeof Reflect.get(item, "path") === "string";
|
|
9594
|
+
};
|
|
9595
|
+
return typeof base === "object" && base !== null && Reflect.get(base, "kind") === "base" && typeof Reflect.get(base, "bundleId") === "string" && file("primary") && file("companion") && file("maskLedger") && Array.isArray(Reflect.get(base, "sessions")) && Array.isArray(Reflect.get(base, "sourceBindings"));
|
|
9596
|
+
}
|
|
9303
9597
|
if (Reflect.get(value, "kind") === "journey-output") {
|
|
9304
9598
|
const output = Reflect.get(value, "output");
|
|
9305
9599
|
return typeof output === "object" && output !== null && typeof Reflect.get(output, "bundleId") === "string" && typeof Reflect.get(output, "primary") === "object" && typeof Reflect.get(output, "companion") === "object" && Array.isArray(Reflect.get(value, "tokens")) && typeof Reflect.get(value, "tokensComplete") === "boolean";
|
|
@@ -9320,6 +9614,8 @@ function isWorkerMessage(value) {
|
|
|
9320
9614
|
if (kind === "worker-error") return code === "ARTIFACT_WORKER_MEMORY" || code === "ARTIFACT_PROCESSING_FAILED";
|
|
9321
9615
|
return kind === "error" && typeof code === "string" && code.length > 0 && (sourceId === void 0 || typeof sourceId === "string");
|
|
9322
9616
|
}
|
|
9617
|
+
/** How long a stopped controller may take to end its Worker and flush its messages (ADR 0219). */
|
|
9618
|
+
const stopGraceMs = 2e3;
|
|
9323
9619
|
/** One active request per process; IPC backpressure never causes a resend or another queue. */
|
|
9324
9620
|
function createSessionProcess(workerUrl, heapMb, onMessage, onFailure) {
|
|
9325
9621
|
const options = {
|
|
@@ -9354,7 +9650,7 @@ function createSessionProcess(workerUrl, heapMb, onMessage, onFailure) {
|
|
|
9354
9650
|
closed.then(() => onFailure(memoryFailure ? "ARTIFACT_WORKER_MEMORY" : "ARTIFACT_PROCESSING_FAILED"));
|
|
9355
9651
|
};
|
|
9356
9652
|
child.on("message", (message) => {
|
|
9357
|
-
if (!closing) onMessage(message);
|
|
9653
|
+
if (!closing || Reflect.get(Object(message), "kind") === "spool") onMessage(message);
|
|
9358
9654
|
});
|
|
9359
9655
|
child.on("error", fail);
|
|
9360
9656
|
child.on("disconnect", fail);
|
|
@@ -9376,7 +9672,20 @@ function createSessionProcess(workerUrl, heapMb, onMessage, onFailure) {
|
|
|
9376
9672
|
async close() {
|
|
9377
9673
|
if (!closing) {
|
|
9378
9674
|
closing = true;
|
|
9379
|
-
if (child.exitCode === null && child.signalCode === null)
|
|
9675
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
9676
|
+
const kill = () => {
|
|
9677
|
+
if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL");
|
|
9678
|
+
};
|
|
9679
|
+
const timer = setTimeout(kill, stopGraceMs);
|
|
9680
|
+
try {
|
|
9681
|
+
if (child.connected) child.send({ kind: "stop" }, (error) => error && kill());
|
|
9682
|
+
else kill();
|
|
9683
|
+
} catch {
|
|
9684
|
+
kill();
|
|
9685
|
+
}
|
|
9686
|
+
await closed;
|
|
9687
|
+
clearTimeout(timer);
|
|
9688
|
+
}
|
|
9380
9689
|
}
|
|
9381
9690
|
await closed;
|
|
9382
9691
|
}
|
|
@@ -9411,6 +9720,34 @@ function sessionWorkerFailure(error) {
|
|
|
9411
9720
|
function requestKind(task) {
|
|
9412
9721
|
return typeof task.message === "object" && task.message !== null ? Reflect.get(task.message, "kind") : void 0;
|
|
9413
9722
|
}
|
|
9723
|
+
/**
|
|
9724
|
+
* Files one job may name: a journey output its three final files and three temporary files
|
|
9725
|
+
* (ADR 0181), an output shard its two archives and a shard readback none (ADR 0199).
|
|
9726
|
+
*/
|
|
9727
|
+
/**
|
|
9728
|
+
* A journey output or base names its three final files and three temporary files (ADR 0181,
|
|
9729
|
+
* ADR 0228); an output shard its two archives and a shard readback none (ADR 0199).
|
|
9730
|
+
*/
|
|
9731
|
+
function spoolLimit(task) {
|
|
9732
|
+
const kind = requestKind(task);
|
|
9733
|
+
return kind === "journey-output" || kind === "journey-base" ? 6 : kind === "journey-output-shard" ? 2 : kind === "journey-output-verify" ? 0 : 4;
|
|
9734
|
+
}
|
|
9735
|
+
const factsName = /^(.+)\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.facts$/;
|
|
9736
|
+
/**
|
|
9737
|
+
* Best-effort removal of a stopped job's files: its named spools and the facts files created
|
|
9738
|
+
* beside them (`<spool>.<uuid>.facts`), which are unlinked once open but can keep their name
|
|
9739
|
+
* when the process stops in between; on Windows that spans two ACL helper round trips.
|
|
9740
|
+
*/
|
|
9741
|
+
async function removeStoppedSpools(paths) {
|
|
9742
|
+
for (const [directory, spools] of Map.groupBy(paths, (path) => dirname(path))) {
|
|
9743
|
+
for (const path of spools) await unlink(path).catch(() => {});
|
|
9744
|
+
const names = new Set(spools.map((path) => basename(path)));
|
|
9745
|
+
for (const entry of await readdir(directory).catch(() => [])) {
|
|
9746
|
+
const spool = factsName.exec(entry)?.[1];
|
|
9747
|
+
if (spool !== void 0 && names.has(spool)) await unlink(join(directory, entry)).catch(() => {});
|
|
9748
|
+
}
|
|
9749
|
+
}
|
|
9750
|
+
}
|
|
9414
9751
|
/** Best-effort removal of a worker spool that no longer has an owner. */
|
|
9415
9752
|
function removeSpool(path) {
|
|
9416
9753
|
if (path === void 0) return;
|
|
@@ -9484,7 +9821,7 @@ function createSessionWorkerPool(url, size, heapMb = workerHeapMb) {
|
|
|
9484
9821
|
stopping = Promise.all(slots.map(async (slot) => {
|
|
9485
9822
|
try {
|
|
9486
9823
|
await slot.process.close();
|
|
9487
|
-
|
|
9824
|
+
if (slot.task) await removeStoppedSpools(slot.task.spoolPaths);
|
|
9488
9825
|
} finally {
|
|
9489
9826
|
slot.task?.reject(blame(slot));
|
|
9490
9827
|
slot.task = void 0;
|
|
@@ -9499,8 +9836,11 @@ function createSessionWorkerPool(url, size, heapMb = workerHeapMb) {
|
|
|
9499
9836
|
};
|
|
9500
9837
|
const onAbort = () => stop(/* @__PURE__ */ new Error("ARTIFACT_ABORTED"));
|
|
9501
9838
|
const receive = (slot, message) => {
|
|
9502
|
-
if (closed) return;
|
|
9503
9839
|
const task = slot.task;
|
|
9840
|
+
if (closed) {
|
|
9841
|
+
if (task && isWorkerMessage(message) && message.kind === "spool" && (task.spoolPaths.has(message.path) || task.spoolPaths.size < spoolLimit(task))) task.spoolPaths.add(message.path);
|
|
9842
|
+
return;
|
|
9843
|
+
}
|
|
9504
9844
|
if (!isWorkerMessage(message)) {
|
|
9505
9845
|
failPool(/* @__PURE__ */ new Error("ARTIFACT_PROCESSING_FAILED"), slot);
|
|
9506
9846
|
return;
|
|
@@ -9516,9 +9856,7 @@ function createSessionWorkerPool(url, size, heapMb = workerHeapMb) {
|
|
|
9516
9856
|
try {
|
|
9517
9857
|
if (message.kind === "source") task.onSourceProgress?.(message.bytes);
|
|
9518
9858
|
else if (message.kind === "spool") {
|
|
9519
|
-
|
|
9520
|
-
const spoolLimit = kind === "journey-output" ? 6 : kind === "journey-output-shard" ? 2 : kind === "journey-output-verify" ? 0 : 4;
|
|
9521
|
-
if (!task.spoolPaths.has(message.path) && task.spoolPaths.size >= spoolLimit) {
|
|
9859
|
+
if (!task.spoolPaths.has(message.path) && task.spoolPaths.size >= spoolLimit(task)) {
|
|
9522
9860
|
failPool(/* @__PURE__ */ new Error("ARTIFACT_PROCESSING_FAILED"), slot);
|
|
9523
9861
|
return;
|
|
9524
9862
|
}
|
|
@@ -9526,7 +9864,7 @@ function createSessionWorkerPool(url, size, heapMb = workerHeapMb) {
|
|
|
9526
9864
|
task.onSpool?.(message.path);
|
|
9527
9865
|
} else if (message.kind === "result") {
|
|
9528
9866
|
const requestedKind = requestKind(task);
|
|
9529
|
-
if ((requestedKind === "render" || requestedKind === "capture" || requestedKind === "scan" || requestedKind === "journey-output" || requestedKind === "journey-output-shard" || requestedKind === "journey-output-verify") && message.result.kind !== requestedKind) {
|
|
9867
|
+
if ((requestedKind === "render" || requestedKind === "capture" || requestedKind === "scan" || requestedKind === "journey-output" || requestedKind === "journey-output-shard" || requestedKind === "journey-output-verify" || requestedKind === "journey-base") && message.result.kind !== requestedKind) {
|
|
9530
9868
|
failPool(/* @__PURE__ */ new Error("ARTIFACT_PROCESSING_FAILED"), slot);
|
|
9531
9869
|
return;
|
|
9532
9870
|
}
|
|
@@ -9542,6 +9880,15 @@ function createSessionWorkerPool(url, size, heapMb = workerHeapMb) {
|
|
|
9542
9880
|
settle(slot, void 0, message.result);
|
|
9543
9881
|
return;
|
|
9544
9882
|
}
|
|
9883
|
+
if (message.result.kind === "journey-base") {
|
|
9884
|
+
const { primary, companion, maskLedger } = message.result.base;
|
|
9885
|
+
if (!task.spoolPaths.has(primary.path) || !task.spoolPaths.has(companion.path) || !task.spoolPaths.has(maskLedger.path)) {
|
|
9886
|
+
failPool(/* @__PURE__ */ new Error("ARTIFACT_PROCESSING_FAILED"), slot);
|
|
9887
|
+
return;
|
|
9888
|
+
}
|
|
9889
|
+
settle(slot, void 0, message.result);
|
|
9890
|
+
return;
|
|
9891
|
+
}
|
|
9545
9892
|
if (message.result.kind === "journey-output") {
|
|
9546
9893
|
if (!task.spoolPaths.has(message.result.output.primary.path) || !task.spoolPaths.has(message.result.output.companion.path)) {
|
|
9547
9894
|
failPool(/* @__PURE__ */ new Error("ARTIFACT_PROCESSING_FAILED"), slot);
|
|
@@ -10234,7 +10581,7 @@ function validateCollectionIndex(index) {
|
|
|
10234
10581
|
const maximumCollectionIndexBytes = 16777216;
|
|
10235
10582
|
const maximumCollectionNodes = 1e6;
|
|
10236
10583
|
function source(value) {
|
|
10237
|
-
const item = record(value);
|
|
10584
|
+
const item = record$1(value);
|
|
10238
10585
|
keys(item, [
|
|
10239
10586
|
"sourceId",
|
|
10240
10587
|
"sourceOrdinal",
|
|
@@ -10247,7 +10594,7 @@ function source(value) {
|
|
|
10247
10594
|
};
|
|
10248
10595
|
}
|
|
10249
10596
|
function session(value) {
|
|
10250
|
-
const item = record(value);
|
|
10597
|
+
const item = record$1(value);
|
|
10251
10598
|
keys(item, [
|
|
10252
10599
|
"sessionId",
|
|
10253
10600
|
"scopeOrdinal",
|
|
@@ -10268,7 +10615,7 @@ function session(value) {
|
|
|
10268
10615
|
};
|
|
10269
10616
|
}
|
|
10270
10617
|
function parseCollectionWorkspaceSummary(value) {
|
|
10271
|
-
const item = record(value);
|
|
10618
|
+
const item = record$1(value);
|
|
10272
10619
|
keys(item, [
|
|
10273
10620
|
"format",
|
|
10274
10621
|
"formatVersion",
|
|
@@ -10285,7 +10632,7 @@ function parseCollectionWorkspaceSummary(value) {
|
|
|
10285
10632
|
};
|
|
10286
10633
|
}
|
|
10287
10634
|
function parseCompanionDescriptor(value) {
|
|
10288
|
-
const item = record(value);
|
|
10635
|
+
const item = record$1(value);
|
|
10289
10636
|
keys(item, [
|
|
10290
10637
|
"path",
|
|
10291
10638
|
"archiveBytes",
|
|
@@ -10298,7 +10645,7 @@ function parseCompanionDescriptor(value) {
|
|
|
10298
10645
|
};
|
|
10299
10646
|
}
|
|
10300
10647
|
function bundle(value) {
|
|
10301
|
-
const item = record(value);
|
|
10648
|
+
const item = record$1(value);
|
|
10302
10649
|
keys(item, [
|
|
10303
10650
|
"workspaceSlot",
|
|
10304
10651
|
"workspaceVersion",
|
|
@@ -10333,7 +10680,7 @@ function bundle(value) {
|
|
|
10333
10680
|
};
|
|
10334
10681
|
}
|
|
10335
10682
|
function sourceScope(value) {
|
|
10336
|
-
const item = record(value);
|
|
10683
|
+
const item = record$1(value);
|
|
10337
10684
|
keys(item, ["applicationSessionId", "sourceId"]);
|
|
10338
10685
|
return {
|
|
10339
10686
|
applicationSessionId: string(item["applicationSessionId"]),
|
|
@@ -10341,7 +10688,7 @@ function sourceScope(value) {
|
|
|
10341
10688
|
};
|
|
10342
10689
|
}
|
|
10343
10690
|
function exclusion(value) {
|
|
10344
|
-
const item = record(value);
|
|
10691
|
+
const item = record$1(value);
|
|
10345
10692
|
keys(item, [
|
|
10346
10693
|
"applicationSessionId",
|
|
10347
10694
|
"sourceId",
|
|
@@ -10356,7 +10703,7 @@ function exclusion(value) {
|
|
|
10356
10703
|
};
|
|
10357
10704
|
}
|
|
10358
10705
|
function sessionBinding(value) {
|
|
10359
|
-
const item = record(value);
|
|
10706
|
+
const item = record$1(value);
|
|
10360
10707
|
keys(item, [
|
|
10361
10708
|
"applicationSessionId",
|
|
10362
10709
|
"bundleId",
|
|
@@ -10371,7 +10718,7 @@ function sessionBinding(value) {
|
|
|
10371
10718
|
};
|
|
10372
10719
|
}
|
|
10373
10720
|
function sourceBinding(value) {
|
|
10374
|
-
const item = record(value);
|
|
10721
|
+
const item = record$1(value);
|
|
10375
10722
|
keys(item, [
|
|
10376
10723
|
"applicationSessionId",
|
|
10377
10724
|
"sourceId",
|
|
@@ -10397,7 +10744,7 @@ function parseCollectionIndex(text) {
|
|
|
10397
10744
|
if (error instanceof Error && error.message === "ARTIFACT_METADATA_LIMIT") fail("ARTIFACT_INDEX_LIMIT", { cause: error });
|
|
10398
10745
|
throw error;
|
|
10399
10746
|
}
|
|
10400
|
-
const item = record(value);
|
|
10747
|
+
const item = record$1(value);
|
|
10401
10748
|
keys(item, [
|
|
10402
10749
|
"format",
|
|
10403
10750
|
"formatVersion",
|
|
@@ -10493,7 +10840,7 @@ function measured(value, copy) {
|
|
|
10493
10840
|
reasonCode: value.reasonCode
|
|
10494
10841
|
};
|
|
10495
10842
|
}
|
|
10496
|
-
function patch(value) {
|
|
10843
|
+
function patch$1(value) {
|
|
10497
10844
|
return {
|
|
10498
10845
|
grammarVersion: value.grammarVersion,
|
|
10499
10846
|
basis: value.basis,
|
|
@@ -10512,7 +10859,7 @@ function fact(value) {
|
|
|
10512
10859
|
extractorVersion: value.extractorVersion,
|
|
10513
10860
|
...value.decodedUtf8Bytes === void 0 ? {} : { decodedUtf8Bytes: measured(value.decodedUtf8Bytes, (number) => number) },
|
|
10514
10861
|
...value.logicalLines === void 0 ? {} : { logicalLines: measured(value.logicalLines, (number) => number) },
|
|
10515
|
-
...value.patchDelta === void 0 ? {} : { patchDelta: measured(value.patchDelta, patch) }
|
|
10862
|
+
...value.patchDelta === void 0 ? {} : { patchDelta: measured(value.patchDelta, patch$1) }
|
|
10516
10863
|
};
|
|
10517
10864
|
}
|
|
10518
10865
|
function relation(value) {
|
|
@@ -10640,7 +10987,7 @@ function pointer(value) {
|
|
|
10640
10987
|
return result;
|
|
10641
10988
|
}
|
|
10642
10989
|
function parseInputField(value) {
|
|
10643
|
-
const v = record(value);
|
|
10990
|
+
const v = record$1(value);
|
|
10644
10991
|
keys(v, [
|
|
10645
10992
|
"fieldId",
|
|
10646
10993
|
"sourceFieldId",
|
|
@@ -10662,13 +11009,13 @@ function parseInputField(value) {
|
|
|
10662
11009
|
if (scalarKind !== void 0 && scalarKind !== "literal" && scalarKind !== "structure" && scalarKind !== "container") return fail("ARTIFACT_INVALID_MANIFEST");
|
|
10663
11010
|
const text = string(v["text"]), fieldHash = digest(v["fieldHash"]);
|
|
10664
11011
|
if (!text.length || hash$1(text) !== fieldHash) fail("ARTIFACT_PROCESSING_MISMATCH");
|
|
10665
|
-
const c = v["cleanedRange"] === void 0 ? void 0 : record(v["cleanedRange"]);
|
|
11012
|
+
const c = v["cleanedRange"] === void 0 ? void 0 : record$1(v["cleanedRange"]);
|
|
10666
11013
|
if (c) keys(c, ["start", "end"]);
|
|
10667
11014
|
const cleanedRange = c ? {
|
|
10668
11015
|
start: integer(c["start"]),
|
|
10669
11016
|
end: integer(c["end"])
|
|
10670
11017
|
} : void 0;
|
|
10671
|
-
const r = v["originalRange"] === void 0 ? void 0 : record(v["originalRange"]);
|
|
11018
|
+
const r = v["originalRange"] === void 0 ? void 0 : record$1(v["originalRange"]);
|
|
10672
11019
|
if (r) keys(r, ["start", "end"]);
|
|
10673
11020
|
const range = r ? {
|
|
10674
11021
|
start: integer(r["start"]),
|
|
@@ -10949,25 +11296,18 @@ async function runConfiguredSessionJob(job, processing, signal, onSourceProgress
|
|
|
10949
11296
|
let processingMs = 0;
|
|
10950
11297
|
const spoolOptions = {
|
|
10951
11298
|
keepPath: true,
|
|
11299
|
+
...onSpool === void 0 ? {} : { onPath: onSpool },
|
|
10952
11300
|
...job.spoolDirectory === void 0 ? {} : { directory: job.spoolDirectory }
|
|
10953
11301
|
};
|
|
10954
11302
|
const spool = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
|
|
10955
|
-
onSpool?.(spool.path);
|
|
10956
11303
|
let companion;
|
|
10957
11304
|
let maskSpool;
|
|
10958
11305
|
let reviewSpool;
|
|
10959
11306
|
let session;
|
|
10960
11307
|
try {
|
|
10961
11308
|
companion = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
|
|
10962
|
-
|
|
10963
|
-
if (job.
|
|
10964
|
-
maskSpool = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
|
|
10965
|
-
onSpool?.(maskSpool.path);
|
|
10966
|
-
}
|
|
10967
|
-
if (job.captureReview) {
|
|
10968
|
-
reviewSpool = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
|
|
10969
|
-
onSpool?.(reviewSpool.path);
|
|
10970
|
-
}
|
|
11309
|
+
if (job.captureMasks) maskSpool = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
|
|
11310
|
+
if (job.captureReview) reviewSpool = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
|
|
10971
11311
|
const readPass = /* @__PURE__ */ new Map();
|
|
10972
11312
|
const captures = new Map((job.captures ?? []).map((capture) => [capture.partId, capture]));
|
|
10973
11313
|
session = await prepareConfiguredSession({
|
|
@@ -11045,6 +11385,7 @@ async function runConfiguredSessionJob(job, processing, signal, onSourceProgress
|
|
|
11045
11385
|
parts,
|
|
11046
11386
|
entries,
|
|
11047
11387
|
agentSetup: completed.agentSetup,
|
|
11388
|
+
...completed.agentSources === void 0 ? {} : { agentSources: completed.agentSources },
|
|
11048
11389
|
images: completed.images
|
|
11049
11390
|
};
|
|
11050
11391
|
} catch (error) {
|
|
@@ -14683,13 +15024,18 @@ async function writePrivateReviewPayload(request, signal) {
|
|
|
14683
15024
|
}
|
|
14684
15025
|
//#endregion
|
|
14685
15026
|
//#region packages/artifact/src/configured/journey/base.ts
|
|
14686
|
-
/**
|
|
14687
|
-
|
|
15027
|
+
/**
|
|
15028
|
+
* Publish an immutable, private base pair for review/resume without a public collection index.
|
|
15029
|
+
* `onPath` names each file this call may leave behind: a temporary file before it is created, a
|
|
15030
|
+
* published one before it is linked, so a packaging worker's owner can remove them when it stops
|
|
15031
|
+
* the worker mid-write (ADR 0228). Session spools live under `<temporary>.<uuid>.parallel`.
|
|
15032
|
+
*/
|
|
15033
|
+
async function writeLogicalJourneyBase(request, hooks, onPath) {
|
|
14688
15034
|
const directory = await privateJourneyDirectory(request.directory);
|
|
14689
15035
|
const primary = await createTemporary({
|
|
14690
15036
|
outputDir: directory,
|
|
14691
15037
|
keepTemp: false
|
|
14692
|
-
});
|
|
15038
|
+
}, onPath);
|
|
14693
15039
|
const cleanup = createCleanup();
|
|
14694
15040
|
let companion;
|
|
14695
15041
|
let masks;
|
|
@@ -14710,15 +15056,15 @@ async function writeLogicalJourneyBase(request, hooks) {
|
|
|
14710
15056
|
companion = await createTemporary({
|
|
14711
15057
|
outputDir: directory,
|
|
14712
15058
|
keepTemp: false
|
|
14713
|
-
});
|
|
15059
|
+
}, onPath);
|
|
14714
15060
|
masks = await createTemporary({
|
|
14715
15061
|
outputDir: directory,
|
|
14716
15062
|
keepTemp: false
|
|
14717
|
-
});
|
|
15063
|
+
}, onPath);
|
|
14718
15064
|
if (request.captureReview) review = await createTemporary({
|
|
14719
15065
|
outputDir: directory,
|
|
14720
15066
|
keepTemp: false
|
|
14721
|
-
});
|
|
15067
|
+
}, onPath);
|
|
14722
15068
|
const written = await writeLogicalWorkBundle({
|
|
14723
15069
|
production: request.production,
|
|
14724
15070
|
work: request.work,
|
|
@@ -14734,15 +15080,19 @@ async function writeLogicalJourneyBase(request, hooks) {
|
|
|
14734
15080
|
const primaryPath = join(directory, `${bundleId}.primary.zip`);
|
|
14735
15081
|
const companionPath = join(directory, `${bundleId}.companion.zip`);
|
|
14736
15082
|
const maskPath = join(directory, `${bundleId}.private-masks.zip`);
|
|
15083
|
+
onPath?.(primaryPath);
|
|
14737
15084
|
await link(primary.temporary.tempPath, primaryPath);
|
|
14738
15085
|
linked.push(primaryPath);
|
|
15086
|
+
onPath?.(companionPath);
|
|
14739
15087
|
await link(companion.temporary.tempPath, companionPath);
|
|
14740
15088
|
linked.push(companionPath);
|
|
15089
|
+
onPath?.(maskPath);
|
|
14741
15090
|
await link(masks.temporary.tempPath, maskPath);
|
|
14742
15091
|
linked.push(maskPath);
|
|
14743
15092
|
if (!identityMatches(await lstat(primaryPath, { bigint: true }), primary.temporary.identity) || !identityMatches(await lstat(companionPath, { bigint: true }), companion.temporary.identity) || !identityMatches(await lstat(maskPath, { bigint: true }), masks.temporary.identity)) fail("ARTIFACT_IDENTITY_MISMATCH");
|
|
14744
15093
|
const reviewPath = join(directory, `${bundleId}.private-review.zip`);
|
|
14745
15094
|
if (review) {
|
|
15095
|
+
onPath?.(reviewPath);
|
|
14746
15096
|
await link(review.temporary.tempPath, reviewPath);
|
|
14747
15097
|
linked.push(reviewPath);
|
|
14748
15098
|
if (!identityMatches(await lstat(reviewPath, { bigint: true }), review.temporary.identity)) fail("ARTIFACT_IDENTITY_MISMATCH");
|
|
@@ -15093,16 +15443,14 @@ async function writeOutputShard(request, signal, onPath) {
|
|
|
15093
15443
|
const output = await createTemporary({
|
|
15094
15444
|
outputDir: directory,
|
|
15095
15445
|
keepTemp: false
|
|
15096
|
-
});
|
|
15097
|
-
onPath?.(output.temporary.tempPath);
|
|
15446
|
+
}, onPath);
|
|
15098
15447
|
created.push(output.temporary.tempPath);
|
|
15099
15448
|
handles.push(output.handle);
|
|
15100
15449
|
sink = fileWriter(output.handle, signal);
|
|
15101
15450
|
const ledger = await createTemporary({
|
|
15102
15451
|
outputDir: directory,
|
|
15103
15452
|
keepTemp: false
|
|
15104
|
-
});
|
|
15105
|
-
onPath?.(ledger.temporary.tempPath);
|
|
15453
|
+
}, onPath);
|
|
15106
15454
|
created.push(ledger.temporary.tempPath);
|
|
15107
15455
|
handles.push(ledger.handle);
|
|
15108
15456
|
masks = await createFinalMaskWriter({
|
|
@@ -15185,11 +15533,12 @@ function protectedRanges(field, host, ranges) {
|
|
|
15185
15533
|
*/
|
|
15186
15534
|
async function runConfiguredScanJob(job, processing, signal, onSourceProgress, onSpool) {
|
|
15187
15535
|
const directory = await privateJourneyDirectory(job.directory);
|
|
15188
|
-
const
|
|
15536
|
+
const fieldsPath = join(directory, `${randomUUID()}.scan.jsonl`);
|
|
15537
|
+
onSpool?.(fieldsPath);
|
|
15538
|
+
const fields = await openRowFile(fieldsPath, signal);
|
|
15189
15539
|
const cleanup = createCleanup();
|
|
15190
15540
|
let success = false;
|
|
15191
15541
|
try {
|
|
15192
|
-
onSpool?.(fields.path);
|
|
15193
15542
|
const captures = new Map(job.captures.map((capture) => [capture.partId, capture]));
|
|
15194
15543
|
if (captures.size !== job.captures.length || job.sources.some((source) => !captures.has(source.source.id))) fail("ARTIFACT_SOURCE_CHANGED");
|
|
15195
15544
|
if (job.sources.length === 0 || job.sources.length > 1e4) fail("ARTIFACT_EMPTY_SCOPE");
|
|
@@ -15542,7 +15891,7 @@ function hash(value) {
|
|
|
15542
15891
|
return text;
|
|
15543
15892
|
}
|
|
15544
15893
|
function range(value) {
|
|
15545
|
-
const v = record(value);
|
|
15894
|
+
const v = record$1(value);
|
|
15546
15895
|
keys(v, ["start", "end"]);
|
|
15547
15896
|
const start = integer(v["start"]), end = integer(v["end"]);
|
|
15548
15897
|
if (end <= start) fail("ARTIFACT_PROCESSING_MISMATCH");
|
|
@@ -15563,7 +15912,7 @@ function rowIdentity(v, input) {
|
|
|
15563
15912
|
};
|
|
15564
15913
|
}
|
|
15565
15914
|
function parseSessionScanRow(value, input) {
|
|
15566
|
-
const v = record(value);
|
|
15915
|
+
const v = record$1(value);
|
|
15567
15916
|
keys(v, [
|
|
15568
15917
|
"sourceId",
|
|
15569
15918
|
"ordinal",
|
|
@@ -15573,7 +15922,7 @@ function parseSessionScanRow(value, input) {
|
|
|
15573
15922
|
const { sourceId, ordinal, id, source } = rowIdentity(v, input);
|
|
15574
15923
|
const ids = /* @__PURE__ */ new Set();
|
|
15575
15924
|
const fields = array(v["fields"], (item) => {
|
|
15576
|
-
const { sessionId, sourceId: fieldSource, ordinal: fieldOrdinal, recordId: fieldRecord, protectedRanges, ...plain } = record(item);
|
|
15925
|
+
const { sessionId, sourceId: fieldSource, ordinal: fieldOrdinal, recordId: fieldRecord, protectedRanges, ...plain } = record$1(item);
|
|
15577
15926
|
const field = parseInputField(plain);
|
|
15578
15927
|
if (!source || source.native.role !== "main" || sessionId !== input.sessionId || fieldSource !== sourceId || fieldOrdinal !== ordinal || fieldRecord !== id || field.role === "tool-output" || field.scalarKind !== void 0 || ids.has(field.fieldId) || !field.sourceFieldId.startsWith(`${id}-f`)) fail("ARTIFACT_PROCESSING_MISMATCH");
|
|
15579
15928
|
const node = field.sourceFieldId.slice(`${id}-f`.length);
|
|
@@ -15600,20 +15949,20 @@ function parseSessionScanRow(value, input) {
|
|
|
15600
15949
|
};
|
|
15601
15950
|
}
|
|
15602
15951
|
function scanFile(value) {
|
|
15603
|
-
const file = record(value);
|
|
15952
|
+
const file = record$1(value);
|
|
15604
15953
|
keys(file, [
|
|
15605
15954
|
"path",
|
|
15606
15955
|
"identity",
|
|
15607
15956
|
"sha256",
|
|
15608
15957
|
"byteLength"
|
|
15609
15958
|
]);
|
|
15610
|
-
const identity = record(file["identity"]);
|
|
15959
|
+
const identity = record$1(file["identity"]);
|
|
15611
15960
|
keys(identity, ["dev", "ino"]);
|
|
15612
15961
|
if (!string(file["path"]) || !string(identity["dev"]) || !string(identity["ino"]) || integer(file["byteLength"]) > maximumPartBytes) fail("ARTIFACT_PROCESSING_MISMATCH");
|
|
15613
15962
|
hash(file["sha256"]);
|
|
15614
15963
|
}
|
|
15615
15964
|
function validateSessionScanInput(input) {
|
|
15616
|
-
keys(record(input), [
|
|
15965
|
+
keys(record$1(input), [
|
|
15617
15966
|
"version",
|
|
15618
15967
|
"sessionId",
|
|
15619
15968
|
"emptyReviewVerified",
|
|
@@ -15630,7 +15979,7 @@ function validateSessionScanInput(input) {
|
|
|
15630
15979
|
integer(input.fieldCount);
|
|
15631
15980
|
integer(input.inputUtf16);
|
|
15632
15981
|
const sources = /* @__PURE__ */ new Set(), parts = /* @__PURE__ */ new Set();
|
|
15633
|
-
for (const item of array(input.sources, record)) {
|
|
15982
|
+
for (const item of array(input.sources, record$1)) {
|
|
15634
15983
|
keys(item, [
|
|
15635
15984
|
"sourceId",
|
|
15636
15985
|
"sourcePartId",
|
|
@@ -15641,7 +15990,7 @@ function validateSessionScanInput(input) {
|
|
|
15641
15990
|
if (!id || !part || sources.has(id) || parts.has(part) || !nativeSourceIdentitySchema.safeParse(item["native"]).success) fail("ARTIFACT_PROCESSING_MISMATCH");
|
|
15642
15991
|
sources.add(id);
|
|
15643
15992
|
parts.add(part);
|
|
15644
|
-
const facts = record(item["facts"]);
|
|
15993
|
+
const facts = record$1(item["facts"]);
|
|
15645
15994
|
keys(facts, [
|
|
15646
15995
|
"representation",
|
|
15647
15996
|
"byteLength",
|
|
@@ -15677,7 +16026,7 @@ async function* scan(handle, input, signal) {
|
|
|
15677
16026
|
const ordinals = /* @__PURE__ */ new Map();
|
|
15678
16027
|
for await (const value of frames(handle, input.file, signal)) {
|
|
15679
16028
|
if (footer) fail("ARTIFACT_PROCESSING_MISMATCH");
|
|
15680
|
-
if (record(value)["kind"] === "session-scan-footer") {
|
|
16029
|
+
if (record$1(value)["kind"] === "session-scan-footer") {
|
|
15681
16030
|
const { file: _file, ...descriptor } = input;
|
|
15682
16031
|
if (!isDeepStrictEqual(value, {
|
|
15683
16032
|
kind: "session-scan-footer",
|
|
@@ -16419,4 +16768,4 @@ async function verifyPreparedSessionSources(prepared, input, signal) {
|
|
|
16419
16768
|
}
|
|
16420
16769
|
}
|
|
16421
16770
|
//#endregion
|
|
16422
|
-
export {
|
|
16771
|
+
export { safeError as $, runConfiguredSessionJob as A, writeLogicalJourneyOutput as B, readConfiguredSearchFields as C, captureLogicalJourneySources as D, prepareCollectionProduction as E, sessionWorkerFailure as F, staticMaskCategory as G, readLogicalJourneyFinalMasks as H, privateCollectionDirectory as I, createConfiguredPreviewStream as J, readWorkspacePair as K, defaultParallelism as L, parseCollectionWorkspaceSummary as M, createSharedSessionPool as N, capturedJourneyScope as O, SessionWorkerError as P, createCleanup as Q, gitSeedsProvider as R, readOriginalSearchFields as S, checkReusableBundle as T, readConfiguredOutputInfo as U, privateJourneyDirectory as V, processJourneyMetadataFields as W, createTemporary as X, createInspectionProcessor as Y, removeNamedTemporarySpools as Z, readStaticSessionMasks as _, scanReviewFields as a, isWindowsAclFailure as at, writePrivateReviewPayload as b, readSessionScanRecords as c, verifyOutputShard as d, exclusiveLock as et, writeOutputShard as f, processJourneyMetadata as g, readCapturedOriginalRows as h, buildWorkScanBatches as i, windowsOwnerOnly as it, readCollectionIndex as j, renderJobDigest as k, scanPreparedSession as l, captureConfiguredSessionJob as m, verifyPreparedSessionSources as n, openPrivateFile as nt, createWorkPieces as o, windowsAclCodes as ot, openConfiguredUpload as p, listAgentSetup as q, prepareSessionScans as r, restrictToOwner as rt, readSessionScanFields as s, preparedScanConfiguration as t, makePrivateDirectory as tt, runConfiguredScanJob as u, staticSessionJobs as v, createCollectionArtifacts as w, readPrivateReviewPayload as x, writeLogicalJourneyBase as y, parallelismLimits as z };
|