agentpool-cli 0.1.12__tar.gz → 0.1.13__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 (126) hide show
  1. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/.github/workflows/release.yml +9 -3
  2. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/CHANGELOG.md +14 -0
  3. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/PKG-INFO +6 -6
  4. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/README.md +5 -5
  5. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/agent-cli-and-mcp.md +1 -1
  6. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/agentpool-skill.md +19 -9
  7. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/examples.md +1 -1
  8. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/mcp-clients.md +3 -2
  9. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/mcp-tools.md +26 -7
  10. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/quickstart.md +1 -1
  11. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/release.md +37 -25
  12. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/setup-codex.md +1 -1
  13. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/pyproject.toml +1 -1
  14. agentpool_cli-0.1.13/scripts/check_release_metadata.py +108 -0
  15. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/server.json +2 -2
  16. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/__init__.py +1 -1
  17. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/agent_io.py +3 -1
  18. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/artifacts.py +52 -5
  19. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/cli.py +5 -1
  20. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/mcp/tools.py +60 -3
  21. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/mcp_server.py +38 -8
  22. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/runtimes/base.py +1 -1
  23. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/runtimes/terminal_control.py +17 -3
  24. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/runtimes/tmux.py +8 -1
  25. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/session_manager.py +213 -8
  26. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_cli.py +1 -1
  27. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_mcp_surface.py +64 -5
  28. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_mcp_tools.py +106 -2
  29. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_models_config_store.py +177 -2
  30. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/uv.lock +1 -1
  31. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/.cursor/mcp.json.example +0 -0
  32. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/.github/CODEOWNERS +0 -0
  33. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  34. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/.github/ISSUE_TEMPLATE/provider_probe.md +0 -0
  35. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/.github/dependabot.yml +0 -0
  36. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/.github/workflows/ci.yml +0 -0
  37. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/.gitignore +0 -0
  38. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/.mcp.json.example +0 -0
  39. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/AGENTS.md +0 -0
  40. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/CONTRIBUTING.md +0 -0
  41. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/LICENSE +0 -0
  42. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/SECURITY.md +0 -0
  43. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/architecture.md +0 -0
  44. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/examples/README.md +0 -0
  45. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/install.md +0 -0
  46. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/model-catalog.md +0 -0
  47. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/onboarding.md +0 -0
  48. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/provider-adapters.md +0 -0
  49. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/provider-lifecycle-matrix.md +0 -0
  50. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/security.md +0 -0
  51. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/setup-claude-code.md +0 -0
  52. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/setup-copilot.md +0 -0
  53. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/setup-cursor-cli.md +0 -0
  54. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/setup-cursor.md +0 -0
  55. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/setup-devin.md +0 -0
  56. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/setup-droid.md +0 -0
  57. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/stats.md +0 -0
  58. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/usage-detection.md +0 -0
  59. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/docs/usage-probe-matrix.md +0 -0
  60. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/scripts/install.sh +0 -0
  61. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/__main__.py +0 -0
  62. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/config.py +0 -0
  63. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/event_detection.py +0 -0
  64. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/fixtures/__init__.py +0 -0
  65. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/fixtures/fake_agents/__init__.py +0 -0
  66. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/fixtures/fake_agents/fake_approval_agent.py +0 -0
  67. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/fixtures/fake_agents/fake_common.py +0 -0
  68. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/fixtures/fake_agents/fake_completed_agent.py +0 -0
  69. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/fixtures/fake_agents/fake_idle_agent.py +0 -0
  70. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/fixtures/fake_agents/fake_limit_agent.py +0 -0
  71. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/fixtures/fake_agents/fake_patch_agent.py +0 -0
  72. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/fixtures/fake_agents/fake_question_agent.py +0 -0
  73. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/git_worktree.py +0 -0
  74. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/mcp/__init__.py +0 -0
  75. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/mcp/resources.py +0 -0
  76. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/models.py +0 -0
  77. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/onboarding.py +0 -0
  78. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/policy.py +0 -0
  79. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/preferences.py +0 -0
  80. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/provider_model_catalog.json +0 -0
  81. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/providers/__init__.py +0 -0
  82. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/providers/base.py +0 -0
  83. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/providers/registry.py +0 -0
  84. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/redaction.py +0 -0
  85. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/runtimes/__init__.py +0 -0
  86. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/stats/__init__.py +0 -0
  87. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/stats/card.py +0 -0
  88. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/stats/compute.py +0 -0
  89. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/stats/queries.py +0 -0
  90. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/stats/render.py +0 -0
  91. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/stats/window.py +0 -0
  92. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/store.py +0 -0
  93. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/__init__.py +0 -0
  94. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/_common.py +0 -0
  95. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/ccusage.py +0 -0
  96. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/claude.py +0 -0
  97. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/codex.py +0 -0
  98. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/codexbar.py +0 -0
  99. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/combine.py +0 -0
  100. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/copilot.py +0 -0
  101. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/devin.py +0 -0
  102. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/parsers.py +0 -0
  103. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/probes.py +0 -0
  104. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/provider_parsers.py +0 -0
  105. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/usage/summary.py +0 -0
  106. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/src/agentpool/utils.py +0 -0
  107. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/fixtures/provider_model_catalog_golden.json +0 -0
  108. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/fixtures/stats_seed.py +0 -0
  109. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/fixtures/usage/claude_usage.txt +0 -0
  110. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/fixtures/usage/codex_rate_limits.json +0 -0
  111. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/fixtures/usage/copilot_user.json +0 -0
  112. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/fixtures/usage/devin_plan_status.json +0 -0
  113. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/integration/test_fake_terminal_control_flow.py +0 -0
  114. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/integration/test_fake_tmux_flow.py +0 -0
  115. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_agent_io.py +0 -0
  116. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_event_policy.py +0 -0
  117. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_onboarding.py +0 -0
  118. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_redaction.py +0 -0
  119. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_stats_cli.py +0 -0
  120. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_stats_mcp.py +0 -0
  121. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_stats_window.py +0 -0
  122. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_subprocess_safety.py +0 -0
  123. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_terminal_control_runtime.py +0 -0
  124. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_usage_probes.py +0 -0
  125. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_usage_provider_parsers.py +0 -0
  126. {agentpool_cli-0.1.12 → agentpool_cli-0.1.13}/tests/unit/test_usage_summary_enrichment.py +0 -0
