npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@somarc/da-cli

v0.4.5

Published

Agentic-first CLI for Adobe Edge Delivery Services via DA Admin API

Readme

da-cli

Agentic-first CLI for Adobe Edge Delivery Services via the DA Admin API.

npm version npm downloads CI License

npm install -g @somarc/da-cli

Requires Node >= 18. Zero npm runtime dependencies beyond commander and js-yaml.

Package: npm · Releases: GitHub Releases · Changelog: CHANGELOG.md · Security: SECURITY.md

For agent-specific operating guidance, see AGENTS.md. For the user-facing command reference, keep this README as the source of truth and mirror material changes into AGENTS.md.


Quick start

# 1. Authenticate
da auth login

# 2. Set project context (or pass --org / --repo flags each time)
da config init          # interactive setup, writes .da.json in current directory

# 3. List content
da content list /

# 4. Serve the current repo locally for browser/agent verification
da up --format json

Resolve Targets For Agents

Use da resolve when an agent has a URL/path and needs the canonical DA target before reading, writing, previewing, publishing, or running a pipeline.

da resolve https://main--site--owner.aem.page/about --format json
da --org owner --repo site resolve /about --branch main --format json

The JSON response includes resolved.confidence (high, medium, low, or none) and a next array of executable da commands. next is intentionally command-oriented so agents and pipeline runners do not have to interpret prose.

Agent-oriented JSON responses use a shared envelope: ok, operation, target, resolved, data, changes, warnings, errors, next, and artifacts. next entries are always runnable da commands with a real subcommand, never prose.

Check local agent readiness without mutating auth, config, or remote state:

da --format json status
da --format json status https://main--site--owner.aem.page/about

Global flags

These flags apply to every command and are resolved before any subcommand runs.

| Flag | Description | |------|-------------| | --org <org> | DA org (overrides .da.json and ~/.da/config.json) | | --repo <repo> | DA repo | | --env <env> | DA Admin API environment. Use prod unless intentionally testing DA internals. | | --format <fmt> | Output format: table | json | md (default: table) | | --log-level <level> | Log level: silent | error | warn | info | debug (default: info) | | --log-file <file> | Append logs to a file instead of stderr | | --request-id <id> | Request correlation ID sent as x-request-id to DA/Helix admin APIs | | --dry-run | Show what would happen without mutating (default for write operations) | | --commit | Execute mutations (required to override dry-run on all write operations) | | --quiet | Suppress progress output, print only results | | --verbose | Print full request/response details |

Notes:

  • Root --env selects the DA Admin API host, not an Edge Delivery Services preview/live target. The supported public/default value is prod, which talks to https://admin.da.live.
  • stage and dev currently both point at https://stage-admin.da.live; treat them as advanced/internal DA API testing values, not normal project environments.
  • EDS preview/live is expressed by the rendered host: aem.page for preview/pre-production and aem.live for live production.
  • EDS branch subdomains isolate code delivery, not DA source content. A URL like feature--repo--owner.aem.page uses the feature code branch, but DA-authored documents are shared for the repo.
  • da index validate and da index query accept --target preview|live for the EDS query host. Their old subcommand-local --env preview|live remains as a backward-compatible alias.
  • For write operations, prefer passing root flags before the subcommand, for example: da --commit publish page /index.

Branches And Draft Content

For an established site, avoid using canonical DA paths such as /nav.html or /products/foo.html for experiments that should not appear on main. Use branches for code changes and draft-scoped paths for content changes:

da --commit content put /products/foo.html content/products/foo.html --draft
da --commit preview page /products/foo.html --branch feature/foo --draft --yes
da audit full /products/foo --branch feature/foo --draft --format json

--draft maps paths under /drafts by default, so /products/foo.html becomes /drafts/products/foo.html and renders at https://feature-foo--repo--owner.aem.page/drafts/products/foo. Use --draft-prefix <path> when a project uses another draft namespace. If a draft page needs experimental navigation, author /drafts/nav.html and set page metadata Nav to /drafts/nav; do not edit canonical /nav.html until the content is ready for the main site.

Operator Roadmap

da-cli is being hardened as a local operator and agent execution harness for DA/Edge Delivery workflows. The current roadmap slices are:

  1. Commerce-native ingestion and inspection.
  2. Durable local jobs for large tree operations.
  3. Retry/backoff and resumability for transient pipeline failures.
  4. Job observability: progress summaries and task-level inspection.
  5. Detached execution: start a worker, return the job id, and let agents watch/report without babysitting the process.
  6. Publish jobs that can promote only successfully previewed paths.
  7. First-class site model: org, repo, branch, delivery hosts, DA source, codebus, and route ownership.
  8. Stable JSON/schema contracts for machine and agent consumers.
  9. OpenAPI-first public contract for command outputs and local operator surfaces where a formal API shape exists.
  10. Route registry discipline: centralize command/route ownership, mutation class, capability requirements, and safety gates in reviewable code instead of scattering that logic.

0.4.4 Hardening Candidates

The next cleanup pass should stay feature-light and focus on the remaining architecture seams:

  • Complete shared agent-envelope adoption beyond resolve and status.
  • Consolidate remaining EDS HTML extraction/parsing helpers into a dedicated lib/eds-html.js layer.
  • Add live publish freshness reporting, either by extending preview status or adding publish status, so operators can compare source, preview, and live Last-Modified values and get a clear previewFreshness/liveFreshness verdict.
  • Evaluate a command executor abstraction for safety preflight, API error handling, and write-command boilerplate.
  • Continue shrinking the largest modules (site, stardust, and pipeline-runner) only where the extraction creates clearer ownership or stronger tests.

Virtuous Pipeline Flywheel

The pipeline YAML library should grow from real DA/EDS field runs. Each operator pass produces two useful artifacts: a repeatable graph that worked, and a friction record for what was missing or too manual.

That creates the flywheel:

  1. Run a real workflow against a real site.
  2. Capture the successful command graph as reusable pipeline YAML.
  3. Record frictions as concrete missing primitives, diagnostics, or safer defaults.
  4. Promote recurring fixes into commands, contracts, schemas, or pipeline templates.
  5. Re-run the improved graph and let the next field pass sharpen it again.

The goal is not a pile of one-off scripts. The goal is accumulated operational judgment encoded as inspectable, resumable, agent-friendly graphs.

Operator Contracts

Machine-facing output contracts live under docs/schemas/, and the local operator surface is described OpenAPI-first in docs/openapi/api.yaml. The initial stable contracts cover da site model, da site freshness, job summaries, job listing, job inspection, and preview-job promotion.

