From 5b58460618d4f9b0f03415972094400027f3d0dd Mon Sep 17 00:00:00 2001 From: Anton Volnuhin Date: Thu, 6 Aug 2026 02:23:49 +0300 Subject: [PATCH] Track agent CLI configs, with codex secrets externalized codex's config.toml held nine live API keys inline under [mcp_servers.*.env] -- deepseek, gemini, kimi, mimo, qwen, glm, cursor, an OpenAI key and a Home Assistant token -- so it could not be tracked as it stood. TOML env tables take literal values only, with no ${VAR} indirection or env_file, so the keys cannot simply be named there. Move them to ~/.codex/secrets.env (0600, ignored) and route the four affected servers through mcp-with-secrets.sh, which sources that file and execs the real command. Doing it in the wrapper rather than relying on exported shell vars means it does not depend on how codex handles environment inheritance, and works on ssh-only boxes with no keychain or 1Password agent, which is why this was preferred over a chezmoi template. Adds configs for claude, codex, pi, grok, kimi, kimi-code and reasonix, and extends .chezmoiignore so credentials, session logs, local state and .bak files stay out even if a directory is ever added whole. Held back for still containing live keys: opencode.json (bailian), and reasonix config.json and .env. --- .chezmoiignore | 30 ++ dot_claude/CLAUDE.md | 16 + dot_claude/private_settings.json | 326 +++++++++++++ dot_claude/statusline-command.sh | 52 +++ dot_codex/github-mcp-env.zsh | 21 + dot_codex/hooks.json | 76 +++ dot_codex/keybindings.json | 6 + dot_codex/private_config.toml | 437 ++++++++++++++++++ .../private_executable_mcp-with-secrets.sh | 28 ++ dot_grok/config.toml | 22 + dot_kimi-code/private_config.toml | 138 ++++++ dot_kimi-code/private_tui.toml | 8 + dot_kimi/config.toml | 78 ++++ dot_kimi/private_kimi.json | 19 + dot_pi/agent/settings.json | 4 +- dot_reasonix/private_config.toml | 241 ++++++++++ 16 files changed, 1500 insertions(+), 2 deletions(-) create mode 100644 dot_claude/CLAUDE.md create mode 100644 dot_claude/private_settings.json create mode 100644 dot_claude/statusline-command.sh create mode 100644 dot_codex/github-mcp-env.zsh create mode 100644 dot_codex/hooks.json create mode 100644 dot_codex/keybindings.json create mode 100644 dot_codex/private_config.toml create mode 100644 dot_codex/private_executable_mcp-with-secrets.sh create mode 100644 dot_grok/config.toml create mode 100644 dot_kimi-code/private_config.toml create mode 100644 dot_kimi-code/private_tui.toml create mode 100644 dot_kimi/config.toml create mode 100644 dot_kimi/private_kimi.json create mode 100644 dot_reasonix/private_config.toml 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}" }