modelstat 0.0.6 → 0.0.7
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 +333 -55
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -4424,6 +4424,17 @@ var init_redact = __esm({
|
|
|
4424
4424
|
}
|
|
4425
4425
|
});
|
|
4426
4426
|
|
|
4427
|
+
// ../../packages/core/src/billing.ts
|
|
4428
|
+
var MILLION, FREE_INCLUDED_TOKENS, TEAM_INCLUDED_PER_SEAT;
|
|
4429
|
+
var init_billing = __esm({
|
|
4430
|
+
"../../packages/core/src/billing.ts"() {
|
|
4431
|
+
"use strict";
|
|
4432
|
+
MILLION = 1000000n;
|
|
4433
|
+
FREE_INCLUDED_TOKENS = 100n * MILLION;
|
|
4434
|
+
TEAM_INCLUDED_PER_SEAT = 250n * MILLION;
|
|
4435
|
+
}
|
|
4436
|
+
});
|
|
4437
|
+
|
|
4427
4438
|
// ../../packages/core/src/index.ts
|
|
4428
4439
|
var init_src = __esm({
|
|
4429
4440
|
"../../packages/core/src/index.ts"() {
|
|
@@ -4432,6 +4443,7 @@ var init_src = __esm({
|
|
|
4432
4443
|
init_schemas();
|
|
4433
4444
|
init_ids();
|
|
4434
4445
|
init_redact();
|
|
4446
|
+
init_billing();
|
|
4435
4447
|
}
|
|
4436
4448
|
});
|
|
4437
4449
|
|
|
@@ -5512,7 +5524,7 @@ __export(daemon_exports, {
|
|
|
5512
5524
|
setProgress: () => setProgress,
|
|
5513
5525
|
setQueue: () => setQueue
|
|
5514
5526
|
});
|
|
5515
|
-
import { existsSync as
|
|
5527
|
+
import { existsSync as existsSync5, statSync as statSync2 } from "fs";
|
|
5516
5528
|
import { request as request2 } from "undici";
|
|
5517
5529
|
function setPhase(phase, message) {
|
|
5518
5530
|
status.phase = phase;
|
|
@@ -5616,21 +5628,21 @@ async function runDaemon() {
|
|
|
5616
5628
|
await runDiscovery();
|
|
5617
5629
|
await runScanCycle("startup");
|
|
5618
5630
|
const chokidar2 = (await import("chokidar")).default;
|
|
5619
|
-
const { homedir:
|
|
5620
|
-
const { join:
|
|
5621
|
-
const
|
|
5631
|
+
const { homedir: homedir5, platform: platform5 } = await import("os");
|
|
5632
|
+
const { join: join5 } = await import("path");
|
|
5633
|
+
const home2 = homedir5();
|
|
5622
5634
|
const dirs = [
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
...
|
|
5628
|
-
|
|
5629
|
-
|
|
5635
|
+
join5(home2, ".claude/projects"),
|
|
5636
|
+
join5(home2, ".codex/sessions"),
|
|
5637
|
+
join5(home2, ".cursor/ai-tracking"),
|
|
5638
|
+
join5(home2, ".gemini"),
|
|
5639
|
+
...platform5() === "darwin" ? [
|
|
5640
|
+
join5(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
|
|
5641
|
+
join5(home2, "Library/Application Support/Claude")
|
|
5630
5642
|
] : [
|
|
5631
|
-
|
|
5643
|
+
join5(home2, ".config/Cursor/User/workspaceStorage")
|
|
5632
5644
|
]
|
|
5633
|
-
].filter((p) =>
|
|
5645
|
+
].filter((p) => existsSync5(p) && statSync2(p).isDirectory());
|
|
5634
5646
|
setPhase("watching", `Watching ${dirs.length} directories`);
|
|
5635
5647
|
const watcher = chokidar2.watch(dirs, {
|
|
5636
5648
|
persistent: true,
|
|
@@ -5695,37 +5707,37 @@ __export(watch_exports, {
|
|
|
5695
5707
|
watchForever: () => watchForever
|
|
5696
5708
|
});
|
|
5697
5709
|
import chokidar from "chokidar";
|
|
5698
|
-
import { existsSync as
|
|
5699
|
-
import { homedir as
|
|
5700
|
-
import { join as
|
|
5710
|
+
import { existsSync as existsSync6 } from "fs";
|
|
5711
|
+
import { homedir as homedir4, platform as platform3 } from "os";
|
|
5712
|
+
import { join as join4 } from "path";
|
|
5701
5713
|
function resolveWatchDirs() {
|
|
5702
|
-
const
|
|
5703
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ??
|
|
5704
|
-
const xdgData = process.env.XDG_DATA_HOME ??
|
|
5714
|
+
const home2 = homedir4();
|
|
5715
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME ?? join4(home2, ".config");
|
|
5716
|
+
const xdgData = process.env.XDG_DATA_HOME ?? join4(home2, ".local/share");
|
|
5705
5717
|
const candidates = [
|
|
5706
5718
|
// universal (default HOME-rooted CLI data dirs)
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5719
|
+
join4(home2, ".claude/projects"),
|
|
5720
|
+
join4(home2, ".codex/sessions"),
|
|
5721
|
+
join4(home2, ".cursor/ai-tracking"),
|
|
5722
|
+
join4(home2, ".gemini"),
|
|
5723
|
+
join4(home2, ".aider"),
|
|
5712
5724
|
// XDG / Linux
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5725
|
+
join4(xdgConfig, "claude/projects"),
|
|
5726
|
+
join4(xdgConfig, "codex/sessions"),
|
|
5727
|
+
join4(xdgConfig, "Cursor/User/workspaceStorage"),
|
|
5728
|
+
join4(xdgConfig, "Code/User/workspaceStorage"),
|
|
5729
|
+
join4(xdgConfig, "Code - Insiders/User/workspaceStorage"),
|
|
5730
|
+
join4(xdgData, "claude/projects"),
|
|
5719
5731
|
// macOS
|
|
5720
|
-
...
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5732
|
+
...platform3() === "darwin" ? [
|
|
5733
|
+
join4(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
|
|
5734
|
+
join4(home2, "Library/Application Support/Claude"),
|
|
5735
|
+
join4(home2, "Library/Application Support/Code/User/workspaceStorage"),
|
|
5736
|
+
join4(home2, "Library/Application Support/Windsurf/User/workspaceStorage"),
|
|
5737
|
+
join4(home2, "Library/Application Support/Zed")
|
|
5726
5738
|
] : []
|
|
5727
5739
|
];
|
|
5728
|
-
return Array.from(new Set(candidates)).filter((p) =>
|
|
5740
|
+
return Array.from(new Set(candidates)).filter((p) => existsSync6(p));
|
|
5729
5741
|
}
|
|
5730
5742
|
async function safeScan(reason) {
|
|
5731
5743
|
if (scanning) {
|
|
@@ -5788,10 +5800,224 @@ init_api();
|
|
|
5788
5800
|
init_config();
|
|
5789
5801
|
init_scan();
|
|
5790
5802
|
import { spawn } from "child_process";
|
|
5791
|
-
import { platform as
|
|
5803
|
+
import { platform as platform4, release, arch as cpuArch, hostname as hostname2 } from "os";
|
|
5792
5804
|
import { setTimeout as delay } from "timers/promises";
|
|
5805
|
+
|
|
5806
|
+
// src/service.ts
|
|
5807
|
+
import { spawnSync } from "child_process";
|
|
5808
|
+
import {
|
|
5809
|
+
copyFileSync,
|
|
5810
|
+
existsSync as existsSync4,
|
|
5811
|
+
mkdirSync,
|
|
5812
|
+
unlinkSync,
|
|
5813
|
+
writeFileSync
|
|
5814
|
+
} from "fs";
|
|
5815
|
+
import { homedir as homedir3, platform as platform2, userInfo } from "os";
|
|
5816
|
+
import { dirname as dirname3, join as join3 } from "path";
|
|
5817
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5818
|
+
var SERVICE_LABEL = "ai.modelstat.agent";
|
|
5819
|
+
var SYSTEMD_UNIT = "modelstat";
|
|
5820
|
+
function home() {
|
|
5821
|
+
return homedir3();
|
|
5822
|
+
}
|
|
5823
|
+
function stateDir() {
|
|
5824
|
+
return join3(home(), ".modelstat");
|
|
5825
|
+
}
|
|
5826
|
+
function binDir() {
|
|
5827
|
+
return join3(stateDir(), "bin");
|
|
5828
|
+
}
|
|
5829
|
+
function logDir() {
|
|
5830
|
+
return join3(stateDir(), "logs");
|
|
5831
|
+
}
|
|
5832
|
+
function installedCliPath() {
|
|
5833
|
+
return join3(binDir(), "modelstat.mjs");
|
|
5834
|
+
}
|
|
5835
|
+
function runningCliPath() {
|
|
5836
|
+
return fileURLToPath2(import.meta.url).replace(/service\.(mjs|js|ts)$/, "cli.mjs");
|
|
5837
|
+
}
|
|
5838
|
+
function installBundle() {
|
|
5839
|
+
mkdirSync(binDir(), { recursive: true });
|
|
5840
|
+
mkdirSync(logDir(), { recursive: true });
|
|
5841
|
+
const src = runningCliPath();
|
|
5842
|
+
const dest = installedCliPath();
|
|
5843
|
+
if (!existsSync4(src)) {
|
|
5844
|
+
throw new Error(
|
|
5845
|
+
`Can't find the CLI bundle to install from (${src}). Are you running a local dev build?`
|
|
5846
|
+
);
|
|
5847
|
+
}
|
|
5848
|
+
copyFileSync(src, dest);
|
|
5849
|
+
return dest;
|
|
5850
|
+
}
|
|
5851
|
+
function nodeBinary() {
|
|
5852
|
+
return process.execPath;
|
|
5853
|
+
}
|
|
5854
|
+
function plistPath() {
|
|
5855
|
+
return join3(home(), "Library", "LaunchAgents", `${SERVICE_LABEL}.plist`);
|
|
5856
|
+
}
|
|
5857
|
+
function writePlist(cliPath) {
|
|
5858
|
+
const p = plistPath();
|
|
5859
|
+
mkdirSync(dirname3(p), { recursive: true });
|
|
5860
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
5861
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
5862
|
+
<plist version="1.0">
|
|
5863
|
+
<dict>
|
|
5864
|
+
<key>Label</key><string>${SERVICE_LABEL}</string>
|
|
5865
|
+
<key>ProgramArguments</key>
|
|
5866
|
+
<array>
|
|
5867
|
+
<string>${nodeBinary()}</string>
|
|
5868
|
+
<string>${cliPath}</string>
|
|
5869
|
+
<string>start</string>
|
|
5870
|
+
</array>
|
|
5871
|
+
<key>RunAtLoad</key><true/>
|
|
5872
|
+
<key>KeepAlive</key>
|
|
5873
|
+
<dict><key>SuccessfulExit</key><false/></dict>
|
|
5874
|
+
<key>ThrottleInterval</key><integer>30</integer>
|
|
5875
|
+
<key>StandardOutPath</key><string>${join3(logDir(), "out.log")}</string>
|
|
5876
|
+
<key>StandardErrorPath</key><string>${join3(logDir(), "err.log")}</string>
|
|
5877
|
+
<key>EnvironmentVariables</key>
|
|
5878
|
+
<dict>
|
|
5879
|
+
<key>PATH</key><string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin</string>
|
|
5880
|
+
</dict>
|
|
5881
|
+
<key>WorkingDirectory</key><string>${home()}</string>
|
|
5882
|
+
</dict>
|
|
5883
|
+
</plist>
|
|
5884
|
+
`;
|
|
5885
|
+
writeFileSync(p, plist, { mode: 420 });
|
|
5886
|
+
return p;
|
|
5887
|
+
}
|
|
5888
|
+
function launchctl(args) {
|
|
5889
|
+
const r = spawnSync("launchctl", args, { encoding: "utf8" });
|
|
5890
|
+
return { ok: r.status === 0, out: r.stdout ?? "", err: r.stderr ?? "" };
|
|
5891
|
+
}
|
|
5892
|
+
function macInstall() {
|
|
5893
|
+
const cliPath = installBundle();
|
|
5894
|
+
const plist = writePlist(cliPath);
|
|
5895
|
+
const uid = userInfo().uid;
|
|
5896
|
+
const target = `gui/${uid}/${SERVICE_LABEL}`;
|
|
5897
|
+
launchctl(["bootout", target]);
|
|
5898
|
+
const boot = launchctl(["bootstrap", `gui/${uid}`, plist]);
|
|
5899
|
+
if (!boot.ok && !/already loaded|service already bootstrapped/i.test(boot.err)) {
|
|
5900
|
+
const load = launchctl(["load", "-w", plist]);
|
|
5901
|
+
if (!load.ok) {
|
|
5902
|
+
throw new Error(
|
|
5903
|
+
`launchctl load failed:
|
|
5904
|
+
bootstrap: ${boot.err.trim()}
|
|
5905
|
+
load: ${load.err.trim()}`
|
|
5906
|
+
);
|
|
5907
|
+
}
|
|
5908
|
+
}
|
|
5909
|
+
launchctl(["kickstart", "-k", target]);
|
|
5910
|
+
}
|
|
5911
|
+
function macUninstall() {
|
|
5912
|
+
const uid = userInfo().uid;
|
|
5913
|
+
const target = `gui/${uid}/${SERVICE_LABEL}`;
|
|
5914
|
+
launchctl(["bootout", target]);
|
|
5915
|
+
const plist = plistPath();
|
|
5916
|
+
if (existsSync4(plist)) {
|
|
5917
|
+
try {
|
|
5918
|
+
unlinkSync(plist);
|
|
5919
|
+
} catch {
|
|
5920
|
+
}
|
|
5921
|
+
}
|
|
5922
|
+
}
|
|
5923
|
+
function macStatus() {
|
|
5924
|
+
const uid = userInfo().uid;
|
|
5925
|
+
const r = launchctl(["print", `gui/${uid}/${SERVICE_LABEL}`]);
|
|
5926
|
+
return { running: r.ok, hint: r.ok ? "launchd managed" : "not installed" };
|
|
5927
|
+
}
|
|
5928
|
+
function systemdUnitPath() {
|
|
5929
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? join3(home(), ".config");
|
|
5930
|
+
return join3(xdg, "systemd", "user", `${SYSTEMD_UNIT}.service`);
|
|
5931
|
+
}
|
|
5932
|
+
function writeSystemdUnit(cliPath) {
|
|
5933
|
+
const unitPath = systemdUnitPath();
|
|
5934
|
+
mkdirSync(dirname3(unitPath), { recursive: true });
|
|
5935
|
+
const unit = `[Unit]
|
|
5936
|
+
Description=modelstat agent
|
|
5937
|
+
Documentation=https://modelstat.ai
|
|
5938
|
+
After=network-online.target
|
|
5939
|
+
Wants=network-online.target
|
|
5940
|
+
|
|
5941
|
+
[Service]
|
|
5942
|
+
Type=simple
|
|
5943
|
+
ExecStart=${nodeBinary()} ${cliPath} start
|
|
5944
|
+
Restart=always
|
|
5945
|
+
RestartSec=10
|
|
5946
|
+
# Don't restart-storm if the backend is persistently unreachable.
|
|
5947
|
+
StartLimitIntervalSec=300
|
|
5948
|
+
StartLimitBurst=10
|
|
5949
|
+
StandardOutput=append:${join3(logDir(), "out.log")}
|
|
5950
|
+
StandardError=append:${join3(logDir(), "err.log")}
|
|
5951
|
+
|
|
5952
|
+
[Install]
|
|
5953
|
+
WantedBy=default.target
|
|
5954
|
+
`;
|
|
5955
|
+
writeFileSync(unitPath, unit, { mode: 420 });
|
|
5956
|
+
return unitPath;
|
|
5957
|
+
}
|
|
5958
|
+
function systemctl(args) {
|
|
5959
|
+
const r = spawnSync("systemctl", ["--user", ...args], { encoding: "utf8" });
|
|
5960
|
+
return { ok: r.status === 0, out: r.stdout ?? "", err: r.stderr ?? "" };
|
|
5961
|
+
}
|
|
5962
|
+
function linuxInstall() {
|
|
5963
|
+
const cliPath = installBundle();
|
|
5964
|
+
writeSystemdUnit(cliPath);
|
|
5965
|
+
systemctl(["daemon-reload"]);
|
|
5966
|
+
const en = systemctl(["enable", "--now", `${SYSTEMD_UNIT}.service`]);
|
|
5967
|
+
if (!en.ok) {
|
|
5968
|
+
throw new Error(`systemctl enable failed: ${en.err.trim()}`);
|
|
5969
|
+
}
|
|
5970
|
+
systemctl(["restart", `${SYSTEMD_UNIT}.service`]);
|
|
5971
|
+
}
|
|
5972
|
+
function linuxUninstall() {
|
|
5973
|
+
systemctl(["disable", "--now", `${SYSTEMD_UNIT}.service`]);
|
|
5974
|
+
const unit = systemdUnitPath();
|
|
5975
|
+
if (existsSync4(unit)) {
|
|
5976
|
+
try {
|
|
5977
|
+
unlinkSync(unit);
|
|
5978
|
+
} catch {
|
|
5979
|
+
}
|
|
5980
|
+
}
|
|
5981
|
+
systemctl(["daemon-reload"]);
|
|
5982
|
+
}
|
|
5983
|
+
function linuxStatus() {
|
|
5984
|
+
const r = systemctl(["is-active", `${SYSTEMD_UNIT}.service`]);
|
|
5985
|
+
const active = r.out.trim() === "active";
|
|
5986
|
+
return { running: active, hint: active ? "systemd managed" : "not running" };
|
|
5987
|
+
}
|
|
5988
|
+
function installService() {
|
|
5989
|
+
const p = platform2();
|
|
5990
|
+
if (p === "darwin") {
|
|
5991
|
+
macInstall();
|
|
5992
|
+
return { path: plistPath(), logs: logDir() };
|
|
5993
|
+
}
|
|
5994
|
+
if (p === "linux") {
|
|
5995
|
+
linuxInstall();
|
|
5996
|
+
return { path: systemdUnitPath(), logs: logDir() };
|
|
5997
|
+
}
|
|
5998
|
+
throw new Error(
|
|
5999
|
+
`Service installation isn't supported on ${p}. Run 'modelstat start' manually to keep the agent running.`
|
|
6000
|
+
);
|
|
6001
|
+
}
|
|
6002
|
+
function uninstallService() {
|
|
6003
|
+
const p = platform2();
|
|
6004
|
+
if (p === "darwin") return macUninstall();
|
|
6005
|
+
if (p === "linux") return linuxUninstall();
|
|
6006
|
+
throw new Error(`Service uninstall isn't supported on ${p}.`);
|
|
6007
|
+
}
|
|
6008
|
+
function serviceStatus() {
|
|
6009
|
+
const p = platform2();
|
|
6010
|
+
if (p === "darwin") return macStatus();
|
|
6011
|
+
if (p === "linux") return linuxStatus();
|
|
6012
|
+
return { running: false, hint: `unsupported platform (${p})` };
|
|
6013
|
+
}
|
|
6014
|
+
function logsDir() {
|
|
6015
|
+
return logDir();
|
|
6016
|
+
}
|
|
6017
|
+
|
|
6018
|
+
// src/cli.ts
|
|
5793
6019
|
function tryOpenBrowser(url) {
|
|
5794
|
-
const p =
|
|
6020
|
+
const p = platform4();
|
|
5795
6021
|
const cmd = p === "darwin" ? "open" : p === "win32" ? "cmd" : "xdg-open";
|
|
5796
6022
|
const args = p === "win32" ? ["/c", "start", "", url] : [url];
|
|
5797
6023
|
try {
|
|
@@ -5807,7 +6033,7 @@ function tryOpenBrowser(url) {
|
|
|
5807
6033
|
}
|
|
5808
6034
|
var AGENT_VERSION3 = "agent-dev-0.0.1";
|
|
5809
6035
|
function osFamily() {
|
|
5810
|
-
const p =
|
|
6036
|
+
const p = platform4();
|
|
5811
6037
|
if (p === "darwin") return "macos";
|
|
5812
6038
|
if (p === "linux") return "linux";
|
|
5813
6039
|
return "other";
|
|
@@ -5897,13 +6123,33 @@ async function cmdConnect() {
|
|
|
5897
6123
|
}
|
|
5898
6124
|
state.setDeviceId(enroll.device_id);
|
|
5899
6125
|
console.log(`\u2713 device registered (${enroll.device_id.slice(0, 8)}\u2026)`);
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
6126
|
+
try {
|
|
6127
|
+
const svc = installService();
|
|
6128
|
+
console.log(`\u2713 service installed (${svc.path})`);
|
|
6129
|
+
console.log(` logs: ${svc.logs}`);
|
|
6130
|
+
console.log();
|
|
6131
|
+
const banner = "\u2501".repeat(60);
|
|
6132
|
+
console.log(banner);
|
|
6133
|
+
console.log(" You're connected. The agent is now running in the");
|
|
6134
|
+
console.log(" background and will start on login.");
|
|
6135
|
+
console.log();
|
|
6136
|
+
console.log(" Manage it from the dashboard:");
|
|
6137
|
+
console.log(" \x1B[1;36mhttps://modelstat.ai/dashboard\x1B[0m");
|
|
6138
|
+
console.log();
|
|
6139
|
+
console.log(" Stop it any time: \x1B[2mmodelstat stop\x1B[0m");
|
|
6140
|
+
console.log(" Uninstall: \x1B[2mmodelstat uninstall\x1B[0m");
|
|
6141
|
+
console.log(banner);
|
|
6142
|
+
return;
|
|
6143
|
+
} catch (err) {
|
|
6144
|
+
console.warn();
|
|
6145
|
+
console.warn(`\u26A0 couldn't install as a background service: ${err.message}`);
|
|
6146
|
+
console.warn(" Running in the foreground instead \u2014 press Ctrl-C to stop.");
|
|
6147
|
+
console.warn(" (Install globally with `npm i -g modelstat` then re-run `modelstat connect`.)");
|
|
6148
|
+
console.warn();
|
|
6149
|
+
const { runDaemon: runDaemon2 } = await Promise.resolve().then(() => (init_daemon(), daemon_exports));
|
|
6150
|
+
await runDaemon2();
|
|
6151
|
+
return;
|
|
6152
|
+
}
|
|
5907
6153
|
}
|
|
5908
6154
|
} catch (e) {
|
|
5909
6155
|
if (dots % 15 === 0) console.warn(`
|
|
@@ -5947,6 +6193,29 @@ async function cmdStart() {
|
|
|
5947
6193
|
const { runDaemon: runDaemon2 } = await Promise.resolve().then(() => (init_daemon(), daemon_exports));
|
|
5948
6194
|
await runDaemon2();
|
|
5949
6195
|
}
|
|
6196
|
+
async function cmdStop() {
|
|
6197
|
+
try {
|
|
6198
|
+
uninstallService();
|
|
6199
|
+
console.log("\u2713 service stopped and uninstalled");
|
|
6200
|
+
console.log(` Your device pairing is still in ${state.storePath}`);
|
|
6201
|
+
console.log(" Run `modelstat connect` again to re-enable.");
|
|
6202
|
+
} catch (err) {
|
|
6203
|
+
console.error(`\u2717 ${err.message}`);
|
|
6204
|
+
process.exit(1);
|
|
6205
|
+
}
|
|
6206
|
+
}
|
|
6207
|
+
async function cmdStatus() {
|
|
6208
|
+
const s = serviceStatus();
|
|
6209
|
+
const paired = !!state.bearer && !!state.deviceId;
|
|
6210
|
+
console.log(`paired: ${paired ? "yes" : "no"}`);
|
|
6211
|
+
if (paired) {
|
|
6212
|
+
console.log(` user: ${state.userEmail ?? "(unknown)"}`);
|
|
6213
|
+
console.log(` device: ${state.deviceId}`);
|
|
6214
|
+
}
|
|
6215
|
+
console.log(`service: ${s.running ? "running" : "stopped"} (${s.hint})`);
|
|
6216
|
+
console.log(`logs: ${logsDir()}`);
|
|
6217
|
+
console.log(`state: ${state.storePath}`);
|
|
6218
|
+
}
|
|
5950
6219
|
async function main() {
|
|
5951
6220
|
const cmd = process.argv[2];
|
|
5952
6221
|
switch (cmd) {
|
|
@@ -5964,16 +6233,25 @@ async function main() {
|
|
|
5964
6233
|
return cmdScan();
|
|
5965
6234
|
case "watch":
|
|
5966
6235
|
return cmdWatch();
|
|
6236
|
+
case "stop":
|
|
6237
|
+
case "uninstall":
|
|
6238
|
+
return cmdStop();
|
|
6239
|
+
case "status":
|
|
6240
|
+
return cmdStatus();
|
|
5967
6241
|
default:
|
|
5968
|
-
console.log(
|
|
6242
|
+
console.log(
|
|
6243
|
+
"usage: modelstat [connect|status|stop|start|discover|scan|watch|register]"
|
|
6244
|
+
);
|
|
5969
6245
|
console.log();
|
|
5970
|
-
console.log(" (no args)
|
|
5971
|
-
console.log(" connect
|
|
5972
|
-
console.log("
|
|
5973
|
-
console.log("
|
|
5974
|
-
console.log("
|
|
5975
|
-
console.log("
|
|
5976
|
-
console.log("
|
|
6246
|
+
console.log(" (no args) \u2014 pair if needed, then run the daemon in the foreground");
|
|
6247
|
+
console.log(" connect \u2014 pair + install as a background service, then exit");
|
|
6248
|
+
console.log(" status \u2014 show pairing + service state");
|
|
6249
|
+
console.log(" stop \u2014 stop and uninstall the background service");
|
|
6250
|
+
console.log(" start \u2014 run the daemon (used by the installed service)");
|
|
6251
|
+
console.log(" discover \u2014 one-shot report of installs/identities");
|
|
6252
|
+
console.log(" scan \u2014 one-shot parse + upload of local JSONL");
|
|
6253
|
+
console.log(" watch \u2014 continuous (chokidar) with periodic backstop");
|
|
6254
|
+
console.log(" register \u2014 DEV shortcut (email-only, no OAuth)");
|
|
5977
6255
|
process.exit(1);
|
|
5978
6256
|
}
|
|
5979
6257
|
}
|