@wrongstack/core 0.270.0 → 0.272.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 (76) hide show
  1. package/dist/{agent-bridge-PcHQl_UQ.d.ts → agent-bridge-jVSZiygR.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-SHJW7t8q.d.ts → agent-subagent-runner-DOLIwBRo.d.ts} +7 -7
  3. package/dist/{brain-BYcK__Ym.d.ts → brain-CdbbJWi3.d.ts} +71 -1
  4. package/dist/{compactor-C2RKEBtC.d.ts → compactor-72ug-ZRB.d.ts} +1 -1
  5. package/dist/{config-C_ae2k86.d.ts → config-D2DGoGSQ.d.ts} +29 -2
  6. package/dist/{context-Dp87Bcaq.d.ts → context-Dw55zZ_Q.d.ts} +110 -1
  7. package/dist/coordination/index.d.ts +121 -17
  8. package/dist/coordination/index.js +738 -74
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/defaults/index.d.ts +25 -25
  11. package/dist/defaults/index.js +599 -86
  12. package/dist/defaults/index.js.map +1 -1
  13. package/dist/execution/index.d.ts +23 -18
  14. package/dist/execution/index.js +136 -41
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/execution/prompt-enhancer.d.ts +36 -6
  17. package/dist/execution/prompt-enhancer.js +35 -9
  18. package/dist/execution/prompt-enhancer.js.map +1 -1
  19. package/dist/extension/index.d.ts +6 -6
  20. package/dist/{global-mailbox-Bvrz1P3f.d.ts → global-mailbox-CQj_C9Dp.d.ts} +139 -3
  21. package/dist/{goal-preamble-CA_4yiGQ.d.ts → goal-preamble-ZXDjjR1y.d.ts} +9 -9
  22. package/dist/{goal-store-DhuJoUNG.d.ts → goal-store-CcJBd-g1.d.ts} +1 -1
  23. package/dist/hq/index.d.ts +93 -6
  24. package/dist/hq/index.js +616 -46
  25. package/dist/hq/index.js.map +1 -1
  26. package/dist/{index-whDfTANu.d.ts → index-2Lhk5v0o.d.ts} +2 -2
  27. package/dist/{index-CZQ6Pwbs.d.ts → index-BL7BAx0p.d.ts} +8 -8
  28. package/dist/{index-W4VJCzHa.d.ts → index-Qo4kTzgw.d.ts} +5 -5
  29. package/dist/index.d.ts +96 -56
  30. package/dist/index.js +1938 -349
  31. package/dist/index.js.map +1 -1
  32. package/dist/infrastructure/index.d.ts +6 -6
  33. package/dist/infrastructure/index.js +5 -3
  34. package/dist/infrastructure/index.js.map +1 -1
  35. package/dist/kernel/index.d.ts +9 -9
  36. package/dist/kernel/index.js.map +1 -1
  37. package/dist/{mcp-servers-DJdZiRcv.d.ts → mcp-servers-DS-YUXvF.d.ts} +3 -3
  38. package/dist/models/index.d.ts +5 -5
  39. package/dist/models/index.js +28 -5
  40. package/dist/models/index.js.map +1 -1
  41. package/dist/{models-registry-C3a-2-Yd.d.ts → models-registry-DP6pGHet.d.ts} +1 -1
  42. package/dist/{multi-agent-coordinator-CJSpTe5O.d.ts → multi-agent-coordinator-BvbdNQ14.d.ts} +1 -1
  43. package/dist/{null-fleet-bus-QVshIsDx.d.ts → null-fleet-bus-BxTfXBKo.d.ts} +6 -6
  44. package/dist/observability/index.d.ts +2 -2
  45. package/dist/{parallel-eternal-engine-D9y5Pkcc.d.ts → parallel-eternal-engine-Cf-GTegR.d.ts} +9 -9
  46. package/dist/{path-resolver-CnQ8SIfh.d.ts → path-resolver-DztfnFcv.d.ts} +3 -3
  47. package/dist/{permission-CvYQNUqZ.d.ts → permission-CC7XFYWG.d.ts} +1 -1
  48. package/dist/{permission-policy-D5Ss8j4B.d.ts → permission-policy-cYR4RJmw.d.ts} +2 -2
  49. package/dist/{pipeline-l_zzFRh3.d.ts → pipeline-sNIkhXeB.d.ts} +2 -2
  50. package/dist/{plan-templates-NtPgyeJA.d.ts → plan-templates-DYiKFmEb.d.ts} +11 -5
  51. package/dist/{provider-model-resolve-d5poT5y0.d.ts → provider-model-resolve-dYAbTs_i.d.ts} +3 -3
  52. package/dist/{provider-runner-gkctlQV_.d.ts → provider-runner-Dw8x0F7u.d.ts} +3 -3
  53. package/dist/{retry-policy-CtFhfwa8.d.ts → retry-policy-BV7nzeAd.d.ts} +1 -1
  54. package/dist/sdd/index.d.ts +8 -8
  55. package/dist/sdd/index.js +2 -0
  56. package/dist/sdd/index.js.map +1 -1
  57. package/dist/{secret-vault-BLsVmTIK.d.ts → secret-vault-eMBKfheR.d.ts} +9 -1
  58. package/dist/security/index.d.ts +5 -5
  59. package/dist/security/index.js +137 -10
  60. package/dist/security/index.js.map +1 -1
  61. package/dist/{selector-CXl2_y9W.d.ts → selector-C4ORTOid.d.ts} +1 -1
  62. package/dist/{session-event-bridge-Ccud20CC.d.ts → session-event-bridge-CeNpUL9w.d.ts} +1 -1
  63. package/dist/{session-reader-ZeXQmsmE.d.ts → session-reader-BepLSnGL.d.ts} +1 -1
  64. package/dist/storage/index.d.ts +45 -13
  65. package/dist/storage/index.js +374 -113
  66. package/dist/storage/index.js.map +1 -1
  67. package/dist/tools/index.d.ts +2 -2
  68. package/dist/tools/index.js +9 -2
  69. package/dist/tools/index.js.map +1 -1
  70. package/dist/types/index.d.ts +19 -19
  71. package/dist/types/index.js +202 -41
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/utils/index.d.ts +17 -4
  74. package/dist/utils/index.js +48 -9
  75. package/dist/utils/index.js.map +1 -1
  76. package/package.json +1 -1
