From 4602457011feaab6cbb6c37abab2e34e81beb256 Mon Sep 17 00:00:00 2001 From: Volv G Date: Sat, 4 Jul 2026 20:26:33 -0700 Subject: [PATCH] docs: add canonical tangent agent skills Assisted-By: devx/9c4ad24f-24d3-4eb9-8747-dbf53e3221df --- README.md | 4 ++ pyproject.toml | 1 + skills/tangent/OSS-CONVENTIONS.md | 52 ++++++++++------ skills/tangent/PORT-README.md | 6 +- skills/tangent/SKILL.md | 5 +- skills/tangent/agents/auth-wizard.md | 2 +- skills/tangent/agents/builder.md | 4 +- skills/tangent/agents/debugger.md | 8 +-- skills/tangent/agents/reporter.md | 3 +- skills/tangent/agents/researcher.md | 4 +- skills/tangent/agents/reviewer.md | 6 +- skills/tangent/references/setup.md | 31 +++++++--- .../tangent/references/step-0-initialize.md | 14 ++--- skills/tangent/references/tangle-tools.md | 33 +++++++---- tests/test_packaging.py | 59 +++++++++++++++++++ 15 files changed, 162 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index dcd0396..5482ae1 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,10 @@ uv run tangle sdk pipelines validate pipeline.yaml Custom API/codegen users can still run codegen from the fully capable install; generating bindings does not require removing the official `tangle-api` package. For project-local generated APIs, generate into a local source tree such as `src/tangle_api/generated` (and `src/tangle_api/schema/openapi.json` when you want `tangle api --schema-source official`) and run from that project so local `src/tangle_api` shadows site-packages. For packaged custom APIs, publish/provide a distribution named `tangle-api` with a version compatible with this `tangle-cli` release (for example `0.0.1a3+yourorg` for a `tangle-cli` dependency on `tangle-api==0.0.1a3`) via a private index, `--find-links`, or uv sources. As an expert escape hatch, `--no-deps` installs only `tangle-cli` and skips all dependencies, so that environment must manually provide every required runtime dependency plus its generated/custom `tangle_api`; this is acceptable for controlled codegen/custom scenarios but not normal UX. +## Agent skills + +This repo includes the Tangent agent-skill bundle under `skills/tangent/`. The bundle was ported from `tangle-cli-lab` and now treats this repository as the canonical source. It drives the public `tangle` / `tangle-cli` command surface, assumes the default `tangle-cli` install includes `tangle-api`, and keeps relative references (`agents/*.md`, `references/*.md`) self-contained for Pi-style skill loaders. The source distribution includes `skills/**` so downstream source-based consumers can inspect or vendor the skill docs with the release. + ## Quick command examples Local-only SDK commands: diff --git a/pyproject.toml b/pyproject.toml index 8e4bf86..239b68a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,6 +42,7 @@ build-backend = "uv_build" [tool.uv.build-backend] module-root = "packages/tangle-cli/src" +source-include = ["skills/**"] [tool.uv.sources] cloud-pipelines-backend = { git = "https://github.com/TangleML/tangle", rev = "stable_cli" } diff --git a/skills/tangent/OSS-CONVENTIONS.md b/skills/tangent/OSS-CONVENTIONS.md index 349662f..617f66c 100644 --- a/skills/tangent/OSS-CONVENTIONS.md +++ b/skills/tangent/OSS-CONVENTIONS.md @@ -19,7 +19,9 @@ and `api`) and **never** any internal wrapper/hook layer. ## 1. Invocation rule -**Run every command as `uv run tangle …` from a checkout of the `tangle-cli` repo.** +**Keep checkout/dev invocation separate from installed-tool invocation.** + +From a checkout of the `tangle-cli` repo, run commands through the workspace: ```bash uv run tangle quickstart @@ -28,20 +30,31 @@ uv run tangle sdk --help uv run tangle api --help ``` +For a persistent user-level CLI install, prefer uv tools: + +```bash +uv tool install tangle-cli +tangle quickstart +tangle-cli --help +``` + +For one-off execution without a persistent install, use `uvx`: + +```bash +uvx --from tangle-cli tangle --help +``` + +Generic Python environments may also use `pip install tangle-cli`; use +`uv pip install tangle-cli` only inside an explicitly managed virtualenv. + - **Never** prefix a command with an internal env-shim exec wrapper. That internal dev-env tooling must not appear in any ported file. -- As of 2026-06-12 `tangle-cli` is **not yet a public PyPI package** (it is - consumed internally as a vendored git submodule). So install text must say - `uv run tangle …` **from a checkout**. Present the public install path only as a - future state: - - > *Once `tangle-cli` is promoted to the public OSS package, you will be able to - > `pip install 'tangle-cli[native]'` and invoke `tangle …` directly. Until then, - > use `uv run tangle …` from a checkout of the repo.* - -- The `[native]` extra is what enables the static API-backed commands and the - handwritten `TangleApiClient` wrapper (see §3). In the `tangle-cli` workspace, `uv` - installs the workspace `tangle-api` package automatically for dev/tests. +- `tangle-cli` is a public PyPI package. The default install includes the + matching `tangle-api` package and supports static API-backed commands plus the + handwritten `TangleApiClient` wrapper (see §3). The old `[native]` extra is + only a compatibility/no-op alias. +- In the `tangle-cli` workspace, `uv` installs the workspace `tangle-api` package + automatically for dev/tests. - Help is standard cyclopts `--help`. **There is no `--help-extended` / `--help-full`.** - Skills live **in-repo** (checked into the `tangle-cli` repo). There is **no internal bundle-refresh step**; relative cross-references (`agents/*.md`, `references/*.md`) @@ -61,7 +74,7 @@ OSS replacement. **Verbs/flags below were verified against the `tangle-cli` sour | Internal | OSS | |---|---| -| ` -- …` | `uv run tangle …` (or installed `tangle …` once promoted) | +| ` -- …` | `uv run tangle …` from a checkout, or installed `tangle …` / `tangle-cli …` | | ` quickstart` | `tangle quickstart` (real; static onboarding text) | | `--help-extended` / `--help-full` | `--help` | | `from import TangleApiClient` | `from tangle_cli.client import TangleApiClient` (see §3) | @@ -161,9 +174,10 @@ existing = client.find_existing_components( A bare `TangleApiClient()` only works against the default localhost backend. - `TangleApiClient` lives in `tangle_cli.client` and inherits generated endpoint methods from `tangle_api.generated.operations.GeneratedTangleApiOperations`. - **Importing it requires the native bindings** — install the `[native]` extra (or - provide a local `tangle_api.generated` package) before `from tangle_cli.client import …`. - The top-level `import tangle_cli` is intentionally native-free. + **Importing it requires generated bindings**. The default `tangle-cli` install + includes `tangle-api`; custom API projects may provide a local or packaged + compatible `tangle_api.generated` package before `from tangle_cli.client import …`. + The top-level `import tangle_cli` intentionally does not eagerly import generated bindings. - **Prefer the CLI over Python snippets for status/polling.** Any internal snippet that calls unverified methods like `get_pipeline_run`, `get_execution_graph_state`, `set_verbose`, `.status_totals`, or `.root_execution_id` must be replaced. The @@ -200,7 +214,9 @@ internal backend's auth verification, and the internal package index **entirely* - **Run links:** replace internal run-URL links (`https:///runs/`) with `/runs/` **or** "inspect via `tangle sdk pipeline-runs details RUN_ID`". - **No internal package index.** Resolve dependencies against public PyPI - (`uv sync` / `tangle-cli[native]`). + (`uv sync` from a checkout, `uv tool install tangle-cli` for a persistent CLI, + or `uvx --from tangle-cli tangle …` for one-off execution). Generic Python + environments may also use `pip install tangle-cli`. - Example for a protected backend: ```bash diff --git a/skills/tangent/PORT-README.md b/skills/tangent/PORT-README.md index e755c8b..fccf8a5 100644 --- a/skills/tangent/PORT-README.md +++ b/skills/tangent/PORT-README.md @@ -38,11 +38,7 @@ references/ ← the loop steps + topic references ## How to invoke -All commands run as **`uv run tangle …` from a checkout of the `tangle-cli` repo**. `tangle-cli` is not yet -a published package, so the public `pip install 'tangle-cli[native]'` / bare `tangle …` -*invocation* form is presented as a future state; elsewhere `tangle` still appears as a bare -command noun in prose and in the §2 CLI map (the naming-surface exception). See -`OSS-CONVENTIONS.md` §1. +Commands can run as **`uv run tangle …` from a checkout of the `tangle-cli` repo**, from a persistent uv tool install (`uv tool install tangle-cli`, then `tangle …` / `tangle-cli …`), or as a one-off uvx command (`uvx --from tangle-cli tangle …`). Elsewhere, `tangle` still appears as a bare command noun in prose and in the §2 CLI map (the naming-surface exception). See `OSS-CONVENTIONS.md` §1. ## What changed from the internal bundle diff --git a/skills/tangent/SKILL.md b/skills/tangent/SKILL.md index 0f122cb..8e8e86f 100644 --- a/skills/tangent/SKILL.md +++ b/skills/tangent/SKILL.md @@ -22,10 +22,7 @@ bundle-refresh step. Relative cross-references in this skill (`agents/*.md`, `references/*.md`) resolve directly on disk. Read [`references/setup.md`](references/setup.md) to set up the CLI and auth. -Run every command as `uv run tangle …` from a checkout of the `tangle-cli` repo. (Once `tangle-cli` is promoted to the public OSS package, you will be able to -`pip install 'tangle-cli[native]'` and invoke `tangle …` directly; until then, use -`uv run tangle …` from a checkout.) See -[`OSS-CONVENTIONS.md`](OSS-CONVENTIONS.md) §1. +Run commands as `uv run tangle …` from a checkout of the `tangle-cli` repo. For an installed CLI, prefer `uv tool install tangle-cli`; for one-off execution, use `uvx --from tangle-cli tangle …`. See [`OSS-CONVENTIONS.md`](OSS-CONVENTIONS.md) §1. ## Commands diff --git a/skills/tangent/agents/auth-wizard.md b/skills/tangent/agents/auth-wizard.md index 50bc6b6..f069310 100644 --- a/skills/tangent/agents/auth-wizard.md +++ b/skills/tangent/agents/auth-wizard.md @@ -14,7 +14,7 @@ environment variables (see [OSS-CONVENTIONS.md §4](../OSS-CONVENTIONS.md)). ## Tools -**Run every command as `uv run tangle …` from a checkout of the `tangle-cli` repo.** +**From a checkout, run commands as `uv run tangle …`. For an installed CLI, prefer `uv tool install tangle-cli`; for one-off execution, use `uvx --from tangle-cli tangle …`.** Help is standard `--help` (there is no `--help-extended` / `--help-full`). Resolution precedence: explicit CLI option > `--config` file value > environment diff --git a/skills/tangent/agents/builder.md b/skills/tangent/agents/builder.md index 9fe46a2..d3316bc 100644 --- a/skills/tangent/agents/builder.md +++ b/skills/tangent/agents/builder.md @@ -11,9 +11,7 @@ components with local code changes for testing. ## Tools -**Run every `tangle` command via Bash as `uv run tangle …` from a checkout of the `tangle-cli` repo** (see [`../OSS-CONVENTIONS.md`](../OSS-CONVENTIONS.md) §1). Once `tangle-cli` is promoted to the public OSS package you will be able to -`pip install 'tangle-cli[native]'` and invoke `tangle …` directly; until then use -`uv run tangle …`. +**Run every `tangle` command via Bash as `uv run tangle …` from a checkout of the `tangle-cli` repo**. For an installed CLI, prefer `uv tool install tangle-cli`; for one-off execution, use `uvx --from tangle-cli tangle …` (see [`../OSS-CONVENTIONS.md`](../OSS-CONVENTIONS.md) §1). Run `uv run tangle quickstart` to discover available commands. Use `--help` on any command or group for detailed usage (there is no `--help-extended` / `--help-full`). diff --git a/skills/tangent/agents/debugger.md b/skills/tangent/agents/debugger.md index 8fc6ffb..5277faa 100644 --- a/skills/tangent/agents/debugger.md +++ b/skills/tangent/agents/debugger.md @@ -11,10 +11,10 @@ return a one-line diagnosis. ## Tools -**Always use the `tangle` CLI via Bash.** Run every command as `uv run tangle …` -from a checkout of the `tangle-cli` repo (see `OSS-CONVENTIONS.md` §1). Once `tangle-cli` is promoted to the public OSS package you will be able to `pip install -'tangle-cli[native]'` and invoke `tangle …` directly; until then, use `uv run -tangle …` from a checkout. +**Always use the `tangle` CLI via Bash.** Run commands as `uv run tangle …` +from a checkout of the `tangle-cli` repo. For an installed CLI, prefer +`uv tool install tangle-cli`; for one-off execution, use +`uvx --from tangle-cli tangle …` (see `OSS-CONVENTIONS.md` §1). Run `uv run tangle quickstart` to discover available commands. Use `--help` on any command (or group, e.g. `uv run tangle sdk pipeline-runs --help`) for detailed usage. diff --git a/skills/tangent/agents/reporter.md b/skills/tangent/agents/reporter.md index dde7ab8..9fa96ac 100644 --- a/skills/tangent/agents/reporter.md +++ b/skills/tangent/agents/reporter.md @@ -11,8 +11,7 @@ Generate an ML experiment report. Regenerate from scratch each round. ## Tools **Always use the `tangle` CLI via Bash. Do NOT use any MCP tools.** -Run every command as `uv run tangle …` from a checkout of the `tangle-cli` repo (see -[OSS-CONVENTIONS.md §1](../OSS-CONVENTIONS.md)). +Run commands as `uv run tangle …` from a checkout of the `tangle-cli` repo. For an installed CLI, prefer `uv tool install tangle-cli`; for one-off execution, use `uvx --from tangle-cli tangle …` (see [OSS-CONVENTIONS.md §1](../OSS-CONVENTIONS.md)). Run `uv run tangle quickstart` to discover available commands. Use `--help` on any command for detailed usage. diff --git a/skills/tangent/agents/researcher.md b/skills/tangent/agents/researcher.md index 17e4c4a..ef35344 100644 --- a/skills/tangent/agents/researcher.md +++ b/skills/tangent/agents/researcher.md @@ -13,9 +13,7 @@ Think like an MLE who reads papers and asks "what if we tried this?" ## Tools **Always use the `tangle` CLI via Bash. Do NOT use any MCP tool layer.** -Run every command as `uv run tangle …` from a checkout of the `tangle-cli` repo. (Once `tangle-cli` is promoted to the public OSS package you will be able to `pip install -'tangle-cli[native]'` and invoke `tangle …` directly; until then use `uv run tangle -…` from a checkout.) See [`../OSS-CONVENTIONS.md`](../OSS-CONVENTIONS.md) §1. +Run commands as `uv run tangle …` from a checkout of the `tangle-cli` repo. For an installed CLI, prefer `uv tool install tangle-cli`; for one-off execution, use `uvx --from tangle-cli tangle …`. See [`../OSS-CONVENTIONS.md`](../OSS-CONVENTIONS.md) §1. Run `uv run tangle quickstart` to discover available commands. Use `--help` on any command for detailed usage. For broader docs, see `uv run tangle sdk diff --git a/skills/tangent/agents/reviewer.md b/skills/tangent/agents/reviewer.md index f94506d..19d5732 100644 --- a/skills/tangent/agents/reviewer.md +++ b/skills/tangent/agents/reviewer.md @@ -12,8 +12,10 @@ ML methodology issues. Be skeptical. Check the work. ## Tools -**Always use the `tangle` CLI via Bash.** Run every command as `uv run tangle …` -from a checkout of the `tangle-cli` repo. See [OSS-CONVENTIONS.md](../OSS-CONVENTIONS.md) +**Always use the `tangle` CLI via Bash.** Run commands as `uv run tangle …` +from a checkout of the `tangle-cli` repo. For an installed CLI, prefer +`uv tool install tangle-cli`; for one-off execution, use +`uvx --from tangle-cli tangle …`. See [OSS-CONVENTIONS.md](../OSS-CONVENTIONS.md) §1 for the invocation rule and §4 for auth flags. Run `uv run tangle quickstart` to discover available commands. Use `--help` on any diff --git a/skills/tangent/references/setup.md b/skills/tangent/references/setup.md index 5799a0f..e6284a0 100644 --- a/skills/tangent/references/setup.md +++ b/skills/tangent/references/setup.md @@ -10,8 +10,7 @@ cross-references resolve directly on disk. ## 1. Install / run the CLI -The CLI is consumed from a checkout of the repo. Run every command as -`uv run tangle …`: +From a checkout, run commands through `uv run`: ```bash uv run tangle quickstart @@ -20,14 +19,28 @@ uv run tangle sdk --help uv run tangle api --help ``` +For a persistent user-level CLI install, prefer uv tools: + +```bash +uv tool install tangle-cli +tangle quickstart +tangle-cli --help +``` + +For one-off execution without a persistent install, use `uvx`: + +```bash +uvx --from tangle-cli tangle --help +``` + +Generic Python environments may also use `pip install tangle-cli`; use +`uv pip install tangle-cli` only inside an explicitly managed virtualenv. + `uv` resolves dependencies against public PyPI. In the `tangle-cli` workspace, `uv` installs the workspace `tangle-api` package automatically for dev/tests. The -`[native]` extra enables the static API-backed commands and the handwritten -`TangleApiClient` wrapper. - -> Once `tangle-cli` is promoted to the public OSS package, you will be able to -> `pip install 'tangle-cli[native]'` and invoke `tangle …` directly. Until then, -> use `uv run tangle …` from a checkout of the repo. +published default `tangle-cli` install includes `tangle-api`, enabling static +API-backed commands and the handwritten `TangleApiClient` wrapper. The old +`native` extra is retained only as a compatibility/no-op alias. Then discover available commands: ```bash @@ -143,4 +156,4 @@ fetch bytes, use the signed-URL recipe in | `403 Forbidden` | Authenticated but not permitted — re-run with a different `--token` for the right identity. | | Connection error / timeout | Wrong or unreachable `--base-url` / `TANGLE_API_URL`; confirm the backend is up. | | Want to see the raw HTTP exchange | Set `TANGLE_VERBOSE=1` for redacted request/response diagnostics. | -| Import error from `from tangle_cli.client import TangleApiClient` | Install the `[native]` extra (the client needs the native bindings). | +| Import error from `from tangle_cli.client import TangleApiClient` | Install `tangle-cli` normally so `tangle-api` is present, or provide a compatible local/custom `tangle_api.generated` package for a custom API. | diff --git a/skills/tangent/references/step-0-initialize.md b/skills/tangent/references/step-0-initialize.md index 405b9c5..6bb9f8d 100644 --- a/skills/tangent/references/step-0-initialize.md +++ b/skills/tangent/references/step-0-initialize.md @@ -11,17 +11,13 @@ core, run from a checkout of the `tangle-cli` repo: uv run tangle --help ``` -If that fails, work through `references/setup.md` first (checkout, `uv sync`, the -`[native]` extra, base-url/auth). Once `uv run tangle --help` works, discover the -available commands: +If that fails, work through `references/setup.md` first (checkout, `uv tool install tangle-cli`, or `uvx --from tangle-cli tangle …`; base-url/auth). Once `uv run tangle --help` or installed `tangle --help` works, discover the available commands: ```bash uv run tangle quickstart ``` -> Once `tangle-cli` is promoted to the public OSS package you will be able to -> `pip install 'tangle-cli[native]'` and invoke `tangle …` directly. Until then, -> use `uv run tangle …` from a checkout of the repo. +> For an installed CLI, prefer `uv tool install tangle-cli` and invoke `tangle …` or `tangle-cli …`; for one-off execution, use `uvx --from tangle-cli tangle …`. ## Scenario Directory @@ -31,8 +27,10 @@ All experiment state lives in the scenario directory. Set the absolute path: SCENARIO_DIR= ``` -All `tangle` commands run via `uv run tangle …`. All file reads/writes use -absolute `SCENARIO_DIR` paths. These are different locations — don't confuse them. +From a checkout, all `tangle` commands run via `uv run tangle …`. From an +installed CLI, use `tangle …` / `tangle-cli …`; for one-off execution, use +`uvx --from tangle-cli tangle …`. All file reads/writes use absolute +`SCENARIO_DIR` paths. These are different locations — don't confuse them. ## No Scenario Yet? Build One diff --git a/skills/tangent/references/tangle-tools.md b/skills/tangent/references/tangle-tools.md index 442f626..308db35 100644 --- a/skills/tangent/references/tangle-tools.md +++ b/skills/tangent/references/tangle-tools.md @@ -14,7 +14,7 @@ with new commands and flags — discover the current surface with `--help` and ## Install / Invoke -Run every command as `uv run tangle …` from a checkout of the `tangle-cli` repo: +From a checkout, run commands as `uv run tangle …`: ```bash uv run tangle quickstart @@ -23,13 +23,24 @@ uv run tangle sdk --help uv run tangle api --help ``` -The `[native]` extra enables the static API-backed commands and the handwritten -`TangleApiClient` (see [Programmatic client](#programmatic-client-python)). In the `tangle-cli` workspace `uv` installs the workspace `tangle-api` package automatically for -dev/tests. +For a persistent user-level CLI install, prefer uv tools: -> Once `tangle-cli` is promoted to the public OSS package, you will be able to -> `pip install 'tangle-cli[native]'` and invoke `tangle …` directly. Until then, -> use `uv run tangle …` from a checkout of the repo. +```bash +uv tool install tangle-cli +tangle quickstart +tangle-cli --help +``` + +For one-off execution without a persistent install, use `uvx`: + +```bash +uvx --from tangle-cli tangle --help +``` + +Generic Python environments may also use `pip install tangle-cli`; use +`uv pip install tangle-cli` only inside an explicitly managed virtualenv. + +The default `tangle-cli` install includes `tangle-api` and enables static API-backed commands plus the handwritten `TangleApiClient` (see [Programmatic client](#programmatic-client-python)). In the `tangle-cli` workspace, `uv` installs the workspace `tangle-api` package automatically for dev/tests. The old `native` extra is a compatibility/no-op alias. ## Discover Available Commands @@ -361,10 +372,10 @@ existing = client.find_existing_components( - Constructor: `TangleApiClient(base_url, *, token=, auth_header=, header=, headers=, …)`. A bare `TangleApiClient()` only works against the default localhost backend. -- Importing it requires the native bindings — install the `[native]` extra (or - provide a local `tangle_api.generated` package) before - `from tangle_cli.client import …`. The top-level `import tangle_cli` is - intentionally native-free. +- Importing it requires generated bindings. The default `tangle-cli` install + includes `tangle-api`; custom API projects can provide a compatible local or + packaged `tangle_api.generated` package before `from tangle_cli.client import …`. + The top-level `import tangle_cli` intentionally does not eagerly import generated bindings. - The verified surface is `client.pipeline_runs_get(run_id)` and the `find_existing_components(...)` helper. For status/graph state, prefer the CLI: `tangle sdk pipeline-runs status RUN_ID` and diff --git a/tests/test_packaging.py b/tests/test_packaging.py index a65aba0..f083f6a 100644 --- a/tests/test_packaging.py +++ b/tests/test_packaging.py @@ -5,6 +5,7 @@ import os import subprocess import sys +import tarfile import zipfile from pathlib import Path @@ -26,6 +27,15 @@ def _build_wheel(tmp_path: Path, *args: str) -> Path: return wheels[-1] +def _build_sdist(tmp_path: Path, *args: str) -> Path: + out_dir = tmp_path / "dist" + command = ["uv", "build", "--sdist", "--out-dir", str(out_dir), *args] + subprocess.run(command, cwd=_REPO_ROOT, check=True, text=True, capture_output=True) + sdists = sorted(out_dir.glob("*.tar.gz")) + assert sdists, f"no sdist built by {' '.join(command)}" + return sdists[-1] + + def _write_import_stubs(path: Path) -> None: path.mkdir() _write_runtime_stubs(path) @@ -102,6 +112,55 @@ def _write_consumer_tangle_api(path: Path) -> Path: return source_root +def test_tangent_skill_bundle_is_in_repo_and_current() -> None: + skill_root = _REPO_ROOT / "skills" / "tangent" + expected = [ + "SKILL.md", + "OSS-CONVENTIONS.md", + "PORT-README.md", + "agents/auth-wizard.md", + "agents/builder.md", + "agents/debugger.md", + "agents/reporter.md", + "agents/researcher.md", + "agents/reviewer.md", + "agents/scenario-builder.md", + "references/tangle-tools.md", + "references/setup.md", + "references/step-0-initialize.md", + "references/step-1-analyze.md", + "references/step-2-hypothesize.md", + "references/step-3-submit.md", + "references/step-4-monitor.md", + "references/step-5-evaluate.md", + "references/step-6-synthesize.md", + "references/step-7-decide.md", + ] + for relative in expected: + assert (skill_root / relative).is_file(), relative + + markdown = "\n".join(path.read_text(encoding="utf-8") for path in skill_root.rglob("*.md")) + assert "tangle-cli-lab" not in markdown + assert "not yet a public PyPI package" not in markdown + assert "pip install 'tangle-cli[native]'" not in markdown + assert "uv install" not in markdown + assert "uv tool install tangle-cli" in markdown + assert "uvx --from tangle-cli tangle" in markdown + assert "uv pip install tangle-cli` only inside an explicitly managed virtualenv" in markdown + assert "pip install tangle-cli" in markdown + assert "compatibility/no-op" in markdown + + +def test_tangle_cli_sdist_includes_tangent_skill_bundle(tmp_path) -> None: + sdist = _build_sdist(tmp_path) + with tarfile.open(sdist) as archive: + names = archive.getnames() + + assert any(name.endswith("/skills/tangent/SKILL.md") for name in names) + assert any(name.endswith("/skills/tangent/OSS-CONVENTIONS.md") for name in names) + assert any(name.endswith("/skills/tangent/references/tangle-tools.md") for name in names) + + def test_tangle_cli_wheel_supports_expert_no_deps_import_path_without_tangle_api(tmp_path) -> None: wheel = _build_wheel(tmp_path) stubs = tmp_path / "stubs"