Command-family ownership, mutation class, target dependency, and commit requirements are centralized in src/lib/route-registry.js. Pipeline validation consumes that registry instead of carrying its own independent command allowlist.

Large Tree Operations

AEM preview and live publish tree operations are naturally asynchronous at site scale. Large catalogs can contain hundreds or thousands of pages, and admin.hlx.page can respond slowly or rate-limit bursty tree mutations.

preview tree can create a durable local job checkpoint for large trees:

da preview tree / --commit --yes --job
da preview tree / --commit --yes --job --run
da job watch <job-id>
da job start <job-id>
da job run <job-id>

The job contract tracks per-path state in .da/jobs/, supports resume after interruption, and returns structured progress for agents. Preview and publish jobs retry transient failures such as 429, timeouts, and 5xx responses with bounded backoff. Detached workers write logs beside the checkpoint as .da/jobs/<job-id>.log, so the foreground agent can retain the job id and watch only meaningful state changes.

Request Signature

da-cli does not send background telemetry. Requests that the user explicitly initiates against DA Admin or Helix Admin include a lightweight CLI signature so server-side logs can distinguish tool usage:

  • User-Agent: browser-compatible user agent with a trailing da-cli/<version> token
  • x-da-cli-version: CLI package version
  • x-da-cli-command: command path such as content.list or preview.page
  • x-da-cli-runtime: Node.js version and OS/CPU pair

The signature does not include org, repo, branch, URL, local path, content, token values, or machine identifiers.


Configuration

.env files are loaded automatically by searching upward from the current directory. DA_* and AEM_* environment variables are supported for the common root options.

Config is resolved in this precedence order (highest wins):

per-command overrides  >  CLI flags  >  DA_*/AEM_* environment  >  project .da.json  >  ~/.da/config.json  >  defaults

In addition to org, repo, and env, config may also include branch. Commands that support --branch use that as the default when the flag is omitted. Keep env unset or set to prod for normal use. Environment equivalents are DA_ORG/AEM_ORG, DA_REPO/AEM_REPO, DA_ENV/AEM_ENV, DA_BRANCH/AEM_BRANCH, plus DA_FORMAT, DA_LOG_LEVEL, DA_LOG_FILE, and DA_REQUEST_ID.

da config init

Interactive setup — prompts for org, repo, and optional DA Admin API environment, then writes to .da.json in the current directory.

da config init           # project .da.json
da config init --global  # ~/.da/config.json

da config get <key>

Print a single resolved config value.

da config get org

da config set <key> <value>

Write a key to project or global config.

da config set repo my-site
da config set org my-org --global
da config set branch feature/my-work

da config show

Print full resolved config with source annotation (flag / project / global / default).

da config show
da config show --format json

Authentication

Tokens are cached at ~/.aem/da-token.json.

da auth login

Obtain and cache a Bearer token. Requires npx (bundled with Node) to invoke github:adobe-rnd/da-auth-helper, which is fetched on first login.

da auth login            # uses cached token if still valid
da auth login --refresh  # force re-auth

da auth logout

Remove the cached token.

da auth status

Show token validity and time remaining.

da auth status
# valid  expires 5/15/2026, 2:30:00 PM  (~47 min remaining)

da auth token

Print the raw Bearer token to stdout — useful for piping to curl or populating env vars.

export TOKEN=$(da auth token)
curl -H "Authorization: Bearer $TOKEN" https://admin.da.live/list/myorg/myrepo

Local server

da up

Run an agent-friendly proxied rendering surface for the current repository.

da up
da up --port 3000 --fallback preview
da up --content content --fallback live
da up --fallback none --format json

Resolution order:

  1. Local code files from --root (default: current directory)
  2. Local DA content workspace from --content (default: content/, when present)
  3. Remote fallback to the configured EDS preview or live host

The server does not open a browser by default. It prints a readiness object with status, url, source roots, fallback, and source priority. Use --format json when another tool or agent needs to start the server and parse the URL.

da up is not intended to clone the official aem up human development server. Its purpose is to give agents a deterministic local/proxied surface for execution decisions: which file or fallback served a route, whether local content wins, whether generated fixtures are reachable, and what URL should be probed next. For full human visual preview, screenshots, live reload, TLS, and browser ergonomics, use the official AEM CLI alongside da-cli.

Local content lookup mirrors common EDS author URLs. For example, /products/comfort-devices, /products/comfort-devices/, and /products/comfort-devices/index can all resolve to content/products/comfort-devices/index.html when that file exists.

Options:

| Flag | Description | |------|-------------| | --port <port> | Port to listen on (default: 3000) | | --host <host> | Host to bind (default: 127.0.0.1) | | --root <dir> | Code repository root to serve (default: .) | | --content <dir> | Local DA content workspace directory (default: content) | | --no-content | Disable local content workspace lookup | | --fallback <mode> | Missing-file fallback: preview, live, or none (default: preview) | | --branch <branch> | EDS branch for preview/live fallback |


Commerce

Commerce has two explicit modes:

  • Fixture-backed DA content for local prototyping and stress testing.
  • Product Bus ingestion for structured catalog records at https://api.adobecommerce.live/{org}/sites/{site}/catalog/*.

Use da commerce fixture ... when you want the fixture scope to be explicit. da commerce inspect and da commerce scaffold are also available as shorthand forms.

Use da commerce product-bus ... when DA should be an optional editorial overlay and Product Bus should be the product source of truth.

da commerce fixture inspect <source>

Inspect demo-style product category sheets stored as index.json files.

da commerce fixture inspect content/products
da commerce fixture inspect content/products --format json

The inspector validates that each product row includes the minimum fields needed by the starter product grid: sku, url, title, price, and image. It also reports the product-grid search contract so agents can confirm the client-side inventory controls have data to work with: search fields are sku, title, category, and summary, with category facet counts included in JSON output.

da commerce fixture scaffold <outputDir>

Create a local fixture-backed catalog slice.

da commerce fixture scaffold content
da commerce fixture scaffold content --category-slug comfort-devices --category-title "Comfort Devices"
da commerce fixture scaffold content --static-json-dir .

The scaffold writes a category page, category index.json, and fictional PDP pages under the output directory. Use --static-json-dir . when the EDS block fetches JSON from the code/static surface at runtime, for example /products/comfort-devices/index.json. It refuses to overwrite existing files unless --force is passed.

da commerce product-bus plan <source>

Build and validate a Product Bus payload without mutating the remote catalog.

da --org somarc --repo fluffyjaws-medical commerce product-bus plan content/products/inventory/index.json --site fluffyjaws-medical --branch feature-commerce-catalog
da --org somarc --repo fluffyjaws-medical commerce product-bus plan content/products/inventory/index.json --site fluffyjaws-medical --branch feature-commerce-catalog --output product-bus-plan.json

