@phigon/observer 8.2.0 → 8.3.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 (187) hide show
  1. package/README.md +194 -11
  2. package/dist/bin/guardian-runner-darwin-amd64 +0 -0
  3. package/dist/bin/guardian-runner-darwin-arm64 +0 -0
  4. package/dist/bin/guardian-runner-linux-amd64 +0 -0
  5. package/dist/bin/guardian-runner-linux-arm64 +0 -0
  6. package/dist/bin/guardian-runner-windows-amd64.exe +0 -0
  7. package/dist/bin/guardian-runner-windows-arm64.exe +0 -0
  8. package/dist/src/abortable-delay.d.ts +10 -0
  9. package/dist/src/abortable-delay.d.ts.map +1 -0
  10. package/dist/src/abortable-delay.js +21 -0
  11. package/dist/src/abortable-delay.js.map +1 -0
  12. package/dist/src/activity/adapters/claude.d.ts.map +1 -1
  13. package/dist/src/activity/adapters/claude.js +9 -1
  14. package/dist/src/activity/adapters/claude.js.map +1 -1
  15. package/dist/src/activity/adapters/openai-compatible.d.ts.map +1 -1
  16. package/dist/src/activity/adapters/openai-compatible.js +9 -1
  17. package/dist/src/activity/adapters/openai-compatible.js.map +1 -1
  18. package/dist/src/activity/collector.d.ts +31 -1
  19. package/dist/src/activity/collector.d.ts.map +1 -1
  20. package/dist/src/activity/collector.js +337 -77
  21. package/dist/src/activity/collector.js.map +1 -1
  22. package/dist/src/activity/ingest.d.ts +9 -0
  23. package/dist/src/activity/ingest.d.ts.map +1 -1
  24. package/dist/src/activity/ingest.js +92 -3
  25. package/dist/src/activity/ingest.js.map +1 -1
  26. package/dist/src/activity/json-document-source.d.ts +15 -0
  27. package/dist/src/activity/json-document-source.d.ts.map +1 -1
  28. package/dist/src/activity/json-document-source.js +19 -2
  29. package/dist/src/activity/json-document-source.js.map +1 -1
  30. package/dist/src/activity/native-capabilities.d.ts.map +1 -1
  31. package/dist/src/activity/native-capabilities.js +8 -12
  32. package/dist/src/activity/native-capabilities.js.map +1 -1
  33. package/dist/src/activity/opencode-sqlite-source.js +1 -0
  34. package/dist/src/activity/opencode-sqlite-source.js.map +1 -1
  35. package/dist/src/activity/source-reader.d.ts +44 -3
  36. package/dist/src/activity/source-reader.d.ts.map +1 -1
  37. package/dist/src/activity/source-reader.js +325 -86
  38. package/dist/src/activity/source-reader.js.map +1 -1
  39. package/dist/src/agent-action-executor.d.ts +5 -0
  40. package/dist/src/agent-action-executor.d.ts.map +1 -1
  41. package/dist/src/agent-action-executor.js +9 -6
  42. package/dist/src/agent-action-executor.js.map +1 -1
  43. package/dist/src/atomic-replace.d.ts +7 -0
  44. package/dist/src/atomic-replace.d.ts.map +1 -1
  45. package/dist/src/atomic-replace.js +28 -3
  46. package/dist/src/atomic-replace.js.map +1 -1
  47. package/dist/src/bridge-journal.d.ts +32 -0
  48. package/dist/src/bridge-journal.d.ts.map +1 -0
  49. package/dist/src/bridge-journal.js +113 -0
  50. package/dist/src/bridge-journal.js.map +1 -0
  51. package/dist/src/cli.d.ts +7 -1
  52. package/dist/src/cli.d.ts.map +1 -1
  53. package/dist/src/cli.js +490 -43
  54. package/dist/src/cli.js.map +1 -1
  55. package/dist/src/collection-notice.d.ts +34 -0
  56. package/dist/src/collection-notice.d.ts.map +1 -0
  57. package/dist/src/collection-notice.js +73 -0
  58. package/dist/src/collection-notice.js.map +1 -0
  59. package/dist/src/config.d.ts +26 -0
  60. package/dist/src/config.d.ts.map +1 -1
  61. package/dist/src/config.js +88 -33
  62. package/dist/src/config.js.map +1 -1
  63. package/dist/src/content-redaction.d.ts +17 -1
  64. package/dist/src/content-redaction.d.ts.map +1 -1
  65. package/dist/src/content-redaction.js +44 -3
  66. package/dist/src/content-redaction.js.map +1 -1
  67. package/dist/src/credential-store.d.ts +20 -1
  68. package/dist/src/credential-store.d.ts.map +1 -1
  69. package/dist/src/credential-store.js +27 -3
  70. package/dist/src/credential-store.js.map +1 -1
  71. package/dist/src/discovery/engine.d.ts.map +1 -1
  72. package/dist/src/discovery/engine.js +1 -11
  73. package/dist/src/discovery/engine.js.map +1 -1
  74. package/dist/src/doctor-check.d.ts +51 -0
  75. package/dist/src/doctor-check.d.ts.map +1 -0
  76. package/dist/src/doctor-check.js +174 -0
  77. package/dist/src/doctor-check.js.map +1 -0
  78. package/dist/src/enroll.d.ts +86 -0
  79. package/dist/src/enroll.d.ts.map +1 -0
  80. package/dist/src/enroll.js +245 -0
  81. package/dist/src/enroll.js.map +1 -0
  82. package/dist/src/entry.d.ts +3 -0
  83. package/dist/src/entry.d.ts.map +1 -0
  84. package/dist/src/entry.js +14 -0
  85. package/dist/src/entry.js.map +1 -0
  86. package/dist/src/event-queue.d.ts +13 -1
  87. package/dist/src/event-queue.d.ts.map +1 -1
  88. package/dist/src/event-queue.js +50 -5
  89. package/dist/src/event-queue.js.map +1 -1
  90. package/dist/src/event-spool.d.ts +61 -3
  91. package/dist/src/event-spool.d.ts.map +1 -1
  92. package/dist/src/event-spool.js +290 -41
  93. package/dist/src/event-spool.js.map +1 -1
  94. package/dist/src/generated/phigon/v1/identity_pb.d.ts +7 -0
  95. package/dist/src/generated/phigon/v1/identity_pb.d.ts.map +1 -1
  96. package/dist/src/generated/phigon/v1/identity_pb.js +1 -1
  97. package/dist/src/generated/phigon/v1/identity_pb.js.map +1 -1
  98. package/dist/src/guardian-decision-journal.d.ts.map +1 -1
  99. package/dist/src/guardian-decision-journal.js +4 -20
  100. package/dist/src/guardian-decision-journal.js.map +1 -1
  101. package/dist/src/guardian-managed-exec.js +6 -19
  102. package/dist/src/guardian-managed-exec.js.map +1 -1
  103. package/dist/src/guardian-process-monitor.d.ts +1 -0
  104. package/dist/src/guardian-process-monitor.d.ts.map +1 -1
  105. package/dist/src/guardian-process-monitor.js +74 -26
  106. package/dist/src/guardian-process-monitor.js.map +1 -1
  107. package/dist/src/health.d.ts +19 -1
  108. package/dist/src/health.d.ts.map +1 -1
  109. package/dist/src/health.js +22 -1
  110. package/dist/src/health.js.map +1 -1
  111. package/dist/src/historical-identity-store.d.ts +8 -1
  112. package/dist/src/historical-identity-store.d.ts.map +1 -1
  113. package/dist/src/historical-identity-store.js +26 -9
  114. package/dist/src/historical-identity-store.js.map +1 -1
  115. package/dist/src/index.d.ts +2 -0
  116. package/dist/src/index.d.ts.map +1 -1
  117. package/dist/src/index.js +2 -0
  118. package/dist/src/index.js.map +1 -1
  119. package/dist/src/installation.d.ts +2 -0
  120. package/dist/src/installation.d.ts.map +1 -1
  121. package/dist/src/installation.js +3 -1
  122. package/dist/src/installation.js.map +1 -1
  123. package/dist/src/instance-lock.d.ts +45 -0
  124. package/dist/src/instance-lock.d.ts.map +1 -0
  125. package/dist/src/instance-lock.js +243 -0
  126. package/dist/src/instance-lock.js.map +1 -0
  127. package/dist/src/machine-command-executor.d.ts +2 -2
  128. package/dist/src/machine-command-executor.d.ts.map +1 -1
  129. package/dist/src/machine-command-executor.js +7 -20
  130. package/dist/src/machine-command-executor.js.map +1 -1
  131. package/dist/src/node-version.d.ts +8 -0
  132. package/dist/src/node-version.d.ts.map +1 -0
  133. package/dist/src/node-version.js +17 -0
  134. package/dist/src/node-version.js.map +1 -0
  135. package/dist/src/observer-log.d.ts +50 -0
  136. package/dist/src/observer-log.d.ts.map +1 -0
  137. package/dist/src/observer-log.js +141 -0
  138. package/dist/src/observer-log.js.map +1 -0
  139. package/dist/src/pair.d.ts +68 -1
  140. package/dist/src/pair.d.ts.map +1 -1
  141. package/dist/src/pair.js +204 -66
  142. package/dist/src/pair.js.map +1 -1
  143. package/dist/src/private-directory.d.ts +6 -0
  144. package/dist/src/private-directory.d.ts.map +1 -1
  145. package/dist/src/private-directory.js +33 -2
  146. package/dist/src/private-directory.js.map +1 -1
  147. package/dist/src/proxy.d.ts +68 -0
  148. package/dist/src/proxy.d.ts.map +1 -0
  149. package/dist/src/proxy.js +209 -0
  150. package/dist/src/proxy.js.map +1 -0
  151. package/dist/src/purge.d.ts +17 -0
  152. package/dist/src/purge.d.ts.map +1 -0
  153. package/dist/src/purge.js +84 -0
  154. package/dist/src/purge.js.map +1 -0
  155. package/dist/src/remove-machine.d.ts +5 -1
  156. package/dist/src/remove-machine.d.ts.map +1 -1
  157. package/dist/src/remove-machine.js +28 -14
  158. package/dist/src/remove-machine.js.map +1 -1
  159. package/dist/src/server-authority.d.ts +5 -2
  160. package/dist/src/server-authority.d.ts.map +1 -1
  161. package/dist/src/server-authority.js +10 -6
  162. package/dist/src/server-authority.js.map +1 -1
  163. package/dist/src/server-clock.d.ts +32 -0
  164. package/dist/src/server-clock.d.ts.map +1 -0
  165. package/dist/src/server-clock.js +72 -0
  166. package/dist/src/server-clock.js.map +1 -0
  167. package/dist/src/service-command.d.ts +20 -0
  168. package/dist/src/service-command.d.ts.map +1 -0
  169. package/dist/src/service-command.js +136 -0
  170. package/dist/src/service-command.js.map +1 -0
  171. package/dist/src/service.d.ts +98 -0
  172. package/dist/src/service.d.ts.map +1 -0
  173. package/dist/src/service.js +472 -0
  174. package/dist/src/service.js.map +1 -0
  175. package/dist/src/stream-client.d.ts +18 -0
  176. package/dist/src/stream-client.d.ts.map +1 -1
  177. package/dist/src/stream-client.js +91 -16
  178. package/dist/src/stream-client.js.map +1 -1
  179. package/dist/src/stream-state.d.ts +2 -0
  180. package/dist/src/stream-state.d.ts.map +1 -1
  181. package/dist/src/stream-state.js +3 -1
  182. package/dist/src/stream-state.js.map +1 -1
  183. package/dist/src/user-notices.d.ts +11 -0
  184. package/dist/src/user-notices.d.ts.map +1 -1
  185. package/dist/src/user-notices.js +24 -0
  186. package/dist/src/user-notices.js.map +1 -1
  187. package/package.json +7 -7
