opencode-swarm-plugin 0.44.0 → 0.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/bin/swarm.serve.test.ts +6 -4
  2. package/bin/swarm.ts +16 -10
  3. package/dist/compaction-prompt-scoring.js +139 -0
  4. package/dist/eval-capture.js +12811 -0
  5. package/dist/hive.d.ts.map +1 -1
  6. package/dist/index.js +7644 -62599
  7. package/dist/plugin.js +23766 -78721
  8. package/dist/swarm-orchestrate.d.ts.map +1 -1
  9. package/dist/swarm-prompts.d.ts.map +1 -1
  10. package/dist/swarm-review.d.ts.map +1 -1
  11. package/package.json +17 -5
  12. package/.changeset/swarm-insights-data-layer.md +0 -63
  13. package/.hive/analysis/eval-failure-analysis-2025-12-25.md +0 -331
  14. package/.hive/analysis/session-data-quality-audit.md +0 -320
  15. package/.hive/eval-results.json +0 -483
  16. package/.hive/issues.jsonl +0 -138
  17. package/.hive/memories.jsonl +0 -729
  18. package/.opencode/eval-history.jsonl +0 -327
  19. package/.turbo/turbo-build.log +0 -9
  20. package/CHANGELOG.md +0 -2286
  21. package/SCORER-ANALYSIS.md +0 -598
  22. package/docs/analysis/subagent-coordination-patterns.md +0 -902
  23. package/docs/analysis-socratic-planner-pattern.md +0 -504
  24. package/docs/planning/ADR-001-monorepo-structure.md +0 -171
  25. package/docs/planning/ADR-002-package-extraction.md +0 -393
  26. package/docs/planning/ADR-003-performance-improvements.md +0 -451
  27. package/docs/planning/ADR-004-message-queue-features.md +0 -187
  28. package/docs/planning/ADR-005-devtools-observability.md +0 -202
  29. package/docs/planning/ADR-007-swarm-enhancements-worktree-review.md +0 -168
  30. package/docs/planning/ADR-008-worker-handoff-protocol.md +0 -293
  31. package/docs/planning/ADR-009-oh-my-opencode-patterns.md +0 -353
  32. package/docs/planning/ADR-010-cass-inhousing.md +0 -1215
  33. package/docs/planning/ROADMAP.md +0 -368
  34. package/docs/semantic-memory-cli-syntax.md +0 -123
  35. package/docs/swarm-mail-architecture.md +0 -1147
  36. package/docs/testing/context-recovery-test.md +0 -470
  37. package/evals/ARCHITECTURE.md +0 -1189
  38. package/evals/README.md +0 -768
  39. package/evals/compaction-prompt.eval.ts +0 -149
  40. package/evals/compaction-resumption.eval.ts +0 -289
  41. package/evals/coordinator-behavior.eval.ts +0 -307
  42. package/evals/coordinator-session.eval.ts +0 -154
  43. package/evals/evalite.config.ts.bak +0 -15
  44. package/evals/example.eval.ts +0 -31
  45. package/evals/fixtures/cass-baseline.ts +0 -217
  46. package/evals/fixtures/compaction-cases.ts +0 -350
  47. package/evals/fixtures/compaction-prompt-cases.ts +0 -311
  48. package/evals/fixtures/coordinator-sessions.ts +0 -328
  49. package/evals/fixtures/decomposition-cases.ts +0 -105
  50. package/evals/lib/compaction-loader.test.ts +0 -248
  51. package/evals/lib/compaction-loader.ts +0 -320
  52. package/evals/lib/data-loader.evalite-test.ts +0 -289
  53. package/evals/lib/data-loader.test.ts +0 -345
  54. package/evals/lib/data-loader.ts +0 -281
  55. package/evals/lib/llm.ts +0 -115
  56. package/evals/scorers/compaction-prompt-scorers.ts +0 -145
  57. package/evals/scorers/compaction-scorers.ts +0 -305
  58. package/evals/scorers/coordinator-discipline.evalite-test.ts +0 -539
  59. package/evals/scorers/coordinator-discipline.ts +0 -325
  60. package/evals/scorers/index.test.ts +0 -146
  61. package/evals/scorers/index.ts +0 -328
  62. package/evals/scorers/outcome-scorers.evalite-test.ts +0 -27
  63. package/evals/scorers/outcome-scorers.ts +0 -349
  64. package/evals/swarm-decomposition.eval.ts +0 -121
  65. package/examples/commands/swarm.md +0 -745
  66. package/examples/plugin-wrapper-template.ts +0 -2515
  67. package/examples/skills/hive-workflow/SKILL.md +0 -212
  68. package/examples/skills/skill-creator/SKILL.md +0 -223
  69. package/examples/skills/swarm-coordination/SKILL.md +0 -292
  70. package/global-skills/cli-builder/SKILL.md +0 -344
  71. package/global-skills/cli-builder/references/advanced-patterns.md +0 -244
  72. package/global-skills/learning-systems/SKILL.md +0 -644
  73. package/global-skills/skill-creator/LICENSE.txt +0 -202
  74. package/global-skills/skill-creator/SKILL.md +0 -352
  75. package/global-skills/skill-creator/references/output-patterns.md +0 -82
  76. package/global-skills/skill-creator/references/workflows.md +0 -28
  77. package/global-skills/swarm-coordination/SKILL.md +0 -995
  78. package/global-skills/swarm-coordination/references/coordinator-patterns.md +0 -235
  79. package/global-skills/swarm-coordination/references/strategies.md +0 -138
  80. package/global-skills/system-design/SKILL.md +0 -213
  81. package/global-skills/testing-patterns/SKILL.md +0 -430
  82. package/global-skills/testing-patterns/references/dependency-breaking-catalog.md +0 -586
  83. package/opencode-swarm-plugin-0.30.7.tgz +0 -0
  84. package/opencode-swarm-plugin-0.31.0.tgz +0 -0
  85. package/scripts/cleanup-test-memories.ts +0 -346
  86. package/scripts/init-skill.ts +0 -222
  87. package/scripts/migrate-unknown-sessions.ts +0 -349
  88. package/scripts/validate-skill.ts +0 -204
  89. package/src/agent-mail.ts +0 -1724
  90. package/src/anti-patterns.test.ts +0 -1167
  91. package/src/anti-patterns.ts +0 -448
  92. package/src/compaction-capture.integration.test.ts +0 -257
  93. package/src/compaction-hook.test.ts +0 -838
  94. package/src/compaction-hook.ts +0 -1204
  95. package/src/compaction-observability.integration.test.ts +0 -139
  96. package/src/compaction-observability.test.ts +0 -187
  97. package/src/compaction-observability.ts +0 -324
  98. package/src/compaction-prompt-scorers.test.ts +0 -475
  99. package/src/compaction-prompt-scoring.ts +0 -300
  100. package/src/contributor-tools.test.ts +0 -133
  101. package/src/contributor-tools.ts +0 -201
  102. package/src/dashboard.test.ts +0 -611
  103. package/src/dashboard.ts +0 -462
  104. package/src/error-enrichment.test.ts +0 -403
  105. package/src/error-enrichment.ts +0 -219
  106. package/src/eval-capture.test.ts +0 -1015
  107. package/src/eval-capture.ts +0 -929
  108. package/src/eval-gates.test.ts +0 -306
  109. package/src/eval-gates.ts +0 -218
  110. package/src/eval-history.test.ts +0 -508
  111. package/src/eval-history.ts +0 -214
  112. package/src/eval-learning.test.ts +0 -378
  113. package/src/eval-learning.ts +0 -360
  114. package/src/eval-runner.test.ts +0 -223
  115. package/src/eval-runner.ts +0 -402
  116. package/src/export-tools.test.ts +0 -476
  117. package/src/export-tools.ts +0 -257
  118. package/src/hive.integration.test.ts +0 -2241
  119. package/src/hive.ts +0 -1628
  120. package/src/index.ts +0 -940
  121. package/src/learning.integration.test.ts +0 -1815
  122. package/src/learning.ts +0 -1079
  123. package/src/logger.test.ts +0 -189
  124. package/src/logger.ts +0 -135
  125. package/src/mandate-promotion.test.ts +0 -473
  126. package/src/mandate-promotion.ts +0 -239
  127. package/src/mandate-storage.integration.test.ts +0 -601
  128. package/src/mandate-storage.test.ts +0 -578
  129. package/src/mandate-storage.ts +0 -794
  130. package/src/mandates.ts +0 -540
  131. package/src/memory-tools.test.ts +0 -195
  132. package/src/memory-tools.ts +0 -344
  133. package/src/memory.integration.test.ts +0 -334
  134. package/src/memory.test.ts +0 -158
  135. package/src/memory.ts +0 -527
  136. package/src/model-selection.test.ts +0 -188
  137. package/src/model-selection.ts +0 -68
  138. package/src/observability-tools.test.ts +0 -359
  139. package/src/observability-tools.ts +0 -871
  140. package/src/output-guardrails.test.ts +0 -438
  141. package/src/output-guardrails.ts +0 -381
  142. package/src/pattern-maturity.test.ts +0 -1160
  143. package/src/pattern-maturity.ts +0 -525
  144. package/src/planning-guardrails.test.ts +0 -491
  145. package/src/planning-guardrails.ts +0 -438
  146. package/src/plugin.ts +0 -23
  147. package/src/post-compaction-tracker.test.ts +0 -251
  148. package/src/post-compaction-tracker.ts +0 -237
  149. package/src/query-tools.test.ts +0 -636
  150. package/src/query-tools.ts +0 -324
  151. package/src/rate-limiter.integration.test.ts +0 -466
  152. package/src/rate-limiter.ts +0 -774
  153. package/src/replay-tools.test.ts +0 -496
  154. package/src/replay-tools.ts +0 -240
  155. package/src/repo-crawl.integration.test.ts +0 -441
  156. package/src/repo-crawl.ts +0 -610
  157. package/src/schemas/cell-events.test.ts +0 -347
  158. package/src/schemas/cell-events.ts +0 -807
  159. package/src/schemas/cell.ts +0 -257
  160. package/src/schemas/evaluation.ts +0 -166
  161. package/src/schemas/index.test.ts +0 -199
  162. package/src/schemas/index.ts +0 -286
  163. package/src/schemas/mandate.ts +0 -232
  164. package/src/schemas/swarm-context.ts +0 -115
  165. package/src/schemas/task.ts +0 -161
  166. package/src/schemas/worker-handoff.test.ts +0 -302
  167. package/src/schemas/worker-handoff.ts +0 -131
  168. package/src/sessions/agent-discovery.test.ts +0 -137
  169. package/src/sessions/agent-discovery.ts +0 -112
  170. package/src/sessions/index.ts +0 -15
  171. package/src/skills.integration.test.ts +0 -1192
  172. package/src/skills.test.ts +0 -643
  173. package/src/skills.ts +0 -1549
  174. package/src/storage.integration.test.ts +0 -341
  175. package/src/storage.ts +0 -884
  176. package/src/structured.integration.test.ts +0 -817
  177. package/src/structured.test.ts +0 -1046
  178. package/src/structured.ts +0 -762
  179. package/src/swarm-decompose.test.ts +0 -188
  180. package/src/swarm-decompose.ts +0 -1302
  181. package/src/swarm-deferred.integration.test.ts +0 -157
  182. package/src/swarm-deferred.test.ts +0 -38
  183. package/src/swarm-insights.test.ts +0 -214
  184. package/src/swarm-insights.ts +0 -459
  185. package/src/swarm-mail.integration.test.ts +0 -970
  186. package/src/swarm-mail.ts +0 -739
  187. package/src/swarm-orchestrate.integration.test.ts +0 -282
  188. package/src/swarm-orchestrate.test.ts +0 -548
  189. package/src/swarm-orchestrate.ts +0 -3084
  190. package/src/swarm-prompts.test.ts +0 -1270
  191. package/src/swarm-prompts.ts +0 -2077
  192. package/src/swarm-research.integration.test.ts +0 -701
  193. package/src/swarm-research.test.ts +0 -698
  194. package/src/swarm-research.ts +0 -472
  195. package/src/swarm-review.integration.test.ts +0 -285
  196. package/src/swarm-review.test.ts +0 -879
  197. package/src/swarm-review.ts +0 -709
  198. package/src/swarm-strategies.ts +0 -407
  199. package/src/swarm-worktree.test.ts +0 -501
  200. package/src/swarm-worktree.ts +0 -575
  201. package/src/swarm.integration.test.ts +0 -2377
  202. package/src/swarm.ts +0 -38
  203. package/src/tool-adapter.integration.test.ts +0 -1221
  204. package/src/tool-availability.ts +0 -461
  205. package/tsconfig.json +0 -28
