@loicngr/kobo 1.8.4 → 1.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +24 -60
- package/dist/mcp-server/kobo-tasks-handlers.js +18 -0
- package/dist/mcp-server/kobo-tasks-server.js +458 -297
- package/dist/server/db/migrations.js +16 -0
- package/dist/server/db/schema.js +1 -0
- package/dist/server/routes/workspaces.js +2 -1
- package/dist/server/services/auto-loop-service.js +17 -4
- package/dist/server/services/forge/types.js +9 -4
- package/dist/shared/codex-models.js +27 -3
- package/package.json +6 -2
- package/src/client/dist/spa/assets/{ActivityFeed-B-N-w5Rb.js → ActivityFeed-Cru3Y4vS.js} +1 -1
- package/src/client/dist/spa/assets/{ChangelogPage-zx7lCp-x.js → ChangelogPage-Bg-DDspc.js} +1 -1
- package/src/client/dist/spa/assets/{ClosePopup-BRpX_Dln.js → ClosePopup-HRef5kSi.js} +1 -1
- package/src/client/dist/spa/assets/CreatePage-C-2rBnTd.css +1 -0
- package/src/client/dist/spa/assets/CreatePage-DqZTSsVk.js +2 -0
- package/src/client/dist/spa/assets/DiffViewer-D_yY4zph.js +8 -0
- package/src/client/dist/spa/assets/{HealthPage-CPrkYvOa.js → HealthPage-DuOcnPX7.js} +1 -1
- package/src/client/dist/spa/assets/{MainLayout-kiLQknmc.js → MainLayout-C4VC4R3n.js} +3 -3
- package/src/client/dist/spa/assets/QBtnGroup-CLMT4pWA.js +1 -0
- package/src/client/dist/spa/assets/QBtnToggle-Bnfx8-LH.js +1 -0
- package/src/client/dist/spa/assets/{QChip-FwfgX3I-.js → QChip-UP-CYKPe.js} +1 -1
- package/src/client/dist/spa/assets/{QExpansionItem-p5lig24k.js → QExpansionItem-BGl-iIpb.js} +1 -1
- package/src/client/dist/spa/assets/{QScrollArea-BrHNtdCG.js → QScrollArea-BsnAIb_6.js} +1 -1
- package/src/client/dist/spa/assets/{QSelect-BUGbllmy.js → QSelect-DHWr1DWW.js} +1 -1
- package/src/client/dist/spa/assets/{QTooltip-BD9D1HVa.js → QTooltip-1Cqe-wzt.js} +1 -1
- package/src/client/dist/spa/assets/{SearchPage-Dwi-Xlgl.js → SearchPage-CQ_Rw4cC.js} +1 -1
- package/src/client/dist/spa/assets/{SettingsPage-2jpbUouh.js → SettingsPage-Xt75bNBF.js} +1 -1
- package/src/client/dist/spa/assets/{TouchPan-DupH8iiT.js → TouchPan-8v88x-k5.js} +1 -1
- package/src/client/dist/spa/assets/{WorkspacePage-RQM3Id33.js → WorkspacePage-n6XL6ra6.js} +3 -3
- package/src/client/dist/spa/assets/build-path-tree-CsEz_AvN.js +1 -0
- package/src/client/dist/spa/assets/{cssMode-B7C4cbyr.js → cssMode-DaW1C4P4.js} +1 -1
- package/src/client/dist/spa/assets/{documents-B4fS1AKZ.js → documents-DsG4t5fl.js} +1 -1
- package/src/client/dist/spa/assets/{editor.api2-BEDcOHdz.js → editor.api2-Bjz6ygpj.js} +1 -1
- package/src/client/dist/spa/assets/{editor.main-ds11Fcak.js → editor.main-CLBGHEET.js} +2 -2
- package/src/client/dist/spa/assets/{expand-template-CVyd1bxK.js → expand-template-BtZ2WHZx.js} +1 -1
- package/src/client/dist/spa/assets/{formatters-CJbAt2Mu.js → formatters-CzrIaq3v.js} +1 -1
- package/src/client/dist/spa/assets/{freemarker2-CsVyqCrh.js → freemarker2-CQz_-RAv.js} +1 -1
- package/src/client/dist/spa/assets/{handlebars-9TD9qTMp.js → handlebars-D3T_RE92.js} +1 -1
- package/src/client/dist/spa/assets/{html-B0pzvK6l.js → html-C19hlQ10.js} +1 -1
- package/src/client/dist/spa/assets/{htmlMode-BNHxBP74.js → htmlMode-CcKHMqav.js} +1 -1
- package/src/client/dist/spa/assets/i18n-gU9Nz2Dy.js +1 -0
- package/src/client/dist/spa/assets/{index-DRkpEFKl.js → index-C1u3FMCQ.js} +7 -7
- package/src/client/dist/spa/assets/{javascript-BnNLP9qT.js → javascript-BtbPTi_2.js} +1 -1
- package/src/client/dist/spa/assets/{jsonMode-B296XtvX.js → jsonMode-M6yQyl3x.js} +1 -1
- package/src/client/dist/spa/assets/{kobo-commands-BW_aGHfH.js → kobo-commands-CRSnRjVe.js} +1 -1
- package/src/client/dist/spa/assets/{layout-DaXKrWc-.js → layout-CGI1vMRN.js} +1 -1
- package/src/client/dist/spa/assets/{liquid-Ct1nP3ps.js → liquid-DhD-glYJ.js} +1 -1
- package/src/client/dist/spa/assets/{lspLanguageFeatures-BVnfMLUC.js → lspLanguageFeatures-DsxRGZID.js} +1 -1
- package/src/client/dist/spa/assets/{mdx-BYShqwXi.js → mdx-BQKAfE4m.js} +1 -1
- package/src/client/dist/spa/assets/{monaco.contribution-BqpwqnRw.js → monaco.contribution-BxeTJn7e.js} +2 -2
- package/src/client/dist/spa/assets/{network-auth-BaLDs74-.js → network-auth-ClL9UkXB.js} +1 -1
- package/src/client/dist/spa/assets/permissionModes-DKmBv8m2.js +1 -0
- package/src/client/dist/spa/assets/{project-color-C1cADhCz.js → project-color-hgkIRO39.js} +1 -1
- package/src/client/dist/spa/assets/{python-DOG2VwjV.js → python-7eduqhxd.js} +1 -1
- package/src/client/dist/spa/assets/{razor-CWtKYbeq.js → razor-DsfMRZhn.js} +1 -1
- package/src/client/dist/spa/assets/{render-chat-markdown-Bxde8duq.js → render-chat-markdown-jyoLsnBV.js} +18 -18
- package/src/client/dist/spa/assets/{tsMode-JdYs8yvB.js → tsMode-BBuJqcnA.js} +1 -1
- package/src/client/dist/spa/assets/{typescript-Pry6QqCJ.js → typescript-C1QMF4IF.js} +1 -1
- package/src/client/dist/spa/assets/{use-onboarding-CR5TvnD3.js → use-onboarding-CR4gkqI9.js} +1 -1
- package/src/client/dist/spa/assets/{use-quasar-Bs5QmJMV.js → use-quasar-B65SkvJp.js} +1 -1
- package/src/client/dist/spa/assets/{workers-C8y4UFZ9.js → workers-kAnE9Ph9.js} +1 -1
- package/src/client/dist/spa/assets/{xml-B1O2QccM.js → xml-DlrR7f2a.js} +1 -1
- package/src/client/dist/spa/assets/{yaml-BiayGfV2.js → yaml-CNExkyN_.js} +1 -1
- package/src/client/dist/spa/index.html +1 -1
- package/src/mcp-server/README.md +46 -1
- package/src/mcp-server/kobo-tasks-handlers.ts +37 -0
- package/src/mcp-server/kobo-tasks-server.ts +496 -328
- package/src/client/dist/spa/assets/CreatePage-CtdVnG5s.js +0 -2
- package/src/client/dist/spa/assets/CreatePage-Cyo8mr_a.css +0 -1
- package/src/client/dist/spa/assets/DiffViewer-CpJwmcJ9.js +0 -8
- package/src/client/dist/spa/assets/build-path-tree-Gmn_Ljbw.js +0 -1
- package/src/client/dist/spa/assets/i18n-CMH5j9Af.js +0 -1
- package/src/client/dist/spa/assets/permissionModes-CoMkeI-P.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,15 @@ All notable changes to Kōbō are documented here. The format is based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/). Each release is an `## <version>`
|
|
5
5
|
section — the in-app "What's new" dialog reads this file.
|
|
6
6
|
|
|
7
|
+
## 1.8.6
|
|
8
|
+
|
|
9
|
+
- feat: add auto-loop session modes and global MCP workspace tools
|
|
10
|
+
|
|
11
|
+
## 1.8.5
|
|
12
|
+
|
|
13
|
+
- feat: add gpt-5.6 codex model family and gpt-5.2 to catalogue
|
|
14
|
+
- docs: overhaul README and split contributor guide into CONTRIBUTING.md
|
|
15
|
+
|
|
7
16
|
## 1.8.4
|
|
8
17
|
|
|
9
18
|
- feat: add Claude Sonnet 5 to the model catalogue
|
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
Kōbō runs multiple coding agents in parallel, each isolated in its own git worktree, branch, and dev server. A single Vue dashboard streams output, tasks, git state, and quota usage across every workspace.
|
|
10
10
|
|
|
11
|
+

