agentic-flow 3.1.0 → 3.2.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 (72) hide show
  1. package/.agents/skills/agentic-flow-ecosystem/SKILL.md +50 -0
  2. package/.claude/skills/agentic-flow-ecosystem/skill.md +58 -0
  3. package/.claude/skills/agentic-flow-quickstart/skill.md +6 -6
  4. package/.claude/skills/hooks-automation/skill.md +11 -11
  5. package/.claude/skills/memory-patterns/skill.md +7 -7
  6. package/.claude/skills/sparc-methodology/skill.md +13 -13
  7. package/.claude/skills/swarm-coordination/skill.md +5 -5
  8. package/.claude/skills/worker-benchmarks/skill.md +5 -5
  9. package/.claude/skills/worker-integration/skill.md +5 -5
  10. package/CHANGELOG.md +25 -0
  11. package/README.md +82 -67
  12. package/dist/.tsbuildinfo +1 -1
  13. package/dist/cli/commands/init.d.ts.map +1 -1
  14. package/dist/cli/commands/init.js +9 -0
  15. package/dist/cli/commands/init.js.map +1 -1
  16. package/dist/core/agentdb-fast.d.ts +21 -11
  17. package/dist/core/agentdb-fast.d.ts.map +1 -1
  18. package/dist/core/agentdb-fast.js +39 -14
  19. package/dist/core/agentdb-fast.js.map +1 -1
  20. package/dist/integrations/agent-booster.d.ts +35 -0
  21. package/dist/integrations/agent-booster.d.ts.map +1 -0
  22. package/dist/integrations/agent-booster.js +45 -0
  23. package/dist/integrations/agent-booster.js.map +1 -0
  24. package/dist/integrations/index.d.ts +15 -0
  25. package/dist/integrations/index.d.ts.map +1 -0
  26. package/dist/integrations/index.js +11 -0
  27. package/dist/integrations/index.js.map +1 -0
  28. package/dist/integrations/onnx-wasm-embedder.d.ts +59 -0
  29. package/dist/integrations/onnx-wasm-embedder.d.ts.map +1 -0
  30. package/dist/integrations/onnx-wasm-embedder.js +145 -0
  31. package/dist/integrations/onnx-wasm-embedder.js.map +1 -0
  32. package/dist/integrations/optional.d.ts +44 -0
  33. package/dist/integrations/optional.d.ts.map +1 -0
  34. package/dist/integrations/optional.js +107 -0
  35. package/dist/integrations/optional.js.map +1 -0
  36. package/dist/integrations/prompt-injection.d.ts +52 -0
  37. package/dist/integrations/prompt-injection.d.ts.map +1 -0
  38. package/dist/integrations/prompt-injection.js +126 -0
  39. package/dist/integrations/prompt-injection.js.map +1 -0
  40. package/dist/integrations/sublinear.d.ts +71 -0
  41. package/dist/integrations/sublinear.d.ts.map +1 -0
  42. package/dist/integrations/sublinear.js +227 -0
  43. package/dist/integrations/sublinear.js.map +1 -0
  44. package/dist/integrations/task-partition.d.ts +40 -0
  45. package/dist/integrations/task-partition.d.ts.map +1 -0
  46. package/dist/integrations/task-partition.js +173 -0
  47. package/dist/integrations/task-partition.js.map +1 -0
  48. package/dist/mcp/mcp-policy.d.ts.map +1 -1
  49. package/dist/mcp/mcp-policy.js +2 -0
  50. package/dist/mcp/mcp-policy.js.map +1 -1
  51. package/dist/mcp/standalone-stdio.js +12 -26
  52. package/dist/mcp/standalone-stdio.js.map +1 -1
  53. package/dist/mcp/tools/ecosystem-tools.d.ts +49 -0
  54. package/dist/mcp/tools/ecosystem-tools.d.ts.map +1 -0
  55. package/dist/mcp/tools/ecosystem-tools.js +126 -0
  56. package/dist/mcp/tools/ecosystem-tools.js.map +1 -0
  57. package/dist/routing/SemanticRouter.d.ts +25 -9
  58. package/dist/routing/SemanticRouter.d.ts.map +1 -1
  59. package/dist/routing/SemanticRouter.js +63 -12
  60. package/dist/routing/SemanticRouter.js.map +1 -1
  61. package/dist/utils/input-validator.d.ts +10 -2
  62. package/dist/utils/input-validator.d.ts.map +1 -1
  63. package/dist/utils/input-validator.js +30 -2
  64. package/dist/utils/input-validator.js.map +1 -1
  65. package/dist/utils/model-cache.d.ts.map +1 -1
  66. package/dist/utils/model-cache.js +6 -25
  67. package/dist/utils/model-cache.js.map +1 -1
  68. package/dist/wasm/onnx-embeddings-wasm.d.ts.map +1 -1
  69. package/dist/wasm/onnx-embeddings-wasm.js +21 -10
  70. package/dist/wasm/onnx-embeddings-wasm.js.map +1 -1
  71. package/docs/integrations/FASTMCP_CLI_INTEGRATION.md +1 -1
  72. package/package.json +12 -7
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Linear solves and PageRank through `sublinear-time-solver`, verified.
3
+ *
4
+ * sublinear-time-solver (optionalDependency, ~120 MB installed with its own
5
+ * deps) solves diagonally dominant systems with push / random-walk methods.
6
+ * Measured against 1.7.2: `forward-push` is accurate, but the default
7
+ * `neumann` method returned a wrong answer with `converged: false` and
8
+ * `random-walk` threw, and the package logs banners with `console.log`. So:
9
+ * - only `forward-push` is used;
10
+ * - every answer is checked against the residual ||Mx - b||_inf here, and a
11
+ * built-in Gauss-Seidel solve replaces it when the check fails;
12
+ * - the import, construction and solve run with console output sent to stderr
13
+ * (the MCP stdio server owns stdout).
14
+ *
15
+ * The 5 bundled `sublinear/*` agents name sublinear-time-solver tools; the
16
+ * `sublinear_solve` / `sublinear_pagerank` MCP tools in this package give them
17
+ * a working in-process path without a separate MCP server.
18
+ */
19
+ export interface SparseEntry {
20
+ row: number;
21
+ col: number;
22
+ value: number;
23
+ }
24
+ export type MatrixInput = number[][] | {
25
+ size: number;
26
+ entries: SparseEntry[];
27
+ };
28
+ export interface LinearSolveResult {
29
+ solution: number[];
30
+ /** max_i |(Mx - b)_i| */
31
+ residual: number;
32
+ converged: boolean;
33
+ iterations: number;
34
+ diagonallyDominant: boolean;
35
+ engine: 'sublinear-time-solver' | 'builtin';
36
+ /** Set when the library answered but failed verification. */
37
+ libraryRejected?: string;
38
+ }
39
+ /**
40
+ * Solve Mx = b. Intended for (row) diagonally dominant M; other matrices are
41
+ * attempted with Gauss-Seidel and reported with `converged: false` if it fails.
42
+ */
43
+ export declare function solveLinearSystem(matrix: MatrixInput, b: number[], options?: {
44
+ tolerance?: number;
45
+ maxIterations?: number;
46
+ engine?: 'auto' | 'builtin';
47
+ }): Promise<LinearSolveResult>;
48
+ export interface PageRankResult {
49
+ scores: Record<string, number>;
50
+ ranking: Array<{
51
+ node: string;
52
+ score: number;
53
+ }>;
54
+ engine: LinearSolveResult['engine'];
55
+ residual: number;
56
+ }
57
+ /**
58
+ * PageRank over a directed graph as a linear system:
59
+ * (I - d·Pᵀ) y = 1, then scores = y / Σy. With dangling rows left at zero this
60
+ * equals PageRank with uniform teleport from dangling nodes.
61
+ */
62
+ export declare function pageRank(edges: Array<{
63
+ from: string;
64
+ to: string;
65
+ weight?: number;
66
+ }>, options?: {
67
+ damping?: number;
68
+ nodes?: string[];
69
+ engine?: 'auto' | 'builtin';
70
+ }): Promise<PageRankResult>;
71
+ //# sourceMappingURL=sublinear.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sublinear.d.ts","sourceRoot":"","sources":["../../src/integrations/sublinear.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,EAAE,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AAEhF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,MAAM,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC5C,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAsGD;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,WAAW,EACnB,CAAC,EAAE,MAAM,EAAE,EACX,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GACxF,OAAO,CAAC,iBAAiB,CAAC,CAsC5B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC3D,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAChF,OAAO,CAAC,cAAc,CAAC,CA8CzB"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Linear solves and PageRank through `sublinear-time-solver`, verified.
3
+ *
4
+ * sublinear-time-solver (optionalDependency, ~120 MB installed with its own
5
+ * deps) solves diagonally dominant systems with push / random-walk methods.
6
+ * Measured against 1.7.2: `forward-push` is accurate, but the default
7
+ * `neumann` method returned a wrong answer with `converged: false` and
8
+ * `random-walk` threw, and the package logs banners with `console.log`. So:
9
+ * - only `forward-push` is used;
10
+ * - every answer is checked against the residual ||Mx - b||_inf here, and a
11
+ * built-in Gauss-Seidel solve replaces it when the check fails;
12
+ * - the import, construction and solve run with console output sent to stderr
13
+ * (the MCP stdio server owns stdout).
14
+ *
15
+ * The 5 bundled `sublinear/*` agents name sublinear-time-solver tools; the
16
+ * `sublinear_solve` / `sublinear_pagerank` MCP tools in this package give them
17
+ * a working in-process path without a separate MCP server.
18
+ */
19
+ import { importOptional, withStdoutToStderr } from './optional.js';
20
+ function toCsr(m) {
21
+ if (Array.isArray(m)) {
22
+ const n = m.length;
23
+ const rows = m.map((row, i) => {
24
+ if (!Array.isArray(row) || row.length !== n)
25
+ throw new Error(`matrix must be square; row ${i} has ${row?.length}`);
26
+ const out = [];
27
+ row.forEach((v, j) => {
28
+ if (!Number.isFinite(v))
29
+ throw new Error(`matrix[${i}][${j}] is not finite`);
30
+ if (v !== 0)
31
+ out.push([j, v]);
32
+ });
33
+ return out;
34
+ });
35
+ return { n, rows, diag: m.map((row, i) => row[i]) };
36
+ }
37
+ const n = m.size;
38
+ if (!Number.isInteger(n) || n < 1)
39
+ throw new Error('size must be a positive integer');
40
+ const acc = Array.from({ length: n }, () => new Map());
41
+ for (const { row, col, value } of m.entries) {
42
+ if (!Number.isInteger(row) || !Number.isInteger(col) || row < 0 || col < 0 || row >= n || col >= n) {
43
+ throw new Error(`entry (${row}, ${col}) is outside a ${n}x${n} matrix`);
44
+ }
45
+ if (!Number.isFinite(value))
46
+ throw new Error(`entry (${row}, ${col}) is not finite`);
47
+ acc[row].set(col, (acc[row].get(col) ?? 0) + value);
48
+ }
49
+ const rows = acc.map((r) => [...r.entries()].filter(([, v]) => v !== 0));
50
+ return { n, rows, diag: acc.map((r, i) => r.get(i) ?? 0) };
51
+ }
52
+ function residualInf(a, x, b) {
53
+ let worst = 0;
54
+ for (let i = 0; i < a.n; i++) {
55
+ let s = 0;
56
+ for (const [j, v] of a.rows[i])
57
+ s += v * x[j];
58
+ worst = Math.max(worst, Math.abs(s - b[i]));
59
+ }
60
+ return worst;
61
+ }
62
+ function isDiagonallyDominant(a) {
63
+ return a.rows.every((row, i) => {
64
+ let off = 0;
65
+ for (const [j, v] of row)
66
+ if (j !== i)
67
+ off += Math.abs(v);
68
+ return Math.abs(a.diag[i]) >= off && a.diag[i] !== 0;
69
+ });
70
+ }
71
+ function gaussSeidel(a, b, tol, maxIterations) {
72
+ const x = new Array(a.n).fill(0);
73
+ let it = 0;
74
+ for (; it < maxIterations; it++) {
75
+ for (let i = 0; i < a.n; i++) {
76
+ if (a.diag[i] === 0)
77
+ throw new Error(`zero diagonal at row ${i}: Gauss-Seidel needs a nonzero diagonal`);
78
+ let s = b[i];
79
+ for (const [j, v] of a.rows[i])
80
+ if (j !== i)
81
+ s -= v * x[j];
82
+ x[i] = s / a.diag[i];
83
+ }
84
+ if (residualInf(a, x, b) <= tol)
85
+ return { x, iterations: it + 1 };
86
+ }
87
+ return { x, iterations: it };
88
+ }
89
+ const solverCache = new Map();
90
+ async function librarySolve(a, b, tol, maxIterations) {
91
+ return withStdoutToStderr(async () => {
92
+ const mod = await importOptional('sublinear-time-solver/core', { quietStdout: true });
93
+ const Solver = mod?.SublinearSolver;
94
+ if (typeof Solver !== 'function')
95
+ return null;
96
+ const key = `${tol}|${maxIterations}`;
97
+ let solver = solverCache.get(key);
98
+ if (!solver) {
99
+ solver = new Solver({ method: 'forward-push', epsilon: tol, maxIterations });
100
+ // The constructor starts WASM probing asynchronously and logs when it
101
+ // finishes; let that settle while console output is still redirected.
102
+ await solver.initializeWasm?.().catch(() => undefined);
103
+ await new Promise((r) => setTimeout(r, 0));
104
+ if (solverCache.size > 8)
105
+ solverCache.clear();
106
+ solverCache.set(key, solver);
107
+ }
108
+ const values = [];
109
+ const rowIndices = [];
110
+ const colIndices = [];
111
+ a.rows.forEach((row, i) => {
112
+ for (const [j, v] of row) {
113
+ values.push(v);
114
+ rowIndices.push(i);
115
+ colIndices.push(j);
116
+ }
117
+ });
118
+ const res = await solver.solve({ rows: a.n, cols: a.n, values, rowIndices, colIndices, format: 'coo' }, b);
119
+ return Array.isArray(res?.solution) ? res.solution.map(Number) : null;
120
+ });
121
+ }
122
+ /**
123
+ * Solve Mx = b. Intended for (row) diagonally dominant M; other matrices are
124
+ * attempted with Gauss-Seidel and reported with `converged: false` if it fails.
125
+ */
126
+ export async function solveLinearSystem(matrix, b, options = {}) {
127
+ const a = toCsr(matrix);
128
+ if (!Array.isArray(b) || b.length !== a.n)
129
+ throw new Error(`vector length ${b?.length} != matrix size ${a.n}`);
130
+ if (!b.every(Number.isFinite))
131
+ throw new Error('vector entries must be finite');
132
+ const tol = options.tolerance ?? 1e-8;
133
+ const maxIterations = Math.min(options.maxIterations ?? 10000, 1_000_000);
134
+ // Residual tolerance scaled to the problem: absolute tol on ||b||_inf ~ 1.
135
+ const scale = Math.max(1, ...b.map(Math.abs));
136
+ const accept = tol * scale * 10;
137
+ const diagonallyDominant = isDiagonallyDominant(a);
138
+ let libraryRejected;
139
+ if (options.engine !== 'builtin') {
140
+ try {
141
+ const x = await librarySolve(a, b, tol, maxIterations);
142
+ if (x && x.length === a.n && x.every(Number.isFinite)) {
143
+ const r = residualInf(a, x, b);
144
+ if (r <= accept) {
145
+ return { solution: x, residual: r, converged: true, iterations: 0, diagonallyDominant, engine: 'sublinear-time-solver' };
146
+ }
147
+ libraryRejected = `residual ${r.toExponential(2)} above ${accept.toExponential(2)}`;
148
+ }
149
+ }
150
+ catch (err) {
151
+ libraryRejected = err?.message ?? String(err);
152
+ }
153
+ }
154
+ const { x, iterations } = gaussSeidel(a, b, accept, maxIterations);
155
+ const residual = residualInf(a, x, b);
156
+ return {
157
+ solution: x,
158
+ residual,
159
+ converged: residual <= accept,
160
+ iterations,
161
+ diagonallyDominant,
162
+ engine: 'builtin',
163
+ ...(libraryRejected ? { libraryRejected } : {}),
164
+ };
165
+ }
166
+ /**
167
+ * PageRank over a directed graph as a linear system:
168
+ * (I - d·Pᵀ) y = 1, then scores = y / Σy. With dangling rows left at zero this
169
+ * equals PageRank with uniform teleport from dangling nodes.
170
+ */
171
+ export async function pageRank(edges, options = {}) {
172
+ const d = options.damping ?? 0.85;
173
+ if (!(d > 0 && d < 1))
174
+ throw new Error('damping must be in (0, 1)');
175
+ const ids = new Map();
176
+ const names = [];
177
+ const add = (s) => {
178
+ if (!ids.has(s)) {
179
+ ids.set(s, names.length);
180
+ names.push(s);
181
+ }
182
+ return ids.get(s);
183
+ };
184
+ for (const n of options.nodes ?? [])
185
+ add(String(n));
186
+ const out = [];
187
+ for (const e of edges) {
188
+ const w = e.weight ?? 1;
189
+ if (!Number.isFinite(w) || w < 0)
190
+ throw new Error(`invalid edge weight ${w}`);
191
+ const a = add(String(e.from));
192
+ const b = add(String(e.to));
193
+ while (out.length < names.length)
194
+ out.push(new Map());
195
+ out[a].set(b, (out[a].get(b) ?? 0) + w);
196
+ }
197
+ while (out.length < names.length)
198
+ out.push(new Map());
199
+ const n = names.length;
200
+ if (n === 0)
201
+ return { scores: {}, ranking: [], engine: 'builtin', residual: 0 };
202
+ // M = I - d * P^T, P row-normalised out-links.
203
+ const entries = [];
204
+ for (let i = 0; i < n; i++)
205
+ entries.push({ row: i, col: i, value: 1 });
206
+ out.forEach((links, src) => {
207
+ let total = 0;
208
+ for (const w of links.values())
209
+ total += w;
210
+ if (total === 0)
211
+ return;
212
+ for (const [dst, w] of links)
213
+ entries.push({ row: dst, col: src, value: -d * (w / total) });
214
+ });
215
+ const res = await solveLinearSystem({ size: n, entries }, new Array(n).fill(1), {
216
+ tolerance: 1e-10,
217
+ engine: options.engine,
218
+ });
219
+ const sum = res.solution.reduce((s, v) => s + v, 0) || 1;
220
+ const scores = {};
221
+ names.forEach((name, i) => (scores[name] = res.solution[i] / sum));
222
+ const ranking = names
223
+ .map((node) => ({ node, score: scores[node] }))
224
+ .sort((x, y) => y.score - x.score);
225
+ return { scores, ranking, engine: res.engine, residual: res.residual };
226
+ }
227
+ //# sourceMappingURL=sublinear.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sublinear.js","sourceRoot":"","sources":["../../src/integrations/sublinear.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Linear solves and PageRank through `sublinear-time-solver`, verified.\n *\n * sublinear-time-solver (optionalDependency, ~120 MB installed with its own\n * deps) solves diagonally dominant systems with push / random-walk methods.\n * Measured against 1.7.2: `forward-push` is accurate, but the default\n * `neumann` method returned a wrong answer with `converged: false` and\n * `random-walk` threw, and the package logs banners with `console.log`. So:\n * - only `forward-push` is used;\n * - every answer is checked against the residual ||Mx - b||_inf here, and a\n * built-in Gauss-Seidel solve replaces it when the check fails;\n * - the import, construction and solve run with console output sent to stderr\n * (the MCP stdio server owns stdout).\n *\n * The 5 bundled `sublinear/*` agents name sublinear-time-solver tools; the\n * `sublinear_solve` / `sublinear_pagerank` MCP tools in this package give them\n * a working in-process path without a separate MCP server.\n */\n\nimport { importOptional, withStdoutToStderr } from './optional.js';\n\nexport interface SparseEntry {\n row: number;\n col: number;\n value: number;\n}\n\nexport type MatrixInput = number[][] | { size: number; entries: SparseEntry[] };\n\nexport interface LinearSolveResult {\n solution: number[];\n /** max_i |(Mx - b)_i| */\n residual: number;\n converged: boolean;\n iterations: number;\n diagonallyDominant: boolean;\n engine: 'sublinear-time-solver' | 'builtin';\n /** Set when the library answered but failed verification. */\n libraryRejected?: string;\n}\n\ninterface Csr {\n n: number;\n rows: Array<Array<[number, number]>>; // per row: [col, value]\n diag: number[];\n}\n\nfunction toCsr(m: MatrixInput): Csr {\n if (Array.isArray(m)) {\n const n = m.length;\n const rows = m.map((row, i) => {\n if (!Array.isArray(row) || row.length !== n) throw new Error(`matrix must be square; row ${i} has ${row?.length}`);\n const out: Array<[number, number]> = [];\n row.forEach((v, j) => {\n if (!Number.isFinite(v)) throw new Error(`matrix[${i}][${j}] is not finite`);\n if (v !== 0) out.push([j, v]);\n });\n return out;\n });\n return { n, rows, diag: m.map((row, i) => row[i]) };\n }\n const n = m.size;\n if (!Number.isInteger(n) || n < 1) throw new Error('size must be a positive integer');\n const acc: Array<Map<number, number>> = Array.from({ length: n }, () => new Map());\n for (const { row, col, value } of m.entries) {\n if (!Number.isInteger(row) || !Number.isInteger(col) || row < 0 || col < 0 || row >= n || col >= n) {\n throw new Error(`entry (${row}, ${col}) is outside a ${n}x${n} matrix`);\n }\n if (!Number.isFinite(value)) throw new Error(`entry (${row}, ${col}) is not finite`);\n acc[row].set(col, (acc[row].get(col) ?? 0) + value);\n }\n const rows = acc.map((r) => [...r.entries()].filter(([, v]) => v !== 0));\n return { n, rows, diag: acc.map((r, i) => r.get(i) ?? 0) };\n}\n\nfunction residualInf(a: Csr, x: number[], b: number[]): number {\n let worst = 0;\n for (let i = 0; i < a.n; i++) {\n let s = 0;\n for (const [j, v] of a.rows[i]) s += v * x[j];\n worst = Math.max(worst, Math.abs(s - b[i]));\n }\n return worst;\n}\n\nfunction isDiagonallyDominant(a: Csr): boolean {\n return a.rows.every((row, i) => {\n let off = 0;\n for (const [j, v] of row) if (j !== i) off += Math.abs(v);\n return Math.abs(a.diag[i]) >= off && a.diag[i] !== 0;\n });\n}\n\nfunction gaussSeidel(a: Csr, b: number[], tol: number, maxIterations: number) {\n const x = new Array(a.n).fill(0);\n let it = 0;\n for (; it < maxIterations; it++) {\n for (let i = 0; i < a.n; i++) {\n if (a.diag[i] === 0) throw new Error(`zero diagonal at row ${i}: Gauss-Seidel needs a nonzero diagonal`);\n let s = b[i];\n for (const [j, v] of a.rows[i]) if (j !== i) s -= v * x[j];\n x[i] = s / a.diag[i];\n }\n if (residualInf(a, x, b) <= tol) return { x, iterations: it + 1 };\n }\n return { x, iterations: it };\n}\n\nconst solverCache = new Map<string, any>();\n\nasync function librarySolve(a: Csr, b: number[], tol: number, maxIterations: number): Promise<number[] | null> {\n return withStdoutToStderr(async () => {\n const mod = await importOptional<any>('sublinear-time-solver/core', { quietStdout: true });\n const Solver = mod?.SublinearSolver;\n if (typeof Solver !== 'function') return null;\n const key = `${tol}|${maxIterations}`;\n let solver = solverCache.get(key);\n if (!solver) {\n solver = new Solver({ method: 'forward-push', epsilon: tol, maxIterations });\n // The constructor starts WASM probing asynchronously and logs when it\n // finishes; let that settle while console output is still redirected.\n await solver.initializeWasm?.().catch(() => undefined);\n await new Promise((r) => setTimeout(r, 0));\n if (solverCache.size > 8) solverCache.clear();\n solverCache.set(key, solver);\n }\n const values: number[] = [];\n const rowIndices: number[] = [];\n const colIndices: number[] = [];\n a.rows.forEach((row, i) => {\n for (const [j, v] of row) {\n values.push(v);\n rowIndices.push(i);\n colIndices.push(j);\n }\n });\n const res = await solver.solve({ rows: a.n, cols: a.n, values, rowIndices, colIndices, format: 'coo' }, b);\n return Array.isArray(res?.solution) ? res.solution.map(Number) : null;\n });\n}\n\n/**\n * Solve Mx = b. Intended for (row) diagonally dominant M; other matrices are\n * attempted with Gauss-Seidel and reported with `converged: false` if it fails.\n */\nexport async function solveLinearSystem(\n matrix: MatrixInput,\n b: number[],\n options: { tolerance?: number; maxIterations?: number; engine?: 'auto' | 'builtin' } = {},\n): Promise<LinearSolveResult> {\n const a = toCsr(matrix);\n if (!Array.isArray(b) || b.length !== a.n) throw new Error(`vector length ${b?.length} != matrix size ${a.n}`);\n if (!b.every(Number.isFinite)) throw new Error('vector entries must be finite');\n const tol = options.tolerance ?? 1e-8;\n const maxIterations = Math.min(options.maxIterations ?? 10000, 1_000_000);\n // Residual tolerance scaled to the problem: absolute tol on ||b||_inf ~ 1.\n const scale = Math.max(1, ...b.map(Math.abs));\n const accept = tol * scale * 10;\n const diagonallyDominant = isDiagonallyDominant(a);\n\n let libraryRejected: string | undefined;\n if (options.engine !== 'builtin') {\n try {\n const x = await librarySolve(a, b, tol, maxIterations);\n if (x && x.length === a.n && x.every(Number.isFinite)) {\n const r = residualInf(a, x, b);\n if (r <= accept) {\n return { solution: x, residual: r, converged: true, iterations: 0, diagonallyDominant, engine: 'sublinear-time-solver' };\n }\n libraryRejected = `residual ${r.toExponential(2)} above ${accept.toExponential(2)}`;\n }\n } catch (err: any) {\n libraryRejected = err?.message ?? String(err);\n }\n }\n\n const { x, iterations } = gaussSeidel(a, b, accept, maxIterations);\n const residual = residualInf(a, x, b);\n return {\n solution: x,\n residual,\n converged: residual <= accept,\n iterations,\n diagonallyDominant,\n engine: 'builtin',\n ...(libraryRejected ? { libraryRejected } : {}),\n };\n}\n\nexport interface PageRankResult {\n scores: Record<string, number>;\n ranking: Array<{ node: string; score: number }>;\n engine: LinearSolveResult['engine'];\n residual: number;\n}\n\n/**\n * PageRank over a directed graph as a linear system:\n * (I - d·Pᵀ) y = 1, then scores = y / Σy. With dangling rows left at zero this\n * equals PageRank with uniform teleport from dangling nodes.\n */\nexport async function pageRank(\n edges: Array<{ from: string; to: string; weight?: number }>,\n options: { damping?: number; nodes?: string[]; engine?: 'auto' | 'builtin' } = {},\n): Promise<PageRankResult> {\n const d = options.damping ?? 0.85;\n if (!(d > 0 && d < 1)) throw new Error('damping must be in (0, 1)');\n const ids = new Map<string, number>();\n const names: string[] = [];\n const add = (s: string) => {\n if (!ids.has(s)) {\n ids.set(s, names.length);\n names.push(s);\n }\n return ids.get(s)!;\n };\n for (const n of options.nodes ?? []) add(String(n));\n const out: Array<Map<number, number>> = [];\n for (const e of edges) {\n const w = e.weight ?? 1;\n if (!Number.isFinite(w) || w < 0) throw new Error(`invalid edge weight ${w}`);\n const a = add(String(e.from));\n const b = add(String(e.to));\n while (out.length < names.length) out.push(new Map());\n out[a].set(b, (out[a].get(b) ?? 0) + w);\n }\n while (out.length < names.length) out.push(new Map());\n const n = names.length;\n if (n === 0) return { scores: {}, ranking: [], engine: 'builtin', residual: 0 };\n\n // M = I - d * P^T, P row-normalised out-links.\n const entries: SparseEntry[] = [];\n for (let i = 0; i < n; i++) entries.push({ row: i, col: i, value: 1 });\n out.forEach((links, src) => {\n let total = 0;\n for (const w of links.values()) total += w;\n if (total === 0) return;\n for (const [dst, w] of links) entries.push({ row: dst, col: src, value: -d * (w / total) });\n });\n const res = await solveLinearSystem({ size: n, entries }, new Array(n).fill(1), {\n tolerance: 1e-10,\n engine: options.engine,\n });\n const sum = res.solution.reduce((s, v) => s + v, 0) || 1;\n const scores: Record<string, number> = {};\n names.forEach((name, i) => (scores[name] = res.solution[i] / sum));\n const ranking = names\n .map((node) => ({ node, score: scores[node] }))\n .sort((x, y) => y.score - x.score);\n return { scores, ranking, engine: res.engine, residual: res.residual };\n}\n"]}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Split a task-dependency graph into two groups with the least coupling.
3
+ *
4
+ * A global minimum cut over the (undirected, weighted) dependency graph finds
5
+ * the split that severs the fewest/lightest dependencies — the natural seam for
6
+ * handing work to two agent teams so they block on each other least.
7
+ *
8
+ * Engine: `@ruvector/mincut-wasm` (optionalDependency) when installed; a
9
+ * built-in Stoer-Wagner implementation otherwise (O(n^3), capped at
10
+ * BUILTIN_MAX_TASKS). Both are exact, so they agree on the cut weight.
11
+ *
12
+ * A global min cut can be lopsided (one loosely-attached task vs the rest):
13
+ * that is the correct answer to "where is the weakest seam", not a balance
14
+ * guarantee. Tasks with no dependencies have nothing to cut and are reported
15
+ * in `isolated` rather than forced into a side.
16
+ */
17
+ export interface TaskDependency {
18
+ from: string;
19
+ to: string;
20
+ /** Coupling strength, default 1. Must be finite and >= 0. */
21
+ weight?: number;
22
+ }
23
+ export interface TaskPartition {
24
+ groups: [string[], string[]];
25
+ /** Tasks that have no dependencies at all. */
26
+ isolated: string[];
27
+ /** Sum of weights of the dependencies crossing between the groups. */
28
+ cutWeight: number;
29
+ cutEdges: Array<{
30
+ from: string;
31
+ to: string;
32
+ weight: number;
33
+ }>;
34
+ engine: 'mincut-wasm' | 'builtin';
35
+ }
36
+ export declare const BUILTIN_MAX_TASKS = 400;
37
+ export declare function partitionTaskGraph(tasks: string[], dependencies: TaskDependency[], options?: {
38
+ engine?: 'auto' | 'builtin';
39
+ }): Promise<TaskPartition>;
40
+ //# sourceMappingURL=task-partition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-partition.d.ts","sourceRoot":"","sources":["../../src/integrations/task-partition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7B,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;CACnC;AAED,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAmGrC,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EAAE,EACf,YAAY,EAAE,cAAc,EAAE,EAC9B,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAC5C,OAAO,CAAC,aAAa,CAAC,CAkExB"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Split a task-dependency graph into two groups with the least coupling.
3
+ *
4
+ * A global minimum cut over the (undirected, weighted) dependency graph finds
5
+ * the split that severs the fewest/lightest dependencies — the natural seam for
6
+ * handing work to two agent teams so they block on each other least.
7
+ *
8
+ * Engine: `@ruvector/mincut-wasm` (optionalDependency) when installed; a
9
+ * built-in Stoer-Wagner implementation otherwise (O(n^3), capped at
10
+ * BUILTIN_MAX_TASKS). Both are exact, so they agree on the cut weight.
11
+ *
12
+ * A global min cut can be lopsided (one loosely-attached task vs the rest):
13
+ * that is the correct answer to "where is the weakest seam", not a balance
14
+ * guarantee. Tasks with no dependencies have nothing to cut and are reported
15
+ * in `isolated` rather than forced into a side.
16
+ */
17
+ import { importOptional } from './optional.js';
18
+ export const BUILTIN_MAX_TASKS = 400;
19
+ function normalize(tasks, deps) {
20
+ const ids = new Map();
21
+ const names = [];
22
+ const add = (t) => {
23
+ if (!ids.has(t)) {
24
+ ids.set(t, names.length);
25
+ names.push(t);
26
+ }
27
+ return ids.get(t);
28
+ };
29
+ for (const t of tasks)
30
+ add(String(t));
31
+ const weights = new Map();
32
+ for (const d of deps) {
33
+ const w = d.weight ?? 1;
34
+ if (!Number.isFinite(w) || w < 0)
35
+ throw new Error(`invalid dependency weight ${w} (${d.from} -> ${d.to})`);
36
+ const a = add(String(d.from));
37
+ const b = add(String(d.to));
38
+ if (a === b || w === 0)
39
+ continue;
40
+ const key = a < b ? `${a},${b}` : `${b},${a}`;
41
+ weights.set(key, (weights.get(key) ?? 0) + w);
42
+ }
43
+ const edges = [];
44
+ for (const [key, w] of weights) {
45
+ const [a, b] = key.split(',').map(Number);
46
+ edges.push([a, b, w]);
47
+ }
48
+ return { names, edges };
49
+ }
50
+ /** Exact global min cut (Stoer-Wagner) over vertices that appear in `edges`. */
51
+ function stoerWagner(n, edges) {
52
+ const W = Array.from({ length: n }, () => new Array(n).fill(0));
53
+ for (const [a, b, w] of edges) {
54
+ W[a][b] += w;
55
+ W[b][a] += w;
56
+ }
57
+ const members = Array.from({ length: n }, (_, i) => [i]);
58
+ let active = Array.from({ length: n }, (_, i) => i);
59
+ let best = Infinity;
60
+ let bestSide = [];
61
+ while (active.length > 1) {
62
+ const added = new Set();
63
+ const conn = new Map(active.map((v) => [v, 0]));
64
+ let prev = -1;
65
+ let last = -1;
66
+ for (let step = 0; step < active.length; step++) {
67
+ let pick = -1;
68
+ for (const v of active) {
69
+ if (!added.has(v) && (pick === -1 || conn.get(v) > conn.get(pick)))
70
+ pick = v;
71
+ }
72
+ added.add(pick);
73
+ prev = last;
74
+ last = pick;
75
+ if (step === active.length - 1) {
76
+ const cutOfPhase = conn.get(pick);
77
+ if (cutOfPhase < best) {
78
+ best = cutOfPhase;
79
+ bestSide = [...members[pick]];
80
+ }
81
+ }
82
+ for (const v of active)
83
+ if (!added.has(v))
84
+ conn.set(v, conn.get(v) + W[pick][v]);
85
+ }
86
+ // merge `last` into `prev`
87
+ for (const v of active) {
88
+ W[prev][v] += W[last][v];
89
+ W[v][prev] = W[prev][v];
90
+ }
91
+ members[prev].push(...members[last]);
92
+ active = active.filter((v) => v !== last);
93
+ }
94
+ return { cut: best === Infinity ? 0 : best, side: new Set(bestSide) };
95
+ }
96
+ function components(n, edges) {
97
+ const parent = Array.from({ length: n }, (_, i) => i);
98
+ const find = (x) => (parent[x] === x ? x : (parent[x] = find(parent[x])));
99
+ for (const [a, b] of edges)
100
+ parent[find(a)] = find(b);
101
+ const groups = new Map();
102
+ for (let i = 0; i < n; i++) {
103
+ const r = find(i);
104
+ if (!groups.has(r))
105
+ groups.set(r, []);
106
+ groups.get(r).push(i);
107
+ }
108
+ return [...groups.values()];
109
+ }
110
+ export async function partitionTaskGraph(tasks, dependencies, options = {}) {
111
+ const { names, edges } = normalize(tasks, dependencies);
112
+ const touched = new Set();
113
+ for (const [a, b] of edges) {
114
+ touched.add(a);
115
+ touched.add(b);
116
+ }
117
+ const isolated = names.filter((_, i) => !touched.has(i));
118
+ const toEdges = (list) => list.map((e) => ({ from: names[e.u], to: names[e.v], weight: e.weight }));
119
+ if (touched.size < 2) {
120
+ return { groups: [names.filter((_, i) => touched.has(i)), []], isolated, cutWeight: 0, cutEdges: [], engine: 'builtin' };
121
+ }
122
+ if (options.engine !== 'builtin') {
123
+ const mod = await importOptional('@ruvector/mincut-wasm');
124
+ if (mod?.WasmMinCut) {
125
+ const g = mod.WasmMinCut.fromEdges(edges);
126
+ try {
127
+ const p = g.partition();
128
+ return {
129
+ groups: [p.s.map((i) => names[i]), p.t.map((i) => names[i])],
130
+ isolated,
131
+ cutWeight: g.minCutValue(),
132
+ cutEdges: toEdges(g.cutEdges()),
133
+ engine: 'mincut-wasm',
134
+ };
135
+ }
136
+ finally {
137
+ g.free?.();
138
+ }
139
+ }
140
+ }
141
+ // Built-in: disconnected graphs cut at weight 0 between components.
142
+ const comps = components(names.length, edges).filter((c) => c.some((v) => touched.has(v)));
143
+ let side;
144
+ let cut;
145
+ if (comps.length > 1) {
146
+ side = new Set(comps[0]);
147
+ cut = 0;
148
+ }
149
+ else {
150
+ if (touched.size > BUILTIN_MAX_TASKS) {
151
+ throw new Error(`built-in min cut is limited to ${BUILTIN_MAX_TASKS} connected tasks; install @ruvector/mincut-wasm for larger graphs`);
152
+ }
153
+ // Re-index the touched vertices densely for Stoer-Wagner.
154
+ const order = [...touched];
155
+ const local = new Map(order.map((v, i) => [v, i]));
156
+ const r = stoerWagner(order.length, edges.map(([a, b, w]) => [local.get(a), local.get(b), w]));
157
+ side = new Set([...r.side].map((i) => order[i]));
158
+ cut = r.cut;
159
+ }
160
+ const s = [...touched].filter((v) => side.has(v));
161
+ const t = [...touched].filter((v) => !side.has(v));
162
+ const crossing = edges
163
+ .filter(([a, b]) => side.has(a) !== side.has(b))
164
+ .map(([u, v, weight]) => ({ u, v, weight }));
165
+ return {
166
+ groups: [s.map((i) => names[i]), t.map((i) => names[i])],
167
+ isolated,
168
+ cutWeight: cut,
169
+ cutEdges: toEdges(crossing),
170
+ engine: 'builtin',
171
+ };
172
+ }
173
+ //# sourceMappingURL=task-partition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-partition.js","sourceRoot":"","sources":["../../src/integrations/task-partition.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Split a task-dependency graph into two groups with the least coupling.\n *\n * A global minimum cut over the (undirected, weighted) dependency graph finds\n * the split that severs the fewest/lightest dependencies — the natural seam for\n * handing work to two agent teams so they block on each other least.\n *\n * Engine: `@ruvector/mincut-wasm` (optionalDependency) when installed; a\n * built-in Stoer-Wagner implementation otherwise (O(n^3), capped at\n * BUILTIN_MAX_TASKS). Both are exact, so they agree on the cut weight.\n *\n * A global min cut can be lopsided (one loosely-attached task vs the rest):\n * that is the correct answer to \"where is the weakest seam\", not a balance\n * guarantee. Tasks with no dependencies have nothing to cut and are reported\n * in `isolated` rather than forced into a side.\n */\n\nimport { importOptional } from './optional.js';\n\nexport interface TaskDependency {\n from: string;\n to: string;\n /** Coupling strength, default 1. Must be finite and >= 0. */\n weight?: number;\n}\n\nexport interface TaskPartition {\n groups: [string[], string[]];\n /** Tasks that have no dependencies at all. */\n isolated: string[];\n /** Sum of weights of the dependencies crossing between the groups. */\n cutWeight: number;\n cutEdges: Array<{ from: string; to: string; weight: number }>;\n engine: 'mincut-wasm' | 'builtin';\n}\n\nexport const BUILTIN_MAX_TASKS = 400;\n\ninterface MinCutModule {\n WasmMinCut: {\n fromEdges(edges: Array<[number, number, number]>): {\n minCutValue(): number;\n partition(): { s: number[]; t: number[] };\n cutEdges(): Array<{ u: number; v: number; weight: number }>;\n free?(): void;\n };\n };\n}\n\nfunction normalize(tasks: string[], deps: TaskDependency[]) {\n const ids = new Map<string, number>();\n const names: string[] = [];\n const add = (t: string) => {\n if (!ids.has(t)) {\n ids.set(t, names.length);\n names.push(t);\n }\n return ids.get(t)!;\n };\n for (const t of tasks) add(String(t));\n const weights = new Map<string, number>();\n for (const d of deps) {\n const w = d.weight ?? 1;\n if (!Number.isFinite(w) || w < 0) throw new Error(`invalid dependency weight ${w} (${d.from} -> ${d.to})`);\n const a = add(String(d.from));\n const b = add(String(d.to));\n if (a === b || w === 0) continue;\n const key = a < b ? `${a},${b}` : `${b},${a}`;\n weights.set(key, (weights.get(key) ?? 0) + w);\n }\n const edges: Array<[number, number, number]> = [];\n for (const [key, w] of weights) {\n const [a, b] = key.split(',').map(Number);\n edges.push([a, b, w]);\n }\n return { names, edges };\n}\n\n/** Exact global min cut (Stoer-Wagner) over vertices that appear in `edges`. */\nfunction stoerWagner(n: number, edges: Array<[number, number, number]>): { cut: number; side: Set<number> } {\n const W: number[][] = Array.from({ length: n }, () => new Array(n).fill(0));\n for (const [a, b, w] of edges) {\n W[a][b] += w;\n W[b][a] += w;\n }\n const members: number[][] = Array.from({ length: n }, (_, i) => [i]);\n let active = Array.from({ length: n }, (_, i) => i);\n let best = Infinity;\n let bestSide: number[] = [];\n while (active.length > 1) {\n const added = new Set<number>();\n const conn = new Map<number, number>(active.map((v) => [v, 0]));\n let prev = -1;\n let last = -1;\n for (let step = 0; step < active.length; step++) {\n let pick = -1;\n for (const v of active) {\n if (!added.has(v) && (pick === -1 || conn.get(v)! > conn.get(pick)!)) pick = v;\n }\n added.add(pick);\n prev = last;\n last = pick;\n if (step === active.length - 1) {\n const cutOfPhase = conn.get(pick)!;\n if (cutOfPhase < best) {\n best = cutOfPhase;\n bestSide = [...members[pick]];\n }\n }\n for (const v of active) if (!added.has(v)) conn.set(v, conn.get(v)! + W[pick][v]);\n }\n // merge `last` into `prev`\n for (const v of active) {\n W[prev][v] += W[last][v];\n W[v][prev] = W[prev][v];\n }\n members[prev].push(...members[last]);\n active = active.filter((v) => v !== last);\n }\n return { cut: best === Infinity ? 0 : best, side: new Set(bestSide) };\n}\n\nfunction components(n: number, edges: Array<[number, number, number]>): number[][] {\n const parent = Array.from({ length: n }, (_, i) => i);\n const find = (x: number): number => (parent[x] === x ? x : (parent[x] = find(parent[x])));\n for (const [a, b] of edges) parent[find(a)] = find(b);\n const groups = new Map<number, number[]>();\n for (let i = 0; i < n; i++) {\n const r = find(i);\n if (!groups.has(r)) groups.set(r, []);\n groups.get(r)!.push(i);\n }\n return [...groups.values()];\n}\n\nexport async function partitionTaskGraph(\n tasks: string[],\n dependencies: TaskDependency[],\n options: { engine?: 'auto' | 'builtin' } = {},\n): Promise<TaskPartition> {\n const { names, edges } = normalize(tasks, dependencies);\n const touched = new Set<number>();\n for (const [a, b] of edges) {\n touched.add(a);\n touched.add(b);\n }\n const isolated = names.filter((_, i) => !touched.has(i));\n const toEdges = (list: Array<{ u: number; v: number; weight: number }>) =>\n list.map((e) => ({ from: names[e.u], to: names[e.v], weight: e.weight }));\n\n if (touched.size < 2) {\n return { groups: [names.filter((_, i) => touched.has(i)), []], isolated, cutWeight: 0, cutEdges: [], engine: 'builtin' };\n }\n\n if (options.engine !== 'builtin') {\n const mod = await importOptional<MinCutModule>('@ruvector/mincut-wasm');\n if (mod?.WasmMinCut) {\n const g = mod.WasmMinCut.fromEdges(edges);\n try {\n const p = g.partition();\n return {\n groups: [p.s.map((i) => names[i]), p.t.map((i) => names[i])],\n isolated,\n cutWeight: g.minCutValue(),\n cutEdges: toEdges(g.cutEdges()),\n engine: 'mincut-wasm',\n };\n } finally {\n g.free?.();\n }\n }\n }\n\n // Built-in: disconnected graphs cut at weight 0 between components.\n const comps = components(names.length, edges).filter((c) => c.some((v) => touched.has(v)));\n let side: Set<number>;\n let cut: number;\n if (comps.length > 1) {\n side = new Set(comps[0]);\n cut = 0;\n } else {\n if (touched.size > BUILTIN_MAX_TASKS) {\n throw new Error(\n `built-in min cut is limited to ${BUILTIN_MAX_TASKS} connected tasks; install @ruvector/mincut-wasm for larger graphs`,\n );\n }\n // Re-index the touched vertices densely for Stoer-Wagner.\n const order = [...touched];\n const local = new Map(order.map((v, i) => [v, i]));\n const r = stoerWagner(order.length, edges.map(([a, b, w]) => [local.get(a)!, local.get(b)!, w] as [number, number, number]));\n side = new Set([...r.side].map((i) => order[i]));\n cut = r.cut;\n }\n const s = [...touched].filter((v) => side.has(v));\n const t = [...touched].filter((v) => !side.has(v));\n const crossing = edges\n .filter(([a, b]) => side.has(a) !== side.has(b))\n .map(([u, v, weight]) => ({ u, v, weight }));\n return {\n groups: [s.map((i) => names[i]), t.map((i) => names[i])],\n isolated,\n cutWeight: cut,\n cutEdges: toEdges(crossing),\n engine: 'builtin',\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-policy.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp-policy.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;AAWzE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAMrE;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/D,OAAO,CAQT;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAA;CAAE,EACzF,MAAM,EAAE,CAAC,EACT,OAAO,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/D,CAAC,CAOH"}
1
+ {"version":3,"file":"mcp-policy.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp-policy.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;AAazE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAMrE;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/D,OAAO,CAQT;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAA;CAAE,EACzF,MAAM,EAAE,CAAC,EACT,OAAO,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/D,CAAC,CAOH"}
@@ -3,6 +3,8 @@ const READONLY = [
3
3
  /^agentdb_(stats|pattern_search|pattern_stats)$/,
4
4
  /^harness_(capabilities|manifest|verify)$/,
5
5
  /_(stats|get_profile|list_profiles|benchmark)$/,
6
+ // Ecosystem tools: pure computations over their arguments, no side effects.
7
+ /^(ecosystem_status|swarm_partition_tasks|sublinear_solve|sublinear_pagerank|prompt_injection_scan)$/,
6
8
  ];
