@scopebond/agent 0.3.2 → 0.4.1
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 +22 -2
- package/dist/autostart.d.ts +7 -4
- package/dist/autostart.d.ts.map +1 -1
- package/dist/autostart.js +28 -11
- package/dist/autostart.js.map +1 -1
- package/dist/cli.js +70 -17
- package/dist/cli.js.map +1 -1
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js +5 -0
- package/dist/health.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/selfcheck.d.ts.map +1 -1
- package/dist/selfcheck.js +5 -1
- package/dist/selfcheck.js.map +1 -1
- package/dist/service.d.ts +13 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +66 -4
- package/dist/service.js.map +1 -1
- package/dist/setup.d.ts +32 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +182 -0
- package/dist/setup.js.map +1 -0
- package/dist/update.d.ts +5 -0
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +26 -4
- package/dist/update.js.map +1 -1
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -30,7 +30,22 @@ agent never takes part in a decision. It only keeps everything around the decisi
|
|
|
30
30
|
|
|
31
31
|
## Use
|
|
32
32
|
|
|
33
|
+
One command from nothing to a connected computer:
|
|
34
|
+
|
|
33
35
|
```bash
|
|
36
|
+
npx -y @scopebond/agent@latest setup https://cloud.scopebond.com # Windows: npx.cmd
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`setup` checks Node.js (22.13 or later), signs you in with a code you approve in the workspace (which adds the
|
|
40
|
+
Scopebond hook to your user-level agent settings), installs the agent for your user, turns autostart on and ends with
|
|
41
|
+
`status`. Add `--cursor` or `--codex` for those tools. Run it again at any time: it keeps an existing connection to the
|
|
42
|
+
same workspace (`--relogin` signs in again), does not reinstall the same version, and only puts back what is missing.
|
|
43
|
+
If npm's global folder is not on PATH, it says which folder and how to add it.
|
|
44
|
+
|
|
45
|
+
Or step by step (from your home folder; on Windows type `npx.cmd`, `npm.cmd` and `scopebond-agent.cmd`):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx -y @scopebond/hook@latest login https://cloud.scopebond.com # sign in first: the agent delivers what the hook records
|
|
34
49
|
npm install -g @scopebond/agent@latest
|
|
35
50
|
scopebond-agent autostart on # start with your sign-in (Windows Run entry, macOS LaunchAgent, Linux systemd user unit)
|
|
36
51
|
scopebond-agent status # what it reports about this computer
|
|
@@ -42,17 +57,22 @@ For `npx` commands, use `npx.cmd`; no execution-policy change is needed.
|
|
|
42
57
|
|
|
43
58
|
| Command | What it does |
|
|
44
59
|
|---|---|
|
|
60
|
+
| `scopebond-agent setup <workspace-url>` | Sign in, install for this user, start with sign-in, show status; safe to run again |
|
|
45
61
|
| `scopebond-agent run` | Run in the foreground (what autostart starts) |
|
|
46
62
|
| `scopebond-agent status [--json]` | Delivery state, records waiting and the last problem |
|
|
47
63
|
| `scopebond-agent flush` | Deliver waiting records now |
|
|
48
64
|
| `scopebond-agent repair` | Put the Scopebond hook back into agent settings that lost it |
|
|
49
65
|
| `scopebond-agent check` | Check for updates and run the self-check now |
|
|
50
|
-
| `scopebond-agent autostart on\|off` | Start with your sign-in, or stop doing so |
|
|
66
|
+
| `scopebond-agent autostart on\|off` | Start with your sign-in, or stop doing so (off also stops it now) |
|
|
67
|
+
| `scopebond-agent stop` | Stop the running agent until the next sign-in |
|
|
68
|
+
|
|
69
|
+
The Scopebond hook stops a coding agent from switching the agent off: `autostart off`, stopping it by name and a
|
|
70
|
+
global uninstall of `@scopebond/agent` are denied when the coding agent runs them. Run them from your own terminal.
|
|
51
71
|
|
|
52
72
|
## Local control channel
|
|
53
73
|
|
|
54
74
|
The agent listens on `127.0.0.1` only, on a random port, and every request must carry a random token. Port, token and
|
|
55
|
-
process id are in `~/.scopebond/agent.json`, readable by you only. Routes: `GET /status`, `POST /flush`, `POST /repair`, `POST /maintain`, `POST /override`.
|
|
75
|
+
process id are in `~/.scopebond/agent.json`, readable by you only. Routes: `GET /status`, `POST /flush`, `POST /repair`, `POST /maintain`, `POST /override`, `POST /stop`.
|
|
56
76
|
Exactly one agent serves a computer's Scopebond home; a second one exits.
|
|
57
77
|
|
|
58
78
|
## Autostart
|
package/dist/autostart.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ export declare const LABEL = "com.scopebond.agent";
|
|
|
2
2
|
export declare function launcherPath(home: string, platform?: NodeJS.Platform): string;
|
|
3
3
|
export declare function windowsLauncher(node: string, cli: string, logFile: string): string;
|
|
4
4
|
export declare function posixLauncher(node: string, cli: string): string;
|
|
5
|
-
/** The Run value: the launcher under a headless console host, so nothing appears on screen. */
|
|
6
5
|
export declare function windowsRunCommand(launcher: string): string;
|
|
7
6
|
export declare function macLaunchAgent(launcher: string, logFile: string): string;
|
|
8
7
|
export declare function linuxUserUnit(launcher: string): string;
|
|
@@ -10,9 +9,13 @@ export declare function autostartPaths(home?: string): {
|
|
|
10
9
|
macPlist: string;
|
|
11
10
|
linuxUnit: string;
|
|
12
11
|
};
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
|
|
12
|
+
/** The ways to start the agent now on Windows, in order: the launcher under a headless console (no window,
|
|
13
|
+
* as sign-in does), then the launcher through cmd.exe with its window hidden, for a session where the
|
|
14
|
+
* headless console host does not start (seen on Windows Server). macOS and Linux start it themselves
|
|
15
|
+
* when autostart is turned on (RunAtLoad, enable --now). */
|
|
16
|
+
export declare function startCommands(launcher: string, platform?: NodeJS.Platform): Array<[string, string[]]>;
|
|
17
|
+
/** Start the agent now with the `attempt`-th way (0 first), detached from this terminal. Returns whether it tried one. */
|
|
18
|
+
export declare function startNow(scopebondHome: string, platform?: NodeJS.Platform, attempt?: number): boolean;
|
|
16
19
|
/** Turn autostart on for this user. Returns a one-line description of what changed. */
|
|
17
20
|
export declare function enableAutostart(scopebondHome: string, cli: string, node?: string, platform?: NodeJS.Platform): string;
|
|
18
21
|
export declare function disableAutostart(scopebondHome: string, platform?: NodeJS.Platform): string;
|
package/dist/autostart.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autostart.d.ts","sourceRoot":"","sources":["../src/autostart.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,KAAK,wBAAwB,CAAC;AAO3C,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,MAAM,CAE/F;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"autostart.d.ts","sourceRoot":"","sources":["../src/autostart.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,KAAK,wBAAwB,CAAC;AAO3C,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,MAAM,CAE/F;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAkBlF;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAkB/D;AAOD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAexE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CActD;AAED,wBAAgB,cAAc,CAAC,IAAI,SAAY;;;EAK9C;AAWD;;;6DAG6D;AAC7D,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAIvH;AAED,0HAA0H;AAC1H,wBAAgB,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,kBAAmB,EAAE,OAAO,SAAI,GAAG,OAAO,CAUjG;AAED,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,SAAmB,EAAE,QAAQ,kBAAmB,GAAG,MAAM,CAkBhI;AAED,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,kBAAmB,GAAG,MAAM,CAiB3F;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,kBAAmB,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAWhI"}
|
package/dist/autostart.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { execFileSync, spawn } from "node:child_process";
|
|
9
9
|
import { chmodSync, existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { homedir } from "node:os";
|
|
11
|
-
import { dirname, join } from "node:path";
|
|
11
|
+
import { dirname, join, win32 } from "node:path";
|
|
12
12
|
export const LABEL = "com.scopebond.agent";
|
|
13
13
|
const RUN_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
|
|
14
14
|
const RUN_VALUE = "ScopebondAgent";
|
|
@@ -20,6 +20,9 @@ export function launcherPath(home, platform = process.platform) {
|
|
|
20
20
|
export function windowsLauncher(node, cli, logFile) {
|
|
21
21
|
return [
|
|
22
22
|
"@echo off",
|
|
23
|
+
// cmd.exe reads a batch file in the console code page: switch to UTF-8 first, so a profile folder
|
|
24
|
+
// with non-ASCII letters in the paths below reads as written.
|
|
25
|
+
"chcp 65001 >nul",
|
|
23
26
|
"rem Scopebond Agent launcher: finds Node and the agent each time, so a Node upgrade never stops it.",
|
|
24
27
|
"setlocal",
|
|
25
28
|
`set "NODE=${noQuotes(node)}"`,
|
|
@@ -28,7 +31,8 @@ export function windowsLauncher(node, cli, logFile) {
|
|
|
28
31
|
`set "CLI=${noQuotes(cli)}"`,
|
|
29
32
|
`if not exist "%CLI%" for /f "delims=" %%i in ('npm.cmd root -g 2^>nul') do set "CLI=%%i\\@scopebond\\agent\\dist\\cli.js"`,
|
|
30
33
|
`if not defined NODE exit /b 1`,
|
|
31
|
-
|
|
34
|
+
// The log sits beside this launcher; %~dp0 keeps it right whatever the folder is called.
|
|
35
|
+
`"%NODE%" --disable-warning=ExperimentalWarning "%CLI%" run >> "%~dp0${win32.basename(noQuotes(logFile))}" 2>&1`,
|
|
32
36
|
"",
|
|
33
37
|
].join("\r\n");
|
|
34
38
|
}
|
|
@@ -52,8 +56,11 @@ exec "$NODE" --disable-warning=ExperimentalWarning "$CLI" run
|
|
|
52
56
|
`;
|
|
53
57
|
}
|
|
54
58
|
/** The Run value: the launcher under a headless console host, so nothing appears on screen. */
|
|
59
|
+
/** `cmd /s /c ""<launcher>""`: cmd drops only the outer quotes and runs the quoted path as it is, so a
|
|
60
|
+
* profile folder with a space and a `(`, `)` or `&` ("John (Work)") still starts the launcher. */
|
|
61
|
+
const cmdRun = (launcher) => `/d /s /c ""${noQuotes(launcher)}""`;
|
|
55
62
|
export function windowsRunCommand(launcher) {
|
|
56
|
-
return `conhost.exe --headless cmd.exe
|
|
63
|
+
return `conhost.exe --headless cmd.exe ${cmdRun(launcher)}`;
|
|
57
64
|
}
|
|
58
65
|
export function macLaunchAgent(launcher, logFile) {
|
|
59
66
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -101,16 +108,24 @@ function writeLauncher(scopebondHome, node, cli, platform) {
|
|
|
101
108
|
chmodSync(launcher, 0o700);
|
|
102
109
|
return launcher;
|
|
103
110
|
}
|
|
104
|
-
/**
|
|
105
|
-
*
|
|
106
|
-
|
|
111
|
+
/** The ways to start the agent now on Windows, in order: the launcher under a headless console (no window,
|
|
112
|
+
* as sign-in does), then the launcher through cmd.exe with its window hidden, for a session where the
|
|
113
|
+
* headless console host does not start (seen on Windows Server). macOS and Linux start it themselves
|
|
114
|
+
* when autostart is turned on (RunAtLoad, enable --now). */
|
|
115
|
+
export function startCommands(launcher, platform = process.platform) {
|
|
107
116
|
if (platform !== "win32")
|
|
108
|
-
return
|
|
117
|
+
return [];
|
|
118
|
+
// Passed verbatim (startNow sets windowsVerbatimArguments): Node's own quoting follows other rules than cmd's.
|
|
119
|
+
return [["conhost.exe", ["--headless", "cmd.exe", cmdRun(launcher)]], ["cmd.exe", [cmdRun(launcher)]]];
|
|
120
|
+
}
|
|
121
|
+
/** Start the agent now with the `attempt`-th way (0 first), detached from this terminal. Returns whether it tried one. */
|
|
122
|
+
export function startNow(scopebondHome, platform = process.platform, attempt = 0) {
|
|
109
123
|
const launcher = launcherPath(scopebondHome, platform);
|
|
110
|
-
|
|
124
|
+
const command = startCommands(launcher, platform)[attempt];
|
|
125
|
+
if (!command || !existsSync(launcher))
|
|
111
126
|
return false;
|
|
112
127
|
try {
|
|
113
|
-
const child = spawn(
|
|
128
|
+
const child = spawn(command[0], command[1], { detached: true, stdio: "ignore", windowsHide: true, windowsVerbatimArguments: true });
|
|
114
129
|
child.on("error", () => { });
|
|
115
130
|
child.unref();
|
|
116
131
|
return true;
|
|
@@ -193,10 +208,12 @@ export function autostartHealth(scopebondHome, platform = process.platform) {
|
|
|
193
208
|
}
|
|
194
209
|
else
|
|
195
210
|
on = existsSync(platform === "darwin" ? paths.macPlist : paths.linuxUnit);
|
|
211
|
+
// The fix as the person types it: PowerShell blocks the plain scopebond-agent script shim.
|
|
212
|
+
const fix = `${platform === "win32" ? "scopebond-agent.cmd" : "scopebond-agent"} autostart on`;
|
|
196
213
|
if (!on)
|
|
197
|
-
return { on, ok: false, detail:
|
|
214
|
+
return { on, ok: false, detail: `the agent does not start with sign-in (run: ${fix})` };
|
|
198
215
|
if (!existsSync(launcherPath(scopebondHome, platform)))
|
|
199
|
-
return { on, ok: false, detail:
|
|
216
|
+
return { on, ok: false, detail: `the autostart launcher is missing (run: ${fix})` };
|
|
200
217
|
return { on, ok: true, detail: "starts with sign-in" };
|
|
201
218
|
}
|
|
202
219
|
//# sourceMappingURL=autostart.js.map
|
package/dist/autostart.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autostart.js","sourceRoot":"","sources":["../src/autostart.ts"],"names":[],"mappings":"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","sourcesContent":["// Start the agent when the person signs in to the computer, per user, with no administrator\n// rights: a Run entry on Windows, a LaunchAgent on macOS, a systemd user unit on Linux.\n//\n// Each of them starts a small launcher script in the Scopebond home, not Node directly. The\n// launcher finds Node and the agent when it runs (the recorded paths first, then the system's),\n// so upgrading Node or switching versions never leaves an autostart entry pointing at nothing.\n// On Windows it runs under `conhost --headless`, so no window opens at sign-in.\n\nimport { execFileSync, spawn } from \"node:child_process\";\nimport { chmodSync, existsSync, mkdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport const LABEL = \"com.scopebond.agent\";\nconst RUN_KEY = \"HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\";\nconst RUN_VALUE = \"ScopebondAgent\";\n\nconst xml = (s: string) => s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\nconst noQuotes = (s: string) => s.replace(/\"/g, \"\");\n\nexport function launcherPath(home: string, platform: NodeJS.Platform = process.platform): string {\n return join(home, platform === \"win32\" ? \"agent-launch.cmd\" : \"agent-launch.sh\");\n}\n\nexport function windowsLauncher(node: string, cli: string, logFile: string): string {\n return [\n \"@echo off\",\n \"rem Scopebond Agent launcher: finds Node and the agent each time, so a Node upgrade never stops it.\",\n \"setlocal\",\n `set \"NODE=${noQuotes(node)}\"`,\n `if not exist \"%NODE%\" set \"NODE=\"`,\n `if not defined NODE for /f \"delims=\" %%i in ('where node 2^>nul') do if not defined NODE set \"NODE=%%i\"`,\n `set \"CLI=${noQuotes(cli)}\"`,\n `if not exist \"%CLI%\" for /f \"delims=\" %%i in ('npm.cmd root -g 2^>nul') do set \"CLI=%%i\\\\@scopebond\\\\agent\\\\dist\\\\cli.js\"`,\n `if not defined NODE exit /b 1`,\n `\"%NODE%\" --disable-warning=ExperimentalWarning \"%CLI%\" run >> \"${noQuotes(logFile)}\" 2>&1`,\n \"\",\n ].join(\"\\r\\n\");\n}\n\nexport function posixLauncher(node: string, cli: string): string {\n const q = (s: string) => `'${s.replace(/'/g, \"'\\\\''\")}'`;\n return `#!/bin/sh\n# Scopebond Agent launcher: finds Node and the agent each time, so a Node upgrade never stops it.\nNODE=${q(node)}\nif [ ! -x \"$NODE\" ]; then\n [ -s \"$HOME/.nvm/nvm.sh\" ] && . \"$HOME/.nvm/nvm.sh\" >/dev/null 2>&1\n NODE=\"$(command -v node 2>/dev/null)\"\n for candidate in /opt/homebrew/bin/node /usr/local/bin/node /usr/bin/node; do\n [ -n \"$NODE\" ] && break\n [ -x \"$candidate\" ] && NODE=\"$candidate\"\n done\nfi\nCLI=${q(cli)}\n[ -f \"$CLI\" ] || CLI=\"$(npm root -g 2>/dev/null)/@scopebond/agent/dist/cli.js\"\n[ -n \"$NODE\" ] || exit 1\nexec \"$NODE\" --disable-warning=ExperimentalWarning \"$CLI\" run\n`;\n}\n\n/** The Run value: the launcher under a headless console host, so nothing appears on screen. */\nexport function windowsRunCommand(launcher: string): string {\n return `conhost.exe --headless cmd.exe /d /c \"${noQuotes(launcher)}\"`;\n}\n\nexport function macLaunchAgent(launcher: string, logFile: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key><string>${LABEL}</string>\n <key>ProgramArguments</key>\n <array><string>/bin/sh</string><string>${xml(launcher)}</string></array>\n <key>RunAtLoad</key><true/>\n <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>\n <key>StandardOutPath</key><string>${xml(logFile)}</string>\n <key>StandardErrorPath</key><string>${xml(logFile)}</string>\n</dict>\n</plist>\n`;\n}\n\nexport function linuxUserUnit(launcher: string): string {\n const q = (s: string) => `\"${s.replace(/([\"\\\\])/g, \"\\\\$1\")}\"`;\n return `[Unit]\nDescription=Scopebond Agent (delivers this computer's records to its Scopebond workspace)\nAfter=network-online.target\n\n[Service]\nExecStart=/bin/sh ${q(launcher)}\nRestart=on-failure\nRestartSec=30\n\n[Install]\nWantedBy=default.target\n`;\n}\n\nexport function autostartPaths(home = homedir()) {\n return {\n macPlist: join(home, \"Library\", \"LaunchAgents\", `${LABEL}.plist`),\n linuxUnit: join(home, \".config\", \"systemd\", \"user\", \"scopebond-agent.service\"),\n };\n}\n\nfunction writeLauncher(scopebondHome: string, node: string, cli: string, platform: NodeJS.Platform): string {\n mkdirSync(scopebondHome, { recursive: true });\n const launcher = launcherPath(scopebondHome, platform);\n const log = join(scopebondHome, \"agent.log\");\n writeFileSync(launcher, platform === \"win32\" ? windowsLauncher(node, cli, log) : posixLauncher(node, cli), { mode: 0o700 });\n if (platform !== \"win32\") chmodSync(launcher, 0o700);\n return launcher;\n}\n\n/** Start the agent now, the way sign-in will (Windows: the launcher under a headless console, detached from this terminal).\n * macOS and Linux start it themselves when autostart is turned on (RunAtLoad, enable --now). Returns whether it started one. */\nexport function startNow(scopebondHome: string, platform = process.platform): boolean {\n if (platform !== \"win32\") return false;\n const launcher = launcherPath(scopebondHome, platform);\n if (!existsSync(launcher)) return false;\n try {\n const child = spawn(\"conhost.exe\", [\"--headless\", \"cmd.exe\", \"/d\", \"/c\", launcher], { detached: true, stdio: \"ignore\", windowsHide: true });\n child.on(\"error\", () => { /* it starts at the next sign-in instead */ });\n child.unref();\n return true;\n } catch { return false; }\n}\n\n/** Turn autostart on for this user. Returns a one-line description of what changed. */\nexport function enableAutostart(scopebondHome: string, cli: string, node = process.execPath, platform = process.platform): string {\n const launcher = writeLauncher(scopebondHome, node, cli, platform);\n const paths = autostartPaths();\n if (platform === \"win32\") {\n execFileSync(\"reg\", [\"add\", RUN_KEY, \"/v\", RUN_VALUE, \"/t\", \"REG_SZ\", \"/d\", windowsRunCommand(launcher), \"/f\"], { stdio: \"ignore\" });\n return `added ${RUN_VALUE} to ${RUN_KEY} (launcher ${launcher})`;\n }\n if (platform === \"darwin\") {\n mkdirSync(dirname(paths.macPlist), { recursive: true });\n writeFileSync(paths.macPlist, macLaunchAgent(launcher, join(scopebondHome, \"agent.log\")));\n try { execFileSync(\"launchctl\", [\"load\", \"-w\", paths.macPlist], { stdio: \"ignore\" }); } catch { /* loads at next sign-in */ }\n return `wrote ${paths.macPlist}`;\n }\n mkdirSync(dirname(paths.linuxUnit), { recursive: true });\n writeFileSync(paths.linuxUnit, linuxUserUnit(launcher));\n try { execFileSync(\"systemctl\", [\"--user\", \"daemon-reload\"], { stdio: \"ignore\" }); execFileSync(\"systemctl\", [\"--user\", \"enable\", \"--now\", \"scopebond-agent.service\"], { stdio: \"ignore\" }); }\n catch { return `wrote ${paths.linuxUnit} (enable it with: systemctl --user enable --now scopebond-agent)`; }\n return `wrote and enabled ${paths.linuxUnit}`;\n}\n\nexport function disableAutostart(scopebondHome: string, platform = process.platform): string {\n const paths = autostartPaths();\n rmSync(launcherPath(scopebondHome, platform), { force: true });\n if (platform === \"win32\") {\n try { execFileSync(\"reg\", [\"delete\", RUN_KEY, \"/v\", RUN_VALUE, \"/f\"], { stdio: \"ignore\" }); } catch { return \"autostart was not on\"; }\n return `removed ${RUN_VALUE} from ${RUN_KEY}`;\n }\n if (platform === \"darwin\") {\n if (!existsSync(paths.macPlist)) return \"autostart was not on\";\n try { execFileSync(\"launchctl\", [\"unload\", \"-w\", paths.macPlist], { stdio: \"ignore\" }); } catch { /* not loaded */ }\n rmSync(paths.macPlist, { force: true });\n return `removed ${paths.macPlist}`;\n }\n if (!existsSync(paths.linuxUnit)) return \"autostart was not on\";\n try { execFileSync(\"systemctl\", [\"--user\", \"disable\", \"--now\", \"scopebond-agent.service\"], { stdio: \"ignore\" }); } catch { /* not enabled */ }\n rmSync(paths.linuxUnit, { force: true });\n return `removed ${paths.linuxUnit}`;\n}\n\n/** Whether autostart is on and its launcher can start the agent now. */\nexport function autostartHealth(scopebondHome: string, platform = process.platform): { on: boolean; ok: boolean; detail: string } {\n const paths = autostartPaths();\n let on = false;\n if (platform === \"win32\") {\n try { execFileSync(\"reg\", [\"query\", RUN_KEY, \"/v\", RUN_VALUE], { stdio: \"ignore\" }); on = true; } catch { on = false; }\n } else on = existsSync(platform === \"darwin\" ? paths.macPlist : paths.linuxUnit);\n if (!on) return { on, ok: false, detail: \"the agent does not start with sign-in (run: scopebond-agent autostart on)\" };\n if (!existsSync(launcherPath(scopebondHome, platform))) return { on, ok: false, detail: \"the autostart launcher is missing (run: scopebond-agent autostart on)\" };\n return { on, ok: true, detail: \"starts with sign-in\" };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"autostart.js","sourceRoot":"","sources":["../src/autostart.ts"],"names":[],"mappings":"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","sourcesContent":["// Start the agent when the person signs in to the computer, per user, with no administrator\n// rights: a Run entry on Windows, a LaunchAgent on macOS, a systemd user unit on Linux.\n//\n// Each of them starts a small launcher script in the Scopebond home, not Node directly. The\n// launcher finds Node and the agent when it runs (the recorded paths first, then the system's),\n// so upgrading Node or switching versions never leaves an autostart entry pointing at nothing.\n// On Windows it runs under `conhost --headless`, so no window opens at sign-in.\n\nimport { execFileSync, spawn } from \"node:child_process\";\nimport { chmodSync, existsSync, mkdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, win32 } from \"node:path\";\n\nexport const LABEL = \"com.scopebond.agent\";\nconst RUN_KEY = \"HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\";\nconst RUN_VALUE = \"ScopebondAgent\";\n\nconst xml = (s: string) => s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\nconst noQuotes = (s: string) => s.replace(/\"/g, \"\");\n\nexport function launcherPath(home: string, platform: NodeJS.Platform = process.platform): string {\n return join(home, platform === \"win32\" ? \"agent-launch.cmd\" : \"agent-launch.sh\");\n}\n\nexport function windowsLauncher(node: string, cli: string, logFile: string): string {\n return [\n \"@echo off\",\n // cmd.exe reads a batch file in the console code page: switch to UTF-8 first, so a profile folder\n // with non-ASCII letters in the paths below reads as written.\n \"chcp 65001 >nul\",\n \"rem Scopebond Agent launcher: finds Node and the agent each time, so a Node upgrade never stops it.\",\n \"setlocal\",\n `set \"NODE=${noQuotes(node)}\"`,\n `if not exist \"%NODE%\" set \"NODE=\"`,\n `if not defined NODE for /f \"delims=\" %%i in ('where node 2^>nul') do if not defined NODE set \"NODE=%%i\"`,\n `set \"CLI=${noQuotes(cli)}\"`,\n `if not exist \"%CLI%\" for /f \"delims=\" %%i in ('npm.cmd root -g 2^>nul') do set \"CLI=%%i\\\\@scopebond\\\\agent\\\\dist\\\\cli.js\"`,\n `if not defined NODE exit /b 1`,\n // The log sits beside this launcher; %~dp0 keeps it right whatever the folder is called.\n `\"%NODE%\" --disable-warning=ExperimentalWarning \"%CLI%\" run >> \"%~dp0${win32.basename(noQuotes(logFile))}\" 2>&1`,\n \"\",\n ].join(\"\\r\\n\");\n}\n\nexport function posixLauncher(node: string, cli: string): string {\n const q = (s: string) => `'${s.replace(/'/g, \"'\\\\''\")}'`;\n return `#!/bin/sh\n# Scopebond Agent launcher: finds Node and the agent each time, so a Node upgrade never stops it.\nNODE=${q(node)}\nif [ ! -x \"$NODE\" ]; then\n [ -s \"$HOME/.nvm/nvm.sh\" ] && . \"$HOME/.nvm/nvm.sh\" >/dev/null 2>&1\n NODE=\"$(command -v node 2>/dev/null)\"\n for candidate in /opt/homebrew/bin/node /usr/local/bin/node /usr/bin/node; do\n [ -n \"$NODE\" ] && break\n [ -x \"$candidate\" ] && NODE=\"$candidate\"\n done\nfi\nCLI=${q(cli)}\n[ -f \"$CLI\" ] || CLI=\"$(npm root -g 2>/dev/null)/@scopebond/agent/dist/cli.js\"\n[ -n \"$NODE\" ] || exit 1\nexec \"$NODE\" --disable-warning=ExperimentalWarning \"$CLI\" run\n`;\n}\n\n/** The Run value: the launcher under a headless console host, so nothing appears on screen. */\n/** `cmd /s /c \"\"<launcher>\"\"`: cmd drops only the outer quotes and runs the quoted path as it is, so a\n * profile folder with a space and a `(`, `)` or `&` (\"John (Work)\") still starts the launcher. */\nconst cmdRun = (launcher: string) => `/d /s /c \"\"${noQuotes(launcher)}\"\"`;\n\nexport function windowsRunCommand(launcher: string): string {\n return `conhost.exe --headless cmd.exe ${cmdRun(launcher)}`;\n}\n\nexport function macLaunchAgent(launcher: string, logFile: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key><string>${LABEL}</string>\n <key>ProgramArguments</key>\n <array><string>/bin/sh</string><string>${xml(launcher)}</string></array>\n <key>RunAtLoad</key><true/>\n <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>\n <key>StandardOutPath</key><string>${xml(logFile)}</string>\n <key>StandardErrorPath</key><string>${xml(logFile)}</string>\n</dict>\n</plist>\n`;\n}\n\nexport function linuxUserUnit(launcher: string): string {\n const q = (s: string) => `\"${s.replace(/([\"\\\\])/g, \"\\\\$1\")}\"`;\n return `[Unit]\nDescription=Scopebond Agent (delivers this computer's records to its Scopebond workspace)\nAfter=network-online.target\n\n[Service]\nExecStart=/bin/sh ${q(launcher)}\nRestart=on-failure\nRestartSec=30\n\n[Install]\nWantedBy=default.target\n`;\n}\n\nexport function autostartPaths(home = homedir()) {\n return {\n macPlist: join(home, \"Library\", \"LaunchAgents\", `${LABEL}.plist`),\n linuxUnit: join(home, \".config\", \"systemd\", \"user\", \"scopebond-agent.service\"),\n };\n}\n\nfunction writeLauncher(scopebondHome: string, node: string, cli: string, platform: NodeJS.Platform): string {\n mkdirSync(scopebondHome, { recursive: true });\n const launcher = launcherPath(scopebondHome, platform);\n const log = join(scopebondHome, \"agent.log\");\n writeFileSync(launcher, platform === \"win32\" ? windowsLauncher(node, cli, log) : posixLauncher(node, cli), { mode: 0o700 });\n if (platform !== \"win32\") chmodSync(launcher, 0o700);\n return launcher;\n}\n\n/** The ways to start the agent now on Windows, in order: the launcher under a headless console (no window,\n * as sign-in does), then the launcher through cmd.exe with its window hidden, for a session where the\n * headless console host does not start (seen on Windows Server). macOS and Linux start it themselves\n * when autostart is turned on (RunAtLoad, enable --now). */\nexport function startCommands(launcher: string, platform: NodeJS.Platform = process.platform): Array<[string, string[]]> {\n if (platform !== \"win32\") return [];\n // Passed verbatim (startNow sets windowsVerbatimArguments): Node's own quoting follows other rules than cmd's.\n return [[\"conhost.exe\", [\"--headless\", \"cmd.exe\", cmdRun(launcher)]], [\"cmd.exe\", [cmdRun(launcher)]]];\n}\n\n/** Start the agent now with the `attempt`-th way (0 first), detached from this terminal. Returns whether it tried one. */\nexport function startNow(scopebondHome: string, platform = process.platform, attempt = 0): boolean {\n const launcher = launcherPath(scopebondHome, platform);\n const command = startCommands(launcher, platform)[attempt];\n if (!command || !existsSync(launcher)) return false;\n try {\n const child = spawn(command[0], command[1], { detached: true, stdio: \"ignore\", windowsHide: true, windowsVerbatimArguments: true });\n child.on(\"error\", () => { /* the next way, or the next sign-in */ });\n child.unref();\n return true;\n } catch { return false; }\n}\n\n/** Turn autostart on for this user. Returns a one-line description of what changed. */\nexport function enableAutostart(scopebondHome: string, cli: string, node = process.execPath, platform = process.platform): string {\n const launcher = writeLauncher(scopebondHome, node, cli, platform);\n const paths = autostartPaths();\n if (platform === \"win32\") {\n execFileSync(\"reg\", [\"add\", RUN_KEY, \"/v\", RUN_VALUE, \"/t\", \"REG_SZ\", \"/d\", windowsRunCommand(launcher), \"/f\"], { stdio: \"ignore\" });\n return `added ${RUN_VALUE} to ${RUN_KEY} (launcher ${launcher})`;\n }\n if (platform === \"darwin\") {\n mkdirSync(dirname(paths.macPlist), { recursive: true });\n writeFileSync(paths.macPlist, macLaunchAgent(launcher, join(scopebondHome, \"agent.log\")));\n try { execFileSync(\"launchctl\", [\"load\", \"-w\", paths.macPlist], { stdio: \"ignore\" }); } catch { /* loads at next sign-in */ }\n return `wrote ${paths.macPlist}`;\n }\n mkdirSync(dirname(paths.linuxUnit), { recursive: true });\n writeFileSync(paths.linuxUnit, linuxUserUnit(launcher));\n try { execFileSync(\"systemctl\", [\"--user\", \"daemon-reload\"], { stdio: \"ignore\" }); execFileSync(\"systemctl\", [\"--user\", \"enable\", \"--now\", \"scopebond-agent.service\"], { stdio: \"ignore\" }); }\n catch { return `wrote ${paths.linuxUnit} (enable it with: systemctl --user enable --now scopebond-agent)`; }\n return `wrote and enabled ${paths.linuxUnit}`;\n}\n\nexport function disableAutostart(scopebondHome: string, platform = process.platform): string {\n const paths = autostartPaths();\n rmSync(launcherPath(scopebondHome, platform), { force: true });\n if (platform === \"win32\") {\n try { execFileSync(\"reg\", [\"delete\", RUN_KEY, \"/v\", RUN_VALUE, \"/f\"], { stdio: \"ignore\" }); } catch { return \"autostart was not on\"; }\n return `removed ${RUN_VALUE} from ${RUN_KEY}`;\n }\n if (platform === \"darwin\") {\n if (!existsSync(paths.macPlist)) return \"autostart was not on\";\n try { execFileSync(\"launchctl\", [\"unload\", \"-w\", paths.macPlist], { stdio: \"ignore\" }); } catch { /* not loaded */ }\n rmSync(paths.macPlist, { force: true });\n return `removed ${paths.macPlist}`;\n }\n if (!existsSync(paths.linuxUnit)) return \"autostart was not on\";\n try { execFileSync(\"systemctl\", [\"--user\", \"disable\", \"--now\", \"scopebond-agent.service\"], { stdio: \"ignore\" }); } catch { /* not enabled */ }\n rmSync(paths.linuxUnit, { force: true });\n return `removed ${paths.linuxUnit}`;\n}\n\n/** Whether autostart is on and its launcher can start the agent now. */\nexport function autostartHealth(scopebondHome: string, platform = process.platform): { on: boolean; ok: boolean; detail: string } {\n const paths = autostartPaths();\n let on = false;\n if (platform === \"win32\") {\n try { execFileSync(\"reg\", [\"query\", RUN_KEY, \"/v\", RUN_VALUE], { stdio: \"ignore\" }); on = true; } catch { on = false; }\n } else on = existsSync(platform === \"darwin\" ? paths.macPlist : paths.linuxUnit);\n // The fix as the person types it: PowerShell blocks the plain scopebond-agent script shim.\n const fix = `${platform === \"win32\" ? \"scopebond-agent.cmd\" : \"scopebond-agent\"} autostart on`;\n if (!on) return { on, ok: false, detail: `the agent does not start with sign-in (run: ${fix})` };\n if (!existsSync(launcherPath(scopebondHome, platform))) return { on, ok: false, detail: `the autostart launcher is missing (run: ${fix})` };\n return { on, ok: true, detail: \"starts with sign-in\" };\n}\n"]}
|
package/dist/cli.js
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// scopebond-agent: run, look at and control the Scopebond Agent for this user.
|
|
3
3
|
//
|
|
4
|
+
// scopebond-agent setup <workspace-url> [--claude|--cursor|--codex] [--relogin]
|
|
5
|
+
// one command to start: sign in, install, autostart, status
|
|
4
6
|
// scopebond-agent run run in the foreground (what autostart starts)
|
|
5
7
|
// scopebond-agent status [--json] what the running agent reports, or why it is not running
|
|
6
8
|
// scopebond-agent flush deliver now
|
|
7
9
|
// scopebond-agent repair put the Scopebond hook back where agent settings lost it
|
|
8
10
|
// scopebond-agent check update check, hook upkeep and the end-to-end self-check, now
|
|
9
|
-
// scopebond-agent autostart on|off start with this user's sign-in, or stop doing so
|
|
11
|
+
// scopebond-agent autostart on|off start with this user's sign-in, or stop doing so (off also stops it now)
|
|
12
|
+
// scopebond-agent stop stop the running agent (autostart still starts it at the next sign-in)
|
|
10
13
|
import { realpathSync } from "node:fs";
|
|
11
14
|
import { fileURLToPath } from "node:url";
|
|
12
15
|
import { isEphemeralPath, userHome } from "@scopebond/hook";
|
|
13
16
|
import { computerStatus } from "./agent.js";
|
|
14
17
|
import { autostartHealth, disableAutostart, enableAutostart, startNow } from "./autostart.js";
|
|
15
18
|
import { callAgent } from "./ipc.js";
|
|
19
|
+
import { runSetup } from "./setup.js";
|
|
20
|
+
import { agentVersion } from "./update.js";
|
|
16
21
|
import { AFTER_PID_ENV, AGENT_VERSION, startService } from "./service.js";
|
|
17
22
|
const [cmd = "help", ...rest] = process.argv.slice(2);
|
|
18
23
|
// What a person types here: on Windows, PowerShell blocks the plain name's script shim.
|
|
@@ -20,14 +25,17 @@ const me = process.platform === "win32" ? "scopebond-agent.cmd" : "scopebond-age
|
|
|
20
25
|
const dir = process.env.SCOPEBOND_HOME ?? userHome();
|
|
21
26
|
const cliPath = realpathSync(fileURLToPath(import.meta.url));
|
|
22
27
|
function help() {
|
|
28
|
+
const c = (sub) => `${me} ${sub}`.padEnd(me.length + 36);
|
|
23
29
|
console.log(`Scopebond Agent — keeps this computer delivering to its Scopebond workspace.
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
${c("setup <workspace-url>")}sign in, install for this user, start with sign-in, show status
|
|
32
|
+
${c("run")}run in the foreground (what autostart starts)
|
|
33
|
+
${c("status [--json]")}what the agent reports about this computer
|
|
34
|
+
${c("flush")}deliver waiting records now
|
|
35
|
+
${c("repair")}put the Scopebond hook back where agent settings lost it
|
|
36
|
+
${c("check")}check for updates and run the end-to-end self-check now
|
|
37
|
+
${c("autostart on|off")}start with your sign-in, or stop doing so (off also stops it now)
|
|
38
|
+
${c("stop")}stop the running agent until the next sign-in
|
|
31
39
|
|
|
32
40
|
The hook keeps deciding every action on its own; the agent only keeps delivery, rules and the
|
|
33
41
|
connection current. Home: ${dir}`);
|
|
@@ -39,7 +47,7 @@ async function main() {
|
|
|
39
47
|
const previous = Number(process.env[AFTER_PID_ENV]);
|
|
40
48
|
if (Number.isInteger(previous) && previous > 0)
|
|
41
49
|
await waitForExit(previous, 30_000);
|
|
42
|
-
const service = await startService({ dir });
|
|
50
|
+
const service = await startService({ dir, onStopped: () => process.exit(0) });
|
|
43
51
|
const stop = () => { void service.stop().finally(() => process.exit(0)); };
|
|
44
52
|
process.on("SIGINT", stop);
|
|
45
53
|
process.on("SIGTERM", stop);
|
|
@@ -80,33 +88,67 @@ async function main() {
|
|
|
80
88
|
console.log(JSON.stringify(answer, null, 2));
|
|
81
89
|
return;
|
|
82
90
|
}
|
|
91
|
+
case "setup": {
|
|
92
|
+
const target = rest.find((a) => !a.startsWith("--"));
|
|
93
|
+
let origin = null;
|
|
94
|
+
try {
|
|
95
|
+
const url = new URL(target ?? "");
|
|
96
|
+
const local = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
|
|
97
|
+
if (url.protocol === "https:" || (local && url.protocol === "http:"))
|
|
98
|
+
origin = url.origin;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
origin = null;
|
|
102
|
+
}
|
|
103
|
+
if (!origin) {
|
|
104
|
+
console.error(`usage: ${process.platform === "win32" ? "npx.cmd" : "npx"} -y @scopebond/agent@${agentVersion()} setup <workspace-url> [--claude|--cursor|--codex]`);
|
|
105
|
+
console.error("The workspace URL is the address of your Scopebond workspace, for example https://cloud.scopebond.com.");
|
|
106
|
+
process.exitCode = 1;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const harness = rest.includes("--cursor") ? "cursor" : rest.includes("--codex") ? "codex" : "claude";
|
|
110
|
+
process.exitCode = await runSetup({ dir, origin, harness, relogin: rest.includes("--relogin"), version: agentVersion(), me });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
case "stop": {
|
|
114
|
+
console.log(await stopRunning() ? "Stopped the Scopebond Agent." : "The Scopebond Agent was not running.");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
83
117
|
case "autostart": {
|
|
84
118
|
const on = rest[0] === "on";
|
|
85
119
|
if (rest[0] !== "on" && rest[0] !== "off") {
|
|
86
|
-
console.error(
|
|
120
|
+
console.error(`usage: ${me} autostart on|off`);
|
|
87
121
|
process.exitCode = 1;
|
|
88
122
|
return;
|
|
89
123
|
}
|
|
90
124
|
if (on && isEphemeralPath(cliPath)) {
|
|
91
125
|
// npx runs from a cache npm clears; an autostart entry pointing there would stop working.
|
|
92
|
-
console.error(
|
|
126
|
+
console.error(`Install the agent first so autostart has a stable path: ${process.platform === "win32" ? "npm.cmd" : "npm"} install -g @scopebond/agent`);
|
|
93
127
|
process.exitCode = 1;
|
|
94
128
|
return;
|
|
95
129
|
}
|
|
96
130
|
console.log(on ? enableAutostart(dir, cliPath) : disableAutostart(dir));
|
|
97
|
-
if (!on)
|
|
131
|
+
if (!on) {
|
|
132
|
+
// Off means off: an agent left running would keep going until sign-out, even after an uninstall.
|
|
133
|
+
if (await stopRunning())
|
|
134
|
+
console.log("Stopped the running Scopebond Agent.");
|
|
98
135
|
return;
|
|
136
|
+
}
|
|
99
137
|
// Turning autostart on also starts the agent now, so nobody has to sign out and in again.
|
|
100
138
|
if (await callAgent(dir, "GET", "/status", undefined, 2_000)) {
|
|
101
139
|
console.log("The Scopebond Agent is running.");
|
|
102
140
|
return;
|
|
103
141
|
}
|
|
104
|
-
|
|
105
|
-
for (let
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
142
|
+
// Each way of starting it gets a few seconds; a headless console that never starts falls back to a hidden cmd.exe.
|
|
143
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
144
|
+
if (!startNow(dir, process.platform, attempt) && attempt > 0)
|
|
145
|
+
break;
|
|
146
|
+
for (let i = 0; i < (attempt === 0 ? 12 : 18); i++) {
|
|
147
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
148
|
+
if (await callAgent(dir, "GET", "/status", undefined, 1_000)) {
|
|
149
|
+
console.log(`The Scopebond Agent is running${process.platform === "win32" ? "; its icon is in the taskbar tray (it may be under the ^ arrow)" : ""}.`);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
110
152
|
}
|
|
111
153
|
}
|
|
112
154
|
console.log(`It starts at your next sign-in. To start it now: ${me} run`);
|
|
@@ -118,6 +160,17 @@ async function main() {
|
|
|
118
160
|
process.exitCode = 1;
|
|
119
161
|
}
|
|
120
162
|
}
|
|
163
|
+
/** Ask the running agent to stop and wait until its control channel is gone. Whether one was running. */
|
|
164
|
+
async function stopRunning() {
|
|
165
|
+
if (!await callAgent(dir, "POST", "/stop", {}, 3_000))
|
|
166
|
+
return false;
|
|
167
|
+
for (let i = 0; i < 40; i++) {
|
|
168
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
169
|
+
if (!await callAgent(dir, "GET", "/status", undefined, 1_000))
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
121
174
|
async function waitForExit(pid, timeoutMs) {
|
|
122
175
|
const until = Date.now() + timeoutMs;
|
|
123
176
|
while (Date.now() < until) {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// scopebond-agent: run, look at and control the Scopebond Agent for this user.\n//\n// scopebond-agent run run in the foreground (what autostart starts)\n// scopebond-agent status [--json] what the running agent reports, or why it is not running\n// scopebond-agent flush deliver now\n// scopebond-agent repair put the Scopebond hook back where agent settings lost it\n// scopebond-agent check update check, hook upkeep and the end-to-end self-check, now\n// scopebond-agent autostart on|off start with this user's sign-in, or stop doing so\n\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { isEphemeralPath, userHome } from \"@scopebond/hook\";\nimport { computerStatus } from \"./agent.js\";\nimport { autostartHealth, disableAutostart, enableAutostart, startNow } from \"./autostart.js\";\nimport { callAgent } from \"./ipc.js\";\nimport { AFTER_PID_ENV, AGENT_VERSION, startService } from \"./service.js\";\n\nconst [cmd = \"help\", ...rest] = process.argv.slice(2);\n// What a person types here: on Windows, PowerShell blocks the plain name's script shim.\nconst me = process.platform === \"win32\" ? \"scopebond-agent.cmd\" : \"scopebond-agent\";\nconst dir = process.env.SCOPEBOND_HOME ?? userHome();\nconst cliPath = realpathSync(fileURLToPath(import.meta.url));\n\nfunction help(): void {\n console.log(`Scopebond Agent — keeps this computer delivering to its Scopebond workspace.\n\n scopebond-agent run run in the foreground (what autostart starts)\n scopebond-agent status [--json] what the agent reports about this computer\n scopebond-agent flush deliver waiting records now\n scopebond-agent repair put the Scopebond hook back where agent settings lost it\n scopebond-agent check check for updates and run the end-to-end self-check now\n scopebond-agent autostart on|off start with your sign-in, or stop doing so\n\nThe hook keeps deciding every action on its own; the agent only keeps delivery, rules and the\nconnection current. Home: ${dir}`);\n}\n\nasync function main(): Promise<void> {\n switch (cmd) {\n case \"run\": {\n // Started by an agent that just updated itself: let it exit first.\n const previous = Number(process.env[AFTER_PID_ENV]);\n if (Number.isInteger(previous) && previous > 0) await waitForExit(previous, 30_000);\n const service = await startService({ dir });\n const stop = () => { void service.stop().finally(() => process.exit(0)); };\n process.on(\"SIGINT\", stop);\n process.on(\"SIGTERM\", stop);\n return;\n }\n case \"status\": {\n const live = await callAgent(dir, \"GET\", \"/status\") as (ReturnType<typeof computerStatus> & { agent?: AgentReport | null }) | null;\n const status = { ...(live ?? { ...computerStatus(dir), agent: null }), autostart: autostartHealth(dir) };\n if (rest.includes(\"--json\")) { console.log(JSON.stringify(status, null, 2)); return; }\n const d = status.delivery;\n console.log(`Scopebond Agent: ${live ? \"running\" : \"not running\"}`);\n console.log(` state ${live ? status.state : \"not running: records wait on this computer until it runs\"}`);\n console.log(` connected ${d.connected ? \"yes\" : \"no\"}`);\n console.log(` waiting to send ${d.pending} record(s)${d.oldest_pending_age_s !== null ? `, oldest ${Math.round(d.oldest_pending_age_s / 60)} min` : \"\"}`);\n if (d.last_error) console.log(` last problem ${d.last_error}`);\n console.log(` version ${status.agent?.version ?? AGENT_VERSION}`);\n console.log(` autostart ${status.autostart.detail}`);\n const check = status.agent?.last_maintenance?.selfCheck;\n if (check) console.log(` self-check ${check.ok ? \"passed\" : `failed: ${check.failed.join(\", \")}`}`);\n if (!live) console.log(`\\nStart it with: ${me} autostart on`);\n return;\n }\n case \"flush\":\n case \"repair\":\n case \"check\": {\n const answer = await callAgent(dir, \"POST\", `/${cmd === \"check\" ? \"maintain\" : cmd}`, {}, 6 * 60_000);\n if (!answer) { console.error(`The Scopebond Agent is not running. Start it with: ${me} autostart on`); process.exitCode = 1; return; }\n console.log(JSON.stringify(answer, null, 2));\n return;\n }\n case \"autostart\": {\n const on = rest[0] === \"on\";\n if (rest[0] !== \"on\" && rest[0] !== \"off\") { console.error(\"usage: scopebond-agent autostart on|off\"); process.exitCode = 1; return; }\n if (on && isEphemeralPath(cliPath)) {\n // npx runs from a cache npm clears; an autostart entry pointing there would stop working.\n console.error(\"Install the agent first so autostart has a stable path: npm install -g @scopebond/agent\");\n process.exitCode = 1;\n return;\n }\n console.log(on ? enableAutostart(dir, cliPath) : disableAutostart(dir));\n if (!on) return;\n // Turning autostart on also starts the agent now, so nobody has to sign out and in again.\n if (await callAgent(dir, \"GET\", \"/status\", undefined, 2_000)) { console.log(\"The Scopebond Agent is running.\"); return; }\n startNow(dir);\n for (let i = 0; i < 30; i++) {\n await new Promise((r) => setTimeout(r, 500));\n if (await callAgent(dir, \"GET\", \"/status\", undefined, 1_000)) {\n console.log(`The Scopebond Agent is running${process.platform === \"win32\" ? \"; its icon is in the taskbar tray (it may be under the ^ arrow)\" : \"\"}.`);\n return;\n }\n }\n console.log(`It starts at your next sign-in. To start it now: ${me} run`);\n return;\n }\n default:\n help();\n if (cmd !== \"help\" && cmd !== \"--help\") process.exitCode = 1;\n }\n}\n\ninterface AgentReport { version?: string; last_maintenance?: { selfCheck?: { ok: boolean; failed: string[] } | null } | null }\n\nasync function waitForExit(pid: number, timeoutMs: number): Promise<void> {\n const until = Date.now() + timeoutMs;\n while (Date.now() < until) {\n try { process.kill(pid, 0); } catch { return; }\n await new Promise((r) => setTimeout(r, 250));\n }\n}\n\nvoid main().catch((error) => { console.error((error as Error).message); process.exitCode = 1; });\n"]}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// scopebond-agent: run, look at and control the Scopebond Agent for this user.\n//\n// scopebond-agent setup <workspace-url> [--claude|--cursor|--codex] [--relogin]\n// one command to start: sign in, install, autostart, status\n// scopebond-agent run run in the foreground (what autostart starts)\n// scopebond-agent status [--json] what the running agent reports, or why it is not running\n// scopebond-agent flush deliver now\n// scopebond-agent repair put the Scopebond hook back where agent settings lost it\n// scopebond-agent check update check, hook upkeep and the end-to-end self-check, now\n// scopebond-agent autostart on|off start with this user's sign-in, or stop doing so (off also stops it now)\n// scopebond-agent stop stop the running agent (autostart still starts it at the next sign-in)\n\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { isEphemeralPath, userHome } from \"@scopebond/hook\";\nimport { computerStatus } from \"./agent.js\";\nimport { autostartHealth, disableAutostart, enableAutostart, startNow } from \"./autostart.js\";\nimport { callAgent } from \"./ipc.js\";\nimport { runSetup } from \"./setup.js\";\nimport { agentVersion } from \"./update.js\";\nimport { AFTER_PID_ENV, AGENT_VERSION, startService } from \"./service.js\";\n\nconst [cmd = \"help\", ...rest] = process.argv.slice(2);\n// What a person types here: on Windows, PowerShell blocks the plain name's script shim.\nconst me = process.platform === \"win32\" ? \"scopebond-agent.cmd\" : \"scopebond-agent\";\nconst dir = process.env.SCOPEBOND_HOME ?? userHome();\nconst cliPath = realpathSync(fileURLToPath(import.meta.url));\n\nfunction help(): void {\n const c = (sub: string) => `${me} ${sub}`.padEnd(me.length + 36);\n console.log(`Scopebond Agent — keeps this computer delivering to its Scopebond workspace.\n\n ${c(\"setup <workspace-url>\")}sign in, install for this user, start with sign-in, show status\n ${c(\"run\")}run in the foreground (what autostart starts)\n ${c(\"status [--json]\")}what the agent reports about this computer\n ${c(\"flush\")}deliver waiting records now\n ${c(\"repair\")}put the Scopebond hook back where agent settings lost it\n ${c(\"check\")}check for updates and run the end-to-end self-check now\n ${c(\"autostart on|off\")}start with your sign-in, or stop doing so (off also stops it now)\n ${c(\"stop\")}stop the running agent until the next sign-in\n\nThe hook keeps deciding every action on its own; the agent only keeps delivery, rules and the\nconnection current. Home: ${dir}`);\n}\n\nasync function main(): Promise<void> {\n switch (cmd) {\n case \"run\": {\n // Started by an agent that just updated itself: let it exit first.\n const previous = Number(process.env[AFTER_PID_ENV]);\n if (Number.isInteger(previous) && previous > 0) await waitForExit(previous, 30_000);\n const service = await startService({ dir, onStopped: () => process.exit(0) });\n const stop = () => { void service.stop().finally(() => process.exit(0)); };\n process.on(\"SIGINT\", stop);\n process.on(\"SIGTERM\", stop);\n return;\n }\n case \"status\": {\n const live = await callAgent(dir, \"GET\", \"/status\") as (ReturnType<typeof computerStatus> & { agent?: AgentReport | null }) | null;\n const status = { ...(live ?? { ...computerStatus(dir), agent: null }), autostart: autostartHealth(dir) };\n if (rest.includes(\"--json\")) { console.log(JSON.stringify(status, null, 2)); return; }\n const d = status.delivery;\n console.log(`Scopebond Agent: ${live ? \"running\" : \"not running\"}`);\n console.log(` state ${live ? status.state : \"not running: records wait on this computer until it runs\"}`);\n console.log(` connected ${d.connected ? \"yes\" : \"no\"}`);\n console.log(` waiting to send ${d.pending} record(s)${d.oldest_pending_age_s !== null ? `, oldest ${Math.round(d.oldest_pending_age_s / 60)} min` : \"\"}`);\n if (d.last_error) console.log(` last problem ${d.last_error}`);\n console.log(` version ${status.agent?.version ?? AGENT_VERSION}`);\n console.log(` autostart ${status.autostart.detail}`);\n const check = status.agent?.last_maintenance?.selfCheck;\n if (check) console.log(` self-check ${check.ok ? \"passed\" : `failed: ${check.failed.join(\", \")}`}`);\n if (!live) console.log(`\\nStart it with: ${me} autostart on`);\n return;\n }\n case \"flush\":\n case \"repair\":\n case \"check\": {\n const answer = await callAgent(dir, \"POST\", `/${cmd === \"check\" ? \"maintain\" : cmd}`, {}, 6 * 60_000);\n if (!answer) { console.error(`The Scopebond Agent is not running. Start it with: ${me} autostart on`); process.exitCode = 1; return; }\n console.log(JSON.stringify(answer, null, 2));\n return;\n }\n case \"setup\": {\n const target = rest.find((a) => !a.startsWith(\"--\"));\n let origin: string | null = null;\n try {\n const url = new URL(target ?? \"\");\n const local = [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname);\n if (url.protocol === \"https:\" || (local && url.protocol === \"http:\")) origin = url.origin;\n } catch { origin = null; }\n if (!origin) {\n console.error(`usage: ${process.platform === \"win32\" ? \"npx.cmd\" : \"npx\"} -y @scopebond/agent@${agentVersion()} setup <workspace-url> [--claude|--cursor|--codex]`);\n console.error(\"The workspace URL is the address of your Scopebond workspace, for example https://cloud.scopebond.com.\");\n process.exitCode = 1;\n return;\n }\n const harness = rest.includes(\"--cursor\") ? \"cursor\" : rest.includes(\"--codex\") ? \"codex\" : \"claude\";\n process.exitCode = await runSetup({ dir, origin, harness, relogin: rest.includes(\"--relogin\"), version: agentVersion(), me });\n return;\n }\n case \"stop\": {\n console.log(await stopRunning() ? \"Stopped the Scopebond Agent.\" : \"The Scopebond Agent was not running.\");\n return;\n }\n case \"autostart\": {\n const on = rest[0] === \"on\";\n if (rest[0] !== \"on\" && rest[0] !== \"off\") { console.error(`usage: ${me} autostart on|off`); process.exitCode = 1; return; }\n if (on && isEphemeralPath(cliPath)) {\n // npx runs from a cache npm clears; an autostart entry pointing there would stop working.\n console.error(`Install the agent first so autostart has a stable path: ${process.platform === \"win32\" ? \"npm.cmd\" : \"npm\"} install -g @scopebond/agent`);\n process.exitCode = 1;\n return;\n }\n console.log(on ? enableAutostart(dir, cliPath) : disableAutostart(dir));\n if (!on) {\n // Off means off: an agent left running would keep going until sign-out, even after an uninstall.\n if (await stopRunning()) console.log(\"Stopped the running Scopebond Agent.\");\n return;\n }\n // Turning autostart on also starts the agent now, so nobody has to sign out and in again.\n if (await callAgent(dir, \"GET\", \"/status\", undefined, 2_000)) { console.log(\"The Scopebond Agent is running.\"); return; }\n // Each way of starting it gets a few seconds; a headless console that never starts falls back to a hidden cmd.exe.\n for (let attempt = 0; attempt < 2; attempt++) {\n if (!startNow(dir, process.platform, attempt) && attempt > 0) break;\n for (let i = 0; i < (attempt === 0 ? 12 : 18); i++) {\n await new Promise((r) => setTimeout(r, 500));\n if (await callAgent(dir, \"GET\", \"/status\", undefined, 1_000)) {\n console.log(`The Scopebond Agent is running${process.platform === \"win32\" ? \"; its icon is in the taskbar tray (it may be under the ^ arrow)\" : \"\"}.`);\n return;\n }\n }\n }\n console.log(`It starts at your next sign-in. To start it now: ${me} run`);\n return;\n }\n default:\n help();\n if (cmd !== \"help\" && cmd !== \"--help\") process.exitCode = 1;\n }\n}\n\n/** Ask the running agent to stop and wait until its control channel is gone. Whether one was running. */\nasync function stopRunning(): Promise<boolean> {\n if (!await callAgent(dir, \"POST\", \"/stop\", {}, 3_000)) return false;\n for (let i = 0; i < 40; i++) {\n await new Promise((r) => setTimeout(r, 250));\n if (!await callAgent(dir, \"GET\", \"/status\", undefined, 1_000)) return true;\n }\n return true;\n}\n\ninterface AgentReport { version?: string; last_maintenance?: { selfCheck?: { ok: boolean; failed: string[] } | null } | null }\n\nasync function waitForExit(pid: number, timeoutMs: number): Promise<void> {\n const until = Date.now() + timeoutMs;\n while (Date.now() < until) {\n try { process.kill(pid, 0); } catch { return; }\n await new Promise((r) => setTimeout(r, 250));\n }\n}\n\nvoid main().catch((error) => { console.error((error as Error).message); process.exitCode = 1; });\n"]}
|
package/dist/health.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AACpD,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE,qDAAqD;IACrD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AACpD,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE,qDAAqD;IACrD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAuBpH"}
|
package/dist/health.js
CHANGED
|
@@ -7,6 +7,11 @@ export function healthOf(status, selfCheck) {
|
|
|
7
7
|
if (!status.delivery.connected) {
|
|
8
8
|
return { level: "red", headline: "Not connected to a workspace: records stay on this computer", fix: null, hint: "Connect it: npx @scopebond/hook login https://<your-workspace>" };
|
|
9
9
|
}
|
|
10
|
+
// W20: the hook blocks every action while its delivery queue cannot be opened.
|
|
11
|
+
const queueError = status.delivery.queue_error;
|
|
12
|
+
if (queueError) {
|
|
13
|
+
return { level: "red", headline: "Every action is blocked: the delivery queue cannot be opened", fix: null, hint: `${queueError}. Free some disk space, or make that file and its -wal and -shm files writable (do not delete it).` };
|
|
14
|
+
}
|
|
10
15
|
if (status.delivery.connection_refused_since !== null) {
|
|
11
16
|
return { level: "red", headline: "The workspace refuses this computer's connection", fix: null, hint: "Sign in again: npx @scopebond/hook login https://<your-workspace>" };
|
|
12
17
|
}
|
package/dist/health.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.js","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAC3H,2EAA2E;AAc3E,MAAM,UAAU,QAAQ,CAAC,MAAkB,EAAE,SAA+D;IAC1G,IAAI,MAAM,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;QACrC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,6DAA6D,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC3J,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,6DAA6D,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,gEAAgE,EAAE,CAAC;IACtL,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,wBAAwB,KAAK,IAAI,EAAE,CAAC;QACtD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,kDAAkD,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,mEAAmE,EAAE,CAAC;IAC9K,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,KAAK,mBAAmB,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,qBAAqB,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACtJ,CAAC;IACD,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,gCAAgC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACpK,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,8DAA8D,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC7H,CAAC","sourcesContent":["// One line for a person: green, amber or red, what it means, and the one action that fixes it. The tray icon (Windows) and\n// the notifications (macOS, Linux) show this; nothing else decides colour.\n\nimport type { StatusJson } from \"@scopebond/hook\";\n\nexport type HealthLevel = \"green\" | \"amber\" | \"red\";\nexport interface Health {\n level: HealthLevel;\n headline: string;\n /** The local-channel route that fixes it, with its button label, when one exists. */\n fix: { label: string; route: \"/repair\" | \"/flush\" | \"/maintain\" } | null;\n /** What a person types when no button can fix it. */\n hint: string | null;\n}\n\nexport function healthOf(status: StatusJson, selfCheck: { ok: boolean; failed: string[] } | null | undefined): Health {\n if (status.state === \"not_governing\") {\n return { level: \"red\", headline: \"Scopebond is not checking any coding agent on this computer\", fix: { label: \"Repair\", route: \"/repair\" }, hint: null };\n }\n if (!status.delivery.connected) {\n return { level: \"red\", headline: \"Not connected to a workspace: records stay on this computer\", fix: null, hint: \"Connect it: npx @scopebond/hook login https://<your-workspace>\" };\n }\n if (status.delivery.connection_refused_since !== null) {\n return { level: \"red\", headline: \"The workspace refuses this computer's connection\", fix: null, hint: \"Sign in again: npx @scopebond/hook login https://<your-workspace>\" };\n }\n if (status.state === \"recording_locally\") {\n const n = status.delivery.pending;\n return { level: \"amber\", headline: `${n} record${n === 1 ? \"\" : \"s\"} waiting to be sent`, fix: { label: \"Send now\", route: \"/flush\" }, hint: null };\n }\n if (selfCheck && !selfCheck.ok) {\n return { level: \"amber\", headline: `The daily self-check failed: ${selfCheck.failed.join(\", \")}`, fix: { label: \"Check again\", route: \"/maintain\" }, hint: null };\n }\n return { level: \"green\", headline: \"Checking your coding agents and delivering to your workspace\", fix: null, hint: null };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAC3H,2EAA2E;AAc3E,MAAM,UAAU,QAAQ,CAAC,MAAkB,EAAE,SAA+D;IAC1G,IAAI,MAAM,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;QACrC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,6DAA6D,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC3J,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,6DAA6D,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,gEAAgE,EAAE,CAAC;IACtL,CAAC;IACD,+EAA+E;IAC/E,MAAM,UAAU,GAAI,MAAM,CAAC,QAA4C,CAAC,WAAW,CAAC;IACpF,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,8DAA8D,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,UAAU,oGAAoG,EAAE,CAAC;IACxO,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,wBAAwB,KAAK,IAAI,EAAE,CAAC;QACtD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,kDAAkD,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,mEAAmE,EAAE,CAAC;IAC9K,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,KAAK,mBAAmB,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,qBAAqB,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACtJ,CAAC;IACD,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,gCAAgC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACpK,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,8DAA8D,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC7H,CAAC","sourcesContent":["// One line for a person: green, amber or red, what it means, and the one action that fixes it. The tray icon (Windows) and\n// the notifications (macOS, Linux) show this; nothing else decides colour.\n\nimport type { StatusJson } from \"@scopebond/hook\";\n\nexport type HealthLevel = \"green\" | \"amber\" | \"red\";\nexport interface Health {\n level: HealthLevel;\n headline: string;\n /** The local-channel route that fixes it, with its button label, when one exists. */\n fix: { label: string; route: \"/repair\" | \"/flush\" | \"/maintain\" } | null;\n /** What a person types when no button can fix it. */\n hint: string | null;\n}\n\nexport function healthOf(status: StatusJson, selfCheck: { ok: boolean; failed: string[] } | null | undefined): Health {\n if (status.state === \"not_governing\") {\n return { level: \"red\", headline: \"Scopebond is not checking any coding agent on this computer\", fix: { label: \"Repair\", route: \"/repair\" }, hint: null };\n }\n if (!status.delivery.connected) {\n return { level: \"red\", headline: \"Not connected to a workspace: records stay on this computer\", fix: null, hint: \"Connect it: npx @scopebond/hook login https://<your-workspace>\" };\n }\n // W20: the hook blocks every action while its delivery queue cannot be opened.\n const queueError = (status.delivery as { queue_error?: string | null }).queue_error;\n if (queueError) {\n return { level: \"red\", headline: \"Every action is blocked: the delivery queue cannot be opened\", fix: null, hint: `${queueError}. Free some disk space, or make that file and its -wal and -shm files writable (do not delete it).` };\n }\n if (status.delivery.connection_refused_since !== null) {\n return { level: \"red\", headline: \"The workspace refuses this computer's connection\", fix: null, hint: \"Sign in again: npx @scopebond/hook login https://<your-workspace>\" };\n }\n if (status.state === \"recording_locally\") {\n const n = status.delivery.pending;\n return { level: \"amber\", headline: `${n} record${n === 1 ? \"\" : \"s\"} waiting to be sent`, fix: { label: \"Send now\", route: \"/flush\" }, hint: null };\n }\n if (selfCheck && !selfCheck.ok) {\n return { level: \"amber\", headline: `The daily self-check failed: ${selfCheck.failed.join(\", \")}`, fix: { label: \"Check again\", route: \"/maintain\" }, hint: null };\n }\n return { level: \"green\", headline: \"Checking your coding agents and delivering to your workspace\", fix: null, hint: null };\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
export { runCycle, computerStatus, expectedHarnesses, missingHookEntries } from "./agent.js";
|
|
2
2
|
export type { CycleOptions, CycleResult } from "./agent.js";
|
|
3
|
-
export { startService, repairHookEntries, spawnReplacement, AGENT_VERSION, AFTER_PID_ENV } from "./service.js";
|
|
3
|
+
export { startService, repairHookEntries, spawnReplacement, acquireAgentLock, releaseAgentLock, AGENT_LOCK, AGENT_VERSION, AFTER_PID_ENV } from "./service.js";
|
|
4
4
|
export type { Service, ServiceOptions, MaintenanceResult } from "./service.js";
|
|
5
5
|
export { startControl, callAgent, readEndpoint, AGENT_FILE, TOKEN_HEADER } from "./ipc.js";
|
|
6
6
|
export type { AgentEndpoint } from "./ipc.js";
|
|
7
|
-
export { launcherPath, windowsLauncher, posixLauncher, windowsRunCommand, macLaunchAgent, linuxUserUnit, enableAutostart, disableAutostart, autostartHealth, autostartPaths, LABEL, } from "./autostart.js";
|
|
8
|
-
export { agentVersion, fetchClientVersion, compareVersions, commandHookVersion, maintainedHookCommand, maintainHookEntries, installAgent, } from "./update.js";
|
|
7
|
+
export { launcherPath, windowsLauncher, posixLauncher, windowsRunCommand, macLaunchAgent, linuxUserUnit, enableAutostart, disableAutostart, autostartHealth, autostartPaths, startCommands, startNow, LABEL, } from "./autostart.js";
|
|
8
|
+
export { agentVersion, fetchClientVersion, compareVersions, commandHookVersion, maintainedHookCommand, maintainHookEntries, installAgent, ownNpm, } from "./update.js";
|
|
9
9
|
export type { ClientVersion } from "./update.js";
|
|
10
10
|
export { selfCheckProof, localChecks, runSelfCheck } from "./selfcheck.js";
|
|
11
11
|
export { parseQuestion, questionText, windowsScript, systemPrompter, serialized } from "./prompt.js";
|
|
12
12
|
export type { OverrideQuestion, OverrideAnswer, Prompter } from "./prompt.js";
|
|
13
13
|
export { queueReason, flushReasons, pendingReasons, REASONS_FILE } from "./override-reasons.js";
|
|
14
14
|
export type { SelfCheckItem } from "./selfcheck.js";
|
|
15
|
+
export { setupPlan, globalBinDir, onPath, addToPathCommand, nodeSupported, runSetup } from "./setup.js";
|
|
16
|
+
export type { SetupState, SetupStep, SetupOptions } from "./setup.js";
|
|
15
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC7F,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC7F,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/J,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC3F,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EACL,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAC9F,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,GACnG,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,GACxI,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrG,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChG,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACxG,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export { runCycle, computerStatus, expectedHarnesses, missingHookEntries } from "./agent.js";
|
|
2
|
-
export { startService, repairHookEntries, spawnReplacement, AGENT_VERSION, AFTER_PID_ENV } from "./service.js";
|
|
2
|
+
export { startService, repairHookEntries, spawnReplacement, acquireAgentLock, releaseAgentLock, AGENT_LOCK, AGENT_VERSION, AFTER_PID_ENV } from "./service.js";
|
|
3
3
|
export { startControl, callAgent, readEndpoint, AGENT_FILE, TOKEN_HEADER } from "./ipc.js";
|
|
4
|
-
export { launcherPath, windowsLauncher, posixLauncher, windowsRunCommand, macLaunchAgent, linuxUserUnit, enableAutostart, disableAutostart, autostartHealth, autostartPaths, LABEL, } from "./autostart.js";
|
|
5
|
-
export { agentVersion, fetchClientVersion, compareVersions, commandHookVersion, maintainedHookCommand, maintainHookEntries, installAgent, } from "./update.js";
|
|
4
|
+
export { launcherPath, windowsLauncher, posixLauncher, windowsRunCommand, macLaunchAgent, linuxUserUnit, enableAutostart, disableAutostart, autostartHealth, autostartPaths, startCommands, startNow, LABEL, } from "./autostart.js";
|
|
5
|
+
export { agentVersion, fetchClientVersion, compareVersions, commandHookVersion, maintainedHookCommand, maintainHookEntries, installAgent, ownNpm, } from "./update.js";
|
|
6
6
|
export { selfCheckProof, localChecks, runSelfCheck } from "./selfcheck.js";
|
|
7
7
|
export { parseQuestion, questionText, windowsScript, systemPrompter, serialized } from "./prompt.js";
|
|
8
8
|
export { queueReason, flushReasons, pendingReasons, REASONS_FILE } from "./override-reasons.js";
|
|
9
|
+
export { setupPlan, globalBinDir, onPath, addToPathCommand, nodeSupported, runSetup } from "./setup.js";
|
|
9
10
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE7F,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE/
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE7F,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE/J,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE3F,OAAO,EACL,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAC9F,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,GACnG,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,GACxI,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAErG,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEhG,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC","sourcesContent":["export { runCycle, computerStatus, expectedHarnesses, missingHookEntries } from \"./agent.js\";\nexport type { CycleOptions, CycleResult } from \"./agent.js\";\nexport { startService, repairHookEntries, spawnReplacement, acquireAgentLock, releaseAgentLock, AGENT_LOCK, AGENT_VERSION, AFTER_PID_ENV } from \"./service.js\";\nexport type { Service, ServiceOptions, MaintenanceResult } from \"./service.js\";\nexport { startControl, callAgent, readEndpoint, AGENT_FILE, TOKEN_HEADER } from \"./ipc.js\";\nexport type { AgentEndpoint } from \"./ipc.js\";\nexport {\n launcherPath, windowsLauncher, posixLauncher, windowsRunCommand, macLaunchAgent, linuxUserUnit,\n enableAutostart, disableAutostart, autostartHealth, autostartPaths, startCommands, startNow, LABEL,\n} from \"./autostart.js\";\nexport {\n agentVersion, fetchClientVersion, compareVersions, commandHookVersion, maintainedHookCommand, maintainHookEntries, installAgent, ownNpm,\n} from \"./update.js\";\nexport type { ClientVersion } from \"./update.js\";\nexport { selfCheckProof, localChecks, runSelfCheck } from \"./selfcheck.js\";\nexport { parseQuestion, questionText, windowsScript, systemPrompter, serialized } from \"./prompt.js\";\nexport type { OverrideQuestion, OverrideAnswer, Prompter } from \"./prompt.js\";\nexport { queueReason, flushReasons, pendingReasons, REASONS_FILE } from \"./override-reasons.js\";\nexport type { SelfCheckItem } from \"./selfcheck.js\";\nexport { setupPlan, globalBinDir, onPath, addToPathCommand, nodeSupported, runSetup } from \"./setup.js\";\nexport type { SetupState, SetupStep, SetupOptions } from \"./setup.js\";\n"]}
|