@scopebond/agent 0.5.6 → 0.6.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.
Files changed (61) hide show
  1. package/dist/agent.d.ts +6 -0
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +10 -3
  4. package/dist/agent.js.map +1 -1
  5. package/dist/allowance-sender.js +10 -4
  6. package/dist/allowance-sender.js.map +1 -1
  7. package/dist/apps-entry.d.ts +46 -0
  8. package/dist/apps-entry.d.ts.map +1 -0
  9. package/dist/apps-entry.js +118 -0
  10. package/dist/apps-entry.js.map +1 -0
  11. package/dist/autostart.d.ts +11 -5
  12. package/dist/autostart.d.ts.map +1 -1
  13. package/dist/autostart.js +60 -6
  14. package/dist/autostart.js.map +1 -1
  15. package/dist/awake.d.ts +31 -0
  16. package/dist/awake.d.ts.map +1 -0
  17. package/dist/awake.js +57 -0
  18. package/dist/awake.js.map +1 -0
  19. package/dist/cli-main.d.ts.map +1 -1
  20. package/dist/cli-main.js +28 -1
  21. package/dist/cli-main.js.map +1 -1
  22. package/dist/index.d.ts +12 -7
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +8 -5
  25. package/dist/index.js.map +1 -1
  26. package/dist/ipc.d.ts +9 -4
  27. package/dist/ipc.d.ts.map +1 -1
  28. package/dist/ipc.js +15 -9
  29. package/dist/ipc.js.map +1 -1
  30. package/dist/log-file.js.map +1 -1
  31. package/dist/native-update.d.ts +83 -7
  32. package/dist/native-update.d.ts.map +1 -1
  33. package/dist/native-update.js +230 -33
  34. package/dist/native-update.js.map +1 -1
  35. package/dist/prompt.d.ts.map +1 -1
  36. package/dist/prompt.js +1 -0
  37. package/dist/prompt.js.map +1 -1
  38. package/dist/selfcheck.d.ts.map +1 -1
  39. package/dist/selfcheck.js +4 -1
  40. package/dist/selfcheck.js.map +1 -1
  41. package/dist/service.d.ts +20 -3
  42. package/dist/service.d.ts.map +1 -1
  43. package/dist/service.js +141 -44
  44. package/dist/service.js.map +1 -1
  45. package/dist/setup.d.ts +12 -0
  46. package/dist/setup.d.ts.map +1 -1
  47. package/dist/setup.js +42 -13
  48. package/dist/setup.js.map +1 -1
  49. package/dist/tray-model.d.ts +2 -0
  50. package/dist/tray-model.d.ts.map +1 -1
  51. package/dist/tray-model.js +2 -0
  52. package/dist/tray-model.js.map +1 -1
  53. package/dist/update.d.ts +56 -12
  54. package/dist/update.d.ts.map +1 -1
  55. package/dist/update.js +209 -38
  56. package/dist/update.js.map +1 -1
  57. package/dist/upkeep.d.ts +16 -0
  58. package/dist/upkeep.d.ts.map +1 -0
  59. package/dist/upkeep.js +55 -0
  60. package/dist/upkeep.js.map +1 -0
  61. package/package.json +4 -4
