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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 70 additions & 53 deletions repotests/contract_clarity_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,24 @@ func TestContractClarity_RuntimeMetadataAndDocsStayAligned(t *testing.T) {
t.Fatal(err)
}

mustContain(t, string(rootReadme), "Build one plugin and ship it to many AI agents was the legacy authoring goal.")
// The root README separates the installer and unreleased standard preview
// from preserved v1 capabilities. Keep legacy claims inside that boundary.
currentReadme, historicalReadme, found := cutHistoricalReadme(string(rootReadme))
if !found {
t.Fatal("README missing historical authoring boundary")
}
mustContain(t, currentReadme, "## Use plugins")
mustContain(t, currentReadme, "## Build plugins — unreleased preview")
currentProse := strings.Join(strings.Fields(currentReadme), " ")
mustContain(t, currentProse, "root `plugin.json` with optional `skills/` and `mcp.json`")
mustContain(t, currentProse, "`agentplugins author` and `plugin-kit-ai` are the two prepared entrypoints to one standard authoring engine.")
mustContain(t, currentProse, "Public deployment remains gated on release acceptance")
mustContain(t, currentProse, "There is no implicit YAML fallback or second supported YAML engine.")
mustContain(t, historicalReadme, "[Historical plugin-kit-ai v1, baseline 1.2.4](website/source/en/legacy/v1/index.md)")
mustContain(t, historicalReadme, "Project migration is not available in v2 yet.")
mustContain(t, historicalReadme, "Maintain legacy projects using the v1 1.2.4 command set.")
mustContain(t, strings.Join(strings.Fields(historicalReadme), " "), "All commands, stability labels, and supported-output claims in this section describe the preserved v1 workflow, not the unreleased standard authoring MVP.")
mustContain(t, historicalReadme, "Build one plugin and ship it to many AI agents was the legacy authoring goal.")
mustContain(t, string(sdkReadme), "`(*plugin-kit-ai.App).Gemini()`")
mustContain(t, string(sdkReadme), "`github.com/777genius/plugin-kit-ai/sdk/gemini`")
mustContain(t, string(sdkReadme), "## Gemini Example")
Expand Down Expand Up @@ -264,32 +281,32 @@ func TestContractClarity_RuntimeMetadataAndDocsStayAligned(t *testing.T) {
mustContain(t, string(architectureDoc), "`sdk/gemini`")
mustContain(t, string(architectureDoc), "`sdk/internal/platforms/gemini`")
mustContain(t, string(architectureDoc), "Gemini runtime hooks use `stdin_json`")
mustContain(t, string(rootReadme), "`plugin-kit-ai` keeps authored source under `plugin/`, generates the supported outputs you need, and helps you validate the repo before handoff.")
mustContain(t, string(rootReadme), "supported outputs for Claude, Codex, Gemini, Cursor, and OpenCode where the repo shape allows it")
mustContain(t, string(rootReadme), "The honest promise is `one repo / many supported outputs`, not fake parity everywhere")
mustContain(t, string(rootReadme), "overview: [plugin-kit-ai documentation](https://github.com/777genius/universal-agent-plugins/blob/9beca10448ac50fbe526a52101d1433a12471980/website/source/en/index.md)")
mustContain(t, string(rootReadme), "fastest start: [Quickstart](https://github.com/777genius/universal-agent-plugins/blob/9beca10448ac50fbe526a52101d1433a12471980/website/source/en/guide/quickstart.md)")
mustContain(t, string(rootReadme), "choose by job first: [Choose What You Are Building](https://github.com/777genius/universal-agent-plugins/blob/9beca10448ac50fbe526a52101d1433a12471980/website/source/en/guide/choose-what-you-are-building.md)")
mustContain(t, string(rootReadme), "one repo, many outputs: [What You Can Build](https://github.com/777genius/universal-agent-plugins/blob/9beca10448ac50fbe526a52101d1433a12471980/website/source/en/guide/what-you-can-build.md)")
mustContain(t, string(rootReadme), "honest caveat: [Support Boundary](https://github.com/777genius/universal-agent-plugins/blob/9beca10448ac50fbe526a52101d1433a12471980/website/source/en/reference/support-boundary.md)")
mustContain(t, string(rootReadme), "## Choose What You Are Building")
mustContain(t, string(rootReadme), "### Connect an online service")
mustContain(t, string(rootReadme), "### Connect a local tool")
mustContain(t, string(rootReadme), "### Build custom plugin logic")
mustContain(t, string(rootReadme), "## Quick start")
mustContain(t, string(rootReadme), "brew install 777genius/homebrew-plugin-kit-ai/plugin-kit-ai")
mustContain(t, string(rootReadme), "npm: `npm i -g plugin-kit-ai@1.2.4` or `npx plugin-kit-ai@1.2.4 ...`")
mustContain(t, string(rootReadme), "pipx (`public-beta`, only when that release is published to PyPI): `pipx install plugin-kit-ai==1.2.4`")
mustContain(t, string(rootReadme), "fallback installer: `curl -fsSL https://raw.githubusercontent.com/777genius/plugin-kit-ai/main/scripts/install.sh | sh`")
mustContain(t, string(rootReadme), "plugin-kit-ai init my-plugin --template online-service")
mustContain(t, string(rootReadme), "plugin-kit-ai init my-plugin --template local-tool")
mustContain(t, string(rootReadme), "plugin-kit-ai init my-plugin --template custom-logic")
mustContain(t, string(rootReadme), "plugin-kit-ai init my-plugin")
mustContain(t, string(rootReadme), "plugin-kit-ai generate .")
mustContain(t, string(rootReadme), "plugin-kit-ai validate . --platform codex-runtime --strict")
mustContain(t, string(rootReadme), "## Works Across Multiple Outputs")
mustContain(t, string(rootReadme), "## What To Do Next")
mustContain(t, string(rootReadme), "## Keep This Rule In Mind")
mustContain(t, historicalReadme, "`plugin-kit-ai` keeps authored source under `plugin/`, generates the supported outputs you need, and helps you validate the repo before handoff.")
mustContain(t, historicalReadme, "supported outputs for Claude, Codex, Gemini, Cursor, and OpenCode where the repo shape allows it")
mustContain(t, historicalReadme, "The honest promise is `one repo / many supported outputs`, not fake parity everywhere")
mustContain(t, historicalReadme, "overview: [plugin-kit-ai documentation](https://github.com/777genius/universal-agent-plugins/blob/9beca10448ac50fbe526a52101d1433a12471980/website/source/en/index.md)")
mustContain(t, historicalReadme, "fastest start: [Quickstart](https://github.com/777genius/universal-agent-plugins/blob/9beca10448ac50fbe526a52101d1433a12471980/website/source/en/guide/quickstart.md)")
mustContain(t, historicalReadme, "choose by job first: [Choose What You Are Building](https://github.com/777genius/universal-agent-plugins/blob/9beca10448ac50fbe526a52101d1433a12471980/website/source/en/guide/choose-what-you-are-building.md)")
mustContain(t, historicalReadme, "one repo, many outputs: [What You Can Build](https://github.com/777genius/universal-agent-plugins/blob/9beca10448ac50fbe526a52101d1433a12471980/website/source/en/guide/what-you-can-build.md)")
mustContain(t, historicalReadme, "honest caveat: [Support Boundary](https://github.com/777genius/universal-agent-plugins/blob/9beca10448ac50fbe526a52101d1433a12471980/website/source/en/reference/support-boundary.md)")
mustContain(t, historicalReadme, "## Choose What You Are Building")
mustContain(t, historicalReadme, "### Connect an online service")
mustContain(t, historicalReadme, "### Connect a local tool")
mustContain(t, historicalReadme, "### Build custom plugin logic")
mustContain(t, historicalReadme, "## Historical Quick Start")
mustContain(t, historicalReadme, "brew install 777genius/homebrew-plugin-kit-ai/plugin-kit-ai")
mustContain(t, historicalReadme, "npm: `npm i -g plugin-kit-ai@1.2.4` or `npx plugin-kit-ai@1.2.4 ...`")
mustContain(t, historicalReadme, "pipx (`public-beta`, only when that release is published to PyPI): `pipx install plugin-kit-ai==1.2.4`")
mustContain(t, historicalReadme, "fallback installer: `curl -fsSL https://raw.githubusercontent.com/777genius/plugin-kit-ai/main/scripts/install.sh | sh`")
mustContain(t, historicalReadme, "plugin-kit-ai init my-plugin --template online-service")
mustContain(t, historicalReadme, "plugin-kit-ai init my-plugin --template local-tool")
mustContain(t, historicalReadme, "plugin-kit-ai init my-plugin --template custom-logic")
mustContain(t, historicalReadme, "plugin-kit-ai init my-plugin")
mustContain(t, historicalReadme, "plugin-kit-ai generate .")
mustContain(t, historicalReadme, "plugin-kit-ai validate . --platform codex-runtime --strict")
mustContain(t, historicalReadme, "## Works Across Multiple Outputs")
mustContain(t, historicalReadme, "## What To Do Next")
mustContain(t, historicalReadme, "## Keep This Rule In Mind")
mustContain(t, string(cliReadme), "How To Publish Plugins")
mustContain(t, string(cliReadme), "https://777genius.github.io/plugin-kit-ai/docs/en/guide/how-to-publish-plugins.html")
mustContain(t, string(publishGuideEn), "codex-marketplace")
Expand All @@ -304,32 +321,32 @@ func TestContractClarity_RuntimeMetadataAndDocsStayAligned(t *testing.T) {
mustContain(t, string(publishGuideRu), "Gemini в v1 использует plan-and-readiness publication, а не local apply.")
mustContain(t, string(guideIndexEn), "/en/guide/how-to-publish-plugins")
mustContain(t, string(guideIndexRu), "/ru/guide/how-to-publish-plugins")
mustContain(t, string(rootReadme), "## Deep Product Details")
mustContain(t, string(rootReadme), "## Go Deeper By Goal")
mustContain(t, string(rootReadme), "### Fast Local Plugin")
mustContain(t, string(rootReadme), "### Production-Ready Plugin Repo")
mustContain(t, string(rootReadme), "### Already Have Native Config")
mustContain(t, string(rootReadme), "[examples/starters/README.md](examples/starters/README.md)")
mustContain(t, string(rootReadme), "[examples/local/README.md](examples/local/README.md)")
mustContain(t, string(rootReadme), "[docs/CHOOSING_HELPER_DELIVERY_MODE.md](docs/CHOOSING_HELPER_DELIVERY_MODE.md)")
mustContain(t, string(rootReadme), "the stable local Python and Node subset on `codex-runtime` and `claude`")
mustContain(t, string(rootReadme), "`doctor`, `bootstrap`, `validate --strict`, `export`, and bundle handoff for that stable local subset")
mustContain(t, string(rootReadme), "`generate`, `import`, and `normalize` are still `public-beta`")
mustContain(t, string(rootReadme), "[docs/generated/target_support_matrix.md](docs/generated/target_support_matrix.md)")
mustContain(t, string(rootReadme), "[docs/generated/support_matrix.md](docs/generated/support_matrix.md)")
mustContain(t, string(rootReadme), "[docs/SUPPORT.md](docs/SUPPORT.md)")
mustContain(t, string(rootReadme), "## SDK And CLI")
mustContain(t, string(rootReadme), "Go SDK packages:")
mustContain(t, string(rootReadme), "`github.com/777genius/plugin-kit-ai/sdk/claude`")
mustContain(t, string(rootReadme), "`github.com/777genius/plugin-kit-ai/sdk/codex`")
mustContain(t, string(rootReadme), "`github.com/777genius/plugin-kit-ai/sdk/gemini`")
mustContain(t, string(rootReadme), "./bin/plugin-kit-ai doctor ./my-plugin")
mustContain(t, string(rootReadme), "./bin/plugin-kit-ai bootstrap ./my-plugin")
mustContain(t, string(rootReadme), "./bin/plugin-kit-ai import ./native-plugin --from codex-runtime")
mustContain(t, string(rootReadme), "./bin/plugin-kit-ai capabilities --format json")
mustContain(t, string(rootReadme), "`plugin-kit-ai validate --format json` now emits the versioned `plugin-kit-ai/validate-report` contract")
mustContain(t, string(rootReadme), "[docs/CODEX_TARGET_BOUNDARY.md](docs/CODEX_TARGET_BOUNDARY.md)")
mustContain(t, string(rootReadme), "[docs/VALIDATE_JSON_CONTRACT.md](docs/VALIDATE_JSON_CONTRACT.md)")
mustContain(t, historicalReadme, "## Deep Product Details")
mustContain(t, historicalReadme, "## Go Deeper By Goal")
mustContain(t, historicalReadme, "### Fast Local Plugin")
mustContain(t, historicalReadme, "### Production-Ready Plugin Repo")
mustContain(t, historicalReadme, "### Already Have Native Config")
mustContain(t, historicalReadme, "[examples/starters/README.md](examples/starters/README.md)")
mustContain(t, historicalReadme, "[examples/local/README.md](examples/local/README.md)")
mustContain(t, historicalReadme, "[docs/CHOOSING_HELPER_DELIVERY_MODE.md](docs/CHOOSING_HELPER_DELIVERY_MODE.md)")
mustContain(t, historicalReadme, "the stable local Python and Node subset on `codex-runtime` and `claude`")
mustContain(t, historicalReadme, "`doctor`, `bootstrap`, `validate --strict`, `export`, and bundle handoff for that stable local subset")
mustContain(t, historicalReadme, "`generate`, `import`, and `normalize` are still `public-beta`")
mustContain(t, historicalReadme, "[docs/generated/target_support_matrix.md](docs/generated/target_support_matrix.md)")
mustContain(t, historicalReadme, "[docs/generated/support_matrix.md](docs/generated/support_matrix.md)")
mustContain(t, historicalReadme, "[docs/SUPPORT.md](docs/SUPPORT.md)")
mustContain(t, historicalReadme, "## SDK And CLI")
mustContain(t, historicalReadme, "Go SDK packages:")
mustContain(t, historicalReadme, "`github.com/777genius/plugin-kit-ai/sdk/claude`")
mustContain(t, historicalReadme, "`github.com/777genius/plugin-kit-ai/sdk/codex`")
mustContain(t, historicalReadme, "`github.com/777genius/plugin-kit-ai/sdk/gemini`")
mustContain(t, historicalReadme, "./bin/plugin-kit-ai doctor ./my-plugin")
mustContain(t, historicalReadme, "./bin/plugin-kit-ai bootstrap ./my-plugin")
mustContain(t, historicalReadme, "./bin/plugin-kit-ai import ./native-plugin --from codex-runtime")
mustContain(t, historicalReadme, "./bin/plugin-kit-ai capabilities --format json")
mustContain(t, historicalReadme, "`plugin-kit-ai validate --format json` now emits the versioned `plugin-kit-ai/validate-report` contract")
mustContain(t, historicalReadme, "[docs/CODEX_TARGET_BOUNDARY.md](docs/CODEX_TARGET_BOUNDARY.md)")
mustContain(t, historicalReadme, "[docs/VALIDATE_JSON_CONTRACT.md](docs/VALIDATE_JSON_CONTRACT.md)")
mustContain(t, string(cliReadme), "## Fast Local Plugin")
mustContain(t, string(cliReadme), "## Production-Ready Plugin Repo")
mustContain(t, string(cliReadme), "## Already Have Native Config")
Expand Down
46 changes: 46 additions & 0 deletions repotests/readme_boundary_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package pluginkitairepo_test

import (
"strings"
"testing"
)

// Normalize only Windows line endings; retain the exact historical heading and
// terminating newline so current and preserved-v1 assertions stay separated.
func cutHistoricalReadme(readme string) (current, historical string, found bool) {
return strings.Cut(strings.ReplaceAll(readme, "\r\n", "\n"), "### Historical authoring and development\n")
}

func TestHistoricalReadmeBoundaryLineEndings(t *testing.T) {
const heading = "### Historical authoring and development"
for _, newline := range []struct{ name, value string }{{"LF", "\n"}, {"CRLF", "\r\n"}} {
for _, tc := range []struct {
name, boundary string
found bool
}{
{"exact", heading + newline.value, true},
{"missing", "", false},
{"wrong_title", "### Historical authoring" + newline.value, false},
{"wrong_level", "## Historical authoring and development" + newline.value, false},
{"trailing_space", heading + " " + newline.value, false},
{"suffix", heading + " extra" + newline.value, false},
{"no_newline", heading, false},
{"bare_CR", heading + "\r", false},
} {
t.Run(newline.name+"/"+tc.name, func(t *testing.T) {
input := "current" + newline.value + tc.boundary + "historical" + newline.value
current, historical, found := cutHistoricalReadme(input)
if found != tc.found {
t.Fatalf("boundary found = %v, want %v", found, tc.found)
}
if found {
if current != "current\n" || historical != "historical\n" {
t.Fatalf("incorrect sections: current=%q historical=%q", current, historical)
}
} else if current != strings.ReplaceAll(input, "\r\n", "\n") || historical != "" {
t.Fatalf("missing boundary changed sections: current=%q historical=%q", current, historical)
}
})
}
}
}
11 changes: 10 additions & 1 deletion repotests/starter_template_sync_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,16 @@ func TestStarterTemplateSyncContractFilesStayAligned(t *testing.T) {
mustContain(t, workflow, "run: ./scripts/update-starter-template.sh")
mustContain(t, workflow, "default: \"all\"")
mustContain(t, workflow, "- all-runtime-package")
mustContain(t, rootReadme, "Codex and Claude starters across Go, Python, and")
// Preserved v1 starters remain discoverable without being advertised as
// root plugin.json templates for the unreleased standard authoring MVP.
_, historicalReadme, found := cutHistoricalReadme(rootReadme)
if !found {
t.Fatal("README missing historical authoring boundary")
}
mustContain(t, strings.Join(strings.Fields(historicalReadme), " "), "The repository preserves Codex and Claude starters across Go, Python, and Node/TypeScript.")
mustContain(t, historicalReadme, "[starters](examples/starters/README.md)")
mustContain(t, startersReadme, "Historical plugin-kit-ai v1 managed examples; baseline 1.2.4.")
mustContain(t, startersReadme, "These are not root `plugin.json` starters for the standard MVP.")
mustContain(t, cliReadme, "Official starter templates:")
mustContain(t, startersReadme, "These starter repos are the fastest way to get one working plugin repo that can later expand to more supported outputs.")
mustContain(t, startersReadme, "Use this template")
Expand Down
Loading