mixdog 0.9.35 → 0.9.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/package.json +3 -2
  2. package/scripts/abort-recovery-test.mjs +118 -0
  3. package/scripts/compact-smoke.mjs +7 -7
  4. package/scripts/explore-bench-tmp.mjs +19 -0
  5. package/scripts/explore-bench.mjs +36 -6
  6. package/scripts/explore-prompt-policy-test.mjs +27 -0
  7. package/scripts/ingest-pure-conversation-smoke.mjs +11 -11
  8. package/scripts/openai-ws-early-settle-test.mjs +176 -0
  9. package/scripts/output-style-smoke.mjs +17 -17
  10. package/scripts/provider-toolcall-test.mjs +333 -14
  11. package/scripts/recall-bench-cases.json +3 -3
  12. package/scripts/recall-bench.mjs +1 -1
  13. package/scripts/recall-quality-cases.json +4 -4
  14. package/scripts/recall-usecase-cases.json +2 -2
  15. package/scripts/session-bench.mjs +13 -13
  16. package/scripts/steering-drain-buckets-test.mjs +72 -11
  17. package/scripts/submit-commandbusy-race-test.mjs +114 -0
  18. package/scripts/tool-smoke.mjs +83 -10
  19. package/src/app.mjs +2 -1
  20. package/src/defaults/cycle3-review-prompt.md +9 -0
  21. package/src/defaults/skills/setup/SKILL.md +93 -293
  22. package/src/lib/rules-builder.cjs +3 -2
  23. package/src/output-styles/default.md +2 -2
  24. package/src/output-styles/extreme-minimal.md +1 -1
  25. package/src/output-styles/minimal.md +1 -1
  26. package/src/output-styles/simple.md +2 -3
  27. package/src/rules/agent/30-explorer.md +15 -7
  28. package/src/rules/lead/01-general.md +4 -0
  29. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +15 -3
  30. package/src/runtime/agent/orchestrator/config.mjs +1 -1
  31. package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -7
  32. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +6 -6
  33. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +6 -6
  34. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +35 -5
  35. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +27 -0
  36. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +36 -37
  37. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +2 -2
  38. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +72 -1
  39. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +26 -3
  40. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +12 -28
  41. package/src/runtime/agent/orchestrator/providers/openai-transport-policy.mjs +18 -15
  42. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +4 -2
  43. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +113 -2
  44. package/src/runtime/agent/orchestrator/providers/registry.mjs +44 -5
  45. package/src/runtime/agent/orchestrator/providers/tool-stream-state.mjs +78 -0
  46. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +57 -31
  47. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +8 -6
  48. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +28 -2
  49. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +1 -3
  50. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +15 -2
  51. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +26 -17
  52. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +2 -2
  53. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +24 -16
  54. package/src/runtime/agent/orchestrator/session/result-classification.mjs +2 -0
  55. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -2
  56. package/src/runtime/agent/orchestrator/stall-policy.mjs +18 -0
  57. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +35 -20
  58. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -7
  59. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +77 -31
  60. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +25 -3
  61. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +9 -2
  62. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +73 -25
  63. package/src/runtime/agent/orchestrator/tools/builtin.mjs +2 -1
  64. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +17 -7
  65. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +14 -12
  66. package/src/runtime/agent/orchestrator/tools/code-graph/graph-model.mjs +5 -0
  67. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +56 -6
  68. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +9 -0
  69. package/src/runtime/channels/lib/worker-main.mjs +5 -0
  70. package/src/runtime/memory/lib/core-memory-store.mjs +104 -0
  71. package/src/runtime/memory/lib/ko-morph.mjs +1 -1
  72. package/src/runtime/memory/lib/memory-cycle3.mjs +64 -4
  73. package/src/runtime/memory/lib/memory-text-utils.mjs +4 -4
  74. package/src/runtime/memory/lib/recall-format.mjs +3 -3
  75. package/src/runtime/shared/child-spawn-gate.mjs +15 -0
  76. package/src/runtime/shared/config.mjs +98 -12
  77. package/src/runtime/shared/process-listener-headroom.mjs +12 -0
  78. package/src/session-runtime/cwd-plugins.mjs +6 -3
  79. package/src/session-runtime/model-route-api.mjs +50 -2
  80. package/src/session-runtime/provider-auth-api.mjs +8 -1
  81. package/src/session-runtime/resource-api.mjs +22 -0
  82. package/src/session-runtime/runtime-core.mjs +13 -2
  83. package/src/session-runtime/settings-api.mjs +11 -2
  84. package/src/standalone/agent-tool.mjs +15 -9
  85. package/src/standalone/explore-tool.mjs +4 -1
  86. package/src/tui/App.jsx +6 -5
  87. package/src/tui/app/transcript-window.mjs +60 -10
  88. package/src/tui/app/use-transcript-window.mjs +2 -1
  89. package/src/tui/components/ContextPanel.jsx +4 -1
  90. package/src/tui/components/ToolExecution.jsx +15 -12
  91. package/src/tui/components/TranscriptItem.jsx +1 -1
  92. package/src/tui/components/tool-execution/surface-detail.mjs +8 -8
  93. package/src/tui/dist/index.mjs +473 -155
  94. package/src/tui/engine/agent-job-feed.mjs +26 -6
  95. package/src/tui/engine/context-state.mjs +13 -4
  96. package/src/tui/engine/notification-plan.mjs +3 -3
  97. package/src/tui/engine/render-timing.mjs +104 -8
  98. package/src/tui/engine/session-api.mjs +58 -3
  99. package/src/tui/engine/session-flow.mjs +78 -28
  100. package/src/tui/engine/tool-card-results.mjs +28 -13
  101. package/src/tui/engine/turn.mjs +232 -156
  102. package/src/tui/engine.mjs +17 -8
  103. package/src/tui/index.jsx +10 -1
  104. package/src/workflows/default/WORKFLOW.md +8 -4
  105. package/src/workflows/solo/WORKFLOW.md +8 -4
@@ -1,332 +1,132 @@
1
1
  ---
2
2
  name: setup
3
- description: Use this skill to configure a mixdog installation — request-driven recipes for models, MCP, channels, output style, memory/recap, skills, and secrets. Triggers on "셋업", "세팅 도와줘", "setup", "환경 구성", "모델 바꿔줘", "MCP 추가", "출력 스타일", "디스코드 토큰". Skip for non-configuration tasks.
3
+ description: Use this skill to configure a mixdog installation — request-driven recipes for models, MCP, channels, output style, memory/recap, skills, secrets, and workflow packs. Triggers on "setup", "configure", "change model", "add MCP", "output style", "Discord token", "workflow".
4
4
  ---
5
5
 
