mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-21 17:27:54 +00:00
Initial commit of Gemini Code CLI
This commit introduces the initial codebase for the Gemini Code CLI, a command-line interface designed to facilitate interaction with the Gemini API for software engineering tasks.
The code was migrated from a previous git repository as a single squashed commit.
Core Features & Components:
* **Gemini Integration:** Leverages the `@google/genai` SDK to interact with the Gemini models, supporting chat history, streaming responses, and function calling (tools).
* **Terminal UI:** Built with Ink (React for CLIs) providing an interactive chat interface within the terminal, including input prompts, message display, loading indicators, and tool interaction elements.
* **Tooling Framework:** Implements a robust tool system allowing Gemini to interact with the local environment. Includes tools for:
* File system listing (`ls`)
* File reading (`read-file`)
* Content searching (`grep`)
* File globbing (`glob`)
* File editing (`edit`)
* File writing (`write-file`)
* Executing bash commands (`terminal`)
* **State Management:** Handles the streaming state of Gemini responses and manages the conversation history.
* **Configuration:** Parses command-line arguments (`yargs`) and loads environment variables (`dotenv`) for setup.
* **Project Structure:** Organized into `core`, `ui`, `tools`, `config`, and `utils` directories using TypeScript. Includes basic build (`tsc`) and start scripts.
This initial version establishes the foundation for a powerful CLI tool enabling developers to use Gemini for coding assistance directly in their terminal environment.
---
Created by yours truly: __Gemini Code__
This commit is contained in:
34
packages/cli/src/config/args.ts
Normal file
34
packages/cli/src/config/args.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import yargs from 'yargs/yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
|
||||
export interface CliArgs {
|
||||
target_dir: string | undefined;
|
||||
_: (string | number)[]; // Captures positional arguments
|
||||
// Add other expected args here if needed
|
||||
// e.g., verbose?: boolean;
|
||||
}
|
||||
|
||||
export async function parseArguments(): Promise<CliArgs> {
|
||||
const argv = await yargs(hideBin(process.argv))
|
||||
.option('target_dir', {
|
||||
alias: 'd',
|
||||
type: 'string',
|
||||
description:
|
||||
'The target directory for Gemini operations. Defaults to the current working directory.',
|
||||
})
|
||||
.help()
|
||||
.alias('h', 'help')
|
||||
.strict() // Keep strict mode to error on unknown options
|
||||
.parseAsync();
|
||||
|
||||
// Handle warnings for extra arguments here
|
||||
if (argv._ && argv._.length > 0) {
|
||||
console.warn(
|
||||
`Warning: Additional arguments provided (${argv._.join(', ')}), but will be ignored.`
|
||||
);
|
||||
}
|
||||
|
||||
// Cast to the interface to ensure the structure aligns with expectations
|
||||
// Use `unknown` first for safer casting if types might not perfectly match
|
||||
return argv as unknown as CliArgs;
|
||||
}
|
||||
46
packages/cli/src/config/env.ts
Normal file
46
packages/cli/src/config/env.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import * as dotenv from 'dotenv';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import process from 'node:process';
|
||||
|
||||
function findEnvFile(startDir: string): string | null {
|
||||
// Start search from the provided directory (e.g., current working directory)
|
||||
let currentDir = path.resolve(startDir); // Ensure absolute path
|
||||
while (true) {
|
||||
const envPath = path.join(currentDir, '.env');
|
||||
if (fs.existsSync(envPath)) {
|
||||
return envPath;
|
||||
}
|
||||
|
||||
const parentDir = path.dirname(currentDir);
|
||||
if (parentDir === currentDir || !parentDir) {
|
||||
return null;
|
||||
}
|
||||
currentDir = parentDir;
|
||||
}
|
||||
}
|
||||
|
||||
export function loadEnvironment(): void {
|
||||
// Start searching from the current working directory by default
|
||||
const envFilePath = findEnvFile(process.cwd());
|
||||
|
||||
if (!envFilePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
dotenv.config({ path: envFilePath });
|
||||
|
||||
if (!process.env.GEMINI_API_KEY) {
|
||||
console.error('Error: GEMINI_API_KEY environment variable is not set in the loaded .env file.');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
export function getApiKey(): string {
|
||||
loadEnvironment();
|
||||
const apiKey = process.env.GEMINI_API_KEY;
|
||||
if (!apiKey) {
|
||||
throw new Error('GEMINI_API_KEY is missing. Ensure loadEnvironment() was called successfully.');
|
||||
}
|
||||
return apiKey;
|
||||
}
|
||||
Reference in New Issue
Block a user