7
9
  const RETRIEVAL = [...READONLY, /search$/, /context$/];
8
10
  const LEARNING = [...RETRIEVAL, /^agentic_flow_agent$/, /^agentdb_pattern_store$/, /^sona_/];
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-policy.js","sourceRoot":"","sources":["../../src/mcp/mcp-policy.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG;IACf,0DAA0D;IAC1D,gDAAgD;IAChD,0CAA0C;IAC1C,+CAA+C;CAChD,CAAC;AACF,MAAM,SAAS,GAAG,CAAC,GAAG,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AACvD,MAAM,QAAQ,GAAG,CAAC,GAAG,SAAS,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,QAAQ,CAAC,CAAC;AAE7F,MAAM,UAAU,eAAe,CAAC,KAAyB;IACvD,MAAM,OAAO,GAAG,KAAK,IAAI,UAAU,CAAC;IACpC,IAAI,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,OAAqB,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,OAAgE;IAEhE,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,oBAAoB,KAAK,IAAI,CAAC;IAC9E,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACvD,OAAO,CAAC,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IACzD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,MAAS,EACT,OAAgE;IAEhE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,IAAsB,EAAE,EAAE;QAC3C,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/D,OAAO,SAAS,CAAC;IACnB,CAAC,CAAiB,CAAC;IACnB,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["export type McpProfile = 'readonly' | 'retrieval' | 'learning' | 'admin';\n\nconst READONLY = [\n /^agentic_flow_(list|list_all|agent_info|check_conflicts)/,\n /^agentdb_(stats|pattern_search|pattern_stats)$/,\n /^harness_(capabilities|manifest|verify)$/,\n /_(stats|get_profile|list_profiles|benchmark)$/,\n];\nconst RETRIEVAL = [...READONLY, /search$/, /context$/];\nconst LEARNING = [...RETRIEVAL, /^agentic_flow_agent$/, /^agentdb_pattern_store$/, /^sona_/];\n\nexport function parseMcpProfile(value: string | undefined): McpProfile {\n const profile = value ?? 'readonly';\n if (!['readonly', 'retrieval', 'learning', 'admin'].includes(profile)) {\n throw new Error(`invalid MCP profile: ${profile}`);\n }\n return profile as McpProfile;\n}\n\nexport function isMcpToolAllowed(\n name: string,\n options: { profile: McpProfile; allowDarwinExecution?: boolean },\n): boolean {\n if (name === 'harness_repair') {\n return options.profile === 'admin' && options.allowDarwinExecution === true;\n }\n if (options.profile === 'admin') return true;\n const rules = options.profile === 'learning' ? LEARNING :\n options.profile === 'retrieval' ? RETRIEVAL : READONLY;\n return rules.some((rule) => rule.test(name));\n}\n\nexport function installMcpPolicy<T extends { addTool: (tool: { name: string }) => unknown }>(\n server: T,\n options: { profile: McpProfile; allowDarwinExecution?: boolean },\n): T {\n const addTool = server.addTool.bind(server);\n server.addTool = ((tool: { name: string }) => {\n if (isMcpToolAllowed(tool.name, options)) return addTool(tool);\n return undefined;\n }) as T['addTool'];\n return server;\n}\n"]}
1
+ {"version":3,"file":"mcp-policy.js","sourceRoot":"","sources":["../../src/mcp/mcp-policy.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG;IACf,0DAA0D;IAC1D,gDAAgD;IAChD,0CAA0C;IAC1C,+CAA+C;IAC/C,4EAA4E;IAC5E,qGAAqG;CACtG,CAAC;AACF,MAAM,SAAS,GAAG,CAAC,GAAG,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AACvD,MAAM,QAAQ,GAAG,CAAC,GAAG,SAAS,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,QAAQ,CAAC,CAAC;AAE7F,MAAM,UAAU,eAAe,CAAC,KAAyB;IACvD,MAAM,OAAO,GAAG,KAAK,IAAI,UAAU,CAAC;IACpC,IAAI,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,OAAqB,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,OAAgE;IAEhE,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,oBAAoB,KAAK,IAAI,CAAC;IAC9E,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACvD,OAAO,CAAC,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IACzD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,MAAS,EACT,OAAgE;IAEhE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,IAAsB,EAAE,EAAE;QAC3C,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/D,OAAO,SAAS,CAAC;IACnB,CAAC,CAAiB,CAAC;IACnB,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["export type McpProfile = 'readonly' | 'retrieval' | 'learning' | 'admin';\n\nconst READONLY = [\n /^agentic_flow_(list|list_all|agent_info|check_conflicts)/,\n /^agentdb_(stats|pattern_search|pattern_stats)$/,\n /^harness_(capabilities|manifest|verify)$/,\n /_(stats|get_profile|list_profiles|benchmark)$/,\n // Ecosystem tools: pure computations over their arguments, no side effects.\n /^(ecosystem_status|swarm_partition_tasks|sublinear_solve|sublinear_pagerank|prompt_injection_scan)$/,\n];\nconst RETRIEVAL = [...READONLY, /search$/, /context$/];\nconst LEARNING = [...RETRIEVAL, /^agentic_flow_agent$/, /^agentdb_pattern_store$/, /^sona_/];\n\nexport function parseMcpProfile(value: string | undefined): McpProfile {\n const profile = value ?? 'readonly';\n if (!['readonly', 'retrieval', 'learning', 'admin'].includes(profile)) {\n throw new Error(`invalid MCP profile: ${profile}`);\n }\n return profile as McpProfile;\n}\n\nexport function isMcpToolAllowed(\n name: string,\n options: { profile: McpProfile; allowDarwinExecution?: boolean },\n): boolean {\n if (name === 'harness_repair') {\n return options.profile === 'admin' && options.allowDarwinExecution === true;\n }\n if (options.profile === 'admin') return true;\n const rules = options.profile === 'learning' ? LEARNING :\n options.profile === 'retrieval' ? RETRIEVAL : READONLY;\n return rules.some((rule) => rule.test(name));\n}\n\nexport function installMcpPolicy<T extends { addTool: (tool: { name: string }) => unknown }>(\n server: T,\n options: { profile: McpProfile; allowDarwinExecution?: boolean },\n): T {\n const addTool = server.addTool.bind(server);\n server.addTool = ((tool: { name: string }) => {\n if (isMcpToolAllowed(tool.name, options)) return addTool(tool);\n return undefined;\n }) as T['addTool'];\n return server;\n}\n"]}