The source may be a JSON array, { "products": [...] }, or DA sheet-style { "data": [...] }. Fixture rows with sku, url, title, price, image, category, and summary are normalized into Product Bus records with sku, name, path, url, urlKey, type, availability, description, metaTitle, metaDescription, images, price, and custom.

da commerce product-bus ingest <source>

Ingest structured product records into Product Bus. Like the rest of da-cli, this is dry-run by default and requires root --commit to mutate remote state.

export DA_COMMERCE_API_TOKEN=...
da --org somarc --repo fluffyjaws-medical --commit commerce product-bus ingest content/products/inventory/index.json --site fluffyjaws-medical --branch feature-commerce-catalog --yes

The command creates the Product Bus index route unless --no-index is passed, then posts catalog records in batches of 50 by default. Product Bus indexing is asynchronous, so generated index/feed surfaces can lag ingestion.

Auth resolution is explicit first, then convenient: --api-token, commerce token environment variables such as DA_COMMERCE_API_TOKEN, then the existing da auth token as a fallback. If Product Bus rejects the DA auth fallback with 401 or 403, provide a Product Bus token explicitly.

da commerce product-bus inspect <url>

Inspect a generated Product Bus index JSON URL after ingestion.

da commerce product-bus inspect https://feature-commerce-catalog--fluffyjaws-medical--somarc.aem.page/products/index.json

Content

CRUD operations on DA source documents.

EDS reads HTML source documents from .html paths. When uploading an HTML file to an extensionless path, da content put normalizes the DA path to .html because DA stores /path and /path.html as distinct documents.

da content list [path]

List documents and folders at a path (default: repo root).

da content list /
da content list /blog

da content tree [prefix]

Recursively list source documents under a prefix. This is useful when preparing an explicit path set for bulk preview or publish.

da content tree /
da content tree / --ext html
da content tree /blog --ext html --format json

da content sheets [prefix]

Discover DA sheet JSON documents, including form sheets under paths such as /forms/contact-us.json.

da content sheets /
da content sheets /forms --format json

This helps distinguish project-level/config-style sheets from page HTML when diagnosing sheet-backed blocks such as forms.

da content get <path>

Fetch a source document to stdout or a file.

da content get /index.html
da content get /blog/post.html -o post.html

da content put <path> <file>

Upload a document or binary asset. Dry-run by default — shows diff before writing for text/HTML uploads.

da content put /index.html ./index.html          # dry-run: shows diff
da --commit content put /index.html ./index.html # writes to DA
da --commit content put /index.html ./index.html --yes # accepted for consistency with bulk writes
da content put /media/hero.png ./hero.png        # dry-run: binary preflight

Warns if the HTML lacks a <main> wrapper — Helix extracts only content inside <main>, so an unwrapped document will render empty. Known binary asset extensions such as images, video, audio, PDF, fonts, and zip files are uploaded with their matching MIME type and skip text diff/HTML fragment checks. Local file uploads are contained to the current working tree by default. Use --allow-outside-worktree only when intentionally uploading an external file. Large text diffs are truncated so large JSON or generated HTML writes remain readable.

da content put-tree [dir]

Upload a local content tree to DA. This is the content-first site build primitive: author semantic DA documents locally, upload the tree, then preview the tree before generating or polishing blocks.

da content put-tree content                  # dry-run: prints mapped DA paths
da --org somarc --repo chronicle --commit content put-tree content         # uploads the tree
da --org somarc --repo chronicle --commit content put-tree content --prefix /drafts
da --commit content put-tree content --yes   # allow configured target after reviewing preflight

Path mapping is deterministic: content/index.html becomes /index.html, content/nav.html becomes /nav.html, and nested files preserve their folder structure. HTML files are normalized to .html DA paths so EDS preview reads the expected source document.

da content delete <path>

Delete a source document. Requires --commit.

da --commit content delete /old-page.html

da content move <src> <dst>

Move or rename a document. Requires --commit.

da --commit content move /old-name.html /new-name.html

da content copy <src> <dst>

Copy a document to a new path. Requires --commit.

da --commit content copy /template.html /new-page.html

da content versions <path>

List version history for a document.

da content versions /index.html

da content clone

Clone DA source documents into a local content/ workspace and write tracking state to .da/content-state.json.

da content clone --path /blog
da content clone --all
da content clone --path / --force

da content status

Show locally added, modified, and deleted files under content/.

da content status

da content diff [path]

Show a diff between local content/ files and the current remote DA source.

da content diff
da content diff /blog/post.html

da content add [files...]

Stage local workspace changes. With no files, stages all changed files.

da content add
da content add content/blog/post.html

da content commit

Record a local content commit for staged files.

da content commit -m "Update blog copy"

da content push

Push committed local workspace changes to DA. Dry-run by default; pass root --commit to write.

da content push
da --org somarc --repo chronicle --commit content push
da --commit content push --path /blog
da --commit content push --yes               # allow configured target after reviewing preflight

da content merge [path]

Refresh local workspace files from the current remote DA source.

da content merge
da content merge /blog/post.html

Preview

Triggers the EDS content pipeline. Updates *.aem.page only — use da publish to promote to *.aem.live.

Preview operations mutate remote *.aem.page pipeline state and require root --commit in 0.4.0. Read-only preview diagnostics such as preview status and preview explain do not require --commit.

Preview is a two-step operation:

  1. Flush the DA editor cache (admin.da.live/preview)
  2. Trigger the Helix content pipeline (admin.hlx.page/preview)

After a successful preview, da-cli fetches .plain.html and warns if the content pipeline returned empty content.

da preview page <path>

Preview a single page.

da --commit preview page /index
da --commit preview /index                            # shorthand for preview page /index
da --commit preview page /blog/post --branch feature-branch

da preview pages <source...>

Batch preview — accepts direct page paths, a local file of paths (one per line), or a DA path prefix (recursively lists all pages under it).

da --org somarc --repo chronicle --commit preview pages /blog                  # all pages under /blog
da --org somarc --repo chronicle --commit preview pages paths.txt              # file of newline-delimited paths
da --org somarc --repo chronicle --commit preview pages /one.html /two.html    # direct page paths
da --org somarc --repo chronicle --commit preview pages /blog --concurrency 10

da preview tree [prefix]

Preview every HTML source document under a DA prefix. This is the agent-friendly path for full-site preview because it includes shared documents such as /nav.html and /footer.html when they exist.

da --commit preview tree /
da --org somarc --repo chronicle --commit preview tree /docs --concurrency 10
da --commit preview tree / --verify   # fail if any .plain.html is empty or unreachable
da --commit preview tree / --job      # checkpoint under .da/jobs instead of foreground execution
da --commit preview tree / --job --run
da --commit preview tree / --job --max-attempts 5 --backoff-ms 2000

