diggylab 0.1.48 → 0.1.50
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/README.md +14 -1
- package/cli.js +128 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,6 +28,19 @@ node apps/desktop-agent/dist-cli/cli/cli.js --help
|
|
|
28
28
|
|
|
29
29
|
State lives in `~/.diggylab` (`--config <directory>` or `DIGGYLAB_AGENT_DIR` overrides it).
|
|
30
30
|
|
|
31
|
+
## Update
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
diggylab update
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
It asks npm for the newest release and upgrades the global install in place; when you are already
|
|
38
|
+
current it says so and changes nothing. `diggylab run` checks once a day in the background and
|
|
39
|
+
prints `A newer version is available: ...` when there is one, and every other command repeats the
|
|
40
|
+
last known notice for free — so an old worker does not go unnoticed. A systemd service needs no
|
|
41
|
+
reinstall — the unit points at npm's symlink, so restart it to switch versions (`systemctl restart
|
|
42
|
+
diggylab`).
|
|
43
|
+
|
|
31
44
|
## Publishing the npm package
|
|
32
45
|
|
|
33
46
|
```bash
|
|
@@ -176,7 +189,7 @@ journalctl -u diggylab -f # follow the worker log
|
|
|
176
189
|
|
|
177
190
|
The unit keeps the same state directory and API origin you are using, restarts the worker if it
|
|
178
191
|
crashes, and starts it on boot. It points at npm's `diggylab` symlink, so upgrading the package is
|
|
179
|
-
enough — no need to reinstall the service. Run it as root (or with `sudo`) to write the unit.
|
|
192
|
+
enough — no need to reinstall the service (`diggylab update`, then `systemctl restart diggylab`). Run it as root (or with `sudo`) to write the unit.
|
|
180
193
|
|
|
181
194
|
<details>
|
|
182
195
|
<summary>Equivalent unit, if you prefer to write it yourself</summary>
|
package/cli.js
CHANGED
|
@@ -421,7 +421,7 @@ function parseFacebookGraphqlBody(body, groupUrl) {
|
|
|
421
421
|
function toComment(node) {
|
|
422
422
|
const typename = typeof node.__typename === "string" ? node.__typename : void 0;
|
|
423
423
|
const text = firstString(node, commentTextPaths);
|
|
424
|
-
if (!text || typename
|
|
424
|
+
if (!text || !typename || !/comment$/i.test(typename))
|
|
425
425
|
return void 0;
|
|
426
426
|
const authorName = firstString(node, commentAuthorPaths);
|
|
427
427
|
const authorAvatarUrl = firstString(node, commentAvatarPaths, false);
|
|
@@ -3218,6 +3218,7 @@ Usage:
|
|
|
3218
3218
|
diggylab install-service (systemd: start "run" on boot)
|
|
3219
3219
|
diggylab uninstall-service
|
|
3220
3220
|
diggylab status
|
|
3221
|
+
diggylab update (upgrades the installed npm package)
|
|
3221
3222
|
diggylab install-browser
|
|
3222
3223
|
diggylab unpair
|
|
3223
3224
|
|
|
@@ -3225,20 +3226,25 @@ Global options:
|
|
|
3225
3226
|
--config <directory> Agent state directory (default ~/.diggylab)
|
|
3226
3227
|
--api <origin> API origin (default $DIGGYLAB_API_URL or https://api.diggylab.com)`;
|
|
3227
3228
|
var MISSING_BROWSER_HINT = "Chromium for Playwright is not installed yet. Run `diggylab install-browser` once.";
|
|
3228
|
-
function
|
|
3229
|
+
function readAgentManifest() {
|
|
3229
3230
|
let directory = fileURLToPath(new URL(".", import.meta.url));
|
|
3230
3231
|
for (let depth = 0; depth < 4; depth += 1) {
|
|
3231
3232
|
const manifest = join4(directory, "package.json");
|
|
3232
3233
|
if (existsSync2(manifest)) {
|
|
3233
3234
|
try {
|
|
3234
|
-
const
|
|
3235
|
-
if (typeof version === "string" && version)
|
|
3235
|
+
const parsed = JSON.parse(readFileSync2(manifest, "utf8"));
|
|
3236
|
+
if (typeof parsed.version === "string" && parsed.version) {
|
|
3237
|
+
return { name: typeof parsed.name === "string" ? parsed.name : "", version: parsed.version };
|
|
3238
|
+
}
|
|
3236
3239
|
} catch {
|
|
3237
3240
|
}
|
|
3238
3241
|
}
|
|
3239
3242
|
directory = dirname3(directory);
|
|
3240
3243
|
}
|
|
3241
|
-
return "0.0.0";
|
|
3244
|
+
return { name: "", version: "0.0.0" };
|
|
3245
|
+
}
|
|
3246
|
+
function agentVersion() {
|
|
3247
|
+
return readAgentManifest().version;
|
|
3242
3248
|
}
|
|
3243
3249
|
function resolvePlatform() {
|
|
3244
3250
|
if (process.platform === "darwin") return "MACOS";
|
|
@@ -3591,6 +3597,7 @@ async function commandRun(runtime, io) {
|
|
|
3591
3597
|
io.error("This agent is not paired yet. Run `diggylab pair --code <code>` first.");
|
|
3592
3598
|
return 2;
|
|
3593
3599
|
}
|
|
3600
|
+
startUpdateRefresh(runtime.directory, io);
|
|
3594
3601
|
const recordActivity = (message, code, options = {}) => {
|
|
3595
3602
|
void runtime.activity.append({
|
|
3596
3603
|
category: options.category ?? "CONNECTION",
|
|
@@ -3748,6 +3755,119 @@ async function commandStatus(runtime, io) {
|
|
|
3748
3755
|
io.log(`Facebook: ${hasUser ? "connected" : "missing \u2014 run `diggylab login`"}`);
|
|
3749
3756
|
return 0;
|
|
3750
3757
|
}
|
|
3758
|
+
function npmExecutable() {
|
|
3759
|
+
return process.platform === "win32" ? "npm.cmd" : "npm";
|
|
3760
|
+
}
|
|
3761
|
+
function runNpm(args, capture) {
|
|
3762
|
+
return new Promise((resolve, reject) => {
|
|
3763
|
+
const child = spawn(npmExecutable(), args, {
|
|
3764
|
+
shell: process.platform === "win32",
|
|
3765
|
+
stdio: capture ? ["ignore", "pipe", "pipe"] : "inherit"
|
|
3766
|
+
});
|
|
3767
|
+
let stderr = "";
|
|
3768
|
+
let stdout = "";
|
|
3769
|
+
child.stdout?.on("data", (chunk) => {
|
|
3770
|
+
stdout += String(chunk);
|
|
3771
|
+
});
|
|
3772
|
+
child.stderr?.on("data", (chunk) => {
|
|
3773
|
+
stderr += String(chunk);
|
|
3774
|
+
});
|
|
3775
|
+
child.once("error", reject);
|
|
3776
|
+
child.once("exit", (value) => resolve({ code: value ?? 1, stderr, stdout }));
|
|
3777
|
+
});
|
|
3778
|
+
}
|
|
3779
|
+
function compareVersions(current, latest) {
|
|
3780
|
+
const currentParts = current.split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
3781
|
+
const latestParts = latest.split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
3782
|
+
for (let index = 0; index < 3; index += 1) {
|
|
3783
|
+
const difference = (currentParts[index] ?? 0) - (latestParts[index] ?? 0);
|
|
3784
|
+
if (difference !== 0) return difference;
|
|
3785
|
+
}
|
|
3786
|
+
return 0;
|
|
3787
|
+
}
|
|
3788
|
+
async function commandUpdate(options, io) {
|
|
3789
|
+
const manifest = readAgentManifest();
|
|
3790
|
+
if (manifest.name !== "diggylab") {
|
|
3791
|
+
io.error("This is a development build; update the repository instead (git pull && pnpm install).");
|
|
3792
|
+
return 1;
|
|
3793
|
+
}
|
|
3794
|
+
const directory = resolveConfigDirectory(options);
|
|
3795
|
+
let latest = "";
|
|
3796
|
+
try {
|
|
3797
|
+
const check = await runNpm(["view", "diggylab", "version", "--json"], true);
|
|
3798
|
+
if (check.code !== 0) {
|
|
3799
|
+
io.error("Could not ask npm for the latest version. Check the network and the npm registry, then try again.");
|
|
3800
|
+
if (check.stderr.trim()) io.error(check.stderr.trim());
|
|
3801
|
+
return 1;
|
|
3802
|
+
}
|
|
3803
|
+
latest = check.stdout.trim().replace(/^"(.*)"$/, "$1");
|
|
3804
|
+
} catch (error) {
|
|
3805
|
+
io.error(`Could not run npm: ${error instanceof Error ? error.message : String(error)}`);
|
|
3806
|
+
return 1;
|
|
3807
|
+
}
|
|
3808
|
+
if (!/^\d+\.\d+\.\d+/.test(latest)) {
|
|
3809
|
+
io.error(`npm returned an unexpected version "${latest.slice(0, 40)}".`);
|
|
3810
|
+
return 1;
|
|
3811
|
+
}
|
|
3812
|
+
writeUpdateCache(directory, latest);
|
|
3813
|
+
if (compareVersions(manifest.version, latest) >= 0) {
|
|
3814
|
+
io.log(`Already on the latest version (${manifest.version}).`);
|
|
3815
|
+
return 0;
|
|
3816
|
+
}
|
|
3817
|
+
io.log(`Updating diggylab ${manifest.version} -> ${latest}...`);
|
|
3818
|
+
try {
|
|
3819
|
+
const install = await runNpm(["install", "-g", "diggylab@latest"], false);
|
|
3820
|
+
if (install.code !== 0) {
|
|
3821
|
+
io.error("The npm upgrade failed. If npm reported a permissions error, fix the global prefix or run the command with sudo.");
|
|
3822
|
+
return 1;
|
|
3823
|
+
}
|
|
3824
|
+
} catch (error) {
|
|
3825
|
+
io.error(`Could not run npm: ${error instanceof Error ? error.message : String(error)}`);
|
|
3826
|
+
return 1;
|
|
3827
|
+
}
|
|
3828
|
+
io.log(`Updated to ${latest}. Start a new diggylab command to use it; a service picks it up on its next restart.`);
|
|
3829
|
+
return 0;
|
|
3830
|
+
}
|
|
3831
|
+
var UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
3832
|
+
function readUpdateCache(directory) {
|
|
3833
|
+
try {
|
|
3834
|
+
const parsed = JSON.parse(readFileSync2(join4(directory, "update-check.json"), "utf8"));
|
|
3835
|
+
if (typeof parsed.latest === "string" && /^\d+\.\d+\.\d+/.test(parsed.latest) && typeof parsed.checkedAt === "number") {
|
|
3836
|
+
return { checkedAt: parsed.checkedAt, latest: parsed.latest };
|
|
3837
|
+
}
|
|
3838
|
+
} catch {
|
|
3839
|
+
}
|
|
3840
|
+
return void 0;
|
|
3841
|
+
}
|
|
3842
|
+
function writeUpdateCache(directory, latest) {
|
|
3843
|
+
try {
|
|
3844
|
+
writeFileSync2(join4(directory, "update-check.json"), `${JSON.stringify({ checkedAt: Date.now(), latest })}
|
|
3845
|
+
`);
|
|
3846
|
+
} catch {
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
function logUpdateNotice(io, current, latest) {
|
|
3850
|
+
io.log(`A newer version is available: ${current} -> ${latest} (run \`diggylab update\`).`);
|
|
3851
|
+
}
|
|
3852
|
+
function logCachedUpdateNotice(directory, io) {
|
|
3853
|
+
const manifest = readAgentManifest();
|
|
3854
|
+
if (manifest.name !== "diggylab") return;
|
|
3855
|
+
const cache = readUpdateCache(directory);
|
|
3856
|
+
if (cache && compareVersions(manifest.version, cache.latest) < 0) logUpdateNotice(io, manifest.version, cache.latest);
|
|
3857
|
+
}
|
|
3858
|
+
function startUpdateRefresh(directory, io) {
|
|
3859
|
+
const manifest = readAgentManifest();
|
|
3860
|
+
if (manifest.name !== "diggylab") return;
|
|
3861
|
+
const cache = readUpdateCache(directory);
|
|
3862
|
+
if (cache && Date.now() - cache.checkedAt < UPDATE_CHECK_INTERVAL_MS) return;
|
|
3863
|
+
void runNpm(["view", "diggylab", "version", "--json"], true).then((check) => {
|
|
3864
|
+
if (check.code !== 0) return;
|
|
3865
|
+
const latest = check.stdout.trim().replace(/^"(.*)"$/, "$1");
|
|
3866
|
+
if (!/^\d+\.\d+\.\d+/.test(latest)) return;
|
|
3867
|
+
writeUpdateCache(directory, latest);
|
|
3868
|
+
if (compareVersions(manifest.version, latest) < 0) logUpdateNotice(io, manifest.version, latest);
|
|
3869
|
+
}).catch(() => void 0);
|
|
3870
|
+
}
|
|
3751
3871
|
async function commandUnpair(runtime, io) {
|
|
3752
3872
|
await runtime.manager.clear();
|
|
3753
3873
|
await runtime.facebook.clear();
|
|
@@ -3836,12 +3956,14 @@ async function main(argv, io = console) {
|
|
|
3836
3956
|
io.log(USAGE);
|
|
3837
3957
|
return 0;
|
|
3838
3958
|
}
|
|
3839
|
-
if (!["install-browser", "install-service", "login", "logout", "pair", "rename", "run", "status", "uninstall-service", "unpair"].includes(command)) {
|
|
3959
|
+
if (!["install-browser", "install-service", "login", "logout", "pair", "rename", "run", "status", "uninstall-service", "unpair", "update"].includes(command)) {
|
|
3840
3960
|
io.error(`Unknown command "${command}".`);
|
|
3841
3961
|
io.error(USAGE);
|
|
3842
3962
|
return 2;
|
|
3843
3963
|
}
|
|
3844
3964
|
if (command === "install-browser") return commandInstallBrowser(io);
|
|
3965
|
+
if (command === "update") return commandUpdate(parsed.options, io);
|
|
3966
|
+
logCachedUpdateNotice(resolveConfigDirectory(parsed.options), io);
|
|
3845
3967
|
const runtime = createRuntime(parsed.options);
|
|
3846
3968
|
switch (command) {
|
|
3847
3969
|
case "pair":
|