@schoolai/shipyard 3.18.0 → 3.18.1-rc.20260629.1

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 (45) hide show
  1. package/dist/capability-detector-worker.js +6 -6
  2. package/dist/{chunk-CTCRVL3I.js → chunk-4AUX3FMD.js} +2 -2
  3. package/dist/chunk-4AUX3FMD.js.map +1 -0
  4. package/dist/{chunk-H2NFBWK7.js → chunk-5GY7WGIC.js} +6 -5
  5. package/dist/{chunk-H2NFBWK7.js.map → chunk-5GY7WGIC.js.map} +1 -1
  6. package/dist/{chunk-ETUNY4NF.js → chunk-BK24XTBR.js} +375 -4
  7. package/dist/chunk-BK24XTBR.js.map +1 -0
  8. package/dist/{chunk-D3JA5MXR.js → chunk-CKQL7TWQ.js} +4 -3
  9. package/dist/{chunk-D3JA5MXR.js.map → chunk-CKQL7TWQ.js.map} +1 -1
  10. package/dist/{chunk-LXIRZZFC.js → chunk-D6RYU2JU.js} +14 -5
  11. package/dist/{chunk-LXIRZZFC.js.map → chunk-D6RYU2JU.js.map} +1 -1
  12. package/dist/{chunk-72CO4KIJ.js → chunk-E74MXZWW.js} +2 -2
  13. package/dist/{chunk-RM4WIKPZ.js → chunk-K4HUYO2V.js} +3 -3
  14. package/dist/{chunk-NIVME6MT.js → chunk-LN2AW36U.js} +134 -53
  15. package/dist/chunk-LN2AW36U.js.map +1 -0
  16. package/dist/{chunk-UD4BVZOD.js → chunk-PXZCSRS5.js} +5 -5
  17. package/dist/chunk-PXZCSRS5.js.map +1 -0
  18. package/dist/{chunk-UTLVWPBT.js → chunk-VDK5N7EH.js} +38 -2
  19. package/dist/chunk-VDK5N7EH.js.map +1 -0
  20. package/dist/{chunk-DHYIAHZN.js → chunk-XXRTRTG4.js} +2 -2
  21. package/dist/cursor-runner.js +14 -7
  22. package/dist/cursor-runner.js.map +1 -1
  23. package/dist/electron-utility.js +2 -2
  24. package/dist/{git-repo-KK5ZNJUW.js → git-repo-6DHYJICW.js} +2 -2
  25. package/dist/index.js +4 -4
  26. package/dist/{login-53IPU5BJ.js → login-4AUKCCVX.js} +3 -3
  27. package/dist/{mcp-servers-WZF27B7W.js → mcp-servers-Z3LIT6CL.js} +2 -2
  28. package/dist/{plan-backfill-2AOFAPND.js → plan-backfill-X4FGEJ4G.js} +4 -4
  29. package/dist/{serve-NTV6KMY3.js → serve-IP4COF55.js} +12370 -11791
  30. package/dist/{serve-NTV6KMY3.js.map → serve-IP4COF55.js.map} +1 -1
  31. package/dist/{start-MW3BBTC3.js → start-P57AEVJI.js} +6 -6
  32. package/package.json +10 -10
  33. package/dist/chunk-CTCRVL3I.js.map +0 -1
  34. package/dist/chunk-ETUNY4NF.js.map +0 -1
  35. package/dist/chunk-NIVME6MT.js.map +0 -1
  36. package/dist/chunk-UD4BVZOD.js.map +0 -1
  37. package/dist/chunk-UTLVWPBT.js.map +0 -1
  38. /package/dist/{chunk-72CO4KIJ.js.map → chunk-E74MXZWW.js.map} +0 -0
  39. /package/dist/{chunk-RM4WIKPZ.js.map → chunk-K4HUYO2V.js.map} +0 -0
  40. /package/dist/{chunk-DHYIAHZN.js.map → chunk-XXRTRTG4.js.map} +0 -0
  41. /package/dist/{git-repo-KK5ZNJUW.js.map → git-repo-6DHYJICW.js.map} +0 -0
  42. /package/dist/{login-53IPU5BJ.js.map → login-4AUKCCVX.js.map} +0 -0
  43. /package/dist/{mcp-servers-WZF27B7W.js.map → mcp-servers-Z3LIT6CL.js.map} +0 -0
  44. /package/dist/{plan-backfill-2AOFAPND.js.map → plan-backfill-X4FGEJ4G.js.map} +0 -0
  45. /package/dist/{start-MW3BBTC3.js.map → start-P57AEVJI.js.map} +0 -0
