Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

## Unreleased

Catalog update for AI LABS 8-repo wave adaptation and hygiene patch. Totals become **63** (47 model-invoked, 16 manual slash commands).
Catalog update for AI LABS 8-repo wave adaptation, hygiene patch, and MarkItDown ingest. Totals become **64** (48 model-invoked, 16 manual slash commands).

- Add model-invoked specialist `markitdown` as a Markdown ingest converter (Office/PDF/HTML/CSV/XLSX/PPTX/EPUB/ZIP). Optional MCP `opencode-bf markitdown enable` registers local stdio (`uvx --from markitdown-mcp markitdown-mcp`). `FOREIGN_ON_DEMAND`. SmartDoc keeps contract/QA/render. No npm plugin, no Azure keys, no docker bind-all.
- Add first-party model-invoked specialist `img2threejs` for code-only procedural Three.js TypeScript model reconstruction from reference object images (editable Group factory, visible vs. inferred geometry spec, screenshot loop gate; no mesh blob downloads).
- Add optional `reticle` MCP (`opencode-bf reticle enable` / `disable`) registering local perception server (`npx -y @reticlehq/server mcp`). `FOREIGN_ON_DEMAND`, server is FSL-1.1-ALv2, perception only, never an auto-implementer; default verification remains `playwright-qa` / `chrome-devtools-axi`.
- Add optional `ui-skills` remote MCP (`opencode-bf ui-skills enable` / `disable`) registering `https://www.ui-skills.com/mcp` for design-skill lookup only. Product UI remains Design Bank + Impeccable + Design V2 atoms + shadcn; `BANK_MISS` never generates from random ui-skills documents.
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# OpenCodeBestFriend

Production-ready capability layer for OpenCode:
63 routed skills (core + Wave 2/3 warehouse specialists), MCP, Codebase Memory,
64 routed skills (core + Wave 2/3 warehouse specialists), MCP, Codebase Memory,
Design Bank, Design Intelligence, SmartDoc, browser and verification tooling.

