A successful clone printed a bare, timestamped app path that wrapped mid-word
in the terminal, so users' `cd` failed and `npm install && npm run dev` ran in
the wrong directory — a confusing failure from a successful clone. Plus there
was no first-party "see it locally" path, no central docs page, "clone" was
conflated with `git clone`, and key hygiene wasn't stated.
CLI (compiler):
- Add compiler/src/cliSummary.ts: a copy-paste-safe success block on stderr — a
single QUOTED `cd "<app>" && npm install && npm run dev` line that survives
terminal wrapping — plus the AGENTS.md safe-to-edit pointers (content.ts,
components/). The machine-readable {"event":"done",...} JSON stays on stdout.
- Add --serve (npm install + npm run dev in the generated app) and --open
(also open the browser at the detected dev URL). Wired into single + multi.
- Add writeLatestPointer(): refresh a runs/<site>/latest symlink to the newest
run so there's a stable, timestamp-free cd/script target. The reuse/regen
scanners already filter to digit-prefixed run dirs, so `latest` is ignored.
- Tests: cliSummary (quoting, single-line command, Next/Vite roots, stable-path
preference, --serve/--open hint) and runsLayout (symlink write + in-place
refresh, timestamp-free stable path).
Docs:
- Add docs/README.md as a central documentation index.
- State prominently that ditto "cloning" = generating a codebase from a live
URL, NOT `git clone` (no source repo required), in README + docs hub.
- Add "keys are secrets: use $DITTO_API_KEY, never inline/commit, rotate
anytime" beside the key/auth examples in README + docs/SERVICE.md.
- Document --serve/--open and the latest symlink in README + compiler/README.
Note: the live ditto.site/docs web route and the dashboard's inline-token
snippet live in the marketing-site repo and still need a change there.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two follow-ups to the single-page Lottie support:
1. Multi-page (clone-site). generateSiteApp emitted only DittoWire; it now wires
DittoLottie per route exactly like wires — builds the route's lottie spec,
emits the import + JSX, writes DittoLottie.tsx once, and injects lottie-web
into the site package.json when any route replays an animation (the write
moved after the route loop so the dep reflects actual usage). cloneSite now
captures motion on full route captures (motion: full) so lotties are observed;
light sibling probes skip it. Per-route gating verified: a route with no
animation gets no DittoLottie.
2. Inline animationData. When a lottie is only in memory (data-driven init, no
fetchable URL), capture now writes the JSON to the assets store as a real,
content-hashed .json so it materializes to /assets/cloned/lottie like any
source — instead of embedding the blob in the page spec. buildLottieSpec then
resolves it to a local path; the spec carries path, not animationData.
Verified end-to-end: a 2-page fixture emits DittoLottie only on the animated
route with lottie-web added; a data-driven inline fixture materializes
fd7c…json and the spec references it by path.
Co-Authored-By: claude-flow <ruv@ruv.net>