@mclawnet/swarm 0.1.4 → 0.1.5

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 (224) hide show
  1. package/README.md +118 -0
  2. package/dist/__tests__/action-parser.test.js +29 -82
  3. package/dist/__tests__/action-parser.test.js.map +1 -1
  4. package/dist/__tests__/coordinator-create-tx.test.d.ts +2 -0
  5. package/dist/__tests__/coordinator-create-tx.test.d.ts.map +1 -0
  6. package/dist/__tests__/coordinator-create-tx.test.js +114 -0
  7. package/dist/__tests__/coordinator-create-tx.test.js.map +1 -0
  8. package/dist/__tests__/coordinator-inbox-migration.test.d.ts +2 -0
  9. package/dist/__tests__/coordinator-inbox-migration.test.d.ts.map +1 -0
  10. package/dist/__tests__/coordinator-inbox-migration.test.js +56 -0
  11. package/dist/__tests__/coordinator-inbox-migration.test.js.map +1 -0
  12. package/dist/__tests__/inbox-integration.test.d.ts +2 -0
  13. package/dist/__tests__/inbox-integration.test.d.ts.map +1 -0
  14. package/dist/__tests__/inbox-integration.test.js +120 -0
  15. package/dist/__tests__/inbox-integration.test.js.map +1 -0
  16. package/dist/__tests__/inbox-persistence-recovery.test.d.ts +2 -0
  17. package/dist/__tests__/inbox-persistence-recovery.test.d.ts.map +1 -0
  18. package/dist/__tests__/inbox-persistence-recovery.test.js +139 -0
  19. package/dist/__tests__/inbox-persistence-recovery.test.js.map +1 -0
  20. package/dist/__tests__/inbox-relay-interceptor.test.d.ts +2 -0
  21. package/dist/__tests__/inbox-relay-interceptor.test.d.ts.map +1 -0
  22. package/dist/__tests__/inbox-relay-interceptor.test.js +156 -0
  23. package/dist/__tests__/inbox-relay-interceptor.test.js.map +1 -0
  24. package/dist/__tests__/inbox-relay.test.d.ts +2 -0
  25. package/dist/__tests__/inbox-relay.test.d.ts.map +1 -0
  26. package/dist/__tests__/inbox-relay.test.js +318 -0
  27. package/dist/__tests__/inbox-relay.test.js.map +1 -0
  28. package/dist/__tests__/inbox-store.test.d.ts +2 -0
  29. package/dist/__tests__/inbox-store.test.d.ts.map +1 -0
  30. package/dist/__tests__/inbox-store.test.js +129 -0
  31. package/dist/__tests__/inbox-store.test.js.map +1 -0
  32. package/dist/__tests__/inbox-watcher.test.d.ts +2 -0
  33. package/dist/__tests__/inbox-watcher.test.d.ts.map +1 -0
  34. package/dist/__tests__/inbox-watcher.test.js +104 -0
  35. package/dist/__tests__/inbox-watcher.test.js.map +1 -0
  36. package/dist/__tests__/persistence-path.test.d.ts +2 -0
  37. package/dist/__tests__/persistence-path.test.d.ts.map +1 -0
  38. package/dist/__tests__/persistence-path.test.js +79 -0
  39. package/dist/__tests__/persistence-path.test.js.map +1 -0
  40. package/dist/__tests__/persistence-robust.test.d.ts +2 -0
  41. package/dist/__tests__/persistence-robust.test.d.ts.map +1 -0
  42. package/dist/__tests__/persistence-robust.test.js +125 -0
  43. package/dist/__tests__/persistence-robust.test.js.map +1 -0
  44. package/dist/__tests__/persistence.test.d.ts +2 -0
  45. package/dist/__tests__/persistence.test.d.ts.map +1 -0
  46. package/dist/__tests__/persistence.test.js +105 -0
  47. package/dist/__tests__/persistence.test.js.map +1 -0
  48. package/dist/__tests__/phase4-5-e2e.test.d.ts +2 -0
  49. package/dist/__tests__/phase4-5-e2e.test.d.ts.map +1 -0
  50. package/dist/__tests__/phase4-5-e2e.test.js +203 -0
  51. package/dist/__tests__/phase4-5-e2e.test.js.map +1 -0
  52. package/dist/__tests__/phase6-7-e2e.test.d.ts +2 -0
  53. package/dist/__tests__/phase6-7-e2e.test.d.ts.map +1 -0
  54. package/dist/__tests__/phase6-7-e2e.test.js +93 -0
  55. package/dist/__tests__/phase6-7-e2e.test.js.map +1 -0
  56. package/dist/__tests__/recovery-cross-project.test.d.ts +2 -0
  57. package/dist/__tests__/recovery-cross-project.test.d.ts.map +1 -0
  58. package/dist/__tests__/recovery-cross-project.test.js +87 -0
  59. package/dist/__tests__/recovery-cross-project.test.js.map +1 -0
  60. package/dist/__tests__/recovery-forwards-to-coordinator.test.d.ts +2 -0
  61. package/dist/__tests__/recovery-forwards-to-coordinator.test.d.ts.map +1 -0
  62. package/dist/__tests__/recovery-forwards-to-coordinator.test.js +59 -0
  63. package/dist/__tests__/recovery-forwards-to-coordinator.test.js.map +1 -0
  64. package/dist/__tests__/recovery-resume.test.d.ts +2 -0
  65. package/dist/__tests__/recovery-resume.test.d.ts.map +1 -0
  66. package/dist/__tests__/recovery-resume.test.js +132 -0
  67. package/dist/__tests__/recovery-resume.test.js.map +1 -0
  68. package/dist/__tests__/retrospective.test.js +1 -0
  69. package/dist/__tests__/retrospective.test.js.map +1 -1
  70. package/dist/__tests__/role-loader-preamble-all.test.d.ts +2 -0
  71. package/dist/__tests__/role-loader-preamble-all.test.d.ts.map +1 -0
  72. package/dist/__tests__/role-loader-preamble-all.test.js +38 -0
  73. package/dist/__tests__/role-loader-preamble-all.test.js.map +1 -0
  74. package/dist/__tests__/role-loader-tools.test.d.ts +2 -0
  75. package/dist/__tests__/role-loader-tools.test.d.ts.map +1 -0
  76. package/dist/__tests__/role-loader-tools.test.js +39 -0
  77. package/dist/__tests__/role-loader-tools.test.js.map +1 -0
  78. package/dist/__tests__/role-loader.test.js +116 -1
  79. package/dist/__tests__/role-loader.test.js.map +1 -1
  80. package/dist/__tests__/role-prompt-no-legacy-protocol.test.d.ts +2 -0
  81. package/dist/__tests__/role-prompt-no-legacy-protocol.test.d.ts.map +1 -0
  82. package/dist/__tests__/role-prompt-no-legacy-protocol.test.js +37 -0
  83. package/dist/__tests__/role-prompt-no-legacy-protocol.test.js.map +1 -0
  84. package/dist/__tests__/role-tools.test.d.ts +2 -0
  85. package/dist/__tests__/role-tools.test.d.ts.map +1 -0
  86. package/dist/__tests__/role-tools.test.js +80 -0
  87. package/dist/__tests__/role-tools.test.js.map +1 -0
  88. package/dist/__tests__/spawn-role-injects-briefings.test.d.ts +2 -0
  89. package/dist/__tests__/spawn-role-injects-briefings.test.d.ts.map +1 -0
  90. package/dist/__tests__/spawn-role-injects-briefings.test.js +182 -0
  91. package/dist/__tests__/spawn-role-injects-briefings.test.js.map +1 -0
  92. package/dist/__tests__/spawn-role-tool-policy.test.d.ts +2 -0
  93. package/dist/__tests__/spawn-role-tool-policy.test.d.ts.map +1 -0
  94. package/dist/__tests__/spawn-role-tool-policy.test.js +96 -0
  95. package/dist/__tests__/spawn-role-tool-policy.test.js.map +1 -0
  96. package/dist/__tests__/swarm-coordinator-inbox-watcher.test.d.ts +2 -0
  97. package/dist/__tests__/swarm-coordinator-inbox-watcher.test.d.ts.map +1 -0
  98. package/dist/__tests__/swarm-coordinator-inbox-watcher.test.js +61 -0
  99. package/dist/__tests__/swarm-coordinator-inbox-watcher.test.js.map +1 -0
  100. package/dist/__tests__/swarm-coordinator-inbox.test.d.ts +2 -0
  101. package/dist/__tests__/swarm-coordinator-inbox.test.d.ts.map +1 -0
  102. package/dist/__tests__/swarm-coordinator-inbox.test.js +182 -0
  103. package/dist/__tests__/swarm-coordinator-inbox.test.js.map +1 -0
  104. package/dist/__tests__/swarm-coordinator-init.test.js +36 -8
  105. package/dist/__tests__/swarm-coordinator-init.test.js.map +1 -1
  106. package/dist/__tests__/swarm-coordinator-legacy-plan-review-warn.test.d.ts +2 -0
  107. package/dist/__tests__/swarm-coordinator-legacy-plan-review-warn.test.d.ts.map +1 -0
  108. package/dist/__tests__/swarm-coordinator-legacy-plan-review-warn.test.js +113 -0
  109. package/dist/__tests__/swarm-coordinator-legacy-plan-review-warn.test.js.map +1 -0
  110. package/dist/__tests__/swarm-coordinator-plan-review-intercept.test.d.ts +2 -0
  111. package/dist/__tests__/swarm-coordinator-plan-review-intercept.test.d.ts.map +1 -0
  112. package/dist/__tests__/swarm-coordinator-plan-review-intercept.test.js +465 -0
  113. package/dist/__tests__/swarm-coordinator-plan-review-intercept.test.js.map +1 -0
  114. package/dist/__tests__/swarm-coordinator-plan-review-recovery.test.d.ts +2 -0
  115. package/dist/__tests__/swarm-coordinator-plan-review-recovery.test.d.ts.map +1 -0
  116. package/dist/__tests__/swarm-coordinator-plan-review-recovery.test.js +284 -0
  117. package/dist/__tests__/swarm-coordinator-plan-review-recovery.test.js.map +1 -0
  118. package/dist/__tests__/swarm-coordinator-plan-review.test.d.ts +2 -0
  119. package/dist/__tests__/swarm-coordinator-plan-review.test.d.ts.map +1 -0
  120. package/dist/__tests__/swarm-coordinator-plan-review.test.js +294 -0
  121. package/dist/__tests__/swarm-coordinator-plan-review.test.js.map +1 -0
  122. package/dist/__tests__/swarm-coordinator-resume.test.d.ts +2 -0
  123. package/dist/__tests__/swarm-coordinator-resume.test.d.ts.map +1 -0
  124. package/dist/__tests__/swarm-coordinator-resume.test.js +93 -0
  125. package/dist/__tests__/swarm-coordinator-resume.test.js.map +1 -0
  126. package/dist/__tests__/swarm-coordinator-roleId.test.js +2 -2
  127. package/dist/__tests__/swarm-coordinator-roleId.test.js.map +1 -1
  128. package/dist/__tests__/swarm-destroy-detach.test.d.ts +2 -0
  129. package/dist/__tests__/swarm-destroy-detach.test.d.ts.map +1 -0
  130. package/dist/__tests__/swarm-destroy-detach.test.js +135 -0
  131. package/dist/__tests__/swarm-destroy-detach.test.js.map +1 -0
  132. package/dist/action-parser.d.ts +0 -9
  133. package/dist/action-parser.d.ts.map +1 -1
  134. package/dist/action-parser.js +0 -114
  135. package/dist/action-parser.js.map +1 -1
  136. package/dist/inbox-relay.d.ts +50 -0
  137. package/dist/inbox-relay.d.ts.map +1 -0
  138. package/dist/inbox-relay.js +168 -0
  139. package/dist/inbox-relay.js.map +1 -0
  140. package/dist/inbox-store.d.ts +25 -0
  141. package/dist/inbox-store.d.ts.map +1 -0
  142. package/dist/inbox-store.js +95 -0
  143. package/dist/inbox-store.js.map +1 -0
  144. package/dist/inbox-watcher.d.ts +13 -0
  145. package/dist/inbox-watcher.d.ts.map +1 -0
  146. package/dist/inbox-watcher.js +89 -0
  147. package/dist/inbox-watcher.js.map +1 -0
  148. package/dist/index.d.ts +4 -3
  149. package/dist/index.d.ts.map +1 -1
  150. package/dist/index.js +3 -2
  151. package/dist/index.js.map +1 -1
  152. package/dist/persistence.d.ts +19 -5
  153. package/dist/persistence.d.ts.map +1 -1
  154. package/dist/persistence.js +97 -22
  155. package/dist/persistence.js.map +1 -1
  156. package/dist/recovery.d.ts +12 -0
  157. package/dist/recovery.d.ts.map +1 -1
  158. package/dist/recovery.js +14 -19
  159. package/dist/recovery.js.map +1 -1
  160. package/dist/roles/role-loader.d.ts +28 -1
  161. package/dist/roles/role-loader.d.ts.map +1 -1
  162. package/dist/roles/role-loader.js +73 -1
  163. package/dist/roles/role-loader.js.map +1 -1
  164. package/dist/roles/role-tools.d.ts +16 -0
  165. package/dist/roles/role-tools.d.ts.map +1 -0
  166. package/dist/roles/role-tools.js +25 -0
  167. package/dist/roles/role-tools.js.map +1 -0
  168. package/dist/roles/types.d.ts +4 -0
  169. package/dist/roles/types.d.ts.map +1 -1
  170. package/dist/swarm-coordinator.d.ts +176 -12
  171. package/dist/swarm-coordinator.d.ts.map +1 -1
  172. package/dist/swarm-coordinator.js +863 -370
  173. package/dist/swarm-coordinator.js.map +1 -1
  174. package/dist/types.d.ts +26 -0
  175. package/dist/types.d.ts.map +1 -1
  176. package/package.json +9 -6
  177. package/roles/analyst-livermore.md +6 -30
  178. package/roles/designer-rams.md +2 -30
  179. package/roles/dev-torvalds.md +8 -44
  180. package/roles/developer.md +5 -21
  181. package/roles/director-jia.md +20 -49
  182. package/roles/editor-boyong.md +8 -40
  183. package/roles/macro-dalio.md +6 -30
  184. package/roles/planner-maoni.md +24 -53
  185. package/roles/pm-jobs.md +20 -71
  186. package/roles/preset-analyst-simons.md +2 -18
  187. package/roles/preset-architect-knuth.md +2 -18
  188. package/roles/preset-designer-norman.md +2 -18
  189. package/roles/preset-designer.md +2 -18
  190. package/roles/preset-dev-carmack.md +2 -18
  191. package/roles/preset-dev-gosling.md +2 -18
  192. package/roles/preset-developer.md +7 -23
  193. package/roles/preset-manager-grove.md +2 -18
  194. package/roles/preset-manager-musk.md +2 -18
  195. package/roles/preset-pm.md +7 -34
  196. package/roles/preset-researcher-feynman.md +2 -18
  197. package/roles/preset-reviewer.md +5 -21
  198. package/roles/preset-strategist-buffett.md +2 -18
  199. package/roles/preset-strategist-munger.md +2 -18
  200. package/roles/preset-strategist-sunzi.md +2 -18
  201. package/roles/preset-tester-beck.md +2 -18
  202. package/roles/preset-tester.md +5 -21
  203. package/roles/preset-writer-orwell.md +2 -18
  204. package/roles/preset-writer.md +2 -18
  205. package/roles/quant-simons.md +5 -32
  206. package/roles/queen.md +25 -41
  207. package/roles/reviewer-martin.md +11 -37
  208. package/roles/reviewer.md +20 -21
  209. package/roles/rhythm-tangsan.md +5 -29
  210. package/roles/risk-taleb.md +4 -32
  211. package/roles/script-shitiesheng.md +8 -31
  212. package/roles/storyboard-xuke.md +9 -29
  213. package/roles/strategist-soros.md +16 -73
  214. package/roles/tester-beck.md +4 -40
  215. package/roles/tester.md +5 -21
  216. package/roles/trader-jones.md +4 -32
  217. package/roles/vfx-guchangwei.md +8 -27
  218. package/roles/writer-zhouzi.md +7 -39
  219. package/templates/dev-team-pro.md +4 -1
  220. package/templates/dev-team.md +3 -1
  221. package/templates/minimal.md +2 -1
  222. package/templates/trading-team.md +6 -1
  223. package/templates/video-team.md +4 -1
  224. package/templates/writing-team.md +4 -1
