opencode-swarm 7.164.11 → 7.164.12

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 (107) hide show
  1. package/.opencode/skills/engineering-conventions/SKILL.md +1 -1
  2. package/dist/background/pending-delegations.d.ts +7 -2
  3. package/dist/background/pr-subscriptions.d.ts +3 -3
  4. package/dist/cli/{coder-settlement-0rfk8y11.js → coder-settlement-yh1q5fr3.js} +15 -16
  5. package/dist/cli/{config-doctor-j17b7qq2.js → config-doctor-bd4yzmh7.js} +3 -3
  6. package/dist/cli/{core-evhjjrtt.js → core-y0s1vmyc.js} +2 -2
  7. package/dist/cli/{curation-policy-vj6z5hvr.js → curation-policy-gs1qakn7.js} +5 -6
  8. package/dist/cli/{curator-vqd5yeck.js → curator-brqack0j.js} +48 -46
  9. package/dist/cli/{curator-drift-ez81vg2t.js → curator-drift-1sg9yk2m.js} +14 -12
  10. package/dist/cli/curator-llm-factory-dtsjc3zf.js +70 -0
  11. package/dist/cli/{dispatch-dqybvj8v.js → dispatch-c7xjt7js.js} +3 -3
  12. package/dist/cli/{evidence-summary-service-937x7rbg.js → evidence-summary-service-nqbcvp30.js} +24 -23
  13. package/dist/cli/{gate-evidence-q1cehr4k.js → gate-evidence-9stdtpej.js} +9 -10
  14. package/dist/cli/guardrail-explain-3ff1z3fm.js +71 -0
  15. package/dist/cli/{guardrail-log-3g93f3g2.js → guardrail-log-sf39x00b.js} +10 -10
  16. package/dist/cli/{guardrail-reset-qe2r5qzq.js → guardrail-reset-9wr6a60s.js} +48 -46
  17. package/dist/cli/hive-promoter-bqtj8261.js +85 -0
  18. package/dist/cli/{index-kv2tdkk5.js → index-03enxdaq.js} +1 -1
  19. package/dist/cli/{index-ggrp3v00.js → index-0byep4pe.js} +15 -17
  20. package/dist/cli/{index-2bgr671r.js → index-2bhz5k91.js} +20 -2
  21. package/dist/cli/{index-mmjamc9b.js → index-3fnym6ac.js} +5 -5
  22. package/dist/cli/{index-d9entpn3.js → index-40twgsyh.js} +4 -4
  23. package/dist/cli/{index-ggtmsm84.js → index-4mjmnysc.js} +1 -1
  24. package/dist/cli/{index-e90em0x4.js → index-4vb56w2k.js} +12 -17
  25. package/dist/cli/{index-r656jh9j.js → index-5wc5pbzc.js} +3700 -2609
  26. package/dist/cli/{index-w3gtqey0.js → index-6chhqq2n.js} +4 -4
  27. package/dist/cli/{index-qbw3yw2d.js → index-888pq4xx.js} +11 -11
  28. package/dist/cli/{index-3146wmgv.js → index-8d90gzaz.js} +1 -1
  29. package/dist/cli/{index-5jx22kwc.js → index-8vw2pjgr.js} +544 -15
  30. package/dist/cli/{index-b2nj04q6.js → index-9ss2m4rs.js} +1 -434
  31. package/dist/cli/{index-x43debgx.js → index-ad9064j9.js} +15 -17
  32. package/dist/cli/{index-5kcvrpkt.js → index-b25t91a3.js} +1 -1
  33. package/dist/cli/index-c45662wc.js +361 -0
  34. package/dist/cli/{index-aqppaaqx.js → index-cgewrpw5.js} +3 -2
  35. package/dist/cli/{index-zfs3zqeq.js → index-d3mpxsmy.js} +771 -21
  36. package/dist/cli/{index-y1yqmkv7.js → index-d7j3n5ra.js} +52 -50
  37. package/dist/cli/{index-4vb6qa73.js → index-ebce775n.js} +36 -2
  38. package/dist/cli/{index-dsg9dw3b.js → index-eed0gkv6.js} +2 -2
  39. package/dist/cli/index-es64amqt.js +675 -0
  40. package/dist/cli/{index-9gxbjkts.js → index-ewv8qa8q.js} +22 -19
  41. package/dist/cli/{index-1ww7wj8d.js → index-hb7bh4r2.js} +15 -15
  42. package/dist/cli/{index-kc2tgcm7.js → index-hg09xemc.js} +4 -4
  43. package/dist/cli/{index-w95vxjde.js → index-hvz4ad2t.js} +39 -8
  44. package/dist/cli/{index-77z98j76.js → index-k0s8n6m5.js} +314 -130
  45. package/dist/cli/{index-7m32fjb4.js → index-kxv193aq.js} +9 -9
  46. package/dist/cli/{index-hp22pzn5.js → index-m8xrbdmn.js} +2 -2
  47. package/dist/cli/{index-4gqxppcx.js → index-mee9maf5.js} +2 -2
  48. package/dist/cli/{index-r3mvsbtq.js → index-p612v1mv.js} +7 -1
  49. package/dist/cli/{index-r5q5gd2a.js → index-qgajv9rd.js} +2 -2
  50. package/dist/cli/{index-zjg4chy2.js → index-qqq04n70.js} +2 -2
  51. package/dist/cli/{index-ww6zm5hr.js → index-r2p0pgst.js} +3 -3
  52. package/dist/cli/{index-47kh2103.js → index-r69gzes2.js} +14 -14
  53. package/dist/cli/{index-vdn32nws.js → index-sphahrmq.js} +3 -3
  54. package/dist/cli/{index-rhqdsc1x.js → index-vw66q1rw.js} +9 -9
  55. package/dist/cli/{index-kch6yenm.js → index-wasdrhev.js} +7 -7
  56. package/dist/cli/{index-c5v1w13g.js → index-wknpkfm8.js} +807 -629
  57. package/dist/cli/{index-pp2nya9v.js → index-x39hjdf1.js} +2 -4
  58. package/dist/cli/{index-n8688d12.js → index-xxfk62zd.js} +2 -2
  59. package/dist/cli/index-yvqg6kn5.js +429 -0
  60. package/dist/cli/{index-nqsj0g5y.js → index-ztm0q26v.js} +8 -8
  61. package/dist/cli/index.js +50 -48
  62. package/dist/cli/{knowledge-escalator-j04g450p.js → knowledge-escalator-01vva51d.js} +17 -18
  63. package/dist/cli/{knowledge-events-53z45rs0.js → knowledge-events-dpfwh1hs.js} +15 -16
  64. package/dist/cli/{knowledge-link-a6kfg3qm.js → knowledge-link-2rvp966j.js} +4 -5
  65. package/dist/cli/{knowledge-store-whm0gagt.js → knowledge-store-aw58ae7b.js} +6 -7
  66. package/dist/cli/{knowledge-validator-h8m7065g.js → knowledge-validator-yhd31ryf.js} +8 -9
  67. package/dist/cli/{pending-delegations-6hkpe5ze.js → pending-delegations-fjetcz8e.js} +17 -8
  68. package/dist/cli/{pr-subscriptions-11zca1mh.js → pr-subscriptions-cwwtfs8w.js} +17 -8
  69. package/dist/cli/{pr-workflow-gate-6g29rkg7.js → pr-workflow-gate-5xwtg1k2.js} +50 -48
  70. package/dist/cli/{runner-5abw3t35.js → runner-mb51twxt.js} +6 -7
  71. package/dist/cli/{scan-cursor-mkfx410t.js → scan-cursor-j11qwf0v.js} +9 -10
  72. package/dist/cli/{schema-jbbam3ev.js → schema-0xp3bde3.js} +1 -1
  73. package/dist/cli/{scope-persistence-q1ct4k42.js → scope-persistence-brrk806y.js} +19 -12
  74. package/dist/cli/{skill-generator-cv8fg96x.js → skill-generator-j8qzmet9.js} +20 -21
  75. package/dist/cli/snapshot-coordination-init-h0xmtftq.js +84 -0
  76. package/dist/cli/{telemetry-mbqqamsj.js → telemetry-m84ap0pp.js} +1 -1
  77. package/dist/cli/{workspace-snapshot-eh18vgkn.js → workspace-snapshot-6z9rk7xw.js} +3 -3
  78. package/dist/cli/{worktree-collision-ownership-xgnn8dsq.js → worktree-collision-ownership-j9zykj18.js} +21 -12
  79. package/dist/cli/{worktree-isolation-k2dgfmeg.js → worktree-isolation-jd39xz6h.js} +48 -46
  80. package/dist/commands/close.d.ts +13 -6
  81. package/dist/commands/reset-session.d.ts +4 -0
  82. package/dist/db/coordination-store.d.ts +85 -0
  83. package/dist/db/durability.d.ts +22 -5
  84. package/dist/db/index.d.ts +1 -0
  85. package/dist/db/project-db.d.ts +12 -0
  86. package/dist/index.js +810 -705
  87. package/dist/memory/schema.d.ts +3 -3
  88. package/dist/pr-review/authorization.d.ts +5 -4
  89. package/dist/pr-review/persistence.d.ts +10 -1
  90. package/dist/scope/scope-binding.d.ts +10 -0
  91. package/dist/scope/scope-persistence.d.ts +10 -0
  92. package/dist/services/handoff-service.d.ts +2 -0
  93. package/dist/services/status-service.d.ts +4 -0
  94. package/dist/session/snapshot-coordination-init.d.ts +49 -0
  95. package/dist/session/snapshot-reader.d.ts +2 -0
  96. package/dist/session/snapshot-store.d.ts +42 -0
  97. package/dist/session/snapshot-writer.d.ts +4 -1
  98. package/dist/state.d.ts +6 -3
  99. package/dist/turbo/epic/state.d.ts +4 -20
  100. package/dist/utils/bun-compat.d.ts +10 -0
  101. package/dist/utils/external-tool-runner.d.ts +2 -0
  102. package/package.json +3 -2
  103. package/dist/cli/curator-llm-factory-sxcpmcqq.js +0 -68
  104. package/dist/cli/guardrail-explain-xv9aw1bf.js +0 -69
  105. package/dist/cli/hive-promoter-09yc9mp5.js +0 -83
  106. package/dist/cli/index-xnb3tk7x.js +0 -24
  107. package/dist/cli/{ast-diff-ekd9v10f.js → ast-diff-b0esr2kf.js} +3 -3
