@agent-link/agent 0.1.196 → 0.1.198

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.
@@ -1,199 +0,0 @@
1
- /**
2
- * Auto-update: periodically checks npm for a newer version of @agent-link/agent.
3
- * When an update is found, waits for idle (no active Claude turn), installs the
4
- * new version via npm, and restarts the daemon. The session URL is preserved
5
- * through the existing agent.json sessionId restore mechanism.
6
- */
7
- import { execSync, spawn } from 'child_process';
8
- import { createRequire } from 'module';
9
- import { join } from 'path';
10
- import { openSync, existsSync, readdirSync, rmSync } from 'fs';
11
- import os from 'os';
12
- import { resolveConfig, loadRuntimeState, saveRuntimeState, getLogDir, getLogDate, cleanOldLogs } from './config.js';
13
- import { getConversations } from './claude.js';
14
- import { setPreserveRuntimeState } from './index.js';
15
- const require = createRequire(import.meta.url);
16
- const pkg = require('../package.json');
17
- const CHECK_DELAY = 30_000; // first check 30s after startup
18
- const CHECK_INTERVAL = 4 * 3600_000; // then every 4 hours
19
- const IDLE_POLL_INTERVAL = 5_000; // poll turn status every 5s
20
- const IDLE_TIMEOUT = 10 * 60_000; // give up waiting after 10 min
21
- let timer = null;
22
- /**
23
- * Returns true if `latest` is strictly newer than `current` (semver comparison).
24
- * Used to prevent downgrades (e.g., beta 0.1.155 > latest 0.1.153).
25
- */
26
- export function isNewerVersion(current, latest) {
27
- const [curMajor, curMinor, curPatch] = current.split('.').map(Number);
28
- const [latMajor, latMinor, latPatch] = latest.split('.').map(Number);
29
- if (latMajor !== curMajor)
30
- return latMajor > curMajor;
31
- if (latMinor !== curMinor)
32
- return latMinor > curMinor;
33
- return latPatch > curPatch;
34
- }
35
- function getLatestVersion() {
36
- try {
37
- return execSync('npm view @agent-link/agent version', {
38
- encoding: 'utf-8',
39
- timeout: 30_000,
40
- windowsHide: true,
41
- }).trim();
42
- }
43
- catch {
44
- return null;
45
- }
46
- }
47
- function isTurnActive() {
48
- for (const [, conv] of getConversations()) {
49
- if (conv.turnActive)
50
- return true;
51
- }
52
- return false;
53
- }
54
- async function waitForIdle() {
55
- if (!isTurnActive())
56
- return true;
57
- console.log('[AutoUpdate] Waiting for current turn to finish...');
58
- const deadline = Date.now() + IDLE_TIMEOUT;
59
- while (Date.now() < deadline) {
60
- await new Promise(r => setTimeout(r, IDLE_POLL_INTERVAL));
61
- if (!isTurnActive())
62
- return true;
63
- }
64
- return false;
65
- }
66
- async function checkAndUpdate(daemon) {
67
- const currentVersion = pkg.version;
68
- const latestVersion = getLatestVersion();
69
- if (!latestVersion || latestVersion === currentVersion)
70
- return;
71
- // Only upgrade, never downgrade (beta versions may be newer than latest)
72
- if (!isNewerVersion(currentVersion, latestVersion)) {
73
- return;
74
- }
75
- console.log(`[AutoUpdate] New version available: ${currentVersion} → ${latestVersion}`);
76
- if (!daemon) {
77
- // Foreground mode: just notify, don't auto-update
78
- console.log('[AutoUpdate] Run "agentlink-client upgrade" to update.');
79
- return;
80
- }
81
- // Wait for idle
82
- const idle = await waitForIdle();
83
- if (!idle) {
84
- console.log('[AutoUpdate] Turn still active after timeout, skipping this update cycle.');
85
- return;
86
- }
87
- // Install new version
88
- console.log(`[AutoUpdate] Installing @agent-link/agent@${latestVersion}...`);
89
- try {
90
- execSync(`npm install -g @agent-link/agent@${latestVersion}`, {
91
- stdio: 'ignore',
92
- timeout: 120_000,
93
- windowsHide: true,
94
- });
95
- }
96
- catch (err) {
97
- console.error(`[AutoUpdate] Install failed: ${err.message}`);
98
- return;
99
- }
100
- console.log(`[AutoUpdate] Updated to v${latestVersion}. Restarting daemon...`);
101
- // Clean up npm's leftover temp dirs from previous upgrades (Windows only).
102
- // On Windows, node-pty's conpty.node is locked by the running process,
103
- // so npm can't delete its temp staging dirs during install. These
104
- // accumulate as .agent-XXXXXXXX directories. Clean them up now.
105
- if (process.platform === 'win32') {
106
- try {
107
- const npmPrefix = execSync('npm prefix -g', { encoding: 'utf-8', timeout: 15_000, windowsHide: true }).trim();
108
- const pkgParent = join(npmPrefix, 'node_modules', '@agent-link');
109
- if (existsSync(pkgParent)) {
110
- for (const entry of readdirSync(pkgParent)) {
111
- if (entry.startsWith('.agent-')) {
112
- try {
113
- rmSync(join(pkgParent, entry), { recursive: true, force: true });
114
- }
115
- catch { /* best effort */ }
116
- }
117
- }
118
- }
119
- }
120
- catch { /* non-critical */ }
121
- }
122
- // We can't use `agentlink-client start --daemon` synchronously because
123
- // this process is still alive and the start command rejects "already running".
124
- // Instead, spawn the new daemon.js directly (detached), then exit.
125
- // Resolve the new daemon.js from the freshly-installed package
126
- let newDaemonScript;
127
- try {
128
- const npmPrefix = execSync('npm prefix -g', { encoding: 'utf-8', windowsHide: true }).trim();
129
- const pkgDir = join(npmPrefix, process.platform === 'win32' ? '' : 'lib', 'node_modules', '@agent-link', 'agent', 'dist');
130
- newDaemonScript = join(pkgDir, 'daemon.js');
131
- }
132
- catch (err) {
133
- console.error(`[AutoUpdate] Failed to locate new daemon script: ${err.message}`);
134
- console.error('[AutoUpdate] Keeping current process alive. Will retry next cycle.');
135
- return;
136
- }
137
- // Build config for the new daemon — use resolveConfig to ensure all fields
138
- // (especially dir) have proper defaults, not just what's in config.json.
139
- // Override dir from runtime state (agent.json) which has the actual working
140
- // directory the daemon was started with, rather than relying on process.cwd().
141
- const runtimeState = loadRuntimeState();
142
- const config = resolveConfig(runtimeState?.dir ? { dir: runtimeState.dir } : {});
143
- if (!config.autoUpdate)
144
- config.autoUpdate = true; // we're in auto-update, keep it on
145
- // Guard: if the working directory doesn't exist, fall back to home dir
146
- if (!existsSync(config.dir)) {
147
- const fallback = os.homedir();
148
- console.warn(`[AutoUpdate] Working directory does not exist: ${config.dir}, falling back to: ${fallback}`);
149
- config.dir = fallback;
150
- }
151
- const logDir = getLogDir();
152
- const dateTag = getLogDate();
153
- cleanOldLogs(7);
154
- const out = openSync(join(logDir, `agent-${dateTag}.log`), 'a');
155
- const err = openSync(join(logDir, `agent-${dateTag}.err`), 'a');
156
- console.log('[AutoUpdate] Spawning new daemon and exiting...');
157
- const child = spawn(process.execPath, [newDaemonScript, JSON.stringify(config)], {
158
- detached: true,
159
- stdio: ['ignore', out, err],
160
- cwd: config.dir,
161
- windowsHide: true,
162
- });
163
- child.unref();
164
- // Tell shutdown handler to keep agent.json so the new daemon can
165
- // restore the sessionId and preserve the session URL across upgrades.
166
- setPreserveRuntimeState(true);
167
- // Rewrite agent.json with the NEW daemon's PID so `stop` can find it.
168
- // Preserve sessionId so the new daemon can restore the session URL.
169
- if (runtimeState && child.pid)
170
- saveRuntimeState({ ...runtimeState, pid: child.pid });
171
- // Exit old process — new daemon is starting
172
- process.exit(0);
173
- }
174
- /**
175
- * Start the auto-update check loop.
176
- * @param daemon - true if running in daemon mode (will auto-install + restart);
177
- * false for foreground mode (prints notification only).
178
- */
179
- export function startAutoUpdate(daemon) {
180
- // First check after a delay so startup isn't slowed
181
- setTimeout(() => {
182
- checkAndUpdate(daemon).catch(() => { });
183
- // Subsequent checks on interval
184
- timer = setInterval(() => {
185
- checkAndUpdate(daemon).catch(() => { });
186
- }, CHECK_INTERVAL);
187
- // Don't keep process alive just for the timer
188
- if (timer && typeof timer === 'object' && 'unref' in timer) {
189
- timer.unref();
190
- }
191
- }, CHECK_DELAY);
192
- }
193
- export function stopAutoUpdate() {
194
- if (timer) {
195
- clearInterval(timer);
196
- timer = null;
197
- }
198
- }
199
- //# sourceMappingURL=auto-update.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-update.js","sourceRoot":"","sources":["../src/auto-update.ts"],"names":[],"mappings":"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"}