@akagilnc/pi-workflow-roles 0.1.4870 → 0.1.4885
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/acp-host/production-host.js +73 -42
- package/dist/archivist-record-entry.js +12 -14
- package/dist/headless-host/production-host.js +56 -25
- package/dist/migrate-book-topology.js +9 -34
- package/dist/pi/record-session-host.js +28 -0
- package/dist/role-run-relocation.js +2 -15
- package/package.json +1 -1
- package/scripts/build-package.mjs +1 -0
- package/src/archivist-record-entry.ts +26 -24
- package/src/book-topology-mixed-volume-migrators.ts +0 -15
- package/src/host-contracts.ts +37 -0
- package/src/pi/in-process-session.ts +3 -3
- package/src/pi/record-session-host.ts +30 -0
- package/src/role-run-relocation.ts +2 -17
- package/src/worker-submission-gates.ts +3 -3
|
@@ -587,6 +587,39 @@ var init_archivist_record_topology = __esm({
|
|
|
587
587
|
}
|
|
588
588
|
});
|
|
589
589
|
|
|
590
|
+
// src/pi/record-session-host.ts
|
|
591
|
+
import { existsSync } from "node:fs";
|
|
592
|
+
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
593
|
+
var piRecordSessionHost;
|
|
594
|
+
var init_record_session_host = __esm({
|
|
595
|
+
"src/pi/record-session-host.ts"() {
|
|
596
|
+
"use strict";
|
|
597
|
+
piRecordSessionHost = {
|
|
598
|
+
openRecordSession({ sessionFile, sessionDir, cwd }) {
|
|
599
|
+
return SessionManager.open(sessionFile, sessionDir, cwd);
|
|
600
|
+
},
|
|
601
|
+
createRecordSession({ cwd, sessionDir, parentSession }) {
|
|
602
|
+
return SessionManager.create(
|
|
603
|
+
cwd,
|
|
604
|
+
sessionDir,
|
|
605
|
+
parentSession === void 0 ? void 0 : { parentSession }
|
|
606
|
+
);
|
|
607
|
+
},
|
|
608
|
+
continueRecentRecordSession({ cwd, sessionDir }) {
|
|
609
|
+
const session = SessionManager.continueRecent(cwd, sessionDir);
|
|
610
|
+
const sessionFile = session.getSessionFile();
|
|
611
|
+
return {
|
|
612
|
+
session,
|
|
613
|
+
resumed: sessionFile !== void 0 && existsSync(sessionFile)
|
|
614
|
+
};
|
|
615
|
+
},
|
|
616
|
+
inMemoryRecordSession(cwd) {
|
|
617
|
+
return SessionManager.inMemory(cwd);
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
|
|
590
623
|
// src/archivist-record-entry.ts
|
|
591
624
|
var archivist_record_entry_exports = {};
|
|
592
625
|
__export(archivist_record_entry_exports, {
|
|
@@ -600,7 +633,7 @@ __export(archivist_record_entry_exports, {
|
|
|
600
633
|
});
|
|
601
634
|
import {
|
|
602
635
|
closeSync,
|
|
603
|
-
existsSync,
|
|
636
|
+
existsSync as existsSync2,
|
|
604
637
|
mkdirSync as mkdirSync2,
|
|
605
638
|
openSync,
|
|
606
639
|
readdirSync,
|
|
@@ -612,7 +645,6 @@ import {
|
|
|
612
645
|
} from "node:fs";
|
|
613
646
|
import { dirname as dirname3, resolve as resolve3, join as join4 } from "node:path";
|
|
614
647
|
import { StringDecoder } from "node:string_decoder";
|
|
615
|
-
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
616
648
|
function readCurrentSession(sessionDir) {
|
|
617
649
|
const ledger = join4(sessionDir, CURRENT_SESSION_LEDGER);
|
|
618
650
|
try {
|
|
@@ -763,7 +795,7 @@ function mostRecentNavigatorSessionFile(sessionDir, cwd) {
|
|
|
763
795
|
}
|
|
764
796
|
function resolveNavigatorNestContinuation(sessionDir, cwd) {
|
|
765
797
|
const ledgerPath = currentSessionLedgerPath(sessionDir);
|
|
766
|
-
if (
|
|
798
|
+
if (existsSync2(ledgerPath)) {
|
|
767
799
|
const recentFile = readCurrentSession(sessionDir);
|
|
768
800
|
assertRecentFinalFileUnderSessionDir(sessionDir, recentFile);
|
|
769
801
|
return recentFile;
|
|
@@ -815,7 +847,7 @@ function assertRecentFinalFileUnderSessionDir(sessionDir, recentFile) {
|
|
|
815
847
|
);
|
|
816
848
|
}
|
|
817
849
|
}
|
|
818
|
-
function createRecordSessionOpen(options) {
|
|
850
|
+
function createRecordSessionOpen(options, host = piRecordSessionHost) {
|
|
819
851
|
const cwd = options.cwd;
|
|
820
852
|
const parentFile = options.parent?.getSessionFile();
|
|
821
853
|
let sessionDir;
|
|
@@ -835,7 +867,7 @@ function createRecordSessionOpen(options) {
|
|
|
835
867
|
mayResumeSameNest = true;
|
|
836
868
|
} else if (parentFile === void 0 || parentFile.length === 0) {
|
|
837
869
|
if (options.subject === void 0) {
|
|
838
|
-
return { session:
|
|
870
|
+
return { session: host.inMemoryRecordSession(cwd), resumed: false };
|
|
839
871
|
}
|
|
840
872
|
throw new Error("Durable record ownership requires a parent session inside the ledger home");
|
|
841
873
|
} else {
|
|
@@ -848,34 +880,32 @@ function createRecordSessionOpen(options) {
|
|
|
848
880
|
parentSession = parentFile;
|
|
849
881
|
mayResumeSameNest = options.kind === WORKER_SUBMISSION_GATE_KIND;
|
|
850
882
|
}
|
|
851
|
-
const nestAlreadyExists =
|
|
883
|
+
const nestAlreadyExists = existsSync2(sessionDir);
|
|
852
884
|
ensureRealDirectoryTree(ledgerHome, sessionDir);
|
|
853
885
|
if (mayResumeSameNest && nestAlreadyExists) {
|
|
854
886
|
if (options.kind === NAVIGATOR_RECORD_KIND) {
|
|
855
887
|
const recentFile = resolveNavigatorNestContinuation(sessionDir, cwd);
|
|
856
888
|
if (recentFile !== void 0) {
|
|
857
889
|
return {
|
|
858
|
-
session:
|
|
890
|
+
session: host.openRecordSession({ sessionFile: recentFile, sessionDir, cwd }),
|
|
859
891
|
resumed: true
|
|
860
892
|
};
|
|
861
893
|
}
|
|
862
894
|
} else {
|
|
863
|
-
const
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
resumed: true
|
|
868
|
-
};
|
|
895
|
+
const continued = host.continueRecentRecordSession({ cwd, sessionDir });
|
|
896
|
+
if (continued.resumed) {
|
|
897
|
+
return continued;
|
|
898
|
+
}
|
|
869
899
|
}
|
|
870
900
|
}
|
|
871
|
-
const session =
|
|
901
|
+
const session = host.createRecordSession({
|
|
872
902
|
cwd,
|
|
873
903
|
sessionDir,
|
|
874
|
-
parentSession === void 0 ?
|
|
875
|
-
);
|
|
904
|
+
...parentSession === void 0 ? {} : { parentSession }
|
|
905
|
+
});
|
|
876
906
|
if (session.isPersisted()) {
|
|
877
907
|
const file = session.getSessionFile();
|
|
878
|
-
if (file !== void 0 && !
|
|
908
|
+
if (file !== void 0 && !existsSync2(file)) {
|
|
879
909
|
const header = session.getHeader();
|
|
880
910
|
if (header !== null && header.type === "session") {
|
|
881
911
|
writeFileSync(file, `${JSON.stringify(header)}
|
|
@@ -883,7 +913,7 @@ function createRecordSessionOpen(options) {
|
|
|
883
913
|
session.setSessionFile(file);
|
|
884
914
|
}
|
|
885
915
|
}
|
|
886
|
-
if (mayResumeSameNest && file !== void 0) {
|
|
916
|
+
if (options.kind === NAVIGATOR_RECORD_KIND && mayResumeSameNest && file !== void 0) {
|
|
887
917
|
writeCurrentSession(sessionDir, file);
|
|
888
918
|
}
|
|
889
919
|
}
|
|
@@ -916,6 +946,7 @@ var init_archivist_record_entry = __esm({
|
|
|
916
946
|
"use strict";
|
|
917
947
|
init_activation_ledger_topology();
|
|
918
948
|
init_archivist_record_topology();
|
|
949
|
+
init_record_session_host();
|
|
919
950
|
init_archivist_record_topology();
|
|
920
951
|
CURRENT_SESSION_LEDGER = "current-session.json";
|
|
921
952
|
SESSION_HEADER_CHUNK_BYTES = 4096;
|
|
@@ -5226,7 +5257,7 @@ var init_session_assistant_usage = __esm({
|
|
|
5226
5257
|
});
|
|
5227
5258
|
|
|
5228
5259
|
// src/package-resources/engine-material.ts
|
|
5229
|
-
import { existsSync as
|
|
5260
|
+
import { existsSync as existsSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
5230
5261
|
import { join as join10 } from "node:path";
|
|
5231
5262
|
function pickEngineAxis(source) {
|
|
5232
5263
|
return {
|
|
@@ -5269,7 +5300,7 @@ function engineSessionMaterialFromOptions(options) {
|
|
|
5269
5300
|
const model = options.engineModel === void 0 ? void 0 : assertLegalEngineModel(options.engineModel);
|
|
5270
5301
|
const materialPath = resolveEngineMaterialPath(options.packageRoot, name);
|
|
5271
5302
|
const modelField = model === void 0 ? {} : { model };
|
|
5272
|
-
if (
|
|
5303
|
+
if (existsSync3(materialPath)) {
|
|
5273
5304
|
return Object.freeze({ name, materialPath, ...modelField });
|
|
5274
5305
|
}
|
|
5275
5306
|
return Object.freeze({ name, ...modelField });
|
|
@@ -5472,7 +5503,7 @@ var init_sitian_contracts = __esm({
|
|
|
5472
5503
|
import { createHash as createHash5, randomUUID } from "node:crypto";
|
|
5473
5504
|
import {
|
|
5474
5505
|
appendFileSync,
|
|
5475
|
-
existsSync as
|
|
5506
|
+
existsSync as existsSync4,
|
|
5476
5507
|
readFileSync as readFileSync2,
|
|
5477
5508
|
unlinkSync,
|
|
5478
5509
|
writeFileSync as writeFileSync2
|
|
@@ -5492,14 +5523,14 @@ function createExclusiveFile(path, contents) {
|
|
|
5492
5523
|
writeFileSync2(path, contents, { encoding: "utf8", flag: "wx" });
|
|
5493
5524
|
}
|
|
5494
5525
|
function sealTornTail(recordFile) {
|
|
5495
|
-
if (!
|
|
5526
|
+
if (!existsSync4(recordFile)) return;
|
|
5496
5527
|
const buffer = readFileSync2(recordFile);
|
|
5497
5528
|
if (buffer.length > 0 && buffer[buffer.length - 1] !== 10) {
|
|
5498
5529
|
appendFileSync(recordFile, "\n", "utf8");
|
|
5499
5530
|
}
|
|
5500
5531
|
}
|
|
5501
5532
|
function findIdentityPointer(recordFile, identity, kind, level) {
|
|
5502
|
-
if (!
|
|
5533
|
+
if (!existsSync4(recordFile)) return void 0;
|
|
5503
5534
|
const text = readFileSync2(recordFile, "utf8");
|
|
5504
5535
|
for (const line2 of text.split("\n")) {
|
|
5505
5536
|
const trimmed = line2.trim();
|
|
@@ -5693,13 +5724,13 @@ var init_sitian_appender = __esm({
|
|
|
5693
5724
|
});
|
|
5694
5725
|
|
|
5695
5726
|
// src/sitian-reader.ts
|
|
5696
|
-
import { existsSync as
|
|
5727
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
5697
5728
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
5698
5729
|
function isRecord5(value) {
|
|
5699
5730
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5700
5731
|
}
|
|
5701
5732
|
async function readSitianRecords(recordFile) {
|
|
5702
|
-
if (!
|
|
5733
|
+
if (!existsSync5(recordFile)) {
|
|
5703
5734
|
return { records: [], diagnostics: [] };
|
|
5704
5735
|
}
|
|
5705
5736
|
const text = await readFile4(recordFile, "utf8");
|
|
@@ -9651,7 +9682,7 @@ var init_option_definitions = __esm({
|
|
|
9651
9682
|
|
|
9652
9683
|
// src/public-cli/invocation.ts
|
|
9653
9684
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
9654
|
-
import { existsSync as
|
|
9685
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
9655
9686
|
import {
|
|
9656
9687
|
lstat as lstat4,
|
|
9657
9688
|
mkdtemp as mkdtemp2,
|
|
@@ -9913,7 +9944,7 @@ async function bindTicketNumberOnRunDirectory(runDirectory, ticketNumber) {
|
|
|
9913
9944
|
`bindTicketNumberOnRunDirectory refuses to replace existing ticket #${existing} with #${ticketNumber}`
|
|
9914
9945
|
);
|
|
9915
9946
|
}
|
|
9916
|
-
if (
|
|
9947
|
+
if (existsSync6(invocationPath)) {
|
|
9917
9948
|
const invocation = JSON.parse(
|
|
9918
9949
|
await readFile10(invocationPath, "utf8")
|
|
9919
9950
|
);
|
|
@@ -11342,7 +11373,7 @@ var init_invocation = __esm({
|
|
|
11342
11373
|
});
|
|
11343
11374
|
|
|
11344
11375
|
// src/public-cli/load-production-acp-host.ts
|
|
11345
|
-
import { existsSync as
|
|
11376
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
11346
11377
|
import { join as join19 } from "node:path";
|
|
11347
11378
|
import { pathToFileURL } from "node:url";
|
|
11348
11379
|
async function loadProductionAcpHostFactory(packageRoot, host) {
|
|
@@ -11352,7 +11383,7 @@ async function loadProductionAcpHostFactory(packageRoot, host) {
|
|
|
11352
11383
|
}
|
|
11353
11384
|
const built = join19(packageRoot, "dist/acp-host/production-host.js");
|
|
11354
11385
|
const source = join19(packageRoot, "src/acp-host/production-host.ts");
|
|
11355
|
-
const target =
|
|
11386
|
+
const target = existsSync7(built) ? built : source;
|
|
11356
11387
|
const href = pathToFileURL(target).href;
|
|
11357
11388
|
const mod = await import(href);
|
|
11358
11389
|
const create = mod.createProductionAcpRoleTurnHost;
|
|
@@ -11366,7 +11397,7 @@ var init_load_production_acp_host = __esm({
|
|
|
11366
11397
|
});
|
|
11367
11398
|
|
|
11368
11399
|
// src/public-cli/load-production-headless-host.ts
|
|
11369
|
-
import { existsSync as
|
|
11400
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
11370
11401
|
import { join as join20 } from "node:path";
|
|
11371
11402
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
11372
11403
|
async function loadProductionHeadlessHostFactory(packageRoot, host) {
|
|
@@ -11376,7 +11407,7 @@ async function loadProductionHeadlessHostFactory(packageRoot, host) {
|
|
|
11376
11407
|
}
|
|
11377
11408
|
const built = join20(packageRoot, "dist/headless-host/production-host.js");
|
|
11378
11409
|
const source = join20(packageRoot, "src/headless-host/production-host.ts");
|
|
11379
|
-
const target =
|
|
11410
|
+
const target = existsSync8(built) ? built : source;
|
|
11380
11411
|
const href = pathToFileURL2(target).href;
|
|
11381
11412
|
const mod = await import(href);
|
|
11382
11413
|
const create = mod.createProductionHeadlessRoleTurnHost;
|
|
@@ -13242,14 +13273,14 @@ var init_submission_ledger = __esm({
|
|
|
13242
13273
|
});
|
|
13243
13274
|
|
|
13244
13275
|
// src/session-opening-materials.ts
|
|
13245
|
-
import { existsSync as
|
|
13276
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
13246
13277
|
import { readFile as readFile13 } from "node:fs/promises";
|
|
13247
13278
|
import { dirname as dirname12, join as join25 } from "node:path";
|
|
13248
13279
|
import { fileURLToPath, pathToFileURL as pathToFileURL3 } from "node:url";
|
|
13249
13280
|
function resolvePackageRootDir(moduleUrl = import.meta.url) {
|
|
13250
13281
|
let dir = dirname12(fileURLToPath(moduleUrl));
|
|
13251
13282
|
for (let i = 0; i < 8; i += 1) {
|
|
13252
|
-
if (
|
|
13283
|
+
if (existsSync9(join25(dir, "package.json")) && existsSync9(join25(dir, "souls"))) {
|
|
13253
13284
|
return dir;
|
|
13254
13285
|
}
|
|
13255
13286
|
const parent = dirname12(dir);
|
|
@@ -13637,7 +13668,7 @@ var init_engine_detour_usage = __esm({
|
|
|
13637
13668
|
});
|
|
13638
13669
|
|
|
13639
13670
|
// src/dossier-resolution.ts
|
|
13640
|
-
import { existsSync as
|
|
13671
|
+
import { existsSync as existsSync10, statSync as statSync3 } from "node:fs";
|
|
13641
13672
|
import { resolve as resolve10 } from "node:path";
|
|
13642
13673
|
function isHostContext(value) {
|
|
13643
13674
|
return "sessionManager" in value;
|
|
@@ -13657,7 +13688,7 @@ function resolveAuditDossier(source) {
|
|
|
13657
13688
|
}
|
|
13658
13689
|
const runDirectory = resolve10(raw);
|
|
13659
13690
|
try {
|
|
13660
|
-
if (!
|
|
13691
|
+
if (!existsSync10(runDirectory) || !statSync3(runDirectory).isDirectory()) {
|
|
13661
13692
|
return { status: "incomplete", observation: { kind: "missing-dossier" } };
|
|
13662
13693
|
}
|
|
13663
13694
|
} catch {
|
|
@@ -22640,7 +22671,7 @@ __export(public_role_summons_exports, {
|
|
|
22640
22671
|
withEphemeralReviewerWorktree: () => withEphemeralReviewerWorktree
|
|
22641
22672
|
});
|
|
22642
22673
|
import { execFile as execFile3 } from "node:child_process";
|
|
22643
|
-
import { existsSync as
|
|
22674
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
22644
22675
|
import { mkdir as mkdir4, mkdtemp as mkdtemp4, realpath as realpath7, rm as rm6 } from "node:fs/promises";
|
|
22645
22676
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
22646
22677
|
import { join as join40, relative as relative3, sep as sep5 } from "node:path";
|
|
@@ -22667,7 +22698,7 @@ function parentDir(path) {
|
|
|
22667
22698
|
function walkPackageRoot(start) {
|
|
22668
22699
|
let dir = start;
|
|
22669
22700
|
for (let i = 0; i < 12; i += 1) {
|
|
22670
|
-
if (
|
|
22701
|
+
if (existsSync11(join40(dir, "package.json")) && existsSync11(join40(dir, "souls"))) {
|
|
22671
22702
|
return dir;
|
|
22672
22703
|
}
|
|
22673
22704
|
const parent = parentDir(dir);
|
|
@@ -26406,7 +26437,7 @@ init_sitian_facade();
|
|
|
26406
26437
|
init_submission_errors();
|
|
26407
26438
|
init_submission_errors();
|
|
26408
26439
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
26409
|
-
import { existsSync as
|
|
26440
|
+
import { existsSync as existsSync12, lstatSync as lstatSync3, readdirSync as readdirSync3, readFileSync as readFileSync5, rmdirSync, rmSync } from "node:fs";
|
|
26410
26441
|
import { resolve as resolve18 } from "node:path";
|
|
26411
26442
|
var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
|
|
26412
26443
|
var WORKER_COMMIT_BASELINE_ENTRY_TYPE = "commit-baseline";
|
|
@@ -26437,7 +26468,7 @@ function statusOf(error) {
|
|
|
26437
26468
|
return typeof error === "object" && error !== null && "status" in error ? error.status : void 0;
|
|
26438
26469
|
}
|
|
26439
26470
|
function tryGetAll(file, key) {
|
|
26440
|
-
if (!
|
|
26471
|
+
if (!existsSync12(file)) return [];
|
|
26441
26472
|
try {
|
|
26442
26473
|
const out = gitFile(file, ["--get-all", key]);
|
|
26443
26474
|
return out.length === 0 ? [] : out.split("\n");
|
|
@@ -26447,7 +26478,7 @@ function tryGetAll(file, key) {
|
|
|
26447
26478
|
}
|
|
26448
26479
|
}
|
|
26449
26480
|
function ownedHook(path) {
|
|
26450
|
-
if (!
|
|
26481
|
+
if (!existsSync12(path)) return false;
|
|
26451
26482
|
return readFileSync5(path, "utf8").includes(HOOK_MARKER);
|
|
26452
26483
|
}
|
|
26453
26484
|
function escapeGitConfigValueRegex(value) {
|
|
@@ -26474,11 +26505,11 @@ function rmOwnedDir(dir) {
|
|
|
26474
26505
|
const hookPath = resolve18(dir, HOOK_FILE);
|
|
26475
26506
|
if (!ownedHook(hookPath)) return;
|
|
26476
26507
|
rmSync(hookPath, { force: true });
|
|
26477
|
-
if (
|
|
26508
|
+
if (existsSync12(dir) && readdirSync3(dir).length === 0) rmdirSync(dir);
|
|
26478
26509
|
}
|
|
26479
26510
|
function linkedGitDirs(commonDir) {
|
|
26480
26511
|
const root = resolve18(commonDir, "worktrees");
|
|
26481
|
-
if (!
|
|
26512
|
+
if (!existsSync12(root)) return [];
|
|
26482
26513
|
return readdirSync3(root).map((name) => resolve18(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
|
|
26483
26514
|
}
|
|
26484
26515
|
function uninstallPackageWorkerHooks(cwd) {
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
} from "node:fs";
|
|
13
13
|
import { dirname, resolve, join } from "node:path";
|
|
14
14
|
import { StringDecoder } from "node:string_decoder";
|
|
15
|
-
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
16
15
|
import {
|
|
17
16
|
ActivationLedgerError,
|
|
18
17
|
ensureRealDirectoryTree,
|
|
@@ -26,6 +25,7 @@ import {
|
|
|
26
25
|
NAVIGATOR_RECORD_KIND,
|
|
27
26
|
resolveNavigatorWorkSubjectPlacement
|
|
28
27
|
} from "./archivist-record-topology.js";
|
|
28
|
+
import { piRecordSessionHost } from "./pi/record-session-host.js";
|
|
29
29
|
import {
|
|
30
30
|
NAVIGATOR_RECORD_KIND as NAVIGATOR_RECORD_KIND2,
|
|
31
31
|
resolveNavigatorWorkSubjectPlacement as resolveNavigatorWorkSubjectPlacement2
|
|
@@ -236,7 +236,7 @@ function assertRecentFinalFileUnderSessionDir(sessionDir, recentFile) {
|
|
|
236
236
|
);
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
|
-
function createRecordSessionOpen(options) {
|
|
239
|
+
function createRecordSessionOpen(options, host = piRecordSessionHost) {
|
|
240
240
|
const cwd = options.cwd;
|
|
241
241
|
const parentFile = options.parent?.getSessionFile();
|
|
242
242
|
let sessionDir;
|
|
@@ -256,7 +256,7 @@ function createRecordSessionOpen(options) {
|
|
|
256
256
|
mayResumeSameNest = true;
|
|
257
257
|
} else if (parentFile === void 0 || parentFile.length === 0) {
|
|
258
258
|
if (options.subject === void 0) {
|
|
259
|
-
return { session:
|
|
259
|
+
return { session: host.inMemoryRecordSession(cwd), resumed: false };
|
|
260
260
|
}
|
|
261
261
|
throw new Error("Durable record ownership requires a parent session inside the ledger home");
|
|
262
262
|
} else {
|
|
@@ -276,24 +276,22 @@ function createRecordSessionOpen(options) {
|
|
|
276
276
|
const recentFile = resolveNavigatorNestContinuation(sessionDir, cwd);
|
|
277
277
|
if (recentFile !== void 0) {
|
|
278
278
|
return {
|
|
279
|
-
session:
|
|
279
|
+
session: host.openRecordSession({ sessionFile: recentFile, sessionDir, cwd }),
|
|
280
280
|
resumed: true
|
|
281
281
|
};
|
|
282
282
|
}
|
|
283
283
|
} else {
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
resumed: true
|
|
289
|
-
};
|
|
284
|
+
const continued = host.continueRecentRecordSession({ cwd, sessionDir });
|
|
285
|
+
if (continued.resumed) {
|
|
286
|
+
return continued;
|
|
287
|
+
}
|
|
290
288
|
}
|
|
291
289
|
}
|
|
292
|
-
const session =
|
|
290
|
+
const session = host.createRecordSession({
|
|
293
291
|
cwd,
|
|
294
292
|
sessionDir,
|
|
295
|
-
parentSession === void 0 ?
|
|
296
|
-
);
|
|
293
|
+
...parentSession === void 0 ? {} : { parentSession }
|
|
294
|
+
});
|
|
297
295
|
if (session.isPersisted()) {
|
|
298
296
|
const file = session.getSessionFile();
|
|
299
297
|
if (file !== void 0 && !existsSync(file)) {
|
|
@@ -304,7 +302,7 @@ function createRecordSessionOpen(options) {
|
|
|
304
302
|
session.setSessionFile(file);
|
|
305
303
|
}
|
|
306
304
|
}
|
|
307
|
-
if (mayResumeSameNest && file !== void 0) {
|
|
305
|
+
if (options.kind === NAVIGATOR_RECORD_KIND && mayResumeSameNest && file !== void 0) {
|
|
308
306
|
writeCurrentSession(sessionDir, file);
|
|
309
307
|
}
|
|
310
308
|
}
|
|
@@ -22954,6 +22954,39 @@ var init_archivist_record_topology = __esm({
|
|
|
22954
22954
|
}
|
|
22955
22955
|
});
|
|
22956
22956
|
|
|
22957
|
+
// src/pi/record-session-host.ts
|
|
22958
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
22959
|
+
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
22960
|
+
var piRecordSessionHost;
|
|
22961
|
+
var init_record_session_host = __esm({
|
|
22962
|
+
"src/pi/record-session-host.ts"() {
|
|
22963
|
+
"use strict";
|
|
22964
|
+
piRecordSessionHost = {
|
|
22965
|
+
openRecordSession({ sessionFile, sessionDir, cwd }) {
|
|
22966
|
+
return SessionManager.open(sessionFile, sessionDir, cwd);
|
|
22967
|
+
},
|
|
22968
|
+
createRecordSession({ cwd, sessionDir, parentSession }) {
|
|
22969
|
+
return SessionManager.create(
|
|
22970
|
+
cwd,
|
|
22971
|
+
sessionDir,
|
|
22972
|
+
parentSession === void 0 ? void 0 : { parentSession }
|
|
22973
|
+
);
|
|
22974
|
+
},
|
|
22975
|
+
continueRecentRecordSession({ cwd, sessionDir }) {
|
|
22976
|
+
const session = SessionManager.continueRecent(cwd, sessionDir);
|
|
22977
|
+
const sessionFile = session.getSessionFile();
|
|
22978
|
+
return {
|
|
22979
|
+
session,
|
|
22980
|
+
resumed: sessionFile !== void 0 && existsSync10(sessionFile)
|
|
22981
|
+
};
|
|
22982
|
+
},
|
|
22983
|
+
inMemoryRecordSession(cwd) {
|
|
22984
|
+
return SessionManager.inMemory(cwd);
|
|
22985
|
+
}
|
|
22986
|
+
};
|
|
22987
|
+
}
|
|
22988
|
+
});
|
|
22989
|
+
|
|
22957
22990
|
// src/archivist-record-entry.ts
|
|
22958
22991
|
var archivist_record_entry_exports = {};
|
|
22959
22992
|
__export(archivist_record_entry_exports, {
|
|
@@ -22967,7 +23000,7 @@ __export(archivist_record_entry_exports, {
|
|
|
22967
23000
|
});
|
|
22968
23001
|
import {
|
|
22969
23002
|
closeSync,
|
|
22970
|
-
existsSync as
|
|
23003
|
+
existsSync as existsSync11,
|
|
22971
23004
|
mkdirSync as mkdirSync2,
|
|
22972
23005
|
openSync,
|
|
22973
23006
|
readdirSync as readdirSync2,
|
|
@@ -22979,7 +23012,6 @@ import {
|
|
|
22979
23012
|
} from "node:fs";
|
|
22980
23013
|
import { dirname as dirname20, resolve as resolve15, join as join40 } from "node:path";
|
|
22981
23014
|
import { StringDecoder } from "node:string_decoder";
|
|
22982
|
-
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
22983
23015
|
function readCurrentSession(sessionDir) {
|
|
22984
23016
|
const ledger = join40(sessionDir, CURRENT_SESSION_LEDGER);
|
|
22985
23017
|
try {
|
|
@@ -23130,7 +23162,7 @@ function mostRecentNavigatorSessionFile(sessionDir, cwd) {
|
|
|
23130
23162
|
}
|
|
23131
23163
|
function resolveNavigatorNestContinuation(sessionDir, cwd) {
|
|
23132
23164
|
const ledgerPath = currentSessionLedgerPath(sessionDir);
|
|
23133
|
-
if (
|
|
23165
|
+
if (existsSync11(ledgerPath)) {
|
|
23134
23166
|
const recentFile = readCurrentSession(sessionDir);
|
|
23135
23167
|
assertRecentFinalFileUnderSessionDir(sessionDir, recentFile);
|
|
23136
23168
|
return recentFile;
|
|
@@ -23182,7 +23214,7 @@ function assertRecentFinalFileUnderSessionDir(sessionDir, recentFile) {
|
|
|
23182
23214
|
);
|
|
23183
23215
|
}
|
|
23184
23216
|
}
|
|
23185
|
-
function createRecordSessionOpen(options) {
|
|
23217
|
+
function createRecordSessionOpen(options, host = piRecordSessionHost) {
|
|
23186
23218
|
const cwd = options.cwd;
|
|
23187
23219
|
const parentFile = options.parent?.getSessionFile();
|
|
23188
23220
|
let sessionDir;
|
|
@@ -23202,7 +23234,7 @@ function createRecordSessionOpen(options) {
|
|
|
23202
23234
|
mayResumeSameNest = true;
|
|
23203
23235
|
} else if (parentFile === void 0 || parentFile.length === 0) {
|
|
23204
23236
|
if (options.subject === void 0) {
|
|
23205
|
-
return { session:
|
|
23237
|
+
return { session: host.inMemoryRecordSession(cwd), resumed: false };
|
|
23206
23238
|
}
|
|
23207
23239
|
throw new Error("Durable record ownership requires a parent session inside the ledger home");
|
|
23208
23240
|
} else {
|
|
@@ -23215,34 +23247,32 @@ function createRecordSessionOpen(options) {
|
|
|
23215
23247
|
parentSession = parentFile;
|
|
23216
23248
|
mayResumeSameNest = options.kind === WORKER_SUBMISSION_GATE_KIND;
|
|
23217
23249
|
}
|
|
23218
|
-
const nestAlreadyExists =
|
|
23250
|
+
const nestAlreadyExists = existsSync11(sessionDir);
|
|
23219
23251
|
ensureRealDirectoryTree(ledgerHome, sessionDir);
|
|
23220
23252
|
if (mayResumeSameNest && nestAlreadyExists) {
|
|
23221
23253
|
if (options.kind === NAVIGATOR_RECORD_KIND) {
|
|
23222
23254
|
const recentFile = resolveNavigatorNestContinuation(sessionDir, cwd);
|
|
23223
23255
|
if (recentFile !== void 0) {
|
|
23224
23256
|
return {
|
|
23225
|
-
session:
|
|
23257
|
+
session: host.openRecordSession({ sessionFile: recentFile, sessionDir, cwd }),
|
|
23226
23258
|
resumed: true
|
|
23227
23259
|
};
|
|
23228
23260
|
}
|
|
23229
23261
|
} else {
|
|
23230
|
-
const
|
|
23231
|
-
|
|
23232
|
-
|
|
23233
|
-
|
|
23234
|
-
resumed: true
|
|
23235
|
-
};
|
|
23262
|
+
const continued = host.continueRecentRecordSession({ cwd, sessionDir });
|
|
23263
|
+
if (continued.resumed) {
|
|
23264
|
+
return continued;
|
|
23265
|
+
}
|
|
23236
23266
|
}
|
|
23237
23267
|
}
|
|
23238
|
-
const session =
|
|
23268
|
+
const session = host.createRecordSession({
|
|
23239
23269
|
cwd,
|
|
23240
23270
|
sessionDir,
|
|
23241
|
-
parentSession === void 0 ?
|
|
23242
|
-
);
|
|
23271
|
+
...parentSession === void 0 ? {} : { parentSession }
|
|
23272
|
+
});
|
|
23243
23273
|
if (session.isPersisted()) {
|
|
23244
23274
|
const file = session.getSessionFile();
|
|
23245
|
-
if (file !== void 0 && !
|
|
23275
|
+
if (file !== void 0 && !existsSync11(file)) {
|
|
23246
23276
|
const header = session.getHeader();
|
|
23247
23277
|
if (header !== null && header.type === "session") {
|
|
23248
23278
|
writeFileSync2(file, `${JSON.stringify(header)}
|
|
@@ -23250,7 +23280,7 @@ function createRecordSessionOpen(options) {
|
|
|
23250
23280
|
session.setSessionFile(file);
|
|
23251
23281
|
}
|
|
23252
23282
|
}
|
|
23253
|
-
if (mayResumeSameNest && file !== void 0) {
|
|
23283
|
+
if (options.kind === NAVIGATOR_RECORD_KIND && mayResumeSameNest && file !== void 0) {
|
|
23254
23284
|
writeCurrentSession(sessionDir, file);
|
|
23255
23285
|
}
|
|
23256
23286
|
}
|
|
@@ -23283,6 +23313,7 @@ var init_archivist_record_entry = __esm({
|
|
|
23283
23313
|
"use strict";
|
|
23284
23314
|
init_activation_ledger_topology();
|
|
23285
23315
|
init_archivist_record_topology();
|
|
23316
|
+
init_record_session_host();
|
|
23286
23317
|
init_archivist_record_topology();
|
|
23287
23318
|
CURRENT_SESSION_LEDGER = "current-session.json";
|
|
23288
23319
|
SESSION_HEADER_CHUNK_BYTES = 4096;
|
|
@@ -26363,7 +26394,7 @@ init_sitian_facade();
|
|
|
26363
26394
|
init_submission_errors();
|
|
26364
26395
|
init_submission_errors();
|
|
26365
26396
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
26366
|
-
import { existsSync as
|
|
26397
|
+
import { existsSync as existsSync12, lstatSync as lstatSync3, readdirSync as readdirSync3, readFileSync as readFileSync5, rmdirSync, rmSync } from "node:fs";
|
|
26367
26398
|
import { resolve as resolve20 } from "node:path";
|
|
26368
26399
|
var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
|
|
26369
26400
|
var WORKER_COMMIT_BASELINE_ENTRY_TYPE = "commit-baseline";
|
|
@@ -26394,7 +26425,7 @@ function statusOf(error) {
|
|
|
26394
26425
|
return typeof error === "object" && error !== null && "status" in error ? error.status : void 0;
|
|
26395
26426
|
}
|
|
26396
26427
|
function tryGetAll(file, key) {
|
|
26397
|
-
if (!
|
|
26428
|
+
if (!existsSync12(file)) return [];
|
|
26398
26429
|
try {
|
|
26399
26430
|
const out = gitFile(file, ["--get-all", key]);
|
|
26400
26431
|
return out.length === 0 ? [] : out.split("\n");
|
|
@@ -26404,7 +26435,7 @@ function tryGetAll(file, key) {
|
|
|
26404
26435
|
}
|
|
26405
26436
|
}
|
|
26406
26437
|
function ownedHook(path) {
|
|
26407
|
-
if (!
|
|
26438
|
+
if (!existsSync12(path)) return false;
|
|
26408
26439
|
return readFileSync5(path, "utf8").includes(HOOK_MARKER);
|
|
26409
26440
|
}
|
|
26410
26441
|
function escapeGitConfigValueRegex(value) {
|
|
@@ -26431,11 +26462,11 @@ function rmOwnedDir(dir) {
|
|
|
26431
26462
|
const hookPath = resolve20(dir, HOOK_FILE);
|
|
26432
26463
|
if (!ownedHook(hookPath)) return;
|
|
26433
26464
|
rmSync(hookPath, { force: true });
|
|
26434
|
-
if (
|
|
26465
|
+
if (existsSync12(dir) && readdirSync3(dir).length === 0) rmdirSync(dir);
|
|
26435
26466
|
}
|
|
26436
26467
|
function linkedGitDirs(commonDir) {
|
|
26437
26468
|
const root = resolve20(commonDir, "worktrees");
|
|
26438
|
-
if (!
|
|
26469
|
+
if (!existsSync12(root)) return [];
|
|
26439
26470
|
return readdirSync3(root).map((name) => resolve20(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
|
|
26440
26471
|
}
|
|
26441
26472
|
function uninstallPackageWorkerHooks(cwd) {
|
|
@@ -29705,7 +29736,7 @@ function headlessMcpConfigDocument(mcpServers) {
|
|
|
29705
29736
|
// src/headless-host/role-turn-host.ts
|
|
29706
29737
|
import { spawn as spawn4, spawnSync } from "node:child_process";
|
|
29707
29738
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
29708
|
-
import { existsSync as
|
|
29739
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
29709
29740
|
import { writeFile as writeFile12 } from "node:fs/promises";
|
|
29710
29741
|
import { dirname as dirname26, isAbsolute as isAbsolute12, join as join48, resolve as resolve21 } from "node:path";
|
|
29711
29742
|
|
|
@@ -29927,7 +29958,7 @@ function formatCodexFailurePayload(payload) {
|
|
|
29927
29958
|
function cwdIsGitWorkTree(cwd) {
|
|
29928
29959
|
let dir = cwd;
|
|
29929
29960
|
for (; ; ) {
|
|
29930
|
-
if (
|
|
29961
|
+
if (existsSync13(join48(dir, ".git"))) return true;
|
|
29931
29962
|
const parent = dirname26(dir);
|
|
29932
29963
|
if (parent === dir) return false;
|
|
29933
29964
|
dir = parent;
|
|
@@ -14644,14 +14644,6 @@ function rewriteAdmittedRoleRunPage(page, rewrites) {
|
|
|
14644
14644
|
);
|
|
14645
14645
|
}
|
|
14646
14646
|
}
|
|
14647
|
-
async function rewriteJsonObjectFile(path7, fields, rewrites) {
|
|
14648
|
-
if (!existsSync(path7)) return;
|
|
14649
|
-
const page = JSON.parse(await readFile2(path7, "utf8"));
|
|
14650
|
-
if (!isPlainObject(page)) return;
|
|
14651
|
-
rewriteRunDirectoryPathFieldsAgainstRewrites(page, fields, rewrites);
|
|
14652
|
-
await writeFile(path7, `${JSON.stringify(page, null, 2)}
|
|
14653
|
-
`, "utf8");
|
|
14654
|
-
}
|
|
14655
14647
|
async function rewriteOfficerPointerFile(path7, rewrites) {
|
|
14656
14648
|
if (!existsSync(path7)) return;
|
|
14657
14649
|
const page = JSON.parse(await readFile2(path7, "utf8"));
|
|
@@ -14793,9 +14785,7 @@ async function rewriteNestedMachinePathPages(pagesDirectory, rewrites) {
|
|
|
14793
14785
|
continue;
|
|
14794
14786
|
}
|
|
14795
14787
|
if (!entry.isFile()) continue;
|
|
14796
|
-
if (entry.name
|
|
14797
|
-
await rewriteJsonObjectFile(path7, CURRENT_SESSION_FIELDS, rewrites);
|
|
14798
|
-
} else if (entry.name.endsWith(".pointer.json")) {
|
|
14788
|
+
if (entry.name.endsWith(".pointer.json")) {
|
|
14799
14789
|
await rewriteOfficerPointerFile(path7, rewrites);
|
|
14800
14790
|
} else if (entry.name === "records.jsonl") {
|
|
14801
14791
|
await rewriteSitianRecordsJsonl(path7, rewrites);
|
|
@@ -14854,7 +14844,7 @@ async function rewriteRoleRunDurablePages(input) {
|
|
|
14854
14844
|
}
|
|
14855
14845
|
await rewriteNestedMachinePathPages(pagesDirectory, rewrites);
|
|
14856
14846
|
}
|
|
14857
|
-
var ADMITTED_PAGE_FIELDS, INVOCATION_PAGE_FIELDS, RUN_STATE_PAGE_FIELDS, SOURCE_RUN_LOCATOR_FIELDS, SUMMONS_PATH_FIELDS,
|
|
14847
|
+
var ADMITTED_PAGE_FIELDS, INVOCATION_PAGE_FIELDS, RUN_STATE_PAGE_FIELDS, SOURCE_RUN_LOCATOR_FIELDS, SUMMONS_PATH_FIELDS, OFFICER_POINTER_FIELDS, SITIAN_RECORD_FIELDS, SESSION_HEADER_FIELDS, BINDING_PARENT_FIELDS;
|
|
14858
14848
|
var init_role_run_relocation = __esm({
|
|
14859
14849
|
"src/role-run-relocation.ts"() {
|
|
14860
14850
|
"use strict";
|
|
@@ -14884,7 +14874,6 @@ var init_role_run_relocation = __esm({
|
|
|
14884
14874
|
];
|
|
14885
14875
|
SOURCE_RUN_LOCATOR_FIELDS = ["runDirectory"];
|
|
14886
14876
|
SUMMONS_PATH_FIELDS = ["sourceRunPath"];
|
|
14887
|
-
CURRENT_SESSION_FIELDS = ["sessionFile"];
|
|
14888
14877
|
OFFICER_POINTER_FIELDS = ["sessionFile", "runDirectory"];
|
|
14889
14878
|
SITIAN_RECORD_FIELDS = ["sessionParent"];
|
|
14890
14879
|
SESSION_HEADER_FIELDS = ["parentSession"];
|
|
@@ -255467,6 +255456,13 @@ async function migrateBookTopology(input) {
|
|
|
255467
255456
|
import { appendFile, cp, lstat as lstat2, mkdir as mkdir2, readFile as readFile5, writeFile as writeFile4 } from "node:fs/promises";
|
|
255468
255457
|
import { dirname as dirname7, join as join12, relative as relative4, resolve as resolve6, sep as sep7 } from "node:path";
|
|
255469
255458
|
|
|
255459
|
+
// src/archivist-record-entry.ts
|
|
255460
|
+
init_activation_ledger_topology();
|
|
255461
|
+
|
|
255462
|
+
// src/archivist-record-topology.ts
|
|
255463
|
+
init_activation_ledger_git();
|
|
255464
|
+
init_activation_ledger_topology();
|
|
255465
|
+
|
|
255470
255466
|
// node_modules/.pnpm/@earendil-works+pi-coding-agent@0.84.1_ws@8.21.1_zod@4.4.3/node_modules/@earendil-works/pi-coding-agent/dist/config.js
|
|
255471
255467
|
import { accessSync, constants, existsSync as existsSync2, readFileSync, realpathSync as realpathSync2 } from "fs";
|
|
255472
255468
|
import { homedir as homedir3 } from "os";
|
|
@@ -277726,13 +277722,6 @@ var DEFAULT_PROJECT_TRUST_BY_LABEL = new Map(Object.entries(DEFAULT_PROJECT_TRUS
|
|
|
277726
277722
|
// node_modules/.pnpm/@earendil-works+pi-coding-agent@0.84.1_ws@8.21.1_zod@4.4.3/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js
|
|
277727
277723
|
var CONFIG_COMMAND_USAGE = `${APP_NAME} config [-l] [--approve|--no-approve]`;
|
|
277728
277724
|
|
|
277729
|
-
// src/archivist-record-entry.ts
|
|
277730
|
-
init_activation_ledger_topology();
|
|
277731
|
-
|
|
277732
|
-
// src/archivist-record-topology.ts
|
|
277733
|
-
init_activation_ledger_git();
|
|
277734
|
-
init_activation_ledger_topology();
|
|
277735
|
-
|
|
277736
277725
|
// src/archivist-record-entry.ts
|
|
277737
277726
|
var MAX_SESSION_HEADER_SCAN_BYTES2 = 1024 * 1024;
|
|
277738
277727
|
var WORKER_SUBMISSION_GATE_KIND = "worker-submission-gate";
|
|
@@ -278337,7 +278326,6 @@ async function migrateWorkerSubmissionGate(context2) {
|
|
|
278337
278326
|
if (entries.length === 0) continue;
|
|
278338
278327
|
const bookRoots = bookHistoricalRoots(booksDirectory, backupBooksDirectory, bookKey);
|
|
278339
278328
|
const volumes = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map((entry) => entry.name).sort();
|
|
278340
|
-
const volumeDestinations = /* @__PURE__ */ new Map();
|
|
278341
278329
|
for (const name of volumes) {
|
|
278342
278330
|
const sourcePath = join12(sourceDir, name);
|
|
278343
278331
|
const source = posixRelative(backupBooksDirectory, sourcePath);
|
|
@@ -278360,8 +278348,6 @@ async function migrateWorkerSubmissionGate(context2) {
|
|
|
278360
278348
|
);
|
|
278361
278349
|
await mkdir2(dirname7(dest), { recursive: true });
|
|
278362
278350
|
await cp(sourcePath, dest, { preserveTimestamps: true });
|
|
278363
|
-
volumeDestinations.set(resolve6(sourcePath), dest);
|
|
278364
|
-
volumeDestinations.set(resolve6(join12(booksDirectory, bookKey, kind, name)), dest);
|
|
278365
278351
|
outcomes.push({
|
|
278366
278352
|
disposition: destRun?.disposition === "placed" ? "placed" : "unbound",
|
|
278367
278353
|
source
|
|
@@ -278373,17 +278359,6 @@ async function migrateWorkerSubmissionGate(context2) {
|
|
|
278373
278359
|
});
|
|
278374
278360
|
}
|
|
278375
278361
|
}
|
|
278376
|
-
await migrateCurrentSessionPointer({
|
|
278377
|
-
sourceDir,
|
|
278378
|
-
volumeDestinations,
|
|
278379
|
-
unboundPointerFile: join12(
|
|
278380
|
-
booksDirectory,
|
|
278381
|
-
bookKey,
|
|
278382
|
-
"unbound",
|
|
278383
|
-
kind,
|
|
278384
|
-
CURRENT_SESSION_LEDGER
|
|
278385
|
-
)
|
|
278386
|
-
});
|
|
278387
278362
|
}
|
|
278388
278363
|
const report = reconcileMigrationPartition(kind, "entries", outcomes);
|
|
278389
278364
|
return {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
const piRecordSessionHost = {
|
|
4
|
+
openRecordSession({ sessionFile, sessionDir, cwd }) {
|
|
5
|
+
return SessionManager.open(sessionFile, sessionDir, cwd);
|
|
6
|
+
},
|
|
7
|
+
createRecordSession({ cwd, sessionDir, parentSession }) {
|
|
8
|
+
return SessionManager.create(
|
|
9
|
+
cwd,
|
|
10
|
+
sessionDir,
|
|
11
|
+
parentSession === void 0 ? void 0 : { parentSession }
|
|
12
|
+
);
|
|
13
|
+
},
|
|
14
|
+
continueRecentRecordSession({ cwd, sessionDir }) {
|
|
15
|
+
const session = SessionManager.continueRecent(cwd, sessionDir);
|
|
16
|
+
const sessionFile = session.getSessionFile();
|
|
17
|
+
return {
|
|
18
|
+
session,
|
|
19
|
+
resumed: sessionFile !== void 0 && existsSync(sessionFile)
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
inMemoryRecordSession(cwd) {
|
|
23
|
+
return SessionManager.inMemory(cwd);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export {
|
|
27
|
+
piRecordSessionHost
|
|
28
|
+
};
|
|
@@ -35,7 +35,6 @@ const RUN_STATE_PAGE_FIELDS = [
|
|
|
35
35
|
];
|
|
36
36
|
const SOURCE_RUN_LOCATOR_FIELDS = ["runDirectory"];
|
|
37
37
|
const SUMMONS_PATH_FIELDS = ["sourceRunPath"];
|
|
38
|
-
const CURRENT_SESSION_FIELDS = ["sessionFile"];
|
|
39
38
|
const OFFICER_POINTER_FIELDS = ["sessionFile", "runDirectory"];
|
|
40
39
|
const SITIAN_RECORD_FIELDS = ["sessionParent"];
|
|
41
40
|
const SESSION_HEADER_FIELDS = ["parentSession"];
|
|
@@ -147,15 +146,6 @@ export function rewriteAdmittedRoleRunPage(page, rewrites) {
|
|
|
147
146
|
rewriteRunDirectoryPathFieldsAgainstRewrites(page.principal, ["sessionDirectory", "sessionFile"], rewrites);
|
|
148
147
|
}
|
|
149
148
|
}
|
|
150
|
-
async function rewriteJsonObjectFile(path, fields, rewrites) {
|
|
151
|
-
if (!existsSync(path))
|
|
152
|
-
return;
|
|
153
|
-
const page = JSON.parse(await readFile(path, "utf8"));
|
|
154
|
-
if (!isPlainObject(page))
|
|
155
|
-
return;
|
|
156
|
-
rewriteRunDirectoryPathFieldsAgainstRewrites(page, fields, rewrites);
|
|
157
|
-
await writeFile(path, `${JSON.stringify(page, null, 2)}\n`, "utf8");
|
|
158
|
-
}
|
|
159
149
|
async function rewriteOfficerPointerFile(path, rewrites) {
|
|
160
150
|
if (!existsSync(path))
|
|
161
151
|
return;
|
|
@@ -280,7 +270,7 @@ async function rewriteSessionTranscriptBindings(path, rewrites) {
|
|
|
280
270
|
}
|
|
281
271
|
/**
|
|
282
272
|
* Package-owned nested seams under session/ only:
|
|
283
|
-
*
|
|
273
|
+
* direct-officer *.pointer.json, sitian records.jsonl,
|
|
284
274
|
* session transcript typed parent bindings. Never walks attachments/ or artifacts/.
|
|
285
275
|
*/
|
|
286
276
|
async function rewriteNestedMachinePathPages(pagesDirectory, rewrites) {
|
|
@@ -303,10 +293,7 @@ async function rewriteNestedMachinePathPages(pagesDirectory, rewrites) {
|
|
|
303
293
|
}
|
|
304
294
|
if (!entry.isFile())
|
|
305
295
|
continue;
|
|
306
|
-
if (entry.name
|
|
307
|
-
await rewriteJsonObjectFile(path, CURRENT_SESSION_FIELDS, rewrites);
|
|
308
|
-
}
|
|
309
|
-
else if (entry.name.endsWith(".pointer.json")) {
|
|
296
|
+
if (entry.name.endsWith(".pointer.json")) {
|
|
310
297
|
await rewriteOfficerPointerFile(path, rewrites);
|
|
311
298
|
}
|
|
312
299
|
else if (entry.name === "records.jsonl") {
|
package/package.json
CHANGED
|
@@ -20,6 +20,7 @@ const entries = [
|
|
|
20
20
|
"activation-ledger-git",
|
|
21
21
|
"activation-ledger-topology",
|
|
22
22
|
"archivist-record-entry",
|
|
23
|
+
"pi/record-session-host",
|
|
23
24
|
// Pure subject nest topology — static import of archivist-record-entry;
|
|
24
25
|
// cold discovery without SessionManager (#636). Keep listed while that
|
|
25
26
|
// relative edge remains (#857 removal left the import graph open).
|
|
@@ -17,8 +17,6 @@ import {
|
|
|
17
17
|
} from "node:fs";
|
|
18
18
|
import { dirname, resolve, join } from "node:path";
|
|
19
19
|
import { StringDecoder } from "node:string_decoder";
|
|
20
|
-
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
21
|
-
|
|
22
20
|
import {
|
|
23
21
|
ActivationLedgerError,
|
|
24
22
|
ensureRealDirectoryTree,
|
|
@@ -32,6 +30,8 @@ import {
|
|
|
32
30
|
NAVIGATOR_RECORD_KIND,
|
|
33
31
|
resolveNavigatorWorkSubjectPlacement,
|
|
34
32
|
} from "./archivist-record-topology.ts";
|
|
33
|
+
import type { HostRecordSession, RecordSessionHost } from "./host-contracts.ts";
|
|
34
|
+
import { piRecordSessionHost } from "./pi/record-session-host.ts";
|
|
35
35
|
|
|
36
36
|
export {
|
|
37
37
|
NAVIGATOR_RECORD_KIND,
|
|
@@ -355,27 +355,29 @@ function assertRecentFinalFileUnderSessionDir(
|
|
|
355
355
|
|
|
356
356
|
/** Open result including the sole continuation fact. */
|
|
357
357
|
export type RecordSessionOpen = {
|
|
358
|
-
readonly session:
|
|
359
|
-
/** True when an existing navigator work-subject or worker-submission-gate volume was
|
|
358
|
+
readonly session: HostRecordSession;
|
|
359
|
+
/** True when an existing navigator work-subject or worker-submission-gate volume was continued. */
|
|
360
360
|
readonly resumed: boolean;
|
|
361
361
|
};
|
|
362
362
|
|
|
363
363
|
/**
|
|
364
364
|
* Sole package entry that constructs a durable Pi session record (ADR 0065).
|
|
365
365
|
* No destination/path parameters — location is computed from ledger topology only.
|
|
366
|
-
* SessionDir placement is owned by ensureRealDirectoryTree
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
* nests and the authorized worker-submission-gate durable path (ADR 0066 / #852).
|
|
366
|
+
* SessionDir placement is owned by ensureRealDirectoryTree. Navigator sidecar targets
|
|
367
|
+
* are checked once before host open (the directory walk cannot see a trailing .jsonl
|
|
368
|
+
* symlink). New principals mint under the already-validated sessionDir.
|
|
369
|
+
* Navigator work-subject nests use their AK ledger; worker-submission-gate asks the
|
|
370
|
+
* host to continue its recent native session without selecting a stored file path.
|
|
372
371
|
* Other ordinary no-subject children (auditor-roles, …) always mint fresh.
|
|
373
372
|
* New persisted principals materialize their deferred session header before return so
|
|
374
373
|
* custom-entry-only writers do not need a parallel delayed-header helper.
|
|
375
374
|
*
|
|
376
375
|
* `resumed` is the sole open-or-continue fact — callers must not re-probe nest existence.
|
|
377
376
|
*/
|
|
378
|
-
export function createRecordSessionOpen(
|
|
377
|
+
export function createRecordSessionOpen(
|
|
378
|
+
options: CreateRecordSessionOptions,
|
|
379
|
+
host: RecordSessionHost = piRecordSessionHost,
|
|
380
|
+
): RecordSessionOpen {
|
|
379
381
|
const cwd = options.cwd;
|
|
380
382
|
const parentFile = options.parent?.getSessionFile();
|
|
381
383
|
|
|
@@ -402,7 +404,7 @@ export function createRecordSessionOpen(options: CreateRecordSessionOptions): Re
|
|
|
402
404
|
} else if (parentFile === undefined || parentFile.length === 0) {
|
|
403
405
|
if (options.subject === undefined) {
|
|
404
406
|
// No durable principal requested: preserve prior in-memory child behavior.
|
|
405
|
-
return { session:
|
|
407
|
+
return { session: host.inMemoryRecordSession(cwd), resumed: false };
|
|
406
408
|
}
|
|
407
409
|
throw new Error("Durable record ownership requires a parent session inside the ledger home");
|
|
408
410
|
} else {
|
|
@@ -427,26 +429,26 @@ export function createRecordSessionOpen(options: CreateRecordSessionOptions): Re
|
|
|
427
429
|
const recentFile = resolveNavigatorNestContinuation(sessionDir, cwd);
|
|
428
430
|
if (recentFile !== undefined) {
|
|
429
431
|
return {
|
|
430
|
-
session:
|
|
432
|
+
session: host.openRecordSession({ sessionFile: recentFile, sessionDir, cwd }),
|
|
431
433
|
resumed: true,
|
|
432
434
|
};
|
|
433
435
|
}
|
|
434
436
|
// No sidecar and no cwd-matching session — mint fresh in the existing nest.
|
|
435
437
|
} else {
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
438
|
+
const continued = host.continueRecentRecordSession({ cwd, sessionDir });
|
|
439
|
+
if (continued.resumed) {
|
|
440
|
+
return continued;
|
|
441
|
+
}
|
|
442
|
+
// Pi's native continuation falls back to an unparented fresh session. The
|
|
443
|
+
// archivist owns the durable parent, so mint through the ordinary fresh path.
|
|
442
444
|
}
|
|
443
445
|
}
|
|
444
446
|
|
|
445
|
-
const session =
|
|
447
|
+
const session = host.createRecordSession({
|
|
446
448
|
cwd,
|
|
447
449
|
sessionDir,
|
|
448
|
-
parentSession === undefined ?
|
|
449
|
-
);
|
|
450
|
+
...(parentSession === undefined ? {} : { parentSession }),
|
|
451
|
+
});
|
|
450
452
|
// Pi defers session-file create until the first assistant message. Custom-entry-only
|
|
451
453
|
// records never get that turn, so the sole record entry materializes the in-memory
|
|
452
454
|
// header onto the UUIDv7 path before returning. Existing path → early return.
|
|
@@ -460,7 +462,7 @@ export function createRecordSessionOpen(options: CreateRecordSessionOptions): Re
|
|
|
460
462
|
session.setSessionFile(file);
|
|
461
463
|
}
|
|
462
464
|
}
|
|
463
|
-
if (mayResumeSameNest && file !== undefined) {
|
|
465
|
+
if (options.kind === NAVIGATOR_RECORD_KIND && mayResumeSameNest && file !== undefined) {
|
|
464
466
|
writeCurrentSession(sessionDir, file);
|
|
465
467
|
}
|
|
466
468
|
}
|
|
@@ -468,7 +470,7 @@ export function createRecordSessionOpen(options: CreateRecordSessionOptions): Re
|
|
|
468
470
|
}
|
|
469
471
|
|
|
470
472
|
/** Session-only facade — most callers only need the manager. */
|
|
471
|
-
export function createRecordSession(options: CreateRecordSessionOptions):
|
|
473
|
+
export function createRecordSession(options: CreateRecordSessionOptions): HostRecordSession {
|
|
472
474
|
return createRecordSessionOpen(options).session;
|
|
473
475
|
}
|
|
474
476
|
|
|
@@ -391,7 +391,6 @@ async function migrateWorkerSubmissionGate(
|
|
|
391
391
|
.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl"))
|
|
392
392
|
.map((entry) => entry.name)
|
|
393
393
|
.sort();
|
|
394
|
-
const volumeDestinations = new Map<string, string>();
|
|
395
394
|
|
|
396
395
|
for (const name of volumes) {
|
|
397
396
|
const sourcePath = join(sourceDir, name);
|
|
@@ -417,8 +416,6 @@ async function migrateWorkerSubmissionGate(
|
|
|
417
416
|
);
|
|
418
417
|
await mkdir(dirname(dest), { recursive: true });
|
|
419
418
|
await cp(sourcePath, dest, { preserveTimestamps: true });
|
|
420
|
-
volumeDestinations.set(resolve(sourcePath), dest);
|
|
421
|
-
volumeDestinations.set(resolve(join(booksDirectory, bookKey, kind, name)), dest);
|
|
422
419
|
// One outcome per volume keeps the entries closure; bad rows attach below.
|
|
423
420
|
outcomes.push({
|
|
424
421
|
disposition: destRun?.disposition === "placed" ? "placed" : "unbound",
|
|
@@ -431,18 +428,6 @@ async function migrateWorkerSubmissionGate(
|
|
|
431
428
|
});
|
|
432
429
|
}
|
|
433
430
|
}
|
|
434
|
-
|
|
435
|
-
await migrateCurrentSessionPointer({
|
|
436
|
-
sourceDir,
|
|
437
|
-
volumeDestinations,
|
|
438
|
-
unboundPointerFile: join(
|
|
439
|
-
booksDirectory,
|
|
440
|
-
bookKey,
|
|
441
|
-
"unbound",
|
|
442
|
-
kind,
|
|
443
|
-
CURRENT_SESSION_LEDGER,
|
|
444
|
-
),
|
|
445
|
-
});
|
|
446
431
|
}
|
|
447
432
|
|
|
448
433
|
const report = reconcileMigrationPartition(kind, "entries", outcomes);
|
package/src/host-contracts.ts
CHANGED
|
@@ -532,3 +532,40 @@ export interface InstitutionalSessionHost {
|
|
|
532
532
|
): Promise<HostInstitutionalSessionHandle>;
|
|
533
533
|
}
|
|
534
534
|
|
|
535
|
+
/** Host-owned durable record session used by AK ledger placement. */
|
|
536
|
+
export interface HostRecordSession {
|
|
537
|
+
getSessionFile(): string | undefined;
|
|
538
|
+
getSessionDir(): string;
|
|
539
|
+
getEntries(): readonly {
|
|
540
|
+
readonly type: string;
|
|
541
|
+
readonly customType?: string;
|
|
542
|
+
readonly data?: unknown;
|
|
543
|
+
}[];
|
|
544
|
+
getHeader(): { readonly type: string } | null;
|
|
545
|
+
isPersisted(): boolean;
|
|
546
|
+
setSessionFile(path: string): void;
|
|
547
|
+
appendCustomEntry(customType: string, data?: unknown): unknown;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/** Host session lifecycle seam; native selection stays inside its adapter. */
|
|
551
|
+
export interface RecordSessionHost {
|
|
552
|
+
openRecordSession(options: {
|
|
553
|
+
readonly sessionFile: string;
|
|
554
|
+
readonly sessionDir: string;
|
|
555
|
+
readonly cwd: string;
|
|
556
|
+
}): HostRecordSession;
|
|
557
|
+
createRecordSession(options: {
|
|
558
|
+
readonly cwd: string;
|
|
559
|
+
readonly sessionDir: string;
|
|
560
|
+
readonly parentSession?: string;
|
|
561
|
+
}): HostRecordSession;
|
|
562
|
+
continueRecentRecordSession(options: {
|
|
563
|
+
readonly cwd: string;
|
|
564
|
+
readonly sessionDir: string;
|
|
565
|
+
}): {
|
|
566
|
+
readonly session: HostRecordSession;
|
|
567
|
+
/** Whether the host continued an existing session rather than falling back to a new one. */
|
|
568
|
+
readonly resumed: boolean;
|
|
569
|
+
};
|
|
570
|
+
inMemoryRecordSession(cwd: string): HostRecordSession;
|
|
571
|
+
}
|
|
@@ -62,6 +62,7 @@ function streamIdleTimeoutFromUnknown(value: unknown): StreamIdleTimeoutError |
|
|
|
62
62
|
: undefined;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
|
|
65
66
|
// ── Stream / remote error projection helpers ───────────────────────────────
|
|
66
67
|
|
|
67
68
|
function emptyUsage(): Usage {
|
|
@@ -599,12 +600,12 @@ export async function openPiInProcessSession(
|
|
|
599
600
|
kind: options.sessionIdentity.kind,
|
|
600
601
|
...(options.sessionIdentity.subject === undefined ? {} : { subject: options.sessionIdentity.subject }),
|
|
601
602
|
...(options.sessionIdentity.parent === undefined ? {} : { parent: options.sessionIdentity.parent }),
|
|
602
|
-
});
|
|
603
|
+
}) as SessionManager;
|
|
603
604
|
} else {
|
|
604
605
|
sessionManager = createRecordSession({
|
|
605
606
|
cwd: options.cwd,
|
|
606
607
|
kind: "institutional",
|
|
607
|
-
});
|
|
608
|
+
}) as SessionManager;
|
|
608
609
|
}
|
|
609
610
|
|
|
610
611
|
// 6. Tools mapping
|
|
@@ -858,4 +859,3 @@ export async function openPiInProcessSession(
|
|
|
858
859
|
throw openError;
|
|
859
860
|
}
|
|
860
861
|
}
|
|
861
|
-
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
|
|
5
|
+
import type { RecordSessionHost } from "../host-contracts.ts";
|
|
6
|
+
|
|
7
|
+
/** Pi-native implementation of the shared record-session lifecycle seam. */
|
|
8
|
+
export const piRecordSessionHost: RecordSessionHost = {
|
|
9
|
+
openRecordSession({ sessionFile, sessionDir, cwd }) {
|
|
10
|
+
return SessionManager.open(sessionFile, sessionDir, cwd);
|
|
11
|
+
},
|
|
12
|
+
createRecordSession({ cwd, sessionDir, parentSession }) {
|
|
13
|
+
return SessionManager.create(
|
|
14
|
+
cwd,
|
|
15
|
+
sessionDir,
|
|
16
|
+
parentSession === undefined ? undefined : { parentSession },
|
|
17
|
+
);
|
|
18
|
+
},
|
|
19
|
+
continueRecentRecordSession({ cwd, sessionDir }) {
|
|
20
|
+
const session = SessionManager.continueRecent(cwd, sessionDir);
|
|
21
|
+
const sessionFile = session.getSessionFile();
|
|
22
|
+
return {
|
|
23
|
+
session,
|
|
24
|
+
resumed: sessionFile !== undefined && existsSync(sessionFile),
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
inMemoryRecordSession(cwd) {
|
|
28
|
+
return SessionManager.inMemory(cwd);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
@@ -40,7 +40,6 @@ const RUN_STATE_PAGE_FIELDS = [
|
|
|
40
40
|
|
|
41
41
|
const SOURCE_RUN_LOCATOR_FIELDS = ["runDirectory"] as const;
|
|
42
42
|
const SUMMONS_PATH_FIELDS = ["sourceRunPath"] as const;
|
|
43
|
-
const CURRENT_SESSION_FIELDS = ["sessionFile"] as const;
|
|
44
43
|
const OFFICER_POINTER_FIELDS = ["sessionFile", "runDirectory"] as const;
|
|
45
44
|
const SITIAN_RECORD_FIELDS = ["sessionParent"] as const;
|
|
46
45
|
const SESSION_HEADER_FIELDS = ["parentSession"] as const;
|
|
@@ -219,18 +218,6 @@ export function rewriteAdmittedRoleRunPage(
|
|
|
219
218
|
}
|
|
220
219
|
}
|
|
221
220
|
|
|
222
|
-
async function rewriteJsonObjectFile(
|
|
223
|
-
path: string,
|
|
224
|
-
fields: readonly string[],
|
|
225
|
-
rewrites: readonly RunDirectoryPathRewrite[],
|
|
226
|
-
): Promise<void> {
|
|
227
|
-
if (!existsSync(path)) return;
|
|
228
|
-
const page = JSON.parse(await readFile(path, "utf8")) as unknown;
|
|
229
|
-
if (!isPlainObject(page)) return;
|
|
230
|
-
rewriteRunDirectoryPathFieldsAgainstRewrites(page, fields, rewrites);
|
|
231
|
-
await writeFile(path, `${JSON.stringify(page, null, 2)}\n`, "utf8");
|
|
232
|
-
}
|
|
233
|
-
|
|
234
221
|
async function rewriteOfficerPointerFile(
|
|
235
222
|
path: string,
|
|
236
223
|
rewrites: readonly RunDirectoryPathRewrite[],
|
|
@@ -377,7 +364,7 @@ async function rewriteSessionTranscriptBindings(
|
|
|
377
364
|
|
|
378
365
|
/**
|
|
379
366
|
* Package-owned nested seams under session/ only:
|
|
380
|
-
*
|
|
367
|
+
* direct-officer *.pointer.json, sitian records.jsonl,
|
|
381
368
|
* session transcript typed parent bindings. Never walks attachments/ or artifacts/.
|
|
382
369
|
*/
|
|
383
370
|
async function rewriteNestedMachinePathPages(
|
|
@@ -400,9 +387,7 @@ async function rewriteNestedMachinePathPages(
|
|
|
400
387
|
continue;
|
|
401
388
|
}
|
|
402
389
|
if (!entry.isFile()) continue;
|
|
403
|
-
if (entry.name
|
|
404
|
-
await rewriteJsonObjectFile(path, CURRENT_SESSION_FIELDS, rewrites);
|
|
405
|
-
} else if (entry.name.endsWith(".pointer.json")) {
|
|
390
|
+
if (entry.name.endsWith(".pointer.json")) {
|
|
406
391
|
await rewriteOfficerPointerFile(path, rewrites);
|
|
407
392
|
} else if (entry.name === "records.jsonl") {
|
|
408
393
|
await rewriteSitianRecordsJsonl(path, rewrites);
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import { execFileSync } from "node:child_process";
|
|
3
3
|
import { existsSync, lstatSync, readdirSync, readFileSync, rmdirSync, rmSync } from "node:fs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
|
-
import type { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
6
5
|
|
|
7
6
|
import {
|
|
8
7
|
createRecordSession,
|
|
9
8
|
type RecordSessionParent,
|
|
10
9
|
WORKER_SUBMISSION_GATE_KIND,
|
|
11
10
|
} from "./archivist-record-entry.ts";
|
|
11
|
+
import type { HostRecordSession } from "./host-contracts.ts";
|
|
12
12
|
import { sitianReport } from "./sitian-facade.ts";
|
|
13
13
|
import {
|
|
14
14
|
WorkerCommitReminderError,
|
|
@@ -162,7 +162,7 @@ function unfinishedReasonPresent(details?: unknown): boolean {
|
|
|
162
162
|
return typeof reason === "string" && reason.trim().length > 0;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
function readGateState(session:
|
|
165
|
+
function readGateState(session: HostRecordSession): {
|
|
166
166
|
baseline: string | null | undefined;
|
|
167
167
|
reminded: boolean;
|
|
168
168
|
prefixReminded: boolean;
|
|
@@ -239,7 +239,7 @@ export function createWorkerSubmissionGate(
|
|
|
239
239
|
let reminded = false;
|
|
240
240
|
let prefixReminded = false;
|
|
241
241
|
let unfinishedReasonBounces = 0;
|
|
242
|
-
let record:
|
|
242
|
+
let record: HostRecordSession | undefined;
|
|
243
243
|
/** Parent session file retained so every gate sitian write path-derives the same ledger home. */
|
|
244
244
|
let sessionParent: string | undefined;
|
|
245
245
|
const explicitHome =
|