@@ -1,461 +0,0 @@
1
- /**
2
- * Tool Availability Module
3
- *
4
- * Checks for external tool availability and provides graceful degradation.
5
- * Tools are checked once and cached for the session.
6
- *
7
- * Supported tools:
8
- * - semantic-memory: Learning persistence with semantic search
9
- * - cass: Cross-agent session search for historical context
10
- * - ubs: Universal bug scanner for pre-commit checks
11
- * - hive: Git-backed issue tracking (primary)
12
- * - beads (bd): DEPRECATED - Use hive instead (kept for backward compatibility)
13
- * - swarm-mail: Embedded multi-agent coordination (PGLite-based)
14
- * - agent-mail: DEPRECATED - Legacy MCP server (use swarm-mail instead)
15
- */
16
-
17
- import { checkSwarmHealth } from "swarm-mail";
18
-
19
- /** Default timeout for URL reachability checks in milliseconds */
20
- const DEFAULT_URL_TIMEOUT_MS = 2000;
21
-
22
- /** Timeout for bunx commands (semantic-memory check) in milliseconds */
23
- const BUNX_TIMEOUT_MS = 10000;
24
-
25
- export type ToolName =
26
- | "semantic-memory"
27
- | "cass"
28
- | "ubs"
29
- | "hive"
30
- | "beads" // DEPRECATED: Use "hive" instead
31
- | "swarm-mail"
32
- | "agent-mail";
33
-
34
- export interface ToolStatus {
35
- available: boolean;
36
- checkedAt: string;
37
- error?: string;
38
- version?: string;
39
- }
40
-
41
- export interface ToolAvailability {
42
- tool: ToolName;
43
- status: ToolStatus;
44
- fallbackBehavior: string;
45
- }
46
-
47
- // Cached tool status
48
- const toolCache = new Map<ToolName, ToolStatus>();
49
-
50
- // Warnings already logged (to avoid spam)
51
- const warningsLogged = new Set<ToolName>();
52
-
53
- /**
54
- * Check if a command exists and is executable
55
- */
56
- async function commandExists(cmd: string): Promise<boolean> {
57
- try {
58
- const result = await Bun.$`which ${cmd}`.quiet().nothrow();
59
- return result.exitCode === 0;
60
- } catch {
61
- return false;
62
- }
63
- }
64
-
65
- /**
66
- * Check if a URL is reachable.
67
- * Uses GET instead of HEAD because some servers don't support HEAD.
68
- * We only check response.ok status, not body content, so GET has minimal overhead vs HEAD.
69
- */
70
- async function urlReachable(
71
- url: string,
72
- timeoutMs: number = DEFAULT_URL_TIMEOUT_MS,
73
- ): Promise<boolean> {
74
- try {
75
- const controller = new AbortController();
76
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
77
-
78
- // Use GET instead of HEAD - some servers don't support HEAD
79
- const response = await fetch(url, {
80
- method: "GET",
81
- signal: controller.signal,
82
- });
83
-
84
- clearTimeout(timeout);
85
- return response.ok;
86
- } catch {
87
- return false;
88
- }
89
- }
90
-
91
- /**
92
- * Tool-specific availability checks
93
- */
94
- const toolCheckers: Record<ToolName, () => Promise<ToolStatus>> = {
95
- "semantic-memory": async () => {
96
- // Check native first, then bunx
97
- const nativeExists = await commandExists("semantic-memory");
98
- if (nativeExists) {
99
- try {
100
- const result = await Bun.$`semantic-memory stats`.quiet().nothrow();
101
- return {
102
- available: result.exitCode === 0,
103
- checkedAt: new Date().toISOString(),
104
- version: "native",
105
- };
106
- } catch (e) {
107
- return {
108
- available: false,
109
- checkedAt: new Date().toISOString(),
110
- error: String(e),
111
- };
112
- }
113
- }
114
-
115
- // Try bunx with manual timeout
116
- try {
117
- const proc = Bun.spawn(["bunx", "semantic-memory", "stats"], {
118
- stdout: "pipe",
119
- stderr: "pipe",
120
- });
121
-
122
- const timeout = setTimeout(() => proc.kill(), BUNX_TIMEOUT_MS);
123
- const exitCode = await proc.exited;
124
- clearTimeout(timeout);
125
-
126
- return {
127
- available: exitCode === 0,
128
- checkedAt: new Date().toISOString(),
129
- version: "bunx",
130
- };
131
- } catch (e) {
132
- return {
133
- available: false,
134
- checkedAt: new Date().toISOString(),
135
- error: String(e),
136
- };
137
- }
138
- },
139
-
140
- cass: async () => {
141
- const exists = await commandExists("cass");
142
- if (!exists) {
143
- return {
144
- available: false,
145
- checkedAt: new Date().toISOString(),
146
- error: "cass command not found",
147
- };
148
- }
149
-
150
- try {
151
- const result = await Bun.$`cass health`.quiet().nothrow();
152
- return {
153
- available: result.exitCode === 0,
154
- checkedAt: new Date().toISOString(),
155
- };
156
- } catch (e) {
157
- return {
158
- available: false,
159
- checkedAt: new Date().toISOString(),
160
- error: String(e),
161
- };
162
- }
163
- },
164
-
165
- ubs: async () => {
166
- const exists = await commandExists("ubs");
167
- if (!exists) {
168
- return {
169
- available: false,
170
- checkedAt: new Date().toISOString(),
171
- error: "ubs command not found",
172
- };
173
- }
174
-
175
- try {
176
- const result = await Bun.$`ubs doctor`.quiet().nothrow();
177
- return {
178
- available: result.exitCode === 0,
179
- checkedAt: new Date().toISOString(),
180
- };
181
- } catch (e) {
182
- return {
183
- available: false,
184
- checkedAt: new Date().toISOString(),
185
- error: String(e),
186
- };
187
- }
188
- },
189
-
190
- hive: async () => {
191
- const exists = await commandExists("hive");
192
- if (!exists) {
193
- return {
194
- available: false,
195
- checkedAt: new Date().toISOString(),
196
- error: "hive command not found",
197
- };
198
- }
199
-
200
- try {
201
- // Just check if hive can run - don't require a repo
202
- const result = await Bun.$`hive --version`.quiet().nothrow();
203
- return {
204
- available: result.exitCode === 0,
205
- checkedAt: new Date().toISOString(),
206
- };
207
- } catch (e) {
208
- return {
209
- available: false,
210
- checkedAt: new Date().toISOString(),
211
- error: String(e),
212
- };
213
- }
214
- },
215
-
216
- // DEPRECATED: Use hive instead
217
- // bd CLI is deprecated - always return false, use HiveAdapter instead
218
- beads: async () => {
219
- return {
220
- available: false,
221
- checkedAt: new Date().toISOString(),
222
- error: "bd CLI is deprecated - use hive_* tools with HiveAdapter instead",
223
- };
224
- },
225
-
226
- "swarm-mail": async () => {
227
- try {
228
- // Note: checkSwarmHealth() accepts optional projectPath parameter.
229
- // For tool availability checking, we call it without args to check global health.
230
- // This is intentional - we're verifying the embedded Swarm Mail system is functional,
231
- // not checking health for a specific project.
232
- const healthResult = await checkSwarmHealth();
233
- return {
234
- available: healthResult.healthy,
235
- checkedAt: new Date().toISOString(),
236
- error: healthResult.healthy
237
- ? undefined
238
- : "Swarm Mail database not healthy",
239
- version: "embedded",
240
- };
241
- } catch (e) {
242
- return {
243
- available: false,
244
- checkedAt: new Date().toISOString(),
245
- error: String(e),
246
- };
247
- }
248
- },
249
-
250
- // DEPRECATED: Use swarm-mail instead
251
- // Kept for backward compatibility only
252
- "agent-mail": async () => {
253
- const reachable = await urlReachable(
254
- "http://127.0.0.1:8765/health/liveness",
255
- );
256
- return {
257
- available: reachable,
258
- checkedAt: new Date().toISOString(),
259
- error: reachable ? undefined : "Agent Mail server not reachable at :8765",
260
- };
261
- },
262
- };
263
-
264
- /**
265
- * Human-readable descriptions of graceful degradation behavior when tools are unavailable.
266
- * Shown to users in warnings and tool status output.
267
- */
268
- const fallbackBehaviors: Record<ToolName, string> = {
269
- "semantic-memory":
270
- "Learning data stored in-memory only (lost on session end)",
271
- cass: "Decomposition proceeds without historical context from past sessions",
272
- ubs: "Subtask completion skips bug scanning - manual review recommended",
273
- hive: "Swarm cannot track issues - task coordination will be less reliable",
274
- beads:
275
- "DEPRECATED: Use hive instead. Swarm cannot track issues - task coordination will be less reliable",
276
- "swarm-mail":
277
- "Multi-agent coordination disabled - file conflicts possible if multiple agents active",
278
- "agent-mail":
279
- "DEPRECATED: Use swarm-mail instead. Legacy MCP server mode - file conflicts possible if multiple agents active",
280
- };
281
-
282
- /**
283
- * Check if a tool is available (cached)
284
- *
285
- * @param tool - Tool name to check
286
- * @returns Tool status
287
- */
288
- export async function checkTool(tool: ToolName): Promise<ToolStatus> {
289
- const cached = toolCache.get(tool);
290
- if (cached) {
291
- return cached;
292
- }
293
-
294
- const checker = toolCheckers[tool];
295
- const status = await checker();
296
- toolCache.set(tool, status);
297
-
298
- return status;
299
- }
300
-
301
- /**
302
- * Check if a tool is available (simple boolean, cached)
303
- */
304
- export async function isToolAvailable(tool: ToolName): Promise<boolean> {
305
- const status = await checkTool(tool);
306
- return status.available;
307
- }
308
-
309
- /**
310
- * Get full availability info including fallback behavior
311
- */
312
- export async function getToolAvailability(
313
- tool: ToolName,
314
- ): Promise<ToolAvailability> {
315
- const status = await checkTool(tool);
316
- return {
317
- tool,
318
- status,
319
- fallbackBehavior: fallbackBehaviors[tool],
320
- };
321
- }
322
-
323
- /**
324
- * Check all tools and return availability map
325
- */
326
- export async function checkAllTools(): Promise<
327
- Map<ToolName, ToolAvailability>
328
- > {
329
- const tools: ToolName[] = [
330
- "semantic-memory",
331
- "cass",
332
- "ubs",
333
- "hive",
334
- "beads",
335
- "swarm-mail",
336
- "agent-mail",
337
- ];
338
-
339
- const results = new Map<ToolName, ToolAvailability>();
340
-
341
- // Check all in parallel
342
- const checks = await Promise.all(
343
- tools.map(async (tool) => ({
344
- tool,
345
- availability: await getToolAvailability(tool),
346
- })),
347
- );
348
-
349
- for (const { tool, availability } of checks) {
350
- results.set(tool, availability);
351
- }
352
-
353
- return results;
354
- }
355
-
356
- /**
357
- * Log a warning when a tool is missing.
358
- * Uses Set to deduplicate - logs once per tool per session to prevent spam
359
- * when tool availability is checked repeatedly.
360
- */
361
- export function warnMissingTool(tool: ToolName): void {
362
- if (warningsLogged.has(tool)) {
363
- return;
364
- }
365
-
366
- warningsLogged.add(tool);
367
- const fallback = fallbackBehaviors[tool];
368
- console.warn(`[swarm] ${tool} not available: ${fallback}`);
369
- }
370
-
371
- /**
372
- * Require a tool - throws if not available
373
- *
374
- * Use this for tools that are mandatory for a feature.
375
- */
376
- export async function requireTool(tool: ToolName): Promise<void> {
377
- const status = await checkTool(tool);
378
- if (!status.available) {
379
- throw new Error(
380
- `Required tool '${tool}' is not available: ${status.error || "unknown error"}`,
381
- );
382
- }
383
- }
384
-
385
- /**
386
- * Execute with fallback - runs the action if tool available, otherwise runs fallback
387
- *
388
- * @param tool - Tool to check
389
- * @param action - Action to run if tool available
390
- * @param fallback - Fallback to run if tool not available
391
- * @returns Result from action or fallback
392
- */
393
- export async function withToolFallback<T>(
394
- tool: ToolName,
395
- action: () => Promise<T>,
396
- fallback: () => T | Promise<T>,
397
- ): Promise<T> {
398
- const available = await isToolAvailable(tool);
399
-
400
- if (available) {
401
- return action();
402
- }
403
-
404
- warnMissingTool(tool);
405
- return fallback();
406
- }
407
-
408
- /**
409
- * Execute if tool available, otherwise return undefined
410
- */
411
- export async function ifToolAvailable<T>(
412
- tool: ToolName,
413
- action: () => Promise<T>,
414
- ): Promise<T | undefined> {
415
- const available = await isToolAvailable(tool);
416
-
417
- if (available) {
418
- return action();
419
- }
420
-
421
- warnMissingTool(tool);
422
- return undefined;
423
- }
424
-
425
- /**
426
- * Reset the tool availability cache.
427
- * Use in tests to ensure fresh checks, or when tool availability may have
428
- * changed mid-session (e.g., after installing a tool via `bunx`).
429
- *
430
- * @example
431
- * // In tests
432
- * beforeEach(() => resetToolCache());
433
- *
434
- * @example
435
- * // After installing a tool
436
- * await installTool('semantic-memory');
437
- * resetToolCache();
438
- * const available = await isToolAvailable('semantic-memory');
439
- */
440
- export function resetToolCache(): void {
441
- toolCache.clear();
442
- warningsLogged.clear();
443
- }
444
-
445
- /**
446
- * Format tool availability for display
447
- */
448
- export function formatToolAvailability(
449
- availability: Map<ToolName, ToolAvailability>,
450
- ): string {
451
- const lines: string[] = ["Tool Availability:"];
452
-
453
- for (const [tool, info] of availability) {
454
- const status = info.status.available ? "✓" : "✗";
455
- const version = info.status.version ? ` (${info.status.version})` : "";
456
- const fallback = info.status.available ? "" : ` → ${info.fallbackBehavior}`;
457
- lines.push(` ${status} ${tool}${version}${fallback}`);
458
- }
459
-
460
- return lines.join("\n");
461
- }
package/tsconfig.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "lib": ["ESNext"],
7
- "types": ["bun-types"],
8
- "strict": true,
9
- "skipLibCheck": true,
10
- "esModuleInterop": true,
11
- "allowSyntheticDefaultImports": true,
12
- "forceConsistentCasingInFileNames": true,
13
- "resolveJsonModule": true,
14
- "declaration": true,
15
- "declarationMap": true,
16
- "emitDeclarationOnly": true,
17
- "sourceMap": true,
18
- "outDir": "./dist",
19
- "rootDir": "./src",
20
- "baseUrl": ".",
21
- "paths": {
22
- "@/*": ["./src/*"],
23
- "@schemas/*": ["./src/schemas/*"]
24
- }
25
- },
26
- "include": ["src/**/*"],
27
- "exclude": ["node_modules", "dist", "**/*.test.ts"]
28
- }