modular-studio 0.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 (187) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +261 -0
  3. package/dist/assets/graphPopulator-C6jg83nL.js +1 -0
  4. package/dist/assets/index-CXhIX28x.js +634 -0
  5. package/dist/assets/index-CeNF0r-K.css +1 -0
  6. package/dist/assets/jszip.min-BlpRodxc.js +2 -0
  7. package/dist/index.html +16 -0
  8. package/dist/vite.svg +1 -0
  9. package/dist-server/bin/modular-mcp.d.ts +8 -0
  10. package/dist-server/bin/modular-mcp.d.ts.map +1 -0
  11. package/dist-server/bin/modular-mcp.js +158 -0
  12. package/dist-server/bin/modular-mcp.js.map +1 -0
  13. package/dist-server/bin/modular-studio.d.ts +3 -0
  14. package/dist-server/bin/modular-studio.d.ts.map +1 -0
  15. package/dist-server/bin/modular-studio.js +63 -0
  16. package/dist-server/bin/modular-studio.js.map +1 -0
  17. package/dist-server/server/config.d.ts +4 -0
  18. package/dist-server/server/config.d.ts.map +1 -0
  19. package/dist-server/server/config.js +33 -0
  20. package/dist-server/server/config.js.map +1 -0
  21. package/dist-server/server/data/mcp-clients.json +5 -0
  22. package/dist-server/server/index.d.ts +3 -0
  23. package/dist-server/server/index.d.ts.map +1 -0
  24. package/dist-server/server/index.js +174 -0
  25. package/dist-server/server/index.js.map +1 -0
  26. package/dist-server/server/mcp/manager.d.ts +47 -0
  27. package/dist-server/server/mcp/manager.d.ts.map +1 -0
  28. package/dist-server/server/mcp/manager.js +203 -0
  29. package/dist-server/server/mcp/manager.js.map +1 -0
  30. package/dist-server/server/mcp/modular-server.d.ts +55 -0
  31. package/dist-server/server/mcp/modular-server.d.ts.map +1 -0
  32. package/dist-server/server/mcp/modular-server.js +492 -0
  33. package/dist-server/server/mcp/modular-server.js.map +1 -0
  34. package/dist-server/server/mcp/transport.d.ts +29 -0
  35. package/dist-server/server/mcp/transport.d.ts.map +1 -0
  36. package/dist-server/server/mcp/transport.js +61 -0
  37. package/dist-server/server/mcp/transport.js.map +1 -0
  38. package/dist-server/server/routes/agent-sdk.d.ts +3 -0
  39. package/dist-server/server/routes/agent-sdk.d.ts.map +1 -0
  40. package/dist-server/server/routes/agent-sdk.js +99 -0
  41. package/dist-server/server/routes/agent-sdk.js.map +1 -0
  42. package/dist-server/server/routes/agents.d.ts +10 -0
  43. package/dist-server/server/routes/agents.d.ts.map +1 -0
  44. package/dist-server/server/routes/agents.js +61 -0
  45. package/dist-server/server/routes/agents.js.map +1 -0
  46. package/dist-server/server/routes/auth-codex.d.ts +3 -0
  47. package/dist-server/server/routes/auth-codex.d.ts.map +1 -0
  48. package/dist-server/server/routes/auth-codex.js +51 -0
  49. package/dist-server/server/routes/auth-codex.js.map +1 -0
  50. package/dist-server/server/routes/capabilities.d.ts +3 -0
  51. package/dist-server/server/routes/capabilities.d.ts.map +1 -0
  52. package/dist-server/server/routes/capabilities.js +32 -0
  53. package/dist-server/server/routes/capabilities.js.map +1 -0
  54. package/dist-server/server/routes/claude-config.d.ts +3 -0
  55. package/dist-server/server/routes/claude-config.d.ts.map +1 -0
  56. package/dist-server/server/routes/claude-config.js +146 -0
  57. package/dist-server/server/routes/claude-config.js.map +1 -0
  58. package/dist-server/server/routes/connectors.d.ts +12 -0
  59. package/dist-server/server/routes/connectors.d.ts.map +1 -0
  60. package/dist-server/server/routes/connectors.js +325 -0
  61. package/dist-server/server/routes/connectors.js.map +1 -0
  62. package/dist-server/server/routes/embeddings.d.ts +6 -0
  63. package/dist-server/server/routes/embeddings.d.ts.map +1 -0
  64. package/dist-server/server/routes/embeddings.js +130 -0
  65. package/dist-server/server/routes/embeddings.js.map +1 -0
  66. package/dist-server/server/routes/health.d.ts +9 -0
  67. package/dist-server/server/routes/health.d.ts.map +1 -0
  68. package/dist-server/server/routes/health.js +284 -0
  69. package/dist-server/server/routes/health.js.map +1 -0
  70. package/dist-server/server/routes/knowledge.d.ts +3 -0
  71. package/dist-server/server/routes/knowledge.d.ts.map +1 -0
  72. package/dist-server/server/routes/knowledge.js +534 -0
  73. package/dist-server/server/routes/knowledge.js.map +1 -0
  74. package/dist-server/server/routes/llm.d.ts +3 -0
  75. package/dist-server/server/routes/llm.d.ts.map +1 -0
  76. package/dist-server/server/routes/llm.js +200 -0
  77. package/dist-server/server/routes/llm.js.map +1 -0
  78. package/dist-server/server/routes/mcp-oauth.d.ts +12 -0
  79. package/dist-server/server/routes/mcp-oauth.d.ts.map +1 -0
  80. package/dist-server/server/routes/mcp-oauth.js +137 -0
  81. package/dist-server/server/routes/mcp-oauth.js.map +1 -0
  82. package/dist-server/server/routes/mcp.d.ts +3 -0
  83. package/dist-server/server/routes/mcp.d.ts.map +1 -0
  84. package/dist-server/server/routes/mcp.js +177 -0
  85. package/dist-server/server/routes/mcp.js.map +1 -0
  86. package/dist-server/server/routes/pipeline.d.ts +45 -0
  87. package/dist-server/server/routes/pipeline.d.ts.map +1 -0
  88. package/dist-server/server/routes/pipeline.js +483 -0
  89. package/dist-server/server/routes/pipeline.js.map +1 -0
  90. package/dist-server/server/routes/providers.d.ts +3 -0
  91. package/dist-server/server/routes/providers.d.ts.map +1 -0
  92. package/dist-server/server/routes/providers.js +204 -0
  93. package/dist-server/server/routes/providers.js.map +1 -0
  94. package/dist-server/server/routes/qualification.d.ts +3 -0
  95. package/dist-server/server/routes/qualification.d.ts.map +1 -0
  96. package/dist-server/server/routes/qualification.js +105 -0
  97. package/dist-server/server/routes/qualification.js.map +1 -0
  98. package/dist-server/server/routes/repo-index.d.ts +4 -0
  99. package/dist-server/server/routes/repo-index.d.ts.map +1 -0
  100. package/dist-server/server/routes/repo-index.js +318 -0
  101. package/dist-server/server/routes/repo-index.js.map +1 -0
  102. package/dist-server/server/routes/runtime.d.ts +3 -0
  103. package/dist-server/server/routes/runtime.d.ts.map +1 -0
  104. package/dist-server/server/routes/runtime.js +122 -0
  105. package/dist-server/server/routes/runtime.js.map +1 -0
  106. package/dist-server/server/routes/skills-search.d.ts +3 -0
  107. package/dist-server/server/routes/skills-search.d.ts.map +1 -0
  108. package/dist-server/server/routes/skills-search.js +198 -0
  109. package/dist-server/server/routes/skills-search.js.map +1 -0
  110. package/dist-server/server/routes/worktrees.d.ts +3 -0
  111. package/dist-server/server/routes/worktrees.d.ts.map +1 -0
  112. package/dist-server/server/routes/worktrees.js +70 -0
  113. package/dist-server/server/routes/worktrees.js.map +1 -0
  114. package/dist-server/server/services/__tests__/embeddingService.test.d.ts +5 -0
  115. package/dist-server/server/services/__tests__/embeddingService.test.d.ts.map +1 -0
  116. package/dist-server/server/services/__tests__/embeddingService.test.js +233 -0
  117. package/dist-server/server/services/__tests__/embeddingService.test.js.map +1 -0
  118. package/dist-server/server/services/agentRunner.d.ts +46 -0
  119. package/dist-server/server/services/agentRunner.d.ts.map +1 -0
  120. package/dist-server/server/services/agentRunner.js +295 -0
  121. package/dist-server/server/services/agentRunner.js.map +1 -0
  122. package/dist-server/server/services/agentStore.d.ts +40 -0
  123. package/dist-server/server/services/agentStore.d.ts.map +1 -0
  124. package/dist-server/server/services/agentStore.js +62 -0
  125. package/dist-server/server/services/agentStore.js.map +1 -0
  126. package/dist-server/server/services/contentStore.d.ts +32 -0
  127. package/dist-server/server/services/contentStore.d.ts.map +1 -0
  128. package/dist-server/server/services/contentStore.js +68 -0
  129. package/dist-server/server/services/contentStore.js.map +1 -0
  130. package/dist-server/server/services/embeddingService.d.ts +53 -0
  131. package/dist-server/server/services/embeddingService.d.ts.map +1 -0
  132. package/dist-server/server/services/embeddingService.js +199 -0
  133. package/dist-server/server/services/embeddingService.js.map +1 -0
  134. package/dist-server/server/services/factExtractor.d.ts +14 -0
  135. package/dist-server/server/services/factExtractor.d.ts.map +1 -0
  136. package/dist-server/server/services/factExtractor.js +126 -0
  137. package/dist-server/server/services/factExtractor.js.map +1 -0
  138. package/dist-server/server/services/githubIndexer.d.ts +59 -0
  139. package/dist-server/server/services/githubIndexer.d.ts.map +1 -0
  140. package/dist-server/server/services/githubIndexer.js +183 -0
  141. package/dist-server/server/services/githubIndexer.js.map +1 -0
  142. package/dist-server/server/services/mcpOAuth.d.ts +32 -0
  143. package/dist-server/server/services/mcpOAuth.d.ts.map +1 -0
  144. package/dist-server/server/services/mcpOAuth.js +264 -0
  145. package/dist-server/server/services/mcpOAuth.js.map +1 -0
  146. package/dist-server/server/services/memoryScorer.d.ts +19 -0
  147. package/dist-server/server/services/memoryScorer.d.ts.map +1 -0
  148. package/dist-server/server/services/memoryScorer.js +147 -0
  149. package/dist-server/server/services/memoryScorer.js.map +1 -0
  150. package/dist-server/server/services/repoIndexer.d.ts +91 -0
  151. package/dist-server/server/services/repoIndexer.d.ts.map +1 -0
  152. package/dist-server/server/services/repoIndexer.js +512 -0
  153. package/dist-server/server/services/repoIndexer.js.map +1 -0
  154. package/dist-server/server/services/teamRunner.d.ts +39 -0
  155. package/dist-server/server/services/teamRunner.d.ts.map +1 -0
  156. package/dist-server/server/services/teamRunner.js +76 -0
  157. package/dist-server/server/services/teamRunner.js.map +1 -0
  158. package/dist-server/server/services/worktreeManager.d.ts +27 -0
  159. package/dist-server/server/services/worktreeManager.d.ts.map +1 -0
  160. package/dist-server/server/services/worktreeManager.js +107 -0
  161. package/dist-server/server/services/worktreeManager.js.map +1 -0
  162. package/dist-server/server/types.d.ts +30 -0
  163. package/dist-server/server/types.d.ts.map +1 -0
  164. package/dist-server/server/types.js +2 -0
  165. package/dist-server/server/types.js.map +1 -0
  166. package/dist-server/server/utils/pathSecurity.d.ts +34 -0
  167. package/dist-server/server/utils/pathSecurity.d.ts.map +1 -0
  168. package/dist-server/server/utils/pathSecurity.js +78 -0
  169. package/dist-server/server/utils/pathSecurity.js.map +1 -0
  170. package/dist-server/src/services/budgetAllocator.d.ts +37 -0
  171. package/dist-server/src/services/budgetAllocator.d.ts.map +1 -0
  172. package/dist-server/src/services/budgetAllocator.js +120 -0
  173. package/dist-server/src/services/budgetAllocator.js.map +1 -0
  174. package/dist-server/src/services/contradictionDetector.d.ts +18 -0
  175. package/dist-server/src/services/contradictionDetector.d.ts.map +1 -0
  176. package/dist-server/src/services/contradictionDetector.js +111 -0
  177. package/dist-server/src/services/contradictionDetector.js.map +1 -0
  178. package/dist-server/src/services/treeIndexer.d.ts +91 -0
  179. package/dist-server/src/services/treeIndexer.d.ts.map +1 -0
  180. package/dist-server/src/services/treeIndexer.js +289 -0
  181. package/dist-server/src/services/treeIndexer.js.map +1 -0
  182. package/dist-server/src/store/knowledgeBase.d.ts +130 -0
  183. package/dist-server/src/store/knowledgeBase.d.ts.map +1 -0
  184. package/dist-server/src/store/knowledgeBase.js +299 -0
  185. package/dist-server/src/store/knowledgeBase.js.map +1 -0
  186. package/dist-server/tsconfig.server.tsbuildinfo +1 -0
  187. package/package.json +92 -0