6
- # mixdog Setup Runbook
6
+ # Setup Skill
7
7
 
8
- 사용자 요청 아래 **레시피**에서 매칭 확인 변경 검증 순서로 진행한다.
8
+ Map the user request to the matching recipe below, confirm the intended change,
9
+ apply it, and verify the result.
9
10
 
10
- > **METHOD·POINTER만** 기록한다. 모델명·토큰·URL·채널 ID **라이브 값은 문서에 넣지 않는다** 항상 config·런타임 status·환경변수에서 그때 읽는다.
11
+ > Record METHOD and POINTERS only. Do not store live model names, tokens, URLs,
12
+ > channel IDs, or other secrets in this document. Always read live values from
13
+ > config, runtime status, or environment variables at execution time.
11
14
 
12
- **공통 진단 (편집 전)**
13
- - Config: `<mixdogData>/mixdog-config.json` (`MIXDOG_DATA_DIR` / `MIXDOG_HOME`로 경로 변경 가능; 정의 `src/runtime/shared/config.mjs`)
14
- - MCP: TUI `/mcp` 목록 또는 런타임 `mcpStatus()`
15
- - Skills: `skillsStatus()` 또는 경로 스캔 (§부록)
16
- - 비밀 존재: `hasStoredSecret(account)` (값 미노출) 또는 `MIXDOG_*` / 표준 provider env
15
+ ## Common diagnostics before editing
17
16
 
18
- **TUI 진입 공통**
19
- - 슬래시 명령: `src/tui/app/slash-commands.mjs`
20
- - 설정 허브: `/setting` (별칭 `/settings`, `/config`) → `src/tui/app/settings-picker.mjs`
17
+ - Config: `<mixdogData>/mixdog-config.json` (`MIXDOG_DATA_DIR` /
18
+ `MIXDOG_HOME` may override the path; definition:
19
+ `src/runtime/shared/config.mjs`).
20
+ - MCP: TUI `/mcp` list or runtime `mcpStatus()`.
21
+ - Skills: `skillsStatus()` or scan skill paths.
22
+ - Secrets: `hasStoredSecret(account)` for presence only, or relevant
23
+ `MIXDOG_*` / provider environment variables.
21
24
 
