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

View file

@ -119,7 +119,7 @@ async def get_welcome(
): ):
"""Return the rendered CLAUDE.md for the authenticated analyst. """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 ``<workspace>/CLAUDE.md``. The content is RBAC-filtered per the
calling user. 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 that are due, dispatching by ``source_type`` to the correct connector's
materialize_query. Honors per-table `sync_schedule` via `is_table_due()`, materialize_query. Honors per-table `sync_schedule` via `is_table_due()`,
computes the file hash inline, and updates `sync_state` so the manifest 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), BigQuery rows go through BqAccess + bigquery_query() (jobs API),
optionally cost-guarded by ``max_bytes_per_materialize``. optionally cost-guarded by ``max_bytes_per_materialize``.

View file

@ -1197,7 +1197,7 @@
<textarea class="form-textarea" id="kbSourceQuery" rows="8"></textarea> <textarea class="form-textarea" id="kbSourceQuery" rows="8"></textarea>
<div class="form-hint">SELECT against <code>kbc."bucket"."table"</code>. <div class="form-hint">SELECT against <code>kbc."bucket"."table"</code>.
Result is materialized to parquet and distributed via Result is materialized to parquet and distributed via
<code>da sync</code>.</div> <code>agnes pull</code>.</div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -2404,7 +2404,7 @@
if (_editOriginalQueryMode === 'materialized' && newMode === 'remote') { 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.'; 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 { } 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.textContent = msg;
warn.style.display = ''; warn.style.display = '';

View file

@ -234,7 +234,7 @@
<p class="welcome-desc"> <p class="welcome-desc">
<strong>Default:</strong> a rich markdown briefing about Agnes commands, registered tables <strong>Default:</strong> a rich markdown briefing about Agnes commands, registered tables
(RBAC-filtered for the calling analyst), available metrics, and marketplace plugins. (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. Use <code>--no-claude-md</code> to skip writing it.
</p> </p>
<p class="welcome-desc"> <p class="welcome-desc">

View file

@ -61,7 +61,7 @@ def catalog(
def _list_metrics(as_json: bool, category: Optional[str] = None) -> None: 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 = {} params = {}
if category: if category:
params["category"] = 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: 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}") resp = api_get(f"/api/metrics/{metric_id}")
if resp.status_code == 404: if resp.status_code == 404:
typer.echo(f"Metric not found: {metric_id}", err=True) 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 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 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 # 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. # `0` would misleadingly suggest the disk is full.
free = shutil.disk_usage(snap_dir if snap_dir.exists() else _local_dir()).free 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")) 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 # Claude Code's stdout stays clean. Errors still flow to stderr so
# the user sees them in their terminal even when the hook redirects # the user sees them in their terminal even when the hook redirects
# `2>/dev/null` (the hook explicitly forwards stderr too in the # `2>/dev/null` (the hook explicitly forwards stderr too in the
# canonical `da analyst setup` template). # canonical `agnes init` template).
if result.errors: if result.errors:
for e in result.errors: for e in result.errors:
typer.echo(f"warn: {e}", err=True) typer.echo(f"warn: {e}", err=True)

View file

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

View file

@ -3,7 +3,7 @@
Three CLI paths surface BigQuery / guardrail / RBAC typed errors today: Three CLI paths surface BigQuery / guardrail / RBAC typed errors today:
- ``agnes query --remote`` (POST /api/query) - ``agnes query --remote`` (POST /api/query)
- ``agnes query --register-bq`` (RemoteQueryEngine wrapping BqAccessError) - ``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 All three previously flattened the structured ``detail`` JSON to a
truncated single-line string, hiding the operator-facing hint that 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 ## How It Works
1. Analysts write insights in their CLAUDE.local.md 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 3. Server processes with LLM (Haiku) to extract knowledge items
4. Items go through governance (pending → approved/mandatory) 4. Items go through governance (pending → approved/mandatory)
5. Approved items are distributed as Claude rules 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` 3. Re-generate token: `agnes login --email your@email.com`
### DuckDB errors locally ### 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/` 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 ### Server unresponsive
1. `docker compose ps` — check container status 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): def snapshot_lock(snap_dir: Path):
"""Exclusive flock on snap_dir/.lock — serializes snapshot installs. """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: if _fcntl is None:
raise RuntimeError( raise RuntimeError(

View file

@ -956,7 +956,7 @@ _V16_TO_V17_MIGRATIONS = [
# v19 -> v20: source_query column backs query_mode='materialized' for BigQuery. # v19 -> v20: source_query column backs query_mode='materialized' for BigQuery.
# Admin-registered SQL stored verbatim; scheduler runs it through the DuckDB BQ # Admin-registered SQL stored verbatim; scheduler runs it through the DuckDB BQ
# extension (via BqAccess) and writes the result to # 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. # flow distributes it to analysts. NULL on existing rows.
_V19_TO_V20_MIGRATIONS = [ _V19_TO_V20_MIGRATIONS = [
"ALTER TABLE table_registry ADD COLUMN IF NOT EXISTS source_query TEXT", "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 doesn't claim a sync happened. Existing rows keep their last
successful `last_sync` / `rows` / `hash` fields only `status` and successful `last_sync` / `rows` / `hash` fields only `status` and
`error` flip so analysts who already pulled the prior good `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. the source.
""" """
self.conn.execute( self.conn.execute(