@@ -0,0 +1,168 @@
1
+ import { InboxStore } from "./inbox-store.js";
2
+ import { createLogger } from "@mclawnet/logger";
3
+ const log = createLogger({ module: "swarm/inbox-relay" });
4
+ /**
5
+ * Escape a string for safe inclusion as an XML/HTML attribute value
6
+ * (between double quotes). Order matters: `&` must be replaced first.
7
+ */
8
+ function escapeXmlAttr(s) {
9
+ return s
10
+ .replace(/&/g, "&")
11
+ .replace(/</g, "&lt;")
12
+ .replace(/>/g, "&gt;")
13
+ .replace(/"/g, "&quot;");
14
+ }
15
+ /**
16
+ * Escape body text so embedded `</message>` / `</info_for_agent>` cannot
17
+ * close the wrapping envelope. Only `<` and `&` need escaping for that.
18
+ */
19
+ function escapeXmlText(s) {
20
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;");
21
+ }
22
+ /**
23
+ * Wrap a batch of inbox messages into a single <info_for_agent> envelope.
24
+ * Host→agent direction; message body is free-form text per design §6.
25
+ */
26
+ function wrapAgentBlock(msgs) {
27
+ const body = msgs
28
+ .map((m) => {
29
+ const taskAttr = m.taskId ? ` taskId="${escapeXmlAttr(m.taskId)}"` : "";
30
+ return `<message from="${escapeXmlAttr(m.from)}" type="${escapeXmlAttr(m.type)}"${taskAttr} id="${escapeXmlAttr(m.id)}">\n${escapeXmlText(m.data)}\n</message>`;
31
+ })
32
+ .join("\n");
33
+ return `\n<info_for_agent>\n${body}\n</info_for_agent>\n`;
34
+ }
35
+ /**
36
+ * InboxRelay: pushes inbox messages to the target agent.
37
+ *
38
+ * Task 7: 4 gates implemented in runDeliver (liveness, lifecycle, single-flight,
39
+ * pending-echo). Single-flight gate sits in deliver(); the other three live
40
+ * inside runDeliver().
41
+ *
42
+ * Task 8 will fill in onAgentTurnSettled() to flush pendingEchoes and
43
+ * markDelivered() in the InboxStore.
44
+ */
45
+ export class InboxRelay {
46
+ sessionAdapter;
47
+ getSwarm;
48
+ messageInterceptor;
49
+ home;
50
+ inFlight = new Map();
51
+ // key → set of messageIds already pushed but awaiting turn-settled ack.
52
+ pendingEchoes = new Map();
53
+ constructor(sessionAdapter, getSwarm, messageInterceptor,
54
+ // Optional override for the user-home root (no `.clawnet` suffix).
55
+ // Threaded down to InboxStore so tests pinned to a tmpdir don't fall
56
+ // through to `homedir()` and write inbox files into the real `~/.clawnet`.
57
+ home) {
58
+ this.sessionAdapter = sessionAdapter;
59
+ this.getSwarm = getSwarm;
60
+ this.messageInterceptor = messageInterceptor;
61
+ this.home = home;
62
+ }
63
+ key(swarmId, instanceId) {
64
+ return `${swarmId}::${instanceId}`;
65
+ }
66
+ async deliver(swarmId, instanceId) {
67
+ const k = this.key(swarmId, instanceId);
68
+ const cur = this.inFlight.get(k);
69
+ if (cur)
70
+ return cur;
71
+ const p = this.runDeliver(swarmId, instanceId).finally(() => {
72
+ this.inFlight.delete(k);
73
+ });
74
+ this.inFlight.set(k, p);
75
+ return p;
76
+ }
77
+ async runDeliver(swarmId, instanceId) {
78
+ // Gate 1: liveness — swarm and role must exist with a workDir.
79
+ const swarm = this.getSwarm(swarmId);
80
+ if (!swarm || !swarm.workDir)
81
+ return;
82
+ const role = swarm.roles.get(instanceId);
83
+ if (!role)
84
+ return;
85
+ // Gate 2: lifecycle — skip agents that are still spawning or already stopped.
86
+ if (role.status === "spawning" || role.status === "stopped")
87
+ return;
88
+ // Read undelivered inbox.
89
+ const store = new InboxStore(swarm.workDir, swarmId, this.home);
90
+ const undelivered = await store.readUndelivered(instanceId);
91
+ if (undelivered.length === 0)
92
+ return;
93
+ // Interceptor pass — give the coordinator a chance to consume system
94
+ // envelopes (plan_review_result etc.) before they reach the LLM. A
95
+ // consumed message is filtered out of the LLM payload AND marked
96
+ // delivered so it does not re-fire on subsequent passes. Throwing
97
+ // interceptors are demoted to no-ops (fail open: message still flows).
98
+ const consumedIds = [];
99
+ const survived = [];
100
+ for (const m of undelivered) {
101
+ let consumed = false;
102
+ if (this.messageInterceptor) {
103
+ try {
104
+ consumed = await this.messageInterceptor(swarmId, instanceId, m);
105
+ }
106
+ catch (err) {
107
+ log.warn({ err, swarmId, instanceId, msgId: m.id, msgType: m.type }, "messageInterceptor threw — falling back to default delivery");
108
+ consumed = false;
109
+ }
110
+ }
111
+ if (consumed)
112
+ consumedIds.push(m.id);
113
+ else
114
+ survived.push(m);
115
+ }
116
+ // Persist consumption so consumed messages don't re-fire next pass.
117
+ if (consumedIds.length > 0) {
118
+ try {
119
+ await store.markDelivered(instanceId, consumedIds);
120
+ }
121
+ catch (err) {
122
+ log.warn({ err, swarmId, instanceId, count: consumedIds.length }, "markDelivered for consumed messages failed (best-effort)");
123
+ }
124
+ }
125
+ if (survived.length === 0)
126
+ return;
127
+ // Gate 3: pending-echo — drop messages already pushed but not yet ack'd.
128
+ const k = this.key(swarmId, instanceId);
129
+ const pending = this.pendingEchoes.get(k) ?? new Set();
130
+ const toPush = survived.filter((m) => !pending.has(m.id));
131
+ if (toPush.length === 0)
132
+ return;
133
+ // Push as a single <info_for_agent> envelope.
134
+ const payload = wrapAgentBlock(toPush);
135
+ this.sessionAdapter.sendInput(role.roleSessionId, payload);
136
+ for (const m of toPush)
137
+ pending.add(m.id);
138
+ this.pendingEchoes.set(k, pending);
139
+ }
140
+ /**
141
+ * Called when the host receives a `result` event signalling the agent
142
+ * finished a turn. Marks all messages currently in pendingEchoes as
143
+ * `delivered=true` in the InboxStore, clears the pending set, then triggers
144
+ * another deliver pass to flush any messages that arrived during the turn.
145
+ *
146
+ * Order: delete-before-mark — protects against (a) the next runDeliver
147
+ * stealing entries from pendingEchoes mid-flight, and (b) markDelivered
148
+ * throwing leaving stale ids in pendingEchoes (the inbox stays
149
+ * delivered=false so the next deliver re-pushes; markDelivered is idempotent).
150
+ */
151
+ async onAgentTurnSettled(swarmId, instanceId) {
152
+ const k = this.key(swarmId, instanceId);
153
+ const pending = this.pendingEchoes.get(k);
154
+ if (!pending || pending.size === 0)
155
+ return;
156
+ const swarm = this.getSwarm(swarmId);
157
+ if (!swarm?.workDir) {
158
+ this.pendingEchoes.delete(k);
159
+ return;
160
+ }
161
+ const ids = [...pending];
162
+ this.pendingEchoes.delete(k);
163
+ const store = new InboxStore(swarm.workDir, swarmId, this.home);
164
+ await store.markDelivered(instanceId, ids);
165
+ void this.deliver(swarmId, instanceId);
166
+ }
167
+ }
168
+ //# sourceMappingURL=inbox-relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox-relay.js","sourceRoot":"","sources":["../src/inbox-relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface InboxMessage {
2
+ id: string;
3
+ from: string;
4
+ type: string;
5
+ data: string;
6
+ taskId?: string;
7
+ timestamp: number;
8
+ delivered: boolean;
9
+ deliveredAt?: number;
10
+ }
11
+ export declare class InboxStore {
12
+ private workDir;
13
+ private swarmId;
14
+ private homeOverride?;
15
+ constructor(workDir: string, swarmId: string, homeOverride?: string | undefined);
16
+ private home;
17
+ private inboxesDir;
18
+ private validateInstanceId;
19
+ inboxFile(instanceId: string): string;
20
+ readAll(instanceId: string): Promise<InboxMessage[]>;
21
+ append(instanceId: string, msg: InboxMessage): Promise<void>;
22
+ readUndelivered(instanceId: string): Promise<InboxMessage[]>;
23
+ markDelivered(instanceId: string, ids: string[]): Promise<void>;
24
+ }
25
+ //# sourceMappingURL=inbox-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox-store.d.ts","sourceRoot":"","sources":["../src/inbox-store.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,UAAU;IAQnB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,YAAY,CAAC;gBAFb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,YAAA;IAG/B,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,kBAAkB;IAM1B,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAK/B,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAUpD,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAe5D,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAI5D,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAoBtE"}
@@ -0,0 +1,95 @@
1
+ import { join } from "node:path";
2
+ import { readFileSync, existsSync, writeFileSync, mkdirSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { projectRoot } from "@mclawnet/task";
5
+ import lockfile from "proper-lockfile";
6
+ const LOCK_OPTS = {
7
+ realpath: false,
8
+ retries: { retries: 50, minTimeout: 20, maxTimeout: 200 },
9
+ };
10
+ export class InboxStore {
11
+ workDir;
12
+ swarmId;
13
+ homeOverride;
14
+ // `home` is the user-home root (no `.clawnet` suffix). projectRoot() adds
15
+ // `.clawnet/projects/...` itself. When omitted we honour CLAWNET_HOME first,
16
+ // then fall back to the OS home — matches TaskStore for symmetry. Callers
17
+ // that already plumb a `rootDir` through ToolContext should pass it here so
18
+ // their writes land inside the test harness's tempdir instead of the real
19
+ // `~/.clawnet/projects/...`.
20
+ constructor(workDir, swarmId, homeOverride) {
21
+ this.workDir = workDir;
22
+ this.swarmId = swarmId;
23
+ this.homeOverride = homeOverride;
24
+ }
25
+ home() {
26
+ return this.homeOverride ?? process.env.CLAWNET_HOME ?? homedir();
27
+ }
28
+ inboxesDir() {
29
+ return join(projectRoot(this.workDir, this.home()), "swarms", this.swarmId, "inboxes");
30
+ }
31
+ validateInstanceId(id) {
32
+ if (!id || /[\\/]|\.\./.test(id) || id.includes("\0")) {
33
+ throw new Error(`InboxStore: invalid instanceId: ${JSON.stringify(id)}`);
34
+ }
35
+ }
36
+ inboxFile(instanceId) {
37
+ this.validateInstanceId(instanceId);
38
+ return join(this.inboxesDir(), `${instanceId}.json`);
39
+ }
40
+ async readAll(instanceId) {
41
+ const fp = this.inboxFile(instanceId);
42
+ if (!existsSync(fp))
43
+ return [];
44
+ try {
45
+ return JSON.parse(readFileSync(fp, "utf-8"));
46
+ }
47
+ catch {
48
+ return [];
49
+ }
50
+ }
51
+ async append(instanceId, msg) {
52
+ mkdirSync(this.inboxesDir(), { recursive: true });
53
+ const fp = this.inboxFile(instanceId);
54
+ if (!existsSync(fp))
55
+ writeFileSync(fp, "[]");
56
+ const release = await lockfile.lock(fp, LOCK_OPTS);
57
+ try {
58
+ const cur = JSON.parse(readFileSync(fp, "utf-8"));
59
+ if (cur.some(m => m.id === msg.id))
60
+ return;
61
+ cur.push(msg);
62
+ writeFileSync(fp, JSON.stringify(cur, null, 2));
63
+ }
64
+ finally {
65
+ await release();
66
+ }
67
+ }
68
+ async readUndelivered(instanceId) {
69
+ return (await this.readAll(instanceId)).filter(m => !m.delivered);
70
+ }
71
+ async markDelivered(instanceId, ids) {
72
+ if (ids.length === 0)
73
+ return;
74
+ const fp = this.inboxFile(instanceId);
75
+ if (!existsSync(fp))
76
+ return;
77
+ const release = await lockfile.lock(fp, LOCK_OPTS);
78
+ try {
79
+ const cur = JSON.parse(readFileSync(fp, "utf-8"));
80
+ const set = new Set(ids);
81
+ const now = Date.now();
82
+ for (const m of cur) {
83
+ if (set.has(m.id) && !m.delivered) {
84
+ m.delivered = true;
85
+ m.deliveredAt = now;
86
+ }
87
+ }
88
+ writeFileSync(fp, JSON.stringify(cur, null, 2));
89
+ }
90
+ finally {
91
+ await release();
92
+ }
93
+ }
94
+ }
95
+ //# sourceMappingURL=inbox-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox-store.js","sourceRoot":"","sources":["../src/inbox-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface InboxRelayLike {
2
+ deliver(swarmId: string, instanceId: string): Promise<void> | void;
3
+ }
4
+ export declare class InboxWatcher {
5
+ private relay;
6
+ private swarms;
7
+ constructor(relay: InboxRelayLike);
8
+ watch(swarmId: string, workDir: string): void;
9
+ unwatch(swarmId: string): void;
10
+ close(): void;
11
+ private schedule;
12
+ }
13
+ //# sourceMappingURL=inbox-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox-watcher.d.ts","sourceRoot":"","sources":["../src/inbox-watcher.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACpE;AAiBD,qBAAa,YAAY;IAGX,OAAO,CAAC,KAAK;IAFzB,OAAO,CAAC,MAAM,CAAiC;gBAE3B,KAAK,EAAE,cAAc;IAEzC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IA6B7C,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAS9B,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,QAAQ;CAWjB"}
@@ -0,0 +1,89 @@
1
+ import { mkdirSync, watch } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { createLogger } from "@mclawnet/logger";
5
+ import { projectRoot as taskProjectRoot } from "@mclawnet/task";
6
+ const log = createLogger({ module: "swarm/inbox-watcher" });
7
+ const DEBOUNCE_MS = 50;
8
+ const VALID_ID_RE = /^[A-Za-z0-9_.-]+$/;
9
+ // Use the canonical layout from @mclawnet/task so the watcher observes the
10
+ // same directory the InboxStore writes into. Previously this used a local
11
+ // `join(home, "projects", ...)` (missing `.clawnet`), which silently created
12
+ // phantom dirs at ~/projects/... while real inboxes lived at ~/.clawnet/...,
13
+ // so fs.watch never fired and task_assigned messages stayed delivered:false.
14
+ function projectRoot(workDir) {
15
+ const home = process.env.CLAWNET_HOME ?? homedir();
16
+ return taskProjectRoot(workDir, home);
17
+ }
18
+ export class InboxWatcher {
19
+ relay;
20
+ swarms = new Map();
21
+ constructor(relay) {
22
+ this.relay = relay;
23
+ }
24
+ watch(swarmId, workDir) {
25
+ if (this.swarms.has(swarmId))
26
+ return;
27
+ const dir = join(projectRoot(workDir), "swarms", swarmId, "inboxes");
28
+ try {
29
+ mkdirSync(dir, { recursive: true });
30
+ }
31
+ catch (err) {
32
+ log.warn({ err, swarmId, dir }, "inbox-watcher: mkdir failed");
33
+ return;
34
+ }
35
+ let fsw;
36
+ try {
37
+ fsw = watch(dir, { persistent: false }, (_evt, filename) => {
38
+ if (!filename)
39
+ return;
40
+ const name = String(filename);
41
+ if (!name.endsWith(".json"))
42
+ return;
43
+ const id = name.slice(0, -".json".length);
44
+ if (!VALID_ID_RE.test(id))
45
+ return;
46
+ this.schedule(swarmId, id);
47
+ });
48
+ }
49
+ catch (err) {
50
+ log.warn({ err, swarmId, dir }, "inbox-watcher: fs.watch failed");
51
+ return;
52
+ }
53
+ fsw.on("error", (err) => {
54
+ log.warn({ err, swarmId }, "inbox-watcher: fs.watch error");
55
+ });
56
+ this.swarms.set(swarmId, { watcher: fsw, timers: new Map() });
57
+ }
58
+ unwatch(swarmId) {
59
+ const entry = this.swarms.get(swarmId);
60
+ if (!entry)
61
+ return;
62
+ for (const t of entry.timers.values())
63
+ clearTimeout(t);
64
+ entry.timers.clear();
65
+ try {
66
+ entry.watcher.close();
67
+ }
68
+ catch { /* ignore */ }
69
+ this.swarms.delete(swarmId);
70
+ }
71
+ close() {
72
+ for (const swarmId of [...this.swarms.keys()])
73
+ this.unwatch(swarmId);
74
+ }
75
+ schedule(swarmId, instanceId) {
76
+ const entry = this.swarms.get(swarmId);
77
+ if (!entry)
78
+ return;
79
+ const existing = entry.timers.get(instanceId);
80
+ if (existing)
81
+ clearTimeout(existing);
82
+ const timer = setTimeout(() => {
83
+ entry.timers.delete(instanceId);
84
+ Promise.resolve(this.relay.deliver(swarmId, instanceId)).catch(() => { });
85
+ }, DEBOUNCE_MS);
86
+ entry.timers.set(instanceId, timer);
87
+ }
88
+ }
89
+ //# sourceMappingURL=inbox-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox-watcher.js","sourceRoot":"","sources":["../src/inbox-watcher.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  export { SwarmCoordinator } from "./swarm-coordinator.js";
2
- export { LocalMessageRouter } from "./message-router.js";
3
- export type { MessageRouter } from "./message-router.js";
4
- export { parseSwarmActions } from "./action-parser.js";
5
2
  export { initRoles, loadRole, listRoles, buildRolePrompt, parseRoleFile } from "./roles/role-loader.js";