OpenCodeBestFriend is an installer and runtime overlay for [OpenCode](https://opencode.ai). It is **not** Claude Code, **not** a model provider, and **not** a dump of a developer home directory.

## What it is

- 63 skills: 47 model-invoked, 16 manual slash commands
- 64 skills: 48 model-invoked, 16 manual slash commands
- A thin `AGENTS.md` router (lazy, one primary specialist)
- Core MCP: Codebase Memory, Context7, shadcn
- Design Bank discovery or download (media is **not** in git)
Expand Down Expand Up @@ -61,7 +61,7 @@ Restart OpenCode after install. Config is not hot-reloaded.
┌───────────────────┼────────────────────┐
▼ ▼ ▼
Skills MCP Rules
47 automatic Codebase Memory Verification
48 automatic Codebase Memory Verification
16 manual Context7 Engineering
shadcn
Expand Down Expand Up @@ -100,6 +100,7 @@ Default: repository evidence first. Then at most one specialist.
| Procedural Three.js object from image | `img2threejs` |
| Deterministic HTML composition video | `hyperframes` |
| Documents (PDF/DOCX/answer/extract/review) | `smartdoc` |
| File to Markdown ingest | `markitdown` |
| Reusable book/module knowledge | `smartbook-ingest` |
| Scholarly literature & manuscripts | `academic` |
| Prose AI-tell removal & humanizing | `humanizer` (`/unslop`) |
Expand Down Expand Up @@ -129,6 +130,7 @@ Optional:
- `stitch` — `opencode-bf stitch enable` registers Google Stitch as a remote comp/mock source. Not an owned core server and not a production UI implementer: hand screens to `found-this-design` or `impeccable` before shipping. Keys are never written into config, only referenced as `{env:STITCH_API_KEY}`, or omitted with `--oauth`. `opencode-bf stitch disable` removes only that server key. Absent is not a `doctor` failure; a malformed entry fails closed.
- `reticle` — `opencode-bf reticle enable` registers Reticle as a local perception server (`npx -y @reticlehq/server mcp`). `FOREIGN_ON_DEMAND`. Server package is FSL-1.1-ALv2 (competing-use clause); SDK packages (Apache-2.0) are not vendored. Never an auto-implementer; default verification remains `playwright-qa` / `chrome-devtools-axi`. `opencode-bf reticle disable` removes only that server key. Absent is not a `doctor` failure; a malformed entry fails closed.
- `ui-skills` — `opencode-bf ui-skills enable` registers UI Skills (`https://www.ui-skills.com/mcp`) as an optional remote MCP server. `FOREIGN_ON_DEMAND` for design-skill lookup only. Product UI remains Design Bank + Impeccable + Design V2 atoms + shadcn; `BANK_MISS` never generates from a random ui-skills document. `opencode-bf ui-skills disable` removes only that server key. Absent is not a `doctor` failure; a malformed entry fails closed.
- `markitdown` — `opencode-bf markitdown enable` registers MarkItDown as a local stdio ingest converter (`uvx --from markitdown-mcp markitdown-mcp`). `FOREIGN_ON_DEMAND`. Local trusted agents only; never `--http` / `0.0.0.0` / docker bind-all. Output is Markdown data; SmartDoc keeps contract/QA/render. `opencode-bf markitdown disable` removes only that server key. Absent is not a `doctor` failure; a malformed entry fails closed.
- `exa` — `FOREIGN_ON_DEMAND`; installer never adds, removes, or overwrites it

NVIDIA SkillEvaluator is `FOREIGN_ON_DEMAND` in the same sense: a maintainer may run it externally for embedding-based overlap scoring or live catalog evaluation. Caliper is `FOREIGN_ON_DEMAND` similarly: a maintainer may `pipx install caliper-eval` off-tree for prompt/agent benchmark evaluation. Neither is vendored into `lib/`, the installer never adds them, `doctor` does not fail when they are absent, and a malformed MCP entry fails closed like any other schema violation.
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
┌───────────────────┼────────────────────┐
▼ ▼ ▼
Skills MCP Rules
47 automatic Codebase Memory Verification
48 automatic Codebase Memory Verification
16 manual Context7 Engineering
shadcn
Expand Down
3 changes: 3 additions & 0 deletions docs/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Optional:
- `stitch` — `opencode-bf stitch enable` (remote comp/mock source only; auth via `{env:STITCH_API_KEY}` or `--oauth`)
- `reticle` — `opencode-bf reticle enable` (local stdio via `npx -y @reticlehq/server mcp`; perception only, never auto-implementer)
- `ui-skills` — `opencode-bf ui-skills enable` (remote HTTP `https://www.ui-skills.com/mcp`; design-skill lookup only)
- `markitdown` — `opencode-bf markitdown enable` (local stdio via `uvx --from markitdown-mcp markitdown-mcp`; Markdown ingest only)
- `exa` — foreign; never add/remove/overwrite

Merge is parse-aware. Comment-free JSON is rewritten with `json.dumps`. JSONC with comments is patched surgically (owned MCP keys only). If surgical merge cannot be verified, install fails closed instead of destroying comments.
Expand All @@ -29,3 +30,5 @@ Doctor reports `CONFIGURED` for owned MCP entries present in config. That is not
`opencode-bf reticle enable` configures Reticle as an optional local perception MCP server (`npx -y @reticlehq/server mcp`). It is `FOREIGN_ON_DEMAND`. The server package is FSL-1.1-ALv2 (competing-use clause); SDK packages (Apache-2.0) are not vendored. Reticle is never an auto-implementer; after a feature is done, default verification remains `playwright-qa` or `chrome-devtools-axi`. Reticle is extra perception if the user enabled it. `opencode-bf reticle disable` surgically removes only the reticle server key. Absent is not a doctor failure; a malformed entry fails closed.

`opencode-bf ui-skills enable` configures UI Skills as an optional remote MCP server (`https://www.ui-skills.com/mcp`). It is `FOREIGN_ON_DEMAND` for design-skill lookup only (`list_skills`, `get_skill`). Product UI remains Design Bank + Impeccable + Design V2 atoms + shadcn; `BANK_MISS` never generates from a random ui-skills document. `opencode-bf ui-skills disable` surgically removes only the ui-skills server key. Absent is not a doctor failure; a malformed entry fails closed.

`opencode-bf markitdown enable` configures MarkItDown as an optional local stdio ingest MCP (`uvx --from markitdown-mcp markitdown-mcp`). It is `FOREIGN_ON_DEMAND`. Official server is for local trusted agents only; never `--http`, never bind `0.0.0.0`, never docker bind-all. The converter is not vendored into `lib/`. Missing `uvx` is documented in the skill (CLI/`pipx`/`enable`); enable still writes the stdio command like reticle. `opencode-bf markitdown disable` surgically removes only the markitdown server key. Absent is not a doctor failure; a malformed entry (including `--http` / `0.0.0.0`) fails closed.
2 changes: 1 addition & 1 deletion docs/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ UI direction from the bank routes to `found-this-design` first, which stops befo

Browser verification follows four explicit doors: exploratory application UI routes to `playwright-qa`, persistent multi-account sessions route to `browser-act`, observed Chromium cause routes to `chrome-devtools-axi`, and button handler sequential undo / shared-store side effects route to `click-path-audit`.

Documents (answer, create, transform, extract, review, PDF/DOCX) route to `smartdoc`. Reusable book/module knowledge routes to `smartbook-ingest`. `/docx` and `/pdf` are missing aliases; nearest is `smartdoc`. `/pptx` is NOT_APPLICABLE. Do not add `commands/pdf.md` or `commands/docx.md`. Impeccable `document` remains DESIGN.md generation.
Documents (answer, create, transform, extract, review, PDF/DOCX) route to `smartdoc`. File-to-Markdown ingest routes to `markitdown`. Reusable book/module knowledge routes to `smartbook-ingest`. `/docx` and `/pdf` are missing aliases; nearest is `smartdoc`. `/pptx` is NOT_APPLICABLE. Do not add `commands/pdf.md` or `commands/docx.md`. Impeccable `document` remains DESIGN.md generation.

Prose AI-tell removal and natural tone polishing route to `humanizer` (`/unslop` is its manual alias). Scholarly research, academic manuscripts, and structured peer critique route to `academic`. Deterministic HTML composition rendered to video routes to `hyperframes`. Editorial technical diagrams (HTML/SVG) route to `diagram-design`.

Expand Down
4 changes: 2 additions & 2 deletions docs/skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

Policy: `vendor/skill-policy.json` plus `vendor/skill-allowlist.txt`.

- 47 model-invoked skills live under `skills/` and install to `~/.config/opencode/skills/` (core + Wave 2/3 warehouse specialists)
- 48 model-invoked skills live under `skills/` and install to `~/.config/opencode/skills/` (core + Wave 2/3 warehouse specialists)
- 16 manual skills live under `manual-skills/` and install to `~/.config/opencode/bestfriend/skills/` plus `commands/`

`smartdoc` is per-job document intelligence. `smartbook-ingest` compiles reusable local knowledge. `humanizer` cleans user-facing prose tells (`/unslop` is its manual alias). `academic` manages scholarly research, writing, and peer review. `hyperframes` handles deterministic HTML-to-MP4 video composition. `diagram-design` crafts editorial HTML/SVG diagrams. `img2threejs` reconstructs procedural Three.js models from reference images. Warehouse diagnostics include `agent-architecture-audit` (agent stack layers), `cost-aware-llm-pipeline` (token budgeting), `eval-harness` (benchmarks), `prompt-optimizer` (prompt refinement), and `skill-stocktake` (catalog hygiene). Wave 3 adds `api-design`, `contract-first`, `automation-audit-ops`, `code-tour`, and `click-path-audit`. Handwriting is a SmartDoc renderer, not a skill.
`smartdoc` is per-job document intelligence. `markitdown` converts Office/PDF/HTML/CSV/XLSX/PPTX/EPUB/ZIP to Markdown for ingest; SmartDoc keeps contract/QA/render. `smartbook-ingest` compiles reusable local knowledge. `humanizer` cleans user-facing prose tells (`/unslop` is its manual alias). `academic` manages scholarly research, writing, and peer review. `hyperframes` handles deterministic HTML-to-MP4 video composition. `diagram-design` crafts editorial HTML/SVG diagrams. `img2threejs` reconstructs procedural Three.js models from reference images. Warehouse diagnostics include `agent-architecture-audit` (agent stack layers), `cost-aware-llm-pipeline` (token budgeting), `eval-harness` (benchmarks), `prompt-optimizer` (prompt refinement), and `skill-stocktake` (catalog hygiene). Wave 3 adds `api-design`, `contract-first`, `automation-audit-ops`, `code-tour`, and `click-path-audit`. Handwriting is a SmartDoc renderer, not a skill.

OpenCode 1.18.x has no `disable-model-invocation` field. Manual skills must not be copied into the discovered skills directory.

Expand Down
16 changes: 16 additions & 0 deletions docs/warehouse-inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,3 +367,19 @@ Evaluation and disposition contract for the AI LABS 8-repo wave (procedural 3D,
| `swiftui-skills` | **DEFER** | `-` | Apple platform / Xcode 26 ecosystem deferred. Target platform gate remains Linux x86_64 and OpenCode 1.18.x. |
| `caliper` | **FOREIGN_ON_DEMAND** | `-` | Benchmark CLI runner (`caliper-eval`). Maintainer may run off-tree via pipx; zero `lib/` vendor coupling. |
| `anti-slop` | **MERGE** | `install-anti-slop`, `impeccable`, `rules/03-prose-discipline.md` | Anti-pattern guardrails merged into existing taste, prose, and linting references; zero extra catalog skills. |

---

## Wave MarkItDown

Microsoft MarkItDown as an ingest converter, not a second document OS. SmartDoc keeps contract/QA/render.

| Candidate / Repo | Decision | BestFriend Target | Reason |
| :--- | :---: | :--- | :--- |
| `microsoft/markitdown` CLI/lib | **NEW** | `skills/markitdown` | Thin first-party skill: convert Office/PDF/HTML/CSV/XLSX/PPTX/EPUB/ZIP to Markdown, then hand off. |
| `markitdown-mcp` official | **FOREIGN_ON_DEMAND** | `mcp.markitdown` | Optional local stdio (`uvx --from markitdown-mcp markitdown-mcp`). Local trusted agents only. |
| `opencode-markitdown` npm plugin | **REJECT** | `-` | Config-hook mutation forbidden. |
| community `trsdn-markitdown-mcp` | **REJECT** | `-` | Not Microsoft. |
| Azure Document Intelligence / Content Understanding | **DEFER** | `-` | No keys in config. |
| youtube / audio extras | **DEFER** | `-` | Out of document lane. |
| Duplicate SmartDoc modes | **REJECT** | `-` | SmartDoc keeps contract/QA/render. |
9 changes: 9 additions & 0 deletions lib/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
cmd_install,
cmd_restore,
cmd_restore_list,
cmd_markitdown_disable,
cmd_markitdown_enable,
cmd_reticle_disable,
cmd_reticle_enable,
cmd_serena_enable,
Expand Down Expand Up @@ -111,6 +113,9 @@ def build_parser() -> argparse.ArgumentParser:
ret = sub.add_parser("reticle", help="optional Reticle local perception MCP")
ret.add_argument("action", choices=["enable", "disable"])

md = sub.add_parser("markitdown", help="optional MarkItDown local ingest MCP")
md.add_argument("action", choices=["enable", "disable"])

uis = sub.add_parser("ui-skills", help="optional UI Skills remote MCP")
uis.add_argument("action", choices=["enable", "disable"])

Expand Down Expand Up @@ -177,6 +182,10 @@ def main(argv: list[str] | None = None) -> int:
if args.action == "enable":
return cmd_reticle_enable()
return cmd_reticle_disable()
if cmd == "markitdown":
if args.action == "enable":
return cmd_markitdown_enable()
return cmd_markitdown_disable()
if cmd == "ui-skills":
if args.action == "enable":
return cmd_ui_skills_enable()
Expand Down
21 changes: 18 additions & 3 deletions lib/doctor.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ def mcp_status_map() -> dict[str, str]:
try:
data = jsonc.load_path(cfg)
except (OSError, json.JSONDecodeError, ValueError):
return {k: "FAIL" for k in ("codebase-memory-mcp", "context7", "shadcn", "serena", "stitch", "reticle", "ui-skills", "exa")}
return {k: "FAIL" for k in ("codebase-memory-mcp", "context7", "shadcn", "serena", "stitch", "reticle", "ui-skills", "markitdown", "exa")}
mcp = data.get("mcp") or {}
owned = {"codebase-memory-mcp", "context7", "shadcn"}
optional = {"serena", "stitch", "reticle", "ui-skills", "exa"}
for name in ("codebase-memory-mcp", "context7", "shadcn", "serena", "stitch", "reticle", "ui-skills", "exa"):
optional = {"serena", "stitch", "reticle", "ui-skills", "markitdown", "exa"}
for name in ("codebase-memory-mcp", "context7", "shadcn", "serena", "stitch", "reticle", "ui-skills", "markitdown", "exa"):
spec = mcp.get(name)
if spec is None:
out[name] = "OPTIONAL_ABSENT" if name in optional else "FAIL"
Expand Down Expand Up @@ -165,6 +165,21 @@ def mcp_status_map() -> dict[str, str]:
continue
out[name] = "CONFIGURED"
continue
if name == "markitdown":
typ = spec.get("type")
cmd = spec.get("command")
if typ != "local" or not isinstance(cmd, list) or not cmd:
out[name] = "FAIL"
continue
joined = " ".join(str(part) for part in cmd)
if "--http" in joined or "0.0.0.0" in joined:
out[name] = "FAIL"
continue
if cmd[0] != "uvx" or "markitdown-mcp" not in cmd:
out[name] = "FAIL"
continue
out[name] = "CONFIGURED"
continue
if name not in owned:
out[name] = "FOREIGN"
continue
Expand Down
15 changes: 14 additions & 1 deletion lib/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ def take(src: Path, dest: Path) -> None:
"modelInvokedSkills": meta["model"],
"manualSkills": meta["manual"],
"ownedMcp": list(OWNED_MCP),
"optionalMcp": ["serena", "stitch", "reticle", "ui-skills", "exa"],
"optionalMcp": ["serena", "stitch", "reticle", "ui-skills", "markitdown", "exa"],
"designBank": {
"root": bank_root,
"source": bank_source,
Expand Down Expand Up @@ -1402,6 +1402,19 @@ def cmd_reticle_disable() -> int:
return _optional_mcp_disable("reticle")


def cmd_markitdown_enable() -> int:
spec: dict[str, object] = {
"type": "local",
"command": ["uvx", "--from", "markitdown-mcp", "markitdown-mcp"],
"enabled": True,
}
return _optional_mcp_enable("markitdown", spec)


def cmd_markitdown_disable() -> int:
return _optional_mcp_disable("markitdown")


def cmd_ui_skills_enable() -> int:
spec: dict[str, object] = {
"type": "remote",
Expand Down
2 changes: 1 addition & 1 deletion rules/00-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Do not infer a model provider from a logical model name. Treat custom-gateway al
- Throwaway evidence for one design question: `/prototype`. Not for production UI; skip ordinary implementation, ADHD, and `/arena`.
- Unknown / hard bugs, regressions, measured slowdown: `/diagnosing-bugs`. Skip typos, known-cause, and test-first known fixes (`/tdd`).
- Authoring SKILL.md / AGENTS.md / skill descriptions / context pointers: `/writing-for-agents` (distinct from `/skill-stocktake` which audits catalog hygiene). Workflow choice stays `/ask-matt`.
- Documents (answer, create, transform, extract, review, PDF/DOCX): `/smartdoc`. Reusable book/module knowledge: `/smartbook-ingest`. SmartDoc may read an existing SmartBook; that is not a second implementation specialist. Impeccable `document` stays DESIGN.md.
- Documents (answer, create, transform, extract, review, PDF/DOCX): `/smartdoc`. File to Markdown ingest: `/markitdown`. Reusable book/module knowledge: `/smartbook-ingest`. SmartDoc may read an existing SmartBook; that is not a second implementation specialist. Impeccable `document` stays DESIGN.md.
- Prose AI-tell removal and natural tone polishing: `/humanizer`. Manual `/unslop` is an alias to the same specialist body. Do not auto-apply on ordinary code or diffs. Technical documentation structure stays `/technical-writing`. Code linting stays `/install-anti-slop`. Prompt structure stays `/prompt-optimizer`.
- Editorial HTML and inline SVG diagrams (architecture, sequence, ER, flowcharts, Wardley): `/diagram-design`. Mermaid/draw.io are inputs to redraw, not final output. Frontend UI implementation stays `/impeccable`. Code-level seams stay `/codebase-design`.
- Agent architecture diagnosis, autonomous loop failures, context leakage, wrapper regressions: `/agent-architecture-audit`. Load only when user names the agent stack job. Defensive security and secrets auditing stay `/full-audit-keamanan`.
Expand Down
Loading
Loading