@scopebond/agent 0.5.5 → 0.6.0

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 (55) 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/apps-entry.d.ts +46 -0
  6. package/dist/apps-entry.d.ts.map +1 -0
  7. package/dist/apps-entry.js +118 -0
  8. package/dist/apps-entry.js.map +1 -0
  9. package/dist/autostart.d.ts +11 -5
  10. package/dist/autostart.d.ts.map +1 -1
  11. package/dist/autostart.js +59 -5
  12. package/dist/autostart.js.map +1 -1
  13. package/dist/awake.d.ts +31 -0
  14. package/dist/awake.d.ts.map +1 -0
  15. package/dist/awake.js +57 -0
  16. package/dist/awake.js.map +1 -0
  17. package/dist/cli-main.d.ts.map +1 -1
  18. package/dist/cli-main.js +28 -1
  19. package/dist/cli-main.js.map +1 -1
  20. package/dist/index.d.ts +12 -7
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +8 -5
  23. package/dist/index.js.map +1 -1
  24. package/dist/ipc.d.ts +6 -2
  25. package/dist/ipc.d.ts.map +1 -1
  26. package/dist/ipc.js +11 -7
  27. package/dist/ipc.js.map +1 -1
  28. package/dist/native-update.d.ts +83 -7
  29. package/dist/native-update.d.ts.map +1 -1
  30. package/dist/native-update.js +230 -33
  31. package/dist/native-update.js.map +1 -1
  32. package/dist/selfcheck.d.ts.map +1 -1
  33. package/dist/selfcheck.js +4 -1
  34. package/dist/selfcheck.js.map +1 -1
  35. package/dist/service.d.ts +20 -3
  36. package/dist/service.d.ts.map +1 -1
  37. package/dist/service.js +141 -44
  38. package/dist/service.js.map +1 -1
  39. package/dist/setup.d.ts +12 -0
  40. package/dist/setup.d.ts.map +1 -1
  41. package/dist/setup.js +41 -12
  42. package/dist/setup.js.map +1 -1
  43. package/dist/tray-model.d.ts +2 -0
  44. package/dist/tray-model.d.ts.map +1 -1
  45. package/dist/tray-model.js +2 -0
  46. package/dist/tray-model.js.map +1 -1
  47. package/dist/update.d.ts +56 -12
  48. package/dist/update.d.ts.map +1 -1
  49. package/dist/update.js +209 -38
  50. package/dist/update.js.map +1 -1
  51. package/dist/upkeep.d.ts +16 -0
  52. package/dist/upkeep.d.ts.map +1 -0
  53. package/dist/upkeep.js +55 -0
  54. package/dist/upkeep.js.map +1 -0
  55. package/package.json +3 -3