|
|
12
|
+
|
|
11
13
|
> [!NOTE]
|
|
12
14
|
> Active development on `develop`. Forward-only migrations and timestamped pre-migration backups keep upgrades safe.
|
|
13
15
|
|
|
@@ -15,16 +17,24 @@ Kōbō runs multiple coding agents in parallel, each isolated in its own git wor
|
|
|
15
17
|
|
|
16
18
|
- **Isolated worktrees**: each workspace is a dedicated git worktree on its own branch, so parallel sessions never collide.
|
|
17
19
|
- **Two agent engines**: Claude Code (via `@anthropic-ai/claude-agent-sdk`) and OpenAI Codex (via `codex app-server`), chosen per workspace.
|
|
18
|
-
- **Live chat**: streaming text, reasoning blocks, inline Edit/Write diffs, per-turn cards, infinite scrollback. `/` autocompletes skills and commands, `@` fuzzy-autocompletes worktree file paths, and you can export any workspace's session events to CSV.
|
|
19
|
-
- **
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
- **
|
|
20
|
+
- **Live chat**: streaming text, reasoning blocks, inline Edit/Write diffs, per-turn cards, a compaction-in-progress indicator, infinite scrollback. `/` autocompletes skills and commands, `@` fuzzy-autocompletes worktree file paths, and you can export any workspace's session events to CSV.
|
|
21
|
+
- **Full MCP toolset (`kobo-tasks`)**: a per-workspace MCP server the agent uses for far more than tasks — task/acceptance-criteria CRUD, starting/stopping the dev server and reading its logs, a unified `get_ticket` (Notion or Sentry), searching past conversations across every workspace, per-session token/cost usage, and a `.ai/thoughts` decision log. Native Claude Code Task tools complement it for lightweight sub-agent coordination. See [`AGENTS.md`](./AGENTS.md) for the full tool list.
|
|
22
|
+
|
|
23
|
+

