@dinanathdash/envault-sdk 1.0.3 → 1.0.4
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../agent-interceptor.ts","../version.ts"],"sourcesContent":["import { execFileSync, execSync } from \"child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport crypto from \"node:crypto\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { SDK_VERSION } from \"./version\";\n\ntype MutationOperation = {\n key: string;\n value?: string;\n action: \"upsert\" | \"delete\";\n};\n\ntype MutationPayload = {\n mutations: MutationOperation[];\n environment?: string;\n environmentSlug?: string;\n};\n\ntype ExecuteMutationOptions = {\n environment?: string;\n waitForApproval?: boolean;\n};\n\ntype PendingApprovalResult = {\n status: \"pending_approval\";\n approval_id: string;\n approval_url: string;\n project_id: string;\n approve_command: string;\n};\n\n/**\n * Encapsulates the runtime SDK execution loop with Human-In-The-Loop intercepts.\n */\nexport class EnvaultAgentClient {\n private endpoint: string;\n private token: string;\n private projectIdHint?: string;\n private resolvedProjectId?: string;\n private compatibilityCheckPromise: Promise<void>;\n private originalSecrets: Record<string, string> = {};\n\n constructor(endpoint: string, token: string, projectId?: string) {\n this.endpoint = endpoint;\n this.token = token;\n this.projectIdHint = projectId;\n this.compatibilityCheckPromise = this.checkSdkCompatibility();\n }\n\n private isUuid(value: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(\n value,\n );\n }\n\n private resolveProjectIdFromEnvaultJson(): string | null {\n const configPath = path.join(process.cwd(), \"envault.json\");\n if (!existsSync(configPath)) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(readFileSync(configPath, \"utf-8\")) as {\n projectId?: unknown;\n };\n if (\n typeof parsed.projectId === \"string\" &&\n this.isUuid(parsed.projectId.trim())\n ) {\n return parsed.projectId.trim();\n }\n } catch {\n // Invalid local config should not crash SDK initialization.\n }\n\n return null;\n }\n\n private resolveProjectId(): string {\n if (this.resolvedProjectId) {\n return this.resolvedProjectId;\n }\n\n const fromHint = (this.projectIdHint || \"\").trim();\n if (this.isUuid(fromHint)) {\n this.resolvedProjectId = fromHint;\n return fromHint;\n }\n\n const fromConfigFile = this.resolveProjectIdFromEnvaultJson();\n if (fromConfigFile) {\n this.resolvedProjectId = fromConfigFile;\n return fromConfigFile;\n }\n\n const fromEnv = (process.env.ENVAULT_PROJECT_ID || \"\").trim();\n if (this.isUuid(fromEnv)) {\n this.resolvedProjectId = fromEnv;\n return fromEnv;\n }\n\n throw new Error(\n \"Unable to resolve project context. Run `envault init` in this directory or set ENVAULT_PROJECT_ID.\",\n );\n }\n\n private compareVersions(a: string, b: string): number {\n const parse = (value: string): number[] => {\n return value\n .trim()\n .replace(/^v/i, \"\")\n .split(\".\")\n .map((segment) => Number.parseInt(segment.replace(/[^0-9].*$/, \"\"), 10) || 0);\n };\n\n const left = parse(a);\n const right = parse(b);\n const maxLength = Math.max(left.length, right.length);\n\n for (let index = 0; index < maxLength; index += 1) {\n const l = left[index] ?? 0;\n const r = right[index] ?? 0;\n if (l > r) return 1;\n if (l < r) return -1;\n }\n\n return 0;\n }\n\n private async checkSdkCompatibility(): Promise<void> {\n try {\n const response = await fetch(`${this.endpoint}/api/sdk-version`, {\n headers: {\n \"X-SDK-Version\": SDK_VERSION,\n },\n });\n\n if (!response.ok) {\n return;\n }\n\n const data = (await response.json()) as {\n latest_version?: unknown;\n min_supported_version?: unknown;\n };\n\n const latestVersion =\n typeof data.latest_version === \"string\" && data.latest_version.trim().length > 0\n ? data.latest_version.trim()\n : null;\n const minSupportedVersion =\n typeof data.min_supported_version === \"string\" &&\n data.min_supported_version.trim().length > 0\n ? data.min_supported_version.trim()\n : null;\n\n if (minSupportedVersion && this.compareVersions(SDK_VERSION, minSupportedVersion) < 0) {\n throw new Error(\n `Envault SDK ${SDK_VERSION} is below minimum supported version ${minSupportedVersion}. Please upgrade before continuing.`,\n );\n }\n\n if (latestVersion && this.compareVersions(SDK_VERSION, latestVersion) < 0) {\n console.warn(\n `[Envault SDK] A newer SDK version (${latestVersion}) is available. You are running ${SDK_VERSION}.`,\n );\n }\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"minimum supported version\")) {\n throw error;\n }\n // Best-effort network check should not block execution when endpoint is unavailable.\n }\n }\n\n private resolveAppBaseUrl(): string {\n const LOCAL_APP_URL = \"https://envault.localhost:1355\";\n const PROD_APP_URL = \"https://envault.tech\";\n\n const normalize = (value: string): string | null => {\n try {\n return new URL(value).origin.replace(/\\/$/, \"\");\n } catch {\n return null;\n }\n };\n\n const configuredCandidates = [\n process.env.BASE_URL,\n process.env.NEXT_PUBLIC_APP_URL,\n ];\n\n for (const configured of configuredCandidates) {\n if (!configured) continue;\n const origin = normalize(configured);\n if (!origin) continue;\n if (origin === LOCAL_APP_URL) return LOCAL_APP_URL;\n if (origin === PROD_APP_URL) return PROD_APP_URL;\n }\n\n try {\n const parsedEndpoint = new URL(this.endpoint);\n if (\n parsedEndpoint.hostname === \"localhost\" ||\n parsedEndpoint.hostname === \"127.0.0.1\" ||\n parsedEndpoint.hostname.endsWith(\".localhost\")\n ) {\n return LOCAL_APP_URL;\n }\n return PROD_APP_URL;\n } catch {\n return PROD_APP_URL;\n }\n }\n\n /**\n * Generates a repeatable Idempotency-Key\n */\n private generateIdempotencyKey(): string {\n return crypto.randomUUID();\n }\n\n /**\n * Exposes a native OS Notification for local setups.\n * Uses a layered fallback so IDE and system alerts still surface when one path fails.\n */\n private async triggerOsNotification(message: string, approvalUrl?: string) {\n const title = \"Envault Agent Security\";\n const notificationIcon = this.resolveNotificationIconPath();\n const allowOsaFallback = process.env.ENVAULT_ALLOW_OSASCRIPT_NOTIFIER === \"true\";\n\n const emitTerminalAttention = () => {\n // VS Code integrated terminal shows a bell/status icon for BEL events.\n process.stdout.write(\"\\u0007\");\n };\n\n const tryNodeNotifier = async (): Promise<boolean> => {\n try {\n const notifierModule = (await import(\"node-notifier\")) as unknown as {\n default?: {\n notify: (\n options: {\n title: string;\n message: string;\n open?: string;\n sound?: boolean;\n wait?: boolean;\n timeout?: number;\n icon?: string;\n },\n callback?: (err: Error | null) => void,\n ) => void;\n };\n notify?: (\n options: {\n title: string;\n message: string;\n open?: string;\n sound?: boolean;\n wait?: boolean;\n timeout?: number;\n icon?: string;\n },\n callback?: (err: Error | null) => void,\n ) => void;\n };\n\n const notify = notifierModule.default?.notify || notifierModule.notify;\n if (!notify) {\n return false;\n }\n\n // Do not block on notifier callbacks; some backends never invoke them.\n notify({\n title,\n message,\n open: approvalUrl,\n sound: true,\n wait: false,\n timeout: 8,\n icon: notificationIcon || undefined,\n });\n\n return true;\n } catch {\n return false;\n }\n };\n\n try {\n // Always emit a local terminal cue first so there is a reliable ping even\n // when native notification permissions/tools are unavailable.\n emitTerminalAttention();\n\n if (await tryNodeNotifier()) {\n return;\n }\n\n if (process.platform === \"darwin\") {\n const terminalNotifierPath = this.resolveTerminalNotifierPath();\n try {\n if (terminalNotifierPath) {\n const args = [\"-title\", title, \"-message\", message, \"-sound\", \"default\"];\n if (approvalUrl) {\n args.push(\"-open\", approvalUrl);\n }\n if (notificationIcon) {\n const iconUrl = pathToFileURL(notificationIcon).toString();\n args.push(\"-appIcon\", iconUrl);\n }\n execFileSync(terminalNotifierPath, args, { stdio: \"ignore\" });\n return;\n }\n } catch {\n // Keep fallback chain moving.\n }\n\n if (allowOsaFallback) {\n try {\n const appleScript = `display notification \"${message.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\" with title \"${title.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\" sound name \"default\"`;\n execFileSync(\"osascript\", [\"-e\", appleScript], { stdio: \"ignore\" });\n return;\n } catch {\n // Keep fallback chain moving.\n }\n }\n\n console.error(`[Envault Agent] Notification unavailable: ${message}`);\n console.error(\"[Envault Agent] Install terminal-notifier (brew install terminal-notifier) to enable native macOS notifications.\");\n if (approvalUrl) {\n console.error(`[Envault Agent] Approval URL: ${approvalUrl}`);\n }\n return;\n } else if (process.platform === \"linux\") {\n const iconArg = notificationIcon\n ? ` --icon=\"${notificationIcon.replace(/\"/g, \"\\\\\\\"\")}\"`\n : \"\";\n execSync(\n `notify-send \"Envault Agent Security\" \"${message.replace(/\"/g, \"'\")}\"${iconArg}`,\n {\n stdio: \"ignore\",\n },\n );\n return;\n }\n } catch {\n // Best-effort local notification, do not crash execution\n }\n }\n\n private resolveNotificationIconPath(): string | null {\n const candidate = path.join(process.cwd(), \"public\", \"favicon.png\");\n return existsSync(candidate) ? candidate : null;\n }\n\n private resolveTerminalNotifierPath(): string | null {\n const candidates = [\n \"/opt/homebrew/bin/terminal-notifier\",\n \"/usr/local/bin/terminal-notifier\",\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n try {\n const commandPath = execSync(\"command -v terminal-notifier\", {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n return commandPath || null;\n } catch {\n return null;\n }\n }\n\n /**\n * Pre-execution routine: Ensure Zero-Trust LLM Context\n * Redacts actual secret values from strings intended for the Chat UI LLM.\n */\n public prepareLlmContext(\n fetchedEnv: Record<string, string>,\n ): Record<string, string> {\n this.originalSecrets = { ...fetchedEnv };\n const redacted: Record<string, string> = {};\n for (const [key] of Object.entries(fetchedEnv)) {\n redacted[key] = `[REDACTED_SECRET_${key}]`;\n }\n return redacted;\n }\n\n private restoreLlmContext(payload: unknown): unknown {\n const restore = (value: unknown): unknown => {\n if (typeof value === \"string\") {\n // Replace redacted tags even when embedded inside larger strings.\n return value.replace(/\\[REDACTED_SECRET_([^\\]]+)\\]/g, (match, key) => {\n return Object.prototype.hasOwnProperty.call(this.originalSecrets, key)\n ? this.originalSecrets[key]\n : match;\n });\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => restore(item));\n }\n\n if (value && typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const restored: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n restored[k] = restore(v);\n }\n return restored;\n }\n\n return value;\n };\n\n return restore(payload);\n }\n\n /**\n * The core 202 Polling Loop for executing mutations.\n * Split-Routing ensures the Chat UI handles the \"why\" and terminal handles \"how\".\n */\n public async executeMutation(\n payload: MutationPayload,\n options?: ExecuteMutationOptions,\n ): Promise<unknown> {\n await this.compatibilityCheckPromise;\n\n const resolvedProjectId = this.resolveProjectId();\n const idempotencyKey = this.generateIdempotencyKey();\n const restoredPayload = this.restoreLlmContext(payload) as MutationPayload;\n\n const selectedEnvironment =\n (options?.environment || restoredPayload.environment || restoredPayload.environmentSlug || \"\")\n .toString()\n .trim();\n\n const payloadForApi: MutationPayload = {\n ...restoredPayload,\n ...(selectedEnvironment\n ? {\n environment: selectedEnvironment,\n environmentSlug: selectedEnvironment,\n }\n : {}),\n };\n\n // Initial Mutation Intercept\n const response = await fetch(`${this.endpoint}/api/sdk/secrets`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n \"Idempotency-Key\": idempotencyKey,\n \"X-SDK-Version\": SDK_VERSION,\n },\n body: JSON.stringify({\n projectId: resolvedProjectId,\n payload: payloadForApi,\n action: \"update\",\n }),\n });\n\n if (response.status === 429) {\n console.error(\"[Envault SDK] Rate limit hit. Terminal execution halted.\");\n throw new Error(\"Too Many Requests\");\n }\n\n if (!response.ok && response.status !== 202) {\n throw new Error(`API Error: ${response.status} ${await response.text()}`);\n }\n\n const data = await response.json();\n\n if (response.status === 202 || data.status === \"pending\") {\n const approvalId =\n typeof data.approval_id === \"string\" ? data.approval_id : \"\";\n if (!approvalId) {\n throw new Error(\"Approval response missing approval_id\");\n }\n const approvalUrl =\n typeof data.approval_url === \"string\" && data.approval_url.length > 0\n ? data.approval_url\n : `${this.resolveAppBaseUrl()}/approve/${approvalId}`;\n\n const pendingResult: PendingApprovalResult = {\n status: \"pending_approval\",\n approval_id: approvalId,\n approval_url: approvalUrl,\n project_id: resolvedProjectId,\n approve_command: `envault approve ${approvalId}`,\n };\n\n // Split-Routing Glass-Box Execution: Stream deterministic state to `stdout`\n process.stdout.write(\n `\\n\\x1b[33m[Envault SDK] Action paused. Human approval required.\\x1b[0m`,\n );\n process.stdout.write(\n `\\n\\x1b[36mApprove inline with: ${pendingResult.approve_command}\\x1b[0m\\n`,\n );\n\n void this.triggerOsNotification(\n `Envault Agent requires approval for [${resolvedProjectId}].`,\n approvalUrl,\n );\n\n if (!options?.waitForApproval) {\n return pendingResult;\n }\n\n try {\n const approvedPayload = await this.pollForApproval(approvalId);\n return {\n status: \"approved\",\n approval_id: approvalId,\n payload: approvedPayload,\n };\n } catch (error) {\n if (error instanceof Error && error.message === \"HitlApprovalRejected\") {\n throw new Error(\"Mutation rejected by project administrator.\");\n }\n throw error;\n }\n }\n\n return data;\n }\n\n /**\n * 3-second polling loop handling the One-Time Read Burn mechanics\n */\n private async pollForApproval(approvalId: string): Promise<unknown> {\n return new Promise((resolve, reject) => {\n process.stdout.write(\"Polling status\");\n let finished = false;\n\n const finish = (fn: () => void) => {\n if (finished) return;\n finished = true;\n clearInterval(interval);\n clearTimeout(timeoutHandle);\n fn();\n };\n\n const interval = setInterval(async () => {\n try {\n process.stdout.write(\".\"); // Terminal execution visual\n\n const res = await fetch(\n `${this.endpoint}/api/sdk/approvals/${approvalId}/status`,\n {\n headers: {\n Authorization: `Bearer ${this.token}`,\n \"X-SDK-Version\": SDK_VERSION,\n },\n },\n );\n\n // 410 Gone means the hitl-burn constraint worked or timed out\n if (res.status === 410) {\n return finish(() => {\n console.log(\n \"\\n\\x1b[31m[Envault SDK] Resource Gone (Approval expired or already consumed by a replay attack).\\x1b[0m\",\n );\n reject(new Error(\"HitlApprovalGone\"));\n });\n }\n\n if (res.status === 403) {\n try {\n await res.json();\n } catch {\n // Ignore JSON parsing failures and fall back to generic 403 rejection.\n }\n return finish(() => {\n console.log(\n \"\\n\\x1b[31m[Envault SDK] Action Rejected by Human.\\x1b[0m\",\n );\n reject(new Error(\"HitlApprovalRejected\"));\n });\n }\n\n if (res.status === 200) {\n const result = await res.json();\n if (result?.status === \"rejected\") {\n return finish(() => {\n console.log(\n \"\\n\\x1b[31m[Envault SDK] Action Rejected by Human.\\x1b[0m\",\n );\n reject(new Error(\"HitlApprovalRejected\"));\n });\n }\n return finish(() => {\n console.log(\n \"\\n\\x1b[32m[Envault SDK] Approved. Resuming execution.\\x1b[0m\\n\",\n );\n resolve(result.payload);\n });\n }\n } catch {\n process.stdout.write(\"x\"); // Local network failure indicator\n }\n }, 3000); // 3-second cycle\n\n // Safety timeout matching the 15m TTL constraint\n const timeoutHandle = setTimeout(() => {\n finish(() => {\n console.log(\"\\n\\x1b[31m[Envault SDK] Polling timeout (15m).\\x1b[0m\");\n reject(new Error(\"HitlApprovalTimeout\"));\n });\n }, 15 * 60 * 1000);\n });\n }\n}\n","export const SDK_VERSION = \"1.0.2\";\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../agent-interceptor.ts","../version.ts"],"sourcesContent":["import { execFileSync, execSync } from \"child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport crypto from \"node:crypto\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { SDK_VERSION } from \"./version\";\n\ntype MutationOperation = {\n key: string;\n value?: string;\n action: \"upsert\" | \"delete\";\n};\n\ntype MutationPayload = {\n mutations: MutationOperation[];\n environment?: string;\n environmentSlug?: string;\n};\n\ntype ExecuteMutationOptions = {\n environment?: string;\n waitForApproval?: boolean;\n};\n\ntype PendingApprovalResult = {\n status: \"pending_approval\";\n approval_id: string;\n approval_url: string;\n project_id: string;\n approve_command: string;\n};\n\n/**\n * Encapsulates the runtime SDK execution loop with Human-In-The-Loop intercepts.\n */\nexport class EnvaultAgentClient {\n private endpoint: string;\n private token: string;\n private projectIdHint?: string;\n private resolvedProjectId?: string;\n private compatibilityCheckPromise: Promise<void>;\n private originalSecrets: Record<string, string> = {};\n\n constructor(endpoint: string, token: string, projectId?: string) {\n this.endpoint = endpoint;\n this.token = token;\n this.projectIdHint = projectId;\n this.compatibilityCheckPromise = this.checkSdkCompatibility();\n }\n\n private isUuid(value: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(\n value,\n );\n }\n\n private resolveProjectIdFromEnvaultJson(): string | null {\n const configPath = path.join(process.cwd(), \"envault.json\");\n if (!existsSync(configPath)) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(readFileSync(configPath, \"utf-8\")) as {\n projectId?: unknown;\n };\n if (\n typeof parsed.projectId === \"string\" &&\n this.isUuid(parsed.projectId.trim())\n ) {\n return parsed.projectId.trim();\n }\n } catch {\n // Invalid local config should not crash SDK initialization.\n }\n\n return null;\n }\n\n private resolveProjectId(): string {\n if (this.resolvedProjectId) {\n return this.resolvedProjectId;\n }\n\n const fromHint = (this.projectIdHint || \"\").trim();\n if (this.isUuid(fromHint)) {\n this.resolvedProjectId = fromHint;\n return fromHint;\n }\n\n const fromConfigFile = this.resolveProjectIdFromEnvaultJson();\n if (fromConfigFile) {\n this.resolvedProjectId = fromConfigFile;\n return fromConfigFile;\n }\n\n const fromEnv = (process.env.ENVAULT_PROJECT_ID || \"\").trim();\n if (this.isUuid(fromEnv)) {\n this.resolvedProjectId = fromEnv;\n return fromEnv;\n }\n\n throw new Error(\n \"Unable to resolve project context. Run `envault init` in this directory or set ENVAULT_PROJECT_ID.\",\n );\n }\n\n private compareVersions(a: string, b: string): number {\n const parse = (value: string): number[] => {\n return value\n .trim()\n .replace(/^v/i, \"\")\n .split(\".\")\n .map((segment) => Number.parseInt(segment.replace(/[^0-9].*$/, \"\"), 10) || 0);\n };\n\n const left = parse(a);\n const right = parse(b);\n const maxLength = Math.max(left.length, right.length);\n\n for (let index = 0; index < maxLength; index += 1) {\n const l = left[index] ?? 0;\n const r = right[index] ?? 0;\n if (l > r) return 1;\n if (l < r) return -1;\n }\n\n return 0;\n }\n\n private async checkSdkCompatibility(): Promise<void> {\n try {\n const response = await fetch(`${this.endpoint}/api/sdk-version`, {\n headers: {\n \"X-SDK-Version\": SDK_VERSION,\n },\n });\n\n if (!response.ok) {\n return;\n }\n\n const data = (await response.json()) as {\n latest_version?: unknown;\n min_supported_version?: unknown;\n };\n\n const latestVersion =\n typeof data.latest_version === \"string\" && data.latest_version.trim().length > 0\n ? data.latest_version.trim()\n : null;\n const minSupportedVersion =\n typeof data.min_supported_version === \"string\" &&\n data.min_supported_version.trim().length > 0\n ? data.min_supported_version.trim()\n : null;\n\n if (minSupportedVersion && this.compareVersions(SDK_VERSION, minSupportedVersion) < 0) {\n throw new Error(\n `Envault SDK ${SDK_VERSION} is below minimum supported version ${minSupportedVersion}. Please upgrade before continuing.`,\n );\n }\n\n if (latestVersion && this.compareVersions(SDK_VERSION, latestVersion) < 0) {\n console.warn(\n `[Envault SDK] A newer SDK version (${latestVersion}) is available. You are running ${SDK_VERSION}.`,\n );\n }\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"minimum supported version\")) {\n throw error;\n }\n // Best-effort network check should not block execution when endpoint is unavailable.\n }\n }\n\n private resolveAppBaseUrl(): string {\n const LOCAL_APP_URL = \"https://envault.localhost:1355\";\n const PROD_APP_URL = \"https://envault.tech\";\n\n const normalize = (value: string): string | null => {\n try {\n return new URL(value).origin.replace(/\\/$/, \"\");\n } catch {\n return null;\n }\n };\n\n const configuredCandidates = [\n process.env.BASE_URL,\n process.env.NEXT_PUBLIC_APP_URL,\n ];\n\n for (const configured of configuredCandidates) {\n if (!configured) continue;\n const origin = normalize(configured);\n if (!origin) continue;\n if (origin === LOCAL_APP_URL) return LOCAL_APP_URL;\n if (origin === PROD_APP_URL) return PROD_APP_URL;\n }\n\n try {\n const parsedEndpoint = new URL(this.endpoint);\n if (\n parsedEndpoint.hostname === \"localhost\" ||\n parsedEndpoint.hostname === \"127.0.0.1\" ||\n parsedEndpoint.hostname.endsWith(\".localhost\")\n ) {\n return LOCAL_APP_URL;\n }\n return PROD_APP_URL;\n } catch {\n return PROD_APP_URL;\n }\n }\n\n /**\n * Generates a repeatable Idempotency-Key\n */\n private generateIdempotencyKey(): string {\n return crypto.randomUUID();\n }\n\n /**\n * Exposes a native OS Notification for local setups.\n * Uses a layered fallback so IDE and system alerts still surface when one path fails.\n */\n private async triggerOsNotification(message: string, approvalUrl?: string) {\n const title = \"Envault Agent Security\";\n const notificationIcon = this.resolveNotificationIconPath();\n const allowOsaFallback = process.env.ENVAULT_ALLOW_OSASCRIPT_NOTIFIER === \"true\";\n\n const emitTerminalAttention = () => {\n // VS Code integrated terminal shows a bell/status icon for BEL events.\n process.stdout.write(\"\\u0007\");\n };\n\n const tryNodeNotifier = async (): Promise<boolean> => {\n try {\n const notifierModule = (await import(\"node-notifier\")) as unknown as {\n default?: {\n notify: (\n options: {\n title: string;\n message: string;\n open?: string;\n sound?: boolean;\n wait?: boolean;\n timeout?: number;\n icon?: string;\n },\n callback?: (err: Error | null) => void,\n ) => void;\n };\n notify?: (\n options: {\n title: string;\n message: string;\n open?: string;\n sound?: boolean;\n wait?: boolean;\n timeout?: number;\n icon?: string;\n },\n callback?: (err: Error | null) => void,\n ) => void;\n };\n\n const notify = notifierModule.default?.notify || notifierModule.notify;\n if (!notify) {\n return false;\n }\n\n // Do not block on notifier callbacks; some backends never invoke them.\n notify({\n title,\n message,\n open: approvalUrl,\n sound: true,\n wait: false,\n timeout: 8,\n icon: notificationIcon || undefined,\n });\n\n return true;\n } catch {\n return false;\n }\n };\n\n try {\n // Always emit a local terminal cue first so there is a reliable ping even\n // when native notification permissions/tools are unavailable.\n emitTerminalAttention();\n\n if (await tryNodeNotifier()) {\n return;\n }\n\n if (process.platform === \"darwin\") {\n const terminalNotifierPath = this.resolveTerminalNotifierPath();\n try {\n if (terminalNotifierPath) {\n const args = [\"-title\", title, \"-message\", message, \"-sound\", \"default\"];\n if (approvalUrl) {\n args.push(\"-open\", approvalUrl);\n }\n if (notificationIcon) {\n const iconUrl = pathToFileURL(notificationIcon).toString();\n args.push(\"-appIcon\", iconUrl);\n }\n execFileSync(terminalNotifierPath, args, { stdio: \"ignore\" });\n return;\n }\n } catch {\n // Keep fallback chain moving.\n }\n\n if (allowOsaFallback) {\n try {\n const appleScript = `display notification \"${message.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\" with title \"${title.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\" sound name \"default\"`;\n execFileSync(\"osascript\", [\"-e\", appleScript], { stdio: \"ignore\" });\n return;\n } catch {\n // Keep fallback chain moving.\n }\n }\n\n console.error(`[Envault Agent] Notification unavailable: ${message}`);\n console.error(\"[Envault Agent] Install terminal-notifier (brew install terminal-notifier) to enable native macOS notifications.\");\n if (approvalUrl) {\n console.error(`[Envault Agent] Approval URL: ${approvalUrl}`);\n }\n return;\n } else if (process.platform === \"linux\") {\n const iconArg = notificationIcon\n ? ` --icon=\"${notificationIcon.replace(/\"/g, \"\\\\\\\"\")}\"`\n : \"\";\n execSync(\n `notify-send \"Envault Agent Security\" \"${message.replace(/\"/g, \"'\")}\"${iconArg}`,\n {\n stdio: \"ignore\",\n },\n );\n return;\n }\n } catch {\n // Best-effort local notification, do not crash execution\n }\n }\n\n private resolveNotificationIconPath(): string | null {\n const candidate = path.join(process.cwd(), \"public\", \"favicon.png\");\n return existsSync(candidate) ? candidate : null;\n }\n\n private resolveTerminalNotifierPath(): string | null {\n const candidates = [\n \"/opt/homebrew/bin/terminal-notifier\",\n \"/usr/local/bin/terminal-notifier\",\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n try {\n const commandPath = execSync(\"command -v terminal-notifier\", {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n return commandPath || null;\n } catch {\n return null;\n }\n }\n\n /**\n * Pre-execution routine: Ensure Zero-Trust LLM Context\n * Redacts actual secret values from strings intended for the Chat UI LLM.\n */\n public prepareLlmContext(\n fetchedEnv: Record<string, string>,\n ): Record<string, string> {\n this.originalSecrets = { ...fetchedEnv };\n const redacted: Record<string, string> = {};\n for (const [key] of Object.entries(fetchedEnv)) {\n redacted[key] = `[REDACTED_SECRET_${key}]`;\n }\n return redacted;\n }\n\n private restoreLlmContext(payload: unknown): unknown {\n const restore = (value: unknown): unknown => {\n if (typeof value === \"string\") {\n // Replace redacted tags even when embedded inside larger strings.\n return value.replace(/\\[REDACTED_SECRET_([^\\]]+)\\]/g, (match, key) => {\n return Object.prototype.hasOwnProperty.call(this.originalSecrets, key)\n ? this.originalSecrets[key]\n : match;\n });\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => restore(item));\n }\n\n if (value && typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const restored: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n restored[k] = restore(v);\n }\n return restored;\n }\n\n return value;\n };\n\n return restore(payload);\n }\n\n /**\n * The core 202 Polling Loop for executing mutations.\n * Split-Routing ensures the Chat UI handles the \"why\" and terminal handles \"how\".\n */\n public async executeMutation(\n payload: MutationPayload,\n options?: ExecuteMutationOptions,\n ): Promise<unknown> {\n await this.compatibilityCheckPromise;\n\n const resolvedProjectId = this.resolveProjectId();\n const idempotencyKey = this.generateIdempotencyKey();\n const restoredPayload = this.restoreLlmContext(payload) as MutationPayload;\n\n const selectedEnvironment =\n (options?.environment || restoredPayload.environment || restoredPayload.environmentSlug || \"\")\n .toString()\n .trim();\n\n const payloadForApi: MutationPayload = {\n ...restoredPayload,\n ...(selectedEnvironment\n ? {\n environment: selectedEnvironment,\n environmentSlug: selectedEnvironment,\n }\n : {}),\n };\n\n // Initial Mutation Intercept\n const response = await fetch(`${this.endpoint}/api/sdk/secrets`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n \"Idempotency-Key\": idempotencyKey,\n \"X-SDK-Version\": SDK_VERSION,\n },\n body: JSON.stringify({\n projectId: resolvedProjectId,\n payload: payloadForApi,\n action: \"update\",\n }),\n });\n\n if (response.status === 429) {\n console.error(\"[Envault SDK] Rate limit hit. Terminal execution halted.\");\n throw new Error(\"Too Many Requests\");\n }\n\n if (!response.ok && response.status !== 202) {\n throw new Error(`API Error: ${response.status} ${await response.text()}`);\n }\n\n const data = await response.json();\n\n if (response.status === 202 || data.status === \"pending\") {\n const approvalId =\n typeof data.approval_id === \"string\" ? data.approval_id : \"\";\n if (!approvalId) {\n throw new Error(\"Approval response missing approval_id\");\n }\n const approvalUrl =\n typeof data.approval_url === \"string\" && data.approval_url.length > 0\n ? data.approval_url\n : `${this.resolveAppBaseUrl()}/approve/${approvalId}`;\n\n const pendingResult: PendingApprovalResult = {\n status: \"pending_approval\",\n approval_id: approvalId,\n approval_url: approvalUrl,\n project_id: resolvedProjectId,\n approve_command: `envault approve ${approvalId}`,\n };\n\n // Split-Routing Glass-Box Execution: Stream deterministic state to `stdout`\n process.stdout.write(\n `\\n\\x1b[33m[Envault SDK] Action paused. Human approval required.\\x1b[0m`,\n );\n process.stdout.write(\n `\\n\\x1b[36mApprove inline with: ${pendingResult.approve_command}\\x1b[0m\\n`,\n );\n\n void this.triggerOsNotification(\n `Envault Agent requires approval for [${resolvedProjectId}].`,\n approvalUrl,\n );\n\n if (!options?.waitForApproval) {\n return pendingResult;\n }\n\n try {\n const approvedPayload = await this.pollForApproval(approvalId);\n return {\n status: \"approved\",\n approval_id: approvalId,\n payload: approvedPayload,\n };\n } catch (error) {\n if (error instanceof Error && error.message === \"HitlApprovalRejected\") {\n throw new Error(\"Mutation rejected by project administrator.\");\n }\n throw error;\n }\n }\n\n return data;\n }\n\n /**\n * 3-second polling loop handling the One-Time Read Burn mechanics\n */\n private async pollForApproval(approvalId: string): Promise<unknown> {\n return new Promise((resolve, reject) => {\n process.stdout.write(\"Polling status\");\n let finished = false;\n\n const finish = (fn: () => void) => {\n if (finished) return;\n finished = true;\n clearInterval(interval);\n clearTimeout(timeoutHandle);\n fn();\n };\n\n const interval = setInterval(async () => {\n try {\n process.stdout.write(\".\"); // Terminal execution visual\n\n const res = await fetch(\n `${this.endpoint}/api/sdk/approvals/${approvalId}/status`,\n {\n headers: {\n Authorization: `Bearer ${this.token}`,\n \"X-SDK-Version\": SDK_VERSION,\n },\n },\n );\n\n // 410 Gone means the hitl-burn constraint worked or timed out\n if (res.status === 410) {\n return finish(() => {\n console.log(\n \"\\n\\x1b[31m[Envault SDK] Resource Gone (Approval expired or already consumed by a replay attack).\\x1b[0m\",\n );\n reject(new Error(\"HitlApprovalGone\"));\n });\n }\n\n if (res.status === 403) {\n try {\n await res.json();\n } catch {\n // Ignore JSON parsing failures and fall back to generic 403 rejection.\n }\n return finish(() => {\n console.log(\n \"\\n\\x1b[31m[Envault SDK] Action Rejected by Human.\\x1b[0m\",\n );\n reject(new Error(\"HitlApprovalRejected\"));\n });\n }\n\n if (res.status === 200) {\n const result = await res.json();\n if (result?.status === \"rejected\") {\n return finish(() => {\n console.log(\n \"\\n\\x1b[31m[Envault SDK] Action Rejected by Human.\\x1b[0m\",\n );\n reject(new Error(\"HitlApprovalRejected\"));\n });\n }\n return finish(() => {\n console.log(\n \"\\n\\x1b[32m[Envault SDK] Approved. Resuming execution.\\x1b[0m\\n\",\n );\n resolve(result.payload);\n });\n }\n } catch {\n process.stdout.write(\"x\"); // Local network failure indicator\n }\n }, 3000); // 3-second cycle\n\n // Safety timeout matching the 15m TTL constraint\n const timeoutHandle = setTimeout(() => {\n finish(() => {\n console.log(\"\\n\\x1b[31m[Envault SDK] Polling timeout (15m).\\x1b[0m\");\n reject(new Error(\"HitlApprovalTimeout\"));\n });\n }, 15 * 60 * 1000);\n });\n }\n}\n","export const SDK_VERSION = \"1.0.3\";\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dinanathdash/envault-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Envault TypeScript SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"types": "./dist/agent-interceptor.d.ts",
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
|
-
"README.md"
|
|
16
|
+
"README.md",
|
|
17
|
+
"postinstall.js"
|
|
17
18
|
],
|
|
18
19
|
"exports": {
|
|
19
20
|
".": {
|
package/postinstall.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import readline from "node:readline/promises";
|
|
3
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
4
|
+
|
|
5
|
+
const prompt =
|
|
6
|
+
"Envault can use native OS notifications (macOS, Windows, Linux) to alert you when an AI agent requires human approval for a secure mutation. Would you like to install the optional native notification helpers? (y/N) ";
|
|
7
|
+
|
|
8
|
+
function isCiEnvironment() {
|
|
9
|
+
return Boolean(process.env.CI && process.env.CI.trim().length > 0);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function npmCommand() {
|
|
13
|
+
return process.platform === "win32" ? "npm.cmd" : "npm";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function main() {
|
|
17
|
+
if (isCiEnvironment()) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!process.stdout.isTTY || !process.stdin.isTTY) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const rl = readline.createInterface({ input, output });
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const answer = (await rl.question(prompt)).trim().toLowerCase();
|
|
29
|
+
if (answer !== "y" && answer !== "yes") {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
} finally {
|
|
33
|
+
rl.close();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const result = spawnSync(npmCommand(), ["install", "--no-save", "node-notifier@^10.0.1"], {
|
|
37
|
+
stdio: "inherit",
|
|
38
|
+
env: process.env,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (result.status !== 0) {
|
|
42
|
+
console.warn("[Envault SDK] Optional notifier helper install failed. Continue without native helper support.");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
void main();
|