agentpool-cli 0.1.9__tar.gz → 0.1.10__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 (122) hide show
  1. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/CHANGELOG.md +9 -0
  2. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/PKG-INFO +11 -1
  3. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/README.md +10 -0
  4. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/examples.md +7 -0
  5. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/quickstart.md +9 -0
  6. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/pyproject.toml +2 -1
  7. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/server.json +2 -2
  8. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/__init__.py +1 -1
  9. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/cli.py +188 -0
  10. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_cli.py +53 -0
  11. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/uv.lock +1 -1
  12. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/.cursor/mcp.json.example +0 -0
  13. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/.github/CODEOWNERS +0 -0
  14. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  15. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/.github/ISSUE_TEMPLATE/provider_probe.md +0 -0
  16. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/.github/dependabot.yml +0 -0
  17. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/.github/workflows/ci.yml +0 -0
  18. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/.github/workflows/release.yml +0 -0
  19. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/.gitignore +0 -0
  20. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/.mcp.json.example +0 -0
  21. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/AGENTS.md +0 -0
  22. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/CONTRIBUTING.md +0 -0
  23. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/LICENSE +0 -0
  24. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/SECURITY.md +0 -0
  25. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/agent-cli-and-mcp.md +0 -0
  26. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/agentpool-skill.md +0 -0
  27. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/architecture.md +0 -0
  28. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/examples/README.md +0 -0
  29. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/install.md +0 -0
  30. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/mcp-clients.md +0 -0
  31. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/mcp-tools.md +0 -0
  32. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/model-catalog.md +0 -0
  33. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/onboarding.md +0 -0
  34. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/provider-adapters.md +0 -0
  35. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/provider-lifecycle-matrix.md +0 -0
  36. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/release.md +0 -0
  37. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/security.md +0 -0
  38. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/setup-claude-code.md +0 -0
  39. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/setup-codex.md +0 -0
  40. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/setup-copilot.md +0 -0
  41. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/setup-cursor-cli.md +0 -0
  42. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/setup-cursor.md +0 -0
  43. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/setup-devin.md +0 -0
  44. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/setup-droid.md +0 -0
  45. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/stats.md +0 -0
  46. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/usage-detection.md +0 -0
  47. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/docs/usage-probe-matrix.md +0 -0
  48. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/scripts/install.sh +0 -0
  49. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/__main__.py +0 -0
  50. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/agent_io.py +0 -0
  51. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/artifacts.py +0 -0
  52. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/config.py +0 -0
  53. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/event_detection.py +0 -0
  54. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/fixtures/__init__.py +0 -0
  55. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/fixtures/fake_agents/__init__.py +0 -0
  56. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/fixtures/fake_agents/fake_approval_agent.py +0 -0
  57. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/fixtures/fake_agents/fake_common.py +0 -0
  58. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/fixtures/fake_agents/fake_completed_agent.py +0 -0
  59. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/fixtures/fake_agents/fake_idle_agent.py +0 -0
  60. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/fixtures/fake_agents/fake_limit_agent.py +0 -0
  61. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/fixtures/fake_agents/fake_patch_agent.py +0 -0
  62. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/fixtures/fake_agents/fake_question_agent.py +0 -0
  63. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/git_worktree.py +0 -0
  64. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/mcp/__init__.py +0 -0
  65. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/mcp/resources.py +0 -0
  66. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/mcp/tools.py +0 -0
  67. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/mcp_server.py +0 -0
  68. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/models.py +0 -0
  69. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/onboarding.py +0 -0
  70. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/policy.py +0 -0
  71. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/preferences.py +0 -0
  72. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/provider_model_catalog.json +0 -0
  73. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/providers/__init__.py +0 -0
  74. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/providers/base.py +0 -0
  75. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/providers/registry.py +0 -0
  76. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/redaction.py +0 -0
  77. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/runtimes/__init__.py +0 -0
  78. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/runtimes/base.py +0 -0
  79. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/runtimes/tmux.py +0 -0
  80. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/session_manager.py +0 -0
  81. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/stats/__init__.py +0 -0
  82. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/stats/card.py +0 -0
  83. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/stats/compute.py +0 -0
  84. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/stats/queries.py +0 -0
  85. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/stats/render.py +0 -0
  86. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/stats/window.py +0 -0
  87. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/store.py +0 -0
  88. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/__init__.py +0 -0
  89. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/_common.py +0 -0
  90. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/ccusage.py +0 -0
  91. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/claude.py +0 -0
  92. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/codex.py +0 -0
  93. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/codexbar.py +0 -0
  94. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/combine.py +0 -0
  95. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/copilot.py +0 -0
  96. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/devin.py +0 -0
  97. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/parsers.py +0 -0
  98. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/probes.py +0 -0
  99. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/provider_parsers.py +0 -0
  100. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/usage/summary.py +0 -0
  101. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/src/agentpool/utils.py +0 -0
  102. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/fixtures/provider_model_catalog_golden.json +0 -0
  103. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/fixtures/stats_seed.py +0 -0
  104. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/fixtures/usage/claude_usage.txt +0 -0
  105. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/fixtures/usage/codex_rate_limits.json +0 -0
  106. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/fixtures/usage/copilot_user.json +0 -0
  107. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/fixtures/usage/devin_plan_status.json +0 -0
  108. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/integration/test_fake_tmux_flow.py +0 -0
  109. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_agent_io.py +0 -0
  110. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_event_policy.py +0 -0
  111. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_mcp_surface.py +0 -0
  112. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_mcp_tools.py +0 -0
  113. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_models_config_store.py +0 -0
  114. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_onboarding.py +0 -0
  115. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_redaction.py +0 -0
  116. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_stats_cli.py +0 -0
  117. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_stats_mcp.py +0 -0
  118. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_stats_window.py +0 -0
  119. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_subprocess_safety.py +0 -0
  120. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_usage_probes.py +0 -0
  121. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_usage_provider_parsers.py +0 -0
  122. {agentpool_cli-0.1.9 → agentpool_cli-0.1.10}/tests/unit/test_usage_summary_enrichment.py +0 -0
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.1.10 - 2026-06-03
6
+
7
+ - Add an AI-agent start section to root help pointing agents at bundled skill
8
+ guidance before they infer workflows from flags.
9
+ - Add `agentpool skills` with `list`, `get`, and `path` so agents can load
10
+ version-matched AgentPool usage guidance from the installed CLI.
11
+ - Include examples with packaged docs so `agentpool skills get core --full`
12
+ returns both the skill and copy-paste CLI flows.
13
+
5
14
  ## 0.1.9 - 2026-06-02