@@ -3,17 +3,13 @@ import {
3
3
  EvaluationRunV1Schema,
4
4
  GateAuditResultV1Schema,
5
5
  getProtectedEvaluationRunIds
6
- } from "./index-pp2nya9v.js";
6
+ } from "./index-x39hjdf1.js";
7
7
  import {
8
8
  validateWorkspaceRoot
9
9
  } from "./index-cw912re7.js";
10
10
  import {
11
- DURABILITY_CLASSES,
12
- getProjectDb,
13
- projectDbExists,
14
- readEffectiveSpecSync,
15
- withDurabilityClass
16
- } from "./index-b2nj04q6.js";
11
+ readEffectiveSpecSync
12
+ } from "./index-9ss2m4rs.js";
17
13
  import {
18
14
  getWorktreeMergeFailure
19
15
  } from "./index-zsrtt42s.js";
@@ -27,14 +23,28 @@ import {
27
23
  readTaskEvidence,
28
24
  readTaskEvidenceRaw,
29
25
  sanitizeTaskId
30
- } from "./index-x43debgx.js";
26
+ } from "./index-ad9064j9.js";
27
+ import {
28
+ estimateCharsForTokens,
29
+ estimateTokens,
30
+ readSwarmFileAsync,
31
+ validateSwarmPath
32
+ } from "./index-qqq04n70.js";
33
+ import {
34
+ bunHash,
35
+ bunWrite,
36
+ mergeEnvForChild
37
+ } from "./index-p612v1mv.js";
38
+ import {
39
+ EVIDENCE_MAX_JSON_BYTES,
40
+ EvidenceBundleSchema,
41
+ EvidenceSchema
42
+ } from "./index-3qf1vxtb.js";
31
43
  import {
32
44
  LedgerStaleWriterError,
33
45
  appendLedgerEvent,
34
46
  computeCurrentPlanHash,
35
47
  computePlanLedgerHash,
36
- derivePlanId,
37
- derivePlanIdentityHash,
38
48
  getLatestLedgerSeq,
39
49
  initLedger,
40
50
  ledgerExists,
@@ -47,40 +57,24 @@ import {
47
57
  replayFromLedgerWithStatus,
48
58
  takeSnapshotEvent,
49
59
  takeSnapshotWithRetry
50
- } from "./index-e90em0x4.js";
60
+ } from "./index-4vb56w2k.js";
51
61
  import {
52
62
  appendCoreEventSync
53
- } from "./index-4gqxppcx.js";
63
+ } from "./index-mee9maf5.js";
54
64
  import {
55
- init_executor,
56
- isUntrustedEnvKey,
57
- isValidEnvKey
58
- } from "./index-4fwbbad3.js";
59
- import {
60
- EVIDENCE_MAX_JSON_BYTES,
61
- EvidenceBundleSchema,
62
- EvidenceSchema
63
- } from "./index-3qf1vxtb.js";
64
- import {
65
- estimateCharsForTokens,
66
- estimateTokens,
67
- readSwarmFileAsync,
68
- validateSwarmPath
69
- } from "./index-zjg4chy2.js";
70
- import {
71
- bunHash,
72
- bunWrite,
73
- mergeEnvForChild
74
- } from "./index-r3mvsbtq.js";
75
- import {
76
- PlanSchema
77
- } from "./index-rhqdsc1x.js";
65
+ derivePlanId,
66
+ derivePlanIdentityHash,
67
+ getCoordinationState,
68
+ importCoordinationOnce,
69
+ listCoordinationStates,
70
+ transitionCoordinationState
71
+ } from "./index-c45662wc.js";
78
72
  import {
79
- GIT_BINARY_ENV_VAR,
80
- describeGitResolution,
81
- init_git_executable,
82
- resolveGitExecutable
83
- } from "./index-9e6fdz2h.js";
73
+ DURABILITY_CLASSES,
74
+ getProjectDb,
75
+ projectDbExists,
76
+ withDurabilityClass
77
+ } from "./index-es64amqt.js";
84
78
  import {
85
79
  canonicalRootKeyFresh
86
80
  } from "./index-7qefgq4j.js";
