humancli 0.2.0__tar.gz → 0.4.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.
Files changed (26) hide show
  1. {humancli-0.2.0 → humancli-0.4.0}/.agents/skills/release/SKILL.md +3 -3
  2. {humancli-0.2.0 → humancli-0.4.0}/.github/workflows/release.yml +2 -2
  3. {humancli-0.2.0 → humancli-0.4.0}/PKG-INFO +8 -8
  4. {humancli-0.2.0 → humancli-0.4.0}/README.md +7 -7
  5. {humancli-0.2.0 → humancli-0.4.0}/pyproject.toml +2 -2
  6. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/__init__.py +2 -2
  7. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/_errors.py +2 -2
  8. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/_output.py +23 -14
  9. humancli-0.2.0/tests/test_agentcli.py → humancli-0.4.0/tests/test_humancli.py +2 -2
  10. {humancli-0.2.0 → humancli-0.4.0}/uv.lock +1 -1
  11. {humancli-0.2.0 → humancli-0.4.0}/.agents/AGENTS.md +0 -0
  12. {humancli-0.2.0 → humancli-0.4.0}/.github/workflows/ci.yml +0 -0
  13. {humancli-0.2.0 → humancli-0.4.0}/.gitignore +0 -0
  14. {humancli-0.2.0 → humancli-0.4.0}/.python-version +0 -0
  15. {humancli-0.2.0 → humancli-0.4.0}/LICENSE +0 -0
  16. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/_agents.py +0 -0
  17. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/_app.py +0 -0
  18. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/_context.py +0 -0
  19. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/_help.py +0 -0
  20. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/_parser.py +0 -0
  21. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/_schema.py +0 -0
  22. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/_types.py +0 -0
  23. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/_wizard.py +0 -0
  24. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/prompt.py +0 -0
  25. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/py.typed +0 -0
  26. {humancli-0.2.0/src/agentcli → humancli-0.4.0/src/humancli}/testing.py +0 -0
@@ -7,7 +7,7 @@ description: Prepare and ship an agentcli release. Use when asked to cut a relea
7
7
 
8
8
  ## Overview
9
9
 
10
- Prepare a tagged release that matches the GitHub Actions release workflow. The workflow requires the tag version to match both `pyproject.toml` and `src/agentcli/__init__.py`.
10
+ Prepare a tagged release that matches the GitHub Actions release workflow. The workflow requires the tag version to match both `pyproject.toml` and `src/humancli/__init__.py`.
11
11
 
12
12
  ## Workflow
13
13
 
@@ -21,7 +21,7 @@ If the current version has a `.dev` suffix, assume the target release version is
21
21
  Update version strings to match the release tag:
22
22
 
23
23
  - `pyproject.toml`: `project.version = "<major.minor.patch>"`
24
- - `src/agentcli/__init__.py`: `__version__ = "<major.minor.patch>"`
24
+ - `src/humancli/__init__.py`: `__version__ = "<major.minor.patch>"`
25
25
  - `uv.lock`: refresh so the root package version matches (run `uv lock` or `uv sync`).
26
26
 
27
27
  ### 3) Run checks
