@foxden-app/foxclaw 0.3.10 → 0.3.11
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 +7 -1
- package/dist/systemd.d.ts +9 -0
- package/dist/systemd.js +45 -0
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -8,6 +8,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
8
8
|
import { APP_HOME, DEFAULT_ENV_PATH, DEFAULT_LOG_PATH, DEFAULT_STATUS_PATH, getLoadedEnvPath, loadConfig, loadEnv, } from './config.js';
|
|
9
9
|
import { acquireProcessLock, LockHeldError } from './lock.js';
|
|
10
10
|
import { readRuntimeStatus, writeRuntimeStatus } from './runtime.js';
|
|
11
|
+
import { refreshFoxclawExecStartDropIns } from './systemd.js';
|
|
11
12
|
const rawCommand = process.argv[2];
|
|
12
13
|
const command = rawCommand || 'serve';
|
|
13
14
|
loadEnv();
|
|
@@ -553,6 +554,7 @@ function installSystemd() {
|
|
|
553
554
|
fs.mkdirSync(userSystemdDir, { recursive: true });
|
|
554
555
|
fs.mkdirSync(configDir, { recursive: true });
|
|
555
556
|
fs.mkdirSync(path.join(APP_HOME, 'logs'), { recursive: true });
|
|
557
|
+
const escapedEntryPoint = systemdEscape(entryPoint);
|
|
556
558
|
fs.writeFileSync(unitPath, `[Unit]
|
|
557
559
|
Description=FoxClaw local Codex execution bridge
|
|
558
560
|
Documentation=https://github.com/foxden-app/foxclaw
|
|
@@ -569,7 +571,7 @@ Environment=USER=${systemdEscape(process.env.USER || '')}
|
|
|
569
571
|
Environment=LOGNAME=${systemdEscape(process.env.LOGNAME || process.env.USER || '')}
|
|
570
572
|
Environment=PATH=${systemdEscape(pathValue)}
|
|
571
573
|
Environment=FOXCLAW_ENV=${systemdEscape(envPath)}
|
|
572
|
-
ExecStart=${systemdEscape(nodeBin)} ${
|
|
574
|
+
ExecStart=${systemdEscape(nodeBin)} ${escapedEntryPoint} serve
|
|
573
575
|
Restart=always
|
|
574
576
|
RestartSec=10
|
|
575
577
|
TimeoutStopSec=45
|
|
@@ -578,6 +580,10 @@ KillMode=process
|
|
|
578
580
|
[Install]
|
|
579
581
|
WantedBy=default.target
|
|
580
582
|
`);
|
|
583
|
+
const dropInUpdates = refreshFoxclawExecStartDropIns(userSystemdDir, unitName, escapedEntryPoint);
|
|
584
|
+
for (const update of dropInUpdates) {
|
|
585
|
+
console.log(`[OK] updated FoxClaw ExecStart override: ${update.path}`);
|
|
586
|
+
}
|
|
581
587
|
spawnChecked('systemctl', ['--user', 'daemon-reload']);
|
|
582
588
|
spawnChecked('systemctl', ['--user', 'enable', unitName]);
|
|
583
589
|
const restarted = spawnSync('systemctl', ['--user', 'restart', unitName], { stdio: 'inherit' });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface SystemdDropInUpdate {
|
|
2
|
+
path: string;
|
|
3
|
+
replacements: number;
|
|
4
|
+
}
|
|
5
|
+
export declare function refreshFoxclawExecStartDropIns(userSystemdDir: string, unitName: string, escapedEntryPoint: string): SystemdDropInUpdate[];
|
|
6
|
+
export declare function refreshFoxclawExecStartText(text: string, escapedEntryPoint: string): {
|
|
7
|
+
text: string;
|
|
8
|
+
replacements: number;
|
|
9
|
+
};
|
package/dist/systemd.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const FOXCLAW_MAIN_PATH_RE = /\S*(?:\.pnpm\/@foxden-app\+foxclaw@[^/\s]+\/node_modules\/@foxden-app\/foxclaw|node_modules\/@foxden-app\/foxclaw)\/dist\/main\.js/g;
|
|
4
|
+
export function refreshFoxclawExecStartDropIns(userSystemdDir, unitName, escapedEntryPoint) {
|
|
5
|
+
const dropInDir = path.join(userSystemdDir, `${unitName}.d`);
|
|
6
|
+
let names;
|
|
7
|
+
try {
|
|
8
|
+
names = fs.readdirSync(dropInDir).filter((name) => name.endsWith('.conf')).sort();
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
const updates = [];
|
|
14
|
+
for (const name of names) {
|
|
15
|
+
const filePath = path.join(dropInDir, name);
|
|
16
|
+
let before = '';
|
|
17
|
+
try {
|
|
18
|
+
before = fs.readFileSync(filePath, 'utf8');
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const { text, replacements } = refreshFoxclawExecStartText(before, escapedEntryPoint);
|
|
24
|
+
if (replacements === 0 || text === before) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
fs.writeFileSync(filePath, text, 'utf8');
|
|
28
|
+
updates.push({ path: filePath, replacements });
|
|
29
|
+
}
|
|
30
|
+
return updates;
|
|
31
|
+
}
|
|
32
|
+
export function refreshFoxclawExecStartText(text, escapedEntryPoint) {
|
|
33
|
+
let replacements = 0;
|
|
34
|
+
const lines = text.split(/(\r?\n)/);
|
|
35
|
+
const refreshed = lines.map((part) => {
|
|
36
|
+
if (!part.startsWith('ExecStart=') || part.trim() === 'ExecStart=') {
|
|
37
|
+
return part;
|
|
38
|
+
}
|
|
39
|
+
return part.replace(FOXCLAW_MAIN_PATH_RE, () => {
|
|
40
|
+
replacements += 1;
|
|
41
|
+
return escapedEntryPoint;
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
return { text: refreshed.join(''), replacements };
|
|
45
|
+
}
|