diff --git a/.delegate/launch.sh b/.delegate/launch.sh new file mode 100755 index 00000000..9dc5ff0f --- /dev/null +++ b/.delegate/launch.sh @@ -0,0 +1,71 @@ +#!/bin/sh +export DELEGATE_LABEL="agy-perms-hooks" +exec 'agy' '-i' 'SPEC: Make Matrix the only In-use view for Permissions + Hooks + +1. OBJECTIVE +Remove the Cards/Board view options from the Permissions In-use page and the Hooks In-use page +so the Matrix view is the sole, always-rendered view. Delete the now-dead code. + +2. CONTEXT +- Repo root = your worktree CWD (a git worktree off `main`). All paths below are relative to it. +- You own ONLY these two features: `frontend/src/features/permissions/**` and + `frontend/src/features/hooks/**`. Do NOT touch any other feature, `components/`, `lib/`, or + the Python backend. +- The Matrix components ALREADY EXIST and must be kept: + `frontend/src/features/permissions/components/PermissionsMatrixView.tsx` + `frontend/src/features/hooks/components/HooksMatrixView.tsx` +- Shared files you must NOT delete or edit (the orchestrator removes them later, after all + branches merge): `frontend/src/components/ViewModeToggle.tsx`, + `frontend/src/lib/usePersistentViewMode.ts`. +- node_modules is symlinked into `frontend/node_modules` for you; npm commands work from repo root. + +Files that carry the view toggle today: + Permissions page: frontend/src/features/permissions/screens/PermissionsInUsePage.tsx + hook: frontend/src/features/permissions/model/usePermissionsInUseViewMode.ts (DELETE) + dead: frontend/src/features/permissions/components/PermissionCardList.tsx (DELETE) + + any component/i18n/test used ONLY by it + Hooks page: frontend/src/features/hooks/screens/HooksInUsePage.tsx + hook: frontend/src/features/hooks/model/useHooksInUseViewMode.ts (DELETE) + dead: frontend/src/features/hooks/components/HookCardList.tsx (DELETE) + frontend/src/features/hooks/components/board/HooksBoard.tsx (DELETE whole board/ dir) + + any component/i18n/test used ONLY by those + +Per page, do exactly this: + a. Remove the render, the `viewModeOptions` array, the `useXViewMode()` + call, and all `viewMode === ...` branching. Render the Matrix component unconditionally + wherever rows exist (keep the loading / error / empty-state branches intact). + b. KEEP all search + filter UI (FilterBar, any filter/pill menu) — those are NOT view modes. + If a filter was gated behind `viewMode === "cards"`, make it always shown. + c. Delete the dead view components listed above and any files (subcomponents, tests, i18n + `viewModes`/`viewModeAria` keys, unused lucide icon imports like Columns3/Grid2X2) that + become unreferenced as a result. No dead code, no unused imports may remain. + d. Delete the section'\''s `useXViewMode.ts` hook file and its test if present. + +3. DEFINITION OF DONE (I will run these exact checks myself in your worktree) +- `grep -rn "ViewModeToggle" frontend/src/features/permissions frontend/src/features/hooks` → NO output +- `grep -rn "usePermissionsInUseViewMode\|useHooksInUseViewMode\|PermissionsInUseViewMode\|HooksInUseViewMode" frontend/src` → NO output +- `grep -rn "PermissionCardList\|HookCardList\|HooksBoard" frontend/src` → NO output +- `git status` shows the useXViewMode hooks and the dead components as deleted. +- `npm run typecheck` exits 0 +- `npm test` passes (update/remove tests that referenced removed views; do NOT weaken unrelated tests) +- `npm run build` exits 0 +- Manual read: PermissionsInUsePage.tsx and HooksInUsePage.tsx render only the Matrix view; search/filter UI preserved. + +4. ESCALATION — stop and ask me (via reverse channel) instead of guessing if: +- Removing a view forces changing shared/global files outside your two features. +- A matrix component is missing an affordance the deleted card/board had and it'\''s unclear where it should live. +- A test failure implies a behavior change you'\''re unsure is intended. +- The real change is materially bigger than this spec implies. + +5. REVERSE CHANNEL — to reach me, run ONE command from your worktree: + ./.delegate/notify needs-input "the question or decision you need answered" + ./.delegate/notify blocked "what you are stuck on" + ./.delegate/notify done "summary of what you finished" + then STOP AND WAIT at your prompt — do not exit, do not continue. I will review and either + confirm or send corrections. After I reply, run `./.delegate/notify resume` before continuing. + +6. OUTPUT — on finish: run `./.delegate/notify done ""`, then STOP AND WAIT. Do not exit. + +7. SCOPE BOUNDARY — stay in your worktree; touch only features/permissions and features/hooks + (plus their tests). Do NOT edit ViewModeToggle.tsx / usePersistentViewMode.ts / other features / + backend. Do NOT push, open PRs, or run any git merge. Make small logical commits on your branch.' '--add-dir' '/Users/hgill/projects/skill-manager-worktrees/agy-perms-hooks' '--dangerously-skip-permissions' '--model' 'gemini-3.1-pro-high' diff --git a/.delegate/notify b/.delegate/notify new file mode 100755 index 00000000..ab0412e4 --- /dev/null +++ b/.delegate/notify @@ -0,0 +1,55 @@ +#!/bin/sh +# notify — reverse-channel helper for a DELEGATED agent. Copied into each +# delegate's worktree as ./.delegate/notify by `spawn`. Run it from the worktree. +# +# Usage: +# ./.delegate/notify needs-input "the question or decision you need answered" +# ./.delegate/notify blocked "what you are stuck on" +# ./.delegate/notify done "summary of what you finished (orchestrator re-verifies)" +# ./.delegate/notify resume # AFTER the orchestrator replies, before you continue working +# +# It does two things so the orchestrator both wakes instantly AND gets full content: +# 1. sets your herdr agent status (event-driven, ~ms wake) via report-agent +# 2. writes the full message to ./.delegate/signal (the orchestrator polls this) +# herdr injects $HERDR_PANE_ID into your pane; $DELEGATE_LABEL is set by spawn. +# +# IMPORTANT: a reported `blocked` is sticky and suppresses herdr's real detection +# until cleared. After the orchestrator answers, run `notify resume` (or it will +# sit falsely blocked forever). + +set -u + +kind="${1:-}" +[ "$#" -gt 0 ] && shift +msg="${*:-}" + +here="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" # the .delegate dir +sigfile="$here/signal" +label="${DELEGATE_LABEL:-delegate}" +pane="${HERDR_PANE_ID:-}" + +report() { # report + [ -n "$pane" ] || return 0 + herdr pane report-agent "$pane" --source delegate-protocol --agent "$label" \ + --state "$1" --custom-status "$2" >/dev/null 2>&1 || true +} + +headline() { printf '%s' "$1" | tr '\n' ' ' | cut -c1-72; } + +case "$kind" in + needs-input) + report blocked "NEEDS-INPUT: $(headline "$msg")" + printf '<> %s\n' "$msg" > "$sigfile" ;; + blocked) + report blocked "BLOCKED: $(headline "$msg")" + printf '<> %s\n' "$msg" > "$sigfile" ;; + done) + # no reportable `done` state; completion rides the file + quiescence + printf '<> %s\n' "$msg" > "$sigfile" ;; + resume) + report working "resumed" + : > "$sigfile" ;; + *) + echo "usage: notify {needs-input|blocked|done|resume} [message]" >&2 + exit 2 ;; +esac diff --git a/.delegate/signal b/.delegate/signal new file mode 100644 index 00000000..c1d5fb76 --- /dev/null +++ b/.delegate/signal @@ -0,0 +1 @@ +<> 62 test files passed, 263 tests passed diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..a76dad41 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,41 @@ +version: 2 +updates: + # Frontend (and dev tooling) JavaScript dependencies. + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 10 + groups: + react: + patterns: + - "react" + - "react-dom" + - "@types/react" + - "@types/react-dom" + radix: + patterns: + - "@radix-ui/*" + testing: + patterns: + - "@testing-library/*" + - "vitest" + - "jsdom" + commit-message: + prefix: chore(deps) + # Python runtime + build dependencies. + - package-ecosystem: pip + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 10 + commit-message: + prefix: chore(deps) + # GitHub Actions used by the CI and Release workflows. + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 10 + commit-message: + prefix: chore(ci) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05ba31b6..cd451973 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,9 +36,9 @@ jobs: - "3.13" - "3.14" steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - - uses: actions/setup-python@v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: ${{ matrix.python-version }} @@ -48,19 +48,30 @@ jobs: ./.venv/bin/python -m pip install --upgrade pip ./.venv/bin/pip install -r requirements.txt + - name: Install dev dependencies + run: ./.venv/bin/pip install -r requirements-dev.txt + + - name: Backend lint + run: ./.venv/bin/ruff check skill_manager tests + + - name: Python dependency audit + run: | + ./.venv/bin/pip install pip-audit + ./.venv/bin/pip-audit + - name: Backend compatibility tests run: bash scripts/test_backend.sh frontend-validate: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - - uses: actions/setup-python@v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.11" - - uses: actions/setup-node@v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: node-version: "20" cache: "npm" @@ -73,6 +84,9 @@ jobs: - name: Install Node dependencies run: npm ci + - name: Dependency audit + run: npm run audit:check + - name: Check version sync run: ./.venv/bin/python scripts/sync_version.py --check @@ -115,13 +129,13 @@ jobs: runner: ubuntu-24.04-arm homebrew: false steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - - uses: actions/setup-python@v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.11" - - uses: actions/setup-node@v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: node-version: "20" cache: "npm" @@ -155,7 +169,7 @@ jobs: bash scripts/validate_homebrew_formula.sh "$VERSION" "$ARTIFACT" - name: Upload packaged artifacts - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: package-smoke-${{ matrix.target }} path: .artifacts/release/* diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ab961914..ffbd2e08 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,14 +30,14 @@ jobs: runner: ubuntu-24.04-arm homebrew: false steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - - uses: actions/setup-python@v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: # Release packaging stays on one stable builder version. python-version: "3.11" - - uses: actions/setup-node@v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: node-version: "20" cache: "npm" @@ -73,7 +73,7 @@ jobs: bash scripts/validate_homebrew_formula.sh "$VERSION" "$ARTIFACT" - name: Upload packaged artifacts - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: release-${{ matrix.target }} path: .artifacts/release/* @@ -83,16 +83,16 @@ jobs: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - - uses: actions/download-artifact@v8 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: path: .artifacts/release pattern: release-* merge-multiple: true - name: Publish GitHub Release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 with: files: .artifacts/release/* @@ -101,14 +101,14 @@ jobs: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - - uses: actions/setup-python@v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: # Publishing tooling stays pinned even though runtime compatibility is validated in CI. python-version: "3.11" - - uses: actions/setup-node@v6 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: node-version: "20" registry-url: "https://registry.npmjs.org" @@ -133,14 +133,14 @@ jobs: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - - uses: actions/setup-python@v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: # Formula rendering is deterministic on the same stable builder version. python-version: "3.11" - - uses: actions/download-artifact@v8 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: path: .artifacts/release pattern: release-* @@ -167,7 +167,7 @@ jobs: run: ruby -c .artifacts/release/skill-manager.rb - name: Upload Homebrew formula artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: homebrew-formula path: .artifacts/release/skill-manager.rb diff --git a/.gitignore b/.gitignore index b5959138..43553036 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,15 @@ packaging/npm/vendor/ task_plan.md findings.md progress.md + +# macOS +.DS_Store + +# Local tool state — machine-specific, expensive to rebuild, never shared +.codegraph/ +.rtk/ + +# Per-agent instruction files generated by local tooling (rtk init and friends). +# Shared working agreements belong in CLAUDE.md; these do not. +.clinerules +.agents/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..6c294a7a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,77 @@ +# skill-manager — working agreement + +This is **our fork** of skill-manager. Read this before doing any git or delegation work. + +## Remotes + +- `fork` → `execsumo/skill-manager` — **ours**. This is where we develop and ship. +- `origin` → `mode-io/skill-manager` — **upstream**. Contributing back is optional. + +## Branch strategy — fork `main` is the cumulative trunk + +`fork/main` is the single line where everything accumulates. It only grows; it always +contains every shipped feature (agy harness, light mode, hooks, …). **Run the app off `main`.** + +- New work = a **short-lived** branch off `main` → merge **back into `main`** when done → delete the branch. +- Do **not** keep long-lived feature branches. They drift from `main` and from the running + instance (this is how light mode "disappeared" once — the checkout was parked on a side branch). +- Commit/push to `main` or a short-lived feature branch. Never develop on a throwaway extract branch. +- Land features into `main` promptly so there is nothing to "keep cumulative" — it just is. + +## Contributing upstream (mode-io) — opt-in and isolated + +**Default: don't.** The fork is a complete product on its own. Only extract an upstream PR when +there is a real reason (you want mode-io to maintain/ship it). It is occasional, not per-feature. + +When you do, **never switch this checkout to an upstream-extract branch** — that strips fork-only +features (light mode, etc.) and breaks the running instance. Do it in a separate worktree so the +main checkout never moves: + +```bash +git worktree add ../skill-manager-upstream origin/main +cd ../skill-manager-upstream +git cherry-pick # keep it a clean subset +git push fork +gh pr create --repo mode-io/skill-manager --base main --head execsumo: +cd - && git worktree remove ../skill-manager-upstream +``` + +Keep the upstream PR a focused subset; do not bundle unrelated fork features into it. + +## Running the app + +Serve/run from `main`. After switching branches or building on a different branch, rebuild so +`frontend/dist` matches the source, then hard-refresh / restart the instance: + +```bash +npm run build +``` + +## Delegating development (herdr + agy) + +We work inside **herdr** (`HERDR_ENV=1`) — use the `ogulcancelik--herdr` skill. Delegate +substantial implementation to the **`agy`** agent running in another pane: + +- Check for an agy pane with `herdr pane list`. If one exists, send the brief with + `herdr pane run ""`. +- **If no agy pane exists, create one**: split a pane (`herdr pane split --direction right --no-focus`) + and run `agy` in it, then delegate to it. +- Give agy a **complete written brief** (a `/tmp/.md` file works well, then point agy at it): + the task, the branch to use (short-lived off `main`, per the strategy above), git discipline + (logical commits, push, **no merge to main without review**), and a **mandatory** pressure-test + plus the full validation suite. +- **Monitor by exception.** Watch agy's herdr `agent_status`: `blocked` → grant the permission or + answer; `idle`/`done` are unreliable instantaneously (agy flaps and reports `done` while waiting + on its own subprocess) — only act on **sustained** quiescence, and **read the pane to confirm it + actually finished** before trusting it. +- **Always independently verify agy's work** before reporting it done — re-run the validation suite + yourself and spot-check the diff. Do not relay agy's pass counts on faith. + +## Validation suite + +```bash +npm run typecheck +bash scripts/test_backend.sh +npm test +npm run build +``` diff --git a/README.md b/README.md index ac2a750f..9dc0766c 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,12 @@ # skill-manager -[中文说明](README.zh-CN.md) -

Skill Manager

A local-first control center for AI extensions.
- Use, review, scan, and discover Skills, MCP servers, slash commands, and CLI tools across agent harnesses. + Use, review, and discover Skills, Agents, MCP servers, slash commands, hooks, and CLI tools across agent harnesses.

@@ -30,16 +28,17 @@ AI extensions are scattered across harness-specific folders, MCP config files, s |---|---| | **In use** | Skill Manager controls the item and can enable or disable it across harnesses. | | **Needs review** | Skill Manager found local state, config differences, or inventory issues that need a decision. | -| **Scan** | Run LLM-backed security checks against Skills before trusting them. | | **Discover** | Browse marketplaces and preview external tools. | ## What you can do - See what is in use, what needs review, and where extensions are active. - Adopt local Skills into one shared inventory, then enable or disable them per harness. -- Scan Skills with a saved LLM provider configuration and review findings before use. - Install or adopt MCP server configs, resolve differences, and enable them where supported. - Manage reusable slash commands once, then sync them to supported harnesses. +- Manage hooks as normalized records, then sync them into supported harness settings with drift detection and review for unmanaged entries. +- Manage Agents — agents are markdown files in the store that get symlinked into each harness's agents directory, with In Use and Needs Review views like every other family. +- Keep everything in portable packages: the default `local` package holds your own resources, and additional packages can be dropped in (or deactivated) as a unit. - Discover Skills, MCP servers, and preview-only CLI tools from marketplace sources. ## Product tour @@ -63,23 +62,6 @@ Typical flow: ![skill-market-skill-matrxi](./assets/skill-manager-skill-matrix.png) -### Skill scanning - -Scan Skills with an LLM-backed security review before you rely on them. - -Typical flow: - -1. Add and validate an LLM scan configuration. -2. Switch Skills in use to the Scan view. -3. Run a scan for one Skill, selected Skills, or the full visible list. -4. Review severity, findings, snippets, and remediation guidance. - -![skill-manager-scan-view](./assets/skill-manager-scan-view.svg) - -Scan configurations are managed separately so you can save multiple providers, choose one active configuration, and keep API keys masked in list views. - -![skill-manager-scan-config](./assets/skill-manager-scan-config.svg) - ### MCP servers Use MCP servers as one normalized config that can be written into each harness shape. @@ -106,6 +88,16 @@ Typical flow: ![skill-market-slash-commands-matrix](./assets/skill-manager-slash_commands-matrix.png) +### Agents + +Subagents you keep in one place instead of copy-pasting between harnesses. + +Typical flow: + +1. Write an agent — a name, a description, and a system prompt — or adopt one Skill Manager found in a harness. +2. Turn it on for the harnesses that should have it. +3. Review agents discovered in harness directories and adopt the ones worth keeping. + ### Marketplace Marketplace is the discovery surface: @@ -140,15 +132,20 @@ Native release artifacts are published on GitHub Releases for macOS ARM64/x64 an + @@ -173,14 +170,23 @@ Native release artifacts are published on GitHub Releases for macOS ARM64/x64 an
+ Claude Code
+ Claude Code
+ Docs +
Codex CLI
Codex CLI
Docs
- Claude Code
- Claude Code
- Docs + Antigravity CLI
+ Antigravity (agy)
+ Docs
Cursor
@@ -161,7 +158,7 @@ Native release artifacts are published on GitHub Releases for macOS ARM64/x64 an Docs
- Hermes Agent
+ Hermes Agent
Hermes Agent
Docs
-| Harness | Skills | MCP servers | Slash commands | -|---|---:|---:|---:| -| Codex CLI | Yes | Yes | Yes | -| Claude Code | Yes | Yes | Yes | -| Cursor | Yes | Yes | Yes | -| OpenCode | Yes | Yes | Yes | -| Hermes Agent | Yes | Yes | Not Yet | -| OpenClaw | Yes | Not Yet | Not Yet | +Harnesses appear in this order everywhere in the app — Settings, and every resource +matrix. The order is declared once, in `SUPPORTED_HARNESS_DEFINITIONS` +(`skill_manager/harness/catalog.py`); every family derives its columns from it, so there +is no per-page ordering to keep in sync. A harness switched off in Settings is dropped +from every matrix rather than shown as an inert column. + +| Harness | Skills | MCP servers | Slash commands | Hooks | +|---|---:|---:|---:|---:| +| Codex CLI | Yes | Yes | Yes | Yes | +| Claude Code | Yes | Yes | Yes | Yes | +| Cursor | Yes | Yes | Yes | Yes | +| OpenCode | Yes | Yes | Yes | Partial | +| Hermes Agent | Yes | Yes | Yes* | Not Yet | +| OpenClaw | Yes | Not Yet | Not Yet | Not Yet | +| Antigravity (agy) | Yes | Yes | Not Yet | Partial | + +\* Hermes Agent slash-command support is provisional. Its slash-command directory (`~/.hermes/commands`, frontmatter Markdown) follows common conventions but is **not yet verified against a shipping Hermes build**; hooks are not yet mapped. See `handoff.md`. ## Local-first safety @@ -192,18 +198,25 @@ Actions that can change local state include: - enabling or disabling a skill for a harness - updating a source-backed skill - removing or deleting a skill -- creating, updating, validating, activating, or deleting an LLM scan configuration -- running a Skill scan, which sends selected Skill context to the configured LLM provider - installing an MCP server into a selected harness config - adopting an existing MCP config - enabling, disabling, resolving, or uninstalling an MCP server - creating, updating, syncing, importing, or deleting a slash command +- creating, enabling, disabling, resolving, or deleting a hook binding - changing harness support settings -App-owned files live under `~/Library/Application Support/skill-manager` on macOS and XDG base directories on Linux. +App-owned files live under `~/.skill-manager` on macOS (with a legacy fallback to `~/Library/Application Support/skill-manager` if it already exists) and XDG base directories on Linux. ## How it works +### Packages + +All Skill Manager resources live inside packages under the app's `packages/` directory. Each package carries a `package.json` (`slug`, `name`, `version`, `mutable`, `active`) plus per-family content (`skills/`, `agents/`, and a skills `manifest.json`). There is always a default `local` package — the mutable workspace where your own resources live. Additional packages are just directories: drop one in to install it, set `active: false` to disable it, and mark it `mutable: false` to protect shared content from accidental edits (the API rejects writes into immutable packages). + +Resource identity stays stable (content-derived refs), while `/` aliases give human-readable references; agent compilation resolves aliases and pins them. If two packages provide the same resource, the `local` package wins and the collision is reported as an inventory issue. + +On first start after upgrading, the legacy shared store (`shared/` + top-level `manifest.json`) is migrated one-time into `packages/local/` — the migration is locked, idempotent, and skipped when the new layout already exists. + ### Skills Before adoption, each harness points at its own local skill folder. After adoption, Skill Manager keeps one canonical package in its shared local store and exposes it to selected harnesses with local links. Disabling a harness removes that harness binding without deleting the package. @@ -214,14 +227,6 @@ Hermes Agent Skills use the categorized Hermes layout under `~/.hermes/skills//agents` +- MCP manifest: `~/.skill-manager/mcp/manifest.json` +- hooks manifest: `~/.skill-manager/hooks/manifest.json` +- slash command library: `~/.skill-manager/slash-commands/commands` +- slash command sync state: `~/.skill-manager/slash-commands/sync-state.json` +- marketplace cache: `~/.skill-manager/marketplace` +- app database: `~/.skill-manager/skill-manager.db` +- app settings: `~/.skill-manager/settings.json` Useful Linux paths: -- shared skills store: `${XDG_DATA_HOME:-~/.local/share}/skill-manager/shared` +- packages root: `${XDG_DATA_HOME:-~/.local/share}/skill-manager/packages` +- shared skills store: `${XDG_DATA_HOME:-~/.local/share}/skill-manager/packages/local/skills` +- agents: `${XDG_DATA_HOME:-~/.local/share}/skill-manager/packages//agents` - MCP manifest: `${XDG_DATA_HOME:-~/.local/share}/skill-manager/mcp/manifest.json` +- hooks manifest: `${XDG_DATA_HOME:-~/.local/share}/skill-manager/hooks/manifest.json` - slash command library: `${XDG_DATA_HOME:-~/.local/share}/skill-manager/slash-commands/commands` - slash command sync state: `${XDG_DATA_HOME:-~/.local/share}/skill-manager/slash-commands/sync-state.json` - marketplace cache: `${XDG_DATA_HOME:-~/.local/share}/skill-manager/marketplace` -- app database and LLM scan configs: `${XDG_DATA_HOME:-~/.local/share}/skill-manager/skill-manager.db` - app settings: `${XDG_CONFIG_HOME:-~/.config}/skill-manager/settings.json` Most users do not need to change these locations. If you manage skills in a custom environment, you can override individual skill roots with environment variables. @@ -287,6 +337,7 @@ Most users do not need to change these locations. If you manage skills in a cust | OpenCode | `SKILL_MANAGER_OPENCODE_ROOT` | `~/.config/opencode/skills` | | Hermes Agent | `SKILL_MANAGER_HERMES_ROOT` | `${HERMES_HOME:-~/.hermes}/skills` | | OpenClaw | `n/a` | `~/.openclaw/skills` | +| Antigravity (agy) | `SKILL_MANAGER_AGY_ROOT` | `~/.gemini/antigravity-cli/skills` | MCP config locations are harness-owned. Skill Manager writes only to verified config paths and skips unsupported harness writes. Hermes Agent config discovery honors `SKILL_MANAGER_HERMES_HOME` first, then `HERMES_HOME`, then `~/.hermes`. @@ -331,6 +382,15 @@ Default local URLs: - Backend: `http://127.0.0.1:8000` - Health: `http://127.0.0.1:8000/api/health` +The server binds to loopback only, and it rejects requests with a non-loopback `Host` header +(DNS-rebinding protection) and mutations with a non-loopback `Origin` header (CSRF protection). +Binding a non-loopback address requires an explicit opt-in, and is discouraged because the API +has no authentication: + +```bash +skill-manager serve --host 0.0.0.0 --allow-remote +``` + Validation: ```bash @@ -351,8 +411,10 @@ npm run build ### Extension families -- [ ] Hook support +- [x] Hook support - [x] Slash command support +- [x] Agent personas +- [x] Package-based storage (portable resource bundles) - [ ] Plugin support ### Harness expansion diff --git a/README.zh-CN.md b/README.zh-CN.md deleted file mode 100644 index 2530f1b9..00000000 --- a/README.zh-CN.md +++ /dev/null @@ -1,336 +0,0 @@ -# skill-manager - -[English](README.md) - -

- Skill Manager -

- -

- 面向 AI 扩展的本地优先控制中心。
- 在不同 agent harness 中统一使用、确认、扫描和发现 Skill、MCP 服务器、slash command 与 CLI 工具。 -

- -

- License: MIT - Latest release - npm version - Install with Homebrew - macOS ARM64/x64 and Linux x64/ARM64 - Local-first -

