diff --git a/.chezmoiignore b/.chezmoiignore index 61e9808..b44b225 100644 --- a/.chezmoiignore +++ b/.chezmoiignore @@ -11,6 +11,36 @@ Library .pi/agent/auth.json .pi/agent/sessions +# agent CLIs: configs are tracked file by file, but never credentials, session +# logs or local state. Belt and braces in case a directory is ever added whole. +.claude/.credentials.json +.claude/projects +.claude/history.jsonl +.claude/file-history +.claude/telemetry +.claude/session-env +.claude/shell-snapshots +.codex/secrets.env +.codex/auth.json +.codex/accounts +.codex/*.bak +.codex/*.bak-* +.codex/*.bak.* +.codex/sessions +.codex/archived_sessions +.codex/logs* +.codex/*.sqlite* +.grok/auth.json* +.grok/projects +.grok/sessions +.kimi/credentials +.kimi/sessions +.kimi-code/oauth +.kimi-code/sessions +.reasonix/.env +.reasonix/sessions +.reasonix/projects + # kitty: the light/dark mode is per-machine, and the *-theme.auto.conf files # are generated from it plus .config/kitty/themes. Tracking them would make # every machine flag the others' mode. run_after_kitty-theme-mode.sh diff --git a/dot_claude/CLAUDE.md b/dot_claude/CLAUDE.md new file mode 100644 index 0000000..8740cd1 --- /dev/null +++ b/dot_claude/CLAUDE.md @@ -0,0 +1,16 @@ +# Global Rules + +## Promises need mechanisms +Never promise behavioral changes with just words ("won't forget", "I'll make sure to"). Each conversation starts fresh — words have no effect on future behavior. When committing to a change: +1. Add to CLAUDE.md (always loaded) — not just memory +2. Add automated enforcement where possible (hooks, linters, CI checks) +3. Never say "I won't forget" without having done at least one of the above + +## Watch long-running work yourself; don't trust notifiers +When you launch anything long-running (background workflow, agent swarm, build, deploy, remote/SSH process), do NOT rely on auto-completion notifications — they can silently fail to fire when the job dies. Actively re-check the job's real state (on-disk progress, file mtime, process liveness) on a **≤10-minute cadence**, enforced by a mechanism (a re-arming background watchdog or scheduled self-check), not a promise. Each check: confirm recent progress, detect stalls/silent deaths early, and resume or restart if it died. Prefer resume (cached/idempotent work) over a cold restart. + +## Ask, don't guess +When something fails (SSH, commands, APIs, unexpected errors), report the error and ask the user how to proceed. Don't burn time trying alternative ports, paths, or workarounds — the user knows their system and can quickly point to the right answer. + +## No throwaway implementations +Don't deploy placeholder or half-baked versions that will be replaced later. Either build the real implementation or wait until the design is ready. Deploying throwaway code wastes time and creates false confidence. diff --git a/dot_claude/private_settings.json b/dot_claude/private_settings.json new file mode 100644 index 0000000..5ee4351 --- /dev/null +++ b/dot_claude/private_settings.json @@ -0,0 +1,326 @@ +{ + "cleanupPeriodDays": 36500, + "includeCoAuthoredBy": false, + "permissions": { + "allow": [ + "Bash(tree:*)", + "Bash(wc:*)", + "Bash(head:*)", + "Bash(pdftotext:*)", + "Bash(python3:*)", + "Bash(source .venv/bin/activate)", + "Skill(superpowers:executing-plans)", + "Bash(python validate_data.py:*)", + "Bash(./process_month.sh:*)", + "Bash(bash:*)", + "Bash(ls:*)", + "Bash(python processing-step.py:*)", + "Bash(tr:*)", + "Bash(python3.12:*)", + "Bash(/opt/homebrew/bin/python3:*)", + "Bash(python tbank_process.py:*)", + "Bash(python freedom-pdf-to-csv-converter.py:*)", + "Bash(python xls_to_csv.py:*)", + "Bash(python:*)", + "WebSearch", + "Bash(grep:*)", + "Bash(git add:*)", + "Bash(git commit -m \"$\\(cat <<''EOF''\nImprove data processing pipeline with better parsing and validation\n\n- Fix number format: use dot decimal separator consistently across all processors\n- Fix date formats: standardize to DD.MM.YYYY in source files, YYYY-MM-DD in consolidated\n- Add transaction filtering: exclude internal transfers, currency exchanges, income\n- Parse merchant/location from Freedom, Raiffeisen, Bakai, Yandex descriptions\n- Preserve operation types in comment field \\(no info loss rule\\)\n- Fix Freedom dates: Date column is processing_date, extract transaction_date from Payment_Purpose\n- Upgrade Yandex PDF converter to gemini-3-flash-preview for better OCR\n- Add raiffeisen_process.py for number format normalization\n- Add test-run.md documenting all processing steps and fixes\n\nCo-Authored-By: Claude Opus 4.5 \nEOF\n\\)\")", + "Bash(echo \"=== Checking if unmatched receipts have matching pairs ===\" echo \"\" echo \"Unmatched 2775.0 \\(Dec 4\\):\" grep -l \"2775\" /Users/anton/dev/moneystat/processing/2025-12/receipts/ozon/anton/*.json)", + "Bash(while read f)", + "Bash(do jq '{date: .date, amount: .total_amount, payment: .payment_method}' \"$f\" done echo \"\" echo \"Unmatched 3841.0 \\(Dec 14\\):\" grep -l \"3841\" /Users/anton/dev/moneystat/processing/2025-12/receipts/ozon/anton/*.json)", + "Bash(do jq '{date: .date, amount: .total_amount, payment: .payment_method}' \"$f\" done echo \"\" echo \"Unmatched 972, 1373 \\(Dec 29\\):\" for amt in 972 1373)", + "Bash(do grep -l \"$amt\" /Users/anton/dev/moneystat/processing/2025-12/receipts/ozon/anton/*.json)", + "Bash(do jq '{date: .date, amount: .total_amount, payment: .payment_method}' \"$f\" done done echo \"\" echo \"Unmatched 957 \\(Dec 30\\):\" grep -l \"957\" /Users/anton/dev/moneystat/processing/2025-12/receipts/ozon/anton/*.json)", + "Bash(find:*)", + "Bash(xargs:*)", + "Bash(sort:*)", + "Bash(for f in *.json)", + "Bash(do echo -n \"$f: \")", + "Bash(done)", + "Bash(for f in data/2025-12/receipts/apple/RUB-Anton/*.eml:*)", + "Bash(do)", + "Bash(cat:*)", + "Bash(git commit:*)", + "Bash(pip3 list:*)", + "Bash(echo:*)", + "Bash(source venv/bin/activate)", + "Bash(git push)", + "Bash(for f in \"data/2025-11/receipts/grab/Your Grab E-Receipt 2.eml\" \"data/2025-11/receipts/grab/Your Grab E-Receipt 5.eml\")", + "Bash(for f in data/2025-11/receipts/grab/*.eml)", + "Bash(__NEW_LINE_7bc163cf2bda176a__ echo \"\")", + "Bash(__NEW_LINE_9da33bceca79eb86__ echo \"\")", + "Bash(pip show:*)", + "Bash(uv pip install:*)", + "Bash(do cat \"$f\")", + "Bash(jq:*)", + "Bash(plutil:*)", + "Bash(pip install:*)", + "Bash(.venv/bin/pip install:*)", + "Bash(.venv/bin/python:*)", + "Bash(pdfinfo:*)", + "Bash(__NEW_LINE_4acfd7b3af874ff7__ echo \"\")", + "Bash(# Check final consolidated file for duplicates wc -l processing/2025-11/*.csv)", + "Bash(# Check for TBank duplicates in consolidated file grep -c \"\"tbank\"\" processing/2025-11/consolidated.csv || echo \"\"No tbank found\"\" # Check unique vs total TBank rows echo \"\"=== TBank rows in consolidated ===\"\" grep \"\"tbank\"\" processing/2025-11/consolidated.csv)", + "Bash(__NEW_LINE_49e63631a274ada1__ echo \"=== Unique TBank rows \\(by date+amount+description\\) ===\")", + "Bash(# Check December for similar issues ls -la processing/2025-12/tbank* || echo \"\"No tbank files in December\"\" echo \"\"\"\" echo \"\"=== TBank rows in December consolidated ===\"\" grep -c \"\"tbank\"\" processing/2025-12/consolidated.csv || echo \"\"No consolidated.csv\"\" echo \"\"\"\" echo \"\"=== Unique TBank rows in December ===\"\" grep \"\"tbank\"\" processing/2025-12/consolidated.csv)", + "Bash(# Check for duplicates by source in consolidated file echo \"\"=== November 2025 ===\"\" echo \"\"Raiffeisen rows:\"\" grep -c \"\"raiffeisen\"\" processing/2025-11/consolidated.csv || echo \"\"0\"\" echo \"\"Freedom rows:\"\" grep -c \"\"freedom\"\" processing/2025-11/consolidated.csv || echo \"\"0\"\" echo \"\"\"\" echo \"\"=== All processed files in November ===\"\" ls -la processing/2025-11/*.processed.csv)", + "Bash(cd /Users/anton/dev/moneystat echo \"=== Source files in data/2025-12 ===\" find data/2025-12 -name \"*.csv\" -o -name \"*.pdf\")", + "Bash(__NEW_LINE_8b3f2148807d3dea__ echo \"\")", + "Bash(__NEW_LINE_d3565e1917fc1e0c__ echo \"=== data/2025-12 structure ===\")", + "Bash(__NEW_LINE_d3565e1917fc1e0c__ echo \"\")", + "Bash(__NEW_LINE_b4a495b4f804ce33__ echo \"=== Freedom source files ===\")", + "Bash(__NEW_LINE_b4a495b4f804ce33__ echo \"\")", + "Bash(__NEW_LINE_9b873e71c557a635__ echo \"=== December 2025: Source files vs Consolidated ===\")", + "Bash(__NEW_LINE_9b873e71c557a635__ echo \"\")", + "Bash(__NEW_LINE_a6dec1f39c81c8c3__ echo \"=== Freedom USD current file ===\")", + "Bash(__NEW_LINE_a6dec1f39c81c8c3__ echo \"\")", + "Bash(__NEW_LINE_8cb166f3ad9c1f18__ python3 -c \"\nimport pandas as pd\nf = ''processing/2025-12/freedom-legal_statement_2025-12-01_2025-12-31_current_1769192100-usd.processed.csv''\ndf = pd.read_csv\\(f\\)\nprint\\(f''Actual records: {len\\(df\\)}''\\)\nprint\\(f''Columns: {list\\(df.columns\\)}''\\)\n\")", + "Bash(cd /Users/anton/dev/moneystat:*)", + "Bash(__NEW_LINE_52b89477ddfdbf8d__ python3 -c \"\nimport pandas as pd\n\n# Check total sum in consolidated\ndf = pd.read_csv\\(''processing/2025-12/consolidated.csv''\\)\nprint\\(f''Total records: {len\\(df\\)}''\\)\nprint\\(f''Total RUB amount: {df[\"\"amount_rub\"\"].sum\\(\\):,.2f}''\\)\n\n# By source\nfor source in df[''info_source''].unique\\(\\):\n subset = df[df[''info_source''] == source]\n print\\(f'' {source}: {len\\(subset\\)} records, {subset[\"\"amount_rub\"\"].sum\\(\\):,.2f} RUB''\\)\n\")", + "Bash(__NEW_LINE_3ae1f017591cfd98__ echo \"\")", + "Bash(__NEW_LINE_60ad38285f384d62__ python3 -c \"\nimport pandas as pd\n\n# Test auto-detect\nf = ''processing/2025-12/ozon-Волнухин_А_Ю_о_движении_денежных_средств_ozonbank_document_23316120.processed.csv''\n\n# Check first line\nwith open\\(f, ''r''\\) as file:\n first_line = file.readline\\(\\)\n print\\(''First line:'', repr\\(first_line\\)\\)\n print\\(''Has semicolon:'', '';'' in first_line\\)\n print\\(''Has comma:'', '','' in first_line\\)\n\n# Read with comma\ndf = pd.read_csv\\(f, delimiter='','', encoding=''utf-8-sig''\\)\nprint\\(\\)\nprint\\(''Columns:'', list\\(df.columns\\)\\)\nprint\\(''Rows:'', len\\(df\\)\\)\nprint\\(\\)\nprint\\(''Sample:''\\)\nprint\\(df.head\\(2\\)\\)\n\")", + "Bash(__NEW_LINE_c3c45e4fba8a30f6__ python3 -c \"\n# Simulate what consolidating-step does for is_internal_transaction\ntext = ''Выдача кредита по договору №2025-06-30-KK- 04581056279272189866, Волнухин Антон Юрьевич''\nsource = ''ozon''\n\ncombined_text = text.lower\\(\\)\nprint\\(''combined_text:'', combined_text\\)\nprint\\(\\)\nprint\\(''Check: выдача кредита in combined_text?'', ''выдача кредита'' in combined_text\\)\nprint\\(''source:'', source\\)\nprint\\(''source != ozon?'', source != ''ozon''\\)\n\")", + "Bash(__NEW_LINE_051a249934ae9d8e__ python consolidating-step.py processing/2025-12)", + "Bash(__NEW_LINE_a5635cd054e2af5d__ python consolidating-step.py processing/2025-12)", + "Bash(__NEW_LINE_be0bb1dd57b96096__ python consolidating-step.py processing/2025-12)", + "Bash(do python -c \"import json; d=json.load\\(open\\(''$f''\\)\\); items=[i for i in d.get\\(''items'',[]\\) if ''Auto Reload'' not in i.get\\(''name'',''''\\)]; print\\(f\"\"{d.get\\(''order_date''\\)}: {sum\\(i[''price''] for i in items\\)} RUB\"\"\\)\")", + "Bash(do rm -v \"$f\")", + "WebFetch(domain:discuss.ai.google.dev)", + "Bash(awk:*)", + "Bash(file:*)", + "Bash(git rm:*)", + "Bash(__NEW_LINE_c0ebfadfa2d82e8e__ echo -e \"\\\\n=== TT NET ===\")", + "Bash(__NEW_LINE_d9661d77cbc2b8df__ echo -e \"\\\\n=== Осетинский интернет ===\")", + "Bash(__NEW_LINE_eb27aace61ca558d__ echo -e \"\\\\n=== Steam ===\")", + "Bash(__NEW_LINE_b138d527c99ac4d4__ echo -e \"\\\\n=== MOFT/Elago/чехол ===\")", + "Bash(curl:*)", + "WebFetch(domain:ai.google.dev)", + "WebFetch(domain:colab.research.google.com)", + "Bash(for script in consolidated-process-ozon.py consolidated-process-samokat.py consolidated-process-vkusvill.py consolidated-process-amazon.py consolidated-process-aliexpress.py consolidated-process-apple-usd.py consolidated-process-steam.py consolidated-process-grab.py)", + "Bash(for amount in 16.33 49 1565 987 400 3262 1471)", + "Bash(perl:*)", + "Bash(cut:*)", + "Bash(git restore:*)", + "Bash(chmod:*)", + "Bash(shasum:*)", + "Bash(# Check if there are any Ozon PDFs to test with ls data/2025-09/receipts/ozon/*/*.pdf)", + "Bash(__NEW_LINE_c3e7f2c4c5b0eb5a__ echo \"\")", + "Bash(shuf:*)", + "Bash(# Check how many files remain ls processing/2025-09/altcats/*.json)", + "Bash(do rm \"$f\")", + "Bash(LLM_DEBUG=1 python run-pipeline.py:*)", + "Bash(LLM_DEBUG=1 python src/stages/stage_3_categories.py:*)", + "Bash(git reset:*)", + "Bash(uv pip:*)", + "Bash(pkill:*)", + "Bash(for i in 1 2 3 4 5)", + "Bash(do sleep 5)", + "Bash(for month in 2025-06 2025-07 2025-09 2025-10 2025-11 2025-12)", + "Bash(# Check for any 2024 dates in cached Lavka JSONs grep -r \"\"2024\"\" /Users/anton/dev/moneystat/processing/2026-01/receipts/yandex/*Lavka*/*.json)", + "Bash(for month in 2025-08 2025-09 2025-10 2025-11 2025-12 2026-01)", + "Bash(git -C /Users/anton/dev/moneystat status)", + "Bash(git -C /Users/anton/dev/moneystat diff)", + "Bash(git -C /Users/anton/dev/moneystat log --oneline -5)", + "Bash(git -C /Users/anton/dev/moneystat log --oneline -3)", + "Bash(git -C /Users/anton/dev/moneystat diff src/parsers/parse_yandex_taxi.py)", + "Bash(git -C /Users/anton/dev/moneystat add src/parsers/parse_yandex_taxi.py)", + "Bash(git -C /Users/anton/dev/moneystat commit -m \"$\\(cat <<''EOF''\nCache downloaded Yandex Taxi invoices\n\nInvoice HTML files are now cached in .invoice_cache directory to avoid\nre-downloading on each pipeline run. Uses the unique invoice URL hash\nas cache key. Reduces parse time from ~7s to ~0.3s for cached invoices.\n\nCo-Authored-By: Claude Opus 4.5 \nEOF\n\\)\")", + "Bash(git -C /Users/anton/dev/moneystat diff src/processors/consolidated_process_samokat.py)", + "Bash(git -C /Users/anton/dev/moneystat add src/processors/consolidated_process_samokat.py)", + "Bash(git -C /Users/anton/dev/moneystat commit -m \"$\\(cat <<''EOF''\nFix: Exclude Ozon transactions from Samokat matching\n\nOzon sellers named \"Самокат Плюс, ООО\" were incorrectly identified as\nSamokat grocery delivery. Now transactions already matched to Ozon\n\\(info_source contains ''ozon''\\) are excluded from Samokat matching.\n\nCo-Authored-By: Claude Opus 4.5 \nEOF\n\\)\")", + "Bash(for parser in parse_ozon parse_yandex parse_grab parse_samokat parse_vkusvill parse_apple parse_amazon parse_aliexpress parse_steam)", + "Bash(for parser in parse_yandex_eda parse_yandex_taxi parse_lavka)", + "Bash(__NEW_LINE_7b4f4fc6eb9d9e49__ echo \"\")", + "Bash(__NEW_LINE_3b4b538c51270f95__ echo \"\")", + "Bash(__NEW_LINE_6f837450c2794e10__ echo \"\")", + "Bash(__NEW_LINE_cdd8a54243e075d5__ echo \"\")", + "Bash(git check-ignore:*)", + "Bash(node:*)", + "Bash(python /tmp/test_month_nav.py:*)", + "Bash(uv run:*)", + "Bash(git commit -m \"$\\(cat <<''EOF''\nAdd visual month navigator with mini donut chart previews\n\nReplace dropdown selector with a visual navigator featuring:\n- Left/right arrow buttons for month navigation\n- Clickable month buttons with mini donut chart previews\n- Russian month labels \\(e.g., \"Январь '25\"\\)\n- Responsive layout for mobile screens\n- Arrows disable at navigation boundaries\n\nCo-Authored-By: Claude Opus 4.5 \nEOF\n\\)\")", + "Skill(commit-commands:commit)", + "mcp__plugin_playwright_playwright__browser_navigate", + "mcp__plugin_playwright_playwright__browser_take_screenshot", + "mcp__plugin_playwright_playwright__browser_run_code", + "mcp__plugin_playwright_playwright__browser_snapshot", + "mcp__plugin_playwright_playwright__browser_click", + "mcp__plugin_playwright_playwright__browser_press_key", + "mcp__plugin_playwright_playwright__browser_close", + "mcp__plugin_playwright_playwright__browser_console_messages", + "mcp__plugin_playwright_playwright__browser_evaluate", + "WebFetch(domain:github.com)", + "mcp__plugin_playwright_playwright__browser_wait_for", + "mcp__plugin_playwright_playwright__browser_navigate_back", + "Bash(lsof:*)", + "mcp__plugin_playwright_playwright__browser_resize", + "mcp__plugin_playwright_playwright__browser_hover", + "Bash(git checkout:*)", + "mcp__plugin_playwright_playwright__browser_tabs", + "Bash(DATA_DIR=. node -e:*)", + "Bash(git merge:*)", + "Bash(git status:*)", + "Bash(xcrun simctl:*)", + "Bash(open:*)", + "Bash(osascript:*)", + "mcp__home-assistant__ha_get_overview", + "mcp__home-assistant__ha_search_entities", + "mcp__home-assistant__ha_config_list_areas", + "mcp__home-assistant__ha_config_list_floors", + "mcp__home-assistant__ha_config_list_groups", + "mcp__home-assistant__ha_get_integration", + "mcp__home-assistant__ha_config_get_automation", + "mcp__home-assistant__ha_config_get_script", + "Bash(ssh:*)", + "Bash(scp:*)", + "mcp__home-assistant__ha_config_get_dashboard", + "mcp__home-assistant__ha_get_state", + "mcp__home-assistant__ha_get_entity", + "mcp__home-assistant__ha_config_list_helpers", + "WebFetch(domain:thesmarthomejourney.com)", + "WebFetch(domain:community.home-assistant.io)", + "WebFetch(domain:magicareas.io)", + "WebFetch(domain:danielbkr.net)", + "WebFetch(domain:newerest.space)", + "WebFetch(domain:www.aaron-powell.com)", + "WebFetch(domain:mikesolin.com)", + "WebFetch(domain:www.dima.pm)", + "WebFetch(domain:joshdotai.medium.com)", + "WebFetch(domain:blog.abodit.com)", + "WebFetch(domain:www.derekseaman.com)", + "WebFetch(domain:blog.shalvah.me)", + "mcp__home-assistant__ha_deep_search" + ], + "defaultMode": "auto" + }, + "hooks": { + "Notification": [ + { + "hooks": [ + { + "type": "command", + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/claude-event-hook.sh' Waiting # notchbar-agents-claude-hook" + } + ] + } + ], + "PostToolUse": [ + { + "hooks": [ + { + "type": "command", + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/claude-event-hook.sh' Auto # notchbar-agents-claude-hook" + } + ] + } + ], + "PostToolUseFailure": [ + { + "hooks": [ + { + "type": "command", + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/claude-event-hook.sh' ToolFail # notchbar-agents-claude-hook" + } + ] + } + ], + "PreToolUse": [ + { + "hooks": [ + { + "type": "command", + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/claude-event-hook.sh' Working # notchbar-agents-claude-hook" + } + ] + } + ], + "SessionEnd": [ + { + "hooks": [ + { + "type": "command", + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/claude-event-hook.sh' Ended # notchbar-agents-claude-hook" + } + ] + } + ], + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/claude-event-hook.sh' Idle # notchbar-agents-claude-hook" + } + ] + }, + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "bash '/Users/anton/.claude/hooks/herdr-agent-state.sh' session", + "timeout": 10 + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/claude-event-hook.sh' Idle # notchbar-agents-claude-hook" + } + ] + } + ], + "UserPromptSubmit": [ + { + "hooks": [ + { + "type": "command", + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/claude-event-hook.sh' Working # notchbar-agents-claude-hook" + } + ] + } + ] + }, + "statusLine": { + "type": "command", + "command": "bash ~/.claude/statusline-command.sh" + }, + "enabledPlugins": { + "clangd-lsp@claude-plugins-official": true, + "codex@openai-codex": true, + "commit-commands@claude-code-plugins": true, + "document-skills@anthropic-agent-skills": true, + "frontend-design@claude-plugins-official": true, + "github@claude-plugins-official": true, + "gopls-lsp@claude-plugins-official": false, + "playwright@claude-plugins-official": true, + "rust-analyzer-lsp@claude-plugins-official": true, + "superpowers@claude-plugins-official": true, + "superpowers@superpowers-marketplace": true + }, + "extraKnownMarketplaces": { + "openai-codex": { + "source": { + "source": "github", + "repo": "openai/codex-plugin-cc" + } + } + }, + "effortLevel": "xhigh", + "tui": "fullscreen", + "autoMemoryEnabled": true, + "autoDreamEnabled": true, + "skipDangerousModePermissionPrompt": true, + "skipWorkflowUsageWarning": true, + "theme": "auto", + "verbose": true, + "preferredNotifChannel": "ghostty", + "remoteControlAtStartup": false, + "agentPushNotifEnabled": true, + "skipAutoPermissionPrompt": true +} diff --git a/dot_claude/statusline-command.sh b/dot_claude/statusline-command.sh new file mode 100644 index 0000000..df07655 --- /dev/null +++ b/dot_claude/statusline-command.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# Claude Code status line — inspired by Powerlevel10k/Tide layout +# Segments: user@host cwd git branch model context % + +input=$(cat) + +cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // ""') +model=$(echo "$input" | jq -r '.model.display_name // ""') +used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty') + +# --- user@host --- +user=$(whoami) +host=$(hostname -s) + +# --- pretty cwd: replace $HOME with ~ --- +home="$HOME" +short_cwd="${cwd/#$home/\~}" + +# --- git branch (skip optional locks) --- +git_branch="" +if git_out=$(git -C "$cwd" --no-optional-locks symbolic-ref --short HEAD 2>/dev/null); then + git_branch="$git_out" +elif git_out=$(git -C "$cwd" --no-optional-locks rev-parse --short HEAD 2>/dev/null); then + git_branch="$git_out" +fi + +# --- context bar --- +context_str="" +if [ -n "$used_pct" ]; then + used_int=${used_pct%.*} + if [ "${used_int:-0}" -ge 80 ]; then + ctx_color="\033[31m" # red + elif [ "${used_int:-0}" -ge 50 ]; then + ctx_color="\033[33m" # yellow + else + ctx_color="\033[32m" # green + fi + context_str=" ${ctx_color}ctx:${used_pct%.*}%\033[0m" +fi + +# --- assemble --- +# user@host in cyan, cwd in bold, git branch in magenta, model in dim +printf "\033[36m%s@%s\033[0m \033[1m%s\033[0m" "$user" "$host" "$short_cwd" +if [ -n "$git_branch" ]; then + printf " \033[35m\ue0a0 %s\033[0m" "$git_branch" +fi +if [ -n "$model" ]; then + printf " \033[2m%s\033[0m" "$model" +fi +if [ -n "$context_str" ]; then + printf "%b" "$context_str" +fi diff --git a/dot_codex/github-mcp-env.zsh b/dot_codex/github-mcp-env.zsh new file mode 100644 index 0000000..a3891a7 --- /dev/null +++ b/dot_codex/github-mcp-env.zsh @@ -0,0 +1,21 @@ +# Populate GitHub MCP auth for Codex from a GitHub personal access token. +# The token value is exported into the process environment but is not stored here. +case "${CODEX_GITHUB_PERSONAL_ACCESS_TOKEN:-}" in + github_pat_*|ghp_*) ;; + *) + unset CODEX_GITHUB_PERSONAL_ACCESS_TOKEN + if command -v security >/dev/null 2>&1; then + _codex_github_token="$(security find-generic-password -a "$USER" -s codex-github-mcp-pat -w 2>/dev/null || true)" + else + _codex_github_token="" + fi + + case "$_codex_github_token" in + github_pat_*|ghp_*) + export CODEX_GITHUB_PERSONAL_ACCESS_TOKEN="$_codex_github_token" + ;; + esac + + unset _codex_github_token + ;; +esac diff --git a/dot_codex/hooks.json b/dot_codex/hooks.json new file mode 100644 index 0000000..195fbd6 --- /dev/null +++ b/dot_codex/hooks.json @@ -0,0 +1,76 @@ +{ + "hooks": { + "PostToolUse": [ + { + "hooks": [ + { + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/codex-notify-hook.sh' # notchbar-agents-codex-hook", + "type": "command" + } + ], + "matcher": "Bash" + } + ], + "PreToolUse": [ + { + "hooks": [ + { + "command": "'/Users/anton/.codex/hooks/confirm-destructive.sh'", + "timeout": 5, + "type": "command" + } + ], + "matcher": "Bash" + }, + { + "hooks": [ + { + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/codex-notify-hook.sh' # notchbar-agents-codex-hook", + "type": "command" + } + ], + "matcher": "Bash" + } + ], + "SessionStart": [ + { + "hooks": [ + { + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/codex-notify-hook.sh' # notchbar-agents-codex-hook", + "type": "command" + } + ], + "matcher": "startup|resume" + }, + { + "hooks": [ + { + "command": "bash '/Users/anton/.codex/herdr-agent-state.sh' session", + "timeout": 10, + "type": "command" + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/codex-notify-hook.sh' # notchbar-agents-codex-hook", + "type": "command" + } + ] + } + ], + "UserPromptSubmit": [ + { + "hooks": [ + { + "command": "'/Users/anton/Library/Application Support/Bartender/NotchBar/AgentStatus/hooks/codex-notify-hook.sh' # notchbar-agents-codex-hook", + "type": "command" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/dot_codex/keybindings.json b/dot_codex/keybindings.json new file mode 100644 index 0000000..ab1d454 --- /dev/null +++ b/dot_codex/keybindings.json @@ -0,0 +1,6 @@ +[ + { + "command": "hotkeyWindow", + "key": "Alt+Space" + } +] diff --git a/dot_codex/private_config.toml b/dot_codex/private_config.toml new file mode 100644 index 0000000..c17812f --- /dev/null +++ b/dot_codex/private_config.toml @@ -0,0 +1,437 @@ +model = "gpt-5.6-sol" +model_reasoning_effort = "high" +personality = "pragmatic" +plan_mode_reasoning_effort = "xhigh" +sandbox_mode = "workspace-write" +service_tier = "priority" + + +notify = ["/Users/anton/.codex/computer-use/Codex Computer Use.app/Contents/SharedSupport/SkyComputerUseClient.app/Contents/MacOS/SkyComputerUseClient", "turn-ended"] + +[features] +hooks = true +apps = true +multi_agent = true +prevent_idle_sleep = true +memories = true +js_repl = false + +[marketplaces.openai-bundled] +last_updated = "2026-07-28T17:16:25Z" +source_type = "local" +source = "/Users/anton/.codex/.tmp/bundled-marketplaces/openai-bundled" + +[marketplaces.openai-primary-runtime] +last_updated = "2026-07-16T08:15:09Z" +source_type = "local" +source = "/Users/anton/.cache/codex-runtimes/codex-primary-runtime/plugins/openai-primary-runtime" + +[marketplaces.claude-plugins-official] +last_updated = "2026-08-05T22:59:06Z" +last_revision = "0ad65e5d170c501235183be69c4e4be30a5f81d8" +source_type = "git" +source = "https://github.com/anthropics/claude-plugins-official.git" + +[marketplaces.openai-codex] +last_updated = "2026-07-08T07:57:58Z" +last_revision = "db52e28f4d9ded852ab3942cea316258ae4ef346" +source_type = "git" +source = "https://github.com/openai/codex-plugin-cc.git" + +[mcp_servers.agent-team-wiki] +url = "https://wiki.agent-team.ru/mcp" + +[mcp_servers.codex-cli] +command = "npx" +args = ["-y", "codex-mcp-server"] + +[mcp_servers.excalidraw] +url = "https://excalidraw-mcp-app.vercel.app/mcp" + +[mcp_servers.glm] +command = "/Users/anton/.codex/mcp-with-secrets.sh" +args = ["node", "/Users/anton/dev/glm/scripts/glm-mcp.mjs"] +startup_timeout_sec = 15.0 +tool_timeout_sec = 1200.0 + +[mcp_servers.glm.env] + +[mcp_servers.glm.tools.glm_consult] +approval_mode = "approve" + +[mcp_servers.glm.tools.glm_freeform] +approval_mode = "approve" + +[mcp_servers.glm.tools.glm_review] +approval_mode = "approve" + +[mcp_servers.multipoly] +command = "/Users/anton/.codex/mcp-with-secrets.sh" +args = ["node", "/Users/anton/dev/multipoly/scripts/multipoly-mcp.mjs"] +startup_timeout_sec = 15.0 +tool_timeout_sec = 600.0 + +[mcp_servers.multipoly.env] +MULTIPOLY_AGY_CLI_KIND = "agy" +MULTIPOLY_AGY_ENABLED = "1" +MULTIPOLY_AGY_TRANSPORT = "cli" +MULTIPOLY_AGY_UNSAFE = "1" +MULTIPOLY_CLAUDE_CLI_KIND = "claude" +MULTIPOLY_CLAUDE_ENABLED = "1" +MULTIPOLY_CLAUDE_MODEL = "claude-opus-4-7" +MULTIPOLY_CLAUDE_TRANSPORT = "cli" +MULTIPOLY_CODEX_CLI_KIND = "codex" +MULTIPOLY_CODEX_ENABLED = "1" +MULTIPOLY_CODEX_MODEL = "gpt-5.5" +MULTIPOLY_CODEX_TRANSPORT = "cli" +MULTIPOLY_COMPOSER_ENABLED = "1" +MULTIPOLY_DEEPSEEK_BASE_URL = "https://api.deepseek.com" +MULTIPOLY_FABLE_CLI_KIND = "claude" +MULTIPOLY_FABLE_ENABLED = "1" +MULTIPOLY_FABLE_MODEL = "claude-fable-5" +MULTIPOLY_FABLE_TRANSPORT = "cli" +MULTIPOLY_GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai" +MULTIPOLY_GEMINI_MODEL = "gemini-3.5-flash" +MULTIPOLY_GEMINI_TRANSPORT = "http" +MULTIPOLY_GLM_MAX_TOKENS_REVIEW = "8192" +MULTIPOLY_GROK_CLI_KIND = "grok" +MULTIPOLY_GROK_ENABLED = "1" +MULTIPOLY_GROK_MODEL = "grok-4.5" +MULTIPOLY_GROK_TRANSPORT = "cli" +MULTIPOLY_KIMI_BASE_URL = "https://api.kimi.com/coding" +MULTIPOLY_KIMI_MAX_TOKENS_CONSULT = "65536" +MULTIPOLY_KIMI_MODEL = "kimi-k.3.0" +MULTIPOLY_KIMI_REASONING = "kimi_toggle" +MULTIPOLY_KIMI_TRANSPORT = "anthropic" +MULTIPOLY_MIMO_BASE_URL = "https://token-plan-sgp.xiaomimimo.com/v1" +MULTIPOLY_MIMO_MAX_TOKENS_REVIEW = "8192" +MULTIPOLY_MIMO_MODEL = "mimo-v2.5-pro" +MULTIPOLY_MIMO_TRANSPORT = "http" +MULTIPOLY_MODELS = "kimi,gemini,claude,codex,agy,mimo,grok,fable" +MULTIPOLY_QWEN_BASE_URL = "https://ws-duxbs2mi0ocqxzxp.eu-central-1.maas.aliyuncs.com/compatible-mode/v1" +MULTIPOLY_QWEN_MODEL = "qwen3.7-max" +MULTIPOLY_TIMEOUT_MS = "3600000" + +[mcp_servers.github] +url = "https://api.githubcopilot.com/mcp/" +bearer_token_env_var = "CODEX_GITHUB_PERSONAL_ACCESS_TOKEN" + +[mcp_servers.ha-mcp] +url = "http://192.168.39.90:8086/mcp" + +[mcp_servers.home-assistant] +command = "/Users/anton/.codex/mcp-with-secrets.sh" +args = ["uvx", "ha-mcp@latest"] + +[mcp_servers.home-assistant.env] +HOMEASSISTANT_URL = "http://192.168.39.50" + +[mcp_servers.playwright] +command = "npx" +args = ["@playwright/mcp@latest"] + +[mcp_servers.playwright.tools.browser_run_code] +approval_mode = "approve" + +[mcp_servers.playwright.tools.browser_tabs] +approval_mode = "approve" + +[mcp_servers.node_repl] +args = [] +command = "/Applications/Codex.app/Contents/Resources/cua_node/bin/node_repl" +startup_timeout_sec = 120 + +[mcp_servers.node_repl.env] +NODE_REPL_NATIVE_PIPE_CONNECT_TIMEOUT_MS = "1000" +NODE_REPL_NODE_MODULE_DIRS = "/Applications/Codex.app/Contents/Resources/cua_node/lib/node_modules" +NODE_REPL_NODE_PATH = "/Applications/Codex.app/Contents/Resources/cua_node/bin/node" +NODE_REPL_TRUSTED_CODE_PATHS = "/Users/anton/.codex" +CODEX_HOME = "/Users/anton/.codex" +NODE_REPL_TRUSTED_BROWSER_CLIENT_SHA256S = "583bf903a6cfb9b00a01e1583381ce921c71d7585085c6fa6b805baa0f60230b,6d25aa7656feac858f3a3bdaea5bcbab0dbfd426c9de8e6931ce90c399ee8e4f" +BROWSER_USE_AVAILABLE_BACKENDS = "chrome,iab" +NODE_REPL_INSTRUCTIONS_USE_CASE_BROWSER = "Control the in-app browser in conjunction with the Browser Plugin." +NODE_REPL_INSTRUCTIONS_USE_CASE_CHROME = "Control the Chrome browser in conjunction with the Chrome Plugin. Prefer this method of controlling Chrome over alternatives (such as Computer Use) unless the user explicitly mentions an alternative." +NODE_REPL_INSTRUCTIONS_USE_CASE_COMPUTER_USE = "Control desktop apps on macOS through Computer Use." +BROWSER_USE_CODEX_APP_BUILD_FLAVOR = "prod" +BROWSER_USE_CODEX_APP_VERSION = "26.715.52143" +SKY_CUA_SERVICE_PATH = "/Users/anton/.codex/plugins/cache/openai-bundled/computer-use/1.0.1000451/Codex Computer Use.app" +CODEX_CLI_PATH = "/Applications/Codex.app/Contents/Resources/codex" + +[mcp_servers.hallucination-detector] +command = "/Users/anton/.codex/mcp-with-secrets.sh" + +args = ["hallucination-detector-mcp"] +[mcp_servers.hallucination-detector.env] + +[mcp_servers.flint] +command = "npx" +args = ["-y", "flint-chart-mcp"] + +[mcp_servers.computer-use] +command = "./Codex Computer Use.app/Contents/SharedSupport/SkyComputerUseClient.app/Contents/MacOS/SkyComputerUseClient" +args = ["mcp"] +cwd = "." +enabled = false + +[mcp_servers.openaiDeveloperDocs] +url = "https://developers.openai.com/mcp" + +[notice] +hide_rate_limit_model_nudge = true + +[notice.model_migrations] +"gpt-5.2-codex" = "gpt-5.4" + +[plugins."canva@openai-curated"] +enabled = true + +[plugins."documents@openai-primary-runtime"] +enabled = true + +[plugins."github@openai-curated"] +enabled = true + +[plugins."presentations@openai-primary-runtime"] +enabled = true + +[plugins."spreadsheets@openai-primary-runtime"] +enabled = true + +[plugins."frontend-design@claude-plugins-official"] +enabled = true + +[plugins."github@claude-plugins-official"] +enabled = true + +[plugins."playwright@claude-plugins-official"] +enabled = true + +[plugins."superpowers@claude-plugins-official"] +enabled = true + +[plugins."codex@openai-codex"] +enabled = true + +[plugins."pdf@openai-primary-runtime"] +enabled = true + +[plugins."clangd-lsp@claude-plugins-official"] +enabled = true + +[plugins."rust-analyzer-lsp@claude-plugins-official"] +enabled = true + +[plugins."template-creator@openai-primary-runtime"] +enabled = true + +[plugins."computer-use@openai-bundled"] +enabled = true + +[plugins."chrome@openai-bundled"] +enabled = true + +[plugins."visualize@openai-bundled"] +enabled = true + +[plugins."sites@openai-bundled"] +enabled = true + +[plugins."browser@openai-bundled"] +enabled = true + +[projects."/"] +trust_level = "trusted" + +[projects."/Users/anton"] +trust_level = "trusted" + +[projects."/Users/anton/.local/share/chezmoi"] +trust_level = "trusted" + +[projects."/Users/anton/dev/aictrl"] +trust_level = "trusted" + +[projects."/Users/anton/dev/aictrl-upstreamm"] +trust_level = "trusted" + +[projects."/Users/anton/dev/claude-sync"] +trust_level = "trusted" + +[projects."/Users/anton/dev/codex-switcher"] +trust_level = "trusted" + +[projects."/Users/anton/dev/ha-assistant"] +trust_level = "trusted" + +[projects."/Users/anton/dev/kitty"] +trust_level = "trusted" + +[projects."/Users/anton/dev/metaai"] +trust_level = "trusted" + +[projects."/Users/anton/dev/moneystat"] +trust_level = "untrusted" + +[projects."/Users/anton/dev/mosh"] +trust_level = "trusted" + +[projects."/Users/anton/dev/summarizer"] +trust_level = "trusted" + +[projects."/Users/anton/dev/translate-podcast"] +trust_level = "trusted" + +[projects."/Users/anton/dev/vless"] +trust_level = "trusted" + +[projects."/Users/anton/prj/aictrl"] +trust_level = "trusted" + +[projects."/Users/anton/prj/papers"] +trust_level = "trusted" + +[projects."/Users/anton/prj/tagir-talk"] +trust_level = "trusted" + +[projects."/Users/anton/dev/r7-project"] +trust_level = "trusted" + +[projects."/Users/anton/dev/glm"] +trust_level = "trusted" + +[projects."/Users/anton/dev/mikrotik"] +trust_level = "trusted" + +[projects."/Users/anton/dev/page-summarizer"] +trust_level = "trusted" + +[projects."/Users/anton/dev/ipranges"] +trust_level = "trusted" + +[projects."/Users/anton/dev/multipoly"] +trust_level = "trusted" + +[projects."/Users/anton/dev/librestat"] +trust_level = "trusted" + +[sandbox_workspace_write] +network_access = true + +[tui] +status_line = [ + "model-with-reasoning", + "context-remaining", + "current-dir", + "model-name", + "project-root", + "git-branch", + "context-used", + "five-hour-limit", +] + +[tui.model_availability_nux] +"gpt-5.5" = 4 +"gpt-5.6-sol" = 4 + +[memories] +generate_memories = true +use_memories = true + +[hooks.state] + +[hooks.state."/Users/anton/.codex/hooks.json:pre_tool_use:0:0"] +enabled = true +trusted_hash = "sha256:b61eb845f14a50e8e24c5435f84cb7b62cea9549c0acebe0c037a2ad94260f02" + +[hooks.state."codex@openai-codex:hooks/hooks.json:session_start:0:0"] +trusted_hash = "sha256:e6b9df143de11443eb576c38874cf6e0c48358f948170948fdf630f1c047c098" + +[hooks.state."codex@openai-codex:hooks/hooks.json:stop:0:0"] +trusted_hash = "sha256:3dfaa7e4f022570b260b8a8cf4ac7585c986175256b887a4723fac4f358a482f" + +[hooks.state."superpowers@claude-plugins-official:hooks/hooks.json:session_start:0:0"] +enabled = false +trusted_hash = "sha256:62acbaff2b2f55f41971e21a164990aaa53c96919baa0a5eae2eb5db73b9e6e6" + +[hooks.state."/Users/anton/.codex/hooks.json:pre_tool_use:1:0"] +trusted_hash = "sha256:bac831afc7106356964ac55df1e35367ef956e914a282cb645284ad23e648c57" + +[hooks.state."/Users/anton/.codex/hooks.json:post_tool_use:0:0"] +trusted_hash = "sha256:f8b3aaf328b64e79eb5f0759d6bf2f4ac1136c24cf67a8887bb92f2bb63c26a4" + +[hooks.state."/Users/anton/.codex/hooks.json:session_start:0:0"] +trusted_hash = "sha256:07a21ec47290f101a3b4e457df0b2a81ff7e5080f5a40e681b8514b8317f2214" + +[hooks.state."/Users/anton/.codex/hooks.json:user_prompt_submit:0:0"] +trusted_hash = "sha256:a7bc3022efbd14a0b526e36d875aeb601cf0b0ed736a6b6d539ecaeb242194d8" + +[hooks.state."/Users/anton/.codex/hooks.json:stop:0:0"] +trusted_hash = "sha256:a654fceae87e9d7f8d679bdd93eb083ab200c5d91bc699d71b5ef7b5a3c71f47" + +[hooks.state."superpowers@claude-plugins-official:hooks/hooks-codex.json:session_start:0:0"] +enabled = false +trusted_hash = "sha256:687e7af87f0cb59b1bcc71d368e097304b45d84999c90dc97358a22811691a3f" + +[hooks.state."/Users/anton/.codex/hooks.json:session_start:1:0"] +trusted_hash = "sha256:0094ae0b175bc5ea2874124bf4140ab0e2c00c8b6ea37980ede20d1e13418b19" + +[hooks.state."codex@openai-codex:hooks/hooks.json:session_end:0:0"] +trusted_hash = "sha256:bc55a03ac0094c5deb4af95c405b75b34735f318b3d9bd64a2f9902973861606" + +[desktop] +appearanceTheme = "system" +appearanceLightCodeThemeId = "codex" +appearanceDarkCodeThemeId = "gruvbox" +sansFontSize = 15 +codeFontSize = 14 +usePointerCursors = false +followUpQueueMode = "steer" +preventSleepWhileRunning = false +keepRemoteControlAwakeWhilePluggedIn = true +conversationDetailMode = "STEPS_COMMANDS" +mac-menu-bar-enabled = false +dock-icon-preference = "codex-system" + +[desktop.appearanceLightChromeTheme] +accent = "#0169cc" +contrast = 45 +ink = "#0d0d0d" +opaqueWindows = true +surface = "#ffffff" + +[desktop.appearanceLightChromeTheme.fonts] + +[desktop.appearanceLightChromeTheme.semanticColors] +diffAdded = "#00a240" +diffRemoved = "#e02e2a" +skill = "#751ed9" + +[desktop.appearanceDarkChromeTheme] +accent = "#458588" +contrast = 60 +ink = "#ebdbb2" +opaqueWindows = false +surface = "#282828" + +[desktop.appearanceDarkChromeTheme.fonts] + +[desktop.appearanceDarkChromeTheme.semanticColors] +diffAdded = "#ebdbb2" +diffRemoved = "#cc241d" +skill = "#b16286" + +[desktop.open-in-target-preferences] +global = "sublimeText" + +[[skills.config]] +path = "/Users/anton/.codex/plugins/cache/claude-plugins-official/superpowers/6.0.3/skills/using-superpowers/SKILL.md" +enabled = false + +[[skills.config]] +path = "/Users/anton/.codex/plugins/cache/claude-plugins-official/superpowers/6.0.3/skills/brainstorming/SKILL.md" +enabled = false + +[shell_environment_policy.set] +BROWSER_USE_AVAILABLE_BACKENDS = "chrome,iab" +NODE_REPL_TRUSTED_BROWSER_CLIENT_SHA256S = "583bf903a6cfb9b00a01e1583381ce921c71d7585085c6fa6b805baa0f60230b,6d25aa7656feac858f3a3bdaea5bcbab0dbfd426c9de8e6931ce90c399ee8e4f" +NODE_REPL_TRUSTED_CODE_PATHS = "/Users/anton/.codex" diff --git a/dot_codex/private_executable_mcp-with-secrets.sh b/dot_codex/private_executable_mcp-with-secrets.sh new file mode 100644 index 0000000..cac9264 --- /dev/null +++ b/dot_codex/private_executable_mcp-with-secrets.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +# Launch an MCP server with its secrets loaded from a machine-local file. +# +# codex's [mcp_servers.*.env] tables only take literal values, so keeping API +# keys out of config.toml means they cannot be named there at all. This wrapper +# sources them itself and then execs the real server, which works no matter how +# codex handles environment inheritance, and needs no shell rc to have run -- +# useful on the ssh-only boxes where a GUI keychain or 1Password is not around. +# +# The secrets file is not tracked by chezmoi; see .chezmoiignore. + +set -eu + +secrets="${CODEX_MCP_SECRETS:-${CODEX_HOME:-$HOME/.codex}/secrets.env}" + +if [ -r "$secrets" ]; then + . "$secrets" +else + echo "mcp-with-secrets: no secrets file at $secrets" >&2 +fi + +[ "$#" -gt 0 ] || { + echo "mcp-with-secrets: no command given" >&2 + exit 2 +} + +exec "$@" diff --git a/dot_grok/config.toml b/dot_grok/config.toml new file mode 100644 index 0000000..49c20b9 --- /dev/null +++ b/dot_grok/config.toml @@ -0,0 +1,22 @@ +[cli] +installer = "internal" +auto_update = true + +[ui] +max_thoughts_width = 120 +fork_secondary_model = "grok-build" +yolo = false +compact_mode = false +theme = "grokday" +permission_mode = "always-approve" + +[models] +default = "grok-composer-2.5-fast" + +[marketplace] +official_marketplace_auto_installed = true +default_skills_installs_purged = true + +[[marketplace.sources]] +name = "xAI Official" +git = "https://github.com/xai-org/plugin-marketplace.git" diff --git a/dot_kimi-code/private_config.toml b/dot_kimi-code/private_config.toml new file mode 100644 index 0000000..d7bf573 --- /dev/null +++ b/dot_kimi-code/private_config.toml @@ -0,0 +1,138 @@ +default_plan_mode = false +merge_all_available_skills = false +telemetry = true +default_model = "kimi-code/k3" + +[loop_control] +max_retries_per_step = 3 +reserved_context_size = 50000 + +[background] +max_running_tasks = 4 +keep_alive_on_exit = false + +[services.moonshot_search] +base_url = "https://api.kimi.com/coding/v1/search" +api_key = "" + +[services.moonshot_search.oauth] +storage = "file" +key = "oauth/kimi-code" + +[services.moonshot_fetch] +base_url = "https://api.kimi.com/coding/v1/fetch" +api_key = "" + +[services.moonshot_fetch.oauth] +storage = "file" +key = "oauth/kimi-code" + +[thinking] +enabled = true +effort = "high" + +[providers."managed:kimi-code"] +type = "kimi" +api_key = "" +base_url = "https://api.kimi.com/coding/v1" + +[providers."managed:kimi-code".oauth] +storage = "file" +key = "oauth/kimi-code" + +[models."kimi-code/kimi-for-coding"] +provider = "managed:kimi-code" +model = "kimi-for-coding" +max_context_size = 262144 +capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ] +display_name = "K2.7 Coding" + +[models."kimi-code/kimi-for-coding-highspeed"] +provider = "managed:kimi-code" +model = "kimi-for-coding-highspeed" +max_context_size = 262144 +capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ] +display_name = "K2.7 Coding Highspeed" + +[models."kimi-code/k3"] +provider = "managed:kimi-code" +model = "k3" +max_context_size = 1048576 +capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ] +display_name = "K3" +support_efforts = [ "low", "high", "max" ] +default_effort = "high" + +[models."kimi-k.3.0"] +provider = "managed:kimi-code" +model = "kimi-k.3.0" +max_context_size = 1048576 +capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ] +display_name = "kimi-k.3.0" + +# >>> herdr kimi integration +[[hooks]] +event = "SessionStart" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' session" +timeout = 10 + +[[hooks]] +event = "UserPromptSubmit" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' working" +timeout = 10 + +[[hooks]] +event = "PreToolUse" +matcher = "^(?!AskUserQuestion$).*$" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' working" +timeout = 10 + +[[hooks]] +event = "PreToolUse" +matcher = "^AskUserQuestion$" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' blocked" +timeout = 10 + +[[hooks]] +event = "PostToolUse" +matcher = "^AskUserQuestion$" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' working" +timeout = 10 + +[[hooks]] +event = "PostToolUseFailure" +matcher = "^AskUserQuestion$" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' working" +timeout = 10 + +[[hooks]] +event = "SubagentStart" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' working" +timeout = 10 + +[[hooks]] +event = "PreCompact" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' working" +timeout = 10 + +[[hooks]] +event = "PermissionRequest" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' blocked" +timeout = 10 + +[[hooks]] +event = "PermissionResult" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' working" +timeout = 10 + +[[hooks]] +event = "Stop" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' idle" +timeout = 10 + +[[hooks]] +event = "Interrupt" +command = "bash '/Users/anton/.kimi-code/hooks/herdr-agent-state.sh' idle" +timeout = 10 + +# <<< herdr kimi integration diff --git a/dot_kimi-code/private_tui.toml b/dot_kimi-code/private_tui.toml new file mode 100644 index 0000000..57e161a --- /dev/null +++ b/dot_kimi-code/private_tui.toml @@ -0,0 +1,8 @@ +theme = "dark" + +[editor] +command = "" + +[notifications] +enabled = true +notification_condition = "unfocused" diff --git a/dot_kimi/config.toml b/dot_kimi/config.toml new file mode 100644 index 0000000..0c2af05 --- /dev/null +++ b/dot_kimi/config.toml @@ -0,0 +1,78 @@ +default_model = "kimi-code/kimi-for-coding" +default_thinking = true +default_yolo = false +default_plan_mode = false +default_editor = "" +theme = "dark" +show_thinking_stream = true +hooks = [] +merge_all_available_skills = false +telemetry = true + +[models."kimi-code/kimi-for-coding"] +provider = "managed:kimi-code" +model = "kimi-for-coding" +max_context_size = 262144 +capabilities = ["thinking", "image_in", "video_in"] +display_name = "Kimi-k2.6" + +[models. "kimi-k.3.0"] +provider = "managed:kimi-code" +model = "kimi-k.3.0" +max_context_size = 1048576 +capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ] +display_name = "kimi-k.3.0" + + + +[providers."managed:kimi-code"] +type = "kimi" +base_url = "https://api.kimi.com/coding/v1" +api_key = "" + + +[providers."managed:kimi-code".oauth] +storage = "file" +key = "oauth/kimi-code" + +[loop_control] +max_steps_per_turn = 500 +max_retries_per_step = 3 +max_ralph_iterations = 0 +reserved_context_size = 50000 +compaction_trigger_ratio = 0.85 + +[background] +max_running_tasks = 4 +read_max_bytes = 30000 +notification_tail_lines = 20 +notification_tail_chars = 3000 +wait_poll_interval_ms = 500 +worker_heartbeat_interval_ms = 5000 +worker_stale_after_ms = 15000 +kill_grace_period_ms = 2000 +keep_alive_on_exit = false +agent_task_timeout_s = 900 +print_wait_ceiling_s = 3600 + +[notifications] +claim_stale_after_ms = 15000 + +[services.moonshot_search] +base_url = "https://api.kimi.com/coding/v1/search" +api_key = "" + +[services.moonshot_search.oauth] +storage = "file" +key = "oauth/kimi-code" + +[services.moonshot_fetch] +base_url = "https://api.kimi.com/coding/v1/fetch" +api_key = "" + +[services.moonshot_fetch.oauth] +storage = "file" +key = "oauth/kimi-code" + +[mcp.client] +tool_call_timeout_ms = 60000 diff --git a/dot_kimi/private_kimi.json b/dot_kimi/private_kimi.json new file mode 100644 index 0000000..045414b --- /dev/null +++ b/dot_kimi/private_kimi.json @@ -0,0 +1,19 @@ +{ + "work_dirs": [ + { + "path": "/Users/anton", + "kaos": "local", + "last_session_id": "c0a99c4e-0915-41f1-a7b6-7c011b1a9ef1" + }, + { + "path": "/Users/anton/dev/glm", + "kaos": "local", + "last_session_id": "79ec0e41-4744-4ad2-a64b-87012c745b30" + }, + { + "path": "/Users/anton/prj/papers", + "kaos": "local", + "last_session_id": null + } + ] +} \ No newline at end of file diff --git a/dot_pi/agent/settings.json b/dot_pi/agent/settings.json index 116242d..065ef16 100644 --- a/dot_pi/agent/settings.json +++ b/dot_pi/agent/settings.json @@ -1,5 +1,5 @@ { - "lastChangelogVersion": "0.82.1", + "lastChangelogVersion": "0.83.0", "theme": "dark", "defaultProvider": "alibaba-code-plan", "defaultModel": "qwen3.8-max-preview", @@ -19,4 +19,4 @@ "npm:pi-powerline-footer", "npm:pi-webaio" ] -} +} \ No newline at end of file diff --git a/dot_reasonix/private_config.toml b/dot_reasonix/private_config.toml new file mode 100644 index 0000000..9f2ffa6 --- /dev/null +++ b/dot_reasonix/private_config.toml @@ -0,0 +1,241 @@ +# Reasonix configuration. +# Resolution order: flag > ./reasonix.toml > ~/.reasonix/config.toml > built-in defaults. +# Fields marked user/global only are not overridden by ./reasonix.toml. +# Secrets are named via api_key_env and stored in Reasonix's global .env; never put keys here. + +config_version = 5 # schema marker for diagnostics; old versions may ignore it +default_model = "deepseek-flash/deepseek-v4-flash" +language = "EN" # ui/model language; empty = auto-detect from $LANG / $REASONIX_LANG +credentials_store = "auto" # legacy compatibility; provider keys are saved in Reasonix's global .env + +[ui] +theme = "auto" # auto|dark|light; CLI colors only; REASONIX_THEME can override per run +# theme_style = "graphite" # graphite|aurora|slate|carbon|nocturne|amber and legacy aliases +# shortcut_layout = "desktop" # classic|desktop; compatibility setting; Shift+Tab toggles Plan, Ctrl+Y toggles YOLO +# cursor_shape = "bar" # block|underline|bar; text input cursor shape +# show_reasoning = true # CLI: show thinking text by default; false = collapsed (toggle with Ctrl+O) + +[desktop] +language = "en" # desktop UI language; empty/auto = browser/OS auto-detect +# currency = "USD" # official pricing currency: CNY|USD; empty/auto follows language +layout_style = "workbench" # desktop layout: classic|workbench|creation +theme = "auto" # desktop only: auto|dark|light +terminal_theme = "auto" # integrated terminal: auto|dark|light; auto follows the desktop app +# theme_style = "graphite" # graphite|aurora|slate|carbon|nocturne|amber and legacy aliases +# external_opener = "vscode" # desktop Open control: installed application id +close_behavior = "background" # desktop: quit|background when the window close button is clicked +status_bar_style = "text" # desktop: icon|text metric labels in the bottom status bar +status_bar_items = ["model", "workspace", "git_branch", "cache", "cache_avg", "session_tokens", "turn_tokens", "turn_cost", "session_turns", "context", "compact", "cost", "balance"] # desktop: ordered visible bottom status bar items +default_tool_approval_mode = "auto" # desktop: Ask/Auto/YOLO default for newly-created sessions +check_updates = true # desktop: check for new versions on startup +telemetry = true # desktop: anonymous launch ping + scrubbed next-launch native crash diagnostics; never content +metrics = true # desktop: aggregate quality/lifecycle metrics (anonymous signal/bucket counts); never content +expand_thinking = false # desktop: show reasoning text expanded by default; false = collapsed +display_mode = "standard" # desktop: standard|compact transcript display mode + +[telemetry] +cli_metrics = "auto" # CLI content-free usage metrics: auto|on|off; auto requires a local interactive terminal + +[notifications] +enabled = false # system notifications for CLI and desktop turns; default off +turn_done = true # notify when a turn finishes +approval_request = true # notify when a tool approval is waiting +ask_request = true # notify when a question is waiting + +[network] +proxy_mode = "auto" # auto|env|custom|off; auto currently uses env proxy +# proxy_url = "socks5://127.0.0.1:7890" # optional custom override +# no_proxy = "localhost,127.0.0.1,.local" # honored for proxy_mode = "custom" + +[network.proxy] +type = "socks5" # http|https|socks5|socks5h +# server = "127.0.0.1" +# port = 7890 +# username = "" +# password = "${REASONIX_PROXY_PASSWORD}" # optional; supports ${VAR} expansion + +[environment] +enabled = true # inject a stable startup environment summary into the model prompt +# [environment.tools] +# go = "/opt/homebrew/bin/go" # trusted executable path; workspace-local paths are not auto-executed + +[agent] +# system_prompt = """...""" # omit to use the built-in prompt for this version +# system_prompt_file = "prompts/system.md" # project paths stay in ; user paths may fall back to +temperature = 0.0 +# recovery_model = "deepseek-pro" # optional; falls back to guardian then main model +# reasoning_language = "zh" # visible reasoning language: auto|zh|en +soft_compact_ratio = 0.5 # notice only; keeps cache-first prefix intact +tool_result_snip_ratio = 0.6 # snip stale tool results at this fraction before summary compaction +compact_ratio = 0.8 # try compacting when prompt reaches this fraction +compact_force_ratio = 0.9 # force compacting at this high-water mark +# keep = ["errors"] # compaction keep policy: errors, user_marked +# recent_keep = 2 # minimum recent messages kept verbatim +cold_resume_prune = true # elide stale tool results when reopening a session past the provider cache window +# plan_mode_read_only_commands = ["gh issue view"] # legacy compatibility only; Plan bash uses Permissions +# planner_model = "deepseek-pro" # optional: enable two-model collaboration +# subagent_model = "deepseek-pro" # optional default for runAs=subagent skills +# subagent_models = { review = "deepseek-pro", security_review = "deepseek-pro" } # per-skill overrides +# subagent_effort = "high" # optional default effort for subagents +# subagent_efforts = { review = "max", task = "high" } # per-tool/skill effort overrides +# max_subagent_depth = 2 # nested subagent delegation depth; set 1 to disable nested delegation +# max_subagent_concurrency = 6 # session-wide sub-agent concurrency (task/fleet/skills) +# max_parallel_writers = 3 # concurrent writers with non-overlapping write_paths +# output_style = "explanatory" # explanatory | learning | concise | custom; empty = default + +[[providers]] +name = "deepseek-flash" +kind = "openai" +base_url = "https://api.deepseek.com" +model = "deepseek-v4-flash" +api_key_env = "DEEPSEEK_API_KEY" +balance_url = "https://api.deepseek.com/user/balance" # optional; wallet-balance endpoint shown in the status bar +context_window = 1000000 # tokens; compaction triggers near this limit +price = { cache_hit = 0.0028, input = 0.14, output = 0.28, currency = "$" } # provider-wide fallback, per 1M tokens + +[[providers]] +name = "deepseek-pro" +kind = "openai" +base_url = "https://api.deepseek.com" +model = "deepseek-v4-pro" +api_key_env = "DEEPSEEK_API_KEY" +balance_url = "https://api.deepseek.com/user/balance" # optional; wallet-balance endpoint shown in the status bar +context_window = 1000000 # tokens; compaction triggers near this limit +price = { cache_hit = 0.003625, input = 0.435, output = 0.87, currency = "$" } # provider-wide fallback, per 1M tokens + +[tools] +enabled = [] # empty = all built-in tools +bash_timeout_seconds = 120 # foreground safety cap; set 0 for no tool-local cap +mcp_startup_timeout_seconds = 30 # background initialize + tools/list safety cap; per-plugin overrides may raise it +mcp_call_timeout_seconds = 300 # default MCP call safety cap; per-plugin/tool overrides may raise it + +[tools.background_jobs] +stalled_warning_seconds = 900 # warn once per background job after this many quiet seconds; 0 disables + +[tools.shell] +# prefer = "auto" # auto|bash|powershell|pwsh; empty/default = auto-detect +# path = "/opt/homebrew/bin/bash" # absolute path to the shell executable; empty = PATH lookup + +[lsp] +enabled = true # language server tools; servers launch lazily when used +# [lsp.servers.go] +# command = "gopls" +# args = [] +# extensions = [".go"] + +[skills] +# paths = ["~/my-skills", "../shared/skills"] # extra custom skill roots +# excluded_paths = ["~/.agents/skills"] # hide convention roots without deleting folders +# max_depth = 3 # nested scan depth; set 1 for legacy root-only discovery +# disabled_skills = ["review"] # hide noisy or unwanted skills + +[permissions] +# Per-call gating. mode = writer fallback when no rule matches: ask|allow|deny. +# Readers always default to allow. Precedence: deny > ask > allow > fallback. +# Rules are "Tool" or "Tool(specifier)"; e.g. Bash(go test:*), Edit(src/**). +mode = "ask" +# allow_dynamic_bash = false # advanced opt-in; deny/ask and exact rules still take precedence +# deny = ["Bash(rm -rf*)", "Bash(git push*)"] # hard-blocked in every mode +# allow = ["Bash(go test:*)", "Bash(git status:*)"] # never prompted +# ask = ["Edit(src/**)"] # force a prompt even if otherwise allowed + +[sandbox] +# Confine tool blast radius. File-writers (write_file/edit_file/multi_edit/move_file) +# may only write under workspace_root (empty = current dir) and allow_write extras. +# bash = "enforce" jails each command in an OS sandbox when available; +# without one, bash execution is refused. Empty defaults to enforce on macOS/Linux. +# Windows has no OS-level Bash sandbox and fixes bash = "off". +# network allows sandboxed bash egress. +# workspace_root = "" # default: current working directory +# allow_write = ["/tmp"] # extra dirs writers may also modify +# forbid_read = [] # dirs the agent cannot read or list +bash = "enforce" +network = true + +[statusline] +# A custom status line: a command whose first stdout line replaces the built-in +# data row. It receives {"model","contextUsed","contextWindow","cwd"} as JSON on stdin. +# command = "my-statusline.sh" + +# Bot gateway: multi-channel IM bot for QQ, Feishu/Lark, and WeChat. +[bot] +enabled = false +# model = "" # empty = default_model +tool_approval_mode = "ask" # ask|auto|yolo; yolo skips tool approvals only +max_steps = 25 +debounce_ms = 1500 +queue_mode = "steer" # steer|followup|collect|interrupt +queue_cap = 20 +queue_drop = "summarize" # summarize|old|new +ignore_self_messages = true # ignore bot echo by returned message_id and configured self user ids + +[bot.self_user_ids] +qq = [] +feishu = [] +weixin = [] + +[bot.control] +enabled = false # local loopback HTTP API for status/send; requires Bearer token +addr = "127.0.0.1:37913" +token_env = "REASONIX_BOT_CONTROL_TOKEN" + +[bot.pairing] +enabled = true +request_ttl_minutes = 60 +max_pending_per_platform = 3 + +[bot.allowlist] +enabled = true +allow_all = false +qq_users = [] +feishu_users = [] +weixin_users = [] +qq_approvers = [] +feishu_approvers = [] +weixin_approvers = [] +qq_admins = [] +feishu_admins = [] +weixin_admins = [] +qq_groups = [] +feishu_groups = [] +weixin_groups = [] + +[bot.qq] +enabled = false +app_id = "" +app_secret_env = "QQ_BOT_APP_SECRET" +sandbox = false + +[bot.feishu] +enabled = false +app_id = "" +domain = "feishu" +app_secret_env = "FEISHU_BOT_APP_SECRET" +verification_token = "" +mode = "webhook" +webhook_port = 8080 +require_mention = true + +[bot.weixin] +enabled = false +account_id = "default" +token_env = "WEIXIN_BOT_TOKEN" +api_base = "https://ilinkai.weixin.qq.com" + +[secrets] # credential protection; user/global only, ./reasonix.toml cannot override +# filter_subprocess_env = false # opt-in; stripping tokens breaks gh, HTTPS git push, npm publish +# protect_sensitive_files = false # opt-in; hiding credential files can break legitimate edit workflows + +# External MCP servers. type: "stdio" (default, a subprocess) | "http" | "sse". +# ${VAR} / ${VAR:-default} are expanded from the environment in command/args/env/url/headers. +# [[plugins]] +# name = "example" +# command = "reasonix-plugin-example" +# startup_timeout_seconds = 60 # optional initialize + tools/list cap +# call_timeout_seconds = 600 # optional per-server MCP call timeout +# tool_timeout_seconds = { "generate_video" = 1800 } # raw MCP tool names +# [[plugins]] # a remote server over Streamable HTTP +# name = "stripe" +# type = "http" +# url = "https://mcp.stripe.com" +# headers = { Authorization = "Bearer ${STRIPE_KEY}" }