sessioncast-cli 2.0.2 → 2.0.3
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/dist/agent/runner.js +23 -0
- package/dist/agent/session-handler.d.ts +1 -2
- package/dist/agent/session-handler.js +34 -79
- package/dist/agent/tmux-executor.d.ts +3 -33
- package/dist/agent/tmux-executor.js +3 -50
- package/dist/agent/tmux.d.ts +2 -6
- package/dist/agent/tmux.js +2 -9
- package/dist/agent/types.d.ts +0 -10
- package/dist/agent/websocket.d.ts +2 -21
- package/dist/agent/websocket.js +10 -46
- package/dist/commands/agent.js +3 -0
- package/dist/index.js +14 -0
- package/dist/sentry.d.ts +4 -0
- package/dist/sentry.js +87 -0
- package/package.json +2 -1
- package/dist/autopilot/index.d.ts +0 -94
- package/dist/autopilot/index.js +0 -322
- package/dist/autopilot/mission-analyzer.d.ts +0 -27
- package/dist/autopilot/mission-analyzer.js +0 -232
- package/dist/autopilot/project-detector.d.ts +0 -12
- package/dist/autopilot/project-detector.js +0 -326
- package/dist/autopilot/source-scanner.d.ts +0 -26
- package/dist/autopilot/source-scanner.js +0 -285
- package/dist/autopilot/speckit-generator.d.ts +0 -60
- package/dist/autopilot/speckit-generator.js +0 -511
- package/dist/autopilot/types.d.ts +0 -110
- package/dist/autopilot/types.js +0 -6
- package/dist/autopilot/workflow-generator.d.ts +0 -33
- package/dist/autopilot/workflow-generator.js +0 -278
- package/dist/commands/autopilot.d.ts +0 -30
- package/dist/commands/autopilot.js +0 -262
- package/dist/commands/project.d.ts +0 -33
- package/dist/commands/project.js +0 -350
- package/dist/project/executor.d.ts +0 -73
- package/dist/project/executor.js +0 -437
- package/dist/project/index.d.ts +0 -4
- package/dist/project/index.js +0 -20
- package/dist/project/manager.d.ts +0 -66
- package/dist/project/manager.js +0 -290
- package/dist/project/relay-client.d.ts +0 -37
- package/dist/project/relay-client.js +0 -204
- package/dist/project/types.d.ts +0 -48
- package/dist/project/types.js +0 -3
- package/dist/utils/fileUtils.d.ts +0 -28
- package/dist/utils/fileUtils.js +0 -159
package/dist/project/executor.js
DELETED
|
@@ -1,437 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.WorkflowExecutor = void 0;
|
|
37
|
-
const child_process_1 = require("child_process");
|
|
38
|
-
const path = __importStar(require("path"));
|
|
39
|
-
const events_1 = require("events");
|
|
40
|
-
const relay_client_1 = require("./relay-client");
|
|
41
|
-
const POLL_INTERVAL_MS = 2000;
|
|
42
|
-
const MAX_RETRIES = 3;
|
|
43
|
-
const CLAUDE_START_DELAY_MS = 1000;
|
|
44
|
-
class WorkflowExecutor extends events_1.EventEmitter {
|
|
45
|
-
constructor(manager, options = {}) {
|
|
46
|
-
super();
|
|
47
|
-
this.workflow = null;
|
|
48
|
-
this.running = false;
|
|
49
|
-
this.pollTimer = null;
|
|
50
|
-
this.relayClient = null;
|
|
51
|
-
this.manager = manager;
|
|
52
|
-
this.options = {
|
|
53
|
-
autoLaunchClaude: options.autoLaunchClaude ?? true,
|
|
54
|
-
claudeCommand: options.claudeCommand ?? 'claude',
|
|
55
|
-
relayUrl: options.relayUrl,
|
|
56
|
-
relayToken: options.relayToken
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Start workflow execution
|
|
61
|
-
*/
|
|
62
|
-
async start() {
|
|
63
|
-
this.workflow = this.manager.loadWorkflow();
|
|
64
|
-
if (!this.workflow) {
|
|
65
|
-
throw new Error('No workflow found. Run project init first.');
|
|
66
|
-
}
|
|
67
|
-
this.running = true;
|
|
68
|
-
console.log(`Starting workflow: ${this.workflow.name}`);
|
|
69
|
-
// Connect to relay if configured
|
|
70
|
-
if (this.options.relayUrl && this.options.relayToken) {
|
|
71
|
-
await this.connectToRelay();
|
|
72
|
-
}
|
|
73
|
-
// Initialize status
|
|
74
|
-
const status = {
|
|
75
|
-
workflow: this.workflow.name,
|
|
76
|
-
startedAt: new Date().toISOString(),
|
|
77
|
-
status: 'running',
|
|
78
|
-
agents: {}
|
|
79
|
-
};
|
|
80
|
-
for (const agent of this.workflow.agents) {
|
|
81
|
-
status.agents[agent.id] = { status: 'pending' };
|
|
82
|
-
}
|
|
83
|
-
this.manager.saveStatus(status);
|
|
84
|
-
// Update relay with initial agents list
|
|
85
|
-
this.updateRelayAgents();
|
|
86
|
-
// Start PM Agent first
|
|
87
|
-
await this.startPMAgent();
|
|
88
|
-
// Then start the workflow execution loop
|
|
89
|
-
this.runExecutionLoop();
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Connect to relay server and register project
|
|
93
|
-
*/
|
|
94
|
-
async connectToRelay() {
|
|
95
|
-
if (!this.options.relayUrl || !this.options.relayToken) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const project = this.manager.load();
|
|
99
|
-
this.relayClient = new relay_client_1.ProjectRelayClient({
|
|
100
|
-
relayUrl: this.options.relayUrl,
|
|
101
|
-
token: this.options.relayToken,
|
|
102
|
-
projectId: this.manager.getProjectId(),
|
|
103
|
-
projectName: project?.name || this.manager.getProjectId(),
|
|
104
|
-
projectPath: this.manager.getProjectPath()
|
|
105
|
-
});
|
|
106
|
-
// Setup event handlers
|
|
107
|
-
this.relayClient.on('connected', () => {
|
|
108
|
-
console.log('[Relay] Connected and project registered');
|
|
109
|
-
this.relayClient?.updateStatus('running');
|
|
110
|
-
});
|
|
111
|
-
this.relayClient.on('addSource', (meta) => {
|
|
112
|
-
console.log('[Relay] Add source request:', meta);
|
|
113
|
-
this.emit('addSourceRequest', meta);
|
|
114
|
-
});
|
|
115
|
-
this.relayClient.on('analyzeMission', (meta) => {
|
|
116
|
-
console.log('[Relay] Analyze mission request:', meta);
|
|
117
|
-
this.emit('analyzeMissionRequest', meta);
|
|
118
|
-
});
|
|
119
|
-
this.relayClient.on('startWorkflow', (meta) => {
|
|
120
|
-
console.log('[Relay] Start workflow request:', meta);
|
|
121
|
-
this.emit('startWorkflowRequest', meta);
|
|
122
|
-
});
|
|
123
|
-
this.relayClient.on('error', (error) => {
|
|
124
|
-
console.error('[Relay] Error:', error.message);
|
|
125
|
-
});
|
|
126
|
-
this.relayClient.connect();
|
|
127
|
-
// Wait a bit for connection
|
|
128
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Update relay with current agents list
|
|
132
|
-
*/
|
|
133
|
-
updateRelayAgents() {
|
|
134
|
-
if (!this.relayClient || !this.workflow)
|
|
135
|
-
return;
|
|
136
|
-
const status = this.manager.loadStatus();
|
|
137
|
-
const agents = this.workflow.agents.map(agent => ({
|
|
138
|
-
id: agent.id,
|
|
139
|
-
name: agent.name,
|
|
140
|
-
status: status?.agents[agent.id]?.status || 'pending'
|
|
141
|
-
}));
|
|
142
|
-
// Add PM agent
|
|
143
|
-
agents.unshift({
|
|
144
|
-
id: 'pm',
|
|
145
|
-
name: 'PM',
|
|
146
|
-
status: status?.agents['pm']?.status || 'pending'
|
|
147
|
-
});
|
|
148
|
-
this.relayClient.updateAgents(agents);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Start PM Agent tmux session
|
|
152
|
-
*/
|
|
153
|
-
async startPMAgent() {
|
|
154
|
-
const sessionName = this.manager.getTmuxSessionName('pm');
|
|
155
|
-
const pmAgentPath = path.join(this.manager.getProjectPath(), 'tools', 'pm-agent');
|
|
156
|
-
console.log(`Starting PM Agent: ${sessionName}`);
|
|
157
|
-
try {
|
|
158
|
-
// Check if session already exists
|
|
159
|
-
try {
|
|
160
|
-
(0, child_process_1.execSync)(`tmux has-session -t "${sessionName}" 2>/dev/null`);
|
|
161
|
-
console.log(`PM Agent session already exists: ${sessionName}`);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
// Session doesn't exist, create it
|
|
166
|
-
}
|
|
167
|
-
// Create new tmux session
|
|
168
|
-
(0, child_process_1.execSync)(`tmux new-session -d -s "${sessionName}" -c "${pmAgentPath}"`, { stdio: 'pipe' });
|
|
169
|
-
console.log(`Created PM Agent session: ${sessionName}`);
|
|
170
|
-
// Auto-launch Claude Code CLI
|
|
171
|
-
if (this.options.autoLaunchClaude) {
|
|
172
|
-
await this.launchClaudeInSession(sessionName, 'pm');
|
|
173
|
-
}
|
|
174
|
-
// Update status
|
|
175
|
-
this.manager.updateAgentStatus('pm', {
|
|
176
|
-
status: 'running',
|
|
177
|
-
startedAt: new Date().toISOString()
|
|
178
|
-
});
|
|
179
|
-
this.emit('agent-started', { agentId: 'pm', sessionName });
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
console.error('Failed to start PM Agent:', error);
|
|
183
|
-
throw error;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Start a work agent
|
|
188
|
-
*/
|
|
189
|
-
async startAgent(agent) {
|
|
190
|
-
const sessionName = this.manager.getTmuxSessionName(agent.id);
|
|
191
|
-
const agentPath = path.join(this.manager.getProjectPath(), agent.workDir);
|
|
192
|
-
console.log(`Starting agent: ${agent.id} (${agent.name})`);
|
|
193
|
-
try {
|
|
194
|
-
// Check if session already exists
|
|
195
|
-
try {
|
|
196
|
-
(0, child_process_1.execSync)(`tmux has-session -t "${sessionName}" 2>/dev/null`);
|
|
197
|
-
console.log(`Agent session already exists: ${sessionName}`);
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
catch {
|
|
201
|
-
// Session doesn't exist, create it
|
|
202
|
-
}
|
|
203
|
-
// Ensure work folder exists with CLAUDE.md
|
|
204
|
-
this.manager.createWorkAgent(agent.id, agent.name, agent.tasks);
|
|
205
|
-
// Create new tmux session
|
|
206
|
-
(0, child_process_1.execSync)(`tmux new-session -d -s "${sessionName}" -c "${agentPath}"`, { stdio: 'pipe' });
|
|
207
|
-
console.log(`Created agent session: ${sessionName}`);
|
|
208
|
-
// Auto-launch Claude Code CLI with task prompt
|
|
209
|
-
if (this.options.autoLaunchClaude) {
|
|
210
|
-
const taskPrompt = this.buildTaskPrompt(agent);
|
|
211
|
-
await this.launchClaudeInSession(sessionName, agent.id, taskPrompt);
|
|
212
|
-
}
|
|
213
|
-
// Update status
|
|
214
|
-
this.manager.updateAgentStatus(agent.id, {
|
|
215
|
-
status: 'running',
|
|
216
|
-
startedAt: new Date().toISOString(),
|
|
217
|
-
currentTask: agent.tasks[0] || 'Starting...'
|
|
218
|
-
});
|
|
219
|
-
this.emit('agent-started', { agentId: agent.id, sessionName });
|
|
220
|
-
}
|
|
221
|
-
catch (error) {
|
|
222
|
-
console.error(`Failed to start agent ${agent.id}:`, error);
|
|
223
|
-
this.manager.updateAgentStatus(agent.id, {
|
|
224
|
-
status: 'failed',
|
|
225
|
-
error: String(error)
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Build task prompt for agent
|
|
231
|
-
*/
|
|
232
|
-
buildTaskPrompt(agent) {
|
|
233
|
-
const tasks = agent.tasks.map((t, i) => `${i + 1}. ${t}`).join('\n');
|
|
234
|
-
return `다음 태스크를 수행해주세요:\n${tasks}\n\n완료 후 반드시:\n1. output.md에 결과 기록\n2. touch DONE 실행`;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Launch Claude Code CLI in a tmux session
|
|
238
|
-
*/
|
|
239
|
-
async launchClaudeInSession(sessionName, agentId, initialPrompt) {
|
|
240
|
-
// Wait for shell to be ready
|
|
241
|
-
await this.sleep(CLAUDE_START_DELAY_MS);
|
|
242
|
-
try {
|
|
243
|
-
// Send claude command
|
|
244
|
-
(0, child_process_1.execSync)(`tmux send-keys -t "${sessionName}" "${this.options.claudeCommand}" Enter`, {
|
|
245
|
-
stdio: 'pipe'
|
|
246
|
-
});
|
|
247
|
-
console.log(`Launched Claude Code in ${agentId}`);
|
|
248
|
-
// If there's an initial prompt, send it after claude starts
|
|
249
|
-
if (initialPrompt) {
|
|
250
|
-
// Wait for claude to initialize
|
|
251
|
-
await this.sleep(3000);
|
|
252
|
-
// Send the initial prompt
|
|
253
|
-
const escapedPrompt = initialPrompt.replace(/"/g, '\\"').replace(/\n/g, '\\n');
|
|
254
|
-
(0, child_process_1.execSync)(`tmux send-keys -t "${sessionName}" "${escapedPrompt}" Enter`, {
|
|
255
|
-
stdio: 'pipe'
|
|
256
|
-
});
|
|
257
|
-
console.log(`Sent initial prompt to ${agentId}`);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
catch (error) {
|
|
261
|
-
console.error(`Failed to launch Claude in ${agentId}:`, error);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Sleep helper
|
|
266
|
-
*/
|
|
267
|
-
sleep(ms) {
|
|
268
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Main execution loop
|
|
272
|
-
*/
|
|
273
|
-
runExecutionLoop() {
|
|
274
|
-
const check = () => {
|
|
275
|
-
if (!this.running || !this.workflow) {
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
const status = this.manager.loadStatus();
|
|
279
|
-
if (!status)
|
|
280
|
-
return;
|
|
281
|
-
// Check each agent
|
|
282
|
-
for (const agent of this.workflow.agents) {
|
|
283
|
-
const agentStatus = status.agents[agent.id];
|
|
284
|
-
// Skip completed or failed agents
|
|
285
|
-
if (agentStatus?.status === 'completed' || agentStatus?.status === 'failed') {
|
|
286
|
-
continue;
|
|
287
|
-
}
|
|
288
|
-
// Check if dependencies are met
|
|
289
|
-
const dependenciesMet = agent.dependsOn.every(depId => {
|
|
290
|
-
return status.agents[depId]?.status === 'completed';
|
|
291
|
-
});
|
|
292
|
-
if (!dependenciesMet) {
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
|
-
// Check if agent is pending (not started yet)
|
|
296
|
-
if (agentStatus?.status === 'pending') {
|
|
297
|
-
this.startAgent(agent);
|
|
298
|
-
continue;
|
|
299
|
-
}
|
|
300
|
-
// Check if running agent is completed
|
|
301
|
-
if (agentStatus?.status === 'running') {
|
|
302
|
-
if (this.manager.isAgentCompleted(agent.id)) {
|
|
303
|
-
const output = this.manager.getAgentOutput(agent.id);
|
|
304
|
-
this.manager.updateAgentStatus(agent.id, {
|
|
305
|
-
status: 'completed',
|
|
306
|
-
completedAt: new Date().toISOString(),
|
|
307
|
-
output: output || undefined
|
|
308
|
-
});
|
|
309
|
-
// Append output to shared context
|
|
310
|
-
if (output) {
|
|
311
|
-
this.manager.appendToContext(`\n## ${agent.name} Output\n${output}\n`);
|
|
312
|
-
}
|
|
313
|
-
console.log(`Agent completed: ${agent.id}`);
|
|
314
|
-
this.emit('agent-completed', { agentId: agent.id, output });
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
// Check if workflow is complete
|
|
319
|
-
const updatedStatus = this.manager.loadStatus();
|
|
320
|
-
if (updatedStatus) {
|
|
321
|
-
const allCompleted = this.workflow.agents.every(a => updatedStatus.agents[a.id]?.status === 'completed');
|
|
322
|
-
if (allCompleted) {
|
|
323
|
-
console.log('Workflow completed!');
|
|
324
|
-
updatedStatus.status = 'completed';
|
|
325
|
-
this.manager.saveStatus(updatedStatus);
|
|
326
|
-
this.emit('workflow-completed', updatedStatus);
|
|
327
|
-
this.stop();
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
const anyFailed = this.workflow.agents.some(a => updatedStatus.agents[a.id]?.status === 'failed');
|
|
331
|
-
if (anyFailed) {
|
|
332
|
-
console.log('Workflow failed!');
|
|
333
|
-
updatedStatus.status = 'failed';
|
|
334
|
-
this.manager.saveStatus(updatedStatus);
|
|
335
|
-
this.emit('workflow-failed', updatedStatus);
|
|
336
|
-
this.stop();
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
// Continue polling
|
|
341
|
-
this.pollTimer = setTimeout(check, POLL_INTERVAL_MS);
|
|
342
|
-
};
|
|
343
|
-
check();
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Stop workflow execution
|
|
347
|
-
*/
|
|
348
|
-
stop() {
|
|
349
|
-
this.running = false;
|
|
350
|
-
if (this.pollTimer) {
|
|
351
|
-
clearTimeout(this.pollTimer);
|
|
352
|
-
this.pollTimer = null;
|
|
353
|
-
}
|
|
354
|
-
// Disconnect from relay
|
|
355
|
-
if (this.relayClient) {
|
|
356
|
-
this.relayClient.updateStatus('completed');
|
|
357
|
-
this.relayClient.destroy();
|
|
358
|
-
this.relayClient = null;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* Kill all project tmux sessions
|
|
363
|
-
*/
|
|
364
|
-
killAllSessions() {
|
|
365
|
-
const projectId = this.manager.getProjectId().replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
366
|
-
const prefix = `proj_${projectId}_`;
|
|
367
|
-
try {
|
|
368
|
-
const sessions = (0, child_process_1.execSync)(`tmux ls -F "#{session_name}" 2>/dev/null || true`, {
|
|
369
|
-
encoding: 'utf-8'
|
|
370
|
-
});
|
|
371
|
-
for (const session of sessions.split('\n')) {
|
|
372
|
-
if (session.startsWith(prefix)) {
|
|
373
|
-
try {
|
|
374
|
-
(0, child_process_1.execSync)(`tmux kill-session -t "${session}"`, { stdio: 'pipe' });
|
|
375
|
-
console.log(`Killed session: ${session}`);
|
|
376
|
-
}
|
|
377
|
-
catch {
|
|
378
|
-
// Ignore errors
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
catch {
|
|
384
|
-
// Ignore errors
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Send keys to an agent session
|
|
389
|
-
*/
|
|
390
|
-
sendToAgent(agentId, keys) {
|
|
391
|
-
const sessionName = this.manager.getTmuxSessionName(agentId);
|
|
392
|
-
try {
|
|
393
|
-
(0, child_process_1.execSync)(`tmux send-keys -t "${sessionName}" "${keys.replace(/"/g, '\\"')}" Enter`, {
|
|
394
|
-
stdio: 'pipe'
|
|
395
|
-
});
|
|
396
|
-
return true;
|
|
397
|
-
}
|
|
398
|
-
catch {
|
|
399
|
-
return false;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Capture agent terminal output
|
|
404
|
-
*/
|
|
405
|
-
captureAgent(agentId) {
|
|
406
|
-
const sessionName = this.manager.getTmuxSessionName(agentId);
|
|
407
|
-
try {
|
|
408
|
-
return (0, child_process_1.execSync)(`tmux capture-pane -t "${sessionName}" -p -e`, {
|
|
409
|
-
encoding: 'utf-8',
|
|
410
|
-
stdio: ['pipe', 'pipe', 'pipe']
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
catch {
|
|
414
|
-
return null;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* List all agent sessions for this project
|
|
419
|
-
*/
|
|
420
|
-
listSessions() {
|
|
421
|
-
const projectId = this.manager.getProjectId().replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
422
|
-
const prefix = `proj_${projectId}_`;
|
|
423
|
-
try {
|
|
424
|
-
const sessions = (0, child_process_1.execSync)(`tmux ls -F "#{session_name}" 2>/dev/null || true`, {
|
|
425
|
-
encoding: 'utf-8'
|
|
426
|
-
});
|
|
427
|
-
return sessions
|
|
428
|
-
.split('\n')
|
|
429
|
-
.filter(s => s.startsWith(prefix))
|
|
430
|
-
.map(s => s.substring(prefix.length));
|
|
431
|
-
}
|
|
432
|
-
catch {
|
|
433
|
-
return [];
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
exports.WorkflowExecutor = WorkflowExecutor;
|
package/dist/project/index.d.ts
DELETED
package/dist/project/index.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./types"), exports);
|
|
18
|
-
__exportStar(require("./manager"), exports);
|
|
19
|
-
__exportStar(require("./executor"), exports);
|
|
20
|
-
__exportStar(require("./relay-client"), exports);
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Project, Workflow, WorkflowStatus, ProjectConfig, AgentStatus } from './types';
|
|
2
|
-
export declare class ProjectManager {
|
|
3
|
-
private projectPath;
|
|
4
|
-
private config;
|
|
5
|
-
constructor(projectPath: string, config?: Partial<ProjectConfig>);
|
|
6
|
-
/**
|
|
7
|
-
* Initialize a new project with folder structure
|
|
8
|
-
*/
|
|
9
|
-
init(projectName?: string): Project;
|
|
10
|
-
private copyTemplateClaude;
|
|
11
|
-
private createInitialFiles;
|
|
12
|
-
private saveProjectConfig;
|
|
13
|
-
/**
|
|
14
|
-
* Load existing project
|
|
15
|
-
*/
|
|
16
|
-
load(): Project | null;
|
|
17
|
-
/**
|
|
18
|
-
* Load workflow definition
|
|
19
|
-
*/
|
|
20
|
-
loadWorkflow(): Workflow | null;
|
|
21
|
-
/**
|
|
22
|
-
* Save workflow definition
|
|
23
|
-
*/
|
|
24
|
-
saveWorkflow(workflow: Workflow): void;
|
|
25
|
-
/**
|
|
26
|
-
* Load workflow status
|
|
27
|
-
*/
|
|
28
|
-
loadStatus(): WorkflowStatus | null;
|
|
29
|
-
/**
|
|
30
|
-
* Save workflow status
|
|
31
|
-
*/
|
|
32
|
-
saveStatus(status: WorkflowStatus): void;
|
|
33
|
-
/**
|
|
34
|
-
* Update agent status
|
|
35
|
-
*/
|
|
36
|
-
updateAgentStatus(agentId: string, agentStatus: Partial<AgentStatus>): void;
|
|
37
|
-
/**
|
|
38
|
-
* Create work agent folder with CLAUDE.md
|
|
39
|
-
*/
|
|
40
|
-
createWorkAgent(agentId: string, agentName: string, tasks: string[]): void;
|
|
41
|
-
/**
|
|
42
|
-
* Get tmux session name for an agent
|
|
43
|
-
* Note: tmux doesn't allow colons in session names, so we use underscores
|
|
44
|
-
*/
|
|
45
|
-
getTmuxSessionName(agentId: string): string;
|
|
46
|
-
/**
|
|
47
|
-
* Check if agent is completed (DONE file exists)
|
|
48
|
-
*/
|
|
49
|
-
isAgentCompleted(agentId: string): boolean;
|
|
50
|
-
/**
|
|
51
|
-
* Get agent output
|
|
52
|
-
*/
|
|
53
|
-
getAgentOutput(agentId: string): string | null;
|
|
54
|
-
/**
|
|
55
|
-
* Append to shared context
|
|
56
|
-
*/
|
|
57
|
-
appendToContext(content: string): void;
|
|
58
|
-
/**
|
|
59
|
-
* Get project path
|
|
60
|
-
*/
|
|
61
|
-
getProjectPath(): string;
|
|
62
|
-
/**
|
|
63
|
-
* Get project ID
|
|
64
|
-
*/
|
|
65
|
-
getProjectId(): string;
|
|
66
|
-
}
|