From 124e5bc4e84697aaf843b93cec6aef9978ea0288 Mon Sep 17 00:00:00 2001 From: Evostructs Date: Tue, 18 Aug 2026 11:39:09 +0800 Subject: [PATCH] docs: generalize installation and harden release --- .github/workflows/ci.yml | 18 +++++++ CHANGELOG.md | 16 ++++++ README.md | 61 +++++++++++++++------ denser/__init__.py | 2 +- denser/skills/README.md | 75 ++++++++++++++++++++------ denser/skills/denser-compress/SKILL.md | 9 ++-- pyproject.toml | 14 ++++- tests/test_version.py | 14 +++++ 8 files changed, 169 insertions(+), 40 deletions(-) create mode 100644 tests/test_version.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e20e51f..6def1aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,6 +65,7 @@ jobs: run: | python - <<'PY' from pathlib import Path + from tarfile import open as open_tar from zipfile import ZipFile wheel = next(Path("dist").glob("*.whl")) @@ -75,6 +76,23 @@ jobs: assert any( name.endswith(".dist-info/licenses/THIRD_PARTY_NOTICES.md") for name in names ) + + sdist = next(Path("dist").glob("*.tar.gz")) + with open_tar(sdist, "r:gz") as archive: + sdist_names = {member.name for member in archive.getmembers()} + forbidden = ( + "/build/", + "/.venv/", + "/.mypy_cache/", + "/.pytest_cache/", + "/.ruff_cache/", + "/site-packages/", + "/Scripts/activate", + ) + leaked = sorted( + name for name in sdist_names if any(marker in name for marker in forbidden) + ) + assert not leaked, f"source distribution contains local build files: {leaked[:10]}" PY - name: Install wheel and run offline smoke test diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a9a078..66ad02e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ All notable changes to this project are documented here. The format follows [Kee ## [Unreleased] +## [0.2.0-alpha.3] — 2026-08-18 + +### Changed +- Reworked installation around three explicit paths: the agent-independent + Python CLI/library, an OpenAI Codex skill, and a Claude Code skill. Codex + setup now follows the official npm, ChatGPT sign-in, and skill-location + documentation. +- Generalized the bundled skill instructions and documentation so the same + workflow can run in Codex or Claude Code. + +### Security +- Explicitly excluded local build directories, virtual environments, and tool + caches from source distributions, and added a package-content regression + check. The affected `0.2.0-alpha.2` source archive is withdrawn; no API keys, + credentials, or commit email were present in that archive. + ## [0.2.0-alpha.2] — 2026-08-18 ### Added diff --git a/README.md b/README.md index 5cac1d6..9922d27 100644 --- a/README.md +++ b/README.md @@ -280,30 +280,60 @@ behavior changes reproducible in a way that an opaque runtime event is not. ## Installation -### Option 1 — As a Claude Code skill (no API key, no Python) +denser can be used as a regular CLI/library with any agent, or as an interactive +skill inside Codex or Claude Code. -If you use Claude Code, install the `denser-compress` skill: +### Option 1 — CLI and Python library (agent-independent) ```bash git clone https://github.com/Evostructs/denser.git -bash denser/denser/skills/install.sh # macOS / Linux -# or: denser\denser\skills\install.ps1 # Windows PowerShell +cd denser +python -m pip install . +denser --version ``` -Restart Claude Code. Then in any session: +This is the general installation for scripts, CI, benchmarks, and Python use. +Commands that call a model still need the corresponding provider or authenticated +CLI; deterministic inspection commands do not. -> "compress this skill at `~/.claude/skills/my-skill/SKILL.md`" +### Option 2 — OpenAI Codex skill (no separate API key or Python) + +If Codex is not installed, the official cross-platform npm option is: + +```bash +npm install -g @openai/codex +codex +``` + +On first launch, choose **Sign in with ChatGPT** or another available sign-in +method. See the [official Codex CLI installation +guide](https://learn.chatgpt.com/docs/codex/cli). + +Then ask Codex to install denser from this repository: + +> `$skill-installer install the denser-compress skill from https://github.com/Evostructs/denser/tree/main/denser/skills/denser-compress` -The skill runs inside Claude Code's authenticated session — no separate API key needed. See [`denser/skills/README.md`](denser/skills/README.md). +Invoke it with `$denser-compress`, or describe a matching compression task. +Codex uses its existing authenticated session; denser needs no separate API key. -### Option 2 — As a Python library from source +### Option 3 — Claude Code skill (no separate API key or Python) + +If you use Claude Code, install the `denser-compress` skill: ```bash git clone https://github.com/Evostructs/denser.git -cd denser -pip install -e ".[dev]" +bash denser/denser/skills/install.sh # macOS / Linux +# or: denser\denser\skills\install.ps1 # Windows PowerShell ``` +Restart Claude Code. Then in any session: + +> "compress this skill at `~/.claude/skills/my-skill/SKILL.md`" + +The skill runs inside Claude Code's authenticated session. For manual Codex and +Claude Code installation, verification, and removal, see +[`denser/skills/README.md`](denser/skills/README.md). + --- ## Quickstart @@ -531,13 +561,12 @@ The hook uses a local estimate, makes no API call, and never blocks a commit on length alone. The reference sizes are review prompts, not quality thresholds. See [`integrations/README.md`](integrations/README.md). -### Claude Code skill - -```bash -bash denser/skills/install.sh -``` +### Agent skill -The `denser-compress` skill runs inside Claude Code's authenticated session — no separate API key. See [`denser/skills/README.md`](denser/skills/README.md). +The portable `denser-compress` skill works in both OpenAI Codex and Claude Code +without a separate provider API key. See +[`denser/skills/README.md`](denser/skills/README.md) for tool-specific install +commands. --- diff --git a/denser/__init__.py b/denser/__init__.py index 3256f8b..e40566b 100644 --- a/denser/__init__.py +++ b/denser/__init__.py @@ -85,7 +85,7 @@ verify, ) -__version__ = "0.2.0a1" +__version__ = "0.2.0a3" __all__ = [ "AUDIT_REPORT_SCHEMA_VERSION", diff --git a/denser/skills/README.md b/denser/skills/README.md index 2db074c..e16580f 100644 --- a/denser/skills/README.md +++ b/denser/skills/README.md @@ -1,23 +1,59 @@ -# denser skills for Claude Code +# denser-compress agent skill -Claude Code skills that bring the denser framework into your editor. No Python, no API key — Claude Code uses its own authenticated session. +A portable skill that brings the denser workflow into OpenAI Codex or Claude +Code. It needs no Python and no separate provider API key because it runs inside +the agent's authenticated session. ## Skills ### `denser-compress` Produces a shorter candidate for a skill, system prompt, tool description, -memory entry, `CLAUDE.md`, or one-shot doc using role-aware rewrite guidance, +memory entry, `CLAUDE.md`, `AGENTS.md`, or one-shot doc using role-aware rewrite guidance, with a preservation report and an approval step before overwriting. The bundled checklist does not prove behavior preservation. -Trigger phrases: "compress this skill", "make this CLAUDE.md denser", "shorten this prompt"... +Trigger phrases: "compress this skill", "make this AGENTS.md denser", "make this +CLAUDE.md denser", "shorten this prompt"... Anti-triggers (the skill will decline): creative writing, code refactoring, chat transcripts, commit messages. denser is for LLM-bound prompt-like text, not general summarization. --- -## Installation +## Install in OpenAI Codex + +Install Codex CLI if needed. The official npm option is: + +```bash +npm install -g @openai/codex +codex +``` + +On first launch, choose **Sign in with ChatGPT** or another available sign-in +method. Then, inside Codex, ask: + +> `$skill-installer install the denser-compress skill from https://github.com/Evostructs/denser/tree/main/denser/skills/denser-compress` + +For a manual user-level installation, copy the skill to the location Codex +documents for personal skills: + +```bash +git clone https://github.com/Evostructs/denser.git +mkdir -p "$HOME/.agents/skills" +cp -R denser/denser/skills/denser-compress "$HOME/.agents/skills/" +``` + +```powershell +git clone https://github.com/Evostructs/denser.git +New-Item -ItemType Directory -Force "$HOME\.agents\skills" | Out-Null +Copy-Item -Recurse -Force ".\denser\denser\skills\denser-compress" "$HOME\.agents\skills\" +``` + +Codex detects skill changes automatically. If the skill does not appear, restart +Codex. See the official [Codex CLI installation](https://learn.chatgpt.com/docs/codex/cli) +and [skill locations](https://learn.chatgpt.com/docs/build-skills) documentation. + +## Install in Claude Code ### macOS / Linux @@ -31,7 +67,7 @@ bash denser/skills/install.sh denser\skills\install.ps1 ``` -Both scripts copy the skill directory to `~/.claude/skills/` and tell Claude Code where it's installed. +Both scripts copy the skill directory to `~/.claude/skills/` and tell Claude Code where it is installed. ### Manual install @@ -47,21 +83,25 @@ Claude Code scans `~/.claude/skills/` on startup. Restart Claude Code after inst ## Verify -After install, open Claude Code and ask: +In Codex, invoke the skill explicitly: + +> `Use $denser-compress to compress ./AGENTS.md.` + +In Claude Code, ask: > "Compress this skill at `~/.claude/skills/some-skill/SKILL.md`" -If the `denser-compress` skill loads, you'll see Claude follow the compression workflow (read, analyze, report, ask before writing). If nothing happens, check that the skill directory is at `~/.claude/skills/denser-compress/` and that both `SKILL.md` and `REFERENCE_taxonomy.md` are present. +If the skill loads, the agent follows the compression workflow: read, analyze, +report, and ask before writing. If nothing happens, check that the skill folder +contains both `SKILL.md` and `REFERENCE_taxonomy.md` in `$HOME/.agents/skills/` +for Codex or `~/.claude/skills/` for Claude Code. --- -## Uninstall - -```bash -rm -rf ~/.claude/skills/denser-compress -``` +## Remove -Restart Claude Code. +Remove the `denser-compress` folder from `$HOME/.agents/skills/` for Codex or +`~/.claude/skills/` for Claude Code, then restart the agent if it still appears. --- @@ -69,10 +109,11 @@ Restart Claude Code. The skill and the library are independent: -| | Python library | Claude Code skill | +| | Python library | Agent skill | |---|---|---| -| Requires | Local source install + provider credentials | Nothing; just Claude Code | +| Requires | Local source install + provider credentials for model-backed commands | An authenticated Codex or Claude Code session | | Best for | CI, batch, eval, benchmarks, plots | Interactive in-editor compression | | Entry point | `denser compress` CLI, `denser.compress()` function | "compress this ..." prompt in chat | -You can use either, both, or neither. The skill is the friction-free onramp for Claude Code users; the library is for pipelines and research. +You can use either or both. The skill is the friction-free interactive onramp; +the library is for pipelines and research. diff --git a/denser/skills/denser-compress/SKILL.md b/denser/skills/denser-compress/SKILL.md index 09b0f4a..cd13d67 100644 --- a/denser/skills/denser-compress/SKILL.md +++ b/denser/skills/denser-compress/SKILL.md @@ -2,7 +2,7 @@ name: denser-compress description: | Produce a shorter candidate for a skill, system prompt, tool description, - memory entry, CLAUDE.md, or one-shot doc using role-aware rewrite guidance + memory entry, CLAUDE.md, AGENTS.md, or one-shot doc using role-aware rewrite guidance and preservation analysis. Use when the user asks to compress / shorten / denser-ify / reduce a prompt-like file or inline text. Do NOT use for general text summarization; denser is role-aware and task-typed. Also do @@ -42,13 +42,13 @@ Does it persist across a session? → skill Is it prepended to every call in the session? → system_prompt - Is it a CLAUDE.md (or equivalent project-level file)? + Is it a CLAUDE.md, AGENTS.md, or equivalent project-level file? → claude_md ``` ## Workflow -1. **Read** the input text (use the Read tool if it's a file). +1. **Read** the input text using the agent's available file-reading tool. 2. **Read `REFERENCE_taxonomy.md`** from this skill's directory (alongside this SKILL.md file). It contains the preserve / strip rules and an @@ -95,7 +95,8 @@ Does it persist across a session? 7. **Ask**: "Write compressed version to `` (overwriting original)? [y/N]". Default is NO. Only write if user says yes. -8. If the user approves, use the Write tool to overwrite the original file. +8. If the user approves, use the agent's available file-editing mechanism to + overwrite the original file. If they decline, do nothing further — the compressed text was shown, they can copy-paste if they want. diff --git a/pyproject.toml b/pyproject.toml index 470ea7a..e9bcf51 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "denser" -version = "0.2.0a2" +version = "0.2.0a3" description = "Behavior-fidelity audits for version-controlled LLM context." readme = "README.md" license = "Apache-2.0" @@ -61,7 +61,17 @@ Documentation = "https://github.com/Evostructs/denser/tree/main/docs" packages = ["denser"] [tool.hatch.build.targets.sdist] -exclude = ["/handoff*.md"] +exclude = [ + "/handoff*.md", + "/build", + "/build/**", + "/.venv", + "/.venv/**", + "/.mypy_cache", + "/.pytest_cache", + "/.ruff_cache", + "/**/__pycache__", +] [tool.ruff] line-length = 100 diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 0000000..7d6fc18 --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,14 @@ +"""Package-version consistency checks.""" + +import re +from pathlib import Path + +import denser + + +def test_runtime_version_matches_package_metadata() -> None: + pyproject = Path("pyproject.toml").read_text(encoding="utf-8") + project = pyproject.split("[project]", 1)[1].split("\n[", 1)[0] + match = re.search(r'^version = "([^"]+)"$', project, flags=re.MULTILINE) + assert match is not None + assert denser.__version__ == match.group(1)