6
3
  export { saveSwarmSnapshot, loadSwarmSnapshot, deleteSwarmSnapshot, appendMessageLog, readMessageLog, listRecoverableSwarmIds, } from "./persistence.js";
7
4
  export type { SwarmSnapshot } from "./persistence.js";
8
5
  export { runRetrospective } from "./retrospective.js";
9
6
  export type { RetrospectiveResult, RoleEvaluation } from "./retrospective.js";
10
7
  export { listRecoverableSwarms, recoverSwarm } from "./recovery.js";
8
+ export { InboxStore } from "./inbox-store.js";
9
+ export type { InboxMessage } from "./inbox-store.js";
10
+ export { InboxRelay } from "./inbox-relay.js";
11
+ export { InboxWatcher, type InboxRelayLike as InboxWatcherRelayLike } from "./inbox-watcher.js";
11
12
  export type { SessionAdapter, HubAdapter, SwarmInstance, RoleInstance, SwarmAction, SwarmMessage, SwarmCreateOptions, RouteEndpoint, SwarmStatus, PlanStatus, } from "./types.js";
12
13
  export type { RoleDefinition, DelegationMap, DelegationEntry } from "./roles/types.js";
13
14
  export { initTemplates, listTemplates, loadTemplate } from "./templates/template-loader.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACxG,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEpE,YAAY,EACV,cAAc,EACd,UAAU,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEvF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC5F,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACxG,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,IAAI,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhG,YAAY,EACV,cAAc,EACd,UAAU,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEvF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC5F,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  // @mclawnet/swarm — Swarm coordination, message routing, and role management