For very large subtrees, preview tree may supplement the DA listing with matching local content/ HTML paths when the remote listing appears capped. The preflight prints a note when that fallback adds paths; verify tail URLs after large previews.

When --job is passed, the command still performs the normal mutation preflight and safety checks, then writes a pending job file without running the full tree in the foreground. Use da job run <jobId> to execute or resume it in the foreground, or da job start <jobId> to hand it to a detached local worker. --job --run creates the checkpoint and starts that detached worker immediately.

da job

Inspect and resume durable local operation jobs stored in .da/jobs.

da job list
da job show <jobId>
da job tasks <jobId>
da job tasks <jobId> --status failed
da job watch <jobId>
da job watch <jobId> --follow
da --commit job promote <previewJobId> --yes
da job start <jobId>
da job run <jobId>
da job cancel <jobId>

Current job support includes preview-tree and publish-tree. Job state includes target org/repo/branch, operation metadata, per-path task status, attempts, result, retryable error history, and structured error details. Detached workers record PID and log-file metadata in the job checkpoint. A cancelled job stops between tasks when the worker observes the updated state file. Use da --commit job promote <previewJobId> to create a publish job from successfully completed preview-tree tasks only. For large configured targets, pass --yes after reviewing the preflight; add --run to start the detached publish worker immediately.

da preview status <path>

Check Helix preview pipeline status for a path.

da preview status /index

da preview explain <path>

Compare the DA source document with the generated preview .plain.html and report block classes that disappeared during preview extraction.

da preview explain /contact

This is useful when DA source contains a block class but preview renders flattened/raw text. The command also emits known block-contract hints, such as the canonical form block shape.


Block Contracts

da block list

List built-in block authoring contracts known to the CLI.

da block list

da block inspect <name>

Show the expected DA source shape for a block.

da block inspect form

The form contract documents the Edge Delivery pattern where the page block links to a DA sheet JSON and a submit endpoint. Field rows belong in the JSON sheet, not directly in the page block.


Publish

Promotes previewed pages to the live CDN (*.aem.live). Step 2 after da preview. All publish operations require --commit.

da publish page <path>

Promote a single page to live CDN.

da --commit publish page /index

da publish pages <source>

Batch publish — same source format as da preview pages.

da --org somarc --repo chronicle --commit publish pages /blog
da --org somarc --repo chronicle --commit publish pages paths.txt --concurrency 10
da --commit publish pages /blog --yes  # allow configured target after reviewing preflight

da publish tree [prefix]

Publish every HTML source document under a DA prefix to *.aem.live. Run da preview tree first.

da --commit publish tree /
da --commit publish tree /docs --concurrency 10
da --commit publish tree / --verify-live   # fail if any canonical live URL is unreachable
da --commit publish tree / --job           # checkpoint under .da/jobs instead of foreground execution
da --commit publish tree / --job --run
da --commit publish tree /docs --yes       # allow configured target after reviewing preflight

Publish tree jobs follow the same checkpoint model as preview jobs. They still require the normal live mutation gate up front; da job run <jobId> resumes a previously approved checkpoint, and da job start <jobId> starts it in a detached worker.

da publish unpublish <path>

Remove a page from the live CDN.

da --commit publish unpublish /old-page

Deploy

Runs the normal 2-step workflow in one command: preview first, then publish. Because both phases mutate remote state, deploy requires root --commit before either phase runs.

da deploy page <path>

Preview a single page, then promote it to live CDN.

da --commit deploy page /index
da --commit deploy page /blog/post --branch feature-branch

da deploy pages <source>

Batch preview first, then publish only the pages that previewed successfully.

da --org somarc --repo chronicle --commit deploy pages /blog --concurrency 10
da --org somarc --repo chronicle --commit deploy pages paths.txt --branch feature-branch
da --commit deploy pages /blog --yes       # allow configured target after reviewing preflight

Route

Classify and manage DA route ownership. Used before any destructive content operation to understand who owns a route.

Ownership classifications:

| Class | Meaning | |-------|---------| | contentbus | DA-owned — safe to do DA content operations | | codebus | Code-repo owned — DA operations will not affect this route | | hybrid | Both DA source and code-repo content present | | orphan | No owner found | | probe-failed | API error — classification incomplete, do not act |

Exit codes match classification for shell scripting: 0=contentbus, 2=orphan, 3=codebus, 4=hybrid, 5=probe-failed.

da route classify <path>

Probe a single route.

da route classify /blog/post
# { path: '/blog/post', ownership: 'contentbus', daSource: true, preview: 200, live: 200 }

da route canonical <path>

Show the DA source path, canonical browser URL path, preview URL, live URL, and .plain.html URL for a route. This is intended for discovery and does not use the classification exit-code contract; use da route classify when a script must branch on ownership.

da route canonical /index.html
# canonicalPath: /
# previewUrl: https://main--my-site--my-org.aem.page/
# liveUrl:    https://main--my-site--my-org.aem.live/

da route audit

Classify every route under a path prefix.

da route audit --prefix /blog
da route audit --prefix / --concurrency 20

da route clean <path>

Delete DA source for a route and flush preview. Dry-run default.

da route clean /old-page               # dry-run: shows classification
da --commit route clean /old-page      # delete source + flush preview
da --commit route clean /old-page --force  # bypass ownership check

Site

Diagnose DA-backed EDS site registration, content, code-bus, preview, and live state.

da site doctor [repo]

Run a compact health check for Sidekick registration, contentSourceType, code-bus visibility, shared DA docs, and key routes.

da site doctor my-site --org my-org
da site doctor my-site --org my-org --deep --limit 100 --concurrency 10
da site doctor --agent --deep --format json

Use --deep to sample HTML documents under the site root and summarize preview/live drift. If DA listing is unavailable, doctor reports that as a diagnostic row instead of aborting with a stack trace.

Use --agent from the EDS site repo to get a machine-readable briefing for coding agents. It inventories authored blocks from preview .plain.html, checks whether each block's JS/CSS resolves on the preview codebus branch, inspects local git for authored block implementations that are committed locally but not pushed upstream, and returns recommended next commands. This preserves Content Driven Development: content can lead implementation, but shared preview and release candidates should verify the content-code contract before being treated as healthy.

da site freshness [prefix]

Report DA source, preview, and live freshness for source documents under a prefix. Use this before release checks or after authoring shared docs such as nav and footer.

da site freshness / --include-shared --format json
da site freshness /news
da site freshness /nav --format json
da site freshness / --verdict live-stale,preview-only
da site freshness / --include-shared --fail-on preview-stale,live-stale,preview-only

