gencode-ai 0.1.3 → 0.2.0
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/README.md +2 -1
- package/dist/agent/agent.d.ts +35 -0
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +93 -3
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/types.d.ts +6 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/checkpointing/checkpoint-manager.d.ts +87 -0
- package/dist/checkpointing/checkpoint-manager.d.ts.map +1 -0
- package/dist/checkpointing/checkpoint-manager.js +281 -0
- package/dist/checkpointing/checkpoint-manager.js.map +1 -0
- package/dist/checkpointing/index.d.ts +29 -0
- package/dist/checkpointing/index.d.ts.map +1 -0
- package/dist/checkpointing/index.js +29 -0
- package/dist/checkpointing/index.js.map +1 -0
- package/dist/checkpointing/types.d.ts +98 -0
- package/dist/checkpointing/types.d.ts.map +1 -0
- package/dist/checkpointing/types.js +7 -0
- package/dist/checkpointing/types.js.map +1 -0
- package/dist/cli/components/App.d.ts.map +1 -1
- package/dist/cli/components/App.js +157 -6
- package/dist/cli/components/App.js.map +1 -1
- package/dist/cli/components/CommandSuggestions.d.ts.map +1 -1
- package/dist/cli/components/CommandSuggestions.js +5 -0
- package/dist/cli/components/CommandSuggestions.js.map +1 -1
- package/dist/cli/components/Messages.d.ts +7 -1
- package/dist/cli/components/Messages.d.ts.map +1 -1
- package/dist/cli/components/Messages.js +11 -2
- package/dist/cli/components/Messages.js.map +1 -1
- package/dist/cli/components/ModeIndicator.d.ts +42 -0
- package/dist/cli/components/ModeIndicator.d.ts.map +1 -0
- package/dist/cli/components/ModeIndicator.js +52 -0
- package/dist/cli/components/ModeIndicator.js.map +1 -0
- package/dist/cli/components/PlanApproval.d.ts +36 -0
- package/dist/cli/components/PlanApproval.d.ts.map +1 -0
- package/dist/cli/components/PlanApproval.js +154 -0
- package/dist/cli/components/PlanApproval.js.map +1 -0
- package/dist/cli/components/theme.d.ts +2 -0
- package/dist/cli/components/theme.d.ts.map +1 -1
- package/dist/cli/components/theme.js +3 -0
- package/dist/cli/components/theme.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/planning/index.d.ts +13 -0
- package/dist/planning/index.d.ts.map +1 -0
- package/dist/planning/index.js +15 -0
- package/dist/planning/index.js.map +1 -0
- package/dist/planning/plan-file.d.ts +59 -0
- package/dist/planning/plan-file.d.ts.map +1 -0
- package/dist/planning/plan-file.js +278 -0
- package/dist/planning/plan-file.js.map +1 -0
- package/dist/planning/state.d.ts +127 -0
- package/dist/planning/state.d.ts.map +1 -0
- package/dist/planning/state.js +261 -0
- package/dist/planning/state.js.map +1 -0
- package/dist/planning/tools/enter-plan-mode.d.ts +25 -0
- package/dist/planning/tools/enter-plan-mode.d.ts.map +1 -0
- package/dist/planning/tools/enter-plan-mode.js +98 -0
- package/dist/planning/tools/enter-plan-mode.js.map +1 -0
- package/dist/planning/tools/exit-plan-mode.d.ts +24 -0
- package/dist/planning/tools/exit-plan-mode.d.ts.map +1 -0
- package/dist/planning/tools/exit-plan-mode.js +149 -0
- package/dist/planning/tools/exit-plan-mode.js.map +1 -0
- package/dist/planning/types.d.ts +100 -0
- package/dist/planning/types.d.ts.map +1 -0
- package/dist/planning/types.js +28 -0
- package/dist/planning/types.js.map +1 -0
- package/dist/pricing/calculator.d.ts +21 -0
- package/dist/pricing/calculator.d.ts.map +1 -0
- package/dist/pricing/calculator.js +59 -0
- package/dist/pricing/calculator.js.map +1 -0
- package/dist/pricing/index.d.ts +7 -0
- package/dist/pricing/index.d.ts.map +1 -0
- package/dist/pricing/index.js +7 -0
- package/dist/pricing/index.js.map +1 -0
- package/dist/pricing/models.d.ts +20 -0
- package/dist/pricing/models.d.ts.map +1 -0
- package/dist/pricing/models.js +322 -0
- package/dist/pricing/models.js.map +1 -0
- package/dist/pricing/types.d.ts +30 -0
- package/dist/pricing/types.d.ts.map +1 -0
- package/dist/pricing/types.js +5 -0
- package/dist/pricing/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +17 -10
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +21 -14
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +12 -8
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/types.d.ts +2 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/vertex-ai.d.ts.map +1 -1
- package/dist/providers/vertex-ai.js +17 -10
- package/dist/providers/vertex-ai.js.map +1 -1
- package/dist/session/manager.d.ts +4 -0
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +8 -0
- package/dist/session/manager.js.map +1 -1
- package/dist/tools/index.d.ts +7 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/registry.d.ts +13 -0
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +79 -2
- package/dist/tools/registry.js.map +1 -1
- package/docs/cost-tracking-comparison.md +904 -0
- package/docs/operating-modes.md +96 -0
- package/docs/proposals/0025-cost-tracking.md +60 -2
- package/docs/proposals/README.md +1 -1
- package/examples/test-checkpointing.ts +121 -0
- package/examples/test-cost-tracking.ts +77 -0
- package/examples/test-interrupt-cleanup.ts +94 -0
- package/package.json +1 -1
- package/src/agent/agent.ts +110 -3
- package/src/agent/types.ts +6 -0
- package/src/checkpointing/checkpoint-manager.ts +327 -0
- package/src/checkpointing/index.ts +45 -0
- package/src/checkpointing/types.ts +104 -0
- package/src/cli/components/App.tsx +204 -5
- package/src/cli/components/CommandSuggestions.tsx +5 -0
- package/src/cli/components/Messages.tsx +23 -4
- package/src/cli/components/ModeIndicator.tsx +174 -0
- package/src/cli/components/PlanApproval.tsx +327 -0
- package/src/cli/components/theme.ts +3 -0
- package/src/index.ts +15 -0
- package/src/planning/index.ts +53 -0
- package/src/planning/plan-file.ts +326 -0
- package/src/planning/state.ts +305 -0
- package/src/planning/tools/enter-plan-mode.ts +111 -0
- package/src/planning/tools/exit-plan-mode.ts +170 -0
- package/src/planning/types.ts +150 -0
- package/src/pricing/calculator.ts +71 -0
- package/src/pricing/index.ts +7 -0
- package/src/pricing/models.ts +334 -0
- package/src/pricing/types.ts +32 -0
- package/src/providers/anthropic.ts +21 -10
- package/src/providers/gemini.ts +25 -14
- package/src/providers/openai.ts +17 -8
- package/src/providers/types.ts +3 -0
- package/src/providers/vertex-ai.ts +21 -10
- package/src/session/manager.ts +9 -0
- package/src/tools/index.ts +8 -0
- package/src/tools/registry.ts +95 -2
- package/.gencode/settings.local.json +0 -7
- package/CLAUDE.md +0 -86
package/src/tools/registry.ts
CHANGED
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
* Tool Registry - Manages available tools
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import * as fs from 'fs/promises';
|
|
5
6
|
import type { Tool, ToolContext, ToolResult } from './types.js';
|
|
6
|
-
import { zodToJsonSchema, getErrorMessage } from './types.js';
|
|
7
|
+
import { zodToJsonSchema, getErrorMessage, resolvePath } from './types.js';
|
|
7
8
|
import type { ToolDefinition } from '../providers/types.js';
|
|
9
|
+
import { getPlanModeManager } from '../planning/index.js';
|
|
10
|
+
import { getCheckpointManager } from '../checkpointing/index.js';
|
|
11
|
+
import type { ChangeType } from '../checkpointing/index.js';
|
|
12
|
+
|
|
13
|
+
// Tools that modify files and should be tracked for checkpointing
|
|
14
|
+
const CHECKPOINT_TOOLS = ['Write', 'Edit'];
|
|
8
15
|
|
|
9
16
|
export class ToolRegistry {
|
|
10
17
|
private tools: Map<string, Tool> = new Map();
|
|
@@ -50,6 +57,20 @@ export class ToolRegistry {
|
|
|
50
57
|
.filter((t): t is ToolDefinition => t !== null);
|
|
51
58
|
}
|
|
52
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Get tool definitions filtered by plan mode
|
|
62
|
+
* In plan mode, only read-only tools are returned
|
|
63
|
+
*/
|
|
64
|
+
getFilteredDefinitions(toolNames?: string[]): ToolDefinition[] {
|
|
65
|
+
const planManager = getPlanModeManager();
|
|
66
|
+
const names = toolNames ?? this.list();
|
|
67
|
+
|
|
68
|
+
// Filter tools based on plan mode state
|
|
69
|
+
const filteredNames = planManager.filterTools(names);
|
|
70
|
+
|
|
71
|
+
return this.getDefinitions(filteredNames);
|
|
72
|
+
}
|
|
73
|
+
|
|
53
74
|
/**
|
|
54
75
|
* Execute a tool by name
|
|
55
76
|
*/
|
|
@@ -75,9 +96,81 @@ export class ToolRegistry {
|
|
|
75
96
|
};
|
|
76
97
|
}
|
|
77
98
|
|
|
78
|
-
|
|
99
|
+
// Capture pre-execution state for checkpointing
|
|
100
|
+
let preState: { filePath: string; content: string | null; existed: boolean } | null = null;
|
|
101
|
+
if (CHECKPOINT_TOOLS.includes(name) && parsed.data && typeof parsed.data === 'object') {
|
|
102
|
+
const filePath = (parsed.data as { file_path?: string }).file_path;
|
|
103
|
+
if (filePath) {
|
|
104
|
+
preState = await this.captureFileState(filePath, context.cwd);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Execute the tool
|
|
109
|
+
const result = await tool.execute(parsed.data, context);
|
|
110
|
+
|
|
111
|
+
// Record checkpoint on successful file modification
|
|
112
|
+
if (result.success && preState) {
|
|
113
|
+
await this.recordCheckpoint(name, preState, context.cwd);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return result;
|
|
79
117
|
} catch (error) {
|
|
80
118
|
return { success: false, output: '', error: `Tool execution failed: ${getErrorMessage(error)}` };
|
|
81
119
|
}
|
|
82
120
|
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Capture file state before modification
|
|
124
|
+
*/
|
|
125
|
+
private async captureFileState(
|
|
126
|
+
filePath: string,
|
|
127
|
+
cwd: string
|
|
128
|
+
): Promise<{ filePath: string; content: string | null; existed: boolean }> {
|
|
129
|
+
const resolvedPath = resolvePath(filePath, cwd);
|
|
130
|
+
try {
|
|
131
|
+
const content = await fs.readFile(resolvedPath, 'utf-8');
|
|
132
|
+
return { filePath: resolvedPath, content, existed: true };
|
|
133
|
+
} catch {
|
|
134
|
+
// File doesn't exist
|
|
135
|
+
return { filePath: resolvedPath, content: null, existed: false };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Record a checkpoint after file modification
|
|
141
|
+
*/
|
|
142
|
+
private async recordCheckpoint(
|
|
143
|
+
toolName: string,
|
|
144
|
+
preState: { filePath: string; content: string | null; existed: boolean },
|
|
145
|
+
cwd: string
|
|
146
|
+
): Promise<void> {
|
|
147
|
+
const checkpointManager = getCheckpointManager();
|
|
148
|
+
|
|
149
|
+
// Read current file content
|
|
150
|
+
let newContent: string | null = null;
|
|
151
|
+
try {
|
|
152
|
+
newContent = await fs.readFile(preState.filePath, 'utf-8');
|
|
153
|
+
} catch {
|
|
154
|
+
// File was deleted or doesn't exist
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Determine change type
|
|
158
|
+
let changeType: ChangeType;
|
|
159
|
+
if (!preState.existed && newContent !== null) {
|
|
160
|
+
changeType = 'create';
|
|
161
|
+
} else if (preState.existed && newContent === null) {
|
|
162
|
+
changeType = 'delete';
|
|
163
|
+
} else {
|
|
164
|
+
changeType = 'modify';
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Record the change
|
|
168
|
+
checkpointManager.recordChange({
|
|
169
|
+
path: preState.filePath,
|
|
170
|
+
changeType,
|
|
171
|
+
previousContent: preState.content,
|
|
172
|
+
newContent,
|
|
173
|
+
toolName,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
83
176
|
}
|
package/CLAUDE.md
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
-
|
|
5
|
-
## Project Overview
|
|
6
|
-
|
|
7
|
-
**GenCode** (npm: `gencode-ai`) is an open-source AI assistant for the terminal. Extensible tools, customizable prompts, multi-provider support.
|
|
8
|
-
|
|
9
|
-
## Build & Run Commands
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm install # Install dependencies
|
|
13
|
-
npm run build # Compile TypeScript to dist/
|
|
14
|
-
npm run dev # Watch mode compilation
|
|
15
|
-
npm start # Run CLI directly via tsx
|
|
16
|
-
npm run example # Run examples/basic.ts
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Architecture
|
|
20
|
-
|
|
21
|
-
### Provider Abstraction Layer (`src/providers/`)
|
|
22
|
-
|
|
23
|
-
Unified `LLMProvider` interface abstracts API differences:
|
|
24
|
-
- `complete()` - Non-streaming completion
|
|
25
|
-
- `stream()` - Streaming completion (AsyncGenerator)
|
|
26
|
-
|
|
27
|
-
Each provider (OpenAI, Anthropic, Gemini) translates the unified message format to its native API format and back. The `createProvider()` factory instantiates providers by name.
|
|
28
|
-
|
|
29
|
-
### Tool System (`src/tools/`)
|
|
30
|
-
|
|
31
|
-
Tools are defined with Zod schemas for input validation:
|
|
32
|
-
```typescript
|
|
33
|
-
interface Tool<TInput> {
|
|
34
|
-
name: string;
|
|
35
|
-
description: string;
|
|
36
|
-
parameters: z.ZodSchema<TInput>;
|
|
37
|
-
execute(input: TInput, context: ToolContext): Promise<ToolResult>;
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
`ToolRegistry` manages tools and converts Zod schemas to JSON Schema for LLM consumption via `zodToJsonSchema()`.
|
|
42
|
-
|
|
43
|
-
### Agent Loop (`src/agent/agent.ts`)
|
|
44
|
-
|
|
45
|
-
The `Agent` class implements the core conversation loop:
|
|
46
|
-
1. User message → LLM with tools
|
|
47
|
-
2. If `stopReason === 'tool_use'`: execute tools, append results, loop back
|
|
48
|
-
3. If `stopReason !== 'tool_use'`: done
|
|
49
|
-
|
|
50
|
-
Events are yielded as `AgentEvent` (text, tool_start, tool_result, done, error).
|
|
51
|
-
|
|
52
|
-
### Session Management (`src/session/`)
|
|
53
|
-
|
|
54
|
-
Sessions persist conversation history to `~/.gencode/sessions/` as JSON files. Supports resume, fork, list, and delete operations.
|
|
55
|
-
|
|
56
|
-
## Configuration
|
|
57
|
-
|
|
58
|
-
Provider/model selection priority:
|
|
59
|
-
1. `GENCODE_PROVIDER` / `GENCODE_MODEL` env vars
|
|
60
|
-
2. Auto-detect from available API keys (ANTHROPIC_API_KEY → OPENAI_API_KEY → GOOGLE_API_KEY)
|
|
61
|
-
3. Default: Gemini
|
|
62
|
-
|
|
63
|
-
Proxy: Set `HTTP_PROXY` or `HTTPS_PROXY` for network proxy support.
|
|
64
|
-
|
|
65
|
-
## Key Patterns
|
|
66
|
-
|
|
67
|
-
- All file paths in tools should be resolved relative to `ToolContext.cwd`
|
|
68
|
-
- Tool input validation uses Zod; errors returned as `ToolResult.error`
|
|
69
|
-
- Provider implementations handle message format conversion internally
|
|
70
|
-
- CLI commands start with `/` (e.g., `/sessions`, `/resume`, `/help`)
|
|
71
|
-
|
|
72
|
-
## Reference Projects
|
|
73
|
-
|
|
74
|
-
Similar projects for learning and reference:
|
|
75
|
-
|
|
76
|
-
| Project | Path | Description |
|
|
77
|
-
|---------|------|-------------|
|
|
78
|
-
| OpenCode | `/Users/myan/Workspace/opencode` | Go-based AI coding assistant with TUI, multi-provider support |
|
|
79
|
-
| System Prompts Collection | `/Users/myan/Workspace/ideas/system-prompts-and-models-of-ai-tools` | Collection of system prompts from various AI tools (Claude Code, Cursor, etc.) |
|
|
80
|
-
| Learn Claude Code | `/Users/myan/Workspace/ideas/learn-claude-code` | Educational resources for understanding Claude Code internals |
|
|
81
|
-
|
|
82
|
-
### Key Learnings from References
|
|
83
|
-
|
|
84
|
-
- **OpenCode**: Go implementation with Ink-based TUI, LSP integration, conversation sessions
|
|
85
|
-
- **System Prompts**: Study prompt engineering patterns used by production AI tools
|
|
86
|
-
- **Learn Claude Code**: Understand Claude Code's tool system, agent loop, and UX patterns
|