Compare commits

..

No commits in common. "a84778a640b182ec31e27771934dfd0768bef741" and "826a9417e7fb9278281968cb20a6e1107c160c2e" have entirely different histories.

19 changed files with 10 additions and 1566 deletions

View File

@ -11,36 +11,6 @@ Library
.pi/agent/auth.json .pi/agent/auth.json
.pi/agent/sessions .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 # 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 # are generated from it plus .config/kitty/themes. Tracking them would make
# every machine flag the others' mode. run_after_kitty-theme-mode.sh # every machine flag the others' mode. run_after_kitty-theme-mode.sh

View File

@ -1,16 +0,0 @@
# 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.

View File

@ -1,326 +0,0 @@
{
"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 <noreply@anthropic.com>\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 <noreply@anthropic.com>\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 <noreply@anthropic.com>\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 <noreply@anthropic.com>\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
}

View File

@ -1,52 +0,0 @@
#!/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

View File

@ -1,21 +0,0 @@
# 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

View File

@ -1,76 +0,0 @@
{
"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"
}
]
}
]
}
}

View File

@ -1,6 +0,0 @@
[
{
"command": "hotkeyWindow",
"key": "Alt+Space"
}
]

View File

@ -1,437 +0,0 @@
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"

View File

@ -1,28 +0,0 @@
#!/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 "$@"

View File

@ -1,22 +0,0 @@
[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"

View File

@ -1,138 +0,0 @@
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

View File

@ -1,8 +0,0 @@
theme = "dark"
[editor]
command = ""
[notifications]
enabled = true
notification_condition = "unfocused"

View File

@ -1,78 +0,0 @@
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

View File

@ -1,19 +0,0 @@
{
"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
}
]
}

View File

@ -1,5 +1,5 @@
{ {
"lastChangelogVersion": "0.83.0", "lastChangelogVersion": "0.82.1",
"theme": "dark", "theme": "dark",
"defaultProvider": "alibaba-code-plan", "defaultProvider": "alibaba-code-plan",
"defaultModel": "qwen3.8-max-preview", "defaultModel": "qwen3.8-max-preview",

View File

@ -1,241 +0,0 @@
# 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 <workspace>; user paths may fall back to <reasonix home>
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}" }

View File

@ -14,22 +14,6 @@
set -eu set -eu
# Permission bits of a file, or 600 if they cannot be read. GNU stat spells this
# `-c %a` while BSD/macOS spells it `-f %Lp`, and each mis-parses the other's
# form -- GNU treats `-f` as --file-system and prints a block of filesystem info
# before failing -- so try one at a time and only accept an octal answer.
file_mode() {
_m=$(stat -c '%a' "$1" 2>/dev/null) || _m=''
case "$_m" in
[0-7][0-7][0-7] | [0-7][0-7][0-7][0-7]) printf '%s\n' "$_m"; return 0 ;;
esac
_m=$(stat -f '%Lp' "$1" 2>/dev/null) || _m=''
case "$_m" in
[0-7][0-7][0-7] | [0-7][0-7][0-7][0-7]) printf '%s\n' "$_m"; return 0 ;;
esac
printf '600\n'
}
script_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" script_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
config_dir=${1:-"$script_dir"} config_dir=${1:-"$script_dir"}
canonical_dir="$config_dir/themes" canonical_dir="$config_dir/themes"
@ -70,9 +54,12 @@ for appearance in dark light no-preference; do
[ -f "$canonical" ] || continue [ -f "$canonical" ] || continue
generated="$config_dir/$appearance-theme.auto.conf" generated="$config_dir/$appearance-theme.auto.conf"
# stat -f is BSD/macOS, stat -c is GNU; this also runs on Linux boxes.
mode_bits=600 mode_bits=600
if [ -f "$generated" ]; then if [ -f "$generated" ]; then
mode_bits=$(file_mode "$generated") mode_bits=$(stat -f '%Lp' "$generated" 2>/dev/null \
|| stat -c '%a' "$generated" 2>/dev/null \
|| echo 600)
fi fi
tmp=$(mktemp "$generated.tmp.XXXXXX") tmp=$(mktemp "$generated.tmp.XXXXXX")

