Something went wrong. Try again.
A local-first event pipeline for independent agents, built on Jazz.
Something went wrong. Try again.
25 kB · 530 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531import fs from "node:fs/promises";import path from "node:path";import { spawn } from "node:child_process";import { randomUUID } from "node:crypto";import { afterEach, describe, expect, test } from "vitest";import { parseEnvironmentAssignments, splitServiceCredentialFile,} from "../src/runtime/credential-compartments.js";import { temporaryProject } from "./helpers.js";
const roots: string[] = [];
afterEach(async () => { await Promise.all(roots.splice(0).map((root) => fs.rm(root, { recursive: true, force: true })));});
describe("service credential compartments", () => { test("writes exact service-specific variable sets without exposing values in its receipt", async () => { const root = await temporaryProject("thoughtstream-credential-split-"); roots.push(root); const values = { letta: generatedValue("letta"), tinker: generatedValue("tinker"), agent: generatedValue("agent"), coAgent: generatedValue("co-agent"), blueskyListener: generatedValue("bluesky-listener"), xListener: generatedValue("x-listener"), socialListener: generatedValue("social-listener"), memory: generatedValue("memory-root"), policy: generatedValue("policy-path"), catalog: generatedValue("catalog-root"), bot: generatedValue("bot"), webhook: generatedValue("webhook"), xConsumer: generatedValue("x-consumer"), xManagement: generatedValue("x-management"), xUserManagement: generatedValue("x-user-management"), fastmail: generatedValue("fastmail"), }; const source = path.join(root, "source.env"); await fs.writeFile(source, [ `LETTA_API_KEY=${values.letta}`, `TINKER_API_KEY=${values.tinker}`, `THOUGHTSTREAM_LETTA_TELEGRAM_AGENT_ID=${values.agent}`, `THOUGHTSTREAM_LETTA_CO_AGENT_ID=${values.coAgent}`, `THOUGHTSTREAM_LETTA_BLUESKY_LISTENER_AGENT_ID=${values.blueskyListener}`, `THOUGHTSTREAM_LETTA_X_LISTENER_AGENT_ID=${values.xListener}`, `THOUGHTSTREAM_LETTA_SOCIAL_LISTENER_AGENT_ID=${values.socialListener}`, "THOUGHTSTREAM_LETTA_ENABLE_BLUESKY_LISTENER=1", "THOUGHTSTREAM_LETTA_ENABLE_X_LISTENER=1", "THOUGHTSTREAM_LETTA_ENABLE_SOCIAL_LISTENER=1", `THOUGHTSTREAM_LETTA_CO_MEMORY_DIR=${values.memory}`, "THOUGHTSTREAM_ENABLE_COIL_PUBLIC_KNOWLEDGE=1", `THOUGHTSTREAM_PUBLIC_KNOWLEDGE_POLICY_PATH=${values.policy}`, `THOUGHTSTREAM_PUBLIC_KNOWLEDGE_CATALOG_ROOT=${values.catalog}`, `THOUGHTSTREAM_TELEGRAM_BOT_TOKEN=${values.bot}`, `THOUGHTSTREAM_TELEGRAM_WEBHOOK_SECRET=${values.webhook}`, `THOUGHTSTREAM_X_CONSUMER_SECRET=${values.xConsumer}`, `THOUGHTSTREAM_X_MANAGEMENT_BEARER_TOKEN=${values.xManagement}`, `THOUGHTSTREAM_X_CAMERON_USER_ACCESS_TOKEN=${values.xUserManagement}`, `FASTMAIL_API_KEY=${values.fastmail}`, "THOUGHTSTREAM_X_API_BASE_URL=https://api.x.com", "THOUGHTSTREAM_TELEGRAM_API_BASE_URL=https://telegram.example.invalid", "THOUGHTSTREAM_JETSTREAM_URL=wss://jetstream.example.invalid/subscribe", "THOUGHTSTREAM_TINKER_REASONING_SMALL_MODEL=fixture/reasoning", "UNRELATED_CONFIGURATION=present", "", ].join("\n"), { mode: 0o600 }); const output = path.join(root, "credentials"); const receipt = await splitServiceCredentialFile(source, output, { consumerProviders: ["letta"], publicContentRoots: [], });
expect(receipt.files["telegram-webhook"].variableNames).toEqual([ "THOUGHTSTREAM_TELEGRAM_API_BASE_URL", "THOUGHTSTREAM_TELEGRAM_BOT_TOKEN", "THOUGHTSTREAM_TELEGRAM_WEBHOOK_SECRET", ]); expect(receipt.files["telegram-dispatcher"].variableNames).toEqual([ "THOUGHTSTREAM_TELEGRAM_API_BASE_URL", "THOUGHTSTREAM_TELEGRAM_BOT_TOKEN", ]); expect(receipt.files["x-webhook"].variableNames).toEqual([ "THOUGHTSTREAM_X_CONSUMER_SECRET", ]); expect(receipt.files["x-management"].variableNames).toEqual([ "THOUGHTSTREAM_X_API_BASE_URL", "THOUGHTSTREAM_X_MANAGEMENT_BEARER_TOKEN", ]); expect(receipt.files["x-user-management"].variableNames).toEqual([ "THOUGHTSTREAM_X_API_BASE_URL", "THOUGHTSTREAM_X_CAMERON_USER_ACCESS_TOKEN", ]); expect(receipt.files["fastmail-jmap"].variableNames).toEqual(["FASTMAIL_API_KEY"]); expect(receipt.files.consumer.variableNames).toEqual([ "LETTA_API_KEY", "THOUGHTSTREAM_ENABLE_COIL_PUBLIC_KNOWLEDGE", "THOUGHTSTREAM_LETTA_BLUESKY_LISTENER_AGENT_ID", "THOUGHTSTREAM_LETTA_CO_AGENT_ID", "THOUGHTSTREAM_LETTA_CO_MEMORY_DIR", "THOUGHTSTREAM_LETTA_ENABLE_BLUESKY_LISTENER", "THOUGHTSTREAM_LETTA_ENABLE_SOCIAL_LISTENER", "THOUGHTSTREAM_LETTA_ENABLE_X_LISTENER", "THOUGHTSTREAM_LETTA_SOCIAL_LISTENER_AGENT_ID", "THOUGHTSTREAM_LETTA_TELEGRAM_AGENT_ID", "THOUGHTSTREAM_LETTA_X_LISTENER_AGENT_ID", "THOUGHTSTREAM_PUBLIC_KNOWLEDGE_CATALOG_ROOT", "THOUGHTSTREAM_PUBLIC_KNOWLEDGE_POLICY_PATH", ]); expect(receipt.files.jetstream.variableNames).toEqual(["THOUGHTSTREAM_JETSTREAM_URL"]); expect(receipt.omittedVariableNames).toEqual([ "THOUGHTSTREAM_TINKER_REASONING_SMALL_MODEL", "TINKER_API_KEY", "UNRELATED_CONFIGURATION", ]); const receiptText = JSON.stringify(receipt); for (const value of Object.values(values)) expect(receiptText).not.toContain(value);
const webhookText = await fs.readFile(receipt.files["telegram-webhook"].path, "utf8"); const dispatcherText = await fs.readFile(receipt.files["telegram-dispatcher"].path, "utf8"); const consumerText = await fs.readFile(receipt.files.consumer.path, "utf8"); const jetstreamText = await fs.readFile(receipt.files.jetstream.path, "utf8"); const xWebhookText = await fs.readFile(receipt.files["x-webhook"].path, "utf8"); const xManagementText = await fs.readFile(receipt.files["x-management"].path, "utf8"); const xUserManagementText = await fs.readFile(receipt.files["x-user-management"].path, "utf8"); const fastmailText = await fs.readFile(receipt.files["fastmail-jmap"].path, "utf8"); expect(webhookText).toContain(values.bot); expect(webhookText).toContain(values.webhook); expect(webhookText).not.toContain(values.letta); expect(dispatcherText).toContain(values.bot); expect(dispatcherText).not.toContain(values.webhook); expect(dispatcherText).not.toContain(values.letta); expect(consumerText).toContain(values.letta); expect(consumerText).toContain(values.agent); expect(consumerText).toContain(values.coAgent); expect(consumerText).toContain(values.blueskyListener); expect(consumerText).toContain(values.xListener); expect(consumerText).toContain(values.socialListener); expect(consumerText).toContain(values.memory); expect(consumerText).toContain(values.policy); expect(consumerText).toContain(values.catalog); expect(consumerText).not.toContain(values.bot); expect(consumerText).not.toContain(values.tinker); expect(xWebhookText).toContain(values.xConsumer); expect(xWebhookText).not.toContain(values.xManagement); expect(xWebhookText).not.toContain(values.letta); expect(xManagementText).toContain(values.xManagement); expect(xManagementText).not.toContain(values.xConsumer); expect(xManagementText).not.toContain(values.letta); expect(xUserManagementText).toContain(values.xUserManagement); expect(xUserManagementText).not.toContain(values.xManagement); expect(xUserManagementText).not.toContain(values.xConsumer); expect(xUserManagementText).not.toContain(values.letta); expect(fastmailText).toContain(values.fastmail); expect(fastmailText).not.toContain(values.letta); expect(fastmailText).not.toContain(values.bot); for (const value of Object.values(values)) expect(jetstreamText).not.toContain(value);
expect((await fs.stat(output)).mode & 0o777).toBe(0o700); for (const file of Object.values(receipt.files)) { expect((await fs.stat(file.path)).mode & 0o777).toBe(0o600); } });
test("CLI receipt remains value-dark", async () => { const root = await temporaryProject("thoughtstream-credential-cli-"); roots.push(root); const source = path.join(root, "source.env"); const values = [generatedValue("letta"), generatedValue("agent"), generatedValue("bot"), generatedValue("webhook")]; await fs.writeFile(source, [ `LETTA_API_KEY=${values[0]}`, `THOUGHTSTREAM_LETTA_TELEGRAM_AGENT_ID=${values[1]}`, `THOUGHTSTREAM_TELEGRAM_BOT_TOKEN=${values[2]}`, `THOUGHTSTREAM_TELEGRAM_WEBHOOK_SECRET=${values[3]}`, "", ].join("\n"), { mode: 0o600 }); const result = await runSplitter(source, path.join(root, "credentials")); expect(result.code).toBe(0); expect(JSON.parse(result.stdout)).toMatchObject({ files: { "telegram-webhook": { variableNames: expect.any(Array) }, consumer: { variableNames: expect.any(Array) }, }, }); for (const value of values) { expect(result.stdout).not.toContain(value); expect(result.stderr).not.toContain(value); } }, 15_000);
test("refuses a partial source that would erase existing compartments before any write", async () => { const root = await temporaryProject("thoughtstream-credential-removal-preflight-"); roots.push(root); const source = path.join(root, "source.env"); const output = path.join(root, "credentials"); await fs.writeFile(source, validSource({ includeX: true }), { mode: 0o600 }); await splitServiceCredentialFile(source, output, { consumerProviders: ["letta"], publicContentRoots: [], }); const before = await directoryEntries(output);
await fs.writeFile(source, validSource(), { mode: 0o600 }); await expect(splitServiceCredentialFile(source, output, { consumerProviders: ["letta"], publicContentRoots: [], })).rejects.toThrow( "Credential split would remove existing assignments without explicit authorization: x-management:THOUGHTSTREAM_X_MANAGEMENT_BEARER_TOKEN, x-webhook:THOUGHTSTREAM_X_CONSUMER_SECRET", ); expect(await directoryEntries(output)).toEqual(before); });
test("requires the exact current variable-name set for intentional credential removal", async () => { const root = await temporaryProject("thoughtstream-credential-explicit-removal-"); roots.push(root); const source = path.join(root, "source.env"); const output = path.join(root, "credentials"); const fullSource = validSource({ includeX: true }); await fs.writeFile(source, fullSource, { mode: 0o600 }); await splitServiceCredentialFile(source, output, { consumerProviders: ["letta"], publicContentRoots: [], }); const before = await directoryEntries(output); await fs.writeFile(source, withoutXAssignments(fullSource), { mode: 0o600 });
await expect(splitServiceCredentialFile(source, output, { consumerProviders: ["letta"], publicContentRoots: [], allowedRemovedVariableNames: [ "THOUGHTSTREAM_X_CONSUMER_SECRET", "THOUGHTSTREAM_X_MANAGEMENT_BEARER_TOKEN", "NOT_IN_PLAN", ], })).rejects.toThrow("Explicitly removed variable names do not match the current removal plan: NOT_IN_PLAN");
const receipt = await splitServiceCredentialFile(source, output, { consumerProviders: ["letta"], publicContentRoots: [], allowedRemovedVariableNames: [ "THOUGHTSTREAM_X_CONSUMER_SECRET", "THOUGHTSTREAM_X_MANAGEMENT_BEARER_TOKEN", ], }); expect(receipt.removedVariableNames).toEqual([ "THOUGHTSTREAM_X_CONSUMER_SECRET", "THOUGHTSTREAM_X_MANAGEMENT_BEARER_TOKEN", ]); expect(parseEnvironmentAssignments(await fs.readFile(receipt.files["x-webhook"].path, "utf8")).size).toBe(0); expect(parseEnvironmentAssignments(await fs.readFile(receipt.files["x-management"].path, "utf8")).size).toBe(0); const after = await directoryEntries(output); for (const name of Object.keys(before).filter((name) => !["x-webhook.env", "x-management.env"].includes(name))) { expect(after[name]).toBe(before[name]); } });
test("forwards repeated explicit removals through the value-dark CLI", async () => { const root = await temporaryProject("thoughtstream-credential-cli-removal-"); roots.push(root); const source = path.join(root, "source.env"); const output = path.join(root, "credentials"); const fullSource = validSource({ includeX: true }); await fs.writeFile(source, fullSource, { mode: 0o600 }); await splitServiceCredentialFile(source, output, { consumerProviders: ["letta"], publicContentRoots: [], }); await fs.writeFile(source, withoutXAssignments(fullSource), { mode: 0o600 });
const result = await runSplitter(source, output, [ "--allow-remove", "THOUGHTSTREAM_X_CONSUMER_SECRET", "--allow-remove", "THOUGHTSTREAM_X_MANAGEMENT_BEARER_TOKEN", ]); expect(result.code).toBe(0); expect(JSON.parse(result.stdout).removedVariableNames).toEqual([ "THOUGHTSTREAM_X_CONSUMER_SECRET", "THOUGHTSTREAM_X_MANAGEMENT_BEARER_TOKEN", ]); expect(result.stdout).not.toContain("x-consumer-"); expect(result.stdout).not.toContain("x-management-"); expect(result.stderr).toBe(""); }, 15_000);
test("refuses a symlinked existing compartment during removal preflight", async () => { const root = await temporaryProject("thoughtstream-credential-preflight-symlink-"); roots.push(root); const source = path.join(root, "source.env"); const output = path.join(root, "credentials"); const target = path.join(root, "outside.env"); await fs.writeFile(source, validSource(), { mode: 0o600 }); await fs.mkdir(output, { mode: 0o700 }); await fs.writeFile(target, "THOUGHTSTREAM_X_CONSUMER_SECRET=synthetic\n", { mode: 0o600 }); await fs.symlink(target, path.join(output, "x-webhook.env"));
await expect(splitServiceCredentialFile(source, output, { consumerProviders: ["letta"], publicContentRoots: [], })).rejects.toThrow("Existing credential compartment must be a regular non-symlink file: x-webhook"); expect(await fs.readFile(target, "utf8")).toBe("THOUGHTSTREAM_X_CONSUMER_SECRET=synthetic\n"); });
test("selects Tinker and fixed OpenAI credentials without retaining Letta authority", async () => { const root = await temporaryProject("thoughtstream-credential-pi-openai-"); roots.push(root); const values = { letta: generatedValue("letta"), agent: generatedValue("agent"), tinker: generatedValue("tinker"), openai: generatedValue("openai"), bot: generatedValue("bot"), webhook: generatedValue("webhook"), }; const source = path.join(root, "source.env"); await fs.writeFile(source, [ `LETTA_API_KEY=${values.letta}`, `THOUGHTSTREAM_LETTA_TELEGRAM_AGENT_ID=${values.agent}`, `TINKER_API_KEY=${values.tinker}`, `THOUGHTSTREAM_TINKER_ESCALATION_MODEL=openai/gpt-oss-120b`, `OPENAI_API_KEY=${values.openai}`, `THOUGHTSTREAM_TELEGRAM_BOT_TOKEN=${values.bot}`, `THOUGHTSTREAM_TELEGRAM_WEBHOOK_SECRET=${values.webhook}`, "", ].join("\n"), { mode: 0o600 });
const receipt = await splitServiceCredentialFile(source, path.join(root, "credentials"), { consumerProviders: ["tinker", "openai"], publicContentRoots: [], });
expect(receipt.files.consumer.variableNames).toEqual([ "OPENAI_API_KEY", "THOUGHTSTREAM_TINKER_ESCALATION_MODEL", "TINKER_API_KEY", ]); const consumerText = await fs.readFile(receipt.files.consumer.path, "utf8"); expect(consumerText).toContain(values.tinker); expect(consumerText).toContain(values.openai); expect(consumerText).not.toContain(values.letta); expect(consumerText).not.toContain(values.agent); expect(JSON.stringify(receipt)).not.toContain(values.tinker); expect(JSON.stringify(receipt)).not.toContain(values.openai); });
test("routes local Agent SDK identity without requiring or copying a Cloud API key", async () => { const root = await temporaryProject("thoughtstream-credential-local-letta-"); roots.push(root); const source = path.join(root, "source.env"); await fs.writeFile(source, [ `THOUGHTSTREAM_LETTA_CO_AGENT_ID=${generatedValue("co-agent")}`, "THOUGHTSTREAM_LETTA_CO_MEMORY_DIR=/private/co-memory", "THOUGHTSTREAM_ENABLE_COIL_PUBLIC_KNOWLEDGE=1", "THOUGHTSTREAM_PUBLIC_KNOWLEDGE_POLICY_PATH=/private/policy.json", "THOUGHTSTREAM_PUBLIC_KNOWLEDGE_CATALOG_ROOT=/private/catalog", `THOUGHTSTREAM_TELEGRAM_BOT_TOKEN=${generatedValue("bot")}`, `THOUGHTSTREAM_TELEGRAM_WEBHOOK_SECRET=${generatedValue("webhook")}`, "", ].join("\n"), { mode: 0o600 }); const receipt = await splitServiceCredentialFile(source, path.join(root, "credentials"), { consumerProviders: ["letta-local"], publicContentRoots: [], }); expect(receipt.files.consumer.variableNames).toEqual([ "THOUGHTSTREAM_ENABLE_COIL_PUBLIC_KNOWLEDGE", "THOUGHTSTREAM_LETTA_CO_AGENT_ID", "THOUGHTSTREAM_LETTA_CO_MEMORY_DIR", "THOUGHTSTREAM_PUBLIC_KNOWLEDGE_CATALOG_ROOT", "THOUGHTSTREAM_PUBLIC_KNOWLEDGE_POLICY_PATH", ]); expect(await fs.readFile(receipt.files.consumer.path, "utf8")).not.toContain("LETTA_API_KEY"); });
test("refuses Git and configured public-content destinations before creating credential files", async () => { const root = await temporaryProject("thoughtstream-credential-path-"); roots.push(root); const source = path.join(root, "source.env"); await fs.writeFile(source, validSource(), { mode: 0o600 });
const gitRoot = path.join(root, "repo"); await fs.mkdir(path.join(gitRoot, ".git"), { recursive: true }); const gitOutput = path.join(gitRoot, "private", "credentials"); await expect(splitServiceCredentialFile(source, gitOutput, { consumerProviders: ["letta"], publicContentRoots: [], })).rejects.toThrow("inside a Git worktree"); await expect(fs.stat(gitOutput)).rejects.toMatchObject({ code: "ENOENT" });
const publicRoot = path.join(root, "published"); const publicOutput = path.join(publicRoot, "credentials"); await expect(splitServiceCredentialFile(source, publicOutput, { consumerProviders: ["letta"], publicContentRoots: [publicRoot], })).rejects.toThrow("inside a public-content root"); await expect(fs.stat(publicOutput)).rejects.toMatchObject({ code: "ENOENT" }); });
test("anchors writes to the approved directory inode and fails closed when its path is swapped", async () => { const root = await temporaryProject("thoughtstream-credential-swap-"); roots.push(root); const source = path.join(root, "source.env"); const sentinel = generatedValue("credential-sentinel"); await fs.writeFile(source, validSource().replace(/^LETTA_API_KEY=.*$/m, `LETTA_API_KEY=${sentinel}`), { mode: 0o600 }); const output = path.join(root, "private-credentials"); const displaced = path.join(root, "approved-directory-inode"); const publicRoot = path.join(root, "synthetic-public-repository"); await fs.mkdir(path.join(publicRoot, ".git"), { recursive: true }); let swapped = false;
await expect(splitServiceCredentialFile(source, output, { consumerProviders: ["letta"], publicContentRoots: [publicRoot], beforeFinalize: async () => { if (swapped) return; swapped = true; await fs.rename(output, displaced); await fs.symlink(publicRoot, output, "dir"); }, })).rejects.toThrow("parent changed during write");
const redirectedEntries = await fs.readdir(publicRoot); expect(redirectedEntries).toEqual([".git"]); expect(JSON.stringify(redirectedEntries)).not.toContain(sentinel); expect(await directoryText(displaced)).not.toContain(sentinel); });
test("fails closed on malformed, duplicate, or unknown credential assignments", async () => { expect(() => parseEnvironmentAssignments("VALID=one\nnot an assignment\n")).toThrow("Invalid environment assignment at line 2"); expect(() => parseEnvironmentAssignments("DUPLICATE=one\nDUPLICATE=two\n")).toThrow("Duplicate environment assignment: DUPLICATE");
const root = await temporaryProject("thoughtstream-credential-unknown-"); roots.push(root); const source = path.join(root, "source.env"); await fs.writeFile(source, `${validSource()}UNROUTED_PRIVATE_KEY=${generatedValue("unknown")}\n`, { mode: 0o600 }); await expect(splitServiceCredentialFile(source, path.join(root, "credentials"), { consumerProviders: ["letta"], publicContentRoots: [], })).rejects.toThrow("Credential-like variables are not assigned to a service compartment: UNROUTED_PRIVATE_KEY"); });
test("systemd drop-ins clear the shared environment file before loading one compartment", async () => { const root = path.resolve(import.meta.dirname, "..", "deploy", "systemd", "credential-compartments"); const expected = { "thoughtstream-telegram-webhook.service.conf": "telegram-webhook.env", "thoughtstream-consumers.service.conf": "consumer.env", "thoughtstream-telegram-dispatcher.service.conf": "telegram-dispatcher.env", "thoughtstream-jetstream.service.conf": "jetstream.env", "thoughtstream-fastmail-jmap.service.conf": "fastmail-jmap.env", }; for (const [file, environmentFile] of Object.entries(expected)) { const contents = await fs.readFile(path.join(root, file), "utf8"); expect(contents).toContain("EnvironmentFile=\n"); expect(contents).toContain(`EnvironmentFile=%h/.config/thoughtstream/credentials/${environmentFile}`); expect(contents).not.toContain("/live/.env"); } const batcher = await fs.readFile(path.resolve(root, "..", "thoughtstream-batches.service"), "utf8"); expect(batcher).toContain("ExecStart=/usr/bin/env pnpm thought batches"); expect(batcher).toContain("EnvironmentFile=\n"); expect(batcher).not.toContain("WantedBy="); });});
async function directoryText(directory: string): Promise<string> { const entries = await fs.readdir(directory).catch(() => []); return (await Promise.all(entries.map((entry) => fs.readFile(path.join(directory, entry), "utf8").catch(() => "")))).join("\n");}
async function runSplitter( source: string, outputDirectory: string, extraArguments: string[] = [],): Promise<{ code: number | null; stdout: string; stderr: string }> { return await new Promise((resolve, reject) => { const child = spawn(process.execPath, [ "--import", "tsx", "scripts/split-service-credentials.ts", "--source", source, "--output-dir", outputDirectory, "--consumer-providers", "letta", ...extraArguments, ], { cwd: path.resolve(import.meta.dirname, ".."), env: { PATH: process.env.PATH, HOME: process.env.HOME }, stdio: ["ignore", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.on("data", (chunk) => { stdout += String(chunk); }); child.stderr.on("data", (chunk) => { stderr += String(chunk); }); child.once("error", reject); child.once("exit", (code) => resolve({ code, stdout, stderr })); });}
function withoutXAssignments(contents: string): string { return contents .split("\n") .filter((line) => !line.startsWith("THOUGHTSTREAM_X_")) .join("\n");}
function validSource(options: { includeX?: boolean } = {}): string { return [ `LETTA_API_KEY=${generatedValue("letta")}`, `THOUGHTSTREAM_LETTA_TELEGRAM_AGENT_ID=${generatedValue("agent")}`, `THOUGHTSTREAM_TELEGRAM_BOT_TOKEN=${generatedValue("bot")}`, `THOUGHTSTREAM_TELEGRAM_WEBHOOK_SECRET=${generatedValue("webhook")}`, ...(options.includeX ? [ `THOUGHTSTREAM_X_CONSUMER_SECRET=${generatedValue("x-consumer")}`, `THOUGHTSTREAM_X_MANAGEMENT_BEARER_TOKEN=${generatedValue("x-management")}`, ] : []), "", ].join("\n");}
async function directoryEntries(directory: string): Promise<Record<string, string>> { return Object.fromEntries(await Promise.all((await fs.readdir(directory)).sort().map(async (name) => [ name, await fs.readFile(path.join(directory, name), "utf8"), ])));}
function generatedValue(label: string): string { return `${label}-${randomUUID()}`;}