@schoolai/shipyard 3.22.0 → 3.23.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.
Files changed (58) hide show
  1. package/dist/{auth-SRHTZ2JL.js → auth-OHZTVIQU.js} +3 -3
  2. package/dist/capability-detector-worker.js +8 -8
  3. package/dist/{chunk-TFWDJCUJ.js → chunk-2UE3TNY7.js} +2 -2
  4. package/dist/{chunk-WFBU4LXL.js → chunk-2YH743ND.js} +2 -2
  5. package/dist/{chunk-XEBCOG2U.js → chunk-7E6VXTEO.js} +4 -4
  6. package/dist/{chunk-MRD6526D.js → chunk-CA5PKTNJ.js} +2 -2
  7. package/dist/{chunk-JGFN3QI6.js → chunk-CGNWVGXL.js} +4 -4
  8. package/dist/{chunk-ABFHBWBF.js → chunk-HQTCVJRK.js} +2 -2
  9. package/dist/{chunk-TSJOSKN3.js → chunk-JD4WV327.js} +2 -2
  10. package/dist/{chunk-DE3IJ4E4.js → chunk-K7EXPNAD.js} +6 -6
  11. package/dist/{chunk-WPH74RMT.js → chunk-LRBG3X5U.js} +3 -3
  12. package/dist/{chunk-VOC55DTY.js → chunk-OCYT65KO.js} +7 -7
  13. package/dist/{chunk-6RJG24XI.js → chunk-ROEOOZOW.js} +2 -2
  14. package/dist/{chunk-UTL5PF43.js → chunk-SXXAWBW7.js} +5 -3
  15. package/dist/{chunk-UTL5PF43.js.map → chunk-SXXAWBW7.js.map} +1 -1
  16. package/dist/{chunk-TUQTEWK3.js → chunk-VSRWL5SP.js} +2 -2
  17. package/dist/{chunk-WCWHY4C3.js → chunk-W3EMVBWP.js} +4 -4
  18. package/dist/{chunk-VPJRM77V.js → chunk-Y4RRW6MA.js} +4 -4
  19. package/dist/cursor-runner.js +3 -3
  20. package/dist/electron-utility.js +6 -6
  21. package/dist/{git-repo-3OG3TPCC.js → git-repo-IVN2RQNY.js} +4 -4
  22. package/dist/index.js +10 -10
  23. package/dist/{logger-R3DVMU7P.js → logger-I6HU4VSX.js} +3 -3
  24. package/dist/{login-TKO7FQXH.js → login-WL5WEEGJ.js} +6 -6
  25. package/dist/{logout-23UJSTCS.js → logout-EZQ4UBLH.js} +5 -5
  26. package/dist/{mcp-servers-2QITAK3X.js → mcp-servers-52C67MDD.js} +4 -4
  27. package/dist/{plan-backfill-D6FJZ65E.js → plan-backfill-EF6KR6BE.js} +4 -4
  28. package/dist/{roi-E27VSQ7N.js → roi-GUUSTWXN.js} +3 -3
  29. package/dist/{serve-5D77VQ6J.js → serve-J3MG3WHK.js} +147 -56
  30. package/dist/{serve-5D77VQ6J.js.map → serve-J3MG3WHK.js.map} +1 -1
  31. package/dist/{skills-N4FXCXYQ.js → skills-XBREPCFU.js} +2 -2
  32. package/dist/{start-VQSOEMXG.js → start-TCI35UML.js} +11 -11
  33. package/dist/start-TCI35UML.js.map +1 -0
  34. package/package.json +1 -1
  35. package/dist/start-VQSOEMXG.js.map +0 -1
  36. /package/dist/{auth-SRHTZ2JL.js.map → auth-OHZTVIQU.js.map} +0 -0
  37. /package/dist/{chunk-TFWDJCUJ.js.map → chunk-2UE3TNY7.js.map} +0 -0
  38. /package/dist/{chunk-WFBU4LXL.js.map → chunk-2YH743ND.js.map} +0 -0
  39. /package/dist/{chunk-XEBCOG2U.js.map → chunk-7E6VXTEO.js.map} +0 -0
  40. /package/dist/{chunk-MRD6526D.js.map → chunk-CA5PKTNJ.js.map} +0 -0
  41. /package/dist/{chunk-JGFN3QI6.js.map → chunk-CGNWVGXL.js.map} +0 -0
  42. /package/dist/{chunk-ABFHBWBF.js.map → chunk-HQTCVJRK.js.map} +0 -0
  43. /package/dist/{chunk-TSJOSKN3.js.map → chunk-JD4WV327.js.map} +0 -0
  44. /package/dist/{chunk-DE3IJ4E4.js.map → chunk-K7EXPNAD.js.map} +0 -0
  45. /package/dist/{chunk-WPH74RMT.js.map → chunk-LRBG3X5U.js.map} +0 -0
  46. /package/dist/{chunk-VOC55DTY.js.map → chunk-OCYT65KO.js.map} +0 -0
  47. /package/dist/{chunk-6RJG24XI.js.map → chunk-ROEOOZOW.js.map} +0 -0
  48. /package/dist/{chunk-TUQTEWK3.js.map → chunk-VSRWL5SP.js.map} +0 -0
  49. /package/dist/{chunk-WCWHY4C3.js.map → chunk-W3EMVBWP.js.map} +0 -0
  50. /package/dist/{chunk-VPJRM77V.js.map → chunk-Y4RRW6MA.js.map} +0 -0
  51. /package/dist/{git-repo-3OG3TPCC.js.map → git-repo-IVN2RQNY.js.map} +0 -0
  52. /package/dist/{logger-R3DVMU7P.js.map → logger-I6HU4VSX.js.map} +0 -0
  53. /package/dist/{login-TKO7FQXH.js.map → login-WL5WEEGJ.js.map} +0 -0
  54. /package/dist/{logout-23UJSTCS.js.map → logout-EZQ4UBLH.js.map} +0 -0
  55. /package/dist/{mcp-servers-2QITAK3X.js.map → mcp-servers-52C67MDD.js.map} +0 -0
  56. /package/dist/{plan-backfill-D6FJZ65E.js.map → plan-backfill-EF6KR6BE.js.map} +0 -0
  57. /package/dist/{roi-E27VSQ7N.js.map → roi-GUUSTWXN.js.map} +0 -0
  58. /package/dist/{skills-N4FXCXYQ.js.map → skills-XBREPCFU.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  enableNativeCrashReports
4
- } from "./chunk-TSJOSKN3.js";
4
+ } from "./chunk-JD4WV327.js";
5
5
  import {
6
6
  installWasmPanicBuffer
7
7
  } from "./chunk-5OTUGRW3.js";
