diff --git a/docs/PRODUCT.md b/docs/PRODUCT.md index 92d8e7749..f891eeba7 100644 --- a/docs/PRODUCT.md +++ b/docs/PRODUCT.md @@ -107,7 +107,7 @@ the file path and parse details. The TUI has an extensible slash-command framework. Built-ins include `/help` (shortcut + command overlay), `/model` (models-only picker for connected accounts; **Alt+A** or `/connect` adds a provider), `/settings`, `/permissions`, `/plugins`, `/clear`, `/new`, `/compact` (fold conversation context now, optional trailing instructions to the summarizer; does not wait for the 60% occupancy governor; idle success shows the fold and does not start a new turn), `/mcp` (enable, disable, or remove servers), `/handoff [optional instructions]` (folds context through the shared operator pipeline, then immediately starts the next turn with the instructions as the inbound content — default copy when omitted; unlike `/compact`, which stops after the fold, handoff always re-infers, so the operator can pivot goals without `/clear`; a handoff issued mid-tool-batch queues behind the in-flight batch and whichever boundary fires first runs the single fold), and `/yolo` (`/yolo [on|off|toggle]`, bare `/yolo` toggles), plus a `/` command per available workflow. `/yolo` persists skip-permissions to the active settings file. That file is the user-global `~/.corbits/settings.json` by default, making the setting machine-wide; explicit `--config ` selects a different active file, and `/yolo` writes that file. An ordinary TUI launch without the same `--config` returns to the user-global source and does not modify the custom file. `--dangerously-skip-permissions` and `--yolo` are process-only aliases. Secret-guard and authz still apply. When a session starts with its active persisted setting already on, the TUI and `corbits exec` warn that permission prompts are disabled by saved settings at the active settings path and direct the operator to edit that file to re-enable them. Plugins can register additional commands. -**Default skills** exist out of the gate as first-party slash **actions**, not director names: `/implement`, `/plan`, `/refactor`, `/review`, `/pull-request`, `/issue`, `/docs`, `/interview`. Each one is a how-to playbook — the slash sends the skill body to the primary, which follows the steps. Skills do not assign identity or route the fleet; that stays on director system prompts. Background reference skills (`typescript`, `git-worktrees`, and the `interchange` hub with its `interchange-agents`, `interchange-workflows`, `interchange-run-modes`, `interchange-embed-hub`, `interchange-hub-setup`, `interchange-hub-api`, `interchange-chat`, and `interchange-client-apps` references) have no slash; the model loads them with `skill_search` and `use_skill`, and each one ends with "need more, go here" pointers to the next skill in the chain. `/review` classifies the target first, then dispatches a selected fleet; `/pull-request` finds or opens the PR for the current branch, and `/review` takes a PR target and reviews it from a worktree; `/docs` is how to maintain PRODUCT / ARCHITECTURE / IMPLEMENTATION; `/implement` takes a plan and a ticket to a pushed branch (worktree, per-commit planner/build/reviewer loop, whole-branch review, push, hand off to `/pull-request`) — it does not steal planning from `/plan`. Substantial coder work consumes a planner / `/plan` plan first; tiny parent-DIY stays plan-optional. `/plan` authors an eng change plan (files, AC, non-goals, risks, ordered steps) and does not implement. `/issue` finds or creates the tracker issue: Linear MCP when available; otherwise it `ask_operator`s for the platform (GitHub etc.) and persists `Preferred issue tracker` in `.corbits/MEMORY.md` (GitHub via `gh issue create`). There is no first-party dispatch skill: the dispatch director orchestrates natively. `typescript` stays `use_skill` only (`user-invocable: false`); `git-worktrees` is a background library that is not listed for `use_skill`. Designer and the other specialists are not slashes; they remain closed directors via `spawn_agent(agent=…)`. There is no catch-all worker. Slash names are also available to the model via `skill_search` (descriptions) then `use_skill` (body). Disable the catalog in `/plugins` (`corbits-skills`) if you want them gone. +**Default skills** exist out of the gate as first-party slash **actions**, not director names: `/implement`, `/plan`, `/refactor`, `/review`, `/pull-request`, `/issue`, `/docs`, `/interview`. Each one is a how-to playbook — the slash sends the skill body to the primary, which follows the steps. Skills do not assign identity or route the fleet; that stays on director system prompts. Background reference skills (`typescript`, `git-worktrees`, and the `interchange` hub with its `interchange-agents`, `interchange-workflows`, `interchange-run-modes`, `interchange-embed-hub`, `interchange-hub-setup`, `interchange-hub-api`, `interchange-chat`, and `interchange-client-apps` references, and the `corbits` hub with `corbits-inference`, `corbits-system-one`, `corbits-tools`, `corbits-hub-libs`, and `corbits-ui-apps`) have no slash; the model loads them with `skill_search` and `use_skill`, and each one ends with "need more, go here" pointers to the next skill in the chain. `/review` classifies the target first, then dispatches a selected fleet; `/pull-request` finds or opens the PR for the current branch, and `/review` takes a PR target and reviews it from a worktree; `/docs` is how to maintain PRODUCT / ARCHITECTURE / IMPLEMENTATION; `/implement` takes a plan and a ticket to a pushed branch (worktree, per-commit planner/build/reviewer loop, whole-branch review, push, hand off to `/pull-request`) — it does not steal planning from `/plan`. Substantial coder work consumes a planner / `/plan` plan first; tiny parent-DIY stays plan-optional. `/plan` authors an eng change plan (files, AC, non-goals, risks, ordered steps) and does not implement. `/issue` finds or creates the tracker issue: Linear MCP when available; otherwise it `ask_operator`s for the platform (GitHub etc.) and persists `Preferred issue tracker` in `.corbits/MEMORY.md` (GitHub via `gh issue create`). There is no first-party dispatch skill: the dispatch director orchestrates natively. `typescript` stays `use_skill` only (`user-invocable: false`); `git-worktrees` is a background library that is not listed for `use_skill`. Designer and the other specialists are not slashes; they remain closed directors via `spawn_agent(agent=…)`. There is no catch-all worker. Slash names are also available to the model via `skill_search` (descriptions) then `use_skill` (body). Disable the catalog in `/plugins` (`corbits-skills`) if you want them gone. Providers are **models-first**: there is no standalone `/login` command. `/model` opens a **models-only list** (Recent, Favorites, then connected provider/model rows) — type-to-filter owns printable keys, so Connect is never a bare letter. **Alt+A** or `/connect` opens a dedicated add-provider selector over every first-class kind (OpenAI dual-path ChatGPT OAuth or API key, xAI, OpenCode Zen, Anthropic, Google, OpenCode Go, Z.AI Coding Plan, Ollama, Custom), each annotated with its live account count and never filtered out for “already connected.” **Alt+F** toggles favorite on the highlighted model. **Alt+D** persists the highlighted pair as the default without switching the live session. Advanced provider drill-down (edit/delete/tiers) stays on the advanced surface, not a bare printable key while the model list is filtering. OAuth providers open their existing browser login with a named account step so multiple accounts per kind coexist (`codex/work`, …). API-key providers use the same named-instance step before the key (auth-only form: instance name + key + fixed catalog base URL), so personal and team keys land as distinct catalog rows (`openai/default`, `anthropic/work`, …); reusing a name re-keys that instance after confirm. Custom remains a free-form single endpoint (full manual form). Successful connect refreshes the catalog and reopens the model list focused on the new account’s default model. OpenCode Go lists models from the live `/zen/go/v1/models` catalog (packaged seed on fetch failure), routes each by its protocol metadata (chat completions, OpenAI responses, or Anthropic messages) and can show subscription usage in the status bar when active (rolling 5h / weekly / monthly windows when the usage API responds; omitted on auth or network failure). When Go returns a quota or rate-limit error — including some HTTP 400 responses that carry limit payloads — Corbits classifies them so quota aborts cleanly and short provider rate limits remain retryable. On a free-tier or subscription quota hit, wait for the window to reset or use OpenCode Zen free models. diff --git a/docs/TELEMETRY.md b/docs/TELEMETRY.md index 44bf126c5..c7e9e904a 100644 --- a/docs/TELEMETRY.md +++ b/docs/TELEMETRY.md @@ -81,7 +81,7 @@ director ids from `DIRECTOR_IDS` (and the legacy `worker` alias) are reported by id; project-defined or marketplace profile ids become `custom`. `skill_used` carries `skill_name`: a first-party skill name reportable by name from the closed `corbits-skills` allowlist in `src/telemetry/classify.ts` -(the slash workflows plus the background skills `git-worktrees`, `typescript`, and the `interchange` chain), or `custom` for anything else, including bundled background +(the slash workflows plus the background skills `git-worktrees`, `typescript`, and the `interchange` and `corbits` chains), or `custom` for anything else, including bundled background skills outside the list. Unknown, project-local, and plugin-authored skill names are never transmitted; `skill_name` is the only identifying-adjacent property the event can carry. diff --git a/plugins/corbits-skills/manifest.json b/plugins/corbits-skills/manifest.json index 791e85f45..a084eca32 100644 --- a/plugins/corbits-skills/manifest.json +++ b/plugins/corbits-skills/manifest.json @@ -3,5 +3,5 @@ "name": "Corbits Skills", "kind": "command", "defaultEnabled": true, - "description": "Default operator skills and slash commands (implement, refactor, review, pull-request, issue, docs, interview, plan) and background reference skills (git-worktrees, typescript, interchange)." + "description": "Default operator skills and slash commands (implement, refactor, review, pull-request, issue, docs, interview, plan) and background reference skills (git-worktrees, typescript, interchange, corbits)." } diff --git a/plugins/corbits-skills/skills/corbits-hub-libs/SKILL.md b/plugins/corbits-skills/skills/corbits-hub-libs/SKILL.md new file mode 100644 index 000000000..91e8a578d --- /dev/null +++ b/plugins/corbits-skills/skills/corbits-hub-libs/SKILL.md @@ -0,0 +1,69 @@ +--- +name: corbits-hub-libs +description: Mount Corbits hub libraries (cron, artifacts, memory, mailbox, webhooks, agent-token) and use the embedding and reranking clients. Load when adding schedules, webhooks, artifacts, memory, inboxes, or agent tokens to a hub. +user-invocable: false +--- + +# Corbits hub libraries + +Six libraries add features to an Interchange hub. They share one shape. + +## Shared pattern + +- Each exports `createXRoutes(deps)`, a Hono sub-app you mount with `app.route(...)` on `@intx/hub-api`, gated by `requireGrant` (from `createRequireGrant({ grantStore, conditionRegistry })`). +- Each has `runXMigrations(dbConfig, { schema })`. On every boot run `@intx/db`'s `runMigrations` first, then these. They are idempotent and advisory-locked, so replicas are safe. +- Each owns its own Postgres schema. `schema` is the host schema holding `tenant`, `principal`, and `credential`. +- Mount paths: `/api/tenants/:tenantId/`, with `artifacts` at `/api` and `webhooks` at `/api/hooks`. +- Agents reach them through a tool pack (`.../sidecar-bundle`) and run-scoped routes that use an agent token. + +## Pick one + +| Package | Reach for it when | Notes | +| ---------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `@corbits/cron` | An agent should run on a schedule. | Five-field UTC cron. No edit: delete and recreate. At most once per due minute. Pair with webhooks' deliverer. | +| `@corbits/webhooks` | An outside system should trigger a run. | Verifies Slack, Standard Webhooks, bearer. No unsigned mode. Mount outside session middleware. | +| `@corbits/artifacts` | Users or agents produce files or documents to keep. | Versioned. Bytes go through a pluggable `ContentStore` (`InlineContentStore` uses Postgres). No UI. | +| `@corbits/memory` | Agents need shared searchable memory. | Needs Postgres with pgvector, and falls back to full text (`degraded`). Tools: `memory_add`, `memory_search`, `memory_list`, `memory_feed`. | +| `@corbits/mailbox` | Humans need an inbox in the loop (approvals by mail). | For human principals. No UI and no transport: the host supplies `deliver`. | +| `@corbits/agent-token` | A deployed agent calls back into the hub. | Mint and revoke routes plus `requireAgentToken` middleware. Tokens last until revoked. | + +## Mount example + +```ts +import { + createCronRoutes, + createCronTicker, + createRunTriggerCronDeliver, +} from "@corbits/cron"; +import { runCronMigrations } from "@corbits/cron/migrations"; + +await runMigrations(dbConfig, { schema: "public" }); +await runCronMigrations(dbConfig, { schema: "public" }); +app.route( + `/api/tenants/:tenantId/cron`, + createCronRoutes({ db, requireGrant }), +); +createCronTicker({ + db, + deliver: createRunTriggerCronDeliver(deliverer), +}).start(); +``` + +Run one ticker per hub process. The best real wiring is upstream in `workbench/apps/hub/src/server.ts` and `migrate.ts` (note its older pins), and each README has a "Using with Interchange" section. + +## Standalone clients (no hub) + +- `@corbits/embedding`: `embedTexts(texts, { baseURL, model })` over any OpenAI-compatible `/v1/embeddings` (OpenAI, Ollama, TEI, vLLM, Jina). It does not store or search. +- `@corbits/reranking`: `rerankDocuments(query, docs, { baseURL, apiStyle: "tei" | "cohere" | "voyage" })` returns `{ id, score }[]`, best first. On failure keep the original order. + +## Grants + +Libraries declare the grants they need in `package.json` under `interchange.grantRequirements`. Give principals only what they need, for example `cron-schedule:*` create, `memory:search`, `artifact:*` create. + +## Need more + +- Triggering workflows from these: `use_skill interchange-workflows`. +- Chat over `@corbits/mailbox`: `use_skill interchange-chat`. +- A client UI for artifacts, mail, and runs: `use_skill corbits-ui-apps`. +- Composing a hub that mounts these: `use_skill interchange-embed-hub`. Topology and credentials: `use_skill interchange-run-modes`. +- Catalog: `use_skill corbits`. diff --git a/plugins/corbits-skills/skills/corbits-inference/SKILL.md b/plugins/corbits-skills/skills/corbits-inference/SKILL.md new file mode 100644 index 000000000..44aa2989a --- /dev/null +++ b/plugins/corbits-skills/skills/corbits-inference/SKILL.md @@ -0,0 +1,64 @@ +--- +name: corbits-inference +description: Add OpenAI Responses, Codex, xAI, or Ollama inference and OAuth login to Interchange with the Corbits provider packages. Load when wiring a model provider or a login flow. +user-invocable: false +--- + +# Corbits inference and login + +| Package | Use it for | +| --------------------------- | --------------------------------------------------------------------------------------- | +| `@corbits/openai-responses` | Any OpenAI Responses endpoint (`/v1/responses`). Backend differences are JSON `quirks`. | +| `@corbits/codex-provider` | ChatGPT subscription ("Login with ChatGPT") as inference. No API-key path exists. | +| `@corbits/xai-provider` | Grok through the grok CLI OAuth login. Those tokens only work on the CLI chat proxy. | +| `@corbits/ollama-adapter` | Local or cloud Ollama over `/v1/chat/completions` or `/v1/messages`. | +| `@corbits/oauth-core` | PKCE plus loopback OAuth login, token refresh, and hub login routes. | +| `@corbits/credential-http` | Origin-pinned credentials for any header (x-api-key, raw authorization, MCP). | + +Codex and xAI are built on `openai-responses` and `oauth-core`. Codex depends on the ChatGPT backend and is the most fragile. + +## Wire an adapter in process + +```ts +import { createDependencies, runInference } from "@intx/inference"; +import { + createOpenAIResponsesAdapter, + OPENAI_RESPONSES_PROVIDER, +} from "@corbits/openai-responses"; + +const deps = createDependencies({ + has: (p) => p === OPENAI_RESPONSES_PROVIDER, + resolve: (source, quirks) => createOpenAIResponsesAdapter(source, quirks), +}); +const source = { + id: "openai", + provider: OPENAI_RESPONSES_PROVIDER, + baseURL: "https://api.openai.com/v1", + credentialId: "OPENAI_API_KEY", + model: "gpt-5-mini", +}; +// runInference({ deps, source, turns, nextSeq, readMaterial: (id) => ({ secret: process.env[id]! }) }) +``` + +## Wire an adapter in a sidecar + +```bash +SIDECAR_ADAPTER_MANIFEST='[{"provider":"ollama","specifier":"@corbits/ollama-adapter","export":"createOllamaAdapter"}]' +``` + +The hub forwards this variable to sidecars it spawns. Codex uses `createCodexResponsesAdapter` with provider id `codex`. Ollama on `/v1/messages` uses the export `createOllamaAnthropicAdapter`. + +## Per-package notes + +- **Codex:** name your host with `CodexQuirks { productName, environmentTagName }`. Pass the account id as `providerOptions[CODEX_ACCOUNT_ID_OPTION]`. `createDependencies` binds global fetch, so build deps by hand to install `withCodexContentTypeRepair`. +- **xAI:** for API keys use `XAI_API_KEY_BASE_URL` (`https://api.x.ai/v1`). For the OAuth login use `XAI_OAUTH_PROXY_BASE_URL` and pass the user id option. +- **Ollama:** set `reasoning` per model in mixed fleets (Ollama rejects `reasoning_effort` on non-reasoning models). It ignores `num_ctx` on `/v1`, so start the server with `OLLAMA_CONTEXT_LENGTH`. +- **oauth-core:** `loginWithProvider(...)` for CLIs. On the hub, `mountOAuthLogin` and `createOAuthTokenRefresher` from `@corbits/oauth-core/hub`. A provider is `{ oauthConfig, exchange, refresh }`, supplied by a package like codex or xai. +- **Peer ranges:** codex and xai currently peer on `oauth-core@^0.2.0` and `openai-responses@^0.2.0`, but oauth-core is 0.3.0. Check peer warnings before installing them together. + +## Need more + +- Typed decisions instead of chat (routing, gating): `use_skill corbits-system-one`. +- MCP servers and their credentials: `use_skill corbits-tools`. +- How sources and failover work in an agent: `use_skill interchange-agents`. +- Catalog: `use_skill corbits`. diff --git a/plugins/corbits-skills/skills/corbits-system-one/SKILL.md b/plugins/corbits-skills/skills/corbits-system-one/SKILL.md new file mode 100644 index 000000000..6480c761f --- /dev/null +++ b/plugins/corbits-skills/skills/corbits-system-one/SKILL.md @@ -0,0 +1,65 @@ +--- +name: corbits-system-one +description: Use @corbits/system-one for fast typed decisions (choice, score, yes/no) over a JSON state. Load when adding routing, gating, or triage in front of an agent. +user-invocable: false +--- + +# Corbits System One + +`@corbits/system-one` is a client for TypeSafe's Jev model. It is not a chat model and never generates text. You send a JSON `state` plus questions with unique ids, and you get one validated decision per id. + +| Question type | You supply | Decision comes back as | +| ------------------- | ---------------------------------------------- | ------------------------------------------------- | +| `choice` | `criteria`: option name to description | `choice`, `probabilities`, `confidence` | +| `score` | `criteria`: 2 to 10 ordered level descriptions | `score`, `legend`, `probabilities` | +| `boolean` or `noul` | optional `criteria: { true?, false? }` | `noul`: probability 0 to 1 that the answer is yes | + +## Use + +```ts +import { evaluate } from "@corbits/system-one"; + +const result = await evaluate({ + state: { action: "drop-database", env: "production", approvals: 0 }, + questions: [ + { + id: "route", + type: "choice", + instructions: "What permission decision does this warrant?", + criteria: { allow: "Low-risk request", deny: "Refuse the request" }, + }, + { + id: "escalate", + type: "boolean", + instructions: "Must this be escalated for human approval?", + }, + ], + config: { timeoutMs: 15_000 }, +}); +if (result.fallback) return failClosed(result.reason); +const [route, escalate] = result.decisions; +``` + +- Key: `TYPESAFE_API_KEY` (official endpoint). The `gateway` endpoint uses `AI_GATEWAY_API_KEY`. `SYSTEM_ONE_API_KEY` is an alias on all of them. +- Failures are data. `evaluate` returns `{ fallback: true, reason }` for `no-key`, `timeout`, `network`, `http-error`, or `parse-error`, and throws only on invalid caller input. Branch on `result.fallback` and fail closed for gates. +- The default timeout is 1500 ms. No latency or pricing is published, so measure both yourself using the returned `latencyMs` and `usage`. +- One POST carries every question, so ask all your questions for a state in one call. +- `exactOptionalPropertyTypes` is on: omit optional keys instead of passing `undefined`. + +## As an Interchange adapter + +Register `createSystemOneAdapter()` under `SYSTEM_ONE_PROVIDER`. Pass questions per call with `inferenceOptions.providerOptions.systemOne = { state?, questions? }`. The adapter emits one `inference.text.delta` per decision (the token is decision JSON). A malformed body on this path is a `ProtocolMismatchError`, not a fallback. + +## Good uses + +- A permission or escalation gate before a risky tool call (from the package's own examples). +- Routing or classifying a request before an agent runs, for example a `choice` between a cheap model, a strong model, and a specialist. Use `probabilities` to fall back to a default when confidence is low. This is an inference from the API shape, not a documented feature. +- Structured triage: intent, risk, and needs-human in one round trip. + +Do not use it for generation, summaries, or tool-calling loops. + +## Need more + +- Upstream README in corbitsdev/corbits-system-one and the wire contract at https://docs.typesafe.ai. +- Chat inference providers: `use_skill corbits-inference`. +- Catalog: `use_skill corbits`. diff --git a/plugins/corbits-skills/skills/corbits-tools/SKILL.md b/plugins/corbits-skills/skills/corbits-tools/SKILL.md new file mode 100644 index 000000000..423d0fa55 --- /dev/null +++ b/plugins/corbits-skills/skills/corbits-tools/SKILL.md @@ -0,0 +1,77 @@ +--- +name: corbits-tools +description: Give an Interchange agent remote MCP tools, Gmail, or Granola with @corbits/mcp, credential-http, google-tools, and granola. Load when adding MCP servers or third-party tools to an agent. +user-invocable: false +--- + +# Corbits tool packages + +Tools reach an agent as sidecar bundles listed in `tools` on `defineAgent`. The agent never holds the secret: the sidecar resolves a credential by handle and sends requests through an origin-pinned fetch. + +## `@corbits/mcp` + +Each tool on a remote MCP server (streamable HTTP) becomes its own agent tool named `.`, so grants apply per tool. + +```ts +import { mcpListTools } from "@corbits/mcp"; +import { mcpServers } from "@corbits/mcp/sidecar-bundle"; + +const url = "https://mcp.deepwiki.com/mcp"; +const bundle = mcpServers({ + servers: [ + { + handle: "deepwiki", + url, + tools: await mcpListTools(url), + allowWithoutAsk: ["deepwiki.read_wiki_structure"], + }, + ], +}); +``` + +- Grants use the resource `tool:.` or `tool:.*`. Deny beats ask beats allow. Handles may not contain ".". +- Every generated tool starts as `ask`. Tools with `destructiveHint: true` can never be lowered to `allow`. +- The handle names a credential. Auth mode lives in credential `metadata.mcp.auth`: `none`, `token`, or `oauth` (login through `@corbits/oauth-core`). +- Hub side: `mountMcpDiscovery` from `@corbits/mcp/hub` adds `POST /mcp/discover`. +- Responses and frames are capped at 4 MiB, and `timeoutMs` defaults to 60 s. + +## `@corbits/credential-http` + +Interchange's built-in `http` credential provider only sends `authorization: Bearer`. This package adds other headers, pinned to the credential's origin, with no redirects and a fresh secret read per call. + +```ts +const registry = createCredentialProviderRegistry([ + ...builtinCredentialProviders(), + createXApiKeyCredentialProvider(), +]); +``` + +Presets: `createXApiKeyCredentialProvider`, `createRawAuthorizationCredentialProvider`, `createMcpStreamableHttpCredentialProvider` (keyless MCP servers use `MCP_NO_TOKEN_SENTINEL`). Then create a provider, a credential, and a grant through the hub REST API. + +## `@corbits/google-tools` + +Gmail only: ten tools (search, get thread or message, list labels, create or list drafts, label and unlabel). Drafts are never sent. Every tool is `approval: "ask"`. + +```ts +import { gmail } from "@corbits/google-tools/sidecar-bundle"; +defineAgent({ + id: "inbox-agent", + systemPrompt, + tools: [gmail], + capabilities: [], + inference, +}); +``` + +Store the user's Google credential on the hub as `gmail-api` (scope `gmail.modify`) and grant it to the agent. + +## `@corbits/granola` + +Early. The npm name is `@corbits/granola` (repo `granola-tools`) and it may not be on npm yet (`bun add github:corbitsdev/granola-tools`, pin a commit). Its two tool handlers currently throw "not implemented". Use the REST client and ingest pipeline only, and verify before depending on it. + +## Need more + +- Credentials and push model: `use_skill interchange-run-modes`. +- OAuth login: `use_skill corbits-inference`. +- Building the agent around these tools: `use_skill interchange-agents`. +- Catalog: `use_skill corbits`. diff --git a/plugins/corbits-skills/skills/corbits-ui-apps/SKILL.md b/plugins/corbits-skills/skills/corbits-ui-apps/SKILL.md new file mode 100644 index 000000000..6855e7bf8 --- /dev/null +++ b/plugins/corbits-skills/skills/corbits-ui-apps/SKILL.md @@ -0,0 +1,39 @@ +--- +name: corbits-ui-apps +description: Build agent UIs with @corbits/react-ui and find the reference apps (workbench, Solution Builder) that show everything wired together. Load when building a chat, run, or approval UI. +user-invocable: false +--- + +# Corbits UI and reference apps + +## `@corbits/react-ui` + +Props in, markup out React components for agent products. They fetch nothing: you pass data from your hub client. Tailwind v4 theme. Stateful modules are marked `"use client"`. + +```tsx +import "@corbits/react-ui/styles.css"; +import { ThemeProvider, ChatThread } from "@corbits/react-ui"; + + + +; +``` + +- CSS: import `styles.css` once (includes preflight), or `theme.css` if you already run Tailwind v4. Never both. Fonts are not bundled. Dark mode is the `.dark` class. +- Message parts are `{ type: "text" | "reasoning" | "tool", ... }`. Roles are `user`, `agent`, and `system`, and parts also include `file`. A tool part carries `toolCallId`, `toolName`, `label`, `state`, `output`. +- Components: chat (`ChatThread`, `ChatComposer`, `ToolBlock`, `ReasoningBlock`), runs (`ApprovalCard`, `GateBlock`, `StepList`, `LiveRunBanner`, `TraceWaterfall`), artifacts (`ArtifactBody`, `CsvTable`), charts, and layout shells. +- Dialog, menu, tooltip, toast, and command palette live on subpaths (`ui/dialog`, `ui/menu`, ...) because they need optional peers (Radix, sonner). +- Needs React 18.2+ or 19. + +Feed it from your own typed hub client (`use_skill interchange-hub-setup`; `@intx/hub-client` is private) and the hub libraries (`use_skill corbits-hub-libs`). For chat data, `use_skill interchange-chat`. + +## Reference apps (private, read them, do not depend on them) + +- **workbench** (`corbitsdev/workbench`): a multiplayer workspace for people and agents, built on Corbits. `apps/hub` composes every hub library (see `server.ts` and `migrate.ts`), `apps/web` is the React client, `apps/sidecar` is the execution host. It pins older git SHAs of some libraries, so when a call differs from a library README, trust the README. Run with Bun plus Postgres 17 with pgvector: `bun install`, copy `.env.example`, `bun run dev`. +- **Solution Builder** (`corbitsdev/corbits-solution-builder`): a desktop app (Tauri over a local Bun host) that takes a problem to shipped software through nine human-gated stages, using Interchange as an embedded or remote hub. It is the reference client-driven app: the app owns first-run setup (owner account, tenants, grants, provider credentials, workflow assets, deploys) through `packages/installer` over a stock hub, and `packages/embed-hub` runs that hub in process on pglite. Start there (`use_skill interchange-hub-setup`, `use_skill interchange-embed-hub`). Stage 8 (bounded build), delivery evidence, and signing are unfinished. `solutions-builder-alpha` is an older snapshot. + +## Need more + +- An app that sets up and drives its own hub: `use_skill interchange-client-apps`. Hosting the hub: `use_skill interchange-embed-hub`. Chat and run status: `use_skill interchange-chat`. +- Mounting the libraries the UI reads from: `use_skill corbits-hub-libs`. +- Catalog: `use_skill corbits`. diff --git a/plugins/corbits-skills/skills/corbits/SKILL.md b/plugins/corbits-skills/skills/corbits/SKILL.md new file mode 100644 index 000000000..6c943f756 --- /dev/null +++ b/plugins/corbits-skills/skills/corbits/SKILL.md @@ -0,0 +1,41 @@ +--- +name: corbits +description: Catalog of the @corbits/* packages and which one to use. Load when a task mentions a Corbits package, or needs inference providers, MCP, memory, cron, webhooks, or agent UI on Interchange. +user-invocable: false +--- + +# Corbits packages + +Corbits publishes packages that plug into Interchange (`use_skill interchange`). Repos live at https://github.com/corbitsdev. Every package is 0.x, so a minor bump can break you, and each README has an "Upgrading from 0.1" section. License is LGPL-2.1. Runtime is Node 24+ or Bun 1.2+. + +## Install rules + +- `@intx/*` packages are peer dependencies pinned `^0.4.0` (this excludes 0.5). The host must resolve exactly one copy. Prefer the published packages. Vendoring is an escape hatch with a patch ledger (Corbits Code, Solution Builder, and workbench each do it), so a consumer library never uses `workspace:`. +- Trust each package's README and `package.json` over the workbench app, which pins older git SHAs. + +## Pick a package + +| Need | Package | Skill | +| ---------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------ | +| OpenAI Responses, Codex login, xAI login, Ollama | `@corbits/openai-responses`, `codex-provider`, `xai-provider`, `ollama-adapter` | `use_skill corbits-inference` | +| OAuth login (PKCE) and token refresh | `@corbits/oauth-core` | `use_skill corbits-inference` | +| Typed yes/no, choice, or score decisions from a JSON state | `@corbits/system-one` | `use_skill corbits-system-one` | +| Remote MCP servers as granted tools | `@corbits/mcp`, `@corbits/credential-http` | `use_skill corbits-tools` | +| Gmail tools, Granola | `@corbits/google-tools`, `@corbits/granola` | `use_skill corbits-tools` | +| Cron, artifacts, memory, mailbox, webhooks, agent tokens | `@corbits/cron`, `artifacts`, `memory`, `mailbox`, `webhooks`, `agent-token` | `use_skill corbits-hub-libs` | +| Embeddings and reranking (no hub needed) | `@corbits/embedding`, `@corbits/reranking` | `use_skill corbits-hub-libs` | +| React components for chat, runs, approvals | `@corbits/react-ui` | `use_skill corbits-ui-apps` | +| A full reference app | workbench, Solution Builder (both private) | `use_skill corbits-ui-apps` | + +Not an npm package: `subcritical` (Go, eBPF audit and sandbox for tool calls) is unreleased and unstable. Do not plan on it. + +## How they plug in + +- Inference packages are `@intx/inference` provider adapters. In process they go through `createDependencies`. In a sidecar they load through `SIDECAR_ADAPTER_MANIFEST`. +- Hub libraries are Hono sub-apps mounted on `@intx/hub-api`, gated by `requireGrant`, and they run their own migrations after `@intx/db`'s. +- Tool packages are sidecar bundles (`.../sidecar-bundle`) that an agent definition lists in `tools`. + +## Need more + +- Interchange concepts and run modes: `use_skill interchange`. +- Each skill above ends with the upstream README to read for full reference. diff --git a/src/telemetry/classify.ts b/src/telemetry/classify.ts index b453a5b68..a60cdb5c7 100644 --- a/src/telemetry/classify.ts +++ b/src/telemetry/classify.ts @@ -83,6 +83,12 @@ const BUILT_IN_AGENT_NAMES: ReadonlySet = new Set([ // never a leak). Project- or plugin-authored skills are never reported by // name. const FIRST_PARTY_SKILL_NAMES: ReadonlySet = new Set([ + "corbits", + "corbits-hub-libs", + "corbits-inference", + "corbits-system-one", + "corbits-tools", + "corbits-ui-apps", "docs", "git-worktrees", "implement",