thatgfsj-code 0.3.0 → 0.4.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/dist/cmd/index.js +56 -8
- package/dist/cmd/index.js.map +1 -1
- package/dist/config/index.d.ts +5 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +22 -4
- package/dist/config/index.js.map +1 -1
- package/dist/config/providers.d.ts +5 -10
- package/dist/config/providers.d.ts.map +1 -1
- package/dist/config/providers.js +152 -78
- package/dist/config/providers.js.map +1 -1
- package/dist/config/types.d.ts +1 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/llm/anthropic.d.ts +24 -6
- package/dist/llm/anthropic.d.ts.map +1 -1
- package/dist/llm/anthropic.js +136 -46
- package/dist/llm/anthropic.js.map +1 -1
- package/dist/llm/gemini.d.ts +4 -4
- package/dist/llm/gemini.d.ts.map +1 -1
- package/dist/llm/gemini.js +67 -30
- package/dist/llm/gemini.js.map +1 -1
- package/dist/llm/index.d.ts +10 -23
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +73 -78
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/openai.d.ts +19 -6
- package/dist/llm/openai.d.ts.map +1 -1
- package/dist/llm/openai.js +86 -35
- package/dist/llm/openai.js.map +1 -1
- package/dist/llm/provider.d.ts +11 -16
- package/dist/llm/provider.d.ts.map +1 -1
- package/dist/tui/input.d.ts +0 -1
- package/dist/tui/input.d.ts.map +1 -1
- package/dist/tui/input.js +2 -5
- package/dist/tui/input.js.map +1 -1
- package/dist/tui/output.d.ts +27 -12
- package/dist/tui/output.d.ts.map +1 -1
- package/dist/tui/output.js +176 -40
- package/dist/tui/output.js.map +1 -1
- package/dist/tui/repl.d.ts +0 -10
- package/dist/tui/repl.d.ts.map +1 -1
- package/dist/tui/repl.js +76 -42
- package/dist/tui/repl.js.map +1 -1
- package/dist/tui/welcome.d.ts +2 -8
- package/dist/tui/welcome.d.ts.map +1 -1
- package/dist/tui/welcome.js +101 -51
- package/dist/tui/welcome.js.map +1 -1
- package/package.json +1 -1
- package/src/cmd/index.ts +49 -8
- package/src/config/index.ts +21 -4
- package/src/config/providers.ts +153 -79
- package/src/config/types.ts +11 -5
- package/src/llm/anthropic.ts +148 -51
- package/src/llm/gemini.ts +81 -39
- package/src/llm/index.ts +75 -83
- package/src/llm/openai.ts +96 -41
- package/src/llm/provider.ts +12 -16
- package/src/tui/input.ts +2 -5
- package/src/tui/output.ts +193 -40
- package/src/tui/repl.ts +82 -43
- package/src/tui/welcome.ts +110 -53
package/src/tui/welcome.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Welcome / Setup Wizard
|
|
3
|
-
* Migrated and simplified from old src/repl/welcome.ts
|
|
2
|
+
* Welcome / Setup Wizard - Clean UI
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
5
|
import chalk from 'chalk';
|
|
@@ -8,94 +7,152 @@ import readline from 'readline';
|
|
|
8
7
|
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
9
8
|
import { join } from 'path';
|
|
10
9
|
import { homedir } from 'os';
|
|
11
|
-
import { PROVIDERS, getModelsForProvider, listProviders } from '../config/providers.js';
|
|
10
|
+
import { PROVIDERS, getModelsForProvider, listProviders, isCustomProvider } from '../config/providers.js';
|
|
12
11
|
import type { ProviderName } from '../config/types.js';
|
|
13
12
|
|
|
13
|
+
const line = chalk.gray('─'.repeat(52));
|
|
14
|
+
|
|
14
15
|
export class WelcomeScreen {
|
|
15
|
-
|
|
16
|
-
* Show welcome if no API key is configured
|
|
17
|
-
*/
|
|
16
|
+
|
|
18
17
|
static show(hasApiKey: boolean): void {
|
|
19
18
|
if (hasApiKey) return;
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
console.log(chalk.cyan
|
|
23
|
-
console.log(chalk.
|
|
24
|
-
console.log(
|
|
25
|
-
console.log(
|
|
26
|
-
console.log(chalk.
|
|
27
|
-
console.log(
|
|
20
|
+
console.log();
|
|
21
|
+
console.log(chalk.cyan.bold(' ⚡ Thatgfsj Code') + chalk.gray(' v0.4.1'));
|
|
22
|
+
console.log(chalk.gray(' AI Coding Assistant'));
|
|
23
|
+
console.log(line);
|
|
24
|
+
console.log();
|
|
25
|
+
console.log(chalk.yellow(' ⚠ No API key configured'));
|
|
26
|
+
console.log();
|
|
27
|
+
console.log(chalk.gray(' Run ') + chalk.cyan.bold('gfcode init') + chalk.gray(' to set up your provider.'));
|
|
28
|
+
console.log();
|
|
29
|
+
console.log(chalk.gray(' Supported providers:'));
|
|
30
|
+
console.log(chalk.gray(' OpenAI · Claude · DeepSeek · Kimi · GLM · Gemini · 中转站'));
|
|
31
|
+
console.log(line);
|
|
28
32
|
console.log();
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
/**
|
|
32
|
-
* Interactive setup wizard
|
|
33
|
-
*/
|
|
34
35
|
static async interactiveSetup(): Promise<void> {
|
|
35
36
|
console.clear();
|
|
36
|
-
console.log(
|
|
37
|
+
console.log();
|
|
38
|
+
console.log(chalk.cyan.bold(' ⚡ Thatgfsj Code') + chalk.gray(' - Setup'));
|
|
39
|
+
console.log(line);
|
|
40
|
+
console.log();
|
|
37
41
|
|
|
38
42
|
const rl = readline.createInterface({
|
|
39
43
|
input: process.stdin,
|
|
40
44
|
output: process.stdout,
|
|
41
45
|
});
|
|
42
46
|
|
|
43
|
-
const
|
|
47
|
+
const ask = (prompt: string): Promise<string> =>
|
|
44
48
|
new Promise(resolve => rl.question(prompt, answer => resolve(answer.trim())));
|
|
45
49
|
|
|
46
50
|
try {
|
|
47
|
-
// Step 1:
|
|
48
|
-
console.log(chalk.
|
|
51
|
+
// ── Step 1: Provider ────────────────────────────────
|
|
52
|
+
console.log(chalk.bold(' 1. Choose Provider'));
|
|
53
|
+
console.log();
|
|
49
54
|
const providers = listProviders();
|
|
50
55
|
providers.forEach((p, i) => {
|
|
51
|
-
|
|
56
|
+
const num = chalk.cyan((i + 1).toString().padStart(2));
|
|
57
|
+
console.log(` ${num} ${p.name}`);
|
|
52
58
|
});
|
|
53
59
|
console.log();
|
|
54
60
|
|
|
55
|
-
const choice = await
|
|
61
|
+
const choice = await ask(chalk.cyan(' ❯ '));
|
|
56
62
|
const selected = providers[parseInt(choice) - 1] || providers[0];
|
|
57
63
|
const providerName = selected.key;
|
|
58
64
|
|
|
59
|
-
// Step 2:
|
|
60
|
-
console.log(
|
|
61
|
-
console.log(chalk.
|
|
62
|
-
const apiKey = await question(chalk.green(' 请输入 API Key: '));
|
|
63
|
-
|
|
64
|
-
// Step 3: Choose model
|
|
65
|
-
console.log(chalk.white('\n 步骤 3/3: 选择模型\n'));
|
|
66
|
-
const models = getModelsForProvider(providerName);
|
|
67
|
-
models.forEach((m, i) => {
|
|
68
|
-
console.log(chalk.green(` ${i + 1}. ${m.name}`) + chalk.gray(` - ${m.desc}`));
|
|
69
|
-
});
|
|
65
|
+
// ── Step 2: API Key ─────────────────────────────────
|
|
66
|
+
console.log();
|
|
67
|
+
console.log(chalk.bold(' 2. API Key'));
|
|
70
68
|
console.log();
|
|
71
69
|
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
let baseUrl: string | undefined;
|
|
71
|
+
|
|
72
|
+
if (isCustomProvider(providerName)) {
|
|
73
|
+
console.log(chalk.yellow(' Custom Provider (Relay Station)'));
|
|
74
|
+
console.log(chalk.gray(' OpenAI-compatible or Anthropic-compatible'));
|
|
75
|
+
console.log();
|
|
76
|
+
baseUrl = await ask(chalk.cyan(' Base URL ❯ '));
|
|
77
|
+
if (!baseUrl) {
|
|
78
|
+
console.log(chalk.red(' ❌ Base URL required'));
|
|
79
|
+
rl.close();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
baseUrl = baseUrl.replace(/\/+$/, '');
|
|
83
|
+
}
|
|
74
84
|
|
|
75
|
-
|
|
76
|
-
const configDir = join(homedir(), '.thatgfsj');
|
|
77
|
-
const configPath = join(configDir, 'config.json');
|
|
85
|
+
const apiKey = await ask(chalk.cyan(' API Key ❯ '));
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
// ── Step 3: Model ───────────────────────────────────
|
|
88
|
+
console.log();
|
|
89
|
+
console.log(chalk.bold(' 3. Choose Model'));
|
|
90
|
+
console.log();
|
|
82
91
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
if (isCustomProvider(providerName)) {
|
|
93
|
+
console.log(chalk.gray(' Enter model name for your relay station'));
|
|
94
|
+
console.log(chalk.gray(' e.g. gpt-4o-mini, claude-sonnet-4-20250514'));
|
|
95
|
+
console.log();
|
|
96
|
+
const model = await ask(chalk.cyan(' Model ❯ '));
|
|
97
|
+
if (!model) {
|
|
98
|
+
console.log(chalk.red(' ❌ Model name required'));
|
|
99
|
+
rl.close();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
this.saveConfig(providerName, model, apiKey, baseUrl);
|
|
103
|
+
} else {
|
|
104
|
+
const models = getModelsForProvider(providerName);
|
|
105
|
+
models.forEach((m, i) => {
|
|
106
|
+
const num = chalk.cyan((i + 1).toString().padStart(2));
|
|
107
|
+
console.log(` ${num} ${chalk.white(m.name)} ${chalk.gray(m.desc)}`);
|
|
108
|
+
});
|
|
109
|
+
console.log();
|
|
110
|
+
|
|
111
|
+
const modelChoice = await ask(chalk.cyan(' ❯ '));
|
|
112
|
+
const selectedModel = models[parseInt(modelChoice) - 1] || models[0];
|
|
113
|
+
this.saveConfig(providerName, selectedModel.id, apiKey, baseUrl);
|
|
114
|
+
}
|
|
90
115
|
|
|
91
|
-
|
|
92
|
-
console.log(
|
|
93
|
-
console.log(
|
|
94
|
-
console.log(chalk.
|
|
95
|
-
console.log(
|
|
116
|
+
// ── Done ────────────────────────────────────────────
|
|
117
|
+
console.log();
|
|
118
|
+
console.log(line);
|
|
119
|
+
console.log(chalk.green.bold(' ✅ Configuration saved!'));
|
|
120
|
+
console.log();
|
|
121
|
+
console.log(chalk.gray(' Config: ') + chalk.white(join(homedir(), '.thatgfsj', 'config.json')));
|
|
122
|
+
console.log(chalk.gray(' Run ') + chalk.cyan.bold('gfcode') + chalk.gray(' to start.'));
|
|
123
|
+
console.log(line);
|
|
124
|
+
console.log();
|
|
96
125
|
|
|
97
126
|
} finally {
|
|
98
127
|
rl.close();
|
|
99
128
|
}
|
|
100
129
|
}
|
|
130
|
+
|
|
131
|
+
private static saveConfig(provider: ProviderName, model: string, apiKey: string, baseUrl?: string): void {
|
|
132
|
+
const configDir = join(homedir(), '.thatgfsj');
|
|
133
|
+
const configPath = join(configDir, 'config.json');
|
|
134
|
+
|
|
135
|
+
if (!existsSync(configDir)) {
|
|
136
|
+
mkdirSync(configDir, { recursive: true });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const config: Record<string, any> = {
|
|
140
|
+
provider,
|
|
141
|
+
model,
|
|
142
|
+
apiKey,
|
|
143
|
+
temperature: 0.7,
|
|
144
|
+
maxTokens: 4096,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
if (baseUrl) config.baseUrl = baseUrl;
|
|
148
|
+
|
|
149
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
150
|
+
|
|
151
|
+
console.log();
|
|
152
|
+
console.log(chalk.gray(' Provider: ') + chalk.white(provider));
|
|
153
|
+
console.log(chalk.gray(' Model: ') + chalk.white(model));
|
|
154
|
+
if (baseUrl) {
|
|
155
|
+
console.log(chalk.gray(' URL: ') + chalk.white(baseUrl));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
101
158
|
}
|