gencode-ai 0.1.3 → 0.3.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 +44 -2
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +130 -11
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/types.d.ts +11 -1
- 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 +171 -14
- 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 +12 -3
- 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/ModelSelector.d.ts +4 -3
- package/dist/cli/components/ModelSelector.d.ts.map +1 -1
- package/dist/cli/components/ModelSelector.js +54 -37
- package/dist/cli/components/ModelSelector.js.map +1 -1
- 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/ProviderManager.d.ts +2 -2
- package/dist/cli/components/ProviderManager.d.ts.map +1 -1
- package/dist/cli/components/ProviderManager.js +137 -156
- package/dist/cli/components/ProviderManager.js.map +1 -1
- 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/cli/index.js +30 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/levels.d.ts +5 -5
- package/dist/config/levels.d.ts.map +1 -1
- package/dist/config/levels.js +20 -20
- package/dist/config/levels.js.map +1 -1
- package/dist/config/merger.js +1 -1
- package/dist/config/merger.js.map +1 -1
- package/dist/config/providers-config.d.ts +8 -5
- package/dist/config/providers-config.d.ts.map +1 -1
- package/dist/config/providers-config.js +19 -22
- package/dist/config/providers-config.js.map +1 -1
- package/dist/config/test-utils.d.ts +2 -2
- package/dist/config/test-utils.d.ts.map +1 -1
- package/dist/config/test-utils.js +4 -4
- package/dist/config/test-utils.js.map +1 -1
- package/dist/config/types.d.ts +23 -17
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +14 -14
- package/dist/config/types.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/memory/memory-manager.d.ts +25 -12
- package/dist/memory/memory-manager.d.ts.map +1 -1
- package/dist/memory/memory-manager.js +241 -112
- package/dist/memory/memory-manager.js.map +1 -1
- package/dist/memory/test-utils.d.ts +1 -1
- package/dist/memory/test-utils.d.ts.map +1 -1
- package/dist/memory/test-utils.js +3 -3
- package/dist/memory/test-utils.js.map +1 -1
- package/dist/memory/types.d.ts +20 -10
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +13 -13
- package/dist/memory/types.js.map +1 -1
- package/dist/migration/migrate.d.ts +24 -0
- package/dist/migration/migrate.d.ts.map +1 -0
- package/dist/migration/migrate.js +164 -0
- package/dist/migration/migrate.js.map +1 -0
- package/dist/permissions/persistence.d.ts +2 -2
- package/dist/permissions/persistence.js +4 -4
- package/dist/permissions/persistence.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/prompts/index.d.ts +5 -4
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +11 -8
- package/dist/prompts/index.js.map +1 -1
- package/dist/providers/anthropic.d.ts +2 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +24 -10
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/gemini.d.ts +2 -1
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +28 -14
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/index.d.ts +20 -10
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +48 -24
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/openai.d.ts +2 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +19 -8
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/registry.d.ts +48 -34
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +72 -88
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/store.d.ts +43 -17
- package/dist/providers/store.d.ts.map +1 -1
- package/dist/providers/store.js +112 -19
- package/dist/providers/store.js.map +1 -1
- package/dist/providers/types.d.ts +25 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/vertex-ai.d.ts +15 -7
- package/dist/providers/vertex-ai.d.ts.map +1 -1
- package/dist/providers/vertex-ai.js +63 -23
- 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/session/types.js +1 -1
- package/dist/session/types.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/config-system-comparison.md +50 -50
- package/docs/cost-tracking-comparison.md +904 -0
- package/docs/memory-system.md +124 -31
- package/docs/operating-modes.md +96 -0
- package/docs/permissions.md +2 -2
- package/docs/proposals/0006-memory-system.md +4 -4
- package/docs/proposals/0008-checkpointing.md +109 -2
- package/docs/proposals/0011-custom-commands.md +2 -1
- package/docs/proposals/0021-skills-system.md +2 -1
- package/docs/proposals/0023-permission-enhancements.md +2 -2
- package/docs/proposals/0025-cost-tracking.md +60 -2
- package/docs/proposals/0033-enterprise-deployment.md +1 -1
- package/docs/proposals/0041-configuration-system.md +17 -19
- package/docs/proposals/0042-prompt-optimization.md +17 -9
- package/docs/proposals/README.md +6 -6
- package/docs/providers.md +94 -9
- 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 +3 -2
- package/scripts/migrate.ts +449 -0
- package/src/agent/agent.ts +161 -12
- package/src/agent/types.ts +11 -1
- 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 +221 -13
- package/src/cli/components/CommandSuggestions.tsx +5 -0
- package/src/cli/components/Messages.tsx +24 -5
- package/src/cli/components/ModeIndicator.tsx +174 -0
- package/src/cli/components/ModelSelector.tsx +62 -43
- package/src/cli/components/PlanApproval.tsx +327 -0
- package/src/cli/components/ProviderManager.tsx +278 -323
- package/src/cli/components/theme.ts +3 -0
- package/src/cli/index.tsx +36 -17
- package/src/config/index.ts +5 -3
- package/src/config/levels.test.ts +22 -22
- package/src/config/levels.ts +22 -22
- package/src/config/loader.test.ts +14 -14
- package/src/config/manager.test.ts +19 -19
- package/src/config/merger.test.ts +23 -23
- package/src/config/merger.ts +1 -1
- package/src/config/providers-config.ts +23 -21
- package/src/config/test-utils.ts +6 -6
- package/src/config/types.ts +30 -20
- package/src/index.ts +15 -0
- package/src/memory/memory-manager.test.ts +242 -24
- package/src/memory/memory-manager.ts +270 -141
- package/src/memory/test-utils.ts +4 -4
- package/src/memory/types.ts +28 -17
- package/src/permissions/persistence.ts +4 -4
- 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/prompts/index.ts +13 -9
- package/src/providers/anthropic.ts +30 -10
- package/src/providers/gemini.ts +34 -14
- package/src/providers/index.ts +76 -33
- package/src/providers/openai.ts +26 -8
- package/src/providers/registry.ts +116 -111
- package/src/providers/store.ts +130 -28
- package/src/providers/types.ts +36 -1
- package/src/providers/vertex-ai.ts +70 -23
- package/src/session/manager.ts +9 -0
- package/src/session/types.ts +1 -1
- 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
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Supports Claude models
|
|
2
|
+
* Anthropic Vertex AI Provider
|
|
3
|
+
* Supports Claude models via Google Cloud Vertex AI
|
|
4
|
+
*
|
|
5
|
+
* Documentation: https://code.claude.com/docs/en/google-vertex-ai
|
|
6
|
+
*
|
|
7
|
+
* Required environment variables:
|
|
8
|
+
* - CLAUDE_CODE_USE_VERTEX=1
|
|
9
|
+
* - ANTHROPIC_VERTEX_PROJECT_ID=your-project-id
|
|
10
|
+
* - CLOUD_ML_REGION=global (or specific region like us-east5)
|
|
4
11
|
*
|
|
5
12
|
* Authentication uses Google Cloud's default credential chain:
|
|
6
|
-
* 1.
|
|
7
|
-
* 2.
|
|
13
|
+
* 1. gcloud auth application-default login (recommended)
|
|
14
|
+
* 2. GOOGLE_APPLICATION_CREDENTIALS (service account JSON)
|
|
8
15
|
* 3. GCE/GKE metadata service (when running on GCP)
|
|
9
16
|
*/
|
|
10
17
|
|
|
11
18
|
import { GoogleAuth } from 'google-auth-library';
|
|
19
|
+
import { calculateCost } from '../pricing/calculator.js';
|
|
12
20
|
import type {
|
|
13
21
|
LLMProvider,
|
|
22
|
+
ProviderClassMeta,
|
|
14
23
|
CompletionOptions,
|
|
15
24
|
CompletionResponse,
|
|
16
25
|
StreamChunk,
|
|
@@ -128,23 +137,40 @@ type StreamEvent =
|
|
|
128
137
|
| { type: 'message_stop' }
|
|
129
138
|
| { type: 'ping' };
|
|
130
139
|
|
|
131
|
-
export class
|
|
132
|
-
readonly
|
|
140
|
+
export class AnthropicVertexProvider implements LLMProvider {
|
|
141
|
+
static readonly meta: ProviderClassMeta = {
|
|
142
|
+
provider: 'anthropic',
|
|
143
|
+
authMethod: 'vertex',
|
|
144
|
+
envVars: [
|
|
145
|
+
'CLAUDE_CODE_USE_VERTEX',
|
|
146
|
+
'ANTHROPIC_VERTEX_PROJECT_ID',
|
|
147
|
+
'CLOUD_ML_REGION',
|
|
148
|
+
],
|
|
149
|
+
displayName: 'Google Vertex AI',
|
|
150
|
+
description: 'Claude via Google Cloud Platform',
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
readonly name = 'anthropic-vertex';
|
|
133
154
|
private projectId: string;
|
|
134
155
|
private region: string;
|
|
135
156
|
private auth: GoogleAuth;
|
|
136
157
|
private accessToken?: string;
|
|
137
158
|
|
|
138
159
|
constructor(config: VertexAIConfig = {}) {
|
|
160
|
+
// Project ID priority (per Claude Code docs):
|
|
161
|
+
// 1. config.projectId
|
|
162
|
+
// 2. ANTHROPIC_VERTEX_PROJECT_ID
|
|
163
|
+
// 3. GCLOUD_PROJECT
|
|
164
|
+
// 4. GOOGLE_CLOUD_PROJECT
|
|
139
165
|
this.projectId =
|
|
140
166
|
config.projectId ??
|
|
141
167
|
process.env.ANTHROPIC_VERTEX_PROJECT_ID ??
|
|
168
|
+
process.env.GCLOUD_PROJECT ??
|
|
142
169
|
process.env.GOOGLE_CLOUD_PROJECT ??
|
|
143
170
|
'';
|
|
144
171
|
|
|
145
172
|
this.region =
|
|
146
173
|
config.region ??
|
|
147
|
-
process.env.ANTHROPIC_VERTEX_REGION ??
|
|
148
174
|
process.env.CLOUD_ML_REGION ??
|
|
149
175
|
'us-east5';
|
|
150
176
|
|
|
@@ -152,7 +178,7 @@ export class VertexAIProvider implements LLMProvider {
|
|
|
152
178
|
|
|
153
179
|
if (!this.projectId) {
|
|
154
180
|
throw new Error(
|
|
155
|
-
'Vertex AI requires a project ID. Set ANTHROPIC_VERTEX_PROJECT_ID
|
|
181
|
+
'Vertex AI requires a project ID. Set one of: ANTHROPIC_VERTEX_PROJECT_ID, GCLOUD_PROJECT, or GOOGLE_CLOUD_PROJECT'
|
|
156
182
|
);
|
|
157
183
|
}
|
|
158
184
|
|
|
@@ -166,12 +192,23 @@ export class VertexAIProvider implements LLMProvider {
|
|
|
166
192
|
return this.accessToken;
|
|
167
193
|
}
|
|
168
194
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
195
|
+
try {
|
|
196
|
+
const client = await this.auth.getClient();
|
|
197
|
+
const tokenResponse = await client.getAccessToken();
|
|
198
|
+
if (!tokenResponse.token) {
|
|
199
|
+
throw new Error('Failed to get access token from Google Cloud');
|
|
200
|
+
}
|
|
201
|
+
return tokenResponse.token;
|
|
202
|
+
} catch (error) {
|
|
203
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
204
|
+
throw new Error(
|
|
205
|
+
`Failed to authenticate with Google Cloud. Please ensure you have:\n` +
|
|
206
|
+
`1. Run: gcloud auth application-default login\n` +
|
|
207
|
+
`2. Set ANTHROPIC_VERTEX_PROJECT_ID or GOOGLE_CLOUD_PROJECT\n` +
|
|
208
|
+
`3. Enabled Vertex AI API in your GCP project\n` +
|
|
209
|
+
`Original error: ${message}`
|
|
210
|
+
);
|
|
173
211
|
}
|
|
174
|
-
return tokenResponse.token;
|
|
175
212
|
}
|
|
176
213
|
|
|
177
214
|
private getEndpoint(model: string, stream: boolean = false): string {
|
|
@@ -210,7 +247,7 @@ export class VertexAIProvider implements LLMProvider {
|
|
|
210
247
|
}
|
|
211
248
|
|
|
212
249
|
const data = (await response.json()) as VertexAIResponse;
|
|
213
|
-
return this.convertResponse(data);
|
|
250
|
+
return this.convertResponse(data, options.model);
|
|
214
251
|
}
|
|
215
252
|
|
|
216
253
|
async *stream(options: CompletionOptions): AsyncGenerator<StreamChunk, void, unknown> {
|
|
@@ -337,15 +374,20 @@ export class VertexAIProvider implements LLMProvider {
|
|
|
337
374
|
// Build final response
|
|
338
375
|
const content = this.buildFinalContent(contentBlocks, toolInputBuffers);
|
|
339
376
|
|
|
377
|
+
const usage = {
|
|
378
|
+
inputTokens,
|
|
379
|
+
outputTokens,
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
const cost = calculateCost(this.name, options.model, usage);
|
|
383
|
+
|
|
340
384
|
yield {
|
|
341
385
|
type: 'done',
|
|
342
386
|
response: {
|
|
343
387
|
content,
|
|
344
388
|
stopReason,
|
|
345
|
-
usage
|
|
346
|
-
|
|
347
|
-
outputTokens,
|
|
348
|
-
},
|
|
389
|
+
usage,
|
|
390
|
+
cost,
|
|
349
391
|
},
|
|
350
392
|
};
|
|
351
393
|
}
|
|
@@ -449,14 +491,19 @@ export class VertexAIProvider implements LLMProvider {
|
|
|
449
491
|
}));
|
|
450
492
|
}
|
|
451
493
|
|
|
452
|
-
private convertResponse(response: VertexAIResponse): CompletionResponse {
|
|
494
|
+
private convertResponse(response: VertexAIResponse, model: string): CompletionResponse {
|
|
495
|
+
const usage = {
|
|
496
|
+
inputTokens: response.usage.input_tokens,
|
|
497
|
+
outputTokens: response.usage.output_tokens,
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
const cost = calculateCost(this.name, model, usage);
|
|
501
|
+
|
|
453
502
|
return {
|
|
454
503
|
content: this.convertContent(response.content),
|
|
455
504
|
stopReason: this.convertStopReason(response.stop_reason),
|
|
456
|
-
usage
|
|
457
|
-
|
|
458
|
-
outputTokens: response.usage.output_tokens,
|
|
459
|
-
},
|
|
505
|
+
usage,
|
|
506
|
+
cost,
|
|
460
507
|
};
|
|
461
508
|
}
|
|
462
509
|
|
package/src/session/manager.ts
CHANGED
|
@@ -326,6 +326,15 @@ export class SessionManager {
|
|
|
326
326
|
}
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
+
/**
|
|
330
|
+
* Remove the last message from current session
|
|
331
|
+
*/
|
|
332
|
+
removeLastMessage(): void {
|
|
333
|
+
if (this.currentSession && this.currentSession.messages.length > 0) {
|
|
334
|
+
this.currentSession.messages.pop();
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
329
338
|
/**
|
|
330
339
|
* Export session to JSON
|
|
331
340
|
*/
|
package/src/session/types.ts
CHANGED
package/src/tools/index.ts
CHANGED
|
@@ -28,6 +28,9 @@ export type {
|
|
|
28
28
|
AskUserQuestionResult,
|
|
29
29
|
} from './builtin/ask-user.js';
|
|
30
30
|
|
|
31
|
+
// Plan mode tools
|
|
32
|
+
export { enterPlanModeTool, exitPlanModeTool } from '../planning/index.js';
|
|
33
|
+
|
|
31
34
|
import { ToolRegistry } from './registry.js';
|
|
32
35
|
import { readTool } from './builtin/read.js';
|
|
33
36
|
import { writeTool } from './builtin/write.js';
|
|
@@ -39,6 +42,7 @@ import { webfetchTool } from './builtin/webfetch.js';
|
|
|
39
42
|
import { websearchTool } from './builtin/websearch.js';
|
|
40
43
|
import { todowriteTool } from './builtin/todowrite.js';
|
|
41
44
|
import { askUserQuestionTool } from './builtin/ask-user.js';
|
|
45
|
+
import { enterPlanModeTool, exitPlanModeTool } from '../planning/index.js';
|
|
42
46
|
|
|
43
47
|
/**
|
|
44
48
|
* Create a registry with all built-in tools
|
|
@@ -56,6 +60,8 @@ export function createDefaultRegistry(): ToolRegistry {
|
|
|
56
60
|
websearchTool,
|
|
57
61
|
todowriteTool,
|
|
58
62
|
askUserQuestionTool,
|
|
63
|
+
enterPlanModeTool,
|
|
64
|
+
exitPlanModeTool,
|
|
59
65
|
]);
|
|
60
66
|
return registry;
|
|
61
67
|
}
|
|
@@ -74,4 +80,6 @@ export const builtinTools = [
|
|
|
74
80
|
websearchTool,
|
|
75
81
|
todowriteTool,
|
|
76
82
|
askUserQuestionTool,
|
|
83
|
+
enterPlanModeTool,
|
|
84
|
+
exitPlanModeTool,
|
|
77
85
|
];
|
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
|