alab-cli 0.1.0__tar.gz → 0.1.2__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 (52) hide show
  1. {alab_cli-0.1.0 → alab_cli-0.1.2}/PKG-INFO +46 -8
  2. {alab_cli-0.1.0 → alab_cli-0.1.2}/README.md +44 -7
  3. {alab_cli-0.1.0 → alab_cli-0.1.2}/pyproject.toml +3 -2
  4. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/__init__.py +1 -1
  5. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/cli.py +11 -2
  6. alab_cli-0.1.2/src/alab/dashboard.py +1200 -0
  7. alab_cli-0.1.2/src/alab/dashboard_static/app.js +4774 -0
  8. alab_cli-0.1.2/src/alab/dashboard_static/index.html +50 -0
  9. alab_cli-0.1.2/src/alab/dashboard_static/styles.css +3649 -0
  10. alab_cli-0.1.2/src/alab/dashboard_static/vendor/chart.umd.js +14 -0
  11. alab_cli-0.1.2/src/alab/dashboard_static/vendor/chartjs-LICENSE.md +9 -0
  12. alab_cli-0.1.2/src/alab/dashboard_static/vendor/lucide-LICENSE +43 -0
  13. alab_cli-0.1.2/src/alab/dashboard_static/vendor/lucide-icons.svg +60 -0
  14. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/home.py +5 -0
  15. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/registry.py +8 -1
  16. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/runner.py +25 -8
  17. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/services.py +1289 -236
  18. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab_cli.egg-info/PKG-INFO +46 -8
  19. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab_cli.egg-info/SOURCES.txt +9 -0
  20. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_cli_contract.py +817 -7
  21. alab_cli-0.1.2/tests/test_dashboard.py +1238 -0
  22. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_real_docker.py +44 -0
  23. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_runner_docker.py +1 -0
  24. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_runner_harbor.py +49 -2
  25. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_runner_local.py +8 -0
  26. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_smoke.py +14 -0
  27. {alab_cli-0.1.0 → alab_cli-0.1.2}/LICENSE +0 -0
  28. {alab_cli-0.1.0 → alab_cli-0.1.2}/setup.cfg +0 -0
  29. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/__main__.py +0 -0
  30. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/auth.py +0 -0
  31. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/configs.py +0 -0
  32. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/context.py +0 -0
  33. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/db.py +0 -0
  34. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/docker_platform.py +0 -0
  35. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/errors.py +0 -0
  36. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/ids.py +0 -0
  37. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/migrations/1_initial.sql +0 -0
  38. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/proc.py +0 -0
  39. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/rendering.py +0 -0
  40. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/source_import.py +0 -0
  41. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab/timeutil.py +0 -0
  42. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab_cli.egg-info/dependency_links.txt +0 -0
  43. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab_cli.egg-info/entry_points.txt +0 -0
  44. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab_cli.egg-info/requires.txt +0 -0
  45. {alab_cli-0.1.0 → alab_cli-0.1.2}/src/alab_cli.egg-info/top_level.txt +0 -0
  46. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_auth.py +0 -0
  47. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_errors.py +0 -0
  48. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_ids.py +0 -0
  49. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_migrations.py +0 -0
  50. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_real_skydiscover_catalog.py +0 -0
  51. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_real_skydiscover_python.py +0 -0
  52. {alab_cli-0.1.0 → alab_cli-0.1.2}/tests/test_runner_skydiscover.py +0 -0
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alab-cli
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Local agent-first experiment workbench CLI
5
5
  Author: ALab contributors
6
6
  License-Expression: GPL-3.0-or-later
7
7
  Project-URL: Homepage, https://github.com/bebetterest/ALab
8
8
  Project-URL: Repository, https://github.com/bebetterest/ALab
9
9
  Project-URL: Issues, https://github.com/bebetterest/ALab/issues
10
+ Project-URL: Changelog, https://github.com/bebetterest/ALab/blob/main/CHANGELOG.md
10
11
  Requires-Python: >=3.11
11
12
  Description-Content-Type: text/markdown
12
13
  License-File: LICENSE
