From deedd4cd0c7cc02328eca98711633a36427ce4f7 Mon Sep 17 00:00:00 2001 From: Yash Dewasthale Date: Fri, 3 Jul 2026 23:17:12 +0530 Subject: [PATCH 1/2] feat: add ElevenLabs Scribe support, fix noise-injected transcriptions, improve retry UX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add ElevenLabs STT provider (scribe_v1) with tag_audio_events: false to prevent sound descriptions like "(Clicking noise)" from appearing in text - Keep Groq as fallback provider via STT_PROVIDER env var - Add sanitizeTranscription() regex as provider-agnostic fallback for remaining parenthetical noise labels - Return "" instead of throwing on no-speech, enabling clean retry flow - Show persistent "No speech detected — press voice key to retry" message (no longer auto-clears after 3s) - Dismiss footer message on any typed character - Switch primary voice key from F2 to Ctrl+V (more ergonomic), keep F2 as fallback - Remove console.error stack traces from voice failure paths - Clean up abortCapture → stopCapture naming, remove unused user-abort flag --- AGENTS.md | 3 + apps/supercode-cli/server/README.md | 14 +++ apps/supercode-cli/server/package.json | 2 +- .../server/src/cli/ai/chat/chat.ts | 39 +++--- .../server/src/voice/__tests__/speech.test.ts | 84 +++++++++++++ apps/supercode-cli/server/src/voice/speech.ts | 115 ++++++++++++++---- apps/web/.env.example | 71 ++++------- packages/secrets/index.ts | 2 + packages/secrets/package.json | 19 +++ packages/secrets/src/apply.ts | 26 ++++ packages/secrets/src/client.ts | 20 +++ packages/secrets/src/errors.ts | 26 ++++ packages/secrets/src/index.ts | 44 +++++++ packages/secrets/src/resolve-token.ts | 41 +++++++ packages/secrets/tsconfig.json | 11 ++ 15 files changed, 427 insertions(+), 90 deletions(-) create mode 100644 apps/supercode-cli/server/src/voice/__tests__/speech.test.ts create mode 100644 packages/secrets/index.ts create mode 100644 packages/secrets/package.json create mode 100644 packages/secrets/src/apply.ts create mode 100644 packages/secrets/src/client.ts create mode 100644 packages/secrets/src/errors.ts create mode 100644 packages/secrets/src/index.ts create mode 100644 packages/secrets/src/resolve-token.ts create mode 100644 packages/secrets/tsconfig.json diff --git a/AGENTS.md b/AGENTS.md index 87c1bd2..4ba2d4e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -99,6 +99,7 @@ apps/ packages/ db/ # Prisma database client auth/ # Better-Auth authentication + secrets/ # Infisical secrets wrapper (@super/secrets) ui/ # Shared UI components (empty) sdk/ # SDK package (empty) config/ # Shared config (empty) @@ -109,6 +110,8 @@ packages/ - Web app: `apps/web/.env` or `apps/.env.local` - Required for auth: `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`, `NEXT_PUBLIC_BETTER_AUTH_URL` - Required for DB: `DATABASE_URL` +- Voice/STT: `ELEVENLABS_API_KEY` (default provider), `STT_PROVIDER` (`elevenlabs`|`groq`), `ELEVENLABS_MODEL`, `STT_LANGUAGE` +- Secrets: `INFISICAL_CLIENT_ID`, `INFISICAL_CLIENT_SECRET` (when Infisical is configured) ### Linting - ESLint configured for web app only (`apps/web/eslint.config.mjs`) diff --git a/apps/supercode-cli/server/README.md b/apps/supercode-cli/server/README.md index c8d07ec..718040f 100644 --- a/apps/supercode-cli/server/README.md +++ b/apps/supercode-cli/server/README.md @@ -42,6 +42,20 @@ The AI has access to file reading, searching, web fetching, and code execution t | `MINIMAX_API_KEY` | MiniMax API key | — | | `NVIDIA_API_KEY` | NVIDIA NIM API key | — | +### Voice Input + +Voice capture requires `ffmpeg` and an STT provider API key. + +| Env Var | Description | Default | +|---|---|---| +| `STT_PROVIDER` | STT provider (`elevenlabs` or `groq`) | `elevenlabs` | +| `ELEVENLABS_API_KEY` | ElevenLabs API key (required for ElevenLabs STT) | — | +| `ELEVENLABS_MODEL` | ElevenLabs model ID | `scribe_v1` | +| `GROQ_API_KEY` | Groq API key (required when `STT_PROVIDER=groq`) | — | +| `STT_LANGUAGE` | Transcription language | `en` | + +Press **Ctrl+Shift+V** during a chat session to start voice capture. + ## License MIT diff --git a/apps/supercode-cli/server/package.json b/apps/supercode-cli/server/package.json index c6e5610..e634b71 100644 --- a/apps/supercode-cli/server/package.json +++ b/apps/supercode-cli/server/package.json @@ -1,6 +1,6 @@ { "name": "supercode-cli", - "version": "0.1.38", + "version": "0.1.39", "description": "AI-powered coding agent CLI", "main": "dist/main.js", "bin": { diff --git a/apps/supercode-cli/server/src/cli/ai/chat/chat.ts b/apps/supercode-cli/server/src/cli/ai/chat/chat.ts index 766f03e..b8a152e 100644 --- a/apps/supercode-cli/server/src/cli/ai/chat/chat.ts +++ b/apps/supercode-cli/server/src/cli/ai/chat/chat.ts @@ -59,7 +59,7 @@ import { saveCliConfig } from "src/lib/cli-config" import { voiceCaptureFlow, canVoiceCapture, - abortCapture, + stopCapture, } from "src/voice/speech.ts" @@ -809,7 +809,7 @@ function stdinKeypress(_str: string, key: any) { // Enter/Escape during voice capture stops recording, doesn't submit if (voiceCaptureActive && (key.name === "return" || key.name === "enter" || key.name === "escape")) { - abortCapture() + stopCapture() return } @@ -1008,26 +1008,26 @@ function stdinKeypress(_str: string, key: any) { return } - // Voice capture — F2 is the primary trigger (most reliable across terminals). -// Ctrl+Shift+V is also accepted but some terminals intercept it as a paste -// shortcut, and Node.js readline treats Ctrl+V as a "literal next" key -// which prevents the Shift+V combination from being detected reliably. + // Voice capture — Ctrl+V is the primary trigger (bottom-left corner of most + // keyboards, reliably detected in any terminal). F2 is also accepted as a + // fallback. Note: Shift is intentionally omitted — terminals fold Shift into + // Ctrl+letter combos, so Ctrl+Shift+V sends the same byte as Ctrl+V. const isVoiceKey = - key.name === "F2" || - (key.ctrl && key.shift && (key.name === "v" || key.name === "V")) + (key.ctrl && (key.name === "v" || key.name === "V")) || + key.name === "f2" if (isVoiceKey) { if (!voiceCaptureActive) { - voiceCaptureActive = true - activeFooter?.setStatusMessage("🎤 Recording... (Enter to stop)") startVoiceCapture().finally(() => { voiceCaptureActive = false - activeFooter?.setStatusMessage("") }) + } else { + stopCapture() } return } if (_str && _str.length === 1 && !key.ctrl && !key.meta) { + activeFooter?.setStatusMessage("") stdinInput = stdinInput.slice(0, stdinCursor) + _str + stdinInput.slice(stdinCursor) stdinCursor++ slashSelected = -1 @@ -1040,23 +1040,28 @@ function stdinKeypress(_str: string, key: any) { async function startVoiceCapture() { const check = canVoiceCapture() if (!check.ok) { - activeFooter?.setStatusMessage("⛭ Voice unavailable: " + (check.reason ?? "unknown")) + const reason = check.reason ?? "unknown" + activeFooter?.setStatusMessage("⛭ Voice unavailable: " + reason) setTimeout(() => activeFooter?.setStatusMessage(""), 4000) return } + const prevMode = voiceCaptureActive + voiceCaptureActive = true + activeFooter?.setStatusMessage("🎤 Recording... (voice key or Enter to stop)") try { const text = await voiceCaptureFlow() if (text) { stdinInput = stdinInput.slice(0, stdinCursor) + text + " " + stdinInput.slice(stdinCursor) stdinCursor += text.length + 1 - // Don't call renderInput here — the chat loop will call chatInput() next, - // which preserves stdinInput (via voiceJustCaptured) and renders it once. + } else { + activeFooter?.setStatusMessage("🎤 No speech detected — press voice key to retry") } } catch (err) { - const msg = err instanceof Error ? err.message : "Voice capture failed" - activeFooter?.setStatusMessage("⛭ " + msg) + activeFooter?.setStatusMessage("⛭ Voice failed: " + (err instanceof Error ? err.message : err)) setTimeout(() => activeFooter?.setStatusMessage(""), 4000) + } finally { + voiceCaptureActive = prevMode } } @@ -1616,7 +1621,7 @@ export async function startChat( // ── Quick-start hint ──────────────────────────────────────── console.log( - ` ${chalk.hex(theme.greenDim)("hint")} ${chalk.hex(theme.green)("·")} ${chalk.hex(theme.greenGlow)("/model")} to switch ${chalk.hex(theme.greenDim)("·")} ${chalk.hex(theme.greenGlow)("F2")} voice ${chalk.hex(theme.greenDim)("·")} ${chalk.hex(theme.greenGlow)("/help")} for commands ${chalk.hex(theme.greenDim)("·")} ${chalk.hex(theme.greenGlow)("Tab")} to cycle mode`, + ` ${chalk.hex(theme.greenDim)("hint")} ${chalk.hex(theme.green)("·")} ${chalk.hex(theme.greenGlow)("/model")} to switch ${chalk.hex(theme.greenDim)("·")} ${chalk.hex(theme.greenGlow)("Ctrl+V")} voice ${chalk.hex(theme.greenDim)("·")} ${chalk.hex(theme.greenGlow)("/help")} for commands ${chalk.hex(theme.greenDim)("·")} ${chalk.hex(theme.greenGlow)("Tab")} to cycle mode`, ) console.log() diff --git a/apps/supercode-cli/server/src/voice/__tests__/speech.test.ts b/apps/supercode-cli/server/src/voice/__tests__/speech.test.ts new file mode 100644 index 0000000..f2e3fb2 --- /dev/null +++ b/apps/supercode-cli/server/src/voice/__tests__/speech.test.ts @@ -0,0 +1,84 @@ +import { describe, it, expect, beforeEach, afterEach } from "bun:test" + +describe("canVoiceCapture", () => { + const origEnv = { ...process.env } + + beforeEach(() => { + process.env = { PATH: origEnv.PATH, FFMPEG_PATH: origEnv.FFMPEG_PATH } + delete process.env.ELEVENLABS_API_KEY + delete process.env.GROQ_API_KEY + delete process.env.STT_PROVIDER + }) + + afterEach(() => { + process.env = { ...origEnv } + }) + + it("returns ok=false when ELEVENLABS_API_KEY is missing and STT_PROVIDER=elevenlabs", async () => { + process.env.STT_PROVIDER = "elevenlabs" + const { canVoiceCapture } = await import("../speech.ts") + const result = canVoiceCapture() + expect(result.ok).toBe(false) + expect(result.reason).toContain("ELEVENLABS_API_KEY") + }) + + it("returns ok=false when GROQ_API_KEY is missing and STT_PROVIDER=groq", async () => { + process.env.STT_PROVIDER = "groq" + const { canVoiceCapture } = await import("../speech.ts") + const result = canVoiceCapture() + expect(result.ok).toBe(false) + expect(result.reason).toContain("GROQ_API_KEY") + }) + + it("uses elevenlabs by default when STT_PROVIDER is unset", async () => { + const { canVoiceCapture } = await import("../speech.ts") + const result = canVoiceCapture() + expect(result.ok).toBe(false) + expect(result.reason).toContain("ELEVENLABS_API_KEY") + }) + + it("returns ok=false with ffmpeg reason when ffmpeg is missing", async () => { + process.env.ELEVENLABS_API_KEY = "sk-test" + process.env.FFMPEG_PATH = "/nonexistent/ffmpeg" + const { canVoiceCapture } = await import("../speech.ts") + const result = canVoiceCapture() + expect(result.ok).toBe(false) + expect(result.reason).toContain("ffmpeg") + }) +}) + +describe("getSttProvider", () => { + const origEnv = { ...process.env } + + beforeEach(() => { + process.env = { PATH: origEnv.PATH } + delete process.env.STT_PROVIDER + }) + + afterEach(() => { + process.env = { ...origEnv } + }) + + it('returns "elevenlabs" when STT_PROVIDER is unset', async () => { + const mod = await import("../speech.ts") + expect((mod as any).getSttProvider()).toBe("elevenlabs") + }) + + it('returns "elevenlabs" when STT_PROVIDER is "elevenlabs"', async () => { + process.env.STT_PROVIDER = "elevenlabs" + const mod = await import("../speech.ts") + expect((mod as any).getSttProvider()).toBe("elevenlabs") + }) + + it('returns "groq" when STT_PROVIDER is "groq"', async () => { + process.env.STT_PROVIDER = "groq" + const mod = await import("../speech.ts") + expect((mod as any).getSttProvider()).toBe("groq") + }) + + it('returns "elevenlabs" for unknown STT_PROVIDER values', async () => { + process.env.STT_PROVIDER = "invalid" + const mod = await import("../speech.ts") + expect((mod as any).getSttProvider()).toBe("elevenlabs") + }) +}) diff --git a/apps/supercode-cli/server/src/voice/speech.ts b/apps/supercode-cli/server/src/voice/speech.ts index 7ff24fe..83b5c12 100644 --- a/apps/supercode-cli/server/src/voice/speech.ts +++ b/apps/supercode-cli/server/src/voice/speech.ts @@ -4,18 +4,32 @@ import { join } from "path" import { unlinkSync, readFileSync } from "fs" import { randomUUID } from "crypto" -const FFMPEG_PATH = process.env.FFMPEG_PATH || "/opt/homebrew/bin/ffmpeg" +function getFfmpegPath(): string { + return process.env.FFMPEG_PATH || "/opt/homebrew/bin/ffmpeg" +} + +const ELEVENLABS_URL = "https://api.elevenlabs.io/v1/speech-to-text" +const ELEVENLABS_MODEL = process.env.ELEVENLABS_MODEL || "scribe_v1" +const STT_LANGUAGE = process.env.STT_LANGUAGE || "en" + +/* groq provider */ const GROQ_URL = "https://api.groq.com/openai/v1/audio/transcriptions" const GROQ_MODEL = process.env.GROQ_MODEL || "whisper-large-v3-turbo" -const DEFAULT_MAX_DURATION_MS = 8_000 + + +const DEFAULT_MAX_DURATION_MS = 4_000 let activeFfmpegProcess: ChildProcess | null = null -let activeFfmpegUserAbort = false -export function abortCapture(): void { +export function getSttProvider(): "elevenlabs" | "groq" { + const raw = process.env.STT_PROVIDER || "elevenlabs" + if (raw === "groq") return "groq" + return "elevenlabs" +} + +export function stopCapture(): void { if (activeFfmpegProcess) { - activeFfmpegUserAbort = true activeFfmpegProcess.kill("SIGTERM") activeFfmpegProcess = null } @@ -23,7 +37,7 @@ export function abortCapture(): void { export function isFfmpegAvailable(): boolean { try { - const out = spawnSync(FFMPEG_PATH, ["-version"], { encoding: "utf-8", timeout: 3000 }) + const out = spawnSync(getFfmpegPath(), ["-version"], { encoding: "utf-8", timeout: 3000 }) return out.status === 0 } catch { return false @@ -34,9 +48,16 @@ export function canVoiceCapture(): { ok: boolean reason?: string } { - if (!isFfmpegAvailable()) return { ok: false, reason: `ffmpeg not found at ${FFMPEG_PATH}` } - const groqKey = process.env.GROQ_API_KEY - if (!groqKey) return { ok: false, reason: "GROQ_API_KEY not set" } + if (!isFfmpegAvailable()) return { ok: false, reason: `ffmpeg not found at ${getFfmpegPath()}` } + + const provider = getSttProvider() + if (provider === "groq") { + /* groq provider */ + if (!process.env.GROQ_API_KEY) return { ok: false, reason: "GROQ_API_KEY not set" } + } else { + if (!process.env.ELEVENLABS_API_KEY) return { ok: false, reason: "ELEVENLABS_API_KEY not set" } + } + return { ok: true } } @@ -47,7 +68,7 @@ function captureAudio( const tmpFile = join(tmpdir(), `voice-${randomUUID()}.wav`) const stderrChunks: Buffer[] = [] - const proc = spawn(FFMPEG_PATH, [ + const proc = spawn(getFfmpegPath(), [ "-f", "avfoundation", "-i", ":0", "-ac", "1", @@ -70,8 +91,6 @@ function captureAudio( proc.on("exit", (code, signal) => { clearTimeout(timeout) activeFfmpegProcess = null - const userAborted = activeFfmpegUserAbort - activeFfmpegUserAbort = false const stderr = Buffer.concat(stderrChunks).toString("utf-8") @@ -82,8 +101,6 @@ function captureAudio( try { unlinkSync(tmpFile) } catch {} if (stderr.includes("No audio device") || stderr.includes("Input/output error")) { reject(new Error("Microphone not accessible — grant mic permission to your terminal in System Settings > Privacy & Security > Microphone")) - } else if (userAborted) { - reject(new Error("No audio captured")) } else { const snippet = stderr.split("\n").filter(l => l.includes("Error") || l.includes("device") || l.includes("No ")).slice(-3).join("; ") || "ffmpeg capture failed" reject(new Error(snippet)) @@ -103,14 +120,50 @@ function captureAudio( proc.on("error", (err) => { clearTimeout(timeout) activeFfmpegProcess = null - activeFfmpegUserAbort = false try { unlinkSync(tmpFile) } catch {} reject(err) }) }) } -export async function transcribeAudio(filePath: string): Promise { +async function transcribeElevenLabs(filePath: string): Promise { + const apiKey = process.env.ELEVENLABS_API_KEY + if (!apiKey) throw new Error("ELEVENLABS_API_KEY not configured") + + const formData = new FormData() + formData.append("model_id", ELEVENLABS_MODEL) + formData.append("file", Bun.file(filePath), "audio.wav") + formData.append("tag_audio_events", "false") + + const start = performance.now() + const res = await fetch(ELEVENLABS_URL, { + method: "POST", + headers: { + "xi-api-key": apiKey, + }, + body: formData, + signal: AbortSignal.timeout(15_000), + }) + + const body = await res.text().catch(() => "") + const elapsed = ((performance.now() - start) / 1000).toFixed(2) + + if (!res.ok) { + throw new Error(`ElevenLabs transcription error ${res.status}: ${body}`) + } + + let data: { text?: string } + try { + data = JSON.parse(body) as { text?: string } + } catch { + throw new Error(`ElevenLabs transcription invalid JSON: ${body}`) + } + + return data.text ?? "" +} + +/* groq provider */ +async function transcribeGroq(filePath: string): Promise { const apiKey = process.env.GROQ_API_KEY if (!apiKey) throw new Error("GROQ_API_KEY not configured") @@ -142,20 +195,34 @@ export async function transcribeAudio(filePath: string): Promise { return data.text ?? "" } +export async function transcribeAudio(filePath: string): Promise { + const provider = getSttProvider() + + if (provider === "groq") { + /* groq provider */ + return transcribeGroq(filePath) + } + + return transcribeElevenLabs(filePath) +} + +const SOUND_DESCRIPTION_RE = /\([^)]*?(?:noise|clicking|static|background|sound|audio|speaking|unintelligible|laughs?|coughs?|clears?\s+(?:throat|voice)|throat|pause|music|beep|tone|silence|indistinct|foreign|applause|sniffling|sighs?|breathing|rustling|mumbling|chatter|echo)[^)]*?\)/gi + +function sanitizeTranscription(text: string): string { + return text.replace(SOUND_DESCRIPTION_RE, "").trim() +} + export async function voiceCaptureFlow(): Promise { const { base64, filePath } = await captureAudio() try { const text = await transcribeAudio(filePath) - const trimmed = text.trim() - if (!trimmed) { - throw new Error("No speech detected in recording") + const cleaned = sanitizeTranscription(text) + if (!cleaned || cleaned.length < 2 || !/[a-zA-Z0-9]/.test(cleaned)) { + return "" } - if (trimmed.length < 2 || !/[a-zA-Z0-9]/.test(trimmed)) { - throw new Error("No clear speech detected — try speaking louder or longer") - } - return trimmed + return cleaned } finally { try { unlinkSync(filePath) } catch {} } -} \ No newline at end of file +} diff --git a/apps/web/.env.example b/apps/web/.env.example index 0628758..4bb64c8 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -1,54 +1,29 @@ -# ────────────────────────────────────────────── -# Supercode Dashboard — Environment Variables -# ────────────────────────────────────────────── -# Copy this to apps/web/.env.local and fill in your values. -# -# 🔴 Required — app won't start without it -# 🟡 Required for feature (e.g. auth, AI) -# ⚪ Optional — skip if you don't need the feature -# -# ─── Database ────────────────────────────────── -# 🔴 PostgreSQL connection string -# Docker Desktop: postgresql://postgres:postgres@localhost:5432/postgres -DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" +# ─── Database ─── +DATABASE_URL= -# ─── Authentication (Better-Auth) ────────────── -# 🔴 Session encryption secret -# Generate with: openssl rand -hex 32 -BETTER_AUTH_SECRET="" -# 🔴 Base URL — must match your browser address -BETTER_AUTH_URL="http://localhost:3000" +# ─── Auth (Better-Auth) ─── +BETTER_AUTH_URL= +BETTER_AUTH_SECRET= -# 🟡 GitHub OAuth — required to log in -# Create an OAuth app: https://github.com/settings/developers -GITHUB_CLIENT_ID="" -GITHUB_CLIENT_SECRET="" +GITHUB_CLIENT_ID= +GITHUB_CLIENT_SECRET= -# ─── App URLs ────────────────────────────────── -# ⚪ Public base URL for OAuth callbacks, absolute links -NEXT_PUBLIC_APP_BASE_URL="http://localhost:3000" -# ⚪ Alternate public URL (used by some components) -NEXT_PUBLIC_APP_URL="http://localhost:3000" +# ─── Secrets (Infisical) ─── +INFISICAL_CLIENT_ID= +INFISICAL_CLIENT_SECRET= -# ⚪ Terminal server URL — only needed for CLI features -TERMINAL_SERVER_URL="http://localhost:3004" +# ─── Voice / STT ─── +# Primary STT provider (elevenlabs | groq). Default: elevenlabs +STT_PROVIDER= +ELEVENLABS_API_KEY= +ELEVENLABS_MODEL=scribe_v1 +STT_LANGUAGE=en -# ─── Vector Search (Pinecone) ────────────────── -# 🟡 Required for semantic search features -# Get a key: https://app.pinecone.io -PINECONE_DB_API_KEY="" +# Groq (parked — use STT_PROVIDER=groq to re-enable) +# GROQ_API_KEY= -# ─── AI Providers ────────────────────────────── -# 🟡 At least one required for AI features -GOOGLE_GENERATIVE_AI_API_KEY="" -OPENAI_API_KEY="" -ANTHROPIC_API_KEY="" - -# ─── Email (Nodemailer/SMTP) ────────────────── -# ⚪ Only needed for email features -SMTP_HOST="smtp.gmail.com" -SMTP_PORT=587 -SMTP_USER="" -SMTP_PASS="" -EMAIL_FROM="" -RESEND_ADMIN_EMAIL="" +# ─── AI Providers (CLI) ─── +GOOGLE_GENERATIVE_AI_API_KEY= +OPENROUTER_API_KEY= +MINIMAX_API_KEY= +NVIDIA_API_KEY= diff --git a/packages/secrets/index.ts b/packages/secrets/index.ts new file mode 100644 index 0000000..be3bf3d --- /dev/null +++ b/packages/secrets/index.ts @@ -0,0 +1,2 @@ +export { loadSecrets, type LoadSecretsOptions, type AppId, type EnvName } from "./src/index" +export { MissingInfisicalTokenError, SecretSchemaError } from "./src/errors" diff --git a/packages/secrets/package.json b/packages/secrets/package.json new file mode 100644 index 0000000..ef975f1 --- /dev/null +++ b/packages/secrets/package.json @@ -0,0 +1,19 @@ +{ + "name": "@super/secrets", + "version": "0.1.0", + "private": true, + "main": "./index.ts", + "types": "./index.ts", + "exports": { + ".": "./index.ts" + }, + "scripts": { + "build": "echo 'secrets build pending'", + "lint": "echo 'secrets lint pending'", + "typecheck": "echo 'secrets typecheck pending'" + }, + "dependencies": { + "@infisical/sdk": "^0.0.30", + "zod": "^3.24.0" + } +} diff --git a/packages/secrets/src/apply.ts b/packages/secrets/src/apply.ts new file mode 100644 index 0000000..135281b --- /dev/null +++ b/packages/secrets/src/apply.ts @@ -0,0 +1,26 @@ +import type { z } from "zod" +import { SecretSchemaError } from "./errors" +import type { AppId, EnvName } from "./index" + +export function applySecrets( + secrets: Record, + app: AppId, + env: EnvName, + schema?: z.ZodTypeAny, +): void { + if (schema) { + const result = schema.safeParse(secrets) + if (!result.success) { + const issues = result.error.issues.map( + (i) => `${i.path.join(".")}: ${i.message}`, + ) + throw new SecretSchemaError(app, env, issues) + } + } + + for (const [key, value] of Object.entries(secrets)) { + if (value !== undefined && !(key in process.env)) { + process.env[key] = value + } + } +} diff --git a/packages/secrets/src/client.ts b/packages/secrets/src/client.ts new file mode 100644 index 0000000..2de1db6 --- /dev/null +++ b/packages/secrets/src/client.ts @@ -0,0 +1,20 @@ +import { InfisicalClient } from "@infisical/sdk" +import { resolveToken } from "./resolve-token" +import type { AppId } from "./resolve-token" + +let shared: InfisicalClient | null = null + +export function getClient(app: AppId): InfisicalClient { + if (!shared) { + const { token, source } = resolveToken(app) + shared = new InfisicalClient({ + token, + siteUrl: process.env.INFISICAL_SITE_URL ?? "https://app.infisical.com", + }) + } + return shared +} + +export function resetClient(): void { + shared = null +} diff --git a/packages/secrets/src/errors.ts b/packages/secrets/src/errors.ts new file mode 100644 index 0000000..49b6529 --- /dev/null +++ b/packages/secrets/src/errors.ts @@ -0,0 +1,26 @@ +export class MissingInfisicalTokenError extends Error { + constructor(app: string) { + super( + [ + `No Infisical auth found for app "${app}".`, + "", + " Run: infisical login", + "", + "Then retry. No .env fallback is available.", + ].join("\n"), + ) + this.name = "MissingInfisicalTokenError" + } +} + +export class SecretSchemaError extends Error { + constructor(app: string, env: string, issues: string[]) { + super( + [ + `Secret schema validation failed for "${app}" in "${env}":`, + ...issues.map((i) => ` - ${i}`), + ].join("\n"), + ) + this.name = "SecretSchemaError" + } +} diff --git a/packages/secrets/src/index.ts b/packages/secrets/src/index.ts new file mode 100644 index 0000000..afcd9fe --- /dev/null +++ b/packages/secrets/src/index.ts @@ -0,0 +1,44 @@ +import type { z } from "zod" +import { getClient } from "./client" +import { applySecrets } from "./apply" +import type { AppId } from "./resolve-token" + +export type { AppId } from "./resolve-token" + +export type EnvName = "dev" | "staging" | "prod" + +export interface LoadSecretsOptions { + app: AppId + env: EnvName + schema?: z.ZodTypeAny + projectId?: string +} + +const DEFAULT_PROJECT_ID = process.env.INFISICAL_PROJECT_ID + +export async function loadSecrets(options: LoadSecretsOptions): Promise { + const { app, env, schema, projectId = DEFAULT_PROJECT_ID } = options + + if (!projectId) { + throw new Error( + "INFISICAL_PROJECT_ID is required. Set it via env or pass projectId in options.", + ) + } + + const client = getClient(app) + const secrets = await client.listSecrets({ + environment: env, + projectId, + attachToProcessEnv: false, + }) + + const flat: Record = {} + for (const secret of secrets) { + const value = secret.secretValue ?? undefined + if (value !== undefined) { + flat[secret.secretKey] = value + } + } + + applySecrets(flat, app, env, schema) +} diff --git a/packages/secrets/src/resolve-token.ts b/packages/secrets/src/resolve-token.ts new file mode 100644 index 0000000..f519cbe --- /dev/null +++ b/packages/secrets/src/resolve-token.ts @@ -0,0 +1,41 @@ +import { readFileSync, existsSync } from "node:fs" +import { join } from "node:path" +import { homedir } from "node:os" +import { MissingInfisicalTokenError } from "./errors" + +export type AppId = "web" | "cli-server" | "terminal" + +function inferAppTokenVar(app: AppId): string { + return `INFISICAL_TOKEN_${app.replace(/-/g, "_").toUpperCase()}` +} + +function readLocalSessionToken(): string | null { + const configPath = join(homedir(), ".infisical", "infisical-config.json") + if (!existsSync(configPath)) return null + try { + const raw = readFileSync(configPath, "utf-8") + const config = JSON.parse(raw) + return config?.token ?? config?.accessToken ?? null + } catch { + return null + } +} + +export interface ResolvedToken { + token: string + source: "env" | "generic-env" | "local-session" +} + +export function resolveToken(app: AppId): ResolvedToken { + const appVar = inferAppTokenVar(app) + const appToken = process.env[appVar] + if (appToken) return { token: appToken, source: "env" } + + const genericToken = process.env.INFISICAL_TOKEN + if (genericToken) return { token: genericToken, source: "generic-env" } + + const localToken = readLocalSessionToken() + if (localToken) return { token: localToken, source: "local-session" } + + throw new MissingInfisicalTokenError(app) +} diff --git a/packages/secrets/tsconfig.json b/packages/secrets/tsconfig.json new file mode 100644 index 0000000..00b9b04 --- /dev/null +++ b/packages/secrets/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true + }, + "include": ["src/**/*"] +} From 31e4cb619804ebcdc6d1c545894d9a255bb3c0a2 Mon Sep 17 00:00:00 2001 From: Yash Dewasthale Date: Fri, 3 Jul 2026 23:28:01 +0530 Subject: [PATCH 2/2] fix: bump @infisical/sdk from unpublished 0.0.30 to v5, adapt to new API - Bump @infisical/sdk to ^5.0.2 (v0.0.30 was never published to npm) - Replace InfisicalClient with InfisicalSDK, authenticate via separate .authenticate(token) call per v5 API - Destructure .secrets from listSecrets response (v5 returns { secrets: Secret[] } instead of a bare array) - Fixes "No version matching ^0.0.30 found" on Vercel deployment --- bun.lock | 154 ++++++++++++++++++++++++++++++++- packages/secrets/package.json | 2 +- packages/secrets/src/client.ts | 12 +-- packages/secrets/src/index.ts | 4 +- 4 files changed, 162 insertions(+), 10 deletions(-) diff --git a/bun.lock b/bun.lock index 7c09642..618ab4b 100644 --- a/bun.lock +++ b/bun.lock @@ -89,7 +89,7 @@ }, "apps/supercode-cli/server": { "name": "supercode-cli", - "version": "0.1.26", + "version": "0.1.39", "bin": { "supercode": "dist/main.js", }, @@ -283,6 +283,14 @@ "name": "@super/sdk", "version": "0.1.0", }, + "packages/secrets": { + "name": "@super/secrets", + "version": "0.1.0", + "dependencies": { + "@infisical/sdk": "^5.0.2", + "zod": "^3.24.0", + }, + }, "packages/ui": { "name": "@super/ui", "version": "0.1.0", @@ -320,6 +328,68 @@ "@apidevtools/swagger-methods": ["@apidevtools/swagger-methods@3.0.2", "", {}, "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg=="], + "@aws-crypto/sha256-browser": ["@aws-crypto/sha256-browser@5.2.0", "", { "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-crypto/supports-web-crypto": "^5.2.0", "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw=="], + + "@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], + + "@aws-crypto/supports-web-crypto": ["@aws-crypto/supports-web-crypto@5.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg=="], + + "@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], + + "@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.993.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/credential-provider-node": "^3.972.10", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", "@aws-sdk/util-user-agent-node": "^3.972.9", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.16", "@smithy/middleware-retry": "^4.4.33", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.10", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.32", "@smithy/util-defaults-mode-node": "^4.2.35", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7Ne3Yk/bgQPVebAkv7W+RfhiwTRSbfER9BtbhOa2w/+dIr902LrJf6vrZlxiqaJbGj2ALx8M+ZK1YIHVxSwu9A=="], + + "@aws-sdk/core": ["@aws-sdk/core@3.974.27", "", { "dependencies": { "@aws-sdk/types": "^3.973.15", "@aws-sdk/xml-builder": "^3.972.33", "@aws/lambda-invoke-store": "^0.3.0", "@smithy/core": "^3.29.0", "@smithy/signature-v4": "^5.6.1", "@smithy/types": "^4.15.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-WRWEgIq6vx+NU6ot3VrRu4Jovj9MIObitSi6of/GV5THDDPccBhivCRNkWJutMM+m3GvdeI3l/UbGNcoOobxOA=="], + + "@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.52", "", { "dependencies": { "@aws-sdk/nested-clients": "^3.997.27", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-m+akZFJsghShferf2xsMw0Hogl1jNIJl2zUoZBNTFyWvlaOj1aK5sMTzcnw8m1dICvlQ+lC4T1OPGGsmZ+ezXA=="], + + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.53", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-+KDA3uc/HZ1vIneGu5QMQb0gAXDYrm2vOE60+BJ7lS0YinMQ5i2oV4PR1A16XkF6K1IbSwjEHd1hQIIgMsK48w=="], + + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.55", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/fetch-http-handler": "^5.6.2", "@smithy/node-http-handler": "^4.9.2", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-1gBfkWY3RWeBlCoB9lIJjXMx45/54wxcgfzv6BY9otTmMrZPcNPi1v+MwZxxaCUg441NV3jsr1efnFNCXiW70g=="], + + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.60", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/credential-provider-env": "^3.972.53", "@aws-sdk/credential-provider-http": "^3.972.55", "@aws-sdk/credential-provider-login": "^3.972.59", "@aws-sdk/credential-provider-process": "^3.972.53", "@aws-sdk/credential-provider-sso": "^3.972.59", "@aws-sdk/credential-provider-web-identity": "^3.972.59", "@aws-sdk/nested-clients": "^3.997.27", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/credential-provider-imds": "^4.4.5", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-CV2md+PXvABwRjApWGhQ0wACy9WSFIhnUGrovLcjnjBCd/46TbuivLADtkF8IWNjtCQmQ+2IagSaxqBYqXBNAQ=="], + + "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.59", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/nested-clients": "^3.997.27", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-JG4S9yyA1GFzJdJXqLKrUzZbyK+VDp2QIsJD7YOicJHAhqymfHpDJIok2dLnhOdVB0I37RjdC53uOwCMVS00gw=="], + + "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.62", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.53", "@aws-sdk/credential-provider-http": "^3.972.55", "@aws-sdk/credential-provider-ini": "^3.972.60", "@aws-sdk/credential-provider-process": "^3.972.53", "@aws-sdk/credential-provider-sso": "^3.972.59", "@aws-sdk/credential-provider-web-identity": "^3.972.59", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/credential-provider-imds": "^4.4.5", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-S6Slq3Tx7bvFk5yc34XNADyZYTX2HUXvaFAnowGRQnhjBO8J/mP62Fn7lxvJwjaDyYm/7gh9h6HEHaltRyMFXw=="], + + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.53", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-EhfH+MQlqOMCkXIVa8MMObPzAQqwTTtxA7KhEJiyPeuNVA8PLOOUpgK7nBrgaDaGiIDLN/9LpGdaHuDjomeRTw=="], + + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.59", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/nested-clients": "^3.997.27", "@aws-sdk/token-providers": "3.1079.0", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-h8793pOjcImx0SB+VcLONcaQQ57VAvKVuqyewQMRKqqH+CSXsG2dwOeLMUJPMxLdNvL7dXOM0ueTukyNUnu5mA=="], + + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.59", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/nested-clients": "^3.997.27", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-VoyO9+vl3XVmpZwn4obskrWIkrA/Jf3lSe1E3ZERlaN9u0D4YZ6+HywC3+L98QOXqZesEfedk67gRER8tK8+8w=="], + + "@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.993.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.993.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/credential-provider-cognito-identity": "^3.972.3", "@aws-sdk/credential-provider-env": "^3.972.9", "@aws-sdk/credential-provider-http": "^3.972.11", "@aws-sdk/credential-provider-ini": "^3.972.9", "@aws-sdk/credential-provider-login": "^3.972.9", "@aws-sdk/credential-provider-node": "^3.972.10", "@aws-sdk/credential-provider-process": "^3.972.9", "@aws-sdk/credential-provider-sso": "^3.972.9", "@aws-sdk/credential-provider-web-identity": "^3.972.9", "@aws-sdk/nested-clients": "3.993.0", "@aws-sdk/types": "^3.973.1", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-1M/nukgPSLqe9krzOKHnE8OylUaKAiokAV3xRLdeExVHcRE7WG5uzCTKWTj1imKvPjDqXq/FWhlbbdWIn7xIwA=="], + + "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.28", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "tslib": "^2.6.2" } }, "sha512-2w4cKugljxKCgBPL5LQJLj+1kUBkWG8HO7C+7GYTS7UNATMijEK+MCEktnCpfA2koBZFcf7Ioe5YhNZ5vh5ruw=="], + + "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.27", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "tslib": "^2.6.2" } }, "sha512-Qia7FsijpSh+LL9H6i9HQ3JZQsN9qdOQjwCAIi4Zi9Xqc62N7c3udBOfliavqn40FKZlgpgV/Js+NpKguyXfiA=="], + + "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "tslib": "^2.6.2" } }, "sha512-iM0ZSNerIexGGFokLEJqEr/H2kV+WiTENZXHLb391q1ldF+qWDn86MpyH4HKfKwQRzEhInehwX9u9/a1IXAz6g=="], + + "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.57", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "tslib": "^2.6.2" } }, "sha512-4gstakrfAVK7CAQ8Rar4Sig7Ztjxdp+Xt/A48VwTxwPVVNs+lAWs1+ZTGF+zlT65qWbnihUsX7uzBdPEllzLSA=="], + + "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.993.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", "@aws-sdk/util-user-agent-node": "^3.972.9", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.16", "@smithy/middleware-retry": "^4.4.33", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.10", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.32", "@smithy/util-defaults-mode-node": "^4.2.35", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-iOq86f2H67924kQUIPOAvlmMaOAvOLoDOIb66I2YqSUpMYB6ufiuJW3RlREgskxv86S5qKzMnfy/X6CqMjK6XQ=="], + + "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.31", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "tslib": "^2.6.2" } }, "sha512-5qLGtfKWyPK/eSLxIzsrNRfHVYZliXxe5mXYldmVB1Ca5VCpz0TjZhIb9otq1eUER8m2AQ1Jy0EBeR6qC65wvg=="], + + "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.38", "", { "dependencies": { "@aws-sdk/types": "^3.973.15", "@smithy/signature-v4": "^5.6.1", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-C379Sk+MiFZCfWZphKlMyLHKxV22OjoGM5KJjj5IJNJcOCWL4IGIpnEGzv1FQiRwhYXfq55SJMfxlqPE08JJ9g=="], + + "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1079.0", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/nested-clients": "^3.997.27", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-cbietrLlHPhhmbnMPTuDS4Zj/KNGhY+3vVhn6dwjO6Dqzrwothzg2srtcY34T9mlICsTXn34avDoWLHSntP54A=="], + + "@aws-sdk/types": ["@aws-sdk/types@3.973.15", "", { "dependencies": { "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-IULn8uBV/SMtmOIANsm4WHXIOtVPBWfOWs3WGL0j/sI+KhaYehvOw0ET+9urnn8MBpiijuU/0JOpuwKOE451PQ=="], + + "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.993.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw=="], + + "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.965.8", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g=="], + + "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.28", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "tslib": "^2.6.2" } }, "sha512-qr0fi8bkpkALaVPQzPinjAlWYR9/gswh4JUXHMoCBKS9YnoHCX+1qHROYGxWRI13BRg+OD4Wpl2NcuM0eFPyUA=="], + + "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.43", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "tslib": "^2.6.2" } }, "sha512-sM+qbPrMr3kLDSJi6J93On74p9IFNzI2Jx4JyO/8TvYB9sn2e0EbBt2z7pES+NCfKI+ITSqixY8pM+RZdT0Qow=="], + + "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.33", "", { "dependencies": { "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-ezbwz9WpuLctm6o7P2t2naDhVVPI5jFGrVefVybhcKGjU57VIyT46pQVO0RI2RYkUdhdj2Z9uSIlAzGZE9NW9A=="], + + "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.3.0", "", {}, "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ=="], + "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], "@babel/compat-data": ["@babel/compat-data@7.28.5", "", {}, "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA=="], @@ -592,6 +662,8 @@ "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], + "@infisical/sdk": ["@infisical/sdk@5.0.2", "", { "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-sdk/credential-providers": "3.993.0", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "typescript": "^5.5.4", "zod": "^3.23.8" } }, "sha512-mkgghtmIgBOEOFj1gb2n/AoiroFvN+NqaEEwC8ezEQ87V55yf2yksHhnBMU2MiZ26n6b3sGcpDZHF1/H6JrgyA=="], + "@inngest/ai": ["@inngest/ai@0.1.7", "", { "dependencies": { "@types/node": "^22.10.5", "typescript": "^5.7.3" } }, "sha512-5xWatW441jacGf9czKEZdgAmkvoy7GS2tp7X8GSbdGeRXzjisHR6vM+q8DQbv6rqRsmQoCQ5iShh34MguELvUQ=="], "@inquirer/ansi": ["@inquirer/ansi@2.0.7", "", {}, "sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q=="], @@ -1166,6 +1238,66 @@ "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], + "@smithy/config-resolver": ["@smithy/config-resolver@4.6.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-yI8StAYGQKiI+DxT0xkLhHSzxcIFSZTTWi0c4Lk3WLgmbe2QfLpR/Roo81ZF3VYwfwqH4IQVTKsy3FLZiVRaTQ=="], + + "@smithy/core": ["@smithy/core@3.29.1", "", { "dependencies": { "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-qoiY4nrk5OCu1+eIR1VB8l5DmON/oKiqrd5zZFAhXJXjJlLWQusKEW/SkBDAtGDcPaz86m9kfcE1lngU0GlM6A=="], + + "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-B2WQ/PV/H6Jeg3lrIq6bKUfa6Hy01mtK7CGs6lhjzHA6k4aagldH6T6eEjnzKl4HI0cJnAsxfJ19pgb5PV+CVQ=="], + + "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.6.3", "", { "dependencies": { "@smithy/core": "^3.29.1", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-CwCc/7SMTj45y97MUnDTbTaxvtAsiNNRm81z3abROIuMbMsC2Iy5EKfkkVdsKrz8WExQAAMx1EJapq+9j4fFTQ=="], + + "@smithy/hash-node": ["@smithy/hash-node@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-O6YGQgZGxypohUJDm+aIBNx9ldzOvQOjnnAmHYKAVJcVRMYQLf+g88s/vCUIHJudeXbgEo7xq1vXUGYlBpdBsg=="], + + "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-M2NNf2yB5pDYQiMyW3q6kD/aQyEfQlVFtFNR+LCnRKS/sg9xqOrOqkIZNP94B2aTwf+pwX3Qgp6foKw2ls9vIg=="], + + "@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], + + "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-kMXyfLgm2iqC3objUiElh1fp0AI33PxiAmPX+C0z7H8v4sfae2I2V9N62MlwO/LVPf+MlXpmfCYCHouetbecGg=="], + + "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.6.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-d7L894W4LE9HL2MkpWi0+KJG6/VCcuoxkquVaXYMMsrqK7PLT83GZsUBYL+ixxpEfwnlSE5hBotsB1A/qfWO9A=="], + + "@smithy/middleware-retry": ["@smithy/middleware-retry@4.7.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-zUF+liYyzSiPcz8vQhGCjUlykg521Y3shrsyzJ37Y3nkpz20KujcVXcOvgZb6e68n7Unl/Pb2RG0jrkx73AE+Q=="], + + "@smithy/middleware-serde": ["@smithy/middleware-serde@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-h9JBsYQBiltcbe5EJECXoJy+ZJSmnJKhc9UXyoWvEB1BIUkE8inxQ614dpeb+yydm2cq4YXqMXQLQB0QUBE6rA=="], + + "@smithy/middleware-stack": ["@smithy/middleware-stack@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-LUO+XAQP381sbiZ0QHOSLKPpS2I0/wXTh44rH/kP4/751Ogscn5JUsAWvUH+rYJWLupmiEsdHZT3Bn4Dvd4J/Q=="], + + "@smithy/node-config-provider": ["@smithy/node-config-provider@4.5.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-3fFpVGK28z1UhbDIPY6pujmnGwDhcD70NqJ8wJJwdQES5EYBe3mdOojSZdXtL0jfQE9BAbZSBi73WQ6VEOLRgQ=="], + + "@smithy/node-http-handler": ["@smithy/node-http-handler@4.9.3", "", { "dependencies": { "@smithy/core": "^3.29.1", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-qZTa4gQFUo8RM02rk6q5UVTDLNrQ1oS20LsepBzqq1QBVc/EHJ03OOUADcqMZiXHArW+Y7+OGY0BpdTwZRq/Yg=="], + + "@smithy/property-provider": ["@smithy/property-provider@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-lXq53BiaAI5XHMu0Sckzc+ouMX33exTdxkIyfaP4/61AAblnnjSd1QiT64LqjlFYwtxl8ldya1Wx0LLhtMv+hw=="], + + "@smithy/protocol-http": ["@smithy/protocol-http@5.5.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-ezPS1foOBPU+uv0da16sLF/7fMBXxeo7hFKitn/2gOxHd8HaQ7qK6DT8l0f1dUGoUS1lZC2s7mEkCwJ44QLCJg=="], + + "@smithy/signature-v4": ["@smithy/signature-v4@5.6.2", "", { "dependencies": { "@smithy/core": "^3.29.1", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-QgHflghMoPxCJ9axiCVh8KZfbC9fuP6vkXXyK//E3cq7nLaSSyyLj0GAoqVWezYeDQmXIZhmlRvLE16jsqDK6g=="], + + "@smithy/smithy-client": ["@smithy/smithy-client@4.14.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-Nr6u0buDP8iprqxAJ83pSFu2RavKHa/OG8n/ReWTYHg1OS3GLoDoa8F+2zoWoYkvwUawTa/dFugJ7NS0CuPcYg=="], + + "@smithy/types": ["@smithy/types@4.15.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-x3L0XSACF6UYzKpa9biqiRMgvH5+wnFFew9Tm/grFYqgaupPwx/+ojDPpPJM8dZON3S9tjz5U+PQYsCBd1Mw5Q=="], + + "@smithy/url-parser": ["@smithy/url-parser@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-bR6Te2/feLMCLiyEFqnZpM5AqkXlBGr7A5jHQn+WSVLk0X53NvPq1KF8jh5TJIv56RzDv3oKEW3t0DysRNLZdw=="], + + "@smithy/util-base64": ["@smithy/util-base64@4.5.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-N3hAANIKhtewRYICJjHscGtqQmAWISV+6Re5kbh8mOMiGKn6CvM252zocDdh9YWCmE/x9S1XAbe+5lzw+zjEZQ=="], + + "@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-oCVUok1wVnObl1nvtuj3DrVDtsgFNSmvVFc5VstnXKusqGKycKKPTtQHdlUMCklpB4g8pOp0jUOt7l7aAJlksg=="], + + "@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-hNk9goWxXF3BGXT7yIyyzG29gYvtqxk55cn7wyZHRsWDWEAA1ZN9E+tLFLpKEkEPVVqprCqLmHAmnmPc/556sg=="], + + "@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], + + "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.5.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-lsApK6dpDK9LY49GMHEsNQV2XpT/Y9WxKy8CmfbN6oLqPMCXlCYVLeIhedtdJmgbi0Mg09ZIjbhYVEg+V/wK0Q=="], + + "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-lKt5zA8YVx5SXanQ1t1iVZuaCuQcoJxUEh9BEpW64y5qKo3asCua7PiYsKkCv2RctwWZQqeEquB6WMostXBI4w=="], + + "@smithy/util-endpoints": ["@smithy/util-endpoints@3.6.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-IIgVh4W8OwBP3WL17RROPs7EWkaRdygli4I3vnhEK+zkVvMFagoKN7KbDCitTafQ7GSM3ev0ZawYehN+cFzd+A=="], + + "@smithy/util-middleware": ["@smithy/util-middleware@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-13aBkHIs4auNrqDwGE40rbkF/gXZQ/qNtufQKDHxYjc1juSAzY0ol0Kbv8Md5oaUovnNpTp2cXLQXZn3eAEnlA=="], + + "@smithy/util-retry": ["@smithy/util-retry@4.5.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-o7QZYe6U1HV5c9Oqb/mwf01YL+8NJ1wTWjGNSyA3fuaOaiC0U2UhmAY320dcBZlKOJU8O60QNfr8RWqE+OnU/w=="], + + "@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], + "@stablelib/base64": ["@stablelib/base64@1.0.1", "", {}, "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="], "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], @@ -1188,6 +1320,8 @@ "@super/sdk": ["@super/sdk@workspace:packages/sdk"], + "@super/secrets": ["@super/secrets@workspace:packages/secrets"], + "@super/ui": ["@super/ui@workspace:packages/ui"], "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], @@ -1564,6 +1698,8 @@ "bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="], + "bowser": ["bowser@2.14.1", "", {}, "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg=="], + "boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="], "brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], @@ -3300,6 +3436,22 @@ "@apidevtools/json-schema-ref-parser/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "@aws-sdk/client-cognito-identity/@smithy/util-utf8": ["@smithy/util-utf8@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-gncTZwzB/RTzm29VvK1nZhCHdPjBkR8pNaFtUMbQpkG6vFMjPHe/RsnmMXfrYj8Qs5s6QH5f1Mp9CBXFOHxqlQ=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.27", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/signature-v4-multi-region": "^3.996.38", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/fetch-http-handler": "^5.6.2", "@smithy/node-http-handler": "^4.9.2", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-A8PIePF9NIIOJ/4Lg1rl9xm/+QaKkHGetq+Z9wb5B+3Da31YYXRo8n7IDMh5C+HQI5eyEmjrwkGWVdYtnLtbXQ=="], + + "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.27", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/signature-v4-multi-region": "^3.996.38", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/fetch-http-handler": "^5.6.2", "@smithy/node-http-handler": "^4.9.2", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-A8PIePF9NIIOJ/4Lg1rl9xm/+QaKkHGetq+Z9wb5B+3Da31YYXRo8n7IDMh5C+HQI5eyEmjrwkGWVdYtnLtbXQ=="], + + "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.27", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/signature-v4-multi-region": "^3.996.38", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/fetch-http-handler": "^5.6.2", "@smithy/node-http-handler": "^4.9.2", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-A8PIePF9NIIOJ/4Lg1rl9xm/+QaKkHGetq+Z9wb5B+3Da31YYXRo8n7IDMh5C+HQI5eyEmjrwkGWVdYtnLtbXQ=="], + + "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.27", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/signature-v4-multi-region": "^3.996.38", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/fetch-http-handler": "^5.6.2", "@smithy/node-http-handler": "^4.9.2", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-A8PIePF9NIIOJ/4Lg1rl9xm/+QaKkHGetq+Z9wb5B+3Da31YYXRo8n7IDMh5C+HQI5eyEmjrwkGWVdYtnLtbXQ=="], + + "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.27", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/signature-v4-multi-region": "^3.996.38", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/fetch-http-handler": "^5.6.2", "@smithy/node-http-handler": "^4.9.2", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-A8PIePF9NIIOJ/4Lg1rl9xm/+QaKkHGetq+Z9wb5B+3Da31YYXRo8n7IDMh5C+HQI5eyEmjrwkGWVdYtnLtbXQ=="], + + "@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.4.6", "", { "dependencies": { "@smithy/core": "^3.29.1", "tslib": "^2.6.2" } }, "sha512-gncTZwzB/RTzm29VvK1nZhCHdPjBkR8pNaFtUMbQpkG6vFMjPHe/RsnmMXfrYj8Qs5s6QH5f1Mp9CBXFOHxqlQ=="], + + "@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.27", "", { "dependencies": { "@aws-sdk/core": "^3.974.27", "@aws-sdk/signature-v4-multi-region": "^3.996.38", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/fetch-http-handler": "^5.6.2", "@smithy/node-http-handler": "^4.9.2", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-A8PIePF9NIIOJ/4Lg1rl9xm/+QaKkHGetq+Z9wb5B+3Da31YYXRo8n7IDMh5C+HQI5eyEmjrwkGWVdYtnLtbXQ=="], + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/helper-annotate-as-pure/@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], diff --git a/packages/secrets/package.json b/packages/secrets/package.json index ef975f1..df07b7d 100644 --- a/packages/secrets/package.json +++ b/packages/secrets/package.json @@ -13,7 +13,7 @@ "typecheck": "echo 'secrets typecheck pending'" }, "dependencies": { - "@infisical/sdk": "^0.0.30", + "@infisical/sdk": "^5.0.2", "zod": "^3.24.0" } } diff --git a/packages/secrets/src/client.ts b/packages/secrets/src/client.ts index 2de1db6..01e8b30 100644 --- a/packages/secrets/src/client.ts +++ b/packages/secrets/src/client.ts @@ -1,16 +1,16 @@ -import { InfisicalClient } from "@infisical/sdk" +import { InfisicalSDK } from "@infisical/sdk" import { resolveToken } from "./resolve-token" import type { AppId } from "./resolve-token" -let shared: InfisicalClient | null = null +let shared: InfisicalSDK | null = null -export function getClient(app: AppId): InfisicalClient { +export function getClient(app: AppId): InfisicalSDK { if (!shared) { - const { token, source } = resolveToken(app) - shared = new InfisicalClient({ - token, + const { token } = resolveToken(app) + shared = new InfisicalSDK({ siteUrl: process.env.INFISICAL_SITE_URL ?? "https://app.infisical.com", }) + shared.authenticate(token) } return shared } diff --git a/packages/secrets/src/index.ts b/packages/secrets/src/index.ts index afcd9fe..099c7c7 100644 --- a/packages/secrets/src/index.ts +++ b/packages/secrets/src/index.ts @@ -25,8 +25,8 @@ export async function loadSecrets(options: LoadSecretsOptions): Promise { ) } - const client = getClient(app) - const secrets = await client.listSecrets({ + const sdk = getClient(app) + const { secrets } = await sdk.secrets().listSecrets({ environment: env, projectId, attachToProcessEnv: false,