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.
- package/LICENSE +21 -0
- package/README.md +260 -0
- package/bin/mcp.mjs +61 -0
- package/bin/swarm.mjs +45 -0
- package/dist/agents/aider.d.ts +12 -0
- package/dist/agents/aider.js +192 -0
- package/dist/agents/aider.js.map +1 -0
- package/dist/agents/claude-code.d.ts +9 -0
- package/dist/agents/claude-code.js +236 -0
- package/dist/agents/claude-code.js.map +1 -0
- package/dist/agents/codex.d.ts +14 -0
- package/dist/agents/codex.js +203 -0
- package/dist/agents/codex.js.map +1 -0
- package/dist/agents/direct-llm.d.ts +22 -0
- package/dist/agents/direct-llm.js +254 -0
- package/dist/agents/direct-llm.js.map +1 -0
- package/dist/agents/mock.d.ts +10 -0
- package/dist/agents/mock.js +170 -0
- package/dist/agents/mock.js.map +1 -0
- package/dist/agents/opencode.d.ts +23 -0
- package/dist/agents/opencode.js +631 -0
- package/dist/agents/opencode.js.map +1 -0
- package/dist/agents/provider.d.ts +11 -0
- package/dist/agents/provider.js +31 -0
- package/dist/agents/provider.js.map +1 -0
- package/dist/compression/compressor.d.ts +28 -0
- package/dist/compression/compressor.js +268 -0
- package/dist/compression/compressor.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.js +172 -0
- package/dist/config.js.map +1 -0
- package/dist/contextos/loader.d.ts +46 -0
- package/dist/contextos/loader.js +120 -0
- package/dist/contextos/loader.js.map +1 -0
- package/dist/contextos/selector.d.ts +46 -0
- package/dist/contextos/selector.js +80 -0
- package/dist/contextos/selector.js.map +1 -0
- package/dist/core/action-dispatcher.d.ts +15 -0
- package/dist/core/action-dispatcher.js +28 -0
- package/dist/core/action-dispatcher.js.map +1 -0
- package/dist/core/action-schema.d.ts +72 -0
- package/dist/core/action-schema.js +86 -0
- package/dist/core/action-schema.js.map +1 -0
- package/dist/core/repl-interface.d.ts +48 -0
- package/dist/core/repl-interface.js +5 -0
- package/dist/core/repl-interface.js.map +1 -0
- package/dist/core/repl.d.ts +59 -0
- package/dist/core/repl.js +353 -0
- package/dist/core/repl.js.map +1 -0
- package/dist/core/rlm.d.ts +65 -0
- package/dist/core/rlm.js +564 -0
- package/dist/core/rlm.js.map +1 -0
- package/dist/core/runtime.py +470 -0
- package/dist/core/types.d.ts +265 -0
- package/dist/core/types.js +19 -0
- package/dist/core/types.js.map +1 -0
- package/dist/env.d.ts +10 -0
- package/dist/env.js +75 -0
- package/dist/env.js.map +1 -0
- package/dist/hooks/runner.d.ts +43 -0
- package/dist/hooks/runner.js +173 -0
- package/dist/hooks/runner.js.map +1 -0
- package/dist/labs/cli.d.ts +15 -0
- package/dist/labs/cli.js +295 -0
- package/dist/labs/cli.js.map +1 -0
- package/dist/labs/episodic-memory.d.ts +132 -0
- package/dist/labs/episodic-memory.js +391 -0
- package/dist/labs/episodic-memory.js.map +1 -0
- package/dist/labs/interactive-swarm.d.ts +20 -0
- package/dist/labs/interactive-swarm.js +1173 -0
- package/dist/labs/interactive-swarm.js.map +1 -0
- package/dist/labs/interactive.d.ts +10 -0
- package/dist/labs/interactive.js +2099 -0
- package/dist/labs/interactive.js.map +1 -0
- package/dist/labs/ts-analyzer.d.ts +74 -0
- package/dist/labs/ts-analyzer.js +379 -0
- package/dist/labs/ts-analyzer.js.map +1 -0
- package/dist/labs/viewer.d.ts +12 -0
- package/dist/labs/viewer.js +1284 -0
- package/dist/labs/viewer.js.map +1 -0
- package/dist/main.d.ts +15 -0
- package/dist/main.js +247 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp/server.d.ts +16 -0
- package/dist/mcp/server.js +192775 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session.d.ts +117 -0
- package/dist/mcp/session.js +450 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/mcp/state.d.ts +42 -0
- package/dist/mcp/state.js +537 -0
- package/dist/mcp/state.js.map +1 -0
- package/dist/mcp/tools/contextos.d.ts +17 -0
- package/dist/mcp/tools/contextos.js +583 -0
- package/dist/mcp/tools/contextos.js.map +1 -0
- package/dist/mcp/tools.d.ts +15 -0
- package/dist/mcp/tools.js +393 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/orchestration/reviewer-gate.d.ts +43 -0
- package/dist/orchestration/reviewer-gate.js +280 -0
- package/dist/orchestration/reviewer-gate.js.map +1 -0
- package/dist/orchestration/reviewer-prompt.d.ts +18 -0
- package/dist/orchestration/reviewer-prompt.js +67 -0
- package/dist/orchestration/reviewer-prompt.js.map +1 -0
- package/dist/orchestration/verification-runner.d.ts +53 -0
- package/dist/orchestration/verification-runner.js +352 -0
- package/dist/orchestration/verification-runner.js.map +1 -0
- package/dist/plugins/adapter.d.ts +11 -0
- package/dist/plugins/adapter.js +11 -0
- package/dist/plugins/adapter.js.map +1 -0
- package/dist/plugins/core/archive.d.ts +9 -0
- package/dist/plugins/core/archive.js +128 -0
- package/dist/plugins/core/archive.js.map +1 -0
- package/dist/plugins/core/digest.d.ts +11 -0
- package/dist/plugins/core/digest.js +70 -0
- package/dist/plugins/core/digest.js.map +1 -0
- package/dist/plugins/core/grants.d.ts +22 -0
- package/dist/plugins/core/grants.js +90 -0
- package/dist/plugins/core/grants.js.map +1 -0
- package/dist/plugins/core/index.d.ts +10 -0
- package/dist/plugins/core/index.js +11 -0
- package/dist/plugins/core/index.js.map +1 -0
- package/dist/plugins/core/pinning.d.ts +15 -0
- package/dist/plugins/core/pinning.js +86 -0
- package/dist/plugins/core/pinning.js.map +1 -0
- package/dist/plugins/core/types.d.ts +105 -0
- package/dist/plugins/core/types.js +22 -0
- package/dist/plugins/core/types.js.map +1 -0
- package/dist/plugins/core/updater.d.ts +16 -0
- package/dist/plugins/core/updater.js +64 -0
- package/dist/plugins/core/updater.js.map +1 -0
- package/dist/plugins/loader.d.ts +65 -0
- package/dist/plugins/loader.js +110 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/prompts/orchestrator.d.ts +6 -0
- package/dist/prompts/orchestrator.js +114 -0
- package/dist/prompts/orchestrator.js.map +1 -0
- package/dist/routing/model-resolver.d.ts +27 -0
- package/dist/routing/model-resolver.js +265 -0
- package/dist/routing/model-resolver.js.map +1 -0
- package/dist/routing/model-router.d.ts +130 -0
- package/dist/routing/model-router.js +515 -0
- package/dist/routing/model-router.js.map +1 -0
- package/dist/runtime/attestations.cjs +260 -0
- package/dist/runtime/reviewer-pipeline.cjs +319 -0
- package/dist/runtime/sandbox.cjs +468 -0
- package/dist/runtime/state-machine.cjs +885 -0
- package/dist/runtime/thread-store.cjs +175 -0
- package/dist/runtime/transactional-git.cjs +315 -0
- package/dist/runtime/verification-pipeline.cjs +435 -0
- package/dist/sandbox/execution.d.ts +165 -0
- package/dist/sandbox/execution.js +497 -0
- package/dist/sandbox/execution.js.map +1 -0
- package/dist/security/file-policy.d.ts +22 -0
- package/dist/security/file-policy.js +53 -0
- package/dist/security/file-policy.js.map +1 -0
- package/dist/security/repository-boundary.d.ts +21 -0
- package/dist/security/repository-boundary.js +119 -0
- package/dist/security/repository-boundary.js.map +1 -0
- package/dist/security/secret-filter.d.ts +36 -0
- package/dist/security/secret-filter.js +149 -0
- package/dist/security/secret-filter.js.map +1 -0
- package/dist/swarm.d.ts +14 -0
- package/dist/swarm.js +624 -0
- package/dist/swarm.js.map +1 -0
- package/dist/threads/cache.d.ts +64 -0
- package/dist/threads/cache.js +241 -0
- package/dist/threads/cache.js.map +1 -0
- package/dist/threads/manager.d.ts +94 -0
- package/dist/threads/manager.js +914 -0
- package/dist/threads/manager.js.map +1 -0
- package/dist/ui/banner.d.ts +14 -0
- package/dist/ui/banner.js +42 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/dashboard.d.ts +33 -0
- package/dist/ui/dashboard.js +135 -0
- package/dist/ui/dashboard.js.map +1 -0
- package/dist/ui/index.d.ts +11 -0
- package/dist/ui/index.js +12 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/log.d.ts +39 -0
- package/dist/ui/log.js +126 -0
- package/dist/ui/log.js.map +1 -0
- package/dist/ui/onboarding.d.ts +14 -0
- package/dist/ui/onboarding.js +755 -0
- package/dist/ui/onboarding.js.map +1 -0
- package/dist/ui/run-log.d.ts +50 -0
- package/dist/ui/run-log.js +60 -0
- package/dist/ui/run-log.js.map +1 -0
- package/dist/ui/spinner.d.ts +41 -0
- package/dist/ui/spinner.js +172 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/streaming-feed.d.ts +72 -0
- package/dist/ui/streaming-feed.js +386 -0
- package/dist/ui/streaming-feed.js.map +1 -0
- package/dist/ui/summary.d.ts +18 -0
- package/dist/ui/summary.js +113 -0
- package/dist/ui/summary.js.map +1 -0
- package/dist/ui/text-input.d.ts +19 -0
- package/dist/ui/text-input.js +266 -0
- package/dist/ui/text-input.js.map +1 -0
- package/dist/ui/theme.d.ts +63 -0
- package/dist/ui/theme.js +97 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/utils/command-exists.d.ts +11 -0
- package/dist/utils/command-exists.js +41 -0
- package/dist/utils/command-exists.js.map +1 -0
- package/dist/utils/process-security.d.ts +19 -0
- package/dist/utils/process-security.js +90 -0
- package/dist/utils/process-security.js.map +1 -0
- package/dist/utils/rolling-buffer.d.ts +16 -0
- package/dist/utils/rolling-buffer.js +30 -0
- package/dist/utils/rolling-buffer.js.map +1 -0
- package/dist/utils/safe-spawn.d.ts +13 -0
- package/dist/utils/safe-spawn.js +49 -0
- package/dist/utils/safe-spawn.js.map +1 -0
- package/dist/worktree/manager.d.ts +69 -0
- package/dist/worktree/manager.js +593 -0
- package/dist/worktree/manager.js.map +1 -0
- package/dist/worktree/merge.d.ts +58 -0
- package/dist/worktree/merge.js +389 -0
- package/dist/worktree/merge.js.map +1 -0
- 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
|
+
}>;
|