2
2
  export { SwarmCoordinator } from "./swarm-coordinator.js";
3
- export { LocalMessageRouter } from "./message-router.js";
4
- export { parseSwarmActions } from "./action-parser.js";
5
3
  export { initRoles, loadRole, listRoles, buildRolePrompt, parseRoleFile } from "./roles/role-loader.js";
6
4
  export { saveSwarmSnapshot, loadSwarmSnapshot, deleteSwarmSnapshot, appendMessageLog, readMessageLog, listRecoverableSwarmIds, } from "./persistence.js";
7
5
  export { runRetrospective } from "./retrospective.js";
8
6
  export { listRecoverableSwarms, recoverSwarm } from "./recovery.js";
7
+ export { InboxStore } from "./inbox-store.js";
8
+ export { InboxRelay } from "./inbox-relay.js";
9
+ export { InboxWatcher } from "./inbox-watcher.js";
9
10
  export { initTemplates, listTemplates, loadTemplate } from "./templates/template-loader.js";
10
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACxG,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAiBpE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACxG,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAgD,MAAM,oBAAoB,CAAC;AAiBhG,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC"}
@@ -3,22 +3,36 @@ export interface SwarmSnapshot {
3
3
  id: string;
4
4
  hubSessionId: string;
5
5
  workDir?: string;
6
+ teamName: string;
6
7
  roles: Array<{
7
8
  instanceId: string;
8
9
  roleName: string;
9
10
  status: string;
10
11
  currentTask?: string;
12
+ claudeSessionId?: string;
13
+ type?: "queen" | "worker";
11
14
  }>;
12
15
  plan: unknown;
13
16
  nextInstanceSeq: Record<string, number>;
14
17
  savedAt: number;
15
18
  status?: SwarmStatus;
16
19
  planStatus?: PlanStatus;
20
+ partialRecover?: boolean;
17
21
  }