6
15
 
7
16
  - Harden agent-facing CLI recovery with examples on root/group help, structured
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentpool-cli
3
- Version: 0.1.9
3
+ Version: 0.1.10
4
4
  Summary: Make full use of every coding-agent subscription you pay for: a local CLI + MCP server that surfaces live usage limits and offloads work to providers with headroom.
5
5
  Author: AgentPool contributors
6
6
  License-Expression: MIT
@@ -103,6 +103,13 @@ notes.
103
103
 
104
104
  ## Quickstart
105
105
 
106
+ For AI agents, start by loading the bundled version-matched skill:
107
+
108
+ ```bash
109
+ agentpool skills get agentpool
110
+ agentpool skills get core --full
111
+ ```
112
+
106
113
  ```bash
107
114
  agentpool init
108
115
  agentpool setup cursor
@@ -312,6 +319,9 @@ summary, provider models, preferences, spawn, observe, send, interrupt,
312
319
  collect, artifact manifest, transcript paging, and terminate. Add opt-in
313
320
  toolsets with `agentpool mcp --toolsets default,stats,sessions,leases,worktrees`.
314
321
 
322
+ Shell-capable agents can use `agentpool skills get agentpool` instead of MCP
323
+ resources to load the same core usage guidance from the installed CLI.
324
+
315
325
  Coding agents with shell access should prefer the CLI path. It is more
316
326
  token-efficient because large worker output stays in artifact files and
317
327
  `observe`/`collect` return compact manifests by default. MCP remains first-class
@@ -82,6 +82,13 @@ notes.
82
82
 
83
83
  ## Quickstart
84
84
 
85
+ For AI agents, start by loading the bundled version-matched skill:
86
+
87
+ ```bash
88
+ agentpool skills get agentpool
89
+ agentpool skills get core --full
90
+ ```
91
+
85
92
  ```bash
86
93
  agentpool init
87
94
  agentpool setup cursor
@@ -291,6 +298,9 @@ summary, provider models, preferences, spawn, observe, send, interrupt,
291
298
  collect, artifact manifest, transcript paging, and terminate. Add opt-in