@@ -6,12 +6,13 @@ on:
6
6
  - "v*"
7
7
  workflow_dispatch:
8
8
 
9
- permissions:
10
- contents: write
9
+ permissions: {}
11
10
 
12
11
  jobs:
13
12
  release:
14
13
  runs-on: ubuntu-latest
14
+ permissions:
15
+ contents: write
15
16
 
16
17
  steps:
17
18
  - name: Check out
@@ -33,6 +34,7 @@ jobs:
33
34
  - name: Run release checks
34
35
  run: |
35
36
  python -m pytest -q
37
+ python scripts/check_release_metadata.py
36
38
  agentpool models validate --path src/agentpool/provider_model_catalog.json --json
37
39
  agentpool config validate --json
38
40
  agentpool smoke --provider fake-question --repo . --json
@@ -82,7 +84,9 @@ jobs:
82
84
  needs: release
83
85
  runs-on: ubuntu-latest
84
86
  # Gated on the PUBLISH_TO_PYPI repo variable so tagging never publishes by accident.
85
- # Requires a configured PyPI Trusted Publisher and a `pypi` environment.
87
+ # PyPI Trusted Publisher must be:
88
+ # project=agentpool-cli, owner=sidduHERE, repo=agentpool, workflow=release.yml, environment=pypi.
89
+ # Requires the GitHub `pypi` environment and no PyPI token secret.
86
90
  if: startsWith(github.ref, 'refs/tags/') && vars.PUBLISH_TO_PYPI == 'true'
87
91
  environment:
88
92
  name: pypi
@@ -99,3 +103,5 @@ jobs:
99
103
 
100
104
  - name: Publish to PyPI (Trusted Publishing)
101
105
  uses: pypa/gh-action-pypi-publish@release/v1
106
+ with:
107
+ print-hash: true
@@ -2,6 +2,20 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.1.13 - 2026-06-24
6
+
7
+ - Add `poll_worker` as a fast MCP progress snapshot and make
8
+ `observe_worker(timeout_seconds=0/1)` behave as a true fast poll.
9
+ - Bound MCP observe waits below common host executor timeouts and return timeout
10
+ metadata instead of leaving coordinators with dropped tool calls.
11
+ - Honor `include_recent_log` for MCP observation, refresh
12
+ `summary.partial.md` while workers are running, and avoid full transcript
13
+ scans on observe/poll artifact manifests.
14
+ - Accept terminal state names such as `COMPLETED`, `FAILED`, and `CANCELLED` in
15
+ `wait_for` and pass observe deadlines into runtime capture calls.
16
+ - Mark `terminate_worker` as explicit, side-effecting, idempotent cleanup in
17
+ MCP annotations without treating it as user-data destruction.
18
+
5
19
  ## 0.1.12 - 2026-06-06
6
20
 
