contextos-mcp 0.4.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 (223) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +260 -0
  3. package/bin/mcp.mjs +61 -0
  4. package/bin/swarm.mjs +45 -0
  5. package/dist/agents/aider.d.ts +12 -0
  6. package/dist/agents/aider.js +192 -0
  7. package/dist/agents/aider.js.map +1 -0
  8. package/dist/agents/claude-code.d.ts +9 -0
  9. package/dist/agents/claude-code.js +236 -0
  10. package/dist/agents/claude-code.js.map +1 -0
  11. package/dist/agents/codex.d.ts +14 -0
  12. package/dist/agents/codex.js +203 -0
  13. package/dist/agents/codex.js.map +1 -0
  14. package/dist/agents/direct-llm.d.ts +22 -0
  15. package/dist/agents/direct-llm.js +254 -0
  16. package/dist/agents/direct-llm.js.map +1 -0
  17. package/dist/agents/mock.d.ts +10 -0
  18. package/dist/agents/mock.js +170 -0
  19. package/dist/agents/mock.js.map +1 -0
  20. package/dist/agents/opencode.d.ts +23 -0
  21. package/dist/agents/opencode.js +631 -0
  22. package/dist/agents/opencode.js.map +1 -0
  23. package/dist/agents/provider.d.ts +11 -0
  24. package/dist/agents/provider.js +31 -0
  25. package/dist/agents/provider.js.map +1 -0
  26. package/dist/compression/compressor.d.ts +28 -0
  27. package/dist/compression/compressor.js +268 -0
  28. package/dist/compression/compressor.js.map +1 -0
  29. package/dist/config.d.ts +43 -0
  30. package/dist/config.js +172 -0
  31. package/dist/config.js.map +1 -0
  32. package/dist/contextos/loader.d.ts +46 -0
  33. package/dist/contextos/loader.js +120 -0
  34. package/dist/contextos/loader.js.map +1 -0
  35. package/dist/contextos/selector.d.ts +46 -0
  36. package/dist/contextos/selector.js +80 -0
  37. package/dist/contextos/selector.js.map +1 -0
  38. package/dist/core/action-dispatcher.d.ts +15 -0
  39. package/dist/core/action-dispatcher.js +28 -0
  40. package/dist/core/action-dispatcher.js.map +1 -0
  41. package/dist/core/action-schema.d.ts +72 -0
  42. package/dist/core/action-schema.js +86 -0
  43. package/dist/core/action-schema.js.map +1 -0
  44. package/dist/core/repl-interface.d.ts +48 -0
  45. package/dist/core/repl-interface.js +5 -0
  46. package/dist/core/repl-interface.js.map +1 -0
  47. package/dist/core/repl.d.ts +59 -0
  48. package/dist/core/repl.js +353 -0
  49. package/dist/core/repl.js.map +1 -0
  50. package/dist/core/rlm.d.ts +65 -0
  51. package/dist/core/rlm.js +564 -0
  52. package/dist/core/rlm.js.map +1 -0
  53. package/dist/core/runtime.py +470 -0
  54. package/dist/core/types.d.ts +265 -0
  55. package/dist/core/types.js +19 -0
  56. package/dist/core/types.js.map +1 -0
  57. package/dist/env.d.ts +10 -0
  58. package/dist/env.js +75 -0
  59. package/dist/env.js.map +1 -0
  60. package/dist/hooks/runner.d.ts +43 -0
  61. package/dist/hooks/runner.js +173 -0
  62. package/dist/hooks/runner.js.map +1 -0
  63. package/dist/labs/cli.d.ts +15 -0
  64. package/dist/labs/cli.js +295 -0
  65. package/dist/labs/cli.js.map +1 -0
  66. package/dist/labs/episodic-memory.d.ts +132 -0
  67. package/dist/labs/episodic-memory.js +391 -0
  68. package/dist/labs/episodic-memory.js.map +1 -0
  69. package/dist/labs/interactive-swarm.d.ts +20 -0
  70. package/dist/labs/interactive-swarm.js +1173 -0
  71. package/dist/labs/interactive-swarm.js.map +1 -0
  72. package/dist/labs/interactive.d.ts +10 -0
  73. package/dist/labs/interactive.js +2099 -0
  74. package/dist/labs/interactive.js.map +1 -0
  75. package/dist/labs/ts-analyzer.d.ts +74 -0
  76. package/dist/labs/ts-analyzer.js +379 -0
  77. package/dist/labs/ts-analyzer.js.map +1 -0
  78. package/dist/labs/viewer.d.ts +12 -0
  79. package/dist/labs/viewer.js +1284 -0
  80. package/dist/labs/viewer.js.map +1 -0
  81. package/dist/main.d.ts +15 -0
  82. package/dist/main.js +247 -0
  83. package/dist/main.js.map +1 -0
  84. package/dist/mcp/server.d.ts +16 -0
  85. package/dist/mcp/server.js +192775 -0
  86. package/dist/mcp/server.js.map +1 -0
  87. package/dist/mcp/session.d.ts +117 -0
  88. package/dist/mcp/session.js +450 -0
  89. package/dist/mcp/session.js.map +1 -0
  90. package/dist/mcp/state.d.ts +42 -0
  91. package/dist/mcp/state.js +537 -0
  92. package/dist/mcp/state.js.map +1 -0
  93. package/dist/mcp/tools/contextos.d.ts +17 -0
  94. package/dist/mcp/tools/contextos.js +583 -0
  95. package/dist/mcp/tools/contextos.js.map +1 -0
  96. package/dist/mcp/tools.d.ts +15 -0
  97. package/dist/mcp/tools.js +393 -0
  98. package/dist/mcp/tools.js.map +1 -0
  99. package/dist/orchestration/reviewer-gate.d.ts +43 -0
  100. package/dist/orchestration/reviewer-gate.js +280 -0
  101. package/dist/orchestration/reviewer-gate.js.map +1 -0
  102. package/dist/orchestration/reviewer-prompt.d.ts +18 -0
  103. package/dist/orchestration/reviewer-prompt.js +67 -0
  104. package/dist/orchestration/reviewer-prompt.js.map +1 -0
  105. package/dist/orchestration/verification-runner.d.ts +53 -0
  106. package/dist/orchestration/verification-runner.js +352 -0
  107. package/dist/orchestration/verification-runner.js.map +1 -0
  108. package/dist/plugins/adapter.d.ts +11 -0
  109. package/dist/plugins/adapter.js +11 -0
  110. package/dist/plugins/adapter.js.map +1 -0
  111. package/dist/plugins/core/archive.d.ts +9 -0
  112. package/dist/plugins/core/archive.js +128 -0
  113. package/dist/plugins/core/archive.js.map +1 -0
  114. package/dist/plugins/core/digest.d.ts +11 -0
  115. package/dist/plugins/core/digest.js +70 -0
  116. package/dist/plugins/core/digest.js.map +1 -0
  117. package/dist/plugins/core/grants.d.ts +22 -0
  118. package/dist/plugins/core/grants.js +90 -0
  119. package/dist/plugins/core/grants.js.map +1 -0
  120. package/dist/plugins/core/index.d.ts +10 -0
  121. package/dist/plugins/core/index.js +11 -0
  122. package/dist/plugins/core/index.js.map +1 -0
  123. package/dist/plugins/core/pinning.d.ts +15 -0
  124. package/dist/plugins/core/pinning.js +86 -0
  125. package/dist/plugins/core/pinning.js.map +1 -0
  126. package/dist/plugins/core/types.d.ts +105 -0
  127. package/dist/plugins/core/types.js +22 -0
  128. package/dist/plugins/core/types.js.map +1 -0
  129. package/dist/plugins/core/updater.d.ts +16 -0
  130. package/dist/plugins/core/updater.js +64 -0
  131. package/dist/plugins/core/updater.js.map +1 -0
  132. package/dist/plugins/loader.d.ts +65 -0
  133. package/dist/plugins/loader.js +110 -0
  134. package/dist/plugins/loader.js.map +1 -0
  135. package/dist/prompts/orchestrator.d.ts +6 -0
  136. package/dist/prompts/orchestrator.js +114 -0
  137. package/dist/prompts/orchestrator.js.map +1 -0
  138. package/dist/routing/model-resolver.d.ts +27 -0
  139. package/dist/routing/model-resolver.js +265 -0
  140. package/dist/routing/model-resolver.js.map +1 -0
  141. package/dist/routing/model-router.d.ts +130 -0
  142. package/dist/routing/model-router.js +515 -0
  143. package/dist/routing/model-router.js.map +1 -0
  144. package/dist/runtime/attestations.cjs +260 -0
  145. package/dist/runtime/reviewer-pipeline.cjs +319 -0
  146. package/dist/runtime/sandbox.cjs +468 -0
  147. package/dist/runtime/state-machine.cjs +885 -0
  148. package/dist/runtime/thread-store.cjs +175 -0
  149. package/dist/runtime/transactional-git.cjs +315 -0
  150. package/dist/runtime/verification-pipeline.cjs +435 -0
  151. package/dist/sandbox/execution.d.ts +165 -0
  152. package/dist/sandbox/execution.js +497 -0
  153. package/dist/sandbox/execution.js.map +1 -0
  154. package/dist/security/file-policy.d.ts +22 -0
  155. package/dist/security/file-policy.js +53 -0
  156. package/dist/security/file-policy.js.map +1 -0
  157. package/dist/security/repository-boundary.d.ts +21 -0
  158. package/dist/security/repository-boundary.js +119 -0
  159. package/dist/security/repository-boundary.js.map +1 -0
  160. package/dist/security/secret-filter.d.ts +36 -0
  161. package/dist/security/secret-filter.js +149 -0
  162. package/dist/security/secret-filter.js.map +1 -0
  163. package/dist/swarm.d.ts +14 -0
  164. package/dist/swarm.js +624 -0
  165. package/dist/swarm.js.map +1 -0
  166. package/dist/threads/cache.d.ts +64 -0
  167. package/dist/threads/cache.js +241 -0
  168. package/dist/threads/cache.js.map +1 -0
  169. package/dist/threads/manager.d.ts +94 -0
  170. package/dist/threads/manager.js +914 -0
  171. package/dist/threads/manager.js.map +1 -0
  172. package/dist/ui/banner.d.ts +14 -0
  173. package/dist/ui/banner.js +42 -0
  174. package/dist/ui/banner.js.map +1 -0
  175. package/dist/ui/dashboard.d.ts +33 -0
  176. package/dist/ui/dashboard.js +135 -0
  177. package/dist/ui/dashboard.js.map +1 -0
  178. package/dist/ui/index.d.ts +11 -0
  179. package/dist/ui/index.js +12 -0
  180. package/dist/ui/index.js.map +1 -0
  181. package/dist/ui/log.d.ts +39 -0
  182. package/dist/ui/log.js +126 -0
  183. package/dist/ui/log.js.map +1 -0
  184. package/dist/ui/onboarding.d.ts +14 -0
  185. package/dist/ui/onboarding.js +755 -0
  186. package/dist/ui/onboarding.js.map +1 -0
  187. package/dist/ui/run-log.d.ts +50 -0
  188. package/dist/ui/run-log.js +60 -0
  189. package/dist/ui/run-log.js.map +1 -0
  190. package/dist/ui/spinner.d.ts +41 -0
  191. package/dist/ui/spinner.js +172 -0
  192. package/dist/ui/spinner.js.map +1 -0
  193. package/dist/ui/streaming-feed.d.ts +72 -0
  194. package/dist/ui/streaming-feed.js +386 -0
  195. package/dist/ui/streaming-feed.js.map +1 -0
  196. package/dist/ui/summary.d.ts +18 -0
  197. package/dist/ui/summary.js +113 -0
  198. package/dist/ui/summary.js.map +1 -0
  199. package/dist/ui/text-input.d.ts +19 -0
  200. package/dist/ui/text-input.js +266 -0
  201. package/dist/ui/text-input.js.map +1 -0
  202. package/dist/ui/theme.d.ts +63 -0
  203. package/dist/ui/theme.js +97 -0
  204. package/dist/ui/theme.js.map +1 -0
  205. package/dist/utils/command-exists.d.ts +11 -0
  206. package/dist/utils/command-exists.js +41 -0
  207. package/dist/utils/command-exists.js.map +1 -0
  208. package/dist/utils/process-security.d.ts +19 -0
  209. package/dist/utils/process-security.js +90 -0
  210. package/dist/utils/process-security.js.map +1 -0
  211. package/dist/utils/rolling-buffer.d.ts +16 -0
  212. package/dist/utils/rolling-buffer.js +30 -0
  213. package/dist/utils/rolling-buffer.js.map +1 -0
  214. package/dist/utils/safe-spawn.d.ts +13 -0
  215. package/dist/utils/safe-spawn.js +49 -0
  216. package/dist/utils/safe-spawn.js.map +1 -0
  217. package/dist/worktree/manager.d.ts +69 -0
  218. package/dist/worktree/manager.js +593 -0
  219. package/dist/worktree/manager.js.map +1 -0
  220. package/dist/worktree/merge.d.ts +58 -0
  221. package/dist/worktree/merge.js +389 -0
  222. package/dist/worktree/merge.js.map +1 -0
  223. package/package.json +63 -0
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Agent provider interface and registry.
3
+ *
4
+ * Each agent backend (OpenCode, Claude Code, etc.) implements AgentProvider.
5
+ * The registry maps backend names to providers.
6
+ */
7
+ const registry = new Map();
8
+ export function registerAgent(provider) {
9
+ registry.set(provider.name, provider);
10
+ }
11
+ export function getAgent(name) {
12
+ const provider = registry.get(name);
13
+ if (!provider) {
14
+ const available = [...registry.keys()].join(", ");
15
+ throw new Error(`Unknown agent backend "${name}". Available: ${available || "none"}`);
16
+ }
17
+ return provider;
18
+ }
19
+ export function listAgents() {
20
+ return [...registry.keys()];
21
+ }
22
+ export async function getAvailableAgents() {
23
+ const results = [];
24
+ for (const [name, provider] of registry) {
25
+ if (await provider.isAvailable()) {
26
+ results.push(name);
27
+ }
28
+ }
29
+ return results;
30
+ }
31
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/agents/provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;AAElD,MAAM,UAAU,aAAa,CAAC,QAAuB;IACpD,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACpC,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,MAAM,SAAS,GAAG,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,iBAAiB,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,UAAU;IACzB,OAAO,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACvC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzC,IAAI,MAAM,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACF,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Context compression — compresses thread output before returning to the orchestrator.
3
+ *
4
+ * Strategies:
5
+ * - structured (default): status + files + diff stats + key hunks + tail output
6
+ * - diff-only: just the git diff
7
+ * - truncate: raw truncation
8
+ * - llm-summary: use a cheap LLM to summarize thread work
9
+ *
10
+ * Episode quality: All strategies apply filterToSuccessfulOutput() first,
11
+ * stripping failed attempts, retries, and error noise so the orchestrator
12
+ * only sees what contributed to the final result (Slate-style episodes).
13
+ */
14
+ import type { SwarmConfig } from "../core/types.js";
15
+ export interface CompressionInput {
16
+ agentOutput: string;
17
+ diff: string;
18
+ diffStats: string;
19
+ filesChanged: string[];
20
+ success: boolean;
21
+ durationMs: number;
22
+ error?: string;
23
+ }
24
+ /** Optional LLM summarizer for llm-summary strategy. */
25
+ export type LlmSummarizer = (text: string, instruction: string) => Promise<string>;
26
+ /** Register an LLM summarizer for the llm-summary compression strategy. */
27
+ export declare function setSummarizer(fn: LlmSummarizer): void;
28
+ export declare function compressResult(input: CompressionInput, strategy?: SwarmConfig["compression_strategy"], maxChars?: number): Promise<string>;
@@ -0,0 +1,268 @@
1
+ /**
2
+ * Context compression — compresses thread output before returning to the orchestrator.
3
+ *
4
+ * Strategies:
5
+ * - structured (default): status + files + diff stats + key hunks + tail output
6
+ * - diff-only: just the git diff
7
+ * - truncate: raw truncation
8
+ * - llm-summary: use a cheap LLM to summarize thread work
9
+ *
10
+ * Episode quality: All strategies apply filterToSuccessfulOutput() first,
11
+ * stripping failed attempts, retries, and error noise so the orchestrator
12
+ * only sees what contributed to the final result (Slate-style episodes).
13
+ */
14
+ import { redactSecrets } from "../security/secret-filter.js";
15
+ // Module-level summarizer — set once by the swarm orchestrator
16
+ let _summarizer;
17
+ /** Register an LLM summarizer for the llm-summary compression strategy. */
18
+ export function setSummarizer(fn) {
19
+ _summarizer = fn;
20
+ }
21
+ // ── Episode quality filter ────────────────────────────────────────────────
22
+ /**
23
+ * Patterns that indicate failed attempts, retries, or noise in agent output.
24
+ * These lines are stripped so the orchestrator only sees successful conclusions.
25
+ */
26
+ const FAILURE_NOISE_PATTERNS = [
27
+ // Error/retry indicators (anchored to avoid matching "Error handling added")
28
+ /^error: /i,
29
+ /^Error: /,
30
+ /^failed to /i,
31
+ /^retrying/i,
32
+ /^retry attempt/i,
33
+ /^warning: /i,
34
+ /^timed? ?out/i,
35
+ // Common agent noise: stack traces
36
+ /^\s+at\s+\S+\s+\(/,
37
+ /^Traceback \(most recent/,
38
+ /^\s+File ".*", line \d+/,
39
+ // Agent internal chatter
40
+ /^Thinking\.\.\./i,
41
+ /^Searching\.\.\./i,
42
+ /^Reading\.\.\./i,
43
+ /^Running command\.\.\./i,
44
+ // Reverted / undone actions (anchored to start of line)
45
+ /^reverted /i,
46
+ /^undoing /i,
47
+ /^rolling back/i,
48
+ ];
49
+ /** Patterns that indicate successful, conclusive output worth keeping. */
50
+ const SUCCESS_SIGNAL_PATTERNS = [
51
+ /^Applied edit to/i,
52
+ /^Wrote /,
53
+ /^Created /i,
54
+ /^Updated /i,
55
+ /^Added /i,
56
+ /^Removed /i,
57
+ /^Fixed /i,
58
+ /^Committing /,
59
+ /tests? pass/i,
60
+ /✓|✔|PASS/,
61
+ /^DONE/i,
62
+ /^SUCCESS/i,
63
+ /^Result:/i,
64
+ /^Summary:/i,
65
+ /^Completed/i,
66
+ ];
67
+ /**
68
+ * Filter agent output to only include lines that contributed to the final result.
69
+ * Strips failed attempts, retries, stack traces, and noise.
70
+ * Keeps: success signals, file-change confirmations, final conclusions, and
71
+ * any line that doesn't match a known noise pattern.
72
+ *
73
+ * Strategy: remove known-bad lines rather than keep only known-good,
74
+ * so novel agent output is preserved by default.
75
+ */
76
+ function filterToSuccessfulOutput(agentOutput) {
77
+ if (!agentOutput)
78
+ return agentOutput;
79
+ const lines = agentOutput.split("\n");
80
+ const filtered = [];
81
+ let inStackTrace = false;
82
+ for (const line of lines) {
83
+ const trimmed = line.trimStart();
84
+ // Detect start of stack trace blocks (test untrimmed `line` for JS stack traces with leading whitespace)
85
+ if (/^Traceback \(most recent/.test(trimmed) || /^\s+at\s+\S+\s+\(/.test(line)) {
86
+ inStackTrace = true;
87
+ continue;
88
+ }
89
+ // End stack trace on blank line or non-indented line
90
+ if (inStackTrace) {
91
+ if (trimmed === "" || (!trimmed.startsWith(" ") && !trimmed.startsWith("\t"))) {
92
+ inStackTrace = false;
93
+ // Still check if this line itself is noise
94
+ }
95
+ else {
96
+ continue; // Skip stack trace continuation
97
+ }
98
+ }
99
+ // Always keep lines with success signals
100
+ if (SUCCESS_SIGNAL_PATTERNS.some((p) => p.test(trimmed))) {
101
+ filtered.push(line);
102
+ continue;
103
+ }
104
+ // Skip lines matching failure/noise patterns
105
+ if (FAILURE_NOISE_PATTERNS.some((p) => p.test(trimmed))) {
106
+ continue;
107
+ }
108
+ // Keep everything else (default: preserve novel output)
109
+ filtered.push(line);
110
+ }
111
+ // Collapse runs of blank lines to max 2
112
+ const collapsed = [];
113
+ let blankRun = 0;
114
+ for (const line of filtered) {
115
+ if (line.trim() === "") {
116
+ blankRun++;
117
+ if (blankRun <= 2)
118
+ collapsed.push(line);
119
+ }
120
+ else {
121
+ blankRun = 0;
122
+ collapsed.push(line);
123
+ }
124
+ }
125
+ return collapsed.join("\n").trim();
126
+ }
127
+ export async function compressResult(input, strategy = "structured", maxChars = 1000) {
128
+ // Episode quality: filter agent output to successful conclusions only
129
+ // Security: redact secrets from diff and agent output before any compression
130
+ const filtered = {
131
+ ...input,
132
+ agentOutput: filterToSuccessfulOutput(input.agentOutput),
133
+ diff: redactSecrets(input.diff),
134
+ };
135
+ switch (strategy) {
136
+ case "structured":
137
+ return compressStructured(filtered, maxChars);
138
+ case "diff-only":
139
+ return compressDiffOnly(filtered, maxChars);
140
+ case "truncate":
141
+ return compressTruncate(filtered, maxChars);
142
+ case "llm-summary":
143
+ return compressLlmSummary(filtered, maxChars);
144
+ default:
145
+ return compressStructured(filtered, maxChars);
146
+ }
147
+ }
148
+ function compressStructured(input, maxChars) {
149
+ const parts = [];
150
+ // Status line
151
+ parts.push(`Status: ${input.success ? "SUCCESS" : "FAILED"} (${(input.durationMs / 1000).toFixed(1)}s)`);
152
+ if (input.error) {
153
+ parts.push(`Error: ${input.error}`);
154
+ }
155
+ // Files changed
156
+ if (input.filesChanged.length > 0) {
157
+ parts.push(`Files changed (${input.filesChanged.length}):`);
158
+ for (const f of input.filesChanged.slice(0, 20)) {
159
+ parts.push(` - ${f}`);
160
+ }
161
+ if (input.filesChanged.length > 20) {
162
+ parts.push(` ... and ${input.filesChanged.length - 20} more`);
163
+ }
164
+ }
165
+ // Diff stats
166
+ if (input.diffStats && input.diffStats !== "(no changes)") {
167
+ parts.push(`\nDiff stats:\n${input.diffStats}`);
168
+ }
169
+ // Key diff hunks (first portion)
170
+ if (input.diff && input.diff !== "(no changes)") {
171
+ const diffBudget = Math.floor(maxChars * 0.4);
172
+ const truncatedDiff = input.diff.length > diffBudget ? `${input.diff.slice(0, diffBudget)}\n... [diff truncated]` : input.diff;
173
+ parts.push(`\nKey changes:\n${truncatedDiff}`);
174
+ }
175
+ // Agent output tail
176
+ if (input.agentOutput) {
177
+ const outputBudget = Math.floor(maxChars * 0.3);
178
+ const lines = input.agentOutput.split("\n");
179
+ const tail = lines.slice(-30).join("\n");
180
+ const truncatedOutput = tail.length > outputBudget ? tail.slice(-outputBudget) : tail;
181
+ parts.push(`\nAgent output (last 30 lines):\n${truncatedOutput}`);
182
+ }
183
+ const result = parts.join("\n");
184
+ // Final truncation safety (4x maxChars is the hard cap for combined sections)
185
+ if (result.length > maxChars * 4) {
186
+ return `${result.slice(0, maxChars * 4)}\n... [compressed output truncated]`;
187
+ }
188
+ return result;
189
+ }
190
+ function compressDiffOnly(input, maxChars) {
191
+ const status = `Status: ${input.success ? "SUCCESS" : "FAILED"} (${(input.durationMs / 1000).toFixed(1)}s)`;
192
+ if (!input.diff || input.diff === "(no changes)") {
193
+ return `${status}\n(no changes)`;
194
+ }
195
+ if (input.diff.length > maxChars * 4) {
196
+ return `${status}\n${input.diff.slice(0, maxChars * 4)}\n... [diff truncated]`;
197
+ }
198
+ return `${status}\n${input.diff}`;
199
+ }
200
+ function compressTruncate(input, maxChars) {
201
+ const raw = [`Status: ${input.success ? "SUCCESS" : "FAILED"}`, input.agentOutput, input.diff]
202
+ .filter(Boolean)
203
+ .join("\n\n");
204
+ if (raw.length > maxChars * 4) {
205
+ // Preserve status line at the head, truncate from the middle
206
+ const statusEnd = raw.indexOf("\n");
207
+ const statusLine = statusEnd !== -1 ? raw.slice(0, statusEnd) : "";
208
+ const remaining = maxChars * 4 - statusLine.length - 20;
209
+ return `${statusLine}\n... [truncated]\n${raw.slice(-remaining)}`;
210
+ }
211
+ return raw;
212
+ }
213
+ /**
214
+ * LLM-based compression — uses a cheap model to summarize the thread's work.
215
+ * Falls back to structured compression if no summarizer is registered.
216
+ */
217
+ async function compressLlmSummary(input, maxChars) {
218
+ if (!_summarizer) {
219
+ // Fall back to structured if no summarizer available
220
+ return compressStructured(input, maxChars);
221
+ }
222
+ // Build the text to summarize
223
+ const parts = [];
224
+ parts.push(`Task outcome: ${input.success ? "SUCCESS" : "FAILED"} (${(input.durationMs / 1000).toFixed(1)}s)`);
225
+ if (input.error) {
226
+ parts.push(`Error: ${input.error}`);
227
+ }
228
+ if (input.filesChanged.length > 0) {
229
+ parts.push(`Files changed: ${input.filesChanged.join(", ")}`);
230
+ }
231
+ if (input.diffStats && input.diffStats !== "(no changes)") {
232
+ parts.push(`Diff stats:\n${input.diffStats}`);
233
+ }
234
+ // Include truncated diff for context
235
+ if (input.diff && input.diff !== "(no changes)") {
236
+ const diffSlice = input.diff.slice(0, maxChars * 2);
237
+ parts.push(`Diff:\n${diffSlice}`);
238
+ }
239
+ // Include truncated agent output
240
+ if (input.agentOutput) {
241
+ const outputSlice = input.agentOutput.slice(-maxChars);
242
+ parts.push(`Agent output (tail):\n${outputSlice}`);
243
+ }
244
+ const textToSummarize = parts.join("\n\n");
245
+ const instruction = [
246
+ "Summarize this coding agent thread result concisely.",
247
+ "Include: what was done, which files were changed, whether it succeeded, and any key details.",
248
+ `Keep the summary under ${maxChars} characters.`,
249
+ "Be specific about code changes — mention function names, patterns, and key decisions.",
250
+ ].join(" ");
251
+ try {
252
+ const summary = await _summarizer(textToSummarize, instruction);
253
+ // Prepend status line
254
+ const status = `Status: ${input.success ? "SUCCESS" : "FAILED"} (${(input.durationMs / 1000).toFixed(1)}s)`;
255
+ const filesLine = input.filesChanged.length > 0 ? `\nFiles: ${input.filesChanged.join(", ")}` : "";
256
+ const result = `${status}${filesLine}\n\n${summary}`;
257
+ // Safety cap
258
+ if (result.length > maxChars * 2) {
259
+ return `${result.slice(0, maxChars * 2)}\n... [summary truncated]`;
260
+ }
261
+ return result;
262
+ }
263
+ catch {
264
+ // Fall back to structured on LLM failure
265
+ return compressStructured(input, maxChars);
266
+ }
267
+ }
268
+ //# sourceMappingURL=compressor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compressor.js","sourceRoot":"","sources":["../../src/compression/compressor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Configuration loader for swarm-code.
3
+ *
4
+ * Reads swarm_config.yaml (or rlm_config.yaml fallback) from project root or cwd.
5
+ * Extends RLM config with swarm-specific fields.
6
+ */
7
+ /** Named model slot overrides — lets users assign specific models per task type. */
8
+ export interface ModelSlots {
9
+ execution: string;
10
+ search: string;
11
+ reasoning: string;
12
+ planning: string;
13
+ }
14
+ export interface SwarmConfig {
15
+ max_iterations: number;
16
+ max_depth: number;
17
+ max_sub_queries: number;
18
+ truncate_len: number;
19
+ metadata_preview_lines: number;
20
+ max_threads: number;
21
+ max_total_threads: number;
22
+ thread_timeout_ms: number;
23
+ max_thread_budget_usd: number;
24
+ max_session_budget_usd: number;
25
+ default_agent: string;
26
+ default_model: string;
27
+ auto_model_selection: boolean;
28
+ compression_strategy: "structured" | "llm-summary" | "diff-only" | "truncate";
29
+ compression_max_tokens: number;
30
+ worktree_base_dir: string;
31
+ auto_cleanup_worktrees: boolean;
32
+ episodic_memory_enabled: boolean;
33
+ memory_dir: string;
34
+ thread_retries: number;
35
+ model_slots: ModelSlots;
36
+ thread_cache_persist: boolean;
37
+ thread_cache_dir: string;
38
+ thread_cache_ttl_hours: number;
39
+ opencode_server_mode: boolean;
40
+ allow_hooks: boolean;
41
+ }
42
+ export type RlmConfig = SwarmConfig;
43
+ export declare function loadConfig(cwd?: string): SwarmConfig;
package/dist/config.js ADDED
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Configuration loader for swarm-code.
3
+ *
4
+ * Reads swarm_config.yaml (or rlm_config.yaml fallback) from project root or cwd.
5
+ * Extends RLM config with swarm-specific fields.
6
+ */
7
+ import * as fs from "node:fs";
8
+ import * as os from "node:os";
9
+ import * as path from "node:path";
10
+ import { fileURLToPath } from "node:url";
11
+ const DEFAULTS = {
12
+ // RLM defaults
13
+ max_iterations: 20,
14
+ max_depth: 3,
15
+ max_sub_queries: 50,
16
+ truncate_len: 5000,
17
+ metadata_preview_lines: 20,
18
+ // Swarm defaults
19
+ max_threads: 5,
20
+ max_total_threads: 20,
21
+ thread_timeout_ms: 300000,
22
+ max_thread_budget_usd: 1.0,
23
+ max_session_budget_usd: 10.0,
24
+ default_agent: "opencode",
25
+ default_model: "anthropic/claude-sonnet-4-6",
26
+ auto_model_selection: true,
27
+ compression_strategy: "structured",
28
+ compression_max_tokens: 1000,
29
+ worktree_base_dir: ".swarm-worktrees",
30
+ auto_cleanup_worktrees: true,
31
+ episodic_memory_enabled: false,
32
+ memory_dir: path.join(os.homedir(), ".swarm", "memory"),
33
+ thread_retries: 1,
34
+ model_slots: {
35
+ execution: "", // empty = use agent's default based on complexity
36
+ search: "",
37
+ reasoning: "",
38
+ planning: "",
39
+ },
40
+ thread_cache_persist: false,
41
+ thread_cache_dir: path.join(os.homedir(), ".swarm", "cache"),
42
+ thread_cache_ttl_hours: 24,
43
+ opencode_server_mode: true,
44
+ allow_hooks: false,
45
+ };
46
+ function parseYaml(text) {
47
+ // Minimal YAML parser for flat key:value files (no nested objects, no arrays)
48
+ const result = {};
49
+ for (const line of text.split("\n")) {
50
+ const trimmed = line.trim();
51
+ if (!trimmed || trimmed.startsWith("#"))
52
+ continue;
53
+ const colonIdx = trimmed.indexOf(":");
54
+ if (colonIdx === -1)
55
+ continue;
56
+ const key = trimmed.slice(0, colonIdx).trim();
57
+ const rawVal = trimmed.slice(colonIdx + 1).trim();
58
+ // Strip inline comments (but not inside quoted strings)
59
+ let val;
60
+ if ((rawVal.startsWith('"') && rawVal.includes('"', 1)) || (rawVal.startsWith("'") && rawVal.includes("'", 1))) {
61
+ // Quoted value — don't strip inline comments
62
+ val = rawVal;
63
+ }
64
+ else {
65
+ val = rawVal.replace(/\s+#.*$/, "");
66
+ }
67
+ // Parse number
68
+ const num = Number(val);
69
+ if (!Number.isNaN(num) && val !== "") {
70
+ result[key] = num;
71
+ }
72
+ else if (val === "true") {
73
+ result[key] = true;
74
+ }
75
+ else if (val === "false") {
76
+ result[key] = false;
77
+ }
78
+ else {
79
+ // Strip quotes
80
+ result[key] = val.replace(/^["']|["']$/g, "");
81
+ }
82
+ }
83
+ return result;
84
+ }
85
+ export function loadConfig(cwd) {
86
+ // Search order: cwd swarm_config, cwd rlm_config, package root swarm_config, package root rlm_config
87
+ // User prefs (~/.swarm/config.yaml) are overlaid on top of the first found project config
88
+ const projectDir = cwd || process.cwd();
89
+ const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
90
+ const userConfigPath = path.join(os.homedir(), ".swarm", "config.yaml");
91
+ const candidates = [
92
+ path.resolve(projectDir, "swarm_config.yaml"),
93
+ path.resolve(projectDir, "rlm_config.yaml"),
94
+ path.resolve(pkgRoot, "swarm_config.yaml"),
95
+ path.resolve(pkgRoot, "rlm_config.yaml"),
96
+ ];
97
+ for (const configPath of candidates) {
98
+ if (fs.existsSync(configPath)) {
99
+ try {
100
+ const raw = fs.readFileSync(configPath, "utf-8");
101
+ let parsed = parseYaml(raw);
102
+ // Overlay user preferences from ~/.swarm/config.yaml
103
+ if (fs.existsSync(userConfigPath)) {
104
+ try {
105
+ const userRaw = fs.readFileSync(userConfigPath, "utf-8");
106
+ const userParsed = parseYaml(userRaw);
107
+ parsed = { ...parsed, ...userParsed };
108
+ }
109
+ catch {
110
+ /* ignore malformed user config */
111
+ }
112
+ }
113
+ const clamp = (v, min, max, def) => typeof v === "number" && Number.isFinite(v) ? Math.max(min, Math.min(max, Math.round(v))) : def;
114
+ const str = (v, def) => (typeof v === "string" && v.length > 0 ? v : def);
115
+ const bool = (v, def) => (typeof v === "boolean" ? v : def);
116
+ const validStrategies = ["structured", "llm-summary", "diff-only", "truncate"];
117
+ const strategyVal = str(parsed.compression_strategy, DEFAULTS.compression_strategy);
118
+ const strategy = validStrategies.includes(strategyVal)
119
+ ? strategyVal
120
+ : DEFAULTS.compression_strategy;
121
+ return {
122
+ // RLM fields
123
+ max_iterations: clamp(parsed.max_iterations, 1, 100, DEFAULTS.max_iterations),
124
+ max_depth: clamp(parsed.max_depth, 1, 10, DEFAULTS.max_depth),
125
+ max_sub_queries: clamp(parsed.max_sub_queries, 1, 500, DEFAULTS.max_sub_queries),
126
+ truncate_len: clamp(parsed.truncate_len, 500, 50000, DEFAULTS.truncate_len),
127
+ metadata_preview_lines: clamp(parsed.metadata_preview_lines, 5, 100, DEFAULTS.metadata_preview_lines),
128
+ // Swarm fields
129
+ max_threads: clamp(parsed.max_threads, 1, 20, DEFAULTS.max_threads),
130
+ max_total_threads: clamp(parsed.max_total_threads, 1, 100, DEFAULTS.max_total_threads),
131
+ thread_timeout_ms: clamp(parsed.thread_timeout_ms, 10000, 3600000, DEFAULTS.thread_timeout_ms),
132
+ max_thread_budget_usd: typeof parsed.max_thread_budget_usd === "number" &&
133
+ Number.isFinite(parsed.max_thread_budget_usd) &&
134
+ parsed.max_thread_budget_usd > 0
135
+ ? parsed.max_thread_budget_usd
136
+ : DEFAULTS.max_thread_budget_usd,
137
+ max_session_budget_usd: typeof parsed.max_session_budget_usd === "number" &&
138
+ Number.isFinite(parsed.max_session_budget_usd) &&
139
+ parsed.max_session_budget_usd > 0
140
+ ? parsed.max_session_budget_usd
141
+ : DEFAULTS.max_session_budget_usd,
142
+ default_agent: str(parsed.default_agent, DEFAULTS.default_agent),
143
+ default_model: str(parsed.default_model, DEFAULTS.default_model),
144
+ auto_model_selection: bool(parsed.auto_model_selection, DEFAULTS.auto_model_selection),
145
+ compression_strategy: strategy,
146
+ compression_max_tokens: clamp(parsed.compression_max_tokens, 100, 10000, DEFAULTS.compression_max_tokens),
147
+ worktree_base_dir: str(parsed.worktree_base_dir, DEFAULTS.worktree_base_dir),
148
+ auto_cleanup_worktrees: bool(parsed.auto_cleanup_worktrees, DEFAULTS.auto_cleanup_worktrees),
149
+ episodic_memory_enabled: bool(parsed.episodic_memory_enabled, DEFAULTS.episodic_memory_enabled),
150
+ memory_dir: str(parsed.memory_dir, DEFAULTS.memory_dir),
151
+ thread_retries: clamp(parsed.thread_retries, 0, 3, DEFAULTS.thread_retries),
152
+ model_slots: {
153
+ execution: str(parsed.model_slot_execution, DEFAULTS.model_slots.execution),
154
+ search: str(parsed.model_slot_search, DEFAULTS.model_slots.search),
155
+ reasoning: str(parsed.model_slot_reasoning, DEFAULTS.model_slots.reasoning),
156
+ planning: str(parsed.model_slot_planning, DEFAULTS.model_slots.planning),
157
+ },
158
+ thread_cache_persist: bool(parsed.thread_cache_persist, DEFAULTS.thread_cache_persist),
159
+ thread_cache_dir: str(parsed.thread_cache_dir, DEFAULTS.thread_cache_dir),
160
+ thread_cache_ttl_hours: clamp(parsed.thread_cache_ttl_hours, 1, 720, DEFAULTS.thread_cache_ttl_hours),
161
+ opencode_server_mode: bool(parsed.opencode_server_mode, DEFAULTS.opencode_server_mode),
162
+ allow_hooks: bool(parsed.allow_hooks, DEFAULTS.allow_hooks),
163
+ };
164
+ }
165
+ catch {
166
+ // Fall through to defaults
167
+ }
168
+ }
169
+ }
170
+ return { ...DEFAULTS };
171
+ }
172
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { type SelectorOptions } from "./selector.js";
2
+ /** Soft compatibility budget; selected bodies are never sliced. */
3
+ export declare const MAX_TOTAL_SKILLS_CHARS = 14000;
4
+ export declare function findAgentsDir(projectRoot: string): string | null;
5
+ export interface BuildPromptOptions extends SelectorOptions {
6
+ /** Soft limit for selected skill bodies; overflow is reported, never truncated. */
7
+ maxTotalSkillsChars?: number;
8
+ /** Hard limit for the entire assembled prompt. Overflow throws with a report. */
9
+ hardLimitChars?: number;
10
+ }
11
+ export interface ContextSource {
12
+ kind: "bootstrap" | "rule" | "skill";
13
+ id: string;
14
+ path: string;
15
+ sha256: string;
16
+ bytes: number;
17
+ chars: number;
18
+ }
19
+ export interface ContextAssemblyReport {
20
+ sources: ContextSource[];
21
+ warnings: Array<{
22
+ code: string;
23
+ message: string;
24
+ }>;
25
+ omissions: Array<{
26
+ id: string;
27
+ reasonCode: string;
28
+ }>;
29
+ totalChars: number;
30
+ skillChars: number;
31
+ /** Character estimate, not provider token telemetry. */
32
+ estimatedTokens: number;
33
+ softSkillLimitChars: number;
34
+ hardLimitChars?: number;
35
+ }
36
+ export declare class ContextAssemblyError extends Error {
37
+ readonly code: string;
38
+ readonly report: ContextAssemblyReport;
39
+ constructor(code: string, message: string, report: ContextAssemblyReport);
40
+ }
41
+ export declare function assembleContextPrompt(projectRoot: string, task: string, options?: BuildPromptOptions): {
42
+ prompt: string;
43
+ report: ContextAssemblyReport;
44
+ };
45
+ /** Compatibility wrapper for existing agent call sites. */
46
+ export declare function buildContextPrompt(projectRoot: string, task: string, options?: BuildPromptOptions): string;