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.
Files changed (180) hide show
  1. package/README.md +15 -17
  2. package/dist/agent/agent.d.ts +43 -0
  3. package/dist/agent/agent.d.ts.map +1 -1
  4. package/dist/agent/agent.js +107 -4
  5. package/dist/agent/agent.js.map +1 -1
  6. package/dist/agent/index.d.ts +1 -0
  7. package/dist/agent/index.d.ts.map +1 -1
  8. package/dist/agent/types.d.ts +20 -1
  9. package/dist/agent/types.d.ts.map +1 -1
  10. package/dist/checkpointing/checkpoint-manager.d.ts +87 -0
  11. package/dist/checkpointing/checkpoint-manager.d.ts.map +1 -0
  12. package/dist/checkpointing/checkpoint-manager.js +281 -0
  13. package/dist/checkpointing/checkpoint-manager.js.map +1 -0
  14. package/dist/checkpointing/index.d.ts +29 -0
  15. package/dist/checkpointing/index.d.ts.map +1 -0
  16. package/dist/checkpointing/index.js +29 -0
  17. package/dist/checkpointing/index.js.map +1 -0
  18. package/dist/checkpointing/types.d.ts +98 -0
  19. package/dist/checkpointing/types.d.ts.map +1 -0
  20. package/dist/checkpointing/types.js +7 -0
  21. package/dist/checkpointing/types.js.map +1 -0
  22. package/dist/cli/components/App.d.ts.map +1 -1
  23. package/dist/cli/components/App.js +193 -7
  24. package/dist/cli/components/App.js.map +1 -1
  25. package/dist/cli/components/CommandSuggestions.d.ts.map +1 -1
  26. package/dist/cli/components/CommandSuggestions.js +5 -0
  27. package/dist/cli/components/CommandSuggestions.js.map +1 -1
  28. package/dist/cli/components/Messages.d.ts +7 -1
  29. package/dist/cli/components/Messages.d.ts.map +1 -1
  30. package/dist/cli/components/Messages.js +28 -2
  31. package/dist/cli/components/Messages.js.map +1 -1
  32. package/dist/cli/components/ModeIndicator.d.ts +42 -0
  33. package/dist/cli/components/ModeIndicator.d.ts.map +1 -0
  34. package/dist/cli/components/ModeIndicator.js +52 -0
  35. package/dist/cli/components/ModeIndicator.js.map +1 -0
  36. package/dist/cli/components/PlanApproval.d.ts +36 -0
  37. package/dist/cli/components/PlanApproval.d.ts.map +1 -0
  38. package/dist/cli/components/PlanApproval.js +154 -0
  39. package/dist/cli/components/PlanApproval.js.map +1 -0
  40. package/dist/cli/components/QuestionPrompt.d.ts +23 -0
  41. package/dist/cli/components/QuestionPrompt.d.ts.map +1 -0
  42. package/dist/cli/components/QuestionPrompt.js +231 -0
  43. package/dist/cli/components/QuestionPrompt.js.map +1 -0
  44. package/dist/cli/components/index.d.ts +1 -0
  45. package/dist/cli/components/index.d.ts.map +1 -1
  46. package/dist/cli/components/index.js +1 -0
  47. package/dist/cli/components/index.js.map +1 -1
  48. package/dist/cli/components/theme.d.ts +9 -0
  49. package/dist/cli/components/theme.d.ts.map +1 -1
  50. package/dist/cli/components/theme.js +14 -1
  51. package/dist/cli/components/theme.js.map +1 -1
  52. package/dist/index.d.ts +1 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +2 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/permissions/types.d.ts.map +1 -1
  57. package/dist/permissions/types.js +2 -0
  58. package/dist/permissions/types.js.map +1 -1
  59. package/dist/planning/index.d.ts +13 -0
  60. package/dist/planning/index.d.ts.map +1 -0
  61. package/dist/planning/index.js +15 -0
  62. package/dist/planning/index.js.map +1 -0
  63. package/dist/planning/plan-file.d.ts +59 -0
  64. package/dist/planning/plan-file.d.ts.map +1 -0
  65. package/dist/planning/plan-file.js +278 -0
  66. package/dist/planning/plan-file.js.map +1 -0
  67. package/dist/planning/state.d.ts +127 -0
  68. package/dist/planning/state.d.ts.map +1 -0
  69. package/dist/planning/state.js +261 -0
  70. package/dist/planning/state.js.map +1 -0
  71. package/dist/planning/tools/enter-plan-mode.d.ts +25 -0
  72. package/dist/planning/tools/enter-plan-mode.d.ts.map +1 -0
  73. package/dist/planning/tools/enter-plan-mode.js +98 -0
  74. package/dist/planning/tools/enter-plan-mode.js.map +1 -0
  75. package/dist/planning/tools/exit-plan-mode.d.ts +24 -0
  76. package/dist/planning/tools/exit-plan-mode.d.ts.map +1 -0
  77. package/dist/planning/tools/exit-plan-mode.js +149 -0
  78. package/dist/planning/tools/exit-plan-mode.js.map +1 -0
  79. package/dist/planning/types.d.ts +100 -0
  80. package/dist/planning/types.d.ts.map +1 -0
  81. package/dist/planning/types.js +28 -0
  82. package/dist/planning/types.js.map +1 -0
  83. package/dist/pricing/calculator.d.ts +21 -0
  84. package/dist/pricing/calculator.d.ts.map +1 -0
  85. package/dist/pricing/calculator.js +59 -0
  86. package/dist/pricing/calculator.js.map +1 -0
  87. package/dist/pricing/index.d.ts +7 -0
  88. package/dist/pricing/index.d.ts.map +1 -0
  89. package/dist/pricing/index.js +7 -0
  90. package/dist/pricing/index.js.map +1 -0
  91. package/dist/pricing/models.d.ts +20 -0
  92. package/dist/pricing/models.d.ts.map +1 -0
  93. package/dist/pricing/models.js +322 -0
  94. package/dist/pricing/models.js.map +1 -0
  95. package/dist/pricing/types.d.ts +30 -0
  96. package/dist/pricing/types.d.ts.map +1 -0
  97. package/dist/pricing/types.js +5 -0
  98. package/dist/pricing/types.js.map +1 -0
  99. package/dist/providers/anthropic.d.ts.map +1 -1
  100. package/dist/providers/anthropic.js +17 -10
  101. package/dist/providers/anthropic.js.map +1 -1
  102. package/dist/providers/gemini.d.ts.map +1 -1
  103. package/dist/providers/gemini.js +21 -14
  104. package/dist/providers/gemini.js.map +1 -1
  105. package/dist/providers/openai.d.ts.map +1 -1
  106. package/dist/providers/openai.js +12 -8
  107. package/dist/providers/openai.js.map +1 -1
  108. package/dist/providers/types.d.ts +2 -0
  109. package/dist/providers/types.d.ts.map +1 -1
  110. package/dist/providers/vertex-ai.d.ts.map +1 -1
  111. package/dist/providers/vertex-ai.js +17 -10
  112. package/dist/providers/vertex-ai.js.map +1 -1
  113. package/dist/session/manager.d.ts +4 -0
  114. package/dist/session/manager.d.ts.map +1 -1
  115. package/dist/session/manager.js +8 -0
  116. package/dist/session/manager.js.map +1 -1
  117. package/dist/tools/builtin/ask-user.d.ts +64 -0
  118. package/dist/tools/builtin/ask-user.d.ts.map +1 -0
  119. package/dist/tools/builtin/ask-user.js +148 -0
  120. package/dist/tools/builtin/ask-user.js.map +1 -0
  121. package/dist/tools/index.d.ts +19 -1
  122. package/dist/tools/index.d.ts.map +1 -1
  123. package/dist/tools/index.js +11 -0
  124. package/dist/tools/index.js.map +1 -1
  125. package/dist/tools/registry.d.ts +13 -0
  126. package/dist/tools/registry.d.ts.map +1 -1
  127. package/dist/tools/registry.js +79 -2
  128. package/dist/tools/registry.js.map +1 -1
  129. package/dist/tools/types.d.ts +17 -0
  130. package/dist/tools/types.d.ts.map +1 -1
  131. package/dist/tools/types.js.map +1 -1
  132. package/docs/cost-tracking-comparison.md +904 -0
  133. package/docs/operating-modes.md +96 -0
  134. package/docs/proposals/0012-ask-user-question.md +66 -1
  135. package/docs/proposals/0025-cost-tracking.md +60 -2
  136. package/docs/proposals/README.md +2 -2
  137. package/examples/test-ask-user.ts +167 -0
  138. package/examples/test-checkpointing.ts +121 -0
  139. package/examples/test-cost-tracking.ts +77 -0
  140. package/examples/test-interrupt-cleanup.ts +94 -0
  141. package/package.json +1 -1
  142. package/src/agent/agent.ts +130 -4
  143. package/src/agent/index.ts +1 -0
  144. package/src/agent/types.ts +19 -1
  145. package/src/checkpointing/checkpoint-manager.ts +327 -0
  146. package/src/checkpointing/index.ts +45 -0
  147. package/src/checkpointing/types.ts +104 -0
  148. package/src/cli/components/App.tsx +259 -8
  149. package/src/cli/components/CommandSuggestions.tsx +5 -0
  150. package/src/cli/components/Messages.tsx +66 -4
  151. package/src/cli/components/ModeIndicator.tsx +174 -0
  152. package/src/cli/components/PlanApproval.tsx +327 -0
  153. package/src/cli/components/QuestionPrompt.tsx +462 -0
  154. package/src/cli/components/index.ts +1 -0
  155. package/src/cli/components/theme.ts +14 -1
  156. package/src/index.ts +15 -0
  157. package/src/permissions/types.ts +2 -0
  158. package/src/planning/index.ts +53 -0
  159. package/src/planning/plan-file.ts +326 -0
  160. package/src/planning/state.ts +305 -0
  161. package/src/planning/tools/enter-plan-mode.ts +111 -0
  162. package/src/planning/tools/exit-plan-mode.ts +170 -0
  163. package/src/planning/types.ts +150 -0
  164. package/src/pricing/calculator.ts +71 -0
  165. package/src/pricing/index.ts +7 -0
  166. package/src/pricing/models.ts +334 -0
  167. package/src/pricing/types.ts +32 -0
  168. package/src/prompts/system/base.txt +42 -0
  169. package/src/prompts/tools/ask-user.txt +110 -0
  170. package/src/providers/anthropic.ts +21 -10
  171. package/src/providers/gemini.ts +25 -14
  172. package/src/providers/openai.ts +17 -8
  173. package/src/providers/types.ts +3 -0
  174. package/src/providers/vertex-ai.ts +21 -10
  175. package/src/session/manager.ts +9 -0
  176. package/src/tools/builtin/ask-user.ts +185 -0
  177. package/src/tools/index.ts +23 -0
  178. package/src/tools/registry.ts +95 -2
  179. package/src/tools/types.ts +18 -0
  180. 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**: Draft
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**: Draft
5
+ - **Status**: Implemented
6
6
  - **Created**: 2025-01-15
7
- - **Updated**: 2025-01-15
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)
@@ -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 | Draft |
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 | Draft |
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);