very-happy-cli 0.2.122 → 0.2.124

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 (35) hide show
  1. package/dist/{AcpBackend-pgDnK76l.mjs → AcpBackend-CT9TOBEM.mjs} +1 -1
  2. package/dist/{AcpBackend-YPVwACkW.cjs → AcpBackend-au0veuIF.cjs} +1 -1
  3. package/dist/{AcpSessionManager-6rypahwH.cjs → AcpSessionManager-BCWeBKDd.cjs} +1 -1
  4. package/dist/{AcpSessionManager-Bq5Tiky1.mjs → AcpSessionManager-p1tj7FxF.mjs} +1 -1
  5. package/dist/{config-BTEW041n.mjs → config-DwMic6AC.mjs} +2 -2
  6. package/dist/{config-rQdv_Yr0.cjs → config-GzzqE5Ev.cjs} +2 -2
  7. package/dist/{index-CaIsj1q7.mjs → index-B3-daYaX.mjs} +2 -2
  8. package/dist/{index-BeHr5uMY.mjs → index-Ba6Fu6MJ.mjs} +5 -5
  9. package/dist/{index-BHg0P9cY.cjs → index-C69uF6Up.cjs} +2 -2
  10. package/dist/{index-DKRU6E-x.cjs → index-DI_VC3vJ.cjs} +390 -190
  11. package/dist/{index-uPpFZhhr.cjs → index-DgN9P02i.cjs} +4 -4
  12. package/dist/{index-BTnlYGaP.mjs → index-SQKnWyz-.mjs} +388 -188
  13. package/dist/index.cjs +2 -2
  14. package/dist/index.mjs +2 -2
  15. package/dist/{installTerminalHooks-CGqopr1A.cjs → installTerminalHooks-CvMt8cBI.cjs} +2 -2
  16. package/dist/{installTerminalHooks-DFmKhCto.mjs → installTerminalHooks-Df4hzzdM.mjs} +2 -2
  17. package/dist/lib.cjs +1 -1
  18. package/dist/lib.d.cts +7 -0
  19. package/dist/lib.d.mts +7 -0
  20. package/dist/lib.mjs +1 -1
  21. package/dist/{mcp-DnKBKXYa.mjs → mcp-C0oW5u-b.mjs} +2 -2
  22. package/dist/{mcp-FlbfMw6_.cjs → mcp-DnyLwSPq.cjs} +2 -2
  23. package/dist/{runGemini-DYawZQTu.cjs → runGemini-_FHrxuHN.cjs} +4 -4
  24. package/dist/{runGemini-BsfadDSa.mjs → runGemini-mqLjz-M7.mjs} +4 -4
  25. package/dist/{runOpenClaw-xGtbJ7f8.mjs → runOpenClaw-Bs03yQHe.mjs} +3 -3
  26. package/dist/{runOpenClaw-C2XjFP2m.cjs → runOpenClaw-C5VZQ6Na.cjs} +3 -3
  27. package/dist/{send-B0Wojz18.cjs → send-BD2gTVoP.cjs} +2 -2
  28. package/dist/{send-DRZppEr2.mjs → send-BaLjQPZQ.mjs} +2 -2
  29. package/dist/{sessions-CTuUV0TW.cjs → sessions-B108j_Xj.cjs} +2 -2
  30. package/dist/{sessions-BuMgxuxd.mjs → sessions-ggBePfSY.mjs} +2 -2
  31. package/dist/{spawn-BRdfNDsu.mjs → spawn-CORFRb9D.mjs} +2 -2
  32. package/dist/{spawn-7U_4QTHw.cjs → spawn-iI8w8sD7.cjs} +2 -2
  33. package/dist/{types-Jag0GwhO.cjs → types-CZIwVSN2.cjs} +138 -14
  34. package/dist/{types-q7wtjfxb.mjs → types-gDOmwOKw.mjs} +137 -14
  35. package/package.json +7 -7
@@ -29,7 +29,7 @@ import { SandboxManager } from '@anthropic-ai/sandbox-runtime';
29
29
  import { Expo } from 'expo-server-sdk';
30
30
 
31
31
  var name = "very-happy-cli";