18
22
  export declare function saveSwarmSnapshot(swarm: SwarmInstance): void;
19
- export declare function loadSwarmSnapshot(swarmId: string): SwarmSnapshot | null;
20
- export declare function deleteSwarmSnapshot(swarmId: string): void;
21
- export declare function readMessageLog(swarmId: string): object[];
22
- export declare function appendMessageLog(swarmId: string, entry: object): void;
23
- export declare function listRecoverableSwarmIds(): string[];
23
+ export declare function loadSwarmSnapshot(workDir: string, swarmId: string): SwarmSnapshot | null;
24
+ export declare function deleteSwarmSnapshot(workDir: string, swarmId: string): void;
25
+ export declare function readMessageLog(workDir: string, swarmId: string): object[];
26
+ export declare function appendMessageLog(workDir: string, swarmId: string, entry: object): void;
27
+ /**
28
+ * List recoverable swarms across all per-project roots. The authoritative
29
+ * `workDir` is read from each snapshot's `workDir` field (snapshots written
30
+ * since 0.1.6 always include it). Falling back on the encoded directory
31
+ * name is lossy for paths whose segments contain `-`, so we deliberately
32
+ * skip entries whose snapshot can't be parsed or doesn't carry `workDir`.
33
+ */
34
+ export declare function listRecoverableSwarmIds(): Array<{
35
+ workDir: string;
36
+ swarmId: string;
37
+ }>;
24
38
  //# sourceMappingURL=persistence.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAUzE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;IACH,IAAI,EAAE,OAAO,CAAC;IACd,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAoB5D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAQvE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKzD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBxD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAIrE;AAED,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAMlD"}
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAgBzE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,EAAE,OAAO,CAAC;IACd,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CA2C5D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAgBxF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAK1E;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBzE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAItF;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,IAAI,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAyCrF"}