8
8
  import "./chunk-UNGAIUEX.js";
9
9
  import {
10
10
  logger
11
- } from "./chunk-MRD6526D.js";
11
+ } from "./chunk-CA5PKTNJ.js";
12
12
  import {
13
13
  validateEnv
14
- } from "./chunk-UTL5PF43.js";
14
+ } from "./chunk-SXXAWBW7.js";
15
15
  import "./chunk-JCEWPG3R.js";
16
16
  import "./chunk-2H7UOFLK.js";
17
17
 
@@ -106,7 +106,7 @@ function parseCliArgs() {
106
106
  }
107
107
  async function loadAuthFromConfig(env) {
108
108
  if (env.SHIPYARD_USER_TOKEN) return;
109
- const { loadAuthToken } = await import("./auth-SRHTZ2JL.js");
109
+ const { loadAuthToken } = await import("./auth-OHZTVIQU.js");
110
110
  const auth = await loadAuthToken();
111
111
  if (auth.status === "ok") {
112
112
  env.SHIPYARD_USER_TOKEN = auth.token;
@@ -126,28 +126,28 @@ async function loadAuthFromConfig(env) {
126
126
  async function handleSubcommand() {
127
127
  const subcommand = process.argv[2];
128
128
  if (subcommand === "login") {
129
- const { loginCommand } = await import("./login-TKO7FQXH.js");
129
+ const { loginCommand } = await import("./login-WL5WEEGJ.js");
130
130
  const hasCheck = process.argv.includes("--check");
131
131
  await loginCommand({ check: hasCheck });
132
132
  return true;
133
133
  }
134
134
  if (subcommand === "logout") {
135
- const { logoutCommand } = await import("./logout-23UJSTCS.js");
135
+ const { logoutCommand } = await import("./logout-EZQ4UBLH.js");
136
136
  await logoutCommand();
137
137
  return true;
138
138
  }
139
139
  if (subcommand === "start") {
140
- const { startCommand } = await import("./start-VQSOEMXG.js");
140
+ const { startCommand } = await import("./start-TCI35UML.js");
141
141
  await startCommand();
142
142
  return true;
143
143
  }
144
144
  if (subcommand === "roi") {
145
- const { roiCommand } = await import("./roi-E27VSQ7N.js");
145
+ const { roiCommand } = await import("./roi-GUUSTWXN.js");
146
146
  await roiCommand();
147
147
  return true;
148
148
  }
149
149
  if (subcommand === "plan-backfill") {
150
- const { planBackfillCommand } = await import("./plan-backfill-D6FJZ65E.js");
150
+ const { planBackfillCommand } = await import("./plan-backfill-EF6KR6BE.js");
151
151
  await planBackfillCommand();
152
152
  return true;
153
153
  }
@@ -159,7 +159,7 @@ async function main() {
159
159
  const args = parseCliArgs();
160
160
  if (args.serve) {
161
161
  await loadAuthFromConfig(env);
162
- const { serve } = await import("./serve-5D77VQ6J.js");
162
+ const { serve } = await import("./serve-J3MG3WHK.js");
163
163
  return serve({ isDev: env.SHIPYARD_DEV });
164
164
  }
165
165
  logger.error("Use `shipyard start` to run the daemon. Use --help for usage.");
@@ -8,8 +8,8 @@ import {
8
8
  resolveLoggerLevels,
9
9
  shouldAttachFileTransport,
10
10
  shouldDeleteLogFile
11
- } from "./chunk-MRD6526D.js";
12
- import "./chunk-UTL5PF43.js";
11
+ } from "./chunk-CA5PKTNJ.js";
12
+ import "./chunk-SXXAWBW7.js";
13
13
  import "./chunk-JCEWPG3R.js";
14
14
  import "./chunk-2H7UOFLK.js";
15
15
  export {
@@ -22,4 +22,4 @@ export {
22
22
  shouldAttachFileTransport,
23
23
  shouldDeleteLogFile
24
24
  };
25
- //# sourceMappingURL=logger-R3DVMU7P.js.map
25
+ //# sourceMappingURL=logger-I6HU4VSX.js.map
@@ -3,13 +3,13 @@ import {
3
3
  ensureAuthenticated,
4
4
  getSignalingUrl,
5
5
  loginCommand
6
- } from "./chunk-VPJRM77V.js";
7
- import "./chunk-WFBU4LXL.js";
8
- import "./chunk-TFWDJCUJ.js";
6
+ } from "./chunk-Y4RRW6MA.js";
7
+ import "./chunk-2YH743ND.js";
8
+ import "./chunk-2UE3TNY7.js";
9
9
  import "./chunk-UESTOND6.js";
10
10
  import "./chunk-EHQITHQX.js";
11
- import "./chunk-MRD6526D.js";
12
- import "./chunk-UTL5PF43.js";
11
+ import "./chunk-CA5PKTNJ.js";
12
+ import "./chunk-SXXAWBW7.js";
13
13
  import "./chunk-JCEWPG3R.js";
14
14
  import "./chunk-2H7UOFLK.js";
15
15
  export {
@@ -17,4 +17,4 @@ export {
17
17
  getSignalingUrl,
18
18
  loginCommand
19
19
  };
20
- //# sourceMappingURL=login-TKO7FQXH.js.map
20
+ //# sourceMappingURL=login-WL5WEEGJ.js.map
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  print
4
- } from "./chunk-WFBU4LXL.js";
4
+ } from "./chunk-2YH743ND.js";
5
5
  import {
6
6
  deleteConfig,
7
7
  getConfigPath
8
- } from "./chunk-TFWDJCUJ.js";
9
- import "./chunk-MRD6526D.js";
10
- import "./chunk-UTL5PF43.js";
8
+ } from "./chunk-2UE3TNY7.js";
9
+ import "./chunk-CA5PKTNJ.js";
10
+ import "./chunk-SXXAWBW7.js";
11
11
  import "./chunk-JCEWPG3R.js";
12
12
  import "./chunk-2H7UOFLK.js";
13
13
 
@@ -23,4 +23,4 @@ async function logoutCommand() {
23
23
  export {
24
24
  logoutCommand
25
25
  };
26
- //# sourceMappingURL=logout-23UJSTCS.js.map
26
+ //# sourceMappingURL=logout-EZQ4UBLH.js.map
@@ -15,10 +15,10 @@ import {
15
15
  resolveAuthStatuses,
16
16
  resolveClaudeCodeAuthStatuses,
17
17
  shouldFetchClaudeAiIntegrations
18
- } from "./chunk-JGFN3QI6.js";
18
+ } from "./chunk-CGNWVGXL.js";
19
19
  import "./chunk-RR6V6SNM.js";
20
- import "./chunk-MRD6526D.js";
21
- import "./chunk-UTL5PF43.js";
20
+ import "./chunk-CA5PKTNJ.js";
21
+ import "./chunk-SXXAWBW7.js";
22
22
  import "./chunk-JCEWPG3R.js";
23
23
  import "./chunk-2H7UOFLK.js";
24
24
  export {
@@ -38,4 +38,4 @@ export {
38
38
  resolveClaudeCodeAuthStatuses,
39
39
  shouldFetchClaudeAiIntegrations
40
40
  };
41
- //# sourceMappingURL=mcp-servers-2QITAK3X.js.map
41
+ //# sourceMappingURL=mcp-servers-52C67MDD.js.map
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  buildTaskStateStore,
4
4
  runPlanBackfill
5
- } from "./chunk-WPH74RMT.js";
5
+ } from "./chunk-LRBG3X5U.js";
6
6
  import "./chunk-RR6V6SNM.js";
7
7
  import "./chunk-QI5ERXFK.js";
8
8
  import "./chunk-UESTOND6.js";
@@ -10,11 +10,11 @@ import "./chunk-EHQITHQX.js";
10
10
  import "./chunk-X3MULCV5.js";
11
11
  import {
12
12
  logger
13
- } from "./chunk-MRD6526D.js";
13
+ } from "./chunk-CA5PKTNJ.js";
14
14
  import {
15
15
  getShipyardHome,
16
16
  validateEnv
17
- } from "./chunk-UTL5PF43.js";
17
+ } from "./chunk-SXXAWBW7.js";
18
18
  import "./chunk-JCEWPG3R.js";
