varlock 1.3.0 → 1.4.0

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 (101) hide show
  1. package/dist/audit.command-PXY2ZGU2.js +16 -0
  2. package/dist/{audit.command-LLD5UIAW.js.map → audit.command-PXY2ZGU2.js.map} +1 -1
  3. package/dist/{chunk-HMWAOBZR.js → chunk-2GZ4APXU.js} +7 -7
  4. package/dist/{chunk-HMWAOBZR.js.map → chunk-2GZ4APXU.js.map} +1 -1
  5. package/dist/{chunk-XXSPHSF7.js → chunk-66VKZYD7.js} +6 -6
  6. package/dist/{chunk-XXSPHSF7.js.map → chunk-66VKZYD7.js.map} +1 -1
  7. package/dist/{chunk-MPHVA4WC.js → chunk-7VERU3F7.js} +3 -3
  8. package/dist/{chunk-MPHVA4WC.js.map → chunk-7VERU3F7.js.map} +1 -1
  9. package/dist/{chunk-RQZZDYWL.js → chunk-A5L3SRQS.js} +7 -7
  10. package/dist/{chunk-RQZZDYWL.js.map → chunk-A5L3SRQS.js.map} +1 -1
  11. package/dist/{chunk-WTBUNHUJ.js → chunk-DQTUCLA7.js} +5 -5
  12. package/dist/{chunk-WTBUNHUJ.js.map → chunk-DQTUCLA7.js.map} +1 -1
  13. package/dist/{chunk-NW4KR67N.js → chunk-EGFAEO7L.js} +7 -7
  14. package/dist/{chunk-NW4KR67N.js.map → chunk-EGFAEO7L.js.map} +1 -1
  15. package/dist/{chunk-WJLMLKSG.js → chunk-F64DA7XN.js} +6 -6
  16. package/dist/{chunk-WJLMLKSG.js.map → chunk-F64DA7XN.js.map} +1 -1
  17. package/dist/{chunk-4A54P4EM.js → chunk-MGUGRIW2.js} +1185 -1152
  18. package/dist/chunk-MGUGRIW2.js.map +1 -0
  19. package/dist/{chunk-F6ZYIWAR.js → chunk-N7FJTNE5.js} +11 -5
  20. package/dist/chunk-N7FJTNE5.js.map +1 -0
  21. package/dist/{chunk-XUY3HAO2.js → chunk-NHNQJTPB.js} +4 -4
  22. package/dist/{chunk-XUY3HAO2.js.map → chunk-NHNQJTPB.js.map} +1 -1
  23. package/dist/{chunk-INGOLNLE.js → chunk-NZTQKZND.js} +4 -4
  24. package/dist/{chunk-INGOLNLE.js.map → chunk-NZTQKZND.js.map} +1 -1
  25. package/dist/{chunk-YWTIKDGU.js → chunk-P4HNABAM.js} +98 -20
  26. package/dist/chunk-P4HNABAM.js.map +1 -0
  27. package/dist/{chunk-GKN3UJNE.js → chunk-PBWMMYWL.js} +520 -373
  28. package/dist/chunk-PBWMMYWL.js.map +1 -0
  29. package/dist/{chunk-C5LW5EET.js → chunk-Q4I7MXFB.js} +5 -5
  30. package/dist/{chunk-C5LW5EET.js.map → chunk-Q4I7MXFB.js.map} +1 -1
  31. package/dist/{chunk-GJ7PTJM4.js → chunk-Q7XUQDLE.js} +3 -3
  32. package/dist/{chunk-GJ7PTJM4.js.map → chunk-Q7XUQDLE.js.map} +1 -1
  33. package/dist/{chunk-IO2OGZQU.js → chunk-ROZITJAP.js} +7 -7
  34. package/dist/{chunk-IO2OGZQU.js.map → chunk-ROZITJAP.js.map} +1 -1
  35. package/dist/{chunk-CESFJIM4.js → chunk-RTKFINP6.js} +6 -6
  36. package/dist/{chunk-CESFJIM4.js.map → chunk-RTKFINP6.js.map} +1 -1
  37. package/dist/{chunk-5DRCCFKV.js → chunk-RWXFFQWH.js} +4 -4
  38. package/dist/{chunk-5DRCCFKV.js.map → chunk-RWXFFQWH.js.map} +1 -1
  39. package/dist/{chunk-JOGGSYT2.js → chunk-SX2NUZCL.js} +3 -3
  40. package/dist/{chunk-JOGGSYT2.js.map → chunk-SX2NUZCL.js.map} +1 -1
  41. package/dist/{chunk-KI5QLKPU.js → chunk-T3NMDBCU.js} +5 -5
  42. package/dist/{chunk-KI5QLKPU.js.map → chunk-T3NMDBCU.js.map} +1 -1
  43. package/dist/{chunk-HH647LSU.js → chunk-YZCCCHDD.js} +6 -6
  44. package/dist/{chunk-HH647LSU.js.map → chunk-YZCCCHDD.js.map} +1 -1
  45. package/dist/{chunk-OGGTDFVX.js → chunk-ZCYV47TZ.js} +7 -7
  46. package/dist/{chunk-OGGTDFVX.js.map → chunk-ZCYV47TZ.js.map} +1 -1
  47. package/dist/cli/cli-executable.js +1545 -38
  48. package/dist/cli/cli-executable.js.map +1 -1
  49. package/dist/config-item-HMRJLPJY.js +7 -0
  50. package/dist/{config-item-SQFJ2BJ2.js.map → config-item-HMRJLPJY.js.map} +1 -1
  51. package/dist/encrypt.command-7M34IUJY.js +14 -0
  52. package/dist/{encrypt.command-WISNYCTG.js.map → encrypt.command-7M34IUJY.js.map} +1 -1
  53. package/dist/explain.command-LZJOP4TM.js +15 -0
  54. package/dist/{explain.command-THO6CRHD.js.map → explain.command-LZJOP4TM.js.map} +1 -1
  55. package/dist/help.command-VIBYZWCF.js +5 -0
  56. package/dist/{help.command-7E52XAOO.js.map → help.command-VIBYZWCF.js.map} +1 -1
  57. package/dist/index.js +6 -6
  58. package/dist/init.command-FFORG2JL.js +14 -0
  59. package/dist/{init.command-3EDACW36.js.map → init.command-FFORG2JL.js.map} +1 -1
  60. package/dist/install-plugin.command-SFNHDKVE.js +13 -0
  61. package/dist/{install-plugin.command-MXBZTBTE.js.map → install-plugin.command-SFNHDKVE.js.map} +1 -1
  62. package/dist/load.command-V3C5H6CZ.js +15 -0
  63. package/dist/{load.command-XRABTXAE.js.map → load.command-V3C5H6CZ.js.map} +1 -1
  64. package/dist/lock.command-QQV2S6NY.js +7 -0
  65. package/dist/{lock.command-O5MPBQ2I.js.map → lock.command-QQV2S6NY.js.map} +1 -1
  66. package/dist/printenv.command-2BIP7FCF.js +15 -0
  67. package/dist/{printenv.command-DLCI4IPZ.js.map → printenv.command-2BIP7FCF.js.map} +1 -1
  68. package/dist/reveal.command-7LHNCYS4.js +15 -0
  69. package/dist/{reveal.command-6BTK3FJZ.js.map → reveal.command-7LHNCYS4.js.map} +1 -1
  70. package/dist/run.command-TRSRYDOM.js +16 -0
  71. package/dist/{run.command-5CIHZECD.js.map → run.command-TRSRYDOM.js.map} +1 -1
  72. package/dist/{scan.command-PW3OOLQY.js → scan.command-NMBEPFUC.js} +9 -9
  73. package/dist/{scan.command-PW3OOLQY.js.map → scan.command-NMBEPFUC.js.map} +1 -1
  74. package/dist/telemetry.command-SMIT5ZZB.js +13 -0
  75. package/dist/{telemetry.command-TZDNG2WR.js.map → telemetry.command-SMIT5ZZB.js.map} +1 -1
  76. package/dist/typegen.command-C5KWLYPL.js +14 -0
  77. package/dist/{typegen.command-QD26Q3MP.js.map → typegen.command-C5KWLYPL.js.map} +1 -1
  78. package/native-bins/darwin/VarlockEnclave.app/Contents/CodeResources +0 -0
  79. package/native-bins/darwin/VarlockEnclave.app/Contents/MacOS/varlock-local-encrypt +0 -0
  80. package/native-bins/linux-arm64/varlock-local-encrypt +0 -0
  81. package/native-bins/linux-x64/varlock-local-encrypt +0 -0
  82. package/native-bins/win32-x64/varlock-local-encrypt.exe +0 -0
  83. package/package.json +4 -3
  84. package/dist/audit.command-LLD5UIAW.js +0 -16
  85. package/dist/chunk-4A54P4EM.js.map +0 -1
  86. package/dist/chunk-F6ZYIWAR.js.map +0 -1
  87. package/dist/chunk-GKN3UJNE.js.map +0 -1
  88. package/dist/chunk-YWTIKDGU.js.map +0 -1
  89. package/dist/config-item-SQFJ2BJ2.js +0 -7
  90. package/dist/encrypt.command-WISNYCTG.js +0 -14
  91. package/dist/explain.command-THO6CRHD.js +0 -15
  92. package/dist/help.command-7E52XAOO.js +0 -5
  93. package/dist/init.command-3EDACW36.js +0 -14
  94. package/dist/install-plugin.command-MXBZTBTE.js +0 -13
  95. package/dist/load.command-XRABTXAE.js +0 -15
  96. package/dist/lock.command-O5MPBQ2I.js +0 -7
  97. package/dist/printenv.command-DLCI4IPZ.js +0 -15
  98. package/dist/reveal.command-6BTK3FJZ.js +0 -15
  99. package/dist/run.command-5CIHZECD.js +0 -16
  100. package/dist/telemetry.command-TZDNG2WR.js +0 -13
  101. package/dist/typegen.command-QD26Q3MP.js +0 -14
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/helpers/js-package-manager-utils.ts","../src/cli/helpers/pretty-format.ts"],"names":[],"mappings":"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","file":"chunk-INGOLNLE.js","sourcesContent":["// Re-exports for backward compatibility - prefer importing from lib/workspace-utils directly\nexport {\n JS_PACKAGE_MANAGERS,\n detectWorkspaceInfo,\n getWorkspaceInfo,\n runWithWorkspaceInfo,\n type JsPackageManager,\n type JsPackageManagerMeta,\n type WorkspaceInfo,\n type MonorepoTool,\n} from '../../lib/workspace-utils';\n\nimport path from 'node:path';\nimport fs, { existsSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { CliExitError } from './exit-error';\nimport { detectWorkspaceInfo, type JsPackageManager } from '../../lib/workspace-utils';\n\nexport function detectJsPackageManager(opts?: {\n cwd?: string,\n exitIfNotFound?: boolean,\n}) {\n const info = detectWorkspaceInfo({ cwd: opts?.cwd });\n if (!info) {\n if (opts?.exitIfNotFound) {\n throw new CliExitError('Unable to detect your JavaScript package manager!', {\n suggestion: 'We look for lock files (ex: package-lock.json) so you may just need to run a dependency install (ie `npm install`)',\n forceExit: true,\n });\n }\n return undefined;\n }\n return info.packageManager;\n}\n\nexport function installJsDependency(opts: {\n packageName: string,\n packageManager: JsPackageManager,\n packagePath?: string,\n isMonoRepoRoot?: boolean,\n}) {\n const packageJsonPath = path.join(opts.packagePath || process.cwd(), 'package.json');\n\n // for now, we'll just bail if we dont see a package.json\n if (!existsSync(packageJsonPath)) return false;\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n // bail if already installed\n if (packageJson.dependencies?.varlock) return false;\n\n // TODO: might want to check first if it's already installed?\n execSync([\n // move to the correct directory if needed\n opts.packagePath && `cd ${opts.packagePath} &&`,\n // `add` works in all of them\n `${opts.packageManager} add ${opts.packageName}`,\n // tells pnpm to either install in the workspace root explicitly\n // or to not check if we are the in the root\n opts.packageManager === 'pnpm' && (opts.isMonoRepoRoot ? '-w' : '--ignore-workspace-root-check'),\n ].filter(Boolean).join(' '));\n\n return true;\n}\n","import ansis from 'ansis';\nimport { detectJsPackageManager, type JsPackageManagerMeta } from './js-package-manager-utils';\n\n\nexport const fmt = {\n decorator: (s: string) => ansis.magenta(s),\n filePath: (s: string) => `📂 ${ansis.cyan.italic(s)}`,\n fileName: (s: string) => `${ansis.cyan.italic(s)}`,\n command: (s: string, opts?: { jsPackageManager?: JsPackageManagerMeta | true }) => {\n let jsPackageManager: JsPackageManagerMeta | undefined;\n if (opts?.jsPackageManager === true) {\n jsPackageManager = detectJsPackageManager();\n } else if (opts?.jsPackageManager) {\n jsPackageManager = opts.jsPackageManager;\n }\n if (jsPackageManager) {\n s = `${jsPackageManager.exec} ${s}`;\n }\n return ansis.green.italic(s);\n },\n packageName: (s: string) => ansis.green.italic(s),\n};\n\nexport const logLines = (lines: Array<string | false | undefined>) => {\n for (const line of lines) {\n // skip false, null, undefined, but not empty strings\n if (!line && line !== '') continue;\n console.log(line);\n }\n};\n"]}
1
+ {"version":3,"sources":["../src/cli/helpers/js-package-manager-utils.ts","../src/cli/helpers/pretty-format.ts"],"names":[],"mappings":"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","file":"chunk-NZTQKZND.js","sourcesContent":["// Re-exports for backward compatibility - prefer importing from lib/workspace-utils directly\nexport {\n JS_PACKAGE_MANAGERS,\n detectWorkspaceInfo,\n getWorkspaceInfo,\n runWithWorkspaceInfo,\n type JsPackageManager,\n type JsPackageManagerMeta,\n type WorkspaceInfo,\n type MonorepoTool,\n} from '../../lib/workspace-utils';\n\nimport path from 'node:path';\nimport fs, { existsSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { CliExitError } from './exit-error';\nimport { detectWorkspaceInfo, type JsPackageManager } from '../../lib/workspace-utils';\n\nexport function detectJsPackageManager(opts?: {\n cwd?: string,\n exitIfNotFound?: boolean,\n}) {\n const info = detectWorkspaceInfo({ cwd: opts?.cwd });\n if (!info) {\n if (opts?.exitIfNotFound) {\n throw new CliExitError('Unable to detect your JavaScript package manager!', {\n suggestion: 'We look for lock files (ex: package-lock.json) so you may just need to run a dependency install (ie `npm install`)',\n forceExit: true,\n });\n }\n return undefined;\n }\n return info.packageManager;\n}\n\nexport function installJsDependency(opts: {\n packageName: string,\n packageManager: JsPackageManager,\n packagePath?: string,\n isMonoRepoRoot?: boolean,\n}) {\n const packageJsonPath = path.join(opts.packagePath || process.cwd(), 'package.json');\n\n // for now, we'll just bail if we dont see a package.json\n if (!existsSync(packageJsonPath)) return false;\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n // bail if already installed\n if (packageJson.dependencies?.varlock) return false;\n\n // TODO: might want to check first if it's already installed?\n execSync([\n // move to the correct directory if needed\n opts.packagePath && `cd ${opts.packagePath} &&`,\n // `add` works in all of them\n `${opts.packageManager} add ${opts.packageName}`,\n // tells pnpm to either install in the workspace root explicitly\n // or to not check if we are the in the root\n opts.packageManager === 'pnpm' && (opts.isMonoRepoRoot ? '-w' : '--ignore-workspace-root-check'),\n ].filter(Boolean).join(' '));\n\n return true;\n}\n","import ansis from 'ansis';\nimport { detectJsPackageManager, type JsPackageManagerMeta } from './js-package-manager-utils';\n\n\nexport const fmt = {\n decorator: (s: string) => ansis.magenta(s),\n filePath: (s: string) => `📂 ${ansis.cyan.italic(s)}`,\n fileName: (s: string) => `${ansis.cyan.italic(s)}`,\n command: (s: string, opts?: { jsPackageManager?: JsPackageManagerMeta | true }) => {\n let jsPackageManager: JsPackageManagerMeta | undefined;\n if (opts?.jsPackageManager === true) {\n jsPackageManager = detectJsPackageManager();\n } else if (opts?.jsPackageManager) {\n jsPackageManager = opts.jsPackageManager;\n }\n if (jsPackageManager) {\n s = `${jsPackageManager.exec} ${s}`;\n }\n return ansis.green.italic(s);\n },\n packageName: (s: string) => ansis.green.italic(s),\n};\n\nexport const logLines = (lines: Array<string | false | undefined>) => {\n for (const line of lines) {\n // skip false, null, undefined, but not empty strings\n if (!line && line !== '') continue;\n console.log(line);\n }\n};\n"]}
@@ -858,13 +858,88 @@ function debug3(msg) {
858
858
  }
859
859
  }
860
860
  __name(debug3, "debug");
861
- var _cachedSessionId;
862
- function getSelfSessionId() {
863
- if (_cachedSessionId) return _cachedSessionId;
861
+ var SHELL_RUNNER_NAMES = /* @__PURE__ */ new Set(["sh", "bash", "zsh", "dash", "fish", "ksh", "csh", "tcsh"]);
862
+ var VARLOCK_LAUNCHER_NAMES = /* @__PURE__ */ new Set(["varlock", "varlock.exe", "varlock.cmd"]);
863
+ var PACKAGE_MANAGER_RUNNER_NAMES = /* @__PURE__ */ new Set(["bun", "node", "npm", "npx", "pnpm", "pnpx", "yarn", "yarnpkg"]);
864
+ var NO_TTY_SESSION_ENV_KEYS = [
865
+ "CODEX_THREAD_ID",
866
+ "CLAUDE_CODE_SESSION_ID",
867
+ "CLAUDE_SESSION_ID"
868
+ ];
869
+ function getProcessName(pid) {
870
+ try {
871
+ const exePath = fs.readlinkSync(`/proc/${pid}/exe`);
872
+ return exePath.split("/").pop()?.toLowerCase();
873
+ } catch {
874
+ }
875
+ try {
876
+ return fs.readFileSync(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
877
+ } catch {
878
+ return void 0;
879
+ }
880
+ }
881
+ __name(getProcessName, "getProcessName");
882
+ function getProcessArgs(pid) {
883
+ try {
884
+ return fs.readFileSync(`/proc/${pid}/cmdline`, "utf-8").split("\0").filter(Boolean);
885
+ } catch {
886
+ return [];
887
+ }
888
+ }
889
+ __name(getProcessArgs, "getProcessArgs");
890
+ function processCommandLineLaunchesVarlock(pid) {
891
+ return getProcessArgs(pid).some((arg) => {
892
+ const name = arg.split("/").pop()?.toLowerCase();
893
+ return Boolean(
894
+ name && VARLOCK_LAUNCHER_NAMES.has(name) || arg.includes("/node_modules/.bin/varlock") || arg.includes("/varlock/bin/cli.js") || arg.includes("/packages/varlock/bin/cli.js")
895
+ );
896
+ });
897
+ }
898
+ __name(processCommandLineLaunchesVarlock, "processCommandLineLaunchesVarlock");
899
+ function isEphemeralRunner(pid) {
900
+ const name = getProcessName(pid);
901
+ if (!name) return false;
902
+ if (SHELL_RUNNER_NAMES.has(name) || VARLOCK_LAUNCHER_NAMES.has(name)) return true;
903
+ return PACKAGE_MANAGER_RUNNER_NAMES.has(name) && processCommandLineLaunchesVarlock(pid);
904
+ }
905
+ __name(isEphemeralRunner, "isEphemeralRunner");
906
+ function selectScopePidFromChain(chain) {
907
+ if (chain.length < 2) return void 0;
908
+ if (chain.length >= 4) {
909
+ let scopePid = chain[chain.length - 3];
910
+ if (isEphemeralRunner(scopePid)) {
911
+ const fallback = chain[chain.length - 2];
912
+ scopePid = isEphemeralRunner(fallback) ? chain[chain.length - 1] : fallback;
913
+ }
914
+ return scopePid;
915
+ }
916
+ return chain[chain.length - 1];
917
+ }
918
+ __name(selectScopePidFromChain, "selectScopePidFromChain");
919
+ function getProcessStartTime(pid) {
920
+ try {
921
+ const scopeStat = fs.readFileSync(`/proc/${pid}/stat`, "utf-8");
922
+ const scopeFields = scopeStat.split(") ");
923
+ if (scopeFields.length >= 2) {
924
+ return parseInt(scopeFields[1].split(" ")[19], 10) || 0;
925
+ }
926
+ } catch {
927
+ }
928
+ return 0;
929
+ }
930
+ __name(getProcessStartTime, "getProcessStartTime");
931
+ function getNoTtySessionIdFromEnv() {
932
+ for (const key of NO_TTY_SESSION_ENV_KEYS) {
933
+ const value = process.env[key]?.trim();
934
+ if (value) return `env:${key}:${value}`;
935
+ }
936
+ return void 0;
937
+ }
938
+ __name(getNoTtySessionIdFromEnv, "getNoTtySessionIdFromEnv");
939
+ function getParentSessionId() {
864
940
  try {
865
941
  const ttyPath = fs.readlinkSync("/proc/self/fd/0");
866
942
  if (ttyPath && ttyPath.startsWith("/dev/")) {
867
- _cachedSessionId = ttyPath;
868
943
  return ttyPath;
869
944
  }
870
945
  } catch {
@@ -881,23 +956,26 @@ function getSelfSessionId() {
881
956
  chain.push(ppid);
882
957
  current = ppid;
883
958
  }
884
- if (chain.length >= 4) {
885
- const scopePid = chain[chain.length - 3];
886
- let startTime = 0;
887
- try {
888
- const scopeStat = fs.readFileSync(`/proc/${scopePid}/stat`, "utf-8");
889
- const scopeFields = scopeStat.split(") ");
890
- if (scopeFields.length >= 2) {
891
- startTime = parseInt(scopeFields[1].split(" ")[19], 10) || 0;
892
- }
893
- } catch {
894
- }
895
- _cachedSessionId = `ptree:${scopePid}:${startTime}`;
896
- return _cachedSessionId;
959
+ const scopePid = selectScopePidFromChain(chain);
960
+ if (scopePid !== void 0) {
961
+ const startTime = getProcessStartTime(scopePid);
962
+ return `ptree:${scopePid}:${startTime}`;
897
963
  }
898
964
  } catch {
899
965
  }
900
- _cachedSessionId = `pid:${process.pid}`;
966
+ return `pid:${process.pid}`;
967
+ }
968
+ __name(getParentSessionId, "getParentSessionId");
969
+ var _cachedSessionId;
970
+ function getSelfSessionId() {
971
+ if (_cachedSessionId) return _cachedSessionId;
972
+ const parentSessionId = getParentSessionId();
973
+ const envSessionId = getNoTtySessionIdFromEnv();
974
+ if (envSessionId) {
975
+ _cachedSessionId = `${envSessionId}|${parentSessionId}`;
976
+ return _cachedSessionId;
977
+ }
978
+ _cachedSessionId = parentSessionId;
901
979
  return _cachedSessionId;
902
980
  }
903
981
  __name(getSelfSessionId, "getSelfSessionId");
@@ -1203,5 +1281,5 @@ async function lockSession() {
1203
1281
  __name(lockSession, "lockSession");
1204
1282
 
1205
1283
  export { decryptValue2 as decryptValue, encryptValue2 as encryptValue, ensureKey, getBackendInfo, getDaemonClient, lockSession };
1206
- //# sourceMappingURL=chunk-YWTIKDGU.js.map
1207
- //# sourceMappingURL=chunk-YWTIKDGU.js.map
1284
+ //# sourceMappingURL=chunk-P4HNABAM.js.map
1285
+ //# sourceMappingURL=chunk-P4HNABAM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/local-encrypt/binary-resolver.ts","../src/lib/local-encrypt/daemon-client.ts","../src/lib/local-encrypt/crypto.ts","../src/lib/local-encrypt/file-backend.ts","../src/lib/local-encrypt/index.ts"],"names":["__dirname","debug","path","fs","DEFAULT_KEY_ID","keyExists","generateKey","encryptValue","result","decryptValue"],"mappings":"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","file":"chunk-P4HNABAM.js","sourcesContent":["/**\n * Resolves the path to the platform-specific native helper binary.\n *\n * Resolution order:\n * 1. SEA sibling: same directory as the running varlock binary (install.sh, standalone)\n * 1b. SEA libexec: ../libexec/ relative to the binary (homebrew convention)\n * 2. Bundled in npm package: native-bins/<platform>[-<arch>]/ within the varlock package\n * 3. Dev fallback: walk up from __dirname to find build output\n *\n * Returns undefined if no binary is found (file-based fallback will be used instead).\n */\n\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { isWSL } from './wsl-detect';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n/** Debug logger — prints to stderr when VARLOCK_DEBUG is set */\nfunction debug(msg: string) {\n if (process.env.VARLOCK_DEBUG) {\n process.stderr.write(`[varlock:binary-resolver] ${msg}\\n`);\n }\n}\n\nconst BINARY_NAME = 'varlock-local-encrypt';\nconst MACOS_APP_BUNDLE = 'VarlockEnclave.app';\n\n/**\n * Resolve the varlock package root by walking up from this module until we\n * find package.json with name=varlock. This is robust across src/dist layouts.\n */\nfunction resolvePackageRoot(): string {\n let dir = __dirname;\n for (let i = 0; i < 10; i++) {\n const pkgJsonPath = path.join(dir, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {\n try {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) as { name?: string };\n if (pkgJson.name === 'varlock') return dir;\n } catch {\n // Ignore invalid/unreadable package.json and continue walking upward\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n // Last-resort fallback for unexpected layouts.\n return path.resolve(__dirname, '..', '..', '..');\n}\n\n/** Get the binary name for the current platform */\nfunction getPlatformBinaryName(): string {\n if (process.platform === 'win32' || isWSL()) return `${BINARY_NAME}.exe`;\n return BINARY_NAME;\n}\n\n/** Get the subdirectory name within native-bins/ for the current platform */\nfunction getNativeBinSubdir(): string {\n if (process.platform === 'darwin') return 'darwin';\n if (process.platform === 'win32') return `win32-${process.arch}`;\n // WSL2: use the Windows binary for DPAPI + Windows Hello support\n if (isWSL()) return 'win32-x64';\n return `${process.platform}-${process.arch}`;\n}\n\n/**\n * Resolve the macOS .app bundle binary path, or fall back to bare binary.\n */\nfunction resolveMacOSBinary(dir: string): string | undefined {\n // Try .app bundle first (needed for custom Touch ID icon)\n const appBundlePath = path.join(dir, MACOS_APP_BUNDLE, 'Contents', 'MacOS', BINARY_NAME);\n if (fs.existsSync(appBundlePath)) return appBundlePath;\n\n // Fall back to bare binary\n const barePath = path.join(dir, BINARY_NAME);\n if (fs.existsSync(barePath)) return barePath;\n\n return undefined;\n}\n\n/**\n * Resolve the binary path for Linux/Windows.\n */\nfunction resolveStandardBinary(dir: string): string | undefined {\n const binaryPath = path.join(dir, getPlatformBinaryName());\n if (fs.existsSync(binaryPath)) return binaryPath;\n return undefined;\n}\n\n/**\n * Resolve binary from a directory, handling macOS .app bundle vs standard binary.\n */\nfunction resolveBinaryFromDir(dir: string): string | undefined {\n if (process.platform === 'darwin') return resolveMacOSBinary(dir);\n return resolveStandardBinary(dir);\n}\n\n/**\n * Strategy 1: Look for the binary next to the running varlock binary,\n * then check ../libexec/ (homebrew convention for internal helpers).\n * This is the primary path for binary/SEA distribution.\n */\nfunction resolveSeaSibling(): string | undefined {\n const execDir = path.dirname(fs.realpathSync(process.execPath));\n\n // 1a. Same directory as the binary (install.sh, standalone archives)\n const sibling = resolveBinaryFromDir(execDir);\n if (sibling) return sibling;\n\n // 1b. ../libexec/ relative to the binary (homebrew layout)\n const libexecDir = path.join(execDir, '..', 'libexec');\n return resolveBinaryFromDir(libexecDir);\n}\n\n/**\n * Strategy 2: Look for the binary bundled in the varlock npm package.\n * native-bins/<platform-subdir>/\n */\nfunction resolveNpmBundled(): string | undefined {\n const packageRoot = resolvePackageRoot();\n const nativeBinsDir = path.join(packageRoot, 'native-bins', getNativeBinSubdir());\n if (fs.existsSync(nativeBinsDir)) return resolveBinaryFromDir(nativeBinsDir);\n\n // Legacy/alternate layout: native-bins as a sibling of the package root.\n const adjacentNativeBinsDir = path.join(path.dirname(packageRoot), 'native-bins', getNativeBinSubdir());\n if (fs.existsSync(adjacentNativeBinsDir)) return resolveBinaryFromDir(adjacentNativeBinsDir);\n\n return undefined;\n}\n\n/**\n * Strategy 3: Development fallback — look for build output in the monorepo.\n * Walks up from __dirname looking for native binary build output\n */\nfunction resolveDevFallback(): string | undefined {\n let dir = __dirname;\n for (let i = 0; i < 10; i++) {\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n\n // Check for Swift build output (macOS)\n if (process.platform === 'darwin') {\n const swiftBuild = path.join(dir, 'packages', 'encryption-binary-swift', 'swift', '.build', 'release', 'VarlockEnclave');\n if (fs.existsSync(swiftBuild)) return swiftBuild;\n }\n\n // Check for Rust build output (Linux/Windows)\n const rustBuild = path.join(dir, 'packages', 'encryption-binary-rust', 'target', 'release', getPlatformBinaryName());\n if (fs.existsSync(rustBuild)) return rustBuild;\n }\n\n return undefined;\n}\n\n/**\n * Ensure the binary at the given path is executable.\n * GitHub Actions artifact upload/download strips execute permissions,\n * and some extraction tools may do the same.\n */\nfunction ensureExecutable(binaryPath: string): string {\n try {\n fs.accessSync(binaryPath, fs.constants.X_OK);\n } catch {\n // Not executable — try to fix it\n if (process.platform !== 'win32') {\n fs.chmodSync(binaryPath, 0o755);\n }\n }\n return binaryPath;\n}\n\n/**\n * Resolve the native helper binary path.\n * Returns undefined if no binary is found — caller should fall back to pure JS.\n */\nlet _cachedBinaryPath: string | undefined | null = null; // null = not yet resolved\n\nexport function resolveNativeBinary(): string | undefined {\n if (_cachedBinaryPath !== null) return _cachedBinaryPath;\n\n if (process.env._VARLOCK_FORCE_FILE_ENCRYPTION_FALLBACK) {\n debug('_VARLOCK_FORCE_FILE_ENCRYPTION_FALLBACK is set — skipping native binary resolution');\n _cachedBinaryPath = undefined;\n return undefined;\n }\n\n debug(`resolving: platform=${process.platform}, isWSL=${isWSL()}, binaryName=${getPlatformBinaryName()}, subdir=${getNativeBinSubdir()}`);\n\n const seaSibling = resolveSeaSibling();\n if (seaSibling) {\n debug(`resolved via SEA sibling: ${seaSibling}`);\n _cachedBinaryPath = ensureExecutable(seaSibling);\n return _cachedBinaryPath;\n }\n\n const npmBundled = resolveNpmBundled();\n if (npmBundled) {\n debug(`resolved via npm bundled: ${npmBundled}`);\n _cachedBinaryPath = ensureExecutable(npmBundled);\n return _cachedBinaryPath;\n }\n\n const devFallback = resolveDevFallback();\n if (devFallback) {\n debug(`resolved via dev fallback: ${devFallback}`);\n _cachedBinaryPath = ensureExecutable(devFallback);\n return _cachedBinaryPath;\n }\n\n debug('NOT FOUND: no binary resolved from any strategy');\n debug(` SEA sibling dir: ${path.dirname(process.execPath)}`);\n const packageRoot = resolvePackageRoot();\n debug(` npm bundled dir: ${path.join(packageRoot, 'native-bins', getNativeBinSubdir())}`);\n _cachedBinaryPath = undefined;\n return undefined;\n}\n","/**\n * Daemon client for communicating with the native encryption helper binary.\n *\n * Handles daemon lifecycle (spawn, connect, reconnect) and IPC messaging\n * using the 4-byte LE length-prefixed JSON protocol.\n *\n * - macOS/Linux: Unix domain socket\n * - Windows: named pipe (TODO)\n *\n * Generalized from the secure-enclave plugin's EnclaveDaemonClient.\n *\n * Note: WSL2 cannot connect to the Windows named-pipe daemon from the Linux\n * side. All WSL2 code paths that need biometric operations must bypass this\n * client and invoke the Windows binary directly (e.g. via --via-daemon).\n */\n\nimport net from 'node:net';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport crypto from 'node:crypto';\nimport { spawn } from 'node:child_process';\n\nimport { getUserVarlockDir } from '../user-config-dir';\nimport { resolveNativeBinary } from './binary-resolver';\nimport { isWSL } from './wsl-detect';\nimport type { KeychainItemMeta, KeychainItemRef } from './types';\n\n/** Timeout for daemon IPC messages that don't involve user interaction */\nconst SEND_TIMEOUT_MS = 30_000;\n/**\n * Timeout for messages that may trigger biometric auth (Touch ID).\n * Must exceed the Swift-side biometric timeout (60s) so the TS client\n * doesn't kill the daemon while Touch ID is still waiting for the user.\n * Killing mid-biometric can leave the process stuck in kernel UE state.\n */\nconst BIOMETRIC_TIMEOUT_MS = 90_000;\n/** Timeout for interactive messages (GUI dialogs for secret input, keychain picker) */\nconst INTERACTIVE_TIMEOUT_MS = 5 * 60_000;\n/** How long to wait for SIGTERM before escalating to SIGKILL */\nconst KILL_GRACE_MS = 2_000;\n\nfunction debug(msg: string) {\n if (process.env.VARLOCK_DEBUG) {\n process.stderr.write(`[varlock:daemon-client] ${msg}\\n`);\n }\n}\n\n/**\n * Kill a daemon process, escalating from SIGTERM to SIGKILL if it doesn't\n * die within KILL_GRACE_MS. Handles the case where the process is already dead.\n *\n * Returns true if the process is confirmed dead, false if it's stuck in an\n * unkillable state (e.g. macOS UE/uninterruptible Secure Enclave wait).\n * Callers should clean up state files and proceed regardless — a zombie\n * with no socket file is effectively dead.\n */\nfunction killDaemonProcess(pid: number): boolean {\n try {\n process.kill(pid, 'SIGTERM');\n } catch {\n return true; // already dead\n }\n\n // Poll briefly to see if SIGTERM was effective\n const start = Date.now();\n while (Date.now() - start < KILL_GRACE_MS) {\n try {\n process.kill(pid, 0);\n } catch {\n return true; // process exited\n }\n // Busy-wait in small increments (this is a rare recovery path)\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 100);\n }\n\n // Still alive — force kill\n debug(`daemon pid ${pid} didn't respond to SIGTERM, sending SIGKILL`);\n try {\n process.kill(pid, 'SIGKILL');\n } catch {\n return true; // already dead\n }\n\n // Give SIGKILL a moment to take effect\n const killStart = Date.now();\n while (Date.now() - killStart < 500) {\n try {\n process.kill(pid, 0);\n } catch {\n return true; // process exited\n }\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 50);\n }\n\n // Process is unkillable (UE state — stuck in kernel, e.g. Secure Enclave).\n // It's harmless once we remove the socket/PID files; it will clear on reboot.\n debug(`daemon pid ${pid} is unkillable (likely in uninterruptible kernel wait) — proceeding anyway`);\n return false;\n}\n\nfunction getSocketDir(): string {\n return path.join(getUserVarlockDir(), 'local-encrypt');\n}\n\nfunction getSocketPath(): string {\n if (process.platform === 'win32') {\n // Windows named pipe — fixed name shared by all varlock processes\n return '\\\\\\\\.\\\\pipe\\\\varlock-local-encrypt';\n }\n return path.join(getSocketDir(), 'daemon.sock');\n}\n\nfunction getLockPath(): string {\n return `${getSocketPath()}.lock`;\n}\n\nfunction getPidPath(): string {\n return path.join(getSocketDir(), 'daemon.pid');\n}\n\nfunction getDaemonInfoPath(): string {\n return path.join(getSocketDir(), 'daemon.info');\n}\n\n/** All state files that should be cleaned up when resetting daemon state */\nfunction getDaemonStateFiles(): Array<string> {\n const files = [getPidPath(), getDaemonInfoPath()];\n if (process.platform !== 'win32') {\n files.push(getSocketPath(), getLockPath());\n }\n return files;\n}\n\n/** Remove all daemon state files, ignoring errors */\nfunction cleanupDaemonFiles(): void {\n for (const file of getDaemonStateFiles()) {\n try {\n fs.unlinkSync(file);\n } catch { /* ignore */ }\n }\n}\n\n/**\n * Check whether the currently running daemon was spawned from the same binary\n * we would spawn now. Compares the resolved binary path and its mtime against\n * the values recorded in daemon.info when the daemon was last started.\n *\n * Returns the stale PID (to kill) if there's a mismatch or no info file\n * exists (daemon predates version tracking), or undefined if daemon is current.\n */\nfunction checkDaemonBinaryStale(): number | undefined {\n const infoPath = getDaemonInfoPath();\n const pidPath = getPidPath();\n\n let info: { binaryPath: string; binaryMtimeMs: number } | undefined;\n try {\n info = JSON.parse(fs.readFileSync(infoPath, 'utf-8'));\n } catch {\n // No info file — daemon predates version tracking, treat as stale\n }\n\n const currentBinaryPath = resolveNativeBinary();\n if (!currentBinaryPath) return undefined; // no binary available at all\n\n if (info) {\n // Path changed (e.g. new npm install, different resolution strategy)\n if (currentBinaryPath !== info.binaryPath) {\n debug(`daemon binary path changed: ${info.binaryPath} → ${currentBinaryPath}`);\n } else {\n // Same path — check if the file was updated in place\n try {\n const stat = fs.statSync(currentBinaryPath);\n if (stat.mtimeMs === info.binaryMtimeMs) {\n debug('daemon binary is current — no restart needed');\n return undefined; // same binary, daemon is current\n }\n debug(`daemon binary mtime changed: ${info.binaryMtimeMs} → ${stat.mtimeMs}`);\n } catch {\n return undefined; // can't stat, assume OK\n }\n }\n } else {\n debug('no daemon.info file — treating running daemon as stale');\n }\n\n // Binary changed — read PID so caller can kill the stale daemon\n try {\n const pid = parseInt(fs.readFileSync(pidPath, 'utf-8').trim(), 10);\n process.kill(pid, 0); // verify process is alive\n return pid;\n } catch {\n // Process already gone — clean up stale files so spawnDaemon starts clean\n debug('stale PID file points to dead process — cleaning up');\n cleanupDaemonFiles();\n return undefined;\n }\n}\n\n/** Write daemon.info recording which binary was used to spawn the daemon */\nfunction writeDaemonInfo(binaryPath: string): void {\n try {\n const stat = fs.statSync(binaryPath);\n fs.writeFileSync(getDaemonInfoPath(), JSON.stringify({\n binaryPath,\n binaryMtimeMs: stat.mtimeMs,\n }));\n } catch {\n // Non-fatal — version checking just won't work this time\n }\n}\n\nexport class DaemonClient {\n private socket: net.Socket | null = null;\n private messageQueue = new Map<string, {\n resolve: (value: any) => void;\n reject: (error: Error) => void;\n }>();\n private isConnected = false;\n private buffer = Buffer.alloc(0);\n private connectingPromise: Promise<void> | null = null;\n /** Set after we spawn a daemon in this process — skip stale check to avoid restart loops */\n private spawnedInThisProcess = false;\n\n async ensureConnected(): Promise<void> {\n if (this.isConnected && this.socket) return;\n\n // Deduplicate concurrent ensureConnected calls — multiple varlock() items\n // may resolve concurrently and all call decrypt → ensureConnected\n if (this.connectingPromise) return this.connectingPromise;\n\n this.connectingPromise = this.doConnect();\n try {\n await this.connectingPromise;\n } finally {\n this.connectingPromise = null;\n }\n }\n\n /**\n * Try to connect to an existing daemon without spawning a new one.\n * Returns true if connected, false if no daemon is running.\n */\n async tryConnect(): Promise<boolean> {\n if (this.isConnected && this.socket) return true;\n const socketPath = getSocketPath();\n try {\n await this.connectToSocket(socketPath);\n return true;\n } catch {\n return false;\n }\n }\n\n private async doConnect(): Promise<void> {\n const socketPath = getSocketPath();\n\n // Check if a running daemon was spawned from a stale binary\n const stalePid = this.spawnedInThisProcess ? undefined : checkDaemonBinaryStale();\n if (stalePid) {\n debug(`killing stale daemon (pid ${stalePid}) — binary has been updated`);\n killDaemonProcess(stalePid);\n cleanupDaemonFiles();\n } else {\n try {\n await this.connectToSocket(socketPath);\n return;\n } catch {\n // Daemon not running, spawn it\n }\n }\n\n try {\n await this.spawnDaemon();\n } catch (err) {\n // Another process may have won the race to spawn the daemon.\n // Wait briefly for it to be ready, then try connecting.\n debug(`spawnDaemon failed: ${err instanceof Error ? err.message : err}`);\n await new Promise<void>((r) => {\n setTimeout(r, 1000);\n });\n }\n await this.connectToSocket(socketPath);\n }\n\n async decrypt(ciphertext: string, keyId = 'varlock-default'): Promise<string> {\n return this.withRetry(async () => {\n await this.ensureConnected();\n const result = await this.sendMessage({\n action: 'decrypt',\n payload: { ciphertext, keyId },\n }, BIOMETRIC_TIMEOUT_MS);\n if (typeof result === 'string') return result;\n if (result && typeof result === 'object' && 'error' in result) {\n throw new Error(String(result.error));\n }\n return String(result);\n });\n }\n\n async promptSecret(opts?: {\n itemKey?: string;\n message?: string;\n keyId?: string;\n }): Promise<string | undefined> {\n return this.withRetry(async () => {\n await this.ensureConnected();\n try {\n const result = await this.sendMessage({\n action: 'prompt-secret',\n payload: {\n itemKey: opts?.itemKey,\n message: opts?.message,\n keyId: opts?.keyId,\n },\n }, INTERACTIVE_TIMEOUT_MS);\n if (result && typeof result === 'object' && 'ciphertext' in result) {\n return result.ciphertext as string;\n }\n return undefined;\n } catch (err) {\n if (err instanceof Error && err.message === 'cancelled') return undefined;\n throw err;\n }\n });\n }\n\n async invalidateSession(): Promise<void> {\n return this.withRetry(async () => {\n await this.ensureConnected();\n await this.sendMessage({ action: 'invalidate-session' });\n });\n }\n\n async keychainGet(opts: { service?: string; account?: string; keychain?: string; field?: string }): Promise<string> {\n return this.withRetry(async () => {\n await this.ensureConnected();\n // Password reads may trigger biometric; metadata field reads won't,\n // but we use the biometric timeout for both since it's harmless.\n const result = await this.sendMessage({\n action: 'keychain-get',\n payload: opts,\n }, BIOMETRIC_TIMEOUT_MS);\n if (typeof result === 'string') return result;\n if (result && typeof result === 'object' && 'error' in result) {\n throw new Error(String(result.error));\n }\n return String(result);\n });\n }\n\n async keychainSearch(opts?: { query?: string; keychain?: string }): Promise<Array<KeychainItemMeta>> {\n return this.withRetry(async () => {\n await this.ensureConnected();\n const result = await this.sendMessage({\n action: 'keychain-search',\n payload: opts ?? {},\n });\n return (result ?? []) as Array<KeychainItemMeta>;\n });\n }\n\n async keychainPick(opts?: { itemKey?: string }): Promise<KeychainItemRef | undefined> {\n return this.withRetry(async () => {\n await this.ensureConnected();\n try {\n const result = await this.sendMessage({\n action: 'keychain-pick',\n payload: { itemKey: opts?.itemKey },\n }, INTERACTIVE_TIMEOUT_MS);\n if (result && typeof result === 'object' && 'service' in result) {\n return result as KeychainItemRef;\n }\n return undefined;\n } catch (err) {\n if (err instanceof Error && err.message === 'cancelled') return undefined;\n throw err;\n }\n });\n }\n\n cleanup(): void {\n for (const { reject } of this.messageQueue.values()) {\n reject(new Error('Connection closed'));\n }\n this.messageQueue.clear();\n this.socket?.end();\n this.socket = null;\n this.isConnected = false;\n this.buffer = Buffer.alloc(0);\n }\n\n // -- Private --\n\n /**\n * Run an async operation, and on recoverable failure (timeout, connection\n * closed) clean up, reconnect to the daemon, and retry once.\n */\n private async withRetry<T>(fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (err) {\n const msg = err instanceof Error ? err.message : '';\n const recoverable = msg.includes('timed out')\n || msg.includes('connection closed')\n || msg.includes('Not connected');\n if (!recoverable) throw err;\n\n debug(`recoverable error, reconnecting: ${msg}`);\n this.forceCleanup();\n await this.ensureConnected();\n return await fn();\n }\n }\n\n /**\n * Aggressive cleanup: kill the daemon process if we know its PID,\n * then reset client state so the next ensureConnected spawns fresh.\n */\n private forceCleanup(): void {\n this.cleanup();\n this.spawnedInThisProcess = false; // allow stale-binary check on reconnect\n\n // Try to kill the daemon by PID so we don't reconnect to a broken process\n try {\n const pid = parseInt(fs.readFileSync(getPidPath(), 'utf-8').trim(), 10);\n killDaemonProcess(pid);\n } catch { /* no PID file or already dead */ }\n\n // Remove stale files so spawnDaemon starts clean\n cleanupDaemonFiles();\n }\n\n private connectToSocket(socketPath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = new net.Socket();\n const timeout = setTimeout(() => {\n socket.destroy();\n reject(new Error('Connection timeout'));\n }, 5000);\n\n socket.on('connect', () => {\n clearTimeout(timeout);\n this.socket = socket;\n this.isConnected = true;\n this.buffer = Buffer.alloc(0);\n resolve();\n });\n\n socket.on('data', (data: Buffer) => {\n this.handleData(data);\n });\n\n socket.on('error', (err) => {\n clearTimeout(timeout);\n this.isConnected = false;\n reject(err);\n });\n\n socket.on('close', () => {\n this.isConnected = false;\n this.socket = null;\n // Reject all pending messages so callers don't hang\n for (const { reject: rej } of this.messageQueue.values()) {\n rej(new Error('Daemon connection closed'));\n }\n this.messageQueue.clear();\n this.buffer = Buffer.alloc(0);\n });\n\n socket.connect(socketPath);\n });\n }\n\n private handleData(data: Buffer): void {\n this.buffer = Buffer.concat([this.buffer, data]);\n\n while (this.buffer.length >= 4) {\n const messageLength = this.buffer.readUInt32LE(0);\n if (this.buffer.length < 4 + messageLength) break;\n\n const messageData = this.buffer.subarray(4, 4 + messageLength);\n this.buffer = this.buffer.subarray(4 + messageLength);\n\n try {\n const message = JSON.parse(messageData.toString());\n if (message.id && this.messageQueue.has(message.id)) {\n const { resolve: res, reject: rej } = this.messageQueue.get(message.id)!;\n this.messageQueue.delete(message.id);\n if (message.error) {\n rej(new Error(message.error));\n } else {\n res(message.result);\n }\n }\n } catch {\n // Ignore malformed messages\n }\n }\n }\n\n private sendMessage(message: Record<string, any>, timeoutMs = SEND_TIMEOUT_MS): Promise<any> {\n return new Promise((resolve, reject) => {\n if (!this.isConnected || !this.socket) {\n reject(new Error('Not connected to daemon'));\n return;\n }\n\n const messageId = `${Date.now().toString(36)}-${crypto.randomBytes(4).toString('hex')}`;\n const messageWithId = { ...message, id: messageId };\n const jsonData = JSON.stringify(messageWithId);\n const messageBytes = Buffer.from(jsonData, 'utf-8');\n\n const lengthBuf = Buffer.alloc(4);\n lengthBuf.writeUInt32LE(messageBytes.length, 0);\n\n // Timeout to prevent hanging forever on a stuck daemon\n const timeout = setTimeout(() => {\n this.messageQueue.delete(messageId);\n reject(new Error(`Daemon message timed out after ${timeoutMs}ms (action: ${message.action})`));\n }, timeoutMs);\n\n this.messageQueue.set(messageId, {\n resolve: (value) => {\n clearTimeout(timeout);\n resolve(value);\n },\n reject: (err) => {\n clearTimeout(timeout);\n reject(err);\n },\n });\n this.socket.write(Buffer.concat([lengthBuf, messageBytes]));\n });\n }\n\n private async spawnDaemon(): Promise<void> {\n // WSL2: the Windows daemon listens on a Windows named pipe that Linux\n // sockets cannot connect to. All WSL2 biometric operations must bypass\n // DaemonClient and invoke the Windows binary directly via --via-daemon.\n // If we somehow reach this point on WSL2, fail fast with a clear message\n // rather than spawning a broken daemon or hanging indefinitely.\n if (isWSL()) {\n throw new Error(\n 'DaemonClient is not supported on WSL2. The Windows encryption daemon uses a Windows named pipe that Linux socket APIs cannot connect to. Use the Windows binary directly instead.',\n );\n }\n\n const binaryPath = resolveNativeBinary();\n if (!binaryPath) {\n throw new Error('Native encryption binary not found — cannot start daemon');\n }\n\n const socketPath = getSocketPath();\n const pidPath = getPidPath();\n const isWindows = process.platform === 'win32';\n\n // Ensure PID directory exists (don't mkdir for Windows pipe paths)\n if (!isWindows) {\n fs.mkdirSync(path.dirname(socketPath), { recursive: true });\n }\n fs.mkdirSync(path.dirname(pidPath), { recursive: true });\n\n // Check for existing daemon via PID\n if (fs.existsSync(pidPath)) {\n try {\n const pid = parseInt(fs.readFileSync(pidPath, 'utf-8').trim(), 10);\n process.kill(pid, 0); // Throws if process doesn't exist\n\n // Process is alive — verify it's actually responsive on the socket\n try {\n await this.connectToSocket(socketPath);\n return; // daemon is alive and accepting connections\n } catch {\n // Alive but socket unresponsive — kill it and respawn\n debug(`daemon pid ${pid} alive but socket unresponsive — killing`);\n killDaemonProcess(pid);\n }\n } catch {\n // Stale PID file — clean up both PID and socket\n }\n }\n\n // Clean up stale files before spawning\n cleanupDaemonFiles();\n if (!isWindows && fs.existsSync(socketPath)) {\n throw new Error(`Failed to clean up stale socket file: ${socketPath}`);\n }\n\n return new Promise((resolve, reject) => {\n const child = spawn(binaryPath, [\n 'daemon',\n '--socket-path',\n socketPath,\n '--pid-path',\n pidPath,\n ], {\n detached: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n const timeout = setTimeout(() => {\n reject(new Error('Daemon failed to start within timeout'));\n }, 10000);\n\n let stdoutData = '';\n let stderrData = '';\n\n child.stdout!.on('data', (data: Buffer) => {\n stdoutData += data.toString();\n try {\n const parsed = JSON.parse(stdoutData);\n if (parsed.ready) {\n clearTimeout(timeout);\n writeDaemonInfo(binaryPath);\n this.spawnedInThisProcess = true;\n child.unref();\n child.stdout!.destroy();\n child.stderr!.destroy();\n resolve();\n }\n } catch {\n // Incomplete JSON, keep buffering\n }\n });\n\n child.stderr!.on('data', (data: Buffer) => {\n stderrData += data.toString();\n });\n\n child.on('error', (err) => {\n clearTimeout(timeout);\n reject(new Error(`Failed to spawn daemon: ${err.message}`));\n });\n\n child.on('exit', (code) => {\n clearTimeout(timeout);\n if (code !== 0) {\n const details = [\n stderrData.trim() && `stderr: ${stderrData.trim()}`,\n stdoutData.trim() && `stdout: ${stdoutData.trim()}`,\n `binary: ${binaryPath}`,\n `socket: ${socketPath}`,\n ].filter(Boolean).join('\\n');\n reject(new Error(`Daemon exited with code ${code}\\n${details}`));\n }\n });\n });\n }\n}\n","/**\n * Pure JS ECIES implementation using Node.js Web Crypto API.\n *\n * Wire-compatible with the Swift Secure Enclave implementation:\n * - P-256 ECDH key agreement\n * - HKDF-SHA256 (salt: \"varlock-ecies-v1\", info: ephemeralPub || recipientPub)\n * - AES-256-GCM with random 12-byte nonce\n * - Payload: version(1) | ephemeralPubKey(65) | nonce(12) | ciphertext(N) | tag(16)\n *\n * Adapted from PR #19's apple-crypto.ts, modified to match the custom ECIES scheme\n * used by the Swift SecureEnclaveManager rather than Apple's built-in variant.\n */\n\nimport { webcrypto } from 'node:crypto';\n\nconst subtle = webcrypto.subtle;\n\nconst PAYLOAD_VERSION = 0x01;\nconst HKDF_SALT = new TextEncoder().encode('varlock-ecies-v1');\nconst EC_ALGORITHM = { name: 'ECDH', namedCurve: 'P-256' };\n\n/** Uncompressed P-256 public key is 65 bytes (0x04 || x(32) || y(32)) */\nconst PUBLIC_KEY_LENGTH = 65;\nconst NONCE_LENGTH = 12;\nconst TAG_LENGTH = 16;\nconst HEADER_LENGTH = 1 + PUBLIC_KEY_LENGTH + NONCE_LENGTH; // version + pubkey + nonce\n\n// Bun's types are stricter about BufferSource (requires ArrayBuffer, not ArrayBufferLike).\n// This type assertion is safe — we always work with standard ArrayBuffers.\n\nconst bs = (data: Uint8Array | ArrayBuffer) => data as any;\n\n// ── Key types ──────────────────────────────────────────────────────────\n\nexport interface EcKeyPair {\n /** Base64-encoded uncompressed P-256 public key (65 bytes raw) */\n publicKey: string;\n /** Base64-encoded PKCS8 private key */\n privateKey: string;\n}\n\n// ── Utilities ──────────────────────────────────────────────────────────\n\nfunction concatBuffers(...buffers: Array<Uint8Array>): Uint8Array {\n const totalLength = buffers.reduce((sum, b) => sum + b.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const buf of buffers) {\n result.set(buf, offset);\n offset += buf.length;\n }\n return result;\n}\n\nfunction bufferToBase64(buffer: ArrayBuffer | Uint8Array): string {\n if (buffer instanceof Uint8Array) {\n return Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength).toString('base64');\n }\n return Buffer.from(buffer).toString('base64');\n}\n\nfunction base64ToUint8(base64: string): Uint8Array {\n const buf = Buffer.from(base64, 'base64');\n return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n}\n\n// ── HKDF-SHA256 ────────────────────────────────────────────────────────\n\n/**\n * HKDF-SHA256 (RFC 5869) — matches the Swift SecureEnclaveManager.deriveKey implementation.\n *\n * We implement this manually rather than using Web Crypto's built-in HKDF because\n * the Web Crypto HKDF requires importing the input key material as a CryptoKey,\n * which adds complexity. This manual implementation is a direct port of the Swift code.\n */\nasync function hkdfSha256(\n ikm: Uint8Array,\n salt: Uint8Array,\n info: Uint8Array,\n outputByteCount: number,\n): Promise<Uint8Array> {\n // HKDF-Extract: PRK = HMAC-SHA256(salt, IKM)\n const saltKey = await subtle.importKey('raw', bs(salt), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n const prk = new Uint8Array(await subtle.sign('HMAC', saltKey, bs(ikm)));\n\n // HKDF-Expand: OKM = T(1) || T(2) || ...\n const prkKey = await subtle.importKey('raw', bs(prk), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n const okm = new Uint8Array(outputByteCount);\n let t = new Uint8Array(0);\n let offset = 0;\n let counter = 1;\n\n while (offset < outputByteCount) {\n const input = concatBuffers(t, info, new Uint8Array([counter]));\n t = new Uint8Array(await subtle.sign('HMAC', prkKey, bs(input)));\n okm.set(t.slice(0, Math.min(t.length, outputByteCount - offset)), offset);\n offset += t.length;\n counter++;\n }\n\n return okm;\n}\n\n// ── Key management ─────────────────────────────────────────────────────\n\n/** Import a public key from its base64-encoded uncompressed representation. */\nasync function importPublicKey(base64: string): Promise<CryptoKey> {\n return subtle.importKey('raw', bs(base64ToUint8(base64)), EC_ALGORITHM, true, []);\n}\n\n/** Import a private key from its base64-encoded PKCS8 representation. */\nasync function importPrivateKey(base64: string): Promise<CryptoKey> {\n return subtle.importKey('pkcs8', bs(base64ToUint8(base64)), EC_ALGORITHM, true, ['deriveBits']);\n}\n\n/** Generate a new P-256 ECDH key pair. */\nexport async function createKeyPair(): Promise<EcKeyPair> {\n const keyPair = await subtle.generateKey(EC_ALGORITHM, true, ['deriveBits']);\n\n const publicKeyRaw = await subtle.exportKey('raw', keyPair.publicKey);\n const privateKeyPkcs8 = await subtle.exportKey('pkcs8', keyPair.privateKey);\n\n return {\n publicKey: bufferToBase64(publicKeyRaw),\n privateKey: bufferToBase64(privateKeyPkcs8),\n };\n}\n\n// ── ECIES encrypt ──────────────────────────────────────────────────────\n\n/**\n * Encrypt plaintext using ECIES with the recipient's public key.\n *\n * @param publicKeyBase64 - Base64-encoded uncompressed P-256 public key (65 bytes raw)\n * @param plaintext - UTF-8 string to encrypt\n * @returns Base64-encoded ciphertext payload\n */\nexport async function encrypt(publicKeyBase64: string, plaintext: string): Promise<string> {\n const recipientPublicKey = await importPublicKey(publicKeyBase64);\n const recipientPubKeyRaw = base64ToUint8(publicKeyBase64);\n\n // Generate ephemeral key pair\n const ephemeralKeyPair = await subtle.generateKey(EC_ALGORITHM, true, ['deriveBits']);\n const ephemeralPubKeyRaw = new Uint8Array(await subtle.exportKey('raw', ephemeralKeyPair.publicKey));\n\n // ECDH: ephemeral private × recipient public → shared secret (32 bytes for P-256)\n const sharedSecretBits = await subtle.deriveBits(\n { name: 'ECDH', public: recipientPublicKey },\n ephemeralKeyPair.privateKey,\n 256,\n );\n const sharedSecret = new Uint8Array(sharedSecretBits);\n\n // HKDF-SHA256 → AES-256 key\n const info = concatBuffers(ephemeralPubKeyRaw, recipientPubKeyRaw);\n const aesKey = await hkdfSha256(sharedSecret, HKDF_SALT, info, 32);\n\n // AES-256-GCM encrypt\n const nonce = webcrypto.getRandomValues(new Uint8Array(NONCE_LENGTH));\n const plaintextBytes = new TextEncoder().encode(plaintext);\n\n const cryptoKey = await subtle.importKey('raw', bs(aesKey), 'AES-GCM', false, ['encrypt']);\n const encrypted = new Uint8Array(\n await subtle.encrypt({ name: 'AES-GCM', iv: bs(nonce), tagLength: TAG_LENGTH * 8 }, cryptoKey, bs(plaintextBytes)),\n );\n\n // Web Crypto appends the tag to ciphertext — split them to match Swift format\n const ciphertext = encrypted.slice(0, encrypted.length - TAG_LENGTH);\n const tag = encrypted.slice(encrypted.length - TAG_LENGTH);\n\n // Assemble payload: version(1) | ephemeralPub(65) | nonce(12) | ciphertext(N) | tag(16)\n const payload = concatBuffers(\n new Uint8Array([PAYLOAD_VERSION]),\n ephemeralPubKeyRaw,\n nonce,\n ciphertext,\n tag,\n );\n\n return bufferToBase64(payload);\n}\n\n// ── ECIES decrypt ──────────────────────────────────────────────────────\n\n/**\n * Decrypt ciphertext using ECIES with the recipient's private key.\n *\n * @param privateKeyBase64 - Base64-encoded PKCS8 private key\n * @param publicKeyBase64 - Base64-encoded uncompressed P-256 public key of the recipient\n * @param ciphertextBase64 - Base64-encoded ciphertext payload\n * @returns Decrypted UTF-8 string\n */\nexport async function decrypt(\n privateKeyBase64: string,\n publicKeyBase64: string,\n ciphertextBase64: string,\n): Promise<string> {\n const payloadBytes = base64ToUint8(ciphertextBase64);\n\n if (payloadBytes.byteLength < HEADER_LENGTH + TAG_LENGTH) {\n throw new Error('Payload too short');\n }\n\n // Parse payload\n const version = payloadBytes[0];\n if (version !== PAYLOAD_VERSION) {\n throw new Error(`Unsupported payload version: ${version}`);\n }\n\n const ephemeralPubKeyRaw = payloadBytes.slice(1, 1 + PUBLIC_KEY_LENGTH);\n const nonce = payloadBytes.slice(1 + PUBLIC_KEY_LENGTH, HEADER_LENGTH);\n const ciphertextAndTag = payloadBytes.slice(HEADER_LENGTH);\n\n if (ciphertextAndTag.length < TAG_LENGTH) {\n throw new Error('Payload too short for tag');\n }\n\n // Import keys\n const privateKey = await importPrivateKey(privateKeyBase64);\n const ephemeralPublicKey = await subtle.importKey('raw', bs(ephemeralPubKeyRaw), EC_ALGORITHM, true, []);\n\n // Recipient public key bytes for HKDF info\n const recipientPubKeyRaw = base64ToUint8(publicKeyBase64);\n\n // ECDH: recipient private × ephemeral public → shared secret\n const sharedSecretBits = await subtle.deriveBits(\n { name: 'ECDH', public: ephemeralPublicKey },\n privateKey,\n 256,\n );\n const sharedSecret = new Uint8Array(sharedSecretBits);\n\n // HKDF-SHA256 → AES-256 key (must match encrypt side)\n const info = concatBuffers(ephemeralPubKeyRaw, recipientPubKeyRaw);\n const aesKey = await hkdfSha256(sharedSecret, HKDF_SALT, info, 32);\n\n // AES-256-GCM decrypt\n // Web Crypto expects ciphertext + tag concatenated\n const cryptoKey = await subtle.importKey('raw', bs(aesKey), 'AES-GCM', false, ['decrypt']);\n try {\n const decrypted = await subtle.decrypt(\n { name: 'AES-GCM', iv: bs(nonce), tagLength: TAG_LENGTH * 8 },\n cryptoKey,\n bs(ciphertextAndTag), // already ciphertext || tag\n );\n return new TextDecoder().decode(decrypted);\n } catch (err) {\n throw new Error(\n 'Unable to decrypt value',\n { cause: err },\n );\n }\n}\n","/**\n * File-based local encryption backend.\n *\n * Stores P-256 ECDH key pairs as JSON files on disk with restricted permissions.\n * Uses the pure JS ECIES implementation for all crypto operations.\n * Works on all platforms — no native binary required.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { getUserVarlockDir } from '../user-config-dir';\nimport { createKeyPair, encrypt, decrypt } from './crypto';\n\nconst KEY_STORE_SUBDIR = 'local-encrypt/keys';\nconst DEFAULT_KEY_ID = 'varlock-default';\n\ninterface StoredKeyPair {\n keyId: string;\n publicKey: string;\n privateKey: string;\n protectedPrivateKey?: string;\n protection?: 'none' | string;\n createdAt: string;\n}\n\nfunction getKeyStorePath(): string {\n return path.join(getUserVarlockDir(), KEY_STORE_SUBDIR);\n}\n\nfunction getKeyFilePath(keyId: string): string {\n return path.join(getKeyStorePath(), `${keyId}.json`);\n}\n\n// ── Key management ─────────────────────────────────────────────────────\n\nexport function keyExists(keyId: string = DEFAULT_KEY_ID): boolean {\n return fs.existsSync(getKeyFilePath(keyId));\n}\n\nexport async function generateKey(keyId: string = DEFAULT_KEY_ID): Promise<{ keyId: string; publicKey: string }> {\n const keyPair = await createKeyPair();\n\n const stored: StoredKeyPair = {\n keyId,\n publicKey: keyPair.publicKey,\n privateKey: keyPair.privateKey,\n createdAt: new Date().toISOString(),\n };\n\n const keyStorePath = getKeyStorePath();\n fs.mkdirSync(keyStorePath, { recursive: true });\n\n const filePath = getKeyFilePath(keyId);\n fs.writeFileSync(filePath, JSON.stringify(stored, null, 2), { mode: 0o600 });\n\n return { keyId, publicKey: keyPair.publicKey };\n}\n\nexport function deleteKey(keyId: string = DEFAULT_KEY_ID): boolean {\n const filePath = getKeyFilePath(keyId);\n try {\n fs.unlinkSync(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function listKeys(): Array<string> {\n const keyStorePath = getKeyStorePath();\n try {\n return fs.readdirSync(keyStorePath)\n .filter((f) => f.endsWith('.json'))\n .map((f) => f.slice(0, -5));\n } catch {\n return [];\n }\n}\n\n// ── Internal key loading ───────────────────────────────────────────────\n\nfunction loadKeyPair(keyId: string): StoredKeyPair {\n const filePath = getKeyFilePath(keyId);\n if (!fs.existsSync(filePath)) {\n throw new Error(`Key not found: ${keyId}`);\n }\n const data = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(data) as Partial<StoredKeyPair>;\n\n // Back-compat: older key files store private material under\n // `protectedPrivateKey` with `protection: \"none\"`.\n const privateKey = parsed.privateKey\n ?? (parsed.protection === 'none' ? parsed.protectedPrivateKey : undefined)\n ?? parsed.protectedPrivateKey;\n\n if (!parsed.publicKey || !privateKey) {\n throw new Error(`Invalid key file format for key: ${keyId}`);\n }\n\n return {\n keyId: parsed.keyId || keyId,\n publicKey: parsed.publicKey,\n privateKey,\n createdAt: parsed.createdAt || new Date().toISOString(),\n protection: parsed.protection,\n protectedPrivateKey: parsed.protectedPrivateKey,\n };\n}\n\nfunction getPublicKey(keyId: string): string {\n return loadKeyPair(keyId).publicKey;\n}\n\n// ── Encrypt / Decrypt ──────────────────────────────────────────────────\n\nexport async function encryptValue(plaintext: string, keyId: string = DEFAULT_KEY_ID): Promise<string> {\n const publicKey = getPublicKey(keyId);\n return encrypt(publicKey, plaintext);\n}\n\nexport async function decryptValue(ciphertext: string, keyId: string = DEFAULT_KEY_ID): Promise<string> {\n const stored = loadKeyPair(keyId);\n return decrypt(stored.privateKey, stored.publicKey, ciphertext);\n}\n","/**\n * Cross-platform local encryption for varlock.\n *\n * Provides a unified API for encrypting/decrypting secrets using the best\n * available backend on the current platform:\n *\n * 1. macOS Secure Enclave (Swift binary) — hardware-backed, Touch ID\n * 2. Windows TPM/Hello (Rust binary) — hardware-backed, Windows Hello (TODO)\n * 3. Linux TPM2 (Rust binary) — hardware-backed (TODO)\n * 4. File-based (pure JS) — universal fallback, no native binary needed\n */\n\nimport { execFileSync, spawnSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport { resolveNativeBinary } from './binary-resolver';\nimport { DaemonClient } from './daemon-client';\nimport * as fileBackend from './file-backend';\nimport { isWSL } from './wsl-detect';\nimport type { BackendInfo, BackendType, NativeStatusResult } from './types';\n\nexport type { BackendInfo, BackendType } from './types';\n\nconst DEFAULT_KEY_ID = 'varlock-default';\n\n/** Debug logger — prints to stderr when VARLOCK_DEBUG is set */\nfunction debug(msg: string) {\n if (process.env.VARLOCK_DEBUG) {\n process.stderr.write(`[varlock:local-encrypt] ${msg}\\n`);\n }\n}\n\nconst SHELL_RUNNER_NAMES = new Set(['sh', 'bash', 'zsh', 'dash', 'fish', 'ksh', 'csh', 'tcsh']);\nconst VARLOCK_LAUNCHER_NAMES = new Set(['varlock', 'varlock.exe', 'varlock.cmd']);\nconst PACKAGE_MANAGER_RUNNER_NAMES = new Set(['bun', 'node', 'npm', 'npx', 'pnpm', 'pnpx', 'yarn', 'yarnpkg']);\nconst NO_TTY_SESSION_ENV_KEYS = [\n 'CODEX_THREAD_ID',\n 'CLAUDE_CODE_SESSION_ID',\n 'CLAUDE_SESSION_ID',\n] as const;\n\nfunction getProcessName(pid: number): string | undefined {\n try {\n const exePath = fs.readlinkSync(`/proc/${pid}/exe`);\n return exePath.split('/').pop()?.toLowerCase();\n } catch { /* ignore */ }\n try {\n return fs.readFileSync(`/proc/${pid}/comm`, 'utf-8').trim().toLowerCase();\n } catch {\n return undefined;\n }\n}\n\nfunction getProcessArgs(pid: number): Array<string> {\n try {\n return fs.readFileSync(`/proc/${pid}/cmdline`, 'utf-8').split('\\0').filter(Boolean);\n } catch {\n return [];\n }\n}\n\nfunction processCommandLineLaunchesVarlock(pid: number): boolean {\n return getProcessArgs(pid).some((arg) => {\n const name = arg.split('/').pop()?.toLowerCase();\n return Boolean(\n (name && VARLOCK_LAUNCHER_NAMES.has(name))\n || arg.includes('/node_modules/.bin/varlock')\n || arg.includes('/varlock/bin/cli.js')\n || arg.includes('/packages/varlock/bin/cli.js'),\n );\n });\n}\n\nfunction isEphemeralRunner(pid: number): boolean {\n const name = getProcessName(pid);\n if (!name) return false;\n if (SHELL_RUNNER_NAMES.has(name) || VARLOCK_LAUNCHER_NAMES.has(name)) return true;\n return PACKAGE_MANAGER_RUNNER_NAMES.has(name) && processCommandLineLaunchesVarlock(pid);\n}\n\nfunction selectScopePidFromChain(chain: Array<number>): number | undefined {\n if (chain.length < 2) return undefined;\n\n if (chain.length >= 4) {\n let scopePid = chain[chain.length - 3];\n if (isEphemeralRunner(scopePid)) {\n const fallback = chain[chain.length - 2];\n scopePid = isEphemeralRunner(fallback) ? chain[chain.length - 1] : fallback;\n }\n return scopePid;\n }\n\n return chain[chain.length - 1];\n}\n\nfunction getProcessStartTime(pid: number): number {\n try {\n const scopeStat = fs.readFileSync(`/proc/${pid}/stat`, 'utf-8');\n const scopeFields = scopeStat.split(') ');\n if (scopeFields.length >= 2) {\n return parseInt(scopeFields[1].split(' ')[19], 10) || 0;\n }\n } catch { /* ignore */ }\n return 0;\n}\n\nfunction getNoTtySessionIdFromEnv(): string | undefined {\n for (const key of NO_TTY_SESSION_ENV_KEYS) {\n const value = process.env[key]?.trim();\n if (value) return `env:${key}:${value}`;\n }\n return undefined;\n}\n\nfunction getParentSessionId(): string {\n try {\n const ttyPath = fs.readlinkSync('/proc/self/fd/0');\n if (ttyPath && ttyPath.startsWith('/dev/')) {\n return ttyPath;\n }\n } catch {\n // Not available\n }\n\n try {\n const chain: Array<number> = [process.pid];\n let current = process.pid;\n for (let i = 0; i < 64; i++) {\n const stat = fs.readFileSync(`/proc/${current}/stat`, 'utf-8');\n const fields = stat.split(') ');\n if (fields.length < 2) break;\n const ppid = parseInt(fields[1].split(' ')[1], 10);\n if (!ppid || ppid <= 1) break;\n chain.push(ppid);\n current = ppid;\n }\n const scopePid = selectScopePidFromChain(chain);\n if (scopePid !== undefined) {\n const startTime = getProcessStartTime(scopePid);\n return `ptree:${scopePid}:${startTime}`;\n }\n } catch {\n // Not available\n }\n\n return `pid:${process.pid}`;\n}\n\n/**\n * Get a session identifier for biometric session scoping (WSL only).\n * Prefers the controlling terminal; falls back to a stable ancestor PID\n * found by walking the process tree (mirrors the macOS Swift daemon logic).\n */\nlet _cachedSessionId: string | undefined;\nfunction getSelfSessionId(): string {\n if (_cachedSessionId) return _cachedSessionId;\n\n const parentSessionId = getParentSessionId();\n const envSessionId = getNoTtySessionIdFromEnv();\n if (envSessionId) {\n _cachedSessionId = `${envSessionId}|${parentSessionId}`;\n return _cachedSessionId;\n }\n\n _cachedSessionId = parentSessionId;\n return _cachedSessionId;\n}\n\nlet _wslDaemonPrestartAttempted = false;\n\nfunction toWindowsPathFromWsl(pathInWsl: string): string | undefined {\n if (!isWSL()) return undefined;\n try {\n return execFileSync('wslpath', ['-w', pathInWsl], {\n encoding: 'utf-8',\n timeout: 10_000,\n }).trim();\n } catch (err) {\n debug(`toWindowsPathFromWsl failed: ${err instanceof Error ? err.message : err}`);\n return undefined;\n }\n}\n\nfunction tryPrestartWindowsDaemonFromWsl(binaryPath: string): boolean {\n if (_wslDaemonPrestartAttempted) {\n return true;\n }\n\n const windowsPath = toWindowsPathFromWsl(binaryPath);\n if (!windowsPath) {\n return false;\n }\n\n // Ask native PowerShell to seed the daemon in the interactive desktop\n // session. This returns quickly; the follow-up decrypt call has a longer\n // timeout and the helper's own daemon retry path to absorb startup latency.\n const escapedPath = windowsPath.replaceAll(\"'\", \"''\");\n const psScript = `Start-Process -WindowStyle Hidden -FilePath '${escapedPath}' -ArgumentList 'start-daemon'`;\n const proc = spawnSync('powershell.exe', [\n '-NoProfile',\n '-NonInteractive',\n '-ExecutionPolicy',\n 'Bypass',\n '-Command',\n psScript,\n ], {\n encoding: 'utf-8',\n timeout: 20_000,\n });\n\n if (proc.error) {\n debug(`tryPrestartWindowsDaemonFromWsl: powershell error: ${proc.error.message}`);\n return false;\n }\n if (proc.status !== 0) {\n debug(`tryPrestartWindowsDaemonFromWsl: powershell exit ${proc.status}: ${(proc.stderr || proc.stdout || '').trim()}`);\n return false;\n }\n\n debug('tryPrestartWindowsDaemonFromWsl: start-daemon invoked via PowerShell');\n _wslDaemonPrestartAttempted = true;\n return true;\n}\n\nfunction pingWindowsDaemonFromWsl(binaryPath: string, timeoutMs: number = 2_000): boolean {\n const proc = spawnSync(binaryPath, ['ping-daemon'], {\n encoding: 'utf-8',\n timeout: timeoutMs,\n });\n\n if (proc.error || proc.status !== 0) {\n return false;\n }\n\n try {\n const parsed = JSON.parse((proc.stdout || '').trim()) as { ready?: boolean };\n return parsed.ready === true;\n } catch {\n return false;\n }\n}\n\nfunction waitForWindowsDaemonFromWsl(binaryPath: string, timeoutMs: number = 12_000): boolean {\n const deadline = Date.now() + timeoutMs;\n\n while (Date.now() < deadline) {\n if (pingWindowsDaemonFromWsl(binaryPath)) {\n debug('waitForWindowsDaemonFromWsl: daemon is ready');\n return true;\n }\n\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 150);\n }\n\n debug('waitForWindowsDaemonFromWsl: timed out waiting for daemon readiness');\n return false;\n}\n\n// ── Native binary one-shot commands ────────────────────────────────────\n\nfunction runNativeBinary(args: Array<string>, opts?: { timeout?: number }): string {\n const binaryPath = resolveNativeBinary();\n if (!binaryPath) {\n debug('runNativeBinary: no binary found');\n throw new Error('Native binary not found');\n }\n debug(`runNativeBinary: ${binaryPath} ${args.join(' ')}`);\n const output = execFileSync(binaryPath, args, {\n encoding: 'utf-8',\n timeout: opts?.timeout ?? 30_000,\n }).trim();\n debug(`runNativeBinary result: ${output.slice(0, 200)}`);\n return output;\n}\n\nfunction runNativeBinaryJson<T = Record<string, unknown>>(args: Array<string>, opts?: { timeout?: number }): T {\n const output = runNativeBinary(args, opts);\n const parsed = JSON.parse(output);\n if (parsed.error) {\n throw new Error(parsed.error);\n }\n return parsed as T;\n}\n\n// ── Backend detection ──────────────────────────────────────────────────\n\nlet cachedBackendInfo: BackendInfo | undefined;\n/** Keys reported by the status command — avoids a separate key-exists .exe spawn on WSL2 */\nlet cachedStatusKeys: Array<string> | undefined;\n\nfunction detectBackendType(): { type: BackendType; isFileFallback: boolean } {\n const binaryPath = resolveNativeBinary();\n debug(`detectBackendType: binaryPath=${binaryPath ?? 'NOT FOUND'}, isWSL=${isWSL()}, platform=${process.platform}`);\n if (!binaryPath) {\n // All supported platforms (macOS, Windows, Linux, WSL2) should have a native binary\n const isFileFallback = ['darwin', 'win32', 'linux'].includes(process.platform);\n return { type: 'file', isFileFallback };\n }\n\n // WSL2 uses the Windows binary for DPAPI + Windows Hello\n if (isWSL()) return { type: 'windows-tpm', isFileFallback: false };\n\n switch (process.platform) {\n case 'darwin': return { type: 'secure-enclave', isFileFallback: false };\n case 'win32': return { type: 'windows-tpm', isFileFallback: false };\n case 'linux': return { type: 'linux-tpm', isFileFallback: false };\n default: return { type: 'file', isFileFallback: false };\n }\n}\n\n/** Get information about the active encryption backend. */\nexport function getBackendInfo(): BackendInfo {\n if (cachedBackendInfo) return cachedBackendInfo;\n\n const { type, isFileFallback } = detectBackendType();\n const binaryPath = type !== 'file' ? resolveNativeBinary() : undefined;\n\n if (type !== 'file' && binaryPath) {\n // Query the native binary for its actual capabilities\n try {\n const status = runNativeBinaryJson<NativeStatusResult>(['status']);\n debug(`getBackendInfo: status result: hardwareBacked=${status.hardwareBacked}, biometricAvailable=${status.biometricAvailable}, backend=${status.backend}, keys=${status.keys?.join(',')}`);\n cachedStatusKeys = status.keys;\n cachedBackendInfo = {\n type,\n platform: process.platform,\n hardwareBacked: status.hardwareBacked,\n biometricAvailable: status.biometricAvailable,\n binaryPath,\n };\n } catch (err) {\n // Binary failed — fall back to reasonable defaults\n debug(`getBackendInfo: status command failed: ${err instanceof Error ? err.message : err}`);\n cachedBackendInfo = {\n type,\n platform: process.platform,\n hardwareBacked: type === 'secure-enclave',\n biometricAvailable: type === 'secure-enclave',\n binaryPath,\n };\n }\n } else {\n debug(`getBackendInfo: using file backend (type=${type}, binaryPath=${binaryPath ?? 'none'}, isFileFallback=${isFileFallback})`);\n if (isFileFallback && !process.env._VARLOCK_FORCE_FILE_ENCRYPTION_FALLBACK) {\n process.stderr.write(\n '[varlock] Warning: native encryption binary not found, falling back to file-based encryption (not hardware-backed)\\n',\n );\n }\n cachedBackendInfo = {\n type,\n platform: process.platform,\n hardwareBacked: false,\n biometricAvailable: false,\n binaryPath: undefined,\n isFileFallback,\n };\n }\n\n debug(`getBackendInfo: final result: type=${cachedBackendInfo!.type}, biometric=${cachedBackendInfo!.biometricAvailable}, hwBacked=${cachedBackendInfo!.hardwareBacked}`);\n return cachedBackendInfo!;\n}\n\n// ── Daemon client (singleton for biometric-enabled backends) ───────────\n\nlet daemonClient: DaemonClient | undefined;\n\nexport function getDaemonClient(): DaemonClient {\n daemonClient ||= new DaemonClient();\n return daemonClient;\n}\n\n// ── Key management ─────────────────────────────────────────────────────\n\n/** Check if a key exists. */\nexport function keyExists(keyId: string = DEFAULT_KEY_ID): boolean {\n const backend = getBackendInfo();\n if (backend.type === 'file') {\n return fileBackend.keyExists(keyId);\n }\n // Use cached keys from status command to avoid an extra .exe spawn (significant on WSL2)\n if (cachedStatusKeys) {\n debug(`keyExists: using cached status keys for ${keyId}`);\n return cachedStatusKeys.includes(keyId);\n }\n const result = runNativeBinaryJson<{ exists: boolean }>(['key-exists', '--key-id', keyId]);\n return result.exists;\n}\n\n/** Generate a new encryption key. */\nexport async function generateKey(keyId: string = DEFAULT_KEY_ID): Promise<{ keyId: string; publicKey: string }> {\n const backend = getBackendInfo();\n if (backend.type === 'file') {\n return fileBackend.generateKey(keyId);\n }\n return runNativeBinaryJson<{ keyId: string; publicKey: string }>(['generate-key', '--key-id', keyId]);\n}\n\n/** Ensure a key exists, generating one if necessary. */\nexport async function ensureKey(keyId: string = DEFAULT_KEY_ID): Promise<void> {\n if (!keyExists(keyId)) {\n await generateKey(keyId);\n }\n}\n\n// ── Encrypt / Decrypt ──────────────────────────────────────────────────\n\n/**\n * Encrypt a plaintext value.\n *\n * For hardware-backed backends, encryption uses the public key only (no biometric needed).\n * For file-based backend, uses the pure JS ECIES implementation.\n */\nexport async function encryptValue(plaintext: string, keyId: string = DEFAULT_KEY_ID): Promise<string> {\n const backend = getBackendInfo();\n if (backend.type === 'file') {\n return fileBackend.encryptValue(plaintext, keyId);\n }\n // Native binary encrypt (one-shot, no biometric needed for encrypt)\n const b64Input = Buffer.from(plaintext, 'utf-8').toString('base64');\n if (isWSL()) {\n // On WSL2, pass data via stdin to avoid arg mangling across the WSL/Windows boundary\n const binaryPath = resolveNativeBinary();\n if (!binaryPath) throw new Error('Native binary not found');\n const proc = spawnSync(binaryPath, ['encrypt', '--key-id', keyId, '--data-stdin'], {\n input: b64Input,\n encoding: 'utf-8',\n timeout: 30_000,\n });\n if (proc.error) throw proc.error;\n const result = JSON.parse(proc.stdout.trim());\n if (result.error) throw new Error(result.error);\n return result.ciphertext;\n }\n const result = runNativeBinaryJson<{ ciphertext: string }>(['encrypt', '--key-id', keyId, '--data', b64Input]);\n return result.ciphertext;\n}\n\n/**\n * Decrypt a ciphertext value.\n *\n * For biometric-enabled backends (macOS Secure Enclave, Windows Hello),\n * uses the daemon client for session caching (avoids repeated biometric prompts).\n * For file-based backend, uses the pure JS ECIES implementation.\n */\nexport async function decryptValue(ciphertext: string, keyId: string = DEFAULT_KEY_ID): Promise<string> {\n const backend = getBackendInfo();\n if (backend.type === 'file') {\n debug('decryptValue: using file backend');\n return fileBackend.decryptValue(ciphertext, keyId);\n }\n\n // Use daemon client for biometric backends (session caching)\n // In WSL2, the .exe handles daemon management internally via --via-daemon\n if (backend.biometricAvailable) {\n if (isWSL()) {\n debug('decryptValue: WSL2 biometric decrypt via --via-daemon');\n const binaryPath = resolveNativeBinary();\n if (!binaryPath) throw new Error('Native binary not found');\n const daemonAlreadyReady = pingWindowsDaemonFromWsl(binaryPath, 1_500);\n const daemonPrestarted = daemonAlreadyReady || tryPrestartWindowsDaemonFromWsl(binaryPath);\n if (!daemonAlreadyReady && daemonPrestarted) {\n waitForWindowsDaemonFromWsl(binaryPath);\n }\n // Use spawnSync with stdin to avoid exposing ciphertext or session\n // identity in process listings (visible via tasklist/procfs).\n // Stdin JSON includes both the data and the session ID for session scoping.\n const stdinPayload = JSON.stringify({\n data: ciphertext,\n ttyId: getSelfSessionId(),\n });\n const runViaDaemon = (timeout: number) => spawnSync(binaryPath, ['decrypt', '--key-id', keyId, '--data-stdin', '--via-daemon'], {\n input: stdinPayload,\n encoding: 'utf-8',\n timeout,\n });\n\n let proc = runViaDaemon(daemonPrestarted ? 120_000 : 60_000);\n\n const output = (proc.stdout || proc.stderr || '').trim();\n const timedOut = proc.error && (proc.error as NodeJS.ErrnoException).code === 'ETIMEDOUT';\n const needsRetry = Boolean(proc.error) || proc.status !== 0;\n const likelyDaemonStartupIssue = timedOut\n || /daemon is not running|daemon did not become ready within timeout|schtasks|windows hello daemon/i.test(output);\n\n if (needsRetry && likelyDaemonStartupIssue) {\n debug(`decryptValue: via-daemon startup issue detected; attempting native start-daemon bridge. output=${output.slice(0, 180)}`);\n if (tryPrestartWindowsDaemonFromWsl(binaryPath)) {\n // Give the daemon a little more room on first auth after bridge start.\n proc = runViaDaemon(120_000);\n }\n }\n\n if (proc.error) throw proc.error;\n if (proc.status !== 0) {\n const finalOutput = (proc.stdout || proc.stderr || '').trim();\n try {\n const parsed = JSON.parse(finalOutput);\n if (parsed.error) throw new Error(parsed.error);\n } catch { /* not JSON */ }\n\n const windowsPath = toWindowsPathFromWsl(binaryPath);\n const setupHint = windowsPath\n ? `\\nHint: In native Windows PowerShell run:\\n Start-Process -WindowStyle Hidden \"${windowsPath}\" start-daemon`\n : '';\n throw new Error(`Decrypt failed (exit ${proc.status}): ${finalOutput}${setupHint}`);\n }\n\n const result = JSON.parse(proc.stdout.trim());\n if (result.error) throw new Error(result.error);\n debug(`decryptValue: WSL2 result: ${proc.stdout.trim().slice(0, 100)}`);\n return result.plaintext;\n }\n debug('decryptValue: biometric decrypt via daemon client');\n const client = getDaemonClient();\n return client.decrypt(ciphertext, keyId);\n }\n\n // Non-biometric native backend (e.g., Linux TPM without polkit) — one-shot\n debug('decryptValue: non-biometric one-shot decrypt');\n const result = runNativeBinaryJson<{ plaintext: string }>(['decrypt', '--key-id', keyId, '--data', ciphertext]);\n return result.plaintext;\n}\n\n/**\n * Invalidate the biometric session, requiring re-authentication for next decrypt.\n * Connects to the running daemon without spawning one (varlock lock runs in a separate process).\n */\nexport async function lockSession(): Promise<void> {\n const backend = getBackendInfo();\n if (!backend.biometricAvailable) return;\n const client = getDaemonClient();\n const connected = await client.tryConnect();\n if (!connected) {\n throw new Error('No encryption daemon is running');\n }\n await client.invalidateSession();\n}\n"]}