@gitroll/tacitt-cli 0.4.2 → 0.5.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-Bpsi-BCv.mjs → agent-setup-BZbgLgHg.mjs} +2 -2
- package/dist/agent-setup-worker.mjs +5 -5
- package/dist/cli.mjs +6 -5
- package/dist/codex-title-worker.mjs +1 -1
- package/dist/configured-preview-worker.mjs +5 -5
- package/dist/configured-session-worker.mjs +5 -5
- package/dist/{frame-IeDOLy1o.mjs → frame-DGun31Uc.mjs} +1 -1
- package/dist/{heap-DiOlSa8T.mjs → heap-NDnGBXH6.mjs} +3 -3
- package/dist/inspection-worker.mjs +4 -4
- package/dist/{job-BII94L2c.mjs → job-BO0a67HQ.mjs} +383 -8
- package/dist/{locate-CBiw-CJK.mjs → locate-JYtFmKu-.mjs} +115 -3
- package/dist/{model-DGTsARtV.mjs → model-CmHypB0p.mjs} +1 -1
- package/dist/operation-executor.mjs +3 -3
- package/dist/preview-worker.mjs +1 -1
- package/dist/privacy-validator.mjs +1 -1
- package/dist/{query-CVqWNFYf.mjs → query-BZvNsP1u.mjs} +458 -29
- package/dist/{run-BGlf-W0M.mjs → run-DvRM-NR8.mjs} +4 -4
- package/dist/{src-CBTvOa44.mjs → src-C1SjCDx0.mjs} +21 -3
- package/dist/{src-D4nrfC2S.mjs → src-CQeUBG2Y.mjs} +6 -5
- package/dist/{src-37kIclGK.mjs → src-xidy0yF7.mjs} +4 -4
- package/dist/store-database-worker.mjs +1 -1
- package/dist/web/assets/index-Bbck2aOB.css +1 -0
- package/dist/web/assets/{index-D3g_ATU-.js → index-D0j-mvf1.js} +2 -2
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/skills/tacitt/SKILL.md +2 -2
- package/skills/tacitt/references/INDEX.md +11 -10
- package/skills/tacitt/references/commands.md +13 -0
- package/skills/tacitt/references/journey.md +1 -1
- package/skills/tacitt/references/remote-workers.md +46 -0
- package/skills/tacitt/references/send.md +4 -0
- package/skills/tacitt/scripts/privacy-validator.mjs +76 -3
- package/dist/web/assets/index-D5DEG5Ue.css +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { J as listAgentSetup } from "./src-
|
|
2
|
-
import {
|
|
3
|
-
import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-
|
|
4
|
-
import { at as maximumAgentSetupSessions, ci as effectiveTreatmentSchema } from "./src-
|
|
5
|
-
import "./agent-setup-
|
|
1
|
+
import { J as listAgentSetup } from "./src-CQeUBG2Y.mjs";
|
|
2
|
+
import { Dn as createStaticProcessor, dn as workspaceSchema, ln as sessionSchema } from "./locate-JYtFmKu-.mjs";
|
|
3
|
+
import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-xidy0yF7.mjs";
|
|
4
|
+
import { at as maximumAgentSetupSessions, ci as effectiveTreatmentSchema } from "./src-C1SjCDx0.mjs";
|
|
5
|
+
import "./agent-setup-BZbgLgHg.mjs";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { parentPort, workerData } from "node:worker_threads";
|
|
8
8
|
//#region apps/cli/src/agent-setup/worker.ts
|
package/dist/cli.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { _ as readStateDump, a as readAgentPresence, b as traceStartup, d as helpText, f as parseOptions, g as startupFailure, h as permissionDiagnostic, i as invoke, l as awaitingPassport, m as longCommands, n as readOperation, o as createRuntime, p as businessCommands, r as waitOperation, s as executorEventSchema, t as cancelOperation, u as createRenderActivity, v as createExecutionPort, y as startHost$1 } from "./query-
|
|
3
|
-
import { nt as makePrivateDirectory, rt as openPrivateFile } from "./src-
|
|
4
|
-
import {
|
|
5
|
-
import { Zn as reviewTransportBytes, et as readWorkspaceOutcomes, ii as stateSchema, st as resolveFailureLocation } from "./src-
|
|
6
|
-
import { _t as isCoordinationBusy } from "./heap-
|
|
2
|
+
import { _ as readStateDump, a as readAgentPresence, b as traceStartup, d as helpText, f as parseOptions, g as startupFailure, h as permissionDiagnostic, i as invoke, l as awaitingPassport, m as longCommands, n as readOperation, o as createRuntime, p as businessCommands, r as waitOperation, s as executorEventSchema, t as cancelOperation, u as createRenderActivity, v as createExecutionPort, y as startHost$1 } from "./query-BZvNsP1u.mjs";
|
|
3
|
+
import { nt as makePrivateDirectory, rt as openPrivateFile } from "./src-CQeUBG2Y.mjs";
|
|
4
|
+
import { $t as safeField, Qt as safeCode, Xt as ApplicationError } from "./locate-JYtFmKu-.mjs";
|
|
5
|
+
import { Zn as reviewTransportBytes, et as readWorkspaceOutcomes, ii as stateSchema, st as resolveFailureLocation } from "./src-C1SjCDx0.mjs";
|
|
6
|
+
import { _t as isCoordinationBusy } from "./heap-NDnGBXH6.mjs";
|
|
7
7
|
import { constants, createReadStream, write } from "node:fs";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { lstat, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, writeFile } from "node:fs/promises";
|
|
@@ -1161,6 +1161,7 @@ const writeJson = (value) => new Promise((resolve, reject) => {
|
|
|
1161
1161
|
/** Procedures the review helper sends; each runs exactly as its own `--input` command would. */
|
|
1162
1162
|
const streamProcedures = /* @__PURE__ */ new Set([
|
|
1163
1163
|
"journey.get",
|
|
1164
|
+
"journey.remoteWorkers",
|
|
1164
1165
|
"journey.prepare",
|
|
1165
1166
|
"journey.catalog",
|
|
1166
1167
|
"journey.classificationSessions",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as errorCode } from "./model-
|
|
1
|
+
import { i as errorCode } from "./model-CmHypB0p.mjs";
|
|
2
2
|
import { a as titleHintLimits, i as encodeTitleError, o as titleInputSchema, t as assertTitleHeap } from "./heap-1FYhGds4.mjs";
|
|
3
3
|
import { stat } from "node:fs/promises";
|
|
4
4
|
import { isAbsolute, join } from "node:path";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Y as createConfiguredPreviewStream } from "./src-
|
|
2
|
-
import {
|
|
3
|
-
import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-
|
|
4
|
-
import { ci as effectiveTreatmentSchema } from "./src-
|
|
5
|
-
import { a as classifyRecord, n as assertPreviewHeap, t as runPreview } from "./run-
|
|
1
|
+
import { Y as createConfiguredPreviewStream } from "./src-CQeUBG2Y.mjs";
|
|
2
|
+
import { Dn as createStaticProcessor, dn as workspaceSchema, ln as sessionSchema } from "./locate-JYtFmKu-.mjs";
|
|
3
|
+
import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-xidy0yF7.mjs";
|
|
4
|
+
import { ci as effectiveTreatmentSchema } from "./src-C1SjCDx0.mjs";
|
|
5
|
+
import { a as classifyRecord, n as assertPreviewHeap, t as runPreview } from "./run-DvRM-NR8.mjs";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { parentPort, workerData } from "node:worker_threads";
|
|
8
8
|
//#region apps/cli/src/preview/run.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { et as safeError, h as captureConfiguredSessionJob, j as runConfiguredSessionJob, u as runConfiguredScanJob, z as gitSeedsProvider } from "./src-
|
|
2
|
-
import {
|
|
3
|
-
import { l as createNativeAdapters } from "./src-
|
|
4
|
-
import "./src-
|
|
5
|
-
import { d as runJourneyBaseJob, i as runJourneyOutputVerifyJob, n as runJourneyOutputJob, r as runJourneyOutputShardJob } from "./job-
|
|
1
|
+
import { et as safeError, h as captureConfiguredSessionJob, j as runConfiguredSessionJob, u as runConfiguredScanJob, z as gitSeedsProvider } from "./src-CQeUBG2Y.mjs";
|
|
2
|
+
import { Dn as createStaticProcessor, Qt as safeCode } from "./locate-JYtFmKu-.mjs";
|
|
3
|
+
import { l as createNativeAdapters } from "./src-xidy0yF7.mjs";
|
|
4
|
+
import "./src-C1SjCDx0.mjs";
|
|
5
|
+
import { d as runJourneyBaseJob, i as runJourneyOutputVerifyJob, n as runJourneyOutputJob, r as runJourneyOutputShardJob } from "./job-BO0a67HQ.mjs";
|
|
6
6
|
import { parentPort } from "node:worker_threads";
|
|
7
7
|
//#region apps/cli/src/configured-session-worker.ts
|
|
8
8
|
const port = parentPort;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ur as ProcessingError } from "./locate-JYtFmKu-.mjs";
|
|
2
2
|
//#region packages/processing/src/compression/frame.ts
|
|
3
3
|
function createZstdFrameCheck(fail = () => {
|
|
4
4
|
throw new ProcessingError("PROCESSING_INVALID_RECORD");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { S as readPrivateReviewPayload, at as windowsOwnerOnly, it as restrictToOwner, rt as openPrivateFile, tt as exclusiveLock, x as writePrivateReviewPayload } from "./src-
|
|
2
|
-
import {
|
|
3
|
-
import { $n as mergeBRepair, $t as journeyResourceSchema, At as validateAttemptAppend, B as validateInspectionBatch, Bt as newJourneyWork, Et as obsoleteJourney, Fn as confirmedHideGroupIds, Ft as applyClassificationProposal, G as validateInspectionFence, Gn as workPrivacyDecisions, Gr as withReadingProgress, Gt as hideFinishSchema, Hn as syncTermGroups, Hr as isReadingComplete, Ht as journeyContextQuerySchema, In as confirmedHideKey, It as classificationCommitSchema, J as validateInspectionQuery, Jn as reviewCandidateResourceSchema, Jt as journeySearchSaveSchema, K as validateInspectionHead, Kr as mergePrivacyTerms, Kt as hidePublishSchema, Mn as bMaskedHits, Nt as journeyBatchReadSchema, Pr as journeySendSchema, Pt as journeyReviewStorageQuerySchema, Qn as bReviewDigest, Qt as journeyResourceQuerySchema, Rn as confirmedHideTerms, Un as retireWorkDescription, Ur as isSelectedWork, Ut as journeyContextSchema, V as validateInspectionBatches, Vn as maskedHitsStale, W as validateInspectionClaim, Wn as workDecisionDigest, Wr as selectedWorks, Wt as hideBeginSchema, X as validateDetectionSummary, Xn as reviewRepairResourceSchema, Xt as journeyPolicyRespondSchema, Y as validateInspectionContribution, Yt as searchScopeDigest, Z as inspectionInputs, Zt as projectPreparationProgress, _ as projectJourneyInventory, _n as journeyCommitResultSchema, _r as preparationSettlementSchema, an as reviewAttemptsResultSchema, ar as scanGitSeedsId, b as bReviewScope, c as reconstructBFields, cn as sessionReconciliationResourceSchema, en as journeyIsolateSchema, fn as sessionReviewQuerySchema, fr as journeyInventoryReadSchema, gn as sessionUsefulnessResourceSchema, gr as preparationBeginSchema, h as semanticGroupKey, hn as sessionUsefulnessInputSchema, ht as candidateSortAvailable, ii as stateSchema, in as reviewAttemptsQuerySchema, ir as scanSessionResourceSchema, jt as journeyGuidance, kr as staticSessionId, kt as attemptBudgetCodePoints, l as reviseGroupMembership, lr as validateScanExclusion, m as hideScopeDigest, mn as sessionReviewStatusSchema, mr as journeyPreparationProgressSchema, nn as sortingApplySchema, nr as scanCanonicalResourceSchema, o as bRereadDigest, pn as sessionReviewResourceSchema, pr as journeyInventorySchema, pt as manualUploadSchema, q as validateInspectionInputs, qt as journeySearchResultSchema, rn as reviewAttemptResourceSchema, s as reconcileBSession, sn as sessionReconcileResultSchema, t as scanBatchContextDigest, tn as journeyPlaceSchema, tr as scanAliasResourceSchema, u as resolveGroupSplit, un as sessionRereadResourceSchema, ut as manualUploadBindingSchema, v as preparationScope, vn as journeyCommitSchema, vr as preparationStartSchema, wn as settleConfirmedHides, wt as settleCorrections, xn as confirmedHideDeltaSchema, xr as applyCardAnswers, yn as journeyEventSchema, yr as validatePreparationFacts, zn as dictionaryHides } from "./src-
|
|
1
|
+
import { S as readPrivateReviewPayload, at as windowsOwnerOnly, it as restrictToOwner, rt as openPrivateFile, tt as exclusiveLock, x as writePrivateReviewPayload } from "./src-CQeUBG2Y.mjs";
|
|
2
|
+
import { At as journeyTermSchema, It as termTypeSchema, Mt as reviewTermsResultSchema, Xt as ApplicationError, _ as semanticFindingSchema, b as validateBReview, c as textDigest, d as reviewAlignmentAudit, dt as nativeJourneySchema, er as isStaticCategory, ft as journeyGuidanceSchema, g as validateReviewAlignment, gt as journeyWorkSuggestionSchema, ht as journeyDescribeSchema, i as reviewBatchSchema, it as journeyDigestSchema, jt as reviewTermsInputSchema, kt as privacyTermSchema, l as validateReview, m as reviewAlignmentSchema, nn as reviewFamilies, o as reviewDigest, ot as journeyIdSchema, r as reviewBatchChunks, s as reviewSubmitSchema, sn as fileIdentitySchema, tn as familySelected, tr as staticCategories, u as findingReferenceKey, v as bContextEvidence, wn as createDetectionSummary } from "./locate-JYtFmKu-.mjs";
|
|
3
|
+
import { $n as mergeBRepair, $t as journeyResourceSchema, At as validateAttemptAppend, B as validateInspectionBatch, Bt as newJourneyWork, Et as obsoleteJourney, Fn as confirmedHideGroupIds, Ft as applyClassificationProposal, G as validateInspectionFence, Gn as workPrivacyDecisions, Gr as withReadingProgress, Gt as hideFinishSchema, Hn as syncTermGroups, Hr as isReadingComplete, Ht as journeyContextQuerySchema, In as confirmedHideKey, It as classificationCommitSchema, J as validateInspectionQuery, Jn as reviewCandidateResourceSchema, Jt as journeySearchSaveSchema, K as validateInspectionHead, Kr as mergePrivacyTerms, Kt as hidePublishSchema, Mn as bMaskedHits, Nt as journeyBatchReadSchema, Pr as journeySendSchema, Pt as journeyReviewStorageQuerySchema, Qn as bReviewDigest, Qt as journeyResourceQuerySchema, Rn as confirmedHideTerms, Un as retireWorkDescription, Ur as isSelectedWork, Ut as journeyContextSchema, V as validateInspectionBatches, Vn as maskedHitsStale, W as validateInspectionClaim, Wn as workDecisionDigest, Wr as selectedWorks, Wt as hideBeginSchema, X as validateDetectionSummary, Xn as reviewRepairResourceSchema, Xt as journeyPolicyRespondSchema, Y as validateInspectionContribution, Yt as searchScopeDigest, Z as inspectionInputs, Zt as projectPreparationProgress, _ as projectJourneyInventory, _n as journeyCommitResultSchema, _r as preparationSettlementSchema, an as reviewAttemptsResultSchema, ar as scanGitSeedsId, b as bReviewScope, c as reconstructBFields, cn as sessionReconciliationResourceSchema, en as journeyIsolateSchema, fn as sessionReviewQuerySchema, fr as journeyInventoryReadSchema, gn as sessionUsefulnessResourceSchema, gr as preparationBeginSchema, h as semanticGroupKey, hn as sessionUsefulnessInputSchema, ht as candidateSortAvailable, ii as stateSchema, in as reviewAttemptsQuerySchema, ir as scanSessionResourceSchema, jt as journeyGuidance, kr as staticSessionId, kt as attemptBudgetCodePoints, l as reviseGroupMembership, lr as validateScanExclusion, m as hideScopeDigest, mn as sessionReviewStatusSchema, mr as journeyPreparationProgressSchema, nn as sortingApplySchema, nr as scanCanonicalResourceSchema, o as bRereadDigest, pn as sessionReviewResourceSchema, pr as journeyInventorySchema, pt as manualUploadSchema, q as validateInspectionInputs, qt as journeySearchResultSchema, rn as reviewAttemptResourceSchema, s as reconcileBSession, sn as sessionReconcileResultSchema, t as scanBatchContextDigest, tn as journeyPlaceSchema, tr as scanAliasResourceSchema, u as resolveGroupSplit, un as sessionRereadResourceSchema, ut as manualUploadBindingSchema, v as preparationScope, vn as journeyCommitSchema, vr as preparationStartSchema, wn as settleConfirmedHides, wt as settleCorrections, xn as confirmedHideDeltaSchema, xr as applyCardAnswers, yn as journeyEventSchema, yr as validatePreparationFacts, zn as dictionaryHides } from "./src-C1SjCDx0.mjs";
|
|
4
4
|
import { constants } from "node:fs";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { copyFile, link, lstat, mkdir, mkdtemp, open, readFile, realpath, rm, unlink } from "node:fs/promises";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { X as createInspectionProcessor } from "./src-
|
|
2
|
-
import {
|
|
3
|
-
import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-
|
|
4
|
-
import { H as validateInspectionRequest } from "./src-
|
|
1
|
+
import { X as createInspectionProcessor } from "./src-CQeUBG2Y.mjs";
|
|
2
|
+
import { Dn as createStaticProcessor } from "./locate-JYtFmKu-.mjs";
|
|
3
|
+
import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-xidy0yF7.mjs";
|
|
4
|
+
import { H as validateInspectionRequest } from "./src-C1SjCDx0.mjs";
|
|
5
5
|
import "./messages-D3m3bhva.mjs";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { parentPort, workerData } from "node:worker_threads";
|
|
@@ -1,12 +1,386 @@
|
|
|
1
|
-
import { A as renderJobDigest, D as prepareCollectionProduction, V as writeLogicalJourneyOutput, W as readConfiguredOutputInfo, b as writeLogicalJourneyBase, d as verifyOutputShard, f as writeOutputShard, w as readConfiguredSearchFields, z as gitSeedsProvider } from "./src-
|
|
2
|
-
import {
|
|
3
|
-
import { Ar as staticSessionResourceSchema, Cn as renderedHideValue, Dn as hideKeyId, En as addHideIndexTokens, di as selectFrozenConfiguration, kn as packHideIndex, li as defaultScopedSettings, ui as freezeConfiguration } from "./src-
|
|
1
|
+
import { A as renderJobDigest, D as prepareCollectionProduction, V as writeLogicalJourneyOutput, W as readConfiguredOutputInfo, at as windowsOwnerOnly, b as writeLogicalJourneyBase, d as verifyOutputShard, f as writeOutputShard, nt as makePrivateDirectory, w as readConfiguredSearchFields, z as gitSeedsProvider } from "./src-CQeUBG2Y.mjs";
|
|
2
|
+
import { Xt as ApplicationError, nn as reviewFamilies, zt as filterInventoryByPeriod } from "./locate-JYtFmKu-.mjs";
|
|
3
|
+
import { Ar as staticSessionResourceSchema, Cn as renderedHideValue, Dn as hideKeyId, En as addHideIndexTokens, di as selectFrozenConfiguration, kn as packHideIndex, li as defaultScopedSettings, ui as freezeConfiguration } from "./src-C1SjCDx0.mjs";
|
|
4
4
|
import { constants } from "node:fs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { copyFile, link, lstat, mkdir, mkdtemp, open, readFile, realpath, rename, rm, unlink, writeFile } from "node:fs/promises";
|
|
7
|
+
import { execFile } from "node:child_process";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
import { promisify } from "node:util";
|
|
7
10
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
12
|
+
import { quote } from "shell-quote";
|
|
13
|
+
//#region apps/cli/src/remote/model.ts
|
|
14
|
+
function validRemotePath(path, harness) {
|
|
15
|
+
return harness === "codex" ? /^\.codex\/sessions\/\d{4}\/\d{2}\/\d{2}\/rollout-[A-Za-z0-9_.-]+\.jsonl$/u.test(path) : /^\.claude\/projects\/[A-Za-z0-9_-]+\/[A-Za-z0-9_-]+\.jsonl$/u.test(path);
|
|
16
|
+
}
|
|
17
|
+
function insideWindow(start, window) {
|
|
18
|
+
const time = Date.parse(start);
|
|
19
|
+
return Number.isFinite(time) && time >= Date.parse(window.start) && time <= Date.parse(window.end);
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region apps/cli/src/remote/transport.ts
|
|
23
|
+
const execute = promisify(execFile);
|
|
24
|
+
/** Pin every component to the signed-in user's home without following links. */
|
|
25
|
+
const sourceReader = `def source_open(relative):
|
|
26
|
+
parts=relative.split('/')
|
|
27
|
+
if any(part in ('','.', '..') for part in parts): raise RuntimeError('invalid source')
|
|
28
|
+
directory=os.open(os.path.expanduser('~'),os.O_RDONLY|os.O_DIRECTORY|os.O_NOFOLLOW)
|
|
29
|
+
try:
|
|
30
|
+
for part in parts[:-1]:
|
|
31
|
+
child=os.open(part,os.O_RDONLY|os.O_DIRECTORY|os.O_NOFOLLOW,dir_fd=directory)
|
|
32
|
+
os.close(directory)
|
|
33
|
+
directory=child
|
|
34
|
+
descriptor=os.open(parts[-1],os.O_RDONLY|os.O_NOFOLLOW|os.O_NONBLOCK,dir_fd=directory)
|
|
35
|
+
try:
|
|
36
|
+
metadata=os.fstat(descriptor)
|
|
37
|
+
if not stat.S_ISREG(metadata.st_mode) or metadata.st_uid!=os.getuid(): raise RuntimeError('invalid source owner or type')
|
|
38
|
+
return os.fdopen(descriptor,'rb')
|
|
39
|
+
except BaseException:
|
|
40
|
+
os.close(descriptor)
|
|
41
|
+
raise
|
|
42
|
+
finally: os.close(directory)`;
|
|
43
|
+
/** Read only a bounded prefix, ignoring Claude bookkeeping before native session records. */
|
|
44
|
+
const startReader = `def session_start(f,harness):
|
|
45
|
+
prefix=f.read(262145)
|
|
46
|
+
lines=prefix[:262144].split(b'\\n')
|
|
47
|
+
if len(prefix)>262144: lines.pop()
|
|
48
|
+
types=('user','assistant','system','progress','summary','result','queue-operation')
|
|
49
|
+
for line in lines:
|
|
50
|
+
if not line.strip(): continue
|
|
51
|
+
record=json.loads(line)
|
|
52
|
+
if not isinstance(record,dict): continue
|
|
53
|
+
if harness=='codex' and record.get('type')!='session_meta': return None
|
|
54
|
+
if harness=='claude' and record.get('type') not in types: continue
|
|
55
|
+
time=record.get('timestamp')
|
|
56
|
+
if isinstance(time,str):
|
|
57
|
+
try:
|
|
58
|
+
stamp(time)
|
|
59
|
+
return time
|
|
60
|
+
except ValueError: pass
|
|
61
|
+
if harness=='codex': return None
|
|
62
|
+
return None`;
|
|
63
|
+
/** Fixed remote program: bounded first-record metadata only, never directory copying. */
|
|
64
|
+
const listing = `import os,glob,json,datetime,stat
|
|
65
|
+
harness,start,end=INPUT
|
|
66
|
+
home=os.path.expanduser('~')
|
|
67
|
+
def stamp(s):
|
|
68
|
+
return datetime.datetime.fromisoformat(s.replace('Z','+00:00')).timestamp()
|
|
69
|
+
${startReader}
|
|
70
|
+
${sourceReader}
|
|
71
|
+
low,high=stamp(start),stamp(end)
|
|
72
|
+
pattern='.codex/sessions/*/*/*/rollout-*.jsonl' if harness=='codex' else '.claude/projects/*/*.jsonl'
|
|
73
|
+
result=[]
|
|
74
|
+
for count,relative in enumerate(glob.iglob(pattern,root_dir=home)):
|
|
75
|
+
if count>=100000: raise RuntimeError('listing limit')
|
|
76
|
+
path=os.path.join(home,relative)
|
|
77
|
+
if os.path.realpath(path)!=path or not stat.S_ISREG(os.stat(path).st_mode): continue
|
|
78
|
+
try:
|
|
79
|
+
with source_open(relative) as f: time=session_start(f,harness)
|
|
80
|
+
if isinstance(time,str) and low<=stamp(time)<=high: result.append({'path':relative,'start':time})
|
|
81
|
+
except (ValueError,KeyError,TypeError,OSError,RuntimeError): continue
|
|
82
|
+
if len(result)>10000: raise RuntimeError('file limit')
|
|
83
|
+
print(json.dumps(result))`;
|
|
84
|
+
function invocation(window, script) {
|
|
85
|
+
const command = quote([
|
|
86
|
+
"python3",
|
|
87
|
+
"-c",
|
|
88
|
+
script
|
|
89
|
+
]);
|
|
90
|
+
return window.transport === "ssh" ? {
|
|
91
|
+
executable: "ssh",
|
|
92
|
+
args: [
|
|
93
|
+
"-oBatchMode=yes",
|
|
94
|
+
"-oConnectTimeout=10",
|
|
95
|
+
"-oStrictHostKeyChecking=yes",
|
|
96
|
+
"-n",
|
|
97
|
+
...window.args,
|
|
98
|
+
command
|
|
99
|
+
]
|
|
100
|
+
} : {
|
|
101
|
+
executable: "gcloud",
|
|
102
|
+
args: [
|
|
103
|
+
"compute",
|
|
104
|
+
"ssh",
|
|
105
|
+
...window.args,
|
|
106
|
+
"--quiet",
|
|
107
|
+
"--ssh-flag=-oBatchMode=yes",
|
|
108
|
+
"--ssh-flag=-oConnectTimeout=10",
|
|
109
|
+
"--ssh-flag=-oStrictHostKeyChecking=yes",
|
|
110
|
+
"--ssh-flag=-n",
|
|
111
|
+
"--command",
|
|
112
|
+
command
|
|
113
|
+
]
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
async function run(window, script, maxBuffer) {
|
|
117
|
+
const call = invocation(window, script);
|
|
118
|
+
const execution = execute(call.executable, call.args, {
|
|
119
|
+
timeout: 6e4,
|
|
120
|
+
killSignal: "SIGKILL",
|
|
121
|
+
maxBuffer,
|
|
122
|
+
encoding: "buffer",
|
|
123
|
+
env: {
|
|
124
|
+
...process.env,
|
|
125
|
+
SSH_ASKPASS_REQUIRE: "never",
|
|
126
|
+
CLOUDSDK_CORE_DISABLE_PROMPTS: "1"
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
let timer;
|
|
130
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
131
|
+
timer = setTimeout(() => {
|
|
132
|
+
execution.child?.kill("SIGKILL");
|
|
133
|
+
execution.child?.stdin?.destroy();
|
|
134
|
+
execution.child?.stdout?.destroy();
|
|
135
|
+
execution.child?.stderr?.destroy();
|
|
136
|
+
reject(/* @__PURE__ */ new Error("REMOTE_TRANSPORT_TIMEOUT"));
|
|
137
|
+
}, 6e4);
|
|
138
|
+
});
|
|
139
|
+
try {
|
|
140
|
+
return await Promise.race([execution, deadline]);
|
|
141
|
+
} finally {
|
|
142
|
+
clearTimeout(timer);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function createRemoteTransport() {
|
|
146
|
+
return {
|
|
147
|
+
async list(window) {
|
|
148
|
+
const input = JSON.stringify([
|
|
149
|
+
window.harness,
|
|
150
|
+
window.start,
|
|
151
|
+
window.end
|
|
152
|
+
]);
|
|
153
|
+
const { stdout } = await run(window, listing.replace("INPUT", input), 4194304);
|
|
154
|
+
const value = JSON.parse(stdout.toString("utf8"));
|
|
155
|
+
if (!Array.isArray(value)) throw new Error("INVALID_REMOTE_LIST");
|
|
156
|
+
const files = [];
|
|
157
|
+
for (const item of value) {
|
|
158
|
+
if (!item || typeof item !== "object" || !("path" in item) || !("start" in item) || typeof item.path !== "string" || typeof item.start !== "string") throw new Error("INVALID_REMOTE_FILE");
|
|
159
|
+
files.push({
|
|
160
|
+
path: item.path,
|
|
161
|
+
start: item.start
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return files;
|
|
165
|
+
},
|
|
166
|
+
async copy(window, file, destination) {
|
|
167
|
+
if (!validRemotePath(file.path, window.harness)) throw new Error("INVALID_REMOTE_PATH");
|
|
168
|
+
const { stdout } = await run(window, `import os,sys,stat,json,datetime
|
|
169
|
+
def stamp(value): return datetime.datetime.fromisoformat(value.replace('Z','+00:00')).timestamp()
|
|
170
|
+
${startReader}
|
|
171
|
+
${sourceReader}
|
|
172
|
+
with source_open(${JSON.stringify(file.path)}) as f:
|
|
173
|
+
s=os.fstat(f.fileno())
|
|
174
|
+
if not stat.S_ISREG(s.st_mode) or s.st_size>268435456: raise RuntimeError('source limit')
|
|
175
|
+
time=session_start(f,${JSON.stringify(window.harness)})
|
|
176
|
+
if time is None or not stamp(${JSON.stringify(window.start)})<=stamp(time)<=stamp(${JSON.stringify(window.end)}): raise RuntimeError('source outside window')
|
|
177
|
+
f.seek(0)
|
|
178
|
+
data=f.read(268435457)
|
|
179
|
+
if len(data)>268435456: raise RuntimeError('source limit')
|
|
180
|
+
sys.stdout.buffer.write(data)`, 268435456);
|
|
181
|
+
await writeFile(destination, stdout, {
|
|
182
|
+
flag: "wx",
|
|
183
|
+
mode: 384
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
//#endregion
|
|
189
|
+
//#region apps/cli/src/remote/collect.ts
|
|
190
|
+
/** Validate the copied bounded native start records rather than trusting a stale remote listing. */
|
|
191
|
+
async function copiedStart(path, harness) {
|
|
192
|
+
const handle = await open(path, "r");
|
|
193
|
+
try {
|
|
194
|
+
if ((await handle.stat()).size > 268435456) throw new Error("REMOTE_FILE_TOO_LARGE");
|
|
195
|
+
const limit = 262144;
|
|
196
|
+
const buffer = Buffer.alloc(262145);
|
|
197
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
198
|
+
const lines = buffer.toString("utf8", 0, Math.min(bytesRead, limit)).split("\n");
|
|
199
|
+
if (bytesRead > limit) lines.pop();
|
|
200
|
+
const types = [
|
|
201
|
+
"user",
|
|
202
|
+
"assistant",
|
|
203
|
+
"system",
|
|
204
|
+
"progress",
|
|
205
|
+
"summary",
|
|
206
|
+
"result",
|
|
207
|
+
"queue-operation"
|
|
208
|
+
];
|
|
209
|
+
for (const line of lines) {
|
|
210
|
+
if (!line.trim()) continue;
|
|
211
|
+
const value = JSON.parse(line);
|
|
212
|
+
if (!value || typeof value !== "object" || !("type" in value)) continue;
|
|
213
|
+
if (harness === "codex" && value.type !== "session_meta") return null;
|
|
214
|
+
if (harness === "claude" && (typeof value.type !== "string" || !types.includes(value.type))) continue;
|
|
215
|
+
if ("timestamp" in value && typeof value.timestamp === "string" && Number.isFinite(Date.parse(value.timestamp))) return value.timestamp;
|
|
216
|
+
if (harness === "codex") return null;
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
} finally {
|
|
220
|
+
await handle.close();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/** Only consented hosts are contacted. Every copy is exclusive and normal discovery reads it next. */
|
|
224
|
+
async function collectRemoteWorkers(dispatches, confirmations, home, transport = createRemoteTransport(), reportFailure = () => console.error("REMOTE_WORKER_COLLECTION_FAILED"), roots = {}) {
|
|
225
|
+
const copied = [];
|
|
226
|
+
const failures = /* @__PURE__ */ new Set();
|
|
227
|
+
const seen = /* @__PURE__ */ new Set();
|
|
228
|
+
for (const window of dispatches) {
|
|
229
|
+
if (confirmations[window.host] !== true || failures.has(window.host)) continue;
|
|
230
|
+
let temporary;
|
|
231
|
+
try {
|
|
232
|
+
temporary = await mkdtemp(join(tmpdir(), "tacitt-remote-"));
|
|
233
|
+
const files = await transport.list(window);
|
|
234
|
+
if (files.length > 1e4) throw new Error("REMOTE_LIST_TOO_LARGE");
|
|
235
|
+
for (const file of files) {
|
|
236
|
+
if (!validRemotePath(file.path, window.harness) || !insideWindow(file.start, window)) continue;
|
|
237
|
+
const key = JSON.stringify([window.host, file.path]);
|
|
238
|
+
if (seen.has(key)) continue;
|
|
239
|
+
const staging = join(temporary, "worker.jsonl");
|
|
240
|
+
await transport.copy(window, file, staging);
|
|
241
|
+
const start = await copiedStart(staging, window.harness);
|
|
242
|
+
if (!start || !insideWindow(start, window)) {
|
|
243
|
+
await rm(staging, { force: true });
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
const hash = createHash("sha256").update(key).digest("hex");
|
|
247
|
+
const date = new Date(start).toISOString().slice(0, 10).split("-");
|
|
248
|
+
const path = window.harness === "codex" ? join(roots.codexHome ?? join(home, ".codex"), "sessions", ...date, `rollout-remote-${hash}.jsonl`) : join(roots.claudeHome ?? join(home, ".claude"), "projects", `remote-${hash.slice(0, 16)}`, `${hash}.jsonl`);
|
|
249
|
+
await mkdir(dirname(path), {
|
|
250
|
+
recursive: true,
|
|
251
|
+
mode: 448
|
|
252
|
+
});
|
|
253
|
+
try {
|
|
254
|
+
await copyFile(staging, path, constants.COPYFILE_EXCL);
|
|
255
|
+
copied.push({
|
|
256
|
+
path,
|
|
257
|
+
sourceSessionId: window.sourceSessionId
|
|
258
|
+
});
|
|
259
|
+
} catch (error) {
|
|
260
|
+
if (!(error instanceof Error) || !("code" in error) || error.code !== "EEXIST") throw error;
|
|
261
|
+
const existing = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
262
|
+
try {
|
|
263
|
+
if ((await existing.stat()).size <= 268435456) {
|
|
264
|
+
const incoming = await open(staging, "r");
|
|
265
|
+
try {
|
|
266
|
+
const [left, right] = await Promise.all([existing.readFile(), incoming.readFile()]);
|
|
267
|
+
if (left.equals(right)) copied.push({
|
|
268
|
+
path,
|
|
269
|
+
sourceSessionId: window.sourceSessionId
|
|
270
|
+
});
|
|
271
|
+
} finally {
|
|
272
|
+
await incoming.close();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
} finally {
|
|
276
|
+
await existing.close();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
seen.add(key);
|
|
280
|
+
await rm(staging, { force: true });
|
|
281
|
+
}
|
|
282
|
+
} catch (error) {
|
|
283
|
+
failures.add(window.host);
|
|
284
|
+
reportFailure(window.host, error);
|
|
285
|
+
} finally {
|
|
286
|
+
if (temporary) try {
|
|
287
|
+
await rm(temporary, {
|
|
288
|
+
recursive: true,
|
|
289
|
+
force: true
|
|
290
|
+
});
|
|
291
|
+
} catch (error) {
|
|
292
|
+
failures.add(window.host);
|
|
293
|
+
reportFailure(window.host, error);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
copied,
|
|
299
|
+
failures: [...failures]
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
//#endregion
|
|
303
|
+
//#region apps/cli/src/journey/directory.ts
|
|
304
|
+
async function journeyDirectory(stateDir, journeyId) {
|
|
305
|
+
let path = stateDir;
|
|
306
|
+
for (const name of ["journeys", journeyId]) {
|
|
307
|
+
path = join(path, name);
|
|
308
|
+
try {
|
|
309
|
+
await makePrivateDirectory(path);
|
|
310
|
+
} catch (cause) {
|
|
311
|
+
if (!(cause instanceof Error && "code" in cause && cause.code === "EEXIST")) throw cause;
|
|
312
|
+
}
|
|
313
|
+
const stat = await lstat(path, { bigint: true });
|
|
314
|
+
if (!stat.isDirectory() || stat.isSymbolicLink() || await realpath(path) !== path || (process.platform === "win32" ? !await windowsOwnerOnly(path, "directory") : stat.uid !== BigInt(process.getuid?.() ?? -1) || (stat.mode & 63n) !== 0n)) throw new ApplicationError("UNSAFE_STATE_PATH");
|
|
315
|
+
}
|
|
316
|
+
return path;
|
|
317
|
+
}
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region apps/cli/src/remote/state.ts
|
|
320
|
+
const attachment = z.object({
|
|
321
|
+
path: z.string(),
|
|
322
|
+
sourceSessionId: z.string()
|
|
323
|
+
}).strict();
|
|
324
|
+
async function readRemoteState(stateDir, journeyId) {
|
|
325
|
+
const path = join(await journeyDirectory(stateDir, journeyId), "remote-workers.json");
|
|
326
|
+
try {
|
|
327
|
+
const value = JSON.parse(await readFile(path, "utf8"));
|
|
328
|
+
return z.object({
|
|
329
|
+
windows: z.array(z.object({
|
|
330
|
+
host: z.string(),
|
|
331
|
+
harness: z.enum(["codex", "claude"]),
|
|
332
|
+
transport: z.enum(["ssh", "gcloud"]),
|
|
333
|
+
args: z.array(z.string()),
|
|
334
|
+
sourceSessionId: z.string(),
|
|
335
|
+
start: z.string(),
|
|
336
|
+
end: z.string()
|
|
337
|
+
}).strict()),
|
|
338
|
+
decisions: z.record(z.string(), z.boolean()),
|
|
339
|
+
parents: z.record(z.string(), z.string()),
|
|
340
|
+
copied: z.array(attachment),
|
|
341
|
+
failures: z.array(z.string())
|
|
342
|
+
}).strict().parse(value);
|
|
343
|
+
} catch (error) {
|
|
344
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
|
|
345
|
+
throw error;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
async function saveRemoteState(stateDir, journeyId, state) {
|
|
349
|
+
const path = join(await journeyDirectory(stateDir, journeyId), "remote-workers.json");
|
|
350
|
+
const temporary = `${path}.${randomUUID()}`;
|
|
351
|
+
await writeFile(temporary, JSON.stringify(state), {
|
|
352
|
+
mode: 384,
|
|
353
|
+
flag: "wx"
|
|
354
|
+
});
|
|
355
|
+
await rename(temporary, path);
|
|
356
|
+
}
|
|
357
|
+
async function attachRemoteWorkers(inventory, stateDir, journeyId) {
|
|
358
|
+
const state = await readRemoteState(stateDir, journeyId);
|
|
359
|
+
const allowed = new Set(state?.copied.map((copy) => copy.path) ?? []);
|
|
360
|
+
const sessions = inventory.sessions.filter((session) => session.parts.every((part) => !isRemoteImport(part.path) || allowed.has(part.path))).flatMap((session) => {
|
|
361
|
+
const imports = (state?.copied ?? []).filter((copy) => session.parts.some((part) => part.path === copy.path));
|
|
362
|
+
const parent = imports[0]?.sourceSessionId;
|
|
363
|
+
const key = parent ? state?.parents[parent] : void 0;
|
|
364
|
+
const parents = key ? inventory.sessions.filter((candidate) => candidate.sourceKey === key && candidate.parts.every((part) => !isRemoteImport(part.path))) : [];
|
|
365
|
+
const resolved = parents.length === 1 ? parents[0] : void 0;
|
|
366
|
+
if (!resolved || imports.some((copy) => copy.sourceSessionId !== parent)) return session.parts.some((part) => isRemoteImport(part.path)) ? [] : [session];
|
|
367
|
+
return [{
|
|
368
|
+
...session,
|
|
369
|
+
remoteParentSessionId: resolved.id
|
|
370
|
+
}];
|
|
371
|
+
});
|
|
372
|
+
return {
|
|
373
|
+
...inventory,
|
|
374
|
+
sessions
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
/** Reserved importer names never enter a later Send without that Send's consent receipt. */
|
|
378
|
+
function isRemoteImport(path) {
|
|
379
|
+
return /(?:^|[/\\])rollout-remote-[a-f0-9]{64}\.jsonl$/u.test(path) || /(?:^|[/\\])projects[/\\]remote-[a-f0-9]{16}[/\\][a-f0-9]{64}\.jsonl$/u.test(path);
|
|
380
|
+
}
|
|
381
|
+
//#endregion
|
|
8
382
|
//#region apps/cli/src/journey/plan.ts
|
|
9
|
-
async function prepareSourcePlan(storage, harnesses, journeyId, sensitiveTerms, signal, period = {}) {
|
|
383
|
+
async function prepareSourcePlan(storage, harnesses, journeyId, sensitiveTerms, signal, period = {}, stateDir) {
|
|
10
384
|
const saved = (await storage.resources({
|
|
11
385
|
journeyId,
|
|
12
386
|
kind: "plan"
|
|
@@ -14,7 +388,8 @@ async function prepareSourcePlan(storage, harnesses, journeyId, sensitiveTerms,
|
|
|
14
388
|
if (saved?.kind === "plan") return saved;
|
|
15
389
|
const discovered = await harnesses.discover(signal);
|
|
16
390
|
if (!discovered.complete) throw new ApplicationError("SCOPE_NOT_READY");
|
|
17
|
-
const
|
|
391
|
+
const linked = stateDir ? await attachRemoteWorkers(discovered, stateDir, journeyId) : discovered;
|
|
392
|
+
const inventory = filterInventoryByPeriod(linked, period);
|
|
18
393
|
if (inventory.sessions.length === 0) throw new ApplicationError("INVALID_SELECTION");
|
|
19
394
|
const families = reviewFamilies(inventory);
|
|
20
395
|
const defaults = defaultScopedSettings();
|
|
@@ -612,4 +987,4 @@ async function runJourneyOutputJob(job, live, signal, onPath) {
|
|
|
612
987
|
};
|
|
613
988
|
}
|
|
614
989
|
//#endregion
|
|
615
|
-
export { staticBaseProduction as _, writeJourneyOutput as a, mergeHideIndexTokens as c, runJourneyBaseJob as d, writeJourneyBase as f, staticBaseInputs as g, staticSessions as h, runJourneyOutputVerifyJob as i, packRenderHideIndex as l, saveStaticSession as m, runJourneyOutputJob as n, createHideIndexTokens as o, readStaticResult as p, runJourneyOutputShardJob as r, hideIndexTexts as s, journeyOutputJob as t, journeyBaseJob as u, prepareSourcePlan as v, workApproval as y };
|
|
990
|
+
export { journeyDirectory as C, saveRemoteState as S, staticBaseProduction as _, writeJourneyOutput as a, isRemoteImport as b, mergeHideIndexTokens as c, runJourneyBaseJob as d, writeJourneyBase as f, staticBaseInputs as g, staticSessions as h, runJourneyOutputVerifyJob as i, packRenderHideIndex as l, saveStaticSession as m, runJourneyOutputJob as n, createHideIndexTokens as o, readStaticResult as p, runJourneyOutputShardJob as r, hideIndexTexts as s, journeyOutputJob as t, journeyBaseJob as u, prepareSourcePlan as v, collectRemoteWorkers as w, readRemoteState as x, workApproval as y };
|