super-subagents 1.0.1
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/.windsurf/plans/persist-tasks-by-cwd.md +113 -0
- package/CHANGELOG.md +10 -0
- package/CLAUDE.md +67 -0
- package/README.md +124 -0
- package/build/config/timeouts.d.ts +12 -0
- package/build/config/timeouts.d.ts.map +1 -0
- package/build/config/timeouts.js +21 -0
- package/build/config/timeouts.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +116 -0
- package/build/index.js.map +1 -0
- package/build/models.d.ts +11 -0
- package/build/models.d.ts.map +1 -0
- package/build/models.js +22 -0
- package/build/models.js.map +1 -0
- package/build/services/client-context.d.ts +31 -0
- package/build/services/client-context.d.ts.map +1 -0
- package/build/services/client-context.js +44 -0
- package/build/services/client-context.js.map +1 -0
- package/build/services/copilot-switch.d.ts +36 -0
- package/build/services/copilot-switch.d.ts.map +1 -0
- package/build/services/copilot-switch.js +226 -0
- package/build/services/copilot-switch.js.map +1 -0
- package/build/services/process-spawner.d.ts +9 -0
- package/build/services/process-spawner.d.ts.map +1 -0
- package/build/services/process-spawner.js +475 -0
- package/build/services/process-spawner.js.map +1 -0
- package/build/services/retry-queue.d.ts +35 -0
- package/build/services/retry-queue.d.ts.map +1 -0
- package/build/services/retry-queue.js +125 -0
- package/build/services/retry-queue.js.map +1 -0
- package/build/services/task-manager.d.ts +124 -0
- package/build/services/task-manager.d.ts.map +1 -0
- package/build/services/task-manager.js +584 -0
- package/build/services/task-manager.js.map +1 -0
- package/build/services/task-persistence.d.ts +29 -0
- package/build/services/task-persistence.d.ts.map +1 -0
- package/build/services/task-persistence.js +158 -0
- package/build/services/task-persistence.js.map +1 -0
- package/build/templates/index.d.ts +11 -0
- package/build/templates/index.d.ts.map +1 -0
- package/build/templates/index.js +30 -0
- package/build/templates/index.js.map +1 -0
- package/build/tools/batch-spawn.d.ts +69 -0
- package/build/tools/batch-spawn.d.ts.map +1 -0
- package/build/tools/batch-spawn.js +150 -0
- package/build/tools/batch-spawn.js.map +1 -0
- package/build/tools/cancel-task.d.ts +21 -0
- package/build/tools/cancel-task.d.ts.map +1 -0
- package/build/tools/cancel-task.js +44 -0
- package/build/tools/cancel-task.js.map +1 -0
- package/build/tools/clear-tasks.d.ts +21 -0
- package/build/tools/clear-tasks.d.ts.map +1 -0
- package/build/tools/clear-tasks.js +43 -0
- package/build/tools/clear-tasks.js.map +1 -0
- package/build/tools/force-start.d.ts +21 -0
- package/build/tools/force-start.d.ts.map +1 -0
- package/build/tools/force-start.js +38 -0
- package/build/tools/force-start.js.map +1 -0
- package/build/tools/get-status.d.ts +31 -0
- package/build/tools/get-status.d.ts.map +1 -0
- package/build/tools/get-status.js +384 -0
- package/build/tools/get-status.js.map +1 -0
- package/build/tools/list-tasks.d.ts +26 -0
- package/build/tools/list-tasks.d.ts.map +1 -0
- package/build/tools/list-tasks.js +74 -0
- package/build/tools/list-tasks.js.map +1 -0
- package/build/tools/recover-task.d.ts +29 -0
- package/build/tools/recover-task.d.ts.map +1 -0
- package/build/tools/recover-task.js +91 -0
- package/build/tools/recover-task.js.map +1 -0
- package/build/tools/resume-task.d.ts +29 -0
- package/build/tools/resume-task.d.ts.map +1 -0
- package/build/tools/resume-task.js +43 -0
- package/build/tools/resume-task.js.map +1 -0
- package/build/tools/retry-task.d.ts +21 -0
- package/build/tools/retry-task.d.ts.map +1 -0
- package/build/tools/retry-task.js +52 -0
- package/build/tools/retry-task.js.map +1 -0
- package/build/tools/simulate-rate-limit.d.ts +25 -0
- package/build/tools/simulate-rate-limit.d.ts.map +1 -0
- package/build/tools/simulate-rate-limit.js +69 -0
- package/build/tools/simulate-rate-limit.js.map +1 -0
- package/build/tools/spawn-task.d.ts +57 -0
- package/build/tools/spawn-task.d.ts.map +1 -0
- package/build/tools/spawn-task.js +113 -0
- package/build/tools/spawn-task.js.map +1 -0
- package/build/tools/stream-output.d.ts +29 -0
- package/build/tools/stream-output.d.ts.map +1 -0
- package/build/tools/stream-output.js +96 -0
- package/build/tools/stream-output.js.map +1 -0
- package/build/types.d.ts +75 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +12 -0
- package/build/types.js.map +1 -0
- package/build/utils/format.d.ts +29 -0
- package/build/utils/format.d.ts.map +1 -0
- package/build/utils/format.js +81 -0
- package/build/utils/format.js.map +1 -0
- package/build/utils/sanitize.d.ts +63 -0
- package/build/utils/sanitize.d.ts.map +1 -0
- package/build/utils/sanitize.js +28 -0
- package/build/utils/sanitize.js.map +1 -0
- package/build/utils/task-id-generator.d.ts +10 -0
- package/build/utils/task-id-generator.d.ts.map +1 -0
- package/build/utils/task-id-generator.js +22 -0
- package/build/utils/task-id-generator.js.map +1 -0
- package/docs/timeout-durability.md +28 -0
- package/package.json +39 -0
- package/plans/timeout-durability/00-overview.md +38 -0
- package/plans/timeout-durability/01-analysis.md +37 -0
- package/plans/timeout-durability/decisions.md +22 -0
- package/plans/timeout-durability/resources.md +24 -0
- package/plans/timeout-durability/step-01-timeout-flow.md +27 -0
- package/plans/timeout-durability/step-02-root-cause-map.md +26 -0
- package/plans/timeout-durability/step-03-state-schema.md +26 -0
- package/plans/timeout-durability/step-04-messaging-recovery.md +27 -0
- package/src/config/timeouts.ts +22 -0
- package/src/index.ts +129 -0
- package/src/models.ts +23 -0
- package/src/services/client-context.ts +49 -0
- package/src/services/copilot-switch.ts +269 -0
- package/src/services/process-spawner.ts +548 -0
- package/src/services/retry-queue.ts +151 -0
- package/src/services/task-manager.ts +667 -0
- package/src/services/task-persistence.ts +175 -0
- package/src/templates/index.ts +35 -0
- package/src/templates/super-coder.mdx +519 -0
- package/src/templates/super-planner.mdx +558 -0
- package/src/templates/super-researcher.mdx +394 -0
- package/src/templates/super-tester.mdx +688 -0
- package/src/tools/batch-spawn.ts +179 -0
- package/src/tools/cancel-task.ts +58 -0
- package/src/tools/clear-tasks.ts +52 -0
- package/src/tools/force-start.ts +48 -0
- package/src/tools/get-status.ts +480 -0
- package/src/tools/list-tasks.ts +83 -0
- package/src/tools/recover-task.ts +112 -0
- package/src/tools/resume-task.ts +51 -0
- package/src/tools/retry-task.ts +72 -0
- package/src/tools/simulate-rate-limit.ts +84 -0
- package/src/tools/spawn-task.ts +135 -0
- package/src/tools/stream-output.ts +101 -0
- package/src/types.ts +86 -0
- package/src/utils/format.ts +83 -0
- package/src/utils/sanitize.ts +35 -0
- package/src/utils/task-id-generator.ts +25 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Persist Tasks by CWD (MD5 Hashed)
|
|
2
|
+
|
|
3
|
+
Make task state persistent per-workspace using MD5 hash of cwd as filename, stored in a centralized `~/.super-agents/` directory.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
~/.super-agents/
|
|
9
|
+
├── {md5(cwd1)}.json ← tasks for /Users/alice/project-a
|
|
10
|
+
├── {md5(cwd2)}.json ← tasks for /Users/bob/project-b
|
|
11
|
+
└── ...
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Why MD5 hash?**
|
|
15
|
+
- Multiple users/processes can use same MCP server with different workspaces
|
|
16
|
+
- No filesystem path conflicts (slashes, special chars)
|
|
17
|
+
- Centralized storage — doesn't pollute workspace directories
|
|
18
|
+
- Deterministic: same cwd always maps to same file
|
|
19
|
+
|
|
20
|
+
## Implementation Steps
|
|
21
|
+
|
|
22
|
+
### 1. Create persistence service (`src/services/task-persistence.ts`)
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// Core functions
|
|
26
|
+
getStorageDir(): string // ~/.super-agents/
|
|
27
|
+
getStoragePath(cwd: string): string // ~/.super-agents/{md5(cwd)}.json
|
|
28
|
+
saveTasks(cwd: string, tasks: TaskState[]): void
|
|
29
|
+
loadTasks(cwd: string): TaskState[]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Key behaviors:**
|
|
33
|
+
- Use `crypto.createHash('md5').update(cwd).digest('hex')` for hash
|
|
34
|
+
- Create `~/.super-agents/` directory if missing (use `os.homedir()`)
|
|
35
|
+
- Exclude non-serializable `process` field via custom serializer
|
|
36
|
+
- Atomic writes: write to `.tmp` file, then rename
|
|
37
|
+
- Mark previously-running tasks as `failed` with `"Server restarted"` error on load
|
|
38
|
+
|
|
39
|
+
### 2. Update `TaskManager` (`src/services/task-manager.ts`)
|
|
40
|
+
|
|
41
|
+
**New methods:**
|
|
42
|
+
- `setCwd(cwd: string)` — set active workspace, load existing tasks
|
|
43
|
+
- `persist()` — save current state to disk (debounced)
|
|
44
|
+
|
|
45
|
+
**Modify existing methods to trigger persistence:**
|
|
46
|
+
- `createTask()` → persist after
|
|
47
|
+
- `updateTask()` → persist after
|
|
48
|
+
- `appendOutput()` → persist after (debounced more aggressively)
|
|
49
|
+
- `cancelTask()` → persist after
|
|
50
|
+
|
|
51
|
+
**Debounce strategy:**
|
|
52
|
+
- State changes: 100ms debounce
|
|
53
|
+
- Output appends: 1000ms debounce (high frequency)
|
|
54
|
+
|
|
55
|
+
### 3. Wire persistence in `index.ts`
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
server.oninitialized = async () => {
|
|
59
|
+
// ... existing root detection ...
|
|
60
|
+
const cwd = clientContext.getDefaultCwd();
|
|
61
|
+
taskManager.setCwd(cwd); // loads tasks from ~/.super-agents/{md5(cwd)}.json
|
|
62
|
+
};
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 4. Update README.md
|
|
66
|
+
|
|
67
|
+
Document:
|
|
68
|
+
- Persistence location: `~/.super-agents/`
|
|
69
|
+
- Per-workspace isolation via MD5 hash
|
|
70
|
+
- Crash recovery behavior
|
|
71
|
+
|
|
72
|
+
## Files to Create/Modify
|
|
73
|
+
|
|
74
|
+
| File | Action |
|
|
75
|
+
|------|--------|
|
|
76
|
+
| `src/services/task-persistence.ts` | **Create** — MD5 hashing, atomic JSON read/write |
|
|
77
|
+
| `src/services/task-manager.ts` | **Modify** — add `setCwd()`, `persist()`, debouncing |
|
|
78
|
+
| `src/index.ts` | **Modify** — call `taskManager.setCwd()` on init |
|
|
79
|
+
| `README.md` | **Modify** — document persistence |
|
|
80
|
+
|
|
81
|
+
## Edge Cases (All Covered)
|
|
82
|
+
|
|
83
|
+
| Scenario | Handling |
|
|
84
|
+
|----------|----------|
|
|
85
|
+
| **Orphaned running tasks** | Mark as `failed` with error `"Server restarted"` on load |
|
|
86
|
+
| **Corrupted JSON** | Log warning to stderr, start with empty task list |
|
|
87
|
+
| **Concurrent writes** | Atomic write (temp file + rename) prevents corruption |
|
|
88
|
+
| **Missing storage dir** | Create `~/.super-agents/` on first write |
|
|
89
|
+
| **Permission denied** | Log warning, continue in memory-only mode |
|
|
90
|
+
| **Disk full** | Catch write error, log warning, don't crash |
|
|
91
|
+
| **Very long output** | Already truncated by `MAX_OUTPUT_LINES` (2000) |
|
|
92
|
+
| **Multiple MCP instances** | Each instance uses same hash → shares state (feature) |
|
|
93
|
+
| **Task TTL cleanup** | Runs on loaded tasks too, cleans old completed tasks |
|
|
94
|
+
|
|
95
|
+
## Serialization
|
|
96
|
+
|
|
97
|
+
**Included fields:**
|
|
98
|
+
```typescript
|
|
99
|
+
{ id, status, prompt, output, pid, sessionId, startTime, endTime,
|
|
100
|
+
exitCode, error, cwd, model, autonomous, isResume }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Excluded fields:**
|
|
104
|
+
- `process` — live process handle, not serializable
|
|
105
|
+
|
|
106
|
+
## Success Criteria
|
|
107
|
+
|
|
108
|
+
- [x] Tasks survive server restart
|
|
109
|
+
- [x] Each workspace has independent task history (via MD5)
|
|
110
|
+
- [x] Multiple users/workspaces supported concurrently
|
|
111
|
+
- [x] No data loss on normal shutdown
|
|
112
|
+
- [x] Graceful degradation on disk errors
|
|
113
|
+
- [x] Atomic writes prevent corruption
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
- Add centralized timeout configuration with env overrides.
|
|
7
|
+
- Record task activity timestamps, timeout reasons, and context for diagnostics.
|
|
8
|
+
- Improve get_status and stream_output guidance for stalls/timeouts.
|
|
9
|
+
- Add recover_task tool for timed_out recovery paths.
|
|
10
|
+
- Document timeout durability workflow and new env settings.
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Build & Development Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install # Install dependencies
|
|
9
|
+
npm run build # Compile TypeScript to build/
|
|
10
|
+
npm run dev # Watch mode with tsx (auto-reload)
|
|
11
|
+
npm start # Run compiled server
|
|
12
|
+
npm run clean # Remove build directory
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Architecture Overview
|
|
16
|
+
|
|
17
|
+
This is an MCP (Model Context Protocol) server that spawns GitHub Copilot CLI agents as background tasks. It wraps the Copilot CLI (`/opt/homebrew/bin/copilot` by default) with task management, dependency chains, and automatic rate-limit retry.
|
|
18
|
+
|
|
19
|
+
### Core Components
|
|
20
|
+
|
|
21
|
+
**Entry Point** (`src/index.ts`): Sets up MCP server, registers all tools, and wires up task manager callbacks for retry and dependency execution.
|
|
22
|
+
|
|
23
|
+
**Task Manager** (`src/services/task-manager.ts`): Central state machine managing all tasks. Handles:
|
|
24
|
+
- Task lifecycle (pending → waiting → running → completed/failed/cancelled/rate_limited/timed_out)
|
|
25
|
+
- Dependency resolution via `areDependenciesSatisfied()` and `processWaitingTasks()`
|
|
26
|
+
- Persistence scheduling with debouncing
|
|
27
|
+
- Auto-cleanup of expired tasks (1 hour TTL)
|
|
28
|
+
|
|
29
|
+
**Process Spawner** (`src/services/process-spawner.ts`): Executes Copilot CLI via `execa`. Builds command args, captures stdout/stderr, detects rate limits, and handles timeouts.
|
|
30
|
+
|
|
31
|
+
**Persistence** (`src/services/task-persistence.ts`): Tasks persist to `~/.super-agents/{md5(cwd)}.json`. Uses atomic writes (write temp → rename).
|
|
32
|
+
|
|
33
|
+
**Retry Queue** (`src/services/retry-queue.ts`): Detects rate-limit errors via regex patterns, calculates exponential backoff (5m → 10m → 20m → 40m → 1h → 2h), and extracts wait times from error messages.
|
|
34
|
+
|
|
35
|
+
### Tool Handlers
|
|
36
|
+
|
|
37
|
+
Each tool in `src/tools/` exports:
|
|
38
|
+
- A tool definition object (`{name, description, inputSchema}`)
|
|
39
|
+
- A handler function that validates input via Zod schemas from `src/utils/sanitize.ts`
|
|
40
|
+
|
|
41
|
+
### Templates
|
|
42
|
+
|
|
43
|
+
Task templates in `src/templates/*.mdx` wrap user prompts with specialized instructions. The `applyTemplate()` function replaces `{{user_prompt}}` placeholder or appends if not found.
|
|
44
|
+
|
|
45
|
+
### Key Types
|
|
46
|
+
|
|
47
|
+
- `TaskStatus` enum: `pending`, `waiting`, `running`, `completed`, `failed`, `cancelled`, `rate_limited`, `timed_out`
|
|
48
|
+
- `TaskState`: Full task object with output buffer, retry info, dependencies, labels
|
|
49
|
+
- `SpawnOptions`: Input for creating tasks
|
|
50
|
+
|
|
51
|
+
### Task IDs
|
|
52
|
+
|
|
53
|
+
Human-readable IDs like `brave-tiger-42` generated via `unique-names-generator`. Normalized to lowercase for lookups.
|
|
54
|
+
|
|
55
|
+
## Environment Variables
|
|
56
|
+
|
|
57
|
+
| Variable | Default | Purpose |
|
|
58
|
+
|----------|---------|---------|
|
|
59
|
+
| `COPILOT_PATH` | `/opt/homebrew/bin/copilot` | Path to Copilot CLI executable |
|
|
60
|
+
| `ENABLE_OPUS` | `false` | Allow opus model (cost control) |
|
|
61
|
+
| `ENABLE_STREAMING` | `false` | Enable experimental `stream_output` tool |
|
|
62
|
+
|
|
63
|
+
## Adding New Tools
|
|
64
|
+
|
|
65
|
+
1. Create `src/tools/new-tool.ts` with tool definition and handler
|
|
66
|
+
2. Import and add to `tools` array in `src/index.ts`
|
|
67
|
+
3. Add case to switch statement in `CallToolRequestSchema` handler
|
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Super Agents MCP Server
|
|
2
|
+
|
|
3
|
+
MCP server that spawns GitHub Copilot CLI agents as background tasks with human-readable IDs, dependency chains, and automatic rate-limit retry.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install && npm run build
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"mcpServers": {
|
|
14
|
+
"super-agents": {
|
|
15
|
+
"command": "node",
|
|
16
|
+
"args": ["/path/to/copilot-agents/build/index.js"]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Tools
|
|
23
|
+
|
|
24
|
+
| Tool | Description |
|
|
25
|
+
|------|-------------|
|
|
26
|
+
| `spawn_task` | Create a task. Returns `task_id` for tracking. |
|
|
27
|
+
| `batch_spawn` | Create multiple tasks with dependency chains (max 20). |
|
|
28
|
+
| `get_status` | Check task status. Supports batch checking with array. |
|
|
29
|
+
| `list_tasks` | List all tasks. Filter by `status` or `label`. |
|
|
30
|
+
| `resume_task` | Resume interrupted session by `session_id`. |
|
|
31
|
+
| `retry_task` | Immediately retry a rate-limited task. |
|
|
32
|
+
| `cancel_task` | Kill a running/pending task (SIGTERM). |
|
|
33
|
+
| `recover_task` | Recover a timed_out task (resume if session is available). |
|
|
34
|
+
| `force_start` | Start a waiting task, bypassing dependencies. |
|
|
35
|
+
| `clear_tasks` | Delete all tasks for workspace. Requires `confirm: true`. |
|
|
36
|
+
| `stream_output` | *(experimental)* Get incremental output with offset. Requires `ENABLE_STREAMING=true`. |
|
|
37
|
+
|
|
38
|
+
## Task Statuses
|
|
39
|
+
|
|
40
|
+
`pending` → `waiting` → `running` → `completed` | `failed` | `cancelled` | `rate_limited` | `timed_out`
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
|
|
44
|
+
### Dependencies
|
|
45
|
+
```json
|
|
46
|
+
{ "prompt": "Deploy", "depends_on": ["build-task-id", "test-task-id"] }
|
|
47
|
+
```
|
|
48
|
+
Task waits until all dependencies complete. Use `force_start` to bypass.
|
|
49
|
+
|
|
50
|
+
### Labels
|
|
51
|
+
```json
|
|
52
|
+
{ "prompt": "Build API", "labels": ["backend", "urgent"] }
|
|
53
|
+
```
|
|
54
|
+
Filter with `list_tasks({ "label": "backend" })`.
|
|
55
|
+
|
|
56
|
+
### Batch Spawn
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"tasks": [
|
|
60
|
+
{ "id": "build", "prompt": "Build project" },
|
|
61
|
+
{ "id": "test", "prompt": "Run tests", "depends_on": ["build"] },
|
|
62
|
+
{ "id": "deploy", "prompt": "Deploy", "depends_on": ["test"] }
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
Local `id` fields map to real `task_id` in response.
|
|
67
|
+
|
|
68
|
+
### Task Templates
|
|
69
|
+
|
|
70
|
+
| Template | Use Case |
|
|
71
|
+
|----------|----------|
|
|
72
|
+
| `super-coder` | Implementation, bug fixes, refactoring |
|
|
73
|
+
| `super-planner` | Architecture, design decisions |
|
|
74
|
+
| `super-researcher` | Codebase exploration, investigation |
|
|
75
|
+
| `super-tester` | Writing tests, QA verification |
|
|
76
|
+
|
|
77
|
+
### Models
|
|
78
|
+
`claude-sonnet-4.5` (default), `claude-haiku-4.5`. Opus blocked by default (set `ENABLE_OPUS=true` to allow).
|
|
79
|
+
|
|
80
|
+
### Timeout
|
|
81
|
+
Default: 10 min (600000ms). Max: 1 hour. Tasks exceeding timeout get `timed_out` status.
|
|
82
|
+
Configurable via `MCP_TASK_TIMEOUT_MS`, `MCP_TASK_TIMEOUT_MIN_MS`, and `MCP_TASK_TIMEOUT_MAX_MS`.
|
|
83
|
+
Stall warnings are based on `MCP_TASK_STALL_WARN_MS`. Timed out tasks may include a reason and can be recovered via `recover_task` or `resume_task` when a session is available.
|
|
84
|
+
|
|
85
|
+
### Rate Limit Auto-Retry
|
|
86
|
+
Rate-limited tasks auto-retry with exponential backoff (5m → 10m → 20m → 40m → 1h → 2h). Max 6 retries.
|
|
87
|
+
|
|
88
|
+
### Persistence
|
|
89
|
+
Tasks persist to `~/.super-agents/{md5(cwd)}.json`. Survives server restarts.
|
|
90
|
+
|
|
91
|
+
### Output Streaming (Experimental)
|
|
92
|
+
Requires `ENABLE_STREAMING=true`. Disabled by default.
|
|
93
|
+
```json
|
|
94
|
+
// First call
|
|
95
|
+
{ "task_id": "brave-tiger-42", "offset": 0 }
|
|
96
|
+
// Response: { "lines": [...], "next_offset": 50, "has_more": true }
|
|
97
|
+
|
|
98
|
+
// Subsequent calls
|
|
99
|
+
{ "task_id": "brave-tiger-42", "offset": 50 }
|
|
100
|
+
```
|
|
101
|
+
Use `next_offset` from response to get new lines without re-fetching.
|
|
102
|
+
|
|
103
|
+
### Polling Backoff
|
|
104
|
+
Response includes `retry_after_seconds` (30s → 60s → 120s → 180s) to prevent excessive polling.
|
|
105
|
+
|
|
106
|
+
## Environment
|
|
107
|
+
|
|
108
|
+
| Variable | Default | Description |
|
|
109
|
+
|----------|---------|-------------|
|
|
110
|
+
| `COPILOT_PATH` | `/opt/homebrew/bin/copilot` | Copilot CLI path |
|
|
111
|
+
| `ENABLE_OPUS` | `false` | Allow opus model (cost control) |
|
|
112
|
+
| `ENABLE_STREAMING` | `false` | Enable experimental `stream_output` tool |
|
|
113
|
+
| `MCP_TASK_TIMEOUT_MS` | `600000` | Default task timeout (ms) |
|
|
114
|
+
| `MCP_TASK_TIMEOUT_MIN_MS` | `1000` | Minimum allowed task timeout (ms) |
|
|
115
|
+
| `MCP_TASK_TIMEOUT_MAX_MS` | `3600000` | Maximum allowed task timeout (ms) |
|
|
116
|
+
| `MCP_TASK_STALL_WARN_MS` | `300000` | No-output stall warning threshold (ms) |
|
|
117
|
+
| `MCP_COPILOT_SWITCH_TIMEOUT_MS` | `120000` | Timeout for copilot-switch command (ms) |
|
|
118
|
+
| `MCP_COPILOT_SWITCH_LOCK_STALE_MS` | `150000` | Stale lock threshold for copilot-switch (ms) |
|
|
119
|
+
| `MCP_COPILOT_SWITCH_LOCK_TIMEOUT_MS` | `150000` | Wait timeout for copilot-switch lock (ms) |
|
|
120
|
+
| `MCP_COPILOT_SWITCH_LOCK_POLL_MS` | `500` | Lock poll interval for copilot-switch (ms) |
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized timeout configuration with optional environment overrides.
|
|
3
|
+
*/
|
|
4
|
+
export declare const TASK_TIMEOUT_MIN_MS: number;
|
|
5
|
+
export declare const TASK_TIMEOUT_MAX_MS: number;
|
|
6
|
+
export declare const TASK_TIMEOUT_DEFAULT_MS: number;
|
|
7
|
+
export declare const TASK_STALL_WARN_MS: number;
|
|
8
|
+
export declare const COPILOT_SWITCH_COMMAND_TIMEOUT_MS: number;
|
|
9
|
+
export declare const COPILOT_SWITCH_LOCK_STALE_MS: number;
|
|
10
|
+
export declare const COPILOT_SWITCH_LOCK_TIMEOUT_MS: number;
|
|
11
|
+
export declare const COPILOT_SWITCH_LOCK_POLL_MS: number;
|
|
12
|
+
//# sourceMappingURL=timeouts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeouts.d.ts","sourceRoot":"","sources":["../../src/config/timeouts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,eAAO,MAAM,mBAAmB,QAA+C,CAAC;AAChF,eAAO,MAAM,mBAAmB,QAAmD,CAAC;AACpF,eAAO,MAAM,uBAAuB,QAA6C,CAAC;AAClF,eAAO,MAAM,kBAAkB,QAAmD,CAAC;AAGnF,eAAO,MAAM,iCAAiC,QAAuD,CAAC;AACtG,eAAO,MAAM,4BAA4B,QAA0D,CAAC;AACpG,eAAO,MAAM,8BAA8B,QAA4D,CAAC;AACxG,eAAO,MAAM,2BAA2B,QAAqD,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized timeout configuration with optional environment overrides.
|
|
3
|
+
*/
|
|
4
|
+
function readIntEnv(name, fallback) {
|
|
5
|
+
const raw = process.env[name];
|
|
6
|
+
if (!raw)
|
|
7
|
+
return fallback;
|
|
8
|
+
const value = Number(raw);
|
|
9
|
+
return Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
|
|
10
|
+
}
|
|
11
|
+
// Task execution timeout bounds
|
|
12
|
+
export const TASK_TIMEOUT_MIN_MS = readIntEnv('MCP_TASK_TIMEOUT_MIN_MS', 1_000);
|
|
13
|
+
export const TASK_TIMEOUT_MAX_MS = readIntEnv('MCP_TASK_TIMEOUT_MAX_MS', 3_600_000);
|
|
14
|
+
export const TASK_TIMEOUT_DEFAULT_MS = readIntEnv('MCP_TASK_TIMEOUT_MS', 600_000);
|
|
15
|
+
export const TASK_STALL_WARN_MS = readIntEnv('MCP_TASK_STALL_WARN_MS', 5 * 60_000);
|
|
16
|
+
// Copilot switch timings
|
|
17
|
+
export const COPILOT_SWITCH_COMMAND_TIMEOUT_MS = readIntEnv('MCP_COPILOT_SWITCH_TIMEOUT_MS', 120_000);
|
|
18
|
+
export const COPILOT_SWITCH_LOCK_STALE_MS = readIntEnv('MCP_COPILOT_SWITCH_LOCK_STALE_MS', 150_000);
|
|
19
|
+
export const COPILOT_SWITCH_LOCK_TIMEOUT_MS = readIntEnv('MCP_COPILOT_SWITCH_LOCK_TIMEOUT_MS', 150_000);
|
|
20
|
+
export const COPILOT_SWITCH_LOCK_POLL_MS = readIntEnv('MCP_COPILOT_SWITCH_LOCK_POLL_MS', 500);
|
|
21
|
+
//# sourceMappingURL=timeouts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeouts.js","sourceRoot":"","sources":["../../src/config/timeouts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS,UAAU,CAAC,IAAY,EAAE,QAAgB;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC5E,CAAC;AAED,gCAAgC;AAChC,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;AAChF,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC;AACpF,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;AAClF,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC,wBAAwB,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC;AAEnF,yBAAyB;AACzB,MAAM,CAAC,MAAM,iCAAiC,GAAG,UAAU,CAAC,+BAA+B,EAAE,OAAO,CAAC,CAAC;AACtG,MAAM,CAAC,MAAM,4BAA4B,GAAG,UAAU,CAAC,kCAAkC,EAAE,OAAO,CAAC,CAAC;AACpG,MAAM,CAAC,MAAM,8BAA8B,GAAG,UAAU,CAAC,oCAAoC,EAAE,OAAO,CAAC,CAAC;AACxG,MAAM,CAAC,MAAM,2BAA2B,GAAG,UAAU,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { spawnTaskTool, handleSpawnTask } from './tools/spawn-task.js';
|
|
6
|
+
import { getTaskStatusTool, handleGetTaskStatus } from './tools/get-status.js';
|
|
7
|
+
import { listTasksTool, handleListTasks } from './tools/list-tasks.js';
|
|
8
|
+
import { resumeTaskTool, handleResumeTask } from './tools/resume-task.js';
|
|
9
|
+
import { clearTasksTool, handleClearTasks } from './tools/clear-tasks.js';
|
|
10
|
+
import { retryTaskTool, handleRetryTask } from './tools/retry-task.js';
|
|
11
|
+
import { cancelTaskTool, handleCancelTask } from './tools/cancel-task.js';
|
|
12
|
+
import { recoverTaskTool, handleRecoverTask } from './tools/recover-task.js';
|
|
13
|
+
import { forceStartTool, handleForceStart } from './tools/force-start.js';
|
|
14
|
+
import { batchSpawnTool, handleBatchSpawn } from './tools/batch-spawn.js';
|
|
15
|
+
import { streamOutputTool, handleStreamOutput } from './tools/stream-output.js';
|
|
16
|
+
import { simulateRateLimitTool, handleSimulateRateLimit } from './tools/simulate-rate-limit.js';
|
|
17
|
+
import { taskManager } from './services/task-manager.js';
|
|
18
|
+
import { clientContext } from './services/client-context.js';
|
|
19
|
+
import { checkCopilotInstalled, checkClaudeCliInstalled } from './services/process-spawner.js';
|
|
20
|
+
import { isSwitchAvailable } from './services/copilot-switch.js';
|
|
21
|
+
import { mcpText } from './utils/format.js';
|
|
22
|
+
// Feature flags (off by default for cost control)
|
|
23
|
+
const ENABLE_STREAMING = process.env.ENABLE_STREAMING === 'true';
|
|
24
|
+
const server = new Server({ name: 'copilot-agent', version: '1.0.0' }, { capabilities: { tools: {} } });
|
|
25
|
+
// Register retry callback for rate-limited tasks
|
|
26
|
+
taskManager.onRetry(async (task) => {
|
|
27
|
+
const { spawnCopilotProcess } = await import('./services/process-spawner.js');
|
|
28
|
+
console.error(`[index] Retrying task ${task.id}: "${task.prompt.slice(0, 50)}..."`);
|
|
29
|
+
try {
|
|
30
|
+
// Spawn a new process with the same parameters, carrying forward retry info
|
|
31
|
+
const newTaskId = await spawnCopilotProcess({
|
|
32
|
+
prompt: task.prompt,
|
|
33
|
+
cwd: task.cwd,
|
|
34
|
+
model: task.model,
|
|
35
|
+
autonomous: task.autonomous ?? true,
|
|
36
|
+
retryInfo: task.retryInfo,
|
|
37
|
+
fallbackAttempted: task.fallbackAttempted,
|
|
38
|
+
});
|
|
39
|
+
return newTaskId;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
console.error(`[index] Failed to retry task ${task.id}:`, err);
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
// Register execute callback for waiting tasks (dependencies satisfied)
|
|
47
|
+
taskManager.onExecute(async (task) => {
|
|
48
|
+
const { executeWaitingTask } = await import('./services/process-spawner.js');
|
|
49
|
+
console.error(`[index] Executing waiting task ${task.id}: "${task.prompt.slice(0, 50)}..."`);
|
|
50
|
+
await executeWaitingTask(task);
|
|
51
|
+
});
|
|
52
|
+
server.oninitialized = async () => {
|
|
53
|
+
try {
|
|
54
|
+
const result = await server.listRoots();
|
|
55
|
+
if (result?.roots?.length) {
|
|
56
|
+
clientContext.setRoots(result.roots);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Client may not support roots - use server cwd as fallback
|
|
61
|
+
}
|
|
62
|
+
// Load persisted tasks for this workspace (also triggers auto-retry for rate-limited tasks)
|
|
63
|
+
const cwd = clientContext.getDefaultCwd();
|
|
64
|
+
taskManager.setCwd(cwd);
|
|
65
|
+
};
|
|
66
|
+
const tools = [
|
|
67
|
+
spawnTaskTool, getTaskStatusTool, listTasksTool, resumeTaskTool,
|
|
68
|
+
clearTasksTool, retryTaskTool, cancelTaskTool, recoverTaskTool, forceStartTool, batchSpawnTool,
|
|
69
|
+
...(ENABLE_STREAMING ? [streamOutputTool] : []),
|
|
70
|
+
simulateRateLimitTool,
|
|
71
|
+
];
|
|
72
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
73
|
+
tools: tools.map(t => ({ name: t.name, description: t.description, inputSchema: t.inputSchema })),
|
|
74
|
+
}));
|
|
75
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
76
|
+
const { name, arguments: args } = request.params;
|
|
77
|
+
switch (name) {
|
|
78
|
+
case 'spawn_task': return handleSpawnTask(args);
|
|
79
|
+
case 'get_status': return handleGetTaskStatus(args);
|
|
80
|
+
case 'list_tasks': return handleListTasks(args);
|
|
81
|
+
case 'resume_task': return handleResumeTask(args);
|
|
82
|
+
case 'clear_tasks': return handleClearTasks(request.params.arguments);
|
|
83
|
+
case 'retry_task': return handleRetryTask(request.params.arguments);
|
|
84
|
+
case 'cancel_task': return handleCancelTask(request.params.arguments);
|
|
85
|
+
case 'recover_task': return handleRecoverTask(args);
|
|
86
|
+
case 'force_start': return handleForceStart(request.params.arguments);
|
|
87
|
+
case 'batch_spawn': return handleBatchSpawn(request.params.arguments);
|
|
88
|
+
case 'stream_output': return ENABLE_STREAMING
|
|
89
|
+
? handleStreamOutput(request.params.arguments)
|
|
90
|
+
: mcpText('**Error:** `stream_output` is disabled (experimental). Set `ENABLE_STREAMING=true` to enable.');
|
|
91
|
+
case 'simulate_rate_limit': return handleSimulateRateLimit(request.params.arguments);
|
|
92
|
+
default: return mcpText(`**Error:** Unknown tool \`${name}\``);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
async function main() {
|
|
96
|
+
if (!checkCopilotInstalled())
|
|
97
|
+
console.error('Warning: Copilot CLI not found');
|
|
98
|
+
if (isSwitchAvailable()) {
|
|
99
|
+
console.error('Info: Copilot account switching available');
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.error('Info: Copilot account switching not available (no ~/bin/copilot-switch)');
|
|
103
|
+
}
|
|
104
|
+
if (!checkClaudeCliInstalled()) {
|
|
105
|
+
console.error('Warning: Claude CLI not found - fallback on rate limit will not be available');
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
console.error('Info: Claude CLI available for rate limit fallback');
|
|
109
|
+
}
|
|
110
|
+
const transport = new StdioServerTransport();
|
|
111
|
+
await server.connect(transport);
|
|
112
|
+
process.on('SIGINT', () => { taskManager.shutdown(); process.exit(0); });
|
|
113
|
+
process.on('SIGTERM', () => { taskManager.shutdown(); process.exit(0); });
|
|
114
|
+
}
|
|
115
|
+
main().catch(e => { console.error('Fatal:', e); process.exit(1); });
|
|
116
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const MODELS: {
|
|
2
|
+
readonly 'claude-sonnet-4.5': "Latest Sonnet - best balance of speed and capability (default)";
|
|
3
|
+
readonly 'claude-opus-4.5': "Most capable - complex reasoning, large codebases";
|
|
4
|
+
readonly 'claude-haiku-4.5': "Fastest - simple tasks, quick iterations";
|
|
5
|
+
};
|
|
6
|
+
export type ModelId = keyof typeof MODELS;
|
|
7
|
+
export declare const DEFAULT_MODEL: ModelId;
|
|
8
|
+
export declare const MODEL_IDS: ModelId[];
|
|
9
|
+
/** Validate and sanitize model selection */
|
|
10
|
+
export declare function resolveModel(requested?: string): ModelId;
|
|
11
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM;;;;CAIT,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,MAAM,CAAC;AAC1C,eAAO,MAAM,aAAa,EAAE,OAA6B,CAAC;AAK1D,eAAO,MAAM,SAAS,EAAE,OAAO,EAEc,CAAC;AAE9C,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAKxD"}
|
package/build/models.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const MODELS = {
|
|
2
|
+
'claude-sonnet-4.5': 'Latest Sonnet - best balance of speed and capability (default)',
|
|
3
|
+
'claude-opus-4.5': 'Most capable - complex reasoning, large codebases',
|
|
4
|
+
'claude-haiku-4.5': 'Fastest - simple tasks, quick iterations',
|
|
5
|
+
};
|
|
6
|
+
export const DEFAULT_MODEL = 'claude-sonnet-4.5';
|
|
7
|
+
// ENABLE_OPUS=false by default - opus blocked unless explicitly enabled
|
|
8
|
+
const ENABLE_OPUS = process.env.ENABLE_OPUS === 'true';
|
|
9
|
+
export const MODEL_IDS = ENABLE_OPUS
|
|
10
|
+
? ['claude-sonnet-4.5', 'claude-opus-4.5', 'claude-haiku-4.5']
|
|
11
|
+
: ['claude-sonnet-4.5', 'claude-haiku-4.5'];
|
|
12
|
+
/** Validate and sanitize model selection */
|
|
13
|
+
export function resolveModel(requested) {
|
|
14
|
+
if (!requested)
|
|
15
|
+
return DEFAULT_MODEL;
|
|
16
|
+
if (requested === 'claude-opus-4.5' && !ENABLE_OPUS)
|
|
17
|
+
return DEFAULT_MODEL;
|
|
18
|
+
if (MODEL_IDS.includes(requested))
|
|
19
|
+
return requested;
|
|
20
|
+
return DEFAULT_MODEL;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,mBAAmB,EAAE,gEAAgE;IACrF,iBAAiB,EAAE,mDAAmD;IACtE,kBAAkB,EAAE,0CAA0C;CACtD,CAAC;AAGX,MAAM,CAAC,MAAM,aAAa,GAAY,mBAAmB,CAAC;AAE1D,wEAAwE;AACxE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,MAAM,CAAC;AAEvD,MAAM,CAAC,MAAM,SAAS,GAAc,WAAW;IAC7C,CAAC,CAAC,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,kBAAkB,CAAC;IAC9D,CAAC,CAAC,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;AAE9C,4CAA4C;AAC5C,MAAM,UAAU,YAAY,CAAC,SAAkB;IAC7C,IAAI,CAAC,SAAS;QAAE,OAAO,aAAa,CAAC;IACrC,IAAI,SAAS,KAAK,iBAAiB,IAAI,CAAC,WAAW;QAAE,OAAO,aAAa,CAAC;IAC1E,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAoB,CAAC;QAAE,OAAO,SAAoB,CAAC;IAC1E,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stores client context including workspace roots from MCP initialization.
|
|
3
|
+
* The first root is used as default CWD for spawned processes.
|
|
4
|
+
*/
|
|
5
|
+
declare class ClientContext {
|
|
6
|
+
private _roots;
|
|
7
|
+
private _defaultCwd;
|
|
8
|
+
/**
|
|
9
|
+
* Set roots from client's roots/list response
|
|
10
|
+
*/
|
|
11
|
+
setRoots(roots: Array<{
|
|
12
|
+
uri: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
}>): void;
|
|
15
|
+
/**
|
|
16
|
+
* Get the default CWD for spawning processes.
|
|
17
|
+
* Returns first client root if available, otherwise server's cwd.
|
|
18
|
+
*/
|
|
19
|
+
getDefaultCwd(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Get all client roots
|
|
22
|
+
*/
|
|
23
|
+
getRoots(): string[];
|
|
24
|
+
/**
|
|
25
|
+
* Check if roots were provided by client
|
|
26
|
+
*/
|
|
27
|
+
hasRoots(): boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare const clientContext: ClientContext;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=client-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-context.d.ts","sourceRoot":"","sources":["../../src/services/client-context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAM,aAAa;IACjB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAyB;IAE5C;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAc5D;;;OAGG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,QAAQ,IAAI,MAAM,EAAE;IAIpB;;OAEG;IACH,QAAQ,IAAI,OAAO;CAGpB;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stores client context including workspace roots from MCP initialization.
|
|
3
|
+
* The first root is used as default CWD for spawned processes.
|
|
4
|
+
*/
|
|
5
|
+
class ClientContext {
|
|
6
|
+
_roots = [];
|
|
7
|
+
_defaultCwd = process.cwd();
|
|
8
|
+
/**
|
|
9
|
+
* Set roots from client's roots/list response
|
|
10
|
+
*/
|
|
11
|
+
setRoots(roots) {
|
|
12
|
+
this._roots = roots.map(r => {
|
|
13
|
+
// Convert file:// URI to filesystem path
|
|
14
|
+
if (r.uri.startsWith('file://')) {
|
|
15
|
+
return decodeURIComponent(r.uri.replace('file://', ''));
|
|
16
|
+
}
|
|
17
|
+
return r.uri;
|
|
18
|
+
});
|
|
19
|
+
if (this._roots.length > 0) {
|
|
20
|
+
this._defaultCwd = this._roots[0];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get the default CWD for spawning processes.
|
|
25
|
+
* Returns first client root if available, otherwise server's cwd.
|
|
26
|
+
*/
|
|
27
|
+
getDefaultCwd() {
|
|
28
|
+
return this._defaultCwd;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get all client roots
|
|
32
|
+
*/
|
|
33
|
+
getRoots() {
|
|
34
|
+
return [...this._roots];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if roots were provided by client
|
|
38
|
+
*/
|
|
39
|
+
hasRoots() {
|
|
40
|
+
return this._roots.length > 0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export const clientContext = new ClientContext();
|
|
44
|
+
//# sourceMappingURL=client-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-context.js","sourceRoot":"","sources":["../../src/services/client-context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,aAAa;IACT,MAAM,GAAa,EAAE,CAAC;IACtB,WAAW,GAAW,OAAO,CAAC,GAAG,EAAE,CAAC;IAE5C;;OAEG;IACH,QAAQ,CAAC,KAA4C;QACnD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAC1B,yCAAyC;YACzC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAChC,OAAO,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;YAC1D,CAAC;YACD,OAAO,CAAC,CAAC,GAAG,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAChC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC"}
|