@@ -10,7 +10,7 @@ import {
10
10
  run,
11
11
  runWithTimeout,
12
12
  truncateDiff
13
- } from "./chunk-LXIRZZFC.js";
13
+ } from "./chunk-D6RYU2JU.js";
14
14
  import {
15
15
  gitExecSafe
16
16
  } from "./chunk-4T2OQAVL.js";
@@ -19,7 +19,7 @@ import {
19
19
  CODEX_RUNTIME_ID,
20
20
  CURSOR_RUNTIME_ID,
21
21
  detectMCPServers
22
- } from "./chunk-UTLVWPBT.js";
22
+ } from "./chunk-VDK5N7EH.js";
23
23
  import {
24
24
  isEnoent
25
25
  } from "./chunk-RR6V6SNM.js";
@@ -38,7 +38,7 @@ import {
38
38
  formatTaskFeedback,
39
39
  toRecord,
40
40
  toSdkContent
41
- } from "./chunk-72CO4KIJ.js";
41
+ } from "./chunk-E74MXZWW.js";
42
42
  import {
43
43
  AGENT_IDS,
44
44
  AGENT_SYSTEM_CLAUDE_CODE,
@@ -50,14 +50,14 @@ import {
50
50
  REASONING_EFFORTS,
51
51
  inflateToolResultContent,
52
52
  isImageMimeType
53
- } from "./chunk-ETUNY4NF.js";
53
+ } from "./chunk-BK24XTBR.js";
54
54
  import {
55
55
  AnthropicAuthStatusSchema,
56
56
  CodexAuthStatusSchema,
57
57
  CursorAuthStatusSchema,
58
58
  PermissionModeSchema,
59
59
  TESTED_CODEX_VERSION
60
- } from "./chunk-UD4BVZOD.js";
60
+ } from "./chunk-PXZCSRS5.js";
61
61
  import {
62
62
  logger
63
63
  } from "./chunk-X53VIV2J.js";
@@ -650,6 +650,38 @@ async function readEffortArrayFromBinary(binaryPath) {
650
650
  }
651
651
  }
652
652
 
653
+ // src/shared/observability/watchdog-context.ts
654
+ var currentLabel = null;
655
+ var prevCompletedLabel = null;
656
+ var prevCompletedDurationMs = 0;
657
+ var prevCompletedAtMs = 0;
658
+ async function withLabelAsync(name, fn) {
659
+ const priorLabel = currentLabel;
660
+ const start = Date.now();
661
+ currentLabel = name;
662
+ try {
663
+ return await fn();
664
+ } finally {
665
+ const completedAt = Date.now();
666
+ prevCompletedLabel = name;
667
+ prevCompletedDurationMs = completedAt - start;
668
+ prevCompletedAtMs = completedAt;
669
+ currentLabel = priorLabel;
670
+ }
671
+ }
672
+ function getCurrentWatchdogLabel() {
673
+ return currentLabel;
674
+ }
675
+ function getPreviousWatchdogLabel() {
676
+ return prevCompletedLabel;
677
+ }
678
+ function getPreviousWatchdogDurationMs() {
679
+ return prevCompletedDurationMs;
680
+ }
681
+ function getPreviousWatchdogCompletedAtMs() {
682
+ return prevCompletedAtMs;
683
+ }
684
+
653
685
  // src/shared/capabilities/env-methods.ts
