@hellolynk-ai/workbuddy-mcp 0.3.97 → 0.3.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.
@@ -61,8 +61,8 @@ try {
61
61
  "--expected-manifest-sha256", sourceRelease.outerManifestSha256,
62
62
  ]);
63
63
  } else {
64
- const originalLocations = resolveLocations();
65
64
  const accountModule = await importStableCore(PACKAGE_ROOT, "hellolynk-client-account.mjs", "hellolynk_npm_account_runtime_invalid");
65
+ const originalLocations = resolveLocations(accountModule.clientAccountBaseRoot);
66
66
  const baseRoot = accountModule.clientAccountBaseRoot(originalLocations.hostRoot);
67
67
  const packageLocations = { ...originalLocations, hostRoot: baseRoot, finalCurrentRoot: path.dirname(baseRoot) };
68
68
  const accounts = accountModule.createClientAccountActions({ client: metadata.client, storeRoot: baseRoot });
@@ -84,6 +84,13 @@ try {
84
84
  if (mutating) {
85
85
  await prepareFinalClientRoot(locations);
86
86
  installed = await installStablePackage({ packageClosure, sourceRelease, locations: packageLocations });
87
+ if (metadata.client === "codex") {
88
+ // The invoking updater can still be B255 code. Stop its old cleanup
89
+ // before switching the binding/cache to a release with process records.
90
+ const cleanup = await importStableCore(installed.packageRoot, "hellolynk-release-retention.mjs", "hellolynk_release_retention_unavailable");
91
+ await cleanup.protectRetentionReceipt({ releasesRoot: path.dirname(installed.packageRoot),
92
+ client: "codex", currentRelease: installed.packageRoot });
93
+ }
87
94
  }
88
95
  const activation = await inspectActivation(locations.hostRoot, metadata.profileId);
89
96
  // Both public install commands use the actual account state. Native recovery
@@ -831,7 +838,7 @@ async function verifyRelease(releaseRoot, packageRoot, expectedMetadata = metada
831
838
  return Object.freeze({ manifestSha256, outerManifestSha256 });
832
839
  }
833
840
 
834
- function resolveLocations() {
841
+ function resolveLocations(getDefaultHostRoot) {
835
842
  if (process.platform !== "win32") fail("hellolynk_npm_windows_only");
836
843
  const home = path.resolve(process.env.USERPROFILE || os.homedir());
837
844
  const localAppData = path.resolve(process.env.LOCALAPPDATA || path.join(home, "AppData", "Local"));
@@ -841,7 +848,7 @@ function resolveLocations() {
841
848
  const codexHome = path.resolve(configuredCodexHome || path.join(home, ".codex"));
842
849
  const configuredHostRoot = String(process.env.HELLOLYNK_NEUTRAL_STORE_ROOT || "").trim();
843
850
  if (configuredHostRoot && !path.isAbsolute(configuredHostRoot)) fail("hellolynk_npm_store_root_invalid");
844
- const hostRoot = path.resolve(configuredHostRoot || path.join(localAppData, "HelloLynk", "host"));
851
+ const hostRoot = path.resolve(configuredHostRoot || getDefaultHostRoot());
845
852
  if (configuredHostRoot && path.basename(hostRoot).toLowerCase() !== "host") {
846
853
  fail("hellolynk_npm_store_root_invalid");
847
854
  }
@@ -997,6 +1004,12 @@ async function startHostWhenAbsent(runtime, binding) {
997
1004
  }
998
1005
 
999
1006
  async function secureStableReleaseTree(locations, releaseId, options = {}) {
1007
+ const releasePath = path.resolve(locations.finalCurrentRoot, "releases", releaseId);
1008
+ // An existing AppData root can be shared while a new release is redirected
1009
+ // into one desktop app's private cache. Other clients cannot use that release.
1010
+ if (process.platform === "win32" && realpathSync.native(releasePath).toLowerCase() !== releasePath.toLowerCase()) {
1011
+ fail("client_root_alias_rejected");
1012
+ }
1000
1013
  const module = await importCore(
1001
1014
  "hellolynk-platform-credential-store.mjs",
1002
1015
  "hellolynk_npm_client_root_security_unavailable",
@@ -1,4 +1,5 @@
1
1
  import { lstat, mkdir, open, readFile, rename, rm, stat } from "node:fs/promises";
2
+ import { readdirSync } from "node:fs";
2
3
  import { homedir } from "node:os";
3
4
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
4
5
  import { randomUUID } from "node:crypto";
@@ -19,12 +20,34 @@ const SAFE_SCOPE = /^[a-z][a-z0-9_.:-]{0,127}$/;
19
20
  const MAX_PROFILE_BYTES = 64 * 1024;
20
21
 
21
22
  export function defaultHelloLynkClientRoot(platform = process.platform, env = process.env) {
22
- const home = resolve(String(env.HOME || env.USERPROFILE || homedir()));
23
- if (platform === "win32") return resolve(String(env.LOCALAPPDATA || join(home, "AppData", "Local")), "HelloLynk");
23
+ const home = resolve(String((platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME || env.USERPROFILE) || homedir()));
24
+ if (platform === "win32") {
25
+ const current = join(home, ".hellolynk", "hellolynk-v2");
26
+ // Once selected, another client's older installer must not move us back.
27
+ if (hasWindowsClientInstallation(current)) return current;
28
+ const existing = resolve(String(env.LOCALAPPDATA || join(home, "AppData", "Local")), "HelloLynk");
29
+ // AppData created from a packaged desktop app can be private to that app.
30
+ // Keep an existing installation; an empty failed setup is not an account.
31
+ if (hasWindowsClientInstallation(existing)) return existing;
32
+ return current;
33
+ }
24
34
  if (platform === "darwin") return join(home, "Library", "Application Support", "HelloLynk");
25
35
  return resolve(String(env.XDG_DATA_HOME || join(home, ".local", "share")), "hellolynk");
26
36
  }
27
37
 
38
+ function hasWindowsClientInstallation(root) {
39
+ for (const directory of ["profiles", "releases", "host", "credentials", "e2ee-private-keys"]) {
40
+ try {
41
+ const entries = readdirSync(join(root, directory), { withFileTypes: true });
42
+ if (entries.some((entry) => directory !== "host" || entry.name !== "runtime")) return true;
43
+ } catch (error) {
44
+ // An unreadable existing location must not silently become a fresh account.
45
+ if (error.code !== "ENOENT") return true;
46
+ }
47
+ }
48
+ return false;
49
+ }
50
+
28
51
  function safeId(value, code) {
29
52
  const normalized = String(value || "").trim();
30
53
  if (!SAFE_ID.test(normalized)) throw new Error(code);
@@ -18,7 +18,7 @@ const conversationGuidance = "HelloLynk 是本人授权的 AI 通讯。接着已
18
18
  // What every client shows for the shared tools; nativeTool applies it.
19
19
  const toolText = Object.freeze({
20
20
  hellolynk_reply_authorized_message: { title: "回复来信", description: "接着当前对话的一封来信发送;不接手其他对话。" },
21
- hellolynk_send_authorized_message: { title: "发起通信", description: "向本人授权的联系人发起新通信。contact 填对方名字;本人点名了对话时,targetConversationTitle 填完整标题。接着已有来往用 hellolynk_reply_authorized_message。" },
21
+ hellolynk_send_authorized_message: { title: "发起通信", description: "向本人授权的联系人发起新通信。contact 填对方名字;本人点名了对话时,targetConversationTitle 填完整标题。未指定对话的新通信默认送到对方的 HelloLynk 独立会话;要继续已有来往,用 hellolynk_reply_authorized_message 回复原信。" },
22
22
  hellolynk_list_authorized_contacts: { title: "查找联系人", description: queryDescription },
23
23
  hellolynk_claim_message: { title: "读取来信", description: "按自动提醒里的 batchId 一次读取整批来信(合计不超过 2 万字);手动读单条传 localMessageId 和 conversationKey。" },
24
24
  hellolynk_list_pending_messages: { title: "待处理来信", description: "列出当前对话等待 AI 处理的来信,不含正文。" },
@@ -12,10 +12,9 @@ import {
12
12
  } from "node:fs/promises";
13
13
  import { basename, dirname, isAbsolute, join, parse, resolve } from "node:path";
14
14
  import { spawn } from "node:child_process";
15
- import { homedir } from "node:os";
16
15
  import { performance } from "node:perf_hooks";
17
16
  import { withLocalProcessLock } from "./hellolynk-local-process-lock.mjs";
18
- import { readClientProfile } from "./hellolynk-client-profile.mjs";
17
+ import { defaultHelloLynkClientRoot, readClientProfile } from "./hellolynk-client-profile.mjs";
19
18
  import { assertIdentifier } from "./hellolynk-host-auth.mjs";
20
19
  import runtimeSafety from "./hellolynk-runtime-safety.cjs";
21
20
 
@@ -46,10 +45,7 @@ export function defaultNeutralHostStoreRoot(platform = process.platform, env = p
46
45
  }
47
46
  return root;
48
47
  }
49
- const home = resolve(String(env.HOME || env.USERPROFILE || homedir()));
50
- if (platform === "win32") return resolve(String(env.LOCALAPPDATA || join(home, "AppData", "Local")), "HelloLynk", "host");
51
- if (platform === "darwin") return join(home, "Library", "Application Support", "HelloLynk", "host");
52
- return resolve(String(env.XDG_DATA_HOME || join(home, ".local", "share")), "hellolynk", "host");
48
+ return join(defaultHelloLynkClientRoot(platform, env), "host");
53
49
  }
54
50
 
55
51
  export function createNeutralHostInstallationStore(options = {}) {
@@ -34,7 +34,7 @@ export const HELLOLYNK_NEUTRAL_HOST_PROCESS_CONTRACT = "hellolynk-neutral-host-p
34
34
  export const HELLOLYNK_NEUTRAL_HOST_DISCOVERY_CONTRACT = "hellolynk-neutral-host-discovery-v1";
35
35
  // Raised with every release batch, together with the six client versions. A Host reports it
36
36
  // in its health; the higher release stays and the lower one makes room.
37
- export const HELLOLYNK_HOST_RELEASE_ORDINAL = 13;
37
+ export const HELLOLYNK_HOST_RELEASE_ORDINAL = 15;
38
38
 
39
39
  const INSTALLATION_LOCK_CONTRACT = "hellolynk-neutral-host-installation-lock-v2";
40
40
  const INSTALLATION_LOCK_MAX_BYTES = 4 * 1024;
@@ -15,12 +15,29 @@ const contract = 'hellolynk-release-retention-v1';
15
15
  // receipt: an older worker that cleans up after an update deletes nothing.
16
16
  const ENTRY = { 'claude-code': ['claude-code', 'hellolynk-claude-code.mjs'] };
17
17
  const contractWithEntry = 'hellolynk-release-retention-v2';
18
+ // B255 workers understand v2 but do not read Codex process records.
19
+ const codexContract = 'hellolynk-release-retention-v3';
18
20
  const PROCESS_CONTRACT = 'hellolynk-release-process-v1';
19
21
  const START_TOLERANCE_MS = 15000;
20
22
  export const releaseProcessDirectory = (releasesRoot, client) => path.join(releasesRoot, `.${client}-processes`);
21
23
  const failure = code => Object.assign(new Error(code), { code });
22
24
  const equal = (a, b) => process.platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b;
23
25
 
26
+ // A cache MCP keeps an installed prepare function in memory. Record its most
27
+ // recent successful binding, even when its command line names only the cache.
28
+ // A checkout/uninstalled fixture has no immutable release to retain.
29
+ export async function recordCodexReleaseProcess(packageRoot) {
30
+ if (process.platform !== 'win32' || !path.isAbsolute(packageRoot || '')
31
+ || path.basename(path.dirname(packageRoot)) !== 'releases' || !/^codex-[a-f0-9]{64}$/.test(path.basename(packageRoot))) return;
32
+ try {
33
+ const root = await rootPath(path.dirname(packageRoot));
34
+ const folder = releaseProcessDirectory(root, 'codex');
35
+ await fs.mkdir(folder, { recursive: true });
36
+ await writeReceipt(path.join(folder, `${process.pid}.json`), { contract: PROCESS_CONTRACT, pid: process.pid,
37
+ startedAt: Math.round(performance.timeOrigin), release: path.basename(packageRoot) });
38
+ } catch { /* A missing record defers cleanup; it must not stop communication. */ }
39
+ }
40
+
24
41
  async function directory(target) {
25
42
  const stat = await fs.lstat(target);
26
43
  if (!stat.isDirectory() || stat.isSymbolicLink()) throw failure('release_retention_path_invalid');
@@ -67,20 +84,25 @@ export async function runningReleaseNames(releasesRoot) {
67
84
  return names;
68
85
  }
69
86
 
70
- // The given pids and every process whose command line runs this installation's
71
- // stable entry: pid, start time and whether it runs the entry. Only processes
87
+ // The given pids, this installation's stable entry, and Codex cache children:
88
+ // pid, start time and whether it runs the entry. Only processes
72
89
  // with a positive pid are listed, and command lines never leave PowerShell.
73
90
  export async function entryProcessList(client, releasesRoot, pids = []) {
74
- if (!ENTRY[client]) return [];
91
+ if (!ENTRY[client] && client !== 'codex') return [];
75
92
  if (process.platform !== 'win32') throw failure('release_retention_process_check_unavailable');
76
93
  if (!Array.isArray(pids) || pids.some(pid => !Number.isSafeInteger(pid) || pid <= 0)) throw failure('release_retention_process_check_invalid');
77
94
  const root = await rootPath(releasesRoot);
78
95
  // This installation's entry only, in its given and canonical spellings:
79
96
  // any case, either slash, quoted or not.
80
97
  const literal = value => value.split(/[\\/]+/).map(part => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('[\\\\/]+');
81
- const entries = [...new Set([root, path.resolve(releasesRoot)])].map(value => literal(path.join(path.dirname(value), ...ENTRY[client])));
82
- const pattern = `(?<=^|["\\s])(?:${entries.join('|')})(?=["\\s]|$)`.replaceAll("'", "''");
83
- const script = `$ErrorActionPreference='Stop'; $wanted=@(${pids.join(',')}); $epoch=[datetime]::new(1970,1,1,0,0,0,[DateTimeKind]::Utc); $list=@(Get-CimInstance Win32_Process | Where-Object { $_.ProcessId -gt 0 } | ForEach-Object { $entry=[bool]($_.CommandLine -and [regex]::IsMatch($_.CommandLine,'${pattern}','IgnoreCase')); if ($entry -or ($wanted -contains [int64]$_.ProcessId)) { [pscustomobject]@{ pid=[int64]$_.ProcessId; startedAt=$(if ($_.CreationDate) { [int64](($_.CreationDate.ToUniversalTime() - $epoch).TotalMilliseconds) } else { $null }); entry=$entry } } }); ConvertTo-Json -Compress -InputObject $list`;
98
+ const entries = ENTRY[client] ? [...new Set([root, path.resolve(releasesRoot)])].map(value => literal(path.join(path.dirname(value), ...ENTRY[client]))) : [];
99
+ const pattern = (client === 'codex' ? '(?:^|["\\s\\\\/])(?:\\.[\\\\/])?server[\\\\/]mcp-proxy\\.mjs(?=["\\s]|$)'
100
+ : `(?<=^|["\\s])(?:${entries.join('|')})(?=["\\s]|$)`).replaceAll("'", "''");
101
+ // Relative cache entries do not reveal their installation. An older Codex
102
+ // child without a record conservatively delays this client's cleanup until
103
+ // it reconnects through a recording release or exits. Other Node apps do not.
104
+ const parentCheck = client === 'codex' ? "$_.Name -ieq 'node.exe' -and ($codexParents -contains $_.ParentProcessId) -and " : '';
105
+ const script = `$ErrorActionPreference='Stop'; $wanted=@(${pids.join(',')}); $epoch=[datetime]::new(1970,1,1,0,0,0,[DateTimeKind]::Utc); $all=@(Get-CimInstance Win32_Process); $codexParents=@($all | Where-Object { $_.Name -ieq 'Codex.exe' } | ForEach-Object { $_.ProcessId }); $list=@($all | Where-Object { $_.ProcessId -gt 0 } | ForEach-Object { $entry=[bool](${parentCheck}$_.CommandLine -and [regex]::IsMatch($_.CommandLine,'${pattern}','IgnoreCase')); if ($entry -or ($wanted -contains [int64]$_.ProcessId)) { [pscustomobject]@{ pid=[int64]$_.ProcessId; startedAt=$(if ($_.CreationDate) { [int64](($_.CreationDate.ToUniversalTime() - $epoch).TotalMilliseconds) } else { $null }); entry=$entry } } }); ConvertTo-Json -Compress -InputObject $list`;
84
106
  const shell = path.join(process.env.SystemRoot || process.env.SYSTEMROOT || 'C:\\Windows', 'System32/WindowsPowerShell/v1.0/powershell.exe');
85
107
  const { stdout } = await execute(shell, ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', script],
86
108
  { windowsHide: true, timeout: 15000, maxBuffer: 1024 * 1024 });
@@ -95,7 +117,7 @@ export async function entryProcessList(client, releasesRoot, pids = []) {
95
117
  // Records of exited or reused pids are removed, so a release can go at the
96
118
  // next install once its last process is gone.
97
119
  async function entryReleases(releasesRoot, root, client, pattern, dependencies) {
98
- if (!ENTRY[client]) return { names: [], unregistered: false };
120
+ if (!ENTRY[client] && client !== 'codex') return { names: [], unregistered: false };
99
121
  const folder = releaseProcessDirectory(root, client);
100
122
  let items = [];
101
123
  try {
@@ -179,21 +201,20 @@ export async function pruneInstalledReleases({ releasesRoot, client, currentRele
179
201
  return result;
180
202
  }
181
203
 
182
- // A stable-entry client calls this before it switches an install on its stable
183
- // entry. An update worker of an earlier release cleans up after that install with
184
- // its own code, which cannot see what a stable-entry process runs and stops
185
- // before deleting only at a receipt other than v1. Resolves once the receipt is
186
- // v2, keeping the adoption it records, with whether it wrote. Throws when that
204
+ // Call before switching the binding/entry. An earlier updater cleans up after
205
+ // setup with its own code. Claude needs v2 to stop pre-B255 workers; Codex needs
206
+ // v3 to stop B255 workers that know only Claude records. Preserve the recorded
207
+ // adoption order and resolve with whether the receipt changed. Throw when that
187
208
  // cannot be confirmed, even for a cause that passes before the worker reads the
188
209
  // receipt (a file another process holds open): the caller then switches nothing.
189
210
  // currentRelease, the release the install starts now, is recorded only when
190
211
  // there is no receipt yet.
191
212
  export async function protectRetentionReceipt({ releasesRoot, client, currentRelease }) {
192
- if (!ENTRY[client]) throw failure('release_retention_client_invalid');
213
+ if (!ENTRY[client] && client !== 'codex') throw failure('release_retention_client_invalid');
193
214
  const root = await rootPath(releasesRoot), pattern = new RegExp(`^${client}-[a-f0-9]{64}$`);
194
215
  const receiptPath = path.join(root, `.${client}-retention.json`);
195
216
  const old = await readReceipt(receiptPath, client, pattern);
196
- if (old?.contract === contractWithEntry) return false;
217
+ if (old?.contract === receiptContract(client)) return false;
197
218
  let current = old?.current;
198
219
  if (!current) {
199
220
  if (typeof currentRelease !== 'string' || !path.isAbsolute(currentRelease) || !pattern.test(path.basename(currentRelease))
@@ -201,11 +222,11 @@ export async function protectRetentionReceipt({ releasesRoot, client, currentRel
201
222
  current = path.basename(currentRelease);
202
223
  await directory(path.join(root, current));
203
224
  }
204
- await writeReceipt(receiptPath, { contract: contractWithEntry, client, current, previous: old ? old.previous : null });
225
+ await writeReceipt(receiptPath, { contract: receiptContract(client), client, current, previous: old ? old.previous : null });
205
226
  return true;
206
227
  }
207
228
 
208
- const receiptContract = client => ENTRY[client] ? contractWithEntry : contract;
229
+ const receiptContract = client => client === 'codex' ? codexContract : ENTRY[client] ? contractWithEntry : contract;
209
230
 
210
231
  async function readReceipt(receiptPath, client, pattern) {
211
232
  let old = null;
@@ -213,7 +234,7 @@ async function readReceipt(receiptPath, client, pattern) {
213
234
  const stat = await fs.lstat(receiptPath);
214
235
  if (!stat.isFile() || stat.isSymbolicLink() || stat.nlink !== 1 || stat.size > 4096) throw failure('release_retention_receipt_invalid');
215
236
  old = JSON.parse(await fs.readFile(receiptPath, 'utf8'));
216
- if (![contract, contractWithEntry].includes(old?.contract) || old.client !== client || !pattern.test(old.current)
237
+ if (![contract, contractWithEntry, ...(client === 'codex' ? [codexContract] : [])].includes(old?.contract) || old.client !== client || !pattern.test(old.current)
217
238
  || old.previous !== null && !pattern.test(old.previous) || old.current === old.previous) throw failure('release_retention_receipt_invalid');
218
239
  } catch (error) {
219
240
  if (error.code === 'ENOENT') return null;
@@ -245,7 +266,7 @@ export async function removeInstalledReleases({ releasesRoot, client }, dependen
245
266
  if (!result.deferred.length) {
246
267
  await fs.rm(path.join(root, `.${client}-retention.json`), { force: true });
247
268
  // entryReleases checked above that this is a folder in the releases root.
248
- if (ENTRY[client]) await fs.rm(releaseProcessDirectory(root, client), { recursive: true, force: true });
269
+ if (ENTRY[client] || client === 'codex') await fs.rm(releaseProcessDirectory(root, client), { recursive: true, force: true });
249
270
  }
250
271
  result.complete = result.deferred.length === 0;
251
272
  } catch (error) { result.error = safeCode(error); }
@@ -2,7 +2,7 @@
2
2
  "contract": "hellolynk-client-npm-pack-manifest-v1",
3
3
  "client": "workbuddy",
4
4
  "packageName": "@hellolynk-ai/workbuddy-mcp",
5
- "version": "0.3.97",
5
+ "version": "0.3.99",
6
6
  "workbench": {
7
7
  "path": "runtime/workbench/hellolynk-workbench-build.json",
8
8
  "contract": "hellolynk-shared-workbench-build-v1",
@@ -12,8 +12,8 @@
12
12
  "files": [
13
13
  {
14
14
  "path": "bin/hellolynk-client-setup.mjs",
15
- "bytes": 141259,
16
- "sha256": "ab6ce9491d9b88856fdc0207b0df3230ed27642d9d206f52341a4f9791622a4e"
15
+ "bytes": 142207,
16
+ "sha256": "95386fcd9092f31abb3b0441033b3b385b3c355506613da24b4557d5f9cac6ef"
17
17
  },
18
18
  {
19
19
  "path": "bin/hellolynk-mcp-config-shape.mjs",
@@ -32,8 +32,8 @@
32
32
  },
33
33
  {
34
34
  "path": "clients/core/hellolynk-client-profile.mjs",
35
- "bytes": 8473,
36
- "sha256": "81d4f64c11c8dbccec04a05435cc42b53823db2649f2c88739647299b3c97fd2"
35
+ "bytes": 9573,
36
+ "sha256": "4528f2eb90417dbe232c4fef254beeb20c94f9216388ec721f982dd7ee4adde5"
37
37
  },
38
38
  {
39
39
  "path": "clients/core/hellolynk-client-update-entry.mjs",
@@ -167,8 +167,8 @@
167
167
  },
168
168
  {
169
169
  "path": "clients/core/hellolynk-native-addressing-tools.cjs",
170
- "bytes": 19581,
171
- "sha256": "e583c769b72d8cf52523c19b3320c982c2550f002041770f5953f16951690162"
170
+ "bytes": 19674,
171
+ "sha256": "cce89fa33dbe630a78d77843919a8e4b0c12f3482e754f783e6ff038b81929c4"
172
172
  },
173
173
  {
174
174
  "path": "clients/core/hellolynk-native-conversations.mjs",
@@ -212,8 +212,8 @@
212
212
  },
213
213
  {
214
214
  "path": "clients/core/hellolynk-neutral-host-installation-store.mjs",
215
- "bytes": 34290,
216
- "sha256": "9ff399639d320e5527e51cd0ddbf049e7e0e8d3cc225cdc30f0d4637356a1590"
215
+ "bytes": 33944,
216
+ "sha256": "7b8d62ce31f47ad08f2cf50b48f3bb66cfb9c4957942184abb6d04f437b1e4a0"
217
217
  },
218
218
  {
219
219
  "path": "clients/core/hellolynk-neutral-host-launcher.mjs",
@@ -223,7 +223,7 @@
223
223
  {
224
224
  "path": "clients/core/hellolynk-neutral-host-process.mjs",
225
225
  "bytes": 229535,
226
- "sha256": "75076c91d2240ed749969997b6fc8f0f252e938ab33412904031c9298ee831f7"
226
+ "sha256": "2aaf2b604f896de0d171b20590954c8da0a4c29b2eced508b4aa0a27927b40d5"
227
227
  },
228
228
  {
229
229
  "path": "clients/core/hellolynk-neutral-host-store-adapters.mjs",
@@ -247,8 +247,8 @@
247
247
  },
248
248
  {
249
249
  "path": "clients/core/hellolynk-release-retention.mjs",
250
- "bytes": 19099,
251
- "sha256": "679bd875f8952a5070455d7219926cf95117c7589b8abdf1d79eabf6917b5530"
250
+ "bytes": 20922,
251
+ "sha256": "9f8b5b97eee7530dc8ef965b0df6a19065b06012255100977d8abb17ce50d204"
252
252
  },
253
253
  {
254
254
  "path": "clients/core/hellolynk-runtime-safety.cjs",
@@ -303,7 +303,7 @@
303
303
  {
304
304
  "path": "integrations/workbuddy/package.json",
305
305
  "bytes": 1124,
306
- "sha256": "94dd6849e56be0342485fcee3a1ac6e63ed9efdac97f5c64fa4b38d80cda3d3b"
306
+ "sha256": "646b5125edbb5b195b7c30deca6929f01adba997f0081dae4122f51991bf0aac"
307
307
  },
308
308
  {
309
309
  "path": "integrations/workbuddy/server/host-lifecycle.mjs",
@@ -413,7 +413,7 @@
413
413
  {
414
414
  "path": "package.json",
415
415
  "bytes": 2018,
416
- "sha256": "a7deda81be6fae750d06de8da0d35e86b493d638b5718af4b984c13db64c7133"
416
+ "sha256": "f970020e4fb9ba78788bb46f1e186a164fa4f65bee83407e13e06da0d4a54c54"
417
417
  },
418
418
  {
419
419
  "path": "README.md",
@@ -442,8 +442,8 @@
442
442
  },
443
443
  {
444
444
  "path": "runtime/core/hellolynk-client-profile.mjs",
445
- "bytes": 8282,
446
- "sha256": "4b45a78b4d6c4794a1f494bd95777579c32c56a68321a1d3b484048942ae4742"
445
+ "bytes": 9359,
446
+ "sha256": "8be37831c96610e3d0a64848ada86488970cc6079e49764b47d8a8b2ba852269"
447
447
  },
448
448
  {
449
449
  "path": "runtime/core/hellolynk-client-update-entry.mjs",
@@ -577,8 +577,8 @@
577
577
  },
578
578
  {
579
579
  "path": "runtime/core/hellolynk-native-addressing-tools.cjs",
580
- "bytes": 19350,
581
- "sha256": "252251de855c3fe9c5ebdd54a97ba976a8009f4ac57ec44f492bed8c7fb903de"
580
+ "bytes": 19443,
581
+ "sha256": "f4bd81b3d03277e28955a62409383a0c4072c6212567f71425df4e18ece75d63"
582
582
  },
583
583
  {
584
584
  "path": "runtime/core/hellolynk-native-conversations.mjs",
@@ -617,8 +617,8 @@
617
617
  },
618
618
  {
619
619
  "path": "runtime/core/hellolynk-neutral-host-installation-store.mjs",
620
- "bytes": 33525,
621
- "sha256": "b5f6288732af6f9b9c0c750f6002eae657dde9513fc97674f6e59200f3cc9dc6"
620
+ "bytes": 33183,
621
+ "sha256": "dfb6bba4c627082cd6fca8cb38dc786f905e38f3e83ccf91dbfe57e55639e8a2"
622
622
  },
623
623
  {
624
624
  "path": "runtime/core/hellolynk-neutral-host-launcher.mjs",
@@ -628,7 +628,7 @@
628
628
  {
629
629
  "path": "runtime/core/hellolynk-neutral-host-process.mjs",
630
630
  "bytes": 225161,
631
- "sha256": "48f9bd6451adafdf3b43591a3b1469e36174c30fe04214cd2a84fb0aeebea023"
631
+ "sha256": "e744bacf65f7b86cbcf7d654189c0e07e09401083e2b6f9053b17c1c3bacd1b4"
632
632
  },
633
633
  {
634
634
  "path": "runtime/core/hellolynk-neutral-host-store-adapters.mjs",
@@ -652,8 +652,8 @@
652
652
  },
653
653
  {
654
654
  "path": "runtime/core/hellolynk-release-retention.mjs",
655
- "bytes": 18822,
656
- "sha256": "4ba5607e92f98a9a33b9ffd9ad166e559bc3197fcb1a6d54cef96b2b91ddc38e"
655
+ "bytes": 20624,
656
+ "sha256": "9b02a42a510fa5ef4a251b6e675f9ccc60f20b718d17c1617027cd048c5634dd"
657
657
  },
658
658
  {
659
659
  "path": "runtime/core/hellolynk-runtime-safety.cjs",
@@ -688,12 +688,12 @@
688
688
  {
689
689
  "path": "runtime/neutral-host-release-manifest.json",
690
690
  "bytes": 11228,
691
- "sha256": "a90945fc34ec9cd8bccfdc39193084515f432aa84980f927a475841a6cdb34b2"
691
+ "sha256": "379a5532724e4935decd6ffbd7bc6b52cc927c1f910decc406394d9601b55ba3"
692
692
  },
693
693
  {
694
694
  "path": "runtime/neutral-host-release-pin.json",
695
695
  "bytes": 146,
696
- "sha256": "1e8e8e153126b9a9d38412a36bba7eda55a9d68d5f58cd7e2fa43633913580ce"
696
+ "sha256": "8e5b0243291a35d03f82c340be87f91dbf4d6344aaedce5fa529caa32911a8ca"
697
697
  },
698
698
  {
699
699
  "path": "runtime/platform/windows/configure-agent.ps1",
@@ -873,12 +873,12 @@
873
873
  {
874
874
  "path": "workbuddy-package-manifest.json",
875
875
  "bytes": 22134,
876
- "sha256": "5ec9f5e9ee1c7f44b58e465029b1146918892d71792a62629b83adcccc2d3bcc"
876
+ "sha256": "089faf1216ca42ffad28595e9a4f26bb9df08acbebecc60e61f59e1466b384c7"
877
877
  },
878
878
  {
879
879
  "path": "workbuddy-package-pin.json",
880
880
  "bytes": 143,
881
- "sha256": "f1799d502d498ff3cdd5ab1b1f226e6d478dee786b23c98e312b18ef821fc354"
881
+ "sha256": "013367d517bb4f03d0b9823924d415fe5ad054cb03d5c426012fb7c76bfdbfb7"
882
882
  }
883
883
  ]
884
884
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "contract": "hellolynk-client-npm-pack-pin-v1",
3
- "manifestSha256": "ec5f18618a17fe5c1a07de4f2a01ab3b9d195ff3ebab4a2ac789da0e7c234ca8"
3
+ "manifestSha256": "02bc5eaa65027ce0b39b68f9c4108d35177c1650174cc9da3cc7c0894663e613"
4
4
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hellolynk-ai/workbuddy-mcp",
3
- "version": "0.3.97",
3
+ "version": "0.3.99",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "WorkBuddy one-click bridge for local HelloLynk Messaging.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hellolynk-ai/workbuddy-mcp",
3
- "version": "0.3.97",
3
+ "version": "0.3.99",
4
4
  "description": "HelloLynk Messaging for WorkBuddy: open conversations and let your AI message other people's AI assistants.",
5
5
  "homepage": "https://hellolynk.com",
6
6
  "repository": {
@@ -1,4 +1,5 @@
1
1
  import { lstat, mkdir, open, readFile, rename, rm, stat } from "node:fs/promises";
2
+ import { readdirSync } from "node:fs";
2
3
  import { homedir } from "node:os";
3
4
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
4
5
  import { randomUUID } from "node:crypto";
@@ -19,12 +20,34 @@ const SAFE_SCOPE = /^[a-z][a-z0-9_.:-]{0,127}$/;
19
20
  const MAX_PROFILE_BYTES = 64 * 1024;
20
21
 
21
22
  export function defaultHelloLynkClientRoot(platform = process.platform, env = process.env) {
22
- const home = resolve(String(env.HOME || env.USERPROFILE || homedir()));
23
- if (platform === "win32") return resolve(String(env.LOCALAPPDATA || join(home, "AppData", "Local")), "HelloLynk");
23
+ const home = resolve(String((platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME || env.USERPROFILE) || homedir()));
24
+ if (platform === "win32") {
25
+ const current = join(home, ".hellolynk", "hellolynk-v2");
26
+ // Once selected, another client's older installer must not move us back.
27
+ if (hasWindowsClientInstallation(current)) return current;
28
+ const existing = resolve(String(env.LOCALAPPDATA || join(home, "AppData", "Local")), "HelloLynk");
29
+ // AppData created from a packaged desktop app can be private to that app.
30
+ // Keep an existing installation; an empty failed setup is not an account.
31
+ if (hasWindowsClientInstallation(existing)) return existing;
32
+ return current;
33
+ }
24
34
  if (platform === "darwin") return join(home, "Library", "Application Support", "HelloLynk");
25
35
  return resolve(String(env.XDG_DATA_HOME || join(home, ".local", "share")), "hellolynk");
26
36
  }
27
37
 
38
+ function hasWindowsClientInstallation(root) {
39
+ for (const directory of ["profiles", "releases", "host", "credentials", "e2ee-private-keys"]) {
40
+ try {
41
+ const entries = readdirSync(join(root, directory), { withFileTypes: true });
42
+ if (entries.some((entry) => directory !== "host" || entry.name !== "runtime")) return true;
43
+ } catch (error) {
44
+ // An unreadable existing location must not silently become a fresh account.
45
+ if (error.code !== "ENOENT") return true;
46
+ }
47
+ }
48
+ return false;
49
+ }
50
+
28
51
  function safeId(value, code) {
29
52
  const normalized = String(value || "").trim();
30
53
  if (!SAFE_ID.test(normalized)) throw new Error(code);
@@ -18,7 +18,7 @@ const conversationGuidance = "HelloLynk 是本人授权的 AI 通讯。接着已
18
18
  // What every client shows for the shared tools; nativeTool applies it.
19
19
  const toolText = Object.freeze({
20
20
  hellolynk_reply_authorized_message: { title: "回复来信", description: "接着当前对话的一封来信发送;不接手其他对话。" },
21
- hellolynk_send_authorized_message: { title: "发起通信", description: "向本人授权的联系人发起新通信。contact 填对方名字;本人点名了对话时,targetConversationTitle 填完整标题。接着已有来往用 hellolynk_reply_authorized_message。" },
21
+ hellolynk_send_authorized_message: { title: "发起通信", description: "向本人授权的联系人发起新通信。contact 填对方名字;本人点名了对话时,targetConversationTitle 填完整标题。未指定对话的新通信默认送到对方的 HelloLynk 独立会话;要继续已有来往,用 hellolynk_reply_authorized_message 回复原信。" },
22
22
  hellolynk_list_authorized_contacts: { title: "查找联系人", description: queryDescription },
23
23
  hellolynk_claim_message: { title: "读取来信", description: "按自动提醒里的 batchId 一次读取整批来信(合计不超过 2 万字);手动读单条传 localMessageId 和 conversationKey。" },
24
24
  hellolynk_list_pending_messages: { title: "待处理来信", description: "列出当前对话等待 AI 处理的来信,不含正文。" },
@@ -12,10 +12,9 @@ import {
12
12
  } from "node:fs/promises";
13
13
  import { basename, dirname, isAbsolute, join, parse, resolve } from "node:path";
14
14
  import { spawn } from "node:child_process";
15
- import { homedir } from "node:os";
16
15
  import { performance } from "node:perf_hooks";
17
16
  import { withLocalProcessLock } from "./hellolynk-local-process-lock.mjs";
18
- import { readClientProfile } from "./hellolynk-client-profile.mjs";
17
+ import { defaultHelloLynkClientRoot, readClientProfile } from "./hellolynk-client-profile.mjs";
19
18
  import { assertIdentifier } from "./hellolynk-host-auth.mjs";
20
19
  import runtimeSafety from "./hellolynk-runtime-safety.cjs";
21
20
 
@@ -46,10 +45,7 @@ export function defaultNeutralHostStoreRoot(platform = process.platform, env = p
46
45
  }
47
46
  return root;
48
47
  }
49
- const home = resolve(String(env.HOME || env.USERPROFILE || homedir()));
50
- if (platform === "win32") return resolve(String(env.LOCALAPPDATA || join(home, "AppData", "Local")), "HelloLynk", "host");
51
- if (platform === "darwin") return join(home, "Library", "Application Support", "HelloLynk", "host");
52
- return resolve(String(env.XDG_DATA_HOME || join(home, ".local", "share")), "hellolynk", "host");
48
+ return join(defaultHelloLynkClientRoot(platform, env), "host");
53
49
  }
54
50
 
55
51
  export function createNeutralHostInstallationStore(options = {}) {
@@ -34,7 +34,7 @@ export const HELLOLYNK_NEUTRAL_HOST_PROCESS_CONTRACT = "hellolynk-neutral-host-p
34
34
  export const HELLOLYNK_NEUTRAL_HOST_DISCOVERY_CONTRACT = "hellolynk-neutral-host-discovery-v1";
35
35
  // Raised with every release batch, together with the six client versions. A Host reports it
36
36
  // in its health; the higher release stays and the lower one makes room.
37
- export const HELLOLYNK_HOST_RELEASE_ORDINAL = 13;
37
+ export const HELLOLYNK_HOST_RELEASE_ORDINAL = 15;
38
38
 
39
39
  const INSTALLATION_LOCK_CONTRACT = "hellolynk-neutral-host-installation-lock-v2";
40
40
  const INSTALLATION_LOCK_MAX_BYTES = 4 * 1024;
@@ -15,12 +15,29 @@ const contract = 'hellolynk-release-retention-v1';
15
15
  // receipt: an older worker that cleans up after an update deletes nothing.
16
16
  const ENTRY = { 'claude-code': ['claude-code', 'hellolynk-claude-code.mjs'] };
17
17
  const contractWithEntry = 'hellolynk-release-retention-v2';
18
+ // B255 workers understand v2 but do not read Codex process records.
19
+ const codexContract = 'hellolynk-release-retention-v3';
18
20
  const PROCESS_CONTRACT = 'hellolynk-release-process-v1';
19
21
  const START_TOLERANCE_MS = 15000;
20
22
  export const releaseProcessDirectory = (releasesRoot, client) => path.join(releasesRoot, `.${client}-processes`);
21
23
  const failure = code => Object.assign(new Error(code), { code });
22
24
  const equal = (a, b) => process.platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b;
23
25
 
26
+ // A cache MCP keeps an installed prepare function in memory. Record its most
27
+ // recent successful binding, even when its command line names only the cache.
28
+ // A checkout/uninstalled fixture has no immutable release to retain.
29
+ export async function recordCodexReleaseProcess(packageRoot) {
30
+ if (process.platform !== 'win32' || !path.isAbsolute(packageRoot || '')
31
+ || path.basename(path.dirname(packageRoot)) !== 'releases' || !/^codex-[a-f0-9]{64}$/.test(path.basename(packageRoot))) return;
32
+ try {
33
+ const root = await rootPath(path.dirname(packageRoot));
34
+ const folder = releaseProcessDirectory(root, 'codex');
35
+ await fs.mkdir(folder, { recursive: true });
36
+ await writeReceipt(path.join(folder, `${process.pid}.json`), { contract: PROCESS_CONTRACT, pid: process.pid,
37
+ startedAt: Math.round(performance.timeOrigin), release: path.basename(packageRoot) });
38
+ } catch { /* A missing record defers cleanup; it must not stop communication. */ }
39
+ }
40
+
24
41
  async function directory(target) {
25
42
  const stat = await fs.lstat(target);
26
43
  if (!stat.isDirectory() || stat.isSymbolicLink()) throw failure('release_retention_path_invalid');
@@ -67,20 +84,25 @@ export async function runningReleaseNames(releasesRoot) {
67
84
  return names;
68
85
  }
69
86
 
70
- // The given pids and every process whose command line runs this installation's
71
- // stable entry: pid, start time and whether it runs the entry. Only processes
87
+ // The given pids, this installation's stable entry, and Codex cache children:
88
+ // pid, start time and whether it runs the entry. Only processes
72
89
  // with a positive pid are listed, and command lines never leave PowerShell.
73
90
  export async function entryProcessList(client, releasesRoot, pids = []) {
74
- if (!ENTRY[client]) return [];
91
+ if (!ENTRY[client] && client !== 'codex') return [];
75
92
  if (process.platform !== 'win32') throw failure('release_retention_process_check_unavailable');
76
93
  if (!Array.isArray(pids) || pids.some(pid => !Number.isSafeInteger(pid) || pid <= 0)) throw failure('release_retention_process_check_invalid');
77
94
  const root = await rootPath(releasesRoot);
78
95
  // This installation's entry only, in its given and canonical spellings:
79
96
  // any case, either slash, quoted or not.
80
97
  const literal = value => value.split(/[\\/]+/).map(part => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('[\\\\/]+');
81
- const entries = [...new Set([root, path.resolve(releasesRoot)])].map(value => literal(path.join(path.dirname(value), ...ENTRY[client])));
82
- const pattern = `(?<=^|["\\s])(?:${entries.join('|')})(?=["\\s]|$)`.replaceAll("'", "''");
83
- const script = `$ErrorActionPreference='Stop'; $wanted=@(${pids.join(',')}); $epoch=[datetime]::new(1970,1,1,0,0,0,[DateTimeKind]::Utc); $list=@(Get-CimInstance Win32_Process | Where-Object { $_.ProcessId -gt 0 } | ForEach-Object { $entry=[bool]($_.CommandLine -and [regex]::IsMatch($_.CommandLine,'${pattern}','IgnoreCase')); if ($entry -or ($wanted -contains [int64]$_.ProcessId)) { [pscustomobject]@{ pid=[int64]$_.ProcessId; startedAt=$(if ($_.CreationDate) { [int64](($_.CreationDate.ToUniversalTime() - $epoch).TotalMilliseconds) } else { $null }); entry=$entry } } }); ConvertTo-Json -Compress -InputObject $list`;
98
+ const entries = ENTRY[client] ? [...new Set([root, path.resolve(releasesRoot)])].map(value => literal(path.join(path.dirname(value), ...ENTRY[client]))) : [];
99
+ const pattern = (client === 'codex' ? '(?:^|["\\s\\\\/])(?:\\.[\\\\/])?server[\\\\/]mcp-proxy\\.mjs(?=["\\s]|$)'
100
+ : `(?<=^|["\\s])(?:${entries.join('|')})(?=["\\s]|$)`).replaceAll("'", "''");
101
+ // Relative cache entries do not reveal their installation. An older Codex
102
+ // child without a record conservatively delays this client's cleanup until
103
+ // it reconnects through a recording release or exits. Other Node apps do not.
104
+ const parentCheck = client === 'codex' ? "$_.Name -ieq 'node.exe' -and ($codexParents -contains $_.ParentProcessId) -and " : '';
105
+ const script = `$ErrorActionPreference='Stop'; $wanted=@(${pids.join(',')}); $epoch=[datetime]::new(1970,1,1,0,0,0,[DateTimeKind]::Utc); $all=@(Get-CimInstance Win32_Process); $codexParents=@($all | Where-Object { $_.Name -ieq 'Codex.exe' } | ForEach-Object { $_.ProcessId }); $list=@($all | Where-Object { $_.ProcessId -gt 0 } | ForEach-Object { $entry=[bool](${parentCheck}$_.CommandLine -and [regex]::IsMatch($_.CommandLine,'${pattern}','IgnoreCase')); if ($entry -or ($wanted -contains [int64]$_.ProcessId)) { [pscustomobject]@{ pid=[int64]$_.ProcessId; startedAt=$(if ($_.CreationDate) { [int64](($_.CreationDate.ToUniversalTime() - $epoch).TotalMilliseconds) } else { $null }); entry=$entry } } }); ConvertTo-Json -Compress -InputObject $list`;
84
106
  const shell = path.join(process.env.SystemRoot || process.env.SYSTEMROOT || 'C:\\Windows', 'System32/WindowsPowerShell/v1.0/powershell.exe');
85
107
  const { stdout } = await execute(shell, ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', script],
86
108
  { windowsHide: true, timeout: 15000, maxBuffer: 1024 * 1024 });
@@ -95,7 +117,7 @@ export async function entryProcessList(client, releasesRoot, pids = []) {
95
117
  // Records of exited or reused pids are removed, so a release can go at the
96
118
  // next install once its last process is gone.
97
119
  async function entryReleases(releasesRoot, root, client, pattern, dependencies) {
98
- if (!ENTRY[client]) return { names: [], unregistered: false };
120
+ if (!ENTRY[client] && client !== 'codex') return { names: [], unregistered: false };
99
121
  const folder = releaseProcessDirectory(root, client);
100
122
  let items = [];
101
123
  try {
@@ -179,21 +201,20 @@ export async function pruneInstalledReleases({ releasesRoot, client, currentRele
179
201
  return result;
180
202
  }
181
203
 
182
- // A stable-entry client calls this before it switches an install on its stable
183
- // entry. An update worker of an earlier release cleans up after that install with
184
- // its own code, which cannot see what a stable-entry process runs and stops
185
- // before deleting only at a receipt other than v1. Resolves once the receipt is
186
- // v2, keeping the adoption it records, with whether it wrote. Throws when that
204
+ // Call before switching the binding/entry. An earlier updater cleans up after
205
+ // setup with its own code. Claude needs v2 to stop pre-B255 workers; Codex needs
206
+ // v3 to stop B255 workers that know only Claude records. Preserve the recorded
207
+ // adoption order and resolve with whether the receipt changed. Throw when that
187
208
  // cannot be confirmed, even for a cause that passes before the worker reads the
188
209
  // receipt (a file another process holds open): the caller then switches nothing.
189
210
  // currentRelease, the release the install starts now, is recorded only when
190
211
  // there is no receipt yet.
191
212
  export async function protectRetentionReceipt({ releasesRoot, client, currentRelease }) {
192
- if (!ENTRY[client]) throw failure('release_retention_client_invalid');
213
+ if (!ENTRY[client] && client !== 'codex') throw failure('release_retention_client_invalid');
193
214
  const root = await rootPath(releasesRoot), pattern = new RegExp(`^${client}-[a-f0-9]{64}$`);
194
215
  const receiptPath = path.join(root, `.${client}-retention.json`);
195
216
  const old = await readReceipt(receiptPath, client, pattern);
196
- if (old?.contract === contractWithEntry) return false;
217
+ if (old?.contract === receiptContract(client)) return false;
197
218
  let current = old?.current;
198
219
  if (!current) {
199
220
  if (typeof currentRelease !== 'string' || !path.isAbsolute(currentRelease) || !pattern.test(path.basename(currentRelease))
@@ -201,11 +222,11 @@ export async function protectRetentionReceipt({ releasesRoot, client, currentRel
201
222
  current = path.basename(currentRelease);
202
223
  await directory(path.join(root, current));
203
224
  }
204
- await writeReceipt(receiptPath, { contract: contractWithEntry, client, current, previous: old ? old.previous : null });
225
+ await writeReceipt(receiptPath, { contract: receiptContract(client), client, current, previous: old ? old.previous : null });
205
226
  return true;
206
227
  }
207
228
 
208
- const receiptContract = client => ENTRY[client] ? contractWithEntry : contract;
229
+ const receiptContract = client => client === 'codex' ? codexContract : ENTRY[client] ? contractWithEntry : contract;
209
230
 
210
231
  async function readReceipt(receiptPath, client, pattern) {
211
232
  let old = null;
@@ -213,7 +234,7 @@ async function readReceipt(receiptPath, client, pattern) {
213
234
  const stat = await fs.lstat(receiptPath);
214
235
  if (!stat.isFile() || stat.isSymbolicLink() || stat.nlink !== 1 || stat.size > 4096) throw failure('release_retention_receipt_invalid');
215
236
  old = JSON.parse(await fs.readFile(receiptPath, 'utf8'));
216
- if (![contract, contractWithEntry].includes(old?.contract) || old.client !== client || !pattern.test(old.current)
237
+ if (![contract, contractWithEntry, ...(client === 'codex' ? [codexContract] : [])].includes(old?.contract) || old.client !== client || !pattern.test(old.current)
217
238
  || old.previous !== null && !pattern.test(old.previous) || old.current === old.previous) throw failure('release_retention_receipt_invalid');
218
239
  } catch (error) {
219
240
  if (error.code === 'ENOENT') return null;
@@ -245,7 +266,7 @@ export async function removeInstalledReleases({ releasesRoot, client }, dependen
245
266
  if (!result.deferred.length) {
246
267
  await fs.rm(path.join(root, `.${client}-retention.json`), { force: true });
247
268
  // entryReleases checked above that this is a folder in the releases root.
248
- if (ENTRY[client]) await fs.rm(releaseProcessDirectory(root, client), { recursive: true, force: true });
269
+ if (ENTRY[client] || client === 'codex') await fs.rm(releaseProcessDirectory(root, client), { recursive: true, force: true });
249
270
  }
250
271
  result.complete = result.deferred.length === 0;
251
272
  } catch (error) { result.error = safeCode(error); }
@@ -32,7 +32,7 @@
32
32
  },
33
33
  {
34
34
  "path": "core/hellolynk-client-profile.mjs",
35
- "sha256": "4b45a78b4d6c4794a1f494bd95777579c32c56a68321a1d3b484048942ae4742"
35
+ "sha256": "8be37831c96610e3d0a64848ada86488970cc6079e49764b47d8a8b2ba852269"
36
36
  },
37
37
  {
38
38
  "path": "core/hellolynk-client-update-entry.mjs",
@@ -48,7 +48,7 @@
48
48
  },
49
49
  {
50
50
  "path": "core/hellolynk-release-retention.mjs",
51
- "sha256": "4ba5607e92f98a9a33b9ffd9ad166e559bc3197fcb1a6d54cef96b2b91ddc38e"
51
+ "sha256": "9b02a42a510fa5ef4a251b6e675f9ccc60f20b718d17c1617027cd048c5634dd"
52
52
  },
53
53
  {
54
54
  "path": "core/hellolynk-contact-request-e2ee.mjs",
@@ -164,7 +164,7 @@
164
164
  },
165
165
  {
166
166
  "path": "core/hellolynk-native-addressing-tools.cjs",
167
- "sha256": "252251de855c3fe9c5ebdd54a97ba976a8009f4ac57ec44f492bed8c7fb903de"
167
+ "sha256": "f4bd81b3d03277e28955a62409383a0c4072c6212567f71425df4e18ece75d63"
168
168
  },
169
169
  {
170
170
  "path": "core/hellolynk-native-human-confirmation-broker.mjs",
@@ -176,7 +176,7 @@
176
176
  },
177
177
  {
178
178
  "path": "core/hellolynk-neutral-host-installation-store.mjs",
179
- "sha256": "b5f6288732af6f9b9c0c750f6002eae657dde9513fc97674f6e59200f3cc9dc6"
179
+ "sha256": "dfb6bba4c627082cd6fca8cb38dc786f905e38f3e83ccf91dbfe57e55639e8a2"
180
180
  },
181
181
  {
182
182
  "path": "core/hellolynk-neutral-host-launcher.mjs",
@@ -184,7 +184,7 @@
184
184
  },
185
185
  {
186
186
  "path": "core/hellolynk-neutral-host-process.mjs",
187
- "sha256": "48f9bd6451adafdf3b43591a3b1469e36174c30fe04214cd2a84fb0aeebea023"
187
+ "sha256": "e744bacf65f7b86cbcf7d654189c0e07e09401083e2b6f9053b17c1c3bacd1b4"
188
188
  },
189
189
  {
190
190
  "path": "core/hellolynk-neutral-host-store-adapters.mjs",
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "contract": "hellolynk-neutral-host-release-pin-v1",
3
- "manifestSha256": "a90945fc34ec9cd8bccfdc39193084515f432aa84980f927a475841a6cdb34b2"
3
+ "manifestSha256": "379a5532724e4935decd6ffbd7bc6b52cc927c1f910decc406394d9601b55ba3"
4
4
  }
@@ -1 +1 @@
1
- {"contract":"hellolynk-workbuddy-immutable-package-v1","entry":"integrations/workbuddy/server/mcp-proxy.mjs","files":[{"path":"clients/core/hellolynk-client-account.mjs","sha256":"a22f14f494c1a44a9272ca95e160f8cb1df612a1ceb8b54e32596b13f90c3740"},{"path":"clients/core/hellolynk-client-core.mjs","sha256":"af7c9cb7a996fdb194c51dbcc745c48b616ff1686d79a1451104690d882df1b8"},{"path":"clients/core/hellolynk-client-profile.mjs","sha256":"81d4f64c11c8dbccec04a05435cc42b53823db2649f2c88739647299b3c97fd2"},{"path":"clients/core/hellolynk-client-update-entry.mjs","sha256":"dc62228a7351c721514b5ca7921d485dc6aa05475aaa2e3881b78d7de0e1a134"},{"path":"clients/core/hellolynk-client-update-runtime.mjs","sha256":"0a76f2bdcf338c544e493ca7d0b7168f03ffa32ed223e3537eccafc1cbaafba0"},{"path":"clients/core/hellolynk-client-update.mjs","sha256":"a4104a67dd72cb7a1950585c92aa8424b9387c1eda4f191e0df3f901c4f16a8f"},{"path":"clients/core/hellolynk-contact-request-e2ee.mjs","sha256":"18526628b354d18bcbe5e621360ecfcd5dfa4cb4d91397fb87d0c20e1f332a5d"},{"path":"clients/core/hellolynk-device-enrollment.mjs","sha256":"18f9decb843a5a82ef8dfc3e866904e0b04bbc48d700eac55a8ae54c5729c2aa"},{"path":"clients/core/hellolynk-direct-text-e2ee-client.mjs","sha256":"dd5dfa410a664e21e14b3c253ca496dd303e36aa5a2e1370b78cc51ec1fba973"},{"path":"clients/core/hellolynk-direct-text-e2ee.mjs","sha256":"3fee00210896b81cf40d25c634a6a758adee18704ef4a74fbc00b699a58d53e5"},{"path":"clients/core/hellolynk-host-auth.mjs","sha256":"49baa0b82ab078ad74a892a179189bdbd303a791d580ba4d6eac457564fad535"},{"path":"clients/core/hellolynk-host-protected-store.mjs","sha256":"0cefa22574df9dd99073d73bb688e9cae3faf6da862af013c1dfe9c87efef32e"},{"path":"clients/core/hellolynk-host-transport-client.mjs","sha256":"0c97425346496a5d5e1f2b3d092d5d227179051b63e8097bab225dffe576008a"},{"path":"clients/core/hellolynk-host.mjs","sha256":"ed88f2285b4c5eb8618a2f3f3c2a7a65d798465933b91b109121bb90b45f5880"},{"path":"clients/core/hellolynk-human-confirmation-ledger.mjs","sha256":"265ae39e93112416588841a14eb0351905d60b2552cf04c8cf8bd057acd64586"},{"path":"clients/core/hellolynk-human-relationship-controller.mjs","sha256":"01589c3eeb1c35f26cb50a14ce4e603c7bffe71e0b11863aed97c85f356e3c97"},{"path":"clients/core/hellolynk-inbox-read-state.mjs","sha256":"3c354aaa7038446f8f554f9520db287cc06559e6cb22cb69f0121a179ff2cb01"},{"path":"clients/core/hellolynk-indexed-message-store.mjs","sha256":"101f928dc5fab8064132e8755f74e157d35f921b5fe7d52fc80c0e46dc131428"},{"path":"clients/core/hellolynk-instance-conversation.mjs","sha256":"2e4a23917d4a86216b653ed04ec46216b9400fa94c13c0a00f1afc7877e284cb"},{"path":"clients/core/hellolynk-local-contact-requests.mjs","sha256":"3cbf0a0c6adeff17ceb310d202138c2dde7e23d0e8309f2584c161aae4c36acd"},{"path":"clients/core/hellolynk-local-contacts.mjs","sha256":"93d923702bdb5cbcbd47faf01f2c2e30bfe612fc450ef35ee98477412b2bbc6e"},{"path":"clients/core/hellolynk-local-data-migration.mjs","sha256":"72046a992b14f43167d6a671ec1094d34041cf43ba16d9d507583228045c7aa2"},{"path":"clients/core/hellolynk-local-data-protection.mjs","sha256":"798f42e9bd45a00565b628282233a55abfdc4d7102423cb0558a7e01fab76810"},{"path":"clients/core/hellolynk-local-identity-trust.mjs","sha256":"658fb5264d587341497e7d869408e51c1850f750856585ec7368a13c26f76a07"},{"path":"clients/core/hellolynk-local-messaging.mjs","sha256":"76b4348eb6eff34dec41c90666ac8ee14554018c5729c39b5b78bac30f0eaf80"},{"path":"clients/core/hellolynk-local-peer-transport.mjs","sha256":"4b8f01002b03fa19a9eea9dd72c7a41c4c951d6ef201f06dd1a89086a0a872cd"},{"path":"clients/core/hellolynk-local-process-lock.mjs","sha256":"5dd9b21f4e4509b148daaf2b495036e336e56be320d2bf7a3fac08b8a567d3bf"},{"path":"clients/core/hellolynk-model-inbox.mjs","sha256":"e112cbbb1caff5aa6f4a71bdfcb2d1c38260a96e3e4ab076b5f95c55e1da645e"},{"path":"clients/core/hellolynk-model-notices.cjs","sha256":"1b1c6e190b89f7305d05e1dddddaa6d50b7289b90aeab4599073eaaae27396f1"},{"path":"clients/core/hellolynk-native-addressing-tools.cjs","sha256":"e583c769b72d8cf52523c19b3320c982c2550f002041770f5953f16951690162"},{"path":"clients/core/hellolynk-native-conversations.mjs","sha256":"38116a956c2c96dbac6b5355e2097385475879ab5e9965ae3552912739379630"},{"path":"clients/core/hellolynk-native-human-confirmation-broker.mjs","sha256":"755fd03a4ee3b97cdfdb1efc491fb4cf602e25173819380ea8a715c04c82ea5a"},{"path":"clients/core/hellolynk-native-inbox-runtime.mjs","sha256":"bee3a5789420cc25cbc153cc8291f144b3a10ae50e96269823b7890cb603789d"},{"path":"clients/core/hellolynk-native-notice.mjs","sha256":"6cdbae7ad07f104c1d19123299d9b672d9d51265e5e1f512acd12a083617d419"},{"path":"clients/core/hellolynk-native-reply-routes.mjs","sha256":"65af258205a7eb9d2c599e0f400dbd9ea198c38a26f491e06f27c5c46101fc9b"},{"path":"clients/core/hellolynk-native-task-index.cjs","sha256":"aaeb19ee32e4736bd4b8fd23c544305d98c41908ab5ff9b211454b913edd009e"},{"path":"clients/core/hellolynk-native-worker-lease.mjs","sha256":"41eb3103c216a09b80159522700b7bb78f3b082a644501fd19fa51ce1bf6bab7"},{"path":"clients/core/hellolynk-neutral-host-assembly.mjs","sha256":"98b2b669183cda15272b182d5c04d3ae77511b8b657cd3179cbf2fa5d5f27920"},{"path":"clients/core/hellolynk-neutral-host-installation-store.mjs","sha256":"9ff399639d320e5527e51cd0ddbf049e7e0e8d3cc225cdc30f0d4637356a1590"},{"path":"clients/core/hellolynk-neutral-host-launcher.mjs","sha256":"490f8010bd84fc7c92a00ec4d4a996c27dd398b2e3584ded8bcebb74c598c18d"},{"path":"clients/core/hellolynk-neutral-host-process.mjs","sha256":"75076c91d2240ed749969997b6fc8f0f252e938ab33412904031c9298ee831f7"},{"path":"clients/core/hellolynk-neutral-host-store-adapters.mjs","sha256":"b033d5cdedc54847bf1a9fd4d5b70af6d0e1ed8094e74feebbb592c242a0cde9"},{"path":"clients/core/hellolynk-neutral-host-workbench-read-model.mjs","sha256":"6767b4aaf5c7304587d7126f203535f02d1f1bfd692741105ad644686ecb1612"},{"path":"clients/core/hellolynk-platform-credential-store.mjs","sha256":"0558aca043ff586f10d7b82e1b2fe9b537ff661913dce76fc92feaf9bd7e5546"},{"path":"clients/core/hellolynk-relay-client-cli.mjs","sha256":"e3134f37ff8c327b3148a4c417ee14c6c8bfbc3be9680e25c1ea29d215dff1d7"},{"path":"clients/core/hellolynk-release-retention.mjs","sha256":"679bd875f8952a5070455d7219926cf95117c7589b8abdf1d79eabf6917b5530"},{"path":"clients/core/hellolynk-runtime-safety.cjs","sha256":"1518d9904b329f05a92092f0f2d4014675014597573ba85f33e3e06c25ecea16"},{"path":"clients/core/hellolynk-workbench-action-grants.mjs","sha256":"7247f4bce07e6fafce6559604ef9c7a8f7a033b922c212344462411be55ea9ac"},{"path":"clients/core/hellolynk-workbench-connection.mjs","sha256":"198fb21c3db2c91b85ca38d334c0ffe56ef28f2f052b6b62a8d2ed5c166fcd82"},{"path":"clients/platform/windows/credential-store.ps1","sha256":"7ec7362eba2c442d9417035ff14c1108c7a58558b6f09ac36a2275828370debb"},{"path":"clients/platform/windows/hellolynk-host-protected-store.ps1","sha256":"84ac61c3762b7f944bf3e2c895f9a6427985ce697052afd9bc610474c921adad"},{"path":"clients/platform/windows/hellolynk-human-confirmation-ledger.ps1","sha256":"317409f270f2cbd8017b61384292cf9caf4bd0fce6ef7a9894c1ec4c173b240c"},{"path":"clients/platform/windows/hellolynk-local-data-key.ps1","sha256":"3143122114c9756370e2ff3f56eba4a03e4a1657888aab1c6d4387427081d937"},{"path":"clients/platform/windows/hellolynk-native-human-confirmation-broker.ps1","sha256":"d63e02b34eb43d1a81d771f0e23f0b8d38e34c8f96663156d0c7b79985802936"},{"path":"clients/workbench/contract.mjs","sha256":"9994f8c7260495355d9e02ff96b7dd1074e1bf2ee238fbaafa6864bf749c095c"},{"path":"clients/workbench/service.mjs","sha256":"681fe98e286a69a187fb59c8f955c274a51bb38606b9618800ee5995f768e367"},{"path":"integrations/workbuddy/package.json","sha256":"94dd6849e56be0342485fcee3a1ac6e63ed9efdac97f5c64fa4b38d80cda3d3b"},{"path":"integrations/workbuddy/server/host-lifecycle.mjs","sha256":"3b8e6d6d537226a6242059830759df1a686a42f50c3103c5e949d79806c1a4f9"},{"path":"integrations/workbuddy/server/mcp-proxy.mjs","sha256":"5b4a4ac035e23bea30e4559451252ce0aa48fc7e2929c910fa9a2e31324bfc70"},{"path":"integrations/workbuddy/server/mcp-server.mjs","sha256":"00ea077f3cbcd5cc75f5d3df8689c6a46381506198149fcad98ef20f85833b18"},{"path":"integrations/workbuddy/server/model-call-origin.mjs","sha256":"4cece99ea644c71388323557dc0d9ba493a96cff75b55421d5e53d35ec97f584"},{"path":"integrations/workbuddy/server/native-task-cdp.mjs","sha256":"4a6894cc97866c8e9d0beae138e2e0a98412191207494e98844b17120ec839f5"},{"path":"integrations/workbuddy/server/native-task-debug-startup.mjs","sha256":"2bb5a92a82213191c120af0c3e6ce62977e3164551bec60d1e0bcbb3635d99e4"},{"path":"integrations/workbuddy/server/native-task-debug-startup.ps1","sha256":"49b2c00c806cce6b6b50abf8e4e6cf699777889fe4b488872e926980b6368615"},{"path":"integrations/workbuddy/server/native-task-mcp-registration.mjs","sha256":"fe19db7cd3d700542c20325589f99a3f607c3d2b893a950afd06c9007fd01d7b"},{"path":"integrations/workbuddy/server/native-task-service-registration.mjs","sha256":"025e9be428c438bb87565536404ded32cb1db56614441911c74169270f6e1422"},{"path":"integrations/workbuddy/server/native-task-worker.mjs","sha256":"8b6d11fca70adde335a6b1c92776c6d76ba69ff669457a7d803a8076457b4c8d"},{"path":"integrations/workbuddy/server/neutral-host-adapter.mjs","sha256":"fa053192e761bbd9eecea95e127b68d3b94d56e91d861230bd9771a1cd754b09"},{"path":"integrations/workbuddy/server/origin-hook.mjs","sha256":"4f2fe78f59771fef1ca1e1cc145a38df566cc70ff318ff6192f2e4003d76bc3d"},{"path":"integrations/workbuddy/server/origin-routes.mjs","sha256":"893bfb495c78579062e1007afab6dee07f0994d48109413355d8951eceb52dd5"},{"path":"integrations/workbuddy/server/package-bootstrap.mjs","sha256":"8794c98a846c6d1c3683fa31b9296267725a5f4f9160b57a6f6039937292cb25"},{"path":"integrations/workbuddy/server/workbench-candidate.mjs","sha256":"caa64a710a71afe67dde53b7a46dd91ea555b5a946a2749909fcf54e5f9265c0"},{"path":"integrations/workbuddy/server/workbench-hidden-launcher.vbs","sha256":"0fc1a0da2efdc49d39784888036b39a72aa6edf1f496a064ad4db105890b1a9e"},{"path":"integrations/workbuddy/server/workbench-process.mjs","sha256":"dbbb372e522b17894b6e50c12a13fc172ff752d1487354c772fcc670add212c0"},{"path":"integrations/workbuddy/server/workbench-task.ps1","sha256":"c2973667a10eefc96c0f999290f8aecc5e3b2062870f7637bf828252dff15fb5"},{"path":"integrations/workbuddy/skills/hellolynk-inbox/SKILL.md","sha256":"27b0f6b8033b702bcb22f0c70e39eac89ea61e0f1f2f6973a79361b0ec854942"},{"path":"integrations/workbuddy/skills/hellolynk-inbox/workbuddy.json","sha256":"163e506e3c87dd3f5128cd449de6affba48591c573e927edc128aeb93cd28735"},{"path":"runtime/connect-activate.mjs","sha256":"50ec8b0a58ac5b099a653722b0946acb23d0a29a054bfb3856dc963db6f84bee"},{"path":"runtime/core/hellolynk-agent-configurator.mjs","sha256":"505b010ffd2c3fb614f2a4c6eae92a9fc5b640b8e48dff39e563dcbaabfd344b"},{"path":"runtime/core/hellolynk-client-account.mjs","sha256":"ab7ec5dda92e510e7deb14f900fd2df4c6c3373fbeb4af4fb2b6c1a72aa41a99"},{"path":"runtime/core/hellolynk-client-core.mjs","sha256":"94bbad1d0ccee969bbffed176449e427188f1b892512a64167ab31f63d258e2b"},{"path":"runtime/core/hellolynk-client-profile.mjs","sha256":"4b45a78b4d6c4794a1f494bd95777579c32c56a68321a1d3b484048942ae4742"},{"path":"runtime/core/hellolynk-client-update-entry.mjs","sha256":"b2740406d79d0fa129c3bd1b5e6a07c3f52eed5e35a91ffea40b099ddc708936"},{"path":"runtime/core/hellolynk-client-update-runtime.mjs","sha256":"3ed31f0cea704c3ad26481126a78a7d39c21df69a5c52d1074a096a2b7b3e32f"},{"path":"runtime/core/hellolynk-client-update.mjs","sha256":"8f0d6f54313c91bd2ffb4643859a91dd1e122bb5f1da9143fe2851a3370d7fbf"},{"path":"runtime/core/hellolynk-contact-request-e2ee.mjs","sha256":"657664c6250d2738061e1ec2680eda6b36063c357d9e2d9c743e4218ece50895"},{"path":"runtime/core/hellolynk-device-enrollment.mjs","sha256":"f3e99ff2bdfa76e5a830a518792a1b9e5e705d7a8a01eca725dd7c5c8391d4ef"},{"path":"runtime/core/hellolynk-direct-text-e2ee-client.mjs","sha256":"4007bf5e6c91df00adf10384cc1f0d0d28491b8ded518365dddbac717f3ac5be"},{"path":"runtime/core/hellolynk-direct-text-e2ee.mjs","sha256":"f0abc3714cfad007669140ead4bfbb3f5bd56edd24d4389c3addee3f42887a01"},{"path":"runtime/core/hellolynk-host-auth.mjs","sha256":"db1ec56f4e60e6450fba50188eecf89748f39f5d7a75c2456c30a6053233555d"},{"path":"runtime/core/hellolynk-host-protected-store.mjs","sha256":"89b6e6c4ce9c6ba2984f8c301de4251da6004bdd402cc44d578a4505c21b75b1"},{"path":"runtime/core/hellolynk-host-transport-client.mjs","sha256":"9f27d3e44ce8333413e712eb38b970a335b64081d7e3be6882ff5ca921668859"},{"path":"runtime/core/hellolynk-host.mjs","sha256":"6cbe0ba6ec7aa81059a4a2d0e247fbedb6731687ec21ded4aaefa0e79be9e493"},{"path":"runtime/core/hellolynk-human-confirmation-ledger.mjs","sha256":"63bcbbb0870ad83fc031636d74ce77fc070d5f4d1d4c10297f8b3ec9ad85bbf6"},{"path":"runtime/core/hellolynk-human-relationship-controller.mjs","sha256":"7ef584c30febf0e142f621b719e433c0a9f5d976bbb917ab15f6cc1abb39ad52"},{"path":"runtime/core/hellolynk-inbox-read-state.mjs","sha256":"bf2353075f0a10cc3492c0d7309f8d3fef4a4bda1996b878cfbae8515beaeb34"},{"path":"runtime/core/hellolynk-indexed-message-store.mjs","sha256":"61a9d642fb0453aa949c6e634a30ae3f8562a81d3a666580a2f32d414c9f80ad"},{"path":"runtime/core/hellolynk-instance-conversation.mjs","sha256":"f00161cbdab48b33f0be1a809389145c167d8b8bdfab32d8c929db3bc167b4a1"},{"path":"runtime/core/hellolynk-local-contact-requests.mjs","sha256":"9724729b28c4c979696fcd53531e89eddb18a3045e32f602ecfb002af1c44b4c"},{"path":"runtime/core/hellolynk-local-contacts.mjs","sha256":"b7c722f0c300f951ed390ea82aec04975b226f2ea4d5c873764ab36ef9a8bc2c"},{"path":"runtime/core/hellolynk-local-data-migration.mjs","sha256":"1e791114633770fe3955842725965798dfd749e1dbf513f08efc4e01b9ed1756"},{"path":"runtime/core/hellolynk-local-data-protection.mjs","sha256":"1bda879aa0bdf46700a63374e82cc7bc639385656b1463a75a49e8510971066c"},{"path":"runtime/core/hellolynk-local-identity-trust.mjs","sha256":"b6d22715c627820c0ea92ca543cf52bbfeee5d5f416d242c2e21230640310420"},{"path":"runtime/core/hellolynk-local-messaging.mjs","sha256":"23e701818b18b96ba36ad1dfc3c2489d80fec8dafa2f433cf29947175786ed07"},{"path":"runtime/core/hellolynk-local-peer-transport.mjs","sha256":"9c32b2fa5f716f1ff36e09b3f2cd697479acc2f3c6bcb6e96045f5ca65e3b1c6"},{"path":"runtime/core/hellolynk-local-process-lock.mjs","sha256":"5212990a98b9ad2eb83fa2d5fb8a123d687c5ef6daf6cba49a4b6d04a7fe251e"},{"path":"runtime/core/hellolynk-model-inbox.mjs","sha256":"516c846340ee7a2fd624eaedaa51ded81988ef875b8a7eeb15c2e296774bfa63"},{"path":"runtime/core/hellolynk-model-notices.cjs","sha256":"c1b0d9071d3750c87755bc9fdf969d89c7fa62a0dede4c37b8cb2954b81163b0"},{"path":"runtime/core/hellolynk-native-addressing-tools.cjs","sha256":"252251de855c3fe9c5ebdd54a97ba976a8009f4ac57ec44f492bed8c7fb903de"},{"path":"runtime/core/hellolynk-native-conversations.mjs","sha256":"671030938a5259f6cce0c1eb4e61997f7f89232c677c9ba26062daea91b6f8c6"},{"path":"runtime/core/hellolynk-native-human-confirmation-broker.mjs","sha256":"2fb2d3b40869362be3e40a1ec55947021319af5315cbf8fdc5ed59df717cceb3"},{"path":"runtime/core/hellolynk-native-inbox-runtime.mjs","sha256":"039ba7fe8273357d178556fc57e751c469e2bf0056bcaee5029e7fe376099c72"},{"path":"runtime/core/hellolynk-native-notice.mjs","sha256":"6a5fe50fbccac465d690612839eaf7c10a5622cd84151277b0bf4507eccbe087"},{"path":"runtime/core/hellolynk-native-reply-routes.mjs","sha256":"8ed07580f2b6fe6bff9953951ea79f6c7c1c806887cd0bf21d4893ba8343ebe2"},{"path":"runtime/core/hellolynk-native-worker-lease.mjs","sha256":"e4e6864ff047b1d3511c363eb2bc7a3a3841a453f5d9d40b94bde55cc38cebc5"},{"path":"runtime/core/hellolynk-neutral-host-assembly.mjs","sha256":"d0ac9c697bf8a85263d99a0739da557c62f52c72f4afb105eb97b3aac2ae1f3b"},{"path":"runtime/core/hellolynk-neutral-host-installation-store.mjs","sha256":"b5f6288732af6f9b9c0c750f6002eae657dde9513fc97674f6e59200f3cc9dc6"},{"path":"runtime/core/hellolynk-neutral-host-launcher.mjs","sha256":"789b2531cdbde6e6d8f91f2a40746372e903e9e48e8aa6846b9abf2d28150780"},{"path":"runtime/core/hellolynk-neutral-host-process.mjs","sha256":"48f9bd6451adafdf3b43591a3b1469e36174c30fe04214cd2a84fb0aeebea023"},{"path":"runtime/core/hellolynk-neutral-host-store-adapters.mjs","sha256":"3e425ca2cc111e750f55e94be2561cae8a3b308e473fb549e42da3443b67fd34"},{"path":"runtime/core/hellolynk-neutral-host-workbench-read-model.mjs","sha256":"65ca217dbd5be05f4cf38fd977b0d536526f79463a402fae90a7329dac375670"},{"path":"runtime/core/hellolynk-platform-credential-store.mjs","sha256":"f27f5f377cc4d6d2b5664212cf8fcc4c98d910064c1677ff9c1f776df1a59dba"},{"path":"runtime/core/hellolynk-relay-client-cli.mjs","sha256":"29707c4e0d91d5db6f46408b4c1101b9ab30b117500a9e315da8802e71a43010"},{"path":"runtime/core/hellolynk-release-retention.mjs","sha256":"4ba5607e92f98a9a33b9ffd9ad166e559bc3197fcb1a6d54cef96b2b91ddc38e"},{"path":"runtime/core/hellolynk-runtime-safety.cjs","sha256":"43d576d9f774409f4a735793c1503a6f397e787b10c59a4ac9cc9257299f5efe"},{"path":"runtime/core/hellolynk-workbench-action-grants.mjs","sha256":"076d1bb848c85c06695440f33daebd853a9f49147a85cf582cc3e2964d95198a"},{"path":"runtime/core/hellolynk-workbench-connection.mjs","sha256":"d3396350fd75af78e60772e021cf6dfb643d9eee41894c5461c959a56650cb60"},{"path":"runtime/neutral-host-bootstrap.mjs","sha256":"db0ffd88a5fbb9091f16ceab4e391ac6919ba2640cdbc358574034779f848d7e"},{"path":"runtime/neutral-host-release-entry.mjs","sha256":"d434d392c85728228772369e9a890cef34598833ab2433dcc7b963c17bf5c146"},{"path":"runtime/neutral-host-release-loader.mjs","sha256":"00b226c65732bcd4d18d2b1b4ebc5092b7073fac52ee500d5d746b01217bfa65"},{"path":"runtime/neutral-host-release-manifest.json","sha256":"a90945fc34ec9cd8bccfdc39193084515f432aa84980f927a475841a6cdb34b2"},{"path":"runtime/neutral-host-release-pin.json","sha256":"1e8e8e153126b9a9d38412a36bba7eda55a9d68d5f58cd7e2fa43633913580ce"},{"path":"runtime/platform/windows/configure-agent.ps1","sha256":"7dc7c75bf0f7e45060b041a08d502993afe84581040f165e7f4437bf490708fa"},{"path":"runtime/platform/windows/credential-store.ps1","sha256":"d00dae4af08205fffa52c4956d1c87d5c3423e8f20982ccfc1b76e3424fe442e"},{"path":"runtime/platform/windows/hellolynk-host-protected-store.ps1","sha256":"24357e8ce54090b4ec68e457f02c9e834a80f3273ef3c03a8c0fa7258797fb49"},{"path":"runtime/platform/windows/hellolynk-human-confirmation-ledger.ps1","sha256":"4612561e2128dfd96c018f2c2d9ae41016f35bb6df8536314e9f0fb428165a82"},{"path":"runtime/platform/windows/hellolynk-local-data-key.ps1","sha256":"0976a0ecdd724e767b87e65743a230569c3fcb30e2449cf38bb718eb1604c15c"},{"path":"runtime/platform/windows/hellolynk-native-human-confirmation-broker.ps1","sha256":"757a731a3e8761d5d473db19ecfc330783f2826663a0057c4d6896e679d7a388"},{"path":"runtime/workbench/candidate-bootstrap.mjs","sha256":"891b02f750693e5b4836e716922c2d632f6736b2a5b3b7417f161499459f3f56"},{"path":"runtime/workbench/contract.mjs","sha256":"20648c3ed8e20b984b698010855414f8d4acaf0e2ade53b997b5582a85d90a08"},{"path":"runtime/workbench/hellolynk-workbench-build.json","sha256":"43e42633242cb456ecf2a120380230485e4d8533934ad6242089049d9282da11"},{"path":"runtime/workbench/host-capabilities.mjs","sha256":"4e1a82e6cb46dd775ba39e2d34ff21eb1c293523883d18e607084ca91cfffb87"},{"path":"runtime/workbench/i18n.mjs","sha256":"272917746c06cabc1b87b94341f2deca5591f0bea2d7a0e07b2d959d8e1f8c74"},{"path":"runtime/workbench/loopback-surface.mjs","sha256":"6a550034c5dd558dfd22f9cb589fd76df40a99e976538e3b5d01371d212c9aa6"},{"path":"runtime/workbench/mcp-app-bundle.mjs","sha256":"48fb8224cbaa7f78a386a79b2dba761f4de6c4b83b16032f7f96bd9783e172e4"},{"path":"runtime/workbench/service.mjs","sha256":"3bf82a0076e9fe3b62105c626fe0d622092224f28d3905c62eafd65bf5385dcc"},{"path":"runtime/workbench/state.mjs","sha256":"770d10f3bf76236772c87e86f5da346c013da387fb40c08360f895a7052cf7b5"},{"path":"runtime/workbench/transports.mjs","sha256":"0c9f42ca9c9a4b4cc29b1bdcc0a0488d16a9ad06c235c642dff9cd4fc6f0d528"},{"path":"runtime/workbench/ui/app.mjs","sha256":"643a5ac8d303f936ee87dd7c0c851aa1988e99ea9a9a45c6c89da28bdc76e799"},{"path":"runtime/workbench/ui/connection-form.mjs","sha256":"700ca793f5eddca1dfea5f220c73732efc51ea4e1f8b8fc36da2bb67136240f0"},{"path":"runtime/workbench/ui/hellolynk-mark.png","sha256":"108e5c90e1717a87169d317c15f8de33859ed487b06654888047c729d9ab5982"},{"path":"runtime/workbench/ui/http-transport.mjs","sha256":"b2fedbc2c34bcf065e0fc23c8c5fb37d358c03daa2c82ba46530b8dfb8fdc571"},{"path":"runtime/workbench/ui/icons/arrow-left.svg","sha256":"1c527dd347b5fba0312cdcd66cf7514a261855672f7585d1c8b1882f602442a6"},{"path":"runtime/workbench/ui/icons/close.svg","sha256":"22f5c4fb0660601a817ead151c37e82e93d39b2ef4ce1192d66f9099a3c59b36"},{"path":"runtime/workbench/ui/icons/contacts.svg","sha256":"de0add3c43bca68d8cae7736bc3ea8145ca0abb7f32c25127542c6f5a27b3f45"},{"path":"runtime/workbench/ui/icons/inbox.svg","sha256":"e1938770f085e6794a2e22aa3f8e890e083ac341a3c3faa13098a8243dc8306b"},{"path":"runtime/workbench/ui/icons/refresh.svg","sha256":"a7b91e87c1a25d117b1352d2ec131bf6e3fe67df2020af87e0d3575c06d86f29"},{"path":"runtime/workbench/ui/icons/search.svg","sha256":"135df34e348445114a1b88757fe7ef79a6718ffa4cc761c30f8026044552b699"},{"path":"runtime/workbench/ui/icons/security.svg","sha256":"9b6c502b2ce2795530f2e7018e2c24aaaf1cf49472f040868bad148d3321071e"},{"path":"runtime/workbench/ui/icons/settings.svg","sha256":"17b528a15b8187aecd80c4974c7432ec6e58e6a12e062104fae70bf63c46caa2"},{"path":"runtime/workbench/ui/index.html","sha256":"b24cd1f768d5132539722ac7ade3acfe5aa86a47ee16a2adacf3bbf18b70c989"},{"path":"runtime/workbench/ui/loopback-entry.mjs","sha256":"0e5e5d259ab6e2d8408c6d2e089551e6f279dcb1267e9db19f9d9dded0956fd4"},{"path":"runtime/workbench/ui/mcp-app-client.mjs","sha256":"91b1e6e84a12434c2be7614845febfa44afa341d5d7f580bc1bfc106ed37f8f8"},{"path":"runtime/workbench/ui/mcp-app-entry.mjs","sha256":"ba82ac55c4efcf7701bda33b6c6e0df4d59da542b1d6c33c96ba7f2391c4773a"},{"path":"runtime/workbench/ui/styles.css","sha256":"34d24d3d35800a796905049eb5f785f402cf1e82118c66efd4893bd003adbe31"}]}
1
+ {"contract":"hellolynk-workbuddy-immutable-package-v1","entry":"integrations/workbuddy/server/mcp-proxy.mjs","files":[{"path":"clients/core/hellolynk-client-account.mjs","sha256":"a22f14f494c1a44a9272ca95e160f8cb1df612a1ceb8b54e32596b13f90c3740"},{"path":"clients/core/hellolynk-client-core.mjs","sha256":"af7c9cb7a996fdb194c51dbcc745c48b616ff1686d79a1451104690d882df1b8"},{"path":"clients/core/hellolynk-client-profile.mjs","sha256":"4528f2eb90417dbe232c4fef254beeb20c94f9216388ec721f982dd7ee4adde5"},{"path":"clients/core/hellolynk-client-update-entry.mjs","sha256":"dc62228a7351c721514b5ca7921d485dc6aa05475aaa2e3881b78d7de0e1a134"},{"path":"clients/core/hellolynk-client-update-runtime.mjs","sha256":"0a76f2bdcf338c544e493ca7d0b7168f03ffa32ed223e3537eccafc1cbaafba0"},{"path":"clients/core/hellolynk-client-update.mjs","sha256":"a4104a67dd72cb7a1950585c92aa8424b9387c1eda4f191e0df3f901c4f16a8f"},{"path":"clients/core/hellolynk-contact-request-e2ee.mjs","sha256":"18526628b354d18bcbe5e621360ecfcd5dfa4cb4d91397fb87d0c20e1f332a5d"},{"path":"clients/core/hellolynk-device-enrollment.mjs","sha256":"18f9decb843a5a82ef8dfc3e866904e0b04bbc48d700eac55a8ae54c5729c2aa"},{"path":"clients/core/hellolynk-direct-text-e2ee-client.mjs","sha256":"dd5dfa410a664e21e14b3c253ca496dd303e36aa5a2e1370b78cc51ec1fba973"},{"path":"clients/core/hellolynk-direct-text-e2ee.mjs","sha256":"3fee00210896b81cf40d25c634a6a758adee18704ef4a74fbc00b699a58d53e5"},{"path":"clients/core/hellolynk-host-auth.mjs","sha256":"49baa0b82ab078ad74a892a179189bdbd303a791d580ba4d6eac457564fad535"},{"path":"clients/core/hellolynk-host-protected-store.mjs","sha256":"0cefa22574df9dd99073d73bb688e9cae3faf6da862af013c1dfe9c87efef32e"},{"path":"clients/core/hellolynk-host-transport-client.mjs","sha256":"0c97425346496a5d5e1f2b3d092d5d227179051b63e8097bab225dffe576008a"},{"path":"clients/core/hellolynk-host.mjs","sha256":"ed88f2285b4c5eb8618a2f3f3c2a7a65d798465933b91b109121bb90b45f5880"},{"path":"clients/core/hellolynk-human-confirmation-ledger.mjs","sha256":"265ae39e93112416588841a14eb0351905d60b2552cf04c8cf8bd057acd64586"},{"path":"clients/core/hellolynk-human-relationship-controller.mjs","sha256":"01589c3eeb1c35f26cb50a14ce4e603c7bffe71e0b11863aed97c85f356e3c97"},{"path":"clients/core/hellolynk-inbox-read-state.mjs","sha256":"3c354aaa7038446f8f554f9520db287cc06559e6cb22cb69f0121a179ff2cb01"},{"path":"clients/core/hellolynk-indexed-message-store.mjs","sha256":"101f928dc5fab8064132e8755f74e157d35f921b5fe7d52fc80c0e46dc131428"},{"path":"clients/core/hellolynk-instance-conversation.mjs","sha256":"2e4a23917d4a86216b653ed04ec46216b9400fa94c13c0a00f1afc7877e284cb"},{"path":"clients/core/hellolynk-local-contact-requests.mjs","sha256":"3cbf0a0c6adeff17ceb310d202138c2dde7e23d0e8309f2584c161aae4c36acd"},{"path":"clients/core/hellolynk-local-contacts.mjs","sha256":"93d923702bdb5cbcbd47faf01f2c2e30bfe612fc450ef35ee98477412b2bbc6e"},{"path":"clients/core/hellolynk-local-data-migration.mjs","sha256":"72046a992b14f43167d6a671ec1094d34041cf43ba16d9d507583228045c7aa2"},{"path":"clients/core/hellolynk-local-data-protection.mjs","sha256":"798f42e9bd45a00565b628282233a55abfdc4d7102423cb0558a7e01fab76810"},{"path":"clients/core/hellolynk-local-identity-trust.mjs","sha256":"658fb5264d587341497e7d869408e51c1850f750856585ec7368a13c26f76a07"},{"path":"clients/core/hellolynk-local-messaging.mjs","sha256":"76b4348eb6eff34dec41c90666ac8ee14554018c5729c39b5b78bac30f0eaf80"},{"path":"clients/core/hellolynk-local-peer-transport.mjs","sha256":"4b8f01002b03fa19a9eea9dd72c7a41c4c951d6ef201f06dd1a89086a0a872cd"},{"path":"clients/core/hellolynk-local-process-lock.mjs","sha256":"5dd9b21f4e4509b148daaf2b495036e336e56be320d2bf7a3fac08b8a567d3bf"},{"path":"clients/core/hellolynk-model-inbox.mjs","sha256":"e112cbbb1caff5aa6f4a71bdfcb2d1c38260a96e3e4ab076b5f95c55e1da645e"},{"path":"clients/core/hellolynk-model-notices.cjs","sha256":"1b1c6e190b89f7305d05e1dddddaa6d50b7289b90aeab4599073eaaae27396f1"},{"path":"clients/core/hellolynk-native-addressing-tools.cjs","sha256":"cce89fa33dbe630a78d77843919a8e4b0c12f3482e754f783e6ff038b81929c4"},{"path":"clients/core/hellolynk-native-conversations.mjs","sha256":"38116a956c2c96dbac6b5355e2097385475879ab5e9965ae3552912739379630"},{"path":"clients/core/hellolynk-native-human-confirmation-broker.mjs","sha256":"755fd03a4ee3b97cdfdb1efc491fb4cf602e25173819380ea8a715c04c82ea5a"},{"path":"clients/core/hellolynk-native-inbox-runtime.mjs","sha256":"bee3a5789420cc25cbc153cc8291f144b3a10ae50e96269823b7890cb603789d"},{"path":"clients/core/hellolynk-native-notice.mjs","sha256":"6cdbae7ad07f104c1d19123299d9b672d9d51265e5e1f512acd12a083617d419"},{"path":"clients/core/hellolynk-native-reply-routes.mjs","sha256":"65af258205a7eb9d2c599e0f400dbd9ea198c38a26f491e06f27c5c46101fc9b"},{"path":"clients/core/hellolynk-native-task-index.cjs","sha256":"aaeb19ee32e4736bd4b8fd23c544305d98c41908ab5ff9b211454b913edd009e"},{"path":"clients/core/hellolynk-native-worker-lease.mjs","sha256":"41eb3103c216a09b80159522700b7bb78f3b082a644501fd19fa51ce1bf6bab7"},{"path":"clients/core/hellolynk-neutral-host-assembly.mjs","sha256":"98b2b669183cda15272b182d5c04d3ae77511b8b657cd3179cbf2fa5d5f27920"},{"path":"clients/core/hellolynk-neutral-host-installation-store.mjs","sha256":"7b8d62ce31f47ad08f2cf50b48f3bb66cfb9c4957942184abb6d04f437b1e4a0"},{"path":"clients/core/hellolynk-neutral-host-launcher.mjs","sha256":"490f8010bd84fc7c92a00ec4d4a996c27dd398b2e3584ded8bcebb74c598c18d"},{"path":"clients/core/hellolynk-neutral-host-process.mjs","sha256":"2aaf2b604f896de0d171b20590954c8da0a4c29b2eced508b4aa0a27927b40d5"},{"path":"clients/core/hellolynk-neutral-host-store-adapters.mjs","sha256":"b033d5cdedc54847bf1a9fd4d5b70af6d0e1ed8094e74feebbb592c242a0cde9"},{"path":"clients/core/hellolynk-neutral-host-workbench-read-model.mjs","sha256":"6767b4aaf5c7304587d7126f203535f02d1f1bfd692741105ad644686ecb1612"},{"path":"clients/core/hellolynk-platform-credential-store.mjs","sha256":"0558aca043ff586f10d7b82e1b2fe9b537ff661913dce76fc92feaf9bd7e5546"},{"path":"clients/core/hellolynk-relay-client-cli.mjs","sha256":"e3134f37ff8c327b3148a4c417ee14c6c8bfbc3be9680e25c1ea29d215dff1d7"},{"path":"clients/core/hellolynk-release-retention.mjs","sha256":"9f8b5b97eee7530dc8ef965b0df6a19065b06012255100977d8abb17ce50d204"},{"path":"clients/core/hellolynk-runtime-safety.cjs","sha256":"1518d9904b329f05a92092f0f2d4014675014597573ba85f33e3e06c25ecea16"},{"path":"clients/core/hellolynk-workbench-action-grants.mjs","sha256":"7247f4bce07e6fafce6559604ef9c7a8f7a033b922c212344462411be55ea9ac"},{"path":"clients/core/hellolynk-workbench-connection.mjs","sha256":"198fb21c3db2c91b85ca38d334c0ffe56ef28f2f052b6b62a8d2ed5c166fcd82"},{"path":"clients/platform/windows/credential-store.ps1","sha256":"7ec7362eba2c442d9417035ff14c1108c7a58558b6f09ac36a2275828370debb"},{"path":"clients/platform/windows/hellolynk-host-protected-store.ps1","sha256":"84ac61c3762b7f944bf3e2c895f9a6427985ce697052afd9bc610474c921adad"},{"path":"clients/platform/windows/hellolynk-human-confirmation-ledger.ps1","sha256":"317409f270f2cbd8017b61384292cf9caf4bd0fce6ef7a9894c1ec4c173b240c"},{"path":"clients/platform/windows/hellolynk-local-data-key.ps1","sha256":"3143122114c9756370e2ff3f56eba4a03e4a1657888aab1c6d4387427081d937"},{"path":"clients/platform/windows/hellolynk-native-human-confirmation-broker.ps1","sha256":"d63e02b34eb43d1a81d771f0e23f0b8d38e34c8f96663156d0c7b79985802936"},{"path":"clients/workbench/contract.mjs","sha256":"9994f8c7260495355d9e02ff96b7dd1074e1bf2ee238fbaafa6864bf749c095c"},{"path":"clients/workbench/service.mjs","sha256":"681fe98e286a69a187fb59c8f955c274a51bb38606b9618800ee5995f768e367"},{"path":"integrations/workbuddy/package.json","sha256":"646b5125edbb5b195b7c30deca6929f01adba997f0081dae4122f51991bf0aac"},{"path":"integrations/workbuddy/server/host-lifecycle.mjs","sha256":"3b8e6d6d537226a6242059830759df1a686a42f50c3103c5e949d79806c1a4f9"},{"path":"integrations/workbuddy/server/mcp-proxy.mjs","sha256":"5b4a4ac035e23bea30e4559451252ce0aa48fc7e2929c910fa9a2e31324bfc70"},{"path":"integrations/workbuddy/server/mcp-server.mjs","sha256":"00ea077f3cbcd5cc75f5d3df8689c6a46381506198149fcad98ef20f85833b18"},{"path":"integrations/workbuddy/server/model-call-origin.mjs","sha256":"4cece99ea644c71388323557dc0d9ba493a96cff75b55421d5e53d35ec97f584"},{"path":"integrations/workbuddy/server/native-task-cdp.mjs","sha256":"4a6894cc97866c8e9d0beae138e2e0a98412191207494e98844b17120ec839f5"},{"path":"integrations/workbuddy/server/native-task-debug-startup.mjs","sha256":"2bb5a92a82213191c120af0c3e6ce62977e3164551bec60d1e0bcbb3635d99e4"},{"path":"integrations/workbuddy/server/native-task-debug-startup.ps1","sha256":"49b2c00c806cce6b6b50abf8e4e6cf699777889fe4b488872e926980b6368615"},{"path":"integrations/workbuddy/server/native-task-mcp-registration.mjs","sha256":"fe19db7cd3d700542c20325589f99a3f607c3d2b893a950afd06c9007fd01d7b"},{"path":"integrations/workbuddy/server/native-task-service-registration.mjs","sha256":"025e9be428c438bb87565536404ded32cb1db56614441911c74169270f6e1422"},{"path":"integrations/workbuddy/server/native-task-worker.mjs","sha256":"8b6d11fca70adde335a6b1c92776c6d76ba69ff669457a7d803a8076457b4c8d"},{"path":"integrations/workbuddy/server/neutral-host-adapter.mjs","sha256":"fa053192e761bbd9eecea95e127b68d3b94d56e91d861230bd9771a1cd754b09"},{"path":"integrations/workbuddy/server/origin-hook.mjs","sha256":"4f2fe78f59771fef1ca1e1cc145a38df566cc70ff318ff6192f2e4003d76bc3d"},{"path":"integrations/workbuddy/server/origin-routes.mjs","sha256":"893bfb495c78579062e1007afab6dee07f0994d48109413355d8951eceb52dd5"},{"path":"integrations/workbuddy/server/package-bootstrap.mjs","sha256":"8794c98a846c6d1c3683fa31b9296267725a5f4f9160b57a6f6039937292cb25"},{"path":"integrations/workbuddy/server/workbench-candidate.mjs","sha256":"caa64a710a71afe67dde53b7a46dd91ea555b5a946a2749909fcf54e5f9265c0"},{"path":"integrations/workbuddy/server/workbench-hidden-launcher.vbs","sha256":"0fc1a0da2efdc49d39784888036b39a72aa6edf1f496a064ad4db105890b1a9e"},{"path":"integrations/workbuddy/server/workbench-process.mjs","sha256":"dbbb372e522b17894b6e50c12a13fc172ff752d1487354c772fcc670add212c0"},{"path":"integrations/workbuddy/server/workbench-task.ps1","sha256":"c2973667a10eefc96c0f999290f8aecc5e3b2062870f7637bf828252dff15fb5"},{"path":"integrations/workbuddy/skills/hellolynk-inbox/SKILL.md","sha256":"27b0f6b8033b702bcb22f0c70e39eac89ea61e0f1f2f6973a79361b0ec854942"},{"path":"integrations/workbuddy/skills/hellolynk-inbox/workbuddy.json","sha256":"163e506e3c87dd3f5128cd449de6affba48591c573e927edc128aeb93cd28735"},{"path":"runtime/connect-activate.mjs","sha256":"50ec8b0a58ac5b099a653722b0946acb23d0a29a054bfb3856dc963db6f84bee"},{"path":"runtime/core/hellolynk-agent-configurator.mjs","sha256":"505b010ffd2c3fb614f2a4c6eae92a9fc5b640b8e48dff39e563dcbaabfd344b"},{"path":"runtime/core/hellolynk-client-account.mjs","sha256":"ab7ec5dda92e510e7deb14f900fd2df4c6c3373fbeb4af4fb2b6c1a72aa41a99"},{"path":"runtime/core/hellolynk-client-core.mjs","sha256":"94bbad1d0ccee969bbffed176449e427188f1b892512a64167ab31f63d258e2b"},{"path":"runtime/core/hellolynk-client-profile.mjs","sha256":"8be37831c96610e3d0a64848ada86488970cc6079e49764b47d8a8b2ba852269"},{"path":"runtime/core/hellolynk-client-update-entry.mjs","sha256":"b2740406d79d0fa129c3bd1b5e6a07c3f52eed5e35a91ffea40b099ddc708936"},{"path":"runtime/core/hellolynk-client-update-runtime.mjs","sha256":"3ed31f0cea704c3ad26481126a78a7d39c21df69a5c52d1074a096a2b7b3e32f"},{"path":"runtime/core/hellolynk-client-update.mjs","sha256":"8f0d6f54313c91bd2ffb4643859a91dd1e122bb5f1da9143fe2851a3370d7fbf"},{"path":"runtime/core/hellolynk-contact-request-e2ee.mjs","sha256":"657664c6250d2738061e1ec2680eda6b36063c357d9e2d9c743e4218ece50895"},{"path":"runtime/core/hellolynk-device-enrollment.mjs","sha256":"f3e99ff2bdfa76e5a830a518792a1b9e5e705d7a8a01eca725dd7c5c8391d4ef"},{"path":"runtime/core/hellolynk-direct-text-e2ee-client.mjs","sha256":"4007bf5e6c91df00adf10384cc1f0d0d28491b8ded518365dddbac717f3ac5be"},{"path":"runtime/core/hellolynk-direct-text-e2ee.mjs","sha256":"f0abc3714cfad007669140ead4bfbb3f5bd56edd24d4389c3addee3f42887a01"},{"path":"runtime/core/hellolynk-host-auth.mjs","sha256":"db1ec56f4e60e6450fba50188eecf89748f39f5d7a75c2456c30a6053233555d"},{"path":"runtime/core/hellolynk-host-protected-store.mjs","sha256":"89b6e6c4ce9c6ba2984f8c301de4251da6004bdd402cc44d578a4505c21b75b1"},{"path":"runtime/core/hellolynk-host-transport-client.mjs","sha256":"9f27d3e44ce8333413e712eb38b970a335b64081d7e3be6882ff5ca921668859"},{"path":"runtime/core/hellolynk-host.mjs","sha256":"6cbe0ba6ec7aa81059a4a2d0e247fbedb6731687ec21ded4aaefa0e79be9e493"},{"path":"runtime/core/hellolynk-human-confirmation-ledger.mjs","sha256":"63bcbbb0870ad83fc031636d74ce77fc070d5f4d1d4c10297f8b3ec9ad85bbf6"},{"path":"runtime/core/hellolynk-human-relationship-controller.mjs","sha256":"7ef584c30febf0e142f621b719e433c0a9f5d976bbb917ab15f6cc1abb39ad52"},{"path":"runtime/core/hellolynk-inbox-read-state.mjs","sha256":"bf2353075f0a10cc3492c0d7309f8d3fef4a4bda1996b878cfbae8515beaeb34"},{"path":"runtime/core/hellolynk-indexed-message-store.mjs","sha256":"61a9d642fb0453aa949c6e634a30ae3f8562a81d3a666580a2f32d414c9f80ad"},{"path":"runtime/core/hellolynk-instance-conversation.mjs","sha256":"f00161cbdab48b33f0be1a809389145c167d8b8bdfab32d8c929db3bc167b4a1"},{"path":"runtime/core/hellolynk-local-contact-requests.mjs","sha256":"9724729b28c4c979696fcd53531e89eddb18a3045e32f602ecfb002af1c44b4c"},{"path":"runtime/core/hellolynk-local-contacts.mjs","sha256":"b7c722f0c300f951ed390ea82aec04975b226f2ea4d5c873764ab36ef9a8bc2c"},{"path":"runtime/core/hellolynk-local-data-migration.mjs","sha256":"1e791114633770fe3955842725965798dfd749e1dbf513f08efc4e01b9ed1756"},{"path":"runtime/core/hellolynk-local-data-protection.mjs","sha256":"1bda879aa0bdf46700a63374e82cc7bc639385656b1463a75a49e8510971066c"},{"path":"runtime/core/hellolynk-local-identity-trust.mjs","sha256":"b6d22715c627820c0ea92ca543cf52bbfeee5d5f416d242c2e21230640310420"},{"path":"runtime/core/hellolynk-local-messaging.mjs","sha256":"23e701818b18b96ba36ad1dfc3c2489d80fec8dafa2f433cf29947175786ed07"},{"path":"runtime/core/hellolynk-local-peer-transport.mjs","sha256":"9c32b2fa5f716f1ff36e09b3f2cd697479acc2f3c6bcb6e96045f5ca65e3b1c6"},{"path":"runtime/core/hellolynk-local-process-lock.mjs","sha256":"5212990a98b9ad2eb83fa2d5fb8a123d687c5ef6daf6cba49a4b6d04a7fe251e"},{"path":"runtime/core/hellolynk-model-inbox.mjs","sha256":"516c846340ee7a2fd624eaedaa51ded81988ef875b8a7eeb15c2e296774bfa63"},{"path":"runtime/core/hellolynk-model-notices.cjs","sha256":"c1b0d9071d3750c87755bc9fdf969d89c7fa62a0dede4c37b8cb2954b81163b0"},{"path":"runtime/core/hellolynk-native-addressing-tools.cjs","sha256":"f4bd81b3d03277e28955a62409383a0c4072c6212567f71425df4e18ece75d63"},{"path":"runtime/core/hellolynk-native-conversations.mjs","sha256":"671030938a5259f6cce0c1eb4e61997f7f89232c677c9ba26062daea91b6f8c6"},{"path":"runtime/core/hellolynk-native-human-confirmation-broker.mjs","sha256":"2fb2d3b40869362be3e40a1ec55947021319af5315cbf8fdc5ed59df717cceb3"},{"path":"runtime/core/hellolynk-native-inbox-runtime.mjs","sha256":"039ba7fe8273357d178556fc57e751c469e2bf0056bcaee5029e7fe376099c72"},{"path":"runtime/core/hellolynk-native-notice.mjs","sha256":"6a5fe50fbccac465d690612839eaf7c10a5622cd84151277b0bf4507eccbe087"},{"path":"runtime/core/hellolynk-native-reply-routes.mjs","sha256":"8ed07580f2b6fe6bff9953951ea79f6c7c1c806887cd0bf21d4893ba8343ebe2"},{"path":"runtime/core/hellolynk-native-worker-lease.mjs","sha256":"e4e6864ff047b1d3511c363eb2bc7a3a3841a453f5d9d40b94bde55cc38cebc5"},{"path":"runtime/core/hellolynk-neutral-host-assembly.mjs","sha256":"d0ac9c697bf8a85263d99a0739da557c62f52c72f4afb105eb97b3aac2ae1f3b"},{"path":"runtime/core/hellolynk-neutral-host-installation-store.mjs","sha256":"dfb6bba4c627082cd6fca8cb38dc786f905e38f3e83ccf91dbfe57e55639e8a2"},{"path":"runtime/core/hellolynk-neutral-host-launcher.mjs","sha256":"789b2531cdbde6e6d8f91f2a40746372e903e9e48e8aa6846b9abf2d28150780"},{"path":"runtime/core/hellolynk-neutral-host-process.mjs","sha256":"e744bacf65f7b86cbcf7d654189c0e07e09401083e2b6f9053b17c1c3bacd1b4"},{"path":"runtime/core/hellolynk-neutral-host-store-adapters.mjs","sha256":"3e425ca2cc111e750f55e94be2561cae8a3b308e473fb549e42da3443b67fd34"},{"path":"runtime/core/hellolynk-neutral-host-workbench-read-model.mjs","sha256":"65ca217dbd5be05f4cf38fd977b0d536526f79463a402fae90a7329dac375670"},{"path":"runtime/core/hellolynk-platform-credential-store.mjs","sha256":"f27f5f377cc4d6d2b5664212cf8fcc4c98d910064c1677ff9c1f776df1a59dba"},{"path":"runtime/core/hellolynk-relay-client-cli.mjs","sha256":"29707c4e0d91d5db6f46408b4c1101b9ab30b117500a9e315da8802e71a43010"},{"path":"runtime/core/hellolynk-release-retention.mjs","sha256":"9b02a42a510fa5ef4a251b6e675f9ccc60f20b718d17c1617027cd048c5634dd"},{"path":"runtime/core/hellolynk-runtime-safety.cjs","sha256":"43d576d9f774409f4a735793c1503a6f397e787b10c59a4ac9cc9257299f5efe"},{"path":"runtime/core/hellolynk-workbench-action-grants.mjs","sha256":"076d1bb848c85c06695440f33daebd853a9f49147a85cf582cc3e2964d95198a"},{"path":"runtime/core/hellolynk-workbench-connection.mjs","sha256":"d3396350fd75af78e60772e021cf6dfb643d9eee41894c5461c959a56650cb60"},{"path":"runtime/neutral-host-bootstrap.mjs","sha256":"db0ffd88a5fbb9091f16ceab4e391ac6919ba2640cdbc358574034779f848d7e"},{"path":"runtime/neutral-host-release-entry.mjs","sha256":"d434d392c85728228772369e9a890cef34598833ab2433dcc7b963c17bf5c146"},{"path":"runtime/neutral-host-release-loader.mjs","sha256":"00b226c65732bcd4d18d2b1b4ebc5092b7073fac52ee500d5d746b01217bfa65"},{"path":"runtime/neutral-host-release-manifest.json","sha256":"379a5532724e4935decd6ffbd7bc6b52cc927c1f910decc406394d9601b55ba3"},{"path":"runtime/neutral-host-release-pin.json","sha256":"8e5b0243291a35d03f82c340be87f91dbf4d6344aaedce5fa529caa32911a8ca"},{"path":"runtime/platform/windows/configure-agent.ps1","sha256":"7dc7c75bf0f7e45060b041a08d502993afe84581040f165e7f4437bf490708fa"},{"path":"runtime/platform/windows/credential-store.ps1","sha256":"d00dae4af08205fffa52c4956d1c87d5c3423e8f20982ccfc1b76e3424fe442e"},{"path":"runtime/platform/windows/hellolynk-host-protected-store.ps1","sha256":"24357e8ce54090b4ec68e457f02c9e834a80f3273ef3c03a8c0fa7258797fb49"},{"path":"runtime/platform/windows/hellolynk-human-confirmation-ledger.ps1","sha256":"4612561e2128dfd96c018f2c2d9ae41016f35bb6df8536314e9f0fb428165a82"},{"path":"runtime/platform/windows/hellolynk-local-data-key.ps1","sha256":"0976a0ecdd724e767b87e65743a230569c3fcb30e2449cf38bb718eb1604c15c"},{"path":"runtime/platform/windows/hellolynk-native-human-confirmation-broker.ps1","sha256":"757a731a3e8761d5d473db19ecfc330783f2826663a0057c4d6896e679d7a388"},{"path":"runtime/workbench/candidate-bootstrap.mjs","sha256":"891b02f750693e5b4836e716922c2d632f6736b2a5b3b7417f161499459f3f56"},{"path":"runtime/workbench/contract.mjs","sha256":"20648c3ed8e20b984b698010855414f8d4acaf0e2ade53b997b5582a85d90a08"},{"path":"runtime/workbench/hellolynk-workbench-build.json","sha256":"43e42633242cb456ecf2a120380230485e4d8533934ad6242089049d9282da11"},{"path":"runtime/workbench/host-capabilities.mjs","sha256":"4e1a82e6cb46dd775ba39e2d34ff21eb1c293523883d18e607084ca91cfffb87"},{"path":"runtime/workbench/i18n.mjs","sha256":"272917746c06cabc1b87b94341f2deca5591f0bea2d7a0e07b2d959d8e1f8c74"},{"path":"runtime/workbench/loopback-surface.mjs","sha256":"6a550034c5dd558dfd22f9cb589fd76df40a99e976538e3b5d01371d212c9aa6"},{"path":"runtime/workbench/mcp-app-bundle.mjs","sha256":"48fb8224cbaa7f78a386a79b2dba761f4de6c4b83b16032f7f96bd9783e172e4"},{"path":"runtime/workbench/service.mjs","sha256":"3bf82a0076e9fe3b62105c626fe0d622092224f28d3905c62eafd65bf5385dcc"},{"path":"runtime/workbench/state.mjs","sha256":"770d10f3bf76236772c87e86f5da346c013da387fb40c08360f895a7052cf7b5"},{"path":"runtime/workbench/transports.mjs","sha256":"0c9f42ca9c9a4b4cc29b1bdcc0a0488d16a9ad06c235c642dff9cd4fc6f0d528"},{"path":"runtime/workbench/ui/app.mjs","sha256":"643a5ac8d303f936ee87dd7c0c851aa1988e99ea9a9a45c6c89da28bdc76e799"},{"path":"runtime/workbench/ui/connection-form.mjs","sha256":"700ca793f5eddca1dfea5f220c73732efc51ea4e1f8b8fc36da2bb67136240f0"},{"path":"runtime/workbench/ui/hellolynk-mark.png","sha256":"108e5c90e1717a87169d317c15f8de33859ed487b06654888047c729d9ab5982"},{"path":"runtime/workbench/ui/http-transport.mjs","sha256":"b2fedbc2c34bcf065e0fc23c8c5fb37d358c03daa2c82ba46530b8dfb8fdc571"},{"path":"runtime/workbench/ui/icons/arrow-left.svg","sha256":"1c527dd347b5fba0312cdcd66cf7514a261855672f7585d1c8b1882f602442a6"},{"path":"runtime/workbench/ui/icons/close.svg","sha256":"22f5c4fb0660601a817ead151c37e82e93d39b2ef4ce1192d66f9099a3c59b36"},{"path":"runtime/workbench/ui/icons/contacts.svg","sha256":"de0add3c43bca68d8cae7736bc3ea8145ca0abb7f32c25127542c6f5a27b3f45"},{"path":"runtime/workbench/ui/icons/inbox.svg","sha256":"e1938770f085e6794a2e22aa3f8e890e083ac341a3c3faa13098a8243dc8306b"},{"path":"runtime/workbench/ui/icons/refresh.svg","sha256":"a7b91e87c1a25d117b1352d2ec131bf6e3fe67df2020af87e0d3575c06d86f29"},{"path":"runtime/workbench/ui/icons/search.svg","sha256":"135df34e348445114a1b88757fe7ef79a6718ffa4cc761c30f8026044552b699"},{"path":"runtime/workbench/ui/icons/security.svg","sha256":"9b6c502b2ce2795530f2e7018e2c24aaaf1cf49472f040868bad148d3321071e"},{"path":"runtime/workbench/ui/icons/settings.svg","sha256":"17b528a15b8187aecd80c4974c7432ec6e58e6a12e062104fae70bf63c46caa2"},{"path":"runtime/workbench/ui/index.html","sha256":"b24cd1f768d5132539722ac7ade3acfe5aa86a47ee16a2adacf3bbf18b70c989"},{"path":"runtime/workbench/ui/loopback-entry.mjs","sha256":"0e5e5d259ab6e2d8408c6d2e089551e6f279dcb1267e9db19f9d9dded0956fd4"},{"path":"runtime/workbench/ui/mcp-app-client.mjs","sha256":"91b1e6e84a12434c2be7614845febfa44afa341d5d7f580bc1bfc106ed37f8f8"},{"path":"runtime/workbench/ui/mcp-app-entry.mjs","sha256":"ba82ac55c4efcf7701bda33b6c6e0df4d59da542b1d6c33c96ba7f2391c4773a"},{"path":"runtime/workbench/ui/styles.css","sha256":"34d24d3d35800a796905049eb5f785f402cf1e82118c66efd4893bd003adbe31"}]}
@@ -1 +1 @@
1
- {"contract":"hellolynk-workbuddy-immutable-package-pin-v1","manifestSha256":"5ec9f5e9ee1c7f44b58e465029b1146918892d71792a62629b83adcccc2d3bcc"}
1
+ {"contract":"hellolynk-workbuddy-immutable-package-pin-v1","manifestSha256":"089faf1216ca42ffad28595e9a4f26bb9df08acbebecc60e61f59e1466b384c7"}