sessioncast-cli 1.0.0 → 1.1.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 (48) hide show
  1. package/README.md +65 -40
  2. package/dist/agent/session-handler.d.ts +1 -0
  3. package/dist/agent/session-handler.js +42 -0
  4. package/dist/agent/tmux-executor.d.ts +66 -0
  5. package/dist/agent/tmux-executor.js +368 -0
  6. package/dist/agent/tmux.d.ts +9 -1
  7. package/dist/agent/tmux.js +52 -76
  8. package/dist/agent/websocket.d.ts +2 -8
  9. package/dist/agent/websocket.js +78 -14
  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/commands/autopilot.d.ts +30 -0
  25. package/dist/commands/autopilot.js +262 -0
  26. package/dist/commands/login.d.ts +2 -1
  27. package/dist/commands/login.js +199 -8
  28. package/dist/commands/project.d.ts +1 -1
  29. package/dist/commands/project.js +4 -13
  30. package/dist/config.d.ts +20 -0
  31. package/dist/config.js +69 -2
  32. package/dist/index.js +7 -47
  33. package/dist/project/executor.d.ts +8 -53
  34. package/dist/project/executor.js +64 -520
  35. package/dist/project/manager.d.ts +0 -13
  36. package/dist/project/manager.js +0 -107
  37. package/dist/project/relay-client.d.ts +18 -68
  38. package/dist/project/relay-client.js +134 -130
  39. package/dist/project/types.d.ts +5 -0
  40. package/dist/utils/fileUtils.d.ts +28 -0
  41. package/dist/utils/fileUtils.js +159 -0
  42. package/dist/utils/oauthServer.d.ts +18 -0
  43. package/dist/utils/oauthServer.js +244 -0
  44. package/dist/utils/pkce.d.ts +16 -0
  45. package/dist/utils/pkce.js +73 -0
  46. package/package.json +7 -14
  47. package/scripts/postinstall.js +75 -0
  48. package/LICENSE +0 -21
@@ -1,4 +1,37 @@
1
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
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
@@ -7,35 +40,193 @@ exports.login = login;
7
40
  exports.logout = logout;
8
41
  exports.status = status;
9
42
  const chalk_1 = __importDefault(require("chalk"));
43
+ const ora_1 = __importDefault(require("ora"));
44
+ const open_1 = __importDefault(require("open"));
45
+ const node_fetch_1 = __importDefault(require("node-fetch"));
10
46
  const config_1 = require("../config");
