@hellolynk-ai/workbuddy-mcp 0.0.0-stage → 0.3.96

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 (176) hide show
  1. package/LICENSE +92 -0
  2. package/README.md +88 -2
  3. package/bin/hellolynk-client-setup.mjs +2748 -0
  4. package/bin/hellolynk-mcp-config-shape.mjs +23 -0
  5. package/clients/core/hellolynk-client-account.mjs +180 -0
  6. package/clients/core/hellolynk-client-core.mjs +770 -0
  7. package/clients/core/hellolynk-client-profile.mjs +191 -0
  8. package/clients/core/hellolynk-client-update-entry.mjs +31 -0
  9. package/clients/core/hellolynk-client-update-runtime.mjs +600 -0
  10. package/clients/core/hellolynk-client-update.mjs +453 -0
  11. package/clients/core/hellolynk-contact-request-e2ee.mjs +867 -0
  12. package/clients/core/hellolynk-device-enrollment.mjs +435 -0
  13. package/clients/core/hellolynk-direct-text-e2ee-client.mjs +1964 -0
  14. package/clients/core/hellolynk-direct-text-e2ee.mjs +1207 -0
  15. package/clients/core/hellolynk-host-auth.mjs +347 -0
  16. package/clients/core/hellolynk-host-protected-store.mjs +2721 -0
  17. package/clients/core/hellolynk-host-transport-client.mjs +946 -0
  18. package/clients/core/hellolynk-host.mjs +2374 -0
  19. package/clients/core/hellolynk-human-confirmation-ledger.mjs +256 -0
  20. package/clients/core/hellolynk-human-relationship-controller.mjs +1234 -0
  21. package/clients/core/hellolynk-inbox-read-state.mjs +11 -0
  22. package/clients/core/hellolynk-indexed-message-store.mjs +1558 -0
  23. package/clients/core/hellolynk-instance-conversation.mjs +185 -0
  24. package/clients/core/hellolynk-local-contact-requests.mjs +1733 -0
  25. package/clients/core/hellolynk-local-contacts.mjs +1228 -0
  26. package/clients/core/hellolynk-local-data-migration.mjs +766 -0
  27. package/clients/core/hellolynk-local-data-protection.mjs +747 -0
  28. package/clients/core/hellolynk-local-identity-trust.mjs +274 -0
  29. package/clients/core/hellolynk-local-messaging.mjs +3043 -0
  30. package/clients/core/hellolynk-local-peer-transport.mjs +103 -0
  31. package/clients/core/hellolynk-local-process-lock.mjs +157 -0
  32. package/clients/core/hellolynk-model-inbox.mjs +230 -0
  33. package/clients/core/hellolynk-model-notices.cjs +60 -0
  34. package/clients/core/hellolynk-native-addressing-tools.cjs +231 -0
  35. package/clients/core/hellolynk-native-conversations.mjs +280 -0
  36. package/clients/core/hellolynk-native-human-confirmation-broker.mjs +1036 -0
  37. package/clients/core/hellolynk-native-inbox-runtime.mjs +553 -0
  38. package/clients/core/hellolynk-native-notice.mjs +50 -0
  39. package/clients/core/hellolynk-native-reply-routes.mjs +96 -0
  40. package/clients/core/hellolynk-native-task-index.cjs +305 -0
  41. package/clients/core/hellolynk-native-worker-lease.mjs +84 -0
  42. package/clients/core/hellolynk-neutral-host-assembly.mjs +955 -0
  43. package/clients/core/hellolynk-neutral-host-installation-store.mjs +765 -0
  44. package/clients/core/hellolynk-neutral-host-launcher.mjs +665 -0
  45. package/clients/core/hellolynk-neutral-host-process.mjs +4374 -0
  46. package/clients/core/hellolynk-neutral-host-store-adapters.mjs +548 -0
  47. package/clients/core/hellolynk-neutral-host-workbench-read-model.mjs +1365 -0
  48. package/clients/core/hellolynk-platform-credential-store.mjs +773 -0
  49. package/clients/core/hellolynk-relay-client-cli.mjs +232 -0
  50. package/clients/core/hellolynk-release-retention.mjs +160 -0
  51. package/clients/core/hellolynk-runtime-safety.cjs +471 -0
  52. package/clients/core/hellolynk-workbench-action-grants.mjs +457 -0
  53. package/clients/core/hellolynk-workbench-connection.mjs +234 -0
  54. package/clients/platform/windows/credential-store.ps1 +844 -0
  55. package/clients/platform/windows/hellolynk-host-protected-store.ps1 +2866 -0
  56. package/clients/platform/windows/hellolynk-human-confirmation-ledger.ps1 +155 -0
  57. package/clients/platform/windows/hellolynk-local-data-key.ps1 +300 -0
  58. package/clients/platform/windows/hellolynk-native-human-confirmation-broker.ps1 +216 -0
  59. package/clients/workbench/contract.mjs +1314 -0
  60. package/clients/workbench/service.mjs +485 -0
  61. package/hellolynk-client-pack-manifest.json +884 -0
  62. package/hellolynk-client-pack-pin.json +4 -0
  63. package/integrations/workbuddy/package.json +15 -0
  64. package/integrations/workbuddy/server/host-lifecycle.mjs +249 -0
  65. package/integrations/workbuddy/server/mcp-proxy.mjs +258 -0
  66. package/integrations/workbuddy/server/mcp-server.mjs +357 -0
  67. package/integrations/workbuddy/server/model-call-origin.mjs +87 -0
  68. package/integrations/workbuddy/server/native-task-cdp.mjs +175 -0
  69. package/integrations/workbuddy/server/native-task-debug-startup.mjs +117 -0
  70. package/integrations/workbuddy/server/native-task-debug-startup.ps1 +40 -0
  71. package/integrations/workbuddy/server/native-task-mcp-registration.mjs +30 -0
  72. package/integrations/workbuddy/server/native-task-service-registration.mjs +115 -0
  73. package/integrations/workbuddy/server/native-task-worker.mjs +127 -0
  74. package/integrations/workbuddy/server/neutral-host-adapter.mjs +639 -0
  75. package/integrations/workbuddy/server/origin-hook.mjs +111 -0
  76. package/integrations/workbuddy/server/origin-routes.mjs +211 -0
  77. package/integrations/workbuddy/server/package-bootstrap.mjs +111 -0
  78. package/integrations/workbuddy/server/workbench-candidate.mjs +202 -0
  79. package/integrations/workbuddy/server/workbench-hidden-launcher.vbs +46 -0
  80. package/integrations/workbuddy/server/workbench-process.mjs +373 -0
  81. package/integrations/workbuddy/server/workbench-task.ps1 +196 -0
  82. package/integrations/workbuddy/skills/hellolynk-inbox/SKILL.md +9 -0
  83. package/integrations/workbuddy/skills/hellolynk-inbox/workbuddy.json +6 -0
  84. package/package.json +65 -4
  85. package/runtime/connect-activate.mjs +837 -0
  86. package/runtime/core/hellolynk-agent-configurator.mjs +701 -0
  87. package/runtime/core/hellolynk-client-account.mjs +180 -0
  88. package/runtime/core/hellolynk-client-core.mjs +770 -0
  89. package/runtime/core/hellolynk-client-profile.mjs +191 -0
  90. package/runtime/core/hellolynk-client-update-entry.mjs +31 -0
  91. package/runtime/core/hellolynk-client-update-runtime.mjs +600 -0
  92. package/runtime/core/hellolynk-client-update.mjs +453 -0
  93. package/runtime/core/hellolynk-contact-request-e2ee.mjs +867 -0
  94. package/runtime/core/hellolynk-device-enrollment.mjs +435 -0
  95. package/runtime/core/hellolynk-direct-text-e2ee-client.mjs +1964 -0
  96. package/runtime/core/hellolynk-direct-text-e2ee.mjs +1207 -0
  97. package/runtime/core/hellolynk-host-auth.mjs +347 -0
  98. package/runtime/core/hellolynk-host-protected-store.mjs +2721 -0
  99. package/runtime/core/hellolynk-host-transport-client.mjs +946 -0
  100. package/runtime/core/hellolynk-host.mjs +2374 -0
  101. package/runtime/core/hellolynk-human-confirmation-ledger.mjs +256 -0
  102. package/runtime/core/hellolynk-human-relationship-controller.mjs +1234 -0
  103. package/runtime/core/hellolynk-inbox-read-state.mjs +11 -0
  104. package/runtime/core/hellolynk-indexed-message-store.mjs +1558 -0
  105. package/runtime/core/hellolynk-instance-conversation.mjs +185 -0
  106. package/runtime/core/hellolynk-local-contact-requests.mjs +1733 -0
  107. package/runtime/core/hellolynk-local-contacts.mjs +1228 -0
  108. package/runtime/core/hellolynk-local-data-migration.mjs +766 -0
  109. package/runtime/core/hellolynk-local-data-protection.mjs +747 -0
  110. package/runtime/core/hellolynk-local-identity-trust.mjs +274 -0
  111. package/runtime/core/hellolynk-local-messaging.mjs +3043 -0
  112. package/runtime/core/hellolynk-local-peer-transport.mjs +103 -0
  113. package/runtime/core/hellolynk-local-process-lock.mjs +157 -0
  114. package/runtime/core/hellolynk-model-inbox.mjs +230 -0
  115. package/runtime/core/hellolynk-model-notices.cjs +60 -0
  116. package/runtime/core/hellolynk-native-addressing-tools.cjs +231 -0
  117. package/runtime/core/hellolynk-native-conversations.mjs +280 -0
  118. package/runtime/core/hellolynk-native-human-confirmation-broker.mjs +1036 -0
  119. package/runtime/core/hellolynk-native-inbox-runtime.mjs +553 -0
  120. package/runtime/core/hellolynk-native-notice.mjs +50 -0
  121. package/runtime/core/hellolynk-native-reply-routes.mjs +96 -0
  122. package/runtime/core/hellolynk-native-worker-lease.mjs +84 -0
  123. package/runtime/core/hellolynk-neutral-host-assembly.mjs +955 -0
  124. package/runtime/core/hellolynk-neutral-host-installation-store.mjs +765 -0
  125. package/runtime/core/hellolynk-neutral-host-launcher.mjs +665 -0
  126. package/runtime/core/hellolynk-neutral-host-process.mjs +4374 -0
  127. package/runtime/core/hellolynk-neutral-host-store-adapters.mjs +548 -0
  128. package/runtime/core/hellolynk-neutral-host-workbench-read-model.mjs +1365 -0
  129. package/runtime/core/hellolynk-platform-credential-store.mjs +773 -0
  130. package/runtime/core/hellolynk-relay-client-cli.mjs +232 -0
  131. package/runtime/core/hellolynk-release-retention.mjs +160 -0
  132. package/runtime/core/hellolynk-runtime-safety.cjs +471 -0
  133. package/runtime/core/hellolynk-workbench-action-grants.mjs +457 -0
  134. package/runtime/core/hellolynk-workbench-connection.mjs +234 -0
  135. package/runtime/neutral-host-bootstrap.mjs +57 -0
  136. package/runtime/neutral-host-release-entry.mjs +81 -0
  137. package/runtime/neutral-host-release-loader.mjs +156 -0
  138. package/runtime/neutral-host-release-manifest.json +302 -0
  139. package/runtime/neutral-host-release-pin.json +4 -0
  140. package/runtime/platform/windows/configure-agent.ps1 +281 -0
  141. package/runtime/platform/windows/credential-store.ps1 +844 -0
  142. package/runtime/platform/windows/hellolynk-host-protected-store.ps1 +2866 -0
  143. package/runtime/platform/windows/hellolynk-human-confirmation-ledger.ps1 +155 -0
  144. package/runtime/platform/windows/hellolynk-local-data-key.ps1 +300 -0
  145. package/runtime/platform/windows/hellolynk-native-human-confirmation-broker.ps1 +216 -0
  146. package/runtime/workbench/candidate-bootstrap.mjs +54 -0
  147. package/runtime/workbench/contract.mjs +1314 -0
  148. package/runtime/workbench/hellolynk-workbench-build.json +215 -0
  149. package/runtime/workbench/host-capabilities.mjs +80 -0
  150. package/runtime/workbench/i18n.mjs +1127 -0
  151. package/runtime/workbench/loopback-surface.mjs +740 -0
  152. package/runtime/workbench/mcp-app-bundle.mjs +97 -0
  153. package/runtime/workbench/service.mjs +485 -0
  154. package/runtime/workbench/state.mjs +421 -0
  155. package/runtime/workbench/transports.mjs +171 -0
  156. package/runtime/workbench/ui/app.mjs +6120 -0
  157. package/runtime/workbench/ui/connection-form.mjs +155 -0
  158. package/runtime/workbench/ui/hellolynk-mark.png +0 -0
  159. package/runtime/workbench/ui/http-transport.mjs +247 -0
  160. package/runtime/workbench/ui/icons/arrow-left.svg +3 -0
  161. package/runtime/workbench/ui/icons/close.svg +3 -0
  162. package/runtime/workbench/ui/icons/contacts.svg +3 -0
  163. package/runtime/workbench/ui/icons/inbox.svg +3 -0
  164. package/runtime/workbench/ui/icons/refresh.svg +3 -0
  165. package/runtime/workbench/ui/icons/search.svg +3 -0
  166. package/runtime/workbench/ui/icons/security.svg +3 -0
  167. package/runtime/workbench/ui/icons/settings.svg +3 -0
  168. package/runtime/workbench/ui/index.html +139 -0
  169. package/runtime/workbench/ui/loopback-entry.mjs +26 -0
  170. package/runtime/workbench/ui/mcp-app-client.mjs +151 -0
  171. package/runtime/workbench/ui/mcp-app-entry.mjs +452 -0
  172. package/runtime/workbench/ui/styles.css +686 -0
  173. package/tools/hellolynk-activate-neutral-host-clients.mjs +837 -0
  174. package/tools/hellolynk-install-client-skills.mjs +1211 -0
  175. package/workbuddy-package-manifest.json +1 -0
  176. package/workbuddy-package-pin.json +1 -0
