@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.
Files changed (127) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +81 -399
  3. package/dist/server/db/migrations.js +33 -0
  4. package/dist/server/index.js +21 -2
  5. package/dist/server/routes/changelog.js +47 -0
  6. package/dist/server/routes/export.js +71 -0
  7. package/dist/server/routes/fs.js +49 -0
  8. package/dist/server/routes/git.js +16 -1
  9. package/dist/server/routes/health.js +2 -1
  10. package/dist/server/routes/workspaces.js +107 -64
  11. package/dist/server/services/agent/orchestrator.js +10 -0
  12. package/dist/server/services/archive-script-service.js +65 -0
  13. package/dist/server/services/auto-loop-service.js +7 -0
  14. package/dist/server/services/cleanup-script-service.js +118 -0
  15. package/dist/server/services/settings-service.js +184 -2
  16. package/dist/server/services/setup-script-service.js +10 -81
  17. package/dist/server/utils/git-ops.js +30 -0
  18. package/dist/server/utils/paths.js +4 -0
  19. package/dist/server/utils/script-runner.js +96 -0
  20. package/package.json +2 -1
  21. package/src/client/dist/spa/assets/ActivityFeed-DU6lDEP0.js +8 -0
  22. package/src/client/dist/spa/assets/{ActivityFeed-WjiQ9716.css → ActivityFeed-yUMQhnW4.css} +1 -1
  23. package/src/client/dist/spa/assets/{ClosePopup-C5EF3QrA.js → ClosePopup-CxvZA3ft.js} +1 -1
  24. package/src/client/dist/spa/assets/CreatePage-CdZr7f3j.js +2 -0
  25. package/src/client/dist/spa/assets/CreatePage-DgHjL4cZ.css +1 -0
  26. package/src/client/dist/spa/assets/{DiffViewer-hWxcG22N.js → DiffViewer-m801GPfI.js} +3 -3
  27. package/src/client/dist/spa/assets/HealthPage-z1uIOpYk.js +1 -0
  28. package/src/client/dist/spa/assets/{MainLayout-Bp0oVWa-.css → MainLayout-BJmBXwYn.css} +1 -1
  29. package/src/client/dist/spa/assets/MainLayout-oJdQ-QKM.js +37 -0
  30. package/src/client/dist/spa/assets/{QBadge-u0mEz_W1.js → QBadge-NEwszYs7.js} +1 -1
  31. package/src/client/dist/spa/assets/QBanner-Jsq4uJZs.js +1 -0
  32. package/src/client/dist/spa/assets/QBtn-CoU-UC_j.js +1 -0
  33. package/src/client/dist/spa/assets/{QCheckbox-skYuqkHX.js → QCheckbox-Cq2STfHp.js} +1 -1
  34. package/src/client/dist/spa/assets/{QChip-DSMeriN6.js → QChip-DnJyQVs2.js} +2 -2
  35. package/src/client/dist/spa/assets/QExpansionItem-BTd5m2yV.js +1 -0
  36. package/src/client/dist/spa/assets/QIcon-BmEX2rXO.js +1 -0
  37. package/src/client/dist/spa/assets/QInput-D0t39uK_.js +1 -0
  38. package/src/client/dist/spa/assets/{QItemLabel-B0tYxHQg.js → QItemLabel-Btqw0P7M.js} +1 -1
  39. package/src/client/dist/spa/assets/QItemSection-DRg-QuAD.js +1 -0
  40. package/src/client/dist/spa/assets/QList-B3TuWSqL.js +1 -0
  41. package/src/client/dist/spa/assets/QMenu-C2Wwwf2E.js +1 -0
  42. package/src/client/dist/spa/assets/QPage-DO_bQyV_.js +1 -0
  43. package/src/client/dist/spa/assets/QRadio-M9mC5jZy.js +1 -0
  44. package/src/client/dist/spa/assets/QScrollArea-A1wI0IXU.js +1 -0
  45. package/src/client/dist/spa/assets/QSpace-DONPiIes.js +1 -0
  46. package/src/client/dist/spa/assets/{QSpinnerDots-CluOpUgq.js → QSpinnerDots-DspFKwCZ.js} +1 -1
  47. package/src/client/dist/spa/assets/{QToggle-aBvIHg6j.js → QToggle-DBzTAIbK.js} +1 -1
  48. package/src/client/dist/spa/assets/QTooltip-Bfdmzm_m.js +1 -0
  49. package/src/client/dist/spa/assets/SearchPage-ChmKHNKn.js +1 -0
  50. package/src/client/dist/spa/assets/SettingsPage-B59LoCos.js +9 -0
  51. package/src/client/dist/spa/assets/{SettingsPage-B_qPRSDH.css → SettingsPage-BJLyYrBN.css} +1 -1
  52. package/src/client/dist/spa/assets/{TouchPan-DPBZDRzA.js → TouchPan-BIE5rs7U.js} +1 -1
  53. package/src/client/dist/spa/assets/WorkspacePage-Bj1PJSWT.js +4 -0
  54. package/src/client/dist/spa/assets/WorkspacePage-tFBswKV9.css +1 -0
  55. package/src/client/dist/spa/assets/build-path-tree-BGUV3nY1.js +1 -0
  56. package/src/client/dist/spa/assets/{cssMode-DTibHxcy.js → cssMode-BU4X8R6a.js} +1 -1
  57. package/src/client/dist/spa/assets/documents-B3nitIYF.js +1 -0
  58. package/src/client/dist/spa/assets/{editor.api-CdLzoLLv.js → editor.api-B4xBDzmJ.js} +1 -1
  59. package/src/client/dist/spa/assets/{editor.main-DSLdinVQ.js → editor.main-CSZRkloL.js} +3 -3
  60. package/src/client/dist/spa/assets/engineFeatures-CLOVr5b4.js +1 -0
  61. package/src/client/dist/spa/assets/expand-template-BxUkuL5g.js +1 -0
  62. package/src/client/dist/spa/assets/{formatters-CgfY9uSI.js → formatters-9dcj2tyJ.js} +1 -1
  63. package/src/client/dist/spa/assets/{freemarker2-wf8G5c3b.js → freemarker2-DRz20wAV.js} +1 -1
  64. package/src/client/dist/spa/assets/{handlebars-BGPZbdOB.js → handlebars-C0dsvPnC.js} +1 -1
  65. package/src/client/dist/spa/assets/{html-DPEVCP74.js → html-Cqvj1pWs.js} +1 -1
  66. package/src/client/dist/spa/assets/{htmlMode-DMWUNRWz.js → htmlMode-BTHNvkm6.js} +1 -1
  67. package/src/client/dist/spa/assets/i18n-D1I-Us2H.js +1 -0
  68. package/src/client/dist/spa/assets/{index-5ydpLSpt.css → index-ClabzOPc.css} +1 -1
  69. package/src/client/dist/spa/assets/index-KABmOIkF.js +2 -0
  70. package/src/client/dist/spa/assets/{javascript-hOcrXbaP.js → javascript-C8n3U02v.js} +1 -1
  71. package/src/client/dist/spa/assets/{jsonMode-EeNIyfJU.js → jsonMode-C3AFxQ6K.js} +1 -1
  72. package/src/client/dist/spa/assets/{kobo-commands-Bh5k0Smw.js → kobo-commands-BuxgteGZ.js} +1 -1
  73. package/src/client/dist/spa/assets/{liquid-Cvw1gFPR.js → liquid-C4wtUDrJ.js} +1 -1
  74. package/src/client/dist/spa/assets/{mdx-CGtsv5px.js → mdx-CaT1p1F2.js} +1 -1
  75. package/src/client/dist/spa/assets/{monaco.contribution-RY1eW2u5.js → monaco.contribution-CJg5GKVf.js} +2 -2
  76. package/src/client/dist/spa/assets/notifications-BC6en6Lt.js +1 -0
  77. package/src/client/dist/spa/assets/permissionModes-BQHBTBwa.js +1 -0
  78. package/src/client/dist/spa/assets/{python-t0GNay3W.js → python-Cj54W2Tg.js} +1 -1
  79. package/src/client/dist/spa/assets/{razor-v9eEhqO6.js → razor-D3gJxoX_.js} +1 -1
  80. package/src/client/dist/spa/assets/render-chat-markdown-DxEHr3lW.js +60 -0
  81. package/src/client/dist/spa/assets/runtime-core.esm-bundler-D_RRiKBh.js +1 -0
  82. package/src/client/dist/spa/assets/{tsMode-B376_f_2.js → tsMode-B6S4PLWH.js} +1 -1
  83. package/src/client/dist/spa/assets/{typescript-WTvQ8gc0.js → typescript-Ca8AEX3t.js} +1 -1
  84. package/src/client/dist/spa/assets/use-checkbox-DnSuDqo2.js +1 -0
  85. package/src/client/dist/spa/assets/use-id-BCnfiBjU.js +1 -0
  86. package/src/client/dist/spa/assets/use-onboarding-B3l7mx48.css +1 -0
  87. package/src/client/dist/spa/assets/use-onboarding-CNeLPDtv.js +2 -0
  88. package/src/client/dist/spa/assets/use-quasar-k24tGxE-.js +1 -0
  89. package/src/client/dist/spa/assets/{vue-i18n-cyuEW5NY.js → vue-i18n-Cq-KgjJC.js} +2 -2
  90. package/src/client/dist/spa/assets/{xml-BMuHSj3C.js → xml-CsKo4k8C.js} +1 -1
  91. package/src/client/dist/spa/assets/{yaml-BRigOMm_.js → yaml-X5yKmi6z.js} +1 -1
  92. package/src/client/dist/spa/index.html +13 -13
  93. package/src/client/dist/spa/assets/ActivityFeed-CrlJXGsr.js +0 -8
  94. package/src/client/dist/spa/assets/CreatePage-B7DVVS0u.js +0 -2
  95. package/src/client/dist/spa/assets/CreatePage-ZyBHUbl0.css +0 -1
  96. package/src/client/dist/spa/assets/HealthPage-BP_TiWeV.js +0 -1
  97. package/src/client/dist/spa/assets/MainLayout-BRV8i-6o.js +0 -37
  98. package/src/client/dist/spa/assets/QBtn-CLU6snCm.js +0 -1
  99. package/src/client/dist/spa/assets/QExpansionItem-BFqbf9C7.js +0 -1
  100. package/src/client/dist/spa/assets/QIcon-0rjEivgj.js +0 -1
  101. package/src/client/dist/spa/assets/QInput-Ciqjq5-e.js +0 -1
  102. package/src/client/dist/spa/assets/QItemSection-DZnyqPM3.js +0 -1
  103. package/src/client/dist/spa/assets/QList-MfhZa-uv.js +0 -1
  104. package/src/client/dist/spa/assets/QMenu-Cx3v9_6z.js +0 -1
  105. package/src/client/dist/spa/assets/QPage-CGYPttdA.js +0 -1
  106. package/src/client/dist/spa/assets/QRadio-BEsMlsx1.js +0 -1
  107. package/src/client/dist/spa/assets/QSpace-BrtkvWzZ.js +0 -1
  108. package/src/client/dist/spa/assets/QTooltip-DdpeVKGV.js +0 -1
  109. package/src/client/dist/spa/assets/SearchPage-MfSrrMo1.js +0 -1
  110. package/src/client/dist/spa/assets/SettingsPage-CR3kXpHd.js +0 -9
  111. package/src/client/dist/spa/assets/WorkspacePage-B4YnZ6re.css +0 -1
  112. package/src/client/dist/spa/assets/WorkspacePage-DUKKBulA.js +0 -4
  113. package/src/client/dist/spa/assets/build-path-tree-DOtGuDWX.js +0 -1
  114. package/src/client/dist/spa/assets/documents-qOarUoMj.js +0 -1
  115. package/src/client/dist/spa/assets/engineFeatures-DNZNjYIf.js +0 -1
  116. package/src/client/dist/spa/assets/expand-template-Fy2sU7vj.js +0 -1
  117. package/src/client/dist/spa/assets/i18n-CUkOJRYM.js +0 -1
  118. package/src/client/dist/spa/assets/index-D9yyMIdQ.js +0 -2
  119. package/src/client/dist/spa/assets/notifications-BzyK_kYE.js +0 -1
  120. package/src/client/dist/spa/assets/permissionModes-BBA8zBcf.js +0 -1
  121. package/src/client/dist/spa/assets/project-color-d_h7ZYoM.js +0 -1
  122. package/src/client/dist/spa/assets/purify.es-CxaFgMzS.js +0 -60
  123. package/src/client/dist/spa/assets/render-chat-markdown-B41YA3kF.js +0 -1
  124. package/src/client/dist/spa/assets/runtime-core.esm-bundler-DPcTPMmX.js +0 -1
  125. package/src/client/dist/spa/assets/use-checkbox-DzLCp4E3.js +0 -1
  126. package/src/client/dist/spa/assets/use-id-BQW6DfJU.js +0 -1
  127. 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