292
299
  toolsets with `agentpool mcp --toolsets default,stats,sessions,leases,worktrees`.
293
300
 
301
+ Shell-capable agents can use `agentpool skills get agentpool` instead of MCP
302
+ resources to load the same core usage guidance from the installed CLI.
303
+
294
304
  Coding agents with shell access should prefer the CLI path. It is more
295
305
  token-efficient because large worker output stays in artifact files and
296
306
  `observe`/`collect` return compact manifests by default. MCP remains first-class
@@ -1,5 +1,12 @@
1
1
  # Examples
2
2
 
3
+ Load agent guidance from the installed CLI:
4
+
5
+ ```bash
6
+ agentpool skills get agentpool
7
+ agentpool skills get core --full
8
+ ```
9
+
3
10
  Spawn a fake question worker:
4
11
 
5
12
  ```bash
@@ -7,6 +7,14 @@ plane, not a router: you pick the provider and model explicitly.
7
7
 
8
8
  ## 1. Verify the environment
9
9
 
10
+ AI agents should load the bundled version-matched skill before inferring flows
11
+ from flags:
12
+
13
+ ```bash
14
+ agentpool skills get agentpool
15
+ agentpool skills get core --full
16
+ ```
17
+
10
18
  ```bash
11
19
  agentpool init
12
20
  agentpool doctor --deep --privacy
@@ -58,6 +66,7 @@ Use `--isolation worktree` instead of `read_only` for tasks that edit files.
58
66
 
59
67
  ## Next
60
68
 
69
+ - CLI agent guidance: `agentpool skills get agentpool`
61
70
  - Full agent guidance: `agentpool://skill.md`
62
71
  - Setup and privacy detail: `agentpool://onboarding`