654
686
  function resolveEnvMethod(env) {
655
687
  if (env.CLAUDE_CODE_USE_BEDROCK) return { method: "bedrock", envVar: "CLAUDE_CODE_USE_BEDROCK" };
@@ -993,6 +1025,10 @@ function extractXmlTag(xml, tag) {
993
1025
  function isRecord(value) {
994
1026
  return typeof value === "object" && value !== null;
995
1027
  }
1028
+ function toRateLimitInfo(info) {
1029
+ const { rateLimitType, ...rest } = info;
1030
+ return rateLimitType === "seven_day_overage_included" ? rest : { ...rest, rateLimitType };
1031
+ }
996
1032
  function classifyMessage(message, log) {
997
1033
  switch (message.type) {
998
1034
  case "system":
@@ -1040,7 +1076,7 @@ function classifyMessage(message, log) {
1040
1076
  toolUseIds: message.preceding_tool_use_ids
1041
1077
  };
1042
1078
  case "rate_limit_event":
1043
- return { type: "rate_limit", info: message.rate_limit_info };
1079
+ return { type: "rate_limit", info: toRateLimitInfo(message.rate_limit_info) };
1044
1080
  case "prompt_suggestion":
1045
1081
  return null;
1046
1082
  default: {
@@ -5009,7 +5045,7 @@ var cursorProfile = {
5009
5045
  canInjectInputMidRun: false
5010
5046
  },
5011
5047
  /**
5012
- * Rewind contract — `@cursor/sdk@1.0.13` has no live-rollback RPC, but the
5048
+ * Rewind contract — `@cursor/sdk@1.0.22` has no live-rollback RPC, but the
5013
5049
  * conversation lives in a git-shaped Merkle tree (per-agent `store.db`), so a
5014
5050
  * rewind is a lossless head re-point + ledger trim, done on disk while no SDK
5015
5051
  * process holds the store. We declare `dropLastTurns` (the divider lights up
@@ -5216,13 +5252,11 @@ var cursorProfile = {
5216
5252
  */
5217
5253
  authDetector: cursorAuthDetectorBinding,
5218
5254
  /**
5219
- * Cursor reports per-call cost via the SDK but the SDK surface in
5220
- * 1.0.13 does not expose a stable accessor for cost dollars at the
5221
- * frame level. Set `reported` per v2 plan §5.8; the daemon's billing
5222
- * pipeline reads cost off the runner's `run_complete` payload when
5223
- * present and treats absence as null (no synthetic estimate).
5255
+ * Cursor reports token usage via the SDK, but Shipyard applies local Cursor
5256
+ * catalog pricing when `run_complete` arrives, so the emitted turn cost is
5257
+ * still an estimate rather than vendor-reported dollars.
5224
5258
  */
5225
- costReporting: "reported",
5259
+ costReporting: "estimated",
5226
5260
  costEstimator: null,
5227
5261
  tokenUsageFieldMap: {
5228
5262
  /**
@@ -5255,7 +5289,7 @@ var cursorProfile = {
5255
5289
  {
5256
5290
  event: "cursor_subagent_terminate_noop",
5257
5291
  subagentId,
5258
- reason: "Cursor SDK has no targeted subagent-kill RPC at v1.0.13."
5292
+ reason: "Cursor SDK has no targeted subagent-kill RPC at v1.0.22."
5259
5293
  },
5260
5294
  "cursor_subagent_terminate_noop"
5261
5295
  );
@@ -5357,7 +5391,7 @@ var cursorProfile = {
5357
5391
  }
5358
5392
  },
5359
5393
  /**
5360
- * MCP auth idioms — Cursor 1.0.13 exposes no MCP-auth API
5394
+ * MCP auth idioms — Cursor 1.0.22 exposes no MCP-auth API
5361
5395
  * (`canMcpOauth: false`). The strings here match Claude's shape for
5362
5396
  * contract uniformity but are never reached at runtime.
5363
5397
  */
@@ -5506,38 +5540,6 @@ import { readFile as readFile6 } from "fs/promises";
5506
5540
  import { homedir as homedir8 } from "os";
5507
5541
  import { join as join10 } from "path";
5508
5542
 
5509
- // src/shared/observability/watchdog-context.ts
5510
- var currentLabel = null;
5511
- var prevCompletedLabel = null;
5512
- var prevCompletedDurationMs = 0;
5513
- var prevCompletedAtMs = 0;
5514
- async function withLabelAsync(name, fn) {
5515
- const priorLabel = currentLabel;
5516
- const start = Date.now();
5517
- currentLabel = name;
5518
- try {
5519
- return await fn();
5520
- } finally {
5521
- const completedAt = Date.now();
5522
- prevCompletedLabel = name;
5523
- prevCompletedDurationMs = completedAt - start;
5524
- prevCompletedAtMs = completedAt;
5525
- currentLabel = priorLabel;
5526
- }
5527
- }
5528
- function getCurrentWatchdogLabel() {
5529
- return currentLabel;
5530
- }
5531
- function getPreviousWatchdogLabel() {
5532
- return prevCompletedLabel;
5533
- }
5534
- function getPreviousWatchdogDurationMs() {
5535
- return prevCompletedDurationMs;
5536
- }
5537
- function getPreviousWatchdogCompletedAtMs() {
5538
- return prevCompletedAtMs;
5539
- }
5540
-
5541
5543
  // src/shared/capabilities/agent-providers-cache.ts
5542
5544
  import { mkdir, readFile, rename, stat, unlink, writeFile } from "fs/promises";
5543
5545
  import { dirname as dirname2, join as join4 } from "path";
@@ -5677,6 +5679,7 @@ function buildAgent(id, name, version) {
5677
5679
  }
5678
5680
  var sessionClaudeVersionCache = null;
5679
5681
  var inflightClaudeRevalidation = null;
5682
+ var pendingSessionVersionCachePersists = /* @__PURE__ */ new Set();
5680
5683
  async function loadAgentProvidersFromDisk() {
5681
5684
  if (sessionClaudeVersionCache !== null) return false;
5682
5685
  const entry = await loadClaudeVersionCache();
@@ -5700,7 +5703,7 @@ async function loadAgentProvidersFromDisk() {
5700
5703
  }
5701
5704
  function persistSessionVersionCache(cache) {
5702
5705
  if (!cache.version || cache.binaryMtimeMs == null) return;
5703
- void saveClaudeVersionCache({
5706
+ const persist = saveClaudeVersionCache({
5704
5707
  binaryPath: cache.binaryPath,
5705
5708
  version: cache.version,
5706
5709
  binaryMtimeMs: cache.binaryMtimeMs,
@@ -5710,7 +5713,10 @@ function persistSessionVersionCache(cache) {
5710
5713
  { binaryPath: cache.binaryPath, version: cache.version },
5711
5714
  "claude_code_version_cache_persisted"
5712
5715
  );
5716
+ }).finally(() => {
5717
+ pendingSessionVersionCachePersists.delete(persist);
5713
5718
  });
5719
+ pendingSessionVersionCachePersists.add(persist);
5714
5720
  }
5715
5721
  function isAuthoritativeNotFound(err) {
5716
5722
  if (!(err instanceof Error)) return false;
@@ -6770,6 +6776,71 @@ async function findRenames(cwd, oldRef, newRef) {
6770
6776
  return result;
6771
6777
  }
6772
6778
 
6779
+ // src/services/pr-poll-plan.ts
6780
+ var DAEMON_PR_POLL_INTERVAL_MS = 6e4;
6781
+ var DAEMON_PR_POLL_MAX_CONCURRENT = 4;
6782
+ var DAEMON_PR_POLL_RATE_LIMIT_BACKOFF_MS = 5 * 6e4;
6783
+ function isDaemonPrPollEligible(task) {
6784
+ if (!task.cwd) return false;
6785
+ if (task.archivedAt !== null) return false;
6786
+ if (task.status === "completed" || task.status === "canceled") return false;
6787
+ if (task.mergedAt !== null) return false;
6788
+ if (task.prState === "closed" || task.prState === "merged") return false;
6789
+ if (task.prState === "open" || task.prState === "draft") return true;
6790
+ return task.prUrl !== null;
6791
+ }
6792
+ function decidePrPollPlan(tasks, now, lastPolledAt, rateLimitState, options = {}) {
6793
+ if (rateLimitState.backoffUntil !== null && now < rateLimitState.backoffUntil) return [];
6794
+ const intervalMs = options.intervalMs ?? DAEMON_PR_POLL_INTERVAL_MS;
6795
+ const maxConcurrentPolls = options.maxConcurrentPolls ?? DAEMON_PR_POLL_MAX_CONCURRENT;
6796
+ if (maxConcurrentPolls <= 0) return [];
6797
+ return tasks.filter((task) => {
6798
+ if (!isDaemonPrPollEligible(task)) return false;
6799
+ const last = lastPolledAt.get(task.taskId);
6800
+ return last === void 0 || now - last >= intervalMs;
6801
+ }).sort((a, b) => {
6802
+ const aLast = lastPolledAt.get(a.taskId) ?? Number.NEGATIVE_INFINITY;
6803
+ const bLast = lastPolledAt.get(b.taskId) ?? Number.NEGATIVE_INFINITY;
6804
+ if (aLast !== bLast) return aLast - bLast;
6805
+ return a.taskId.localeCompare(b.taskId);
6806
+ }).slice(0, maxConcurrentPolls).map((task) => task.taskId);
6807
+ }
6808
+
6809
+ // src/shared/capabilities/github-read-backoff.ts
6810
+ var GITHUB_READ_FAILURE_BACKOFF_MS = 6e4;
6811
+ var currentBackoff = null;
6812
+ function messageFor(err) {
6813
+ return err instanceof Error ? err.message : String(err);
6814
+ }
6815
+ function isExpectedNoPullRequest(err) {
6816
+ const message = messageFor(err).toLowerCase();
6817
+ return message.includes("no pull requests found") || message.includes("no pull request found");
6818
+ }
6819
+ function classifyGithubReadFailure(err) {
6820
+ if (isExpectedNoPullRequest(err)) return null;
6821
+ const message = messageFor(err).toLowerCase();
6822
+ const isRateLimit = message.includes("secondary rate") || message.includes("abuse detection") || message.includes("rate limit") || message.includes("http 403") || message.includes("status code 403");
6823
+ return {
6824
+ backoffUntil: Date.now() + (isRateLimit ? DAEMON_PR_POLL_RATE_LIMIT_BACKOFF_MS : GITHUB_READ_FAILURE_BACKOFF_MS),
6825
+ reason: isRateLimit ? "github_rate_limit" : "github_read_failure"
6826
+ };
6827
+ }
6828
+ function recordGithubReadFailure(err) {
6829
+ const next = classifyGithubReadFailure(err);
6830
+ if (!next) return;
6831
+ if (currentBackoff && currentBackoff.backoffUntil >= next.backoffUntil) return;
6832
+ currentBackoff = next;
6833
+ }
6834
+ function getGithubReadBackoffState(now = Date.now()) {
6835
+ if (currentBackoff && now >= currentBackoff.backoffUntil) {
6836
+ currentBackoff = null;
6837
+ }
6838
+ return {
6839
+ backoffUntil: currentBackoff?.backoffUntil ?? null,
6840
+ reason: currentBackoff?.reason ?? null
6841
+ };
6842
+ }
6843
+
6773
6844
  // src/shared/capabilities/git-pr-search.ts
6774
6845
  var SEARCH_PR_JSON_FIELDS = "number,title,url,state,isDraft,author,labels,updatedAt,createdAt,assignees,repository,commentsCount";
6775
6846
  var PR_VIEW_JSON_FIELDS = "baseRefName,headRefName,headRepository,isCrossRepository,reviewDecision,additions,deletions,changedFiles,comments,reviewRequests";
@@ -7226,7 +7297,8 @@ async function getPRForCurrentBranch(cwd) {
7226
7297
  return null;
7227
7298
  }
7228
7299
  return mapGhPRToPRData(parseResult.data);
7229
- } catch {
7300
+ } catch (err) {
7301
+ recordGithubReadFailure(err);
7230
7302
  return null;
7231
7303
  }
7232
7304
  }
@@ -7249,7 +7321,8 @@ async function getAssignedReviews(cwd) {
7249
7321
  const parseResult = GhPRListResponseSchema.safeParse(JSON.parse(result.value.trim()));
7250
7322
  if (!parseResult.success) return [];
7251
7323
  return parseResult.data.map(mapGhPRToPRData);
7252
- } catch {
7324
+ } catch (err) {
7325
+ recordGithubReadFailure(err);
7253
7326
  return [];
7254
7327
  }
7255
7328
  }
@@ -7287,7 +7360,8 @@ async function getPRByBranch(cwd, branch) {
7287
7360
  return b.updatedAt - a.updatedAt;
7288
7361
  });
7289
7362
  return prs[0] ?? null;
7290
- } catch {
7363
+ } catch (err) {
7364
+ recordGithubReadFailure(err);
7291
7365
  return null;
7292
7366
  }
7293
7367
  }
@@ -7312,7 +7386,8 @@ async function getUserPRs(cwd) {
7312
7386
  const parseResult = GhPRListResponseSchema.safeParse(JSON.parse(result.value.trim()));
7313
7387
  if (!parseResult.success) return [];
7314
7388
  return parseResult.data.map(mapGhPRToPRData);
7315
- } catch {
7389
+ } catch (err) {
7390
+ recordGithubReadFailure(err);
7316
7391
  return [];
7317
7392
  }
7318
7393
  }
@@ -8067,6 +8142,7 @@ export {
8067
8142
  resolveClaudeBinaryPath,
8068
8143
  getSupportedEfforts,
8069
8144
  getSupportedEffortsSync,
8145
+ withLabelAsync,
8070
8146
  getCurrentWatchdogLabel,
8071
8147
  getPreviousWatchdogLabel,
8072
8148
  getPreviousWatchdogDurationMs,
@@ -8140,6 +8216,11 @@ export {
8140
8216
  getStackFiles,
8141
8217
  getFileAtRef,
8142
8218
  findRenames,
8219
+ DAEMON_PR_POLL_INTERVAL_MS,
8220
+ isDaemonPrPollEligible,
8221
+ decidePrPollPlan,
8222
+ recordGithubReadFailure,
8223
+ getGithubReadBackoffState,
8143
8224
  searchPrs,
8144
8225
  notificationsSince,
8145
8226
  getPRForCurrentBranch,
@@ -8174,4 +8255,4 @@ export {
8174
8255
  refreshInstalledAgents,
8175
8256
  refreshCodexAuthSlice
8176
8257
  };
8177
- //# sourceMappingURL=chunk-NIVME6MT.js.map
8258
+ //# sourceMappingURL=chunk-LN2AW36U.js.map