chore(cli-rename): replace stale da verbs in active code paths

Bring admin UI, audit-log messages, code comments, and analyst-facing
skill docs in line with the post-bootstrap CLI surface (`agnes pull`,
`agnes push`, `agnes init`, `agnes snapshot create`). The legacy
`_LEGACY_STRINGS` detection tuple in `app/api/claude_md.py` and the hook
upgrade markers in `cli/lib/hooks.py` are intentionally left as-is —
they exist precisely to flag pre-rewrite content for re-authoring.

Strip "(folded from `da metrics list`)" / "(lifted from `da metrics
show`)" / "Replaces the old `da analyst status`" docstring noise — the
rename history is in CHANGELOG.md, not in module docstrings.
This commit is contained in:
ZdenekSrotyr 2026-05-04 21:10:43 +02:00
parent 500db8cd3c
commit 103efb69f0
15 changed files with 21 additions and 22 deletions

View file

@ -2463,7 +2463,7 @@ async def unregister_table(
For materialized rows, also removes the canonical parquet at
`${DATA_DIR}/extracts/<source_type>/data/<id>.parquet` and clears
the matching `sync_state` row. Without these two cleanups, the
manifest endpoint kept advertising the dropped table to `da sync`
manifest endpoint kept advertising the dropped table to `agnes pull`
(sync_state-driven) and the orchestrator's next rebuild could
resurrect a master view from the leftover parquet (E2E sub-agent
finding 2026-05-01).
@ -2515,7 +2515,7 @@ async def unregister_table(
# Clear sync_state for any source/mode (a row that was synced at any
# point — local/materialized — has a sync_state entry that the manifest
# serves regardless of registry state). Pre-fix, the manifest still
# advertised the dropped table to `da sync` because sync_state was
# advertised the dropped table to `agnes pull` because sync_state was
# never cleaned up, and analysts kept getting it through the manifest.
try:
conn.execute("DELETE FROM sync_state WHERE table_id = ?", [name])
@ -2523,7 +2523,7 @@ async def unregister_table(
except Exception as e:
logger.warning(
"Failed to clear sync_state for unregistered table %s: %s"
"manifest may still advertise the dropped row to da sync",
"manifest may still advertise the dropped row to agnes pull",
table_id, e,
)

View file

@ -119,7 +119,7 @@ async def get_welcome(
):
"""Return the rendered CLAUDE.md for the authenticated analyst.
The CLI calls this endpoint during ``da analyst setup`` to write
The CLI calls this endpoint during ``agnes init`` to write
``<workspace>/CLAUDE.md``. The content is RBAC-filtered per the
calling user.

View file

@ -59,7 +59,7 @@ def _run_materialized_pass(conn: duckdb.DuckDBPyConnection, bq) -> dict:
that are due, dispatching by ``source_type`` to the correct connector's
materialize_query. Honors per-table `sync_schedule` via `is_table_due()`,
computes the file hash inline, and updates `sync_state` so the manifest
can serve the row to `da sync` without re-hashing on every request.
can serve the row to `agnes pull` without re-hashing on every request.
BigQuery rows go through BqAccess + bigquery_query() (jobs API),
optionally cost-guarded by ``max_bytes_per_materialize``.

View file

@ -1197,7 +1197,7 @@
<textarea class="form-textarea" id="kbSourceQuery" rows="8"></textarea>
<div class="form-hint">SELECT against <code>kbc."bucket"."table"</code>.
Result is materialized to parquet and distributed via
<code>da sync</code>.</div>
<code>agnes pull</code>.</div>
</div>
<div class="form-group">
@ -2404,7 +2404,7 @@
if (_editOriginalQueryMode === 'materialized' && newMode === 'remote') {
msg = '⚠ Switching Synced locally → Live from BigQuery will drop the materialized parquet on the next sync. Analysts who already pulled this table will start getting live BQ queries instead of a local copy; the sync schedule becomes ignored.';
} else {
msg = '⚠ Switching Live from BigQuery → Synced locally: the next scheduled sync runs a SELECT and writes a parquet. Analysts will start reading the local copy on their next `da sync`. Remember to set a sync schedule.';
msg = '⚠ Switching Live from BigQuery → Synced locally: the next scheduled sync runs a SELECT and writes a parquet. Analysts will start reading the local copy on their next `agnes pull`. Remember to set a sync schedule.';
}
warn.textContent = msg;
warn.style.display = '';

View file

@ -234,7 +234,7 @@
<p class="welcome-desc">
<strong>Default:</strong> a rich markdown briefing about Agnes commands, registered tables
(RBAC-filtered for the calling analyst), available metrics, and marketplace plugins.
Written to <code>CLAUDE.md</code> in the analyst workspace at <code>da analyst setup</code> time.
Written to <code>CLAUDE.md</code> in the analyst workspace at <code>agnes init</code> time.
Use <code>--no-claude-md</code> to skip writing it.
</p>
<p class="welcome-desc">

View file

@ -61,7 +61,7 @@ def catalog(
def _list_metrics(as_json: bool, category: Optional[str] = None) -> None:
"""List metric definitions from the server (lifted from `da metrics list`)."""
"""List metric definitions from the server."""
params = {}
if category:
params["category"] = category
@ -99,7 +99,7 @@ def _list_metrics(as_json: bool, category: Optional[str] = None) -> None:
def _show_one_metric(metric_id: str, as_json: bool) -> None:
"""Show details for a single metric (lifted from `da metrics show`)."""
"""Show details for a single metric."""
resp = api_get(f"/api/metrics/{metric_id}")
if resp.status_code == 404:
typer.echo(f"Metric not found: {metric_id}", err=True)

View file

@ -34,7 +34,7 @@ def disk_info(
used = sum(p.stat().st_size for p in snap_dir.rglob("*") if p.is_file()) if snap_dir.exists() else 0
count = len(list(snap_dir.glob("*.parquet"))) if snap_dir.exists() else 0
# Fall back to the user's local dir for free-space stats when the
# snapshot dir doesn't exist yet (first run, before any `da fetch`).
# snapshot dir doesn't exist yet (first run, before any `agnes snapshot create`).
# `0` would misleadingly suggest the disk is full.
free = shutil.disk_usage(snap_dir if snap_dir.exists() else _local_dir()).free
quota_gb = int(os.environ.get("AGNES_SNAPSHOT_QUOTA_GB", "10"))

View file

@ -101,7 +101,7 @@ def pull(
# Claude Code's stdout stays clean. Errors still flow to stderr so
# the user sees them in their terminal even when the hook redirects
# `2>/dev/null` (the hook explicitly forwards stderr too in the
# canonical `da analyst setup` template).
# canonical `agnes init` template).
if result.errors:
for e in result.errors:
typer.echo(f"warn: {e}", err=True)

View file

@ -1,8 +1,7 @@
"""`agnes status` — workspace status: initialized? data fresh? hooks active?
Replaces the old `da analyst status` command. The previous server-health
content (which used to live here) has moved to `agnes diagnose system`
under the existing `agnes diagnose` group (Task 13).
Server-health checks live under `agnes diagnose system` (see the
`agnes diagnose` group).
"""
from __future__ import annotations

View file

@ -3,7 +3,7 @@
Three CLI paths surface BigQuery / guardrail / RBAC typed errors today:
- ``agnes query --remote`` (POST /api/query)
- ``agnes query --register-bq`` (RemoteQueryEngine wrapping BqAccessError)
- ``da fetch`` / ``agnes schema`` etc. (cli.v2_client wrappers around v2 endpoints)
- ``agnes snapshot create`` / ``agnes schema`` etc. (cli.v2_client wrappers around v2 endpoints)
All three previously flattened the structured ``detail`` JSON to a
truncated single-line string, hiding the operator-facing hint that

View file

@ -6,7 +6,7 @@ and makes it available to everyone through a curated catalog.
## How It Works
1. Analysts write insights in their CLAUDE.local.md
2. `da sync --upload-only` pushes content to server
2. `agnes push` uploads sessions and CLAUDE.local.md to the server
3. Server processes with LLM (Haiku) to extract knowledge items
4. Items go through governance (pending → approved/mandatory)
5. Approved items are distributed as Claude rules

View file

@ -18,9 +18,9 @@ agnes diagnose --json
3. Re-generate token: `agnes login --email your@email.com`
### DuckDB errors locally
1. Re-sync: `da sync` (rebuilds views)
1. Re-sync: `agnes pull` (rebuilds views)
2. Check disk space: `du -sh user/duckdb/`
3. Delete and re-create: `rm user/duckdb/analytics.duckdb && da sync`
3. Delete and re-create: `rm user/duckdb/analytics.duckdb && agnes pull`
### Server unresponsive
1. `docker compose ps` — check container status

View file

@ -80,7 +80,7 @@ def delete_snapshot(snap_dir: Path, name: str) -> bool:
def snapshot_lock(snap_dir: Path):
"""Exclusive flock on snap_dir/.lock — serializes snapshot installs.
Concurrent `da fetch` invocations queue here.
Concurrent `agnes snapshot create` invocations queue here.
"""
if _fcntl is None:
raise RuntimeError(

View file

@ -956,7 +956,7 @@ _V16_TO_V17_MIGRATIONS = [
# v19 -> v20: source_query column backs query_mode='materialized' for BigQuery.
# Admin-registered SQL stored verbatim; scheduler runs it through the DuckDB BQ
# extension (via BqAccess) and writes the result to
# /data/extracts/bigquery/data/<id>.parquet so the existing manifest + da sync
# /data/extracts/bigquery/data/<id>.parquet so the existing manifest + agnes pull
# flow distributes it to analysts. NULL on existing rows.
_V19_TO_V20_MIGRATIONS = [
"ALTER TABLE table_registry ADD COLUMN IF NOT EXISTS source_query TEXT",

View file

@ -92,7 +92,7 @@ class SyncStateRepository:
doesn't claim a sync happened. Existing rows keep their last
successful `last_sync` / `rows` / `hash` fields only `status` and
`error` flip so analysts who already pulled the prior good
parquet via `da sync` keep serving from it while the operator fixes
parquet via `agnes pull` keep serving from it while the operator fixes
the source.
"""
self.conn.execute(