package/dist/hq/index.js CHANGED
@@ -2,7 +2,7 @@ import { randomUUID, randomBytes, createHash } from 'crypto';
2
2
  import * as syncFs from 'fs';
3
3
  import * as os from 'os';
4
4
  import { hostname } from 'os';
5
- import * as path3 from 'path';
5
+ import * as path2 from 'path';
6
6
  import { basename } from 'path';
7
7
  import * as fsp from 'fs/promises';
8
8
 
@@ -105,7 +105,13 @@ function parseHqFrame(raw) {
105
105
  }
106
106
  }
107
107
  }
108
- var KNOWN_HQ_EVENT_PAYLOAD_TYPES = /* @__PURE__ */ new Set(["mailbox.snapshot", "mailbox.event"]);
108
+ var KNOWN_HQ_EVENT_PAYLOAD_TYPES = /* @__PURE__ */ new Set([
109
+ "mailbox.snapshot",
110
+ "mailbox.event",
111
+ "session.snapshot",
112
+ "session.transcript",
113
+ "session.ended"
114
+ ]);
109
115
  function isHqMailboxMessageSummary(x) {
110
116
  if (typeof x !== "object" || x === null) return false;
111
117
  const v = x;
@@ -152,6 +158,52 @@ function isHqMailboxEventPayload(x) {
152
158
  if (v.agent !== void 0 && !isHqMailboxAgentSummary(v.agent)) return false;
153
159
  return true;
154
160
  }
161
+ var HQ_SESSION_AGENT_STATUSES = /* @__PURE__ */ new Set([
162
+ "idle",
163
+ "running",
164
+ "streaming",
165
+ "waiting_user",
166
+ "error"
167
+ ]);
168
+ function isHqSessionAgentSummary(x) {
169
+ if (typeof x !== "object" || x === null) return false;
170
+ const v = x;
171
+ return typeof v.id === "string" && typeof v.name === "string" && typeof v.status === "string" && HQ_SESSION_AGENT_STATUSES.has(v.status) && typeof v.iterations === "number" && typeof v.toolCalls === "number" && typeof v.lastActivityAt === "string";
172
+ }
173
+ var HQ_SESSION_STATUSES = /* @__PURE__ */ new Set(["active", "idle", "closing", "stale"]);
174
+ function isHqSessionSnapshotPayload(x) {
175
+ if (typeof x !== "object" || x === null) return false;
176
+ const v = x;
177
+ if (typeof v.sessionId !== "string" || typeof v.clientKind !== "string" || typeof v.machineId !== "string" || typeof v.projectId !== "string" || typeof v.projectName !== "string" || typeof v.projectRoot !== "string" || typeof v.status !== "string" || !HQ_SESSION_STATUSES.has(v.status) || typeof v.startedAt !== "string" || typeof v.lastActivityAt !== "string" || typeof v.agentCount !== "number" || !Array.isArray(v.agents)) {
178
+ return false;
179
+ }
180
+ for (const agent of v.agents) {
181
+ if (!isHqSessionAgentSummary(agent)) return false;
182
+ }
183
+ return true;
184
+ }
185
+ var HQ_TRANSCRIPT_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "tool", "system", "error"]);
186
+ function isHqTranscriptEntry(x) {
187
+ if (typeof x !== "object" || x === null) return false;
188
+ const v = x;
189
+ return typeof v.ts === "string" && typeof v.role === "string" && HQ_TRANSCRIPT_ROLES.has(v.role) && typeof v.text === "string";
190
+ }
191
+ function isHqTranscriptAppendPayload(x) {
192
+ if (typeof x !== "object" || x === null) return false;
193
+ const v = x;
194
+ if (typeof v.sessionId !== "string" || typeof v.fromSeq !== "number" || !Array.isArray(v.entries)) {
195
+ return false;
196
+ }
197
+ for (const entry of v.entries) {
198
+ if (!isHqTranscriptEntry(entry)) return false;
199
+ }
200
+ return true;
201
+ }
202
+ function isHqSessionEndedPayload(x) {
203
+ if (typeof x !== "object" || x === null) return false;
204
+ const v = x;
205
+ return typeof v.sessionId === "string" && typeof v.endedAt === "string";
206
+ }
155
207
  function parseHqEventPayload(eventType, payload) {
156
208
  if (!KNOWN_HQ_EVENT_PAYLOAD_TYPES.has(eventType)) {
157
209
  return { ok: true, payload };
@@ -161,6 +213,12 @@ function parseHqEventPayload(eventType, payload) {
161
213
  return isHqMailboxSnapshotPayload(payload) ? { ok: true, payload } : { ok: false, reason: "malformed-payload" };
162
214
  case "mailbox.event":
163
215
  return isHqMailboxEventPayload(payload) ? { ok: true, payload } : { ok: false, reason: "malformed-payload" };
216
+ case "session.snapshot":
217
+ return isHqSessionSnapshotPayload(payload) ? { ok: true, payload } : { ok: false, reason: "malformed-payload" };
218
+ case "session.transcript":
219
+ return isHqTranscriptAppendPayload(payload) ? { ok: true, payload } : { ok: false, reason: "malformed-payload" };
220
+ case "session.ended":
221
+ return isHqSessionEndedPayload(payload) ? { ok: true, payload } : { ok: false, reason: "malformed-payload" };
164
222
  default: {
165
223
  const _exhaustive = eventType;
166
224
  return _exhaustive;
@@ -797,6 +855,41 @@ var HqPublisher = class {
797
855
  ...input.timestamp !== void 0 ? { timestamp: input.timestamp } : {}
798
856
  });
799
857
  }
858
+ /** The client identity this publisher announced (clientId, kind, machineId, …). */
859
+ get identity() {
860
+ return this.options.client;
861
+ }
862
+ /** The project identity this publisher is bound to. */
863
+ get project() {
864
+ return this.options.project;
865
+ }
866
+ /** Publish a live session/terminal snapshot (state + agents). */
867
+ publishSessionSnapshot(payload, opts) {
868
+ return this.publishEvent({
869
+ type: "session.snapshot",
870
+ payload,
871
+ sessionId: payload.sessionId,
872
+ ...opts?.timestamp !== void 0 ? { timestamp: opts.timestamp } : {}
873
+ });
874
+ }
875
+ /** Publish an incremental batch of transcript turns for a session. */
876
+ publishTranscriptAppend(payload, opts) {
877
+ return this.publishEvent({
878
+ type: "session.transcript",
879
+ payload,
880
+ sessionId: payload.sessionId,
881
+ ...opts?.timestamp !== void 0 ? { timestamp: opts.timestamp } : {}
882
+ });
883
+ }
884
+ /** Mark a session/terminal as ended. */
885
+ publishSessionEnded(payload, opts) {
886
+ return this.publishEvent({
887
+ type: "session.ended",
888
+ payload,
889
+ sessionId: payload.sessionId,
890
+ ...opts?.timestamp !== void 0 ? { timestamp: opts.timestamp } : {}
891
+ });
892
+ }
800
893
  pollCommands() {
801
894
  this.sendFrame({
802
895
  type: "client.command_poll",
@@ -914,9 +1007,9 @@ var HqPublisher = class {
914
1007
  }
915
1008
  };
916
1009
  async function atomicWrite(targetPath, content, opts = {}) {
917
- const dir = path3.dirname(targetPath);
1010
+ const dir = path2.dirname(targetPath);
918
1011
  await fsp.mkdir(dir, { recursive: true });
919
- const tmp = path3.join(dir, `.${path3.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
1012
+ const tmp = path2.join(dir, `.${path2.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
920
1013
  try {
921
1014
  if (typeof content === "string") {
922
1015
  await fsp.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
@@ -934,8 +1027,8 @@ async function atomicWrite(targetPath, content, opts = {}) {
934
1027
  }
935
1028
  let mode;
936
1029
  try {
937
- const stat3 = await fsp.stat(targetPath);
938
- mode = stat3.mode & 511;
1030
+ const stat4 = await fsp.stat(targetPath);
1031
+ mode = stat4.mode & 511;
939
1032
  } catch {
940
1033
  mode = opts.mode;
941
1034
  }
@@ -952,9 +1045,9 @@ async function atomicWrite(targetPath, content, opts = {}) {
952
1045
  }
953
1046
  }
954
1047
  async function withFileLock(targetPath, fn, opts = {}) {
955
- const dir = path3.dirname(targetPath);
1048
+ const dir = path2.dirname(targetPath);
956
1049
  await fsp.mkdir(dir, { recursive: true });
957
- const lockPath = path3.join(dir, `.${path3.basename(targetPath)}.lock`);
1050
+ const lockPath = path2.join(dir, `.${path2.basename(targetPath)}.lock`);
958
1051
  const timeoutMs = opts.timeoutMs ?? 5e3;
959
1052
  const staleMs = opts.staleMs ?? 3e4;
960
1053
  const started = Date.now();
@@ -972,8 +1065,8 @@ async function withFileLock(targetPath, fn, opts = {}) {
972
1065
  }
973
1066
  if (code !== "EEXIST") throw err;
974
1067
  try {
975
- const stat3 = await fsp.stat(lockPath);
976
- if (Date.now() - stat3.mtimeMs > staleMs) {
1068
+ const stat4 = await fsp.stat(lockPath);
1069
+ if (Date.now() - stat4.mtimeMs > staleMs) {
977
1070
  await fsp.unlink(lockPath);
978
1071
  continue;
979
1072
  }
@@ -1022,10 +1115,62 @@ async function renameWithRetry(from, to) {
1022
1115
  }
1023
1116
  throw lastErr;
1024
1117
  }
1118
+ function projectHash(absRoot) {
1119
+ return createHash("sha256").update(path2.resolve(absRoot)).digest("hex").slice(0, 12);
1120
+ }
1121
+ function projectSlug(absRoot) {
1122
+ const base = slugify(path2.basename(absRoot));
1123
+ const hash = createHash("sha256").update(path2.resolve(absRoot)).digest("hex").slice(0, 6);
1124
+ return `${base}-${hash}`;
1125
+ }
1126
+ function slugify(name) {
1127
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40) || "project";
1128
+ }
1025
1129
  function wstackGlobalRoot() {
1026
1130
  const fromEnv = process.env["WRONGSTACK_HOME"];
1027
- if (fromEnv && fromEnv.trim().length > 0) return path3.resolve(fromEnv);
1028
- return path3.join(os.homedir(), ".wrongstack");
1131
+ if (fromEnv && fromEnv.trim().length > 0) return path2.resolve(fromEnv);
1132
+ return path2.join(os.homedir(), ".wrongstack");
1133
+ }
1134
+ function resolveWstackPaths(opts) {
1135
+ const globalRoot = opts.globalRoot ?? (opts.userHome ? path2.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
1136
+ const hash = projectHash(opts.projectRoot);
1137
+ const slug = projectSlug(opts.projectRoot);
1138
+ const projectDir = path2.join(globalRoot, "projects", slug);
1139
+ return {
1140
+ globalRoot,
1141
+ configDir: globalRoot,
1142
+ globalConfig: path2.join(globalRoot, "config.json"),
1143
+ secretsKey: path2.join(globalRoot, ".key"),
1144
+ globalMemory: path2.join(globalRoot, "memory.md"),
1145
+ globalSkills: path2.join(globalRoot, "skills"),
1146
+ globalPrompts: path2.join(globalRoot, "prompts"),
1147
+ cacheDir: path2.join(globalRoot, "cache"),
1148
+ modelsCache: path2.join(globalRoot, "cache", "models.dev.json"),
1149
+ modelsOverlayCache: path2.join(globalRoot, "cache", "models-overlay.json"),
1150
+ historyFile: path2.join(globalRoot, "history"),
1151
+ logFile: path2.join(globalRoot, "logs", "wrongstack.log"),
1152
+ projectDir,
1153
+ projectCodebaseIndex: path2.join(projectDir, "codebase-index"),
1154
+ projectMemory: path2.join(projectDir, "memory.md"),
1155
+ projectSessions: path2.join(projectDir, "sessions"),
1156
+ projectTrust: path2.join(projectDir, "trust.json"),
1157
+ projectMeta: path2.join(projectDir, "meta.json"),
1158
+ projectLocalConfig: path2.join(projectDir, "config.local.json"),
1159
+ inProjectConfig: path2.join(opts.projectRoot, ".wrongstack", "config.json"),
1160
+ inProjectAgentsFile: path2.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
1161
+ inProjectSkills: path2.join(opts.projectRoot, ".wrongstack", "skills"),
1162
+ inProjectWorktrees: path2.join(opts.projectRoot, ".wrongstack", "worktrees"),
1163
+ projectHash: hash,
1164
+ projectSlug: slug,
1165
+ projectGoal: path2.join(projectDir, "goal.json"),
1166
+ projectSpecs: path2.join(projectDir, "specs"),
1167
+ projectTaskGraphs: path2.join(projectDir, "task-graphs"),
1168
+ projectSddSession: path2.join(projectDir, "sdd-session.json"),
1169
+ projectPlan: path2.join(projectDir, "plan.json"),
1170
+ projectAutophase: path2.join(projectDir, "autophase"),
1171
+ syncConfig: path2.join(globalRoot, "sync.json"),
1172
+ projectStatus: (projectHash2) => path2.join(globalRoot, "projects", projectHash2, "status.json")
1173
+ };
1029
1174
  }
1030
1175
 
1031
1176
  // src/coordination/mailbox-types.ts
@@ -1093,14 +1238,14 @@ var GlobalMailbox = class {
1093
1238
  * @param hqPublisher — optional HQ publisher for cross-project telemetry
1094
1239
  */
1095
1240
  constructor(projectDir, events, hqPublisher) {
1096
- this.messagePath = path3.join(projectDir, MAILBOX_FILE);
1097
- this.registryPath = path3.join(projectDir, "_mailbox.registry.json");
1098
- this.clientRegistryPath = path3.join(projectDir, CLIENT_REGISTRY_FILE);
1241
+ this.messagePath = path2.join(projectDir, MAILBOX_FILE);
1242
+ this.registryPath = path2.join(projectDir, "_mailbox.registry.json");
1243
+ this.clientRegistryPath = path2.join(projectDir, CLIENT_REGISTRY_FILE);
1099
1244
  this._events = events;
1100
1245
  this._hqPublisher = hqPublisher;
1101
1246
  }
1102
1247
  get hqMailboxId() {
1103
- return `${path3.basename(path3.dirname(this.messagePath))}:mailbox`;
1248
+ return `${path2.basename(path2.dirname(this.messagePath))}:mailbox`;
1104
1249
  }
1105
1250
  publishHqMailboxEvent(input) {
1106
1251
  try {
@@ -1133,7 +1278,7 @@ var GlobalMailbox = class {
1133
1278
  taskContext: input.taskContext
1134
1279
  };
1135
1280
  const line = JSON.stringify(msg) + LINE_SEPARATOR;
1136
- await fsp.mkdir(path3.dirname(this.messagePath), { recursive: true });
1281
+ await fsp.mkdir(path2.dirname(this.messagePath), { recursive: true });
1137
1282
  await withFileLock(this.messagePath, async () => {
1138
1283
  await fsp.appendFile(this.messagePath, line, "utf8");
1139
1284
  this._pushToCache(msg);
@@ -1472,30 +1617,69 @@ var GlobalMailbox = class {
1472
1617
  async _readMessages() {
1473
1618
  try {
1474
1619
  const raw = await fsp.readFile(this.messagePath, "utf8");
1475
- const lines = raw.split(LINE_SEPARATOR).filter((l) => l.trim().length > 0);
1476
- const messages = [];
1477
- for (const line of lines) {
1478
- try {
1479
- const parsed = JSON.parse(line);
1480
- if (!parsed["readBy"]) {
1481
- const readBy = {};
1482
- if (parsed["read"] && parsed["readAt"]) {
1483
- readBy[parsed["to"]] = parsed["readAt"];
1484
- }
1485
- parsed["readBy"] = readBy;
1486
- delete parsed["read"];
1487
- delete parsed["readAt"];
1488
- }
1489
- messages.push(parsed);
1490
- } catch {
1491
- }
1492
- }
1493
- return messages;
1620
+ return this._parseLines(raw);
1494
1621
  } catch (err) {
1495
1622
  if (err.code === "ENOENT") return [];
1496
1623
  throw err;
1497
1624
  }
1498
1625
  }
1626
+ /**
1627
+ * Read only newly-appended bytes from the file and append them to the
1628
+ * in-memory cache. This avoids re-reading and re-parsing the entire file
1629
+ * when another process appended messages since our last read.
1630
+ *
1631
+ * Only safe when the file grew in size (messages are append-only). When
1632
+ * the file was rewritten (ack/purge changed existing content), callers
1633
+ * must fall back to {@link _readMessages}.
1634
+ *
1635
+ * @returns The (now up-to-date) message cache.
1636
+ */
1637
+ async _readNewMessagesOnly(fd, oldSize, newSize) {
1638
+ const tailLen = newSize - oldSize;
1639
+ const buf = Buffer.alloc(tailLen);
1640
+ await fd.read(buf, 0, tailLen, oldSize);
1641
+ const tail = buf.toString("utf8");
1642
+ for (const line of tail.split(LINE_SEPARATOR)) {
1643
+ if (!line.trim()) continue;
1644
+ try {
1645
+ const parsed = JSON.parse(line);
1646
+ if (!parsed["readBy"]) {
1647
+ const readBy = {};
1648
+ if (parsed["read"] && parsed["readAt"]) {
1649
+ readBy[parsed["to"]] = parsed["readAt"];
1650
+ }
1651
+ parsed["readBy"] = readBy;
1652
+ delete parsed["read"];
1653
+ delete parsed["readAt"];
1654
+ }
1655
+ this._messageCache.push(parsed);
1656
+ } catch {
1657
+ }
1658
+ }
1659
+ return this._messageCache;
1660
+ }
1661
+ /** Parse a JSONL string into MailboxMessage[], including migration. */
1662
+ _parseLines(raw) {
1663
+ const lines = raw.split(LINE_SEPARATOR).filter((l) => l.trim().length > 0);
1664
+ const messages = [];
1665
+ for (const line of lines) {
1666
+ try {
1667
+ const parsed = JSON.parse(line);
1668
+ if (!parsed["readBy"]) {
1669
+ const readBy = {};
1670
+ if (parsed["read"] && parsed["readAt"]) {
1671
+ readBy[parsed["to"]] = parsed["readAt"];
1672
+ }
1673
+ parsed["readBy"] = readBy;
1674
+ delete parsed["read"];
1675
+ delete parsed["readAt"];
1676
+ }
1677
+ messages.push(parsed);
1678
+ } catch {
1679
+ }
1680
+ }
1681
+ return messages;
1682
+ }
1499
1683
  /**
1500
1684
  * Read messages, then adopt the result as the in-memory cache. Use this
1501
1685
  * from writers that just took the file lock — the read reflects the
@@ -1515,6 +1699,10 @@ var GlobalMailbox = class {
1515
1699
  * stat matches the cached mtime+size we return the cached array — no
1516
1700
  * file read and no JSON.parse — collapsing the per-iteration query
1517
1701
  * cost on the mailbox-loop hot path.
1702
+ *
1703
+ * When the file only grew (new messages appended by another process),
1704
+ * we read and parse just the tail bytes instead of the entire file.
1705
+ * This avoids re-parsing the full 10K-message history on every check.
1518
1706
  */
1519
1707
  async _readMessagesCached() {
1520
1708
  try {
@@ -1522,6 +1710,17 @@ var GlobalMailbox = class {
1522
1710
  if (this._messageCache !== null && this._messageCacheMtime === st.mtimeMs && this._messageCacheSize === st.size) {
1523
1711
  return this._messageCache;
1524
1712
  }
1713
+ if (this._messageCache !== null && this._messageCacheSize >= 0 && st.size > this._messageCacheSize) {
1714
+ const fd = await fsp.open(this.messagePath, "r");
1715
+ try {
1716
+ const updated = await this._readNewMessagesOnly(fd, this._messageCacheSize, st.size);
1717
+ this._messageCacheMtime = st.mtimeMs;
1718
+ this._messageCacheSize = st.size;
1719
+ return updated;
1720
+ } finally {
1721
+ await fd.close();
1722
+ }
1723
+ }
1525
1724
  const all = await this._readMessages();
1526
1725
  this._setMessageCache(all, st.mtimeMs, st.size);
1527
1726
  return all;
@@ -1574,7 +1773,7 @@ var GlobalMailbox = class {
1574
1773
  this._messageCache.push(msg);
1575
1774
  }
1576
1775
  async _ensureRegistry() {
1577
- await fsp.mkdir(path3.dirname(this.registryPath), { recursive: true });
1776
+ await fsp.mkdir(path2.dirname(this.registryPath), { recursive: true });
1578
1777
  }
1579
1778
  async _readRegistry(opts) {
1580
1779
  if (!opts?.fresh && this._registryCache && Date.now() - this._registryCacheAt < REGISTRY_CACHE_TTL_MS) {
@@ -1619,7 +1818,7 @@ var GlobalMailbox = class {
1619
1818
  }
1620
1819
  // ── Client registry internals ───────────────────────────────────────────
1621
1820
  async _ensureClientRegistry() {
1622
- await fsp.mkdir(path3.dirname(this.clientRegistryPath), { recursive: true });
1821
+ await fsp.mkdir(path2.dirname(this.clientRegistryPath), { recursive: true });
1623
1822
  }
1624
1823
  async _readClientRegistry(opts) {
1625
1824
  if (!opts?.fresh && this._clientRegistryCache && Date.now() - this._clientRegistryCacheAt < REGISTRY_CACHE_TTL_MS) {
@@ -1665,12 +1864,12 @@ var GlobalMailbox = class {
1665
1864
  };
1666
1865
  var HQ_AUTH_FILE_VERSION = 1;
1667
1866
  function defaultHqDataDir() {
1668
- return path3.join(wstackGlobalRoot(), "hq");
1867
+ return path2.join(wstackGlobalRoot(), "hq");
1669
1868
  }
1670
1869
  function resolveHqDataDir(override, env = process.env) {
1671
1870
  const raw = override ?? env["WRONGSTACK_HQ_DATA_DIR"]?.trim();
1672
1871
  if (!raw) return defaultHqDataDir();
1673
- return path3.isAbsolute(raw) ? path3.resolve(raw) : path3.resolve(process.cwd(), raw);
1872
+ return path2.isAbsolute(raw) ? path2.resolve(raw) : path2.resolve(process.cwd(), raw);
1674
1873
  }
1675
1874
  function emptyHqAuthFile() {
1676
1875
  return {
@@ -1679,10 +1878,10 @@ function emptyHqAuthFile() {
1679
1878
  };
1680
1879
  }
1681
1880
  function hqAuthFilePath(dataDir) {
1682
- return path3.join(dataDir, "auth.json");
1881
+ return path2.join(dataDir, "auth.json");
1683
1882
  }
1684
1883
  function hqRuntimeFilePath(dataDir) {
1685
- return path3.join(dataDir, "runtime.json");
1884
+ return path2.join(dataDir, "runtime.json");
1686
1885
  }
1687
1886
  async function writeHqRuntimeFile(dataDir, file) {
1688
1887
  const payload = {
@@ -1794,7 +1993,7 @@ function watchHqAuthFile(dataDir, onChange, opts = {}) {
1794
1993
  let closed = false;
1795
1994
  let watcher;
1796
1995
  try {
1797
- watcher = syncFs.watch(path3.dirname(file), { recursive: false });
1996
+ watcher = syncFs.watch(path2.dirname(file), { recursive: false });
1798
1997
  } catch (err) {
1799
1998
  opts.warn?.(`HQ auth watcher could not start: ${err.message}`);
1800
1999
  return { close: () => {
@@ -1818,7 +2017,7 @@ function watchHqAuthFile(dataDir, onChange, opts = {}) {
1818
2017
  watcher.on("change", (eventType, filename) => {
1819
2018
  const name = typeof filename === "string" ? filename : "";
1820
2019
  if (eventType === "rename" || eventType === "change") {
1821
- if (!name || name === "auth.json" || name === path3.basename(file)) {
2020
+ if (!name || name === "auth.json" || name === path2.basename(file)) {
1822
2021
  trigger();
1823
2022
  }
1824
2023
  }
@@ -1883,7 +2082,7 @@ function resolveHqConfig(options = {}) {
1883
2082
  };
1884
2083
  }
1885
2084
  function stableMachineId() {
1886
- return createHash("sha256").update(`${hostname()}:${process.pid}`).digest("hex").slice(0, 12);
2085
+ return createHash("sha256").update(hostname()).digest("hex").slice(0, 12);
1887
2086
  }
1888
2087
  function deriveProjectId(projectRoot) {
1889
2088
  return createHash("sha256").update(projectRoot).digest("hex").slice(0, 12);
@@ -1926,6 +2125,377 @@ function createGlobalMailbox(options) {
1926
2125
  return new GlobalMailbox(options.projectDir, options.events, options.hqPublisher);
1927
2126
  }
1928
2127
 
1929
- export { DEFAULT_HQ_REDACTION_POLICY, HQ_AUTH_FILE_VERSION, HQ_PROTOCOL_VERSION, HqPublisher, createGlobalMailbox, createHqEventEnvelope, createHqPublisherFromEnv, createMailboxEventPayload, createMailboxSnapshotPayload, createMailboxSnapshotPayloadFromMailbox, defaultHqDataDir, emptyHqAuthFile, ensureHqFirstRunAuthFile, hqAuthFilePath, hqRuntimeFilePath, mapMailboxAgentToHqSummary, mapMailboxMessageToHqSummary, mintHqBrowserToken, mintHqToken, mutateHqAuthFile, parseHqEventPayload, parseHqFrame, readHqAuthFile, readHqRuntimeFileSync, redactHqEvent, redactHqValue, resolveHqConfig, resolveHqConfigFromEnv, resolveHqDataDir, scrubAndTruncateHqPreview, summarizeHqToolArgs, watchHqAuthFile, writeHqAuthFile, writeHqRuntimeFile };
2128
+ // src/hq/agent-bridge.ts
2129
+ function startAgentMonitorEventBridge(opts) {
2130
+ const { events, clientId, projectId, publish } = opts;
2131
+ const seq = { current: 0 };
2132
+ function nextSeq() {
2133
+ seq.current += 1;
2134
+ return seq.current;
2135
+ }
2136
+ function buildEnvelope(type, payload) {
2137
+ return createHqEventEnvelope({
2138
+ id: `${Date.now().toString(36)}-${nextSeq()}`,
2139
+ type,
2140
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2141
+ clientId,
2142
+ projectId,
2143
+ seq: nextSeq(),
2144
+ payload
2145
+ });
2146
+ }
2147
+ const offMessage = events.on("agent.timeline.message", (payload) => {
2148
+ if (!publish) return;
2149
+ const msgPayload = {
2150
+ subagentId: payload.subagentId,
2151
+ agentName: payload.agentName,
2152
+ content: payload.content,
2153
+ kind: payload.kind,
2154
+ iteration: payload.iteration,
2155
+ ts: payload.ts
2156
+ };
2157
+ if (payload.toolName !== void 0) msgPayload.toolName = payload.toolName;
2158
+ if (payload.costUsd !== void 0) msgPayload.costUsd = payload.costUsd;
2159
+ publish(buildEnvelope("agent.message", msgPayload));
2160
+ });
2161
+ const offStatus = events.on("agent.status_changed", (payload) => {
2162
+ if (!publish) return;
2163
+ const statusPayload = {
2164
+ subagentId: payload.subagentId,
2165
+ agentName: payload.agentName,
2166
+ status: payload.status,
2167
+ ts: payload.ts
2168
+ };
2169
+ if (payload.summary !== void 0) statusPayload.summary = payload.summary;
2170
+ if (payload.task !== void 0) statusPayload.task = payload.task;
2171
+ publish(buildEnvelope("agent.status", statusPayload));
2172
+ });
2173
+ return () => {
2174
+ offMessage();
2175
+ offStatus();
2176
+ };
2177
+ }
2178
+
2179
+ // src/hq/transcript-mapper.ts
2180
+ function blocksToText(content) {
2181
+ if (typeof content === "string") return content;
2182
+ if (Array.isArray(content)) {
2183
+ return content.filter(
2184
+ (b) => !!b && typeof b === "object" && b.type === "text" && typeof b.text === "string"
2185
+ ).map((b) => b.text).join("\n");
2186
+ }
2187
+ return "";
2188
+ }
2189
+ function asString(v) {
2190
+ if (typeof v === "string") return v;
2191
+ try {
2192
+ return JSON.stringify(v, null, 2);
2193
+ } catch {
2194
+ return String(v);
2195
+ }
2196
+ }
2197
+ function argsEntry(ts, name, input, id) {
2198
+ return {
2199
+ ts,
2200
+ role: "tool",
2201
+ tool: String(name ?? "tool"),
2202
+ toolInput: input !== void 0 && input !== null ? asString(input) : "{}",
2203
+ text: "",
2204
+ ...typeof id === "string" ? { toolUseId: id } : {}
2205
+ };
2206
+ }
2207
+ function mapSessionEventToEntries(ev) {
2208
+ const ts = typeof ev["ts"] === "string" ? ev["ts"] : "";
2209
+ const make = (role, text, extra) => ({
2210
+ ts,
2211
+ role,
2212
+ text,
2213
+ ...extra
2214
+ });
2215
+ switch (ev["type"]) {
2216
+ case "user_input": {
2217
+ const t = blocksToText(ev["content"]);
2218
+ return t.trim() ? [make("user", t)] : [];
2219
+ }
2220
+ case "llm_response": {
2221
+ const out = [];
2222
+ const t = blocksToText(ev["content"]);
2223
+ if (t.trim()) out.push(make("assistant", t));
2224
+ const content = ev["content"];
2225
+ if (Array.isArray(content)) {
2226
+ for (const b of content) {
2227
+ if (b && typeof b === "object" && b.type === "tool_use") {
2228
+ const block = b;
2229
+ out.push(argsEntry(ts, block.name, block.input, block.id));
2230
+ }
2231
+ }
2232
+ }
2233
+ return out;
2234
+ }
2235
+ case "tool_use":
2236
+ return [argsEntry(ts, ev["name"], ev["input"], ev["id"])];
2237
+ case "tool_call_start":
2238
+ return [argsEntry(ts, ev["name"], ev["input"] ?? ev["args"], ev["id"])];
2239
+ case "tool_result": {
2240
+ const isError = ev["isError"] === true;
2241
+ const content = ev["content"] ?? ev["output"];
2242
+ const outStr = content !== void 0 && content !== null ? asString(content) : "";
2243
+ return [
2244
+ make(isError ? "error" : "tool", outStr, {
2245
+ tool: "\u21B3 result",
2246
+ ...isError ? { isError: true } : {},
2247
+ ...typeof ev["id"] === "string" ? { toolUseId: ev["id"] } : {}
2248
+ })
2249
+ ];
2250
+ }
2251
+ case "tool_call_end": {
2252
+ const isError = ev["isError"] === true;
2253
+ const content = ev["output"] ?? ev["content"];
2254
+ const outStr = content !== void 0 && content !== null ? asString(content) : "";
2255
+ if (!outStr.trim() && !isError && typeof ev["durationMs"] !== "number") return [];
2256
+ return [
2257
+ make(isError ? "error" : "tool", outStr, {
2258
+ tool: typeof ev["name"] === "string" ? String(ev["name"]) : "\u21B3 result",
2259
+ ...typeof ev["durationMs"] === "number" ? { durationMs: ev["durationMs"] } : {},
2260
+ ...isError ? { isError: true } : {},
2261
+ ...typeof ev["id"] === "string" ? { toolUseId: ev["id"] } : {}
2262
+ })
2263
+ ];
2264
+ }
2265
+ case "error":
2266
+ case "provider_error":
2267
+ return [make("error", String(ev["message"] ?? "error"))];
2268
+ case "agent_spawned":
2269
+ return [make("system", `spawned ${String(ev["role"] ?? "agent")}`)];
2270
+ case "task_completed":
2271
+ return [make("system", `task done: ${String(ev["title"] ?? "")}`)];
2272
+ case "task_failed":
2273
+ return [make("system", `task failed: ${String(ev["title"] ?? "")}`)];
2274
+ default:
2275
+ return [];
2276
+ }
2277
+ }
2278
+ function isResultEntry(e) {
2279
+ return (e.role === "tool" || e.role === "error") && e.toolUseId !== void 0 && e.toolInput === void 0;
2280
+ }
2281
+ function mergeToolResults(flat) {
2282
+ const out = [];
2283
+ const argsById = /* @__PURE__ */ new Map();
2284
+ for (const src of flat) {
2285
+ const e = { ...src };
2286
+ if (isResultEntry(e) && e.toolUseId !== void 0) {
2287
+ const tgt = argsById.get(e.toolUseId);
2288
+ if (tgt) {
2289
+ tgt.text = e.text || "";
2290
+ if (e.durationMs !== void 0) tgt.durationMs = e.durationMs;
2291
+ if (e.isError) {
2292
+ tgt.role = "error";
2293
+ tgt.isError = true;
2294
+ }
2295
+ continue;
2296
+ }
2297
+ }
2298
+ out.push(e);
2299
+ if (e.role === "tool" && e.toolUseId !== void 0 && e.toolInput !== void 0) {
2300
+ argsById.set(e.toolUseId, e);
2301
+ }
2302
+ }
2303
+ return out;
2304
+ }
2305
+ function buildTranscriptFromEvents(events) {
2306
+ const flat = [];
2307
+ for (const ev of events) {
2308
+ for (const e of mapSessionEventToEntries(ev)) flat.push(e);
2309
+ }
2310
+ return mergeToolResults(flat);
2311
+ }
2312
+
2313
+ // src/hq/session-bridge.ts
2314
+ var VALID_AGENT_STATUS = /* @__PURE__ */ new Set([
2315
+ "idle",
2316
+ "running",
2317
+ "streaming",
2318
+ "waiting_user",
2319
+ "error"
2320
+ ]);
2321
+ function toAgentSummary(a) {
2322
+ const status = VALID_AGENT_STATUS.has(a.status) ? a.status : "idle";
2323
+ return {
2324
+ id: a.id,
2325
+ name: a.name,
2326
+ status,
2327
+ iterations: a.iterations,
2328
+ toolCalls: a.toolCalls,
2329
+ lastActivityAt: a.lastActivityAt,
2330
+ ...a.currentTool !== void 0 ? { currentTool: a.currentTool } : {},
2331
+ ...a.costUsd !== void 0 ? { costUsd: a.costUsd } : {},
2332
+ ...a.tokensIn !== void 0 ? { tokensIn: a.tokensIn } : {},
2333
+ ...a.tokensOut !== void 0 ? { tokensOut: a.tokensOut } : {},
2334
+ ...a.ctxPct !== void 0 ? { ctxPct: a.ctxPct } : {},
2335
+ ...a.model !== void 0 ? { model: a.model } : {},
2336
+ ...a.partialText !== void 0 ? { partialText: a.partialText } : {}
2337
+ };
2338
+ }
2339
+ function deriveSessionStatus(agents) {
2340
+ return agents.some(
2341
+ (a) => a.status === "running" || a.status === "streaming" || a.status === "waiting_user"
2342
+ ) ? "active" : "idle";
2343
+ }
2344
+ function startSessionTelemetryBridge(opts) {
2345
+ const now = opts.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
2346
+ const publisher = opts.publisher;
2347
+ const identity = publisher.identity;
2348
+ const project = publisher.project;
2349
+ const startedAt = opts.startedAt ?? now();
2350
+ const wpaths = resolveWstackPaths({
2351
+ projectRoot: opts.projectRoot,
2352
+ ...opts.globalRoot !== void 0 ? { globalRoot: opts.globalRoot } : {}
2353
+ });
2354
+ const sessionFile = path2.join(wpaths.projectSessions, `${opts.sessionId}.jsonl`);
2355
+ let agents = [];
2356
+ let lastActivityAt = startedAt;
2357
+ let lastSnapshotHash = "";
2358
+ let disposed = false;
2359
+ function buildSnapshot() {
2360
+ return {
2361
+ sessionId: opts.sessionId,
2362
+ clientKind: identity.kind,
2363
+ machineId: identity.machineId,
2364
+ projectId: project.projectId,
2365
+ projectName: opts.projectName ?? project.projectName,
2366
+ projectRoot: opts.projectRoot,
2367
+ status: deriveSessionStatus(agents),
2368
+ startedAt,
2369
+ lastActivityAt,
2370
+ agentCount: agents.length,
2371
+ agents,
2372
+ ...identity.hostname !== void 0 ? { hostname: identity.hostname } : {},
2373
+ ...identity.pid !== void 0 ? { pid: identity.pid } : {},
2374
+ ...opts.gitBranch !== void 0 ? { gitBranch: opts.gitBranch } : {}
2375
+ };
2376
+ }
2377
+ function publishSnapshot(force = false) {
2378
+ if (disposed) return;
2379
+ const snap = buildSnapshot();
2380
+ const hash = JSON.stringify({ ...snap, lastActivityAt: "" });
2381
+ if (!force && hash === lastSnapshotHash) return;
2382
+ lastSnapshotHash = hash;
2383
+ try {
2384
+ publisher.publishSessionSnapshot(snap);
2385
+ } catch {
2386
+ }
2387
+ }
2388
+ const offAgents = opts.events?.on("session.agents_updated", (payload) => {
2389
+ agents = payload.agents.map(toAgentSummary);
2390
+ lastActivityAt = now();
2391
+ publishSnapshot();
2392
+ });
2393
+ publishSnapshot(true);
2394
+ let offset = 0;
2395
+ let partial = "";
2396
+ let seqEmitted = 0;
2397
+ let tailing = false;
2398
+ let watcher = null;
2399
+ let watchPending = false;
2400
+ function setupWatcher() {
2401
+ if (disposed || watcher) return;
2402
+ try {
2403
+ const nextWatcher = syncFs.watch(sessionFile, () => {
2404
+ if (watchPending || disposed) return;
2405
+ watchPending = true;
2406
+ setTimeout(() => {
2407
+ watchPending = false;
2408
+ void tail();
2409
+ }, 25);
2410
+ });
2411
+ nextWatcher.on("error", () => {
2412
+ try {
2413
+ nextWatcher.close();
2414
+ } catch {
2415
+ }
2416
+ if (watcher === nextWatcher) watcher = null;
2417
+ });
2418
+ watcher = nextWatcher;
2419
+ } catch {
2420
+ watcher = null;
2421
+ }
2422
+ }
2423
+ async function tail() {
2424
+ if (disposed || tailing) return;
2425
+ tailing = true;
2426
+ try {
2427
+ const stat4 = await fsp.stat(sessionFile).catch(() => null);
2428
+ if (disposed) return;
2429
+ if (!stat4) return;
2430
+ setupWatcher();
2431
+ if (stat4.size <= offset) return;
2432
+ const fd = await fsp.open(sessionFile, "r");
2433
+ try {
2434
+ if (disposed) return;
2435
+ const len = stat4.size - offset;
2436
+ const buf = Buffer.allocUnsafe(len);
2437
+ await fd.read(buf, 0, len, offset);
2438
+ offset = stat4.size;
2439
+ partial += buf.toString("utf8");
2440
+ const lines = partial.split("\n");
2441
+ partial = lines.pop() ?? "";
2442
+ const entries = [];
2443
+ for (const line of lines) {
2444
+ const trimmed = line.trim();
2445
+ if (!trimmed) continue;
2446
+ let obj;
2447
+ try {
2448
+ obj = JSON.parse(trimmed);
2449
+ } catch {
2450
+ continue;
2451
+ }
2452
+ for (const entry of mapSessionEventToEntries(obj)) entries.push(entry);
2453
+ }
2454
+ if (entries.length > 0) {
2455
+ try {
2456
+ publisher.publishTranscriptAppend({
2457
+ sessionId: opts.sessionId,
2458
+ fromSeq: seqEmitted,
2459
+ entries
2460
+ });
2461
+ } catch {
2462
+ }
2463
+ seqEmitted += entries.length;
2464
+ lastActivityAt = now();
2465
+ }
2466
+ } finally {
2467
+ await fd.close();
2468
+ }
2469
+ } catch {
2470
+ } finally {
2471
+ tailing = false;
2472
+ }
2473
+ }
2474
+ const snapshotTimer = setInterval(() => publishSnapshot(true), opts.snapshotIntervalMs ?? 2500);
2475
+ const tailTimer = setInterval(() => void tail(), opts.transcriptIntervalMs ?? 500);
2476
+ snapshotTimer.unref?.();
2477
+ tailTimer.unref?.();
2478
+ void tail();
2479
+ return () => {
2480
+ if (disposed) return;
2481
+ disposed = true;
2482
+ offAgents?.();
2483
+ if (watcher) {
2484
+ try {
2485
+ watcher.close();
2486
+ } catch {
2487
+ }
2488
+ watcher = null;
2489
+ }
2490
+ clearInterval(snapshotTimer);
2491
+ clearInterval(tailTimer);
2492
+ try {
2493
+ publisher.publishSessionEnded({ sessionId: opts.sessionId, endedAt: now() });
2494
+ } catch {
2495
+ }
2496
+ };
2497
+ }
2498
+
2499
+ export { DEFAULT_HQ_REDACTION_POLICY, HQ_AUTH_FILE_VERSION, HQ_PROTOCOL_VERSION, HqPublisher, buildTranscriptFromEvents, createGlobalMailbox, createHqEventEnvelope, createHqPublisherFromEnv, createMailboxEventPayload, createMailboxSnapshotPayload, createMailboxSnapshotPayloadFromMailbox, defaultHqDataDir, emptyHqAuthFile, ensureHqFirstRunAuthFile, hqAuthFilePath, hqRuntimeFilePath, mapMailboxAgentToHqSummary, mapMailboxMessageToHqSummary, mapSessionEventToEntries, mergeToolResults, mintHqBrowserToken, mintHqToken, mutateHqAuthFile, parseHqEventPayload, parseHqFrame, readHqAuthFile, readHqRuntimeFileSync, redactHqEvent, redactHqValue, resolveHqConfig, resolveHqConfigFromEnv, resolveHqDataDir, scrubAndTruncateHqPreview, startAgentMonitorEventBridge, startSessionTelemetryBridge, summarizeHqToolArgs, watchHqAuthFile, writeHqAuthFile, writeHqRuntimeFile };
1930
2500
  //# sourceMappingURL=index.js.map
1931
2501
  //# sourceMappingURL=index.js.map