11
- async function login(apiKey, options) {
47
+ const pkce_1 = require("../utils/pkce");
48
+ const oauthServer_1 = require("../utils/oauthServer");
49
+ const os = __importStar(require("os"));
50
+ const CLIENT_ID = 'sessioncast-cli';
51
+ const DEFAULT_SCOPES = 'openid profile email';
52
+ async function login(apiKey, options = {}) {
53
+ // If API key provided, use manual login
54
+ if (apiKey) {
55
+ return manualLogin(apiKey, options);
56
+ }
57
+ // Otherwise, use browser-based OAuth login
58
+ return browserLogin(options);
59
+ }
60
+ async function manualLogin(apiKey, options) {
12
61
  if (options.url) {
13
62
  (0, config_1.setApiUrl)(options.url);
14
63
  console.log(chalk_1.default.gray(`API URL set to: ${options.url}`));
15
64
  }
16
65
  // Validate API key format
17
- if (!apiKey.startsWith('sk-')) {
18
- console.log(chalk_1.default.red('Invalid API key format. Key should start with "sk-"'));
66
+ if (!apiKey.startsWith('sk-') && !apiKey.startsWith('agt_')) {
67
+ console.log(chalk_1.default.red('Invalid key format. Key should start with "sk-" or "agt_"'));
68
+ process.exit(1);
69
+ }
70
+ if (apiKey.startsWith('agt_')) {
71
+ (0, config_1.setAgentToken)(apiKey);
72
+ console.log(chalk_1.default.green('✓ Agent token saved!'));
73
+ }
74
+ else {
75
+ (0, config_1.setApiKey)(apiKey);
76
+ console.log(chalk_1.default.green('✓ API key saved!'));
77
+ }
78
+ }
79
+ async function browserLogin(options = {}) {
80
+ console.log(chalk_1.default.bold('\n SessionCast Login\n'));
81
+ // Set custom URLs if provided
82
+ if (options.url) {
83
+ (0, config_1.setApiUrl)(options.url);
84
+ }
85
+ if (options.auth) {
86
+ (0, config_1.setAuthUrl)(options.auth);
87
+ }
88
+ const authUrl = (0, config_1.getAuthUrl)();
89
+ const apiUrl = (0, config_1.getApiUrl)();
90
+ // Find available port for callback
91
+ const spinner = (0, ora_1.default)('Preparing login...').start();
92
+ let port;
93
+ try {
94
+ port = await (0, oauthServer_1.findAvailablePort)(9876);
95
+ }
96
+ catch (err) {
97
+ spinner.fail('Could not find an available port');
98
+ console.log(chalk_1.default.yellow('\nFallback: Manual token entry'));
99
+ console.log(chalk_1.default.gray(`Visit ${authUrl} and copy your token`));
100
+ process.exit(1);
101
+ return;
102
+ }
103
+ const redirectUri = `http://127.0.0.1:${port}/callback`;
104
+ // Generate PKCE values
105
+ const codeVerifier = (0, pkce_1.generateCodeVerifier)();
106
+ const codeChallenge = (0, pkce_1.generateCodeChallenge)(codeVerifier);
107
+ const state = (0, pkce_1.generateState)();
108
+ // Build authorization URL
109
+ const authorizationUrl = new URL(`${authUrl}/oauth/authorize`);
110
+ authorizationUrl.searchParams.set('client_id', CLIENT_ID);
111
+ authorizationUrl.searchParams.set('redirect_uri', redirectUri);
112
+ authorizationUrl.searchParams.set('response_type', 'code');
113
+ authorizationUrl.searchParams.set('scope', DEFAULT_SCOPES);
114
+ authorizationUrl.searchParams.set('state', state);
115
+ authorizationUrl.searchParams.set('code_challenge', codeChallenge);
116
+ authorizationUrl.searchParams.set('code_challenge_method', 'S256');
117
+ spinner.text = 'Opening browser...';
118
+ // Start callback server and open browser
119
+ const serverPromise = (0, oauthServer_1.startCallbackServer)(port, 300000); // 5 minute timeout
120
+ try {
121
+ await (0, open_1.default)(authorizationUrl.toString());
122
+ spinner.text = 'Waiting for authentication...';
123
+ console.log(chalk_1.default.gray(`\n If browser didn't open, visit:\n ${authorizationUrl.toString()}\n`));
124
+ }
125
+ catch (err) {
126
+ spinner.warn('Could not open browser automatically');
127
+ console.log(chalk_1.default.yellow(`\nPlease open this URL in your browser:\n${authorizationUrl.toString()}\n`));
128
+ }
129
+ // Wait for callback
130
+ let result;
131
+ try {
132
+ result = await serverPromise;
133
+ }
134
+ catch (err) {
135
+ spinner.fail(err.message || 'Login failed');
136
+ process.exit(1);
137
+ return;
138
+ }
139
+ // Check for errors
140
+ if (result.error) {
141
+ spinner.fail(`Authentication failed: ${result.errorDescription || result.error}`);
142
+ process.exit(1);
143
+ return;
144
+ }
145
+ // Verify state
146
+ if (result.state !== state) {
147
+ spinner.fail('Security error: State mismatch');
148
+ process.exit(1);
149
+ return;
150
+ }
151
+ if (!result.code) {
152
+ spinner.fail('No authorization code received');
153
+ process.exit(1);
154
+ return;
155
+ }
156
+ // Exchange code for token
157
+ spinner.text = 'Exchanging code for token...';
158
+ try {
159
+ const tokenResponse = await (0, node_fetch_1.default)(`${authUrl}/oauth/token`, {
160
+ method: 'POST',
161
+ headers: {
162
+ 'Content-Type': 'application/x-www-form-urlencoded',
163
+ },
164
+ body: new URLSearchParams({
165
+ grant_type: 'authorization_code',
166
+ client_id: CLIENT_ID,
167
+ code: result.code,
168
+ redirect_uri: redirectUri,
169
+ code_verifier: codeVerifier,
170
+ }).toString(),
171
+ });
172
+ if (!tokenResponse.ok) {
173
+ const errorText = await tokenResponse.text();
174
+ throw new Error(`Token exchange failed: ${errorText}`);
175
+ }
176
+ const tokenData = await tokenResponse.json();
177
+ // Save tokens
178
+ (0, config_1.setAccessToken)(tokenData.access_token, tokenData.expires_in);
179
+ if (tokenData.refresh_token) {
180
+ (0, config_1.setRefreshToken)(tokenData.refresh_token);
181
+ }
182
+ spinner.text = 'Generating agent token...';
183
+ // Generate agent token
184
+ const agentTokenResponse = await (0, node_fetch_1.default)(`${apiUrl}/api/tokens/generate`, {
185
+ method: 'POST',
186
+ headers: {
187
+ 'Authorization': `Bearer ${tokenData.access_token}`,
188
+ 'Content-Type': 'application/json',
189
+ },
190
+ body: JSON.stringify({
191
+ machineId: os.hostname(),
192
+ }),
193
+ });
194
+ if (agentTokenResponse.ok) {
195
+ const agentData = await agentTokenResponse.json();
196
+ (0, config_1.setAgentToken)(agentData.token);
197
+ (0, config_1.setMachineId)(agentData.machineId || os.hostname());
198
+ }
199
+ spinner.succeed('Login successful!');
200
+ console.log(chalk_1.default.green('\n✓ You are now logged in to SessionCast\n'));
201
+ console.log(chalk_1.default.gray(' Run `sessioncast agent` to start the agent'));
202
+ console.log(chalk_1.default.gray(' Run `sessioncast status` to check your login status\n'));
203
+ }
204
+ catch (err) {
205
+ spinner.fail(`Login failed: ${err.message}`);
19
206
  process.exit(1);
20
207
  }
21
- (0, config_1.setApiKey)(apiKey);
22
- console.log(chalk_1.default.green('✓ Logged in successfully!'));
23
- console.log(chalk_1.default.gray('Your API key has been saved.'));
24
208
  }
25
209
  async function logout() {
26
210
  if (!(0, config_1.isLoggedIn)()) {
27
211
  console.log(chalk_1.default.yellow('Not logged in.'));
28
212
  return;
29
213
  }
30
- (0, config_1.clearApiKey)();
214
+ (0, config_1.clearAuth)();
31
215
  console.log(chalk_1.default.green('✓ Logged out successfully!'));
32
216
  }
33
217
  function status() {
218
+ const accessToken = (0, config_1.getAccessToken)();
34
219
  if ((0, config_1.isLoggedIn)()) {
35
220
  console.log(chalk_1.default.green('✓ Logged in'));
221
+ if (accessToken) {
222
+ console.log(chalk_1.default.gray(' Auth method: OAuth'));
223
+ }
224
+ else {
225
+ console.log(chalk_1.default.gray(' Auth method: API Key / Agent Token'));
226
+ }
36
227
  }
37
228
  else {
38
229
  console.log(chalk_1.default.yellow('Not logged in'));
39
- console.log(chalk_1.default.gray('Run: sessioncast login <api-key>'));
230
+ console.log(chalk_1.default.gray('Run: sessioncast login'));
40
231
  }
41
232
  }
@@ -10,7 +10,7 @@ export declare function projectInit(projectPath: string, options: {
10
10
  export declare function projectRun(projectPath: string, options: {
11
11
  watch?: boolean;
12
12
  noClaude?: boolean;
13
- relayUrl?: string;
13
+ relay?: string;
14
14
  relayToken?: string;
15
15
  }): Promise<void>;
16
16
  /**
@@ -91,28 +91,19 @@ async function projectRun(projectPath, options) {
91
91
  console.error(chalk_1.default.red('Error: No workflow.yml found. Define your workflow first.'));
92
92
  process.exit(1);
93
93
  }
94
- // Use default dev token for local development
95
- let relayToken = options.relayToken;
96
- if (options.relayUrl && !relayToken) {
97
- const isDevRelay = options.relayUrl.includes('localhost') || options.relayUrl.includes('127.0.0.1');
98
- if (isDevRelay) {
99
- relayToken = 'dev@localhost';
100
- console.log(chalk_1.default.gray(' Using default dev token: dev@localhost'));
101
- }
102
- }
103
94
  console.log(chalk_1.default.gray('─'.repeat(50)));
104
95
  console.log(` Workflow: ${chalk_1.default.bold(workflow.name)}`);
105
96
  console.log(` Mission: ${workflow.mission}`);
106
97
  console.log(` Agents: ${workflow.agents.map(a => a.id).join(', ')}`);
107
98
  console.log(` Auto-launch Claude: ${options.noClaude ? 'No' : 'Yes'}`);
108
- if (options.relayUrl) {
109
- console.log(` Relay: ${options.relayUrl}`);
99
+ if (options.relay) {
100
+ console.log(` Relay: ${options.relay}`);
110
101
  }
111
102
  console.log(chalk_1.default.gray('─'.repeat(50)));
112
103
  const executor = new project_1.WorkflowExecutor(manager, {
113
104
  autoLaunchClaude: !options.noClaude,
114
- relayUrl: options.relayUrl,
115
- relayToken: relayToken
105
+ relayUrl: options.relay,
106
+ relayToken: options.relayToken
116
107
  });
117
108
  executor.on('agent-started', ({ agentId, sessionName }) => {
118
109
  console.log(chalk_1.default.cyan(`[${agentId}] Started - tmux session: ${sessionName}`));
package/dist/config.d.ts CHANGED
@@ -2,6 +2,13 @@ import Conf from 'conf';
2
2
  interface ConfigSchema {
3
3
  apiKey?: string;
4
4
  apiUrl: string;
5
+ authUrl: string;
6
+ relayUrl: string;
7
+ accessToken?: string;
8
+ refreshToken?: string;
9
+ tokenExpiresAt?: number;
10
+ agentToken?: string;
11
+ machineId?: string;
5
12
  }
6
13
  declare const config: Conf<ConfigSchema>;
7
14
  export declare function getApiKey(): string | undefined;
@@ -9,5 +16,18 @@ export declare function setApiKey(key: string): void;
9
16
  export declare function clearApiKey(): void;
10
17
  export declare function getApiUrl(): string;
11
18
  export declare function setApiUrl(url: string): void;
19
+ export declare function getAuthUrl(): string;
20
+ export declare function setAuthUrl(url: string): void;
21
+ export declare function getRelayUrl(): string;
22
+ export declare function setRelayUrl(url: string): void;
23
+ export declare function getAccessToken(): string | undefined;
24
+ export declare function setAccessToken(token: string, expiresIn: number): void;
25
+ export declare function getRefreshToken(): string | undefined;
26
+ export declare function setRefreshToken(token: string): void;
27
+ export declare function getAgentToken(): string | undefined;
28
+ export declare function setAgentToken(token: string): void;
29
+ export declare function getMachineId(): string | undefined;
30
+ export declare function setMachineId(id: string): void;
31
+ export declare function clearAuth(): void;
12
32
  export declare function isLoggedIn(): boolean;
13
33
  export default config;
package/dist/config.js CHANGED
@@ -8,12 +8,27 @@ exports.setApiKey = setApiKey;
8
8
  exports.clearApiKey = clearApiKey;
9
9
  exports.getApiUrl = getApiUrl;
10
10
  exports.setApiUrl = setApiUrl;
11
+ exports.getAuthUrl = getAuthUrl;
12
+ exports.setAuthUrl = setAuthUrl;
13
+ exports.getRelayUrl = getRelayUrl;
14
+ exports.setRelayUrl = setRelayUrl;
15
+ exports.getAccessToken = getAccessToken;
16
+ exports.setAccessToken = setAccessToken;
17
+ exports.getRefreshToken = getRefreshToken;
18
+ exports.setRefreshToken = setRefreshToken;
19
+ exports.getAgentToken = getAgentToken;
20
+ exports.setAgentToken = setAgentToken;
21
+ exports.getMachineId = getMachineId;
22
+ exports.setMachineId = setMachineId;
23
+ exports.clearAuth = clearAuth;
11
24
  exports.isLoggedIn = isLoggedIn;
12
25
  const conf_1 = __importDefault(require("conf"));
13
26
  const config = new conf_1.default({
14
27
  projectName: 'sessioncast',
15
28
  defaults: {
16
- apiUrl: 'https://api.sessioncast.io'
29
+ apiUrl: 'https://api.sessioncast.io',
30
+ authUrl: 'https://auth.sessioncast.io',
31
+ relayUrl: 'wss://relay.sessioncast.io/ws',
17
32
  }
18
33
  });
19
34
  function getApiKey() {
@@ -31,7 +46,59 @@ function getApiUrl() {
31
46
  function setApiUrl(url) {
32
47
  config.set('apiUrl', url);
33
48
  }
49
+ function getAuthUrl() {
50
+ return config.get('authUrl');
51
+ }
52
+ function setAuthUrl(url) {
53
+ config.set('authUrl', url);
54
+ }
55
+ function getRelayUrl() {
56
+ return config.get('relayUrl');
57
+ }
58
+ function setRelayUrl(url) {
59
+ config.set('relayUrl', url);
60
+ }
61
+ // OAuth token management
62
+ function getAccessToken() {
63
+ const token = config.get('accessToken');
64
+ const expiresAt = config.get('tokenExpiresAt');
65
+ // Check if token is expired
66
+ if (token && expiresAt && Date.now() > expiresAt) {
67
+ return undefined; // Token expired
68
+ }
69
+ return token;
70
+ }
71
+ function setAccessToken(token, expiresIn) {
72
+ config.set('accessToken', token);
73
+ config.set('tokenExpiresAt', Date.now() + (expiresIn * 1000));
74
+ }
75
+ function getRefreshToken() {
76
+ return config.get('refreshToken');
77
+ }
78
+ function setRefreshToken(token) {
79
+ config.set('refreshToken', token);
80
+ }
81
+ // Agent token (for relay connection)
82
+ function getAgentToken() {
83
+ return config.get('agentToken');
84
+ }
85
+ function setAgentToken(token) {
86
+ config.set('agentToken', token);
87
+ }
88
+ function getMachineId() {
89
+ return config.get('machineId');
90
+ }
91
+ function setMachineId(id) {
92
+ config.set('machineId', id);
93
+ }
94
+ function clearAuth() {
95
+ config.delete('apiKey');
96
+ config.delete('accessToken');
97
+ config.delete('refreshToken');
98
+ config.delete('tokenExpiresAt');
99
+ config.delete('agentToken');
100
+ }
34
101
  function isLoggedIn() {
35
- return !!getApiKey();
102
+ return !!(getApiKey() || getAccessToken() || getAgentToken());
36
103
  }
37
104
  exports.default = config;
package/dist/index.js CHANGED
@@ -11,17 +11,17 @@ const agents_1 = require("./commands/agents");
11
11
  const sessions_1 = require("./commands/sessions");
12
12
  const sendkeys_1 = require("./commands/sendkeys");
13
13
  const agent_1 = require("./commands/agent");
14
- const project_1 = require("./commands/project");
15
14
  const program = new commander_1.Command();
16
15
  program
17
16
  .name('sessioncast')
18
17
  .description('SessionCast CLI - Control your agents from anywhere')
19
- .version('1.0.0');
18
+ .version('0.1.0');
20
19
  // Login command
21
20
  program
22
- .command('login <api-key>')
23
- .description('Login with your API key')
21
+ .command('login [api-key]')
22
+ .description('Login to SessionCast (opens browser if no API key provided)')
24
23
  .option('-u, --url <url>', 'Custom API URL')
24
+ .option('-a, --auth <url>', 'Custom Auth URL')
25
25
  .action(login_1.login);
26
26
  // Logout command
27
27
  program
@@ -57,60 +57,20 @@ program
57
57
  .description('Start the SessionCast agent')
58
58
  .option('-c, --config <path>', 'Path to config file')
59
59
  .action(agent_1.startAgent);
60
- // Project commands
61
- const project = program
62
- .command('project')
63
- .description('Project mode commands');
64
- project
65
- .command('init [path]')
66
- .description('Initialize a new SessionCast project')
67
- .option('-n, --name <name>', 'Project name')
68
- .action(project_1.projectInit);
69
- project
70
- .command('run [path]')
71
- .description('Run the workflow')
72
- .option('-w, --watch', 'Watch mode - keep running after completion')
73
- .option('--no-claude', 'Do not auto-launch Claude Code CLI')
74
- .option('--relay-url <url>', 'Relay server WebSocket URL')
75
- .option('--relay-token <token>', 'Relay server authentication token')
76
- .action(project_1.projectRun);
77
- project
78
- .command('status [path]')
79
- .description('Show project and workflow status')
80
- .action(project_1.projectStatus);
81
- project
82
- .command('stop [path]')
83
- .description('Stop all agent sessions')
84
- .action(project_1.projectStop);
85
- project
86
- .command('send <path> <agent> <message>')
87
- .description('Send a message to an agent')
88
- .action(project_1.projectSend);
89
- project
90
- .command('workflow [path]')
91
- .description('Create workflow from template')
92
- .option('-t, --template <template>', 'Template: basic, android, fullstack')
93
- .action(project_1.projectCreateWorkflow);
94
60
  // Help examples
95
61
  program.on('--help', () => {
96
62
  console.log('');
97
63
  console.log('Examples:');
98
- console.log(' $ sessioncast login sk-xxx-xxx-xxx');
64
+ console.log(' $ sessioncast login # Browser-based login (recommended)');
65
+ console.log(' $ sessioncast login agt_xxx # Login with agent token');
99
66
  console.log(' $ sessioncast agents');
100
67
  console.log(' $ sessioncast list');
101
68
  console.log(' $ sessioncast list macbook');
102
69
  console.log(' $ sessioncast send macbook:dev "ls -la"');
103
70
  console.log(' $ sessioncast send server:main:0 "npm run build"');
104
- console.log(' $ sessioncast agent # Start agent with default config');
71
+ console.log(' $ sessioncast agent # Start agent');
105
72
  console.log(' $ sessioncast agent -c ~/.sessioncast.yml # Start with custom config');
106
73
  console.log('');
107
- console.log('Project Mode:');
108
- console.log(' $ sessioncast project init ./my-project # Initialize new project');
109
- console.log(' $ sessioncast project workflow . -t android # Create workflow from template');
110
- console.log(' $ sessioncast project run . # Run the workflow');
111
- console.log(' $ sessioncast project status . # Check status');
112
- console.log(' $ sessioncast project stop . # Stop all agents');
113
- console.log('');
114
74
  console.log('Target format:');
115
75
  console.log(' <agent>:<session> - Send to session');
116
76
  console.log(' <agent>:<session>:<window> - Send to specific window');
@@ -5,7 +5,6 @@ export interface ExecutorOptions {
5
5
  claudeCommand?: string;
6
6
  relayUrl?: string;
7
7
  relayToken?: string;
8
- machineId?: string;
9
8
  }
10
9
  export declare class WorkflowExecutor extends EventEmitter {
11
10
  private manager;
@@ -19,6 +18,14 @@ export declare class WorkflowExecutor extends EventEmitter {
19
18
  * Start workflow execution
20
19
  */
21
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;
22
29
  /**
23
30
  * Start PM Agent tmux session
24
31
  */
@@ -43,58 +50,6 @@ export declare class WorkflowExecutor extends EventEmitter {
43
50
  * Main execution loop
44
51
  */
45
52
  private runExecutionLoop;
46
- /**
47
- * Connect to relay server
48
- */
49
- private connectToRelay;
50
- /**
51
- * Handle incoming messages from relay server
52
- */
53
- private handleRelayMessage;
54
- /**
55
- * Handle mission analysis request - calls Claude Code to analyze
56
- */
57
- private handleAnalyzeMission;
58
- /**
59
- * Handle addSource request - clone/copy source into work folder
60
- */
61
- private handleAddSource;
62
- /**
63
- * Execute the source addition command
64
- */
65
- private executeAddSource;
66
- /**
67
- * Use Claude to interpret a natural language prompt and add source
68
- */
69
- private executeAddSourceWithAI;
70
- /**
71
- * Call Claude Code CLI to analyze mission and return steps and decisions
72
- */
73
- private callClaudeForAnalysis;
74
- /**
75
- * Read source file contents from context paths for Claude analysis
76
- */
77
- private readSourceContext;
78
- /**
79
- * Get key files from a source directory for context
80
- */
81
- private getKeyFilesFromDirectory;
82
- /**
83
- * Build the prompt for Claude Code to analyze the mission
84
- */
85
- private buildAnalysisPrompt;
86
- /**
87
- * Parse Claude's response to extract steps and decisions
88
- */
89
- private parseAnalysisResponse;
90
- /**
91
- * Get default steps when analysis fails
92
- */
93
- private getDefaultSteps;
94
- /**
95
- * Update relay with current status
96
- */
97
- private updateRelayStatus;
98
53
  /**
99
54
  * Stop workflow execution
100
55
  */