@@ -88,18 +82,33 @@ import {
88
82
  assertProjectRoot,
89
83
  tryAcquireLock,
90
84
  withEvidenceLock
91
- } from "./index-2bgr671r.js";
85
+ } from "./index-2bhz5k91.js";
92
86
  import {
87
+ atomicWriteSwarmFileSync,
93
88
  invalidateCachedArtifact,
94
89
  readCachedParsedFile
95
- } from "./index-9gxbjkts.js";
90
+ } from "./index-ewv8qa8q.js";
96
91
  import {
97
92
  emit
98
- } from "./index-ww6zm5hr.js";
93
+ } from "./index-r2p0pgst.js";
94
+ import {
95
+ PlanSchema
96
+ } from "./index-vw66q1rw.js";
97
+ import {
98
+ GIT_BINARY_ENV_VAR,
99
+ describeGitResolution,
100
+ init_git_executable,
101
+ resolveGitExecutable
102
+ } from "./index-9e6fdz2h.js";
99
103
  import {
100
104
  ZodError,
101
105
  init_zod
102
106
  } from "./index-bpmtbmy9.js";
107
+ import {
108
+ init_executor,
109
+ isUntrustedEnvKey,
110
+ isValidEnvKey
111
+ } from "./index-4fwbbad3.js";
103
112
  import {
104
113
  criticalWarn,
105
114
  error,
@@ -117,8 +126,8 @@ import {
117
126
  openSync,
118
127
  readdirSync,
119
128
  renameSync as renameSync2,
120
- unlinkSync as unlinkSync2,
121
- writeFileSync as writeFileSync2
129
+ unlinkSync,
130
+ writeFileSync
122
131
  } from "fs";
123
132
  import * as fsPromises from "fs/promises";
124
133
  import * as path4 from "path";
@@ -1069,10 +1078,13 @@ var _internals2 = {
1069
1078
  };
1070
1079
 
1071
1080
  // src/turbo/epic/state.ts
1081
+ import { createHash as createHash3 } from "crypto";
1072
1082
  import * as fs2 from "fs";
1073
1083
  import * as path2 from "path";
1074
1084
  init_logger();
1075
1085
  var STATE_FILE = "epic-state.json";
1086
+ var COORDINATION_NAMESPACE = "turbo.epic.session";
1087
+ var MAX_SESSION_WRITE_ATTEMPTS = 5;
1076
1088
  function nowISO() {
1077
1089
  return new Date().toISOString();
1078
1090
  }
@@ -1083,6 +1095,200 @@ function ensureSwarmDir(directory) {
1083
1095
  }
1084
1096
  return swarmDir;
1085
1097
  }
