sessioncast-cli 2.0.0 → 2.0.2

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 (34) hide show
  1. package/dist/agent/session-handler.d.ts +2 -1
  2. package/dist/agent/session-handler.js +79 -32
  3. package/dist/agent/tmux-executor.d.ts +33 -3
  4. package/dist/agent/tmux-executor.js +50 -3
  5. package/dist/agent/tmux.d.ts +6 -2
  6. package/dist/agent/tmux.js +9 -2
  7. package/dist/agent/types.d.ts +10 -0
  8. package/dist/agent/websocket.d.ts +21 -2
  9. package/dist/agent/websocket.js +46 -10
  10. package/dist/autopilot/index.d.ts +94 -0
  11. package/dist/autopilot/index.js +322 -0
  12. package/dist/autopilot/mission-analyzer.d.ts +27 -0
  13. package/dist/autopilot/mission-analyzer.js +232 -0
  14. package/dist/autopilot/project-detector.d.ts +12 -0
  15. package/dist/autopilot/project-detector.js +326 -0
  16. package/dist/autopilot/source-scanner.d.ts +26 -0
  17. package/dist/autopilot/source-scanner.js +285 -0
  18. package/dist/autopilot/speckit-generator.d.ts +60 -0
  19. package/dist/autopilot/speckit-generator.js +511 -0
  20. package/dist/autopilot/types.d.ts +110 -0
  21. package/dist/autopilot/types.js +6 -0
  22. package/dist/autopilot/workflow-generator.d.ts +33 -0
  23. package/dist/autopilot/workflow-generator.js +278 -0
  24. package/dist/project/executor.d.ts +73 -0
  25. package/dist/project/executor.js +437 -0
  26. package/dist/project/index.d.ts +4 -0
  27. package/dist/project/index.js +20 -0
  28. package/dist/project/manager.d.ts +66 -0
  29. package/dist/project/manager.js +290 -0
  30. package/dist/project/relay-client.d.ts +37 -0
  31. package/dist/project/relay-client.js +204 -0
  32. package/dist/project/types.d.ts +48 -0
  33. package/dist/project/types.js +3 -0
  34. package/package.json +1 -1
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ /**
3
+ * WorkflowGenerator - Convert mission analysis into executable workflow
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.generateWorkflow = generateWorkflow;
40
+ exports.toExecutableWorkflow = toExecutableWorkflow;
41
+ exports.createQuickWorkflow = createQuickWorkflow;
42
+ const path = __importStar(require("path"));
43
+ /**
44
+ * Generate workflow from mission analysis
45
+ */
46
+ function generateWorkflow(analysis, context) {
47
+ // Generate unique workflow name
48
+ const timestamp = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14);
49
+ const workflowName = `autopilot-${timestamp}`;
50
+ // Determine required agents based on steps
51
+ const agents = createAgents(analysis.steps, context);
52
+ // Create workflow steps with proper IDs and dependencies
53
+ const steps = createSteps(analysis.steps, agents);
54
+ return {
55
+ name: workflowName,
56
+ mission: analysis.mission,
57
+ agents,
58
+ steps
59
+ };
60
+ }
61
+ /**
62
+ * Create agent configurations based on step types
63
+ */
64
+ function createAgents(steps, context) {
65
+ const agentTypes = new Set();
66
+ for (const step of steps) {
67
+ agentTypes.add(step.type);
68
+ }
69
+ const agents = [];
70
+ for (const type of agentTypes) {
71
+ const agentId = `agent-${type}`;
72
+ const workDir = getWorkDirForType(type, context);
73
+ agents.push({
74
+ id: agentId,
75
+ name: getAgentName(type, context.projectType),
76
+ role: getAgentRole(type),
77
+ workingDir: workDir
78
+ });
79
+ }
80
+ // If only one agent, use a generic name
81
+ if (agents.length === 1) {
82
+ agents[0].name = `${context.projectName} Developer`;
83
+ agents[0].id = 'agent-main';
84
+ }
85
+ return agents;
86
+ }
87
+ /**
88
+ * Get working directory for agent type
89
+ */
90
+ function getWorkDirForType(type, context) {
91
+ const { workingDir, projectType } = context;
92
+ switch (type) {
93
+ case 'frontend':
94
+ // React/Vue/Next projects might have frontend in root or src
95
+ if (['react', 'next', 'vue'].includes(projectType)) {
96
+ return workingDir;
97
+ }
98
+ // Full-stack projects might have separate frontend dir
99
+ return path.join(workingDir, 'frontend');
100
+ case 'backend':
101
+ if (['spring', 'go', 'rust', 'python', 'node'].includes(projectType)) {
102
+ return workingDir;
103
+ }
104
+ return path.join(workingDir, 'backend');
105
+ case 'mobile':
106
+ if (projectType === 'android') {
107
+ return path.join(workingDir, 'app');
108
+ }
109
+ if (projectType === 'ios') {
110
+ return workingDir;
111
+ }
112
+ return workingDir;
113
+ case 'infra':
114
+ return workingDir;
115
+ case 'test':
116
+ return workingDir;
117
+ case 'fullstack':
118
+ default:
119
+ return workingDir;
120
+ }
121
+ }
122
+ /**
123
+ * Get agent display name
124
+ */
125
+ function getAgentName(type, projectType) {
126
+ const typeNames = {
127
+ frontend: 'Frontend Developer',
128
+ backend: 'Backend Developer',
129
+ fullstack: 'Full-Stack Developer',
130
+ mobile: getMobileAgentName(projectType),
131
+ infra: 'DevOps Engineer',
132
+ test: 'QA Engineer'
133
+ };
134
+ return typeNames[type];
135
+ }
136
+ /**
137
+ * Get mobile agent name based on platform
138
+ */
139
+ function getMobileAgentName(projectType) {
140
+ if (projectType === 'android')
141
+ return 'Android Developer';
142
+ if (projectType === 'ios')
143
+ return 'iOS Developer';
144
+ return 'Mobile Developer';
145
+ }
146
+ /**
147
+ * Get agent role description
148
+ */
149
+ function getAgentRole(type) {
150
+ const roles = {
151
+ frontend: 'Implements UI components and client-side logic',
152
+ backend: 'Implements server-side logic and APIs',
153
+ fullstack: 'Handles both frontend and backend development',
154
+ mobile: 'Develops mobile application features',
155
+ infra: 'Manages infrastructure and deployment',
156
+ test: 'Creates and runs tests'
157
+ };
158
+ return roles[type];
159
+ }
160
+ /**
161
+ * Create workflow steps from analyzed steps
162
+ */
163
+ function createSteps(analyzedSteps, agents) {
164
+ const steps = [];
165
+ const stepIdMap = new Map();
166
+ // First pass: create steps and generate IDs
167
+ for (let i = 0; i < analyzedSteps.length; i++) {
168
+ const analyzed = analyzedSteps[i];
169
+ const stepId = `step-${i + 1}`;
170
+ stepIdMap.set(analyzed.name, stepId);
171
+ // Find the agent for this step type
172
+ const agent = findAgentForType(analyzed.type, agents);
173
+ steps.push({
174
+ id: stepId,
175
+ name: analyzed.name,
176
+ description: analyzed.description,
177
+ agentId: agent.id,
178
+ prompt: buildAgentPrompt(analyzed),
179
+ status: 'pending'
180
+ });
181
+ }
182
+ // Second pass: resolve dependencies
183
+ for (let i = 0; i < analyzedSteps.length; i++) {
184
+ const analyzed = analyzedSteps[i];
185
+ if (analyzed.dependsOn && analyzed.dependsOn.length > 0) {
186
+ steps[i].dependsOn = analyzed.dependsOn
187
+ .map(name => stepIdMap.get(name))
188
+ .filter((id) => id !== undefined);
189
+ }
190
+ }
191
+ return steps;
192
+ }
193
+ /**
194
+ * Find the appropriate agent for a step type
195
+ */
196
+ function findAgentForType(type, agents) {
197
+ // First try exact match
198
+ const exact = agents.find(a => a.id === `agent-${type}`);
199
+ if (exact)
200
+ return exact;
201
+ // If only one agent, use it
202
+ if (agents.length === 1)
203
+ return agents[0];
204
+ // Fallback to fullstack or first available
205
+ const fullstack = agents.find(a => a.id === 'agent-fullstack');
206
+ return fullstack || agents[0];
207
+ }
208
+ /**
209
+ * Build detailed prompt for agent execution
210
+ */
211
+ function buildAgentPrompt(step) {
212
+ let prompt = step.prompt;
213
+ // Add context if not already present
214
+ if (!prompt.toLowerCase().includes('step') && !prompt.toLowerCase().includes('task')) {
215
+ prompt = `Task: ${step.name}\n\n${step.description}\n\nDetails:\n${step.prompt}`;
216
+ }
217
+ return prompt;
218
+ }
219
+ /**
220
+ * Convert GeneratedWorkflow to existing Workflow format
221
+ */
222
+ function toExecutableWorkflow(generated) {
223
+ // Group steps by agent
224
+ const agentTasks = new Map();
225
+ const agentDeps = new Map();
226
+ for (const step of generated.steps) {
227
+ const tasks = agentTasks.get(step.agentId) || [];
228
+ tasks.push(step.prompt);
229
+ agentTasks.set(step.agentId, tasks);
230
+ // Collect dependencies (other agents this agent depends on)
231
+ if (step.dependsOn) {
232
+ const deps = agentDeps.get(step.agentId) || new Set();
233
+ for (const depStepId of step.dependsOn) {
234
+ const depStep = generated.steps.find(s => s.id === depStepId);
235
+ if (depStep && depStep.agentId !== step.agentId) {
236
+ deps.add(depStep.agentId);
237
+ }
238
+ }
239
+ agentDeps.set(step.agentId, deps);
240
+ }
241
+ }
242
+ return {
243
+ name: generated.name,
244
+ mission: generated.mission,
245
+ created: new Date().toISOString(),
246
+ agents: generated.agents.map(agent => ({
247
+ id: agent.id,
248
+ name: agent.name,
249
+ workDir: agent.workingDir,
250
+ tasks: agentTasks.get(agent.id) || [],
251
+ dependsOn: Array.from(agentDeps.get(agent.id) || [])
252
+ }))
253
+ };
254
+ }
255
+ /**
256
+ * Create a simple single-agent workflow for quick execution
257
+ */
258
+ function createQuickWorkflow(prompt, context) {
259
+ const timestamp = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14);
260
+ return {
261
+ name: `quick-${timestamp}`,
262
+ mission: prompt,
263
+ agents: [{
264
+ id: 'agent-main',
265
+ name: `${context.projectName} Developer`,
266
+ role: 'Full-stack developer for this project',
267
+ workingDir: context.workingDir
268
+ }],
269
+ steps: [{
270
+ id: 'step-1',
271
+ name: 'Execute task',
272
+ description: prompt,
273
+ agentId: 'agent-main',
274
+ prompt: prompt,
275
+ status: 'pending'
276
+ }]
277
+ };
278
+ }
@@ -0,0 +1,73 @@
1
+ import { EventEmitter } from 'events';
2
+ import { ProjectManager } from './manager';
3
+ export interface ExecutorOptions {
4
+ autoLaunchClaude?: boolean;
5
+ claudeCommand?: string;
6
+ relayUrl?: string;
7
+ relayToken?: string;
8
+ }
9
+ export declare class WorkflowExecutor extends EventEmitter {
10
+ private manager;
11
+ private workflow;
12
+ private running;
13
+ private pollTimer;
14
+ private options;
15
+ private relayClient;
16
+ constructor(manager: ProjectManager, options?: ExecutorOptions);
17
+ /**
18
+ * Start workflow execution
19
+ */
20
+ start(): Promise<void>;
21
+ /**
22
+ * Connect to relay server and register project
23
+ */
24
+ private connectToRelay;
25
+ /**
26
+ * Update relay with current agents list
27
+ */
28
+ private updateRelayAgents;
29
+ /**
30
+ * Start PM Agent tmux session
31
+ */
32
+ private startPMAgent;
33
+ /**
34
+ * Start a work agent
35
+ */
36
+ private startAgent;
37
+ /**
38
+ * Build task prompt for agent
39
+ */
40
+ private buildTaskPrompt;
41
+ /**
42
+ * Launch Claude Code CLI in a tmux session
43
+ */
44
+ private launchClaudeInSession;
45
+ /**
46
+ * Sleep helper
47
+ */
48
+ private sleep;
49
+ /**
50
+ * Main execution loop
51
+ */
52
+ private runExecutionLoop;
53
+ /**
54
+ * Stop workflow execution
55
+ */
56
+ stop(): void;
57
+ /**
58
+ * Kill all project tmux sessions
59
+ */
60
+ killAllSessions(): void;
61
+ /**
62
+ * Send keys to an agent session
63
+ */
64
+ sendToAgent(agentId: string, keys: string): boolean;
65
+ /**
66
+ * Capture agent terminal output
67
+ */
68
+ captureAgent(agentId: string): string | null;
69
+ /**
70
+ * List all agent sessions for this project
71
+ */
72
+ listSessions(): string[];
73
+ }