gencode-ai 0.1.2 → 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 +15 -17
- package/dist/agent/agent.d.ts +43 -0
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +107 -4
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/types.d.ts +20 -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 +193 -7
- 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 +28 -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/QuestionPrompt.d.ts +23 -0
- package/dist/cli/components/QuestionPrompt.d.ts.map +1 -0
- package/dist/cli/components/QuestionPrompt.js +231 -0
- package/dist/cli/components/QuestionPrompt.js.map +1 -0
- package/dist/cli/components/index.d.ts +1 -0
- package/dist/cli/components/index.d.ts.map +1 -1
- package/dist/cli/components/index.js +1 -0
- package/dist/cli/components/index.js.map +1 -1
- package/dist/cli/components/theme.d.ts +9 -0
- package/dist/cli/components/theme.d.ts.map +1 -1
- package/dist/cli/components/theme.js +14 -1
- 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/permissions/types.d.ts.map +1 -1
- package/dist/permissions/types.js +2 -0
- package/dist/permissions/types.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/builtin/ask-user.d.ts +64 -0
- package/dist/tools/builtin/ask-user.d.ts.map +1 -0
- package/dist/tools/builtin/ask-user.js +148 -0
- package/dist/tools/builtin/ask-user.js.map +1 -0
- package/dist/tools/index.d.ts +19 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +11 -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/dist/tools/types.d.ts +17 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/docs/cost-tracking-comparison.md +904 -0
- package/docs/operating-modes.md +96 -0
- package/docs/proposals/0012-ask-user-question.md +66 -1
- package/docs/proposals/0025-cost-tracking.md +60 -2
- package/docs/proposals/README.md +2 -2
- package/examples/test-ask-user.ts +167 -0
- 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 +130 -4
- package/src/agent/index.ts +1 -0
- package/src/agent/types.ts +19 -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 +259 -8
- package/src/cli/components/CommandSuggestions.tsx +5 -0
- package/src/cli/components/Messages.tsx +66 -4
- package/src/cli/components/ModeIndicator.tsx +174 -0
- package/src/cli/components/PlanApproval.tsx +327 -0
- package/src/cli/components/QuestionPrompt.tsx +462 -0
- package/src/cli/components/index.ts +1 -0
- package/src/cli/components/theme.ts +14 -1
- package/src/index.ts +15 -0
- package/src/permissions/types.ts +2 -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/prompts/system/base.txt +42 -0
- package/src/prompts/tools/ask-user.txt +110 -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/builtin/ask-user.ts +185 -0
- package/src/tools/index.ts +23 -0
- package/src/tools/registry.ts +95 -2
- package/src/tools/types.ts +18 -0
- package/.gencode/settings.local.json +0 -7
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Operating Modes
|
|
2
|
+
|
|
3
|
+
> Reference: [Claude Code](https://claude.ai/code) operating modes
|
|
4
|
+
|
|
5
|
+
GenCode has **3 operating modes** that can be cycled with `Shift+Tab`:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Normal (default)
|
|
9
|
+
↓ Shift+Tab
|
|
10
|
+
Plan (⏸ plan mode on)
|
|
11
|
+
↓ Shift+Tab
|
|
12
|
+
Accept (⏵⏵ accept edits on)
|
|
13
|
+
↓ Shift+Tab
|
|
14
|
+
Normal
|
|
15
|
+
...
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Mode Comparison
|
|
19
|
+
|
|
20
|
+
| Mode | Status Indicator | Edit Confirmation | Available Tools |
|
|
21
|
+
|------|------------------|-------------------|-----------------|
|
|
22
|
+
| **Normal** | _(none)_ | Required | All |
|
|
23
|
+
| **Plan** | `⏸ plan mode on (shift+tab to cycle)` | N/A (edits blocked) | Read-only |
|
|
24
|
+
| **Accept** | `⏵⏵ accept edits on (shift+tab to cycle)` | Auto-approved | All |
|
|
25
|
+
|
|
26
|
+
## Mode Details
|
|
27
|
+
|
|
28
|
+
### 1. Normal Mode (Default)
|
|
29
|
+
|
|
30
|
+
- Normal execution mode
|
|
31
|
+
- Every Write/Edit operation requires user confirmation
|
|
32
|
+
- All tools available
|
|
33
|
+
- Default mode when GenCode starts
|
|
34
|
+
|
|
35
|
+
### 2. Plan Mode
|
|
36
|
+
|
|
37
|
+
- Read-only exploration mode for designing implementation approaches
|
|
38
|
+
- Write, Edit, and Bash tools are blocked
|
|
39
|
+
- Used for understanding codebase and creating implementation plans
|
|
40
|
+
|
|
41
|
+
**Allowed Tools:** Read, Glob, Grep, WebFetch, WebSearch, TodoWrite, AskUserQuestion
|
|
42
|
+
|
|
43
|
+
**Blocked Tools:** Write, Edit, Bash
|
|
44
|
+
|
|
45
|
+
### 3. Auto-accept Mode
|
|
46
|
+
|
|
47
|
+
- Automatic edit acceptance mode
|
|
48
|
+
- Write/Edit operations are automatically approved without confirmation
|
|
49
|
+
- Useful when trusting the agent or after approving a plan
|
|
50
|
+
- **Caution**: May cause unintended file changes
|
|
51
|
+
|
|
52
|
+
## Plan Mode Workflow
|
|
53
|
+
|
|
54
|
+
When in Plan mode, the agent goes through 5 phases:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
EnterPlanMode
|
|
58
|
+
↓
|
|
59
|
+
┌─────────────┐
|
|
60
|
+
│Understanding│ ← Explore codebase
|
|
61
|
+
└──────┬──────┘
|
|
62
|
+
↓
|
|
63
|
+
┌─────────────┐
|
|
64
|
+
│ Design │ ← Design approach
|
|
65
|
+
└──────┬──────┘
|
|
66
|
+
↓
|
|
67
|
+
┌─────────────┐
|
|
68
|
+
│ Review │ ← (Optional) Clarify requirements
|
|
69
|
+
└──────┬──────┘
|
|
70
|
+
↓
|
|
71
|
+
┌─────────────┐
|
|
72
|
+
│ Final │ ← Write plan to file
|
|
73
|
+
└──────┬──────┘
|
|
74
|
+
↓
|
|
75
|
+
ExitPlanMode
|
|
76
|
+
↓
|
|
77
|
+
┌─────────────┐
|
|
78
|
+
│ Approval │ ← User approves/modifies/cancels
|
|
79
|
+
└─────────────┘
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Plan Approval Options
|
|
83
|
+
|
|
84
|
+
When exiting Plan mode:
|
|
85
|
+
|
|
86
|
+
| Option | Description | Next Mode |
|
|
87
|
+
|--------|-------------|-----------|
|
|
88
|
+
| **approve** | Accept plan, auto-accept edits | Accept |
|
|
89
|
+
| **approve_manual** | Accept plan, manually approve each edit | Normal |
|
|
90
|
+
| **modify** | Return to modify the plan | Plan |
|
|
91
|
+
| **cancel** | Cancel plan entirely | Normal |
|
|
92
|
+
|
|
93
|
+
## References
|
|
94
|
+
|
|
95
|
+
- [Claude Code Best Practices](https://www.anthropic.com/engineering/claude-code-best-practices)
|
|
96
|
+
- [Plan Mode Proposal](./proposals/0004-plan-mode.md)
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
- **Proposal ID**: 0012
|
|
4
4
|
- **Author**: gencode team
|
|
5
|
-
- **Status**:
|
|
5
|
+
- **Status**: Implemented
|
|
6
6
|
- **Created**: 2025-01-15
|
|
7
7
|
- **Updated**: 2025-01-16
|
|
8
|
+
- **Implemented**: 2025-01-16
|
|
8
9
|
|
|
9
10
|
## Summary
|
|
10
11
|
|
|
@@ -1014,6 +1015,70 @@ describe('AskUserQuestion Integration', () => {
|
|
|
1014
1015
|
|
|
1015
1016
|
No breaking changes to existing functionality.
|
|
1016
1017
|
|
|
1018
|
+
## Implementation Notes
|
|
1019
|
+
|
|
1020
|
+
### Files Created/Modified
|
|
1021
|
+
|
|
1022
|
+
| File | Action | Description |
|
|
1023
|
+
|------|--------|-------------|
|
|
1024
|
+
| `src/tools/builtin/ask-user.ts` | Created | Tool implementation with Zod schemas |
|
|
1025
|
+
| `src/tools/types.ts` | Modified | Added Question/QuestionAnswer interfaces to ToolContext |
|
|
1026
|
+
| `src/tools/index.ts` | Modified | Registered and exported askUserQuestionTool |
|
|
1027
|
+
| `src/agent/types.ts` | Modified | Added AgentEventAskUser type |
|
|
1028
|
+
| `src/agent/agent.ts` | Modified | Added askUserCallback and toolContext integration |
|
|
1029
|
+
| `src/agent/index.ts` | Modified | Exported AskUserCallback type |
|
|
1030
|
+
| `src/cli/components/QuestionPrompt.tsx` | Created | Question UI component with Claude Code style |
|
|
1031
|
+
| `src/cli/components/App.tsx` | Modified | Integrated QuestionPrompt and state management |
|
|
1032
|
+
| `src/cli/components/theme.ts` | Modified | Added new icons for checkboxes and chips |
|
|
1033
|
+
| `src/cli/components/index.ts` | Modified | Exported QuestionPrompt and AnswerDisplay |
|
|
1034
|
+
| `src/prompts/tools/ask-user.txt` | Created | Tool description for LLM |
|
|
1035
|
+
|
|
1036
|
+
### Key Implementation Details
|
|
1037
|
+
|
|
1038
|
+
1. **Callback-based architecture**: The tool uses a callback (`askUser`) injected via `ToolContext` to communicate with the CLI layer
|
|
1039
|
+
2. **Promise-based async flow**: Questions block agent execution until user responds
|
|
1040
|
+
3. **Claude Code UI alignment**: Uses radio buttons (○/●), checkboxes (☐/☑), chip headers, and matching color scheme
|
|
1041
|
+
4. **Auto-added "Other" option**: Every question automatically includes an "Other" option for custom input
|
|
1042
|
+
5. **Multi-select support**: Full support for both single-select and multi-select modes
|
|
1043
|
+
|
|
1044
|
+
### Prompt Guidance (Critical for LLM Tool Usage)
|
|
1045
|
+
|
|
1046
|
+
The system prompt in `src/prompts/system/base.txt` includes explicit guidance with bad examples to ensure the LLM uses the tool instead of plain text:
|
|
1047
|
+
|
|
1048
|
+
```
|
|
1049
|
+
CRITICAL: You MUST use the AskUserQuestion tool for ALL questions with choices.
|
|
1050
|
+
NEVER write numbered lists, bullet points, or "which do you prefer" questions as plain text.
|
|
1051
|
+
|
|
1052
|
+
## Wrong - Plain Text Questions (DO NOT DO THIS)
|
|
1053
|
+
|
|
1054
|
+
<bad-example>
|
|
1055
|
+
user: Set up a new database
|
|
1056
|
+
assistant: I can set up a database for you. Which one would you prefer?
|
|
1057
|
+
1. PostgreSQL - relational database
|
|
1058
|
+
2. MongoDB - document database
|
|
1059
|
+
3. SQLite - embedded database
|
|
1060
|
+
</bad-example>
|
|
1061
|
+
|
|
1062
|
+
## Correct - Use AskUserQuestion Tool
|
|
1063
|
+
|
|
1064
|
+
<example>
|
|
1065
|
+
user: Set up a new database
|
|
1066
|
+
assistant: [uses AskUserQuestion tool with structured options]
|
|
1067
|
+
</example>
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
The tool description in `src/prompts/tools/ask-user.txt` reinforces this with explicit "WRONG" examples:
|
|
1071
|
+
|
|
1072
|
+
```
|
|
1073
|
+
CRITICAL: You MUST use this tool for ANY question with 2+ choices.
|
|
1074
|
+
NEVER present options as plain text, numbered lists, or bullet points.
|
|
1075
|
+
|
|
1076
|
+
WRONG (never do this):
|
|
1077
|
+
- "Which do you prefer? 1. Option A 2. Option B"
|
|
1078
|
+
- "What type? - Web - CLI - API"
|
|
1079
|
+
- Writing any numbered or bulleted choices in your response
|
|
1080
|
+
```
|
|
1081
|
+
|
|
1017
1082
|
## Theme Extensions
|
|
1018
1083
|
|
|
1019
1084
|
Add the following icons to `src/cli/components/theme.ts`:
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
- **Proposal ID**: 0025
|
|
4
4
|
- **Author**: mycode team
|
|
5
|
-
- **Status**:
|
|
5
|
+
- **Status**: Implemented
|
|
6
6
|
- **Created**: 2025-01-15
|
|
7
|
-
- **Updated**:
|
|
7
|
+
- **Updated**: 2026-01-16
|
|
8
|
+
- **Implemented**: 2026-01-16
|
|
8
9
|
|
|
9
10
|
## Summary
|
|
10
11
|
|
|
@@ -439,6 +440,63 @@ Only show costs after session ends.
|
|
|
439
440
|
|
|
440
441
|
No breaking changes.
|
|
441
442
|
|
|
443
|
+
## Implementation Notes
|
|
444
|
+
|
|
445
|
+
### Phase 1 Complete (2026-01-16)
|
|
446
|
+
|
|
447
|
+
Implemented core cost tracking functionality with real-time display in CLI.
|
|
448
|
+
|
|
449
|
+
### Files Created
|
|
450
|
+
|
|
451
|
+
| File | Description |
|
|
452
|
+
|------|-------------|
|
|
453
|
+
| `src/pricing/types.ts` | Type definitions for pricing and costs |
|
|
454
|
+
| `src/pricing/models.ts` | Model pricing database (updated Jan 2025) |
|
|
455
|
+
| `src/pricing/calculator.ts` | Cost calculation and formatting utilities |
|
|
456
|
+
| `src/pricing/index.ts` | Module exports |
|
|
457
|
+
| `examples/test-cost-tracking.ts` | Test script for cost tracking |
|
|
458
|
+
| `docs/cost-tracking-comparison.md` | Detailed comparison with OpenCode |
|
|
459
|
+
|
|
460
|
+
### Files Modified
|
|
461
|
+
|
|
462
|
+
| File | Changes |
|
|
463
|
+
|------|---------|
|
|
464
|
+
| `src/providers/types.ts` | Added `cost?: CostEstimate` to `CompletionResponse` |
|
|
465
|
+
| `src/providers/anthropic.ts` | Calculate and return cost in responses |
|
|
466
|
+
| `src/providers/openai.ts` | Calculate and return cost in responses |
|
|
467
|
+
| `src/providers/gemini.ts` | Calculate and return cost in responses |
|
|
468
|
+
| `src/providers/vertex-ai.ts` | Calculate and return cost in responses |
|
|
469
|
+
| `src/agent/types.ts` | Added `usage` and `cost` to `AgentEventDone` |
|
|
470
|
+
| `src/agent/agent.ts` | Pass usage and cost to done event |
|
|
471
|
+
| `src/cli/components/App.tsx` | Pass cost data to CompletionMessage |
|
|
472
|
+
| `src/cli/components/Messages.tsx` | Display cost and token usage |
|
|
473
|
+
|
|
474
|
+
### Key Implementation Details
|
|
475
|
+
|
|
476
|
+
1. **Pricing Database**: Comprehensive pricing for all major models (Anthropic, OpenAI, Google Gemini/Vertex AI) as of January 2025
|
|
477
|
+
|
|
478
|
+
2. **Cost Calculation**: Simple formula `(tokens / 1M) * pricePerMillion` for each token type
|
|
479
|
+
|
|
480
|
+
3. **CLI Display Format**: `✻ Done for 2.3s • Tokens: 1.2K in / 567 out • (~$0.02)`
|
|
481
|
+
|
|
482
|
+
4. **Provider Integration**: All 4 providers (Anthropic, OpenAI, Gemini, Vertex AI) calculate cost when usage data is available
|
|
483
|
+
|
|
484
|
+
5. **Graceful Degradation**: Cost displays only when provider returns usage data (some stream modes may not include it)
|
|
485
|
+
|
|
486
|
+
### Testing
|
|
487
|
+
|
|
488
|
+
- Tested cost calculation with sample data
|
|
489
|
+
- Verified correct pricing for all providers
|
|
490
|
+
- Confirmed CLI display formatting
|
|
491
|
+
|
|
492
|
+
### Future Enhancements (Phase 2+)
|
|
493
|
+
|
|
494
|
+
- Session cost aggregation
|
|
495
|
+
- Budget system with alerts
|
|
496
|
+
- Cost reporting (`/costs` command)
|
|
497
|
+
- Multi-provider cost comparison
|
|
498
|
+
- Advanced token types (reasoning, cache)
|
|
499
|
+
|
|
442
500
|
## References
|
|
443
501
|
|
|
444
502
|
- [Anthropic Pricing](https://www.anthropic.com/pricing)
|
package/docs/proposals/README.md
CHANGED
|
@@ -27,7 +27,7 @@ This directory contains enhancement proposals for the gencode project. Each prop
|
|
|
27
27
|
| [0009](./0009-hooks-system.md) | Hooks System | Draft |
|
|
28
28
|
| [0010](./0010-mcp-integration.md) | MCP Integration | Draft |
|
|
29
29
|
| [0011](./0011-custom-commands.md) | Custom Commands | Draft |
|
|
30
|
-
| [0012](./0012-ask-user-question.md) | AskUserQuestion Tool |
|
|
30
|
+
| [0012](./0012-ask-user-question.md) | AskUserQuestion Tool | Implemented |
|
|
31
31
|
| [0041](./0041-configuration-system.md) | Configuration System | Implemented |
|
|
32
32
|
| [0042](./0042-prompt-optimization.md) | Prompt System Optimization | Implemented |
|
|
33
33
|
|
|
@@ -47,7 +47,7 @@ This directory contains enhancement proposals for the gencode project. Each prop
|
|
|
47
47
|
| [0022](./0022-plugin-system.md) | Plugin System | Draft |
|
|
48
48
|
| [0023](./0023-permission-enhancements.md) | Permission Enhancements | Draft |
|
|
49
49
|
| [0024](./0024-keyboard-shortcuts.md) | Keyboard Shortcuts | Draft |
|
|
50
|
-
| [0025](./0025-cost-tracking.md) | Cost Tracking |
|
|
50
|
+
| [0025](./0025-cost-tracking.md) | Cost Tracking | Implemented |
|
|
51
51
|
| [0026](./0026-git-integration.md) | Git Integration | Draft |
|
|
52
52
|
| [0027](./0027-enhanced-read-tool.md) | Enhanced Read Tool | Draft |
|
|
53
53
|
| [0028](./0028-enhanced-bash-tool.md) | Enhanced Bash Tool | Draft |
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test script for AskUserQuestion tool
|
|
3
|
+
*
|
|
4
|
+
* Run with: npx tsx examples/test-ask-user.ts [mode]
|
|
5
|
+
*
|
|
6
|
+
* Modes:
|
|
7
|
+
* single - Single question, single select (default)
|
|
8
|
+
* multi - Single question, multi-select
|
|
9
|
+
* multiple - Multiple questions with review screen
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { render } from 'ink';
|
|
13
|
+
import React from 'react';
|
|
14
|
+
import { QuestionPrompt } from '../src/cli/components/QuestionPrompt.js';
|
|
15
|
+
import type { Question, QuestionAnswer } from '../src/tools/types.js';
|
|
16
|
+
|
|
17
|
+
// Test questions - matching Claude Code style
|
|
18
|
+
const testQuestions: Question[] = [
|
|
19
|
+
{
|
|
20
|
+
question: 'What type of database would you like to create?',
|
|
21
|
+
header: 'DB Type',
|
|
22
|
+
options: [
|
|
23
|
+
{
|
|
24
|
+
label: 'PostgreSQL',
|
|
25
|
+
description: 'Powerful open-source relational database with advanced features like JSON support and full-text search',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: 'MySQL',
|
|
29
|
+
description: 'Popular relational database, great for web applications and general-purpose use',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: 'SQLite',
|
|
33
|
+
description: 'Lightweight file-based database, perfect for local development or embedded applications',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
label: 'MongoDB',
|
|
37
|
+
description: 'NoSQL document database for flexible schema and JSON-like documents',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
multiSelect: false,
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const testMultiSelectQuestions: Question[] = [
|
|
45
|
+
{
|
|
46
|
+
question: 'Which features should we enable for your project?',
|
|
47
|
+
header: 'Features',
|
|
48
|
+
options: [
|
|
49
|
+
{
|
|
50
|
+
label: 'TypeScript',
|
|
51
|
+
description: 'Type safety and better IDE support with static type checking',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
label: 'ESLint + Prettier',
|
|
55
|
+
description: 'Code linting and automatic formatting for consistent code style',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
label: 'Testing (Vitest)',
|
|
59
|
+
description: 'Fast unit testing framework with native ESM support',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: 'Tailwind CSS',
|
|
63
|
+
description: 'Utility-first CSS framework for rapid UI development',
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
multiSelect: true,
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
const testMultipleQuestions: Question[] = [
|
|
71
|
+
{
|
|
72
|
+
question: 'What type of database would you like to create?',
|
|
73
|
+
header: 'DB Type',
|
|
74
|
+
options: [
|
|
75
|
+
{
|
|
76
|
+
label: 'PostgreSQL',
|
|
77
|
+
description: 'Powerful open-source relational database with advanced features like JSON support and full-text search',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
label: 'MySQL',
|
|
81
|
+
description: 'Popular relational database, great for web applications and general-purpose use',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
label: 'SQLite',
|
|
85
|
+
description: 'Lightweight file-based database, perfect for local development or embedded applications',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
label: 'MongoDB',
|
|
89
|
+
description: 'NoSQL document database for flexible schema and JSON-like documents',
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
multiSelect: false,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
question: 'What is the primary purpose of this database?',
|
|
96
|
+
header: 'Purpose',
|
|
97
|
+
options: [
|
|
98
|
+
{
|
|
99
|
+
label: 'GenCode project',
|
|
100
|
+
description: 'Add database functionality to the GenCode AI assistant project',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
label: 'New project',
|
|
104
|
+
description: 'Create a database for a separate new project',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
label: 'Learning/Testing',
|
|
108
|
+
description: 'Set up a database for experimentation and learning',
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
multiSelect: false,
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
// Choose which test to run
|
|
116
|
+
const testMode = process.argv[2] || 'single';
|
|
117
|
+
|
|
118
|
+
let questions: Question[];
|
|
119
|
+
switch (testMode) {
|
|
120
|
+
case 'multi':
|
|
121
|
+
questions = testMultiSelectQuestions;
|
|
122
|
+
console.log('\n=== Testing Multi-Select Mode ===\n');
|
|
123
|
+
break;
|
|
124
|
+
case 'multiple':
|
|
125
|
+
questions = testMultipleQuestions;
|
|
126
|
+
console.log('\n=== Testing Multiple Questions with Review ===\n');
|
|
127
|
+
break;
|
|
128
|
+
default:
|
|
129
|
+
questions = testQuestions;
|
|
130
|
+
console.log('\n=== Testing Single-Select Mode ===\n');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function TestApp() {
|
|
134
|
+
const handleComplete = (answers: QuestionAnswer[]) => {
|
|
135
|
+
console.log('\n\n=== Answers Received ===');
|
|
136
|
+
answers.forEach((answer, i) => {
|
|
137
|
+
console.log(`\n${i + 1}. ${answer.header}`);
|
|
138
|
+
console.log(` Question: ${answer.question}`);
|
|
139
|
+
console.log(` Selected: ${answer.selectedOptions.join(', ') || '(none)'}`);
|
|
140
|
+
if (answer.customInput) {
|
|
141
|
+
console.log(` Custom: ${answer.customInput}`);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
console.log('\n');
|
|
145
|
+
process.exit(0);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const handleCancel = () => {
|
|
149
|
+
console.log('\n\nCancelled by user\n');
|
|
150
|
+
process.exit(0);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
return React.createElement(QuestionPrompt, {
|
|
154
|
+
questions,
|
|
155
|
+
onComplete: handleComplete,
|
|
156
|
+
onCancel: handleCancel,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Render the test app
|
|
161
|
+
const { unmount } = render(React.createElement(TestApp));
|
|
162
|
+
|
|
163
|
+
// Handle Ctrl+C
|
|
164
|
+
process.on('SIGINT', () => {
|
|
165
|
+
unmount();
|
|
166
|
+
process.exit(0);
|
|
167
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Checkpointing System
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates the automatic file change tracking and rewind capabilities.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CheckpointManager } from '../src/checkpointing/index.js';
|
|
8
|
+
import * as fs from 'fs/promises';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
|
|
15
|
+
async function testCheckpointing() {
|
|
16
|
+
console.log('🧪 Testing Checkpointing System\n');
|
|
17
|
+
|
|
18
|
+
const manager = new CheckpointManager('test-session');
|
|
19
|
+
const testDir = path.join(__dirname, '../.test-checkpoints');
|
|
20
|
+
const testFile = path.join(testDir, 'example.txt');
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
// Create test directory
|
|
24
|
+
await fs.mkdir(testDir, { recursive: true });
|
|
25
|
+
|
|
26
|
+
console.log('1️⃣ Recording file creation...');
|
|
27
|
+
const originalContent = 'Hello, World!';
|
|
28
|
+
await fs.writeFile(testFile, originalContent, 'utf-8');
|
|
29
|
+
|
|
30
|
+
manager.recordChange({
|
|
31
|
+
path: testFile,
|
|
32
|
+
changeType: 'create',
|
|
33
|
+
previousContent: null,
|
|
34
|
+
newContent: originalContent,
|
|
35
|
+
toolName: 'Write',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
console.log(' ✓ File created:', testFile);
|
|
39
|
+
console.log(' ✓ Checkpoint recorded\n');
|
|
40
|
+
|
|
41
|
+
console.log('2️⃣ Recording file modification...');
|
|
42
|
+
const modifiedContent = 'Hello, Checkpointing!';
|
|
43
|
+
await fs.writeFile(testFile, modifiedContent, 'utf-8');
|
|
44
|
+
|
|
45
|
+
manager.recordChange({
|
|
46
|
+
path: testFile,
|
|
47
|
+
changeType: 'modify',
|
|
48
|
+
previousContent: originalContent,
|
|
49
|
+
newContent: modifiedContent,
|
|
50
|
+
toolName: 'Edit',
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
console.log(' ✓ File modified');
|
|
54
|
+
console.log(' ✓ Checkpoint recorded\n');
|
|
55
|
+
|
|
56
|
+
console.log('3️⃣ Listing checkpoints...');
|
|
57
|
+
console.log(manager.formatCheckpointList(true));
|
|
58
|
+
console.log();
|
|
59
|
+
|
|
60
|
+
console.log('4️⃣ Getting summary...');
|
|
61
|
+
const summary = manager.getSummary();
|
|
62
|
+
console.log(` Created: ${summary.created}`);
|
|
63
|
+
console.log(` Modified: ${summary.modified}`);
|
|
64
|
+
console.log(` Deleted: ${summary.deleted}`);
|
|
65
|
+
console.log(` Total: ${summary.total}\n`);
|
|
66
|
+
|
|
67
|
+
console.log('5️⃣ Rewinding last change...');
|
|
68
|
+
const result = await manager.rewind({ count: 1 });
|
|
69
|
+
|
|
70
|
+
if (result.success) {
|
|
71
|
+
console.log(' ✓ Rewind successful');
|
|
72
|
+
result.revertedFiles.forEach((f) => {
|
|
73
|
+
console.log(` • ${path.basename(f.path)} (${f.action})`);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Verify content was restored
|
|
77
|
+
const restoredContent = await fs.readFile(testFile, 'utf-8');
|
|
78
|
+
if (restoredContent === originalContent) {
|
|
79
|
+
console.log(' ✓ Content restored correctly\n');
|
|
80
|
+
} else {
|
|
81
|
+
console.log(' ✗ Content mismatch!\n');
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
console.log(' ✗ Rewind failed');
|
|
85
|
+
result.errors.forEach((e) => console.log(` ${e.error}`));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
console.log('6️⃣ Rewinding all changes...');
|
|
89
|
+
const finalResult = await manager.rewind({ all: true });
|
|
90
|
+
|
|
91
|
+
if (finalResult.success) {
|
|
92
|
+
console.log(' ✓ All changes reverted');
|
|
93
|
+
finalResult.revertedFiles.forEach((f) => {
|
|
94
|
+
console.log(` • ${path.basename(f.path)} (${f.action})`);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Verify file was deleted
|
|
98
|
+
try {
|
|
99
|
+
await fs.access(testFile);
|
|
100
|
+
console.log(' ✗ File still exists!\n');
|
|
101
|
+
} catch {
|
|
102
|
+
console.log(' ✓ File was deleted as expected\n');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log('✅ All tests passed!\n');
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error('❌ Test failed:', error);
|
|
109
|
+
} finally {
|
|
110
|
+
// Cleanup
|
|
111
|
+
try {
|
|
112
|
+
await fs.rm(testDir, { recursive: true, force: true });
|
|
113
|
+
console.log('🧹 Cleaned up test directory');
|
|
114
|
+
} catch {
|
|
115
|
+
// Ignore cleanup errors
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Run the test
|
|
121
|
+
testCheckpointing();
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test cost tracking functionality
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { createProvider } from '../src/providers/index.js';
|
|
6
|
+
import { calculateCost, formatCost, formatTokens } from '../src/pricing/calculator.js';
|
|
7
|
+
|
|
8
|
+
async function testCostTracking() {
|
|
9
|
+
console.log('='.repeat(60));
|
|
10
|
+
console.log('Testing Cost Tracking Feature');
|
|
11
|
+
console.log('='.repeat(60));
|
|
12
|
+
console.log();
|
|
13
|
+
|
|
14
|
+
// Test 1: Cost Calculation
|
|
15
|
+
console.log('Test 1: Cost Calculation');
|
|
16
|
+
console.log('-'.repeat(60));
|
|
17
|
+
|
|
18
|
+
const testCases = [
|
|
19
|
+
{ provider: 'anthropic', model: 'claude-sonnet-4', input: 1000, output: 500 },
|
|
20
|
+
{ provider: 'openai', model: 'gpt-4o', input: 1000, output: 500 },
|
|
21
|
+
{ provider: 'gemini', model: 'gemini-2.0-flash', input: 1000, output: 500 },
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
for (const test of testCases) {
|
|
25
|
+
const cost = calculateCost(test.provider, test.model, {
|
|
26
|
+
inputTokens: test.input,
|
|
27
|
+
outputTokens: test.output,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
console.log(`\n${test.provider}/${test.model}:`);
|
|
31
|
+
console.log(` Input: ${formatTokens(test.input)} tokens`);
|
|
32
|
+
console.log(` Output: ${formatTokens(test.output)} tokens`);
|
|
33
|
+
console.log(` Cost: ${formatCost(cost.totalCost)}`);
|
|
34
|
+
console.log(` Breakdown: ${formatCost(cost.inputCost)} (input) + ${formatCost(cost.outputCost)} (output)`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log();
|
|
38
|
+
console.log('='.repeat(60));
|
|
39
|
+
console.log();
|
|
40
|
+
|
|
41
|
+
// Test 2: Real API Call (if env var is set)
|
|
42
|
+
if (process.env.ANTHROPIC_API_KEY) {
|
|
43
|
+
console.log('Test 2: Real API Call with Anthropic');
|
|
44
|
+
console.log('-'.repeat(60));
|
|
45
|
+
|
|
46
|
+
const provider = createProvider({ provider: 'anthropic', model: 'claude-haiku-3-5' });
|
|
47
|
+
|
|
48
|
+
const response = await provider.complete({
|
|
49
|
+
model: 'claude-haiku-3-5',
|
|
50
|
+
messages: [{ role: 'user', content: 'Say hello in one word' }],
|
|
51
|
+
maxTokens: 10,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
console.log('\nResponse:', response.content[0]?.type === 'text' ? response.content[0].text : '');
|
|
55
|
+
|
|
56
|
+
if (response.usage) {
|
|
57
|
+
console.log(`\nToken Usage:`);
|
|
58
|
+
console.log(` Input: ${formatTokens(response.usage.inputTokens)}`);
|
|
59
|
+
console.log(` Output: ${formatTokens(response.usage.outputTokens)}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (response.cost) {
|
|
63
|
+
console.log(`\nCost Estimate:`);
|
|
64
|
+
console.log(` Total: ${formatCost(response.cost.totalCost)}`);
|
|
65
|
+
console.log(` Input: ${formatCost(response.cost.inputCost)}`);
|
|
66
|
+
console.log(` Output: ${formatCost(response.cost.outputCost)}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
console.log();
|
|
70
|
+
console.log('='.repeat(60));
|
|
71
|
+
} else {
|
|
72
|
+
console.log('Skipping API test (no ANTHROPIC_API_KEY)');
|
|
73
|
+
console.log('='.repeat(60));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
testCostTracking().catch(console.error);
|