@loicngr/kobo 1.7.13 → 1.7.15
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 +25 -0
- package/README.md +81 -399
- package/dist/server/db/migrations.js +33 -0
- package/dist/server/index.js +21 -2
- package/dist/server/routes/changelog.js +47 -0
- package/dist/server/routes/export.js +71 -0
- package/dist/server/routes/fs.js +49 -0
- package/dist/server/routes/git.js +16 -1
- package/dist/server/routes/health.js +2 -1
- package/dist/server/routes/workspaces.js +107 -64
- package/dist/server/services/agent/orchestrator.js +10 -0
- package/dist/server/services/archive-script-service.js +65 -0
- package/dist/server/services/auto-loop-service.js +7 -0
- package/dist/server/services/cleanup-script-service.js +118 -0
- package/dist/server/services/settings-service.js +184 -2
- package/dist/server/services/setup-script-service.js +10 -81
- package/dist/server/utils/git-ops.js +30 -0
- package/dist/server/utils/paths.js +4 -0
- package/dist/server/utils/script-runner.js +96 -0
- package/package.json +2 -1
- package/src/client/dist/spa/assets/ActivityFeed-DU6lDEP0.js +8 -0
- package/src/client/dist/spa/assets/{ActivityFeed-WjiQ9716.css → ActivityFeed-yUMQhnW4.css} +1 -1
- package/src/client/dist/spa/assets/{ClosePopup-C5EF3QrA.js → ClosePopup-CxvZA3ft.js} +1 -1
- package/src/client/dist/spa/assets/CreatePage-CdZr7f3j.js +2 -0
- package/src/client/dist/spa/assets/CreatePage-DgHjL4cZ.css +1 -0
- package/src/client/dist/spa/assets/{DiffViewer-hWxcG22N.js → DiffViewer-m801GPfI.js} +3 -3
- package/src/client/dist/spa/assets/HealthPage-z1uIOpYk.js +1 -0
- package/src/client/dist/spa/assets/{MainLayout-Bp0oVWa-.css → MainLayout-BJmBXwYn.css} +1 -1
- package/src/client/dist/spa/assets/MainLayout-oJdQ-QKM.js +37 -0
- package/src/client/dist/spa/assets/{QBadge-u0mEz_W1.js → QBadge-NEwszYs7.js} +1 -1
- package/src/client/dist/spa/assets/QBanner-Jsq4uJZs.js +1 -0
- package/src/client/dist/spa/assets/QBtn-CoU-UC_j.js +1 -0
- package/src/client/dist/spa/assets/{QCheckbox-skYuqkHX.js → QCheckbox-Cq2STfHp.js} +1 -1
- package/src/client/dist/spa/assets/{QChip-DSMeriN6.js → QChip-DnJyQVs2.js} +2 -2
- package/src/client/dist/spa/assets/QExpansionItem-BTd5m2yV.js +1 -0
- package/src/client/dist/spa/assets/QIcon-BmEX2rXO.js +1 -0
- package/src/client/dist/spa/assets/QInput-D0t39uK_.js +1 -0
- package/src/client/dist/spa/assets/{QItemLabel-B0tYxHQg.js → QItemLabel-Btqw0P7M.js} +1 -1
- package/src/client/dist/spa/assets/QItemSection-DRg-QuAD.js +1 -0
- package/src/client/dist/spa/assets/QList-B3TuWSqL.js +1 -0
- package/src/client/dist/spa/assets/QMenu-C2Wwwf2E.js +1 -0
- package/src/client/dist/spa/assets/QPage-DO_bQyV_.js +1 -0
- package/src/client/dist/spa/assets/QRadio-M9mC5jZy.js +1 -0
- package/src/client/dist/spa/assets/QScrollArea-A1wI0IXU.js +1 -0
- package/src/client/dist/spa/assets/QSpace-DONPiIes.js +1 -0
- package/src/client/dist/spa/assets/{QSpinnerDots-CluOpUgq.js → QSpinnerDots-DspFKwCZ.js} +1 -1
- package/src/client/dist/spa/assets/{QToggle-aBvIHg6j.js → QToggle-DBzTAIbK.js} +1 -1
- package/src/client/dist/spa/assets/QTooltip-Bfdmzm_m.js +1 -0
- package/src/client/dist/spa/assets/SearchPage-ChmKHNKn.js +1 -0
- package/src/client/dist/spa/assets/SettingsPage-B59LoCos.js +9 -0
- package/src/client/dist/spa/assets/{SettingsPage-B_qPRSDH.css → SettingsPage-BJLyYrBN.css} +1 -1
- package/src/client/dist/spa/assets/{TouchPan-DPBZDRzA.js → TouchPan-BIE5rs7U.js} +1 -1
- package/src/client/dist/spa/assets/WorkspacePage-Bj1PJSWT.js +4 -0
- package/src/client/dist/spa/assets/WorkspacePage-tFBswKV9.css +1 -0
- package/src/client/dist/spa/assets/build-path-tree-BGUV3nY1.js +1 -0
- package/src/client/dist/spa/assets/{cssMode-DTibHxcy.js → cssMode-BU4X8R6a.js} +1 -1
- package/src/client/dist/spa/assets/documents-B3nitIYF.js +1 -0
- package/src/client/dist/spa/assets/{editor.api-CdLzoLLv.js → editor.api-B4xBDzmJ.js} +1 -1
- package/src/client/dist/spa/assets/{editor.main-DSLdinVQ.js → editor.main-CSZRkloL.js} +3 -3
- package/src/client/dist/spa/assets/engineFeatures-CLOVr5b4.js +1 -0
- package/src/client/dist/spa/assets/expand-template-BxUkuL5g.js +1 -0
- package/src/client/dist/spa/assets/{formatters-CgfY9uSI.js → formatters-9dcj2tyJ.js} +1 -1
- package/src/client/dist/spa/assets/{freemarker2-wf8G5c3b.js → freemarker2-DRz20wAV.js} +1 -1
- package/src/client/dist/spa/assets/{handlebars-BGPZbdOB.js → handlebars-C0dsvPnC.js} +1 -1
- package/src/client/dist/spa/assets/{html-DPEVCP74.js → html-Cqvj1pWs.js} +1 -1
- package/src/client/dist/spa/assets/{htmlMode-DMWUNRWz.js → htmlMode-BTHNvkm6.js} +1 -1
- package/src/client/dist/spa/assets/i18n-D1I-Us2H.js +1 -0
- package/src/client/dist/spa/assets/{index-5ydpLSpt.css → index-ClabzOPc.css} +1 -1
- package/src/client/dist/spa/assets/index-KABmOIkF.js +2 -0
- package/src/client/dist/spa/assets/{javascript-hOcrXbaP.js → javascript-C8n3U02v.js} +1 -1
- package/src/client/dist/spa/assets/{jsonMode-EeNIyfJU.js → jsonMode-C3AFxQ6K.js} +1 -1
- package/src/client/dist/spa/assets/{kobo-commands-Bh5k0Smw.js → kobo-commands-BuxgteGZ.js} +1 -1
- package/src/client/dist/spa/assets/{liquid-Cvw1gFPR.js → liquid-C4wtUDrJ.js} +1 -1
- package/src/client/dist/spa/assets/{mdx-CGtsv5px.js → mdx-CaT1p1F2.js} +1 -1
- package/src/client/dist/spa/assets/{monaco.contribution-RY1eW2u5.js → monaco.contribution-CJg5GKVf.js} +2 -2
- package/src/client/dist/spa/assets/notifications-BC6en6Lt.js +1 -0
- package/src/client/dist/spa/assets/permissionModes-BQHBTBwa.js +1 -0
- package/src/client/dist/spa/assets/{python-t0GNay3W.js → python-Cj54W2Tg.js} +1 -1
- package/src/client/dist/spa/assets/{razor-v9eEhqO6.js → razor-D3gJxoX_.js} +1 -1
- package/src/client/dist/spa/assets/render-chat-markdown-DxEHr3lW.js +60 -0
- package/src/client/dist/spa/assets/runtime-core.esm-bundler-D_RRiKBh.js +1 -0
- package/src/client/dist/spa/assets/{tsMode-B376_f_2.js → tsMode-B6S4PLWH.js} +1 -1
- package/src/client/dist/spa/assets/{typescript-WTvQ8gc0.js → typescript-Ca8AEX3t.js} +1 -1
- package/src/client/dist/spa/assets/use-checkbox-DnSuDqo2.js +1 -0
- package/src/client/dist/spa/assets/use-id-BCnfiBjU.js +1 -0
- package/src/client/dist/spa/assets/use-onboarding-B3l7mx48.css +1 -0
- package/src/client/dist/spa/assets/use-onboarding-CNeLPDtv.js +2 -0
- package/src/client/dist/spa/assets/use-quasar-k24tGxE-.js +1 -0
- package/src/client/dist/spa/assets/{vue-i18n-cyuEW5NY.js → vue-i18n-Cq-KgjJC.js} +2 -2
- package/src/client/dist/spa/assets/{xml-BMuHSj3C.js → xml-CsKo4k8C.js} +1 -1
- package/src/client/dist/spa/assets/{yaml-BRigOMm_.js → yaml-X5yKmi6z.js} +1 -1
- package/src/client/dist/spa/index.html +13 -13
- package/src/client/dist/spa/assets/ActivityFeed-CrlJXGsr.js +0 -8
- package/src/client/dist/spa/assets/CreatePage-B7DVVS0u.js +0 -2
- package/src/client/dist/spa/assets/CreatePage-ZyBHUbl0.css +0 -1
- package/src/client/dist/spa/assets/HealthPage-BP_TiWeV.js +0 -1
- package/src/client/dist/spa/assets/MainLayout-BRV8i-6o.js +0 -37
- package/src/client/dist/spa/assets/QBtn-CLU6snCm.js +0 -1
- package/src/client/dist/spa/assets/QExpansionItem-BFqbf9C7.js +0 -1
- package/src/client/dist/spa/assets/QIcon-0rjEivgj.js +0 -1
- package/src/client/dist/spa/assets/QInput-Ciqjq5-e.js +0 -1
- package/src/client/dist/spa/assets/QItemSection-DZnyqPM3.js +0 -1
- package/src/client/dist/spa/assets/QList-MfhZa-uv.js +0 -1
- package/src/client/dist/spa/assets/QMenu-Cx3v9_6z.js +0 -1
- package/src/client/dist/spa/assets/QPage-CGYPttdA.js +0 -1
- package/src/client/dist/spa/assets/QRadio-BEsMlsx1.js +0 -1
- package/src/client/dist/spa/assets/QSpace-BrtkvWzZ.js +0 -1
- package/src/client/dist/spa/assets/QTooltip-DdpeVKGV.js +0 -1
- package/src/client/dist/spa/assets/SearchPage-MfSrrMo1.js +0 -1
- package/src/client/dist/spa/assets/SettingsPage-CR3kXpHd.js +0 -9
- package/src/client/dist/spa/assets/WorkspacePage-B4YnZ6re.css +0 -1
- package/src/client/dist/spa/assets/WorkspacePage-DUKKBulA.js +0 -4
- package/src/client/dist/spa/assets/build-path-tree-DOtGuDWX.js +0 -1
- package/src/client/dist/spa/assets/documents-qOarUoMj.js +0 -1
- package/src/client/dist/spa/assets/engineFeatures-DNZNjYIf.js +0 -1
- package/src/client/dist/spa/assets/expand-template-Fy2sU7vj.js +0 -1
- package/src/client/dist/spa/assets/i18n-CUkOJRYM.js +0 -1
- package/src/client/dist/spa/assets/index-D9yyMIdQ.js +0 -2
- package/src/client/dist/spa/assets/notifications-BzyK_kYE.js +0 -1
- package/src/client/dist/spa/assets/permissionModes-BBA8zBcf.js +0 -1
- package/src/client/dist/spa/assets/project-color-d_h7ZYoM.js +0 -1
- package/src/client/dist/spa/assets/purify.es-CxaFgMzS.js +0 -60
- package/src/client/dist/spa/assets/render-chat-markdown-B41YA3kF.js +0 -1
- package/src/client/dist/spa/assets/runtime-core.esm-bundler-DPcTPMmX.js +0 -1
- package/src/client/dist/spa/assets/use-checkbox-DzLCp4E3.js +0 -1
- package/src/client/dist/spa/assets/use-id-BQW6DfJU.js +0 -1
- package/src/client/dist/spa/assets/use-quasar-C5gKpYwL.js +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Kōbō are documented here. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/). Each release is an `## <version>`
|
|
5
|
+
section — the in-app "What's new" dialog reads this file.
|
|
6
|
+
|
|
7
|
+
## 1.7.15
|
|
8
|
+
|
|
9
|
+
- docs: document new settings and features
|
|
10
|
+
- build(release): generate changelog section in version bump
|
|
11
|
+
- feat(onboarding): guided tour and what's-new dialog
|
|
12
|
+
- feat(settings): scripts, branch prefixes and project cards
|
|
13
|
+
- feat(workspaces): bulk-delete archived workspaces and fix flat sort
|
|
14
|
+
- feat(create): per-project task prompt template
|
|
15
|
+
- feat(health): show schema and settings migration versions
|
|
16
|
+
- feat(chat): dedicated script cards in the conversation feed
|
|
17
|
+
- feat(chat): @-mention file autocomplete with fuzzy matching
|
|
18
|
+
- feat(export): CSV export of workspace session events
|
|
19
|
+
- feat(server): lifecycle scripts, bulk delete and migration safety
|
|
20
|
+
|
|
21
|
+
## 1.7.14
|
|
22
|
+
|
|
23
|
+
- Show the Kōbō version in the Health page Environment card.
|
|
24
|
+
- Document the `SERVER_PORT` / `PORT` overrides and fix the default port.
|
|
25
|
+
- Split the configuration reference into a dedicated `CONFIGURATION.md`.
|
package/README.md
CHANGED
|
@@ -1,459 +1,141 @@
|
|
|
1
1
|
# Kōbō
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Multi-workspace orchestrator for [Claude Code](https://claude.com/claude-code) and [OpenAI Codex](https://developers.openai.com/codex/) agents.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@loicngr/kobo)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
[](https://nodejs.org/)
|
|
7
8
|
|
|
8
|
-
Kōbō
|
|
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.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
> [!NOTE]
|
|
12
|
+
> Active development on `develop`. Forward-only migrations and timestamped pre-migration backups keep upgrades safe.
|
|
11
13
|
|
|
12
14
|
## Features
|
|
13
15
|
|
|
14
|
-
- **Isolated
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
23
|
-
- **
|
|
24
|
-
- **
|
|
25
|
-
- **Pull request automation** — one-click `push`, `pull`, `open-pr`, and "change PR base" endpoints integrate with the GitHub CLI, using a configurable prompt template
|
|
26
|
-
- **Multi-session support** — create multiple Claude agent sessions per workspace, each with its own chat history; resume completed sessions via `--resume`; sessions are named and persisted in localStorage
|
|
27
|
-
- **Prompt templates** — personal library of reusable prompts with variable substitution (`{working_branch}`, `{commit_count}`, etc.), insertable from the chat input via `/` autocomplete; editable in Settings > Templates
|
|
28
|
-
- **Favorites and tags** — pin workspaces to the top via right-click favourite, organise with per-workspace tags filterable from the sidebar; a global tag catalogue keeps colours consistent across workspaces
|
|
29
|
-
- **Health panel + config export/import** — inspect backend health (agent sessions, migration state, dev servers, DB size) and roundtrip your Kōbō config (settings, templates, skills) between machines via JSON
|
|
30
|
-
- **Account-level quota panel** — a colored mini-bar badge in the chat footer shows the current Claude Code 5-hour and 7-day usage (Claude workspaces) or live Codex rate-limit buckets (Codex workspaces — driven by the structured `account/rateLimits/updated` app-server notification). Click to open a popover with full bars, reset times, a "Refresh now" button, and a one-click jump to the Stats tab. Pluggable per-provider, persisted in SQLite so the badge is populated on cold start, and account-level so it's the same across workspaces sharing the same engine
|
|
31
|
-
- **Resizable right drawer** — drag-to-resize horizontally and vertically, with tab state and split ratio persisted to localStorage
|
|
32
|
-
- **Soft interrupt** — pause an agent mid-execution (SIGINT, like pressing Escape in Claude Code) without killing the process; the agent stops the current tool and waits for the next message
|
|
33
|
-
- **Archive instead of delete** — soft-remove workspaces without losing the worktree, branches, or history; unarchive restores the exact pre-archive state
|
|
34
|
-
- **Auto-loop mode** — opt-in, per-workspace: when enabled, Kōbō spawns a fresh Claude session for the next pending task after every `session:ended`, walking through the task list until all are `done`. Stops automatically on error, on stall (3 consecutive sessions with no task completed), or when the user clicks Stop. A grooming step (`/kobo-prep-autoloop`) ensures tasks are atomic before the loop runs; Notion-imported workspaces with both todos and acceptance criteria are auto-unlocked. **E2E grooming** — when a project declares an E2E framework in Settings (Cypress, Playwright, Vitest, etc.), the grooming phase injects an `[E2E] ` test sub-task between every parent task; each iteration then runs the matching E2E suite as part of its acceptance check. **Sidebar progress chip** — auto-loop workspaces show an `X / Y tâches` badge in the workspace list, fed by the same task counts used by the in-page chip
|
|
35
|
-
- **Attach existing worktrees** — Kōbō detects orphan git worktrees for the selected project (created outside Kōbō, or left over from an earlier install) and lets you attach them to a new workspace from the creation form, picking up the existing branch and folder instead of cloning a new one
|
|
36
|
-
- **Persistent quota backoff** — when a Claude rate limit is hit mid-session, Kōbō schedules the retry at the actual reset time reported by the API (via `rate_limit.info.buckets[].resetsAt`), falling back to the OAuth usage poller, then to a 15 → 30 → 60 → 180 → 300 min ladder when both are missing. The pending backoff is **persisted in SQLite** and re-armed on server restart, so nothing is lost if the host reboots mid-window. A live banner counts down to the reset and lets the user cancel the wait. Only auto-loop workspaces resume automatically — others stay in `quota` status awaiting a manual nudge
|
|
37
|
-
- **Workspace description fields** — every workspace has TWO independent description fields. The user-side `description` is editable via the header input or right-click **Modifier la description**, and stays under the user's control (the agent cannot overwrite it). The agent maintains its own `agent_description` via the `set_workspace_agent_description` MCP tool to broadcast a live status (e.g. "Investigating SERVICE-1600 → enriching local Notion file"). Both are visible: the sidebar shows `agent_description` when set, falling back to the user `description`; the workspace header shows the user input plus an italic read-only line for the agent's current focus
|
|
38
|
-
- **Scheduled wakeups** — the `ScheduleWakeup` tool is honoured server-side: Kōbō persists the wakeup in SQLite, rehydrates on restart, and respawns the agent with `--resume` at the target time. Delay is clamped to `[60s, 6h]`. The kobo-tasks MCP server also exposes `kobo__schedule_wakeup` / `kobo__cancel_wakeup` for the same flow with first-class tool descriptors
|
|
39
|
-
- **Recurring & one-shot crons** — agents schedule recurring triggers via `kobo__cron_create(expression, prompt, label?, mode?, oneShot?)`. Standard 5-field cron expressions (`*/30 * * * *`) plus helpers (`@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`). Two modes: `'resume'` (default) pins the cron to the session that scheduled it so each fire continues that conversation; `'fresh'` spawns a brand-new session per fire (clean context, ideal for periodic CI / dashboard checks). `oneShot: true` cancels the cron after the first real fire — useful for "trigger once at a specific date/time" without recurring. Crons are persisted in SQLite, re-armed on restart with skip-missed semantics (no catchup spam after downtime), and skip-if-active when a session is already running. Multiple crons per workspace. The native Claude Code `CronCreate` tool is also intercepted and mirrored as a kobo cron so even agents using the SDK-default tool benefit from persistence
|
|
40
|
-
- **Schedule panel in the right drawer** — dedicated tab listing every wakeup and cron currently armed for the focused workspace, with their next/last fire times, prompt preview, and a `×` button to cancel inline. Sidebar workspace cards display an `event_repeat` icon when one or more crons are scheduled, even for workspaces not currently focused — broadcast live via WebSocket events
|
|
41
|
-
|
|
42
|
-
## Tech stack
|
|
43
|
-
|
|
44
|
-
- **Backend** — Node.js ≥ 20, [Hono](https://hono.dev/), [better-sqlite3](https://github.com/WiseLibs/better-sqlite3), [ws](https://github.com/websockets/ws), [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
45
|
-
- **Frontend** — [Vue 3](https://vuejs.org/), [Quasar 2](https://quasar.dev/), [Pinia](https://pinia.vuejs.org/), `vue-router`, [Monaco Editor](https://microsoft.github.io/monaco-editor/) (git diff viewer), `marked` + `dompurify` (markdown rendering)
|
|
46
|
-
- **Tooling** — TypeScript, [Vitest](https://vitest.dev/), [Biome](https://biomejs.dev/) (lint + format), `tsx` for dev
|
|
47
|
-
- **Storage** — single SQLite file (`~/.config/kobo/kobo.db` by default, overridable via `KOBO_HOME`) with WAL mode and forward-only migrations
|
|
16
|
+
- **Isolated worktrees** — each workspace is a dedicated git worktree on its own branch; parallel sessions never collide.
|
|
17
|
+
- **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 & commands and `@` fuzzy-autocompletes worktree file paths; every workspace's session events are exportable to CSV.
|
|
19
|
+
- **Task tracking** — per-workspace MCP server (`kobo-tasks`) lets the agent manage its own tasks, acceptance criteria, and live status.
|
|
20
|
+
- **Git panel** — Monaco-based diff viewer, inline conflict resolution, `Sync` / `Push` / `Open PR` wired to the `gh` CLI.
|
|
21
|
+
- **Auto-loop** — opt-in mode that walks the task list, spawning a fresh session per task and stopping on completion, stall, or error.
|
|
22
|
+
- **Quota-aware** — 5-hour / 7-day Claude usage and Codex rate-limit buckets in the footer; sessions auto-resume after a rate-limit reset.
|
|
23
|
+
- **Scheduled wakeups** — the agent schedules a one-shot wake-up via the `ScheduleWakeup` tool; Kōbō persists it across restarts, shows a live countdown, and re-invokes the agent with the stored prompt at the chosen time.
|
|
24
|
+
- **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.
|
|
25
|
+
- **Lifecycle scripts** — shell scripts run automatically at key moments: **setup** (worktree created), **cleanup** (session ended), **archive** (workspace archived). Configured globally or per project, with their output streamed into the chat.
|
|
26
|
+
- **Optional integrations** — Notion (import missions), Sentry (fix from issue URL), local voice transcription (whisper.cpp).
|
|
48
27
|
|
|
49
28
|
## Quick start
|
|
50
29
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- Node.js ≥ 20
|
|
54
|
-
- At least one agent runtime, authenticated:
|
|
55
|
-
- [Claude Code](https://claude.com/claude-code) — `claude /login` once. The `claude` CLI is **no longer required at runtime** — Kōbō embeds the official [`@anthropic-ai/claude-agent-sdk`](https://github.com/anthropics/claude-agent-sdk-typescript), which reuses the same login.
|
|
56
|
-
- [OpenAI Codex](https://developers.openai.com/codex/) — `codex login` once, or export `OPENAI_API_KEY` in the env. See [OpenAI Codex integration](#openai-codex-integration). Workspaces pick an engine at creation time, so you only need to set up the one(s) you use.
|
|
57
|
-
- Git
|
|
58
|
-
- Optional: Docker (if you configure per-workspace dev servers)
|
|
59
|
-
- Optional: `gh` CLI (if you use the PR automation)
|
|
60
|
-
- Optional: a Notion integration token (only if you want to import workspace missions from Notion pages — see [Notion integration](#notion-integration))
|
|
61
|
-
- Optional: a Sentry auth token (only if you want to create fix workspaces from Sentry issue URLs — see [Sentry integration](#sentry-integration))
|
|
62
|
-
|
|
63
|
-
### Run via `npx` (recommended)
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
SERVER_PORT=9998 PORT=9999 npx @loicngr/kobo@latest
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
That's it. npm downloads the package, installs dependencies, starts the Kōbō server on the port you specified, and serves the web UI at `http://localhost:9999`. Data is persisted to `~/.config/kobo/` (overridable via `KOBO_HOME`).
|
|
70
|
-
|
|
71
|
-
On first launch Kōbō creates `~/.config/kobo/` if it doesn't exist. If you have not yet logged in to Claude Code (`claude /login`), the SDK will prompt for an `ANTHROPIC_API_KEY` instead — log in once to share the same authentication across Claude Code, the embedded SDK, and the quota poller.
|
|
72
|
-
|
|
73
|
-
### Run from source (contributors)
|
|
30
|
+
Requires Node.js ≥ 20 and a logged-in Claude Code **or** Codex CLI.
|
|
74
31
|
|
|
75
32
|
```bash
|
|
76
|
-
|
|
77
|
-
cd kobo
|
|
78
|
-
npm install
|
|
79
|
-
(cd src/client && npm install)
|
|
33
|
+
npx @loicngr/kobo@latest
|
|
80
34
|
```
|
|
81
35
|
|
|
82
|
-
|
|
36
|
+
Default port is `3000`. If you already run something on that port (or another Kōbō instance), pick your own — `SERVER_PORT` is read first, `PORT` is the fallback:
|
|
83
37
|
|
|
84
38
|
```bash
|
|
85
|
-
|
|
39
|
+
SERVER_PORT=9997 PORT=9998 npx @loicngr/kobo@latest
|
|
86
40
|
```
|
|
87
41
|
|
|
88
|
-
|
|
42
|
+
Open <http://localhost:3000> (or whichever port you picked). Data is persisted under `~/.config/kobo/` (override via `KOBO_HOME`).
|
|
89
43
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
To run them separately:
|
|
44
|
+
### From source
|
|
93
45
|
|
|
94
46
|
```bash
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
npm run build # builds client + server
|
|
103
|
-
npm start # runs the compiled server
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Test & lint
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
npm test # backend vitest suite (1200+ tests)
|
|
110
|
-
npm run test:client # client vitest suite (Pinia stores + pure utils, 230+ tests)
|
|
111
|
-
npm run test:all # backend + client suites
|
|
112
|
-
npm run lint # biome check (lint + format verification)
|
|
113
|
-
npm run lint:fix # biome check with safe auto-fixes
|
|
114
|
-
npm run format # biome format --write
|
|
115
|
-
npx tsc --noEmit # server type check
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Notion integration
|
|
119
|
-
|
|
120
|
-
Kōbō can pull the content of a Notion page (title, body, checklists) and turn it into tasks and acceptance criteria when you create a workspace. **This feature is opt-in and requires you to configure your own Notion credentials** — Kōbō does not ship an API key.
|
|
121
|
-
|
|
122
|
-
Under the hood, Kōbō spawns the official [`@notionhq/notion-mcp-server`](https://github.com/makenotion/notion-mcp-server) as a child process and talks to it over stdio using the Model Context Protocol. The package is fetched via `npx -y @notionhq/notion-mcp-server` the first time you trigger an import, so there is nothing to install manually — only a token to provide.
|
|
123
|
-
|
|
124
|
-
### Getting a Notion integration token
|
|
125
|
-
|
|
126
|
-
1. Go to <https://www.notion.so/profile/integrations> and create a new internal integration
|
|
127
|
-
2. Give it a name (e.g. `kobo`) and the capabilities you need (at minimum: *Read content*)
|
|
128
|
-
3. Copy the internal integration secret (format `ntn_...` or `secret_...`)
|
|
129
|
-
4. Open the Notion page you want to import, click **…** → **Connections** → **Add connection** → select your integration. Kōbō can only read pages that are explicitly shared with the integration.
|
|
130
|
-
|
|
131
|
-
### Giving the token to Kōbō
|
|
132
|
-
|
|
133
|
-
Kōbō reads the token from the first source available, in this order:
|
|
134
|
-
|
|
135
|
-
1. `NOTION_API_TOKEN` environment variable
|
|
136
|
-
2. `NOTION_TOKEN` environment variable
|
|
137
|
-
3. `~/.claude.json` — if you already have the Notion MCP configured for Claude Code, Kōbō reads the token from `mcpServers.notion.env.NOTION_TOKEN` (or `NOTION_API_TOKEN`). **This is the recommended setup** — one token configured once, shared by both Claude Code and Kōbō.
|
|
138
|
-
|
|
139
|
-
Example: configure Notion MCP in Claude Code (one-time setup that also unlocks Kōbō's Notion import):
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
claude mcp add notion -s user -e NOTION_TOKEN=ntn_your_token_here -- npx -y @notionhq/notion-mcp-server
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Or launch Kōbō with the token inline:
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
NOTION_API_TOKEN=ntn_your_token_here PORT=9999 npx @loicngr/kobo@latest
|
|
47
|
+
git clone https://github.com/loicngr/Kobo.git
|
|
48
|
+
cd Kobo
|
|
49
|
+
npm install
|
|
50
|
+
(cd src/client && npm install)
|
|
51
|
+
npm run dev:all # backend :3300 + client :8080
|
|
149
52
|
```
|
|
150
53
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
If you need to pin a specific version of the Notion MCP server, use a fork, or avoid `npx`, set these env vars before launching Kōbō:
|
|
154
|
-
|
|
155
|
-
- `NOTION_MCP_COMMAND` — the binary to run (default: `npx`)
|
|
156
|
-
- `NOTION_MCP_ARGS` — space-separated arguments (default: `-y @notionhq/notion-mcp-server`)
|
|
157
|
-
|
|
158
|
-
Without a valid token configured, the Notion import field in the workspace creation form will return an error when you click **Refresh** or submit a Notion URL — the rest of Kōbō (workspaces, agents, tasks, Git integration) keeps working independently.
|
|
159
|
-
|
|
160
|
-
## OpenAI Codex integration
|
|
161
|
-
|
|
162
|
-
> [!WARNING]
|
|
163
|
-
> 🧪 **Experimental** — the Codex engine has shipped but is still maturing. The Claude Code engine remains the primary, battle-tested path. Expect occasional rough edges on Codex-only flows (tool rendering for less common item types, sub-agent interactions, edge cases around `collaborationMode` and approval prompts). Bugs and feedback welcome on the issue tracker.
|
|
164
|
-
|
|
165
|
-
Kōbō ships a second agent engine that runs on top of the official **OpenAI Codex** CLI. Pick `OpenAI Codex` in the engine selector when you create a workspace and the agent talks to the `codex` binary instead of Claude Code, with the same UI surface: streaming text, reasoning blocks, tool cards (Bash, Edit, Read, WebSearch, MCP tools, ImageGeneration), sub-agents (Codex's `collabAgentToolCall` family is mapped onto the same `Task` panel Claude's Task tool feeds), todo list, permission modes, interactive approvals, structured rate limits, auto-loop. **This feature is opt-in and requires you to authenticate the `codex` CLI separately from Claude Code** — Kōbō ships no OpenAI credentials.
|
|
166
|
-
|
|
167
|
-
Under the hood, Kōbō spawns a long-lived `codex app-server` subprocess per workspace and speaks the [Codex app-server JSON-RPC protocol](https://github.com/openai/codex/tree/main/codex-rs/app-server) over stdio. The `codex` binary is pulled in via the [`@openai/codex`](https://www.npmjs.com/package/@openai/codex) npm package, which is a direct dependency — no separate install required.
|
|
168
|
-
|
|
169
|
-
### Authenticating the Codex CLI
|
|
170
|
-
|
|
171
|
-
Two paths, pick one:
|
|
172
|
-
|
|
173
|
-
1. **`codex login` (recommended)** — run `codex login` once. The CLI writes a token to `~/.codex/auth.json` which Kōbō's spawned `codex app-server` reuses automatically:
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
codex login
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
2. **`OPENAI_API_KEY` env var** — set the variable before launching Kōbō:
|
|
180
|
-
|
|
181
|
-
```bash
|
|
182
|
-
OPENAI_API_KEY=sk-your-key-here PORT=9999 npx @loicngr/kobo@latest
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Kōbō does not store or proxy the key. If you change the credential or revoke it, Kōbō follows automatically on the next session start.
|
|
186
|
-
|
|
187
|
-
### Permission modes (Codex)
|
|
188
|
-
|
|
189
|
-
Kōbō's four permission modes (`plan` / `bypass` / `strict` / `interactive`) map to Codex's `sandbox` + `approvalPolicy` pair, plus a separate `collaborationMode` flag that gates interactive questions:
|
|
190
|
-
|
|
191
|
-
| Kōbō mode | Codex sandbox | Codex approvalPolicy | Codex collaborationMode | Effect |
|
|
192
|
-
|---|---|---|---|---|
|
|
193
|
-
| `plan` | `read-only` | `never` | `plan` | Read-only sandbox + the agent can ask interactive questions (`request_user_input`) |
|
|
194
|
-
| `bypass` | `workspace-write` | `never` | `default` | Full autonomy in the worktree, no approvals |
|
|
195
|
-
| `strict` | `workspace-write` | `on-request` | `default` | Writes allowed, approval prompted on sensitive commands |
|
|
196
|
-
| `interactive` | `workspace-write` | `unless-trusted` | `default` | Writes allowed, approval prompted on every untrusted action |
|
|
197
|
-
|
|
198
|
-
Interactive Q&A (`request_user_input`) is only available in `plan` — this is a constraint of Codex itself, not Kōbō. The typical workflow is: brainstorm in `plan` until the agent has the context it needs, then switch to `bypass`/`strict` for execution.
|
|
199
|
-
|
|
200
|
-
### Models and reasoning effort
|
|
201
|
-
|
|
202
|
-
The Codex engine exposes the OpenAI model catalogue (`gpt-5-codex`, `gpt-5.4`, `o4-mini`, `o3`) and the standard reasoning-effort scale (`auto` / `minimal` / `low` / `medium` / `high` / `xhigh`). Both selectors switch automatically when you flip the workspace's engine.
|
|
203
|
-
|
|
204
|
-
### Sub-agents
|
|
205
|
-
|
|
206
|
-
When the Codex agent uses its `spawnAgent` collab tool, Kōbō renders a **Task** card in the chat (like Claude's Task tool) and a live entry in the **SUB-AGENTS** panel of the right drawer — same plumbing the Claude engine uses. The same panel is hidden for engines that don't expose sub-agents.
|
|
54
|
+
A production-installed Kōbō (`npx @loicngr/kobo`) and a dev server can run side by side — they use separate data directories.
|
|
207
55
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
The `kobo-tasks` MCP server (and any other MCP server you configure on the workspace) is plumbed into Codex through the standard `config.mcp_servers` entry. Tool calls under those servers are pre-approved (`default_tools_approval_mode: 'auto'`) so the agent doesn't get blocked on every call.
|
|
211
|
-
|
|
212
|
-
### When the binary is missing
|
|
56
|
+
## Configuration
|
|
213
57
|
|
|
214
|
-
|
|
58
|
+
The most common knobs:
|
|
215
59
|
|
|
216
|
-
|
|
60
|
+
| Env var | Default | Purpose |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| `PORT` | `3000` | HTTP / WebSocket server port (overridden by `SERVER_PORT` if set) |
|
|
63
|
+
| `SERVER_PORT` | — | Preferred override for the server port; takes precedence over `PORT` |
|
|
64
|
+
| `KOBO_HOME` | `~/.config/kobo` | Data directory (SQLite, settings, voice models) |
|
|
65
|
+
| `NOTION_API_TOKEN` | — | Notion integration token |
|
|
66
|
+
| `OPENAI_API_KEY` | — | Codex engine credential (alternative to `codex login`) |
|
|
217
67
|
|
|
218
|
-
|
|
68
|
+
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.
|
|
219
69
|
|
|
220
|
-
|
|
221
|
-
- `CreatePage` (workspace instructions textarea)
|
|
70
|
+
The full reference — every env var, every setting key, MCP server registration, Notion / Sentry / Voice setup — is in [`CONFIGURATION.md`](./CONFIGURATION.md).
|
|
222
71
|
|
|
223
|
-
|
|
72
|
+
## Agent runtimes
|
|
224
73
|
|
|
225
|
-
- `
|
|
226
|
-
- `
|
|
227
|
-
- `cmake` (required to build `whisper.cpp` from source)
|
|
228
|
-
- At least one Whisper model downloaded from **Settings → Voice**
|
|
74
|
+
- **Claude Code.** Authenticate once with `claude /login`. Kōbō calls the embedded SDK directly — no `claude` binary required at runtime.
|
|
75
|
+
- **OpenAI Codex** (experimental). Run `codex login` or export `OPENAI_API_KEY`. Kōbō spawns a long-lived `codex app-server` subprocess per workspace and bridges its JSON-RPC stream to the same UI.
|
|
229
76
|
|
|
230
|
-
|
|
77
|
+
Engine selection happens at workspace creation. Both share the same task tracking, permission modes, sub-agent panel, and quota footer. The mapping of Kōbō's four permission modes (`plan` / `bypass` / `strict` / `interactive`) to each engine's native sandbox + approval semantics is in [`CONFIGURATION.md`](./CONFIGURATION.md#permission-modes).
|
|
231
78
|
|
|
232
|
-
|
|
233
|
-
git clone https://github.com/ggml-org/whisper.cpp.git
|
|
234
|
-
cd whisper.cpp
|
|
235
|
-
cmake -B build
|
|
236
|
-
cmake --build build -j
|
|
237
|
-
```
|
|
79
|
+
## Optional integrations
|
|
238
80
|
|
|
239
|
-
|
|
81
|
+
Kōbō ships first-class support for three external systems. All are opt-in and reuse credentials you may already have configured for Claude Code.
|
|
240
82
|
|
|
241
|
-
|
|
83
|
+
- **Notion** — import missions, tasks, and acceptance criteria from a Notion page.
|
|
84
|
+
- **Sentry** — paste an issue URL to spawn a fix workspace with the stacktrace, tags, and a TDD workflow.
|
|
85
|
+
- **Voice transcription** — local push-to-talk via [`whisper.cpp`](https://github.com/ggml-org/whisper.cpp).
|
|
242
86
|
|
|
243
|
-
|
|
87
|
+
See [`CONFIGURATION.md`](./CONFIGURATION.md) for the setup of each.
|
|
244
88
|
|
|
245
|
-
|
|
89
|
+
## Skill suites
|
|
246
90
|
|
|
247
|
-
|
|
248
|
-
sudo apt update
|
|
249
|
-
sudo apt install -y cmake build-essential ffmpeg
|
|
250
|
-
```
|
|
91
|
+
Kōbō's auto-generated prompts (review, auto-loop grooming, QA, brainstorming) can target four different skill ecosystems, selectable in **Settings → Skills**:
|
|
251
92
|
|
|
252
|
-
|
|
93
|
+
- **[superpowers](https://github.com/obra/superpowers)** (default) — plugin for Claude Code with the brainstorm → spec → plan → execute discipline, TDD, debugging, code review.
|
|
94
|
+
- **[gstack](https://github.com/garrytan/gstack)** — CLI slash commands for navigation, QA, design review, ship pipeline, second-opinion via Codex.
|
|
95
|
+
- **superpowers + gstack** — both, with each used for what it does best.
|
|
96
|
+
- **custom** — write your own prompts.
|
|
253
97
|
|
|
254
|
-
|
|
255
|
-
- Verify in PowerShell:
|
|
98
|
+
Optionally pair with **[gbrain](https://github.com/garrytan/gbrain)** — a per-project knowledge graph + semantic search exposed as an MCP server. Inherited automatically from your `~/.claude.json` config.
|
|
256
99
|
|
|
257
|
-
|
|
258
|
-
where ffmpeg
|
|
259
|
-
ffmpeg -version
|
|
260
|
-
```
|
|
100
|
+
Full install instructions and the prompt-suite differences are in [`CONFIGURATION.md`](./CONFIGURATION.md#skill-suites).
|
|
261
101
|
|
|
262
|
-
|
|
102
|
+
## Architecture
|
|
263
103
|
|
|
264
|
-
|
|
104
|
+
Hono backend, Vue 3 + Quasar SPA, SQLite (WAL) for persistence, WebSocket for live updates. Each workspace spawns its own agent engine and a dedicated MCP server (`kobo-tasks`) the agent uses to query and mutate workspace state.
|
|
265
105
|
|
|
266
|
-
```powershell
|
|
267
|
-
where whisper-cli
|
|
268
|
-
whisper-cli -h
|
|
269
106
|
```
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
- **ffmpeg binary path (optional)**
|
|
279
|
-
- If left empty, Kōbō falls back to:
|
|
280
|
-
- `whisper-cli` from `PATH` (or `WHISPER_CPP_COMMAND` if set)
|
|
281
|
-
- `ffmpeg` from `PATH`
|
|
282
|
-
- Download a model (e.g. `base`) and select it as active
|
|
283
|
-
|
|
284
|
-
The Voice panel shows runtime status (`ready/missing`) for both Whisper and ffmpeg so setup issues are visible immediately.
|
|
285
|
-
|
|
286
|
-
### Advanced voice parameters
|
|
287
|
-
|
|
288
|
-
Kōbō exposes additional transcription settings in **Settings → Voice**:
|
|
289
|
-
|
|
290
|
-
- **Temperature** (`0..1`) — decoding stability vs flexibility
|
|
291
|
-
- **Initial prompt** — optional context/jargon for better recognition
|
|
292
|
-
- **Translate to English** — translate non-English speech to English
|
|
293
|
-
- **Suppress non-speech tokens** — reduce non-speech artifacts in output
|
|
294
|
-
|
|
295
|
-
Recommended defaults by model:
|
|
296
|
-
|
|
297
|
-
- `tiny` / `base` → `0.1`
|
|
298
|
-
- `small` / `medium` / `large-v3` → `0.2`
|
|
299
|
-
|
|
300
|
-
## Sentry integration
|
|
301
|
-
|
|
302
|
-
Kōbō can turn a Sentry issue into a dedicated "fix workspace" — you paste the issue URL at workspace creation and Kōbō extracts the stacktrace, culprit, tags, offending spans and extra context, writes them as a local markdown file inside the worktree (`.ai/thoughts/SENTRY-<id>.md`), and primes the Claude agent with a TDD fix workflow that points at that file. The agent also keeps access to the Sentry MCP tools (`search_issue_events`, `get_issue_tag_values`, `get_sentry_resource`) so it can dig deeper on its own. **This feature is opt-in and reuses the Sentry MCP configuration you already have for Claude Code** — Kōbō does not manage a Sentry token separately.
|
|
303
|
-
|
|
304
|
-
Under the hood, Kōbō spawns the official [`@sentry/mcp-server`](https://www.npmjs.com/package/@sentry/mcp-server) as a child process using the exact `command`, `args`, and `env` from your `~/.claude.json`, then calls `get_sentry_resource` over stdio. No token handling inside Kōbō — if you change the token or the host in your Claude Code config, Kōbō follows automatically.
|
|
305
|
-
|
|
306
|
-
### Getting a Sentry auth token
|
|
307
|
-
|
|
308
|
-
1. In Sentry, go to **Settings → Developer Settings → Custom Integrations** (or **User Auth Tokens** for personal use)
|
|
309
|
-
2. Create a token with at least these scopes: `project:read`, `event:read`, `org:read`
|
|
310
|
-
3. Copy the token (format `sntryu_...` for user tokens)
|
|
311
|
-
|
|
312
|
-
### Configuring the Sentry MCP in Claude Code
|
|
313
|
-
|
|
314
|
-
The recommended setup is to register the Sentry MCP once in Claude Code — Kōbō picks it up automatically:
|
|
315
|
-
|
|
316
|
-
```bash
|
|
317
|
-
claude mcp add sentry -s user \
|
|
318
|
-
-e SENTRY_ACCESS_TOKEN=sntryu_your_token_here \
|
|
319
|
-
-e SENTRY_HOST=your-org.sentry.io \
|
|
320
|
-
-- npx -y @sentry/mcp-server@latest
|
|
107
|
+
src/
|
|
108
|
+
├── server/ # Hono backend (routes, services, db, agent orchestrator)
|
|
109
|
+
│ ├── services/agent/engines/ # claude-code/ + codex/ engines
|
|
110
|
+
│ └── ...
|
|
111
|
+
├── client/ # Vue 3 + Quasar SPA
|
|
112
|
+
├── mcp-server/ # kobo-tasks MCP server, spawned per workspace
|
|
113
|
+
├── shared/ # types shared backend ↔ frontend
|
|
114
|
+
└── __tests__/ # Vitest suite (1500+ tests)
|
|
321
115
|
```
|
|
322
116
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
### How Kōbō picks the entry
|
|
326
|
-
|
|
327
|
-
Kōbō reads `~/.claude.json` and uses the first entry under `mcpServers` whose key contains `sentry` (case-insensitive) **and is not disabled**. This means:
|
|
328
|
-
|
|
329
|
-
- A single `sentry` entry → used as-is
|
|
330
|
-
- Multiple entries whose key contains `sentry` → the first matching non-disabled key wins
|
|
331
|
-
- Toggle `"disabled": true` on an entry to make Kōbō skip it
|
|
117
|
+
[`AGENTS.md`](./AGENTS.md) covers the data model, WebSocket protocol, engine contracts, MCP tool surface, migration discipline, i18n rules, and contribution guidelines.
|
|
332
118
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
1. In the workspace creation form, click **Import Sentry**
|
|
336
|
-
2. Paste the issue URL (e.g. `https://your-org.sentry.io/issues/112081699`)
|
|
337
|
-
3. Submit — Kōbō extracts the issue, writes `.ai/thoughts/SENTRY-<numericId>.md`, creates a `Fix: <title>` task, and boots the agent with the fix workflow
|
|
338
|
-
|
|
339
|
-
The Sentry issue Short-ID (e.g. `ACME-API-3` — the canonical identifier Sentry assigns to each issue) is used as the ticket prefix for the working branch (e.g. `fix/ACME-API-3--slow-db-query` or `bugfix/ACME-API-3--slow-db-query`, depending on the branch prefix you chose at creation). The Short-ID is also what Sentry recognises in commit messages like `Fixes ACME-API-3` to auto-close the issue on merge. The local copy of the issue is written to `.ai/thoughts/SENTRY-<shortId>.md` (e.g. `SENTRY-ACME-API-3.md`). When Sentry is active, the description field becomes optional — the extracted context is enough to start work.
|
|
340
|
-
|
|
341
|
-
If the MCP server is slow to initialize (e.g. cold `npx` fetch, self-hosted host validation), bump the handshake timeout with `KOBO_MCP_INIT_TIMEOUT_MS` (default: `30000`).
|
|
342
|
-
|
|
343
|
-
Without a valid Sentry MCP configured in `~/.claude.json`, the Sentry import field returns a clear error when you submit — the rest of Kōbō keeps working.
|
|
344
|
-
|
|
345
|
-
## Recommended: Superpowers plugin for Claude Code
|
|
346
|
-
|
|
347
|
-
For the best experience, we recommend installing the [**superpowers**](https://github.com/obra/superpowers) plugin in Claude Code. Kōbō is designed to work well with it out of the box:
|
|
348
|
-
|
|
349
|
-
- **Brainstorming → spec → plan → execute** workflow — superpowers produces design specs in `docs/superpowers/specs/` and implementation plans in `docs/superpowers/plans/`; Kōbō's **Plan browser** (right-side drawer) lists both so you can review them without leaving the UI
|
|
350
|
-
- **Subagent-driven development** — executes plans task-by-task via parallel subagents; Kōbō surfaces sub-agent activity in the chat feed and the *Agent busy* banner so you always know what's running
|
|
351
|
-
- **Test-driven development, systematic debugging, code review** — all integrated with Kōbō's task tracking and git workflow
|
|
352
|
-
|
|
353
|
-
Install inside Claude Code:
|
|
119
|
+
## Scripts
|
|
354
120
|
|
|
355
121
|
```bash
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
```
|
|
365
|
-
src/
|
|
366
|
-
├── server/ # Hono backend
|
|
367
|
-
│ ├── index.ts # app bootstrap + WS upgrade
|
|
368
|
-
│ ├── db/ # SQLite schema, migrations, singleton
|
|
369
|
-
│ ├── services/
|
|
370
|
-
│ │ ├── agent/ # agent engine abstraction (replaces agent-manager.ts)
|
|
371
|
-
│ │ │ ├── orchestrator.ts # per-workspace engine map, retry/quota, watchdog, public API
|
|
372
|
-
│ │ │ ├── session-controller.ts # lifecycle wrapper around one AgentEngine instance
|
|
373
|
-
│ │ │ ├── event-router.ts # maps engine AgentEvent stream to WS emit + DB side-effects
|
|
374
|
-
│ │ │ └── engines/claude-code/ # spawn + NDJSON stream-parser + args-builder + mcp-config + capabilities
|
|
375
|
-
│ │ ├── content-migration-service.ts # legacy ws_events → normalised AgentEvent rows, with DB backup
|
|
376
|
-
│ │ ├── usage/ # pluggable quota provider, 60s poller, persistence, WS broadcast
|
|
377
|
-
│ │ ├── quota-backoff-service.ts # persisted Claude rate-limit backoff timers (re-armed on restart)
|
|
378
|
-
│ │ ├── cron-service.ts # persisted cron schedules (recurring + one-shot, resume/fresh modes)
|
|
379
|
-
│ │ ├── wakeup-service.ts # persisted one-shot session resumes (clamped to [60s, 6h])
|
|
380
|
-
│ │ └── … # workspace, dev-server, ws, notion, sentry, settings, pr-template
|
|
381
|
-
│ ├── routes/ # Hono handlers (workspaces, engines, migration, templates, usage, …)
|
|
382
|
-
│ └── utils/ # git-ops, process-tracker, paths
|
|
383
|
-
├── shared/ # modules shared by backend and frontend (e.g. model catalogue)
|
|
384
|
-
├── client/ # Vue 3 + Quasar SPA
|
|
385
|
-
│ └── src/
|
|
386
|
-
│ ├── stores/ # Pinia: workspace, websocket, agent-stream, migration, settings, …
|
|
387
|
-
│ ├── components/ # ActivityFeed, TurnCard, WorkspaceList, ChatInput, GitPanel, …
|
|
388
|
-
│ ├── services/ # agent-event-view (foldEvents), conversation-turns (groupIntoTurns), inline-diff
|
|
389
|
-
│ ├── pages/ # WorkspacePage, CreatePage, SettingsPage
|
|
390
|
-
│ └── router/
|
|
391
|
-
├── mcp-server/ # standalone MCP server spawned per workspace
|
|
392
|
-
│ ├── kobo-tasks-server.ts # entry point, registers list_tasks & mark_task_done
|
|
393
|
-
│ └── kobo-tasks-handlers.ts # pure handlers over SQLite
|
|
394
|
-
└── __tests__/ # Vitest suite (engines, orchestrator, migration, routes, …)
|
|
122
|
+
npm run dev:all # backend (:3300) + client (:8080)
|
|
123
|
+
npm run build # production build (client + server)
|
|
124
|
+
npm start # run the compiled server
|
|
125
|
+
npm test # backend vitest suite
|
|
126
|
+
npm run test:client # client vitest suite
|
|
127
|
+
npm run lint # biome check (lint + format)
|
|
128
|
+
make ci # full CI pipeline (audit + lint + tsc + tests)
|
|
395
129
|
```
|
|
396
130
|
|
|
397
|
-
See [`AGENTS.md`](./AGENTS.md) for a deeper dive into conventions, data model, WebSocket protocol, and contribution guidelines.
|
|
398
|
-
|
|
399
|
-
## Data model
|
|
400
|
-
|
|
401
|
-
| Table | Purpose |
|
|
402
|
-
|---|---|
|
|
403
|
-
| `workspaces` | the unit of work — branch, `worktree_path`, status, model, engine, `archived_at`, `favorited_at`, `tags`, Notion link, plus the two independent description columns (`description` user-controlled, `agent_description` agent-controlled), … |
|
|
404
|
-
| `tasks` | workspace sub-items — tasks and acceptance criteria |
|
|
405
|
-
| `agent_sessions` | agent runs — pid, `engine_session_id`, lifecycle |
|
|
406
|
-
| `ws_events` | persisted WebSocket events (chat history, `agent:event` stream, user messages) for replay on reconnect |
|
|
407
|
-
| `usage_snapshots` | latest quota snapshot per provider (one row per `provider_id`) — populated by the 60s polling loop, used for cold-start hydration of the chat-footer quota badge |
|
|
408
|
-
| `pending_wakeups` | one row per scheduled wakeup, target time and resume context, re-armed on server restart |
|
|
409
|
-
| `pending_quota_backoffs` | one row per workspace currently waiting on a Claude rate-limit reset, target time + reset metadata + retry count, re-armed on server restart |
|
|
410
|
-
| `pending_crons` | one row per scheduled cron — expression, prompt, label, optional pinned `agent_session_id` (= resume mode) or NULL (= fresh mode), `next_fire_at`, `last_fired_at`, `one_shot` flag, re-armed on server restart with skip-missed semantics |
|
|
411
|
-
|
|
412
|
-
## MCP server
|
|
413
|
-
|
|
414
|
-
Each workspace spawns its own `kobo-tasks` MCP server as a child process of the Claude Code agent. It exposes a curated tool surface tailored for agents working inside a Kōbō workspace, grouped by intent:
|
|
415
|
-
|
|
416
|
-
- **Tasks** — `list_tasks`, `create_task`, `update_task`, `delete_task`, `mark_task_done`
|
|
417
|
-
- **Workspace metadata** — `get_workspace_info` (returns name, branch, status, both `description` and `agentDescription`, etc.), `set_workspace_agent_description` (live status the user sees in the sidebar without opening the workspace), `set_workspace_status`
|
|
418
|
-
- **Auto-loop** — `mark_auto_loop_ready` (flip the grooming gate when the brainstorm step is done)
|
|
419
|
-
- **Git** — `get_git_info` (branch, commit count, dirty state)
|
|
420
|
-
- **Dev server** — `get_dev_server_status`, `start_dev_server`, `stop_dev_server`, `get_dev_server_logs`
|
|
421
|
-
- **External sources** — `get_notion_ticket`, `get_settings`
|
|
422
|
-
- **Documents & search** — `list_documents`, `read_document`, `log_thought`, `search_codebase`, `list_workspace_images`
|
|
423
|
-
- **Scheduling & telemetry** — `schedule_wakeup`, `cancel_wakeup`, `cron_create`, `cron_delete`, `cron_list`, `get_session_usage`
|
|
424
|
-
|
|
425
|
-
State-mutating tools that change UI-visible data (tasks, agent description, auto-loop readiness) write directly to SQLite for low latency, then fire-and-forget a `notify-*` HTTP call to the backend so the WebSocket layer broadcasts the change to every connected client. Tools that arm in-memory timers (`cron_create`, `cron_delete`) route through the backend HTTP API instead — the timer Map lives in the backend process which owns the orchestrator, so the cron survives the MCP server's session-bound lifetime.
|
|
426
|
-
|
|
427
|
-
The MCP server reads and writes the same SQLite database as the main backend. Isolation between workspaces is enforced via the `KOBO_WORKSPACE_ID` environment variable passed at spawn time and validated on every query.
|
|
428
|
-
|
|
429
|
-
## Configuration
|
|
430
|
-
|
|
431
|
-
Kōbō reads settings from `~/.config/kobo/settings.json` (or falls back to defaults). Global settings define defaults, with per-project overrides for project-scoped fields:
|
|
432
|
-
|
|
433
|
-
- `defaultModel` — Claude model to use (e.g. `claude-opus-4-6`)
|
|
434
|
-
- `worktreesPath` — where new workspace worktrees are created. Defaults to `.worktrees`, resolved relative to the project. Absolute Linux/macOS paths, Windows paths (`C:\kobo\worktrees`, UNC shares), `$HOME/...`, `${HOME}/...`, `~/...`, and `%USERPROFILE%\...` are accepted. Paths containing parent-directory traversal (`..`) or drive-relative Windows syntax (`C:foo`) are rejected.
|
|
435
|
-
- `prPromptTemplate` — template rendered when opening a PR via the `/open-pr` endpoint; supports `{{pr_number}}`, `{{pr_url}}`, `{{branch_name}}`, `{{diff_stats}}`, `{{commits}}`, etc.
|
|
436
|
-
- `gitConventions` — markdown-formatted git conventions written to `.ai/.git-conventions.md` in every workspace so the agent follows them when committing
|
|
437
|
-
- `devServer` — per-project `startCommand` / `stopCommand` for launching workspace-scoped dev servers
|
|
438
|
-
- `e2e` — per-project E2E test framework (`cypress`, `playwright`, `jest`, `vitest`, `other`, or none) plus an optional skill name and prompt; consumed by the auto-loop grooming step to inject `[E2E] ` test sub-tasks alongside parent tasks
|
|
439
|
-
- `finalization` — per-project free-form prompt that runs as the very last auto-loop iteration. The grooming step injects a `[FINAL]`-prefixed task at the end of the list whose iteration block is replaced by this prompt. Default content asks the agent to run linters, type-checkers, and tests. Empty string disables the feature.
|
|
440
|
-
|
|
441
131
|
## Contributing
|
|
442
132
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
1. Read [`AGENTS.md`](./AGENTS.md) — it covers the commit rules, branching model, and code conventions
|
|
446
|
-
2. Run `npm run lint`, `npx tsc --noEmit`, and `npm test` locally
|
|
447
|
-
3. Base your branch on `develop` (not `main`); PRs target `develop`
|
|
448
|
-
|
|
449
|
-
CI runs lint + type check + tests on every PR to `develop`.
|
|
133
|
+
PRs welcome. Branch off `develop`, follow Conventional Commits, run `make ci` before pushing. CI runs lint, type check, and tests on every PR to `develop`. See [`AGENTS.md`](./AGENTS.md) for code conventions and the database-migration discipline.
|
|
450
134
|
|
|
451
135
|
## Release
|
|
452
136
|
|
|
453
|
-
Releases are cut from `main`. Bump `package.json`
|
|
137
|
+
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 — failing early if the version or tag already exists.
|
|
454
138
|
|
|
455
139
|
## License
|
|
456
140
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
Kōbō links against [`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3), [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk), [Vue](https://vuejs.org/), [Quasar](https://quasar.dev/), and other open-source libraries — see `package.json` for the full list.
|
|
141
|
+
GPL-3.0-or-later. See [`LICENSE`](./LICENSE).
|