Rows include source/preview/live status, last-modified timestamps, a freshness verdict, and next commands such as da --commit preview page ... or da --commit publish page ....

Use --verdict to focus the report and --fail-on to turn freshness drift into a release gate. The JSON row contract is documented in docs/schemas/site-freshness.schema.json.


Index

Inspect and query helix-query.yaml indices. Searches upward from cwd to find the file.

da index show

Print index definitions with field list.

da index show
da index show --file ./helix-query.yaml

da index validate

Check that fields defined in helix-query.yaml exist in the live query-index responses.

Use --target preview|live to select the EDS query host. The older subcommand-local --env preview|live form still works, but --target avoids confusing this with the root DA Admin API environment flag.

Do not assume the public /query-index.json endpoint exists just because helix-query.yaml is present locally. Missing endpoints return a structured diagnostic instead of an ambiguous failure.

da index validate
da index validate --target preview

Exits with code 1 if any fields are missing from the live index.

da index query <index-name>

Run a live query against a named index.

Use --target preview|live to select the EDS query host. The older subcommand-local --env preview|live form still works, but --target avoids confusing this with the root DA Admin API environment flag.

da index query blog
da index query blog --limit 100 --offset 0
da index query blog --filter type=article --filter author=jane
da index query blog --target preview

Audit

Validate EDS page content via .plain.html. Fetches from the EDS preview domain — the page must be previewed first.

da audit semantics <path>

Check heading hierarchy, metadata quality, and link quality.

da audit semantics /index

da audit blocks <path>

Validate block structure and decoration.

da audit blocks /blog/post

da audit full <path>

Run all audits with unified severity-classified report. Exits with code 1 if any error-severity findings are present.

da audit full /index

da audit contracts

List all block class names used across a path prefix (block inventory).

da audit contracts --prefix /blog
da audit contracts --prefix / --verify-code --format json

Add --verify-code to check that every authored block has matching /blocks/<block>/<block>.js and .css assets on the preview codebus branch. The command exits non-zero if preview block assets are missing or if local block implementation changes for authored blocks have not reached the configured upstream branch.


Migrate

Import external web pages into DA as EDS content. Scrapes the source URL, extracts main content, converts to EDS HTML structure, and uploads to DA.

The HTML conversion pipeline: fetch → extract <main> → absolutize URLs → strip scripts/styles/noise → convert recognizable patterns to EDS blocks → wrap in EDS document skeleton with metadata block.

da migrate import <url>

Import a single URL. Derives DA path from URL pathname by default.

da migrate import https://old-site.com/about                   # dry-run: shows generated HTML + diff
da --commit migrate import https://old-site.com/about          # uploads + triggers preview
da --commit migrate import https://old-site.com/about --path /about-us
da --commit migrate import https://old-site.com/about --no-preview

da migrate batch <url-file>

Import multiple URLs from a newline-delimited file. Supports resumable jobs — interrupted batches can be resumed with --job-id.

da --commit migrate batch urls.txt
da --commit migrate batch urls.txt --path-prefix /blog --concurrency 5
da --commit migrate batch urls.txt --job-id abc12345  # resume interrupted job

Lines starting with # are treated as comments.

da migrate status [job-id]

Show batch import progress.

da migrate status                # list all jobs
da migrate status abc12345       # detail for a specific job

da migrate validate <path>

Run a full audit on an imported page via its EDS preview URL.

da migrate validate /about-us

Pipeline

Execute declarative YAML pipeline DAGs — sequences and parallelizes da commands with dependency tracking, approval gates, and resumable state.

Start from a scaffold when an agent needs a deterministic workflow:

da pipeline scaffold agent-validate
da pipeline scaffold block-cdd --path /features/tabs
da pipeline scaffold content-block-benchmark --path /benchmarks/fluffycoins-moonshot
da pipeline scaffold release-candidate
da pipeline scaffold site-readiness
da pipeline scaffold local-super-loop
  • agent-validate orients the agent, verifies block contracts/codebus assets, checks /index preview status, explains preview structure, and runs a final doctor pass.
  • block-cdd is for Content Driven Development on a block: orient first, inspect the block contract, check preview status/explain the target page, then verify authored blocks against codebus assets.
  • content-block-benchmark is a dry-run self-check for agents that need to prove the content/block/style workflow: quality gate, block JS/CSS code sync dry-runs, content upload dry-run, and an agent doctor briefing scoped to the benchmark path.
  • release-candidate is the stricter pre-publish template: agent doctor, contract/codebus verification, preview tree verification, preview explain, and final doctor.
  • site-readiness is a release-gate scaffold for status, model, freshness, contract, and public code proof checks.
  • local-super-loop is a trusted local loop that can run Git, npm, and DA commands. It requires the hidden --riverboat-gambler flag and should only run against trusted YAML in a trusted repository.

Pipeline YAML format

pipeline:
  name: "Publish blog posts"
  context:
    org: my-org
    repo: my-site
  steps:
    - id: preview-index
      command: "preview status /index"
    - id: preview-blog
      command: "preview pages /blog --concurrency 10"
      depends_on: [preview-index]
    - id: publish-all
      command: "publish pages /blog --yes"
      depends_on: [preview-blog]
      requires_approval: true
      timeout: 5m
      continue_on_error: false

Steps at the same dependency level run in parallel. Timeouts accept s, m, or h suffixes.

Use inputs plus for_each when an agent needs to run the same deterministic step for a known batch. The expansion happens before validation, so each generated step still has to be an allowed da command and still participates in the normal dependency graph.

pipeline:
  name: "Driver profile checks"
  inputs:
    pages:
      - slug: christopher-bell
        path: /nascar-cup/drivers/christopher-bell
        source: content/nascar-cup/drivers/christopher-bell.html
      - slug: denny-hamlin
        path: /nascar-cup/drivers/denny-hamlin
        source: content/nascar-cup/drivers/denny-hamlin.html
  steps:
    - id: upload-${page.slug}
      command: "content put ${page.path}.html ${page.source} --format json"
      for_each:
        items: inputs.pages
        as: page
    - id: preview-${page.slug}
      command: "preview status ${page.path}.html --format json"
      depends_on: [upload-${page.slug}]
      for_each:
        items: inputs.pages
        as: page

Pipeline steps can also define a reconciliation loop. This is useful after da audit: if the audit fails, run a repair/reconcile command and then retry the audit before the pipeline gives up.

