zencefyl 0.2.5 → 0.2.7

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.
@@ -201,7 +201,9 @@ var MODEL_REGISTRY = [
201
201
  { id: "kimi-k1.5-long-context", label: "Kimi K1.5 (2M ctx)", provider: "moonshot" }
202
202
  ];
203
203
  var PROVIDER_LABELS = {
204
+ "claude-code": "Claude Code",
204
205
  "anthropic": "Anthropic",
206
+ "openai-compat": "OpenAI-Compatible",
205
207
  "openai-subscription": "OpenAI (subscription)",
206
208
  "gemini-subscription": "Gemini (subscription)",
207
209
  "ollama": "Ollama (local)",
@@ -221,4 +223,4 @@ export {
221
223
  MODEL_REGISTRY,
222
224
  PROVIDER_LABELS
223
225
  };
224
- //# sourceMappingURL=chunk-VGMBOH7B.js.map
226
+ //# sourceMappingURL=chunk-CZ4NCT3D.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants/models.ts"],"sourcesContent":["// Default model IDs and pricing constants.\n// Override model IDs in ~/.zencefyl/config.json — no code changes needed.\n//\n// Model IDs sourced from @mariozechner/pi-ai models.generated.js (subscription)\n// and official pricing pages (API key providers).\n\nimport type { ModelConfig } from '../types/config'\n\n// Fallback models used when config.json has no models section.\nexport const DEFAULT_MODELS: ModelConfig = {\n fast: 'claude-haiku-4-5-20251001', // Cheap + fast — background tasks\n default: 'claude-sonnet-4-6', // Main model for most turns\n deep: 'claude-opus-4-6', // Reserved for deep reasoning\n}\n\n// Default models for the local-transformers provider.\nexport const LOCAL_TRANSFORMERS_MODELS: ModelConfig = {\n fast: 'tinyllama', // 1.1B params, fast on CPU\n default: 'phi3-mini', // 3.8B params, good quality\n deep: 'stablelm2', // 1.6B params, better reasoning\n}\n\n// Context window sizes per model (input tokens).\n// Used to show a \"X / Y tokens\" budget indicator in the status bar.\nexport const MODEL_CONTEXT_WINDOW: Record<string, number> = {\n // Anthropic\n 'claude-haiku-4-5-20251001': 200_000,\n 'claude-sonnet-4-6': 200_000,\n 'claude-opus-4-6': 200_000,\n // OpenAI subscription (via ChatGPT plan — @mariozechner/pi-ai)\n // Context windows are approximate — Codex endpoint docs not fully public.\n 'gpt-5.4': 128_000,\n 'gpt-5.4-mini': 128_000,\n 'gpt-5.3-codex': 128_000,\n 'gpt-5.3-codex-spark': 128_000,\n 'gpt-5.2': 128_000,\n 'gpt-5.2-codex': 128_000,\n 'gpt-5.1': 128_000,\n 'gpt-5.1-codex-max': 128_000,\n 'gpt-5.1-codex-mini': 128_000,\n // Gemini subscription (via Google Cloud Code Assist — @mariozechner/pi-ai)\n 'gemini-3.1-pro-preview': 1_000_000,\n 'gemini-3-pro-preview': 1_000_000,\n 'gemini-3-flash-preview': 1_000_000,\n 'gemini-2.5-pro': 1_000_000,\n 'gemini-2.5-flash': 1_000_000,\n 'gemini-2.0-flash': 1_000_000,\n // Ollama local models (context varies — using typical defaults)\n 'gemma3': 128_000,\n 'gemma3:1b': 32_000,\n 'gemma3:12b': 128_000,\n 'llama3.2': 128_000,\n 'llama3.2:1b': 128_000,\n 'llama3.3': 128_000,\n 'mistral': 32_000,\n 'mistral-nemo': 128_000,\n 'phi4': 128_000,\n 'phi4-mini': 128_000,\n 'tinyllama': 4_096,\n 'qwen2.5': 128_000,\n 'qwen2.5:14b': 128_000,\n 'qwen2.5:72b': 128_000,\n 'deepseek-r1': 64_000,\n 'deepseek-r1:14b': 64_000,\n 'deepseek-r1:32b': 64_000,\n 'qwq': 128_000,\n 'codellama': 16_000,\n 'codellama:13b': 16_000,\n 'codegemma': 8_000,\n 'llava': 4_096,\n 'llava:13b': 4_096,\n // Local transformers models (approximate — varies by model)\n 'phi3-mini': 4_096,\n 'stablelm2': 4_096,\n 'gemma-2b': 8_192,\n // Moonshot (Kimi models)\n 'kimi-k2.5': 256_000,\n 'kimi-k1.5': 256_000,\n 'kimi-k1.5-long-context': 2_000_000,\n}\n\n// Cost per million tokens in USD.\n// Subscription providers (openai-subscription, gemini-subscription) are billed\n// through the plan itself — we track $0 here so StatusBar shows \"free\" for them.\nexport const MODEL_PRICING: Record<string, { inputPerM: number; outputPerM: number }> = {\n // Anthropic (source: anthropic.com/pricing)\n 'claude-haiku-4-5-20251001': { inputPerM: 0.80, outputPerM: 4.00 },\n 'claude-sonnet-4-6': { inputPerM: 3.00, outputPerM: 15.00 },\n 'claude-opus-4-6': { inputPerM: 15.00, outputPerM: 75.00 },\n // OpenAI subscription models — billed via ChatGPT plan, not per token\n 'gpt-5.4': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.4-mini': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.3-codex': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.3-codex-spark': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.2': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.2-codex': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.1': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.1-codex-max': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.1-codex-mini': { inputPerM: 0, outputPerM: 0 },\n // Gemini subscription models — billed via Google Cloud Code Assist plan, not per token\n 'gemini-3.1-pro-preview': { inputPerM: 0, outputPerM: 0 },\n 'gemini-3-pro-preview': { inputPerM: 0, outputPerM: 0 },\n 'gemini-3-flash-preview': { inputPerM: 0, outputPerM: 0 },\n 'gemini-2.5-pro': { inputPerM: 0, outputPerM: 0 },\n 'gemini-2.5-flash': { inputPerM: 0, outputPerM: 0 },\n 'gemini-2.0-flash': { inputPerM: 0, outputPerM: 0 },\n // Moonshot (Kimi) — approximate pricing (check platform.moonshot.cn for current rates)\n 'kimi-k2.5': { inputPerM: 2.00, outputPerM: 10.00 },\n 'kimi-k1.5': { inputPerM: 8.00, outputPerM: 32.00 },\n 'kimi-k1.5-long-context': { inputPerM: 4.00, outputPerM: 16.00 },\n // Local transformers models — $0 (runs locally, no API cost)\n 'tinyllama': { inputPerM: 0, outputPerM: 0 },\n 'phi3-mini': { inputPerM: 0, outputPerM: 0 },\n 'stablelm2': { inputPerM: 0, outputPerM: 0 },\n 'gemma-2b': { inputPerM: 0, outputPerM: 0 },\n}\n\n// ── Per-provider default model tiers ──────────────────────────────────────────\n\n// Default models for the ChatGPT OAuth subscription provider.\n// IDs must match what @mariozechner/pi-ai openai-codex provider recognises.\n// Valid IDs: gpt-5.1, gpt-5.1-codex-max, gpt-5.1-codex-mini, gpt-5.2,\n// gpt-5.2-codex, gpt-5.3-codex, gpt-5.3-codex-spark, gpt-5.4, gpt-5.4-mini\nexport const OPENAI_SUBSCRIPTION_MODELS: ModelConfig = {\n fast: 'gpt-5.4-mini', // smaller, faster tier\n default: 'gpt-5.4', // latest flagship\n deep: 'gpt-5.3-codex', // strong coding + reasoning\n}\n\n// Default models for the Gemini OAuth subscription provider.\nexport const GEMINI_SUBSCRIPTION_MODELS: ModelConfig = {\n fast: 'gemini-3-flash-preview', // Gemini 3 fast tier\n default: 'gemini-2.5-pro', // stable flagship\n deep: 'gemini-3.1-pro-preview', // latest strongest\n}\n\n// Default models for the Ollama provider.\nexport const OLLAMA_MODELS_DEFAULT: ModelConfig = {\n fast: 'gemma3:1b', // small + fast\n default: 'gemma3', // 4B — recommended general-purpose\n deep: 'qwen2.5', // 7B — stronger for complex tasks\n}\n\n// Default models for the Moonshot (Kimi) provider.\nexport const MOONSHOT_MODELS: ModelConfig = {\n fast: 'kimi-k2.5', // fastest, most cost-effective\n default: 'kimi-k2.5', // balanced — the model you're talking to now\n deep: 'kimi-k1.5', // strongest reasoning with thinking\n}\n\n// ── Model registry for the /model picker ──────────────────────────────────────\n\n// A model entry shown in the interactive /model picker.\nexport interface ModelEntry {\n id: string // model ID passed to provider.chat()\n label: string // human-readable display name\n provider: string // which provider it belongs to (for grouping)\n tier?: string // 'fast' | 'default' | 'deep' — optional badge\n size?: string // disk size hint shown in install wizard (e.g. '3.3 GB')\n}\n\n// All models surfaced in the /model picker, grouped by provider.\n// Subscription models marked with their subscription; Ollama entries are generic.\nexport const MODEL_REGISTRY: ModelEntry[] = [\n // ── Anthropic (claude-code or anthropic provider) ─────────────────────────\n { id: 'claude-sonnet-4-6', label: 'Claude Sonnet 4.6', provider: 'anthropic' },\n { id: 'claude-opus-4-6', label: 'Claude Opus 4.6', provider: 'anthropic' },\n { id: 'claude-haiku-4-5-20251001', label: 'Claude Haiku 4.5', provider: 'anthropic' },\n\n // ── OpenAI subscription (via ChatGPT plan — @mariozechner/pi-ai) ─────────\n // Model IDs must match what pi-ai's openai-codex provider recognises.\n { id: 'gpt-5.4', label: 'GPT-5.4', provider: 'openai-subscription', tier: 'default' },\n { id: 'gpt-5.4-mini', label: 'GPT-5.4 Mini', provider: 'openai-subscription', tier: 'fast' },\n { id: 'gpt-5.3-codex', label: 'GPT-5.3 Codex', provider: 'openai-subscription', tier: 'deep' },\n { id: 'gpt-5.3-codex-spark', label: 'GPT-5.3 Codex Spark', provider: 'openai-subscription' },\n { id: 'gpt-5.2-codex', label: 'GPT-5.2 Codex', provider: 'openai-subscription' },\n { id: 'gpt-5.2', label: 'GPT-5.2', provider: 'openai-subscription' },\n { id: 'gpt-5.1', label: 'GPT-5.1', provider: 'openai-subscription' },\n { id: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max', provider: 'openai-subscription' },\n { id: 'gpt-5.1-codex-mini', label: 'GPT-5.1 Codex Mini', provider: 'openai-subscription' },\n\n // ── Gemini subscription (via Google Cloud Code Assist — @mariozechner/pi-ai) ─\n // Model IDs from pi-ai's google-gemini-cli provider.\n { id: 'gemini-3.1-pro-preview', label: 'Gemini 3.1 Pro', provider: 'gemini-subscription', tier: 'deep' },\n { id: 'gemini-3-pro-preview', label: 'Gemini 3 Pro', provider: 'gemini-subscription' },\n { id: 'gemini-3-flash-preview', label: 'Gemini 3 Flash', provider: 'gemini-subscription', tier: 'fast' },\n { id: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro', provider: 'gemini-subscription', tier: 'default' },\n { id: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash', provider: 'gemini-subscription' },\n { id: 'gemini-2.0-flash', label: 'Gemini 2.0 Flash', provider: 'gemini-subscription' },\n\n // ── Ollama (local) — requires `ollama serve` ──────────────────────────────\n // Fast / small models (< 4 GB)\n { id: 'gemma3:1b', label: 'Gemma 3 1B', provider: 'ollama', tier: 'fast', size: '0.8 GB' },\n { id: 'llama3.2:1b', label: 'Llama 3.2 1B', provider: 'ollama', tier: 'fast', size: '1.3 GB' },\n { id: 'phi4-mini', label: 'Phi 4 Mini', provider: 'ollama', tier: 'fast', size: '2.5 GB' },\n { id: 'tinyllama', label: 'TinyLlama 1.1B', provider: 'ollama', tier: 'fast', size: '0.6 GB' },\n // Balanced models (2–8 GB) — recommended for daily use\n { id: 'gemma3', label: 'Gemma 3 4B', provider: 'ollama', tier: 'default', size: '3.3 GB' },\n { id: 'gemma3:12b', label: 'Gemma 3 12B', provider: 'ollama', size: '8.1 GB' },\n { id: 'llama3.2', label: 'Llama 3.2 3B', provider: 'ollama', tier: 'default', size: '2.0 GB' },\n { id: 'llama3.3', label: 'Llama 3.3 70B', provider: 'ollama', tier: 'deep', size: '43 GB' },\n { id: 'mistral', label: 'Mistral 7B', provider: 'ollama', size: '4.1 GB' },\n { id: 'mistral-nemo', label: 'Mistral Nemo 12B', provider: 'ollama', size: '7.1 GB' },\n { id: 'phi4', label: 'Phi 4 14B', provider: 'ollama', size: '9.1 GB' },\n { id: 'qwen2.5', label: 'Qwen 2.5 7B', provider: 'ollama', tier: 'default', size: '4.7 GB' },\n { id: 'qwen2.5:14b', label: 'Qwen 2.5 14B', provider: 'ollama', size: '9.0 GB' },\n { id: 'qwen2.5:72b', label: 'Qwen 2.5 72B', provider: 'ollama', tier: 'deep', size: '47 GB' },\n // Reasoning models\n { id: 'deepseek-r1', label: 'DeepSeek R1 7B', provider: 'ollama', size: '4.7 GB' },\n { id: 'deepseek-r1:14b', label: 'DeepSeek R1 14B', provider: 'ollama', size: '9.0 GB' },\n { id: 'deepseek-r1:32b', label: 'DeepSeek R1 32B', provider: 'ollama', tier: 'deep', size: '20 GB' },\n { id: 'qwq', label: 'QwQ 32B (reasoning)', provider: 'ollama', tier: 'deep', size: '20 GB' },\n // Code models\n { id: 'codellama', label: 'CodeLlama 7B', provider: 'ollama', size: '3.8 GB' },\n { id: 'codellama:13b', label: 'CodeLlama 13B', provider: 'ollama', size: '7.4 GB' },\n { id: 'codegemma', label: 'CodeGemma 7B', provider: 'ollama', size: '5.0 GB' },\n // Multimodal\n { id: 'llava', label: 'LLaVA 7B (vision)', provider: 'ollama', size: '4.5 GB' },\n { id: 'llava:13b', label: 'LLaVA 13B (vision)', provider: 'ollama', size: '8.0 GB' },\n\n // ── Local Transformers (fully local, no external deps) ───────────────────\n { id: 'tinyllama', label: 'TinyLlama 1.1B', provider: 'local-transformers', tier: 'fast' },\n { id: 'phi3-mini', label: 'Phi-3 Mini 3.8B', provider: 'local-transformers', tier: 'default' },\n { id: 'stablelm2', label: 'StableLM 2 Zephyr 1.6B', provider: 'local-transformers', tier: 'default' },\n { id: 'gemma-2b', label: 'Gemma 2B Instruct', provider: 'local-transformers', tier: 'fast' },\n\n // ── Moonshot (Kimi) ─────────────────────────────────────────────────────────\n { id: 'kimi-k2.5', label: 'Kimi K2.5', provider: 'moonshot' },\n { id: 'kimi-k1.5', label: 'Kimi K1.5', provider: 'moonshot' },\n { id: 'kimi-k1.5-long-context', label: 'Kimi K1.5 (2M ctx)', provider: 'moonshot' },\n]\n\n// Provider display names for the picker's group headers.\nexport const PROVIDER_LABELS: Record<string, string> = {\n 'anthropic': 'Anthropic',\n 'openai-subscription': 'OpenAI (subscription)',\n 'gemini-subscription': 'Gemini (subscription)',\n 'ollama': 'Ollama (local)',\n 'local-transformers': 'Local Models (transformers.js)',\n 'moonshot': 'Moonshot (Kimi)',\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/constants/models.ts"],"sourcesContent":["// Default model IDs and pricing constants.\n// Override model IDs in ~/.zencefyl/config.json — no code changes needed.\n//\n// Model IDs sourced from @mariozechner/pi-ai models.generated.js (subscription)\n// and official pricing pages (API key providers).\n\nimport type { ModelConfig } from '../types/config'\n\n// Fallback models used when config.json has no models section.\nexport const DEFAULT_MODELS: ModelConfig = {\n fast: 'claude-haiku-4-5-20251001', // Cheap + fast — background tasks\n default: 'claude-sonnet-4-6', // Main model for most turns\n deep: 'claude-opus-4-6', // Reserved for deep reasoning\n}\n\n// Default models for the local-transformers provider.\nexport const LOCAL_TRANSFORMERS_MODELS: ModelConfig = {\n fast: 'tinyllama', // 1.1B params, fast on CPU\n default: 'phi3-mini', // 3.8B params, good quality\n deep: 'stablelm2', // 1.6B params, better reasoning\n}\n\n// Context window sizes per model (input tokens).\n// Used to show a \"X / Y tokens\" budget indicator in the status bar.\nexport const MODEL_CONTEXT_WINDOW: Record<string, number> = {\n // Anthropic\n 'claude-haiku-4-5-20251001': 200_000,\n 'claude-sonnet-4-6': 200_000,\n 'claude-opus-4-6': 200_000,\n // OpenAI subscription (via ChatGPT plan — @mariozechner/pi-ai)\n // Context windows are approximate — Codex endpoint docs not fully public.\n 'gpt-5.4': 128_000,\n 'gpt-5.4-mini': 128_000,\n 'gpt-5.3-codex': 128_000,\n 'gpt-5.3-codex-spark': 128_000,\n 'gpt-5.2': 128_000,\n 'gpt-5.2-codex': 128_000,\n 'gpt-5.1': 128_000,\n 'gpt-5.1-codex-max': 128_000,\n 'gpt-5.1-codex-mini': 128_000,\n // Gemini subscription (via Google Cloud Code Assist — @mariozechner/pi-ai)\n 'gemini-3.1-pro-preview': 1_000_000,\n 'gemini-3-pro-preview': 1_000_000,\n 'gemini-3-flash-preview': 1_000_000,\n 'gemini-2.5-pro': 1_000_000,\n 'gemini-2.5-flash': 1_000_000,\n 'gemini-2.0-flash': 1_000_000,\n // Ollama local models (context varies — using typical defaults)\n 'gemma3': 128_000,\n 'gemma3:1b': 32_000,\n 'gemma3:12b': 128_000,\n 'llama3.2': 128_000,\n 'llama3.2:1b': 128_000,\n 'llama3.3': 128_000,\n 'mistral': 32_000,\n 'mistral-nemo': 128_000,\n 'phi4': 128_000,\n 'phi4-mini': 128_000,\n 'tinyllama': 4_096,\n 'qwen2.5': 128_000,\n 'qwen2.5:14b': 128_000,\n 'qwen2.5:72b': 128_000,\n 'deepseek-r1': 64_000,\n 'deepseek-r1:14b': 64_000,\n 'deepseek-r1:32b': 64_000,\n 'qwq': 128_000,\n 'codellama': 16_000,\n 'codellama:13b': 16_000,\n 'codegemma': 8_000,\n 'llava': 4_096,\n 'llava:13b': 4_096,\n // Local transformers models (approximate — varies by model)\n 'phi3-mini': 4_096,\n 'stablelm2': 4_096,\n 'gemma-2b': 8_192,\n // Moonshot (Kimi models)\n 'kimi-k2.5': 256_000,\n 'kimi-k1.5': 256_000,\n 'kimi-k1.5-long-context': 2_000_000,\n}\n\n// Cost per million tokens in USD.\n// Subscription providers (openai-subscription, gemini-subscription) are billed\n// through the plan itself — we track $0 here so StatusBar shows \"free\" for them.\nexport const MODEL_PRICING: Record<string, { inputPerM: number; outputPerM: number }> = {\n // Anthropic (source: anthropic.com/pricing)\n 'claude-haiku-4-5-20251001': { inputPerM: 0.80, outputPerM: 4.00 },\n 'claude-sonnet-4-6': { inputPerM: 3.00, outputPerM: 15.00 },\n 'claude-opus-4-6': { inputPerM: 15.00, outputPerM: 75.00 },\n // OpenAI subscription models — billed via ChatGPT plan, not per token\n 'gpt-5.4': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.4-mini': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.3-codex': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.3-codex-spark': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.2': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.2-codex': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.1': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.1-codex-max': { inputPerM: 0, outputPerM: 0 },\n 'gpt-5.1-codex-mini': { inputPerM: 0, outputPerM: 0 },\n // Gemini subscription models — billed via Google Cloud Code Assist plan, not per token\n 'gemini-3.1-pro-preview': { inputPerM: 0, outputPerM: 0 },\n 'gemini-3-pro-preview': { inputPerM: 0, outputPerM: 0 },\n 'gemini-3-flash-preview': { inputPerM: 0, outputPerM: 0 },\n 'gemini-2.5-pro': { inputPerM: 0, outputPerM: 0 },\n 'gemini-2.5-flash': { inputPerM: 0, outputPerM: 0 },\n 'gemini-2.0-flash': { inputPerM: 0, outputPerM: 0 },\n // Moonshot (Kimi) — approximate pricing (check platform.moonshot.cn for current rates)\n 'kimi-k2.5': { inputPerM: 2.00, outputPerM: 10.00 },\n 'kimi-k1.5': { inputPerM: 8.00, outputPerM: 32.00 },\n 'kimi-k1.5-long-context': { inputPerM: 4.00, outputPerM: 16.00 },\n // Local transformers models — $0 (runs locally, no API cost)\n 'tinyllama': { inputPerM: 0, outputPerM: 0 },\n 'phi3-mini': { inputPerM: 0, outputPerM: 0 },\n 'stablelm2': { inputPerM: 0, outputPerM: 0 },\n 'gemma-2b': { inputPerM: 0, outputPerM: 0 },\n}\n\n// ── Per-provider default model tiers ──────────────────────────────────────────\n\n// Default models for the ChatGPT OAuth subscription provider.\n// IDs must match what @mariozechner/pi-ai openai-codex provider recognises.\n// Valid IDs: gpt-5.1, gpt-5.1-codex-max, gpt-5.1-codex-mini, gpt-5.2,\n// gpt-5.2-codex, gpt-5.3-codex, gpt-5.3-codex-spark, gpt-5.4, gpt-5.4-mini\nexport const OPENAI_SUBSCRIPTION_MODELS: ModelConfig = {\n fast: 'gpt-5.4-mini', // smaller, faster tier\n default: 'gpt-5.4', // latest flagship\n deep: 'gpt-5.3-codex', // strong coding + reasoning\n}\n\n// Default models for the Gemini OAuth subscription provider.\nexport const GEMINI_SUBSCRIPTION_MODELS: ModelConfig = {\n fast: 'gemini-3-flash-preview', // Gemini 3 fast tier\n default: 'gemini-2.5-pro', // stable flagship\n deep: 'gemini-3.1-pro-preview', // latest strongest\n}\n\n// Default models for the Ollama provider.\nexport const OLLAMA_MODELS_DEFAULT: ModelConfig = {\n fast: 'gemma3:1b', // small + fast\n default: 'gemma3', // 4B — recommended general-purpose\n deep: 'qwen2.5', // 7B — stronger for complex tasks\n}\n\n// Default models for the Moonshot (Kimi) provider.\nexport const MOONSHOT_MODELS: ModelConfig = {\n fast: 'kimi-k2.5', // fastest, most cost-effective\n default: 'kimi-k2.5', // balanced — the model you're talking to now\n deep: 'kimi-k1.5', // strongest reasoning with thinking\n}\n\n// ── Model registry for the /model picker ──────────────────────────────────────\n\n// A model entry shown in the interactive /model picker.\nexport interface ModelEntry {\n id: string // model ID passed to provider.chat()\n label: string // human-readable display name\n provider: string // which provider it belongs to (for grouping)\n tier?: string // 'fast' | 'default' | 'deep' — optional badge\n size?: string // disk size hint shown in install wizard (e.g. '3.3 GB')\n}\n\n// All models surfaced in the /model picker, grouped by provider.\n// Subscription models marked with their subscription; Ollama entries are generic.\nexport const MODEL_REGISTRY: ModelEntry[] = [\n // ── Anthropic (claude-code or anthropic provider) ─────────────────────────\n { id: 'claude-sonnet-4-6', label: 'Claude Sonnet 4.6', provider: 'anthropic' },\n { id: 'claude-opus-4-6', label: 'Claude Opus 4.6', provider: 'anthropic' },\n { id: 'claude-haiku-4-5-20251001', label: 'Claude Haiku 4.5', provider: 'anthropic' },\n\n // ── OpenAI subscription (via ChatGPT plan — @mariozechner/pi-ai) ─────────\n // Model IDs must match what pi-ai's openai-codex provider recognises.\n { id: 'gpt-5.4', label: 'GPT-5.4', provider: 'openai-subscription', tier: 'default' },\n { id: 'gpt-5.4-mini', label: 'GPT-5.4 Mini', provider: 'openai-subscription', tier: 'fast' },\n { id: 'gpt-5.3-codex', label: 'GPT-5.3 Codex', provider: 'openai-subscription', tier: 'deep' },\n { id: 'gpt-5.3-codex-spark', label: 'GPT-5.3 Codex Spark', provider: 'openai-subscription' },\n { id: 'gpt-5.2-codex', label: 'GPT-5.2 Codex', provider: 'openai-subscription' },\n { id: 'gpt-5.2', label: 'GPT-5.2', provider: 'openai-subscription' },\n { id: 'gpt-5.1', label: 'GPT-5.1', provider: 'openai-subscription' },\n { id: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max', provider: 'openai-subscription' },\n { id: 'gpt-5.1-codex-mini', label: 'GPT-5.1 Codex Mini', provider: 'openai-subscription' },\n\n // ── Gemini subscription (via Google Cloud Code Assist — @mariozechner/pi-ai) ─\n // Model IDs from pi-ai's google-gemini-cli provider.\n { id: 'gemini-3.1-pro-preview', label: 'Gemini 3.1 Pro', provider: 'gemini-subscription', tier: 'deep' },\n { id: 'gemini-3-pro-preview', label: 'Gemini 3 Pro', provider: 'gemini-subscription' },\n { id: 'gemini-3-flash-preview', label: 'Gemini 3 Flash', provider: 'gemini-subscription', tier: 'fast' },\n { id: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro', provider: 'gemini-subscription', tier: 'default' },\n { id: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash', provider: 'gemini-subscription' },\n { id: 'gemini-2.0-flash', label: 'Gemini 2.0 Flash', provider: 'gemini-subscription' },\n\n // ── Ollama (local) — requires `ollama serve` ──────────────────────────────\n // Fast / small models (< 4 GB)\n { id: 'gemma3:1b', label: 'Gemma 3 1B', provider: 'ollama', tier: 'fast', size: '0.8 GB' },\n { id: 'llama3.2:1b', label: 'Llama 3.2 1B', provider: 'ollama', tier: 'fast', size: '1.3 GB' },\n { id: 'phi4-mini', label: 'Phi 4 Mini', provider: 'ollama', tier: 'fast', size: '2.5 GB' },\n { id: 'tinyllama', label: 'TinyLlama 1.1B', provider: 'ollama', tier: 'fast', size: '0.6 GB' },\n // Balanced models (2–8 GB) — recommended for daily use\n { id: 'gemma3', label: 'Gemma 3 4B', provider: 'ollama', tier: 'default', size: '3.3 GB' },\n { id: 'gemma3:12b', label: 'Gemma 3 12B', provider: 'ollama', size: '8.1 GB' },\n { id: 'llama3.2', label: 'Llama 3.2 3B', provider: 'ollama', tier: 'default', size: '2.0 GB' },\n { id: 'llama3.3', label: 'Llama 3.3 70B', provider: 'ollama', tier: 'deep', size: '43 GB' },\n { id: 'mistral', label: 'Mistral 7B', provider: 'ollama', size: '4.1 GB' },\n { id: 'mistral-nemo', label: 'Mistral Nemo 12B', provider: 'ollama', size: '7.1 GB' },\n { id: 'phi4', label: 'Phi 4 14B', provider: 'ollama', size: '9.1 GB' },\n { id: 'qwen2.5', label: 'Qwen 2.5 7B', provider: 'ollama', tier: 'default', size: '4.7 GB' },\n { id: 'qwen2.5:14b', label: 'Qwen 2.5 14B', provider: 'ollama', size: '9.0 GB' },\n { id: 'qwen2.5:72b', label: 'Qwen 2.5 72B', provider: 'ollama', tier: 'deep', size: '47 GB' },\n // Reasoning models\n { id: 'deepseek-r1', label: 'DeepSeek R1 7B', provider: 'ollama', size: '4.7 GB' },\n { id: 'deepseek-r1:14b', label: 'DeepSeek R1 14B', provider: 'ollama', size: '9.0 GB' },\n { id: 'deepseek-r1:32b', label: 'DeepSeek R1 32B', provider: 'ollama', tier: 'deep', size: '20 GB' },\n { id: 'qwq', label: 'QwQ 32B (reasoning)', provider: 'ollama', tier: 'deep', size: '20 GB' },\n // Code models\n { id: 'codellama', label: 'CodeLlama 7B', provider: 'ollama', size: '3.8 GB' },\n { id: 'codellama:13b', label: 'CodeLlama 13B', provider: 'ollama', size: '7.4 GB' },\n { id: 'codegemma', label: 'CodeGemma 7B', provider: 'ollama', size: '5.0 GB' },\n // Multimodal\n { id: 'llava', label: 'LLaVA 7B (vision)', provider: 'ollama', size: '4.5 GB' },\n { id: 'llava:13b', label: 'LLaVA 13B (vision)', provider: 'ollama', size: '8.0 GB' },\n\n // ── Local Transformers (fully local, no external deps) ───────────────────\n { id: 'tinyllama', label: 'TinyLlama 1.1B', provider: 'local-transformers', tier: 'fast' },\n { id: 'phi3-mini', label: 'Phi-3 Mini 3.8B', provider: 'local-transformers', tier: 'default' },\n { id: 'stablelm2', label: 'StableLM 2 Zephyr 1.6B', provider: 'local-transformers', tier: 'default' },\n { id: 'gemma-2b', label: 'Gemma 2B Instruct', provider: 'local-transformers', tier: 'fast' },\n\n // ── Moonshot (Kimi) ─────────────────────────────────────────────────────────\n { id: 'kimi-k2.5', label: 'Kimi K2.5', provider: 'moonshot' },\n { id: 'kimi-k1.5', label: 'Kimi K1.5', provider: 'moonshot' },\n { id: 'kimi-k1.5-long-context', label: 'Kimi K1.5 (2M ctx)', provider: 'moonshot' },\n]\n\n// Provider display names for the picker's group headers.\nexport const PROVIDER_LABELS: Record<string, string> = {\n 'claude-code': 'Claude Code',\n 'anthropic': 'Anthropic',\n 'openai-compat': 'OpenAI-Compatible',\n 'openai-subscription': 'OpenAI (subscription)',\n 'gemini-subscription': 'Gemini (subscription)',\n 'ollama': 'Ollama (local)',\n 'local-transformers': 'Local Models (transformers.js)',\n 'moonshot': 'Moonshot (Kimi)',\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,283 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/auth/credentials.ts
4
+ import fs from "fs";
5
+ import path from "path";
6
+ import os from "os";
7
+ var GOOGLE_CODE_ASSIST_ENDPOINT = "https://cloudcode-pa.googleapis.com";
8
+ var GOOGLE_TIER_FREE = "free-tier";
9
+ var GOOGLE_TIER_LEGACY = "legacy-tier";
10
+ var GOOGLE_TIER_STANDARD = "standard-tier";
11
+ function credentialsPath(dataDir) {
12
+ return path.join(dataDir, "credentials.json");
13
+ }
14
+ function loadCredentials(dataDir) {
15
+ const p = credentialsPath(dataDir);
16
+ if (!fs.existsSync(p)) return {};
17
+ try {
18
+ return JSON.parse(fs.readFileSync(p, "utf8"));
19
+ } catch {
20
+ return {};
21
+ }
22
+ }
23
+ function saveCredentials(dataDir, store) {
24
+ fs.writeFileSync(credentialsPath(dataDir), JSON.stringify(store, null, 2), "utf8");
25
+ }
26
+ function saveProviderCredentials(dataDir, providerId, creds) {
27
+ const store = loadCredentials(dataDir);
28
+ store[providerId] = creds;
29
+ saveCredentials(dataDir, store);
30
+ }
31
+ function decodeJwtExpiryMs(token) {
32
+ const parts = token.split(".");
33
+ if (parts.length < 2) return null;
34
+ try {
35
+ const payloadRaw = Buffer.from(parts[1] ?? "", "base64url").toString("utf8");
36
+ const payload = JSON.parse(payloadRaw);
37
+ return typeof payload.exp === "number" && Number.isFinite(payload.exp) && payload.exp > 0 ? payload.exp * 1e3 : null;
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+ function resolveCodexCliAuthPath() {
43
+ const codexHome = process.env["CODEX_HOME"] ? path.resolve(process.env["CODEX_HOME"]) : path.join(os.homedir(), ".codex");
44
+ return path.join(codexHome, "auth.json");
45
+ }
46
+ function loadCodexCliCredentials() {
47
+ const authPath = resolveCodexCliAuthPath();
48
+ if (!fs.existsSync(authPath)) return null;
49
+ try {
50
+ const raw = JSON.parse(fs.readFileSync(authPath, "utf8"));
51
+ const tokens = raw["tokens"];
52
+ if (!tokens || typeof tokens !== "object") return null;
53
+ const record = tokens;
54
+ const access = record["access_token"];
55
+ const refresh = record["refresh_token"];
56
+ if (typeof access !== "string" || !access || typeof refresh !== "string" || !refresh) {
57
+ return null;
58
+ }
59
+ let fallbackExpiry = Date.now() + 60 * 60 * 1e3;
60
+ try {
61
+ fallbackExpiry = fs.statSync(authPath).mtimeMs + 60 * 60 * 1e3;
62
+ } catch {
63
+ }
64
+ return {
65
+ access,
66
+ refresh,
67
+ expires: decodeJwtExpiryMs(access) ?? fallbackExpiry,
68
+ ...typeof record["account_id"] === "string" ? { accountId: record["account_id"] } : {}
69
+ };
70
+ } catch {
71
+ return null;
72
+ }
73
+ }
74
+ function resolveGeminiProjectId(value) {
75
+ const projectId = value ?? process.env["GOOGLE_CLOUD_PROJECT"] ?? process.env["GOOGLE_CLOUD_PROJECT_ID"] ?? process.env["GCLOUD_PROJECT"] ?? loadGcloudConfiguredProjectId() ?? null;
76
+ return typeof projectId === "string" && projectId.trim() ? projectId.trim() : null;
77
+ }
78
+ function gcloudConfigDir() {
79
+ return path.join(os.homedir(), ".config", "gcloud");
80
+ }
81
+ function parseIniValue(contents, section, key) {
82
+ let currentSection = "";
83
+ for (const rawLine of contents.split(/\r?\n/)) {
84
+ const line = rawLine.trim();
85
+ if (!line || line.startsWith("#") || line.startsWith(";")) continue;
86
+ const sectionMatch = line.match(/^\[(.+)\]$/);
87
+ if (sectionMatch) {
88
+ currentSection = sectionMatch[1] ?? "";
89
+ continue;
90
+ }
91
+ if (currentSection !== section) continue;
92
+ const valueMatch = line.match(/^([^=]+?)\s*=\s*(.+)$/);
93
+ if (!valueMatch) continue;
94
+ if (valueMatch[1]?.trim() !== key) continue;
95
+ const value = valueMatch[2]?.trim() ?? "";
96
+ return value || null;
97
+ }
98
+ return null;
99
+ }
100
+ function loadGcloudConfiguredProjectId() {
101
+ const gcloudDir = gcloudConfigDir();
102
+ const activeConfigPath = path.join(gcloudDir, "active_config");
103
+ let activeConfig = "default";
104
+ try {
105
+ if (fs.existsSync(activeConfigPath)) {
106
+ activeConfig = fs.readFileSync(activeConfigPath, "utf8").trim() || "default";
107
+ }
108
+ } catch {
109
+ }
110
+ const configPath = path.join(gcloudDir, "configurations", `config_${activeConfig}`);
111
+ if (!fs.existsSync(configPath)) return null;
112
+ try {
113
+ return parseIniValue(fs.readFileSync(configPath, "utf8"), "core", "project");
114
+ } catch {
115
+ return null;
116
+ }
117
+ }
118
+ function isVpcScAffected(payload) {
119
+ if (!payload || typeof payload !== "object") return false;
120
+ const error = payload.error;
121
+ if (!error || typeof error !== "object") return false;
122
+ const details = error.details;
123
+ if (!Array.isArray(details)) return false;
124
+ return details.some(
125
+ (item) => typeof item === "object" && item !== null && item.reason === "SECURITY_POLICY_VIOLATED"
126
+ );
127
+ }
128
+ function getDefaultGeminiTier(allowedTiers) {
129
+ if (!allowedTiers?.length) return { id: GOOGLE_TIER_LEGACY };
130
+ return allowedTiers.find((tier) => tier.isDefault) ?? { id: GOOGLE_TIER_LEGACY };
131
+ }
132
+ async function wait(ms) {
133
+ await new Promise((resolve) => setTimeout(resolve, ms));
134
+ }
135
+ async function pollGeminiProjectOperation(operationName, headers) {
136
+ for (let attempt = 0; attempt < 24; attempt += 1) {
137
+ if (attempt > 0) await wait(5e3);
138
+ const response = await fetch(`${GOOGLE_CODE_ASSIST_ENDPOINT}/v1internal/${operationName}`, {
139
+ method: "GET",
140
+ headers
141
+ });
142
+ if (!response.ok) {
143
+ throw new Error(`Failed to poll Gemini project provisioning: ${response.status} ${response.statusText}`);
144
+ }
145
+ const data = await response.json();
146
+ if (data.done) return data;
147
+ }
148
+ throw new Error("Timed out while waiting for Gemini project provisioning");
149
+ }
150
+ async function discoverGeminiProjectIdWithAccessToken(accessToken) {
151
+ const envProjectId = resolveGeminiProjectId();
152
+ const headers = {
153
+ Authorization: `Bearer ${accessToken}`,
154
+ "Content-Type": "application/json",
155
+ "User-Agent": "google-api-nodejs-client/9.15.1",
156
+ "X-Goog-Api-Client": `gl-node/${process.versions.node}`
157
+ };
158
+ const loadBody = {
159
+ ...envProjectId ? { cloudaicompanionProject: envProjectId } : {},
160
+ metadata: {
161
+ ideType: "IDE_UNSPECIFIED",
162
+ platform: "PLATFORM_UNSPECIFIED",
163
+ pluginType: "GEMINI",
164
+ ...envProjectId ? { duetProject: envProjectId } : {}
165
+ }
166
+ };
167
+ const loadResponse = await fetch(`${GOOGLE_CODE_ASSIST_ENDPOINT}/v1internal:loadCodeAssist`, {
168
+ method: "POST",
169
+ headers,
170
+ body: JSON.stringify(loadBody)
171
+ });
172
+ let data;
173
+ if (!loadResponse.ok) {
174
+ let payload = null;
175
+ try {
176
+ payload = await loadResponse.clone().json();
177
+ } catch {
178
+ payload = null;
179
+ }
180
+ if (isVpcScAffected(payload)) {
181
+ data = { currentTier: { id: GOOGLE_TIER_STANDARD } };
182
+ } else {
183
+ const text = await loadResponse.text();
184
+ throw new Error(`Gemini loadCodeAssist failed: ${loadResponse.status} ${loadResponse.statusText}${text ? `: ${text}` : ""}`);
185
+ }
186
+ } else {
187
+ data = await loadResponse.json();
188
+ }
189
+ if (data.currentTier) {
190
+ const project = data.cloudaicompanionProject;
191
+ if (typeof project === "string" && project.trim()) return project.trim();
192
+ if (typeof project === "object" && typeof project?.id === "string" && project.id.trim()) return project.id.trim();
193
+ if (envProjectId) return envProjectId;
194
+ throw new Error(
195
+ "This Gemini account requires GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_PROJECT_ID, or an active gcloud project."
196
+ );
197
+ }
198
+ const tierId = getDefaultGeminiTier(data.allowedTiers).id ?? GOOGLE_TIER_FREE;
199
+ if (tierId !== GOOGLE_TIER_FREE && !envProjectId) {
200
+ throw new Error(
201
+ "This Gemini account requires GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_PROJECT_ID, or an active gcloud project."
202
+ );
203
+ }
204
+ const onboardBody = {
205
+ tierId,
206
+ metadata: {
207
+ ideType: "IDE_UNSPECIFIED",
208
+ platform: "PLATFORM_UNSPECIFIED",
209
+ pluginType: "GEMINI"
210
+ }
211
+ };
212
+ if (tierId !== GOOGLE_TIER_FREE && envProjectId) {
213
+ onboardBody["cloudaicompanionProject"] = envProjectId;
214
+ onboardBody["metadata"]["duetProject"] = envProjectId;
215
+ }
216
+ const onboardResponse = await fetch(`${GOOGLE_CODE_ASSIST_ENDPOINT}/v1internal:onboardUser`, {
217
+ method: "POST",
218
+ headers,
219
+ body: JSON.stringify(onboardBody)
220
+ });
221
+ if (!onboardResponse.ok) {
222
+ const text = await onboardResponse.text();
223
+ throw new Error(`Gemini onboardUser failed: ${onboardResponse.status} ${onboardResponse.statusText}${text ? `: ${text}` : ""}`);
224
+ }
225
+ let operation = await onboardResponse.json();
226
+ if (!operation.done && operation.name) {
227
+ operation = await pollGeminiProjectOperation(operation.name, headers);
228
+ }
229
+ const projectId = operation.response?.cloudaicompanionProject?.id;
230
+ if (typeof projectId === "string" && projectId.trim()) return projectId.trim();
231
+ if (envProjectId) return envProjectId;
232
+ throw new Error(
233
+ "Could not discover or provision a Gemini Code Assist project. Set GOOGLE_CLOUD_PROJECT or select a gcloud project."
234
+ );
235
+ }
236
+ async function ensureGeminiProjectId(accessToken, value) {
237
+ const existing = resolveGeminiProjectId(value);
238
+ if (existing) return existing;
239
+ return await discoverGeminiProjectIdWithAccessToken(accessToken);
240
+ }
241
+ var REFRESH_BUFFER_MS = 6e4;
242
+ function isExpired(creds) {
243
+ return Date.now() >= creds.expires - REFRESH_BUFFER_MS;
244
+ }
245
+ async function getAccessToken(dataDir, providerId) {
246
+ const store = loadCredentials(dataDir);
247
+ const creds = store[providerId];
248
+ if (!creds) {
249
+ throw new Error(
250
+ `No credentials for ${providerId}. Run zencefyl setup and choose the subscription option.`
251
+ );
252
+ }
253
+ if (!isExpired(creds)) {
254
+ return creds.access;
255
+ }
256
+ let refreshed;
257
+ if (providerId === "openai-subscription") {
258
+ const { refreshOpenAICodexToken } = await import("@mariozechner/pi-ai/oauth");
259
+ refreshed = await refreshOpenAICodexToken(creds.refresh);
260
+ } else {
261
+ const { refreshGoogleCloudToken } = await import("@mariozechner/pi-ai/oauth");
262
+ const projectId = await ensureGeminiProjectId(
263
+ creds.access,
264
+ creds.projectId ?? null
265
+ );
266
+ refreshed = await refreshGoogleCloudToken(creds.refresh, projectId);
267
+ refreshed.projectId = projectId;
268
+ }
269
+ saveProviderCredentials(dataDir, providerId, refreshed);
270
+ return refreshed.access;
271
+ }
272
+
273
+ export {
274
+ credentialsPath,
275
+ loadCredentials,
276
+ saveCredentials,
277
+ saveProviderCredentials,
278
+ loadCodexCliCredentials,
279
+ resolveGeminiProjectId,
280
+ ensureGeminiProjectId,
281
+ getAccessToken
282
+ };
283
+ //# sourceMappingURL=chunk-JZA53FAX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth/credentials.ts"],"sourcesContent":["// Credential storage and refresh for OAuth providers.\n//\n// Credentials are stored in ~/.zencefyl/credentials.json — separate from\n// config.json so they are never accidentally committed to git.\n//\n// Structure:\n// {\n// \"openai-subscription\": { access: \"...\", refresh: \"...\", expires: 1234567890 },\n// \"gemini-subscription\": { access: \"...\", refresh: \"...\", expires: 1234567890, projectId: \"...\" }\n// }\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport type { OAuthCredentials } from '@mariozechner/pi-ai/oauth'\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type ProviderId = 'openai-subscription' | 'gemini-subscription'\n\n// Gemini credentials carry a projectId needed by refreshGoogleCloudToken.\nexport type GeminiCredentials = OAuthCredentials & { projectId?: string }\n\ntype CredentialsStore = {\n 'openai-subscription'?: OAuthCredentials\n 'gemini-subscription'?: GeminiCredentials\n}\n\ntype CodexCliAuth = OAuthCredentials & { accountId?: string }\n\nconst GOOGLE_USERINFO_URL = 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json'\nconst GOOGLE_CODE_ASSIST_ENDPOINT = 'https://cloudcode-pa.googleapis.com'\nconst GOOGLE_TIER_FREE = 'free-tier'\nconst GOOGLE_TIER_LEGACY = 'legacy-tier'\nconst GOOGLE_TIER_STANDARD = 'standard-tier'\n\n// ── File path ─────────────────────────────────────────────────────────────────\n\nexport function credentialsPath(dataDir: string): string {\n return path.join(dataDir, 'credentials.json')\n}\n\n// ── Load / Save ───────────────────────────────────────────────────────────────\n\nexport function loadCredentials(dataDir: string): CredentialsStore {\n const p = credentialsPath(dataDir)\n if (!fs.existsSync(p)) return {}\n try {\n return JSON.parse(fs.readFileSync(p, 'utf8')) as CredentialsStore\n } catch {\n return {}\n }\n}\n\nexport function saveCredentials(dataDir: string, store: CredentialsStore): void {\n fs.writeFileSync(credentialsPath(dataDir), JSON.stringify(store, null, 2), 'utf8')\n}\n\nexport function saveProviderCredentials(\n dataDir: string,\n providerId: ProviderId,\n creds: OAuthCredentials | GeminiCredentials,\n): void {\n const store = loadCredentials(dataDir)\n store[providerId] = creds as GeminiCredentials\n saveCredentials(dataDir, store)\n}\n\nfunction decodeJwtExpiryMs(token: string): number | null {\n const parts = token.split('.')\n if (parts.length < 2) return null\n\n try {\n const payloadRaw = Buffer.from(parts[1] ?? '', 'base64url').toString('utf8')\n const payload = JSON.parse(payloadRaw) as { exp?: unknown }\n return typeof payload.exp === 'number' && Number.isFinite(payload.exp) && payload.exp > 0\n ? payload.exp * 1000\n : null\n } catch {\n return null\n }\n}\n\nfunction resolveCodexCliAuthPath(): string {\n const codexHome = process.env['CODEX_HOME']\n ? path.resolve(process.env['CODEX_HOME'])\n : path.join(os.homedir(), '.codex')\n\n return path.join(codexHome, 'auth.json')\n}\n\n// Reuse credentials created by the official Codex CLI so Zencefyl does not\n// depend on a fragile duplicate browser OAuth flow when valid local auth exists.\nexport function loadCodexCliCredentials(): CodexCliAuth | null {\n const authPath = resolveCodexCliAuthPath()\n if (!fs.existsSync(authPath)) return null\n\n try {\n const raw = JSON.parse(fs.readFileSync(authPath, 'utf8')) as Record<string, unknown>\n const tokens = raw['tokens']\n if (!tokens || typeof tokens !== 'object') return null\n\n const record = tokens as Record<string, unknown>\n const access = record['access_token']\n const refresh = record['refresh_token']\n if (typeof access !== 'string' || !access || typeof refresh !== 'string' || !refresh) {\n return null\n }\n\n let fallbackExpiry = Date.now() + 60 * 60 * 1000\n try {\n fallbackExpiry = fs.statSync(authPath).mtimeMs + 60 * 60 * 1000\n } catch {\n // Ignore stat failures and keep the generic fallback expiry.\n }\n\n return {\n access,\n refresh,\n expires: decodeJwtExpiryMs(access) ?? fallbackExpiry,\n ...(typeof record['account_id'] === 'string' ? { accountId: record['account_id'] } : {}),\n }\n } catch {\n return null\n }\n}\n\nexport function resolveGeminiProjectId(\n value?: string | null,\n): string | null {\n const projectId = value\n ?? process.env['GOOGLE_CLOUD_PROJECT']\n ?? process.env['GOOGLE_CLOUD_PROJECT_ID']\n ?? process.env['GCLOUD_PROJECT']\n ?? loadGcloudConfiguredProjectId()\n ?? null\n\n return typeof projectId === 'string' && projectId.trim()\n ? projectId.trim()\n : null\n}\n\nfunction gcloudConfigDir(): string {\n return path.join(os.homedir(), '.config', 'gcloud')\n}\n\nfunction parseIniValue(contents: string, section: string, key: string): string | null {\n let currentSection = ''\n for (const rawLine of contents.split(/\\r?\\n/)) {\n const line = rawLine.trim()\n if (!line || line.startsWith('#') || line.startsWith(';')) continue\n\n const sectionMatch = line.match(/^\\[(.+)\\]$/)\n if (sectionMatch) {\n currentSection = sectionMatch[1] ?? ''\n continue\n }\n\n if (currentSection !== section) continue\n const valueMatch = line.match(/^([^=]+?)\\s*=\\s*(.+)$/)\n if (!valueMatch) continue\n if (valueMatch[1]?.trim() !== key) continue\n\n const value = valueMatch[2]?.trim() ?? ''\n return value || null\n }\n\n return null\n}\n\nfunction loadGcloudConfiguredProjectId(): string | null {\n const gcloudDir = gcloudConfigDir()\n const activeConfigPath = path.join(gcloudDir, 'active_config')\n let activeConfig = 'default'\n\n try {\n if (fs.existsSync(activeConfigPath)) {\n activeConfig = fs.readFileSync(activeConfigPath, 'utf8').trim() || 'default'\n }\n } catch {\n // Ignore local gcloud config read failures and continue to other fallbacks.\n }\n\n const configPath = path.join(gcloudDir, 'configurations', `config_${activeConfig}`)\n if (!fs.existsSync(configPath)) return null\n\n try {\n return parseIniValue(fs.readFileSync(configPath, 'utf8'), 'core', 'project')\n } catch {\n return null\n }\n}\n\nfunction isVpcScAffected(payload: unknown): boolean {\n if (!payload || typeof payload !== 'object') return false\n const error = (payload as { error?: unknown }).error\n if (!error || typeof error !== 'object') return false\n const details = (error as { details?: unknown[] }).details\n if (!Array.isArray(details)) return false\n\n return details.some(item =>\n typeof item === 'object' &&\n item !== null &&\n (item as { reason?: string }).reason === 'SECURITY_POLICY_VIOLATED'\n )\n}\n\nfunction getDefaultGeminiTier(\n allowedTiers?: Array<{ id?: string; isDefault?: boolean }>,\n): { id?: string } {\n if (!allowedTiers?.length) return { id: GOOGLE_TIER_LEGACY }\n return allowedTiers.find(tier => tier.isDefault) ?? { id: GOOGLE_TIER_LEGACY }\n}\n\nasync function wait(ms: number): Promise<void> {\n await new Promise(resolve => setTimeout(resolve, ms))\n}\n\nasync function pollGeminiProjectOperation(\n operationName: string,\n headers: Record<string, string>,\n): Promise<{ done?: boolean; response?: { cloudaicompanionProject?: { id?: string } } }> {\n for (let attempt = 0; attempt < 24; attempt += 1) {\n if (attempt > 0) await wait(5000)\n\n const response = await fetch(`${GOOGLE_CODE_ASSIST_ENDPOINT}/v1internal/${operationName}`, {\n method: 'GET',\n headers,\n })\n\n if (!response.ok) {\n throw new Error(`Failed to poll Gemini project provisioning: ${response.status} ${response.statusText}`)\n }\n\n const data = await response.json() as {\n done?: boolean\n response?: { cloudaicompanionProject?: { id?: string } }\n }\n\n if (data.done) return data\n }\n\n throw new Error('Timed out while waiting for Gemini project provisioning')\n}\n\nasync function discoverGeminiProjectIdWithAccessToken(accessToken: string): Promise<string> {\n const envProjectId = resolveGeminiProjectId()\n const headers = {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'User-Agent': 'google-api-nodejs-client/9.15.1',\n 'X-Goog-Api-Client': `gl-node/${process.versions.node}`,\n }\n\n const loadBody = {\n ...(envProjectId ? { cloudaicompanionProject: envProjectId } : {}),\n metadata: {\n ideType: 'IDE_UNSPECIFIED',\n platform: 'PLATFORM_UNSPECIFIED',\n pluginType: 'GEMINI',\n ...(envProjectId ? { duetProject: envProjectId } : {}),\n },\n }\n\n const loadResponse = await fetch(`${GOOGLE_CODE_ASSIST_ENDPOINT}/v1internal:loadCodeAssist`, {\n method: 'POST',\n headers,\n body: JSON.stringify(loadBody),\n })\n\n let data: {\n currentTier?: { id?: string }\n cloudaicompanionProject?: string | { id?: string }\n allowedTiers?: Array<{ id?: string; isDefault?: boolean }>\n }\n\n if (!loadResponse.ok) {\n let payload: unknown = null\n try {\n payload = await loadResponse.clone().json()\n } catch {\n payload = null\n }\n\n if (isVpcScAffected(payload)) {\n data = { currentTier: { id: GOOGLE_TIER_STANDARD } }\n } else {\n const text = await loadResponse.text()\n throw new Error(`Gemini loadCodeAssist failed: ${loadResponse.status} ${loadResponse.statusText}${text ? `: ${text}` : ''}`)\n }\n } else {\n data = await loadResponse.json() as typeof data\n }\n\n if (data.currentTier) {\n const project = data.cloudaicompanionProject\n if (typeof project === 'string' && project.trim()) return project.trim()\n if (typeof project === 'object' && typeof project?.id === 'string' && project.id.trim()) return project.id.trim()\n if (envProjectId) return envProjectId\n throw new Error(\n 'This Gemini account requires GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_PROJECT_ID, or an active gcloud project.'\n )\n }\n\n const tierId = getDefaultGeminiTier(data.allowedTiers).id ?? GOOGLE_TIER_FREE\n if (tierId !== GOOGLE_TIER_FREE && !envProjectId) {\n throw new Error(\n 'This Gemini account requires GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_PROJECT_ID, or an active gcloud project.'\n )\n }\n\n const onboardBody: Record<string, unknown> = {\n tierId,\n metadata: {\n ideType: 'IDE_UNSPECIFIED',\n platform: 'PLATFORM_UNSPECIFIED',\n pluginType: 'GEMINI',\n },\n }\n\n if (tierId !== GOOGLE_TIER_FREE && envProjectId) {\n onboardBody['cloudaicompanionProject'] = envProjectId\n ;(onboardBody['metadata'] as Record<string, unknown>)['duetProject'] = envProjectId\n }\n\n const onboardResponse = await fetch(`${GOOGLE_CODE_ASSIST_ENDPOINT}/v1internal:onboardUser`, {\n method: 'POST',\n headers,\n body: JSON.stringify(onboardBody),\n })\n\n if (!onboardResponse.ok) {\n const text = await onboardResponse.text()\n throw new Error(`Gemini onboardUser failed: ${onboardResponse.status} ${onboardResponse.statusText}${text ? `: ${text}` : ''}`)\n }\n\n let operation = await onboardResponse.json() as {\n done?: boolean\n name?: string\n response?: { cloudaicompanionProject?: { id?: string } }\n }\n\n if (!operation.done && operation.name) {\n operation = await pollGeminiProjectOperation(operation.name, headers)\n }\n\n const projectId = operation.response?.cloudaicompanionProject?.id\n if (typeof projectId === 'string' && projectId.trim()) return projectId.trim()\n if (envProjectId) return envProjectId\n\n throw new Error(\n 'Could not discover or provision a Gemini Code Assist project. Set GOOGLE_CLOUD_PROJECT or select a gcloud project.'\n )\n}\n\n// Gemini CLI / Code Assist can require a project that is not present in the\n// OAuth payload. We resolve it lazily from env, gcloud config, or by asking the\n// Cloud Code Assist backend to discover/provision one for the authenticated user.\nexport async function ensureGeminiProjectId(\n accessToken: string,\n value?: string | null,\n): Promise<string> {\n const existing = resolveGeminiProjectId(value)\n if (existing) return existing\n return await discoverGeminiProjectIdWithAccessToken(accessToken)\n}\n\n// ── Token refresh ─────────────────────────────────────────────────────────────\n\n// Buffer in ms — refresh 60s before actual expiry so requests never hit an\n// expired token mid-flight.\nconst REFRESH_BUFFER_MS = 60_000\n\nfunction isExpired(creds: OAuthCredentials): boolean {\n return Date.now() >= creds.expires - REFRESH_BUFFER_MS\n}\n\n// Returns a valid access token, refreshing first if needed.\n// Persists updated credentials back to disk on refresh.\nexport async function getAccessToken(\n dataDir: string,\n providerId: 'openai-subscription',\n): Promise<string>\nexport async function getAccessToken(\n dataDir: string,\n providerId: 'gemini-subscription',\n): Promise<string>\nexport async function getAccessToken(dataDir: string, providerId: ProviderId): Promise<string> {\n const store = loadCredentials(dataDir)\n const creds = store[providerId]\n\n if (!creds) {\n throw new Error(\n `No credentials for ${providerId}. ` +\n `Run zencefyl setup and choose the subscription option.`\n )\n }\n\n if (!isExpired(creds)) {\n return creds.access\n }\n\n // Token expired — refresh it\n let refreshed: OAuthCredentials\n\n if (providerId === 'openai-subscription') {\n const { refreshOpenAICodexToken } = await import('@mariozechner/pi-ai/oauth')\n refreshed = await refreshOpenAICodexToken(creds.refresh)\n } else {\n const { refreshGoogleCloudToken } = await import('@mariozechner/pi-ai/oauth')\n const projectId = await ensureGeminiProjectId(\n creds.access,\n (creds as GeminiCredentials).projectId ?? null,\n )\n refreshed = await refreshGoogleCloudToken(creds.refresh, projectId)\n // Preserve projectId through refresh\n ;(refreshed as GeminiCredentials).projectId = projectId\n }\n\n saveProviderCredentials(dataDir, providerId, refreshed)\n return refreshed.access\n}\n"],"mappings":"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","names":[]}
@@ -1,16 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  credentialsPath,
4
+ ensureGeminiProjectId,
4
5
  getAccessToken,
6
+ loadCodexCliCredentials,
5
7
  loadCredentials,
8
+ resolveGeminiProjectId,
6
9
  saveCredentials,
7
10
  saveProviderCredentials
8
- } from "./chunk-OBDSCGMH.js";
11
+ } from "./chunk-JZA53FAX.js";
9
12
  export {
10
13
  credentialsPath,
14
+ ensureGeminiProjectId,
11
15
  getAccessToken,
16
+ loadCodexCliCredentials,
12
17
  loadCredentials,
18
+ resolveGeminiProjectId,
13
19
  saveCredentials,
14
20
  saveProviderCredentials
15
21
  };
16
- //# sourceMappingURL=credentials-7Z74C2OF.js.map
22
+ //# sourceMappingURL=credentials-C7NSDIAG.js.map