22
- ---
23
-
24
- ## 요청별 레시피
25
-
26
- **인덱스 — 요청 키워드 → 레시피/명령**
27
-
28
- | 요청 | 경로 |
29
- |------|------|
30
- | 메인 모델 변경 | `/model` (아래 레시피) |
31
- | 특정 에이전트 모델 | `/agents` (아래 레시피) |
32
- | 워크플로 슬롯 라우트 | 아래 레시피 표 |
33
- | 웹서치 모델 | `/search` (아래 레시피) |
34
- | reasoning effort | `/effort [level]` (아래 레시피) |
35
- | Fast 모드 | `/fast [on\|off]` (아래 레시피) |
36
- | Provider API 키 | `/providers` (아래 레시피) |
37
- | Provider OAuth 로그인/해제 | `/providers` → Login/Forget (아래 레시피) |
38
- | 로컬/커스텀 엔드포인트 | `/providers` → local (아래 레시피) |
39
- | Usage 로그인 | `/providers` → Usage login (아래 레시피) |
40
- | 출력 스타일 | `/OutputStyle`·`/style` (아래 레시피) |
41
- | TUI 테마 | `/theme [id]` (아래 레시피) |
42
- | 프로필(호칭·언어) | `/profile` (아래 레시피) |
43
- | 음성(채널 보이스 전사) | `/channels` → **Voice** (아래 레시피) |
44
- | autoclear | `/autoclear` (아래 레시피) |
45
- | auto-compact | `/setting` → Auto-compact 토글 (compact type은 고정, 아래 레시피) |
46
- | Recap/메모리 | `/memory` 토글 (아래 레시피) |
47
- | memory interval | config 편집 (아래 레시피) |
48
- | MCP 추가/삭제/재연결/진단 | `/mcp` + config (아래 레시피) |
49
- | 채널/토큰/스케줄/웹훅 | `/channels`, `/schedules`, `/webhooks` (아래 레시피) |
50
- | 원격 세션 클레임 | `/remote` (아래 레시피) |
51
- | 채널 백엔드(Discord↔Telegram) | `/setting` → Channel (아래 레시피) |
52
- | 시스템 셸 | config `shell` (아래 레시피) |
53
- | before-tool hooks | `/hooks` (아래 레시피) |
54
- | 플러그인 | `/plugins` (아래 레시피) |
55
- | 스킬 생성 | 아래 레시피 |
56
- | 워크플로 팩 | `/workflow` (아래 레시피) |
57
- | 프로젝트(작업 디렉터리) | `/project` (아래 레시피) |
58
- | 업데이트 | `/update` (아래 레시피) |
59
- | 조회·세션 조작(레시피 없음) | `/context`(컨텍스트 표면) `/usage`(쿼터) `/resume`(이어하기) `/compact`(컨텍스트 압축) `/clear`(새 채팅) `/autoclear status` `/quit` |
60
-
61
- ### 메인 모델 변경 ("메인 모델 바꿔줘", "모델 변경")
62
-
63
- 1. **확인**: TUI 상태줄 또는 `/setting` → **Model** 메타; config `workflowRoutes.lead` / preset `workflow-lead` / 현재 `setRoute` 반영 여부는 `mixdog-config.json`에서 교차 확인.
64
- 2. **변경 (사용자 경로)**
65
- - `/model` → 모델 피커 (`openModelPicker` → `store.setModel` → `runtime.setRoute`)
66
- - 또는 `/setting` → **Model**
67
- - 온보딩 일괄: `mixdog --onboarding` Step 2 **Main** (`completeOnboarding` + `defaultRoute`)
68
- 3. **검증**: 다음 턴부터 적용(진행 중 세션의 라이브 route는 유지). 새 채팅 `/clear` 후 provider/model 표시 확인.
69
-
70
- ### 특정 에이전트만 모델 변경 ("리뷰어만 다른 모델", "worker 모델")
71
-
72
- 1. **확인**: `/agents` 목록의 **Reviewer** 등 메타 = `config.agents[<id>]` override; 없으면 Main Model 동적 상속.
73
- 2. **변경**: `/agents` → 에이전트 선택 → 모델 피커 → `store.setAgentRoute` (`src/mixdog-session-runtime.mjs`: `agents`, `presets` `agent-<id>`, workflow-backed면 `workflowRoutes` + `maintenance` 미러).
74
- 3. **검증**: `/agents`에서 해당 에이전트 메타 갱신; config에 `agents.reviewer` (예) 및 일관된 preset 존재.
75
-
76
- **Main으로 되돌리기**: TUI `/agents`에는 “Default” 행 없음 → config에서 `agents.<id>` 키 삭제 후 저장, 또는 `mixdog --onboarding` Step 2에서 해당 에이전트 **Default** (onboarding만 override 제거 UI 제공).
77
-
78
- ### 워크플로 슬롯 라우트 ("lead/agent/explorer/memory 슬롯", "에이전트 라우트")
79
-
80
- 슬롯 정의: `WORKFLOW_ROUTE_SLOTS = ['lead','agent','explorer','memory']` (`src/session-runtime/workflow.mjs`).
81
-
82
- | 슬롯 | 사용자-facing 변경 |
83
- |------|-------------------|
84
- | **lead** | **메인 모델 변경** 레시피 (`/model`) |
85
- | **explorer** | `/agents` → **Explore** |
86
- | **memory** | `/agents` → **Maintainer** |
87
- | **agent** | 전용 TUI 슬롯 피커 없음 → `mixdog --onboarding` Step 2 또는 config `workflowRoutes.agent` + preset `workflow-agent` 수동 일관 편집 |
88
-
89
- 1. **확인**: config `workflowRoutes`, `presets` (`workflow-<slot>`, `agent-<id>`), `maintenance.explore` / `maintenance.memory`.
90
- 2. **변경**: 위 표 경로; 대량·최초 설정은 `mixdog --onboarding` → `completeOnboarding` → `saveConfigAndAdopt`.
91
- 3. **검증**: **3키 일관성** — `workflowRoutes`, `agents`, `presets`가 서로 모순 없는지 (파일 직접 편집 시 필수).
92
-
93
- ### Provider API 키 ("API 키 설정", "OpenAI 키")
94
-
95
- 1. **확인**: `/providers` 또는 `/setting` → **Providers**; provider 행의 authenticated/env 상태.
96
- 2. **변경**: `/providers` → API provider → **Add/Replace API key** → 마스크 입력 (`provider-setup-picker.mjs` → keychain `agent.<provider>.apiKey`). OAuth/local provider는 동일 피커 내 해당 액션.
97
- 3. **검증**: `/providers`에서 authenticated; 필요 시 `/model` 목록 로드 성공.
98
- **대안**: 표준 env 최우선 (`OPENAI_API_KEY` 등 — §부록 secrets).
99
-
100
- ### Provider OAuth 로그인 ("클로드 로그인", "OAuth 인증", "구독 계정 연결")
101
-
102
- 1. **확인**: `/providers` — OAuth provider 행(예: anthropic-oauth, openai-oauth, grok-oauth)의 authenticated 상태.
103
- 2. **변경**: `/providers` → OAuth provider 선택 → **Login** (`login-oauth` → `startOAuthLogin`, 브라우저 로그인 플로우) / 해제는 **Forget** (`forget-oauth`). 자격은 `<mixdogData>`의 provider별 credential 파일(예: `anthropic-oauth-credentials.json`)에 저장.
104
- 3. **검증**: `/providers` authenticated 표시; `/model`에서 해당 provider 모델 목록 로드.
105
-
106
- ### 로컬/커스텀 엔드포인트 ("로컬 모델", "ollama 연결")
107
-
108
- 1. **확인**: `/providers` — local provider 행.
109
- 2. **변경**: `/providers` → local provider 선택 → 로컬 엔드포인트 액션 피커(`openLocalProviderActions` — URL 등 설정).
110
- 3. **검증**: `/providers` 상태; `/model` 목록에 로컬 모델 노출.
111
-
112
- ### Usage 로그인 (OpenCode Go 등) ("사용량 인증")
113
-
114
- - `/providers` → 해당 provider → **Usage login (browser)** — 브라우저 로그인 후 auth cookie 자동 캡처(keychain `agent.opencode-go.authCookie`). `/usage`가 쿼터를 못 읽을 때 이 경로.
115
-
116
- ### 출력 스타일 변경 ("출력 스타일 바꿔", "minimal로")
117
-
118
- 1. **확인**: config 루트 `outputStyle` (레거시 `agent.outputStyle` 제거 권장); `outputStyleStatus()` / `/OutputStyle status`.
119
- 2. **변경**: `/OutputStyle` 또는 `/style` (인자 없으면 피커); 직접 `/OutputStyle minimal` → `setOutputStyle` (`output-styles.mjs` id·별칭). 사용자 정의: `<mixdogData>/output-styles/<id>.md`.
120
- 3. **검증**: notice의 label; 대화가 있으면 “Use /clear to apply” — 빈 세션은 자동 세션 재생성.
121
-
122
- ### Recap / 메모리 배경 주기 ("메모리 꺼줘", "recap off")
123
-
124
- **구분**: 코어 메모리 도구는 상시; UI **Recap** = config `recap.enabled` (`setMemoryEnabled` → `setRecapEnabled`, `settings-api.mjs`). 전용 `/recap` 명령·`/setting` Recap 행은 **없음** — 진입점은 `/memory` 피커 토글뿐.
125
-
126
- 1. **확인**: `/memory` → 코어 메모리 피커 상단 토글 메타; config `recap.enabled`.
127
- 2. **변경**: `/memory` 피커 상단 토글 (`core-memory-picker.mjs` → `store.setMemoryEnabled`); 또는 config `recap.enabled` 직접 편집.
128
- 3. **검증**: 토글 후 피커 메타/notice; config `recap.enabled`.
129
-
130
- ### memory interval ("사이클 간격", "10m 간격")
131
-
132
- TUI 전용 interval 피커 없음.
133
-
134
- 1. **확인**: config `memory.cycle1.interval`, `memory.cycle2.interval` (duration 문자열, 템플릿 `src/defaults/mixdog-config.template.json`).
135
- 2. **변경**: `mixdog-config.json`의 `memory` 섹션 편집 (유효 JSON 유지).
136
- 3. **검증**: 파일 재읽기; memory 데몬은 config 리로드 정책에 따름(변경 후 mixdog 재시작이 가장 확실).
137
-
138
- ### MCP 서버 추가 — stdio / http ("MCP 추가해줘", "stdio MCP")
139
-
140
- **소스**: config `mcpServers` + 프로젝트 `.mcp.json` 병합; 이름 충돌 시 **프로젝트 승** (`mcp-glue.mjs`).
141
-
142
- 1. **확인**: `/mcp` 연결 수; 프로젝트 `<cwd>/.mcp.json` 존재 여부.
143
- 2. **변경**
144
- - **사용자 config**: `mixdog-config.json` → `mcpServers.<name>` 추가 (stdio: `type`,`command`,`args`,`cwd` 프로젝트 하위만; http: `type`,`url`,`headers`) 후 **mixdog TUI 재시작** (런타임 `addMcpServer` / `reconnectMcp`는 `engine.mjs`에 있으나 **TUI 메뉴에서 호출처 없음**; `App.jsx`의 `mcp-add` 텍스트 프롬프트 핸들러만 존재하고 진입 UI 미연결).
145
- - **프로젝트 전용**: `<cwd>/.mcp.json` 편집 → 저장 후 TUI 재시작 또는 cwd 변경 시 자동 재연결.
146
- 3. **검증**: `/mcp`에서 `connected`, `toolCount>0`, `source` (config vs project).
25
+ ## TUI entry points
147
26
 