View File

@ -2,22 +2,6 @@
set -eu set -eu
# Permission bits of a file, or 600 if they cannot be read. GNU stat spells this
# `-c %a` while BSD/macOS spells it `-f %Lp`, and each mis-parses the other's
# form -- GNU treats `-f` as --file-system and prints a block of filesystem info
# before failing -- so try one at a time and only accept an octal answer.
file_mode() {
_m=$(stat -c '%a' "$1" 2>/dev/null) || _m=''
case "$_m" in
[0-7][0-7][0-7] | [0-7][0-7][0-7][0-7]) printf '%s\n' "$_m"; return 0 ;;
esac
_m=$(stat -f '%Lp' "$1" 2>/dev/null) || _m=''
case "$_m" in
[0-7][0-7][0-7] | [0-7][0-7][0-7][0-7]) printf '%s\n' "$_m"; return 0 ;;
esac
printf '600\n'
}
config_dir=${1:-"$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"} config_dir=${1:-"$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"}
for appearance in dark light no-preference; do for appearance in dark light no-preference; do
@ -38,7 +22,10 @@ for appearance in dark light no-preference; do
trap 'rm -f "$tmp"' EXIT HUP INT TERM trap 'rm -f "$tmp"' EXIT HUP INT TERM
awk '$1 != "macos_titlebar_color"' "$config_file" > "$tmp" awk '$1 != "macos_titlebar_color"' "$config_file" > "$tmp"
printf '\nmacos_titlebar_color background\n' >> "$tmp" printf '\nmacos_titlebar_color background\n' >> "$tmp"
chmod "$(file_mode "$config_file")" "$tmp" # stat -f is BSD/macOS, stat -c is GNU; this also runs on Linux boxes.
chmod "$(stat -f '%Lp' "$config_file" 2>/dev/null \
|| stat -c '%a' "$config_file" 2>/dev/null \
|| echo 600)" "$tmp"
mv -f "$tmp" "$config_file" mv -f "$tmp" "$config_file"
trap - EXIT HUP INT TERM trap - EXIT HUP INT TERM
done done

View File

@ -149,36 +149,4 @@ run_fish dark 'theme >/dev/null'
"$root/tests/verify_auto_themes.sh" "$config_dir" "$root/tests/verify_auto_themes.sh" "$config_dir"
# --- the scripts must work where stat is GNU, not BSD ---------------------
# GNU stat reads -f as --file-system, so `stat -f '%Lp' file` prints a block of
# filesystem info to stdout *and* exits non-zero. Chaining it into `|| stat -c`
# concatenates that block with the real answer and chmod then rejects it, which
# broke `chezmoi apply` on Linux with "could not regenerate kitty theme files".
cat >"$fake_bin/stat" <<'EOF'
#!/bin/sh
case "$1" in
-c) shift; [ "$1" = "%a" ] && shift; /usr/bin/stat -f '%Lp' "$1" ;;
-f) shift
echo " File: \"$2\""
echo "Block size: 4096 Fundamental block size: 4096"
exit 1 ;;
*) exec /usr/bin/stat "$@" ;;
esac
EOF
chmod +x "$fake_bin/stat"
echo auto >"$config_dir/theme-mode"
if ! PATH="$fake_bin:/usr/bin:/bin" "$root/apply-theme-mode.sh" "$config_dir" \
>/dev/null 2>&1; then
echo "not ok - apply-theme-mode.sh fails where stat is GNU" >&2
exit 1
fi
for appearance in dark light no-preference; do
[ -f "$config_dir/$appearance-theme.auto.conf" ] || {
echo "not ok - GNU stat run did not produce $appearance theme" >&2
exit 1
}
done
rm -f "$fake_bin/stat"
echo "PASS: theme mode is remembered, survives kitten themes, and collapses to auto" echo "PASS: theme mode is remembered, survives kitten themes, and collapses to auto"