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

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 +101 -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 +277 -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,64 @@
1
+ #!/usr/bin/env node
2
+ import path from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+ import { prepareCodexNeutralRelease } from "../server/codex-neutral-production.mjs";
5
+
6
+ export async function runNeutralHostBootstrap(argv = process.argv.slice(2)) {
7
+ const options = parse(argv);
8
+ const prepared = await prepareCodexNeutralRelease({ storeRoot: options.root });
9
+ const { release } = prepared;
10
+ if (typeof release.run !== "function") throw codeError("neutral_codex_runner_integrity_invalid");
11
+ // Hand over the binding this process just resolved; null makes the runner resolve it again.
12
+ const binding = await prepared.runnerBinding?.(options.root) ?? null;
13
+ return release.run({ root: options.root, binding });
14
+ }
15
+
16
+ function parse(argv) {
17
+ if (argv.length !== 3 || argv[0] !== "run" || argv[1] !== "--root"
18
+ || !path.isAbsolute(String(argv[2] || ""))) throw codeError("neutral_codex_launch_configuration_required");
19
+ return { root: path.resolve(argv[2]) };
20
+ }
21
+
22
+ function safeCode(error) {
23
+ const value = String(error?.code || error?.message || "neutral_codex_launch_failed");
24
+ return /^neutral_(?:codex|host)_[a-z0-9_]{2,100}$/.test(value) ? value : "neutral_codex_launch_failed";
25
+ }
26
+ function codeError(code) { const error = new Error(code); error.code = code; return error; }
27
+
28
+ // Start failures and a failed Host both end here. A failed Host keeps its lock until this
29
+ // process exits on its own: a closed stderr pipe (the detached launcher may be gone) must
30
+ // not crash it before admitted work finishes.
31
+ function exitWithFailure(code) {
32
+ process.stderr.on("error", () => {});
33
+ process.stderr.write(`${JSON.stringify({ ok: false, code })}\n`);
34
+ process.exitCode = 1;
35
+ }
36
+
37
+ // A stray rejection must not take the Host down: log a stable code and keep serving. A synchronous
38
+ // uncaught exception leaves state unknown: stop the Host (releases its lock), then exit; 15 s bounds a stuck stop.
39
+ function guardHostProcess(result) {
40
+ process.on("unhandledRejection", (reason) => writeFailure("neutral_codex_unhandled_rejection", reason));
41
+ process.on("uncaughtException", (error) => {
42
+ writeFailure("neutral_codex_uncaught_exception", error);
43
+ process.exitCode = 1;
44
+ const exit = () => process.exit(1);
45
+ setTimeout(exit, 15_000).unref?.();
46
+ Promise.resolve().then(() => result?.stop?.("uncaught_exception")).then(exit, exit);
47
+ });
48
+ return result;
49
+ }
50
+
51
+ function writeFailure(code, cause) {
52
+ if (!process.stderr.listenerCount("error")) process.stderr.on("error", () => {});
53
+ process.stderr.write(`${JSON.stringify({ ok: false, code, cause: String(cause?.code || cause?.name || "").slice(0, 80) })}\n`);
54
+ }
55
+
56
+ if (import.meta.url === pathToFileURL(process.argv[1] || "").href) {
57
+ runNeutralHostBootstrap()
58
+ .then((result) => {
59
+ guardHostProcess(result);
60
+ if (typeof result?.waitUntilStopped === "function") return result.waitUntilStopped();
61
+ return new Promise(() => {});
62
+ })
63
+ .catch((error) => exitWithFailure(safeCode(error)));
64
+ }
@@ -0,0 +1,70 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+
4
+ import { createHostProtectedStore } from "./core/hellolynk-host-protected-store.mjs";
5
+ import {
6
+ createNeutralHostInstallationStore,
7
+ defaultNeutralHostStoreRoot,
8
+ } from "./core/hellolynk-neutral-host-installation-store.mjs";
9
+ import { startHelloLynkNeutralHostAssembly } from "./core/hellolynk-neutral-host-assembly.mjs";
10
+
11
+ export async function createNeutralHostReleaseRuntime() {
12
+ return Object.freeze({
13
+ defaultStoreRoot: (env) => defaultNeutralHostStoreRoot("win32", env),
14
+ createInstallationStore: (options) => createNeutralHostInstallationStore(options),
15
+ createProtectedStore: (options) => createHostProtectedStore(options),
16
+ run: async ({ root, binding }) => runProductionHost(root, binding),
17
+ });
18
+ }
19
+
20
+ async function runProductionHost(rootInput, handedBinding = null) {
21
+ const root = path.resolve(String(rootInput || ""));
22
+ if (!path.isAbsolute(root) || root.length < 4) throw codeError("neutral_codex_launch_configuration_required");
23
+ const installationStore = createNeutralHostInstallationStore({ root });
24
+ const protectedStore = createHostProtectedStore({ root, installationStore });
25
+ // The bootstrap hands over the binding it resolved in this process while
26
+ // nothing changed since. Only its launch paths are used here.
27
+ const binding = handedBinding || await resolveLaunchPaths(protectedStore);
28
+ const profiles = await readProfileManifest(binding.profileManifestPath);
29
+ const assembly = await startHelloLynkNeutralHostAssembly({
30
+ root,
31
+ runtimeRoot: binding.runtimeRoot,
32
+ profiles: profiles.map((profileFile) => ({ profileFile })),
33
+ }, { installationStore, protectedStore });
34
+ return Object.freeze({
35
+ stop: assembly.stop,
36
+ waitUntilStopped: async () => {
37
+ while (assembly.host.status !== "stopped") {
38
+ // A failed Host never reaches "stopped"; end the wait so the bootstrap exits with its code.
39
+ if (assembly.host.status === "failed") throw codeError(assembly.host.failureCode || "neutral_host_stop_failed");
40
+ await new Promise((resolve) => setTimeout(resolve, 50));
41
+ }
42
+ },
43
+ });
44
+ }
45
+
46
+ async function resolveLaunchPaths(protectedStore) {
47
+ const { capability, ...binding } = await protectedStore.resolveCodexNeutralBinding();
48
+ capability?.secretBuffer?.fill(0);
49
+ return binding;
50
+ }
51
+
52
+ async function readProfileManifest(manifestPathInput) {
53
+ const manifestPath = path.resolve(String(manifestPathInput || ""));
54
+ if (!path.isAbsolute(manifestPath)) throw codeError("neutral_codex_launch_manifest_invalid");
55
+ let manifest;
56
+ try { manifest = JSON.parse(await fs.readFile(manifestPath, "utf8")); }
57
+ catch { throw codeError("neutral_codex_launch_manifest_invalid"); }
58
+ if (!manifest || manifest.contract !== "hellolynk-neutral-host-profile-manifest-v1"
59
+ || !Array.isArray(manifest.profiles) || !manifest.profiles.length || manifest.profiles.length > 16
60
+ || Object.keys(manifest).sort().join(",") !== "contract,profiles") {
61
+ throw codeError("neutral_codex_launch_manifest_invalid");
62
+ }
63
+ const profiles = manifest.profiles.map((value) => path.resolve(String(value || "")));
64
+ if (profiles.some((value, index) => !path.isAbsolute(value) || profiles.indexOf(value) !== index)) {
65
+ throw codeError("neutral_codex_launch_manifest_invalid");
66
+ }
67
+ return Object.freeze(profiles);
68
+ }
69
+
70
+ function codeError(code) { const error = new Error(code); error.code = code; return error; }
@@ -0,0 +1,156 @@
1
+ import crypto from "node:crypto";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
+
6
+ const ROOT = path.dirname(fileURLToPath(import.meta.url));
7
+ const PIN_PATH = path.join(ROOT, "neutral-host-release-pin.json");
8
+ const MANIFEST_PATH = path.join(ROOT, "neutral-host-release-manifest.json");
9
+ const SAFE_RUNTIME_RELATIVE = /^(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*[A-Za-z0-9][A-Za-z0-9._-]*\.(?:cjs|mjs|ps1)$/;
10
+ const SAFE_RELEASE_RELATIVE = /^release\/(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*[A-Za-z0-9][A-Za-z0-9._-]*\.(?:mjs|ps1|md|html|js|css|json)$/;
11
+
12
+ export async function inspectNeutralHostRelease() {
13
+ await assertNoReparseAncestors(ROOT);
14
+ const pinArtifact = await readArtifact(PIN_PATH, 16 * 1024);
15
+ const pin = parseJson(pinArtifact.bytes);
16
+ exact(pin, ["contract", "manifestSha256"]);
17
+ if (pin.contract !== "hellolynk-neutral-host-release-pin-v1" || !HASH.test(String(pin.manifestSha256 || ""))) fail();
18
+ const manifestArtifact = await readArtifact(MANIFEST_PATH, 256 * 1024);
19
+ if (sha256(manifestArtifact.bytes) !== pin.manifestSha256) fail();
20
+ let manifest;
21
+ try { manifest = JSON.parse(manifestArtifact.bytes); } catch { fail(); }
22
+ exact(manifest, ["contract", "entry", "files"]);
23
+ if (manifest.contract !== "hellolynk-neutral-host-release-manifest-v1"
24
+ || !Array.isArray(manifest.files) || manifest.files.length < 3 || manifest.files.length > 128) fail();
25
+ const files = [];
26
+ const seen = new Set();
27
+ for (const item of manifest.files) {
28
+ exact(item, ["path", "sha256"]);
29
+ const relative = safeRelative(item.path);
30
+ if (seen.has(relative) || !HASH.test(String(item.sha256 || ""))) fail();
31
+ seen.add(relative);
32
+ const artifact = await readArtifact(inside(relative), 2 * 1024 * 1024);
33
+ if (sha256(artifact.bytes) !== item.sha256) fail();
34
+ files.push(Object.freeze({ relative, sha256: item.sha256, identity: artifact.identity }));
35
+ }
36
+ const entry = safeRelative(manifest.entry);
37
+ if (!seen.has(entry) || !seen.has("neutral-host-bootstrap.mjs")
38
+ || !seen.has("neutral-host-release-loader.mjs")) fail();
39
+ return Object.freeze({
40
+ contract: "hellolynk-neutral-host-release-inspection-v1",
41
+ releaseRoot: path.dirname(ROOT),
42
+ manifestSha256: pin.manifestSha256,
43
+ entry,
44
+ controls: Object.freeze([
45
+ Object.freeze({ relative: "neutral-host-release-pin.json", sha256: sha256(pinArtifact.bytes), identity: pinArtifact.identity }),
46
+ Object.freeze({ relative: "neutral-host-release-manifest.json", sha256: pin.manifestSha256, identity: manifestArtifact.identity }),
47
+ ]),
48
+ files: Object.freeze(files),
49
+ });
50
+ }
51
+
52
+ export async function activateNeutralHostRelease(inspection) {
53
+ if (!inspection || inspection.contract !== "hellolynk-neutral-host-release-inspection-v1"
54
+ || inspection.releaseRoot !== path.dirname(ROOT) || !Array.isArray(inspection.controls)
55
+ || inspection.controls.length !== 2 || !Array.isArray(inspection.files)) fail();
56
+ await assertNoReparseAncestors(ROOT);
57
+ for (const expected of inspection.controls) {
58
+ const control = CONTROL_PATHS.get(expected.relative);
59
+ if (!control) fail();
60
+ const artifact = await readArtifact(control, 256 * 1024);
61
+ if (sha256(artifact.bytes) !== expected.sha256 || !sameIdentity(artifact.identity, expected.identity)) fail();
62
+ }
63
+ for (const expected of inspection.files) {
64
+ const artifact = await readArtifact(inside(safeRelative(expected.relative)), 2 * 1024 * 1024);
65
+ if (sha256(artifact.bytes) !== expected.sha256 || !sameIdentity(artifact.identity, expected.identity)) fail();
66
+ }
67
+ const entryFile = inside(safeRelative(inspection.entry));
68
+ let module;
69
+ try { module = await import(`${pathToFileURL(entryFile).href}?verified=${inspection.manifestSha256}`); }
70
+ catch { throw codeError("neutral_codex_runner_integrity_invalid"); }
71
+ if (typeof module.createNeutralHostReleaseRuntime !== "function") fail();
72
+ const runtime = await module.createNeutralHostReleaseRuntime();
73
+ if (!runtime || typeof runtime !== "object" || Array.isArray(runtime)) fail();
74
+ return Object.freeze({ ...runtime, releaseManifestSha256: inspection.manifestSha256 });
75
+ }
76
+
77
+ export async function loadNeutralHostRelease() {
78
+ return activateNeutralHostRelease(await inspectNeutralHostRelease());
79
+ }
80
+
81
+ async function readArtifact(file, maximum) {
82
+ await assertNoReparseAncestors(file);
83
+ let handle;
84
+ try { handle = await fs.open(file, "r"); }
85
+ catch (error) {
86
+ if (error?.code === "ENOENT") throw codeError("neutral_codex_runner_unavailable");
87
+ throw codeError("neutral_codex_runner_integrity_invalid");
88
+ }
89
+ try {
90
+ const before = await handle.stat({ bigint: true });
91
+ if (!before.isFile() || before.nlink !== 1n || before.size > BigInt(maximum)) fail();
92
+ const bytes = await handle.readFile();
93
+ const after = await handle.stat({ bigint: true });
94
+ if (!sameIdentity(identity(before), identity(after))) fail();
95
+ return Object.freeze({ bytes, identity: identity(after) });
96
+ } catch (error) {
97
+ if (/^neutral_codex_/.test(String(error?.code || ""))) throw error;
98
+ throw codeError("neutral_codex_runner_integrity_invalid");
99
+ } finally { await handle?.close(); }
100
+ }
101
+
102
+ async function assertNoReparseAncestors(target) {
103
+ const resolved = path.resolve(target);
104
+ const parsed = path.parse(resolved);
105
+ let cursor = parsed.root;
106
+ for (const segment of path.relative(parsed.root, resolved).split(path.sep).filter(Boolean)) {
107
+ cursor = path.join(cursor, segment);
108
+ let stat;
109
+ try { stat = await fs.lstat(cursor); }
110
+ catch (error) {
111
+ if (error?.code === "ENOENT") throw codeError("neutral_codex_runner_unavailable");
112
+ throw codeError("neutral_codex_runner_integrity_invalid");
113
+ }
114
+ if (stat.isSymbolicLink()) fail();
115
+ }
116
+ }
117
+
118
+ function identity(stat) {
119
+ return Object.freeze({
120
+ dev: String(stat.dev), ino: String(stat.ino), size: String(stat.size),
121
+ mtimeNs: String(stat.mtimeNs), nlink: String(stat.nlink),
122
+ });
123
+ }
124
+ function sameIdentity(left, right) {
125
+ return left.dev === right.dev && left.ino === right.ino && left.size === right.size
126
+ && left.mtimeNs === right.mtimeNs && left.nlink === right.nlink;
127
+ }
128
+ function parseJson(bytes) { try { return JSON.parse(bytes); } catch { fail(); } }
129
+ function safeRelative(value) {
130
+ const text = String(value || "");
131
+ const allowed = text.startsWith("release/") ? SAFE_RELEASE_RELATIVE : SAFE_RUNTIME_RELATIVE;
132
+ if (!allowed.test(text) || text.split("/").includes("..")) fail();
133
+ return text;
134
+ }
135
+ function inside(relative) {
136
+ const releaseRoot = path.dirname(ROOT);
137
+ const result = relative.startsWith("release/")
138
+ ? path.resolve(releaseRoot, relative.slice("release/".length))
139
+ : path.resolve(ROOT, relative);
140
+ const base = relative.startsWith("release/") ? releaseRoot : ROOT;
141
+ if (!result.startsWith(`${base}${path.sep}`)) fail();
142
+ return result;
143
+ }
144
+ function exact(value, expected) {
145
+ if (!value || typeof value !== "object" || Array.isArray(value)) fail();
146
+ const actual = Object.keys(value).sort(); const wanted = [...expected].sort();
147
+ if (actual.length !== wanted.length || actual.some((key, index) => key !== wanted[index])) fail();
148
+ }
149
+ const HASH = /^[a-f0-9]{64}$/;
150
+ const CONTROL_PATHS = new Map([
151
+ ["neutral-host-release-pin.json", PIN_PATH],
152
+ ["neutral-host-release-manifest.json", MANIFEST_PATH],
153
+ ]);
154
+ function sha256(value) { return crypto.createHash("sha256").update(value).digest("hex"); }
155
+ function fail() { throw codeError("neutral_codex_runner_integrity_invalid"); }
156
+ function codeError(code) { const error = new Error(code); error.code = code; return error; }
@@ -0,0 +1,358 @@
1
+ {
2
+ "contract": "hellolynk-neutral-host-release-manifest-v1",
3
+ "entry": "neutral-host-release-entry.mjs",
4
+ "files": [
5
+ {
6
+ "path": "release/package.json",
7
+ "sha256": "bd762c92db97e96c4b9a1e1bef99a13d96cdd0e06bd58f4cf875fbcd00186cf9"
8
+ },
9
+ {
10
+ "path": "neutral-host-bootstrap.mjs",
11
+ "sha256": "53513deed7f0155a6603a1489d1609fae37776442358181ff7650d0cd9351f0a"
12
+ },
13
+ {
14
+ "path": "connect-activate.mjs",
15
+ "sha256": "50ec8b0a58ac5b099a653722b0946acb23d0a29a054bfb3856dc963db6f84bee"
16
+ },
17
+ {
18
+ "path": "neutral-host-release-loader.mjs",
19
+ "sha256": "15593e237fd5cbd765b65e60efe7a1c87e24a5390ad932c8a23d2c03b8da9770"
20
+ },
21
+ {
22
+ "path": "neutral-host-release-entry.mjs",
23
+ "sha256": "23e88d39362fe556eb96f86b2ac9740c0390f33f01edee5c89d708c80c4f8fa6"
24
+ },
25
+ {
26
+ "path": "core/hellolynk-agent-configurator.mjs",
27
+ "sha256": "505b010ffd2c3fb614f2a4c6eae92a9fc5b640b8e48dff39e563dcbaabfd344b"
28
+ },
29
+ {
30
+ "path": "core/hellolynk-client-account.mjs",
31
+ "sha256": "ab7ec5dda92e510e7deb14f900fd2df4c6c3373fbeb4af4fb2b6c1a72aa41a99"
32
+ },
33
+ {
34
+ "path": "core/hellolynk-client-core.mjs",
35
+ "sha256": "94bbad1d0ccee969bbffed176449e427188f1b892512a64167ab31f63d258e2b"
36
+ },
37
+ {
38
+ "path": "core/hellolynk-client-profile.mjs",
39
+ "sha256": "4b45a78b4d6c4794a1f494bd95777579c32c56a68321a1d3b484048942ae4742"
40
+ },
41
+ {
42
+ "path": "core/hellolynk-client-update-entry.mjs",
43
+ "sha256": "b2740406d79d0fa129c3bd1b5e6a07c3f52eed5e35a91ffea40b099ddc708936"
44
+ },
45
+ {
46
+ "path": "core/hellolynk-client-update-runtime.mjs",
47
+ "sha256": "3ed31f0cea704c3ad26481126a78a7d39c21df69a5c52d1074a096a2b7b3e32f"
48
+ },
49
+ {
50
+ "path": "core/hellolynk-client-update.mjs",
51
+ "sha256": "8f0d6f54313c91bd2ffb4643859a91dd1e122bb5f1da9143fe2851a3370d7fbf"
52
+ },
53
+ {
54
+ "path": "core/hellolynk-release-retention.mjs",
55
+ "sha256": "4ba5607e92f98a9a33b9ffd9ad166e559bc3197fcb1a6d54cef96b2b91ddc38e"
56
+ },
57
+ {
58
+ "path": "core/hellolynk-contact-request-e2ee.mjs",
59
+ "sha256": "657664c6250d2738061e1ec2680eda6b36063c357d9e2d9c743e4218ece50895"
60
+ },
61
+ {
62
+ "path": "core/hellolynk-device-enrollment.mjs",
63
+ "sha256": "f3e99ff2bdfa76e5a830a518792a1b9e5e705d7a8a01eca725dd7c5c8391d4ef"
64
+ },
65
+ {
66
+ "path": "core/hellolynk-direct-text-e2ee-client.mjs",
67
+ "sha256": "4007bf5e6c91df00adf10384cc1f0d0d28491b8ded518365dddbac717f3ac5be"
68
+ },
69
+ {
70
+ "path": "core/hellolynk-direct-text-e2ee.mjs",
71
+ "sha256": "f0abc3714cfad007669140ead4bfbb3f5bd56edd24d4389c3addee3f42887a01"
72
+ },
73
+ {
74
+ "path": "core/hellolynk-host-auth.mjs",
75
+ "sha256": "db1ec56f4e60e6450fba50188eecf89748f39f5d7a75c2456c30a6053233555d"
76
+ },
77
+ {
78
+ "path": "core/hellolynk-host-protected-store.mjs",
79
+ "sha256": "89b6e6c4ce9c6ba2984f8c301de4251da6004bdd402cc44d578a4505c21b75b1"
80
+ },
81
+ {
82
+ "path": "core/hellolynk-host-transport-client.mjs",
83
+ "sha256": "9f27d3e44ce8333413e712eb38b970a335b64081d7e3be6882ff5ca921668859"
84
+ },
85
+ {
86
+ "path": "core/hellolynk-host.mjs",
87
+ "sha256": "6cbe0ba6ec7aa81059a4a2d0e247fbedb6731687ec21ded4aaefa0e79be9e493"
88
+ },
89
+ {
90
+ "path": "core/hellolynk-model-notices.cjs",
91
+ "sha256": "c1b0d9071d3750c87755bc9fdf969d89c7fa62a0dede4c37b8cb2954b81163b0"
92
+ },
93
+ {
94
+ "path": "core/hellolynk-model-inbox.mjs",
95
+ "sha256": "516c846340ee7a2fd624eaedaa51ded81988ef875b8a7eeb15c2e296774bfa63"
96
+ },
97
+ {
98
+ "path": "core/hellolynk-native-inbox-runtime.mjs",
99
+ "sha256": "039ba7fe8273357d178556fc57e751c469e2bf0056bcaee5029e7fe376099c72"
100
+ },
101
+ {
102
+ "path": "core/hellolynk-native-reply-routes.mjs",
103
+ "sha256": "8ed07580f2b6fe6bff9953951ea79f6c7c1c806887cd0bf21d4893ba8343ebe2"
104
+ },
105
+ {
106
+ "path": "core/hellolynk-native-worker-lease.mjs",
107
+ "sha256": "e4e6864ff047b1d3511c363eb2bc7a3a3841a453f5d9d40b94bde55cc38cebc5"
108
+ },
109
+ {
110
+ "path": "core/hellolynk-human-confirmation-ledger.mjs",
111
+ "sha256": "63bcbbb0870ad83fc031636d74ce77fc070d5f4d1d4c10297f8b3ec9ad85bbf6"
112
+ },
113
+ {
114
+ "path": "core/hellolynk-human-relationship-controller.mjs",
115
+ "sha256": "7ef584c30febf0e142f621b719e433c0a9f5d976bbb917ab15f6cc1abb39ad52"
116
+ },
117
+ {
118
+ "path": "core/hellolynk-indexed-message-store.mjs",
119
+ "sha256": "61a9d642fb0453aa949c6e634a30ae3f8562a81d3a666580a2f32d414c9f80ad"
120
+ },
121
+ {
122
+ "path": "core/hellolynk-inbox-read-state.mjs",
123
+ "sha256": "bf2353075f0a10cc3492c0d7309f8d3fef4a4bda1996b878cfbae8515beaeb34"
124
+ },
125
+ {
126
+ "path": "core/hellolynk-instance-conversation.mjs",
127
+ "sha256": "f00161cbdab48b33f0be1a809389145c167d8b8bdfab32d8c929db3bc167b4a1"
128
+ },
129
+ {
130
+ "path": "core/hellolynk-local-contact-requests.mjs",
131
+ "sha256": "9724729b28c4c979696fcd53531e89eddb18a3045e32f602ecfb002af1c44b4c"
132
+ },
133
+ {
134
+ "path": "core/hellolynk-local-contacts.mjs",
135
+ "sha256": "b7c722f0c300f951ed390ea82aec04975b226f2ea4d5c873764ab36ef9a8bc2c"
136
+ },
137
+ {
138
+ "path": "core/hellolynk-local-data-migration.mjs",
139
+ "sha256": "1e791114633770fe3955842725965798dfd749e1dbf513f08efc4e01b9ed1756"
140
+ },
141
+ {
142
+ "path": "core/hellolynk-local-data-protection.mjs",
143
+ "sha256": "1bda879aa0bdf46700a63374e82cc7bc639385656b1463a75a49e8510971066c"
144
+ },
145
+ {
146
+ "path": "core/hellolynk-local-identity-trust.mjs",
147
+ "sha256": "b6d22715c627820c0ea92ca543cf52bbfeee5d5f416d242c2e21230640310420"
148
+ },
149
+ {
150
+ "path": "core/hellolynk-local-messaging.mjs",
151
+ "sha256": "23e701818b18b96ba36ad1dfc3c2489d80fec8dafa2f433cf29947175786ed07"
152
+ },
153
+ {
154
+ "path": "core/hellolynk-local-peer-transport.mjs",
155
+ "sha256": "9c32b2fa5f716f1ff36e09b3f2cd697479acc2f3c6bcb6e96045f5ca65e3b1c6"
156
+ },
157
+ {
158
+ "path": "core/hellolynk-local-process-lock.mjs",
159
+ "sha256": "5212990a98b9ad2eb83fa2d5fb8a123d687c5ef6daf6cba49a4b6d04a7fe251e"
160
+ },
161
+ {
162
+ "path": "core/hellolynk-native-conversations.mjs",
163
+ "sha256": "671030938a5259f6cce0c1eb4e61997f7f89232c677c9ba26062daea91b6f8c6"
164
+ },
165
+ {
166
+ "path": "core/hellolynk-native-notice.mjs",
167
+ "sha256": "6a5fe50fbccac465d690612839eaf7c10a5622cd84151277b0bf4507eccbe087"
168
+ },
169
+ {
170
+ "path": "core/hellolynk-native-addressing-tools.cjs",
171
+ "sha256": "252251de855c3fe9c5ebdd54a97ba976a8009f4ac57ec44f492bed8c7fb903de"
172
+ },
173
+ {
174
+ "path": "core/hellolynk-native-human-confirmation-broker.mjs",
175
+ "sha256": "2fb2d3b40869362be3e40a1ec55947021319af5315cbf8fdc5ed59df717cceb3"
176
+ },
177
+ {
178
+ "path": "core/hellolynk-neutral-host-assembly.mjs",
179
+ "sha256": "d0ac9c697bf8a85263d99a0739da557c62f52c72f4afb105eb97b3aac2ae1f3b"
180
+ },
181
+ {
182
+ "path": "core/hellolynk-neutral-host-installation-store.mjs",
183
+ "sha256": "b5f6288732af6f9b9c0c750f6002eae657dde9513fc97674f6e59200f3cc9dc6"
184
+ },
185
+ {
186
+ "path": "core/hellolynk-neutral-host-launcher.mjs",
187
+ "sha256": "789b2531cdbde6e6d8f91f2a40746372e903e9e48e8aa6846b9abf2d28150780"
188
+ },
189
+ {
190
+ "path": "core/hellolynk-neutral-host-process.mjs",
191
+ "sha256": "48f9bd6451adafdf3b43591a3b1469e36174c30fe04214cd2a84fb0aeebea023"
192
+ },
193
+ {
194
+ "path": "core/hellolynk-neutral-host-store-adapters.mjs",
195
+ "sha256": "3e425ca2cc111e750f55e94be2561cae8a3b308e473fb549e42da3443b67fd34"
196
+ },
197
+ {
198
+ "path": "core/hellolynk-neutral-host-workbench-read-model.mjs",
199
+ "sha256": "65ca217dbd5be05f4cf38fd977b0d536526f79463a402fae90a7329dac375670"
200
+ },
201
+ {
202
+ "path": "core/hellolynk-platform-credential-store.mjs",
203
+ "sha256": "f27f5f377cc4d6d2b5664212cf8fcc4c98d910064c1677ff9c1f776df1a59dba"
204
+ },
205
+ {
206
+ "path": "core/hellolynk-relay-client-cli.mjs",
207
+ "sha256": "29707c4e0d91d5db6f46408b4c1101b9ab30b117500a9e315da8802e71a43010"
208
+ },
209
+ {
210
+ "path": "core/hellolynk-runtime-safety.cjs",
211
+ "sha256": "43d576d9f774409f4a735793c1503a6f397e787b10c59a4ac9cc9257299f5efe"
212
+ },
213
+ {
214
+ "path": "core/hellolynk-workbench-action-grants.mjs",
215
+ "sha256": "076d1bb848c85c06695440f33daebd853a9f49147a85cf582cc3e2964d95198a"
216
+ },
217
+ {
218
+ "path": "core/hellolynk-workbench-connection.mjs",
219
+ "sha256": "d3396350fd75af78e60772e021cf6dfb643d9eee41894c5461c959a56650cb60"
220
+ },
221
+ {
222
+ "path": "workbench/candidate-bootstrap.mjs",
223
+ "sha256": "891b02f750693e5b4836e716922c2d632f6736b2a5b3b7417f161499459f3f56"
224
+ },
225
+ {
226
+ "path": "workbench/contract.mjs",
227
+ "sha256": "20648c3ed8e20b984b698010855414f8d4acaf0e2ade53b997b5582a85d90a08"
228
+ },
229
+ {
230
+ "path": "workbench/host-capabilities.mjs",
231
+ "sha256": "4e1a82e6cb46dd775ba39e2d34ff21eb1c293523883d18e607084ca91cfffb87"
232
+ },
233
+ {
234
+ "path": "workbench/i18n.mjs",
235
+ "sha256": "272917746c06cabc1b87b94341f2deca5591f0bea2d7a0e07b2d959d8e1f8c74"
236
+ },
237
+ {
238
+ "path": "workbench/loopback-surface.mjs",
239
+ "sha256": "6a550034c5dd558dfd22f9cb589fd76df40a99e976538e3b5d01371d212c9aa6"
240
+ },
241
+ {
242
+ "path": "workbench/mcp-app-bundle.mjs",
243
+ "sha256": "48fb8224cbaa7f78a386a79b2dba761f4de6c4b83b16032f7f96bd9783e172e4"
244
+ },
245
+ {
246
+ "path": "workbench/service.mjs",
247
+ "sha256": "3bf82a0076e9fe3b62105c626fe0d622092224f28d3905c62eafd65bf5385dcc"
248
+ },
249
+ {
250
+ "path": "workbench/state.mjs",
251
+ "sha256": "770d10f3bf76236772c87e86f5da346c013da387fb40c08360f895a7052cf7b5"
252
+ },
253
+ {
254
+ "path": "workbench/transports.mjs",
255
+ "sha256": "0c9f42ca9c9a4b4cc29b1bdcc0a0488d16a9ad06c235c642dff9cd4fc6f0d528"
256
+ },
257
+ {
258
+ "path": "workbench/ui/app.mjs",
259
+ "sha256": "643a5ac8d303f936ee87dd7c0c851aa1988e99ea9a9a45c6c89da28bdc76e799"
260
+ },
261
+ {
262
+ "path": "workbench/ui/connection-form.mjs",
263
+ "sha256": "700ca793f5eddca1dfea5f220c73732efc51ea4e1f8b8fc36da2bb67136240f0"
264
+ },
265
+ {
266
+ "path": "workbench/ui/http-transport.mjs",
267
+ "sha256": "b2fedbc2c34bcf065e0fc23c8c5fb37d358c03daa2c82ba46530b8dfb8fdc571"
268
+ },
269
+ {
270
+ "path": "workbench/ui/loopback-entry.mjs",
271
+ "sha256": "0e5e5d259ab6e2d8408c6d2e089551e6f279dcb1267e9db19f9d9dded0956fd4"
272
+ },
273
+ {
274
+ "path": "workbench/ui/mcp-app-client.mjs",
275
+ "sha256": "91b1e6e84a12434c2be7614845febfa44afa341d5d7f580bc1bfc106ed37f8f8"
276
+ },
277
+ {
278
+ "path": "workbench/ui/mcp-app-entry.mjs",
279
+ "sha256": "ba82ac55c4efcf7701bda33b6c6e0df4d59da542b1d6c33c96ba7f2391c4773a"
280
+ },
281
+ {
282
+ "path": "platform/windows/configure-agent.ps1",
283
+ "sha256": "7dc7c75bf0f7e45060b041a08d502993afe84581040f165e7f4437bf490708fa"
284
+ },
285
+ {
286
+ "path": "platform/windows/credential-store.ps1",
287
+ "sha256": "d00dae4af08205fffa52c4956d1c87d5c3423e8f20982ccfc1b76e3424fe442e"
288
+ },
289
+ {
290
+ "path": "platform/windows/hellolynk-host-protected-store.ps1",
291
+ "sha256": "24357e8ce54090b4ec68e457f02c9e834a80f3273ef3c03a8c0fa7258797fb49"
292
+ },
293
+ {
294
+ "path": "platform/windows/hellolynk-human-confirmation-ledger.ps1",
295
+ "sha256": "4612561e2128dfd96c018f2c2d9ae41016f35bb6df8536314e9f0fb428165a82"
296
+ },
297
+ {
298
+ "path": "platform/windows/hellolynk-local-data-key.ps1",
299
+ "sha256": "0976a0ecdd724e767b87e65743a230569c3fcb30e2449cf38bb718eb1604c15c"
300
+ },
301
+ {
302
+ "path": "platform/windows/hellolynk-native-human-confirmation-broker.ps1",
303
+ "sha256": "757a731a3e8761d5d473db19ecfc330783f2826663a0057c4d6896e679d7a388"
304
+ },
305
+ {
306
+ "path": "bootstrap/core/hellolynk-client-account.mjs",
307
+ "sha256": "ab7ec5dda92e510e7deb14f900fd2df4c6c3373fbeb4af4fb2b6c1a72aa41a99"
308
+ },
309
+ {
310
+ "path": "bootstrap/core/hellolynk-client-core.mjs",
311
+ "sha256": "94bbad1d0ccee969bbffed176449e427188f1b892512a64167ab31f63d258e2b"
312
+ },
313
+ {
314
+ "path": "bootstrap/core/hellolynk-client-profile.mjs",
315
+ "sha256": "4b45a78b4d6c4794a1f494bd95777579c32c56a68321a1d3b484048942ae4742"
316
+ },
317
+ {
318
+ "path": "bootstrap/core/hellolynk-host-auth.mjs",
319
+ "sha256": "db1ec56f4e60e6450fba50188eecf89748f39f5d7a75c2456c30a6053233555d"
320
+ },
321
+ {
322
+ "path": "bootstrap/core/hellolynk-host-protected-store.mjs",
323
+ "sha256": "89b6e6c4ce9c6ba2984f8c301de4251da6004bdd402cc44d578a4505c21b75b1"
324
+ },
325
+ {
326
+ "path": "bootstrap/core/hellolynk-local-process-lock.mjs",
327
+ "sha256": "5212990a98b9ad2eb83fa2d5fb8a123d687c5ef6daf6cba49a4b6d04a7fe251e"
328
+ },
329
+ {
330
+ "path": "bootstrap/core/hellolynk-neutral-host-installation-store.mjs",
331
+ "sha256": "b5f6288732af6f9b9c0c750f6002eae657dde9513fc97674f6e59200f3cc9dc6"
332
+ },
333
+ {
334
+ "path": "bootstrap/core/hellolynk-platform-credential-store.mjs",
335
+ "sha256": "f27f5f377cc4d6d2b5664212cf8fcc4c98d910064c1677ff9c1f776df1a59dba"
336
+ },
337
+ {
338
+ "path": "bootstrap/core/hellolynk-runtime-safety.cjs",
339
+ "sha256": "43d576d9f774409f4a735793c1503a6f397e787b10c59a4ac9cc9257299f5efe"
340
+ },
341
+ {
342
+ "path": "bootstrap/platform/windows/hellolynk-host-protected-store.ps1",
343
+ "sha256": "24357e8ce54090b4ec68e457f02c9e834a80f3273ef3c03a8c0fa7258797fb49"
344
+ },
345
+ {
346
+ "path": "release/server/codex-neutral-production.mjs",
347
+ "sha256": "34b865d80d7eb3c8e6986635b158c8583ddddb40bb528c4a75f0a498bdb3e1fb"
348
+ },
349
+ {
350
+ "path": "release/server/neutral-host-adapter.mjs",
351
+ "sha256": "19f81e47c58531cb0f043ffb1ef1cbfa316a59bf9949770eea33cfe83418bd51"
352
+ },
353
+ {
354
+ "path": "release/server/workbench-runtime.mjs",
355
+ "sha256": "1136c7ea50cc73065fe04094c5b5c19cb676c40a0a189979015766a9c4e908d8"
356
+ }
357
+ ]
358
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "contract": "hellolynk-neutral-host-release-pin-v1",
3
+ "manifestSha256": "98a0a761956020462c08bc6c02000b06fd37e0c2a5f44266ca5d4657c3ea28ce"
4
+ }