148
- ### MCP 비활성화 / 삭제 / 재연결
27
+ - Slash commands: `src/tui/app/slash-commands.mjs`.
28
+ - Settings hub: `/setting` (aliases `/settings`, `/config`) via
29
+ `src/tui/app/settings-picker.mjs`.
149
30
 
150
- 1. **확인**: `/mcp` 서버 행 status·error.
151
- 2. **변경**
152
- - **비활성화 (config `mcpServers`만)**: `/mcp` → 서버 선택/←→ → `setMcpServerEnabled` (config 항목). 프로젝트 `.mcp.json` 항목은 파일에서 `enabled:false` 또는 항목 제거.
153
- - **삭제**: config면 `mcpServers`에서 키 제거 (`removeMcpServer` — TUI 미노출 → 파일 편집); 프로젝트면 `.mcp.json`에서 제거.
154
- - **재연결**: 파일 직접 편집 후 **mixdog 재시작** (`reconnectMcp` TUI 미연결).
155
- 3. **검증**: `/mcp` connected 비율; 실패 시 error 문자열.
31
+ ## Request index
156
32
 
157
- ### MCP 연결 됨 — Unity MCP 등 ("유니티 MCP 연결 안 돼")
33
+ | Request | Route |
34
+ |---|---|
35
+ | Main model | `/model` |
36
+ | Agent model | `/agents` |
37
+ | Workflow pack | `/workflow` |
38
+ | Search model | `/search` |
39
+ | Reasoning effort | `/effort [level]` |
40
+ | Fast mode | `/fast [on|off]` |
41
+ | Output style | `/style` |
42
+ | Memory / recap | `/memory`, `/recap`, config |
43
+ | MCP server | `/mcp`, config |
44
+ | Provider secret | provider login flow or secret store |
45
+ | Discord / channel | config and channel runtime status |
46
+ | Skill add/update | project or global `skills/<name>/SKILL.md` |
158
47
 
159
- 1. **확인**: `/mcp`에서 서버명·`source:project`·`transport`·`error`; `<cwd>/.mcp.json` url/command; config 동일 이름 덮어쓰기 여부.
160
- 2. **조치**: HTTP면 URL·방화벽·Unity 쪽 MCP 프로세스 기동; stdio면 `cwd`가 **프로젝트 하위**인지 (`normalizeMcpServerInput`); 충돌 시 프로젝트 정의가 우선인지 확인; `env`는 서버 프로세스용(민감값은 호스트 env 참조).
161
- 3. **검증**: `connected:true`, 기대 tool 노출.
48
+ ## Recipes
162
49
 
163
- ### Discord / Telegram 토큰 ("디스코드 토큰 설정", "채널 설정")
50
+ ### Main model
164
51
 
165
- 1. **확인**: `/channels` 또는 `/setting` **Setting** / **Channel**; `getChannelSetup()` authenticated·main target.
166
- 2. **변경**: `/channels` **Discord** 또는 **Telegram** → **Bot token** → 붙여넣기 (keychain `discord.token` / `telegram.token`, `channel-pickers.mjs`). Main channel/chat ID는 동 피커 **Main channel/chat**.
167
- 3. **검증**: 피커 description “Ready”; `hasStoredSecret('discord.token')` (값 미노출).
168
- **참고**: `/setting` → **Channels enabled** = 채널 모듈 on/off (`channels` 섹션).
52
+ 1. Check current route via status line, `/model`, or config.
53
+ 2. Change with `/model` and the model picker.
54
+ 3. Verify the selected route is reflected in config and the status line.
169
55
 
170
- ### 스킬 만들기 ("스킬 만들어줘")
56
+ ### Agent model
171
57
 
172
- 1. **확인**: `/skills` 목록; 우선순위 프로젝트 vs 글로벌 (§부록).
173
- 2. **변경**
174
- - **프로젝트**: `<cwd>/.mixdog/skills/<name>/SKILL.md` 생성 (frontmatter `name`, `description`).
175
- - **글로벌**: `<mixdogData>/skills/<name>/SKILL.md` (이 setup 스킬과 동일 트리).
176
- - 런타임 `addSkill` / TUI `skill-add` 프롬프트: **핸들러만 존재, 메뉴 진입 없음** → 파일 생성이 기본 사용자 경로.
177
- 3. **검증**: `/skills`에 표시; 트리거 문구를 `description`에 포함.
58
+ 1. Check `/agents` and the configured agent route.
59
+ 2. Change the target agent route through the agent picker.
60
+ 3. Verify the target agent reports the new route on the next run.
178
61
 
179
- ### 워크플로 팩 변경 ("워크플로 바꿔")
62
+ ### Workflow pack
180
63
 
181
- 1. **확인**: `/workflow` 또는 `/setting` **Workflow** active 표시.
182
- 2. **변경**: `/workflow` 선택 → `setWorkflow` (`config.workflow.active`).
183
- 3. **검증**: notice + active ✓.
64
+ 1. Check `/workflow` or `/setting` for the active workflow.
65
+ 2. Change with `/workflow`; this updates `config.workflow.active`.
66
+ 3. Verify the notice and active marker.
184
67
 
185
- ### 웹서치 모델 ("서치 모델 바꿔", "search provider")
68
+ ### Search model
186
69
 
187
- 1. **확인**: config `searchRoute` (`{ provider, model, effort? }`); 상태줄/`/setting`.
188
- 2. **변경**: `/search` 모델 피커 `store.setSearchRoute` (`route-pickers.mjs` `openSearchPicker`). 인자 없이 피커만 지원.
189
- 3. **검증**: config `searchRoute` 갱신; search 호출 해당 모델 사용.
70
+ 1. Check `searchRoute` in config and the status line.
71
+ 2. Change with `/search`; the picker updates `store.setSearchRoute`.
72
+ 3. Verify `searchRoute` and run a search call if needed.
190
73
 
191
- ### reasoning effort ("effort 올려", "high로")
74
+ ### Reasoning effort
192
75
 