@@ -0,0 +1,256 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { lstat } from "node:fs/promises";
3
+ import { createConnection } from "node:net";
4
+ import { dirname, isAbsolute, resolve } from "node:path";
5
+ import { spawn } from "node:child_process";
6
+ import { fileURLToPath } from "node:url";
7
+ import runtimeSafety from "./hellolynk-runtime-safety.cjs";
8
+
9
+ const { sanitizeHelloLynkChildEnvironment } = runtimeSafety;
10
+
11
+ export const HELLOLYNK_HUMAN_CONFIRMATION_LEDGER_CONTRACT =
12
+ "hellolynk-native-human-confirmation-ledger-v1";
13
+
14
+ const HELPER_PATH = fileURLToPath(new URL(
15
+ "../platform/windows/hellolynk-human-confirmation-ledger.ps1",
16
+ import.meta.url,
17
+ ));
18
+ const HEX_64 = /^[a-f0-9]{64}$/;
19
+ const ACTION_ID = /^human_[A-Za-z0-9_-]{16,96}$/;
20
+ const CODE = /^human_confirmation_[a-z0-9_]{1,100}$/;
21
+ const TERMINAL_STATES = new Set([
22
+ "approved", "cancelled", "consuming", "expired", "failed", "invalidated",
23
+ ]);
24
+
25
+ export function createWindowsHumanConfirmationLedger(options = {}) {
26
+ if ((options.platform || process.platform) !== "win32") {
27
+ throw error("human_confirmation_ledger_platform_unsupported");
28
+ }
29
+ const root = assertRoot(options.root);
30
+ const helperPath = resolve(options.helperPath || HELPER_PATH);
31
+ const invoke = options.invoke || ((command, value) => invokeHelper({
32
+ command, value, root, helperPath,
33
+ }));
34
+
35
+ async function admit(value) {
36
+ const input = normalizeAdmission(value);
37
+ const result = await invoke("Admit", input);
38
+ assertPlain(result);
39
+ if (result.accepted === true && Object.keys(result).length === 1) {
40
+ return Object.freeze({ accepted: true });
41
+ }
42
+ if (result.accepted !== false) throw error("human_confirmation_ledger_response_invalid");
43
+ if (result.reason === "rate_limited") {
44
+ assertExact(result, ["accepted", "reason", "retryAfterMs"], "human_confirmation_ledger_response_invalid");
45
+ return Object.freeze({
46
+ accepted: false,
47
+ reason: "rate_limited",
48
+ retryAfterMs: integer(result.retryAfterMs, "human_confirmation_ledger_response_invalid"),
49
+ });
50
+ }
51
+ if (result.reason === "partition_pending") {
52
+ assertExact(result, ["accepted", "reason"], "human_confirmation_ledger_response_invalid");
53
+ return Object.freeze({ accepted: false, reason: "partition_pending" });
54
+ }
55
+ throw error("human_confirmation_ledger_response_invalid");
56
+ }
57
+
58
+ async function record(value) {
59
+ const input = normalizeRecord(value);
60
+ const result = await invoke("Record", input);
61
+ assertExact(result, ["recorded"], "human_confirmation_ledger_response_invalid");
62
+ if (result.recorded !== true) throw error("human_confirmation_ledger_response_invalid");
63
+ }
64
+
65
+ async function lookup(value) {
66
+ const input = normalizeLookup(value);
67
+ const result = await invoke("Lookup", input);
68
+ assertExact(result, ["record"], "human_confirmation_ledger_response_invalid");
69
+ if (result.record === null) return null;
70
+ return normalizeTombstone(result.record, input);
71
+ }
72
+
73
+ return Object.freeze({
74
+ contract: HELLOLYNK_HUMAN_CONFIRMATION_LEDGER_CONTRACT,
75
+ durability: "cross-process",
76
+ admit,
77
+ record,
78
+ lookup,
79
+ });
80
+ }
81
+
82
+ function normalizeAdmission(value) {
83
+ assertExact(value, [
84
+ "actionId", "contract", "createdAtMs", "expiresAtMs", "partitionHash",
85
+ "rateLimit", "rateWindowMs", "restartTombstoneCode", "restartTombstoneState",
86
+ ]);
87
+ if (value.contract !== HELLOLYNK_HUMAN_CONFIRMATION_LEDGER_CONTRACT
88
+ || value.restartTombstoneState !== "invalidated"
89
+ || value.restartTombstoneCode !== "human_confirmation_restart_invalidated"
90
+ || value.rateLimit !== 3 || value.rateWindowMs !== 60_000) {
91
+ throw error("human_confirmation_ledger_input_invalid");
92
+ }
93
+ const createdAtMs = integer(value.createdAtMs);
94
+ const expiresAtMs = integer(value.expiresAtMs);
95
+ if (expiresAtMs <= createdAtMs) throw error("human_confirmation_ledger_input_invalid");
96
+ return Object.freeze({
97
+ contract: value.contract,
98
+ actionId: actionId(value.actionId),
99
+ partitionDigest: digest(value.partitionHash),
100
+ createdAtMs,
101
+ expiresAtMs,
102
+ rateWindowMs: value.rateWindowMs,
103
+ rateLimit: value.rateLimit,
104
+ restartTombstoneState: value.restartTombstoneState,
105
+ restartTombstoneCode: value.restartTombstoneCode,
106
+ });
107
+ }
108
+
109
+ function normalizeRecord(value) {
110
+ assertExact(value, [
111
+ "actionId", "code", "contract", "createdAtMs", "expiresAtMs", "partitionHash",
112
+ "recordedAtMs", "state",
113
+ ]);
114
+ if (value.contract !== HELLOLYNK_HUMAN_CONFIRMATION_LEDGER_CONTRACT
115
+ || !TERMINAL_STATES.has(value.state)) throw error("human_confirmation_ledger_input_invalid");
116
+ const createdAtMs = integer(value.createdAtMs);
117
+ const expiresAtMs = integer(value.expiresAtMs);
118
+ const recordedAtMs = integer(value.recordedAtMs);
119
+ if (expiresAtMs <= createdAtMs || recordedAtMs < createdAtMs) {
120
+ throw error("human_confirmation_ledger_input_invalid");
121
+ }
122
+ const code = value.code === null ? null : String(value.code);
123
+ if (code !== null && !CODE.test(code)) throw error("human_confirmation_ledger_input_invalid");
124
+ if (value.state === "consuming" && code !== null) throw error("human_confirmation_ledger_input_invalid");
125
+ return Object.freeze({
126
+ contract: value.contract,
127
+ actionId: actionId(value.actionId),
128
+ partitionDigest: digest(value.partitionHash),
129
+ state: value.state,
130
+ code,
131
+ createdAtMs,
132
+ expiresAtMs,
133
+ recordedAtMs,
134
+ });
135
+ }
136
+
137
+ function normalizeLookup(value) {
138
+ assertExact(value, ["actionId", "contract", "partitionHash"]);
139
+ if (value.contract !== HELLOLYNK_HUMAN_CONFIRMATION_LEDGER_CONTRACT) {
140
+ throw error("human_confirmation_ledger_input_invalid");
141
+ }
142
+ return Object.freeze({
143
+ contract: value.contract,
144
+ actionId: actionId(value.actionId),
145
+ partitionDigest: digest(value.partitionHash),
146
+ });
147
+ }
148
+
149
+ function normalizeTombstone(value, query) {
150
+ assertExact(value, ["actionId", "code", "createdAtMs", "expiresAtMs", "state"], "human_confirmation_ledger_response_invalid");
151
+ if (value.actionId !== query.actionId || !TERMINAL_STATES.has(value.state)) {
152
+ throw error("human_confirmation_ledger_response_invalid");
153
+ }
154
+ const code = value.code === null ? null : String(value.code);
155
+ if (code !== null && !CODE.test(code)) throw error("human_confirmation_ledger_response_invalid");
156
+ return Object.freeze({
157
+ actionId: value.actionId,
158
+ state: value.state,
159
+ code,
160
+ createdAtMs: integer(value.createdAtMs, "human_confirmation_ledger_response_invalid"),
161
+ expiresAtMs: integer(value.expiresAtMs, "human_confirmation_ledger_response_invalid"),
162
+ });
163
+ }
164
+
165
+ async function invokeHelper(input) {
166
+ const helper = await lstat(input.helperPath);
167
+ if (!helper.isFile() || helper.isSymbolicLink()) throw error("human_confirmation_ledger_helper_invalid");
168
+ const pipeName = `HelloLynkHumanLedger-${process.pid}-${randomBytes(18).toString("base64url")}`;
169
+ const pipePath = `\\\\.\\pipe\\${pipeName}`;
170
+ const args = [
171
+ "-NoLogo", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", input.helperPath,
172
+ "-Command", input.command, "-StoreRoot", input.root, "-ResultPipeName", pipeName,
173
+ ];
174
+ const child = spawn("pwsh.exe", args, {
175
+ windowsHide: true,
176
+ stdio: ["pipe", "pipe", "pipe"],
177
+ env: minimalEnvironment(process.env),
178
+ });
179
+ let cancelled = false;
180
+ const resultPromise = readPipe(pipePath, () => cancelled);
181
+ resultPromise.catch(() => {});
182
+ const stdout = [];
183
+ const stderr = [];
184
+ let stdoutBytes = 0;
185
+ let stderrBytes = 0;
186
+ child.stdout.on("data", (chunk) => { stdoutBytes += chunk.length; if (stdoutBytes <= 1024) stdout.push(chunk); });
187
+ child.stderr.on("data", (chunk) => { stderrBytes += chunk.length; if (stderrBytes <= 4096) stderr.push(chunk); });
188
+ child.stdin.end(JSON.stringify(input.value), "utf8");
189
+ const exitCode = await new Promise((resolveExit, rejectExit) => {
190
+ child.once("error", rejectExit);
191
+ child.once("close", resolveExit);
192
+ });
193
+ if (stdoutBytes) { cancelled = true; throw error("human_confirmation_ledger_helper_stdout_forbidden"); }
194
+ if (stderrBytes > 4096) { cancelled = true; throw error("human_confirmation_ledger_helper_stderr_oversize"); }
195
+ if (exitCode !== 0) {
196
+ cancelled = true;
197
+ throw error(publicCode(Buffer.concat(stderr).toString("utf8").trim()));
198
+ }
199
+ const raw = await resultPromise;
200
+ try { return JSON.parse(raw); } catch { throw error("human_confirmation_ledger_response_invalid"); }
201
+ }
202
+
203
+ async function readPipe(path, cancelled) {
204
+ const deadline = Date.now() + 45_000;
205
+ while (true) {
206
+ try {
207
+ return await new Promise((resolvePipe, rejectPipe) => {
208
+ const chunks = [];
209
+ let bytes = 0;
210
+ const socket = createConnection(path);
211
+ socket.on("data", (chunk) => {
212
+ bytes += chunk.length;
213
+ if (bytes > 64 * 1024) socket.destroy(error("human_confirmation_ledger_response_too_large"));
214
+ else chunks.push(chunk);
215
+ });
216
+ socket.on("error", rejectPipe);
217
+ socket.on("end", () => resolvePipe(Buffer.concat(chunks).toString("utf8")));
218
+ });
219
+ } catch (cause) {
220
+ if (cancelled()) throw error("human_confirmation_ledger_result_cancelled");
221
+ if (cause?.code !== "ENOENT" || Date.now() >= deadline) throw cause;
222
+ await new Promise((resolveWait) => setTimeout(resolveWait, 10));
223
+ }
224
+ }
225
+ }
226
+
227
+ function minimalEnvironment(source) {
228
+ const allowed = ["PATH", "Path", "PATHEXT", "SYSTEMROOT", "SystemRoot", "TEMP", "TMP", "COMSPEC"];
229
+ return sanitizeHelloLynkChildEnvironment(Object.fromEntries(
230
+ allowed.filter((key) => source[key] !== undefined).map((key) => [key, source[key]]),
231
+ ));
232
+ }
233
+
234
+ function publicCode(value) {
235
+ return /^human_confirmation_ledger_[a-z0-9_]{1,90}$/.test(value)
236
+ ? value
237
+ : "human_confirmation_ledger_operation_failed";
238
+ }
239
+
240
+ function assertRoot(value) {
241
+ const raw = String(value || "");
242
+ if (!/^[A-Za-z]:[\\/]/.test(raw) || raw.startsWith("\\\\") || raw.includes("\0")) {
243
+ throw error("human_confirmation_ledger_root_invalid");
244
+ }
245
+ const root = resolve(raw);
246
+ if (!isAbsolute(root) || !/^[A-Za-z]:\\/.test(root) || root.length < 4) {
247
+ throw error("human_confirmation_ledger_root_invalid");
248
+ }
249
+ return root;
250
+ }
251
+ function actionId(value) { const v = String(value || ""); if (!ACTION_ID.test(v)) throw error("human_confirmation_ledger_input_invalid"); return v; }
252
+ function digest(value) { const v = String(value || "").toLowerCase(); if (!HEX_64.test(v)) throw error("human_confirmation_ledger_input_invalid"); return v; }
253
+ function integer(value, code = "human_confirmation_ledger_input_invalid") { if (!Number.isSafeInteger(value) || value < 0) throw error(code); return value; }
254
+ function assertPlain(value) { if (!value || typeof value !== "object" || Array.isArray(value)) throw error("human_confirmation_ledger_response_invalid"); }
255
+ function assertExact(value, keys, code = "human_confirmation_ledger_input_invalid") { assertPlain(value); const a = Object.keys(value).sort(); const b = [...keys].sort(); if (a.length !== b.length || a.some((v, i) => v !== b[i])) throw error(code); }
256
+ function error(code) { const value = new Error(code); value.code = code; return value; }