19
19
  import "./chunk-2H7UOFLK.js";
20
20
 
@@ -65,4 +65,4 @@ async function planBackfillCommand(argv = process.argv.slice(3)) {
65
65
  export {
66
66
  planBackfillCommand
67
67
  };
68
- //# sourceMappingURL=plan-backfill-D6FJZ65E.js.map
68
+ //# sourceMappingURL=plan-backfill-EF6KR6BE.js.map
@@ -8,10 +8,10 @@ import {
8
8
  import "./chunk-EHQITHQX.js";
9
9
  import {
10
10
  logger
11
- } from "./chunk-MRD6526D.js";
11
+ } from "./chunk-CA5PKTNJ.js";
12
12
  import {
13
13
  validateEnv
14
- } from "./chunk-UTL5PF43.js";
14
+ } from "./chunk-SXXAWBW7.js";
15
15
  import "./chunk-JCEWPG3R.js";
16
16
  import "./chunk-2H7UOFLK.js";
17
17
 
@@ -702,4 +702,4 @@ function renderReport(report, format) {
702
702
  export {
703
703
  roiCommand
704
704
  };
705
- //# sourceMappingURL=roi-E27VSQ7N.js.map
705
+ //# sourceMappingURL=roi-GUUSTWXN.js.map
@@ -12,7 +12,7 @@ import {
12
12
  guardedSubscribe,
13
13
  makeInitialAttemptState,
14
14
  shutdownFileWatcherGuard
15
- } from "./chunk-XEBCOG2U.js";
15
+ } from "./chunk-7E6VXTEO.js";
16
16
  import {
17
17
  TRAILER_SCHEMA_VERSION,
18
18
  appendTrailerToMessage,
@@ -39,13 +39,13 @@ import {
39
39
  startPlanBackfillForDaemon,
40
40
  sync,
41
41
  validatePeerId
42
- } from "./chunk-WPH74RMT.js";
42
+ } from "./chunk-LRBG3X5U.js";
43
43
  import {
44
44
  loadAuthToken
45
- } from "./chunk-TFWDJCUJ.js";
45
+ } from "./chunk-2UE3TNY7.js";
46
46
  import {
47
47
  getDaemonVersion
48
- } from "./chunk-WCWHY4C3.js";
48
+ } from "./chunk-W3EMVBWP.js";
49
49
  import {
50
50
  collectPriorCrashDetail,
51
51
  getRecentWasmPanicMessages
@@ -174,12 +174,12 @@ import {
174
174
  unresolveReviewThread,
175
175
  withLabelAsync,
176
176
  writeCursorApiKeyToVault
177
- } from "./chunk-VOC55DTY.js";
177
+ } from "./chunk-OCYT65KO.js";
178
178
  import {
179
179
  buildNodeSpawnEnv,
180
180
  nodeSpawnEnvOverlay,
181
181
  rewriteElectronNodeScriptSpawn
182
- } from "./chunk-TUQTEWK3.js";
182
+ } from "./chunk-VSRWL5SP.js";
183
183
  import {
184
184
  TIMEOUT_MS,
185
185
  addWorktreeToCache,
@@ -192,7 +192,7 @@ import {
192
192
  removeWorktreeFromCache,
193
193
  run,
194
194
  runWithTimeout
195
- } from "./chunk-DE3IJ4E4.js";
195
+ } from "./chunk-K7EXPNAD.js";
196
196
  import {
197
197
  gitExecSafe
198
198
  } from "./chunk-4T2OQAVL.js";
