scripts/update_plugin_cachebuster.py
scripts/update_plugin_cachebuster.pyBrowse 11 files
691 tokens
3,045 bytes
Token encoding: o200k_base
Snapshot 18d7ace
← Back to SKILL.md
1#!/usr/bin/env python32"""Rewrite a local plugin version to a single Codex cachebuster suffix."""3 4from __future__ import annotations5 6import argparse7import json8import re9import sys10from datetime import datetime, timezone11from pathlib import Path12 13sys.path.insert(0, str(Path(__file__).resolve().parent))14 15from identifier_validation import validate_plugin_identifier16 17 18CACHEBUSTER_PREFIX = "codex"19 20 21def parse_args() -> argparse.Namespace:22 parser = argparse.ArgumentParser(23 description=(24 "Rewrite a local plugin's version so it preserves everything before '+' and uses "25 "a single +codex.<cachebuster> suffix."26 )27 )28 parser.add_argument("plugin_path", help="Path to the plugin root directory")29 parser.add_argument(30 "--cachebuster",31 help="Optional cachebuster token to embed in the plugin version",32 )33 return parser.parse_args()34 35 36def main() -> None:37 args = parse_args()38 plugin_root = Path(args.plugin_path).expanduser().resolve()39 manifest_path = plugin_root / ".codex-plugin" / "plugin.json"40 manifest = load_manifest(manifest_path)41 42 plugin_name = manifest.get("name")43 if not isinstance(plugin_name, str) or not plugin_name.strip():44 raise ValueError(f"{manifest_path} must contain a non-empty string 'name'.")45 validate_plugin_identifier(plugin_name)46 47 version = manifest.get("version")48 if not isinstance(version, str) or not version.strip():49 raise ValueError(f"{manifest_path} must contain a non-empty string 'version'.")50 cachebuster = sanitize_cachebuster(args.cachebuster or default_cachebuster())51 next_version = with_cachebuster(version, cachebuster)52 manifest["version"] = next_version53 manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")54 55 print(f"Updated plugin version: {version} -> {next_version}")56 57 58def load_manifest(manifest_path: Path) -> dict[str, object]:59 if not manifest_path.is_file():60 raise FileNotFoundError(f"missing manifest: {manifest_path}")61 payload = json.loads(manifest_path.read_text(encoding="utf-8"))62 if not isinstance(payload, dict):63 raise ValueError(f"{manifest_path} must contain a JSON object.")64 return payload65 66 67def sanitize_cachebuster(value: str) -> str:68 sanitized = re.sub(r"[^a-z0-9-]+", "-", value.strip().lower())69 sanitized = re.sub(r"-{2,}", "-", sanitized).strip("-")70 if not sanitized:71 raise ValueError("Cachebuster must contain at least one letter or digit.")72 return sanitized73 74 75def default_cachebuster() -> str:76 return datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")77 78 79def with_cachebuster(version: str, cachebuster: str) -> str:80 version_prefix = version.split("+", 1)[0]81 return f"{version_prefix}+{CACHEBUSTER_PREFIX}.{cachebuster}"82 83 84if __name__ == "__main__":85 try:86 main()87 except Exception as err: # noqa: BLE001 - CLI should surface a single clear message.88 print(str(err), file=sys.stderr)89 raise SystemExit(1) from err90 Referenced from SKILL.md
SKILL.mdView in source ↗
Source excerpt starting at line 75.SKILL.mdView in source ↗75python3 scripts/read_marketplace_name.py76python3 scripts/update_plugin_cachebuster.py <plugin-path>77```
Source excerpt starting at line 208.208 or `marketplace.json`. Use the update flow documented in209 `references/installing-and-updating.md` and `scripts/update_plugin_cachebuster.py`.210- Do not tell the user to run `codex plugin marketplace add` for the default personal-marketplace
