@foxden-app/foxclaw 0.3.14 → 0.3.15
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/main.js +9 -1
- package/dist/update.d.ts +2 -1
- package/dist/update.js +61 -13
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -9,7 +9,7 @@ import { APP_HOME, DEFAULT_ENV_PATH, DEFAULT_LOG_PATH, DEFAULT_STATUS_PATH, getL
|
|
|
9
9
|
import { acquireProcessLock, LockHeldError } from './lock.js';
|
|
10
10
|
import { readRuntimeStatus, writeRuntimeStatus } from './runtime.js';
|
|
11
11
|
import { refreshFoxclawExecStartDropIns, removeFoxclawExecStartDropIns } from './systemd.js';
|
|
12
|
-
import { createSelfUpdateRuntime, performSelfUpdate } from './update.js';
|
|
12
|
+
import { createSelfUpdateRuntime, inferPnpmHomeFromEntryPoint, performSelfUpdate } from './update.js';
|
|
13
13
|
const rawCommand = process.argv[2];
|
|
14
14
|
const command = rawCommand || 'serve';
|
|
15
15
|
loadEnv();
|
|
@@ -776,9 +776,17 @@ function stopLaunchd() {
|
|
|
776
776
|
console.log(`Stopped ${plist}`);
|
|
777
777
|
}
|
|
778
778
|
function buildServicePath(nodeDir) {
|
|
779
|
+
const pnpmPath = resolveCommand('pnpm');
|
|
780
|
+
const inferredPnpmHome = inferPnpmHomeFromEntryPoint(entryPoint) || '';
|
|
781
|
+
const configuredPnpmHome = process.env.PNPM_HOME?.trim() || '';
|
|
779
782
|
const parts = [
|
|
780
783
|
path.join(process.env.HOME || '', '.local', 'bin'),
|
|
781
784
|
nodeDir,
|
|
785
|
+
inferredPnpmHome,
|
|
786
|
+
inferredPnpmHome ? path.join(inferredPnpmHome, 'bin') : '',
|
|
787
|
+
configuredPnpmHome,
|
|
788
|
+
configuredPnpmHome ? path.join(configuredPnpmHome, 'bin') : '',
|
|
789
|
+
pnpmPath ? path.dirname(pnpmPath) : '',
|
|
782
790
|
'/usr/local/sbin',
|
|
783
791
|
'/usr/local/bin',
|
|
784
792
|
'/usr/sbin',
|
package/dist/update.d.ts
CHANGED
|
@@ -41,7 +41,8 @@ export interface SelfUpdateOutcome {
|
|
|
41
41
|
error: string | null;
|
|
42
42
|
}
|
|
43
43
|
export declare function selfUpdateStatusPath(statusPath: string): string;
|
|
44
|
-
export declare function
|
|
44
|
+
export declare function inferPnpmHomeFromEntryPoint(entryPoint: string): string | null;
|
|
45
|
+
export declare function resolveSelfUpdateInstaller(entryPoint: string, nodePath?: string, exists?: (target: string) => boolean, env?: NodeJS.ProcessEnv): SelfUpdateInstaller;
|
|
45
46
|
export declare function readSelfUpdateStatus(statusFile: string): SelfUpdateStatus | null;
|
|
46
47
|
export declare function writeSelfUpdateStatus(statusFile: string, status: SelfUpdateStatus): void;
|
|
47
48
|
export declare function createSelfUpdateRuntime(options: CreateSelfUpdateRuntimeOptions): SelfUpdateRuntime;
|
package/dist/update.js
CHANGED
|
@@ -7,21 +7,42 @@ const UPDATE_STATUS_FILENAME = 'self-update.json';
|
|
|
7
7
|
export function selfUpdateStatusPath(statusPath) {
|
|
8
8
|
return path.join(path.dirname(statusPath), UPDATE_STATUS_FILENAME);
|
|
9
9
|
}
|
|
10
|
-
export function
|
|
10
|
+
export function inferPnpmHomeFromEntryPoint(entryPoint) {
|
|
11
11
|
const normalizedEntryPoint = entryPoint.replace(/\\/g, '/');
|
|
12
12
|
const globalMarker = '/global/';
|
|
13
13
|
const globalIndex = normalizedEntryPoint.indexOf(globalMarker);
|
|
14
|
-
if (globalIndex
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
if (globalIndex <= 0 || !normalizedEntryPoint.includes('/.pnpm/')) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return normalizedEntryPoint.slice(0, globalIndex);
|
|
18
|
+
}
|
|
19
|
+
export function resolveSelfUpdateInstaller(entryPoint, nodePath = process.execPath, exists = fs.existsSync, env = process.env) {
|
|
20
|
+
const pnpmHome = inferPnpmHomeFromEntryPoint(entryPoint);
|
|
21
|
+
if (pnpmHome) {
|
|
22
|
+
const commandName = process.platform === 'win32' ? 'pnpm.cmd' : 'pnpm';
|
|
23
|
+
const candidates = executableCandidates(commandName, nodePath, env, [
|
|
24
|
+
path.join(pnpmHome, commandName),
|
|
25
|
+
path.join(pnpmHome, 'bin', commandName),
|
|
26
|
+
env.PNPM_HOME?.trim() ? path.join(env.PNPM_HOME.trim(), commandName) : '',
|
|
27
|
+
env.PNPM_HOME?.trim() ? path.join(env.PNPM_HOME.trim(), 'bin', commandName) : '',
|
|
28
|
+
]);
|
|
29
|
+
const pnpmCommand = candidates.find((candidate) => exists(candidate));
|
|
30
|
+
if (pnpmCommand) {
|
|
31
|
+
return {
|
|
32
|
+
manager: 'pnpm',
|
|
33
|
+
command: pnpmCommand,
|
|
34
|
+
installArgs: ['add', '--global', PACKAGE_SPEC],
|
|
35
|
+
rootArgs: ['root', '--global'],
|
|
36
|
+
};
|
|
19
37
|
}
|
|
38
|
+
const npmCommandName = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
39
|
+
const npmCommand = executableCandidates(npmCommandName, nodePath, env)
|
|
40
|
+
.find((candidate) => exists(candidate)) ?? npmCommandName;
|
|
20
41
|
return {
|
|
21
42
|
manager: 'pnpm',
|
|
22
|
-
command:
|
|
23
|
-
installArgs: ['add', '--global', PACKAGE_SPEC],
|
|
24
|
-
rootArgs: ['root', '--global'],
|
|
43
|
+
command: npmCommand,
|
|
44
|
+
installArgs: ['exec', '--yes', '--package=pnpm@latest', '--', 'pnpm', 'add', '--global', PACKAGE_SPEC],
|
|
45
|
+
rootArgs: ['exec', '--yes', '--package=pnpm@latest', '--', 'pnpm', 'root', '--global'],
|
|
25
46
|
};
|
|
26
47
|
}
|
|
27
48
|
const adjacentNpm = path.join(path.dirname(nodePath), process.platform === 'win32' ? 'npm.cmd' : 'npm');
|
|
@@ -117,13 +138,14 @@ export function performSelfUpdate(options) {
|
|
|
117
138
|
const env = options.env ?? process.env;
|
|
118
139
|
let toVersion = null;
|
|
119
140
|
try {
|
|
120
|
-
const installer = resolveSelfUpdateInstaller(options.entryPoint, options.nodePath);
|
|
141
|
+
const installer = resolveSelfUpdateInstaller(options.entryPoint, options.nodePath, fs.existsSync, env);
|
|
142
|
+
const installerEnv = buildInstallerEnv(options.entryPoint, installer, env);
|
|
121
143
|
console.log(`[UPDATE] Installing ${PACKAGE_SPEC} with ${installer.manager}...`);
|
|
122
|
-
runInherited(installer.command, installer.installArgs,
|
|
123
|
-
const updatedEntryPoint = resolveUpdatedEntryPoint(installer,
|
|
144
|
+
runInherited(installer.command, installer.installArgs, installerEnv);
|
|
145
|
+
const updatedEntryPoint = resolveUpdatedEntryPoint(installer, installerEnv);
|
|
124
146
|
toVersion = readInstalledPackageVersion(updatedEntryPoint);
|
|
125
147
|
console.log('[UPDATE] Running checks and restarting the FoxClaw service...');
|
|
126
|
-
runInherited(options.nodePath, [updatedEntryPoint, 'start'],
|
|
148
|
+
runInherited(options.nodePath, [updatedEntryPoint, 'start'], installerEnv);
|
|
127
149
|
completeNotification(options.notificationFile, 'succeeded', toVersion, null);
|
|
128
150
|
console.log(`[OK] FoxClaw updated and restarted: ${options.version} -> ${toVersion}`);
|
|
129
151
|
return {
|
|
@@ -145,6 +167,32 @@ export function performSelfUpdate(options) {
|
|
|
145
167
|
};
|
|
146
168
|
}
|
|
147
169
|
}
|
|
170
|
+
function executableCandidates(commandName, nodePath, env, preferred = []) {
|
|
171
|
+
return [
|
|
172
|
+
...preferred,
|
|
173
|
+
path.join(path.dirname(nodePath), commandName),
|
|
174
|
+
...(env.PATH || '').split(path.delimiter).filter(Boolean).map((dir) => path.join(dir, commandName)),
|
|
175
|
+
].filter((candidate, index, all) => candidate && all.indexOf(candidate) === index);
|
|
176
|
+
}
|
|
177
|
+
function buildInstallerEnv(entryPoint, installer, env) {
|
|
178
|
+
const pnpmHome = installer.manager === 'pnpm' ? inferPnpmHomeFromEntryPoint(entryPoint) : null;
|
|
179
|
+
if (!pnpmHome) {
|
|
180
|
+
return env;
|
|
181
|
+
}
|
|
182
|
+
const configuredPnpmHome = env.PNPM_HOME?.trim() || pnpmHome;
|
|
183
|
+
const pathEntries = [
|
|
184
|
+
configuredPnpmHome,
|
|
185
|
+
path.join(configuredPnpmHome, 'bin'),
|
|
186
|
+
pnpmHome,
|
|
187
|
+
path.join(pnpmHome, 'bin'),
|
|
188
|
+
...(env.PATH || '').split(path.delimiter).filter(Boolean),
|
|
189
|
+
];
|
|
190
|
+
return {
|
|
191
|
+
...env,
|
|
192
|
+
PNPM_HOME: configuredPnpmHome,
|
|
193
|
+
PATH: pathEntries.filter((entry, index, all) => all.indexOf(entry) === index).join(path.delimiter),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
148
196
|
function runInherited(command, args, env) {
|
|
149
197
|
const result = spawnSync(command, args, { stdio: 'inherit', env });
|
|
150
198
|
if (result.error) {
|