Skip to content

Commit 565f8a4

Browse files
znsoftznsoft
authored andcommitted
macos
1 parent d339e9a commit 565f8a4

File tree

10 files changed

+378
-120
lines changed

10 files changed

+378
-120
lines changed

app.go

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ var UpdateTrayMenu func(string)
3030

3131
type ModelConfig struct {
3232
ModelName string `json:"model_name"`
33+
ModelId string `json:"model_id"`
3334
ModelUrl string `json:"model_url"`
3435
ApiKey string `json:"api_key"`
3536
IsCustom bool `json:"is_custom"`
@@ -271,38 +272,35 @@ func (a *App) syncToClaudeSettings(config AppConfig) error {
271272
switch strings.ToLower(selectedModel.ModelName) {
272273
case "kimi":
273274
env["ANTHROPIC_BASE_URL"] = "https://api.kimi.com/coding"
274-
env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = "kimi-k2-thinking"
275-
env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = "kimi-k2-thinking"
276-
env["ANTHROPIC_DEFAULT_SONNET_MODEL"] = "kimi-k2-thinking"
277-
env["ANTHROPIC_MODEL"] = "kimi-k2-thinking"
275+
env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = selectedModel.ModelId
276+
env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = selectedModel.ModelId
277+
env["ANTHROPIC_DEFAULT_SONNET_MODEL"] = selectedModel.ModelId
278+
env["ANTHROPIC_MODEL"] = selectedModel.ModelId
278279
case "glm", "glm-4.7":
279280
env["ANTHROPIC_BASE_URL"] = "https://open.bigmodel.cn/api/anthropic"
280-
env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = "glm-4.7"
281-
env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = "glm-4.7"
282-
env["ANTHROPIC_DEFAULT_SONNET_MODEL"] = "glm-4.7"
283-
env["ANTHROPIC_MODEL"] = "glm-4.7"
281+
env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = selectedModel.ModelId
282+
env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = selectedModel.ModelId
283+
env["ANTHROPIC_DEFAULT_SONNET_MODEL"] = selectedModel.ModelId
284+
env["ANTHROPIC_MODEL"] = selectedModel.ModelId
284285
settings["permissions"] = map[string]string{"defaultMode": "dontAsk"}
285286
case "doubao":
286287
env["ANTHROPIC_BASE_URL"] = "https://ark.cn-beijing.volces.com/api/coding"
287-
env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = "doubao-seed-code-preview-latest"
288-
env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = "doubao-seed-code-preview-latest"
289-
env["ANTHROPIC_DEFAULT_SONNET_MODEL"] = "doubao-seed-code-preview-latest"
290-
env["ANTHROPIC_MODEL"] = "doubao-seed-code-preview-latest"
288+
env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = selectedModel.ModelId
289+
env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = selectedModel.ModelId
290+
env["ANTHROPIC_DEFAULT_SONNET_MODEL"] = selectedModel.ModelId
291+
env["ANTHROPIC_MODEL"] = selectedModel.ModelId
291292
case "minimax":
292293
env["ANTHROPIC_BASE_URL"] = "https://api.minimaxi.com/anthropic"
293-
env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = "MiniMax-M2.1"
294-
env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = "MiniMax-M2.1"
295-
env["ANTHROPIC_DEFAULT_SONNET_MODEL"] = "MiniMax-M2.1"
296-
env["ANTHROPIC_MODEL"] = "MiniMax-M2.1"
297-
env["ANTHROPIC_SMALL_FAST_MODEL"] = "MiniMax-M2.1"
294+
env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = selectedModel.ModelId
295+
env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = selectedModel.ModelId
296+
env["ANTHROPIC_DEFAULT_SONNET_MODEL"] = selectedModel.ModelId
297+
env["ANTHROPIC_MODEL"] = selectedModel.ModelId
298+
env["ANTHROPIC_SMALL_FAST_MODEL"] = selectedModel.ModelId
298299
env["API_TIMEOUT_MS"] = "3000000"
299300
env["CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC"] = "1"
300-
case "aicodemirror", "aicodemirror-claude":
301-
env["ANTHROPIC_BASE_URL"] = selectedModel.ModelUrl
302-
env["ANTHROPIC_MODEL"] = "Haiku"
303301
default:
304302
env["ANTHROPIC_BASE_URL"] = selectedModel.ModelUrl
305-
env["ANTHROPIC_MODEL"] = selectedModel.ModelName
303+
env["ANTHROPIC_MODEL"] = selectedModel.ModelId
306304
}
307305

308306
settings["env"] = env
@@ -410,7 +408,7 @@ writeConfigToml:
410408
}
411409

412410
configToml := fmt.Sprintf(`model_provider = "aicodemirror"
413-
model = "gpt-5.2-codex"
411+
model = "%s"
414412
model_reasoning_effort = "xhigh"
415413
disable_response_storage = true
416414
preferred_auth_method = "apikey"
@@ -419,7 +417,7 @@ preferred_auth_method = "apikey"
419417
name = "aicodemirror"
420418
base_url = "%s"
421419
wire_api = "responses"
422-
`, baseUrl)
420+
`, selectedModel.ModelId, baseUrl)
423421

424422
configBytes := []byte(configToml)
425423

@@ -566,6 +564,21 @@ func (a *App) LaunchTool(toolName string, yoloMode bool, projectDir string) {
566564
os.Setenv(envBaseUrl, selectedModel.ModelUrl)
567565
env[envBaseUrl] = selectedModel.ModelUrl
568566
}
567+
568+
// Set generic model name env var if applicable
569+
if selectedModel.ModelId != "" {
570+
switch strings.ToLower(toolName) {
571+
case "claude":
572+
os.Setenv("ANTHROPIC_MODEL", selectedModel.ModelId)
573+
env["ANTHROPIC_MODEL"] = selectedModel.ModelId
574+
case "gemini":
575+
os.Setenv("GOOGLE_GEMINI_MODEL", selectedModel.ModelId)
576+
env["GOOGLE_GEMINI_MODEL"] = selectedModel.ModelId
577+
case "codex":
578+
os.Setenv("OPENAI_MODEL", selectedModel.ModelId)
579+
env["OPENAI_MODEL"] = selectedModel.ModelId
580+
}
581+
}
569582

570583
// Tool-specific configurations
571584
switch strings.ToLower(toolName) {
@@ -638,23 +651,23 @@ func (a *App) LoadConfig() (AppConfig, error) {
638651

639652
// Helper for default models
640653
defaultClaudeModels := []ModelConfig{
641-
{ModelName: "Original", ModelUrl: "", ApiKey: ""},
642-
{ModelName: "GLM", ModelUrl: "https://open.bigmodel.cn/api/anthropic", ApiKey: ""},
643-
{ModelName: "kimi", ModelUrl: "https://api.kimi.com/coding", ApiKey: ""},
644-
{ModelName: "doubao", ModelUrl: "https://ark.cn-beijing.volces.com/api/coding", ApiKey: ""},
645-
{ModelName: "MiniMax", ModelUrl: "https://api.minimaxi.com/anthropic", ApiKey: ""},
646-
{ModelName: "AICodeMirror", ModelUrl: "https://api.aicodemirror.com/api/claudecode", ApiKey: ""},
647-
{ModelName: "Custom", ModelUrl: "", ApiKey: "", IsCustom: true},
654+
{ModelName: "Original", ModelId: "", ModelUrl: "", ApiKey: ""},
655+
{ModelName: "GLM", ModelId: "glm-4.7", ModelUrl: "https://open.bigmodel.cn/api/anthropic", ApiKey: ""},
656+
{ModelName: "kimi", ModelId: "kimi-k2-thinking", ModelUrl: "https://api.kimi.com/coding", ApiKey: ""},
657+
{ModelName: "doubao", ModelId: "doubao-seed-code-preview-latest", ModelUrl: "https://ark.cn-beijing.volces.com/api/coding", ApiKey: ""},
658+
{ModelName: "MiniMax", ModelId: "MiniMax-M2.1", ModelUrl: "https://api.minimaxi.com/anthropic", ApiKey: ""},
659+
{ModelName: "AICodeMirror", ModelId: "Haiku", ModelUrl: "https://api.aicodemirror.com/api/claudecode", ApiKey: ""},
660+
{ModelName: "Custom", ModelId: "", ModelUrl: "", ApiKey: "", IsCustom: true},
648661
}
649662
defaultGeminiModels := []ModelConfig{
650-
{ModelName: "Original", ModelUrl: "", ApiKey: ""},
651-
{ModelName: "AiCodeMirror", ModelUrl: "https://api.aicodemirror.com/api/gemini", ApiKey: ""},
652-
{ModelName: "Custom", ModelUrl: "", ApiKey: "", IsCustom: true},
663+
{ModelName: "Original", ModelId: "", ModelUrl: "", ApiKey: ""},
664+
{ModelName: "AiCodeMirror", ModelId: "gemini-2.0-flash-exp", ModelUrl: "https://api.aicodemirror.com/api/gemini", ApiKey: ""},
665+
{ModelName: "Custom", ModelId: "", ModelUrl: "", ApiKey: "", IsCustom: true},
653666
}
654667
defaultCodexModels := []ModelConfig{
655-
{ModelName: "Original", ModelUrl: "", ApiKey: ""},
656-
{ModelName: "AiCodeMirror", ModelUrl: "https://api.aicodemirror.com/api/codex/backend-api/codex", ApiKey: ""},
657-
{ModelName: "Custom", ModelUrl: "", ApiKey: "", IsCustom: true},
668+
{ModelName: "Original", ModelId: "", ModelUrl: "", ApiKey: ""},
669+
{ModelName: "AiCodeMirror", ModelId: "gpt-5.2-codex", ModelUrl: "https://api.aicodemirror.com/api/codex/backend-api/codex", ApiKey: ""},
670+
{ModelName: "Custom", ModelId: "", ModelUrl: "", ApiKey: "", IsCustom: true},
658671
}
659672

660673
if _, err := os.Stat(path); os.IsNotExist(err) {
@@ -1080,6 +1093,26 @@ func (a *App) ShowMessage(title, message string) {
10801093
})
10811094
}
10821095

1096+
func (a *App) ClipboardGetText() (string, error) {
1097+
// Try Wails runtime first
1098+
if a.ctx != nil {
1099+
text, err := runtime.ClipboardGetText(a.ctx)
1100+
if err == nil && text != "" {
1101+
return text, nil
1102+
}
1103+
}
1104+
1105+
// Fallback for macOS: use pbpaste command
1106+
cmd := exec.Command("pbpaste")
1107+
var out bytes.Buffer
1108+
cmd.Stdout = &out
1109+
if err := cmd.Run(); err == nil {
1110+
return out.String(), nil
1111+
}
1112+
1113+
return "", nil
1114+
}
1115+
10831116
func (a *App) ReadBBS() (string, error) {
10841117
url := "https://raw.githubusercontent.com/RapidAI/cceasy/main/bbs.md"
10851118

build_number

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2
1+
80

build_release.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,20 @@ APP_NAME="AICoder"
55
# Read version from build_number if exists, else default
66
if [ -f "build_number" ]; then
77
BUILD_NUM=$(cat build_number)
8+
BUILD_NUM=$((BUILD_NUM + 1))
9+
echo $BUILD_NUM > build_number
810
VERSION="2.0.0.${BUILD_NUM}"
911
else
12+
BUILD_NUM=1
13+
echo $BUILD_NUM > build_number
1014
VERSION="2.0.0.1"
1115
fi
1216

17+
# Sync version to frontend
18+
echo "Syncing version $VERSION to frontend..."
19+
sed -i '' "s/const APP_VERSION = \".*\";/const APP_VERSION = \"$VERSION\";/" frontend/src/App.tsx
20+
echo "export const buildNumber = \"$BUILD_NUM\";" > frontend/src/version.ts
21+
1322
IDENTIFIER="com.wails.AICoder"
1423
OUTPUT_DIR="dist"
1524
BIN_DIR="build/bin"

frontend/src/App.css

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,12 @@ body {
157157
.tabs {
158158
display: flex;
159159
border-bottom: 1px solid var(--border-color);
160-
margin-bottom: 15px;
160+
margin-bottom: 12px;
161161
gap: 2px;
162162
}
163163

164164
.tab-button {
165-
padding: 8px 16px;
165+
padding: 6px 16px;
166166
cursor: pointer;
167167
background-color: transparent;
168168
border: 1px solid transparent;
@@ -205,20 +205,20 @@ body {
205205

206206
/* Form Elements */
207207
.form-group {
208-
margin-bottom: 12px;
208+
margin-bottom: 10px;
209209
}
210210

211211
.form-label {
212212
display: block;
213-
margin-bottom: 6px;
213+
margin-bottom: 5px;
214214
font-size: 0.85rem;
215215
font-weight: 500;
216216
color: var(--text-color);
217217
}
218218

219219
.form-input {
220220
width: 100%;
221-
padding: 8px;
221+
padding: 6px 8px;
222222
border: 1px solid var(--border-color);
223223
border-radius: 6px;
224224
font-size: 0.9rem;
@@ -238,7 +238,7 @@ body {
238238
font-size: 0.9rem;
239239
color: var(--text-secondary);
240240
background-color: var(--accent-bg);
241-
padding: 8px 12px;
241+
padding: 6px 12px;
242242
border-radius: 6px;
243243
border: 1px solid rgba(59, 130, 246, 0.1);
244244
}
@@ -247,7 +247,7 @@ body {
247247
.btn-primary {
248248
background: linear-gradient(135deg, var(--primary-color), var(--primary-dark));
249249
color: white;
250-
padding: 8px 16px;
250+
padding: 6px 16px;
251251
border: none;
252252
border-radius: 6px;
253253
font-size: 0.95rem;
@@ -266,7 +266,7 @@ body {
266266
background-color: transparent;
267267
color: var(--primary-color);
268268
border: 1px solid var(--primary-color);
269-
padding: 8px 12px;
269+
padding: 6px 12px;
270270
border-radius: 6px;
271271
font-size: 0.9rem;
272272
font-weight: 600;
@@ -286,7 +286,7 @@ body {
286286
border: 1px solid var(--border-color);
287287
color: var(--text-secondary);
288288
font-size: 0.8rem;
289-
padding: 4px 12px;
289+
padding: 3px 12px;
290290
border-radius: 15px;
291291
transition: all 0.2s;
292292
font-weight: 500;
@@ -303,7 +303,7 @@ body {
303303
border: 1px solid #24292f;
304304
color: #24292f;
305305
font-size: 0.75rem;
306-
padding: 3px 10px;
306+
padding: 2px 10px;
307307
border-radius: 12px;
308308
transition: all 0.2s;
309309
font-weight: 500;
@@ -323,13 +323,13 @@ body {
323323
.model-switcher {
324324
display: flex;
325325
gap: 10px;
326-
margin-bottom: 15px;
326+
margin-bottom: 12px;
327327
padding: 0 2px; /* Visual balance */
328328
}
329329

330330
.model-btn {
331331
flex: 1;
332-
padding: 7.68px 10px;
332+
padding: 6px 10px;
333333
border: 1px solid var(--border-color);
334334
background-color: var(--surface-color);
335335
color: var(--text-secondary);
@@ -360,7 +360,7 @@ body {
360360
.btn-launch {
361361
background: linear-gradient(135deg, var(--primary-color), var(--primary-dark));
362362
color: white;
363-
padding: 10px 30px;
363+
padding: 8px 30px;
364364
border: none;
365365
border-radius: 8px;
366366
font-size: 0.95rem;
@@ -432,3 +432,16 @@ body {
432432
.modal-close:hover {
433433
color: #374151;
434434
}
435+
436+
.context-menu-item {
437+
padding: 8px 15px;
438+
font-size: 0.9rem;
439+
color: var(--text-color);
440+
cursor: pointer;
441+
transition: background-color 0.2s;
442+
}
443+
444+
.context-menu-item:hover {
445+
background-color: #f1f5f9;
446+
color: var(--primary-color);
447+
}

0 commit comments

Comments
 (0)