@@ -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, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, win32 } from \"node:path\";\nimport { isSingleExecutable } from \"@scopebond/hook\";\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, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\nconst noQuotes = (s: string) => s.replace(/\"/g, \"\");\n\n/** The agent's log, which the agent writes itself (`SCOPEBOND_AGENT_LOG`) when a Windows launcher or a handover starts it. */\nexport const AGENT_LOG_ENV = \"SCOPEBOND_AGENT_LOG\";\n\n/** Written into every Windows launcher this version makes. A launcher without it redirects the agent's output into\n * agent.log itself, which keeps a replacement agent from starting (see `spawnReplacement`). */\nexport const LAUNCHER_MARK = \"rem Scopebond Agent launcher 2:\";\n\n/** Whether a launcher's text is this version's (an older one is rewritten once no agent runs under it). */\nexport function launcherIsCurrent(text: string, platform: NodeJS.Platform = process.platform): boolean {\n return platform !== \"win32\" || text.includes(LAUNCHER_MARK);\n}\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\n/** The Windows launcher. With `cli` empty, `node` is the single executable: it is started as it is, with no Node to find. */\nexport function windowsLauncher(node: string, cli: string, logFile: string): string {\n const log = `\"%~dp0${win32.basename(noQuotes(logFile))}\"`;\n const single = cli === \"\";\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 `${LAUNCHER_MARK} finds Node and the agent each time, so a Node upgrade never stops it.`,\n \"setlocal\",\n // The agent writes its own log. A `>> agent.log` here would hold the file shared for reading only, the old agent's\n // children inherit that handle, and a replacement started during an update could then never open it: cmd skips the\n // whole command line when a redirect fails. The log sits beside this launcher; %~dp0 keeps it right whatever the folder is called.\n `set \"${AGENT_LOG_ENV}=%~dp0${win32.basename(noQuotes(logFile))}\"`,\n `set \"NODE=${noQuotes(node)}\"`,\n ...(single ? [`if not exist \"%NODE%\" exit /b 1`] : [\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 ]),\n // Restart on failure, as launchd (KeepAlive) and systemd (Restart=on-failure) do: a crash restarts the agent after\n // 30 seconds, up to 50 times; a clean exit (stop, autostart off, an update handing over) ends the launcher.\n \"set /a TRIES=0\",\n \":run\",\n // (call) sets the error level to 1 first, so a command that never ran counts as a failure, not a clean stop.\n \"(call)\",\n single ? `\"%NODE%\" run >nul 2>&1` : `\"%NODE%\" --disable-warning=ExperimentalWarning \"%CLI%\" run >nul 2>&1`,\n `set \"CODE=%ERRORLEVEL%\"`,\n // An update's handover names the agent to wait for; a restart after a crash has nothing to wait for.\n `set \"SCOPEBOND_AGENT_AFTER_PID=\"`,\n \"if %CODE% EQU 0 exit /b 0\",\n \"set /a TRIES+=1\",\n `echo %DATE% %TIME% the agent stopped with exit code %CODE%; restarting in 30 seconds (attempt %TRIES% of 50) >> ${log}`,\n \"if %TRIES% GEQ 50 exit /b 1\",\n // ping waits without a console to read from (timeout.exe refuses to run under a headless console).\n \"ping -n 31 127.0.0.1 >nul\",\n \"goto run\",\n \"\",\n ].join(\"\\r\\n\");\n}\n\n/** The macOS/Linux launcher. With `cli` empty, `node` is the single executable, started as it is. */\nexport function posixLauncher(node: string, cli: string): string {\n const q = (s: string) => `'${s.replace(/'/g, \"'\\\\''\")}'`;\n if (cli === \"\") return `#!/bin/sh\n# Scopebond Agent launcher: the single executable.\nexec ${q(node)} run\n`;\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\n/** Rewrite an older Windows launcher as this version's, keeping autostart as it is. Only safe once no cmd.exe runs the old\n * one (cmd reads a batch file line by line from where it left off): the handover calls it after the old agent has exited.\n * Returns whether it rewrote one. */\nexport function refreshLauncher(scopebondHome: string, cli: string, node = process.execPath, platform = process.platform): boolean {\n const launcher = launcherPath(scopebondHome, platform);\n let text: string;\n try { text = readFileSync(launcher, \"utf8\"); } catch { return false; }\n if (launcherIsCurrent(text, platform)) return false;\n writeLauncher(scopebondHome, node, cli, platform);\n return true;\n}\n\nfunction writeLauncher(scopebondHome: string, node: string, cli: string, platform: NodeJS.Platform): string {\n // The single executable is both Node and the agent: the launcher starts it with `run`.\n if (isSingleExecutable()) { node = process.execPath; cli = \"\"; }\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"]}
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, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, win32 } from \"node:path\";\nimport { isSingleExecutable } from \"@scopebond/hook\";\nimport { nativeTrayPath } from \"./native-update.js\";\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, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\nconst noQuotes = (s: string) => s.replace(/\"/g, \"\");\n\n/** The agent's log, which the agent writes itself (`SCOPEBOND_AGENT_LOG`) when a Windows launcher or a handover starts it. */\nexport const AGENT_LOG_ENV = \"SCOPEBOND_AGENT_LOG\";\n\n/** Written into every Windows launcher this version makes. A launcher without it redirects the agent's output into\n * agent.log itself, which keeps a replacement agent from starting (see `spawnReplacement`). */\nexport const LAUNCHER_MARK = \"rem Scopebond Agent launcher 2:\";\n\n/** Whether a launcher's text is this version's (an older one is rewritten once no agent runs under it). */\nexport function launcherIsCurrent(text: string, platform: NodeJS.Platform = process.platform): boolean {\n return platform !== \"win32\" || text.includes(LAUNCHER_MARK);\n}\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\n/** The Windows launcher. With `cli` empty, `node` is the single executable: it is started as it is, with no Node to find. */\nexport function windowsLauncher(node: string, cli: string, logFile: string): string {\n const log = `\"%~dp0${win32.basename(noQuotes(logFile))}\"`;\n const single = cli === \"\";\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 `${LAUNCHER_MARK} finds Node and the agent each time, so a Node upgrade never stops it.`,\n \"setlocal\",\n // The agent writes its own log. A `>> agent.log` here would hold the file shared for reading only, the old agent's\n // children inherit that handle, and a replacement started during an update could then never open it: cmd skips the\n // whole command line when a redirect fails. The log sits beside this launcher; %~dp0 keeps it right whatever the folder is called.\n `set \"${AGENT_LOG_ENV}=%~dp0${win32.basename(noQuotes(logFile))}\"`,\n `set \"NODE=${noQuotes(node)}\"`,\n ...(single ? [`if not exist \"%NODE%\" exit /b 1`] : [\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 ]),\n // Restart on failure, as launchd (KeepAlive) and systemd (Restart=on-failure) do: a crash restarts the agent after\n // 30 seconds, up to 50 times; a clean exit (stop, autostart off, an update handing over) ends the launcher.\n \"set /a TRIES=0\",\n \":run\",\n // (call) sets the error level to 1 first, so a command that never ran counts as a failure, not a clean stop.\n \"(call)\",\n single ? `\"%NODE%\" run >nul 2>&1` : `\"%NODE%\" --disable-warning=ExperimentalWarning \"%CLI%\" run >nul 2>&1`,\n `set \"CODE=%ERRORLEVEL%\"`,\n // An update's handover names the agent to wait for; a restart after a crash has nothing to wait for.\n `set \"SCOPEBOND_AGENT_AFTER_PID=\"`,\n \"if %CODE% EQU 0 exit /b 0\",\n \"set /a TRIES+=1\",\n `echo %DATE% %TIME% the agent stopped with exit code %CODE%; restarting in 30 seconds (attempt %TRIES% of 50) >> ${log}`,\n \"if %TRIES% GEQ 50 exit /b 1\",\n // ping waits without a console to read from (timeout.exe refuses to run under a headless console).\n \"ping -n 31 127.0.0.1 >nul\",\n \"goto run\",\n \"\",\n ].join(\"\\r\\n\");\n}\n\n/** The macOS/Linux launcher. With `cli` empty, `node` is the single executable, started as it is. */\nexport function posixLauncher(node: string, cli: string): string {\n const q = (s: string) => `'${s.replace(/'/g, \"'\\\\''\")}'`;\n if (cli === \"\") return `#!/bin/sh\n# Scopebond Agent launcher: the single executable.\nexec ${q(node)} run\n`;\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\n/** Rewrite an older Windows launcher as this version's, keeping autostart as it is. Only safe once no cmd.exe runs the old\n * one (cmd reads a batch file line by line from where it left off): the handover calls it after the old agent has exited.\n * Returns whether it rewrote one. */\nexport function refreshLauncher(scopebondHome: string, cli: string, node = process.execPath, platform = process.platform): boolean {\n const launcher = launcherPath(scopebondHome, platform);\n let text: string;\n try { text = readFileSync(launcher, \"utf8\"); } catch { return false; }\n if (launcherIsCurrent(text, platform)) return false;\n writeLauncher(scopebondHome, node, cli, platform);\n return true;\n}\n\nfunction writeLauncher(scopebondHome: string, node: string, cli: string, platform: NodeJS.Platform): string {\n // The single executable is both Node and the agent: the launcher starts it with `run`.\n if (isSingleExecutable()) { node = process.execPath; cli = \"\"; }\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// The signed Windows install with its native tray (`scopebond-tray.exe` beside the agent): the installer adds a Run value\n// `Scopebond` that starts the tray, and the tray starts the agent and keeps it running. Autostart then means that value,\n// not the launcher's `ScopebondAgent`, which would start a second agent (refused by its lock) at every sign-in.\n\n/** Runs `reg.exe` with these arguments; whether it succeeded. Tests pass their own. */\nexport type RegRunner = (args: string[]) => boolean;\nconst runReg: RegRunner = (args) => {\n try { execFileSync(\"reg\", args, { stdio: \"ignore\", windowsHide: true }); return true; } catch { return false; }\n};\nexport const TRAY_RUN_VALUE = \"Scopebond\";\nconst MACHINE_RUN_KEY = \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\";\nconst trayFor = (platform: NodeJS.Platform) => (platform === \"win32\" ? nativeTrayPath() : null);\n/** The tray's Run value set for every user (an install with ALLUSERS=1): only whoever installed it changes it. */\nconst trayForEveryone = (reg: RegRunner) => reg([\"query\", MACHINE_RUN_KEY, \"/v\", TRAY_RUN_VALUE]);\n\n/** The launcher's Run value is not used beside the native tray. Whether there was one to remove. */\nexport function retireLauncherRunValue(reg: RegRunner = runReg): boolean {\n return reg([\"query\", RUN_KEY, \"/v\", RUN_VALUE]) && reg([\"delete\", RUN_KEY, \"/v\", RUN_VALUE, \"/f\"]);\n}\n\n/** Start the agent now with the `attempt`-th way (0 first), detached from this terminal. Returns whether it tried one.\n * Beside the native tray, the one way is to start the tray (it starts the agent; a second tray gives way to the first). */\nexport function startNow(scopebondHome: string, platform = process.platform, attempt = 0, tray: string | null = trayFor(platform)): boolean {\n if (tray) {\n if (attempt > 0) return false;\n try {\n const child = spawn(tray, [], { detached: true, stdio: \"ignore\", windowsHide: true });\n child.on(\"error\", () => { /* the next sign-in starts it */ });\n child.unref();\n return true;\n } catch { return false; }\n }\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, tray: string | null = trayFor(platform), reg: RegRunner = runReg): string {\n if (tray) {\n retireLauncherRunValue(reg);\n if (trayForEveryone(reg)) return \"the Scopebond tray starts for every user of this computer and keeps the agent running\";\n if (!reg([\"add\", RUN_KEY, \"/v\", TRAY_RUN_VALUE, \"/t\", \"REG_SZ\", \"/d\", `\"${noQuotes(tray)}\"`, \"/f\"])) throw new Error(`could not add ${TRAY_RUN_VALUE} to ${RUN_KEY}`);\n return `added ${TRAY_RUN_VALUE} to ${RUN_KEY}: the Scopebond tray starts with your sign-in and keeps the agent running`;\n }\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, tray: string | null = trayFor(platform), reg: RegRunner = runReg): string {\n const paths = autostartPaths();\n rmSync(launcherPath(scopebondHome, platform), { force: true });\n if (tray) {\n const launcherValue = retireLauncherRunValue(reg);\n const trayValue = reg([\"query\", RUN_KEY, \"/v\", TRAY_RUN_VALUE]) && reg([\"delete\", RUN_KEY, \"/v\", TRAY_RUN_VALUE, \"/f\"]);\n if (trayValue || launcherValue) return `removed ${trayValue ? TRAY_RUN_VALUE : RUN_VALUE} from ${RUN_KEY}`;\n return trayForEveryone(reg) ? \"Scopebond starts for every user of this computer; whoever installed it changes that\" : \"autostart was not on\";\n }\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, tray: string | null = trayFor(platform), reg: RegRunner = runReg): { on: boolean; ok: boolean; detail: string } {\n if (tray) {\n const on = reg([\"query\", RUN_KEY, \"/v\", TRAY_RUN_VALUE]) || trayForEveryone(reg);\n return on\n ? { on, ok: true, detail: \"starts with sign-in (the Scopebond tray keeps the agent running)\" }\n : { on, ok: false, detail: \"the Scopebond tray does not start with sign-in (turn on Start with Windows in its menu, or run: scopebond-agent.exe autostart on)\" };\n }\n const paths = autostartPaths();\n let on: boolean;\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"]}
@@ -0,0 +1,31 @@
1
+ export declare const AWAKE_FILE = "agent-awake.json";
2
+ export interface AwakeState {
3
+ /** When the computer last woke (or started), as this agent saw it, in milliseconds. */
4
+ awake_since: number;
5
+ /** When this agent last ran a cycle. */
6
+ last_cycle_at: number;
7
+ }
8
+ /** Where waiting is counted from when the agent starts. The tray counts waiting as `now - max(oldest record, this)`.
9
+ * - The last cycle was recent and after the computer started: the agent restarted while the computer stayed awake, so the
10
+ * saved wake time stands (never earlier than the computer's start).
11
+ * - The computer started after the last cycle: it was off (or rebooted), so it has been awake since it started, and the
12
+ * oldest record counts from `max(its enqueue time, the computer's start)`.
13
+ * - A long gap since the last cycle without a restart of the computer. The agent cannot tell sleep (or a shutdown with
14
+ * Windows Fast Startup, which keeps the uptime) from an agent that was stopped, so it uses the records as evidence:
15
+ * - the oldest waiting record was written after the last cycle: the hook ran while the agent did not, so the computer was
16
+ * awake and the agent was not running; waiting counts from that record (`now - max(record, computer's start)`);
17
+ * - the oldest waiting record is older than the gap: the time it waited before the gap, while the agent ran its cycles,
18
+ * was awake time and still counts; the gap itself does not (it may have been sleep). Waiting resumes from there.
19
+ * - nothing waiting: from now.
20
+ * - No saved state, or times that make no sense (a clock moved back): from now. */
21
+ export declare function awakeSinceAtStart(input: {
22
+ saved: AwakeState | null;
23
+ now: number;
24
+ uptimeMs: number;
25
+ allowedGapMs: number;
26
+ oldestPendingAt?: number | null;
27
+ }): number;
28
+ /** The saved state, or null when there is none or it cannot be read. */
29
+ export declare function readAwake(dir: string): AwakeState | null;
30
+ export declare function writeAwake(dir: string, state: AwakeState): void;
31
+ //# sourceMappingURL=awake.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"awake.d.ts","sourceRoot":"","sources":["../src/awake.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,UAAU,qBAAqB,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,uFAAuF;IACvF,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;oFAYoF;AACpF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,CAanK;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAMxD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAE/D"}
package/dist/awake.js ADDED
@@ -0,0 +1,57 @@
1
+ // Since when the computer has been awake, kept across agent restarts. Time asleep or switched off never counts as records
2
+ // waiting, but a restart of the agent alone (an update, a crash, `stop` and `run`) is not sleep: before this, every
3
+ // restart counted waiting again from the agent's start, so a four-hour backlog showed as protected for fifteen minutes.
4
+ import { readFileSync, writeFileSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ export const AWAKE_FILE = "agent-awake.json";
7
+ /** Where waiting is counted from when the agent starts. The tray counts waiting as `now - max(oldest record, this)`.
8
+ * - The last cycle was recent and after the computer started: the agent restarted while the computer stayed awake, so the
9
+ * saved wake time stands (never earlier than the computer's start).
10
+ * - The computer started after the last cycle: it was off (or rebooted), so it has been awake since it started, and the
11
+ * oldest record counts from `max(its enqueue time, the computer's start)`.
12
+ * - A long gap since the last cycle without a restart of the computer. The agent cannot tell sleep (or a shutdown with
13
+ * Windows Fast Startup, which keeps the uptime) from an agent that was stopped, so it uses the records as evidence:
14
+ * - the oldest waiting record was written after the last cycle: the hook ran while the agent did not, so the computer was
15
+ * awake and the agent was not running; waiting counts from that record (`now - max(record, computer's start)`);
16
+ * - the oldest waiting record is older than the gap: the time it waited before the gap, while the agent ran its cycles,
17
+ * was awake time and still counts; the gap itself does not (it may have been sleep). Waiting resumes from there.
18
+ * - nothing waiting: from now.
19
+ * - No saved state, or times that make no sense (a clock moved back): from now. */
20
+ export function awakeSinceAtStart(input) {
21
+ const { saved, now } = input;
22
+ const bootAt = now - Math.max(0, input.uptimeMs);
23
+ if (!saved)
24
+ return now;
25
+ const { awake_since: since, last_cycle_at: last } = saved;
26
+ if (last > now || since > last)
27
+ return now;
28
+ if (last < bootAt)
29
+ return bootAt;
30
+ if (now - last <= input.allowedGapMs)
31
+ return Math.max(since, bootAt);
32
+ const oldest = input.oldestPendingAt;
33
+ if (oldest === null || oldest === undefined || !Number.isFinite(oldest) || oldest > now)
34
+ return now;
35
+ if (oldest > last)
36
+ return Math.max(oldest, bootAt);
37
+ const awakeBeforeGap = Math.max(0, last - Math.max(oldest, since, bootAt));
38
+ return now - awakeBeforeGap;
39
+ }
40
+ /** The saved state, or null when there is none or it cannot be read. */
41
+ export function readAwake(dir) {
42
+ try {
43
+ const raw = JSON.parse(readFileSync(join(dir, AWAKE_FILE), "utf8"));
44
+ return Number.isFinite(raw.awake_since) && Number.isFinite(raw.last_cycle_at)
45
+ ? { awake_since: Number(raw.awake_since), last_cycle_at: Number(raw.last_cycle_at) } : null;
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ export function writeAwake(dir, state) {
52
+ try {
53
+ writeFileSync(join(dir, AWAKE_FILE), `${JSON.stringify(state)}\n`);
54
+ }
55
+ catch { /* the next cycle writes it again */ }
56
+ }
57
+ //# sourceMappingURL=awake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"awake.js","sourceRoot":"","sources":["../src/awake.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAC1H,oHAAoH;AACpH,wHAAwH;AAExH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,UAAU,GAAG,kBAAkB,CAAC;AAS7C;;;;;;;;;;;;oFAYoF;AACpF,MAAM,UAAU,iBAAiB,CAAC,KAAyH;IACzJ,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;IAC7B,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK;QAAE,OAAO,GAAG,CAAC;IACvB,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IAC1D,IAAI,IAAI,GAAG,GAAG,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC;IAC3C,IAAI,IAAI,GAAG,MAAM;QAAE,OAAO,MAAM,CAAC;IACjC,IAAI,GAAG,GAAG,IAAI,IAAI,KAAK,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,KAAK,CAAC,eAAe,CAAC;IACrC,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO,GAAG,CAAC;IACpG,IAAI,MAAM,GAAG,IAAI;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3E,OAAO,GAAG,GAAG,cAAc,CAAC;AAC9B,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAwB,CAAC;QAC3F,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC;YAC3E,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAChG,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,KAAiB;IACvD,IAAI,CAAC;QAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,oCAAoC,CAAC,CAAC;AAC5H,CAAC","sourcesContent":["// Since when the computer has been awake, kept across agent restarts. Time asleep or switched off never counts as records\n// waiting, but a restart of the agent alone (an update, a crash, `stop` and `run`) is not sleep: before this, every\n// restart counted waiting again from the agent's start, so a four-hour backlog showed as protected for fifteen minutes.\n\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport const AWAKE_FILE = \"agent-awake.json\";\n\nexport interface AwakeState {\n /** When the computer last woke (or started), as this agent saw it, in milliseconds. */\n awake_since: number;\n /** When this agent last ran a cycle. */\n last_cycle_at: number;\n}\n\n/** Where waiting is counted from when the agent starts. The tray counts waiting as `now - max(oldest record, this)`.\n * - The last cycle was recent and after the computer started: the agent restarted while the computer stayed awake, so the\n * saved wake time stands (never earlier than the computer's start).\n * - The computer started after the last cycle: it was off (or rebooted), so it has been awake since it started, and the\n * oldest record counts from `max(its enqueue time, the computer's start)`.\n * - A long gap since the last cycle without a restart of the computer. The agent cannot tell sleep (or a shutdown with\n * Windows Fast Startup, which keeps the uptime) from an agent that was stopped, so it uses the records as evidence:\n * - the oldest waiting record was written after the last cycle: the hook ran while the agent did not, so the computer was\n * awake and the agent was not running; waiting counts from that record (`now - max(record, computer's start)`);\n * - the oldest waiting record is older than the gap: the time it waited before the gap, while the agent ran its cycles,\n * was awake time and still counts; the gap itself does not (it may have been sleep). Waiting resumes from there.\n * - nothing waiting: from now.\n * - No saved state, or times that make no sense (a clock moved back): from now. */\nexport function awakeSinceAtStart(input: { saved: AwakeState | null; now: number; uptimeMs: number; allowedGapMs: number; oldestPendingAt?: number | null }): number {\n const { saved, now } = input;\n const bootAt = now - Math.max(0, input.uptimeMs);\n if (!saved) return now;\n const { awake_since: since, last_cycle_at: last } = saved;\n if (last > now || since > last) return now;\n if (last < bootAt) return bootAt;\n if (now - last <= input.allowedGapMs) return Math.max(since, bootAt);\n const oldest = input.oldestPendingAt;\n if (oldest === null || oldest === undefined || !Number.isFinite(oldest) || oldest > now) return now;\n if (oldest > last) return Math.max(oldest, bootAt);\n const awakeBeforeGap = Math.max(0, last - Math.max(oldest, since, bootAt));\n return now - awakeBeforeGap;\n}\n\n/** The saved state, or null when there is none or it cannot be read. */\nexport function readAwake(dir: string): AwakeState | null {\n try {\n const raw = JSON.parse(readFileSync(join(dir, AWAKE_FILE), \"utf8\")) as Partial<AwakeState>;\n return Number.isFinite(raw.awake_since) && Number.isFinite(raw.last_cycle_at)\n ? { awake_since: Number(raw.awake_since), last_cycle_at: Number(raw.last_cycle_at) } : null;\n } catch { return null; }\n}\n\nexport function writeAwake(dir: string, state: AwakeState): void {\n try { writeFileSync(join(dir, AWAKE_FILE), `${JSON.stringify(state)}\\n`); } catch { /* the next cycle writes it again */ }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cli-main.d.ts","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"AAiDA,8HAA8H;AAC9H,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAuGhF"}
1
+ {"version":3,"file":"cli-main.d.ts","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"AAqDA,8HAA8H;AAC9H,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAuHhF"}
package/dist/cli-main.js CHANGED
@@ -10,9 +10,10 @@
10
10
  // scopebond-agent autostart on|off start with this user's sign-in, or stop doing so (off also stops it now)
11
11
  // scopebond-agent stop stop the running agent (autostart still starts it at the next sign-in)
12
12
  // scopebond-agent uninstall [--purge] autostart off, stop, the hook's uninstall (tells the workspace); what the installer runs
13
+ // scopebond-agent version this program's version and the hook it carries (an update checks the new one starts)
13
14
  import { spawnSync } from "node:child_process";
14
15
  import { homedir } from "node:os";
15
- import { hookSelfCommand, isEphemeralPath, userHome } from "@scopebond/hook";
16
+ import { hookSelfCommand, hookVersion, isEphemeralPath, userHome } from "@scopebond/hook";
16
17
  import { computerStatus } from "./agent.js";
17
18
  import { AGENT_LOG_ENV, autostartHealth, disableAutostart, enableAutostart, startNow } from "./autostart.js";
18
19
  import { callAgent } from "./ipc.js";
@@ -20,6 +21,9 @@ import { agentCliPath } from "./self.js";
20
21
  import { runSetup } from "./setup.js";
21
22
  import { agentVersion } from "./update.js";
22
23
  import { writeOutputTo } from "./log-file.js";
24
+ import { removeAppsEntry, writeAppsEntry } from "./apps-entry.js";
25
+ import { installKind } from "./native-update.js";
26
+ import { upkeepCommand } from "./upkeep.js";
23
27
  import { AGENT_VERSION, startService, takeOver } from "./service.js";
24
28
  let cmd = "help";
25
29
  let rest = [];
@@ -60,6 +64,15 @@ export async function main(argv = process.argv.slice(2)) {
60
64
  process.on("SIGTERM", stop);
61
65
  return;
62
66
  }
67
+ case "upkeep": {
68
+ // Internal: the agent runs its local store upkeep through this, in a process of its own.
69
+ upkeepCommand(dir, rest);
70
+ return;
71
+ }
72
+ case "version":
73
+ case "--version":
74
+ console.log(`agent/${agentVersion()} hook/${hookVersion()}`);
75
+ return;
63
76
  case "status": {
64
77
  const live = await callAgent(dir, "GET", "/status");
65
78
  const status = { ...(live ?? { ...computerStatus(dir), agent: null }), autostart: autostartHealth(dir) };
@@ -131,6 +144,9 @@ export async function main(argv = process.argv.slice(2)) {
131
144
  console.log(disableAutostart(dir));
132
145
  if (await stopRunning())
133
146
  console.log("Stopped the running Scopebond Agent.");
147
+ const listed = removeAppsEntry(dir);
148
+ if (listed)
149
+ console.log(listed);
134
150
  const [program, args] = hookSelfCommand(["uninstall", "--yes", ...(rest.includes("--purge") ? ["--purge"] : [])]);
135
151
  const removal = spawnSync(program, args, { stdio: "inherit", cwd: homedir(), env: { ...process.env, SCOPEBOND_HOME: dir } });
136
152
  process.exitCode = removal.status ?? 1;
@@ -150,6 +166,17 @@ export async function main(argv = process.argv.slice(2)) {
150
166
  return;
151
167
  }
152
168
  console.log(on ? enableAutostart(dir, agentCliPath()) : disableAutostart(dir));
169
+ // An npm install is listed in Settings -> Apps from here on (the signed installer has its own entry).
170
+ if (on && installKind() === "npm") {
171
+ try {
172
+ const listed = writeAppsEntry(dir, { version: agentVersion(), cli: agentCliPath() });
173
+ if (listed)
174
+ console.log(listed);
175
+ }
176
+ catch (error) {
177
+ console.error(`Could not list Scopebond in Settings -> Apps: ${error.message}`);
178
+ }
179
+ }
153
180
  if (!on) {
154
181
  // Off means off: an agent left running would keep going until sign-out, even after an uninstall.
155
182
  if (await stopRunning())
@@ -1 +1 @@
1
- {"version":3,"file":"cli-main.js","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"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","sourcesContent":["// 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// scopebond-agent uninstall [--purge] autostart off, stop, the hook's uninstall (tells the workspace); what the installer runs\n\nimport { spawnSync } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { hookSelfCommand, isEphemeralPath, userHome } from \"@scopebond/hook\";\nimport { computerStatus } from \"./agent.js\";\nimport { AGENT_LOG_ENV, autostartHealth, disableAutostart, enableAutostart, startNow } from \"./autostart.js\";\nimport { callAgent } from \"./ipc.js\";\nimport { agentCliPath } from \"./self.js\";\nimport { runSetup } from \"./setup.js\";\nimport { agentVersion } from \"./update.js\";\nimport { writeOutputTo } from \"./log-file.js\";\nimport { AGENT_VERSION, startService, takeOver } from \"./service.js\";\n\nlet cmd = \"help\";\nlet rest: string[] = [];\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();\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 ${c(\"uninstall [--purge]\")}stop it, stop starting it, take the hook out and tell the workspace\n\nThe hook keeps deciding every action on its own; the agent only keeps delivery, rules and the\nconnection current. Home: ${dir}`);\n}\n\n/** Run one command (`argv` as after the program name). cli.ts, the npm program, calls this; so does the single executable. */\nexport async function main(argv: string[] = process.argv.slice(2)): Promise<void> {\n [cmd = \"help\", ...rest] = argv;\n switch (cmd) {\n case \"run\": {\n // A launcher or a handover names the log; the agent writes it itself (see log-file.ts).\n const log = process.env[AGENT_LOG_ENV];\n if (log) writeOutputTo(log);\n // Started by an agent that just updated itself: let it exit first.\n await takeOver(dir, agentCliPath());\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 const updatedTo = (answer as { updatedTo?: unknown }).updatedTo;\n if (cmd === \"check\" && typeof updatedTo === \"string\") console.log(await afterUpdate(updatedTo));\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 \"uninstall\": {\n // What the Windows installer runs when Scopebond is removed (and anyone may run): stop and unregister the agent,\n // then the hook's own uninstall, which tells the workspace and takes the hook out of the coding agents' settings.\n // The Scopebond folder (keys, receipts) stays unless --purge.\n console.log(disableAutostart(dir));\n if (await stopRunning()) console.log(\"Stopped the running Scopebond Agent.\");\n const [program, args] = hookSelfCommand([\"uninstall\", \"--yes\", ...(rest.includes(\"--purge\") ? [\"--purge\"] : [])]);\n const removal = spawnSync(program, args, { stdio: \"inherit\", cwd: homedir(), env: { ...process.env, SCOPEBOND_HOME: dir } });\n process.exitCode = removal.status ?? 1;\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(agentCliPath())) {\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, agentCliPath()) : 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 if (await startAndWait()) {\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 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/** Start the agent through its autostart launcher and wait until it answers. Each way of starting it gets a few seconds;\n * a headless console that never starts falls back to a hidden cmd.exe. Whether it answers. */\nasync function startAndWait(): Promise<boolean> {\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)) return true;\n }\n }\n return false;\n}\n\n/** After `check` updated the agent: wait for the updated one to answer, start it if nothing does, and say which version runs. */\nasync function afterUpdate(version: string): Promise<string> {\n const running = async () => ((await callAgent(dir, \"GET\", \"/status\", undefined, 1_000)) as { agent?: AgentReport | null } | null)?.agent?.version ?? null;\n let seen: string | null = null;\n for (let i = 0; i < 60; i++) {\n await new Promise((r) => setTimeout(r, 1_000));\n seen = await running();\n if (seen === `agent/${version}`) return `The Scopebond Agent ${version} is running.`;\n }\n if (seen) return `The Scopebond Agent running now is ${seen.replace(/^agent\\//, \"\")}, not ${version}. Restart it with: ${me} stop, then ${me} autostart on`;\n if (autostartHealth(dir).on && await startAndWait()) return \"The updated agent had not started; it is running now.\";\n return `The updated agent is not running. Start it with: ${me} autostart on`;\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\n"]}
1
+ {"version":3,"file":"cli-main.js","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"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","sourcesContent":["// 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// scopebond-agent uninstall [--purge] autostart off, stop, the hook's uninstall (tells the workspace); what the installer runs\n// scopebond-agent version this program's version and the hook it carries (an update checks the new one starts)\n\nimport { spawnSync } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { hookSelfCommand, hookVersion, isEphemeralPath, userHome } from \"@scopebond/hook\";\nimport { computerStatus } from \"./agent.js\";\nimport { AGENT_LOG_ENV, autostartHealth, disableAutostart, enableAutostart, startNow } from \"./autostart.js\";\nimport { callAgent } from \"./ipc.js\";\nimport { agentCliPath } from \"./self.js\";\nimport { runSetup } from \"./setup.js\";\nimport { agentVersion } from \"./update.js\";\nimport { writeOutputTo } from \"./log-file.js\";\nimport { removeAppsEntry, writeAppsEntry } from \"./apps-entry.js\";\nimport { installKind } from \"./native-update.js\";\nimport { upkeepCommand } from \"./upkeep.js\";\nimport { AGENT_VERSION, startService, takeOver } from \"./service.js\";\n\nlet cmd = \"help\";\nlet rest: string[] = [];\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();\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 ${c(\"uninstall [--purge]\")}stop it, stop starting it, take the hook out and tell the workspace\n\nThe hook keeps deciding every action on its own; the agent only keeps delivery, rules and the\nconnection current. Home: ${dir}`);\n}\n\n/** Run one command (`argv` as after the program name). cli.ts, the npm program, calls this; so does the single executable. */\nexport async function main(argv: string[] = process.argv.slice(2)): Promise<void> {\n [cmd = \"help\", ...rest] = argv;\n switch (cmd) {\n case \"run\": {\n // A launcher or a handover names the log; the agent writes it itself (see log-file.ts).\n const log = process.env[AGENT_LOG_ENV];\n if (log) writeOutputTo(log);\n // Started by an agent that just updated itself: let it exit first.\n await takeOver(dir, agentCliPath());\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 \"upkeep\": {\n // Internal: the agent runs its local store upkeep through this, in a process of its own.\n upkeepCommand(dir, rest);\n return;\n }\n case \"version\":\n case \"--version\":\n console.log(`agent/${agentVersion()} hook/${hookVersion()}`);\n return;\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 const updatedTo = (answer as { updatedTo?: unknown }).updatedTo;\n if (cmd === \"check\" && typeof updatedTo === \"string\") console.log(await afterUpdate(updatedTo));\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 \"uninstall\": {\n // What the Windows installer runs when Scopebond is removed (and anyone may run): stop and unregister the agent,\n // then the hook's own uninstall, which tells the workspace and takes the hook out of the coding agents' settings.\n // The Scopebond folder (keys, receipts) stays unless --purge.\n console.log(disableAutostart(dir));\n if (await stopRunning()) console.log(\"Stopped the running Scopebond Agent.\");\n const listed = removeAppsEntry(dir);\n if (listed) console.log(listed);\n const [program, args] = hookSelfCommand([\"uninstall\", \"--yes\", ...(rest.includes(\"--purge\") ? [\"--purge\"] : [])]);\n const removal = spawnSync(program, args, { stdio: \"inherit\", cwd: homedir(), env: { ...process.env, SCOPEBOND_HOME: dir } });\n process.exitCode = removal.status ?? 1;\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(agentCliPath())) {\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, agentCliPath()) : disableAutostart(dir));\n // An npm install is listed in Settings -> Apps from here on (the signed installer has its own entry).\n if (on && installKind() === \"npm\") {\n try { const listed = writeAppsEntry(dir, { version: agentVersion(), cli: agentCliPath() }); if (listed) console.log(listed); }\n catch (error) { console.error(`Could not list Scopebond in Settings -> Apps: ${(error as Error).message}`); }\n }\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 if (await startAndWait()) {\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 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/** Start the agent through its autostart launcher and wait until it answers. Each way of starting it gets a few seconds;\n * a headless console that never starts falls back to a hidden cmd.exe. Whether it answers. */\nasync function startAndWait(): Promise<boolean> {\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)) return true;\n }\n }\n return false;\n}\n\n/** After `check` updated the agent: wait for the updated one to answer, start it if nothing does, and say which version runs. */\nasync function afterUpdate(version: string): Promise<string> {\n const running = async () => ((await callAgent(dir, \"GET\", \"/status\", undefined, 1_000)) as { agent?: AgentReport | null } | null)?.agent?.version ?? null;\n let seen: string | null = null;\n for (let i = 0; i < 60; i++) {\n await new Promise((r) => setTimeout(r, 1_000));\n seen = await running();\n if (seen === `agent/${version}`) return `The Scopebond Agent ${version} is running.`;\n }\n if (seen) return `The Scopebond Agent running now is ${seen.replace(/^agent\\//, \"\")}, not ${version}. Restart it with: ${me} stop, then ${me} autostart on`;\n if (autostartHealth(dir).on && await startAndWait()) return \"The updated agent had not started; it is running now.\";\n return `The updated agent is not running. Start it with: ${me} autostart on`;\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\n"]}
package/dist/index.d.ts CHANGED
@@ -1,21 +1,26 @@
1
1
  export { runCycle, computerStatus, expectedHarnesses, missingHookEntries } from "./agent.js";
2
2
  export type { CycleOptions, CycleResult } from "./agent.js";
3
- export { startService, repairHookEntries, spawnReplacement, handoverPlan, takeOver, acquireAgentLock, releaseAgentLock, AGENT_LOCK, AGENT_VERSION, AFTER_PID_ENV, REFRESH_LAUNCHER_ENV, RESTART_EXIT_CODE } from "./service.js";
3
+ export { startService, repairHookEntries, spawnReplacement, handoverPlan, takeOver, acquireAgentLock, releaseAgentLock, lockHeldBy, waitForAgentVersion, HANDOVER_CONFIRM_MS, AGENT_LOCK, AGENT_VERSION, AFTER_PID_ENV, REFRESH_LAUNCHER_ENV, RESTART_EXIT_CODE, STOPPED_FILE } from "./service.js";
4
4
  export type { Handover } from "./service.js";
5
5
  export { writeOutputTo, FALLBACK_LOG } from "./log-file.js";
6
6
  export type { Service, ServiceOptions, MaintenanceResult } from "./service.js";
7
+ export { appsEntryValues, uninstallScript, writeUninstallScript, writeAppsEntry, removeAppsEntry, npmBeside, psQuote, UNINSTALL_KEY, UNINSTALL_SCRIPT, UTF8_BOM } from "./apps-entry.js";
8
+ export { awakeSinceAtStart, readAwake, writeAwake, AWAKE_FILE } from "./awake.js";
9
+ export type { AwakeState } from "./awake.js";
10
+ export { runUpkeepApart, upkeepCommand, UPKEEP_BUDGET_MS, UPKEEP_TIMEOUT_MS } from "./upkeep.js";
11
+ export type { UpkeepReport, UpkeepApartOptions } from "./upkeep.js";
7
12
  export { startControl, callAgent, readEndpoint, localSocketPath, AGENT_FILE, TOKEN_HEADER } from "./ipc.js";
8
13
  export type { AgentEndpoint } from "./ipc.js";
9
- export { launcherPath, windowsLauncher, posixLauncher, windowsRunCommand, macLaunchAgent, linuxUserUnit, enableAutostart, disableAutostart, autostartHealth, autostartPaths, startCommands, startNow, LABEL, AGENT_LOG_ENV, LAUNCHER_MARK, launcherIsCurrent, refreshLauncher, } from "./autostart.js";
10
- export { agentVersion, fetchClientVersion, compareVersions, commandHookVersion, maintainedHookCommand, maintainHookEntries, installAgent, ownNpm, } from "./update.js";
11
- export type { ClientVersion } from "./update.js";
14
+ export { launcherPath, windowsLauncher, posixLauncher, windowsRunCommand, macLaunchAgent, linuxUserUnit, enableAutostart, disableAutostart, autostartHealth, autostartPaths, startCommands, startNow, LABEL, AGENT_LOG_ENV, LAUNCHER_MARK, launcherIsCurrent, refreshLauncher, retireLauncherRunValue, TRAY_RUN_VALUE, } from "./autostart.js";
15
+ export { agentVersion, fetchClientVersion, compareVersions, commandHookVersion, maintainedHookCommand, maintainHookEntries, installAgent, ownNpm, isVersion, npmInstallArgs, npmEnvironment, checkProvenance, startCheck, recordFailedUpdate, recentlyFailedUpdate, NPM_REGISTRY, PROVENANCE_REPOSITORY, PROVENANCE_REF, CLIENT_VERSION_MAX_BYTES, FAILED_UPDATE_FILE, FAILED_UPDATE_RETRY_MS, } from "./update.js";
16
+ export type { ClientVersion, ProvenanceResult } from "./update.js";
12
17
  export { selfCheckProof, localChecks, runSelfCheck } from "./selfcheck.js";
13
18
  export { parseQuestion, questionText, windowsScript, systemPrompter, serialized } from "./prompt.js";
14
19
  export type { OverrideQuestion, OverrideAnswer, Prompter } from "./prompt.js";
15
20
  export { queueReason, flushReasons, pendingReasons, REASONS_FILE } from "./override-reasons.js";
16
21
  export type { SelfCheckItem } from "./selfcheck.js";
17
- export { setupPlan, globalBinDir, onPath, addToPathCommand, nodeSupported, runSetup } from "./setup.js";
22
+ export { setupPlan, agentOnThisComputer, globalBinDir, onPath, addToPathCommand, nodeSupported, runSetup } from "./setup.js";
18
23
  export type { SetupState, SetupStep, SetupOptions } from "./setup.js";
19
- export { installKind, updaterPublicKey, verifyManifest, fetchVerifiedInstaller, installerName, MANIFEST_DOMAIN, PUBLISHER } from "./native-update.js";
20
- export type { InstallKind, ReleaseManifest } from "./native-update.js";
24
+ export { installKind, updaterKeys, keyId, verifyManifest, fetchVerifiedInstaller, installerName, installerUnchanged, installHelperScript, installerRecheckScript, windowsTool, installHelper, installAfterExitScript, nativeTrayPath, takeInstallResult, INSTALL_HELPER_SCRIPT, INSTALL_RESULT, MANIFEST_DOMAIN, PUBLISHER, } from "./native-update.js";
25
+ export type { InstallKind, ReleaseManifest, UpdaterKey, VerifiedInstaller } from "./native-update.js";
21
26
  //# sourceMappingURL=index.d.ts.map
@@ -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,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAChO,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC5D,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC5G,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,EAClG,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,GACjE,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;AACtE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,sBAAsB,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACtJ,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,12 +1,15 @@
1
1
  export { runCycle, computerStatus, expectedHarnesses, missingHookEntries } from "./agent.js";
2
- export { startService, repairHookEntries, spawnReplacement, handoverPlan, takeOver, acquireAgentLock, releaseAgentLock, AGENT_LOCK, AGENT_VERSION, AFTER_PID_ENV, REFRESH_LAUNCHER_ENV, RESTART_EXIT_CODE } from "./service.js";
2
+ export { startService, repairHookEntries, spawnReplacement, handoverPlan, takeOver, acquireAgentLock, releaseAgentLock, lockHeldBy, waitForAgentVersion, HANDOVER_CONFIRM_MS, AGENT_LOCK, AGENT_VERSION, AFTER_PID_ENV, REFRESH_LAUNCHER_ENV, RESTART_EXIT_CODE, STOPPED_FILE } from "./service.js";
3
3
  export { writeOutputTo, FALLBACK_LOG } from "./log-file.js";
4
+ export { appsEntryValues, uninstallScript, writeUninstallScript, writeAppsEntry, removeAppsEntry, npmBeside, psQuote, UNINSTALL_KEY, UNINSTALL_SCRIPT, UTF8_BOM } from "./apps-entry.js";
5
+ export { awakeSinceAtStart, readAwake, writeAwake, AWAKE_FILE } from "./awake.js";
6
+ export { runUpkeepApart, upkeepCommand, UPKEEP_BUDGET_MS, UPKEEP_TIMEOUT_MS } from "./upkeep.js";
4
7
  export { startControl, callAgent, readEndpoint, localSocketPath, AGENT_FILE, TOKEN_HEADER } from "./ipc.js";
5
- export { launcherPath, windowsLauncher, posixLauncher, windowsRunCommand, macLaunchAgent, linuxUserUnit, enableAutostart, disableAutostart, autostartHealth, autostartPaths, startCommands, startNow, LABEL, AGENT_LOG_ENV, LAUNCHER_MARK, launcherIsCurrent, refreshLauncher, } from "./autostart.js";
6
- export { agentVersion, fetchClientVersion, compareVersions, commandHookVersion, maintainedHookCommand, maintainHookEntries, installAgent, ownNpm, } from "./update.js";
8
+ export { launcherPath, windowsLauncher, posixLauncher, windowsRunCommand, macLaunchAgent, linuxUserUnit, enableAutostart, disableAutostart, autostartHealth, autostartPaths, startCommands, startNow, LABEL, AGENT_LOG_ENV, LAUNCHER_MARK, launcherIsCurrent, refreshLauncher, retireLauncherRunValue, TRAY_RUN_VALUE, } from "./autostart.js";
9
+ export { agentVersion, fetchClientVersion, compareVersions, commandHookVersion, maintainedHookCommand, maintainHookEntries, installAgent, ownNpm, isVersion, npmInstallArgs, npmEnvironment, checkProvenance, startCheck, recordFailedUpdate, recentlyFailedUpdate, NPM_REGISTRY, PROVENANCE_REPOSITORY, PROVENANCE_REF, CLIENT_VERSION_MAX_BYTES, FAILED_UPDATE_FILE, FAILED_UPDATE_RETRY_MS, } from "./update.js";
7
10
  export { selfCheckProof, localChecks, runSelfCheck } from "./selfcheck.js";
8
11
  export { parseQuestion, questionText, windowsScript, systemPrompter, serialized } from "./prompt.js";
9
12
  export { queueReason, flushReasons, pendingReasons, REASONS_FILE } from "./override-reasons.js";
10
- export { setupPlan, globalBinDir, onPath, addToPathCommand, nodeSupported, runSetup } from "./setup.js";
11
- export { installKind, updaterPublicKey, verifyManifest, fetchVerifiedInstaller, installerName, MANIFEST_DOMAIN, PUBLISHER } from "./native-update.js";
13
+ export { setupPlan, agentOnThisComputer, globalBinDir, onPath, addToPathCommand, nodeSupported, runSetup } from "./setup.js";
14
+ export { installKind, updaterKeys, keyId, verifyManifest, fetchVerifiedInstaller, installerName, installerUnchanged, installHelperScript, installerRecheckScript, windowsTool, installHelper, installAfterExitScript, nativeTrayPath, takeInstallResult, INSTALL_HELPER_SCRIPT, INSTALL_RESULT, MANIFEST_DOMAIN, PUBLISHER, } from "./native-update.js";
12
15
  //# 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,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEhO,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE5G,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,EAClG,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,GACjE,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;AAExG,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,sBAAsB,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export { runCycle, computerStatus, expectedHarnesses, missingHookEntries } from \"./agent.js\";\nexport type { CycleOptions, CycleResult } from \"./agent.js\";\nexport { startService, repairHookEntries, spawnReplacement, handoverPlan, takeOver, acquireAgentLock, releaseAgentLock, AGENT_LOCK, AGENT_VERSION, AFTER_PID_ENV, REFRESH_LAUNCHER_ENV, RESTART_EXIT_CODE } from \"./service.js\";\nexport type { Handover } from \"./service.js\";\nexport { writeOutputTo, FALLBACK_LOG } from \"./log-file.js\";\nexport type { Service, ServiceOptions, MaintenanceResult } from \"./service.js\";\nexport { startControl, callAgent, readEndpoint, localSocketPath, 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 AGENT_LOG_ENV, LAUNCHER_MARK, launcherIsCurrent, refreshLauncher,\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\";\nexport { installKind, updaterPublicKey, verifyManifest, fetchVerifiedInstaller, installerName, MANIFEST_DOMAIN, PUBLISHER } from \"./native-update.js\";\nexport type { InstallKind, ReleaseManifest } from \"./native-update.js\";\n"]}
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,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEpS,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,oBAAoB,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACzL,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAElF,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEjG,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE5G,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,EAClG,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,sBAAsB,EAAE,cAAc,GACzG,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,EACvI,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,kBAAkB,EAAE,oBAAoB,EAChH,YAAY,EAAE,qBAAqB,EAAE,cAAc,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,sBAAsB,GAC1H,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,mBAAmB,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE7H,OAAO,EACL,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,aAAa,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,sBAAsB,EACvJ,WAAW,EAAE,aAAa,EAAE,sBAAsB,EAAE,cAAc,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,GACzJ,MAAM,oBAAoB,CAAC","sourcesContent":["export { runCycle, computerStatus, expectedHarnesses, missingHookEntries } from \"./agent.js\";\nexport type { CycleOptions, CycleResult } from \"./agent.js\";\nexport { startService, repairHookEntries, spawnReplacement, handoverPlan, takeOver, acquireAgentLock, releaseAgentLock, lockHeldBy, waitForAgentVersion, HANDOVER_CONFIRM_MS, AGENT_LOCK, AGENT_VERSION, AFTER_PID_ENV, REFRESH_LAUNCHER_ENV, RESTART_EXIT_CODE, STOPPED_FILE } from \"./service.js\";\nexport type { Handover } from \"./service.js\";\nexport { writeOutputTo, FALLBACK_LOG } from \"./log-file.js\";\nexport type { Service, ServiceOptions, MaintenanceResult } from \"./service.js\";\nexport { appsEntryValues, uninstallScript, writeUninstallScript, writeAppsEntry, removeAppsEntry, npmBeside, psQuote, UNINSTALL_KEY, UNINSTALL_SCRIPT, UTF8_BOM } from \"./apps-entry.js\";\nexport { awakeSinceAtStart, readAwake, writeAwake, AWAKE_FILE } from \"./awake.js\";\nexport type { AwakeState } from \"./awake.js\";\nexport { runUpkeepApart, upkeepCommand, UPKEEP_BUDGET_MS, UPKEEP_TIMEOUT_MS } from \"./upkeep.js\";\nexport type { UpkeepReport, UpkeepApartOptions } from \"./upkeep.js\";\nexport { startControl, callAgent, readEndpoint, localSocketPath, 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 AGENT_LOG_ENV, LAUNCHER_MARK, launcherIsCurrent, refreshLauncher, retireLauncherRunValue, TRAY_RUN_VALUE,\n} from \"./autostart.js\";\nexport {\n agentVersion, fetchClientVersion, compareVersions, commandHookVersion, maintainedHookCommand, maintainHookEntries, installAgent, ownNpm,\n isVersion, npmInstallArgs, npmEnvironment, checkProvenance, startCheck, recordFailedUpdate, recentlyFailedUpdate,\n NPM_REGISTRY, PROVENANCE_REPOSITORY, PROVENANCE_REF, CLIENT_VERSION_MAX_BYTES, FAILED_UPDATE_FILE, FAILED_UPDATE_RETRY_MS,\n} from \"./update.js\";\nexport type { ClientVersion, ProvenanceResult } 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, agentOnThisComputer, globalBinDir, onPath, addToPathCommand, nodeSupported, runSetup } from \"./setup.js\";\nexport type { SetupState, SetupStep, SetupOptions } from \"./setup.js\";\nexport {\n installKind, updaterKeys, keyId, verifyManifest, fetchVerifiedInstaller, installerName, installerUnchanged, installHelperScript, installerRecheckScript,\n windowsTool, installHelper, installAfterExitScript, nativeTrayPath, takeInstallResult, INSTALL_HELPER_SCRIPT, INSTALL_RESULT, MANIFEST_DOMAIN, PUBLISHER,\n} from \"./native-update.js\";\nexport type { InstallKind, ReleaseManifest, UpdaterKey, VerifiedInstaller } from \"./native-update.js\";\n"]}
package/dist/ipc.d.ts CHANGED
@@ -14,14 +14,19 @@ export interface AgentEndpoint {
14
14
  * first. Elsewhere: `run/agent.sock` in the Scopebond home (folder 0700), or a private folder under the temporary folder
15
15
  * when that path is longer than a Unix socket path may be. */
16
16
  export declare function localSocketPath(dir: string, platform?: NodeJS.Platform, random?: string): string;
17
- export type Handler = (body: unknown) => Promise<unknown> | unknown;
17
+ /** Returns the answer, or a promise of it. */
18
+ export type Handler = (body: unknown) => unknown;
18
19
  export declare function readEndpoint(dir: string): AgentEndpoint | null;
19
- /** Start the control server. `routes` maps "METHOD /path" to a handler. */
20
- export declare function startControl(dir: string, version: string, routes: Record<string, Handler>): Promise<{
20
+ /** Start the control server. `routes` maps "METHOD /path" to a handler. `loopback`: also listen on 127.0.0.1 (default:
21
+ * unless SCOPEBOND_AGENT_LOOPBACK=0); it is used anyway when the pipe or socket could not be made, or nothing could reach
22
+ * the agent. */
23
+ export declare function startControl(dir: string, version: string, routes: Record<string, Handler>, options?: {
24
+ loopback?: boolean;
25
+ }): Promise<{
21
26
  server: Server;
22
27
  endpoint: AgentEndpoint;
23
28
  close(): Promise<void>;
24
29
  }>;
25
30
  /** Call a running agent, over its pipe or socket when it has one. Returns null when no agent answers. */
26
- export declare function callAgent(dir: string, method: "GET" | "POST", path: string, body?: unknown, timeoutMs?: number): Promise<unknown | null>;
31
+ export declare function callAgent(dir: string, method: "GET" | "POST", path: string, body?: unknown, timeoutMs?: number): Promise<unknown>;
27
32
  //# sourceMappingURL=ipc.d.ts.map
package/dist/ipc.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ipc.d.ts","sourceRoot":"","sources":["../src/ipc.ts"],"names":[],"mappings":"AAOA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AAOjG,eAAO,MAAM,UAAU,eAAe,CAAC;AACvC,eAAO,MAAM,YAAY,4BAA4B,CAAC;AAEtD,8GAA8G;AAC9G,MAAM,WAAW,aAAa;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AAExI;;+DAE+D;AAC/D,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAAE,MAAM,SAAkC,GAAG,MAAM,CAK3I;AAED,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAEpE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAI9D;AAED,2EAA2E;AAC3E,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC;IAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAkD9K;AAED,yGAAyG;AACzG,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,SAAQ,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAe7I"}
1
+ {"version":3,"file":"ipc.d.ts","sourceRoot":"","sources":["../src/ipc.ts"],"names":[],"mappings":"AAQA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AAOjG,eAAO,MAAM,UAAU,eAAe,CAAC;AACvC,eAAO,MAAM,YAAY,4BAA4B,CAAC;AAEtD,8GAA8G;AAC9G,MAAM,WAAW,aAAa;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AAExI;;+DAE+D;AAC/D,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAAE,MAAM,SAAkC,GAAG,MAAM,CAK3I;AAED,8CAA8C;AAC9C,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC;AAEjD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAI9D;AAED;;iBAEiB;AACjB,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC;IAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAqDpN;AAED,yGAAyG;AACzG,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,SAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAetI"}