Kobo
KΕbΕ β multi-workspace agent manager for Claude Code. Orchestrates isolated git worktrees with dev servers, Notion integration, and MCP tools.
Ask AI about Kobo
Powered by Claude Β· Grounded in docs
I know everything about Kobo. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
KΕbΕ
KΕbΕ (ε·₯ζΏ) β Japanese for workshop. A multi-workspace agent manager for Claude Code.
[!NOTE] π§ Active development β breaking changes may still land on
develop. The database layer ships with forward-only migrations and a timestamped pre-migration backup ofkobo.dbbefore any schema change, so upgrades preserve your data even across invasive refactors.
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.
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.
Features
- 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
- Pluggable agent engine β KΕbΕ talks to agents through an
AgentEnginecontract with a normalisedAgentEventstream (src/server/services/agent/engines/). Theclaude-codeengine runs on the official@anthropic-ai/claude-agent-sdk; adding a second runtime (e.g. Codex) only requires a new adapter, not a rewrite of the UI or orchestration layer - Interactive
AskUserQuestionβ when the agent invokesAskUserQuestion, KΕbΕ pauses the session via the SDK'sdeferpattern, 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 - 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
- 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 - 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 - 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:
Syncsplit-button (pull / rebase / merge),Push,Diff,Create PR - 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
- 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 - Per-workspace dev servers β start/stop Docker or Node dev servers scoped to each branch, with log streaming
- Conventional-commit enforcement β project-level git conventions are written to
.ai/.git-conventions.mdinside every workspace so Claude follows them during commits - Pull request automation β one-click
push,pull,open-pr, and "change PR base" endpoints integrate with the GitHub CLI, using a configurable prompt template - 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 - 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 - 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
- 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
- Account-level quota panel β a colored mini-bar badge in the chat footer shows the current Claude Code 5-hour and 7-day usage, fed by a backend service that polls Anthropic's OAuth usage endpoint every 60 seconds. 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 (Codex-ready), 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
- Resizable right drawer β drag-to-resize horizontally and vertically, with tab state and split ratio persisted to localStorage
- 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
- Archive instead of delete β soft-remove workspaces without losing the worktree, branches, or history; unarchive restores the exact pre-archive state
- 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 aredone. 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 anX / Y tΓ’chesbadge in the workspace list, fed by the same task counts used by the in-page chip - 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
- 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 inquotastatus awaiting a manual nudge - Workspace description fields β every workspace has TWO independent description fields. The user-side
descriptionis 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 ownagent_descriptionvia theset_workspace_agent_descriptionMCP tool to broadcast a live status (e.g. "Investigating SERVICE-1600 β enriching local Notion file"). Both are visible: the sidebar showsagent_descriptionwhen set, falling back to the userdescription; the workspace header shows the user input plus an italic read-only line for the agent's current focus - Scheduled wakeups β the
ScheduleWakeuptool is honoured server-side: KΕbΕ persists the wakeup in SQLite, rehydrates on restart, and respawns the agent with--resumeat the target time. Delay is clamped to[60s, 6h]. The kobo-tasks MCP server also exposeskobo__schedule_wakeup/kobo__cancel_wakeupfor the same flow with first-class tool descriptors - 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: truecancels 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 CodeCronCreatetool is also intercepted and mirrored as a kobo cron so even agents using the SDK-default tool benefit from persistence - 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 anevent_repeaticon when one or more crons are scheduled, even for workspaces not currently focused β broadcast live via WebSocket events
Tech stack
- Backend β Node.js β₯ 20, Hono, better-sqlite3, ws,
@modelcontextprotocol/sdk - Frontend β Vue 3, Quasar 2, Pinia,
vue-router, Monaco Editor (git diff viewer),marked+dompurify(markdown rendering) - Tooling β TypeScript, Vitest, Biome (lint + format),
tsxfor dev - Storage β single SQLite file (
~/.config/kobo/kobo.dbby default, overridable viaKOBO_HOME) with WAL mode and forward-only migrations
Quick start
Prerequisites
- Node.js β₯ 20
- Claude Code authenticated via
claude /loginonce. TheclaudeCLI is no longer required at runtime β KΕbΕ embeds the official@anthropic-ai/claude-agent-sdk, which reuses the same login. - Git
- Optional: Docker (if you configure per-workspace dev servers)
- Optional:
ghCLI (if you use the PR automation) - Optional: a Notion integration token (only if you want to import workspace missions from Notion pages β see Notion integration)
- Optional: a Sentry auth token (only if you want to create fix workspaces from Sentry issue URLs β see Sentry integration)
Run via npx (recommended)
SERVER_PORT=9998 PORT=9999 npx @loicngr/kobo@latest
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).
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.
Run from source (contributors)
git clone https://github.com/loicngr/kobo.git
cd kobo
npm install
(cd src/client && npm install)
Run (development)
npm run dev:all
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.
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.
To run them separately:
npm run dev # backend only (KOBO_HOME=./data automatically)
npm run dev:client # frontend only
Build (production)
npm run build # builds client + server
npm start # runs the compiled server
Test & lint
npm test # backend vitest suite (1200+ tests)
npm run test:client # client vitest suite (Pinia stores + pure utils, 230+ tests)
npm run test:all # backend + client suites
npm run lint # biome check (lint + format verification)
npm run lint:fix # biome check with safe auto-fixes
npm run format # biome format --write
npx tsc --noEmit # server type check
Notion integration
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.
Under the hood, KΕbΕ spawns the official @notionhq/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.
Getting a Notion integration token
- Go to https://www.notion.so/profile/integrations and create a new internal integration
- Give it a name (e.g.
kobo) and the capabilities you need (at minimum: Read content) - Copy the internal integration secret (format
ntn_...orsecret_...) - 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.
Giving the token to KΕbΕ
KΕbΕ reads the token from the first source available, in this order:
NOTION_API_TOKENenvironment variableNOTION_TOKENenvironment variable~/.claude.jsonβ if you already have the Notion MCP configured for Claude Code, KΕbΕ reads the token frommcpServers.notion.env.NOTION_TOKEN(orNOTION_API_TOKEN). This is the recommended setup β one token configured once, shared by both Claude Code and KΕbΕ.
Example: configure Notion MCP in Claude Code (one-time setup that also unlocks KΕbΕ's Notion import):
claude mcp add notion -s user -e NOTION_TOKEN=ntn_your_token_here -- npx -y @notionhq/notion-mcp-server
Or launch KΕbΕ with the token inline:
NOTION_API_TOKEN=ntn_your_token_here PORT=9999 npx @loicngr/kobo@latest
Advanced: overriding the MCP command
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Ε:
NOTION_MCP_COMMANDβ the binary to run (default:npx)NOTION_MCP_ARGSβ space-separated arguments (default:-y @notionhq/notion-mcp-server)
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.
Sentry integration
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.
Under the hood, KΕbΕ spawns the official @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.
Getting a Sentry auth token
- In Sentry, go to Settings β Developer Settings β Custom Integrations (or User Auth Tokens for personal use)
- Create a token with at least these scopes:
project:read,event:read,org:read - Copy the token (format
sntryu_...for user tokens)
Configuring the Sentry MCP in Claude Code
The recommended setup is to register the Sentry MCP once in Claude Code β KΕbΕ picks it up automatically:
claude mcp add sentry -s user \
-e SENTRY_ACCESS_TOKEN=sntryu_your_token_here \
-e SENTRY_HOST=your-org.sentry.io \
-- npx -y @sentry/mcp-server@latest
For self-hosted Sentry, set SENTRY_HOST to your Sentry hostname (e.g. sentry.mycompany.com).
How KΕbΕ picks the entry
KΕbΕ reads ~/.claude.json and uses the first entry under mcpServers whose key contains sentry (case-insensitive) and is not disabled. This means:
- A single
sentryentry β used as-is - Multiple entries whose key contains
sentryβ the first matching non-disabled key wins - Toggle
"disabled": trueon an entry to make KΕbΕ skip it
Usage
- In the workspace creation form, click Import Sentry
- Paste the issue URL (e.g.
https://your-org.sentry.io/issues/112081699) - Submit β KΕbΕ extracts the issue, writes
.ai/thoughts/SENTRY-<numericId>.md, creates aFix: <title>task, and boots the agent with the fix workflow
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.
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).
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.
Recommended: Superpowers plugin for Claude Code
For the best experience, we recommend installing the superpowers plugin in Claude Code. KΕbΕ is designed to work well with it out of the box:
- Brainstorming β spec β plan β execute workflow β superpowers produces design specs in
docs/superpowers/specs/and implementation plans indocs/superpowers/plans/; KΕbΕ's Plan browser (right-side drawer) lists both so you can review them without leaving the UI - 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
- Test-driven development, systematic debugging, code review β all integrated with KΕbΕ's task tracking and git workflow
Install inside Claude Code:
/plugin marketplace add obra/superpowers-marketplace
/plugin install superpowers@superpowers-marketplace
Then start a new workspace in KΕbΕ β the agent will pick up the skills automatically.
Architecture
src/
βββ server/ # Hono backend
β βββ index.ts # app bootstrap + WS upgrade
β βββ db/ # SQLite schema, migrations, singleton
β βββ services/
β β βββ agent/ # agent engine abstraction (replaces agent-manager.ts)
β β β βββ orchestrator.ts # per-workspace engine map, retry/quota, watchdog, public API
β β β βββ session-controller.ts # lifecycle wrapper around one AgentEngine instance
β β β βββ event-router.ts # maps engine AgentEvent stream to WS emit + DB side-effects
β β β βββ engines/claude-code/ # spawn + NDJSON stream-parser + args-builder + mcp-config + capabilities
β β βββ content-migration-service.ts # legacy ws_events β normalised AgentEvent rows, with DB backup
β β βββ usage/ # pluggable quota provider, 60s poller, persistence, WS broadcast
β β βββ quota-backoff-service.ts # persisted Claude rate-limit backoff timers (re-armed on restart)
β β βββ cron-service.ts # persisted cron schedules (recurring + one-shot, resume/fresh modes)
β β βββ wakeup-service.ts # persisted one-shot session resumes (clamped to [60s, 6h])
β β βββ β¦ # workspace, dev-server, ws, notion, sentry, settings, pr-template
β βββ routes/ # Hono handlers (workspaces, engines, migration, templates, usage, β¦)
β βββ utils/ # git-ops, process-tracker, paths
βββ shared/ # modules shared by backend and frontend (e.g. model catalogue)
βββ client/ # Vue 3 + Quasar SPA
β βββ src/
β βββ stores/ # Pinia: workspace, websocket, agent-stream, migration, settings, β¦
β βββ components/ # ActivityFeed, TurnCard, WorkspaceList, ChatInput, GitPanel, β¦
β βββ services/ # agent-event-view (foldEvents), conversation-turns (groupIntoTurns), inline-diff
β βββ pages/ # WorkspacePage, CreatePage, SettingsPage
β βββ router/
βββ mcp-server/ # standalone MCP server spawned per workspace
β βββ kobo-tasks-server.ts # entry point, registers list_tasks & mark_task_done
β βββ kobo-tasks-handlers.ts # pure handlers over SQLite
βββ __tests__/ # Vitest suite (engines, orchestrator, migration, routes, β¦)
See AGENTS.md for a deeper dive into conventions, data model, WebSocket protocol, and contribution guidelines.
Data model
| Table | Purpose |
|---|---|
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), β¦ |
tasks | workspace sub-items β tasks and acceptance criteria |
agent_sessions | agent runs β pid, engine_session_id, lifecycle |
ws_events | persisted WebSocket events (chat history, agent:event stream, user messages) for replay on reconnect |
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 |
pending_wakeups | one row per scheduled wakeup, target time and resume context, re-armed on server restart |
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 |
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 |
MCP server
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:
- Tasks β
list_tasks,create_task,update_task,delete_task,mark_task_done - Workspace metadata β
get_workspace_info(returns name, branch, status, bothdescriptionandagentDescription, etc.),set_workspace_agent_description(live status the user sees in the sidebar without opening the workspace),set_workspace_status - Auto-loop β
mark_auto_loop_ready(flip the grooming gate when the brainstorm step is done) - Git β
get_git_info(branch, commit count, dirty state) - Dev server β
get_dev_server_status,start_dev_server,stop_dev_server,get_dev_server_logs - External sources β
get_notion_ticket,get_settings - Documents & search β
list_documents,read_document,log_thought,search_codebase,list_workspace_images - Scheduling & telemetry β
schedule_wakeup,cancel_wakeup,cron_create,cron_delete,cron_list,get_session_usage
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.
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.
Configuration
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:
defaultModelβ Claude model to use (e.g.claude-opus-4-6)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.prPromptTemplateβ template rendered when opening a PR via the/open-prendpoint; supports{{pr_number}},{{pr_url}},{{branch_name}},{{diff_stats}},{{commits}}, etc.gitConventionsβ markdown-formatted git conventions written to.ai/.git-conventions.mdin every workspace so the agent follows them when committingdevServerβ per-projectstartCommand/stopCommandfor launching workspace-scoped dev serverse2eβ 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 tasksfinalizationβ 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.
Contributing
This is a personal tool, but PRs and issues are welcome. Before submitting:
- Read
AGENTS.mdβ it covers the commit rules, branching model, and code conventions - Run
npm run lint,npx tsc --noEmit, andnpm testlocally - Base your branch on
develop(notmain); PRs targetdevelop
CI runs lint + type check + tests on every PR to develop.
Release
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.
License
GNU General Public License v3.0 or later. See LICENSE for the full text.
KΕbΕ links against better-sqlite3, @modelcontextprotocol/sdk, Vue, Quasar, and other open-source libraries β see package.json for the full list.