1098
+ function stateFilePath(directory) {
1099
+ return path2.join(directory, ".swarm", STATE_FILE);
1100
+ }
1101
+ function importedStateFilePath(directory) {
1102
+ return `${stateFilePath(directory)}.imported`;
1103
+ }
1104
+ function archiveStateFileWithoutOverwrite(directory) {
1105
+ const filePath = stateFilePath(directory);
1106
+ if (!fs2.existsSync(filePath))
1107
+ return;
1108
+ const canonical = importedStateFilePath(directory);
1109
+ if (!fs2.existsSync(canonical)) {
1110
+ fs2.renameSync(filePath, canonical);
1111
+ return;
1112
+ }
1113
+ for (let suffix = 1;suffix <= 1000; suffix += 1) {
1114
+ const candidate = `${canonical}.${suffix}`;
1115
+ if (fs2.existsSync(candidate))
1116
+ continue;
1117
+ fs2.renameSync(filePath, candidate);
1118
+ return;
1119
+ }
1120
+ throw new Error("Epic state legacy archive collision limit exceeded");
1121
+ }
1122
+ function isRecord(value) {
1123
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1124
+ }
1125
+ function validatePersistedShape(parsed) {
1126
+ return isRecord(parsed) && parsed.version === 1 && isRecord(parsed.sessions);
1127
+ }
1128
+ function parsePersistedJson(raw) {
1129
+ const parsed = JSON.parse(raw);
1130
+ if (!validatePersistedShape(parsed)) {
1131
+ const maybe = parsed;
1132
+ throw new Error(`malformed shape (version=${maybe?.version}, sessions type=${Array.isArray(maybe?.sessions) ? "array" : typeof maybe?.sessions})`);
1133
+ }
1134
+ return {
1135
+ version: 1,
1136
+ updatedAt: typeof parsed.updatedAt === "string" && parsed.updatedAt.length > 0 ? parsed.updatedAt : nowISO(),
1137
+ sessions: parsed.sessions
1138
+ };
1139
+ }
1140
+ function parseSessionPayload(payload, entityKey) {
1141
+ const parsed = JSON.parse(payload);
1142
+ if (!isRecord(parsed) || parsed.sessionID !== entityKey) {
1143
+ throw new Error(`session payload malformed for ${entityKey}: sessionID mismatch`);
1144
+ }
1145
+ return parsed;
1146
+ }
1147
+ function buildPersistedFromCoordination(directory) {
1148
+ const rows = listCoordinationStates(directory, COORDINATION_NAMESPACE);
1149
+ if (rows.length === 0)
1150
+ return null;
1151
+ const sessions = {};
1152
+ let updatedAt = "";
1153
+ for (const row of rows) {
1154
+ sessions[row.entityKey] = parseSessionPayload(row.payload, row.entityKey);
1155
+ if (!updatedAt || row.updatedAt > updatedAt)
1156
+ updatedAt = row.updatedAt;
1157
+ }
1158
+ return {
1159
+ version: 1,
1160
+ updatedAt: updatedAt || nowISO(),
1161
+ sessions
1162
+ };
1163
+ }
1164
+ function readLegacyPersisted(directory) {
1165
+ const filePath = stateFilePath(directory);
1166
+ if (!fs2.existsSync(filePath))
1167
+ return null;
1168
+ const raw = fs2.readFileSync(filePath, "utf-8");
1169
+ return {
1170
+ persisted: parsePersistedJson(raw),
1171
+ sourceDigest: createHash3("sha256").update(raw).digest("hex")
1172
+ };
1173
+ }
1174
+ function writeProjection(directory, persisted) {
1175
+ ensureSwarmDir(directory);
1176
+ const filePath = stateFilePath(directory);
1177
+ if (fs2.existsSync(filePath) && fs2.lstatSync(filePath).isDirectory()) {
1178
+ throw new Error(`${STATE_FILE} is a directory`);
1179
+ }
1180
+ const payload = `${JSON.stringify(persisted, null, 2)}
1181
+ `;
1182
+ atomicWriteSwarmFileSync(filePath, payload);
1183
+ }
1184
+ function seedProjectionBestEffort(directory, persisted) {
1185
+ try {
1186
+ writeProjection(directory, persisted);
1187
+ } catch {}
1188
+ }
1189
+ function preflightProjectionTarget(directory) {
1190
+ ensureSwarmDir(directory);
1191
+ const filePath = stateFilePath(directory);
1192
+ if (fs2.existsSync(filePath) && fs2.lstatSync(filePath).isDirectory()) {
1193
+ throw new Error(`Epic state persistence prepare failed: ${STATE_FILE} is a directory`);
1194
+ }
1195
+ }
1196
+ function importLegacyStateIfNeeded(directory) {
1197
+ const legacy = readLegacyPersisted(directory);
1198
+ if (!legacy)
1199
+ return null;
1200
+ const outcome = importCoordinationOnce(directory, {
1201
+ source: STATE_FILE,
1202
+ sourceDigest: legacy.sourceDigest,
1203
+ rowCount: Object.keys(legacy.persisted.sessions).length,
1204
+ emptyNamespace: COORDINATION_NAMESPACE
1205
+ }, () => {
1206
+ for (const [sessionID, state] of Object.entries(legacy.persisted.sessions)) {
1207
+ const result = transitionCoordinationState(directory, {
1208
+ namespace: COORDINATION_NAMESPACE,
1209
+ entityKey: sessionID,
1210
+ expectedRevision: null,
1211
+ generation: 1,
1212
+ status: state.active ? "active" : "inactive",
1213
+ payload: JSON.stringify(state)
1214
+ });
1215
+ if (result.outcome !== "applied") {
1216
+ throw new Error("Epic legacy import conflict");
1217
+ }
1218
+ }
1219
+ });
1220
+ if (outcome === "imported") {
1221
+ archiveStateFileWithoutOverwrite(directory);
1222
+ }
1223
+ const authoritative = buildPersistedFromCoordination(directory) ?? emptyPersisted();
1224
+ seedProjectionBestEffort(directory, authoritative);
1225
+ return authoritative;
1226
+ }
1227
+ function unreadableStateError(directory) {
1228
+ return new Error(`Epic state is unreadable for ${directory}. Repair .swarm/${STATE_FILE} before continuing.`);
1229
+ }
1230
+ function ensureReadableState(directory) {
1231
+ if (stateUnreadableMap.get(stateKey(directory)))
1232
+ throw unreadableStateError(directory);
1233
+ if (!readPersisted(directory))
1234
+ throw unreadableStateError(directory);
1235
+ }
1236
+ function refreshProjectionFromCoordination(directory) {
1237
+ const persisted = buildPersistedFromCoordination(directory) ?? emptyPersisted();
1238
+ writeProjection(directory, persisted);
1239
+ }
1240
+ function saveSessionRowAtomic(directory, state) {
1241
+ preflightProjectionTarget(directory);
1242
+ ensureReadableState(directory);
1243
+ for (let attempt = 0;attempt < MAX_SESSION_WRITE_ATTEMPTS; attempt++) {
1244
+ const current = getCoordinationState(directory, COORDINATION_NAMESPACE, state.sessionID);
1245
+ const result = transitionCoordinationState(directory, {
1246
+ namespace: COORDINATION_NAMESPACE,
1247
+ entityKey: state.sessionID,
1248
+ expectedRevision: current?.revision ?? null,
1249
+ generation: (current?.generation ?? 0) + 1,
1250
+ status: state.active ? "active" : "inactive",
1251
+ payload: JSON.stringify(state)
1252
+ });
1253
+ if (result.outcome === "applied") {
1254
+ refreshProjectionFromCoordination(directory);
1255
+ return;
1256
+ }
1257
+ if (result.outcome === "revision_conflict" || result.outcome === "stale_generation") {
1258
+ continue;
1259
+ }
1260
+ throw new Error(`Epic state persistence failed: ${result.outcome} for ${state.sessionID}`);
1261
+ }
1262
+ throw new Error(`Epic state persistence failed: contention for ${state.sessionID}`);
1263
+ }
1264
+ function mutateSessionRowAtomic(directory, sessionID, mutate) {
1265
+ preflightProjectionTarget(directory);
1266
+ ensureReadableState(directory);
1267
+ for (let attempt = 0;attempt < MAX_SESSION_WRITE_ATTEMPTS; attempt++) {
1268
+ const current = getCoordinationState(directory, COORDINATION_NAMESPACE, sessionID);
1269
+ if (!current)
1270
+ return null;
1271
+ const nextState = parseSessionPayload(current.payload, sessionID);
1272
+ mutate(nextState);
1273
+ const result = transitionCoordinationState(directory, {
1274
+ namespace: COORDINATION_NAMESPACE,
1275
+ entityKey: sessionID,
1276
+ expectedRevision: current.revision,
1277
+ generation: current.generation + 1,
1278
+ status: nextState.active ? "active" : "inactive",
1279
+ payload: JSON.stringify(nextState)
1280
+ });
1281
+ if (result.outcome === "applied") {
1282
+ refreshProjectionFromCoordination(directory);
1283
+ return nextState;
1284
+ }
1285
+ if (result.outcome === "revision_conflict" || result.outcome === "stale_generation") {
1286
+ continue;
1287
+ }
1288
+ throw new Error(`Epic state persistence failed: ${result.outcome} for ${sessionID}`);
1289
+ }
1290
+ throw new Error(`Epic state persistence failed: contention for ${sessionID}`);
1291
+ }
1086
1292
  function emptyPersisted() {
1087
1293
  return { version: 1, updatedAt: nowISO(), sessions: {} };
1088
1294
  }