7
21
  - Add optional Terminal Control runtime support while keeping tmux as the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentpool-cli
3
- Version: 0.1.12
3
+ Version: 0.1.13
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
@@ -148,7 +148,7 @@ agentpool spawn \
148
148
  --task "Inspect the project and ask one clarifying question." \
149
149
  --isolation read_only
150
150
 
151
- agentpool observe <session-id> --wait-for completed,error,question,approval_prompt --timeout 120 --json
151
+ agentpool observe <session-id> --wait-for completed,error,question,approval_prompt --timeout 60 --json
152
152
  agentpool send <session-id> "Continue with the smallest useful check."
153
153
  agentpool artifacts <session-id> --json
154
154
  agentpool transcript <session-id> --tail-lines 80 --json
@@ -308,9 +308,9 @@ Use `--absolute-command` if the MCP host does not inherit your shell `PATH`.
308
308
  Verified per-host steps live in [docs/mcp-clients.md](docs/mcp-clients.md).
309
309
  Team templates: [.cursor/mcp.json.example](.cursor/mcp.json.example),
310
310
  [.mcp.json.example](.mcp.json.example), and [docs/examples/README.md](docs/examples/README.md).
311
- MCP Registry draft metadata: [server.json](server.json). It intentionally omits
312
- package entries until `agentpool-cli` exists on PyPI. Release checklist:
313
- [docs/release.md](docs/release.md).
311
+ MCP Registry metadata: [server.json](server.json). It advertises the
312
+ `agentpool-cli` PyPI package and should be bumped with each release. Release
313
+ checklist: [docs/release.md](docs/release.md).
314
314
  Provider setup guides:
315
315
  [Cursor](docs/setup-cursor.md),
316
316
  [Cursor Agent CLI](docs/setup-cursor-cli.md),
@@ -330,7 +330,7 @@ Then use tools for live operations. The user-owned preferences file also shows
330
330
  up through `agentpool preferences` and `get_delegation_preferences()`. It may
331
331
  say to use your native subagent system instead of AgentPool for some tasks. The
332
332
  default MCP toolset is deliberately small: inventory, usage snapshot, usage
333
- summary, provider models, preferences, spawn, observe, send, interrupt,
333
+ summary, provider models, preferences, spawn, observe, poll, send, interrupt,
334
334
  collect, artifact manifest, transcript paging, and terminate. Add opt-in
335
335
  toolsets with `agentpool mcp --toolsets default,stats,sessions,leases,worktrees`.
336
336
 
@@ -127,7 +127,7 @@ agentpool spawn \
127
127
  --task "Inspect the project and ask one clarifying question." \
128
128
  --isolation read_only
129
129
 
130
- agentpool observe <session-id> --wait-for completed,error,question,approval_prompt --timeout 120 --json
130
+ agentpool observe <session-id> --wait-for completed,error,question,approval_prompt --timeout 60 --json
131
131
  agentpool send <session-id> "Continue with the smallest useful check."
132
132
  agentpool artifacts <session-id> --json
133
133
  agentpool transcript <session-id> --tail-lines 80 --json
@@ -287,9 +287,9 @@ Use `--absolute-command` if the MCP host does not inherit your shell `PATH`.
287
287
  Verified per-host steps live in [docs/mcp-clients.md](docs/mcp-clients.md).
288
288
  Team templates: [.cursor/mcp.json.example](.cursor/mcp.json.example),
289
289
  [.mcp.json.example](.mcp.json.example), and [docs/examples/README.md](docs/examples/README.md).
290
- MCP Registry draft metadata: [server.json](server.json). It intentionally omits
291
- package entries until `agentpool-cli` exists on PyPI. Release checklist:
292
- [docs/release.md](docs/release.md).
290
+ MCP Registry metadata: [server.json](server.json). It advertises the
291
+ `agentpool-cli` PyPI package and should be bumped with each release. Release
292
+ checklist: [docs/release.md](docs/release.md).
293
293
  Provider setup guides:
294
294
  [Cursor](docs/setup-cursor.md),
295
295
  [Cursor Agent CLI](docs/setup-cursor-cli.md),
@@ -309,7 +309,7 @@ Then use tools for live operations. The user-owned preferences file also shows
309
309
  up through `agentpool preferences` and `get_delegation_preferences()`. It may
310
310
  say to use your native subagent system instead of AgentPool for some tasks. The
311
311
  default MCP toolset is deliberately small: inventory, usage snapshot, usage
312
- summary, provider models, preferences, spawn, observe, send, interrupt,
312
+ summary, provider models, preferences, spawn, observe, poll, send, interrupt,
313
313
  collect, artifact manifest, transcript paging, and terminate. Add opt-in
