@schoolai/shipyard 3.30.0 → 3.31.0-rc.20260915.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/capability-detector-worker.js +3 -3
- package/dist/{chunk-CW2PKTA6.js → chunk-3RWQ7G4S.js} +2 -2
- package/dist/{chunk-WO5EM3BP.js → chunk-5ZR72FWA.js} +2 -2
- package/dist/{chunk-ZSMWOXEN.js → chunk-GRJGV64D.js} +3 -3
- package/dist/{chunk-22TVFTWD.js → chunk-JTOJZZT2.js} +10 -1
- package/dist/{chunk-22TVFTWD.js.map → chunk-JTOJZZT2.js.map} +1 -1
- package/dist/{chunk-JM2E5QZ5.js → chunk-KWDGZXQH.js} +2 -2
- package/dist/{chunk-RGVTFZDF.js → chunk-WWO24OO4.js} +3 -3
- package/dist/cursor-runner.js +2 -2
- package/dist/electron-utility.js +2 -2
- package/dist/index.js +3 -3
- package/dist/{plan-backfill-G5ZN6E5L.js → plan-backfill-PU24U6NO.js} +3 -3
- package/dist/{serve-3TQOIJID.js → serve-JEU6SMZX.js} +357 -193
- package/dist/{serve-3TQOIJID.js.map → serve-JEU6SMZX.js.map} +1 -1
- package/dist/{start-6KMPC5RK.js → start-SCYT42PD.js} +4 -4
- package/dist/start-SCYT42PD.js.map +1 -0
- package/package.json +1 -1
- package/dist/start-6KMPC5RK.js.map +0 -1
- /package/dist/{chunk-CW2PKTA6.js.map → chunk-3RWQ7G4S.js.map} +0 -0
- /package/dist/{chunk-WO5EM3BP.js.map → chunk-5ZR72FWA.js.map} +0 -0
- /package/dist/{chunk-ZSMWOXEN.js.map → chunk-GRJGV64D.js.map} +0 -0
- /package/dist/{chunk-JM2E5QZ5.js.map → chunk-KWDGZXQH.js.map} +0 -0
- /package/dist/{chunk-RGVTFZDF.js.map → chunk-WWO24OO4.js.map} +0 -0
- /package/dist/{plan-backfill-G5ZN6E5L.js.map → plan-backfill-PU24U6NO.js.map} +0 -0
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
guardedSubscribe,
|
|
13
13
|
makeInitialAttemptState,
|
|
14
14
|
shutdownFileWatcherGuard
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-5ZR72FWA.js";
|
|
16
16
|
import {
|
|
17
17
|
TRAILER_SCHEMA_VERSION,
|
|
18
18
|
appendTrailerToMessage,
|
|
@@ -40,13 +40,13 @@ import {
|
|
|
40
40
|
startPlanBackfillForDaemon,
|
|
41
41
|
sync,
|
|
42
42
|
validatePeerId
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-KWDGZXQH.js";
|
|
44
44
|
import {
|
|
45
45
|
loadAuthToken
|
|
46
46
|
} from "./chunk-XPYW5WQS.js";
|
|
47
47
|
import {
|
|
48
48
|
getDaemonVersion
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-WWO24OO4.js";
|
|
50
50
|
import {
|
|
51
51
|
collectPriorCrashDetail,
|
|
52
52
|
getRecentWasmPanicMessages
|
|
@@ -188,7 +188,7 @@ import {
|
|
|
188
188
|
unresolveReviewThread,
|
|
189
189
|
withLabelAsync,
|
|
190
190
|
writeCursorApiKeyToVault
|
|
191
|
-
} from "./chunk-
|
|
191
|
+
} from "./chunk-GRJGV64D.js";
|
|
192
192
|
import {
|
|
193
193
|
classifySkill,
|
|
194
194
|
detectSkills,
|
|
@@ -256,7 +256,7 @@ import {
|
|
|
256
256
|
createAssetResolver,
|
|
257
257
|
toSdkContent,
|
|
258
258
|
toSdkPermissionMode
|
|
259
|
-
} from "./chunk-
|
|
259
|
+
} from "./chunk-3RWQ7G4S.js";
|
|
260
260
|
import {
|
|
261
261
|
AGENT_IDS,
|
|
262
262
|
AGENT_SYSTEM_CLAUDE_CODE,
|
|
@@ -465,7 +465,7 @@ import {
|
|
|
465
465
|
unsafeAssertSourceId,
|
|
466
466
|
vizFileExtension,
|
|
467
467
|
withPreferredRuntimeAuthMethod
|
|
468
|
-
} from "./chunk-
|
|
468
|
+
} from "./chunk-JTOJZZT2.js";
|
|
469
469
|
import {
|
|
470
470
|
AuthGitHubCallbackRequestSchema,
|
|
471
471
|
AuthGitHubCallbackResponseSchema,
|
|
@@ -554,7 +554,7 @@ import "./chunk-2H7UOFLK.js";
|
|
|
554
554
|
// src/services/serve.ts
|
|
555
555
|
import { mkdir as mkdir48, realpath as realpath7 } from "fs/promises";
|
|
556
556
|
import { homedir as homedir17 } from "os";
|
|
557
|
-
import { join as
|
|
557
|
+
import { join as join94 } from "path";
|
|
558
558
|
import { query as query2 } from "@anthropic-ai/claude-agent-sdk";
|
|
559
559
|
|
|
560
560
|
// ../../node_modules/.pnpm/@levischuck+tiny-cbor@0.3.2/node_modules/@levischuck/tiny-cbor/esm/cbor/cbor_internal.js
|
|
@@ -6067,7 +6067,7 @@ function nanoid(size = 21) {
|
|
|
6067
6067
|
}
|
|
6068
6068
|
|
|
6069
6069
|
// src/services/bootstrap/signaling.ts
|
|
6070
|
-
var DAEMON_NPM_VERSION = true ? "3.
|
|
6070
|
+
var DAEMON_NPM_VERSION = true ? "3.31.0" : "unknown";
|
|
6071
6071
|
function createDaemonSignaling(config) {
|
|
6072
6072
|
const agentId = config.agentId ?? nanoid();
|
|
6073
6073
|
function send(msg) {
|
|
@@ -34704,7 +34704,7 @@ function buildCollabRoomManager(deps) {
|
|
|
34704
34704
|
// src/services/serve-factory.ts
|
|
34705
34705
|
import { randomUUID as randomUUID27 } from "crypto";
|
|
34706
34706
|
import { mkdir as mkdir40 } from "fs/promises";
|
|
34707
|
-
import { join as
|
|
34707
|
+
import { join as join86 } from "path";
|
|
34708
34708
|
import { getHeapStatistics } from "v8";
|
|
34709
34709
|
|
|
34710
34710
|
// src/shared/capabilities/cursor-boot-auth.ts
|
|
@@ -34758,8 +34758,8 @@ function getCursorHookShimPath() {
|
|
|
34758
34758
|
function verifyCursorHookShimPresent(path8) {
|
|
34759
34759
|
const resolved = path8 ?? getCursorHookShimPath();
|
|
34760
34760
|
try {
|
|
34761
|
-
const
|
|
34762
|
-
if (!
|
|
34761
|
+
const stat23 = statSync4(resolved);
|
|
34762
|
+
if (!stat23.isFile()) return null;
|
|
34763
34763
|
return { path: resolved };
|
|
34764
34764
|
} catch {
|
|
34765
34765
|
return null;
|
|
@@ -86622,9 +86622,135 @@ function buildDeliverableStore(dataDir) {
|
|
|
86622
86622
|
|
|
86623
86623
|
// src/services/storage/jsonl-conversation-store.ts
|
|
86624
86624
|
import { createReadStream as createReadStream5 } from "fs";
|
|
86625
|
-
import { appendFile as
|
|
86626
|
-
import { join as
|
|
86625
|
+
import { appendFile as appendFile4, mkdir as mkdir31, open as open4, readFile as readFile41, stat as stat20 } from "fs/promises";
|
|
86626
|
+
import { join as join74 } from "path";
|
|
86627
86627
|
import { createInterface as createInterface5 } from "readline";
|
|
86628
|
+
|
|
86629
|
+
// src/services/storage/jsonl-sdk-uuid-stamps.ts
|
|
86630
|
+
import { appendFile as appendFile3, readFile as readFile40, rm as rm12, stat as stat19 } from "fs/promises";
|
|
86631
|
+
import { join as join73 } from "path";
|
|
86632
|
+
var SdkUuidStampSchema = external_exports.object({
|
|
86633
|
+
messageId: external_exports.string(),
|
|
86634
|
+
sdkUuid: external_exports.string(),
|
|
86635
|
+
batchCorrelationIds: external_exports.array(external_exports.string()).optional()
|
|
86636
|
+
});
|
|
86637
|
+
function recoverAfterTear(line) {
|
|
86638
|
+
for (let i = line.indexOf("{", 1); i !== -1; i = line.indexOf("{", i + 1)) {
|
|
86639
|
+
try {
|
|
86640
|
+
return JSON.parse(line.slice(i));
|
|
86641
|
+
} catch {
|
|
86642
|
+
}
|
|
86643
|
+
}
|
|
86644
|
+
return void 0;
|
|
86645
|
+
}
|
|
86646
|
+
function parseStampLines(raw) {
|
|
86647
|
+
const stamps = [];
|
|
86648
|
+
for (const line of raw.split("\n")) {
|
|
86649
|
+
if (line.length === 0) continue;
|
|
86650
|
+
let json;
|
|
86651
|
+
try {
|
|
86652
|
+
json = JSON.parse(line);
|
|
86653
|
+
} catch {
|
|
86654
|
+
json = recoverAfterTear(line);
|
|
86655
|
+
if (json === void 0) continue;
|
|
86656
|
+
}
|
|
86657
|
+
const parsed = SdkUuidStampSchema.safeParse(json);
|
|
86658
|
+
if (parsed.success) stamps.push(parsed.data);
|
|
86659
|
+
}
|
|
86660
|
+
return stamps;
|
|
86661
|
+
}
|
|
86662
|
+
function serializeStamp(stamp) {
|
|
86663
|
+
return `${JSON.stringify(stamp)}
|
|
86664
|
+
`;
|
|
86665
|
+
}
|
|
86666
|
+
function applySdkUuidStamps(messages, stamps) {
|
|
86667
|
+
if (stamps.length === 0) return messages;
|
|
86668
|
+
const byMessageId = /* @__PURE__ */ new Map();
|
|
86669
|
+
for (const stamp of stamps) byMessageId.set(stamp.messageId, stamp);
|
|
86670
|
+
const overlay = (message) => {
|
|
86671
|
+
const stamp = byMessageId.get(message.messageId);
|
|
86672
|
+
if (!stamp) return null;
|
|
86673
|
+
const patch = {};
|
|
86674
|
+
if (!message.sdkUuid) patch.sdkUuid = stamp.sdkUuid;
|
|
86675
|
+
const batch = stamp.batchCorrelationIds;
|
|
86676
|
+
if (batch && batch.length > 0 && !message.batchCorrelationIds)
|
|
86677
|
+
patch.batchCorrelationIds = [...batch];
|
|
86678
|
+
return Object.keys(patch).length > 0 ? patch : null;
|
|
86679
|
+
};
|
|
86680
|
+
if (!messages.some((message) => overlay(message) !== null)) return messages;
|
|
86681
|
+
return messages.map((message) => {
|
|
86682
|
+
const patch = overlay(message);
|
|
86683
|
+
return patch === null ? message : { ...message, ...patch };
|
|
86684
|
+
});
|
|
86685
|
+
}
|
|
86686
|
+
var EMPTY_STAMPS = Object.freeze([]);
|
|
86687
|
+
var MAX_STAMPS_CACHE_ENTRIES = 512;
|
|
86688
|
+
function createSdkUuidStampSidecar(channelsDir) {
|
|
86689
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
86690
|
+
function path8(channelId) {
|
|
86691
|
+
return join73(channelsDir, `${channelId}.stamps.jsonl`);
|
|
86692
|
+
}
|
|
86693
|
+
function remember(channelId, entry) {
|
|
86694
|
+
cache2.delete(channelId);
|
|
86695
|
+
cache2.set(channelId, entry);
|
|
86696
|
+
while (cache2.size > MAX_STAMPS_CACHE_ENTRIES) {
|
|
86697
|
+
const oldest = cache2.keys().next();
|
|
86698
|
+
if (oldest.done === true) break;
|
|
86699
|
+
cache2.delete(oldest.value);
|
|
86700
|
+
}
|
|
86701
|
+
}
|
|
86702
|
+
return {
|
|
86703
|
+
path: path8,
|
|
86704
|
+
async read(channelId) {
|
|
86705
|
+
const target = path8(channelId);
|
|
86706
|
+
let fileStat;
|
|
86707
|
+
try {
|
|
86708
|
+
const s2 = await stat19(target);
|
|
86709
|
+
fileStat = { size: s2.size, mtimeMs: s2.mtimeMs };
|
|
86710
|
+
} catch (err3) {
|
|
86711
|
+
if (!isEnoent(err3)) throw err3;
|
|
86712
|
+
cache2.delete(channelId);
|
|
86713
|
+
return { stamps: EMPTY_STAMPS, size: 0, mtimeMs: 0 };
|
|
86714
|
+
}
|
|
86715
|
+
if (fileStat.size === 0) {
|
|
86716
|
+
cache2.delete(channelId);
|
|
86717
|
+
return { stamps: EMPTY_STAMPS, size: 0, mtimeMs: 0 };
|
|
86718
|
+
}
|
|
86719
|
+
const hit = cache2.get(channelId);
|
|
86720
|
+
if (hit && hit.size === fileStat.size && hit.mtimeMs === fileStat.mtimeMs) {
|
|
86721
|
+
return { stamps: hit.stamps, size: hit.size, mtimeMs: hit.mtimeMs };
|
|
86722
|
+
}
|
|
86723
|
+
let raw;
|
|
86724
|
+
try {
|
|
86725
|
+
raw = await readFile40(target, "utf-8");
|
|
86726
|
+
} catch (err3) {
|
|
86727
|
+
if (isEnoent(err3)) return { stamps: EMPTY_STAMPS, size: 0, mtimeMs: 0 };
|
|
86728
|
+
throw err3;
|
|
86729
|
+
}
|
|
86730
|
+
const stamps = parseStampLines(raw);
|
|
86731
|
+
remember(channelId, { size: fileStat.size, mtimeMs: fileStat.mtimeMs, stamps });
|
|
86732
|
+
return { stamps, size: fileStat.size, mtimeMs: fileStat.mtimeMs };
|
|
86733
|
+
},
|
|
86734
|
+
async append(channelId, stamp) {
|
|
86735
|
+
await appendFile3(path8(channelId), serializeStamp(stamp), "utf-8");
|
|
86736
|
+
},
|
|
86737
|
+
async discard(channelId) {
|
|
86738
|
+
cache2.delete(channelId);
|
|
86739
|
+
try {
|
|
86740
|
+
await rm12(path8(channelId));
|
|
86741
|
+
return true;
|
|
86742
|
+
} catch (err3) {
|
|
86743
|
+
if (isEnoent(err3)) return false;
|
|
86744
|
+
throw err3;
|
|
86745
|
+
}
|
|
86746
|
+
},
|
|
86747
|
+
cachedChannelCount() {
|
|
86748
|
+
return cache2.size;
|
|
86749
|
+
}
|
|
86750
|
+
};
|
|
86751
|
+
}
|
|
86752
|
+
|
|
86753
|
+
// src/services/storage/jsonl-conversation-store.ts
|
|
86628
86754
|
var StoredMessageSchema = MessageSchema.omit({ seqNo: true, channelId: true });
|
|
86629
86755
|
function logPerf(entry) {
|
|
86630
86756
|
try {
|
|
@@ -86641,7 +86767,7 @@ function computeReadCacheBudgetBytes(heapSizeLimitBytes) {
|
|
|
86641
86767
|
return Math.min(READ_CACHE_BUDGET_CAP_BYTES, Math.max(DEFAULT_READ_CACHE_BUDGET_BYTES, scaled));
|
|
86642
86768
|
}
|
|
86643
86769
|
function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
86644
|
-
const channelsDir =
|
|
86770
|
+
const channelsDir = join74(dataDir, "channels");
|
|
86645
86771
|
const seqCounters = /* @__PURE__ */ new Map();
|
|
86646
86772
|
const channelQueues = /* @__PURE__ */ new Map();
|
|
86647
86773
|
const readCache = /* @__PURE__ */ new Map();
|
|
@@ -86686,8 +86812,9 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
86686
86812
|
}
|
|
86687
86813
|
const turnCountCache = /* @__PURE__ */ new Map();
|
|
86688
86814
|
function channelPath(channelId) {
|
|
86689
|
-
return
|
|
86815
|
+
return join74(channelsDir, `${channelId}.jsonl`);
|
|
86690
86816
|
}
|
|
86817
|
+
const stampSidecar = createSdkUuidStampSidecar(channelsDir);
|
|
86691
86818
|
function countRuns(messages) {
|
|
86692
86819
|
let turns = 0;
|
|
86693
86820
|
let prev = null;
|
|
@@ -86747,9 +86874,10 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
86747
86874
|
async function readLines(channelId) {
|
|
86748
86875
|
const startedAt = Date.now();
|
|
86749
86876
|
logPerf({ event: "perf_jsonl_read_start", channelId });
|
|
86877
|
+
const stamps = await stampSidecar.read(channelId);
|
|
86750
86878
|
let raw;
|
|
86751
86879
|
try {
|
|
86752
|
-
raw = await
|
|
86880
|
+
raw = await readFile41(channelPath(channelId), "utf-8");
|
|
86753
86881
|
} catch (err3) {
|
|
86754
86882
|
if (!isEnoent(err3)) throw err3;
|
|
86755
86883
|
logPerf({
|
|
@@ -86759,9 +86887,9 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
86759
86887
|
linesParsed: 0,
|
|
86760
86888
|
durationMs: Date.now() - startedAt
|
|
86761
86889
|
});
|
|
86762
|
-
return [];
|
|
86890
|
+
return { messages: [], stampsSize: stamps.size, stampsMtimeMs: stamps.mtimeMs };
|
|
86763
86891
|
}
|
|
86764
|
-
const messages = parseJsonlBlob(raw, channelId);
|
|
86892
|
+
const messages = applySdkUuidStamps(parseJsonlBlob(raw, channelId), stamps.stamps);
|
|
86765
86893
|
logPerf({
|
|
86766
86894
|
event: "perf_jsonl_read_done",
|
|
86767
86895
|
channelId,
|
|
@@ -86769,7 +86897,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
86769
86897
|
linesParsed: messages.length,
|
|
86770
86898
|
durationMs: Date.now() - startedAt
|
|
86771
86899
|
});
|
|
86772
|
-
return messages;
|
|
86900
|
+
return { messages, stampsSize: stamps.size, stampsMtimeMs: stamps.mtimeMs };
|
|
86773
86901
|
}
|
|
86774
86902
|
async function countLinesInFile(path8) {
|
|
86775
86903
|
let fh;
|
|
@@ -86858,23 +86986,31 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
86858
86986
|
const startSeqNo = totalLines - tailLines2.length;
|
|
86859
86987
|
const messages = parseTailLines(tailLines2, startSeqNo, channelId);
|
|
86860
86988
|
if (messages === null) return null;
|
|
86861
|
-
|
|
86989
|
+
const stamps = await stampSidecar.read(channelId);
|
|
86990
|
+
return { messages: applySdkUuidStamps(messages, stamps.stamps), totalLines };
|
|
86862
86991
|
} finally {
|
|
86863
86992
|
await fh.close();
|
|
86864
86993
|
}
|
|
86865
86994
|
}
|
|
86866
86995
|
async function statFreshness(path8) {
|
|
86867
86996
|
try {
|
|
86868
|
-
const s2 = await
|
|
86997
|
+
const s2 = await stat20(path8);
|
|
86869
86998
|
return { size: s2.size, mtimeMs: s2.mtimeMs };
|
|
86870
86999
|
} catch (err3) {
|
|
86871
87000
|
if (isEnoent(err3)) return null;
|
|
86872
87001
|
throw err3;
|
|
86873
87002
|
}
|
|
86874
87003
|
}
|
|
86875
|
-
function
|
|
87004
|
+
function isCacheEntryFresh(entry, fileStat, stampsStat) {
|
|
87005
|
+
return entry.size === fileStat.size && entry.mtimeMs === fileStat.mtimeMs && entry.stampsSize === stampsStat.size && entry.stampsMtimeMs === stampsStat.mtimeMs;
|
|
87006
|
+
}
|
|
87007
|
+
function readTailFromCache(channelId, limit, fileStat, stampsStat) {
|
|
86876
87008
|
const hit = readCache.get(channelId);
|
|
86877
|
-
if (!hit
|
|
87009
|
+
if (!hit) return null;
|
|
87010
|
+
if (!isCacheEntryFresh(hit, fileStat, stampsStat)) {
|
|
87011
|
+
dropCacheEntry(channelId);
|
|
87012
|
+
return null;
|
|
87013
|
+
}
|
|
86878
87014
|
touchCacheEntry(channelId, hit);
|
|
86879
87015
|
const tail = hit.messages.length <= limit ? [...hit.messages] : hit.messages.slice(-limit);
|
|
86880
87016
|
return { messages: tail, totalLines: hit.messages.length };
|
|
@@ -86883,7 +87019,8 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
86883
87019
|
if (limit <= 0) return { messages: [], totalLines: 0 };
|
|
86884
87020
|
const fileStat = await statFreshness(channelPath(channelId));
|
|
86885
87021
|
if (fileStat === null || fileStat.size === 0) return { messages: [], totalLines: 0 };
|
|
86886
|
-
const
|
|
87022
|
+
const stampsStat = await stampSidecar.read(channelId);
|
|
87023
|
+
const cached = readTailFromCache(channelId, limit, fileStat, stampsStat);
|
|
86887
87024
|
if (cached !== null) return cached;
|
|
86888
87025
|
if (fileStat.size <= 256 * 1024) {
|
|
86889
87026
|
const all = await readLinesCached(channelId);
|
|
@@ -86896,24 +87033,29 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
86896
87033
|
const path8 = channelPath(channelId);
|
|
86897
87034
|
let fileStat = null;
|
|
86898
87035
|
try {
|
|
86899
|
-
const s2 = await
|
|
87036
|
+
const s2 = await stat20(path8);
|
|
86900
87037
|
fileStat = { size: s2.size, mtimeMs: s2.mtimeMs };
|
|
86901
87038
|
} catch (err3) {
|
|
86902
87039
|
if (isEnoent(err3)) return [];
|
|
86903
87040
|
throw err3;
|
|
86904
87041
|
}
|
|
87042
|
+
const stampsStat = await stampSidecar.read(channelId);
|
|
86905
87043
|
const hit = readCache.get(channelId);
|
|
86906
|
-
if (hit && hit
|
|
87044
|
+
if (hit && isCacheEntryFresh(hit, fileStat, stampsStat)) {
|
|
86907
87045
|
touchCacheEntry(channelId, hit);
|
|
86908
87046
|
return [...hit.messages];
|
|
86909
87047
|
}
|
|
87048
|
+
if (hit) dropCacheEntry(channelId);
|
|
86910
87049
|
const fresh = await readLines(channelId);
|
|
87050
|
+
await opts._testHooks?.onAfterReadBeforeCachePopulate?.();
|
|
86911
87051
|
setCacheEntry(channelId, {
|
|
86912
|
-
messages: fresh,
|
|
87052
|
+
messages: fresh.messages,
|
|
86913
87053
|
size: fileStat.size,
|
|
86914
|
-
mtimeMs: fileStat.mtimeMs
|
|
87054
|
+
mtimeMs: fileStat.mtimeMs,
|
|
87055
|
+
stampsSize: fresh.stampsSize,
|
|
87056
|
+
stampsMtimeMs: fresh.stampsMtimeMs
|
|
86915
87057
|
});
|
|
86916
|
-
return [...fresh];
|
|
87058
|
+
return [...fresh.messages];
|
|
86917
87059
|
}
|
|
86918
87060
|
function pushIntoLiveCache(channelId, appended, fileStat) {
|
|
86919
87061
|
const liveHit = readCache.get(channelId);
|
|
@@ -86932,7 +87074,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
86932
87074
|
async function refreshCacheAfterAppend(channelId, appended) {
|
|
86933
87075
|
if (!readCache.get(channelId)) return;
|
|
86934
87076
|
try {
|
|
86935
|
-
const s2 = await
|
|
87077
|
+
const s2 = await stat20(channelPath(channelId));
|
|
86936
87078
|
await opts._testHooks?.onAfterStatBeforePush?.();
|
|
86937
87079
|
pushIntoLiveCache(channelId, appended, { size: s2.size, mtimeMs: s2.mtimeMs });
|
|
86938
87080
|
} catch (err3) {
|
|
@@ -87026,7 +87168,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
87026
87168
|
seqCounters.set(message.channelId, seqNo);
|
|
87027
87169
|
const { channelId: _channelId, ...rest } = message;
|
|
87028
87170
|
const line = JSON.stringify(rest);
|
|
87029
|
-
await
|
|
87171
|
+
await appendFile4(channelPath(message.channelId), `${line}
|
|
87030
87172
|
`, "utf-8");
|
|
87031
87173
|
await refreshCacheAfterAppend(message.channelId, {
|
|
87032
87174
|
...rest,
|
|
@@ -87080,7 +87222,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
87080
87222
|
lines.push(JSON.stringify(rest));
|
|
87081
87223
|
cacheUpdates.push({ ...rest, channelId, seqNo });
|
|
87082
87224
|
}
|
|
87083
|
-
await
|
|
87225
|
+
await appendFile4(channelPath(channelId), `${lines.join("\n")}
|
|
87084
87226
|
`, "utf-8");
|
|
87085
87227
|
seqCounters.set(channelId, startSeqNo + messages.length - 1);
|
|
87086
87228
|
await refreshCacheAfterAppend(channelId, cacheUpdates);
|
|
@@ -87125,7 +87267,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
87125
87267
|
seqCounters.set(message.channelId, decision.seqNo);
|
|
87126
87268
|
const { channelId: _channelId, ...rest } = message;
|
|
87127
87269
|
const line = JSON.stringify(rest);
|
|
87128
|
-
await
|
|
87270
|
+
await appendFile4(channelPath(message.channelId), `${line}
|
|
87129
87271
|
`, "utf-8");
|
|
87130
87272
|
await refreshCacheAfterAppend(message.channelId, {
|
|
87131
87273
|
...rest,
|
|
@@ -87145,7 +87287,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
87145
87287
|
channelQueues.set(message.channelId, next);
|
|
87146
87288
|
return resultPromise;
|
|
87147
87289
|
},
|
|
87148
|
-
async stampSdkUuid(channelId,
|
|
87290
|
+
async stampSdkUuid(channelId, messageId, sdkUuid, batchCorrelationIds) {
|
|
87149
87291
|
let resolveVoid;
|
|
87150
87292
|
let rejectVoid;
|
|
87151
87293
|
const voidPromise = new Promise((resolve15, reject) => {
|
|
@@ -87154,30 +87296,13 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
87154
87296
|
});
|
|
87155
87297
|
const prev = channelQueues.get(channelId) ?? Promise.resolve();
|
|
87156
87298
|
const next = prev.then(async () => {
|
|
87157
|
-
|
|
87158
|
-
const target = messages.find(
|
|
87159
|
-
(m2) => m2.senderKind === "human" && m2.correlationId === primaryCorrelationId && !m2.sdkUuid
|
|
87160
|
-
);
|
|
87161
|
-
if (!target) {
|
|
87162
|
-
resolveVoid();
|
|
87163
|
-
return;
|
|
87164
|
-
}
|
|
87299
|
+
await ensureDir();
|
|
87165
87300
|
const secondaryIds = batchCorrelationIds && batchCorrelationIds.length > 0 ? batchCorrelationIds : void 0;
|
|
87166
|
-
|
|
87167
|
-
|
|
87168
|
-
|
|
87169
|
-
|
|
87170
|
-
...rest,
|
|
87171
|
-
sdkUuid,
|
|
87172
|
-
...secondaryIds ? { batchCorrelationIds: secondaryIds } : {}
|
|
87173
|
-
});
|
|
87174
|
-
}
|
|
87175
|
-
return JSON.stringify(rest);
|
|
87301
|
+
await stampSidecar.append(channelId, {
|
|
87302
|
+
messageId,
|
|
87303
|
+
sdkUuid,
|
|
87304
|
+
...secondaryIds ? { batchCorrelationIds: secondaryIds } : {}
|
|
87176
87305
|
});
|
|
87177
|
-
const content = lines.length > 0 ? `${lines.join("\n")}
|
|
87178
|
-
` : "";
|
|
87179
|
-
const filePath = channelPath(channelId);
|
|
87180
|
-
await atomicWriteFile(filePath, content);
|
|
87181
87306
|
dropCacheEntry(channelId);
|
|
87182
87307
|
resolveVoid();
|
|
87183
87308
|
}).catch((err3) => {
|
|
@@ -87245,7 +87370,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
87245
87370
|
});
|
|
87246
87371
|
const prev = channelQueues.get(channelId) ?? Promise.resolve();
|
|
87247
87372
|
const next = prev.then(async () => {
|
|
87248
|
-
const messages = await readLines(channelId);
|
|
87373
|
+
const { messages } = await readLines(channelId);
|
|
87249
87374
|
const kept = messages.filter((m2) => m2.seqNo <= targetSeqNo);
|
|
87250
87375
|
const removed = messages.length - kept.length;
|
|
87251
87376
|
if (removed === 0) {
|
|
@@ -87263,6 +87388,13 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
|
|
|
87263
87388
|
await atomicWriteFile(filePath, content);
|
|
87264
87389
|
seqCounters.set(channelId, kept.length > 0 ? kept.length - 1 : -1);
|
|
87265
87390
|
dropCacheEntry(channelId);
|
|
87391
|
+
const discardedStamps = await stampSidecar.discard(channelId);
|
|
87392
|
+
logPerf({
|
|
87393
|
+
event: "perf_jsonl_stamps_discarded",
|
|
87394
|
+
channelId,
|
|
87395
|
+
existed: discardedStamps,
|
|
87396
|
+
keptLines: kept.length
|
|
87397
|
+
});
|
|
87266
87398
|
resolveCount(removed);
|
|
87267
87399
|
}).catch((err3) => {
|
|
87268
87400
|
dropCacheEntry(channelId);
|
|
@@ -87326,8 +87458,8 @@ function buildObservableConversationStore(inner) {
|
|
|
87326
87458
|
}
|
|
87327
87459
|
return result;
|
|
87328
87460
|
},
|
|
87329
|
-
stampSdkUuid(channelId,
|
|
87330
|
-
return inner.stampSdkUuid(channelId,
|
|
87461
|
+
stampSdkUuid(channelId, messageId, sdkUuid, batchCorrelationIds) {
|
|
87462
|
+
return inner.stampSdkUuid(channelId, messageId, sdkUuid, batchCorrelationIds);
|
|
87331
87463
|
},
|
|
87332
87464
|
countSenderTurns(channelId) {
|
|
87333
87465
|
return inner.countSenderTurns(channelId);
|
|
@@ -87366,7 +87498,7 @@ function buildObservableConversationStore(inner) {
|
|
|
87366
87498
|
|
|
87367
87499
|
// src/services/storage/projects-store.ts
|
|
87368
87500
|
import { randomUUID as randomUUID21 } from "crypto";
|
|
87369
|
-
import { mkdir as mkdir32, readFile as
|
|
87501
|
+
import { mkdir as mkdir32, readFile as readFile42 } from "fs/promises";
|
|
87370
87502
|
import { dirname as dirname32 } from "path";
|
|
87371
87503
|
var ProjectsArraySchema = external_exports.array(ProjectSchema);
|
|
87372
87504
|
function buildProjectsStore(filePath) {
|
|
@@ -87388,7 +87520,7 @@ function buildProjectsStore(filePath) {
|
|
|
87388
87520
|
async function readStore() {
|
|
87389
87521
|
if (cache2) return cache2;
|
|
87390
87522
|
try {
|
|
87391
|
-
const raw = await
|
|
87523
|
+
const raw = await readFile42(filePath, "utf-8");
|
|
87392
87524
|
const parsed = JSON.parse(raw);
|
|
87393
87525
|
const migrated = migrateProjectsStore(parsed);
|
|
87394
87526
|
cache2 = migrated.projects;
|
|
@@ -87417,7 +87549,7 @@ function buildProjectsStore(filePath) {
|
|
|
87417
87549
|
}
|
|
87418
87550
|
async function readFromDisk() {
|
|
87419
87551
|
try {
|
|
87420
|
-
const raw = await
|
|
87552
|
+
const raw = await readFile42(filePath, "utf-8");
|
|
87421
87553
|
return migrateProjectsStore(JSON.parse(raw)).projects;
|
|
87422
87554
|
} catch (err3) {
|
|
87423
87555
|
if (isEnoent(err3)) return [];
|
|
@@ -87538,8 +87670,8 @@ function buildProjectsStore(filePath) {
|
|
|
87538
87670
|
}
|
|
87539
87671
|
|
|
87540
87672
|
// src/services/storage/rate-limit-store.ts
|
|
87541
|
-
import { mkdir as mkdir33, readFile as
|
|
87542
|
-
import { dirname as dirname33, join as
|
|
87673
|
+
import { mkdir as mkdir33, readFile as readFile43 } from "fs/promises";
|
|
87674
|
+
import { dirname as dirname33, join as join75 } from "path";
|
|
87543
87675
|
var RATE_LIMIT_STORE_VERSION = 4;
|
|
87544
87676
|
var RateLimitRecordSchema = external_exports.object({
|
|
87545
87677
|
info: RateLimitInfoSchema,
|
|
@@ -87578,7 +87710,7 @@ function isWindowKey(x2) {
|
|
|
87578
87710
|
return x2 !== void 0 && WINDOW_KEYS.has(x2);
|
|
87579
87711
|
}
|
|
87580
87712
|
async function buildRateLimitStore(dataDir, opts) {
|
|
87581
|
-
const filePath =
|
|
87713
|
+
const filePath = join75(dataDir, "rate-limits.json");
|
|
87582
87714
|
const lockPath2 = `${filePath}.lock`;
|
|
87583
87715
|
const initial = await loadStoreFile(filePath, opts.logger);
|
|
87584
87716
|
const records = { ...initial.records };
|
|
@@ -87728,7 +87860,7 @@ function mergeEvent(prev, incoming, eventTime) {
|
|
|
87728
87860
|
}
|
|
87729
87861
|
async function loadStoreFile(filePath, logger2) {
|
|
87730
87862
|
try {
|
|
87731
|
-
const raw = await
|
|
87863
|
+
const raw = await readFile43(filePath, "utf-8");
|
|
87732
87864
|
const parsed = JSON.parse(raw);
|
|
87733
87865
|
const v4 = StoreFileSchemaV4.safeParse(parsed);
|
|
87734
87866
|
if (v4.success) return v4.data;
|
|
@@ -87831,8 +87963,8 @@ async function atomicWrite4(filePath, data) {
|
|
|
87831
87963
|
}
|
|
87832
87964
|
|
|
87833
87965
|
// src/services/storage/schedule-store.ts
|
|
87834
|
-
import { mkdir as mkdir34, readFile as
|
|
87835
|
-
import { dirname as dirname34, join as
|
|
87966
|
+
import { mkdir as mkdir34, readFile as readFile44, writeFile as writeFile26 } from "fs/promises";
|
|
87967
|
+
import { dirname as dirname34, join as join76 } from "path";
|
|
87836
87968
|
import properLockfile from "proper-lockfile";
|
|
87837
87969
|
var STORE_FILE = "schedules.json";
|
|
87838
87970
|
function emptyState() {
|
|
@@ -87874,7 +88006,7 @@ function notify(listeners, event) {
|
|
|
87874
88006
|
}
|
|
87875
88007
|
}
|
|
87876
88008
|
function buildScheduleStore(dataDir, options = {}) {
|
|
87877
|
-
const filePath =
|
|
88009
|
+
const filePath = join76(dataDir, STORE_FILE);
|
|
87878
88010
|
const lockPath2 = `${filePath}.automation-lock`;
|
|
87879
88011
|
const listeners = /* @__PURE__ */ new Set();
|
|
87880
88012
|
const staleMs = options.lockStaleMs ?? 6e4;
|
|
@@ -87917,7 +88049,7 @@ function buildScheduleStore(dataDir, options = {}) {
|
|
|
87917
88049
|
async function loadFromDisk() {
|
|
87918
88050
|
let source;
|
|
87919
88051
|
try {
|
|
87920
|
-
source = await
|
|
88052
|
+
source = await readFile44(filePath, "utf-8");
|
|
87921
88053
|
} catch (error) {
|
|
87922
88054
|
if (isEnoent(error)) return { state: emptyState(), source: null, migratedFromVersion: null };
|
|
87923
88055
|
throw error;
|
|
@@ -87942,7 +88074,7 @@ function buildScheduleStore(dataDir, options = {}) {
|
|
|
87942
88074
|
if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "EEXIST") {
|
|
87943
88075
|
throw error;
|
|
87944
88076
|
}
|
|
87945
|
-
const existingBackup = await
|
|
88077
|
+
const existingBackup = await readFile44(backupPath, "utf-8");
|
|
87946
88078
|
if (existingBackup !== loaded.source) {
|
|
87947
88079
|
throw new Error(`Schedule migration backup does not match source: ${backupPath}`);
|
|
87948
88080
|
}
|
|
@@ -88052,8 +88184,8 @@ function buildScheduleStore(dataDir, options = {}) {
|
|
|
88052
88184
|
}
|
|
88053
88185
|
|
|
88054
88186
|
// src/services/storage/session-persistence.ts
|
|
88055
|
-
import { mkdir as mkdir35, readdir as readdir21, readFile as
|
|
88056
|
-
import { join as
|
|
88187
|
+
import { mkdir as mkdir35, readdir as readdir21, readFile as readFile45, rm as rm13 } from "fs/promises";
|
|
88188
|
+
import { join as join77 } from "path";
|
|
88057
88189
|
var PersistedSessionSchema = external_exports.object({
|
|
88058
88190
|
sessionId: external_exports.string(),
|
|
88059
88191
|
channelId: external_exports.string(),
|
|
@@ -88084,7 +88216,7 @@ var PersistedSessionSchema = external_exports.object({
|
|
|
88084
88216
|
}));
|
|
88085
88217
|
async function loadOneSessionFile(originalPath, corruptionLogger) {
|
|
88086
88218
|
try {
|
|
88087
|
-
const raw = await
|
|
88219
|
+
const raw = await readFile45(originalPath, "utf-8");
|
|
88088
88220
|
return PersistedSessionSchema.parse(JSON.parse(raw));
|
|
88089
88221
|
} catch (err3) {
|
|
88090
88222
|
if (isCorruptionError(err3)) {
|
|
@@ -88110,9 +88242,9 @@ async function loadOneSessionFile(originalPath, corruptionLogger) {
|
|
|
88110
88242
|
}
|
|
88111
88243
|
}
|
|
88112
88244
|
function buildSessionPersistence(dataDir, corruptionLogger) {
|
|
88113
|
-
const channelsDir =
|
|
88245
|
+
const channelsDir = join77(dataDir, "channels");
|
|
88114
88246
|
function sessionPath(channelId) {
|
|
88115
|
-
return
|
|
88247
|
+
return join77(channelsDir, `${channelId}.session.json`);
|
|
88116
88248
|
}
|
|
88117
88249
|
async function ensureDir() {
|
|
88118
88250
|
await mkdir35(channelsDir, { recursive: true });
|
|
@@ -88126,7 +88258,7 @@ function buildSessionPersistence(dataDir, corruptionLogger) {
|
|
|
88126
88258
|
async load(channelId) {
|
|
88127
88259
|
const path8 = sessionPath(channelId);
|
|
88128
88260
|
try {
|
|
88129
|
-
const raw = await
|
|
88261
|
+
const raw = await readFile45(path8, "utf-8");
|
|
88130
88262
|
return PersistedSessionSchema.parse(JSON.parse(raw));
|
|
88131
88263
|
} catch (err3) {
|
|
88132
88264
|
if (isEnoent(err3)) return null;
|
|
@@ -88146,7 +88278,7 @@ function buildSessionPersistence(dataDir, corruptionLogger) {
|
|
|
88146
88278
|
},
|
|
88147
88279
|
async clear(channelId) {
|
|
88148
88280
|
try {
|
|
88149
|
-
await
|
|
88281
|
+
await rm13(sessionPath(channelId));
|
|
88150
88282
|
} catch (err3) {
|
|
88151
88283
|
if (isEnoent(err3)) return;
|
|
88152
88284
|
throw err3;
|
|
@@ -88170,7 +88302,7 @@ function buildSessionPersistence(dataDir, corruptionLogger) {
|
|
|
88170
88302
|
if (i >= sessionEntries.length) return;
|
|
88171
88303
|
const entry = sessionEntries[i];
|
|
88172
88304
|
if (!entry) return;
|
|
88173
|
-
results[i] = await loadOneSessionFile(
|
|
88305
|
+
results[i] = await loadOneSessionFile(join77(channelsDir, entry), corruptionLogger);
|
|
88174
88306
|
}
|
|
88175
88307
|
}
|
|
88176
88308
|
const workers = Array.from(
|
|
@@ -88184,12 +88316,12 @@ function buildSessionPersistence(dataDir, corruptionLogger) {
|
|
|
88184
88316
|
}
|
|
88185
88317
|
|
|
88186
88318
|
// src/services/storage/template-store.ts
|
|
88187
|
-
import { join as
|
|
88319
|
+
import { join as join78 } from "path";
|
|
88188
88320
|
function buildTemplateStore(dataDir) {
|
|
88189
88321
|
const store = buildJsonDocumentStore({
|
|
88190
88322
|
storeName: "templates",
|
|
88191
88323
|
docType: "template",
|
|
88192
|
-
filePath:
|
|
88324
|
+
filePath: join78(dataDir, "templates.json"),
|
|
88193
88325
|
recordSchema: TaskTemplateRecordSchema,
|
|
88194
88326
|
currentVersion: TEMPLATE_STORE_VERSION,
|
|
88195
88327
|
migrate(raw) {
|
|
@@ -88227,7 +88359,7 @@ function buildTemplateStore(dataDir) {
|
|
|
88227
88359
|
}
|
|
88228
88360
|
|
|
88229
88361
|
// src/services/storage/user-settings-store.ts
|
|
88230
|
-
import { mkdir as mkdir36, readFile as
|
|
88362
|
+
import { mkdir as mkdir36, readFile as readFile46 } from "fs/promises";
|
|
88231
88363
|
import { dirname as dirname35 } from "path";
|
|
88232
88364
|
function buildUserSettingsStore(filePath) {
|
|
88233
88365
|
let cache2 = null;
|
|
@@ -88248,7 +88380,7 @@ function buildUserSettingsStore(filePath) {
|
|
|
88248
88380
|
async function readStore() {
|
|
88249
88381
|
if (cache2) return cache2;
|
|
88250
88382
|
try {
|
|
88251
|
-
const raw = await
|
|
88383
|
+
const raw = await readFile46(filePath, "utf-8");
|
|
88252
88384
|
const parsed = JSON.parse(raw);
|
|
88253
88385
|
const migrated = migrateUserSettingsStore(parsed);
|
|
88254
88386
|
cache2 = migrated.settings;
|
|
@@ -88295,7 +88427,7 @@ function buildUserSettingsStore(filePath) {
|
|
|
88295
88427
|
}
|
|
88296
88428
|
async function readSettingsFromDisk() {
|
|
88297
88429
|
try {
|
|
88298
|
-
const raw = await
|
|
88430
|
+
const raw = await readFile46(filePath, "utf-8");
|
|
88299
88431
|
return migrateUserSettingsStore(JSON.parse(raw)).settings;
|
|
88300
88432
|
} catch (err3) {
|
|
88301
88433
|
if (isEnoent(err3)) return { ...DEFAULT_USER_SETTINGS };
|
|
@@ -93614,7 +93746,11 @@ var ThreadEventProcessor = class {
|
|
|
93614
93746
|
}
|
|
93615
93747
|
this.#deps.callbacks.onMessageStored?.(result.seqNo, echoMsgId, "human", event.mark);
|
|
93616
93748
|
if (meta?.correlationId) {
|
|
93617
|
-
this.#deps.callbacks.onUserMessageConfirmed?.(
|
|
93749
|
+
this.#deps.callbacks.onUserMessageConfirmed?.(
|
|
93750
|
+
meta.correlationId,
|
|
93751
|
+
event.mark,
|
|
93752
|
+
result.existingMessage?.messageId ?? echoMsgId
|
|
93753
|
+
);
|
|
93618
93754
|
}
|
|
93619
93755
|
}
|
|
93620
93756
|
async #handleInitReceived(event) {
|
|
@@ -94847,9 +94983,9 @@ var Thread = class {
|
|
|
94847
94983
|
// src/services/plan/plan-handler.ts
|
|
94848
94984
|
import { randomUUID as randomUUID23 } from "crypto";
|
|
94849
94985
|
import { existsSync as existsSync11, readdirSync as readdirSync5, statSync as statSync5 } from "fs";
|
|
94850
|
-
import { mkdir as mkdir37, readFile as
|
|
94986
|
+
import { mkdir as mkdir37, readFile as readFile48, writeFile as writeFile28 } from "fs/promises";
|
|
94851
94987
|
import { homedir as homedir13 } from "os";
|
|
94852
|
-
import { dirname as dirname37, join as
|
|
94988
|
+
import { dirname as dirname37, join as join80 } from "path";
|
|
94853
94989
|
|
|
94854
94990
|
// src/services/plan-backfill/plan-lazy-rebuild.ts
|
|
94855
94991
|
var SETTLE_BUDGET_MS = 2e3;
|
|
@@ -95022,7 +95158,7 @@ function decideWatchResolved(trigger, snapshot) {
|
|
|
95022
95158
|
// src/services/plan/plan-file-bridge.ts
|
|
95023
95159
|
import { createHash as createHash15, randomUUID as randomUUID22 } from "crypto";
|
|
95024
95160
|
import { existsSync as existsSync9 } from "fs";
|
|
95025
|
-
import { readFile as
|
|
95161
|
+
import { readFile as readFile47, rename as rename18, stat as stat21, writeFile as writeFile27 } from "fs/promises";
|
|
95026
95162
|
import { basename as basename13, dirname as dirname36 } from "path";
|
|
95027
95163
|
var FILE_READ_MAX_RETRIES = 3;
|
|
95028
95164
|
var FILE_READ_RETRY_BASE_MS = 200;
|
|
@@ -95439,7 +95575,7 @@ var PlanFileBridge = class _PlanFileBridge {
|
|
|
95439
95575
|
async #existingFileSize() {
|
|
95440
95576
|
if (!this.#filePath) return 0;
|
|
95441
95577
|
try {
|
|
95442
|
-
return (await
|
|
95578
|
+
return (await stat21(this.#filePath)).size;
|
|
95443
95579
|
} catch {
|
|
95444
95580
|
return 0;
|
|
95445
95581
|
}
|
|
@@ -95448,7 +95584,7 @@ var PlanFileBridge = class _PlanFileBridge {
|
|
|
95448
95584
|
let lastError;
|
|
95449
95585
|
for (let attempt = 0; attempt < FILE_READ_MAX_RETRIES; attempt++) {
|
|
95450
95586
|
try {
|
|
95451
|
-
return await
|
|
95587
|
+
return await readFile47(filePath, "utf-8");
|
|
95452
95588
|
} catch (err3) {
|
|
95453
95589
|
lastError = err3;
|
|
95454
95590
|
const msg = err3 instanceof Error ? err3.message : String(err3);
|
|
@@ -95728,8 +95864,8 @@ function greedyLCS(a, b2) {
|
|
|
95728
95864
|
// src/services/plan/plan-file-watcher.ts
|
|
95729
95865
|
import { existsSync as existsSync10 } from "fs";
|
|
95730
95866
|
import { homedir as homedir12 } from "os";
|
|
95731
|
-
import { join as
|
|
95732
|
-
var DEFAULT_PLANS_DIR =
|
|
95867
|
+
import { join as join79 } from "path";
|
|
95868
|
+
var DEFAULT_PLANS_DIR = join79(homedir12(), ".claude", "plans");
|
|
95733
95869
|
var PLAN_WATCH_TIMEOUT_MS = 1e4;
|
|
95734
95870
|
var PLAN_WATCH_DEBOUNCE_MS = 250;
|
|
95735
95871
|
function createPlanFileWatcher(deps) {
|
|
@@ -96364,7 +96500,7 @@ var PlanHandler = class {
|
|
|
96364
96500
|
}
|
|
96365
96501
|
async #readFileForRehydrate(filePath) {
|
|
96366
96502
|
try {
|
|
96367
|
-
return await
|
|
96503
|
+
return await readFile48(filePath, "utf-8");
|
|
96368
96504
|
} catch (err3) {
|
|
96369
96505
|
this.#deps.log({
|
|
96370
96506
|
event: "plan_bridge_rehydrate_read_failed",
|
|
@@ -96511,7 +96647,7 @@ var PlanHandler = class {
|
|
|
96511
96647
|
* Called when a Write tool result mentions a file in ~/.claude/plans/.
|
|
96512
96648
|
*/
|
|
96513
96649
|
trackCreatedFile(filePath) {
|
|
96514
|
-
const plansDir =
|
|
96650
|
+
const plansDir = join80(homedir13(), ".claude", "plans");
|
|
96515
96651
|
if (filePath.startsWith(plansDir) && filePath.endsWith(".md")) {
|
|
96516
96652
|
this.#createdPlanFiles.add(filePath);
|
|
96517
96653
|
this.#deps.log({
|
|
@@ -96605,7 +96741,7 @@ var PlanHandler = class {
|
|
|
96605
96741
|
this.#assertNativePlanOwner(threadId);
|
|
96606
96742
|
this.#nativeThreadId = threadId;
|
|
96607
96743
|
this.#nativeRevisionPending = true;
|
|
96608
|
-
const filePath =
|
|
96744
|
+
const filePath = join80(getShipyardHome(), "plans", `${this.#deps.taskId}.md`);
|
|
96609
96745
|
try {
|
|
96610
96746
|
await mkdir37(dirname37(filePath), { recursive: true });
|
|
96611
96747
|
await writeFile28(filePath, content, "utf-8");
|
|
@@ -97129,12 +97265,12 @@ var PlanHandler = class {
|
|
|
97129
97265
|
}).filter((f2) => f2 !== null).sort((a, b2) => b2.mtime - a.mtime)[0];
|
|
97130
97266
|
return newest?.path ?? null;
|
|
97131
97267
|
}
|
|
97132
|
-
const plansDir =
|
|
97268
|
+
const plansDir = join80(homedir13(), ".claude", "plans");
|
|
97133
97269
|
if (!existsSync11(plansDir)) return null;
|
|
97134
97270
|
try {
|
|
97135
97271
|
const files = readdirSync5(plansDir).filter((f2) => f2.endsWith(".md")).map((f2) => ({
|
|
97136
|
-
path:
|
|
97137
|
-
mtime: statSync5(
|
|
97272
|
+
path: join80(plansDir, f2),
|
|
97273
|
+
mtime: statSync5(join80(plansDir, f2)).mtimeMs
|
|
97138
97274
|
})).sort((a, b2) => b2.mtime - a.mtime);
|
|
97139
97275
|
const recent = files[0];
|
|
97140
97276
|
if (recent && Date.now() - recent.mtime < 3e4) return recent.path;
|
|
@@ -99687,8 +99823,8 @@ var RewindCheckpointHandler = class _RewindCheckpointHandler {
|
|
|
99687
99823
|
};
|
|
99688
99824
|
|
|
99689
99825
|
// src/services/task/side-thread-registry.ts
|
|
99690
|
-
import { mkdir as mkdir38, readFile as
|
|
99691
|
-
import { dirname as dirname38, join as
|
|
99826
|
+
import { mkdir as mkdir38, readFile as readFile49, rename as rename19, writeFile as writeFile29 } from "fs/promises";
|
|
99827
|
+
import { dirname as dirname38, join as join81 } from "path";
|
|
99692
99828
|
var ThreadFileSchema = external_exports.object({
|
|
99693
99829
|
threads: external_exports.record(external_exports.string(), ThreadMetadataSchema)
|
|
99694
99830
|
});
|
|
@@ -100207,7 +100343,7 @@ var SideThreadRegistry = class {
|
|
|
100207
100343
|
}
|
|
100208
100344
|
/** Persistence */
|
|
100209
100345
|
#filePath() {
|
|
100210
|
-
return
|
|
100346
|
+
return join81(this.#deps.dataDir, "threads", `${this.#deps.taskId}.json`);
|
|
100211
100347
|
}
|
|
100212
100348
|
async #ensureLoaded() {
|
|
100213
100349
|
if (this.#loadedFromDisk.has(this.#deps.taskId)) return;
|
|
@@ -100227,7 +100363,7 @@ var SideThreadRegistry = class {
|
|
|
100227
100363
|
const filePath = this.#filePath();
|
|
100228
100364
|
let raw;
|
|
100229
100365
|
try {
|
|
100230
|
-
raw = await
|
|
100366
|
+
raw = await readFile49(filePath, "utf-8");
|
|
100231
100367
|
} catch (err3) {
|
|
100232
100368
|
if (isEnoent(err3)) return;
|
|
100233
100369
|
throw err3;
|
|
@@ -103317,9 +103453,9 @@ function buildProfileRewindCapability(resolve15, runtimeId, primary) {
|
|
|
103317
103453
|
|
|
103318
103454
|
// src/services/task/cc-task-file-store.ts
|
|
103319
103455
|
import { existsSync as existsSync12 } from "fs";
|
|
103320
|
-
import { readdir as readdir22, readFile as
|
|
103456
|
+
import { readdir as readdir22, readFile as readFile50 } from "fs/promises";
|
|
103321
103457
|
import { homedir as homedir14 } from "os";
|
|
103322
|
-
import { basename as basename14, dirname as dirname39, join as
|
|
103458
|
+
import { basename as basename14, dirname as dirname39, join as join82 } from "path";
|
|
103323
103459
|
var VALID_STATUSES = /* @__PURE__ */ new Set(["pending", "in_progress", "completed"]);
|
|
103324
103460
|
var IDLE_DETACH_MS = 5 * 60 * 1e3;
|
|
103325
103461
|
var IDLE_SWEEP_INTERVAL_MS = 6e4;
|
|
@@ -103335,7 +103471,7 @@ function isCCTaskFile(value) {
|
|
|
103335
103471
|
}
|
|
103336
103472
|
function createCCTaskFileWatcher(listId, log) {
|
|
103337
103473
|
const sanitizedId = sanitize(listId);
|
|
103338
|
-
const dir =
|
|
103474
|
+
const dir = join82(homedir14(), ".claude", "tasks", sanitizedId);
|
|
103339
103475
|
const targetDirName = basename14(dir);
|
|
103340
103476
|
const parentDir = dirname39(dir);
|
|
103341
103477
|
const watchState = {
|
|
@@ -103371,9 +103507,9 @@ function createCCTaskFileWatcher(listId, log) {
|
|
|
103371
103507
|
return tasks;
|
|
103372
103508
|
}
|
|
103373
103509
|
async function readTask(taskId) {
|
|
103374
|
-
const filePath =
|
|
103510
|
+
const filePath = join82(dir, `${taskId}.json`);
|
|
103375
103511
|
try {
|
|
103376
|
-
const raw = await
|
|
103512
|
+
const raw = await readFile50(filePath, "utf-8");
|
|
103377
103513
|
const parsed = JSON.parse(raw);
|
|
103378
103514
|
if (isCCTaskFile(parsed)) return parsed;
|
|
103379
103515
|
log?.({
|
|
@@ -103438,7 +103574,7 @@ function createCCTaskFileWatcher(listId, log) {
|
|
|
103438
103574
|
watchState.parentSub = null;
|
|
103439
103575
|
return;
|
|
103440
103576
|
}
|
|
103441
|
-
if (ev.path.endsWith(targetDirName) || ev.path ===
|
|
103577
|
+
if (ev.path.endsWith(targetDirName) || ev.path === join82(parentDir, targetDirName)) {
|
|
103442
103578
|
void ensureDirWatcher();
|
|
103443
103579
|
break;
|
|
103444
103580
|
}
|
|
@@ -103555,7 +103691,7 @@ function createCCTaskFileWatcher(listId, log) {
|
|
|
103555
103691
|
// src/services/task/cc-task-file-writer.ts
|
|
103556
103692
|
import { createHash as createHash16 } from "crypto";
|
|
103557
103693
|
import { mkdir as mkdir39, readdir as readdir23, rename as rename20, unlink as unlink14, writeFile as writeFile30 } from "fs/promises";
|
|
103558
|
-
import { join as
|
|
103694
|
+
import { join as join83 } from "path";
|
|
103559
103695
|
function contentHash2(data) {
|
|
103560
103696
|
return createHash16("sha256").update(data).digest("hex").slice(0, 16);
|
|
103561
103697
|
}
|
|
@@ -103571,7 +103707,7 @@ async function writeTasks(dir, tasks, hashes) {
|
|
|
103571
103707
|
const json = JSON.stringify(structuredTaskToCCFile(task), null, 2);
|
|
103572
103708
|
const hash = contentHash2(json);
|
|
103573
103709
|
if (hashes.get(id) === hash) continue;
|
|
103574
|
-
await atomicWriteFile2(
|
|
103710
|
+
await atomicWriteFile2(join83(dir, `${id}.json`), json);
|
|
103575
103711
|
hashes.set(id, hash);
|
|
103576
103712
|
}
|
|
103577
103713
|
return targetIds;
|
|
@@ -103587,7 +103723,7 @@ async function removeStaleFiles(dir, targetIds, hashes) {
|
|
|
103587
103723
|
if (!entry.endsWith(".json")) continue;
|
|
103588
103724
|
const id = entry.slice(0, -".json".length);
|
|
103589
103725
|
if (!targetIds.has(id) && hashes.has(id)) {
|
|
103590
|
-
await unlink14(
|
|
103726
|
+
await unlink14(join83(dir, entry)).catch(() => {
|
|
103591
103727
|
});
|
|
103592
103728
|
hashes.delete(id);
|
|
103593
103729
|
}
|
|
@@ -104219,10 +104355,10 @@ var StructuredTaskTracker = class {
|
|
|
104219
104355
|
import { unwatchFile, watchFile } from "fs";
|
|
104220
104356
|
import { open as open5 } from "fs/promises";
|
|
104221
104357
|
import { homedir as homedir15 } from "os";
|
|
104222
|
-
import { join as
|
|
104358
|
+
import { join as join84 } from "path";
|
|
104223
104359
|
function computeTranscriptPath(cwd, sessionId, taskId) {
|
|
104224
104360
|
const cwdSlug = cwd.replace(/[^a-zA-Z0-9]/g, "-").slice(0, 200);
|
|
104225
|
-
return
|
|
104361
|
+
return join84(
|
|
104226
104362
|
homedir15(),
|
|
104227
104363
|
".claude",
|
|
104228
104364
|
"projects",
|
|
@@ -104403,9 +104539,9 @@ var SubagentTranscriptWatcher = class {
|
|
|
104403
104539
|
let fh = null;
|
|
104404
104540
|
try {
|
|
104405
104541
|
fh = await open5(this.#config.transcriptPath, "r");
|
|
104406
|
-
const
|
|
104407
|
-
if (
|
|
104408
|
-
const bytesToRead =
|
|
104542
|
+
const stat23 = await fh.stat();
|
|
104543
|
+
if (stat23.size <= this.#bytesRead) return;
|
|
104544
|
+
const bytesToRead = stat23.size - this.#bytesRead;
|
|
104409
104545
|
const buffer = Buffer.alloc(bytesToRead);
|
|
104410
104546
|
const { bytesRead } = await fh.read(buffer, 0, bytesToRead, this.#bytesRead);
|
|
104411
104547
|
this.#bytesRead += bytesRead;
|
|
@@ -104955,13 +105091,40 @@ function trackPlanFileCreation(content, onPlanFile) {
|
|
|
104955
105091
|
}
|
|
104956
105092
|
}
|
|
104957
105093
|
|
|
105094
|
+
// src/services/task/orchestrator/task-unpushed-selection.ts
|
|
105095
|
+
function isUnconfirmedHuman(message, excludeCorrelationIds) {
|
|
105096
|
+
if (message.senderKind !== "human") return false;
|
|
105097
|
+
const { correlationId } = message;
|
|
105098
|
+
if (!correlationId) return false;
|
|
105099
|
+
if (message.sdkUuid) return false;
|
|
105100
|
+
return !excludeCorrelationIds?.has(correlationId);
|
|
105101
|
+
}
|
|
105102
|
+
function selectUnpushedMessages(messages, excludeCorrelationIds) {
|
|
105103
|
+
let lastAgentIndex = -1;
|
|
105104
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
105105
|
+
if (messages[i]?.senderKind === "agent") {
|
|
105106
|
+
lastAgentIndex = i;
|
|
105107
|
+
break;
|
|
105108
|
+
}
|
|
105109
|
+
}
|
|
105110
|
+
const selected = [];
|
|
105111
|
+
let supersededByAgentReply = 0;
|
|
105112
|
+
for (let i = 0; i < messages.length; i++) {
|
|
105113
|
+
const message = messages[i];
|
|
105114
|
+
if (message === void 0 || !isUnconfirmedHuman(message, excludeCorrelationIds)) continue;
|
|
105115
|
+
if (i < lastAgentIndex) supersededByAgentReply++;
|
|
105116
|
+
else selected.push(message);
|
|
105117
|
+
}
|
|
105118
|
+
return { messages: selected, supersededByAgentReply };
|
|
105119
|
+
}
|
|
105120
|
+
|
|
104958
105121
|
// src/services/token-counter.ts
|
|
104959
105122
|
import { spawn as spawn13 } from "child_process";
|
|
104960
105123
|
import { createHash as createHash17 } from "crypto";
|
|
104961
105124
|
import { unlink as unlink15, writeFile as writeFile31 } from "fs/promises";
|
|
104962
105125
|
import { createRequire as createRequire4 } from "module";
|
|
104963
105126
|
import { tmpdir as tmpdir2 } from "os";
|
|
104964
|
-
import { join as
|
|
105127
|
+
import { join as join85 } from "path";
|
|
104965
105128
|
function spawnCollect(bin, args, opts) {
|
|
104966
105129
|
return new Promise((resolve15, reject) => {
|
|
104967
105130
|
const child = spawn13(bin, args, {
|
|
@@ -105019,7 +105182,7 @@ function resolveDaemonNodeModules(log) {
|
|
|
105019
105182
|
} catch {
|
|
105020
105183
|
}
|
|
105021
105184
|
try {
|
|
105022
|
-
const cwdRequire = createRequire4(
|
|
105185
|
+
const cwdRequire = createRequire4(join85(process.cwd(), "package.json"));
|
|
105023
105186
|
const sdkPath = cwdRequire.resolve("@modelcontextprotocol/sdk/server/mcp.js");
|
|
105024
105187
|
const idx = sdkPath.lastIndexOf("node_modules");
|
|
105025
105188
|
if (idx >= 0) return sdkPath.slice(0, idx + "node_modules".length);
|
|
@@ -105029,7 +105192,7 @@ function resolveDaemonNodeModules(log) {
|
|
|
105029
105192
|
error: err3 instanceof Error ? err3.message : String(err3)
|
|
105030
105193
|
});
|
|
105031
105194
|
}
|
|
105032
|
-
return
|
|
105195
|
+
return join85(process.cwd(), "node_modules");
|
|
105033
105196
|
}
|
|
105034
105197
|
function planTokenCount(systemPrompt, metadata, cwd, model, mcpServers) {
|
|
105035
105198
|
return {
|
|
@@ -105228,7 +105391,7 @@ async function serializeMcpConfig(servers, allToolNames, daemonNodeModules, rese
|
|
|
105228
105391
|
if (isReservedMcpServerName(serverName, reservedServerNames)) continue;
|
|
105229
105392
|
const script = buildStubServerScript(serverName, tools);
|
|
105230
105393
|
if (!script) continue;
|
|
105231
|
-
const stubPath =
|
|
105394
|
+
const stubPath = join85(tmpdir2(), `shipyard-mcp-stub-${serverName}-${Date.now()}.cjs`);
|
|
105232
105395
|
await writeFile31(stubPath, script, "utf-8");
|
|
105233
105396
|
stubPaths.push(stubPath);
|
|
105234
105397
|
mcpServers[serverName] = {
|
|
@@ -105254,7 +105417,7 @@ async function prepareTokenCountArgs(plan, log, reservedServerNames = SDK_RESERV
|
|
|
105254
105417
|
reservedServerNames
|
|
105255
105418
|
);
|
|
105256
105419
|
if (!serialized.config) return { args, mcpConfigPath: null, stubPaths: serialized.stubPaths };
|
|
105257
|
-
const mcpConfigPath =
|
|
105420
|
+
const mcpConfigPath = join85(tmpdir2(), `shipyard-mcp-${Date.now()}.json`);
|
|
105258
105421
|
await writeFile31(mcpConfigPath, JSON.stringify(serialized.config), "utf-8");
|
|
105259
105422
|
args.push("--mcp-config", mcpConfigPath);
|
|
105260
105423
|
return { args, mcpConfigPath, stubPaths: serialized.stubPaths };
|
|
@@ -105816,22 +105979,21 @@ var Task = class {
|
|
|
105816
105979
|
correlationId: meta?.correlationIds[0]
|
|
105817
105980
|
};
|
|
105818
105981
|
},
|
|
105819
|
-
onUserMessageConfirmed: (correlationId, mark) => {
|
|
105982
|
+
onUserMessageConfirmed: (correlationId, mark, storedMessageId) => {
|
|
105820
105983
|
const currentMeta = this.#pendingMessageMeta[0];
|
|
105821
105984
|
const idsToAck = currentMeta?.correlationIds ?? [correlationId];
|
|
105822
105985
|
if (mark) {
|
|
105823
|
-
const [
|
|
105824
|
-
const primaryId = primary ?? correlationId;
|
|
105986
|
+
const [, ...secondary] = idsToAck;
|
|
105825
105987
|
this.#deps.store.stampSdkUuid(
|
|
105826
105988
|
this.#deps.channelId,
|
|
105827
|
-
|
|
105989
|
+
storedMessageId,
|
|
105828
105990
|
mark.ref,
|
|
105829
105991
|
secondary.length > 0 ? secondary : void 0
|
|
105830
105992
|
).catch((err3) => {
|
|
105831
105993
|
this.#deps.log({
|
|
105832
105994
|
event: "stamp_sdk_uuid_failed",
|
|
105833
105995
|
taskId: this.#deps.taskId,
|
|
105834
|
-
|
|
105996
|
+
messageId: storedMessageId,
|
|
105835
105997
|
error: err3 instanceof Error ? err3.message : String(err3)
|
|
105836
105998
|
});
|
|
105837
105999
|
});
|
|
@@ -106692,21 +106854,23 @@ var Task = class {
|
|
|
106692
106854
|
}
|
|
106693
106855
|
/**
|
|
106694
106856
|
* Sub-phase 7b: Rehydrate persisted-but-unpushed user messages after daemon restart.
|
|
106695
|
-
*
|
|
106696
|
-
*
|
|
106697
|
-
*
|
|
106698
|
-
* so the next subprocess spawn receives them in order.
|
|
106699
|
-
*
|
|
106700
|
-
* Pass excludeCorrelationIds to skip messages already handled by rehydrateCollabQueue,
|
|
106701
|
-
* preventing double-send of the same message to the subprocess.
|
|
106702
|
-
*
|
|
106703
|
-
* Returns the number of messages re-injected.
|
|
106857
|
+
* Bounded to the trailing human segment — selectUnpushedMessages explains why
|
|
106858
|
+
* an agent reply outranks a missing sdkUuid. Pass excludeCorrelationIds to skip
|
|
106859
|
+
* messages already handled by rehydrateCollabQueue. Returns the count injected.
|
|
106704
106860
|
*/
|
|
106705
106861
|
async rehydrateUnpushedMessages(excludeCorrelationIds) {
|
|
106706
106862
|
const messages = await this.#deps.store.getMessages(this.#deps.channelId);
|
|
106707
|
-
const unpushed =
|
|
106708
|
-
|
|
106863
|
+
const { messages: unpushed, supersededByAgentReply } = selectUnpushedMessages(
|
|
106864
|
+
messages,
|
|
106865
|
+
excludeCorrelationIds
|
|
106709
106866
|
);
|
|
106867
|
+
if (supersededByAgentReply > 0) {
|
|
106868
|
+
this.#deps.log({
|
|
106869
|
+
event: "unpushed_messages_superseded",
|
|
106870
|
+
taskId: this.#deps.taskId,
|
|
106871
|
+
count: supersededByAgentReply
|
|
106872
|
+
});
|
|
106873
|
+
}
|
|
106710
106874
|
if (unpushed.length === 0) return 0;
|
|
106711
106875
|
this.#ensureFileWatcherAttached();
|
|
106712
106876
|
for (const msg of unpushed) {
|
|
@@ -111877,7 +112041,7 @@ async function createDaemon(deps) {
|
|
|
111877
112041
|
const annotationStore = buildAnnotationStore(deps.dataDir);
|
|
111878
112042
|
const deliverableStore = buildDeliverableStore(deps.dataDir);
|
|
111879
112043
|
const resourceRegistry = createResourceRegistry();
|
|
111880
|
-
const assetStore = buildAssetStore(
|
|
112044
|
+
const assetStore = buildAssetStore(join86(deps.dataDir, "assets"));
|
|
111881
112045
|
const shipyardResolver = createShipyardResolver();
|
|
111882
112046
|
shipyardResolver.addSubResolver("asset", createAssetResolver(assetStore));
|
|
111883
112047
|
const pluginResourceResolver = new PluginResourceResolver(deps.log);
|
|
@@ -111908,10 +112072,10 @@ async function createDaemon(deps) {
|
|
|
111908
112072
|
workspaceRoot: deps.workspaceRoot,
|
|
111909
112073
|
log: deps.log
|
|
111910
112074
|
});
|
|
111911
|
-
const userSettingsStore = buildUserSettingsStore(
|
|
111912
|
-
const projectsStore = buildProjectsStore(
|
|
112075
|
+
const userSettingsStore = buildUserSettingsStore(join86(deps.dataDir, "user-settings.json"));
|
|
112076
|
+
const projectsStore = buildProjectsStore(join86(deps.dataDir, "projects.json"));
|
|
111913
112077
|
const credentialsVaultStore = buildCredentialsVaultStore(
|
|
111914
|
-
|
|
112078
|
+
join86(deps.dataDir, "credentials-vault.json")
|
|
111915
112079
|
);
|
|
111916
112080
|
const cursorVaultKeyRef = { current: null };
|
|
111917
112081
|
let resolveCursorVaultKey;
|
|
@@ -112379,7 +112543,7 @@ async function createDaemon(deps) {
|
|
|
112379
112543
|
taskId: args.taskId,
|
|
112380
112544
|
agentSystem: args.agentSystem,
|
|
112381
112545
|
environmentKey: args.cwd,
|
|
112382
|
-
pluginsDir:
|
|
112546
|
+
pluginsDir: join86(deps.shipyardHome, "plugins"),
|
|
112383
112547
|
vizWatcher: getOrCreateVizWatcher(args.taskId).watcher,
|
|
112384
112548
|
mode: "task",
|
|
112385
112549
|
ownerUserId: deps.auth.userId,
|
|
@@ -112517,7 +112681,7 @@ async function createDaemon(deps) {
|
|
|
112517
112681
|
/** Claude in-process harness — Codex uses the HTTP path with 'codex' above. */
|
|
112518
112682
|
agentSystem: AGENT_SYSTEM_CLAUDE_CODE,
|
|
112519
112683
|
environmentKey: args.cwd,
|
|
112520
|
-
pluginsDir:
|
|
112684
|
+
pluginsDir: join86(deps.shipyardHome, "plugins"),
|
|
112521
112685
|
vizWatcher: args.vizWatcher,
|
|
112522
112686
|
mode: args.mode ?? "task",
|
|
112523
112687
|
ownerUserId: deps.auth.userId,
|
|
@@ -113596,7 +113760,7 @@ async function createDaemon(deps) {
|
|
|
113596
113760
|
deps.metricsCollector
|
|
113597
113761
|
);
|
|
113598
113762
|
const planDocGapReporter = startPlanDocPersistenceGapReporter({
|
|
113599
|
-
loroDir:
|
|
113763
|
+
loroDir: join86(deps.dataDir, "loro"),
|
|
113600
113764
|
listTasks: () => taskStateStore.listTasks(),
|
|
113601
113765
|
log: deps.log,
|
|
113602
113766
|
metricsCollector: deps.metricsCollector
|
|
@@ -113612,7 +113776,7 @@ async function createDaemon(deps) {
|
|
|
113612
113776
|
const stallProfilerConfig = getStallProfilerConfig();
|
|
113613
113777
|
const stallProfiler = new StallProfiler({
|
|
113614
113778
|
log: deps.log,
|
|
113615
|
-
outDir:
|
|
113779
|
+
outDir: join86(deps.dataDir, "stall-profiles"),
|
|
113616
113780
|
thresholdMs: stallProfilerConfig.thresholdMs,
|
|
113617
113781
|
captureMs: stallProfilerConfig.captureMs,
|
|
113618
113782
|
rateLimitMs: stallProfilerConfig.rateLimitMs
|
|
@@ -114264,8 +114428,8 @@ import { existsSync as existsSync14 } from "fs";
|
|
|
114264
114428
|
// src/services/bootstrap/self-update.ts
|
|
114265
114429
|
import { execFile as execFile13, spawn as spawn14 } from "child_process";
|
|
114266
114430
|
import { createHash as createHash18 } from "crypto";
|
|
114267
|
-
import { chmod as chmod4, mkdir as mkdir41, readFile as
|
|
114268
|
-
import { join as
|
|
114431
|
+
import { chmod as chmod4, mkdir as mkdir41, readFile as readFile51, rename as rename21, unlink as unlink16, writeFile as writeFile32 } from "fs/promises";
|
|
114432
|
+
import { join as join87 } from "path";
|
|
114269
114433
|
|
|
114270
114434
|
// src/services/bootstrap/self-update-installer-scripts.ts
|
|
114271
114435
|
function buildPosixInstallerScript(params) {
|
|
@@ -114667,7 +114831,7 @@ async function downloadTarball(url2, destPath, fetchFn) {
|
|
|
114667
114831
|
throw new Error(`download failed: HTTP ${response.status} ${response.statusText}`);
|
|
114668
114832
|
}
|
|
114669
114833
|
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
114670
|
-
await mkdir41(
|
|
114834
|
+
await mkdir41(join87(destPath, ".."), { recursive: true });
|
|
114671
114835
|
try {
|
|
114672
114836
|
await writeFile32(tmpPath, bytes);
|
|
114673
114837
|
await rename21(tmpPath, destPath);
|
|
@@ -114686,7 +114850,7 @@ async function downloadTarball(url2, destPath, fetchFn) {
|
|
|
114686
114850
|
}
|
|
114687
114851
|
async function verifyChecksum(path8, expectedHash) {
|
|
114688
114852
|
const algo = expectedHash.length === 40 ? "sha1" : "sha256";
|
|
114689
|
-
const raw = await
|
|
114853
|
+
const raw = await readFile51(path8);
|
|
114690
114854
|
const actual = createHash18(algo).update(raw).digest("hex");
|
|
114691
114855
|
if (actual !== expectedHash) {
|
|
114692
114856
|
try {
|
|
@@ -114697,7 +114861,7 @@ async function verifyChecksum(path8, expectedHash) {
|
|
|
114697
114861
|
}
|
|
114698
114862
|
}
|
|
114699
114863
|
async function stageInstallerScript(scriptPath, params) {
|
|
114700
|
-
await mkdir41(
|
|
114864
|
+
await mkdir41(join87(scriptPath, ".."), { recursive: true });
|
|
114701
114865
|
const body = process.platform === "win32" ? buildWindowsInstallerScript(params) : buildPosixInstallerScript(params);
|
|
114702
114866
|
await writeFile32(scriptPath, body);
|
|
114703
114867
|
await chmod4(scriptPath, 493);
|
|
@@ -114747,16 +114911,16 @@ function buildInstallerParams(state, deps) {
|
|
|
114747
114911
|
targetVersion: state.resolved.version,
|
|
114748
114912
|
previousVersion: deps.currentVersion,
|
|
114749
114913
|
parentPid: deps.pid,
|
|
114750
|
-
statusFilePath:
|
|
114751
|
-
pidFilePath:
|
|
114752
|
-
logPath:
|
|
114753
|
-
snapshotPath:
|
|
114914
|
+
statusFilePath: join87(deps.shipyardHome, "update-status.json"),
|
|
114915
|
+
pidFilePath: join87(deps.shipyardHome, "daemon.pid"),
|
|
114916
|
+
logPath: join87(deps.shipyardHome, "updates", `install-${deps.pid}.log`),
|
|
114917
|
+
snapshotPath: join87(deps.shipyardHome, "updates", `rollback-${deps.currentVersion}`),
|
|
114754
114918
|
npmBin: "npm"
|
|
114755
114919
|
};
|
|
114756
114920
|
}
|
|
114757
114921
|
function tarballPathFor(shipyardHome, version, shasum) {
|
|
114758
114922
|
const shaPrefix = shasum.slice(0, 12);
|
|
114759
|
-
return
|
|
114923
|
+
return join87(shipyardHome, "updates", `${version}-${shaPrefix}.tgz`);
|
|
114760
114924
|
}
|
|
114761
114925
|
async function runResolveStep(step, state, deps) {
|
|
114762
114926
|
const resolver = deps.resolveVersion ?? defaultResolveVersion;
|
|
@@ -115804,8 +115968,8 @@ function buildLocalDirectChannelCallbacks(deps) {
|
|
|
115804
115968
|
}
|
|
115805
115969
|
|
|
115806
115970
|
// src/services/skills-cache/codex-skills-cache.ts
|
|
115807
|
-
import { mkdir as mkdir42, readFile as
|
|
115808
|
-
import { dirname as dirname41, join as
|
|
115971
|
+
import { mkdir as mkdir42, readFile as readFile52, rename as rename22, writeFile as writeFile33 } from "fs/promises";
|
|
115972
|
+
import { dirname as dirname41, join as join88 } from "path";
|
|
115809
115973
|
var CACHE_FILENAME = "codex-skills-cache.json";
|
|
115810
115974
|
var SkillInfoCacheEntrySchema = external_exports.object({
|
|
115811
115975
|
name: external_exports.string(),
|
|
@@ -115822,12 +115986,12 @@ var CodexSkillsCacheFileSchema = external_exports.object({
|
|
|
115822
115986
|
skills: external_exports.array(SkillInfoCacheEntrySchema)
|
|
115823
115987
|
});
|
|
115824
115988
|
function defaultCodexSkillsCachePath(shipyardHome) {
|
|
115825
|
-
return
|
|
115989
|
+
return join88(shipyardHome, "state", CACHE_FILENAME);
|
|
115826
115990
|
}
|
|
115827
115991
|
async function loadCodexSkillsCache(path8) {
|
|
115828
115992
|
let raw;
|
|
115829
115993
|
try {
|
|
115830
|
-
raw = await
|
|
115994
|
+
raw = await readFile52(path8, "utf-8");
|
|
115831
115995
|
} catch (err3) {
|
|
115832
115996
|
if (isEnoent(err3)) return null;
|
|
115833
115997
|
logger.warn(
|
|
@@ -115884,13 +116048,13 @@ async function saveCodexSkillsCache(path8, cache2) {
|
|
|
115884
116048
|
}
|
|
115885
116049
|
|
|
115886
116050
|
// src/services/skills-mirror/manager.ts
|
|
115887
|
-
import { lstat as lstat6, mkdir as mkdir44, readlink, stat as
|
|
116051
|
+
import { lstat as lstat6, mkdir as mkdir44, readlink, stat as stat22, symlink, unlink as unlink18 } from "fs/promises";
|
|
115888
116052
|
import { homedir as homedir16 } from "os";
|
|
115889
|
-
import { dirname as dirname43, join as
|
|
116053
|
+
import { dirname as dirname43, join as join90 } from "path";
|
|
115890
116054
|
|
|
115891
116055
|
// src/services/skills-mirror/manifest.ts
|
|
115892
|
-
import { mkdir as mkdir43, readFile as
|
|
115893
|
-
import { dirname as dirname42, join as
|
|
116056
|
+
import { mkdir as mkdir43, readFile as readFile53, rename as rename23, unlink as unlink17, writeFile as writeFile34 } from "fs/promises";
|
|
116057
|
+
import { dirname as dirname42, join as join89 } from "path";
|
|
115894
116058
|
var MANIFEST_VERSION = 1;
|
|
115895
116059
|
var ManifestEntrySchema = external_exports.object({
|
|
115896
116060
|
/** Display name of the skill (e.g. `qa`, or `plugin:name` when namespaced). */
|
|
@@ -115910,11 +116074,11 @@ function emptyManifest() {
|
|
|
115910
116074
|
return { version: MANIFEST_VERSION, entries: [] };
|
|
115911
116075
|
}
|
|
115912
116076
|
function defaultManifestPath(shipyardHome) {
|
|
115913
|
-
return
|
|
116077
|
+
return join89(shipyardHome, "state", "skill-mirror-manifest.json");
|
|
115914
116078
|
}
|
|
115915
116079
|
async function loadManifest(path8) {
|
|
115916
116080
|
try {
|
|
115917
|
-
const raw = await
|
|
116081
|
+
const raw = await readFile53(path8, "utf-8");
|
|
115918
116082
|
const parsed = ManifestFileSchema.safeParse(JSON.parse(raw));
|
|
115919
116083
|
if (!parsed.success) return emptyManifest();
|
|
115920
116084
|
return parsed.data;
|
|
@@ -115941,15 +116105,15 @@ async function deleteManifest(path8) {
|
|
|
115941
116105
|
function defaultPaths() {
|
|
115942
116106
|
const home = homedir16();
|
|
115943
116107
|
return {
|
|
115944
|
-
claudeSkillsDir:
|
|
115945
|
-
codexSkillsDir:
|
|
116108
|
+
claudeSkillsDir: join90(home, ".claude", "skills"),
|
|
116109
|
+
codexSkillsDir: join90(home, ".agents", "skills"),
|
|
115946
116110
|
manifestPath: defaultManifestPath(getShipyardHome())
|
|
115947
116111
|
};
|
|
115948
116112
|
}
|
|
115949
116113
|
function plannedSymlinkPath(skill, paths) {
|
|
115950
116114
|
const linkName = skill.namespace ? `${skill.namespace}:${skill.name}` : skill.name;
|
|
115951
|
-
if (skill.sourceAgent === "claude-code") return
|
|
115952
|
-
if (skill.sourceAgent === "codex") return
|
|
116115
|
+
if (skill.sourceAgent === "claude-code") return join90(paths.codexSkillsDir, linkName);
|
|
116116
|
+
if (skill.sourceAgent === "codex") return join90(paths.claudeSkillsDir, linkName);
|
|
115953
116117
|
return null;
|
|
115954
116118
|
}
|
|
115955
116119
|
function isPermissionError(err3) {
|
|
@@ -116096,7 +116260,7 @@ function planMirrorActions(skills, paths) {
|
|
|
116096
116260
|
}
|
|
116097
116261
|
async function classifyManifestEntry(entry) {
|
|
116098
116262
|
try {
|
|
116099
|
-
await
|
|
116263
|
+
await stat22(entry.target);
|
|
116100
116264
|
return "retain";
|
|
116101
116265
|
} catch (err3) {
|
|
116102
116266
|
if (isEnoent(err3)) return "sweep-dangling";
|
|
@@ -116161,8 +116325,8 @@ async function ensureMirror(skills, config, paths = defaultPaths()) {
|
|
|
116161
116325
|
}
|
|
116162
116326
|
|
|
116163
116327
|
// src/services/skills-mirror/prefs.ts
|
|
116164
|
-
import { mkdir as mkdir45, readFile as
|
|
116165
|
-
import { dirname as dirname44, join as
|
|
116328
|
+
import { mkdir as mkdir45, readFile as readFile54, rename as rename24, writeFile as writeFile35 } from "fs/promises";
|
|
116329
|
+
import { dirname as dirname44, join as join91 } from "path";
|
|
116166
116330
|
var SkillsMirrorPrefsSchema = external_exports.object({
|
|
116167
116331
|
enabled: external_exports.boolean().default(false)
|
|
116168
116332
|
});
|
|
@@ -116171,11 +116335,11 @@ function defaultSkillsMirrorPrefs() {
|
|
|
116171
116335
|
return { enabled: false };
|
|
116172
116336
|
}
|
|
116173
116337
|
function prefsPath(dataDir) {
|
|
116174
|
-
return
|
|
116338
|
+
return join91(dataDir, FILENAME);
|
|
116175
116339
|
}
|
|
116176
116340
|
async function loadSkillsMirrorPrefs(dataDir) {
|
|
116177
116341
|
try {
|
|
116178
|
-
const raw = await
|
|
116342
|
+
const raw = await readFile54(prefsPath(dataDir), "utf-8");
|
|
116179
116343
|
const parsed = SkillsMirrorPrefsSchema.safeParse(JSON.parse(raw));
|
|
116180
116344
|
if (!parsed.success) return defaultSkillsMirrorPrefs();
|
|
116181
116345
|
return parsed.data;
|
|
@@ -116219,8 +116383,8 @@ async function reconcileSkillsMirror(args) {
|
|
|
116219
116383
|
|
|
116220
116384
|
// src/services/storage/daemon-settings-store.ts
|
|
116221
116385
|
import { createHash as createHash19 } from "crypto";
|
|
116222
|
-
import { mkdir as mkdir46, readFile as
|
|
116223
|
-
import { join as
|
|
116386
|
+
import { mkdir as mkdir46, readFile as readFile55 } from "fs/promises";
|
|
116387
|
+
import { join as join92 } from "path";
|
|
116224
116388
|
var ProjectSettingsSchema = external_exports.object({
|
|
116225
116389
|
disabledMcpServers: external_exports.array(external_exports.string()).optional(),
|
|
116226
116390
|
previewMigrationV36Done: external_exports.boolean().default(false)
|
|
@@ -116229,9 +116393,9 @@ function hashProjectPath(projectPath) {
|
|
|
116229
116393
|
return createHash19("sha256").update(projectPath).digest("hex").slice(0, 16);
|
|
116230
116394
|
}
|
|
116231
116395
|
function buildDaemonSettingsStore(dataDir) {
|
|
116232
|
-
const settingsDir =
|
|
116396
|
+
const settingsDir = join92(dataDir, "settings");
|
|
116233
116397
|
function settingsPath(projectPath) {
|
|
116234
|
-
return
|
|
116398
|
+
return join92(settingsDir, `${hashProjectPath(projectPath)}.json`);
|
|
116235
116399
|
}
|
|
116236
116400
|
async function ensureDir() {
|
|
116237
116401
|
await mkdir46(settingsDir, { recursive: true });
|
|
@@ -116239,7 +116403,7 @@ function buildDaemonSettingsStore(dataDir) {
|
|
|
116239
116403
|
return {
|
|
116240
116404
|
async load(projectPath) {
|
|
116241
116405
|
try {
|
|
116242
|
-
const raw = await
|
|
116406
|
+
const raw = await readFile55(settingsPath(projectPath), "utf-8");
|
|
116243
116407
|
return ProjectSettingsSchema.parse(JSON.parse(raw));
|
|
116244
116408
|
} catch (err3) {
|
|
116245
116409
|
if (isEnoent(err3)) return ProjectSettingsSchema.parse({});
|
|
@@ -116255,18 +116419,18 @@ function buildDaemonSettingsStore(dataDir) {
|
|
|
116255
116419
|
}
|
|
116256
116420
|
|
|
116257
116421
|
// src/services/storage/plugin-config-store.ts
|
|
116258
|
-
import { mkdir as mkdir47, readFile as
|
|
116259
|
-
import { join as
|
|
116422
|
+
import { mkdir as mkdir47, readFile as readFile56 } from "fs/promises";
|
|
116423
|
+
import { join as join93 } from "path";
|
|
116260
116424
|
function buildPluginConfigStore(pluginsDir) {
|
|
116261
116425
|
const cache2 = /* @__PURE__ */ new Map();
|
|
116262
116426
|
const writeQueues = /* @__PURE__ */ new Map();
|
|
116263
116427
|
function configPath(pluginId) {
|
|
116264
|
-
return
|
|
116428
|
+
return join93(pluginsDir, pluginId, "config.json");
|
|
116265
116429
|
}
|
|
116266
116430
|
async function readConfigFromDisk(pluginId) {
|
|
116267
116431
|
const fp = configPath(pluginId);
|
|
116268
116432
|
try {
|
|
116269
|
-
const raw = await
|
|
116433
|
+
const raw = await readFile56(fp, "utf-8");
|
|
116270
116434
|
const parsed = JSON.parse(raw);
|
|
116271
116435
|
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
116272
116436
|
return Object.fromEntries(Object.entries(parsed));
|
|
@@ -116315,7 +116479,7 @@ function buildPluginConfigStore(pluginsDir) {
|
|
|
116315
116479
|
const fresh = await readConfigFromDisk(pluginId);
|
|
116316
116480
|
fresh[key] = value;
|
|
116317
116481
|
cache2.set(pluginId, fresh);
|
|
116318
|
-
await mkdir47(
|
|
116482
|
+
await mkdir47(join93(pluginsDir, pluginId), { recursive: true });
|
|
116319
116483
|
await atomicWriteFile(configPath(pluginId), JSON.stringify(fresh, null, 2));
|
|
116320
116484
|
})
|
|
116321
116485
|
);
|
|
@@ -116543,7 +116707,7 @@ async function serve(options = {}) {
|
|
|
116543
116707
|
}
|
|
116544
116708
|
async function runServeBody(options, captureRefs) {
|
|
116545
116709
|
const shipyardHome = options.shipyardHome ?? getShipyardHome();
|
|
116546
|
-
const dataDir =
|
|
116710
|
+
const dataDir = join94(shipyardHome, options.isDev ? "data-dev" : "data");
|
|
116547
116711
|
const log = createChildLogger({ mode: "serve" });
|
|
116548
116712
|
log.info(
|
|
116549
116713
|
{ event: "daemon_start", version: getDaemonVersion(), pid: process.pid },
|
|
@@ -116551,7 +116715,7 @@ async function runServeBody(options, captureRefs) {
|
|
|
116551
116715
|
);
|
|
116552
116716
|
const { workspaceRoot, unscopedWorkspace, unscopedReason } = await resolveWorkspaceScope();
|
|
116553
116717
|
registerBuiltinPlugins();
|
|
116554
|
-
const pluginConfigStore = buildPluginConfigStore(
|
|
116718
|
+
const pluginConfigStore = buildPluginConfigStore(join94(dataDir, "plugins"));
|
|
116555
116719
|
await mkdir48(dataDir, { recursive: true });
|
|
116556
116720
|
log.info(
|
|
116557
116721
|
{
|
|
@@ -116644,9 +116808,9 @@ async function runServeBody(options, captureRefs) {
|
|
|
116644
116808
|
await bootstrapPhase("pid_sweep_orphans", () => pidTracker.sweepOrphans(logAdapter));
|
|
116645
116809
|
await bootstrapPhase(
|
|
116646
116810
|
"legacy_epoch_prune",
|
|
116647
|
-
() => pruneOldEpochData(
|
|
116811
|
+
() => pruneOldEpochData(join94(dataDir, "loro"), logAdapter)
|
|
116648
116812
|
);
|
|
116649
|
-
const storage = new FileStorageAdapter(
|
|
116813
|
+
const storage = new FileStorageAdapter(join94(dataDir, "loro"));
|
|
116650
116814
|
const personalWebrtcAdapter = new WebRtcDataChannelAdapter();
|
|
116651
116815
|
const peerRoleRegistry = createPeerRoleRegistry();
|
|
116652
116816
|
const presencePoolRef = { pool: {} };
|
|
@@ -116754,14 +116918,14 @@ async function runServeBody(options, captureRefs) {
|
|
|
116754
116918
|
current: []
|
|
116755
116919
|
};
|
|
116756
116920
|
const terminalPtys = /* @__PURE__ */ new Map();
|
|
116757
|
-
const terminalLogsDir =
|
|
116921
|
+
const terminalLogsDir = join94(shipyardHome, "data", "terminals");
|
|
116758
116922
|
await mkdir48(terminalLogsDir, { recursive: true, mode: 448 });
|
|
116759
116923
|
const publishedArtifactStore = createPublishedArtifactStore({
|
|
116760
|
-
rootDir:
|
|
116924
|
+
rootDir: join94(dataDir, "published"),
|
|
116761
116925
|
log: logAdapter
|
|
116762
116926
|
});
|
|
116763
116927
|
const previewStateStore = createPreviewStateStore({
|
|
116764
|
-
rootDir:
|
|
116928
|
+
rootDir: join94(dataDir, "preview-state"),
|
|
116765
116929
|
logger: log
|
|
116766
116930
|
});
|
|
116767
116931
|
let codexSkillsApplyScopedPatchRef = null;
|
|
@@ -116845,7 +117009,7 @@ async function runServeBody(options, captureRefs) {
|
|
|
116845
117009
|
daemon.healthMetrics.start();
|
|
116846
117010
|
publishedArtifactStore.setSendControlMessage((msg) => daemon.taskManager.broadcastControl(msg));
|
|
116847
117011
|
previewStateStore.setSendControlMessage((msg) => daemon.taskManager.broadcastControl(msg));
|
|
116848
|
-
const pluginsDir =
|
|
117012
|
+
const pluginsDir = join94(shipyardHome, "plugins");
|
|
116849
117013
|
await mkdir48(pluginsDir, { recursive: true });
|
|
116850
117014
|
let loadedPlugins = [];
|
|
116851
117015
|
const loadedPluginsRef = {
|
|
@@ -117410,4 +117574,4 @@ export {
|
|
|
117410
117574
|
decideWorkspaceScope,
|
|
117411
117575
|
serve
|
|
117412
117576
|
};
|
|
117413
|
-
//# sourceMappingURL=serve-
|
|
117577
|
+
//# sourceMappingURL=serve-JEU6SMZX.js.map
|