@@ -1098,69 +1304,38 @@ function isStateUnreadable(directory) {
1098
1304
  }
1099
1305
  function markStateUnreadable(directory, reason) {
1100
1306
  stateUnreadableMap.set(stateKey(directory), true);
1101
- error(`[turbo/epic/state] state file unreadable for ${directory}: ${reason} \u2014 failing closed`);
1307
+ error(`[turbo/epic/state] state unreadable for ${directory}: ${reason} \u2014 failing closed`);
1102
1308
  }
1103
1309
  function readPersisted(directory) {
1104
1310
  try {
1105
- const filePath = path2.join(directory, ".swarm", STATE_FILE);
1106
- if (!fs2.existsSync(filePath)) {
1107
- const seed = emptyPersisted();
1108
- try {
1109
- ensureSwarmDir(directory);
1110
- fs2.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
1111
- `, "utf-8");
1112
- } catch {}
1113
- return seed;
1114
- }
1115
- const raw = fs2.readFileSync(filePath, "utf-8");
1116
- const parsed = JSON.parse(raw);
1117
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
1118
- markStateUnreadable(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
1119
- return null;
1311
+ const coordinated = buildPersistedFromCoordination(directory);
1312
+ if (coordinated) {
1313
+ const filePath = stateFilePath(directory);
1314
+ if (fs2.existsSync(filePath)) {
1315
+ let matches = false;
1316
+ try {
1317
+ matches = JSON.stringify(parsePersistedJson(fs2.readFileSync(filePath, "utf-8"))) === JSON.stringify(coordinated);
1318
+ } catch {
1319
+ matches = false;
1320
+ }
1321
+ if (!matches)
1322
+ archiveStateFileWithoutOverwrite(directory);
1323
+ }
1324
+ seedProjectionBestEffort(directory, coordinated);
1325
+ return coordinated;
1120
1326
  }
1121
- return {
1122
- version: 1,
1123
- updatedAt: parsed.updatedAt ?? nowISO(),
1124
- sessions: parsed.sessions
1125
- };
1327
+ const imported = importLegacyStateIfNeeded(directory);
1328
+ if (imported)
1329
+ return imported;
1330
+ const seed = emptyPersisted();
1331
+ seedProjectionBestEffort(directory, seed);
1332
+ return seed;
1126
1333
  } catch (error2) {
1127
1334
  const reason = error2 instanceof Error ? error2.message : String(error2);
1128
1335
  markStateUnreadable(directory, reason);
1129
1336
  return null;
1130
1337
  }
1131
1338
  }
1132
- function writePersisted(directory, persisted) {
1133
- if (stateUnreadableMap.get(stateKey(directory))) {
1134
- throw new Error(`Epic state is unreadable. Please repair .swarm/${STATE_FILE} before continuing.`);
1135
- }
1136
- let filePath;
1137
- let tmpPath;
1138
- let payload;
1139
- try {
1140
- ensureSwarmDir(directory);
1141
- filePath = path2.join(directory, ".swarm", STATE_FILE);
1142
- tmpPath = `${filePath}.tmp.${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
1143
- persisted.updatedAt = nowISO();
1144
- payload = `${JSON.stringify(persisted, null, 2)}
1145
- `;
1146
- } catch (error2) {
1147
- const msg = error2 instanceof Error ? error2.message : String(error2);
1148
- error(`[turbo/epic/state] Failed to prepare ${STATE_FILE} write: ${msg}`);
1149
- throw new Error(`Epic state persistence prepare failed: ${msg}`);
1150
- }
1151
- try {
1152
- fs2.writeFileSync(tmpPath, payload, "utf-8");
1153
- fs2.renameSync(tmpPath, filePath);
1154
- } catch (error2) {
1155
- const msg = error2 instanceof Error ? error2.message : String(error2);
1156
- error(`[turbo/epic/state] Failed to persist ${STATE_FILE} atomically: ${msg}`);
1157
- try {
1158
- if (fs2.existsSync(tmpPath))
1159
- fs2.unlinkSync(tmpPath);
1160
- } catch {}
1161
- throw new Error(`Epic state persistence failed: ${msg}`);
1162
- }
1163
- }
1164
1339
  function loadEpicSessionState(directory, sessionID) {
1165
1340
  if (stateUnreadableMap.get(stateKey(directory)))
1166
1341
  return null;
@@ -1169,25 +1344,23 @@ function loadEpicSessionState(directory, sessionID) {
1169
1344
  return null;
1170
1345
  return persisted.sessions[sessionID] ?? null;
1171
1346
  }
1172
- function saveEpicSessionState(directory, state) {
1173
- if (stateUnreadableMap.get(stateKey(directory))) {
1174
- throw new Error(`Epic state is unreadable for ${directory}. Repair .swarm/${STATE_FILE} before continuing.`);
1175
- }
1176
- const persisted = readPersisted(directory);
1177
- if (!persisted) {
1178
- throw new Error(`Epic state is unreadable for ${directory}. Repair .swarm/${STATE_FILE} before continuing.`);
1179
- }
1180
- persisted.sessions[state.sessionID] = state;
1181
- writePersisted(directory, persisted);
1182
- }
1183
1347
  function isEpicModeActive(directory, sessionID) {
1184
1348
  const state = loadEpicSessionState(directory, sessionID);
1185
1349
  return state?.active === true;
1186
1350
  }
1187
1351
  function isEpicModeActiveForProject(directory) {
1352
+ if (directory.split(/[\\/]/).includes(".."))
1353
+ return false;
1188
1354
  if (stateUnreadableMap.get(stateKey(directory)))
1189
1355
  return false;
1190
- if (!fs2.existsSync(path2.join(directory, ".swarm", STATE_FILE))) {
1356
+ const hasLegacyFile = fs2.existsSync(stateFilePath(directory));
1357
+ let hasCoordinationRows = false;
1358
+ try {
1359
+ hasCoordinationRows = projectDbExists(directory) && listCoordinationStates(directory, COORDINATION_NAMESPACE, 1).length > 0;
1360
+ } catch {
1361
+ return false;
1362
+ }
1363
+ if (!hasLegacyFile && !hasCoordinationRows) {
1191
1364
  return false;
1192
1365
  }
1193
1366
  const persisted = readPersisted(directory);
@@ -1200,24 +1373,35 @@ function isEpicModeActiveForProject(directory) {
1200
1373
  return false;
1201
1374
  }
1202
1375
  function enableEpicMode(directory, sessionID) {
1203
- const current = loadEpicSessionState(directory, sessionID) ?? emptySessionState(sessionID);
1204
- current.active = true;
1205
- current.enabledAt = nowISO();
1206
- current.disabledAt = undefined;
1207
- saveEpicSessionState(directory, current);
1376
+ const current = loadEpicSessionState(directory, sessionID);
1377
+ if (!current) {
1378
+ saveSessionRowAtomic(directory, {
1379
+ ...emptySessionState(sessionID),
1380
+ active: true,
1381
+ enabledAt: nowISO(),
1382
+ disabledAt: undefined
1383
+ });
1384
+ return;
1385
+ }
1386
+ mutateSessionRowAtomic(directory, sessionID, (state) => {
1387
+ state.active = true;
1388
+ state.enabledAt = nowISO();
1389
+ state.disabledAt = undefined;
1390
+ });
1208
1391
  }
1209
1392
  function disableEpicMode(directory, sessionID) {
1210
1393
  const current = loadEpicSessionState(directory, sessionID);
1211
1394
  if (!current) {
1212
- saveEpicSessionState(directory, {
1395
+ saveSessionRowAtomic(directory, {
1213
1396
  ...emptySessionState(sessionID),
1214
1397
  disabledAt: nowISO()
1215
1398
  });
1216
1399
  return;
1217
1400
  }
1218
- current.active = false;
1219
- current.disabledAt = nowISO();
1220
- saveEpicSessionState(directory, current);
1401
+ mutateSessionRowAtomic(directory, sessionID, (state) => {
1402
+ state.active = false;
1403
+ state.disabledAt = nowISO();
1404
+ });
1221
1405
  }
1222
1406
 
1223
1407
  // src/turbo/epic/task-commit.ts
@@ -1459,14 +1643,14 @@ function readTaskScopes(directory, taskId) {
1459
1643
  }
1460
1644
 
1461
1645
  // src/utils/spec-hash.ts
1462
- import { createHash as createHash3 } from "crypto";
1646
+ import { createHash as createHash4 } from "crypto";
1463
1647
  import * as fsSync2 from "fs";
1464
1648
  import { join as join3 } from "path";
1465
1649
  async function computeSpecHash(directory) {
1466
1650
  const spec = _internals4.readEffectiveSpecSync(directory);
1467
1651
  if (!spec)
1468
1652
  return null;
1469
- return createHash3("sha256").update(spec.content, "utf-8").digest("hex");
1653
+ return createHash4("sha256").update(spec.content, "utf-8").digest("hex");
1470
1654
  }
1471
1655
  async function isSpecStale(directory, plan) {
1472
1656
  const currentHash = await _internals4.computeSpecHash(directory);
@@ -1876,7 +2060,7 @@ ${markdown}`;
1876
2060
  renameSync2(mdTempPath, mdPath);
1877
2061
  } finally {
1878
2062
  try {
1879
- unlinkSync2(mdTempPath);
2063
+ unlinkSync(mdTempPath);
1880
2064
  } catch {}
1881
2065
  }
1882
2066
  invalidateCachedArtifact(mdPath);
@@ -2234,7 +2418,7 @@ async function savePlan(directory, plan, options) {
2234
2418
  if (errorMessage2.includes("already initialized")) {
2235
2419
  try {
2236
2420
  if (existsSync3(oldLedgerBackupPath))
2237
- unlinkSync2(oldLedgerBackupPath);
2421
+ unlinkSync(oldLedgerBackupPath);
2238
2422
  } catch {}
2239
2423
  } else {
2240
2424
  if (existsSync3(oldLedgerBackupPath)) {
@@ -2243,7 +2427,7 @@ async function savePlan(directory, plan, options) {
2243
2427
  } catch {
2244
2428
  copyFileSync(oldLedgerBackupPath, oldLedgerPath);
2245
2429
  try {
2246
- unlinkSync2(oldLedgerBackupPath);
2430
+ unlinkSync(oldLedgerBackupPath);
2247
2431
  } catch {}
2248
2432
  }
2249
2433
  }
@@ -2260,13 +2444,13 @@ async function savePlan(directory, plan, options) {
2260
2444
  warn(`[savePlan] Could not archive old ledger (rename failed: ${renameErr instanceof Error ? renameErr.message : String(renameErr)}). Old ledger may still exist at ${oldLedgerBackupPath}.`);
2261
2445
  try {
2262
2446
  if (existsSync3(oldLedgerBackupPath))
2263
- unlinkSync2(oldLedgerBackupPath);
2447
+ unlinkSync(oldLedgerBackupPath);
2264
2448
  } catch {}
2265
2449
  }
2266
2450
  } else if (!initSucceeded && backupExists) {
2267
2451
  try {
2268
2452
  if (existsSync3(oldLedgerBackupPath))
2269
- unlinkSync2(oldLedgerBackupPath);
2453
+ unlinkSync(oldLedgerBackupPath);
2270
2454
  } catch {}
2271
2455
  }
2272
2456
  const MAX_ARCHIVED_SIBLINGS = 5;
@@ -2277,7 +2461,7 @@ async function savePlan(directory, plan, options) {
2277
2461
  const toRemove = archivedSiblings.slice(0, archivedSiblings.length - MAX_ARCHIVED_SIBLINGS);
2278
2462
  for (const file of toRemove) {
2279
2463
  try {
2280
- unlinkSync2(path4.join(swarmDir2, file));
2464
+ unlinkSync(path4.join(swarmDir2, file));
2281
2465
  } catch {}
2282
2466
  }
2283
2467
  }
@@ -2469,7 +2653,7 @@ async function savePlan(directory, plan, options) {
2469
2653
  renameSync2(tempPath, planPath);
2470
2654
  } finally {
2471
2655
  try {
2472
- unlinkSync2(tempPath);
2656
+ unlinkSync(tempPath);
2473
2657
  } catch {}
2474
2658
  }
2475
2659
  invalidateCachedArtifact(planPath);
@@ -2496,7 +2680,7 @@ ${markdown}`;
2496
2680
  renameSync2(mdTempPath, mdPath);
2497
2681
  } finally {
2498
2682
  try {
2499
- unlinkSync2(mdTempPath);
2683
+ unlinkSync(mdTempPath);
2500
2684
  } catch {}
2501
2685
  }
2502
2686
  invalidateCachedArtifact(mdPath);
@@ -2568,7 +2752,7 @@ async function rebuildPlan(directory, plan, options) {
2568
2752
  {
2569
2753
  const fd = openSync(tempPlanPath, "w");
2570
2754
  try {
2571
- writeFileSync2(fd, JSON.stringify(targetPlan, null, 2), "utf8");
2755
+ writeFileSync(fd, JSON.stringify(targetPlan, null, 2), "utf8");
2572
2756
  fsyncSync(fd);
2573
2757
  } finally {
2574
2758
  closeSync(fd);
@@ -1,4 +1,9 @@
1
1
  // @bun
2
+ import {
3
+ queryHistoricalOutcomes,
4
+ readKnowledgeEvents,
5
+ recordKnowledgeEvent
6
+ } from "./index-0byep4pe.js";
2
7
  import {
3
8
  jaccardBigram,
4
9
  readKnowledge,
@@ -6,12 +11,7 @@ import {
6
11
  resolveSwarmKnowledgePath,
7
12
  transactKnowledge,
8
13
  wordBigrams
9
- } from "./index-qbw3yw2d.js";
10
- import {
11
- queryHistoricalOutcomes,
12
- readKnowledgeEvents,
13
- recordKnowledgeEvent
14
- } from "./index-ggrp3v00.js";
14
+ } from "./index-888pq4xx.js";
15
15
  import {
16
16
  init_knowledge_types,
17
17
  isActiveStatus
@@ -224,11 +224,11 @@ async function maybeQuarantineOnContradiction(directory, entryId, threshold, win
224
224
  alreadyInactive: true
225
225
  };
226
226
  }
227
- const { quarantineEntry } = await import("./knowledge-validator-h8m7065g.js");
227
+ const { quarantineEntry } = await import("./knowledge-validator-yhd31ryf.js");
228
228
  let policyConfig;
229
229
  try {
230
- const { KnowledgeConfigSchema } = await import("./schema-jbbam3ev.js");
231
- const { loadPluginConfigWithMeta } = await import("./index-mmjamc9b.js");
230
+ const { KnowledgeConfigSchema } = await import("./schema-0xp3bde3.js");
231
+ const { loadPluginConfigWithMeta } = await import("./index-3fnym6ac.js");
232
232
  const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
233
233
  policyConfig = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
234
234
  } catch {
@@ -14,14 +14,14 @@ import {
14
14
  detectWindowsWrites,
15
15
  getSharedClassifierGuardrailBlock,
16
16
  resolveWriteTargets
17
- } from "./index-r656jh9j.js";
17
+ } from "./index-5wc5pbzc.js";
18
18
  import {
19
19
  checkFileAuthority,
20
20
  classifyFile,
21
21
  isInDeclaredScope,
22
22
  redactPath,
23
23
  redactShellCommand
24
- } from "./index-kch6yenm.js";
24
+ } from "./index-wasdrhev.js";
25
25
 
26
26
  // src/services/guardrail-explain-service.ts
27
27
  import path from "path";