32
- var version = "0.2.122";
32
+ var version = "0.2.124";
33
33
  var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
34
34
  var author = "Kirill Dubovitskiy";
35
35
  var contributors = [
@@ -142,12 +142,12 @@ var dependencies = {
142
142
  zod: "^4.0.0"
143
143
  };
144
144
  var optionalDependencies = {
145
- "very-happy-tools-arm64-darwin": "0.2.122",
146
- "very-happy-tools-x64-darwin": "0.2.122",
147
- "very-happy-tools-arm64-linux": "0.2.122",
148
- "very-happy-tools-x64-linux": "0.2.122",
149
- "very-happy-tools-arm64-win32": "0.2.122",
150
- "very-happy-tools-x64-win32": "0.2.122"
145
+ "very-happy-tools-arm64-darwin": "0.2.124",
146
+ "very-happy-tools-x64-darwin": "0.2.124",
147
+ "very-happy-tools-arm64-linux": "0.2.124",
148
+ "very-happy-tools-x64-linux": "0.2.124",
149
+ "very-happy-tools-arm64-win32": "0.2.124",
150
+ "very-happy-tools-x64-win32": "0.2.124"
151
151
  };
152
152
  var devDependencies = {
153
153
  "@slopus/happy-wire": "workspace:*",
@@ -1019,6 +1019,8 @@ const ConnectionDiagnosticEventSchema = z$1.object({
1019
1019
  durationMs: z$1.number().int().min(0).max(3e5),
1020
1020
  deviceClass: z$1.enum(["mobile", "desktop", "unknown"]),
1021
1021
  visibility: z$1.enum(["visible", "hidden"]),
1022
+ relayRegion: z$1.enum(["central", "sg", "us", "other", "unknown"]).optional(),
1023
+ timing: z$1.enum(["active", "background", "censored", "unknown"]).optional(),
1022
1024
  client: z$1.string().regex(/^web\/(?:[a-f0-9]{7,40}|unknown)$/)
1023
1025
  }).strict();
1024
1026
  z$1.object({
@@ -1073,6 +1075,7 @@ const CliUpdateStateSchema = z$1.object({
1073
1075
  /** B-351: the version this machine may install by itself. Pinned separately
1074
1076
  * from `recommendedVersion`; null means no unattended install. */
1075
1077
  autoUpdateVersion: z$1.string().nullable().optional(),
1078
+ retrySupported: z$1.boolean().optional(),
1076
1079
  checkedAt: z$1.number(),
1077
1080
  /**
1078
1081
  * B-321: a new bundle is on disk but refused to run, so the daemon is still
@@ -13196,6 +13199,18 @@ function isUserPrompt(parsed) {
13196
13199
  const content = parsed.message?.content;
13197
13200
  return typeof content === "string";
13198
13201
  }
13202
+ function hasPromptAttachments(parsed) {
13203
+ const content = parsed.message?.content;
13204
+ return typeof content === "string" && content.includes("<attached_files>") || Array.isArray(content) && content.some((block) => block?.type !== "text" || typeof block.text === "string" && block.text.includes("<attached_files>"));
13205
+ }
13206
+ function userPromptText(parsed) {
13207
+ if (parsed?.type !== "user" || parsed.isSidechain || parsed.isMeta || parsed.isSynthetic) return null;
13208
+ const content = parsed.message?.content;
13209
+ if (typeof content === "string") return content.trim() ? content : null;
13210
+ if (!Array.isArray(content) || content.some((block) => block?.type === "tool_result")) return null;
13211
+ const text = content.filter((block) => block?.type === "text" && typeof block.text === "string").map((block) => block.text).join("\n");
13212
+ return text.trim() ? text : null;
13213
+ }
13199
13214
  async function discardForkedSession(projectDir, claudeSessionId) {
13200
13215
  try {
13201
13216
  await unlink$1(jsonlPath(projectDir, claudeSessionId));
@@ -13295,23 +13310,68 @@ async function listClaudeRewindPoints(projectDir, claudeSessionId) {
13295
13310
  } catch {
13296
13311
  continue;
13297
13312
  }
13298
- if (parsed?.type !== "user") continue;
13299
- if (parsed.isSidechain) continue;
13313
+ const content = userPromptText(parsed);
13314
+ if (content === null) continue;
13300
13315
  if (typeof parsed.uuid !== "string" || parsed.uuid.length === 0) continue;
13301
- const content = parsed.message?.content;
13302
- if (typeof content !== "string") continue;
13303
- const trimmed = content.trim();
13304
- if (trimmed.length === 0) continue;
13305
13316
  const timestampRaw = parsed.timestamp;
13306
13317
  const timestamp = typeof timestampRaw === "string" ? Date.parse(timestampRaw) : typeof timestampRaw === "number" ? timestampRaw : Date.now();
13307
13318
  points.push({
13308
13319
  uuid: parsed.uuid,
13309
13320
  text: content,
13321
+ ...hasPromptAttachments(parsed) ? { hasAttachments: true } : {},
13310
13322
  timestamp: Number.isFinite(timestamp) ? timestamp : Date.now()
13311
13323
  });
13312
13324
  }
13313
13325
  return points;
13314
13326
  }
13327
+ async function forkBeforeUserMessage(projectDir, sourceClaudeSessionId, cutBeforeUuid) {
13328
+ const src = jsonlPath(projectDir, sourceClaudeSessionId);
13329
+ let raw;
13330
+ try {
13331
+ raw = await readFile$1(src, "utf-8");
13332
+ } catch (error) {
13333
+ if (error.code === "ENOENT") throw new ForkSourceMissingError(src);
13334
+ throw error;
13335
+ }
13336
+ const lines = raw.split("\n");
13337
+ let hasPreviousConversation = false;
13338
+ let hasPreviousPrompt = false;
13339
+ let cut = -1;
13340
+ for (let i = 0; i < lines.length; i++) {
13341
+ let entry;
13342
+ try {
13343
+ entry = JSON.parse(lines[i]);
13344
+ } catch {
13345
+ continue;
13346
+ }
13347
+ if (userPromptText(entry) !== null && entry.uuid === cutBeforeUuid) {
13348
+ if (hasPromptAttachments(entry)) throw new Error("Cannot edit and rerun a message with attachments");
13349
+ cut = i;
13350
+ break;
13351
+ }
13352
+ if (!entry?.isSidechain && !entry?.isMeta && !entry?.isSynthetic && (entry?.type === "user" || entry?.type === "assistant")) {
13353
+ hasPreviousConversation = true;
13354
+ const content = entry.message?.content;
13355
+ if (entry.type === "user" && (typeof content === "string" || Array.isArray(content) && content.length > 0 && !content.some((block) => block?.type === "tool_result"))) {
13356
+ hasPreviousPrompt = true;
13357
+ }
13358
+ }
13359
+ }
13360
+ if (cut < 0) throw new ForkTruncateUuidNotFoundError(cutBeforeUuid, src);
13361
+ if (!hasPreviousConversation) return null;
13362
+ if (!hasPreviousPrompt) throw new Error("Cannot safely rewind: earlier history has no user prompt");
13363
+ const newId = randomUUID$1();
13364
+ const destination = jsonlPath(projectDir, newId);
13365
+ const temporary = `${destination}.tmp-${process.pid}`;
13366
+ try {
13367
+ await writeFile(temporary, lines.slice(0, cut).join("\n") + "\n", { encoding: "utf-8", flag: "wx" });
13368
+ await rename$1(temporary, destination);
13369
+ } catch (error) {
13370
+ await unlink$1(temporary).catch(() => void 0);
13371
+ throw error;
13372
+ }
13373
+ return newId;
13374
+ }
13315
13375
 
13316
13376
  function serializedByteLength(value) {
13317
13377
  try {
@@ -14588,6 +14648,14 @@ class CodexForkRewindPointNotFoundError extends Error {
14588
14648
  this.name = "CodexForkRewindPointNotFoundError";
14589
14649
  }
14590
14650
  }
14651
+ function hasUserAttachments(item) {
14652
+ const content = item.content;
14653
+ return Array.isArray(content) && content.some((part) => !part || typeof part !== "object" || part.type !== "text" || typeof part.text === "string" && part.text.includes("<attached_files>"));
14654
+ }
14655
+ function rejectAttachedTarget(thread, itemId) {
14656
+ const item = thread.turns?.flatMap((turn) => turn.items ?? []).find((item2) => item2.id === itemId);
14657
+ if (item && hasUserAttachments(item)) throw new Error("Cannot edit and rerun a message with attachments");
14658
+ }
14591
14659
  function textFromUserItem(item) {
14592
14660
  if (item.type !== "userMessage") {
14593
14661
  return null;
@@ -14614,6 +14682,7 @@ function listCodexRewindPoints(thread) {
14614
14682
  points.push({
14615
14683
  itemId: item.id,
14616
14684
  text,
14685
+ ...hasUserAttachments(item) ? { hasAttachments: true } : {},
14617
14686
  timestamp: timestampFromTurn(turn)
14618
14687
  });
14619
14688
  }
@@ -14671,6 +14740,37 @@ async function forkCodexThread(client, opts) {
14671
14740
  newCodexThreadId: forked.threadId
14672
14741
  };
14673
14742
  }
14743
+ async function forkCodexBeforeUserMessage(client, opts) {
14744
+ const { thread: source } = await client.readThread({ threadId: opts.threadId, includeTurns: true });
14745
+ rejectAttachedTarget(source, opts.cutBeforeItemId);
14746
+ const sourceCut = findCutTurn(source, opts.cutBeforeItemId);
14747
+ if (!sourceCut) throw new CodexForkRewindPointNotFoundError(opts.cutBeforeItemId, opts.threadId);
14748
+ if ((source.turns?.[sourceCut.index].items ?? []).findIndex((item) => item.id === opts.cutBeforeItemId) !== 0) {
14749
+ throw new Error("Cannot safely rewind a user message inside an existing turn");
14750
+ }
14751
+ if (sourceCut.index === 0) return { type: "success", startFresh: true };
14752
+ const forked = await client.forkThread({ threadId: opts.threadId, cwd: opts.cwd });
14753
+ if (forked.threadId === opts.threadId) throw new Error("Codex did not create an independent fork");
14754
+ rejectAttachedTarget(forked.thread, opts.cutBeforeItemId);
14755
+ const cut = findCutTurn(forked.thread, opts.cutBeforeItemId);
14756
+ if (!cut) throw new CodexForkRewindPointNotFoundError(opts.cutBeforeItemId, opts.threadId);
14757
+ const turns = forked.thread.turns ?? [];
14758
+ const items = turns[cut.index].items ?? [];
14759
+ if (items.findIndex((item) => item.id === opts.cutBeforeItemId) !== 0) {
14760
+ throw new Error("Cannot safely rewind a user message inside an existing turn");
14761
+ }
14762
+ if (cut.index === 0) return { type: "success", startFresh: true };
14763
+ const expectedTurnIds = turns.slice(0, cut.index).map((turn) => turn.id);
14764
+ const { thread } = await client.rollbackThread({
14765
+ threadId: forked.threadId,
14766
+ numTurns: turns.length - cut.index
14767
+ });
14768
+ const remaining = thread.turns ?? [];
14769
+ if (remaining.length !== cut.index || remaining.some((turn, index) => turn.id !== expectedTurnIds[index])) {
14770
+ throw new Error("Codex rollback did not preserve the expected history");
14771
+ }
14772
+ return { type: "success", newCodexThreadId: forked.threadId };
14773
+ }
14674
14774
 
14675
14775
  const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
14676
14776
  function requireNonEmptyString(value, name) {
@@ -14803,6 +14903,9 @@ class ApiMachineClient {
14803
14903
  encTerminalData(dataBase64) {
14804
14904
  return encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, dataBase64));
14805
14905
  }
14906
+ setCliUpdateRetryHandler(handler) {
14907
+ this.rpcHandlerManager.registerHandler("cli-update-retry", (params) => handler(params && typeof params === "object" ? params.version : void 0));
14908
+ }
14806
14909
  /** Cache the latest relay policy locally and publish it now or on the next
14807
14910
  * socket connect. This makes startup/offline races harmless. */
14808
14911
  setCliUpdateState(state) {
@@ -15172,6 +15275,26 @@ class ApiMachineClient {
15172
15275
  throw error;
15173
15276
  }
15174
15277
  });
15278
+ this.rpcHandlerManager.registerHandler("claude-rewind-before-message", async (params) => {
15279
+ const directory = requireNonEmptyString(params?.directory, "directory");
15280
+ const claudeSessionId = requireNonEmptyString(params?.claudeSessionId, "claudeSessionId");
15281
+ const cutBeforeUuid = requireNonEmptyString(params?.cutBeforeUuid, "cutBeforeUuid");
15282
+ if (!UUID_RE.test(claudeSessionId) || !UUID_RE.test(cutBeforeUuid)) {
15283
+ throw new Error("claudeSessionId and cutBeforeUuid must be valid UUIDs");
15284
+ }
15285
+ const newClaudeSessionId = await forkBeforeUserMessage(getProjectPath(directory), claudeSessionId, cutBeforeUuid);
15286
+ return newClaudeSessionId === null ? { type: "success", startFresh: true } : { type: "success", newClaudeSessionId };
15287
+ });
15288
+ this.rpcHandlerManager.registerHandler("codex-rewind-before-message", async (params) => {
15289
+ const directory = requireNonEmptyString(params?.directory, "directory");
15290
+ const codexThreadId = requireNonEmptyString(params?.codexThreadId, "codexThreadId");
15291
+ const cutBeforeItemId = requireNonEmptyString(params?.cutBeforeItemId, "cutBeforeItemId");
15292
+ return withCodexAppServerClient((client) => forkCodexBeforeUserMessage(client, {
15293
+ threadId: codexThreadId,
15294
+ cwd: directory,
15295
+ cutBeforeItemId
15296
+ }));
15297
+ });
15175
15298
  this.rpcHandlerManager.registerHandler("stop-daemon", () => {
15176
15299
  logger.debug("[API MACHINE] Received stop-daemon RPC request");
15177
15300
  setTimeout(() => {
@@ -16814,4 +16937,4 @@ const RawJSONLinesSchema = z$1.discriminatedUnion("type", [
16814
16937
  }).passthrough()
16815
16938
  ]);
16816
16939
 
16817
- export { scrubTmuxClientEnv as $, ApiClient as A, commandOnPath as B, readCredentials as C, credentialRelayProblem as D, deriveLocalCliUpdateSummary as E, readSettingsOutcome as F, updateSettings as G, encodeBase64Url as H, InvalidateSync as I, decodeBase64 as J, writeCredentialsLegacy as K, writeCredentialsDataKey as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, readCredentialsForConfiguredRelay as N, encrypt as O, isClaudeSessionId as P, getLocalHappyAgentCredentialPath as Q, RawJSONLinesSchema as R, STREAM_DELTA_MAX_CHARS as S, readLocalHappyAgentCredentials as T, decryptWithDataKey as U, decryptLegacy as V, compareExactVersions as W, extractCompleteLines as X, decideBackfill as Y, parseTerminalHookPayload as Z, tmuxArgs as _, ApiSessionClient as a, decideMirrorBinding as a0, MIRROR_BACKFILL_LINES_DEFAULT as a1, persistSession as a2, mirrorLineKey as a3, mirrorLocalId as a4, detectCLIAvailability as a5, detectResumeSupport as a6, acquireDaemonLock as a7, summarizeSpawnSessionForLog as a8, deletePersistedSessions as a9, shellescape as aa, decrypt as ab, writeDaemonState as ac, writeSettings as ad, fetchCliUpdateState as ae, resolveCliUpdateCheckInterval as af, DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS as ag, releaseDaemonLock as ah, listVhTerminals as ai, isValidTerminalId as aj, readVhTerminal as ak, sendToVhTerminal as al, TITLE_PROMPT_PREFIX as am, BOARD_ANALYZER_PROMPT_PREFIX as an, startOfflineReconnection as ao, clearCredentials as ap, clearMachineId as aq, SandboxConfigSchema as ar, CodexAppServerClient as as, getLatestDaemonLog as at, persistence as au, api as av, createEnvelope as b, configuration as c, connectionState as d, readSettings as e, encodeBase64 as f, contentLogMetadata as g, errorLogMetadata as h, isValidSessionId as i, packageJson as j, delay as k, logger as l, ensurePrivateDirectorySync as m, hardenPrivateFileSync as n, readDaemonState as o, projectPath as p, clearDaemonState as q, readPersistedSessions as r, streamKeyOf as s, getProjectPath as t, initializeSandbox as u, wrapCommand as v, writePrivateFileSync as w, AsyncLock as x, ensurePrivateDirectory as y, hardenPrivateFile as z };
16940
+ export { tmuxArgs as $, ApiClient as A, commandOnPath as B, readCredentials as C, credentialRelayProblem as D, deriveLocalCliUpdateSummary as E, readSettingsOutcome as F, updateSettings as G, encodeBase64Url as H, InvalidateSync as I, decodeBase64 as J, writeCredentialsLegacy as K, writeCredentialsDataKey as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, readCredentialsForConfiguredRelay as N, encrypt as O, isClaudeSessionId as P, getLocalHappyAgentCredentialPath as Q, RawJSONLinesSchema as R, STREAM_DELTA_MAX_CHARS as S, readLocalHappyAgentCredentials as T, decryptWithDataKey as U, decryptLegacy as V, parseExactVersion as W, compareExactVersions as X, extractCompleteLines as Y, decideBackfill as Z, parseTerminalHookPayload as _, ApiSessionClient as a, scrubTmuxClientEnv as a0, decideMirrorBinding as a1, MIRROR_BACKFILL_LINES_DEFAULT as a2, persistSession as a3, mirrorLineKey as a4, mirrorLocalId as a5, detectCLIAvailability as a6, detectResumeSupport as a7, acquireDaemonLock as a8, summarizeSpawnSessionForLog as a9, deletePersistedSessions as aa, shellescape as ab, decrypt as ac, writeDaemonState as ad, writeSettings as ae, fetchCliUpdateState as af, resolveCliUpdateCheckInterval as ag, DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS as ah, releaseDaemonLock as ai, listVhTerminals as aj, isValidTerminalId as ak, readVhTerminal as al, sendToVhTerminal as am, TITLE_PROMPT_PREFIX as an, BOARD_ANALYZER_PROMPT_PREFIX as ao, startOfflineReconnection as ap, clearCredentials as aq, clearMachineId as ar, SandboxConfigSchema as as, CodexAppServerClient as at, getLatestDaemonLog as au, persistence as av, api as aw, createEnvelope as b, configuration as c, connectionState as d, readSettings as e, encodeBase64 as f, contentLogMetadata as g, errorLogMetadata as h, isValidSessionId as i, packageJson as j, delay as k, logger as l, ensurePrivateDirectorySync as m, hardenPrivateFileSync as n, readDaemonState as o, projectPath as p, clearDaemonState as q, readPersistedSessions as r, streamKeyOf as s, getProjectPath as t, initializeSandbox as u, wrapCommand as v, writePrivateFileSync as w, AsyncLock as x, ensurePrivateDirectory as y, hardenPrivateFile as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "very-happy-cli",
3
- "version": "0.2.122",
3
+ "version": "0.2.124",
4
4
  "description": "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.",
5
5
  "author": "Kirill Dubovitskiy",
6
6
  "contributors": [
@@ -113,12 +113,12 @@
113
113
  "zod": "^4.0.0"
114
114
  },
115
115
  "optionalDependencies": {
116
- "very-happy-tools-arm64-darwin": "0.2.122",
117
- "very-happy-tools-x64-darwin": "0.2.122",
118
- "very-happy-tools-arm64-linux": "0.2.122",
119
- "very-happy-tools-x64-linux": "0.2.122",
120
- "very-happy-tools-arm64-win32": "0.2.122",
121
- "very-happy-tools-x64-win32": "0.2.122"
116
+ "very-happy-tools-arm64-darwin": "0.2.124",
117
+ "very-happy-tools-x64-darwin": "0.2.124",
118
+ "very-happy-tools-arm64-linux": "0.2.124",
119
+ "very-happy-tools-x64-linux": "0.2.124",
120
+ "very-happy-tools-arm64-win32": "0.2.124",
121
+ "very-happy-tools-x64-win32": "0.2.124"
122
122
  },
123
123
  "devDependencies": {
124
124
  "@slopus/happy-wire": "workspace:*",