- -![skill-market-overview](./assets/skill-manager-skill-unification.svg) - -## 为什么需要它 - -AI 扩展通常分散在各个 harness 自己的文件夹、MCP 配置文件、slash command 位置和商城来源中。Skill Manager 提供一个本地控制界面来管理这些内容: - -| 产品概念 | 含义 | -|---|---| -| **使用中** | Skill Manager 正在控制此项目,并可在不同 harness 中启用或停用。 | -| **待确认** | Skill Manager 发现了本地状态、配置差异或库存问题,需要你先做决定。 | -| **扫描** | 在信任某个 Skill 之前,使用 LLM 驱动的安全检查进行确认。 | -| **发现** | 浏览商城,并预览外部工具。 | - -## 你可以做什么 - -- 查看哪些扩展正在使用、哪些需要确认,以及它们在哪些 harness 中启用。 -- 将本地 Skill 采用到共享库存,再按 harness 启用或停用。 -- 使用保存的 LLM provider 配置扫描 Skill,并在使用前查看发现项。 -- 安装或采用 MCP 服务器配置,解决配置差异,并写入支持的 harness。 -- 统一管理可复用的 slash command,并同步到支持的 harness。 -- 从商城来源发现 Skill、MCP 服务器,以及仅预览的 CLI 工具。 - -## 产品导览 - -### 总览 - -从整个扩展组合开始查看:使用中、待确认、可发现内容,以及各 harness 的覆盖情况。 - -![skill-market-overview](./assets/skill-manager-overview.png) - -### Skill - -使用 Skill 作为共享本地包,而不是在每个 harness 中维护单独副本。 - -典型流程: - -1. 确认 harness 中发现的 Skill,或从商城安装一个 Skill。 -2. 将它采用到 Skill Manager 库存。 -3. 只在需要的 harness 中启用。 -4. 从一个地方更新、移除或删除。 - -![skill-market-skill-matrxi](./assets/skill-manager-skill-matrix.png) - -### Skill 扫描 - -在依赖某个 Skill 之前,可以使用 LLM 驱动的安全确认流程先扫描它。 - -典型流程: - -1. 添加并验证一个 LLM 扫描配置。 -2. 将使用中的 Skill 切换到扫描视图。 -3. 对单个 Skill、已选 Skill 或当前可见列表运行扫描。 -4. 查看严重程度、发现项、代码片段和修复建议。 - -![skill-manager-scan-view](./assets/skill-manager-scan-view.svg) - -扫描配置单独管理,因此你可以保存多个 provider,选择一个当前配置,并且在列表中只显示隐藏后的 API Key。 - -![skill-manager-scan-config](./assets/skill-manager-scan-config.svg) - -### MCP 服务器 - -MCP 服务器会被规范化为 Skill Manager 记录,再转换为各 harness 期望的配置形状。 - -典型流程: - -1. 确认 harness 中发现的 MCP 服务器,或从商城安装一个。 -2. 将它采用到 Skill Manager 库存。 -3. 在需要的 harness 中启用。 -4. 解决配置差异、停用 harness 绑定,或从一个地方卸载。 - -![skill-market-skill-matrxi](./assets/skill-manager-mcp-matrix.png) - -### Slash command - -Slash command 作为共享 prompt 库保存,而不是在每个 harness 专用格式中重复维护。 - -典型流程: - -1. 创建包含名称、描述和 prompt 的 slash command。 -2. 用 `$ARGUMENTS` 表示运行时输入插入位置。 -3. 同步到支持的 harness。 -4. 确认已有的 harness command 文件,并在需要时采用到共享库。 - -![skill-market-slash-commands-matrix](./assets/skill-manager-slash_commands-matrix.png) - -### 商城 - -商城是发现界面: - -- **Skill 商城**:浏览并安装 Skill。 -- **MCP 商城**:浏览并安装 MCP 服务器。 -- **CLI 商城**:从 CLIs.dev 预览外部 CLI 工具。此区域仅展示,Skill Manager 不安装或管理 CLI。 - -![skill-market-skill-matrxi](./assets/skill-manager-marketplace.png) - -## 安装 - -### Homebrew(macOS 推荐) - -```bash -brew tap mode-io/tap -brew install skill-manager -skill-manager start -``` - -### npm(macOS ARM64/x64 和 Linux x64/ARM64) - -```bash -npm install -g @mode-io/skill-manager -skill-manager start -``` - -npm wrapper 会为当前平台和 CPU 架构下载对应的原生 release artifact。 -GitHub Releases 会发布 macOS ARM64/x64 和 Linux x64/ARM64 的原生 release artifact。 - -## 支持的 harness - -| Harness | Skill | MCP 服务器 | Slash command | -|---|---:|---:|---:| -| Codex CLI | 支持 | 支持 | 支持 | -| Claude Code | 支持 | 支持 | 支持 | -| Cursor | 支持 | 支持 | 支持 | -| OpenCode | 支持 | 支持 | 支持 | -| Hermes Agent | 支持 | 支持 | 暂不支持 | -| OpenClaw | 支持 | 暂不支持 | 暂不支持 | - -## 本地优先安全模型 - -Skill Manager 是本地配置管理工具。它在你的机器上运行,并读取或写入本地 harness 扩展状态。 - -可能修改本地状态的操作包括: - -- 采用本地 Skill 文件夹 -- 为某个 harness 启用或停用 Skill -- 更新带来源信息的 Skill -- 移除或删除 Skill -- 创建、更新、验证、激活或删除 LLM 扫描配置 -- 运行 Skill 扫描,这会将所选 Skill 上下文发送给已配置的 LLM provider -- 将 MCP 服务器安装到来源 harness -- 采用已有 MCP 配置 -- 启用、停用、解决差异或卸载 MCP 服务器 -- 创建、更新、同步、导入或删除 slash command -- 修改 harness 支持设置 - -在 macOS 上,应用拥有的文件位于 `~/Library/Application Support/skill-manager`;在 Linux 上使用 XDG base directories。 - -## 工作方式 - -### Skill - -采用之前,各 harness 指向各自的本地 Skill 文件夹。采用之后,Skill Manager 会在共享本地存储中保留一个规范包,并通过本地链接暴露给选定 harness。停用某个 harness 会移除该 harness 绑定,但不会删除包本身。 - -Skill Manager 默认把已管理 Skill 视为可迁移:Skill 一旦进入 shared store,就可以启用到任何受支持 harness。`originHarness` 只保留作来源记录。 - -Hermes Agent Skill 使用 Hermes 分类目录:`~/.hermes/skills///SKILL.md`。共享 Skill 启用到 Hermes 时,默认会链接到 `skill-manager` 分类下。Skill Manager 只导入 Hermes 自己从外部 hub provenance 安装的 Skill(`.hub/lock.json` 中非 official/builtin/optional 的条目)。Hermes 自学习/local Skill、`.bundled_manifest` 跟踪的内置打包 Skill,以及 Hermes hub provenance 中记录的官方 optional Skill,都会从 Skill Manager 库存和批量操作中排除;Skill Manager 不会修改、链接或删除这些文件夹,让 `hermes update` 和 Hermes 自有 Skill 同步继续保持原有所有权。 - -![skill-market-overview](./assets/skill-manager-skill-unification.svg) - -### Skill 扫描 - -Skill 扫描会从 `SKILL.md`、manifest 元数据、脚本与配置文件,以及 Skill 指令引用的文件中构建受限 prompt 上下文。`.env`、私钥、证书和 credential 文件等可能包含 secret 的文件会从 prompt 上下文中排除;超过扫描器限制的大文件也会被跳过。 - -扫描器优先使用当前激活的已保存 LLM 配置。如果没有激活配置,也可以回退到支持的环境变量,例如 `ANTHROPIC_API_KEY`、`OPENAI_API_KEY`、`OPENROUTER_API_KEY`、`GEMINI_API_KEY`、`GOOGLE_API_KEY`、`AZURE_OPENAI_API_KEY`、`AWS_BEDROCK_MODEL` 或 `OLLAMA_HOST`。 - -扫描报告会展示 Skill 是否安全、最高严重程度、发现项、位置、片段和修复建议。前端会将已完成报告缓存在浏览器 localStorage 中,因此最近结果在页面切换后仍可查看。 - -### MCP 服务器 - -MCP 服务器以规范化 Skill Manager 记录保存,再转换为每个 harness 需要的配置形状: - -- Codex 使用 `mcp_servers` 下的 TOML。 -- Claude Code 和 Cursor 使用 `mcpServers` JSON 条目。 -- OpenCode 使用类型化的本地或远程 MCP 条目。 -- Hermes Agent 使用 `~/.hermes/config.yaml`(或 `$HERMES_HOME/config.yaml`)中 `mcp_servers` 下的 YAML 配置。 -- OpenClaw 暂不支持 MCP 写入。 - -当 Skill Manager 发现同一个 MCP 服务器存在不同配置时,会先要求你选择事实来源。 - -![skill-market-overview](./assets/skill-manager-mcp-translation.svg) - -### Slash command - -Slash command 以 TOML 记录保存在 Skill Manager 应用存储中,再渲染到每个支持 harness 的格式: - -- OpenCode 写入 `~/.config/opencode/commands` 下的 Markdown command 文件,并通过 `/` 调用。 -- Claude Code 写入 `~/.claude/commands` 下的 Markdown command 文件,并通过 `/` 调用。 -- Cursor 写入 `~/.cursor/commands` 下的纯文本 command 文件,并通过 `/` 调用。 -- Codex 写入 `~/.codex/prompts` 下的 prompt 文件,并通过 `/prompts:` 调用。 -- Hermes Agent 暂不支持 slash command 写入;Hermes 的可复用工作流优先通过 Skill 管理。 -- OpenClaw 暂不支持 slash command 写入。 - -Skill Manager 使用同步状态和内容哈希跟踪目标所有权。它不会自动覆盖未跟踪的 command 文件;当目标不再匹配上次同步哈希时,会报告托管文件已变更或缺失。确认操作可用于采用未托管 command、恢复托管内容、将已变更的 harness command 采用为新来源,或移除损坏绑定且保留 harness 文件。 - -### CLI - -CLI marketplace 条目仅用于预览。 - -## 配置 - -在 macOS 上,应用拥有的文件位于 `~/Library/Application Support/skill-manager`;在 Linux 上使用 XDG base directories。 - -常用 macOS 路径: - -- 共享 Skill 存储:`~/Library/Application Support/skill-manager/shared` -- MCP manifest:`~/Library/Application Support/skill-manager/mcp/manifest.json` -- slash command 库:`~/Library/Application Support/skill-manager/slash-commands/commands` -- slash command 同步状态:`~/Library/Application Support/skill-manager/slash-commands/sync-state.json` -- 商城缓存:`~/Library/Application Support/skill-manager/marketplace` -- 应用数据库和 LLM 扫描配置:`~/Library/Application Support/skill-manager/skill-manager.db` -- 应用设置:`~/Library/Application Support/skill-manager/settings.json` - -常用 Linux 路径: - -- 共享 Skill 存储:`${XDG_DATA_HOME:-~/.local/share}/skill-manager/shared` -- MCP manifest:`${XDG_DATA_HOME:-~/.local/share}/skill-manager/mcp/manifest.json` -- slash command 库:`${XDG_DATA_HOME:-~/.local/share}/skill-manager/slash-commands/commands` -- slash command 同步状态:`${XDG_DATA_HOME:-~/.local/share}/skill-manager/slash-commands/sync-state.json` -- 商城缓存:`${XDG_DATA_HOME:-~/.local/share}/skill-manager/marketplace` -- 应用数据库和 LLM 扫描配置:`${XDG_DATA_HOME:-~/.local/share}/skill-manager/skill-manager.db` -- 应用设置:`${XDG_CONFIG_HOME:-~/.config}/skill-manager/settings.json` - -大多数用户不需要修改这些位置。如果你在自定义环境中管理 Skill,可以用环境变量覆盖单个 Skill 根目录。 - -| Harness | 环境变量 | 默认 Skill Manager Skill 根目录 | -|---|---|---| -| Codex | `SKILL_MANAGER_CODEX_ROOT` | `~/.agents/skills` | -| Claude | `SKILL_MANAGER_CLAUDE_ROOT` | `~/.claude/skills` | -| Cursor | `SKILL_MANAGER_CURSOR_ROOT` | `~/.cursor/skills` | -| OpenCode | `SKILL_MANAGER_OPENCODE_ROOT` | `~/.config/opencode/skills` | -| Hermes Agent | `SKILL_MANAGER_HERMES_ROOT` | `${HERMES_HOME:-~/.hermes}/skills` | -| OpenClaw | `n/a` | `~/.openclaw/skills` | - -MCP 配置位置由 harness 拥有。Skill Manager 只写入经过验证的配置路径,并跳过不支持的 harness 写入。Hermes Agent 配置发现会优先使用 `SKILL_MANAGER_HERMES_HOME`,然后是 `HERMES_HOME`,最后回退到 `~/.hermes`。 - -## 从源码运行 - -### 要求 - -- Python 3.11+ -- Node.js 18+ -- npm - -`skill-manager` 支持 Python 3.11+。CI 会验证 Python 3.11 到 3.14 的后端兼容性;为了确定性,打包和发布构建仍固定在 Python 3.11。 - -### 贡献者设置 - -```bash -scripts/install-dev.sh -``` - -### 本地运行 - -```bash -scripts/start-dev.sh -``` - -停止本地托管实例: - -```bash -scripts/stop-dev.sh -``` - -需要 Vite 热更新时,可以使用拆分开发流程: - -```bash -npm run dev -npm run dev:backend -``` - -默认本地 URL: - -- Frontend:`http://127.0.0.1:5173` -- Backend:`http://127.0.0.1:8000` -- Health:`http://127.0.0.1:8000/api/health` - -验证: - -```bash -scripts/install-dev.sh -npm run typecheck -bash scripts/test_backend.sh -npm test -npm run build -``` - -## 故障排查 - -- 如果商城请求失败并显示 `Marketplace is temporarily unavailable`,请确认网络连接后重试。 -- 在 macOS 上,如果 `npm install -g @mode-io/skill-manager` 提示 Homebrew 已拥有 `skill-manager`,请先卸载 Homebrew formula。反过来也一样:切回 Homebrew 前请先卸载 npm 包。 -- 如果某个 MCP harness 显示为不可用,说明 Skill Manager 检测到本地客户端缺失,或该客户端不支持所需配置界面。 - -## 后续计划 - -### 扩展类型 - -- [ ] Hook 支持 -- [x] Slash command 支持 -- [ ] Plugin 支持 - -### Harness 扩展 - -- [ ] GitHub Copilot -- [ ] Gemini CLI -- [ ] Cline -- [ ] Windsurf -- [ ] Qwen Code -- [ ] Kimi Code -- [ ] Qoder - -## 社区 - -- 查看 [CONTRIBUTING.md](CONTRIBUTING.md) 了解贡献指南。 -- 查看 [SECURITY.md](SECURITY.md) 以私下报告安全漏洞。 diff --git a/RECOMMENDATIONS.md b/RECOMMENDATIONS.md new file mode 100644 index 00000000..f584e482 --- /dev/null +++ b/RECOMMENDATIONS.md @@ -0,0 +1,154 @@ +# Recommendations + +> Review of 2026-07-25, refreshed against `main` after the Tier-1 batch. Verified by running the +> suites: backend unit (385) + integration (155) tests pass, `npm run typecheck` clean, `npm test` +> green (263), `ruff check` clean, OpenAPI drift gate clean. +> Ordered by value: each tier outranks the next. Within a tier, items are ordered by +> value-for-effort. Effort scale: **S** < 1 hour, **M** hours–a day, **L** multi-day. +> +> **This list is kept to open items only — shipped work is removed.** Shipped batches: +> 2026-07-24 merge `98c3417` (audit gates, loopback guards, static-root containment, dead-code pass); +> 2026-07-25 Tier-1 batch (Dependabot + SHA-pinned actions; golden writer round-trip tests; ruff lint +> gate; Hermes slash provisional label) — see `handoff.md` for the record. Partially-shipped items +> below keep their number and describe only the remaining scope. + +## Already strong — don't churn these + +- Atomic writes + `flock` for file mutations (`skill_manager/atomic_files.py`), with a dedicated + store-concurrency test. +- OpenAPI contract discipline: generated TS client committed, `codegen:check` drift gate in CI. +- One canonical harness catalog (`skill_manager/harness/catalog.py`) that drives every family. +- Subprocess calls are all list-form (no `shell=True`); marketplace fetchers use a pinned CA + context with TLS fixtures under test. +- CI matrix across Python 3.11–3.14 plus a full packaging smoke on four OS/arch targets. +- Ruff lint gate in CI (`[tool.ruff]` in `pyproject.toml`): import sorting + pyflakes enforced + and baselined green; `requirements-dev.txt` pins the tool. + +--- + +## Tier 1 — High value, moderate effort + +### 1.1 Harden the writers so unknown user fields survive a round-trip — M + +**Shipped (2026-07-25):** `tests/unit/test_writer_round_trip.py` codifies the test the retrospective +in `plan-agents-simplify.md` calls for — for every writer of a user-authored file (slash frontmatter +codec, every MCP transport mapper) it pins idempotency, owned-field preservation, and a +*characterization* of the unknown keys/comments currently dropped. The data-loss surface is now +visible and locked. + +**Remaining:** the characterization tests today assert that unknown frontmatter keys/comments and +unknown MCP entry fields (e.g. `disabled`, `autoApprove`) are *dropped* — the writers still destroy +what they do not model. Flip those to preservation assertions: have +`FrontmatterMarkdownCommandCodec` carry unknown frontmatter verbatim and `McpServerSpec` carry +per-entry extras, so re-writing a realistic file leaves untouched regions byte-identical (OpenCode's +force-`enabled=True` is the clearest live example). Consider `hypothesis` for frontmatter/JSON +round-trip properties once preservation lands. + +### 1.2 Finish static-analysis adoption (type-check + frontend lint + baseline cleanup) — M + +**Shipped (2026-07-25):** ruff is the backend lint gate — `[tool.ruff]` in `pyproject.toml`, +`requirements-dev.txt`, and a "Backend lint" CI step. Import sorting (I) is enforced and applied +across the tree; pyflakes (F) is enforced with `F401`/`F821`/`F841` baselined (the baseline is +documented in-config and meant to shrink). + +**Remaining:** (a) chip the ruff baseline — drop `F401` by removing the 29 unused imports in a +verified per-module pass (a blanket `--fix` rewrote import paths and broke test collection, so this +needs care), then broaden `select` toward `E`/`W`/`UP`/`B`; (b) add `pyright` (or `mypy`) with a +committed config + CI step, starting from `basic`; (c) add ESLint (typescript + react-hooks) for +`frontend/src`. The fifteen `# noqa: BLE001` comments are the existing half-adoption this completes. + + +### 1.3 Finish labeling (or verify) the Hermes harness — M + +**Shipped (2026-07-25):** the Hermes **slash** binding now carries a provisional `support_note` +("…unverified against a real Hermes install; writes may not take effect…") in +`harness/catalog.py`, surfaced to the UI via the existing `SlashTarget.supportNote` path. The agents +binding was already labeled unavailable (no agent-definition format). + +**Remaining:** MCP and hooks are still written on unverified assumptions with no provisional label. +Thread a `support_note` through `ConfigSubtreeBindingProfile` → the MCP/hooks read models (typed, +so it needs an OpenAPI regen) and mark both provisional, **or** validate against a real Hermes +build and record the evidence in `handoff.md` (as was done for Claude/agy agent symlinks). With +seven more harnesses on the README roadmap, define a repeatable "new harness verification" checklist +(probe CLI, real read, real write, round-trip diff) and reuse it per harness. + +--- + +## Tier 2 — Strategic investments + +### 2.1 A mutation audit journal — M–L + +A tool whose job is mutating local config has almost no observability: a `grep -rn 'logging'` +over `skill_manager/` now returns **zero** hits (the last holdout, `db/migrations.py`, was removed +in `9f23101`), and uvicorn runs with `access_log=False`. When something goes wrong in a +user's setup — or a user asks "what did Skill Manager change?" — there is no answer on disk. + +**Action:** append a structured record (JSON Lines) to +`${XDG_DATA_HOME}/skill-manager/audit.log` for every mutation: timestamp, family, operation, +target paths, outcome. This doubles as product surface later (an activity view) and strengthens +the trust story that "Needs Review" already builds. + +### 2.2 Coverage measurement with a ratchet — S–M + +385 backend unit tests, 155 integration tests, and 62 frontend test files (263 tests) exist, but nothing measures what they cover, so +gaps are invisible (e.g. the two data-loss bugs in §1.1 lived in well-tested-looking code). + +**Action:** add `coverage.py` to `scripts/test_backend.sh` and `vitest --coverage` to CI; report +per-package coverage and ratchet the threshold (fail if it drops). The point is trend, not a +vanity number. + +### 2.3 Document the family/harness template; then decide on extraction — M + +Each family (skills, MCP, hooks, permissions, agents, slash commands) re-implements the same +octet: store / mappers / adapters / inventory / mutations / queries / read_models / harness +application — e.g. `hooks/mappers.py` is 897 lines, `permissions/mappers.py` 683. The mirroring +is deliberate and has real benefits (families evolve independently), but the *knowledge* of what +a conforming family needs exists only in the plans and handoffs. + +**Action:** write `docs/adding-a-family.md` + `docs/adding-a-harness.md` checklists (the harness +one pairs with §1.3's verification checklist). Only after that, evaluate extracting a shared +"family framework" for the truly invariant parts (manifest store, matrix read model) — with the +checklist as the spec it must satisfy. Do not extract first: the agents rebuild shows the cost of +a bespoke abstraction that had to be torn out. + +### 2.4 Machine-readable API error codes — S–M + +Every error is `{"error": ""}` (`api/errors.py`), so the frontend can only branch +on message text — brittle under rewording and under i18n (several features already have `i18n.ts` +modules). + +**Action:** add a stable `code` field (`"skill_not_found"`, `"harness_unavailable"`, …) alongside +`error`; adopt incrementally in the frontend where behavior branches on errors today. + +--- + +## Tier 3 — Housekeeping (low priority, cheap when touched next) + +- **Root doc sprawl.** `handoff.md` (21 KB), two `plan-agents-*.md`, and this file sit beside a + 22 KB README. Move plans/handoffs under `docs/` (keeping the handoff discipline that clearly + works) and leave a pointer at the root. — **S** +- **Windows is architecturally excluded, not just unsupported.** `atomic_files.py` imports + `fcntl` at module top level, so the package doesn't even *import* on Windows. Fine while the + README badges say macOS/Linux — just gate the import so "Windows support" later is a port of + one module, not an archaeology dig. — **S** +- **`choose_port` / `bind_socket` TOCTOU race** (`runtime/server.py:32-49`): probe-bind, close, + re-bind. Two quick starts can collide between the probes. Bind once and keep the socket (the + code already passes `fd` to uvicorn, so this is mostly deleting the probe). — **S** +- **Clean local scratch from the repo dir.** Stale `test_scan_*.pyc` and `.pytest_cache` linger + in the working tree (untracked, but confusing); and the `skill_manager/db/` directory now + contains **only** stale `__pycache__/*.pyc` — its source was removed in `9f23101` but the + compiled cache and the empty package dir were left behind. The project standardizes on + `unittest`, so either document pytest compatibility or remove the cache dirs / orphaned + `db/` package. — **S** + +--- + +## Suggested sequencing + +1. **Tier-1 batch shipped 2026-07-25** (1.4 Dependabot + SHA pinning; 1.1 golden round-trip tests; + 1.2 ruff gate; 1.3 Hermes slash label). **Next (all S/M):** finish the partials in value order — + 1.1 harden the writers to preserve unknown fields, 1.2 add pyright + ESLint + chip the ruff + baseline, 1.3 label/verify Hermes MCP & hooks. +2. **When planning the next family or harness:** 2.3 first, 2.1 alongside, 2.2 to keep it honest. +3. **Tier 3 housekeeping** rides along whenever its files are touched next. + diff --git a/assets/harness-logos/agy-logo.svg b/assets/harness-logos/agy-logo.svg new file mode 100644 index 00000000..fe5fd4c3 --- /dev/null +++ b/assets/harness-logos/agy-logo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/harness-logos/hermes-logo.png b/assets/harness-logos/hermes-logo.png deleted file mode 100644 index 2d629d2f..00000000 Binary files a/assets/harness-logos/hermes-logo.png and /dev/null differ diff --git a/assets/harness-logos/hermes-logo.svg b/assets/harness-logos/hermes-logo.svg new file mode 100644 index 00000000..85534203 --- /dev/null +++ b/assets/harness-logos/hermes-logo.svg @@ -0,0 +1 @@ +Hermes Agent \ No newline at end of file diff --git a/assets/skill-manager-scan-config.svg b/assets/skill-manager-scan-config.svg deleted file mode 100644 index efff56b7..00000000 --- a/assets/skill-manager-scan-config.svg +++ /dev/null @@ -1,81 +0,0 @@ - - Scan Config page - Dark Skill Manager page for saved LLM scan configurations, with provider, base URL, masked API key, active state, edit, and delete actions. - - - Scan Config - View and manage all saved LLM configurations for security scans. - - - New configuration - - - - - - Name - Model - Provider - Base URL - API Key - - - skill5 - deepseek/deepseek-v4-f... - openrouter - https://openrouter.ai/ap... - sk-o...047b - - Active - - Edit - - Delete - - - - skill-manager - qwen-plus - openai- - compatible - https://dashscope.aliyun... - sk-e...7835 - - Make active - - Edit - - Delete - - - - skill4 - openai/gpt-oss-120b:fr... - openrouter - https://openrouter.ai/ap... - sk-o...2baf - - Make active - - Edit - - Delete - - - - skill6 - deepseek-v4-pro - openai- - compatible - https://dashscope.aliyun... - sk-2...2d98 - - Make active - - Edit - - Delete - - - - diff --git a/assets/skill-manager-scan-view.svg b/assets/skill-manager-scan-view.svg deleted file mode 100644 index 9578603d..00000000 --- a/assets/skill-manager-scan-view.svg +++ /dev/null @@ -1,71 +0,0 @@ - - Skills in use scan view - Dark Skill Manager screen showing the Scan view for skills in use, with selectable rows and View Result actions. - - - Skills in use - - - Grid - Board - Matrix - - Scan - - - - Import folder - - - - - - Search by name, tag, description... - - - Name - - Action - - - - find-skills - Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X"... - - View Result - - - - - frontend-design - Create distinctive, production-grade frontend interfaces with high design quality. - - View Result - - - - - test2 - Earn money by completing web scraping tasks when your computer is idle - - View Result - - - - - ui-ux-pro-max - UI/UX design intelligence for web and mobile. Includes styles, palettes, font pairings, product types, and guidelines. - - View Result - - - - - vulnerable-test-skill - A test skill with intentional security issues for scanner testing. - - View Result - - - - diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index 62d8133b..a0ea0710 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -19,7 +19,6 @@ function stubEmptyApi() { createRouteFetchMock( [ { match: "/api/skills", response: skillsPayload() }, - { match: "/api/scan/configs", response: { configs: [], activeId: null } }, { match: "/api/mcp/servers", response: mcpInventoryPayload() }, { match: "/api/settings", response: settingsPayload() }, { match: "/api/slash-commands", response: slashCommandsPayload() }, @@ -59,7 +58,6 @@ describe("App shell", () => { expect(screen.getByText(/skill-manager/)).toBeInTheDocument(); expect(screen.getByRole("link", { name: /^Overview$/i })).toBeInTheDocument(); expect(screen.getByRole("button", { name: /Skills/i })).toBeInTheDocument(); - expect(screen.getByRole("link", { name: "Scan Config" })).toBeInTheDocument(); expect(screen.getByRole("button", { name: /Slash Commands/i })).toBeInTheDocument(); expect(screen.getByRole("button", { name: /MCP Servers/i })).toBeInTheDocument(); expect(screen.getByRole("button", { name: /Marketplace/i })).toBeInTheDocument(); @@ -98,10 +96,9 @@ describe("App shell", () => { expect(screen.getByRole("button", { name: "MCP Servers 3" })).toBeInTheDocument(); }); expect(screen.getByRole("link", { name: "In use 10" })).toBeInTheDocument(); - expect(screen.getByRole("link", { name: "Needs review 3" })).toBeInTheDocument(); - expect(screen.getByRole("link", { name: "Scan Config" })).toBeInTheDocument(); + expect(screen.getByRole("link", { name: "Unmanaged 3" })).toBeInTheDocument(); expect(screen.getByRole("link", { name: "In use 2" })).toBeInTheDocument(); - expect(screen.getByRole("link", { name: "Needs review 1" })).toBeInTheDocument(); + expect(screen.getByRole("link", { name: "Unmanaged 1" })).toBeInTheDocument(); expect(screen.getByRole("button", { name: "Marketplace" })).toBeInTheDocument(); expect(screen.getByRole("link", { name: "Skills" })).toBeInTheDocument(); expect(screen.getByRole("link", { name: "MCP" })).toBeInTheDocument(); @@ -127,7 +124,6 @@ describe("App shell", () => { ["/overview", "Overview"], ["/skills/use", "Skills in use"], ["/skills/review", "Skills to review"], - ["/scan-config", "Scan Config"], ["/slash-commands", "Slash Commands"], ["/slash-commands/use", "Slash Commands"], ["/slash-commands/review", "Slash commands to review"], diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index d94b43d7..ca401c63 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -10,10 +10,12 @@ import { invalidateCapabilityQueries } from "./app/capability-registry"; import { SkillsWorkspaceSessionProvider } from "./features/skills/model/session"; import SkillsNeedsReviewPage from "./features/skills/screens/SkillsNeedsReviewPage"; import SkillsInUsePage from "./features/skills/screens/SkillsInUsePage"; -import ScanConfigPage from "./features/skills/screens/ScanConfigPage"; import SkillsWorkspacePage from "./features/skills/screens/SkillsWorkspacePage"; import { LocaleProvider, useCommonCopy } from "./i18n"; +import { HomeDirProvider } from "./lib/paths"; +import { ThemeProvider } from "./lib/theme"; + const MarketplaceLayout = lazy(() => import("./features/marketplace/components/MarketplaceLayout")); const OverviewPage = lazy(() => import("./features/overview/screens/OverviewPage")); const SettingsPage = lazy(() => import("./features/settings/screens/SettingsPage")); @@ -21,6 +23,12 @@ const SlashCommandsPage = lazy(() => import("./features/slash-commands/screens/S const SlashCommandsReviewPage = lazy(() => import("./features/slash-commands/screens/SlashCommandsReviewPage")); const McpNeedsReviewPage = lazy(() => import("./features/mcp/screens/McpNeedsReviewPage")); const McpInUsePage = lazy(() => import("./features/mcp/screens/McpInUsePage")); +const AgentsInUsePage = lazy(() => import("./features/agents/screens/AgentsInUsePage")); +const AgentsNeedsReviewPage = lazy(() => import("./features/agents/screens/AgentsNeedsReviewPage")); +const HooksInUsePage = lazy(() => import("./features/hooks/screens/HooksInUsePage")); +const HooksNeedsReviewPage = lazy(() => import("./features/hooks/screens/HooksNeedsReviewPage")); +const PermissionsInUsePage = lazy(() => import("./features/permissions/screens/PermissionsInUsePage")); +const PermissionsNeedsReviewPage = lazy(() => import("./features/permissions/screens/PermissionsNeedsReviewPage")); export function App() { const [queryClient] = useState( @@ -36,13 +44,17 @@ export function App() { return ( - - - - - - - + + + + + + + + + + + ); } @@ -75,6 +87,23 @@ function AppContent() { } /> + } /> + }> + + + } + /> + }> + + + } + /> }> } /> @@ -85,7 +114,6 @@ function AppContent() { } /> - } /> } /> } /> + } /> + }> + + + } + /> + }> + + + } + /> + + } /> + }> + + + } + /> + }> + + + } + /> + ; export interface components { schemas: { + /** AddHookRequest */ + AddHookRequest: { + /** Command */ + command: string; + /** + * Description + * @default + */ + description: string; + /** Event */ + event: string; + /** Id */ + id: string; + /** Match */ + match?: string | null; + /** Timeout */ + timeout?: number | null; + }; /** AddMcpServerRequest */ AddMcpServerRequest: { /** Qualifiedname */ qualifiedName: string; }; + /** AddPermissionRequest */ + AddPermissionRequest: { + /** Decision */ + decision: string; + /** + * Description + * @default + */ + description: string; + /** Id */ + id: string; + /** Pattern */ + pattern?: string | null; + /** Scope */ + scope: string; + }; + /** AdoptAgentRequest */ + AdoptAgentRequest: { + /** Onconflict */ + onConflict?: ("keep_store" | "replace_store") | null; + }; + /** AdoptAgentResponse */ + AdoptAgentResponse: { + /** Ok */ + ok: boolean; + /** Ref */ + ref: string; + }; + /** AdoptAllAgentsResponse */ + AdoptAllAgentsResponse: { + /** Adopted */ + adopted: string[]; + /** Ok */ + ok: boolean; + /** Skipped */ + skipped: components["schemas"]["AdoptAllSkippedResponse"][]; + }; + /** AdoptAllSkippedResponse */ + AdoptAllSkippedResponse: { + /** Reason */ + reason: string; + /** Ref */ + ref: string; + }; /** AdoptMcpRequest */ AdoptMcpRequest: { /** Harnesses */ @@ -828,25 +1133,160 @@ export interface components { /** Observed harness */ observedHarness?: string | null; }; - /** BulkManageFailureResponse */ - BulkManageFailureResponse: { - /** Error */ - error: string; - /** Name */ - name: string; - /** Skillref */ - skillRef: string; + /** AgentActionsResponse */ + AgentActionsResponse: { + /** Canadopt */ + canAdopt: boolean; + /** Candelete */ + canDelete: boolean; }; - /** BulkManageResultResponse */ - BulkManageResultResponse: { - /** Failures */ - failures: components["schemas"]["BulkManageFailureResponse"][]; - /** Managedcount */ - managedCount: number; - /** Ok */ - ok: boolean; - /** Skippedcount */ - skippedCount: number; + /** AgentBindingResponse */ + AgentBindingResponse: { + /** Detail */ + detail?: string | null; + /** Harness */ + harness: string; + /** + * State + * @enum {string} + */ + state: "enabled" | "disabled" | "unsupported"; + }; + /** AgentColumnResponse */ + AgentColumnResponse: { + /** Harness */ + harness: string; + /** Installed */ + installed: boolean; + /** Label */ + label: string; + /** Logokey */ + logoKey?: string | null; + }; + /** + * AgentConfigEntryResponse + * @description One frontmatter key we do not interpret, shown verbatim. + */ + AgentConfigEntryResponse: { + /** Key */ + key: string; + /** Value */ + value: string; + }; + /** AgentDetailResponse */ + AgentDetailResponse: { + /** Candelete */ + canDelete: boolean; + /** Configuration */ + configuration?: components["schemas"]["AgentConfigEntryResponse"][]; + /** Description */ + description: string; + /** Document */ + document: string; + /** Harnesses */ + harnesses: components["schemas"]["AgentHarnessDetailResponse"][]; + /** Name */ + name: string; + /** Prompt */ + prompt: string; + /** Ref */ + ref: string; + /** Storepath */ + storePath: string; + /** Tools */ + tools: string[]; + }; + /** AgentEntryResponse */ + AgentEntryResponse: { + actions: components["schemas"]["AgentActionsResponse"]; + /** Bindings */ + bindings: components["schemas"]["AgentBindingResponse"][]; + /** Description */ + description: string; + /** Harnesspath */ + harnessPath?: string | null; + /** + * Kind + * @enum {string} + */ + kind: "managed" | "unmanaged"; + /** Name */ + name: string; + /** Ref */ + ref: string; + }; + /** AgentHarnessDetailResponse */ + AgentHarnessDetailResponse: { + /** Detail */ + detail?: string | null; + /** Harness */ + harness: string; + /** + * Installmethod + * @enum {string} + */ + installMethod: "symlink" | "rendered" | "none"; + /** Installed */ + installed: boolean; + /** Label */ + label: string; + /** Logokey */ + logoKey?: string | null; + /** Path */ + path: string; + /** + * State + * @enum {string} + */ + state: "enabled" | "disabled" | "unsupported"; + }; + /** AgentHarnessRequest */ + AgentHarnessRequest: { + /** Harness */ + harness: string; + }; + /** AgentInventoryResponse */ + AgentInventoryResponse: { + /** Columns */ + columns: components["schemas"]["AgentColumnResponse"][]; + /** Entries */ + entries: components["schemas"]["AgentEntryResponse"][]; + /** Issues */ + issues?: components["schemas"]["AgentIssueResponse"][]; + }; + /** AgentIssueResponse */ + AgentIssueResponse: { + /** Name */ + name: string; + /** Reason */ + reason: string; + }; + /** AgentMutationFailureResponse */ + AgentMutationFailureResponse: { + /** Error */ + error: string; + /** Harness */ + harness: string; + }; + /** BulkManageFailureResponse */ + BulkManageFailureResponse: { + /** Error */ + error: string; + /** Name */ + name: string; + /** Skillref */ + skillRef: string; + }; + /** BulkManageResultResponse */ + BulkManageResultResponse: { + /** Failures */ + failures: components["schemas"]["BulkManageFailureResponse"][]; + /** Managedcount */ + managedCount: number; + /** Ok */ + ok: boolean; + /** Skippedcount */ + skippedCount: number; }; /** CliMarketplaceDetailResponse */ CliMarketplaceDetailResponse: { @@ -935,18 +1375,30 @@ export interface components { /** Nextoffset */ nextOffset?: number | null; }; - /** DetectedProviderResponse */ - DetectedProviderResponse: { - /** Apikeysource */ - apiKeySource: string; - /** Baseurl */ - baseUrl?: string | null; - /** Isavailable */ - isAvailable: boolean; - /** Model */ - model?: string | null; - /** Provider */ - provider: string; + /** CreateAgentRequest */ + CreateAgentRequest: { + /** + * Description + * @default + */ + description: string; + /** Name */ + name: string; + /** + * Prompt + * @default + */ + prompt: string; + /** Tools */ + tools?: string[]; + }; + /** DisableHookRequest */ + DisableHookRequest: { + /** + * Harness + * @description Harness identifier + */ + harness: string; }; /** DisableMcpServerRequest */ DisableMcpServerRequest: { @@ -956,6 +1408,14 @@ export interface components { */ harness: string; }; + /** DisablePermissionRequest */ + DisablePermissionRequest: { + /** + * Harness + * @description Harness identifier + */ + harness: string; + }; /** DisableSkillRequest */ DisableSkillRequest: { /** @@ -964,6 +1424,14 @@ export interface components { */ harness: string; }; + /** EnableHookRequest */ + EnableHookRequest: { + /** + * Harness + * @description Harness identifier + */ + harness: string; + }; /** EnableMcpServerRequest */ EnableMcpServerRequest: { /** Config */ @@ -976,6 +1444,14 @@ export interface components { */ harness: string; }; + /** EnablePermissionRequest */ + EnablePermissionRequest: { + /** + * Harness + * @description Harness identifier + */ + harness: string; + }; /** EnableSkillRequest */ EnableSkillRequest: { /** @@ -1016,22 +1492,134 @@ export interface components { /** Logokey */ logoKey?: string | null; }; + /** HookApplyConfigResponse */ + HookApplyConfigResponse: { + /** Failed */ + failed: components["schemas"]["HookMutationFailureResponse"][]; + hook: components["schemas"]["HookSpecResponse"]; + /** Ok */ + ok: boolean; + /** Succeeded */ + succeeded: string[]; + }; + /** HookBindingResponse */ + HookBindingResponse: { + /** Caveat */ + caveat?: string | null; + /** Driftdetail */ + driftDetail?: string | null; + /** Harness */ + harness: string; + /** + * State + * @enum {string} + */ + state: "managed" | "drifted" | "unmanaged" | "missing" | "unsupported"; + }; + /** HookInventoryColumnResponse */ + HookInventoryColumnResponse: { + /** Configpresent */ + configPresent: boolean; + /** Harness */ + harness: string; + /** Hooksunavailablereason */ + hooksUnavailableReason?: string | null; + /** + * Hookswritable + * @default true + */ + hooksWritable: boolean; + /** Installed */ + installed: boolean; + /** Label */ + label: string; + /** Logokey */ + logoKey?: string | null; + }; + /** HookInventoryEntryResponse */ + HookInventoryEntryResponse: { + /** Canenable */ + canEnable: boolean; + /** Displayname */ + displayName: string; + /** + * Enabledstatus + * @enum {string} + */ + enabledStatus: "enabled" | "disabled"; + /** Id */ + id: string; + /** + * Kind + * @enum {string} + */ + kind: "managed" | "unmanaged"; + /** Sightings */ + sightings: components["schemas"]["HookBindingResponse"][]; + spec?: components["schemas"]["HookSpecResponse"] | null; + }; + /** HookInventoryIssueResponse */ + HookInventoryIssueResponse: { + /** Name */ + name: string; + /** Reason */ + reason: string; + }; + /** HookInventoryResponse */ + HookInventoryResponse: { + /** Columns */ + columns: components["schemas"]["HookInventoryColumnResponse"][]; + /** Entries */ + entries: components["schemas"]["HookInventoryEntryResponse"][]; + /** Issues */ + issues?: components["schemas"]["HookInventoryIssueResponse"][]; + }; + /** HookMutationFailureResponse */ + HookMutationFailureResponse: { + /** Error */ + error: string; + /** Harness */ + harness: string; + }; + /** HookMutationResponse */ + HookMutationResponse: { + hook: components["schemas"]["HookSpecResponse"]; + /** Ok */ + ok: boolean; + }; + /** HookSetHarnessesResultResponse */ + HookSetHarnessesResultResponse: { + /** Failed */ + failed: components["schemas"]["HookMutationFailureResponse"][]; + /** Ok */ + ok: boolean; + /** Succeeded */ + succeeded: string[]; + }; + /** HookSpecResponse */ + HookSpecResponse: { + /** Command */ + command: string; + /** Description */ + description: string; + /** Event */ + event: string; + /** Id */ + id: string; + /** Installedat */ + installedAt: string; + /** Match */ + match?: string | null; + /** Revision */ + revision: string; + /** Timeout */ + timeout?: number | null; + }; /** InstallMarketplaceSkillRequest */ InstallMarketplaceSkillRequest: { /** Installtoken */ installToken: string; }; - /** LLMDetectionResponse */ - LLMDetectionResponse: { - /** Defaultmodel */ - defaultModel?: string | null; - /** Defaultprovider */ - defaultProvider?: string | null; - /** Hasanyavailable */ - hasAnyAvailable: boolean; - /** Providers */ - providers: components["schemas"]["DetectedProviderResponse"][]; - }; /** McpAdoptionIssueResponse */ McpAdoptionIssueResponse: { /** Configpath */ @@ -1614,266 +2202,214 @@ export interface components { /** Ok */ ok: boolean; }; - /** ReconcileMcpServerRequest */ - ReconcileMcpServerRequest: { - /** Harnesses */ - harnesses?: string[] | null; - /** Observed harness */ - observedHarness?: string | null; + /** PermissionApplyConfigResponse */ + PermissionApplyConfigResponse: { + /** Failed */ + failed: components["schemas"]["PermissionMutationFailureResponse"][]; + /** Ok */ + ok: boolean; + permission: components["schemas"]["PermissionSpecResponse"]; + /** Succeeded */ + succeeded: string[]; + }; + /** PermissionBindingResponse */ + PermissionBindingResponse: { + /** Caveat */ + caveat?: string | null; + /** Driftdetail */ + driftDetail?: string | null; + /** Harness */ + harness: string; /** - * Sourcekind + * State * @enum {string} */ - sourceKind: "managed" | "harness"; - }; - /** ScanAvailabilityResponse */ - ScanAvailabilityResponse: { - /** Available */ - available: boolean; + state: "managed" | "drifted" | "unmanaged" | "missing" | "unsupported"; }; - /** ScanConfigItem */ - ScanConfigItem: { - /** Apikeymasked */ - apiKeyMasked: string; - /** Apiversion */ - apiVersion: string; - /** Awsprofile */ - awsProfile: string; - /** Awsregion */ - awsRegion: string; - /** Baseurl */ - baseUrl: string; - /** Consensusruns */ - consensusRuns: number; - /** Id */ - id: number; - /** Isactive */ - isActive: boolean; - /** Lastvalidatedat */ - lastValidatedAt?: string | null; + /** PermissionInventoryColumnResponse */ + PermissionInventoryColumnResponse: { + /** Configpresent */ + configPresent: boolean; + /** Harness */ + harness: string; + /** Installed */ + installed: boolean; + /** Label */ + label: string; + /** Logokey */ + logoKey?: string | null; + /** Permissionsunavailablereason */ + permissionsUnavailableReason?: string | null; /** - * Lastvalidationerror - * @default - */ - lastValidationError: string; - /** Maxtokens */ - maxTokens: number; - /** Model */ - model: string; - /** Name */ - name: string; - /** Provider */ - provider: string; - }; - /** ScanConfigListResponse */ - ScanConfigListResponse: { - /** Activeid */ - activeId: number | null; - /** Configs */ - configs: components["schemas"]["ScanConfigItem"][]; - }; - /** ScanConfigSaveRequest */ - ScanConfigSaveRequest: { - /** Apikey */ - apiKey: string; - /** - * Apiversion - * @default + * Permissionswritable + * @default true */ - apiVersion: string; + permissionsWritable: boolean; + }; + /** PermissionInventoryEntryResponse */ + PermissionInventoryEntryResponse: { + /** Canenable */ + canEnable: boolean; + /** Displayname */ + displayName: string; /** - * Awsprofile - * @default + * Enabledstatus + * @enum {string} */ - awsProfile: string; - /** - * Awsregion - * @default - */ - awsRegion: string; - /** - * Awssessiontoken - * @default - */ - awsSessionToken: string; - /** Baseurl */ - baseUrl: string; - /** - * Consensusruns - * @default 1 - */ - consensusRuns: number; + enabledStatus: "enabled" | "disabled"; + /** Id */ + id: string; /** - * Maxtokens - * @default 8192 + * Kind + * @enum {string} */ - maxTokens: number; - /** Model */ - model: string; + kind: "managed" | "unmanaged"; + /** Sightings */ + sightings: components["schemas"]["PermissionBindingResponse"][]; + spec?: components["schemas"]["PermissionSpecResponse"] | null; + }; + /** PermissionInventoryIssueResponse */ + PermissionInventoryIssueResponse: { /** Name */ name: string; - /** - * Provider - * @default - */ - provider: string; + /** Reason */ + reason: string; }; - /** ScanConfigSecretResponse */ - ScanConfigSecretResponse: { - /** Apikey */ - apiKey: string; + /** PermissionInventoryResponse */ + PermissionInventoryResponse: { + /** Columns */ + columns: components["schemas"]["PermissionInventoryColumnResponse"][]; + /** Entries */ + entries: components["schemas"]["PermissionInventoryEntryResponse"][]; + /** Issues */ + issues?: components["schemas"]["PermissionInventoryIssueResponse"][]; }; - /** ScanConfigValidateRequest */ - ScanConfigValidateRequest: { - /** Apikey */ - apiKey: string; - /** - * Apiversion - * @default - */ - apiVersion: string; - /** - * Awsprofile - * @default - */ - awsProfile: string; - /** - * Awsregion - * @default - */ - awsRegion: string; - /** - * Awssessiontoken - * @default - */ - awsSessionToken: string; - /** Baseurl */ - baseUrl: string; - /** - * Consensusruns - * @default 1 - */ - consensusRuns: number; - /** Existingconfigid */ - existingConfigId?: number | null; - /** - * Maxtokens - * @default 8192 - */ - maxTokens: number; - /** Model */ - model: string; - /** Name */ - name: string; - /** - * Provider - * @default - */ - provider: string; + /** PermissionMutationFailureResponse */ + PermissionMutationFailureResponse: { + /** Error */ + error: string; + /** Harness */ + harness: string; }; - /** ScanConfigValidationResponse */ - ScanConfigValidationResponse: { - /** Durationms */ - durationMs?: number | null; - /** Errorcode */ - errorCode?: string | null; - /** Message */ - message: string; - /** Model */ - model?: string | null; + /** PermissionMutationResponse */ + PermissionMutationResponse: { /** Ok */ ok: boolean; - /** Provider */ - provider?: string | null; + permission: components["schemas"]["PermissionSpecResponse"]; }; - /** ScanFindingResponse */ - ScanFindingResponse: { - /** Analyzer */ - analyzer?: string | null; - /** Category */ - category: string; + /** PermissionSetHarnessesResultResponse */ + PermissionSetHarnessesResultResponse: { + /** Failed */ + failed: components["schemas"]["PermissionMutationFailureResponse"][]; + /** Ok */ + ok: boolean; + /** Succeeded */ + succeeded: string[]; + }; + /** PermissionSpecResponse */ + PermissionSpecResponse: { + /** Decision */ + decision: string; /** Description */ description: string; - /** Filepath */ - filePath?: string | null; /** Id */ id: string; - /** Linenumber */ - lineNumber?: number | null; + /** Installedat */ + installedAt: string; + /** Pattern */ + pattern?: string | null; + /** Revision */ + revision: string; + /** Scope */ + scope: string; + }; + /** PromoteHookRequest */ + PromoteHookRequest: { + /** Observed harness */ + observedHarness?: string | null; + }; + /** PromotePermissionRequest */ + PromotePermissionRequest: { + /** Observed harness */ + observedHarness?: string | null; + }; + /** ReconcileHookRequest */ + ReconcileHookRequest: { + /** Harnesses */ + harnesses?: string[] | null; + /** Observed harness */ + observedHarness?: string | null; /** - * Metadata - * @default {} + * Sourcekind + * @enum {string} */ - metadata: { - [key: string]: unknown; - }; - /** Remediation */ - remediation?: string | null; - /** Ruleid */ - ruleId: string; - /** Severity */ - severity: string; - /** Snippet */ - snippet?: string | null; - /** Title */ - title: string; - }; - /** ScanOptionsRequest */ - ScanOptionsRequest: { - /** Awsprofile */ - awsProfile?: string | null; - /** Awsregion */ - awsRegion?: string | null; - /** Awssessiontoken */ - awsSessionToken?: string | null; - /** Llmapikey */ - llmApiKey?: string | null; - /** Llmapiversion */ - llmApiVersion?: string | null; - /** Llmbaseurl */ - llmBaseUrl?: string | null; - /** - * Llmconsensusruns - * @default 1 - */ - llmConsensusRuns: number; - /** - * Llmmaxtokens - * @default 8192 - */ - llmMaxTokens: number; - /** Llmmodel */ - llmModel?: string | null; - /** Llmprovider */ - llmProvider?: string | null; - /** - * Usellm - * @default true + sourceKind: "managed" | "harness"; + }; + /** ReconcileMcpServerRequest */ + ReconcileMcpServerRequest: { + /** Harnesses */ + harnesses?: string[] | null; + /** Observed harness */ + observedHarness?: string | null; + /** + * Sourcekind + * @enum {string} + */ + sourceKind: "managed" | "harness"; + }; + /** ReconcilePermissionRequest */ + ReconcilePermissionRequest: { + /** Harnesses */ + harnesses?: string[] | null; + /** Observed harness */ + observedHarness?: string | null; + /** + * Sourcekind + * @enum {string} */ - useLlm: boolean; - }; - /** ScanResultResponse */ - ScanResultResponse: { - /** Analyzersused */ - analyzersUsed: string[]; - /** Durationseconds */ - durationSeconds: number; - /** Findings */ - findings: components["schemas"]["ScanFindingResponse"][]; - /** Findingscount */ - findingsCount: number; - /** Issafe */ - isSafe: boolean; - /** Maxseverity */ - maxSeverity: string; - /** Skillname */ - skillName: string; + sourceKind: "managed" | "harness"; + }; + /** ScaffoldRequest */ + ScaffoldRequest: { + /** Asset Type */ + asset_type: string; + /** Description */ + description: string; + /** Name */ + name: string; + }; + /** ScaffoldResponse */ + ScaffoldResponse: { + /** File Path */ + file_path: string; + }; + /** SetAgentHarnessesRequest */ + SetAgentHarnessesRequest: { + /** Harnesses */ + harnesses?: string[]; + }; + /** SetAgentHarnessesResultResponse */ + SetAgentHarnessesResultResponse: { + /** Failed */ + failed: components["schemas"]["AgentMutationFailureResponse"][]; + /** Ok */ + ok: boolean; + /** Succeeded */ + succeeded: string[]; }; /** SetHarnessSupportRequest */ SetHarnessSupportRequest: { /** Enabled */ enabled: boolean; }; + /** SetHookHarnessesRequest */ + SetHookHarnessesRequest: { + /** + * Target + * @enum {string} + */ + target: "enabled" | "disabled"; + }; /** SetMcpServerHarnessesRequest */ SetMcpServerHarnessesRequest: { /** Config */ @@ -1886,6 +2422,14 @@ export interface components { */ target: "enabled" | "disabled"; }; + /** SetPermissionHarnessesRequest */ + SetPermissionHarnessesRequest: { + /** + * Target + * @enum {string} + */ + target: "enabled" | "disabled"; + }; /** SetSkillHarnessesFailureResponse */ SetSkillHarnessesFailureResponse: { /** Error */ @@ -2083,14 +2627,14 @@ export interface components { * Target * @enum {string} */ - target: "opencode" | "claude" | "cursor" | "codex"; + target: "claude" | "codex" | "cursor" | "opencode" | "hermes"; }; /** SlashCommandListResponse */ SlashCommandListResponse: { /** Commands */ commands: components["schemas"]["SlashCommandResponse"][]; /** Defaulttargets */ - defaultTargets: ("opencode" | "claude" | "cursor" | "codex")[]; + defaultTargets: ("claude" | "codex" | "cursor" | "opencode" | "hermes")[]; /** Reviewcommands */ reviewCommands: components["schemas"]["SlashCommandReviewResponse"][]; /** Storepath */ @@ -2109,7 +2653,7 @@ export interface components { /** Prompt */ prompt: string; /** Targets */ - targets?: ("opencode" | "claude" | "cursor" | "codex")[] | null; + targets?: ("claude" | "codex" | "cursor" | "opencode" | "hermes")[] | null; }; /** SlashCommandMutationResponse */ SlashCommandMutationResponse: { @@ -2132,7 +2676,7 @@ export interface components { * Target * @enum {string} */ - target: "opencode" | "claude" | "cursor" | "codex"; + target: "claude" | "codex" | "cursor" | "opencode" | "hermes"; }; /** SlashCommandResponse */ SlashCommandResponse: { @@ -2174,111 +2718,680 @@ export interface components { * Target * @enum {string} */ - target: "opencode" | "claude" | "cursor" | "codex"; + target: "claude" | "codex" | "cursor" | "opencode" | "hermes"; /** Targetlabel */ targetLabel: string; }; - /** SlashCommandUpdateRequest */ - SlashCommandUpdateRequest: { - /** Description */ - description: string; - /** Prompt */ - prompt: string; - /** Targets */ - targets?: ("opencode" | "claude" | "cursor" | "codex")[] | null; + /** SlashCommandUpdateRequest */ + SlashCommandUpdateRequest: { + /** Description */ + description: string; + /** Prompt */ + prompt: string; + /** Targets */ + targets?: ("claude" | "codex" | "cursor" | "opencode" | "hermes")[] | null; + }; + /** SlashSyncEntryResponse */ + SlashSyncEntryResponse: { + /** Error */ + error?: string | null; + /** Path */ + path: string; + /** + * Status + * @enum {string} + */ + status: "synced" | "removed" | "not_selected" | "blocked_manual_file" | "blocked_modified_file" | "missing" | "drifted" | "failed"; + /** + * Target + * @enum {string} + */ + target: "claude" | "codex" | "cursor" | "opencode" | "hermes"; + }; + /** SlashSyncRequest */ + SlashSyncRequest: { + /** Targets */ + targets?: ("claude" | "codex" | "cursor" | "opencode" | "hermes")[] | null; + }; + /** SlashTargetResponse */ + SlashTargetResponse: { + /** Available */ + available: boolean; + /** Defaultselected */ + defaultSelected: boolean; + /** Docsurl */ + docsUrl: string; + /** Enabled */ + enabled: boolean; + /** Fileglob */ + fileGlob: string; + /** + * Id + * @enum {string} + */ + id: "claude" | "codex" | "cursor" | "opencode" | "hermes"; + /** Invocationprefix */ + invocationPrefix: string; + /** Label */ + label: string; + /** Outputdir */ + outputDir: string; + /** + * Renderformat + * @enum {string} + */ + renderFormat: "frontmatter_markdown" | "cursor_plaintext"; + /** Rootpath */ + rootPath: string; + /** + * Scope + * @enum {string} + */ + scope: "global" | "project"; + /** Supportnote */ + supportNote?: string | null; + /** Supportsfrontmatter */ + supportsFrontmatter: boolean; + }; + /** UpdateAgentRequest */ + UpdateAgentRequest: { + /** Description */ + description?: string | null; + /** Name */ + name?: string | null; + /** Prompt */ + prompt?: string | null; + /** Tools */ + tools?: string[] | null; + }; + /** ValidationError */ + ValidationError: { + /** Context */ + ctx?: Record; + /** Input */ + input?: unknown; + /** Location */ + loc: (string | number)[]; + /** Message */ + msg: string; + /** Error Type */ + type: string; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} +export type $defs = Record; +export interface operations { + list_agents_api_agents_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AgentInventoryResponse"]; + }; + }; + }; + }; + create_agent_api_agents_post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateAgentRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AgentDetailResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + adopt_all_agents_api_agents_adopt_all_post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AdoptAllAgentsResponse"]; + }; + }; + }; + }; + get_agent_api_agents__agent_ref__get: { + parameters: { + query?: never; + header?: never; + path: { + agent_ref: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AgentDetailResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + update_agent_api_agents__agent_ref__put: { + parameters: { + query?: never; + header?: never; + path: { + agent_ref: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateAgentRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AgentDetailResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + delete_agent_api_agents__agent_ref__delete: { + parameters: { + query?: never; + header?: never; + path: { + agent_ref: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["OkResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + adopt_agent_api_agents__agent_ref__adopt_post: { + parameters: { + query?: never; + header?: never; + path: { + agent_ref: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AdoptAgentRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AdoptAgentResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + disable_agent_api_agents__agent_ref__disable_post: { + parameters: { + query?: never; + header?: never; + path: { + agent_ref: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AgentHarnessRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["OkResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + enable_agent_api_agents__agent_ref__enable_post: { + parameters: { + query?: never; + header?: never; + path: { + agent_ref: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AgentHarnessRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["OkResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + set_agent_harnesses_api_agents__agent_ref__set_harnesses_post: { + parameters: { + query?: never; + header?: never; + path: { + agent_ref: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SetAgentHarnessesRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SetAgentHarnessesResultResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + health_api_health_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": { + [key: string]: unknown; + }; + }; + }; + }; + }; + list_hooks_api_hooks_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HookInventoryResponse"]; + }; + }; + }; + }; + create_hook_api_hooks_post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AddHookRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HookMutationResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + get_hook_api_hooks__id__get: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HookInventoryEntryResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + delete_hook_api_hooks__id__delete: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HookSetHarnessesResultResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + disable_hook_api_hooks__id__disable_post: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DisableHookRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["OkResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + enable_hook_api_hooks__id__enable_post: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["EnableHookRequest"]; + }; }; - /** SlashSyncEntryResponse */ - SlashSyncEntryResponse: { - /** Error */ - error?: string | null; - /** Path */ - path: string; - /** - * Status - * @enum {string} - */ - status: "synced" | "removed" | "not_selected" | "blocked_manual_file" | "blocked_modified_file" | "missing" | "drifted" | "failed"; - /** - * Target - * @enum {string} - */ - target: "opencode" | "claude" | "cursor" | "codex"; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["OkResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; }; - /** SlashSyncRequest */ - SlashSyncRequest: { - /** Targets */ - targets?: ("opencode" | "claude" | "cursor" | "codex")[] | null; + }; + promote_hook_api_hooks__id__promote_post: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; }; - /** SlashTargetResponse */ - SlashTargetResponse: { - /** Available */ - available: boolean; - /** Defaultselected */ - defaultSelected: boolean; - /** Docsurl */ - docsUrl: string; - /** Enabled */ - enabled: boolean; - /** Fileglob */ - fileGlob: string; - /** - * Id - * @enum {string} - */ - id: "opencode" | "claude" | "cursor" | "codex"; - /** Invocationprefix */ - invocationPrefix: string; - /** Label */ - label: string; - /** Outputdir */ - outputDir: string; - /** - * Renderformat - * @enum {string} - */ - renderFormat: "frontmatter_markdown" | "cursor_plaintext"; - /** Rootpath */ - rootPath: string; - /** - * Scope - * @enum {string} - */ - scope: "global" | "project"; - /** Supportnote */ - supportNote?: string | null; - /** Supportsfrontmatter */ - supportsFrontmatter: boolean; + requestBody: { + content: { + "application/json": components["schemas"]["PromoteHookRequest"]; + }; }; - /** ValidationError */ - ValidationError: { - /** Context */ - ctx?: Record; - /** Input */ - input?: unknown; - /** Location */ - loc: (string | number)[]; - /** Message */ - msg: string; - /** Error Type */ - type: string; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HookMutationResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; }; }; - responses: never; - parameters: never; - requestBodies: never; - headers: never; - pathItems: never; -} -export type $defs = Record; -export interface operations { - health_api_health_get: { + reconcile_hook_api_hooks__id__reconcile_post: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + "application/json": components["schemas"]["ReconcileHookRequest"]; + }; + }; responses: { /** @description Successful Response */ 200: { @@ -2286,9 +3399,51 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": { - [key: string]: unknown; - }; + "application/json": components["schemas"]["HookApplyConfigResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + set_hook_harnesses_api_hooks__id__set_harnesses_post: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SetHookHarnessesRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HookSetHarnessesResultResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; }; }; }; @@ -2996,7 +4151,7 @@ export interface operations { }; }; }; - check_scan_availability_api_scan_availability_get: { + list_permissions_api_permissions_get: { parameters: { query?: never; header?: never; @@ -3011,19 +4166,23 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["ScanAvailabilityResponse"]; + "application/json": components["schemas"]["PermissionInventoryResponse"]; }; }; }; }; - list_scan_configs_api_scan_configs_get: { + create_permission_api_permissions_post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + "application/json": components["schemas"]["AddPermissionRequest"]; + }; + }; responses: { /** @description Successful Response */ 200: { @@ -3031,23 +4190,30 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["ScanConfigListResponse"]; + "application/json": components["schemas"]["PermissionMutationResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; }; }; }; }; - create_scan_config_api_scan_configs_post: { + get_permission_api_permissions__id__get: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["ScanConfigSaveRequest"]; + path: { + id: string; }; + cookie?: never; }; + requestBody?: never; responses: { /** @description Successful Response */ 200: { @@ -3055,7 +4221,7 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["ScanConfigItem"]; + "application/json": components["schemas"]["PermissionInventoryEntryResponse"]; }; }; /** @description Validation Error */ @@ -3069,18 +4235,16 @@ export interface operations { }; }; }; - validate_scan_config_api_scan_configs_validate_post: { + delete_permission_api_permissions__id__delete: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["ScanConfigValidateRequest"]; + path: { + id: string; }; + cookie?: never; }; + requestBody?: never; responses: { /** @description Successful Response */ 200: { @@ -3088,7 +4252,7 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["ScanConfigValidationResponse"]; + "application/json": components["schemas"]["PermissionSetHarnessesResultResponse"]; }; }; /** @description Validation Error */ @@ -3102,18 +4266,18 @@ export interface operations { }; }; }; - update_scan_config_api_scan_configs__config_id__put: { + disable_permission_api_permissions__id__disable_post: { parameters: { query?: never; header?: never; path: { - config_id: number; + id: string; }; cookie?: never; }; requestBody: { content: { - "application/json": components["schemas"]["ScanConfigSaveRequest"]; + "application/json": components["schemas"]["DisablePermissionRequest"]; }; }; responses: { @@ -3123,7 +4287,7 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["ScanConfigItem"]; + "application/json": components["schemas"]["OkResponse"]; }; }; /** @description Validation Error */ @@ -3137,16 +4301,20 @@ export interface operations { }; }; }; - delete_scan_config_api_scan_configs__config_id__delete: { + enable_permission_api_permissions__id__enable_post: { parameters: { query?: never; header?: never; path: { - config_id: number; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + "application/json": components["schemas"]["EnablePermissionRequest"]; + }; + }; responses: { /** @description Successful Response */ 200: { @@ -3154,7 +4322,7 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": unknown; + "application/json": components["schemas"]["OkResponse"]; }; }; /** @description Validation Error */ @@ -3168,16 +4336,20 @@ export interface operations { }; }; }; - set_active_scan_config_api_scan_configs__config_id__active_put: { + promote_permission_api_permissions__id__promote_post: { parameters: { query?: never; header?: never; path: { - config_id: number; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + "application/json": components["schemas"]["PromotePermissionRequest"]; + }; + }; responses: { /** @description Successful Response */ 200: { @@ -3185,7 +4357,7 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": unknown; + "application/json": components["schemas"]["PermissionMutationResponse"]; }; }; /** @description Validation Error */ @@ -3199,16 +4371,20 @@ export interface operations { }; }; }; - reveal_scan_config_secret_api_scan_configs__config_id__secret_get: { + reconcile_permission_api_permissions__id__reconcile_post: { parameters: { query?: never; header?: never; path: { - config_id: number; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + "application/json": components["schemas"]["ReconcilePermissionRequest"]; + }; + }; responses: { /** @description Successful Response */ 200: { @@ -3216,7 +4392,7 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["ScanConfigSecretResponse"]; + "application/json": components["schemas"]["PermissionApplyConfigResponse"]; }; }; /** @description Validation Error */ @@ -3230,14 +4406,20 @@ export interface operations { }; }; }; - detect_llm_api_scan_llm_detection_get: { + set_permission_harnesses_api_permissions__id__set_harnesses_post: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + "application/json": components["schemas"]["SetPermissionHarnessesRequest"]; + }; + }; responses: { /** @description Successful Response */ 200: { @@ -3245,23 +4427,30 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["LLMDetectionResponse"]; + "application/json": components["schemas"]["PermissionSetHarnessesResultResponse"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; }; }; }; }; - scan_skill_api_scan_skills__skill_ref__post: { + scaffold_asset_api_scaffold_post: { parameters: { query?: never; header?: never; - path: { - skill_ref: string; - }; + path?: never; cookie?: never; }; - requestBody?: { + requestBody: { content: { - "application/json": components["schemas"]["ScanOptionsRequest"] | null; + "application/json": components["schemas"]["ScaffoldRequest"]; }; }; responses: { @@ -3271,7 +4460,7 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["ScanResultResponse"]; + "application/json": components["schemas"]["ScaffoldResponse"]; }; }; /** @description Validation Error */ diff --git a/frontend/src/api/openapi.json b/frontend/src/api/openapi.json index 26971799..d18cc864 100644 --- a/frontend/src/api/openapi.json +++ b/frontend/src/api/openapi.json @@ -1,6 +1,60 @@ { "components": { "schemas": { + "AddHookRequest": { + "additionalProperties": false, + "properties": { + "command": { + "minLength": 1, + "title": "Command", + "type": "string" + }, + "description": { + "default": "", + "title": "Description", + "type": "string" + }, + "event": { + "minLength": 1, + "title": "Event", + "type": "string" + }, + "id": { + "minLength": 1, + "title": "Id", + "type": "string" + }, + "match": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Match" + }, + "timeout": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Timeout" + } + }, + "required": [ + "id", + "event", + "command" + ], + "title": "AddHookRequest", + "type": "object" + }, "AddMcpServerRequest": { "additionalProperties": false, "properties": { @@ -16,118 +70,158 @@ "title": "AddMcpServerRequest", "type": "object" }, - "AdoptMcpRequest": { + "AddPermissionRequest": { "additionalProperties": false, "properties": { - "harnesses": { + "decision": { + "minLength": 1, + "title": "Decision", + "type": "string" + }, + "description": { + "default": "", + "title": "Description", + "type": "string" + }, + "id": { + "minLength": 1, + "title": "Id", + "type": "string" + }, + "pattern": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "type": "string" }, { "type": "null" } ], - "title": "Harnesses" + "title": "Pattern" }, - "name": { + "scope": { "minLength": 1, - "title": "Name", + "title": "Scope", "type": "string" - }, - "observedHarness": { + } + }, + "required": [ + "id", + "decision", + "scope" + ], + "title": "AddPermissionRequest", + "type": "object" + }, + "AdoptAgentRequest": { + "properties": { + "onConflict": { "anyOf": [ { + "enum": [ + "keep_store", + "replace_store" + ], "type": "string" }, { "type": "null" } ], - "title": "Observed harness" + "title": "Onconflict" } }, - "required": [ - "name" - ], - "title": "AdoptMcpRequest", + "title": "AdoptAgentRequest", "type": "object" }, - "BulkManageFailureResponse": { + "AdoptAgentResponse": { "properties": { - "error": { - "title": "Error", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" + "ok": { + "title": "Ok", + "type": "boolean" }, - "skillRef": { - "title": "Skillref", + "ref": { + "title": "Ref", "type": "string" } }, "required": [ - "skillRef", - "name", - "error" + "ok", + "ref" ], - "title": "BulkManageFailureResponse", + "title": "AdoptAgentResponse", "type": "object" }, - "BulkManageResultResponse": { + "AdoptAllAgentsResponse": { "properties": { - "failures": { + "adopted": { "items": { - "$ref": "#/components/schemas/BulkManageFailureResponse" + "type": "string" }, - "title": "Failures", + "title": "Adopted", "type": "array" }, - "managedCount": { - "title": "Managedcount", - "type": "integer" - }, "ok": { "title": "Ok", "type": "boolean" }, - "skippedCount": { - "title": "Skippedcount", - "type": "integer" + "skipped": { + "items": { + "$ref": "#/components/schemas/AdoptAllSkippedResponse" + }, + "title": "Skipped", + "type": "array" } }, "required": [ "ok", - "managedCount", - "skippedCount", - "failures" + "adopted", + "skipped" ], - "title": "BulkManageResultResponse", + "title": "AdoptAllAgentsResponse", "type": "object" }, - "CliMarketplaceDetailResponse": { + "AdoptAllSkippedResponse": { "properties": { - "category": { + "reason": { + "title": "Reason", + "type": "string" + }, + "ref": { + "title": "Ref", + "type": "string" + } + }, + "required": [ + "ref", + "reason" + ], + "title": "AdoptAllSkippedResponse", + "type": "object" + }, + "AdoptMcpRequest": { + "additionalProperties": false, + "properties": { + "harnesses": { "anyOf": [ { - "type": "string" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } ], - "title": "Category" + "title": "Harnesses" }, - "description": { - "title": "Description", + "name": { + "minLength": 1, + "title": "Name", "type": "string" }, - "githubUrl": { + "observedHarness": { "anyOf": [ { "type": "string" @@ -136,17 +230,36 @@ "type": "null" } ], - "title": "Githuburl" - }, - "hasMcp": { - "title": "Hasmcp", + "title": "Observed harness" + } + }, + "required": [ + "name" + ], + "title": "AdoptMcpRequest", + "type": "object" + }, + "AgentActionsResponse": { + "properties": { + "canAdopt": { + "title": "Canadopt", "type": "boolean" }, - "hasSkill": { - "title": "Hasskill", + "canDelete": { + "title": "Candelete", "type": "boolean" - }, - "iconUrl": { + } + }, + "required": [ + "canAdopt", + "canDelete" + ], + "title": "AgentActionsResponse", + "type": "object" + }, + "AgentBindingResponse": { + "properties": { + "detail": { "anyOf": [ { "type": "string" @@ -155,43 +268,44 @@ "type": "null" } ], - "title": "Iconurl" + "title": "Detail" }, - "id": { - "title": "Id", + "harness": { + "title": "Harness", "type": "string" }, - "installCommand": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } + "state": { + "enum": [ + "enabled", + "disabled", + "unsupported" ], - "title": "Installcommand" - }, - "isOfficial": { - "title": "Isofficial", - "type": "boolean" + "title": "State", + "type": "string" + } + }, + "required": [ + "harness", + "state" + ], + "title": "AgentBindingResponse", + "type": "object" + }, + "AgentColumnResponse": { + "properties": { + "harness": { + "title": "Harness", + "type": "string" }, - "isTui": { - "title": "Istui", + "installed": { + "title": "Installed", "type": "boolean" }, - "language": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Language" + "label": { + "title": "Label", + "type": "string" }, - "longDescription": { + "logoKey": { "anyOf": [ { "type": "string" @@ -200,97 +314,119 @@ "type": "null" } ], - "title": "Longdescription" - }, - "marketplaceUrl": { - "title": "Marketplaceurl", + "title": "Logokey" + } + }, + "required": [ + "harness", + "label", + "installed" + ], + "title": "AgentColumnResponse", + "type": "object" + }, + "AgentConfigEntryResponse": { + "description": "One frontmatter key we do not interpret, shown verbatim.", + "properties": { + "key": { + "title": "Key", "type": "string" }, + "value": { + "title": "Value", + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "title": "AgentConfigEntryResponse", + "type": "object" + }, + "AgentDetailResponse": { + "properties": { + "canDelete": { + "title": "Candelete", + "type": "boolean" + }, + "configuration": { + "items": { + "$ref": "#/components/schemas/AgentConfigEntryResponse" + }, + "title": "Configuration", + "type": "array" + }, + "description": { + "title": "Description", + "type": "string" + }, + "document": { + "title": "Document", + "type": "string" + }, + "harnesses": { + "items": { + "$ref": "#/components/schemas/AgentHarnessDetailResponse" + }, + "title": "Harnesses", + "type": "array" + }, "name": { "title": "Name", "type": "string" }, - "slug": { - "title": "Slug", + "prompt": { + "title": "Prompt", "type": "string" }, - "sourceType": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Sourcetype" - }, - "stars": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Stars" + "ref": { + "title": "Ref", + "type": "string" }, - "vendorName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Vendorname" + "storePath": { + "title": "Storepath", + "type": "string" }, - "websiteUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Websiteurl" + "tools": { + "items": { + "type": "string" + }, + "title": "Tools", + "type": "array" } }, "required": [ - "id", - "slug", + "ref", "name", "description", - "marketplaceUrl", - "hasMcp", - "hasSkill", - "isOfficial", - "isTui" + "prompt", + "tools", + "document", + "storePath", + "harnesses", + "canDelete" ], - "title": "CliMarketplaceDetailResponse", + "title": "AgentDetailResponse", "type": "object" }, - "CliMarketplaceItemResponse": { + "AgentEntryResponse": { "properties": { - "category": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Category" + "actions": { + "$ref": "#/components/schemas/AgentActionsResponse" + }, + "bindings": { + "items": { + "$ref": "#/components/schemas/AgentBindingResponse" + }, + "title": "Bindings", + "type": "array" }, "description": { "title": "Description", "type": "string" }, - "githubUrl": { + "harnessPath": { "anyOf": [ { "type": "string" @@ -299,40 +435,39 @@ "type": "null" } ], - "title": "Githuburl" - }, - "hasMcp": { - "title": "Hasmcp", - "type": "boolean" + "title": "Harnesspath" }, - "hasSkill": { - "title": "Hasskill", - "type": "boolean" - }, - "iconUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } + "kind": { + "enum": [ + "managed", + "unmanaged" ], - "title": "Iconurl" - }, - "id": { - "title": "Id", + "title": "Kind", "type": "string" }, - "isOfficial": { - "title": "Isofficial", - "type": "boolean" - }, - "isTui": { - "title": "Istui", - "type": "boolean" + "name": { + "title": "Name", + "type": "string" }, - "language": { + "ref": { + "title": "Ref", + "type": "string" + } + }, + "required": [ + "ref", + "name", + "description", + "kind", + "bindings", + "actions" + ], + "title": "AgentEntryResponse", + "type": "object" + }, + "AgentHarnessDetailResponse": { + "properties": { + "detail": { "anyOf": [ { "type": "string" @@ -341,21 +476,30 @@ "type": "null" } ], - "title": "Language" + "title": "Detail" }, - "marketplaceUrl": { - "title": "Marketplaceurl", + "harness": { + "title": "Harness", "type": "string" }, - "name": { - "title": "Name", + "installMethod": { + "enum": [ + "symlink", + "rendered", + "none" + ], + "title": "Installmethod", "type": "string" }, - "slug": { - "title": "Slug", + "installed": { + "title": "Installed", + "type": "boolean" + }, + "label": { + "title": "Label", "type": "string" }, - "sourceType": { + "logoKey": { "anyOf": [ { "type": "string" @@ -364,233 +508,170 @@ "type": "null" } ], - "title": "Sourcetype" - }, - "stars": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Stars" + "title": "Logokey" }, - "vendorName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Vendorname" + "path": { + "title": "Path", + "type": "string" }, - "websiteUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } + "state": { + "enum": [ + "enabled", + "disabled", + "unsupported" ], - "title": "Websiteurl" + "title": "State", + "type": "string" } }, "required": [ - "id", - "slug", - "name", - "description", - "marketplaceUrl", - "hasMcp", - "hasSkill", - "isOfficial", - "isTui" + "harness", + "label", + "state", + "path", + "installMethod", + "installed" ], - "title": "CliMarketplaceItemResponse", + "title": "AgentHarnessDetailResponse", "type": "object" }, - "CliMarketplacePageResponse": { + "AgentHarnessRequest": { "properties": { - "hasMore": { - "title": "Hasmore", - "type": "boolean" - }, - "items": { - "items": { - "$ref": "#/components/schemas/CliMarketplaceItemResponse" - }, - "title": "Items", - "type": "array" - }, - "nextOffset": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Nextoffset" + "harness": { + "title": "Harness", + "type": "string" } }, "required": [ - "items", - "hasMore" + "harness" ], - "title": "CliMarketplacePageResponse", + "title": "AgentHarnessRequest", "type": "object" }, - "DetectedProviderResponse": { + "AgentInventoryResponse": { "properties": { - "apiKeySource": { - "title": "Apikeysource", - "type": "string" - }, - "baseUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Baseurl" - }, - "isAvailable": { - "title": "Isavailable", - "type": "boolean" + "columns": { + "items": { + "$ref": "#/components/schemas/AgentColumnResponse" + }, + "title": "Columns", + "type": "array" }, - "model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Model" + "entries": { + "items": { + "$ref": "#/components/schemas/AgentEntryResponse" + }, + "title": "Entries", + "type": "array" }, - "provider": { - "title": "Provider", - "type": "string" + "issues": { + "items": { + "$ref": "#/components/schemas/AgentIssueResponse" + }, + "title": "Issues", + "type": "array" } }, "required": [ - "provider", - "apiKeySource", - "isAvailable" + "columns", + "entries" ], - "title": "DetectedProviderResponse", + "title": "AgentInventoryResponse", "type": "object" }, - "DisableMcpServerRequest": { + "AgentIssueResponse": { "properties": { - "harness": { - "description": "Harness identifier", - "minLength": 1, - "title": "Harness", + "name": { + "title": "Name", "type": "string" - } - }, - "required": [ - "harness" - ], - "title": "DisableMcpServerRequest", - "type": "object" - }, - "DisableSkillRequest": { - "properties": { - "harness": { - "description": "Harness identifier", - "minLength": 1, - "title": "Harness", + }, + "reason": { + "title": "Reason", "type": "string" } }, "required": [ - "harness" + "name", + "reason" ], - "title": "DisableSkillRequest", + "title": "AgentIssueResponse", "type": "object" }, - "EnableMcpServerRequest": { + "AgentMutationFailureResponse": { "properties": { - "config": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "title": "Config" + "error": { + "title": "Error", + "type": "string" }, "harness": { - "description": "Harness identifier", - "minLength": 1, "title": "Harness", "type": "string" } }, "required": [ - "harness" + "harness", + "error" ], - "title": "EnableMcpServerRequest", + "title": "AgentMutationFailureResponse", "type": "object" }, - "EnableSkillRequest": { + "BulkManageFailureResponse": { "properties": { - "harness": { - "description": "Harness identifier", - "minLength": 1, - "title": "Harness", + "error": { + "title": "Error", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "skillRef": { + "title": "Skillref", "type": "string" } }, "required": [ - "harness" + "skillRef", + "name", + "error" ], - "title": "EnableSkillRequest", + "title": "BulkManageFailureResponse", "type": "object" }, - "HTTPValidationError": { + "BulkManageResultResponse": { "properties": { - "detail": { + "failures": { "items": { - "$ref": "#/components/schemas/ValidationError" + "$ref": "#/components/schemas/BulkManageFailureResponse" }, - "title": "Detail", + "title": "Failures", "type": "array" + }, + "managedCount": { + "title": "Managedcount", + "type": "integer" + }, + "ok": { + "title": "Ok", + "type": "boolean" + }, + "skippedCount": { + "title": "Skippedcount", + "type": "integer" } }, - "title": "HTTPValidationError", + "required": [ + "ok", + "managedCount", + "skippedCount", + "failures" + ], + "title": "BulkManageResultResponse", "type": "object" }, - "HarnessCellResponse": { + "CliMarketplaceDetailResponse": { "properties": { - "harness": { - "title": "Harness", - "type": "string" - }, - "interactive": { - "title": "Interactive", - "type": "boolean" - }, - "label": { - "title": "Label", - "type": "string" - }, - "logoKey": { + "category": { "anyOf": [ { "type": "string" @@ -599,43 +680,13 @@ "type": "null" } ], - "title": "Logokey" - }, - "state": { - "enum": [ - "enabled", - "disabled", - "found", - "empty" - ], - "title": "State", - "type": "string" - } - }, - "required": [ - "harness", - "label", - "state", - "interactive" - ], - "title": "HarnessCellResponse", - "type": "object" - }, - "HarnessColumnResponse": { - "properties": { - "harness": { - "title": "Harness", - "type": "string" - }, - "installed": { - "title": "Installed", - "type": "boolean" + "title": "Category" }, - "label": { - "title": "Label", + "description": { + "title": "Description", "type": "string" }, - "logoKey": { + "githubUrl": { "anyOf": [ { "type": "string" @@ -644,34 +695,17 @@ "type": "null" } ], - "title": "Logokey" - } - }, - "required": [ - "harness", - "label", - "installed" - ], - "title": "HarnessColumnResponse", - "type": "object" - }, - "InstallMarketplaceSkillRequest": { - "properties": { - "installToken": { - "minLength": 1, - "title": "Installtoken", - "type": "string" - } - }, - "required": [ - "installToken" - ], - "title": "InstallMarketplaceSkillRequest", - "type": "object" - }, - "LLMDetectionResponse": { - "properties": { - "defaultModel": { + "title": "Githuburl" + }, + "hasMcp": { + "title": "Hasmcp", + "type": "boolean" + }, + "hasSkill": { + "title": "Hasskill", + "type": "boolean" + }, + "iconUrl": { "anyOf": [ { "type": "string" @@ -680,9 +714,13 @@ "type": "null" } ], - "title": "Defaultmodel" + "title": "Iconurl" + }, + "id": { + "title": "Id", + "type": "string" }, - "defaultProvider": { + "installCommand": { "anyOf": [ { "type": "string" @@ -691,30 +729,17 @@ "type": "null" } ], - "title": "Defaultprovider" + "title": "Installcommand" }, - "hasAnyAvailable": { - "title": "Hasanyavailable", + "isOfficial": { + "title": "Isofficial", "type": "boolean" }, - "providers": { - "items": { - "$ref": "#/components/schemas/DetectedProviderResponse" - }, - "title": "Providers", - "type": "array" - } - }, - "required": [ - "providers", - "hasAnyAvailable" - ], - "title": "LLMDetectionResponse", - "type": "object" - }, - "McpAdoptionIssueResponse": { - "properties": { - "configPath": { + "isTui": { + "title": "Istui", + "type": "boolean" + }, + "language": { "anyOf": [ { "type": "string" @@ -723,17 +748,9 @@ "type": "null" } ], - "title": "Configpath" - }, - "harness": { - "title": "Harness", - "type": "string" - }, - "label": { - "title": "Label", - "type": "string" + "title": "Language" }, - "logoKey": { + "longDescription": { "anyOf": [ { "type": "string" @@ -742,112 +759,43 @@ "type": "null" } ], - "title": "Logokey" + "title": "Longdescription" + }, + "marketplaceUrl": { + "title": "Marketplaceurl", + "type": "string" }, "name": { "title": "Name", "type": "string" }, - "payloadPreview": { + "slug": { + "title": "Slug", + "type": "string" + }, + "sourceType": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "title": "Payloadpreview" - }, - "reason": { - "title": "Reason", - "type": "string" - } - }, - "required": [ - "harness", - "label", - "name", - "reason" - ], - "title": "McpAdoptionIssueResponse", - "type": "object" - }, - "McpApplyConfigResponse": { - "properties": { - "failed": { - "items": { - "$ref": "#/components/schemas/McpMutationFailureResponse" - }, - "title": "Failed", - "type": "array" - }, - "ok": { - "title": "Ok", - "type": "boolean" - }, - "server": { - "$ref": "#/components/schemas/McpServerSpecResponse" + "title": "Sourcetype" }, - "succeeded": { - "items": { - "type": "string" - }, - "title": "Succeeded", - "type": "array" - } - }, - "required": [ - "ok", - "server", - "succeeded", - "failed" - ], - "title": "McpApplyConfigResponse", - "type": "object" - }, - "McpAvailabilityCheckResponse": { - "properties": { - "availabilityReason": { + "stars": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Availabilityreason" - }, - "availabilityStatus": { - "enum": [ - "available", - "unavailable" - ], - "title": "Availabilitystatus", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" + "title": "Stars" }, - "ok": { - "title": "Ok", - "type": "boolean" - } - }, - "required": [ - "ok", - "name", - "availabilityStatus" - ], - "title": "McpAvailabilityCheckResponse", - "type": "object" - }, - "McpBindingResponse": { - "properties": { - "driftDetail": { + "vendorName": { "anyOf": [ { "type": "string" @@ -856,33 +804,37 @@ "type": "null" } ], - "title": "Driftdetail" - }, - "harness": { - "title": "Harness", - "type": "string" + "title": "Vendorname" }, - "state": { - "enum": [ - "managed", - "drifted", - "unmanaged", - "missing" + "websiteUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } ], - "title": "State", - "type": "string" + "title": "Websiteurl" } }, "required": [ - "harness", - "state" + "id", + "slug", + "name", + "description", + "marketplaceUrl", + "hasMcp", + "hasSkill", + "isOfficial", + "isTui" ], - "title": "McpBindingResponse", + "title": "CliMarketplaceDetailResponse", "type": "object" }, - "McpConfigChoiceResponse": { + "CliMarketplaceItemResponse": { "properties": { - "configPath": { + "category": { "anyOf": [ { "type": "string" @@ -891,24 +843,13 @@ "type": "null" } ], - "title": "Configpath" - }, - "env": { - "items": { - "$ref": "#/components/schemas/McpEnvEntryResponse" - }, - "title": "Env", - "type": "array" - }, - "id": { - "title": "Id", - "type": "string" + "title": "Category" }, - "label": { - "title": "Label", + "description": { + "title": "Description", "type": "string" }, - "logoKey": { + "githubUrl": { "anyOf": [ { "type": "string" @@ -917,9 +858,17 @@ "type": "null" } ], - "title": "Logokey" + "title": "Githuburl" }, - "observedHarness": { + "hasMcp": { + "title": "Hasmcp", + "type": "boolean" + }, + "hasSkill": { + "title": "Hasskill", + "type": "boolean" + }, + "iconUrl": { "anyOf": [ { "type": "string" @@ -928,51 +877,21 @@ "type": "null" } ], - "title": "Observed harness" - }, - "payloadPreview": { - "additionalProperties": true, - "title": "Payloadpreview", - "type": "object" - }, - "recommended": { - "default": false, - "title": "Recommended", - "type": "boolean" + "title": "Iconurl" }, - "sourceKind": { - "enum": [ - "managed", - "harness" - ], - "title": "Sourcekind", + "id": { + "title": "Id", "type": "string" }, - "spec": { - "$ref": "#/components/schemas/McpServerSpecResponse" - } - }, - "required": [ - "id", - "sourceKind", - "label", - "payloadPreview", - "spec" - ], - "title": "McpConfigChoiceResponse", - "type": "object" - }, - "McpEnvEntryResponse": { - "properties": { - "isEnvRef": { - "title": "Isenvref", + "isOfficial": { + "title": "Isofficial", "type": "boolean" }, - "key": { - "title": "Key", - "type": "string" + "isTui": { + "title": "Istui", + "type": "boolean" }, - "value": { + "language": { "anyOf": [ { "type": "string" @@ -981,65 +900,43 @@ "type": "null" } ], - "title": "Value" - } - }, - "required": [ - "key", - "isEnvRef" - ], - "title": "McpEnvEntryResponse", - "type": "object" - }, - "McpIdentityGroupResponse": { - "properties": { - "canonicalSpec": { + "title": "Language" + }, + "marketplaceUrl": { + "title": "Marketplaceurl", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "slug": { + "title": "Slug", + "type": "string" + }, + "sourceType": { "anyOf": [ { - "$ref": "#/components/schemas/McpServerSpecResponse" + "type": "string" }, { "type": "null" } - ] - }, - "identical": { - "title": "Identical", - "type": "boolean" + ], + "title": "Sourcetype" }, - "marketplaceLink": { + "stars": { "anyOf": [ { - "$ref": "#/components/schemas/McpMarketplaceLinkResponse" + "type": "integer" }, { "type": "null" } - ] - }, - "name": { - "title": "Name", - "type": "string" + ], + "title": "Stars" }, - "sightings": { - "items": { - "$ref": "#/components/schemas/McpIdentitySightingResponse" - }, - "title": "Sightings", - "type": "array" - } - }, - "required": [ - "name", - "identical", - "sightings" - ], - "title": "McpIdentityGroupResponse", - "type": "object" - }, - "McpIdentitySightingResponse": { - "properties": { - "configPath": { + "vendorName": { "anyOf": [ { "type": "string" @@ -1048,24 +945,9 @@ "type": "null" } ], - "title": "Configpath" - }, - "env": { - "items": { - "$ref": "#/components/schemas/McpEnvEntryResponse" - }, - "title": "Env", - "type": "array" - }, - "harness": { - "title": "Harness", - "type": "string" - }, - "label": { - "title": "Label", - "type": "string" + "title": "Vendorname" }, - "logoKey": { + "websiteUrl": { "anyOf": [ { "type": "string" @@ -1074,404 +956,245 @@ "type": "null" } ], - "title": "Logokey" - }, - "payloadPreview": { - "additionalProperties": true, - "title": "Payloadpreview", - "type": "object" - }, - "recommended": { - "default": false, - "title": "Recommended", - "type": "boolean" - }, - "spec": { - "$ref": "#/components/schemas/McpServerSpecResponse" + "title": "Websiteurl" } }, "required": [ - "harness", - "label", - "payloadPreview", - "spec" + "id", + "slug", + "name", + "description", + "marketplaceUrl", + "hasMcp", + "hasSkill", + "isOfficial", + "isTui" ], - "title": "McpIdentitySightingResponse", + "title": "CliMarketplaceItemResponse", "type": "object" }, - "McpInstallConfigFieldResponse": { + "CliMarketplacePageResponse": { "properties": { - "choices": { + "hasMore": { + "title": "Hasmore", + "type": "boolean" + }, + "items": { "items": { - "type": "string" + "$ref": "#/components/schemas/CliMarketplaceItemResponse" }, - "title": "Choices", + "title": "Items", "type": "array" }, - "default": { + "nextOffset": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Default" - }, + "title": "Nextoffset" + } + }, + "required": [ + "items", + "hasMore" + ], + "title": "CliMarketplacePageResponse", + "type": "object" + }, + "CreateAgentRequest": { + "properties": { "description": { + "default": "", "title": "Description", "type": "string" }, - "format": { - "enum": [ - "string", - "number", - "boolean", - "filepath" - ], - "title": "Format", - "type": "string" - }, - "label": { - "title": "Label", - "type": "string" - }, "name": { "title": "Name", "type": "string" }, - "placeholder": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Placeholder" - }, - "required": { - "title": "Required", - "type": "boolean" - }, - "secret": { - "title": "Secret", - "type": "boolean" - }, - "target": { - "enum": [ - "env", - "header", - "urlVariable", - "packageArgument", - "runtimeArgument" - ], - "title": "Target", + "prompt": { + "default": "", + "title": "Prompt", "type": "string" + }, + "tools": { + "items": { + "type": "string" + }, + "title": "Tools", + "type": "array" } }, "required": [ - "name", - "label", - "description", - "format", - "required", - "secret", - "target" + "name" ], - "title": "McpInstallConfigFieldResponse", + "title": "CreateAgentRequest", "type": "object" }, - "McpInstallConfigResponse": { + "DisableHookRequest": { "properties": { - "fields": { - "items": { - "$ref": "#/components/schemas/McpInstallConfigFieldResponse" - }, - "title": "Fields", - "type": "array" - }, - "required": { - "title": "Required", - "type": "boolean" + "harness": { + "description": "Harness identifier", + "minLength": 1, + "title": "Harness", + "type": "string" } }, "required": [ - "required" + "harness" ], - "title": "McpInstallConfigResponse", + "title": "DisableHookRequest", "type": "object" }, - "McpInstallConfigStatusResponse": { + "DisableMcpServerRequest": { "properties": { - "configured": { - "title": "Configured", - "type": "boolean" - }, - "hasFields": { - "title": "Hasfields", - "type": "boolean" - }, - "missingRequired": { - "items": { - "type": "string" - }, - "title": "Missingrequired", - "type": "array" + "harness": { + "description": "Harness identifier", + "minLength": 1, + "title": "Harness", + "type": "string" } }, "required": [ - "hasFields", - "missingRequired", - "configured" + "harness" ], - "title": "McpInstallConfigStatusResponse", + "title": "DisableMcpServerRequest", "type": "object" }, - "McpInventoryColumnResponse": { + "DisablePermissionRequest": { "properties": { - "configPresent": { - "title": "Configpresent", - "type": "boolean" - }, "harness": { + "description": "Harness identifier", + "minLength": 1, "title": "Harness", "type": "string" - }, - "installed": { - "title": "Installed", - "type": "boolean" - }, - "label": { - "title": "Label", + } + }, + "required": [ + "harness" + ], + "title": "DisablePermissionRequest", + "type": "object" + }, + "DisableSkillRequest": { + "properties": { + "harness": { + "description": "Harness identifier", + "minLength": 1, + "title": "Harness", "type": "string" - }, - "logoKey": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Logokey" - }, - "mcpUnavailableReason": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Mcpunavailablereason" - }, - "mcpWritable": { - "default": true, - "title": "Mcpwritable", - "type": "boolean" } }, "required": [ - "harness", - "label", - "installed", - "configPresent" + "harness" ], - "title": "McpInventoryColumnResponse", + "title": "DisableSkillRequest", "type": "object" }, - "McpInventoryEntryResponse": { + "EnableHookRequest": { "properties": { - "availabilityReason": { + "harness": { + "description": "Harness identifier", + "minLength": 1, + "title": "Harness", + "type": "string" + } + }, + "required": [ + "harness" + ], + "title": "EnableHookRequest", + "type": "object" + }, + "EnableMcpServerRequest": { + "properties": { + "config": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Deprecated compatibility field; use mcpStatus.reason instead.", - "title": "Availabilityreason" - }, - "availabilityStatus": { - "description": "Deprecated compatibility field; use mcpStatus instead.", - "enum": [ - "available", - "unavailable" - ], - "title": "Availabilitystatus", - "type": "string" - }, - "canEnable": { - "title": "Canenable", - "type": "boolean" - }, - "displayName": { - "title": "Displayname", - "type": "string" - }, - "enabledStatus": { - "enum": [ - "enabled", - "disabled" - ], - "title": "Enabledstatus", - "type": "string" - }, - "installConfigStatus": { - "$ref": "#/components/schemas/McpInstallConfigStatusResponse" - }, - "kind": { - "enum": [ - "managed", - "unmanaged" - ], - "title": "Kind", - "type": "string" - }, - "mcpStatus": { - "$ref": "#/components/schemas/McpStatusResponse" + "title": "Config" }, - "name": { - "title": "Name", + "harness": { + "description": "Harness identifier", + "minLength": 1, + "title": "Harness", "type": "string" - }, - "sightings": { - "items": { - "$ref": "#/components/schemas/McpBindingResponse" - }, - "title": "Sightings", - "type": "array" - }, - "spec": { - "anyOf": [ - { - "$ref": "#/components/schemas/McpServerSpecResponse" - }, - { - "type": "null" - } - ] } }, "required": [ - "name", - "displayName", - "kind", - "canEnable", - "enabledStatus", - "availabilityStatus", - "mcpStatus", - "installConfigStatus", - "sightings" + "harness" ], - "title": "McpInventoryEntryResponse", + "title": "EnableMcpServerRequest", "type": "object" }, - "McpInventoryIssueResponse": { + "EnablePermissionRequest": { "properties": { - "name": { - "title": "Name", - "type": "string" - }, - "reason": { - "title": "Reason", + "harness": { + "description": "Harness identifier", + "minLength": 1, + "title": "Harness", "type": "string" } }, "required": [ - "name", - "reason" + "harness" ], - "title": "McpInventoryIssueResponse", + "title": "EnablePermissionRequest", "type": "object" }, - "McpInventoryResponse": { + "EnableSkillRequest": { "properties": { - "columns": { - "items": { - "$ref": "#/components/schemas/McpInventoryColumnResponse" - }, - "title": "Columns", - "type": "array" - }, - "entries": { - "items": { - "$ref": "#/components/schemas/McpInventoryEntryResponse" - }, - "title": "Entries", - "type": "array" - }, - "issues": { - "items": { - "$ref": "#/components/schemas/McpInventoryIssueResponse" - }, - "title": "Issues", - "type": "array" + "harness": { + "description": "Harness identifier", + "minLength": 1, + "title": "Harness", + "type": "string" } }, "required": [ - "columns", - "entries" + "harness" ], - "title": "McpInventoryResponse", + "title": "EnableSkillRequest", "type": "object" }, - "McpMarketplaceCapabilityCountsResponse": { + "HTTPValidationError": { "properties": { - "prompts": { - "title": "Prompts", - "type": "integer" - }, - "resources": { - "title": "Resources", - "type": "integer" - }, - "tools": { - "title": "Tools", - "type": "integer" + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "title": "Detail", + "type": "array" } }, - "required": [ - "tools", - "resources", - "prompts" - ], - "title": "McpMarketplaceCapabilityCountsResponse", + "title": "HTTPValidationError", "type": "object" }, - "McpMarketplaceConnectionResponse": { + "HarnessCellResponse": { "properties": { - "bundleUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Bundleurl" + "harness": { + "title": "Harness", + "type": "string" }, - "configSchema": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "title": "Configschema" + "interactive": { + "title": "Interactive", + "type": "boolean" }, - "deploymentUrl": { + "label": { + "title": "Label", + "type": "string" + }, + "logoKey": { "anyOf": [ { "type": "string" @@ -1480,13 +1203,43 @@ "type": "null" } ], - "title": "Deploymenturl" + "title": "Logokey" }, - "kind": { - "title": "Kind", + "state": { + "enum": [ + "enabled", + "disabled", + "found", + "empty" + ], + "title": "State", + "type": "string" + } + }, + "required": [ + "harness", + "label", + "state", + "interactive" + ], + "title": "HarnessCellResponse", + "type": "object" + }, + "HarnessColumnResponse": { + "properties": { + "harness": { + "title": "Harness", "type": "string" }, - "runtime": { + "installed": { + "title": "Installed", + "type": "boolean" + }, + "label": { + "title": "Label", + "type": "string" + }, + "logoKey": { "anyOf": [ { "type": "string" @@ -1495,23 +1248,53 @@ "type": "null" } ], - "title": "Runtime" + "title": "Logokey" + } + }, + "required": [ + "harness", + "label", + "installed" + ], + "title": "HarnessColumnResponse", + "type": "object" + }, + "HookApplyConfigResponse": { + "properties": { + "failed": { + "items": { + "$ref": "#/components/schemas/HookMutationFailureResponse" + }, + "title": "Failed", + "type": "array" }, - "stdioArgs": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "title": "Stdioargs" + "hook": { + "$ref": "#/components/schemas/HookSpecResponse" }, - "stdioCommand": { + "ok": { + "title": "Ok", + "type": "boolean" + }, + "succeeded": { + "items": { + "type": "string" + }, + "title": "Succeeded", + "type": "array" + } + }, + "required": [ + "ok", + "hook", + "succeeded", + "failed" + ], + "title": "HookApplyConfigResponse", + "type": "object" + }, + "HookBindingResponse": { + "properties": { + "caveat": { "anyOf": [ { "type": "string" @@ -1520,9 +1303,9 @@ "type": "null" } ], - "title": "Stdiocommand" + "title": "Caveat" }, - "stdioFunction": { + "driftDetail": { "anyOf": [ { "type": "string" @@ -1531,28 +1314,42 @@ "type": "null" } ], - "title": "Stdiofunction" + "title": "Driftdetail" + }, + "harness": { + "title": "Harness", + "type": "string" + }, + "state": { + "enum": [ + "managed", + "drifted", + "unmanaged", + "missing", + "unsupported" + ], + "title": "State", + "type": "string" } }, "required": [ - "kind" + "harness", + "state" ], - "title": "McpMarketplaceConnectionResponse", + "title": "HookBindingResponse", "type": "object" }, - "McpMarketplaceDetailResponse": { + "HookInventoryColumnResponse": { "properties": { - "capabilityCounts": { - "$ref": "#/components/schemas/McpMarketplaceCapabilityCountsResponse" + "configPresent": { + "title": "Configpresent", + "type": "boolean" }, - "connections": { - "items": { - "$ref": "#/components/schemas/McpMarketplaceConnectionResponse" - }, - "title": "Connections", - "type": "array" + "harness": { + "title": "Harness", + "type": "string" }, - "deploymentUrl": { + "hooksUnavailableReason": { "anyOf": [ { "type": "string" @@ -1561,32 +1358,22 @@ "type": "null" } ], - "title": "Deploymenturl" + "title": "Hooksunavailablereason" }, - "description": { - "title": "Description", - "type": "string" + "hooksWritable": { + "default": true, + "title": "Hookswritable", + "type": "boolean" }, - "displayName": { - "title": "Displayname", - "type": "string" + "installed": { + "title": "Installed", + "type": "boolean" }, - "externalUrl": { - "title": "Externalurl", + "label": { + "title": "Label", "type": "string" }, - "githubUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Githuburl" - }, - "iconUrl": { + "logoKey": { "anyOf": [ { "type": "string" @@ -1595,206 +1382,213 @@ "type": "null" } ], - "title": "Iconurl" - }, - "installConfig": { - "$ref": "#/components/schemas/McpInstallConfigResponse" - }, - "isRemote": { - "title": "Isremote", + "title": "Logokey" + } + }, + "required": [ + "harness", + "label", + "installed", + "configPresent" + ], + "title": "HookInventoryColumnResponse", + "type": "object" + }, + "HookInventoryEntryResponse": { + "properties": { + "canEnable": { + "title": "Canenable", "type": "boolean" }, - "managedName": { - "title": "Managedname", + "displayName": { + "title": "Displayname", "type": "string" }, - "prompts": { - "items": { - "$ref": "#/components/schemas/McpMarketplacePromptResponse" - }, - "title": "Prompts", - "type": "array" + "enabledStatus": { + "enum": [ + "enabled", + "disabled" + ], + "title": "Enabledstatus", + "type": "string" }, - "qualifiedName": { - "title": "Qualifiedname", + "id": { + "title": "Id", "type": "string" }, - "resources": { - "items": { - "$ref": "#/components/schemas/McpMarketplaceResourceResponse" - }, - "title": "Resources", - "type": "array" + "kind": { + "enum": [ + "managed", + "unmanaged" + ], + "title": "Kind", + "type": "string" }, - "tools": { + "sightings": { "items": { - "$ref": "#/components/schemas/McpMarketplaceToolResponse" + "$ref": "#/components/schemas/HookBindingResponse" }, - "title": "Tools", + "title": "Sightings", "type": "array" }, - "websiteUrl": { + "spec": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/HookSpecResponse" }, { "type": "null" } - ], - "title": "Websiteurl" + ] } }, "required": [ - "qualifiedName", - "managedName", + "id", "displayName", - "description", - "isRemote", - "connections", - "tools", - "resources", - "prompts", - "capabilityCounts", - "externalUrl" + "kind", + "canEnable", + "enabledStatus", + "sightings" ], - "title": "McpMarketplaceDetailResponse", + "title": "HookInventoryEntryResponse", "type": "object" }, - "McpMarketplaceItemResponse": { + "HookInventoryIssueResponse": { "properties": { - "createdAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Createdat" - }, - "description": { - "title": "Description", + "name": { + "title": "Name", "type": "string" }, - "displayName": { - "title": "Displayname", + "reason": { + "title": "Reason", "type": "string" + } + }, + "required": [ + "name", + "reason" + ], + "title": "HookInventoryIssueResponse", + "type": "object" + }, + "HookInventoryResponse": { + "properties": { + "columns": { + "items": { + "$ref": "#/components/schemas/HookInventoryColumnResponse" + }, + "title": "Columns", + "type": "array" }, - "externalUrl": { - "title": "Externalurl", - "type": "string" - }, - "githubUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Githuburl" - }, - "homepage": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Homepage" + "entries": { + "items": { + "$ref": "#/components/schemas/HookInventoryEntryResponse" + }, + "title": "Entries", + "type": "array" }, - "iconUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Iconurl" + "issues": { + "items": { + "$ref": "#/components/schemas/HookInventoryIssueResponse" + }, + "title": "Issues", + "type": "array" + } + }, + "required": [ + "columns", + "entries" + ], + "title": "HookInventoryResponse", + "type": "object" + }, + "HookMutationFailureResponse": { + "properties": { + "error": { + "title": "Error", + "type": "string" }, - "isDeployed": { - "title": "Isdeployed", - "type": "boolean" + "harness": { + "title": "Harness", + "type": "string" + } + }, + "required": [ + "harness", + "error" + ], + "title": "HookMutationFailureResponse", + "type": "object" + }, + "HookMutationResponse": { + "properties": { + "hook": { + "$ref": "#/components/schemas/HookSpecResponse" }, - "isRemote": { - "title": "Isremote", + "ok": { + "title": "Ok", "type": "boolean" + } + }, + "required": [ + "ok", + "hook" + ], + "title": "HookMutationResponse", + "type": "object" + }, + "HookSetHarnessesResultResponse": { + "properties": { + "failed": { + "items": { + "$ref": "#/components/schemas/HookMutationFailureResponse" + }, + "title": "Failed", + "type": "array" }, - "isVerified": { - "title": "Isverified", + "ok": { + "title": "Ok", "type": "boolean" }, - "namespace": { - "title": "Namespace", - "type": "string" - }, - "qualifiedName": { - "title": "Qualifiedname", - "type": "string" - }, - "useCount": { - "title": "Usecount", - "type": "integer" - }, - "websiteUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Websiteurl" + "succeeded": { + "items": { + "type": "string" + }, + "title": "Succeeded", + "type": "array" } }, "required": [ - "qualifiedName", - "namespace", - "displayName", - "description", - "isVerified", - "isRemote", - "isDeployed", - "useCount", - "externalUrl" + "ok", + "succeeded", + "failed" ], - "title": "McpMarketplaceItemResponse", + "title": "HookSetHarnessesResultResponse", "type": "object" }, - "McpMarketplaceLinkResponse": { + "HookSpecResponse": { "properties": { + "command": { + "title": "Command", + "type": "string" + }, "description": { "title": "Description", "type": "string" }, - "displayName": { - "title": "Displayname", + "event": { + "title": "Event", "type": "string" }, - "externalUrl": { - "title": "Externalurl", + "id": { + "title": "Id", "type": "string" }, - "githubUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Githuburl" + "installedAt": { + "title": "Installedat", + "type": "string" }, - "iconUrl": { + "match": { "anyOf": [ { "type": "string" @@ -1803,252 +1597,147 @@ "type": "null" } ], - "title": "Iconurl" - }, - "isRemote": { - "title": "Isremote", - "type": "boolean" - }, - "isVerified": { - "title": "Isverified", - "type": "boolean" + "title": "Match" }, - "qualifiedName": { - "title": "Qualifiedname", + "revision": { + "title": "Revision", "type": "string" }, - "websiteUrl": { + "timeout": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Websiteurl" + "title": "Timeout" } }, "required": [ - "qualifiedName", - "displayName", - "externalUrl", + "id", + "event", + "command", "description", - "isRemote", - "isVerified" + "installedAt", + "revision" ], - "title": "McpMarketplaceLinkResponse", + "title": "HookSpecResponse", "type": "object" }, - "McpMarketplacePageResponse": { + "InstallMarketplaceSkillRequest": { "properties": { - "hasMore": { - "title": "Hasmore", - "type": "boolean" - }, - "items": { - "items": { - "$ref": "#/components/schemas/McpMarketplaceItemResponse" - }, - "title": "Items", - "type": "array" - }, - "nextOffset": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Nextoffset" + "installToken": { + "minLength": 1, + "title": "Installtoken", + "type": "string" } }, "required": [ - "items", - "hasMore" + "installToken" ], - "title": "McpMarketplacePageResponse", + "title": "InstallMarketplaceSkillRequest", "type": "object" }, - "McpMarketplaceParameterResponse": { + "McpAdoptionIssueResponse": { "properties": { - "default": { + "configPath": { "anyOf": [ - {}, + { + "type": "string" + }, { "type": "null" } ], - "title": "Default" + "title": "Configpath" }, - "description": { - "title": "Description", + "harness": { + "title": "Harness", "type": "string" }, - "enum": { + "label": { + "title": "Label", + "type": "string" + }, + "logoKey": { "anyOf": [ { - "items": {}, - "type": "array" + "type": "string" }, { "type": "null" } ], - "title": "Enum" + "title": "Logokey" }, - "maxItems": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Maxitems" - }, - "maxLength": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Maxlength" - }, - "maximum": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Maximum" - }, - "minItems": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Minitems" - }, - "minLength": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Minlength" + "name": { + "title": "Name", + "type": "string" }, - "minimum": { + "payloadPreview": { "anyOf": [ { - "type": "number" - }, - { - "type": "integer" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Minimum" - }, - "name": { - "title": "Name", - "type": "string" - }, - "required": { - "title": "Required", - "type": "boolean" - }, - "type": { - "title": "Type", - "type": "string" - } - }, - "required": [ - "name", - "type", - "description", - "required" - ], - "title": "McpMarketplaceParameterResponse", - "type": "object" - }, - "McpMarketplacePromptArgumentResponse": { - "properties": { - "description": { - "title": "Description", - "type": "string" + "title": "Payloadpreview" }, - "name": { - "title": "Name", + "reason": { + "title": "Reason", "type": "string" - }, - "required": { - "title": "Required", - "type": "boolean" } }, "required": [ + "harness", + "label", "name", - "description", - "required" + "reason" ], - "title": "McpMarketplacePromptArgumentResponse", + "title": "McpAdoptionIssueResponse", "type": "object" }, - "McpMarketplacePromptResponse": { + "McpApplyConfigResponse": { "properties": { - "arguments": { + "failed": { "items": { - "$ref": "#/components/schemas/McpMarketplacePromptArgumentResponse" + "$ref": "#/components/schemas/McpMutationFailureResponse" }, - "title": "Arguments", + "title": "Failed", "type": "array" }, - "description": { - "title": "Description", - "type": "string" + "ok": { + "title": "Ok", + "type": "boolean" }, - "name": { - "title": "Name", - "type": "string" + "server": { + "$ref": "#/components/schemas/McpServerSpecResponse" + }, + "succeeded": { + "items": { + "type": "string" + }, + "title": "Succeeded", + "type": "array" } }, "required": [ - "name", - "description", - "arguments" + "ok", + "server", + "succeeded", + "failed" ], - "title": "McpMarketplacePromptResponse", + "title": "McpApplyConfigResponse", "type": "object" }, - "McpMarketplaceResourceResponse": { + "McpAvailabilityCheckResponse": { "properties": { - "description": { - "title": "Description", - "type": "string" - }, - "mimeType": { + "availabilityReason": { "anyOf": [ { "type": "string" @@ -2057,72 +1746,71 @@ "type": "null" } ], - "title": "Mimetype" - }, - "name": { - "title": "Name", - "type": "string" + "title": "Availabilityreason" }, - "uri": { - "title": "Uri", - "type": "string" - } - }, - "required": [ - "name", - "uri", - "description" - ], - "title": "McpMarketplaceResourceResponse", - "type": "object" - }, - "McpMarketplaceToolResponse": { - "properties": { - "description": { - "title": "Description", + "availabilityStatus": { + "enum": [ + "available", + "unavailable" + ], + "title": "Availabilitystatus", "type": "string" }, "name": { "title": "Name", "type": "string" }, - "parameters": { - "items": { - "$ref": "#/components/schemas/McpMarketplaceParameterResponse" - }, - "title": "Parameters", - "type": "array" + "ok": { + "title": "Ok", + "type": "boolean" } }, "required": [ + "ok", "name", - "description", - "parameters" + "availabilityStatus" ], - "title": "McpMarketplaceToolResponse", + "title": "McpAvailabilityCheckResponse", "type": "object" }, - "McpMutationFailureResponse": { + "McpBindingResponse": { "properties": { - "error": { - "title": "Error", - "type": "string" + "driftDetail": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Driftdetail" }, "harness": { "title": "Harness", "type": "string" + }, + "state": { + "enum": [ + "managed", + "drifted", + "unmanaged", + "missing" + ], + "title": "State", + "type": "string" } }, "required": [ "harness", - "error" + "state" ], - "title": "McpMutationFailureResponse", + "title": "McpBindingResponse", "type": "object" }, - "McpServerDetailResponse": { + "McpConfigChoiceResponse": { "properties": { - "availabilityReason": { + "configPath": { "anyOf": [ { "type": "string" @@ -2131,209 +1819,181 @@ "type": "null" } ], - "description": "Deprecated compatibility field; use mcpStatus.reason instead.", - "title": "Availabilityreason" - }, - "availabilityStatus": { - "description": "Deprecated compatibility field; use mcpStatus instead.", - "enum": [ - "available", - "unavailable" - ], - "title": "Availabilitystatus", - "type": "string" - }, - "canEnable": { - "title": "Canenable", - "type": "boolean" + "title": "Configpath" }, - "configChoices": { + "env": { "items": { - "$ref": "#/components/schemas/McpConfigChoiceResponse" + "$ref": "#/components/schemas/McpEnvEntryResponse" }, - "title": "Configchoices", + "title": "Env", "type": "array" }, - "displayName": { - "title": "Displayname", - "type": "string" - }, - "enabledStatus": { - "enum": [ - "enabled", - "disabled" - ], - "title": "Enabledstatus", + "id": { + "title": "Id", "type": "string" }, - "env": { - "items": { - "$ref": "#/components/schemas/McpEnvEntryResponse" - }, - "title": "Env", - "type": "array" - }, - "installConfigStatus": { - "$ref": "#/components/schemas/McpInstallConfigStatusResponse" - }, - "kind": { - "enum": [ - "managed", - "unmanaged" - ], - "title": "Kind", + "label": { + "title": "Label", "type": "string" }, - "marketplaceLink": { + "logoKey": { "anyOf": [ { - "$ref": "#/components/schemas/McpMarketplaceLinkResponse" + "type": "string" }, { "type": "null" } - ] - }, - "mcpStatus": { - "$ref": "#/components/schemas/McpStatusResponse" - }, - "name": { - "title": "Name", - "type": "string" - }, - "sightings": { - "items": { - "$ref": "#/components/schemas/McpBindingResponse" - }, - "title": "Sightings", - "type": "array" + ], + "title": "Logokey" }, - "spec": { + "observedHarness": { "anyOf": [ { - "$ref": "#/components/schemas/McpServerSpecResponse" + "type": "string" }, { "type": "null" } - ] - } - }, - "required": [ - "name", - "displayName", - "kind", - "canEnable", - "enabledStatus", - "availabilityStatus", - "mcpStatus", - "installConfigStatus", - "sightings" - ], - "title": "McpServerDetailResponse", - "type": "object" - }, - "McpServerMutationResponse": { - "properties": { - "ok": { - "title": "Ok", + ], + "title": "Observed harness" + }, + "payloadPreview": { + "additionalProperties": true, + "title": "Payloadpreview", + "type": "object" + }, + "recommended": { + "default": false, + "title": "Recommended", "type": "boolean" }, - "server": { + "sourceKind": { + "enum": [ + "managed", + "harness" + ], + "title": "Sourcekind", + "type": "string" + }, + "spec": { "$ref": "#/components/schemas/McpServerSpecResponse" } }, "required": [ - "ok", - "server" + "id", + "sourceKind", + "label", + "payloadPreview", + "spec" ], - "title": "McpServerMutationResponse", + "title": "McpConfigChoiceResponse", "type": "object" }, - "McpServerSpecResponse": { + "McpEnvEntryResponse": { "properties": { - "args": { + "isEnvRef": { + "title": "Isenvref", + "type": "boolean" + }, + "key": { + "title": "Key", + "type": "string" + }, + "value": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "type": "string" }, { "type": "null" } ], - "title": "Args" - }, - "command": { + "title": "Value" + } + }, + "required": [ + "key", + "isEnvRef" + ], + "title": "McpEnvEntryResponse", + "type": "object" + }, + "McpIdentityGroupResponse": { + "properties": { + "canonicalSpec": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/McpServerSpecResponse" }, { "type": "null" } - ], - "title": "Command" + ] }, - "displayName": { - "title": "Displayname", - "type": "string" + "identical": { + "title": "Identical", + "type": "boolean" }, - "env": { + "marketplaceLink": { "anyOf": [ { - "additionalProperties": { - "type": "string" - }, - "type": "object" + "$ref": "#/components/schemas/McpMarketplaceLinkResponse" }, { "type": "null" } - ], - "title": "Env" + ] }, - "headers": { + "name": { + "title": "Name", + "type": "string" + }, + "sightings": { + "items": { + "$ref": "#/components/schemas/McpIdentitySightingResponse" + }, + "title": "Sightings", + "type": "array" + } + }, + "required": [ + "name", + "identical", + "sightings" + ], + "title": "McpIdentityGroupResponse", + "type": "object" + }, + "McpIdentitySightingResponse": { + "properties": { + "configPath": { "anyOf": [ { - "additionalProperties": { - "type": "string" - }, - "type": "object" + "type": "string" }, { "type": "null" } ], - "title": "Headers" - }, - "installedAt": { - "title": "Installedat", - "type": "string" + "title": "Configpath" }, - "name": { - "title": "Name", - "type": "string" + "env": { + "items": { + "$ref": "#/components/schemas/McpEnvEntryResponse" + }, + "title": "Env", + "type": "array" }, - "revision": { - "title": "Revision", + "harness": { + "title": "Harness", "type": "string" }, - "source": { - "$ref": "#/components/schemas/McpSourceResponse" - }, - "transport": { - "enum": [ - "stdio", - "http", - "sse" - ], - "title": "Transport", + "label": { + "title": "Label", "type": "string" }, - "url": { + "logoKey": { "anyOf": [ { "type": "string" @@ -2342,85 +2002,74 @@ "type": "null" } ], - "title": "Url" + "title": "Logokey" + }, + "payloadPreview": { + "additionalProperties": true, + "title": "Payloadpreview", + "type": "object" + }, + "recommended": { + "default": false, + "title": "Recommended", + "type": "boolean" + }, + "spec": { + "$ref": "#/components/schemas/McpServerSpecResponse" } }, "required": [ - "name", - "displayName", - "source", - "transport", - "installedAt", - "revision" + "harness", + "label", + "payloadPreview", + "spec" ], - "title": "McpServerSpecResponse", + "title": "McpIdentitySightingResponse", "type": "object" }, - "McpSetHarnessesResultResponse": { + "McpInstallConfigFieldResponse": { "properties": { - "failed": { + "choices": { "items": { - "$ref": "#/components/schemas/McpMutationFailureResponse" + "type": "string" }, - "title": "Failed", + "title": "Choices", "type": "array" }, - "ok": { - "title": "Ok", - "type": "boolean" + "default": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Default" }, - "succeeded": { - "items": { - "type": "string" - }, - "title": "Succeeded", - "type": "array" - } - }, - "required": [ - "ok", - "succeeded", - "failed" - ], - "title": "McpSetHarnessesResultResponse", - "type": "object" - }, - "McpSourceResponse": { - "properties": { - "kind": { + "description": { + "title": "Description", + "type": "string" + }, + "format": { "enum": [ - "marketplace", - "adopted", - "manual" + "string", + "number", + "boolean", + "filepath" ], - "title": "Kind", + "title": "Format", "type": "string" }, - "locator": { - "title": "Locator", + "label": { + "title": "Label", "type": "string" - } - }, - "required": [ - "kind", - "locator" - ], - "title": "McpSourceResponse", - "type": "object" - }, - "McpStatusResponse": { - "properties": { - "kind": { - "enum": [ - "available", - "needs_config", - "connection_issue", - "unchecked" - ], - "title": "Kind", + }, + "name": { + "title": "Name", "type": "string" }, - "reason": { + "placeholder": { "anyOf": [ { "type": "string" @@ -2429,59 +2078,88 @@ "type": "null" } ], - "title": "Reason" + "title": "Placeholder" + }, + "required": { + "title": "Required", + "type": "boolean" + }, + "secret": { + "title": "Secret", + "type": "boolean" + }, + "target": { + "enum": [ + "env", + "header", + "urlVariable", + "packageArgument", + "runtimeArgument" + ], + "title": "Target", + "type": "string" } }, "required": [ - "kind" + "name", + "label", + "description", + "format", + "required", + "secret", + "target" ], - "title": "McpStatusResponse", + "title": "McpInstallConfigFieldResponse", "type": "object" }, - "McpUnmanagedByServerResponse": { + "McpInstallConfigResponse": { "properties": { - "harnesses": { + "fields": { "items": { - "$ref": "#/components/schemas/McpUnmanagedHarnessResponse" + "$ref": "#/components/schemas/McpInstallConfigFieldResponse" }, - "title": "Harnesses", + "title": "Fields", "type": "array" }, - "issues": { - "items": { - "$ref": "#/components/schemas/McpAdoptionIssueResponse" - }, - "title": "Issues", - "type": "array" + "required": { + "title": "Required", + "type": "boolean" + } + }, + "required": [ + "required" + ], + "title": "McpInstallConfigResponse", + "type": "object" + }, + "McpInstallConfigStatusResponse": { + "properties": { + "configured": { + "title": "Configured", + "type": "boolean" }, - "servers": { + "hasFields": { + "title": "Hasfields", + "type": "boolean" + }, + "missingRequired": { "items": { - "$ref": "#/components/schemas/McpIdentityGroupResponse" + "type": "string" }, - "title": "Servers", + "title": "Missingrequired", "type": "array" } }, "required": [ - "harnesses", - "servers" + "hasFields", + "missingRequired", + "configured" ], - "title": "McpUnmanagedByServerResponse", + "title": "McpInstallConfigStatusResponse", "type": "object" }, - "McpUnmanagedHarnessResponse": { + "McpInventoryColumnResponse": { "properties": { - "configPath": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Configpath" - }, "configPresent": { "title": "Configpresent", "type": "boolean" @@ -2532,40 +2210,12 @@ "installed", "configPresent" ], - "title": "McpUnmanagedHarnessResponse", - "type": "object" - }, - "OkResponse": { - "properties": { - "ok": { - "title": "Ok", - "type": "boolean" - } - }, - "required": [ - "ok" - ], - "title": "OkResponse", + "title": "McpInventoryColumnResponse", "type": "object" }, - "ReconcileMcpServerRequest": { - "additionalProperties": false, + "McpInventoryEntryResponse": { "properties": { - "harnesses": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "title": "Harnesses" - }, - "observedHarness": { + "availabilityReason": { "anyOf": [ { "type": "string" @@ -2574,327 +2224,182 @@ "type": "null" } ], - "title": "Observed harness" + "description": "Deprecated compatibility field; use mcpStatus.reason instead.", + "title": "Availabilityreason" }, - "sourceKind": { + "availabilityStatus": { + "description": "Deprecated compatibility field; use mcpStatus instead.", "enum": [ - "managed", - "harness" + "available", + "unavailable" ], - "title": "Sourcekind", + "title": "Availabilitystatus", "type": "string" - } - }, - "required": [ - "sourceKind" - ], - "title": "ReconcileMcpServerRequest", - "type": "object" - }, - "ScanAvailabilityResponse": { - "properties": { - "available": { - "title": "Available", + }, + "canEnable": { + "title": "Canenable", "type": "boolean" - } - }, - "required": [ - "available" - ], - "title": "ScanAvailabilityResponse", - "type": "object" - }, - "ScanConfigItem": { - "properties": { - "apiKeyMasked": { - "title": "Apikeymasked", - "type": "string" }, - "apiVersion": { - "title": "Apiversion", + "displayName": { + "title": "Displayname", "type": "string" }, - "awsProfile": { - "title": "Awsprofile", + "enabledStatus": { + "enum": [ + "enabled", + "disabled" + ], + "title": "Enabledstatus", "type": "string" }, - "awsRegion": { - "title": "Awsregion", - "type": "string" + "installConfigStatus": { + "$ref": "#/components/schemas/McpInstallConfigStatusResponse" }, - "baseUrl": { - "title": "Baseurl", + "kind": { + "enum": [ + "managed", + "unmanaged" + ], + "title": "Kind", "type": "string" }, - "consensusRuns": { - "title": "Consensusruns", - "type": "integer" - }, - "id": { - "title": "Id", - "type": "integer" - }, - "isActive": { - "title": "Isactive", - "type": "boolean" - }, - "lastValidatedAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Lastvalidatedat" - }, - "lastValidationError": { - "default": "", - "title": "Lastvalidationerror", - "type": "string" - }, - "maxTokens": { - "title": "Maxtokens", - "type": "integer" - }, - "model": { - "title": "Model", - "type": "string" + "mcpStatus": { + "$ref": "#/components/schemas/McpStatusResponse" }, "name": { "title": "Name", "type": "string" }, - "provider": { - "title": "Provider", - "type": "string" - } - }, - "required": [ - "id", - "name", - "baseUrl", - "apiKeyMasked", - "model", - "provider", - "apiVersion", - "awsRegion", - "awsProfile", - "maxTokens", - "consensusRuns", - "isActive" - ], - "title": "ScanConfigItem", - "type": "object" - }, - "ScanConfigListResponse": { - "properties": { - "activeId": { + "sightings": { + "items": { + "$ref": "#/components/schemas/McpBindingResponse" + }, + "title": "Sightings", + "type": "array" + }, + "spec": { "anyOf": [ { - "type": "integer" + "$ref": "#/components/schemas/McpServerSpecResponse" }, { "type": "null" } - ], - "title": "Activeid" - }, - "configs": { - "items": { - "$ref": "#/components/schemas/ScanConfigItem" - }, - "title": "Configs", - "type": "array" + ] } }, "required": [ - "configs", - "activeId" + "name", + "displayName", + "kind", + "canEnable", + "enabledStatus", + "availabilityStatus", + "mcpStatus", + "installConfigStatus", + "sightings" ], - "title": "ScanConfigListResponse", + "title": "McpInventoryEntryResponse", "type": "object" }, - "ScanConfigSaveRequest": { + "McpInventoryIssueResponse": { "properties": { - "apiKey": { - "title": "Apikey", - "type": "string" - }, - "apiVersion": { - "default": "", - "title": "Apiversion", - "type": "string" - }, - "awsProfile": { - "default": "", - "title": "Awsprofile", - "type": "string" - }, - "awsRegion": { - "default": "", - "title": "Awsregion", - "type": "string" - }, - "awsSessionToken": { - "default": "", - "title": "Awssessiontoken", - "type": "string" - }, - "baseUrl": { - "title": "Baseurl", - "type": "string" - }, - "consensusRuns": { - "default": 1, - "title": "Consensusruns", - "type": "integer" - }, - "maxTokens": { - "default": 8192, - "title": "Maxtokens", - "type": "integer" - }, - "model": { - "title": "Model", - "type": "string" - }, "name": { "title": "Name", "type": "string" }, - "provider": { - "default": "", - "title": "Provider", + "reason": { + "title": "Reason", "type": "string" } }, "required": [ "name", - "baseUrl", - "apiKey", - "model" + "reason" ], - "title": "ScanConfigSaveRequest", + "title": "McpInventoryIssueResponse", "type": "object" }, - "ScanConfigSecretResponse": { + "McpInventoryResponse": { "properties": { - "apiKey": { - "title": "Apikey", - "type": "string" + "columns": { + "items": { + "$ref": "#/components/schemas/McpInventoryColumnResponse" + }, + "title": "Columns", + "type": "array" + }, + "entries": { + "items": { + "$ref": "#/components/schemas/McpInventoryEntryResponse" + }, + "title": "Entries", + "type": "array" + }, + "issues": { + "items": { + "$ref": "#/components/schemas/McpInventoryIssueResponse" + }, + "title": "Issues", + "type": "array" } }, "required": [ - "apiKey" + "columns", + "entries" ], - "title": "ScanConfigSecretResponse", + "title": "McpInventoryResponse", "type": "object" }, - "ScanConfigValidateRequest": { + "McpMarketplaceCapabilityCountsResponse": { "properties": { - "apiKey": { - "title": "Apikey", - "type": "string" - }, - "apiVersion": { - "default": "", - "title": "Apiversion", - "type": "string" - }, - "awsProfile": { - "default": "", - "title": "Awsprofile", - "type": "string" - }, - "awsRegion": { - "default": "", - "title": "Awsregion", - "type": "string" - }, - "awsSessionToken": { - "default": "", - "title": "Awssessiontoken", - "type": "string" - }, - "baseUrl": { - "title": "Baseurl", - "type": "string" - }, - "consensusRuns": { - "default": 1, - "title": "Consensusruns", + "prompts": { + "title": "Prompts", "type": "integer" }, - "existingConfigId": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Existingconfigid" - }, - "maxTokens": { - "default": 8192, - "title": "Maxtokens", + "resources": { + "title": "Resources", "type": "integer" }, - "model": { - "title": "Model", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "provider": { - "default": "", - "title": "Provider", - "type": "string" + "tools": { + "title": "Tools", + "type": "integer" } }, "required": [ - "name", - "baseUrl", - "apiKey", - "model" + "tools", + "resources", + "prompts" ], - "title": "ScanConfigValidateRequest", + "title": "McpMarketplaceCapabilityCountsResponse", "type": "object" }, - "ScanConfigValidationResponse": { + "McpMarketplaceConnectionResponse": { "properties": { - "durationMs": { + "bundleUrl": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "title": "Durationms" + "title": "Bundleurl" }, - "errorCode": { + "configSchema": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Errorcode" - }, - "message": { - "title": "Message", - "type": "string" + "title": "Configschema" }, - "model": { + "deploymentUrl": { "anyOf": [ { "type": "string" @@ -2903,13 +2408,13 @@ "type": "null" } ], - "title": "Model" + "title": "Deploymenturl" }, - "ok": { - "title": "Ok", - "type": "boolean" + "kind": { + "title": "Kind", + "type": "string" }, - "provider": { + "runtime": { "anyOf": [ { "type": "string" @@ -2918,38 +2423,23 @@ "type": "null" } ], - "title": "Provider" - } - }, - "required": [ - "ok", - "message" - ], - "title": "ScanConfigValidationResponse", - "type": "object" - }, - "ScanFindingResponse": { - "properties": { - "analyzer": { + "title": "Runtime" + }, + "stdioArgs": { "anyOf": [ { - "type": "string" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } ], - "title": "Analyzer" - }, - "category": { - "title": "Category", - "type": "string" - }, - "description": { - "title": "Description", - "type": "string" + "title": "Stdioargs" }, - "filePath": { + "stdioCommand": { "anyOf": [ { "type": "string" @@ -2958,30 +2448,39 @@ "type": "null" } ], - "title": "Filepath" - }, - "id": { - "title": "Id", - "type": "string" + "title": "Stdiocommand" }, - "lineNumber": { + "stdioFunction": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "title": "Linenumber" + "title": "Stdiofunction" + } + }, + "required": [ + "kind" + ], + "title": "McpMarketplaceConnectionResponse", + "type": "object" + }, + "McpMarketplaceDetailResponse": { + "properties": { + "capabilityCounts": { + "$ref": "#/components/schemas/McpMarketplaceCapabilityCountsResponse" }, - "metadata": { - "additionalProperties": true, - "default": {}, - "title": "Metadata", - "type": "object" + "connections": { + "items": { + "$ref": "#/components/schemas/McpMarketplaceConnectionResponse" + }, + "title": "Connections", + "type": "array" }, - "remediation": { + "deploymentUrl": { "anyOf": [ { "type": "string" @@ -2990,17 +2489,21 @@ "type": "null" } ], - "title": "Remediation" + "title": "Deploymenturl" + }, + "description": { + "title": "Description", + "type": "string" }, - "ruleId": { - "title": "Ruleid", + "displayName": { + "title": "Displayname", "type": "string" }, - "severity": { - "title": "Severity", + "externalUrl": { + "title": "Externalurl", "type": "string" }, - "snippet": { + "githubUrl": { "anyOf": [ { "type": "string" @@ -3009,27 +2512,9 @@ "type": "null" } ], - "title": "Snippet" + "title": "Githuburl" }, - "title": { - "title": "Title", - "type": "string" - } - }, - "required": [ - "id", - "ruleId", - "category", - "severity", - "title", - "description" - ], - "title": "ScanFindingResponse", - "type": "object" - }, - "ScanOptionsRequest": { - "properties": { - "awsProfile": { + "iconUrl": { "anyOf": [ { "type": "string" @@ -3038,10 +2523,46 @@ "type": "null" } ], - "title": "Awsprofile" + "title": "Iconurl" }, - "awsRegion": { - "anyOf": [ + "installConfig": { + "$ref": "#/components/schemas/McpInstallConfigResponse" + }, + "isRemote": { + "title": "Isremote", + "type": "boolean" + }, + "managedName": { + "title": "Managedname", + "type": "string" + }, + "prompts": { + "items": { + "$ref": "#/components/schemas/McpMarketplacePromptResponse" + }, + "title": "Prompts", + "type": "array" + }, + "qualifiedName": { + "title": "Qualifiedname", + "type": "string" + }, + "resources": { + "items": { + "$ref": "#/components/schemas/McpMarketplaceResourceResponse" + }, + "title": "Resources", + "type": "array" + }, + "tools": { + "items": { + "$ref": "#/components/schemas/McpMarketplaceToolResponse" + }, + "title": "Tools", + "type": "array" + }, + "websiteUrl": { + "anyOf": [ { "type": "string" }, @@ -3049,9 +2570,28 @@ "type": "null" } ], - "title": "Awsregion" - }, - "awsSessionToken": { + "title": "Websiteurl" + } + }, + "required": [ + "qualifiedName", + "managedName", + "displayName", + "description", + "isRemote", + "connections", + "tools", + "resources", + "prompts", + "capabilityCounts", + "externalUrl" + ], + "title": "McpMarketplaceDetailResponse", + "type": "object" + }, + "McpMarketplaceItemResponse": { + "properties": { + "createdAt": { "anyOf": [ { "type": "string" @@ -3060,9 +2600,21 @@ "type": "null" } ], - "title": "Awssessiontoken" + "title": "Createdat" + }, + "description": { + "title": "Description", + "type": "string" + }, + "displayName": { + "title": "Displayname", + "type": "string" + }, + "externalUrl": { + "title": "Externalurl", + "type": "string" }, - "llmApiKey": { + "githubUrl": { "anyOf": [ { "type": "string" @@ -3071,9 +2623,9 @@ "type": "null" } ], - "title": "Llmapikey" + "title": "Githuburl" }, - "llmApiVersion": { + "homepage": { "anyOf": [ { "type": "string" @@ -3082,9 +2634,9 @@ "type": "null" } ], - "title": "Llmapiversion" + "title": "Homepage" }, - "llmBaseUrl": { + "iconUrl": { "anyOf": [ { "type": "string" @@ -3093,19 +2645,73 @@ "type": "null" } ], - "title": "Llmbaseurl" + "title": "Iconurl" }, - "llmConsensusRuns": { - "default": 1, - "title": "Llmconsensusruns", - "type": "integer" + "isDeployed": { + "title": "Isdeployed", + "type": "boolean" + }, + "isRemote": { + "title": "Isremote", + "type": "boolean" + }, + "isVerified": { + "title": "Isverified", + "type": "boolean" + }, + "namespace": { + "title": "Namespace", + "type": "string" }, - "llmMaxTokens": { - "default": 8192, - "title": "Llmmaxtokens", + "qualifiedName": { + "title": "Qualifiedname", + "type": "string" + }, + "useCount": { + "title": "Usecount", "type": "integer" }, - "llmModel": { + "websiteUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Websiteurl" + } + }, + "required": [ + "qualifiedName", + "namespace", + "displayName", + "description", + "isVerified", + "isRemote", + "isDeployed", + "useCount", + "externalUrl" + ], + "title": "McpMarketplaceItemResponse", + "type": "object" + }, + "McpMarketplaceLinkResponse": { + "properties": { + "description": { + "title": "Description", + "type": "string" + }, + "displayName": { + "title": "Displayname", + "type": "string" + }, + "externalUrl": { + "title": "Externalurl", + "type": "string" + }, + "githubUrl": { "anyOf": [ { "type": "string" @@ -3114,9 +2720,9 @@ "type": "null" } ], - "title": "Llmmodel" + "title": "Githuburl" }, - "llmProvider": { + "iconUrl": { "anyOf": [ { "type": "string" @@ -3125,347 +2731,326 @@ "type": "null" } ], - "title": "Llmprovider" + "title": "Iconurl" }, - "useLlm": { - "default": true, - "title": "Usellm", + "isRemote": { + "title": "Isremote", "type": "boolean" - } - }, - "title": "ScanOptionsRequest", - "type": "object" - }, - "ScanResultResponse": { - "properties": { - "analyzersUsed": { - "items": { - "type": "string" - }, - "title": "Analyzersused", - "type": "array" - }, - "durationSeconds": { - "title": "Durationseconds", - "type": "number" - }, - "findings": { - "items": { - "$ref": "#/components/schemas/ScanFindingResponse" - }, - "title": "Findings", - "type": "array" - }, - "findingsCount": { - "title": "Findingscount", - "type": "integer" }, - "isSafe": { - "title": "Issafe", + "isVerified": { + "title": "Isverified", "type": "boolean" }, - "maxSeverity": { - "title": "Maxseverity", + "qualifiedName": { + "title": "Qualifiedname", "type": "string" }, - "skillName": { - "title": "Skillname", - "type": "string" + "websiteUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Websiteurl" } }, "required": [ - "skillName", - "isSafe", - "maxSeverity", - "findingsCount", - "findings", - "analyzersUsed", - "durationSeconds" + "qualifiedName", + "displayName", + "externalUrl", + "description", + "isRemote", + "isVerified" ], - "title": "ScanResultResponse", + "title": "McpMarketplaceLinkResponse", "type": "object" }, - "SetHarnessSupportRequest": { + "McpMarketplacePageResponse": { "properties": { - "enabled": { - "title": "Enabled", + "hasMore": { + "title": "Hasmore", "type": "boolean" - } - }, - "required": [ - "enabled" - ], - "title": "SetHarnessSupportRequest", - "type": "object" - }, - "SetMcpServerHarnessesRequest": { - "properties": { - "config": { + }, + "items": { + "items": { + "$ref": "#/components/schemas/McpMarketplaceItemResponse" + }, + "title": "Items", + "type": "array" + }, + "nextOffset": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "integer" }, { "type": "null" } ], - "title": "Config" - }, - "target": { - "enum": [ - "enabled", - "disabled" - ], - "title": "Target", - "type": "string" + "title": "Nextoffset" } }, "required": [ - "target" + "items", + "hasMore" ], - "title": "SetMcpServerHarnessesRequest", + "title": "McpMarketplacePageResponse", "type": "object" }, - "SetSkillHarnessesFailureResponse": { + "McpMarketplaceParameterResponse": { "properties": { - "error": { - "title": "Error", - "type": "string" + "default": { + "anyOf": [ + {}, + { + "type": "null" + } + ], + "title": "Default" }, - "harness": { - "title": "Harness", + "description": { + "title": "Description", "type": "string" - } - }, - "required": [ - "harness", - "error" - ], - "title": "SetSkillHarnessesFailureResponse", - "type": "object" - }, - "SetSkillHarnessesRequest": { - "properties": { - "target": { - "description": "Target state to apply to every interactive harness cell on this skill", - "enum": [ - "enabled", - "disabled" + }, + "enum": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "null" + } ], - "title": "Target", - "type": "string" - } - }, - "required": [ - "target" - ], - "title": "SetSkillHarnessesRequest", - "type": "object" - }, - "SetSkillHarnessesResultResponse": { - "properties": { - "failed": { - "items": { - "$ref": "#/components/schemas/SetSkillHarnessesFailureResponse" - }, - "title": "Failed", - "type": "array" + "title": "Enum" }, - "ok": { - "title": "Ok", - "type": "boolean" + "maxItems": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Maxitems" }, - "succeeded": { - "items": { - "type": "string" - }, - "title": "Succeeded", - "type": "array" - } - }, - "required": [ - "ok", - "succeeded", - "failed" - ], - "title": "SetSkillHarnessesResultResponse", - "type": "object" - }, - "SettingsHarnessResponse": { - "properties": { - "harness": { - "title": "Harness", - "type": "string" + "maxLength": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Maxlength" }, - "installed": { - "title": "Installed", - "type": "boolean" + "maximum": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Maximum" }, - "label": { - "title": "Label", - "type": "string" + "minItems": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Minitems" }, - "logoKey": { + "minLength": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Logokey" + "title": "Minlength" }, - "managedLocation": { + "minimum": { "anyOf": [ { - "type": "string" + "type": "number" + }, + { + "type": "integer" }, { "type": "null" } ], - "title": "Managedlocation" + "title": "Minimum" }, - "supportEnabled": { - "title": "Supportenabled", + "name": { + "title": "Name", + "type": "string" + }, + "required": { + "title": "Required", "type": "boolean" + }, + "type": { + "title": "Type", + "type": "string" } }, "required": [ - "harness", - "label", - "supportEnabled", - "installed", - "managedLocation" + "name", + "type", + "description", + "required" ], - "title": "SettingsHarnessResponse", + "title": "McpMarketplaceParameterResponse", "type": "object" }, - "SettingsResponse": { + "McpMarketplacePromptArgumentResponse": { "properties": { - "harnesses": { - "items": { - "$ref": "#/components/schemas/SettingsHarnessResponse" - }, - "title": "Harnesses", - "type": "array" + "description": { + "title": "Description", + "type": "string" }, - "storage": { - "$ref": "#/components/schemas/SettingsStorageResponse" + "name": { + "title": "Name", + "type": "string" + }, + "required": { + "title": "Required", + "type": "boolean" } }, "required": [ - "storage", - "harnesses" + "name", + "description", + "required" ], - "title": "SettingsResponse", + "title": "McpMarketplacePromptArgumentResponse", "type": "object" }, - "SettingsStorageResponse": { + "McpMarketplacePromptResponse": { "properties": { - "configDir": { - "title": "Configdir", - "type": "string" + "arguments": { + "items": { + "$ref": "#/components/schemas/McpMarketplacePromptArgumentResponse" + }, + "title": "Arguments", + "type": "array" }, - "dataDir": { - "title": "Datadir", + "description": { + "title": "Description", "type": "string" }, - "marketplaceCachePath": { - "title": "Marketplacecachepath", + "name": { + "title": "Name", "type": "string" - }, - "platform": { - "enum": [ - "macos", - "linux" - ], - "title": "Platform", + } + }, + "required": [ + "name", + "description", + "arguments" + ], + "title": "McpMarketplacePromptResponse", + "type": "object" + }, + "McpMarketplaceResourceResponse": { + "properties": { + "description": { + "title": "Description", "type": "string" }, - "settingsPath": { - "title": "Settingspath", - "type": "string" + "mimeType": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Mimetype" }, - "skillsStorePath": { - "title": "Skillsstorepath", + "name": { + "title": "Name", "type": "string" }, - "stateDir": { - "title": "Statedir", + "uri": { + "title": "Uri", "type": "string" } }, "required": [ - "platform", - "configDir", - "dataDir", - "stateDir", - "skillsStorePath", - "marketplaceCachePath", - "settingsPath" + "name", + "uri", + "description" ], - "title": "SettingsStorageResponse", + "title": "McpMarketplaceResourceResponse", "type": "object" }, - "SkillDetailActionsResponse": { + "McpMarketplaceToolResponse": { "properties": { - "canDelete": { - "title": "Candelete", - "type": "boolean" + "description": { + "title": "Description", + "type": "string" }, - "canManage": { - "title": "Canmanage", - "type": "boolean" - }, - "deleteHarnessLabels": { - "items": { - "type": "string" - }, - "title": "Deleteharnesslabels", - "type": "array" + "name": { + "title": "Name", + "type": "string" }, - "stopManagingHarnessLabels": { + "parameters": { "items": { - "type": "string" + "$ref": "#/components/schemas/McpMarketplaceParameterResponse" }, - "title": "Stopmanagingharnesslabels", + "title": "Parameters", "type": "array" - }, - "stopManagingStatus": { - "anyOf": [ - { - "enum": [ - "available", - "disabled_no_enabled" - ], - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Stopmanagingstatus" } }, "required": [ - "canManage", - "stopManagingStatus", - "stopManagingHarnessLabels", - "canDelete", - "deleteHarnessLabels" + "name", + "description", + "parameters" ], - "title": "SkillDetailActionsResponse", + "title": "McpMarketplaceToolResponse", "type": "object" }, - "SkillDetailResponse": { + "McpMutationFailureResponse": { "properties": { - "actions": { - "$ref": "#/components/schemas/SkillDetailActionsResponse" + "error": { + "title": "Error", + "type": "string" }, - "attentionMessage": { + "harness": { + "title": "Harness", + "type": "string" + } + }, + "required": [ + "harness", + "error" + ], + "title": "McpMutationFailureResponse", + "type": "object" + }, + "McpServerDetailResponse": { + "properties": { + "availabilityReason": { "anyOf": [ { "type": "string" @@ -3474,57 +3059,87 @@ "type": "null" } ], - "title": "Attentionmessage" + "description": "Deprecated compatibility field; use mcpStatus.reason instead.", + "title": "Availabilityreason" }, - "description": { - "title": "Description", + "availabilityStatus": { + "description": "Deprecated compatibility field; use mcpStatus instead.", + "enum": [ + "available", + "unavailable" + ], + "title": "Availabilitystatus", "type": "string" }, - "displayStatus": { + "canEnable": { + "title": "Canenable", + "type": "boolean" + }, + "configChoices": { + "items": { + "$ref": "#/components/schemas/McpConfigChoiceResponse" + }, + "title": "Configchoices", + "type": "array" + }, + "displayName": { + "title": "Displayname", + "type": "string" + }, + "enabledStatus": { "enum": [ - "Managed", - "Unmanaged" + "enabled", + "disabled" ], - "title": "Displaystatus", + "title": "Enabledstatus", "type": "string" }, - "documentMarkdown": { + "env": { + "items": { + "$ref": "#/components/schemas/McpEnvEntryResponse" + }, + "title": "Env", + "type": "array" + }, + "installConfigStatus": { + "$ref": "#/components/schemas/McpInstallConfigStatusResponse" + }, + "kind": { + "enum": [ + "managed", + "unmanaged" + ], + "title": "Kind", + "type": "string" + }, + "marketplaceLink": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/McpMarketplaceLinkResponse" }, { "type": "null" } - ], - "title": "Documentmarkdown" - }, - "harnessCells": { - "items": { - "$ref": "#/components/schemas/HarnessCellResponse" - }, - "title": "Harnesscells", - "type": "array" + ] }, - "locations": { - "items": { - "$ref": "#/components/schemas/SkillLocationResponse" - }, - "title": "Locations", - "type": "array" + "mcpStatus": { + "$ref": "#/components/schemas/McpStatusResponse" }, "name": { "title": "Name", "type": "string" }, - "skillRef": { - "title": "Skillref", - "type": "string" + "sightings": { + "items": { + "$ref": "#/components/schemas/McpBindingResponse" + }, + "title": "Sightings", + "type": "array" }, - "sourceLinks": { + "spec": { "anyOf": [ { - "$ref": "#/components/schemas/SkillSourceLinksResponse" + "$ref": "#/components/schemas/McpServerSpecResponse" }, { "type": "null" @@ -3533,34 +3148,53 @@ } }, "required": [ - "skillRef", "name", - "description", - "displayStatus", - "attentionMessage", - "actions", - "harnessCells", - "locations", - "sourceLinks", - "documentMarkdown" + "displayName", + "kind", + "canEnable", + "enabledStatus", + "availabilityStatus", + "mcpStatus", + "installConfigStatus", + "sightings" ], - "title": "SkillDetailResponse", + "title": "McpServerDetailResponse", "type": "object" }, - "SkillLocationResponse": { + "McpServerMutationResponse": { "properties": { - "detail": { + "ok": { + "title": "Ok", + "type": "boolean" + }, + "server": { + "$ref": "#/components/schemas/McpServerSpecResponse" + } + }, + "required": [ + "ok", + "server" + ], + "title": "McpServerMutationResponse", + "type": "object" + }, + "McpServerSpecResponse": { + "properties": { + "args": { "anyOf": [ { - "type": "string" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } ], - "title": "Detail" + "title": "Args" }, - "harness": { + "command": { "anyOf": [ { "type": "string" @@ -3569,519 +3203,605 @@ "type": "null" } ], - "title": "Harness" - }, - "kind": { - "enum": [ - "shared", - "harness" - ], - "title": "Kind", - "type": "string" + "title": "Command" }, - "label": { - "title": "Label", + "displayName": { + "title": "Displayname", "type": "string" }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Path" - }, - "revision": { + "env": { "anyOf": [ { - "type": "string" + "additionalProperties": { + "type": "string" + }, + "type": "object" }, { "type": "null" } ], - "title": "Revision" + "title": "Env" }, - "scope": { + "headers": { "anyOf": [ { - "type": "string" + "additionalProperties": { + "type": "string" + }, + "type": "object" }, { "type": "null" } ], - "title": "Scope" + "title": "Headers" }, - "sourceKind": { - "title": "Sourcekind", + "installedAt": { + "title": "Installedat", "type": "string" }, - "sourceLocator": { - "title": "Sourcelocator", + "name": { + "title": "Name", "type": "string" - } + }, + "revision": { + "title": "Revision", + "type": "string" + }, + "source": { + "$ref": "#/components/schemas/McpSourceResponse" + }, + "transport": { + "enum": [ + "stdio", + "http", + "sse" + ], + "title": "Transport", + "type": "string" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Url" + } }, "required": [ - "kind", - "harness", - "label", - "scope", - "path", - "revision", - "sourceKind", - "sourceLocator", - "detail" + "name", + "displayName", + "source", + "transport", + "installedAt", + "revision" ], - "title": "SkillLocationResponse", + "title": "McpServerSpecResponse", "type": "object" }, - "SkillRowActionsResponse": { + "McpSetHarnessesResultResponse": { "properties": { - "canDelete": { - "title": "Candelete", - "type": "boolean" + "failed": { + "items": { + "$ref": "#/components/schemas/McpMutationFailureResponse" + }, + "title": "Failed", + "type": "array" }, - "canManage": { - "title": "Canmanage", + "ok": { + "title": "Ok", "type": "boolean" }, - "canStopManaging": { - "title": "Canstopmanaging", - "type": "boolean" + "succeeded": { + "items": { + "type": "string" + }, + "title": "Succeeded", + "type": "array" } }, "required": [ - "canManage", - "canStopManaging", - "canDelete" + "ok", + "succeeded", + "failed" ], - "title": "SkillRowActionsResponse", + "title": "McpSetHarnessesResultResponse", "type": "object" }, - "SkillSourceLinksResponse": { + "McpSourceResponse": { "properties": { - "folderUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } + "kind": { + "enum": [ + "marketplace", + "adopted", + "manual" ], - "title": "Folderurl" - }, - "repoLabel": { - "title": "Repolabel", + "title": "Kind", "type": "string" }, - "repoUrl": { - "title": "Repourl", + "locator": { + "title": "Locator", "type": "string" } }, "required": [ - "repoLabel", - "repoUrl", - "folderUrl" + "kind", + "locator" ], - "title": "SkillSourceLinksResponse", + "title": "McpSourceResponse", "type": "object" }, - "SkillSourceStatusResponse": { + "McpStatusResponse": { "properties": { - "updateStatus": { + "kind": { + "enum": [ + "available", + "needs_config", + "connection_issue", + "unchecked" + ], + "title": "Kind", + "type": "string" + }, + "reason": { "anyOf": [ { - "enum": [ - "update_available", - "no_update_available", - "no_source_available", - "local_changes_detected" - ], "type": "string" }, { "type": "null" } ], - "title": "Updatestatus" + "title": "Reason" } }, "required": [ - "updateStatus" + "kind" ], - "title": "SkillSourceStatusResponse", + "title": "McpStatusResponse", "type": "object" }, - "SkillTableRowResponse": { + "McpUnmanagedByServerResponse": { "properties": { - "actions": { - "$ref": "#/components/schemas/SkillRowActionsResponse" - }, - "cells": { + "harnesses": { "items": { - "$ref": "#/components/schemas/HarnessCellResponse" + "$ref": "#/components/schemas/McpUnmanagedHarnessResponse" }, - "title": "Cells", + "title": "Harnesses", "type": "array" }, - "description": { - "title": "Description", - "type": "string" - }, - "displayStatus": { - "enum": [ - "Managed", - "Unmanaged" - ], - "title": "Displaystatus", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "skillRef": { - "title": "Skillref", - "type": "string" - } - }, - "required": [ - "skillRef", - "name", - "description", - "displayStatus", - "actions", - "cells" - ], - "title": "SkillTableRowResponse", - "type": "object" - }, - "SkillsPageResponse": { - "properties": { - "harnessColumns": { + "issues": { "items": { - "$ref": "#/components/schemas/HarnessColumnResponse" + "$ref": "#/components/schemas/McpAdoptionIssueResponse" }, - "title": "Harnesscolumns", + "title": "Issues", "type": "array" }, - "rows": { + "servers": { "items": { - "$ref": "#/components/schemas/SkillTableRowResponse" + "$ref": "#/components/schemas/McpIdentityGroupResponse" }, - "title": "Rows", + "title": "Servers", "type": "array" - }, - "summary": { - "$ref": "#/components/schemas/SkillsSummaryResponse" } }, "required": [ - "summary", - "harnessColumns", - "rows" + "harnesses", + "servers" ], - "title": "SkillsPageResponse", + "title": "McpUnmanagedByServerResponse", "type": "object" }, - "SkillsSummaryResponse": { + "McpUnmanagedHarnessResponse": { "properties": { - "managed": { - "title": "Managed", - "type": "integer" + "configPath": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Configpath" }, - "unmanaged": { - "title": "Unmanaged", - "type": "integer" - } - }, - "required": [ - "managed", - "unmanaged" - ], - "title": "SkillsSummaryResponse", - "type": "object" - }, - "SlashCommandDeleteResponse": { - "properties": { - "ok": { - "title": "Ok", + "configPresent": { + "title": "Configpresent", "type": "boolean" }, - "sync": { - "items": { - "$ref": "#/components/schemas/SlashSyncEntryResponse" - }, - "title": "Sync", - "type": "array" - } - }, - "required": [ - "ok", - "sync" - ], - "title": "SlashCommandDeleteResponse", - "type": "object" - }, - "SlashCommandImportRequest": { - "properties": { - "name": { - "minLength": 1, - "title": "Name", + "harness": { + "title": "Harness", "type": "string" }, - "target": { - "enum": [ - "opencode", - "claude", - "cursor", - "codex" - ], - "title": "Target", + "installed": { + "title": "Installed", + "type": "boolean" + }, + "label": { + "title": "Label", "type": "string" + }, + "logoKey": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Logokey" + }, + "mcpUnavailableReason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Mcpunavailablereason" + }, + "mcpWritable": { + "default": true, + "title": "Mcpwritable", + "type": "boolean" } }, "required": [ - "target", - "name" + "harness", + "label", + "installed", + "configPresent" ], - "title": "SlashCommandImportRequest", + "title": "McpUnmanagedHarnessResponse", "type": "object" }, - "SlashCommandListResponse": { + "OkResponse": { "properties": { - "commands": { + "ok": { + "title": "Ok", + "type": "boolean" + } + }, + "required": [ + "ok" + ], + "title": "OkResponse", + "type": "object" + }, + "PermissionApplyConfigResponse": { + "properties": { + "failed": { "items": { - "$ref": "#/components/schemas/SlashCommandResponse" + "$ref": "#/components/schemas/PermissionMutationFailureResponse" }, - "title": "Commands", + "title": "Failed", "type": "array" }, - "defaultTargets": { + "ok": { + "title": "Ok", + "type": "boolean" + }, + "permission": { + "$ref": "#/components/schemas/PermissionSpecResponse" + }, + "succeeded": { "items": { - "enum": [ - "opencode", - "claude", - "cursor", - "codex" - ], "type": "string" }, - "title": "Defaulttargets", + "title": "Succeeded", "type": "array" + } + }, + "required": [ + "ok", + "permission", + "succeeded", + "failed" + ], + "title": "PermissionApplyConfigResponse", + "type": "object" + }, + "PermissionBindingResponse": { + "properties": { + "caveat": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Caveat" }, - "reviewCommands": { - "items": { - "$ref": "#/components/schemas/SlashCommandReviewResponse" - }, - "title": "Reviewcommands", - "type": "array" + "driftDetail": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Driftdetail" }, - "storePath": { - "title": "Storepath", + "harness": { + "title": "Harness", "type": "string" }, - "syncStatePath": { - "title": "Syncstatepath", + "state": { + "enum": [ + "managed", + "drifted", + "unmanaged", + "missing", + "unsupported" + ], + "title": "State", "type": "string" - }, - "targets": { - "items": { - "$ref": "#/components/schemas/SlashTargetResponse" - }, - "title": "Targets", - "type": "array" } }, "required": [ - "storePath", - "syncStatePath", - "targets", - "defaultTargets", - "commands", - "reviewCommands" + "harness", + "state" ], - "title": "SlashCommandListResponse", + "title": "PermissionBindingResponse", "type": "object" }, - "SlashCommandMutationRequest": { + "PermissionInventoryColumnResponse": { "properties": { - "description": { - "minLength": 1, - "title": "Description", - "type": "string" + "configPresent": { + "title": "Configpresent", + "type": "boolean" }, - "name": { - "minLength": 1, - "title": "Name", + "harness": { + "title": "Harness", "type": "string" }, - "prompt": { - "minLength": 1, - "title": "Prompt", + "installed": { + "title": "Installed", + "type": "boolean" + }, + "label": { + "title": "Label", "type": "string" }, - "targets": { + "logoKey": { "anyOf": [ { - "items": { - "enum": [ - "opencode", - "claude", - "cursor", - "codex" - ], - "type": "string" - }, - "type": "array" + "type": "string" }, { "type": "null" } ], - "title": "Targets" - } - }, - "required": [ - "name", - "description", - "prompt" - ], - "title": "SlashCommandMutationRequest", - "type": "object" - }, - "SlashCommandMutationResponse": { - "properties": { - "command": { + "title": "Logokey" + }, + "permissionsUnavailableReason": { "anyOf": [ { - "$ref": "#/components/schemas/SlashCommandResponse" + "type": "string" }, { "type": "null" } - ] + ], + "title": "Permissionsunavailablereason" }, - "ok": { - "title": "Ok", + "permissionsWritable": { + "default": true, + "title": "Permissionswritable", "type": "boolean" - }, - "sync": { - "items": { - "$ref": "#/components/schemas/SlashSyncEntryResponse" - }, - "title": "Sync", - "type": "array" } }, "required": [ - "ok", - "command", - "sync" + "harness", + "label", + "installed", + "configPresent" ], - "title": "SlashCommandMutationResponse", + "title": "PermissionInventoryColumnResponse", "type": "object" }, - "SlashCommandResolveRequest": { + "PermissionInventoryEntryResponse": { "properties": { - "action": { + "canEnable": { + "title": "Canenable", + "type": "boolean" + }, + "displayName": { + "title": "Displayname", + "type": "string" + }, + "enabledStatus": { "enum": [ - "restore_managed", - "adopt_target", - "remove_binding" + "enabled", + "disabled" ], - "title": "Action", + "title": "Enabledstatus", "type": "string" }, - "name": { - "minLength": 1, - "title": "Name", + "id": { + "title": "Id", "type": "string" }, - "target": { + "kind": { "enum": [ - "opencode", - "claude", - "cursor", - "codex" + "managed", + "unmanaged" ], - "title": "Target", + "title": "Kind", "type": "string" - } - }, - "required": [ - "target", - "name", - "action" - ], - "title": "SlashCommandResolveRequest", + }, + "sightings": { + "items": { + "$ref": "#/components/schemas/PermissionBindingResponse" + }, + "title": "Sightings", + "type": "array" + }, + "spec": { + "anyOf": [ + { + "$ref": "#/components/schemas/PermissionSpecResponse" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "id", + "displayName", + "kind", + "canEnable", + "enabledStatus", + "sightings" + ], + "title": "PermissionInventoryEntryResponse", "type": "object" }, - "SlashCommandResponse": { + "PermissionInventoryIssueResponse": { "properties": { - "description": { - "title": "Description", - "type": "string" - }, "name": { "title": "Name", "type": "string" }, - "prompt": { - "title": "Prompt", + "reason": { + "title": "Reason", "type": "string" + } + }, + "required": [ + "name", + "reason" + ], + "title": "PermissionInventoryIssueResponse", + "type": "object" + }, + "PermissionInventoryResponse": { + "properties": { + "columns": { + "items": { + "$ref": "#/components/schemas/PermissionInventoryColumnResponse" + }, + "title": "Columns", + "type": "array" }, - "syncTargets": { + "entries": { "items": { - "$ref": "#/components/schemas/SlashSyncEntryResponse" + "$ref": "#/components/schemas/PermissionInventoryEntryResponse" }, - "title": "Synctargets", + "title": "Entries", + "type": "array" + }, + "issues": { + "items": { + "$ref": "#/components/schemas/PermissionInventoryIssueResponse" + }, + "title": "Issues", "type": "array" } }, "required": [ - "name", - "description", - "prompt", - "syncTargets" + "columns", + "entries" ], - "title": "SlashCommandResponse", + "title": "PermissionInventoryResponse", "type": "object" }, - "SlashCommandReviewResponse": { + "PermissionMutationFailureResponse": { "properties": { - "actions": { + "error": { + "title": "Error", + "type": "string" + }, + "harness": { + "title": "Harness", + "type": "string" + } + }, + "required": [ + "harness", + "error" + ], + "title": "PermissionMutationFailureResponse", + "type": "object" + }, + "PermissionMutationResponse": { + "properties": { + "ok": { + "title": "Ok", + "type": "boolean" + }, + "permission": { + "$ref": "#/components/schemas/PermissionSpecResponse" + } + }, + "required": [ + "ok", + "permission" + ], + "title": "PermissionMutationResponse", + "type": "object" + }, + "PermissionSetHarnessesResultResponse": { + "properties": { + "failed": { "items": { - "enum": [ - "import", - "restore_managed", - "adopt_target", - "remove_binding" - ], - "type": "string" + "$ref": "#/components/schemas/PermissionMutationFailureResponse" }, - "title": "Actions", + "title": "Failed", "type": "array" }, - "canImport": { - "title": "Canimport", + "ok": { + "title": "Ok", "type": "boolean" }, - "commandExists": { - "title": "Commandexists", - "type": "boolean" + "succeeded": { + "items": { + "type": "string" + }, + "title": "Succeeded", + "type": "array" + } + }, + "required": [ + "ok", + "succeeded", + "failed" + ], + "title": "PermissionSetHarnessesResultResponse", + "type": "object" + }, + "PermissionSpecResponse": { + "properties": { + "decision": { + "title": "Decision", + "type": "string" }, "description": { "title": "Description", "type": "string" }, - "error": { + "id": { + "title": "Id", + "type": "string" + }, + "installedAt": { + "title": "Installedat", + "type": "string" + }, + "pattern": { "anyOf": [ { "type": "string" @@ -4090,107 +3810,50 @@ "type": "null" } ], - "title": "Error" - }, - "kind": { - "enum": [ - "unmanaged", - "drifted", - "missing" - ], - "title": "Kind", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "path": { - "title": "Path", - "type": "string" - }, - "prompt": { - "title": "Prompt", - "type": "string" - }, - "reviewRef": { - "title": "Reviewref", - "type": "string" + "title": "Pattern" }, - "target": { - "enum": [ - "opencode", - "claude", - "cursor", - "codex" - ], - "title": "Target", + "revision": { + "title": "Revision", "type": "string" }, - "targetLabel": { - "title": "Targetlabel", + "scope": { + "title": "Scope", "type": "string" } }, "required": [ - "reviewRef", - "kind", - "target", - "targetLabel", - "name", - "path", + "id", + "decision", + "scope", "description", - "prompt", - "commandExists", - "canImport", - "actions" + "installedAt", + "revision" ], - "title": "SlashCommandReviewResponse", + "title": "PermissionSpecResponse", "type": "object" }, - "SlashCommandUpdateRequest": { + "PromoteHookRequest": { + "additionalProperties": false, "properties": { - "description": { - "minLength": 1, - "title": "Description", - "type": "string" - }, - "prompt": { - "minLength": 1, - "title": "Prompt", - "type": "string" - }, - "targets": { + "observedHarness": { "anyOf": [ { - "items": { - "enum": [ - "opencode", - "claude", - "cursor", - "codex" - ], - "type": "string" - }, - "type": "array" + "type": "string" }, { "type": "null" } ], - "title": "Targets" + "title": "Observed harness" } }, - "required": [ - "description", - "prompt" - ], - "title": "SlashCommandUpdateRequest", + "title": "PromoteHookRequest", "type": "object" }, - "SlashSyncEntryResponse": { + "PromotePermissionRequest": { + "additionalProperties": false, "properties": { - "error": { + "observedHarness": { "anyOf": [ { "type": "string" @@ -4199,57 +3862,62 @@ "type": "null" } ], - "title": "Error" - }, - "path": { - "title": "Path", - "type": "string" + "title": "Observed harness" + } + }, + "title": "PromotePermissionRequest", + "type": "object" + }, + "ReconcileHookRequest": { + "additionalProperties": false, + "properties": { + "harnesses": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Harnesses" }, - "status": { - "enum": [ - "synced", - "removed", - "not_selected", - "blocked_manual_file", - "blocked_modified_file", - "missing", - "drifted", - "failed" + "observedHarness": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } ], - "title": "Status", - "type": "string" + "title": "Observed harness" }, - "target": { + "sourceKind": { "enum": [ - "opencode", - "claude", - "cursor", - "codex" + "managed", + "harness" ], - "title": "Target", + "title": "Sourcekind", "type": "string" } }, "required": [ - "target", - "path", - "status" + "sourceKind" ], - "title": "SlashSyncEntryResponse", + "title": "ReconcileHookRequest", "type": "object" }, - "SlashSyncRequest": { + "ReconcileMcpServerRequest": { + "additionalProperties": false, "properties": { - "targets": { + "harnesses": { "anyOf": [ { "items": { - "enum": [ - "opencode", - "claude", - "cursor", - "codex" - ], "type": "string" }, "type": "array" @@ -4258,100 +3926,1365 @@ "type": "null" } ], - "title": "Targets" + "title": "Harnesses" + }, + "observedHarness": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Observed harness" + }, + "sourceKind": { + "enum": [ + "managed", + "harness" + ], + "title": "Sourcekind", + "type": "string" } }, - "title": "SlashSyncRequest", + "required": [ + "sourceKind" + ], + "title": "ReconcileMcpServerRequest", "type": "object" }, - "SlashTargetResponse": { + "ReconcilePermissionRequest": { + "additionalProperties": false, "properties": { - "available": { - "title": "Available", - "type": "boolean" - }, - "defaultSelected": { - "title": "Defaultselected", - "type": "boolean" - }, - "docsUrl": { - "title": "Docsurl", - "type": "string" - }, - "enabled": { - "title": "Enabled", - "type": "boolean" + "harnesses": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Harnesses" }, - "fileGlob": { - "title": "Fileglob", - "type": "string" + "observedHarness": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Observed harness" }, - "id": { + "sourceKind": { "enum": [ - "opencode", - "claude", - "cursor", - "codex" + "managed", + "harness" ], - "title": "Id", + "title": "Sourcekind", "type": "string" - }, - "invocationPrefix": { - "title": "Invocationprefix", + } + }, + "required": [ + "sourceKind" + ], + "title": "ReconcilePermissionRequest", + "type": "object" + }, + "ScaffoldRequest": { + "properties": { + "asset_type": { + "title": "Asset Type", "type": "string" }, - "label": { - "title": "Label", + "description": { + "title": "Description", "type": "string" }, - "outputDir": { - "title": "Outputdir", + "name": { + "title": "Name", "type": "string" - }, - "renderFormat": { - "enum": [ - "frontmatter_markdown", - "cursor_plaintext" - ], - "title": "Renderformat", + } + }, + "required": [ + "asset_type", + "name", + "description" + ], + "title": "ScaffoldRequest", + "type": "object" + }, + "ScaffoldResponse": { + "properties": { + "file_path": { + "title": "File Path", "type": "string" + } + }, + "required": [ + "file_path" + ], + "title": "ScaffoldResponse", + "type": "object" + }, + "SetAgentHarnessesRequest": { + "properties": { + "harnesses": { + "items": { + "type": "string" + }, + "title": "Harnesses", + "type": "array" + } + }, + "title": "SetAgentHarnessesRequest", + "type": "object" + }, + "SetAgentHarnessesResultResponse": { + "properties": { + "failed": { + "items": { + "$ref": "#/components/schemas/AgentMutationFailureResponse" + }, + "title": "Failed", + "type": "array" }, - "rootPath": { - "title": "Rootpath", - "type": "string" + "ok": { + "title": "Ok", + "type": "boolean" }, - "scope": { + "succeeded": { + "items": { + "type": "string" + }, + "title": "Succeeded", + "type": "array" + } + }, + "required": [ + "ok", + "succeeded", + "failed" + ], + "title": "SetAgentHarnessesResultResponse", + "type": "object" + }, + "SetHarnessSupportRequest": { + "properties": { + "enabled": { + "title": "Enabled", + "type": "boolean" + } + }, + "required": [ + "enabled" + ], + "title": "SetHarnessSupportRequest", + "type": "object" + }, + "SetHookHarnessesRequest": { + "properties": { + "target": { "enum": [ - "global", - "project" + "enabled", + "disabled" ], - "title": "Scope", + "title": "Target", "type": "string" - }, - "supportNote": { + } + }, + "required": [ + "target" + ], + "title": "SetHookHarnessesRequest", + "type": "object" + }, + "SetMcpServerHarnessesRequest": { + "properties": { + "config": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Supportnote" + "title": "Config" }, - "supportsFrontmatter": { - "title": "Supportsfrontmatter", - "type": "boolean" + "target": { + "enum": [ + "enabled", + "disabled" + ], + "title": "Target", + "type": "string" } }, "required": [ - "id", - "label", - "rootPath", - "outputDir", - "invocationPrefix", - "renderFormat", - "scope", + "target" + ], + "title": "SetMcpServerHarnessesRequest", + "type": "object" + }, + "SetPermissionHarnessesRequest": { + "properties": { + "target": { + "enum": [ + "enabled", + "disabled" + ], + "title": "Target", + "type": "string" + } + }, + "required": [ + "target" + ], + "title": "SetPermissionHarnessesRequest", + "type": "object" + }, + "SetSkillHarnessesFailureResponse": { + "properties": { + "error": { + "title": "Error", + "type": "string" + }, + "harness": { + "title": "Harness", + "type": "string" + } + }, + "required": [ + "harness", + "error" + ], + "title": "SetSkillHarnessesFailureResponse", + "type": "object" + }, + "SetSkillHarnessesRequest": { + "properties": { + "target": { + "description": "Target state to apply to every interactive harness cell on this skill", + "enum": [ + "enabled", + "disabled" + ], + "title": "Target", + "type": "string" + } + }, + "required": [ + "target" + ], + "title": "SetSkillHarnessesRequest", + "type": "object" + }, + "SetSkillHarnessesResultResponse": { + "properties": { + "failed": { + "items": { + "$ref": "#/components/schemas/SetSkillHarnessesFailureResponse" + }, + "title": "Failed", + "type": "array" + }, + "ok": { + "title": "Ok", + "type": "boolean" + }, + "succeeded": { + "items": { + "type": "string" + }, + "title": "Succeeded", + "type": "array" + } + }, + "required": [ + "ok", + "succeeded", + "failed" + ], + "title": "SetSkillHarnessesResultResponse", + "type": "object" + }, + "SettingsHarnessResponse": { + "properties": { + "harness": { + "title": "Harness", + "type": "string" + }, + "installed": { + "title": "Installed", + "type": "boolean" + }, + "label": { + "title": "Label", + "type": "string" + }, + "logoKey": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Logokey" + }, + "managedLocation": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Managedlocation" + }, + "supportEnabled": { + "title": "Supportenabled", + "type": "boolean" + } + }, + "required": [ + "harness", + "label", + "supportEnabled", + "installed", + "managedLocation" + ], + "title": "SettingsHarnessResponse", + "type": "object" + }, + "SettingsResponse": { + "properties": { + "harnesses": { + "items": { + "$ref": "#/components/schemas/SettingsHarnessResponse" + }, + "title": "Harnesses", + "type": "array" + }, + "storage": { + "$ref": "#/components/schemas/SettingsStorageResponse" + } + }, + "required": [ + "storage", + "harnesses" + ], + "title": "SettingsResponse", + "type": "object" + }, + "SettingsStorageResponse": { + "properties": { + "configDir": { + "title": "Configdir", + "type": "string" + }, + "dataDir": { + "title": "Datadir", + "type": "string" + }, + "marketplaceCachePath": { + "title": "Marketplacecachepath", + "type": "string" + }, + "platform": { + "enum": [ + "macos", + "linux" + ], + "title": "Platform", + "type": "string" + }, + "settingsPath": { + "title": "Settingspath", + "type": "string" + }, + "skillsStorePath": { + "title": "Skillsstorepath", + "type": "string" + }, + "stateDir": { + "title": "Statedir", + "type": "string" + } + }, + "required": [ + "platform", + "configDir", + "dataDir", + "stateDir", + "skillsStorePath", + "marketplaceCachePath", + "settingsPath" + ], + "title": "SettingsStorageResponse", + "type": "object" + }, + "SkillDetailActionsResponse": { + "properties": { + "canDelete": { + "title": "Candelete", + "type": "boolean" + }, + "canManage": { + "title": "Canmanage", + "type": "boolean" + }, + "deleteHarnessLabels": { + "items": { + "type": "string" + }, + "title": "Deleteharnesslabels", + "type": "array" + }, + "stopManagingHarnessLabels": { + "items": { + "type": "string" + }, + "title": "Stopmanagingharnesslabels", + "type": "array" + }, + "stopManagingStatus": { + "anyOf": [ + { + "enum": [ + "available", + "disabled_no_enabled" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Stopmanagingstatus" + } + }, + "required": [ + "canManage", + "stopManagingStatus", + "stopManagingHarnessLabels", + "canDelete", + "deleteHarnessLabels" + ], + "title": "SkillDetailActionsResponse", + "type": "object" + }, + "SkillDetailResponse": { + "properties": { + "actions": { + "$ref": "#/components/schemas/SkillDetailActionsResponse" + }, + "attentionMessage": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Attentionmessage" + }, + "description": { + "title": "Description", + "type": "string" + }, + "displayStatus": { + "enum": [ + "Managed", + "Unmanaged" + ], + "title": "Displaystatus", + "type": "string" + }, + "documentMarkdown": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Documentmarkdown" + }, + "harnessCells": { + "items": { + "$ref": "#/components/schemas/HarnessCellResponse" + }, + "title": "Harnesscells", + "type": "array" + }, + "locations": { + "items": { + "$ref": "#/components/schemas/SkillLocationResponse" + }, + "title": "Locations", + "type": "array" + }, + "name": { + "title": "Name", + "type": "string" + }, + "skillRef": { + "title": "Skillref", + "type": "string" + }, + "sourceLinks": { + "anyOf": [ + { + "$ref": "#/components/schemas/SkillSourceLinksResponse" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "skillRef", + "name", + "description", + "displayStatus", + "attentionMessage", + "actions", + "harnessCells", + "locations", + "sourceLinks", + "documentMarkdown" + ], + "title": "SkillDetailResponse", + "type": "object" + }, + "SkillLocationResponse": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Detail" + }, + "harness": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Harness" + }, + "kind": { + "enum": [ + "shared", + "harness" + ], + "title": "Kind", + "type": "string" + }, + "label": { + "title": "Label", + "type": "string" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "revision": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Revision" + }, + "scope": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope" + }, + "sourceKind": { + "title": "Sourcekind", + "type": "string" + }, + "sourceLocator": { + "title": "Sourcelocator", + "type": "string" + } + }, + "required": [ + "kind", + "harness", + "label", + "scope", + "path", + "revision", + "sourceKind", + "sourceLocator", + "detail" + ], + "title": "SkillLocationResponse", + "type": "object" + }, + "SkillRowActionsResponse": { + "properties": { + "canDelete": { + "title": "Candelete", + "type": "boolean" + }, + "canManage": { + "title": "Canmanage", + "type": "boolean" + }, + "canStopManaging": { + "title": "Canstopmanaging", + "type": "boolean" + } + }, + "required": [ + "canManage", + "canStopManaging", + "canDelete" + ], + "title": "SkillRowActionsResponse", + "type": "object" + }, + "SkillSourceLinksResponse": { + "properties": { + "folderUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Folderurl" + }, + "repoLabel": { + "title": "Repolabel", + "type": "string" + }, + "repoUrl": { + "title": "Repourl", + "type": "string" + } + }, + "required": [ + "repoLabel", + "repoUrl", + "folderUrl" + ], + "title": "SkillSourceLinksResponse", + "type": "object" + }, + "SkillSourceStatusResponse": { + "properties": { + "updateStatus": { + "anyOf": [ + { + "enum": [ + "update_available", + "no_update_available", + "no_source_available", + "local_changes_detected" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Updatestatus" + } + }, + "required": [ + "updateStatus" + ], + "title": "SkillSourceStatusResponse", + "type": "object" + }, + "SkillTableRowResponse": { + "properties": { + "actions": { + "$ref": "#/components/schemas/SkillRowActionsResponse" + }, + "cells": { + "items": { + "$ref": "#/components/schemas/HarnessCellResponse" + }, + "title": "Cells", + "type": "array" + }, + "description": { + "title": "Description", + "type": "string" + }, + "displayStatus": { + "enum": [ + "Managed", + "Unmanaged" + ], + "title": "Displaystatus", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "skillRef": { + "title": "Skillref", + "type": "string" + } + }, + "required": [ + "skillRef", + "name", + "description", + "displayStatus", + "actions", + "cells" + ], + "title": "SkillTableRowResponse", + "type": "object" + }, + "SkillsPageResponse": { + "properties": { + "harnessColumns": { + "items": { + "$ref": "#/components/schemas/HarnessColumnResponse" + }, + "title": "Harnesscolumns", + "type": "array" + }, + "rows": { + "items": { + "$ref": "#/components/schemas/SkillTableRowResponse" + }, + "title": "Rows", + "type": "array" + }, + "summary": { + "$ref": "#/components/schemas/SkillsSummaryResponse" + } + }, + "required": [ + "summary", + "harnessColumns", + "rows" + ], + "title": "SkillsPageResponse", + "type": "object" + }, + "SkillsSummaryResponse": { + "properties": { + "managed": { + "title": "Managed", + "type": "integer" + }, + "unmanaged": { + "title": "Unmanaged", + "type": "integer" + } + }, + "required": [ + "managed", + "unmanaged" + ], + "title": "SkillsSummaryResponse", + "type": "object" + }, + "SlashCommandDeleteResponse": { + "properties": { + "ok": { + "title": "Ok", + "type": "boolean" + }, + "sync": { + "items": { + "$ref": "#/components/schemas/SlashSyncEntryResponse" + }, + "title": "Sync", + "type": "array" + } + }, + "required": [ + "ok", + "sync" + ], + "title": "SlashCommandDeleteResponse", + "type": "object" + }, + "SlashCommandImportRequest": { + "properties": { + "name": { + "minLength": 1, + "title": "Name", + "type": "string" + }, + "target": { + "enum": [ + "claude", + "codex", + "cursor", + "opencode", + "hermes" + ], + "title": "Target", + "type": "string" + } + }, + "required": [ + "target", + "name" + ], + "title": "SlashCommandImportRequest", + "type": "object" + }, + "SlashCommandListResponse": { + "properties": { + "commands": { + "items": { + "$ref": "#/components/schemas/SlashCommandResponse" + }, + "title": "Commands", + "type": "array" + }, + "defaultTargets": { + "items": { + "enum": [ + "claude", + "codex", + "cursor", + "opencode", + "hermes" + ], + "type": "string" + }, + "title": "Defaulttargets", + "type": "array" + }, + "reviewCommands": { + "items": { + "$ref": "#/components/schemas/SlashCommandReviewResponse" + }, + "title": "Reviewcommands", + "type": "array" + }, + "storePath": { + "title": "Storepath", + "type": "string" + }, + "syncStatePath": { + "title": "Syncstatepath", + "type": "string" + }, + "targets": { + "items": { + "$ref": "#/components/schemas/SlashTargetResponse" + }, + "title": "Targets", + "type": "array" + } + }, + "required": [ + "storePath", + "syncStatePath", + "targets", + "defaultTargets", + "commands", + "reviewCommands" + ], + "title": "SlashCommandListResponse", + "type": "object" + }, + "SlashCommandMutationRequest": { + "properties": { + "description": { + "minLength": 1, + "title": "Description", + "type": "string" + }, + "name": { + "minLength": 1, + "title": "Name", + "type": "string" + }, + "prompt": { + "minLength": 1, + "title": "Prompt", + "type": "string" + }, + "targets": { + "anyOf": [ + { + "items": { + "enum": [ + "claude", + "codex", + "cursor", + "opencode", + "hermes" + ], + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Targets" + } + }, + "required": [ + "name", + "description", + "prompt" + ], + "title": "SlashCommandMutationRequest", + "type": "object" + }, + "SlashCommandMutationResponse": { + "properties": { + "command": { + "anyOf": [ + { + "$ref": "#/components/schemas/SlashCommandResponse" + }, + { + "type": "null" + } + ] + }, + "ok": { + "title": "Ok", + "type": "boolean" + }, + "sync": { + "items": { + "$ref": "#/components/schemas/SlashSyncEntryResponse" + }, + "title": "Sync", + "type": "array" + } + }, + "required": [ + "ok", + "command", + "sync" + ], + "title": "SlashCommandMutationResponse", + "type": "object" + }, + "SlashCommandResolveRequest": { + "properties": { + "action": { + "enum": [ + "restore_managed", + "adopt_target", + "remove_binding" + ], + "title": "Action", + "type": "string" + }, + "name": { + "minLength": 1, + "title": "Name", + "type": "string" + }, + "target": { + "enum": [ + "claude", + "codex", + "cursor", + "opencode", + "hermes" + ], + "title": "Target", + "type": "string" + } + }, + "required": [ + "target", + "name", + "action" + ], + "title": "SlashCommandResolveRequest", + "type": "object" + }, + "SlashCommandResponse": { + "properties": { + "description": { + "title": "Description", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "prompt": { + "title": "Prompt", + "type": "string" + }, + "syncTargets": { + "items": { + "$ref": "#/components/schemas/SlashSyncEntryResponse" + }, + "title": "Synctargets", + "type": "array" + } + }, + "required": [ + "name", + "description", + "prompt", + "syncTargets" + ], + "title": "SlashCommandResponse", + "type": "object" + }, + "SlashCommandReviewResponse": { + "properties": { + "actions": { + "items": { + "enum": [ + "import", + "restore_managed", + "adopt_target", + "remove_binding" + ], + "type": "string" + }, + "title": "Actions", + "type": "array" + }, + "canImport": { + "title": "Canimport", + "type": "boolean" + }, + "commandExists": { + "title": "Commandexists", + "type": "boolean" + }, + "description": { + "title": "Description", + "type": "string" + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error" + }, + "kind": { + "enum": [ + "unmanaged", + "drifted", + "missing" + ], + "title": "Kind", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "path": { + "title": "Path", + "type": "string" + }, + "prompt": { + "title": "Prompt", + "type": "string" + }, + "reviewRef": { + "title": "Reviewref", + "type": "string" + }, + "target": { + "enum": [ + "claude", + "codex", + "cursor", + "opencode", + "hermes" + ], + "title": "Target", + "type": "string" + }, + "targetLabel": { + "title": "Targetlabel", + "type": "string" + } + }, + "required": [ + "reviewRef", + "kind", + "target", + "targetLabel", + "name", + "path", + "description", + "prompt", + "commandExists", + "canImport", + "actions" + ], + "title": "SlashCommandReviewResponse", + "type": "object" + }, + "SlashCommandUpdateRequest": { + "properties": { + "description": { + "minLength": 1, + "title": "Description", + "type": "string" + }, + "prompt": { + "minLength": 1, + "title": "Prompt", + "type": "string" + }, + "targets": { + "anyOf": [ + { + "items": { + "enum": [ + "claude", + "codex", + "cursor", + "opencode", + "hermes" + ], + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Targets" + } + }, + "required": [ + "description", + "prompt" + ], + "title": "SlashCommandUpdateRequest", + "type": "object" + }, + "SlashSyncEntryResponse": { + "properties": { + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error" + }, + "path": { + "title": "Path", + "type": "string" + }, + "status": { + "enum": [ + "synced", + "removed", + "not_selected", + "blocked_manual_file", + "blocked_modified_file", + "missing", + "drifted", + "failed" + ], + "title": "Status", + "type": "string" + }, + "target": { + "enum": [ + "claude", + "codex", + "cursor", + "opencode", + "hermes" + ], + "title": "Target", + "type": "string" + } + }, + "required": [ + "target", + "path", + "status" + ], + "title": "SlashSyncEntryResponse", + "type": "object" + }, + "SlashSyncRequest": { + "properties": { + "targets": { + "anyOf": [ + { + "items": { + "enum": [ + "claude", + "codex", + "cursor", + "opencode", + "hermes" + ], + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Targets" + } + }, + "title": "SlashSyncRequest", + "type": "object" + }, + "SlashTargetResponse": { + "properties": { + "available": { + "title": "Available", + "type": "boolean" + }, + "defaultSelected": { + "title": "Defaultselected", + "type": "boolean" + }, + "docsUrl": { + "title": "Docsurl", + "type": "string" + }, + "enabled": { + "title": "Enabled", + "type": "boolean" + }, + "fileGlob": { + "title": "Fileglob", + "type": "string" + }, + "id": { + "enum": [ + "claude", + "codex", + "cursor", + "opencode", + "hermes" + ], + "title": "Id", + "type": "string" + }, + "invocationPrefix": { + "title": "Invocationprefix", + "type": "string" + }, + "label": { + "title": "Label", + "type": "string" + }, + "outputDir": { + "title": "Outputdir", + "type": "string" + }, + "renderFormat": { + "enum": [ + "frontmatter_markdown", + "cursor_plaintext" + ], + "title": "Renderformat", + "type": "string" + }, + "rootPath": { + "title": "Rootpath", + "type": "string" + }, + "scope": { + "enum": [ + "global", + "project" + ], + "title": "Scope", + "type": "string" + }, + "supportNote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Supportnote" + }, + "supportsFrontmatter": { + "title": "Supportsfrontmatter", + "type": "boolean" + } + }, + "required": [ + "id", + "label", + "rootPath", + "outputDir", + "invocationPrefix", + "renderFormat", + "scope", "docsUrl", "fileGlob", "supportsFrontmatter", @@ -4359,75 +5292,924 @@ "enabled", "available" ], - "title": "SlashTargetResponse", - "type": "object" - }, - "ValidationError": { - "properties": { - "ctx": { - "title": "Context", - "type": "object" - }, - "input": { - "title": "Input" + "title": "SlashTargetResponse", + "type": "object" + }, + "UpdateAgentRequest": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "prompt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prompt" + }, + "tools": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tools" + } + }, + "title": "UpdateAgentRequest", + "type": "object" + }, + "ValidationError": { + "properties": { + "ctx": { + "title": "Context", + "type": "object" + }, + "input": { + "title": "Input" + }, + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "title": "Location", + "type": "array" + }, + "msg": { + "title": "Message", + "type": "string" + }, + "type": { + "title": "Error Type", + "type": "string" + } + }, + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError", + "type": "object" + } + } + }, + "info": { + "title": "skill-manager", + "version": "0.1.0" + }, + "openapi": "3.1.0", + "paths": { + "/api/agents": { + "get": { + "operationId": "list_agents_api_agents_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentInventoryResponse" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "List Agents", + "tags": [ + "Agents" + ] + }, + "post": { + "operationId": "create_agent_api_agents_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateAgentRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentDetailResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Create Agent", + "tags": [ + "Agents" + ] + } + }, + "/api/agents/adopt-all": { + "post": { + "operationId": "adopt_all_agents_api_agents_adopt_all_post", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdoptAllAgentsResponse" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Adopt All Agents", + "tags": [ + "Agents" + ] + } + }, + "/api/agents/{agent_ref}": { + "delete": { + "operationId": "delete_agent_api_agents__agent_ref__delete", + "parameters": [ + { + "in": "path", + "name": "agent_ref", + "required": true, + "schema": { + "title": "Agent Ref", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OkResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Delete Agent", + "tags": [ + "Agents" + ] + }, + "get": { + "operationId": "get_agent_api_agents__agent_ref__get", + "parameters": [ + { + "in": "path", + "name": "agent_ref", + "required": true, + "schema": { + "title": "Agent Ref", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentDetailResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Get Agent", + "tags": [ + "Agents" + ] + }, + "put": { + "operationId": "update_agent_api_agents__agent_ref__put", + "parameters": [ + { + "in": "path", + "name": "agent_ref", + "required": true, + "schema": { + "title": "Agent Ref", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateAgentRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentDetailResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Update Agent", + "tags": [ + "Agents" + ] + } + }, + "/api/agents/{agent_ref}/adopt": { + "post": { + "operationId": "adopt_agent_api_agents__agent_ref__adopt_post", + "parameters": [ + { + "in": "path", + "name": "agent_ref", + "required": true, + "schema": { + "title": "Agent Ref", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdoptAgentRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdoptAgentResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Adopt Agent", + "tags": [ + "Agents" + ] + } + }, + "/api/agents/{agent_ref}/disable": { + "post": { + "operationId": "disable_agent_api_agents__agent_ref__disable_post", + "parameters": [ + { + "in": "path", + "name": "agent_ref", + "required": true, + "schema": { + "title": "Agent Ref", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentHarnessRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OkResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Disable Agent", + "tags": [ + "Agents" + ] + } + }, + "/api/agents/{agent_ref}/enable": { + "post": { + "operationId": "enable_agent_api_agents__agent_ref__enable_post", + "parameters": [ + { + "in": "path", + "name": "agent_ref", + "required": true, + "schema": { + "title": "Agent Ref", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentHarnessRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OkResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Enable Agent", + "tags": [ + "Agents" + ] + } + }, + "/api/agents/{agent_ref}/set-harnesses": { + "post": { + "operationId": "set_agent_harnesses_api_agents__agent_ref__set_harnesses_post", + "parameters": [ + { + "in": "path", + "name": "agent_ref", + "required": true, + "schema": { + "title": "Agent Ref", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetAgentHarnessesRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetAgentHarnessesResultResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Set Agent Harnesses", + "tags": [ + "Agents" + ] + } + }, + "/api/health": { + "get": { + "operationId": "health_api_health_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": true, + "title": "Response Health Api Health Get", + "type": "object" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Health" + } + }, + "/api/hooks": { + "get": { + "operationId": "list_hooks_api_hooks_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HookInventoryResponse" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "List Hooks" + }, + "post": { + "operationId": "create_hook_api_hooks_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddHookRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HookMutationResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Create Hook" + } + }, + "/api/hooks/{id}": { + "delete": { + "operationId": "delete_hook_api_hooks__id__delete", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "title": "Id", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HookSetHarnessesResultResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Delete Hook" + }, + "get": { + "operationId": "get_hook_api_hooks__id__get", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "title": "Id", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HookInventoryEntryResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Get Hook" + } + }, + "/api/hooks/{id}/disable": { + "post": { + "operationId": "disable_hook_api_hooks__id__disable_post", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "title": "Id", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisableHookRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OkResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Disable Hook" + } + }, + "/api/hooks/{id}/enable": { + "post": { + "operationId": "enable_hook_api_hooks__id__enable_post", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "title": "Id", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnableHookRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OkResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Enable Hook" + } + }, + "/api/hooks/{id}/promote": { + "post": { + "operationId": "promote_hook_api_hooks__id__promote_post", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "title": "Id", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PromoteHookRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HookMutationResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Promote Hook" + } + }, + "/api/hooks/{id}/reconcile": { + "post": { + "operationId": "reconcile_hook_api_hooks__id__reconcile_post", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "title": "Id", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReconcileHookRequest" + } + } }, - "loc": { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "integer" + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HookApplyConfigResponse" } - ] + } }, - "title": "Location", - "type": "array" - }, - "msg": { - "title": "Message", - "type": "string" + "description": "Successful Response" }, - "type": { - "title": "Error Type", - "type": "string" + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" } }, - "required": [ - "loc", - "msg", - "type" - ], - "title": "ValidationError", - "type": "object" + "summary": "Reconcile Hook" } - } - }, - "info": { - "title": "skill-manager", - "version": "0.1.0" - }, - "openapi": "3.1.0", - "paths": { - "/api/health": { - "get": { - "operationId": "health_api_health_get", + }, + "/api/hooks/{id}/set-harnesses": { + "post": { + "operationId": "set_hook_harnesses_api_hooks__id__set_harnesses_post", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "title": "Id", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetHookHarnessesRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "additionalProperties": true, - "title": "Response Health Api Health Get", - "type": "object" + "$ref": "#/components/schemas/HookSetHarnessesResultResponse" } } }, "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" } }, - "summary": "Health" + "summary": "Set Hook Harnesses" } }, "/api/marketplace/clis/items/{slug}": { @@ -5454,48 +7236,30 @@ "summary": "List Unmanaged By Server" } }, - "/api/scan/availability": { - "get": { - "operationId": "check_scan_availability_api_scan_availability_get", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ScanAvailabilityResponse" - } - } - }, - "description": "Successful Response" - } - }, - "summary": "Check Scan Availability" - } - }, - "/api/scan/configs": { + "/api/permissions": { "get": { - "operationId": "list_scan_configs_api_scan_configs_get", + "operationId": "list_permissions_api_permissions_get", "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ScanConfigListResponse" + "$ref": "#/components/schemas/PermissionInventoryResponse" } } }, "description": "Successful Response" } }, - "summary": "List Scan Configs" + "summary": "List Permissions" }, "post": { - "operationId": "create_scan_config_api_scan_configs_post", + "operationId": "create_permission_api_permissions_post", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ScanConfigSaveRequest" + "$ref": "#/components/schemas/AddPermissionRequest" } } }, @@ -5506,7 +7270,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ScanConfigItem" + "$ref": "#/components/schemas/PermissionMutationResponse" } } }, @@ -5523,28 +7287,29 @@ "description": "Validation Error" } }, - "summary": "Create Scan Config" + "summary": "Create Permission" } }, - "/api/scan/configs/validate": { - "post": { - "operationId": "validate_scan_config_api_scan_configs_validate_post", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ScanConfigValidateRequest" - } + "/api/permissions/{id}": { + "delete": { + "operationId": "delete_permission_api_permissions__id__delete", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "title": "Id", + "type": "string" } - }, - "required": true - }, + } + ], "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ScanConfigValidationResponse" + "$ref": "#/components/schemas/PermissionSetHarnessesResultResponse" } } }, @@ -5561,20 +7326,18 @@ "description": "Validation Error" } }, - "summary": "Validate Scan Config" - } - }, - "/api/scan/configs/{config_id}": { - "delete": { - "operationId": "delete_scan_config_api_scan_configs__config_id__delete", + "summary": "Delete Permission" + }, + "get": { + "operationId": "get_permission_api_permissions__id__get", "parameters": [ { "in": "path", - "name": "config_id", + "name": "id", "required": true, "schema": { - "title": "Config Id", - "type": "integer" + "title": "Id", + "type": "string" } } ], @@ -5582,7 +7345,9 @@ "200": { "content": { "application/json": { - "schema": {} + "schema": { + "$ref": "#/components/schemas/PermissionInventoryEntryResponse" + } } }, "description": "Successful Response" @@ -5598,18 +7363,20 @@ "description": "Validation Error" } }, - "summary": "Delete Scan Config" - }, - "put": { - "operationId": "update_scan_config_api_scan_configs__config_id__put", + "summary": "Get Permission" + } + }, + "/api/permissions/{id}/disable": { + "post": { + "operationId": "disable_permission_api_permissions__id__disable_post", "parameters": [ { "in": "path", - "name": "config_id", + "name": "id", "required": true, "schema": { - "title": "Config Id", - "type": "integer" + "title": "Id", + "type": "string" } } ], @@ -5617,7 +7384,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ScanConfigSaveRequest" + "$ref": "#/components/schemas/DisablePermissionRequest" } } }, @@ -5628,7 +7395,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ScanConfigItem" + "$ref": "#/components/schemas/OkResponse" } } }, @@ -5645,28 +7412,40 @@ "description": "Validation Error" } }, - "summary": "Update Scan Config" + "summary": "Disable Permission" } }, - "/api/scan/configs/{config_id}/active": { - "put": { - "operationId": "set_active_scan_config_api_scan_configs__config_id__active_put", + "/api/permissions/{id}/enable": { + "post": { + "operationId": "enable_permission_api_permissions__id__enable_post", "parameters": [ { "in": "path", - "name": "config_id", + "name": "id", "required": true, "schema": { - "title": "Config Id", - "type": "integer" + "title": "Id", + "type": "string" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnablePermissionRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { - "schema": {} + "schema": { + "$ref": "#/components/schemas/OkResponse" + } } }, "description": "Successful Response" @@ -5682,29 +7461,39 @@ "description": "Validation Error" } }, - "summary": "Set Active Scan Config" + "summary": "Enable Permission" } }, - "/api/scan/configs/{config_id}/secret": { - "get": { - "operationId": "reveal_scan_config_secret_api_scan_configs__config_id__secret_get", + "/api/permissions/{id}/promote": { + "post": { + "operationId": "promote_permission_api_permissions__id__promote_post", "parameters": [ { "in": "path", - "name": "config_id", + "name": "id", "required": true, "schema": { - "title": "Config Id", - "type": "integer" + "title": "Id", + "type": "string" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PromotePermissionRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ScanConfigSecretResponse" + "$ref": "#/components/schemas/PermissionMutationResponse" } } }, @@ -5721,37 +7510,68 @@ "description": "Validation Error" } }, - "summary": "Reveal Scan Config Secret" + "summary": "Promote Permission" } }, - "/api/scan/llm/detection": { - "get": { - "operationId": "detect_llm_api_scan_llm_detection_get", + "/api/permissions/{id}/reconcile": { + "post": { + "operationId": "reconcile_permission_api_permissions__id__reconcile_post", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "title": "Id", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReconcilePermissionRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/LLMDetectionResponse" + "$ref": "#/components/schemas/PermissionApplyConfigResponse" } } }, "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" } }, - "summary": "Detect Llm" + "summary": "Reconcile Permission" } }, - "/api/scan/skills/{skill_ref}": { + "/api/permissions/{id}/set-harnesses": { "post": { - "operationId": "scan_skill_api_scan_skills__skill_ref__post", + "operationId": "set_permission_harnesses_api_permissions__id__set_harnesses_post", "parameters": [ { "in": "path", - "name": "skill_ref", + "name": "id", "required": true, "schema": { - "title": "Skill Ref", + "title": "Id", "type": "string" } } @@ -5760,25 +7580,56 @@ "content": { "application/json": { "schema": { - "anyOf": [ - { - "$ref": "#/components/schemas/ScanOptionsRequest" - }, - { - "type": "null" - } - ], - "title": "Body" + "$ref": "#/components/schemas/SetPermissionHarnessesRequest" } } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PermissionSetHarnessesResultResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" } }, + "summary": "Set Permission Harnesses" + } + }, + "/api/scaffold": { + "post": { + "operationId": "scaffold_asset_api_scaffold_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScaffoldRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ScanResultResponse" + "$ref": "#/components/schemas/ScaffoldResponse" } } }, @@ -5795,7 +7646,10 @@ "description": "Validation Error" } }, - "summary": "Scan Skill" + "summary": "Scaffold Asset", + "tags": [ + "Scaffold" + ] } }, "/api/settings": { diff --git a/frontend/src/app/capability-registry/import-boundary.test.ts b/frontend/src/app/capability-registry/import-boundary.test.ts index 525bf0f1..852559ea 100644 --- a/frontend/src/app/capability-registry/import-boundary.test.ts +++ b/frontend/src/app/capability-registry/import-boundary.test.ts @@ -6,9 +6,11 @@ const FORBIDDEN = [ ["../..", "mcp", "api"].join("/"), ["../..", "skills", "api"].join("/"), ["../..", "settings", "queries"].join("/"), + ["../..", "agents", "api"].join("/"), ["..", "mcp", "api"].join("/"), ["..", "skills", "api"].join("/"), ["..", "settings", "queries"].join("/"), + ["..", "agents", "api"].join("/"), ]; describe("feature public import boundaries", () => { diff --git a/frontend/src/app/capability-registry/index.ts b/frontend/src/app/capability-registry/index.ts index 54763c23..7033fade 100644 --- a/frontend/src/app/capability-registry/index.ts +++ b/frontend/src/app/capability-registry/index.ts @@ -16,5 +16,6 @@ export { type SidebarGroupModel, type SidebarIconKey, type SidebarLinkModel, + type SidebarTopLinkModel, type SidebarModel, } from "./sidebar"; diff --git a/frontend/src/app/capability-registry/invalidation.ts b/frontend/src/app/capability-registry/invalidation.ts index 209845e5..c76dae22 100644 --- a/frontend/src/app/capability-registry/invalidation.ts +++ b/frontend/src/app/capability-registry/invalidation.ts @@ -5,6 +5,8 @@ import { invalidateMcpQueries } from "../../features/mcp/public"; import { invalidateSettingsQueries } from "../../features/settings/public"; import { invalidateSkillsQueries } from "../../features/skills/public"; import { invalidateSlashCommandQueries } from "../../features/slash-commands/public"; +import { invalidateHooksQueries } from "../../features/hooks/public"; +import { invalidateAgentsQueries } from "../../features/agents/public"; export async function invalidateCapabilityQueries(queryClient: QueryClient): Promise { await Promise.all([ @@ -13,5 +15,7 @@ export async function invalidateCapabilityQueries(queryClient: QueryClient): Pro invalidateSettingsQueries(queryClient), invalidateMarketplaceQueries(queryClient), invalidateSlashCommandQueries(queryClient), + invalidateHooksQueries(queryClient), + invalidateAgentsQueries(queryClient), ]); } diff --git a/frontend/src/app/capability-registry/overview.test.ts b/frontend/src/app/capability-registry/overview.test.ts index c08d0ce2..3ba9f73e 100644 --- a/frontend/src/app/capability-registry/overview.test.ts +++ b/frontend/src/app/capability-registry/overview.test.ts @@ -73,9 +73,12 @@ describe("capability overview model", () => { ], issues: [], }, + null, + null, + null, ); - expect(model.extensions.map((entry) => entry.key)).toEqual(["skills", "slash-commands", "mcp"]); + expect(model.extensions.map((entry) => entry.key)).toEqual(["skills", "slash-commands", "mcp", "hooks", "permissions", "agents"]); expect(model.marketplaceEntries.map((entry) => entry.key)).toEqual(["skills", "mcp", "clis"]); expect(model.marketplaceEntries.find((entry) => entry.key === "clis")).toMatchObject({ badge: "Preview only", diff --git a/frontend/src/app/capability-registry/overview.ts b/frontend/src/app/capability-registry/overview.ts index bbbd895e..86fd9a71 100644 --- a/frontend/src/app/capability-registry/overview.ts +++ b/frontend/src/app/capability-registry/overview.ts @@ -1,4 +1,10 @@ import type { QueryClient } from "@tanstack/react-query"; +import { + invalidateAgentsQueries, + agentsRoutes, + useAgentsInventoryQuery, + type AgentInventoryDto, +} from "../../features/agents/public"; import { useMemo } from "react"; import { @@ -22,6 +28,18 @@ import { } from "../../features/slash-commands/public"; import { marketplaceRoutes } from "../../features/marketplace/public"; import { overviewCopy, useOverviewCopy, type OverviewCopy } from "../../features/overview/i18n"; +import { + invalidateHooksQueries, + hooksRoutes, + useHooksInventoryQuery, + type HookInventoryDto, +} from "../../features/hooks/public"; +import { + invalidatePermissionsQueries, + permissionsRoutes, + usePermissionsInventoryQuery, + type PermissionInventoryDto, +} from "../../features/permissions/public"; export interface OverviewStatMetric { value: number | null; @@ -47,9 +65,9 @@ export interface OverviewExtensionFact { } export interface OverviewExtensionKind { - key: "skills" | "slash-commands" | "mcp"; + key: "skills" | "slash-commands" | "mcp" | "hooks" | "permissions" | "agents"; label: string; - iconKey: "skills" | "slash-commands" | "mcp"; + iconKey: "skills" | "slash-commands" | "mcp" | "agents"; facts: OverviewExtensionFact[]; actions: OverviewExtensionAction[]; } @@ -104,12 +122,25 @@ export function useOverviewData() { const skillsQuery = useSkillsListQuery(); const slashCommandsQuery = useSlashCommandsQuery(); const mcpQuery = useMcpInventoryQuery(); - const model = useOverviewModel(skillsQuery.data, slashCommandsQuery.data, mcpQuery.data); + const hooksQuery = useHooksInventoryQuery(); + const permissionsQuery = usePermissionsInventoryQuery(); + const agentsQuery = useAgentsInventoryQuery(); + const model = useOverviewModel( + skillsQuery.data, + slashCommandsQuery.data, + mcpQuery.data, + hooksQuery.data, + permissionsQuery.data, + agentsQuery.data, + ); return { skillsQuery, slashCommandsQuery, mcpQuery, + hooksQuery, + permissionsQuery, + agentsQuery, model, }; } @@ -119,6 +150,9 @@ export async function invalidateOverviewData(queryClient: QueryClient): Promise< invalidateSkillsQueries(queryClient), invalidateSlashCommandQueries(queryClient), invalidateMcpQueries(queryClient), + invalidateHooksQueries(queryClient), + invalidatePermissionsQueries(queryClient), + invalidateAgentsQueries(queryClient), ]); } @@ -130,31 +164,44 @@ export function useOverviewModel( skills: SkillsWorkspaceData | null | undefined, slashCommands: SlashCommandListDto | null | undefined, mcp: McpInventoryDto | null | undefined, + hooks: HookInventoryDto | null | undefined, + permissions: PermissionInventoryDto | null | undefined, + agents: AgentInventoryDto | null | undefined, ): OverviewModel { const copy = useOverviewCopy(); - return useMemo(() => buildOverviewModel(skills, slashCommands, mcp, copy), [skills, slashCommands, mcp, copy]); + return useMemo( + () => buildOverviewModel(skills, slashCommands, mcp, hooks, permissions, agents, copy), + [skills, slashCommands, mcp, hooks, permissions, agents, copy], + ); } export function buildOverviewModel( skills: SkillsWorkspaceData | null | undefined, slashCommands: SlashCommandListDto | null | undefined, mcp: McpInventoryDto | null | undefined, + hooks: HookInventoryDto | null | undefined, + permissions: PermissionInventoryDto | null | undefined, + agents: AgentInventoryDto | null | undefined, copy: OverviewCopy = overviewCopy.en, ): OverviewModel { const inUseSkills = skills?.summary.managed ?? null; const skillsToReview = skills?.summary.unmanaged ?? null; const inUseSlashCommands = slashCommands?.commands?.length ?? null; const slashCommandsToReview = slashCommands?.reviewCommands?.length ?? null; - const inUseMcpServers = mcp?.entries.filter((entry) => entry.kind === "managed").length ?? null; - const mcpConfigsToReview = mcp?.entries.filter((entry) => entry.kind === "unmanaged").length ?? null; + const inUseMcpServers = mcp?.entries?.filter((entry) => entry.kind === "managed").length ?? null; + const mcpConfigsToReview = mcp?.entries?.filter((entry) => entry.kind === "unmanaged").length ?? null; + const inUseHooks = hooks?.entries?.filter((entry) => entry.kind === "managed").length ?? null; + const inUsePermissions = permissions?.entries?.filter((entry) => entry.kind === "managed").length ?? null; + const inUseAgents = agents?.entries?.filter((entry) => entry.kind === "managed").length ?? null; + const agentsToReview = agents?.entries?.filter((entry) => entry.kind === "unmanaged").length ?? null; const differentConfigMcpServers = - mcp?.entries.filter( + mcp?.entries?.filter( (entry) => entry.kind === "managed" && entry.sightings.some((sighting) => sighting.state === "drifted"), ).length ?? null; const inventoryIssues = mcp?.issues?.length ?? null; - const unavailableHarnesses = mcp?.columns.filter((column) => column.mcpWritable === false).length ?? null; + const unavailableHarnesses = mcp?.columns?.filter((column) => column.mcpWritable === false).length ?? null; const reviewItems = buildReviewItems({ skillsToReview, slashCommandsToReview, @@ -165,13 +212,16 @@ export function buildOverviewModel( copy, }); const harnessRows = buildHarnessRows(skills, mcp); - const hasOverviewData = Boolean(skills || slashCommands || mcp); + const hasOverviewData = Boolean(skills || slashCommands || mcp || hooks || permissions || agents); return { stats: buildStats({ inUseSkills, inUseSlashCommands, inUseMcpServers, + inUseHooks, + inUsePermissions, + inUseAgents, needsReview: hasOverviewData ? reviewItems.reduce((total, item) => total + item.count, 0) : null, harnesses: hasOverviewData ? harnessRows.length : null, copy, @@ -186,6 +236,10 @@ export function buildOverviewModel( differentConfigMcpServers, inventoryIssues, unavailableHarnesses, + inUseHooks, + inUsePermissions, + inUseAgents, + agentsToReview, copy, }), marketplaceEntries: buildMarketplaceEntries(copy), @@ -198,6 +252,9 @@ function buildStats({ inUseSkills, inUseSlashCommands, inUseMcpServers, + inUseHooks, + inUsePermissions, + inUseAgents, needsReview, harnesses, copy, @@ -205,13 +262,16 @@ function buildStats({ inUseSkills: number | null; inUseSlashCommands: number | null; inUseMcpServers: number | null; + inUseHooks: number | null; + inUsePermissions: number | null; + inUseAgents: number | null; needsReview: number | null; harnesses: number | null; copy: OverviewCopy; }): OverviewStats { return { inUse: { - value: sumKnown(inUseSkills, inUseSlashCommands, inUseMcpServers), + value: sumKnown(inUseSkills, inUseSlashCommands, inUseMcpServers, inUseHooks, inUsePermissions, inUseAgents), detail: copy.stats.inUseDetail(inUseSkills, inUseSlashCommands, inUseMcpServers), }, needsReview: { @@ -243,6 +303,10 @@ function buildExtensions({ differentConfigMcpServers, inventoryIssues, unavailableHarnesses, + inUseHooks, + inUsePermissions, + inUseAgents, + agentsToReview, copy, }: { inUseSkills: number | null; @@ -254,6 +318,10 @@ function buildExtensions({ differentConfigMcpServers: number | null; inventoryIssues: number | null; unavailableHarnesses: number | null; + inUseHooks: number | null; + inUsePermissions: number | null; + inUseAgents: number | null; + agentsToReview: number | null; copy: OverviewCopy; }): OverviewExtensionKind[] { return [ @@ -305,6 +373,41 @@ function buildExtensions({ { label: copy.stats.needsReview, to: mcpRoutes.needsReview }, ], }, + { + key: "hooks", + label: "Hooks", + iconKey: "mcp", + facts: [ + { label: copy.extensions.inUseFact, value: inUseHooks }, + ], + actions: [ + { label: copy.stats.inUse, to: hooksRoutes.inUse, primary: true }, + ], + }, + { + key: "permissions", + label: "Permissions", + iconKey: "skills", + facts: [ + { label: copy.extensions.inUseFact, value: inUsePermissions }, + ], + actions: [ + { label: copy.stats.inUse, to: permissionsRoutes.inUse, primary: true }, + ], + }, + { + key: "agents", + label: "Agents", + iconKey: "agents", + facts: [ + { label: copy.extensions.inUseFact, value: inUseAgents }, + { label: copy.extensions.reviewFact, value: agentsToReview, tone: "warning" }, + ], + actions: [ + { label: copy.stats.inUse, to: agentsRoutes.inUse, primary: true }, + { label: copy.stats.needsReview, to: agentsRoutes.needsReview }, + ], + }, ]; } diff --git a/frontend/src/app/capability-registry/sidebar.ts b/frontend/src/app/capability-registry/sidebar.ts index f92baabb..17ebc24d 100644 --- a/frontend/src/app/capability-registry/sidebar.ts +++ b/frontend/src/app/capability-registry/sidebar.ts @@ -1,13 +1,15 @@ import { useMemo } from "react"; import { mcpRoutes, useMcpInventoryQuery } from "../../features/mcp/public"; -import { useSkillsCopy } from "../../features/skills/i18n"; import { skillsRoutes, useSkillsListQuery } from "../../features/skills/public"; import { slashCommandRoutes, useSlashCommandsQuery } from "../../features/slash-commands/public"; import { marketplaceRoutes } from "../../features/marketplace/public"; +import { hooksRoutes, useHooksInventoryQuery } from "../../features/hooks/public"; +import { permissionsRoutes, usePermissionsInventoryQuery } from "../../features/permissions/public"; +import { agentsRoutes, useAgentsInventoryQuery } from "../../features/agents/public"; import { useCommonCopy } from "../../i18n"; -export type SidebarIconKey = "overview" | "skills" | "slash-commands" | "mcp" | "marketplace"; +export type SidebarIconKey = "overview" | "skills" | "slash-commands" | "mcp" | "marketplace" | "hooks" | "permissions" | "agents"; export interface SidebarLinkModel { key: string; @@ -16,6 +18,10 @@ export interface SidebarLinkModel { count?: number | null; } +export interface SidebarTopLinkModel extends SidebarLinkModel { + iconKey: SidebarIconKey; +} + export interface SidebarGroupModel { key: string; label: string; @@ -25,7 +31,7 @@ export interface SidebarGroupModel { } export interface SidebarModel { - topLinks: SidebarLinkModel[]; + topLinks: SidebarTopLinkModel[]; groups: SidebarGroupModel[]; } @@ -34,13 +40,18 @@ export function useSidebarModel(): SidebarModel { const mcpQuery = useMcpInventoryQuery(); const slashCommandsQuery = useSlashCommandsQuery(); const common = useCommonCopy(); - const skillsCopy = useSkillsCopy(); const inUseSkills = skillsQuery.data?.summary.managed ?? null; const needsReviewSkills = skillsQuery.data?.summary.unmanaged ?? null; const slashCommandCount = slashCommandsQuery.data?.commands.length ?? null; const slashCommandReviewCount = slashCommandsQuery.data?.reviewCommands.length ?? null; const mcpCounts = mcpSidebarCounts(mcpQuery.data); + const hooksQuery = useHooksInventoryQuery(); + const hooksCounts = hooksSidebarCounts(hooksQuery.data); + const permissionsQuery = usePermissionsInventoryQuery(); + const permissionsCounts = permissionsSidebarCounts(permissionsQuery.data); + const agentsQuery = useAgentsInventoryQuery(); + const agentsCounts = agentsSidebarCounts(agentsQuery.data); return useMemo( () => ({ @@ -49,9 +60,26 @@ export function useSidebarModel(): SidebarModel { key: "overview", to: "/overview", label: common.nav.overview, + iconKey: "overview", }, + ], groups: [ + { + key: "agents", + label: "Agents", + iconKey: "agents", + count: agentsCounts.total, + links: [ + { key: "agents-use", to: agentsRoutes.inUse, label: common.productLanguage.inUse, count: agentsCounts.inUse }, + { + key: "agents-review", + to: agentsRoutes.needsReview, + label: common.productLanguage.needsReview, + count: agentsCounts.needsReview, + }, + ], + }, { key: "skills", label: common.nav.skills, @@ -65,7 +93,6 @@ export function useSidebarModel(): SidebarModel { label: common.productLanguage.needsReview, count: needsReviewSkills, }, - { key: "skills-scan-config", to: skillsRoutes.scanConfig, label: skillsCopy.scan.configNav }, ], }, { @@ -103,6 +130,36 @@ export function useSidebarModel(): SidebarModel { }, ], }, + { + key: "hooks", + label: "Hooks", + iconKey: "hooks", + count: hooksCounts.total, + links: [ + { key: "hooks-use", to: hooksRoutes.inUse, label: common.productLanguage.inUse, count: hooksCounts.inUse }, + { + key: "hooks-review", + to: hooksRoutes.needsReview, + label: common.productLanguage.needsReview, + count: hooksCounts.needsReview, + }, + ], + }, + { + key: "permissions", + label: common.nav.permissions || "Permissions", + iconKey: "permissions", + count: permissionsCounts.total, + links: [ + { key: "permissions-use", to: permissionsRoutes.inUse, label: common.productLanguage.inUse, count: permissionsCounts.inUse }, + { + key: "permissions-review", + to: permissionsRoutes.needsReview, + label: common.productLanguage.needsReview, + count: permissionsCounts.needsReview, + }, + ], + }, { key: "marketplace", label: common.nav.marketplace, @@ -120,11 +177,19 @@ export function useSidebarModel(): SidebarModel { mcpCounts.inUse, mcpCounts.needsReview, mcpCounts.total, + hooksCounts.inUse, + hooksCounts.needsReview, + hooksCounts.total, + permissionsCounts.inUse, + permissionsCounts.needsReview, + permissionsCounts.total, + agentsCounts.inUse, + agentsCounts.needsReview, + agentsCounts.total, needsReviewSkills, slashCommandCount, slashCommandReviewCount, common, - skillsCopy, ], ); } @@ -145,7 +210,58 @@ function mcpSidebarCounts(inventory: ReturnType["da needsReview: number | null; total: number | null; } { - if (!inventory) { + if (!inventory || !inventory.entries) { + return { inUse: null, needsReview: null, total: null }; + } + const inUse = inventory.entries.filter((entry) => entry.kind === "managed").length; + const needsReview = inventory.entries.filter((entry) => entry.kind === "unmanaged").length; + return { + inUse, + needsReview, + total: sumLoadedCounts(inUse, needsReview), + }; +} + +function hooksSidebarCounts(inventory: ReturnType["data"]): { + inUse: number | null; + needsReview: number | null; + total: number | null; +} { + if (!inventory || !inventory.entries) { + return { inUse: null, needsReview: null, total: null }; + } + const inUse = inventory.entries.filter((entry) => entry.kind === "managed").length; + const needsReview = inventory.entries.filter((entry) => entry.kind === "unmanaged").length; + return { + inUse, + needsReview, + total: sumLoadedCounts(inUse, needsReview), + }; +} + +function permissionsSidebarCounts(inventory: ReturnType["data"]): { + inUse: number | null; + needsReview: number | null; + total: number | null; +} { + if (!inventory || !inventory.entries) { + return { inUse: null, needsReview: null, total: null }; + } + const inUse = inventory.entries.filter((entry) => entry.kind === "managed").length; + const needsReview = inventory.entries.filter((entry) => entry.kind === "unmanaged").length; + return { + inUse, + needsReview, + total: sumLoadedCounts(inUse, needsReview), + }; +} + +function agentsSidebarCounts(inventory: ReturnType["data"]): { + inUse: number | null; + needsReview: number | null; + total: number | null; +} { + if (!inventory || !inventory.entries) { return { inUse: null, needsReview: null, total: null }; } const inUse = inventory.entries.filter((entry) => entry.kind === "managed").length; diff --git a/frontend/src/assets/harness-logos/agy-logo.svg b/frontend/src/assets/harness-logos/agy-logo.svg new file mode 100644 index 00000000..fe5fd4c3 --- /dev/null +++ b/frontend/src/assets/harness-logos/agy-logo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/frontend/src/assets/harness-logos/hermes-logo.png b/frontend/src/assets/harness-logos/hermes-logo.png deleted file mode 100644 index 2d629d2f..00000000 Binary files a/frontend/src/assets/harness-logos/hermes-logo.png and /dev/null differ diff --git a/frontend/src/assets/harness-logos/hermes-logo.svg b/frontend/src/assets/harness-logos/hermes-logo.svg new file mode 100644 index 00000000..85534203 --- /dev/null +++ b/frontend/src/assets/harness-logos/hermes-logo.svg @@ -0,0 +1 @@ +Hermes Agent \ No newline at end of file diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 051b1b3f..fbee7ded 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -15,11 +15,14 @@ import { Command, Languages, LayoutDashboard, + Moon, RefreshCw, Settings, Store, SunMedium, Terminal, + Webhook, + Bot, } from "lucide-react"; import { Link, NavLink, useLocation } from "react-router-dom"; @@ -27,6 +30,7 @@ import { useSidebarModel, type SidebarIconKey } from "../app/capability-registry import { LoadingSpinner } from "./LoadingSpinner"; import { useToast } from "./Toast"; import { useCommonCopy, useLocale } from "../i18n"; +import { useTheme } from "../lib/theme"; interface SidebarProps { onRefresh: () => void | Promise; @@ -37,6 +41,7 @@ export function Sidebar({ onRefresh, refreshPending }: SidebarProps) { const model = useSidebarModel(); const { toast } = useToast(); const common = useCommonCopy(); + const { theme, toggleTheme } = useTheme(); return (