@@ -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
@@ -16,8 +16,12 @@ export interface AgentEndpoint {
16
16
  export declare function localSocketPath(dir: string, platform?: NodeJS.Platform, random?: string): string;
17
17
  export type Handler = (body: unknown) => Promise<unknown> | unknown;
18
18
  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<{
19
+ /** Start the control server. `routes` maps "METHOD /path" to a handler. `loopback`: also listen on 127.0.0.1 (default:
20
+ * unless SCOPEBOND_AGENT_LOOPBACK=0); it is used anyway when the pipe or socket could not be made, or nothing could reach
21
+ * the agent. */
22
+ export declare function startControl(dir: string, version: string, routes: Record<string, Handler>, options?: {
23
+ loopback?: boolean;
24
+ }): Promise<{
21
25
  server: Server;
22
26
  endpoint: AgentEndpoint;
23
27
  close(): Promise<void>;
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,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;;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,CAmDpN;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"}
package/dist/ipc.js CHANGED
@@ -1,7 +1,8 @@
1
1
  // The agent's local control channel: HTTP with a random token, over a named pipe on Windows (a random name) or a Unix
2
- // socket in a folder only this user can open, and for one more release also on 127.0.0.1 at a random port (the PowerShell
3
- // tray uses it; SCOPEBOND_AGENT_LOOPBACK=0 turns it off). The pipe or socket, the port, the token and the process id are
4
- // written to agent.json in the Scopebond home, which is how the CLI, the hook's override window and the tray find it.
2
+ // socket in a folder only this user can open. npm installs also listen on 127.0.0.1 at a random port, because the
3
+ // PowerShell tray and hooks before the pipe use it (SCOPEBOND_AGENT_LOOPBACK=0 turns it off); the signed install with the
4
+ // native tray does not (its tray and its hook use the pipe). The pipe or socket, the port, the token and the process id
5
+ // are written to agent.json in the Scopebond home, which is how the CLI, the hook's override window and the tray find it.
5
6
  // A loopback port can be reached by any program on the computer; the pipe's name and the socket's folder cannot be found
6
7
  // or opened by another user. Every request must carry the token either way.
7
8
  import { createServer } from "node:http";
@@ -34,8 +35,10 @@ export function readEndpoint(dir) {
34
35
  return null;
35
36
  }
36
37
  }
37
- /** Start the control server. `routes` maps "METHOD /path" to a handler. */
38
- export async function startControl(dir, version, routes) {
38
+ /** Start the control server. `routes` maps "METHOD /path" to a handler. `loopback`: also listen on 127.0.0.1 (default:
39
+ * unless SCOPEBOND_AGENT_LOOPBACK=0); it is used anyway when the pipe or socket could not be made, or nothing could reach
40
+ * the agent. */
41
+ export async function startControl(dir, version, routes, options = {}) {
39
42
  const token = randomBytes(24).toString("base64url");
40
43
  const expected = Buffer.from(token);
41
44
  const handle = async (req, res) => {
@@ -76,8 +79,9 @@ export async function startControl(dir, version, routes) {
76
79
  catch {
77
80
  socket = null;
78
81
  }
79
- // Loopback for one more release (the PowerShell tray), unless turned off; always when the pipe could not be made.
80
- const loopback = process.env.SCOPEBOND_AGENT_LOOPBACK !== "0" || socket === null;
82
+ // Loopback where something still needs it (the PowerShell tray, older hooks), unless turned off; always when the pipe
83
+ // could not be made.
84
+ const loopback = (options.loopback ?? process.env.SCOPEBOND_AGENT_LOOPBACK !== "0") || socket === null;
81
85
  const server = createServer(handle);
82
86
  if (loopback)
83
87
  await new Promise((resolve, reject) => { server.once("error", reject); server.listen(0, "127.0.0.1", () => resolve()); });
package/dist/ipc.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ipc.js","sourceRoot":"","sources":["../src/ipc.ts"],"names":[],"mappings":"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","sourcesContent":["// The agent's local control channel: HTTP with a random token, over a named pipe on Windows (a random name) or a Unix\n// socket in a folder only this user can open, and for one more release also on 127.0.0.1 at a random port (the PowerShell\n// tray uses it; SCOPEBOND_AGENT_LOOPBACK=0 turns it off). The pipe or socket, the port, the token and the process id are\n// written to agent.json in the Scopebond home, which is how the CLI, the hook's override window and the tray find it.\n// A loopback port can be reached by any program on the computer; the pipe's name and the socket's folder cannot be found\n// or opened by another user. Every request must carry the token either way.\n\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { randomBytes, timingSafeEqual } from \"node:crypto\";\nimport { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { requestOverSocket } from \"@scopebond/hook\";\n\nexport const AGENT_FILE = \"agent.json\";\nexport const TOKEN_HEADER = \"x-scopebond-agent-token\";\n\n/** `socket`: the named pipe or Unix socket (absent from agents before it); `port`: 0 when loopback is off. */\nexport interface AgentEndpoint { port: number; socket?: string | null; token: string; pid: number; started_at: number; version: string }\n\n/** Where this start's pipe or socket goes. Windows: a pipe whose name is random, so no other user can guess it or claim it\n * first. Elsewhere: `run/agent.sock` in the Scopebond home (folder 0700), or a private folder under the temporary folder\n * when that path is longer than a Unix socket path may be. */\nexport function localSocketPath(dir: string, platform: NodeJS.Platform = process.platform, random = randomBytes(16).toString(\"hex\")): string {\n if (platform === \"win32\") return `\\\\\\\\.\\\\pipe\\\\scopebond-agent-${random}`;\n const inHome = join(dir, \"run\", \"agent.sock\");\n if (Buffer.byteLength(inHome) <= 100) return inHome;\n return join(mkdtempSync(join(tmpdir(), \"scopebond-\")), \"agent.sock\");\n}\n\nexport type Handler = (body: unknown) => Promise<unknown> | unknown;\n\nexport function readEndpoint(dir: string): AgentEndpoint | null {\n const file = join(dir, AGENT_FILE);\n if (!existsSync(file)) return null;\n try { return JSON.parse(readFileSync(file, \"utf8\")) as AgentEndpoint; } catch { return null; }\n}\n\n/** Start the control server. `routes` maps \"METHOD /path\" to a handler. */\nexport async function startControl(dir: string, version: string, routes: Record<string, Handler>): Promise<{ server: Server; endpoint: AgentEndpoint; close(): Promise<void> }> {\n const token = randomBytes(24).toString(\"base64url\");\n const expected = Buffer.from(token);\n const handle = async (req: IncomingMessage, res: ServerResponse) => {\n const send = (status: number, body: unknown) => { res.writeHead(status, { \"content-type\": \"application/json; charset=utf-8\", \"cache-control\": \"no-store\" }); res.end(JSON.stringify(body)); };\n const offered = Buffer.from(String(req.headers[TOKEN_HEADER] ?? \"\"));\n if (offered.length !== expected.length || !timingSafeEqual(offered, expected)) return send(401, { error: \"unauthorized\" });\n const handler = routes[`${req.method} ${(req.url ?? \"/\").split(\"?\")[0]}`];\n if (!handler) return send(404, { error: \"not found\" });\n let raw = \"\";\n for await (const chunk of req) { raw += chunk; if (raw.length > 64 * 1024) return send(413, { error: \"too large\" }); }\n try { send(200, await handler(raw ? JSON.parse(raw) : null)); }\n catch (error) { send(500, { error: (error as Error).message.slice(0, 200) }); }\n };\n // The pipe or socket first. A Unix socket's folder is created for this user only, and the socket itself is too.\n const socketPath = localSocketPath(dir);\n const local = createServer(handle);\n let socket: string | null = socketPath;\n try {\n if (process.platform !== \"win32\") {\n mkdirSync(join(socketPath, \"..\"), { recursive: true, mode: 0o700 });\n chmodSync(join(socketPath, \"..\"), 0o700);\n rmSync(socketPath, { force: true });\n }\n await new Promise<void>((resolve, reject) => { local.once(\"error\", reject); local.listen(socketPath, () => resolve()); });\n if (process.platform !== \"win32\") chmodSync(socketPath, 0o600);\n } catch { socket = null; }\n // Loopback for one more release (the PowerShell tray), unless turned off; always when the pipe could not be made.\n const loopback = process.env.SCOPEBOND_AGENT_LOOPBACK !== \"0\" || socket === null;\n const server = createServer(handle);\n if (loopback) await new Promise<void>((resolve, reject) => { server.once(\"error\", reject); server.listen(0, \"127.0.0.1\", () => resolve()); });\n const address = loopback ? server.address() : null;\n const port = typeof address === \"object\" && address ? address.port : 0;\n const endpoint: AgentEndpoint = { port, socket, token, pid: process.pid, started_at: Date.now(), version };\n const file = join(dir, AGENT_FILE);\n const temp = `${file}.${process.pid}.tmp`;\n writeFileSync(temp, JSON.stringify(endpoint, null, 2) + \"\\n\", { mode: 0o600 });\n renameSync(temp, file);\n return {\n server, endpoint,\n close: () => new Promise<void>((resolve) => {\n let open = (loopback ? 1 : 0) + (socket ? 1 : 0);\n const done = () => { if (--open <= 0) resolve(); };\n if (open === 0) resolve();\n if (loopback) server.close(done);\n if (socket) local.close(() => { if (process.platform !== \"win32\") rmSync(socketPath, { force: true }); done(); });\n // Only remove the file if it is still ours (a newer agent may have replaced it).\n try { if (readEndpoint(dir)?.pid === process.pid) rmSync(file, { force: true }); } catch { /* best effort */ }\n }),\n };\n}\n\n/** Call a running agent, over its pipe or socket when it has one. Returns null when no agent answers. */\nexport async function callAgent(dir: string, method: \"GET\" | \"POST\", path: string, body?: unknown, timeoutMs = 5_000): Promise<unknown | null> {\n const endpoint = readEndpoint(dir);\n if (!endpoint) return null;\n if (typeof endpoint.socket === \"string\" && endpoint.socket) {\n const answer = await requestOverSocket(endpoint.socket, method, path, { [TOKEN_HEADER]: endpoint.token }, body, timeoutMs);\n if (answer) return answer.status >= 200 && answer.status < 300 ? answer.body : null;\n if (!endpoint.port) return null;\n }\n try {\n const res = await fetch(`http://127.0.0.1:${endpoint.port}${path}`, {\n method, headers: { [TOKEN_HEADER]: endpoint.token, ...(body !== undefined ? { \"content-type\": \"application/json\" } : {}) },\n body: body !== undefined ? JSON.stringify(body) : undefined, signal: AbortSignal.timeout(timeoutMs),\n });\n return res.ok ? await res.json() : null;\n } catch { return null; }\n}\n"]}
1
+ {"version":3,"file":"ipc.js","sourceRoot":"","sources":["../src/ipc.ts"],"names":[],"mappings":"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","sourcesContent":["// The agent's local control channel: HTTP with a random token, over a named pipe on Windows (a random name) or a Unix\n// socket in a folder only this user can open. npm installs also listen on 127.0.0.1 at a random port, because the\n// PowerShell tray and hooks before the pipe use it (SCOPEBOND_AGENT_LOOPBACK=0 turns it off); the signed install with the\n// native tray does not (its tray and its hook use the pipe). The pipe or socket, the port, the token and the process id\n// are written to agent.json in the Scopebond home, which is how the CLI, the hook's override window and the tray find it.\n// A loopback port can be reached by any program on the computer; the pipe's name and the socket's folder cannot be found\n// or opened by another user. Every request must carry the token either way.\n\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { randomBytes, timingSafeEqual } from \"node:crypto\";\nimport { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { requestOverSocket } from \"@scopebond/hook\";\n\nexport const AGENT_FILE = \"agent.json\";\nexport const TOKEN_HEADER = \"x-scopebond-agent-token\";\n\n/** `socket`: the named pipe or Unix socket (absent from agents before it); `port`: 0 when loopback is off. */\nexport interface AgentEndpoint { port: number; socket?: string | null; token: string; pid: number; started_at: number; version: string }\n\n/** Where this start's pipe or socket goes. Windows: a pipe whose name is random, so no other user can guess it or claim it\n * first. Elsewhere: `run/agent.sock` in the Scopebond home (folder 0700), or a private folder under the temporary folder\n * when that path is longer than a Unix socket path may be. */\nexport function localSocketPath(dir: string, platform: NodeJS.Platform = process.platform, random = randomBytes(16).toString(\"hex\")): string {\n if (platform === \"win32\") return `\\\\\\\\.\\\\pipe\\\\scopebond-agent-${random}`;\n const inHome = join(dir, \"run\", \"agent.sock\");\n if (Buffer.byteLength(inHome) <= 100) return inHome;\n return join(mkdtempSync(join(tmpdir(), \"scopebond-\")), \"agent.sock\");\n}\n\nexport type Handler = (body: unknown) => Promise<unknown> | unknown;\n\nexport function readEndpoint(dir: string): AgentEndpoint | null {\n const file = join(dir, AGENT_FILE);\n if (!existsSync(file)) return null;\n try { return JSON.parse(readFileSync(file, \"utf8\")) as AgentEndpoint; } catch { return null; }\n}\n\n/** Start the control server. `routes` maps \"METHOD /path\" to a handler. `loopback`: also listen on 127.0.0.1 (default:\n * unless SCOPEBOND_AGENT_LOOPBACK=0); it is used anyway when the pipe or socket could not be made, or nothing could reach\n * the agent. */\nexport async function startControl(dir: string, version: string, routes: Record<string, Handler>, options: { loopback?: boolean } = {}): Promise<{ server: Server; endpoint: AgentEndpoint; close(): Promise<void> }> {\n const token = randomBytes(24).toString(\"base64url\");\n const expected = Buffer.from(token);\n const handle = async (req: IncomingMessage, res: ServerResponse) => {\n const send = (status: number, body: unknown) => { res.writeHead(status, { \"content-type\": \"application/json; charset=utf-8\", \"cache-control\": \"no-store\" }); res.end(JSON.stringify(body)); };\n const offered = Buffer.from(String(req.headers[TOKEN_HEADER] ?? \"\"));\n if (offered.length !== expected.length || !timingSafeEqual(offered, expected)) return send(401, { error: \"unauthorized\" });\n const handler = routes[`${req.method} ${(req.url ?? \"/\").split(\"?\")[0]}`];\n if (!handler) return send(404, { error: \"not found\" });\n let raw = \"\";\n for await (const chunk of req) { raw += chunk; if (raw.length > 64 * 1024) return send(413, { error: \"too large\" }); }\n try { send(200, await handler(raw ? JSON.parse(raw) : null)); }\n catch (error) { send(500, { error: (error as Error).message.slice(0, 200) }); }\n };\n // The pipe or socket first. A Unix socket's folder is created for this user only, and the socket itself is too.\n const socketPath = localSocketPath(dir);\n const local = createServer(handle);\n let socket: string | null = socketPath;\n try {\n if (process.platform !== \"win32\") {\n mkdirSync(join(socketPath, \"..\"), { recursive: true, mode: 0o700 });\n chmodSync(join(socketPath, \"..\"), 0o700);\n rmSync(socketPath, { force: true });\n }\n await new Promise<void>((resolve, reject) => { local.once(\"error\", reject); local.listen(socketPath, () => resolve()); });\n if (process.platform !== \"win32\") chmodSync(socketPath, 0o600);\n } catch { socket = null; }\n // Loopback where something still needs it (the PowerShell tray, older hooks), unless turned off; always when the pipe\n // could not be made.\n const loopback = (options.loopback ?? process.env.SCOPEBOND_AGENT_LOOPBACK !== \"0\") || socket === null;\n const server = createServer(handle);\n if (loopback) await new Promise<void>((resolve, reject) => { server.once(\"error\", reject); server.listen(0, \"127.0.0.1\", () => resolve()); });\n const address = loopback ? server.address() : null;\n const port = typeof address === \"object\" && address ? address.port : 0;\n const endpoint: AgentEndpoint = { port, socket, token, pid: process.pid, started_at: Date.now(), version };\n const file = join(dir, AGENT_FILE);\n const temp = `${file}.${process.pid}.tmp`;\n writeFileSync(temp, JSON.stringify(endpoint, null, 2) + \"\\n\", { mode: 0o600 });\n renameSync(temp, file);\n return {\n server, endpoint,\n close: () => new Promise<void>((resolve) => {\n let open = (loopback ? 1 : 0) + (socket ? 1 : 0);\n const done = () => { if (--open <= 0) resolve(); };\n if (open === 0) resolve();\n if (loopback) server.close(done);\n if (socket) local.close(() => { if (process.platform !== \"win32\") rmSync(socketPath, { force: true }); done(); });\n // Only remove the file if it is still ours (a newer agent may have replaced it).\n try { if (readEndpoint(dir)?.pid === process.pid) rmSync(file, { force: true }); } catch { /* best effort */ }\n }),\n };\n}\n\n/** Call a running agent, over its pipe or socket when it has one. Returns null when no agent answers. */\nexport async function callAgent(dir: string, method: \"GET\" | \"POST\", path: string, body?: unknown, timeoutMs = 5_000): Promise<unknown | null> {\n const endpoint = readEndpoint(dir);\n if (!endpoint) return null;\n if (typeof endpoint.socket === \"string\" && endpoint.socket) {\n const answer = await requestOverSocket(endpoint.socket, method, path, { [TOKEN_HEADER]: endpoint.token }, body, timeoutMs);\n if (answer) return answer.status >= 200 && answer.status < 300 ? answer.body : null;\n if (!endpoint.port) return null;\n }\n try {\n const res = await fetch(`http://127.0.0.1:${endpoint.port}${path}`, {\n method, headers: { [TOKEN_HEADER]: endpoint.token, ...(body !== undefined ? { \"content-type\": \"application/json\" } : {}) },\n body: body !== undefined ? JSON.stringify(body) : undefined, signal: AbortSignal.timeout(timeoutMs),\n });\n return res.ok ? await res.json() : null;\n } catch { return null; }\n}\n"]}