@hellolynk-ai/codex-plugin 0.0.0-stage → 0.2.99

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 (123) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/LICENSE +92 -0
  3. package/README.md +86 -2
  4. package/bin/hellolynk-client-setup.mjs +2748 -0
  5. package/bin/hellolynk-mcp-config-shape.mjs +23 -0
  6. package/hellolynk-client-pack-manifest.json +619 -0
  7. package/hellolynk-client-pack-pin.json +4 -0
  8. package/package.json +58 -4
  9. package/plugins/hellolynk-codex/.app.json +3 -0
  10. package/plugins/hellolynk-codex/.codex-plugin/plugin.json +38 -0
  11. package/plugins/hellolynk-codex/.mcp.json +19 -0
  12. package/plugins/hellolynk-codex/assets/hellolynk-mark.png +0 -0
  13. package/plugins/hellolynk-codex/package.json +11 -0
  14. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-client-account.mjs +180 -0
  15. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-client-core.mjs +770 -0
  16. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-client-profile.mjs +191 -0
  17. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-host-auth.mjs +347 -0
  18. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-host-protected-store.mjs +2721 -0
  19. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-local-process-lock.mjs +157 -0
  20. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-neutral-host-installation-store.mjs +765 -0
  21. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-platform-credential-store.mjs +773 -0
  22. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-runtime-safety.cjs +471 -0
  23. package/plugins/hellolynk-codex/runtime/bootstrap/platform/windows/hellolynk-host-protected-store.ps1 +2866 -0
  24. package/plugins/hellolynk-codex/runtime/connect-activate.mjs +837 -0
  25. package/plugins/hellolynk-codex/runtime/core/hellolynk-agent-configurator.mjs +701 -0
  26. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-account.mjs +180 -0
  27. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-core.mjs +770 -0
  28. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-profile.mjs +191 -0
  29. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-update-entry.mjs +31 -0
  30. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-update-runtime.mjs +600 -0
  31. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-update.mjs +453 -0
  32. package/plugins/hellolynk-codex/runtime/core/hellolynk-contact-request-e2ee.mjs +867 -0
  33. package/plugins/hellolynk-codex/runtime/core/hellolynk-device-enrollment.mjs +435 -0
  34. package/plugins/hellolynk-codex/runtime/core/hellolynk-direct-text-e2ee-client.mjs +1964 -0
  35. package/plugins/hellolynk-codex/runtime/core/hellolynk-direct-text-e2ee.mjs +1207 -0
  36. package/plugins/hellolynk-codex/runtime/core/hellolynk-host-auth.mjs +347 -0
  37. package/plugins/hellolynk-codex/runtime/core/hellolynk-host-protected-store.mjs +2721 -0
  38. package/plugins/hellolynk-codex/runtime/core/hellolynk-host-transport-client.mjs +946 -0
  39. package/plugins/hellolynk-codex/runtime/core/hellolynk-host.mjs +2374 -0
  40. package/plugins/hellolynk-codex/runtime/core/hellolynk-human-confirmation-ledger.mjs +256 -0
  41. package/plugins/hellolynk-codex/runtime/core/hellolynk-human-relationship-controller.mjs +1234 -0
  42. package/plugins/hellolynk-codex/runtime/core/hellolynk-inbox-read-state.mjs +11 -0
  43. package/plugins/hellolynk-codex/runtime/core/hellolynk-indexed-message-store.mjs +1558 -0
  44. package/plugins/hellolynk-codex/runtime/core/hellolynk-instance-conversation.mjs +185 -0
  45. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-contact-requests.mjs +1733 -0
  46. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-contacts.mjs +1228 -0
  47. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-data-migration.mjs +766 -0
  48. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-data-protection.mjs +747 -0
  49. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-identity-trust.mjs +274 -0
  50. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-messaging.mjs +3043 -0
  51. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-peer-transport.mjs +103 -0
  52. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-process-lock.mjs +157 -0
  53. package/plugins/hellolynk-codex/runtime/core/hellolynk-model-inbox.mjs +230 -0
  54. package/plugins/hellolynk-codex/runtime/core/hellolynk-model-notices.cjs +60 -0
  55. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-addressing-tools.cjs +231 -0
  56. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-conversations.mjs +280 -0
  57. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-human-confirmation-broker.mjs +1036 -0
  58. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-inbox-runtime.mjs +553 -0
  59. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-notice.mjs +50 -0
  60. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-reply-routes.mjs +96 -0
  61. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-worker-lease.mjs +84 -0
  62. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-assembly.mjs +955 -0
  63. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-installation-store.mjs +765 -0
  64. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-launcher.mjs +665 -0
  65. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-process.mjs +4374 -0
  66. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-store-adapters.mjs +548 -0
  67. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-workbench-read-model.mjs +1365 -0
  68. package/plugins/hellolynk-codex/runtime/core/hellolynk-platform-credential-store.mjs +773 -0
  69. package/plugins/hellolynk-codex/runtime/core/hellolynk-relay-client-cli.mjs +232 -0
  70. package/plugins/hellolynk-codex/runtime/core/hellolynk-release-retention.mjs +160 -0
  71. package/plugins/hellolynk-codex/runtime/core/hellolynk-runtime-safety.cjs +471 -0
  72. package/plugins/hellolynk-codex/runtime/core/hellolynk-workbench-action-grants.mjs +457 -0
  73. package/plugins/hellolynk-codex/runtime/core/hellolynk-workbench-connection.mjs +234 -0
  74. package/plugins/hellolynk-codex/runtime/neutral-host-bootstrap.mjs +64 -0
  75. package/plugins/hellolynk-codex/runtime/neutral-host-release-entry.mjs +70 -0
  76. package/plugins/hellolynk-codex/runtime/neutral-host-release-loader.mjs +156 -0
  77. package/plugins/hellolynk-codex/runtime/neutral-host-release-manifest.json +358 -0
  78. package/plugins/hellolynk-codex/runtime/neutral-host-release-pin.json +4 -0
  79. package/plugins/hellolynk-codex/runtime/platform/windows/configure-agent.ps1 +281 -0
  80. package/plugins/hellolynk-codex/runtime/platform/windows/credential-store.ps1 +844 -0
  81. package/plugins/hellolynk-codex/runtime/platform/windows/hellolynk-host-protected-store.ps1 +2866 -0
  82. package/plugins/hellolynk-codex/runtime/platform/windows/hellolynk-human-confirmation-ledger.ps1 +155 -0
  83. package/plugins/hellolynk-codex/runtime/platform/windows/hellolynk-local-data-key.ps1 +300 -0
  84. package/plugins/hellolynk-codex/runtime/platform/windows/hellolynk-native-human-confirmation-broker.ps1 +216 -0
  85. package/plugins/hellolynk-codex/runtime/workbench/candidate-bootstrap.mjs +54 -0
  86. package/plugins/hellolynk-codex/runtime/workbench/contract.mjs +1314 -0
  87. package/plugins/hellolynk-codex/runtime/workbench/hellolynk-workbench-build.json +215 -0
  88. package/plugins/hellolynk-codex/runtime/workbench/host-capabilities.mjs +80 -0
  89. package/plugins/hellolynk-codex/runtime/workbench/i18n.mjs +1127 -0
  90. package/plugins/hellolynk-codex/runtime/workbench/loopback-surface.mjs +740 -0
  91. package/plugins/hellolynk-codex/runtime/workbench/mcp-app-bundle.mjs +97 -0
  92. package/plugins/hellolynk-codex/runtime/workbench/service.mjs +485 -0
  93. package/plugins/hellolynk-codex/runtime/workbench/state.mjs +421 -0
  94. package/plugins/hellolynk-codex/runtime/workbench/transports.mjs +171 -0
  95. package/plugins/hellolynk-codex/runtime/workbench/ui/app.mjs +6120 -0
  96. package/plugins/hellolynk-codex/runtime/workbench/ui/connection-form.mjs +155 -0
  97. package/plugins/hellolynk-codex/runtime/workbench/ui/hellolynk-mark.png +0 -0
  98. package/plugins/hellolynk-codex/runtime/workbench/ui/http-transport.mjs +247 -0
  99. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/arrow-left.svg +3 -0
  100. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/close.svg +3 -0
  101. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/contacts.svg +3 -0
  102. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/inbox.svg +3 -0
  103. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/refresh.svg +3 -0
  104. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/search.svg +3 -0
  105. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/security.svg +3 -0
  106. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/settings.svg +3 -0
  107. package/plugins/hellolynk-codex/runtime/workbench/ui/index.html +139 -0
  108. package/plugins/hellolynk-codex/runtime/workbench/ui/loopback-entry.mjs +26 -0
  109. package/plugins/hellolynk-codex/runtime/workbench/ui/mcp-app-client.mjs +151 -0
  110. package/plugins/hellolynk-codex/runtime/workbench/ui/mcp-app-entry.mjs +452 -0
  111. package/plugins/hellolynk-codex/runtime/workbench/ui/styles.css +686 -0
  112. package/plugins/hellolynk-codex/server/codex-neutral-production.mjs +520 -0
  113. package/plugins/hellolynk-codex/server/mcp-proxy.mjs +306 -0
  114. package/plugins/hellolynk-codex/server/mcp-server.mjs +1193 -0
  115. package/plugins/hellolynk-codex/server/native-conversation-directory.mjs +33 -0
  116. package/plugins/hellolynk-codex/server/native-reply-routes.mjs +32 -0
  117. package/plugins/hellolynk-codex/server/native-task-client.mjs +382 -0
  118. package/plugins/hellolynk-codex/server/native-task-runtime.mjs +8 -0
  119. package/plugins/hellolynk-codex/server/neutral-host-adapter.mjs +649 -0
  120. package/plugins/hellolynk-codex/server/workbench-runtime.mjs +180 -0
  121. package/plugins/hellolynk-codex/skills/hellolynk-open/SKILL.md +11 -0
  122. package/plugins/hellolynk-codex/skills/hellolynk-open/agents/openai.yaml +4 -0
  123. package/tools/hellolynk-activate-neutral-host-clients.mjs +837 -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; }