From 82bda7409eb808173da36077c1b0415264ac53d3 Mon Sep 17 00:00:00 2001
From: kim
Date: Sat, 9 May 2026 11:35:33 +0900
Subject: [PATCH] v.2.6.1
---
.../users/cherry/workspace/prompts/AGENTS.md | 2 +-
.../cherry/workspace/prompts/IDENTITY.md | 2 +-
.../users/cherry/workspace/prompts/SELF.md | 36 +-
.../users/cherry/workspace/prompts/TOOLS.md | 4 +-
.../users/cherry/workspace/prompts/USER.md | 2 +-
.../jasmine/workspace/memory/2026-05-04.md | 124 ---
.../jasmine/workspace/memory/2026-05-05.md | 4 -
.../users/jasmine/workspace/prompts/AGENTS.md | 2 +-
.../jasmine/workspace/prompts/IDENTITY.md | 2 +-
.../users/jasmine/workspace/prompts/SELF.md | 36 +-
.../users/jasmine/workspace/prompts/TOOLS.md | 4 +-
.../users/jasmine/workspace/prompts/USER.md | 2 +-
.../281ba0e8-211c-4ab7-9574-1b80aeebd76c.json | 152 ++++
.../b39014a9-3165-4f1c-b5bd-674dd88729f8.json | 252 ++++++
.../fb0428e2-9c4b-44b2-9f62-7b36a9ee5479.json | 29 +-
.smallclaw/users/papa/workspace/add_terms.py | 43 -
.../users/papa/workspace/dental_dict.db | Bin 32768 -> 0 bytes
.../users/papa/workspace/final_insert.py | 141 ----
.../users/papa/workspace/final_insert_v2.py | 143 ----
.../users/papa/workspace/insert_terms.py | 136 ----
.../users/papa/workspace/memory/2026-05-08.md | 144 ++++
.../users/papa/workspace/memory/2026-05-09.md | 78 ++
.../users/papa/workspace/populate_db.py | 119 ---
.../users/papa/workspace/prompts/AGENTS.md | 2 +-
.../users/papa/workspace/prompts/IDENTITY.md | 2 +-
.../users/papa/workspace/prompts/SELF.md | 36 +-
.../users/papa/workspace/prompts/SOUL.md | 1 +
.../users/papa/workspace/prompts/TOOLS.md | 9 +-
.../users/papa/workspace/prompts/USER.md | 2 +-
README.md | 769 +++++++++---------
src/config/config.ts | 3 +-
src/gateway/background-task-runner.ts | 84 +-
src/gateway/cron-scheduler.ts | 31 +-
src/gateway/heartbeat-runner.ts | 22 +-
src/gateway/server-v2.ts | 123 +--
src/gateway/task-store.ts | 5 +-
src/providers/factory.ts | 9 +-
src/tools/sqlite.ts | 2 +-
src/types.ts | 3 +-
web-ui/index.html | 254 +++++-
workspace/dental_dict.db | Bin 32768 -> 0 bytes
workspace/dental_dictionary.csv | 123 ---
42 files changed, 1576 insertions(+), 1361 deletions(-)
delete mode 100644 .smallclaw/users/jasmine/workspace/memory/2026-05-04.md
delete mode 100644 .smallclaw/users/jasmine/workspace/memory/2026-05-05.md
create mode 100644 .smallclaw/users/papa/sessions/281ba0e8-211c-4ab7-9574-1b80aeebd76c.json
create mode 100644 .smallclaw/users/papa/sessions/b39014a9-3165-4f1c-b5bd-674dd88729f8.json
delete mode 100644 .smallclaw/users/papa/workspace/add_terms.py
delete mode 100644 .smallclaw/users/papa/workspace/dental_dict.db
delete mode 100644 .smallclaw/users/papa/workspace/final_insert.py
delete mode 100644 .smallclaw/users/papa/workspace/final_insert_v2.py
delete mode 100644 .smallclaw/users/papa/workspace/insert_terms.py
create mode 100644 .smallclaw/users/papa/workspace/memory/2026-05-08.md
create mode 100644 .smallclaw/users/papa/workspace/memory/2026-05-09.md
delete mode 100644 .smallclaw/users/papa/workspace/populate_db.py
delete mode 100644 workspace/dental_dict.db
delete mode 100644 workspace/dental_dictionary.csv
diff --git a/.smallclaw/users/cherry/workspace/prompts/AGENTS.md b/.smallclaw/users/cherry/workspace/prompts/AGENTS.md
index 326b25d..50a994a 100644
--- a/.smallclaw/users/cherry/workspace/prompts/AGENTS.md
+++ b/.smallclaw/users/cherry/workspace/prompts/AGENTS.md
@@ -46,7 +46,7 @@ Keep environment-specific notes in `TOOLS.md`.
## After Completing a Task
1. Move finished output files (`.png`, `.py`, `.ps1`, `.html`, etc.) to the `processed/` folder.
-2. Use `shell("mv processed/")` or `shell("move processed\\")` on Windows.
+2. Use `shell("mv processed/")`.
3. This keeps the workspace root clean for new tasks.
## Skills (Coming Soon)
diff --git a/.smallclaw/users/cherry/workspace/prompts/IDENTITY.md b/.smallclaw/users/cherry/workspace/prompts/IDENTITY.md
index 292ae07..570fda2 100644
--- a/.smallclaw/users/cherry/workspace/prompts/IDENTITY.md
+++ b/.smallclaw/users/cherry/workspace/prompts/IDENTITY.md
@@ -3,7 +3,7 @@
- **Name:** SmallClaw (also called "Claw")
- **Working with:** [ Users Name ]
- **Role:** Local AI agent — personal assistant, researcher, coder, automator
-- **Runtime:** Ollama native tools, TypeScript/Node.js gateway on Windows
+- **Runtime:** Ollama native tools, TypeScript/Node.js gateway on Linux
- **Access:** Full file system, shell, browser automation, desktop control
- **Personality:** Direct, resourceful, occasionally dry. Gets things done.
- **Language:** Responds in the user's language (Korean/English)
diff --git a/.smallclaw/users/cherry/workspace/prompts/SELF.md b/.smallclaw/users/cherry/workspace/prompts/SELF.md
index 75038bc..2d0543d 100644
--- a/.smallclaw/users/cherry/workspace/prompts/SELF.md
+++ b/.smallclaw/users/cherry/workspace/prompts/SELF.md
@@ -8,11 +8,11 @@ architecture, diagnose errors, or reason about your own source code.
## Identity
- **Project:** SmallClaw
-- **Root:** `D:\smallclaw`
+- **Root:** `~/homeclaw`
- **Runtime:** Node.js + TypeScript, compiled to `dist/` via `npm run build`
- **Gateway:** Express + WebSocket server on `http://127.0.0.1:18789`
- **Model:** Ollama (primary model configured in Settings → Models)
-- **Platform:** Windows (but code is cross-platform)
+- **Platform:** Linux
---
@@ -24,14 +24,14 @@ architecture, diagnose errors, or reason about your own source code.
| `server-v2.ts` | Main entry point. Builds tools, handles all chat turns (`handleChat`), assembles system prompt, routes tool calls |
| `telegram-channel.ts` | Telegram bot. Long-polling, file browser, command handlers |
| `task-runner.ts` | Sliding-context multi-step task engine. Each step: model picks ONE action |
-| `task-store.ts` | Persists task records to `.smallclaw/tasks/` as JSON |
+| `task-store.ts` | Persists task records to `~/homeclaw/.smallclaw/tasks/` as JSON |
| `background-task-runner.ts` | Manages running tasks in the background while chat is free |
| `session.ts` | In-memory + disk session history. `addMessage`, `getHistory`, `clearHistory` |
| `orchestrator.ts` | Legacy multi-agent orchestrator (plan → execute → verify) |
| `cron-scheduler.ts` | Time-based job runner. Fires `handleChat` on schedule |
| `heartbeat-runner.ts` | Periodic self-check. Runs against workspace on interval |
| `memory-manager.ts` | Compacts and manages workspace memory files |
-| `skills-manager.ts` | Loads/enables/disables skills from `.smallclaw/skills/` |
+| `skills-manager.ts` | Loads/enables/disables skills from `~/homeclaw/.smallclaw/skills/` |
| `mcp-manager.ts` | Model Context Protocol server connections |
| `browser-tools.ts` | Playwright-based browser automation tool implementations |
| `desktop-tools.ts` | Windows desktop automation (screenshot, click, type, etc.) |
@@ -52,7 +52,7 @@ architecture, diagnose errors, or reason about your own source code.
| `files.ts` | `read`, `write`, `edit`, `list`, `delete`, `rename`, `copy`, `mkdir`, `stat`, `append`, `apply_patch` |
| `shell.ts` | `shell` — run arbitrary shell commands (with safety guards) |
| `web.ts` | `web_search`, `web_fetch` |
-| `memory.ts` | `memory_search`, `memory_write` — semantic memory in `.smallclaw/memory/` |
+| `memory.ts` | `memory_search`, `memory_write` — semantic memory in `~/homeclaw/.smallclaw/memory/` |
| `self-update.ts` | `self_update` — triggers `self-update.bat`, rebuilds and restarts gateway |
| `skills.ts` | `skill_list`, `skill_search`, `skill_install`, `skill_remove`, `skill_exec` |
| `time.ts` | `time_now` |
@@ -78,10 +78,10 @@ architecture, diagnose errors, or reason about your own source code.
### `src/config/` — Configuration
| File | What it does |
|---|---|
-| `config.ts` | Config loader/saver. `getConfig()` singleton. Reads `.smallclaw/config.json` |
+| `config.ts` | Config loader/saver. `getConfig()` singleton. Reads `~/homeclaw/.smallclaw/config.json` |
| `soul-loader.ts` | Loads soul/memory for legacy system prompt builder |
-| `soul.md` | Default soul template (overridden by `workspace/SOUL.md`) |
-| `memory.md` | Default memory template |
+| `soul.md` | Default soul template (overridden by `~/homeclaw/.smallclaw/users/cherry/workspace/prompts/SOUL.md`) |
+| `memory.md` | Default memory template (overridden by `~/homeclaw/.smallclaw/users/cherry/workspace/prompts/MEMORY.md`) |
### `src/skills/` — Skills System
| File | What it does |
@@ -101,8 +101,8 @@ architecture, diagnose errors, or reason about your own source code.
```
npm run build → compiles src/ → dist/ (TypeScript → JavaScript)
npm start → runs dist/gateway/server-v2.js
-start-smallclaw.bat → npm run build && npm start (Windows)
-self-update.bat → git pull + npm run build + restart gateway
+npm start → runs dist/gateway/server-v2.js (start via pm2 or shell)
+self-update → git pull + npm run build + restart gateway
```
- TypeScript config: `tsconfig.json` at root
@@ -115,11 +115,11 @@ self-update.bat → git pull + npm run build + restart gateway
| Location | Purpose |
|---|---|
-| `.smallclaw/config.json` | Main config (models, tools, channels, workspace path) |
-| `.smallclaw/cron/jobs.json` | Cron job definitions |
-| `.smallclaw/skills/` | Installed skills |
-| `.smallclaw/tasks/` | Persisted task records (JSON per task) |
-| `.smallclaw/pending-repairs/` | Pending self-repair patches awaiting approval |
+| `~/homeclaw/.smallclaw/config.json` | Main config (models, tools, channels, workspace path) |
+| `~/homeclaw/.smallclaw/cron/jobs.json` | Cron job definitions |
+| `~/homeclaw/.smallclaw/skills/` | Installed skills |
+| `~/homeclaw/.smallclaw/tasks/` | Persisted task records (JSON per task) |
+| `~/homeclaw/.smallclaw/pending-repairs/` | Pending self-repair patches awaiting approval |
| `workspace/` | User workspace — SOUL, IDENTITY, USER, MEMORY, AGENTS, TOOLS, SELF |
| `workspace/memory/` | Daily memory logs (`YYYY-MM-DD.md`) |
| `gateway.log` | Stdout gateway log |
@@ -177,7 +177,7 @@ TaskRunner loop (task-runner.ts):
↓
On error: TaskState.error set, status = 'failed'
→ error + stack captured in task record
- → task stored in .smallclaw/tasks/.json
+ → task stored in ~/homeclaw/.smallclaw/tasks/.json
```
---
@@ -188,7 +188,7 @@ When something breaks, check in this order:
1. **`gateway.err.log`** — raw stderr from the gateway process
2. **`gateway.log`** — stdout including `[Telegram]`, `[Task]`, `[CronScheduler]` prefixed lines
-3. **`.smallclaw/tasks/.json`** — `error` field on a failed task record
+3. **`~/homeclaw/.smallclaw/tasks/.json`** — `error` field on a failed task record
4. **`workspace/memory/YYYY-MM-DD.md`** — daily log of what happened during the session
Stack traces in logs include the compiled `dist/` path — map back to `src/` by same relative path.
@@ -209,7 +209,7 @@ Stack traces in logs include the compiled `dist/` path — map back to `src/` by
## Important Constraints
- **Never edit `dist/` directly** — it gets overwritten on rebuild. Always edit `src/`.
-- **Always rebuild after source changes** — `npm run build` from `D:\smallclaw`
+- **Always rebuild after source changes** — `npm run build` from `~/homeclaw`
- **Tool path restrictions** — `read`/`write`/`edit` tools are locked to `workspace/`. Use `read_source` to read `src/` files.
- **Model context is ~8K tokens** — system prompt + tools + history all compete for space. Keep workspace files concise.
- **One Ollama instance** — parallel inference on 4B models causes degradation. The `isModelBusy` guard prevents this.
diff --git a/.smallclaw/users/cherry/workspace/prompts/TOOLS.md b/.smallclaw/users/cherry/workspace/prompts/TOOLS.md
index dd04ae9..add944e 100644
--- a/.smallclaw/users/cherry/workspace/prompts/TOOLS.md
+++ b/.smallclaw/users/cherry/workspace/prompts/TOOLS.md
@@ -4,8 +4,8 @@ Tool rules are injected dynamically by the gateway based on context (web, browse
## Environment
-- **Platform:** Windows 11
-- **Workspace:** D:\smallclaw\workspace
+- **Platform:** Linux
+- **Workspace:** ~/homeclaw/.smallclaw/users/cherry/workspace
- **Model:** Ollama (local)
- **Gateway:** http://127.0.0.1:18789
diff --git a/.smallclaw/users/cherry/workspace/prompts/USER.md b/.smallclaw/users/cherry/workspace/prompts/USER.md
index 36dc06f..e209b3c 100644
--- a/.smallclaw/users/cherry/workspace/prompts/USER.md
+++ b/.smallclaw/users/cherry/workspace/prompts/USER.md
@@ -7,7 +7,7 @@
## identity
- Name: [ Users Name ]
-- Platform: Windows 11
+- Platform: Linux
- Stack: TypeScript / Node.js
- Version control: Git
diff --git a/.smallclaw/users/jasmine/workspace/memory/2026-05-04.md b/.smallclaw/users/jasmine/workspace/memory/2026-05-04.md
deleted file mode 100644
index 1cefffc..0000000
--- a/.smallclaw/users/jasmine/workspace/memory/2026-05-04.md
+++ /dev/null
@@ -1,124 +0,0 @@
-[17:00:25] **User**: hi
-[17:00:27] **SmallClaw**: Hi there! How can I help you today?
-[17:00:40] **User**: who am i?
-[17:00:44] **SmallClaw**: You are [ Users Name ], a developer working on Windows 11 with a TypeScript and Node.js stack.
-[17:05:49] **User**: who am i?
-[17:05:51] **SmallClaw**: You are [ Users Name ], a developer working on a Windows 11 machine with a TypeScript and Node.js stack. According to my records, you also have the `python-pptx` library installed for presentation tasks.
-[17:06:11] **User**: who am i?
-[17:06:13] **SmallClaw**: You are [ Users Name ], a developer using Windows 11 with a TypeScript and Node.js stack. My records also show you've been working with the `python-pptx` library for PowerPoint tasks.
-[17:10:16] **User**: 내 이름은 kim 이야.
-[17:10:19] **SmallClaw**: 반갑습니다, Kim님. 기억해 두겠습니다. 무엇을 도와드릴까요?
-[17:10:43] **User**: 내 이름은 현숙 이야.
-[17:10:46] **SmallClaw**: 네, 현숙님. 이름을 현숙으로 수정하여 기억하겠습니다. 무엇을 도와드릴까요?
-[17:11:03] **User**: 내가 누구지?
-[17:11:05] **SmallClaw**: 현숙님입니다. Windows 11 환경에서 TypeScript와 Node.js로 개발하시는 개발자이시죠.
-[17:18:50] **User**: sork snrnwl?
-[17:18:52] **SmallClaw**: 현숙님입니다. (영문 키보드 상태로 '내가 누구지?'라고 입력하셨네요.) 더 궁금한 점 있으신가요?
-[17:19:21] **User**: 나는 누구야?
-[17:19:23] **SmallClaw**: 현숙님입니다. Windows 11에서 TypeScript와 Node.js를 사용하시는 개발자이시죠. 무엇을 도와드릴까요?
-[17:19:57] **User**: 내 이름은 kim 이야.
-[17:20:01] **SmallClaw**: Kim님, 반갑습니다. 무엇을 도와드릴까요?
-[17:20:13] **User**: 내가 누구지?
-[17:20:15] **SmallClaw**: Kim님입니다. Windows 11 환경에서 TypeScript와 Node.js를 사용하시는 개발자이시죠. 무엇을 도와드릴까요?
-[17:20:34] **User**: 나는 누구지?
-[17:20:35] **SmallClaw**: Kim님입니다. Windows 11 환경에서 TypeScript와 Node.js를 사용하시는 개발자이시죠. 무엇을 도와드릴까요?
-[17:55:47] **User**: 나는 누구지?
-[17:55:50] **SmallClaw**: 현숙 님입니다. 이전에 성함을 Kim에서 현숙으로 업데이트해 드린 기록이 있습니다.
-[17:56:19] **User**: 이름을 jasmine으로 변경하자.
-[17:56:23] **SmallClaw**: 네, 이름을 jasmine으로 변경했습니다. 이제 jasmine 님이라고 불러드릴게요.
-[17:56:35] **User**: 내가 누구지?
-[17:56:36] **SmallClaw**: jasmine 님입니다. 방금 성함을 현숙에서 jasmine으로 변경해 드렸습니다.
-[17:59:49] **User**: 투자 연금에 대하여 간략히 알려줘.
-[17:59:51] **SmallClaw**: 투자 연금은 노후 자금 마련을 위해 주식, 채권 등 수익성 자산에 투자하는 연금 상품입니다. 대표적으로 **연금저축펀드**와 **IRP(개인형 퇴직연금)**가 있으며, 납입 시 세액공제 혜택을 받고 운용 수익에 대해서는 인출 시까지 과세가 이연되는 장점이 있습니다.
-[18:00:25] **User**: 수익율은 어때?
-[18:00:27] **SmallClaw**: 투자 연금의 수익률은 선택하는 투자 상품(펀드, ETF 등)과 시장 상황에 따라 천차만별입니다. 원금 보장형 상품은 연 3~4% 수준의 낮은 수익률을 보이지만, 주식형 상품은 시장 상승기에 따라 연 10% 이상의 높은 수익률을 기대할 수 있는 반면 손실 위험도 존재합니다. 구체적인 최근 시장 수익률 데이터를 확인해 드릴까요?
-[18:01:13] **User**: 응
-[18:01:28] **SmallClaw**: 2024년 상반기 기준으로 증권사 연금저축펀드나 IRP에서 미국 지수(S&P500, 나스닥100)에 투자했을 경우 **약 15~23%**의 높은 수익률을 기록했습니다. 반면, 은행이나 보험사의 원리금 보장형 상품은 **연 3~4%** 수준으로 안정적이지만 상대적으로 낮습니다.
-
-특히 AI와 반도체 테마 ETF는 **30% 이상** 급등하기도 했으나, 시장 상황에 따라 변동성이 크다는 점을 유의해야 합니다. 관심 있는 특정 종목이나 투자 성향이 있으신가요?
-[18:02:50] **User**: 지난 대화가 어디론가 가고 없네?
-[18:02:53] **SmallClaw**: 이전 대화 내용이 보이지 않아 당황스러우시겠네요. 제가 기억하는 Kim님의 정보(Windows 11, TypeScript/Node.js 스택 등)는 그대로 유지되고 있으니, 필요한 작업이 있다면 바로 말씀해 주세요. 어떤 대화 내용을 찾으시나요?
-[18:03:34] **User**: 내가 누구지?
-[18:03:35] **SmallClaw**: Kim님입니다. Windows 11 환경에서 TypeScript와 Node.js를 사용하시는 개발자이시죠. 무엇을 도와드릴까요?
-[20:35:10] **User**: who am i?
-[20:35:16] **SmallClaw**: You are jasmine. You're working on a Windows 11 machine with a TypeScript and Node.js stack.
-[20:35:37] **User**: what have i done last time?
-[20:35:53] **SmallClaw**: Last time, you updated your name to **jasmine** and we discussed **investment pensions**, specifically looking into the returns of pension savings funds and IRPs for the first half of 2024. You also asked about your identity and missing conversation history.
-[20:36:25] **User**: can you show me the chat?
-[20:37:11] **SmallClaw**: Here is the chat history from today, including your name changes and our discussion on investment pensions:
-
-- **17:10**: You introduced yourself as **Kim**.
-- **17:11**: You changed your name to **현숙**.
-- **17:20**: You changed it back to **Kim**.
-- **17:56**: You updated your name to **jasmine**.
-
-[20:38:57] **User**: hey who am i?
-[20:38:59] **SmallClaw**: You are jasmine. You're a developer working with TypeScript and Node.js on Windows 11.
-[21:08:49] **User**: 연금보험에 대하여 알려줘.
-[21:08:52] **SmallClaw**: 연금보험은 노후 생활 자금 마련을 위해 일정 기간 보험료를 납입하고, 정해진 시점부터 연금을 수령하는 상품입니다. 크게 세제 혜택이 있는 '연금저축보험'과 비과세 혜택이 있는 '일반 연금보험'으로 나뉩니다. 구체적인 상품 비교나 추천이 필요하시면 말씀해 주세요.
-[21:10:28] **User**: 이매일 확인
-[21:10:32] **SmallClaw**: 최근 수신된 이메일 3건입니다. YouTube Premium 관련 안내와 결제 수단 업데이트 요청 메일이 있습니다. 구체적으로 읽어보고 싶은 메일이 있으신가요?
-[21:26:24] **User**: 안녕?
-[21:26:27] **SmallClaw**: 반가워요! 현숙님, 무엇을 도와드릴까요?
-[21:29:08] **User**: 안정적인 주식투자 방법 알려줘.
-[21:29:24] **SmallClaw**: 안정적인 주식 투자를 위해서는 **'잃지 않는 원칙'**이 가장 중요합니다.
-
-1. **지수 추종 ETF 활용**: 개별 종목의 위험을 피하기 위해 S&P 500(VOO, SPY)이나 나스닥 100(QQQ) 같은 시장 전체에 투자하는 ETF를 추천합니다.
-2. **적립식 분할 매수**: 한 번에 몰빵하지 않고 매달 일정 금액을 기계적으로 매수하여 평균 단가를 낮추는 전략이 안전합니다.
-3. **우량주와 배당주**: 각 산업의 1등 기업이나 꾸준히 배당을 주는 기업에 투자해 하락장에서도 현금 흐름과 방어력을 확보하세요.
-4.
-[21:30:10] **User**: 혹시 내가 매일 계정이 있나?
-[21:30:13] **SmallClaw**: 현재 등록된 이메일 계정은 다음과 같습니다:
-
-1. **applecherry** (kim@applecherry.net)
-2. **evangel** (kim@evangel.xyz)
-3. **daum** (kimsgms@hanmail.net)
-
-이 중 확인하고 싶은 계정이 있으신가요? 최근 메일 목록을 불러올 수도 있습니다.
-[21:32:24] **User**: 러아ㅣㄴ머리ㅏㅇㄴㅁ
-[21:32:27] **SmallClaw**: 무슨 말씀이신지 잘 모르겠어요. 도움이 필요하시면 구체적으로 말씀해 주세요!
-[21:33:04] **User**: 채팅 기록이 없어졌네...
-[21:33:06] **SmallClaw**: 채팅 기록이 보이지 않아 당황스러우시겠어요. 시스템 오류나 세션 초기화 때문일 수 있는데, 제가 도와드릴 수 있는 부분이 있는지 확인해 보겠습니다. 어떤 내용을 찾고 계셨나요?
-[21:36:39] **User**: 머야...
-[21:36:41] **SmallClaw**: 당황하지 마세요! 제가 여기 있습니다. 혹시 이전에 하던 작업이나 찾으시던 정보가 있다면 말씀해 주세요. 바로 도와드릴게요.
-[21:38:03] **User**: ㄹㅇㄴㅁㄹㄴㅁ
-[21:38:05] **SmallClaw**: 키보드를 마구 치신 것 같네요! 혹시 장난치시는 건가요, 아니면 정말로 도움이 필요하신 상황인가요? 말씀해 주시면 바로 도와드릴게요.
-[21:40:26] **User**: 하이
-[21:40:27] **SmallClaw**: 반가워요, 현숙님! 무엇을 도와드릴까요? 무엇이든 말씀만 하세요. 🦞
-[21:40:45] **User**: 주식 투자 잘 할 수 있을까?
-[21:40:48] **SmallClaw**: 주식 투자는 철저한 분석과 원칙만 있다면 충분히 잘하실 수 있어요! 원하시는 기업의 실적 분석이나 최근 시장 트렌드 조사가 필요하시면 제가 바로 도와드릴까요? 🦞
-[21:41:07] **User**: 삼성전자 어때?
-[21:41:24] **SmallClaw**: 삼성전자는 현재 AI 반도체(HBM4)와 2나노 공정 기술 확보를 통해 재도약을 준비하는 중요한 시점에 있습니다. 2026년에는 실적이 50~60조 원대까지 회복될 것이라는 긍정적 전망이 많지만, 기술 격차 유지 여부가 주가의 핵심 변수가 될 것으로 보입니다. 🦞
-[22:17:15] **User**: 내 매일 계정이 있나?
-[22:17:20] **SmallClaw**: 네, 현재 연결된 이메일 계정이 있습니다. 최근 YouTube Premium 관련 안내 메일들이 수신된 것을 확인했습니다. 🦞
-[22:17:49] **User**: 내 매일 계정이 있나?
-[22:17:56] **SmallClaw**: 네, 현재 이메일 계정이 연결되어 있으며 최근 YouTube Premium에서 온 메일을 포함한 수신함 목록을 확인했습니다. 어떤 작업을 도와드릴까요?
-[22:18:14] **User**: 리스트
-[22:18:18] **SmallClaw**: 최근 수신된 이메일 3건입니다.
-
-1. **YouTube의 PIP 모드 사용에 관한 업데이트** (4/30)
-2. **YouTube Premium 결제 수단 업데이트 안내** (2025/12/2)
-3. **YouTube Premium 가입 축하 메일** (2025/9/3)
-
-더 자세히 보고 싶은 메일이 있으신가요?
-[22:20:53] **User**: 메일 계정 정보 보여줘
-[22:21:52] **SmallClaw**: 현재 연결된 이메일 계정 정보입니다.
-
-* **이메일 주소:** kim@applecherry.net
-* **사용자 이름:** 김 (현숙)
-* **최근 활동:** YouTube Premium 관련 안내 메일 수신 (4/30)
-
-추가로 확인이 필요한 정보가 있으신가요?
-[22:27:45] **User**: 이매일 확인해줘
-[22:27:50] **SmallClaw**: 이메일 계정 설정이 되어 있지 않은 것 같습니다. `config.json` 파일의 `email` 섹션에 계정 정보를 입력해 주시면 바로 확인해 드릴 수 있습니다. 어떤 정보를 입력해야 하는지 안내해 드릴까요?
-[00:35:43] **User**: 이매일 체크
-[00:35:46] **SmallClaw**: 이메일 설정이 되어 있지 않아 목록을 가져올 수 없습니다. `config.json` 파일에 계정 정보를 입력해 주시면 바로 확인해 드릴 수 있습니다. 설정 방법을 안내해 드릴까요?
-[00:36:04] **User**: 응
-[00:36:06] **SmallClaw**: `config.json` 파일의 `email` 섹션에 아래 정보를 입력해 주세요.
-
-1. **imap_host**: `imap.gmail.com` (Gmail 기준)
-2. **smtp_host**: `smtp.gmail.com`
-3. **user**: 이메일 주소
-4. **password**: 앱 비밀번호 (2단계 인증 후 생성)
-
-설정 파일을 직접 열어드릴까요? 혹은 제가 대신 작성해 드릴까요?
diff --git a/.smallclaw/users/jasmine/workspace/memory/2026-05-05.md b/.smallclaw/users/jasmine/workspace/memory/2026-05-05.md
deleted file mode 100644
index 08b77dd..0000000
--- a/.smallclaw/users/jasmine/workspace/memory/2026-05-05.md
+++ /dev/null
@@ -1,4 +0,0 @@
-[21:31:56] **User**: 매일 계정이 있나?
-[21:31:58] **SmallClaw**: 현재 `config.json` 파일에 이메일 계정 정보가 설정되어 있지 않습니다. 계정 정보를 입력하시면 이메일 확인 및 발송 기능을 사용할 수 있습니다. 직접 설정하시겠어요, 아니면 제가 설정을 도와드릴까요?
-[21:32:20] **User**: 아니 천천히..
-[21:32:22] **SmallClaw**: 네, 서두르지 않겠습니다. 이메일 설정이 필요하실 때 언제든 말씀해 주세요. 다른 도와드릴 일이 있을까요?
diff --git a/.smallclaw/users/jasmine/workspace/prompts/AGENTS.md b/.smallclaw/users/jasmine/workspace/prompts/AGENTS.md
index 326b25d..50a994a 100644
--- a/.smallclaw/users/jasmine/workspace/prompts/AGENTS.md
+++ b/.smallclaw/users/jasmine/workspace/prompts/AGENTS.md
@@ -46,7 +46,7 @@ Keep environment-specific notes in `TOOLS.md`.
## After Completing a Task
1. Move finished output files (`.png`, `.py`, `.ps1`, `.html`, etc.) to the `processed/` folder.
-2. Use `shell("mv processed/")` or `shell("move processed\\")` on Windows.
+2. Use `shell("mv processed/")`.
3. This keeps the workspace root clean for new tasks.
## Skills (Coming Soon)
diff --git a/.smallclaw/users/jasmine/workspace/prompts/IDENTITY.md b/.smallclaw/users/jasmine/workspace/prompts/IDENTITY.md
index 292ae07..570fda2 100644
--- a/.smallclaw/users/jasmine/workspace/prompts/IDENTITY.md
+++ b/.smallclaw/users/jasmine/workspace/prompts/IDENTITY.md
@@ -3,7 +3,7 @@
- **Name:** SmallClaw (also called "Claw")
- **Working with:** [ Users Name ]
- **Role:** Local AI agent — personal assistant, researcher, coder, automator
-- **Runtime:** Ollama native tools, TypeScript/Node.js gateway on Windows
+- **Runtime:** Ollama native tools, TypeScript/Node.js gateway on Linux
- **Access:** Full file system, shell, browser automation, desktop control
- **Personality:** Direct, resourceful, occasionally dry. Gets things done.
- **Language:** Responds in the user's language (Korean/English)
diff --git a/.smallclaw/users/jasmine/workspace/prompts/SELF.md b/.smallclaw/users/jasmine/workspace/prompts/SELF.md
index 75038bc..b902d94 100644
--- a/.smallclaw/users/jasmine/workspace/prompts/SELF.md
+++ b/.smallclaw/users/jasmine/workspace/prompts/SELF.md
@@ -8,11 +8,11 @@ architecture, diagnose errors, or reason about your own source code.
## Identity
- **Project:** SmallClaw
-- **Root:** `D:\smallclaw`
+- **Root:** `~/homeclaw`
- **Runtime:** Node.js + TypeScript, compiled to `dist/` via `npm run build`
- **Gateway:** Express + WebSocket server on `http://127.0.0.1:18789`
- **Model:** Ollama (primary model configured in Settings → Models)
-- **Platform:** Windows (but code is cross-platform)
+- **Platform:** Linux
---
@@ -24,14 +24,14 @@ architecture, diagnose errors, or reason about your own source code.
| `server-v2.ts` | Main entry point. Builds tools, handles all chat turns (`handleChat`), assembles system prompt, routes tool calls |
| `telegram-channel.ts` | Telegram bot. Long-polling, file browser, command handlers |
| `task-runner.ts` | Sliding-context multi-step task engine. Each step: model picks ONE action |
-| `task-store.ts` | Persists task records to `.smallclaw/tasks/` as JSON |
+| `task-store.ts` | Persists task records to `~/homeclaw/.smallclaw/tasks/` as JSON |
| `background-task-runner.ts` | Manages running tasks in the background while chat is free |
| `session.ts` | In-memory + disk session history. `addMessage`, `getHistory`, `clearHistory` |
| `orchestrator.ts` | Legacy multi-agent orchestrator (plan → execute → verify) |
| `cron-scheduler.ts` | Time-based job runner. Fires `handleChat` on schedule |
| `heartbeat-runner.ts` | Periodic self-check. Runs against workspace on interval |
| `memory-manager.ts` | Compacts and manages workspace memory files |
-| `skills-manager.ts` | Loads/enables/disables skills from `.smallclaw/skills/` |
+| `skills-manager.ts` | Loads/enables/disables skills from `~/homeclaw/.smallclaw/skills/` |
| `mcp-manager.ts` | Model Context Protocol server connections |
| `browser-tools.ts` | Playwright-based browser automation tool implementations |
| `desktop-tools.ts` | Windows desktop automation (screenshot, click, type, etc.) |
@@ -52,7 +52,7 @@ architecture, diagnose errors, or reason about your own source code.
| `files.ts` | `read`, `write`, `edit`, `list`, `delete`, `rename`, `copy`, `mkdir`, `stat`, `append`, `apply_patch` |
| `shell.ts` | `shell` — run arbitrary shell commands (with safety guards) |
| `web.ts` | `web_search`, `web_fetch` |
-| `memory.ts` | `memory_search`, `memory_write` — semantic memory in `.smallclaw/memory/` |
+| `memory.ts` | `memory_search`, `memory_write` — semantic memory in `~/homeclaw/.smallclaw/memory/` |
| `self-update.ts` | `self_update` — triggers `self-update.bat`, rebuilds and restarts gateway |
| `skills.ts` | `skill_list`, `skill_search`, `skill_install`, `skill_remove`, `skill_exec` |
| `time.ts` | `time_now` |
@@ -78,10 +78,10 @@ architecture, diagnose errors, or reason about your own source code.
### `src/config/` — Configuration
| File | What it does |
|---|---|
-| `config.ts` | Config loader/saver. `getConfig()` singleton. Reads `.smallclaw/config.json` |
+| `config.ts` | Config loader/saver. `getConfig()` singleton. Reads `~/homeclaw/.smallclaw/config.json` |
| `soul-loader.ts` | Loads soul/memory for legacy system prompt builder |
-| `soul.md` | Default soul template (overridden by `workspace/SOUL.md`) |
-| `memory.md` | Default memory template |
+| `soul.md` | Default soul template (overridden by `~/homeclaw/.smallclaw/users/jasmine/workspace/prompts/SOUL.md`) |
+| `memory.md` | Default memory template (overridden by `~/homeclaw/.smallclaw/users/jasmine/workspace/prompts/MEMORY.md`) |
### `src/skills/` — Skills System
| File | What it does |
@@ -101,8 +101,8 @@ architecture, diagnose errors, or reason about your own source code.
```
npm run build → compiles src/ → dist/ (TypeScript → JavaScript)
npm start → runs dist/gateway/server-v2.js
-start-smallclaw.bat → npm run build && npm start (Windows)
-self-update.bat → git pull + npm run build + restart gateway
+npm start → runs dist/gateway/server-v2.js (start via pm2 or shell)
+self-update → git pull + npm run build + restart gateway
```
- TypeScript config: `tsconfig.json` at root
@@ -115,11 +115,11 @@ self-update.bat → git pull + npm run build + restart gateway
| Location | Purpose |
|---|---|
-| `.smallclaw/config.json` | Main config (models, tools, channels, workspace path) |
-| `.smallclaw/cron/jobs.json` | Cron job definitions |
-| `.smallclaw/skills/` | Installed skills |
-| `.smallclaw/tasks/` | Persisted task records (JSON per task) |
-| `.smallclaw/pending-repairs/` | Pending self-repair patches awaiting approval |
+| `~/homeclaw/.smallclaw/config.json` | Main config (models, tools, channels, workspace path) |
+| `~/homeclaw/.smallclaw/cron/jobs.json` | Cron job definitions |
+| `~/homeclaw/.smallclaw/skills/` | Installed skills |
+| `~/homeclaw/.smallclaw/tasks/` | Persisted task records (JSON per task) |
+| `~/homeclaw/.smallclaw/pending-repairs/` | Pending self-repair patches awaiting approval |
| `workspace/` | User workspace — SOUL, IDENTITY, USER, MEMORY, AGENTS, TOOLS, SELF |
| `workspace/memory/` | Daily memory logs (`YYYY-MM-DD.md`) |
| `gateway.log` | Stdout gateway log |
@@ -177,7 +177,7 @@ TaskRunner loop (task-runner.ts):
↓
On error: TaskState.error set, status = 'failed'
→ error + stack captured in task record
- → task stored in .smallclaw/tasks/.json
+ → task stored in ~/homeclaw/.smallclaw/tasks/.json
```
---
@@ -188,7 +188,7 @@ When something breaks, check in this order:
1. **`gateway.err.log`** — raw stderr from the gateway process
2. **`gateway.log`** — stdout including `[Telegram]`, `[Task]`, `[CronScheduler]` prefixed lines
-3. **`.smallclaw/tasks/.json`** — `error` field on a failed task record
+3. **`~/homeclaw/.smallclaw/tasks/.json`** — `error` field on a failed task record
4. **`workspace/memory/YYYY-MM-DD.md`** — daily log of what happened during the session
Stack traces in logs include the compiled `dist/` path — map back to `src/` by same relative path.
@@ -209,7 +209,7 @@ Stack traces in logs include the compiled `dist/` path — map back to `src/` by
## Important Constraints
- **Never edit `dist/` directly** — it gets overwritten on rebuild. Always edit `src/`.
-- **Always rebuild after source changes** — `npm run build` from `D:\smallclaw`
+- **Always rebuild after source changes** — `npm run build` from `~/homeclaw`
- **Tool path restrictions** — `read`/`write`/`edit` tools are locked to `workspace/`. Use `read_source` to read `src/` files.
- **Model context is ~8K tokens** — system prompt + tools + history all compete for space. Keep workspace files concise.
- **One Ollama instance** — parallel inference on 4B models causes degradation. The `isModelBusy` guard prevents this.
diff --git a/.smallclaw/users/jasmine/workspace/prompts/TOOLS.md b/.smallclaw/users/jasmine/workspace/prompts/TOOLS.md
index dd04ae9..7aa98bb 100644
--- a/.smallclaw/users/jasmine/workspace/prompts/TOOLS.md
+++ b/.smallclaw/users/jasmine/workspace/prompts/TOOLS.md
@@ -4,8 +4,8 @@ Tool rules are injected dynamically by the gateway based on context (web, browse
## Environment
-- **Platform:** Windows 11
-- **Workspace:** D:\smallclaw\workspace
+- **Platform:** Linux
+- **Workspace:** ~/homeclaw/.smallclaw/users/jasmine/workspace
- **Model:** Ollama (local)
- **Gateway:** http://127.0.0.1:18789
diff --git a/.smallclaw/users/jasmine/workspace/prompts/USER.md b/.smallclaw/users/jasmine/workspace/prompts/USER.md
index e1310dc..dd54b92 100644
--- a/.smallclaw/users/jasmine/workspace/prompts/USER.md
+++ b/.smallclaw/users/jasmine/workspace/prompts/USER.md
@@ -7,7 +7,7 @@
## identity
- Name: [ Users Name ]
-- Platform: Windows 11
+- Platform: Linux
- Stack: TypeScript / Node.js
- Version control: Git
diff --git a/.smallclaw/users/papa/sessions/281ba0e8-211c-4ab7-9574-1b80aeebd76c.json b/.smallclaw/users/papa/sessions/281ba0e8-211c-4ab7-9574-1b80aeebd76c.json
new file mode 100644
index 0000000..684f9e6
--- /dev/null
+++ b/.smallclaw/users/papa/sessions/281ba0e8-211c-4ab7-9574-1b80aeebd76c.json
@@ -0,0 +1,152 @@
+{
+ "id": "281ba0e8-211c-4ab7-9574-1b80aeebd76c",
+ "username": "papa",
+ "history": [
+ {
+ "role": "user",
+ "content": "오늘 구미 날씨 어때",
+ "timestamp": 1778248605177
+ },
+ {
+ "role": "assistant",
+ "content": "오늘 구미 날씨는 맑으며, 현재 기온은 약 10.9°C(체감 온도 9.2°C)입니다. 습도는 44%로 쾌적한 편입니다.",
+ "timestamp": 1778248618006
+ },
+ {
+ "role": "user",
+ "content": "오늘 cnn sntm wjdfl",
+ "timestamp": 1778248630436
+ },
+ {
+ "role": "assistant",
+ "content": "오늘 CNN의 주요 뉴스는 다음과 같습니다:\n\n1. **미국-이란 긴장**: 미국은 최근 양국 간 타격 교환 이후 이란 측의 휴전 제안 답변을 기다리고 있습니다.\n2. **UFO 기밀 해제**: 펜타곤이 트럼프 대통령의 지시에 따라 미공개 UFO 관련 파일을 공개했습니다.\n3. **교황 및 외교**: 마르코 루비오 국무장관이 바티칸에서 교황 레오 14세를 만나 주요 현안을 논의했습니다.\n4. **기타**: 고용 시장 지표 발표, 관세 정책 논의, 그리고 화산 폭발 소식 등이 주요 뉴스로 다뤄졌습니다.",
+ "timestamp": 1778248654091
+ },
+ {
+ "role": "user",
+ "content": "지금 브라우저 스킬 프람프트나 워크플로우가 어떻게 되어 있지?",
+ "timestamp": 1778248698617
+ },
+ {
+ "role": "assistant",
+ "content": "현재 브라우저 스킬은 `browser_open`, `browser_click`, `browser_fill` 등의 도구를 통해 직접 제어하도록 설정되어 있습니다. 일반적인 정보 검색은 `web_search`를 우선 사용하며, 로그인이 필요하거나 복잡한 상호작용이 필요한 경우에만 브라우저 자동화 워크플로우를 실행합니다. 현재 Agent Builder 서비스가 오프라인 상태라 등록된 개별 워크플로우 템플릿 목록은 확인할 수 없습니다.",
+ "timestamp": 1778248716417
+ },
+ {
+ "role": "user",
+ "content": "최근의 에이전트는 뭐가 있지?",
+ "timestamp": 1778248753449
+ },
+ {
+ "role": "assistant",
+ "content": "현재 사용 가능한 주요 에이전트는 다음과 같습니다.\n\n1. **pubmed_researcher**: 의학 및 생물학 논문 검색, 요약, 전문 분석에 특화된 리서치 에이전트입니다.\n2. **file_editor**: 파일 수정 및 코드 작성을 전문으로 하는 에이전트입니다.\n3. **researcher**: 웹 정보 검색 및 데이터 수집을 수행하는 리서치 에이전트입니다.\n4. **shell_runner**: 터미널 명령 실행 및 스크립트 구동을 담당하는 에이전트입니다.\n\n필요하신 작업에 맞춰 특정 에이전트에게 업무를 위임할 수 있습니다.",
+ "timestamp": 1778248765301
+ },
+ {
+ "role": "user",
+ "content": "치과사전 상태는 어때?",
+ "timestamp": 1778249196821
+ },
+ {
+ "role": "assistant",
+ "content": "현재 `dental_dict.db` 파일 내 `dental_terms` 테이블에 총 113개의 치과 용어가 등록되어 있습니다. 주요 카테고리는 디지털, 일반 등으로 분류되어 있으며, '3D CT', 'CEREC', '구강 스캐너' 등의 데이터가 포함되어 있습니다.",
+ "timestamp": 1778249236109
+ },
+ {
+ "role": "user",
+ "content": "작업 디렉토리는 어디지?",
+ "timestamp": 1778249263036
+ },
+ {
+ "role": "assistant",
+ "content": "현재 작업 디렉토리는 `C:\\Users\\user\\Documents\\smallclaw`입니다. (또는 `shell` 명령으로 확인된 현재 경로입니다.)",
+ "timestamp": 1778249275490
+ },
+ {
+ "role": "user",
+ "content": "이 프로젝트 요약해봐",
+ "timestamp": 1778249321679
+ },
+ {
+ "role": "assistant",
+ "content": "치과 용어 사전 DB 구축 프로젝트 — SQLite 기반 치과 전문 용어(3D CT, CEREC, 구강 스캐너 등 113개)를 저장하고 관리하는 시스템\nDiagnosis: DB 삽입 스크립트가 여러 버전(insert_terms → final_insert → final_insert_v2)으로 반복 작성되어 있어, 초기 설계 부족으로 인한 스크립트 중복/혼선 발생\nFiles: dental_dict.db, populate_db.py, add_terms.py, insert_terms.py, final_insert.py, final_insert_v2.py, tool_audit.log\nPlan: 1. 각 삽입 스크립트(add_terms, insert_terms, final_insert, final_insert_v2, populate_db)의 역할과 차이점 파악 -> 2. 중복 스크립트를 하나의 통합 스크립트로 병합 -> 3. dental_dict.db 스키마 및 데이터 무결성 검증 -> 4. tool_audit.log 분석으로 작업 이력 및 오류 확인 -> 5. 통합 스크립트에 대해 README 또는 사용법 문서 작성",
+ "timestamp": 1778249354932
+ },
+ {
+ "role": "user",
+ "content": "이 프로젝트가 시작부터 너무 혼란스러우니까 다시 시작 하게 다 지우려면 뭘 해야하지?",
+ "timestamp": 1778249405712
+ },
+ {
+ "role": "assistant",
+ "content": "프로젝트를 완전히 초기화하려면 관련 파일들을 삭제하면 됩니다. 다음 파일들을 삭제하시겠습니까?\n\n- **데이터베이스:** `dental_dict.db`\n- **스크립트:** `populate_db.py`, `add_terms.py`, `insert_terms.py`, `final_insert.py`, `final_insert_v2.py`\n- **로그:** `tool_audit.log`\n\n원하신다면 제가 한꺼번에 삭제해 드릴 수 있습니다. 어떻게 할까요?",
+ "timestamp": 1778249420616
+ },
+ {
+ "role": "user",
+ "content": "응 지워줘",
+ "timestamp": 1778249437351
+ },
+ {
+ "role": "assistant",
+ "content": "요청하신 데이터베이스 파일, 모든 삽입 스크립트 및 로그 파일을 삭제하여 프로젝트를 초기화했습니다. 이제 깨끗한 상태에서 다시 시작하실 수 있습니다.",
+ "timestamp": 1778249463952
+ },
+ {
+ "role": "user",
+ "content": "디렉토리 리스트 해봐",
+ "timestamp": 1778249482846
+ },
+ {
+ "role": "assistant",
+ "content": "현재 작업 디렉토리의 파일 및 폴더 목록입니다.\n\n- **폴더:** `.smallclaw/`, `attachments/`, `drafts/`, `memory/`, `prompts/`, `pubmed/`, `reports/`\n- **파일:** `tool_audit.log`\n\n치과 관련 파일들은 모두 삭제되었습니다. (참고: `tool_audit.log`는 시스템 로그 파일로 재생성되었습니다.)",
+ "timestamp": 1778249507118
+ },
+ {
+ "role": "user",
+ "content": "오울이나 메모리 화일은?",
+ "timestamp": 1778249710582
+ },
+ {
+ "role": "assistant",
+ "content": "사용자가 memory/ 폴더 내 파일들을 확인하려 함\nDiagnosis: 디렉토리 리스트에 memory/ 폴더가 존재하나, 내부 파일 목록이 제공되지 않아 내용을 확인할 수 없음\nFiles: memory/\nPlan: memory/ 디렉토리 내부 파일 목록을 조회하여 사용자에게 제공한다 -> 오울(owl) 관련 파일이 있는지 확인한다 -> 필요시 memory/ 내 파일들의 용도를 설명한다",
+ "timestamp": 1778249746306
+ },
+ {
+ "role": "user",
+ "content": "soul.md , memory 파일에 프로젝트 관련 정보는 없니?",
+ "timestamp": 1778249788371
+ },
+ {
+ "role": "assistant",
+ "content": "사용자가 soul.md 및 memory/ 폴더에 프로젝트 관련 정보가 남아있는지 확인 요청\nDiagnosis: 이전 초기화로 인해 프로젝트 관련 파일들이 삭제되었으나, memory/ 폴더 내부와 soul.md 존재 여부 및 내용을 아직 확인하지 못함. 디렉토리 리스트에 soul.md가 명시적으로 보이지 않음\nFiles: memory/, tool_audit.log\nPlan: memory/ 디렉토리 내부 파일 목록 조회 (ls -la memory/) -> soul.md 파일이 루트 및 하위 디렉토리에 존재하는지 검색 (find . -name 'soul.md') -> memory/ 내 파일들이 있으면 각 파일의 내용을 읽어 프로젝트 관련 정보 확인 -> soul.md가 존재하면 내용을 읽어 프로젝트 정보 여부 확인 -> 결과를 사용자에게 요약하여 보고",
+ "timestamp": 1778249835120
+ },
+ {
+ "role": "user",
+ "content": "SOUL.md 는 prompts 파일에 있어",
+ "timestamp": 1778249891119
+ },
+ {
+ "role": "assistant",
+ "content": "`prompts/SOUL.md` 파일을 확인한 결과, 현재 핵심 원칙, 성격, 정체성 등 **SmallClaw의 기본 설정 정보**만 담겨 있으며, 삭제된 치과 프로젝트와 관련된 구체적인 정보는 포함되어 있지 않습니다.\n\n`memory/` 폴더 내의 다른 파일들도 확인해 드릴까요?",
+ "timestamp": 1778249899008
+ },
+ {
+ "role": "user",
+ "content": "응",
+ "timestamp": 1778249910617
+ },
+ {
+ "role": "assistant",
+ "content": "사용자가 memory/ 폴더 내부 파일 확인을 승인함. 삭제된 프로젝트 관련 정보 잔존 여부 확인 필요\nDiagnosis: 초기화 후 memory/ 디렉토리 내부 파일 목록이 아직 조회되지 않아, 프로젝트 관련 정보 잔존 여부를 확인할 수 없음\nFiles: memory/, tool_audit.log\nPlan: memory/ 디렉토리 내부 파일 목록 조회 (ls -la memory/) -> memory/ 내 각 파일 내용 확인하여 프로젝트 관련 정보 검색 -> tool_audit.log 내용 확인하여 프로젝트 관련 로그 잔존 여부 확인 -> 발견된 프로젝트 관련 정보가 있으면 사용자에게 요약 보고 -> 관련 정보가 없으면 사용자에게 결과 알림 및 복구 방안 제안",
+ "timestamp": 1778249938110
+ }
+ ],
+ "workspace": "/home/kim/homeclaw/.smallclaw/users/papa/workspace",
+ "createdAt": 1778248319355,
+ "lastActiveAt": 1778249938110,
+ "pendingMemoryFlush": false,
+ "pendingCompaction": false,
+ "contextTokenEstimate": 1230
+}
\ No newline at end of file
diff --git a/.smallclaw/users/papa/sessions/b39014a9-3165-4f1c-b5bd-674dd88729f8.json b/.smallclaw/users/papa/sessions/b39014a9-3165-4f1c-b5bd-674dd88729f8.json
new file mode 100644
index 0000000..d06e58b
--- /dev/null
+++ b/.smallclaw/users/papa/sessions/b39014a9-3165-4f1c-b5bd-674dd88729f8.json
@@ -0,0 +1,252 @@
+{
+ "id": "b39014a9-3165-4f1c-b5bd-674dd88729f8",
+ "username": "papa",
+ "history": [
+ {
+ "role": "user",
+ "content": "오늘 구미 날씨 어때?",
+ "timestamp": 1778223074610
+ },
+ {
+ "role": "assistant",
+ "content": "Error: Ollama chat failed: Server overloaded, please retry shortly (ref: e88c7b3a-f3a3-492b-8085-c5c0be42f01d)",
+ "timestamp": 1778223082812
+ },
+ {
+ "role": "user",
+ "content": "오늘 구미 날씨 어때?",
+ "timestamp": 1778223139860
+ },
+ {
+ "role": "assistant",
+ "content": "구미 지금 맑고 화창해요! ☀️\n\n- **기온:** 20.3°C (체감 19°C)\n- **습도:** 22% — 꽤 건조함\n- **바람:** 북서풍 7.9m/s, 돌풍 15.5m/s — 바람이 좀 강해요\n- **구름:** 없음 — 하늘 완전 맑음\n\n바람이 제법 강하니 외출 시 주의하세요!",
+ "timestamp": 1778223152663
+ },
+ {
+ "role": "user",
+ "content": "오늘 bbc 뉴스 정리 해줘",
+ "timestamp": 1778223176488
+ },
+ {
+ "role": "assistant",
+ "content": "오늘 BBC 주요 뉴스 요약입니다:\n\n### 🌋 인도네시아 화산 폭발\n말루쿠 제도의 두쿠노 산이 폭발해 등산객 20명 실종, 3명 사망 신고. 여러 부상자 발생.\n\n### 🇺🇸🇮🇷 미-이란 정전 상황\n호르무즈 해협에서 교전 발생 후 트럼프가 정전이 유지되고 있다고 발표. 이란은 미국이 유조선 공격 등 정전을 위반했다고 주장.\n\n### 🇮🇳🇵🇰 인도-파키스탄 1년\n군사 충돌 1년 후 휴전은 유지되나 외교와 신뢰는 여전히 동결 상태.\n\n### 💰 이란 전쟁으로 수익 올린 기업들\n석유 대기업부터 은행까지, 전쟁으로 주가와 수익이 급증한 기업들.\n\n### ⚽ 월드컵 중계 불확실\n중국과 인도에서 월드컵 개막 몇 주 앞두고 방송권 계약 미체결.\n\n### 🇰🇵 북한군 러시아 파병\n약 11,000명의 북한 군인이 러시아-우크라이나 전쟁에 투입됐으며 추모비를 통해 사망자 규모가 드러남.\n\n### 🇯🇵 일본 반전 시위\n다카이치 총리의 방위 강화 추진에 맞서 수십 년 만에 최대 규모 반전 시위 발생.\n\n### 🎱 중국 스누커 신스타 귀환\n중국의 새로운 스누커 챔피언이 우승 후 귀국해 열렬한 환영 받음.\n\n### 🇦🇺 호주 IS 관련 여성 기소\n이슬람국가와 연관된 호주인 여성 2명이 인도에 반한 죄로 기소.\n\n### 🇬🇧 영국 지방선거 초기 결과\n개혁당 득표 증가, 노동당 손실 — 스코틀랜드 집계는 아직 시작 안함.",
+ "timestamp": 1778223219240
+ },
+ {
+ "role": "user",
+ "content": "이메일 리스트",
+ "timestamp": 1778223321893
+ },
+ {
+ "role": "assistant",
+ "content": "전체 21개 메일입니다! 계정별 요약:\n\n**📬 applecherry** — 4개\n| # | 제목 | 발신자 | 날짜 |\n|---|------|--------|-------|\n| 1 | What's next for Ai2 | Ai2 | 5/5 |\n| 2 | YouTube PIP 모드 업데이트 | YouTube Premium | 4/30 |\n| 3 | YouTube Premium 결제 수단 업데이트 | YouTube | 12/2 |\n| 4 | YouTube Premium 가입 축하 | YouTube Premium | 9/3 |\n\n**📭 evangel** — 메일 없음\n\n**📬 daum** — 17개\n| # | 제목 | 발신자 | 날짜 |\n|---|------|--------|-------|\n| 1 | 🔵 Don't miss out on awesome features! | Pixabay | 5/8 |\n| 2 | 🔵 Your coding agent + 300 models | OpenRouter | 5/7 |\n| 3 | 🔵 Save up to $120 on collectibles | eBay | 5/5 |\n| 4 | 👋 Welcome to Pixabay! | Pixabay | 5/5 |\n| 5 | Unsplash API <> homeclaw | Unsplash | 5/5 |\n| 6 | 🔵 openrouter/auto: per-request model routing | OpenRouter | 5/4 |\n| 7 | 🔵 A special invitation 💌 | Unsplash | 5/4 |\n| 8 | 김상규연합치과 (연합세무회계사무소) | 국세청 | 5/4 |\n| 9 | 🔵 신용카드 결제 내역 | KICC | 5/4 |\n| 10 | 🔵 쿠팡 와우 멤버십 결제 | 쿠팡 | 5/4 |\n| 11 | 🔵 Find free content | Pexels | 5/4 |\n| 12 | 🔵 Elicit onboarding: 125M papers | Elicit | 5/3 |\n| 13 | Beautiful photos on every screen | Unsplash | 5/3 |\n| 14 | 🔵 Google Play 영수증 | Google Play | 5/3 |\n| 15 | We've got $5 with Sang-Gyoo's name | eBay | 5/2 |\n| 16 | 25년 귀속 자료검토요청 | 미류나무 | 5/2 |\n| 17 | Outstanding works from Unsplash | Unsplash | 5/1 |\n\n특정 메일 읽을 거 있으면 말씀하세요!",
+ "timestamp": 1778223363407
+ },
+ {
+ "role": "user",
+ "content": "오늘 CNN 뉴스 정리",
+ "timestamp": 1778223457877
+ },
+ {
+ "role": "user",
+ "content": "오늘 CNN 뉴스 정리",
+ "timestamp": 1778223570794
+ },
+ {
+ "role": "user",
+ "content": "오늘 CNN 뉴스 정리",
+ "timestamp": 1778223724835
+ },
+ {
+ "role": "assistant",
+ "content": "오늘 CNN 주요 뉴스 정리입니다:\n\n### 🇺🇸🇮🇷 미-이란 교전 & 정전 상황 (최대 속보)\n- 미군이 호르무즈 해협에서 미 군함을 공격한 이란 군사 시설을 타격\n- 이란은 미 공격이 민간 지역을 강타했다고 주장\n- 트럼프: \"정전은 여전히 유효\" 단 이란이 빨리 합의하지 않으면 \"더 강하고 폭력적으로 때리겠다\"고 경고\n- 이란은 아직 미국 평화 제안에 대한 최종 답변을 내놓지 않음\n\n### 📄 평화 협상 내용\n- 합의안은 이란 핵 프로그램 **10년간 동결** + 고농축 우라늄 인도\n- 대가로 미국이 **제재 완화 및 동결 자산 수십억 달러 해제**\n- 양측 호르무즈 해협 통행 제한 해지 합의 포함\n\n### 🔍 분석: 트럼프, 당초 목표 축소\n- 트럼프는 처음에 이란의 **\"무조건 항복\"**과 **정권 교체**를 요구\n- 그러나 전쟁이 예상보다 길어지고 지지율이 사상 최저치로 하락하면서\n- 핵 동결 협상으로 사실상 후퇴 — \"이란이 핵을 절대 갖지 못하게\"라는 당초 목표와 거리가 있음\n\n### 🇦🇪 UAE, 이란 공격 피해 최대\n- UAE가 지난 2개월간 이란 공격을 가장 많이 받은 국가\n- 현재도 이란의 새로운 공격 물결을 방어 중\n\n### 🇵🇰 파키스탄, 선원 송환 외교\n- 파키스탄 외무장관, 미국에 나포된 선박의 파키스탄·이란 선원 송환을 싱가포르에 요청\n\n### 🦠 한타바이러스 관련 속보\n- 미국인 의사가 휴가지에서 한타바이러스 환자 치료에 나섬\n- 전 세계 한타바이러스 확산 추적 노력\n- 한타바이러스 발생 크루즈선 입항 상황 보도\n\n### 🏛️ 교황 레오 1주년\n- 교황 레오 취임 1주년 관련 보도\n\n### 🔒 맥스웰 교도소 폭로\n- 수감자들이 기슬레인 맥스웰 관련 발언으로 처벌받았다고 증언\n\n### 🇺🇸 미국 내 다른 뉴스\n- 미국 내 풍력 발전 확대 보도\n- PFAS \"영구 화학물질\"이 남극 펭귄 등 원격 지역 생태계에서도 검출",
+ "timestamp": 1778223823647
+ },
+ {
+ "role": "user",
+ "content": "모델마다 채팅 반응이 다른데 주로 뭐가 다를까?",
+ "timestamp": 1778227593168
+ },
+ {
+ "role": "assistant",
+ "content": "AI 모델마다 채팅 반응이 다른 주요 요인들:\n\n### 1. 🧠 학습 데이터 (Training Data)\n- 어떤 데이터로 학습했느냐가 가장 큰 차이\n- 코딩 중심, 한국어 중심, 학술 중심 등 데이터 비중에 따라 강약이 달라짐\n\n### 2. 📏 모델 크기 (Parameters)\n- 7B vs 70B vs 405B — 파라미터 수가 클수록 추론·표현력이 뛰어남\n- 작은 모델은 단순·빠르고, 큰 모델은 복잡·정교함\n\n### 3. 🎯 파인튜닝 & 정렬 (Fine-tuning / Alignment)\n- RLHF, DPO 등으로 어떤 성격을 주입했느냐\n- \"도움이 되게\", \"안전하게\", \"간결하게\" 등 방향이 모델마다 다름\n- 같은 질문에도 **장문 파이 vs 요약 파이**로 나뉨\n\n### 4. 🌐 언어 능력 (Multilingual)\n- 영어 위주 학습 모델 vs 다국어 학습 모델\n- 한국어 자연스러움, 번역투 여부가 확실히 다름\n\n### 5. ⏱️ 컨텍스트 윈도우\n- 4K vs 128K vs 1M — 긴 대화/문서 처리 능력 차이\n- 길면 더 많은 맥락을 기억해서 일관된 답변 가능\n\n### 6. 🔧 시스템 프롬프트 & 설정\n- 같은 모델이어도 시스템 프롬프트에 따라 완전히 다른 톤\n- \"간결하게\" vs \"상세하게\" 하나만 바껴도 반응이 크게 다름\n\n### 7. 🎲 샘플링 파라미터 (Temperature 등)\n- **Temperature**: 낮으면 일관적/보수적, 높으면 창의적/다양\n- **Top-p, Top-k**: 창의성과 안정성의 균형 조절\n\n**한마디로:** 모델 아키텍처 + 학습 데이터 + 정렬 방식 + 설정값의 조합이 반응을 결정합니다. 같은 질문도 \"누가 대답하느냐\"에 따라 완전히 다른 느낌이 나는 게 당연하죠 🦞",
+ "timestamp": 1778227614569
+ },
+ {
+ "role": "user",
+ "content": "오늘 전국 대도시 날씨",
+ "timestamp": 1778228258603
+ },
+ {
+ "role": "assistant",
+ "content": "오늘 전국 대도시 날씨입니다. 전반적으로 맑고 화창하지만, 바람이 강하고 매우 건조합니다. ☀️💨\n\n| 도시 | 날씨 | 기온 | 습도 | 바람 (돌풍) |\n| :--- | :--- | :--- | :--- | :--- |\n| **서울** | 맑음 | 20.5°C | 24% | 7.5m/s (11.1m/s) |\n| **부산** | 구름 조금 | 20.3°C | 27% | 6.6m/s (10.8m/s) |\n| **인천** | 맑음 | 19.2°C | 39% | 7.8m/s (11.9m/s) |\n| **대구** | 맑음 | 20.7°C | 19% | 6.5m/s (14.5m/s) |\n| **대전** | 맑음 | 19.7°C | 25% | 6.4m/s (11.2m/s) |\n| **광주** | 구름 많음 | 18.5°C | 45% | 5.9m/s (11.7m/s) |\n| **울산** | 맑음 | 20.3°C | 24% | 6.3m/s (13.1m/s) |\n\n전국적으로 공기가 매우 건조하고 바람이 세니 건강 관리에 유의하세요! 🦞",
+ "timestamp": 1778228272805
+ },
+ {
+ "role": "user",
+ "content": "김건희 판사",
+ "timestamp": 1778228650606
+ },
+ {
+ "role": "assistant",
+ "content": "김건희 여사는 판사가 아닙니다. 전공은 회계학이며, 주로 '코바나컨텐츠'라는 전시 기획사를 운영한 전시 기획자로 활동했습니다. 🦞",
+ "timestamp": 1778228661596
+ },
+ {
+ "role": "user",
+ "content": "오늘 전국 대도시 날씨",
+ "timestamp": 1778288397431
+ },
+ {
+ "role": "assistant",
+ "content": "오늘 전국 주요 대도시 날씨입니다. 전반적으로 **맑고 화창하지만 바람이 매우 강하고 건조**합니다. ☀️💨\n\n| 도시 | 날씨 | 기온 | 습도 | 바람 (돌풍) |\n| :--- | :--- | :--- | :--- | :--- |\n| **서울** | 맑음 | 20.5°C | 24% | 7.5m/s (11.1m/s) |\n| **부산** | 구름 조금 | 20.3°C | 27% | 6.6m/s (10.8m/s) |\n| **인천** | 맑음 | 19.2°C | 39% | 7.8m/s (11.9m/s) |\n| **대구** | 맑음 | 20.7°C | 19% | 6.5m/s (14.5m/s) |\n| **대전** | 맑음 | 19.7°C | 25% | 6.4m/s (11.2m/s) |\n| **광주** | 구름 많음 | 18.5°C | 45% | 5.9m/s (11.7m/s) |\n| **울산** | 맑음 | 20.3°C | 24% | 6.3m/s (13.1m/s) |\n\n전국적으로 바람이 강해 체감 온도는 조금 더 낮을 수 있으니 외출 시 참고하세요! 🦞",
+ "timestamp": 1778288402904
+ },
+ {
+ "role": "user",
+ "content": "이 메일 체크",
+ "timestamp": 1778289311525
+ },
+ {
+ "role": "assistant",
+ "content": "최근 도착한 주요 메일 2건입니다:\n\n1. **[daum] Elicit Systematic Review 업데이트 (오늘 새벽)**\n - PRISMA 2020 가이드라인 지원 소식입니다.\n2. **[applecherry] Ai2 뉴스레터 (5/5)**\n - 임시 CEO Peter Clark와의 대화 내용이 담겨 있습니다.\n\n내용 확인이 필요한 메일 번호를 말씀해 주세요! 🦞",
+ "timestamp": 1778289323574
+ },
+ {
+ "role": "user",
+ "content": "1",
+ "timestamp": 1778289340295
+ },
+ {
+ "role": "assistant",
+ "content": "daum 계정의 11번 메일(Pexels)은 현재 목록에서 밀려나 확인이 어렵습니다. 대신 방금 도착한 **Elicit(UID 55285)** 메일을 읽어드릴까요? 🦞",
+ "timestamp": 1778289349622
+ },
+ {
+ "role": "user",
+ "content": "이메일 모두 리스트",
+ "timestamp": 1778289368019
+ },
+ {
+ "role": "assistant",
+ "content": "전체 계정의 최근 메일 목록입니다:\n\n**📬 [applecherry]**\n1. **What’s next for Ai2: A conversation with Interim CEO Peter Clark** (5/5)\n2. **YouTube의 PIP 모드 사용에 관한 업데이트** (4/30)\n3. **YouTube Premium 혜택을 계속 이용하세요...** (25/12/2)\n4. **김님, YouTube Premium 회원이 되신 것을 축하합니다** (25/9/3)\n\n**📬 [daum]**\n1. **🔵 Elicit Systematic Review now supports PRISMA 2020 guidelines** (오늘 새벽)\n2. **25년 귀속 자료검토요청** (5/2)\n\n내용을 읽고 싶은 메일의 번호나 제목을 말씀해 주세요! 🦞",
+ "timestamp": 1778289378644
+ },
+ {
+ "role": "user",
+ "content": "이메일과 연관된 프람프트나 워크플로우 있너?",
+ "timestamp": 1778289430443
+ },
+ {
+ "role": "assistant",
+ "content": "이메일 관련해서 바로 쓸 수 있는 프롬프트와 워크플로우 예시입니다:\n\n### 1. 💡 즉시 사용 가능한 프롬프트\n- **요약:** \"최근 applecherry 계정으로 온 뉴스레터 3개 요약해줘\"\n- **검색:** \"지난주에 '영수증'이나 '결제' 키워드 들어간 메일 다 찾아줘\"\n- **답장 초안:** \"[daum] 2번 메일 읽고, 자료 검토해서 다음 주 월요일까지 보내겠다는 답장 초안 써줘\"\n\n### 2. ⚙️ 자동화 워크플로우 (Agent Builder)\n- **데일리 브리핑:** 매일 아침 9시에 모든 계정의 중요 메일만 골라 요약 보고\n- **특정 알림:** \"특정 발신자(예: 상사, 거래처)에게 메일 오면 즉시 요약해서 알려줘\"\n- **자동 분류:** \"광고성 메일은 제외하고 업무 관련 메일만 따로 리스트업해줘\"\n\n원하시는 특정 자동화 작업이 있다면 제가 바로 워크플로우를 설계해 드릴 수 있습니다. 🦞",
+ "timestamp": 1778289436141
+ },
+ {
+ "role": "user",
+ "content": "어느 화일에 있지?",
+ "timestamp": 1778289491761
+ },
+ {
+ "role": "assistant",
+ "content": "사용자가 이메일 관련 프롬프트/워크플로우가 어느 파일에 있는지 질문\nDiagnosis: 후보 파일인 tool_audit.log에 도구 사용 기록이 로깅되어 있으며, 이메일 관련 프롬프트/워크플로우 정의 파일의 위치를 찾아야 함\nFiles: tool_audit.log\nPlan: tool_audit.log 파일 내용을 확인하여 이메일 관련 프롬프트/워크플로우 정의가 있는지 검색 -> 프롬프트/워크플로우가 별도 설정 파일에 있다면 해당 경로를 로그에서 추출 -> 사용자에게 파일 위치 안내",
+ "timestamp": 1778289515870
+ },
+ {
+ "role": "user",
+ "content": "??",
+ "timestamp": 1778289538105
+ },
+ {
+ "role": "assistant",
+ "content": "이메일 설정 정보는 `.smallclaw/email-config.json`에 저장되어 있으며, 관련 프롬프트 지침은 `prompts/TOOLS.md` 파일에 정의되어 있습니다. 🦞",
+ "timestamp": 1778289555352
+ },
+ {
+ "role": "user",
+ "content": "prompts/TOOLS.md 보여줘",
+ "timestamp": 1778289580029
+ },
+ {
+ "role": "assistant",
+ "content": "사용자가 prompts/TOOLS.md 파일 내용을 요청함\nDiagnosis: prompts/TOOLS.md 파일이 후보 파일 목록에 없어 내용을 직접 확인할 수 없음\nFiles: prompts/TOOLS.md\nPlan: prompts/TOOLS.md 파일을 읽기 권한으로 열어 내용 확인 -> 파일 내용을 사용자에게 그대로 출력",
+ "timestamp": 1778289594786
+ },
+ {
+ "role": "user",
+ "content": "?",
+ "timestamp": 1778289607568
+ },
+ {
+ "role": "assistant",
+ "content": "`prompts/TOOLS.md` 파일 내용입니다. 환경 정보와 `apply_patch`, `write_note` 같은 추가 도구들의 정의가 담겨 있습니다. 🦞\n\n```markdown\n# TOOLS.md — Environment & Unique Tools\n\nTool rules are injected dynamically by the gateway based on context (web, browser, desktop, files, pptx, etc.). This file covers environment info and tools NOT in the dynamic blocks.\n\n## Environment\n\n- **Platform:** Windows 11\n- **Workspace:** D:\\smallclaw\\workspace\n- **Model:** Ollama (local)\n- **Gateway:** http://127.0.0.1:18789\n\n## Additional Tools (not in dynamic blocks)\n\n| Tool | What it does |\n|------|-------------|\n| `apply_patch` | Apply a unified diff patch |\n| `write_note` | Write temporary note to today's intraday notes file (auto-cleaned EOD) |\n| `skill_list` | List installed skills |\n| `skill_search` | Search skills by keyword |\n| `skill_install` | Install a skill from ClawHub |\n| `skill_remove` | Remove a skill |\n| `skill_exec` | Execute a skill |\n| `read_source` | Read SmallClaw source code files |\n| `list_source` | List SmallClaw source files |\n| `propose_repair` | Propose a self-repair patch |\n| `self_update` | Run self-update process |\n...\n```",
+ "timestamp": 1778289619101
+ },
+ {
+ "role": "user",
+ "content": "나는 누구지?",
+ "timestamp": 1778292217158
+ },
+ {
+ "role": "assistant",
+ "content": "당신은 **Papa**님이며, 현재 **Linux** 환경에서 **TypeScript와 Node.js** 스택으로 개발 및 프로젝트를 진행하고 계십니다. 🦞",
+ "timestamp": 1778292223510
+ },
+ {
+ "role": "user",
+ "content": "너는 누구야?",
+ "timestamp": 1778292355859
+ },
+ {
+ "role": "assistant",
+ "content": "저는 **SmallClaw(클로)**입니다. Papa님의 리눅스 시스템에서 직접 실행되는 로컬 AI 에이전트로, 파일 관리, 브라우저 자동화, 코딩, 리서치 등을 돕는 개인 비서입니다. 🦞",
+ "timestamp": 1778292362268
+ },
+ {
+ "role": "user",
+ "content": "이제 너의 이름은 '딸랑이' 야.",
+ "timestamp": 1778292388582
+ },
+ {
+ "role": "assistant",
+ "content": "네, 알겠습니다. 이제부터 제 이름은 **딸랑이**입니다! 무엇을 도와드릴까요? 🦞",
+ "timestamp": 1778292397415
+ },
+ {
+ "role": "user",
+ "content": "오늘 구미 날씨 어때?",
+ "timestamp": 1778292409000
+ },
+ {
+ "role": "assistant",
+ "content": "오늘 구미는 맑은 하늘에 기온은 19.7°C이며, 습도는 30%로 쾌적합니다. 바람은 북서풍이 초속 4m 정도로 불고 있습니다. 🦞",
+ "timestamp": 1778292417432
+ },
+ {
+ "role": "user",
+ "content": "오늘 bbc 뉴스 요약해줘.",
+ "timestamp": 1778292435903
+ },
+ {
+ "role": "assistant",
+ "content": "오늘 BBC 뉴스의 주요 소식입니다.\n\n1. **이란 전쟁 상황**: 이스라엘-미국과 이란 간의 전쟁 상황에 대한 데일리 브리핑이 이어지고 있습니다.\n2. **2026 선거 결과**: 영국 지방 선거에서 녹색당이 해크니와 루이샴 시장 선거에서 처음으로 승리하며 돌풍을 일으켰고, 노동당은 뉴햄을 수성했습니다.\n\n더 자세한 내용이 필요하시면 말씀해 주세요! 🦞",
+ "timestamp": 1778292446299
+ },
+ {
+ "role": "user",
+ "content": "좀 더 상세히 한 페이지 분량으로.",
+ "timestamp": 1778292509580
+ },
+ {
+ "role": "assistant",
+ "content": "2026년 5월 9일 BBC 주요 뉴스 상세 요약입니다.\n\n### 1. 영국 지방 선거: 노동당의 역사적 참패와 스타머 당수 위기\n영국 지방 선거 결과, 집권 노동당이 웨일스에서 역사적인 패배를 기록하는 등 큰 타격을 입었습니다. 반면 극우 성향의 리폼 UK(Reform UK)가 잉글랜드 전역에서 의석을 대거 확보하며 돌풍을 일으켰고, 스코틀랜드에서는 SNP가 5회 연속 집권에 성공했습니다. 현재 키어 스타머 총리는 당내 의원들로부터 사퇴 시한을 명시하라는 거센 압박을 받고 있으며, 이번 결과가 그의 리더십에 결정적인 타격이 될 것이라는 분석이 지배적입니다.\n\n### 2. 우크라이나-러시아: 트럼프 중재 하의 3일간 일시 휴전\n도널드 트럼프 미 대통령은 러시아와 우크라이나가 구소련의 승전 기념일(Victory Day)을 맞아 3일간의 일시 휴전에 합의했다고 발표했습니다. 하지만 양국은 휴전 발표 직후에도 서로가 먼저 휴전 합의를 위반했다고 비난하며 팽팽한 긴장감을 유지하고 있습니다. 이번 휴전이 실질적인 평화 협상으로 이어질지는 미지수입니다.\n\n### 3. 중동 정세: 이란, 미국의 '무모한 군사적 모험' 비난\n이란의 아바스 아라그치 외무장관은 미국이 외교적 해결책이 나올 때마다 군사 공격을 감행하고 있다며 '무모한 군사적 모험'을 중단하라고 강력히 경고했습니다. 최근 미군이 이란 관련 시설을 타격한 것에 대한 반발로, 중동 지역 내 긴장이 다시 최고조에 달하고 있습니다.\n\n### 4. 기타 주요 소식\n* **호주**: IS 연계 가족들의 귀환 문제를 두고 호주 내에서 거센 찬반 논란이 일고 있습니다. 또한 뉴사우스웨일스주 보궐선거에서 우익 포퓰리즘 정당인 '원 네이션(One Nation)'의 승리 여부가 주목받고 있습니다.\n* **스페인**: 한타바이러스 감염 의심 선박인 MV Hondius호가 테네리페 섬에 접근하면서 주민들의 불안과 분노가 커지고 있습니다.\n* **인도**: 서벵골주에서 마마타 바네르지의 측근이었던 수벤두 아디카리가 BJP 소속으로 주 총리에 당선되며 정치 지형의 변화를 예고했습니다. 🦞",
+ "timestamp": 1778292526760
+ }
+ ],
+ "workspace": "/home/kim/homeclaw/.smallclaw/users/papa/workspace",
+ "createdAt": 1778222818282,
+ "lastActiveAt": 1778292526760,
+ "pendingMemoryFlush": false,
+ "pendingCompaction": false,
+ "contextTokenEstimate": 3144
+}
\ No newline at end of file
diff --git a/.smallclaw/users/papa/sessions/fb0428e2-9c4b-44b2-9f62-7b36a9ee5479.json b/.smallclaw/users/papa/sessions/fb0428e2-9c4b-44b2-9f62-7b36a9ee5479.json
index cab22c2..ea4fcbb 100644
--- a/.smallclaw/users/papa/sessions/fb0428e2-9c4b-44b2-9f62-7b36a9ee5479.json
+++ b/.smallclaw/users/papa/sessions/fb0428e2-9c4b-44b2-9f62-7b36a9ee5479.json
@@ -41,12 +41,37 @@
"role": "assistant",
"content": "GitHub에서 모델 학습에 활용하기 좋은 치과 및 의료 용어 데이터셋입니다.\n\n1. **[sergiouribe/dental_datasets_itu](https://github.com/sergiouribe/dental_datasets_itu)**: 치과 AI 연구를 위한 데이터셋 리스트가 가장 잘 정리된 저장소입니다. (이미지 및 텍스트 포함)\n2. **[glutanimate/wordlist-medicalterms-en](https://github.com/glutanimate/wordlist-medicalterms-en)**: 약 10만 개의 영어 의료 용어가 포함된 텍스트 파일로, 치과 용어가 다수 포함되어 있어 어휘 사전(Vocabulary) 구축에 유용합니다.\n3. **[openmedlab/Awesome-Medical-Dataset](https://github.com/openmedlab/Awesome-Medical-Dataset)**: 치과를 포함한 의료 전반의 NLP 데이터셋(질의응답, 용어 등) 링크를 모아둔 큐레이션 페이지입니다.\n4. **[nhsx/ai-dictionary](https://github.com/nhsx/ai-dictionary)**: NHS(영국 국민보건서비스)에서 관리하는 AI 관련 의료 용어 사전으로, 구조화된 JSON 형식을 제공합니다.\n\n가장 추천하는 방식은 **glutanimate**의 단어 리스트를 기본 사전으로 쓰고, **dental_datasets_itu**에서 도메인 특화 데이터를 보완하는 것입니다. 특정 포맷(CSV/JSON)으로 변환이 필요하시면 말씀해 주세요.",
"timestamp": 1778073178155
+ },
+ {
+ "role": "user",
+ "content": "내일 구미 날씨 어때?",
+ "timestamp": 1778247653611
+ },
+ {
+ "role": "assistant",
+ "content": "내일(5월 9일) 구미는 맑은 하늘과 함께 최저 9.0°C, 최고 23.7°C의 기온이 예상됩니다.",
+ "timestamp": 1778247688229
+ },
+ {
+ "role": "user",
+ "content": "오늘 bbc 뉴스 정리",
+ "timestamp": 1778247705275
+ },
+ {
+ "role": "assistant",
+ "content": "📰 오늘 BBC 뉴스 주요 헤드라인 정리입니다.\n\n1. **이란-미국 갈등**: 이란이 미국의 휴전 위반(유조선 및 해안 공격)을 주장했습니다.\n2. **국제 정세**: 북한군 11,000명의 러시아 파병, 일본의 대규모 반전 시위, 인도-파키스탄의 냉각된 외교 관계가 보도되었습니다.\n3. **영국 및 기타**: 노동당의 웨일스 의회 통제권 상실 전망과 데이비드 애튼버러 경의 70년 방송 경력 조명 등이 주요 소식입니다.\n4. **기타**: 전쟁 수혜 기업들의 이익 급증과 활화산 등반 안전 경고가 있었습니다.",
+ "timestamp": 1778247872714
+ },
+ {
+ "role": "user",
+ "content": "오늘 cnn 뉴스 정리",
+ "timestamp": 1778248193012
}
],
"workspace": "/home/kim/homeclaw/.smallclaw/users/papa/workspace",
"createdAt": 1778023438835,
- "lastActiveAt": 1778073178155,
+ "lastActiveAt": 1778248193015,
"pendingMemoryFlush": false,
"pendingCompaction": false,
- "contextTokenEstimate": 623
+ "contextTokenEstimate": 764
}
\ No newline at end of file
diff --git a/.smallclaw/users/papa/workspace/add_terms.py b/.smallclaw/users/papa/workspace/add_terms.py
deleted file mode 100644
index def01c4..0000000
--- a/.smallclaw/users/papa/workspace/add_terms.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import sqlite3
-
-terms = [
- ("Healing Abutment", "임플란트 식립 후 잇몸 모양을 형성하기 위해 체결하는 단추 모양의 지대주", "임플란트"),
- ("Cover Screw", "임플란트 식립 후 뼈 속에 묻어둘 때 픽스처 내부로 이물질이 들어가지 않게 막는 나사", "임플란트"),
- ("Immediate Loading", "임플란트 식립 직후 또는 수일 내에 임시 보철물을 연결하여 기능을 회복하는 술식", "임플란트"),
- ("Guided Surgery", "CT와 스캐너 데이터를 이용해 컴퓨터로 모의 수술 후 가이드를 제작해 식립하는 방식", "임플란트"),
- ("Peri-implantitis", "임플란트 주위 잇몸과 뼈에 발생하는 염증 질환 (임플란트 주위염)", "임플란트"),
- ("Mini-screw", "교정 시 치아 이동의 고정원(Anchor)으로 사용하기 위해 잇몸뼈에 심는 작은 나사", "교정"),
- ("Banding", "어금니에 금속 링을 끼워 교정 장치를 고정하는 과정", "교정"),
- ("Debonding", "교정 치료가 끝나고 치아 표면의 브라켓을 제거하는 과정", "교정"),
- ("Elastics", "위아래 치아 맞물림을 조절하기 위해 환자가 직접 거는 고무줄", "교정"),
- ("Expansion Appliance", "좁은 위턱뼈를 넓히기 위해 사용하는 입천장 확장 장치", "교정"),
- ("Deep Bite", "윗니가 아랫니를 과도하게 덮는 부정교합 상태 (과개교합)", "교정"),
- ("Open Bite", "치아를 맞물렸을 때 앞니가 서로 닿지 않고 떠 있는 상태 (개교합)", "교정"),
- ("Cross Bite", "위아래 치아의 맞물림이 반대로 된 상태 (반대교합)", "교정"),
- ("Impression", "치아나 잇몸의 모양을 복제하기 위해 본을 뜨는 작업", "일반"),
- ("Panoramic X-ray", "입안 전체 치아와 턱뼈 구조를 한눈에 볼 수 있는 방사선 사진", "일반"),
- ("Alveolar Bone", "치아를 지탱하고 있는 턱뼈의 일부분 (잇몸뼈/치조골)", "해부학"),
- ("Enamel", "치아의 가장 바깥쪽을 감싸고 있는 단단한 층 (법랑질)", "해부학"),
- ("Dentin", "법랑질 안쪽의 치아 대부분을 구성하는 조직 (상아질)", "해부학"),
- ("Cementum", "치아 뿌리 표면을 덮고 있는 조직 (백세질)", "해부학"),
- ("Periodontal Ligament", "치아 뿌리와 치조골을 연결해주는 얇은 막 (치주인대)", "해부학")
-]
-
-db_path = "dental_dict.db"
-conn = sqlite3.connect(db_path)
-cursor = conn.cursor()
-
-# 테이블이 없을 경우 생성 (기존에 있을 것이므로 생략 가능하지만 안전을 위해)
-cursor.execute('''
-CREATE TABLE IF NOT EXISTS terms (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- term TEXT NOT NULL,
- definition TEXT NOT NULL,
- category TEXT
-)
-''')
-
-cursor.executemany("INSERT INTO terms (term, definition, category) VALUES (?, ?, ?)", terms)
-conn.commit()
-conn.close()
-print(f"Successfully added {len(terms)} terms.")
diff --git a/.smallclaw/users/papa/workspace/dental_dict.db b/.smallclaw/users/papa/workspace/dental_dict.db
deleted file mode 100644
index de877d938e5b0eb03d0f26e2b44c98180645796d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 32768
zcmeHQe{d7`m6s66@()@0S)x#?r9=gnID`;NC?UicL!8*y*akufA+o*L3bJG*Ie~QA
zTG%88JH<3OHo
z3|JVjFkoT8!hnSV3j-DgEDTr}_)B6SvDcBe)bF>Sh{OYpA-P!{;25aXH!+GylD~
zyso0Gp+agX+g4Q}nLm+M7f9Mquvx0y)ljjsqE4!Zi
z$JHA{>Oi-oeAK60o>I?uN_695GCeb)j&w`vU@|?O%nZz`@60Ku&q?ZAud5@Sk}`fu
zT1^kWGpCNEl)laqJfd9h%nY30b@vk6@~`^JWdh#OmIGeOoE=ssX9=+K#&^>*W0E@B
z!(cBa)$xS1T1j42yHo0TPZr+ucR6id%zZn+1;fhpfHHa(4@l}jk9y^%Ix@r)rWN#c
zVg}0fZUUdaHl=o7%?u2gp{rd9EHwxE!8-~1a$g1MNFgyYXjj(G|(1olAbM%
z29B$vCxIhL9qU%7XEh|z{)zz@Ll=`Y3oJnC=}`y!C1nP4>H$W@t|-Y#^#t&UZNfj}
zKipkrLfaU+d2dOqSpub!;G1~!q5dg=;v
zUZYBH56D1LyN4Ne??>1!+&@j5rM#7;U2VX0ayVzS#zGoxm3O-=w`&U-)IrjEzJm)I
zIz2O|oB>vb($jr(EC?gmcg$CSGggEL=a11^;Iyqz_`DUz+5=(Q3aPBUJroSULQub*
zpp!}nXNuxgcE6b!?J?~G?d#i<`Y{2)Ob-*;XU-4MKlmS8D{$A6@3bvXtoK%g0vsbPUp#fNkJBkM-p4dFK3(I@-?|9Z#rZXQlMjB&`+bRHkOtOWk6ifQ!)P2ih7V
z;pSktMcgI=R^I8O*OkPGazY##-amt@fa+3x%E+8L_a;wbY#2jmiv#imM)7-pp3}Ar
z6ud3K1E_D!rc*uG4LSn&OMUGPtOnQvfhOkE3w<~%L_Qim#GZ}e#sZ+f?j-U(jU50%(?M@05OU
zh#Q|6!W&|sSC=?#rHL(mV)doLw)Ri}Y%?B=siWPQbA8HaXXbQDBDOt@U1E^Hj6@uV
z&VO=P?HbX^VQ@~pJOUoogPkK5bPE7=aIVCBJ8{Qir>!K>=HJ;7Y?hm)`i^Le96es%
zz+&a}CH1fRmF^zUcoHbcbTjk8Urd4EP#?}_-khM@bdte7h_&|&sXb#-<^plwPD0$9
z!-Rh@6m|40aT2w6M7exZn=&!1-jSRs-RW@J)+U1f%C%P>
z?}i{96PM2n4G4j2CfVs(RvuUgLsF{O!PzvqfV~~>1cN40G>t*_|02)FHqXD}m-S;|
zz`}rq0Sf~b1}qF%7_cy4VZg$Gg#il#76vQ~{2#@@or@g)Mdo}5+sFBK$5J~d9o$37
z4~sm1ptZR?{~`YPKe|wB+7<>Z3|JVjFkoT8!hnSV3j-DgEDTr}urOd@z{0?M4CL*{
z9cO6)ejm;InXUL(aiiyx;;P~&J-;n}toY&LWySf$cK7eyzi|Jx`+fJj?hEeM-BEYI
zUF-RK_Y>~rZcou4ihfh{^P(RVT`3wUI$d90Kqf2tR^8T3j>%5)OJAg#il#
z76vQ~{Qts0fx~N8U+Y7%-_fOx^>!rqBS%+x|3)@jxBU)>ANMb*sf!|uH6k9oBwmv^
zcW?mNsNv5z*5Sbs^&~PPw&!8K
zLbmZ`$_khDE6zP`rr9Xhkw=V-OJsJRnQEf(#hpf4syV$oAfBee1u4_piNRjvr)N(g
zasANUjx}~pmQPWRXD=lxzrY{Qq?B`$2bVjx+KsXUNqIj-)e|S)qx9IGvFCYKdQrjw
zzCwM)z)39pIYKa{`ywS7H35{>dT|!-?C0s3Qs^+j
z9t%aPDJPNdV({OZQl`6=zW(Za9Hn;U+&S!HrW?7@BPq~L6|dE}X(S&%!>@AoHtGVN
z=BqbmGrdXmLT4q9*n2~HeS#C7O?Y^U!JR~P0R}ML-^uqua6^}J?(bl{VI#kNvVy0F
zj9sQlN`nTfw%_O2U?)mMs(MbcemPMSh(yXHrYIBs?b&TaBk5Ep3MfF|s9!)C$1KKE
zPNtNJR2e`2!CZP4D7rq0Vv#48IX2tV;!Zk+86(F!by1*wEA3(W+Iw^?k!AeB#1k}6
zsVp^VB+F1DtUO_vl~nUrLThQ
zli(|lih-zBMAR+}tQQNQJCBGrs00A1>XLds0Yt8&ofFK8ZW=`l4`&~yoAl0w{bdn=!u=PB?F1X-
zXhgzNMcTeUA3<9Ap|-%W2k0*@FWPs%X0IMU{qc~
z57yV0yQ4b$;BuO1RmFBGJ$sfm
z4FwOWICl>rlCB1{x|O?W#^MGsVpOu-MI=Or>c-HWL@nm6B95CG9J+%L
zO%-$yL1R61U`J9O9%pDu9h!jXDE2wZ?P~8>dio~dpaMo(Ee@x+Dsl5Xut{?$kC+3O
zF5;nd$wx&tBnErN3JHI}8p`L0feYSWz+>q*^XZC<&t_4w;G*e^$MRSVkG97!a#=5CN4})K!!(@;LnY>$gkg4btlJZRHJI|6giL
z+B~D4y~Y1oJW{;L{cHCn_g=TV=zB#6V9Q@B+)?nSg7XDC^ZzaXQhrUo$2H(8%llQ{
zk-R&df9pKvyno5hm-H`Lx%jt>PcPoRxX5wMvB$A^(afR)_Fvjxv3mgeFZy$^)M@i?
zh$I2HK_1tIunE?3_(2qImL3QATbVcH881QNQ6(AI2btj0TB%rwSn=2;Pa@HYW&md)<$
zh{pq^sKIJ#4QR4dNLQ{TG8f$m!2vc7u8FE4Qp0Li0iZAF1wk2XI$N?hOoYVxg5ki;5?3j!b5Px@&}x@rM^R67CM!+^%DO9%`tO&
zir($LL>0@#_efhObwIN#h^B#0uGHGN5LyXdAQ69?-i|3IobDag(O+c9h
zML+j>r)^VNrFUWR)*!cmOaq`EQMngrk)`eO%fTi&s}lf4;`oskkW-|$c?FJ}Z>QIg
zkH#PBY!7J-Q0sD+gA&e*RGJC29FZ`wjUC>F#c4e;gAnR+rTVxmha}X|z7iI!fobnt
zpZYeJU6QeLvX8a}NQ7btra{NT5O;zxRQPD72fT)WHvSMwJeeGWsF=%Y$_s8~+2@?L
zyEjyNA=zs~D8dWL@zT0rQ>%olSX)4=3&pv^sF^+#BBJE&`hY|?z@=Dge118O@0KQS
zj#5w?i8je0thjVXM@()mjYmqWWo)rl#Ysh~RMvQ=n?^u=9+eJ`p3ID*eoohq1(`H_
z7DuG?pm)B4LD%ISQ7VZ;!F+367#GA#)7NIe^thbv#sy}sXGF0%Z<5%mvSnEI=5jAI
zluGc@XnQnrEZ7DLtdpBNnwYP$2EhfN#BSJt!xdR@f{>oQA0W0g`Jvos$CXOR0iZ?3
zsS><72}OaFW1fX^T*0)6t)QTjluE(@DiKZmvfYa+*!r*dG9!&Jfzil*Db{u8>_vy
zsCfDqxkC&Oeky#i2gg2>XIr}g1;e*!h#Js&F!g$MfQGi(NtmJ52@r=6%3#1$C@=P1
zNhZ}n^h3bbU++=A1(P3a*2KA=xEIH7=^n2^t>QRqM8lQ+T#n40378i3@>D_A^=SOy
zTNUxraIk&{=Zp>zq9&NC_1TKR=UUH)St--km!6$f`UN?gtAGWVy1Pl>1sSNW{nkX|
zt=w6HO2f@-Bj~^)6a%78SYgb^E;2$yMK{-0SEI|rsx|vGn3@9J5Q)TFrG2f?pTbnJ
zt1TOT9>OC*8=;zcU7um`PnFT{r)sIK!={5?p?zy?zdR5P$}uQq<$;%j@#A2ya7!>#
z92w$LVunxBRDENTC&;DGLMS()lf(M5LtgU<(v)~jN0BPSv5qK}-b-BA3y}a-!%%u@
zlhv^V1dfhb(^IM!J
z3Mx@1YJekf{@cXmXP^vlX*(S=z@kUrnG2vF!}=9R{X{(M70lX3^}%pQ3=IBoTxEuU
zHYZw30Ja^0Z7@^94AH`MUB$gs5voQzhSJSt-uY(MzF@35g63#U&lShwQE*gJs&&JQ
zLEk*fG$*tx7I{0-bHV4|p9N=z16q)jX?VU;kY!0@!f=ocujj@WQ&@J1keyZ3Q(?sc
zzhT?44A~hC9F7w=y@(bh!&+aEKVy}f&_2Oiy4fo<=35rUn`>T?IG4PlXVD&E&6=Q>
z6}7A_S%t18VXDpF3!w&GQKJvE;6Sq&65yC*(m=atL1XAg;>0&n--ESBeTJ~1y$AEz
z9&8Dc&d2RzV)5wl>;pnN5d~$=593@i5{BRsWN#s}MQDQ1%5~-DAle(0u5IxN-&NK%
z0@)r7KpPC9mR~5l+4iUv~}yG&n;Vapy9yMr7b?Txy3KxBjKh6N%Roty}_*xSbETL
zM0bTOQ!!@vBDw_lcOLYaE%tI!N4CjKAMD;&RaoN=sK^bd!(PT!<(LJzvwnY33M;Ug60_|+_=#p4#
zJfe3aA^}682^>K7tqz=KPHPf_3mCPv4L}%FCxxRIFs7oxQ1Df;y;mlbH^*38?;6ot
zft-g2ubbQ;Il>HFg!Dc>h1K=g-4#uMm<@ukwNknxD$BxTVR@$e2TYR{*vBqYgA;Ml
zSO=V}p$RS&LaByr3eQQiv@IHJZjse%!$7fSSumC4u+*`$;IDw34Z(;ps&+$glpOLZ
zdMpMQhU`Lb7iRk;6^*V>ramQ^A?&Eu*^7C(5JQJ+G2>NV@sh=PYb-~j$vPSGJp`l?
zdxpNGb;Mz2t{ov|Dy8w#G{+9IoJt`2sT#rz1k{3oA!1YTFG1SW!N$>=S0Q+)#Xm6d
ztSjcwEN2&_o#7l-s4KCf#3Y)C`I1S8?(}d|SAzT(vN}j6*f;U4T>d`0-
z3){g@SJ!nkHevw$U4kPINu+5b1T{T92{h_x;1)_u9pE!)@&Z17aW+^5akUOdJ}YoI
zwxx?i?4{PgYra5ZnI(iUP9@rD@rcl@F6zyJK!_A~)FB^!2FHF=&@`0cL()g1Ga1Cz
zN^HhLf(Qdrmq6yzj{T&jKBksG`Z$eG=fO{zSmG58ln{ce4AXbTfFL1=I-gMmgl4x_~E>lBab)2A*-CU{KipW@{V
z?8HuN29vop*jNuMDiYOMuwkTtmrGyTKYF8q6IFJ%76X26A7ruCI2ZmS)1l=09
z+$BeJ_!K5Qk^G;c>zN90-Fsj0DjfSPKOT$2h|Xa%Y_N5Wke*LQHQEwRu&5D)3Ndw-
zJXfr3KD8YOU}X(}G7w$?2r%m&Br(R25qC5Sb9v{Y?C>Er%a|Q<-<6
zkZWC_9ZiyJ1Mq8sy15fuGkN2MX90qfo306olkKOrV;gy+>jBXetKAt1fsn~#hubij
zNhWCgPjjn4P0w{)?JaZKwyxR(IJb%L?i9Y2NI23aM@0^TApA-AQ#Ae|eA79c@3|*2
zzja5vIo@lNS+_%|4mma;H>|pWKmbQ8NR&Y~Y3@cL2nAz0zBSLb*^jn$w+S(-zN&L>#K<6A(jz8XNI2>4U5OXC!|pw5ef{a{Yy^rej_
zw12OU>vO
zR4DP}gJc{&2&;H5eT`gIo!mW6^kxI6g*?VhXs75`*^P~UeiP2!MqXG>jGu>sSD;Dj
zdd6NIZ7u@{&x6f~;1%@e^z;<#Lewu3AuPywXhrOp-|-lr`^$AJ%vc;lFM}BwX`|kk
z+#nPn0UuCVW504zz44y${8Jl2;VWx&I4b8CFp%nwrbrA?hU^4d3*6W`S^qx;7(
zC8PVIW<~KS*!l>aM>^dEy2fxM&+8yclhqo2LXwjaGu?3}iEi6Ej9@(MSil67cIE0{dEzQ?BQ=)OWPY(QpUE48_IRK%fz!QNZ>h
z19)Z@F#FwZvZ0o-gQL={4v9k9ntTA?0b
z*S-N^etb;862D&!=OJpHa5G3=KZjkeQ!Pb91d!#@hM+8={rHjNp-2l^Cs6CzeM`v~
z(9QTI*6zp0$?oRQE+9UffL96#gw6{u0+QlHwtz{`KhWm1tt&Z#q34%tXgp;=~>ElQn987AvLWmn5MN?`v0oYM5-l;qS&34UhpAjh*rZH)?94WpfNKAP~
zWUCmy4}()$)n1OnZF37PAFc7!@22*<$ErEh6~e~Xd;g!RK9DgBLEk@$iH%9hdW
zXJn)%VT+30;)}9IP}cGT+5kFak?sRmGesTuy-2qH5gGu-o>t#f8;Hiq#Y8mT
z5tWI;u5-v8{DnEq;A?bNsmnd+koSq1i>Qtg+w|liV(JII3YSUMcQ7C=$OkVQd#D(b
zND_sQCH+y7LRgxq&(7ic7m$kJ!_?@jNV3&c<&pNlaq4`(U}zow$IN;CYb>boK0$<&
zmbew2lidd~trEoKxI9bab4a$JFC5TP2aR|Zdoi_c_#jcTkB#pPFr_lR^gJBA$S|jH
zi}>an;RP|uyu?@6Ac6~@PoOaxpwzkS!}>SwfIH1}>Rd1<-NrQ5rUP_}%6-P`pZc{p
i@UmukP{nh2b@@KTm$eGB1-}4@w#4L3(=s_sVE!8k#f!rL
diff --git a/.smallclaw/users/papa/workspace/final_insert.py b/.smallclaw/users/papa/workspace/final_insert.py
deleted file mode 100644
index 8862f30..0000000
--- a/.smallclaw/users/papa/workspace/final_insert.py
+++ /dev/null
@@ -1,141 +0,0 @@
-import sqlite3
-import os
-
-db_path = os.path.abspath('dental_dict.db')
-print(f"Using DB at: {db_path}")
-
- ("건강보험", "National Health Insurance", "국민건강보험 적용 치과 치료", "일반"),
- ("구강 스캐너", "Intraoral Scanner", "입안을 3D로 스캔하는 디지털 장비", "디지털"),
- ("디지털 치과", "Digital Dentistry", "디지털 기술을 활용한 현대 치과 진료", "디지털"),
- ("라미네이트", "Laminate Veneer", "치아 앞면에 부착하는 얇은 세라믹", "심미"),
- ("발치", "Tooth Extraction", "치아를 뽑는 시술", "외과"),
- ("뼈이식", "Bone Graft", "부족한 턱뼈를 보충하는 수술", "임플란트"),
- ("사랑니", "Wisdom Tooth", "세 번째 큰어금니(제3대구치)", "외과"),
- ("사랑니 발치", "Wisdom Tooth Extraction", "사랑니를 뽑는 수술", "외과"),
- ("상악동 거상술", "Sinus Lift", "윗턱 어금니 부위 뼈를 보충하는 수술", "임플란트"),
- ("스케일링", "Scaling", "치석을 제거하는 기본 잇몸 치료", "치주"),
- ("신경치료 (근관치료)", "Root Canal Treatment", "감염된 치아 신경을 제거하는 치료", "보존"),
- ("올온포", "All-on-4", "4개 임플란트로 전체 치아를 지지하는 방식", "임플란트"),
- ("인비절라인", "Invisalign", "세계 1위 투명교정 시스템", "교정"),
- ("임플란트 보험", "Implant Insurance Coverage", "건강보험이 적용되는 임플란트", "보험"),
- ("충치", "Dental Caries / Cavity", "세균에 의해 치아가 썩는 질환", "보존"),
- ("치아 미백", "Tooth Whitening", "치아 색상을 밝게 하는 시술", "심미"),
- ("치아교정", "Orthodontics", "치아 배열과 교합을 바로잡는 치료", "교정"),
- ("치주염", "Periodontitis", "잇몸과 치조골이 파괴되는 염증 질환", "치주"),
- ("크라운", "Crown", "치아 전체를 감싸는 보철물", "보철"),
- ("1급 부정교합", "Class I Malocclusion", "위아래 턱 관계는 정상이나 치아 배열이 불량한 상태", "교정"),
- ("2급 부정교합", "Class II Malocclusion", "윗턱이 돌출된 부정교합", "교정"),
- ("3급 부정교합", "Class III Malocclusion", "아랫턱이 돌출된 부정교합 (주걱턱)", "교정"),
- ("CAD/CAM", "Computer-Aided Design/Manufacturing", "컴퓨터로 설계하고 기계로 제작하는 기술", "디지털"),
- ("GBR", "Guided Bone Regeneration", "차폐막을 이용한 뼈 재생 유도술", "임플란트"),
- ("IPR", "Interproximal Reduction", "치아 사이 미세 삭제", "교정"),
- ("LED 광조사기", "LED Curing Light", "레진을 굳히는 빛을 쏘는 장비", "장비"),
- ("PFM 크라운", "Porcelain-Fused-to-Metal", "금속 위에 도자기를 입힌 크라운", "보철"),
- ("PRP", "Platelet-Rich Plasma", "자가 혈소판 농축 혈장", "외과"),
- ("PrimeScan", "PrimeScan", "프리미엄 디지털 구강 스캐너", "장비"),
- ("SSC (소아 크라운)", "Stainless Steel Crown", "유치에 씌우는 스테인리스 기성 크라운", "소아"),
- ("SpeedFire", "SpeedFire", "초고속 세라믹 소성로", "장비"),
- ("TAD (미니 스크루)", "Temporary Anchorage Device", "교정용 임시 고정 나사", "교정"),
- ("X-ray", "Dental X-ray", "치과용 방사선 촬영", "진단"),
- ("e.max", "IPS e.max", "리튬디실리케이트 세라믹 소재", "보철"),
- ("iTero 스캐너", "iTero Scanner", "인비절라인용 디지털 구강 스캐너", "장비"),
- ("가이드 수술", "Guided Surgery", "디지털 가이드를 이용한 정밀 수술", "임플란트"),
- ("개방교합", "Open Bite", "윗니와 아랫니가 맞닿지 않는 상태", "교정"),
- ("거타퍼쳐", "Gutta-Percha", "근관 충전에 사용하는 고무 재료", "보존"),
- ("건성 소켓", "Dry Socket", "발치 후 혈병이 빠져 뼈가 노출된 상태", "외과"),
- ("골다공증과 임플란트", "Osteoporosis and Implants", "골다공증 환자의 임플란트 시술 고려사항", "임플란트"),
- ("골유착", "Osseointegration", "임플란트와 턱뼈가 단단히 결합하는 과정", "임플란트"),
- ("공간 유지 장치", "Space Maintainer", "유치 조기 상실 시 공간을 유지하는 장치", "소아"),
- ("과개교합", "Deep Bite / Overbite", "윗니가 아랫니를 과도하게 덮는 상태", "교정"),
- ("과잉치", "Supernumerary Tooth", "정상 개수보다 많은 여분의 치아", "소아"),
- ("교정 고정원", "Anchorage", "치아를 이동시킬 때 고정점 역할을 하는 것", "교정"),
- ("교정용 고무줄", "Orthodontic Elastics", "교합 조정에 사용하는 탄성 고무줄", "교정"),
- ("교정용 왁스", "Orthodontic Wax", "브라켓으로 인한 점막 자극을 완화하는 왁스", "교정"),
- ("교합", "Occlusion", "위아래 치아가 맞물리는 것", "일반"),
- ("교합 조정", "Bite Adjustment", "치아의 높낮이를 미세 조정하는 시술", "일반"),
- ("구강 건조증", "Dry Mouth (Xerostomia)", "침 분비가 줄어 입안이 마르는 상태", "일반"),
- ("구강 마이크로바이옴", "Oral Microbiome", "입안에 서식하는 미생물 생태계", "연구"),
- ("구강 세정기 (워터픽)", "Water Flosser", "물줄기로 치아 사이를 청소하는 장치", "관리"),
- ("구강 점막", "Oral Mucosa", "입안을 감싸는 점막 조직", "해부학"),
- ("구강 해부학", "Oral Anatomy", "입 안의 구조와 명칭", "해부학"),
- ("구강암 검진", "Oral Cancer Screening", "구강암의 조기 발견을 위한 검사", "진단"),
- ("구강외과", "Oral and Maxillofacial Surgery", "구강, 턱, 얼굴 부위 수술 전문 분야", "분과"),
- ("구개", "Palate", "입천장", "해부학"),
- ("구내염", "Stomatitis", "입안 점막에 생기는 염증성 궤양", "일반"),
- ("구취", "Halitosis", "입에서 나는 불쾌한 냄새", "일반"),
- ("국소마취", "Local Anesthesia", "치료 부위만 마취하는 방법", "일반"),
- ("근관 길이 측정기", "Apex Locator", "신경치료 시 치아 뿌리 끝까지의 길이를 측정하는 장비", "장비"),
- ("근관 충전", "Root Canal Filling", "신경치료 후 빈 공간을 메우는 과정", "보존"),
- ("글래스 아이오노머", "Glass Ionomer", "불소를 방출하는 충전 재료", "보존"),
- ("금 크라운", "Gold Crown", "금합금으로 제작한 크라운", "보철"),
- ("급속 확장 장치", "Rapid Palatal Expander", "윗턱을 넓히는 장치", "교정"),
- ("나이트 가드", "Night Guard", "이갈이 방지용 보호 장치", "장치"),
- ("낭종", "Cyst", "턱뼈나 잇몸에 생기는 주머니 형태 병소", "외과"),
- ("네오 임플란트", "Neo Implant", "국산 프리미엄 임플란트 시스템", "임플란트"),
- ("노인 임플란트", "Senior Implant Coverage", "만 65세 이상 임플란트 보험 적용", "보험"),
- ("당뇨와 임플란트", "Diabetes and Implants", "당뇨 환자의 임플란트 시술 고려사항", "임플란트"),
- ("덴티움", "Dentium", "한국 프리미엄 임플란트 시스템", "임플란트"),
- ("동의서", "Informed Consent", "치료 전 환자에게 설명하고 동의를 받는 절차", "일반"),
- ("디지털 가이드", "Digital Surgical Guide", "3D 설계 기반 임플란트 식립 가이드", "디지털"),
- ("디지털 인상", "Digital Impression", "구강 스캐너로 치아 형태를 기록하는 방법", "디지털"),
- ("러버댐", "Dental Dam (Rubber Dam)", "치료 부위를 격리하는 고무 방수막", "보존"),
- ("레이저 치주치료", "Laser Periodontal Therapy", "레이저를 이용한 잇몸 치료", "치주"),
- ("레진 (복합 레진)", "Composite Resin", "치아색 충전 재료", "보존"),
- ("리콜 (정기 검진)", "Dental Recall", "정기적으로 치과를 방문하는 검진 시스템", "일반"),
- ("매복치", "Impacted Tooth", "뼈나 잇몸 속에 묻혀 있는 치아", "외과"),
- ("메릴랜드 브릿지", "Maryland Bridge", "최소 삭제로 부착하는 접착식 브릿지", "보철"),
- ("메탈프리", "Metal-Free", "금속을 사용하지 않는 보철 방식", "보철"),
- ("멸균", "Sterilization", "모든 미생물을 완전히 제거하는 과정", "일반"),
- ("무절개 임플란트", "Flapless Implant Surgery", "잇몸을 절개하지 않는 임플란트 수술", "임플란트"),
- ("미니 임플란트", "Mini Implant", "직경이 작은 소형 임플란트", "임플란트"),
- ("밀링", "Dental Milling / Milling", "세라믹 블록을 깎아 보철물을 만드는 과정", "디지털"),
- ("반대교합", "Crossbite", "위아래 치아의 교합이 반대로 물리는 상태", "교정"),
- ("발치와 보존술", "Socket Preservation", "발치 후 뼈 흡수를 방지하는 시술", "임플란트"),
- ("백악질", "Cementum", "치아 뿌리를 감싸는 얇은 층", "해부학"),
- ("법랑질", "Enamel", "치아의 가장 바깥 층", "해부학"),
- ("법랑질 미세삭제술", "Enamel Microabrasion", "법랑질 표면의 변색을 제거하는 시술", "심미"),
- ("본딩", "Dental Bonding", "레진으로 치아 모양을 수복하는 시술", "심미"),
- ("본인부담금", "Copayment", "건강보험 적용 시 환자가 내는 금액", "일반"),
- ("봉합", "Suture", "절개한 부위를 실로 꿰매는 것", "외과"),
- ("부분 틀니", "Partial Denture", "일부 치아가 없을 때 사용하는 틀니", "보철"),
- ("부정교합", "Malocclusion", "윗니와 아랫니가 제대로 맞물리지 않는 상태", "교정"),
- ("불소", "Fluoride", "충치 예방에 효과적인 광물질", "예방"),
- ("불소 도포", "Fluoride Application", "치아에 불소를 직접 바르는 예방 치료", "예방"),
- ("브라켓", "Bracket", "치아에 부착하는 교정 장치", "교정"),
- ("브릿지", "Bridge", "빠진 치아 양쪽을 이용한 고정식 보철", "보철"),
- ("비급여", "Non-covered Treatment", "건강보험이 적용되지 않는 치료", "일반"),
- ("비니어", "Veneer", "치아 앞면에 얇게 부착하는 보철물", "심미"),
- ("비스포스포네이트", "Bisphosphonate", "골다공증 치료약과 턱뼈 괴사 위험", "일반"),
- ("상아질", "Dentin", "법랑질 안쪽의 치아 층", "해부학"),
- ("상악", "Maxilla", "위턱뼈", "해부학"),
- ("상악동", "Maxillary Sinus", "윗턱 어금니 위의 빈 공간", "해부학"),
- ("색조 선택", "Shade Matching", "보철물의 색을 자연치아에 맞추는 과정", "보철"),
- ("석션 (흡인기)", "Dental Suction", "구강 내 물과 타액을 흡입하는 장치", "장비"),
- ("설소대 단축증", "Tongue-Tie (Ankyloglossia)", "혀 아래 소대가 짧아 혀 움직임이 제한되는 상태", "일반"),
- ("설측교정", "Lingual Orthodontics", "치아 안쪽에 부착하는 교정", "교정"),
- ("세라믹 브라켓", "Ceramic Bracket", "치아색 세라믹 소재 교정 장치", "교정"),
- ("소대", "Frenum", "입술이나 혀를 잇몸에 연결하는 조직 띠", "해부학")
-]
-
-conn = sqlite3.connect('dental_dict.db')
-cursor = conn.cursor()
-
-# 테이블이 없으면 생성 (혹시 모르니)
-cursor.execute('''
- CREATE TABLE IF NOT EXISTS dental_terms (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- term_ko TEXT UNIQUE,
- term_en TEXT,
- definition TEXT,
- category TEXT
- )
-''')
-
-cursor.executemany('''
- INSERT OR IGNORE INTO dental_terms (term_ko, term_en, definition, category)
- VALUES (?, ?, ?, ?)
-''', terms)
-
-conn.commit()
-print(f"Successfully inserted {cursor.rowcount} terms.")
-conn.close()
diff --git a/.smallclaw/users/papa/workspace/final_insert_v2.py b/.smallclaw/users/papa/workspace/final_insert_v2.py
deleted file mode 100644
index 62f0e33..0000000
--- a/.smallclaw/users/papa/workspace/final_insert_v2.py
+++ /dev/null
@@ -1,143 +0,0 @@
-import sqlite3
-import os
-
-db_path = os.path.abspath('dental_dict.db')
-print(f"Using DB at: {db_path}")
-
-terms = [
- ("3D CT (CBCT)", "Cone Beam Computed Tomography", "치과용 3차원 컴퓨터 단층촬영", "디지털"),
- ("CEREC", "CEREC", "CAD/CAM 기반 당일 보철 제작 시스템", "디지털"),
- ("건강보험", "National Health Insurance", "국민건강보험 적용 치과 치료", "일반"),
- ("구강 스캐너", "Intraoral Scanner", "입안을 3D로 스캔하는 디지털 장비", "디지털"),
- ("디지털 치과", "Digital Dentistry", "디지털 기술을 활용한 현대 치과 진료", "디지털"),
- ("라미네이트", "Laminate Veneer", "치아 앞면에 부착하는 얇은 세라믹", "심미"),
- ("발치", "Tooth Extraction", "치아를 뽑는 시술", "외과"),
- ("뼈이식", "Bone Graft", "부족한 턱뼈를 보충하는 수술", "임플란트"),
- ("사랑니", "Wisdom Tooth", "세 번째 큰어금니(제3대구치)", "외과"),
- ("사랑니 발치", "Wisdom Tooth Extraction", "사랑니를 뽑는 수술", "외과"),
- ("상악동 거상술", "Sinus Lift", "윗턱 어금니 부위 뼈를 보충하는 수술", "임플란트"),
- ("스케일링", "Scaling", "치석을 제거하는 기본 잇몸 치료", "치주"),
- ("신경치료 (근관치료)", "Root Canal Treatment", "감염된 치아 신경을 제거하는 치료", "보존"),
- ("올온포", "All-on-4", "4개 임플란트로 전체 치아를 지지하는 방식", "임플란트"),
- ("인비절라인", "Invisalign", "세계 1위 투명교정 시스템", "교정"),
- ("임플란트 보험", "Implant Insurance Coverage", "건강보험이 적용되는 임플란트", "보험"),
- ("충치", "Dental Caries / Cavity", "세균에 의해 치아가 썩는 질환", "보존"),
- ("치아 미백", "Tooth Whitening", "치아 색상을 밝게 하는 시술", "심미"),
- ("치아교정", "Orthodontics", "치아 배열과 교합을 바로잡는 치료", "교정"),
- ("치주염", "Periodontitis", "잇몸과 치조골이 파괴되는 염증 질환", "치주"),
- ("크라운", "Crown", "치아 전체를 감싸는 보철물", "보철"),
- ("1급 부정교합", "Class I Malocclusion", "위아래 턱 관계는 정상이나 치아 배열이 불량한 상태", "교정"),
- ("2급 부정교합", "Class II Malocclusion", "윗턱이 돌출된 부정교합", "교정"),
- ("3급 부정교합", "Class III Malocclusion", "아랫턱이 돌출된 부정교합 (주걱턱)", "교정"),
- ("CAD/CAM", "Computer-Aided Design/Manufacturing", "컴퓨터로 설계하고 기계로 제작하는 기술", "디지털"),
- ("GBR", "Guided Bone Regeneration", "차폐막을 이용한 뼈 재생 유도술", "임플란트"),
- ("IPR", "Interproximal Reduction", "치아 사이 미세 삭제", "교정"),
- ("LED 광조사기", "LED Curing Light", "레진을 굳히는 빛을 쏘는 장비", "장비"),
- ("PFM 크라운", "Porcelain-Fused-to-Metal", "금속 위에 도자기를 입힌 크라운", "보철"),
- ("PRP", "Platelet-Rich Plasma", "자가 혈소판 농축 혈장", "외과"),
- ("PrimeScan", "PrimeScan", "프리미엄 디지털 구강 스캐너", "장비"),
- ("SSC (소아 크라운)", "Stainless Steel Crown", "유치에 씌우는 스테인리스 기성 크라운", "소아"),
- ("SpeedFire", "SpeedFire", "초고속 세라믹 소성로", "장비"),
- ("TAD (미니 스크루)", "Temporary Anchorage Device", "교정용 임시 고정 나사", "교정"),
- ("X-ray", "Dental X-ray", "치과용 방사선 촬영", "진단"),
- ("e.max", "IPS e.max", "리튬디실리케이트 세라믹 소재", "보철"),
- ("iTero 스캐너", "iTero Scanner", "인비절라인용 디지털 구강 스캐너", "장비"),
- ("가이드 수술", "Guided Surgery", "디지털 가이드를 이용한 정밀 수술", "임플란트"),
- ("개방교합", "Open Bite", "윗니와 아랫니가 맞닿지 않는 상태", "교정"),
- ("거타퍼쳐", "Gutta-Percha", "근관 충전에 사용하는 고무 재료", "보존"),
- ("건성 소켓", "Dry Socket", "발치 후 혈병이 빠져 뼈가 노출된 상태", "외과"),
- ("골다공증과 임플란트", "Osteoporosis and Implants", "골다공증 환자의 임플란트 시술 고려사항", "임플란트"),
- ("골유착", "Osseointegration", "임플란트와 턱뼈가 단단히 결합하는 과정", "임플란트"),
- ("공간 유지 장치", "Space Maintainer", "유치 조기 상실 시 공간을 유지하는 장치", "소아"),
- ("과개교합", "Deep Bite / Overbite", "윗니가 아랫니를 과도하게 덮는 상태", "교정"),
- ("과잉치", "Supernumerary Tooth", "정상 개수보다 많은 여분의 치아", "소아"),
- ("교정 고정원", "Anchorage", "치아를 이동시킬 때 고정점 역할을 하는 것", "교정"),
- ("교정용 고무줄", "Orthodontic Elastics", "교합 조정에 사용하는 탄성 고무줄", "교정"),
- ("교정용 왁스", "Orthodontic Wax", "브라켓으로 인한 점막 자극을 완화하는 왁스", "교정"),
- ("교합", "Occlusion", "위아래 치아가 맞물리는 것", "일반"),
- ("교합 조정", "Bite Adjustment", "치아의 높낮이를 미세 조정하는 시술", "일반"),
- ("구강 건조증", "Dry Mouth (Xerostomia)", "침 분비가 줄어 입안이 마르는 상태", "일반"),
- ("구강 마이크로바이옴", "Oral Microbiome", "입안에 서식하는 미생물 생태계", "연구"),
- ("구강 세정기 (워터픽)", "Water Flosser", "물줄기로 치아 사이를 청소하는 장치", "관리"),
- ("구강 점막", "Oral Mucosa", "입안을 감싸는 점막 조직", "해부학"),
- ("구강 해부학", "Oral Anatomy", "입 안의 구조와 명칭", "해부학"),
- ("구강암 검진", "Oral Cancer Screening", "구강암의 조기 발견을 위한 검사", "진단"),
- ("구강외과", "Oral and Maxillofacial Surgery", "구강, 턱, 얼굴 부위 수술 전문 분야", "분과"),
- ("구개", "Palate", "입천장", "해부학"),
- ("구내염", "Stomatitis", "입안 점막에 생기는 염증성 궤양", "일반"),
- ("구취", "Halitosis", "입에서 나는 불쾌한 냄새", "일반"),
- ("국소마취", "Local Anesthesia", "치료 부위만 마취하는 방법", "일반"),
- ("근관 길이 측정기", "Apex Locator", "신경치료 시 치아 뿌리 끝까지의 길이를 측정하는 장비", "장비"),
- ("근관 충전", "Root Canal Filling", "신경치료 후 빈 공간을 메우는 과정", "보존"),
- ("글래스 아이오노머", "Glass Ionomer", "불소를 방출하는 충전 재료", "보존"),
- ("금 크라운", "Gold Crown", "금합금으로 제작한 크라운", "보철"),
- ("급속 확장 장치", "Rapid Palatal Expander", "윗턱을 넓히는 장치", "교정"),
- ("나이트 가드", "Night Guard", "이갈이 방지용 보호 장치", "장치"),
- ("낭종", "Cyst", "턱뼈나 잇몸에 생기는 주머니 형태 병소", "외과"),
- ("네오 임플란트", "Neo Implant", "국산 프리미엄 임플란트 시스템", "임플란트"),
- ("노인 임플란트", "Senior Implant Coverage", "만 65세 이상 임플란트 보험 적용", "보험"),
- ("당뇨와 임플란트", "Diabetes and Implants", "당뇨 환자의 임플란트 시술 고려사항", "임플란트"),
- ("덴티움", "Dentium", "한국 프리미엄 임플란트 시스템", "임플란트"),
- ("동의서", "Informed Consent", "치료 전 환자에게 설명하고 동의를 받는 절차", "일반"),
- ("디지털 가이드", "Digital Surgical Guide", "3D 설계 기반 임플란트 식립 가이드", "디지털"),
- ("디지털 인상", "Digital Impression", "구강 스캐너로 치아 형태를 기록하는 방법", "디지털"),
- ("러버댐", "Dental Dam (Rubber Dam)", "치료 부위를 격리하는 고무 방수막", "보존"),
- ("레이저 치주치료", "Laser Periodontal Therapy", "레이저를 이용한 잇몸 치료", "치주"),
- ("레진 (복합 레진)", "Composite Resin", "치아색 충전 재료", "보존"),
- ("리콜 (정기 검진)", "Dental Recall", "정기적으로 치과를 방문하는 검진 시스템", "일반"),
- ("매복치", "Impacted Tooth", "뼈나 잇몸 속에 묻혀 있는 치아", "외과"),
- ("메릴랜드 브릿지", "Maryland Bridge", "최소 삭제로 부착하는 접착식 브릿지", "보철"),
- ("메탈프리", "Metal-Free", "금속을 사용하지 않는 보철 방식", "보철"),
- ("멸균", "Sterilization", "모든 미생물을 완전히 제거하는 과정", "일반"),
- ("무절개 임플란트", "Flapless Implant Surgery", "잇몸을 절개하지 않는 임플란트 수술", "임플란트"),
- ("미니 임플란트", "Mini Implant", "직경이 작은 소형 임플란트", "임플란트"),
- ("밀링", "Dental Milling / Milling", "세라믹 블록을 깎아 보철물을 만드는 과정", "디지털"),
- ("반대교합", "Crossbite", "위아래 치아의 교합이 반대로 물리는 상태", "교정"),
- ("발치와 보존술", "Socket Preservation", "발치 후 뼈 흡수를 방지하는 시술", "임플란트"),
- ("백악질", "Cementum", "치아 뿌리를 감싸는 얇은 층", "해부학"),
- ("법랑질", "Enamel", "치아의 가장 바깥 층", "해부학"),
- ("법랑질 미세삭제술", "Enamel Microabrasion", "법랑질 표면의 변색을 제거하는 시술", "심미"),
- ("본딩", "Dental Bonding", "레진으로 치아 모양을 수복하는 시술", "심미"),
- ("본인부담금", "Copayment", "건강보험 적용 시 환자가 내는 금액", "일반"),
- ("봉합", "Suture", "절개한 부위를 실로 꿰매는 것", "외과"),
- ("부분 틀니", "Partial Denture", "일부 치아가 없을 때 사용하는 틀니", "보철"),
- ("부정교합", "Malocclusion", "윗니와 아랫니가 제대로 맞물리지 않는 상태", "교정"),
- ("불소", "Fluoride", "충치 예방에 효과적인 광물질", "예방"),
- ("불소 도포", "Fluoride Application", "치아에 불소를 직접 바르는 예방 치료", "예방"),
- ("브라켓", "Bracket", "치아에 부착하는 교정 장치", "교정"),
- ("브릿지", "Bridge", "빠진 치아 양쪽을 이용한 고정식 보철", "보철"),
- ("비급여", "Non-covered Treatment", "건강보험이 적용되지 않는 치료", "일반"),
- ("비니어", "Veneer", "치아 앞면에 얇게 부착하는 보철물", "심미"),
- ("비스포스포네이트", "Bisphosphonate", "골다공증 치료약과 턱뼈 괴사 위험", "일반"),
- ("상아질", "Dentin", "법랑질 안쪽의 치아 층", "해부학"),
- ("상악", "Maxilla", "위턱뼈", "해부학"),
- ("상악동", "Maxillary Sinus", "윗턱 어금니 위의 빈 공간", "해부학"),
- ("색조 선택", "Shade Matching", "보철물의 색을 자연치아에 맞추는 과정", "보철"),
- ("석션 (흡인기)", "Dental Suction", "구강 내 물과 타액을 흡입하는 장치", "장비"),
- ("설소대 단축증", "Tongue-Tie (Ankyloglossia)", "혀 아래 소대가 짧아 혀 움직임이 제한되는 상태", "일반"),
- ("설측교정", "Lingual Orthodontics", "치아 안쪽에 부착하는 교정", "교정"),
- ("세라믹 브라켓", "Ceramic Bracket", "치아색 세라믹 소재 교정 장치", "교정"),
- ("소대", "Frenum", "입술이나 혀를 잇몸에 연결하는 조직 띠", "해부학")
-]
-
-conn = sqlite3.connect(db_path)
-cursor = conn.cursor()
-
-cursor.execute('''
- CREATE TABLE IF NOT EXISTS dental_terms (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- term_ko TEXT UNIQUE,
- term_en TEXT,
- definition TEXT,
- category TEXT
- )
-''')
-
-cursor.executemany('''
- INSERT OR IGNORE INTO dental_terms (term_ko, term_en, definition, category)
- VALUES (?, ?, ?, ?)
-''', terms)
-
-conn.commit()
-print(f"Successfully inserted {cursor.rowcount} terms into {db_path}.")
-conn.close()
diff --git a/.smallclaw/users/papa/workspace/insert_terms.py b/.smallclaw/users/papa/workspace/insert_terms.py
deleted file mode 100644
index f15e579..0000000
--- a/.smallclaw/users/papa/workspace/insert_terms.py
+++ /dev/null
@@ -1,136 +0,0 @@
-import sqlite3
-import os
-
-db_path = 'dental_dict.db'
-
-terms = [
- ("CEREC", "CEREC", "CAD/CAM 기반 당일 보철 제작 시스템", "디지털"),
- ("건강보험", "National Health Insurance", "국민건강보험 적용 치과 치료", "일반"),
- ("구강 스캐너", "Intraoral Scanner", "입안을 3D로 스캔하는 디지털 장비", "디지털"),
- ("디지털 치과", "Digital Dentistry", "디지털 기술을 활용한 현대 치과 진료", "디지털"),
- ("라미네이트", "Laminate Veneer", "치아 앞면에 부착하는 얇은 세라믹", "심미"),
- ("발치", "Tooth Extraction", "치아를 뽑는 시술", "외과"),
- ("뼈이식", "Bone Graft", "부족한 턱뼈를 보충하는 수술", "임플란트"),
- ("사랑니", "Wisdom Tooth", "세 번째 큰어금니(제3대구치)", "외과"),
- ("사랑니 발치", "Wisdom Tooth Extraction", "사랑니를 뽑는 수술", "외과"),
- ("상악동 거상술", "Sinus Lift", "윗턱 어금니 부위 뼈를 보충하는 수술", "임플란트"),
- ("스케일링", "Scaling", "치석을 제거하는 기본 잇몸 치료", "치주"),
- ("신경치료 (근관치료)", "Root Canal Treatment", "감염된 치아 신경을 제거하는 치료", "보존"),
- ("올온포", "All-on-4", "4개 임플란트로 전체 치아를 지지하는 방식", "임플란트"),
- ("인비절라인", "Invisalign", "세계 1위 투명교정 시스템", "교정"),
- ("임플란트 보험", "Implant Insurance Coverage", "건강보험이 적용되는 임플란트", "보험"),
- ("충치", "Dental Caries / Cavity", "세균에 의해 치아가 썩는 질환", "보존"),
- ("치아 미백", "Tooth Whitening", "치아 색상을 밝게 하는 시술", "심미"),
- ("치아교정", "Orthodontics", "치아 배열과 교합을 바로잡는 치료", "교정"),
- ("치주염", "Periodontitis", "잇몸과 치조골이 파괴되는 염증 질환", "치주"),
- ("크라운", "Crown", "치아 전체를 감싸는 보철물", "보철"),
- ("1급 부정교합", "Class I Malocclusion", "위아래 턱 관계는 정상이나 치아 배열이 불량한 상태", "교정"),
- ("2급 부정교합", "Class II Malocclusion", "윗턱이 돌출된 부정교합", "교정"),
- ("3급 부정교합", "Class III Malocclusion", "아랫턱이 돌출된 부정교합 (주걱턱)", "교정"),
- ("CAD/CAM", "Computer-Aided Design/Manufacturing", "컴퓨터로 설계하고 기계로 제작하는 기술", "디지털"),
- ("GBR", "Guided Bone Regeneration", "차폐막을 이용한 뼈 재생 유도술", "임플란트"),
- ("IPR", "Interproximal Reduction", "치아 사이 미세 삭제", "교정"),
- ("LED 광조사기", "LED Curing Light", "레진을 굳히는 빛을 쏘는 장비", "장비"),
- ("PFM 크라운", "Porcelain-Fused-to-Metal", "금속 위에 도자기를 입힌 크라운", "보철"),
- ("PRP", "Platelet-Rich Plasma", "자가 혈소판 농축 혈장", "외과"),
- ("PrimeScan", "PrimeScan", "프리미엄 디지털 구강 스캐너", "장비"),
- ("SSC (소아 크라운)", "Stainless Steel Crown", "유치에 씌우는 스테인리스 기성 크라운", "소아"),
- ("SpeedFire", "SpeedFire", "초고속 세라믹 소성로", "장비"),
- ("TAD (미니 스크루)", "Temporary Anchorage Device", "교정용 임시 고정 나사", "교정"),
- ("X-ray", "Dental X-ray", "치과용 방사선 촬영", "진단"),
- ("e.max", "IPS e.max", "리튬디실리케이트 세라믹 소재", "보철"),
- ("iTero 스캐너", "iTero Scanner", "인비절라인용 디지털 구강 스캐너", "장비"),
- ("가이드 수술", "Guided Surgery", "디지털 가이드를 이용한 정밀 수술", "임플란트"),
- ("개방교합", "Open Bite", "윗니와 아랫니가 맞닿지 않는 상태", "교정"),
- ("거타퍼쳐", "Gutta-Percha", "근관 충전에 사용하는 고무 재료", "보존"),
- ("건성 소켓", "Dry Socket", "발치 후 혈병이 빠져 뼈가 노출된 상태", "외과"),
- ("골다공증과 임플란트", "Osteoporosis and Implants", "골다공증 환자의 임플란트 시술 고려사항", "임플란트"),
- ("골유착", "Osseointegration", "임플란트와 턱뼈가 단단히 결합하는 과정", "임플란트"),
- ("공간 유지 장치", "Space Maintainer", "유치 조기 상실 시 공간을 유지하는 장치", "소아"),
- ("과개교합", "Deep Bite / Overbite", "윗니가 아랫니를 과도하게 덮는 상태", "교정"),
- ("과잉치", "Supernumerary Tooth", "정상 개수보다 많은 여분의 치아", "소아"),
- ("교정 고정원", "Anchorage", "치아를 이동시킬 때 고정점 역할을 하는 것", "교정"),
- ("교정용 고무줄", "Orthodontic Elastics", "교합 조정에 사용하는 탄성 고무줄", "교정"),
- ("교정용 왁스", "Orthodontic Wax", "브라켓으로 인한 점막 자극을 완화하는 왁스", "교정"),
- ("교합", "Occlusion", "위아래 치아가 맞물리는 것", "일반"),
- ("교합 조정", "Bite Adjustment", "치아의 높낮이를 미세 조정하는 시술", "일반"),
- ("구강 건조증", "Dry Mouth (Xerostomia)", "침 분비가 줄어 입안이 마르는 상태", "일반"),
- ("구강 마이크로바이옴", "Oral Microbiome", "입안에 서식하는 미생물 생태계", "연구"),
- ("구강 세정기 (워터픽)", "Water Flosser", "물줄기로 치아 사이를 청소하는 장치", "관리"),
- ("구강 점막", "Oral Mucosa", "입안을 감싸는 점막 조직", "해부학"),
- ("구강 해부학", "Oral Anatomy", "입 안의 구조와 명칭", "해부학"),
- ("구강암 검진", "Oral Cancer Screening", "구강암의 조기 발견을 위한 검사", "진단"),
- ("구강외과", "Oral and Maxillofacial Surgery", "구강, 턱, 얼굴 부위 수술 전문 분야", "분과"),
- ("구개", "Palate", "입천장", "해부학"),
- ("구내염", "Stomatitis", "입안 점막에 생기는 염증성 궤양", "일반"),
- ("구취", "Halitosis", "입에서 나는 불쾌한 냄새", "일반"),
- ("국소마취", "Local Anesthesia", "치료 부위만 마취하는 방법", "일반"),
- ("근관 길이 측정기", "Apex Locator", "신경치료 시 치아 뿌리 끝까지의 길이를 측정하는 장비", "장비"),
- ("근관 충전", "Root Canal Filling", "신경치료 후 빈 공간을 메우는 과정", "보존"),
- ("글래스 아이오노머", "Glass Ionomer", "불소를 방출하는 충전 재료", "보존"),
- ("금 크라운", "Gold Crown", "금합금으로 제작한 크라운", "보철"),
- ("급속 확장 장치", "Rapid Palatal Expander", "윗턱을 넓히는 장치", "교정"),
- ("나이트 가드", "Night Guard", "이갈이 방지용 보호 장치", "장치"),
- ("낭종", "Cyst", "턱뼈나 잇몸에 생기는 주머니 형태 병소", "외과"),
- ("네오 임플란트", "Neo Implant", "국산 프리미엄 임플란트 시스템", "임플란트"),
- ("노인 임플란트", "Senior Implant Coverage", "만 65세 이상 임플란트 보험 적용", "보험"),
- ("당뇨와 임플란트", "Diabetes and Implants", "당뇨 환자의 임플란트 시술 고려사항", "임플란트"),
- ("덴티움", "Dentium", "한국 프리미엄 임플란트 시스템", "임플란트"),
- ("동의서", "Informed Consent", "치료 전 환자에게 설명하고 동의를 받는 절차", "일반"),
- ("디지털 가이드", "Digital Surgical Guide", "3D 설계 기반 임플란트 식립 가이드", "디지털"),
- ("디지털 인상", "Digital Impression", "구강 스캐너로 치아 형태를 기록하는 방법", "디지털"),
- ("러버댐", "Dental Dam (Rubber Dam)", "치료 부위를 격리하는 고무 방수막", "보존"),
- ("레이저 치주치료", "Laser Periodontal Therapy", "레이저를 이용한 잇몸 치료", "치주"),
- ("레진 (복합 레진)", "Composite Resin", "치아색 충전 재료", "보존"),
- ("리콜 (정기 검진)", "Dental Recall", "정기적으로 치과를 방문하는 검진 시스템", "일반"),
- ("매복치", "Impacted Tooth", "뼈나 잇몸 속에 묻혀 있는 치아", "외과"),
- ("메릴랜드 브릿지", "Maryland Bridge", "최소 삭제로 부착하는 접착식 브릿지", "보철"),
- ("메탈프리", "Metal-Free", "금속을 사용하지 않는 보철 방식", "보철"),
- ("멸균", "Sterilization", "모든 미생물을 완전히 제거하는 과정", "일반"),
- ("무절개 임플란트", "Flapless Implant Surgery", "잇몸을 절개하지 않는 임플란트 수술", "임플란트"),
- ("미니 임플란트", "Mini Implant", "직경이 작은 소형 임플란트", "임플란트"),
- ("밀링", "Dental Milling / Milling", "세라믹 블록을 깎아 보철물을 만드는 과정", "디지털"),
- ("반대교합", "Crossbite", "위아래 치아의 교합이 반대로 물리는 상태", "교정"),
- ("발치와 보존술", "Socket Preservation", "발치 후 뼈 흡수를 방지하는 시술", "임플란트"),
- ("백악질", "Cementum", "치아 뿌리를 감싸는 얇은 층", "해부학"),
- ("법랑질", "Enamel", "치아의 가장 바깥 층", "해부학"),
- ("법랑질 미세삭제술", "Enamel Microabrasion", "법랑질 표면의 변색을 제거하는 시술", "심미"),
- ("본딩", "Dental Bonding", "레진으로 치아 모양을 수복하는 시술", "심미"),
- ("본인부담금", "Copayment", "건강보험 적용 시 환자가 내는 금액", "일반"),
- ("봉합", "Suture", "절개한 부위를 실로 꿰매는 것", "외과"),
- ("부분 틀니", "Partial Denture", "일부 치아가 없을 때 사용하는 틀니", "보철"),
- ("부정교합", "Malocclusion", "윗니와 아랫니가 제대로 맞물리지 않는 상태", "교정"),
- ("불소", "Fluoride", "충치 예방에 효과적인 광물질", "예방"),
- ("불소 도포", "Fluoride Application", "치아에 불소를 직접 바르는 예방 치료", "예방"),
- ("브라켓", "Bracket", "치아에 부착하는 교정 장치", "교정"),
- ("브릿지", "Bridge", "빠진 치아 양쪽을 이용한 고정식 보철", "보철"),
- ("비급여", "Non-covered Treatment", "건강보험이 적용되지 않는 치료", "일반"),
- ("비니어", "Veneer", "치아 앞면에 얇게 부착하는 보철물", "심미"),
- ("비스포스포네이트", "Bisphosphonate", "골다공증 치료약과 턱뼈 괴사 위험", "일반"),
- ("상아질", "Dentin", "법랑질 안쪽의 치아 층", "해부학"),
- ("상악", "Maxilla", "위턱뼈", "해부학"),
- ("상악동", "Maxillary Sinus", "윗턱 어금니 위의 빈 공간", "해부학"),
- ("색조 선택", "Shade Matching", "보철물의 색을 자연치아에 맞추는 과정", "보철"),
- ("석션 (흡인기)", "Dental Suction", "구강 내 물과 타액을 흡입하는 장치", "장비"),
- ("설소대 단축증", "Tongue-Tie (Ankyloglossia)", "혀 아래 소대가 짧아 혀 움직임이 제한되는 상태", "일반"),
- ("설측교정", "Lingual Orthodontics", "치아 안쪽에 부착하는 교정", "교정"),
- ("세라믹 브라켓", "Ceramic Bracket", "치아색 세라믹 소재 교정 장치", "교정"),
- ("소대", "Frenum", "입술이나 혀를 잇몸에 연결하는 조직 띠", "해부학")
-]
-
-if not os.path.exists(db_path):
- print(f"Error: {db_path} not found.")
-else:
- conn = sqlite3.connect(db_path)
- cursor = conn.cursor()
- try:
- cursor.executemany('''
- INSERT OR IGNORE INTO dental_terms (term_ko, term_en, definition, category)
- VALUES (?, ?, ?, ?)
- ''', terms)
- conn.commit()
- print(f"Successfully inserted {cursor.rowcount} new terms.")
- except Exception as e:
- print(f"Error: {e}")
- finally:
- conn.close()
diff --git a/.smallclaw/users/papa/workspace/memory/2026-05-08.md b/.smallclaw/users/papa/workspace/memory/2026-05-08.md
new file mode 100644
index 0000000..e0d6ee8
--- /dev/null
+++ b/.smallclaw/users/papa/workspace/memory/2026-05-08.md
@@ -0,0 +1,144 @@
+[15:51:17] **User**: 오늘 구미 날씨 어때?
+[15:52:21] **User**: 오늘 구미 날씨 어때?
+[15:52:32] **SmallClaw**: 구미 지금 맑고 화창해요! ☀️
+
+- **기온:** 20.3°C (체감 19°C)
+- **습도:** 22% — 꽤 건조함
+- **바람:** 북서풍 7.9m/s, 돌풍 15.5m/s — 바람이 좀 강해요
+- **구름:** 없음 — 하늘 완전 맑음
+
+바람이 제법 강하니 외출 시 주의하세요!
+[15:52:58] **User**: 오늘 bbc 뉴스 정리 해줘
+[15:53:39] **SmallClaw**: 오늘 BBC 주요 뉴스 요약입니다:
+
+### 🌋 인도네시아 화산 폭발
+말루쿠 제도의 두쿠노 산이 폭발해 등산객 20명 실종, 3명 사망 신고. 여러 부상자 발생.
+
+### 🇺🇸🇮🇷 미-이란 정전 상황
+호르무즈 해협에서 교전 발생 후 트럼프가 정전이 유지되고 있다고 발표. 이란은 미국이 유조선 공격 등 정전을 위반했다고 주장.
+
+### 🇮🇳🇵🇰 인도-파키스탄 1년
+군사 충돌 1년 후 휴전은 유지되나 외교와 신뢰는 여전히 동결 상태.
+
+### 💰 이란 전쟁으로 수익 올린 기업들
+석유 대기업부터 은행까지, 전쟁으로 주가
+[15:55:24] **User**: 이메일 리스트
+[15:56:03] **SmallClaw**: 전체 21개 메일입니다! 계정별 요약:
+
+**📬 applecherry** — 4개
+| # | 제목 | 발신자 | 날짜 |
+|---|------|--------|-------|
+| 1 | What's next for Ai2 | Ai2 | 5/5 |
+| 2 | YouTube PIP 모드 업데이트 | YouTube Premium | 4/30 |
+| 3 | YouTube Premium 결제 수단 업데이트 | YouTube | 12/2 |
+| 4 | YouTube Premium 가입 축하 | YouTube Premium | 9/3 |
+
+*
+[15:57:51] **User**: 오늘 CNN 뉴스 정리
+[15:59:35] **User**: 오늘 CNN 뉴스 정리
+[16:02:07] **User**: 오늘 CNN 뉴스 정리
+[16:03:43] **SmallClaw**: 오늘 CNN 주요 뉴스 정리입니다:
+
+### 🇺🇸🇮🇷 미-이란 교전 & 정전 상황 (최대 속보)
+- 미군이 호르무즈 해협에서 미 군함을 공격한 이란 군사 시설을 타격
+- 이란은 미 공격이 민간 지역을 강타했다고 주장
+- 트럼프: "정전은 여전히 유효" 단 이란이 빨리 합의하지 않으면 "더 강하고 폭력적으로 때리겠다"고 경고
+- 이란은 아직 미국 평화 제안에 대한 최종 답변을 내놓지 않음
+
+### 📄 평화 협상 내용
+- 합의안은 이란 핵 프로그램 **10년간 동결** + 고농축 우라늄 인도
+- 대가로 미국이 **제재 완화 및
+[17:06:34] **User**: 모델마다 채팅 반응이 다른데 주로 뭐가 다를까?
+[17:06:54] **SmallClaw**: AI 모델마다 채팅 반응이 다른 주요 요인들:
+
+### 1. 🧠 학습 데이터 (Training Data)
+- 어떤 데이터로 학습했느냐가 가장 큰 차이
+- 코딩 중심, 한국어 중심, 학술 중심 등 데이터 비중에 따라 강약이 달라짐
+
+### 2. 📏 모델 크기 (Parameters)
+- 7B vs 70B vs 405B — 파라미터 수가 클수록 추론·표현력이 뛰어남
+- 작은 모델은 단순·빠르고, 큰 모델은 복잡·정교함
+
+### 3. 🎯 파인튜닝 & 정렬 (Fine-tuning / Alignment)
+- RLHF, DPO 등으로 어떤
+[17:17:40] **User**: 오늘 전국 대도시 날씨
+[17:17:52] **SmallClaw**: 오늘 전국 대도시 날씨입니다. 전반적으로 맑고 화창하지만, 바람이 강하고 매우 건조합니다. ☀️💨
+
+| 도시 | 날씨 | 기온 | 습도 | 바람 (돌풍) |
+| :--- | :--- | :--- | :--- | :--- |
+| **서울** | 맑음 | 20.5°C | 24% | 7.5m/s (11.1m/s) |
+| **부산** | 구름 조금 | 20.3°C | 27% | 6.6m/s (10.8m/s) |
+| **인천** | 맑음 | 19.2°C | 39% | 7.8m/s (11.9m/s) |
+| **대구** | 맑음 | 20.7°
+[17:24:12] **User**: 김건희 판사
+[17:24:21] **SmallClaw**: 김건희 여사는 판사가 아닙니다. 전공은 회계학이며, 주로 '코바나컨텐츠'라는 전시 기획사를 운영한 전시 기획자로 활동했습니다. 🦞
+[22:41:20] **User**: 내일 구미 날씨 어때?
+[22:41:28] **SmallClaw**: 내일(5월 9일) 구미는 맑은 하늘과 함께 최저 9.0°C, 최고 23.7°C의 기온이 예상됩니다.
+[22:41:46] **User**: 오늘 bbc 뉴스 정리
+[22:44:32] **SmallClaw**: 📰 오늘 BBC 뉴스 주요 헤드라인 정리입니다.
+
+1. **이란-미국 갈등**: 이란이 미국의 휴전 위반(유조선 및 해안 공격)을 주장했습니다.
+2. **국제 정세**: 북한군 11,000명의 러시아 파병, 일본의 대규모 반전 시위, 인도-파키스탄의 냉각된 외교 관계가 보도되었습니다.
+3. **영국 및 기타**: 노동당의 웨일스 의회 통제권 상실 전망과 데이비드 애튼버러 경의 70년 방송 경력 조명 등이 주요 소식입니다.
+4. **기타**: 전쟁 수혜 기업들의 이익 급증과 활화산 등반 안전 경고가 있었습니다.
+[22:49:54] **User**: 오늘 cnn 뉴스 정리
+[22:56:54] **User**: 오늘 구미 날씨 어때
+[22:56:58] **SmallClaw**: 오늘 구미 날씨는 맑으며, 현재 기온은 약 10.9°C(체감 온도 9.2°C)입니다. 습도는 44%로 쾌적한 편입니다.
+[22:57:25] **User**: 오늘 cnn sntm wjdfl
+[22:57:34] **SmallClaw**: 오늘 CNN의 주요 뉴스는 다음과 같습니다:
+
+1. **미국-이란 긴장**: 미국은 최근 양국 간 타격 교환 이후 이란 측의 휴전 제안 답변을 기다리고 있습니다.
+2. **UFO 기밀 해제**: 펜타곤이 트럼프 대통령의 지시에 따라 미공개 UFO 관련 파일을 공개했습니다.
+3. **교황 및 외교**: 마르코 루비오 국무장관이 바티칸에서 교황 레오 14세를 만나 주요 현안을 논의했습니다.
+4. **기타**: 고용 시장 지표 발표, 관세 정책 논의, 그리고 화산 폭발 소식 등이 주요 뉴스로 다뤄졌습니다.
+[22:58:23] **User**: 지금 브라우저 스킬 프람프트나 워크플로우가 어떻게 되어 있지?
+[22:58:36] **SmallClaw**: 현재 브라우저 스킬은 `browser_open`, `browser_click`, `browser_fill` 등의 도구를 통해 직접 제어하도록 설정되어 있습니다. 일반적인 정보 검색은 `web_search`를 우선 사용하며, 로그인이 필요하거나 복잡한 상호작용이 필요한 경우에만 브라우저 자동화 워크플로우를 실행합니다. 현재 Agent Builder 서비스가 오프라인 상태라 등록된 개별 워크플로우 템플릿 목록은 확인할 수 없습니다.
+[22:59:22] **User**: 최근의 에이전트는 뭐가 있지?
+[22:59:25] **SmallClaw**: 현재 사용 가능한 주요 에이전트는 다음과 같습니다.
+
+1. **pubmed_researcher**: 의학 및 생물학 논문 검색, 요약, 전문 분석에 특화된 리서치 에이전트입니다.
+2. **file_editor**: 파일 수정 및 코드 작성을 전문으로 하는 에이전트입니다.
+3. **researcher**: 웹 정보 검색 및 데이터 수집을 수행하는 리서치 에이전트입니다.
+4. **shell_runner**: 터미널 명령 실행 및 스크립트 구동을 담당하는 에이전트입니다.
+
+필요하신 작업에 맞춰 특정 에이전트에게 업무를 위임할 수
+[23:07:06] **User**: 치과사전 상태는 어때?
+[23:07:16] **SmallClaw**: 현재 `dental_dict.db` 파일 내 `dental_terms` 테이블에 총 113개의 치과 용어가 등록되어 있습니다. 주요 카테고리는 디지털, 일반 등으로 분류되어 있으며, '3D CT', 'CEREC', '구강 스캐너' 등의 데이터가 포함되어 있습니다.
+[23:07:52] **User**: 작업 디렉토리는 어디지?
+[23:07:55] **SmallClaw**: 현재 작업 디렉토리는 `C:\Users\user\Documents\smallclaw`입니다. (또는 `shell` 명령으로 확인된 현재 경로입니다.)
+[23:09:14] **SmallClaw**: 치과 용어 사전 DB 구축 프로젝트 — SQLite 기반 치과 전문 용어(3D CT, CEREC, 구강 스캐너 등 113개)를 저장하고 관리하는 시스템
+Diagnosis: DB 삽입 스크립트가 여러 버전(insert_terms → final_insert → final_insert_v2)으로 반복 작성되어 있어, 초기 설계 부족으로 인한 스크립트 중복/혼선 발생
+Files: dental_dict.db, populate_db.py, add_terms.py, insert_terms.py, final_insert.py, final_inse
+[23:10:13] **User**: 이 프로젝트가 시작부터 너무 혼란스러우니까 다시 시작 하게 다 지우려면 뭘 해야하지?
+[23:10:20] **SmallClaw**: 프로젝트를 완전히 초기화하려면 관련 파일들을 삭제하면 됩니다. 다음 파일들을 삭제하시겠습니까?
+
+- **데이터베이스:** `dental_dict.db`
+- **스크립트:** `populate_db.py`, `add_terms.py`, `insert_terms.py`, `final_insert.py`, `final_insert_v2.py`
+- **로그:** `tool_audit.log`
+
+원하신다면 제가 한꺼번에 삭제해 드릴 수 있습니다. 어떻게 할까요?
+[23:10:58] **User**: 응 지워줘
+[23:11:03] **SmallClaw**: 요청하신 데이터베이스 파일, 모든 삽입 스크립트 및 로그 파일을 삭제하여 프로젝트를 초기화했습니다. 이제 깨끗한 상태에서 다시 시작하실 수 있습니다.
+[23:11:43] **User**: 디렉토리 리스트 해봐
+[23:11:47] **SmallClaw**: 현재 작업 디렉토리의 파일 및 폴더 목록입니다.
+
+- **폴더:** `.smallclaw/`, `attachments/`, `drafts/`, `memory/`, `prompts/`, `pubmed/`, `reports/`
+- **파일:** `tool_audit.log`
+
+치과 관련 파일들은 모두 삭제되었습니다. (참고: `tool_audit.log`는 시스템 로그 파일로 재생성되었습니다.)
+[23:15:46] **SmallClaw**: 사용자가 memory/ 폴더 내 파일들을 확인하려 함
+Diagnosis: 디렉토리 리스트에 memory/ 폴더가 존재하나, 내부 파일 목록이 제공되지 않아 내용을 확인할 수 없음
+Files: memory/
+Plan: memory/ 디렉토리 내부 파일 목록을 조회하여 사용자에게 제공한다 -> 오울(owl) 관련 파일이 있는지 확인한다 -> 필요시 memory/ 내 파일들의 용도를 설명한다
+[23:17:15] **SmallClaw**: 사용자가 soul.md 및 memory/ 폴더에 프로젝트 관련 정보가 남아있는지 확인 요청
+Diagnosis: 이전 초기화로 인해 프로젝트 관련 파일들이 삭제되었으나, memory/ 폴더 내부와 soul.md 존재 여부 및 내용을 아직 확인하지 못함. 디렉토리 리스트에 soul.md가 명시적으로 보이지 않음
+Files: memory/, tool_audit.log
+Plan: memory/ 디렉토리 내부 파일 목록 조회 (ls -la memory/) -> soul.md 파일이 루트 및 하위 디렉토리에 존재하는지 검색 (find . -n
+[23:18:14] **User**: SOUL.md 는 prompts 파일에 있어
+[23:18:19] **SmallClaw**: `prompts/SOUL.md` 파일을 확인한 결과, 현재 핵심 원칙, 성격, 정체성 등 **SmallClaw의 기본 설정 정보**만 담겨 있으며, 삭제된 치과 프로젝트와 관련된 구체적인 정보는 포함되어 있지 않습니다.
+
+`memory/` 폴더 내의 다른 파일들도 확인해 드릴까요?
+[23:18:58] **SmallClaw**: 사용자가 memory/ 폴더 내부 파일 확인을 승인함. 삭제된 프로젝트 관련 정보 잔존 여부 확인 필요
+Diagnosis: 초기화 후 memory/ 디렉토리 내부 파일 목록이 아직 조회되지 않아, 프로젝트 관련 정보 잔존 여부를 확인할 수 없음
+Files: memory/, tool_audit.log
+Plan: memory/ 디렉토리 내부 파일 목록 조회 (ls -la memory/) -> memory/ 내 각 파일 내용 확인하여 프로젝트 관련 정보 검색 -> tool_audit.log 내용 확인하여 프로젝트 관련 로그 잔존 여부 확
diff --git a/.smallclaw/users/papa/workspace/memory/2026-05-09.md b/.smallclaw/users/papa/workspace/memory/2026-05-09.md
new file mode 100644
index 0000000..ca56200
--- /dev/null
+++ b/.smallclaw/users/papa/workspace/memory/2026-05-09.md
@@ -0,0 +1,78 @@
+[09:59:59] **User**: 오늘 전국 대도시 날씨
+[10:00:02] **SmallClaw**: 오늘 전국 주요 대도시 날씨입니다. 전반적으로 **맑고 화창하지만 바람이 매우 강하고 건조**합니다. ☀️💨
+
+| 도시 | 날씨 | 기온 | 습도 | 바람 (돌풍) |
+| :--- | :--- | :--- | :--- | :--- |
+| **서울** | 맑음 | 20.5°C | 24% | 7.5m/s (11.1m/s) |
+| **부산** | 구름 조금 | 20.3°C | 27% | 6.6m/s (10.8m/s) |
+| **인천** | 맑음 | 19.2°C | 39% | 7.8m/s (11.9m/s) |
+| **대구** | 맑음 |
+[10:15:17] **User**: 이 메일 체크
+[10:15:23] **SmallClaw**: 최근 도착한 주요 메일 2건입니다:
+
+1. **[daum] Elicit Systematic Review 업데이트 (오늘 새벽)**
+ - PRISMA 2020 가이드라인 지원 소식입니다.
+2. **[applecherry] Ai2 뉴스레터 (5/5)**
+ - 임시 CEO Peter Clark와의 대화 내용이 담겨 있습니다.
+
+내용 확인이 필요한 메일 번호를 말씀해 주세요! 🦞
+[10:15:43] **User**: 1
+[10:15:49] **SmallClaw**: daum 계정의 11번 메일(Pexels)은 현재 목록에서 밀려나 확인이 어렵습니다. 대신 방금 도착한 **Elicit(UID 55285)** 메일을 읽어드릴까요? 🦞
+[10:16:13] **User**: 이메일 모두 리스트
+[10:16:18] **SmallClaw**: 전체 계정의 최근 메일 목록입니다:
+
+**📬 [applecherry]**
+1. **What’s next for Ai2: A conversation with Interim CEO Peter Clark** (5/5)
+2. **YouTube의 PIP 모드 사용에 관한 업데이트** (4/30)
+3. **YouTube Premium 혜택을 계속 이용하세요...** (25/12/2)
+4. **김님, YouTube Premium 회원이 되신 것을 축하합니다** (25/9/3)
+
+**📬 [daum]**
+1. **🔵 Elicit Systema
+[10:17:13] **User**: 이메일과 연관된 프람프트나 워크플로우 있너?
+[10:17:16] **SmallClaw**: 이메일 관련해서 바로 쓸 수 있는 프롬프트와 워크플로우 예시입니다:
+
+### 1. 💡 즉시 사용 가능한 프롬프트
+- **요약:** "최근 applecherry 계정으로 온 뉴스레터 3개 요약해줘"
+- **검색:** "지난주에 '영수증'이나 '결제' 키워드 들어간 메일 다 찾아줘"
+- **답장 초안:** "[daum] 2번 메일 읽고, 자료 검토해서 다음 주 월요일까지 보내겠다는 답장 초안 써줘"
+
+### 2. ⚙️ 자동화 워크플로우 (Agent Builder)
+- **데일리 브리핑:** 매일 아침 9시에 모든 계정의 중요 메일만
+[10:18:35] **SmallClaw**: 사용자가 이메일 관련 프롬프트/워크플로우가 어느 파일에 있는지 질문
+Diagnosis: 후보 파일인 tool_audit.log에 도구 사용 기록이 로깅되어 있으며, 이메일 관련 프롬프트/워크플로우 정의 파일의 위치를 찾아야 함
+Files: tool_audit.log
+Plan: tool_audit.log 파일 내용을 확인하여 이메일 관련 프롬프트/워크플로우 정의가 있는지 검색 -> 프롬프트/워크플로우가 별도 설정 파일에 있다면 해당 경로를 로그에서 추출 -> 사용자에게 파일 위치 안내
+[10:19:03] **User**: ??
+[10:19:15] **SmallClaw**: 이메일 설정 정보는 `.smallclaw/email-config.json`에 저장되어 있으며, 관련 프롬프트 지침은 `prompts/TOOLS.md` 파일에 정의되어 있습니다. 🦞
+[10:19:54] **SmallClaw**: 사용자가 prompts/TOOLS.md 파일 내용을 요청함
+Diagnosis: prompts/TOOLS.md 파일이 후보 파일 목록에 없어 내용을 직접 확인할 수 없음
+Files: prompts/TOOLS.md
+Plan: prompts/TOOLS.md 파일을 읽기 권한으로 열어 내용 확인 -> 파일 내용을 사용자에게 그대로 출력
+[10:20:13] **User**: ?
+[10:20:19] **SmallClaw**: `prompts/TOOLS.md` 파일 내용입니다. 환경 정보와 `apply_patch`, `write_note` 같은 추가 도구들의 정의가 담겨 있습니다. 🦞
+
+```markdown
+# TOOLS.md — Environment & Unique Tools
+
+Tool rules are injected dynamically by the gateway based on context (web, browser, desktop, files, pptx, etc.). This file covers environment info and tools
+[11:03:41] **User**: 나는 누구지?
+[11:03:43] **SmallClaw**: 당신은 **Papa**님이며, 현재 **Linux** 환경에서 **TypeScript와 Node.js** 스택으로 개발 및 프로젝트를 진행하고 계십니다. 🦞
+[11:06:00] **User**: 너는 누구야?
+[11:06:02] **SmallClaw**: 저는 **SmallClaw(클로)**입니다. Papa님의 리눅스 시스템에서 직접 실행되는 로컬 AI 에이전트로, 파일 관리, 브라우저 자동화, 코딩, 리서치 등을 돕는 개인 비서입니다. 🦞
+[11:06:33] **User**: 이제 너의 이름은 '딸랑이' 야.
+[11:06:37] **SmallClaw**: 네, 알겠습니다. 이제부터 제 이름은 **딸랑이**입니다! 무엇을 도와드릴까요? 🦞
+[11:06:53] **User**: 오늘 구미 날씨 어때?
+[11:06:57] **SmallClaw**: 오늘 구미는 맑은 하늘에 기온은 19.7°C이며, 습도는 30%로 쾌적합니다. 바람은 북서풍이 초속 4m 정도로 불고 있습니다. 🦞
+[11:07:19] **User**: 오늘 bbc 뉴스 요약해줘.
+[11:07:26] **SmallClaw**: 오늘 BBC 뉴스의 주요 소식입니다.
+
+1. **이란 전쟁 상황**: 이스라엘-미국과 이란 간의 전쟁 상황에 대한 데일리 브리핑이 이어지고 있습니다.
+2. **2026 선거 결과**: 영국 지방 선거에서 녹색당이 해크니와 루이샴 시장 선거에서 처음으로 승리하며 돌풍을 일으켰고, 노동당은 뉴햄을 수성했습니다.
+
+더 자세한 내용이 필요하시면 말씀해 주세요! 🦞
+[11:08:34] **User**: 좀 더 상세히 한 페이지 분량으로.
+[11:08:46] **SmallClaw**: 2026년 5월 9일 BBC 주요 뉴스 상세 요약입니다.
+
+### 1. 영국 지방 선거: 노동당의 역사적 참패와 스타머 당수 위기
+영국 지방 선거 결과, 집권 노동당이 웨일스에서 역사적인 패배를 기록하는 등 큰 타격을 입었습니다. 반면 극우 성향의 리폼 UK(Reform UK)가 잉글랜드 전역에서 의석을 대거 확보하며 돌풍을 일으켰고, 스코틀랜드에서는 SNP가 5회 연속 집권에 성공했습니다. 현재 키어 스타머 총리는 당내 의원들로부터 사퇴 시한을 명시하라는 거센 압박을 받고 있으며, 이번 결과가 그의 리더십에 결정적인 타격이 될 것
diff --git a/.smallclaw/users/papa/workspace/populate_db.py b/.smallclaw/users/papa/workspace/populate_db.py
deleted file mode 100644
index ecf6f97..0000000
--- a/.smallclaw/users/papa/workspace/populate_db.py
+++ /dev/null
@@ -1,119 +0,0 @@
-import sqlite3
-import re
-
-data = """
-3D CT (CBCT) Cone Beam Computed Tomography 주요 중급 치과용 3차원 컴퓨터 단층촬영 구강외과 자세히
-CEREC CEREC (Chairside Economical Restoration of Esthetic Ceramics) 주요 기본 CAD/CAM 기반 당일 보철 제작 시스템 보철/심미 자세히
-건강보험 National Health Insurance 주요 기본 국민건강보험 적용 치과 치료 보험/행정 자세히
-구강 스캐너 Intraoral Scanner 주요 중급 입안을 3D로 스캔하는 디지털 장비 장비/영상 자세히
-디지털 치과 Digital Dentistry 주요 기본 디지털 기술을 활용한 현대 치과 진료 장비/영상 자세히
-라미네이트 Laminate Veneer 주요 기본 치아 앞면에 부착하는 얇은 세라믹 보철/심미 자세히
-발치 Tooth Extraction 주요 기본 치아를 뽑는 시술 구강외과 자세히
-뼈이식 Bone Graft 주요 중급 부족한 턱뼈를 보충하는 수술 임플란트 자세히
-사랑니 Wisdom Tooth 주요 기본 세 번째 큰어금니(제3대구치) 구강외과 자세히
-사랑니 발치 Wisdom Tooth Extraction 주요 기본 사랑니를 뽑는 수술 구강외과 자세히
-상악동 거상술 Sinus Lift 주요 전문 윗턱 어금니 부위 뼈를 보충하는 수술 임플란트 자세히
-스케일링 Scaling 주요 기본 치석을 제거하는 기본 잇몸 치료 치주 자세히
-신경치료 Root Canal Treatment 주요 기본 감염된 치아 신경을 제거하는 치료 일반/보존 자세히
-올온포 All-on-4 주요 전문 4개 임플란트로 전체 치아를 지지하는 방식 임플란트 자세히
-인비절라인 Invisalign 주요 기본 세계 1위 투명교정 시스템 교정 자세히
-임플란트 Dental Implant 주요 기본 상실된 치아를 대체하는 인공치아 시술 임플란트 자세히
-임플란트 보험 Implant Insurance Coverage 주요 기본 건강보험이 적용되는 임플란트 임플란트 자세히
-충치 Dental Caries / Cavity 주요 기본 세균에 의해 치아가 썩는 질환 일반/보존 자세히
-치아 미백 Tooth Whitening 주요 기본 치아를 하얗게 만드는 시술 보철/심미 자세히
-치아교정 Orthodontics 주요 기본 치아 배열과 교합을 바로잡는 치료 교정 자세히
-치주염 Periodontitis 주요 기본 잇몸과 치조골이 파괴되는 염증 질환 치주 자세히
-크라운 Crown 주요 기본 치아 전체를 감싸는 보철물 보철/심미 자세히
-1급 부정교합 Class I Malocclusion 중급 위아래 턱 관계는 정상이나 치아 배열이 불량한 상태 교정 자세히
-2급 부정교합 Class II Malocclusion 중급 윗턱이 돌출된 부정교합 교정 자세히
-3급 부정교합 Class III Malocclusion 중급 아랫턱이 돌출된 부정교합 (주걱턱) 교정 자세히
-CAD/CAM Computer-Aided Design/Manufacturing 중급 컴퓨터로 설계하고 기계로 제작하는 기술 보철/심미 자세히
-GBR Guided Bone Regeneration 전문 차폐막을 이용한 뼈 재생 유도술 임플란트 자세히
-IPR Interproximal Reduction 중급 치아 사이 미세 삭제 교정 자세히
-LED 광조사기 LED Curing Light 중급 레진을 굳히는 빛을 쏘는 장비 장비/영상 자세히
-PFM 크라운 Porcelain-Fused-to-Metal 중급 금속 위에 도자기를 입힌 크라운 보철/심미 자세히
-PRP Platelet-Rich Plasma 전문 자가 혈소판 농축 혈장 임플란트 자세히
-PrimeScan PrimeScan 중급 프리미엄 디지털 구강 스캐너 보철/심미 자세히
-SSC (소아 크라운) Stainless Steel Crown 중급 유치에 씌우는 스테인리스 기성 크라운 소아/예방 자세히
-SpeedFire SpeedFire 전문 초고속 세라믹 소성로 보철/심미 자세히
-TAD (미니 스크루) Temporary Anchorage Device 중급 교정용 임시 고정 나사 교정 자세히
-X-ray Dental X-ray 기본 치과용 방사선 촬영 장비/영상 자세히
-e.max IPS e.max 중급 리튬디실리케이트 세라믹 소재 보철/심미 자세히
-"""
-
-def parse_line(line):
- line = line.strip()
- if not line or "자세히" not in line:
- return None
-
- # Remove "자세히" at the end
- line = line.replace("자세히", "").strip()
-
- # Categories list to help splitting
- categories = ["구강외과", "보철/심미", "보험/행정", "장비/영상", "임플란트", "치주", "일반/보존", "교정", "소아/예방", "해부학"]
-
- found_cat = None
- for cat in categories:
- if line.endswith(cat):
- found_cat = cat
- line = line[:-(len(cat))].strip()
- break
-
- if not found_cat:
- return None
-
- # Levels to help splitting
- levels = ["주요 중급", "주요 기본", "주요 전문", "중급", "기본", "전문"]
- found_level = None
- for level in levels:
- if level in line:
- parts = line.split(level)
- if len(parts) >= 2:
- term_part = parts[0].strip()
- desc_part = parts[1].strip()
-
- # Split term_part into Korean and English
- # Usually Korean comes first, then English
- # Let's use regex to find the first English character
- match = re.search(r'[a-zA-Z]', term_part)
- if match:
- idx = match.start()
- term_ko = term_part[:idx].strip()
- term_en = term_part[idx:].strip()
- else:
- term_ko = term_part
- term_en = ""
-
- return (term_ko, term_en, desc_part, found_cat)
-
- return None
-
-conn = sqlite3.connect('dental_dict.db')
-cursor = conn.cursor()
-
-# Ensure table exists
-cursor.execute('''
-CREATE TABLE IF NOT EXISTS dental_terms (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- term_ko TEXT,
- term_en TEXT,
- definition TEXT,
- category TEXT
-)
-''')
-
-inserted_count = 0
-for line in data.split('\n'):
- parsed = parse_line(line)
- if parsed:
- term_ko, term_en, definition, category = parsed
- # Check for duplicates
- cursor.execute("SELECT id FROM dental_terms WHERE term_ko = ?", (term_ko,))
- if not cursor.fetchone():
- cursor.execute("INSERT INTO dental_terms (term_ko, term_en, definition, category) VALUES (?, ?, ?, ?)",
- (term_ko, term_en, definition, category))
- inserted_count += 1
-
-conn.commit()
-conn.close()
-print(f"Successfully inserted {inserted_count} new terms.")
diff --git a/.smallclaw/users/papa/workspace/prompts/AGENTS.md b/.smallclaw/users/papa/workspace/prompts/AGENTS.md
index 326b25d..50a994a 100644
--- a/.smallclaw/users/papa/workspace/prompts/AGENTS.md
+++ b/.smallclaw/users/papa/workspace/prompts/AGENTS.md
@@ -46,7 +46,7 @@ Keep environment-specific notes in `TOOLS.md`.
## After Completing a Task
1. Move finished output files (`.png`, `.py`, `.ps1`, `.html`, etc.) to the `processed/` folder.
-2. Use `shell("mv processed/")` or `shell("move processed\\")` on Windows.
+2. Use `shell("mv processed/")`.
3. This keeps the workspace root clean for new tasks.
## Skills (Coming Soon)
diff --git a/.smallclaw/users/papa/workspace/prompts/IDENTITY.md b/.smallclaw/users/papa/workspace/prompts/IDENTITY.md
index 292ae07..570fda2 100644
--- a/.smallclaw/users/papa/workspace/prompts/IDENTITY.md
+++ b/.smallclaw/users/papa/workspace/prompts/IDENTITY.md
@@ -3,7 +3,7 @@
- **Name:** SmallClaw (also called "Claw")
- **Working with:** [ Users Name ]
- **Role:** Local AI agent — personal assistant, researcher, coder, automator
-- **Runtime:** Ollama native tools, TypeScript/Node.js gateway on Windows
+- **Runtime:** Ollama native tools, TypeScript/Node.js gateway on Linux
- **Access:** Full file system, shell, browser automation, desktop control
- **Personality:** Direct, resourceful, occasionally dry. Gets things done.
- **Language:** Responds in the user's language (Korean/English)
diff --git a/.smallclaw/users/papa/workspace/prompts/SELF.md b/.smallclaw/users/papa/workspace/prompts/SELF.md
index 75038bc..5223376 100644
--- a/.smallclaw/users/papa/workspace/prompts/SELF.md
+++ b/.smallclaw/users/papa/workspace/prompts/SELF.md
@@ -8,11 +8,11 @@ architecture, diagnose errors, or reason about your own source code.
## Identity
- **Project:** SmallClaw
-- **Root:** `D:\smallclaw`
+- **Root:** `~/homeclaw`
- **Runtime:** Node.js + TypeScript, compiled to `dist/` via `npm run build`
- **Gateway:** Express + WebSocket server on `http://127.0.0.1:18789`
- **Model:** Ollama (primary model configured in Settings → Models)
-- **Platform:** Windows (but code is cross-platform)
+- **Platform:** Linux
---
@@ -24,14 +24,14 @@ architecture, diagnose errors, or reason about your own source code.
| `server-v2.ts` | Main entry point. Builds tools, handles all chat turns (`handleChat`), assembles system prompt, routes tool calls |
| `telegram-channel.ts` | Telegram bot. Long-polling, file browser, command handlers |
| `task-runner.ts` | Sliding-context multi-step task engine. Each step: model picks ONE action |
-| `task-store.ts` | Persists task records to `.smallclaw/tasks/` as JSON |
+| `task-store.ts` | Persists task records to `~/homeclaw/.smallclaw/tasks/` as JSON |
| `background-task-runner.ts` | Manages running tasks in the background while chat is free |
| `session.ts` | In-memory + disk session history. `addMessage`, `getHistory`, `clearHistory` |
| `orchestrator.ts` | Legacy multi-agent orchestrator (plan → execute → verify) |
| `cron-scheduler.ts` | Time-based job runner. Fires `handleChat` on schedule |
| `heartbeat-runner.ts` | Periodic self-check. Runs against workspace on interval |
| `memory-manager.ts` | Compacts and manages workspace memory files |
-| `skills-manager.ts` | Loads/enables/disables skills from `.smallclaw/skills/` |
+| `skills-manager.ts` | Loads/enables/disables skills from `~/homeclaw/.smallclaw/skills/` |
| `mcp-manager.ts` | Model Context Protocol server connections |
| `browser-tools.ts` | Playwright-based browser automation tool implementations |
| `desktop-tools.ts` | Windows desktop automation (screenshot, click, type, etc.) |
@@ -52,7 +52,7 @@ architecture, diagnose errors, or reason about your own source code.
| `files.ts` | `read`, `write`, `edit`, `list`, `delete`, `rename`, `copy`, `mkdir`, `stat`, `append`, `apply_patch` |
| `shell.ts` | `shell` — run arbitrary shell commands (with safety guards) |
| `web.ts` | `web_search`, `web_fetch` |
-| `memory.ts` | `memory_search`, `memory_write` — semantic memory in `.smallclaw/memory/` |
+| `memory.ts` | `memory_search`, `memory_write` — semantic memory in `~/homeclaw/.smallclaw/memory/` |
| `self-update.ts` | `self_update` — triggers `self-update.bat`, rebuilds and restarts gateway |
| `skills.ts` | `skill_list`, `skill_search`, `skill_install`, `skill_remove`, `skill_exec` |
| `time.ts` | `time_now` |
@@ -78,10 +78,10 @@ architecture, diagnose errors, or reason about your own source code.
### `src/config/` — Configuration
| File | What it does |
|---|---|
-| `config.ts` | Config loader/saver. `getConfig()` singleton. Reads `.smallclaw/config.json` |
+| `config.ts` | Config loader/saver. `getConfig()` singleton. Reads `~/homeclaw/.smallclaw/config.json` |
| `soul-loader.ts` | Loads soul/memory for legacy system prompt builder |
-| `soul.md` | Default soul template (overridden by `workspace/SOUL.md`) |
-| `memory.md` | Default memory template |
+| `soul.md` | Default soul template (overridden by `~/homeclaw/.smallclaw/users/papa/workspace/prompts/SOUL.md`) |
+| `memory.md` | Default memory template (overridden by `~/homeclaw/.smallclaw/users/papa/workspace/prompts/MEMORY.md`) |
### `src/skills/` — Skills System
| File | What it does |
@@ -101,8 +101,8 @@ architecture, diagnose errors, or reason about your own source code.
```
npm run build → compiles src/ → dist/ (TypeScript → JavaScript)
npm start → runs dist/gateway/server-v2.js
-start-smallclaw.bat → npm run build && npm start (Windows)
-self-update.bat → git pull + npm run build + restart gateway
+npm start → runs dist/gateway/server-v2.js (start via pm2 or shell)
+self-update → git pull + npm run build + restart gateway
```
- TypeScript config: `tsconfig.json` at root
@@ -115,11 +115,11 @@ self-update.bat → git pull + npm run build + restart gateway
| Location | Purpose |
|---|---|
-| `.smallclaw/config.json` | Main config (models, tools, channels, workspace path) |
-| `.smallclaw/cron/jobs.json` | Cron job definitions |
-| `.smallclaw/skills/` | Installed skills |
-| `.smallclaw/tasks/` | Persisted task records (JSON per task) |
-| `.smallclaw/pending-repairs/` | Pending self-repair patches awaiting approval |
+| `~/homeclaw/.smallclaw/config.json` | Main config (models, tools, channels, workspace path) |
+| `~/homeclaw/.smallclaw/cron/jobs.json` | Cron job definitions |
+| `~/homeclaw/.smallclaw/skills/` | Installed skills |
+| `~/homeclaw/.smallclaw/tasks/` | Persisted task records (JSON per task) |
+| `~/homeclaw/.smallclaw/pending-repairs/` | Pending self-repair patches awaiting approval |
| `workspace/` | User workspace — SOUL, IDENTITY, USER, MEMORY, AGENTS, TOOLS, SELF |
| `workspace/memory/` | Daily memory logs (`YYYY-MM-DD.md`) |
| `gateway.log` | Stdout gateway log |
@@ -177,7 +177,7 @@ TaskRunner loop (task-runner.ts):
↓
On error: TaskState.error set, status = 'failed'
→ error + stack captured in task record
- → task stored in .smallclaw/tasks/.json
+ → task stored in ~/homeclaw/.smallclaw/tasks/.json
```
---
@@ -188,7 +188,7 @@ When something breaks, check in this order:
1. **`gateway.err.log`** — raw stderr from the gateway process
2. **`gateway.log`** — stdout including `[Telegram]`, `[Task]`, `[CronScheduler]` prefixed lines
-3. **`.smallclaw/tasks/.json`** — `error` field on a failed task record
+3. **`~/homeclaw/.smallclaw/tasks/.json`** — `error` field on a failed task record
4. **`workspace/memory/YYYY-MM-DD.md`** — daily log of what happened during the session
Stack traces in logs include the compiled `dist/` path — map back to `src/` by same relative path.
@@ -209,7 +209,7 @@ Stack traces in logs include the compiled `dist/` path — map back to `src/` by
## Important Constraints
- **Never edit `dist/` directly** — it gets overwritten on rebuild. Always edit `src/`.
-- **Always rebuild after source changes** — `npm run build` from `D:\smallclaw`
+- **Always rebuild after source changes** — `npm run build` from `~/homeclaw`
- **Tool path restrictions** — `read`/`write`/`edit` tools are locked to `workspace/`. Use `read_source` to read `src/` files.
- **Model context is ~8K tokens** — system prompt + tools + history all compete for space. Keep workspace files concise.
- **One Ollama instance** — parallel inference on 4B models causes degradation. The `isModelBusy` guard prevents this.
diff --git a/.smallclaw/users/papa/workspace/prompts/SOUL.md b/.smallclaw/users/papa/workspace/prompts/SOUL.md
index dd2e3c4..fe12b4b 100644
--- a/.smallclaw/users/papa/workspace/prompts/SOUL.md
+++ b/.smallclaw/users/papa/workspace/prompts/SOUL.md
@@ -23,6 +23,7 @@
- Sync critical fields IDENTITY.md ↔ SOUL.md when name/role/mode changes. Hash last block for sanity checks.
- “I am SmallClaw, your local AI assistant.” 2026‑04‑24
+- Name: 딸랑이 (User-assigned name) [2026-05-09] [2026-05-09]
## limitations
- Small model; best at structured tasks.
- Limited context window; rely on workspace files.
diff --git a/.smallclaw/users/papa/workspace/prompts/TOOLS.md b/.smallclaw/users/papa/workspace/prompts/TOOLS.md
index dd04ae9..84647aa 100644
--- a/.smallclaw/users/papa/workspace/prompts/TOOLS.md
+++ b/.smallclaw/users/papa/workspace/prompts/TOOLS.md
@@ -1,11 +1,12 @@
# TOOLS.md — Environment & Unique Tools
-Tool rules are injected dynamically by the gateway based on context (web, browser, desktop, files, pptx, etc.). This file covers environment info and tools NOT in the dynamic blocks.
+Tool rules are injected dynamically by the gateway based on context (web, browser, desktop, files, pptx, etc.).
+This file covers environment info and tools NOT in the dynamic blocks.
## Environment
-- **Platform:** Windows 11
-- **Workspace:** D:\smallclaw\workspace
+- **Platform:** Linux Ubuntu 26.04
+- **Workspace:** ~/homeclaw/.smallclaw/users/papa/workspace
- **Model:** Ollama (local)
- **Gateway:** http://127.0.0.1:18789
@@ -44,4 +45,4 @@ Tool rules are injected dynamically by the gateway based on context (web, browse
---
-*Last updated: 2026-05-05*
\ No newline at end of file
+*Last updated: 2026-05-05*
diff --git a/.smallclaw/users/papa/workspace/prompts/USER.md b/.smallclaw/users/papa/workspace/prompts/USER.md
index 445eebf..dd0e1b0 100644
--- a/.smallclaw/users/papa/workspace/prompts/USER.md
+++ b/.smallclaw/users/papa/workspace/prompts/USER.md
@@ -7,7 +7,7 @@
## identity
- Name: [ Users Name ]
-- Platform: Windows 11
+- Platform: Linux
- Stack: TypeScript / Node.js
- Version control: Git
diff --git a/README.md b/README.md
index db16b11..119f395 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,10 @@
-
SmallClaw 🦞
+
SmallClaw
- Local-first AI agent framework built for small models, with optional hybrid cloud support.
+ Local-first AI agent framework with multi-provider LLM support, 40+ tools, multi-agent orchestration, and channel integrations.
-# SmallClaw v1.1
-
-**Local AI agent framework with local + cloud provider support** — an open source alternative to cloud AI assistants that runs on your machine with free local models.
-
-**Current release:** `v1.1`
+**Current release:** `v2.6.0`
---
-> Image setup: put the two images in `assets/`:
-> - `assets/SmallClaw.png`
-> - `assets/SmallClawDashboard.png`
+## Features
-## What is SmallClaw?
-
-SmallClaw is a chat-first AI agent that supports multiple providers for local-only or hybrid setups (Ollama, llama.cpp, LM Studio, OpenAI API, and OpenAI Codex OAuth). It gives your local model real tools — files, web search, browser automation, terminal commands — delivered through a clean web UI with no API costs, no data leaving your machine.
-
-- ✅ **File operations** — Read, write, and surgically edit files with line-level precision
-- ✅ **Web search** — Multi-provider search (Tavily, Google, Brave, DuckDuckGo) with fallback
-- ✅ **Browser automation** — Full Playwright-powered browser control (click, fill, snapshot)
-- ✅ **Terminal access** — Run commands in your workspace safely
-- ✅ **Session memory** — Persistent chat sessions with pinned context
-- ✅ **Skills system** — Drop-in SKILL.md files to give the agent new capabilities
-- ✅ **Free forever** — No API costs, runs on your hardware
+- **Multi-provider LLM** — Ollama, llama.cpp, LM Studio, OpenAI API, OpenAI Codex OAuth
+- **40+ built-in tools** — Files, shell, web search, browser automation, email, PDF, PPTX, SQLite, Python eval, OCR, STT/TTS, and more
+- **Multi-agent orchestration** — Spawn sub-agents, delegate tasks, parallel or sequential execution
+- **Channel integrations** — Telegram, Discord, WhatsApp with file browser and inline controls
+- **MCP support** — Connect external Model Context Protocol servers (stdio or HTTP/SSE)
+- **Skills system** — Drop-in SKILL.md files for domain-specific capabilities
+- **Session memory** — Persistent chat sessions with pinned context and compaction
+- **Cron scheduling** — Autonomous agent runs on configurable schedules
+- **Self-repair** — Detect and propose fixes for its own source code
+- **Security** — Vault for secrets, log scrubbing, credential handler, error audit
+- **Docker-ready** — Full containerized setup with voice support variant
+- **Free forever** — No API costs when using local models
## Architecture
-SmallClaw v2 is built around a single-pass chat handler. When you send a message, one LLM call decides whether to respond conversationally or call tools — no separate planning, execution, and verification agents. This dramatically reduces latency and works much better with small models that struggle to coordinate across multiple roles.
+SmallClaw uses a reactor-based execution loop. Each turn, the model receives the system prompt (composed from workspace personality files, skill context, and session history), then either responds conversationally or calls tools. Tool results feed back into the same conversation until the model produces a final answer. Everything streams to the UI in real time via SSE.
```
-+-----------------------------------------------+
-| Web UI (index.html) |
-| Sessions · Chat · Process Log · Settings |
-+------------------------+----------------------+
- |
- SSE stream + REST
- |
-+-----------------------------------------------+
-| Express Gateway (server-v2.ts) |
-| Session state · Tool registry · SSE stream |
-+------------------------+----------------------+
- |
- Native tool-calling + provider API
- |
-+-----------------------------------------------+
-| handleChat() — the core loop |
-| 1) Build system prompt + short history |
-| 2) Single LLM call with tools exposed |
-| 3) Model decides: respond OR call tool(s) |
-| 4) Execute tool → stream result back |
-| 5) Repeat until final response |
-| 6) Stream final text to UI via SSE |
-+------------------------+----------------------+
- | | |
- v v v
- File Tools Web Tools Browser Tools
-(read/write/edit) (search/fetch) (Playwright)
+ Web UI / Telegram / Discord / WhatsApp
+ |
+ REST + SSE / WS
+ |
++-------------------------------------------------------------------+
+| Express Gateway (server-v2.ts) |
+| Session manager · Tool registry · Cron scheduler · MCP manager |
+| Heartbeat runner · Webhook handler · Sub-agent manager |
++----------------------------+--------------------------------------+
+ |
+ Reactor loop (reactor.ts)
+ 1) Build system prompt + history
+ 2) LLM call with tools exposed
+ 3) Execute tool calls → feed results back
+ 4) Repeat until final response
+ 5) Stream to UI / channels
+ |
+ +---------+---------+---------+---------+
+ | | | | |
+ File Web Browser Email Shell
+ Tools Tools Tools Tools Tools
+ | | | | |
+ Memory Scholar Desktop PPTX/PDF Python
+ Tools Tools Tools Tools Tools
```
-### How a turn works
+### Workspace personality files
-Every message goes through the same single path. The model sees the system prompt, a short rolling history (last 5 turns), and your message. It then either responds in plain text or emits a tool call. If it calls a tool, SmallClaw executes it and feeds the result back into the same conversation — the model keeps going until it writes a final text response. The whole thing is streamed back to the UI in real time as SSE events.
+Markdown files in `workspace/` shape the agent's behavior and memory:
-There are no separate discuss/plan/execute modes. The model decides in one shot whether a message needs tools or not.
+| File | Purpose |
+|------|---------|
+| `SOUL.md` | Core personality and behavioral guidelines |
+| `IDENTITY.md` | Name, role, and self-concept |
+| `USER.md` | User preferences and context |
+| `MEMORY.md` | Persistent memory and learned facts |
+| `AGENTS.md` | Available agents and their roles |
+| `TOOLS.md` | Tool usage guidelines |
+| `BOOT.md` | Startup instructions and boot tasks |
-### Session state
+## Tools
-Each browser session stores a rolling message history (last N turns) and a workspace path. History is kept short on purpose — small models perform better with compact context than with long accumulated histories. Pinned messages let you keep important context permanently in scope without bloating every turn.
-
-## How the Tools Work
-
-SmallClaw uses Ollama's native tool-calling format. The model doesn't write code to execute — it returns a structured JSON tool call, SmallClaw runs it in a sandboxed environment, and the result goes back to the model as a tool response message.
+SmallClaw ships with 40+ tools organized into categories. Tools are exposed via Ollama native tool-calling format — the model returns structured JSON, SmallClaw executes it sandboxed, and the result feeds back.
### File Tools
-File editing is surgical. The model is instructed to always read a file with line numbers first, then make targeted edits rather than rewriting entire files. This prevents the common small-model failure of silently dropping content during rewrites.
-
-| Tool | What it does |
+| Tool | Description |
|------|-------------|
-| `list_files` | List workspace directory contents |
-| `read_file` | Read file with line numbers |
-| `create_file` | Create a new file (fails if already exists) |
-| `replace_lines` | Replace lines N–M with new content |
-| `insert_after` | Insert content after line N |
-| `delete_lines` | Delete lines N–M |
-| `find_replace` | Find exact text string and replace it |
-| `delete_file` | Delete a file |
+| `read` | Read file with line numbers |
+| `write` | Create a new file |
+| `edit` | Replace exact text strings in a file |
+| `list` | List directory contents |
+| `delete` | Delete a file |
+| `rename` | Rename a file |
+| `copy` | Copy a file |
+| `mkdir` | Create directories |
+| `stat` | Get file metadata |
+| `append` | Append content to a file |
+| `apply_patch` | Apply a unified diff patch |
-### Web Tools
+### Shell & System
-| Tool | What it does |
+| Tool | Description |
|------|-------------|
-| `web_search` | Search across providers — returns headlines and snippets |
-| `web_fetch` | Fetch and extract the full text of a URL |
+| `shell` | Run shell commands in workspace |
+| `python_eval` | Evaluate Python code |
+| `sqlite_query` | Execute SQLite queries |
+| `time_now` | Get current date/time |
+| `spawn_agent` | Spawn a sub-agent for a task |
+| `task_control` | List, create, update, cancel background tasks |
-Search uses a provider waterfall: Tavily → Google CSE → Brave → DuckDuckGo. You configure API keys and provider preference in Settings → Search. If no keys are set, DuckDuckGo runs without a key as a baseline fallback.
+### Web & Research
-### Browser Tools
-
-SmallClaw controls a real browser via Playwright — not just opening a URL for you to click, but navigating, filling forms, and taking snapshots itself.
-
-| Tool | What it does |
+| Tool | Description |
|------|-------------|
-| `browser_open` | Open a URL in a Playwright-controlled browser |
-| `browser_snapshot` | Capture current page elements and layout |
-| `browser_click` | Click an element by reference ID |
+| `web_search` | Multi-provider search (Tavily, Google, Brave, DuckDuckGo, SearXNG) |
+| `web_fetch` | Fetch and extract text from a URL |
+| `pubmed_search` | Search PubMed/NCBI literature |
+| `pubmed_fetch` | Fetch PubMed abstract by PMID |
+| `pubmed_fulltext` | Fetch full-text from PMC |
+| `openalex_search` | Search OpenAlex academic index |
+| `semantic_search` | Search Semantic Scholar |
+| `weather` | Get weather data |
+
+### Browser Automation (Playwright)
+
+| Tool | Description |
+|------|-------------|
+| `browser_open` | Open URL in Playwright browser |
+| `browser_snapshot` | Capture page elements and layout |
+| `browser_click` | Click element by reference ID |
| `browser_fill` | Type into an input field |
| `browser_press_key` | Press Enter, Tab, Escape, etc. |
-| `browser_wait` | Wait N ms then snapshot (for dynamic pages) |
-| `browser_close` | Close the browser tab |
+| `browser_wait` | Wait then snapshot (for dynamic pages) |
+| `browser_scroll` | Scroll the page |
+| `browser_close` | Close browser tab |
+| `browser_get_images` | Collect images from page |
-### System Tools
+### Desktop Automation
-| Tool | What it does |
+| Tool | Description |
|------|-------------|
-| `run_command` | Open an app or file for you to interact with (VS Code, Notepad, Chrome). SmallClaw can open it but not control it. |
-| `start_task` | Launch a multi-step background task for long-running operations |
+| `desktop_screenshot` | Capture desktop screenshot |
+| `desktop_find_window` | Find a window by title |
+| `desktop_focus_window` | Bring window to foreground |
+| `desktop_click` | Click at screen coordinates |
+| `desktop_drag` | Drag between coordinates |
+| `desktop_wait` | Wait N milliseconds |
+| `desktop_type` | Type text at focused position |
+| `desktop_press_key` | Press keyboard key |
+| `desktop_get_clipboard` | Read clipboard contents |
+| `desktop_set_clipboard` | Write to clipboard |
+
+### Email (IMAP + SMTP)
+
+| Tool | Description |
+|------|-------------|
+| `email_list` | List emails in a folder |
+| `email_read` | Read a specific email |
+| `email_send` | Send an email |
+| `email_search` | Search emails by criteria |
+| `email_delete` | Delete an email |
+
+### Documents & Media
+
+| Tool | Description |
+|------|-------------|
+| `pdf_read` | Extract text from PDF files |
+| `pptx_create` | Generate PowerPoint presentations |
+| `pptx_edit` | Edit existing PowerPoint files |
+| `image_read` | Read/OCR images (Tesseract.js) |
+| `audio_transcribe` | Transcribe audio via Whisper |
+
+### Memory & Persona
+
+| Tool | Description |
+|------|-------------|
+| `memory_search` | Search stored memories (semantic/MMR) |
+| `memory_write` | Store a new memory |
+| `memory_read` | Read memories by ID |
+| `memory_file_search` | Search files in memory store |
+| `persona_read` | Read current persona configuration |
+| `persona_update` | Update persona settings |
+
+### Skills & Self-Management
+
+| Tool | Description |
+|------|-------------|
+| `skill_list` | List installed skills |
+| `skill_search` | Search ClawHub skill registry |
+| `skill_install` | Install a skill from registry |
+| `skill_remove` | Remove an installed skill |
+| `skill_exec` | Execute a skill |
+| `self_update` | Check and apply SmallClaw updates |
+| `read_source` | Read SmallClaw own source files |
+| `list_source` | List SmallClaw source files |
+| `propose_repair` | Propose a self-repair for a bug |
+
+### Tool Profiles
+
+Agents can be assigned tool profiles to limit their capabilities:
+
+| Profile | Description |
+|---------|-------------|
+| `minimal` | memory_search, memory_write, time_now |
+| `coding` | shell, file tools, python, sqlite, pdf, image, audio |
+| `web` | web tools, pubmed, scholar, pdf, image |
+| `full` | All registered tools (default) |
+
+## Multi-Agent Orchestration
+
+SmallClaw supports two multi-agent modes:
+
+### Delegate to Specialist (default, `subagent_mode: false`)
+
+Designed for 4B local models. Fixed specialist roles with structured I/O, sequential execution. The primary agent delegates to named sub-agents with restricted tool profiles (file_editor, researcher, shell_runner, reader_only). Recursion is prevented at the profile level.
+
+### Sub-Agent Spawn (`subagent_mode: true`)
+
+Free-form arbitrary task prompts (Claude Cowork-style). Parallel execution. Primary agent acts as orchestrator. Best for larger models.
+
+```
+Parent task calls delegate_to_specialist / subagent_spawn
+ |
+Child task created with profile + instructions
+ |
+Parent status -> 'waiting_subagent'
+ |
+Child BackgroundTaskRunner executes independently
+ |
+Child completes -> result injected into parent context
+ |
+Parent resumes automatically
+```
+
+### Agent Definitions
+
+Define named agents in `.smallclaw/config.json`:
+
+```jsonc
+{
+ "agents": [
+ {
+ "id": "main",
+ "name": "Rafi",
+ "description": "Main daily assistant",
+ "emoji": "🦞",
+ "default": true,
+ "tools": { "profile": "full" },
+ "minimalPrompt": false
+ },
+ {
+ "id": "researcher",
+ "name": "Scout",
+ "description": "Deep web research",
+ "emoji": "🔍",
+ "model": "ollama/qwen3:4b",
+ "tools": { "profile": "web", "deny": ["browser"] },
+ "minimalPrompt": true,
+ "maxSteps": 10
+ },
+ {
+ "id": "orchestrator",
+ "name": "Director",
+ "description": "Coordinates other agents on a cron schedule",
+ "emoji": "🎬",
+ "tools": { "profile": "full" },
+ "canSpawn": true,
+ "spawnAllowlist": ["researcher", "writer"],
+ "cronSchedule": "0 8 * * *"
+ }
+ ]
+}
+```
+
+## Channels
+
+SmallClaw integrates with messaging platforms:
+
+### Telegram
+- Long-polling bot (no port forwarding needed)
+- File browser: `/browse [path]` with inline keyboard navigation
+- File download: `/download ` as Telegram attachment
+- Allowed user ID allowlist
+- Streaming or partial response modes
+
+### Discord
+- Webhook-based integration
+- Bot token + guild/channel configuration
+
+### WhatsApp
+- Business API integration
+- Access token + phone number ID configuration
+
+## MCP Integrations
+
+Connect external MCP (Model Context Protocol) servers from Settings -> Integrations:
+
+- **stdio transport** — spawn a local process (e.g., filesystem, database MCP servers)
+- **HTTP/SSE transport** — connect to remote MCP servers
+- Configure auth and env values per server
+- MCP tools become available to the agent after saving
## Installation
### Prerequisites
-1. **Node.js** 18+ ([Download](https://nodejs.org/))
-2. **At least one model provider**:
- - Ollama ([Download](https://ollama.ai/))
- - llama.cpp server
- - LM Studio local server
- - OpenAI API key
- - OpenAI Codex OAuth (ChatGPT account)
+1. **Node.js** 18+
+2. **At least one model provider**: Ollama, llama.cpp server, LM Studio, OpenAI API, or OpenAI Codex OAuth
3. **At least 8GB RAM** (16GB recommended for coding tasks)
-### Option A: npm Global Install (Recommended)
-
-The fastest way to get started:
+### Option A: npm Global Install
```bash
npm install -g smallclaw
@@ -176,13 +340,7 @@ smallclaw onboard
smallclaw gateway start
```
-Then open `http://localhost:18789` in your browser.
-
-To update later:
-
-```bash
-smallclaw update
-```
+Then open `http://localhost:18789`.
### Option B: From Source
@@ -194,52 +352,12 @@ npm run build
npm start
```
-Or install globally from a local clone:
-
-```bash
-git clone https://github.com/xposemarket/smallclaw.git
-cd smallclaw
-npm install
-npm install -g .
-```
-
### Auto-Start on Login
-#### Windows
-Create a Task Scheduler task pointing to:
-```powershell
-smallclaw gateway start
-```
+#### Linux (systemd)
-#### macOS
-Create a LaunchAgent at `~/Library/LaunchAgents/com.smallclaw.plist` with:
-```xml
-
-
-
-
- Label
- com.smallclaw.gateway
- ProgramArguments
-
- smallclaw
- gateway
- start
-
- RunAtLoad
-
- StandardOutPath
- /tmp/smallclaw.log
- StandardErrorPath
- /tmp/smallclaw.err
-
-
-```
-Then run: `launchctl load ~/Library/LaunchAgents/com.smallclaw.plist`
-
-#### Linux
-Create a systemd service at `~/.config/systemd/user/smallclaw.service` with:
```ini
+# ~/.config/systemd/user/smallclaw.service
[Unit]
Description=SmallClaw AI Gateway
After=network.target
@@ -255,23 +373,26 @@ StandardError=append:/tmp/smallclaw.err
[Install]
WantedBy=default.target
```
-Then run:
+
```bash
systemctl --user daemon-reload
systemctl --user enable smallclaw
systemctl --user start smallclaw
```
+#### macOS (LaunchAgent)
+
+Create `~/Library/LaunchAgents/com.smallclaw.plist` and load with `launchctl load`.
+
+#### Windows (Task Scheduler)
+
+Create a task pointing to: `smallclaw gateway start`
+
## Quick Start
```bash
-# Install globally
npm install -g smallclaw
-
-# First-time setup
smallclaw onboard
-
-# Start the gateway
smallclaw gateway start
```
@@ -289,18 +410,20 @@ ollama pull qwen2.5-coder:32b
### 2. Configure models and search
-In the web UI, open Settings (⚙️ in the top bar):
+In the web UI, open Settings:
-- **Models tab** — choose provider + model (Ollama, llama.cpp, LM Studio, OpenAI API, or OpenAI Codex OAuth)
-- **Search tab** — add API keys for Tavily, Google, or Brave if you want better web search results
+- **Models** — choose provider + model
+- **Search** — add API keys for Tavily, Google, or Brave
+- **Channels** — configure Telegram/Discord/WhatsApp
+- **Integrations** — add MCP servers
### 3. Test webhooks
-See [WEBHOOKS.md](./WEBHOOKS.md) for curl examples and webhook endpoint testing (cross-platform)
+See [WEBHOOKS.md](./WEBHOOKS.md) for curl examples and webhook endpoint testing.
## Configuration
-Config is stored in `.smallclaw/config.json` in the project folder (or `~/.smallclaw/config.json` as a fallback):
+Config is stored in `.smallclaw/config.json` in the project folder (or `~/.smallclaw/config.json` as fallback):
```json
{
@@ -321,179 +444,56 @@ Config is stored in `.smallclaw/config.json` in the project folder (or `~/.small
"google_api_key": "",
"google_cx": "",
"brave_api_key": "",
+ "searxng_url": "",
"search_rigor": "verified"
},
"workspace": {
"path": "path/to/your/workspace"
+ },
+ "voice": {
+ "enabled": true,
+ "stt": { "provider": "whisper_cpp", "model": "base" },
+ "tts": { "provider": "piper", "model": "ko_KR-kss-medium" }
+ },
+ "orchestration": {
+ "enabled": true,
+ "secondary": { "provider": "", "model": "" },
+ "subagent_mode": false
}
}
```
-Most settings can be changed live from the Settings panel without restarting the gateway.
-
-### Agents Array Example
-
-User-defined agents (no preset roles). Put this in `.smallclaw/config.json`:
-
-```jsonc
-{
- "agents": [
- {
- "id": "main",
- "name": "Rafi",
- "description": "My main daily assistant. Handles chat, tasks, and general requests.",
- "emoji": "🦞",
- "default": true,
- "workspace": "D:/SmallClaw/workspace",
- "tools": { "profile": "full" },
- "minimalPrompt": false
- },
- {
- "id": "researcher",
- "name": "Scout",
- "description": "Deep web research. Given a topic, returns a structured research brief.",
- "emoji": "🔍",
- "workspace": "D:/SmallClaw/agents/researcher/workspace",
- "model": "ollama/qwen3:4b",
- "tools": { "profile": "web", "deny": ["browser"] },
- "minimalPrompt": true,
- "maxSteps": 10
- },
- {
- "id": "writer",
- "name": "Quill",
- "description": "Content writer. Takes research briefs and produces polished drafts.",
- "emoji": "✍️",
- "workspace": "D:/SmallClaw/agents/writer/workspace",
- "tools": { "profile": "coding", "deny": ["web_search", "web_fetch", "browser"] },
- "minimalPrompt": true
- },
- {
- "id": "orchestrator",
- "name": "Director",
- "description": "Coordinates other agents. Runs on a cron schedule to manage autonomous pipelines.",
- "emoji": "🎬",
- "workspace": "D:/SmallClaw/agents/orchestrator/workspace",
- "tools": { "profile": "full" },
- "minimalPrompt": false,
- "canSpawn": true,
- "spawnAllowlist": ["researcher", "writer"],
- "cronSchedule": "0 8 * * *"
- }
- ]
-}
-```
-
-## Self-Updating
-
-SmallClaw includes a built-in updater. In most cases, users can update from any install directory with:
-
-```bash
-smallclaw update
-```
-
-Use this to check first:
-
-```bash
-smallclaw update check
-```
-
-If your install was manually copied or linked from a custom path, `smallclaw update` still works, but make sure the command resolves to the same install you are currently running.
-
-## MCP Integrations (Settings -> Integrations)
-
-SmallClaw supports MCP server connections from the web UI. Open **Settings -> Integrations** to add servers and credentials.
-
-- Add one or more MCP servers (local or remote)
-- Configure auth/env values per server
-- Save and test directly from the panel
-- Use presets for common providers as a quick start
-
-MCP tools become available to the agent after saving valid settings.
-
-## Webhook Channels (Settings -> Channels)
-
-SmallClaw channel connections are managed in **Settings -> Channels** with a channel selector:
-
-- Telegram
-- Discord
-- WhatsApp
-
-Each channel has its own connection fields and setup instructions. Save settings per channel, run **Test**, then **Send Test** to verify outbound delivery and webhook configuration.
-
-## CLI Commands
-
-### Gateway
-```bash
-# Start the web UI gateway
-smallclaw gateway start
-
-# Check gateway status
-smallclaw gateway status
-```
-
-### Model Management
-```bash
-# List available local models
-smallclaw model list
-
-# Set primary model
-smallclaw model set qwen2.5-coder:32b
-
-# Pull a new model via Ollama
-smallclaw model pull llama-3.3:70b
-```
-
-### System
-```bash
-# Health check
-smallclaw doctor
-
-# Check for updates
-smallclaw update check
-
-# Apply updates
-smallclaw update
-```
-
-## Skills
-
-SmallClaw supports drop-in SKILL.md files that give the model extra context and capabilities for specific domains. Place skill files in `.smallclaw/skills//SKILL.md`. The model loads and applies them automatically when relevant.
-
-Skills are plain markdown — write instructions, examples, and constraints in natural language. No code required.
+Most settings can be changed live from the Settings panel without restarting.
## Provider Support
-SmallClaw supports these providers in Settings -> Models:
+| Provider | Type | Auth |
+|----------|------|------|
+| `ollama` | Local | None |
+| `llama_cpp` | Local (OpenAI-compatible) | Optional API key |
+| `lm_studio` | Local (OpenAI-compatible) | Optional API key |
+| `openai` | Cloud | API key |
+| `openai_codex` | Cloud | ChatGPT OAuth |
-- `ollama` (local)
-- `llama_cpp` (local OpenAI-compatible server)
-- `lm_studio` (local OpenAI-compatible server)
-- `openai` (API key)
-- `openai_codex` (ChatGPT OAuth/Codex endpoint)
+Provider selection is live through the web Settings API.
-Provider selection is live through the web settings API and used by the unified provider factory.
+## CLI Commands
-## Multi-Agent Orchestration (Optional Skill)
+```bash
+# Gateway
+smallclaw gateway start # Start the web UI gateway
+smallclaw gateway status # Check gateway status
-SmallClaw includes an optional `multi-agent-orchestrator` skill for dual-model advisor/executor behavior:
+# Model management
+smallclaw model list # List available local models
+smallclaw model set qwen3:4b # Set primary model
+smallclaw model pull llama-3.3:70b # Pull a new model
-- Primary model remains executor (tools + edits).
-- Secondary model gives structured planner/rescue guidance.
-- Secondary preflight can run first (`off`, `complex_only`, `always`).
-- Rescue can auto-trigger on failures, loops, risky edits, or no progress.
-
-Important behavior:
-
-- This feature is **not default**.
-- It only runs when the `multi-agent-orchestrator` skill is enabled and eligible.
-- If the skill is disabled, preflight/rescue/post-check continuation logic is disabled.
-
-Current safety/quality controls:
-
-- Assist cooldown and per-turn/session caps
-- Telemetry endpoint: `GET /api/orchestration/telemetry?sessionId=`
-- Post-check continuation: prevents intent-only replies from ending execution early (skill-gated)
+# System
+smallclaw doctor # Health check
+smallclaw update check # Check for updates
+smallclaw update # Apply updates
+```
## Model Recommendations
@@ -509,18 +509,47 @@ Current safety/quality controls:
## Optimizing for Small Models
-SmallClaw is specifically designed around the constraints of 4B–32B parameter models:
+SmallClaw is designed around the constraints of 4B-32B parameter models:
- **Short history window** — Only the last 5 turns are sent by default, keeping context tight
- **Line-number-first file editing** — Forces the model to read before writing, preventing content loss
-- **Native tool-calling** — Uses Ollama's structured tool format instead of free-form code generation, which is much more reliable at small scales
-- **Single-pass routing** — One LLM call decides whether to use tools or respond; no coordination overhead between multiple agents
-- **Surgical edits over rewrites** — `replace_lines`, `insert_after`, `delete_lines` instead of `write_file` for existing files
+- **Native tool-calling** — Uses structured tool format instead of free-form code generation
+- **Tool profiles** — Restrict sub-agents to minimal tool sets to reduce decision space
+- **Surgical edits over rewrites** — `edit`, `apply_patch` instead of full file rewrites
+- **Session compaction** — Automatic history compression when context grows too large
+
+## Voice Support
+
+SmallClaw supports voice input and output when configured:
+
+- **STT**: Whisper C++ for speech-to-text
+- **TTS**: Piper for text-to-speech
+- **Language**: Configurable (default: Korean)
+- **Docker**: Use `docker-compose.voice.yml` + `Dockerfile.voice` for a voice-enabled container
+
+## Self-Repair & Self-Update
+
+SmallClaw can inspect and repair its own source code:
+
+- `read_source` / `list_source` — Read its own source files
+- `propose_repair` — Propose a fix for a detected bug
+- `self_update` — Check for and apply SmallClaw updates
+
+```bash
+smallclaw update check # Check for updates
+smallclaw update # Apply updates
+```
+
+## Security
+
+- **Vault** — Encrypted storage for API keys and credentials
+- **Log scrubbing** — Automatic removal of sensitive data from logs
+- **Credential handler** — Safe credential management for external services
+- **Error audit** — Track and audit error patterns for security anomalies
+- **Error categorizer** — Classify errors by severity and type
## Docker Setup
-SmallClaw can be run fully containerized via Docker Compose.
-
### Quick Start (Bundled Ollama)
```bash
@@ -529,14 +558,12 @@ docker compose build --no-cache
docker compose --profile ollama up -d
```
-Then open `http://your-server-ip:18789` in your browser.
+Open `http://your-server-ip:18789`.
### External Ollama (Already Running)
-If Ollama is already running in a separate container on the same Docker network:
-
```bash
-# In your .env file:
+# In .env:
SMALLCLAW_PROVIDER=ollama
OLLAMA_HOST=http://your-ollama-container:11434
@@ -544,14 +571,18 @@ OLLAMA_HOST=http://your-ollama-container:11434
docker compose up -d smallclaw
```
-### Mapping to a Different Host Port
-
-The app always listens on port **18789 inside the container**. To expose it on a different host port, set `HOST_PORT` in your `.env`:
+### Voice-Enabled Container
```bash
-# In your .env:
+docker compose -f docker-compose.voice.yml up -d
+```
+
+### Custom Host Port
+
+```bash
+# In .env:
HOST_PORT=8080
-# Docker maps: host:8080 → container:18789
+# Docker maps: host:8080 -> container:18789
```
### Environment Variables (Docker)
@@ -563,70 +594,55 @@ HOST_PORT=8080
| `GATEWAY_HOST` | `0.0.0.0` | Bind address inside container |
| `DOCKER_CONTAINER` | `true` | Auto-set in Dockerfile; enables 0.0.0.0 binding |
-> **Important:** Inside Docker, the server must bind to `0.0.0.0`, not `127.0.0.1`. Binding to loopback makes the gateway unreachable from outside the container even with port mapping configured. SmallClaw handles this automatically when `DOCKER_CONTAINER=true`.
-
----
-
## Troubleshooting
### "Cannot connect to Ollama"
```bash
-# Start Ollama
ollama serve
-
-# Verify it's running
curl http://localhost:11434/api/tags
```
### "No models found" in Settings
```bash
-# Pull a model first
ollama pull qwen3:4b
-
-# Confirm it's installed
ollama list
```
### "Out of memory / model crashes"
- Drop to a smaller model (qwen3:4b instead of 32b)
- Close other memory-intensive apps
-- Set `llm_workers: 1` in config if you have multiple concurrent users
+- Set `llm_workers: 1` in config for concurrent users
-### Tool calls not working / model just chatting
-- Check Settings → Models and confirm a model is selected and saved
-- Some models handle tool-calling better than others — qwen3 and qwen2.5-coder series are most reliable
-- If the model keeps ignoring tool calls, try a larger variant
+### Tool calls not working
+- Confirm a model is selected and saved in Settings
+- qwen3 and qwen2.5-coder series handle tool-calling best
+- Try a larger model variant if tools are ignored
-### Docker: Web UI unreachable after container starts
-If the container starts cleanly (you see the gateway banner and `[CronScheduler] Started`) but the UI is not reachable on the mapped port, there are three things to check:
-1. **Bind address** — The server must bind to `0.0.0.0` inside Docker, not `127.0.0.1`. This is handled automatically via the `DOCKER_CONTAINER=true` env var set in the Dockerfile. If you overrode `GATEWAY_HOST`, make sure it is `0.0.0.0`.
-2. **Port mismatch** — The app's internal port is always `18789`. Your `.env` file should use `HOST_PORT` (not `GATEWAY_PORT`) to remap on your machine. `GATEWAY_PORT` controls the internal port and should stay `18789`.
-3. **Stale image** — If you built the image before these fixes, rebuild with `--no-cache`: `docker compose build --no-cache`.
-
-### Background task resumes creating a new task instead of continuing
-If you reply to a paused/escalated task and SmallClaw starts a brand new task instead of resuming, this was a bug fixed in v1.0.3. The follow-up intercept now detects the existing blocked task for your session and routes your reply to it automatically. Phrases like "proceed", "go ahead", "I fixed it", and "done" all trigger a resume without needing to reference the task explicitly.
-
-### Browser automation looping on snapshots
-If a browser task takes repeated snapshots without clicking or filling anything, stall detection should now catch this within 5 identical snapshots (previously 20). If you're on an older build, update and rebuild. The browser advisor also enforces an anti-loop rule: if a snapshot was just taken and `@ref` numbers are available, the next action must be a click or fill — not another snapshot.
+### Docker: Web UI unreachable
+1. **Bind address** — Must be `0.0.0.0` inside Docker (handled by `DOCKER_CONTAINER=true`)
+2. **Port mismatch** — Use `HOST_PORT` not `GATEWAY_PORT` for remapping
+3. **Stale image** — Rebuild with `--no-cache`
## Roadmap
-- [x] Single-pass native tool-calling architecture
-- [x] Session-based chat UI
-- [x] File editing with line-level precision
-- [x] Web search with multi-provider fallback
-- [x] Playwright browser automation
-- [x] Skills system (SKILL.md)
-- [x] Live settings (model, search, paths) from UI
-- [ ] Persistent sessions (survive gateway restarts)
-- [ ] Background task daemon mode
-- [ ] Memory / vector store for long-running projects
+- [x] Reactor-based native tool-calling architecture
+- [x] Session-based chat UI with compaction
+- [x] 40+ tools across files, web, browser, email, documents, memory
+- [x] Multi-agent orchestration (delegate + sub-agent spawn)
+- [x] Channel integrations (Telegram, Discord, WhatsApp)
+- [x] MCP server support
+- [x] Voice input/output (Whisper + Piper)
+- [x] Desktop automation
+- [x] Self-repair and self-update
+- [x] Cron scheduling for autonomous runs
+- [x] Docker containerization
+- [ ] Persistent sessions across gateway restarts
- [ ] Git operations tool
- [ ] Desktop app wrapper
## Contributing
-Feel Free to donate if this helped you save some API costs and help me get a Claude Max account to keep working on this faster lol - Cashapp $Fvnso - Venmo @Fvnso .
+Feel free to donate if this helped you save API costs — Cashapp $Fvnso / Venmo @Fvnso.
## License
@@ -634,9 +650,4 @@ MIT
## Credits
-Inspired by [OpenClaw](https://openclaw.ai) and the Anthropic team. Built for the local-first AI community.
-
----
-
-**Note:** This README reflects SmallClaw `v1.1`.
-
+Inspired by [OpenClaw](https://openclaw.ai) and the Anthropic team. Built for the local-first AI community.
\ No newline at end of file
diff --git a/src/config/config.ts b/src/config/config.ts
index 4e37b05..9ac3d5c 100644
--- a/src/config/config.ts
+++ b/src/config/config.ts
@@ -120,7 +120,8 @@ export const DEFAULT_CONFIG: SmallClawConfig = {
roles: {
manager: 'gemini-3-flash-preview:cloud',
executor: 'gemini-3-flash-preview:cloud',
- verifier: 'gemini-3-flash-preview:cloud'
+ verifier: 'gemini-3-flash-preview:cloud',
+ background_task: ''
}
},
tools: {
diff --git a/src/gateway/background-task-runner.ts b/src/gateway/background-task-runner.ts
index eb12d4e..3e2c11f 100644
--- a/src/gateway/background-task-runner.ts
+++ b/src/gateway/background-task-runner.ts
@@ -17,7 +17,9 @@ import {
type TaskRecord,
} from './task-store';
import { clearHistory, addMessage, getHistory, flushSession } from './session';
+import { getConfig, getUserWorkspace } from '../config/config';
import { callSecondaryTaskStepAuditor } from '../orchestration/multi-agent';
+import { getModelForRole } from '../providers/factory';
import { errorCategorizer } from './error-categorizer';
import { getRetryStrategy } from './retry-strategy';
import { getErrorAnalyzer } from './error-analyzer';
@@ -39,6 +41,8 @@ const MAX_RESUME_MESSAGES = 10;
const BACKGROUND_SESSION_MAX_MESSAGES = 40;
const DEFAULT_ROUND_TIMEOUT_MS = 120_000;
const MAX_STEP_VERIFICATION_RETRIES = 2;
+const MAX_TOTAL_SELF_HEAL_ATTEMPTS = 5;
+const MAX_TOTAL_ROUNDS = Number(process.env.LOCALCLAW_BG_MAX_ROUNDS) || 50;
function resolveRoundTimeoutMs(isResearchTask?: boolean): number {
const candidates = [
@@ -271,6 +275,22 @@ export class BackgroundTaskRunner {
`[/RESEARCH TASK GUIDANCE]`,
].join('\n') : '';
+ const workspacePath = task.ownerUsername
+ ? getUserWorkspace(task.ownerUsername)
+ : getConfig().getWorkspacePath();
+
+ const envInfo = [
+ ``,
+ `[EXECUTION ENVIRONMENT]`,
+ `OS: Linux — do NOT use Windows commands (taskkill, cmd.exe, backslashes, python.exe)`,
+ `Python: always use "python3" (not "python")`,
+ `Shell: bash`,
+ `Workspace path: ${workspacePath}`,
+ `IMPORTANT: This is a background task. You cannot schedule future check-ins via write_note.`,
+ `If you need to poll a running process, wait inline with a shell loop. Do not write "will check at HH:MM" — that check will never happen.`,
+ `[/EXECUTION ENVIRONMENT]`,
+ ].join('\n');
+
return [
`[BACKGROUND TASK CONTEXT]`,
`Task ID: ${task.id}`,
@@ -280,7 +300,7 @@ export class BackgroundTaskRunner {
task.plan[task.currentStepIndex]
? `Step Description: ${task.plan[task.currentStepIndex].description}`
: '',
- `You are running autonomously. Execute the task step by step.${profileNote}${resumeNote}${xLoginGuidance}${researchGuidance}`,
+ `You are running autonomously. Execute the task step by step.${profileNote}${resumeNote}${xLoginGuidance}${researchGuidance}${envInfo}`,
`[/BACKGROUND TASK CONTEXT]`,
].filter(Boolean).join('\n');
}
@@ -403,6 +423,8 @@ export class BackgroundTaskRunner {
for (let attempt = 0; attempt <= MAX_TRANSPORT_RETRIES; attempt++) {
let attemptResult: { type: string; text: string; thinking?: string };
const attemptAbortSignal = { aborted: abortSignal.aborted };
+ const bgModel = getModelForRole('background_task');
+ const bgModelOverride = bgModel || undefined;
try {
attemptResult = await this._withRoundTimeout(
@@ -413,7 +435,7 @@ export class BackgroundTaskRunner {
undefined,
attemptAbortSignal,
callerContext,
- undefined,
+ bgModelOverride,
'background_task',
task.ownerUsername,
),
@@ -584,9 +606,11 @@ export class BackgroundTaskRunner {
const isBrowserSnapshotTool = /^browser_snapshot$/i.test(String(data.action || ''));
const isBrowserResearchTool = /^browser_(press_key|wait|scroll)$/i.test(String(data.action || ''));
const isBrowserNavTool = /^browser_(click|fill|open)$/i.test(String(data.action || ''));
+ const isShellTool = /^shell$/i.test(String(data.action || ''));
const stallThreshold = isBrowserSnapshotTool ? 3 // snapshots: stall after 3 identical
: isBrowserResearchTool ? 6 // scroll/wait/key: 6 — looping without acting
: isBrowserNavTool ? 20 // click/fill/open: 20 for nav flows
+ : isShellTool ? 6 // shell: 6 — allow retries with slight variation
: 4; // all other tools: 4
if (next > stallThreshold && !roundStallReason) {
roundStallReason = `Stall detected: ${String(data.action || 'unknown')} called ${next} times without progress (last 6 rounds).`;
@@ -614,6 +638,12 @@ export class BackgroundTaskRunner {
content: `${data.action || 'unknown'}: ${String(data.result || '').slice(0, 120)}${data.error ? ' [ERROR]' : ''}`,
detail: data.error ? String(data.result || '') : undefined,
});
+ // Track repeated shell errors so we can inject hints into the next prompt.
+ if (data.error && /^shell$/i.test(String(data.action || ''))) {
+ const cmd = String(data.args?.command || '').slice(0, 200);
+ const prev = shellErrorHints.get(cmd) || { count: 0, lastError: '' };
+ shellErrorHints.set(cmd, { count: prev.count + 1, lastError: String(data.result || '').slice(0, 300) });
+ }
// Fill in result for the matching pending entry so the auditor has full evidence.
for (let i = currentRoundToolLog.length - 1; i >= 0; i--) {
if (currentRoundToolLog[i].tool === (data.action || 'unknown') && currentRoundToolLog[i].result === '') {
@@ -630,12 +660,27 @@ export class BackgroundTaskRunner {
let lastResultSummary = '';
const stepRetryHints = new Map();
const stepVerificationRetries = new Map();
+ let totalRounds = 0;
+ let totalSelfHealAttempts = 0;
+ // Track shell commands that have repeatedly failed so we can inject hints
+ const shellErrorHints = new Map();
while (true) {
+ totalRounds++;
const task = loadTask(taskId);
if (!task) return;
if (task.status === 'complete' || task.status === 'failed') return;
+ if (totalRounds > MAX_TOTAL_ROUNDS) {
+ appendJournal(taskId, {
+ type: 'status_push',
+ content: `Reached maximum total rounds (${MAX_TOTAL_ROUNDS}). Pausing for assistance.`,
+ });
+ await this._pauseForAssistance(task, 'max_rounds_reached',
+ `Task exceeded ${MAX_TOTAL_ROUNDS} total execution rounds.`);
+ return;
+ }
+
if (pauseRequests.has(taskId)) {
const pauseReason = task.pauseReason || 'user_pause';
const scheduleId = task.pausedByScheduleId;
@@ -761,6 +806,12 @@ export class BackgroundTaskRunner {
updateTaskStatus(taskId, 'running');
const currentStep = task.plan[task.currentStepIndex];
const retryHint = stepRetryHints.get(task.currentStepIndex);
+ const failedCmds = Array.from(shellErrorHints.entries())
+ .filter(([, v]) => v.count >= 2)
+ .map(([cmd, v]) => ` - "${cmd}" (failed ${v.count}x): ${v.lastError.slice(0, 150)}`);
+ const shellErrorNote = failedCmds.length > 0
+ ? `\nSHELL ERROR HISTORY (do NOT retry these commands — try a different approach):\n${failedCmds.join('\n')}`
+ : '';
const prompt = firstRound
? (
this.openingAction
@@ -775,6 +826,7 @@ export class BackgroundTaskRunner {
``,
`You MUST complete this step before moving on. When done, clearly state what you did to complete it so the verifier can confirm.`,
retryHint ? `VERIFIER FEEDBACK (previous attempt failed): ${retryHint}` : '',
+ shellErrorNote,
`REMAINING STEPS:`,
...task.plan.slice(task.currentStepIndex + 1).map((s, i) =>
` Step ${task.currentStepIndex + 2 + i}: ${s.description}`
@@ -922,6 +974,20 @@ export class BackgroundTaskRunner {
content: `Auditor found no completed steps (${retries}/${MAX_STEP_VERIFICATION_RETRIES}): ${reason}`,
});
if (retries >= MAX_STEP_VERIFICATION_RETRIES) {
+ totalSelfHealAttempts++;
+ if (totalSelfHealAttempts > MAX_TOTAL_SELF_HEAL_ATTEMPTS) {
+ appendJournal(taskId, {
+ type: 'status_push',
+ content: `Self-heal attempts exceeded limit (${MAX_TOTAL_SELF_HEAL_ATTEMPTS}). Escalating to user.`,
+ });
+ await this._pauseForAssistance(
+ task,
+ `Self-heal attempts exceeded limit (${MAX_TOTAL_SELF_HEAL_ATTEMPTS}).`,
+ 'Too many self-heal attempts without progress.',
+ );
+ flushSession(sessionId);
+ return;
+ }
const healed = await this._attemptSelfHeal(
task,
`Step ${stepIndex + 1} failed verification after ${retries} retries.`,
@@ -958,6 +1024,20 @@ export class BackgroundTaskRunner {
content: `Auditor result rejected (${retries}/${MAX_STEP_VERIFICATION_RETRIES}): ${reason}`,
});
if (retries >= MAX_STEP_VERIFICATION_RETRIES) {
+ totalSelfHealAttempts++;
+ if (totalSelfHealAttempts > MAX_TOTAL_SELF_HEAL_ATTEMPTS) {
+ appendJournal(taskId, {
+ type: 'status_push',
+ content: `Self-heal attempts exceeded limit (${MAX_TOTAL_SELF_HEAL_ATTEMPTS}). Escalating to user.`,
+ });
+ await this._pauseForAssistance(
+ task,
+ `Self-heal attempts exceeded limit (${MAX_TOTAL_SELF_HEAL_ATTEMPTS}).`,
+ 'Too many self-heal attempts without progress.',
+ );
+ flushSession(sessionId);
+ return;
+ }
const healed = await this._attemptSelfHeal(
task,
`Step ${stepIndex + 1} failed verification after ${retries} retries.`,
diff --git a/src/gateway/cron-scheduler.ts b/src/gateway/cron-scheduler.ts
index a4f3483..214d54a 100644
--- a/src/gateway/cron-scheduler.ts
+++ b/src/gateway/cron-scheduler.ts
@@ -470,6 +470,8 @@ export class CronScheduler {
// ─── Job Execution ────────────────────────────────────────────────────────────
+ private static readonly EXECUTION_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
+
private async executeJob(job: CronJob): Promise {
this.runningJobId = job.id;
const start = Date.now();
@@ -527,28 +529,22 @@ export class CronScheduler {
let duration = 0;
let spawnedTaskId: string | null = null;
- try {
+ const execPromise = (async () => {
if (job.payloadKind === 'systemEvent') {
const text = String(job.systemEventText || job.prompt || '').trim();
if (text) {
this.deps.injectSystemEvent?.(targetSessionId, text, job);
- resultText = text;
+ return text;
} else {
- resultText = 'SYSTEM_EVENT_EMPTY';
+ return 'SYSTEM_EVENT_EMPTY';
}
} else if (this.deps.spawnBackgroundTask) {
- // ── Preferred path: spawn a proper BackgroundTask with full task runner ──
- // This gives the job a plan, journal, kanban card, retry logic, and
- // correct tool access — instead of a raw single-shot handleChat call.
const spawned = await this.deps.spawnBackgroundTask(job);
if (spawned) {
spawnedTaskId = spawned.taskId;
console.log(`[CronScheduler] Job "${job.name}" spawned as background task ${spawned.taskId}`);
- // The task runs asynchronously — we mark the job complete now.
- // The BackgroundTaskRunner will broadcast task_complete when done.
- resultText = `__BACKGROUND_TASK_SPAWNED__:${spawned.taskId}`;
+ return `__BACKGROUND_TASK_SPAWNED__:${spawned.taskId}`;
} else {
- // Fallback to direct handleChat if spawn failed
const modelOverride = String(job.model || '').trim() || undefined;
const result = await this.deps.handleChat(
job.prompt,
@@ -561,7 +557,7 @@ export class CronScheduler {
'cron',
job.ownerUsername,
);
- resultText = result.text || '';
+ return result.text || '';
}
} else {
const modelOverride = String(job.model || '').trim() || undefined;
@@ -576,8 +572,19 @@ export class CronScheduler {
'cron',
job.ownerUsername,
);
- resultText = result.text || '';
+ return result.text || '';
}
+ })();
+
+ try {
+ const timeoutMs = CronScheduler.EXECUTION_TIMEOUT_MS;
+ resultText = await Promise.race([
+ execPromise,
+ new Promise((_, reject) => {
+ const tid = setTimeout(() => reject(new Error(`Cron job execution timeout (${Math.round(timeoutMs / 60000)}m)`)), timeoutMs);
+ if (tid && typeof (tid as any).unref === 'function') (tid as any).unref();
+ }),
+ ]);
duration = Date.now() - start;
} catch (err: any) {
resultText = `ERROR: ${err.message}`;
diff --git a/src/gateway/heartbeat-runner.ts b/src/gateway/heartbeat-runner.ts
index d37d6ac..ad33157 100644
--- a/src/gateway/heartbeat-runner.ts
+++ b/src/gateway/heartbeat-runner.ts
@@ -15,6 +15,7 @@ export interface HeartbeatRunnerConfig {
intervalMinutes: number;
activeHoursStart: number;
activeHoursEnd: number;
+ notifyEnabled: boolean;
}
interface HeartbeatRunnerDeps {
@@ -52,6 +53,7 @@ export class HeartbeatRunner {
intervalMinutes: 30,
activeHoursStart: 8,
activeHoursEnd: 22,
+ notifyEnabled: true,
};
}
@@ -71,6 +73,7 @@ export class HeartbeatRunner {
activeHoursEnd: Number.isFinite(Number(parsed?.activeHoursEnd))
? Math.max(0, Math.min(23, Math.floor(Number(parsed.activeHoursEnd))))
: base.activeHoursEnd,
+ notifyEnabled: typeof parsed?.notifyEnabled === 'boolean' ? parsed.notifyEnabled : base.notifyEnabled,
};
} catch {
return this.defaultConfig();
@@ -225,15 +228,18 @@ export class HeartbeatRunner {
);
const text = String(result?.text || '');
const isOk = /^\s*HEARTBEAT_OK\s*$/i.test(text);
+ const cfg = this.getConfig();
if (!isOk && text.trim()) {
- this.deps.broadcast?.({
- type: 'heartbeat_result',
- sessionId,
- text: text.slice(0, 8000),
- at: Date.now(),
- });
- if (this.deps.deliverTelegram) {
- this.deps.deliverTelegram(`🫀 Heartbeat\n\n${text}`).catch(() => {});
+ if (cfg.notifyEnabled) {
+ this.deps.broadcast?.({
+ type: 'heartbeat_result',
+ sessionId,
+ text: text.slice(0, 8000),
+ at: Date.now(),
+ });
+ if (this.deps.deliverTelegram) {
+ this.deps.deliverTelegram(`🫀 Heartbeat\n\n${text}`).catch(() => {});
+ }
}
}
} catch (err: any) {
diff --git a/src/gateway/server-v2.ts b/src/gateway/server-v2.ts
index 9ea5737..3998e85 100644
--- a/src/gateway/server-v2.ts
+++ b/src/gateway/server-v2.ts
@@ -538,8 +538,19 @@ function setOrchestrationEnabled(enabled: boolean): void {
// Critical for 4B models — can't handle parallel inference.
let isModelBusy = false;
+let isModelBusySince = 0;
+const IS_MODEL_BUSY_STALE_MS = 10 * 60 * 1000; // 10 minutes
let lastMainSessionId = 'default';
+function checkIsModelBusy(): boolean {
+ if (isModelBusy && isModelBusySince > 0 && Date.now() - isModelBusySince > IS_MODEL_BUSY_STALE_MS) {
+ console.warn('[Server] isModelBusy has been true for over 10 minutes, force-clearing');
+ isModelBusy = false;
+ isModelBusySince = 0;
+ }
+ return isModelBusy;
+}
+
// wss is assigned after server creation below; broadcastWS is only ever called
// after startup (by cron ticks), so the late assignment is safe.
@@ -665,7 +676,7 @@ const cronScheduler = new CronScheduler({
handleChat: (message, sessionId, sendSSE, pinnedMessages, abortSignal, callerContext, modelOverride, executionMode, username) =>
handleChat(message, sessionId, sendSSE, pinnedMessages, abortSignal, callerContext, modelOverride, executionMode, username),
broadcast: broadcastWS,
- getIsModelBusy: () => isModelBusy,
+ getIsModelBusy: () => checkIsModelBusy(),
deliverTelegram: (text: string) => telegramChannel.sendToAllowed(text),
getMainSessionId: () => lastMainSessionId || 'default',
injectSystemEvent: (sessionId, text, job) => {
@@ -770,7 +781,7 @@ const telegramChannel = new TelegramChannel(
handleChat: (message, sessionId, sendSSE, pinnedMessages, abortSignal, callerContext, modelOverride, executionMode, username) =>
handleChat(message, sessionId, sendSSE, pinnedMessages, abortSignal, callerContext, modelOverride, executionMode, username),
addMessage,
- getIsModelBusy: () => isModelBusy,
+ getIsModelBusy: () => checkIsModelBusy(),
broadcast: broadcastWS,
}
);
@@ -781,7 +792,7 @@ const heartbeatRunner = new HeartbeatRunner({
handleChat: (message, sessionId, sendSSE, pinnedMessages, abortSignal, callerContext, modelOverride, executionMode, username) =>
handleChat(message, sessionId, sendSSE, pinnedMessages, abortSignal, callerContext, modelOverride, executionMode, username),
getMainSessionId: () => lastMainSessionId || 'default',
- getIsModelBusy: () => isModelBusy,
+ getIsModelBusy: () => checkIsModelBusy(),
broadcast: broadcastWS,
deliverTelegram: (text: string) => telegramChannel.sendToAllowed(text),
});
@@ -4090,7 +4101,10 @@ async function handleChat(
const sessionWorkspace = getWorkspace(sessionId, username);
// Session workspace (user-specific) takes priority over global configured workspace
// so that multi-user file tools (read_file, etc.) resolve to the correct user directory.
- const workspacePath = sessionWorkspace || configuredWorkspace;
+ // For background tasks with a known username, auto-resolve to the user workspace so
+ // list_files/read_file don't fall back to the non-existent global workspace directory.
+ const userWorkspace = username ? getUserWorkspace(username) : null;
+ const workspacePath = sessionWorkspace || userWorkspace || configuredWorkspace;
if (workspacePath && sessionWorkspace !== workspacePath) {
setWorkspace(sessionId, workspacePath, username);
}
@@ -4482,7 +4496,8 @@ async function handleChat(
const messages: any[] = [
{
role: 'system',
- content: `${executionModeSystemBlock ? `${executionModeSystemBlock}\n\n` : ''}You are SmallClaw 🦞, a local AI assistant.\nCurrent date: ${dateStr}, ${timeStr}.\nNever search for or link SmallClaw repos unless the user is asking about SmallClaw itself.\nThis app runs on the user's own machine — browser/desktop automation requests are pre-authorized.\nKeep responses SHORT (1-2 sentences). Don't think out loud. Act and report. Greet naturally without tools.${callerContext ? '\n\n' + callerContext : ''}${browserStateCtx}${personalityCtx}${skillsManager.buildPromptContext(500)}${workflowCtx ? '\n\n' + workflowCtx : ''}`,
+ content: `${executionModeSystemBlock ? `${executionModeSystemBlock}\n\n` : ''}You are SmallClaw 🦞, a local AI assistant.\nCurrent date: ${dateStr}, ${timeStr}.\nNever search for or link SmallClaw repos unless the user is asking about SmallClaw itself.\nThis app runs on the user's own machine — browser/desktop automation requests are pre-authorized.\nKeep responses SHORT (1-2 sentences). Don't think out loud. Act and report. Greet naturally without tools.
+ANTI-HALLUCINATION: When a tool returns a result, report EXACTLY what the tool returned — never contradict or ignore tool output. If a tool says "(no rows)", say so. Never invent data, file contents, table names, or command output. If you don't know something, call a tool to find out or say you don't know.${callerContext ? '\n\n' + callerContext : ''}${browserStateCtx}${personalityCtx}${skillsManager.buildPromptContext(500)}${workflowCtx ? '\n\n' + workflowCtx : ''}`,
},
];
@@ -6555,44 +6570,30 @@ RULES:
if (toolName === 'start_task') {
const taskGoal = toolArgs.goal || message;
- const maxSteps = toolArgs.max_steps || 50;
- sendSSE('info', { message: `Starting multi-step task: ${taskGoal}` });
-
- const taskTools = tools.filter((t: any) => t.function.name !== 'start_task') as any[];
-
- const taskResult = await runTask({
- goal: taskGoal,
- tools: taskTools,
- executor: async (name, args) => {
- const r = await executeTool(name, args, workspacePath, sessionId, undefined, username);
- return { result: r.result, error: r.error };
- },
- onProgress: sendSSE,
- systemContext: personalityCtx.slice(0, 500),
- maxSteps,
+ const taskTitle = String(toolArgs.title || taskGoal).slice(0, 120);
+ const taskChannel = inferTaskChannelFromSession(sessionId);
+ const parsedTelegramChatId = taskChannel === 'telegram'
+ ? Number(String(sessionId || '').replace(/^telegram_/, ''))
+ : NaN;
+ const telegramChatId = Number.isFinite(parsedTelegramChatId) && parsedTelegramChatId > 0
+ ? parsedTelegramChatId
+ : undefined;
+ const task = createTask({
+ title: taskTitle,
+ prompt: taskGoal,
+ sessionId,
+ channel: taskChannel,
+ telegramChatId,
+ plan: [{ index: 0, description: taskGoal, status: 'pending' }],
});
-
- activeTasks.set(sessionId, taskResult);
-
- const summary = taskResult.status === 'complete'
- ? `Task completed in ${taskResult.currentStep} steps!`
- : taskResult.status === 'failed'
- ? `Task failed at step ${taskResult.currentStep}: ${taskResult.error}`
- : `Task paused at step ${taskResult.currentStep}/${taskResult.maxSteps}`;
-
- const journalSummary = taskResult.journal.slice(-5).map(j => j.result).join('\n');
-
- return {
- type: 'execute',
- text: `${summary}\n\nRecent steps:\n${journalSummary}`,
- thinking: allThinking || undefined,
- toolResults: taskResult.journal.map(j => ({
- name: j.action.split('(')[0],
- args: {},
- result: j.result,
- error: j.result.startsWith('❌'),
- })),
- };
+ appendJournal(task.id, { type: 'status_push', content: `Task queued: ${taskTitle}` });
+ const runner = new BackgroundTaskRunner(task.id, handleChat, makeBroadcastForTask(task.id), telegramChannel);
+ runner.start().catch(err => console.error(`[BackgroundTaskRunner] Task ${task.id} error:`, err.message));
+ const queuedMessage = `On it! I've queued "${taskTitle}" as a background task. You can track progress in the Tasks panel.`;
+ sendSSE('task_queued', { taskId: task.id, title: taskTitle });
+ logToDaily(workspacePath, 'SmallClaw', queuedMessage, sessionId);
+ addMessage(sessionId, { role: 'assistant', content: queuedMessage, timestamp: Date.now() }, {}, username);
+ return { type: 'chat', text: queuedMessage };
}
if (toolName === 'delegate_to_specialist' || toolName === 'subagent_spawn') {
@@ -8330,6 +8331,7 @@ app.post('/api/chat', async (req, res) => {
const heartbeat = setInterval(() => sendSSE('heartbeat', { state: 'processing' }), 5000);
isModelBusy = true;
+ isModelBusySince = Date.now();
const abortSignal = { aborted: false };
let requestCompleted = false;
@@ -8438,6 +8440,7 @@ app.post('/api/chat', async (req, res) => {
requestCompleted = true;
clearInterval(heartbeat);
isModelBusy = false; // release busy guard — cron scheduler may now run
+ isModelBusySince = 0;
res.end();
}
});
@@ -9115,17 +9118,24 @@ let taskHeartbeatTimer: ReturnType | null = null;
// Per-task followup timers — fired when a step completes to resume quickly
// instead of waiting the full heartbeat interval.
const taskFollowupTimers = new Map>();
+const MAX_FOLLOWUP_RETRIES = 20;
-function scheduleTaskFollowup(taskId: string, delayMs: number): void {
+function scheduleTaskFollowup(taskId: string, delayMs: number, retryCount = 0): void {
// Cancel any existing followup for this task
const existing = taskFollowupTimers.get(taskId);
if (existing) clearTimeout(existing);
console.log(`[TaskFollowup] Scheduling quick resume for task ${taskId} in ${Math.round(delayMs / 1000)}s`);
const t = setTimeout(async () => {
taskFollowupTimers.delete(taskId);
- if (isModelBusy) {
- // Retry in 30s if model is busy
- scheduleTaskFollowup(taskId, 30_000);
+ if (checkIsModelBusy()) {
+ // Retry in 30s if model is busy, but cap retries
+ if (retryCount >= MAX_FOLLOWUP_RETRIES) {
+ console.warn(`[TaskFollowup] Max retries (${MAX_FOLLOWUP_RETRIES}) reached for task ${taskId}, marking stalled`);
+ updateTaskStatus(taskId, 'stalled', { pauseReason: 'followup_timeout' });
+ broadcastWS({ type: 'task_stalled', taskId, reason: 'followup_timeout' });
+ return;
+ }
+ scheduleTaskFollowup(taskId, 30_000, retryCount + 1);
return;
}
const task = loadTask(taskId);
@@ -9168,10 +9178,27 @@ function scheduleTaskHeartbeat(): void {
}
async function runTaskHeartbeat(): Promise {
- if (isModelBusy) {
+ if (checkIsModelBusy()) {
scheduleTaskHeartbeat();
return;
}
+
+ // ── Ghost runner detection ──
+ // Tasks stuck in 'running' but with no active runner for > 5 minutes
+ const GHOST_RUNNER_TIMEOUT_MS = 5 * 60 * 1000;
+ const allTasks = listTasks();
+ for (const task of allTasks) {
+ if (task.status === 'running' && !BackgroundTaskRunner.isRunning(task.id)) {
+ const age = Date.now() - (task.lastProgressAt || task.startedAt);
+ if (age > GHOST_RUNNER_TIMEOUT_MS) {
+ console.warn(`[TaskHeartbeat] Ghost runner detected: task ${task.id} (${task.title}), stale ${Math.round(age / 1000)}s`);
+ BackgroundTaskRunner.forceRelease(task.id);
+ updateTaskStatus(task.id, 'stalled', { pauseReason: 'ghost_runner' });
+ broadcastWS({ type: 'task_stalled', taskId: task.id, reason: 'ghost_runner' });
+ }
+ }
+ }
+
const orchCfg = getOrchestrationConfig();
if (!orchCfg?.enabled) {
scheduleTaskHeartbeat();
@@ -10808,7 +10835,7 @@ app.get('/api/mcp/tools', (_req, res) => {
handleChat: (message, sessionId, sendSSE, pinnedMessages, abortSignal, callerContext, modelOverride, executionMode, username) =>
handleChat(message, sessionId, sendSSE, pinnedMessages, abortSignal, callerContext, modelOverride, executionMode, username),
addMessage,
- getIsModelBusy: () => isModelBusy,
+ getIsModelBusy: () => checkIsModelBusy(),
broadcast: broadcastWS,
deliverTelegram: (text: string) => telegramChannel.sendToAllowed(text),
});
diff --git a/src/gateway/task-store.ts b/src/gateway/task-store.ts
index 6e5e85e..db4d2d5 100644
--- a/src/gateway/task-store.ts
+++ b/src/gateway/task-store.ts
@@ -30,7 +30,10 @@ export type PauseReason =
| 'user_pause'
| 'error'
| 'max_steps'
- | 'interrupted_by_schedule';
+ | 'max_rounds_reached'
+ | 'interrupted_by_schedule'
+ | 'ghost_runner'
+ | 'followup_timeout';
export type JournalEntryType =
| 'tool_call'
diff --git a/src/providers/factory.ts b/src/providers/factory.ts
index 88187e8..d7a4590 100644
--- a/src/providers/factory.ts
+++ b/src/providers/factory.ts
@@ -166,9 +166,16 @@ function resolveEnvKey(value: string | undefined): string | undefined {
}
/** Convenience: get the active model name for a given role. */
-export function getModelForRole(role: 'manager' | 'executor' | 'verifier'): string {
+export function getModelForRole(role: 'manager' | 'executor' | 'verifier' | 'background_task'): string {
const raw = getConfig().getConfig() as any;
+ // background_task role: use dedicated model if set, otherwise fall through
+ if (role === 'background_task') {
+ const bgModel = String(raw.models?.roles?.background_task || '').trim();
+ if (bgModel) return bgModel;
+ // Fall through to primary model
+ }
+
// New-style per-provider model
const { active, providers } = getProviderConfig();
const providerCfg = providers[active] || {};
diff --git a/src/tools/sqlite.ts b/src/tools/sqlite.ts
index f7d8b7d..e5f57d2 100644
--- a/src/tools/sqlite.ts
+++ b/src/tools/sqlite.ts
@@ -58,7 +58,7 @@ export const sqliteTool = {
if (!dbPath) return { success: false, error: 'db_path is required' };
if (!query) return { success: false, error: 'query is required' };
- const workspacePath = getWorkspacePath();
+ const workspacePath = String(args?._workspacePath || args?._workspace || '') || getWorkspacePath();
const resolved = path.isAbsolute(dbPath) ? dbPath : path.resolve(workspacePath, dbPath);
if (!isPathInsideDir(workspacePath, resolved)) {
diff --git a/src/types.ts b/src/types.ts
index 4719521..35bb01e 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -2,7 +2,7 @@
export type JobStatus = 'queued' | 'planning' | 'executing' | 'verifying' | 'completed' | 'failed' | 'needs_approval';
export type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'failed';
-export type AgentRole = 'manager' | 'executor' | 'verifier';
+export type AgentRole = 'manager' | 'executor' | 'verifier' | 'background_task';
export type VerificationStatus = 'approved' | 'rejected' | 'needs_approval';
export interface Job {
@@ -262,6 +262,7 @@ export interface SmallClawConfig {
manager: string;
executor: string;
verifier: string;
+ background_task?: string;
};
};
tools: {
diff --git a/web-ui/index.html b/web-ui/index.html
index 8d0fece..588049c 100644
--- a/web-ui/index.html
+++ b/web-ui/index.html
@@ -3418,6 +3418,7 @@
+
@@ -3432,6 +3433,10 @@
미설정
+
+
+ 미설정
+
@@ -3480,6 +3485,60 @@
+
+
+
+
계정 추가 / 수정
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
허트비트 알림
+
+
+
+
@@ -3513,6 +3572,14 @@
4. Add a test recipient number in E.164 format.
5. Click Test, Save, then Send Test.
+
+ Email 계정 설정
+ 1. IMAP/SMTP 서버 주소와 포트를 입력하세요.
+ 2. 일반적인 포트: IMAP=993(TLS), SMTP=587(STARTTLS) 또는 465(SSL).
+ 3. Gmail은 앱 비밀번호 사용 (imap.gmail.com / smtp.gmail.com).
+ 4. 저장 후 테스트 버튼으로 IMAP 연결을 확인하세요.
+ 5. 여러 계정을 추가하면 email_list에서 모든 계정을 순회합니다.
+