193
- 1. **확인**: 상태줄 effort 표시.
194
- 2. **변경**: `/effort [level]` `store.setEffort` (현재 라우트/preset에 `effort` 기록). busy 중에는 거부됨.
195
- 3. **검증**: notice "Effort set to <level>"; config 해당 route `effort`.
76
+ 1. Check the status line effort value.
77
+ 2. Change with `/effort [level]`; busy sessions reject the change.
78
+ 3. Verify the notice and persisted route effort.
196
79
 
197
- ### Fast 모드 ("fast 켜줘")
80
+ ### Fast mode
198
81
 
199
- 1. **확인**: 상태줄 fast 표시.
200
- 2. **변경**: `/fast [on|off]` (인자 없으면 토글). busy 중 거부.
201
- 3. **검증**: notice; 다음 턴부터 적용.
82
+ 1. Check the status line fast-mode marker.
83
+ 2. Change with `/fast [on|off]` or toggle with `/fast`.
84
+ 3. Verify the notice; the next turn uses the updated mode.
202
85
 
203
- ### TUI 테마 ("테마 바꿔", "다크 테마")
86
+ ### Output style
204
87
 
205
- 1. **확인**: `store.getTheme()` / `/theme` 피커의 ✓ 표시.
206
- 2. **변경**: `/theme` (피커) 또는 `/theme <id>` → `setThemeSetting` **TUI 로컬 설정**, config `ui.theme`에 persist (`src/tui/theme.mjs`). 런타임 왕복 없음, 즉시 적용.
207
- 3. **검증**: 화면 팔레트 즉시 변경 + notice "Theme set to ...".
88
+ 1. Check `/style` or config.
89
+ 2. Change with `/style` and the picker.
90
+ 3. Verify the active style and run a short response if needed.
208
91
 
209
- ### 프로필 호칭·응답 언어 ("이름 불러줘", "영어로 답해")
92
+ ### Memory and recap
210
93
 
211
- 1. **확인**: `/setting` **Profile** 메타.
212
- 2. **변경**: `/profile` (또는 `/setting` → Profile) → title 입력 / 언어 선택 → `setProfile` (`settings-api.mjs`) — config `profile` 섹션 (`title`, `language`; 미지원 언어 id는 `system`으로 정규화, 목록 `PROFILE_LANGUAGES`).
213
- 3. **검증**: config `profile`; 프롬프트 주입은 `composeSystemPrompt` 경유 세션부터 반영.
94
+ 1. Inspect memory/recap status via commands or config.
95
+ 2. Update the requested setting only.
96
+ 3. Verify status output and, when relevant, run a small recall/recap check.
214
97
 
215
- ### 음성 — 채널 보이스 메시지 전사 ("보이스 켜줘")
98
+ ### MCP server
216
99
 
217
- 전용 `/voice` 명령 **없음** — `/channels` 허브의 **Voice** 행.
100
+ 1. Inspect `/mcp` or `mcpStatus()`.
101
+ 2. Edit config or use the supported MCP flow.
102
+ 3. Reconnect or restart as required.
103
+ 4. Verify status, exposed tools, and any expected auth state.
218
104
 
219
- 1. **확인**: `/channels` → **Voice** 행 meta (On/Off); config `voice.enabled`.
220
- 2. **변경**: **Voice** 행 ←/→ 또는 Enter → `toggleVoice` (`src/tui/lib/voice-setup.mjs`) — config `voice.enabled` persist + 미설치 whisper/ffmpeg 자동 설치 시퀀스 (진행/실패 notice 자체 출력, 설치 중 재토글 거부).
221
- 3. **검증**: Voice 행 meta 갱신; 켜지면 채널로 온 음성 메시지가 전사되어 처리됨.
105
+ ### Secrets
222
106
 
223
- ### autoclear ("자동 클리어", "idle 정리")
107
+ 1. Confirm which provider/account needs a secret.
108
+ 2. Use the provider login flow, secret store, or environment variable path.
109
+ 3. Verify presence only; never print the secret value.
224
110
 
225
- 1. **확인**: `/autoclear status` 또는 `/setting` → **Auto-clear**.
226
- 2. **변경**: `/autoclear [on|off|<duration>]` (예 `90m`, `1h`) 또는 피커 — `setAutoClear` (`settings-api.mjs`) → config `autoClear` (`enabled`, `idleMs`, provider별 `providerIdleMs`; 최소 1분, 빈 값 리셋=provider 기본).
227
- 3. **검증**: notice "autoclear on · idle <duration>"; idle 초과 시 제출 전 자동 클리어 동작.
111
+ ### Discord or channel configuration
228
112
 
229
- ### auto-compact ("자동 압축", "컴팩트 방식")
113
+ 1. Check config and runtime channel status.
114
+ 2. Update the requested channel setting.
115
+ 3. Restart/reconnect only when the channel implementation requires it.
116
+ 4. Verify channel presence and a non-secret status signal.
230
117
 
231
- 1. **확인**: `/setting` → **Auto-compact** (On/Off); **Compact type** 행은 `Fast-track (fixed)` 고정 표시 — 토글 불가(`_action:null`, `settings-picker.mjs`).
232
- 2. **변경**: `/setting` **Auto-compact** 행에서 ←/→ 또는 Enter 토글 — `applyCompaction({ auto })` → config `compaction.auto`. compact type은 UI에서 변경 불가(Fast-track 고정).
233
- 3. **검증**: `/setting` Auto-compact 메타 갱신; 컨텍스트 높을 때 자동 압축 발동 여부.
118
+ ### Skills
234
119
 
