Skip to content

Use the public contree-client library#13

Open
mosquito wants to merge 7 commits into
masterfrom
feature/use-contree-client
Open

Use the public contree-client library#13
mosquito wants to merge 7 commits into
masterfrom
feature/use-contree-client

Conversation

@mosquito

Copy link
Copy Markdown
Collaborator

Summary

Switches the CLI onto the public contree-client package (>=0.1.3) and reworks skill installation semantics.

contree-client adoption

  • contree-client becomes the only runtime dependency: HTTP transport, typed API methods, models, retries, operation helpers, image reference resolution, profile parsing, and stream decoding now come from the library.
  • client.py shrinks to CLI-side glue: CliClient announcing the CLI identity in the User-Agent, client_from_profile() with the CLI retry policy, and version helpers.
  • config.py keeps only the write side of profile management (atomic 0600 save, switch, delete with session-DB cleanup) on top of contree_client.profiles.
  • uv.lock now resolves the package from PyPI instead of an editable sibling checkout; docs and tests updated across the board.

skill install/remove rework

  • Directory specs mean a project root: every kind resolves to its project location under it (.claude/skills/contree, .agents/skills/contree, .claude/agents/*.md, ...). Paths pointing at a skill artifact (SKILL.md inside, contree basename, .md suffix, tool markers) stay literal.
  • Codex skills move to .agents/skills (project) / ~/.agents/skills (global), matching current Codex discovery; rules stay in $CODEX_HOME.
  • Install writes only the files it owns instead of replacing the target directory; remove deletes only those files and prunes empty layout dirs. Installing into a repository can never wipe foreign content (regression coverage included).
  • The Codex sandbox section renders the resolved CONTREE_HOME into writable_roots, so overridden data directories get correct sandbox permissions.
  • Claude subagent frontmatter uses the tools field, agent template uses the documented comma-separated form, and stale registry rows are forgotten on remove.

Test plan

  • make tests (ruff + mypy strict + pytest): 1869 passed, 4 skipped against contree-client 0.1.3 from PyPI.
  • Live smoke: uv run contree skill install codex:PATH lands in PATH/.agents/skills/contree; raw-dir install/remove cycle leaves the project byte-identical.

mosquito added 3 commits July 17, 2026 12:48
…e sandbox

Directory specs now mean a project root: every kind resolves to its
project location under it (.claude/skills/contree, .agents/skills/contree,
.claude/agents/*.md, ...); paths pointing at a skill artifact stay literal.
Codex skills move to .agents/skills (project) and ~/.agents/skills (global),
rules remain in CODEX_HOME. Install writes only the files it owns instead
of replacing the target directory, remove deletes only those files and
prunes empty layout dirs, so installing into a repository can never wipe
foreign content. The Codex sandbox section renders the resolved
CONTREE_HOME into writable_roots. Subagent frontmatter uses the tools
field, the workflow numbering is owned by the template, and stale registry
rows are forgotten on remove.
…as POSIX

skills_from_spec treated any spec containing a colon as kind:HINT, so
C:\path never expanded as a project root. The Codex sandbox rendered
CONTREE_HOME with backslashes, which are escape sequences inside TOML
basic strings; render with forward slashes instead. Path assertions in
the CONTREE_HOME tests no longer assume the pytest tmp dir lives
outside the user home.
Comment thread contree_cli/client.py Outdated
Comment thread contree_cli/docker/kw_from.py
Comment thread contree_cli/skill.py
Comment thread contree_cli/cli/export.py Outdated
mosquito added 4 commits July 17, 2026 23:59
…fing

The library yields the body exactly as served with compressed=True and
transparently decompressed tar with compressed=False, so the CLI writes
the stream as-is and drops the magic-byte passthrough.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates contree-cli from its internal HTTP/DTO layer to the public contree-client package, and updates CLI semantics, docs, and tests to match the new typed-client surface (including skill install layout changes and new export/build behaviors).

Changes:

  • Replace ad-hoc HTTP calls with contree-client typed methods/models and shared runtime helpers (errors, stream decoding, pagination/iterators).
  • Rework skill install/remove semantics (project-root specs, owned-file writes/removals, Codex layout alignment) and update docs/examples for renamed global flags (-o/--format/--output, etc.).
  • Add/expand end-to-end and doc-lint tests (entrypoint lifecycle, export command, documentation example validation).

Reviewed changes

Copilot reviewed 83 out of 84 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/test_use.py Update use tests for typed client mocks
tests/test_url_fetch.py Switch URL fetch tests to ensure_file/models
tests/test_tag.py Update tag tests for typed tag APIs/errors
tests/test_show.py Update show tests for typed operation responses
tests/test_shell_repl.py Align shell error handling + -o flag
tests/test_shell_parser.py Update parser tests for -o global flag
tests/test_shell_completer.py Update completion fixtures to typed models
tests/test_session.py Update session path tests to new helper
tests/test_session_cmd.py Add typed operation helpers for session cmd tests
tests/test_main.py New: assert client context-manager lifecycle in main
tests/test_ls.py Update ls tests for typed inspect + raw RequestSpec path
tests/test_kill.py Update cancel/kill tests for typed operations
tests/test_export.py New: coverage for export archive streaming
tests/test_doc_examples.py New: validate documented CLI examples against parser/help
tests/test_cp.py Update cp tests for streaming download API + progress
tests/test_config.py Migrate config tests to library Profile + constants
tests/test_cd.py Update cd validation tests to typed inspect/list errors
tests/test_cat.py Update cat tests to typed download API + call assertions
tests/test_auth.py Update auth tests to typed whoami parsing behavior
tests/conftest.py Replace fake HTTP stack with contree_client.testing client
README.md Update docs for dependencies + -o flag + workflow tweaks
pyproject.toml Add runtime dependency contree-client>=0.1.3
docs/tutorial/workflows.md Update examples to -o global output flag
docs/tutorial/shell.md Update REPL format flag docs to -o
docs/tutorial/installation.md Note contree-client dependency
docs/tutorial/images.md Update tag delete example to -U
docs/tutorial/configuration.md Update examples to -o global output flag
docs/index.md Update landing page examples + dependency messaging
docs/commands/show.md Update show docs for -o (needs --raw wording fix)
docs/commands/shell.md Update shell docs to -o global output flag
docs/commands/ps.md Fix kind flag example to -k
docs/commands/operation.md Update operation docs to -o global output flag
docs/commands/ls.md Update ls docs to -o global output flag
docs/commands/images.md Update images docs (include untagged via -a, uuid example)
docs/commands/file.md Update file docs to -o global output flag
docs/commands/cd.md Update cd semantics docs (print cwd; validate via inspect API)
docs/commands/auth.md Update auth docs to -o global output flag
contree_cli/types.py Update flag aliases (-o, --output, force -f) + add --decompress
contree_cli/skill_body.md Refresh skill text (sandbox section templated, -o examples)
contree_cli/shell/sources.py Use typed list APIs + server-side tag prefix filtering
contree_cli/shell/repl.py Handle ContreeAPIError + -o/--output format builtin
contree_cli/shell/completer.py Update completion builtins/flags for -o/--output
contree_cli/shell/argmap.py Add completion mapping for export args
contree_cli/session.py Add SessionStore.select_session helper
contree_cli/manual.md Update manual examples to -o global output flag
contree_cli/log.py Mirror CLI log level into contree_client logger
contree_cli/docker/url_fetch.py Use ensure_file; close HTTPError in HEAD helper
contree_cli/docker/kw_run.py Use typed spawn/status helpers + stream decoding from library
contree_cli/docker/kw_from.py Implement multistage sealing + typed import/wait/cancel
contree_cli/docker/kw_copy.py Implement COPY --from via archive export + extraction RUN (bug noted)
contree_cli/docker/kw_add.py Reject unsupported ADD --from explicitly
contree_cli/docker/context.py Update build context typing + stage tracking
contree_cli/config.py Refactor config around contree_client.profiles + session DB helpers
contree_cli/cli/use.py Use client.resolve_image; reuse SessionStore via select_session
contree_cli/cli/tag.py Use typed tag APIs + resolve-on-delete behavior
contree_cli/cli/skill.py Switch to multi-skill spec expansion + registry cleanup on missing
contree_cli/cli/show.py Use typed operation status + terminal-status constants
contree_cli/cli/session.py Use typed polling; raw RequestSpec for session_key filtering
contree_cli/cli/operation.py Switch to typed iterators + typed cancel/status; progress logs
contree_cli/cli/ls.py Use typed inspect list + raw RequestSpec for ?text=1
contree_cli/cli/images.py Use typed iterators/import helpers + credential model
contree_cli/cli/file.py Use typed streaming download + ensure_file + file iterators
contree_cli/cli/export.py New: export archive streaming command
contree_cli/cli/cp.py Use streaming download API; support DEST directory targets
contree_cli/cli/cd.py Validate dirs via typed inspect/list + typed errors
contree_cli/cli/cat.py Use typed download; preserve cache behavior
contree_cli/cli/build.py Multistage notes; use session_db_path + typed tag update
contree_cli/cli/auth.py Use typed whoami + stricter parsing/error handling
contree_cli/arguments.py Register new export command
contree_cli/agent.md Update agent guide examples and include export
contree_cli/main.py Drive client via context manager using ExitStack
contree_cli/init.py Update contextvar types to contree-client Profile/CliClient

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +199 to +201
try:
for chunk in ctx.client.inspect_image_archive(image_uuid, src):
buffer.write(chunk)
Comment thread contree_cli/cli/export.py
Comment on lines +141 to +153
start = time.monotonic()
try:
if args.output:
with Path(args.output).open("wb") as sink:
written = write_stream(chunks, sink)
else:
written = write_stream(chunks, sys.stdout.buffer)
sys.stdout.buffer.flush()
except NotFoundError:
if args.output:
Path(args.output).unlink(missing_ok=True)
logger.error("export: %s: not found in image", path)
return 1
Comment thread docs/commands/show.md
Comment on lines 76 to 80
Nested objects (`metadata`, `result`) are dropped from the flat row
— use `--raw` for the full server payload, or `-f json` to keep the
— use `--raw` for the full server payload, or `-o json` to keep the
flat structured row.

Pass `--raw` to skip all of the above and print each operation's
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants