Lines 14-54javascript
14// is NOT encrypted; it is plaintext that the OS protects with file permissions.
15// The agent is also blocked from reading that path (see safety/patterns.ts).
16const keychainModuleName = '@napi-rs/keyring/keytar.js';
17const keysFile = join(homedir(), '.clai', 'keys.json');
19let keytarLoadAttempted = false;
20// On many Linux servers and most Windows non-interactive sessions the
21// napi-rs keyring binary loads cleanly but the underlying OS keystore
22// (libsecret/DBus on Linux, Windows Credential Manager) is unreachable.
23// In that case the first call fails — we record it and stop trying
24// for the rest of the process so every read/write/delete falls back
25// to the restricted-permission plaintext JSON file silently.
26let keychainRuntimeUnavailable = false;
27let keychainRuntimeWarned = false;
28async function loadKeytar() {
31 if (keytarLoadAttempted)
33 keytarLoadAttempted = true;
35 const imported = (await import(keychainModuleName));
36 cachedKeytar = imported.default ?? imported;
MediumDynamic Require
Package source references dynamic require/import behavior.
dist/store/keys.jsView on unpkg · L34 43function isMissingKeychainError(error) {
44 // Best-effort detection so transient errors (eg locked keychain prompt
45 // dismissed) don't permanently disable the keychain. Anything that
46 // looks like a missing-platform-service signature gets latched off.
47 const message = error instanceof Error ? error.message : String(error);
48 return /(no such (?:bus|service)|secret service|libsecret|dbus|keyring|gnome-keyring|kwallet|credential|keychain|security framework|access denied|not (?:available|implemented))/i.test(message);
50function noteKeychainRuntimeFailure(error) {
51 if (isMissingKeychainError(error))
52 keychainRuntimeUnavailable = true;
53 if (!keychainRuntimeWarned) {
54 keychainRuntimeWarned = true;