@@ -23,13 +24,22 @@ Dynamic: license-file
23
24
  <img src="docs/assets/readme-header.png" alt="Hand-drawn ALab virtual experiment workbench banner" width="100%">
24
25
  </p>
25
26
 
27
+ > 🤖 Most of the code is completed by [Codex](https://openai.com/codex/).
28
+ >
29
+ > 📮 Feedback: [bebetterest@outlook.com](mailto:bebetterest@outlook.com)
30
+ >
31
+ > [English](README.md) | [中文](README_cn.md)
32
+
26
33
  ALab is a local, agent-first Python CLI workbench for iterative experiments. It lets external agents work in isolated Git worktrees, run repeatable evaluations, submit final results, and inspect visible prior experiment evidence through explicit collaboration boundaries.
27
34
 
28
- ALab V1 is intentionally local-only: no server, sync service, web UI, built-in agent launcher, or account system. It owns the local project records, source snapshots, experiment lifecycle, runner execution, logs, artifacts, and visibility rules; agents remain external CLI operators.
35
+ ALab V1 is intentionally local-only: no hosted service, sync service, remote web UI, built-in agent launcher, or account system. It owns the local project records, source snapshots, experiment lifecycle, runner execution, logs, artifacts, visibility rules, and a root-only local read-only dashboard; agents remain external CLI operators.
29
36
 
30
37
  ## Highlights
31
38
 
32
39
  - Local CLI workbench for projects, sources, experiments, runs, submissions, logs, artifacts, annotations, and audits.
40
+ - HOME-level feedback capture so any ALab role can leave local suggestions, questions, or bug reports without needing project credentials.
41
+ - Root-only local dashboard for browser-based read-only inspection of global/project/experiment/run/log/artifact/audit/feedback/system state.
42
+ - Markdown evidence reports for project owners or visible experiment contexts through `alab report`.
33
43
  - Context-aware command surface: `alab help` and command preflight show only what the current project, experiment, inspection checkout, token, or explicit key can use.
34
44
  - Git-backed experiment isolation: each experiment is an isolated branch/worktree with a worktree token for run and submit operations.
35
45
  - Reproducible project setup: project config controls runner, reward, artifact capture, environment, secrets, mutable paths, and visibility.
@@ -198,6 +208,9 @@ Useful next commands:
198
208
 
199
209
  ```sh
200
210
  alab help
211
+ alab feedback --kind suggestion --body "Describe a suggestion, question, or bug for the project owner."
212
+ alab --key <root-key> dashboard --no-open
213
+ alab --key <admin-or-root-key> report --project <project-id> --out ./alab-project-report.md
201
214
  alab observe experiments list
202
215
  alab observe runs list --exp <exp-id>
203
216
  alab observe experiments best
@@ -211,6 +224,9 @@ alab observe experiments best
211
224
  - **Experiment**: isolated Git branch/worktree bound to exactly one source and one config version.
212
225
  - **Run**: one evaluator execution for an experiment commit, with status, reward, logs, artifacts, and warning codes.
213
226
  - **Submit**: closes an experiment with final summary, feedback, final run, final commit, and explicit refs.
227
+ - **Feedback**: HOME-level plaintext notes for suggestions, questions, bugs, or other agent observations, stored as one directory per entry under `feedback/`.
228
+ - **Dashboard**: root-only local browser panel for read-only inspection. It binds to `127.0.0.1`, uses a random browser session token, serves bounded paginated read models for large homes, and writes no ALab records.
229
+ - **Reports**: Markdown evidence exports for project-level owner handoffs or visible experiment contexts, without raw secrets, hidden log contents, or artifact bytes.
214
230
  - **Inspection checkout**: read-only checkout for observing/exporting scoped experiment evidence without becoming submit-capable.
215
231
 
216
232
  ## Configuration
@@ -228,7 +244,14 @@ See [docs/spec_runners_adapters.md](docs/spec_runners_adapters.md), [docs/spec_p
228
244
 
229
245
  ## Examples
230
246
 
231
- - [examples/skydiscover_circle_packing_codex](examples/skydiscover_circle_packing_codex/): complete SkyDiscover circle-packing example with setup, single Codex worker run, project-controller loop, report collection, and real-run notes.
247
+ See [examples](examples/) for the runnable example matrix. The current examples
248
+ cover a local scoring loop, a Dockerized clinic-order fulfillment planner with
249
+ artifact export, a Harbor hidden-verifier incident classifier, a collaborative
250
+ incident triage lifecycle workflow, a generated dashboard showcase home, and
251
+ the SkyDiscover circle-packing Codex single-worker protocol. The same examples area also includes
252
+ `examples/templates/`, a copyable multi-instance TSP template library for
253
+ local, Docker, Harbor, SkyDiscover Python, and SkyDiscover Docker runner
254
+ projects.
232
255
 
233
256
  The repository also includes Codex-facing role skills under [skills](skills/). They are external runbooks for operating ALab through the CLI as an experiment worker, project controller, or global admin; they do not add an embedded agent launcher to ALab.
234
257
 
@@ -245,10 +268,10 @@ Opt-in integration gates are excluded from the default suite:
245
268
 
246
269
  ```sh
247
270
  ALAB_RUN_REAL_DOCKER=1 UV_CACHE_DIR=.uv-cache UV_DEFAULT_INDEX=https://pypi.org/simple uv run pytest -m real_docker
248
- ALAB_RUN_REAL_SKYDISCOVER_PYTHON=1 UV_CACHE_DIR=.uv-cache uv run pytest -m real_skydiscover_python
271
+ ALAB_RUN_REAL_SKYDISCOVER_PYTHON=1 UV_CACHE_DIR=.uv-cache UV_DEFAULT_INDEX=https://pypi.org/simple uv run pytest -m real_skydiscover_python
249
272
  ALAB_RUN_NETWORKED_SKYDISCOVER_PYTHON=1 UV_CACHE_DIR=.uv-cache UV_DEFAULT_INDEX=https://pypi.org/simple uv run pytest -m networked_skydiscover_python
250
273
  ALAB_RUN_NATIVE_SKYDISCOVER_PYTHON=1 UV_CACHE_DIR=.uv-cache UV_DEFAULT_INDEX=https://pypi.org/simple uv run pytest -m native_skydiscover_python
251
- ALAB_RUN_LIVE_SKYDISCOVER_CATALOG=1 UV_CACHE_DIR=.uv-cache uv run pytest -m live_skydiscover_catalog
274
+ ALAB_RUN_LIVE_SKYDISCOVER_CATALOG=1 UV_CACHE_DIR=.uv-cache UV_DEFAULT_INDEX=https://pypi.org/simple uv run pytest -m live_skydiscover_catalog
252
275
  ```
253
276
 
254
277
  Notes:
@@ -256,7 +279,7 @@ Notes:
256
279
  - `uv.lock` is tracked because CI and local validation use `uv run --locked`.
257
280
  - Keep local cache/output paths ignored (`.uv-cache/`, `.pytest_cache/`, `.ruff_cache/`, `.alab-demo/`, `.env`).
258
281
  - GitHub Actions runs the default lint and pytest suite on pull requests and pushes to `main`; real Docker and live/networked SkyDiscover gates remain manual workflow inputs.
259
- - Pushes to `main` check PyPI for the current `pyproject.toml` package version; if that exact version is missing, CI builds and publishes through PyPI Trusted Publishing, otherwise it skips publishing.
282
+ - Pushes to `main` check PyPI for the current `pyproject.toml` package version; if that exact version is missing, CI builds and publishes through PyPI Trusted Publishing, then creates a `v<version>` GitHub Release from the matching [CHANGELOG.md](CHANGELOG.md) section. If PyPI already has that version, publishing and release creation are skipped.
260
283
  - The PyPI `alab-cli` project must trust repository `bebetterest/ALab`, workflow `ci.yml`, and environment `pypi` before the first automated publish can succeed.
261
284
 
262
285
  ## Security And Data Model
@@ -268,6 +291,7 @@ ALab V1 is a local collaboration boundary, not a multi-user security product:
268
291
  - Credential verifiers are stored; raw credential secrets are not.
269
292
  - Project records are local plaintext SQLite/filesystem data.
270
293
  - `secret_env` values are local plaintext, redacted from rendered logs where configured, and never exported by config commands.
294
+ - The dashboard is loopback-only and root-only. Its API can read hidden/full logs and artifact bytes for that root session, but it must not render raw keys, raw tokens, credential verifier material, or raw `secret_env` values.
271
295
  - Artifact exports are exact captured bytes and are not automatically redacted.
272
296
 
273
297
  ## Repository Structure
@@ -280,6 +304,8 @@ ALab V1 is a local collaboration boundary, not a multi-user security product:
280
304
  ├── docs/
281
305
  │ ├── assets/
282
306
  │ │ └── readme-header.png
307
+ │ ├── README.md
308
+ │ ├── README_cn.md
283
309
  │ ├── blueprint.md
284
310
  │ ├── blueprint_cn.md
285
311
  │ ├── completion_audit.md
@@ -289,7 +315,15 @@ ALab V1 is a local collaboration boundary, not a multi-user security product:
289
315
  │ ├── progress_pipeline.md
290
316
  │ └── progress_pipeline_cn.md
291
317
  ├── examples/
292
- └── skydiscover_circle_packing_codex/
318
+ ├── README.md
319
+ │ ├── README_cn.md
320
+ │ ├── collaboration_observe_lifecycle/
321
+ │ ├── dashboard_showcase/
322
+ │ ├── docker_file_reward_artifacts/
323
+ │ ├── harbor_verifier_minimal/
324
+ │ ├── local_agent_scoreboard/
325
+ │ ├── skydiscover_circle_packing_codex/
326
+ │ └── templates/
293
327
  ├── skills/
294
328
  │ ├── alab-experiment-worker/
295
329
  │ ├── alab-project-controller/
@@ -304,6 +338,8 @@ ALab V1 is a local collaboration boundary, not a multi-user security product:
304
338
  │ └── test_runner_skydiscover.py
305
339
  ├── LICENSE
306
340
  ├── .env.example
341
+ ├── CHANGELOG.md
342
+ ├── CHANGELOG_cn.md
307
343
  ├── pyproject.toml
308
344
  ├── uv.lock
309
345
  ├── README.md
@@ -316,10 +352,12 @@ Local-only agent notes such as `AGENTS.md` and `CORE.md` are intentionally git-i
316
352
 
317
353
  - English documentation is canonical.
318
354
  - Synchronized Chinese documents use the `*_cn.md` naming pattern.
355
+ - [docs/README.md](docs/README.md) explains the documentation structure and reading order.
319
356
  - [docs/blueprint.md](docs/blueprint.md) is the V1 product overview.
320
- - [docs/spec_cli.md](docs/spec_cli.md), [docs/spec_storage_auth_context.md](docs/spec_storage_auth_context.md), [docs/spec_project_source_experiment.md](docs/spec_project_source_experiment.md), [docs/spec_lifecycle.md](docs/spec_lifecycle.md), [docs/spec_runners_adapters.md](docs/spec_runners_adapters.md), [docs/spec_observe_collaboration.md](docs/spec_observe_collaboration.md), and [docs/spec_tests.md](docs/spec_tests.md) define subsystem contracts.
357
+ - [docs/spec_cli.md](docs/spec_cli.md), [docs/spec_storage_auth_context.md](docs/spec_storage_auth_context.md), [docs/spec_project_source_experiment.md](docs/spec_project_source_experiment.md), [docs/spec_lifecycle.md](docs/spec_lifecycle.md), [docs/spec_runners_adapters.md](docs/spec_runners_adapters.md), [docs/spec_observe_collaboration.md](docs/spec_observe_collaboration.md), [docs/spec_dashboard.md](docs/spec_dashboard.md), and [docs/spec_tests.md](docs/spec_tests.md) define subsystem contracts.
321
358
  - [docs/progress.md](docs/progress.md), [docs/progress_pipeline.md](docs/progress_pipeline.md), [docs/progress_closed_gaps.md](docs/progress_closed_gaps.md), and [docs/progress_log.md](docs/progress_log.md) track current state, active queues, closed gaps, and history.
322
359
  - [docs/completion_audit.md](docs/completion_audit.md) tracks requirement-level evidence.
360
+ - [CHANGELOG.md](CHANGELOG.md) records release-facing changes and is used by CI for GitHub Release notes.
323
361
 
324
362
  ## Contributing
325
363
 
@@ -4,13 +4,22 @@
4
4
  <img src="docs/assets/readme-header.png" alt="Hand-drawn ALab virtual experiment workbench banner" width="100%">
5
5
  </p>
6
6
 
7
+ > 🤖 Most of the code is completed by [Codex](https://openai.com/codex/).
8
+ >
9
+ > 📮 Feedback: [bebetterest@outlook.com](mailto:bebetterest@outlook.com)
10
+ >
11
+ > [English](README.md) | [中文](README_cn.md)
12
+
7
13
  ALab is a local, agent-first Python CLI workbench for iterative experiments. It lets external agents work in isolated Git worktrees, run repeatable evaluations, submit final results, and inspect visible prior experiment evidence through explicit collaboration boundaries.
8
14
 
9
- ALab V1 is intentionally local-only: no server, sync service, web UI, built-in agent launcher, or account system. It owns the local project records, source snapshots, experiment lifecycle, runner execution, logs, artifacts, and visibility rules; agents remain external CLI operators.
15
+ ALab V1 is intentionally local-only: no hosted service, sync service, remote web UI, built-in agent launcher, or account system. It owns the local project records, source snapshots, experiment lifecycle, runner execution, logs, artifacts, visibility rules, and a root-only local read-only dashboard; agents remain external CLI operators.
10
16
 
11
17
  ## Highlights
12
18
 
13
19
  - Local CLI workbench for projects, sources, experiments, runs, submissions, logs, artifacts, annotations, and audits.
20
+ - HOME-level feedback capture so any ALab role can leave local suggestions, questions, or bug reports without needing project credentials.
21
+ - Root-only local dashboard for browser-based read-only inspection of global/project/experiment/run/log/artifact/audit/feedback/system state.
22
+ - Markdown evidence reports for project owners or visible experiment contexts through `alab report`.
14
23
  - Context-aware command surface: `alab help` and command preflight show only what the current project, experiment, inspection checkout, token, or explicit key can use.
15
24
  - Git-backed experiment isolation: each experiment is an isolated branch/worktree with a worktree token for run and submit operations.
16
25
  - Reproducible project setup: project config controls runner, reward, artifact capture, environment, secrets, mutable paths, and visibility.
@@ -179,6 +188,9 @@ Useful next commands:
179
188
 
180
189
  ```sh
181
190
  alab help
191
+ alab feedback --kind suggestion --body "Describe a suggestion, question, or bug for the project owner."
192
+ alab --key <root-key> dashboard --no-open
193
+ alab --key <admin-or-root-key> report --project <project-id> --out ./alab-project-report.md
182
194
  alab observe experiments list
183
195
  alab observe runs list --exp <exp-id>
184
196
  alab observe experiments best
@@ -192,6 +204,9 @@ alab observe experiments best
192
204
  - **Experiment**: isolated Git branch/worktree bound to exactly one source and one config version.
193
205
  - **Run**: one evaluator execution for an experiment commit, with status, reward, logs, artifacts, and warning codes.
194
206
  - **Submit**: closes an experiment with final summary, feedback, final run, final commit, and explicit refs.
207
+ - **Feedback**: HOME-level plaintext notes for suggestions, questions, bugs, or other agent observations, stored as one directory per entry under `feedback/`.
208
+ - **Dashboard**: root-only local browser panel for read-only inspection. It binds to `127.0.0.1`, uses a random browser session token, serves bounded paginated read models for large homes, and writes no ALab records.
209
+ - **Reports**: Markdown evidence exports for project-level owner handoffs or visible experiment contexts, without raw secrets, hidden log contents, or artifact bytes.
195
210
  - **Inspection checkout**: read-only checkout for observing/exporting scoped experiment evidence without becoming submit-capable.
196
211
 
197
212
  ## Configuration
@@ -209,7 +224,14 @@ See [docs/spec_runners_adapters.md](docs/spec_runners_adapters.md), [docs/spec_p
209
224
 
210
225
  ## Examples
211
226
 
212
- - [examples/skydiscover_circle_packing_codex](examples/skydiscover_circle_packing_codex/): complete SkyDiscover circle-packing example with setup, single Codex worker run, project-controller loop, report collection, and real-run notes.
227
+ See [examples](examples/) for the runnable example matrix. The current examples
228
+ cover a local scoring loop, a Dockerized clinic-order fulfillment planner with
229
+ artifact export, a Harbor hidden-verifier incident classifier, a collaborative
230
+ incident triage lifecycle workflow, a generated dashboard showcase home, and
231
+ the SkyDiscover circle-packing Codex single-worker protocol. The same examples area also includes
232
+ `examples/templates/`, a copyable multi-instance TSP template library for
233
+ local, Docker, Harbor, SkyDiscover Python, and SkyDiscover Docker runner
234
+ projects.
213
235
 
214
236
  The repository also includes Codex-facing role skills under [skills](skills/). They are external runbooks for operating ALab through the CLI as an experiment worker, project controller, or global admin; they do not add an embedded agent launcher to ALab.
215
237
 
@@ -226,10 +248,10 @@ Opt-in integration gates are excluded from the default suite:
226
248
 
227
249
  ```sh
228
250
  ALAB_RUN_REAL_DOCKER=1 UV_CACHE_DIR=.uv-cache UV_DEFAULT_INDEX=https://pypi.org/simple uv run pytest -m real_docker
229
- ALAB_RUN_REAL_SKYDISCOVER_PYTHON=1 UV_CACHE_DIR=.uv-cache uv run pytest -m real_skydiscover_python
251
+ ALAB_RUN_REAL_SKYDISCOVER_PYTHON=1 UV_CACHE_DIR=.uv-cache UV_DEFAULT_INDEX=https://pypi.org/simple uv run pytest -m real_skydiscover_python
230
252
  ALAB_RUN_NETWORKED_SKYDISCOVER_PYTHON=1 UV_CACHE_DIR=.uv-cache UV_DEFAULT_INDEX=https://pypi.org/simple uv run pytest -m networked_skydiscover_python
231
253
  ALAB_RUN_NATIVE_SKYDISCOVER_PYTHON=1 UV_CACHE_DIR=.uv-cache UV_DEFAULT_INDEX=https://pypi.org/simple uv run pytest -m native_skydiscover_python
232
- ALAB_RUN_LIVE_SKYDISCOVER_CATALOG=1 UV_CACHE_DIR=.uv-cache uv run pytest -m live_skydiscover_catalog
254
+ ALAB_RUN_LIVE_SKYDISCOVER_CATALOG=1 UV_CACHE_DIR=.uv-cache UV_DEFAULT_INDEX=https://pypi.org/simple uv run pytest -m live_skydiscover_catalog
233
255
  ```
234
256
 
235
257
  Notes:
@@ -237,7 +259,7 @@ Notes:
237
259
  - `uv.lock` is tracked because CI and local validation use `uv run --locked`.
238
260
  - Keep local cache/output paths ignored (`.uv-cache/`, `.pytest_cache/`, `.ruff_cache/`, `.alab-demo/`, `.env`).
239
261
  - GitHub Actions runs the default lint and pytest suite on pull requests and pushes to `main`; real Docker and live/networked SkyDiscover gates remain manual workflow inputs.
240
- - Pushes to `main` check PyPI for the current `pyproject.toml` package version; if that exact version is missing, CI builds and publishes through PyPI Trusted Publishing, otherwise it skips publishing.
262
+ - Pushes to `main` check PyPI for the current `pyproject.toml` package version; if that exact version is missing, CI builds and publishes through PyPI Trusted Publishing, then creates a `v<version>` GitHub Release from the matching [CHANGELOG.md](CHANGELOG.md) section. If PyPI already has that version, publishing and release creation are skipped.
241
263
  - The PyPI `alab-cli` project must trust repository `bebetterest/ALab`, workflow `ci.yml`, and environment `pypi` before the first automated publish can succeed.
242
264
 
243
265
  ## Security And Data Model
@@ -249,6 +271,7 @@ ALab V1 is a local collaboration boundary, not a multi-user security product:
249
271
  - Credential verifiers are stored; raw credential secrets are not.
250
272
  - Project records are local plaintext SQLite/filesystem data.
251
273
  - `secret_env` values are local plaintext, redacted from rendered logs where configured, and never exported by config commands.
274
+ - The dashboard is loopback-only and root-only. Its API can read hidden/full logs and artifact bytes for that root session, but it must not render raw keys, raw tokens, credential verifier material, or raw `secret_env` values.
252
275
  - Artifact exports are exact captured bytes and are not automatically redacted.
253
276
 
254
277
  ## Repository Structure
@@ -261,6 +284,8 @@ ALab V1 is a local collaboration boundary, not a multi-user security product:
261
284
  ├── docs/
262
285
  │ ├── assets/
263
286
  │ │ └── readme-header.png
287
+ │ ├── README.md
288
+ │ ├── README_cn.md
264
289
  │ ├── blueprint.md
265
290
  │ ├── blueprint_cn.md
266
291
  │ ├── completion_audit.md
@@ -270,7 +295,15 @@ ALab V1 is a local collaboration boundary, not a multi-user security product:
270
295
  │ ├── progress_pipeline.md
271
296
  │ └── progress_pipeline_cn.md
272
297
  ├── examples/
273
- └── skydiscover_circle_packing_codex/
298
+ ├── README.md
299
+ │ ├── README_cn.md
300
+ │ ├── collaboration_observe_lifecycle/
301
+ │ ├── dashboard_showcase/
302
+ │ ├── docker_file_reward_artifacts/
303
+ │ ├── harbor_verifier_minimal/
304
+ │ ├── local_agent_scoreboard/
305
+ │ ├── skydiscover_circle_packing_codex/
306
+ │ └── templates/
274
307
  ├── skills/
275
308
  │ ├── alab-experiment-worker/
276
309
  │ ├── alab-project-controller/
@@ -285,6 +318,8 @@ ALab V1 is a local collaboration boundary, not a multi-user security product:
285
318
  │ └── test_runner_skydiscover.py
286
319
  ├── LICENSE
287
320
  ├── .env.example
321
+ ├── CHANGELOG.md
322
+ ├── CHANGELOG_cn.md
288
323
  ├── pyproject.toml
289
324
  ├── uv.lock
290
325
  ├── README.md
@@ -297,10 +332,12 @@ Local-only agent notes such as `AGENTS.md` and `CORE.md` are intentionally git-i
297
332
 
298
333
  - English documentation is canonical.
299
334
  - Synchronized Chinese documents use the `*_cn.md` naming pattern.
335
+ - [docs/README.md](docs/README.md) explains the documentation structure and reading order.
300
336
  - [docs/blueprint.md](docs/blueprint.md) is the V1 product overview.
301
- - [docs/spec_cli.md](docs/spec_cli.md), [docs/spec_storage_auth_context.md](docs/spec_storage_auth_context.md), [docs/spec_project_source_experiment.md](docs/spec_project_source_experiment.md), [docs/spec_lifecycle.md](docs/spec_lifecycle.md), [docs/spec_runners_adapters.md](docs/spec_runners_adapters.md), [docs/spec_observe_collaboration.md](docs/spec_observe_collaboration.md), and [docs/spec_tests.md](docs/spec_tests.md) define subsystem contracts.
337
+ - [docs/spec_cli.md](docs/spec_cli.md), [docs/spec_storage_auth_context.md](docs/spec_storage_auth_context.md), [docs/spec_project_source_experiment.md](docs/spec_project_source_experiment.md), [docs/spec_lifecycle.md](docs/spec_lifecycle.md), [docs/spec_runners_adapters.md](docs/spec_runners_adapters.md), [docs/spec_observe_collaboration.md](docs/spec_observe_collaboration.md), [docs/spec_dashboard.md](docs/spec_dashboard.md), and [docs/spec_tests.md](docs/spec_tests.md) define subsystem contracts.
302
338
  - [docs/progress.md](docs/progress.md), [docs/progress_pipeline.md](docs/progress_pipeline.md), [docs/progress_closed_gaps.md](docs/progress_closed_gaps.md), and [docs/progress_log.md](docs/progress_log.md) track current state, active queues, closed gaps, and history.
303
339
  - [docs/completion_audit.md](docs/completion_audit.md) tracks requirement-level evidence.
340
+ - [CHANGELOG.md](CHANGELOG.md) records release-facing changes and is used by CI for GitHub Release notes.
304
341
 
305
342
  ## Contributing
306
343
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "alab-cli"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  description = "Local agent-first experiment workbench CLI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -22,6 +22,7 @@ dependencies = [
22
22
  Homepage = "https://github.com/bebetterest/ALab"
23
23
  Repository = "https://github.com/bebetterest/ALab"
24
24
  Issues = "https://github.com/bebetterest/ALab/issues"
25
+ Changelog = "https://github.com/bebetterest/ALab/blob/main/CHANGELOG.md"
25
26
 
26
27
  [project.scripts]
27
28
  alab = "alab.cli:main"
@@ -36,7 +37,7 @@ dev = [
36
37
  package = true
37
38
 
38
39
  [tool.setuptools.package-data]
39
- alab = ["migrations/*.sql"]
40
+ alab = ["migrations/*.sql", "dashboard_static/*", "dashboard_static/vendor/*"]
40
41
 
41
42
  [tool.pytest.ini_options]
42
43
  testpaths = ["tests"]
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.1.0"
5
+ __version__ = "0.1.2"
@@ -16,7 +16,7 @@ from .errors import AlabError, error_exit_code
16
16
  from .home import resolve_home
17
17
  from .registry import COMMANDS, CommandSpec, match_command
18
18
  from .rendering import ResultBlock, error_block, render_text
19
- from .services import GlobalOptions, Request
19
+ from .services import GlobalOptions, LongRunningResult, Request
20
20
 
21
21
 
22
22
  @dataclass
@@ -48,6 +48,7 @@ GLOBAL_PUBLIC: set[PathTuple] = {
48
48
  ("config", "validate"),
49
49
  ("context", "show"),
50
50
  ("context", "repair"),
51
+ ("feedback",),
51
52
  }
52
53
 
53
54
  GLOBAL_CONFIG_REPAIR: set[PathTuple] = {
@@ -56,6 +57,7 @@ GLOBAL_CONFIG_REPAIR: set[PathTuple] = {
56
57
  ("config", "set"),
57
58
  ("config", "reset"),
58
59
  ("config", "validate"),
60
+ ("feedback",),
59
61
  }
60
62
 
61
63
  PUBLIC_PROJECT: set[PathTuple] = {
@@ -86,6 +88,7 @@ OBSERVE_READ: set[PathTuple] = {
86
88
  ("exp", "search"),
87
89
  ("exp", "show"),
88
90
  ("exp", "best"),
91
+ ("report",),
89
92
  ("observe", "experiments", "list"),
90
93
  ("observe", "experiments", "search"),
91
94
  ("observe", "experiments", "show"),
@@ -586,7 +589,13 @@ def run(argv: list[str]) -> int:
586
589
  enforce_global_config_valid(spec.path, base_req)
587
590
  req = build_request(parsed)
588
591
  preflight(spec, req, rest)
589
- blocks = spec.handler(rest, req)
592
+ result = spec.handler(rest, req)
593
+ if isinstance(result, LongRunningResult):
594
+ blocks = _with_context_token_warnings(req, result.blocks)
595
+ sys.stdout.write(render_text(blocks))
596
+ sys.stdout.flush()
597
+ return result.run()
598
+ blocks = result
590
599
  blocks = _with_context_token_warnings(req, blocks)
591
600
  sys.stdout.write(render_text(blocks))
592
601
  return infer_result_exit_code(blocks)