modelstat 0.0.26 → 0.0.28
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/cli.mjs +119 -34
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.mjs +91 -1
package/package.json
CHANGED
package/scripts/postinstall.mjs
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
import { existsSync } from "node:fs";
|
|
29
|
+
import { homedir } from "node:os";
|
|
29
30
|
import { dirname, join, resolve } from "node:path";
|
|
30
31
|
import { fileURLToPath } from "node:url";
|
|
31
32
|
|
|
@@ -97,7 +98,7 @@ async function main() {
|
|
|
97
98
|
try {
|
|
98
99
|
await ensureLlamaModel(defaultLlamaConfig());
|
|
99
100
|
console.log("");
|
|
100
|
-
console.log("[modelstat] ✓ summariser ready
|
|
101
|
+
console.log("[modelstat] ✓ summariser ready");
|
|
101
102
|
} catch (err) {
|
|
102
103
|
// Don't fail the npm install. The model will retry-download on
|
|
103
104
|
// first scan; better to leave the user with a working binary
|
|
@@ -109,6 +110,95 @@ async function main() {
|
|
|
109
110
|
"[modelstat] the model will download lazily on first `modelstat scan` instead",
|
|
110
111
|
);
|
|
111
112
|
}
|
|
113
|
+
|
|
114
|
+
// ── Auto-replace + restart the existing service ───────────────
|
|
115
|
+
// If a previous version of the agent is already installed as a
|
|
116
|
+
// launchd / systemd service, its bundle copy at
|
|
117
|
+
// ~/.modelstat/bin/modelstat.mjs is now STALE — the new code we
|
|
118
|
+
// just installed lives in <global node_modules>/modelstat/dist.
|
|
119
|
+
// Stop the service, refresh the bundle copy, restart. Without
|
|
120
|
+
// this step the user has to manually `modelstat stop && modelstat
|
|
121
|
+
// connect` after every upgrade.
|
|
122
|
+
await rebootServiceIfInstalled();
|
|
123
|
+
console.log(
|
|
124
|
+
"[modelstat] all set — your dashboard already has the new agent running",
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function rebootServiceIfInstalled() {
|
|
129
|
+
const stateDir = join(homedir(), ".modelstat");
|
|
130
|
+
const installedBundle = join(stateDir, "bin", "modelstat.mjs");
|
|
131
|
+
const launchdPlist = join(
|
|
132
|
+
homedir(),
|
|
133
|
+
"Library",
|
|
134
|
+
"LaunchAgents",
|
|
135
|
+
"ai.modelstat.agent.plist",
|
|
136
|
+
);
|
|
137
|
+
const systemdUnit = join(
|
|
138
|
+
process.env.XDG_CONFIG_HOME ?? join(homedir(), ".config"),
|
|
139
|
+
"systemd",
|
|
140
|
+
"user",
|
|
141
|
+
"modelstat.service",
|
|
142
|
+
);
|
|
143
|
+
const hasService = existsSync(launchdPlist) || existsSync(systemdUnit);
|
|
144
|
+
if (!hasService) {
|
|
145
|
+
console.log(
|
|
146
|
+
"[modelstat] no background service installed — run `modelstat connect` to set one up",
|
|
147
|
+
);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Locate the freshly-installed bundle in this package. From
|
|
152
|
+
// scripts/postinstall.mjs → ../dist/cli.mjs.
|
|
153
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
154
|
+
const freshBundle = join(here, "..", "dist", "cli.mjs");
|
|
155
|
+
if (!existsSync(freshBundle)) {
|
|
156
|
+
console.warn(
|
|
157
|
+
"[modelstat] couldn't find new bundle — service refresh skipped",
|
|
158
|
+
);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Spawn the FRESH bundle to do the actual restart through its own
|
|
163
|
+
// service.ts — that's the same code that knows how to talk to
|
|
164
|
+
// launchd / systemd on each platform. We can't import service.ts
|
|
165
|
+
// directly here (postinstall is a plain .mjs without TS resolution),
|
|
166
|
+
// but spawning the new bundle gives us the new behaviour.
|
|
167
|
+
const { spawnSync } = await import("node:child_process");
|
|
168
|
+
console.log("[modelstat] refreshing background service…");
|
|
169
|
+
|
|
170
|
+
// Stop first — best effort, ignore failures.
|
|
171
|
+
spawnSync(process.execPath, [freshBundle, "stop"], {
|
|
172
|
+
stdio: "ignore",
|
|
173
|
+
timeout: 30_000,
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Copy the new bundle over the old `~/.modelstat/bin/modelstat.mjs`
|
|
177
|
+
// so the service supervisor (launchd/systemd) loads the new code on
|
|
178
|
+
// next launch. The fresh bundle's `connect` / `start` does this on
|
|
179
|
+
// its own first run, but we want the service to come back alive
|
|
180
|
+
// immediately — not wait for a manual `modelstat connect`.
|
|
181
|
+
const { copyFileSync, mkdirSync } = await import("node:fs");
|
|
182
|
+
try {
|
|
183
|
+
mkdirSync(dirname(installedBundle), { recursive: true });
|
|
184
|
+
copyFileSync(freshBundle, installedBundle);
|
|
185
|
+
} catch (err) {
|
|
186
|
+
console.warn(
|
|
187
|
+
`[modelstat] couldn't refresh installed bundle: ${err && err.message ? err.message : err}`,
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Start back up. `modelstat start` re-runs preflight (incl. the
|
|
192
|
+
// processing-version reconcile that wipes cursors when we ship a
|
|
193
|
+
// new pipeline), so the upgrade picks up the new behaviour
|
|
194
|
+
// immediately. Detached so the daemon survives this script.
|
|
195
|
+
const { spawn } = await import("node:child_process");
|
|
196
|
+
const child = spawn(process.execPath, [freshBundle, "start"], {
|
|
197
|
+
detached: true,
|
|
198
|
+
stdio: "ignore",
|
|
199
|
+
});
|
|
200
|
+
child.unref();
|
|
201
|
+
console.log("[modelstat] ✓ background service restarted with new build");
|
|
112
202
|
}
|
|
113
203
|
|
|
114
204
|
main().catch((err) => {
|