@@ -45,4 +45,4 @@ If you keep a dev version between releases, bump the minor version (reset patch
45
45
 
46
46
  ## Notes
47
47
 
48
- - The release workflow checks that the tag matches `pyproject.toml` and `src/agentcli/__init__.py`.
48
+ - The release workflow checks that the tag matches `pyproject.toml` and `src/humancli/__init__.py`.
@@ -36,7 +36,7 @@ jobs:
36
36
  project_version = pyproject['project']['version']
37
37
 
38
38
  init_version = None
39
- init_path = Path('src') / 'agentcli' / '__init__.py'
39
+ init_path = Path('src') / 'humancli' / '__init__.py'
40
40
  if init_path.is_file():
41
41
  m = re.search(r'__version__\s*=\s*"([^"]+)"', init_path.read_text(encoding='utf-8'))
42
42
  if m:
@@ -46,7 +46,7 @@ jobs:
46
46
  raise SystemExit(f"Tag {tag!r} does not match pyproject version {project_version!r}")
47
47
  if init_version and init_version != project_version:
48
48
  raise SystemExit(
49
- f"src/agentcli/__init__.py __version__ {init_version!r} does not match pyproject version {project_version!r}"
49
+ f"src/humancli/__init__.py __version__ {init_version!r} does not match pyproject version {project_version!r}"
50
50
  )
51
51
 
52
52
  print(f"OK: tag {tag!r} matches version {project_version!r}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: humancli
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: Python CLIs for agents and humans
5
5
  Project-URL: Repository, https://github.com/elyase/agentcli
6
6
  Project-URL: Issues, https://github.com/elyase/agentcli/issues
@@ -47,10 +47,10 @@ agentcli builds command-line interfaces that produce structured, parseable outpu
47
47
  pip install humancli
48
48
  ```
49
49
 
50
- The package installs as `humancli` on PyPI but you import it as `agentcli`:
50
+ The package installs as `humancli` on PyPI and you import it as `humancli`:
51
51
 
52
52
  ```python
53
- from agentcli import App
53
+ from humancli import App
54
54
  ```
55
55
 
56
56
  ## Quick start
@@ -58,7 +58,7 @@ from agentcli import App
58
58
  ### Single function
59
59
 
60
60
  ```python
61
- from agentcli import run
61
+ from humancli import run
62
62
 
63
63
  def greet(name: str):
64
64
  """Greet someone."""
@@ -84,7 +84,7 @@ $ greet --llms
84
84
  ### Multi-command app
85
85
 
86
86
  ```python
87
- from agentcli import App
87
+ from humancli import App
88
88
 
89
89
  app = App("my-cli", version="1.0.0")
90
90
 
@@ -107,7 +107,7 @@ Parameters before `*` are positional arguments. Parameters after `*` are named o
107
107
 
108
108
  ```python
109
109
  from typing import Annotated, Literal
110
- from agentcli import App, Param
110
+ from humancli import App, Param
111
111
 
112
112
  app = App("deploy-cli")
113
113
 
@@ -156,12 +156,12 @@ def fetch_cases(*, limit: int = 20):
156
156
 
157
157
  ## Agent discovery
158
158
 
159
- Every agentcli app gets built-in flags for agent consumption:
159
+ Every humancli app gets built-in flags for agent consumption:
160
160
 
161
161
  - `--llms` — markdown command index
162
162
  - `--llms-full` — full JSON schema of all commands
163
163
  - `--json` / `--yaml` / `--jsonl` — structured output formats
164
- - `--mcp` — start as an MCP server (requires `agentcli[mcp]`)
164
+ - `--mcp` — start as an MCP server (requires `humancli[mcp]`)
165
165
 
166
166
  ## Optional extras
167
167
 
@@ -10,10 +10,10 @@ agentcli builds command-line interfaces that produce structured, parseable outpu
10
10
  pip install humancli
11
11
  ```
12
12
 
13
- The package installs as `humancli` on PyPI but you import it as `agentcli`:
13
+ The package installs as `humancli` on PyPI and you import it as `humancli`:
14
14
 
15
15
  ```python
16
- from agentcli import App
16
+ from humancli import App
17
17
  ```
18
18
 
19
19
  ## Quick start
@@ -21,7 +21,7 @@ from agentcli import App
21
21
  ### Single function
22
22
 
23
23
  ```python
24
- from agentcli import run
24
+ from humancli import run
25
25
 
26
26
  def greet(name: str):
27
27
  """Greet someone."""
@@ -47,7 +47,7 @@ $ greet --llms
47
47
  ### Multi-command app
48
48
 
49
49
  ```python
50
- from agentcli import App
50
+ from humancli import App
51
51
 
52
52
  app = App("my-cli", version="1.0.0")
53
53
 
@@ -70,7 +70,7 @@ Parameters before `*` are positional arguments. Parameters after `*` are named o
70
70
 
71
71
  ```python
72
72
  from typing import Annotated, Literal
73
- from agentcli import App, Param
73
+ from humancli import App, Param
74
74
 
75
75
  app = App("deploy-cli")
76
76
 
@@ -119,12 +119,12 @@ def fetch_cases(*, limit: int = 20):
119
119
 
120
120
  ## Agent discovery
121
121
 
122
- Every agentcli app gets built-in flags for agent consumption:
122
+ Every humancli app gets built-in flags for agent consumption:
123
123
 
124
124
  - `--llms` — markdown command index
125
125
  - `--llms-full` — full JSON schema of all commands
126
126
  - `--json` / `--yaml` / `--jsonl` — structured output formats
127
- - `--mcp` — start as an MCP server (requires `agentcli[mcp]`)
127
+ - `--mcp` — start as an MCP server (requires `humancli[mcp]`)
128
128
 
129
129
  ## Optional extras
130
130
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "humancli"
3
- version = "0.2.0"
3
+ version = "0.4.0"
4
4
  description = "Python CLIs for agents and humans"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -44,7 +44,7 @@ requires = ["hatchling"]
44
44
  build-backend = "hatchling.build"
45
45
 
46
46
  [tool.hatch.build.targets.wheel]
47
- packages = ["src/agentcli"]
47
+ packages = ["src/humancli"]
48
48
 
49
49
  [tool.pytest.ini_options]
50
50
  testpaths = ["tests"]
@@ -1,11 +1,11 @@
1
- """agentcli: Python CLIs for agents and humans."""
1
+ """humancli: Python CLIs for agents and humans."""
2
2
 
3
3
  from ._app import App, run
4
4
  from ._context import Context
5
5
  from ._errors import AgentCliError, ConfigError, ParseError, ValidationError
6
6
  from ._types import Param, Result
7
7
 
8
- __version__ = "0.2.0"
8
+ __version__ = "0.4.0"
9
9
 
10
10
  __all__ = [
11
11
  "AgentCliError",
@@ -31,13 +31,13 @@ class AgentCliError(Exception):
31
31
  self.exit_code = exit_code
32
32
 
33
33
  def to_error_info(self) -> ErrorInfo:
34
- from ._output import ErrorInfo
34
+ from ._output import ErrorInfo, _make_cta
35
35
 
36
36
  return ErrorInfo(
37
37
  code=self.code,
38
38
  message=self.message,
39
39
  retryable=self.retryable,
40
- suggested_commands=self.cta,
40
+ cta=_make_cta(self.cta, description="To fix this:"),
41
41
  )
42
42
 
43
43
 
@@ -2,24 +2,30 @@ from __future__ import annotations
2
2
 
3
3
  import dataclasses
4
4
  import json
5
- from dataclasses import dataclass
5
+ from dataclasses import dataclass, field
6
6
  from typing import Any
7
7
 
8
8
  from ._errors import AgentCliError
9
9
 
10
10
 
11
+ @dataclass(frozen=True)
12
+ class CtaBlock:
13
+ description: str = "Suggested commands:"
14
+ commands: list[str] = field(default_factory=list)
15
+
16
+
11
17
  @dataclass(frozen=True)
12
18
  class ErrorInfo:
13
19
  code: str
14
20
  message: str
15
21
  retryable: bool = False
16
- suggested_commands: list[str] | None = None
22
+ cta: CtaBlock | None = None
17
23
 
18
24
 
19
25
  @dataclass
20
26
  class Meta:
21
27
  command: str
22
- suggested_commands: list[str] | None = None
28
+ cta: CtaBlock | None = None
23
29
  duration_ms: float | None = None
24
30
  streamed: bool = False
25
31
 
@@ -32,32 +38,35 @@ class Envelope:
32
38
  meta: Meta | None = None
33
39
 
34
40
 
41
+ def _make_cta(
42
+ commands: list[str] | None, description: str = "Suggested commands:"
43
+ ) -> CtaBlock | None:
44
+ if not commands:
45
+ return None
46
+ return CtaBlock(description=description, commands=commands)
47
+
48
+
35
49
  def make_success_envelope(
36
50
  data: Any,
37
51
  *,
38
52
  command: str,
39
53
  cta: list[str] | None = None,
40
54
  ) -> Envelope:
41
- return Envelope(
42
- ok=True, data=data, meta=Meta(command=command, suggested_commands=cta)
43
- )
55
+ return Envelope(ok=True, data=data, meta=Meta(command=command, cta=_make_cta(cta)))
44
56
 
45
57
 
46
58
  def make_error_envelope(error: Exception, *, command: str) -> Envelope:
47
59
  if isinstance(error, AgentCliError):
60
+ cta_block = _make_cta(error.cta, description="To fix this:")
48
61
  info = ErrorInfo(
49
62
  code=error.code,
50
63
  message=error.message,
51
64
  retryable=error.retryable,
52
- suggested_commands=error.cta,
65
+ cta=cta_block,
53
66
  )
54
67
  else:
55
68
  info = ErrorInfo(code="UNKNOWN", message=str(error), retryable=False)
56
- return Envelope(
57
- ok=False,
58
- error=info,
59
- meta=Meta(command=command, suggested_commands=info.suggested_commands),
60
- )
69
+ return Envelope(ok=False, error=info, meta=Meta(command=command, cta=info.cta))
61
70
 
62
71
 
63
72
  def make_envelope(
@@ -77,7 +86,7 @@ def make_envelope(
77
86
  data=data,
78
87
  meta=Meta(
79
88
  command=command,
80
- suggested_commands=cta,
89
+ cta=_make_cta(cta),
81
90
  duration_ms=duration_ms,
82
91
  streamed=streamed,
83
92
  ),
@@ -87,7 +96,7 @@ def make_envelope(
87
96
  error=error,
88
97
  meta=Meta(
89
98
  command=command,
90
- suggested_commands=cta,
99
+ cta=_make_cta(cta),
91
100
  duration_ms=duration_ms,
92
101
  streamed=streamed,
93
102
  ),
@@ -3,8 +3,8 @@ from __future__ import annotations
3
3
  import unittest
4
4
  from typing import Annotated, Literal
5
5
 
6
- from agentcli import App, Context, Param, Result
7
- from agentcli.testing import CliRunner
6
+ from humancli import App, Context, Param, Result
7
+ from humancli.testing import CliRunner
8
8
 
9
9
 
10
10
  class AgentCliTests(unittest.TestCase):
@@ -249,7 +249,7 @@ wheels = [
249
249
 
250
250
  [[package]]
251
251
  name = "humancli"
252
- version = "0.2.0"
252
+ version = "0.4.0"
253
253
  source = { editable = "." }
254
254
  dependencies = [
255
255
  { name = "docstring-parser" },
File without changes
File without changes
File without changes
File without changes