@@ -213,7 +213,7 @@ import {
213
213
  resolveStdioEnv,
214
214
  setTelemetrySink,
215
215
  telemeter
216
- } from "./chunk-JGFN3QI6.js";
216
+ } from "./chunk-CGNWVGXL.js";
217
217
  import {
218
218
  atomicWriteFile,
219
219
  findProjectRoot,
@@ -224,7 +224,7 @@ import {
224
224
  } from "./chunk-RR6V6SNM.js";
225
225
  import {
226
226
  classifySkill
227
- } from "./chunk-6RJG24XI.js";
227
+ } from "./chunk-ROEOOZOW.js";
228
228
  import {
229
229
  createOneShotPool
230
230
  } from "./chunk-ZFKJAYAN.js";
@@ -236,7 +236,7 @@ import {
236
236
  createAssetResolver,
237
237
  toSdkContent,
238
238
  toSdkPermissionMode
239
- } from "./chunk-ABFHBWBF.js";
239
+ } from "./chunk-HQTCVJRK.js";
240
240
  import {
241
241
  AGENT_IDS,
242
242
  AGENT_SYSTEM_CLAUDE_CODE,
@@ -500,7 +500,7 @@ import {
500
500
  createChildLogger,
501
501
  flushLogger,
502
502
  logger
503
- } from "./chunk-MRD6526D.js";
503
+ } from "./chunk-CA5PKTNJ.js";
504
504
  import {
505
505
  getShipyardHome,
506
506
  getStallProfilerConfig,
@@ -509,7 +509,7 @@ import {
509
509
  isVanillaAgentMode,
510
510
  resolveNodeExecPath,
511
511
  validateEnv
512
- } from "./chunk-UTL5PF43.js";
512
+ } from "./chunk-SXXAWBW7.js";
513
513
  import {
514
514
  external_exports
515
515
  } from "./chunk-JCEWPG3R.js";
