convertible-cli 0.4.0__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/CHANGELOG.md +7 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/PKG-INFO +32 -3
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/README.md +31 -2
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/__init__.py +19 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/drive.py +5 -2
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/explain/catalog.py +10 -5
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/pyproject.toml +1 -1
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_cli.py +23 -1
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/uv.lock +1 -1
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/agent-config/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/agent-config/scripts/show.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/cicd/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/run-tests/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/sonarclaude/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/spec-to-plan/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/think/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/think/scripts/think.sh +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/version-bump/SKILL.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills.local.yaml.example +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.devague/current +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.devague/current_plan +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.devague/frames/convertible-gains-an-extensibility-layer-like-clau.json +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.devague/frames/convertible-v0-ships-point-it-at-a-repo-task-and-i.json +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.devague/plans/convertible-gains-an-extensibility-layer-like-clau.json +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.devague/plans/convertible-v0-ships-point-it-at-a-repo-task-and-i.json +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.flake8 +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.github/workflows/publish.yml +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.github/workflows/tests.yml +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.gitignore +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/.markdownlint-cli2.yaml +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/CLAUDE.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/LICENSE +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/__init__.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/__main__.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/artifact.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_banner-big.txt +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_banner.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_banner.txt +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/__init__.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/cli.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/commands.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/doctor.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/explain.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/hooks.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/learn.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/overview.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/session.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/wheels.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_commands/whoami.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_errors.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/cli/_output.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/commands.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/config.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/configdir.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/contract.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/engine.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/engines/__init__.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/engines/mock.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/engines/vllm_openai.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/explain/__init__.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/handoff.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/hooks.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/loop.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/registry.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/convertible/tools.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/culture.yaml +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/docs/plans/2026-05-26-convertible-v0-ships-point-it-at-a-repo-task-and-i.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/docs/plans/2026-05-27-convertible-gains-an-extensibility-layer-like-clau.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/docs/skill-sources.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/docs/specs/2026-05-26-convertible-v0-ships-point-it-at-a-repo-task-and-i.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/docs/specs/2026-05-27-convertible-gains-an-extensibility-layer-like-clau.md +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/sonar-project.properties +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/__init__.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_artifact.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_banner.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_boundary.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_cli_introspection.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_commands.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_commands_cli.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_config.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_configdir.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_contract.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_drive.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_e2e_extensibility.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_e2e_mock.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_engine.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_handoff.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_hooks.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_hooks_cli.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_loop.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_mock_engine.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_registry.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_review_fixes.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_session.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_tools.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_vllm_live.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_vllm_openai.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_wheels.py +0 -0
- {convertible_cli-0.4.0 → convertible_cli-0.5.0}/tests/test_zero_deps.py +0 -0
|
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/). This project
|
|
6
6
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.5.0] - 2026-05-27
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Bare `convertible` (no subcommand) now opens the interactive harness (the `session` palette) when run at a terminal — the natural "get in and drive" gesture. Piped, redirected, or otherwise non-interactive, it still prints usage, preserving the discoverable surface for scripts and agents. `-h/--help` is unaffected.
|
|
13
|
+
- Reframed `convertible drive` help and `explain` text to lead with the goal/instruction ("drive toward a goal") rather than "run a repo task"; the repo is the target, not the headline. No behavior change.
|
|
14
|
+
|
|
8
15
|
## [0.4.0] - 2026-05-27
|
|
9
16
|
|
|
10
17
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: convertible-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Convertible CLI is a swappable coder-agent harness that turns different models into repo workers behind one shared task contract.
|
|
5
5
|
Project-URL: Homepage, https://github.com/agentculture/convertible
|
|
6
6
|
Project-URL: Issues, https://github.com/agentculture/convertible/issues
|
|
@@ -17,6 +17,27 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
|
|
18
18
|
# convertible
|
|
19
19
|
|
|
20
|
+
```text
|
|
21
|
+
,"^,::,:::::I::::::^
|
|
22
|
+
^!'` `"^,. ::`
|
|
23
|
+
`,;;i;,,' .!^'`",. "<," " ;,^
|
|
24
|
+
^ '"^";"^```,":::','"'^`"."'.,:^,i::,"".
|
|
25
|
+
.I. ' I-l '",I;!ii,I.,,l;;IlIl:i!:::::,,,^^;",,'
|
|
26
|
+
'^ ""::``':. .`";,"```"^.. '^^'":,''.
|
|
27
|
+
::,`;!"..^..'^"^ .' .."" ..`"^ ..`"`'"".
|
|
28
|
+
;;l!i:' ^ '^"`. `"`.. ',^.. `` '^
|
|
29
|
+
:i>I!lII". .' .''^` '`^' .`". ^. :;lI.
|
|
30
|
+
",l!`;"':l;,,`. .' '",'. ^...'^`'"...^l'":;Ii!!l:!';.
|
|
31
|
+
^''^., '`^^`:l;"^"',!~ .^^^,""..'`^. .^l,I''^.:l!;;;i>|+,!IlI::^
|
|
32
|
+
`;. :>i":` "`, ',^^" "; I.'. :::"^:;iil;'":^; '"
|
|
33
|
+
'^"'"IlI,.:,::;:' .`;"!l:``,,"``',,,^,,:ll!,,l^
|
|
34
|
+
":^:,I^:"!;:: :I>l:::"`""::,:I>!<i^ " ;.
|
|
35
|
+
",;"Il;i^: ',":;"`'`'^, ><[il```'
|
|
36
|
+
" ;;I"l:^.^;^''lI" :^::",:,'
|
|
37
|
+
,`:;,I.^ ''
|
|
38
|
+
`. " "
|
|
39
|
+
```
|
|
40
|
+
|
|
20
41
|
> Convertible CLI is a swappable coder-agent harness that turns different models
|
|
21
42
|
> into repo workers behind one shared task contract.
|
|
22
43
|
>
|
|
@@ -106,10 +127,13 @@ engine, so it binds equally to `mock`, `vllm-openai`, and any future wheel.
|
|
|
106
127
|
uv sync
|
|
107
128
|
uv run pytest -n auto # full suite, no network needed
|
|
108
129
|
|
|
130
|
+
# Open the interactive harness (the session palette) at a terminal:
|
|
131
|
+
uv run convertible
|
|
132
|
+
|
|
109
133
|
# Discover the engines installed in this environment:
|
|
110
134
|
uv run convertible wheels list
|
|
111
135
|
|
|
112
|
-
# Drive a
|
|
136
|
+
# Drive toward a goal with the deterministic mock engine (no model, no network):
|
|
113
137
|
uv run convertible drive "add a CONTRIBUTING.md stub" --repo . --engine mock --no-pr
|
|
114
138
|
```
|
|
115
139
|
|
|
@@ -297,6 +321,11 @@ loop, hooks, and artifact — no parallel code path):
|
|
|
297
321
|
uv run convertible session --repo /path/to/repo --engine vllm-openai
|
|
298
322
|
```
|
|
299
323
|
|
|
324
|
+
Running `convertible` with no arguments **at a terminal** opens this same palette
|
|
325
|
+
(with the default engine and repo) — the natural "get in and drive" gesture.
|
|
326
|
+
Piped, redirected, or otherwise non-interactive, bare `convertible` prints usage
|
|
327
|
+
instead, so scripts and agents keep a discoverable surface.
|
|
328
|
+
|
|
300
329
|
The session loops until the user enters `q`, `quit`, or an empty line. Any
|
|
301
330
|
driver flags accepted by `drive` (`--engine`, `--no-pr`, `--base-url`, etc.)
|
|
302
331
|
are also accepted by `session`.
|
|
@@ -333,7 +362,7 @@ rely on a non-existent flag.
|
|
|
333
362
|
|
|
334
363
|
| Verb | What it does |
|
|
335
364
|
|------|--------------|
|
|
336
|
-
| `drive <
|
|
365
|
+
| `drive <goal>` | Drive toward a goal/instruction: work autonomously through a coder engine; write the artifact; hand off. |
|
|
337
366
|
| `drive --command <name> [args…]` | Expand a saved command template and drive it. |
|
|
338
367
|
| `commands list` | List discovered command templates for a repo. |
|
|
339
368
|
| `commands overview` | Describe the commands surface. |
|
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# convertible
|
|
2
2
|
|
|
3
|
+
```text
|
|
4
|
+
,"^,::,:::::I::::::^
|
|
5
|
+
^!'` `"^,. ::`
|
|
6
|
+
`,;;i;,,' .!^'`",. "<," " ;,^
|
|
7
|
+
^ '"^";"^```,":::','"'^`"."'.,:^,i::,"".
|
|
8
|
+
.I. ' I-l '",I;!ii,I.,,l;;IlIl:i!:::::,,,^^;",,'
|
|
9
|
+
'^ ""::``':. .`";,"```"^.. '^^'":,''.
|
|
10
|
+
::,`;!"..^..'^"^ .' .."" ..`"^ ..`"`'"".
|
|
11
|
+
;;l!i:' ^ '^"`. `"`.. ',^.. `` '^
|
|
12
|
+
:i>I!lII". .' .''^` '`^' .`". ^. :;lI.
|
|
13
|
+
",l!`;"':l;,,`. .' '",'. ^...'^`'"...^l'":;Ii!!l:!';.
|
|
14
|
+
^''^., '`^^`:l;"^"',!~ .^^^,""..'`^. .^l,I''^.:l!;;;i>|+,!IlI::^
|
|
15
|
+
`;. :>i":` "`, ',^^" "; I.'. :::"^:;iil;'":^; '"
|
|
16
|
+
'^"'"IlI,.:,::;:' .`;"!l:``,,"``',,,^,,:ll!,,l^
|
|
17
|
+
":^:,I^:"!;:: :I>l:::"`""::,:I>!<i^ " ;.
|
|
18
|
+
",;"Il;i^: ',":;"`'`'^, ><[il```'
|
|
19
|
+
" ;;I"l:^.^;^''lI" :^::",:,'
|
|
20
|
+
,`:;,I.^ ''
|
|
21
|
+
`. " "
|
|
22
|
+
```
|
|
23
|
+
|
|
3
24
|
> Convertible CLI is a swappable coder-agent harness that turns different models
|
|
4
25
|
> into repo workers behind one shared task contract.
|
|
5
26
|
>
|
|
@@ -89,10 +110,13 @@ engine, so it binds equally to `mock`, `vllm-openai`, and any future wheel.
|
|
|
89
110
|
uv sync
|
|
90
111
|
uv run pytest -n auto # full suite, no network needed
|
|
91
112
|
|
|
113
|
+
# Open the interactive harness (the session palette) at a terminal:
|
|
114
|
+
uv run convertible
|
|
115
|
+
|
|
92
116
|
# Discover the engines installed in this environment:
|
|
93
117
|
uv run convertible wheels list
|
|
94
118
|
|
|
95
|
-
# Drive a
|
|
119
|
+
# Drive toward a goal with the deterministic mock engine (no model, no network):
|
|
96
120
|
uv run convertible drive "add a CONTRIBUTING.md stub" --repo . --engine mock --no-pr
|
|
97
121
|
```
|
|
98
122
|
|
|
@@ -280,6 +304,11 @@ loop, hooks, and artifact — no parallel code path):
|
|
|
280
304
|
uv run convertible session --repo /path/to/repo --engine vllm-openai
|
|
281
305
|
```
|
|
282
306
|
|
|
307
|
+
Running `convertible` with no arguments **at a terminal** opens this same palette
|
|
308
|
+
(with the default engine and repo) — the natural "get in and drive" gesture.
|
|
309
|
+
Piped, redirected, or otherwise non-interactive, bare `convertible` prints usage
|
|
310
|
+
instead, so scripts and agents keep a discoverable surface.
|
|
311
|
+
|
|
283
312
|
The session loops until the user enters `q`, `quit`, or an empty line. Any
|
|
284
313
|
driver flags accepted by `drive` (`--engine`, `--no-pr`, `--base-url`, etc.)
|
|
285
314
|
are also accepted by `session`.
|
|
@@ -316,7 +345,7 @@ rely on a non-existent flag.
|
|
|
316
345
|
|
|
317
346
|
| Verb | What it does |
|
|
318
347
|
|------|--------------|
|
|
319
|
-
| `drive <
|
|
348
|
+
| `drive <goal>` | Drive toward a goal/instruction: work autonomously through a coder engine; write the artifact; hand off. |
|
|
320
349
|
| `drive --command <name> [args…]` | Expand a saved command template and drive it. |
|
|
321
350
|
| `commands list` | List discovered command templates for a repo. |
|
|
322
351
|
| `commands overview` | Describe the commands surface. |
|
|
@@ -61,6 +61,17 @@ def _argv_has_json(argv: list[str] | None) -> bool:
|
|
|
61
61
|
return any(t == "--json" or t.startswith("--json=") for t in tokens)
|
|
62
62
|
|
|
63
63
|
|
|
64
|
+
def _stdio_is_interactive() -> bool:
|
|
65
|
+
"""Whether stdin and stdout are both interactive terminals.
|
|
66
|
+
|
|
67
|
+
Bare ``convertible`` opens the interactive harness only at a real terminal;
|
|
68
|
+
isolated as a module function so tests can force the interactive branch
|
|
69
|
+
without a TTY (mirrors :func:`convertible.cli._banner._isatty`). Both streams
|
|
70
|
+
must be a TTY: the palette reads from stdin and renders its chrome to stdout.
|
|
71
|
+
"""
|
|
72
|
+
return sys.stdin.isatty() and sys.stdout.isatty()
|
|
73
|
+
|
|
74
|
+
|
|
64
75
|
def _build_parser() -> argparse.ArgumentParser:
|
|
65
76
|
from convertible.cli._commands import cli as _cli_group
|
|
66
77
|
from convertible.cli._commands import commands as _commands_group
|
|
@@ -136,6 +147,14 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
136
147
|
args = parser.parse_args(argv)
|
|
137
148
|
|
|
138
149
|
if args.command is None:
|
|
150
|
+
# Bare `convertible` opens the interactive harness at a terminal; piped /
|
|
151
|
+
# redirected / non-interactive it prints usage so scripts and agents keep
|
|
152
|
+
# a discoverable surface. `-h/--help` is handled by argparse before here,
|
|
153
|
+
# so the help surface (and the teken rubric, which probes --help) stay
|
|
154
|
+
# available either way. Re-parsing ["session"] reuses the session
|
|
155
|
+
# subparser's defaults and func wiring — no parallel code path.
|
|
156
|
+
if _stdio_is_interactive():
|
|
157
|
+
return _dispatch(parser.parse_args(["session"]))
|
|
139
158
|
parser.print_help()
|
|
140
159
|
return 0
|
|
141
160
|
|
|
@@ -224,7 +224,10 @@ def cmd_drive(args: argparse.Namespace) -> int:
|
|
|
224
224
|
def register(sub: argparse._SubParsersAction) -> None:
|
|
225
225
|
p = sub.add_parser(
|
|
226
226
|
"drive",
|
|
227
|
-
help=
|
|
227
|
+
help=(
|
|
228
|
+
"Drive toward a goal: work autonomously on a request or instruction "
|
|
229
|
+
"through a coder engine, then hand off the result."
|
|
230
|
+
),
|
|
228
231
|
)
|
|
229
232
|
# ``instruction`` is now zero-or-more positional tokens (nargs="*") so
|
|
230
233
|
# ``--command`` can be the sole input without argparse raising an error.
|
|
@@ -232,7 +235,7 @@ def register(sub: argparse._SubParsersAction) -> None:
|
|
|
232
235
|
"instruction",
|
|
233
236
|
nargs="*",
|
|
234
237
|
help=(
|
|
235
|
-
"
|
|
238
|
+
"A goal or instruction to pursue autonomously. "
|
|
236
239
|
"Mutually exclusive with --command. "
|
|
237
240
|
"When --command is used, any positional tokens are passed as template arguments."
|
|
238
241
|
),
|
|
@@ -18,9 +18,13 @@ A clonable template for AgentCulture mesh agents. It carries an agent-first CLI
|
|
|
18
18
|
buildable/deployable package baseline. Clone it, rename the package, edit
|
|
19
19
|
`culture.yaml`, and you have a new agent.
|
|
20
20
|
|
|
21
|
+
Run `convertible` with no verb at a terminal to open the interactive harness (the
|
|
22
|
+
`session` palette); piped or non-interactive, it prints this usage instead.
|
|
23
|
+
|
|
21
24
|
## Verbs
|
|
22
25
|
|
|
23
|
-
- `convertible drive <
|
|
26
|
+
- `convertible drive <goal>` — drive toward a goal/instruction; work autonomously
|
|
27
|
+
through a coder engine and hand off the result.
|
|
24
28
|
- `convertible session` — foreground interactive palette over the drive path.
|
|
25
29
|
- `convertible wheels list` — list discovered engine wheels.
|
|
26
30
|
- `convertible whoami` — identity probe from `culture.yaml`.
|
|
@@ -122,10 +126,11 @@ itself (distinct from the global `overview`, which describes the agent).
|
|
|
122
126
|
_DRIVE = """\
|
|
123
127
|
# convertible drive
|
|
124
128
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
change as a branch + PR. The
|
|
128
|
-
`--
|
|
129
|
+
Drive toward a goal: hand convertible a request or instruction and it works
|
|
130
|
+
autonomously — selecting an engine wheel, running the bounded agentic tool-loop,
|
|
131
|
+
writing a result artifact, and handing off the change as a branch + PR. The repo
|
|
132
|
+
is the target (`--repo`, default cwd); the same invocation works for every
|
|
133
|
+
engine — only `--engine` changes.
|
|
129
134
|
|
|
130
135
|
## Usage
|
|
131
136
|
|
|
@@ -18,12 +18,34 @@ def test_version_flag(capsys: pytest.CaptureFixture[str]) -> None:
|
|
|
18
18
|
assert __version__ in capsys.readouterr().out
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
def
|
|
21
|
+
def test_no_args_non_tty_prints_help(
|
|
22
|
+
capsys: pytest.CaptureFixture[str], monkeypatch: pytest.MonkeyPatch
|
|
23
|
+
) -> None:
|
|
24
|
+
# Force the non-interactive branch so this is deterministic regardless of
|
|
25
|
+
# pytest's capture mode: under `pytest -s` from a real terminal stdin/stdout
|
|
26
|
+
# would be TTYs and bare invocation would otherwise open the session loop
|
|
27
|
+
# (and block on input()). Non-interactive must fall back to usage, preserving
|
|
28
|
+
# the discoverable surface for scripts and agents.
|
|
29
|
+
monkeypatch.setattr("convertible.cli._stdio_is_interactive", lambda: False)
|
|
22
30
|
rc = main([])
|
|
23
31
|
assert rc == 0
|
|
24
32
|
assert "usage: convertible" in capsys.readouterr().out
|
|
25
33
|
|
|
26
34
|
|
|
35
|
+
def test_no_args_tty_opens_session(
|
|
36
|
+
capsys: pytest.CaptureFixture[str], monkeypatch: pytest.MonkeyPatch
|
|
37
|
+
) -> None:
|
|
38
|
+
# At an interactive terminal, bare `convertible` opens the session harness.
|
|
39
|
+
# Force the interactive branch via the isolated seam, and stub input() to a
|
|
40
|
+
# quit token so the session renders its palette header then exits cleanly.
|
|
41
|
+
monkeypatch.setattr("convertible.cli._stdio_is_interactive", lambda: True)
|
|
42
|
+
monkeypatch.setattr("builtins.input", lambda *a, **k: "q")
|
|
43
|
+
rc = main([])
|
|
44
|
+
assert rc == 0
|
|
45
|
+
out = capsys.readouterr().out
|
|
46
|
+
assert "convertible session" in out
|
|
47
|
+
|
|
48
|
+
|
|
27
49
|
def test_unknown_command_errors(capsys: pytest.CaptureFixture[str]) -> None:
|
|
28
50
|
with pytest.raises(SystemExit) as exc:
|
|
29
51
|
main(["bogus"])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/cicd/scripts/_resolve-nick.sh
RENAMED
|
File without changes
|
{convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/cicd/scripts/portability-lint.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/scripts/fetch-issues.sh
RENAMED
|
File without changes
|
{convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/scripts/mesh-message.sh
RENAMED
|
File without changes
|
{convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/scripts/post-comment.sh
RENAMED
|
File without changes
|
{convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/communicate/scripts/post-issue.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/doc-test-alignment/scripts/check.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{convertible_cli-0.4.0 → convertible_cli-0.5.0}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|