Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/cli/commands/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ function buildInitTemplate(): string {
apiKeyCommand: DEFAULTS.llm.apiKeyCommand,
},

// Embedding backend for `codegraph embed`/`search`. Leave provider null
// for the local bundled model, or set it to "openai" to call a remote
// OpenAI-compatible endpoint configured via llm.baseUrl/apiKeyCommand.
embeddings: {
model: DEFAULTS.embeddings.model,
llmProvider: DEFAULTS.embeddings.llmProvider,
provider: DEFAULTS.embeddings.provider,
},

query: {
defaultDepth: DEFAULTS.query.defaultDepth,
defaultLimit: DEFAULTS.query.defaultLimit,
Expand Down
50 changes: 50 additions & 0 deletions tests/integration/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,53 @@ describe('Registry CLI commands', () => {
expect(out2).toContain('"api-2"');
});
});

// ─── Config CLI ───────────────────────────────────────────────────────

describe('Config CLI commands', () => {
let tmpHome: string;
let userConfigPath: string;

/**
* Run CLI with isolated HOME *and* an explicit CODEGRAPH_USER_CONFIG so
* --init doesn't touch the real global config. HOME/USERPROFILE alone
* aren't sufficient: getDefaultUserConfigPath() prefers XDG_CONFIG_HOME
* (ambiently set on GitHub Actions ubuntu-latest runners) and, on Windows,
* APPDATA (always set) ahead of the HOME-derived fallback — so on CI the
* scaffolded file can land outside tmpHome unless the path is pinned
* explicitly, same as tests/unit/config-user.test.ts does.
*/
function runCfg(...args) {
return execFileSync('node', [...NODE_TS_FLAGS, CLI, ...args], {
cwd: tmpDir,
encoding: 'utf-8',
timeout: 30_000,
env: {
...process.env,
HOME: tmpHome,
USERPROFILE: tmpHome,
CODEGRAPH_USER_CONFIG: userConfigPath,
XDG_CONFIG_HOME: undefined,
APPDATA: undefined,
},
});
}

beforeAll(() => {
tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraph-cfghome-'));
userConfigPath = path.join(tmpHome, '.config', 'codegraph', 'config.json');
});

afterAll(() => {
if (tmpHome) fs.rmSync(tmpHome, { recursive: true, force: true });
});

test('config --init scaffolds an embeddings section alongside llm', () => {
runCfg('config', '--init');
const scaffolded = JSON.parse(fs.readFileSync(userConfigPath, 'utf-8'));

expect(scaffolded.embeddings).toEqual({ model: null, llmProvider: null, provider: null });
expect(scaffolded.llm).toHaveProperty('baseUrl');
expect(scaffolded.llm).toHaveProperty('apiKeyCommand');
});
});
Loading