pipeline:
  name: "Generate, audit, reconcile, preview"
  steps:
    - id: generate-content
      command: "site generate \"FIRE learning site\" --from .da/blueprint.json"
    - id: audit
      command: "audit full /index"
      depends_on: [generate-content]
      reconcile:
        command: "site reconcile --from-audit /index --apply"
        max_attempts: 3
        fail_on_reconcile_error: true
    - id: preview
      command: "preview page /index"
      depends_on: [audit]

max_attempts counts the original audit attempt. With max_attempts: 3, the pipeline can run audit → reconcile → audit → reconcile → audit.

Content-first site pipeline

For new DA/EDS sites, prefer a content-driven pipeline. Upload the authored source tree first, preview all HTML sources so shared dependencies such as nav, footer, and fragments exist, then run quality gates and reconciliation.

pipeline:
  name: "Content-first EDS site build"
  context:
    org: somarc
    repo: fluffyjaws-financial
  steps:
    - id: upload-content
      command: "content put-tree content"
    - id: preview-tree
      command: "preview tree / --verify"
      depends_on: [upload-content]
    - id: quality-home
      command: "pipeline quality-gate https://main--fluffyjaws-financial--somarc.aem.page/ --min-score 85"
      depends_on: [preview-tree]
      reconcile:
        command: "site reconcile --from-audit /index --out .da/reconcile-index.json"
        max_attempts: 2
        fail_on_reconcile_error: false

Run with explicit target flags, for example da --org somarc --repo fluffyjaws-financial --commit pipeline run site-build.yaml, when you want write-capable steps to mutate remote state. Target-dependent pipelines require explicit root --org/--repo or pipeline.context.org/repo; they do not fall back to global config. Pipeline step commands must not embed --commit; the root pipeline invocation controls the mutation gate for the whole run. Pipeline YAML is intentionally constrained to da subcommands: shell control syntax, arbitrary binaries, and sensitive env overrides are rejected. The ordering is intentional: content expresses the site shape first; blocks should be inferred or scaffolded from repeated content patterns after the source documents exist.

da pipeline quality-gate <source>

Score a page or Stardust prototype using DA audit rules, Impeccable-derived design rules, and optional Stardust token checks. The command exits non-zero when the gate fails, so it can be used directly as a pipeline step.

da pipeline quality-gate /index
da pipeline quality-gate .stardust/prototypes/index.after.html --min-score 90 --stardust-tokens
da pipeline quality-gate https://main--site--org.aem.page/ --allow-errors

Example pipeline gate:

pipeline:
  name: "Objective site quality gate"
  steps:
    - id: stardust-prototype
      command: "stardust prototype /index"
    - id: quality-gate
      command: "pipeline quality-gate .stardust/prototypes/index.after.html --min-score 90 --stardust-tokens"
      depends_on: [stardust-prototype]
      reconcile:
        command: "site reconcile --from-audit /index --out .da/reconcile/index.json"
        max_attempts: 3

da pipeline run <yaml-file>

Execute a pipeline. State is persisted to ~/.da/pipeline-runs/<run-id>.json.

da pipeline run publish-blog.yaml
da --format json pipeline run --dry-run publish-blog.yaml  # expand and validate the plan only
da --org my-org --repo my-site pipeline run publish-blog.yaml
da --org my-org --repo my-site --commit pipeline run publish-blog.yaml  # propagates --commit to all write steps

--dry-run expands for_each, validates commands, checks target requirements, sorts dependency batches, and prints a pipeline.plan envelope without executing steps or writing run state. Target-dependent pipelines require explicit root --org/--repo or a YAML context block with org and repo. This avoids accidentally running a pipeline against stale global configuration.

da pipeline status [run-id]

Show pipeline run progress.

da pipeline status               # list all runs
da pipeline status abc12345      # step-by-step detail for a specific run

da pipeline abort <run-id>

Signal a running pipeline to stop before its next batch. In-flight steps complete.

da pipeline abort abc12345

Code

EDS code-bus operations — sync, inspect, and verify repo-owned code assets.

Normal codebus flow is Git push -> AEM Code Sync app -> da code verify. Use manual code sync --wait as an explicit repair path when the app-driven sync is insufficient or a release gate needs a fresh invalidation proof.

da code sync [path]

Trigger code-bus sync for a path (invalidates CDN for JS/CSS/HTML assets). Requires root --commit.

da --commit code sync /blocks/hero/hero.js
da --commit code sync /                      # sync everything
da --commit code sync block hero --yes --wait

Use --wait when an approved repair path or release gate needs the CLI to poll Helix code status after the sync request. --wait proves the code-bus status has settled; pair it with da code verify when you need to prove the public preview/live asset body contains the expected change.

da code status [path]

Check code-bus sync status for a path.

da code status /styles/styles.css --format json

da code verify <path>

Fetch a public code asset from preview or live and optionally require expected text in the response body. This is read-only and is the best final proof after CSS/JS sync because it checks the same public asset URL a browser loads.

da code verify /styles/styles.css --contains ".racing-hero-container"
da code verify /styles/styles.css --target live --contains ".racing-hero-container"

da code job <jobId>

Poll status of an async Helix admin job.

da code job abc123
da code job abc123 --wait --timeout 180  # block until terminal state

da code sidekick get

Print the current Helix sidekick configuration as JSON.

da code sidekick set <json>

Merge JSON into the sidekick config. Requires --commit.

da --commit code sidekick set '{"plugins":[{"id":"my-plugin","url":"https://example.com"}]}'

da code purge <path>

Purge CDN cache for a path. Requires --commit.

da --commit code purge /styles/fonts.css

Design

Design quality checks powered by the impeccable rule set — detect anti-patterns in EDS pages. Source can be a local HTML file, a URL, or a DA path (/my-page).

Anti-pattern categories

| Category | Description | |----------|-------------| | ai-slop | AI-generated content tells (em-dashes, "delve into", "tapestry of", etc.) | | quality | Design quality violations (gradient text, glassmorphism, bounce easing, pure black backgrounds) | | eds | EDS-specific problems (missing block structure, invalid markup patterns) |

da design detect <source>

Scan for design anti-patterns.

da design detect /index
da design detect https://my-site.aem.page/blog/post
da design detect ./local.html --category ai-slop
da design detect /page --severity error       # errors only
da design detect /page --fix-hints            # include fix suggestions

Exits with code 1 if any error-severity patterns are found.

da design rules

List all anti-pattern rules.

da design rules
da design rules --category ai-slop
da design rules --json

da design audit <source>

Comprehensive scan across all categories with fix hints — grouped report by category.

da design audit /index
da design audit /index --severity error

da design token-check <source>

Verify the Stardust :root CSS custom-property contract is present.

Required tokens: --color-brand-primary, --color-brand-secondary, --type-scale-base, --space-unit.

