From fc4221baf8050662c558afed54fcfec155da4ae3 Mon Sep 17 00:00:00 2001 From: David Chen Date: Wed, 24 Jun 2026 16:37:09 +0800 Subject: [PATCH] agent config update --- .tmux.conf | 3 + agent-tracker/cmd/agent/main.go | 73 ++++++++++++------- agent-tracker/cmd/agent/palette_bubbletea.go | 20 +++++- opencode/AGENTS.md | 2 +- opencode/opencode.json | 69 +++++------------- zsh/env.zsh | 2 + zsh/functions/_op_common.zsh | 75 +++++++++----------- 7 files changed, 122 insertions(+), 122 deletions(-) diff --git a/.tmux.conf b/.tmux.conf index d1eab5f..d5369be 100644 --- a/.tmux.conf +++ b/.tmux.conf @@ -336,6 +336,9 @@ set -g @resurrect-capture-pane-contents 'on' set -g @resurrect-processes 'script lazygit yazi' set -g @resurrect-hook-post-restore-all '~/.config/tmux/scripts/post_resurrect_restore.sh' +unbind C-s +unbind C-r + # Continuum: auto-save every 5 minutes set -g @continuum-save-interval '5' set -g @continuum-restore 'off' diff --git a/agent-tracker/cmd/agent/main.go b/agent-tracker/cmd/agent/main.go index b9da08f..8a1ab73 100644 --- a/agent-tracker/cmd/agent/main.go +++ b/agent-tracker/cmd/agent/main.go @@ -105,9 +105,10 @@ type keyConfig struct { } type repoConfig struct { - BaseBranch string `yaml:"base_branch,omitempty"` - CopyIgnore []string `yaml:"copy_ignore,omitempty"` - AgentKeyPaths []string `yaml:"agent_key_paths,omitempty"` + BaseBranch string `yaml:"base_branch,omitempty"` + DefaultDevice string `yaml:"default_device,omitempty"` + CopyIgnore []string `yaml:"copy_ignore,omitempty"` + AgentKeyPaths []string `yaml:"agent_key_paths,omitempty"` } type featureConfig struct { @@ -260,7 +261,7 @@ func runStart(args []string) error { if noDevice { device = "" } else if device == "" { - device = "web-server" + device = resolveDefaultDevice(repoCfg) } browserEnabled = device == "web-server" port, err = allocatePort(repoRoot, 9100) @@ -360,6 +361,13 @@ func runInit(args []string) error { } cfg := defaultRepoConfig() cfg.BaseBranch = detectDefaultBaseBranch(repoRoot) + if fileExists(filepath.Join(repoRoot, "pubspec.yaml")) { + device, err := promptInputWithDefault("Default device", defaultManagedDeviceID) + if err != nil { + return err + } + cfg.DefaultDevice = strings.TrimSpace(device) + } if err := saveRepoConfig(repoRoot, cfg); err != nil { return err } @@ -369,7 +377,7 @@ func runInit(args []string) error { func runConfig(args []string) error { if len(args) == 0 { - return fmt.Errorf("usage: agent config ") + return fmt.Errorf("usage: agent config ") } repoRoot, err := repoRoot() if err != nil { @@ -403,6 +411,19 @@ func runConfig(args []string) error { return fmt.Errorf("base branch is required") } cfg.BaseBranch = branch + case "set-default-device": + device := "" + if len(args) > 1 { + device = strings.TrimSpace(args[1]) + } + if device == "" { + device, err = promptInputWithDefault("Default device", cfg.DefaultDevice) + if err != nil { + return err + } + device = strings.TrimSpace(device) + } + cfg.DefaultDevice = device case "add-ignore": values := normalizeIgnoreValues(args[1:]) if len(values) == 0 { @@ -1491,14 +1512,14 @@ func launchAgentLayout(record *agentRecord) (err error) { if err != nil { return err } - if err := runTmux("split-window", "-t", topPane, "-h", "-p", "40", "-c", record.WorkspaceRoot); err != nil { + if err := runTmux("split-window", "-t", topPane, "-h", "-l", "35%", "-c", record.WorkspaceRoot); err != nil { return err } rightPane, err := currentPane(windowID) if err != nil { return err } - if err := runTmux("split-window", "-t", rightPane, "-v", "-p", "35", "-c", record.WorkspaceRoot); err != nil { + if err := runTmux("split-window", "-t", rightPane, "-v", "-l", "8", "-c", record.WorkspaceRoot); err != nil { return err } runPane, err := currentPane(windowID) @@ -1940,15 +1961,26 @@ func loadAgentRecordByWorkspaceRoot(workspaceRoot string) *agentRecord { } func resolveStartSourceBranch(repoRoot string, repoCfg *repoConfig) string { - if branch := currentLocalBranch(repoRoot); branch != "" { - return branch - } if repoCfg != nil && strings.TrimSpace(repoCfg.BaseBranch) != "" { return strings.TrimSpace(repoCfg.BaseBranch) } + if branch := currentLocalBranch(repoRoot); branch != "" { + return branch + } return detectDefaultBaseBranch(repoRoot) } +func resolveDefaultDevice(repoCfg *repoConfig) string { + if repoCfg != nil && strings.TrimSpace(repoCfg.DefaultDevice) != "" { + d := strings.TrimSpace(repoCfg.DefaultDevice) + if strings.EqualFold(d, "none") { + return "" + } + return d + } + return defaultManagedDeviceID +} + func resolveBootstrapStartOptions(repoRoot string, repoCfg *repoConfig, record *agentRecord) agentStartOptions { options := agentStartOptions{} if record != nil { @@ -2465,18 +2497,6 @@ PY logfile="$DIR/logs/flutter-$port.log" : > "$logfile" 2>/dev/null || true -flutter_ready_seen() { - if [[ -n "${TMUX_PANE-}" ]]; then - if tmux capture-pane -p -S -200 -t "$TMUX_PANE" 2>/dev/null | grep -qi 'Flutter run key commands\.'; then - return 0 - fi - fi - if [[ -f "$logfile" ]] && grep -qi 'Flutter run key commands\.' "$logfile" 2>/dev/null; then - return 0 - fi - return 1 -} - if [[ -z "$device" ]]; then echo "No launch device selected. Run ./ensure-server.sh to start Flutter." exit 0 @@ -2484,12 +2504,14 @@ fi if [[ "$device" == "web-server" ]]; then ( + "$AGENT_BIN" browser refresh --workspace "$DIR" >/dev/null 2>&1 || true + deadline=$((SECONDS+300)) while [ $SECONDS -lt $deadline ]; do - if flutter_ready_seen; then + if [[ -f "$logfile" ]] && grep -qi 'Flutter run key commands\.' "$logfile" 2>/dev/null; then "$AGENT_BIN" feature --workspace "$DIR" --ready true sleep 2 - "$AGENT_BIN" browser refresh --workspace "$DIR" >/dev/null 2>&1 || true + "$AGENT_BIN" browser refresh --workspace "$DIR" >/dev/null 2>&1 || true exit 0 fi sleep 0.1 @@ -2835,6 +2857,9 @@ func promptInputWithDefault(label, defaultValue string) (string, error) { } value, err := promptInput(fmt.Sprintf("%s [%s]: ", label, defaultValue)) if err != nil { + if strings.TrimSpace(value) == "" { + return defaultValue, nil + } return "", err } if strings.TrimSpace(value) == "" { diff --git a/agent-tracker/cmd/agent/palette_bubbletea.go b/agent-tracker/cmd/agent/palette_bubbletea.go index 6ca0e3a..4f4d188 100644 --- a/agent-tracker/cmd/agent/palette_bubbletea.go +++ b/agent-tracker/cmd/agent/palette_bubbletea.go @@ -422,7 +422,7 @@ func (r *paletteRuntime) runAgentStart(repoRoot, feature, device string, keepWor if feature == "" { return fmt.Errorf("feature name is required") } - agentBin := filepath.Join(os.Getenv("HOME"), ".config", "bin", "agent") + agentBin := filepath.Join(os.Getenv("HOME"), ".config", "agent-tracker", "bin", "agent") args := buildAgentStartArgs(feature, device, keepWorktree) cmd := exec.Command(agentBin, args...) cmd.Dir = repoRoot @@ -495,8 +495,22 @@ func startAgentPromptDevices(repoRoot string) ([]string, int) { if len(devices) == 0 { devices = []string{defaultManagedDeviceID} } - if repoRoot != "" && fileExists(filepath.Join(repoRoot, "pubspec.yaml")) { - return append([]string{paletteNoDeviceOption}, devices...), 1 + isFlutter := repoRoot != "" && fileExists(filepath.Join(repoRoot, "pubspec.yaml")) + if isFlutter { + devices = append([]string{paletteNoDeviceOption}, devices...) + } + repoCfg, _ := loadRepoConfigOrDefault(repoRoot) + preferred := resolveDefaultDevice(repoCfg) + if isPaletteNoDeviceOption(preferred) || preferred == "" { + preferred = paletteNoDeviceOption + } + for i, d := range devices { + if d == preferred { + return devices, i + } + } + if isFlutter { + return devices, 1 } return devices, 0 } diff --git a/opencode/AGENTS.md b/opencode/AGENTS.md index 512eb6e..073e1b2 100644 --- a/opencode/AGENTS.md +++ b/opencode/AGENTS.md @@ -1,5 +1,5 @@ # CRITICAL WORKFLOW REQUIREMENT -- You MUST NOT add comments that describe the change they just made (e.g., “removed”, “legacy”, “cleanup”, “hotfix”, “flag removed”, “temporary workaround”). +- You MUST NOT add comments that describe the change they just made (e.g., "removed", "legacy", "cleanup", "hotfix", "flag removed", "temporary workaround"). - Only add comments for genuinely non‑obvious, persistent logic or external invariants. Keep such comments short (max 2 lines). - When migrating or refactoring code, do not leave legacy code. Remove all deprecated or unused code. - Put change reasoning in your plan/final message — not in code. diff --git a/opencode/opencode.json b/opencode/opencode.json index ee4b248..a310bf1 100644 --- a/opencode/opencode.json +++ b/opencode/opencode.json @@ -1,7 +1,6 @@ { "$schema": "https://opencode.ai/config.json", - "autoupdate": true, - "model": "cliproxy/gpt-5.5", + "autoupdate": false, "small_model": "zai-coding-plan/glm-4.7", "agent": { "build": { @@ -11,6 +10,7 @@ "color": "#8be9fd" } }, + "disabled_providers": ["zen", "cloudflare", "cloudflare-ai-gateway", "cloudflare-workers-ai", "opencode-go", "amazon-bedrock", "ollama-cloud"], "compaction": { "auto": false }, @@ -26,6 +26,9 @@ "extensions": [ ".dart" ] + }, + "biome": { + "disabled": true } }, "permission": { @@ -39,7 +42,12 @@ "mcp": { "web": { "type": "remote", - "url": "http://dmini:8765/searcher/mcp", + "url": "http://127.0.0.1:8775/searcher/mcp", + "enabled": true + }, + "rednote": { + "type": "remote", + "url": "http://127.0.0.1:8776/rednote-evidence/mcp", "enabled": true }, "pinchtab": { @@ -69,55 +77,14 @@ "--stdio" ], "enabled": false - } - }, - "provider": { - "cliproxy": { - "api": "openai", - "name": "CLIProxyAPI (dmini)", - "options": { - "apiKey": "sk-dummy", - "baseURL": "http://dmini:8317/v1" - }, - "models": { - "gpt-5.5": { - "name": "gpt-5.5", - "tool_call": true, - "reasoning": true, - "limit": { - "context": 200000, - "output": 32000 - } - }, - "gpt-5.4-mini": { - "name": "gpt-5.4-mini", - "tool_call": true, - "reasoning": true, - "limit": { - "context": 128000, - "output": 16384 - } - } - } }, - "rapidmlx": { - "api": "openai", - "name": "Rapid-MLX Local", - "options": { - "apiKey": "not-needed", - "baseURL": "http://127.0.0.1:8001/v1" - }, - "models": { - "default": { - "name": "rapid-mlx local", - "tool_call": true, - "reasoning": true, - "limit": { - "context": 32768, - "output": 8192 - } - } - } + "imagegen": { + "type": "local", + "command": [ + "node", + "/Users/david/.config/opencode/tool/imagegen-mcp.mjs" + ], + "enabled": true } } } diff --git a/zsh/env.zsh b/zsh/env.zsh index ead047e..0cc2bdb 100644 --- a/zsh/env.zsh +++ b/zsh/env.zsh @@ -45,3 +45,5 @@ export HOMEBREW_DOWNLOAD_CONCURRENCY=auto if [ -d "$HOME/Github/mac-ctrl/bin" ] && ! echo ":$PATH:" | grep -q ":$HOME/Github/mac-ctrl/bin:" ; then export PATH="$HOME/Github/mac-ctrl/bin:$PATH" fi + +export PATH="$XDG_CONFIG_HOME/agent-tracker/bin$PATH" diff --git a/zsh/functions/_op_common.zsh b/zsh/functions/_op_common.zsh index dc5f960..a0a10b3 100644 --- a/zsh/functions/_op_common.zsh +++ b/zsh/functions/_op_common.zsh @@ -17,9 +17,8 @@ _op_run() { local tmp_home tmp_home=$(mktemp -d "${TMPDIR:-/tmp}/opencode-home.XXXXXX") || return 1 - print -u2 "$tag: using temporary OPENCODE_CONFIG_DIR at $tmp_home" - local cleanup_cmd="print -u2 \"$tag: removing temporary OPENCODE_CONFIG_DIR $tmp_home\"; rm -rf '$tmp_home'" + local cleanup_cmd="rm -rf '$tmp_home'" trap "$cleanup_cmd" EXIT INT TERM if ! cp "$base_config" "$tmp_home/opencode.json" >/dev/null 2>&1; then @@ -29,38 +28,23 @@ _op_run() { return 1 fi - if command -v jq >/dev/null 2>&1 && command -v curl >/dev/null 2>&1; then - local rapid_models_json rapid_model_id rapid_model_limit tmp_config_json tmp_context tmp_output tmp_name - rapid_models_json=$(curl -fsS "http://127.0.0.1:8000/v1/models" 2>/dev/null || true) - rapid_model_id=$(printf '%s' "$rapid_models_json" | jq -r '.data[0].id // empty' 2>/dev/null || true) - - if [ -n "$rapid_model_id" ] && [ -f "$rapid_model_id/config.json" ]; then - tmp_context=$(jq -r ' - .text_config.max_position_embeddings // - .language_model.max_position_embeddings // - .language_config.max_position_embeddings // - .max_position_embeddings // - empty - ' "$rapid_model_id/config.json" 2>/dev/null || true) - - if [ -n "$tmp_context" ] && [ "$tmp_context" != "null" ]; then - tmp_output=8192 - tmp_name=${rapid_model_id:t} - tmp_config_json="$tmp_home/opencode.json.tmp" - - if jq \ - --arg name "$tmp_name" \ - --argjson context "$tmp_context" \ - --argjson output "$tmp_output" \ - ' - .provider.rapidmlx.models.default.name = $name | - .provider.rapidmlx.models.default.limit.context = $context | - .provider.rapidmlx.models.default.limit.output = $output - ' "$tmp_home/opencode.json" > "$tmp_config_json" 2>/dev/null; then - mv "$tmp_config_json" "$tmp_home/opencode.json" - print -u2 "$tag: synced rapidmlx/default to $tmp_name (context $tmp_context, output $tmp_output)" - fi - fi + local private_config="${SCONFIG_HOME:-$HOME/.sconfig}/opencode/opencode.json" + if [ -f "$private_config" ]; then + if ! command -v jq >/dev/null 2>&1; then + trap - EXIT INT TERM + eval "$cleanup_cmd" + print -u2 "$tag: jq is required to merge $private_config" + return 1 + fi + local merged_config_json="$tmp_home/opencode.json.merged" + if jq -s '.[0] * .[1]' "$tmp_home/opencode.json" "$private_config" > "$merged_config_json" 2>/dev/null; then + mv "$merged_config_json" "$tmp_home/opencode.json" + else + rm -f "$merged_config_json" + trap - EXIT INT TERM + eval "$cleanup_cmd" + print -u2 "$tag: failed to merge $private_config" + return 1 fi fi @@ -99,17 +83,15 @@ _op_run() { .mcp.agent_browser = { type: "local", command: [$agent_bin, "browser", "mcp", "--workspace", $workspace], - environment: { + env: { AGENT_WORKSPACE: $workspace, AGENT_FEATURE: $feature, AGENT_BROWSER_URL: $url }, - enabled: true, - timeout: 10000 + enabled: false } ' "$tmp_home/opencode.json" > "$tmp_config_json" 2>/dev/null; then mv "$tmp_config_json" "$tmp_home/opencode.json" - print -u2 "$tag: added agent_browser MCP for ${agent_feature:-$agent_workspace}" else rm -f "$tmp_config_json" print -u2 "$tag: failed to add agent_browser MCP for $agent_workspace" @@ -139,6 +121,18 @@ _op_run() { sessions logs skill + node_modules + package.json + package-lock.json + bun.lock + tui.json + consult.json + tui-plugins + tool + tools + tmp + agent + agents ) local name @@ -168,7 +162,6 @@ _op_run() { fi if [ -d "$base_home/command" ]; then - local f for f in "$base_home/command"/*.md; do [ -f "$f" ] || continue cp "$f" "$tmp_home/command/" @@ -182,7 +175,6 @@ _op_run() { if [ -n "$project_prompts_dir" ]; then local copied_any=0 - local f for f in "$project_prompts_dir"/*.md; do [ -f "$f" ] || continue copied_any=1 @@ -194,9 +186,6 @@ _op_run() { return 1 fi done - if (( copied_any )); then - print -u2 "$tag: added project prompts from $project_prompts_dir to commands" - fi fi OPENCODE_CONFIG_DIR="$tmp_home" \