@aexol/spectral 0.7.1 → 0.7.5
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.
- package/CHANGELOG.md +5 -0
- package/dist/agent/agents.js +1 -1
- package/dist/agent/index.js +199 -184
- package/dist/commands/serve.js +0 -3
- package/dist/designer/data/systems/renault/DESIGN.md +1 -1
- package/dist/designer/philosophies.js +668 -0
- package/dist/mcp/sampling-handler.js +1 -1
- package/dist/memory/commands/status.js +1 -1
- package/dist/memory/compaction.js +2 -2
- package/dist/memory/config.js +1 -1
- package/dist/memory/debug-log.js +1 -1
- package/dist/memory/hooks/compaction-hook.js +29 -0
- package/dist/memory/index.js +2 -0
- package/dist/memory/observer.js +2 -2
- package/dist/memory/project-observations-store.js +14 -0
- package/dist/memory/tokens.js +1 -1
- package/dist/memory/tools/read-project-observations.js +82 -0
- package/dist/memory/tools/recall-observation.js +2 -2
- package/dist/pi/agent-core/agent-loop.js +501 -0
- package/dist/pi/agent-core/agent.js +401 -0
- package/dist/pi/agent-core/harness/agent-harness.js +899 -0
- package/dist/pi/agent-core/harness/compaction/branch-summarization.js +173 -0
- package/dist/pi/agent-core/harness/compaction/compaction.js +532 -0
- package/dist/pi/agent-core/harness/compaction/utils.js +130 -0
- package/dist/pi/agent-core/harness/env/nodejs.js +485 -0
- package/dist/pi/agent-core/harness/messages.js +101 -0
- package/dist/pi/agent-core/harness/prompt-templates.js +229 -0
- package/dist/pi/agent-core/harness/session/jsonl-repo.js +100 -0
- package/dist/pi/agent-core/harness/session/jsonl-storage.js +230 -0
- package/dist/pi/agent-core/harness/session/memory-repo.js +41 -0
- package/dist/pi/agent-core/harness/session/memory-storage.js +113 -0
- package/dist/pi/agent-core/harness/session/repo-utils.js +38 -0
- package/dist/pi/agent-core/harness/session/session.js +196 -0
- package/dist/pi/agent-core/harness/session/uuid.js +49 -0
- package/dist/pi/agent-core/harness/skills.js +310 -0
- package/dist/pi/agent-core/harness/system-prompt.js +29 -0
- package/dist/pi/agent-core/harness/types.js +93 -0
- package/dist/pi/agent-core/harness/utils/shell-output.js +125 -0
- package/dist/pi/agent-core/harness/utils/truncate.js +289 -0
- package/dist/pi/agent-core/index.js +24 -0
- package/dist/pi/agent-core/node.js +2 -0
- package/dist/pi/agent-core/proxy.js +277 -0
- package/dist/pi/agent-core/types.js +1 -0
- package/dist/pi/ai/api-registry.js +43 -0
- package/dist/pi/ai/cli.js +120 -0
- package/dist/pi/ai/env-api-keys.js +169 -0
- package/dist/pi/ai/image-models.generated.js +441 -0
- package/dist/pi/ai/image-models.js +22 -0
- package/dist/pi/ai/images-api-registry.js +21 -0
- package/dist/pi/ai/images.js +13 -0
- package/dist/pi/ai/index.js +18 -0
- package/dist/pi/ai/models.generated.js +16220 -0
- package/dist/pi/ai/models.js +70 -0
- package/dist/pi/ai/oauth.js +1 -0
- package/dist/pi/ai/providers/anthropic.js +945 -0
- package/dist/pi/ai/providers/faux.js +367 -0
- package/dist/pi/ai/providers/github-copilot-headers.js +28 -0
- package/dist/pi/ai/providers/openai-completions.js +945 -0
- package/dist/pi/ai/providers/openai-prompt-cache.js +9 -0
- package/dist/pi/ai/providers/register-builtins.js +97 -0
- package/dist/pi/ai/providers/simple-options.js +40 -0
- package/dist/pi/ai/providers/transform-messages.js +183 -0
- package/dist/pi/ai/session-resources.js +21 -0
- package/dist/pi/ai/stream.js +26 -0
- package/dist/pi/ai/types.js +1 -0
- package/dist/pi/ai/utils/diagnostics.js +24 -0
- package/dist/pi/ai/utils/event-stream.js +80 -0
- package/dist/pi/ai/utils/hash.js +13 -0
- package/dist/pi/ai/utils/headers.js +7 -0
- package/dist/pi/ai/utils/json-parse.js +112 -0
- package/dist/pi/ai/utils/node-http-proxy.js +96 -0
- package/dist/pi/ai/utils/oauth/anthropic.js +334 -0
- package/dist/pi/ai/utils/oauth/device-code.js +54 -0
- package/dist/pi/ai/utils/oauth/github-copilot.js +270 -0
- package/dist/pi/ai/utils/oauth/index.js +121 -0
- package/dist/pi/ai/utils/oauth/oauth-page.js +104 -0
- package/dist/pi/ai/utils/oauth/openai-codex.js +384 -0
- package/dist/pi/ai/utils/oauth/pkce.js +30 -0
- package/dist/pi/ai/utils/oauth/types.js +1 -0
- package/dist/pi/ai/utils/overflow.js +150 -0
- package/dist/pi/ai/utils/sanitize-unicode.js +25 -0
- package/dist/pi/ai/utils/typebox-helpers.js +20 -0
- package/dist/pi/ai/utils/validation.js +280 -0
- package/dist/pi/coding-agent/bun/cli.js +7 -0
- package/dist/pi/coding-agent/bun/restore-sandbox-env.js +31 -0
- package/dist/pi/coding-agent/cli/args.js +340 -0
- package/dist/pi/coding-agent/cli/file-processor.js +82 -0
- package/dist/pi/coding-agent/cli/initial-message.js +21 -0
- package/dist/pi/coding-agent/cli.js +17 -0
- package/dist/pi/coding-agent/config.js +414 -0
- package/dist/pi/coding-agent/core/agent-session-runtime.js +299 -0
- package/dist/pi/coding-agent/core/agent-session-services.js +117 -0
- package/dist/pi/coding-agent/core/agent-session.js +2498 -0
- package/dist/pi/coding-agent/core/auth-guidance.js +20 -0
- package/dist/pi/coding-agent/core/auth-storage.js +441 -0
- package/dist/pi/coding-agent/core/bash-executor.js +110 -0
- package/dist/pi/coding-agent/core/compaction/branch-summarization.js +242 -0
- package/dist/pi/coding-agent/core/compaction/compaction.js +624 -0
- package/dist/pi/coding-agent/core/compaction/index.js +6 -0
- package/dist/pi/coding-agent/core/compaction/utils.js +152 -0
- package/dist/pi/coding-agent/core/defaults.js +1 -0
- package/dist/pi/coding-agent/core/diagnostics.js +1 -0
- package/dist/pi/coding-agent/core/event-bus.js +24 -0
- package/dist/pi/coding-agent/core/exec.js +74 -0
- package/dist/pi/coding-agent/core/export-html/ansi-to-html.js +248 -0
- package/dist/pi/coding-agent/core/export-html/index.js +225 -0
- package/dist/pi/coding-agent/core/export-html/tool-renderer.js +107 -0
- package/dist/pi/coding-agent/core/extensions/index.js +8 -0
- package/dist/pi/coding-agent/core/extensions/loader.js +485 -0
- package/dist/pi/coding-agent/core/extensions/runner.js +824 -0
- package/dist/pi/coding-agent/core/extensions/types.js +44 -0
- package/dist/pi/coding-agent/core/extensions/wrapper.js +21 -0
- package/dist/pi/coding-agent/core/footer-data-provider.js +309 -0
- package/dist/pi/coding-agent/core/http-dispatcher.js +47 -0
- package/dist/pi/coding-agent/core/index.js +11 -0
- package/dist/pi/coding-agent/core/keybindings.js +294 -0
- package/dist/pi/coding-agent/core/messages.js +122 -0
- package/dist/pi/coding-agent/core/model-registry.js +728 -0
- package/dist/pi/coding-agent/core/model-resolver.js +494 -0
- package/dist/pi/coding-agent/core/output-guard.js +58 -0
- package/dist/pi/coding-agent/core/package-manager.js +2020 -0
- package/dist/pi/coding-agent/core/prompt-templates.js +237 -0
- package/dist/pi/coding-agent/core/provider-display-names.js +32 -0
- package/dist/pi/coding-agent/core/resolve-config-value.js +125 -0
- package/dist/pi/coding-agent/core/resource-loader.js +733 -0
- package/dist/pi/coding-agent/core/sdk.js +282 -0
- package/dist/pi/coding-agent/core/session-cwd.js +37 -0
- package/dist/pi/coding-agent/core/session-manager.js +1146 -0
- package/dist/pi/coding-agent/core/settings-manager.js +794 -0
- package/dist/pi/coding-agent/core/skills.js +386 -0
- package/dist/pi/coding-agent/core/slash-commands.js +24 -0
- package/dist/pi/coding-agent/core/source-info.js +18 -0
- package/dist/pi/coding-agent/core/system-prompt.js +122 -0
- package/dist/pi/coding-agent/core/telemetry.js +8 -0
- package/dist/pi/coding-agent/core/timings.js +30 -0
- package/dist/pi/coding-agent/core/tools/bash.js +341 -0
- package/dist/pi/coding-agent/core/tools/edit-diff.js +344 -0
- package/dist/pi/coding-agent/core/tools/edit.js +324 -0
- package/dist/pi/coding-agent/core/tools/file-mutation-queue.js +36 -0
- package/dist/pi/coding-agent/core/tools/find.js +297 -0
- package/dist/pi/coding-agent/core/tools/grep.js +303 -0
- package/dist/pi/coding-agent/core/tools/index.js +111 -0
- package/dist/pi/coding-agent/core/tools/ls.js +168 -0
- package/dist/pi/coding-agent/core/tools/output-accumulator.js +183 -0
- package/dist/pi/coding-agent/core/tools/path-utils.js +61 -0
- package/dist/pi/coding-agent/core/tools/read.js +288 -0
- package/dist/pi/coding-agent/core/tools/render-utils.js +48 -0
- package/dist/pi/coding-agent/core/tools/tool-definition-wrapper.js +33 -0
- package/dist/pi/coding-agent/core/tools/truncate.js +214 -0
- package/dist/pi/coding-agent/core/tools/write.js +212 -0
- package/dist/pi/coding-agent/index.js +41 -0
- package/dist/pi/coding-agent/main.js +5 -0
- package/dist/pi/coding-agent/migrations.js +280 -0
- package/dist/pi/coding-agent/modes/index.js +7 -0
- package/dist/pi/coding-agent/modes/interactive/components/diff.js +132 -0
- package/dist/pi/coding-agent/modes/interactive/components/keybinding-hints.js +35 -0
- package/dist/pi/coding-agent/modes/interactive/components/visual-truncate.js +32 -0
- package/dist/pi/coding-agent/modes/interactive/interactive-mode.js +3 -0
- package/dist/pi/coding-agent/modes/interactive/theme/theme.js +1023 -0
- package/dist/pi/coding-agent/modes/print-mode.js +130 -0
- package/dist/pi/coding-agent/modes/rpc/jsonl.js +48 -0
- package/dist/pi/coding-agent/modes/rpc/rpc-client.js +409 -0
- package/dist/pi/coding-agent/modes/rpc/rpc-mode.js +600 -0
- package/dist/pi/coding-agent/modes/rpc/rpc-types.js +7 -0
- package/dist/pi/coding-agent/utils/ansi.js +51 -0
- package/dist/pi/coding-agent/utils/changelog.js +86 -0
- package/dist/pi/coding-agent/utils/child-process.js +87 -0
- package/dist/pi/coding-agent/utils/clipboard-image.js +244 -0
- package/dist/pi/coding-agent/utils/clipboard-native.js +13 -0
- package/dist/pi/coding-agent/utils/clipboard.js +116 -0
- package/dist/pi/coding-agent/utils/exif-orientation.js +157 -0
- package/dist/pi/coding-agent/utils/frontmatter.js +25 -0
- package/dist/pi/coding-agent/utils/fs-watch.js +24 -0
- package/dist/pi/coding-agent/utils/git.js +162 -0
- package/dist/pi/coding-agent/utils/html.js +39 -0
- package/dist/pi/coding-agent/utils/image-convert.js +38 -0
- package/dist/pi/coding-agent/utils/image-resize.js +136 -0
- package/dist/pi/coding-agent/utils/mime.js +68 -0
- package/dist/pi/coding-agent/utils/paths.js +91 -0
- package/dist/pi/coding-agent/utils/photon.js +120 -0
- package/dist/pi/coding-agent/utils/pi-user-agent.js +4 -0
- package/dist/pi/coding-agent/utils/shell.js +194 -0
- package/dist/pi/coding-agent/utils/sleep.js +16 -0
- package/dist/pi/coding-agent/utils/syntax-highlight.js +117 -0
- package/dist/pi/coding-agent/utils/tools-manager.js +327 -0
- package/dist/pi/coding-agent/utils/version-check.js +81 -0
- package/dist/pi/coding-agent/utils/windows-self-update.js +76 -0
- package/dist/pi/tui/autocomplete.js +631 -0
- package/dist/pi/tui/components/box.js +103 -0
- package/dist/pi/tui/components/cancellable-loader.js +34 -0
- package/dist/pi/tui/components/editor.js +1915 -0
- package/dist/pi/tui/components/image.js +88 -0
- package/dist/pi/tui/components/input.js +425 -0
- package/dist/pi/tui/components/loader.js +68 -0
- package/dist/pi/tui/components/markdown.js +633 -0
- package/dist/pi/tui/components/select-list.js +158 -0
- package/dist/pi/tui/components/settings-list.js +184 -0
- package/dist/pi/tui/components/spacer.js +22 -0
- package/dist/pi/tui/components/text.js +88 -0
- package/dist/pi/tui/components/truncated-text.js +50 -0
- package/dist/pi/tui/editor-component.js +1 -0
- package/dist/pi/tui/fuzzy.js +109 -0
- package/dist/pi/tui/index.js +31 -0
- package/dist/pi/tui/keybindings.js +173 -0
- package/dist/pi/tui/keys.js +1172 -0
- package/dist/pi/tui/kill-ring.js +43 -0
- package/dist/pi/tui/stdin-buffer.js +360 -0
- package/dist/pi/tui/terminal-image.js +335 -0
- package/dist/pi/tui/terminal.js +324 -0
- package/dist/pi/tui/tui.js +1076 -0
- package/dist/pi/tui/undo-stack.js +24 -0
- package/dist/pi/tui/utils.js +1016 -0
- package/dist/relay/dispatcher.js +30 -0
- package/dist/server/handlers/queue.js +52 -0
- package/dist/server/pi-bridge.js +9 -1
- package/dist/server/session-stream.js +76 -111
- package/dist/server/storage.js +154 -2
- package/dist/server/title-generator.js +14 -153
- package/package.json +24 -6
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createInterface } from "node:readline";
|
|
3
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
4
|
+
import { getOAuthProvider, getOAuthProviders } from "./utils/oauth/index.js";
|
|
5
|
+
const AUTH_FILE = "auth.json";
|
|
6
|
+
const PROVIDERS = getOAuthProviders();
|
|
7
|
+
function prompt(rl, question) {
|
|
8
|
+
return new Promise((resolve) => rl.question(question, resolve));
|
|
9
|
+
}
|
|
10
|
+
function loadAuth() {
|
|
11
|
+
if (!existsSync(AUTH_FILE))
|
|
12
|
+
return {};
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(readFileSync(AUTH_FILE, "utf-8"));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function saveAuth(auth) {
|
|
21
|
+
writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), "utf-8");
|
|
22
|
+
}
|
|
23
|
+
async function login(providerId) {
|
|
24
|
+
const provider = getOAuthProvider(providerId);
|
|
25
|
+
if (!provider) {
|
|
26
|
+
console.error(`Unknown provider: ${providerId}`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
30
|
+
const promptFn = (msg) => prompt(rl, `${msg} `);
|
|
31
|
+
try {
|
|
32
|
+
const credentials = await provider.login({
|
|
33
|
+
onAuth: (info) => {
|
|
34
|
+
console.log(`\nOpen this URL in your browser:\n${info.url}`);
|
|
35
|
+
if (info.instructions)
|
|
36
|
+
console.log(info.instructions);
|
|
37
|
+
console.log();
|
|
38
|
+
},
|
|
39
|
+
onDeviceCode: (info) => {
|
|
40
|
+
console.log(`\nOpen this URL in your browser:\n${info.verificationUri}`);
|
|
41
|
+
console.log(`Enter code: ${info.userCode}`);
|
|
42
|
+
console.log();
|
|
43
|
+
},
|
|
44
|
+
onPrompt: async (p) => {
|
|
45
|
+
return await promptFn(`${p.message}${p.placeholder ? ` (${p.placeholder})` : ""}:`);
|
|
46
|
+
},
|
|
47
|
+
onProgress: (msg) => console.log(msg),
|
|
48
|
+
});
|
|
49
|
+
const auth = loadAuth();
|
|
50
|
+
auth[providerId] = { type: "oauth", ...credentials };
|
|
51
|
+
saveAuth(auth);
|
|
52
|
+
console.log(`\nCredentials saved to ${AUTH_FILE}`);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
rl.close();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function main() {
|
|
59
|
+
const args = process.argv.slice(2);
|
|
60
|
+
const command = args[0];
|
|
61
|
+
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
62
|
+
const providerList = PROVIDERS.map((p) => ` ${p.id.padEnd(20)} ${p.name}`).join("\n");
|
|
63
|
+
console.log(`Usage: npx index.ts <command> [provider]
|
|
64
|
+
|
|
65
|
+
Commands:
|
|
66
|
+
login [provider] Login to an OAuth provider
|
|
67
|
+
list List available providers
|
|
68
|
+
|
|
69
|
+
Providers:
|
|
70
|
+
${providerList}
|
|
71
|
+
|
|
72
|
+
Examples:
|
|
73
|
+
npx index.ts login # interactive provider selection
|
|
74
|
+
npx index.ts login anthropic # login to specific provider
|
|
75
|
+
npx index.ts list # list providers
|
|
76
|
+
`);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (command === "list") {
|
|
80
|
+
console.log("Available OAuth providers:\n");
|
|
81
|
+
for (const p of PROVIDERS) {
|
|
82
|
+
console.log(` ${p.id.padEnd(20)} ${p.name}`);
|
|
83
|
+
}
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (command === "login") {
|
|
87
|
+
let provider = args[1];
|
|
88
|
+
if (!provider) {
|
|
89
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
90
|
+
console.log("Select a provider:\n");
|
|
91
|
+
for (let i = 0; i < PROVIDERS.length; i++) {
|
|
92
|
+
console.log(` ${i + 1}. ${PROVIDERS[i].name}`);
|
|
93
|
+
}
|
|
94
|
+
console.log();
|
|
95
|
+
const choice = await prompt(rl, `Enter number (1-${PROVIDERS.length}): `);
|
|
96
|
+
rl.close();
|
|
97
|
+
const index = parseInt(choice, 10) - 1;
|
|
98
|
+
if (index < 0 || index >= PROVIDERS.length) {
|
|
99
|
+
console.error("Invalid selection");
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
provider = PROVIDERS[index].id;
|
|
103
|
+
}
|
|
104
|
+
if (!PROVIDERS.some((p) => p.id === provider)) {
|
|
105
|
+
console.error(`Unknown provider: ${provider}`);
|
|
106
|
+
console.error(`Use 'npx index.ts list' to see available providers`);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
console.log(`Logging in to ${provider}...`);
|
|
110
|
+
await login(provider);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
console.error(`Unknown command: ${command}`);
|
|
114
|
+
console.error(`Use 'npx index.ts --help' for usage`);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
main().catch((err) => {
|
|
118
|
+
console.error("Error:", err.message);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
});
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// NEVER convert to top-level imports - breaks browser/Vite builds
|
|
2
|
+
let _existsSync = null;
|
|
3
|
+
let _homedir = null;
|
|
4
|
+
let _join = null;
|
|
5
|
+
const dynamicImport = (specifier) => import(specifier);
|
|
6
|
+
const NODE_FS_SPECIFIER = "node:" + "fs";
|
|
7
|
+
const NODE_OS_SPECIFIER = "node:" + "os";
|
|
8
|
+
const NODE_PATH_SPECIFIER = "node:" + "path";
|
|
9
|
+
// Eagerly load in Node.js/Bun environment only
|
|
10
|
+
if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) {
|
|
11
|
+
dynamicImport(NODE_FS_SPECIFIER).then((m) => {
|
|
12
|
+
_existsSync = m.existsSync;
|
|
13
|
+
});
|
|
14
|
+
dynamicImport(NODE_OS_SPECIFIER).then((m) => {
|
|
15
|
+
_homedir = m.homedir;
|
|
16
|
+
});
|
|
17
|
+
dynamicImport(NODE_PATH_SPECIFIER).then((m) => {
|
|
18
|
+
_join = m.join;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
let _procEnvCache = null;
|
|
22
|
+
/**
|
|
23
|
+
* Fallback for https://github.com/oven-sh/bun/issues/27802
|
|
24
|
+
* Bun compiled binaries have an empty `process.env` inside sandbox
|
|
25
|
+
* environments on Linux. We can recover the env from `/proc/self/environ`.
|
|
26
|
+
*/
|
|
27
|
+
function getProcEnv(key) {
|
|
28
|
+
if (!process.versions?.bun)
|
|
29
|
+
return undefined;
|
|
30
|
+
if (typeof process === "undefined")
|
|
31
|
+
return undefined;
|
|
32
|
+
// If process.env already has entries, the bug is not triggered.
|
|
33
|
+
if (Object.keys(process.env).length > 0)
|
|
34
|
+
return undefined;
|
|
35
|
+
if (_procEnvCache === null) {
|
|
36
|
+
_procEnvCache = new Map();
|
|
37
|
+
try {
|
|
38
|
+
const { readFileSync } = require("node:fs");
|
|
39
|
+
const data = readFileSync("/proc/self/environ", "utf-8");
|
|
40
|
+
for (const entry of data.split("\0")) {
|
|
41
|
+
const idx = entry.indexOf("=");
|
|
42
|
+
if (idx > 0) {
|
|
43
|
+
_procEnvCache.set(entry.slice(0, idx), entry.slice(idx + 1));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// /proc/self/environ may not be readable.
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return _procEnvCache.get(key);
|
|
52
|
+
}
|
|
53
|
+
let cachedVertexAdcCredentialsExists = null;
|
|
54
|
+
function hasVertexAdcCredentials() {
|
|
55
|
+
if (cachedVertexAdcCredentialsExists === null) {
|
|
56
|
+
// If node modules haven't loaded yet (async import race at startup),
|
|
57
|
+
// return false WITHOUT caching so the next call retries once they're ready.
|
|
58
|
+
// Only cache false permanently in a browser environment where fs is never available.
|
|
59
|
+
if (!_existsSync || !_homedir || !_join) {
|
|
60
|
+
const isNode = typeof process !== "undefined" && (process.versions?.node || process.versions?.bun);
|
|
61
|
+
if (!isNode) {
|
|
62
|
+
// Definitively in a browser — safe to cache false permanently
|
|
63
|
+
cachedVertexAdcCredentialsExists = false;
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
// Check GOOGLE_APPLICATION_CREDENTIALS env var first (standard way)
|
|
68
|
+
const gacPath = process.env.GOOGLE_APPLICATION_CREDENTIALS || getProcEnv("GOOGLE_APPLICATION_CREDENTIALS");
|
|
69
|
+
if (gacPath) {
|
|
70
|
+
cachedVertexAdcCredentialsExists = _existsSync(gacPath);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// Fall back to default ADC path (lazy evaluation)
|
|
74
|
+
cachedVertexAdcCredentialsExists = _existsSync(_join(_homedir(), ".config", "gcloud", "application_default_credentials.json"));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return cachedVertexAdcCredentialsExists;
|
|
78
|
+
}
|
|
79
|
+
function getApiKeyEnvVars(provider) {
|
|
80
|
+
if (provider === "github-copilot") {
|
|
81
|
+
return ["COPILOT_GITHUB_TOKEN"];
|
|
82
|
+
}
|
|
83
|
+
// ANTHROPIC_OAUTH_TOKEN takes precedence over ANTHROPIC_API_KEY
|
|
84
|
+
if (provider === "anthropic") {
|
|
85
|
+
return ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"];
|
|
86
|
+
}
|
|
87
|
+
const envMap = {
|
|
88
|
+
openai: "OPENAI_API_KEY",
|
|
89
|
+
"azure-openai-responses": "AZURE_OPENAI_API_KEY",
|
|
90
|
+
deepseek: "DEEPSEEK_API_KEY",
|
|
91
|
+
google: "GEMINI_API_KEY",
|
|
92
|
+
"google-vertex": "GOOGLE_CLOUD_API_KEY",
|
|
93
|
+
groq: "GROQ_API_KEY",
|
|
94
|
+
cerebras: "CEREBRAS_API_KEY",
|
|
95
|
+
xai: "XAI_API_KEY",
|
|
96
|
+
openrouter: "OPENROUTER_API_KEY",
|
|
97
|
+
"vercel-ai-gateway": "AI_GATEWAY_API_KEY",
|
|
98
|
+
zai: "ZAI_API_KEY",
|
|
99
|
+
mistral: "MISTRAL_API_KEY",
|
|
100
|
+
minimax: "MINIMAX_API_KEY",
|
|
101
|
+
"minimax-cn": "MINIMAX_CN_API_KEY",
|
|
102
|
+
moonshotai: "MOONSHOT_API_KEY",
|
|
103
|
+
"moonshotai-cn": "MOONSHOT_API_KEY",
|
|
104
|
+
huggingface: "HF_TOKEN",
|
|
105
|
+
fireworks: "FIREWORKS_API_KEY",
|
|
106
|
+
together: "TOGETHER_API_KEY",
|
|
107
|
+
opencode: "OPENCODE_API_KEY",
|
|
108
|
+
"opencode-go": "OPENCODE_API_KEY",
|
|
109
|
+
"kimi-coding": "KIMI_API_KEY",
|
|
110
|
+
"cloudflare-workers-ai": "CLOUDFLARE_API_KEY",
|
|
111
|
+
"cloudflare-ai-gateway": "CLOUDFLARE_API_KEY",
|
|
112
|
+
xiaomi: "XIAOMI_API_KEY",
|
|
113
|
+
"xiaomi-token-plan-cn": "XIAOMI_TOKEN_PLAN_CN_API_KEY",
|
|
114
|
+
"xiaomi-token-plan-ams": "XIAOMI_TOKEN_PLAN_AMS_API_KEY",
|
|
115
|
+
"xiaomi-token-plan-sgp": "XIAOMI_TOKEN_PLAN_SGP_API_KEY",
|
|
116
|
+
};
|
|
117
|
+
const envVar = envMap[provider];
|
|
118
|
+
return envVar ? [envVar] : undefined;
|
|
119
|
+
}
|
|
120
|
+
export function findEnvKeys(provider) {
|
|
121
|
+
const envVars = getApiKeyEnvVars(provider);
|
|
122
|
+
if (!envVars)
|
|
123
|
+
return undefined;
|
|
124
|
+
const found = envVars.filter((envVar) => !!process.env[envVar] || !!getProcEnv(envVar));
|
|
125
|
+
return found.length > 0 ? found : undefined;
|
|
126
|
+
}
|
|
127
|
+
export function getEnvApiKey(provider) {
|
|
128
|
+
const envKeys = findEnvKeys(provider);
|
|
129
|
+
if (envKeys?.[0]) {
|
|
130
|
+
return process.env[envKeys[0]] || getProcEnv(envKeys[0]);
|
|
131
|
+
}
|
|
132
|
+
// Vertex AI supports either an explicit API key or Application Default Credentials.
|
|
133
|
+
// Auth is configured via `gcloud auth application-default login`.
|
|
134
|
+
if (provider === "google-vertex") {
|
|
135
|
+
const hasCredentials = hasVertexAdcCredentials();
|
|
136
|
+
const hasProject = !!(process.env.GOOGLE_CLOUD_PROJECT ||
|
|
137
|
+
process.env.GCLOUD_PROJECT ||
|
|
138
|
+
getProcEnv("GOOGLE_CLOUD_PROJECT") ||
|
|
139
|
+
getProcEnv("GCLOUD_PROJECT"));
|
|
140
|
+
const hasLocation = !!(process.env.GOOGLE_CLOUD_LOCATION || getProcEnv("GOOGLE_CLOUD_LOCATION"));
|
|
141
|
+
if (hasCredentials && hasProject && hasLocation) {
|
|
142
|
+
return "<authenticated>";
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (provider === "amazon-bedrock") {
|
|
146
|
+
// Amazon Bedrock supports multiple credential sources:
|
|
147
|
+
// 1. AWS_PROFILE - named profile from ~/.aws/credentials
|
|
148
|
+
// 2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY - standard IAM keys
|
|
149
|
+
// 3. AWS_BEARER_TOKEN_BEDROCK - Bedrock bearer token
|
|
150
|
+
// 4. AWS_CONTAINER_CREDENTIALS_RELATIVE_URI - ECS task roles
|
|
151
|
+
// 5. AWS_CONTAINER_CREDENTIALS_FULL_URI - ECS task roles (full URI)
|
|
152
|
+
// 6. AWS_WEB_IDENTITY_TOKEN_FILE - IRSA (IAM Roles for Service Accounts)
|
|
153
|
+
if (process.env.AWS_PROFILE ||
|
|
154
|
+
(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||
|
|
155
|
+
process.env.AWS_BEARER_TOKEN_BEDROCK ||
|
|
156
|
+
process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI ||
|
|
157
|
+
process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI ||
|
|
158
|
+
process.env.AWS_WEB_IDENTITY_TOKEN_FILE ||
|
|
159
|
+
getProcEnv("AWS_PROFILE") ||
|
|
160
|
+
(getProcEnv("AWS_ACCESS_KEY_ID") && getProcEnv("AWS_SECRET_ACCESS_KEY")) ||
|
|
161
|
+
getProcEnv("AWS_BEARER_TOKEN_BEDROCK") ||
|
|
162
|
+
getProcEnv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") ||
|
|
163
|
+
getProcEnv("AWS_CONTAINER_CREDENTIALS_FULL_URI") ||
|
|
164
|
+
getProcEnv("AWS_WEB_IDENTITY_TOKEN_FILE")) {
|
|
165
|
+
return "<authenticated>";
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|