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,91 @@
1
+ import { z } from 'zod';
2
+ import { taskManager } from '../services/task-manager.js';
3
+ import { spawnCopilotProcess } from '../services/process-spawner.js';
4
+ import { TaskStatus } from '../types.js';
5
+ import { mcpText, formatError, join } from '../utils/format.js';
6
+ import { TASK_TIMEOUT_MAX_MS, TASK_TIMEOUT_MIN_MS } from '../config/timeouts.js';
7
+ const RecoverTaskSchema = z.object({
8
+ task_id: z.string().min(1).describe('Timed out task ID to recover'),
9
+ timeout: z.number().int().min(TASK_TIMEOUT_MIN_MS).max(TASK_TIMEOUT_MAX_MS).optional(),
10
+ cwd: z.string().optional(),
11
+ });
12
+ export const recoverTaskTool = {
13
+ name: 'recover_task',
14
+ description: 'Recover a timed_out task. If session_id exists, resumes it; otherwise suggests spawning a new task.',
15
+ inputSchema: {
16
+ type: 'object',
17
+ properties: {
18
+ task_id: {
19
+ type: 'string',
20
+ description: 'Timed out task ID to recover.',
21
+ },
22
+ timeout: {
23
+ type: 'number',
24
+ description: 'Max execution time in ms for the resumed task (optional).',
25
+ },
26
+ cwd: {
27
+ type: 'string',
28
+ description: 'Working directory override (optional).',
29
+ },
30
+ },
31
+ required: ['task_id'],
32
+ },
33
+ };
34
+ function isProcessAlive(pid) {
35
+ if (!pid)
36
+ return false;
37
+ try {
38
+ process.kill(pid, 0);
39
+ return true;
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ }
45
+ export async function handleRecoverTask(args) {
46
+ try {
47
+ const parsed = RecoverTaskSchema.parse(args || {});
48
+ const taskId = parsed.task_id.toLowerCase().trim();
49
+ const task = taskManager.getTask(taskId);
50
+ if (!task) {
51
+ return mcpText(formatError('Task not found', 'Use `list_tasks` to find valid task IDs.'));
52
+ }
53
+ if (task.status !== TaskStatus.TIMED_OUT) {
54
+ return mcpText(formatError(`Task is not timed_out (status: ${task.status})`, 'Only timed_out tasks can be recovered. Use `resume_task` or `spawn_task` if needed.'));
55
+ }
56
+ let cleaned = false;
57
+ if (task.pid && isProcessAlive(task.pid)) {
58
+ try {
59
+ process.kill(task.pid, 'SIGTERM');
60
+ cleaned = true;
61
+ }
62
+ catch {
63
+ cleaned = false;
64
+ }
65
+ }
66
+ const updatedContext = cleaned
67
+ ? { ...task.timeoutContext, pidAlive: false }
68
+ : task.timeoutContext;
69
+ taskManager.updateTask(task.id, {
70
+ recoveryAttempted: true,
71
+ timeoutContext: updatedContext,
72
+ process: cleaned ? undefined : task.process,
73
+ pid: cleaned ? undefined : task.pid,
74
+ });
75
+ if (!task.sessionId) {
76
+ return mcpText(join(`Task **${task.id}** marked for recovery, but no session_id was found.`, cleaned ? 'Cleaned up lingering process.' : '', 'Use `spawn_task` to create a new task with the same prompt.'));
77
+ }
78
+ const newTaskId = await spawnCopilotProcess({
79
+ prompt: '',
80
+ timeout: parsed.timeout ?? task.timeout,
81
+ cwd: parsed.cwd ?? task.cwd,
82
+ autonomous: task.autonomous ?? true,
83
+ resumeSessionId: task.sessionId,
84
+ });
85
+ return mcpText(join(`Recovered **${task.id}** as **${newTaskId}** using session \`${task.sessionId}\`.`, cleaned ? 'Cleaned up lingering process before resume.' : '', 'Check status with `get_status`.'));
86
+ }
87
+ catch (error) {
88
+ return mcpText(formatError(error instanceof Error ? error.message : 'Unknown error', 'Ensure `task_id` is provided.'));
89
+ }
90
+ }
91
+ //# sourceMappingURL=recover-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recover-task.js","sourceRoot":"","sources":["../../src/tools/recover-task.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export declare const resumeTaskTool: {
2
+ name: string;
3
+ description: string;
4
+ inputSchema: {
5
+ type: "object";
6
+ properties: {
7
+ session_id: {
8
+ type: string;
9
+ description: string;
10
+ };
11
+ cwd: {
12
+ type: string;
13
+ description: string;
14
+ };
15
+ timeout: {
16
+ type: string;
17
+ description: string;
18
+ };
19
+ };
20
+ required: string[];
21
+ };
22
+ };
23
+ export declare function handleResumeTask(args: unknown): Promise<{
24
+ content: Array<{
25
+ type: string;
26
+ text: string;
27
+ }>;
28
+ }>;
29
+ //# sourceMappingURL=resume-task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-task.d.ts","sourceRoot":"","sources":["../../src/tools/resume-task.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;CAqB1B,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAuBjH"}
@@ -0,0 +1,43 @@
1
+ import { ResumeTaskSchema } from '../utils/sanitize.js';
2
+ import { spawnCopilotProcess } from '../services/process-spawner.js';
3
+ import { mcpText, formatError, join } from '../utils/format.js';
4
+ export const resumeTaskTool = {
5
+ name: 'resume_task',
6
+ description: `Resume an interrupted Copilot session. Get session_id from get_status response.`,
7
+ inputSchema: {
8
+ type: 'object',
9
+ properties: {
10
+ session_id: {
11
+ type: 'string',
12
+ description: 'Session ID from previous task.'
13
+ },
14
+ cwd: {
15
+ type: 'string',
16
+ description: 'Working directory. Auto-detected if omitted.'
17
+ },
18
+ timeout: {
19
+ type: 'number',
20
+ description: 'Max execution time in ms. Default: 600000 (configurable via MCP_TASK_TIMEOUT_MS).'
21
+ },
22
+ },
23
+ required: ['session_id'],
24
+ },
25
+ };
26
+ export async function handleResumeTask(args) {
27
+ try {
28
+ const input = args;
29
+ const parsed = ResumeTaskSchema.parse({ sessionId: input?.session_id || input?.sessionId, ...input });
30
+ const taskId = await spawnCopilotProcess({
31
+ prompt: '',
32
+ timeout: parsed.timeout,
33
+ cwd: parsed.cwd,
34
+ autonomous: parsed.autonomous,
35
+ resumeSessionId: parsed.sessionId,
36
+ });
37
+ return mcpText(join(`Session \`${parsed.sessionId}\` resumed as task **${taskId}**.`, 'Check status with `get_status`.'));
38
+ }
39
+ catch (error) {
40
+ return mcpText(formatError(error instanceof Error ? error.message : 'Unknown', 'Get `session_id` from a completed or failed task using `get_status` before resuming.'));
41
+ }
42
+ }
43
+ //# sourceMappingURL=resume-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-task.js","sourceRoot":"","sources":["../../src/tools/resume-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAEhE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,iFAAiF;IAC9F,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,gCAAgC;aAC9C;YACD,GAAG,EAAE;gBACH,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,8CAA8C;aAC5D;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,mFAAmF;aACjG;SACF;QACD,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAa;IAClD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAW,CAAC;QAC1B,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,IAAI,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QAEtG,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;YACvC,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,eAAe,EAAE,MAAM,CAAC,SAAS;SAClC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC,IAAI,CACjB,aAAa,MAAM,CAAC,SAAS,wBAAwB,MAAM,KAAK,EAChE,iCAAiC,CAClC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,OAAO,CAAC,WAAW,CACxB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAClD,sFAAsF,CACvF,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ export declare const retryTaskTool: {
2
+ name: string;
3
+ description: string;
4
+ inputSchema: {
5
+ type: "object";
6
+ properties: {
7
+ task_id: {
8
+ type: string;
9
+ description: string;
10
+ };
11
+ };
12
+ required: string[];
13
+ };
14
+ };
15
+ export declare function handleRetryTask(args: unknown): Promise<{
16
+ content: Array<{
17
+ type: string;
18
+ text: string;
19
+ }>;
20
+ }>;
21
+ //# sourceMappingURL=retry-task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-task.d.ts","sourceRoot":"","sources":["../../src/tools/retry-task.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,aAAa;;;;;;;;;;;;;CAazB,CAAC;AAEF,wBAAsB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA+ChH"}
@@ -0,0 +1,52 @@
1
+ import { z } from 'zod';
2
+ import { taskManager } from '../services/task-manager.js';
3
+ import { TaskStatus } from '../types.js';
4
+ import { mcpText, formatError, join, displayStatus } from '../utils/format.js';
5
+ const RetryTaskSchema = z.object({
6
+ task_id: z.string().min(1).describe('Task ID to retry'),
7
+ });
8
+ export const retryTaskTool = {
9
+ name: 'retry_task',
10
+ description: `Immediately retry a rate-limited task. Creates new task with same prompt.`,
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {
14
+ task_id: {
15
+ type: 'string',
16
+ description: 'Rate-limited task ID to retry.',
17
+ },
18
+ },
19
+ required: ['task_id'],
20
+ },
21
+ };
22
+ export async function handleRetryTask(args) {
23
+ try {
24
+ const parsed = RetryTaskSchema.parse(args || {});
25
+ const taskId = parsed.task_id.toLowerCase().trim();
26
+ const task = taskManager.getTask(taskId);
27
+ if (!task) {
28
+ return mcpText(formatError('Task not found', 'Use `list_tasks` to find valid task IDs.'));
29
+ }
30
+ if (task.status !== TaskStatus.RATE_LIMITED) {
31
+ const hint = task.status === TaskStatus.FAILED
32
+ ? 'Task has already failed. Use `spawn_task` to create a new task with the same prompt.'
33
+ : 'Only `rate_limited` tasks can be retried with this tool.';
34
+ return mcpText(formatError(`Task is not rate-limited (status: ${displayStatus(task.status)})`, hint));
35
+ }
36
+ // Check if max retries exceeded
37
+ if (task.retryInfo && task.retryInfo.retryCount >= task.retryInfo.maxRetries) {
38
+ return mcpText(formatError(`Max retries exceeded (${task.retryInfo.retryCount}/${task.retryInfo.maxRetries})`, 'Use `spawn_task` to create a new task with the same prompt.'));
39
+ }
40
+ // Trigger the retry via TaskManager
41
+ const result = await taskManager.triggerManualRetry(taskId);
42
+ if (!result.success) {
43
+ return mcpText(formatError(result.error || 'Retry failed'));
44
+ }
45
+ const attempt = (task.retryInfo?.retryCount ?? 0) + 1;
46
+ return mcpText(join(`Retried **${task.id}** as **${result.newTaskId}** (attempt ${attempt}).`, 'Check status with `get_status`.'));
47
+ }
48
+ catch (error) {
49
+ return mcpText(formatError(error instanceof Error ? error.message : 'Unknown error', 'Ensure `task_id` is provided.'));
50
+ }
51
+ }
52
+ //# sourceMappingURL=retry-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-task.js","sourceRoot":"","sources":["../../src/tools/retry-task.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export declare const simulateRateLimitTool: {
2
+ name: string;
3
+ description: string;
4
+ inputSchema: {
5
+ type: "object";
6
+ properties: {
7
+ prompt: {
8
+ type: string;
9
+ description: string;
10
+ };
11
+ skip_fallback: {
12
+ type: string;
13
+ description: string;
14
+ };
15
+ };
16
+ required: never[];
17
+ };
18
+ };
19
+ export declare function handleSimulateRateLimit(args: unknown): Promise<{
20
+ content: Array<{
21
+ type: string;
22
+ text: string;
23
+ }>;
24
+ }>;
25
+ //# sourceMappingURL=simulate-rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulate-rate-limit.d.ts","sourceRoot":"","sources":["../../src/tools/simulate-rate-limit.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;CAiBjC,CAAC;AAEF,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAqDxH"}
@@ -0,0 +1,69 @@
1
+ import { z } from 'zod';
2
+ import { taskManager } from '../services/task-manager.js';
3
+ import { TaskStatus } from '../types.js';
4
+ import { createRetryInfo } from '../services/retry-queue.js';
5
+ import { mcpText, formatError, join } from '../utils/format.js';
6
+ const SimulateRateLimitSchema = z.object({
7
+ prompt: z.string().min(1).max(50000).optional().default('Test task for rate limit simulation'),
8
+ skip_fallback: z.boolean().optional().default(false),
9
+ });
10
+ export const simulateRateLimitTool = {
11
+ name: 'simulate_rate_limit',
12
+ description: `[DEBUG] Simulate a rate-limited task to test Claude CLI fallback behavior. Creates a task, marks it as rate-limited, and optionally triggers the fallback flow via manual retry.`,
13
+ inputSchema: {
14
+ type: 'object',
15
+ properties: {
16
+ prompt: {
17
+ type: 'string',
18
+ description: 'Task prompt to use for the simulated task. Default: test prompt.',
19
+ },
20
+ skip_fallback: {
21
+ type: 'boolean',
22
+ description: 'If true, skip triggering retry/fallback and leave task in RATE_LIMITED state for inspection. Default: false.',
23
+ },
24
+ },
25
+ required: [],
26
+ },
27
+ };
28
+ export async function handleSimulateRateLimit(args) {
29
+ try {
30
+ const parsed = SimulateRateLimitSchema.parse(args || {});
31
+ // Create a task marked as coming from copilot
32
+ const task = taskManager.createTask(parsed.prompt, undefined, undefined, {
33
+ provider: 'copilot',
34
+ fallbackAttempted: parsed.skip_fallback,
35
+ });
36
+ // Simulate some output
37
+ taskManager.appendOutput(task.id, 'Starting task...');
38
+ taskManager.appendOutput(task.id, '[simulated] Error: too many requests, rate limit exceeded');
39
+ // Mark as rate-limited
40
+ const retryInfo = createRetryInfo(task, 'Simulated rate limit');
41
+ taskManager.updateTask(task.id, {
42
+ status: TaskStatus.RATE_LIMITED,
43
+ exitCode: 1,
44
+ endTime: new Date().toISOString(),
45
+ error: 'Simulated: too many requests, rate limit exceeded',
46
+ retryInfo,
47
+ });
48
+ // If not skipping fallback, trigger manual retry which will exercise the fallback path
49
+ let fallbackResult;
50
+ if (!parsed.skip_fallback) {
51
+ fallbackResult = await taskManager.triggerManualRetry(task.id);
52
+ }
53
+ let message;
54
+ if (fallbackResult?.success) {
55
+ message = join(`[Debug] Rate limit simulated for **${task.id}**.`, `Fallback retry triggered as **${fallbackResult.newTaskId}**.`, 'Check status with `get_status`.');
56
+ }
57
+ else if (parsed.skip_fallback) {
58
+ message = join(`[Debug] Rate limit simulated for **${task.id}**.`, 'Task left in `rate_limited` state for inspection.');
59
+ }
60
+ else {
61
+ message = join(`[Debug] Rate limit simulated for **${task.id}**.`, `Fallback trigger failed: ${fallbackResult?.error || 'unknown error'}`);
62
+ }
63
+ return mcpText(message);
64
+ }
65
+ catch (error) {
66
+ return mcpText(formatError(error instanceof Error ? error.message : 'Unknown error'));
67
+ }
68
+ }
69
+ //# sourceMappingURL=simulate-rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulate-rate-limit.js","sourceRoot":"","sources":["../../src/tools/simulate-rate-limit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ export declare const spawnTaskTool: {
2
+ name: string;
3
+ description: string;
4
+ inputSchema: {
5
+ type: "object";
6
+ properties: {
7
+ prompt: {
8
+ type: string;
9
+ description: string;
10
+ };
11
+ task_type: {
12
+ type: string;
13
+ enum: ("super-coder" | "super-planner" | "super-researcher" | "super-tester")[];
14
+ description: string;
15
+ };
16
+ model: {
17
+ type: string;
18
+ enum: ("claude-sonnet-4.5" | "claude-opus-4.5" | "claude-haiku-4.5")[];
19
+ description: string;
20
+ };
21
+ cwd: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ timeout: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ autonomous: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ depends_on: {
34
+ type: string;
35
+ items: {
36
+ type: string;
37
+ };
38
+ description: string;
39
+ };
40
+ labels: {
41
+ type: string;
42
+ items: {
43
+ type: string;
44
+ };
45
+ description: string;
46
+ };
47
+ };
48
+ required: string[];
49
+ };
50
+ };
51
+ export declare function handleSpawnTask(args: unknown): Promise<{
52
+ content: Array<{
53
+ type: string;
54
+ text: string;
55
+ }>;
56
+ }>;
57
+ //# sourceMappingURL=spawn-task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-task.d.ts","sourceRoot":"","sources":["../../src/tools/spawn-task.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoEzB,CAAC;AAEF,wBAAsB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAyDhH"}
@@ -0,0 +1,113 @@
1
+ import { SpawnTaskSchema } from '../utils/sanitize.js';
2
+ import { spawnCopilotProcess } from '../services/process-spawner.js';
3
+ import { taskManager } from '../services/task-manager.js';
4
+ import { MODEL_IDS, DEFAULT_MODEL } from '../models.js';
5
+ import { TASK_TYPE_IDS, applyTemplate, isValidTaskType } from '../templates/index.js';
6
+ import { mcpText, formatError, join } from '../utils/format.js';
7
+ export const spawnTaskTool = {
8
+ name: 'spawn_task',
9
+ description: `Spawn an autonomous agent task. Each task runs as a completely isolated agent with NO shared memory or conversation history -- the prompt you provide is the ONLY context the agent receives.
10
+
11
+ IMPORTANT: Prefer spawning tasks one at a time with spawn_task. Only use batch_spawn when you have multiple small tasks with explicit cross-dependencies that must be set up atomically. For most work, individual spawn_task calls give you better control and let you write more detailed, context-rich prompts for each task.
12
+
13
+ Task types: super-coder (implementation), super-planner (architecture), super-researcher (investigation), super-tester (QA).
14
+ Models: ${MODEL_IDS.join(', ')}. Default: ${DEFAULT_MODEL}.`,
15
+ inputSchema: {
16
+ type: 'object',
17
+ properties: {
18
+ prompt: {
19
+ type: 'string',
20
+ description: `The complete, self-contained instructions for the spawned agent. This is the ONLY context the agent will have -- it cannot see your conversation history, previous tool calls, or any other context.
21
+
22
+ Your prompt MUST include:
23
+ - WHAT to do: Clear, specific objective (not vague like "fix the bug" -- say exactly which bug, which file, what the expected behavior is)
24
+ - WHERE to do it: All relevant file paths as absolute paths (e.g. /Users/dev/project/src/auth.ts, not just "auth.ts")
25
+ - HOW to verify: What does "done" look like? What tests to run? What to check?
26
+ - CONTEXT: Any background the agent needs -- error messages, stack traces, related code snippets, architectural decisions
27
+
28
+ BAD prompt: "Fix the login bug"
29
+ GOOD prompt: "In /Users/dev/myapp/src/services/auth.ts, the login() function on line 45 throws 'TypeError: Cannot read property email of undefined' when the user object is null. Fix the null check, ensure the function returns a proper error response for missing users, and verify by running: npm test -- --grep login"
30
+
31
+ The more detailed your prompt, the better the agent performs. Treat it as a complete brief for a developer who has never seen the codebase before.`,
32
+ },
33
+ task_type: {
34
+ type: 'string',
35
+ enum: TASK_TYPE_IDS,
36
+ description: `Agent template that prepends specialized system instructions to your prompt.
37
+ - super-coder: For implementation tasks -- writing, editing, refactoring code
38
+ - super-planner: For architecture and design -- planning implementations, evaluating tradeoffs
39
+ - super-researcher: For investigation -- answering questions, finding code patterns, analyzing behavior
40
+ - super-tester: For QA -- writing tests, running test suites, verifying behavior`,
41
+ },
42
+ model: {
43
+ type: 'string',
44
+ enum: MODEL_IDS,
45
+ description: `Model to use. Default: ${DEFAULT_MODEL}.
46
+ - claude-sonnet-4.5: Best balance of speed and capability (default, recommended for most tasks)
47
+ - claude-haiku-4.5: Fastest -- use for simple, well-defined tasks like running a single command or small edits
48
+ - claude-opus-4.5: Most capable -- use for complex reasoning, large refactors, or tasks requiring deep analysis`,
49
+ },
50
+ cwd: {
51
+ type: 'string',
52
+ description: `The absolute path to the working directory where the agent will execute. You should detect your current working directory and pass it here as a full absolute path. This is especially important when working in git worktrees -- pass the actual worktree path (e.g. /Users/dev/project/worktrees/feature-branch), NOT the main repository root. Do not create a new worktree just for this -- simply pass the directory you are currently working in.`,
53
+ },
54
+ timeout: {
55
+ type: 'number',
56
+ description: 'Max execution time in ms. Default: 600000 (10 min, configurable via MCP_TASK_TIMEOUT_MS). Max: 3600000 (configurable via MCP_TASK_TIMEOUT_MAX_MS). Increase for large tasks.',
57
+ },
58
+ autonomous: {
59
+ type: 'boolean',
60
+ description: 'Run without interactive prompts. Default: true. Almost always leave this as true.',
61
+ },
62
+ depends_on: {
63
+ type: 'array',
64
+ items: { type: 'string' },
65
+ description: 'Task IDs that must complete before this task starts. The task will wait in "waiting" status until all dependencies finish.',
66
+ },
67
+ labels: {
68
+ type: 'array',
69
+ items: { type: 'string' },
70
+ description: 'Labels for grouping and filtering tasks (max 10). Useful when managing multiple related tasks -- e.g. "auth-migration", "phase-1".',
71
+ },
72
+ },
73
+ required: ['prompt'],
74
+ },
75
+ };
76
+ export async function handleSpawnTask(args) {
77
+ try {
78
+ const parsed = SpawnTaskSchema.parse(args);
79
+ // Validate dependencies if provided
80
+ const dependsOn = parsed.depends_on?.filter((d) => d.trim()) || [];
81
+ if (dependsOn.length > 0) {
82
+ const validationError = taskManager.validateDependencies(dependsOn);
83
+ if (validationError) {
84
+ return mcpText(formatError(validationError, 'Ensure all dependency task IDs exist.\nUse `list_tasks` to find valid task IDs.'));
85
+ }
86
+ }
87
+ let finalPrompt = parsed.prompt;
88
+ if (parsed.task_type && isValidTaskType(parsed.task_type)) {
89
+ finalPrompt = applyTemplate(parsed.task_type, parsed.prompt);
90
+ }
91
+ const labels = parsed.labels?.filter((l) => l.trim()) || [];
92
+ const taskId = await spawnCopilotProcess({
93
+ prompt: finalPrompt,
94
+ timeout: parsed.timeout,
95
+ cwd: parsed.cwd,
96
+ model: parsed.model,
97
+ autonomous: parsed.autonomous,
98
+ dependsOn: dependsOn.length > 0 ? dependsOn : undefined,
99
+ labels: labels.length > 0 ? labels : undefined,
100
+ });
101
+ const task = taskManager.getTask(taskId);
102
+ const isWaiting = task?.status === 'waiting';
103
+ if (isWaiting) {
104
+ const depsList = dependsOn.map(d => `\`${d}\``).join(', ');
105
+ return mcpText(join(`Task **${taskId}** spawned (waiting).`, `Depends on: ${depsList}`, '', 'Dependencies must complete before this task runs.', 'Check status with `get_status`.'));
106
+ }
107
+ return mcpText(join(`Task **${taskId}** spawned (${task?.status || 'pending'}).`, 'Check status with `get_status`.'));
108
+ }
109
+ catch (error) {
110
+ return mcpText(formatError(error instanceof Error ? error.message : 'Unknown error', 'Check that the `prompt` parameter is provided and valid.'));
111
+ }
112
+ }
113
+ //# sourceMappingURL=spawn-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-task.js","sourceRoot":"","sources":["../../src/tools/spawn-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAU,aAAa,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,aAAa,EAAc,aAAa,EAAE,eAAe,EAAiB,MAAM,uBAAuB,CAAC;AACjH,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAgB,MAAM,oBAAoB,CAAC;AAE9E,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE;;;;;UAKL,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,aAAa,GAAG;IAC1D,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;;;;;;;;;;;mJAW8H;aAC5I;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE;;;;iFAI4D;aAC1E;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,0BAA0B,aAAa;;;gHAGoD;aACzG;YACD,GAAG,EAAE;gBACH,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,ybAAyb;aACvc;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,8KAA8K;aAC5L;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,mFAAmF;aACjG;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,WAAW,EAAE,4HAA4H;aAC1I;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,WAAW,EAAE,oIAAoI;aAClJ;SACF;QACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;KACrB;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAa;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE3C,oCAAoC;QACpC,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QAC3E,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,eAAe,GAAG,WAAW,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;YACpE,IAAI,eAAe,EAAE,CAAC;gBACpB,OAAO,OAAO,CAAC,WAAW,CACxB,eAAe,EACf,iFAAiF,CAClF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,IAAI,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;QAChC,IAAI,MAAM,CAAC,SAAS,IAAI,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1D,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,SAAqB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QAEpE,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;YACvC,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACvD,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;SAC/C,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;QAE7C,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,OAAO,OAAO,CAAC,IAAI,CACjB,UAAU,MAAM,uBAAuB,EACvC,eAAe,QAAQ,EAAE,EACzB,EAAE,EACF,mDAAmD,EACnD,iCAAiC,CAClC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,OAAO,CAAC,IAAI,CACjB,UAAU,MAAM,eAAe,IAAI,EAAE,MAAM,IAAI,SAAS,IAAI,EAC5D,iCAAiC,CAClC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,OAAO,CAAC,WAAW,CACxB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EACxD,0DAA0D,CAC3D,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,29 @@
1
+ export declare const streamOutputTool: {
2
+ name: string;
3
+ description: string;
4
+ inputSchema: {
5
+ type: "object";
6
+ properties: {
7
+ task_id: {
8
+ type: string;
9
+ description: string;
10
+ };
11
+ offset: {
12
+ type: string;
13
+ description: string;
14
+ };
15
+ limit: {
16
+ type: string;
17
+ description: string;
18
+ };
19
+ };
20
+ required: string[];
21
+ };
22
+ };
23
+ export declare function handleStreamOutput(args: unknown): Promise<{
24
+ content: Array<{
25
+ type: string;
26
+ text: string;
27
+ }>;
28
+ }>;
29
+ //# sourceMappingURL=stream-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-output.d.ts","sourceRoot":"","sources":["../../src/tools/stream-output.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;CAqB5B,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAiEnH"}