sessioncast-cli 2.0.2 → 2.0.4
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 +24 -2
- package/dist/agent/session-handler.d.ts +3 -2
- package/dist/agent/session-handler.js +60 -53
- package/dist/agent/tmux-executor.d.ts +19 -33
- package/dist/agent/tmux-executor.js +51 -38
- package/dist/agent/tmux.d.ts +12 -6
- package/dist/agent/tmux.js +16 -9
- package/dist/agent/types.d.ts +0 -10
- package/dist/agent/websocket.d.ts +6 -13
- package/dist/agent/websocket.js +36 -37
- 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/agent/websocket.js
CHANGED
|
@@ -40,11 +40,10 @@ exports.RelayWebSocketClient = void 0;
|
|
|
40
40
|
const ws_1 = __importDefault(require("ws"));
|
|
41
41
|
const events_1 = require("events");
|
|
42
42
|
const zlib = __importStar(require("zlib"));
|
|
43
|
-
const MAX_RECONNECT_ATTEMPTS =
|
|
43
|
+
const MAX_RECONNECT_ATTEMPTS = 5;
|
|
44
44
|
const BASE_RECONNECT_DELAY_MS = 2000;
|
|
45
45
|
const MAX_RECONNECT_DELAY_MS = 60000;
|
|
46
46
|
const CIRCUIT_BREAKER_DURATION_MS = 120000;
|
|
47
|
-
const PING_INTERVAL_MS = 30000;
|
|
48
47
|
class RelayWebSocketClient extends events_1.EventEmitter {
|
|
49
48
|
constructor(options) {
|
|
50
49
|
super();
|
|
@@ -54,7 +53,6 @@ class RelayWebSocketClient extends events_1.EventEmitter {
|
|
|
54
53
|
this.circuitBreakerOpen = false;
|
|
55
54
|
this.circuitBreakerResetTime = 0;
|
|
56
55
|
this.reconnectTimer = null;
|
|
57
|
-
this.pingTimer = null;
|
|
58
56
|
this.destroyed = false;
|
|
59
57
|
this.url = options.url;
|
|
60
58
|
this.sessionId = options.sessionId;
|
|
@@ -72,9 +70,8 @@ class RelayWebSocketClient extends events_1.EventEmitter {
|
|
|
72
70
|
this.isConnected = true;
|
|
73
71
|
this.reconnectAttempts = 0;
|
|
74
72
|
this.circuitBreakerOpen = false;
|
|
75
|
-
this.registerAsHost();
|
|
76
|
-
this.startPing();
|
|
77
73
|
this.emit('connected');
|
|
74
|
+
this.registerAsHost();
|
|
78
75
|
});
|
|
79
76
|
this.ws.on('message', (data) => {
|
|
80
77
|
try {
|
|
@@ -87,7 +84,6 @@ class RelayWebSocketClient extends events_1.EventEmitter {
|
|
|
87
84
|
});
|
|
88
85
|
this.ws.on('close', (code, reason) => {
|
|
89
86
|
this.isConnected = false;
|
|
90
|
-
this.stopPing();
|
|
91
87
|
this.emit('disconnected', { code, reason: reason.toString() });
|
|
92
88
|
if (this.autoReconnect && !this.destroyed) {
|
|
93
89
|
this.scheduleReconnect();
|
|
@@ -123,7 +119,7 @@ class RelayWebSocketClient extends events_1.EventEmitter {
|
|
|
123
119
|
switch (message.type) {
|
|
124
120
|
case 'keys':
|
|
125
121
|
if (message.session === this.sessionId && message.payload) {
|
|
126
|
-
this.emit('keys', message.payload, message.meta);
|
|
122
|
+
this.emit('keys', message.payload, message.meta?.pane);
|
|
127
123
|
}
|
|
128
124
|
break;
|
|
129
125
|
case 'resize':
|
|
@@ -192,20 +188,6 @@ class RelayWebSocketClient extends events_1.EventEmitter {
|
|
|
192
188
|
console.error(`Error: code=${meta.code}, message=${meta.messageEn}`);
|
|
193
189
|
}
|
|
194
190
|
}
|
|
195
|
-
startPing() {
|
|
196
|
-
this.stopPing();
|
|
197
|
-
this.pingTimer = setInterval(() => {
|
|
198
|
-
if (this.ws && this.ws.readyState === ws_1.default.OPEN) {
|
|
199
|
-
this.ws.ping();
|
|
200
|
-
}
|
|
201
|
-
}, PING_INTERVAL_MS);
|
|
202
|
-
}
|
|
203
|
-
stopPing() {
|
|
204
|
-
if (this.pingTimer) {
|
|
205
|
-
clearInterval(this.pingTimer);
|
|
206
|
-
this.pingTimer = null;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
191
|
scheduleReconnect() {
|
|
210
192
|
if (this.destroyed)
|
|
211
193
|
return;
|
|
@@ -257,38 +239,56 @@ class RelayWebSocketClient extends events_1.EventEmitter {
|
|
|
257
239
|
return false;
|
|
258
240
|
}
|
|
259
241
|
}
|
|
260
|
-
sendScreen(data
|
|
242
|
+
sendScreen(data) {
|
|
261
243
|
if (!this.isConnected)
|
|
262
244
|
return false;
|
|
263
245
|
const base64Data = data.toString('base64');
|
|
264
|
-
|
|
246
|
+
return this.send({
|
|
265
247
|
type: 'screen',
|
|
266
248
|
session: this.sessionId,
|
|
267
249
|
payload: base64Data
|
|
268
|
-
};
|
|
269
|
-
if (paneMeta) {
|
|
270
|
-
msg.meta = { pane: paneMeta.pane, index: String(paneMeta.index) };
|
|
271
|
-
}
|
|
272
|
-
return this.send(msg);
|
|
250
|
+
});
|
|
273
251
|
}
|
|
274
|
-
|
|
252
|
+
sendScreenWithMeta(data, meta) {
|
|
253
|
+
if (!this.isConnected)
|
|
254
|
+
return false;
|
|
255
|
+
return this.send({
|
|
256
|
+
type: 'screen',
|
|
257
|
+
session: this.sessionId,
|
|
258
|
+
payload: data.toString('base64'),
|
|
259
|
+
meta
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
sendScreenCompressed(data) {
|
|
275
263
|
if (!this.isConnected)
|
|
276
264
|
return false;
|
|
277
265
|
try {
|
|
278
266
|
const compressed = zlib.gzipSync(data);
|
|
279
267
|
const base64Data = compressed.toString('base64');
|
|
280
|
-
|
|
268
|
+
return this.send({
|
|
281
269
|
type: 'screenGz',
|
|
282
270
|
session: this.sessionId,
|
|
283
271
|
payload: base64Data
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return this.sendScreen(data);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
sendScreenCompressedWithMeta(data, meta) {
|
|
279
|
+
if (!this.isConnected)
|
|
280
|
+
return false;
|
|
281
|
+
try {
|
|
282
|
+
const compressed = zlib.gzipSync(data);
|
|
283
|
+
return this.send({
|
|
284
|
+
type: 'screenGz',
|
|
285
|
+
session: this.sessionId,
|
|
286
|
+
payload: compressed.toString('base64'),
|
|
287
|
+
meta
|
|
288
|
+
});
|
|
289
289
|
}
|
|
290
290
|
catch {
|
|
291
|
-
return this.
|
|
291
|
+
return this.sendScreenWithMeta(data, meta);
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
sendPaneLayout(panes) {
|
|
@@ -358,7 +358,6 @@ class RelayWebSocketClient extends events_1.EventEmitter {
|
|
|
358
358
|
destroy() {
|
|
359
359
|
this.destroyed = true;
|
|
360
360
|
this.autoReconnect = false;
|
|
361
|
-
this.stopPing();
|
|
362
361
|
if (this.reconnectTimer) {
|
|
363
362
|
clearTimeout(this.reconnectTimer);
|
|
364
363
|
this.reconnectTimer = null;
|
package/dist/commands/agent.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.startAgent = startAgent;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const runner_1 = require("../agent/runner");
|
|
9
|
+
const sentry_1 = require("../sentry");
|
|
9
10
|
async function startAgent(options) {
|
|
10
11
|
try {
|
|
11
12
|
const config = runner_1.AgentRunner.loadConfig(options.config);
|
|
@@ -13,6 +14,8 @@ async function startAgent(options) {
|
|
|
13
14
|
await runner.start();
|
|
14
15
|
}
|
|
15
16
|
catch (error) {
|
|
17
|
+
(0, sentry_1.captureException)(error);
|
|
18
|
+
await (0, sentry_1.flush)();
|
|
16
19
|
console.error(chalk_1.default.red(`Error: ${error.message}`));
|
|
17
20
|
process.exit(1);
|
|
18
21
|
}
|
package/dist/index.js
CHANGED
|
@@ -47,6 +47,20 @@ const sessions_1 = require("./commands/sessions");
|
|
|
47
47
|
const sendkeys_1 = require("./commands/sendkeys");
|
|
48
48
|
const agent_1 = require("./commands/agent");
|
|
49
49
|
const config_1 = require("./config");
|
|
50
|
+
const sentry_1 = require("./sentry");
|
|
51
|
+
// Initialize Sentry as early as possible
|
|
52
|
+
(0, sentry_1.initSentry)();
|
|
53
|
+
// Catch unhandled errors globally
|
|
54
|
+
process.on('uncaughtException', async (error) => {
|
|
55
|
+
(0, sentry_1.captureException)(error);
|
|
56
|
+
await (0, sentry_1.flush)();
|
|
57
|
+
console.error(chalk_1.default.red(`Fatal error: ${error.message}`));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
});
|
|
60
|
+
process.on('unhandledRejection', async (reason) => {
|
|
61
|
+
(0, sentry_1.captureException)(reason);
|
|
62
|
+
await (0, sentry_1.flush)();
|
|
63
|
+
});
|
|
50
64
|
// Check if tmux/itmux is available
|
|
51
65
|
function checkTmux() {
|
|
52
66
|
const isWindows = os.platform() === 'win32';
|
package/dist/sentry.d.ts
ADDED
package/dist/sentry.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
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.initSentry = initSentry;
|
|
37
|
+
exports.captureException = captureException;
|
|
38
|
+
exports.setUser = setUser;
|
|
39
|
+
exports.flush = flush;
|
|
40
|
+
const Sentry = __importStar(require("@sentry/node"));
|
|
41
|
+
const os = __importStar(require("os"));
|
|
42
|
+
const SENTRY_DSN = process.env.SESSIONCAST_SENTRY_DSN || 'https://ee8894c0f54e651031b49f21a5bf8dc4@o4510832077701120.ingest.us.sentry.io/4510861067681792';
|
|
43
|
+
let initialized = false;
|
|
44
|
+
function initSentry() {
|
|
45
|
+
if (initialized || !SENTRY_DSN)
|
|
46
|
+
return;
|
|
47
|
+
Sentry.init({
|
|
48
|
+
dsn: SENTRY_DSN,
|
|
49
|
+
environment: process.env.NODE_ENV || 'production',
|
|
50
|
+
release: `sessioncast-cli@${getVersion()}`,
|
|
51
|
+
beforeSend(event) {
|
|
52
|
+
// Strip sensitive data: tokens, paths with usernames
|
|
53
|
+
if (event.extra) {
|
|
54
|
+
delete event.extra['token'];
|
|
55
|
+
delete event.extra['apiKey'];
|
|
56
|
+
}
|
|
57
|
+
return event;
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
Sentry.setTag('platform', os.platform());
|
|
61
|
+
Sentry.setTag('arch', os.arch());
|
|
62
|
+
Sentry.setTag('node', process.version);
|
|
63
|
+
initialized = true;
|
|
64
|
+
}
|
|
65
|
+
function captureException(error) {
|
|
66
|
+
if (!initialized)
|
|
67
|
+
return;
|
|
68
|
+
Sentry.captureException(error);
|
|
69
|
+
}
|
|
70
|
+
function setUser(email) {
|
|
71
|
+
if (!initialized)
|
|
72
|
+
return;
|
|
73
|
+
Sentry.setUser({ email });
|
|
74
|
+
}
|
|
75
|
+
async function flush() {
|
|
76
|
+
if (!initialized)
|
|
77
|
+
return;
|
|
78
|
+
await Sentry.flush(2000);
|
|
79
|
+
}
|
|
80
|
+
function getVersion() {
|
|
81
|
+
try {
|
|
82
|
+
return require('../package.json').version;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return 'unknown';
|
|
86
|
+
}
|
|
87
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sessioncast-cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "SessionCast CLI - Control your agents from anywhere",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"dist"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
+
"@sentry/node": "^10.38.0",
|
|
29
30
|
"chalk": "^4.1.2",
|
|
30
31
|
"commander": "^12.1.0",
|
|
31
32
|
"conf": "^10.2.0",
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AutoPilot - Single-prompt execution layer for SessionCast
|
|
3
|
-
*
|
|
4
|
-
* Enables opencode-style experience: one prompt → auto-detect → auto-analyze → auto-execute
|
|
5
|
-
*/
|
|
6
|
-
import { EventEmitter } from 'events';
|
|
7
|
-
import { AutoPilotContext, AutoPilotOptions, GeneratedWorkflow } from './types';
|
|
8
|
-
import { toExecutableWorkflow } from './workflow-generator';
|
|
9
|
-
import { generateSpeckit } from './speckit-generator';
|
|
10
|
-
export * from './types';
|
|
11
|
-
export { generateSpeckit, generateQuickSpeckit, saveSpeckit } from './speckit-generator';
|
|
12
|
-
export type { SpeckitOutput } from './speckit-generator';
|
|
13
|
-
export declare class AutoPilot extends EventEmitter {
|
|
14
|
-
private options;
|
|
15
|
-
private context;
|
|
16
|
-
private llmClient?;
|
|
17
|
-
constructor(options: AutoPilotOptions);
|
|
18
|
-
/**
|
|
19
|
-
* Create initial context
|
|
20
|
-
*/
|
|
21
|
-
private createInitialContext;
|
|
22
|
-
/**
|
|
23
|
-
* Set LLM client for mission analysis
|
|
24
|
-
*/
|
|
25
|
-
setLlmClient(client: {
|
|
26
|
-
chat: (messages: {
|
|
27
|
-
role: string;
|
|
28
|
-
content: string;
|
|
29
|
-
}[]) => Promise<string>;
|
|
30
|
-
}): void;
|
|
31
|
-
/**
|
|
32
|
-
* Get current context
|
|
33
|
-
*/
|
|
34
|
-
getContext(): AutoPilotContext;
|
|
35
|
-
/**
|
|
36
|
-
* Main entry point: execute a single prompt
|
|
37
|
-
*/
|
|
38
|
-
execute(prompt: string): Promise<GeneratedWorkflow>;
|
|
39
|
-
/**
|
|
40
|
-
* Quick execute without LLM analysis
|
|
41
|
-
*/
|
|
42
|
-
quickExecute(prompt: string): Promise<GeneratedWorkflow>;
|
|
43
|
-
/**
|
|
44
|
-
* Phase 1: Detect project type
|
|
45
|
-
*/
|
|
46
|
-
private detectProject;
|
|
47
|
-
/**
|
|
48
|
-
* Phase 2: Scan sources
|
|
49
|
-
*/
|
|
50
|
-
private scanProject;
|
|
51
|
-
/**
|
|
52
|
-
* Phase 3: Analyze mission
|
|
53
|
-
*/
|
|
54
|
-
private analyzeMission;
|
|
55
|
-
/**
|
|
56
|
-
* Phase 4: Generate workflow
|
|
57
|
-
*/
|
|
58
|
-
private generateWorkflow;
|
|
59
|
-
/**
|
|
60
|
-
* Convert to executable workflow format (compatible with existing ProjectManager)
|
|
61
|
-
*/
|
|
62
|
-
toExecutableFormat(): ReturnType<typeof toExecutableWorkflow> | null;
|
|
63
|
-
/**
|
|
64
|
-
* Convert to Speckit format (plan.md + tasks.md)
|
|
65
|
-
*/
|
|
66
|
-
toSpeckit(): ReturnType<typeof generateSpeckit>;
|
|
67
|
-
/**
|
|
68
|
-
* Generate and save Speckit files
|
|
69
|
-
*/
|
|
70
|
-
saveSpeckit(outputDir?: string): {
|
|
71
|
-
planPath: string;
|
|
72
|
-
tasksPath: string;
|
|
73
|
-
};
|
|
74
|
-
/**
|
|
75
|
-
* Update status and emit event
|
|
76
|
-
*/
|
|
77
|
-
private updateStatus;
|
|
78
|
-
/**
|
|
79
|
-
* Get a summary of the analysis for display
|
|
80
|
-
*/
|
|
81
|
-
getSummary(): string;
|
|
82
|
-
/**
|
|
83
|
-
* Save workflow to file
|
|
84
|
-
*/
|
|
85
|
-
saveWorkflow(outputPath?: string): Promise<string>;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Convenience function for one-shot execution
|
|
89
|
-
*/
|
|
90
|
-
export declare function autoPilot(prompt: string, options: AutoPilotOptions): Promise<GeneratedWorkflow>;
|
|
91
|
-
/**
|
|
92
|
-
* Quick version without LLM
|
|
93
|
-
*/
|
|
94
|
-
export declare function autoPilotQuick(prompt: string, options: AutoPilotOptions): Promise<GeneratedWorkflow>;
|