mirror of
https://github.com/GMGNAI/gmgn-skills.git
synced 2026-11-02 07:46:11 +00:00
fix(config): make project .env override global config as documented
src/config.ts loaded ~/.config/gmgn/.env with override:true and then the cwd .env without override, so the global file always won — the opposite of what Readme, Readme.zh, CLAUDE.md and the gmgn-cooking skill promise. A user who updated GMGN_PRIVATE_KEY in a project .env kept signing with the stale global key and got AUTH_SIGNATURE_INVALID. Load the cwd .env first and the global file second, both without override, so precedence is shell env > project .env > global .env. `config --check` reuses the same loader instead of its own copy. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
b0f4ac7135
commit
227011b834
@@ -97,6 +97,8 @@ Config lookup order (project overrides global):
|
||||
1. `~/.config/gmgn/.env` — global config, set once for all projects
|
||||
2. `.env` in the current working directory — project-level override (takes precedence)
|
||||
|
||||
Variables already exported in the shell environment override both files.
|
||||
|
||||
Required variables:
|
||||
- `GMGN_API_KEY` — apply at https://gmgn.ai/ai
|
||||
- `GMGN_PRIVATE_KEY` — PEM content, required for swap/order commands only
|
||||
|
||||
@@ -329,7 +329,7 @@ cp .env.example .env
|
||||
# Edit .env and fill in your values
|
||||
```
|
||||
|
||||
Config lookup order: `~/.config/gmgn/.env` → project `.env` (project takes precedence).
|
||||
Config lookup order: `~/.config/gmgn/.env` → project `.env` (project takes precedence). Variables already exported in your shell override both files.
|
||||
|
||||
## 5. Try in AI Clients
|
||||
|
||||
|
||||
+1
-1
@@ -333,7 +333,7 @@ cp .env.example .env
|
||||
# 编辑 .env,填入实际值
|
||||
```
|
||||
|
||||
配置加载顺序:`~/.config/gmgn/.env` → 项目 `.env`(项目级优先)。
|
||||
配置加载顺序:`~/.config/gmgn/.env` → 项目 `.env`(项目级优先)。Shell 中已 export 的同名环境变量优先级最高,会覆盖两个文件。
|
||||
|
||||
## 5. 在 AI 客户端中使用
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { config as loadDotenv } from "dotenv";
|
||||
import { Command } from "commander";
|
||||
import * as crypto from "crypto";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as os from "os";
|
||||
import { execSync } from "child_process";
|
||||
import { loadEnvFiles } from "../config.js";
|
||||
|
||||
const GMGN_CONFIG_DIR = path.join(os.homedir(), ".config", "gmgn");
|
||||
const KEYPAIR_FILE = path.join(GMGN_CONFIG_DIR, "keypair.pem");
|
||||
@@ -116,8 +116,7 @@ export function registerConfigCommands(program: Command): void {
|
||||
const lang = detectLang();
|
||||
|
||||
if (opts.check) {
|
||||
loadDotenv({ path: ENV_FILE, override: true });
|
||||
loadDotenv();
|
||||
loadEnvFiles();
|
||||
process.exit(process.env.GMGN_API_KEY ? 0 : 1);
|
||||
}
|
||||
|
||||
|
||||
+9
-3
@@ -28,9 +28,15 @@ function enforceCredentialFilePermissions(path: string): void {
|
||||
|
||||
enforceCredentialFilePermissions(GLOBAL_ENV_PATH);
|
||||
|
||||
// Load global config first (~/.config/gmgn/.env, takes precedence), then project .env (supplements only)
|
||||
loadDotenv({ path: GLOBAL_ENV_PATH, override: true });
|
||||
loadDotenv();
|
||||
// Precedence: shell environment > project .env (cwd) > global ~/.config/gmgn/.env.
|
||||
// dotenv never overwrites a variable that is already set, so the higher-priority
|
||||
// source must be loaded first and the global file only fills in what is missing.
|
||||
export function loadEnvFiles(): void {
|
||||
loadDotenv();
|
||||
loadDotenv({ path: GLOBAL_ENV_PATH });
|
||||
}
|
||||
|
||||
loadEnvFiles();
|
||||
|
||||
export interface Config {
|
||||
apiKey: string;
|
||||
|
||||
Reference in New Issue
Block a user