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.
Files changed (149) hide show
  1. package/.windsurf/plans/persist-tasks-by-cwd.md +113 -0
  2. package/CHANGELOG.md +10 -0
  3. package/CLAUDE.md +67 -0
  4. package/README.md +124 -0
  5. package/build/config/timeouts.d.ts +12 -0
  6. package/build/config/timeouts.d.ts.map +1 -0
  7. package/build/config/timeouts.js +21 -0
  8. package/build/config/timeouts.js.map +1 -0
  9. package/build/index.d.ts +3 -0
  10. package/build/index.d.ts.map +1 -0
  11. package/build/index.js +116 -0
  12. package/build/index.js.map +1 -0
  13. package/build/models.d.ts +11 -0
  14. package/build/models.d.ts.map +1 -0
  15. package/build/models.js +22 -0
  16. package/build/models.js.map +1 -0
  17. package/build/services/client-context.d.ts +31 -0
  18. package/build/services/client-context.d.ts.map +1 -0
  19. package/build/services/client-context.js +44 -0
  20. package/build/services/client-context.js.map +1 -0
  21. package/build/services/copilot-switch.d.ts +36 -0
  22. package/build/services/copilot-switch.d.ts.map +1 -0
  23. package/build/services/copilot-switch.js +226 -0
  24. package/build/services/copilot-switch.js.map +1 -0
  25. package/build/services/process-spawner.d.ts +9 -0
  26. package/build/services/process-spawner.d.ts.map +1 -0
  27. package/build/services/process-spawner.js +475 -0
  28. package/build/services/process-spawner.js.map +1 -0
  29. package/build/services/retry-queue.d.ts +35 -0
  30. package/build/services/retry-queue.d.ts.map +1 -0
  31. package/build/services/retry-queue.js +125 -0
  32. package/build/services/retry-queue.js.map +1 -0
  33. package/build/services/task-manager.d.ts +124 -0
  34. package/build/services/task-manager.d.ts.map +1 -0
  35. package/build/services/task-manager.js +584 -0
  36. package/build/services/task-manager.js.map +1 -0
  37. package/build/services/task-persistence.d.ts +29 -0
  38. package/build/services/task-persistence.d.ts.map +1 -0
  39. package/build/services/task-persistence.js +158 -0
  40. package/build/services/task-persistence.js.map +1 -0
  41. package/build/templates/index.d.ts +11 -0
  42. package/build/templates/index.d.ts.map +1 -0
  43. package/build/templates/index.js +30 -0
  44. package/build/templates/index.js.map +1 -0
  45. package/build/tools/batch-spawn.d.ts +69 -0
  46. package/build/tools/batch-spawn.d.ts.map +1 -0
  47. package/build/tools/batch-spawn.js +150 -0
  48. package/build/tools/batch-spawn.js.map +1 -0
  49. package/build/tools/cancel-task.d.ts +21 -0
  50. package/build/tools/cancel-task.d.ts.map +1 -0
  51. package/build/tools/cancel-task.js +44 -0
  52. package/build/tools/cancel-task.js.map +1 -0
  53. package/build/tools/clear-tasks.d.ts +21 -0
  54. package/build/tools/clear-tasks.d.ts.map +1 -0
  55. package/build/tools/clear-tasks.js +43 -0
  56. package/build/tools/clear-tasks.js.map +1 -0
  57. package/build/tools/force-start.d.ts +21 -0
  58. package/build/tools/force-start.d.ts.map +1 -0
  59. package/build/tools/force-start.js +38 -0
  60. package/build/tools/force-start.js.map +1 -0
  61. package/build/tools/get-status.d.ts +31 -0
  62. package/build/tools/get-status.d.ts.map +1 -0
  63. package/build/tools/get-status.js +384 -0
  64. package/build/tools/get-status.js.map +1 -0
  65. package/build/tools/list-tasks.d.ts +26 -0
  66. package/build/tools/list-tasks.d.ts.map +1 -0
  67. package/build/tools/list-tasks.js +74 -0
  68. package/build/tools/list-tasks.js.map +1 -0
  69. package/build/tools/recover-task.d.ts +29 -0
  70. package/build/tools/recover-task.d.ts.map +1 -0
  71. package/build/tools/recover-task.js +91 -0
  72. package/build/tools/recover-task.js.map +1 -0
  73. package/build/tools/resume-task.d.ts +29 -0
  74. package/build/tools/resume-task.d.ts.map +1 -0
  75. package/build/tools/resume-task.js +43 -0
  76. package/build/tools/resume-task.js.map +1 -0
  77. package/build/tools/retry-task.d.ts +21 -0
  78. package/build/tools/retry-task.d.ts.map +1 -0
  79. package/build/tools/retry-task.js +52 -0
  80. package/build/tools/retry-task.js.map +1 -0
  81. package/build/tools/simulate-rate-limit.d.ts +25 -0
  82. package/build/tools/simulate-rate-limit.d.ts.map +1 -0
  83. package/build/tools/simulate-rate-limit.js +69 -0
  84. package/build/tools/simulate-rate-limit.js.map +1 -0
  85. package/build/tools/spawn-task.d.ts +57 -0
  86. package/build/tools/spawn-task.d.ts.map +1 -0
  87. package/build/tools/spawn-task.js +113 -0
  88. package/build/tools/spawn-task.js.map +1 -0
  89. package/build/tools/stream-output.d.ts +29 -0
  90. package/build/tools/stream-output.d.ts.map +1 -0
  91. package/build/tools/stream-output.js +96 -0
  92. package/build/tools/stream-output.js.map +1 -0
  93. package/build/types.d.ts +75 -0
  94. package/build/types.d.ts.map +1 -0
  95. package/build/types.js +12 -0
  96. package/build/types.js.map +1 -0
  97. package/build/utils/format.d.ts +29 -0
  98. package/build/utils/format.d.ts.map +1 -0
  99. package/build/utils/format.js +81 -0
  100. package/build/utils/format.js.map +1 -0
  101. package/build/utils/sanitize.d.ts +63 -0
  102. package/build/utils/sanitize.d.ts.map +1 -0
  103. package/build/utils/sanitize.js +28 -0
  104. package/build/utils/sanitize.js.map +1 -0
  105. package/build/utils/task-id-generator.d.ts +10 -0
  106. package/build/utils/task-id-generator.d.ts.map +1 -0
  107. package/build/utils/task-id-generator.js +22 -0
  108. package/build/utils/task-id-generator.js.map +1 -0
  109. package/docs/timeout-durability.md +28 -0
  110. package/package.json +39 -0
  111. package/plans/timeout-durability/00-overview.md +38 -0
  112. package/plans/timeout-durability/01-analysis.md +37 -0
  113. package/plans/timeout-durability/decisions.md +22 -0
  114. package/plans/timeout-durability/resources.md +24 -0
  115. package/plans/timeout-durability/step-01-timeout-flow.md +27 -0
  116. package/plans/timeout-durability/step-02-root-cause-map.md +26 -0
  117. package/plans/timeout-durability/step-03-state-schema.md +26 -0
  118. package/plans/timeout-durability/step-04-messaging-recovery.md +27 -0
  119. package/src/config/timeouts.ts +22 -0
  120. package/src/index.ts +129 -0
  121. package/src/models.ts +23 -0
  122. package/src/services/client-context.ts +49 -0
  123. package/src/services/copilot-switch.ts +269 -0
  124. package/src/services/process-spawner.ts +548 -0
  125. package/src/services/retry-queue.ts +151 -0
  126. package/src/services/task-manager.ts +667 -0
  127. package/src/services/task-persistence.ts +175 -0
  128. package/src/templates/index.ts +35 -0
  129. package/src/templates/super-coder.mdx +519 -0
  130. package/src/templates/super-planner.mdx +558 -0
  131. package/src/templates/super-researcher.mdx +394 -0
  132. package/src/templates/super-tester.mdx +688 -0
  133. package/src/tools/batch-spawn.ts +179 -0
  134. package/src/tools/cancel-task.ts +58 -0
  135. package/src/tools/clear-tasks.ts +52 -0
  136. package/src/tools/force-start.ts +48 -0
  137. package/src/tools/get-status.ts +480 -0
  138. package/src/tools/list-tasks.ts +83 -0
  139. package/src/tools/recover-task.ts +112 -0
  140. package/src/tools/resume-task.ts +51 -0
  141. package/src/tools/retry-task.ts +72 -0
  142. package/src/tools/simulate-rate-limit.ts +84 -0
  143. package/src/tools/spawn-task.ts +135 -0
  144. package/src/tools/stream-output.ts +101 -0
  145. package/src/types.ts +86 -0
  146. package/src/utils/format.ts +83 -0
  147. package/src/utils/sanitize.ts +35 -0
  148. package/src/utils/task-id-generator.ts +25 -0
  149. 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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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"}
@@ -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"}