thatgfsj-code 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/.patches/0001-fix-repl-replace-readline-with-inquirer-input-for-ke.patch +279 -0
- package/.patches/0002-fix-repl-stream-AI-output-directly-to-stdout-so-term.patch +564 -0
- package/.patches/0003-fix-session-break-the-hallucination-loop-in-assistan.patch +194 -0
- package/.patches/0004-chore-release-bump-version-to-0.2.1.patch +24 -0
- package/LICENSE +21 -0
- package/README.md +100 -0
- package/ROADMAP.md +107 -0
- package/dist/agent/core.d.ts +56 -0
- package/dist/agent/core.d.ts.map +1 -0
- package/dist/agent/core.js +142 -0
- package/dist/agent/core.js.map +1 -0
- package/dist/agent/index.d.ts +8 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +8 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/intent.d.ts +36 -0
- package/dist/agent/intent.d.ts.map +1 -0
- package/dist/agent/intent.js +146 -0
- package/dist/agent/intent.js.map +1 -0
- package/dist/agent/streaming.d.ts +50 -0
- package/dist/agent/streaming.d.ts.map +1 -0
- package/dist/agent/streaming.js +110 -0
- package/dist/agent/streaming.js.map +1 -0
- package/dist/core/ai-engine.d.ts +59 -0
- package/dist/core/ai-engine.d.ts.map +1 -0
- package/dist/core/ai-engine.js +378 -0
- package/dist/core/ai-engine.js.map +1 -0
- package/dist/core/cli.d.ts +21 -0
- package/dist/core/cli.d.ts.map +1 -0
- package/dist/core/cli.js +143 -0
- package/dist/core/cli.js.map +1 -0
- package/dist/core/config.d.ts +38 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +129 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context-compactor.d.ts +54 -0
- package/dist/core/context-compactor.d.ts.map +1 -0
- package/dist/core/context-compactor.js +197 -0
- package/dist/core/context-compactor.js.map +1 -0
- package/dist/core/hooks.d.ts +75 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +146 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/permissions.d.ts +52 -0
- package/dist/core/permissions.d.ts.map +1 -0
- package/dist/core/permissions.js +237 -0
- package/dist/core/permissions.js.map +1 -0
- package/dist/core/session.d.ts +54 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +147 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/skills.d.ts +60 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +175 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/state.d.ts +60 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +106 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/subagent.d.ts +68 -0
- package/dist/core/subagent.d.ts.map +1 -0
- package/dist/core/subagent.js +142 -0
- package/dist/core/subagent.js.map +1 -0
- package/dist/core/system-prompt.d.ts +40 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +138 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/tool-registry.d.ts +53 -0
- package/dist/core/tool-registry.d.ts.map +1 -0
- package/dist/core/tool-registry.js +138 -0
- package/dist/core/tool-registry.js.map +1 -0
- package/dist/core/types.d.ts +206 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +127 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +481 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +83 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +267 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/repl/index.d.ts +8 -0
- package/dist/repl/index.d.ts.map +1 -0
- package/dist/repl/index.js +8 -0
- package/dist/repl/index.js.map +1 -0
- package/dist/repl/input.d.ts +61 -0
- package/dist/repl/input.d.ts.map +1 -0
- package/dist/repl/input.js +127 -0
- package/dist/repl/input.js.map +1 -0
- package/dist/repl/loop.d.ts +53 -0
- package/dist/repl/loop.d.ts.map +1 -0
- package/dist/repl/loop.js +241 -0
- package/dist/repl/loop.js.map +1 -0
- package/dist/repl/output.d.ts +105 -0
- package/dist/repl/output.d.ts.map +1 -0
- package/dist/repl/output.js +197 -0
- package/dist/repl/output.js.map +1 -0
- package/dist/repl/welcome.d.ts +68 -0
- package/dist/repl/welcome.d.ts.map +1 -0
- package/dist/repl/welcome.js +249 -0
- package/dist/repl/welcome.js.map +1 -0
- package/dist/tools/file.d.ts +46 -0
- package/dist/tools/file.d.ts.map +1 -0
- package/dist/tools/file.js +100 -0
- package/dist/tools/file.js.map +1 -0
- package/dist/tools/git.d.ts +52 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +112 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/index.d.ts +22 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +43 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/search.d.ts +36 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +223 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/shell.d.ts +57 -0
- package/dist/tools/shell.d.ts.map +1 -0
- package/dist/tools/shell.js +153 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/utils/diff-preview.d.ts +42 -0
- package/dist/utils/diff-preview.d.ts.map +1 -0
- package/dist/utils/diff-preview.js +174 -0
- package/dist/utils/diff-preview.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/memory.d.ts +81 -0
- package/dist/utils/memory.d.ts.map +1 -0
- package/dist/utils/memory.js +186 -0
- package/dist/utils/memory.js.map +1 -0
- package/dist/utils/project-context.d.ts +62 -0
- package/dist/utils/project-context.d.ts.map +1 -0
- package/dist/utils/project-context.js +197 -0
- package/dist/utils/project-context.js.map +1 -0
- package/docs/API_KEY_GUIDE.md +236 -0
- package/docs/FAQ.md +182 -0
- package/install.bat +63 -0
- package/install.ps1 +238 -0
- package/install.sh +113 -0
- package/package.json +36 -0
- package/src/agent/core.ts +179 -0
- package/src/agent/index.ts +8 -0
- package/src/agent/intent.ts +181 -0
- package/src/agent/streaming.ts +132 -0
- package/src/core/ai-engine.ts +437 -0
- package/src/core/cli.ts +171 -0
- package/src/core/config.ts +147 -0
- package/src/core/context-compactor.ts +245 -0
- package/src/core/hooks.ts +196 -0
- package/src/core/permissions.ts +308 -0
- package/src/core/session.ts +165 -0
- package/src/core/skills.ts +208 -0
- package/src/core/state.ts +120 -0
- package/src/core/subagent.ts +195 -0
- package/src/core/system-prompt.ts +163 -0
- package/src/core/tool-registry.ts +157 -0
- package/src/core/types.ts +280 -0
- package/src/index.ts +544 -0
- package/src/mcp/client.ts +330 -0
- package/src/repl/index.ts +8 -0
- package/src/repl/input.ts +139 -0
- package/src/repl/loop.ts +280 -0
- package/src/repl/output.ts +222 -0
- package/src/repl/welcome.ts +296 -0
- package/src/tools/file.ts +117 -0
- package/src/tools/git.ts +132 -0
- package/src/tools/index.ts +48 -0
- package/src/tools/search.ts +263 -0
- package/src/tools/shell.ts +181 -0
- package/src/utils/diff-preview.ts +202 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/memory.ts +223 -0
- package/src/utils/project-context.ts +207 -0
- package/tsconfig.json +19 -0
package/install.ps1
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Thatgfsj Code Installer for Windows
|
|
2
|
+
# Usage:
|
|
3
|
+
# powershell -c "irm https://raw.githubusercontent.com/Thatgfsj/thatgfsj-code/main/install.ps1 | iex"
|
|
4
|
+
# powershell -c "& ([scriptblock]::Create((irm https://raw.githubusercontent.com/Thatgfsj/thatgfsj-code/main/install.ps1)))"
|
|
5
|
+
|
|
6
|
+
param(
|
|
7
|
+
[switch]$NoOpen,
|
|
8
|
+
[switch]$DryRun
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
$ErrorActionPreference = "Stop"
|
|
12
|
+
|
|
13
|
+
# Colors
|
|
14
|
+
function Write-Step { param($msg) Write-Host "[*] $msg" -ForegroundColor Yellow }
|
|
15
|
+
function Write-Success { param($msg) Write-Host "[ā] $msg" -ForegroundColor Green }
|
|
16
|
+
function Write-Error { param($msg) Write-Host "[ā] $msg" -ForegroundColor Red }
|
|
17
|
+
function Write-Info { param($msg) Write-Host " $msg" -ForegroundColor Gray }
|
|
18
|
+
|
|
19
|
+
Write-Host ""
|
|
20
|
+
Write-Host " Thatgfsj Code å®č£
å导" -ForegroundColor Cyan
|
|
21
|
+
Write-Host " =======================" -ForegroundColor Cyan
|
|
22
|
+
Write-Host ""
|
|
23
|
+
|
|
24
|
+
if ($DryRun) {
|
|
25
|
+
Write-Host "[DRY RUN] ä»
ę¾ē¤ŗå°č¦ę§č”ēęä½" -ForegroundColor Yellow
|
|
26
|
+
Write-Host ""
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
# ============== Step 1: Check PowerShell ==============
|
|
30
|
+
Write-Step "ę£ę„ PowerShell ēę¬..."
|
|
31
|
+
|
|
32
|
+
if ($PSVersionTable.PSVersion.Major -lt 5) {
|
|
33
|
+
Write-Error "éč¦ PowerShell 5.0 ęę“é«ēę¬"
|
|
34
|
+
Write-Host "请åēŗ§ęØē PowerShell: https://aka.ms/powershell" -ForegroundColor Gray
|
|
35
|
+
exit 1
|
|
36
|
+
}
|
|
37
|
+
Write-Success "PowerShell $($PSVersionTable.PSVersion) ę£ęµę£åøø"
|
|
38
|
+
|
|
39
|
+
# ============== Step 2: Check/Fetch Node.js ==============
|
|
40
|
+
Write-Step "ę£ę„ Node.js..."
|
|
41
|
+
|
|
42
|
+
function Test-NodeInstalled {
|
|
43
|
+
try {
|
|
44
|
+
$nodeVersion = node --version 2>$null
|
|
45
|
+
if ($nodeVersion) {
|
|
46
|
+
$version = [int]($nodeVersion -replace 'v(\d+)\..*', '$1')
|
|
47
|
+
return @{ installed = $true; version = $nodeVersion; major = $version }
|
|
48
|
+
}
|
|
49
|
+
} catch {}
|
|
50
|
+
return @{ installed = $false; version = $null; major = 0 }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
$nodeStatus = Test-NodeInstalled
|
|
54
|
+
if ($nodeStatus.installed -and $nodeStatus.major -ge 18) {
|
|
55
|
+
Write-Success "Node.js $($nodeStatus.version) å·²å®č£
"
|
|
56
|
+
} else {
|
|
57
|
+
Write-Host " ęŖę£ęµå° Node.js 18+ļ¼å¼å§å®č£
..." -ForegroundColor Gray
|
|
58
|
+
|
|
59
|
+
# Try winget first
|
|
60
|
+
if (Get-Command winget -ErrorAction SilentlyContinue) {
|
|
61
|
+
Write-Info "ä½æēØ winget å®č£
..."
|
|
62
|
+
winget install OpenJS.NodeJS.LTS --source winget --accept-package-agreements --accept-source-agreements
|
|
63
|
+
|
|
64
|
+
# Refresh PATH
|
|
65
|
+
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
|
66
|
+
|
|
67
|
+
$nodeStatus = Test-NodeInstalled
|
|
68
|
+
if ($nodeStatus.installed) {
|
|
69
|
+
Write-Success "Node.js å®č£
å®ę"
|
|
70
|
+
} else {
|
|
71
|
+
Write-Host " éč¦éåÆ PowerShell åéę°čæč”å®č£
" -ForegroundColor Yellow
|
|
72
|
+
exit 0
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
# Try choco
|
|
76
|
+
elseif (Get-Command choco -ErrorAction SilentlyContinue) {
|
|
77
|
+
Write-Info "ä½æēØ Chocolatey å®č£
..."
|
|
78
|
+
choco install nodejs-lts -y
|
|
79
|
+
Write-Success "Node.js å®č£
å®ę (åÆč½éč¦éåÆ)"
|
|
80
|
+
}
|
|
81
|
+
# Manual fallback
|
|
82
|
+
else {
|
|
83
|
+
Write-Host ""
|
|
84
|
+
Write-Error "ęŖę£ęµå°å
ē®”ēåØ (winget/choco/scoop)"
|
|
85
|
+
Write-Host ""
|
|
86
|
+
Write-Host "请ęåØå®č£
Node.js:" -ForegroundColor Yellow
|
|
87
|
+
Write-Host " 1. č®æé® https://nodejs.org" -ForegroundColor Gray
|
|
88
|
+
Write-Host " 2. äøč½½ LTS ēę¬ (ęØč v20 ę v22)" -ForegroundColor Gray
|
|
89
|
+
Write-Host " 3. čæč”å®č£
ēØåŗ" -ForegroundColor Gray
|
|
90
|
+
Write-Host " 4. éę°čæč”ę¤å®č£
čę¬" -ForegroundColor Gray
|
|
91
|
+
Write-Host ""
|
|
92
|
+
exit 1
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# ============== Step 3: Clone/Update Repository ==============
|
|
97
|
+
Write-Step "åå¤å®č£
Thatgfsj Code..."
|
|
98
|
+
|
|
99
|
+
$installDir = Join-Path $env:USERPROFILE "thatgfsj-code"
|
|
100
|
+
|
|
101
|
+
if (Test-Path $installDir) {
|
|
102
|
+
Write-Info "ę£ęµå°å·²ęå®č£
ļ¼ę£åØę“ę°..."
|
|
103
|
+
if (-not $DryRun) {
|
|
104
|
+
Set-Location $installDir
|
|
105
|
+
git pull origin main 2>$null
|
|
106
|
+
if ($LASTEXITCODE -ne 0) {
|
|
107
|
+
# If pull fails, re-clone
|
|
108
|
+
Remove-Item $installDir -Recurse -Force
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
if (-not $DryRun) {
|
|
113
|
+
Write-Info "ę£åØå
éä»åŗ..."
|
|
114
|
+
git clone https://github.com/Thatgfsj/thatgfsj-code.git $installDir
|
|
115
|
+
Set-Location $installDir
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (-not (Test-Path (Join-Path $installDir "package.json"))) {
|
|
120
|
+
Write-Error "å®č£
ē®å½ę ę: $installDir"
|
|
121
|
+
exit 1
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
Write-Success "代ē åå¤å®ę: $installDir"
|
|
125
|
+
|
|
126
|
+
# ============== Step 4: Install Dependencies ==============
|
|
127
|
+
Write-Step "å®č£
ä¾čµ..."
|
|
128
|
+
|
|
129
|
+
if (-not $DryRun) {
|
|
130
|
+
Set-Location $installDir
|
|
131
|
+
npm install
|
|
132
|
+
if ($LASTEXITCODE -ne 0) {
|
|
133
|
+
Write-Error "npm install 失蓄"
|
|
134
|
+
exit 1
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
Write-Info "ē¼čÆ TypeScript..."
|
|
138
|
+
npm run build
|
|
139
|
+
if ($LASTEXITCODE -ne 0) {
|
|
140
|
+
Write-Error "ē¼čÆå¤±č“„"
|
|
141
|
+
exit 1
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
Write-Success "ä¾čµå®č£
å®ę"
|
|
145
|
+
|
|
146
|
+
# ============== Step 5: Link Command ==============
|
|
147
|
+
Write-Step "设置å½ä»¤..."
|
|
148
|
+
|
|
149
|
+
if (-not $DryRun) {
|
|
150
|
+
npm link
|
|
151
|
+
}
|
|
152
|
+
Write-Success "å½ä»¤ 'gfcode' å·²åÆēØ"
|
|
153
|
+
|
|
154
|
+
# ============== Step 6: Setup API Key ==============
|
|
155
|
+
Write-Host ""
|
|
156
|
+
Write-Step "é
ē½® API Key (åÆé)..."
|
|
157
|
+
|
|
158
|
+
$apiKeySet = $false
|
|
159
|
+
$providers = @{
|
|
160
|
+
"1" = @{name="SiliconFlow (ęØč)"; var="SILICONFLOW_API_KEY"; url="https://siliconflow.cn"}
|
|
161
|
+
"2" = @{name="MiniMax"; var="MINIMAX_API_KEY"; url="https://platform.minimax.io"}
|
|
162
|
+
"3" = @{name="OpenAI"; var="OPENAI_API_KEY"; url="https://platform.openai.com"}
|
|
163
|
+
"4" = @{name="Anthropic"; var="ANTHROPIC_API_KEY"; url="https://www.anthropic.com"}
|
|
164
|
+
"5" = @{name="Google Gemini"; var="GEMINI_API_KEY"; url="https://aistudio.google.com/app/apikey"}
|
|
165
|
+
"6" = @{name="č·³čæ (ēØåé
ē½®)"; var=""; url=""}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
Write-Host ""
|
|
169
|
+
Write-Host " éę© AI Provider:" -ForegroundColor White
|
|
170
|
+
Write-Host ""
|
|
171
|
+
foreach ($key in $providers.Keys | Sort-Object) {
|
|
172
|
+
$p = $providers[$key]
|
|
173
|
+
Write-Host " $key. $($p.name)" -ForegroundColor Gray
|
|
174
|
+
}
|
|
175
|
+
Write-Host ""
|
|
176
|
+
|
|
177
|
+
if ($NoOpen) {
|
|
178
|
+
Write-Host " ä½æēØ --NoOpen č·³čæé
ē½®" -ForegroundColor Gray
|
|
179
|
+
} else {
|
|
180
|
+
$choice = Read-Host " 请éę© (1-6, ē“ę„å车跳čæ)"
|
|
181
|
+
|
|
182
|
+
if ($choice -and $providers.ContainsKey($choice)) {
|
|
183
|
+
$selected = $providers[$choice]
|
|
184
|
+
if ($selected.var) {
|
|
185
|
+
Write-Host ""
|
|
186
|
+
Write-Host " č®æé® $($selected.url) č·å API Key" -ForegroundColor Cyan
|
|
187
|
+
Write-Host " č·ååē²č““å°äøę¹" -ForegroundColor Gray
|
|
188
|
+
Write-Host ""
|
|
189
|
+
|
|
190
|
+
$key = Read-Host " 请č¾å
„ API Key (č¾å
„åå车)"
|
|
191
|
+
|
|
192
|
+
if ($key) {
|
|
193
|
+
# Save to config file
|
|
194
|
+
$configDir = Join-Path $env:USERPROFILE ".thatgfsj"
|
|
195
|
+
if (-not (Test-Path $configDir)) {
|
|
196
|
+
New-Item -ItemType Directory -Path $configDir -Force | Out-Null
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
$configFile = Join-Path $configDir "config.json"
|
|
200
|
+
$config = @{
|
|
201
|
+
model = "Qwen/Qwen2.5-7B-Instruct"
|
|
202
|
+
apiKey = $key
|
|
203
|
+
provider = "siliconflow"
|
|
204
|
+
temperature = 0.7
|
|
205
|
+
maxTokens = 4096
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# Set provider-specific defaults
|
|
209
|
+
switch ($choice) {
|
|
210
|
+
"1" { $config.provider = "siliconflow"; $config.model = "Qwen/Qwen2.5-7B-Instruct" }
|
|
211
|
+
"2" { $config.provider = "minimax"; $config.model = "MiniMax-M2.5" }
|
|
212
|
+
"3" { $config.provider = "openai"; $config.model = "gpt-4o-mini" }
|
|
213
|
+
"4" { $config.provider = "anthropic"; $config.model = "claude-3-haiku-20240307" }
|
|
214
|
+
"5" { $config.provider = "gemini"; $config.model = "gemini-1.5-flash-8b" }
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
$config | ConvertTo-Json | Set-Content $configFile -Encoding UTF8
|
|
218
|
+
Write-Success "é
置已äæåå°: $configFile"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
# ============== Done ==============
|
|
225
|
+
Write-Host ""
|
|
226
|
+
Write-Host " ======================================" -ForegroundColor Cyan
|
|
227
|
+
Write-Success " å®č£
å®ę!"
|
|
228
|
+
Write-Host " ======================================" -ForegroundColor Cyan
|
|
229
|
+
Write-Host ""
|
|
230
|
+
Write-Host " 使ēØę¹ę³:" -ForegroundColor White
|
|
231
|
+
Write-Host " gfcode init - éę°é
ē½®" -ForegroundColor Gray
|
|
232
|
+
Write-Host " gfcode - åÆåØäŗ¤äŗęØ”å¼" -ForegroundColor Gray
|
|
233
|
+
Write-Host " gfcode 'ä½ ēé®é¢' - ē“ę„ęé®" -ForegroundColor Gray
|
|
234
|
+
Write-Host " gfcode explain '代ē ' - č§£é代ē " -ForegroundColor Gray
|
|
235
|
+
Write-Host " gfcode debug '代ē ' - č°čÆä»£ē " -ForegroundColor Gray
|
|
236
|
+
Write-Host ""
|
|
237
|
+
Write-Host " ę攣: https://github.com/Thatgfsj/thatgfsj-code" -ForegroundColor Gray
|
|
238
|
+
Write-Host ""
|
package/install.sh
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Thatgfsj Code Installer for macOS/Linux
|
|
3
|
+
# Usage: curl -sL https://raw.githubusercontent.com/Thatgfsj/thatgfsj-code/main/install.sh | bash
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Colors
|
|
8
|
+
RED='\033[0;31m'
|
|
9
|
+
GREEN='\033[0;32m'
|
|
10
|
+
YELLOW='\033[1;33m'
|
|
11
|
+
CYAN='\033[0;36m'
|
|
12
|
+
NC='\033[0m' # No Color
|
|
13
|
+
|
|
14
|
+
echo ""
|
|
15
|
+
echo -e "${CYAN} Thatgfsj Code å®č£
å导${NC}"
|
|
16
|
+
echo -e "${CYAN} =======================${NC}"
|
|
17
|
+
echo ""
|
|
18
|
+
|
|
19
|
+
# ============== Step 1: Check Node.js ==============
|
|
20
|
+
echo -e "${YELLOW}[*] ę£ę„ Node.js...${NC}"
|
|
21
|
+
|
|
22
|
+
if command -v node &> /dev/null; then
|
|
23
|
+
NODE_VERSION=$(node --version)
|
|
24
|
+
MAJOR_VERSION=$(echo $NODE_VERSION | cut -d'v' -f2 | cut -d'.' -f1)
|
|
25
|
+
if [ "$MAJOR_VERSION" -ge 18 ]; then
|
|
26
|
+
echo -e "${GREEN}[ā] Node.js $NODE_VERSION å·²å®č£
${NC}"
|
|
27
|
+
else
|
|
28
|
+
echo -e "${RED}[ā] Node.js ēę¬čæä½ļ¼éč¦ v18+${NC}"
|
|
29
|
+
echo " čÆ·č®æé® https://nodejs.org åēŗ§"
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
else
|
|
33
|
+
echo -e "${YELLOW}[*] ęŖę£ęµå° Node.jsļ¼å¼å§å®č£
...${NC}"
|
|
34
|
+
|
|
35
|
+
# Try Homebrew (macOS)
|
|
36
|
+
if command -v brew &> /dev/null; then
|
|
37
|
+
echo -e "${YELLOW}[*] ä½æēØ Homebrew å®č£
...${NC}"
|
|
38
|
+
brew install node
|
|
39
|
+
# Try apt (Ubuntu/Debian)
|
|
40
|
+
elif command -v apt-get &> /dev/null; then
|
|
41
|
+
echo -e "${YELLOW}[*] ä½æēØ apt å®č£
...${NC}"
|
|
42
|
+
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
|
43
|
+
sudo apt-get install -y nodejs
|
|
44
|
+
# Try yum (CentOS/RHEL)
|
|
45
|
+
elif command -v yum &> /dev/null; then
|
|
46
|
+
echo -e "${YELLOW}[*] ä½æēØ yum å®č£
...${NC}"
|
|
47
|
+
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
|
|
48
|
+
sudo yum install -y nodejs
|
|
49
|
+
else
|
|
50
|
+
echo -e "${RED}[ā] ęŖę¾å°å
ē®”ēåØ${NC}"
|
|
51
|
+
echo " 请ęåØå®č£
: https://nodejs.org"
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# ============== Step 2: Clone/Update ==============
|
|
57
|
+
echo -e "${YELLOW}[*] åå¤å®č£
Thatgfsj Code...${NC}"
|
|
58
|
+
|
|
59
|
+
INSTALL_DIR="$HOME/thatgfsj-code"
|
|
60
|
+
|
|
61
|
+
if [ -d "$INSTALL_DIR" ]; then
|
|
62
|
+
echo -e "${YELLOW}[*] ę£ęµå°å·²ęå®č£
ļ¼ę£åØę“ę°...${NC}"
|
|
63
|
+
cd "$INSTALL_DIR"
|
|
64
|
+
git pull origin main 2>/dev/null || {
|
|
65
|
+
echo -e "${YELLOW}[*] ę“ę°å¤±č“„ļ¼éę°å
é...${NC}"
|
|
66
|
+
rm -rf "$INSTALL_DIR"
|
|
67
|
+
}
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
if [ ! -d "$INSTALL_DIR" ]; then
|
|
71
|
+
echo -e "${YELLOW}[*] å
éä»åŗ...${NC}"
|
|
72
|
+
git clone https://github.com/Thatgfsj/thatgfsj-code.git "$INSTALL_DIR"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
cd "$INSTALL_DIR"
|
|
76
|
+
|
|
77
|
+
if [ ! -f "package.json" ]; then
|
|
78
|
+
echo -e "${RED}[ā] å®č£
ē®å½ę ę${NC}"
|
|
79
|
+
exit 1
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
echo -e "${GREEN}[ā] 代ē åå¤å®ę: $INSTALL_DIR${NC}"
|
|
83
|
+
|
|
84
|
+
# ============== Step 3: Install Dependencies ==============
|
|
85
|
+
echo -e "${YELLOW}[*] å®č£
ä¾čµ...${NC}"
|
|
86
|
+
|
|
87
|
+
npm install
|
|
88
|
+
npm run build
|
|
89
|
+
|
|
90
|
+
echo -e "${GREEN}[ā] ä¾čµå®č£
å®ę${NC}"
|
|
91
|
+
|
|
92
|
+
# ============== Step 4: Link Command ==============
|
|
93
|
+
echo -e "${YELLOW}[*] 设置å½ä»¤...${NC}"
|
|
94
|
+
|
|
95
|
+
npm link
|
|
96
|
+
|
|
97
|
+
echo -e "${GREEN}[ā] å½ä»¤ 'gfcode' å·²åÆēØ${NC}"
|
|
98
|
+
|
|
99
|
+
# ============== Done ==============
|
|
100
|
+
echo ""
|
|
101
|
+
echo -e "${CYAN} ======================================${NC}"
|
|
102
|
+
echo -e "${GREEN} å®č£
å®ę!${NC}"
|
|
103
|
+
echo -e "${CYAN} ======================================${NC}"
|
|
104
|
+
echo ""
|
|
105
|
+
echo -e " ${WHITE}使ēØę¹ę³:${NC}"
|
|
106
|
+
echo -e " gfcode init - éę°é
ē½®"
|
|
107
|
+
echo -e " gfcode - åÆåØäŗ¤äŗęØ”å¼"
|
|
108
|
+
echo -e " gfcode 'ä½ ēé®é¢' - ē“ę„ęé®"
|
|
109
|
+
echo -e " gfcode explain '代ē ' - č§£é代ē "
|
|
110
|
+
echo -e " gfcode debug '代ē ' - č°čÆä»£ē "
|
|
111
|
+
echo ""
|
|
112
|
+
echo -e " ę攣: ${CYAN}https://github.com/Thatgfsj/thatgfsj-code${NC}"
|
|
113
|
+
echo ""
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "thatgfsj-code",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Thatgfsj Code - Your AI Coding Assistant",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"thatgfsj": "./dist/index.js",
|
|
9
|
+
"gfcode": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"dev": "tsc && node dist/index.js",
|
|
15
|
+
"link": "npm link"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"ai",
|
|
19
|
+
"cli",
|
|
20
|
+
"coding",
|
|
21
|
+
"assistant"
|
|
22
|
+
],
|
|
23
|
+
"author": "Thatgfsj",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"chalk": "^5.3.0",
|
|
27
|
+
"commander": "^11.1.0",
|
|
28
|
+
"inquirer": "^13.3.2",
|
|
29
|
+
"ora": "^7.0.1",
|
|
30
|
+
"readline": "^1.3.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.10.0",
|
|
34
|
+
"typescript": "^5.3.0"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Module
|
|
3
|
+
* Core agent logic with intent recognition, task planning, and streaming
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { AIEngine } from '../core/ai-engine.js';
|
|
7
|
+
import { SessionManager } from '../core/session.js';
|
|
8
|
+
import { IntentRecognizer, Intent, SubTask } from './intent.js';
|
|
9
|
+
import { StreamingOutput } from './streaming.js';
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
|
|
12
|
+
export interface AgentConfig {
|
|
13
|
+
maxIterations?: number;
|
|
14
|
+
streaming?: boolean;
|
|
15
|
+
verbose?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class Agent {
|
|
19
|
+
private ai: AIEngine;
|
|
20
|
+
private session: SessionManager;
|
|
21
|
+
private intentRecognizer: IntentRecognizer;
|
|
22
|
+
private config: AgentConfig;
|
|
23
|
+
private streaming: StreamingOutput;
|
|
24
|
+
|
|
25
|
+
constructor(ai: AIEngine, session: SessionManager, config?: AgentConfig) {
|
|
26
|
+
this.ai = ai;
|
|
27
|
+
this.session = session;
|
|
28
|
+
this.intentRecognizer = new IntentRecognizer(ai);
|
|
29
|
+
this.config = {
|
|
30
|
+
maxIterations: 5,
|
|
31
|
+
streaming: false,
|
|
32
|
+
verbose: false,
|
|
33
|
+
...config
|
|
34
|
+
};
|
|
35
|
+
this.streaming = new StreamingOutput();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Process user input through the agent
|
|
40
|
+
*/
|
|
41
|
+
async process(input: string): Promise<string> {
|
|
42
|
+
// Step 1: Recognize intent
|
|
43
|
+
const intent = await this.intentRecognizer.recognize(input);
|
|
44
|
+
|
|
45
|
+
if (this.config.verbose) {
|
|
46
|
+
console.log(chalk.gray(`\nš Intent: ${intent.type} (${intent.confidence}) - ${intent.reason}`));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Step 2: Handle complex tasks
|
|
50
|
+
if (intent.type === 'complex') {
|
|
51
|
+
return await this.handleComplexTask(input, intent);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Step 3: Route to appropriate handler
|
|
55
|
+
switch (intent.type) {
|
|
56
|
+
case 'command':
|
|
57
|
+
return await this.handleCommand(input);
|
|
58
|
+
case 'query':
|
|
59
|
+
return await this.handleQuery(input);
|
|
60
|
+
case 'code':
|
|
61
|
+
case 'chat':
|
|
62
|
+
default:
|
|
63
|
+
return await this.handleGeneral(input);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Handle complex multi-step tasks
|
|
69
|
+
*/
|
|
70
|
+
private async handleComplexTask(input: string, intent: Intent): Promise<string> {
|
|
71
|
+
const subtasks = await this.intentRecognizer.breakIntoSubtasks(input);
|
|
72
|
+
|
|
73
|
+
if (this.config.verbose) {
|
|
74
|
+
console.log(chalk.cyan(`\nš Breaking into ${subtasks.length} subtasks:`));
|
|
75
|
+
subtasks.forEach((task, i) => {
|
|
76
|
+
console.log(chalk.gray(` ${i + 1}. ${task.description} [${task.action}]`));
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let results: string[] = [];
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < subtasks.length; i++) {
|
|
83
|
+
const task = subtasks[i];
|
|
84
|
+
console.log(chalk.cyan(`\n[${i + 1}/${subtasks.length}] ${task.description}...`));
|
|
85
|
+
|
|
86
|
+
const result = await this.process(task.description);
|
|
87
|
+
results.push(result);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return results.join('\n\n');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Handle command intent
|
|
95
|
+
*/
|
|
96
|
+
private async handleCommand(input: string): Promise<string> {
|
|
97
|
+
// Extract command from input
|
|
98
|
+
const command = input
|
|
99
|
+
.replace(/^(run|execute|exec)\s+/i, '')
|
|
100
|
+
.trim();
|
|
101
|
+
|
|
102
|
+
// Add to session and get response
|
|
103
|
+
this.session.addMessage('user', input);
|
|
104
|
+
|
|
105
|
+
const response = await this.ai.chat(this.session.getMessages(), this.config.maxIterations);
|
|
106
|
+
|
|
107
|
+
this.session.addMessage('assistant', response.content);
|
|
108
|
+
|
|
109
|
+
return response.content;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Handle query intent
|
|
114
|
+
*/
|
|
115
|
+
private async handleQuery(input: string): Promise<string> {
|
|
116
|
+
this.session.addMessage('user', input);
|
|
117
|
+
|
|
118
|
+
const response = await this.ai.chat(this.session.getMessages(), this.config.maxIterations);
|
|
119
|
+
|
|
120
|
+
this.session.addMessage('assistant', response.content);
|
|
121
|
+
|
|
122
|
+
return response.content;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Handle general/code/chat intents
|
|
127
|
+
*/
|
|
128
|
+
private async handleGeneral(input: string): Promise<string> {
|
|
129
|
+
this.session.addMessage('user', input);
|
|
130
|
+
|
|
131
|
+
const response = await this.ai.chat(this.session.getMessages(), this.config.maxIterations);
|
|
132
|
+
|
|
133
|
+
this.session.addMessage('assistant', response.content);
|
|
134
|
+
|
|
135
|
+
return response.content;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Process with streaming output
|
|
140
|
+
*/
|
|
141
|
+
async processStream(input: string, onChunk: (chunk: string) => void): Promise<string> {
|
|
142
|
+
const wasStreaming = this.config.streaming;
|
|
143
|
+
this.config.streaming = true;
|
|
144
|
+
|
|
145
|
+
this.streaming.start({ onChunk });
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const result = await this.process(input);
|
|
149
|
+
this.streaming.end();
|
|
150
|
+
return result;
|
|
151
|
+
} catch (error) {
|
|
152
|
+
this.streaming.stop();
|
|
153
|
+
throw error;
|
|
154
|
+
} finally {
|
|
155
|
+
this.config.streaming = wasStreaming;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get session
|
|
161
|
+
*/
|
|
162
|
+
getSession(): SessionManager {
|
|
163
|
+
return this.session;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Clear session
|
|
168
|
+
*/
|
|
169
|
+
clearSession(): void {
|
|
170
|
+
this.session.clear();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Interrupt ongoing operation
|
|
175
|
+
*/
|
|
176
|
+
interrupt(): void {
|
|
177
|
+
this.streaming.stop();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Module
|
|
3
|
+
* Core agent logic with intent recognition and task planning
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { Agent, type AgentConfig } from './core.js';
|
|
7
|
+
export { IntentRecognizer, type Intent, type SubTask } from './intent.js';
|
|
8
|
+
export { StreamingOutput } from './streaming.js';
|