diff --git a/README.md b/README.md index 4e0ded005..829dd3e89 100644 --- a/README.md +++ b/README.md @@ -127,15 +127,54 @@ Requires **Python 3.10+**. Licensed under [Apache-2.0](LICENSE). **InferRSI is a Developer Preview (pre-release), with no API stability promise.** The [daily release bot](docs/releases.md) publishes a version when the default -branch changes. This preview is not on PyPI. Download the wheel and `SHA256SUMS` -from the selected [Release](https://github.com/InferMatrixLab/InferRSI/releases), -verify its checksum, then install the downloaded wheel: +branch changes. + +### Use InferRSI in Codex + +Install the plugin in two steps. Use a local Codex client with ZIP upload support, +Python 3.10+ and Git. + +1. **Download the package from GitHub.** Open + [Releases](https://github.com/InferMatrixLab/InferRSI/releases) and download + `inferrsi-codex-plugin-vX.Y.Z.zip` from the selected version's assets. +2. **Install it in Codex.** If your client offers **Plugins → Add → Upload plugin + archive**, use it to import the downloaded ZIP. Select **Install plugin** on + the InferRSI detail page if that action is available. Once installed, enable + InferRSI and start a new conversation in your target repository. + +[Installation video (English)](docs/assets/inferrsi-codex-install-en.mp4) + +The runtime and knowledge are bundled; core operations need no separate pip +install or InferRSI source checkout. The [plugin guide](docs/codex-plugin.md#install-from-the-release-zip) +covers checksum verification and client compatibility. The video highlights the +click order with English UI illustrations based on the supplied Codex screenshots; +it does not record a completed installation. + +Try a first task: + +> Use InferRSI to research this engine's memory bottleneck. Find relevant +> knowledge and explain what is needed for a controlled comparison. + +Or inspect existing evidence: + +> Use InferRSI to inspect the existing run I provide and explain its verdict, +> missing evidence and next action. + +Setup checks readiness without starting benchmarks. Experiments run locally on +the prepared target machine using your accepted gates and budget. See the +[plugin guide](docs/codex-plugin.md#install-from-the-release-zip) for installation, +updates and troubleshooting. + +### Use the CLI + +This preview is not on PyPI. Download the wheel and `SHA256SUMS` from the selected +[Release](https://github.com/InferMatrixLab/InferRSI/releases), verify its checksum, +then install the downloaded wheel: ```bash python -m pip install "/inferrsi--py3-none-any.whl" ``` -For Codex, use the [standalone plugin ZIP](docs/codex-plugin.md#install-from-the-release-zip). For CLI development from this checkout: ```bash @@ -168,7 +207,7 @@ campaigns out of the common AB/BA scheduler, process cleanup and evaluator. ![InferRSI system architecture: inputs, experiment loop and evidence](docs/assets/system-architecture-en.svg) [English SVG](docs/assets/system-architecture-en.svg) · -[中文原图](docs/assets/system-architecture-zh-CN.svg) +[Chinese original](docs/assets/system-architecture-zh-CN.svg) The supplied overview and its English translation summarize the intended workflow. Evidence feeds the next experiment through explicit review and user-selected diff --git a/docs/assets/inferrsi-codex-install-en.mp4 b/docs/assets/inferrsi-codex-install-en.mp4 new file mode 100644 index 000000000..e64cb6482 Binary files /dev/null and b/docs/assets/inferrsi-codex-install-en.mp4 differ diff --git a/docs/codex-plugin.md b/docs/codex-plugin.md index 7d0c0b983..3914fcaca 100644 --- a/docs/codex-plugin.md +++ b/docs/codex-plugin.md @@ -29,13 +29,18 @@ The downloaded archive bundles the same-version InferRSI runtime and knowledge; installation requires no source checkout, package build or separate pip install. There is no marketplace catalog, registration step or distribution branch. -In a Codex client with **Plugin Creator** available, provide the downloaded ZIP -and ask: "Import this InferRSI plugin ZIP as a private plugin." For an existing -InferRSI plugin, ask to update that plugin from the ZIP instead of creating a -duplicate. Use the returned plugin link to enable it, then start a new -conversation. The import uploads the archive to the account/workspace; it still -requires a network connection. Here, offline package means the runtime and -resources are included, not that the Codex client can operate air-gapped. +If your Codex client offers **Plugins → Add → Upload plugin archive**, use it +to import the downloaded `inferrsi-codex-plugin-vX.Y.Z.zip`. If the InferRSI +detail page offers **Install plugin**, select it and follow the prompts. After +installation, enable InferRSI, open your target repository and start a new +conversation. + +[Watch or download the installation guide (English narration and subtitles)](https://raw.githubusercontent.com/InferMatrixLab/InferRSI/main/docs/assets/inferrsi-codex-install-en.mp4). +The video uses English UI illustrations based on the supplied screenshots to show +the menu click order; it does not record a completed upload or installation. +Exact labels and availability depend +on the client and workspace permissions. Here, offline package describes the +included runtime and resources; it does not guarantee offline client operation. Clients without archive import cannot install this package directly. The current Codex CLI's `plugin add` accepts marketplace selectors, not ZIP paths; do not pass @@ -90,8 +95,9 @@ an existing distribution/archive. For release builds, first build the runtime so SCM generates `_version.py`, then pass `--release-version ` and a versioned output directory. The builder -requires that version to match the generated runtime, and stamps only the -generated plugin manifest. The tracked source template remains unchanged. +requires that version to match the generated runtime. It stamps the generated +plugin manifest and pins the bundled README's video link to the release tag. +The tracked source template remains unchanged. Unbuilt source previews use the runtime's explicit `0+unknown` fallback. Only the ZIP is attached to Releases. The raw `plugins/inferrsi/` source template @@ -105,15 +111,16 @@ source owners. No new core dependencies or CI lanes are introduced. ## Updates, disable and uninstall -Download and verify the new Release ZIP, then ask Plugin Creator to update the -existing InferRSI plugin from that archive. Check the selected bundle with +Download and verify the new Release ZIP, then use the client's supported update +or replacement flow for the existing InferRSI plugin. Check the selected bundle with `--plugin-info` in a new conversation. Do not overwrite an installed cache or carry forward an old runtime by hand. -Plugin Creator updates overlay existing files. Ask it to compare the old and new -runtime manifests and explicitly delete removed runtime/resources while retaining -the same plugin identity and audience; omitting a file from the ZIP alone does -not remove its installed copy. +For older installations managed through Plugin Creator, file updates overlay +existing files. Compare the old and new runtime manifests and explicitly remove +obsolete runtime files and resources while retaining the same plugin identity +and audience. Files omitted from that update archive remain installed. Verify +how native ZIP replacement behaves on your target client. Disable InferRSI in the desktop plugin UI when you want to retain its installation but stop loading it. To uninstall, remove the selected InferRSI plugin in the diff --git a/tests/test_codex_plugin.py b/tests/test_codex_plugin.py index 3b9b61e22..6c272005f 100644 --- a/tests/test_codex_plugin.py +++ b/tests/test_codex_plugin.py @@ -2,11 +2,14 @@ import hashlib import json +import posixpath +import re import shutil import subprocess import sys import zipfile from pathlib import Path +from urllib.parse import unquote, urlsplit import pytest @@ -147,7 +150,13 @@ def test_archive_contains_only_one_standalone_plugin(tmp_path): names = archive.namelist() assert {Path(name).parts[0] for name in names} == {"inferrsi"} assert "inferrsi/plugin.json" in names - assert "inferrsi/README.md" in names + readme = archive.read("inferrsi/README.md") + assert readme == (PROJECT / "docs/codex-plugin.md").read_bytes() + for target in re.findall(r"\[[^\]]*\]\(([^\s)]+)\)", readme.decode("utf-8")): + link = urlsplit(target) + if not link.scheme and not link.netloc and link.path: + path = posixpath.normpath(posixpath.join("inferrsi", unquote(link.path))) + assert path in names, f"Broken link in plugin README: {target}" assert not any("marketplace" in name or ".agents" in name for name in names) metadata = json.loads(archive.read("inferrsi/plugin.json")) assert metadata["$schema"] == "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json" @@ -181,9 +190,18 @@ def test_release_archive_is_installable_and_all_versions_match(release_distribut project, template, result = release_distribution check_plugin(Path(result["archive"]), "v0.2.0") assert (project / "plugins/inferrsi/plugin.json").read_bytes() == template + source_readme = (project / "docs/codex-plugin.md").read_bytes() + assert source_readme == (PROJECT / "docs/codex-plugin.md").read_bytes() + video_base = b"https://raw.githubusercontent.com/InferMatrixLab/InferRSI/" + video_path = b"/docs/assets/inferrsi-codex-install-en.mp4" + main_video = video_base + b"main" + video_path + assert main_video in source_readme with zipfile.ZipFile(result["archive"]) as archive: name = "inferrsi/plugin.json" assert json.loads(archive.read(name))["version"] == "0.2.0" + assert archive.read("inferrsi/README.md") == source_readme.replace( + main_video, video_base + b"refs/tags/v0.2.0" + video_path, + ) with pytest.raises(ValueError, match="agree exactly"): check_plugin(Path(result["archive"]), "v0.2.1") diff --git a/tools/build_codex_plugin.py b/tools/build_codex_plugin.py index bfdcb6614..673002f89 100644 --- a/tools/build_codex_plugin.py +++ b/tools/build_codex_plugin.py @@ -72,7 +72,18 @@ def build_plugin( plugin = Path(staging) / "inferrsi" shutil.copytree(template, plugin, ignore=shutil.ignore_patterns("__pycache__", "*.pyc")) shutil.copyfile(project / "LICENSE", plugin / "LICENSE") - shutil.copyfile(project / "docs" / "codex-plugin.md", plugin / "README.md") + readme = (project / "docs" / "codex-plugin.md").read_bytes() + if release_version is not None: + video_url = ( + "https://raw.githubusercontent.com/InferMatrixLab/InferRSI/{ref}/" + "docs/assets/inferrsi-codex-install-en.mp4" + ) + readme = readme.replace( + video_url.format(ref="main").encode("ascii"), + video_url.format(ref=f"refs/tags/v{release_version}").encode("ascii"), + 1, + ) + (plugin / "README.md").write_bytes(readme) runtime = plugin / "runtime" hashes = {} for path in sorted(source.rglob("*")):