235
- ### 채널 백엔드 전환 ("텔레그램으로 바꿔", "디스코드로")
236
-
237
- 1. **확인**: `/setting` **Channel** 메타 (Discord/Telegram).
238
- 2. **변경**: `/setting` → **Channel** 행에서 ←/→ 순환(`cycleChannelBackend`) 활성 백엔드 전환; 자격/메인 대상은 바로 아래 **Setting** 행(=`/channels` 딥링크).
239
- 3. **검증**: 메타 표시; 해당 백엔드 토큰이 있으면 remote에서 그 채널로 응답.
240
-
241
- ### 시스템 셸 ("셸 바꿔", "bash로")
242
-
243
- TUI 피커 없음 (settings-api `setSystemShell`만 존재).
244
-
245
- 1. **확인**: 상태줄/`state.systemShell` (`source: auto|config`, `command`).
246
- 2. **변경**: config `shell` 키 편집 (`normalizeSystemShellConfig`) 후 재시작 — 셸 명령 경로 지정; 비우면 auto 감지.
247
- 3. **검증**: shell 툴 실행 시 해당 셸 사용.
248
-
249
- ### before-tool hooks ("툴 훅 규칙", "hook 추가")
250
-
251
- 1. **확인**: `/hooks` → 규칙 목록·최근 이벤트 (`hooksStatus`).
252
- 2. **변경**: `/hooks` 피커에서 규칙 관리 — 저장소: `<mixdogData>/hooks.json` — 표준 형태 `{ "hooks": { <Event>: [{ matcher, hooks:[...] }] } }`(우선) 또는 레거시 `{ "toolBefore":[...] }` 배열도 읽음 (`normalizeRules`/`isStandardConfig`, `src/standalone/hook-bus/config.mjs`). 파일 직접 편집도 가능(mtime 감지로 자동 리로드).
253
- 3. **검증**: `/hooks` 목록 반영; 대상 툴 호출 시 규칙 발동.
254
-
255
- ### 플러그인 ("플러그인 관리")
256
-
257
- 1. **확인**: `/plugins` 목록 (manifest·MCP script·skills 감지).
258
- 2. **변경**: `/plugins` 피커에서 활성/비활성 — 플러그인 루트의 `.mcp.json`/`skills/`가 자동 인식됨 (`plugin-mcp.mjs`).
259
- 3. **검증**: `/plugins` 상태 + 해당 플러그인 MCP/스킬 노출 여부.
260
-
261
- ### 스케줄 / 웹훅 ("스케줄 추가", "웹훅")
262
-
263
- 1. **확인**: `/schedules` / `/webhooks` (둘 다 `/channels` 허브의 섹션 딥링크).
264
- 2. **변경**: 해당 피커에서 추가/편집.
265
- - **스케줄 저장소 = PG 테이블 `scheduler.schedules`** (더 이상 `<mixdogData>/schedules/<n>/SCHEDULE.md` 파일 아님). 관리 API `saveSchedule/deleteSchedule/setScheduleEnabled/listSchedules` (`channel-admin.mjs`) → 스토어 `schedules-db.mjs`.
266
- - **필드**: 반복형은 `time`(5·6필드 cron) + 선택 `days`(cron 요일필드로 접힘: daily→`*`, weekday→`1-5`, weekend→`0,6`, `mon,wed,fri`/`1,3,5`→숫자; 못 매핑하면 에러) → `when_cron`. 1회성은 `at`(datetime) → `when_at`. `time`·`at`은 **택1**(스토어 XOR). `channel` 지정 시 `target=channel`+`channel_id`(이때 `model` 필수), 없으면 `target=session`. 본문(instructions)=`prompt`.
267
- - **레거시 마이그레이션**: 기존 `schedules/` 디렉터리는 스토어 첫 init 시 SCHEDULE.md들을 테이블로 1회 자동 임포트(같은 days→cron 접힘) 후 디렉터리를 `schedules.migrated`로 rename(삭제 안 함). 한 줄 요약 로그.
268
- - **웹훅 저장소 = PG 테이블 `webhooks.endpoints`** (더 이상 `<mixdogData>/webhooks/<n>/WEBHOOK.md` + `secret` 파일 아님). 관리 API `saveWebhook/deleteWebhook/setWebhookEnabled/listWebhooks` (`channel-admin.mjs`) → 스토어 `webhooks-db.mjs`(`upsertEndpoint/deleteEndpoint/setEndpointEnabled/listEndpoints`). 필드: `parser`(github·generic·stripe·sentry), 선택 `channel`(지정 시 `model` 필수)→`channel_id`, `secret`(미지정 시 랜덤 생성, 컬럼에 저장), 본문(instructions), `enabled`.
269
- - **웹훅 레거시 마이그레이션**: 기존 `webhooks/` 디렉터리는 스토어 첫 init 시 각 `WEBHOOK.md`+`secret`을 `upsertEndpoint`로 1회 자동 임포트 후 디렉터리를 **삭제**(rename 아님 — 사용자 선택). 부분 실패 시 디렉터리 보존·로그·다음 부팅 재시도. 옛 per-endpoint deliveries(중복제거 이력)는 임포트 안 함(리셋 허용).
270
- 3. **검증**: 피커 목록 반영; 스케줄은 다음 발동 시각 표시.
271
-
272
- ### 원격 세션 ("리모트 가져와")
273
-
274
- 1. **확인**: 상태줄 remote 표시.
275
- 2. **변경**: `/remote` = **강제 클레임(항상 ON)** — 다른 세션 좌석을 뺏어옴(그쪽은 자동 OFF). 끄기는 `/channels`에서.
276
- **시작 시 자동 클레임**: config `remote.autoStart: true` → 모든 세션이 부팅 때 자동으로 remote 클레임 (`mixdog --remote`와 동일 의미, 마지막에 뜬 세션이 좌석 소유).
277
- **토글형**: `/setting` → **Remote Runtime** ←/→ (`applyRemoteRuntime`) — 이 세션의 remote ON/OFF 토글(클레임과 달리 OFF도 가능).
278
- 3. **검증**: notice "Remote mode ON — this session owns remote now."
279
-
280
- ### 프로젝트 전환 ("프로젝트 바꿔", "cwd 변경")
281
-
282
- 1. **확인**: 상태줄 cwd; `/project` 피커 목록.
283
- 2. **변경**: `/project [경로]` (인자 없으면 피커) → cwd 전환 — 프로젝트별 `.mcp.json`/skills 자동 재로드·MCP 재연결, 마지막 cwd persist.
284
- 3. **검증**: 상태줄 cwd; `/mcp`에서 프로젝트 서버 반영.
285
-
286
- ### 업데이트 ("업데이트 확인")
287
-
288
- 1. **확인/변경**: `/update` → 버전 확인·업데이트 피커 (`openUpdatePicker`; 자동 체크 설정은 update settings).
289
- 2. **검증**: 피커에 현재/최신 버전 표시.
290
-
291
- ---
292
-
293
- ## 부록 — 경로·스키마 (압축)
294
-
295
- | 항목 | 위치 |
296
- |------|------|
297
- | Config | `<mixdogData>/mixdog-config.json` |
298
- | 템플릿 | `src/defaults/mixdog-config.template.json` |
299
- | Skills | `<cwd>/.mixdog/skills/<n>/SKILL.md` → `<mixdogData>/skills/<n>/SKILL.md` (프로젝트 우선) |
300
- | 프로젝트 MCP | `<cwd>/.mcp.json` |
301
- | Mixdog.md | 자동 프롬프트 로드 **없음** — skill/core memory로 대체 |
302
-
303
- **outputStyle** — 루트 문자열; id: `default`, `simple`, `minimal`, `extreme-minimal` (+ 별칭 `output-styles.mjs`).
304
-
305
- **memory** — `{ enabled, user, cycle1: { interval }, cycle2: { interval } }` (interval은 duration 문자열).
306
-
307
- **channels** — `{ promptInjection: { mode, targetPath } }`; 식별·백엔드는 `channel`, `channelsConfig`, `discord.applicationId` 등 (진단 로직 참조).
308
-
309
- **MCP config 예시 (shape만)**
310
- - stdio: `{ "type":"stdio", "command":"...", "args":[], "cwd":"<프로젝트 하위>", "env":{} }`
311
- - http: `{ "type":"http", "url":"https://...", "headers":{} }`
312
- - 비활성: `"enabled": false`
313
-
314
- **라우트 스키마** — `{ provider, model, effort? }`; 키: `workflowRoutes`, `agents`, `presets`, `maintenance`, `searchRoute`.
315
-
316
- **Secrets / env (`SECRET_ACCOUNTS`)** — config에 비밀 저장 금지; OS keychain.
317
-
318
- | account | env (예) |
319
- |---------|----------|
320
- | `discord.token` | `MIXDOG_DISCORD_TOKEN` |
321
- | `telegram.token` | `MIXDOG_TELEGRAM_TOKEN` |
322
- | `webhook.authtoken` | `MIXDOG_WEBHOOK_AUTHTOKEN` |
323
- | `agent.<provider>.apiKey` | provider별 표준 env 우선 (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, `DEEPSEEK_API_KEY`, `XAI_API_KEY` / `GROK_API_KEY`, `OPENCODE_API_KEY` 등 — `config.mjs`) |
324
- | `agent.openai.usageSessionKey`, `agent.opencode-go.authCookie` | (provider 피커 전용) |
325
-
326
- MCP 항목 `env` = 서버 자식 프로세스 환경 (keychain 아님).
327
-
328
- ---
120
+ 1. Check existing skills with `/skills` or `skillsStatus()`.
121
+ 2. Project skill path: `<cwd>/.mixdog/skills/<name>/SKILL.md`.
122
+ 3. Global skill path: `<mixdogData>/skills/<name>/SKILL.md`.
123
+ 4. Include frontmatter `name` and `description`; put trigger phrases in
124
+ `description`.
125
+ 5. Verify the skill appears in `/skills`.
329
126
 
