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 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * MCP session manager — maintains per-directory swarm state.
3
+ *
4
+ * Each directory gets its own session with:
5
+ * - ThreadManager (spawning/tracking threads)
6
+ * - SwarmConfig (loaded from the project dir)
7
+ * - AbortController (for cancellation)
8
+ * - BudgetState (cost tracking)
9
+ *
10
+ * Sessions are lazily initialized on first tool call and persist
11
+ * across multiple MCP tool invocations.
12
+ *
13
+ * Concurrency:
14
+ * - pendingSessions deduplicates concurrent init for the same dir
15
+ * - loadConfig(cwd) avoids process.chdir() race conditions
16
+ */
17
+ import type { SwarmConfig } from "../config.js";
18
+ import { ActionDispatcher } from "../core/action-dispatcher.js";
19
+ import type { BudgetState, CompressedResult, MergeResult, ThreadState, VerificationSpec } from "../core/types.js";
20
+ import { ThreadManager } from "../threads/manager.js";
21
+ import { type AsyncTaskRecord } from "./state.js";
22
+ export interface SwarmSession {
23
+ dir: string;
24
+ config: SwarmConfig;
25
+ threadManager: ThreadManager;
26
+ abortController: AbortController;
27
+ createdAt: number;
28
+ dispatcher?: ActionDispatcher;
29
+ }
30
+ export interface ThreadSpawnParams {
31
+ id?: string;
32
+ task: string;
33
+ files?: string[];
34
+ writeScope?: string[];
35
+ writeScopeDeny?: string[];
36
+ allowRepositoryWide?: boolean;
37
+ focusFiles?: string[];
38
+ agent?: string;
39
+ model?: string;
40
+ context?: string;
41
+ testCommand?: string;
42
+ verificationSpec?: VerificationSpec;
43
+ expectedResult?: string;
44
+ maxAttempts?: number;
45
+ }
46
+ /** Inspect existing state without initializing agents, worktrees or migrations. */
47
+ export declare function inspectSession(dir: string): {
48
+ dir: string;
49
+ threads: ThreadState[];
50
+ asyncTasks: Record<string, AsyncTaskRecord>;
51
+ budget: BudgetState;
52
+ } | {
53
+ dir: string;
54
+ threads: ThreadState[];
55
+ asyncTasks: Record<string, AsyncTaskRecord>;
56
+ budget: {
57
+ totalSpentUsd: number;
58
+ sessionLimitUsd: number;
59
+ totalTokens: {
60
+ input: number;
61
+ output: number;
62
+ };
63
+ };
64
+ };
65
+ /**
66
+ * Get or create a session for a directory.
67
+ * The directory is resolved to an absolute path and used as the session key.
68
+ * Concurrent calls for the same directory are deduplicated.
69
+ */
70
+ export declare function getSession(dir: string): Promise<SwarmSession>;
71
+ /**
72
+ * Spawn a thread in a session.
73
+ */
74
+ export declare function spawnThread(session: SwarmSession, params: ThreadSpawnParams): Promise<CompressedResult>;
75
+ /**
76
+ * Get all threads in a session (merging memory with persisted state).
77
+ */
78
+ export declare function getThreads(session: SwarmSession): ThreadState[];
79
+ /**
80
+ * Record an async job into persistent state.
81
+ */
82
+ export declare function recordAsyncJob(session: SwarmSession, taskId: string, agentCount: number, status?: "running" | "completed" | "failed" | "unknown_after_restart"): void;
83
+ /**
84
+ * Get all async jobs from persistent state.
85
+ */
86
+ export declare function getAsyncJobs(session: SwarmSession): Record<string, AsyncTaskRecord>;
87
+ /**
88
+ * Get budget state for a session.
89
+ */
90
+ export declare function getBudgetState(session: SwarmSession): BudgetState;
91
+ /**
92
+ * Merge completed threads.
93
+ */
94
+ export declare function mergeThreads(session: SwarmSession): Promise<MergeResult[]>;
95
+ /**
96
+ * Cancel a specific thread or all threads.
97
+ * Per-thread cancellation uses ThreadManager.cancelThread() which
98
+ * aborts the thread's individual AbortController.
99
+ */
100
+ export declare function cancelThreads(session: SwarmSession, threadId?: string): {
101
+ cancelled: boolean;
102
+ message: string;
103
+ };
104
+ /**
105
+ * Cleanup a session — destroy worktrees, remove session.
106
+ * @param dryRun - If true, report what would be cleaned without actually deleting.
107
+ */
108
+ export declare function cleanupSession(dir: string, purgeAllOrphans?: boolean, dryRun?: boolean): Promise<string>;
109
+ /**
110
+ * Cleanup all sessions. Snapshots keys first to avoid
111
+ * mutating the map during iteration.
112
+ */
113
+ export declare function cleanupAllSessions(): Promise<void>;
114
+ /**
115
+ * Creates an ActionDispatcher wired to a SwarmSession for declarative orchestration.
116
+ */
117
+ export declare function createSessionDispatcher(session: SwarmSession): ActionDispatcher;
@@ -0,0 +1,450 @@
1
+ /**
2
+ * MCP session manager — maintains per-directory swarm state.
3
+ *
4
+ * Each directory gets its own session with:
5
+ * - ThreadManager (spawning/tracking threads)
6
+ * - SwarmConfig (loaded from the project dir)
7
+ * - AbortController (for cancellation)
8
+ * - BudgetState (cost tracking)
9
+ *
10
+ * Sessions are lazily initialized on first tool call and persist
11
+ * across multiple MCP tool invocations.
12
+ *
13
+ * Concurrency:
14
+ * - pendingSessions deduplicates concurrent init for the same dir
15
+ * - loadConfig(cwd) avoids process.chdir() race conditions
16
+ */
17
+ import { randomUUID } from "node:crypto";
18
+ import * as fs from "node:fs";
19
+ import * as path from "node:path";
20
+ import { loadConfig } from "../config.js";
21
+ import { ActionDispatcher } from "../core/action-dispatcher.js";
22
+ import { assertWithinRepository } from "../security/repository-boundary.js";
23
+ import { ThreadManager } from "../threads/manager.js";
24
+ import { isEligibleForMerge, mergeAllThreads, mergeThreadBranch } from "../worktree/merge.js";
25
+ import { clearPersistedState, getPersistedAsyncTasks, getPersistedThreads, purgeOrphans, reconcileSessionStateWithGit, recordAsyncTask, recordThreadState, } from "./state.js";
26
+ // ── Session Manager ────────────────────────────────────────────────────────
27
+ const sessions = new Map();
28
+ /** Deduplicates concurrent getSession() calls for the same directory. */
29
+ const pendingSessions = new Map();
30
+ /** Inspect existing state without initializing agents, worktrees or migrations. */
31
+ export function inspectSession(dir) {
32
+ const canonicalDir = assertWithinRepository(path.resolve(dir), path.resolve(dir));
33
+ const session = sessions.get(canonicalDir);
34
+ if (session)
35
+ return {
36
+ dir: canonicalDir,
37
+ threads: getThreads(session),
38
+ asyncTasks: getAsyncJobs(session),
39
+ budget: getBudgetState(session),
40
+ };
41
+ const config = loadConfig(canonicalDir);
42
+ const threads = getPersistedThreads(canonicalDir, config.worktree_base_dir);
43
+ const asyncTasks = getPersistedAsyncTasks(canonicalDir, config.worktree_base_dir);
44
+ return {
45
+ dir: canonicalDir,
46
+ threads,
47
+ asyncTasks,
48
+ budget: {
49
+ totalSpentUsd: threads.reduce((sum, thread) => sum + (thread.result?.estimatedCostUsd ?? thread.estimatedCostUsd ?? 0), 0),
50
+ sessionLimitUsd: config.max_session_budget_usd,
51
+ totalTokens: threads.reduce((sum, thread) => ({
52
+ input: sum.input + (thread.result?.usage?.inputTokens || 0),
53
+ output: sum.output + (thread.result?.usage?.outputTokens || 0),
54
+ }), { input: 0, output: 0 }),
55
+ },
56
+ };
57
+ }
58
+ /**
59
+ * Lazily init agent backends (only once).
60
+ * Agent modules self-register when imported.
61
+ * The flag is set eagerly to prevent duplicate imports even if
62
+ * the first call hasn't finished awaiting yet.
63
+ */
64
+ let agentsRegistered = false;
65
+ async function ensureAgentsRegistered() {
66
+ if (agentsRegistered)
67
+ return;
68
+ agentsRegistered = true;
69
+ // Each agent module calls registerAgent() at module level on import
70
+ const modules = [
71
+ import("../agents/opencode.js"),
72
+ import("../agents/claude-code.js"),
73
+ import("../agents/codex.js"),
74
+ import("../agents/aider.js"),
75
+ import("../agents/direct-llm.js"),
76
+ ];
77
+ // Import all, ignoring individual failures
78
+ await Promise.allSettled(modules);
79
+ }
80
+ /**
81
+ * Get or create a session for a directory.
82
+ * The directory is resolved to an absolute path and used as the session key.
83
+ * Concurrent calls for the same directory are deduplicated.
84
+ */
85
+ export async function getSession(dir) {
86
+ const absDir = path.resolve(dir);
87
+ if (!fs.existsSync(absDir)) {
88
+ throw new Error(`Directory does not exist: ${absDir}`);
89
+ }
90
+ const canonicalDir = assertWithinRepository(absDir, absDir);
91
+ // Return existing session
92
+ const existing = sessions.get(canonicalDir);
93
+ if (existing)
94
+ return existing;
95
+ // Deduplicate concurrent init for the same dir
96
+ const pending = pendingSessions.get(canonicalDir);
97
+ if (pending)
98
+ return pending;
99
+ const initPromise = initSession(canonicalDir);
100
+ pendingSessions.set(canonicalDir, initPromise);
101
+ try {
102
+ const session = await initPromise;
103
+ return session;
104
+ }
105
+ finally {
106
+ pendingSessions.delete(canonicalDir);
107
+ }
108
+ }
109
+ /**
110
+ * Initialize a new session for a directory.
111
+ * Uses loadConfig(cwd) to avoid process.chdir() race conditions.
112
+ */
113
+ async function initSession(absDir) {
114
+ await ensureAgentsRegistered();
115
+ // Load config from project dir without chdir (concurrency-safe)
116
+ const config = loadConfig(absDir);
117
+ const abortController = new AbortController();
118
+ // ThreadManager creates its own WorktreeManager internally,
119
+ // so we don't need a separate one at the session level.
120
+ const threadManager = new ThreadManager(absDir, config,
121
+ // Progress callback — log to stderr (stdout is MCP protocol) and persist to disk
122
+ (threadId, phase, detail) => {
123
+ const msg = detail ? `[${threadId}] ${phase}: ${detail}` : `[${threadId}] ${phase}`;
124
+ process.stderr.write(`[swarm-mcp] ${msg}\n`);
125
+ const current = threadManager.getThreads();
126
+ const t = current.find((item) => item.id === threadId);
127
+ if (t) {
128
+ recordThreadState(absDir, t, config.worktree_base_dir);
129
+ }
130
+ }, abortController.signal);
131
+ await threadManager.init();
132
+ // Task 2.5d: Reconcile persisted state against active git worktrees on startup
133
+ await reconcileSessionStateWithGit(absDir, config.worktree_base_dir);
134
+ // Rehydrate threads from persisted state (survives server restart)
135
+ const persisted = getPersistedThreads(absDir, config.worktree_base_dir);
136
+ for (const thread of persisted) {
137
+ threadManager.restoreThread(thread);
138
+ }
139
+ // Mark lingering running async tasks as unknown_after_restart
140
+ const asyncTasks = getPersistedAsyncTasks(absDir, config.worktree_base_dir);
141
+ for (const task of Object.values(asyncTasks)) {
142
+ if (task.status === "running") {
143
+ recordAsyncTask(absDir, { ...task, status: "unknown_after_restart" }, config.worktree_base_dir);
144
+ }
145
+ }
146
+ const session = {
147
+ dir: absDir,
148
+ config,
149
+ threadManager,
150
+ abortController,
151
+ createdAt: Date.now(),
152
+ };
153
+ session.dispatcher = createSessionDispatcher(session);
154
+ sessions.set(absDir, session);
155
+ return session;
156
+ }
157
+ /**
158
+ * Spawn a thread in a session.
159
+ */
160
+ export async function spawnThread(session, params) {
161
+ const threadId = params.id || `mcp-${randomUUID()}`;
162
+ if (params.files) {
163
+ for (const file of params.files) {
164
+ assertWithinRepository(path.resolve(session.dir, file), session.dir);
165
+ }
166
+ }
167
+ const threadConfig = {
168
+ id: threadId,
169
+ task: params.task,
170
+ context: params.context || "",
171
+ agent: {
172
+ backend: params.agent || session.config.default_agent,
173
+ model: params.model || session.config.default_model,
174
+ },
175
+ files: params.focusFiles || params.files || [],
176
+ focusFiles: params.focusFiles || params.files || [],
177
+ writeScope: params.writeScope || [],
178
+ writeScopeDeny: params.writeScopeDeny || [],
179
+ allowRepositoryWide: params.allowRepositoryWide ?? params.writeScope?.includes(".") ?? false,
180
+ verificationSpec: params.verificationSpec,
181
+ testCommand: params.testCommand ||
182
+ (params.verificationSpec?.executable
183
+ ? `${params.verificationSpec.executable} ${params.verificationSpec.args.join(" ")}`.trim()
184
+ : undefined),
185
+ taskBrief: params.testCommand || params.verificationSpec || params.expectedResult || params.maxAttempts || params.writeScope
186
+ ? {
187
+ taskId: threadId,
188
+ baseSha: "",
189
+ objective: params.task,
190
+ writeScope: params.writeScope || [],
191
+ writeScopeDeny: params.writeScopeDeny || [],
192
+ allowRepositoryWide: params.allowRepositoryWide ?? params.writeScope?.includes(".") ?? false,
193
+ focusFiles: params.focusFiles || params.files || [],
194
+ testCommand: params.testCommand ||
195
+ (params.verificationSpec?.executable
196
+ ? `${params.verificationSpec.executable} ${params.verificationSpec.args.join(" ")}`.trim()
197
+ : ""),
198
+ verificationSpec: params.verificationSpec,
199
+ expectedResult: params.expectedResult || "Task completes successfully",
200
+ maxAttempts: params.maxAttempts || session.config.thread_retries + 1,
201
+ }
202
+ : undefined,
203
+ };
204
+ const resultPromise = session.threadManager.spawnThread(threadConfig);
205
+ const initialThread = session.threadManager.getThreads().find((t) => t.id === threadId);
206
+ if (initialThread) {
207
+ recordThreadState(session.dir, initialThread, session.config.worktree_base_dir);
208
+ }
209
+ const result = await resultPromise;
210
+ const finalThread = session.threadManager.getThreads().find((t) => t.id === threadId);
211
+ if (finalThread) {
212
+ recordThreadState(session.dir, finalThread, session.config.worktree_base_dir);
213
+ }
214
+ return result;
215
+ }
216
+ /**
217
+ * Get all threads in a session (merging memory with persisted state).
218
+ */
219
+ export function getThreads(session) {
220
+ const memoryThreads = session.threadManager.getThreads();
221
+ const persisted = getPersistedThreads(session.dir, session.config.worktree_base_dir);
222
+ const map = new Map();
223
+ for (const t of persisted)
224
+ map.set(t.id, t);
225
+ for (const t of memoryThreads)
226
+ map.set(t.id, t);
227
+ return Array.from(map.values());
228
+ }
229
+ /**
230
+ * Record an async job into persistent state.
231
+ */
232
+ export function recordAsyncJob(session, taskId, agentCount, status = "running") {
233
+ recordAsyncTask(session.dir, { taskId, agentCount, startedAt: Date.now(), status }, session.config.worktree_base_dir);
234
+ }
235
+ /**
236
+ * Get all async jobs from persistent state.
237
+ */
238
+ export function getAsyncJobs(session) {
239
+ return getPersistedAsyncTasks(session.dir, session.config.worktree_base_dir);
240
+ }
241
+ /**
242
+ * Get budget state for a session.
243
+ */
244
+ export function getBudgetState(session) {
245
+ return session.threadManager.getBudgetState();
246
+ }
247
+ /**
248
+ * Merge completed threads.
249
+ */
250
+ export async function mergeThreads(session) {
251
+ const threads = session.threadManager.getThreads();
252
+ return mergeAllThreads(session.dir, threads, { continueOnConflict: true });
253
+ }
254
+ /**
255
+ * Cancel a specific thread or all threads.
256
+ * Per-thread cancellation uses ThreadManager.cancelThread() which
257
+ * aborts the thread's individual AbortController.
258
+ */
259
+ export function cancelThreads(session, threadId) {
260
+ if (threadId) {
261
+ const cancelled = session.threadManager.cancelThread(threadId);
262
+ if (!cancelled) {
263
+ const threads = session.threadManager.getThreads();
264
+ const thread = threads.find((t) => t.id === threadId);
265
+ if (!thread)
266
+ return { cancelled: false, message: `Thread ${threadId} not found` };
267
+ return { cancelled: false, message: `Thread ${threadId} is ${thread.status}, cannot cancel` };
268
+ }
269
+ return { cancelled: true, message: `Thread ${threadId} cancelled` };
270
+ }
271
+ // Cancel all — abort the session controller
272
+ session.abortController.abort();
273
+ return { cancelled: true, message: "All threads cancelled" };
274
+ }
275
+ /**
276
+ * Cleanup a session — destroy worktrees, remove session.
277
+ * @param dryRun - If true, report what would be cleaned without actually deleting.
278
+ */
279
+ export async function cleanupSession(dir, purgeAllOrphans = false, dryRun = false) {
280
+ const absDir = path.resolve(dir);
281
+ const canonicalDir = fs.existsSync(absDir) ? assertWithinRepository(absDir, absDir) : absDir;
282
+ const session = sessions.get(canonicalDir) || sessions.get(absDir);
283
+ const worktreeBaseDir = session?.config.worktree_base_dir;
284
+ if (!session && !purgeAllOrphans) {
285
+ if (!dryRun && fs.existsSync(canonicalDir))
286
+ clearPersistedState(canonicalDir, worktreeBaseDir);
287
+ return "No active session for this directory";
288
+ }
289
+ if (session && !dryRun) {
290
+ session.abortController.abort();
291
+ await session.threadManager.cleanup();
292
+ sessions.delete(canonicalDir);
293
+ sessions.delete(absDir);
294
+ }
295
+ if (!dryRun && fs.existsSync(canonicalDir)) {
296
+ clearPersistedState(canonicalDir, worktreeBaseDir);
297
+ }
298
+ if (purgeAllOrphans) {
299
+ const { prunedWorktrees, deletedBranches, report } = await purgeOrphans(canonicalDir, dryRun, worktreeBaseDir);
300
+ const prefix = dryRun ? "[DRY RUN] " : "";
301
+ const reportStr = report.length > 0 ? `\n${report.join("\n")}` : "";
302
+ return `${prefix}Session cleaned up for ${canonicalDir} (purged ${prunedWorktrees} orphan worktree dirs, ${deletedBranches} branches)${reportStr}`;
303
+ }
304
+ return `Session cleaned up for ${canonicalDir}`;
305
+ }
306
+ /**
307
+ * Cleanup all sessions. Snapshots keys first to avoid
308
+ * mutating the map during iteration.
309
+ */
310
+ export async function cleanupAllSessions() {
311
+ const dirs = [...sessions.keys()];
312
+ for (const dir of dirs) {
313
+ await cleanupSession(dir);
314
+ }
315
+ }
316
+ /**
317
+ * Creates an ActionDispatcher wired to a SwarmSession for declarative orchestration.
318
+ */
319
+ export function createSessionDispatcher(session) {
320
+ return new ActionDispatcher({
321
+ async spawn(action) {
322
+ const threadId = `mcp-${randomUUID()}`;
323
+ const result = await spawnThread(session, {
324
+ id: threadId,
325
+ task: action.task,
326
+ files: action.focusFiles || [],
327
+ writeScope: action.writeScope,
328
+ focusFiles: action.focusFiles || [],
329
+ model: action.model,
330
+ });
331
+ return {
332
+ threadId,
333
+ success: result.success,
334
+ summary: result.summary,
335
+ filesChanged: result.filesChanged,
336
+ durationMs: result.durationMs,
337
+ };
338
+ },
339
+ async wait(action) {
340
+ const threads = getThreads(session);
341
+ const matched = threads.filter((t) => action.threadIds.includes(t.id));
342
+ return {
343
+ threads: matched.map((t) => ({
344
+ id: t.id,
345
+ status: t.status,
346
+ phase: t.phase,
347
+ success: t.result?.success,
348
+ })),
349
+ };
350
+ },
351
+ async inspectDiff(action) {
352
+ const threads = getThreads(session);
353
+ const thread = threads.find((t) => t.id === action.threadId);
354
+ if (!thread) {
355
+ return { error: `Thread ${action.threadId} not found` };
356
+ }
357
+ let diff = "";
358
+ if (thread.worktreePath) {
359
+ const wm = session.threadManager.getWorktreeManager();
360
+ diff = await wm.getDiff(action.threadId);
361
+ }
362
+ return {
363
+ threadId: action.threadId,
364
+ diff,
365
+ diffStats: thread.result?.diffStats || "",
366
+ filesChanged: thread.result?.filesChanged || [],
367
+ };
368
+ },
369
+ async review(action) {
370
+ const threads = getThreads(session);
371
+ const thread = threads.find((t) => t.id === action.threadId);
372
+ if (!thread) {
373
+ return { error: `Thread ${action.threadId} not found` };
374
+ }
375
+ // Acquire lease for thread mutation
376
+ const store = require("../mcp/state.js").getThreadStore(session.dir);
377
+ let lease = null;
378
+ if (store && typeof store.acquireLease === "function") {
379
+ lease = store.acquireLease(action.threadId, "mcp-action");
380
+ if (!lease.tryAcquire()) {
381
+ return { error: `Thread ${action.threadId} is locked by another process (failed to acquire lease)` };
382
+ }
383
+ }
384
+ try {
385
+ return {
386
+ threadId: action.threadId,
387
+ status: thread.status,
388
+ reviewed: Boolean(thread.review),
389
+ verdict: thread.review,
390
+ };
391
+ }
392
+ finally {
393
+ if (lease)
394
+ lease.release();
395
+ }
396
+ },
397
+ async merge(action) {
398
+ const threads = getThreads(session);
399
+ const thread = threads.find((t) => t.id === action.threadId);
400
+ if (!thread) {
401
+ return { error: `Thread ${action.threadId} not found` };
402
+ }
403
+ if (!thread.branchName) {
404
+ return { error: `Thread ${action.threadId} has no branch` };
405
+ }
406
+ const eligibility = isEligibleForMerge(thread);
407
+ if (!eligibility.eligible) {
408
+ return {
409
+ threadId: action.threadId,
410
+ merged: false,
411
+ error: `Merge blocked by strict merge predicate: ${eligibility.reason}`,
412
+ };
413
+ }
414
+ // Acquire lease for thread mutation
415
+ const store = require("../mcp/state.js").getThreadStore(session.dir);
416
+ let lease = null;
417
+ if (store && typeof store.acquireLease === "function") {
418
+ lease = store.acquireLease(action.threadId, "mcp-action");
419
+ if (!lease.tryAcquire()) {
420
+ return {
421
+ threadId: action.threadId,
422
+ merged: false,
423
+ error: `Thread ${action.threadId} is locked by another process (failed to acquire lease)`,
424
+ };
425
+ }
426
+ }
427
+ try {
428
+ const result = await mergeThreadBranch(session.dir, thread.branchName, action.threadId, thread);
429
+ return {
430
+ threadId: action.threadId,
431
+ merged: result.success,
432
+ branch: result.branch,
433
+ message: result.message,
434
+ conflicts: result.conflicts,
435
+ };
436
+ }
437
+ finally {
438
+ if (lease)
439
+ lease.release();
440
+ }
441
+ },
442
+ async finish(action) {
443
+ return {
444
+ finished: true,
445
+ summary: action.summary,
446
+ };
447
+ },
448
+ });
449
+ }
450
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/mcp/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Persistent session and thread state storage for ContextOS MCP server.
3
+ *
4
+ * Ensures that thread execution states, worktree locations, and results
5
+ * survive MCP server process restarts and can be recovered or cleaned up.
6
+ *
7
+ * Integrates with ContextOS Runtime v2 ThreadStore.
8
+ */
9
+ import type { ThreadState } from "../core/types.js";
10
+ export interface AsyncTaskRecord {
11
+ taskId: string;
12
+ agentCount: number;
13
+ startedAt: number;
14
+ status: "running" | "completed" | "failed" | "unknown_after_restart";
15
+ }
16
+ export interface OrphanReport {
17
+ worktreeDirs: string[];
18
+ swarmBranches: string[];
19
+ }
20
+ export interface StateLockData {
21
+ pid: number;
22
+ sessionId?: string;
23
+ lockedAt: number;
24
+ }
25
+ export declare function isProcessAlive(pid: number): boolean;
26
+ export declare function acquireStateLock(dir: string, sessionId?: string): (() => void) | null;
27
+ export declare function reconcileSessionStateWithGit(repoRoot: string, worktreeBaseDir?: string): Promise<{
28
+ threads: ThreadState[];
29
+ } | null>;
30
+ export declare function recordThreadState(dir: string, thread: ThreadState, _worktreeBaseDir?: string): void;
31
+ export declare function savePersistedState(dir: string, state: any, worktreeBaseDir?: string): void;
32
+ export declare function loadPersistedState(dir: string, worktreeBaseDir?: string): any;
33
+ export declare function recordAsyncTask(dir: string, task: AsyncTaskRecord, _worktreeBaseDir?: string): void;
34
+ export declare function getPersistedThreads(dir: string, _worktreeBaseDir?: string): ThreadState[];
35
+ export declare function getPersistedAsyncTasks(dir: string, _worktreeBaseDir?: string): Record<string, AsyncTaskRecord>;
36
+ export declare function clearPersistedState(_dir: string, _worktreeBaseDir?: string): void;
37
+ export declare function scanOrphanWorktrees(repoRoot: string, worktreeBaseDir?: string): Promise<OrphanReport>;
38
+ export declare function purgeOrphans(repoRoot: string, dryRun?: boolean, worktreeBaseDir?: string): Promise<{
39
+ prunedWorktrees: number;
40
+ deletedBranches: number;
41
+ report: string[];
42
+ }>;