package/dist/src/pair.js CHANGED
@@ -1,25 +1,141 @@
1
1
  import { arch, hostname, platform } from "node:os";
2
- import { FileCredentialStore, } from "./credential-store.js";
3
- import { loadOrCreateInstallationID } from "./installation.js";
2
+ import { FileCredentialStore, credentialFileName, } from "./credential-store.js";
3
+ import { retirePairingState } from "./event-spool.js";
4
+ import { installationFileName, loadOrCreateInstallationID } from "./installation.js";
5
+ import { InstanceLock } from "./instance-lock.js";
4
6
  export const OBSERVER_CONSENT_POLICY_VERSION = "observer-policy-v1";
5
7
  export async function pairMachine(options) {
6
8
  const code = options.code.trim();
7
9
  if (code.length === 0) {
8
10
  throw new Error("Pairing code is required.");
9
11
  }
10
- const installationID = await loadOrCreateInstallationID(options.config.dataDirectory);
11
12
  if (options.config.observabilityProfile === "full" &&
12
13
  options.consentProfile !== "full") {
13
14
  throw new Error("The configured full observability profile requires full-content consent.");
14
15
  }
15
16
  const endpoint = new URL("/v1/pairing/exchange", options.config.controlPlaneUrl);
16
17
  const fetcher = options.fetcher ?? fetch;
18
+ const connected = await connectMachine({
19
+ config: options.config,
20
+ endpoint,
21
+ fetcher,
22
+ ...(options.credentialStore === undefined ? {} : { credentialStore: options.credentialStore }),
23
+ exchange: (installationID, existingCredential) => exchangePairing(fetcher, endpoint, {
24
+ code,
25
+ installation_id: installationID,
26
+ display_name: options.displayName?.trim() || hostname(),
27
+ hostname: hostname(),
28
+ operating_system: normalizedOperatingSystem(),
29
+ architecture: arch(),
30
+ consent: {
31
+ granted: true,
32
+ profile: options.consentProfile,
33
+ policy_version: OBSERVER_CONSENT_POLICY_VERSION,
34
+ },
35
+ ...(existingCredential === undefined ? {} : { existing_credential: existingCredential }),
36
+ }),
37
+ evidence: (_paired, at) => ({
38
+ consentProfile: options.consentProfile,
39
+ consentPolicyVersion: OBSERVER_CONSENT_POLICY_VERSION,
40
+ consentedAt: at,
41
+ consentSource: "owner",
42
+ }),
43
+ });
44
+ return connected.result;
45
+ }
46
+ /**
47
+ * Connects this computer with a code, keeping its machine when the server
48
+ * still accepts its stored key: pairing again, or enrolling, renews consent
49
+ * and keeps the same machine, so its queued activity stays deliverable.
50
+ * When the server no longer accepts the key, the computer connects as a
51
+ * new machine and its old queue moves aside.
52
+ */
53
+ export async function connectMachine(options) {
54
+ const dataDirectory = options.config.dataDirectory;
55
+ const installationID = await loadOrCreateInstallationID(dataDirectory);
17
56
  const credentialStore = options.credentialStore ??
18
- new FileCredentialStore(options.config.dataDirectory);
57
+ new FileCredentialStore(dataDirectory);
19
58
  const previous = await credentialStore.load();
20
- if (previous !== null && previous.controlPlaneOrigin !== endpoint.origin) {
59
+ if (previous !== null && previous.controlPlaneOrigin !== options.endpoint.origin) {
21
60
  throw new Error("The stored machine belongs to a different control plane. Use a separate data directory to pair another workspace.");
22
61
  }
62
+ let paired;
63
+ if (previous !== null) {
64
+ const renewal = await options.exchange(installationID, previous.credential);
65
+ if ("paired" in renewal) {
66
+ paired = renewal.paired;
67
+ }
68
+ else if (!renewal.credentialRejected) {
69
+ throw renewal.error;
70
+ }
71
+ else if (await credentialStillAccepted(options.fetcher, options.config.controlPlaneUrl, previous.credential)) {
72
+ // The exchange also refuses a key that is valid in another workspace.
73
+ throw new Error("This computer is paired with another workspace on this server. Use a separate data directory to pair another workspace.");
74
+ }
75
+ }
76
+ let lock;
77
+ try {
78
+ if (paired === undefined || !sameMachine(previous, paired)) {
79
+ // A new machine. Its queue, stream cursor and credential start empty;
80
+ // the observer must not be using the old ones while they move.
81
+ lock = await InstanceLock.acquire(dataDirectory);
82
+ // The old credential goes with its queue: it is the only key that can
83
+ // decrypt it. Once it is gone, a retry after a lost response pairs
84
+ // without it, and the server answers with the same new machine.
85
+ //
86
+ // A key the server no longer accepts also retires its installation ID:
87
+ // a server can still hold that ID for the deleted machine, and the
88
+ // built-in SQLite server refuses to pair it again. A new ID pairs
89
+ // cleanly everywhere.
90
+ const replacing = paired === undefined && previous !== null;
91
+ retirePairingState(dataDirectory, previous?.machineId, [
92
+ credentialFileName,
93
+ ...(replacing ? [installationFileName] : []),
94
+ ]);
95
+ if (paired === undefined) {
96
+ const freshInstallationID = replacing
97
+ ? await loadOrCreateInstallationID(dataDirectory)
98
+ : installationID;
99
+ const fresh = await options.exchange(freshInstallationID);
100
+ if (!("paired" in fresh))
101
+ throw fresh.error;
102
+ paired = fresh.paired;
103
+ }
104
+ }
105
+ const pairedAt = new Date().toISOString();
106
+ await credentialStore.save({
107
+ machineId: paired.machine.id,
108
+ tenantId: paired.machine.tenant_id,
109
+ credential: paired.credential,
110
+ controlPlaneOrigin: options.config.controlPlaneUrl.origin,
111
+ grpcOrigin: options.config.grpcUrl.origin,
112
+ createdAt: pairedAt,
113
+ ...options.evidence(paired, pairedAt),
114
+ });
115
+ }
116
+ finally {
117
+ await lock?.release();
118
+ }
119
+ const replaced = previous !== null && previous.machineId !== paired.machine.id;
120
+ return Object.freeze({
121
+ paired,
122
+ result: Object.freeze({
123
+ machineId: paired.machine.id,
124
+ displayName: paired.machine.display_name,
125
+ state: paired.machine.state,
126
+ controlPlaneOrigin: options.config.controlPlaneUrl.origin,
127
+ credentialStored: true,
128
+ ...(replaced ? { replacedMachineId: previous.machineId } : {}),
129
+ }),
130
+ });
131
+ }
132
+ function sameMachine(previous, paired) {
133
+ return previous !== null &&
134
+ previous.machineId === paired.machine.id &&
135
+ previous.tenantId === paired.machine.tenant_id &&
136
+ previous.credential === paired.credential;
137
+ }
138
+ async function exchangePairing(fetcher, endpoint, body) {
23
139
  let response;
24
140
  try {
25
141
  response = await fetcher(endpoint, {
@@ -28,20 +144,7 @@ export async function pairMachine(options) {
28
144
  "Content-Type": "application/json",
29
145
  Accept: "application/json",
30
146
  },
31
- body: JSON.stringify({
32
- code,
33
- ...(previous === null ? {} : { existing_credential: previous.credential }),
34
- installation_id: installationID,
35
- display_name: options.displayName?.trim() || hostname(),
36
- hostname: hostname(),
37
- operating_system: normalizedOperatingSystem(),
38
- architecture: arch(),
39
- consent: {
40
- granted: true,
41
- profile: options.consentProfile,
42
- policy_version: OBSERVER_CONSENT_POLICY_VERSION,
43
- },
44
- }),
147
+ body: JSON.stringify(body),
45
148
  redirect: "error",
46
149
  signal: AbortSignal.timeout(10_000),
47
150
  });
@@ -53,7 +156,11 @@ export async function pairMachine(options) {
53
156
  throw new Error(`Could not reach ${endpoint.origin}. Check your internet connection and try again.`);
54
157
  }
55
158
  if (!response.ok) {
56
- throw new Error(await pairingFailureMessage(response));
159
+ const failure = await apiError(response);
160
+ return {
161
+ error: new Error(failure.message ?? `Pairing failed with HTTP ${response.status}.`),
162
+ credentialRejected: credentialRejected(response.status, failure),
163
+ };
57
164
  }
58
165
  let value;
59
166
  try {
@@ -64,67 +171,98 @@ export async function pairMachine(options) {
64
171
  // print fragments. The server supports retries for this installation.
65
172
  throw new Error("The pairing response was incomplete or invalid. Retry with the same code before it expires; keep the existing data directory.");
66
173
  }
67
- const paired = parsePairingResponse(value);
68
- const pairedAt = new Date().toISOString();
69
- await credentialStore.save({
70
- machineId: paired.machine.id,
71
- tenantId: paired.machine.tenant_id,
72
- credential: paired.credential,
73
- controlPlaneOrigin: options.config.controlPlaneUrl.origin,
74
- grpcOrigin: options.config.grpcUrl.origin,
75
- createdAt: pairedAt,
76
- consentProfile: options.consentProfile,
77
- consentPolicyVersion: OBSERVER_CONSENT_POLICY_VERSION,
78
- consentedAt: pairedAt,
79
- });
80
- return Object.freeze({
81
- machineId: paired.machine.id,
82
- displayName: paired.machine.display_name,
83
- state: paired.machine.state,
84
- controlPlaneOrigin: options.config.controlPlaneUrl.origin,
85
- credentialStored: true,
86
- });
87
- }
88
- function parsePairingResponse(value) {
89
- if (typeof value !== "object" ||
90
- value === null ||
91
- !("credential" in value) ||
92
- typeof value.credential !== "string" ||
93
- !value.credential.startsWith("phg_m_") ||
94
- !("machine" in value) ||
95
- typeof value.machine !== "object" ||
96
- value.machine === null ||
97
- !("id" in value.machine) ||
98
- typeof value.machine.id !== "string" ||
99
- !("tenant_id" in value.machine) ||
100
- typeof value.machine.tenant_id !== "string" ||
101
- !("display_name" in value.machine) ||
102
- typeof value.machine.display_name !== "string" ||
103
- !("state" in value.machine) ||
104
- typeof value.machine.state !== "string") {
174
+ if (!isConnectedMachine(value)) {
105
175
  throw new Error("Control plane returned an invalid pairing response.");
106
176
  }
107
- return value;
177
+ return { paired: value };
178
+ }
179
+ /**
180
+ * Whether a failed exchange refused the stored key. The server answers a
181
+ * key it no longer accepts with HTTP 400 and "machine credential is
182
+ * invalid".
183
+ */
184
+ export function credentialRejected(status, failure) {
185
+ return failure.code === "invalid_credential" ||
186
+ (status === 400 &&
187
+ /^machine credential is (?:invalid|revoked)\b/iu.test(failure.message ?? ""));
188
+ }
189
+ /**
190
+ * Whether a server still accepts a stored key. Only a key the server
191
+ * itself calls invalid or revoked, because an administrator removed the
192
+ * computer or revoked the key, may be set aside for a new pairing.
193
+ */
194
+ async function credentialStillAccepted(fetcher, controlPlaneUrl, credential) {
195
+ const endpoint = new URL("/v1/machine/heartbeat", controlPlaneUrl);
196
+ let response;
197
+ try {
198
+ response = await fetcher(endpoint, {
199
+ method: "POST",
200
+ headers: {
201
+ Authorization: `Bearer ${credential}`,
202
+ Accept: "application/json",
203
+ },
204
+ redirect: "error",
205
+ signal: AbortSignal.timeout(10_000),
206
+ });
207
+ }
208
+ catch {
209
+ throw new Error(`Could not reach ${endpoint.origin} to check this computer's earlier pairing. Check your internet connection and try again.`);
210
+ }
211
+ if (response.ok) {
212
+ await response.body?.cancel();
213
+ return true;
214
+ }
215
+ if (response.status === 401 &&
216
+ (await apiError(response)).code === "invalid_credential") {
217
+ return false;
218
+ }
219
+ throw new Error(`Could not check this computer's earlier pairing (HTTP ${response.status}). Try again.`);
220
+ }
221
+ /** A response with a machine and a machine credential. */
222
+ export function isConnectedMachine(value) {
223
+ return typeof value === "object" &&
224
+ value !== null &&
225
+ "credential" in value &&
226
+ typeof value.credential === "string" &&
227
+ value.credential.startsWith("phg_m_") &&
228
+ "machine" in value &&
229
+ typeof value.machine === "object" &&
230
+ value.machine !== null &&
231
+ "id" in value.machine &&
232
+ typeof value.machine.id === "string" &&
233
+ "tenant_id" in value.machine &&
234
+ typeof value.machine.tenant_id === "string" &&
235
+ "display_name" in value.machine &&
236
+ typeof value.machine.display_name === "string" &&
237
+ "state" in value.machine &&
238
+ typeof value.machine.state === "string";
108
239
  }
109
- async function pairingFailureMessage(response) {
240
+ /** The `{ error: { code, message } }` body of a failed control-plane call. */
241
+ export async function apiError(response) {
110
242
  try {
111
243
  const value = await response.json();
112
244
  if (typeof value === "object" &&
113
245
  value !== null &&
114
246
  "error" in value &&
115
247
  typeof value.error === "object" &&
116
- value.error !== null &&
117
- "message" in value.error &&
118
- typeof value.error.message === "string") {
119
- return value.error.message;
248
+ value.error !== null) {
249
+ const error = value.error;
250
+ return {
251
+ ...("code" in error && typeof error.code === "string"
252
+ ? { code: error.code }
253
+ : {}),
254
+ ...("message" in error && typeof error.message === "string"
255
+ ? { message: error.message }
256
+ : {}),
257
+ };
120
258
  }
121
259
  }
122
260
  catch {
123
261
  // The status code still provides an actionable, non-sensitive failure.
124
262
  }
125
- return `Pairing failed with HTTP ${response.status}.`;
263
+ return {};
126
264
  }
127
- function normalizedOperatingSystem() {
265
+ export function normalizedOperatingSystem() {
128
266
  const value = platform();
129
267
  if (value === "darwin")
130
268
  return "macos";
@@ -1 +1 @@
1
- {"version":3,"file":"pair.js","sourceRoot":"","sources":["../../src/pair.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pair.js","sourceRoot":"","sources":["../../src/pair.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,9 @@
1
+ /**
2
+ * The current account's SID from whoami. A name built from USERDOMAIN and
3
+ * USERNAME does not resolve for every account: services that run as
4
+ * LocalSystem or a virtual account see names icacls cannot look up.
5
+ */
6
+ export declare function currentUserSID(): string | undefined;
1
7
  /** Restrict an existing directory to its owner on every platform. */
2
8
  export declare function makeDirectoryPrivate(path: string): Promise<void>;
3
9
  export declare function makeDirectoryPrivateSync(path: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"private-directory.d.ts","sourceRoot":"","sources":["../../src/private-directory.ts"],"names":[],"mappings":"AA4BA,qEAAqE;AACrE,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG3D"}
1
+ {"version":3,"file":"private-directory.d.ts","sourceRoot":"","sources":["../../src/private-directory.ts"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAkBnD;AAuBD,qEAAqE;AACrE,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG3D"}
@@ -1,16 +1,47 @@
1
1
  import { execFileSync } from "node:child_process";
2
2
  import { chmodSync } from "node:fs";
3
3
  import { chmod } from "node:fs/promises";
4
- import { resolve } from "node:path";
4
+ import { join, resolve } from "node:path";
5
5
  // chmod only changes the read-only flag on Windows, so the credential store and
6
6
  // event spool would otherwise rely on the profile folder's default ACL. Owner
7
7
  // and SYSTEM keep access; files created inside inherit the restriction.
8
8
  const restricted = new Set();
9
+ // The account this process runs as, by security identifier: null when
10
+ // Windows would not say.
11
+ let processUserSID;
12
+ /**
13
+ * The current account's SID from whoami. A name built from USERDOMAIN and
14
+ * USERNAME does not resolve for every account: services that run as
15
+ * LocalSystem or a virtual account see names icacls cannot look up.
16
+ */
17
+ export function currentUserSID() {
18
+ if (processUserSID === undefined) {
19
+ processUserSID = null;
20
+ try {
21
+ // By full path: Git for Windows puts another whoami on PATH.
22
+ const whoami = join(process.env["SystemRoot"] ?? "C:\\Windows", "System32", "whoami.exe");
23
+ const output = execFileSync(whoami, ["/user", "/fo", "csv", "/nh"], {
24
+ encoding: "utf8",
25
+ windowsHide: true,
26
+ stdio: ["ignore", "pipe", "ignore"],
27
+ timeout: 15_000,
28
+ });
29
+ processUserSID = /"(S-1-[0-9]+(?:-[0-9]+){1,15})"\s*$/u.exec(output.trim())?.[1] ?? null;
30
+ }
31
+ catch {
32
+ // Fall back to the account name below.
33
+ }
34
+ }
35
+ return processUserSID ?? undefined;
36
+ }
9
37
  function restrictWindowsDirectory(path) {
10
38
  const key = resolve(path).toLowerCase();
11
39
  if (restricted.has(key))
12
40
  return;
13
- const owner = `${process.env["USERDOMAIN"] ?? ""}\\${process.env["USERNAME"] ?? ""}`;
41
+ const sid = currentUserSID();
42
+ const owner = sid === undefined
43
+ ? `${process.env["USERDOMAIN"] ?? ""}\\${process.env["USERNAME"] ?? ""}`
44
+ : `*${sid}`;
14
45
  try {
15
46
  execFileSync("icacls", [resolve(path), "/inheritance:r", "/grant:r", `${owner}:(OI)(CI)F`, "/grant:r", "*S-1-5-18:(OI)(CI)F"], { windowsHide: true, stdio: "ignore", timeout: 15_000 });
16
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"private-directory.js","sourceRoot":"","sources":["../../src/private-directory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,gFAAgF;AAChF,8EAA8E;AAC9E,wEAAwE;AACxE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;AAErC,SAAS,wBAAwB,CAAC,IAAY;IAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO;IAChC,MAAM,KAAK,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;IACrF,IAAI,CAAC;QACH,YAAY,CACV,QAAQ,EACR,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,GAAG,KAAK,YAAY,EAAE,UAAU,EAAE,qBAAqB,CAAC,EACtG,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CACxD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;QACtE,qEAAqE;QACrE,MAAM,IAAI,KAAK,CAAC,0HAA0H,CAAC,CAAC;IAC9I,CAAC;IACD,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAY;IACrD,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,wBAAwB,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACvB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,wBAAwB,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"private-directory.js","sourceRoot":"","sources":["../../src/private-directory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { Socket } from "node:net";
2
+ /**
3
+ * Corporate proxies. The observer's HTTPS calls (pairing, removal, update
4
+ * checks, Guardian and the doctor probe) use `fetch`, which ignores
5
+ * HTTPS_PROXY unless Node.js is told to read it, and the telemetry stream
6
+ * uses @grpc/grpc-js, which reads only the lowercase names. This module
7
+ * points both at the same proxy, using what Node.js offers natively.
8
+ *
9
+ * HTTPS goes through the proxy as a CONNECT tunnel, and TLS is negotiated
10
+ * with the server itself inside it, so the usual certificate checks,
11
+ * including an authority pinned for a company's own server, still apply.
12
+ */
13
+ export type ProxySettings = Readonly<{
14
+ https?: URL;
15
+ http?: URL;
16
+ /** NO_PROXY as written: comma- or space-separated host names. */
17
+ noProxy: string;
18
+ }>;
19
+ /** Reads HTTPS_PROXY, HTTP_PROXY and NO_PROXY (either case) from `environment`. */
20
+ export declare function proxySettings(environment: NodeJS.ProcessEnv): ProxySettings;
21
+ /**
22
+ * The proxy `target` goes through, or undefined to connect directly. It
23
+ * follows Node.js: an entry matches its host and every host under it
24
+ * (`example.com`, `.example.com` and `*.example.com` all cover
25
+ * `a.example.com`), `*` matches everything, and `host:port` only that port.
26
+ */
27
+ export declare function proxyForUrl(target: URL, settings: ProxySettings): URL | undefined;
28
+ /**
29
+ * NO_PROXY in the form @grpc/grpc-js reads, which matches plain host name
30
+ * endings only: `*.example.com` and `.example.com` become `example.com`, and
31
+ * an entry for another port is left out because the stream cannot check
32
+ * ports.
33
+ */
34
+ export declare function grpcNoProxy(noProxy: string, streamPort: number): string;
35
+ /** Whether NO_PROXY turns the proxy off for every host, which grpc-js cannot express. */
36
+ export declare function noProxyForAll(environment: NodeJS.ProcessEnv): boolean;
37
+ type SetGlobalProxy = (environment: NodeJS.ProcessEnv) => () => void;
38
+ export type ProxySetup = Readonly<{
39
+ /** Puts back the global agents and the variables changed for the stream. */
40
+ restore: () => void;
41
+ /** A plain sentence to show when part of the setup could not be applied. */
42
+ notice?: string;
43
+ }>;
44
+ export type ProxySetupOptions = Readonly<{
45
+ /** `http.setGlobalProxyFromEnv`, Node.js 24.14 and newer. */
46
+ setGlobalProxyFromEnv?: SetGlobalProxy | undefined;
47
+ /** The environment @grpc/grpc-js reads: process.env. */
48
+ processEnvironment?: NodeJS.ProcessEnv;
49
+ /** Whether Node.js already applied the proxy variables when it started. */
50
+ startedWithEnvProxy?: boolean;
51
+ nodeVersion?: string;
52
+ /** The telemetry endpoint, to keep NO_PROXY port entries for it. */
53
+ streamUrl?: URL;
54
+ }>;
55
+ /**
56
+ * Sends `fetch` (and `http`/`https` requests) through the proxy that
57
+ * `environment` names, and gives the telemetry stream the same proxy and
58
+ * NO_PROXY list. Does nothing when no proxy is set.
59
+ */
60
+ export declare function useProxyFromEnvironment(environment: NodeJS.ProcessEnv, options?: ProxySetupOptions): ProxySetup;
61
+ /**
62
+ * Opens a CONNECT tunnel through `proxy` to `host:port`, for a raw TLS
63
+ * connection that `fetch` does not cover. Messages name the proxy by host
64
+ * only, never with its credentials.
65
+ */
66
+ export declare function connectThroughProxy(proxy: URL, host: string, port: number, timeoutMs?: number): Promise<Socket>;
67
+ export {};
68
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAuCH,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,GAAG,aAAa,CAQ3E;AAaD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,GAAG,GAAG,GAAG,SAAS,CAYjF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAKvE;AAED,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAGrE;AAED,KAAK,cAAc,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,KAAK,MAAM,IAAI,CAAC;AAErE,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,4EAA4E;IAC5E,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,6DAA6D;IAC7D,qBAAqB,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACnD,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACvC,2EAA2E;IAC3E,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,SAAS,CAAC,EAAE,GAAG,CAAC;CACjB,CAAC,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,CAAC,UAAU,EAC9B,OAAO,GAAE,iBAAsB,GAC9B,UAAU,CA0DZ;AAOD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,GAAG,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,SAAS,SAAS,GACjB,OAAO,CAAC,MAAM,CAAC,CAoCjB"}