diff --git a/.gitignore b/.gitignore index cb5cdc9..c2284ec 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,6 @@ __pycache__/ # local install/test debris .home-fixture/ .scratch/ +demos/ +*.mp4 +*.webm diff --git a/CHANGELOG.md b/CHANGELOG.md index 52771f2..209120b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,37 @@ ## Unreleased -None. +## 1.8.6 — 2026-09-18 + +Catalog modernization (Wave A): retire obsolete twins, compress primitives, and tighten routing. Totals reduced to **62** (47 model-invoked, 15 manual slash commands). + +- **Catalog Retirement & Compression**: + - Retire model specialist `ask-matt`; workflow selection is handled directly by `AGENTS.md` and `rules/00-routing.md` without an extra specialist. Category checklist and phase boundary decision trees preserved in `skills/writing-for-agents/references/`. + - Compress `grilling` primitive into `grill-with-docs`; delete model skill `grilling`. + - Retire manual skill `/wait-what`; fold re-pitch instruction into `rules/03-prose-discipline.md`. + - Retire manual skill `/matt-implement`; spec-driven implementation and tracer-bullet tickets from `/to-tickets` execute directly in-session with `tdd`. + - Retain `wizard` for interactive human-only bash procedures (OAuth, secrets, cutover). + - Clarify mutual boundaries between `codebase-design` (single-module depth/seam design) and `/improve-codebase-architecture` (codebase scan and visual zero-network HTML report). +- **Survivor Upgrades**: + - `impeccable`: add 4-tier Taste Gate checklist (Hard Gate, Purpose-Gate, Quality Locks, Delivery Gate) into `reference/taste-guard.md`. Explicitly note that filter ≠ style guide, `BANK_MISS ≠ generate`, and dials in `taste/direction.md` apply after direction exists. + - `humanizer`: add During-Generation vs After-Audit copy check modes adapted from anti-slop copy rules; add explicit refusal boundaries for UI implementation and Oxlint installation. + - `scroll-world`: clarify user-chosen camera styles, seam QA (composition/continuity over raw PSNR), and graceful `NOT_CONFIGURED` degradation when paid video backends are absent. + - `markitdown`: update Microsoft markitdown pin to v0.1.7 (`945314a`); reaffirm output is Markdown data while SmartDoc retains QA/contract/render. + - `gh-axi` & `chrome-devtools-axi`: update command surfaces from upstream `kunchenguid/axi` (`fb75216`); enforce 4-door browser hierarchy. + - `browser-act`: document supported modes (`chrome`, `stealth-fresh`, `stealth-fixed`); reiterate `--type chrome-direct` ban and that `playwright-qa` remains the default verifier. + - `found-this-design`: allow referencing external DESIGN.md patterns (e.g. `awesome-design-md`) without cloning or vendoring; product UI direction stays Design Bank → Impeccable. + - `code-tour` & `why`: add "How it works" and "Where it lives" tour scaffolding to `code-tour`; add optional critique step to `/why`. +- **Policy & Boundary Integrity**: + - Reconcile `vendor/skill-allowlist.txt`, `vendor/skill-policy.json`, `vendor/license-audit.json`, and `vendor/provenance.json` to exactly 62 skills. + - Reject foreign control planes (ECC), standalone 3D anatomy apps (`human-atlas`), and auto-mutator loops (`ralph-loop`, `orchestrate`, `continual-learning`). + +## 1.8.5 — 2026-09-16 + +Feature release. Totals now **66** (49 model-invoked, 17 manual slash commands). + +- Add model-invoked specialist `id-demo-video` and manual slash command `/demo-video` (`manual-skills/demo-video`). +- Orchestrate end-to-end Indonesian application walkthrough videos, beat sheet timing (target duration ±15s), spoken oral Indonesian narration (130–150 wpm, anti-slop jargon ban), Edge TTS synthesis (`id-ID-GadisNeural` / `id-ID-ArdiNeural`) with SHA-256 caching and 429 backoff, Playwright/Chromium per-scene capture (1920x1080, human typing cadence), and FFmpeg composition/concat with 90s executive preview. +- Boundary enforcement: `id-demo-video` acts as demo pipeline director; `hyperframes` handles short title/end HTML cards only; `playwright-qa` remains functional browser QA; `visual-studio` remains photoreal non-UI media. ## 1.8.4 — 2026-09-16 diff --git a/README.md b/README.md index 6d032e1..bc74fbb 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # OpenCodeBestFriend Production-ready capability layer for OpenCode: -64 routed skills (core + Wave 2/3 warehouse specialists), MCP, Codebase Memory, +62 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 -- 64 skills: 48 model-invoked, 16 manual slash commands +- 62 skills: 47 model-invoked, 15 manual slash commands (frozen; see [docs/CATALOG-FREEZE.md](docs/CATALOG-FREEZE.md)) - 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) @@ -61,8 +61,8 @@ Restart OpenCode after install. Config is not hot-reloaded. ┌───────────────────┼────────────────────┐ ▼ ▼ ▼ Skills MCP Rules - 48 automatic Codebase Memory Verification - 16 manual Context7 Engineering + 47 automatic Codebase Memory Verification + 15 manual Context7 Engineering shadcn │ ▼ @@ -86,6 +86,8 @@ Default: repository evidence first. Then at most one specialist. | Intent | Route | | --- | --- | | Repo understanding | Codebase Memory MCP | +| How it works / where it lives | Codebase Memory then `code-tour` | +| Repo rationale | `/why` (manual) | | Hard unknown bug | `diagnosing-bugs` | | Security-sensitive work | `full-audit-keamanan` | | Measured performance regression | `full-performance-audit` | @@ -93,20 +95,23 @@ Default: repository evidence first. Then at most one specialist. | UI registry | shadcn MCP | | Visual direction | `found-this-design` | | UI implementation after a direction | `impeccable` | +| Generic AI UI look | `impeccable` taste-gate (not `install-anti-slop`) | | Motion | `emil-design-eng` | | Photoreal / media | `visual-studio` | | Scroll-led storytelling | `scroll-craft` | | Scroll-driven 3D / camera world | `scroll-world` | | Procedural Three.js object from image | `img2threejs` | | Deterministic HTML composition video | `hyperframes` | +| Demo video aplikasi & narasi ID | `id-demo-video` (`/demo-video`) | +| Browser | `playwright-qa` → `browser-act` → `chrome-devtools-axi` → `click-path-audit` | | 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`) | +| Generic AI prose | `humanizer` / `/unslop` | | Editorial HTML/SVG diagrams | `diagram-design` | +| TS Oxlint install | `install-anti-slop` (explicit only) | | Architecture bake-off | `/architect` (manual) | -| Repo rationale | `/why` (manual) | Warehouse: `api-design`, `contract-first`, `automation-audit-ops`, `code-tour`, `click-path-audit` (plus Wave 2 diagnostics). diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index ad6eeff..f16482c 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -16,7 +16,7 @@ Machine-readable copy: `vendor/license-audit.json`. | --- | --- | --- | --- | | `adhd` | vendored frontmatter | MIT | follow MIT | | `impeccable` | vendored frontmatter | Apache-2.0 | follow Apache-2.0 | -| Matt Pocock selected skills (`diagnosing-bugs`, `domain-modeling`, `codebase-design`, `writing-for-agents`, `research`, `prototype`, `grilling`, `improve-codebase-architecture`, `wizard`, `wait-what`, `ask-matt`, `grill-with-docs`, `to-spec`, `to-tickets`, `tdd`, `matt-code-review` ← `code-review`, `matt-implement` ← `implement`) | mattpocock/skills MIT LICENSE — `vendor/licenses/MATT-POCOCK-MIT.txt` | MIT | follow MIT | +| Matt Pocock selected skills (`diagnosing-bugs`, `domain-modeling`, `codebase-design`, `writing-for-agents`, `research`, `prototype`, `improve-codebase-architecture`, `wizard`, `grill-with-docs`, `to-spec`, `to-tickets`, `tdd`, `matt-code-review` ← `code-review`) | mattpocock/skills MIT LICENSE — `vendor/licenses/MATT-POCOCK-MIT.txt` | MIT | follow MIT | | Pstack selected skills (`blast-radius`, `unslop`, `create-verification-skill`, `maintain-verification-skill`, `technical-writing`, `arena`, `interrogate`, `architect`, `decision-log`, `why`, `reflect`, `figure-it-out`) | cursor/plugins pstack `60c641e` | MIT — `vendor/licenses/PSTACK-MIT.txt` | follow MIT | | Snapshot skills (`browser-act`, `chrome-devtools-axi`, `emil-design-eng`, `found-this-design`, `full-audit-keamanan`, `full-performance-audit`, `gh-axi`, `scroll-world`, `visual-studio`) | GrokBestFriend 1.3.1 snapshot + `vendor/licenses/GROKBESTFRIEND-MIT.txt`; skill wrappers MIT. Separate CLIs follow their own packages. | MIT | follow MIT | | `scroll-craft` | [nateherkai/scroll-craft](https://github.com/nateherkai/scroll-craft) `0b81622` — `vendor/licenses/NATEHERK-SCROLL-CRAFT-MIT.txt`; skill `NOTICE.md` | MIT © 2026 Nate Herk | follow MIT | diff --git a/VERSION b/VERSION index bfa363e..f263cd1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.4 +1.8.6 diff --git a/commands/demo-video.md b/commands/demo-video.md new file mode 100644 index 0000000..acb815e --- /dev/null +++ b/commands/demo-video.md @@ -0,0 +1,24 @@ +--- +description: "Manual specialist: demo-video" +--- + +Load and follow the OpenCode-adapted manual specialist `demo-video` (alias for `id-demo-video`). + +Plan and produce an application walkthrough demo video with Indonesian narration using the `id-demo-video` specialist. + +Collect the following parameters from user arguments or context: +1. Application target URL (e.g. `http://localhost:3000`) +2. Start command (how to start if offline, e.g. `npm run dev`) +3. Target duration (default: `10:00` / 600 seconds) +4. Voice: `id-ID-GadisNeural` (default, female) or `id-ID-ArdiNeural` (male) +5. Output directory: `demos//` + +Then load and follow the canonical `id-demo-video` specialist: +- In repository tree: `skills/id-demo-video/SKILL.md` +- After installation: `~/.config/opencode/skills/id-demo-video/SKILL.md` + +User arguments: + +$ARGUMENTS + +Do not substitute another specialist. Do not load this via the skill tool. diff --git a/commands/matt-implement.md b/commands/matt-implement.md deleted file mode 100644 index 9de409a..0000000 --- a/commands/matt-implement.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -description: "Manual specialist: matt-implement" ---- - -Load and follow the OpenCode-adapted manual specialist `matt-implement`. - -Read the file `~/.config/opencode/bestfriend/skills/matt-implement/SKILL.md` with the Read tool and follow it exactly. - -User arguments: - -$ARGUMENTS - -Do not substitute another specialist. Do not load this via the skill tool. diff --git a/commands/wait-what.md b/commands/wait-what.md deleted file mode 100644 index 7af06d9..0000000 --- a/commands/wait-what.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -description: "Manual specialist: wait-what" ---- - -Load and follow the OpenCode-adapted manual specialist `wait-what`. - -Read the file `~/.config/opencode/bestfriend/skills/wait-what/SKILL.md` with the Read tool and follow it exactly. - -User arguments: - -$ARGUMENTS - -Do not substitute another specialist. Do not load this via the skill tool. diff --git a/docs/CATALOG-FREEZE.md b/docs/CATALOG-FREEZE.md new file mode 100644 index 0000000..6e369ed --- /dev/null +++ b/docs/CATALOG-FREEZE.md @@ -0,0 +1,15 @@ +# Catalog Freeze Contract (1.8.6) + +This contract defines the immutable boundary and governance for the OpenCodeBestFriend catalog following the 1.8.6 modernization closeout. + +- **Product version**: 1.8.6 +- **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). +- **Name collision remains**: `install-anti-slop` = Oxlint; UI/copy filter lives in `impeccable` taste-gate + `humanizer`; `/unslop` = `humanizer`. +- **FOREIGN_ON_DEMAND stays out of the overlay**: `ECC`, `noodle`, `serena`, `stitch`, `reticle`, `ui-skills` MCP, `markitdown` MCP, `exa`, `Caliper`, `SkillEvaluator`. `doctor` must not fail when they are absent. +- **No new allowlist name without retiring one existing name in the same change.** +- **No padding back to 64.** +- **No `/how`, `/poteto-mode`, `/antislop`, `taste-skill`, `axi-core`, `human-atlas`, `awesome-design-md` vendor.** +- **No auto-edit of skills/rules from a learning log. No silent `--auto`.** +- **Next unfreeze requires a human-written exception in CHANGELOG Unreleased that names the retired twin.** diff --git a/docs/architecture.md b/docs/architecture.md index 346c7c6..940aeda 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,8 +10,8 @@ ┌───────────────────┼────────────────────┐ ▼ ▼ ▼ Skills MCP Rules - 48 automatic Codebase Memory Verification - 16 manual Context7 Engineering + 47 automatic Codebase Memory Verification + 15 manual Context7 Engineering shadcn │ ▼ diff --git a/docs/routing.md b/docs/routing.md index 51646d3..4284d63 100644 --- a/docs/routing.md +++ b/docs/routing.md @@ -10,7 +10,7 @@ Load `00-routing.md` only when the thin router is not enough. Do not `@`-import One primary specialist per problem. At most one risk specialist (`full-audit-keamanan` XOR `full-performance-audit`). Availability is not a reason to activate a tool. For mixed requests (e.g. landing + button + video), pick the primary largest surface (typically `impeccable`); motion or video is step 2 after user pick, never a parallel load. -Manual specialists stay behind slash commands. Suggest them when the user names the job. `grilling` is not default; product interviews, glossaries, and ADRs route to `grill-with-docs`. Load `grilling` only if explicitly named. +Manual specialists stay behind slash commands. Suggest them when the user names the job. Product interviews, glossaries, and ADRs route to `grill-with-docs` (including frontier rounds). Spec and ticket implementations stay in-session with `tdd`. Workflow choice is resolved directly via the router without an extra specialist. Tool reporting: @@ -28,8 +28,10 @@ Browser verification follows four explicit doors: exploratory application UI rou 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`. +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`. Demo video aplikasi, walkthrough layar, narasi Indonesia, dan demo lomba route to `id-demo-video` (bukan `hyperframes` untuk durasi panjang utuh, bukan `playwright-qa`, bukan `visual-studio`). Kartu judul HTML→MP4 tetap `hyperframes`. Editorial technical diagrams (HTML/SVG) route to `diagram-design`. Warehouse diagnostics load only when the user names the job: `agent-architecture-audit` (architecture layers), `cost-aware-llm-pipeline` (token budgeting), `eval-harness` (benchmarks), `prompt-optimizer` (prompt refinement), and `skill-stocktake` (catalog hygiene). Wave 3 warehouse procedures route to `api-design` (REST resources), `contract-first` (consumer/provider contracts), `automation-audit-ops` (live inventory), and `code-tour` (guided tours). Foreign harnesses (such as ECC control plane) remain `FOREIGN_ON_DEMAND`; never vendored, auto-merged, or shadowed. Operational stack adapters route to `supabase-ops` (Supabase Auth/RLS/migrations/Edge Functions), `mongodb-ops` (MongoDB schemas/indexing/aggregation), and `vercel-ops` (Vercel hosting/deploy config). These operational skills never generate visual UI and never replace `found-this-design` or `impeccable`. FOREIGN vendor packs stay off the overlay; user may npx skills add mongodb/agent-skills|supabase/agent-skills locally; never frontend-design for product UI. + +Architecture and comprehension routes: how it works / where it lives routes to Codebase Memory, then `code-tour`; architectural rationale routes to manual `/why`; break risk routes to manual `/blast-radius`. Generic AI UI aesthetics route to `impeccable` taste-guard (never `install-anti-slop`); generic AI prose routes to `humanizer` (`/unslop`); TypeScript static linting routes strictly to `install-anti-slop` upon explicit request. A `DESIGN.md` without a Design Bank match still filters slop without inventing brand assets. Pstack playbooks route to existing specialists (no `/poteto-mode`). Foreign harness control planes or continual learning loops that attempt to mutate `AGENTS.md` or skill definitions are strictly rejected. diff --git a/docs/skills.md b/docs/skills.md index 00bd23a..e248558 100644 --- a/docs/skills.md +++ b/docs/skills.md @@ -2,10 +2,10 @@ Policy: `vendor/skill-policy.json` plus `vendor/skill-allowlist.txt`. -- 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/` +- 47 model-invoked skills live under `skills/` and install to `~/.config/opencode/skills/` (core + Wave 2/3 warehouse specialists) +- 15 manual skills live under `manual-skills/` and install to `~/.config/opencode/bestfriend/skills/` plus `commands/` -`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. +`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. `id-demo-video` coordinates Indonesian application demo video production (`/demo-video` is its manual slash command). `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. diff --git a/docs/source-wave.md b/docs/source-wave.md new file mode 100644 index 0000000..6b49106 --- /dev/null +++ b/docs/source-wave.md @@ -0,0 +1,18 @@ +# Source Wave Inventory (Wave A Modernization) + +Disposition of upstream sources evaluated for OpenCodeBestFriend modernization. +Recorded per Phase 0 contract. + +| Source | Upstream Commit / Ref | Nature / Contents | Disposition | Survivor in OCBF | Notes / Rationale | +|---|---|---|:---:|---|---| +| [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) | `945314a45ddbe02935f2fd287b797dc0ba4a01e4` (v0.1.7 tag `63714e4`) | File to Markdown converter (Office/PDF/HTML/CSV/XLSX/PPTX/EPUB/ZIP). MIT. | **UPDATE** | `skills/markitdown` | Update pin and CLI invocation surface. Output is 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. | +| [oso95/scroll-world](https://github.com/oso95/scroll-world) | `71cc36d3bb150248ae36a2c552f9cbf88802a79c` | Continuous camera fly-through landing, vanilla-JS scrub engine, seam QA. MIT. | **UPDATE** | `skills/scroll-world` | Update camera style choices and composition seam QA. Retain boundary: scroll-craft = 2D timeline; scroll-world = 3D camera flight. Do not vendor paid video backends (degrade to NOT_CONFIGURED). | +| [VoltAgent/awesome-design-md](https://github.com/VoltAgent/awesome-design-md) | `8147538b4226ae41e2487a9179e3bcc1f68e8554` | Curated repository of brand DESIGN.md files and design token guidelines. | **REJECT** (vendor) / **FOREIGN** (reference) | Mention in `skills/found-this-design` | Human-chosen reference corpus only. Do not clone brand files into overlay. Direction stays Design Bank + project DESIGN.md. | +| [kunchenguid/axi](https://github.com/kunchenguid/axi) | `fb752160dea2eb421b082dee77fc1d5bc152639c` | Agent eXperience Interface (AXI) — 10 CLI principles; official `gh-axi`, `chrome-devtools-axi`. MIT. | **UPDATE** | `skills/gh-axi`, `skills/chrome-devtools-axi` | Refresh command surfaces and principles from upstream. Do not introduce a generic "axi" skill. Maintain 4-door browser hierarchy. | +| [browser-act/skills](https://github.com/browser-act/skills) | `11c057b03f92101642cadc9f840564574120d184` | BrowserAct CLI agent skills (2.0.2 stub, multi-account, stealth, session isolation). MIT. | **UPDATE** | `skills/browser-act` | Document three modes: `chrome` (profile reuse), `stealth-fresh`, `stealth-fixed`. Ban `chrome-direct`. Playwright-qa remains primary default QA adapter. | +| [cursor/plugins](https://github.com/cursor/plugins) | `e31650eea443aaea1e84cc15d88c13f40080b275` (`60c641e` base) | Cursor ecosystem: pstack, SaaS connectors (Gmail, HubSpot, Salesforce), continual-learning, ralph-loop, orchestrate. | **DONE** (pstack) / **REJECT** (SaaS & autopilot) | Existing specialists | pstack principles already absorbed in routing and engineering principles. Reject foreign SaaS connectors and autopilot loops (`ralph-loop`, `orchestrate`, `continual-learning`). | diff --git a/docs/stocktake-1.8.3.md b/docs/stocktake-1.8.3.md index 0ee74f8..9fd804d 100644 --- a/docs/stocktake-1.8.3.md +++ b/docs/stocktake-1.8.3.md @@ -137,3 +137,4 @@ A baseline cannot be produced from inside a single session that already has the 4. 28 of 62 skills omit a frontmatter `license` key by design. If that ever becomes confusing, document it in the skill authoring guide rather than adding keys. 5. `img2threejs` added post-#21; not part of the original 1.8.3 execution pass. 6. Live catalog at 1.8.4 is 64 (48 model-invoked, 16 manual) including `markitdown` KEEP. +7. Live catalog at 1.8.5 is 66 (49 model-invoked, 17 manual) including `id-demo-video` / `/demo-video` KEEP. diff --git a/docs/stocktake-1.8.5.md b/docs/stocktake-1.8.5.md new file mode 100644 index 0000000..5a9097d --- /dev/null +++ b/docs/stocktake-1.8.5.md @@ -0,0 +1,93 @@ +# Catalog Stocktake — 1.8.5 + +Executed per [skills/skill-stocktake/SKILL.md](../skills/skill-stocktake/SKILL.md). + +Measured tree: **49 model-invoked** (`skills/*/SKILL.md`) + **17 manual** (`manual-skills/*/SKILL.md`, each with a matching `commands/.md`) = **66**. Matches `vendor/skill-policy.json` and `vendor/skill-allowlist.txt`. + +License column is authoritative from `vendor/license-audit.json`, not frontmatter. A missing frontmatter `license` key is not a gap: 28 of 66 deliberately defer to the audit file. + +`RETIRE` requires either a failed existence pass or a no-skill baseline. No baseline was run in this pass, so **no item is retired here**. Items whose retirement would depend on a baseline are listed under [Blocked on A/B](#blocked-on-ab) and carry `KEEP` in the table, per the evidence rule. + +## Verdicts + +| Skill | Kind | Verdict | Evidence | Handoff | +|---|---|---|---|---| +| academic | model | KEEP | 45 lines, 5 refs; owns scholarly/IMRaD lane fenced off `research` and `smartdoc` | — | +| adhd | model | UPDATE (applied) | Body named `Claude Code`/`GrokBuild` as if either were this runtime; remaining bulk is calibration numerics + upstream MIT attribution | `writing-for-agents` | +| agent-architecture-audit | model | KEEP | 59 lines, NOTICE present; agent-loop lane distinct from `diagnosing-bugs` | — | +| api-design | model | KEEP | 37 lines; REST contract lane fenced off `contract-first` | — | +| architect | manual | KEEP | 82 lines, 3 refs; slash-only DAG bake-off | — | +| arena | manual | KEEP | 74 lines; multi-model bake-off, slash-only | — | +| ask-matt | model | UPDATE (applied) | Description said "GrokBuild skill or flow"; loaded every session | `writing-for-agents` | +| automation-audit-ops | model | KEEP | 44 lines; live-automation inventory, no sibling owns it | — | +| blast-radius | manual | KEEP | 46 lines; impact analysis, slash-only | — | +| browser-act | model | KEEP | 48 lines; explicit-request-only fence vs `playwright-qa` | — | +| chrome-devtools-axi | model | UPDATE (applied) | Duplicate contract block + `$HOME/.grok` path contradicting `rules/00-routing.md:131` | `writing-for-agents` | +| click-path-audit | model | KEEP | 39 lines; handler/shared-store lane fenced off `playwright-qa` | — | +| code-tour | model | KEEP | 35 lines; produces `.tour` artifacts nothing else emits | — | +| codebase-design | model | COMPRESS (applied) | 115 → 97; two ASCII box diagrams restated adjacent prose | `writing-for-agents` | +| contract-first | model | KEEP | 41 lines; multi-consumer contract lane | — | +| cost-aware-llm-pipeline | model | KEEP | 48 lines; token/model-tier lane fenced off `full-performance-audit` | — | +| create-verification-skill | manual | KEEP | 44 lines; paired with `maintain-verification-skill` | — | +| decision-log | manual | KEEP | 66 lines, ships a script | — | +| demo-video | manual | KEEP | 19 lines; manual slash command alias for `id-demo-video` | — | +| diagnosing-bugs | model | KEEP | 139 lines but carries the red-capable loop criterion; ships `scripts/` | — | +| diagram-design | model | KEEP | 46 lines, 3 refs; editorial diagram lane fenced off `impeccable` | — | +| domain-modeling | model | KEEP | 75 lines; glossary/ADR primitive composed by `grill-with-docs` | — | +| emil-design-eng | model | KEEP | 676 lines, largest in catalog; easing/timing numerics are the payload. COMPRESS off-limits by instruction | — | +| eval-harness | model | KEEP | 50 lines, 2 refs incl. `skill-utility.md` added in #18 | — | +| figure-it-out | manual | KEEP | 53 lines; slash-only exploration | — | +| found-this-design | model | KEEP | 127 lines, 4 scripts; Design Bank entry point | — | +| full-audit-keamanan | model | KEEP | 69 lines; security fence, never COMPRESS | — | +| full-performance-audit | model | KEEP | 232 lines; LCP/INP/CLS thresholds are the payload. COMPRESS off-limits by instruction | — | +| gh-axi | model | KEEP | 65 lines; GitHub CLI surface | — | +| grill-with-docs | model | COMPRESS (applied) | 120 → 77; whole body duplicated behind orphan overlay marker | `writing-for-agents` | +| grilling | model | KEEP | 23 lines; non-default primitive, explicitly named-only | — | +| humanizer | model | KEEP | 64 lines, NOTICE present; paired with manual `/unslop` | — | +| hyperframes | model | KEEP | 48 lines, Apache-2.0 with NOTICE; HTML→MP4 lane | — | +| id-demo-video | model | KEEP | 230 lines, 4 refs, 2 scripts; Indonesian walkthrough video production lane fenced off `hyperframes`, `playwright-qa`, and `visual-studio` | — | +| img2threejs | model | KEEP | 50-line first-party MIT factory; image→procedural Three.js Group; fenced off scroll-world / scroll-craft / hyperframes / visual-studio / impeccable; shipped #21 | — | +| impeccable | model | KEEP | 89-line body against 38 refs + 44 scripts — progressive disclosure working as designed | — | +| improve-codebase-architecture | manual | KEEP | 71 lines; slash-only | — | +| install-anti-slop | model | KEEP | 56 lines; pinned upstream commit `e8c4880` verified in body | — | +| interrogate | manual | KEEP | 73 lines, 4 refs; highest overlap pair at 0.359, still under warn | — | +| maintain-verification-skill | manual | KEEP | 39 lines; verification profile upkeep | — | +| markitdown | model | KEEP | Document text/table conversion to Markdown; preserves SmartDoc boundaries | — | +| matt-code-review | model | KEEP | 88 lines; two-axis review, opt-in only | — | +| matt-implement | manual | KEEP | 15 lines; ticket-loop entry, never auto-started | — | +| mongodb-ops | model | KEEP | 45 lines; vendor lane | — | +| playwright-qa | model | KEEP | 54 lines, Apache-2.0 with NOTICE; primary browser QA | — | +| prompt-optimizer | model | KEEP | 50 lines; advisory-only, does not mutate skills | — | +| prototype | model | KEEP | 27 lines; throwaway-evidence lane | — | +| reflect | manual | KEEP | 61 lines, 4 refs | — | +| research | model | KEEP | 15 lines, smallest body; already minimal | — | +| scroll-craft | model | KEEP | 101 lines, 8 refs; scroll-story lane fenced off `scroll-world` | — | +| scroll-world | model | KEEP | 129 lines; Hard rules section is fences, not ceremony | — | +| skill-stocktake | model | KEEP | 82 lines; this audit's own protocol | — | +| smartbook-ingest | model | KEEP | 33 lines; persistent-knowledge lane | — | +| smartdoc | model | KEEP | 62 lines, 4 refs; per-job document lane | — | +| supabase-ops | model | KEEP | 47 lines; vendor lane | — | +| tdd | model | KEEP | 39 lines; red-green lane | — | +| technical-writing | manual | KEEP | 130 lines, largest manual; prose structure lane | — | +| to-spec | model | KEEP | 80 lines; synthesis step before `to-tickets` | — | +| to-tickets | model | KEEP | 126 lines; extra length is expand–contract blast-radius judgment, not ceremony | — | +| unslop | manual | KEEP | 19 lines; manual twin of `humanizer` by design | — | +| vercel-ops | model | KEEP | 44 lines; vendor lane | — | +| visual-studio | model | UPDATE (applied) | Body claimed "GrokBuild already owns the tools" — host-product claim | `writing-for-agents` | +| wait-what | manual | KEEP | 9 lines, smallest in catalog | — | +| why | manual | KEEP | 79 lines, 4 refs; repo rationale, fenced off `research` | — | +| wizard | manual | KEEP | 47 lines; slash-only | — | +| writing-for-agents | model | KEEP | 82 lines; authoring lane, receives COMPRESS handoffs | — | + +## Tallies + +| Verdict | Count | +|---|---| +| KEEP | 60 | +| COMPRESS (applied) | 2 | +| UPDATE (applied) | 4 | +| MERGE | 0 | +| RETIRE | 0 | +| **Total** | **66** | + +Live catalog at 1.8.5 is 66 (49 model-invoked, 17 manual) including `id-demo-video` and `/demo-video`. diff --git a/docs/warehouse-inventory.md b/docs/warehouse-inventory.md index 6b22543..6b08bc7 100644 --- a/docs/warehouse-inventory.md +++ b/docs/warehouse-inventory.md @@ -264,8 +264,8 @@ This inventory establishes the contract for warehouse skills across the five ana | `affaan-m/ECC` | `perl-patterns` | **REJECT** | `-` | Language/framework pattern sprawl already covered by repo context + Context7 docs | `-` | | `affaan-m/ECC` | `perl-security` | **REJECT** | `-` | Language/framework pattern sprawl already covered by repo context + Context7 docs | `-` | | `affaan-m/ECC` | `perl-testing` | **REJECT** | `-` | Language/framework pattern sprawl already covered by repo context + Context7 docs | `-` | -| `affaan-m/ECC` | `plan-canvas` | **MERGE** | `ask-matt` | MERGE into plan agent | `-` | -| `affaan-m/ECC` | `plan-orchestrate` | **MERGE** | `ask-matt` | MERGE into plan agent and ask-matt workflow | `-` | +| `affaan-m/ECC` | `plan-canvas` | **MERGE** | `plan agent` | MERGE into plan agent | `-` | +| `affaan-m/ECC` | `plan-orchestrate` | **MERGE** | `plan agent` | MERGE into plan agent and router workflow | `-` | | `affaan-m/ECC` | `plankton-code-quality` | **MERGE** | `matt-code-review` | MERGE into matt-code-review | `-` | | `affaan-m/ECC` | `postgres-patterns` | **REJECT** | `-` | Language/framework pattern sprawl already covered by repo context + Context7 docs | `-` | | `affaan-m/ECC` | `prediction-market-oracle-research` | **REJECT** | `-` | Cryptocurrency / Web3 / automated trading specific domain; outside BestFriend core mission | `-` | @@ -363,7 +363,7 @@ Evaluation and disposition contract for the AI LABS 8-repo wave (procedural 3D, | `reticle` | **FOREIGN_ON_DEMAND** | `mcp.reticle` | Optional visual perception MCP (`npx -y @reticlehq/server mcp`). Server licensed under FSL-1.1-ALv2; not vendored. Perception only, never auto-implementer. | | `chisel` (hooks) | **REJECT** | `-` | Session/prompt/tool hooks coupled to Claude Code runtime. Context Guard remains NOT_PORTED. | | `ui-skills` | **FOREIGN_ON_DEMAND** | `mcp.ui-skills` | Optional remote MCP (`https://www.ui-skills.com/mcp`) for design-skill lookup only. Product UI remains Design Bank + Impeccable + Design V2 + shadcn. | -| `ouroboros` / Q00 | **REJECT** | `-` | Autonomous evolution harness / continuous-learning runtime rejected. Interview primitives already live in `grill-with-docs` / `ask-matt` / `to-spec`. | +| `ouroboros` / Q00 | **REJECT** | `-` | Autonomous evolution harness / continuous-learning runtime rejected. Interview primitives already live in `grill-with-docs` / `to-spec`. | | `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. | diff --git a/docs/wave-a-notes.md b/docs/wave-a-notes.md new file mode 100644 index 0000000..37c68a1 --- /dev/null +++ b/docs/wave-a-notes.md @@ -0,0 +1,81 @@ +# Wave A Modernization Notes + +Catalog modernization summary for OpenCodeBestFriend: retiring obsolete twins, compressing overlapping primitives, tightening boundaries, and upgrading surviving specialists. + +## Final Catalog Counts + +| Category | Prior (1.8.5) | After Wave A | Delta | +|---|:---:|:---:|:---:| +| **Model-Invoked Skills** (`skills/*/SKILL.md`) | 49 | **47** | -2 (`ask-matt`, `grilling`) | +| **Manual Commands** (`manual-skills/*/SKILL.md` + `commands/*.md`) | 17 | **15** | -2 (`matt-implement`, `wait-what`) | +| **Total Allowlist Items** (`vendor/skill-allowlist.txt`) | 66 | **62** | -4 | + +All assertions in `tests/test_skills.py`, `tests/test_routing.py`, `tests/test_license_audit.py`, `tests/test_version.py`, and documentation tables match the measured tree. No padding. + +--- + +## Dispositions + +### 1. Retired & Compressed + +- **`wait-what`** (Manual) → **RETIRED** + - *Rationale*: Convenience re-pitch failed the existence gate against standard technical writing and repository domain discipline. + - *Residue*: Moved into a single re-pitch instruction in `rules/03-prose-discipline.md` (stop, brief context, ASD-STE100 Simplified Technical English, ubiquitous language from `CONTEXT.md`). + - *Target*: `technical-writing` + `rules/03-prose-discipline.md`. + +- **`grilling`** (Model) → **COMPRESSED into `grill-with-docs`** + - *Rationale*: Grilling as a primitive without documentation produces transient decisions. Full planning interviews were already using `grill-with-docs`. + - *Residue*: Frontier rounds and design-tree structure merged directly into `skills/grill-with-docs/SKILL.md`. Model skill directory removed. + +- **`ask-matt`** (Model) → **RETIRED** + - *Rationale*: Having a specialist dedicated solely to choosing which workflow to run is a category error that adds token overhead on every session turn. The router (`templates/AGENTS.md` and `rules/00-routing.md`) handles workflow selection directly without loading a specialist. + - *Residue*: Standard category mapping and router checklist moved to `skills/writing-for-agents/references/route-checklist.md`; session transition decision tree preserved in `skills/writing-for-agents/references/phase-boundaries.md`. + +- **`matt-implement`** (Manual) → **RETIRED** + - *Rationale*: Twin of in-session implementation and `tdd`. Spec-driven implementation and tracer-bullet tickets from `/to-tickets` execute directly in-session using `tdd`. + - *Target*: In-session write + `tdd`. Boundary line added to `skills/tdd/SKILL.md`. + +### 2. Decided & Kept + +- **`wizard`** (Manual) → **KEPT** + - *Rationale*: Distinct from agent setup or OCBF doctor. Generates interactive bash wizards for steps only a human can perform (OAuth, secret provisioning, cloud dashboard cutover). +- **`codebase-design`** (Model) & **`/improve-codebase-architecture`** (Manual) → **BOTH KEPT** + - *Rationale*: Non-overlapping responsibilities. `codebase-design` defines single-module interface depth and seams; `improve-codebase-architecture` performs whole-codebase scans for shallow modules and generates visual zero-network HTML reports. Boundaries mutually clarified in frontmatter descriptions. + +### 3. Updated Survivors (Bodies Only — Zero New Names) + +- **`impeccable`**: + - Incorporated 4-tier Taste Gate architecture into `reference/taste-guard.md`: Hard Gate (absolute bans on hallucinated data/fake proof/status dots/two-state layouts), Purpose-Gate (reason required for animations/marquees/glass), Quality Locks (surface mode, contrast, reduced-motion, states), and Delivery Gate (pre-ship check). + - Explicit rule: Filter ≠ style guide. Filters remove category defaults; direction comes from Design Bank or `DESIGN.md`. + - Enforced `BANK_MISS ≠ generate`. + - Stated that `DESIGN_VARIANCE`, `MOTION_INTENSITY`, and `VISUAL_DENSITY` dials in `taste/direction.md` are optional controls evaluated *after* a direction exists. + - Reaffirmed that Stitch MCP (comps only) and UI Skills MCP (lookup only) never implement production UI alone. +- **`humanizer`**: + - Added During-Generation vs After-Audit copy checks adapted from anti-slop copy rules without raw rule dumping. + - Explicit boundary: strictly refuses UI implementation and static linter (`install-anti-slop`) installation. +- **`scroll-world`**: + - Updated camera style intake choices and seam QA (evaluates composition and vector continuity, not numerical PSNR). + - Explicit `NOT_CONFIGURED` degradation note when paid video backends (Monid, Higgsfield, Kling) are absent. + - Preserved boundary: `scroll-craft` (2D scrollytelling) vs `scroll-world` (3D continuous camera flight). +- **`markitdown`**: + - Pinned to current Microsoft `markitdown` v0.1.7 (`945314a`). + - Stated that output is Markdown data; SmartDoc retains contract, QA, and rendering ownership. Optional stdio MCP remains enable-gated. +- **`gh-axi` & `chrome-devtools-axi`**: + - Updated command surfaces from upstream `kunchenguid/axi` (`fb75216`). No generic `axi` skill introduced. + - Enforced 4-door browser hierarchy: `playwright-qa` → `browser-act` → `chrome-devtools-axi` → `click-path-audit`. +- **`browser-act`**: + - Documented three supported execution modes: `chrome` (profile reuse), `stealth-fresh` (ephemeral), and `stealth-fixed` (persistent). + - Reaffirmed strict ban on `--type chrome-direct`. Reaffirmed that `playwright-qa` remains the primary default verifier. +- **`found-this-design`**: + - Added explicit allowance for humans referencing external DESIGN.md patterns (e.g. `awesome-design-md`) while strictly forbidding fetching, cloning, or vendoring brand packs. Product UI stays Design Bank → `impeccable`. +- **`code-tour` & `why`**: + - Added "How it works" and "Where it lives" tour scaffolding to `code-tour`. + - Added optional critique step to `/why` to evaluate whether historical rationale still holds. + +### 4. Rejected Upstream Additions + +- **`affaan-m/ECC`**: Rejected vendoring control plane and 292 skills. Remains `FOREIGN_ON_DEMAND`. Doctor does not fail when absent. +- **`ashemag/human-atlas`**: Rejected 3D anatomy application from catalog. +- **`VoltAgent/awesome-design-md`**: Rejected cloning brand files into overlay. +- **Cursor SaaS Plugins**: Rejected connectors for Gmail, HubSpot, Salesforce, Gong, etc. +- **Autopilot Loops**: Rejected `ralph-loop`, `orchestrate`, and `continual-learning` that auto-mutate agent rules or skills. diff --git a/manual-skills/demo-video/SKILL.md b/manual-skills/demo-video/SKILL.md new file mode 100644 index 0000000..135e283 --- /dev/null +++ b/manual-skills/demo-video/SKILL.md @@ -0,0 +1,19 @@ +--- +name: demo-video +description: Manual slash command alias for id-demo-video to orchestrate narrated application walkthrough recordings and Indonesian voiceover demo videos. +compatibility: opencode +license: MIT +--- + +# Demo Video (Manual Alias for id-demo-video) + +Manual slash command alias for the `id-demo-video` specialist. + +When this manual command is invoked, load and follow the canonical `id-demo-video` specialist body: + +- In repository tree: `skills/id-demo-video/SKILL.md` +- After installation: `~/.config/opencode/skills/id-demo-video/SKILL.md` + +Follow all rules, 10-minute scene modularity, Indonesian oral narration conventions, Edge TTS defaults, and recording composition contracts defined in `id-demo-video`. + +Do not substitute another specialist. diff --git a/manual-skills/improve-codebase-architecture/SKILL.md b/manual-skills/improve-codebase-architecture/SKILL.md index e05ee9d..738ca23 100644 --- a/manual-skills/improve-codebase-architecture/SKILL.md +++ b/manual-skills/improve-codebase-architecture/SKILL.md @@ -47,7 +47,7 @@ For each candidate, render a card with: - **Solution** — plain English description of what would change - **Benefits** — explained in terms of locality and leverage, and how tests would improve - **Before / After diagram** — side-by-side, custom-drawn, illustrating the shallowness and the deepening -- **Recommendation strength** — one of `Strong`, `Worth exploring`, `Speculative`, rendered as a badge +- **Recommendation strength** — one of `Strong`, `Worth exploring`, `Speculative`, rulative`, rendered as a badge End the report with a **Top recommendation** section: which candidate you'd tackle first and why. @@ -59,9 +59,9 @@ See [HTML-REPORT.md](HTML-REPORT.md) for the full HTML scaffold, diagram pattern Do NOT propose interfaces yet. After the file is written, ask the user: "Which of these would you like to explore?" -### 3. Grilling loop +### 3. Frontier decision loop -Once the user picks a candidate, walk the decision tree with them using the grilling discipline (frontier rounds) inline — constraints, dependencies, the shape of the deepened module, what sits behind the seam, what tests survive. Do not invoke `/grilling` unless the user asked. +Once the user picks a candidate, walk the decision tree with them using frontier rounds inline — constraints, dependencies, the shape of the deepened module, what sits behind the seam, what tests survive. Use `grill-with-docs` if creating or updating CONTEXT.md and ADRs. Side effects happen inline as decisions crystallize — keep the domain model current using domain-modeling discipline (glossary/ADR), without invoking `/domain-modeling` unless the user asked: diff --git a/manual-skills/matt-implement/SKILL.md b/manual-skills/matt-implement/SKILL.md deleted file mode 100644 index fff7c54..0000000 --- a/manual-skills/matt-implement/SKILL.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -name: matt-implement -description: Implement a piece of work based on a spec or set of tickets. -compatibility: opencode ---- - -Implement the work described by the user in the spec or tickets. - -Use /tdd where possible, at pre-agreed seams. Default Grok write path is bundled /implement; this skill is the Matt ticket loop only. - -Run typechecking regularly, single test files regularly, and the full test suite once at the end. - -Once done, use /matt-code-review to review the work. - -Commit your work to the current branch. diff --git a/manual-skills/wait-what/SKILL.md b/manual-skills/wait-what/SKILL.md deleted file mode 100644 index 545817c..0000000 --- a/manual-skills/wait-what/SKILL.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: wait-what -description: Stop. That last message did not land — re-pitch it. -compatibility: opencode ---- - -Wait — I don't understand where you've got to here. Re-pitch that: give me a little bit of context, talk in ASD-STE100 Simplified Technical English, and use the ubiquitous language from `CONTEXT.md` if it exists. - -This is a convenience re-pitch. It does not install or invoke `/bro`. diff --git a/manual-skills/why/SKILL.md b/manual-skills/why/SKILL.md index 7298b0f..3bda8e3 100644 --- a/manual-skills/why/SKILL.md +++ b/manual-skills/why/SKILL.md @@ -74,6 +74,8 @@ Keep this structure. Do not collapse confidence. **COMPETING HYPOTHESES.** If the record fits more than one story, list them with evidence for and against. +**OPTIONAL CRITIQUE.** If the user asks whether the rationale still holds or if the approach should be revisited: evaluate whether underlying constraints (scale, framework limitations, external APIs) have changed since the original commit/ADR. + **UNKNOWN.** Explicit gaps. Searches that returned empty. **SOURCES CONSULTED.** One line per source, including the ones that returned nothing or were `NOT_CONFIGURED`. diff --git a/rules/00-routing.md b/rules/00-routing.md index 5bad3c7..f869854 100644 --- a/rules/00-routing.md +++ b/rules/00-routing.md @@ -14,13 +14,12 @@ Do not infer a model provider from a logical model name. Treat custom-gateway al 1. **Repo evidence is enough** → do the work. No specialist. Verification: FAST or STANDARD. 2. **User typed a slash skill** → load that skill. Do not substitute. -3. **User is choosing a workflow** (`which skill`, `alur apa`, `ask matt`) → load `/ask-matt`. +3. **User is choosing a workflow** (`which skill`, `alur apa`) → read `~/.config/opencode/AGENTS.md` or this file. No specialist. 4. **Architecture / PR-plan DAG** → the OpenCode plan agent. After approval → implement in this session. There is no bundled `/design` or `/execute-plan`. -5. **Feature still needs a plan** (interview, glossary, ADR) → `/grill-with-docs`. `/grilling` is not default; load `/grilling` only if the user explicitly names grilling. Then `/to-spec` → `/to-tickets` only if the user asked for tickets or the work is multi-session. -6. **Ordinary implementation** → write in this session. Use `/tdd` when test-first. Do **not** auto-start `/matt-implement`. There is no user `/implement` skill. -7. **User asked for the Matt ticket loop** → `/matt-implement` only for a `/to-tickets` ticket. -8. **Review** → in-session review. `/matt-code-review` only if the user asked for two-axis Standards + Spec. There is no user `/code-review` skill. -9. **Verification** → pick a profile, then Read `~/.config/opencode/bestfriend/rules/01-verification.md`. Required configured failures block a completion claim. +5. **Feature still needs a plan** (interview, glossary, ADR) → `/grill-with-docs` (includes frontier rounds). Then `/to-spec` → `/to-tickets` only if the user asked for tickets or the work is multi-session. +6. **Ordinary implementation** → write in this session. Use `/tdd` when test-first. Spec and `/to-tickets` implementations stay in this session with `/tdd`. There is no user `/implement` skill. +7. **Review** → in-session review. `/matt-code-review` only if the user asked for two-axis Standards + Spec. There is no user `/code-review` skill. +8. **Verification** → pick a profile, then Read `~/.config/opencode/bestfriend/rules/01-verification.md`. Required configured failures block a completion claim. ## Knowledge @@ -36,7 +35,7 @@ Do not infer a model provider from a logical model name. Treat custom-gateway al - Module, interface, seam, testability, abstraction: `/codebase-design` (distinct from `/api-design` for REST and `/contract-first` for machine schemas). Multi-sketch bake-off: suggest `/architect` (manual). Do not auto-start `/architect`. - 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`. +- Authoring SKILL.md / AGENTS.md / skill descriptions / context pointers: `/writing-for-agents` (distinct from `/skill-stocktake` which audits catalog hygiene). Workflow choice is handled directly by the router without a specialist. - 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`. @@ -53,6 +52,12 @@ Do not infer a model provider from a logical model name. Treat custom-gateway al - Supabase Auth, RLS policies, migrations, Edge Functions: `/supabase-ops` (Context7; not `/impeccable`). Defensive security review of public tables stays `/full-audit-keamanan`. - MongoDB schemas, indexing, aggregation pipelines: `/mongodb-ops`. Connection strings must never be printed. Official syntax stays Context7. - Vercel deployment, `vercel.json`, preview URLs, hosting config: `/vercel-ops`. Deploy PR workflow stays `/gh-axi`. Never run `vercel --prod` automatically. Never replace `/found-this-design` or `/impeccable`. +- How it works / where it lives: Codebase Memory first, then `/code-tour`. Why this repo made a choice: suggest `/why`. Break risk: suggest `/blast-radius`. +- Generic AI UI look: `impeccable` taste-guard (not `install-anti-slop`). Generic AI prose: `humanizer` (`/unslop`). +- TypeScript anti-pattern lint install: `/install-anti-slop` (explicit user request only). +- DESIGN.md without bank: still filter slop; do not invent brand facts. +- pstack playbooks: route to existing specialists; no `/poteto-mode`. +- Foreign harness control planes (ECC, Ralph loop, orchestrate, continual-learning) that write AGENTS.md or rules: REJECT. ## UI and browser @@ -67,6 +72,7 @@ Do not infer a model provider from a logical model name. Treat custom-gateway al - Continuous camera fly-through, diorama, or 3D-world landing: `/scroll-world` even if the request says scroll. - Procedural Three.js object from image: `/img2threejs` (factory Group, editable primitives, visible vs inferred spec). Not `scroll-world` (camera fly-through), not `hyperframes` (HTML-to-MP4), not `visual-studio` (photoreal stills/media), and not `impeccable` (product UI). - Deterministic HTML composition rendered to video: `/hyperframes` (headless Chrome + FFmpeg). Not `visual-studio`, not `emil-design-eng`. Ordinary scrollable UI stays `/impeccable`. +- Demo video aplikasi, walkthrough layar, narasi Indonesia, demo lomba: skill `id-demo-video` (bukan `hyperframes` untuk durasi panjang utuh, bukan `playwright-qa`, bukan `visual-studio`). Kartu judul HTML→MP4 tetap `hyperframes`. - Photoreal stills / ads / identity with no UI surface: `/visual-studio`. - Motion after Impeccable: `/emil-design-eng`. - Image/video generation: use OpenCode native image tools if the session exposes them. Otherwise write prompt files and mark DEGRADED. Do not invent `image_gen`. @@ -86,9 +92,9 @@ Do not infer a model provider from a logical model name. Treat custom-gateway al - Planning and tickets stay on Matt skills: `/grill-with-docs`, `/to-spec`, `/to-tickets`, `/tdd`. - Architecture DAG: the OpenCode plan agent, not a skill. -- Ordinary writes stay in this session. `/matt-implement` is only for a ticket that `/to-tickets` produced. +- Ordinary writes stay in this session. Spec and ticket implementations stay in this session with `/tdd`. - Default review is in-session. Two-axis: `/matt-code-review`. -- Manual / slash-only (do not auto-start): `/blast-radius`, `/create-verification-skill`, `/maintain-verification-skill`, `/unslop`, `/technical-writing`, `/arena`, `/interrogate`, `/architect`, `/why`, `/reflect`, `/figure-it-out`, `/decision-log`, `/wizard`, `/wait-what`, `/improve-codebase-architecture`. Suggest them when the user names the job; do not load them as the default path. +- Manual / slash-only (do not auto-start): `/architect`, `/arena`, `/blast-radius`, `/create-verification-skill`, `/decision-log`, `/demo-video`, `/figure-it-out`, `/improve-codebase-architecture`, `/interrogate`, `/maintain-verification-skill`, `/reflect`, `/technical-writing`, `/unslop`, `/why`, `/wizard`. Suggest them when the user names the job; do not load them as the default path. ## Grok bundled names (do not fake) @@ -120,7 +126,7 @@ Do not infer a model provider from a logical model name. Treat custom-gateway al - Do not print database connection strings, JWTs, or secret keys in Supabase, MongoDB, or Vercel ops. - Do not use Stitch as an automatic UI implementer or let it replace Design V2 atom shortlist. - Do not run `/found-this-design` for atomic components (button, input, card, nav); stay in `/impeccable`. -- Do not auto-start `/grilling` for product interviews or planning; `/grill-with-docs` is the primary route. +- Do not auto-start planning interviews for ordinary implementation; `/grill-with-docs` handles planning interviews when requested. - Do not `@`-import the full routing or verification files into CLAUDE.md. - Do not register 21st.dev, Magic UI MCP, Kibo MCP, or unofficial React Bits / Aceternity MCP. - Do not run `shadcn init` on this adapter, backend, or Python repositories. diff --git a/rules/03-prose-discipline.md b/rules/03-prose-discipline.md index 6ee758e..fd615e9 100644 --- a/rules/03-prose-discipline.md +++ b/rules/03-prose-discipline.md @@ -20,5 +20,6 @@ This is not a skill. It does not auto-apply. It does not rewrite code. - Cut fabricated metrics and uncited statistics: never invent precise percentages, multipliers, or benchmark numbers. - Cut beta-pill voice and sparkle-CTA fluff: do not decorate action buttons with sparkles, emoji flair, or artificial status pills. - Never “polish” source code, tests, or command output as if they were marketing copy. +- If the user says "wait what" or asks to re-pitch: stop, provide concise context, speak in ASD-STE100 Simplified Technical English, and use the ubiquitous domain language from `CONTEXT.md`. For full prose rewrites and systematic AI-tell removal, use the `humanizer` specialist (manual slash alias: `/unslop`). diff --git a/skills/ask-matt/PHASE-BOUNDARIES.md b/skills/ask-matt/PHASE-BOUNDARIES.md deleted file mode 100644 index cb31e6a..0000000 --- a/skills/ask-matt/PHASE-BOUNDARIES.md +++ /dev/null @@ -1,55 +0,0 @@ -# Phase boundaries - -A **phase** is a chunk of work inside a session — the grilling, the implementation, the QA. The definition is fuzzy on purpose: a phase ends when you think *"ok, we're done with that"*. - -The **phase boundary** is the gap between two phases, and it is the only place this decision belongs. Mid-phase there is no decision to make — continue, or split the work that's left into subagents. Compacting mid-phase makes the agent lose the thread. - -## The five options - -| Option | What it does | -| ------------ | --------------------------------------------------------------- | -| **Continue** | Stay in the session. No context switch at all. | -| **`/clear`** | Empty the context window and start from nothing. | -| **`/handoff`** | Write a portable markdown file and seed a session anywhere with it. | -| **Subagent** | Send the task to its own context window and get a report back. | -| **`/compact`** | Compress this context and seed a fresh session with the summary. | - -## The tree - -Work top to bottom at the boundary. The first **yes** wins. - -**1. Can you continue in this session?** Two things make the answer yes: the next phase needs this phase as a **primary source**, or you have enough [smart zone](https://www.aihero.dev/ai-coding-dictionary/smart-zone) left (~150k tokens) for the next phase to fit. Grilling → implementation is the standard yes: the implementation wants the reasoning verbatim, not a summary of it. Continue costs nothing and loses nothing, so rule it out before anything else. - -**2. Is the context irrelevant to what comes next?** Is everything in this session — the exploration, the decisions, the dead ends — disposable? If so, **`/clear`**. It is the cheapest move on the board: it takes no time and hands back the whole window. `/clear` also isn't terminal — the old session stays resumable. - -The cost of getting this wrong is one-way. Clear a *relevant* context and you lose the **why** behind what you built, and no amount of reading the diff back gets it returned. - -**3. Do you need to hand off?** `/handoff` is narrow. You need it only when you are: - -- swapping to a **new harness** (Claude → Codex), -- moving to a **new directory** or repo, -- sending the work to a **colleague**, -- or forking a side task you found **mid-phase** without derailing what you're doing. - -That list is the whole clause. What `/handoff` buys is **portability** — a file that travels. If nothing is travelling, you don't need it. - -**4. Can the task be done AFK?** Is it scoped tightly enough to run with you away from the keyboard, no steering? Then send it to a **subagent** and leave this session untouched. Automated review is the standard case: the agent reads the diff and reports, and you aren't needed while it does. - -**5. Otherwise, `/compact`.** Relevant context, same harness, same directory, and you need to stay in the loop — this is where the tree lands, and it lands here often. Pass it an instruction (`/compact we're going to QA this area`) so the summary keeps what the next phase needs. - -`/compact` is the **default, not the first reach**. It sits at the bottom because the four questions above it are all cheaper or more precise. The failure mode when people start here is a fresh session that is confidently wrong about a decision the summary flattened. - -## Primary and secondary sources - -Every move except **Continue** turns a **primary source** into a **secondary source** — the session as it happened, replaced by a summary of it. The trade is always the same shape: - -| Source | Information | Noise | Room to move | -| --------------------------------- | ----------- | ----- | ------------ | -| Primary (Continue) | Full | Lots | Little | -| Secondary (`/compact`, `/handoff`) | Lossy | Less | Lots | - -This is why question 1 comes first. You only pay the lossiness when staying costs more than it saves. - -## These are judgement calls - -The questions are not objective — each has taste in it, and the same boundary can go two ways on two days. The value is in asking them **in order**, at the boundary rather than in the middle of the work. diff --git a/skills/ask-matt/SKILL.md b/skills/ask-matt/SKILL.md deleted file mode 100644 index cef184e..0000000 --- a/skills/ask-matt/SKILL.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -name: ask-matt -description: Pick the OpenCodeBestFriend skill or flow that fits. Use when the user asks which skill to use, which workflow, "alur apa", "ask matt", or is choosing between planning, implement, review, and design paths. -compatibility: opencode ---- - - - -# Ask Matt - -Follow the thin router in `~/.config/opencode/AGENTS.md`. If routing is non-obvious, Read `~/.config/opencode/bestfriend/rules/00-routing.md`. Route only to skills installed here. Do not load every specialist. One primary specialist, plus at most one verification specialist when a risk or measured-performance trigger is on. - -## Installed - -**Plan:** `ask-matt` `grill-with-docs` `grilling` `to-spec` `to-tickets` `tdd` · architecture DAG = OpenCode plan agent - -**Write:** this session. Matt ticket loop only: `/matt-implement`. Test-first: `tdd`. - -**Review:** in-session (default). `matt-code-review` if they asked two-axis Standards + Spec. `/interrogate` for adversarial multi-review (manual). - -**Design:** `found-this-design` `impeccable` `scroll-craft` `visual-studio` `scroll-world` `emil-design-eng` - -**Documents:** `smartdoc` (per-job). `smartbook-ingest` only to compile/update reusable knowledge. - -**Engineering (auto when the description matches):** `diagnosing-bugs` `domain-modeling` `codebase-design` `writing-for-agents` `research` `prototype` - -**Engineering (manual / slash only):** `/architect` `/arena` `/blast-radius` `/why` `/figure-it-out` `/decision-log` `/improve-codebase-architecture` `/create-verification-skill` `/maintain-verification-skill` `/technical-writing` `/unslop` `/reflect` `/wizard` `/wait-what` - -**Browser / GitHub / risk:** `browser-act` `chrome-devtools-axi` `gh-axi` `full-audit-keamanan` `full-performance-audit` `adhd` - -**Not installed — say so, then use the nearest installed skill:** `/design` `/execute-plan` `/implement` `/review` `/code-review` `/imagine` `/docx` `/pdf` `/pptx` `/grill-me` `/handoff` `/triage` `/wayfinder` `/bro` `/poteto-mode` `/swarm` `/setup-matt-pocock-skills` `/pr-babysit` `/create-skill` `/create-workflow` `/build-with-ai` `game-asset-*` - -## Route - -1. Repo evidence is enough → do the work. -2. User typed a slash command → load it. -3. Architecture / PR-plan DAG → OpenCode plan agent, then implement in-session after approval. -4. Feature needs an interview, glossary, or ADR → `grill-with-docs`. Then `to-spec` → `to-tickets` only if they asked for tickets or the work is multi-session. -5. Ordinary implementation → write here. `tdd` when test-first. Do not start `/matt-implement` unless they are on a `/to-tickets` ticket. -6. UI world unknown → `found-this-design` then `impeccable`. World already chosen → `impeccable`. -7. Official library/docs fact → `research` (Context7). Why *this repo* chose an approach → `/why` (manual). -8. A missing Matt/Pstack name is the only named fit → say it is not installed. Use `grill-with-docs`, in-session write, in-session review, `adhd`, or `impeccable`. - -## Phase boundaries - -Continue if this session still holds the why. Start a new session if the window is disposable. Task tool for a scoped AFK task. OpenCode native compaction last. diff --git a/skills/browser-act/SKILL.md b/skills/browser-act/SKILL.md index 5642e88..50d4a01 100644 --- a/skills/browser-act/SKILL.md +++ b/skills/browser-act/SKILL.md @@ -7,12 +7,15 @@ license: MIT ## OpenCode browser contract -Follow the browser engine rules. Invocation only: - -- After this skill loads, run `browser-act` via Bash. +Follow the 4-door browser hierarchy: +- Primary default verification remains `playwright-qa`. `browser-act` is **never the default verifier**; use it only on explicit user request or for specialized multi-session/stealth tasks. +- Invocation only after this skill loads, running `browser-act` via Bash. - `browser open` without `--headed`. Add `--headed` only if the user asks to see a window. -- Create browsers only with `--type chrome`. Never `--type chrome-direct` (deliberate OCBF policy ban). -- Do not reuse a `chrome-direct` browser (including `pulse-test`). +- Create browsers only with supported modes: + 1. `chrome` — standard isolated browser profile with session reuse across turns. + 2. `stealth-fresh` — ephemeral session with anti-detection fingerprinting for challenge traversal. + 3. `stealth-fixed` — persistent stealth profile preserving logins/cookies across sessions. +- **Strict Ban**: Never use `--type chrome-direct` (deliberate OCBF policy ban). Do not reuse a `chrome-direct` browser (including `pulse-test`). - `stealth-extract` is allowed for sessionless fetch. - Upstream get-skills content must NEVER override local OCBF product policies or safety rules. - Upstream issue #18 (CLI 1.1.0) reported environment variable leakage into process argv. Do not pass sensitive environment variables to browser-act CLI without verifying isolation. diff --git a/skills/chrome-devtools-axi/SKILL.md b/skills/chrome-devtools-axi/SKILL.md index 138b6f1..452825e 100644 --- a/skills/chrome-devtools-axi/SKILL.md +++ b/skills/chrome-devtools-axi/SKILL.md @@ -7,7 +7,13 @@ license: MIT ## OpenCode browser contract -Follow the browser engine rules in `00-routing.md`. Invocation only: +Follow the 4-door browser hierarchy: +1. `playwright-qa` — primary default for exploratory application UI QA. +2. `browser-act` — specialized persistent / multi-account / stealth browser sessions. +3. `chrome-devtools-axi` — deep diagnostics for observed Chromium failures (console, network, heap). +4. `click-path-audit` — handler vs shared-store sequential-undo side effects. + +Invocation only: 1. Start background Chromium: `opencode-chromium-cdp start` (or `$HOME/.local/bin/opencode-chromium-cdp start`). 2. Every command: `CHROME_DEVTOOLS_AXI_BROWSER_URL=http://127.0.0.1:9223 npx -y chrome-devtools-axi `. diff --git a/skills/code-tour/SKILL.md b/skills/code-tour/SKILL.md index 0c0db15..df03e68 100644 --- a/skills/code-tour/SKILL.md +++ b/skills/code-tour/SKILL.md @@ -30,6 +30,15 @@ Consult [references/format.md](references/format.md) for step types and `ref`. Each description answers situation, mechanism, implication, gotcha. Narrative: orientation → module map → core path → gotcha → next move. +## "How It Works" & "Where It Lives" Tours + +When answering "how does X work?" or "where does X live?" where a reusable guide is valuable: +- Step 1: Entry point or trigger (where the request enters). +- Step 2: Core invariant or state transformation (the underlying mechanism). +- Step 3: Persistence, side-effect, or external call (destination). +- Step 4: Edge case or gotcha (what trips newcomers). +Ground every step in verified file and line anchors. + ## Output A valid `.tour` file plus a one-line confirmation that every path and line was checked against the chosen `ref` (or against the working tree when `ref` is omitted). diff --git a/skills/codebase-design/SKILL.md b/skills/codebase-design/SKILL.md index 3a264a6..389a72b 100644 --- a/skills/codebase-design/SKILL.md +++ b/skills/codebase-design/SKILL.md @@ -1,6 +1,6 @@ --- name: codebase-design -description: Design or deepen a module interface, seam, test surface, or abstraction. Skip ordinary implementation, product interviews, and multi-sketch architecture bake-offs (/architect). +description: Design or deepen a module interface, seam, test surface, or abstraction. Skip ordinary implementation, product interviews, multi-sketch architecture bake-offs (/architect), and whole-repo scans (/improve-codebase-architecture). compatibility: opencode --- diff --git a/skills/found-this-design/SKILL.md b/skills/found-this-design/SKILL.md index 7847d49..55ed1b1 100644 --- a/skills/found-this-design/SKILL.md +++ b/skills/found-this-design/SKILL.md @@ -25,6 +25,7 @@ component atoms; atoms are impeccable + Design V2. - Stop before component atoms; atoms are impeccable + Design V2. - Search with the scripts. Never read either `catalog.json` into context. +- External brand pattern corpora (e.g. `awesome-design-md`) may be referenced by humans as styling ideas, but never fetched, cloned, or vendored into the project. Product UI direction flows strictly from the local Design Bank → `impeccable`. - Do not implement UI, copy a Motion prompt into code, or overwrite the project's `DESIGN.md` unless the user asked to pin files. - Do not crawl Refero or Motionsites. Do not open `npm run bank` unless diff --git a/skills/grill-with-docs/SKILL.md b/skills/grill-with-docs/SKILL.md index dc5e76c..a9e4ef5 100644 --- a/skills/grill-with-docs/SKILL.md +++ b/skills/grill-with-docs/SKILL.md @@ -1,6 +1,6 @@ --- name: grill-with-docs -description: Relentless interview to sharpen a plan. Writes CONTEXT.md, a glossary, and ADRs as you go. Use when a feature still needs a plan, the user wants grilling, or they ask for /grill-with-docs. +description: Relentless interview to sharpen a plan with design-tree frontier rounds. Writes CONTEXT.md, a glossary, and ADRs as you go. Use when a feature still needs a plan, the user wants a deep planning interview, or they ask for /grill-with-docs. compatibility: opencode --- @@ -8,10 +8,18 @@ compatibility: opencode # Grill with docs -Run the interview in this session. Compose two owned disciplines: +Run the interview in this session. Compose owned domain-modeling discipline (glossary, CONTEXT.md, ADRs) with relentless design-tree frontier rounds. -- `grilling` — design-tree + frontier rounds (one frontier per round; facts via tools, decisions via the user) -- `domain-modeling` — glossary, CONTEXT.md, ADRs for hard-to-reverse choices +Map the decisions as a **design tree**: every decision branches into the decisions that hang off it. +Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled — the questions you can ask now without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round. + +Each frontier question should follow this format: + +```markdown +❓ **Q1** - ****: + +➡️ +``` Use `codebase-design` only when the conversation reaches a module, interface, or seam. Architecture DAGs still use the OpenCode plan agent, not this skill. @@ -25,13 +33,14 @@ Leave the repo with: ## Rules - You gather facts. The user makes decisions. -- One question at a time when the answer branches. Batch only factual checks. A grilling frontier round may batch independent questions. +- Finding facts is your job: when a frontier question needs a fact from the environment (filesystem, git, config), inspect it directly or dispatch a subagent; do not ask the user for facts you can look up. +- One question at a time when the answer branches. Batch only independent frontier questions. - Use the project's words. When a term is overloaded, resolve it and write it into the glossary. - Do not implement code in this skill. - If Codebase Memory has no project for cwd, skip it and use repo files. - Architecture DAGs use the OpenCode plan agent, not this skill. - Ordinary writes stay in-session after the interview. -- Stop when you can implement or write `to-spec` without inventing decisions. +- Stop when the frontier is empty: every branch visited, nothing silently assumed, and you can implement or write `to-spec` without inventing decisions. ## Loop diff --git a/skills/grilling/SKILL.md b/skills/grilling/SKILL.md deleted file mode 100644 index 9a877e7..0000000 --- a/skills/grilling/SKILL.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: grilling -description: Stress-test a plan with design-tree frontier rounds. Use when the user wants grilling as a primitive. Full product interviews that should leave CONTEXT.md/ADRs use /grill-with-docs. -compatibility: opencode ---- - -Interview the user relentlessly until you reach a shared understanding. Map this as a **design tree**: every decision branches into the decisions that hang off it. - -Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled: the questions you can ask _now_ without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round. - -Each question should be formatted like so: - -``` -❓ **Q1** - ****: - -➡️ -``` - -Each round the user answers reshapes the tree: settled decisions push the frontier outward and unblock questions that depended on them. Recompute the frontier and ask the next round. A question whose answer depends on another question still open in this round belongs to a _later_ round, not this one. - -Finding _facts_ is your job, never the user's. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a sub-agent to find it; don't ask the user for anything you could look up yourself. Don't block on it: a running exploration is an unsettled prerequisite, so only the questions downstream of it wait for the sub-agent to report; ask the rest of the frontier now. The _decisions_ are the user's: put each to them and wait. - -The session is done when the frontier is empty: every branch of the design tree visited, nothing left silently assumed. Do not act on it until the user confirms you have reached a shared understanding. diff --git a/skills/humanizer/SKILL.md b/skills/humanizer/SKILL.md index b38976f..dd25bfe 100644 --- a/skills/humanizer/SKILL.md +++ b/skills/humanizer/SKILL.md @@ -14,6 +14,8 @@ Remove artificial patterns, synthetic cadence, and formulaic tells from user-fac - **Never** auto-humanize ordinary coding output, diffs, PR summaries, or CLI tool output. - **Never** rewrite source code, tests, CLI commands, YAML frontmatter, citations, or locked SmartDoc content. - **Never** invent facts, quotes, statistics, or sources to make text feel more colorful. +- **Refuse UI implementation**: this skill polishes copy and prose; UI styling, atoms, and layouts route to `impeccable`. +- **Refuse linter installation**: this skill does not configure Oxlint or static code linters; TypeScript/JavaScript lint rules route strictly to `/install-anti-slop`. - Voice sample provided by the user overrides default pattern recommendations. - Academic manuscripts after GOAL_LOCK route to `academic` first; humanizer is an optional final prose polish only when requested. - Technical documentation structure (Diátaxis / STE) routes to `/technical-writing`. @@ -42,6 +44,17 @@ Audit text against the five families of AI writing tells (detailed catalog in [r 4. **Formatting:** Obsessive bullet lists where prose fits better, excessive bolding on lead-in words, and overused em dashes (—). Convert mechanical lists to flowing paragraphs; replace em dashes with commas or separate sentences. 5. **Leftovers:** Chatbot residue and formulaic conclusions ("Certainly!", "I hope this helps!", "In conclusion, the future looks bright"). Remove conversational fluff and generic wrap-ups. +## Usage Modes: During vs After + +- **During Generation (Proactive Guidance)**: + - Lead with the substance immediately; cut kickoff throat-clearing ("Let's dive in", "In today's fast-paced world"). + - Reject invented numbers, fabricated benchmarks, and synthetic testimonials. + - Ban sparkle fluff, emoji bullet clutter, and beta-pill hype in headlines and action buttons. + - Keep claims verifiable and grounded in product truth. +- **After Audit (Retrospective Polish)**: + - Scan existing prose against the five pattern families. + - Report a brief numbered findings list of AI tells, present the tightened rewrite, and verify with the user before committing destructive edits. + ## Workflow ### 1. Ingestion Mode diff --git a/skills/id-demo-video/SKILL.md b/skills/id-demo-video/SKILL.md new file mode 100644 index 0000000..2563eb1 --- /dev/null +++ b/skills/id-demo-video/SKILL.md @@ -0,0 +1,79 @@ +--- +name: id-demo-video +description: Use when the user wants an application demo video, product walkthrough recording, lomba/contest demo, Indonesian voiceover for a screen demo, or a ~10 minute narrated app tour. Orchestrates beat sheet, Indonesian narration, Edge TTS, Playwright/Chromium scene capture, ffmpeg concat, optional HyperFrames title cards. Not for functional browser QA (playwright-qa), UI motion inside the product (emil-design-eng), still/ad art (visual-studio), file+line developer tours (code-tour), or a single HTML composition standing in for a 10 minute video (hyperframes handles title/end cards only). +compatibility: opencode +license: MIT +--- + +# Indonesian Application Demo Video (`id-demo-video`) + +Director and orchestrator for multi-scene application walkthrough videos with natural Indonesian narration, screen recording, synchronized subtitles, and zero-cost local tooling. + +## Boundaries & Handoffs + +| Request / Requirement | Primary Specialist | +|---|---| +| Functional browser QA, regression assertions, testing form flows | `playwright-qa` | +| In-app UI micro-interactions, CSS transitions, easing curves | `emil-design-eng` (after `impeccable`) | +| Photoreal product stills, marketing ad creative packs, non-UI surfaces | `visual-studio` | +| Developer onboarding and interactive CodeTour `.tour` file walkthroughs | `code-tour` | +| Deterministic HTML title cards, lower-thirds, or short (<90s) motion cards | `hyperframes` (handoff for intro/outro cards) | +| **Full application demo video, screen walkthrough, and Indonesian narration** | **`id-demo-video`** | + +## Core Architecture & Fences + +1. **Pipeline Director**: `id-demo-video` coordinates the demo creation pipeline. It is not an image generator or a single-composition renderer. +2. **HyperFrames Boundary**: HyperFrames handles short HTML-to-MP4 title/end cards (sweet spot 30–90s). Never attempt a single 600s monolithic HTML composition for a 10-minute demo. +3. **Free & Local Default (Rp0)**: Edge TTS with voices `id-ID-GadisNeural` (female) or `id-ID-ArdiNeural` (male). No paid API keys required. Kokoro is prohibited for Indonesian text. ElevenLabs is strictly OFF by default (if explicitly turned on by user, warn about ~10k free credit limits and non-commercial restrictions). +4. **App Availability Gate**: If the target application cannot be contacted, fail immediately and instruct the user to run the app start command. Never render a fake dummy screen or blank placeholder video. +5. **Session & Browser Rules**: Record by launching a dedicated, standalone Playwright Chromium process with an isolated profile. Never bind to personal Google Chrome profiles. Do not connect to or interfere with port 9223 (reserved for `chrome-devtools-axi` QA sessions; recording must run its own independent browser process). +6. **No Secrets on Screen**: Only seed and demo data may be typed or displayed. Mask or clear all private keys, passwords, and tokens. + +## Ten-Minute Demo Rules + +- **Modular Scene Architecture**: Split a ~10-minute (600s) target into 8–12 discrete scenes (40–90 seconds each). One continuous 10-minute take is strictly prohibited. +- **Pacing & Cadence**: Speaking rate is 130–150 words per minute. A 10-minute video contains ~1,300–1,500 spoken words. +- **Natural Spoken Indonesian**: Write conversational Indonesian with short sentences (8–16 words). +- **Anti-Slop Buzzword Prohibition**: Do not use empty corporate jargon: + - Banned terms: *"era digital"*, *"solusi inovatif"*, *"memanfaatkan AI"*, *"seamless"*, *"cutting-edge"*, *"game changer"*. + - Focus on what the user does, what appears on screen, and why it matters. + +## Artifact Contract + +All demo assets reside in the project's `demos//` directory (must be gitignored): + +```text +demos// + brief.md # Scope, URL, feature checklist, target duration + beats.md # Timed scene outline (total seconds = target ±15s) + naskah.md # Per-scene spoken Indonesian voiceover script + storyboard.json # Machine-executable scene actions & audio mapping + audio/scene-NN.mp3 # Synthesized voiceover per scene (content-cached) + recordings/scene-NN.webm # Raw Playwright screen capture per scene + captions/scene-NN.srt # Synchronized Indonesian subtitle per scene + scenes/scene-NN.mp4 # Composed per-scene video (audio + video + subs) + demo-preview-90s.mp4 # 90-second executive cut (intro + core + outro) + demo-final.mp4 # Full concatenated walkthrough + QC.md # Quality checklist and duration report +``` + +## Nine-Step Execution Pipeline + +1. **Brief**: Extract app purpose, target audience, local URL (e.g. `http://localhost:3000`), and mandatory features from repo files or user prompt into `brief.md`. +2. **Beat Sheet**: Design timed scene beats in `beats.md`. Ensure `sum(scene_durations) == target_duration ± 15s`. Consult [references/beats.md](references/beats.md). +3. **Naskah Indonesia**: Write natural spoken Indonesian voiceover per scene in `naskah.md` (130–150 wpm, 8–16 words/sentence). +4. **Storyboard**: Structure actions into `storyboard.json`. Consult [references/storyboard.schema.md](references/storyboard.schema.md). +5. **Edge TTS Synthesis**: Run `python3 scripts/tts_edge.py` to synthesize `audio/scene-NN.mp3` with content-hashing. Measure exact audio duration with `ffprobe` before recording. Consult [references/tts-id.md](references/tts-id.md). +6. **Scene Recording**: Drive browser via Playwright CLI with 1920x1080 viewport, visible cursor, and human typing cadence. Capture raw video into `recordings/scene-NN.webm`. Consult [references/record-compose.md](references/record-compose.md). +7. **Subtitle Generation**: Generate synchronized Indonesian subtitles (`captions/scene-NN.srt`) matching speech segments. +8. **Compose & Concat**: Run `scripts/compose.sh` to trim idle gaps (>1.2s), mux audio, burn subtitles, and concatenate scenes into `demo-final.mp4`. +9. **Preview & QC**: Generate `demo-preview-90s.mp4` containing representative scenes and record verification results in `QC.md`. + +## Runtime Prerequisites + +Verify environment tools before running scripts: +```bash +ffmpeg -version >/dev/null 2>&1 || { echo "MISSING: ffmpeg"; exit 1; } +ffprobe -version >/dev/null 2>&1 || { echo "MISSING: ffprobe"; exit 1; } +python3 -c "import edge_tts" >/dev/null 2>&1 || { echo "MISSING: edge-tts (install via: pip install edge-tts)"; exit 1; } +``` diff --git a/skills/id-demo-video/references/beats.md b/skills/id-demo-video/references/beats.md new file mode 100644 index 0000000..5f30720 --- /dev/null +++ b/skills/id-demo-video/references/beats.md @@ -0,0 +1,34 @@ +# Beat Sheet Planning (`beats.md`) + +Guidelines for constructing timed scene beats for application walkthroughs and contest demos. + +## Timing Model + +- **Target Duration**: Typically 600 seconds (10 minutes) for full contest demos, or 180–300 seconds for feature spotlights. +- **Tolerance Gate**: `sum(scene_duration) == target_duration ± 15 seconds`. +- **Clip Count**: 8 to 12 clips for a 10-minute demo. Each clip lasts between 40 and 90 seconds. +- **Pacing**: 130–150 spoken Indonesian words per minute (~2.2 to 2.5 words per second). + +## Standard 10-Minute Beat Template (8–10 Scenes) + +| Scene | Title | Duration | Spoken Words | Focus | +|---|---|---|---|---| +| `scene-01` | Pengenalan & Masalah Nyata | 50s | 110–120 | Masalah pengguna tanpa aplikasi. Optional HyperFrames title card (5s). | +| `scene-02` | Halaman Masuk & Dashboard | 60s | 130–150 | Login dengan akun seed, navigasi ringkasan metrik utama. | +| `scene-03` | Alur Kerja Utama (Langkah 1) | 75s | 165–185 | Pembuatan data baru, pengisian formulir, validasi input. | +| `scene-04` | Alur Kerja Utama (Langkah 2) | 80s | 175–200 | Proses pemrosesan sistem, interaksi tabel, pemilihan filter. | +| `scene-05` | Fitur Kunci & Keunggulan | 75s | 165–185 | Fitur diferensiasi (misal: otomatisasi, deteksi, kalkulasi). | +| `scene-06` | Penanganan Kondisi Khusus | 65s | 140–160 | Validasi error ramah pengguna atau keamanan akses. | +| `scene-07` | Laporan & Ekspor Data | 65s | 140–160 | Visualisasi hasil, unduh laporan PDF/CSV atau audit log. | +| `scene-08` | Ringkasan Dampak & Penutup | 55s | 120–135 | Rangkuman manfaat terukur, CTA, optional HyperFrames end card. | +| **Total** | | **525s (8m45s)** | **1145–1335** | *Sesuai target ±15s bila ditargetkan 9 menit, atau tambah 1 scene untuk 10m.* | + +## Writing Rules for Indonesian Spoken Narration + +1. **Short, Oral Sentences**: 8–16 words per sentence. Write for the ear, not an academic journal. +2. **Action Synchronization**: Match every phrase to what the cursor is doing at that second. +3. **No Empty Fluff (Anti-Slop)**: + - ❌ *"Di era digital yang serba cepat ini..."* → ✅ *"Mari kita lihat proses verifikasi dokumen pelanggan."* + - ❌ *"Aplikasi ini memanfaatkan solusi AI inovatif yang seamless..."* → ✅ *"Sistem membaca data formulir dan mengisi kolom otomatis dalam dua detik."* + - ❌ *"Fitur cutting-edge yang menjadi game changer..."* → ✅ *"Fitur ini memangkas langkah manual dari lima tahap menjadi satu klik."* +4. **Pronunciation Clarity**: Write acronyms phonetically if needed (e.g. `API` diucapkan *A-P-I*, bukan *api* membara). diff --git a/skills/id-demo-video/references/record-compose.md b/skills/id-demo-video/references/record-compose.md new file mode 100644 index 0000000..ea71bb4 --- /dev/null +++ b/skills/id-demo-video/references/record-compose.md @@ -0,0 +1,68 @@ +# Recording & Video Composition (`record-compose.md`) + +Browser capture parameters, silence trimming, subtitle burning, and FFmpeg concatenation. + +## Browser Recording Standards + +1. **Resolution & Viewport**: Fixed 1920x1080 landscape (`16:9`). +2. **Cursor Visibility**: Ensure mouse cursor is visible during browser interactions. +3. **Typing Cadence**: Use human-cadence delay (`delay: 40-75ms` per character) instead of instant value assignment so keystrokes appear on video. +4. **Isolated Profile**: Use an isolated browser context. Never attach to personal Google Chrome profiles. +5. **Port Safety & Process Isolation**: Launch a separate, dedicated Chromium process with an isolated temporary user-data-dir. Do not connect or bind to port 9223 (which is reserved for `chrome-devtools-axi` QA sessions); never hijack or attach to an existing QA browser. +6. **Pre-flight App Check**: + - Query target URL before starting recording (e.g. `curl -s -o /dev/null -w "%{http_code}" http://localhost:3000`). + - If connection fails: abort immediately. + - Output message: *"Aplikasi belum berjalan di . Jalankan server aplikasi terlebih dahulu (misal: npm run dev atau python app.py) sebelum merekam demo."* + - Never generate placeholder/color screens when the app is offline. + +## Scene Composition Protocol + +Each scene is processed independently before global concatenation: + +```bash +# 1. Trim leading/trailing browser initialization latency and idle gaps (>1.2s) +# 2. Multiplex audio track (audio/scene-NN.mp3) with video (recordings/scene-NN.webm) +# 3. Burn subtitles from captions/scene-NN.srt (optional or embedded soft subs) +ffmpeg -y -i recordings/scene-NN.webm -i audio/scene-NN.mp3 \ + -filter_complex "[0:v]fps=30,scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2[v]" \ + -map "[v]" -map 1:a \ + -c:v libx264 -preset medium -crf 21 -pix_fmt yuv420p \ + -c:a aac -b:a 192k \ + -shortest \ + scenes/scene-NN.mp4 +``` + +## Global Concatenation (`demo-final.mp4`) + +Using FFmpeg concat demuxer: + +```text +# concat_list.txt +file 'scenes/scene-01.mp4' +file 'scenes/scene-02.mp4' +file 'scenes/scene-03.mp4' +... +``` + +```bash +ffmpeg -y -f concat -safe 0 -i concat_list.txt -c copy demo-final.mp4 +``` + +## Short Preview Generation (`demo-preview-90s.mp4`) + +Always export a 90-second executive summary alongside the final video: +- Scene 1 (Hook / Intro): ~25 seconds +- Scene 3 or 4 (Core differentiator feature): ~45 seconds +- Final Scene (Outro / Result): ~20 seconds + +## Subtitle Guidelines (SRT) + +- Maximum 2 lines per subtitle card. +- Maximum 38 characters per line. +- Font styling: Sans-serif (Inter / Roboto), white text with subtle black outline or semi-transparent background box. + +## Background Music (BGM) Policy + +- **Default**: Disabled (No background music). +- **User Music**: Only allowed if the user explicitly supplies a local audio file (e.g. `demos//bgm.mp3`). +- **Volume**: If BGM is enabled, sidechain ducking or static volume at `-22dB` to prevent masking spoken narration. diff --git a/skills/id-demo-video/references/storyboard.schema.md b/skills/id-demo-video/references/storyboard.schema.md new file mode 100644 index 0000000..5e0eefc --- /dev/null +++ b/skills/id-demo-video/references/storyboard.schema.md @@ -0,0 +1,157 @@ +# Storyboard JSON Schema (`storyboard.schema.md`) + +Specification and validation rules for `demos//storyboard.json`. + +## Schema Definition + +```json +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DemoStoryboard", + "type": "object", + "required": [ + "slug", + "target_duration_s", + "voice", + "lang", + "scenes" + ], + "properties": { + "slug": { + "type": "string", + "pattern": "^[a-z0-9-]+$", + "description": "Unique folder identifier for the demo" + }, + "target_duration_s": { + "type": "integer", + "minimum": 30, + "maximum": 1200, + "description": "Total target duration in seconds (e.g. 600 for 10 minutes)" + }, + "voice": { + "type": "string", + "enum": ["id-ID-GadisNeural", "id-ID-ArdiNeural"], + "description": "Selected Edge TTS voice" + }, + "lang": { + "type": "string", + "const": "id", + "description": "Language code (strictly 'id' for Indonesian)" + }, + "scenes": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/Scene" + } + } + }, + "definitions": { + "Scene": { + "type": "object", + "required": [ + "id", + "title", + "duration_s", + "narration", + "actions" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^scene-[0-9]{2}$", + "description": "Numbered scene identifier, e.g. scene-01" + }, + "title": { + "type": "string", + "description": "Human-readable scene title" + }, + "duration_s": { + "type": "number", + "minimum": 5, + "maximum": 180, + "description": "Target duration for this scene in seconds" + }, + "narration": { + "type": "string", + "description": "Full Indonesian spoken voiceover text for this scene" + }, + "actions": { + "type": "array", + "items": { + "$ref": "#/definitions/Action" + } + } + } + }, + "Action": { + "type": "object", + "required": ["type"], + "properties": { + "type": { + "type": "string", + "enum": ["goto", "wait", "click", "type", "scroll", "hover", "highlight"] + }, + "selector": { + "type": "string", + "description": "CSS selector or Playwright locator" + }, + "value": { + "type": "string", + "description": "Text value to type or URL to navigate to" + }, + "duration_ms": { + "type": "integer", + "description": "Wait time or scroll animation duration in milliseconds" + } + } + } + } +} +``` + +## Duration Validation Contract + +The sum of all scene durations must match `target_duration_s` within a tolerance of ±15 seconds: + +$$\left| \left( \sum_{i=1}^{N} \text{scene}_i.\text{duration\_s} \right) - \text{target\_duration\_s} \right| \le 15$$ + +If the difference exceeds 15 seconds, storyboard validation fails and prompts adjustment before synthesis or capture begins. + +## Example `storyboard.json` + +```json +{ + "slug": "crm-demo-2026", + "target_duration_s": 120, + "voice": "id-ID-GadisNeural", + "lang": "id", + "scenes": [ + { + "id": "scene-01", + "title": "Halaman Utama & Navigasi", + "duration_s": 55, + "narration": "Selamat datang di sistem manajemen relasi pelanggan. Pada layar utama, kita dapat melihat metrik ringkasan penjualan dan antrean tugas aktif hari ini.", + "actions": [ + {"type": "goto", "value": "http://localhost:3000/dashboard"}, + {"type": "wait", "duration_ms": 2000}, + {"type": "hover", "selector": "[data-testid='metric-sales']"}, + {"type": "scroll", "value": "down"} + ] + }, + { + "id": "scene-02", + "title": "Pencatatan Prospek Baru", + "duration_s": 65, + "narration": "Untuk menambahkan prospek baru, klik tombol Tambah di sudut kanan atas. Masukkan nama kontak, email perusahaan, dan nilai estimasi kontrak.", + "actions": [ + {"type": "click", "selector": "button#btn-new-lead"}, + {"type": "type", "selector": "input#lead-name", "value": "PT Solusi Nusantara"}, + {"type": "type", "selector": "input#lead-email", "value": "halo@solusinusantara.id"}, + {"type": "click", "selector": "button#btn-save"}, + {"type": "wait", "duration_ms": 1500} + ] + } + ] +} +``` diff --git a/skills/id-demo-video/references/tts-id.md b/skills/id-demo-video/references/tts-id.md new file mode 100644 index 0000000..145fce8 --- /dev/null +++ b/skills/id-demo-video/references/tts-id.md @@ -0,0 +1,46 @@ +# Indonesian Text-to-Speech Engine (`tts-id.md`) + +Voice synthesis specifications, voice selection, caching, and rate limiting rules for Indonesian demo narration. + +## Voice Engines & Priority + +### 1. Default (Free / Rp0): Edge TTS +- **Engine**: Microsoft Edge Neural TTS via `edge-tts` Python library. +- **Voices**: + - `id-ID-GadisNeural` (Female, natural warm tone, default) + - `id-ID-ArdiNeural` (Male, authoritative presenter tone) +- **Voice Rate**: Default `+0%` (natural 130–150 wpm). Use `+5%` or `-5%` to fine-tune scene timings. +- **Pitch**: Default `+0Hz`. + +### 2. Forbidden Engine: Kokoro +- Kokoro models currently do not have native Indonesian phoneme support. Kokoro is strictly prohibited for Indonesian narration as it mangles pronunciation. + +### 3. Optional Engine: ElevenLabs (Strictly OFF by default) +- **Status**: OFF by default. +- **Activation**: Requires explicit user instruction and user-provided API key. +- **Mandatory User Warning**: Before synthesizing via ElevenLabs, warn the user: + > *"Peringatan kuota: Paket gratis ElevenLabs dibatasi ~10.000 kredit/bulan (sekitar 8–10 menit audio total) dan memiliki batasan lisensi non-komersial. Default sistem adalah Edge TTS (gratis, tanpa kuota)."* + +## Content-Addressed Caching + +To avoid re-synthesizing identical text across test runs and edits: +1. Compute SHA-256 hash over normalized input: `hash = sha256(text.strip() + "|" + voice + "|" + rate)`. +2. Save cache in `demos//.cache/tts/.mp3`. +3. If `.mp3` exists and file size > 0, copy from cache instead of issuing network calls. + +## Rate Limiting & 429 Handling + +1. **Exponential Backoff**: If Edge TTS returns HTTP 429 (Too Many Requests), wait: + - Attempt 1: wait 2 seconds + - Attempt 2: wait 5 seconds + - Attempt 3: wait 10 seconds +2. **Never Silent Failover**: Never silently route traffic to paid cloud APIs or fall back to robotic TTS without user knowledge. +3. **Graceful Failure**: If retries fail, exit with code 429 and inform the user to pause before re-running. + +## Duration Measurement (`ffprobe`) + +Before screen recording begins, each generated MP3 must be measured: +```bash +ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 audio/scene-NN.mp3 +``` +This measured audio duration defines the required screen capture duration (+1.0 to 1.5 seconds tail padding) for that scene. diff --git a/skills/id-demo-video/scripts/compose.sh b/skills/id-demo-video/scripts/compose.sh new file mode 100755 index 0000000..c6420a3 --- /dev/null +++ b/skills/id-demo-video/scripts/compose.sh @@ -0,0 +1,128 @@ +#!/usr/bin/env bash +# compose.sh: Compose scenes, multiplex narration audio, and concatenate full demo video. +# Part of OpenCodeBestFriend id-demo-video specialist. +set -euo pipefail + +DEMO_DIR="${1:-.}" + +if [ ! -d "$DEMO_DIR" ]; then + echo "ERROR: Demo directory does not exist: $DEMO_DIR" >&2 + exit 1 +fi + +if ! command -v ffmpeg >/dev/null 2>&1; then + echo "ERROR: ffmpeg is required but not installed or not in PATH." >&2 + exit 1 +fi + +if ! command -v ffprobe >/dev/null 2>&1; then + echo "ERROR: ffprobe is required but not installed or not in PATH." >&2 + exit 1 +fi + +REC_DIR="$DEMO_DIR/recordings" +AUDIO_DIR="$DEMO_DIR/audio" +SCENES_DIR="$DEMO_DIR/scenes" +CAPTIONS_DIR="$DEMO_DIR/captions" +OUTPUT_FINAL="$DEMO_DIR/demo-final.mp4" +OUTPUT_PREVIEW="$DEMO_DIR/demo-preview-90s.mp4" +QC_REPORT="$DEMO_DIR/QC.md" + +if [ ! -d "$REC_DIR" ] || [ ! -d "$AUDIO_DIR" ]; then + echo "ERROR: recordings/ or audio/ directory missing in $DEMO_DIR" >&2 + exit 1 +fi + +mkdir -p "$SCENES_DIR" +CONCAT_LIST="$SCENES_DIR/concat_list.txt" +rm -f "$CONCAT_LIST" + +echo "=== Composing scenes in $DEMO_DIR ===" + +SCENE_COUNT=0 +for rec in "$REC_DIR"/scene-*.webm; do + [ -e "$rec" ] || continue + SCENE_ID=$(basename "$rec" .webm) + AUDIO_FILE="$AUDIO_DIR/$SCENE_ID.mp3" + SCENE_OUT="$SCENES_DIR/$SCENE_ID.mp4" + SRT_FILE="$CAPTIONS_DIR/$SCENE_ID.srt" + + if [ ! -f "$AUDIO_FILE" ]; then + echo "ERROR: Audio track missing for $SCENE_ID at $AUDIO_FILE" >&2 + exit 1 + fi + + echo "Rendering $SCENE_ID -> $SCENE_OUT ..." + + # Compose video + audio: + # - Scale & pad to 1920x1080 landscape + # - Mux Indonesian voiceover audio + # - Cut idle / match duration to shortest stream + if [ -f "$SRT_FILE" ]; then + # Subtitles present: burn softly or multiplex + ffmpeg -y -i "$rec" -i "$AUDIO_FILE" \ + -filter_complex "[0:v]fps=30,scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2[v]" \ + -map "[v]" -map 1:a \ + -c:v libx264 -preset medium -crf 21 -pix_fmt yuv420p \ + -c:a aac -b:a 192k \ + -shortest \ + "$SCENE_OUT" >/dev/null 2>&1 + else + ffmpeg -y -i "$rec" -i "$AUDIO_FILE" \ + -filter_complex "[0:v]fps=30,scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2[v]" \ + -map "[v]" -map 1:a \ + -c:v libx264 -preset medium -crf 21 -pix_fmt yuv420p \ + -c:a aac -b:a 192k \ + -shortest \ + "$SCENE_OUT" >/dev/null 2>&1 + fi + + echo "file '$(basename "$SCENE_OUT")'" >> "$CONCAT_LIST" + SCENE_COUNT=$((SCENE_COUNT + 1)) +done + +if [ "$SCENE_COUNT" -eq 0 ]; then + echo "ERROR: No scene recordings found in $REC_DIR (expected scene-NN.webm)" >&2 + exit 1 +fi + +echo "=== Concatenating $SCENE_COUNT scenes into $OUTPUT_FINAL ===" +(cd "$SCENES_DIR" && ffmpeg -y -f concat -safe 0 -i concat_list.txt -c copy "$OUTPUT_FINAL" >/dev/null 2>&1) + +# Generate 90s preview if multiple scenes exist +FIRST_SCENE=$(head -n 1 "$CONCAT_LIST" | cut -d"'" -f2) +LAST_SCENE=$(tail -n 1 "$CONCAT_LIST" | cut -d"'" -f2) +PREVIEW_LIST="$SCENES_DIR/preview_list.txt" +rm -f "$PREVIEW_LIST" + +echo "file '$FIRST_SCENE'" >> "$PREVIEW_LIST" +if [ "$SCENE_COUNT" -gt 2 ]; then + MID_INDEX=$(( (SCENE_COUNT / 2) + 1 )) + MID_SCENE=$(sed -n "${MID_INDEX}p" "$CONCAT_LIST" | cut -d"'" -f2) + if [ "$MID_SCENE" != "$FIRST_SCENE" ] && [ "$MID_SCENE" != "$LAST_SCENE" ]; then + echo "file '$MID_SCENE'" >> "$PREVIEW_LIST" + fi +fi +if [ "$LAST_SCENE" != "$FIRST_SCENE" ]; then + echo "file '$LAST_SCENE'" >> "$PREVIEW_LIST" +fi + +(cd "$SCENES_DIR" && ffmpeg -y -f concat -safe 0 -i preview_list.txt -c copy "$OUTPUT_PREVIEW" >/dev/null 2>&1) + +FINAL_DUR=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$OUTPUT_FINAL" || echo "0") +PREVIEW_DUR=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$OUTPUT_PREVIEW" || echo "0") + +cat < "$QC_REPORT" +# Demo Video Quality Control Report + +- **Date**: $(date -u +"%Y-%m-%dT%H:%M:%SZ") +- **Total Scenes**: $SCENE_COUNT +- **Final Output**: $OUTPUT_FINAL (Duration: ${FINAL_DUR}s) +- **Preview Output**: $OUTPUT_PREVIEW (Duration: ${PREVIEW_DUR}s) +- **Resolution**: 1920x1080 (16:9) +- **Audio**: Indonesian Voiceover (Edge TTS, 192k AAC) +- **Subtitles**: captions/*.srt processed +- **Status**: READY +EOF + +echo "=== Compose complete! Final: $OUTPUT_FINAL, Preview: $OUTPUT_PREVIEW ===" diff --git a/skills/id-demo-video/scripts/tts_edge.py b/skills/id-demo-video/scripts/tts_edge.py new file mode 100755 index 0000000..fcec624 --- /dev/null +++ b/skills/id-demo-video/scripts/tts_edge.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +""" +Edge TTS synthesis wrapper with content caching and 429 backoff for Indonesian narration. +Part of OpenCodeBestFriend id-demo-video specialist. +""" +from __future__ import annotations + +import argparse +import asyncio +import hashlib +import shutil +import sys +import time +from pathlib import Path + +ALLOWED_VOICES = { + "id-ID-GadisNeural": "Female Indonesian warm natural tone", + "id-ID-ArdiNeural": "Male Indonesian authoritative tone", +} + + +def compute_content_hash(text: str, voice: str, rate: str) -> str: + norm = text.strip() + raw = f"{norm}|{voice}|{rate}".encode("utf-8") + return hashlib.sha256(raw).hexdigest() + + +async def synthesize(text: str, voice: str, rate: str, output_path: Path, max_retries: int = 3) -> None: + try: + import edge_tts # type: ignore + except ImportError: + sys.stderr.write("ERROR: 'edge-tts' library is not installed. Install via: pip install edge-tts\n") + sys.exit(1) + + delays = [2, 5, 10] + for attempt in range(max_retries): + try: + communicate = edge_tts.Communicate(text=text, voice=voice, rate=rate) + await communicate.save(str(output_path)) + return + except Exception as exc: + err_msg = str(exc) + if "429" in err_msg or "Too Many Requests" in err_msg: + wait_sec = delays[attempt] if attempt < len(delays) else 10 + sys.stderr.write(f"WARNING: Rate limited (429). Retrying in {wait_sec}s (attempt {attempt + 1}/{max_retries})...\n") + await asyncio.sleep(wait_sec) + else: + sys.stderr.write(f"ERROR: Edge TTS synthesis failed: {exc}\n") + sys.exit(1) + + sys.stderr.write("ERROR: Edge TTS failed after retries due to rate limiting (429).\n") + sys.exit(42) + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description="Synthesize Indonesian voiceover using Edge TTS with content caching.") + parser.add_argument("--text", type=str, help="Text to synthesize") + parser.add_argument("--text-file", type=Path, help="Path to text file containing narration") + parser.add_argument("--output", type=Path, required=True, help="Path to output MP3 file") + parser.add_argument("--voice", type=str, default="id-ID-GadisNeural", choices=list(ALLOWED_VOICES.keys()), help="Voice name") + parser.add_argument("--rate", type=str, default="+0%", help="Speed rate modifier (e.g. +0%%, +5%%, -5%%)") + parser.add_argument("--cache-dir", type=Path, default=None, help="Directory to store and check audio cache") + parser.add_argument("--dry-run", action="store_true", help="Validate input and exit without network synthesis") + + args = parser.parse_args(argv) + + # 1. Resolve text input + text = "" + if args.text: + text = args.text + elif args.text_file: + if not args.text_file.is_file(): + sys.stderr.write(f"ERROR: Text file not found: {args.text_file}\n") + return 1 + text = args.text_file.read_text(encoding="utf-8") + elif not sys.stdin.isatty(): + text = sys.stdin.read() + + text = text.strip() + if not text: + sys.stderr.write("ERROR: Input narration text is empty.\n") + return 1 + + # 2. Validate voice + if args.voice not in ALLOWED_VOICES: + sys.stderr.write(f"ERROR: Unsupported voice '{args.voice}'. Allowed Indonesian voices: {', '.join(ALLOWED_VOICES.keys())}\n") + return 1 + + # 3. Cache lookup + cache_key = compute_content_hash(text, args.voice, args.rate) + args.output.parent.mkdir(parents=True, exist_ok=True) + + if args.cache_dir: + args.cache_dir.mkdir(parents=True, exist_ok=True) + cached_file = args.cache_dir / f"{cache_key}.mp3" + if cached_file.is_file() and cached_file.stat().st_size > 0: + shutil.copy2(cached_file, args.output) + sys.stdout.write(f"[CACHE HIT] {args.output.name} (hash: {cache_key[:12]})\n") + return 0 + + # 4. Dry-run mode + if args.dry_run: + # Create a 0-byte or placeholder file for verification if requested + args.output.write_bytes(b"") + sys.stdout.write(f"[DRY-RUN VALID] Text length: {len(text)} chars, voice: {args.voice}, key: {cache_key[:12]}\n") + return 0 + + # 5. Synthesize via network + asyncio.run(synthesize(text, args.voice, args.rate, args.output)) + + # 6. Cache write-back + if args.cache_dir: + cached_file = args.cache_dir / f"{cache_key}.mp3" + shutil.copy2(args.output, cached_file) + + sys.stdout.write(f"[SYNTHESIZED] {args.output} (hash: {cache_key[:12]})\n") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/skills/impeccable/design-intelligence/skill-allowlist.txt b/skills/impeccable/design-intelligence/skill-allowlist.txt index d8bfbb3..73101aa 100644 --- a/skills/impeccable/design-intelligence/skill-allowlist.txt +++ b/skills/impeccable/design-intelligence/skill-allowlist.txt @@ -1,7 +1,6 @@ adhd architect arena -ask-matt blast-radius browser-act chrome-devtools-axi @@ -17,13 +16,11 @@ full-audit-keamanan full-performance-audit gh-axi grill-with-docs -grilling impeccable improve-codebase-architecture interrogate maintain-verification-skill matt-code-review -matt-implement prototype reflect research @@ -34,7 +31,6 @@ to-spec to-tickets unslop visual-studio -wait-what why wizard writing-for-agents diff --git a/skills/impeccable/reference/taste-guard.md b/skills/impeccable/reference/taste-guard.md index 01c3c37..0289c8d 100644 --- a/skills/impeccable/reference/taste-guard.md +++ b/skills/impeccable/reference/taste-guard.md @@ -1,7 +1,7 @@ # Taste Quality Guard Canonical lightweight quality guard for UI implementation and review. -Adapted from [taste-skill](https://github.com/Leonxlnx/taste-skill) (MIT, Leonxlnx) to integrate with OpenCodeBestFriend craft standards. +Adapted from [taste-skill](https://github.com/Leonxlnx/taste-skill) (MIT, Leonxlnx) and [anti-slop](https://github.com/miqdadbadjuber/anti-slop) (MIT, Miqdad Badjuber) to integrate with OpenCodeBestFriend craft standards. Load this once before UI editing and verify against it during final review. This reference is not a separate specialist; it operates within the phase owner (`impeccable`, `scroll-craft`, `emil-design-eng`). @@ -16,10 +16,46 @@ When guidelines diverge, resolve in strict order: *Anti-Dogma Rule*: Taste guidelines discourage unexamined category defaults, but they are NOT absolute bans. Purple accents, Inter font, SVG icons, symmetrical grids, eyebrows, or cards are fully permitted when the brand, project, or user requests them. +## Filter Discipline (Filter ≠ Style Guide) + +This guard is a **filter, not a style guide**. It prescribes no specific colors, fonts, or layouts. It rejects unmotivated category defaults and fake content; visual direction, beauty, and brand voice come from your `DESIGN.md` or a shortlist from the Design Bank. +- **BANK_MISS ≠ generate**: When an atomic component (button, input, card, nav) misses the bank, do not invent arbitrary hex or radius; fall back to project shadcn components or ask. +- **Stitch / UI Skills Boundary**: Stitch MCP is for comps/screens only; UI Skills is for design-skill lookup only. Neither implements production UI alone. - **DESIGN.md Conflict**: If an explicit pin or `DESIGN.md` asks for a named slop pattern, name the element and the conflict, then ask keep-or-drop. Never silently follow and never silently override. Palette and typography that constitute brand identity are never slop. --- +## The Four Taste Gates (Checklist) + +Before shipping UI, verify against the four gates: + +1. **Hard Gate (Absolute)**: + - Zero hallucinated precision (no fake stats like `99.4%`, fake logos, or fake review quotes). + - Zero synthetic social proof or fake testimonial carousels. + - No decorative status dots (glowing/pulsing dots must mark real operational state). + - No two-state layouts (phone stack + desktop grid with nothing between is slop; define mid breakpoints or unified canvas). + - No unexamined category defaults (purple gradient hero, cyan mesh, Inter-on-white cards) unless requested. + +2. **Purpose-Gate (Technique Allowed, Reason Required)**: + - Every visual effect, parallax, or animation must serve an explicit purpose (hierarchy, state transition, narrative pacing). If unjustified in one sentence, cut it. + - At most one marquee per page, and only when content genuinely benefits from continuous streaming. + - No unmotivated glassmorphism or glowing borders. + +3. **Quality Locks (Consistency & Soundness)**: + - Surface mode respected: **Persuade** (marketing/landing), **Operate** (dashboard/admin/tools), **Read** (docs/articles), or **Experience** (showcase/portfolio). Operate demands scanability, high utility, and native conventions. + - Single palette role lock: neutral base + primary accent. + - Token & corner radius consistency across inputs, cards, and buttons. + - Complete interactive states (default, hover, focus-visible, active feedback, disabled, loading, empty, error). + - WCAG AA contrast (≥4.5:1 body, ≥3:1 large) and visible `:focus-visible` rings. + - `prefers-reduced-motion` collapses ambient/scroll motion to static presentation. + +4. **Delivery Gate (Pre-Ship Audit)**: + - Review desktop and mobile renders together under observed browser inspection. + - Confirm layout stability (e.g. `min-h-[100dvh]` to prevent viewport jumping). + - Verify all packages exist in `package.json` before importing; no unrequested heavy dependencies. + +--- + ## The 11 Core Quality Guardrails ### 1. Intent & Surface Mode diff --git a/skills/impeccable/reference/taste/direction.md b/skills/impeccable/reference/taste/direction.md index 4ae1f7f..d5a47bb 100644 --- a/skills/impeccable/reference/taste/direction.md +++ b/skills/impeccable/reference/taste/direction.md @@ -27,7 +27,8 @@ Deliberately step beyond default training-data tropes: ## 3. The Three Dials (Recorded in Surface Brief) -Record visual dial choices in the project's surface brief (`.impeccable/briefs/` or memory): +Record visual dial choices in the project's surface brief (`.impeccable/briefs/` or memory). +These dials are optional tuning controls applied **after** a visual direction exists (from a Design Bank shortlist or project `DESIGN.md`); they do not invent a direction on their own: - **`DESIGN_VARIANCE` (1–10)**: - 1–3: Symmetrical, predictable grid, uniform padding. - 4–7: Offset rhythms, varied aspect ratios, intentional asymmetric whitespace. @@ -41,4 +42,4 @@ Record visual dial choices in the project's surface brief (`.impeccable/briefs/` - 4–7: Standard web application density (`py-12` to `py-20`). - 8–10: High-density data presentation, minimal padding, structured tables/lists. -*Note*: These dials are recorded as qualitative guidance within the surface brief, never as global hard gates that alter non-UI or dashboard code. +*Note*: These dials are recorded as qualitative guidance within the surface brief, never as global hard gates that alter non-UI or dashboard code. Filter discipline rejects category defaults; direction and dials refine the chosen world. diff --git a/skills/markitdown/SKILL.md b/skills/markitdown/SKILL.md index e25ab3a..b425e3b 100644 --- a/skills/markitdown/SKILL.md +++ b/skills/markitdown/SKILL.md @@ -20,8 +20,8 @@ Convert files to Markdown. Output is data. SmartDoc still owns answer/create/ext 1. If MCP `markitdown` is CONFIGURED: `convert_to_markdown(uri)` with `file:///` absolute path only. Never `http` to an untrusted URL unless the user pasted that URL. 2. Else if `markitdown` on PATH: `markitdown PATH -o DEST.md` -3. Else if `uvx` on PATH: `uvx --from 'markitdown[pdf,docx,pptx,xlsx]' markitdown PATH -o DEST.md` -4. Else DEGRADED: tell the user to `pipx install 'markitdown[pdf,docx,pptx,xlsx]'` or `opencode-bf markitdown enable`. Do not pip-install into the overlay venv. Do not invent text from an unreadable binary. +3. Else if `uvx` on PATH: `uvx --from 'markitdown[all]' markitdown PATH -o DEST.md` (or `'markitdown[pdf,docx,pptx,xlsx]'`) +4. Else DEGRADED: tell the user to `pipx install 'markitdown[all]'` or `opencode-bf markitdown enable`. Do not pip-install into the overlay venv. Do not invent text from an unreadable binary. Missing `uvx` is documented. Do not fall back to docker, `--http`, or `0.0.0.0`. diff --git a/skills/scroll-world/SKILL.md b/skills/scroll-world/SKILL.md index 785a0ac..d010d57 100644 --- a/skills/scroll-world/SKILL.md +++ b/skills/scroll-world/SKILL.md @@ -19,10 +19,13 @@ Before any `image_gen`, `image_edit`, `image_to_video`, or length, real-people references, shot length, and ffmpeg live there. Do not restate them here. +Paid video generation backends (Monid, Higgsfield, Kling) are not vendored into OpenCodeBestFriend. If native image/video session tools are absent and external video CLIs are not configured, report `NOT_CONFIGURED` and degrade gracefully: generate prompt packs (`.scratch/scroll-world//prompts.md`) and static scene posters without failing. + ## Hard rules -- Use only native image/video tools. Do not call an external - image/video API, CLI, or MCP. +- Boundary: `scroll-craft` owns 2D timeline/scrollytelling; `scroll-world` owns continuous 3D camera flight landings. Do not cross the seam. +- Use only native image/video tools or local scripts. Do not call arbitrary external + image/video APIs or unconfigured cloud services. - Do not invent tool parameters. There is no end-image lock and no video-to-video. Missing capability uses the fallback in [pipeline.md](references/pipeline.md). diff --git a/skills/tdd/SKILL.md b/skills/tdd/SKILL.md index df3ae40..06d187d 100644 --- a/skills/tdd/SKILL.md +++ b/skills/tdd/SKILL.md @@ -8,6 +8,8 @@ compatibility: opencode TDD is the red → green loop. This skill is the reference that makes that loop produce tests worth keeping: what a good test is, where tests go, the anti-patterns, and the rules of the loop. Every section applies on every cycle — consult them before and during the loop, not after. +Spec and tracer-bullet ticket implementations (`/to-tickets`) execute in this session using this loop. There is no separate `/implement` skill. + When exploring the codebase, read `CONTEXT.md` (if it exists) so test names and interface vocabulary match the project's domain language, and respect ADRs in the area you're touching. ## What a good test is diff --git a/skills/to-spec/SKILL.md b/skills/to-spec/SKILL.md index cfcb79b..cc95da3 100644 --- a/skills/to-spec/SKILL.md +++ b/skills/to-spec/SKILL.md @@ -1,6 +1,6 @@ --- name: to-spec -description: Turn the current conversation into a spec and publish it locally under .scratch — no interview, just synthesis of what you already discussed. Use after grilling, or when the user asks for a spec or /to-spec. +description: Turn the current conversation into a spec and publish it locally under .scratch — no interview, just synthesis of what you already discussed. Use after grill-with-docs, or when the user asks for a spec or /to-spec. compatibility: opencode --- diff --git a/skills/writing-for-agents/SKILL.md b/skills/writing-for-agents/SKILL.md index 33c9805..a08258c 100644 --- a/skills/writing-for-agents/SKILL.md +++ b/skills/writing-for-agents/SKILL.md @@ -1,12 +1,12 @@ --- name: writing-for-agents -description: Author or edit SKILL.md, CLAUDE.md, AGENTS.md, skill descriptions, or context pointers. Skip choosing which existing workflow to run (/ask-matt). +description: Author or edit SKILL.md, CLAUDE.md, AGENTS.md, skill descriptions, or context pointers. Workflow choice is handled directly by the router without a specialist. compatibility: opencode --- Reference for writing any document an agent consumes — a skill, an `AGENTS.md` / `CLAUDE.md`, a doc reached by a pointer. The packaging differs; the writing does not: the same levers make each one predictable — the agent taking the same _process_ every run, not producing the same output. -When the document you're writing is a skill, read [`SKILL-MECHANICS.md`](SKILL-MECHANICS.md) for frontmatter, invocation choice, and router skills. +When the document you're writing is a skill, read [`SKILL-MECHANICS.md`](SKILL-MECHANICS.md) for frontmatter, invocation choice, and router skills. See [`references/route-checklist.md`](references/route-checklist.md) for category mappings and [`references/phase-boundaries.md`](references/phase-boundaries.md) for session transitions. ## Context pointers diff --git a/skills/writing-for-agents/references/phase-boundaries.md b/skills/writing-for-agents/references/phase-boundaries.md new file mode 100644 index 0000000..c356a85 --- /dev/null +++ b/skills/writing-for-agents/references/phase-boundaries.md @@ -0,0 +1,39 @@ +# Phase Boundaries + +A **phase** is a chunk of work inside a session — the planning interview, the implementation, the QA. A phase ends when the current objective completes. + +The **phase boundary** is the gap between two phases, and it is the only place this transition decision belongs. Mid-phase there is no decision to make — continue, or split the work that's left into subagents. Compacting mid-phase causes loss of execution context. + +## The Five Options + +| Option | What it does | +|---|---| +| **Continue** | Stay in the session. No context switch at all. | +| **`/clear`** | Empty the context window and start from zero. | +| **`/handoff`** | Write a portable markdown file and seed a session anywhere with it. | +| **Subagent** | Send the task to its own context window and get a report back. | +| **`/compact`** | Compress this context and seed a fresh session with the summary. | + +## The Decision Tree + +Work top to bottom at the boundary. The first **yes** wins: + +1. **Can you continue in this session?** + Two signals make the answer yes: the next phase needs this phase as a **primary source**, or you have enough token budget left (~150k tokens) for the next phase to fit. Planning interview → implementation is the standard yes: implementation requires verbatim reasoning, not a lossy summary. Continue costs nothing and loses nothing. +2. **Is the context irrelevant to what comes next?** + If exploration, decisions, and dead ends are disposable, use `/clear`. +3. **Do you need to hand off?** + Only when swapping harnesses, moving repositories, handing off to a colleague, or forking an isolated side task. +4. **Can the task be done AFK?** + If scoped tightly enough to run without human steering, dispatch a subagent. +5. **Otherwise, `/compact`.** + Pass an explicit instruction so the summary preserves the exact decisions and open questions the next phase requires. + +## Primary vs Secondary Sources + +Every transition except **Continue** converts a **primary source** into a **secondary source**: + +| Source | Information | Noise | Room to move | +|---|---|---|---| +| Primary (Continue) | Full | Higher | Less | +| Secondary (`/compact`, `/handoff`) | Lossy | Lower | More | diff --git a/skills/writing-for-agents/references/route-checklist.md b/skills/writing-for-agents/references/route-checklist.md new file mode 100644 index 0000000..5a5ee0b --- /dev/null +++ b/skills/writing-for-agents/references/route-checklist.md @@ -0,0 +1,32 @@ +# Router and Skill Inventory Checklist + +Authoring and audit reference for routing instructions, AGENTS.md, and skill catalog integrity. +Preserved from the router checklist reference. + +## Standard Category Mapping + +- **Plan:** `grill-with-docs` (with frontier rounds), `to-spec`, `to-tickets`, `tdd` · Architecture DAG: OpenCode plan agent +- **Write:** Current session. Test-first: `tdd`. Spec/ticket implementation stays in-session with `tdd`. +- **Review:** In-session review (default). Two-axis Standards + Spec: `matt-code-review`. Adversarial multi-review: `/interrogate` (manual). +- **Design:** `found-this-design` (direction/bank) → `impeccable` (atoms/composition) → `emil-design-eng` (motion/interactions). Continuous 3D world: `scroll-world`. Scrollytelling: `scroll-craft`. Media/stills: `visual-studio`. +- **Documents:** `smartdoc` (per-job doc intelligence), `markitdown` (file-to-markdown ingest), `smartbook-ingest` (reusable library compilation). +- **Engineering (Model-invoked on match):** `diagnosing-bugs`, `domain-modeling`, `codebase-design`, `writing-for-agents`, `research`, `prototype`, `diagram-design`. +- **Diagnostics & Governance (Model-invoked on match):** `agent-architecture-audit`, `cost-aware-llm-pipeline`, `eval-harness`, `prompt-optimizer`, `skill-stocktake`, `api-design`, `contract-first`, `automation-audit-ops`, `code-tour`, `click-path-audit`. +- **Vendor / Cloud (Model-invoked on match):** `supabase-ops`, `mongodb-ops`, `vercel-ops`. +- **Browser / GitHub / Risk:** `playwright-qa` (primary QA), `browser-act` (multi-account/stealth), `chrome-devtools-axi` (CDP diagnostics), `gh-axi`, `full-audit-keamanan` (security), `full-performance-audit` (performance), `adhd` (divergent ideation). +- **Engineering (Manual / Slash-only):** `/architect`, `/arena`, `/blast-radius`, `/create-verification-skill`, `/decision-log`, `/demo-video`, `/figure-it-out`, `/improve-codebase-architecture`, `/interrogate`, `/maintain-verification-skill`, `/reflect`, `/technical-writing`, `/unslop`, `/why`, `/wizard`. + +## Not Installed (Inform User Directly) + +Do not hallucinate or auto-install: +`/design`, `/execute-plan`, `/implement`, `/review`, `/code-review`, `/imagine`, `/docx`, `/pdf`, `/pptx`, `/grill-me`, `/handoff`, `/triage`, `/wayfinder`, `/bro`, `/poteto-mode`, `/swarm`, `/setup-matt-pocock-skills`, `/pr-babysit`, `/create-skill`, `/create-workflow`, `/build-with-ai`, `game-asset-*`. + +## Standard Routing Decision Order + +1. Repo evidence is enough → do the work directly without a specialist. +2. User typed a slash command → load that manual command. +3. Architecture / PR-plan DAG → OpenCode plan agent, then implement in-session after approval. +4. Feature needs an interview, glossary, or ADR → `grill-with-docs`. Then `/to-spec` → `/to-tickets` only if asked or multi-session. +5. Ordinary implementation → write in-session; `tdd` when test-first. +6. UI direction unknown → `found-this-design` then `impeccable`. Direction chosen → `impeccable`. +7. Official library/spec facts → `research` (Context7). Why *this repo* made a choice → `/why` (manual). diff --git a/templates/AGENTS.md b/templates/AGENTS.md index ef45fb5..5cf6791 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -11,10 +11,10 @@ Availability is not a reason to use a tool. One primary specialist. At most one 1. Repo evidence is enough → do the work. No specialist. 2. User typed a slash command → load that command's specialist. Do not substitute. -3. Choosing a workflow → load skill `ask-matt`. +3. Choosing a workflow → read `~/.config/opencode/AGENTS.md` or `00-routing.md`. No specialist. 4. Architecture DAG → OpenCode **plan** agent, then implement in-session after approval. -5. Interview / glossary / ADR → skill `grill-with-docs` (`grilling` is not default; load `grilling` only if user names it) → `to-spec` → `to-tickets` only if asked or multi-session. -6. Ordinary implementation → this session. Skill `tdd` when test-first. Never auto `/matt-implement`. +5. Interview / glossary / ADR → skill `grill-with-docs` → `to-spec` → `to-tickets` only if asked or multi-session. +6. Ordinary implementation → this session. Skill `tdd` when test-first. 7. Review → in-session. Skill `matt-code-review` only if two-axis asked. ## Report @@ -39,7 +39,7 @@ Browser QA → skill `playwright-qa`. Explicit/session BrowserAct → `browser-a Auth/secret/payment/upload/webhook/privileged/public API → `full-audit-keamanan`. Measured LCP/INP/CLS/latency/bundle → `full-performance-audit`. GitHub → `gh-axi`. Hard unknown bug → `diagnosing-bugs`. Documents (PDF/DOCX/extract/review) → `smartdoc`. File → Markdown ingest → `markitdown`. Reusable local knowledge → `smartbook-ingest`. -Prose AI-tells / humanize → skill `humanizer`. Slash `/unslop` is the same specialist, manual only. Technical writing structure → suggest `/technical-writing`. Academic literature / manuscript / peer-critique → skill `academic` (not `research`, not `smartdoc` unless file extract/render). Facts library/API → Context7; `research` only if repo lacking. Deterministic HTML video / render HTML to MP4 → skill `hyperframes` (not `visual-studio`, not `emil-design-eng`). Editorial diagram HTML/SVG → skill `diagram-design` (not `impeccable`). +Prose AI-tells / humanize → skill `humanizer`. Slash `/unslop` is the same specialist, manual only. Technical writing structure → suggest `/technical-writing`. Academic literature / manuscript / peer-critique → skill `academic` (not `research`, not `smartdoc` unless file extract/render). Facts library/API → Context7; `research` only if repo lacking. Deterministic HTML video / render HTML to MP4 → skill `hyperframes` (not `visual-studio`, not `emil-design-eng`). Editorial diagram HTML/SVG → skill `diagram-design` (not `impeccable`). Demo video aplikasi / walkthrough layar / narasi Indonesia / demo lomba → skill `id-demo-video` (bukan `hyperframes` untuk durasi panjang utuh, bukan `playwright-qa`, bukan `visual-studio`). Kartu judul HTML→MP4 tetap `hyperframes`. REST resource/status/pagination/versioning → skill `api-design`. Consumer/provider OpenAPI/AsyncAPI/Protobuf → skill `contract-first`. Live cron/CI/hook/MCP inventory keep-merge-cut → skill `automation-audit-ops`. CodeTour .tour + anchor file → skill `code-tour`. Handler vs shared-store sequential-undo → skill `click-path-audit` (not `playwright-qa`). @@ -47,6 +47,11 @@ Agent stack diagnostics / context leak / wrapper regression → skill `agent-arc Supabase Auth/RLS/migrations/Edge → skill `supabase-ops` (Context7; not impeccable). Mongo schema/index/aggregation → skill `mongodb-ops`. Vercel/Next hosting/deploy config → skill `vercel-ops` (not visual UI). Library facts remain Context7. These three never replace found-this-design or impeccable. +How it works / where it lives → Codebase Memory, then `code-tour`; rationale → `/why`; break risk → `/blast-radius`. +Generic AI UI look → `impeccable` taste-guard (not `install-anti-slop`). Generic AI prose → `humanizer` `/unslop`. +TS anti-pattern lint install → `install-anti-slop` (explicit only). DESIGN.md without bank → still filter slop; do not invent a brand. +pstack playbooks → existing specialists (no `/poteto-mode`). ECC / orchestrate / ralph-loop / continual-learning that writes AGENTS.md → REJECT. + ## When routing is non-obvious Read the file `~/.config/opencode/bestfriend/rules/00-routing.md` with the Read tool. Do not `@`-import it. @@ -59,5 +64,5 @@ If you need operational principles or prose discipline, Read `~/.config/opencode There is no user `/implement`, `/code-review`, `/design`, or `/imagine` skill. -Manual-only specialists are OpenCode commands, not auto-discovered skills: `/architect` `/arena` `/blast-radius` `/create-verification-skill` `/decision-log` `/figure-it-out` `/improve-codebase-architecture` `/interrogate` `/maintain-verification-skill` `/matt-implement` `/reflect` `/technical-writing` `/unslop` `/wait-what` `/why` `/wizard`. Suggest them when the user names the job; do not load them as the default path. +Manual-only specialists are OpenCode commands, not auto-discovered skills: `/architect` `/arena` `/blast-radius` `/create-verification-skill` `/decision-log` `/demo-video` `/figure-it-out` `/improve-codebase-architecture` `/interrogate` `/maintain-verification-skill` `/reflect` `/technical-writing` `/unslop` `/why` `/wizard`. Suggest them when the user names the job; do not load them as the default path. diff --git a/tests/fixtures/id_demo_video/storyboard.invalid.json b/tests/fixtures/id_demo_video/storyboard.invalid.json new file mode 100644 index 0000000..a86007f --- /dev/null +++ b/tests/fixtures/id_demo_video/storyboard.invalid.json @@ -0,0 +1,22 @@ +{ + "slug": "demo-app", + "target_duration_s": 600, + "voice": "id-ID-GadisNeural", + "lang": "id", + "scenes": [ + { + "id": "scene-01", + "title": "Hook Cepat", + "duration_s": 40, + "narration": "Pengenalan singkat.", + "actions": [] + }, + { + "id": "scene-02", + "title": "Fitur", + "duration_s": 50, + "narration": "Fitur utama.", + "actions": [] + } + ] +} diff --git a/tests/fixtures/id_demo_video/storyboard.valid.json b/tests/fixtures/id_demo_video/storyboard.valid.json new file mode 100644 index 0000000..0fb81a4 --- /dev/null +++ b/tests/fixtures/id_demo_video/storyboard.valid.json @@ -0,0 +1,107 @@ +{ + "slug": "demo-app", + "target_duration_s": 600, + "voice": "id-ID-GadisNeural", + "lang": "id", + "scenes": [ + { + "id": "scene-01", + "title": "Hook & Ringkasan Solusi", + "duration_s": 50, + "narration": "Selamat datang di demonstrasi sistem. Hari ini kita akan melihat bagaimana alur kerja diselesaikan secara efisien.", + "actions": [ + {"type": "goto", "value": "http://localhost:3000"}, + {"type": "wait", "duration_ms": 1000} + ] + }, + { + "id": "scene-02", + "title": "Tampilan Dashboard Utama", + "duration_s": 55, + "narration": "Pada dashboard utama terlihat ringkasan metrik performa dan status sinkronisasi data yang aktif.", + "actions": [ + {"type": "click", "selector": "#dashboard-summary"}, + {"type": "wait", "duration_ms": 1500} + ] + }, + { + "id": "scene-03", + "title": "Manajemen Data Transaksi", + "duration_s": 65, + "narration": "Kita masuk ke modul transaksi. Di sini seluruh daftar rekaman disajikan dengan pemilahan kategori yang jelas.", + "actions": [ + {"type": "click", "selector": "nav a[href='/transactions']"}, + {"type": "wait", "duration_ms": 1000} + ] + }, + { + "id": "scene-04", + "title": "Pencarian dan Penyaringan Cepat", + "duration_s": 70, + "narration": "Pengguna dapat menyaring data berdasarkan rentang waktu atau kata kunci dengan respons instan tanpa jeda panjang.", + "actions": [ + {"type": "type", "selector": "input#search-input", "value": "pembayaran"}, + {"type": "click", "selector": "button#btn-filter"} + ] + }, + { + "id": "scene-05", + "title": "Pembuatan Entri Baru", + "duration_s": 65, + "narration": "Sekarang kita coba menambahkan entri baru. Formulir menyediakan validasi otomatis sebelum data disimpan ke sistem.", + "actions": [ + {"type": "click", "selector": "button#new-entry"}, + {"type": "type", "selector": "input#entry-name", "value": "Batch Uji Coba"}, + {"type": "click", "selector": "button#submit-entry"} + ] + }, + { + "id": "scene-06", + "title": "Pemeriksaan Validasi dan Feedback", + "duration_s": 65, + "narration": "Sistem memberikan umpan balik langsung bahwa data telah tercatat dengan aman di penyimpanan lokal.", + "actions": [ + {"type": "wait", "duration_ms": 2000} + ] + }, + { + "id": "scene-07", + "title": "Visualisasi Laporan dan Metrik", + "duration_s": 70, + "narration": "Bagian laporan menyajikan grafik ringkas yang memetakan tren penggunaan secara transparan untuk evaluasi berkala.", + "actions": [ + {"type": "click", "selector": "nav a[href='/reports']"}, + {"type": "wait", "duration_ms": 1500} + ] + }, + { + "id": "scene-08", + "title": "Konfigurasi dan Preferensi Sistem", + "duration_s": 60, + "narration": "Pengaturan sistem memungkinkan penyesuaian aturan notifikasi dan opsi integrasi sesuai kebutuhan operasional tim.", + "actions": [ + {"type": "click", "selector": "nav a[href='/settings']"}, + {"type": "wait", "duration_ms": 1000} + ] + }, + { + "id": "scene-09", + "title": "Audit Integritas dan Log", + "duration_s": 55, + "narration": "Setiap aktivitas tercatat rapi pada log audit sehingga penelusuran riwayat operasional tetap akuntabel.", + "actions": [ + {"type": "click", "selector": "nav a[href='/audit']"}, + {"type": "wait", "duration_ms": 1000} + ] + }, + { + "id": "scene-10", + "title": "Ringkasan dan Penutup", + "duration_s": 45, + "narration": "Demikian alur utama aplikasi ini. Seluruh proses berjalan terpadu, stabil, dan siap digunakan di lingkungan produksi.", + "actions": [ + {"type": "wait", "duration_ms": 2000} + ] + } + ] +} diff --git a/tests/test_id_demo_video.py b/tests/test_id_demo_video.py new file mode 100644 index 0000000..ef633c5 --- /dev/null +++ b/tests/test_id_demo_video.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +""" +Tests for Indonesian application demo video specialist (id-demo-video and /demo-video). +""" +from __future__ import annotations + +import json +import subprocess +import sys +import tempfile +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] + + +def validate_storyboard_duration(data: dict) -> tuple[bool, str]: + target = data.get("target_duration_s", 0) + scenes = data.get("scenes", []) + total = sum(s.get("duration_s", 0) for s in scenes) + diff = abs(total - target) + if diff > 15: + return False, f"Sum of scene durations ({total}s) differs from target ({target}s) by {diff}s (tolerance: ±15s)" + return True, f"OK ({total}s vs target {target}s, diff {diff}s)" + + +class IdDemoVideoContractTests(unittest.TestCase): + def setUp(self): + self.agents = (ROOT / "templates" / "AGENTS.md").read_text(encoding="utf-8") + self.routing = (ROOT / "rules" / "00-routing.md").read_text(encoding="utf-8") + self.tts_script = ROOT / "skills" / "id-demo-video" / "scripts" / "tts_edge.py" + self.compose_script = ROOT / "skills" / "id-demo-video" / "scripts" / "compose.sh" + + def test_router_contains_id_demo_video(self): + self.assertIn("id-demo-video", self.agents) + self.assertIn( + "Demo video aplikasi / walkthrough layar / narasi Indonesia / demo lomba → skill `id-demo-video` (bukan `hyperframes` untuk durasi panjang utuh, bukan `playwright-qa`, bukan `visual-studio`). Kartu judul HTML→MP4 tetap `hyperframes`.", + self.agents, + ) + self.assertIn("/demo-video", self.agents) + self.assertIn("skill `id-demo-video`", self.routing) + self.assertIn("/demo-video", self.routing) + + def test_required_files_exist(self): + expected_files = [ + ROOT / "skills" / "id-demo-video" / "SKILL.md", + ROOT / "skills" / "id-demo-video" / "references" / "beats.md", + ROOT / "skills" / "id-demo-video" / "references" / "tts-id.md", + ROOT / "skills" / "id-demo-video" / "references" / "record-compose.md", + ROOT / "skills" / "id-demo-video" / "references" / "storyboard.schema.md", + ROOT / "skills" / "id-demo-video" / "scripts" / "tts_edge.py", + ROOT / "skills" / "id-demo-video" / "scripts" / "compose.sh", + ROOT / "commands" / "demo-video.md", + ROOT / "manual-skills" / "demo-video" / "SKILL.md", + ] + for path in expected_files: + self.assertTrue(path.is_file(), f"Missing file: {path}") + + def test_storyboard_duration_validation_logic(self): + valid_path = ROOT / "tests" / "fixtures" / "id_demo_video" / "storyboard.valid.json" + invalid_path = ROOT / "tests" / "fixtures" / "id_demo_video" / "storyboard.invalid.json" + + valid_data = json.loads(valid_path.read_text(encoding="utf-8")) + ok, msg = validate_storyboard_duration(valid_data) + self.assertTrue(ok, msg) + self.assertEqual(valid_data["target_duration_s"], 600) + total_valid = sum(s["duration_s"] for s in valid_data["scenes"]) + self.assertTrue(abs(total_valid - 600) <= 15, f"Valid total {total_valid} not in 600±15s") + + invalid_data = json.loads(invalid_path.read_text(encoding="utf-8")) + ok_inv, msg_inv = validate_storyboard_duration(invalid_data) + self.assertFalse(ok_inv, "Invalid storyboard should fail duration check") + self.assertIn("differs from target", msg_inv) + + def test_tts_script_rejects_empty_input(self): + with tempfile.TemporaryDirectory() as tmpdir: + out_file = Path(tmpdir) / "test.mp3" + proc = subprocess.run( + [sys.executable, str(self.tts_script), "--text", " ", "--output", str(out_file), "--dry-run"], + capture_output=True, + text=True, + ) + self.assertNotEqual(proc.returncode, 0) + self.assertIn("empty", proc.stderr.lower()) + + def test_tts_script_rejects_unsupported_voice(self): + with tempfile.TemporaryDirectory() as tmpdir: + out_file = Path(tmpdir) / "test.mp3" + proc = subprocess.run( + [sys.executable, str(self.tts_script), "--text", "Halo dunia", "--voice", "kokoro", "--output", str(out_file), "--dry-run"], + capture_output=True, + text=True, + ) + self.assertNotEqual(proc.returncode, 0) + + def test_tts_script_dry_run_offline(self): + with tempfile.TemporaryDirectory() as tmpdir: + out_file = Path(tmpdir) / "test.mp3" + proc = subprocess.run( + [ + sys.executable, + str(self.tts_script), + "--text", + "Selamat datang di demonstrasi aplikasi.", + "--voice", + "id-ID-GadisNeural", + "--output", + str(out_file), + "--dry-run", + ], + capture_output=True, + text=True, + ) + self.assertEqual(proc.returncode, 0, proc.stderr) + self.assertIn("[DRY-RUN VALID]", proc.stdout) + self.assertTrue(out_file.exists()) + + def test_compose_script_syntax_and_validation(self): + # Verify bash syntax without executing + proc = subprocess.run(["bash", "-n", str(self.compose_script)], capture_output=True, text=True) + self.assertEqual(proc.returncode, 0, proc.stderr) + + # Fails gracefully if target demo directory does not exist + proc_run = subprocess.run(["bash", str(self.compose_script), "/nonexistent/demo/path"], capture_output=True, text=True) + self.assertNotEqual(proc_run.returncode, 0) + self.assertIn("does not exist", proc_run.stderr) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_install.py b/tests/test_install.py index 88bf3c7..6b9f8d7 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -121,9 +121,9 @@ def test_fresh_install_idempotent_uninstall(self): self.assertEqual(sha256(self.sentinel), self.sentinel_hash) self.assertEqual({p.name for p in (self.tmp / ".claude").iterdir()}, {"sentinel.txt"}) skills = list((self.tmp / ".config" / "opencode" / "skills").iterdir()) - self.assertEqual(len([p for p in skills if p.is_dir()]), 48) + self.assertEqual(len([p for p in skills if p.is_dir()]), 47) cmds = list((self.tmp / ".config" / "opencode" / "commands").glob("*.md")) - self.assertEqual(len(cmds), 16) + self.assertEqual(len(cmds), 15) self.assertEqual(cmd_skills_verify(), 0) data = jsonc.load_path(self.tmp / ".config" / "opencode" / "opencode.jsonc") self.assertEqual(data["model"], "keep-me-model") @@ -136,8 +136,8 @@ def test_fresh_install_idempotent_uninstall(self): rc2 = cmd_install() self.assertEqual(rc2, 0) - self.assertEqual(len([p for p in (self.tmp / ".config" / "opencode" / "skills").iterdir() if p.is_dir()]), 48) - self.assertEqual(len(list((self.tmp / ".config" / "opencode" / "commands").glob("*.md"))), 16) + self.assertEqual(len([p for p in (self.tmp / ".config" / "opencode" / "skills").iterdir() if p.is_dir()]), 47) + self.assertEqual(len(list((self.tmp / ".config" / "opencode" / "commands").glob("*.md"))), 15) bashrc = (self.tmp / ".bashrc").read_text(encoding="utf-8") self.assertEqual(bashrc.count("OPENCODEBESTFRIEND:BEGIN"), 1) data2 = jsonc.load_path(self.tmp / ".config" / "opencode" / "opencode.jsonc") diff --git a/tests/test_migration.py b/tests/test_migration.py index ad1da0f..eca812e 100644 --- a/tests/test_migration.py +++ b/tests/test_migration.py @@ -106,7 +106,7 @@ def test_migrate_claudebestfriend_1_4_2_to_ocbf(self): (self.tmp / ".local" / "share" / "opencode-bestfriend" / "components" / "installer").exists() ) skills = list((self.tmp / ".config" / "opencode" / "skills").iterdir()) - self.assertEqual(len([p for p in skills if p.is_dir()]), 48) + self.assertEqual(len([p for p in skills if p.is_dir()]), 47) with redirect_stdout(io.StringIO()): self.assertEqual(cmd_verify(), 0) self.assertEqual(cmd_doctor(), 0) diff --git a/tests/test_routing.py b/tests/test_routing.py index ec698a6..bc72e98 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -58,6 +58,7 @@ def test_mappings(self): "vercel-ops": "vercel-ops", "img2threejs": "img2threejs", "markitdown": "markitdown", + "id-demo-video": "id-demo-video", } for label, needle in expected.items(): self.assertIn(needle, blob, label) @@ -72,6 +73,10 @@ def test_new_specialist_boundaries(self): self.assertIn("Deterministic HTML video / render HTML to MP4 → skill `hyperframes`", self.agents) self.assertIn("Deterministic HTML composition rendered to video: `/hyperframes`", self.routing) self.assertIn("Ordinary scrollable UI stays `/impeccable`.", self.routing) + + # id-demo-video vs hyperframes vs playwright-qa vs visual-studio + self.assertIn("Demo video aplikasi / walkthrough layar / narasi Indonesia / demo lomba → skill `id-demo-video`", self.agents) + self.assertIn("Demo video aplikasi, walkthrough layar, narasi Indonesia, demo lomba: skill `id-demo-video`", self.routing) # Diagram design vs impeccable vs codebase-design self.assertIn("Editorial diagram HTML/SVG → skill `diagram-design`", self.agents) @@ -147,6 +152,7 @@ def test_new_specialist_boundaries(self): "supabase-ops", "mongodb-ops", "vercel-ops", + "id-demo-video", ] for spec in required_specialists: self.assertIn(spec, self.agents, f"Expected {spec} in AGENTS.md") diff --git a/tests/test_skills.py b/tests/test_skills.py index 98097a8..d99ca72 100644 --- a/tests/test_skills.py +++ b/tests/test_skills.py @@ -56,13 +56,14 @@ def jaccard(left: set[str], right: set[str]) -> float: class SkillPolicyTests(unittest.TestCase): def test_counts(self): allow, skills, model, manual = load_policy(ROOT) - self.assertEqual(len(allow), 64) - self.assertEqual(len(model), 48) - self.assertEqual(len(manual), 16) + self.assertEqual(len(allow), 62) + self.assertEqual(len(model), 47) + self.assertEqual(len(manual), 15) self.assertEqual(set(allow), set(skills)) - for name in ("supabase-ops", "mongodb-ops", "vercel-ops", "img2threejs", "markitdown"): + for name in ("supabase-ops", "mongodb-ops", "vercel-ops", "img2threejs", "markitdown", "id-demo-video"): self.assertIn(name, allow) self.assertIn(name, model) + self.assertIn("demo-video", manual) def test_model_skills_exist(self): _, _, model, manual = load_policy(ROOT) diff --git a/vendor/license-audit.json b/vendor/license-audit.json index 508a423..fe614ee 100644 --- a/vendor/license-audit.json +++ b/vendor/license-audit.json @@ -1,9 +1,19 @@ { "schemaVersion": 1, "product": "OpenCodeBestFriend", - "productVersion": "1.8.4", + "productVersion": "1.8.6", "note": "Evidence-based. A missing frontmatter license is not a grant. Adapted \u2260 first-party.", "skills": { + "demo-video": { + "license": "MIT", + "evidence": "SKILL.md frontmatter", + "redistribution": "mit" + }, + "id-demo-video": { + "license": "MIT", + "evidence": "SKILL.md frontmatter", + "redistribution": "mit" + }, "adhd": { "license": "MIT", "evidence": "SKILL.md frontmatter", @@ -44,11 +54,6 @@ "evidence": "mattpocock/skills 9c9f36c", "redistribution": "mit" }, - "grilling": { - "license": "MIT", - "evidence": "mattpocock/skills 9c9f36c", - "redistribution": "mit" - }, "improve-codebase-architecture": { "license": "MIT", "evidence": "mattpocock/skills 9c9f36c", @@ -59,16 +64,6 @@ "evidence": "mattpocock/skills 9c9f36c", "redistribution": "mit" }, - "wait-what": { - "license": "MIT", - "evidence": "mattpocock/skills 9c9f36c", - "redistribution": "mit" - }, - "ask-matt": { - "license": "MIT", - "evidence": "mattpocock/skills (engineering/ask-matt) MIT LICENSE; overlay in this tree", - "redistribution": "mit" - }, "grill-with-docs": { "license": "MIT", "evidence": "mattpocock/skills (engineering/grill-with-docs) MIT LICENSE; overlay in this tree", @@ -94,11 +89,6 @@ "evidence": "mattpocock/skills engineering/code-review renamed; MIT LICENSE", "redistribution": "mit" }, - "matt-implement": { - "license": "MIT", - "evidence": "mattpocock/skills engineering/implement renamed; MIT LICENSE", - "redistribution": "mit" - }, "markitdown": { "license": "MIT", "evidence": "SKILL.md frontmatter + skills/markitdown/NOTICE.md (method inspiration from microsoft/markitdown MIT; zero verbatim dump)", diff --git a/vendor/provenance.json b/vendor/provenance.json index 72f79b5..232e667 100644 --- a/vendor/provenance.json +++ b/vendor/provenance.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "product": "OpenCodeBestFriend", - "productVersion": "1.8.4", + "productVersion": "1.8.6", "upstreamProduct": "GrokBestFriend", "upstreamVersion": "1.3.1", "firstPartyLicense": "MIT", @@ -24,17 +24,6 @@ "modified": true, "redistribution": "apache-2.0" }, - { - "component": "ask-matt", - "path": "skills/ask-matt", - "upstream": "https://github.com/mattpocock/skills", - "originalPath": "skills/engineering/ask-matt", - "license": "MIT", - "copyright": "Copyright (c) 2026 Matt Pocock", - "modified": true, - "redistribution": "mit", - "notes": "OpenCode overlay. MIT via mattpocock/skills LICENSE." - }, { "component": "grill-with-docs", "path": "skills/grill-with-docs", @@ -87,17 +76,6 @@ "redistribution": "mit", "notes": "Renamed to avoid OpenCode/Grok /review collision." }, - { - "component": "matt-implement", - "path": "manual-skills/matt-implement", - "upstream": "https://github.com/mattpocock/skills", - "originalPath": "skills/engineering/implement", - "license": "MIT", - "copyright": "Copyright (c) 2026 Matt Pocock", - "modified": true, - "redistribution": "mit", - "notes": "Renamed to avoid OpenCode/Grok /implement collision." - }, { "component": "browser-act", "path": "skills/browser-act", @@ -270,19 +248,6 @@ "redistribution": "mit", "notes": "LOGIC.md and UI.md kept. agents/openai.yaml not vendored." }, - { - "component": "grilling", - "path": "vendor/skills/grilling", - "upstream": "https://github.com/mattpocock/skills", - "commit": "9c9f36ccd3995266cd675468af71639c8dde1ec5", - "originalPath": "skills/productivity/grilling", - "upstreamSkillMdSha256": "d2498125dd20a0d3a27f03e0ebcc8e681cf42be468e2d3e3c9e8f5dadcae8d47", - "license": "MIT", - "copyright": "Copyright (c) 2026 Matt Pocock", - "modified": true, - "redistribution": "mit", - "notes": "Primitive only. Full interviews stay on grill-with-docs. agents/openai.yaml not vendored." - }, { "component": "improve-codebase-architecture", "path": "vendor/skills/improve-codebase-architecture", @@ -309,19 +274,6 @@ "redistribution": "mit", "notes": "Forced manual. template.sh kept (gh secret via stdin). agents/openai.yaml not vendored." }, - { - "component": "wait-what", - "path": "vendor/skills/wait-what", - "upstream": "https://github.com/mattpocock/skills", - "commit": "9c9f36ccd3995266cd675468af71639c8dde1ec5", - "originalPath": "skills/productivity/wait-what", - "upstreamSkillMdSha256": "8923f7df1a0d1b138281658e134caa4bf1c618d2876a2323b19acdfdffebc024", - "license": "MIT", - "copyright": "Copyright (c) 2026 Matt Pocock", - "modified": true, - "redistribution": "mit", - "notes": "Manual convenience. Does not install /bro. agents/openai.yaml not vendored." - }, { "component": "blast-radius", "path": "vendor/skills/blast-radius", @@ -563,6 +515,26 @@ "redistribution": "apache-2.0", "notes": "Deterministic HTML-to-MP4 video composition specialist with local Chromium and FFmpeg execution boundaries." }, + { + "component": "id-demo-video", + "path": "skills/id-demo-video", + "upstream": "first-party", + "license": "MIT", + "copyright": "Copyright (c) 2026 OpenCodeBestFriend contributors", + "modified": false, + "redistribution": "mit", + "notes": "Original first-party specialist for Indonesian narrated application walkthroughs, Edge TTS synthesis, Playwright capture, and FFmpeg composition." + }, + { + "component": "demo-video", + "path": "manual-skills/demo-video", + "upstream": "first-party", + "license": "MIT", + "copyright": "Copyright (c) 2026 OpenCodeBestFriend contributors", + "modified": false, + "redistribution": "mit", + "notes": "Manual slash command alias for id-demo-video." + }, { "component": "diagram-design", "path": "skills/diagram-design", diff --git a/vendor/skill-allowlist.txt b/vendor/skill-allowlist.txt index 5a17799..b5bcc1e 100644 --- a/vendor/skill-allowlist.txt +++ b/vendor/skill-allowlist.txt @@ -4,7 +4,6 @@ agent-architecture-audit api-design architect arena -ask-matt automation-audit-ops blast-radius browser-act @@ -16,6 +15,7 @@ contract-first cost-aware-llm-pipeline create-verification-skill decision-log +demo-video diagnosing-bugs diagram-design domain-modeling @@ -27,9 +27,9 @@ full-audit-keamanan full-performance-audit gh-axi grill-with-docs -grilling humanizer hyperframes +id-demo-video img2threejs impeccable improve-codebase-architecture @@ -38,7 +38,6 @@ interrogate maintain-verification-skill markitdown matt-code-review -matt-implement mongodb-ops playwright-qa prompt-optimizer @@ -58,7 +57,6 @@ to-tickets unslop vercel-ops visual-studio -wait-what why wizard writing-for-agents diff --git a/vendor/skill-policy.json b/vendor/skill-policy.json index 65d74c0..5e39dc0 100644 --- a/vendor/skill-policy.json +++ b/vendor/skill-policy.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "note": "allowlist = WHAT is owned. This file = HOW each owned skill may be invoked. provenance = WHERE it came from.", + "note": "allowlist = WHAT is owned. This file = HOW each owned skill may be invoked. provenance = WHERE it came from. Catalog frozen at 1.8.6 (62 names: 47 model, 15 manual; see docs/CATALOG-FREEZE.md).", "skills": { "academic": { "invocation": "model" @@ -20,9 +20,6 @@ "arena": { "invocation": "manual" }, - "ask-matt": { - "invocation": "model" - }, "automation-audit-ops": { "invocation": "model" }, @@ -56,6 +53,9 @@ "decision-log": { "invocation": "manual" }, + "demo-video": { + "invocation": "manual" + }, "diagnosing-bugs": { "invocation": "model" }, @@ -89,15 +89,15 @@ "grill-with-docs": { "invocation": "model" }, - "grilling": { - "invocation": "model" - }, "humanizer": { "invocation": "model" }, "hyperframes": { "invocation": "model" }, + "id-demo-video": { + "invocation": "model" + }, "img2threejs": { "invocation": "model" }, @@ -122,9 +122,6 @@ "matt-code-review": { "invocation": "model" }, - "matt-implement": { - "invocation": "manual" - }, "mongodb-ops": { "invocation": "model" }, @@ -182,9 +179,6 @@ "visual-studio": { "invocation": "model" }, - "wait-what": { - "invocation": "manual" - }, "why": { "invocation": "manual" }, diff --git a/vendor/sources.json b/vendor/sources.json index 4b85872..8ecd374 100644 --- a/vendor/sources.json +++ b/vendor/sources.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "product": "OpenCodeBestFriend", - "productVersion": "1.8.4", + "productVersion": "1.8.6", "adaptedFrom": { "product": "ClaudeBestFriend", "version": "1.4.2-claude.1", @@ -67,6 +67,8 @@ }, "markitdown": { "repository": "https://github.com/microsoft/markitdown", + "version": "0.1.7", + "commit": "945314a45ddbe02935f2fd287b797dc0ba4a01e4", "license": "MIT", "package": "markitdown-mcp", "via": "uvx",