gencode-ai 0.1.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 (274) hide show
  1. package/.env.example +11 -0
  2. package/CLAUDE.md +70 -0
  3. package/LICENSE +21 -0
  4. package/README.md +117 -0
  5. package/dist/agent/agent.d.ts +84 -0
  6. package/dist/agent/agent.d.ts.map +1 -0
  7. package/dist/agent/agent.js +233 -0
  8. package/dist/agent/agent.js.map +1 -0
  9. package/dist/agent/index.d.ts +6 -0
  10. package/dist/agent/index.d.ts.map +1 -0
  11. package/dist/agent/index.js +6 -0
  12. package/dist/agent/index.js.map +1 -0
  13. package/dist/agent/types.d.ts +47 -0
  14. package/dist/agent/types.d.ts.map +1 -0
  15. package/dist/agent/types.js +5 -0
  16. package/dist/agent/types.js.map +1 -0
  17. package/dist/cli/components/App.d.ts +14 -0
  18. package/dist/cli/components/App.d.ts.map +1 -0
  19. package/dist/cli/components/App.js +395 -0
  20. package/dist/cli/components/App.js.map +1 -0
  21. package/dist/cli/components/CommandSuggestions.d.ts +13 -0
  22. package/dist/cli/components/CommandSuggestions.d.ts.map +1 -0
  23. package/dist/cli/components/CommandSuggestions.js +32 -0
  24. package/dist/cli/components/CommandSuggestions.js.map +1 -0
  25. package/dist/cli/components/Header.d.ts +9 -0
  26. package/dist/cli/components/Header.d.ts.map +1 -0
  27. package/dist/cli/components/Header.js +13 -0
  28. package/dist/cli/components/Header.js.map +1 -0
  29. package/dist/cli/components/Input.d.ts +13 -0
  30. package/dist/cli/components/Input.d.ts.map +1 -0
  31. package/dist/cli/components/Input.js +27 -0
  32. package/dist/cli/components/Input.js.map +1 -0
  33. package/dist/cli/components/Logo.d.ts +2 -0
  34. package/dist/cli/components/Logo.d.ts.map +1 -0
  35. package/dist/cli/components/Logo.js +8 -0
  36. package/dist/cli/components/Logo.js.map +1 -0
  37. package/dist/cli/components/Messages.d.ts +37 -0
  38. package/dist/cli/components/Messages.d.ts.map +1 -0
  39. package/dist/cli/components/Messages.js +106 -0
  40. package/dist/cli/components/Messages.js.map +1 -0
  41. package/dist/cli/components/ModelSelector.d.ts +13 -0
  42. package/dist/cli/components/ModelSelector.d.ts.map +1 -0
  43. package/dist/cli/components/ModelSelector.js +72 -0
  44. package/dist/cli/components/ModelSelector.js.map +1 -0
  45. package/dist/cli/components/Spinner.d.ts +12 -0
  46. package/dist/cli/components/Spinner.d.ts.map +1 -0
  47. package/dist/cli/components/Spinner.js +45 -0
  48. package/dist/cli/components/Spinner.js.map +1 -0
  49. package/dist/cli/components/index.d.ts +12 -0
  50. package/dist/cli/components/index.d.ts.map +1 -0
  51. package/dist/cli/components/index.js +12 -0
  52. package/dist/cli/components/index.js.map +1 -0
  53. package/dist/cli/components/theme.d.ts +31 -0
  54. package/dist/cli/components/theme.d.ts.map +1 -0
  55. package/dist/cli/components/theme.js +36 -0
  56. package/dist/cli/components/theme.js.map +1 -0
  57. package/dist/cli/index-legacy.d.ts +7 -0
  58. package/dist/cli/index-legacy.d.ts.map +1 -0
  59. package/dist/cli/index-legacy.js +431 -0
  60. package/dist/cli/index-legacy.js.map +1 -0
  61. package/dist/cli/index.d.ts +7 -0
  62. package/dist/cli/index.d.ts.map +1 -0
  63. package/dist/cli/index.js +116 -0
  64. package/dist/cli/index.js.map +1 -0
  65. package/dist/cli/ink-cli.d.ts +7 -0
  66. package/dist/cli/ink-cli.d.ts.map +1 -0
  67. package/dist/cli/ink-cli.js +105 -0
  68. package/dist/cli/ink-cli.js.map +1 -0
  69. package/dist/cli/session-picker.d.ts +16 -0
  70. package/dist/cli/session-picker.d.ts.map +1 -0
  71. package/dist/cli/session-picker.js +280 -0
  72. package/dist/cli/session-picker.js.map +1 -0
  73. package/dist/cli/ui.d.ts +61 -0
  74. package/dist/cli/ui.d.ts.map +1 -0
  75. package/dist/cli/ui.js +364 -0
  76. package/dist/cli/ui.js.map +1 -0
  77. package/dist/config/index.d.ts +7 -0
  78. package/dist/config/index.d.ts.map +1 -0
  79. package/dist/config/index.js +6 -0
  80. package/dist/config/index.js.map +1 -0
  81. package/dist/config/manager.d.ts +31 -0
  82. package/dist/config/manager.d.ts.map +1 -0
  83. package/dist/config/manager.js +65 -0
  84. package/dist/config/manager.js.map +1 -0
  85. package/dist/config/types.d.ts +22 -0
  86. package/dist/config/types.d.ts.map +1 -0
  87. package/dist/config/types.js +6 -0
  88. package/dist/config/types.js.map +1 -0
  89. package/dist/index.d.ts +12 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +21 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/memory/index.d.ts +10 -0
  94. package/dist/memory/index.d.ts.map +1 -0
  95. package/dist/memory/index.js +9 -0
  96. package/dist/memory/index.js.map +1 -0
  97. package/dist/memory/init.d.ts +20 -0
  98. package/dist/memory/init.d.ts.map +1 -0
  99. package/dist/memory/init.js +332 -0
  100. package/dist/memory/init.js.map +1 -0
  101. package/dist/memory/manager.d.ts +85 -0
  102. package/dist/memory/manager.d.ts.map +1 -0
  103. package/dist/memory/manager.js +234 -0
  104. package/dist/memory/manager.js.map +1 -0
  105. package/dist/memory/types.d.ts +74 -0
  106. package/dist/memory/types.d.ts.map +1 -0
  107. package/dist/memory/types.js +6 -0
  108. package/dist/memory/types.js.map +1 -0
  109. package/dist/permissions/index.d.ts +7 -0
  110. package/dist/permissions/index.d.ts.map +1 -0
  111. package/dist/permissions/index.js +6 -0
  112. package/dist/permissions/index.js.map +1 -0
  113. package/dist/permissions/manager.d.ts +32 -0
  114. package/dist/permissions/manager.d.ts.map +1 -0
  115. package/dist/permissions/manager.js +79 -0
  116. package/dist/permissions/manager.js.map +1 -0
  117. package/dist/permissions/types.d.ts +14 -0
  118. package/dist/permissions/types.d.ts.map +1 -0
  119. package/dist/permissions/types.js +17 -0
  120. package/dist/permissions/types.js.map +1 -0
  121. package/dist/providers/anthropic.d.ts +20 -0
  122. package/dist/providers/anthropic.d.ts.map +1 -0
  123. package/dist/providers/anthropic.js +185 -0
  124. package/dist/providers/anthropic.js.map +1 -0
  125. package/dist/providers/gemini.d.ts +21 -0
  126. package/dist/providers/gemini.d.ts.map +1 -0
  127. package/dist/providers/gemini.js +241 -0
  128. package/dist/providers/gemini.js.map +1 -0
  129. package/dist/providers/index.d.ts +34 -0
  130. package/dist/providers/index.d.ts.map +1 -0
  131. package/dist/providers/index.js +72 -0
  132. package/dist/providers/index.js.map +1 -0
  133. package/dist/providers/openai.d.ts +19 -0
  134. package/dist/providers/openai.d.ts.map +1 -0
  135. package/dist/providers/openai.js +221 -0
  136. package/dist/providers/openai.js.map +1 -0
  137. package/dist/providers/types.d.ts +125 -0
  138. package/dist/providers/types.d.ts.map +1 -0
  139. package/dist/providers/types.js +6 -0
  140. package/dist/providers/types.js.map +1 -0
  141. package/dist/session/index.d.ts +6 -0
  142. package/dist/session/index.d.ts.map +1 -0
  143. package/dist/session/index.js +6 -0
  144. package/dist/session/index.js.map +1 -0
  145. package/dist/session/manager.d.ts +101 -0
  146. package/dist/session/manager.d.ts.map +1 -0
  147. package/dist/session/manager.js +295 -0
  148. package/dist/session/manager.js.map +1 -0
  149. package/dist/session/types.d.ts +39 -0
  150. package/dist/session/types.d.ts.map +1 -0
  151. package/dist/session/types.js +10 -0
  152. package/dist/session/types.js.map +1 -0
  153. package/dist/tools/builtin/bash.d.ts +7 -0
  154. package/dist/tools/builtin/bash.d.ts.map +1 -0
  155. package/dist/tools/builtin/bash.js +80 -0
  156. package/dist/tools/builtin/bash.js.map +1 -0
  157. package/dist/tools/builtin/edit.d.ts +7 -0
  158. package/dist/tools/builtin/edit.d.ts.map +1 -0
  159. package/dist/tools/builtin/edit.js +32 -0
  160. package/dist/tools/builtin/edit.js.map +1 -0
  161. package/dist/tools/builtin/glob.d.ts +7 -0
  162. package/dist/tools/builtin/glob.d.ts.map +1 -0
  163. package/dist/tools/builtin/glob.js +36 -0
  164. package/dist/tools/builtin/glob.js.map +1 -0
  165. package/dist/tools/builtin/grep.d.ts +7 -0
  166. package/dist/tools/builtin/grep.d.ts.map +1 -0
  167. package/dist/tools/builtin/grep.js +59 -0
  168. package/dist/tools/builtin/grep.js.map +1 -0
  169. package/dist/tools/builtin/read.d.ts +7 -0
  170. package/dist/tools/builtin/read.d.ts.map +1 -0
  171. package/dist/tools/builtin/read.js +29 -0
  172. package/dist/tools/builtin/read.js.map +1 -0
  173. package/dist/tools/builtin/write.d.ts +7 -0
  174. package/dist/tools/builtin/write.d.ts.map +1 -0
  175. package/dist/tools/builtin/write.js +24 -0
  176. package/dist/tools/builtin/write.js.map +1 -0
  177. package/dist/tools/index.d.ts +38 -0
  178. package/dist/tools/index.d.ts.map +1 -0
  179. package/dist/tools/index.js +32 -0
  180. package/dist/tools/index.js.map +1 -0
  181. package/dist/tools/registry.d.ts +22 -0
  182. package/dist/tools/registry.d.ts.map +1 -0
  183. package/dist/tools/registry.js +71 -0
  184. package/dist/tools/registry.js.map +1 -0
  185. package/dist/tools/types.d.ts +62 -0
  186. package/dist/tools/types.d.ts.map +1 -0
  187. package/dist/tools/types.js +126 -0
  188. package/dist/tools/types.js.map +1 -0
  189. package/docs/README.md +16 -0
  190. package/docs/proposals/0001-web-fetch-tool.md +293 -0
  191. package/docs/proposals/0002-web-search-tool.md +306 -0
  192. package/docs/proposals/0003-task-subagents.md +333 -0
  193. package/docs/proposals/0004-plan-mode.md +338 -0
  194. package/docs/proposals/0005-todo-system.md +299 -0
  195. package/docs/proposals/0006-memory-system.md +539 -0
  196. package/docs/proposals/0007-context-management.md +429 -0
  197. package/docs/proposals/0008-checkpointing.md +327 -0
  198. package/docs/proposals/0009-hooks-system.md +343 -0
  199. package/docs/proposals/0010-mcp-integration.md +382 -0
  200. package/docs/proposals/0011-custom-commands.md +374 -0
  201. package/docs/proposals/0012-ask-user-question.md +317 -0
  202. package/docs/proposals/0013-multi-edit-tool.md +345 -0
  203. package/docs/proposals/0014-lsp-tool.md +478 -0
  204. package/docs/proposals/0015-ls-tool.md +407 -0
  205. package/docs/proposals/0016-kill-shell-tool.md +455 -0
  206. package/docs/proposals/0017-background-tasks.md +489 -0
  207. package/docs/proposals/0018-parallel-tool-execution.md +415 -0
  208. package/docs/proposals/0019-session-enhancements.md +462 -0
  209. package/docs/proposals/0020-session-summarization.md +447 -0
  210. package/docs/proposals/0021-skills-system.md +409 -0
  211. package/docs/proposals/0022-plugin-system.md +467 -0
  212. package/docs/proposals/0023-permission-enhancements.md +470 -0
  213. package/docs/proposals/0024-keyboard-shortcuts.md +443 -0
  214. package/docs/proposals/0025-cost-tracking.md +447 -0
  215. package/docs/proposals/0026-git-integration.md +475 -0
  216. package/docs/proposals/0027-enhanced-read-tool.md +514 -0
  217. package/docs/proposals/0028-enhanced-bash-tool.md +511 -0
  218. package/docs/proposals/0029-notebook-edit-tool.md +413 -0
  219. package/docs/proposals/0030-plugin-marketplace.md +360 -0
  220. package/docs/proposals/0031-command-suggestions.md +295 -0
  221. package/docs/proposals/0032-ide-integrations.md +328 -0
  222. package/docs/proposals/0033-enterprise-deployment.md +221 -0
  223. package/docs/proposals/0034-sandboxing.md +273 -0
  224. package/docs/proposals/0035-auto-updater.md +311 -0
  225. package/docs/proposals/0036-enhanced-glob-tool.md +267 -0
  226. package/docs/proposals/0037-enhanced-grep-tool.md +360 -0
  227. package/docs/proposals/0038-interactive-cli-ui.md +373 -0
  228. package/docs/proposals/0039-streaming-enhancements.md +359 -0
  229. package/docs/proposals/0040-multi-provider-enhancements.md +369 -0
  230. package/docs/proposals/README.md +84 -0
  231. package/docs/proposals/TEMPLATE.md +57 -0
  232. package/docs/proposals/research/claude-code-research.md +307 -0
  233. package/examples/agent-demo.ts +115 -0
  234. package/examples/basic.ts +166 -0
  235. package/package.json +50 -0
  236. package/src/agent/agent.ts +276 -0
  237. package/src/agent/index.ts +6 -0
  238. package/src/agent/types.ts +62 -0
  239. package/src/cli/components/App.tsx +565 -0
  240. package/src/cli/components/CommandSuggestions.tsx +58 -0
  241. package/src/cli/components/Header.tsx +36 -0
  242. package/src/cli/components/Input.tsx +60 -0
  243. package/src/cli/components/Logo.tsx +16 -0
  244. package/src/cli/components/Messages.tsx +210 -0
  245. package/src/cli/components/ModelSelector.tsx +135 -0
  246. package/src/cli/components/Spinner.tsx +72 -0
  247. package/src/cli/components/index.ts +21 -0
  248. package/src/cli/components/theme.ts +36 -0
  249. package/src/cli/index.tsx +136 -0
  250. package/src/config/index.ts +7 -0
  251. package/src/config/manager.ts +77 -0
  252. package/src/config/types.ts +25 -0
  253. package/src/index.ts +86 -0
  254. package/src/permissions/index.ts +7 -0
  255. package/src/permissions/manager.ts +97 -0
  256. package/src/permissions/types.ts +29 -0
  257. package/src/providers/anthropic.ts +224 -0
  258. package/src/providers/gemini.ts +295 -0
  259. package/src/providers/index.ts +97 -0
  260. package/src/providers/openai.ts +261 -0
  261. package/src/providers/types.ts +181 -0
  262. package/src/session/index.ts +6 -0
  263. package/src/session/manager.ts +354 -0
  264. package/src/session/types.ts +49 -0
  265. package/src/tools/builtin/bash.ts +92 -0
  266. package/src/tools/builtin/edit.ts +37 -0
  267. package/src/tools/builtin/glob.ts +42 -0
  268. package/src/tools/builtin/grep.ts +67 -0
  269. package/src/tools/builtin/read.ts +34 -0
  270. package/src/tools/builtin/write.ts +27 -0
  271. package/src/tools/index.ts +36 -0
  272. package/src/tools/registry.ts +83 -0
  273. package/src/tools/types.ts +172 -0
  274. package/tsconfig.json +21 -0
@@ -0,0 +1,429 @@
1
+ # Proposal: Context Management
2
+
3
+ - **Proposal ID**: 0007
4
+ - **Author**: mycode team
5
+ - **Status**: Draft
6
+ - **Created**: 2025-01-15
7
+ - **Updated**: 2025-01-15
8
+
9
+ ## Summary
10
+
11
+ Implement a comprehensive context management system that tracks token usage, manages context window limits, and automatically compacts conversations when approaching limits. This ensures the agent can handle long sessions without losing important context or crashing due to context overflow.
12
+
13
+ ## Motivation
14
+
15
+ Currently, mycode has no awareness of context window limits. This leads to:
16
+
17
+ 1. **Session crashes**: Long conversations exceed context limits silently
18
+ 2. **Lost context**: Important early information gets truncated unexpectedly
19
+ 3. **No visibility**: Users can't see how much context they're using
20
+ 4. **Inefficient usage**: No automatic optimization of context space
21
+ 5. **Provider differences**: Different LLMs have different context limits
22
+
23
+ A context management system solves these by tracking usage and proactively managing context.
24
+
25
+ ## Claude Code Reference
26
+
27
+ Claude Code implements sophisticated context management:
28
+
29
+ 1. **Token Tracking**: Counts tokens for each message and tool result
30
+ 2. **Context Warnings**: Alerts when approaching limits
31
+ 3. **Auto-Compaction**: Automatically summarizes old messages when needed
32
+ 4. **`/compact` Command**: Manual context compaction
33
+ 5. **Unlimited Context**: "The conversation has unlimited context through automatic summarization"
34
+ 6. **Memory Tool (Beta)**: Persistent storage that survives context clears
35
+
36
+ Key behaviors:
37
+ - Displays context usage in status line
38
+ - Warns at 80% context usage
39
+ - Automatically compacts at 90% usage
40
+ - Preserves recent messages and important context
41
+ - Maintains conversation coherence after compaction
42
+
43
+ ### Memory Tool API
44
+
45
+ Claude Code's Memory Tool (beta API `context-management-2025-06-27`) enables agents to persist information across context resets:
46
+
47
+ | Command | Description | Parameters |
48
+ |---------|-------------|------------|
49
+ | `view` | List directory or read file | `path`, `view_range?` |
50
+ | `create` | Create new file | `path`, `file_text` |
51
+ | `str_replace` | Replace text | `path`, `old_str`, `new_str` |
52
+ | `insert` | Insert at line | `path`, `insert_line`, `insert_text` |
53
+ | `delete` | Delete file/directory | `path` |
54
+ | `rename` | Rename/move | `old_path`, `new_path` |
55
+
56
+ ### Context Editing Configuration
57
+
58
+ ```typescript
59
+ context_management: {
60
+ edits: [{
61
+ type: "clear_tool_uses_20250919",
62
+ trigger: { type: "input_tokens", value: 100000 },
63
+ keep: { type: "tool_uses", value: 3 },
64
+ exclude_tools: ["memory"] // Never clear memory operations
65
+ }]
66
+ }
67
+ ```
68
+
69
+ ## Detailed Design
70
+
71
+ ### API Design
72
+
73
+ ```typescript
74
+ // src/context/types.ts
75
+ interface TokenUsage {
76
+ prompt: number;
77
+ completion: number;
78
+ total: number;
79
+ }
80
+
81
+ interface ContextLimits {
82
+ maxContextTokens: number;
83
+ maxOutputTokens: number;
84
+ warningThreshold: number; // Default: 0.8 (80%)
85
+ compactionThreshold: number; // Default: 0.9 (90%)
86
+ }
87
+
88
+ interface ContextStats {
89
+ currentUsage: number;
90
+ maxTokens: number;
91
+ usagePercent: number;
92
+ messageCount: number;
93
+ oldestMessageAge: Date;
94
+ }
95
+
96
+ interface CompactionResult {
97
+ removedMessages: number;
98
+ savedTokens: number;
99
+ summary: string;
100
+ }
101
+ ```
102
+
103
+ ```typescript
104
+ // src/context/context-manager.ts
105
+ class ContextManager {
106
+ private usage: TokenUsage;
107
+ private limits: ContextLimits;
108
+ private tokenizer: Tokenizer;
109
+
110
+ constructor(provider: string, model: string);
111
+
112
+ // Count tokens for a message
113
+ countTokens(content: string | MessageContent[]): number;
114
+
115
+ // Get current context statistics
116
+ getStats(): ContextStats;
117
+
118
+ // Check if compaction is needed
119
+ needsCompaction(): boolean;
120
+
121
+ // Compact conversation history
122
+ async compact(messages: Message[], options?: CompactionOptions): Promise<CompactionResult>;
123
+
124
+ // Update usage after API call
125
+ updateUsage(usage: TokenUsage): void;
126
+
127
+ // Get provider-specific context limit
128
+ static getContextLimit(provider: string, model: string): number;
129
+ }
130
+ ```
131
+
132
+ ```typescript
133
+ // src/context/tokenizer.ts
134
+ interface Tokenizer {
135
+ encode(text: string): number[];
136
+ decode(tokens: number[]): string;
137
+ count(text: string): number;
138
+ }
139
+
140
+ // Provider-specific tokenizer implementations
141
+ class OpenAITokenizer implements Tokenizer { ... }
142
+ class AnthropicTokenizer implements Tokenizer { ... }
143
+ class GeminiTokenizer implements Tokenizer { ... }
144
+ ```
145
+
146
+ ### Implementation Approach
147
+
148
+ 1. **Token Counting**: Use provider-specific tokenizers (tiktoken for OpenAI, etc.)
149
+ 2. **Limit Detection**: Map model names to context limits
150
+ 3. **Usage Tracking**: Track cumulative usage across conversation
151
+ 4. **Compaction Strategy**:
152
+ - Preserve system prompt and memory context
153
+ - Keep recent N messages (configurable)
154
+ - Summarize older messages into a concise summary
155
+ - Preserve tool results that are still relevant
156
+ 5. **Auto-Compaction**: Trigger when usage exceeds threshold
157
+
158
+ ```typescript
159
+ // Context limits by provider/model
160
+ const CONTEXT_LIMITS: Record<string, number> = {
161
+ 'gpt-4': 8192,
162
+ 'gpt-4-turbo': 128000,
163
+ 'gpt-4o': 128000,
164
+ 'claude-3-opus': 200000,
165
+ 'claude-3-sonnet': 200000,
166
+ 'claude-3-haiku': 200000,
167
+ 'gemini-1.5-pro': 2000000,
168
+ 'gemini-1.5-flash': 1000000,
169
+ };
170
+ ```
171
+
172
+ ### Memory Tool Implementation
173
+
174
+ ```typescript
175
+ // src/context/memory-tool.ts
176
+ import { Tool, ToolContext, ToolResult } from '../tools/types';
177
+ import { z } from 'zod';
178
+ import * as fs from 'fs';
179
+ import * as path from 'path';
180
+
181
+ const MemoryInputSchema = z.object({
182
+ command: z.enum(['view', 'create', 'str_replace', 'insert', 'delete', 'rename']),
183
+ path: z.string(),
184
+ file_text: z.string().optional(),
185
+ view_range: z.tuple([z.number(), z.number()]).optional(),
186
+ old_str: z.string().optional(),
187
+ new_str: z.string().optional(),
188
+ insert_line: z.number().optional(),
189
+ insert_text: z.string().optional(),
190
+ old_path: z.string().optional(),
191
+ new_path: z.string().optional(),
192
+ });
193
+
194
+ export class MemoryTool implements Tool<z.infer<typeof MemoryInputSchema>> {
195
+ name = 'memory';
196
+ description = `Store and retrieve information across context resets.
197
+ Commands: view, create, str_replace, insert, delete, rename.
198
+ Use /memories as the base path.`;
199
+
200
+ parameters = MemoryInputSchema;
201
+ private baseDir: string;
202
+
203
+ constructor(baseDir?: string) {
204
+ this.baseDir = baseDir || path.join(process.env.HOME || '~', '.mycode', 'memories');
205
+ if (!fs.existsSync(this.baseDir)) {
206
+ fs.mkdirSync(this.baseDir, { recursive: true });
207
+ }
208
+ }
209
+
210
+ async execute(input: z.infer<typeof MemoryInputSchema>): Promise<ToolResult> {
211
+ const sanitizedPath = this.sanitizePath(input.path);
212
+ if (!sanitizedPath) {
213
+ return { error: `Invalid path: ${input.path}` };
214
+ }
215
+
216
+ switch (input.command) {
217
+ case 'view':
218
+ return this.handleView(sanitizedPath, input.view_range);
219
+ case 'create':
220
+ return this.handleCreate(sanitizedPath, input.file_text || '');
221
+ case 'str_replace':
222
+ return this.handleStrReplace(sanitizedPath, input.old_str!, input.new_str!);
223
+ case 'insert':
224
+ return this.handleInsert(sanitizedPath, input.insert_line!, input.insert_text!);
225
+ case 'delete':
226
+ return this.handleDelete(sanitizedPath);
227
+ case 'rename':
228
+ return this.handleRename(sanitizedPath, this.sanitizePath(input.new_path!)!);
229
+ default:
230
+ return { error: `Unknown command: ${input.command}` };
231
+ }
232
+ }
233
+
234
+ private sanitizePath(inputPath: string): string | null {
235
+ const normalized = inputPath.replace(/^\/memories\/?/, '');
236
+ const fullPath = path.join(this.baseDir, normalized);
237
+ const resolved = path.resolve(fullPath);
238
+ if (!resolved.startsWith(this.baseDir)) return null;
239
+ return resolved;
240
+ }
241
+
242
+ private handleView(filePath: string, range?: [number, number]): ToolResult {
243
+ if (!fs.existsSync(filePath)) {
244
+ return { error: `Path does not exist: ${filePath}` };
245
+ }
246
+ const stat = fs.statSync(filePath);
247
+ if (stat.isDirectory()) {
248
+ const entries = fs.readdirSync(filePath);
249
+ return { content: `Directory contents:\n${entries.join('\n')}` };
250
+ }
251
+ const content = fs.readFileSync(filePath, 'utf-8');
252
+ const lines = content.split('\n');
253
+ const start = range ? range[0] - 1 : 0;
254
+ const end = range ? range[1] : lines.length;
255
+ return {
256
+ content: lines.slice(start, end).map((l, i) =>
257
+ `${String(start + i + 1).padStart(6)} ${l}`
258
+ ).join('\n')
259
+ };
260
+ }
261
+
262
+ private handleCreate(filePath: string, content: string): ToolResult {
263
+ if (fs.existsSync(filePath)) {
264
+ return { error: `File already exists: ${filePath}` };
265
+ }
266
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
267
+ fs.writeFileSync(filePath, content, 'utf-8');
268
+ return { content: `File created: ${filePath}` };
269
+ }
270
+
271
+ private handleStrReplace(filePath: string, oldStr: string, newStr: string): ToolResult {
272
+ const content = fs.readFileSync(filePath, 'utf-8');
273
+ if (!content.includes(oldStr)) {
274
+ return { error: `String not found: ${oldStr}` };
275
+ }
276
+ fs.writeFileSync(filePath, content.replace(oldStr, newStr), 'utf-8');
277
+ return { content: 'File updated successfully' };
278
+ }
279
+
280
+ private handleInsert(filePath: string, line: number, text: string): ToolResult {
281
+ const content = fs.readFileSync(filePath, 'utf-8');
282
+ const lines = content.split('\n');
283
+ lines.splice(line, 0, text);
284
+ fs.writeFileSync(filePath, lines.join('\n'), 'utf-8');
285
+ return { content: `Inserted at line ${line}` };
286
+ }
287
+
288
+ private handleDelete(filePath: string): ToolResult {
289
+ fs.rmSync(filePath, { recursive: true });
290
+ return { content: `Deleted: ${filePath}` };
291
+ }
292
+
293
+ private handleRename(oldPath: string, newPath: string): ToolResult {
294
+ fs.renameSync(oldPath, newPath);
295
+ return { content: `Renamed to: ${newPath}` };
296
+ }
297
+ }
298
+ ```
299
+
300
+ ### File Changes
301
+
302
+ | File | Action | Description |
303
+ |------|--------|-------------|
304
+ | `src/context/types.ts` | Create | Context management types |
305
+ | `src/context/context-manager.ts` | Create | Core context manager |
306
+ | `src/context/memory-tool.ts` | Create | Memory tool implementation |
307
+ | `src/context/tokenizer.ts` | Create | Token counting implementations |
308
+ | `src/context/compactor.ts` | Create | Conversation compaction logic |
309
+ | `src/context/index.ts` | Create | Module exports |
310
+ | `src/agent/agent.ts` | Modify | Integrate context management |
311
+ | `src/session/session-manager.ts` | Modify | Store context stats in session |
312
+ | `src/providers/types.ts` | Modify | Add token usage to responses |
313
+
314
+ ## User Experience
315
+
316
+ ### Status Display
317
+ Show context usage in the CLI status line:
318
+
319
+ ```
320
+ mycode v0.2.0 | gpt-4o | Context: 45% (58K/128K tokens)
321
+ ```
322
+
323
+ ### Warning Messages
324
+ Warn users when approaching limits:
325
+
326
+ ```
327
+ ⚠️ Context usage at 80% (102K/128K tokens)
328
+ Consider using /compact to summarize older messages
329
+ ```
330
+
331
+ ### Auto-Compaction
332
+ Automatically compact when needed:
333
+
334
+ ```
335
+ 📦 Auto-compacting conversation (90% context usage)
336
+ Summarized 45 messages, saved 52K tokens
337
+ Conversation coherence preserved
338
+ ```
339
+
340
+ ### Manual Compaction
341
+ Users can manually compact:
342
+
343
+ ```
344
+ > /compact
345
+ Compacting conversation...
346
+ Removed: 32 messages
347
+ Saved: 41K tokens
348
+ Summary: "Discussion about implementing authentication..."
349
+ ```
350
+
351
+ ### Context Command
352
+ View detailed context information:
353
+
354
+ ```
355
+ > /context
356
+ Context Usage:
357
+ Current: 58,432 tokens (45.6%)
358
+ Maximum: 128,000 tokens
359
+ Messages: 47
360
+ Oldest: 2 hours ago
361
+
362
+ Breakdown:
363
+ System prompt: 1,200 tokens
364
+ Memory context: 800 tokens
365
+ Conversation: 56,432 tokens
366
+ ```
367
+
368
+ ## Alternatives Considered
369
+
370
+ ### Alternative 1: Simple Truncation
371
+ Just remove oldest messages when limit reached.
372
+
373
+ **Pros**: Simple implementation
374
+ **Cons**: Loses important context, poor UX
375
+ **Decision**: Rejected - Summarization preserves more value
376
+
377
+ ### Alternative 2: External Summarization API
378
+ Use a separate API call to summarize.
379
+
380
+ **Pros**: Better summaries
381
+ **Cons**: Additional cost, latency
382
+ **Decision**: Partially adopted - Use same provider for summarization
383
+
384
+ ### Alternative 3: No Auto-Compaction
385
+ Only manual compaction via command.
386
+
387
+ **Pros**: User control
388
+ **Cons**: Sessions crash unexpectedly
389
+ **Decision**: Rejected - Auto-compaction is essential for UX
390
+
391
+ ## Security Considerations
392
+
393
+ 1. **Token Counting Accuracy**: Inaccurate counting could lead to context overflow
394
+ 2. **Compaction Privacy**: Summaries should not leak sensitive information
395
+ 3. **Rate Limiting**: Compaction uses API calls, respect rate limits
396
+ 4. **Caching**: Don't cache sensitive token counts
397
+
398
+ ## Testing Strategy
399
+
400
+ 1. **Unit Tests**:
401
+ - Token counting accuracy for each provider
402
+ - Limit detection for all supported models
403
+ - Compaction logic with various message types
404
+
405
+ 2. **Integration Tests**:
406
+ - End-to-end context tracking
407
+ - Auto-compaction triggering
408
+ - Session persistence of context stats
409
+
410
+ 3. **Load Testing**:
411
+ - Very long conversations
412
+ - Large tool outputs
413
+ - Rapid message sequences
414
+
415
+ ## Migration Path
416
+
417
+ 1. **Phase 1**: Token counting and limit detection
418
+ 2. **Phase 2**: Context stats display and warnings
419
+ 3. **Phase 3**: Manual compaction command
420
+ 4. **Phase 4**: Auto-compaction implementation
421
+ 5. **Phase 5**: Optimized compaction strategies
422
+
423
+ Existing sessions will work without context stats; stats begin tracking on first message after upgrade.
424
+
425
+ ## References
426
+
427
+ - [Claude Code Context Management](https://code.claude.com/docs/en/context)
428
+ - [OpenAI Tokenizer (tiktoken)](https://github.com/openai/tiktoken)
429
+ - [Anthropic Token Counting](https://docs.anthropic.com/en/docs/tokens)