mirror of
https://github.com/twentyhq/twenty.git
synced 2026-06-12 01:46:39 -04:00
@martmull v2.0 ;) --------- Co-authored-by: martmull <martmull@hotmail.fr> Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
113 lines
8.6 KiB
Markdown
113 lines
8.6 KiB
Markdown
# Twenty Codex Plugin — Best Practices Compliance Checklist
|
||
|
||
This file is the authoritative compliance matrix. Every row maps an official requirement (Codex build guide, Codex best-practices guide, or OpenAI reference implementation) to either an **automated** check (a `scripts/validate.js` assertion function) or a **manual** sign-off.
|
||
|
||
A release is shippable when:
|
||
1. `yarn workspace twenty-codex-plugin validate` exits 0 (all `[automated]` rows green).
|
||
2. Every `[manual]` row has a current sign-off date.
|
||
|
||
## Sources of Truth
|
||
|
||
- **Codex Plugin Build Guide** — https://developers.openai.com/codex/plugins/build
|
||
- **Codex Best Practices** — https://developers.openai.com/codex/learn/best-practices
|
||
- **Reference Implementation** — https://github.com/openai/codex-plugin-cc
|
||
|
||
## Plugin Manifest (`.codex-plugin/plugin.json`)
|
||
|
||
| # | Requirement | Source | Check |
|
||
|---|---|---|---|
|
||
| M1 | `name` present, kebab-case, lowercase | Build guide §Naming | [automated] `assertJsonMetadata` |
|
||
| M2 | `version` follows SemVer and matches `package.json` | Build guide §Manifest | [automated] `assertJsonMetadata` |
|
||
| M3 | `description` present and concise | Build guide §Required fields | [automated] `assertInterfaceFields` (planned) |
|
||
| M4 | `mcpServers` points at `./.mcp.json` | Build guide §MCP | [automated] `assertJsonMetadata` |
|
||
| M5 | `skills` points at `./skills/` | Build guide §Skills | [automated] `assertJsonMetadata` |
|
||
| M6 | `interface.displayName` present and non-empty | Build guide §Interface | [automated] `assertInterfaceFields` (planned) |
|
||
| M7 | `interface.shortDescription` ≤ 64 chars | Build guide §Marketplace | [automated] `assertInterfaceFields` (planned) |
|
||
| M8 | `interface.longDescription` present, multi-sentence | Build guide §Marketplace | [automated] `assertInterfaceFields` (planned) |
|
||
| M9 | `interface.category` matches marketplace enum (`Coding`) | Build guide §Marketplace | [automated] `assertInterfaceFields` (planned) |
|
||
| M10 | `interface.capabilities` non-empty subset of `Interactive,Read,Write` | Build guide §Capabilities | [automated] `assertInterfaceFields` (planned) |
|
||
| M11 | `interface.websiteURL`, `privacyPolicyURL`, `termsOfServiceURL` present | Build guide §Publisher links | [automated] `assertInterfaceFields` (planned) |
|
||
| M12 | `interface.brandColor` matches `#RRGGBB` and reflects Twenty brand | Build guide §Marketplace | [automated] `assertInterfaceFields` (planned), [manual] brand alignment |
|
||
| M13 | `interface.defaultPrompt` is a non-empty array of strings | Build guide §Defaults | [automated] `assertInterfaceFields` (planned) |
|
||
| M14 | All manifest paths start with `./` and stay within plugin root | Build guide §Paths | [automated] `assertJsonMetadata` |
|
||
|
||
## Assets (`assets/`)
|
||
|
||
| # | Requirement | Source | Check |
|
||
|---|---|---|---|
|
||
| A1 | `interface.logo` exists and is PNG | Build guide §Assets | [automated] `assertAssets` (planned) |
|
||
| A2 | Logo PNG is ≥ 256×256 | Build guide §Assets | [automated] `assertAssets` (planned, PNG IHDR parse) |
|
||
| A3 | `interface.composerIcon` exists and is valid SVG or PNG | Build guide §Assets | [automated] `assertAssets` (planned) |
|
||
| A4 | `interface.screenshots` has ≥ 1 entry | Build guide §Assets | [automated] `assertAssets` (planned) |
|
||
| A5 | Every screenshot path exists and is PNG | Build guide §Assets | [automated] `assertAssets` (planned) |
|
||
| A6 | Screenshots show the plugin in action (not placeholder mocks) | Build guide §Marketplace | [manual] reviewer sign-off |
|
||
|
||
## Skills (`skills/<name>/SKILL.md`)
|
||
|
||
| # | Requirement | Source | Check |
|
||
|---|---|---|---|
|
||
| S1 | Canonical five skills present | Internal convention | [automated] `assertSkills` |
|
||
| S2 | No legacy skill names anywhere | Internal convention | [automated] `assertNoLegacySkillReferences` |
|
||
| S3 | Each `SKILL.md` has YAML frontmatter with `name` + `description` only | Build guide §Skills | [automated] `assertSkills` |
|
||
| S4 | Frontmatter `name` matches directory | Build guide §Skills | [automated] `assertSkills` |
|
||
| S5 | Each skill has `agents/openai.yaml` with `display_name`, `short_description` (≤64), `default_prompt` (mentions `$<skill>`) | OpenAI Agent format | [automated] `assertSkills` |
|
||
| S6 | Each skill is scoped to a single job with clear boundaries | Best practices §Skill scope | [manual] cross-skill audit |
|
||
| S7 | Each skill includes a `## When to use` trigger-phrase section | Best practices §Descriptions | [automated] `assertSkillTriggerPhrases` (planned) |
|
||
| S8 | Descriptions are disjoint across skills (no routing collision) | Best practices §Descriptions | [manual] cross-skill audit |
|
||
|
||
## References (`references/`)
|
||
|
||
| # | Requirement | Source | Check |
|
||
|---|---|---|---|
|
||
| R1 | All required reference files exist | Internal convention | [automated] `assertReferences` |
|
||
| R2 | `use-twenty-mcp` formatting contract intact across SKILL.md and result-formatting.md | Internal convention | [automated] `assertTwentyMcpFormattingContract` |
|
||
| R3 | Front component guidance correctly split across develop-app skill, layout.md, front-components.md, standalone-pages.md, app-structure.md, front-component-ui.md | Internal convention | [automated] `assertFrontComponentGuidance` |
|
||
| R4 | CLI guidance correctly split between develop-app and manage-app | Internal convention | [automated] `assertCliGuidanceSplit` |
|
||
| R5 | `concepts/how-apps-work.md` is foundational and linked from every skill | Internal convention | [automated] `assertHowAppsWork` |
|
||
|
||
## MCP (`.mcp.json` and `scripts/setup-mcp.sh`)
|
||
|
||
| # | Requirement | Source | Check |
|
||
|---|---|---|---|
|
||
| MCP1 | `.mcp.json` declares only the public `twenty-docs` server | Internal convention | [automated] `assertJsonMetadata` |
|
||
| MCP2 | No workspace-specific MCP configs bundled anywhere | Internal convention | [automated] `assertNoBundledMcpConfig` |
|
||
| MCP3 | No bearer tokens or API keys anywhere in the package | Build guide §Security | [automated] `assertNoBundledMcpConfig` |
|
||
| MCP4 | No non-placeholder URLs in any file | Internal convention | [automated] `assertNoBundledMcpConfig` |
|
||
| MCP5 | `scripts/setup-mcp.sh` passes `bash -n` syntax check | Internal convention | [automated] `assertSetupHelper` |
|
||
| MCP6 | `setup-mcp.sh` correctly normalizes representative URLs | Internal convention | [automated] `assertSetupHelper` |
|
||
|
||
## Marketplace & Distribution
|
||
|
||
| # | Requirement | Source | Check |
|
||
|---|---|---|---|
|
||
| D1 | `templates/marketplace.example.json` matches plugin name/version | Internal convention | [automated] `assertMarketplaceTemplate` (planned) |
|
||
| D2 | Optional repo-level `.agents/plugins/marketplace.json` points at `./packages/twenty-codex-plugin` | Build guide §Distribution | [automated] `assertJsonMetadata` |
|
||
| D3 | `CHANGELOG.md` updated for every version bump | Reference impl | [manual] release reviewer sign-off |
|
||
|
||
## Process
|
||
|
||
| # | Requirement | Source | Check |
|
||
|---|---|---|---|
|
||
| P1 | `validate.js` runs in CI on every PR touching the plugin | Reference impl | [manual] confirm `.github/workflows/ci-codex-plugin.yml` is active |
|
||
| P2 | `validate.js` has its own unit tests | Internal convention | [manual] confirm `scripts/__tests__/` exists and runs |
|
||
| P3 | Version bump procedure documented | Internal convention | [manual] confirm `CONTRIBUTING.md` covers it |
|
||
|
||
## Manual Sign-off Log
|
||
|
||
When a manual row above is verified, add a line here.
|
||
|
||
| Date | Row(s) | Reviewer | Notes |
|
||
|---|---|---|---|
|
||
| 2026-05-28 | S6, S8 | Codex plugin compliance pass | Skill descriptions reviewed side-by-side; "When To Use" sections added to all five SKILL.md files with explicit "do not use this skill for X" boundary callouts referencing the four siblings. Routing surface is disjoint. |
|
||
| 2026-05-28 | M12 | Codex plugin compliance pass | `brandColor: #000000` matches the actual logo background in `assets/twenty-logo.svg`. |
|
||
|
||
## Deferred Items
|
||
|
||
Tracked for a follow-up PR; not blocking the current release.
|
||
|
||
| Item | Reason for deferral |
|
||
|---|---|
|
||
| Real marketplace screenshots (A4, A5, A6) | Requires real captures against a demo workspace. `assets/screenshots/README.md` documents what's needed; `plugin.json` `screenshots` stays `[]` until the PNGs land so `assertAssets` does not regress. |
|
||
| Splitting `standalone-pages.md` / `front-component-ui.md` | The cross-doc contracts assert dozens of exact fragments per file. The mechanical risk of fragment drift outweighs the readability gain at current size (~450 lines each). Re-evaluate when either exceeds 600 lines. |
|
||
| `hooks/hooks.json` SessionStart hook | The Codex hook schema for plugin-bundled hooks needs deeper validation; a misconfigured `SessionStart` hook would fire on every Codex session. Add only when the format is verified against a working reference implementation. |
|