@@ -0,0 +1,76 @@
1
+ import { runAgent } from './agentRunner.js';
2
+ function deduplicateFacts(facts) {
3
+ const seen = new Map();
4
+ for (const fact of facts) {
5
+ const existing = seen.get(fact.key);
6
+ if (!existing || existing.confidence < fact.confidence) {
7
+ seen.set(fact.key, fact);
8
+ }
9
+ }
10
+ return Array.from(seen.values());
11
+ }
12
+ export async function runTeam(config, onProgress) {
13
+ const start = Date.now();
14
+ const sharedFacts = [...(config.initialFacts ?? [])];
15
+ try {
16
+ // Build agent configs — each gets its own or shared system prompt + optional role overlay
17
+ const agentConfigs = config.agents.map((agent) => {
18
+ let systemPrompt = agent.systemPrompt || config.systemPrompt;
19
+ if (agent.rolePrompt) {
20
+ systemPrompt += `\n\n## Your Role\n${agent.rolePrompt}`;
21
+ }
22
+ if (agent.repoUrl) {
23
+ systemPrompt += `\n\n## Repository\nYou are working on: ${agent.repoUrl}`;
24
+ }
25
+ return {
26
+ agentId: agent.agentId,
27
+ name: agent.name,
28
+ systemPrompt,
29
+ task: config.task,
30
+ providerId: agent.providerId || config.providerId,
31
+ model: agent.model || config.model,
32
+ teamFacts: [...sharedFacts],
33
+ maxTurns: agent.maxTurns ?? 10,
34
+ tools: config.tools,
35
+ };
36
+ });
37
+ // Run all agents in parallel
38
+ const results = await Promise.allSettled(agentConfigs.map((agent) => runAgent(agent, onProgress)));
39
+ const agentResults = results.map((r, i) => {
40
+ if (r.status === 'fulfilled')
41
+ return r.value;
42
+ return {
43
+ agentId: config.agents[i].agentId,
44
+ output: '',
45
+ facts: [],
46
+ turns: 0,
47
+ tokens: { input: 0, output: 0 },
48
+ durationMs: 0,
49
+ status: 'error',
50
+ error: r.reason instanceof Error ? r.reason.message : String(r.reason),
51
+ };
52
+ });
53
+ // Merge all extracted facts into shared pool
54
+ const allFacts = agentResults.flatMap((r) => r.facts);
55
+ const mergedFacts = deduplicateFacts([...sharedFacts, ...allFacts]);
56
+ const hasErrors = agentResults.some((r) => r.status === 'error');
57
+ const allErrors = agentResults.every((r) => r.status === 'error');
58
+ return {
59
+ teamId: config.teamId,
60
+ agentResults,
61
+ sharedFacts: mergedFacts,
62
+ durationMs: Date.now() - start,
63
+ status: allErrors ? 'error' : hasErrors ? 'partial' : 'completed',
64
+ };
65
+ }
66
+ catch (err) {
67
+ return {
68
+ teamId: config.teamId,
69
+ agentResults: [],
70
+ sharedFacts,
71
+ durationMs: Date.now() - start,
72
+ status: 'error',
73
+ };
74
+ }
75
+ }
76
+ //# sourceMappingURL=teamRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teamRunner.js","sourceRoot":"","sources":["../../../server/services/teamRunner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface WorktreeRequest {
2
+ repoUrl: string;
3
+ baseRef?: string;
4
+ teamId: string;
5
+ agentId: string;
6
+ }
7
+ export interface WorktreeResult {
8
+ bareRepoPath: string;
9
+ worktreePath: string;
10
+ branch: string;
11
+ baseRef: string;
12
+ }
13
+ export interface WorktreeStatus {
14
+ worktreePath: string;
15
+ branch: string;
16
+ baseBranch: string;
17
+ ahead: number;
18
+ behind: number;
19
+ headSha: string;
20
+ headMessage: string;
21
+ }
22
+ export declare function prepareAgentWorktree(request: WorktreeRequest): WorktreeResult;
23
+ export declare function getWorktreeStatus(worktreePath: string, branch: string, baseBranch?: string): WorktreeStatus;
24
+ export declare function rebaseWorktree(worktreePath: string, branch: string, baseBranch?: string): WorktreeStatus;
25
+ export declare function mergeWorktreeIntoBase(worktreePath: string, branch: string, baseBranch?: string): WorktreeStatus;
26
+ export declare function listTeamWorktrees(teamId: string): string[];
27
+ //# sourceMappingURL=worktreeManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktreeManager.d.ts","sourceRoot":"","sources":["../../../server/services/worktreeManager.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AA4CD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CA4B7E;AAWD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,cAAc,CAQ3G;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,cAAc,CAMxG;AAED,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,cAAc,CAM/G;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAM1D"}
@@ -0,0 +1,107 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { existsSync, mkdirSync, readdirSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { tmpdir } from 'node:os';
5
+ const ROOT = join(tmpdir(), 'modular-worktrees');
6
+ const BARE_ROOT = join(ROOT, 'bare');
7
+ const TREE_ROOT = join(ROOT, 'trees');
8
+ function safeSlug(value) {
9
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
10
+ }
11
+ function normalizeGitUrl(url) {
12
+ return url.endsWith('.git') ? url : `${url}.git`;
13
+ }
14
+ function parseRepoKey(url) {
15
+ const cleaned = url.replace(/\.git$/, '');
16
+ const parts = cleaned.split('/');
17
+ const owner = parts[parts.length - 2] || 'unknown';
18
+ const repo = parts[parts.length - 1] || 'repo';
19
+ return `${safeSlug(owner)}--${safeSlug(repo)}`;
20
+ }
21
+ function ensureDirs() {
22
+ mkdirSync(BARE_ROOT, { recursive: true });
23
+ mkdirSync(TREE_ROOT, { recursive: true });
24
+ }
25
+ function run(command) {
26
+ execSync(command, { stdio: 'pipe', timeout: 120_000 });
27
+ }
28
+ function runText(command) {
29
+ return execSync(command, { stdio: 'pipe', timeout: 120_000 }).toString().trim();
30
+ }
31
+ function branchExists(gitDir, branch) {
32
+ try {
33
+ run(`git --git-dir="${gitDir}" show-ref --verify --quiet "refs/heads/${branch}"`);
34
+ return true;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ export function prepareAgentWorktree(request) {
41
+ ensureDirs();
42
+ const repoKey = parseRepoKey(request.repoUrl);
43
+ const remoteUrl = normalizeGitUrl(request.repoUrl);
44
+ const bareRepoPath = join(BARE_ROOT, `${repoKey}.git`);
45
+ const baseRef = request.baseRef || 'origin/HEAD';
46
+ const branch = `agent/${safeSlug(request.teamId)}-${safeSlug(request.agentId)}`;
47
+ const worktreePath = join(TREE_ROOT, `${repoKey}--${safeSlug(request.teamId)}--${safeSlug(request.agentId)}`);
48
+ if (!existsSync(bareRepoPath)) {
49
+ run(`git clone --bare "${remoteUrl}" "${bareRepoPath}"`);
50
+ }
51
+ else {
52
+ run(`git --git-dir="${bareRepoPath}" fetch --all --prune`);
53
+ }
54
+ if (!existsSync(worktreePath)) {
55
+ const baseArg = baseRef.startsWith('origin/') ? baseRef : `origin/${baseRef}`;
56
+ if (!branchExists(bareRepoPath, branch)) {
57
+ run(`git --git-dir="${bareRepoPath}" worktree add "${worktreePath}" -b "${branch}" "${baseArg}"`);
58
+ }
59
+ else {
60
+ run(`git --git-dir="${bareRepoPath}" worktree add "${worktreePath}" "${branch}"`);
61
+ }
62
+ }
63
+ else {
64
+ run(`git -C "${worktreePath}" checkout "${branch}"`);
65
+ }
66
+ return { bareRepoPath, worktreePath, branch, baseRef };
67
+ }
68
+ function resolveBaseBranch(worktreePath) {
69
+ try {
70
+ const originHead = runText(`git -C "${worktreePath}" symbolic-ref --short refs/remotes/origin/HEAD`);
71
+ return originHead.replace('origin/', '');
72
+ }
73
+ catch {
74
+ return 'master';
75
+ }
76
+ }
77
+ export function getWorktreeStatus(worktreePath, branch, baseBranch) {
78
+ const base = baseBranch || resolveBaseBranch(worktreePath);
79
+ const counts = runText(`git -C "${worktreePath}" rev-list --left-right --count origin/${base}...${branch}`).split(/\s+/);
80
+ const behind = Number(counts[0] || '0');
81
+ const ahead = Number(counts[1] || '0');
82
+ const headSha = runText(`git -C "${worktreePath}" rev-parse --short HEAD`);
83
+ const headMessage = runText(`git -C "${worktreePath}" log -1 --pretty=%s`);
84
+ return { worktreePath, branch, baseBranch: base, ahead, behind, headSha, headMessage };
85
+ }
86
+ export function rebaseWorktree(worktreePath, branch, baseBranch) {
87
+ const base = baseBranch || resolveBaseBranch(worktreePath);
88
+ run(`git -C "${worktreePath}" fetch --all --prune`);
89
+ run(`git -C "${worktreePath}" checkout "${branch}"`);
90
+ run(`git -C "${worktreePath}" rebase "origin/${base}"`);
91
+ return getWorktreeStatus(worktreePath, branch, base);
92
+ }
93
+ export function mergeWorktreeIntoBase(worktreePath, branch, baseBranch) {
94
+ const base = baseBranch || resolveBaseBranch(worktreePath);
95
+ run(`git -C "${worktreePath}" fetch --all --prune`);
96
+ run(`git -C "${worktreePath}" checkout "${base}"`);
97
+ run(`git -C "${worktreePath}" merge --no-ff "${branch}"`);
98
+ return getWorktreeStatus(worktreePath, branch, base);
99
+ }
100
+ export function listTeamWorktrees(teamId) {
101
+ ensureDirs();
102
+ const teamSlug = safeSlug(teamId);
103
+ return readdirSync(TREE_ROOT)
104
+ .filter((name) => name.includes(`--${teamSlug}--`))
105
+ .map((name) => join(TREE_ROOT, name));
106
+ }
107
+ //# sourceMappingURL=worktreeManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktreeManager.js","sourceRoot":"","sources":["../../../server/services/worktreeManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface ProviderConfig {
2
+ id: string;
3
+ name: string;
4
+ type: 'openai' | 'anthropic' | 'openrouter' | 'google' | 'custom';
5
+ apiKey: string;
6
+ baseUrl: string;
7
+ accessToken?: string;
8
+ authMethod?: 'claude-agent-sdk';
9
+ }
10
+ export interface McpServerConfig {
11
+ id: string;
12
+ name: string;
13
+ type?: 'stdio' | 'sse' | 'http' | 'streamable-http';
14
+ command: string;
15
+ args: string[];
16
+ env: Record<string, string>;
17
+ autoConnect?: boolean;
18
+ url?: string;
19
+ headers?: Record<string, string>;
20
+ }
21
+ export interface AppConfig {
22
+ providers: ProviderConfig[];
23
+ mcpServers: McpServerConfig[];
24
+ }
25
+ export interface ApiResponse<T = unknown> {
26
+ status: 'ok' | 'error';
27
+ data?: T;
28
+ error?: string;
29
+ }
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../server/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,kBAAkB,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,iBAAiB,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../server/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Path Security Utilities
3
+ *
4
+ * Shared utilities for validating file paths across the application
5
+ */
6
+ /**
7
+ * Load allowed directories from configuration
8
+ */
9
+ export declare function loadAllowedDirs(): string[];
10
+ /**
11
+ * Check if a target path is safe to access
12
+ *
13
+ * @param targetPath Path to validate
14
+ * @param allowedDirs Array of allowed parent directories
15
+ * @returns true if path is safe, false otherwise
16
+ */
17
+ export declare function isPathSafe(targetPath: string, allowedDirs: string[]): boolean;
18
+ /**
19
+ * Validate a file path and throw an error if not safe
20
+ *
21
+ * @param filePath Path to validate
22
+ * @param allowedDirs Optional array of allowed directories (loads from config if not provided)
23
+ * @throws Error if path is not safe
24
+ */
25
+ export declare function validateFilePath(filePath: string, allowedDirs?: string[]): void;
26
+ /**
27
+ * Validate multiple file paths
28
+ *
29
+ * @param filePaths Array of paths to validate
30
+ * @param allowedDirs Optional array of allowed directories (loads from config if not provided)
31
+ * @throws Error if any path is not safe
32
+ */
33
+ export declare function validateFilePaths(filePaths: string[], allowedDirs?: string[]): void;
34
+ //# sourceMappingURL=pathSecurity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathSecurity.d.ts","sourceRoot":"","sources":["../../../server/utils/pathSecurity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAc1C;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAY7E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAM/E;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAQnF"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Path Security Utilities
3
+ *
4
+ * Shared utilities for validating file paths across the application
5
+ */
6
+ import { resolve } from 'node:path';
7
+ import { existsSync, readFileSync } from 'node:fs';
8
+ import { homedir } from 'node:os';
9
+ import { join } from 'node:path';
10
+ const CONFIG_DIR = join(homedir(), '.modular-studio');
11
+ const CONFIG_PATH = join(CONFIG_DIR, 'config.json');
12
+ /**
13
+ * Load allowed directories from configuration
14
+ */
15
+ export function loadAllowedDirs() {
16
+ try {
17
+ if (existsSync(CONFIG_PATH)) {
18
+ const raw = readFileSync(CONFIG_PATH, 'utf-8');
19
+ const cfg = JSON.parse(raw);
20
+ if (Array.isArray(cfg.allowedDirs) && cfg.allowedDirs.length > 0) {
21
+ return cfg.allowedDirs.map((d) => resolve(d));
22
+ }
23
+ }
24
+ }
25
+ catch {
26
+ // ignore
27
+ }
28
+ // Default: current working directory + user home directory
29
+ return [resolve(process.cwd()), resolve(homedir())];
30
+ }
31
+ /**
32
+ * Check if a target path is safe to access
33
+ *
34
+ * @param targetPath Path to validate
35
+ * @param allowedDirs Array of allowed parent directories
36
+ * @returns true if path is safe, false otherwise
37
+ */
38
+ export function isPathSafe(targetPath, allowedDirs) {
39
+ // Reject path traversal attempts
40
+ if (targetPath.includes('..'))
41
+ return false;
42
+ // SECURITY FIX: Reject null byte attacks
43
+ if (targetPath.includes('\0'))
44
+ return false;
45
+ // Resolve to absolute path and normalize case for comparison
46
+ const resolved = resolve(targetPath).toLowerCase();
47
+ // Check if path starts with any allowed directory
48
+ return allowedDirs.some((dir) => resolved.startsWith(dir.toLowerCase()));
49
+ }
50
+ /**
51
+ * Validate a file path and throw an error if not safe
52
+ *
53
+ * @param filePath Path to validate
54
+ * @param allowedDirs Optional array of allowed directories (loads from config if not provided)
55
+ * @throws Error if path is not safe
56
+ */
57
+ export function validateFilePath(filePath, allowedDirs) {
58
+ const dirs = allowedDirs ?? loadAllowedDirs();
59
+ if (!isPathSafe(filePath, dirs)) {
60
+ throw new Error(`Access denied: path outside allowed directories`);
61
+ }
62
+ }
63
+ /**
64
+ * Validate multiple file paths
65
+ *
66
+ * @param filePaths Array of paths to validate
67
+ * @param allowedDirs Optional array of allowed directories (loads from config if not provided)
68
+ * @throws Error if any path is not safe
69
+ */
70
+ export function validateFilePaths(filePaths, allowedDirs) {
71
+ const dirs = allowedDirs ?? loadAllowedDirs();
72
+ for (const filePath of filePaths) {
73
+ if (!isPathSafe(filePath, dirs)) {
74
+ throw new Error(`Access denied: path outside allowed directories: ${filePath}`);
75
+ }
76
+ }
77
+ }
78
+ //# sourceMappingURL=pathSecurity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathSecurity.js","sourceRoot":"","sources":["../../../server/utils/pathSecurity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACtD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAMpD;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;YAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjE,OAAO,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IACD,2DAA2D;IAC3D,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,UAAkB,EAAE,WAAqB;IAClE,iCAAiC;IACjC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5C,yCAAyC;IACzC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5C,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IAEnD,kDAAkD;IAClD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,WAAsB;IACvE,MAAM,IAAI,GAAG,WAAW,IAAI,eAAe,EAAE,CAAC;IAE9C,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAmB,EAAE,WAAsB;IAC3E,MAAM,IAAI,GAAG,WAAW,IAAI,eAAe,EAAE,CAAC;IAE9C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,oDAAoD,QAAQ,EAAE,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Budget Allocator - Epistemic Budget Allocation Engine
3
+ *
4
+ * Allocates token budgets across knowledge sources based on epistemic weight
5
+ * and content characteristics. Ensures higher-priority knowledge types get
6
+ * proportionally more tokens while respecting minimum floors.
7
+ */
8
+ import type { KnowledgeType } from '../store/knowledgeBase.js';
9
+ export declare const TYPE_WEIGHTS: Record<KnowledgeType, number>;
10
+ export declare const MIN_BUDGET_FLOOR = 0.03;
11
+ export declare const DEPTH_MULTIPLIERS: Record<number, number>;
12
+ export interface BudgetSource {
13
+ name: string;
14
+ knowledgeType: KnowledgeType;
15
+ rawTokens: number;
16
+ depthMultiplier?: number;
17
+ }
18
+ export interface BudgetAllocation {
19
+ name: string;
20
+ knowledgeType: KnowledgeType;
21
+ allocatedTokens: number;
22
+ weight: number;
23
+ cappedBySize: boolean;
24
+ }
25
+ /**
26
+ * Allocate token budgets across sources using epistemic weighting.
27
+ *
28
+ * Algorithm:
29
+ * 1. Group sources by knowledge type
30
+ * 2. Calculate raw weight = TYPE_WEIGHTS[type] / count(same type) * (depthMultiplier || 1.0)
31
+ * 3. Apply minimum budget floor: max(rawWeight, MIN_BUDGET_FLOOR)
32
+ * 4. Normalize weights to sum = 1.0
33
+ * 5. Calculate allocatedTokens = weight * totalBudget
34
+ * 6. Cap by actual content size - redistribute excess (max 3 rounds)
35
+ */
36
+ export declare function allocateBudgets(sources: BudgetSource[], totalBudget: number): BudgetAllocation[];
37
+ //# sourceMappingURL=budgetAllocator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budgetAllocator.d.ts","sourceRoot":"","sources":["../../../src/services/budgetAllocator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG/D,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAO7C,CAAC;AAGX,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAGrC,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAM3C,CAAC;AAEX,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,aAAa,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,YAAY,EAAE,EACvB,WAAW,EAAE,MAAM,GAClB,gBAAgB,EAAE,CAyFpB"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Budget Allocator - Epistemic Budget Allocation Engine
3
+ *
4
+ * Allocates token budgets across knowledge sources based on epistemic weight
5
+ * and content characteristics. Ensures higher-priority knowledge types get
6
+ * proportionally more tokens while respecting minimum floors.
7
+ */
8
+ // Epistemic weights by knowledge type (must sum to 1.0)
9
+ export const TYPE_WEIGHTS = {
10
+ 'ground-truth': 0.30,
11
+ 'guideline': 0.15,
12
+ 'framework': 0.15,
13
+ 'evidence': 0.20,
14
+ 'signal': 0.12,
15
+ 'hypothesis': 0.08,
16
+ };
17
+ // Minimum budget floor as percentage of total budget
18
+ export const MIN_BUDGET_FLOOR = 0.03;
19
+ // Depth multipliers for content at different tree depths
20
+ export const DEPTH_MULTIPLIERS = {
21
+ 0: 1.5, // Full depth - most important
22
+ 1: 1.2, // Detail depth
23
+ 2: 1.0, // Summary depth - baseline
24
+ 3: 0.6, // Headlines depth
25
+ 4: 0.2, // Mention depth - least important
26
+ };
27
+ /**
28
+ * Allocate token budgets across sources using epistemic weighting.
29
+ *
30
+ * Algorithm:
31
+ * 1. Group sources by knowledge type
32
+ * 2. Calculate raw weight = TYPE_WEIGHTS[type] / count(same type) * (depthMultiplier || 1.0)
33
+ * 3. Apply minimum budget floor: max(rawWeight, MIN_BUDGET_FLOOR)
34
+ * 4. Normalize weights to sum = 1.0
35
+ * 5. Calculate allocatedTokens = weight * totalBudget
36
+ * 6. Cap by actual content size - redistribute excess (max 3 rounds)
37
+ */
38
+ export function allocateBudgets(sources, totalBudget) {
39
+ if (sources.length === 0)
40
+ return [];
41
+ if (totalBudget <= 0)
42
+ return sources.map(s => ({
43
+ name: s.name,
44
+ knowledgeType: s.knowledgeType,
45
+ allocatedTokens: 0,
46
+ weight: 0,
47
+ cappedBySize: false,
48
+ }));
49
+ // 1. Group sources by knowledge type
50
+ const typeGroups = new Map();
51
+ for (const source of sources) {
52
+ if (!typeGroups.has(source.knowledgeType)) {
53
+ typeGroups.set(source.knowledgeType, []);
54
+ }
55
+ typeGroups.get(source.knowledgeType).push(source);
56
+ }
57
+ // 2. Calculate raw weights
58
+ const allocations = [];
59
+ for (const [type, groupSources] of typeGroups) {
60
+ const typeWeight = TYPE_WEIGHTS[type];
61
+ const groupSize = groupSources.length;
62
+ for (const source of groupSources) {
63
+ const depthMultiplier = source.depthMultiplier ?? 1.0;
64
+ const rawWeight = (typeWeight / groupSize) * depthMultiplier;
65
+ // 3. Apply minimum budget floor
66
+ const flooredWeight = Math.max(rawWeight, MIN_BUDGET_FLOOR);
67
+ allocations.push({
68
+ name: source.name,
69
+ knowledgeType: source.knowledgeType,
70
+ allocatedTokens: 0, // Will be calculated after normalization
71
+ weight: flooredWeight,
72
+ cappedBySize: false,
73
+ });
74
+ }
75
+ }
76
+ // 4. Normalize weights to sum = 1.0
77
+ const totalWeight = allocations.reduce((sum, a) => sum + a.weight, 0);
78
+ if (totalWeight > 0) {
79
+ for (const allocation of allocations) {
80
+ allocation.weight = allocation.weight / totalWeight;
81
+ }
82
+ }
83
+ // 5. Initial budget allocation
84
+ for (const allocation of allocations) {
85
+ allocation.allocatedTokens = Math.round(allocation.weight * totalBudget);
86
+ }
87
+ // 6. Cap by content size and redistribute excess (max 3 rounds)
88
+ const sourceMap = new Map(sources.map(s => [s.name, s]));
89
+ for (let round = 0; round < 3; round++) {
90
+ let totalExcess = 0;
91
+ const uncappedAllocations = [];
92
+ // Find excess from capped sources
93
+ for (const allocation of allocations) {
94
+ const source = sourceMap.get(allocation.name);
95
+ if (allocation.allocatedTokens > source.rawTokens) {
96
+ totalExcess += allocation.allocatedTokens - source.rawTokens;
97
+ allocation.allocatedTokens = source.rawTokens;
98
+ allocation.cappedBySize = true;
99
+ }
100
+ else if (!allocation.cappedBySize) {
101
+ uncappedAllocations.push(allocation);
102
+ }
103
+ }
104
+ // Redistribute excess to uncapped sources
105
+ if (totalExcess > 0 && uncappedAllocations.length > 0) {
106
+ const totalUncappedWeight = uncappedAllocations.reduce((sum, a) => sum + a.weight, 0);
107
+ if (totalUncappedWeight > 0) {
108
+ for (const allocation of uncappedAllocations) {
109
+ const redistribution = Math.round((allocation.weight / totalUncappedWeight) * totalExcess);
110
+ allocation.allocatedTokens += redistribution;
111
+ }
112
+ }
113
+ }
114
+ else {
115
+ break; // No more redistribution needed
116
+ }
117
+ }
118
+ return allocations;
119
+ }
120
+ //# sourceMappingURL=budgetAllocator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budgetAllocator.js","sourceRoot":"","sources":["../../../src/services/budgetAllocator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type KnowledgeType } from '../store/knowledgeBase.js';
2
+ interface SourceBlock {
3
+ name: string;
4
+ type: KnowledgeType;
5
+ content: string;
6
+ }
7
+ interface ContradictionResult {
8
+ sources: SourceBlock[];
9
+ annotations: string[];
10
+ contradictionsFound: number;
11
+ }
12
+ /**
13
+ * Resolves contradictions between sources by prioritizing higher-authority sources
14
+ * For same entities appearing in multiple sources with different types
15
+ */
16
+ export declare function resolveContradictions(sources: SourceBlock[]): ContradictionResult;
17
+ export {};
18
+ //# sourceMappingURL=contradictionDetector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contradictionDetector.d.ts","sourceRoot":"","sources":["../../../src/services/contradictionDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,mBAAmB;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAiCD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,mBAAmB,CAoGjF"}