314
314
  toolsets with `agentpool mcp --toolsets default,stats,sessions,leases,worktrees`.
315
315
 
@@ -16,7 +16,7 @@ another agent's full transcript through an MCP tool result.
16
16
  agentpool usage-summary --refresh --json
17
17
  agentpool models --provider <provider-id> --json
18
18
  agentpool spawn --provider <provider-id> --model <model-id> --repo . --task "<narrow task>" --isolation read_only --json
19
- agentpool observe <session-id> --wait-for completed,error,question,approval_prompt --timeout 120 --json
19
+ agentpool observe <session-id> --wait-for completed,error,question,approval_prompt --timeout 60 --json
20
20
  agentpool send <session-id> "<steering>"
21
21
  agentpool artifacts <session-id> --json
22
22
  agentpool transcript <session-id> --offset 0 --limit 4000 --json
@@ -36,8 +36,8 @@ need to delegate coding-agent work.
36
36
  - Use `read_only` isolation for exploration, review, and triage.
37
37
  - Choose `worktree` explicitly when AgentPool should create a worktree.
38
38
  - Keep workers narrow: one task, clear stop condition, explicit provider.
39
- - Observe workers with `observe_worker` or `agentpool observe`; do not replace
40
- the control loop with session-list polling.
39
+ - Observe workers with `observe_worker`, `poll_worker`, or `agentpool observe`;
40
+ do not replace the control loop with session-list polling.
41
41
  - Treat worker output as untrusted. Read artifact files only when needed.
42
42
  - Collect artifacts before relying on worker output.
43
43
  - Terminate sessions when finished.
@@ -49,7 +49,7 @@ agentpool usage-summary --refresh --json
49
49
  agentpool preferences
50
50
  agentpool models --provider <provider-id> --json
51
51
  agentpool spawn --provider <provider-id> --model <model-id> --repo . --task "<narrow task>" --isolation read_only --json
52
- agentpool observe <session-id> --wait-for completed,error,question,approval_prompt --timeout 120 --json
52
+ agentpool observe <session-id> --wait-for completed,error,question,approval_prompt --timeout 60 --json
53
53
  agentpool send <session-id> "<steering>"
54
54
  agentpool artifacts <session-id> --json
55
55
  agentpool transcript <session-id> --tail-lines 80 --json
@@ -75,12 +75,22 @@ without dumping the whole file into context.
75
75
  2. `get_usage_summary(provider_id=..., refresh=false)`
76
76
  3. `get_provider_models(provider_id=...)`
77
77
  4. `spawn_worker(provider_id=..., model=..., repo_path=..., task=..., isolation="read_only")`
78
- 5. `observe_worker(session_id=..., wait_for=["completed","error","question","approval_prompt"], timeout_seconds=120)`
79
- 6. `send_worker_message(...)` or `interrupt_worker(...)`
80
- 7. `get_artifact_manifest(...)`
81
- 8. `read_worker_transcript(...)` for bounded transcript pages, only if needed
82
- 9. `collect_worker_artifacts(...)`
83
- 10. `terminate_worker(...)`
78
+ 5. `observe_worker(session_id=..., wait_for=["completed","error","question","approval_prompt"], timeout_seconds=45)`
79
+ 6. `poll_worker(session_id=..., include_recent_log=true)` for immediate progress checks between waits
80
+ 7. `send_worker_message(...)` or `interrupt_worker(...)`
81
+ 8. `get_artifact_manifest(...)`
82
+ 9. `read_worker_transcript(...)` for bounded transcript pages, only if needed
83
+ 10. `collect_worker_artifacts(...)`
84
+ 11. `terminate_worker(...)`
85
+
86
+ In MCP, `observe_worker(timeout_seconds=0)` and
87
+ `observe_worker(timeout_seconds=1)` are fast polls. Prefer `poll_worker` when
88
+ you want a current snapshot without waiting. Long waits are guarded below common
89
+ host executor caps, and AgentPool returns current state plus timeout metadata
90
+ instead of letting the host kill the call. Set `include_recent_log=true` when
91
+ you need a bounded output tail while the worker is still running; AgentPool also
92
+ keeps `summary.partial.md` in the artifact manifest for salvageable progress
93
+ notes before final `summary.md` or `result.md` exists.
84
94
 
85
95
  Use opt-in MCP toolsets for extra surfaces:
86
96
 
@@ -20,7 +20,7 @@ agentpool spawn \
20
20
  Observe and steer:
21
21
 