|
|
24
|
+
- **Git panel**: a Monaco-based diff viewer with **inline file editing** (edit the right-hand panel directly, save with `Ctrl/Cmd+S`, conflict-guarded via sha precondition), inline conflict resolution, and `Sync` / `Push` / `Open PR` / `Change PR base` / `Change source branch`. Multi-forge: GitHub (`gh`), GitLab (`glab`), or no forge, auto-detected from the remote and overridable per project.
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+
- **Dev server panel**: start, stop, and tail logs for a workspace's dev server (Docker or npm) straight from the Tools panel — no need to leave the UI.
|
|
28
|
+
- **Attention indicators**: workspace cards surface CI failures, review-requested changes, and a conflict-aware **ready-to-merge** badge, plus a one-click **Fix CI** button that spawns a fix workspace automatically.
|
|
29
|
+
- **Interactive Q&A**: an agent can pause mid-session to ask a clarifying question through the UI; the workspace surfaces under "Needs Attention" until you answer.
|
|
30
|
+
|
|
31
|
+

|
|
32
|
+
- **Auto-loop**: an opt-in mode that walks the task list, spawning a fresh session per task and stopping once there's nothing left to do, progress stalls, an error occurs, or the agent needs input from you.
|
|
23
33
|
- **Quota-aware**: 5-hour / 7-day Claude usage and Codex rate-limit buckets sit in the footer, and sessions auto-resume after a rate-limit reset.
|
|
24
|
-
- **Scheduled wakeups**: the agent schedules a one-shot wake-up via the `
|
|
34
|
+
- **Scheduled wakeups**: the agent schedules a one-shot wake-up via the `schedule_wakeup` MCP tool. Kōbō persists it across restarts, shows a live countdown, and re-invokes the agent with the stored prompt at the chosen time.
|
|
25
35
|
- **Cron schedules**: recurring per-workspace triggers the agent registers through MCP tools (`cron_create` / `cron_delete` / `cron_list`). Each tick resumes the workspace session (skipped if already active), and schedules are re-armed at boot with skip-missed semantics.
|
|
26
|
-
- **Lifecycle scripts**: shell scripts run automatically at key moments
|
|
27
|
-
- **Disk-space purge**: free a merged workspace's disk space without losing its chat history
|
|
36
|
+
- **Lifecycle scripts**: shell scripts run automatically at key moments — **setup** (worktree created), **cleanup** (session ended), **archive** (workspace archived). Configure them globally or per project, with their output streamed into the chat.
|
|
37
|
+
- **Disk-space purge**: free a merged workspace's disk space without losing its chat history — see [below](#disk-space-purge).
|
|
28
38
|
- **Optional integrations**: Notion (import missions), Sentry (fix from issue URL), local voice transcription (whisper.cpp).
|
|
29
39
|
|
|
30
40
|
## Quick start
|
|
@@ -43,17 +53,7 @@ SERVER_PORT=9997 PORT=9998 npx @loicngr/kobo@latest
|
|
|
43
53
|
|
|
44
54
|
Open <http://localhost:3000> (or whichever port you picked). Data is persisted under `~/.config/kobo/` (override via `KOBO_HOME`).
|
|
45
55
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
git clone https://github.com/loicngr/Kobo.git
|
|
50
|
-
cd Kobo
|
|
51
|
-
npm install
|
|
52
|
-
(cd src/client && npm install)
|
|
53
|
-
npm run dev:all # backend :3300 + client :8080
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
A production-installed Kōbō (`npx @loicngr/kobo`) and a dev server can run side by side, since they use separate data directories.
|
|
56
|
+
Want to run from source or contribute? See [`CONTRIBUTING.md`](./CONTRIBUTING.md).
|
|
57
57
|
|
|
58
58
|
## Configuration
|
|
59
59
|
|
|
@@ -65,6 +65,7 @@ The most common knobs:
|
|
|
65
65
|
| `SERVER_PORT` | none | Preferred override for the server port; takes precedence over `PORT` |
|
|
66
66
|
| `KOBO_HOME` | `~/.config/kobo` | Data directory (SQLite, settings, voice models) |
|
|
67
67
|
| `NOTION_API_TOKEN` | none | Notion integration token |
|
|
68
|
+
| `ANTHROPIC_API_KEY` | none | Claude Code engine credential (alternative to `claude /login`) |
|
|
68
69
|
| `OPENAI_API_KEY` | none | Codex engine credential (alternative to `codex login`) |
|
|
69
70
|
|
|
70
71
|
Global and per-project settings (worktree path, dev server commands, E2E framework, prompt templates, git conventions, branch prefixes, lifecycle scripts, task prompt) are edited in **Settings** at runtime. Per-project values inherit from the global ones when left empty.
|
|
@@ -84,29 +85,8 @@ A merged workspace is automatically archived, but its worktree folder usually ca
|
|
|
84
85
|
|
|
85
86
|
- **Manual**: workspace context menu → *Free disk space (delete worktree)*. The worktree is removed; the chat history and PR metadata stay in the database.
|
|
86
87
|
- **Automatic**: **Settings → Worktrees → Auto-purge worktree on PR merged**. When the pr-watcher sees the OPEN → MERGED transition, it archives **and** purges.
|
|
87
|
-
- **Restore**: recreate the folder yourself (`gh pr checkout <pr>` or `git worktree add <path> <branch>`). The pr-watcher detects the directory reappearing within 30 seconds and re-activates the workspace automatically
|
|
88
|
-
|
|
89
|
-
### Avoiding permission errors during purge
|
|
90
|
-
|
|
91
|
-
Docker containers usually write as `root`, so files in `node_modules` / `vendor` end up root-owned on the host. Plain `rm -rf` (which Kōbō uses under the hood) then fails with `EACCES` / `EPERM`. Pick one of these strategies depending on your setup:
|
|
92
|
-
|
|
93
|
-
1. **Best: run your container as the host user.** Add a `USER` directive in your `Dockerfile`, or set `user: "${UID}:${GID}"` in `docker-compose.yml` with `UID`/`GID` exported in your shell. No more root-owned files, and nothing extra to do.
|
|
94
|
-
2. **Preventive ACL on the worktrees root.** On ext4 / btrfs / xfs with a regular Docker bind mount, a default ACL grants your user access to every file created later:
|
|
95
|
-
```bash
|
|
96
|
-
setfacl -d -m u:$(whoami):rwX <worktrees-root> # e.g. ~/.worktrees
|
|
97
|
-
```
|
|
98
|
-
Caveats: does **not** work on named Docker volumes (use a bind mount), filesystems without ACL support (NTFS, exFAT, tmpfs), strict SELinux with `:Z`, or with Docker `userns-remap`.
|
|
99
|
-
3. **Unblock an already-broken worktree** (existing root-owned files):
|
|
100
|
-
```bash
|
|
101
|
-
# Option A — recursive ACL (keeps ownership intact, just adds your user)
|
|
102
|
-
sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .
|
|
103
|
-
|
|
104
|
-
# Option B — take ownership outright (simpler, loses the "root-from-container" trace)
|
|
105
|
-
sudo chown -R $(whoami):$(whoami) .
|
|
106
|
-
```
|
|
107
|
-
Run from inside the worktree folder, or directly on your worktrees root (e.g. `~/.worktrees/`) to cover all existing and future workspaces at once.
|
|
108
|
-
|
|
109
|
-
When a purge does fail, Kōbō surfaces a toast with a copy-pasteable recovery command and a `git worktree prune` follow-up. The same guide is wired into **Settings → Worktrees → How purge works** for in-app reference.
|
|
88
|
+
- **Restore**: recreate the folder yourself (`gh pr checkout <pr>` or `git worktree add <path> <branch>`). The pr-watcher detects the directory reappearing within 30 seconds and re-activates the workspace automatically. No UI action needed.
|
|
89
|
+
- **Permission errors**: if removal hits `EACCES`/`EPERM` (common with Docker containers writing as `root`), Kōbō first tries to auto-recover by `chown`-ing the worktree from a throwaway Docker container. If that isn't possible, it shows a toast with a copy-pasteable manual recovery command. Full troubleshooting (ACL setup, Docker `USER` directive, manual `chown`) is in [`CONFIGURATION.md`](./CONFIGURATION.md#permission-errors-during-purge).
|
|
110
90
|
|
|
111
91
|
## Optional integrations
|
|
112
92
|
|
|
@@ -165,30 +145,14 @@ src/
|
|
|
165
145
|
├── client/ # Vue 3 + Quasar SPA
|
|
166
146
|
├── mcp-server/ # kobo-tasks MCP server, spawned per workspace
|
|
167
147
|
├── shared/ # types shared backend ↔ frontend
|
|
168
|
-
└── __tests__/ # Vitest suite
|
|
148
|
+
└── __tests__/ # Vitest suite, backend + client, thousands of tests
|
|
169
149
|
```
|
|
170
150
|
|
|
171
151
|
[`AGENTS.md`](./AGENTS.md) covers the data model, WebSocket protocol, engine contracts, MCP tool surface, migration discipline, i18n rules, and contribution guidelines.
|
|
172
152
|
|
|
173
|
-
## Scripts
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
npm run dev:all # backend (:3300) + client (:8080)
|
|
177
|
-
npm run build # production build (client + server)
|
|
178
|
-
npm start # run the compiled server
|
|
179
|
-
npm test # backend vitest suite
|
|
180
|
-
npm run test:client # client vitest suite
|
|
181
|
-
npm run lint # biome check (lint + format)
|
|
182
|
-
make ci # full CI pipeline (audit + lint + tsc + tests)
|
|
183
|
-
```
|
|
184
|
-
|
|
185
153
|
## Contributing
|
|
186
154
|
|
|
187
|
-
PRs welcome.
|
|
188
|
-
|
|
189
|
-
## Release
|
|
190
|
-
|
|
191
|
-
Releases are cut from `main`. Bump `package.json` on `develop`, merge into `main`, push. The release workflow builds, tests, publishes to npm, tags `v<version>`, and creates the GitHub Release. It fails early if the version or tag already exists.
|
|
155
|
+
PRs welcome. See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the from-source setup, scripts, and release process, and [`AGENTS.md`](./AGENTS.md) for code conventions and the database-migration discipline.
|
|
192
156
|
|
|
193
157
|
## License
|
|
194
158
|
|
|
@@ -22,6 +22,24 @@ export function listTasksHandler(db, workspaceId) {
|
|
|
22
22
|
.all(workspaceId);
|
|
23
23
|
return rows.map(rowToDto);
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* List workspaces for the global `list_workspaces` MCP tool. Reads SQLite
|
|
27
|
+
* directly (no backend HTTP dependency) so it works even when the Kōbō
|
|
28
|
+
* server isn't running — the same DB file the backend uses.
|
|
29
|
+
*/
|
|
30
|
+
export function listWorkspacesHandler(db, opts) {
|
|
31
|
+
// updated_at can collide at second resolution (e.g. bulk-seeded test data); rowid DESC breaks ties, most-recently-inserted first.
|
|
32
|
+
const sql = opts.includeArchived
|
|
33
|
+
? 'SELECT id, name, status, created_at FROM workspaces ORDER BY updated_at DESC, rowid DESC'
|
|
34
|
+
: 'SELECT id, name, status, created_at FROM workspaces WHERE archived_at IS NULL ORDER BY updated_at DESC, rowid DESC';
|
|
35
|
+
const rows = db.prepare(sql).all();
|
|
36
|
+
return rows.map((row) => ({
|
|
37
|
+
id: row.id,
|
|
38
|
+
title: row.name,
|
|
39
|
+
status: row.status,
|
|
40
|
+
createdAt: row.created_at,
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
25
43
|
/**
|
|
26
44
|
* Flip the workspace's `auto_loop_ready` flag. Called at the end of a
|
|
27
45
|
* `/kobo-prep-autoloop` grooming session to unlock the auto-loop toggle.
|