@@ -6016,7 +6016,7 @@ function nanoid(size = 21) {
6016
6016
  }
6017
6017
 
6018
6018
  // src/services/bootstrap/signaling.ts
6019
- var DAEMON_NPM_VERSION = true ? "3.22.0" : "unknown";
6019
+ var DAEMON_NPM_VERSION = true ? "3.23.0" : "unknown";
6020
6020
  function createDaemonSignaling(config) {
6021
6021
  const agentId = config.agentId ?? nanoid();
6022
6022
  function send(msg) {
@@ -17228,7 +17228,7 @@ async function refreshPluginCapabilities(daemon, tokenStore) {
17228
17228
  const userSettings = await daemon.userSettingsStore.getSettings();
17229
17229
  const [updatedMarketplace, updatedMcp, updatedSkills] = await Promise.all([
17230
17230
  detectMarketplacePlugins(daemon.capabilities.marketplacePlugins),
17231
- import("./mcp-servers-2QITAK3X.js").then(
17231
+ import("./mcp-servers-52C67MDD.js").then(
17232
17232
  (m2) => m2.detectMCPServers(
17233
17233
  daemon.capabilities.environments,
17234
17234
  tokenStore,
@@ -17237,7 +17237,7 @@ async function refreshPluginCapabilities(daemon, tokenStore) {
17237
17237
  readPreferredClaudeAuthMethod(userSettings)
17238
17238
  )
17239
17239
  ),
17240
- import("./skills-N4FXCXYQ.js").then(
17240
+ import("./skills-XBREPCFU.js").then(
17241
17241
  (m2) => m2.detectSkills(daemon.capabilities.environments)
17242
17242
  )
17243
17243
  ]);
@@ -74322,8 +74322,10 @@ function buildDeliverableStore(dataDir) {
74322
74322
  }
74323
74323
 
74324
74324
  // src/services/storage/jsonl-conversation-store.ts
74325
+ import { createReadStream as createReadStream5 } from "fs";
74325
74326
  import { appendFile as appendFile3, mkdir as mkdir28, open, readFile as readFile39, stat as stat17 } from "fs/promises";
74326
74327
  import { join as join67 } from "path";
74328
+ import { createInterface as createInterface5 } from "readline";
74327
74329
  var StoredMessageSchema = MessageSchema.omit({ seqNo: true, channelId: true });
74328
74330
  function logPerf(entry) {
74329
74331
  try {
@@ -74332,14 +74334,93 @@ function logPerf(entry) {
74332
74334
  } catch {
74333
74335
  }
74334
74336
  }
74337
+ var DEFAULT_READ_CACHE_BUDGET_BYTES = 384 * 1024 * 1024;
74335
74338
  function buildJsonlConversationStore(dataDir, opts = {}) {
74336
74339
  const channelsDir = join67(dataDir, "channels");
74337
74340
  const seqCounters = /* @__PURE__ */ new Map();
74338
74341
  const channelQueues = /* @__PURE__ */ new Map();
74339
74342
  const readCache = /* @__PURE__ */ new Map();
74343
+ let readCacheBytes = 0;
74344
+ const READ_CACHE_BUDGET_BYTES = opts.readCacheBudgetBytes ?? DEFAULT_READ_CACHE_BUDGET_BYTES;
74345
+ function touchCacheEntry(channelId, entry) {
74346
+ readCache.delete(channelId);
74347
+ readCache.set(channelId, entry);
74348
+ }
74349
+ function dropCacheEntry(channelId) {
74350
+ const prev = readCache.get(channelId);
74351
+ if (prev === void 0) return;
74352
+ readCacheBytes -= prev.size;
74353
+ readCache.delete(channelId);
74354
+ }
74355
+ function evictUntilWithinBudget(keepChannelId) {
74356
+ if (readCacheBytes <= READ_CACHE_BUDGET_BYTES) return;
74357
+ let evicted = 0;
74358
+ const freedFrom = readCacheBytes;
74359
+ for (const [id, entry] of readCache) {
74360
+ if (readCacheBytes <= READ_CACHE_BUDGET_BYTES) break;
74361
+ if (id === keepChannelId) continue;
74362
+ readCacheBytes -= entry.size;
74363
+ readCache.delete(id);
74364
+ evicted++;
74365
+ }
74366
+ if (evicted > 0) {
74367
+ logPerf({
74368
+ event: "perf_jsonl_cache_evicted",
74369
+ evicted,
74370
+ freedBytes: freedFrom - readCacheBytes,
74371
+ retainedBytes: readCacheBytes,
74372
+ entries: readCache.size
74373
+ });
74374
+ }
74375
+ }
74376
+ function setCacheEntry(channelId, entry) {
74377
+ dropCacheEntry(channelId);
74378
+ readCache.set(channelId, entry);
74379
+ readCacheBytes += entry.size;
74380
+ evictUntilWithinBudget(channelId);
74381
+ }
74382
+ const turnCountCache = /* @__PURE__ */ new Map();
74340
74383
  function channelPath(channelId) {
74341
74384
  return join67(channelsDir, `${channelId}.jsonl`);
74342
74385
  }
74386
+ function countRuns(messages) {
74387
+ let turns = 0;
74388
+ let prev = null;
74389
+ for (const m2 of messages) {
74390
+ if (m2.senderKind !== prev) {
74391
+ turns++;
74392
+ prev = m2.senderKind;
74393
+ }
74394
+ }
74395
+ return turns;
74396
+ }
74397
+ async function streamCountSenderTurns(channelId) {
74398
+ const stream = createReadStream5(channelPath(channelId), { encoding: "utf-8" });
74399
+ const lines = createInterface5({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
74400
+ let turns = 0;
74401
+ let prev = null;
74402
+ try {
74403
+ for await (const line of lines) {
74404
+ if (!line) continue;
74405
+ let raw;
74406
+ try {
74407
+ raw = JSON.parse(line);
74408
+ } catch {
74409
+ continue;
74410
+ }
74411
+ const parsed = StoredMessageSchema.safeParse(raw);
74412
+ if (!parsed.success) continue;
74413
+ if (parsed.data.senderKind !== prev) {
74414
+ turns++;
74415
+ prev = parsed.data.senderKind;
74416
+ }
74417
+ }
74418
+ } finally {
74419
+ lines.close();
74420
+ stream.destroy();
74421
+ }
74422
+ return turns;
74423
+ }
74343
74424
  async function ensureDir() {
74344
74425
  await mkdir28(channelsDir, { recursive: true });
74345
74426
  }
@@ -74489,6 +74570,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
74489
74570
  function readTailFromCache(channelId, limit, fileStat) {
74490
74571
  const hit = readCache.get(channelId);
74491
74572
  if (!hit || hit.size !== fileStat.size || hit.mtimeMs !== fileStat.mtimeMs) return null;
74573
+ touchCacheEntry(channelId, hit);
74492
74574
  const tail = hit.messages.length <= limit ? [...hit.messages] : hit.messages.slice(-limit);
74493
74575
  return { messages: tail, totalLines: hit.messages.length };
74494
74576
  }
@@ -74517,10 +74599,11 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
74517
74599
  }
74518
74600
  const hit = readCache.get(channelId);
74519
74601
  if (hit && hit.size === fileStat.size && hit.mtimeMs === fileStat.mtimeMs) {
74602
+ touchCacheEntry(channelId, hit);
74520
74603
  return [...hit.messages];
74521
74604
  }
74522
74605
  const fresh = await readLines(channelId);
74523
- readCache.set(channelId, {
74606
+ setCacheEntry(channelId, {
74524
74607
  messages: fresh,
74525
74608
  size: fileStat.size,
74526
74609
  mtimeMs: fileStat.mtimeMs
@@ -74535,8 +74618,11 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
74535
74618
  for (const m2 of incoming) {
74536
74619
  if (m2.seqNo > lastSeqNo) liveHit.messages.push(m2);
74537
74620
  }
74621
+ readCacheBytes += fileStat.size - liveHit.size;
74538
74622
  liveHit.size = fileStat.size;
74539
74623
  liveHit.mtimeMs = fileStat.mtimeMs;
74624
+ touchCacheEntry(channelId, liveHit);
74625
+ evictUntilWithinBudget(channelId);
74540
74626
  }
74541
74627
  async function refreshCacheAfterAppend(channelId, appended) {
74542
74628
  if (!readCache.get(channelId)) return;
@@ -74546,7 +74632,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
74546
74632
  pushIntoLiveCache(channelId, appended, { size: s2.size, mtimeMs: s2.mtimeMs });
74547
74633
  } catch (err3) {
74548
74634
  if (isEnoent(err3)) {
74549
- readCache.delete(channelId);
74635
+ dropCacheEntry(channelId);
74550
74636
  return;
74551
74637
  }
74552
74638
  logPerf({
@@ -74629,7 +74715,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
74629
74715
  });
74630
74716
  resolveSeqNo(seqNo);
74631
74717
  }).catch((err3) => {
74632
- readCache.delete(message.channelId);
74718
+ dropCacheEntry(message.channelId);
74633
74719
  rejectSeqNo(err3);
74634
74720
  });
74635
74721
  channelQueues.set(message.channelId, next);
@@ -74680,7 +74766,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
74680
74766
  await refreshCacheAfterAppend(channelId, cacheUpdates);
74681
74767
  resolveSeqNos(seqNos);
74682
74768
  }).catch((err3) => {
74683
- readCache.delete(channelId);
74769
+ dropCacheEntry(channelId);
74684
74770
  rejectSeqNos(err3);
74685
74771
  });
74686
74772
  channelQueues.set(channelId, next);
@@ -74727,7 +74813,7 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
74727
74813
  });
74728
74814
  resolveResult({ seqNo: decision.seqNo, isDuplicate: false, dedupKey: null });
74729
74815
  }).catch((err3) => {
74730
- readCache.delete(message.channelId);
74816
+ dropCacheEntry(message.channelId);
74731
74817
  rejectResult(err3);
74732
74818
  });
74733
74819
  channelQueues.set(message.channelId, next);
@@ -74766,10 +74852,10 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
74766
74852
  ` : "";
74767
74853
  const filePath = channelPath(channelId);
74768
74854
  await atomicWriteFile(filePath, content);
74769
- readCache.delete(channelId);
74855
+ dropCacheEntry(channelId);
74770
74856
  resolveVoid();
74771
74857
  }).catch((err3) => {
74772
- readCache.delete(channelId);
74858
+ dropCacheEntry(channelId);
74773
74859
  rejectVoid(err3);
74774
74860
  });
74775
74861
  channelQueues.set(channelId, next);
@@ -74850,14 +74936,28 @@ function buildJsonlConversationStore(dataDir, opts = {}) {
74850
74936
  const filePath = channelPath(channelId);
74851
74937
  await atomicWriteFile(filePath, content);
74852
74938
  seqCounters.set(channelId, kept.length > 0 ? kept.length - 1 : -1);
74853
- readCache.delete(channelId);
74939
+ dropCacheEntry(channelId);
74854
74940
  resolveCount(removed);
74855
74941
  }).catch((err3) => {
74856
- readCache.delete(channelId);
74942
+ dropCacheEntry(channelId);
74857
74943
  rejectCount(err3);
74858
74944
  });
74859
74945
  channelQueues.set(channelId, next);
74860
74946
  return countPromise;
74947
+ },
74948
+ async countSenderTurns(channelId) {
74949
+ const fileStat = await statFreshness(channelPath(channelId));
74950
+ if (fileStat === null || fileStat.size === 0) return 0;
74951
+ const hit = turnCountCache.get(channelId);
74952
+ if (hit && hit.size === fileStat.size && hit.mtimeMs === fileStat.mtimeMs) return hit.turns;
74953
+ const cached = readCache.get(channelId);
74954
+ const turns = cached && cached.size === fileStat.size && cached.mtimeMs === fileStat.mtimeMs ? countRuns(cached.messages) : await streamCountSenderTurns(channelId);
74955
+ turnCountCache.set(channelId, {
74956
+ size: fileStat.size,
74957
+ mtimeMs: fileStat.mtimeMs,
74958
+ turns
74959
+ });
74960
+ return turns;
74861
74961
  }
74862
74962
  };
74863
74963
  }
@@ -74903,6 +75003,9 @@ function buildObservableConversationStore(inner) {
74903
75003
  stampSdkUuid(channelId, correlationId, sdkUuid, batchCorrelationIds) {
74904
75004
  return inner.stampSdkUuid(channelId, correlationId, sdkUuid, batchCorrelationIds);
74905
75005
  },
75006
+ countSenderTurns(channelId) {
75007
+ return inner.countSenderTurns(channelId);
75008
+ },
74906
75009
  getMessages(channelId) {
74907
75010
  return inner.getMessages(channelId);
74908
75011
  },
@@ -86187,13 +86290,13 @@ var SideThreadRegistry = class {
86187
86290
  });
86188
86291
  });
86189
86292
  if (status) {
86190
- this.#deps.store.getMessages(entry.metadata.channelId).then((messages) => {
86293
+ this.#deps.store.countSenderTurns(entry.metadata.channelId).then((replyCount) => {
86191
86294
  this.#deps.getSendControlMessage()?.({
86192
86295
  type: "thread_state_update",
86193
86296
  taskId: this.#deps.taskId,
86194
86297
  threadId,
86195
86298
  status,
86196
- replyCount: countTurns(messages)
86299
+ replyCount
86197
86300
  });
86198
86301
  }).catch(() => {
86199
86302
  this.#deps.getSendControlMessage()?.({
@@ -86282,13 +86385,13 @@ var SideThreadRegistry = class {
86282
86385
  });
86283
86386
  const threadStatus = mapSessionStatusToThreadStatus(status);
86284
86387
  if (threadStatus) {
86285
- this.#deps.store.getMessages(params.channelId).then((messages) => {
86388
+ this.#deps.store.countSenderTurns(params.channelId).then((replyCount) => {
86286
86389
  this.#deps.getSendControlMessage()?.({
86287
86390
  type: "thread_state_update",
86288
86391
  taskId: this.#deps.taskId,
86289
86392
  threadId: params.threadId,
86290
86393
  status: threadStatus,
86291
- replyCount: countTurns(messages)
86394
+ replyCount
86292
86395
  });
86293
86396
  }).catch(() => {
86294
86397
  this.#deps.getSendControlMessage()?.({
@@ -86387,8 +86490,7 @@ var SideThreadRegistry = class {
86387
86490
  await this.#ensureLoaded();
86388
86491
  const result = [];
86389
86492
  for (const { metadata } of this.#threads.values()) {
86390
- const messages = await this.#deps.store.getMessages(metadata.channelId);
86391
- const replyCount = countTurns(messages);
86493
+ const replyCount = await this.#deps.store.countSenderTurns(metadata.channelId);
86392
86494
  result.push({ ...metadata, replyCount });
86393
86495
  }
86394
86496
  return result;
@@ -86566,17 +86668,6 @@ var SideThreadRegistry = class {
86566
86668
  await rename19(tmpPath, filePath);
86567
86669
  }
86568
86670
  };
86569
- function countTurns(messages) {
86570
- let turns = 0;
86571
- let prev = null;
86572
- for (const m2 of messages) {
86573
- if (m2.senderKind !== prev) {
86574
- turns++;
86575
- prev = m2.senderKind;
86576
- }
86577
- }
86578
- return turns;
86579
- }
86580
86671
  function mapSessionStatusToThreadStatus(status) {
86581
86672
  switch (status) {
86582
86673
  case "in_progress":
@@ -89340,18 +89431,13 @@ async function handleBeforeFlush(ctx, messages) {
89340
89431
  }
89341
89432
  return result;
89342
89433
  }
89343
- async function elapsedSinceLastUserMessage(ctx) {
89344
- try {
89345
- const messages = await ctx.store.getMessages(ctx.channelId);
89346
- let latest = 0;
89347
- for (const m2 of messages) {
89348
- if (m2.senderKind === "human" && m2.timestamp > latest) latest = m2.timestamp;
89349
- }
89350
- if (latest === 0) return Number.POSITIVE_INFINITY;
89351
- return Date.now() - latest;
89352
- } catch {
89353
- return Number.POSITIVE_INFINITY;
89434
+ function elapsedSinceLastUserMessage(messages) {
89435
+ let latest = 0;
89436
+ for (const m2 of messages) {
89437
+ if (m2.senderKind === "human" && m2.timestamp > latest) latest = m2.timestamp;
89354
89438
  }
89439
+ if (latest === 0) return Number.POSITIVE_INFINITY;
89440
+ return Date.now() - latest;
89355
89441
  }
89356
89442
  async function resolveTaskListPrepend(ctx) {
89357
89443
  const registry = ctx.resourceRegistry;
@@ -93481,8 +93567,13 @@ var Task = class {
93481
93567
  #handleBeforeFlush(messages) {
93482
93568
  return handleBeforeFlush(this.#spawnPrepCtx(), messages);
93483
93569
  }
93484
- #elapsedSinceLastUserMessage() {
93485
- return elapsedSinceLastUserMessage(this.#spawnPrepCtx());
93570
+ async #elapsedSinceLastUserMessage() {
93571
+ try {
93572
+ const messages = await this.#deps.store.getMessages(this.#deps.channelId);
93573
+ return elapsedSinceLastUserMessage(messages);
93574
+ } catch {
93575
+ return Number.POSITIVE_INFINITY;
93576
+ }
93486
93577
  }
93487
93578
  /**
93488
93579
  * Evaluate `on-user-message` triggers for tracked resources. Currently the
@@ -98473,7 +98564,7 @@ async function createDaemon(deps) {
98473
98564
  if (!cwd) return null;
98474
98565
  try {
98475
98566
  const { gitExecSafe: gitExecSafe2 } = await import("./git-pool-V73Q53NX.js");
98476
- const { getRepoDefaultBranch: getRepoDefaultBranch2 } = await import("./git-repo-3OG3TPCC.js");
98567
+ const { getRepoDefaultBranch: getRepoDefaultBranch2 } = await import("./git-repo-IVN2RQNY.js");
98477
98568
  const branch = await gitExecSafe2(cwd, ["rev-parse", "--abbrev-ref", "HEAD"]) ?? "";
98478
98569
  if (!branch || branch === "HEAD") return null;
98479
98570
  const pr = branchPrStateCache.get(taskId)?.currentBranchPR;
@@ -102976,4 +103067,4 @@ export {
102976
103067
  decideWorkspaceScope,
102977
103068
  serve
102978
103069
  };
102979
- //# sourceMappingURL=serve-5D77VQ6J.js.map
103070
+ //# sourceMappingURL=serve-J3MG3WHK.js.map