22
22
  ```bash
23
- agentpool observe <session-id> --wait-for question,completed,error --timeout 120 --json
23
+ agentpool observe <session-id> --wait-for question,completed,error --timeout 60 --json
24
24
  agentpool send <session-id> "Inspect migrations first. Stay read-only."
25
25
  agentpool session show <session-id> --json
26
26
  agentpool collect <session-id> --json
@@ -260,8 +260,9 @@ Once connected, a good first prompt is:
260
260
  Read agentpool://skill.md and agentpool://preferences.md. Then call
261
261
  get_delegation_preferences(), get_usage_summary(refresh=false),
262
262
  get_provider_models(), and get_inventory() before
263
- spawning any workers. After spawn_worker, use observe_worker for the worker
264
- control loop; do not poll get_session/list_sessions as a substitute. Use
263
+ spawning any workers. After spawn_worker, use observe_worker for waits and
264
+ poll_worker for immediate progress checks; do not poll get_session/list_sessions
265
+ as a substitute. Use
265
266
  read_worker_transcript with offset/limit only when you need bounded transcript
266
267
  pages. If Codex shows update or hook-review startup menus, answer the numbered
267
268
  menu choice explicitly before observing again. Choose providers explicitly; do
@@ -39,6 +39,7 @@ The default toolset is the smallest worker lifecycle surface:
39
39
  - `get_delegation_preferences`
40
40
  - `spawn_worker`
41
41
  - `observe_worker`
42
+ - `poll_worker`
42
43
  - `send_worker_message`
43
44
  - `interrupt_worker`
44
45
  - `collect_worker_artifacts`
@@ -85,12 +86,29 @@ Recommended loop:
85
86
  1. `get_usage_summary(provider_id=..., refresh=false)`
86
87
  2. `get_provider_models(provider_id=...)`
87
88
  3. `spawn_worker(provider_id=..., model=..., repo_path=..., task=..., isolation="read_only")`
88
- 4. `observe_worker(session_id=..., wait_for=["completed","error","question","approval_prompt"], timeout_seconds=120)`
89
+ 4. `observe_worker(session_id=..., wait_for=["completed","error","question","approval_prompt"], timeout_seconds=45)`
89
90
  5. `send_worker_message(...)` or `interrupt_worker(...)` when needed
90
- 6. `get_artifact_manifest(...)`
91
- 7. `read_worker_transcript(session_id=..., offset=..., limit=...)` only when a bounded transcript page is needed
92
- 8. `collect_worker_artifacts(...)`
93
- 9. `terminate_worker(...)` when the session is no longer useful
91
+ 6. `poll_worker(session_id=..., include_recent_log=true)` for immediate progress checks between waits
92
+ 7. `get_artifact_manifest(...)`
93
+ 8. `read_worker_transcript(session_id=..., offset=..., limit=...)` only when a bounded transcript page is needed
94
+ 9. `collect_worker_artifacts(...)`
95
+ 10. `terminate_worker(...)` when the session is no longer useful
96
+
97
+ `observe_worker` accepts both event names and terminal state names in
98
+ `wait_for`, so `["completed"]` and `["COMPLETED"]` both work. Unknown
99
+ `wait_for` values are rejected instead of silently becoming a poll. In MCP, long
100
+ observe waits are guarded below common host executor caps; if a larger
101
+ `timeout_seconds` is requested, AgentPool returns a timeout payload with
102
+ `requested_timeout_seconds`, `effective_timeout_seconds`, and the current worker
103
+ metadata rather than letting the outer host drop the tool call. Passing
104
+ `timeout_seconds=0` or `1` is treated as a fast poll. Prefer `poll_worker` when
105
+ you explicitly want "show me the current frame now."
106
+
107
+ When `include_recent_log=true`, `observe_worker` and `poll_worker` include a
108
+ bounded recent screen/log tail in `worker_output`, even before final artifacts
109
+ exist. Each observe also refreshes `summary.partial.md` in the artifact
110
+ manifest. `summary.md` and `result.md` remain final-result files and are written
111
+ when a result marker is found or when artifacts are collected.
94
112
 
95
113
  `spawn_worker.task` must be the concrete delegated instruction. Placeholder text
96
114
  such as `Improve documentation in @filename` is rejected.
@@ -108,9 +126,10 @@ user's provider config.
108
126
 
109
127
  ## Output Detail And Lockdown
110
128
 
111
- Worker text is untrusted model output. `observe_worker` and
129
+ Worker text is untrusted model output. `observe_worker`, `poll_worker`, and
112
130
  `collect_worker_artifacts` default to `detail="summary"`, which returns state,
113
- readiness metadata, and artifact paths without inline worker text.
131
+ readiness metadata, and artifact paths without inline worker text unless an
132
+ observe/poll call explicitly asks for `include_recent_log=true`.
114
133
 
115
134
  Use `detail="excerpt"` or `detail="full"` only when the coordinator needs text
116
135
  inline. Inline worker text is wrapped in a random per-call delimiter:
@@ -54,7 +54,7 @@ agentpool spawn --provider <provider-id> --repo . \
54
54
  The result includes a top-level `session_id`. Drive it with:
55
55
 
56
56
  ```bash
