Skip to content

Add elmo lab CLI commands for one-off AEO runs#362

Open
jrhizor wants to merge 3 commits into
mainfrom
cli-expansion-ifyk0
Open

Add elmo lab CLI commands for one-off AEO runs#362
jrhizor wants to merge 3 commits into
mainfrom
cli-expansion-ifyk0

Conversation

@jrhizor

@jrhizor jrhizor commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

What

Expands the Elmo CLI from deployment management into a one-off AEO toolkit. New elmo lab command group exposes Elmo's core analysis as DB-free one-off runs that reuse the providers/keys configured by elmo init (~/.elmo/.env). Commands are ordered by the workflow you'd actually run:

elmo lab brainstorm <website>   # generate tracking prompts + competitors
elmo lab eval [prompts]         # run prompts → responses, citations, mentions, share-of-voice, fan-out
elmo lab plan <paths...>        # AEO recommendations from your content (+ a prior eval)

Highlights

  • brainstormanalyzeBrand() → suggested prompts + competitors, written as a pipeable brand.json "brand pack".
  • eval — runs each prompt × target × N replications via provider.run(). Captures responses (Markdown), citations, brand/competitor mentions, share-of-voice (reusing report-metrics), and query fan-out (a byproduct of each web-search run — no separate command). Writes a directory tree plus a self-contained, offline index.html report you can double-click to browse everything.
  • plan — feeds your files/dirs (and optionally a prior eval) to a structured AEO prompt → prioritized recommendations + competitors, written back into an augmented brand.json.
  • Shared conventions: model:provider[:version][:online] targeting, repeatable -m for multi-provider, -o/--format csv|jsonl/--stdout, default output to the current directory.

Notable refactors

  • Extracted the worker's duplicated analyzeMentions into @workspace/lib/mentions so day-to-day tracking, reports, and the CLI share one mention implementation.
  • Split the deploy commands (init/compose/edit) into deploy.ts; index.ts is now thin wiring that also registers the lab group.
  • CLI bundles @workspace/lib (LLM SDKs externalized). Verified the bundle has 0 drizzle/pg inlined — truly DB-free, never reads DATABASE_URL.

Docs

New guide at user-guide/cli-lab.mdx walking init → brainstorm → eval → plan with copy-paste examples; validated via the apps/www build.

Testing

  • check-types green for cli/lib/worker; CLI bundle builds (DB-free verified).
  • 26 CLI unit tests + 6 new lib mentions tests (CSV/JSONL, slug, multi--m target resolution, brand-pack round-trip, mention detection, and a self-contained HTML-report test that also asserts active-content sanitization). Full lib suite (187) passes.
  • Biome + knip clean.
  • Provider-calling paths were not run here (they hit billed LLM keys); they're for the author to exercise.

Expose Elmo's core analysis as one-off, DB-free CLI commands that reuse the
providers configured by `elmo init`:

- `elmo lab brainstorm <website>` — generate tracking prompts + competitors
- `elmo lab eval [prompts]` — run prompts across providers → responses,
  citations, mentions, share-of-voice, and query fan-out, plus a
  self-contained index.html report
- `elmo lab plan <paths...>` — AEO recommendations from your content,
  optionally grounded in a prior eval

Commands share a pipeable brand-pack artifact, `model:provider[:version][:online]`
targeting (repeatable for multi-provider), and `--output`/`--format`/`--stdout`.

Refactors: split deploy commands into deploy.ts with index.ts as thin wiring;
extract the worker's duplicated analyzeMentions into @workspace/lib/mentions so
tracking, reports, and the CLI share one implementation. Bundles @workspace/lib
into the CLI (LLM SDKs externalized; no DB). Adds a docs guide and unit tests.
@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
elmo Ready Ready Preview, Comment Jun 16, 2026 10:39pm

Request Review

Comment thread apps/cli/src/core/report-html.ts Fixed
Comment thread apps/cli/src/core/report-html.ts Fixed
Comment thread apps/cli/src/core/report-html.ts Fixed
Comment thread apps/cli/src/core/report-html.ts Fixed
…brand flags

- eval clears its `responses/` tree before writing so re-runs (fewer
  runs/targets or an edited prompt's new slug) can't leave orphaned markdown
  that's inconsistent with the regenerated report
- csvCell prefixes formula-injection-prone text cells (=, +, -, @, …) with `'`;
  numbers/booleans (incl. negatives) emitted verbatim
- eval warns when --brand-domain/--alias are passed without a resolvable brand
- content-gap input now explicitly excludes brand-less runs
Replace the regex-based HTML sanitizer (flagged by CodeQL as incomplete
multi-character sanitization and incomplete URL scheme check) with a marked
renderer that escapes raw HTML to inert text — so only marked's own element set
is emitted — and an href allowlist that strips control chars and permits only
http(s)/mailto/relative/anchor targets (javascript:, data:, vbscript:, … become
`#`). No more bypassable regex stripping of `<script>` / `javascript:`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants