@ebowwa/coder 0.1.12 → 0.2.1
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 +56 -24
- package/dist/cli.js +60 -81
- package/dist/index-1eawy937.js +308 -0
- package/dist/index-29xcjnne.js +280 -0
- package/dist/index-2avyytn5.js +349 -0
- package/dist/index-4xfgd8nz.js +261 -0
- package/dist/index-6e4wf341.js +349 -0
- package/dist/index-77ckwnbm.js +280 -0
- package/dist/index-bk21w99v.js +280 -0
- package/dist/index-cb4ppjdt.js +255 -0
- package/dist/index-cmfa38hh.js +308 -0
- package/dist/index-datjz8q1.js +257 -0
- package/dist/index-em5k0m3z.js +345 -0
- package/dist/index-gkx6k2tr.js +261 -0
- package/dist/index-hcrpwyy3.js +261 -0
- package/dist/index-hk7fwwa8.js +257 -0
- package/dist/index-kbyw4th1.js +347 -0
- package/dist/index-kgj5gqnm.js +345 -0
- package/dist/index-mdf6xp1z.js +255 -0
- package/dist/index-mrhv8kvc.js +280 -0
- package/dist/index-qwdy6x44.js +261 -0
- package/dist/index-sbbw1a61.js +349 -0
- package/dist/index-svy5bcpn.js +345 -0
- package/dist/index-tvmy7tm9.js +261 -0
- package/dist/index-tzz4vzkj.js +312 -0
- package/dist/index-wksgzz8e.js +280 -0
- package/dist/index-xha05vjc.js +257 -0
- package/dist/index.js +1 -16
- package/native/claude_code_native.dylib +0 -0
- package/native/index.d.ts +0 -50
- package/native/index.darwin-arm64.node +0 -0
- package/native/index.js +1 -1
- package/native/package.json +4 -4
- package/package.json +19 -15
package/README.md
CHANGED
|
@@ -1,25 +1,17 @@
|
|
|
1
|
-
# @ebowwa/
|
|
1
|
+
# @ebowwa/coder
|
|
2
2
|
|
|
3
3
|
A reimplementation of Claude Code CLI using TypeScript + Bun + Rust.
|
|
4
4
|
|
|
5
5
|
Based on binary analysis of Claude Code v2.1.50 (~92% feature parity).
|
|
6
6
|
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
- **API Client**: SSE streaming for Anthropic API with cost calculation
|
|
10
|
-
- **Agent Loop**: Turn-based processing with tool execution
|
|
11
|
-
- **Built-in Tools**: Read, Write, Edit, Bash, Glob, Grep
|
|
12
|
-
- **MCP Client**: Model Context Protocol support (stdio, HTTP, SSE, WebSocket)
|
|
13
|
-
- **Hook System**: 10 lifecycle events for customization
|
|
14
|
-
- **Skill System**: YAML frontmatter skills with `/skillname` invocation
|
|
15
|
-
- **Teammate System**: Multi-agent coordination with tmux backend
|
|
16
|
-
- **Native Module**: Rust-based performance for search, tokens, diff, compact
|
|
17
|
-
|
|
18
7
|
## Installation
|
|
19
8
|
|
|
20
9
|
```bash
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
# Install globally
|
|
11
|
+
npm install -g @ebowwa/coder
|
|
12
|
+
|
|
13
|
+
# Or with bun
|
|
14
|
+
bun add -g @ebowwa/coder
|
|
23
15
|
```
|
|
24
16
|
|
|
25
17
|
## Usage
|
|
@@ -28,22 +20,22 @@ bun run build
|
|
|
28
20
|
|
|
29
21
|
```bash
|
|
30
22
|
# Interactive mode
|
|
31
|
-
|
|
23
|
+
coder
|
|
32
24
|
|
|
33
25
|
# Single query
|
|
34
|
-
|
|
26
|
+
coder "What files are in this directory?"
|
|
35
27
|
|
|
36
28
|
# With specific model
|
|
37
|
-
|
|
29
|
+
coder -m claude-opus-4-6 "Explain this codebase"
|
|
38
30
|
|
|
39
31
|
# With permission mode
|
|
40
|
-
|
|
32
|
+
coder --permission-mode acceptEdits "Add a test"
|
|
41
33
|
```
|
|
42
34
|
|
|
43
35
|
### Programmatic
|
|
44
36
|
|
|
45
37
|
```typescript
|
|
46
|
-
import { createMessageStream, agentLoop, tools } from "@ebowwa/
|
|
38
|
+
import { createMessageStream, agentLoop, tools } from "@ebowwa/coder";
|
|
47
39
|
|
|
48
40
|
// Stream API messages
|
|
49
41
|
const result = await createMessageStream(messages, {
|
|
@@ -62,13 +54,37 @@ const agentResult = await agentLoop(messages, {
|
|
|
62
54
|
});
|
|
63
55
|
```
|
|
64
56
|
|
|
57
|
+
## Features
|
|
58
|
+
|
|
59
|
+
- **API Client**: SSE streaming for Anthropic API with cost calculation
|
|
60
|
+
- **Agent Loop**: Turn-based processing with tool execution
|
|
61
|
+
- **Built-in Tools**: Read, Write, Edit, Bash, Glob, Grep
|
|
62
|
+
- **MCP Client**: Model Context Protocol support (stdio, HTTP, SSE, WebSocket)
|
|
63
|
+
- **Hook System**: 10 lifecycle events for customization
|
|
64
|
+
- **Skill System**: YAML frontmatter skills with `/skillname` invocation
|
|
65
|
+
- **Teammate System**: Multi-agent coordination with tmux backend
|
|
66
|
+
- **Native Module**: Rust-based performance for critical operations
|
|
67
|
+
|
|
68
|
+
## Native Modules (Rust)
|
|
69
|
+
|
|
70
|
+
The `@ebowwa/coder-native` package provides high-performance operations:
|
|
71
|
+
|
|
72
|
+
| Module | Description |
|
|
73
|
+
|--------|-------------|
|
|
74
|
+
| **grep** | Ripgrep-based file search with regex support |
|
|
75
|
+
| **hash** | xxHash3/SHA-256 content hashing |
|
|
76
|
+
| **highlight** | Syntax highlighting with syntect |
|
|
77
|
+
| **structure** | Tree-sitter code structure parsing |
|
|
78
|
+
| **patterns** | Tool usage pattern analysis |
|
|
79
|
+
| **multi_edit** | Batch file editing with validation |
|
|
80
|
+
|
|
65
81
|
## Project Structure
|
|
66
82
|
|
|
67
83
|
```
|
|
68
84
|
claude-code-remake/
|
|
69
85
|
├── src/
|
|
70
86
|
│ ├── types/ # TypeScript type definitions
|
|
71
|
-
│ ├── core/ # API client, agent loop
|
|
87
|
+
│ ├── core/ # API client, agent loop, checkpoints
|
|
72
88
|
│ ├── tools/ # Built-in tools (Read, Write, Edit, Bash, etc.)
|
|
73
89
|
│ ├── mcp/ # MCP client implementation
|
|
74
90
|
│ ├── hooks/ # Hook system for lifecycle events
|
|
@@ -78,10 +94,13 @@ claude-code-remake/
|
|
|
78
94
|
│ └── cli.ts # CLI entry point
|
|
79
95
|
├── rust/
|
|
80
96
|
│ └── src/
|
|
81
|
-
│ ├──
|
|
82
|
-
│ ├──
|
|
83
|
-
│ ├──
|
|
84
|
-
│
|
|
97
|
+
│ ├── grep.rs # Ripgrep-based file search
|
|
98
|
+
│ ├── hash.rs # Content hashing (xxHash3, SHA-256)
|
|
99
|
+
│ ├── highlight.rs # Syntax highlighting
|
|
100
|
+
│ ├── structure.rs # Tree-sitter parsing
|
|
101
|
+
│ ├── patterns.rs # Tool pattern analysis
|
|
102
|
+
│ ├── multi_edit.rs # Batch file operations
|
|
103
|
+
│ └── diff.rs # Diff calculation
|
|
85
104
|
├── native/ # Compiled native modules
|
|
86
105
|
└── dist/ # Build output
|
|
87
106
|
```
|
|
@@ -105,6 +124,9 @@ claude-code-remake/
|
|
|
105
124
|
## Development
|
|
106
125
|
|
|
107
126
|
```bash
|
|
127
|
+
# Install dependencies
|
|
128
|
+
bun install
|
|
129
|
+
|
|
108
130
|
# Build TypeScript
|
|
109
131
|
bun run build:ts
|
|
110
132
|
|
|
@@ -116,8 +138,18 @@ bun run build
|
|
|
116
138
|
|
|
117
139
|
# Development mode with watch
|
|
118
140
|
bun run dev
|
|
141
|
+
|
|
142
|
+
# Run tests
|
|
143
|
+
bun test
|
|
119
144
|
```
|
|
120
145
|
|
|
146
|
+
## Packages
|
|
147
|
+
|
|
148
|
+
| Package | Version | Description |
|
|
149
|
+
|---------|---------|-------------|
|
|
150
|
+
| [@ebowwa/coder](https://www.npmjs.com/package/@ebowwa/coder) | 0.2.0 | Main CLI package |
|
|
151
|
+
| [@ebowwa/coder-native](https://www.npmjs.com/package/@ebowwa/coder-native) | 0.2.0 | Native Rust modules |
|
|
152
|
+
|
|
121
153
|
## License
|
|
122
154
|
|
|
123
155
|
MIT
|
package/dist/cli.js
CHANGED
|
@@ -1,33 +1,43 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
import{A as
|
|
4
|
-
`)
|
|
5
|
-
`))
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
${
|
|
14
|
-
|
|
15
|
-
|
|
3
|
+
import{A as vW,Da as kW,E as o,a as PZ,pa as IW,sa as xW,t as WW,ta as fW,u as l,w as ZW,y as yW,ya as RW,za as LW}from"./index-6e4wf341.js";var $={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",italic:"\x1B[3m",underline:"\x1B[4m",strikethrough:"\x1B[9m",purple:"\x1B[38;2;180;142;173m",blue:"\x1B[38;2;143;161;179m",green:"\x1B[38;2;163;190;140m",orange:"\x1B[38;2;208;135;112m",red:"\x1B[38;2;191;97;106m",cyan:"\x1B[38;2;150;181;180m",gray:"\x1B[38;2;192;197;206m",yellow:"\x1B[38;2;235;203;139m",comment:"\x1B[38;2;101;115;126m",header:"\x1B[38;2;143;161;179m\x1B[1m",link:"\x1B[38;2;150;181;180m\x1B[4m",list:"\x1B[38;2;180;142;173m",blockquote:"\x1B[38;2;101;115;126m\x1B[3m",hr:"\x1B[38;2;101;115;126m",tableBorder:"\x1B[38;2;143;161;179m",tableHeader:"\x1B[38;2;180;142;173m\x1B[1m",money:"\x1B[38;2;163;190;140m",moneyLoss:"\x1B[38;2;191;97;106m",moneyGain:"\x1B[38;2;140;190;140m\x1B[1m",percentUp:"\x1B[38;2;163;190;140m",percentDown:"\x1B[38;2;191;97;106m",ticker:"\x1B[38;2;235;203;139m\x1B[1m",crypto:"\x1B[38;2;247;140;108m",timestamp:"\x1B[38;2;101;115;126m",math:"\x1B[38;2;180;142;173m",bullish:"\x1B[38;2;163;190;140m\x1B[1m",bearish:"\x1B[38;2;191;97;106m\x1B[1m",neutral:"\x1B[38;2;235;203;139m",priceTarget:"\x1B[38;2;143;161;179m\x1B[4m"},QW={$:"USD","\u20AC":"EUR","\xA3":"GBP","\xA5":"JPY","\u20B9":"INR","\u20BD":"RUB","\u20A9":"KRW","\u20BF":"BTC","\u039E":"ETH","\u20AE":"USDT","\u20B3":"ADA","\u20B4":"UAH","\u20B8":"KZT","\u20BA":"TRY","\u20BC":"AZN","\u20AA":"ILS","\u20AB":"VND","\u20AD":"LAK","\u20B1":"PHP","\u20B2":"PYG","\u20B5":"GHS","\u20A1":"CRC","\u20A6":"NGN","\u20A3":"CHF","\u20A4":"TRY"},dW=new Set(["BTC","ETH","USDT","BNB","XRP","SOL","USDC","ADA","DOGE","DOT","MATIC","LTC","SHIB","TRX","AVAX","LINK","ATOM","UNI","XMR","ETC","XLM","BCH","APT","NEAR","FIL","LDO","ARB","OP","HBAR","VET","ICP","QNT","AAVE","GRT","ALGO","SAND","MANA","AXS","FTM","EGLD","SUSHI","THETA","XTZ","EOS","FLOW","CHZ","SNX","LUNC","RUNE","KAVA","CRV","COMP","YFI","MKR","ZEC","DASH","NEO","WAVES","ENJ","BAT","1INCH","ANKR","CELO","CVC","DIA","GNO","KNC","OCEAN","OMG","REN","RLC","STORJ","SYN","UMA","ZRX","BLUR","DYDX","GMX","PEPE","BONK","WIF","FLOKI","INJ","SUI","SEI","TIA","IMX","ORDI","JUP","W"]);var SW=new Set(["bull","bullish","long","buy","call","pump","moon","rocket","lambo","hold","hodl","diamond","hands","gains","profit","rally","surge","breakout","uptrend","accumulation","support","bounce","recovery","all-time high","ath","bagholder","whale buy","accumulation","undervalued"]),CW=new Set(["bear","bearish","short","sell","put","dump","crash","dump","rekt","liquidated","loss","bleed","downtrend","breakdown","resistance","correction","dip"," capitulation","panic sell","overvalued","bubble"]);function XW(Z){let W=Z.split(`
|
|
4
|
+
`).filter((J)=>J.length>0);if(W.length<3)return!1;let X=0;for(let J of W.slice(0,10))if(J.startsWith("+++")||J.startsWith("---")||J.startsWith("@@")||J.startsWith("diff ")||J.startsWith("index "))X++;let Q=0,z=0;for(let J of W){if(J.startsWith("+")&&!J.startsWith("+++"))Q++;if(J.startsWith("-")&&!J.startsWith("---"))z++}return X>=2||Q>0&&z>0}function n(Z){let W=Z.split(`
|
|
5
|
+
`),X=[];for(let Q of W)if(Q.startsWith("@@")){let z=Q.match(/^(@@ -\d+(?:,\d+)? \+\d+(?:,\d+)? @@)(.*)$/);if(z)X.push(`${$.cyan}${z[1]}${$.reset}${$.dim}${z[2]}${$.reset}`);else X.push(`${$.cyan}${Q}${$.reset}`)}else if(Q.startsWith("+++")||Q.startsWith("---")){let z=Q.startsWith("+++")?"+":"-",J=Q.slice(3);X.push(`${$.bold}${z}${z}${z}${$.reset}${$.cyan}${J}${$.reset}`)}else if(Q.startsWith("diff --git"))X.push(`${$.dim}${Q}${$.reset}`);else if(Q.startsWith("index "))X.push(`${$.dim}${Q}${$.reset}`);else if(Q.startsWith("new file")||Q.startsWith("deleted file"))X.push(`${$.yellow}${Q}${$.reset}`);else if(Q.startsWith("Binary files"))X.push(`${$.yellow}${Q}${$.reset}`);else if(Q.startsWith("rename from")||Q.startsWith("rename to"))X.push(`${$.purple}${Q}${$.reset}`);else if(Q.startsWith("similarity index"))X.push(`${$.dim}${Q}${$.reset}`);else if(Q.startsWith("+"))if(Q==="+")X.push(`${$.green}+${$.reset}`);else X.push(`${$.green}+${Q.slice(1)}${$.reset}`);else if(Q.startsWith("-"))if(Q==="-")X.push(`${$.red}-${$.reset}`);else X.push(`${$.red}-${Q.slice(1)}${$.reset}`);else if(Q.startsWith(" ")||Q==="")X.push(`${$.dim}${Q}${$.reset}`);else if(Q.match(/^(={67}|>{67}|<{67})/))X.push(`${$.dim}${Q}${$.reset}`);else if(Q.startsWith("***************"))X.push(`${$.cyan}${Q}${$.reset}`);else if(Q.startsWith("*** ")||Q.startsWith("--- "))X.push(`${$.cyan}${Q}${$.reset}`);else X.push(Q);return X.join(`
|
|
6
|
+
`)}function pW(Z){if(Z.includes("```"))return Z;return Z.replace(/`([^`\n]+)`/g,(W,X)=>{return`${$.dim}\`${$.orange}${X}${$.dim}\`${$.reset}`}).replace(/``([^`\n]+)``/g,(W,X)=>{return`${$.dim}\`\`${$.orange}${X}${$.dim}\`\`${$.reset}`})}function hW(Z){if(/\[[^\]]+\]\([^)]+\)/.test(Z))return Z;return Z.replace(/(https?:\/\/[^\s<>\[\]()]+)/g,`${$.link}$1${$.reset}`)}function OW(Z){return Z.replace(/:([a-z0-9_+-]+):/g,(W,X)=>{return`${$.yellow}:${X}:${$.reset}`})}function gW(Z){if(Z.includes("```")||Z.includes("\x1B["))return Z;let W=new RegExp(`([${Object.keys(QW).join("")}])\\s?([\\d,]+(?:\\.\\d{1,8})?)`,"g"),X=Z.replace(W,(Q,z,J)=>{let K=QW[z]||"";return`${$.money}${z}${J}${$.reset}`});return X=X.replace(/\b(USD|EUR|GBP|JPY|CAD|AUD|CHF|CNY|INR|MXN|BRL|KRW|SGD|HKD|NOK|SEK|DKK|NZD|ZAR|RUB|TRY|PLN|THB|IDR|MYR|PHP|VND)\s+([\d,]+(?:\.\d{1,8})?)/gi,(Q,z,J)=>`${$.money}${z} ${J}${$.reset}`),X}function cW(Z){if(Z.includes("```"))return Z;let W=Z,X=new RegExp(`([\\d,]+(?:\\.\\d{1,8})?)\\s*(${Array.from(dW).join("|")})(?=\\s|\\.|,|:|;|!|\\?|$)`,"gi");return W=W.replace(X,(Q,z,J)=>{let K=J.toUpperCase();return`${$.crypto}${z} ${K}${$.reset}`}),W=W.replace(/([\d,]+(?:\.\d{1,8})?)\s*(sats?|satoshis?)(?=\s|\.|,|:|;|!|\?|$)/gi,(Q,z,J)=>{return`${$.crypto}${z} ${J.toLowerCase()}${$.reset}`}),W=W.replace(/([\d,]+(?:\.\d{1,2})?)\s*gwei(?=\s|\.|,|:|;|!|\?|$)/gi,(Q,z)=>{return`${$.crypto}${z} gwei${$.reset}`}),W=W.replace(/([\d,]+)\s*wei(?=\s|\.|,|:|;|!|\?|$)/gi,(Q,z)=>{return`${$.dim}${z} wei${$.reset}`}),W}function uW(Z){if(Z.includes("```")||Z.includes("\x1B["))return Z;let W=Z;return W=W.replace(/(^|\s)\+([\d,]+(?:\.\d{1,4})?)\s*%/gm,(X,Q,z)=>`${Q}${$.percentUp}+${z}%${$.reset}`),W=W.replace(/(^|\s)-([\d,]+(?:\.\d{1,4})?)\s*%/gm,(X,Q,z)=>`${Q}${$.percentDown}-${z}%${$.reset}`),W=W.replace(/(^|\s)([\d,]+(?:\.\d{1,4})?)\s*%/gm,(X,Q,z)=>`${Q}${$.orange}${z}%${$.reset}`),W}function lW(Z){if(Z.includes("```")||Z.includes("\x1B["))return Z;return Z.replace(/(?<![a-zA-Z0-9])\$([A-Z]{1,5})(?![a-zA-Z0-9])/g,(W,X)=>`${$.ticker}$${X}${$.reset}`)}function aW(Z){if(Z.includes("```")||Z.includes("\x1B["))return Z;let W=Z,X=new RegExp(`\\b(${Array.from(SW).join("|")})\\b`,"gi");W=W.replace(X,(z)=>{return`${$.bullish}${z}${$.reset}`});let Q=new RegExp(`\\b(${Array.from(CW).join("|")})\\b`,"gi");return W=W.replace(Q,(z)=>{return`${$.bearish}${z}${$.reset}`}),W}function nW(Z){if(Z.includes("```"))return Z;let W=Z;return W=W.replace(/\b(?:PT|price target|target|TP|take profit)\s*:?\s*([\$\u20AC\u00A3\u00A5]?\s*[\d,]+(?:\.\d{1,4})?)/gi,(X,Q)=>`${$.priceTarget}PT: ${Q}${$.reset}`),W=W.replace(/\b(?:SL|stop loss|stop)\s*:?\s*([\$\u20AC\u00A3\u00A5]?\s*[\d,]+(?:\.\d{1,4})?)/gi,(X,Q)=>`${$.red}SL: ${Q}${$.reset}`),W=W.replace(/\b(?:entry|enter|buy in)\s*:?\s*([\$\u20AC\u00A3\u00A5]?\s*[\d,]+(?:\.\d{1,4})?)/gi,(X,Q)=>`${$.green}Entry: ${Q}${$.reset}`),W=W.replace(/([\$\u20AC\u00A3\u00A5]?\s*[\d,]+(?:\.\d{1,4})?)\s*[-\u2013]\s*([\$\u20AC\u00A3\u00A5]?\s*[\d,]+(?:\.\d{1,4})?)/g,(X,Q,z)=>`${$.money}${Q}-${z}${$.reset}`),W}function iW(Z){if(Z.includes("```")||Z.includes("\x1B["))return Z;let W=Z;return W=W.replace(/\b(\d{4}-\d{2}-\d{2})\b/g,(X,Q)=>`${$.timestamp}${Q}${$.reset}`),W=W.replace(/\b(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(Z)?\b/g,(X,Q,z)=>`${$.timestamp}${Q}${z||""}${$.reset}`),W=W.replace(/\b(\d{2}:\d{2}:\d{2})\b/g,(X,Q)=>`${$.timestamp}${Q}${$.reset}`),W=W.replace(/\b(\d+)\s*(second|minute|hour|day|week|month|year)s?\s+ago\b/gi,(X,Q,z)=>`${$.timestamp}${Q} ${z}s ago${$.reset}`),W}function oW(Z){if(Z.includes("```")||Z.includes("\x1B["))return Z;let W=Z;return W=W.replace(/\b(pi|\u03C0|euler|infinity|inf)\b/gi,(X,Q)=>`${$.orange}${Q}${$.reset}`),W=W.replace(/(\d)\^(\d+)/g,(X,Q,z)=>`${$.math}${Q}^${z}${$.reset}`),W=W.replace(/(\d+\.\d+)[eE]([+-]?\d+)/g,(X,Q,z)=>`${$.orange}${Q}e${z}${$.reset}`),W}function rW(Z){if(Z.includes("```"))return Z;let W=Z;return W=W.replace(/\b(?:P\/L|PnL|profit\/loss|PL)\s*:?\s*([+\-]?[\$\u20AC\u00A3\u00A5]?\s*[\d,]+(?:\.\d{1,4})?)/gi,(X,Q)=>{return`${!Q.startsWith("-")?$.moneyGain:$.moneyLoss}P/L: ${Q}${$.reset}`}),W=W.replace(/\b(?:ROI|return)\s*:?\s*([+\-]?[\d,]+(?:\.\d{1,2})?\s*%)/gi,(X,Q)=>{return`${!Q.startsWith("-")?$.percentUp:$.percentDown}ROI: ${Q}${$.reset}`}),W=W.replace(/\b(unrealized|realized)\s+(p\/l|pnl|profit|loss)\s*:?\s*([+\-]?[\$\u20AC\u00A3\u00A5]?\s*[\d,]+(?:\.\d{1,4})?)/gi,(X,Q,z,J)=>{return`${!J.startsWith("-")?$.moneyGain:$.moneyLoss}${Q} P/L: ${J}${$.reset}`}),W}function sW(Z){if(Z.includes("```"))return Z;let W=Z;return W=W.replace(/\b(?:O|Open)\s*:?\s*([\d,]+(?:\.\d{1,8})?)/gi,(X,Q)=>`${$.neutral}O: ${Q}${$.reset}`),W=W.replace(/\b(?:H|High)\s*:?\s*([\d,]+(?:\.\d{1,8})?)/gi,(X,Q)=>`${$.moneyGain}H: ${Q}${$.reset}`),W=W.replace(/\b(?:L|Low)\s*:?\s*([\d,]+(?:\.\d{1,8})?)/gi,(X,Q)=>`${$.moneyLoss}L: ${Q}${$.reset}`),W=W.replace(/\b(?:C|Close)\s*:?\s*([\d,]+(?:\.\d{1,8})?)/gi,(X,Q)=>`${$.neutral}C: ${Q}${$.reset}`),W=W.replace(/\b(?:V|Vol|Volume)\s*:?\s*([\d,]+(?:\.\d{1,2})?[KkMmBb]?)/gi,(X,Q)=>`${$.cyan}Vol: ${Q}${$.reset}`),W=W.replace(/\b(?:MCap|Market Cap|Market Capitalization)\s*:?\s*([\$\u20AC\u00A3\u00A5]?\s*[\d,]+(?:\.\d{1,2})?[KkMmBbTt]?)/gi,(X,Q)=>`${$.money}MCap: ${Q}${$.reset}`),W}function tW(Z){if(Z.includes("\x1B[")||Z.includes("```"))return Z;let W=Z;return W=cW(W),W=gW(W),W=uW(W),W=rW(W),W=nW(W),W=sW(W),W=lW(W),W=aW(W),W=iW(W),W=oW(W),W}function eW(Z){let W=Z;if(Z.includes("```"))return W;return W=W.replace(/^( {0,3})([-*_])( {0,2}\2){2,}$/gm,`${$.hr}$1$2$2$2${$.reset}`),W=W.replace(/^(#{1,6})\s+(.+)$/gm,(X,Q,z)=>{let J=Q.length;if(J===1)return`${$.bold}${$.blue}${Q} ${z}${$.reset}`;else if(J===2)return`${$.bold}${$.cyan}${Q} ${z}${$.reset}`;return`${$.header}${Q} ${z}${$.reset}`}),W=W.replace(/^(.+)\n([=]+)$/gm,(X,Q,z)=>{return`${$.bold}${$.blue}${Q}${$.reset}
|
|
7
|
+
${$.hr}${z}${$.reset}`}),W=W.replace(/^(.+)\n([-]+)$/gm,(X,Q,z)=>{return`${$.bold}${$.cyan}${Q}${$.reset}
|
|
8
|
+
${$.hr}${z}${$.reset}`}),W=W.replace(/^(>{1,})\s?(.*)$/gm,(X,Q,z)=>{let K=Q.length>1?$.dim:$.blockquote;return`${$.green}${Q}${$.reset} ${K}${z}${$.reset}`}),W=W.replace(/^\|(.+)\|\s*$/gm,(X,Q)=>{let J=Q.split("|").map((K)=>{let Y=K.trim();if(Y)return` ${$.gray}${Y}${$.reset} `;return K}).join(`${$.tableBorder}|${$.reset}`);return`${$.tableBorder}|${$.reset}${J}${$.tableBorder}|${$.reset}`}),W=W.replace(/^\|([-:\s|]+)\|\s*$/gm,(X,Q)=>{return`${$.tableBorder}|${Q}|${$.reset}`}),W=W.replace(/\*\*([^*]+)\*\*/g,`${$.bold}$1${$.reset}`),W=W.replace(/__([^_]+)__/g,`${$.bold}$1${$.reset}`),W=W.replace(/~~([^~]+)~~/g,`${$.strikethrough}${$.dim}$1${$.reset}`),W=W.replace(/(?<![a-zA-Z\*])\*([^*]+)\*(?![a-zA-Z\*])/g,`${$.italic}$1${$.reset}`),W=W.replace(/(?<![a-zA-Z_])_([^_]+)_(?![a-zA-Z_])/g,`${$.italic}$1${$.reset}`),W=W.replace(/\*\*\*([^*]+)\*\*\*/g,`${$.bold}${$.italic}$1${$.reset}`),W=W.replace(/___([^_]+)___/g,`${$.bold}${$.italic}$1${$.reset}`),W=W.replace(/^(\s*)[-*]\s\[([ xX])\]/gm,(X,Q,z)=>{let J=z.toLowerCase()==="x"?"\u2713":" ",K=z.toLowerCase()==="x"?$.green:$.dim;return`${Q}${$.list}-${$.reset} ${K}[${J}]${$.reset}`}),W=W.replace(/^(\s*)([-*])\s(?!\[)/gm,`$1${$.list}$2${$.reset} `),W=W.replace(/^(\s*)(\d+\.)(?=\s)/gm,`$1${$.list}$2${$.reset}`),W=W.replace(/^([^:\n]+):\s{2,}(.+)$/gm,`${$.bold}$1${$.reset}:${$.dim} $2${$.reset}`),W=W.replace(/\[([^\]]+)\]\(([^)]+)\)/g,`${$.link}[$1]${$.reset}${$.dim}($2)${$.reset}`),W=W.replace(/\[([^\]]+)\]\[([^\]]*)\]/g,`${$.link}[$1]${$.reset}${$.dim}[$2]${$.reset}`),W=W.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,`${$.yellow}![${$.reset}${$.dim}$1${$.reset}${$.yellow}]${$.reset}${$.dim}($2)${$.reset}`),W=W.replace(/\[\^([^\]]+)\]/g,`${$.yellow}[^$1]${$.reset}`),W=W.replace(/^\[\^([^\]]+)\]:\s*(.+)$/gm,`${$.yellow}[^$1]${$.reset}:${$.dim} $2${$.reset}`),W=W.replace(/<\/?([a-zA-Z][a-zA-Z0-9]*)(\s[^>]*)?>/g,`${$.dim}<${$.purple}$1${$.reset}$2${$.dim}>${$.reset}`),W=W.replace(/==([^=]+)==/g,`${$.yellow}$1${$.reset}`),W=W.replace(/<kbd>([^<]+)<\/kbd>/gi,`${$.dim}[${$.orange}$1${$.dim}]${$.reset}`),W}function WZ(Z){let W=Z.split(/\s+/),X=W[0]||"",Q,z="";for(let J=1;J<W.length;J++){let K=W[J];if(K.includes("="))z+=(z?" ":"")+K;else if(K.includes(".")||K.includes("/"))Q=K}return{language:X,filePath:Q,attrs:z}}var ZZ={".ts":"typescript",".tsx":"typescript",".js":"javascript",".jsx":"javascript",".mjs":"javascript",".cjs":"javascript",".py":"python",".rb":"ruby",".rs":"rust",".go":"go",".java":"java",".kt":"kotlin",".swift":"swift",".c":"c",".cpp":"cpp",".cc":"cpp",".cxx":"cpp",".h":"c",".hpp":"cpp",".cs":"csharp",".php":"php",".sh":"bash",".bash":"bash",".zsh":"bash",".ps1":"powershell",".json":"json",".yaml":"yaml",".yml":"yaml",".toml":"toml",".md":"markdown",".html":"html",".htm":"html",".css":"css",".scss":"css",".less":"css",".sql":"sql",".xml":"xml",".svg":"xml",".vue":"vue",".svelte":"svelte",".dockerfile":"dockerfile",".makefile":"makefile",".cmake":"cmake",".lua":"lua",".r":"r",".ex":"elixir",".exs":"elixir",".erl":"erlang",".hs":"haskell",".ml":"ocaml",".clj":"clojure",".scala":"scala",".groovy":"groovy",".pl":"perl",".pm":"perl"};function i(Z){let W=Z.toLowerCase().slice(Z.lastIndexOf("."));return ZZ[W]}function C(Z){if(Z.includes("\x1B["))return Z;let W=Z;return W=tW(W),W=pW(W),W=eW(W),W=hW(W),W=OW(W),W}function r(){let Z="",W="text",X="",Q="",z="";function J(Y){Z+=Y;let U="";while(!0)if(W==="code"||W==="diff"){let E=Z.match(/\n```/);if(!E){if(Z.length>2000){let F=Z.slice(0,-200);if(Q+=F,W==="diff")U+=n(F);else U+=F;Z=Z.slice(-200)}break}let _=E.index;Q+=Z.slice(0,_);let G,N=X||(z?i(z):"");if(W==="diff"||(X==="diff"||XW(Q)))G=n(Q);else if(N)try{G=o(Q,N).html}catch{G=Q}else G=Q;let q=G.replace(/\x1b\[0m$/,"").trimEnd();U+=q,U+=`
|
|
9
|
+
${$.reset}\`\`\``,Z=Z.slice(_+4),W="text",X="",Q="",z=""}else{let E=Z.match(/```([^\n]*)\n/);if(!E){let y=Z.match(/```([^\n]*)$/);if(y){let j=Z.slice(0,Z.length-y[0].length);U+=C(j),Z=y[0];break}if(Z.length>4){let j=Z.lastIndexOf(`
|
|
10
|
+
`,Z.length-4),H;if(j>0&&Z.length-j<=10)H=Z.slice(0,j+1),Z=Z.slice(j+1);else if(Z.length>100)H=Z.slice(0,-4),Z=Z.slice(-4);else break;U+=C(H)}break}let _=E.index,G=E[1]||"",{language:N,filePath:q}=WZ(G),F=Z.slice(0,_);U+=C(F);let D=N||(q?i(q):"");if(q){let y=N||D||"";U+=`${$.dim}\`\`\`${$.cyan}${y}${$.reset} ${$.comment}${q}${$.reset}
|
|
11
|
+
`}else if(N)U+=`${$.dim}\`\`\`${$.cyan}${N}${$.reset}
|
|
12
|
+
`;else U+=`${$.dim}\`\`\`${$.reset}
|
|
13
|
+
`;if(Z=Z.slice(_+E[0].length),N==="diff"||N==="patch")W="diff";else W="code";X=N,Q="",z=q||""}return U}function K(){let Y="";if(W==="code"||W==="diff"){let U=X||(z?i(z):"");if(W==="diff"||XW(Q))Y+=n(Q);else if(U)try{Y+=o(Q,U).html}catch{Y+=Q}else Y+=Q;Y+=$.reset}if(Z)Y+=C(Z),Z="";return Y}return{process:J,flush:K}}async function p(Z,W){let X=Bun.spawn(["git",...Z],{cwd:W,stdout:"pipe",stderr:"pipe"}),Q=await new Response(X.stdout).text(),z=await new Response(X.stderr).text(),J=await X.exited;return{stdout:Q.trim(),stderr:z.trim(),exitCode:J}}async function $Z(Z){let{exitCode:W}=await p(["rev-parse","--git-dir"],Z);return W===0}async function QZ(Z){let{stdout:W,exitCode:X}=await p(["rev-parse","--abbrev-ref","HEAD"],Z);if(X!==0)return"HEAD";return W||"HEAD"}async function XZ(Z){let{stdout:W,exitCode:X}=await p(["rev-list","--left-right","--count","@{upstream}...HEAD"],Z);if(X!==0||!W)return{ahead:0,behind:0};let Q=W.split(/\s+/);if(Q.length>=2&&Q[0]!==void 0&&Q[1]!==void 0)return{ahead:parseInt(Q[0],10)||0,behind:parseInt(Q[1],10)||0};return{ahead:0,behind:0}}async function zZ(Z){let{stdout:W,exitCode:X}=await p(["status","--porcelain"],Z);if(X!==0||!W)return{staged:[],unstaged:[],untracked:[],conflicted:[]};let Q=[],z=[],J=[],K=[],Y=W.split(`
|
|
14
|
+
`);for(let U of Y){if(!U)continue;let E=U[0],_=U[1],G=U.substring(3);if(G.includes(" -> ")){let q=G.split(" -> ");G=q[1]??q[0]??G}if(E==="U"||_==="U"||E==="A"&&_==="A"||E==="D"&&_==="D"||E==="A"&&_==="U"||E==="U"&&_==="A"||E==="D"&&_==="U"||E==="U"&&_==="D"){K.push(G);continue}if(E==="?"&&_==="?"){J.push(G);continue}if(E!==" "&&E!=="?"&&E!=="!")Q.push(G);if(_!==" "&&_!=="?"&&_!=="!"){if(!Q.includes(G))z.push(G)}}return{staged:Q,unstaged:z,untracked:J,conflicted:K}}async function h(Z){try{if(!await $Z(Z))return null;let[X,Q,z]=await Promise.all([QZ(Z),XZ(Z),zZ(Z)]);return{branch:X,ahead:Q.ahead,behind:Q.behind,staged:z.staged,unstaged:z.unstaged,untracked:z.untracked,conflicted:z.conflicted}}catch(W){return console.error("Error getting git status:",W),null}}import{randomUUID as JZ}from"crypto";import{execSync as O}from"child_process";var g=process.env.CLAUDE_CHECKPOINTS_DIR||`${process.env.HOME}/.claude/checkpoints`;function VZ(Z){let W=0;for(let X=0;X<Z.length;X++){let Q=Z.charCodeAt(X);W=(W<<5)-W+Q,W=W&W}return Math.abs(W).toString(16)}function YZ(Z){try{O("git rev-parse --is-inside-work-tree",{cwd:Z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let W=O("git rev-parse --abbrev-ref HEAD",{cwd:Z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),X=0,Q=0;try{let U=O("git rev-list --left-right --count @{upstream}...HEAD 2>/dev/null || echo '0 0'",{cwd:Z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(/\s+/);Q=parseInt(U[0]||"0",10),X=parseInt(U[1]||"0",10)}catch{}let z=O("git status --porcelain",{cwd:Z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),J=[],K=[],Y=[];for(let U of z.split(`
|
|
15
|
+
`)){if(!U.trim())continue;let E=U[0],_=U[1],G=U.slice(3);if(E==="?"&&_==="?")Y.push(G);else if(E!==" "&&E!=="?")J.push(G);else if(_!==" ")K.push(G)}return{branch:W,ahead:X,behind:Q,staged:J,unstaged:K,untracked:Y}}catch(W){return}}async function KZ(Z,W){let X=[];for(let Q of W)try{let z=`${Z}/${Q}`,J=Bun.file(z);if(await J.exists()){let K=await J.text();X.push({path:Q,content:K,hash:VZ(K)})}}catch{}return X}async function UZ(Z,W){let X=0,Q=0;for(let z of W)try{let J=`${Z}/${z.path}`;await Bun.write(J,z.content),X++}catch{Q++}return{restored:X,failed:Q}}async function zW(){if(!await Bun.file(g).exists())await Bun.write(g+"/.gitkeep","")}function JW(Z){return`${g}/${Z}.json`}async function k(Z){let W=new Map;try{let X=JW(Z),Q=Bun.file(X);if(await Q.exists()){let z=await Q.text(),J=JSON.parse(z);for(let K of J)W.set(K.id,K)}}catch(X){}return W}async function BZ(Z,W){await zW();let X=JW(Z),Q=Array.from(W.values());await Bun.write(X,JSON.stringify(Q,null,2))}async function VW(Z,W,X={}){let Q=await k(Z),z=X.workingDirectory||process.cwd(),J=YZ(z),K=[];if(X.trackFiles!==!1&&J){let U=[...J.staged,...J.unstaged,...J.untracked];K=await KZ(z,U)}let Y={id:JZ().slice(0,8),sessionId:Z,timestamp:Date.now(),label:X.label||`Checkpoint ${Q.size+1}`,description:X.description,messages:JSON.parse(JSON.stringify(W)),files:K,gitState:J,metadata:{model:X.model,workingDirectory:z,totalCost:X.totalCost||0,messageCount:W.length,fileCount:K.length}};return Q.set(Y.id,Y),await BZ(Z,Q),Y}async function s(Z,W){return(await k(Z)).get(W)||null}async function m(Z,W={}){let X=W.workingDirectory||Z.metadata.workingDirectory||process.cwd(),Q=0,z=0;if(W.restoreFiles!==!1&&Z.files.length>0){let J=await UZ(X,Z.files);Q=J.restored,z=J.failed}return{messages:W.restoreMessages!==!1?Z.messages:[],filesRestored:Q,filesFailed:z}}async function YW(Z){let W=await k(Z);return Array.from(W.values()).sort((X,Q)=>Q.timestamp-X.timestamp)}function L(Z,W=!1){let X=new Date(Z.timestamp),Q=X.toLocaleTimeString(),z=X.toLocaleDateString(),J=`\x1B[33m${Z.id}\x1B[0m `;if(J+=`\x1B[1m${Z.label}\x1B[0m `,J+=`\x1B[90m(${z} ${Q})\x1B[0m`,Z.files.length>0)J+=` \x1B[32m[${Z.files.length} files]\x1B[0m`;if(Z.gitState)J+=` \x1B[34m(${Z.gitState.branch})\x1B[0m`;if(W){if(J+=`
|
|
16
|
+
Messages: ${Z.metadata.messageCount}`,J+=`
|
|
17
|
+
Files: ${Z.metadata.fileCount}`,J+=`
|
|
18
|
+
Cost: $${Z.metadata.totalCost.toFixed(4)}`,Z.gitState){let K=Z.gitState.staged.length+Z.gitState.unstaged.length+Z.gitState.untracked.length;J+=`
|
|
19
|
+
Git changes: ${K}`}if(Z.description)J+=`
|
|
20
|
+
${Z.description}`}return J}function KW(Z){if(Z.length===0){console.log("\x1B[90mNo checkpoints saved.\x1B[0m"),console.log("\x1B[90mUse /checkpoint <label> to create one.\x1B[0m");return}console.log(`
|
|
21
|
+
\x1B[1mCheckpoints (${Z.length}):\x1B[0m`),console.log("\x1B[90m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m");for(let W of Z)console.log(L(W));console.log("\x1B[90m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m"),console.log("\x1B[90m/restore <id> - Restore checkpoint (files + chat)\x1B[0m"),console.log("\x1B[90m/restore-chat <id> - Restore chat only (no files)\x1B[0m"),console.log("\x1B[90m/checkpoint <label> - Create new checkpoint\x1B[0m")}function UW(Z){let W=[];if(Z.files.length>0)W.push(`${Z.files.length} files`);if(W.push(`${Z.metadata.messageCount} msgs`),Z.gitState){let X=Z.gitState.staged.length+Z.gitState.unstaged.length+Z.gitState.untracked.length;if(X>0)W.push(`${X} changes`)}return W.join(" | ")}var BW=(Z)=>`${g}/${Z}-nav.json`;async function c(Z){try{let W=Bun.file(BW(Z));if(await W.exists())return JSON.parse(await W.text())}catch{}return{sessionId:Z,checkpointIds:[],currentIndex:-1,undoneIds:[]}}async function t(Z){await zW(),await Bun.write(BW(Z.sessionId),JSON.stringify(Z,null,2))}async function EW(Z,W){let X=await c(Z);if(X.currentIndex<X.checkpointIds.length-1)X.checkpointIds=X.checkpointIds.slice(0,X.currentIndex+1);X.checkpointIds.push(W),X.currentIndex=X.checkpointIds.length-1,X.undoneIds=[],await t(X)}async function GW(Z){let W=await c(Z),X=await k(Z);if(W.currentIndex<=0)return{checkpoint:null,canRedo:!1};let Q=W.checkpointIds[W.currentIndex];if(Q)W.undoneIds.push(Q);W.currentIndex--;let z=W.checkpointIds[W.currentIndex];return await t(W),{checkpoint:z?X.get(z)||null:null,canRedo:W.undoneIds.length>0}}async function HW(Z){let W=await c(Z),X=await k(Z);if(W.undoneIds.length===0)return{checkpoint:null,canRedo:!1};let Q=W.undoneIds.pop();return W.currentIndex++,await t(W),{checkpoint:X.get(Q)||null,canRedo:W.undoneIds.length>0}}async function _W(Z){let W=await c(Z);return{total:W.checkpointIds.length,current:W.currentIndex+1,canUndo:W.currentIndex>0,canRedo:W.undoneIds.length>0,currentId:W.checkpointIds[W.currentIndex]}}import{readFile as EZ,access as GZ}from"fs/promises";import{join as AW}from"path";var HZ={globalPath:`${process.env.HOME}/.claude/CLAUDE.md`,projectPath:".claude/CLAUDE.md",rootPath:"CLAUDE.md"};async function _Z(Z){try{return await GZ(Z),!0}catch{return!1}}async function e(Z){try{if(await _Z(Z))return(await EZ(Z,"utf-8")).trim()}catch(W){}return null}async function AZ(Z=process.cwd(),W={}){let X={...HZ,...W},Q=[],z=null,J=null,K=X.globalPath;if(z=await e(K),z)Q.push(K);let Y=AW(Z,X.projectPath),U=AW(Z,X.rootPath);if(J=await e(Y),J)Q.push(Y);else if(J=await e(U),J)Q.push(U);let E=[];if(z)E.push(`# Global Instructions
|
|
22
|
+
|
|
23
|
+
${z}`);if(J)E.push(`# Project Instructions
|
|
24
|
+
|
|
25
|
+
${J}`);return{global:z,project:J,merged:E.join(`
|
|
16
26
|
|
|
17
27
|
---
|
|
18
28
|
|
|
19
|
-
`),sources:
|
|
29
|
+
`),sources:Q}}async function NW(Z=process.cwd()){let{merged:W,sources:X}=await AZ(Z);if(!W)return"";return`
|
|
20
30
|
## Project Instructions
|
|
21
31
|
|
|
22
32
|
${X.length>0?`Loaded from: ${X.join(", ")}`:""}
|
|
23
33
|
|
|
24
34
|
${W}
|
|
25
|
-
`}import{readFile as
|
|
35
|
+
`}import{readFile as NZ,access as qZ}from"fs/promises";import{join as d}from"path";var TW=process.env.HOME||"",qW=d(TW,".claude"),x={main:d(TW,".claude.json"),settings:d(qW,"settings.json"),keybindings:d(qW,"keybindings.json"),projectSettings:(Z)=>d(Z,".claude","settings.json")};async function TZ(Z){try{return await qZ(Z),!0}catch{return!1}}async function u(Z,W){try{if(await TZ(Z)){let X=await NZ(Z,"utf-8");return{config:JSON.parse(X),loaded:!0}}}catch(X){}return{config:W,loaded:!1}}async function FZ(){return u(x.main,{})}async function jZ(){return u(x.settings,{})}async function MZ(){return u(x.keybindings,{bindings:[]})}async function wZ(Z){return u(x.projectSettings(Z),{})}function DZ(Z,W){return Z.projects?.[W]}async function FW(Z=process.cwd()){let W=[],{config:X,loaded:Q}=await FZ();if(Q)W.push(x.main);let{config:z,loaded:J}=await jZ();if(J)W.push(x.settings);let{config:K,loaded:Y}=await MZ();if(Y)W.push(x.keybindings);let{config:U,loaded:E}=await wZ(Z);if(E)W.push(x.projectSettings(Z));return{main:X,settings:z,keybindings:K,projectSettings:U,sources:W}}function jW(Z,W){return{hooks:{...Z.hooks,...W.hooks},permissions:{...Z.permissions,...W.permissions}}}function MW(Z,W){let X={};if(Z.mcpServers)Object.assign(X,Z.mcpServers);let Q=DZ(Z,W);if(Q?.mcpServers)Object.assign(X,Q.mcpServers);return X}function wW(Z){let W={};if(!Z.hooks)return W;for(let[X,Q]of Object.entries(Z.hooks)){let z=[],J=X;for(let K of Q)for(let Y of K.hooks)z.push({event:J,command:Y.type==="command"?Y.command||"":"",timeout:Y.timeout||60000,enabled:!0,_matcher:K.matcher,_prompt:Y.type==="prompt"?Y.prompt:void 0});if(z.length>0)W[J]=z}return W}function DW(Z){return Z.permissions?.defaultMode||"default"}function PW(Z){return new Set(Z.permissions?.allowedTools||[])}function bW(Z){return new Set(Z.permissions?.disallowedTools||[])}async function bZ(Z){try{let X=await Bun.file(Z).text(),Q=JSON.parse(X);if("servers"in Q&&typeof Q.servers==="object"&&Q.servers!==null)return Q.servers;if("type"in Q){let z={};return z.default=Q,z}return Q}catch(W){let X=W instanceof Error?W.message:String(W);throw Error(`Failed to load MCP config from ${Z}: ${X}`)}}function yZ(Z){let W=[];for(let[X,Q]of Z)for(let z of Q.tools)W.push({name:`mcp__${X}__${z.name}`,description:z.description,input_schema:z.inputSchema,handler:async(J,K)=>{if(!Q.connected)return{content:`Error: MCP server "${X}" is not connected`,is_error:!0};return Q.callTool(z.name,J)}});return W}function vZ(){let Z=process.argv.slice(2),W={model:"claude-sonnet-4-6",permissionMode:"default",maxTokens:4096};for(let X=0;X<Z.length;X++)switch(Z[X]){case"--model":case"-m":W.model=Z[++X]??"claude-sonnet-4-6";break;case"--permission-mode":case"-p":W.permissionMode=Z[++X]??"default";break;case"--max-tokens":W.maxTokens=parseInt(Z[++X]??"4096",10);break;case"--system-prompt":W.systemPrompt=Z[++X];break;case"--append-system-prompt":W.appendSystemPrompt=Z[++X];break;case"--config":W.configFile=Z[++X];break;case"--mcp-config":W.mcpConfig=Z[++X];break;case"--resume":W.resumeSession=Z[++X];break;case"--sessions":W.listSessions=!0;break;case"--teammate-mode":W.teammateMode=!0;break;case"--agent-id":W.agentId=Z[++X];break;case"--agent-name":W.agentName=Z[++X];break;case"--team-name":W.teamName=Z[++X];break;case"--agent-color":W.agentColor=Z[++X];break;case"--interleaved":W.interleaved=!0;break;case"--no-interleaved":W.interleaved=!1;break;case"--extended-thinking":case"-e":W.extendedThinking=!0;break;case"--effort":W.effort=Z[++X]??"medium";break;case"--query":case"-q":W.query=Z[++X];break;case"--help":case"-h":IZ(),process.exit(0)}return W}function IZ(){console.log(`
|
|
26
36
|
Coder v0.1.0
|
|
27
37
|
A reimplementation of Claude Code CLI
|
|
28
38
|
|
|
29
39
|
USAGE:
|
|
30
|
-
|
|
40
|
+
claude-remake [OPTIONS] [QUERY]
|
|
31
41
|
|
|
32
42
|
OPTIONS:
|
|
33
43
|
-m, --model <model> Model to use (default: claude-sonnet-4-6)
|
|
@@ -39,14 +49,6 @@ Extended Thinking:
|
|
|
39
49
|
--effort <level> Thinking effort: low, medium, high, max
|
|
40
50
|
--interleaved Enable interleaved thinking (default: true)
|
|
41
51
|
--no-interleaved Disable interleaved thinking
|
|
42
|
-
|
|
43
|
-
Autonomous Loop:
|
|
44
|
-
-l, --loop Enable autonomous loop mode (runs until TASKS_COMPLETE)
|
|
45
|
-
--max-iterations <n> Max iterations (default: 100, use 0 for unlimited)
|
|
46
|
-
--no-autonomous Disable autonomous discovery (just continue original task)
|
|
47
|
-
-s, --stop-sequences <seq> Comma-separated stop sequences (e.g., "DONE,COMPLETE")
|
|
48
|
-
|
|
49
|
-
Other:
|
|
50
52
|
--system-prompt <prompt> Override system prompt
|
|
51
53
|
--append-system-prompt <p> Append to system prompt
|
|
52
54
|
--config <file> Configuration file path
|
|
@@ -62,28 +64,24 @@ Other:
|
|
|
62
64
|
-h, --help Show this help message
|
|
63
65
|
|
|
64
66
|
EXAMPLES:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
${
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
`)
|
|
82
|
-
`)
|
|
83
|
-
\x1B[90mGoodbye!\x1B[0m`),x.close(),process.exit(0)});let b=(U)=>{return new Promise((G,H)=>{if(x.closed){H(Error("Readline closed"));return}x.question(U,(j)=>{G(j)})})},N=async(U)=>{if(console.log(`
|
|
84
|
-
\x1B[36m\u2501\u2501\u2501 Permission Required \u2501\u2501\u2501\x1B[0m`),console.log(`Tool: \x1B[1m${U.toolName}\x1B[0m`),console.log(`Risk: \x1B[32m${U.riskLevel.toUpperCase()}\x1B[0m`),console.log(`Action: ${U.description}`),U.file)console.log(`File: ${U.file}`);else if(U.command)console.log(`Command: ${U.command}`);else if(U.toolInput.file_path)console.log(`File: ${U.toolInput.file_path}`);else if(U.toolInput.command)console.log(`Command: ${U.toolInput.command}`);while(!0)try{switch((await b(`
|
|
85
|
-
Allow? [y]es / [n]o / [a]lways / [d]eny always: `)).trim().toLowerCase()){case"y":case"yes":case"":return{decision:"allow"};case"n":case"no":return{decision:"deny",reason:"User denied"};case"a":case"always":return{decision:"allowAlways"};case"d":case"deny":return{decision:"denyAlways",reason:"User denied always"};default:console.log("Please enter y, n, a, or d")}}catch{return{decision:"deny",reason:"Input error"}}};while(T)try{let U=await b(`
|
|
86
|
-
\x1B[1;36mYou:\x1B[0m `);if(!U.trim())continue;if(U.startsWith("/")){let F=U.slice(1).split(" ")[0]??"",A=U.slice(F.length+2);switch(F){case"exit":case"quit":case"q":T=!1,console.log("\x1B[90mGoodbye!\x1B[0m");continue;case"help":case"?":console.log(`
|
|
67
|
+
claude-remake "What files are in this directory?"
|
|
68
|
+
claude-remake -m claude-opus-4-6 "Explain this codebase"
|
|
69
|
+
claude-remake --permission-mode acceptEdits "Add a test"
|
|
70
|
+
claude-remake --sessions
|
|
71
|
+
claude-remake --resume abc123-def456
|
|
72
|
+
`)}async function xZ(){let Z=vZ(),W=new yW;if(await W.init(),Z.listSessions){let A=await W.listSessions(20);vW(A),process.exit(0)}let X=process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_API_KEY||process.env.ANTHROPIC_AUTH_TOKEN||process.env.Z_AI_API_KEY;if(!X)console.error("Error: ANTHROPIC_API_KEY, CLAUDE_API_KEY, ANTHROPIC_AUTH_TOKEN, or Z_AI_API_KEY environment variable required"),process.exit(1);console.log("\x1B[90mLoading configuration...\x1B[0m");let Q;try{Q=await FW(process.cwd())}catch(A){let P=A instanceof Error?A.message:String(A);console.error(`\x1B[33mWarning: Failed to load config: ${P}\x1B[0m`),Q={main:{},settings:{},keybindings:{bindings:[]},projectSettings:{},sources:[]}}let z=jW(Q.settings,Q.projectSettings);if(Q.sources.length>0)console.log(`\x1B[90m Config sources: ${Q.sources.length} files\x1B[0m`);if(Z.permissionMode==="default"){let A=DW(z);if(A!=="default")Z.permissionMode=A,console.log(`\x1B[90m Permission mode: ${A} (from config)\x1B[0m`)}let J=PW(z),K=bW(z),Y=new fW,U=new RW,E=new kW,_=wW(z);for(let[A,P]of Object.entries(_))for(let T of P)Y.register(A,T);if(Object.keys(_).length>0)console.log(`\x1B[90m Hooks registered: ${Object.keys(_).length} events\x1B[0m`);let G=process.cwd()+"/.claude/skills";U.loadFromDirectory(G,"project");let N=new Map,F=MW(Q.main,process.cwd());if(Z.mcpConfig)try{console.log(`\x1B[90mLoading MCP config from ${Z.mcpConfig}...\x1B[0m`),F=await bZ(Z.mcpConfig)}catch(A){let P=A instanceof Error?A.message:String(A);console.error(`\x1B[33mWarning: Failed to load MCP config file: ${P}\x1B[0m`)}if(Object.keys(F).length>0){let P=Object.entries(F).filter(([T,M])=>!M.disabled).length;if(P>0){console.log(`\x1B[90m Connecting to ${P} MCP server(s)...\x1B[0m`);let T=await xW(F,(M)=>{console.log(`\x1B[90m ${M}\x1B[0m`)});for(let[M,b]of T)N.set(M,b);if(N.size>0)console.log(`\x1B[32m Connected to ${N.size} MCP server(s)\x1B[0m`);else console.log("\x1B[33m Warning: No MCP servers connected successfully\x1B[0m")}else if(Object.keys(F).length>0)console.log(`\x1B[90m MCP config loaded but all ${Object.keys(F).length} server(s) are disabled\x1B[0m`)}let D=[...IW,...yZ(N)],y=await h(process.cwd()),j=Z.systemPrompt||await LZ(y);if(Z.appendSystemPrompt)j+=`
|
|
73
|
+
|
|
74
|
+
${Z.appendSystemPrompt}`;if(Z.teammateMode&&Z.teamName)j+=`
|
|
75
|
+
|
|
76
|
+
You are running as a teammate agent in the "${Z.teamName}" team.`,j+=`
|
|
77
|
+
Agent ID: ${Z.agentId}`,j+=`
|
|
78
|
+
Agent Name: ${Z.agentName}`;let H=[],w;if(Z.resumeSession){let A=await W.resumeSession(Z.resumeSession);if(!A)console.error(`Error: Session not found: ${Z.resumeSession}`),process.exit(1);H=A.messages,w=Z.resumeSession,Z.model=A.metadata.model,Z.agentName=A.metadata.agentName,Z.agentColor=A.metadata.agentColor,Z.teamName=A.metadata.teamName,console.log(`\x1B[90mResumed session: ${Z.resumeSession}\x1B[0m`),console.log(`\x1B[90mModel: ${Z.model} | Messages: ${H.length}\x1B[0m
|
|
79
|
+
`)}else w=await W.createSession({model:Z.model,workingDirectory:process.cwd(),agentName:Z.agentName,agentColor:Z.agentColor,teamName:Z.teamName});let v=Z.query,I=process.argv[2];if(!v&&process.argv.length>2&&I&&!I.startsWith("-"))v=process.argv.slice(2).join(" ");if(!v)console.log("Claude Code Remake v0.1.0"),console.log(`Session: ${w}`),console.log(`Type your message or /help for commands.
|
|
80
|
+
`),await fZ(X,Z,j,D,Y,U,W,H,w,N);else await RZ(X,Z,j,D,v,W,w)}async function fZ(Z,W,X,Q,z,J,K,Y,U,E){let _=process.stdin.isTTY,G=process.env.CLAUDE_FORCE_INTERACTIVE==="true";if(!_&&!G){console.error("Error: Interactive mode requires a TTY. Use -q for single query mode."),console.error(" Or set CLAUDE_FORCE_INTERACTIVE=true for testing.");return}let N=!0,q=0,F=await h(process.cwd()),D=PZ("readline").createInterface({input:process.stdin,output:process.stdout,terminal:!0,historySize:1000,removeHistoryDuplicates:!0});process.on("SIGINT",()=>{console.log(`
|
|
81
|
+
\x1B[90mGoodbye!\x1B[0m`),D.close(),process.exit(0)});let y=(H)=>{return new Promise((w,v)=>{if(D.closed){v(Error("Readline closed"));return}D.question(H,(I)=>{w(I)})})},j=async(H)=>{if(console.log(`
|
|
82
|
+
\x1B[36m\u2501\u2501\u2501 Permission Required \u2501\u2501\u2501\x1B[0m`),console.log(`Tool: \x1B[1m${H.toolName}\x1B[0m`),console.log(`Risk: \x1B[32m${H.riskLevel.toUpperCase()}\x1B[0m`),console.log(`Action: ${H.description}`),H.file)console.log(`File: ${H.file}`);else if(H.command)console.log(`Command: ${H.command}`);else if(H.toolInput.file_path)console.log(`File: ${H.toolInput.file_path}`);else if(H.toolInput.command)console.log(`Command: ${H.toolInput.command}`);while(!0)try{switch((await y(`
|
|
83
|
+
Allow? [y]es / [n]o / [a]lways / [d]eny always: `)).trim().toLowerCase()){case"y":case"yes":case"":return{decision:"allow"};case"n":case"no":return{decision:"deny",reason:"User denied"};case"a":case"always":return{decision:"allowAlways"};case"d":case"deny":return{decision:"denyAlways",reason:"User denied always"};default:console.log("Please enter y, n, a, or d")}}catch{return{decision:"deny",reason:"Input error"}}};while(N)try{let H=await y(`
|
|
84
|
+
\x1B[1;36mYou:\x1B[0m `);if(!H.trim())continue;if(H.startsWith("/")){let M=H.slice(1).split(" ")[0]??"",b=H.slice(M.length+2);switch(M){case"exit":case"quit":case"q":N=!1,console.log("\x1B[90mGoodbye!\x1B[0m");continue;case"help":case"?":console.log(`
|
|
87
85
|
\x1B[1mCommands:\x1B[0m
|
|
88
86
|
/help, /? Show this help
|
|
89
87
|
/exit, /quit, /q Exit the session
|
|
@@ -107,37 +105,18 @@ Allow? [y]es / [n]o / [a]lways / [d]eny always: `)).trim().toLowerCase()){case"y
|
|
|
107
105
|
|
|
108
106
|
\x1B[1mExport:\x1B[0m
|
|
109
107
|
/export [format] Export session (jsonl/json/md)
|
|
110
|
-
`);continue;case"clear":
|
|
111
|
-
\x1B[1mRestoring checkpoint:\x1B[0m ${
|
|
112
|
-
\x1B[36mRestore files too? [Y/n]: \x1B[0m`)).trim().toLowerCase()!=="n"}let
|
|
113
|
-
\x1B[32m\u2713 Checkpoint restored:\x1B[0m`),console.log(` Messages: ${
|
|
114
|
-
|
|
115
|
-
`+
|
|
116
|
-
\x1B[1;35mClaude:\x1B[0m `);let
|
|
117
|
-
\x1B[90m[Trying: ${
|
|
118
|
-
\x1B[90m${
|
|
119
|
-
\x1B[31mError: ${
|
|
120
|
-
\x1B[
|
|
121
|
-
\x1B[
|
|
122
|
-
\x1B[90m${i(U)}\x1B[0m`),await Q.saveMetrics(U)}}),N=b.messages[b.messages.length-1];if(N&&N.role==="assistant")await Q.saveMessage(N);if(q+=b.totalCost,J.length=0,J.push(...b.messages),E&&!x){let U=[...J].reverse().find((H)=>H.role==="assistant");if(U){let H=U.content;if((Array.isArray(H)?H.filter((B)=>B.type==="text").map((B)=>B.text).join(" "):String(H)).includes("TASKS_COMPLETE")){console.log(`
|
|
123
|
-
\x1B[32m\u2713 Model signaled TASKS_COMPLETE - all work done\x1B[0m`),x=!0;break}}let G=T?"Continue working on the original task. If fully complete, respond with 'TASKS_COMPLETE'.":`Autonomous check #${_}: Scan for additional productive work in this codebase.
|
|
124
|
-
|
|
125
|
-
Look for:
|
|
126
|
-
- TODOs, FIXMEs, or incomplete code
|
|
127
|
-
- Failing or missing tests
|
|
128
|
-
- Outdated documentation
|
|
129
|
-
- Dependencies that could be updated
|
|
130
|
-
- Code quality improvements (typos, dead code, etc.)
|
|
131
|
-
- Security issues or vulnerabilities
|
|
132
|
-
- Performance optimizations
|
|
133
|
-
- Missing error handling
|
|
134
|
-
|
|
135
|
-
Use your tools (Glob, Grep, Read, Bash) to actively search. Do not guess or hallucinate - investigate.
|
|
136
|
-
|
|
137
|
-
If you find productive work, do it. If nothing productive remains, respond with exactly: TASKS_COMPLETE`;J.push({role:"user",content:[{type:"text",text:G}]})}else break}if(E)if(x)console.log(`
|
|
138
|
-
\x1B[32m\u2713 Autonomous loop completed after ${_} iteration(s)\x1B[0m`);else console.log(`
|
|
139
|
-
\x1B[33m\u2713 Loop ended after ${_} iteration(s)\x1B[0m`);console.log(`
|
|
140
|
-
\x1B[90mSession: ${L}\x1B[0m`),console.log(`\x1B[90mTotal cost: ${p(q)}\x1B[0m`)}catch(b){let N=b instanceof Error?b.message:String(b);console.error(`Error: ${N}`),process.exit(1)}}async function YW(z){let W=`You are Claude Code, an AI coding assistant created by Anthropic.
|
|
108
|
+
`);continue;case"clear":Y.length=0,console.log("\x1B[90mConversation cleared.\x1B[0m");continue;case"compact":console.log("\x1B[90mForcing context compaction...\x1B[0m");continue;case"model":if(b)W.model=b,console.log(`\x1B[90mSwitched to model: ${b}\x1B[0m`);else console.log(`Current model: \x1B[1m${W.model}\x1B[0m`);continue;case"tools":console.log("\x1B[1mAvailable tools:\x1B[0m");for(let V of Q){let B=V.description.split(".")[0]??V.description;console.log(` \x1B[33m${V.name}\x1B[0m: ${B}`)}continue;case"mcp":if(E.size===0)console.log("\x1B[90mNo MCP servers connected.\x1B[0m"),console.log("\x1B[90mUse --mcp-config to specify a config file.\x1B[0m");else{console.log("\x1B[1mConnected MCP Servers:\x1B[0m");for(let[V,B]of E){let f=B.connected?"\x1B[32m\u25CF\x1B[0m":"\x1B[31m\u25CB\x1B[0m";console.log(` ${f} \x1B[1m${V}\x1B[0m (${B.tools.length} tools)`);for(let R of B.tools)console.log(` \x1B[33m${R.name}\x1B[0m: ${R.description.slice(0,50)}...`)}}continue;case"skills":let $W=J.getAll();if($W.length===0)console.log("\x1B[90mNo skills loaded.\x1B[0m");else{console.log("\x1B[1mAvailable skills:\x1B[0m");for(let V of $W){let B=V.description??V.prompt.slice(0,50);console.log(` \x1B[33m/${V.name}\x1B[0m: ${B}...`)}}continue;case"cost":console.log(`Total cost: \x1B[1m${l(q)}\x1B[0m`);continue;case"status":case"session":console.log("\x1B[1mSession Status:\x1B[0m"),console.log(` ID: ${U}`),console.log(` Model: ${W.model}`),console.log(` Messages: ${Y.length}`),console.log(` Total cost: ${l(q)}`),console.log(` Permission mode: ${W.permissionMode}`);continue;case"export":try{let V=b||"markdown",B=await K.exportSession(U,V);console.log(`\x1B[90mSession exported to: ${B}\x1B[0m`)}catch(V){let B=V instanceof Error?V.message:String(V);console.error(`\x1B[31mExport failed: ${B}\x1B[0m`)}continue;case"checkpoint":case"cp":if(!b){console.log("\x1B[31mUsage: /checkpoint <label>\x1B[0m"),console.log("\x1B[90mExample: /checkpoint before-refactor\x1B[0m"),console.log("\x1B[90mCreates checkpoint with chat history + file snapshots\x1B[0m");continue}try{let V=await VW(U,Y,{label:b,model:W.model,workingDirectory:process.cwd(),totalCost:q,trackFiles:!0});await EW(U,V.id);let B=UW(V);if(console.log(`\x1B[32m\u2713 Checkpoint saved:\x1B[0m ${L(V)}`),B)console.log(`\x1B[90m ${B}\x1B[0m`)}catch(V){let B=V instanceof Error?V.message:String(V);console.error(`\x1B[31mFailed to create checkpoint: ${B}\x1B[0m`)}continue;case"checkpoints":case"cps":try{let V=await YW(U);KW(V)}catch(V){let B=V instanceof Error?V.message:String(V);console.error(`\x1B[31mFailed to list checkpoints: ${B}\x1B[0m`)}continue;case"restore":case"rollback":case"rewind":if(!b){console.log("\x1B[31mUsage: /${command} <checkpoint-id>\x1B[0m"),console.log("\x1B[90mUse /checkpoints to see available checkpoints\x1B[0m");continue}try{let V=b.trim(),B=await s(U,V);if(!B){console.log(`\x1B[31mCheckpoint not found: ${V}\x1B[0m`),console.log("\x1B[90mUse /checkpoints to see available checkpoints\x1B[0m");continue}console.log(`
|
|
109
|
+
\x1B[1mRestoring checkpoint:\x1B[0m ${L(B)}`);let f=B.files.length>0,R=!1;if(f){console.log(`\x1B[33m${B.files.length} file(s) saved in checkpoint:\x1B[0m`);for(let mW of B.files.slice(0,5))console.log(` - ${mW.path}`);if(B.files.length>5)console.log(` ... and ${B.files.length-5} more`);R=(await y(`
|
|
110
|
+
\x1B[36mRestore files too? [Y/n]: \x1B[0m`)).trim().toLowerCase()!=="n"}let S=await m(B,{restoreFiles:R,restoreMessages:!0,workingDirectory:process.cwd()});if(Y.length=0,Y.push(...S.messages),q=B.metadata.totalCost,console.log(`
|
|
111
|
+
\x1B[32m\u2713 Checkpoint restored:\x1B[0m`),console.log(` Messages: ${Y.length}`),R&&f){if(console.log(` Files restored: ${S.filesRestored}`),S.filesFailed>0)console.log(` \x1B[33mFiles failed: ${S.filesFailed}\x1B[0m`)}console.log(` Cost reset to: $${q.toFixed(4)}`)}catch(V){let B=V instanceof Error?V.message:String(V);console.error(`\x1B[31mFailed to restore checkpoint: ${B}\x1B[0m`)}continue;case"restore-chat":if(!b){console.log("\x1B[31mUsage: /restore-chat <checkpoint-id>\x1B[0m"),console.log("\x1B[90mRestores chat only, no files\x1B[0m");continue}try{let V=b.trim(),B=await s(U,V);if(!B){console.log(`\x1B[31mCheckpoint not found: ${V}\x1B[0m`);continue}let f=await m(B,{restoreFiles:!1,restoreMessages:!0});Y.length=0,Y.push(...f.messages),q=B.metadata.totalCost,console.log(`\x1B[32m\u2713 Chat restored:\x1B[0m ${Y.length} messages (no files changed)`)}catch(V){let B=V instanceof Error?V.message:String(V);console.error(`\x1B[31mFailed to restore chat: ${B}\x1B[0m`)}continue;case"undo":try{let V=await GW(U);if(!V.checkpoint){console.log("\x1B[33mNothing to undo\x1B[0m");continue}let B=await m(V.checkpoint,{restoreFiles:!0,restoreMessages:!0,workingDirectory:process.cwd()});if(Y.length=0,Y.push(...B.messages),q=V.checkpoint.metadata.totalCost,console.log(`\x1B[32m\u2713 Undone to:\x1B[0m ${L(V.checkpoint)}`),console.log(`\x1B[90mMessages: ${Y.length} | Files: ${B.filesRestored}\x1B[0m`),V.canRedo)console.log("\x1B[90mUse /redo to go forward\x1B[0m")}catch(V){let B=V instanceof Error?V.message:String(V);console.error(`\x1B[31mUndo failed: ${B}\x1B[0m`)}continue;case"redo":try{let V=await HW(U);if(!V.checkpoint){console.log("\x1B[33mNothing to redo\x1B[0m");continue}let B=await m(V.checkpoint,{restoreFiles:!0,restoreMessages:!0,workingDirectory:process.cwd()});if(Y.length=0,Y.push(...B.messages),q=V.checkpoint.metadata.totalCost,console.log(`\x1B[32m\u2713 Redone to:\x1B[0m ${L(V.checkpoint)}`),console.log(`\x1B[90mMessages: ${Y.length} | Files: ${B.filesRestored}\x1B[0m`),V.canRedo)console.log("\x1B[90mUse /redo to go forward again\x1B[0m")}catch(V){let B=V instanceof Error?V.message:String(V);console.error(`\x1B[31mRedo failed: ${B}\x1B[0m`)}continue;case"checkpoint-status":case"cps-status":try{let V=await _W(U);if(console.log("\x1B[1mCheckpoint Navigation:\x1B[0m"),console.log(` Position: ${V.current}/${V.total}`),console.log(` Can undo: ${V.canUndo?"\x1B[32myes\x1B[0m":"\x1B[31mno\x1B[0m"}`),console.log(` Can redo: ${V.canRedo?"\x1B[32myes\x1B[0m":"\x1B[31mno\x1B[0m"}`),V.currentId)console.log(` Current: ${V.currentId}`)}catch(V){let B=V instanceof Error?V.message:String(V);console.error(`\x1B[31mFailed to get status: ${B}\x1B[0m`)}continue;default:let a=J.get(M);if(a){console.log(`\x1B[90mLoading skill: ${a.name}\x1B[0m`),X+=`
|
|
112
|
+
|
|
113
|
+
`+LW(a);continue}console.log(`\x1B[31mUnknown command: /${M}\x1B[0m`),console.log("\x1B[90mType /help for available commands.\x1B[0m");continue}}Y.push({role:"user",content:[{type:"text",text:H}]}),await K.saveMessage(Y[Y.length-1]),process.stdout.write(`
|
|
114
|
+
\x1B[1;35mClaude:\x1B[0m `);let w=r(),v=W.extendedThinking?{enabled:!0,effort:W.effort??"medium",interleaved:W.interleaved??!0}:void 0,I=await WW(Y,{apiKey:Z,model:W.model,maxTokens:W.maxTokens,systemPrompt:X,tools:Q,permissionMode:W.permissionMode,workingDirectory:process.cwd(),gitStatus:F,extendedThinking:v,onText:(T)=>{let M=w.process(T);if(M)process.stdout.write(M)},onThinking:(T)=>{process.stdout.write(`\x1B[90m${T}\x1B[0m`)},onToolUse:(T)=>{process.stdout.write(`
|
|
115
|
+
\x1B[90m[Trying: ${T.name}]\x1B[0m `)},onToolResult:(T)=>{if(T.result.is_error)process.stdout.write("\x1B[31m[Error]\x1B[0m ")},onMetrics:async(T)=>{console.log(`
|
|
116
|
+
\x1B[90m${ZW(T)}\x1B[0m`),await K.saveMetrics(T)},onPermissionRequest:async(T)=>{return await j({toolName:T.toolName,toolInput:T.toolInput,riskLevel:T.riskLevel,description:T.description,file:T.file,command:T.command})}}),A=w.flush();if(A)process.stdout.write(A);let P=I.messages[I.messages.length-1];if(P&&P.role==="assistant")await K.saveMessage(P);Y.length=0,Y.push(...I.messages),q+=I.totalCost}catch(H){if(H instanceof Error&&H.message==="Readline closed")break;let w=H instanceof Error?H.message:String(H);console.error(`
|
|
117
|
+
\x1B[31mError: ${w}\x1B[0m`)}D.close()}async function RZ(Z,W,X,Q,z,J,K){let Y=[{role:"user",content:[{type:"text",text:z}]}];await J.saveMessage(Y[0]);let U=await h(process.cwd()),E=r(),_=W.extendedThinking?{enabled:!0,effort:W.effort??"medium",interleaved:W.interleaved??!0}:void 0;try{let G=await WW(Y,{apiKey:Z,model:W.model,maxTokens:W.maxTokens,systemPrompt:X,tools:Q,permissionMode:W.permissionMode,workingDirectory:process.cwd(),gitStatus:U,extendedThinking:_,onText:(F)=>{let D=E.process(F);if(D)process.stdout.write(D)},onThinking:(F)=>{process.stdout.write(`\x1B[90m${F}\x1B[0m`)},onMetrics:async(F)=>{console.log(`
|
|
118
|
+
\x1B[90m${ZW(F)}\x1B[0m`),await J.saveMetrics(F)}}),N=E.flush();if(N)process.stdout.write(N);let q=G.messages[G.messages.length-1];if(q&&q.role==="assistant")await J.saveMessage(q);console.log(`
|
|
119
|
+
\x1B[90mSession: ${K}\x1B[0m`),console.log(`\x1B[90mTotal cost: ${l(G.totalCost)}\x1B[0m`)}catch(G){let N=G instanceof Error?G.message:String(G);console.error(`Error: ${N}`),process.exit(1)}}async function LZ(Z){let W=`You are Claude Code, an AI coding assistant created by Anthropic.
|
|
141
120
|
|
|
142
121
|
You help users with software engineering tasks:
|
|
143
122
|
- Reading, writing, and editing code
|
|
@@ -160,10 +139,10 @@ Available tools:
|
|
|
160
139
|
- Glob: Find files by pattern
|
|
161
140
|
- Grep: Search file contents
|
|
162
141
|
|
|
163
|
-
Working directory: ${process.cwd()}`;if(
|
|
142
|
+
Working directory: ${process.cwd()}`;if(Z){if(W+=`
|
|
164
143
|
|
|
165
144
|
Git Status:`,W+=`
|
|
166
|
-
Branch: ${
|
|
167
|
-
Changes: ${
|
|
145
|
+
Branch: ${Z.branch}`,Z.ahead>0||Z.behind>0)W+=` (${Z.ahead} ahead, ${Z.behind} behind)`;if(Z.staged.length>0||Z.unstaged.length>0||Z.untracked.length>0)W+=`
|
|
146
|
+
Changes: ${Z.staged.length} staged, ${Z.unstaged.length} unstaged, ${Z.untracked.length} untracked`}let X=await NW();if(X)W+=`
|
|
168
147
|
|
|
169
|
-
${X}`;return W}
|
|
148
|
+
${X}`;return W}xZ().catch((Z)=>{console.error("Fatal error:",Z),process.exit(1)});
|