da design token-check /index

Stardust

4-phase EDS site redesign pipeline: extract → direct → prototype → migrate.

State is stored in .stardust/state.json relative to the current working directory. Run da stardust (no subcommand) to see current state and next step.

Phase 1 — da stardust extract [url]

Crawl an existing site (or fetch from DA) and extract brand/content into .stardust/current/. Generates PRODUCT.md and DESIGN.md stubs seeded with detected fonts, colors, and headings.

da stardust extract https://old-site.com --pages 10
da stardust extract              # fetch from DA (requires org/repo config)

Phase 2 — da stardust direct [phrase]

Resolve a design intent phrase into design dimensions and produce:

  • PRODUCT.md — target design brief
  • DESIGN.md — target design spec with CSS custom-property skeleton
  • DESIGN.json — machine-readable dimensions + palette
  • .stardust/direction.md — reasoning trace

Resolves 5 dimensions from the phrase: register, tone, density, expressive axis, distinctiveness.

da stardust direct "clean minimal product site, airy and professional"
da stardust direct --palette ocean-depths --tone serious

Phase 3 — da stardust prototype [page]

Generate before/after HTML prototype viewers in .stardust/prototypes/. Opens in any browser for visual review.

da stardust prototype /index
da stardust prototype --all       # generate for all extracted pages

Phase 4 — da stardust migrate [page]

Push approved designs to DA via the API and trigger preview. Requires --commit.

da --commit stardust migrate /index
da --commit stardust migrate --all

After migration, publish with explicit target flags, for example da --org my-org --repo my-site --commit publish pages /.

da stardust reset

Reset state back to fresh without deleting .stardust/ files.


Site

EDS site scaffolding and management. Requires GitHub CLI.

da site create <name>

Create a new EDS site from the ai-ecoverse/snowflake template — forks the template, creates fstab.yaml, and prints the AEM Sync setup steps. Requires root --commit.

da --commit site create my-new-site
da --commit site create my-new-site --org my-github-org --da-org my-da-org
da --commit site create my-new-site --private
da --commit site create my-new-site --no-da    # code-only, skip DA setup

After creation:

  1. Install AEM Sync on the new repo
  2. Create the matching DA repo at da.live
  3. Run da auth login and da --commit preview page /

da site list

List EDS repos in your GitHub org (detected by presence of fstab.yaml).

da site list
da site list --org my-org --limit 50

da site info [repo]

Show EDS site pipeline health — checks fstab.yaml, Helix content pipeline, and content non-empty.

da site info
da site info my-site --org my-org
da site info my-site --org my-org --branch feature-branch

da site model

Print the resolved EDS/DA site model for agents and durable jobs: org, repo, branch, delivery hosts, DA source mount, codebus identity, local config sources, and optional route ownership probes.

da site model
da site model --route /products/inventory/sku-0001.html /products/inventory/sku-1000.html
da site model --no-routes

If the model reports mixed target provenance, pin the project target before repeated writes or durable jobs:

da --org somarc --repo fluffyjaws-medical site pin-target --branch feature-commerce-catalog

da job init

Prepare a git worktree for durable local jobs by adding .da/jobs/ to .gitignore idempotently. Use this before detached preview/publish work so checkpoint JSON and worker logs do not pollute content commits.

da job init

da site blueprint [sourceUrl]

Analyze an EDS site, a local repo, or both, and emit a generation blueprint. The blueprint inventories indexed content, block primitives, block families, templates, tools, workers, authoring models, Universal Editor models, and integration signals.

da site blueprint https://demo.bbird.live --repo-dir ./demo --format json
da site blueprint https://demo.bbird.live --pages /,/start-here,/learn --limit 25
da site blueprint --repo-dir .

Use this before intent-based generation. It turns a mature EDS site into the concrete primitive map a generator needs: presentation blocks, composition blocks, discovery blocks, interaction blocks, content types, indexes, authoring schemas, and integration recipes.

da site reconcile [path]

Turn audit findings for a page into an actionable reconciliation plan. This command reruns the audit checks for the path, maps failures to candidate repair actions, and can write the plan to a local JSON file for a pipeline step to consume.

da site reconcile /index
da site reconcile --from-audit /index --out .da/reconcile/index.json
da site reconcile --from-audit /index --apply

--apply is reserved for automated mutations; in the current implementation it still emits a plan and reports that no mutation was performed.

da site doctor [repo]

Diagnose DA-backed EDS registration and delivery state. This command checks Sidekick registration, contentSourceType, code-bus visibility, shared DA documents, and route classification for /index, /nav, and /footer.

Use this before reseeding content when preview/publish fails with vague 404s.

da site doctor
da site doctor my-site --org my-org
da site doctor my-site --org my-org --branch feature-branch

Common failure signals:

  • Sidekick registration missing previewHost, liveHost, or contentSourceType
  • DA content exists but key routes classify as orphan
  • Preview is healthy but live is stale
  • Code-bus cannot see normal repo assets

Skills

Agent skills management — install, list, and search skills from GitHub, ClawHub, and Tessl registries. Wraps gh-upskill.

For agent harnesses that are new to da-cli, install the first-party operating skill:

da skills bootstrap
da skills add da-cli-agent --global

The da-cli-agent skill teaches the safety model, DA Admin vs EDS preview/live terminology, content-codebus validation, pipeline starters, and the proof path an agent should run before making changes.

da skills bootstrap

Install the upskill CLI to PATH if not already present.

da skills bootstrap

da skills install [source]

Install a skill from GitHub (owner/repo[@branch]), ClawHub (clawhub:<slug>), or a known shorthand.

da skills install pbakaus/impeccable
da skills install adobe/skills --skill stardust --path plugins/stardust
da skills install clawhub:my-skill
da skills install impeccable --global    # install to ~/.agents/skills/
da skills install impeccable --force     # overwrite existing
da skills install adobe/skills --list    # list available skills without installing

da skills add <shorthand>

Convenience shorthand for well-known EDS/DA skills.

| Shorthand | Source | |-----------|--------| | da-cli-agent | somarc/da-cli (skills/da-cli-agent path) | | impeccable | pbakaus/impeccable | | stardust | adobe/skills (plugins/stardust path) | | snowflake | ai-ecoverse/snowflake |

da skills add da-cli-agent --global
da skills add impeccable
da skills add stardust --global

da skills list

List all installed skills in the current project.

da skills list
da skills list --global

da skills info <name>

Show SKILL.md frontmatter for an installed skill.

da skills read <name>

Print full SKILL.md for an installed skill.

da skills search <query>

Search for skills across GitHub and ClawHub registries.

da skills search eds block

da skills update [name]

Update one installed skill to latest.