330
- ## 규칙
127
+ ## Safety rules
331
128
 
332
- METHOD·POINTER만 유지. 확인되지 않은 키는 추측하지 말고 TODO. TUI에 없는 런타임 API(`addMcpServer`, `removeMcpServer`, `reconnectMcp`)는 **config 편집 + mixdog 재시작**으로 문서화한다.
129
+ - Do not expose secrets.
130
+ - Do not hard-code live deployment values into this file.
131
+ - Prefer the smallest config change that satisfies the request.
132
+ - Verify after every configuration change.
@@ -69,7 +69,7 @@ function readAgentConfig(dataDir) {
69
69
 
70
70
  const PROFILE_LANGUAGE_PROMPTS = Object.freeze({
71
71
  en: 'English',
72
- ko: 'Korean (한국어)',
72
+ ko: 'Korean',
73
73
  ja: 'Japanese (日本語)',
74
74
  'zh-Hans': 'Simplified Chinese (简体中文)',
75
75
  'zh-Hant': 'Traditional Chinese (繁體中文)',
@@ -129,7 +129,8 @@ function buildProfilePreferencesContent(dataDir) {
129
129
  const profile = normalizeProfileConfig(readAgentConfig(dataDir).profile);
130
130
  const lines = [];
131
131
  if (profile.title) {
132
- lines.push(`- Use "${profile.title}" when directly addressing the user (greetings, answers, questions); do not repeat it in routine progress updates or pre-tool preambles.`);
132
+ lines.push(`- User title: ${profile.title}.`);
133
+ lines.push(`- Use "${profile.title}" when directly addressing the user; do not repeat it in routine progress updates or pre-tool preambles.`);
133
134
  }
134
135
  const shell = process.platform === 'win32' ? 'powershell' : 'bash';
135
136
  lines.push(`- Shell environment: ${shell}. Write shell commands and scripts in ${shell} syntax unless the user specifies otherwise; keep commands, paths, symbols, and exact errors verbatim.`);
@@ -26,8 +26,8 @@ Content
26
26
  - Size budget: roughly TWICE the Simple style — per point about 2 rendered
27
27
  lines, whole report ~10–15 lines. Spend the extra room on evidence and
28
28
  context Simple would drop, not on longer sentences.
29
- - Use labels such as `바뀐 점`, `확인한 것`, and `남은 리스크/다음 단계`
30
- in final reports to structure the summary; skip labels on interim progress.
29
+ - Use labels such as `Changes`, `Verification`, and `Risks / next steps` in
30
+ final reports to structure the summary; skip labels on interim progress.
31
31
  - Collapse trivial tasks to a couple of sentences instead of forcing sections.
32
32
  - Synthesize agent or retrieval results; never forward raw reports, long file
33
33
  lists, tool traces, or session metadata.
@@ -17,6 +17,6 @@ characters.
17
17
  detail, and follow-ups unless one is the single most decisive fact.
18
18
  - No headings, bullets, numbered lists, labels, or sections — one plain sentence
19
19
  only, even when the request says "report" or "summary".
20
- - Preferred pattern: `<target> 변경 완료.`
20
+ - Preferred pattern: `<target> changed.`
21
21
  - Preserve only the single decisive path, command, symbol, or error verbatim,
22
22
  and only if it fits the limit.
@@ -20,7 +20,7 @@ Minimal — a very short summary: one or two sentences, nothing more.
20
20
  only what the change accomplishes.
21
21
  - No headings, bullets, numbered lists, labels, or sections — plain sentences
22
22
  only, even when the request says "report" or "summary".
23
- - Preferred pattern: `<target> 변경되었습니다. <verification> 통과 완료입니다.`
23
+ - Preferred pattern: `<target> changed. <verification> passed.`
24
24
  - If verification was not run, say the change is done and verification was not
25
25
  run.
26
26
  - Preserve only the single decisive path, command, symbol, API name, code, or
@@ -31,9 +31,8 @@ result, do not narrate or explain the change.
31
31
  multi-line list items — never a dense wall of text. If a point runs past one
32
32
  line, cut the elaboration — detail beyond key phrase + one clause belongs to
33
33
  Default.
34
- - Final handoffs may use labels like `바뀐 점`, `확인한 것`,
35
- `남은 리스크/다음 단계` for Korean-facing profiles (plain English labels in
36
- English threads); do not label interim progress.
34
+ - Final handoffs may use labels like `Changes`, `Verification`, and
35
+ `Risks / next steps`; do not label interim progress.
37
36
  - Synthesize agent or retrieval results; never forward raw reports, long file
38
37
  lists, tool traces, or session metadata.
39
38
  - Do not hide blockers, failed verification, or required follow-up — state
@@ -13,7 +13,8 @@ Tools: grep/find/glob/code_graph ONLY. `read`/`list` are forbidden with no
13
13
  exception; grep/code_graph lines already carry the `path:line` answer.
14
14
 
15
15
  Turn 1 is the whole search in ONE message: grep `pattern[]` with 3-6 code-token
16
- variants, find name fragments, and code_graph symbol_search for identifiers. A
16
+ variants, code_graph symbol_search for identifiers, and (for unknown/broad
17
+ targets) find `query[]` with path/name fragments from multiple tokens. A
17
18
  single-pattern or single-tool first turn is a defect.
18
19
 
19
20
  Broad grep must use `output_mode:"files_with_matches"`. Use
@@ -23,18 +24,25 @@ Broad grep must use `output_mode:"files_with_matches"`. Use
23
24
  Translate natural/non-English queries to probable English identifiers first;
24
25
  grep non-ASCII only for quoted literal strings.
25
26
 
26
- Scope = session working directory. Omit `path` or use only paths returned
27
- earlier in this session. Never invent directories; after zero hits change
28
- TOKENS/scope, not wording or guessed paths.
27
+ Scope = session working directory. Omit `path` only for a verified project cwd;
28
+ otherwise use only paths returned earlier in this session. If the query or plan
29
+ names an unverified path/name fragment (`src`, `lib`, package/file stem, etc.),
30
+ run `find` for it before any `grep`/`glob` using that path; only an exact
31
+ returned path may be passed to `grep`/`glob`. Never use `path:"."` with guessed
32
+ globs (`src/**`, `lib/**`, etc.) to mask misses, especially from a home or
33
+ machine-wide cwd. Never invent directories; after zero hits change TOKENS/scope,
34
+ not wording or guessed paths.
29
35
 
30
36
  Hit test is mechanical: any `path:line` containing a query token or obvious
31
37
  synonym is an anchor; generic-only words (schema/handler/config/resolver…)
32
38
  without a specific token are zero. code_graph `path:line` hits are anchors —
33
39
  never re-locate them with grep.
34
40
 
35
- Rule zero after every tool result: any matching anchor → answer NOW (mark weak
36
- anchors `?`); zero → one more batch if budget remains. Further searching after
37
- a matching anchor is a defect.
41
+ Rule zero after every tool result: any specific-token anchor → STOP and answer
42
+ NOW (mark weak anchors `?`), this is your final turn; zero → one more batch if
43
+ budget remains. Turns 2-3 exist SOLELY as zero-hit recovery (previous turn
44
+ matched zero specific tokens); a turn spent to confirm, refine, or upgrade an
45
+ anchor you already hold is a defect.
38
46
 
39
47
  Turns: max 3, expected 1; start tool messages with `turn N/3`. Turns 2-3 are
40
48
  miss recovery only and must change tokens or scope.
@@ -1,5 +1,9 @@
1
1
  # General
2
2
 
3
+ - Identity: You are Mixdog, the coding-agent CLI/TUI assistant running this session;
4
+ if asked who you are, answer as Mixdog/the current coding agent, not as a generic
5
+ OpenAI or ChatGPT assistant.
6
+ - Product: Mixdog is a coding-agent CLI/TUI for multi-provider agent workflows.
3
7
  - Preambles are optional: one short sentence only when useful; no direct names,
4
8
  honorifics, headings, labels, or routine lookup narration.
5
9
  - Destructive/hard-to-reverse actions require explicit confirmation.
@@ -21,15 +21,22 @@ const MIXDOG_SLOW_TOOL_TRACE_NAMES = new Set(
21
21
  .filter(Boolean)
22
22
  );
23
23
 
24
- function traceAgentLoop({ sessionId, iteration, sendMs, messageCount, bodyBytesEst }) {
25
- if (process.env.MIXDOG_AGENT_TRACE_VERBOSE !== '1') return;
24
+ function traceAgentLoop({ sessionId, iteration, sendMs, messageCount, bodyBytesEst, agent = null }) {
25
+ // Two emit modes, no behavior change either way:
26
+ // VERBOSE=1 → full loop row incl. body_bytes_est (payload serialized).
27
+ // TIMING=1 → lightweight send-latency attribution for high-fanout
28
+ // benches; bodyBytesEst is skipped upstream so measuring
29
+ // the send does not perturb it (body_bytes_est → null).
30
+ if (process.env.MIXDOG_AGENT_TRACE_VERBOSE !== '1'
31
+ && process.env.MIXDOG_AGENT_TRACE_TIMING !== '1') return;
26
32
  appendAgentTrace({
27
33
  sessionId,
28
34
  iteration,
29
35
  kind: 'loop',
36
+ agent: agent || null,
30
37
  send_ms: sendMs,
31
38
  message_count: messageCount,
32
- body_bytes_est: bodyBytesEst,
39
+ body_bytes_est: bodyBytesEst ?? null,
33
40
  });
34
41
  }
35
42
 
@@ -206,6 +213,11 @@ function _redactLogText(text) {
206
213
 
207
214
  function classifyToolFailure(resultText, toolName) {
208
215
  const text = String(resultText ?? '').toLowerCase();
216
+ if (/\[shell-tool-failed\]/i.test(String(resultText ?? ''))) return 'tool-call/failure';
217
+ if (/\[shell-run-failed\]/i.test(String(resultText ?? ''))) {
218
+ if (/timeout|timed out|aborted|interrupted/.test(text)) return 'timeout/abort';
219
+ return 'command-exit';
220
+ }
209
221
  if (/requires either|invalid arguments|unknown parameter|must be|schema|expected|required|old_string is .*>=/.test(text)) return 'schema/args';
210
222
  if (/not in allow-list|not allowed/.test(text)) return 'permission';
211
223
  if (String(toolName || '') === 'shell' || /^\s*\[exit code:\s*\d+\]/i.test(String(resultText ?? ''))) return 'command-exit';
@@ -46,7 +46,7 @@ export const MAINTENANCE_SLOTS = Object.freeze(['explore', 'memory']);
46
46
  export const PROFILE_LANGUAGES = Object.freeze([
47
47
  { id: 'system', label: 'System (locale)', prompt: null },
48
48
  { id: 'en', label: 'English', prompt: 'English' },
49
- { id: 'ko', label: '한국어', prompt: 'Korean (한국어)' },
49
+ { id: 'ko', label: 'Korean', prompt: 'Korean' },
50
50
  { id: 'ja', label: '日本語', prompt: 'Japanese (日本語)' },
51
51
  { id: 'zh-Hans', label: '中文(简体)', prompt: 'Simplified Chinese (简体中文)' },
52
52
  { id: 'zh-Hant', label: '中文(繁體)', prompt: 'Traditional Chinese (繁體中文)' },