- > **Kōbō** (工房) — Japanese for *workshop*. A multi-workspace agent manager for [Claude Code](https://claude.com/claude-code) and [OpenAI Codex](https://developers.openai.com/codex/) *(Codex support is still experimental — see [the section below](#openai-codex-integration))*.
3
+ > Multi-workspace orchestrator for [Claude Code](https://claude.com/claude-code) and [OpenAI Codex](https://developers.openai.com/codex/) agents.
4
4
 
5
- > [!NOTE]
6
- > 🚧 **Active development** — breaking changes may still land on `develop`. The database layer ships with forward-only migrations and a timestamped pre-migration backup of `kobo.db` before any schema change, so upgrades preserve your data even across invasive refactors.
5
+ [![npm](https://img.shields.io/npm/v/@loicngr/kobo.svg)](https://www.npmjs.com/package/@loicngr/kobo)
6
+ [![license](https://img.shields.io/npm/l/@loicngr/kobo.svg)](./LICENSE)
7
+ [![node](https://img.shields.io/node/v/@loicngr/kobo.svg)](https://nodejs.org/)
7
8
 
8
- Kōbō lets you delegate multiple coding missions to Claude Code agents in parallel. Each workspace lives in its own isolated git worktree with its own branch, its own Claude session, optionally its own dev server, and a custom MCP tools server the agent uses to track progress. A Vue 3 dashboard shows live agent output, tasks, acceptance criteria, and git state across every workspace.
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
- Think of it as an apprentice's hall: you hand out missions, each apprentice sets up their own workbench, and you watch them work from a single control surface.
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 git worktrees** — every workspace runs on its own branch in its own directory, with a configurable global worktrees root for new workspaces, so concurrent Claude sessions never step on each other
15
- - **Pluggable agent engine — two runtimes shipped** — Kōbō talks to agents through an `AgentEngine` contract with a normalised `AgentEvent` stream (`src/server/services/agent/engines/`). The `claude-code` engine runs on the official [`@anthropic-ai/claude-agent-sdk`](https://github.com/anthropics/claude-agent-sdk-typescript); the `codex` engine speaks the [`codex app-server`](https://github.com/openai/codex) JSON-RPC protocol over stdio with the official [`@openai/codex`](https://www.npmjs.com/package/@openai/codex) binary. Engine is chosen per-workspace at creation time, with a single normalised UI (sub-agents, tool calls, todos, reasoning, permission modes, MCP servers, auto-loop) covering both. Adding a third runtime only requires a new adapter, not a rewrite of the UI or orchestration layer
16
- - **Interactive `AskUserQuestion`**when the agent invokes `AskUserQuestion`, Kōbō pauses the session via the SDK's `defer` pattern, surfaces a question panel in the UI, and resumes the agent once the user answers. The session does not occupy any resources while it waits
17
- - **Rich chat feed** — live streaming text, thinking blocks, inline tool calls with expandable diffs for Edit/Write, per-turn session cards, markdown rendering, jump-to-previous-user-message button, and infinite scroll-up over persisted history
18
- - **Task & acceptance criteria tracking** — the agent reports progress through a dedicated MCP server (`kobo-tasks`) that reads and updates tasks directly from the SQLite database
19
- - **Documents panel** — tree view in the right drawer that surfaces every AI-generated markdown file under `docs/plans/`, `docs/superpowers/`, and `.ai/thoughts/`. Paths mentioned in chat messages are auto-detected against the catalogue and become one-click deep-links into the panel
20
- - **Git panel with inline diff viewer** — Monaco-powered side-by-side / inline diff of the working branch against its source, with file tree (same q-tree as Documents), inline rebase/merge conflict resolution, and a clean action bar: `Sync` split-button (pull / rebase / merge), `Push`, `Diff`, `Create PR`
21
- - **Notion integration** — pull workspace missions straight from Notion pages, extract markdown, and use it as the source of truth for acceptance criteria. Right-click a Notion-sourced workspace to jump back to its source page in one click
22
- - **Sentry integration** — paste a Sentry issue URL to spin up a dedicated "fix workspace" with the stacktrace, tags, and offending spans written to `.ai/thoughts/SENTRY-<id>.md`; the agent is primed with a TDD fix workflow and has access to the Sentry MCP tools for deeper digging. Right-click reopens the Sentry issue in Sentry's UI
23
- - **Per-workspace dev servers** — start/stop Docker or Node dev servers scoped to each branch, with log streaming
24
- - **Conventional-commit enforcement** — project-level git conventions are written to `.ai/.git-conventions.md` inside every workspace so Claude follows them during commits
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
- ### Prerequisites
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
- git clone https://github.com/loicngr/kobo.git
77
- cd kobo
78
- npm install
79
- (cd src/client && npm install)
33
+ npx @loicngr/kobo@latest
80
34
  ```
81
35
 
82
- ### Run (development)
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
- npm run dev:all
39
+ SERVER_PORT=9997 PORT=9998 npx @loicngr/kobo@latest
86
40
  ```
87
41
 
88
- This starts the Hono backend on port `3300` (via `tsx watch`, with `KOBO_HOME=./data` so dev uses the repo-local data directory and never touches your real `~/.config/kobo/`) and the Quasar dev server on port `8080` concurrently. Open <http://localhost:8080> in your browser.
42
+ Open <http://localhost:3000> (or whichever port you picked). Data is persisted under `~/.config/kobo/` (override via `KOBO_HOME`).
89
43
 
90
- You can run a production-installed Kōbō (`npx @loicngr/kobo`) alongside a dev server without any conflict — they use different data directories by design.
91
-
92
- To run them separately:
44
+ ### From source
93
45
 
94
46
  ```bash
95
- npm run dev # backend only (KOBO_HOME=./data automatically)
96
- npm run dev:client # frontend only
97
- ```
98
-
99
- ### Build (production)
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
- ### Advanced: overriding the MCP command
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
- ### MCP servers
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
- Without a working `codex` install or a valid credential, creating a `codex`-engine workspace returns a clear error at first turn and the workspace transitions to `error` status. The rest of Kōbō (Claude-engine workspaces, tasks, Git, dev servers) keeps working independently.
58
+ The most common knobs:
215
59
 
216
- ## Voice transcription (local Whisper)
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
- Kōbō supports local voice transcription with push-to-talk in both:
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
- - `WorkspacePage` (chat input)
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
- ### Requirements
72
+ ## Agent runtimes
224
73
 
225
- - `whisper-cli` from [`whisper.cpp`](https://github.com/ggml-org/whisper.cpp)
226
- - `ffmpeg`
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
- ### Install `whisper.cpp` (Linux/macOS)
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
- ```bash
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
- This usually produces `build/bin/whisper-cli`.
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
- You can also download a prebuilt archive from the `whisper.cpp` releases page (for example: <https://github.com/ggml-org/whisper.cpp/releases/tag/v1.8.4>) and point Kōbō to the extracted `whisper-cli` binary path.
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
- ### Install `ffmpeg`
87
+ See [`CONFIGURATION.md`](./CONFIGURATION.md) for the setup of each.
244
88
 
245
- Ubuntu / Debian:
89
+ ## Skill suites
246
90
 
247
- ```bash
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
- Windows:
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
- - Install `ffmpeg` (for example via Chocolatey: `choco install ffmpeg`, or via Scoop: `scoop install ffmpeg`)
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
- ```powershell
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
- ### Windows notes for `whisper.cpp`
102
+ ## Architecture
263
103
 
264
- Install CMake and Visual Studio Build Tools (C/C++), then build `whisper.cpp` (or use a prebuilt `whisper-cli`), then verify:
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
- ### Configure in Kōbō
272
-
273
- Open **Settings → Voice**:
274
-
275
- - Enable voice transcription
276
- - Optionally set:
277
- - **Whisper binary path (optional)**
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
- For self-hosted Sentry, set `SENTRY_HOST` to your Sentry hostname (e.g. `sentry.mycompany.com`).
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
- ### Usage
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
- /plugin marketplace add obra/superpowers-marketplace
357
- /plugin install superpowers@superpowers-marketplace
358
- ```
359
-
360
- Then start a new workspace in Kōbō — the agent will pick up the skills automatically.
361
-
362
- ## Architecture
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
- This is a personal tool, but PRs and issues are welcome. Before submitting:
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` and `package-lock.json` on `develop`, merge `develop` into `main`, then push `main`. The release workflow builds, tests, publishes the current package version to npm, tags it as `v<version>`, and creates the GitHub Release. If the npm version or tag already exists, the workflow fails before publishing.
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
- GNU General Public License v3.0 or later. See [`LICENSE`](./LICENSE) for the full text.
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).