@abdasis/agentdeck 2.44.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.
- package/README.md +122 -0
- package/agent/dist/config.d.ts +31 -0
- package/agent/dist/config.d.ts.map +1 -0
- package/agent/dist/config.js +81 -0
- package/agent/dist/config.js.map +1 -0
- package/agent/dist/db/commands.d.ts +25 -0
- package/agent/dist/db/commands.d.ts.map +1 -0
- package/agent/dist/db/commands.js +93 -0
- package/agent/dist/db/commands.js.map +1 -0
- package/agent/dist/db/index.d.ts +30 -0
- package/agent/dist/db/index.d.ts.map +1 -0
- package/agent/dist/db/index.js +368 -0
- package/agent/dist/db/index.js.map +1 -0
- package/agent/dist/db/schema.d.ts +74 -0
- package/agent/dist/db/schema.d.ts.map +1 -0
- package/agent/dist/db/schema.js +100 -0
- package/agent/dist/db/schema.js.map +1 -0
- package/agent/dist/db/sessions.d.ts +46 -0
- package/agent/dist/db/sessions.d.ts.map +1 -0
- package/agent/dist/db/sessions.js +198 -0
- package/agent/dist/db/sessions.js.map +1 -0
- package/agent/dist/index.d.ts +2 -0
- package/agent/dist/index.d.ts.map +1 -0
- package/agent/dist/index.js +19 -0
- package/agent/dist/index.js.map +1 -0
- package/agent/dist/lib/command-session.d.ts +20 -0
- package/agent/dist/lib/command-session.d.ts.map +1 -0
- package/agent/dist/lib/command-session.js +64 -0
- package/agent/dist/lib/command-session.js.map +1 -0
- package/agent/dist/lib/git.d.ts +8 -0
- package/agent/dist/lib/git.d.ts.map +1 -0
- package/agent/dist/lib/git.js +194 -0
- package/agent/dist/lib/git.js.map +1 -0
- package/agent/dist/lib/init-script.d.ts +33 -0
- package/agent/dist/lib/init-script.d.ts.map +1 -0
- package/agent/dist/lib/init-script.js +523 -0
- package/agent/dist/lib/init-script.js.map +1 -0
- package/agent/dist/lib/transcript.d.ts +16 -0
- package/agent/dist/lib/transcript.d.ts.map +1 -0
- package/agent/dist/lib/transcript.js +64 -0
- package/agent/dist/lib/transcript.js.map +1 -0
- package/agent/dist/logger.d.ts +12 -0
- package/agent/dist/logger.d.ts.map +1 -0
- package/agent/dist/logger.js +39 -0
- package/agent/dist/logger.js.map +1 -0
- package/agent/dist/middleware/auth.d.ts +15 -0
- package/agent/dist/middleware/auth.d.ts.map +1 -0
- package/agent/dist/middleware/auth.js +55 -0
- package/agent/dist/middleware/auth.js.map +1 -0
- package/agent/dist/routes/commands.d.ts +8 -0
- package/agent/dist/routes/commands.d.ts.map +1 -0
- package/agent/dist/routes/commands.js +229 -0
- package/agent/dist/routes/commands.js.map +1 -0
- package/agent/dist/routes/files.d.ts +7 -0
- package/agent/dist/routes/files.d.ts.map +1 -0
- package/agent/dist/routes/files.js +206 -0
- package/agent/dist/routes/files.js.map +1 -0
- package/agent/dist/routes/hooks.d.ts +7 -0
- package/agent/dist/routes/hooks.d.ts.map +1 -0
- package/agent/dist/routes/hooks.js +147 -0
- package/agent/dist/routes/hooks.js.map +1 -0
- package/agent/dist/routes/index.d.ts +10 -0
- package/agent/dist/routes/index.d.ts.map +1 -0
- package/agent/dist/routes/index.js +10 -0
- package/agent/dist/routes/index.js.map +1 -0
- package/agent/dist/routes/pair.d.ts +26 -0
- package/agent/dist/routes/pair.d.ts.map +1 -0
- package/agent/dist/routes/pair.js +384 -0
- package/agent/dist/routes/pair.js.map +1 -0
- package/agent/dist/routes/projects.d.ts +6 -0
- package/agent/dist/routes/projects.d.ts.map +1 -0
- package/agent/dist/routes/projects.js +121 -0
- package/agent/dist/routes/projects.js.map +1 -0
- package/agent/dist/routes/sessions-git.d.ts +7 -0
- package/agent/dist/routes/sessions-git.d.ts.map +1 -0
- package/agent/dist/routes/sessions-git.js +31 -0
- package/agent/dist/routes/sessions-git.js.map +1 -0
- package/agent/dist/routes/sessions-tmux.d.ts +7 -0
- package/agent/dist/routes/sessions-tmux.d.ts.map +1 -0
- package/agent/dist/routes/sessions-tmux.js +94 -0
- package/agent/dist/routes/sessions-tmux.js.map +1 -0
- package/agent/dist/routes/sessions.d.ts +7 -0
- package/agent/dist/routes/sessions.d.ts.map +1 -0
- package/agent/dist/routes/sessions.js +172 -0
- package/agent/dist/routes/sessions.js.map +1 -0
- package/agent/dist/server.d.ts +6 -0
- package/agent/dist/server.d.ts.map +1 -0
- package/agent/dist/server.js +95 -0
- package/agent/dist/server.js.map +1 -0
- package/agent/dist/terminal.d.ts +19 -0
- package/agent/dist/terminal.d.ts.map +1 -0
- package/agent/dist/terminal.js +175 -0
- package/agent/dist/terminal.js.map +1 -0
- package/agent/dist/updater.d.ts +18 -0
- package/agent/dist/updater.d.ts.map +1 -0
- package/agent/dist/updater.js +122 -0
- package/agent/dist/updater.js.map +1 -0
- package/agent/dist/version.d.ts +20 -0
- package/agent/dist/version.d.ts.map +1 -0
- package/agent/dist/version.js +66 -0
- package/agent/dist/version.js.map +1 -0
- package/agent/dist/websocket-handlers.d.ts +38 -0
- package/agent/dist/websocket-handlers.d.ts.map +1 -0
- package/agent/dist/websocket-handlers.js +389 -0
- package/agent/dist/websocket-handlers.js.map +1 -0
- package/agent/node_modules/@agentdeck/shared/dist/index.d.ts +2 -0
- package/agent/node_modules/@agentdeck/shared/dist/index.d.ts.map +1 -0
- package/agent/node_modules/@agentdeck/shared/dist/index.js +2 -0
- package/agent/node_modules/@agentdeck/shared/dist/index.js.map +1 -0
- package/agent/node_modules/@agentdeck/shared/dist/types/index.d.ts +235 -0
- package/agent/node_modules/@agentdeck/shared/dist/types/index.d.ts.map +1 -0
- package/agent/node_modules/@agentdeck/shared/dist/types/index.js +5 -0
- package/agent/node_modules/@agentdeck/shared/dist/types/index.js.map +1 -0
- package/agent/node_modules/@agentdeck/shared/package.json +29 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +304 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/hooks.d.ts +3 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +187 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +109 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logs.d.ts +3 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +38 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/profile.d.ts +3 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +156 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/service.d.ts +3 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +235 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/start.d.ts +3 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +122 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +48 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +3 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +23 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +129 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/version.d.ts +3 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +39 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +68 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +156 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/hooks.d.ts +67 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +353 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/paths.d.ts +36 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +77 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/prerequisites.d.ts +60 -0
- package/dist/lib/prerequisites.d.ts.map +1 -0
- package/dist/lib/prerequisites.js +266 -0
- package/dist/lib/prerequisites.js.map +1 -0
- package/dist/lib/process.d.ts +40 -0
- package/dist/lib/process.d.ts.map +1 -0
- package/dist/lib/process.js +192 -0
- package/dist/lib/process.js.map +1 -0
- package/dist/service/index.d.ts +44 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/service/index.js +18 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/launchd.d.ts +18 -0
- package/dist/service/launchd.d.ts.map +1 -0
- package/dist/service/launchd.js +208 -0
- package/dist/service/launchd.js.map +1 -0
- package/dist/service/systemd.d.ts +18 -0
- package/dist/service/systemd.d.ts.map +1 -0
- package/dist/service/systemd.js +196 -0
- package/dist/service/systemd.js.map +1 -0
- package/hooks/notify-agentdeck.sh +53 -0
- package/package.json +83 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import * as pty from '@homebridge/node-pty-prebuilt-multiarch';
|
|
2
|
+
import { exec, execSync } from 'child_process';
|
|
3
|
+
import { promisify } from 'util';
|
|
4
|
+
import { generateInitScript, writeInitScript, cleanupInitScript, detectUserShell, } from './lib/init-script.js';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
const execAsync = promisify(exec);
|
|
7
|
+
export function createTerminal(cwd, sessionName, options = {}) {
|
|
8
|
+
// Support both old signature (customEnvVars object) and new options object
|
|
9
|
+
const customEnvVars = 'customEnvVars' in options
|
|
10
|
+
? (options.customEnvVars ?? {})
|
|
11
|
+
: options;
|
|
12
|
+
// Check if session already exists before spawning
|
|
13
|
+
let existingSession = false;
|
|
14
|
+
try {
|
|
15
|
+
execSync(`tmux has-session -t "${sessionName}" 2>/dev/null`);
|
|
16
|
+
existingSession = true;
|
|
17
|
+
console.log(`[Terminal] Session '${sessionName}' exists, will attach`);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
existingSession = false;
|
|
21
|
+
console.log(`[Terminal] Session '${sessionName}' does not exist, will create`);
|
|
22
|
+
}
|
|
23
|
+
if (Object.keys(customEnvVars).length > 0) {
|
|
24
|
+
console.log(`[Terminal] Custom env vars for injection: ${Object.keys(customEnvVars).join(', ')}`);
|
|
25
|
+
}
|
|
26
|
+
// Use tmux for session persistence
|
|
27
|
+
// For existing sessions: use attach-session (more reliable)
|
|
28
|
+
// For new sessions: use new-session with init script for clean setup
|
|
29
|
+
let tmuxArgs;
|
|
30
|
+
let initScriptPath = null;
|
|
31
|
+
// Detect test/CI environment for animation skipping
|
|
32
|
+
const isTestEnv = !!(process.env.VITEST || process.env.CI || process.env.JEST_WORKER_ID);
|
|
33
|
+
if (existingSession) {
|
|
34
|
+
tmuxArgs = ['attach-session', '-t', sessionName];
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Extract project name from cwd (last directory component)
|
|
38
|
+
const projectName = path.basename(cwd) || 'unknown';
|
|
39
|
+
// Detect user's preferred shell for the interactive session
|
|
40
|
+
const userShell = detectUserShell();
|
|
41
|
+
// Generate and write init script for new sessions
|
|
42
|
+
// The init script is always sourced by bash (via --init-file)
|
|
43
|
+
// So we generate it for bash, and it ends with `exec ${userShell} -i`
|
|
44
|
+
// to switch to the user's preferred interactive shell
|
|
45
|
+
const scriptContent = generateInitScript({
|
|
46
|
+
sessionName,
|
|
47
|
+
projectName,
|
|
48
|
+
customEnvVars,
|
|
49
|
+
shell: 'bash', // Always bash since bash sources the init-file
|
|
50
|
+
targetShell: userShell, // User's preferred shell for interactive session
|
|
51
|
+
});
|
|
52
|
+
initScriptPath = writeInitScript(sessionName, scriptContent);
|
|
53
|
+
console.log(`[Terminal] Init script written to: ${initScriptPath} (target shell: ${userShell})`);
|
|
54
|
+
// Spawn tmux with bash running the init script
|
|
55
|
+
// The script sets up env vars, tmux config, then runs `exec ${userShell} -i`
|
|
56
|
+
// Use -e to pass environment variable for animation skipping in tests
|
|
57
|
+
tmuxArgs = [
|
|
58
|
+
'new-session',
|
|
59
|
+
'-s',
|
|
60
|
+
sessionName,
|
|
61
|
+
'-c',
|
|
62
|
+
cwd,
|
|
63
|
+
...(isTestEnv ? ['-e', '_agentdeck_SKIP_ANIMATION=1'] : []),
|
|
64
|
+
`bash --init-file ${initScriptPath}`,
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
console.log(`[Terminal] Spawning: tmux ${tmuxArgs.join(' ')}`);
|
|
68
|
+
const shell = pty.spawn('tmux', tmuxArgs, {
|
|
69
|
+
name: 'xterm-256color',
|
|
70
|
+
cols: 120,
|
|
71
|
+
rows: 30,
|
|
72
|
+
cwd,
|
|
73
|
+
env: {
|
|
74
|
+
...process.env,
|
|
75
|
+
TERM: 'xterm-256color',
|
|
76
|
+
AGENTDECK_SESSION: sessionName, // Shared session id for hooks
|
|
77
|
+
CLAUDE_TMUX_SESSION: sessionName, // Also set at PTY level for hook detection
|
|
78
|
+
CODEX_TMUX_SESSION: sessionName,
|
|
79
|
+
PATH: `/opt/homebrew/bin:${process.env.PATH}`,
|
|
80
|
+
// Ensure UTF-8 encoding for proper accent/unicode support
|
|
81
|
+
LANG: process.env.LANG || 'en_US.UTF-8',
|
|
82
|
+
LC_ALL: process.env.LC_ALL || 'en_US.UTF-8',
|
|
83
|
+
// Suppress macOS bash deprecation warning
|
|
84
|
+
BASH_SILENCE_DEPRECATION_WARNING: '1',
|
|
85
|
+
// Pass CI/test detection to init script for animation skipping
|
|
86
|
+
...(isTestEnv ? { _agentdeck_SKIP_ANIMATION: '1' } : {}),
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
// Debug: log any immediate output or errors
|
|
90
|
+
let initialOutput = '';
|
|
91
|
+
const debugHandler = (data) => {
|
|
92
|
+
initialOutput += data;
|
|
93
|
+
if (initialOutput.length < 500) {
|
|
94
|
+
console.log(`[Terminal] Initial output: ${data.substring(0, 100)}`);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
shell.onData(debugHandler);
|
|
98
|
+
// Remove debug handler after 2 seconds to prevent memory leak
|
|
99
|
+
setTimeout(() => {
|
|
100
|
+
shell.removeListener('data', debugHandler);
|
|
101
|
+
}, 2000);
|
|
102
|
+
// Debug: log when shell exits
|
|
103
|
+
shell.onExit(({ exitCode, signal }) => {
|
|
104
|
+
console.log(`[Terminal] Shell exited: code=${exitCode}, signal=${signal}, session='${sessionName}'`);
|
|
105
|
+
});
|
|
106
|
+
// Track terminal readiness state for onReady callback
|
|
107
|
+
// Existing sessions are ready immediately
|
|
108
|
+
let isReady = existingSession;
|
|
109
|
+
const readyCallbacks = [];
|
|
110
|
+
const fireReadyCallbacks = () => {
|
|
111
|
+
console.log(`[Terminal] fireReadyCallbacks: firing ${readyCallbacks.length} callbacks for '${sessionName}'`);
|
|
112
|
+
isReady = true;
|
|
113
|
+
readyCallbacks.forEach((cb) => cb());
|
|
114
|
+
readyCallbacks.length = 0; // Clear the array
|
|
115
|
+
};
|
|
116
|
+
// Handle session initialization and readiness
|
|
117
|
+
if (!existingSession) {
|
|
118
|
+
// For new sessions, the init script handles env vars and tmux config
|
|
119
|
+
// Fire ready callbacks once shell is likely initialized
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
console.log(`[Terminal] New session '${sessionName}' ready (init script executed)`);
|
|
122
|
+
fireReadyCallbacks();
|
|
123
|
+
}, 150);
|
|
124
|
+
// Cleanup init script after shell has started (give it time to read the file)
|
|
125
|
+
if (initScriptPath) {
|
|
126
|
+
setTimeout(() => {
|
|
127
|
+
cleanupInitScript(sessionName);
|
|
128
|
+
console.log(`[Terminal] Init script cleaned up for '${sessionName}'`);
|
|
129
|
+
}, 5000);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// For existing sessions, just ensure mouse is enabled
|
|
134
|
+
// isReady is already true for existing sessions (set above)
|
|
135
|
+
setTimeout(() => {
|
|
136
|
+
exec(`tmux set-option -t "${sessionName}" mouse on`);
|
|
137
|
+
}, 100);
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
write: (data) => shell.write(data),
|
|
141
|
+
resize: (cols, rows) => shell.resize(cols, rows),
|
|
142
|
+
onData: (callback) => shell.onData(callback),
|
|
143
|
+
onExit: (callback) => shell.onExit(callback),
|
|
144
|
+
kill: () => shell.kill(),
|
|
145
|
+
detach: () => {
|
|
146
|
+
// Send tmux detach command (Ctrl+B, d)
|
|
147
|
+
shell.write('\x02d');
|
|
148
|
+
},
|
|
149
|
+
isExistingSession: () => existingSession,
|
|
150
|
+
onReady: (callback) => {
|
|
151
|
+
if (isReady) {
|
|
152
|
+
console.log(`[Terminal] onReady: already ready, calling callback immediately for '${sessionName}'`);
|
|
153
|
+
callback();
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
console.log(`[Terminal] onReady: not ready yet, queuing callback for '${sessionName}'`);
|
|
157
|
+
readyCallbacks.push(callback);
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
captureHistory: async (lines = 10000) => {
|
|
161
|
+
try {
|
|
162
|
+
// Capture scrollback buffer from tmux
|
|
163
|
+
// -p = print to stdout
|
|
164
|
+
// -S -N = start from N lines back (negative = from start of history)
|
|
165
|
+
// -J = preserve trailing spaces for proper formatting
|
|
166
|
+
const { stdout } = await execAsync(`tmux capture-pane -t "${sessionName}" -p -S -${lines} -J 2>/dev/null`);
|
|
167
|
+
return stdout;
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return '';
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-update module for the AgentDeck agent.
|
|
3
|
+
* Handles version detection and automatic updates when the web dashboard
|
|
4
|
+
* reports a newer version.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Check if an update is currently in progress.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isUpdateInProgress(): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Trigger an auto-update to the specified version.
|
|
12
|
+
* Creates a detached shell script that:
|
|
13
|
+
* 1. Waits for the agent to exit
|
|
14
|
+
* 2. Runs npm install -g
|
|
15
|
+
* 3. Restarts the agent via service manager
|
|
16
|
+
*/
|
|
17
|
+
export declare function triggerUpdate(targetVersion: string): void;
|
|
18
|
+
//# sourceMappingURL=updater.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updater.d.ts","sourceRoot":"","sources":["../src/updater.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAqGzD"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-update module for the AgentDeck agent.
|
|
3
|
+
* Handles version detection and automatic updates when the web dashboard
|
|
4
|
+
* reports a newer version.
|
|
5
|
+
*/
|
|
6
|
+
import { spawn } from 'child_process';
|
|
7
|
+
import { writeFileSync } from 'fs';
|
|
8
|
+
import { platform } from 'os';
|
|
9
|
+
import { logger } from './logger.js';
|
|
10
|
+
import { broadcastUpdatePending } from './websocket-handlers.js';
|
|
11
|
+
const UPDATE_SCRIPT = '/tmp/agentdeck-update.sh';
|
|
12
|
+
const PACKAGE_NAME = '@agentdeck/cli';
|
|
13
|
+
let updateInProgress = false;
|
|
14
|
+
/**
|
|
15
|
+
* Check if an update is currently in progress.
|
|
16
|
+
*/
|
|
17
|
+
export function isUpdateInProgress() {
|
|
18
|
+
return updateInProgress;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Trigger an auto-update to the specified version.
|
|
22
|
+
* Creates a detached shell script that:
|
|
23
|
+
* 1. Waits for the agent to exit
|
|
24
|
+
* 2. Runs npm install -g
|
|
25
|
+
* 3. Restarts the agent via service manager
|
|
26
|
+
*/
|
|
27
|
+
export function triggerUpdate(targetVersion) {
|
|
28
|
+
if (updateInProgress) {
|
|
29
|
+
logger.main.warn('Update already in progress, ignoring');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
updateInProgress = true;
|
|
33
|
+
logger.main.info({ targetVersion }, 'Auto-update triggered');
|
|
34
|
+
// Broadcast to all connected clients
|
|
35
|
+
broadcastUpdatePending(targetVersion, `Agent updating to version ${targetVersion}...`);
|
|
36
|
+
// Determine restart command based on platform
|
|
37
|
+
const os = platform();
|
|
38
|
+
let restartCommand;
|
|
39
|
+
if (os === 'darwin') {
|
|
40
|
+
// macOS: try launchctl kickstart first, fallback to manual start
|
|
41
|
+
restartCommand = 'launchctl kickstart -k gui/$(id -u)/com.agentdeck.agent 2>/dev/null || agentdeck start';
|
|
42
|
+
}
|
|
43
|
+
else if (os === 'linux') {
|
|
44
|
+
// Linux: try systemctl first, fallback to manual start
|
|
45
|
+
restartCommand = 'systemctl --user restart agentdeck-agent 2>/dev/null || agentdeck start';
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
logger.main.error({ os }, 'Unsupported platform for auto-update');
|
|
49
|
+
updateInProgress = false;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// Create update script
|
|
53
|
+
const script = `#!/bin/bash
|
|
54
|
+
# AgentDeck Auto-Update Script
|
|
55
|
+
# Target version: ${targetVersion}
|
|
56
|
+
|
|
57
|
+
# Change to /tmp to avoid blocking the agent directory during npm install
|
|
58
|
+
cd /tmp
|
|
59
|
+
|
|
60
|
+
# Wait for agent to fully exit
|
|
61
|
+
sleep 2
|
|
62
|
+
|
|
63
|
+
# Load nvm if available (required for Linux VMs using nvm)
|
|
64
|
+
export NVM_DIR="${'$'}{NVM_DIR:-${'$'}HOME/.nvm}"
|
|
65
|
+
if [ -s "${'$'}NVM_DIR/nvm.sh" ]; then
|
|
66
|
+
source "${'$'}NVM_DIR/nvm.sh"
|
|
67
|
+
echo "[agentdeck] Loaded nvm from ${'$'}NVM_DIR"
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
echo "[agentdeck] Installing version ${targetVersion}..."
|
|
71
|
+
npm install -g ${PACKAGE_NAME}@${targetVersion}
|
|
72
|
+
|
|
73
|
+
if [ $? -ne 0 ]; then
|
|
74
|
+
echo "[agentdeck] npm install failed, attempting restart anyway..."
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Fix executable permissions (npm doesn't always preserve them)
|
|
78
|
+
CLI_BIN="$(npm root -g)/${PACKAGE_NAME}/dist/index.js"
|
|
79
|
+
if [ -f "$CLI_BIN" ]; then
|
|
80
|
+
chmod +x "$CLI_BIN"
|
|
81
|
+
echo "[agentdeck] Fixed executable permissions"
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
echo "[agentdeck] Restarting agent..."
|
|
85
|
+
${restartCommand}
|
|
86
|
+
|
|
87
|
+
echo "[agentdeck] Auto-update complete"
|
|
88
|
+
rm -f "${UPDATE_SCRIPT}"
|
|
89
|
+
`;
|
|
90
|
+
try {
|
|
91
|
+
writeFileSync(UPDATE_SCRIPT, script, { mode: 0o755 });
|
|
92
|
+
logger.main.info({ path: UPDATE_SCRIPT }, 'Update script created');
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
logger.main.error({ err }, 'Failed to write update script');
|
|
96
|
+
updateInProgress = false;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// Build PATH with common locations for npm
|
|
100
|
+
const nvmPath = process.env.NVM_BIN || '';
|
|
101
|
+
const basePath = '/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin';
|
|
102
|
+
const extraPath = process.env.PATH || '';
|
|
103
|
+
// Spawn detached updater process
|
|
104
|
+
const updater = spawn('bash', [UPDATE_SCRIPT], {
|
|
105
|
+
detached: true,
|
|
106
|
+
stdio: 'ignore',
|
|
107
|
+
env: {
|
|
108
|
+
...process.env,
|
|
109
|
+
// Ensure npm and agentdeck are in PATH (nvm paths + homebrew + standard)
|
|
110
|
+
PATH: `${nvmPath}:${basePath}:${extraPath}`,
|
|
111
|
+
NVM_DIR: process.env.NVM_DIR || `${process.env.HOME}/.nvm`,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
updater.unref();
|
|
115
|
+
logger.main.info({ pid: updater.pid }, 'Update script spawned');
|
|
116
|
+
// Exit after short delay to give script time to start
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
logger.main.info('Agent exiting for update...');
|
|
119
|
+
process.exit(0);
|
|
120
|
+
}, 1000);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=updater.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updater.js","sourceRoot":"","sources":["../src/updater.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version management module for auto-update functionality.
|
|
3
|
+
* Reads agent version and provides semver comparison utilities.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Get the current agent version from package.json.
|
|
7
|
+
* Tries multiple paths to support both dev and production (bundled in CLI).
|
|
8
|
+
*/
|
|
9
|
+
export declare function getAgentVersion(): string;
|
|
10
|
+
/**
|
|
11
|
+
* Compare two semver versions.
|
|
12
|
+
* @returns positive if a > b, negative if a < b, 0 if equal
|
|
13
|
+
*/
|
|
14
|
+
export declare function compareSemver(a: string, b: string): number;
|
|
15
|
+
/**
|
|
16
|
+
* Check if the agent needs to update to match the web version.
|
|
17
|
+
* Only returns true if web version is strictly greater (never downgrade).
|
|
18
|
+
*/
|
|
19
|
+
export declare function needsUpdate(agentVersion: string, webVersion: string): boolean;
|
|
20
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAyBxC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAkB1D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAE7E"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version management module for auto-update functionality.
|
|
3
|
+
* Reads agent version and provides semver comparison utilities.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync } from 'fs';
|
|
6
|
+
import { join, dirname } from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
let cachedVersion = null;
|
|
10
|
+
/**
|
|
11
|
+
* Get the current agent version from package.json.
|
|
12
|
+
* Tries multiple paths to support both dev and production (bundled in CLI).
|
|
13
|
+
*/
|
|
14
|
+
export function getAgentVersion() {
|
|
15
|
+
if (cachedVersion)
|
|
16
|
+
return cachedVersion;
|
|
17
|
+
// Paths to try in order:
|
|
18
|
+
// 1. Dev mode: apps/agent/package.json (src -> apps/agent)
|
|
19
|
+
// 2. Prod mode: CLI's package.json (agent/dist -> agent -> cli)
|
|
20
|
+
const paths = [
|
|
21
|
+
join(__dirname, '..', 'package.json'), // dev: src/version.ts -> apps/agent/
|
|
22
|
+
join(__dirname, '..', '..', 'package.json'), // prod: agent/dist/version.js -> agent -> cli/
|
|
23
|
+
];
|
|
24
|
+
for (const p of paths) {
|
|
25
|
+
try {
|
|
26
|
+
const pkg = JSON.parse(readFileSync(p, 'utf-8'));
|
|
27
|
+
if (pkg.version) {
|
|
28
|
+
cachedVersion = pkg.version;
|
|
29
|
+
return cachedVersion;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Try next path
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
cachedVersion = '0.0.0';
|
|
37
|
+
return cachedVersion;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Compare two semver versions.
|
|
41
|
+
* @returns positive if a > b, negative if a < b, 0 if equal
|
|
42
|
+
*/
|
|
43
|
+
export function compareSemver(a, b) {
|
|
44
|
+
// Remove 'v' prefix if present
|
|
45
|
+
const cleanA = a.replace(/^v/, '');
|
|
46
|
+
const cleanB = b.replace(/^v/, '');
|
|
47
|
+
const partsA = cleanA.split('.').map((n) => parseInt(n, 10) || 0);
|
|
48
|
+
const partsB = cleanB.split('.').map((n) => parseInt(n, 10) || 0);
|
|
49
|
+
// Compare major, minor, patch
|
|
50
|
+
for (let i = 0; i < 3; i++) {
|
|
51
|
+
const va = partsA[i] || 0;
|
|
52
|
+
const vb = partsB[i] || 0;
|
|
53
|
+
if (va !== vb) {
|
|
54
|
+
return va - vb;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check if the agent needs to update to match the web version.
|
|
61
|
+
* Only returns true if web version is strictly greater (never downgrade).
|
|
62
|
+
*/
|
|
63
|
+
export function needsUpdate(agentVersion, webVersion) {
|
|
64
|
+
return compareSemver(webVersion, agentVersion) > 0;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,IAAI,aAAa,GAAkB,IAAI,CAAC;AAExC;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IAExC,yBAAyB;IACzB,2DAA2D;IAC3D,gEAAgE;IAChE,MAAM,KAAK,GAAG;QACZ,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,qCAAqC;QAC5E,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,+CAA+C;KAC7F,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YACjD,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAChB,aAAa,GAAG,GAAG,CAAC,OAAiB,CAAC;gBACtC,OAAO,aAAa,CAAC;YACvB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;IACH,CAAC;IAED,aAAa,GAAG,OAAO,CAAC;IACxB,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,CAAS,EAAE,CAAS;IAChD,+BAA+B;IAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEnC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAElE,8BAA8B;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACd,OAAO,EAAE,GAAG,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,YAAoB,EAAE,UAAkB;IAClE,OAAO,aAAa,CAAC,UAAU,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket handlers for terminal connections and sessions subscriptions.
|
|
3
|
+
* Simplified version without status tracking, worktree or execution manager features.
|
|
4
|
+
*/
|
|
5
|
+
import { WebSocket } from 'ws';
|
|
6
|
+
import type { WSSessionInfo } from '@agentdeck/shared';
|
|
7
|
+
/**
|
|
8
|
+
* Broadcast session removed event to all subscribers
|
|
9
|
+
*/
|
|
10
|
+
export declare function broadcastSessionRemoved(sessionName: string): void;
|
|
11
|
+
/**
|
|
12
|
+
* Broadcast session archived event to all subscribers
|
|
13
|
+
*/
|
|
14
|
+
export declare function broadcastSessionArchived(sessionName: string, session: WSSessionInfo): void;
|
|
15
|
+
/**
|
|
16
|
+
* Broadcast session status update to all subscribers
|
|
17
|
+
* Called when a hook notifies the agent of a status change
|
|
18
|
+
*/
|
|
19
|
+
export declare function broadcastStatusUpdate(session: WSSessionInfo): void;
|
|
20
|
+
/**
|
|
21
|
+
* Broadcast the full current sessions list to all /sessions subscribers.
|
|
22
|
+
* Called after a session is created so the sidebar updates without a reload
|
|
23
|
+
* (the WS /sessions stream is the source of truth, not the 30s HTTP poll).
|
|
24
|
+
*/
|
|
25
|
+
export declare function broadcastSessionsList(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Handle terminal WebSocket connections
|
|
28
|
+
*/
|
|
29
|
+
export declare function handleTerminalConnection(ws: WebSocket, url: URL): void;
|
|
30
|
+
/**
|
|
31
|
+
* Broadcast update-pending message to all sessions subscribers
|
|
32
|
+
*/
|
|
33
|
+
export declare function broadcastUpdatePending(targetVersion: string, message: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Handle sessions WebSocket connections (real-time session list updates)
|
|
36
|
+
*/
|
|
37
|
+
export declare function handleSessionsConnection(ws: WebSocket, url?: URL): void;
|
|
38
|
+
//# sourceMappingURL=websocket-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-handlers.d.ts","sourceRoot":"","sources":["../src/websocket-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAK/B,OAAO,KAAK,EAAoB,aAAa,EAA8B,MAAM,mBAAmB,CAAC;AA4BrG;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAYjE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAa1F;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAgBlE;AAuCD;;;;GAIG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgB3D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAyKtE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAanF;AAyCD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CA4DvE"}
|