da skills update impeccable

Safety model

Write operations (put, delete, move, copy, publish, deploy, migrate, clean, sidekick set, purge) are dry-run by default. They show what would change (diff, classification, or plan) without mutating anything.

Pass --commit at the root level to enable writes:

da --commit content put /index.html ./index.html
da --commit publish page /index
da --commit deploy page /index

Write commands print a compact preflight before remote mutation, including the resolved org/repo, branch, config source, operation, and affected paths. For committed bulk publish/deploy operations, if the target came from config or environment instead of explicit root --org and --repo flags, the command refuses to continue unless --yes is supplied after reviewing the preflight.

da --org somarc --repo chronicle --commit publish pages /blog
da --commit publish pages /blog --yes

The --commit flag propagates through pipeline steps, so a single flag at the root gates an entire pipeline run. Target-dependent pipelines also require explicit root --org/--repo or a YAML context block.

Pipeline YAML is constrained to da subcommands. Arbitrary binaries, shell control syntax, step-local --commit, and sensitive env overrides are rejected.

Command Safety Matrix

The matrix is backed by src/lib/route-registry.js; keep that registry and this prose aligned when adding command families.

| Command family | Remote mutation | Requires root --commit | Extra guard | |---|---:|---:|---| | auth status, config, content list/tree/get/versions, route classify/canonical/audit, site doctor/model/freshness, audit, block inspect, preview status/explain, index, design audit, pipeline quality-gate/status, job list/show/watch/cancel, code status/verify/job, up | No | No | Read-only/local diagnostics | | site pin-target, job init | Local config/worktree hygiene | No | Local files only; no remote mutation | | content put/delete/move/copy | DA source | Yes | content put local file must be inside cwd unless --allow-outside-worktree | | content put-tree, content push | DA source bulk | Yes | Explicit root target or --yes for committed bulk configured targets | | preview page/pages/tree | *.aem.page preview pipeline | Yes | Bulk preview requires explicit root target or --yes for configured targets | | job start/run | Depends on recorded job | Job creation required it | Starts or resumes a previously approved local job checkpoint | | job promote | *.aem.live live CDN | Yes | Creates a publish job from completed preview tasks only; bulk promotion requires explicit root target or --yes | | publish page/pages/tree/unpublish | *.aem.live live CDN | Yes | Bulk publish requires explicit root target or --yes for configured targets | | deploy page/pages | Preview plus live CDN | Yes | Bulk deploy requires explicit root target or --yes for configured targets | | code sync/purge, code sidekick set | Codebus/CDN/admin config | Yes | Target preflight; configured committed targets require --yes; code sync --wait only polls after the approved sync | | route clean | DA source plus preview flush | Yes | Ownership classification before delete; target preflight | | migrate import/batch | DA source plus preview | Yes | Batch import uses committed bulk guard | | stardust migrate | DA source plus preview | Yes | Bulk migration uses committed bulk guard | | site create | GitHub repo/local scaffold | Yes | GitHub name validation; requires gh | | pipeline run | Depends on steps | Step-dependent | Target-dependent steps require explicit target or YAML context; unsafe YAML rejected |


Typical workflows

New EDS site from scratch

da --commit site create my-site
# Follow the printed AEM Sync + DA setup steps
cd my-site
da config init
da auth login
da --commit preview page /

Batch publish a folder

da --org somarc --repo my-site --commit preview pages /blog --concurrency 10
da --org somarc --repo my-site --commit publish pages /blog --concurrency 10

Preview + publish in one command

da --commit deploy page /index
da --org somarc --repo my-site --commit deploy pages /blog --concurrency 10

Import and publish an external page

da --commit migrate import https://old-site.com/about
da --commit publish page /about

Redesign a site with Stardust

da stardust extract https://current-site.com --pages 20
da stardust direct "modern minimal SaaS product site, airy neutral"
da stardust prototype --all
# Review .stardust/prototypes/*.html in browser
da --commit stardust migrate --all
da --org my-org --repo my-site --commit publish pages / --concurrency 10

Audit before publishing

da audit full /index
da design audit /index

Declarative publish pipeline

# publish.yaml
pipeline:
  name: "Full site publish"
  steps:
    - id: audit
      command: "audit full /index"
    - id: preview-all
      command: "preview pages / --concurrency 10"
      depends_on: [audit]
    - id: publish-all
      command: "publish pages / --concurrency 10 --yes"
      depends_on: [preview-all]
      requires_approval: true
da --org my-org --repo my-site --commit pipeline run publish.yaml

EDS content structure

DA documents must use the full EDS HTML skeleton or Helix will extract empty content:

<body>
  <header></header>
  <main>
    <div>
      <!-- page content -->
      <div class="metadata">
        <div><div>title</div><div>My Page Title</div></div>
        <div><div>description</div><div>Page description</div></div>
      </div>
    </div>
  </main>
  <footer></footer>
</body>

EDS blocks are authored as <div class="block-name"> tables — see EDS block authoring docs.


Troubleshooting

da preview page returns a URL but the page renders empty

  1. DA document missing <body><header></header><main>...</main><footer></footer></body> wrapper
  2. AEM Sync GitHub App not installed on the repo
  3. fstab.yaml missing or not committed on main

Run da site info for a health check that surfaces all three.

Unauthorized — run da auth login

Your token has expired. Run da auth login (or da auth login --refresh).

Route /foo is codebus-owned (from da route clean)

The route is served from the code repo, not DA. Deleting the DA source won't remove it. Pass --force only if you understand why you want to clean the DA source anyway.


Development

git clone https://github.com/somarc/da-cli.git
cd da-cli
npm test

Tests use Node's built-in test runner — no additional test framework required.

node --test src/**/*.test.js

To run the CLI locally without installing:

node ./bin/da.js auth status

Manual release

Npm publishing is intentionally manual because the package owner account requires 2FA. GitHub release automation validates the release, but it does not publish to npm.

From a clean main branch:

git pull --ff-only
npm test
npm run release:smoke
npm audit --omit=dev
npm pack --dry-run
npm publish --access public
git tag v0.4.3
git push origin v0.4.3

Before publishing, confirm package.json has the intended version and npm does not already have it:

node -p "require('./package.json').version"
npm view @somarc/da-cli version

CMUX workspace for DA/EDS

This repo includes an experimental CMUX workspace recipe for DA/EDS agentic development flows.

  • .cmux/cmux.json adds a project-local DA CLI Workspace for developing this CLI.
  • templates/cmux/da-cli/cmux.json can be copied into a DA/EDS project repo as .cmux/cmux.json.

See docs/cmux/da-mux.md for the workspace shape and product direction.


License

Apache-2.0