Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ jobs:
if: runner.os == 'Linux'
uses: t1m0thyj/unlock-keyring@v1

- name: Install Secret Service CLI
if: runner.os == 'Linux'
run: sudo apt-get install -qq libsecret-tools

- name: Run tests (extended timeout)
timeout-minutes: 15
# Unit tests must pass for fork PRs (no secrets). Keep API-dependent tests
Expand Down
6 changes: 0 additions & 6 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,6 @@ if (content.startsWith("#!")) {
content = content.slice(content.indexOf("\n") + 1);
}

// Patch secrets requirement back in for node build
content = content.replace(
`(()=>{throw new Error("Cannot require module "+"bun");})().secrets`,
`globalThis.Bun.secrets`,
);

const withShebang = `#!/usr/bin/env node
${content}`;
await Bun.write(outputPath, withShebang);
Expand Down
10 changes: 10 additions & 0 deletions scripts/isolated-unit-tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@
"timeoutMs": 15000,
"reason": "Uses a top-level Bun module mock for the backend client."
},
{
"path": "src/utils/secret-backends.test.ts",
"timeoutMs": 30000,
"reason": "Mutates the secrets runtime override and service name while exercising the real OS credential store."
},
{
"path": "src/utils/secrets.test.ts",
"timeoutMs": 30000,
"reason": "Mutates the process-global secrets service name while exercising the real OS credential store."
},
{
"path": "src/websocket/listen-client-concurrency.test.ts",
"timeoutMs": 30000,
Expand Down
38 changes: 5 additions & 33 deletions scripts/postinstall-patches.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
// Postinstall patcher for vendoring our Ink modifications without patch-package.
// Copies patched runtime files from ./src/vendor into node_modules.

import { execSync } from "node:child_process";
import {
copyFileSync,
existsSync,
mkdirSync,
readFileSync,
writeFileSync,
} from "node:fs";
import { copyFileSync, existsSync, mkdirSync } from "node:fs";
import { createRequire } from "node:module";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
Expand Down Expand Up @@ -100,7 +93,10 @@ await copyToResolved(
"ink/build/hooks/use-input.js",
);
await copyToResolved("vendor/ink/build/devtools.js", "ink/build/devtools.js");
await copyToResolved("vendor/ink/build/log-update.js", "ink/build/log-update.js");
await copyToResolved(
"vendor/ink/build/log-update.js",
"ink/build/log-update.js",
);
await copyToResolved("vendor/ink/build/wrap-text.js", "ink/build/wrap-text.js");

// ink-text-input (optional vendor with externalCursorOffset support)
Expand All @@ -110,27 +106,3 @@ await copyToResolved(
);

console.log("[patch] Ink runtime patched");

// On Unix with Bun available, use polyglot shebang to prefer Bun runtime.
// This enables Bun.secrets for secure keychain storage instead of fallback.
// Windows always uses #!/usr/bin/env node (polyglot shebang breaks npm wrappers).
if (process.platform !== "win32") {
try {
execSync("bun --version", { stdio: "ignore" });
const lettaPath = join(pkgRoot, "letta.js");
if (existsSync(lettaPath)) {
let content = readFileSync(lettaPath, "utf-8");
if (content.startsWith("#!/usr/bin/env node")) {
content = content.replace(
"#!/usr/bin/env node",
`#!/bin/sh
":" //#; exec /usr/bin/env sh -c 'command -v bun >/dev/null && exec bun "$0" "$@" || exec node "$0" "$@"' "$0" "$@"`,
);
writeFileSync(lettaPath, content);
console.log("[patch] Configured letta to prefer Bun runtime");
}
}
} catch {
// Bun not available, keep node shebang
}
}
1 change: 1 addition & 0 deletions src/test-utils/test-process-env.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe("test process env helpers", () => {
expect(env.LETTA_MEMORY_DIR).toBeUndefined();
expect(env.MEMORY_DIR).toBeUndefined();
expect(env.LETTA_DISABLE_SESSION_PERSIST).toBe("1");
expect(env.LETTA_SKIP_KEYCHAIN_CHECK).toBe("1");
expect(env.DISABLE_AUTOUPDATER).toBe("1");
});

Expand Down
1 change: 1 addition & 0 deletions src/test-utils/test-process-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export function createIsolatedCliTestEnv(

Object.assign(env, {
LETTA_DISABLE_SESSION_PERSIST: "1",
LETTA_SKIP_KEYCHAIN_CHECK: "1",
DISABLE_AUTOUPDATER: "1",
});

Expand Down
Loading
Loading