@gitroll/tacitt-cli 0.6.9 → 0.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -4
- package/dist/{agent-setup-CODlN6zl.mjs → agent-setup-DdfF3zch.mjs} +2 -2
- package/dist/agent-setup-worker.mjs +5 -5
- package/dist/cli.mjs +35 -12
- package/dist/codex-title-worker.mjs +1 -1
- package/dist/configured-preview-worker.mjs +5 -5
- package/dist/configured-session-worker.mjs +9 -7
- package/dist/{frame-Dj5Zs6UW.mjs → frame-Bq2zRh-i.mjs} +1 -1
- package/dist/{heap-Dt3-d27v.mjs → heap-CV8Eca8V.mjs} +217 -13
- package/dist/inspection-worker.mjs +4 -4
- package/dist/{job-BQXssW46.mjs → job-BKsifhyv.mjs} +38 -18
- package/dist/{locate-BWkblijS.mjs → locate-Cx52Zqxv.mjs} +204 -20
- package/dist/{model-CSx2dP_P.mjs → model-C1UXkHh9.mjs} +1 -1
- package/dist/operation-executor.mjs +3 -3
- package/dist/preview-worker.mjs +1 -1
- package/dist/privacy-validator.mjs +29 -2
- package/dist/{query-CfhcS4gd.mjs → query-AMZerUh8.mjs} +712 -215
- package/dist/{run-xlOaKCk8.mjs → run-CaPktPhH.mjs} +4 -4
- package/dist/{src-DzKuzGVH.mjs → src-D1iONla3.mjs} +2215 -1613
- package/dist/{src-V9GHLZQs.mjs → src-DlVbGB32.mjs} +74 -37
- package/dist/{src-BgsEnMsy.mjs → src-wZx_v0Ih.mjs} +297 -207
- package/dist/store-database-worker.mjs +1 -1
- package/dist/web/assets/index-CYl7eDUu.js +172 -0
- package/dist/web/assets/index-DzOozqms.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/skills/tacitt/INDEX.md +6 -6
- package/skills/tacitt/SKILL.md +11 -11
- package/skills/tacitt/references/INDEX.md +3 -3
- package/skills/tacitt/references/b-method.md +2 -2
- package/skills/tacitt/references/bootstrap.md +2 -2
- package/skills/tacitt/references/classification.md +15 -5
- package/skills/tacitt/references/commands.md +37 -30
- package/skills/tacitt/references/journey.md +14 -6
- package/skills/tacitt/references/parallel-review.md +27 -33
- package/skills/tacitt/references/send.md +35 -9
- package/skills/tacitt/scripts/INDEX.md +37 -37
- package/skills/tacitt/scripts/answer.mjs +73 -15
- package/skills/tacitt/scripts/journey-classification-metadata.mjs +75 -26
- package/skills/tacitt/scripts/journey-classification-progress.mjs +1 -2
- package/skills/tacitt/scripts/journey-classification-validation.d.mts +13 -0
- package/skills/tacitt/scripts/journey-classification-validation.mjs +38 -0
- package/skills/tacitt/scripts/journey-classification.mjs +6 -1
- package/skills/tacitt/scripts/journey-consolidation.mjs +1 -0
- package/skills/tacitt/scripts/journey-scan-timing.d.mts +1 -0
- package/skills/tacitt/scripts/journey-scan-timing.mjs +19 -4
- package/skills/tacitt/scripts/journey-state.d.mts +15 -1
- package/skills/tacitt/scripts/journey-state.mjs +104 -5
- package/skills/tacitt/scripts/journey-tasks.d.mts +1 -0
- package/skills/tacitt/scripts/journey-tasks.mjs +13 -5
- package/skills/tacitt/scripts/journey.d.mts +46 -28
- package/skills/tacitt/scripts/journey.mjs +57 -8
- package/skills/tacitt/scripts/privacy-validator.mjs +178 -12
- package/skills/tacitt/scripts/review.d.mts +7 -6
- package/skills/tacitt/scripts/review.mjs +576 -147
- package/dist/web/assets/index-9UfCT_2C.js +0 -174
- package/dist/web/assets/index-CYJBq1px.css +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { a as isRecord, i as errorCode, n as checkDiscoveryAbort, o as unresolvedMetadata, r as discoveryBounds, t as DiscoveryWarnings } from "./model-
|
|
4
|
-
import { c as previewLimits, d as checkOpenSource, f as checkSource, h as openSource, i as pageFits, l as previewSourceVersion, m as noSymlinks, p as fileSnapshot, r as previewHeapLimits, s as previewMessageSchema, u as createZstdFrameCheck } from "./run-
|
|
1
|
+
import { Gn as nativeField, Kn as nativeItems, Mn as walkNativeFields, Wn as nativeBoolean, Xn as retainedMainTextNodes, _r as declaredVersion, br as processingSite, dn as observeSource, fn as sourceSnapshotId, gr as ProcessingError, nr as defaultLimits, qn as nativeText, zn as parseNativeRecord } from "./locate-Cx52Zqxv.mjs";
|
|
2
|
+
import { Mt as nativeAdapterVersions, it as reviewInventory, mi as gitMetadataBudgetBytes } from "./src-D1iONla3.mjs";
|
|
3
|
+
import { a as isRecord, i as errorCode, n as checkDiscoveryAbort, o as unresolvedMetadata, r as discoveryBounds, t as DiscoveryWarnings } from "./model-C1UXkHh9.mjs";
|
|
4
|
+
import { c as previewLimits, d as checkOpenSource, f as checkSource, h as openSource, i as pageFits, l as previewSourceVersion, m as noSymlinks, p as fileSnapshot, r as previewHeapLimits, s as previewMessageSchema, u as createZstdFrameCheck } from "./run-CaPktPhH.mjs";
|
|
5
5
|
import { a as titleHintLimits, n as titleHeapLimits, o as titleInputSchema, r as decodeTitleError, s as titleReplySchema } from "./heap-1FYhGds4.mjs";
|
|
6
6
|
import { constants } from "node:fs";
|
|
7
7
|
import { lstat, open, opendir, readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
@@ -313,22 +313,64 @@ function readTitleRecord(text, value, harness, titles, replace, sessionId, signa
|
|
|
313
313
|
function workflowJournalPath(part) {
|
|
314
314
|
return /^[^/]+\/[^/]+\/subagents\/workflows\/[^/]+\/journal\.jsonl$/.test(relative(part.root, part.path).replaceAll("\\", "/"));
|
|
315
315
|
}
|
|
316
|
+
/** `<project>/<session>/subagents/**`: the only place where content shape alone makes a journal. */
|
|
317
|
+
function subagentPath(part) {
|
|
318
|
+
const segments = relative(part.root, part.path).replaceAll("\\", "/").split("/");
|
|
319
|
+
return segments.length > 3 && segments[2] === "subagents";
|
|
320
|
+
}
|
|
316
321
|
/** Only these parts may read past the per-part metadata bound, so every record can be confirmed. */
|
|
317
322
|
function workflowJournalPart(part, harness) {
|
|
318
323
|
return harness === "claude" && workflowJournalPath(part);
|
|
319
324
|
}
|
|
320
325
|
const agentIdPattern = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
321
|
-
/**
|
|
326
|
+
/** Fields of a conversation record. A run-journal record carries none of them (ADR 0279). */
|
|
327
|
+
const transcriptFields = [
|
|
328
|
+
"message",
|
|
329
|
+
"sessionId",
|
|
330
|
+
"session_id",
|
|
331
|
+
"uuid",
|
|
332
|
+
"parentUuid",
|
|
333
|
+
"isSidechain",
|
|
334
|
+
"cwd",
|
|
335
|
+
"version",
|
|
336
|
+
"payload",
|
|
337
|
+
"entrypoint",
|
|
338
|
+
"toolUseResult",
|
|
339
|
+
"attachment",
|
|
340
|
+
"leafUuid",
|
|
341
|
+
"logicalParentUuid"
|
|
342
|
+
];
|
|
343
|
+
/**
|
|
344
|
+
* A Workflow run-journal record (ADR 0279): an exact `launched` record (only `type`), or
|
|
345
|
+
* `started`, `result` or `failed` with a string agent ID and key and no conversation field.
|
|
346
|
+
* Other fields on those three, such as a label, phase or `toolsUsed`, are allowed; result
|
|
347
|
+
* bodies are opaque.
|
|
348
|
+
*/
|
|
322
349
|
function workflowJournalRecord(value) {
|
|
323
|
-
if (!isRecord(value)) return false;
|
|
324
|
-
const fields = Object.keys(value).sort().join(",");
|
|
325
|
-
if (value["type"] === "launched") return fields === "type";
|
|
350
|
+
if (!isRecord(value) || transcriptFields.some((field) => field in value)) return false;
|
|
326
351
|
const agentId = value["agentId"];
|
|
352
|
+
if (value["type"] === "launched") return Object.keys(value).join(",") === "type";
|
|
327
353
|
if (typeof agentId !== "string" || typeof value["key"] !== "string") return false;
|
|
328
|
-
if (value["type"] === "failed") return
|
|
354
|
+
if (value["type"] === "failed") return agentId === "" || agentIdPattern.test(agentId);
|
|
329
355
|
if (!agentIdPattern.test(agentId)) return false;
|
|
330
|
-
if (value["type"] === "started") return
|
|
331
|
-
return value["type"] === "result" &&
|
|
356
|
+
if (value["type"] === "started") return true;
|
|
357
|
+
return value["type"] === "result" && "result" in value;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* A run-journal record that names an agent run (ADR 0279): `started` or `result`. A file is a
|
|
361
|
+
* journal only when every record is a run-journal record and at least one is of this kind.
|
|
362
|
+
*/
|
|
363
|
+
function workflowJournalAgentRecord(value) {
|
|
364
|
+
return workflowJournalRecord(value) && isRecord(value) && (value["type"] === "started" || value["type"] === "result");
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Variant for the gate reviewer (issue #59): an exact `launched` or exact `failed` record. At
|
|
368
|
+
* the journal path, a file made only of these is still a journal, as on `origin/main`.
|
|
369
|
+
*/
|
|
370
|
+
function workflowJournalExactRecord(value) {
|
|
371
|
+
if (!isRecord(value) || !workflowJournalRecord(value)) return false;
|
|
372
|
+
const fields = Object.keys(value).sort().join(",");
|
|
373
|
+
return value["type"] === "launched" || value["type"] === "failed" && fields === "agentId,key,type";
|
|
332
374
|
}
|
|
333
375
|
//#endregion
|
|
334
376
|
//#region packages/harnesses/src/metadata/interaction-time.ts
|
|
@@ -1847,6 +1889,204 @@ function worldState$1(context, payload) {
|
|
|
1847
1889
|
paths(context, nativeField(state, "agents_md"), ["directory"]);
|
|
1848
1890
|
}
|
|
1849
1891
|
//#endregion
|
|
1892
|
+
//#region packages/harnesses/src/export/identity.ts
|
|
1893
|
+
/** Issue #59: each rule that refuses a source names itself with a fixed literal. */
|
|
1894
|
+
function unsupported$1(site) {
|
|
1895
|
+
throw new ProcessingError("PROCESSING_UNSUPPORTED", { site });
|
|
1896
|
+
}
|
|
1897
|
+
function nativeId(root, key) {
|
|
1898
|
+
const node = nativeField(root, key);
|
|
1899
|
+
if (node === void 0 || node.kind === "literal" && node.raw === "null") return null;
|
|
1900
|
+
const value = nativeText(node);
|
|
1901
|
+
if (value === void 0) unsupported$1("native-id-not-text");
|
|
1902
|
+
if (!value) unsupported$1("native-id-empty");
|
|
1903
|
+
if (value.length > 1024) unsupported$1("native-id-too-long");
|
|
1904
|
+
for (let index = 0; index < value.length; index++) if (value.charCodeAt(index) < 32) unsupported$1("native-id-control-char");
|
|
1905
|
+
return value;
|
|
1906
|
+
}
|
|
1907
|
+
function sourceInspector(describe, finalize = (identity) => identity, harness) {
|
|
1908
|
+
let value = {
|
|
1909
|
+
role: "unknown",
|
|
1910
|
+
sessionId: null,
|
|
1911
|
+
agentId: null,
|
|
1912
|
+
dispatchParentSessionId: null,
|
|
1913
|
+
fork: null
|
|
1914
|
+
};
|
|
1915
|
+
let failed = false;
|
|
1916
|
+
let finished = false;
|
|
1917
|
+
let version;
|
|
1918
|
+
function reject(site, cause) {
|
|
1919
|
+
failed = true;
|
|
1920
|
+
throw new ProcessingError("PROCESSING_UNSUPPORTED", {
|
|
1921
|
+
...cause === void 0 ? {} : { cause },
|
|
1922
|
+
site: processingSite(cause)?.site ?? site,
|
|
1923
|
+
...harness ? { harness: harness.harness } : {},
|
|
1924
|
+
...version === void 0 ? {} : { harnessVersion: version }
|
|
1925
|
+
});
|
|
1926
|
+
}
|
|
1927
|
+
function merge(previous, current, site) {
|
|
1928
|
+
if (previous !== null && current !== null && previous !== current) reject(site);
|
|
1929
|
+
return current ?? previous;
|
|
1930
|
+
}
|
|
1931
|
+
function current() {
|
|
1932
|
+
if (failed) reject("source-already-refused");
|
|
1933
|
+
return Object.freeze(finalize(value));
|
|
1934
|
+
}
|
|
1935
|
+
return {
|
|
1936
|
+
inspect(root) {
|
|
1937
|
+
if (failed) reject("source-already-refused");
|
|
1938
|
+
if (finished) reject("source-read-after-finish");
|
|
1939
|
+
version = harness?.version(root) ?? version;
|
|
1940
|
+
try {
|
|
1941
|
+
const next = describe(root);
|
|
1942
|
+
if (value.role !== "unknown" && next.role !== "unknown" && value.role !== next.role) reject("source-role-conflict");
|
|
1943
|
+
if (value.fork !== null && next.fork !== null && JSON.stringify(value.fork) !== JSON.stringify(next.fork)) reject("source-fork-conflict");
|
|
1944
|
+
value = {
|
|
1945
|
+
role: next.role === "unknown" ? value.role : next.role,
|
|
1946
|
+
sessionId: merge(value.sessionId, next.sessionId, "source-session-id-conflict"),
|
|
1947
|
+
agentId: merge(value.agentId, next.agentId, "source-agent-id-conflict"),
|
|
1948
|
+
dispatchParentSessionId: merge(value.dispatchParentSessionId, next.dispatchParentSessionId, "source-parent-id-conflict"),
|
|
1949
|
+
fork: next.fork ?? value.fork
|
|
1950
|
+
};
|
|
1951
|
+
} catch (error) {
|
|
1952
|
+
reject("source-describe-failed", error);
|
|
1953
|
+
}
|
|
1954
|
+
},
|
|
1955
|
+
current,
|
|
1956
|
+
finish() {
|
|
1957
|
+
finished = true;
|
|
1958
|
+
return current();
|
|
1959
|
+
}
|
|
1960
|
+
};
|
|
1961
|
+
}
|
|
1962
|
+
function unknownIdentity() {
|
|
1963
|
+
return {
|
|
1964
|
+
role: "unknown",
|
|
1965
|
+
sessionId: null,
|
|
1966
|
+
agentId: null,
|
|
1967
|
+
dispatchParentSessionId: null,
|
|
1968
|
+
fork: null
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
//#endregion
|
|
1972
|
+
//#region packages/harnesses/src/export/claude.ts
|
|
1973
|
+
const nativeTypes = /* @__PURE__ */ new Set([
|
|
1974
|
+
"user",
|
|
1975
|
+
"assistant",
|
|
1976
|
+
"system",
|
|
1977
|
+
"progress",
|
|
1978
|
+
"summary",
|
|
1979
|
+
"result",
|
|
1980
|
+
"queue-operation",
|
|
1981
|
+
"custom-title",
|
|
1982
|
+
"compact-boundary",
|
|
1983
|
+
"last-prompt",
|
|
1984
|
+
"file-history-snapshot"
|
|
1985
|
+
]);
|
|
1986
|
+
/** Standalone metadata lines: a summary names a leaf, a snapshot lists file backups. */
|
|
1987
|
+
const metadataTypes$1 = /* @__PURE__ */ new Set(["summary", "file-history-snapshot"]);
|
|
1988
|
+
function claudeMetadataRecord(root) {
|
|
1989
|
+
return metadataTypes$1.has(nativeText(nativeField(root, "type")) ?? "");
|
|
1990
|
+
}
|
|
1991
|
+
function claudeIdentityType(type) {
|
|
1992
|
+
return typeof type === "string" && nativeTypes.has(type);
|
|
1993
|
+
}
|
|
1994
|
+
function claudeIdentityRecord(root) {
|
|
1995
|
+
return claudeIdentityType(nativeText(nativeField(root, "type")));
|
|
1996
|
+
}
|
|
1997
|
+
function claudeIdentity(root) {
|
|
1998
|
+
if (!claudeIdentityRecord(root)) return unknownIdentity();
|
|
1999
|
+
const marker = nativeField(root, "isSidechain");
|
|
2000
|
+
const sidechain = nativeBoolean(marker);
|
|
2001
|
+
if (marker !== void 0 && sidechain === void 0) throw new ProcessingError("PROCESSING_UNSUPPORTED", { site: "claude-sidechain-not-boolean" });
|
|
2002
|
+
const sessionId = nativeId(root, "sessionId");
|
|
2003
|
+
return {
|
|
2004
|
+
role: sidechain === void 0 ? "unknown" : sidechain ? "worker" : "main",
|
|
2005
|
+
sessionId,
|
|
2006
|
+
agentId: nativeId(root, "agentId"),
|
|
2007
|
+
dispatchParentSessionId: sidechain === true ? sessionId : null,
|
|
2008
|
+
fork: null
|
|
2009
|
+
};
|
|
2010
|
+
}
|
|
2011
|
+
function claudeRelations(root) {
|
|
2012
|
+
const type = nativeText(nativeField(root, "type"));
|
|
2013
|
+
if (type !== "assistant" && type !== "user") return [];
|
|
2014
|
+
const message = nativeField(root, "message");
|
|
2015
|
+
const role = nativeText(nativeField(message, "role"));
|
|
2016
|
+
if (role !== void 0 && role !== type) return [];
|
|
2017
|
+
const relations = [];
|
|
2018
|
+
for (const item of nativeItems(nativeField(message, "content"))) {
|
|
2019
|
+
const blockType = nativeText(nativeField(item, "type"));
|
|
2020
|
+
const kind = type === "assistant" && blockType === "tool_use" ? "call" : type === "user" && blockType === "tool_result" ? "result" : void 0;
|
|
2021
|
+
if (kind === void 0) continue;
|
|
2022
|
+
const callId = nativeId(item, kind === "call" ? "id" : "tool_use_id");
|
|
2023
|
+
if (callId !== null) relations.push(Object.freeze({
|
|
2024
|
+
kind,
|
|
2025
|
+
callId
|
|
2026
|
+
}));
|
|
2027
|
+
}
|
|
2028
|
+
return Object.freeze(relations);
|
|
2029
|
+
}
|
|
2030
|
+
const sessionFile = /(?:^|[/\\])([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl(?:\.zst)?$/i;
|
|
2031
|
+
/** Claude names a session transcript `<sessionId>.jsonl`; other layouts name no own session. */
|
|
2032
|
+
function claudeOwnSessionId(location) {
|
|
2033
|
+
return sessionFile.exec(location?.path ?? "")?.[1] ?? null;
|
|
2034
|
+
}
|
|
2035
|
+
/**
|
|
2036
|
+
* A main log may embed workers; a worker log never establishes a new root. A side conversation
|
|
2037
|
+
* copies another session's records (with that session's ID) into its own `<sessionId>.jsonl` and
|
|
2038
|
+
* names its own ID only later, so the first native ID decides: when it is not the file's own ID,
|
|
2039
|
+
* the source is that session's fork and keeps its own ID (ADR 0187). Header and complete reads
|
|
2040
|
+
* therefore agree; a third ID, or a foreign ID after the source named itself, stays unsupported.
|
|
2041
|
+
*/
|
|
2042
|
+
function claudeSourceInspector(location) {
|
|
2043
|
+
const own = claudeOwnSessionId(location);
|
|
2044
|
+
let main = false;
|
|
2045
|
+
let first = null;
|
|
2046
|
+
return sourceInspector((root) => {
|
|
2047
|
+
let identity = claudeIdentity(root);
|
|
2048
|
+
if (identity.role === "main") main = true;
|
|
2049
|
+
if (main && identity.role === "worker") identity = {
|
|
2050
|
+
...identity,
|
|
2051
|
+
role: "main",
|
|
2052
|
+
agentId: null,
|
|
2053
|
+
dispatchParentSessionId: null
|
|
2054
|
+
};
|
|
2055
|
+
if (own === null || identity.role === "worker" || identity.sessionId === null) return identity;
|
|
2056
|
+
first ??= identity.sessionId;
|
|
2057
|
+
if (identity.sessionId === own) return {
|
|
2058
|
+
...identity,
|
|
2059
|
+
sessionId: null
|
|
2060
|
+
};
|
|
2061
|
+
if (first === own) throw new ProcessingError("PROCESSING_UNSUPPORTED", { site: "claude-foreign-session-after-own" });
|
|
2062
|
+
return identity;
|
|
2063
|
+
}, (identity) => {
|
|
2064
|
+
if (identity.role === "worker" || own === null || first === null) return {
|
|
2065
|
+
...identity,
|
|
2066
|
+
dispatchParentSessionId: identity.role === "worker" ? identity.sessionId : null
|
|
2067
|
+
};
|
|
2068
|
+
return {
|
|
2069
|
+
...identity,
|
|
2070
|
+
sessionId: own,
|
|
2071
|
+
dispatchParentSessionId: null,
|
|
2072
|
+
fork: first === own ? null : Object.freeze({
|
|
2073
|
+
parentSessionId: first,
|
|
2074
|
+
position: Object.freeze({
|
|
2075
|
+
kind: "unknown",
|
|
2076
|
+
value: null
|
|
2077
|
+
})
|
|
2078
|
+
})
|
|
2079
|
+
};
|
|
2080
|
+
}, {
|
|
2081
|
+
harness: "claude",
|
|
2082
|
+
version: claudeVersion
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
/** The Claude Code version a record declares, when it has the shape of a version. */
|
|
2086
|
+
function claudeVersion(root) {
|
|
2087
|
+
return declaredVersion(nativeText(nativeField(root, "version")));
|
|
2088
|
+
}
|
|
2089
|
+
//#endregion
|
|
1850
2090
|
//#region packages/harnesses/src/retention/output.ts
|
|
1851
2091
|
function outputTags(family, failed) {
|
|
1852
2092
|
return {
|
|
@@ -1996,6 +2236,7 @@ var ClaudeAssociation = class {
|
|
|
1996
2236
|
scope = "main";
|
|
1997
2237
|
unknownSidechain;
|
|
1998
2238
|
invalid = false;
|
|
2239
|
+
version;
|
|
1999
2240
|
options;
|
|
2000
2241
|
constructor(options) {
|
|
2001
2242
|
this.options = options;
|
|
@@ -2003,19 +2244,20 @@ var ClaudeAssociation = class {
|
|
|
2003
2244
|
if (!Number.isSafeInteger(this.maximum) || this.maximum < 1 || this.maximum > 1e5) throw new ProcessingError("PROCESSING_LIMIT");
|
|
2004
2245
|
}
|
|
2005
2246
|
checkSource(root) {
|
|
2006
|
-
if (this.invalid)
|
|
2247
|
+
if (this.invalid) this.rejectSource("claude-retention-already-refused");
|
|
2248
|
+
this.version = claudeVersion(root) ?? this.version;
|
|
2007
2249
|
const sidechain = nativeField(root, "isSidechain");
|
|
2008
2250
|
const value = nativeBoolean(sidechain);
|
|
2009
|
-
if (sidechain && value === void 0) this.rejectSource();
|
|
2010
|
-
if (this.options.sourceRole === "worker" && value === false) this.rejectSource();
|
|
2251
|
+
if (sidechain && value === void 0) this.rejectSource("claude-retention-sidechain-not-boolean");
|
|
2252
|
+
if (this.options.sourceRole === "worker" && value === false) this.rejectSource("claude-retention-worker-not-sidechain");
|
|
2011
2253
|
if (this.options.sourceRole === "unknown" && value !== void 0) {
|
|
2012
|
-
if (this.unknownSidechain !== void 0 && this.unknownSidechain !== value) this.rejectSource();
|
|
2254
|
+
if (this.unknownSidechain !== void 0 && this.unknownSidechain !== value) this.rejectSource("claude-retention-sidechain-changed");
|
|
2013
2255
|
this.unknownSidechain = value;
|
|
2014
2256
|
}
|
|
2015
2257
|
const own = this.options.nativeSessionId;
|
|
2016
2258
|
const sessionId = this.identity(root, "sessionId", void 0);
|
|
2017
2259
|
if (sessionId !== void 0 && this.sessionId !== void 0 && sessionId !== this.sessionId) {
|
|
2018
|
-
if (!own || sessionId !== own) this.rejectSource();
|
|
2260
|
+
if (!own || sessionId !== own) this.rejectSource("claude-retention-session-id-changed");
|
|
2019
2261
|
}
|
|
2020
2262
|
this.sessionId = sessionId ?? this.sessionId;
|
|
2021
2263
|
if (this.options.sourceRole === "worker") this.agentId = this.identity(root, "agentId", this.agentId);
|
|
@@ -2027,12 +2269,18 @@ var ClaudeAssociation = class {
|
|
|
2027
2269
|
const node = nativeField(root, key);
|
|
2028
2270
|
if (!node) return previous;
|
|
2029
2271
|
const value = nativeText(node);
|
|
2030
|
-
if (!value
|
|
2272
|
+
if (!value) this.rejectSource("claude-retention-id-empty");
|
|
2273
|
+
if (value.length > 1024) this.rejectSource("claude-retention-id-too-long");
|
|
2274
|
+
if (previous !== void 0 && previous !== value) this.rejectSource("claude-retention-agent-id-changed");
|
|
2031
2275
|
return value;
|
|
2032
2276
|
}
|
|
2033
|
-
rejectSource() {
|
|
2277
|
+
rejectSource(site) {
|
|
2034
2278
|
this.invalid = true;
|
|
2035
|
-
throw new ProcessingError("PROCESSING_UNSUPPORTED"
|
|
2279
|
+
throw new ProcessingError("PROCESSING_UNSUPPORTED", {
|
|
2280
|
+
site,
|
|
2281
|
+
harness: "claude",
|
|
2282
|
+
...this.version === void 0 ? {} : { harnessVersion: this.version }
|
|
2283
|
+
});
|
|
2036
2284
|
}
|
|
2037
2285
|
register(block, selection) {
|
|
2038
2286
|
const id = nativeText(nativeField(block, "id"));
|
|
@@ -2527,7 +2775,7 @@ var ClaudeSkills = class {
|
|
|
2527
2775
|
};
|
|
2528
2776
|
//#endregion
|
|
2529
2777
|
//#region packages/harnesses/src/retention/claude/index.ts
|
|
2530
|
-
const metadataTypes
|
|
2778
|
+
const metadataTypes = /* @__PURE__ */ new Set([
|
|
2531
2779
|
"system",
|
|
2532
2780
|
"progress",
|
|
2533
2781
|
"summary",
|
|
@@ -2554,7 +2802,7 @@ function createClaudeRetention(options) {
|
|
|
2554
2802
|
"worker",
|
|
2555
2803
|
"guardian",
|
|
2556
2804
|
"unknown"
|
|
2557
|
-
].includes(options.sourceRole)) throw new ProcessingError("PROCESSING_UNSUPPORTED");
|
|
2805
|
+
].includes(options.sourceRole)) throw new ProcessingError("PROCESSING_UNSUPPORTED", { site: "claude-retention-role-unknown" });
|
|
2558
2806
|
const settings = { ...options };
|
|
2559
2807
|
const association = new ClaudeAssociation(settings);
|
|
2560
2808
|
const skills = new ClaudeSkills(settings);
|
|
@@ -2577,7 +2825,7 @@ function createClaudeRetention(options) {
|
|
|
2577
2825
|
}
|
|
2578
2826
|
selection.injected(nativeField(root, "wireToolInputs"), "derived");
|
|
2579
2827
|
if (type === "attachment") return attachment(root, recordSettings.sourceRole === "worker", selection);
|
|
2580
|
-
if (!type || !metadataTypes
|
|
2828
|
+
if (!type || !metadataTypes.has(type) && type !== "user" && type !== "assistant") {
|
|
2581
2829
|
selection.diagnose("unsupported-native-shape", root);
|
|
2582
2830
|
const result = selection.result();
|
|
2583
2831
|
let tolerated = false;
|
|
@@ -3001,13 +3249,15 @@ function content(context, node, role, mode, userAttachments = false) {
|
|
|
3001
3249
|
});
|
|
3002
3250
|
return;
|
|
3003
3251
|
}
|
|
3004
|
-
const marked = userAttachments && role === "main-text" ? pastedAttachments(SourceText.original(node.value))
|
|
3252
|
+
const marked = userAttachments && role === "main-text" ? pastedAttachments(SourceText.original(node.value)) : void 0;
|
|
3005
3253
|
if (marked !== void 0) {
|
|
3006
3254
|
context.edits.push({
|
|
3007
3255
|
nodeId: node.id,
|
|
3008
3256
|
role,
|
|
3009
3257
|
mode: { kind: "remove" },
|
|
3010
|
-
replacement: marked
|
|
3258
|
+
replacement: marked.text,
|
|
3259
|
+
replacementSourceRanges: marked.ranges,
|
|
3260
|
+
replacementTargetRanges: marked.targetRanges
|
|
3011
3261
|
});
|
|
3012
3262
|
return;
|
|
3013
3263
|
}
|
|
@@ -3475,72 +3725,6 @@ function worldState(context, payload) {
|
|
|
3475
3725
|
}
|
|
3476
3726
|
}
|
|
3477
3727
|
//#endregion
|
|
3478
|
-
//#region packages/harnesses/src/export/identity.ts
|
|
3479
|
-
function nativeId(root, key) {
|
|
3480
|
-
const node = nativeField(root, key);
|
|
3481
|
-
if (node === void 0 || node.kind === "literal" && node.raw === "null") return null;
|
|
3482
|
-
const value = nativeText(node);
|
|
3483
|
-
if (!value || value.length > 1024) throw new ProcessingError("PROCESSING_UNSUPPORTED");
|
|
3484
|
-
for (let index = 0; index < value.length; index++) if (value.charCodeAt(index) < 32) throw new ProcessingError("PROCESSING_UNSUPPORTED");
|
|
3485
|
-
return value;
|
|
3486
|
-
}
|
|
3487
|
-
function sourceInspector(describe, finalize = (identity) => identity) {
|
|
3488
|
-
let value = {
|
|
3489
|
-
role: "unknown",
|
|
3490
|
-
sessionId: null,
|
|
3491
|
-
agentId: null,
|
|
3492
|
-
dispatchParentSessionId: null,
|
|
3493
|
-
fork: null
|
|
3494
|
-
};
|
|
3495
|
-
let failed = false;
|
|
3496
|
-
let finished = false;
|
|
3497
|
-
function reject(cause) {
|
|
3498
|
-
failed = true;
|
|
3499
|
-
throw new ProcessingError("PROCESSING_UNSUPPORTED", { cause });
|
|
3500
|
-
}
|
|
3501
|
-
function merge(previous, current) {
|
|
3502
|
-
if (previous !== null && current !== null && previous !== current) reject();
|
|
3503
|
-
return current ?? previous;
|
|
3504
|
-
}
|
|
3505
|
-
function current() {
|
|
3506
|
-
if (failed) reject();
|
|
3507
|
-
return Object.freeze(finalize(value));
|
|
3508
|
-
}
|
|
3509
|
-
return {
|
|
3510
|
-
inspect(root) {
|
|
3511
|
-
if (failed || finished) reject();
|
|
3512
|
-
try {
|
|
3513
|
-
const next = describe(root);
|
|
3514
|
-
if (value.role !== "unknown" && next.role !== "unknown" && value.role !== next.role) reject();
|
|
3515
|
-
if (value.fork !== null && next.fork !== null && JSON.stringify(value.fork) !== JSON.stringify(next.fork)) reject();
|
|
3516
|
-
value = {
|
|
3517
|
-
role: next.role === "unknown" ? value.role : next.role,
|
|
3518
|
-
sessionId: merge(value.sessionId, next.sessionId),
|
|
3519
|
-
agentId: merge(value.agentId, next.agentId),
|
|
3520
|
-
dispatchParentSessionId: merge(value.dispatchParentSessionId, next.dispatchParentSessionId),
|
|
3521
|
-
fork: next.fork ?? value.fork
|
|
3522
|
-
};
|
|
3523
|
-
} catch (error) {
|
|
3524
|
-
reject(error);
|
|
3525
|
-
}
|
|
3526
|
-
},
|
|
3527
|
-
current,
|
|
3528
|
-
finish() {
|
|
3529
|
-
finished = true;
|
|
3530
|
-
return current();
|
|
3531
|
-
}
|
|
3532
|
-
};
|
|
3533
|
-
}
|
|
3534
|
-
function unknownIdentity() {
|
|
3535
|
-
return {
|
|
3536
|
-
role: "unknown",
|
|
3537
|
-
sessionId: null,
|
|
3538
|
-
agentId: null,
|
|
3539
|
-
dispatchParentSessionId: null,
|
|
3540
|
-
fork: null
|
|
3541
|
-
};
|
|
3542
|
-
}
|
|
3543
|
-
//#endregion
|
|
3544
3728
|
//#region packages/harnesses/src/export/codex.ts
|
|
3545
3729
|
function codexIdentity(root) {
|
|
3546
3730
|
if (nativeText(nativeField(root, "type")) !== "session_meta") return unknownIdentity();
|
|
@@ -3550,7 +3734,7 @@ function codexIdentity(root) {
|
|
|
3550
3734
|
const subagent = nativeField(source, "subagent");
|
|
3551
3735
|
const spawn = nativeField(subagent, "thread_spawn");
|
|
3552
3736
|
const guardian = nativeText(nativeField(subagent, "other")) === "guardian";
|
|
3553
|
-
if (guardian && spawn !== void 0) throw new ProcessingError("PROCESSING_UNSUPPORTED");
|
|
3737
|
+
if (guardian && spawn !== void 0) throw new ProcessingError("PROCESSING_UNSUPPORTED", { site: "codex-guardian-thread-spawn" });
|
|
3554
3738
|
const role = source?.kind === "string" && [
|
|
3555
3739
|
"cli",
|
|
3556
3740
|
"vscode",
|
|
@@ -3626,8 +3810,16 @@ function codexSourceInspector() {
|
|
|
3626
3810
|
if (seenMetadata || nativeText(nativeField(root, "type")) !== "session_meta") return unknownIdentity();
|
|
3627
3811
|
seenMetadata = true;
|
|
3628
3812
|
return codexIdentity(root);
|
|
3813
|
+
}, void 0, {
|
|
3814
|
+
harness: "codex",
|
|
3815
|
+
version: codexVersion
|
|
3629
3816
|
});
|
|
3630
3817
|
}
|
|
3818
|
+
/** The Codex CLI version a session_meta record declares, when it has the shape of a version. */
|
|
3819
|
+
function codexVersion(root) {
|
|
3820
|
+
if (nativeText(nativeField(root, "type")) !== "session_meta") return void 0;
|
|
3821
|
+
return declaredVersion(nativeText(nativeField(nativeField(root, "payload"), "cli_version")));
|
|
3822
|
+
}
|
|
3631
3823
|
//#endregion
|
|
3632
3824
|
//#region packages/harnesses/src/retention/codex/index.ts
|
|
3633
3825
|
function nativeItem(context, node, calls) {
|
|
@@ -3675,7 +3867,10 @@ function createCodexRetention(options) {
|
|
|
3675
3867
|
if (type === "session_meta" && payload?.kind === "object") {
|
|
3676
3868
|
if (codexIdentity(root).role === "unknown") unsupported(context, payload);
|
|
3677
3869
|
const physicalRole = inspector.current().role;
|
|
3678
|
-
if (sourceRole !== "unknown" && physicalRole !== "unknown" && physicalRole !== sourceRole) throw new ProcessingError("PROCESSING_UNSUPPORTED"
|
|
3870
|
+
if (sourceRole !== "unknown" && physicalRole !== "unknown" && physicalRole !== sourceRole) throw new ProcessingError("PROCESSING_UNSUPPORTED", {
|
|
3871
|
+
site: "codex-retention-role-mismatch",
|
|
3872
|
+
harness: "codex"
|
|
3873
|
+
});
|
|
3679
3874
|
const id = fieldText(payload, "id");
|
|
3680
3875
|
if (!id || id.length > 512) unsupported(context, payload);
|
|
3681
3876
|
}
|
|
@@ -3716,117 +3911,6 @@ function createCodexRetention(options) {
|
|
|
3716
3911
|
};
|
|
3717
3912
|
}
|
|
3718
3913
|
//#endregion
|
|
3719
|
-
//#region packages/harnesses/src/export/claude.ts
|
|
3720
|
-
const nativeTypes = /* @__PURE__ */ new Set([
|
|
3721
|
-
"user",
|
|
3722
|
-
"assistant",
|
|
3723
|
-
"system",
|
|
3724
|
-
"progress",
|
|
3725
|
-
"summary",
|
|
3726
|
-
"result",
|
|
3727
|
-
"queue-operation",
|
|
3728
|
-
"custom-title",
|
|
3729
|
-
"compact-boundary",
|
|
3730
|
-
"last-prompt",
|
|
3731
|
-
"file-history-snapshot"
|
|
3732
|
-
]);
|
|
3733
|
-
/** Standalone metadata lines: a summary names a leaf, a snapshot lists file backups. */
|
|
3734
|
-
const metadataTypes = /* @__PURE__ */ new Set(["summary", "file-history-snapshot"]);
|
|
3735
|
-
function claudeMetadataRecord(root) {
|
|
3736
|
-
return metadataTypes.has(nativeText(nativeField(root, "type")) ?? "");
|
|
3737
|
-
}
|
|
3738
|
-
function claudeIdentityType(type) {
|
|
3739
|
-
return typeof type === "string" && nativeTypes.has(type);
|
|
3740
|
-
}
|
|
3741
|
-
function claudeIdentityRecord(root) {
|
|
3742
|
-
return claudeIdentityType(nativeText(nativeField(root, "type")));
|
|
3743
|
-
}
|
|
3744
|
-
function claudeIdentity(root) {
|
|
3745
|
-
if (!claudeIdentityRecord(root)) return unknownIdentity();
|
|
3746
|
-
const marker = nativeField(root, "isSidechain");
|
|
3747
|
-
const sidechain = nativeBoolean(marker);
|
|
3748
|
-
if (marker !== void 0 && sidechain === void 0) throw new ProcessingError("PROCESSING_UNSUPPORTED");
|
|
3749
|
-
const sessionId = nativeId(root, "sessionId");
|
|
3750
|
-
return {
|
|
3751
|
-
role: sidechain === void 0 ? "unknown" : sidechain ? "worker" : "main",
|
|
3752
|
-
sessionId,
|
|
3753
|
-
agentId: nativeId(root, "agentId"),
|
|
3754
|
-
dispatchParentSessionId: sidechain === true ? sessionId : null,
|
|
3755
|
-
fork: null
|
|
3756
|
-
};
|
|
3757
|
-
}
|
|
3758
|
-
function claudeRelations(root) {
|
|
3759
|
-
const type = nativeText(nativeField(root, "type"));
|
|
3760
|
-
if (type !== "assistant" && type !== "user") return [];
|
|
3761
|
-
const message = nativeField(root, "message");
|
|
3762
|
-
const role = nativeText(nativeField(message, "role"));
|
|
3763
|
-
if (role !== void 0 && role !== type) return [];
|
|
3764
|
-
const relations = [];
|
|
3765
|
-
for (const item of nativeItems(nativeField(message, "content"))) {
|
|
3766
|
-
const blockType = nativeText(nativeField(item, "type"));
|
|
3767
|
-
const kind = type === "assistant" && blockType === "tool_use" ? "call" : type === "user" && blockType === "tool_result" ? "result" : void 0;
|
|
3768
|
-
if (kind === void 0) continue;
|
|
3769
|
-
const callId = nativeId(item, kind === "call" ? "id" : "tool_use_id");
|
|
3770
|
-
if (callId !== null) relations.push(Object.freeze({
|
|
3771
|
-
kind,
|
|
3772
|
-
callId
|
|
3773
|
-
}));
|
|
3774
|
-
}
|
|
3775
|
-
return Object.freeze(relations);
|
|
3776
|
-
}
|
|
3777
|
-
const sessionFile = /(?:^|[/\\])([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl(?:\.zst)?$/i;
|
|
3778
|
-
/** Claude names a session transcript `<sessionId>.jsonl`; other layouts name no own session. */
|
|
3779
|
-
function claudeOwnSessionId(location) {
|
|
3780
|
-
return sessionFile.exec(location?.path ?? "")?.[1] ?? null;
|
|
3781
|
-
}
|
|
3782
|
-
/**
|
|
3783
|
-
* A main log may embed workers; a worker log never establishes a new root. A side conversation
|
|
3784
|
-
* copies another session's records (with that session's ID) into its own `<sessionId>.jsonl` and
|
|
3785
|
-
* names its own ID only later, so the first native ID decides: when it is not the file's own ID,
|
|
3786
|
-
* the source is that session's fork and keeps its own ID (ADR 0187). Header and complete reads
|
|
3787
|
-
* therefore agree; a third ID, or a foreign ID after the source named itself, stays unsupported.
|
|
3788
|
-
*/
|
|
3789
|
-
function claudeSourceInspector(location) {
|
|
3790
|
-
const own = claudeOwnSessionId(location);
|
|
3791
|
-
let main = false;
|
|
3792
|
-
let first = null;
|
|
3793
|
-
return sourceInspector((root) => {
|
|
3794
|
-
let identity = claudeIdentity(root);
|
|
3795
|
-
if (identity.role === "main") main = true;
|
|
3796
|
-
if (main && identity.role === "worker") identity = {
|
|
3797
|
-
...identity,
|
|
3798
|
-
role: "main",
|
|
3799
|
-
agentId: null,
|
|
3800
|
-
dispatchParentSessionId: null
|
|
3801
|
-
};
|
|
3802
|
-
if (own === null || identity.role === "worker" || identity.sessionId === null) return identity;
|
|
3803
|
-
first ??= identity.sessionId;
|
|
3804
|
-
if (identity.sessionId === own) return {
|
|
3805
|
-
...identity,
|
|
3806
|
-
sessionId: null
|
|
3807
|
-
};
|
|
3808
|
-
if (first === own) throw new ProcessingError("PROCESSING_UNSUPPORTED");
|
|
3809
|
-
return identity;
|
|
3810
|
-
}, (identity) => {
|
|
3811
|
-
if (identity.role === "worker" || own === null || first === null) return {
|
|
3812
|
-
...identity,
|
|
3813
|
-
dispatchParentSessionId: identity.role === "worker" ? identity.sessionId : null
|
|
3814
|
-
};
|
|
3815
|
-
return {
|
|
3816
|
-
...identity,
|
|
3817
|
-
sessionId: own,
|
|
3818
|
-
dispatchParentSessionId: null,
|
|
3819
|
-
fork: first === own ? null : Object.freeze({
|
|
3820
|
-
parentSessionId: first,
|
|
3821
|
-
position: Object.freeze({
|
|
3822
|
-
kind: "unknown",
|
|
3823
|
-
value: null
|
|
3824
|
-
})
|
|
3825
|
-
})
|
|
3826
|
-
};
|
|
3827
|
-
});
|
|
3828
|
-
}
|
|
3829
|
-
//#endregion
|
|
3830
3914
|
//#region packages/harnesses/src/export/annotations.ts
|
|
3831
3915
|
/** Exact fork metadata confirmed by bounded native-header inspection. */
|
|
3832
3916
|
function codexAnnotations(root, options, selection) {
|
|
@@ -4381,7 +4465,9 @@ function createNativeAdapters() {
|
|
|
4381
4465
|
relations: claudeRelations,
|
|
4382
4466
|
lifecycle: Object.freeze({
|
|
4383
4467
|
part: workflowJournalPath,
|
|
4384
|
-
record: workflowJournalRecord
|
|
4468
|
+
record: workflowJournalRecord,
|
|
4469
|
+
agentRecord: workflowJournalAgentRecord,
|
|
4470
|
+
exactRecord: workflowJournalExactRecord
|
|
4385
4471
|
}),
|
|
4386
4472
|
metadataRecord: claudeMetadataRecord,
|
|
4387
4473
|
launch: claudeLaunch,
|
|
@@ -4616,8 +4702,10 @@ async function metadataStream(part, harness, options) {
|
|
|
4616
4702
|
let incompleteRecord = false;
|
|
4617
4703
|
let unchanged = false;
|
|
4618
4704
|
let lastInteractionAt = null;
|
|
4619
|
-
let journalOnly = journalPath;
|
|
4705
|
+
let journalOnly = harness === "claude" && (journalPath || subagentPath(part));
|
|
4706
|
+
let journalAgentRecords = 0;
|
|
4620
4707
|
let journalRecords = 0;
|
|
4708
|
+
let journalExactOnly = true;
|
|
4621
4709
|
let launch;
|
|
4622
4710
|
let launchKnown = false;
|
|
4623
4711
|
let headExhausted = false;
|
|
@@ -4636,14 +4724,16 @@ async function metadataStream(part, harness, options) {
|
|
|
4636
4724
|
try {
|
|
4637
4725
|
const text = decoder.decode(line);
|
|
4638
4726
|
const value = JSON.parse(text);
|
|
4639
|
-
if (journalPath && workflowJournalRecord(value)) {
|
|
4727
|
+
if ((journalPath || journalOnly) && workflowJournalRecord(value)) {
|
|
4640
4728
|
parseNativeRecord(text, {
|
|
4641
4729
|
...defaultLimits,
|
|
4642
4730
|
maxRecordBytes: limit,
|
|
4643
4731
|
maxUnitBytes: limit,
|
|
4644
4732
|
maxDepth: discoveryBounds.depth
|
|
4645
4733
|
}, options.signal ?? new AbortController().signal);
|
|
4734
|
+
if (workflowJournalAgentRecord(value)) journalAgentRecords++;
|
|
4646
4735
|
journalRecords++;
|
|
4736
|
+
if (!workflowJournalExactRecord(value)) journalExactOnly = false;
|
|
4647
4737
|
return;
|
|
4648
4738
|
}
|
|
4649
4739
|
journalOnly = false;
|
|
@@ -4728,7 +4818,7 @@ async function metadataStream(part, harness, options) {
|
|
|
4728
4818
|
}
|
|
4729
4819
|
checkDiscoveryAbort(options.signal);
|
|
4730
4820
|
if (headExhausted && !launchKnown && readMode === "append") launch = await probeLaunch(part, harness, options.signal);
|
|
4731
|
-
const workflowJournal = journalOnly && journalRecords > 0 && !stopped;
|
|
4821
|
+
const workflowJournal = journalOnly && (journalAgentRecords > 0 || journalPath && journalExactOnly && journalRecords > 0) && !stopped && !incompleteRecord;
|
|
4732
4822
|
const complete = !stopped && !incompleteRecord && unchanged;
|
|
4733
4823
|
if (journalPath && !workflowJournal) warnings.add("UNCONFIRMED_WORKFLOW_JOURNAL");
|
|
4734
4824
|
if (launch === "automation") warnings.add("NON_INTERACTIVE_LAUNCH");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as createExecutor, t as assertStoreHeap } from "./heap-
|
|
1
|
+
import { i as createExecutor, t as assertStoreHeap } from "./heap-CV8Eca8V.mjs";
|
|
2
2
|
import { parentPort } from "node:worker_threads";
|
|
3
3
|
//#region packages/local-host/src/store/worker/entry.ts
|
|
4
4
|
if (!parentPort) throw new Error("STORE_WORKER_REQUIRED");
|