diff --git a/CHANGELOG.md b/CHANGELOG.md index dec8175..297a46b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.1.4 — 2026-09-23 - Upgraded `codebase-memory-mcp` pin to v0.11.0 with SHA-256 verified portable tarball download, and added automatic `--format json` argument propagation in `lib/cbm.py` for reliable JSON extraction across project listing and status commands. - Bumped `shadcn` CLI MCP pin to `4.21.0` across `vendor/mcp-wanted.json`, `vendor/mcp-policy.json`, `lib/install.py`, `rules/00-routing.md`, and doctor tests. @@ -10,7 +10,9 @@ - Consolidated Emil Kowalski motion doctrines into `skills/emil-design-eng/references/`: created `motion.md` (decision framework, compositor-only properties, production recipes, exit choreography), `apple-principles.md` (WWDC 2018 fluid interfaces, physics-based springs, velocity handoff, momentum projection, materials, SF Pro optical sizing), and `native-motion.md` (eliminating mobile web browser tells, 100dvh, safe area insets, touch-action, overscroll containment, and Expo / React Native Reanimated 3 worklets). Maintained zero new skill names, preserving catalog freeze at 62. - Refreshed upstream pins in `vendor/sources.json` for `pbakaus/impeccable` (tag `skill-v4.3.1` `cd12f8660e2d` / verified main `e0881d2de397`), `emilkowalski/skills` (`85e8e2363b71`), `microsoft/markitdown` (v0.1.8 `b8f79c57`, PIN_ONLY), and `kunchenguid/axi` (`85a8723276ca`, PIN_ONLY). - Updated `docs/source-wave.md`, `docs/mcp.md`, `README.md`, and `THIRD_PARTY_NOTICES.md` with complete attribution and license notices for merged doctrines. -- Recorded `CODEBASE_MEMORY_BINARY_CHECKSUM_FAILED` in `docs/troubleshooting.md` (delete download cache and `components/codebase-memory`, then reinstall; v0.11 index rebuilds once). Vendored `vendor/licenses/IMPECCABLE-APACHE2.txt` and `vendor/licenses/EMILKOWALSKI-MIT.txt` so `licenseFile` pins are not empty pointers. `scroll-world` and `browser-act` stay **UPDATE** (not body-refreshed in this wave). markitdown `uvx` invocation stays unpinned (`PIN_ONLY` follow-up). +- Recorded `CODEBASE_MEMORY_BINARY_CHECKSUM_FAILED` in `docs/troubleshooting.md` (delete download cache and `components/codebase-memory`, then reinstall; v0.11 index rebuilds once). Vendored `vendor/licenses/IMPECCABLE-APACHE2.txt` and `vendor/licenses/EMILKOWALSKI-MIT.txt` so `licenseFile` pins are not empty pointers. +- Pinned `opencode-he markitdown enable` to `uvx --from markitdown-mcp==0.1.8 markitdown-mcp`. Skill body stays PIN_ONLY. `scroll-world` and `browser-act` stay **UPDATE** (not body-refreshed). +- Synchronized release acceptance fixtures (`docs/acceptance.md`), catalog freeze metadata, compatibility targets, README front page, and vendor specifications to 0.1.4. Tag `v0.1.3` stays on the previous cut. ## 0.1.3 — 2026-09-23 diff --git a/README.md b/README.md index 36ddf6e..184c6e1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ OpenCode 2 overlay: 62 frozen routed skills, thin `AGENTS.md`, `opencode-he`. Installer and runtime overlay for [OpenCode 2](https://opencode.ai/v2/docs/). It is **not** Claude Code, **not** GrokBuild, **not** OpenCodeBestFriend runtime, **not** a model provider, and **not** a dump of a developer home directory. -Version **0.1.3**. The 62-skill catalog is inherited from OpenCodeBestFriend 1.8.6 (`67142e4` / PR #29) and stays frozen. This is a new product on a new host. +Version **0.1.4**. The 62-skill catalog is inherited from OpenCodeBestFriend 1.8.6 (`67142e4` / PR #29) and stays frozen. This is a new product on a new host. ## What it is @@ -16,6 +16,9 @@ Version **0.1.3**. The 62-skill catalog is inherited from OpenCodeBestFriend 1.8 - Explicit specialist handoff graph (`found-this-design` pin → `impeccable` → `playwright-qa` verify edge) - Evidence-blocked done-gate (`FACT:` / `JUDGMENT:`) via verification rules + `/decision-log` - UI polish checklists merged into `emil-design-eng` + practical a11y into `impeccable` (still 62 skills) +- Core MCP pins: Codebase Memory **0.11.0** (tarball and inner-binary SHA-256) and `shadcn@4.21.0` +- Email design is an Impeccable reference, not a new skill (raw HTML uses tables; React Email / MJML may use framework components) +- Emil motion doctrines live under `emil-design-eng` references (still 62 skills) - Design Intelligence (lazy, inside Impeccable) - `opencode-he doctor`, transactional install, uninstall, restore - Claude Code isolation: `OPENCODE_DISABLE_CLAUDE_CODE=1` @@ -164,7 +167,7 @@ Native OpenCode 2 shape (`mcp.servers`, every entry has `type`, `disabled` not V Core (installed): -- `codebase-memory-mcp` — downloaded, SHA-256 verified, Linux x86_64. If the binary will not run, doctor reports `DEGRADED`, never fake `CONNECTED`. +- `codebase-memory-mcp` — downloaded, SHA-256 verified (archive and extracted binary), Linux x86_64, pin **0.11.0**. If the binary will not run, doctor reports `DEGRADED`, never fake `CONNECTED`. A 0.9.0 install must delete the download cache and `components/codebase-memory`, then re-run `./install.sh` (index rebuilds once). - `context7` — `https://mcp.context7.com/mcp` (no secret stored) - `shadcn` — `npx -y shadcn@4.21.0 mcp` @@ -174,7 +177,7 @@ Optional: - `stitch` — `opencode-he 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-he stitch disable` removes only that server key. Absent is not a `doctor` failure; a malformed entry fails closed. - `reticle` — `opencode-he 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-he reticle disable` removes only that server key. Absent is not a `doctor` failure; a malformed entry fails closed. - `ui-skills` — `opencode-he 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-he ui-skills disable` removes only that server key. Absent is not a `doctor` failure; a malformed entry fails closed. -- `markitdown` — `opencode-he 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-he markitdown disable` removes only that server key. Absent is not a `doctor` failure; a malformed entry fails closed. +- `markitdown` — `opencode-he markitdown enable` registers MarkItDown as a local stdio ingest converter (`uvx --from markitdown-mcp==0.1.8 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-he markitdown disable` removes only that server key. Absent is not a `doctor` failure; a malformed entry fails closed. - `jev-mcp` — TypeSafe Jev / `jkudish/jev-mcp` is intentionally SKIPPED as a required runtime MCP; core verification and done-gates operate offline without external server dependencies. - `exa` — `FOREIGN_ON_DEMAND`; installer never adds, removes, or overwrites it diff --git a/VERSION b/VERSION index b1e80bb..845639e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.3 +0.1.4 diff --git a/docs/CATALOG-FREEZE.md b/docs/CATALOG-FREEZE.md index 4d9ad6d..951666d 100644 --- a/docs/CATALOG-FREEZE.md +++ b/docs/CATALOG-FREEZE.md @@ -2,7 +2,7 @@ This contract defines the immutable boundary and governance for the OpenCodeHighEnd catalog. The name set is inherited from OpenCodeBestFriend 1.8.6 (`67142e4` / PR #29) and stays frozen. -- **Product version**: 0.1.3 +- **Product version**: 0.1.4 - **Catalog**: 62 names. 47 model-invoked under `skills/`. 15 manual under `manual-skills/` + `commands/`. - **Retired in this wave and not to be revived**: `ask-matt`, `grilling`, `wait-what`, `matt-implement`. - **Kept on purpose**: `wizard` (target-app bash wizard), `codebase-design` (new module), `/improve-codebase-architecture` (scan + HTML report). diff --git a/docs/acceptance.md b/docs/acceptance.md index ac8284e..7477b17 100644 --- a/docs/acceptance.md +++ b/docs/acceptance.md @@ -5,11 +5,11 @@ `doctor --deep` = is live runtime proven? `doctor --strict` = treat DEGRADED/WARN as failure. -A successful 0.1.3 install should report approximately: +A successful 0.1.4 install should report approximately: ```text PASS INSTALLED_PRODUCT opencode-highend -PASS INSTALLED_VERSION 0.1.3 +PASS INSTALLED_VERSION 0.1.4 PASS SOURCE_REPOSITORY https://github.com/kuker24/OpenCodeHighEnd PASS OpenCode (major >= 2.x) diff --git a/docs/compatibility.md b/docs/compatibility.md index f43d4e3..7373164 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -1,6 +1,6 @@ # Compatibility -Official target for 0.1.3: +Official target for 0.1.4: - Linux x86_64 - OpenCode **2.x** (1.x fails closed) diff --git a/docs/mcp.md b/docs/mcp.md index 4bcd9e9..a8fb0b2 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -16,7 +16,7 @@ Optional: - `stitch` — `opencode-he stitch enable` (remote comp/mock source only; auth via `{env:STITCH_API_KEY}` or `--oauth`) - `reticle` — `opencode-he reticle enable` (local stdio via `npx -y @reticlehq/server mcp`; perception only, never auto-implementer) - `ui-skills` — `opencode-he ui-skills enable` (remote HTTP `https://www.ui-skills.com/mcp`; design-skill lookup only) -- `markitdown` — `opencode-he markitdown enable` (local stdio via `uvx --from markitdown-mcp markitdown-mcp`; Markdown ingest only) +- `markitdown` — `opencode-he markitdown enable` (local stdio via `uvx --from markitdown-mcp==0.1.8 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. @@ -31,7 +31,7 @@ Doctor reports `CONFIGURED` for owned MCP entries present in config. That is not `opencode-he 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-he ui-skills disable` surgically removes only the ui-skills server key. Absent is not a doctor failure; a malformed entry fails closed. -`opencode-he 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-he 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. +`opencode-he markitdown enable` configures MarkItDown as an optional local stdio ingest MCP (`uvx --from markitdown-mcp==0.1.8 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-he 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. ## Evaluated, Skipped & Rejected diff --git a/docs/source-wave.md b/docs/source-wave.md index d286b25..6370ee0 100644 --- a/docs/source-wave.md +++ b/docs/source-wave.md @@ -7,7 +7,7 @@ Recorded per Phase 0 contract. |---|---|---|:---:|---|---| | [miqdadbadjuber/anti-slop](https://github.com/miqdadbadjuber/anti-slop) | `743735248fbaefd76bb56619615687dfa8b3bc1e` (v3.2.9) | UI/copy filter (38 rules R-01–R-38), 3 tiers (Hard Gate, Purpose-Gate, Quality Locks), Delivery Gate checklist, Liveliness dials, during/after usage modes. MIT. | **MERGE** | `skills/impeccable` (taste-guard + direction), `skills/humanizer`, `rules/03-prose-discipline.md` | Filter, not a style guide. Do not vendor as 65th skill (`antislop` or `antislop-ui`). Distinct from Oxlint. | | [dmmulroy/anti-slop](https://github.com/dmmulroy/anti-slop) | `e8c4880471b23ab7f216fba7b27d173a6ef07d4c` (v0.1.2) | TypeScript/JavaScript Oxlint static linter ruleset. MIT. | **DONE** | `skills/install-anti-slop` | Already vendored and pinned. Strictly for static code linting on opt-in TS/JS projects. | -| [microsoft/markitdown](https://github.com/microsoft/markitdown) | `b8f79c57ebc0044be41323d89b2a45d3fda8460e` (v0.1.8) | File to Markdown converter (Office/PDF/HTML/CSV/XLSX/PPTX/EPUB/ZIP). MIT. | **PIN_ONLY** | `skills/markitdown` | Pinned to v0.1.8 (commit `b8f79c57`). CLI invocation unchanged; output remains data-only. SmartDoc keeps contract/QA/render. MCP remains FOREIGN_ON_DEMAND. | +| [microsoft/markitdown](https://github.com/microsoft/markitdown) | `b8f79c57ebc0044be41323d89b2a45d3fda8460e` (v0.1.8) | File to Markdown converter (Office/PDF/HTML/CSV/XLSX/PPTX/EPUB/ZIP). MIT. | **PIN_ONLY** | `skills/markitdown` | Pinned to v0.1.8 (commit `b8f79c57`). Skill body unchanged. Enable writes `uvx --from markitdown-mcp==0.1.8`. Output remains data-only. SmartDoc keeps contract/QA/render. MCP remains FOREIGN_ON_DEMAND. | | [affaan-m/ECC](https://github.com/affaan-m/ECC) | `dd6ee538aee0f548d4a6b520118f875431fd749e` | External agent control plane (68 agents, 292 skills, hooks, learning runtime). | **REJECT** | None (`FOREIGN_ON_DEMAND`) | Do not vendor harness control plane or 292 skills. No installer mutator. Doctor does not fail when absent. Individual warehouse ports remain first-party MIT. | | [Leonxlnx/taste-skill](https://github.com/Leonxlnx/taste-skill) | `e79ca9ec7e071eb3a3b623c4fb752e853fc3ed58` (`ccbc156` base) | Design taste dials (VARIANCE, MOTION, DENSITY), quality rules, GSAP/Tailwind references. MIT. | **MERGE** | `skills/impeccable/reference/taste/direction.md`, `taste-guard.md` | Dials already integrated into Impeccable surface brief. Fenced after Design Bank or DESIGN.md direction exists. Never a frontend-design twin. | | [ashemag/human-atlas](https://github.com/ashemag/human-atlas) | `1c38bf35c254a891200d3cedecfd57abebe83d8d` | 3D human anatomy application (Three.js/R3F + BodyParts3D dataset). CC BY-SA 4.0 / CC BY 4.0 data. | **REJECT** | None (catalog reject) | Standalone 3D application, not an agent writing or coding skill. Do not vendor heavy anatomy meshes or CC BY-4.0 data into OCBF overlay. | diff --git a/docs/warehouse-inventory.md b/docs/warehouse-inventory.md index b370e35..57451d1 100644 --- a/docs/warehouse-inventory.md +++ b/docs/warehouse-inventory.md @@ -377,7 +377,7 @@ Microsoft MarkItDown as an ingest converter, not a second document OS. SmartDoc | 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. | +| `markitdown-mcp` official | **FOREIGN_ON_DEMAND** | `mcp.markitdown` | Optional local stdio (`uvx --from markitdown-mcp==0.1.8 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. | diff --git a/lib/doctor.py b/lib/doctor.py index 5478858..21d1dde 100644 --- a/lib/doctor.py +++ b/lib/doctor.py @@ -181,7 +181,11 @@ def mcp_status_map() -> dict[str, str]: 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: + pinned = any( + part == "markitdown-mcp" or str(part).startswith("markitdown-mcp==") + for part in cmd + ) + if cmd[0] != "uvx" or not pinned: out[name] = "FAIL" continue out[name] = "CONFIGURED" diff --git a/lib/install.py b/lib/install.py index 44bef43..6d506ed 100644 --- a/lib/install.py +++ b/lib/install.py @@ -1487,7 +1487,7 @@ def cmd_reticle_disable() -> int: def cmd_markitdown_enable() -> int: spec: dict[str, object] = { "type": "local", - "command": ["uvx", "--from", "markitdown-mcp", "markitdown-mcp"], + "command": ["uvx", "--from", "markitdown-mcp==0.1.8", "markitdown-mcp"], "disabled": False, } return _optional_mcp_enable("markitdown", spec) diff --git a/tests/test_doctor.py b/tests/test_doctor.py index be3b199..9e4fe6e 100644 --- a/tests/test_doctor.py +++ b/tests/test_doctor.py @@ -439,6 +439,13 @@ def test_doctor_markitdown_valid_configured_passes(self): rc = cmd_doctor() self.assertEqual(rc, 0, buf.getvalue()) self.assertIn("CONFIGURED mcp:markitdown", buf.getvalue()) + data["mcp"]["markitdown"]["command"] = ["uvx", "--from", "markitdown-mcp==0.1.8", "markitdown-mcp"] + cfg.write_text(jsonc.dumps(data), encoding="utf-8") + buf = io.StringIO() + with redirect_stdout(buf): + rc = cmd_doctor() + self.assertEqual(rc, 0, buf.getvalue()) + self.assertIn("CONFIGURED mcp:markitdown", buf.getvalue()) def test_doctor_plugins_clean_when_absent(self): self._install() diff --git a/tests/test_install.py b/tests/test_install.py index 68bf55c..ab3f074 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -573,7 +573,7 @@ def test_markitdown_enable_and_disable(self): self.assertIn("markitdown", data["mcp"]["servers"]) md_spec = data["mcp"]["servers"]["markitdown"] self.assertEqual(md_spec["type"], "local") - self.assertEqual(md_spec["command"], ["uvx", "--from", "markitdown-mcp", "markitdown-mcp"]) + self.assertEqual(md_spec["command"], ["uvx", "--from", "markitdown-mcp==0.1.8", "markitdown-mcp"]) self.assertIs(md_spec.get("disabled"), False) self.assertEqual(cmd_markitdown_enable(), 0) diff --git a/vendor/license-audit.json b/vendor/license-audit.json index d2ecde8..aeda979 100644 --- a/vendor/license-audit.json +++ b/vendor/license-audit.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "product": "OpenCodeHighEnd", - "productVersion": "0.1.3", + "productVersion": "0.1.4", "note": "Evidence-based. A missing frontmatter license is not a grant. Adapted \u2260 first-party.", "skills": { "demo-video": { diff --git a/vendor/mcp-policy.json b/vendor/mcp-policy.json index 18f4193..b038348 100644 --- a/vendor/mcp-policy.json +++ b/vendor/mcp-policy.json @@ -54,7 +54,7 @@ "enabled": false, "transport": "stdio", "command": "uvx", - "args": ["--from", "markitdown-mcp", "markitdown-mcp"] + "args": ["--from", "markitdown-mcp==0.1.8", "markitdown-mcp"] } } } diff --git a/vendor/mcp-wanted.json b/vendor/mcp-wanted.json index e245084..a619992 100644 --- a/vendor/mcp-wanted.json +++ b/vendor/mcp-wanted.json @@ -70,7 +70,7 @@ "scope": "user", "transport": "stdio", "command": "uvx", - "args": ["--from", "markitdown-mcp", "markitdown-mcp"], + "args": ["--from", "markitdown-mcp==0.1.8", "markitdown-mcp"], "status": "FOREIGN_ON_DEMAND" } } diff --git a/vendor/provenance.json b/vendor/provenance.json index 68bb688..a6bc896 100644 --- a/vendor/provenance.json +++ b/vendor/provenance.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "product": "OpenCodeHighEnd", - "productVersion": "0.1.3", + "productVersion": "0.1.4", "upstreamProduct": "OpenCodeBestFriend", "upstreamVersion": "1.8.6", "firstPartyLicense": "MIT", diff --git a/vendor/sources.json b/vendor/sources.json index cf51055..75f1e58 100644 --- a/vendor/sources.json +++ b/vendor/sources.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "product": "OpenCodeHighEnd", - "productVersion": "0.1.3", + "productVersion": "0.1.4", "adaptedFrom": { "product": "OpenCodeBestFriend", "version": "1.8.6", @@ -77,7 +77,7 @@ "via": "uvx", "transport": "stdio", "status": "foreign-on-demand", - "note": "Optional MCP via uvx --from markitdown-mcp. Not vendored. No Azure keys. Enabled via opencode-he markitdown enable." + "note": "Optional MCP via uvx --from markitdown-mcp==0.1.8. Not vendored. No Azure keys. Enabled via opencode-he markitdown enable." }, "browser-act": { "repository": "https://github.com/browser-act/skills",