gm-orchestrator 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +215 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/orchestrator.d.ts +23 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +173 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/permissions.d.ts +18 -0
- package/dist/core/permissions.d.ts.map +1 -0
- package/dist/core/permissions.js +42 -0
- package/dist/core/permissions.js.map +1 -0
- package/dist/core/prompt-builder.d.ts +25 -0
- package/dist/core/prompt-builder.d.ts.map +1 -0
- package/dist/core/prompt-builder.js +84 -0
- package/dist/core/prompt-builder.js.map +1 -0
- package/dist/core/task-utils.d.ts +5 -0
- package/dist/core/task-utils.d.ts.map +1 -0
- package/dist/core/task-utils.js +27 -0
- package/dist/core/task-utils.js.map +1 -0
- package/dist/core/types.d.ts +150 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/infra/claude-runner.d.ts +14 -0
- package/dist/infra/claude-runner.d.ts.map +1 -0
- package/dist/infra/claude-runner.js +42 -0
- package/dist/infra/claude-runner.js.map +1 -0
- package/dist/infra/config.d.ts +7 -0
- package/dist/infra/config.d.ts.map +1 -0
- package/dist/infra/config.js +61 -0
- package/dist/infra/config.js.map +1 -0
- package/dist/infra/gm-client.d.ts +32 -0
- package/dist/infra/gm-client.d.ts.map +1 -0
- package/dist/infra/gm-client.js +70 -0
- package/dist/infra/gm-client.js.map +1 -0
- package/dist/infra/gm-discovery.d.ts +16 -0
- package/dist/infra/gm-discovery.d.ts.map +1 -0
- package/dist/infra/gm-discovery.js +53 -0
- package/dist/infra/gm-discovery.js.map +1 -0
- package/dist/infra/logger.d.ts +13 -0
- package/dist/infra/logger.d.ts.map +1 -0
- package/dist/infra/logger.js +44 -0
- package/dist/infra/logger.js.map +1 -0
- package/dist/infra/notifications/desktop.d.ts +6 -0
- package/dist/infra/notifications/desktop.d.ts.map +1 -0
- package/dist/infra/notifications/desktop.js +18 -0
- package/dist/infra/notifications/desktop.js.map +1 -0
- package/dist/infra/notifications/index.d.ts +9 -0
- package/dist/infra/notifications/index.d.ts.map +1 -0
- package/dist/infra/notifications/index.js +40 -0
- package/dist/infra/notifications/index.js.map +1 -0
- package/dist/infra/notifications/telegram.d.ts +9 -0
- package/dist/infra/notifications/telegram.d.ts.map +1 -0
- package/dist/infra/notifications/telegram.js +41 -0
- package/dist/infra/notifications/telegram.js.map +1 -0
- package/dist/infra/notifications/types.d.ts +30 -0
- package/dist/infra/notifications/types.d.ts.map +1 -0
- package/dist/infra/notifications/types.js +3 -0
- package/dist/infra/notifications/types.js.map +1 -0
- package/dist/infra/notifications/webhook.d.ts +9 -0
- package/dist/infra/notifications/webhook.d.ts.map +1 -0
- package/dist/infra/notifications/webhook.js +39 -0
- package/dist/infra/notifications/webhook.js.map +1 -0
- package/dist/infra/task-poller.d.ts +9 -0
- package/dist/infra/task-poller.d.ts.map +1 -0
- package/dist/infra/task-poller.js +42 -0
- package/dist/infra/task-poller.js.map +1 -0
- package/dist/server/api.d.ts +23 -0
- package/dist/server/api.d.ts.map +1 -0
- package/dist/server/api.js +143 -0
- package/dist/server/api.js.map +1 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +73 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/runner-service.d.ts +15 -0
- package/dist/server/runner-service.d.ts.map +1 -0
- package/dist/server/runner-service.js +193 -0
- package/dist/server/runner-service.js.map +1 -0
- package/dist/server/ws.d.ts +9 -0
- package/dist/server/ws.d.ts.map +1 -0
- package/dist/server/ws.js +30 -0
- package/dist/server/ws.js.map +1 -0
- package/dist/ui/assets/index-BYPkFAEX.css +1 -0
- package/dist/ui/assets/index-CEQTkIqE.js +60 -0
- package/dist/ui/index.html +13 -0
- package/package.json +70 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { sortByPriority, areBlockersResolved } from './task-utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* Orchestrates a full sprint: runs all todo/in_progress tasks in priority
|
|
4
|
+
* order, respecting blockers, retrying on failure, until none remain.
|
|
5
|
+
*
|
|
6
|
+
* Pure orchestration logic — all side effects go through injected ports.
|
|
7
|
+
* This makes the core fully testable without spawning Claude or hitting GM.
|
|
8
|
+
*/
|
|
9
|
+
export async function runSprint(ports, config) {
|
|
10
|
+
const { gm, logger } = ports;
|
|
11
|
+
const startTime = Date.now();
|
|
12
|
+
const stats = { done: 0, cancelled: 0, retried: 0, errors: 0, skipped: 0, durationMs: 0 };
|
|
13
|
+
const failedIds = new Set();
|
|
14
|
+
const retryCounts = new Map();
|
|
15
|
+
logger.section(`Sprint — project: ${config.projectId}${config.tag ? ` tag: ${config.tag}` : ''}`);
|
|
16
|
+
while (true) {
|
|
17
|
+
const tagFilter = config.tag !== undefined ? { tag: config.tag } : {};
|
|
18
|
+
const [inProgress, todo] = await Promise.all([
|
|
19
|
+
gm.listTasks({ status: 'in_progress', ...tagFilter }),
|
|
20
|
+
gm.listTasks({ status: 'todo', ...tagFilter }),
|
|
21
|
+
]);
|
|
22
|
+
// in_progress first (resuming), then todo sorted by priority
|
|
23
|
+
const queue = [
|
|
24
|
+
...sortByPriority(inProgress),
|
|
25
|
+
...sortByPriority(todo),
|
|
26
|
+
].filter((t) => !failedIds.has(t.id));
|
|
27
|
+
if (!queue.length) {
|
|
28
|
+
logger.section('Sprint complete');
|
|
29
|
+
stats.durationMs = Date.now() - startTime;
|
|
30
|
+
logStats(logger, stats);
|
|
31
|
+
return stats;
|
|
32
|
+
}
|
|
33
|
+
const next = findNextRunnable(queue, logger);
|
|
34
|
+
if (!next) {
|
|
35
|
+
logger.warn(`${queue.length} tasks remain but all are blocked — stopping`);
|
|
36
|
+
queue.forEach((t) => logger.skip(` blocked: ${t.title} (${t.id})`));
|
|
37
|
+
stats.durationMs = Date.now() - startTime;
|
|
38
|
+
logStats(logger, stats);
|
|
39
|
+
return stats;
|
|
40
|
+
}
|
|
41
|
+
const result = await runOneTask(next, ports, config);
|
|
42
|
+
await handleResult(result, next, {
|
|
43
|
+
gm, logger, stats, failedIds, retryCounts,
|
|
44
|
+
maxRetries: config.maxRetries,
|
|
45
|
+
});
|
|
46
|
+
await sleep(config.pauseMs);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Runs all tasks belonging to an epic, in priority order with blocker checks.
|
|
51
|
+
* Marks the epic done when all tasks complete.
|
|
52
|
+
*/
|
|
53
|
+
export async function runEpic(epicId, ports, config) {
|
|
54
|
+
const { gm, logger } = ports;
|
|
55
|
+
const startTime = Date.now();
|
|
56
|
+
const stats = { done: 0, cancelled: 0, retried: 0, errors: 0, skipped: 0, durationMs: 0 };
|
|
57
|
+
const epic = await gm.getEpic(epicId);
|
|
58
|
+
logger.section(`Epic: "${epic.title}" (${epicId})`);
|
|
59
|
+
logger.info(`Priority: ${epic.priority} Status: ${epic.status}`);
|
|
60
|
+
const epicTaskIds = new Set((epic.tasks ?? []).map((t) => t.id));
|
|
61
|
+
const failedIds = new Set();
|
|
62
|
+
const retryCounts = new Map();
|
|
63
|
+
while (true) {
|
|
64
|
+
// Fetch fresh task data for all epic tasks
|
|
65
|
+
const allTasks = await Promise.all([...epicTaskIds].map((id) => gm.getTask(id).catch(() => null)));
|
|
66
|
+
const queue = sortByPriority(allTasks.filter((t) => t !== null &&
|
|
67
|
+
!['done', 'cancelled'].includes(t.status) &&
|
|
68
|
+
!failedIds.has(t.id)));
|
|
69
|
+
if (!queue.length) {
|
|
70
|
+
const allDone = allTasks.every((t) => t?.status === 'done');
|
|
71
|
+
if (allDone) {
|
|
72
|
+
logger.success('All epic tasks done — marking epic complete');
|
|
73
|
+
await gm.moveEpic(epicId, 'done');
|
|
74
|
+
}
|
|
75
|
+
logger.section('Epic complete');
|
|
76
|
+
stats.durationMs = Date.now() - startTime;
|
|
77
|
+
logStats(logger, stats);
|
|
78
|
+
return stats;
|
|
79
|
+
}
|
|
80
|
+
const next = findNextRunnable(queue, logger);
|
|
81
|
+
if (!next) {
|
|
82
|
+
logger.warn('All remaining epic tasks are blocked — stopping');
|
|
83
|
+
stats.durationMs = Date.now() - startTime;
|
|
84
|
+
logStats(logger, stats);
|
|
85
|
+
return stats;
|
|
86
|
+
}
|
|
87
|
+
const result = await runOneTask(next, ports, config);
|
|
88
|
+
await handleResult(result, next, {
|
|
89
|
+
gm, logger, stats, failedIds, retryCounts,
|
|
90
|
+
maxRetries: config.maxRetries,
|
|
91
|
+
});
|
|
92
|
+
await sleep(config.pauseMs);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// ── Internal ──────────────────────────────────────────────────────────────
|
|
96
|
+
function findNextRunnable(queue, logger) {
|
|
97
|
+
for (const task of queue) {
|
|
98
|
+
if (areBlockersResolved(task))
|
|
99
|
+
return task;
|
|
100
|
+
logger.skip(`blocked: "${task.title}"`);
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
async function runOneTask(task, { gm, runner, poller, logger }, config) {
|
|
105
|
+
logger.task(task);
|
|
106
|
+
// Mark in_progress (idempotent)
|
|
107
|
+
if (task.status !== 'in_progress') {
|
|
108
|
+
await gm.moveTask(task.id, 'in_progress').catch((e) => {
|
|
109
|
+
logger.warn(`Could not mark in_progress: ${String(e)}`);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (config.dryRun) {
|
|
113
|
+
logger.warn('[DRY RUN] Would spawn claude --print <prompt>');
|
|
114
|
+
await gm.moveTask(task.id, 'done').catch(() => { });
|
|
115
|
+
return 'dry_run';
|
|
116
|
+
}
|
|
117
|
+
// Spawn Claude Code session (fire and forget — poller drives completion)
|
|
118
|
+
const sessionPromise = runner.run(task, config).catch((e) => {
|
|
119
|
+
logger.warn(`Claude session error: ${String(e)}`);
|
|
120
|
+
});
|
|
121
|
+
// Poll GraphMemory until task reaches terminal state
|
|
122
|
+
const pollResult = await poller.waitForCompletion(task.id, {
|
|
123
|
+
timeoutMs: config.timeoutMs,
|
|
124
|
+
});
|
|
125
|
+
await sessionPromise; // let process clean up
|
|
126
|
+
if (pollResult === 'timeout') {
|
|
127
|
+
logger.error(`Timeout: "${task.title}" (${task.id})`);
|
|
128
|
+
return 'timeout';
|
|
129
|
+
}
|
|
130
|
+
if (pollResult === 'done') {
|
|
131
|
+
logger.success(`Done: "${task.title}"`);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
logger.warn(`Cancelled: "${task.title}"`);
|
|
135
|
+
}
|
|
136
|
+
return pollResult;
|
|
137
|
+
}
|
|
138
|
+
async function handleResult(result, task, ctx) {
|
|
139
|
+
const { gm, logger, stats, failedIds, retryCounts, maxRetries } = ctx;
|
|
140
|
+
if (result === 'done' || result === 'dry_run') {
|
|
141
|
+
stats.done++;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (result === 'cancelled') {
|
|
145
|
+
stats.cancelled++;
|
|
146
|
+
failedIds.add(task.id);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// timeout | error
|
|
150
|
+
const retries = retryCounts.get(task.id) ?? 0;
|
|
151
|
+
if (retries < maxRetries) {
|
|
152
|
+
retryCounts.set(task.id, retries + 1);
|
|
153
|
+
stats.retried++;
|
|
154
|
+
logger.warn(`Retrying (${retries + 1}/${maxRetries}): ${task.id}`);
|
|
155
|
+
await gm.moveTask(task.id, 'todo').catch(() => { });
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
stats.errors++;
|
|
159
|
+
failedIds.add(task.id);
|
|
160
|
+
logger.error(`Giving up on: ${task.id}`);
|
|
161
|
+
await gm.moveTask(task.id, 'cancelled').catch(() => { });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function logStats(logger, stats) {
|
|
165
|
+
const secs = Math.round(stats.durationMs / 1000);
|
|
166
|
+
logger.info(`✓ ${stats.done} done ✗ ${stats.cancelled} cancelled ` +
|
|
167
|
+
`↺ ${stats.retried} retried ⚠ ${stats.errors} errors ` +
|
|
168
|
+
`⏱ ${secs}s`);
|
|
169
|
+
}
|
|
170
|
+
function sleep(ms) {
|
|
171
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Permissions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Translates user permission config into Claude Code --allowedTools flags.
|
|
4
|
+
*
|
|
5
|
+
* Rules:
|
|
6
|
+
* - "Read" is always included (cannot be disabled)
|
|
7
|
+
* - "Write" and "Edit" are included only when writeFiles is true
|
|
8
|
+
* - Each runCommands entry becomes "Bash(<command>)"
|
|
9
|
+
* - A command appearing in both runCommands and blockedCommands throws
|
|
10
|
+
* - mcpTools controls MCP tool inclusion: "all" | "none" | string[]
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildAllowedTools(permissions: Permissions): string[];
|
|
13
|
+
/**
|
|
14
|
+
* Returns true if the command is allowed, false if blocked.
|
|
15
|
+
* Uses substring matching against the blockedCommands list.
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateCommand(cmd: string, permissions: Permissions): boolean;
|
|
18
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/core/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,EAAE,CA+BpE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAI9E"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translates user permission config into Claude Code --allowedTools flags.
|
|
3
|
+
*
|
|
4
|
+
* Rules:
|
|
5
|
+
* - "Read" is always included (cannot be disabled)
|
|
6
|
+
* - "Write" and "Edit" are included only when writeFiles is true
|
|
7
|
+
* - Each runCommands entry becomes "Bash(<command>)"
|
|
8
|
+
* - A command appearing in both runCommands and blockedCommands throws
|
|
9
|
+
* - mcpTools controls MCP tool inclusion: "all" | "none" | string[]
|
|
10
|
+
*/
|
|
11
|
+
export function buildAllowedTools(permissions) {
|
|
12
|
+
// Validate: no command may appear in both runCommands and blockedCommands
|
|
13
|
+
const conflicts = permissions.runCommands.filter((cmd) => permissions.blockedCommands.some((blocked) => cmd.includes(blocked) || blocked.includes(cmd)));
|
|
14
|
+
if (conflicts.length > 0) {
|
|
15
|
+
throw new Error(`Permission conflict: commands appear in both runCommands and blockedCommands: ${conflicts.join(', ')}`);
|
|
16
|
+
}
|
|
17
|
+
const tools = ['Read'];
|
|
18
|
+
if (permissions.writeFiles) {
|
|
19
|
+
tools.push('Write', 'Edit');
|
|
20
|
+
}
|
|
21
|
+
for (const cmd of permissions.runCommands) {
|
|
22
|
+
tools.push(`Bash(${cmd})`);
|
|
23
|
+
}
|
|
24
|
+
// MCP tools
|
|
25
|
+
if (permissions.mcpTools === 'all') {
|
|
26
|
+
tools.push('mcp__*');
|
|
27
|
+
}
|
|
28
|
+
else if (permissions.mcpTools !== 'none') {
|
|
29
|
+
for (const tool of permissions.mcpTools) {
|
|
30
|
+
tools.push(tool);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return tools;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Returns true if the command is allowed, false if blocked.
|
|
37
|
+
* Uses substring matching against the blockedCommands list.
|
|
38
|
+
*/
|
|
39
|
+
export function validateCommand(cmd, permissions) {
|
|
40
|
+
return !permissions.blockedCommands.some((blocked) => cmd.includes(blocked));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/core/permissions.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAwB;IACxD,0EAA0E;IAC1E,MAAM,SAAS,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CACvD,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAC9F,CAAC;IACF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,iFAAiF,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACxG,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAa,CAAC,MAAM,CAAC,CAAC;IAEjC,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,YAAY;IACZ,IAAI,WAAW,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvB,CAAC;SAAM,IAAI,WAAW,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,WAAwB;IACnE,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CACtC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CACnC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Task, OrchestratorConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a self-contained, autonomous prompt for a single Claude Code session.
|
|
4
|
+
*
|
|
5
|
+
* AI-first design principles applied here:
|
|
6
|
+
*
|
|
7
|
+
* 1. CONTEXT FRONT-LOADING — everything Claude needs is in the prompt.
|
|
8
|
+
* No back-and-forth, no clarifying questions possible.
|
|
9
|
+
*
|
|
10
|
+
* 2. EXPLICIT CONTRACT — the only output we care about is tasks_move().
|
|
11
|
+
* Claude doesn't need to write to stdout, return JSON, or signal in any
|
|
12
|
+
* other way. This is the single integration point.
|
|
13
|
+
*
|
|
14
|
+
* 3. TOOL-FIRST INSTRUCTIONS — Claude is told to use GraphMemory tools
|
|
15
|
+
* (tasks_get, skills_recall) before doing any work. This leverages the
|
|
16
|
+
* existing knowledge graph instead of reasoning from scratch.
|
|
17
|
+
*
|
|
18
|
+
* 4. FAILURE MODES ARE EXPLICIT — Claude knows what to do when blocked,
|
|
19
|
+
* impossible, or ambiguous. No hanging sessions.
|
|
20
|
+
*
|
|
21
|
+
* 5. MINIMAL PROMPT — only what's needed. The description might be empty
|
|
22
|
+
* deliberately (Claude fetches full context via tasks_get). Don't pad.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildPrompt(task: Task, config: Pick<OrchestratorConfig, 'projectId'>): string;
|
|
25
|
+
//# sourceMappingURL=prompt-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/core/prompt-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,MAAM,CAoC7F"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a self-contained, autonomous prompt for a single Claude Code session.
|
|
3
|
+
*
|
|
4
|
+
* AI-first design principles applied here:
|
|
5
|
+
*
|
|
6
|
+
* 1. CONTEXT FRONT-LOADING — everything Claude needs is in the prompt.
|
|
7
|
+
* No back-and-forth, no clarifying questions possible.
|
|
8
|
+
*
|
|
9
|
+
* 2. EXPLICIT CONTRACT — the only output we care about is tasks_move().
|
|
10
|
+
* Claude doesn't need to write to stdout, return JSON, or signal in any
|
|
11
|
+
* other way. This is the single integration point.
|
|
12
|
+
*
|
|
13
|
+
* 3. TOOL-FIRST INSTRUCTIONS — Claude is told to use GraphMemory tools
|
|
14
|
+
* (tasks_get, skills_recall) before doing any work. This leverages the
|
|
15
|
+
* existing knowledge graph instead of reasoning from scratch.
|
|
16
|
+
*
|
|
17
|
+
* 4. FAILURE MODES ARE EXPLICIT — Claude knows what to do when blocked,
|
|
18
|
+
* impossible, or ambiguous. No hanging sessions.
|
|
19
|
+
*
|
|
20
|
+
* 5. MINIMAL PROMPT — only what's needed. The description might be empty
|
|
21
|
+
* deliberately (Claude fetches full context via tasks_get). Don't pad.
|
|
22
|
+
*/
|
|
23
|
+
export function buildPrompt(task, config) {
|
|
24
|
+
const sections = [];
|
|
25
|
+
sections.push(`# Autonomous Task Execution`);
|
|
26
|
+
sections.push(`You are running as an autonomous agent inside an orchestrator pipeline.\n` +
|
|
27
|
+
`Complete the task below WITHOUT asking for confirmation or clarification.\n` +
|
|
28
|
+
`The orchestrator has no stdin — it only watches GraphMemory task status.`);
|
|
29
|
+
sections.push(`## Task`);
|
|
30
|
+
sections.push(formatTaskHeader(task));
|
|
31
|
+
sections.push(`## Execution Protocol`);
|
|
32
|
+
sections.push(buildProtocol(task));
|
|
33
|
+
if (task.blockedBy?.length) {
|
|
34
|
+
sections.push(`## Resolved Blockers (for context)`);
|
|
35
|
+
sections.push(task.blockedBy.map((b) => `- ${b.title} (${b.id}) ✓`).join('\n'));
|
|
36
|
+
}
|
|
37
|
+
if (task.subtasks?.length) {
|
|
38
|
+
sections.push(`## Subtasks`);
|
|
39
|
+
sections.push(task.subtasks.map((s) => `- [${s.status === 'done' ? 'x' : ' '}] ${s.title} — \`${s.id}\``).join('\n'));
|
|
40
|
+
}
|
|
41
|
+
sections.push(`## Completion Signal`);
|
|
42
|
+
sections.push(`When done: \`tasks_move("${task.id}", "done")\`\n` +
|
|
43
|
+
`When cancelled: \`tasks_move("${task.id}", "cancelled")\` + update description with reason\n\n` +
|
|
44
|
+
`**This is the only output the orchestrator reads. Do not skip it.**`);
|
|
45
|
+
return sections.join('\n\n');
|
|
46
|
+
}
|
|
47
|
+
function formatTaskHeader(task) {
|
|
48
|
+
const lines = [
|
|
49
|
+
`**ID**: \`${task.id}\``,
|
|
50
|
+
`**Title**: ${task.title}`,
|
|
51
|
+
`**Priority**: ${task.priority}`,
|
|
52
|
+
];
|
|
53
|
+
if (task.tags?.length)
|
|
54
|
+
lines.push(`**Tags**: ${task.tags.join(', ')}`);
|
|
55
|
+
if (task.estimate)
|
|
56
|
+
lines.push(`**Estimate**: ${task.estimate}`);
|
|
57
|
+
if (task.dueDate)
|
|
58
|
+
lines.push(`**Due**: ${task.dueDate}`);
|
|
59
|
+
if (task.description) {
|
|
60
|
+
lines.push(`\n**Description**:\n${task.description}`);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
lines.push(`\n_(No description — fetch full context via tasks_get)_`);
|
|
64
|
+
}
|
|
65
|
+
return lines.join('\n');
|
|
66
|
+
}
|
|
67
|
+
function buildProtocol(task) {
|
|
68
|
+
const steps = [
|
|
69
|
+
`1. **Get full context**: \`tasks_get("${task.id}")\` — reads cross-links, attachments, notes`,
|
|
70
|
+
`2. **Check for recipes**: \`skills_recall("<task topic>")\` — use existing patterns if available`,
|
|
71
|
+
`3. **Do the work**: use all available tools (edit files, run commands, search code, etc.)`,
|
|
72
|
+
];
|
|
73
|
+
if (task.subtasks?.length) {
|
|
74
|
+
steps.push(`4. **Subtasks**: complete each one and call \`tasks_move(subtaskId, "done")\` per subtask`);
|
|
75
|
+
steps.push(`5. **Signal completion**: \`tasks_move("${task.id}", "done")\``);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
steps.push(`4. **Signal completion**: \`tasks_move("${task.id}", "done")\``);
|
|
79
|
+
}
|
|
80
|
+
steps.push(`\n**If blocked or impossible**: call \`tasks_move("${task.id}", "cancelled")\` immediately ` +
|
|
81
|
+
`and update the task description with the specific blocker. Do not spin.`);
|
|
82
|
+
return steps.join('\n');
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=prompt-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../src/core/prompt-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Task } from './types.js';
|
|
2
|
+
export declare function sortByPriority(tasks: Task[]): Task[];
|
|
3
|
+
export declare function isTerminal(status: string): boolean;
|
|
4
|
+
export declare function areBlockersResolved(task: Task): boolean;
|
|
5
|
+
//# sourceMappingURL=task-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-utils.d.ts","sourceRoot":"","sources":["../../src/core/task-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAgB,MAAM,YAAY,CAAC;AASrD,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAUpD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAGvD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const PRIORITY_ORDER = {
|
|
2
|
+
critical: 0,
|
|
3
|
+
high: 1,
|
|
4
|
+
medium: 2,
|
|
5
|
+
low: 3,
|
|
6
|
+
};
|
|
7
|
+
export function sortByPriority(tasks) {
|
|
8
|
+
return [...tasks].sort((a, b) => {
|
|
9
|
+
const pa = PRIORITY_ORDER[a.priority] ?? 4;
|
|
10
|
+
const pb = PRIORITY_ORDER[b.priority] ?? 4;
|
|
11
|
+
if (pa !== pb)
|
|
12
|
+
return pa - pb;
|
|
13
|
+
// Secondary: earliest dueDate
|
|
14
|
+
const da = a.dueDate ? new Date(a.dueDate).getTime() : Infinity;
|
|
15
|
+
const db = b.dueDate ? new Date(b.dueDate).getTime() : Infinity;
|
|
16
|
+
return da - db;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export function isTerminal(status) {
|
|
20
|
+
return status === 'done' || status === 'cancelled';
|
|
21
|
+
}
|
|
22
|
+
export function areBlockersResolved(task) {
|
|
23
|
+
if (!task.blockedBy?.length)
|
|
24
|
+
return true;
|
|
25
|
+
return task.blockedBy.every((b) => b.status === 'done');
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=task-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-utils.js","sourceRoot":"","sources":["../../src/core/task-utils.ts"],"names":[],"mappings":"AAEA,MAAM,cAAc,GAAiC;IACnD,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;CACP,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,GAAG,EAAE,CAAC;QAC9B,8BAA8B;QAC9B,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAChE,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAChE,OAAO,EAAE,GAAG,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,WAAW,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAU;IAC5C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export type TaskStatus = 'todo' | 'in_progress' | 'done' | 'cancelled';
|
|
2
|
+
export type TaskPriority = 'critical' | 'high' | 'medium' | 'low';
|
|
3
|
+
export type EpicStatus = 'todo' | 'in_progress' | 'done' | 'cancelled';
|
|
4
|
+
export interface TaskRef {
|
|
5
|
+
id: string;
|
|
6
|
+
title: string;
|
|
7
|
+
status: TaskStatus;
|
|
8
|
+
}
|
|
9
|
+
export interface Task {
|
|
10
|
+
id: string;
|
|
11
|
+
title: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
status: TaskStatus;
|
|
14
|
+
priority: TaskPriority;
|
|
15
|
+
tags?: string[];
|
|
16
|
+
dueDate?: string;
|
|
17
|
+
estimate?: string;
|
|
18
|
+
assignee?: string;
|
|
19
|
+
completedAt?: string;
|
|
20
|
+
createdAt: string;
|
|
21
|
+
updatedAt: string;
|
|
22
|
+
subtasks?: TaskRef[];
|
|
23
|
+
blockedBy?: TaskRef[];
|
|
24
|
+
blocks?: TaskRef[];
|
|
25
|
+
related?: TaskRef[];
|
|
26
|
+
}
|
|
27
|
+
export interface Epic {
|
|
28
|
+
id: string;
|
|
29
|
+
title: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
status: EpicStatus;
|
|
32
|
+
priority: TaskPriority;
|
|
33
|
+
tags?: string[];
|
|
34
|
+
tasks?: TaskRef[];
|
|
35
|
+
createdAt: string;
|
|
36
|
+
updatedAt: string;
|
|
37
|
+
}
|
|
38
|
+
export interface Permissions {
|
|
39
|
+
writeFiles: boolean;
|
|
40
|
+
runCommands: string[];
|
|
41
|
+
blockedCommands: string[];
|
|
42
|
+
mcpTools: 'all' | 'none' | string[];
|
|
43
|
+
}
|
|
44
|
+
export interface OrchestratorConfig {
|
|
45
|
+
baseUrl: string;
|
|
46
|
+
projectId: string;
|
|
47
|
+
apiKey?: string;
|
|
48
|
+
timeoutMs: number;
|
|
49
|
+
pauseMs: number;
|
|
50
|
+
maxRetries: number;
|
|
51
|
+
claudeArgs: string[];
|
|
52
|
+
dryRun: boolean;
|
|
53
|
+
tag?: string;
|
|
54
|
+
}
|
|
55
|
+
export type TaskRunResult = 'done' | 'cancelled' | 'timeout' | 'error' | 'dry_run' | 'blocked';
|
|
56
|
+
export interface SprintStats {
|
|
57
|
+
done: number;
|
|
58
|
+
cancelled: number;
|
|
59
|
+
retried: number;
|
|
60
|
+
errors: number;
|
|
61
|
+
skipped: number;
|
|
62
|
+
durationMs: number;
|
|
63
|
+
}
|
|
64
|
+
export type ServerEvent = {
|
|
65
|
+
type: 'run:started';
|
|
66
|
+
payload: {
|
|
67
|
+
mode: 'sprint' | 'epic';
|
|
68
|
+
epicId?: string;
|
|
69
|
+
};
|
|
70
|
+
} | {
|
|
71
|
+
type: 'run:stopped';
|
|
72
|
+
} | {
|
|
73
|
+
type: 'run:complete';
|
|
74
|
+
payload: SprintStats;
|
|
75
|
+
} | {
|
|
76
|
+
type: 'task:started';
|
|
77
|
+
payload: {
|
|
78
|
+
task: Task;
|
|
79
|
+
};
|
|
80
|
+
} | {
|
|
81
|
+
type: 'task:done';
|
|
82
|
+
payload: {
|
|
83
|
+
task: Task;
|
|
84
|
+
};
|
|
85
|
+
} | {
|
|
86
|
+
type: 'task:cancelled';
|
|
87
|
+
payload: {
|
|
88
|
+
task: Task;
|
|
89
|
+
reason?: string;
|
|
90
|
+
};
|
|
91
|
+
} | {
|
|
92
|
+
type: 'task:timeout';
|
|
93
|
+
payload: {
|
|
94
|
+
task: Task;
|
|
95
|
+
};
|
|
96
|
+
} | {
|
|
97
|
+
type: 'task:retrying';
|
|
98
|
+
payload: {
|
|
99
|
+
task: Task;
|
|
100
|
+
attempt: number;
|
|
101
|
+
};
|
|
102
|
+
} | {
|
|
103
|
+
type: 'log:line';
|
|
104
|
+
payload: {
|
|
105
|
+
taskId: string;
|
|
106
|
+
line: string;
|
|
107
|
+
};
|
|
108
|
+
} | {
|
|
109
|
+
type: 'error';
|
|
110
|
+
payload: {
|
|
111
|
+
message: string;
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Everything the orchestrator needs from GraphMemory.
|
|
116
|
+
* Mock this in tests — never import gm-client directly in core logic.
|
|
117
|
+
*/
|
|
118
|
+
export interface GraphMemoryPort {
|
|
119
|
+
listTasks(opts?: {
|
|
120
|
+
status?: TaskStatus;
|
|
121
|
+
tag?: string;
|
|
122
|
+
limit?: number;
|
|
123
|
+
}): Promise<Task[]>;
|
|
124
|
+
getTask(taskId: string): Promise<Task>;
|
|
125
|
+
moveTask(taskId: string, status: TaskStatus): Promise<void>;
|
|
126
|
+
updateTask(taskId: string, fields: Partial<Task>): Promise<void>;
|
|
127
|
+
getEpic(epicId: string): Promise<Epic>;
|
|
128
|
+
listEpics(opts?: {
|
|
129
|
+
status?: EpicStatus;
|
|
130
|
+
limit?: number;
|
|
131
|
+
}): Promise<Epic[]>;
|
|
132
|
+
moveEpic(epicId: string, status: EpicStatus): Promise<void>;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Abstracts spawning Claude Code.
|
|
136
|
+
* Swap for a mock in tests.
|
|
137
|
+
*/
|
|
138
|
+
export interface ClaudeRunnerPort {
|
|
139
|
+
run(task: Task, config: OrchestratorConfig): Promise<void>;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Abstracts polling for task completion.
|
|
143
|
+
* Lets tests inject instant-resolve fakes.
|
|
144
|
+
*/
|
|
145
|
+
export interface TaskPollerPort {
|
|
146
|
+
waitForCompletion(taskId: string, opts: {
|
|
147
|
+
timeoutMs: number;
|
|
148
|
+
}): Promise<'done' | 'cancelled' | 'timeout'>;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,oDAAoD;AACpD,iDAAiD"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { runSprint, runEpic } from './core/orchestrator.js';
|
|
2
|
+
export { buildPrompt } from './core/prompt-builder.js';
|
|
3
|
+
export { sortByPriority, isTerminal, areBlockersResolved } from './core/task-utils.js';
|
|
4
|
+
export type { TaskStatus, TaskPriority, EpicStatus, TaskRef, Task, Epic, OrchestratorConfig, TaskRunResult, SprintStats, GraphMemoryPort, ClaudeRunnerPort, TaskPollerPort, } from './core/types.js';
|
|
5
|
+
export { GraphMemoryClient } from './infra/gm-client.js';
|
|
6
|
+
export { ClaudeRunner } from './infra/claude-runner.js';
|
|
7
|
+
export { TaskPoller } from './infra/task-poller.js';
|
|
8
|
+
export { loadConfig, validateConfig } from './infra/config.js';
|
|
9
|
+
export { consoleLogger, silentLogger } from './infra/logger.js';
|
|
10
|
+
export type { Logger } from './infra/logger.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAGvF,YAAY,EACV,UAAU,EACV,YAAY,EACZ,UAAU,EACV,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,cAAc,GACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAChE,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// ─── Public API ──────────────────────────────────────────────────────────
|
|
2
|
+
// Core orchestration
|
|
3
|
+
export { runSprint, runEpic } from './core/orchestrator.js';
|
|
4
|
+
export { buildPrompt } from './core/prompt-builder.js';
|
|
5
|
+
export { sortByPriority, isTerminal, areBlockersResolved } from './core/task-utils.js';
|
|
6
|
+
// Infrastructure
|
|
7
|
+
export { GraphMemoryClient } from './infra/gm-client.js';
|
|
8
|
+
export { ClaudeRunner } from './infra/claude-runner.js';
|
|
9
|
+
export { TaskPoller } from './infra/task-poller.js';
|
|
10
|
+
export { loadConfig, validateConfig } from './infra/config.js';
|
|
11
|
+
export { consoleLogger, silentLogger } from './infra/logger.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,qBAAqB;AACrB,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAkBvF,iBAAiB;AACjB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ClaudeRunnerPort, Task, OrchestratorConfig } from '../core/types.js';
|
|
2
|
+
export declare class ClaudeRunner implements ClaudeRunnerPort {
|
|
3
|
+
/**
|
|
4
|
+
* Spawns `claude --print <prompt>` as a child process.
|
|
5
|
+
* Streams stdout/stderr to the parent terminal.
|
|
6
|
+
* Resolves when the process exits (for any reason).
|
|
7
|
+
*
|
|
8
|
+
* Note: the orchestrator does NOT rely on process exit for completion
|
|
9
|
+
* detection — it polls GraphMemory task status instead. The session
|
|
10
|
+
* promise is awaited only for cleanup after the poller signals done.
|
|
11
|
+
*/
|
|
12
|
+
run(task: Task, config: OrchestratorConfig): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=claude-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-runner.d.ts","sourceRoot":"","sources":["../../src/infra/claude-runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGnF,qBAAa,YAAa,YAAW,gBAAgB;IACnD;;;;;;;;OAQG;IACG,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CA+BjE"}
|