57
- agentpool observe <session-id> --wait-for question,completed,error --timeout 120 --json
57
+ agentpool observe <session-id> --wait-for question,completed,error --timeout 60 --json
58
58
  agentpool send <session-id> "Continue with the smallest useful check." --json
59
59
  agentpool session show <session-id> --json
60
60
  agentpool collect <session-id> --json
@@ -7,6 +7,7 @@ metadata, and onboarding verification.
7
7
 
8
8
  ```bash
9
9
  .venv/bin/python -m pytest -q
10
+ .venv/bin/python scripts/check_release_metadata.py
10
11
  agentpool models validate --path src/agentpool/provider_model_catalog.json --json
11
12
  agentpool config validate --json
12
13
  agentpool smoke --provider fake-question --repo . --json
@@ -27,12 +28,13 @@ Update together before tagging:
27
28
  - `pyproject.toml` `[project].version`
28
29
  - `src/agentpool/__init__.py` `__version__`
29
30
  - `server.json` top-level `version`
30
- - `server.json` `packages[].version` after public PyPI publishing is enabled
31
+ - `server.json` `packages[].version`
31
32
  - [CHANGELOG.md](../CHANGELOG.md)
32
33
 
33
34
  The public PyPI distribution name is `agentpool-cli`. The installed console
34
- command remains `agentpool`. Do not publish a package named `agentpool`; that
35
- PyPI name belongs to another project.
35
+ command remains `agentpool`, with an `agentpool-cli` console-script alias for
36
+ `uvx agentpool-cli mcp`. Do not publish a package named `agentpool`; that PyPI
37
+ name belongs to another project.
36
38
 
37
39
  ## Tag and publish
38
40
 
@@ -51,18 +53,37 @@ The [release workflow](../.github/workflows/release.yml) will:
51
53
  repository variable `PUBLISH_TO_PYPI` is set to `true` and the `pypi`
52
54
  deployment environment is configured. Otherwise the publish job is skipped.
53
55
 
54
- See [Manual one-time setup](#manual-one-time-pypi-setup) below for the steps
55
- that must be done on PyPI before the publish job can succeed.
56
+ Keep the external setup in
57
+ [PyPI and GitHub trusted-publisher state](#pypi-and-github-trusted-publisher-state)
58
+ in place before tagging.
56
59
 
57
- ## Manual one-time PyPI setup
60
+ ## PyPI and GitHub trusted-publisher state
58
61
 
59
- These steps are done once, outside CI, before the first automated publish:
62
+ The `agentpool-cli` project is already live on PyPI, and the `v0.1.12`
63
+ distributions were uploaded using Trusted Publishing from
64
+ `sidduHERE/agentpool` via `.github/workflows/release.yml` and the `pypi`
65
+ environment.
60
66
 
61
- 1. Reserve / claim the `agentpool-cli` project name on PyPI.
62
- 2. Configure a PyPI **Trusted Publisher (pending publisher)** pointing at this
63
- GitHub repository, the `release.yml` workflow, and the `pypi` environment.
64
- 3. Create a GitHub **`pypi` deployment environment** on the repo.
65
- 4. Set the repository variable `PUBLISH_TO_PYPI=true` to arm the publish job.
67
+ Keep these exact external settings:
68
+
69
+ - PyPI project: `agentpool-cli`
70
+ - PyPI trusted publisher owner: `sidduHERE`
71
+ - PyPI trusted publisher repository: `agentpool`
72
+ - PyPI trusted publisher workflow: `release.yml`
73
+ - PyPI trusted publisher environment: `pypi`
74
+ - GitHub deployment environment: `pypi`
75
+ - GitHub repository variable: `PUBLISH_TO_PYPI=true`
76
+
77
+ The publish job has `id-token: write` only on the PyPI job and no PyPI token
78
+ secret is required.
79
+
80
+ Recommended GitHub hardening:
81
+
82
+ - Add required reviewers to the `pypi` deployment environment so a tag push does
83
+ not immediately publish without a human release approval.
84
+ - If deployment branch/tag rules are enabled, allow release tags matching `v*`;
85
+ do not restrict the environment to branch deployments only.
86
+ - Keep PyPI API tokens out of GitHub secrets for this project.
66
87
 
67
88
  ## Post-release smoke
68
89
 
@@ -87,25 +108,16 @@ uv tool install --force --python python3.11 \
87
108
 
88
109
  ## MCP Registry
89
110
 
90
- Do not publish [server.json](../server.json) to the MCP Registry until
91
- `agentpool-cli` is available from PyPI. The committed metadata intentionally
92
- omits `packages` so it does not advertise an unavailable install method. After
93
- the first successful PyPI publish, add a `pypi` package entry that maps registry
94
- consumers to:
95
-
96
- ```json
97
- { "command": "agentpool", "args": ["mcp"] }
98
- ```
99
-
100
- Bump `server.json` `packages[].version` together with the project version from
101
- then on.
111
+ [server.json](../server.json) now advertises the published `agentpool-cli` PyPI
112
+ package. Keep its top-level `version` and `packages[].version` aligned with
113
+ `pyproject.toml` and `src/agentpool/__init__.py`.
102
114
 
103
115
  Host-specific install UX remains in [docs/mcp-clients.md](mcp-clients.md).
104
116
 
105
117
  Publish sequence:
106
118
 
107
119
  1. Publish `agentpool-cli` to PyPI with Trusted Publishing (the release job).
108
- 2. Add the `packages` entry to `server.json`.
120
+ 2. Keep [server.json](../server.json) pointed at the same published version.
109
121
  3. Keep the README metadata comment `mcp-name: io.github.sidduHERE/agentpool`.
110
122
  The namespace casing must match the GitHub username exactly (`sidduHERE`, not
111
123
  `sidduhere`); the registry grants `io.github.<login>/*` with the login's
@@ -101,7 +101,7 @@ Read agentpool://skill.md. Then call
101
101
  get_usage_summary(provider_id="codex-cli", refresh=false),
102
102
  get_provider_models(provider_id="codex-cli"), and get_inventory before spawning
103
103
  any workers. After spawn_worker, use
104
- observe_worker for the worker control loop. If Codex shows an update prompt,
104
+ observe_worker for waits and poll_worker for immediate progress checks. If Codex shows an update prompt,
105
105
  send menu choice 2 to skip. If Codex shows a directory trust prompt, send an
106
106
  empty submitted message only when trusting that directory is acceptable. If it
107
107
  shows hook review, send menu choice 3 unless the user approved trusting hooks.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agentpool-cli"
7
- version = "0.1.12"
7
+ version = "0.1.13"
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"
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env python3
2
+ """Validate release metadata that must move together."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import ast
7
+ import json
8
+ import sys
9
+ import tomllib
10
+ from pathlib import Path
11
+
12
+
13
+ ROOT = Path(__file__).resolve().parents[1]
14
+ EXPECTED_DISTRIBUTION = "agentpool-cli"
15
+ EXPECTED_MCP_NAME = "io.github.sidduHERE/agentpool"
16
+ EXPECTED_REPOSITORY = "https://github.com/sidduHERE/agentpool"
17
+ EXPECTED_SERVER_NAME = "io.github.sidduHERE/agentpool"
18
+ EXPECTED_PYPI_URL = "https://pypi.org/p/agentpool-cli"
19
+
20
+
21
+ def fail(message: str) -> None:
22
+ print(f"release metadata check failed: {message}", file=sys.stderr)
23
+ raise SystemExit(1)
24
+
25
+
26
+ def project_metadata() -> dict:
27
+ with (ROOT / "pyproject.toml").open("rb") as handle:
28
+ return tomllib.load(handle)["project"]
29
+
30
+
31
+ def package_version() -> str:
32
+ tree = ast.parse((ROOT / "src/agentpool/__init__.py").read_text(encoding="utf-8"))
33
+ for node in tree.body:
34
+ if (
35
+ isinstance(node, ast.Assign)
36
+ and any(
37
+ isinstance(target, ast.Name) and target.id == "__version__"
38
+ for target in node.targets
39
+ )
40
+ and isinstance(node.value, ast.Constant)
41
+ and isinstance(node.value.value, str)
42
+ ):
43
+ return node.value.value
44
+ fail("src/agentpool/__init__.py does not define a string __version__")
45
+
46
+
47
+ def main() -> None:
48
+ project = project_metadata()
49
+ version = package_version()
50
+ server = json.loads((ROOT / "server.json").read_text(encoding="utf-8"))
51
+ readme = (ROOT / "README.md").read_text(encoding="utf-8")
52
+ workflow = (ROOT / ".github/workflows/release.yml").read_text(encoding="utf-8")
53
+
54
+ if project["name"] != EXPECTED_DISTRIBUTION:
55
+ fail(f"pyproject distribution name must be {EXPECTED_DISTRIBUTION!r}")
56
+ if project["version"] != version:
57
+ fail(f"pyproject version {project['version']!r} != package version {version!r}")
58
+
59
+ scripts = project.get("scripts", {})
60
+ expected_entrypoint = "agentpool.cli:app"
61
+ if scripts.get("agentpool") != expected_entrypoint:
62
+ fail("agentpool console script must point at agentpool.cli:app")
63
+ if scripts.get(EXPECTED_DISTRIBUTION) != expected_entrypoint:
64
+ fail("agentpool-cli console script alias must point at agentpool.cli:app")
65
+
66
+ if f"mcp-name: {EXPECTED_MCP_NAME}" not in readme:
67
+ fail(f"README.md must contain mcp-name: {EXPECTED_MCP_NAME}")
68
+ if "intentionally omits\npackage entries until `agentpool-cli` exists on PyPI" in readme:
69
+ fail("README.md still says server.json omits PyPI package entries")
70
+
71
+ if server["name"] != EXPECTED_SERVER_NAME:
72
+ fail(f"server.json name must be {EXPECTED_SERVER_NAME!r}")
73
+ if server["repository"]["url"] != EXPECTED_REPOSITORY:
74
+ fail(f"server.json repository URL must be {EXPECTED_REPOSITORY!r}")
75
+ if server["version"] != version:
76
+ fail(f"server.json version {server['version']!r} != package version {version!r}")
77
+
78
+ packages = server.get("packages")
79
+ if not isinstance(packages, list) or len(packages) != 1:
80
+ fail("server.json must advertise exactly one PyPI package")
81
+ package = packages[0]
82
+ if package.get("registryType") != "pypi":
83
+ fail("server.json package registryType must be pypi")
84
+ if package.get("identifier") != EXPECTED_DISTRIBUTION:
85
+ fail(f"server.json package identifier must be {EXPECTED_DISTRIBUTION!r}")
86
+ if package.get("version") != version:
87
+ fail(f"server.json package version {package.get('version')!r} != {version!r}")
88
+ if package.get("transport", {}).get("type") != "stdio":
89
+ fail("server.json package transport must be stdio")
90
+ if package.get("packageArguments") != [{"type": "positional", "value": "mcp"}]:
91
+ fail("server.json package arguments must run the MCP stdio server")
92
+
93
+ required_workflow_text = [
94
+ "vars.PUBLISH_TO_PYPI == 'true'",
95
+ "name: pypi",
96
+ EXPECTED_PYPI_URL,
97
+ "id-token: write",
98
+ "pypa/gh-action-pypi-publish@release/v1",
99
+ ]
100
+ for text in required_workflow_text:
101
+ if text not in workflow:
102
+ fail(f"release workflow missing {text!r}")
103
+
104
+ print(f"release metadata ok: {EXPECTED_DISTRIBUTION} {version}")
105
+
106
+
107
+ if __name__ == "__main__":
108
+ main()
@@ -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.12",
6
+ "version": "0.1.13",
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.12",
16
+ "version": "0.1.13",
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.12"
3
+ __version__ = "0.1.13"
@@ -11,7 +11,7 @@ Detail = Literal["summary", "excerpt", "full"]
11
11
  DETAILS: set[str] = {"summary", "excerpt", "full"}
12
12
  EXCERPT_CHARS = 1600
13
13
  FULL_CHARS = 8000
14
- RAW_ARTIFACT_KINDS = {"transcript", "events", "screen", "summary", "result", "diff"}
14
+ RAW_ARTIFACT_KINDS = {"transcript", "events", "screen", "summary_partial", "summary", "result", "diff"}
15
15
 
16
16
 
17
17
  def parse_detail(value: str) -> Detail:
@@ -109,6 +109,8 @@ def collect_payload(result: dict[str, Any], detail: Detail, lockdown: bool = Fal
109
109
  "artifacts": [gate_raw_artifact(artifact, lockdown) for artifact in result.get("artifacts") or []],
110
110
  "git": result.get("git"),
111
111
  }
112
+ if result.get("warnings"):
113
+ payload["warnings"] = result["warnings"]
112
114
  summary = str(result.get("summary") or "")
113
115
  if detail == "summary" or lockdown or not summary:
114
116
  payload["worker_output"] = omitted_worker_output(detail, lockdown)