63
72
  - User delegation preferences: `agentpool://preferences.md`
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agentpool-cli"
7
- version = "0.1.9"
7
+ version = "0.1.10"
8
8
  description = "Make full use of every coding-agent subscription you pay for: a local CLI + MCP server that surfaces live usage limits and offloads work to providers with headroom."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -54,5 +54,6 @@ include = [
54
54
 
55
55
  [tool.hatch.build.targets.wheel.force-include]
56
56
  "docs/agentpool-skill.md" = "agentpool/docs/agentpool-skill.md"
57
+ "docs/examples.md" = "agentpool/docs/examples.md"
57
58
  "docs/onboarding.md" = "agentpool/docs/onboarding.md"
58
59
  "docs/quickstart.md" = "agentpool/docs/quickstart.md"
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.sidduHERE/agentpool",
4
4
  "title": "AgentPool",
5
5
  "description": "See each coding-agent subscription's live limits and offload work to one with headroom.",
6
- "version": "0.1.9",
6
+ "version": "0.1.10",
7
7
  "repository": {
8
8
  "url": "https://github.com/sidduHERE/agentpool",
9
9
  "source": "github"
@@ -13,7 +13,7 @@
13
13
  {
14
14
  "registryType": "pypi",
15
15
  "identifier": "agentpool-cli",
16
- "version": "0.1.9",
16
+ "version": "0.1.10",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  },
@@ -1,3 +1,3 @@
1
1
  """AgentPool local agent control plane."""
2
2
 
3
- __version__ = "0.1.9"
3
+ __version__ = "0.1.10"
@@ -4,6 +4,7 @@ import json
4
4
  import os
5
5
  import shutil
6
6
  import sys
7
+ from importlib import resources
7
8
  from pathlib import Path
8
9
  from typing import Annotated, Any, Callable
9
10
 
@@ -196,6 +197,14 @@ app = AgentPoolTyper(
196
197
  cls=AgentPoolGroup,
197
198
  help=(
198
199
  "Use every coding-agent subscription you pay for: see live usage limits and offload work to providers with headroom.\n\n"
200
+ "Start here (for AI agents):\n"
201
+ " agentpool skills get agentpool\n\n"
202
+ " Skills ship with the CLI, stay version-matched, and include workflow patterns, safety boundaries, "
203
+ "and copy-paste examples. Prefer this over guessing from flag docs alone.\n\n"
204
+ " skills \\[list] List available skills\n"
205
+ " skills get agentpool Core CLI + MCP delegation guide\n"
206
+ " skills get core --full Include quickstart and examples\n"
207
+ " skills path \\[name] Print bundled skill/docs path\n\n"
199
208
  "Examples:\n"
200
209
  " agentpool inventory --json\n"
201
210
  " cat task.md | agentpool spawn --provider codex-cli --repo . --task-stdin\n"
@@ -206,6 +215,19 @@ app = AgentPoolTyper(
206
215
  invoke_without_command=True,
207
216
  no_args_is_help=True,
208
217
  )
218
+ skills_app = AgentPoolTyper(
219
+ cls=AgentPoolGroup,
220
+ help=(
221
+ "List and retrieve bundled AgentPool skill content.\n\n"
222
+ "Examples:\n"
223
+ " agentpool skills\n"
224
+ " agentpool skills get agentpool\n"
225
+ " agentpool skills get core --full\n"
226
+ " agentpool skills path agentpool"
227
+ ),
228
+ invoke_without_command=True,
229
+ no_args_is_help=False,
230
+ )
209
231
  config_app = AgentPoolTyper(
210
232
  cls=AgentPoolGroup,
211
233
  help=(
@@ -242,12 +264,26 @@ worktrees_app = AgentPoolTyper(
242
264
  " agentpool worktrees cleanup --session-id <session-id> --dry-run --json"
243
265
  ),
244
266
  )
267
+ app.add_typer(skills_app, name="skills")
245
268
  app.add_typer(config_app, name="config")
246
269
  app.add_typer(leases_app, name="leases")
247
270
  app.add_typer(session_app, name="session")
248
271
  app.add_typer(worktrees_app, name="worktrees")
249
272
  console = Console()
250
273
 
274
+ SKILL_DEFINITIONS: dict[str, dict[str, Any]] = {
275
+ "agentpool": {
276
+ "aliases": ["core"],
277
+ "filename": "agentpool-skill.md",
278
+ "description": "Core AgentPool CLI + MCP delegation guide. Read this before spawning workers.",
279
+ "references": ["quickstart.md", "examples.md"],
280
+ }
281
+ }
282
+ SKILL_ALIASES = {
283
+ alias: name for name, definition in SKILL_DEFINITIONS.items() for alias in [name, *definition["aliases"]]
284
+ }
285
+ PROJECT_ROOT = Path(__file__).resolve().parents[2]
286
+
251
287
 
252
288
  @app.callback()
253
289
  def root(
@@ -265,6 +301,158 @@ def print_data(data: object, json_output: bool) -> None:
265
301
  console.print(data)
266
302
 
267
303
 
304
+ def _docs_resource(filename: str | None = None) -> Any:
305
+ docs = resources.files("agentpool").joinpath("docs")
306
+ return docs.joinpath(filename) if filename else docs
307
+
308
+
309
+ def _read_packaged_doc(filename: str) -> str:
310
+ packaged = _docs_resource(filename)
311
+ if packaged.is_file():
312
+ return packaged.read_text(encoding="utf-8")
313
+ return (PROJECT_ROOT / "docs" / filename).read_text(encoding="utf-8")
314
+
315
+
316
+ def _resource_display_path(filename: str | None = None) -> str:
317
+ packaged = _docs_resource(filename)
318
+ if packaged.is_file() or (filename is None and packaged.is_dir()):
319
+ return str(packaged)
320
+ fallback_docs = PROJECT_ROOT / "docs"
321
+ return str(fallback_docs / filename) if filename else str(fallback_docs)
322
+
323
+
324
+ def _skill_entry(name: str) -> dict[str, Any]:
325
+ definition = SKILL_DEFINITIONS[name]
326
+ return {
327
+ "name": name,
328
+ "aliases": definition["aliases"],
329
+ "description": definition["description"],
330
+ "full_available": bool(definition.get("references")),
331
+ }
332
+
333
+
334
+ def _resolve_skill_name(name: str) -> str:
335
+ normalized = name.strip().lower()
336
+ if normalized in SKILL_ALIASES:
337
+ return SKILL_ALIASES[normalized]
338
+ raise ToolError(
339
+ "INVALID_REQUEST",
340
+ f"Unknown skill {name!r}.",
341
+ {"example": "agentpool skills list"},
342
+ )
343
+
344
+
345
+ def _skill_text(name: str, *, full: bool = False) -> str:
346
+ definition = SKILL_DEFINITIONS[name]
347
+ chunks = [_read_packaged_doc(definition["filename"])]
348
+ if full:
349
+ for filename in definition.get("references") or []:
350
+ title = filename.removesuffix(".md").replace("-", " ").title()
351
+ chunks.append(f"\n\n# Reference: {title}\n\n{_read_packaged_doc(filename)}")
352
+ return "".join(chunks)
353
+
354
+
355
+ def _print_skills_list(json_output: bool) -> None:
356
+ data = {"skills": [_skill_entry(name) for name in sorted(SKILL_DEFINITIONS)]}
357
+ if json_output:
358
+ console.print_json(json.dumps(data, default=str))
359
+ return
360
+ for skill in data["skills"]:
361
+ aliases = f" (aliases: {', '.join(skill['aliases'])})" if skill["aliases"] else ""
362
+ console.print(f" {skill['name']:<12} {skill['description']}{aliases}")
363
+
364
+
365
+ @skills_app.callback(invoke_without_command=True)
366
+ def skills_root(
367
+ ctx: typer.Context,
368
+ json_output: Annotated[bool, typer.Option("--json", help="Emit JSON.")] = False,
369
+ ) -> None:
370
+ """List bundled skills when no subcommand is provided."""
371
+ if ctx.invoked_subcommand is None:
372
+ _print_skills_list(json_output)
373
+ raise typer.Exit()
374
+
375
+
376
+ @skills_app.command("list")
377
+ def skills_list(json_output: Annotated[bool, typer.Option("--json", help="Emit JSON.")] = False) -> None:
378
+ """List bundled skills.
379
+
380
+ Examples:
381
+ agentpool skills list
382
+ agentpool skills list --json
383
+ """
384
+ _print_skills_list(json_output)
385
+
386
+
387
+ @skills_app.command("get")
388
+ def skills_get(
389
+ name: Annotated[str | None, typer.Argument(help="Skill name, for example: agentpool or core.")] = None,
390
+ full: Annotated[bool, typer.Option("--full", help="Include quickstart and examples with the core skill.")] = False,
391
+ all_skills: Annotated[bool, typer.Option("--all", help="Output every bundled skill.")] = False,
392
+ json_output: Annotated[bool, typer.Option("--json", help="Emit JSON.")] = False,
393
+ ) -> None:
394
+ """Output bundled skill content.
395
+
396
+ Examples:
397
+ agentpool skills get agentpool
398
+ agentpool skills get core --full
399
+ agentpool skills get --all --json
400
+ """
401
+ try:
402
+ if all_skills:
403
+ names = sorted(SKILL_DEFINITIONS)
404
+ elif name:
405
+ names = [_resolve_skill_name(name)]
406
+ else:
407
+ raise ToolError(
408
+ "INVALID_REQUEST",
409
+ "Provide a skill name or --all.",
410
+ {"example": "agentpool skills get agentpool"},
411
+ )
412
+ skills = [
413
+ {
414
+ **_skill_entry(skill_name),
415
+ "full": full,
416
+ "path": _resource_display_path(SKILL_DEFINITIONS[skill_name]["filename"]),
417
+ "text": _skill_text(skill_name, full=full),
418
+ }
419
+ for skill_name in names
420
+ ]
421
+ if json_output:
422
+ console.print_json(json.dumps({"skills": skills}, default=str))
423
+ return
424
+ console.print("\n\n".join(skill["text"] for skill in skills), markup=False)
425
+ except ToolError as exc:
426
+ handle_tool_error(exc, json_output)
427
+
428
+
429
+ @skills_app.command("path")
430
+ def skills_path(
431
+ name: Annotated[str | None, typer.Argument(help="Optional skill name, for example: agentpool or core.")] = None,
432
+ json_output: Annotated[bool, typer.Option("--json", help="Emit JSON.")] = False,
433
+ ) -> None:
434
+ """Print bundled skill/docs path.
435
+
436
+ Examples:
437
+ agentpool skills path
438
+ agentpool skills path agentpool
439
+ agentpool skills path core --json
440
+ """
441
+ try:
442
+ if name:
443
+ skill_name = _resolve_skill_name(name)
444
+ path = _resource_display_path(SKILL_DEFINITIONS[skill_name]["filename"])
445
+ data = {"name": skill_name, "path": path}
446
+ else:
447
+ data = {"path": _resource_display_path()}
448
+ if json_output:
449
+ console.print_json(json.dumps(data, default=str))
450
+ return
451
+ console.print(data["path"], markup=False)
452
+ except ToolError as exc:
453
+ handle_tool_error(exc, json_output)
454
+
455
+
268
456
  def _env_flag(name: str) -> bool:
269
457
  return os.environ.get(name, "").strip().lower() in {"1", "true", "yes", "on"}
270
458
 
@@ -264,6 +264,7 @@ def test_root_and_group_help_have_examples() -> None:
264
264
  runner = CliRunner()
265
265
  for args in (
266
266
  ["--help"],
267
+ ["skills", "--help"],
267
268
  ["config", "--help"],
268
269
  ["leases", "--help"],
269
270
  ["session", "--help"],
@@ -274,6 +275,54 @@ def test_root_and_group_help_have_examples() -> None:
274
275
  assert "Examples:" in result.output
275
276
 
276
277
 
278
+ def test_root_help_points_agents_to_bundled_skills() -> None:
279
+ result = CliRunner().invoke(app, ["--help"])
280
+
281
+ assert result.exit_code == 0
282
+ assert "Start here (for AI agents):" in result.output
283
+ assert "agentpool skills get agentpool" in result.output
284
+ assert "skills [list]" in result.output
285
+ assert "skills path [name]" in result.output
286
+ assert "Skills ship with the CLI" in result.output
287
+
288
+
289
+ def test_skills_list_get_path_and_json() -> None:
290
+ runner = CliRunner()
291
+
292
+ listed = runner.invoke(app, ["skills"])
293
+ listed_json = runner.invoke(app, ["skills", "list", "--json"])
294
+ skill = runner.invoke(app, ["skills", "get", "agentpool"])
295
+ full = runner.invoke(app, ["skills", "get", "core", "--full"])
296
+ path = runner.invoke(app, ["skills", "path", "core"])
297
+ skill_json = runner.invoke(app, ["skills", "get", "agentpool", "--json"])
298
+
299
+ assert listed.exit_code == 0
300
+ assert "agentpool" in listed.output
301
+ assert "aliases: core" in listed.output
302
+ assert listed_json.exit_code == 0
303
+ assert json.loads(listed_json.output)["skills"][0]["name"] == "agentpool"
304
+ assert skill.exit_code == 0
305
+ assert "# AgentPool Skill" in skill.output
306
+ assert "Typical CLI Flow" in skill.output
307
+ assert full.exit_code == 0
308
+ assert "# Reference: Quickstart" in full.output
309
+ assert "# Examples" in full.output
310
+ assert path.exit_code == 0
311
+ assert "agentpool-skill.md" in path.output
312
+ assert skill_json.exit_code == 0
313
+ payload = json.loads(skill_json.output)
314
+ assert payload["skills"][0]["name"] == "agentpool"
315
+ assert "# AgentPool Skill" in payload["skills"][0]["text"]
316
+
317
+
318
+ def test_skills_get_unknown_returns_recovery_hint() -> None:
319
+ result = CliRunner().invoke(app, ["skills", "get", "missing"])
320
+
321
+ assert result.exit_code == 1
322
+ assert "INVALID_REQUEST" in result.output
323
+ assert "try: agentpool skills list" in result.output
324
+
325
+
277
326
  def test_missing_parameter_errors_include_copy_pasteable_examples() -> None:
278
327
  runner = CliRunner()
279
328
 
@@ -555,6 +604,7 @@ def test_core_help_has_examples() -> None:
555
604
  "preferences",
556
605
  "smoke",
557
606
  "providers",
607
+ "skills",
558
608
  "models",
559
609
  "stats",
560
610
  "sessions",
@@ -580,6 +630,9 @@ def test_nested_help_has_examples() -> None:
580
630
  runner = CliRunner()
581
631
  for command in (
582
632
  ("session", "show"),
633
+ ("skills", "list"),
634
+ ("skills", "get"),
635
+ ("skills", "path"),
583
636
  ("config", "path"),
584
637
  ("config", "print"),
585
638
  ("config", "validate"),
@@ -3,7 +3,7 @@ requires-python = ">=3.11"
3
3
 
4
4
  [[package]]
5
5
  name = "agentpool-cli"
6
- version = "0.1.9"
6
+ version = "0.1.10"
7
7
  source = { editable = "." }
8
8
  dependencies = [
9
9
  { name = "certifi" },
File without changes
File without changes
File without changes