diff --git a/.agents/skills/create-pr/SKILL.md b/.agents/skills/create-pr/SKILL.md index d1745aea..68941f28 100644 --- a/.agents/skills/create-pr/SKILL.md +++ b/.agents/skills/create-pr/SKILL.md @@ -72,14 +72,14 @@ personal or non-Block repositories. ## Step 4: Check Release Hygiene -Ghost publishes only `@anarchitecture/ghost`; private packages are ignored by +Ghost publishes only `@design-intelligence/ghost`; private packages are ignored by Changesets. Inspect the diff and decide whether a changeset is required: - Required: user-visible changes to the public package, including CLI behavior, public exports, schema behavior, package output, docs that affect users, or - fixes shipped through `@anarchitecture/ghost`. + fixes shipped through `@design-intelligence/ghost`. - Usually not required: tests only, internal scripts only, private package only, CI-only changes, or docs/ideas notes that are not release-facing. @@ -87,7 +87,7 @@ When a changeset is required, create one before the PR: ```markdown --- -"@anarchitecture/ghost": patch +"@design-intelligence/ghost": patch --- One sentence, user-facing, present tense. diff --git a/.changeset/authoring-is-elicitation.md b/.changeset/authoring-is-elicitation.md new file mode 100644 index 00000000..0740a513 --- /dev/null +++ b/.changeset/authoring-is-elicitation.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Reframe fingerprint authoring as elicitation in the skill bundle and docs: remove the repo-scan-first auto-draft mode, rebuild the authoring scenarios around what the human says and shows, and point repo-derived reality at the adherence inventory. diff --git a/.changeset/binding-path-road.md b/.changeset/binding-path-road.md new file mode 100644 index 00000000..29afd4e5 --- /dev/null +++ b/.changeset/binding-path-road.md @@ -0,0 +1,8 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add `ghost.binding/v1` (`.ghost.bind.yml`) and the path road: a repo path +resolves to the surface that owns it (directory-default binding or explicit +declaration), and `ghost gather --path ` composes that surface's slice. +The contract still carries no paths — bindings own all path matching. diff --git a/.changeset/capture-node-prose-stances.md b/.changeset/capture-node-prose-stances.md new file mode 100644 index 00000000..03a546bb --- /dev/null +++ b/.changeset/capture-node-prose-stances.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Add node prose stances and a scored drafting gate to the capture recipe so authoring agents hold draft nodes to anti-slop standards before human curation. diff --git a/.changeset/checks-review-on-graph.md b/.changeset/checks-review-on-graph.md new file mode 100644 index 00000000..2bcdb945 --- /dev/null +++ b/.changeset/checks-review-on-graph.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +`ghost checks` and `ghost review` now route by catalog references and ground from the selected prose packet: grounding is the surface's gathered nodes by provenance (own / ancestor / edge), replacing the typed why/what (principles, contracts, patterns, exemplars) split — the why and what now live in each node's prose. `ghost checks` gains `--as ` to filter grounding to one output form. Exemplar `path:` is dropped from grounding. diff --git a/.changeset/collapse-containment-into-folder.md b/.changeset/collapse-containment-into-folder.md new file mode 100644 index 00000000..c4dd9b12 --- /dev/null +++ b/.changeset/collapse-containment-into-folder.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Remove redundant containment bookkeeping in favor of path-derived ids: parent and ancestor facts are derived from node paths, and the redundant parent/children maps are removed. diff --git a/.changeset/collapse-graph-remove-checks-review-migrate.md b/.changeset/collapse-graph-remove-checks-review-migrate.md new file mode 100644 index 00000000..9a62b325 --- /dev/null +++ b/.changeset/collapse-graph-remove-checks-review-migrate.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Reduce the fingerprint collection to a flat catalog: remove the `checks`, `review`, and `migrate` commands, drop node `relates` edges and traversal, and reduce `gather` to emitting the menu the agent selects from. diff --git a/.changeset/composition-graph-gaps.md b/.changeset/composition-graph-gaps.md new file mode 100644 index 00000000..b669a9fd --- /dev/null +++ b/.changeset/composition-graph-gaps.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Remove check surface routing: every check is now offered to the reviewer and the agent judges relevance, so the check `surface:` field, `selectChecksForSurfaces`, `RoutedCheck`, and `CheckRelevance` are gone. Checks bind to the fingerprint through an optional `source:` pointer (`node > Heading`) that `review` surfaces so a finding can cite the prose it enforces. diff --git a/.changeset/composition-init-template.md b/.changeset/composition-init-template.md new file mode 100644 index 00000000..aee966b5 --- /dev/null +++ b/.changeset/composition-init-template.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +`ghost init --template composition` scaffolds a composition-steering starter: the default files plus an invariants floor (`principle.composition`), a worked bound/open/refines pattern node, a glossary whose `pattern` and `principle` kinds carry the binding-depth convention, and an index that teaches the ladder — patterns when they match, principles as the floor when they don't, narrowing-only between them. diff --git a/.changeset/config.json b/.changeset/config.json index 8f5a9933..81dfa838 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,5 +7,5 @@ "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": ["ghost-ui", "ghost-docs", "ghost-fleet"] + "ignore": ["@design-intelligence/vessel", "ghost-docs"] } diff --git a/.changeset/consumption-posture.md b/.changeset/consumption-posture.md new file mode 100644 index 00000000..083aa77d --- /dev/null +++ b/.changeset/consumption-posture.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Adds opt-in wild consumption posture for glossary kinds and gather/pull/pulse observability. diff --git a/.changeset/corridor-gather.md b/.changeset/corridor-gather.md new file mode 100644 index 00000000..5c7baf48 --- /dev/null +++ b/.changeset/corridor-gather.md @@ -0,0 +1,14 @@ +--- +"@design-intelligence/ghost": minor +--- + +Recompose `gather` on a corridor + hub-and-spoke model and fix a sibling-surface +context leak. A surface's slice is now: a **spine** of full-body nodes from every +file on the corridor (the package root down to the surface's own folder — folders +are walls, so sibling folders never leak in), the **edges** reachable in one hop +from any spine node's `relates` (so a broad rule authored once high in the tree — +e.g. `relates: { to: arcade }` on `features/` — reaches every descendant), and a +set of **spokes**: pointer entries (id + description) for the surface's own +descendants and any edge hub's subtree, which the agent pulls on demand. The +`CatalogSlice` JSON gains a `spokes` array; catalog nodes carry their file `folder`. +Grounding for `checks`/`review` remains the full-body spine + edges. diff --git a/.changeset/cross-package-extends.md b/.changeset/cross-package-extends.md new file mode 100644 index 00000000..197850b5 --- /dev/null +++ b/.changeset/cross-package-extends.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add cross-package inheritance via `extends`. A package's `manifest.yml` can declare `extends: { : }`, mapping another contract's identity to where it lives. Node refs then reference inherited context by identity, never path — `relates: [{ to: brand:core/trust }]` (the `:` form replaces the earlier npm-style `#` ref grammar). Inherited nodes load read-only and flow into gather and validate like local ones. `ghost validate` resolves cross-package refs and reports unresolved refs, packages not declared in `extends`, identity mismatches, and cross-package cycles. This delivers the shared-brand story: one brand contract extended by many products, without copy-paste or merge. One level of `extends` in v1 (no transitive); location is an explicit relative dir (identity-based discovery is a future upgrade that keeps refs unchanged). diff --git a/.changeset/delete-dormant-entrypoint.md b/.changeset/delete-dormant-entrypoint.md new file mode 100644 index 00000000..067bb99b --- /dev/null +++ b/.changeset/delete-dormant-entrypoint.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Remove the dormant context-selection machinery (`buildContextEntrypoint`, `buildSelectedContext`, and selection-reasons) that was inert since the coordinate removal and orphaned once `review` moved onto the surface rails. Internal cleanup; no public surface change. diff --git a/.changeset/described-nodes.md b/.changeset/described-nodes.md new file mode 100644 index 00000000..6208e719 --- /dev/null +++ b/.changeset/described-nodes.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Make `description` a first-class node field — the retrieval payload an agent matches a task against, the way a tool is selected by name + description. `ghost gather` with no argument now lists nodes by id + description (the catalog), built from the catalog rather than a separate surface menu. Node frontmatter is now passthrough: free-form descriptive keys (`audience`, `stage`, …) are allowed and ride along untouched. The surface composition-edge vocabulary (`composes`/`governed-by`) is removed — lateral composition lives on node `relates`. diff --git a/.changeset/directory-tree-nodes.md b/.changeset/directory-tree-nodes.md new file mode 100644 index 00000000..b5263da1 --- /dev/null +++ b/.changeset/directory-tree-nodes.md @@ -0,0 +1,18 @@ +--- +"@design-intelligence/ghost": minor +--- + +Collapse the on-disk node model into the directory tree: the layout supplies the +catalog. A node's id is its file path (`marketing/email.md` → `marketing/email`) +and its parent is its containing directory; a surface is just a directory, and a +directory's own prose lives in its `index.md` (the package-root `index.md` is +the implicit `core` node). The `surfaces.yml` spine file and the `nodes/` +directory are removed, along with the node frontmatter `id` and `under` fields — +identity and containment now come from where a file sits, never from frontmatter +or a declared spine. Node frontmatter carries descriptive properties only +(`description`, `relates`, `incarnation`, plus passthrough keys); `relates` and +cross-package `extends` refs are path ids (`core/trust`, `brand:core/trust`). +`ghost init` scaffolds `manifest.yml` + a core `index.md`; `ghost migrate` +writes a directory tree; any `*.md` outside the reserved `checks/` subtree lints +as a node. Moving a node is a rename — `ghost validate` reports `relates` that no +longer resolve. diff --git a/.changeset/docs-check-binding.md b/.changeset/docs-check-binding.md new file mode 100644 index 00000000..14b9b770 --- /dev/null +++ b/.changeset/docs-check-binding.md @@ -0,0 +1,9 @@ +--- +"@design-intelligence/ghost": patch +--- + +Align docs and the skill bundle with the prose-bound check model: checks are no +longer routed by surface, every check is offered and the agent judges which +apply, and a check binds to prose via its optional `source:` pointer. Fix +the `ghost scan` next-step hint and skill recipes that referenced a nonexistent +`ghost check` command. diff --git a/.changeset/docs-node-model-refresh.md b/.changeset/docs-node-model-refresh.md new file mode 100644 index 00000000..258558c7 --- /dev/null +++ b/.changeset/docs-node-model-refresh.md @@ -0,0 +1,6 @@ +--- +"@design-intelligence/ghost": patch +--- + +Refresh the README and docs site onto the current command set (drop the removed +`lint`/`verify`/`relay`/`describe`/`survey`/`emit` commands). diff --git a/.changeset/drop-dead-deps.md b/.changeset/drop-dead-deps.md new file mode 100644 index 00000000..7cff1570 --- /dev/null +++ b/.changeset/drop-dead-deps.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Drop two unused runtime dependencies (`jiti`, `tinyglobby`) — neither was imported anywhere in source. Ghost now ships three runtime deps (`cac`, `yaml`, `zod`), shrinking the install footprint by ~1.8 MB. Also fix the build to clear `tsconfig.tsbuildinfo` so `dist/` no longer retains deleted modules from incremental builds (the packed package drops from ~1.9 MB / 777 files to ~397 KB / 248 files). diff --git a/.changeset/events-tape-first-write-notice.md b/.changeset/events-tape-first-write-notice.md new file mode 100644 index 00000000..69c7390c --- /dev/null +++ b/.changeset/events-tape-first-write-notice.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Print a one-time stderr notice when the local `.ghost/.events` tape is first created, so gather/pull logging is never a surprise. diff --git a/.changeset/exit-code-contract.md b/.changeset/exit-code-contract.md new file mode 100644 index 00000000..fea7b82d --- /dev/null +++ b/.changeset/exit-code-contract.md @@ -0,0 +1,8 @@ +--- +"@design-intelligence/ghost": patch +--- + +Make CLI exit codes consistent so an agent can branch on them: unexpected +errors exit `1`, caller mistakes (bad flags, invalid environment, refused +overwrites) exit `2` via a typed `UsageError`, and a missing package now exits +`2` with a `ghost init` hint instead of leaking a raw filesystem error. diff --git a/.changeset/export-source-ref-parser.md b/.changeset/export-source-ref-parser.md new file mode 100644 index 00000000..d0aef29e --- /dev/null +++ b/.changeset/export-source-ref-parser.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Export `parseSourceRef` and `sliceNodeSection` from the core entrypoint: the shared parser for a check's `source:` reference grammar (`node-id > Heading`) and a helper to slice the referenced section out of a node body. diff --git a/.changeset/external-contract-references.md b/.changeset/external-contract-references.md new file mode 100644 index 00000000..93c50ac0 --- /dev/null +++ b/.changeset/external-contract-references.md @@ -0,0 +1,9 @@ +--- +"@design-intelligence/ghost": minor +--- + +Bindings can reference an external contract: a `.ghost.bind.yml` `contract:` now +accepts an npm package name (`@scope/brand`) in addition to `.` (in-repo), +resolved from `node_modules`. `ghost verify` checks the external contract +resolves and that each bound surface exists in it. External fingerprint loading +for grounding remains a follow-up. diff --git a/.changeset/facet-removal.md b/.changeset/facet-removal.md new file mode 100644 index 00000000..2447a910 --- /dev/null +++ b/.changeset/facet-removal.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Remove the facet model — the catalog is now the only fingerprint model. The `intent.yml`/`inventory.yml`/`composition.yml` schemas, the `GhostFingerprintDocument`, the facet→node load-time projection, and the dormant facet slice/grounding are deleted; the loader assembles the package's prose nodes directly into the catalog. `ghost lint` and `ghost verify` are replaced by one `ghost validate` verb (artifact shape pass + catalog pass); `ghost emit` is removed. `ghost scan` now reports node/surface contribution instead of facet contribution. Legacy facet packages no longer load directly — `ghost validate`/load fail with guidance to run `ghost migrate`. Structured exemplar-path and evidence verification is dropped (evidence lives in node prose, per the prose-node model). diff --git a/.changeset/fingerprint-grounding.md b/.changeset/fingerprint-grounding.md new file mode 100644 index 00000000..c283036f --- /dev/null +++ b/.changeset/fingerprint-grounding.md @@ -0,0 +1,9 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add fingerprint grounding to `ghost checks`: for each touched surface, emit the +*why* (principles and experience contracts) and the *what good looks like* +(patterns and exemplars with paths), drawn from that surface's slice and +inherited from its ancestors. A flagged check can now cite the design intent it +serves and point at an exemplar. Use `--no-grounding` for relevance only. diff --git a/.changeset/first-node-onramp.md b/.changeset/first-node-onramp.md new file mode 100644 index 00000000..bf993a5d --- /dev/null +++ b/.changeset/first-node-onramp.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Lead fingerprint authoring with a concrete first move — capture the one surface whose review feedback keeps repeating — instead of a scenario-classification step. diff --git a/.changeset/gather-command.md b/.changeset/gather-command.md new file mode 100644 index 00000000..14c4af2c --- /dev/null +++ b/.changeset/gather-command.md @@ -0,0 +1,7 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add `ghost gather `: compose a surface's context slice (its own placed +nodes, cascaded ancestors, and one-hop typed-edge contributions) with +provenance, or return the surface menu when no surface is named. diff --git a/.changeset/gather-kind-legend.md b/.changeset/gather-kind-legend.md new file mode 100644 index 00000000..86091b0f --- /dev/null +++ b/.changeset/gather-kind-legend.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +`ghost gather` now surfaces the glossary's kind purposes as a menu legend, in both markdown and JSON output, so the menu is self-sufficient selection context. diff --git a/.changeset/gather-on-graph-incarnation.md b/.changeset/gather-on-graph-incarnation.md new file mode 100644 index 00000000..cd2dae1f --- /dev/null +++ b/.changeset/gather-on-graph-incarnation.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +`ghost gather` now composes its context packet from selected fingerprint catalog nodes and emits nodes-by-provenance prose (own / ancestor / edge), and gains `--as ` to filter the packet to one output form (e.g. email, billboard, voice) while always keeping essence (untagged) nodes. diff --git a/.changeset/gather-ranking-and-surface-guard.md b/.changeset/gather-ranking-and-surface-guard.md new file mode 100644 index 00000000..7702e8da --- /dev/null +++ b/.changeset/gather-ranking-and-surface-guard.md @@ -0,0 +1,10 @@ +--- +"@design-intelligence/ghost": minor +--- + +Return the node menu plus closest-id "did you mean" suggestions when `ghost +gather` is given an inexact query, instead of a separate ranked-candidate +search — the agent re-picks by description from the same menu the no-argument +form prints. `gather`, `checks`, and `review` all emit the stable +`ERR_UNKNOWN_SURFACE` code with closest-id suggestions for a node or surface +that is not in the package. diff --git a/.changeset/gather-vocab.md b/.changeset/gather-vocab.md new file mode 100644 index 00000000..f79b9485 --- /dev/null +++ b/.changeset/gather-vocab.md @@ -0,0 +1,9 @@ +--- +"@design-intelligence/ghost": minor +--- + +Rename the `gather` slice vocabulary to plain language. The JSON `slice.spokes` +field is now `slice.pointers`, and the pointer `kind` `"edge-hub"` is now +`"related"` with its origin in a `from` field (was `hub`). Docs and the skill +bundle drop the spine/corridor/hub-and-spoke metaphors; `edge` provenance is +unchanged. diff --git a/.changeset/ghost-check-format.md b/.changeset/ghost-check-format.md new file mode 100644 index 00000000..18df0fa2 --- /dev/null +++ b/.changeset/ghost-check-format.md @@ -0,0 +1,9 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add `ghost.check/v1`: markdown + frontmatter checks (`name`, `description`, +`severity`, optional `tools` / `turn-limit`, plus a Ghost `surface:` placement), +parsed and linted but never executed by Ghost. Markdown files under a `checks/` +directory lint as checks. This mirrors the established agent-check format so +Ghost can route and ground checks without owning a check engine. diff --git a/.changeset/ghost-local-pulse.md b/.changeset/ghost-local-pulse.md new file mode 100644 index 00000000..1042c5ef --- /dev/null +++ b/.changeset/ghost-local-pulse.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add local gather/pull event tracing and a pulse report for fingerprint tuning. diff --git a/.changeset/goose-skill-install-target.md b/.changeset/goose-skill-install-target.md new file mode 100644 index 00000000..2055be3f --- /dev/null +++ b/.changeset/goose-skill-install-target.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add `goose` as a first-class `ghost skill install --agent` destination, installing to `~/.agents/skills` (Goose's canonical global skills directory) and auto-detecting Goose installs. diff --git a/.changeset/inventory-lens-reference.md b/.changeset/inventory-lens-reference.md new file mode 100644 index 00000000..112536fa --- /dev/null +++ b/.changeset/inventory-lens-reference.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Add an inventory-lens authoring reference to the skill bundle. diff --git a/.changeset/materials-transport.md b/.changeset/materials-transport.md new file mode 100644 index 00000000..60f4f610 --- /dev/null +++ b/.changeset/materials-transport.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Ghost validates material locator liveness and inlines small local materials during pull. diff --git a/.changeset/migrate-command.md b/.changeset/migrate-command.md new file mode 100644 index 00000000..a7a6c1a7 --- /dev/null +++ b/.changeset/migrate-command.md @@ -0,0 +1,8 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add `ghost migrate`: transform a legacy `.ghost/` package onto the directory-tree +node model — derive surface directories from old `topology.scopes`, place +single-scope nodes inside them, and report (never guess) any node it cannot place +unambiguously. diff --git a/.changeset/node-authoring.md b/.changeset/node-authoring.md new file mode 100644 index 00000000..2368ac24 --- /dev/null +++ b/.changeset/node-authoring.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +`ghost init` now scaffolds a node package (`manifest.yml` + a core `index.md` node) via a template registry (`--template `, `default` for now) instead of emitting `intent.yml`/`inventory.yml`/`composition.yml`; the `--reference` flag is removed. `ghost migrate` now performs a one-way conversion of legacy/facet packages into a directory tree of nodes (the facet→node projection becomes the writer) and removes the old facet files. The authoring skill (`capture.md`, `SKILL.md`) teaches node authoring with intent/inventory/composition as authoring lenses rather than facet files. diff --git a/.changeset/one-road-remove-binding-and-nesting.md b/.changeset/one-road-remove-binding-and-nesting.md new file mode 100644 index 00000000..6204f2d2 --- /dev/null +++ b/.changeset/one-road-remove-binding-and-nesting.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Remove the path→surface binding (`ghost.binding/v1`, `.ghost.bind.yml`) and all nesting (fingerprint stacks, cross-package discovery): one contract per package, surfaces are the only locality. `checks` and `review` now take agent-stated `--surface ` instead of resolving surfaces from a diff; `gather` takes only a surface or returns the menu. Removed `gather --path`, `checks --diff`, `lint --all`, `verify --all`, `scan --include-nested`, `emit --path`, `init --scope`, and `init --monorepo`. The agent names the touched surfaces; Ghost no longer infers intent from repo location. diff --git a/.changeset/pull-command.md b/.changeset/pull-command.md new file mode 100644 index 00000000..ae08c8e9 --- /dev/null +++ b/.changeset/pull-command.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add `ghost pull […]`: emit selected nodes' prose bodies and record selections in the `.ghost/.events` events tape for fingerprint tuning. diff --git a/.changeset/quiet-owls-export.md b/.changeset/quiet-owls-export.md new file mode 100644 index 00000000..6abc0021 --- /dev/null +++ b/.changeset/quiet-owls-export.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Adds `ghost export` to package fingerprints as portable brand artifacts with material locator audits. diff --git a/.changeset/readme-flat-model.md b/.changeset/readme-flat-model.md new file mode 100644 index 00000000..913cd4e4 --- /dev/null +++ b/.changeset/readme-flat-model.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Rewrite the package README onto the flat-corpus model: plain-language framing, current CLI commands only, and removal of stale relation-era shapes (`relates`, surface directories, `checks/` at the fingerprint root, `ghost checks`/`ghost review`/`ghost migrate`). diff --git a/.changeset/remove-compare-drift-fleet.md b/.changeset/remove-compare-drift-fleet.md new file mode 100644 index 00000000..c22dc87a --- /dev/null +++ b/.changeset/remove-compare-drift-fleet.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Remove `compare`, `drift`, `ack`, `track`, and `diverge` commands and the direct `fingerprint.md` machinery (parser, writer, semantic diff, decisions/dimensions, embeddings, perceptual prior). These rested on a quantified visual-design-system model (fixed dimensions + decision embeddings) that the catalog reframe abandoned; the concepts are parked for a later rethink (see docs/ideas/compare-drift-fleet-rethink.md). The `./compare` and `./drift` package subpaths and the root `compare`/`drift` exports are removed. `ghost lint` now validates `.ghost/` packages and node/surface/check artifacts only (direct `fingerprint.md` is no longer linted); a `*.md` node file lints as a `ghost.node/v1` node. diff --git a/.changeset/remove-extends.md b/.changeset/remove-extends.md new file mode 100644 index 00000000..e12668ef --- /dev/null +++ b/.changeset/remove-extends.md @@ -0,0 +1,10 @@ +--- +"@design-intelligence/ghost": minor +--- + +Remove cross-package `extends` and inherited nodes. A Ghost package is a single +self-contained contract: its `.ghost/` directory tree is the whole fingerprint. +The manifest no longer accepts `extends`, `relates` targets must be local path +ids (the `:` colon ref is gone), and the catalog drops the +`origin` / inherited-node distinction. Use `ghost --package ` to address a +package; there is no shared-brand inheritance in this version. diff --git a/.changeset/remove-haunt-terminology.md b/.changeset/remove-haunt-terminology.md new file mode 100644 index 00000000..80145a9a --- /dev/null +++ b/.changeset/remove-haunt-terminology.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Removes the optional-capability subsystem and its per-capability manifest schema. Checks are now a core capability in a flat `.ghost/checks/` directory: scaffold with `ghost checks init` (or `ghost init --with checks`), and `ghost export --no-checks` replaces the old exclusion flag. `ghost validate` flags packages still using the old nested checks location. diff --git a/.changeset/remove-incarnation.md b/.changeset/remove-incarnation.md new file mode 100644 index 00000000..228cc2f8 --- /dev/null +++ b/.changeset/remove-incarnation.md @@ -0,0 +1,9 @@ +--- +"@design-intelligence/ghost": minor +--- + +Remove the `incarnation` node field and the `--as` gather/checks flag. Ghost +fingerprints a single-medium product surface; the cross-medium projection axis +(essence vs. incarnation, the portability dial) is dropped rather than shipped +unused. Slices no longer carry an `incarnation` field and `ResolveCatalogSliceOptions` +is removed. diff --git a/.changeset/remove-relay-and-legacy-commands.md b/.changeset/remove-relay-and-legacy-commands.md new file mode 100644 index 00000000..42644584 --- /dev/null +++ b/.changeset/remove-relay-and-legacy-commands.md @@ -0,0 +1,9 @@ +--- +"@design-intelligence/ghost": minor +--- + +Remove the absorbed and dead commands: `relay`, `stack`, `survey`, `diff`, and +`describe`, along with the relay-only context modules and the `./relay` package +export. Their intent now lives in the surface model — `gather` for context, +`checks` for diff-routed governance, and bindings for path resolution. The skill +bundle teaches the surface workflow. diff --git a/.changeset/remove-scan-signals-inventory.md b/.changeset/remove-scan-signals-inventory.md new file mode 100644 index 00000000..d71270da --- /dev/null +++ b/.changeset/remove-scan-signals-inventory.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Remove the `ghost scan` and `ghost signals` commands and the deterministic repo-inventory subsystem; the host agent does its own repo reconnaissance and `validate`/`gather` cover package inspection. diff --git a/.changeset/remove-validate-one-check-format.md b/.changeset/remove-validate-one-check-format.md new file mode 100644 index 00000000..844afacc --- /dev/null +++ b/.changeset/remove-validate-one-check-format.md @@ -0,0 +1,9 @@ +--- +"@design-intelligence/ghost": minor +--- + +Collapse to one check format. Remove `ghost.validate/v1`, the `validate.yml` +facet, the `ghost check` deterministic gate, and the `./govern` export. Ghost +now has a single check format — markdown `ghost.check/v1`, routed by surface +(`ghost checks`) and grounded by the fingerprint. `parseUnifiedDiff` moved to a +neutral module; the `drift` stance ledger is unchanged. diff --git a/.changeset/rename-graph-to-catalog.md b/.changeset/rename-graph-to-catalog.md new file mode 100644 index 00000000..ac554969 --- /dev/null +++ b/.changeset/rename-graph-to-catalog.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Standardize the internal collection vocabulary on "catalog" to reflect the flat node set: public exports are `GhostCatalog`, `GhostCatalogNode`, `buildCatalogMenu`, `CatalogMenuEntry`, and `assembleCatalog`, and the loaded package exposes a `catalog` field. diff --git a/.changeset/rename-scope-decentralized-design.md b/.changeset/rename-scope-decentralized-design.md new file mode 100644 index 00000000..8b8793db --- /dev/null +++ b/.changeset/rename-scope-decentralized-design.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Rename the public package from `@anarchitecture/ghost-fingerprint` to `@design-intelligence/ghost`. The `ghost` and `ghost-fingerprint` bins, all subpath exports (`/core`, `/fingerprint`, `/scan`, `/cli`), and the `.ghost/` package format are unchanged; only the npm name moves. Release tags and tarballs now use the `design-intelligence-ghost` prefix. diff --git a/.changeset/rename-scope-design-intelligence.md b/.changeset/rename-scope-design-intelligence.md new file mode 100644 index 00000000..fddb65f9 --- /dev/null +++ b/.changeset/rename-scope-design-intelligence.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Rename the npm scope from `@decentralized-design` to `@design-intelligence`; the package is now `@design-intelligence/ghost` and release tarballs/tags use the `design-intelligence-ghost` prefix. diff --git a/.changeset/rename-to-ghost-fingerprint.md b/.changeset/rename-to-ghost-fingerprint.md new file mode 100644 index 00000000..5996d377 --- /dev/null +++ b/.changeset/rename-to-ghost-fingerprint.md @@ -0,0 +1,13 @@ +--- +"@design-intelligence/ghost": minor +--- + +Rename the published package from `@design-intelligence/ghost` to +`@design-intelligence/ghost`. Ghost is now a family of packages — +`ghost-fingerprint` (the fingerprint and its CLI), `ghost-adherence` (the +code-anchored adherence bridge), and `ghost-vessel` (the reference body) — +and the package name now says which part it is. The `ghost` bin, all export +subpaths (`/fingerprint`, `/scan`, `/core`, `/cli`), and the `.ghost/` +on-disk format are unchanged; only the install name moves. Existing installs +keep working from the old name until it is deprecated on npm with a pointer +forward. diff --git a/.changeset/retire-haunt-materials-review.md b/.changeset/retire-haunt-materials-review.md new file mode 100644 index 00000000..7751112d --- /dev/null +++ b/.changeset/retire-haunt-materials-review.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Collapse the separate adherence package into the fingerprint: nodes carry optional `materials` locators, checks become an opt-in capability of the fingerprint package, and `ghost review` assembles advisory diff packets from material-backed nodes and checks. The external dispatch to a second binary is removed. diff --git a/.changeset/retire-lens-vocabulary.md b/.changeset/retire-lens-vocabulary.md new file mode 100644 index 00000000..625f9303 --- /dev/null +++ b/.changeset/retire-lens-vocabulary.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Retire the "three lenses" vocabulary: authoring docs now speak the same steering dimensions the CLI scores (stance, concreteness, patterns), and the inventory recipe becomes references/blocks.md with a neutral block kind in its examples. diff --git a/.changeset/retire-merge.md b/.changeset/retire-merge.md new file mode 100644 index 00000000..e8b36790 --- /dev/null +++ b/.changeset/retire-merge.md @@ -0,0 +1,10 @@ +--- +"@design-intelligence/ghost": minor +--- + +Retire the `child-wins-by-id` fingerprint merge (Leak E): nested `.ghost/` +packages now bind paths to the root contract's surfaces instead of merging their +own facets in. A path resolves to the single root contract, used as-is — a child +package can no longer silently override or disable an inherited rule or check. +The `stack` / `check` / `review` outputs expose `contract` instead of `merged`, +and drop the `provenance.merge` field. diff --git a/.changeset/review-on-surfaces.md b/.changeset/review-on-surfaces.md new file mode 100644 index 00000000..8dd6b614 --- /dev/null +++ b/.changeset/review-on-surfaces.md @@ -0,0 +1,10 @@ +--- +"@design-intelligence/ghost": minor +--- + +Rebuild `ghost review` on the surface rails: it now resolves the diff's touched +surfaces (via bindings), selects the markdown checks governing them, and grounds +each in the fingerprint slice — instead of emitting `validate.yml` and a +path-selection context packet. The advisory-review JSON replaces +`fingerprint` / `context_markdown` / `checks` / `stacks` with `touched_surfaces`, +`routed_checks`, and `grounding`. `ghost check` remains the deterministic gate. diff --git a/.changeset/scope-manifesto.md b/.changeset/scope-manifesto.md new file mode 100644 index 00000000..231b6d47 --- /dev/null +++ b/.changeset/scope-manifesto.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Add a thesis section to the README: agents changed the unit of design work, the work that compounds is architectural, and Ghost is the artifact those decisions live in. diff --git a/.changeset/shared-cli-manifest-builder.md b/.changeset/shared-cli-manifest-builder.md new file mode 100644 index 00000000..bccd2870 --- /dev/null +++ b/.changeset/shared-cli-manifest-builder.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add a `ghost manifest --format json` command that emits a self-describing manifest of every command and flag, so a host agent can discover the CLI in one call instead of scraping `--help`. The terminal help, docs-site manifest, and this command all derive from one shared `buildCliManifest()` (also exported from `@design-intelligence/ghost/cli`). diff --git a/.changeset/skill-bundle-prose.md b/.changeset/skill-bundle-prose.md new file mode 100644 index 00000000..d41f1e61 --- /dev/null +++ b/.changeset/skill-bundle-prose.md @@ -0,0 +1,6 @@ +--- +"@design-intelligence/ghost": patch +--- + +Clean em dashes out of the shipped skill bundle and package README prose, +rewriting them as plain sentences, colons, or parentheticals. diff --git a/.changeset/skill-encoding-guidance.md b/.changeset/skill-encoding-guidance.md new file mode 100644 index 00000000..765f1877 --- /dev/null +++ b/.changeset/skill-encoding-guidance.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Make the glossary the authoritative source of kind semantics in the skill recipes, teach sample and counter-exemplar capture, add an `anti-goal` starter kind, and establish the `index` node as the always-pulled carrier of a fingerprint's non-negotiables and silence posture. diff --git a/.changeset/skill-verb-first.md b/.changeset/skill-verb-first.md new file mode 100644 index 00000000..80c4ae52 --- /dev/null +++ b/.changeset/skill-verb-first.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Reorder the skill bundle to lead with the workflow loop and CLI verbs, moving the node-catalog model into a later "How It Works" section. diff --git a/.changeset/steering-default-template.md b/.changeset/steering-default-template.md new file mode 100644 index 00000000..2df11c9c --- /dev/null +++ b/.changeset/steering-default-template.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Make the steering starter the default `ghost init` scaffold, move the old small scaffold to `--template minimal`, and mark starter steering content as demo guidance to replace. diff --git a/.changeset/steering-physics-packet.md b/.changeset/steering-physics-packet.md new file mode 100644 index 00000000..bb366be1 --- /dev/null +++ b/.changeset/steering-physics-packet.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Adds steering-ordered pulls, derived concreteness coverage, guard posture review routing, check probes, inspect-pointers for binary materials, and a worked steering starter. diff --git a/.changeset/steering-template.md b/.changeset/steering-template.md new file mode 100644 index 00000000..f53d7e2e --- /dev/null +++ b/.changeset/steering-template.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": minor +--- + +Adds a steering-ready fingerprint template and skill guidance for authoring, briefing, and auditing agent-readable brand steering. diff --git a/.changeset/surface-coordinate-space.md b/.changeset/surface-coordinate-space.md new file mode 100644 index 00000000..3a80b303 --- /dev/null +++ b/.changeset/surface-coordinate-space.md @@ -0,0 +1,8 @@ +--- +"@design-intelligence/ghost": minor +--- + +Replace topology/applies_to/surface_type/scope coordinates with a surface +coordinate space and a single surface placement per node. Remove the +`ghost.map/v1` (`map.md`) coordinate and routing system; checks now route by +`applies_to.paths`. diff --git a/.changeset/surface-routed-checks.md b/.changeset/surface-routed-checks.md new file mode 100644 index 00000000..396498fa --- /dev/null +++ b/.changeset/surface-routed-checks.md @@ -0,0 +1,10 @@ +--- +"@design-intelligence/ghost": minor +--- + +Add markdown checks (`ghost.check/v1`) in a package's `checks/` directory. +`ghost checks --surface ` grounds the named surfaces and offers every +check; the host agent judges which apply. A check binds to the prose it enforces +through an optional `source:` pointer (a node id with an optional `> Heading`), +not by surface routing. Ghost selects, grounds, and emits checks; it never runs +them. diff --git a/.changeset/teach-terms-by-example.md b/.changeset/teach-terms-by-example.md new file mode 100644 index 00000000..dcd6fce8 --- /dev/null +++ b/.changeset/teach-terms-by-example.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Teach the authoring lenses and `incarnation`/essence distinction from a shown node example instead of negative definitions ("not fields", "essence is untagged"). diff --git a/.changeset/thesis-steering-packet.md b/.changeset/thesis-steering-packet.md new file mode 100644 index 00000000..91d8c55b --- /dev/null +++ b/.changeset/thesis-steering-packet.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Reframe the package README and description around the fingerprint as a portable brand steering packet. diff --git a/.changeset/validate-help-describes-current-checks.md b/.changeset/validate-help-describes-current-checks.md new file mode 100644 index 00000000..b1bbcf98 --- /dev/null +++ b/.changeset/validate-help-describes-current-checks.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Update `ghost validate --help` to describe what validation actually checks today: manifest shape, node validity, material locators, check references, and glossary kind prefixes. diff --git a/.changeset/validate-surfaces-invalid-nodes.md b/.changeset/validate-surfaces-invalid-nodes.md new file mode 100644 index 00000000..02352fbe --- /dev/null +++ b/.changeset/validate-surfaces-invalid-nodes.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +`ghost validate` now reports a node that fails its own schema instead of silently dropping it from the catalog. diff --git a/.ghost/.gitignore b/.ghost/.gitignore new file mode 100644 index 00000000..cffd9e8a --- /dev/null +++ b/.ghost/.gitignore @@ -0,0 +1,2 @@ +.events +.pulls diff --git a/.ghost/anti-goal.surface-sprawl.md b/.ghost/anti-goal.surface-sprawl.md new file mode 100644 index 00000000..cf53be1a --- /dev/null +++ b/.ghost/anti-goal.surface-sprawl.md @@ -0,0 +1,19 @@ +--- +description: Guard against speculative surface area. Review-critical for changes that add commands, flags, fields, or vocabulary. +materials: + - packages/ghost/src/commands/*.ts + - .changeset/*.md +--- + +Not: shipping a field, flag, node type, hierarchy, or projection axis because +a future use case might want it. `extends`, `incarnation`, surface routing, +and the graph model all shipped unused and were all cut. + +Instead: ship the smallest surface that solves an observed failure, and cut +surface that has no user. New CLI commands and flags need a changeset, a +manifest regeneration (`pnpm dump:cli-help`), and a worked example in the +skill bundle before they are real. + +Recognize the switch: if a PR adds a concept that no recipe teaches and no +test exercises against a real task, the guard failed. If explaining the +feature requires new vocabulary, that vocabulary is a cost; count it. diff --git a/.ghost/composition.yml b/.ghost/composition.yml deleted file mode 100644 index 295f9e15..00000000 --- a/.ghost/composition.yml +++ /dev/null @@ -1,61 +0,0 @@ -patterns: - - id: sparse-contribution-before-completeness - kind: structure - pattern: Ghost scan and docs describe what each package contributes instead of treating absent facets as incomplete packages. - guidance: - - Do not require every package to contain intent, inventory, composition, and validate. - - Treat nested packages as patches in the broad-to-local fingerprint stack. - - Keep ghost signals as stdout-only reconnaissance for agents, not package material. - - Curate durable building blocks and exemplars into inventory.yml instead of treating raw signals as inventory authorship. - - Use Git review for fingerprint approval instead of Ghost-specific draft files. - evidence: - - path: README.md - - path: docs/fingerprint-format.md - - path: packages/ghost/src/scan/fingerprint-contribution.ts - - id: compact-agent-handoff - kind: content - pattern: CLI and emitted prompts should tell the host agent exactly which fingerprint facets to read and which findings can block. - guidance: - - Prefer short ordered workflows over broad conceptual lectures. - - Name missing fingerprint grounding or facet coverage plainly without creating a separate fingerprint-change workflow. - evidence: - - path: packages/ghost/src/context/package-review-command.ts - - id: editorial-workbench-docs - kind: visual - pattern: Ghost docs combine restrained editorial explanation with concrete command and schema work surfaces. - applies_to: - scopes: - - docs-site - surface_types: - - docs-home - - docs-foundation - - tool-doc - guidance: - - Keep concepts plain and examples inspectable. - - Avoid oversized marketing composition for reference pages. - check_refs: - - validate.check:component-pages-use-display-scale - evidence: - - path: apps/docs/src/components/docs/page-header.tsx - - path: apps/docs/src/components/docs/component-page-shell.tsx - - id: token-first-interface - kind: visual - pattern: Ghost UI surfaces use semantic tokens for repeatable color and avoid ad hoc surface hex values. - applies_to: - scopes: - - docs-site - - ghost-ui-components - surface_types: - - component-catalogue - - docs-foundation - - docs-home - - primitive-demo - - theme-control - guidance: - - Define color meaning in the token layer before repeating values in components. - - Treat one-off literal colors in UI surfaces as review-worthy drift. - - Using the right token is not enough if hierarchy, disclosure, or operability regresses. - check_refs: - - validate.check:no-hardcoded-surface-hex - evidence: - - path: packages/ghost-ui/src/styles/main.css diff --git a/.ghost/decision.flat-corpus.md b/.ghost/decision.flat-corpus.md new file mode 100644 index 00000000..99b51c5c --- /dev/null +++ b/.ghost/decision.flat-corpus.md @@ -0,0 +1,19 @@ +--- +description: Why the fingerprint is a flat set of prose nodes and not a graph. Gather when tempted to add structure, edges, inheritance, or routing. +materials: + - docs/purposes.md +--- + +Chosen: a flat corpus. A node is one markdown file; its kind is a filename +prefix declared in the glossary; altitude and conditions live in the prose; +`materials` is the single locator field. + +Rejected: the graph model (edges, hubs, spokes), cross-package `extends` and +inherited nodes, the `incarnation` projection axis, check surface routing, +and a JSON schema for the artifact. Each added authoring cost and routing +logic that agents did not need: the agent reading prose against a task +out-performed every mechanical routing layer we built. + +Reversal condition: evidence that agents systematically fail to select the +right nodes from a flat menu at realistic corpus sizes. Until then, structure +proposals are surface sprawl (see `anti-goal.surface-sprawl`). diff --git a/.ghost/glossary.md b/.ghost/glossary.md new file mode 100644 index 00000000..3f2c4ff7 --- /dev/null +++ b/.ghost/glossary.md @@ -0,0 +1,24 @@ +--- +kinds: + - name: principle + - name: anti-goal + posture: guard + - name: decision +--- + +# principle + +Durable stance of the Ghost project: true across the CLI, the skill bundle, +the docs site, and the README unless a narrower condition in the prose limits +it. + +# anti-goal + +What Ghost's own surfaces must never look or sound like: named generic +patterns and rejected neighbors, each stated with its replacement. +Review-critical. + +# decision + +Worked tradeoff trace: what was chosen, what was rejected, why, and what would +reverse it. Gather when tempted to revisit a settled question. diff --git a/.ghost/index.md b/.ghost/index.md new file mode 100644 index 00000000..14edd6b5 --- /dev/null +++ b/.ghost/index.md @@ -0,0 +1,29 @@ +--- +description: Always read first. The non-negotiables for anything written or built for the Ghost project itself. +--- + +This fingerprint covers Ghost's own surfaces: the CLI output, the skill +bundle recipes, the docs site, the README, and changesets. It is Ghost +dogfooding Ghost. + +The non-negotiables: + +- **Plain, precise, restrained, product-minded.** Every shipped sentence + earns its place. No brand-deck filler ("elevate", "delight", "seamless", + "empower"), no hype, no exclamation points. See `principle.voice`. +- **The vocabulary is policed.** `scripts/check-terminology.mjs` bans the + memory-era vocabulary and other retired terms across shipped prose, + including this fingerprint. Use the current names: fingerprint, node, kind, + glossary, corpus, materials, check, gather, pull, pulse, review. +- **Deterministic CLI, interpretive agent.** The CLI never calls an LLM and + never interprets. Anything requiring reading a brand or grading a diff + belongs to the host agent via the skill. See + `principle.byoa-boundary`. +- **The fingerprint shape does not bend to consumers.** Flat corpus, filename + kinds, prose bodies. Any feature that needs the artifact to change shape + for one consumer is a leak. See `docs/purposes.md`. + +Where this fingerprint is silent (visual design of the docs site, vessel's +component aesthetics), proceed from local convention and label the choice +provisional. For anything that changes the public package's shape or +vocabulary, ask a human. diff --git a/.ghost/intent.yml b/.ghost/intent.yml deleted file mode 100644 index 5f52542d..00000000 --- a/.ghost/intent.yml +++ /dev/null @@ -1,140 +0,0 @@ -summary: - product: Ghost - audience: - - OSS maintainers adopting AI-assisted product workflows - - agents generating or reviewing product UI - - Ghost contributors - goals: - - Keep product-surface composition fingerprints repo-local, portable, and easy for agents to read. - - Preserve surface composition across generation, review, and remediation. - - Treat intent, inventory, composition, and validate as sparse package facets. - - Use Git as the staging and approval boundary for fingerprint edits. - anti_goals: - - Treat raw inventory as canonical surface guidance. - - Turn support files into peers of intent, inventory, and composition. - - Turn Ghost into a design-system snapshot or screenshot archive. - - Become a fingerprint lifecycle manager or proposal system. - - Let advisory review block work without deterministic checks. - tradeoffs: - - Prefer compact durable intent over exhaustive surveys. - - Keep validation checks in the fingerprint package without treating them as generation input. - - Preserve OSS-friendly language over company-specific strategy. - tone: - - plain - - precise - - restrained - - product-minded -situations: - - id: capturing-fingerprint - title: Capturing fingerprint facets - user_intent: Create or update the Ghost fingerprint for a project. - product_obligation: Help the agent distinguish sparse fingerprint contributions from optional checks and raw repo signals. - principles: - - intent.principle:fingerprint-folder-is-canonical - - intent.principle:signals-are-authoring-evidence - - intent.principle:sparse-packages-are-patches - experience_contracts: - - intent.experience_contract:git-is-approval-boundary - patterns: - - composition.pattern:sparse-contribution-before-completeness - - id: reviewing-generated-ui - title: Reviewing generated or changed UI - user_intent: Know whether a change preserves the product surface. - product_obligation: Separate deterministic blocking checks from advisory critique. - principles: - - intent.principle:checks-are-enforcement - experience_contracts: - - intent.experience_contract:review-cites-fingerprint-and-diff - patterns: - - composition.pattern:compact-agent-handoff - - id: documenting-ghost - title: Explaining Ghost in public docs - user_intent: Understand the model without internal company context. - product_obligation: Use OSS-safe language and examples that fit many repo shapes. - principles: - - intent.principle:oss-language-is-portable - patterns: - - composition.pattern:editorial-workbench-docs -principles: - - id: fingerprint-folder-is-canonical - principle: fingerprint/ is the portable surface-composition package; intent, inventory, composition, and validate are sparse facets. - guidance: - - Describe the fingerprint as product-surface composition, not as an operational archive. - - Keep durable surface intent, hierarchy, behavior, copy, accessibility, trust, and flow in the appropriate facet files. - - Treat uncommitted or unmerged fingerprint edits as drafts handled by Git, not by a Ghost-specific lifecycle. - evidence: - - path: docs/fingerprint-format.md - note: Public format docs define the split fingerprint folder as the source of truth. - - path: packages/ghost/src/scan/fingerprint-package.ts - note: init writes manifest.yml and starter facet files under fingerprint/. - - id: signals-are-authoring-evidence - principle: Raw repo signals answer what exists; curated inventory points to the building blocks, sources, and precedents an agent can inspect or use. - guidance: - - Use ghost signals as scratch evidence while authoring or refreshing fingerprint facets. - - Curate durable building blocks, files, routes, libraries, assets, source links, notes, and exemplars into inventory.yml. - - Do not let signals or building blocks become surface authority without intent and composition. - evidence: - - path: README.md - note: README frames ghost signals as authoring evidence. - - id: sparse-packages-are-patches - principle: A fingerprint package contributes only the facets it knows; it does not need to restate inherited context. - guidance: - - Treat absent intent, inventory, composition, or validate files as absent local contributions, not automatic incompleteness. - - Use nested packages to add local patches to the broad-to-local stack. - - Let scan report contribution state instead of telling users every package must contain every facet. - evidence: - - path: packages/ghost/src/scan/fingerprint-contribution.ts - - path: docs/fingerprint-format.md - - id: checks-are-enforcement - principle: Deterministic checks live in fingerprint/validate.yml and should cite typed fingerprint refs when they enforce surface-composition rules. - guidance: - - Active checks can block; advisory findings cannot block unless check-backed. - - Prefer typed refs such as composition.pattern:token-first-interface. - - Ungrounded checks may exist, but lint should make their missing grounding visible. - - Checks keep explicit status because gates need lifecycle state. - evidence: - - path: packages/ghost/src/ghost-core/checks/lint.ts - note: Check grounding is validated and missing derivation is reported as a warning. - - id: oss-language-is-portable - principle: Public Ghost docs and generated prompts should work for arbitrary OSS repos without internal strategy language. - guidance: - - Use examples that fit docs sites, dashboards, SaaS apps, games, and component libraries. - - Avoid private company concepts in public docs. - evidence: - - path: docs/fingerprint-format.md - - path: docs/generation-loop.md -experience_contracts: - - id: review-cites-fingerprint-and-diff - contract: Advisory review findings must cite the diff location and the relevant fingerprint refs. - obligations: - - Use active checks only when a finding should block. - - Use missing-fingerprint or experience-gap when the fingerprint cannot support a confident finding. - evidence: - - path: packages/ghost/src/context/package-review-command.ts - note: Emitted review command tells agents what to cite. - - id: git-is-approval-boundary - contract: Fingerprint edits use ordinary Git workflow; checked-in fingerprint/ files are truth. - obligations: - - Do not rewrite canonical fingerprint facets silently during generation or review. - - Treat uncommitted or unmerged fingerprint edits as draft work. - - Record durable surface-composition guidance in intent.yml, inventory.yml, and composition.yml; deterministic gates belong in validate.yml. - evidence: - - path: packages/ghost/src/skill-bundle/references/capture.md - - id: emitted-context-prefers-fingerprint-layers - contract: Emitted context bundles and review commands should prefer split fingerprint facets over legacy survey or markdown artifacts. - obligations: - - Default emit paths load the resolved fingerprint package or stack. - - Legacy direct markdown emit is unsupported for package context. - evidence: - - path: packages/ghost/src/context/entrypoint-markdown.ts - - path: packages/ghost/src/scan-emit-command.ts - - id: interfaces-preserve-operability - contract: Ghost interfaces should preserve operability, readable examples, and responsive access before visual polish. - obligations: - - Preserve keyboard-reachable controls and readable code examples. - - Keep docs and reference content readable on narrow screens. - - Let dense work surfaces collapse controls before hiding primary content. - - Keep advisory review separate from dedicated accessibility audits. - evidence: - - path: docs/generation-loop.md - - path: apps/docs/src/components/docs/component-page-shell.tsx diff --git a/.ghost/inventory.yml b/.ghost/inventory.yml deleted file mode 100644 index 23ad1e9a..00000000 --- a/.ghost/inventory.yml +++ /dev/null @@ -1,90 +0,0 @@ -topology: - scopes: - - id: public-cli - paths: - - packages/ghost/src - surface_types: - - cli-command - - emitted-agent-prompt - - id: skill-bundle - paths: - - packages/ghost/src/skill-bundle - surface_types: - - agent-recipe - - id: docs-site - paths: - - docs - - README.md - - apps/docs - surface_types: - - docs-home - - docs-foundation - - tool-doc - - id: ghost-ui-components - paths: - - packages/ghost-ui - surface_types: - - component-catalogue - - primitive-demo - - theme-control - surface_types: - - agent-recipe - - cli-command - - component-catalogue - - docs-foundation - - docs-home - - emitted-agent-prompt - - primitive-demo - - theme-control - - tool-doc -building_blocks: - tokens: - - semantic color CSS variables - - font-display - - spacing and radius scales - components: - - Button - - CodeBlock - - ComponentPageShell - - PageHeader - libraries: - - shadcn-style registry primitives - - lucide icons - assets: - - CLI manifest JSON - - docs code examples - routes: - - apps/docs/src/app - files: - - README.md - - docs/fingerprint-format.md - - docs/generation-loop.md - - packages/ghost/src/relay.ts - - packages/ghost/src/context/entrypoint.ts - - packages/ghost/src/context/entrypoint-markdown.ts - - packages/ghost/src/context/package-review-command.ts - notes: - - Inventory is replaceable material; intent captures what must remain true and composition captures how material is assembled. - - Correct components or tokens do not prove a surface is aligned. -exemplars: - - id: public-readme-fingerprint-model - path: README.md - title: Public README fingerprint model - surface_type: docs-home - scope: docs-site - note: Public entry point describes split fingerprint facets and sparse contribution state. - why: Shows how Ghost explains repo-local sparse fingerprint facets, curated inventory, raw signals, and Git-reviewed approval. - refs: - - intent.principle:fingerprint-folder-is-canonical - - intent.principle:signals-are-authoring-evidence - - id: review-command-fingerprint-packet - path: packages/ghost/src/context/package-review-command.ts - title: Generated review command - surface_type: emitted-agent-prompt - scope: public-cli - note: Review command is generated from split fingerprint intent/inventory/composition. - why: Shows how Ghost turns fingerprint facets into an agent-facing review instruction. - refs: - - intent.experience_contract:review-cites-fingerprint-and-diff - - composition.pattern:compact-agent-handoff -sources: [] diff --git a/.ghost/principle.byoa-boundary.md b/.ghost/principle.byoa-boundary.md new file mode 100644 index 00000000..462e375c --- /dev/null +++ b/.ghost/principle.byoa-boundary.md @@ -0,0 +1,28 @@ +--- +description: The line between the deterministic CLI and the interpreting agent. Gather when adding or changing any CLI command, flag, or emitted packet. +materials: + - packages/ghost/src/cli.ts + - docs/purposes.md +--- + +Ghost is BYOA: the host agent reads, decides, and writes; the CLI grounds +that work deterministically. Every feature lands on one side of this line. + +The CLI side: validation, the gather menu, node pulls, event tapes, packet +assembly. Repeatable, no LLM, same output for the same input. Its emissions +are evidence for an agent, never verdicts: `ghost review` assembles an +advisory packet; it does not grade the diff. Probes run shell commands and +report output as evidence only. + +The agent side: selecting nodes against a task, interpreting prose, +grading review packets, authoring fingerprints. This lives in the skill +bundle, never in CLI code. + +When a proposed feature needs the CLI to interpret meaning, rank by +relevance beyond mechanical matching, or pass/fail on prose, it belongs in +the skill instead. When a proposed skill step is repeatable and mechanical, +move it into the CLI so agents cannot do it inconsistently. + +A consumer may read the fingerprint through any projection it likes; it may +not change the shape of the fingerprint to suit itself. The shape test lives +in `docs/purposes.md`. diff --git a/.ghost/principle.voice.md b/.ghost/principle.voice.md new file mode 100644 index 00000000..ec82fff6 --- /dev/null +++ b/.ghost/principle.voice.md @@ -0,0 +1,25 @@ +--- +description: How Ghost's own prose sounds. Gather before writing docs, CLI output, README copy, skill recipes, or changesets. +materials: + - README.md + - packages/ghost/src/skill-bundle/references/capture.md +--- + +Ghost's prose is plain, precise, restrained, and product-minded. When +completeness and compactness compete, compactness wins; link out for depth +instead of inlining it. + +Concrete over aspirational: name the decision a truth forces, not the value +it serves. "The CLI does repeatable work with no LLM" beats "we believe in +deterministic tooling." + +Teach terms by example before defining them. A worked node body carries more +than a paragraph about node bodies; the README leads with a real `.ghost/` +listing, not a concept diagram. + +No em dashes in shipped prose. Short sentences, active voice, present tense. +Changesets are one sentence, user-facing, present tense. + +The vocabulary is versioned and enforced: `scripts/check-terminology.mjs` +fails the build on retired terms. When renaming a concept, retire the old +word everywhere in the same change and add it to the forbidden list. diff --git a/.ghost/validate.yml b/.ghost/validate.yml deleted file mode 100644 index e29b445f..00000000 --- a/.ghost/validate.yml +++ /dev/null @@ -1,48 +0,0 @@ -schema: ghost.validate/v1 -id: ghost -checks: - - id: no-hardcoded-surface-hex - title: Prefer semantic color tokens over inline hex in UI surfaces - status: proposed - severity: serious - derivation: - composition: - - composition.pattern:token-first-interface - applies_to: - scopes: - - ghost-ui-components - - docs-site - surface_types: - - component-catalogue - - docs-foundation - - docs-home - detector: - type: forbidden-regex - pattern: '#[0-9a-fA-F]{6,8}' - evidence: - support: 0.9 - observed_count: 1 - examples: - - path: packages/ghost-ui/src/styles/main.css - note: Canonical color values are declared as CSS variables before use. - repair: Move repeatable UI colors into the semantic token layer in packages/ghost-ui/src/styles/main.css. - - id: component-pages-use-display-scale - title: Component catalogue pages keep the editorial display scale - status: proposed - severity: nit - derivation: - composition: - - composition.pattern:editorial-workbench-docs - applies_to: - scopes: - - docs-site - detector: - type: required-regex - pattern: font-display - evidence: - support: 0.88 - observed_count: 4 - examples: - - apps/docs/src/components/docs/page-header.tsx - - apps/docs/src/components/docs/component-page-shell.tsx - repair: Use the existing display heading helpers or `font-display` heading scale instead of local one-off title styling. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 0ba9db25..9ea1a184 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ contact_links: - - name: ❓ Questions and Help 🤔 - url: https://discord.gg/block-opensource (/add your discord channel if applicable) - about: This issue tracker is not for support questions. Please refer to the community for more help. + - name: Questions and discussion + url: https://github.com/block/ghost/discussions + about: Ask questions and discuss Ghost. The issue tracker is for bugs. diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 1fc56ceb..2015495d 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -33,13 +33,13 @@ jobs: - run: pnpm install --frozen-lockfile - name: Build Ghost CLI package - run: pnpm --filter @anarchitecture/ghost build + run: pnpm --filter @design-intelligence/ghost build - name: Build ghost-ui library - run: pnpm --filter ghost-ui build:lib + run: pnpm --filter @design-intelligence/vessel build:lib - name: Build shadcn registry - run: pnpm --filter ghost-ui build:registry + run: pnpm --filter @design-intelligence/vessel build:registry - name: Build docs site (base=/ghost/) env: diff --git a/.github/workflows/release-tarball.yml b/.github/workflows/release-tarball.yml index dcc6806e..14e92143 100644 --- a/.github/workflows/release-tarball.yml +++ b/.github/workflows/release-tarball.yml @@ -1,7 +1,7 @@ name: Publish tarball to GitHub Release # Manual fallback for the tarball distribution channel. Builds a -# package-manager-friendly @anarchitecture/ghost archive with runtime +# package-manager-friendly @design-intelligence/ghost archive with runtime # dependencies included and attaches the .tgz to a GitHub Release. # # The normal path is release.yml, which attaches the tarball automatically on @@ -43,7 +43,7 @@ jobs: - run: pnpm install --frozen-lockfile - name: Build - run: pnpm --filter @anarchitecture/ghost build + run: pnpm --filter @design-intelligence/ghost build # Keep this distribution archive separate from npm publishing: npm gets # the normal package, while GitHub Releases get a self-contained archive @@ -63,7 +63,7 @@ jobs: env: INPUT_VERSION: ${{ inputs.version }} run: | - TAG="anarchitecture-ghost@$INPUT_VERSION" + TAG="design-intelligence-ghost@$INPUT_VERSION" echo "tag=$TAG" >> "$GITHUB_OUTPUT" - name: Create GitHub Release diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 92b3535e..b65ec986 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,7 @@ jobs: - run: pnpm install --frozen-lockfile - - run: pnpm --filter @anarchitecture/ghost build + - run: pnpm --filter @design-intelligence/ghost build - name: Create Release PR or publish id: changesets @@ -51,8 +51,8 @@ jobs: createGithubReleases: false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.GHOST_NPM_PUBLISH_TOKEN }} - NODE_AUTH_TOKEN: ${{ secrets.GHOST_NPM_PUBLISH_TOKEN }} + NPM_TOKEN: ${{ secrets.DESIGN_INTELLIGENCE_NPM_PUBLISH_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.DESIGN_INTELLIGENCE_NPM_PUBLISH_TOKEN }} # Changesets publish emits the published package list and skips versions # already present on npm. Keep GitHub Releases owned here so Homebrew has @@ -67,8 +67,8 @@ jobs: run: | set -euo pipefail VERSION="$(echo "$PUBLISHED_PACKAGES" \ - | python3 -c "import json,sys; pkgs=json.load(sys.stdin); print(next(p['version'] for p in pkgs if p['name']=='@anarchitecture/ghost'))")" - TAG="anarchitecture-ghost@${VERSION}" + | python3 -c "import json,sys; pkgs=json.load(sys.stdin); print(next(p['version'] for p in pkgs if p['name']=='@design-intelligence/ghost'))")" + TAG="design-intelligence-ghost@${VERSION}" mkdir -p dist-tarball node scripts/pack-release-tarball.mjs "$GITHUB_WORKSPACE/dist-tarball" ls -la dist-tarball @@ -78,7 +78,7 @@ jobs: gh release upload "$TAG" dist-tarball/*.tgz --clobber # Export the tag, sha256, and artifact URL so the Homebrew tap can # pin the exact tarball. The packed filename is dynamic - # (anarchitecture-ghost-X.Y.Z.tgz), so resolve it from the staging dir. + # (design-intelligence-ghost-X.Y.Z.tgz), so resolve it from the staging dir. archive="$(ls dist-tarball/*.tgz | head -n 1)" filename="$(basename "$archive")" sha256="$(shasum -a 256 "$archive" | awk '{print $1}')" diff --git a/.gitignore b/.gitignore index b022bb76..0c51af86 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ packages/ghost-ui/.ghost/cache/* # Local Superpowers planning artifacts docs/superpowers/plans/ docs/superpowers/specs/ +notes/ +demo/ diff --git a/CLAUDE.md b/CLAUDE.md index 89dd8174..b4a72c9a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,13 +1,17 @@ # Ghost -Agents can assemble UI. What they cannot reliably preserve is the product -surface composition behind that UI: hierarchy, density, restraint, repetition, -trust, flow, and the choices that make a surface feel intentional. - -Ghost keeps that surface composition in a repo-local `.ghost/` fingerprint package. The public npm shape -is one package, `@anarchitecture/ghost`, with one user-facing bin, `ghost`. -The CLI validates, computes, compares, and emits deterministic packets. The -host agent does the interpretive BYOA work through the installed `ghost` skill. +Agents now do the making — screens, emails, empty states, sentences. What they +cannot reliably preserve is the brand behind that work: the stance, the +density, the restraint, the trust moves, and the choices that make an output +feel intentional. An agent holds nothing it isn't handed. + +Ghost hands it the brand as a portable steering packet: a repo-local `.ghost/` +fingerprint package, a flat corpus of prose nodes read before anything is made. The public npm shape is one package, +`@design-intelligence/ghost`, with one user-facing bin, `ghost`. The CLI +validates the corpus, emits the fingerprint menu, pulls selected nodes, records +local selection events, and assembles advisory review packets from checks. Optional +review checks attach under `.ghost/checks/`. The host agent does all +selection and interpretive BYOA work through the installed `ghost` skill. ## Build & Run @@ -23,103 +27,119 @@ Run the public CLI after building: ```bash node packages/ghost/dist/bin.js -pnpm --filter @anarchitecture/ghost exec ghost +pnpm --filter @design-intelligence/ghost exec ghost ``` ## Architecture Ghost is **BYOA (bring your own agent)**. Claude Code, Codex, Cursor, Goose, or -another host agent reads, decides, and writes. Ghost is the deterministic -calculator the agent reaches for: schema validation, repo-signal helpers, -structural diffs, drift checks, comparison math, and handoff packets. +another host agent reads, decides, and writes. Ghost grounds that work with a +deterministic CLI and an interpretive skill bundle. The CLI does repeatable work +with no LLM: schema and node validation, glossary kind-prefix checks, check +validation, a flat gather menu, selected-node pulls, local pulse summaries, and +review packet assembly. The skill teaches the agent how to author and consume +the fingerprint. -The canonical root `.ghost/` package follows: +The canonical root `.ghost/` package is a flat set of prose nodes plus optional +checks: ```text -manifest.yml -intent.yml -inventory.yml -composition.yml -validate.yml +manifest.yml # schema + id (the package anchor) +glossary.md # the author's category vocabulary + what each kind means +..md # a brand truth of a declared kind (principle.density.md) +.md # an uncategorized brand truth (voice.md) +checks/ # optional review assertions; never a node source ``` -The three root facet files are the core model: - -- `intent.yml` for surface intent. -- `inventory.yml` for curated material, exemplars, and source links. -- `composition.yml` for experience patterns. - -`validate.yml` validates output through deterministic checks; it is not -generation input. -Ordinary Git review is the approval boundary for fingerprint edits. - -Legacy `resources.yml`, `map.md`, `survey.json`, and `patterns.yml` may still -appear in older repos or as migration source material. They are not canonical -fingerprint input for new Ghost work. +The **corpus is flat**. A node is a markdown file: a `description` in +frontmatter (the retrieval payload), optional `materials`, and a brand truth in +the prose body. A node's identity is its filename minus `.md`; its kind is the +filename prefix before the first dot, declared in the glossary. There is no +hierarchy, no inheritance, no edges; nesting into folders is a browsing +convenience only. + +`materials` is the single locator field for concrete materials the truth is +about. It accepts repo-relative paths/globs and absolute HTTPS URLs. Components, +patterns, logos, motion files, illustrations, and external asset libraries all +use the same field. Guidance stays in prose; `materials` only says where the +material is. + +While drafting a body, ask three questions of every truth (drafting prompts, +never fields): **why** (the stance), **with what** (the materials, and pointers +to implementation or assets the agent can inspect), and **how it is assembled** +(the patterns that make the output feel intentional). + +Altitude lives in the prose: a universal truth is stated plainly; a narrower +truth names its **condition**, the situation it applies in, never a filing +destination. `ghost gather` emits the whole menu (every node's id, kind, +description, and material count); the agent selects just-in-time against the +actual task. `ghost pull` emits selected node bodies and materials. `ghost +review` reads a diff, matches touched files to node materials, offers relevant +checks, and emits an advisory packet for the host agent to judge. + +**Checks** (`.ghost/checks/*.md`) are optional review assertions that declare +`references` to fingerprint node ids (with optional heading anchors) and prose +instructions for the reviewing agent. Checks are feed-back only and never leak +into generation context. Scaffold them with `ghost checks init` or `ghost init +--with checks`. Ordinary Git review is the approval boundary for fingerprint +edits and checks. ## Packages | Package | Published? | Description | | --- | --- | --- | -| `packages/ghost` | yes: `@anarchitecture/ghost` | Unified public package. Ships the `ghost` CLI, fingerprint package authoring, checks, advisory review packets, comparison, drift stance verbs, and the unified skill bundle. | -| `packages/ghost-core` | no | Private historical shared package. Runtime code needed by npm is folded into `packages/ghost/src/ghost-core`. | -| `packages/ghost-fleet` | no | Private fleet view across many Ghost bundles. Consumes workspace exports from `@anarchitecture/ghost`. | -| `packages/ghost-ui` | no | Reference design system: shadcn registry plus `ghost-mcp` MCP server. | +| `packages/ghost` | yes: `@design-intelligence/ghost` | The public package. Ships the `ghost` CLI, node authoring, corpus validation, gather/pull/pulse, review packet assembly, and the unified skill bundle. Shared runtime lives in `packages/ghost/src/ghost-core`. | +| `packages/vessel` | no | A standalone shadcn component registry plus `vessel-mcp` MCP server: the opinionated default reference body. Design-system-agnostic; nothing in Ghost requires it. | | `apps/docs` | no | Docs site. | ## CLI Commands +Core workflow: + +| Command | Description | +| --- | --- | +| `ghost init` | Scaffold `.ghost/` with a manifest, starter glossary, and a starter `index.md`. `--with checks` also adds the checks directory. | +| `ghost checks init` | Scaffold `.ghost/checks/` with an example review assertion. | +| `ghost validate` | Validate the package: manifest shape, node validity, material locators, check references, and glossary kind prefixes. | +| `ghost gather [ask…]` | Emit the fingerprint menu for the agent to select from. | +| `ghost pull […]` | Emit selected nodes' bodies and materials; append the selection to the local `.ghost/.events` tape. | +| `ghost review` | Emit an advisory review packet for a diff using material-backed nodes and checks (requires `.ghost/checks/`). | +| `ghost pulse` | Summarize local gather/pull events from `.ghost/.events`. | +| `ghost skill install` | Install the unified `ghost` skill bundle. | + +Advanced/maintenance: + | Command | Description | | --- | --- | -| `ghost init` | Create `.ghost/` with manifest, facets, and deterministic checks. | -| `ghost scan` | Report fingerprint contribution facets and BYOA next-step guidance. | -| `ghost signals` | Emit raw repo signals as JSON for fingerprint authoring. | -| `ghost lint` | Validate a fingerprint package or single artifact. | -| `ghost verify` | Validate fingerprint evidence and exemplar paths, and typed check refs. | -| `ghost describe` | Print direct markdown section ranges. | -| `ghost diff` | Structural direct-fingerprint prose diff between direct fingerprints. | -| `ghost survey ` | Legacy survey helpers for optional `ghost.survey/v1` workflows. | -| `ghost check` | Run active `ghost.validate/v1` deterministic gates against a diff. | -| `ghost review` | Emit an evidence-routed advisory review packet grounded in fingerprint facets, inventory exemplars, checks, and the diff. | -| `ghost compare` | Pairwise or composite comparison over packages or direct fingerprints. | -| `ghost ack` | Record stance toward the tracked fingerprint in `.ghost-sync.json`. | -| `ghost track` | Shift the tracked fingerprint. | -| `ghost diverge` | Declare intentional divergence on a dimension. | -| `ghost emit ` | Emit `review-command`. | -| `ghost skill install` | Install the unified `ghost` agentskills.io bundle. | - -`ghost scan --format json` is deterministic contribution and source-signal state. -It does not run an LLM. +| `ghost manifest` | Emit a self-describing JSON manifest of every command and flag. | ## Public Exports -- `@anarchitecture/ghost` for the combined surface. -- `@anarchitecture/ghost/scan` for scan contribution, source signals, and stack discovery. -- `@anarchitecture/ghost/fingerprint` for fingerprint package authoring, linting, verification, parsing, and serialization. -- `@anarchitecture/ghost/drift` for check/review/compare/stance helpers. -- `@anarchitecture/ghost/core` for shared schemas, types, and loaders. -- `@anarchitecture/ghost/cli` for `buildCli()`. +- `@design-intelligence/ghost` for the combined surface. +- `@design-intelligence/ghost/scan` for package-path resolution helpers. +- `@design-intelligence/ghost/fingerprint` for node package authoring, validation, parsing, and serialization. +- `@design-intelligence/ghost/core` for shared schemas, types, and loaders. +- `@design-intelligence/ghost/cli` for `buildCli()`. ## Environment Variables No API key is required to run Ghost. Optional variables: -- `OPENAI_API_KEY` / `VOYAGE_API_KEY` are consumed only by semantic embedding - helpers when a host opts into enriched comparison. +- `GHOST_PACKAGE_DIR` selects a custom package directory (or pass `--package`). Each CLI auto-loads `.env` and `.env.local` from the working directory. ## Releasing & Changesets -`@anarchitecture/ghost` is the only public package. Private packages are -ignored by Changesets. +`@design-intelligence/ghost` is the only public package. Private packages +are ignored by Changesets. When an agent completes a user-visible change to the public package, write a changeset file instead of asking the user to run `pnpm changeset`: ```markdown --- -"@anarchitecture/ghost": patch +"@design-intelligence/ghost": patch --- One sentence, user-facing, present tense. @@ -132,8 +152,11 @@ Use `patch` for fixes and docs, `minor` for new commands/flags/exports, and - Keep publishable runtime code self-contained in `packages/ghost`; no `workspace:*` runtime dependencies in the packed public artifact. -- The canonical on-disk form is a flat `.ghost/` package. -- Direct `fingerprint.md` remains only for legacy/direct compare workflows. +- The canonical on-disk form is a flat `.ghost/` package: `manifest.yml` plus + `glossary.md` plus prose nodes (`..md` or bare `.md`) plus + an optional `.ghost/checks/` directory. The corpus is flat; kinds come + from filename prefixes declared in the glossary, never from a separate + declaration or a directory hierarchy. - Skill recipes live in `packages/ghost/src/skill-bundle/references/`; install them with `ghost skill install`. - The CLI manifest at `apps/docs/src/generated/cli-manifest.json` is generated diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..a5140d80 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,66 @@ +# Contributing to Ghost + +Ghost is pre-1.0 and moving fast. This doc is organized around what gets a +PR declined, because that's the information you actually need. Everything +below is enforced — by review, by CI, or both. + +## Invariants + +These are project-defining. A PR that violates one gets declined regardless +of quality elsewhere. + +1. **The CLI computes; it never decides.** No LLM calls in the CLI, ever. + Ghost is BYOA: the host agent does all interpretive work. The CLI's value + is determinism — same input, same output, no key required. +2. **The fingerprint corpus stays flat.** No hierarchy, no inheritance, no + edges between nodes. A node's identity is its filename; its kind is a + glossary-declared prefix. Altitude lives in prose, not structure. +3. **Feed-back never leaks into generation context.** Checks and + review packets inform the agent after the fact. They are never a node + source and never enter `gather`/`pull` output. +4. **The published artifact packs self-contained.** No `workspace:*` runtime + dependencies in `packages/ghost`. CI checks the packed tarball. + +## The vocabulary gate + +`scripts/check-terminology.mjs` fails CI on banned phrasings. The script is +the source of truth; these are the clusters and their reasons: + +- **The "memory" compounds.** Ghost holds nothing — an agent holds nothing it + isn't handed. The fingerprint is a steering packet, not recall. +- **The "judg-" words.** The CLI computes; the host agent decides. Review + output is advisory. +- **Product-UI-centric framing.** Ghost is brand through every medium — + screens, emails, empty states, sentences — so phrases that anchor it to + product UI alone are banned. +- **Bare next-major version markers.** No speculative roadmap language in + the tree. + +Run `pnpm check:terminology` locally before pushing; don't try to memorize +the list. + +## The deterministic path + +- pnpm 10+, Node 20.19+ or 22.12+. +- `pnpm install` → `pnpm check` → `pnpm test` → `pnpm build`. CI gates: + biome lint/format, typecheck, file-size, terminology, CLI-manifest drift, + docs frontmatter, packed-tarball checks. +- Added, removed, or renamed a CLI command or flag? Run `pnpm dump:cli-help` + and commit the regenerated manifest, or the drift check declines for you. +- **Changesets:** `@design-intelligence/ghost` is the only public + package. Write the changeset file yourself — `patch` for fixes and docs, + `minor` for new commands/flags/exports, `major` for removed or renamed + public behavior. One sentence, user-facing, present tense. + +## Dogfooding + +Surfaces in this repo carry their own fingerprints: `apps/docs/.ghost` and +`packages/vessel/.ghost`. If you touch a surface, `ghost gather` from its +fingerprint before you build, and expect review against it. This is where +you experience Ghost as a user — treat friction you hit here as a bug worth +reporting. + +## Governance + +This repo follows [Block's org-level governance](https://github.com/block/.github/blob/main/GOVERNANCE.md). +Licensed Apache-2.0. diff --git a/README.md b/README.md index f9a2c89a..4a5d326b 100644 --- a/README.md +++ b/README.md @@ -1,189 +1,195 @@ # Ghost -**Ghost captures the composition of a product surface: the intent behind it, -the materials it draws from, and the patterns that make it feel intentional.** - -Ghost gives AI agents a checked-in product fingerprint they can read before -they generate UI and validate after they change it. The public package is -`@anarchitecture/ghost`, and it installs one CLI: `ghost`. - -Agents can assemble components. What they need help preserving is the product -surface behind those components: hierarchy, density, restraint, behavior, copy, -accessibility, trust, and flow. Ghost keeps that surface composition in a -portable `.ghost/` package that ordinary Git review can approve. - -## The Shape - -The canonical package is intentionally small: +**Ghost is your brand, packed for agents.** A `.ghost/` folder of plain-prose +truths — your stance, your voice, your trust moves — checked into the repo and +read by any agent before it makes anything: a screen, an email, an empty +state, a sentence. ```text .ghost/ - manifest.yml # ghost.fingerprint-package/v1 anchor - intent.yml # surface intent - inventory.yml # curated material and exemplars - composition.yml # patterns, flows, states, and arrangements - validate.yml # optional deterministic gates + glossary.md # your vocabulary + principle.trust.md # "near the moment of payment, reduce felt risk…" + voice.md # how the brand talks + asset.logo.md # points at the actual SVGs ``` -A package can be sparse: it contributes whichever facets are locally true. Generation usually uses intent + inventory + composition: +Today those decisions live in reviewers' heads — "that's not our voice," again, +on every surface. The agent that built the thing never saw them. Ghost writes +them down once, where the agent looks first. -- `intent.yml` says what the surface is trying to do and for whom. -- `inventory.yml` points agents at materials they can inspect or reuse. -- `composition.yml` captures the patterns that make those materials feel like - one intentional product. +One portable packet; Claude Code, Codex, Cursor, and Goose all read the same +one. One package, `@design-intelligence/ghost`. One CLI, `ghost`. -`validate.yml`, nested packages, custom host-wrapper package locations, and raw repo -signals are supporting features. They do not replace curated fingerprint -facets. `ghost signals` answers what exists; curated fingerprint facets answer -what the surface is trying to preserve. +## Thesis -Older `resources.yml`, `map.md`, `survey.json`, `patterns.yml`, and direct -`fingerprint.yml` artifacts can still inform migration workflows, but new Ghost -work should target `.ghost/`. +Agents changed the unit of design work. When they make the screens, the +emails, and the sentences, polishing any one of them moves nothing; the next +generation starts from the model's average again. The work that compounds is +architectural: decide where that average serves, decide where the brand must +win, and put those decisions where the agent reads before it makes. -## Project Status: Beta +Ghost is that artifact: a fingerprint checked into the repo, carrying the +truths, the materials they point at, and the conditions they hold under. +Buttons stay buttons. The moments that carry your brand get your stance +instead of the default. The few author it once. Every agent it travels to +builds from it. -> [!WARNING] -> Ghost is pre-1.0 and under active development. The CLI, fingerprint schema, -> on-disk `.ghost/` package shape, and public JavaScript exports may -> change in breaking ways before a stable 1.0 release. -> -> Breaking changes may ship in minor versions while Ghost is pre-1.0. Patch -> versions are reserved for fixes that should not require migration. If you adopt -> Ghost today, expect some churn, pin the version you depend on, and review -> release notes before upgrading. +[Documentation](https://block.github.io/ghost/) · [npm](https://www.npmjs.com/package/@design-intelligence/ghost) ## Install ```bash -npm install -D @anarchitecture/ghost -npx ghost --help -npx ghost --help --all +npm install -D @design-intelligence/ghost +npx ghost skill install ``` -`ghost --help` shows the core workflow. `ghost --help --all` shows the complete -command index, and each command supports `ghost --help`. +Every `ghost` command is also available as `ghost-fingerprint` when another tool +on your machine owns the `ghost` bin. -Install the BYOA skill bundle so Codex, Claude, Cursor, Goose, or another host -agent knows how to author and use the fingerprint: +## Use It -```bash -npx ghost skill install -# or choose an explicit destination -npx ghost skill install --dest ~/.codex/skills/ghost -``` - -Then ask your agent in plain English: +Ghost is **bring-your-own-agent**. Install the skill bundle so Claude Code, +Codex, Cursor, Goose, or another host agent knows how to author and use the +fingerprint, then ask in plain English: ```text Set up the Ghost fingerprint for this repo. +Write down the decision I keep repeating about checkout. Brief this work from the Ghost fingerprint. -Review this PR against the Ghost fingerprint. -Compare these two Ghost bundles. +Review this diff against the Ghost checks. ``` -## Author A Fingerprint +The CLI does deterministic work. The agent does interpretation. -Ghost authoring is a human-plus-agent workflow. The CLI creates, inspects, and -validates the package; the host agent interviews, reads the repo, drafts facet -edits, and asks you to curate the claims. +## The Loop ```bash -ghost init -ghost init --package product-surface -ghost scan --format json -ghost signals . -ghost lint .ghost -ghost lint product-surface -ghost verify .ghost --root . +ghost init # scaffold .ghost/ with the steering starter (fingerprint only) +ghost checks init # opt in to review assertions +ghost validate # check package shape, nodes, materials, and checks +ghost gather # before building: list every node for this task +ghost pull # read the picked truths' full bodies +ghost review # during review: assemble a diff + matched nodes + checks packet +ghost export # package the fingerprint as a portable artifact with a locator audit +ghost pulse # while tuning: summarize local gather/pull events ``` -Use `--reference` when a reference library should seed inventory, `--scope` -for nested product areas, or `--package ` when initializing an exact -package directory such as `product-surface/`. -For monorepos, `ghost init --monorepo` creates or preserves the root package, -detects workspace child roots, and prints proposed `ghost init --scope ...` -commands by default. Run `ghost init --monorepo --apply` to create the detected -child packages. Host wrappers that need Ghost files somewhere other than -`.ghost` may set `GHOST_PACKAGE_DIR=` on the child `ghost` -process. Exact `--package ` values win over the environment default. +`gather` and `pull` append structured JSONL events to `.ghost/.events`, a gitignored events tape. That's for tuning descriptions and seeing what agents reached +for. The events tape is local tuning signal, not canonical fingerprint state. -Drafted fingerprint edits are just ordinary file changes until Git review -accepts them. Checked-in Ghost facet files are the Ghost source of truth. +## CLI Commands -## Generate From Ghost +| Command | Description | +| --- | --- | +| `ghost init` | Scaffold `.ghost/` with the steering starter: manifest, glossary, `index.md`, and demo nodes for stance, composition, anti-goals, patterns, exemplars, materials, and decisions. `--template minimal` writes only the small manifest/glossary/index starter. `--with checks` also adds the checks directory. | +| `ghost checks init` | Scaffold `.ghost/checks/` with an example review assertion. | +| `ghost validate` | Validate the package: manifest, node validity, material locators, check references, and glossary kind prefixes. | +| `ghost gather [ask…]` | Emit the fingerprint menu for the agent to select from; log the exposed ids. Wild-posture kinds are excluded by default; `--wild` opts in. | +| `ghost pull […]` | Emit selected node bodies and material locators; log selected and missed ids. | +| `ghost review` | Emit an advisory review packet from a diff, matched material-backed nodes, and checks (requires `.ghost/checks/`). | +| `ghost export` | Package the fingerprint as a portable artifact with a locator audit. | +| `ghost pulse` | Summarize local gather/pull events: abandoned gathers, hit rates, cold nodes, and misses. | +| `ghost skill install` | Install the skill bundle for your host agent. | +| `ghost manifest` | Emit a self-describing JSON manifest of commands and flags _(advanced)_. | -Before generating or revising UI, gather the Relay brief for the target path: +Run `ghost --help` for the core workflow, `ghost --help --all` for everything, +and `ghost --help` for flags. -```bash -ghost relay gather apps/checkout/review/page.tsx +## How It Works + +A fingerprint is a small folder of prose. The CLI computes; your agent reads, +writes, and decides. + +```text +.ghost/ + manifest.yml # schema + package id (the anchor) + glossary.md # your kind vocabulary + what each kind means + index.md # the curated front door + principle.trust.md # a brand truth of kind `principle` + asset.logo.md # a truth that may point at concrete materials + checks/ # optional review assertions; never nodes +``` + +The fingerprint is a **flat set of nodes**. A node is one markdown file: a +`description` in frontmatter, optional `materials`, and a brand truth in the +prose body. + +```markdown +--- +description: Logo lockups, clearspace, and when the glyph can stand alone. +materials: + - brand/logo*.svg + - https://figma.com/file/example?node-id=logo-lockups +--- + +Use the full lockup when recognition matters. Use the glyph only when space is +constrained or when brand presence should recede. ``` -Relay compiles selected context from the resolved stack as context hits: -fingerprint refs, why they matched, suggested reads, omissions, and gaps. -The important shift is timing: Ghost gives agents surface-composition context -before they build, not only after a review finds drift. +`materials` is one list of locators for the concrete stuff the truth is about: +repo-relative paths/globs or absolute HTTPS URLs. Components, patterns, logos, +motion files, illustrations, and external asset libraries all use the same field. +Guidance stays in prose; `materials` only says where the material is. -After implementation, run the deterministic and advisory workflows against the -same fingerprint: +**Checks** are optional review assertions in a flat `.ghost/checks/` directory. +Core `ghost init` ships no checks; add them explicitly: ```bash -ghost check --base main -ghost review --base main +ghost checks init ``` -`ghost check` runs active `ghost.validate/v1` gates and can fail. `ghost review` -emits an evidence-routed advisory packet for a human or host adapter to use. +Checks are not nodes. They are review assertions used by `ghost review`: + +```markdown +--- +name: logo-clearspace-holds +description: Logo usage preserves clearspace, lockup integrity, and glyph rules. +severity: medium +references: + - asset.logo +--- + +Grade whether the change preserves the logo guidance in `asset.logo`. +``` + +`ghost gather` and `ghost pull` are feed-forward. `ghost review` is feed-back: it +reads a diff, matches touched files to node `materials`, offers relevant checks, +and emits an advisory packet for the host agent to weigh. + +Reserved at the package root: `manifest.yml`, `glossary.md`, and `checks/`. +Every other `*.md` is a node. Renaming a node changes its id. -## Compare And Govern +The packet is the product; the CLI is the courier. Everything above — +gather, pull, review, checks, the events tape — is machinery around the +fingerprint, and the fingerprint outlives all of it. -Advanced workflows remain available when a repo needs package stacks, -comparison, or explicit drift stance: +## Portable by Design + +The fingerprint travels. It is agent-agnostic (every host agent reads the same +packet), medium-agnostic (the same truths steer a screen, a page, an email, a +sentence), and repo-native (it moves with a clone, a fork, a new hire's first +checkout). When you need it as a standalone artifact: ```bash -ghost stack apps/checkout/review/page.tsx -ghost compare market/.ghost dashboard/.ghost -ghost ack --stance aligned --reason "Initial baseline" -ghost track new-tracked.fingerprint.md -ghost diverge typography --reason "Editorial product uses a different type scale" -ghost emit review-command --path apps/checkout/review/page.tsx +ghost export # package the fingerprint as a portable brand artifact, with a locator audit ``` -`ghost scan --format json` emits deterministic contribution state for `intent`, -`inventory`, `composition`, and `validate`. A sparse package can be useful with -only one contributing facet; absent facets may be inherited from broader stack -context. It does not call an LLM. +The export audits every `materials` locator so the packet doesn't silently +point at things that moved. -## CLI Commands +## Project Status: Beta -| Command | Description | -| --- | --- | -| `ghost init` | Create `.ghost/` package facet files. | -| `ghost scan` | Report sparse fingerprint contribution facets. | -| `ghost lint` | Validate a fingerprint package or individual artifact. | -| `ghost verify` | Validate evidence paths, exemplar paths, and typed check refs. | -| `ghost check` | Run active deterministic gates against a diff. | -| `ghost review` | Emit an evidence-routed advisory packet from fingerprint facets and a diff. | -| `ghost relay gather` | Gather fingerprint-grounded context for an agent target. | -| `ghost emit ` | Emit `review-command` artifacts. | -| `ghost skill install` | Install the unified Ghost skill bundle. | -| `ghost stack` | Inspect resolved root-to-leaf fingerprint stacks. | -| `ghost signals` | Emit raw repo signals as JSON for fingerprint authoring. | -| `ghost describe` | Print markdown section ranges. | -| `ghost compare` | Compare fingerprint packages. | -| `ghost ack` / `track` / `diverge` | Record stance toward tracked drift. | -| `ghost diff` / `survey` | Maintain direct markdown fingerprints or survey/cache files for compatibility workflows. | +> [!WARNING] +> Ghost is pre-1.0 and under active development. The CLI, fingerprint schema, +> on-disk `.ghost/` package shape, and public JavaScript exports may change in +> breaking ways before a stable 1.0 release. ## Repo Layout -Ghost is a pnpm monorepo. The public package is self-contained for npm; private -workspace packages remain development context. - | Path | Role | Published? | | ---- | ---- | --- | -| [`packages/ghost`](./packages/ghost) | Public package. Ships the `ghost` CLI, folded core runtime, fingerprint package helpers, deterministic checks, advisory review packets, comparison/stance helpers, and the unified skill bundle. | yes: `@anarchitecture/ghost` | -| [`packages/ghost-fleet`](./packages/ghost-fleet) | Private fleet view across many Ghost bundles. | no | -| [`packages/ghost-ui`](./packages/ghost-ui) | Reference design system: shadcn registry plus `ghost-mcp` MCP server. | no | +| [`packages/ghost`](./packages/ghost) | The public `ghost` CLI, node authoring, corpus validation, gather/pull, review packet assembly, and the skill bundle. | yes: `@design-intelligence/ghost` | +| [`packages/vessel`](./packages/vessel) | A standalone shadcn component registry plus `vessel-mcp` MCP server. | no | | [`apps/docs`](./apps/docs) | Docs site. | no | ## Development @@ -194,20 +200,10 @@ pnpm build pnpm test pnpm check pnpm dump:cli-help -pnpm --filter @anarchitecture/ghost pack ``` -No API key is required to run Ghost. `OPENAI_API_KEY` / `VOYAGE_API_KEY` are -optional and only used by semantic embedding helpers when a host opts in. +No API key is required to run Ghost. -## Resources +## License -| Resource | Description | -| --- | --- | -| [docs/fingerprint-format.md](./docs/fingerprint-format.md) | Portable `.ghost/` package format. | -| [docs/generation-loop.md](./docs/generation-loop.md) | Brief, generate, check, review, and remediate loop. | -| [docs/language-fingerprints.md](./docs/language-fingerprints.md) | Voice and language capture through existing fingerprint facets. | -| [docs/host-adapters.md](./docs/host-adapters.md) | Adapter-neutral JSON, severity mapping, and custom fingerprint directories. | -| [docs/ghost-fleet.md](./docs/ghost-fleet.md) | Current private fleet package model. | -| [GOVERNANCE.md](./GOVERNANCE.md) | Project governance. | -| [LICENSE](./LICENSE) | Apache License, Version 2.0. | +[Apache License 2.0](./LICENSE) · [Governance](./GOVERNANCE.md) diff --git a/apps/docs/.ghost/.gitignore b/apps/docs/.ghost/.gitignore new file mode 100644 index 00000000..cffd9e8a --- /dev/null +++ b/apps/docs/.ghost/.gitignore @@ -0,0 +1,2 @@ +.events +.pulls diff --git a/apps/docs/.ghost/anti-goal.generated-docs-site.md b/apps/docs/.ghost/anti-goal.generated-docs-site.md new file mode 100644 index 00000000..e5134c6b --- /dev/null +++ b/apps/docs/.ghost/anti-goal.generated-docs-site.md @@ -0,0 +1,28 @@ +--- +description: The generic generated docs and AI-product defaults this site rejects — read before adding any UI, visual section, landing page, or marketing copy. +materials: + - apps/docs/src/app/page.tsx + - apps/docs/src/components/docs/hero.tsx + - apps/docs/src/components/docs/doc-prose.tsx +--- + +Ghost is not the generated AI SaaS docs site. + +Reject these defaults even when they are easy to build: + +- Gradient hero text, purple/blue glows, aurora backgrounds, particle fields, + blurred blobs, and "AI sparkle" ornament. +- Rounded-xl feature-card grids on gray-50 with three benefit icons and a fake + dashboard screenshot. +- Mascots, emoji headings, playful empty-state illustrations, or robot metaphors. +- Overpromising copy: "ship on-brand every time," "brand autopilot," "AI that + understands your design system," or any claim that makes Ghost sound like it + replaces taste, review, or human curation. +- Decorative motion that exists only because the page felt static. +- Dense nav chrome, sidebars on landing pages, or tool-index pages that feel like + enterprise documentation portals. + +A technically correct output can still be off-brand if it looks like any AI tool +could ship it. Ghost's docs win by being severe, specific, and a little haunted: +black-and-white, exact language, spectral geometry, and enough restraint that the +one strange gesture actually lands. diff --git a/apps/docs/.ghost/asset.docs-materials.md b/apps/docs/.ghost/asset.docs-materials.md new file mode 100644 index 00000000..c2595c21 --- /dev/null +++ b/apps/docs/.ghost/asset.docs-materials.md @@ -0,0 +1,43 @@ +--- +description: Concrete docs-site materials — inspect before inventing tokens, components, typography, navigation, motion, routes, or command examples. +materials: + - apps/docs/src/App.tsx + - apps/docs/src/main.tsx + - apps/docs/src/styles/dev-fonts.css + - apps/docs/src/components/docs/** + - apps/docs/src/app/**/*.tsx + - apps/docs/src/content/docs/*.mdx + - apps/docs/src/generated/cli-manifest.json + - packages/vessel/src/styles/main.css + - packages/vessel/src/components/** +--- + +Do not invent docs-site vocabulary before inspecting the materials already in +place. + +Material contract: + +- **Tokens and primitives** come from `@design-intelligence/vessel/styles.css`, + backed by `packages/vessel/src/styles/main.css`. Author with semantic roles + (`bg-background`, `text-foreground`, `text-muted-foreground`, `border-border`, + `bg-card`) and the named docs typography variables (`--heading-*`, + `--label-*`). Avoid raw palette utilities unless they are already part of a + documented semantic exception. +- **Fonts** are overridden for the docs dev surface in + `apps/docs/src/styles/dev-fonts.css`; `font-display` and `font-sans` resolve to + Cash Sans locally. Preserve the uppercase label and black display-type rhythm. +- **Navigation** is the bottom floating `Dock`. New top nav, side nav, or + secondary persistent chrome should be treated as a product decision, not a + routine addition. +- **Page structure** lives in `AnimatedPageHeader`, `SectionWrapper`, + `DocsPageLayout`, `DocSection`, and `DocProse`. Use these before making a new + layout primitive. +- **Docs content** is MDX under `apps/docs/src/content/docs/` with frontmatter + wired through the docs manifest and routes. Do not hard-code a one-off article + route unless the content model cannot express it. +- **CLI examples** should be checked against `apps/docs/src/generated/cli-manifest.json` + or regenerated with `pnpm dump:cli-help` after CLI command/flag changes. + +The materials locate facts; this node does not make every existing choice a +brand truth. If a component repeats a weak or legacy pattern, fix the pattern +instead of canonizing it here. diff --git a/apps/docs/.ghost/checks/cli-examples-match-manifest.md b/apps/docs/.ghost/checks/cli-examples-match-manifest.md new file mode 100644 index 00000000..bc938bcd --- /dev/null +++ b/apps/docs/.ghost/checks/cli-examples-match-manifest.md @@ -0,0 +1,16 @@ +--- +name: cli-examples-match-manifest +description: CLI examples and generated docs stay synchronized with the real Ghost command surface. +severity: high +references: + - condition.cli-reference-exactness + - asset.docs-materials +--- + +When a change touches CLI docs, generated command help, command implementation, +or examples in MDX, verify that documented command names and flags exist in the +current CLI manifest or command help. If command metadata changed, require +`pnpm dump:cli-help` so `apps/docs/src/generated/cli-manifest.json` is updated. + +Flag speculative flags, obsolete command names, or examples that describe a skill +workflow as though it were a CLI command. diff --git a/apps/docs/.ghost/checks/no-generic-ai-ornament.md b/apps/docs/.ghost/checks/no-generic-ai-ornament.md new file mode 100644 index 00000000..f8bafddb --- /dev/null +++ b/apps/docs/.ghost/checks/no-generic-ai-ornament.md @@ -0,0 +1,18 @@ +--- +name: no-generic-ai-ornament +description: Docs UI avoids generic AI SaaS ornament and preserves Ghost's restrained monochrome visual stance. +severity: medium +references: + - anti-goal.generated-docs-site + - principle.visual-composition +--- + +Review changes to docs UI surfaces for generic AI-product decoration. Flag newly +introduced gradient hero text, purple or blue glows, aurora backgrounds, +particle fields, blurred blobs, emoji headings, mascot or robot metaphors, fake +product screenshots, or decorative motion that does not clarify reading order or +state. + +This check should not block legitimate semantic color in docs prose or existing +Vessel component behavior. The issue is generic ornament that weakens the severe, +monochrome, typographic Ghost stance. diff --git a/apps/docs/.ghost/checks/review-stays-advisory.md b/apps/docs/.ghost/checks/review-stays-advisory.md new file mode 100644 index 00000000..66f16490 --- /dev/null +++ b/apps/docs/.ghost/checks/review-stays-advisory.md @@ -0,0 +1,16 @@ +--- +name: review-stays-advisory +description: Docs keep checks and review positioned as feed-back advisory context, never deterministic brand verdict or generation input. +severity: high +references: + - principle.product-model + - decision.feed-forward-over-review +--- + +Review docs copy for claims that Ghost review grades, approves, blocks, judges, +or guarantees brand fit. Flag wording that treats checks as generation input or +turns advisory review packets into CI gates. + +Accept wording that says checks are optional deterministic assertions, review +assembles packets, host agents judge, and teams may choose to enforce separate +CI around their own deterministic checks. diff --git a/apps/docs/.ghost/condition.cli-reference-exactness.md b/apps/docs/.ghost/condition.cli-reference-exactness.md new file mode 100644 index 00000000..ee83923d --- /dev/null +++ b/apps/docs/.ghost/condition.cli-reference-exactness.md @@ -0,0 +1,26 @@ +--- +description: CLI exactness condition — gather when editing command docs, generated CLI help, examples, flags, exit codes, or install instructions. +materials: + - apps/docs/src/content/docs/cli-reference.mdx + - apps/docs/src/generated/cli-manifest.json + - packages/ghost/src/commands/** + - scripts/dump-cli-help.mjs +--- + +This condition applies whenever docs mention command names, flags, exit codes, +JSON shape, install commands, or generated help output. + +When it applies: + +- Treat the CLI as the source of truth. Check `ghost --help`, command-specific + help, or `apps/docs/src/generated/cli-manifest.json` before editing examples. +- If a command or flag changed, run `pnpm dump:cli-help` so the docs manifest + matches the CLI. +- Keep examples minimal and copy-pastable. Prefer one direct command over a + shell story with hidden setup. +- Do not document speculative flags, adapter behavior, or workflow aliases that + are only in the skill. If it is not in the CLI, call it an agent workflow, not + a command. + +This condition is narrower than the general docs voice. It optimizes for exact +mechanics over rhetorical smoothness. diff --git a/apps/docs/.ghost/decision.feed-forward-over-review.md b/apps/docs/.ghost/decision.feed-forward-over-review.md new file mode 100644 index 00000000..ff0feae8 --- /dev/null +++ b/apps/docs/.ghost/decision.feed-forward-over-review.md @@ -0,0 +1,31 @@ +--- +description: Tradeoff behind leading with gather/pull before review — gather when docs positioning could overemphasize drift, checks, gates, or scoring. +materials: + - apps/docs/src/content/docs/getting-started.mdx + - apps/docs/src/content/docs/checks-and-review.mdx + - apps/docs/src/app/tools/scan/page.tsx + - apps/docs/src/app/tools/drift/page.tsx +--- + +Decision trace: Ghost could have led with review because drift detection is easy +to understand. We choose feed-forward authoring and recall as the center because +that is the product's real leverage: the agent should receive the decision before +it builds. + +What review is good for: + +- It makes drift visible after a diff. +- It routes changed files to material-backed nodes and checks. +- It gives a host agent an advisory packet for critique. + +Why review does not lead: + +- If the right truth was never gathered, review catches the failure late. +- Calling review a gate makes Ghost sound like it judges brand fit + deterministically, which it does not. +- Teams adopt faster when the first win is one repeated decision written down and + reused before generation. + +The decision reverses only for a page whose explicit job is `ghost review`, the +checks directory, or CI-style integration. Even there, repeat the boundary: review is +feed-back and advisory; checks do not leak into generation context. diff --git a/apps/docs/.ghost/exemplar.home-thesis.md b/apps/docs/.ghost/exemplar.home-thesis.md new file mode 100644 index 00000000..4446c24b --- /dev/null +++ b/apps/docs/.ghost/exemplar.home-thesis.md @@ -0,0 +1,30 @@ +--- +description: Annotated home-page thesis exemplar — match this form when writing high-level Ghost narrative or landing copy. +materials: + - apps/docs/src/app/page.tsx + - apps/docs/src/components/docs/hero.tsx +--- + +The current home page is normative for argument shape, restraint, and visual +pace. + +What to match: + +- **Tiny hero, huge word.** The hero does not explain the whole product. It says + "Ghost" at wordmark scale and gives one sentence of context. That restraint is + the brand move. +- **Editorial thesis cadence.** The thesis unfolds in paragraphs, not a grid of + benefits. It trusts the reader to follow a serious idea. +- **Mechanics over adjectives.** The copy names concrete mechanics — flat corpus, + `gather`, `pull`, `review`, Git approval — instead of claiming the product is + simple, powerful, or magical. +- **Selective emphasis.** Foreground text highlights only the load-bearing model + phrase. Do not bold every important sentence. +- **Haunted restraint.** The concentric circles are spectral and low-opacity; + they make the page feel like Ghost without becoming decoration the prose must + fight. + +Do not copy incidentals: the exact paragraph count, current CLI ordering, and the +word "UI" in the opening line can change as the product positioning evolves. +Preserve the structure: one stark sign, one serious argument, then routes into +the docs. diff --git a/apps/docs/.ghost/glossary.md b/apps/docs/.ghost/glossary.md new file mode 100644 index 00000000..cad2d372 --- /dev/null +++ b/apps/docs/.ghost/glossary.md @@ -0,0 +1,53 @@ +--- +kinds: + - name: principle + - name: condition + - name: pattern + - name: exemplar + - name: anti-goal + - name: asset + - name: decision + - name: voice +--- + +# principle + +Durable stance, tradeoff, or invariant. Principles are always-on unless a +narrower condition explicitly limits them; patterns may narrow principles, never +loosen them. + +# condition + +Situational truth. Use only when the stated situation holds, and do not treat the +condition as a destination bucket. + +# pattern + +Reusable page, component, motion, or content composition. A pattern says when it +applies, what is bound, what is open, and which principle it refines. + +# exemplar + +Concrete reference for form, rhythm, quality, code shape, voice, or behavior. +Match the annotated qualities; do not copy incidental details. + +# anti-goal + +Rejected default, neighboring style, generic generated pattern, or plausible +wrong answer. Always-on like a principle, but phrased as the thing to steer away +from. + +# asset + +Material truth about concrete tokens, components, type, motion, canvases, docs, +copy, code, or files. `materials` locates; prose explains what the files mean. + +# decision + +Worked tradeoff trace: what was chosen, what was rejected, why, and when that +choice would reverse. + +# voice + +Language and naming truth: the product vocabulary, cadence, metaphor, and copy +boundaries that make the docs sound like Ghost rather than generic SaaS docs. diff --git a/apps/docs/.ghost/index.md b/apps/docs/.ghost/index.md new file mode 100644 index 00000000..ce3b50ba --- /dev/null +++ b/apps/docs/.ghost/index.md @@ -0,0 +1,53 @@ +--- +description: Always read first for docs-site work — non-negotiables, coverage, and silence posture for the Ghost docs surface. +materials: + - apps/docs/src/app/page.tsx + - apps/docs/src/content/docs/*.mdx + - apps/docs/src/components/docs/** +--- + +This fingerprint governs the Ghost docs site: the landing page, documentation +index, tool landings, MDX docs pages, and the small components that carry them. +It does not govern Vessel as a reference component registry; Vessel has its own +fingerprint under `packages/vessel/.ghost/`. When the docs consume Vessel +materials, this fingerprint decides the docs' product stance and Vessel decides +the component-system contract. + +## Non-negotiables + +- Ghost is **brand context for agents**, not a component library, lifecycle + manager, design archive, or autonomous judge. Keep the docs centered on the + feed-forward act: the agent reads repo-local brand truth before it builds. +- Preserve the flat corpus model: `.ghost/` is a package of prose nodes; + `manifest.yml`, `glossary.md`, and `checks/` are reserved; everything else is + a node whose id comes from its filename. No hierarchy, inheritance, graph, or + edge language. +- The page should feel like a serious tool, not a SaaS explainer template: + monochrome, restrained, typographic, with precise motion and only one + memorable visual gesture at a time. +- Concrete command names matter. Use `ghost init`, `ghost validate`, + `ghost gather`, `ghost pull`, `ghost pulse`, `ghost checks init`, and + `ghost review` exactly unless the CLI changes and the generated manifest has + been updated. +- Do not let optional review language obscure the boundary: checks and review + are feed-back, advisory, and never generation input. + +## How to read the corpus + +Read `principle.product-model`, `principle.visual-composition`, and +`voice.docs-language` for broad docs work. Pull `asset.docs-materials` before +changing UI, tokens, routes, MDX layouts, or command examples. Pull +`pattern.docs-index-card-grid` for card-index pages and `pattern.doc-article` +for MDX documentation pages. Pull `anti-goal.generated-docs-site` before any new +visual or marketing surface. + +The `decision.*` nodes explain tradeoffs; they are not permanent rules unless a +principle or pattern repeats them. `exemplar.*` nodes show how an existing page +pulls off the stance; match the annotated qualities, not every literal detail. + +## Silence posture + +When this fingerprint is silent, proceed provisionally from nearby docs pages and +Vessel's token/component contract for routine implementation. Ask before +changing product model vocabulary, introducing new visual metaphors, adding a new +agent workflow, or making the docs sound more like marketing than instruction. diff --git a/packages/ghost-ui/.ghost/manifest.yml b/apps/docs/.ghost/manifest.yml similarity index 74% rename from packages/ghost-ui/.ghost/manifest.yml rename to apps/docs/.ghost/manifest.yml index d7193e3e..22e030bc 100644 --- a/packages/ghost-ui/.ghost/manifest.yml +++ b/apps/docs/.ghost/manifest.yml @@ -1,2 +1,2 @@ schema: ghost.fingerprint-package/v1 -id: ghost-ui +id: local diff --git a/apps/docs/.ghost/pattern.doc-article.md b/apps/docs/.ghost/pattern.doc-article.md new file mode 100644 index 00000000..7d0b52a0 --- /dev/null +++ b/apps/docs/.ghost/pattern.doc-article.md @@ -0,0 +1,39 @@ +--- +description: MDX documentation article structure — use for guide pages, conceptual docs, CLI docs, authoring docs, and checks/review docs. +materials: + - apps/docs/src/content/docs/*.mdx + - apps/docs/src/components/docs/docs-page-layout.tsx + - apps/docs/src/components/docs/doc-prose.tsx + - apps/docs/src/mdx-components.tsx +--- + +This pattern applies when the surface teaches a workflow or model in MDX. + +**Bound:** + +- The page is organized as `DocSection` rows, not a freeform prose blob. Section + titles sit in the left column on large screens; the content column carries the + explanation. +- Each section should answer one job: problem, action, model, validation, or + caveat. Do not make section titles decorative. +- Code examples are short and runnable-looking. Prefer exact commands over + pseudo-code; if a command is illustrative, say so in prose. +- Frontmatter carries the route-level promise: title, description, kicker, + section, order, slug. The visible body should satisfy that promise quickly. +- `Callout` is reserved for adoption shortcuts, beta caveats, warnings, or + boundaries that change user behavior. It is not a decoration block. +- Long conceptual paragraphs are allowed, but every abstract claim should be + anchored soon after with a filename, command, or node example. + +**Open:** + +- A page may start with a first-win shortcut when the full model is too heavy for + a new user. +- Tables are appropriate for matrices, command summaries, and property + definitions; lists are better for workflow steps and invariants. +- Exact section order may vary, but the path should move from user's pain to + concrete action before deep model explanation. + +**Refines:** `principle.product-model`, `principle.visual-composition`, and +`voice.docs-language`. If an article explains the schema accurately but does not +make the user's next agent instruction obvious, it has missed the docs product. diff --git a/apps/docs/.ghost/pattern.docs-index-card-grid.md b/apps/docs/.ghost/pattern.docs-index-card-grid.md new file mode 100644 index 00000000..13a73cd2 --- /dev/null +++ b/apps/docs/.ghost/pattern.docs-index-card-grid.md @@ -0,0 +1,39 @@ +--- +description: Docs and tool index card grids — use for /docs, /tools, and per-tool landing pages that route users to a small set of next reads. +materials: + - apps/docs/src/app/docs/page.tsx + - apps/docs/src/app/tools/page.tsx + - apps/docs/src/app/tools/scan/page.tsx + - apps/docs/src/app/tools/drift/page.tsx + - apps/docs/src/components/docs/animated-page-header.tsx +--- + +This pattern applies when a page is a routing surface: it names a section of the +product and offers a small set of next reads or tools. + +**Bound:** + +- Start with `AnimatedPageHeader`: kicker, blunt title, one sentence of routing + context, and the short horizontal rule. +- Use a low-count grid. Two or three columns are enough; if the page needs more + than five cards, reconsider the information architecture before adding visual + density. +- Cards stay quiet by default: border-card, card background, muted icon, compact + title, one short description. The hover state can darken the border and invert + a title underline, but it should not become a whole animated tile. +- Card copy explains the job of the destination, not the feature in abstract. + Prefer "Emit the fingerprint menu with gather" over "Powerful context + discovery." +- Icons are thin-line Lucide symbols at the existing sizes and stroke widths. + They support scanning; they are not illustrations. + +**Open:** + +- Grid cardinality and card ordering may change with the docs IA. +- The exact icon can change when it makes the destination easier to recognize. +- A tool page may use a tighter chip strip instead of large cards when the + choices are secondary. + +**Refines:** `principle.visual-composition` and `voice.docs-language`. If a +proposed card grid needs bright accents, screenshots, badges, or paragraph-long +blurbs to feel useful, the content structure is wrong. diff --git a/apps/docs/.ghost/pattern.landing-thesis.md b/apps/docs/.ghost/pattern.landing-thesis.md new file mode 100644 index 00000000..57fb5a8e --- /dev/null +++ b/apps/docs/.ghost/pattern.landing-thesis.md @@ -0,0 +1,34 @@ +--- +description: Home-page thesis structure — use when editing the landing page, hero, thesis section, or product narrative above the docs index. +materials: + - apps/docs/src/app/page.tsx + - apps/docs/src/components/docs/hero.tsx + - apps/docs/src/components/docs/cycloid-canvas.tsx +--- + +The home page is an argument, not a feature tour. It should make one memorable +claim about why Ghost exists and then let the docs carry the details. + +**Bound:** + +- Hero: one wordmark-scale title, one restrained sentence. The ghost rings can + supply atmosphere; do not add a second hero illustration or product screenshot. +- Thesis: centered longform column around `62ch`, muted body copy, with only a + few foreground highlights for key model words. The rhythm is editorial, not + sales-led. +- The story moves from problem to model to loop to payoff: agents can assemble + UI, but not preserve brand truth; Ghost captures flat prose nodes; the agent + gathers and pulls them; review makes drift visible. +- Lists should clarify the model. If a list reads like benefits marketing, + rewrite it as artifacts and mechanics. +- End with a transfer claim: a brand truth that cannot be recalled or reviewed + against cannot be delegated. + +**Open:** + +- The exact thesis paragraphs may evolve with the product language. +- A single additional visual system can be introduced only if it sharpens the + argument and displaces an existing gesture rather than stacking on top. + +**Refines:** `principle.product-model`, `principle.visual-composition`, and +`voice.docs-language`. diff --git a/apps/docs/.ghost/principle.product-model.md b/apps/docs/.ghost/principle.product-model.md new file mode 100644 index 00000000..33d1ab02 --- /dev/null +++ b/apps/docs/.ghost/principle.product-model.md @@ -0,0 +1,34 @@ +--- +description: Core Ghost product model — gather for docs copy, IA, onboarding, diagrams, workflow explanations, or any statement of what Ghost is. +materials: + - apps/docs/src/app/page.tsx + - apps/docs/src/content/docs/getting-started.mdx + - apps/docs/src/content/docs/fingerprint-authoring.mdx + - apps/docs/src/content/docs/checks-and-review.mdx + - packages/ghost/src/commands/** +--- + +Ghost is a small deterministic layer around an interpretive human-agent loop. +The docs should keep that model crisp: + +- **Feed-forward first.** Ghost helps the agent read the right repo-local brand + truths before it builds. Review is useful, but it is the second half of the + loop, not the headline. +- **BYOA, not an autonomous designer.** The host agent reads, selects, writes, + and judges. The CLI performs repeatable work: scaffold, validate, gather the + menu, pull selected nodes, summarize local events, and assemble advisory + review packets. +- **Flat node corpus.** A fingerprint is a flat `.ghost/` package of markdown + prose nodes. Kinds come from filename prefixes declared in `glossary.md`. + Altitude lives in prose; narrower truths name their condition. Do not describe + folders, inheritance, edge traversal, or schema fields as the conceptual model. +- **Prose is executable context only through use.** A node steers because an + agent can find it, read it, and manifest it. Keep retrieval handles and command + examples close to abstract claims. +- **Git is the approval boundary.** Uncommitted fingerprint edits are drafts; + checked-in node prose is canonical through normal review. + +When the docs must choose between theoretical completeness and a simple first +win, the first win wins. The canonical onboarding story is: write the decision +you keep repeating once, put it in `.ghost/`, gather it before generation, and +review drift after the diff. diff --git a/apps/docs/.ghost/principle.visual-composition.md b/apps/docs/.ghost/principle.visual-composition.md new file mode 100644 index 00000000..39b52795 --- /dev/null +++ b/apps/docs/.ghost/principle.visual-composition.md @@ -0,0 +1,38 @@ +--- +description: Visual composition floor for the docs site — gather before changing landing pages, headers, cards, navigation, motion, or layout rhythm. +materials: + - apps/docs/src/app/page.tsx + - apps/docs/src/app/docs/page.tsx + - apps/docs/src/app/tools/**/*.tsx + - apps/docs/src/components/docs/** + - packages/vessel/src/styles/main.css +--- + +The Ghost docs site should render like a stark technical artifact with one +controlled spectral move, not a generic docs template. + +Hard floor: + +- **Monochrome carries authority.** Default to background, foreground, muted, + border, and card roles. Color is rare and semantic; never invent a product + accent for excitement. +- **Typography is the hero.** Large display type, tight tracking, uppercase + kickers, and generous line-height do most of the branding. If a page needs + impact, increase type hierarchy or negative space before adding illustration. +- **One memorable visual gesture per surface.** The landing page can have the + concentric ghost rings. A docs index can have card underlines. A prose page can + have sticky section labels. Do not stack rings, gradients, decorative blobs, + screenshots, and animated cards on the same surface. +- **Flat before elevated.** Reach for whitespace, alignment, rule lines, and + border-card before shadows or heavy containers. The floating dock is the main + elevated object; new elevation must earn its presence. +- **Motion reveals structure.** Use motion to stage reading order or clarify a + state change. Avoid ambient decoration, bounce, springiness, or motion that + competes with the text. +- **Density is editorial.** Docs pages should feel sparse at the frame level but + precise inside the prose. Long text belongs in the MDX article system; landing + pages should have short thesis blocks and strong scannable routes. + +When a pattern conflicts with this floor, the floor wins and the pattern is +wrong. When Vessel tokens make a choice available but this floor rejects the +output, choose the docs fingerprint. diff --git a/apps/docs/.ghost/voice.docs-language.md b/apps/docs/.ghost/voice.docs-language.md new file mode 100644 index 00000000..acf947b9 --- /dev/null +++ b/apps/docs/.ghost/voice.docs-language.md @@ -0,0 +1,41 @@ +--- +description: Ghost docs voice and vocabulary — gather before writing docs copy, headings, onboarding text, CLI examples, or product explanations. +materials: + - apps/docs/src/content/docs/*.mdx + - apps/docs/src/app/page.tsx + - apps/docs/src/app/docs/page.tsx + - apps/docs/src/app/tools/**/*.tsx +--- + +Ghost docs should sound like an opinionated tool builder explaining a sharp +model, not like a launch page selling a platform. + +Voice rules: + +- Lead with the user's repeated pain: the same review comment, the same drift, + the same missing decision. Then show the small move Ghost makes possible. +- Prefer short declarative sentences around the model: "The CLI does the + deterministic work; your agent does the interpretation." Do not bury the + boundary in hedging. +- Use concrete artifact names: `.ghost/`, `manifest.yml`, `glossary.md`, + `index.md`, `checks/`, `ghost gather`, `ghost pull`. The docs earn trust by + naming the files and commands agents actually touch. +- Say **brand truth**, **fingerprint**, **node**, **kind**, **materials**, + **feed-forward**, **feed-back**, and **advisory review packet** + consistently. Do not introduce synonyms such as brand DNA, style cache, + design brain, magic layer, or guardrail engine. +- Explain by contrast: feed-forward versus feed-back, deterministic CLI versus + interpretive agent, flat corpus versus traversal, testimony versus truth, + draft versus canonical. +- Keep the claim plain when the idea is abstract. A good Ghost sentence should + make a wrong implementation less likely, not merely sound clever. + +Copy anti-patterns: + +- No "unlock," "supercharge," "seamless," "delightful," "AI-powered," or + "world-class" filler. +- No exclamation points in instructional copy. +- No anthropomorphizing Ghost as the judge or designer. The agent judges; Ghost + assembles context and packets. +- No broad promises that Ghost preserves a whole brand automatically. It only + preserves what the fingerprint makes selectable, readable, and reviewable. diff --git a/apps/docs/README.md b/apps/docs/README.md index 617caf02..c3a3d0c4 100644 --- a/apps/docs/README.md +++ b/apps/docs/README.md @@ -2,7 +2,7 @@ **Documentation site for the Ghost project.** -`ghost-docs` is the deployed docs for everything in this monorepo: the `ghost` CLI, the fingerprint package format, the generation loop, and the live `ghost-ui` component catalogue. A Vite + MDX app that consumes [`ghost-ui`](../../packages/ghost-ui) as a workspace dependency. +`ghost-docs` is the deployed docs for everything in this monorepo: the `ghost` CLI, the fingerprint package format, the generation loop, and the live `vessel` component catalogue. A Vite + MDX app that consumes [`vessel`](../../packages/vessel) as a workspace dependency. ## Run diff --git a/apps/docs/package.json b/apps/docs/package.json index 56ea5b35..ffbca9dd 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -10,7 +10,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "ghost-ui": "workspace:*", + "@design-intelligence/vessel": "workspace:*", "@hookform/resolvers": "^5.2.2", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-alert-dialog": "^1.1.15", diff --git a/apps/docs/src/App.tsx b/apps/docs/src/App.tsx index cb3515a5..23bc35da 100644 --- a/apps/docs/src/App.tsx +++ b/apps/docs/src/App.tsx @@ -1,27 +1,14 @@ -import { ThemeProvider } from "ghost-ui"; +import { ThemeProvider } from "@design-intelligence/vessel"; import { useEffect } from "react"; -import { Navigate, Route, Routes, useLocation, useParams } from "react-router"; +import { Navigate, Route, Routes, useLocation } from "react-router"; import DocsIndex from "@/app/docs/page"; import HomePage from "@/app/page"; import GhostDriftLanding from "@/app/tools/drift/page"; -import GhostFleetLanding from "@/app/tools/fleet/page"; import ToolsIndex from "@/app/tools/page"; import GhostScanLanding from "@/app/tools/scan/page"; -import GhostUiLanding from "@/app/tools/ui/page"; -import ComponentPage from "@/app/ui/components/[name]/page"; -import ComponentsIndex from "@/app/ui/components/page"; -import ColorsPage from "@/app/ui/foundations/colors/page"; -import FoundationsIndex from "@/app/ui/foundations/page"; -import TypographyPage from "@/app/ui/foundations/typography/page"; -import DesignLanguageIndex from "@/app/ui/page"; import { Dock } from "@/components/docs/dock"; import { mdxDocsRoutes } from "@/routes/docs-routes"; -function ComponentRedirect() { - const { name } = useParams<{ name: string }>(); - return ; -} - function ScrollToHash() { const { hash, pathname } = useLocation(); @@ -51,7 +38,7 @@ export function App() { } /> - {/* Tools — four-card index plus per-tool landings */} + {/* Tools: four-card index plus per-tool landings */} } /> } /> } /> - } /> - } /> {/* Cross-tool docs hub */} } /> @@ -74,17 +59,6 @@ export function App() { {/* MDX-authored doc pages under /docs/* */} {mdxDocsRoutes()} - {/* Design Language (ghost-ui catalogue) */} - } /> - } /> - } /> - } - /> - } /> - } /> - {/* Redirects from the previous /tools/drift/{getting-started,cli} URLs */} } /> - - {/* Redirects from legacy root /foundations and /components URLs */} - } - /> - } - /> - } - /> - } - /> - } /> diff --git a/apps/docs/src/app/docs/page.tsx b/apps/docs/src/app/docs/page.tsx index 2bf96ca0..78624df5 100644 --- a/apps/docs/src/app/docs/page.tsx +++ b/apps/docs/src/app/docs/page.tsx @@ -1,7 +1,7 @@ "use client"; -import { useStaggerReveal } from "ghost-ui"; -import { BookOpen, Rocket } from "lucide-react"; +import { useStaggerReveal } from "@design-intelligence/vessel"; +import { BookOpen, FileText, Rocket, ShieldCheck, Zap } from "lucide-react"; import type { ReactNode } from "react"; import { Link } from "react-router"; import { AnimatedPageHeader } from "@/components/docs/animated-page-header"; @@ -13,6 +13,13 @@ const sections: { description: string; icon: ReactNode; }[] = [ + { + name: "Five-Minute Ghost", + href: "/docs/quickstart", + description: + "Write down the one decision you keep repeating, once, and let your agent read it before it builds.", + icon: , + }, { name: "Getting Started", href: "/docs/getting-started", @@ -20,11 +27,25 @@ const sections: { "Install Ghost, set up the repo fingerprint, and learn the loop around .ghost.", icon: , }, + { + name: "Fingerprint Authoring", + href: "/docs/fingerprint-authoring", + description: + "Co-author flat prose nodes that steer generation, with kinds from the glossary.", + icon: , + }, + { + name: "Checks And Review", + href: "/docs/checks-and-review", + description: + "Opt in to review checks, bind review assertions to nodes, and assemble advisory packets from a diff.", + icon: , + }, { name: "CLI Reference", href: "/docs/cli", description: - "Commands for checks and comparison, plus the skill recipes your agent runs.", + "Every command around the flat fingerprint: init, checks, validate, gather, pull, pulse, and review.", icon: , }, ]; diff --git a/apps/docs/src/app/page.tsx b/apps/docs/src/app/page.tsx index 12e77918..67d599df 100644 --- a/apps/docs/src/app/page.tsx +++ b/apps/docs/src/app/page.tsx @@ -1,4 +1,4 @@ -import { useStaggerReveal } from "ghost-ui"; +import { useStaggerReveal } from "@design-intelligence/vessel"; import { Hero } from "@/components/docs/hero"; import { SectionWrapper } from "@/components/docs/wrappers"; @@ -29,121 +29,52 @@ export default function Home() {

- Agents can assemble UI. What they cannot reliably preserve is the - surface composition that UI belongs to. + Brand is not the logo.{" "} + It's the accumulated stance behind everything you ship: what + you say plainly, where you slow down, what you refuse to do, how + you behave at the moment someone trusts you. It flows through + every surface — the screen, the email, the empty state, the + sentence.

- For years, design systems solved a human assembly problem. They - gave teams shared tokens, components, examples, and usage rules so - new surfaces could be composed from known parts. + Agents now do the making.{" "} + They're fast, they're capable, and they hold nothing + they aren't handed. Every generated screen and sentence is an + answer to a question the agent was never asked:{" "} + + what would this brand do here? +

- That layer still matters, but agents change the scarce layer. - Models can copy local patterns and recombine components. They do - not consistently preserve the composition that makes a product - surface feel intentional: hierarchy, density, restraint, behavior, - copy, accessibility, trust, and flow. + + Ghost writes the answer down, where the making happens. + {" "} + The fingerprint is a portable steering packet: plain prose truths, + one file each, checked into the repo. A truth is stated once, at + the altitude it is actually true — “near the moment of + payment, reduce felt risk” — and steers whatever is being + made from it. Any agent reads the same packet: Claude, Codex, + Cursor, Goose. Any medium takes the same steer: a screen, a page, + a sentence. It travels with the repo, and it outlives your choice + of agent.

- Ghost captures the composition of a product surface: the intent - behind it, the materials it draws from, and the patterns that make - it feel intentional. + + Around the packet, machinery — and only machinery. + {" "} + ghost gather emits the menu of truths;{" "} + ghost pull delivers the ones that fit the task;{" "} + ghost review assembles an advisory packet after the + work, never during. The CLI computes and never decides. The packet + is the product; the CLI is the courier.

- It stores that composition as checked-in fingerprint facets: which - intent shapes the surface, which materials agents can draw from, - which situations change the obligation, which patterns hold the - surface together, and which examples show it at its best. -

-

- Components, tokens, and libraries become implementation material. - Ghost does not replace them. It gives agents the surface context - that tells them when and how those materials belong. -

-

Ghost keeps that model compact:

-
    -
  • - .ghost/ is the default portable fingerprint package -
  • -
  • - intent.yml, inventory.yml, and{" "} - composition.yml store the three facets -
  • -
  • - validate.yml stores optional deterministic gates - grounded in fingerprint refs -
  • -
  • - ordinary Git review separates draft fingerprint edits from - checked-in truth -
  • -
-

- The split is deliberate. intent.yml captures the - intent behind the surface. inventory.yml captures the - materials it draws from. composition.yml captures the - patterns that make it feel intentional. Checks validate output; - they are not generation input. -

-

A typical loop becomes:

-
    -
  1. Brief from the fingerprint facets and exemplars
  2. -
  3. Generate or edit with the host agent
  4. -
  5. Run active deterministic checks and advisory review
  6. -
  7. - Fix code, explain intentional divergence, or update the Ghost - package through Git -
  8. -
-

- Ghost stays bring-your-own-agent. The agent reads, decides, and - writes. Ghost does the repeatable work: initialization, schema - validation, inventory, evidence verification, checks, advisory - review packets, comparison, and upstream handoff packets. -

-

- This is critical because surface composition that cannot be - recalled or evaluated cannot be delegated. A product surface that - only its original author can assess is not transferable: to - agents, to new engineers, or to forks of the product. -

-

- Drift becomes measurable within this system. When generated or - modified UI diverges from checked-in fingerprint facets, the - failure is not just error; it is signal. Drift can originate from: -

-
    -
  • incorrect generation: agent failure
  • -
  • missing-fingerprint: under-specified surface context
  • -
  • intentional product evolution
  • -
-

- Ghost does not eliminate drift; it surfaces and localizes it. The - system's boundary becomes visible where composition fails. -

-

- The fingerprint package must live where generation happens: in the - repository, versioned alongside the code it governs. As the - product changes, fingerprint edits move through the same ordinary - Git review that introduces new UI. -

-

- This leads to a practical governance model. Each repository owns - its product-surface fingerprint. Advanced workflows can add nested - packages for product areas, custom fingerprint directories for - host wrappers, comparison across systems, and declared drift - stances. -

-

- Across an organization, the collection of Ghost packages forms a - higher-order map: a distributed model of product-surface - composition as it is actually practiced, not as it is only - described. -

-

- Design systems were libraries for humans. Ghost is composition - context for agents: every surface can carry the fingerprint it - extends, and every deviation can carry evidence. + + Brand used to survive by being remembered + {" "} + — carried in heads, enforced one review comment at a time. Ghost + makes it something stronger: written once, read before anything is + made, carried by everything that ships.

diff --git a/apps/docs/src/app/tools/drift/page.tsx b/apps/docs/src/app/tools/drift/page.tsx index 80cb40c5..98bfda0e 100644 --- a/apps/docs/src/app/tools/drift/page.tsx +++ b/apps/docs/src/app/tools/drift/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useStaggerReveal } from "ghost-ui"; +import { useStaggerReveal } from "@design-intelligence/vessel"; import { BookOpen, Orbit, Rocket } from "lucide-react"; import type { ReactNode } from "react"; import { Link } from "react-router"; @@ -14,24 +14,24 @@ const cards: { icon: ReactNode; }[] = [ { - name: "Ghost loop", - href: "/docs/getting-started#the-simple-model", + name: "Checks and review", + href: "/docs/checks-and-review", description: - "See how context, checks, review, comparison, and intent fit together.", + "Opt in to review checks, bind assertions to nodes, and assemble advisory packets.", icon: , }, { name: "Get started", href: "/docs/getting-started", description: - "Install the skill bundle and review changed UI against the .ghost bundle.", + "Install the skill bundle and review changed work against the .ghost fingerprint.", icon: , }, { name: "CLI reference", - href: "/docs/cli#ghost--review-and-compare", + href: "/docs/cli", description: - "Run checks, emit exemplar-guided advisory review, compare fingerprints, and record intent.", + "Every command around the flat fingerprint, including review flags and exit codes.", icon: , }, ]; @@ -47,8 +47,8 @@ export default function GhostDriftLanding() {
, - }, - { - name: "CLI reference", - href: "/docs/cli#ghost-fleet--view-across-projects", - description: "List members, compute a view, and emit fleet reports.", - icon: , - }, - { - name: "Skill bundle", - href: "https://github.com/block/ghost/tree/main/packages/ghost-fleet/src/skill-bundle", - description: "The recipe that turns fleet output into a readable summary.", - icon: , - }, -]; - -export default function GhostFleetLanding() { - const ref = useStaggerReveal(".tool-card", { - stagger: 0.06, - y: 30, - duration: 0.7, - }); - - return ( - - - -
- {cards.map((item) => ( - -
- {item.icon} -
- - - {item.name} - - - -

- {item.description} -

- - ))} -
-
- ); -} diff --git a/apps/docs/src/app/tools/page.tsx b/apps/docs/src/app/tools/page.tsx index ffaefd8f..f6844569 100644 --- a/apps/docs/src/app/tools/page.tsx +++ b/apps/docs/src/app/tools/page.tsx @@ -1,7 +1,7 @@ "use client"; -import { useStaggerReveal } from "ghost-ui"; -import { FileText, Network, Orbit, Palette } from "lucide-react"; +import { useStaggerReveal } from "@design-intelligence/vessel"; +import { FileText, Orbit } from "lucide-react"; import type { ReactNode } from "react"; import { Link } from "react-router"; import { AnimatedPageHeader } from "@/components/docs/animated-page-header"; @@ -14,29 +14,17 @@ const tools: { icon: ReactNode; }[] = [ { - name: "ghost scan", + name: "ghost gather", href: "/tools/scan", - blurb: "Check fingerprint contribution", + blurb: "Gather brand context before building", icon: , }, { name: "ghost review", href: "/tools/drift", - blurb: "Review UI drift", + blurb: "Review a diff against the fingerprint", icon: , }, - { - name: "ghost-fleet", - href: "/tools/fleet", - blurb: "Compare projects", - icon: , - }, - { - name: "ghost-ui", - href: "/tools/ui", - blurb: "Reference UI library", - icon: , - }, ]; function ToolStrip() { @@ -49,7 +37,7 @@ function ToolStrip() { return (
{tools.map((tool) => ( diff --git a/apps/docs/src/app/tools/scan/page.tsx b/apps/docs/src/app/tools/scan/page.tsx index c4a97f49..eaf2debf 100644 --- a/apps/docs/src/app/tools/scan/page.tsx +++ b/apps/docs/src/app/tools/scan/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useStaggerReveal } from "ghost-ui"; +import { useStaggerReveal } from "@design-intelligence/vessel"; import { BookOpen, FileText, Rocket } from "lucide-react"; import type { ReactNode } from "react"; import { Link } from "react-router"; @@ -22,16 +22,15 @@ const cards: { }, { name: "CLI reference", - href: "/docs/cli#ghost--fingerprint-layers-and-package-checks", + href: "/docs/cli", description: - "Check fingerprint contribution facets, validate packages, and emit context.", + "Emit the fingerprint menu with gather, read selected truths with pull, and tune with pulse.", icon: , }, { - name: "Format spec", - href: "https://github.com/block/ghost/blob/main/docs/fingerprint-format.md", - description: - "The full package format for fingerprint intent, inventory, composition, and validation.", + name: "Authoring", + href: "/docs/fingerprint-authoring", + description: "How to write node prose that steers generation.", icon: , }, ]; @@ -46,9 +45,9 @@ export default function GhostScanLanding() { return (
, - }, - { - name: `Components (${componentCount})`, - href: "/ui/components", - description: - "Production-ready primitives + AI elements. Distributed via the shadcn registry.json — installed component-by-component, never wholesale.", - icon: , - }, - { - name: "MCP server", - href: "https://github.com/block/ghost/tree/main/packages/ghost-ui#mcp-server", - description: - "ghost-mcp re-exposes the registry to AI assistants — five tools, two resources, so an agent can search components and pull source.", - icon: , - }, -]; - -export default function GhostUiLanding() { - const ref = useStaggerReveal(".tool-card", { - stagger: 0.06, - y: 30, - duration: 0.7, - }); - - return ( - - - -
- {cards.map((item) => ( - -
- {item.icon} -
- - - {item.name} - - - -

- {item.description} -

- - ))} -
-
- ); -} diff --git a/apps/docs/src/app/ui/components/[name]/page.tsx b/apps/docs/src/app/ui/components/[name]/page.tsx deleted file mode 100644 index 4291697f..00000000 --- a/apps/docs/src/app/ui/components/[name]/page.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { Navigate, useParams } from "react-router"; -import { ComponentPageShell } from "@/components/docs/component-page-shell"; -import { getComponentDoc } from "@/lib/component-docs"; -import { - getCategory, - getComponent, - getComponentsByCategory, -} from "@/lib/component-registry"; -import { getComponentSpec } from "@/lib/component-source"; - -// ── Import demo source files as raw strings at build time ── - -const demoSourceModules = import.meta.glob( - [ - "/src/components/docs/primitives/*-demo.tsx", - "/src/components/docs/ai-elements/*-demo.tsx", - ], - { query: "?raw", eager: true }, -) as Record; - -function getDemoSource( - slug: string, - source: "primitives" | "ai-elements", -): string | null { - const key = `/src/components/docs/${source}/${slug}-demo.tsx`; - return demoSourceModules[key]?.default ?? null; -} - -export default function ComponentPage() { - const { name } = useParams<{ name: string }>(); - - if (!name) return ; - - const component = getComponent(name); - if (!component) return ; - - const category = getCategory(component.primaryCategory); - const siblings = getComponentsByCategory(component.primaryCategory); - const currentIndex = siblings.findIndex((c) => c.slug === name); - const prev = currentIndex > 0 ? siblings[currentIndex - 1] : null; - const next = - currentIndex < siblings.length - 1 ? siblings[currentIndex + 1] : null; - - const demoSource = getDemoSource(component.slug, component.demoSource); - const spec = getComponentSpec(component.slug); - const docs = getComponentDoc(name); - - return ( - - ); -} diff --git a/apps/docs/src/app/ui/components/page.tsx b/apps/docs/src/app/ui/components/page.tsx deleted file mode 100644 index 5be57442..00000000 --- a/apps/docs/src/app/ui/components/page.tsx +++ /dev/null @@ -1,170 +0,0 @@ -"use client"; - -import { useStaggerReveal } from "ghost-ui"; -import { useMemo, useState } from "react"; -import { Link } from "react-router"; -import { AnimatedPageHeader } from "@/components/docs/animated-page-header"; -import { SectionWrapper } from "@/components/docs/wrappers"; -import { - categories, - getAllComponents, - getComponentsByCategory, -} from "@/lib/component-registry"; - -/* ── Fuzzy match ─────────────────────────────────────────────────────── */ - -function fuzzyMatch(query: string, target: string): number { - const q = query.toLowerCase(); - const t = target.toLowerCase(); - - // exact substring match scores highest - if (t.includes(q)) return 1; - - // character-by-character fuzzy: every query char must appear in order - let qi = 0; - let score = 0; - let lastIdx = -1; - - for (let ti = 0; ti < t.length && qi < q.length; ti++) { - if (t[ti] === q[qi]) { - // bonus for consecutive matches - score += ti === lastIdx + 1 ? 2 : 1; - lastIdx = ti; - qi++; - } - } - - // all query characters must be found - if (qi < q.length) return 0; - - // normalise to 0–1 range (below 1 so substring match always wins) - return (score / (q.length * 2)) * 0.9; -} - -/* ── Page ─────────────────────────────────────────────────────────────── */ - -export default function ComponentsIndex() { - const [query, setQuery] = useState(""); - const allComponents = useMemo(() => getAllComponents(), []); - - const filtered = useMemo(() => { - if (!query.trim()) return null; - return allComponents - .map((c) => ({ ...c, score: fuzzyMatch(query, c.name) })) - .filter((c) => c.score > 0) - .sort((a, b) => b.score - a.score); - }, [query, allComponents]); - - const isSearching = query.trim().length > 0; - - return ( - - - - {/* Search */} -
- setQuery(e.target.value)} - placeholder="Search components…" - className="w-full max-w-md rounded-full border border-border-card bg-card px-5 py-2.5 text-sm text-foreground placeholder:text-muted-foreground/50 outline-none focus:border-foreground/25 transition-colors duration-200" - /> -
- - {/* Search results */} - {isSearching && ( -
- {filtered && filtered.length > 0 ? ( -
- {filtered.map((item) => ( - - ))} -
- ) : ( -

- No components match "{query}" -

- )} -
- )} - - {/* Category sections */} - {!isSearching && ( -
- {categories.map((cat) => { - const items = getComponentsByCategory(cat.slug); - if (items.length === 0) return null; - return ( - - ); - })} -
- )} -
- ); -} - -/* ── Pill ─────────────────────────────────────────────────────────────── */ - -function ComponentPill({ slug, name }: { slug: string; name: string }) { - return ( - - - - {name} - - - ); -} - -/* ── Category section ─────────────────────────────────────────────────── */ - -function CategorySection({ - name, - description, - items, -}: { - name: string; - description: string; - items: { slug: string; name: string }[]; -}) { - const ref = useStaggerReveal(".component-card", { - stagger: 0.04, - y: 24, - duration: 0.6, - }); - - return ( -
-

- {name} -

-

{description}

-
- {items.map((item) => ( - - ))} -
-
- ); -} diff --git a/apps/docs/src/app/ui/foundations/colors/page.tsx b/apps/docs/src/app/ui/foundations/colors/page.tsx deleted file mode 100644 index ddaa3355..00000000 --- a/apps/docs/src/app/ui/foundations/colors/page.tsx +++ /dev/null @@ -1,32 +0,0 @@ -"use client"; - -import { useScrollReveal } from "ghost-ui"; -import { AnimatedPageHeader } from "@/components/docs/animated-page-header"; -import { ColorsDemos } from "@/components/docs/foundations/colors"; -import { SectionWrapper } from "@/components/docs/wrappers"; - -export default function ColorsPage() { - const contentRef = useScrollReveal({ - y: 50, - duration: 0.9, - ease: "expo.out", - }); - - return ( - <> - - - - - -
- -
-
- - ); -} diff --git a/apps/docs/src/app/ui/foundations/page.tsx b/apps/docs/src/app/ui/foundations/page.tsx deleted file mode 100644 index 1f648342..00000000 --- a/apps/docs/src/app/ui/foundations/page.tsx +++ /dev/null @@ -1,103 +0,0 @@ -"use client"; - -import { useStaggerReveal } from "ghost-ui"; -import { type ReactNode } from "react"; -import { Link } from "react-router"; -import { AnimatedPageHeader } from "@/components/docs/animated-page-header"; -import { SectionWrapper } from "@/components/docs/wrappers"; - -function ColorsVisual() { - return ( -
- {[ - "bg-foreground", - "bg-foreground/80", - "bg-foreground/60", - "bg-foreground/40", - "bg-foreground/20", - "bg-foreground/10", - ].map((bg, i) => ( -
- ))} -
- ); -} - -function TypographyVisual() { - return ( -
-
-
-
-
-
- ); -} - -const foundations: { - name: string; - href: string; - description: string; - visual: ReactNode; -}[] = [ - { - name: "Colors", - href: "/ui/foundations/colors", - description: - "A pure monochromatic scale with selective semantic color for status and utility.", - visual: , - }, - { - name: "Typography", - href: "/ui/foundations/typography", - description: - "Magazine-grade hierarchy. Display for headers, Regular for body, Mono for data.", - visual: , - }, -]; - -export default function FoundationsIndex() { - const ref = useStaggerReveal(".foundation-card", { - stagger: 0.06, - y: 30, - duration: 0.7, - }); - - return ( - - - -
- {foundations.map((item) => ( - -
{item.visual}
- - - {item.name} - - - -

- {item.description} -

- - ))} -
-
- ); -} diff --git a/apps/docs/src/app/ui/foundations/typography/page.tsx b/apps/docs/src/app/ui/foundations/typography/page.tsx deleted file mode 100644 index d6a8f53c..00000000 --- a/apps/docs/src/app/ui/foundations/typography/page.tsx +++ /dev/null @@ -1,32 +0,0 @@ -"use client"; - -import { useScrollReveal } from "ghost-ui"; -import { AnimatedPageHeader } from "@/components/docs/animated-page-header"; -import { TypographyDemos } from "@/components/docs/foundations/typography"; -import { SectionWrapper } from "@/components/docs/wrappers"; - -export default function TypographyPage() { - const contentRef = useScrollReveal({ - y: 50, - duration: 0.9, - ease: "expo.out", - }); - - return ( - <> - - - - - -
- -
-
- - ); -} diff --git a/apps/docs/src/app/ui/page.tsx b/apps/docs/src/app/ui/page.tsx deleted file mode 100644 index 686405ef..00000000 --- a/apps/docs/src/app/ui/page.tsx +++ /dev/null @@ -1,131 +0,0 @@ -"use client"; - -import { useStaggerReveal } from "ghost-ui"; -import { type ReactNode } from "react"; -import { Link } from "react-router"; -import { AnimatedPageHeader } from "@/components/docs/animated-page-header"; -import { SectionWrapper } from "@/components/docs/wrappers"; -import { getAllComponents } from "@/lib/component-registry"; - -function ColorsVisual() { - return ( -
- {[ - "bg-foreground", - "bg-foreground/80", - "bg-foreground/60", - "bg-foreground/40", - "bg-foreground/20", - "bg-foreground/10", - ].map((bg, i) => ( -
- ))} -
- ); -} - -function TypographyVisual() { - return ( -
-
-
-
-
-
- ); -} - -function ComponentsVisual() { - const count = getAllComponents().length; - return ( -
- {Array.from({ length: 8 }).map((_, i) => ( -
- ))} - - {count} components - -
- ); -} - -const sections: { - name: string; - href: string; - description: string; - visual: ReactNode; -}[] = [ - { - name: "Foundations", - href: "/ui/foundations", - description: - "Color, typography, and the design tokens that underpin every Ghost UI component.", - visual: ( -
-
- -
-
- -
-
- ), - }, - { - name: "Components", - href: "/ui/components", - description: - "Production-ready building blocks. Every component follows Ghost UI — pill-first, monochromatic, accessible.", - visual: , - }, -]; - -export default function DesignLanguageIndex() { - const ref = useStaggerReveal(".dl-card", { - stagger: 0.06, - y: 30, - duration: 0.7, - }); - - return ( - - - -
- {sections.map((item) => ( - -
{item.visual}
- - - {item.name} - - - -

- {item.description} -

- - ))} -
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/agent-demo.tsx b/apps/docs/src/components/docs/ai-elements/agent-demo.tsx deleted file mode 100644 index 0b340865..00000000 --- a/apps/docs/src/components/docs/ai-elements/agent-demo.tsx +++ /dev/null @@ -1,89 +0,0 @@ -"use client"; - -import { - Agent, - AgentContent, - AgentHeader, - AgentInstructions, - AgentOutput, - AgentTool, - AgentTools, -} from "ghost-ui"; - -export function AgentDemo() { - return ( -
- - - - - You are a research assistant that helps users find and summarize - academic papers. Use the provided tools to search databases and - retrieve relevant publications. Always cite your sources. - - - - - - - - - - - - - - Review code for best practices, potential bugs, and performance - issues. Provide actionable feedback with specific line references. - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/artifact-demo.tsx b/apps/docs/src/components/docs/ai-elements/artifact-demo.tsx deleted file mode 100644 index ab5105a5..00000000 --- a/apps/docs/src/components/docs/ai-elements/artifact-demo.tsx +++ /dev/null @@ -1,67 +0,0 @@ -"use client"; - -import { - Artifact, - ArtifactAction, - ArtifactActions, - ArtifactClose, - ArtifactContent, - ArtifactDescription, - ArtifactHeader, - ArtifactTitle, -} from "ghost-ui"; -import { CopyIcon, DownloadIcon, ShareIcon } from "lucide-react"; - -export function ArtifactDemo() { - return ( -
- - -
- React Component - - A reusable button component with variants - -
- - - - - - -
- -
-            {`export function Button({ variant = "primary", children }) {
-  return (
-    
-  );
-}`}
-          
-
-
- - - -
- SVG Illustration - - Generated logo design concept - -
- - - - -
- -
- AI -
-
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/attachments-demo.tsx b/apps/docs/src/components/docs/ai-elements/attachments-demo.tsx deleted file mode 100644 index a5caa72c..00000000 --- a/apps/docs/src/components/docs/ai-elements/attachments-demo.tsx +++ /dev/null @@ -1,83 +0,0 @@ -"use client"; - -import { - Attachment, - AttachmentEmpty, - AttachmentInfo, - AttachmentPreview, - AttachmentRemove, - Attachments, -} from "ghost-ui"; - -const mockAttachments = [ - { - id: "1", - type: "file" as const, - mediaType: "image/png", - filename: "screenshot.png", - url: "https://picsum.photos/seed/attach1/200/200", - }, - { - id: "2", - type: "file" as const, - mediaType: "application/pdf", - filename: "quarterly-report.pdf", - url: "", - }, - { - id: "3", - type: "file" as const, - mediaType: "audio/mp3", - filename: "recording.mp3", - url: "", - }, -]; - -export function AttachmentsDemo() { - return ( -
-
-

Grid variant

- - {mockAttachments.map((file) => ( - {}}> - - - - ))} - -
- -
-

Inline variant

- - {mockAttachments.map((file) => ( - {}}> - - - - - ))} - -
- -
-

List variant

- - {mockAttachments.map((file) => ( - {}}> - - - - - ))} - -
- -
-

Empty state

- -
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/audio-player-demo.tsx b/apps/docs/src/components/docs/ai-elements/audio-player-demo.tsx deleted file mode 100644 index eb65a58e..00000000 --- a/apps/docs/src/components/docs/ai-elements/audio-player-demo.tsx +++ /dev/null @@ -1,53 +0,0 @@ -"use client"; - -import { - AudioPlayer, - AudioPlayerControlBar, - AudioPlayerDurationDisplay, - AudioPlayerElement, - AudioPlayerMuteButton, - AudioPlayerPlayButton, - AudioPlayerSeekBackwardButton, - AudioPlayerSeekForwardButton, - AudioPlayerTimeDisplay, - AudioPlayerTimeRange, - AudioPlayerVolumeRange, -} from "ghost-ui"; - -export function AudioPlayerDemo() { - return ( -
-
-

Full audio player

- - - - - - - - - - - - - -
- -
-

- Minimal player (play, time, scrub) -

- - - - - - - - - -
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/canvas-demo.tsx b/apps/docs/src/components/docs/ai-elements/canvas-demo.tsx deleted file mode 100644 index 27fc23c1..00000000 --- a/apps/docs/src/components/docs/ai-elements/canvas-demo.tsx +++ /dev/null @@ -1,87 +0,0 @@ -"use client"; - -import { type NodeTypes, ReactFlowProvider } from "@xyflow/react"; -import { - Canvas, - Controls, - Node, - NodeContent, - NodeDescription, - NodeHeader, - NodeTitle, -} from "ghost-ui"; -import { useMemo } from "react"; - -const InputNode = () => ( - - - User Input - Text prompt - - -

- Accepts a natural language query from the user. -

-
-
-); - -const ProcessNode = () => ( - - - LLM Processing - GPT-4o - - -

- Processes the input and generates a response. -

-
-
-); - -const OutputNode = () => ( - - - Response - Markdown output - - -

- Displays the generated response to the user. -

-
-
-); - -const initialNodes = [ - { id: "1", type: "input", position: { x: 0, y: 100 }, data: {} }, - { id: "2", type: "process", position: { x: 500, y: 100 }, data: {} }, - { id: "3", type: "output", position: { x: 1000, y: 100 }, data: {} }, -]; - -const initialEdges = [ - { id: "e1-2", source: "1", target: "2" }, - { id: "e2-3", source: "2", target: "3" }, -]; - -export function CanvasDemo() { - const nodeTypes: NodeTypes = useMemo( - () => ({ - input: InputNode, - output: OutputNode, - process: ProcessNode, - }), - [], - ); - - return ( - -
- - - -
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/chain-of-thought-demo.tsx b/apps/docs/src/components/docs/ai-elements/chain-of-thought-demo.tsx deleted file mode 100644 index 5238cc15..00000000 --- a/apps/docs/src/components/docs/ai-elements/chain-of-thought-demo.tsx +++ /dev/null @@ -1,52 +0,0 @@ -"use client"; - -import { - ChainOfThought, - ChainOfThoughtContent, - ChainOfThoughtHeader, - ChainOfThoughtSearchResult, - ChainOfThoughtSearchResults, - ChainOfThoughtStep, -} from "ghost-ui"; -import { DatabaseIcon, FileTextIcon, SearchIcon } from "lucide-react"; - -export function ChainOfThoughtDemo() { - return ( - - Researching climate data - - - - IPCC 2024 - - NASA Climate - - NOAA Data - - - - - - - - - - - ); -} diff --git a/apps/docs/src/components/docs/ai-elements/checkpoint-demo.tsx b/apps/docs/src/components/docs/ai-elements/checkpoint-demo.tsx deleted file mode 100644 index 5073b3d3..00000000 --- a/apps/docs/src/components/docs/ai-elements/checkpoint-demo.tsx +++ /dev/null @@ -1,27 +0,0 @@ -"use client"; - -import { Checkpoint, CheckpointIcon, CheckpointTrigger } from "ghost-ui"; - -export function CheckpointDemo() { - return ( -
- - - - Checkpoint 1 — Initial draft - - - -
- Some conversation content between checkpoints... -
- - - - - Checkpoint 2 — After revisions - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/code-block-demo.tsx b/apps/docs/src/components/docs/ai-elements/code-block-demo.tsx deleted file mode 100644 index 9fa3d01f..00000000 --- a/apps/docs/src/components/docs/ai-elements/code-block-demo.tsx +++ /dev/null @@ -1,79 +0,0 @@ -"use client"; - -import { - CodeBlock, - CodeBlockActions, - CodeBlockCopyButton, - CodeBlockFilename, - CodeBlockHeader, - CodeBlockTitle, -} from "ghost-ui"; - -const typescriptCode = `interface User { - id: string; - name: string; - email: string; - role: "admin" | "user" | "guest"; -} - -async function getUser(id: string): Promise { - const response = await fetch(\`/api/users/\${id}\`); - - if (!response.ok) { - throw new Error(\`Failed to fetch user: \${response.statusText}\`); - } - - return response.json(); -}`; - -const cssCode = `.container { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 1.5rem; - padding: 2rem; -} - -.card { - border-radius: 0.75rem; - background: var(--card-bg); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); -}`; - -const jsonCode = `{ - "name": "@acme/design-system", - "version": "2.4.0", - "dependencies": { - "react": "^19.0.0", - "tailwindcss": "^4.0.0" - } -}`; - -export function CodeBlockDemo() { - return ( -
- - - - lib/api/users.ts - - - - - - - - - - - styles/layout.css - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/commit-demo.tsx b/apps/docs/src/components/docs/ai-elements/commit-demo.tsx deleted file mode 100644 index 73cb521c..00000000 --- a/apps/docs/src/components/docs/ai-elements/commit-demo.tsx +++ /dev/null @@ -1,122 +0,0 @@ -"use client"; - -import { - Commit, - CommitActions, - CommitAuthor, - CommitAuthorAvatar, - CommitContent, - CommitCopyButton, - CommitFile, - CommitFileAdditions, - CommitFileChanges, - CommitFileDeletions, - CommitFileIcon, - CommitFileInfo, - CommitFilePath, - CommitFileStatus, - CommitFiles, - CommitHash, - CommitHeader, - CommitInfo, - CommitMessage, - CommitMetadata, - CommitSeparator, - CommitTimestamp, -} from "ghost-ui"; - -export function CommitDemo() { - return ( -
- - - - - - - - feat: add user authentication with OAuth2 support - - - a1b2c3d - - - - - - - - - - - - - - - src/lib/auth/oauth.ts - - - - - - - - - - - src/middleware.ts - - - - - - - - - - - src/lib/auth/legacy.ts - - - - - - - - - - - src/config/auth.config.ts - - - - - - - - - - - - - - - - - - fix: resolve race condition in data fetching - - - f8e9d0c - - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/confirmation-demo.tsx b/apps/docs/src/components/docs/ai-elements/confirmation-demo.tsx deleted file mode 100644 index 772fc14f..00000000 --- a/apps/docs/src/components/docs/ai-elements/confirmation-demo.tsx +++ /dev/null @@ -1,70 +0,0 @@ -"use client"; - -import { - Confirmation, - ConfirmationAccepted, - ConfirmationAction, - ConfirmationActions, - ConfirmationRejected, - ConfirmationRequest, - ConfirmationTitle, -} from "ghost-ui"; - -export function ConfirmationDemo() { - return ( -
-
-

Approval requested

- - - The assistant wants to execute rm -rf ./build - - -

- This action will delete the build directory. Do you want to - proceed? -

-
- - Deny - Approve - -
-
- -
-

Accepted

- - - Executed rm -rf ./build - - -

- Action was approved and completed successfully. -

-
-
-
- -
-

Rejected

- - - Blocked rm -rf ./build - - -

- Action was denied by the user. -

-
-
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/connection-demo.tsx b/apps/docs/src/components/docs/ai-elements/connection-demo.tsx deleted file mode 100644 index 629c0c58..00000000 --- a/apps/docs/src/components/docs/ai-elements/connection-demo.tsx +++ /dev/null @@ -1,70 +0,0 @@ -"use client"; - -import { type NodeTypes, ReactFlowProvider } from "@xyflow/react"; -import { - Canvas, - Connection, - Node, - NodeContent, - NodeHeader, - NodeTitle, -} from "ghost-ui"; -import { useMemo } from "react"; - -const SourceNode = () => ( - - - Source - - -

- Drag from the handle to see the custom connection line. -

-
-
-); - -const TargetNode = () => ( - - - Target - - -

Drop a connection here.

-
-
-); - -const initialNodes = [ - { id: "1", type: "source", position: { x: 0, y: 80 }, data: {} }, - { id: "2", type: "target", position: { x: 500, y: 80 }, data: {} }, -]; - -export function ConnectionDemo() { - const nodeTypes: NodeTypes = useMemo( - () => ({ - source: SourceNode, - target: TargetNode, - }), - [], - ); - - return ( -
-

- Drag from the source handle to see the animated bezier connection line - with a circular endpoint indicator. -

- -
- -
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/context-demo.tsx b/apps/docs/src/components/docs/ai-elements/context-demo.tsx deleted file mode 100644 index 6b11729b..00000000 --- a/apps/docs/src/components/docs/ai-elements/context-demo.tsx +++ /dev/null @@ -1,44 +0,0 @@ -"use client"; - -import { - Context, - ContextContent, - ContextContentBody, - ContextContentFooter, - ContextContentHeader, - ContextInputUsage, - ContextOutputUsage, - ContextTrigger, -} from "ghost-ui"; - -export function ContextDemo() { - return ( - - - - - -
- - -
-
- -
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/controls-demo.tsx b/apps/docs/src/components/docs/ai-elements/controls-demo.tsx deleted file mode 100644 index 2d845c1f..00000000 --- a/apps/docs/src/components/docs/ai-elements/controls-demo.tsx +++ /dev/null @@ -1,50 +0,0 @@ -"use client"; - -import { type NodeTypes, ReactFlowProvider } from "@xyflow/react"; -import { - Canvas, - Controls, - Node, - NodeContent, - NodeHeader, - NodeTitle, -} from "ghost-ui"; -import { useMemo } from "react"; - -const SampleNode = () => ( - - - Sample Node - - -

- Use the controls in the bottom-left to zoom, fit view, and lock - interactions. -

-
-
-); - -const initialNodes = [ - { id: "1", type: "sample", position: { x: 0, y: 0 }, data: {} }, - { id: "2", type: "sample", position: { x: 400, y: 150 }, data: {} }, -]; - -export function ControlsDemo() { - const nodeTypes: NodeTypes = useMemo( - () => ({ - sample: SampleNode, - }), - [], - ); - - return ( - -
- - - -
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/conversation-demo.tsx b/apps/docs/src/components/docs/ai-elements/conversation-demo.tsx deleted file mode 100644 index 32a994ac..00000000 --- a/apps/docs/src/components/docs/ai-elements/conversation-demo.tsx +++ /dev/null @@ -1,24 +0,0 @@ -"use client"; - -import { - Conversation, - ConversationContent, - ConversationEmptyState, -} from "ghost-ui"; -import { MessageSquareIcon } from "lucide-react"; - -export function ConversationDemo() { - return ( -
- - - } - /> - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/edge-demo.tsx b/apps/docs/src/components/docs/ai-elements/edge-demo.tsx deleted file mode 100644 index ec292976..00000000 --- a/apps/docs/src/components/docs/ai-elements/edge-demo.tsx +++ /dev/null @@ -1,85 +0,0 @@ -"use client"; - -import { - type EdgeTypes, - type NodeTypes, - ReactFlowProvider, -} from "@xyflow/react"; -import { Canvas, Edge, Node, NodeHeader, NodeTitle } from "ghost-ui"; -import { useMemo } from "react"; - -const SimpleNode = ({ data }: { data: { label: string } }) => ( - - - {data.label} - - -); - -const initialNodes = [ - { - id: "a1", - type: "simple", - position: { x: 0, y: 0 }, - data: { label: "Start" }, - }, - { - id: "a2", - type: "simple", - position: { x: 450, y: 0 }, - data: { label: "Animated" }, - }, - { - id: "b1", - type: "simple", - position: { x: 0, y: 150 }, - data: { label: "Draft" }, - }, - { - id: "b2", - type: "simple", - position: { x: 450, y: 150 }, - data: { label: "Temporary" }, - }, -]; - -const initialEdges = [ - { id: "e-animated", source: "a1", target: "a2", type: "animated" }, - { id: "e-temporary", source: "b1", target: "b2", type: "temporary" }, -]; - -export function EdgeDemo() { - const nodeTypes: NodeTypes = useMemo( - () => ({ - simple: SimpleNode, - }), - [], - ); - - const edgeTypes: EdgeTypes = useMemo( - () => ({ - animated: Edge.Animated, - temporary: Edge.Temporary, - }), - [], - ); - - return ( -
-

- Two edge variants: Animated (top, with a traveling dot) - and Temporary (bottom, dashed line). -

- -
- -
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/environment-variables-demo.tsx b/apps/docs/src/components/docs/ai-elements/environment-variables-demo.tsx deleted file mode 100644 index 8c0d8ce4..00000000 --- a/apps/docs/src/components/docs/ai-elements/environment-variables-demo.tsx +++ /dev/null @@ -1,74 +0,0 @@ -"use client"; - -import { - EnvironmentVariable, - EnvironmentVariableCopyButton, - EnvironmentVariableGroup, - EnvironmentVariableName, - EnvironmentVariableRequired, - EnvironmentVariables, - EnvironmentVariablesContent, - EnvironmentVariablesHeader, - EnvironmentVariablesTitle, - EnvironmentVariablesToggle, - EnvironmentVariableValue, -} from "ghost-ui"; - -export function EnvironmentVariablesDemo() { - return ( -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/file-tree-demo.tsx b/apps/docs/src/components/docs/ai-elements/file-tree-demo.tsx deleted file mode 100644 index c2ce9e49..00000000 --- a/apps/docs/src/components/docs/ai-elements/file-tree-demo.tsx +++ /dev/null @@ -1,35 +0,0 @@ -"use client"; - -import { FileTree, FileTreeFile, FileTreeFolder } from "ghost-ui"; - -export function FileTreeDemo() { - return ( -
- - - - - - - - - - - - - - - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/image-demo.tsx b/apps/docs/src/components/docs/ai-elements/image-demo.tsx deleted file mode 100644 index 6511c174..00000000 --- a/apps/docs/src/components/docs/ai-elements/image-demo.tsx +++ /dev/null @@ -1,47 +0,0 @@ -"use client"; - -import { Image } from "ghost-ui"; - -// A tiny 1x1 transparent PNG placeholder -const PLACEHOLDER_BASE64 = - "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="; - -export function ImageDemo() { - return ( -
-

- Renders an AI-generated image from base64 data. The component - automatically constructs a data URI from the provided media type and - base64 string. -

- -
-
- AI-generated landscape placeholder - - PNG, landscape aspect ratio - -
- -
- AI-generated portrait placeholder - - PNG, square aspect ratio - -
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/index.tsx b/apps/docs/src/components/docs/ai-elements/index.tsx deleted file mode 100644 index 46e71e02..00000000 --- a/apps/docs/src/components/docs/ai-elements/index.tsx +++ /dev/null @@ -1,238 +0,0 @@ -"use client"; - -// Code -import { AgentDemo } from "@/components/docs/ai-elements/agent-demo"; -import { ArtifactDemo } from "@/components/docs/ai-elements/artifact-demo"; -// Chatbot -import { AttachmentsDemo } from "@/components/docs/ai-elements/attachments-demo"; -// Voice -import { AudioPlayerDemo } from "@/components/docs/ai-elements/audio-player-demo"; -// Workflow -import { CanvasDemo } from "@/components/docs/ai-elements/canvas-demo"; -import { ChainOfThoughtDemo } from "@/components/docs/ai-elements/chain-of-thought-demo"; -import { CheckpointDemo } from "@/components/docs/ai-elements/checkpoint-demo"; -import { CodeBlockDemo } from "@/components/docs/ai-elements/code-block-demo"; -import { CommitDemo } from "@/components/docs/ai-elements/commit-demo"; -import { ConfirmationDemo } from "@/components/docs/ai-elements/confirmation-demo"; -import { ConnectionDemo } from "@/components/docs/ai-elements/connection-demo"; -import { ContextDemo } from "@/components/docs/ai-elements/context-demo"; -import { ControlsDemo } from "@/components/docs/ai-elements/controls-demo"; -import { ConversationDemo } from "@/components/docs/ai-elements/conversation-demo"; -import { EdgeDemo } from "@/components/docs/ai-elements/edge-demo"; -import { EnvironmentVariablesDemo } from "@/components/docs/ai-elements/environment-variables-demo"; -import { FileTreeDemo } from "@/components/docs/ai-elements/file-tree-demo"; -// Utilities -import { ImageDemo } from "@/components/docs/ai-elements/image-demo"; -import { InlineCitationDemo } from "@/components/docs/ai-elements/inline-citation-demo"; -import { JsxPreviewDemo } from "@/components/docs/ai-elements/jsx-preview-demo"; -import { MessageDemo } from "@/components/docs/ai-elements/message-demo"; -import { MicSelectorDemo } from "@/components/docs/ai-elements/mic-selector-demo"; -import { ModelSelectorDemo } from "@/components/docs/ai-elements/model-selector-demo"; -import { NodeDemo } from "@/components/docs/ai-elements/node-demo"; -import { OpenInChatDemo } from "@/components/docs/ai-elements/open-in-chat-demo"; -import { PackageInfoDemo } from "@/components/docs/ai-elements/package-info-demo"; -import { PanelDemo } from "@/components/docs/ai-elements/panel-demo"; -import { PersonaDemo } from "@/components/docs/ai-elements/persona-demo"; -import { PlanDemo } from "@/components/docs/ai-elements/plan-demo"; -import { PromptInputDemo } from "@/components/docs/ai-elements/prompt-input-demo"; -import { QueueDemo } from "@/components/docs/ai-elements/queue-demo"; -import { ReasoningDemo } from "@/components/docs/ai-elements/reasoning-demo"; -import { SandboxDemo } from "@/components/docs/ai-elements/sandbox-demo"; -import { SchemaDisplayDemo } from "@/components/docs/ai-elements/schema-display-demo"; -import { ShimmerDemo } from "@/components/docs/ai-elements/shimmer-demo"; -import { SnippetDemo } from "@/components/docs/ai-elements/snippet-demo"; -import { SourcesDemo } from "@/components/docs/ai-elements/sources-demo"; -import { SpeechInputDemo } from "@/components/docs/ai-elements/speech-input-demo"; -import { StackTraceDemo } from "@/components/docs/ai-elements/stack-trace-demo"; -import { SuggestionDemo } from "@/components/docs/ai-elements/suggestion-demo"; -import { TaskDemo } from "@/components/docs/ai-elements/task-demo"; -import { TerminalDemo } from "@/components/docs/ai-elements/terminal-demo"; -import { TestResultsDemo } from "@/components/docs/ai-elements/test-results-demo"; -import { ToolDemo } from "@/components/docs/ai-elements/tool-demo"; -import { ToolbarDemo } from "@/components/docs/ai-elements/toolbar-demo"; -import { TranscriptionDemo } from "@/components/docs/ai-elements/transcription-demo"; -import { VoiceSelectorDemo } from "@/components/docs/ai-elements/voice-selector-demo"; -import { WebPreviewDemo } from "@/components/docs/ai-elements/web-preview-demo"; -import { ComponentWrapper } from "@/components/docs/primitives/component-wrapper"; - -function CategoryLabel({ children }: { children: React.ReactNode }) { - return ( -
-

- {children} -

-
- ); -} - -export function AIElementDemos() { - return ( -
- {/* Chatbot */} - Chatbot - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {/* Code */} - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {/* Voice */} - Voice - - - - - - - - - - - - - - - - - - - - {/* Workflow */} - Workflow - - - - - - - - - - - - - - - - - - - - - - - {/* Utilities */} - Utilities - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/inline-citation-demo.tsx b/apps/docs/src/components/docs/ai-elements/inline-citation-demo.tsx deleted file mode 100644 index 32219032..00000000 --- a/apps/docs/src/components/docs/ai-elements/inline-citation-demo.tsx +++ /dev/null @@ -1,65 +0,0 @@ -"use client"; - -import { - InlineCitation, - InlineCitationCard, - InlineCitationCardBody, - InlineCitationCardTrigger, - InlineCitationCarousel, - InlineCitationCarouselContent, - InlineCitationCarouselHeader, - InlineCitationCarouselIndex, - InlineCitationCarouselItem, - InlineCitationCarouselNext, - InlineCitationCarouselPrev, - InlineCitationSource, - InlineCitationText, -} from "ghost-ui"; - -const sources = [ - "https://en.wikipedia.org/wiki/Large_language_model", - "https://arxiv.org/abs/2303.08774", -]; - -export function InlineCitationDemo() { - return ( -

- Large language models are neural networks trained on vast amounts of text - data.{" "} - - - They use transformer architectures to generate coherent text - - - - - - - - - - - - - - - - - - - - - - {" "} - and have become a cornerstone of modern AI applications. -

- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/jsx-preview-demo.tsx b/apps/docs/src/components/docs/ai-elements/jsx-preview-demo.tsx deleted file mode 100644 index ffa7d6f9..00000000 --- a/apps/docs/src/components/docs/ai-elements/jsx-preview-demo.tsx +++ /dev/null @@ -1,32 +0,0 @@ -"use client"; - -import { JSXPreview, JSXPreviewContent, JSXPreviewError } from "ghost-ui"; - -const validJsx = `
-

Welcome Back

-

Your dashboard is ready to explore.

-
- - -
-
`; - -const errorJsx = `
- -
`; - -export function JsxPreviewDemo() { - return ( -
- - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/message-demo.tsx b/apps/docs/src/components/docs/ai-elements/message-demo.tsx deleted file mode 100644 index 40d6673e..00000000 --- a/apps/docs/src/components/docs/ai-elements/message-demo.tsx +++ /dev/null @@ -1,49 +0,0 @@ -"use client"; - -import { - Message, - MessageAction, - MessageActions, - MessageContent, - MessageResponse, -} from "ghost-ui"; -import { - CopyIcon, - RefreshCwIcon, - ThumbsDownIcon, - ThumbsUpIcon, -} from "lucide-react"; - -export function MessageDemo() { - return ( -
- - - Can you explain how React Server Components work? - - - - - - - {`**React Server Components** (RSC) allow you to render components on the server, reducing the amount of JavaScript sent to the client.\n\n### Key Benefits\n\n- **Zero bundle size** — Server Components are not included in the client bundle\n- **Direct backend access** — You can query databases directly\n- **Automatic code splitting** — Client components are lazy-loaded\n\n\`\`\`tsx\n// This runs on the server\nasync function UserProfile({ id }: { id: string }) {\n const user = await db.user.findUnique({ where: { id } });\n return
{user.name}
;\n}\n\`\`\``} -
-
- - - - - - - - - - - - - - -
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/mic-selector-demo.tsx b/apps/docs/src/components/docs/ai-elements/mic-selector-demo.tsx deleted file mode 100644 index 06786dd3..00000000 --- a/apps/docs/src/components/docs/ai-elements/mic-selector-demo.tsx +++ /dev/null @@ -1,48 +0,0 @@ -"use client"; - -import { - MicSelector, - MicSelectorContent, - MicSelectorEmpty, - MicSelectorInput, - MicSelectorItem, - MicSelectorLabel, - MicSelectorList, - MicSelectorTrigger, - MicSelectorValue, -} from "ghost-ui"; - -export function MicSelectorDemo() { - return ( -
-

- Opens a popover listing available audio input devices. Requires - microphone permission to show device names. -

- - - - - - - - {(devices) => - devices.length === 0 ? ( - - ) : ( - devices.map((device) => ( - - - - )) - ) - } - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/model-selector-demo.tsx b/apps/docs/src/components/docs/ai-elements/model-selector-demo.tsx deleted file mode 100644 index df2e74b1..00000000 --- a/apps/docs/src/components/docs/ai-elements/model-selector-demo.tsx +++ /dev/null @@ -1,68 +0,0 @@ -"use client"; - -import { - Button, - ModelSelector, - ModelSelectorContent, - ModelSelectorEmpty, - ModelSelectorGroup, - ModelSelectorInput, - ModelSelectorItem, - ModelSelectorList, - ModelSelectorLogo, - ModelSelectorLogoGroup, - ModelSelectorName, - ModelSelectorTrigger, -} from "ghost-ui"; - -export function ModelSelectorDemo() { - return ( - - - - - - - - No models found. - - - - - - GPT-4o - - - - - - GPT-4o Mini - - - - - - - - Claude Sonnet 4 - - - - - - Claude Opus 4 - - - - - - - - Gemini 2.5 Pro - - - - - - ); -} diff --git a/apps/docs/src/components/docs/ai-elements/node-demo.tsx b/apps/docs/src/components/docs/ai-elements/node-demo.tsx deleted file mode 100644 index 922f9323..00000000 --- a/apps/docs/src/components/docs/ai-elements/node-demo.tsx +++ /dev/null @@ -1,83 +0,0 @@ -"use client"; - -import { ReactFlowProvider } from "@xyflow/react"; -import { - Badge, - Button, - Node, - NodeContent, - NodeDescription, - NodeFooter, - NodeHeader, - NodeTitle, -} from "ghost-ui"; - -export function NodeDemo() { - return ( - -
-
- - - Full Node - - A node with header, content, and footer - - - -

- This node demonstrates all available sub-components arranged - together. It has both target (left) and source (right) handles. -

-
- - Ready - - -
- - - - Source Only - Starting node in a workflow - - -

- This node only has a source handle on the right side. -

-
-
- - - - Target Only - Terminal node in a workflow - - -

- This node only has a target handle on the left side. -

-
-
- - - - Standalone - No handles - - -

- A standalone card-style node with no connection handles. -

-
- - Idle - -
-
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/open-in-chat-demo.tsx b/apps/docs/src/components/docs/ai-elements/open-in-chat-demo.tsx deleted file mode 100644 index f5e1c694..00000000 --- a/apps/docs/src/components/docs/ai-elements/open-in-chat-demo.tsx +++ /dev/null @@ -1,42 +0,0 @@ -"use client"; - -import { - OpenIn, - OpenInChatGPT, - OpenInClaude, - OpenInContent, - OpenInCursor, - OpenInLabel, - OpenInScira, - OpenInSeparator, - OpenInT3, - OpenInTrigger, - OpenInv0, -} from "ghost-ui"; - -export function OpenInChatDemo() { - return ( -
-

- A dropdown menu that lets users open a query in various AI chat - providers. Each item generates a provider-specific URL and opens it in a - new tab. -

- - - - - Open in a chat provider - - - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/package-info-demo.tsx b/apps/docs/src/components/docs/ai-elements/package-info-demo.tsx deleted file mode 100644 index d6d393dd..00000000 --- a/apps/docs/src/components/docs/ai-elements/package-info-demo.tsx +++ /dev/null @@ -1,57 +0,0 @@ -"use client"; - -import { - PackageInfo, - PackageInfoContent, - PackageInfoDependencies, - PackageInfoDependency, - PackageInfoDescription, -} from "ghost-ui"; - -export function PackageInfoDemo() { - return ( -
- - - A JavaScript library for building user interfaces - - - - - - - - - - - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/panel-demo.tsx b/apps/docs/src/components/docs/ai-elements/panel-demo.tsx deleted file mode 100644 index ec110916..00000000 --- a/apps/docs/src/components/docs/ai-elements/panel-demo.tsx +++ /dev/null @@ -1,61 +0,0 @@ -"use client"; - -import { type NodeTypes, ReactFlowProvider } from "@xyflow/react"; -import { - Canvas, - Node, - NodeContent, - NodeHeader, - NodeTitle, - Panel, -} from "ghost-ui"; -import { useMemo } from "react"; - -const PlaceholderNode = () => ( - - - Workflow Node - - -

- Panels float above the canvas at fixed positions. -

-
-
-); - -const initialNodes = [ - { id: "1", type: "placeholder", position: { x: 100, y: 80 }, data: {} }, -]; - -export function PanelDemo() { - const nodeTypes: NodeTypes = useMemo( - () => ({ - placeholder: PlaceholderNode, - }), - [], - ); - - return ( -
-

- Panels are floating overlays positioned at the edges of the canvas. -

- -
- - - Top Left Panel - - - Top Right Panel - - - Bottom Center Panel - - -
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/persona-demo.tsx b/apps/docs/src/components/docs/ai-elements/persona-demo.tsx deleted file mode 100644 index f5e48571..00000000 --- a/apps/docs/src/components/docs/ai-elements/persona-demo.tsx +++ /dev/null @@ -1,55 +0,0 @@ -"use client"; - -import type { PersonaState } from "ghost-ui"; -import { Button, Persona } from "ghost-ui"; -import { useState } from "react"; - -const variants = [ - "obsidian", - "glint", - "halo", - "command", - "mana", - "opal", -] as const; -const states: PersonaState[] = [ - "idle", - "listening", - "thinking", - "speaking", - "asleep", -]; - -export function PersonaDemo() { - const [currentState, setCurrentState] = useState("idle"); - - return ( -
-
- {states.map((s) => ( - - ))} -
- -
- {variants.map((variant) => ( -
- - {variant} -
- ))} -
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/plan-demo.tsx b/apps/docs/src/components/docs/ai-elements/plan-demo.tsx deleted file mode 100644 index ce00bc8d..00000000 --- a/apps/docs/src/components/docs/ai-elements/plan-demo.tsx +++ /dev/null @@ -1,63 +0,0 @@ -"use client"; - -import { - Plan, - PlanAction, - PlanContent, - PlanDescription, - PlanFooter, - PlanHeader, - PlanTitle, - PlanTrigger, -} from "ghost-ui"; -import { CheckCircleIcon, CircleIcon } from "lucide-react"; - -export function PlanDemo() { - return ( -
- - -
- Build a Landing Page - - Create a responsive landing page with hero section, features, and - footer. - -
- - - -
- -
    -
  • - - - Set up project structure - -
  • -
  • - - - Design hero section - -
  • -
  • - - Build features grid -
  • -
  • - - Add footer and navigation -
  • -
-
- -

- 2 of 4 steps completed -

-
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/prompt-input-demo.tsx b/apps/docs/src/components/docs/ai-elements/prompt-input-demo.tsx deleted file mode 100644 index 47132fcf..00000000 --- a/apps/docs/src/components/docs/ai-elements/prompt-input-demo.tsx +++ /dev/null @@ -1,29 +0,0 @@ -"use client"; - -import { - PromptInput, - PromptInputButton, - PromptInputFooter, - PromptInputSubmit, - PromptInputTextarea, - PromptInputTools, -} from "ghost-ui"; -import { PaperclipIcon } from "lucide-react"; - -export function PromptInputDemo() { - return ( -
- {}}> - - - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/queue-demo.tsx b/apps/docs/src/components/docs/ai-elements/queue-demo.tsx deleted file mode 100644 index b6f9b370..00000000 --- a/apps/docs/src/components/docs/ai-elements/queue-demo.tsx +++ /dev/null @@ -1,86 +0,0 @@ -"use client"; - -import { - Queue, - QueueItem, - QueueItemContent, - QueueItemDescription, - QueueItemIndicator, - QueueList, - QueueSection, - QueueSectionContent, - QueueSectionLabel, - QueueSectionTrigger, -} from "ghost-ui"; -import { CheckCircleIcon, ListTodoIcon } from "lucide-react"; - -export function QueueDemo() { - return ( -
- - - - } - /> - - - - -
- - - Refactor authentication module - -
- - Extract shared logic into a reusable hook - -
- -
- - - Write unit tests for API routes - -
-
-
-
-
- - - - } - /> - - - - -
- - - Set up project scaffolding - -
-
- -
- - - Configure database schema - -
-
-
-
-
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/reasoning-demo.tsx b/apps/docs/src/components/docs/ai-elements/reasoning-demo.tsx deleted file mode 100644 index 0ca165bd..00000000 --- a/apps/docs/src/components/docs/ai-elements/reasoning-demo.tsx +++ /dev/null @@ -1,29 +0,0 @@ -"use client"; - -import { Reasoning, ReasoningContent, ReasoningTrigger } from "ghost-ui"; - -export function ReasoningDemo() { - return ( -
-
-

Completed reasoning

- - - - {`The user is asking about the performance implications of using React Server Components. Let me think through the key factors:\n\n1. **Bundle size reduction** - Since server components don't ship JavaScript to the client, the initial bundle can be significantly smaller.\n\n2. **Data fetching** - Server components can fetch data directly during rendering, eliminating client-side waterfalls.\n\n3. **Streaming** - The server can stream HTML progressively, improving Time to First Byte.`} - - -
- -
-

Streaming reasoning

- - - - {`Analyzing the query about database optimization strategies. I should consider indexing, query planning, and caching...`} - - -
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/sandbox-demo.tsx b/apps/docs/src/components/docs/ai-elements/sandbox-demo.tsx deleted file mode 100644 index 55604449..00000000 --- a/apps/docs/src/components/docs/ai-elements/sandbox-demo.tsx +++ /dev/null @@ -1,84 +0,0 @@ -"use client"; - -import { - CodeBlock, - CodeBlockActions, - CodeBlockCopyButton, - CodeBlockFilename, - CodeBlockHeader, - CodeBlockTitle, - Sandbox, - SandboxContent, - SandboxHeader, - SandboxTabContent, - SandboxTabs, - SandboxTabsBar, - SandboxTabsList, - SandboxTabsTrigger, -} from "ghost-ui"; - -const codeSnippet = `import { useState } from "react"; - -export default function Counter() { - const [count, setCount] = useState(0); - - return ( -
-

{count}

- -
- ); -}`; - -const outputText = `> next dev --turbo - Ready in 1.2s - Local: http://localhost:3000 - Network: http://192.168.1.100:3000 - - Compiled /page in 340ms`; - -export function SandboxDemo() { - return ( -
- - - - - - - Code - Output - - - - - - - counter.tsx - - - - - - - - -
{outputText}
-
-
-
-
- - - - -
- Executing test suite... -
-
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/schema-display-demo.tsx b/apps/docs/src/components/docs/ai-elements/schema-display-demo.tsx deleted file mode 100644 index 12c4c54b..00000000 --- a/apps/docs/src/components/docs/ai-elements/schema-display-demo.tsx +++ /dev/null @@ -1,171 +0,0 @@ -"use client"; - -import { SchemaDisplay } from "ghost-ui"; - -export function SchemaDisplayDemo() { - return ( -
- - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/shimmer-demo.tsx b/apps/docs/src/components/docs/ai-elements/shimmer-demo.tsx deleted file mode 100644 index 2eb428f5..00000000 --- a/apps/docs/src/components/docs/ai-elements/shimmer-demo.tsx +++ /dev/null @@ -1,21 +0,0 @@ -"use client"; - -import { Shimmer } from "ghost-ui"; - -export function ShimmerDemo() { - return ( -
- - Generating response... - - - - Analyzing your code and preparing suggestions - - - - Thinking... - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/snippet-demo.tsx b/apps/docs/src/components/docs/ai-elements/snippet-demo.tsx deleted file mode 100644 index 56d45b7b..00000000 --- a/apps/docs/src/components/docs/ai-elements/snippet-demo.tsx +++ /dev/null @@ -1,52 +0,0 @@ -"use client"; - -import { - Snippet, - SnippetAddon, - SnippetCopyButton, - SnippetInput, - SnippetText, -} from "ghost-ui"; - -export function SnippetDemo() { - return ( -
- - - $ - - - - - - - - - - $ - - - - - - - - - - - - - - - - - $ - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/sources-demo.tsx b/apps/docs/src/components/docs/ai-elements/sources-demo.tsx deleted file mode 100644 index 598afb1c..00000000 --- a/apps/docs/src/components/docs/ai-elements/sources-demo.tsx +++ /dev/null @@ -1,25 +0,0 @@ -"use client"; - -import { Source, Sources, SourcesContent, SourcesTrigger } from "ghost-ui"; - -export function SourcesDemo() { - return ( - - - - - - - - - ); -} diff --git a/apps/docs/src/components/docs/ai-elements/speech-input-demo.tsx b/apps/docs/src/components/docs/ai-elements/speech-input-demo.tsx deleted file mode 100644 index 9d75873d..00000000 --- a/apps/docs/src/components/docs/ai-elements/speech-input-demo.tsx +++ /dev/null @@ -1,31 +0,0 @@ -"use client"; - -import { SpeechInput } from "ghost-ui"; -import { useState } from "react"; - -export function SpeechInputDemo() { - const [transcript, setTranscript] = useState(""); - - return ( -
-

- Click the microphone button to begin recording. Uses the Web Speech API - when available, with a MediaRecorder fallback. -

- - - setTranscript((prev) => (prev ? `${prev} ${text}` : text)) - } - /> - -
-

Transcription output

-

- {transcript || "Transcribed text will appear here..."} -

-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/stack-trace-demo.tsx b/apps/docs/src/components/docs/ai-elements/stack-trace-demo.tsx deleted file mode 100644 index b8863d15..00000000 --- a/apps/docs/src/components/docs/ai-elements/stack-trace-demo.tsx +++ /dev/null @@ -1,65 +0,0 @@ -"use client"; - -import { - StackTrace, - StackTraceActions, - StackTraceContent, - StackTraceCopyButton, - StackTraceError, - StackTraceErrorMessage, - StackTraceErrorType, - StackTraceExpandButton, - StackTraceFrames, - StackTraceHeader, -} from "ghost-ui"; - -const typeErrorTrace = `TypeError: Cannot read properties of undefined (reading 'map') - at UserList (/src/components/UserList.tsx:24:18) - at renderWithHooks (node_modules/react-dom/cjs/react-dom.development.js:14985:18) - at mountIndeterminateComponent (node_modules/react-dom/cjs/react-dom.development.js:17811:13) - at beginWork (node_modules/react-dom/cjs/react-dom.development.js:19049:16) - at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:3945:14)`; - -const referenceErrorTrace = `ReferenceError: fetchData is not defined - at loadDashboard (/src/pages/dashboard.ts:15:3) - at async handleRequest (/src/server/router.ts:42:12) - at async processMiddleware (/src/server/middleware.ts:28:5) - at node:internal/process/task_queues:95:5`; - -export function StackTraceDemo() { - return ( -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/suggestion-demo.tsx b/apps/docs/src/components/docs/ai-elements/suggestion-demo.tsx deleted file mode 100644 index feea6511..00000000 --- a/apps/docs/src/components/docs/ai-elements/suggestion-demo.tsx +++ /dev/null @@ -1,18 +0,0 @@ -"use client"; - -import { Suggestion, Suggestions } from "ghost-ui"; - -export function SuggestionDemo() { - return ( -
-

Suggested prompts

- - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/task-demo.tsx b/apps/docs/src/components/docs/ai-elements/task-demo.tsx deleted file mode 100644 index fd752437..00000000 --- a/apps/docs/src/components/docs/ai-elements/task-demo.tsx +++ /dev/null @@ -1,43 +0,0 @@ -"use client"; - -import { - Task, - TaskContent, - TaskItem, - TaskItemFile, - TaskTrigger, -} from "ghost-ui"; - -export function TaskDemo() { - return ( -
- - - - - Found src/auth/login.ts — contains the - main login handler with JWT token generation. - - - Found src/middleware/auth.ts — - validates tokens on protected routes. - - - Found src/lib/session.ts — manages - session creation and expiration. - - - - - - - - - Reviewed prisma/schema.prisma for user - model relationships. - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/terminal-demo.tsx b/apps/docs/src/components/docs/ai-elements/terminal-demo.tsx deleted file mode 100644 index 6142dca7..00000000 --- a/apps/docs/src/components/docs/ai-elements/terminal-demo.tsx +++ /dev/null @@ -1,63 +0,0 @@ -"use client"; - -import { - Terminal, - TerminalActions, - TerminalContent, - TerminalCopyButton, - TerminalHeader, - TerminalTitle, -} from "ghost-ui"; - -const buildOutput = `\x1b[32m$\x1b[0m next build -\x1b[36minfo\x1b[0m - Linting and checking validity of types... -\x1b[36minfo\x1b[0m - Creating an optimized production build... -\x1b[36minfo\x1b[0m - Compiled successfully -\x1b[36minfo\x1b[0m - Collecting page data... -\x1b[36minfo\x1b[0m - Generating static pages (8/8) -\x1b[36minfo\x1b[0m - Finalizing page optimization... - -Route (app) Size First Load JS -\x1b[37m+\x1b[0m / 5.2 kB 89.3 kB -\x1b[37m+\x1b[0m /about 1.8 kB 85.9 kB -\x1b[37m+\x1b[0m /dashboard 12.4 kB 96.5 kB -\x1b[37m+\x1b[0m /api/health 0 B 0 B - -\x1b[32m\u2713\x1b[0m Build completed in 14.2s`; - -const gitOutput = `\x1b[33mOn branch main\x1b[0m -Your branch is up to date with 'origin/main'. - -Changes to be committed: - \x1b[32mnew file: src/components/avatar.tsx\x1b[0m - \x1b[32mmodified: src/lib/utils.ts\x1b[0m - \x1b[31mdeleted: src/old-component.tsx\x1b[0m - -Untracked files: - \x1b[31m.env.local\x1b[0m`; - -export function TerminalDemo() { - return ( -
- - - Build Output - - - - - - - - - - git status - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/test-results-demo.tsx b/apps/docs/src/components/docs/ai-elements/test-results-demo.tsx deleted file mode 100644 index e3811432..00000000 --- a/apps/docs/src/components/docs/ai-elements/test-results-demo.tsx +++ /dev/null @@ -1,132 +0,0 @@ -"use client"; - -import { - Test, - TestError, - TestErrorMessage, - TestErrorStack, - TestResults, - TestResultsContent, - TestResultsDuration, - TestResultsHeader, - TestResultsProgress, - TestResultsSummary, - TestSuite, - TestSuiteContent, - TestSuiteName, -} from "ghost-ui"; - -export function TestResultsDemo() { - return ( -
- - - - - - - - - - - - - - - - - - - - - - - - - - - Expected status 200 but received 500 - - - {`at Object. (tests/api/user.test.ts:45:10) - at processTicksAndRejections (node:internal/process/task_queues:95:5)`} - - - - - - - AssertionError: expected 'invalid' to match - /^[^@]+@[^@]+$/ - - - - - - - - - - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/tool-demo.tsx b/apps/docs/src/components/docs/ai-elements/tool-demo.tsx deleted file mode 100644 index db1d9e3d..00000000 --- a/apps/docs/src/components/docs/ai-elements/tool-demo.tsx +++ /dev/null @@ -1,63 +0,0 @@ -"use client"; - -import { Tool, ToolContent, ToolHeader, ToolInput, ToolOutput } from "ghost-ui"; - -export function ToolDemo() { - return ( -
- - - - - - - - - - - - - - - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/toolbar-demo.tsx b/apps/docs/src/components/docs/ai-elements/toolbar-demo.tsx deleted file mode 100644 index 0d6a2cf5..00000000 --- a/apps/docs/src/components/docs/ai-elements/toolbar-demo.tsx +++ /dev/null @@ -1,71 +0,0 @@ -"use client"; - -import { type NodeTypes, ReactFlowProvider } from "@xyflow/react"; -import { - Button, - Canvas, - Node, - NodeContent, - NodeHeader, - NodeTitle, - Toolbar, -} from "ghost-ui"; -import { CopyIcon, PencilIcon, Trash2Icon } from "lucide-react"; -import { useMemo } from "react"; - -const ToolbarNode = () => ( - - - Select this node - - -

- Click to select and reveal the toolbar below. -

-
- - - - - -
-); - -const initialNodes = [ - { - id: "1", - type: "toolbar", - position: { x: 100, y: 60 }, - data: {}, - selected: true, - }, -]; - -export function ToolbarDemo() { - const nodeTypes: NodeTypes = useMemo( - () => ({ - toolbar: ToolbarNode, - }), - [], - ); - - return ( -
-

- A floating toolbar that appears below a selected node, providing - contextual actions. -

- -
- -
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/transcription-demo.tsx b/apps/docs/src/components/docs/ai-elements/transcription-demo.tsx deleted file mode 100644 index 43c17faf..00000000 --- a/apps/docs/src/components/docs/ai-elements/transcription-demo.tsx +++ /dev/null @@ -1,54 +0,0 @@ -"use client"; - -import { Button, Transcription, TranscriptionSegment } from "ghost-ui"; -import { useState } from "react"; - -const mockSegments = [ - { text: "Welcome to the demo.", startSecond: 0, endSecond: 2 }, - { text: " Today we are looking at", startSecond: 2, endSecond: 4 }, - { text: " the transcription component,", startSecond: 4, endSecond: 6 }, - { text: " which highlights words", startSecond: 6, endSecond: 8 }, - { text: " as audio plays.", startSecond: 8, endSecond: 10 }, - { text: " Each segment is clickable", startSecond: 10, endSecond: 12 }, - { text: " and can seek to", startSecond: 12, endSecond: 14 }, - { text: " the corresponding position", startSecond: 14, endSecond: 16 }, - { text: " in the audio track.", startSecond: 16, endSecond: 18 }, -]; - -export function TranscriptionDemo() { - const [currentTime, setCurrentTime] = useState(0); - - return ( -
-
- - - {currentTime.toFixed(1)}s - - -
- - - {(segment, index) => ( - - )} - -
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/voice-selector-demo.tsx b/apps/docs/src/components/docs/ai-elements/voice-selector-demo.tsx deleted file mode 100644 index a5fe8b04..00000000 --- a/apps/docs/src/components/docs/ai-elements/voice-selector-demo.tsx +++ /dev/null @@ -1,137 +0,0 @@ -"use client"; - -import { - Button, - VoiceSelector, - VoiceSelectorAccent, - VoiceSelectorAge, - VoiceSelectorAttributes, - VoiceSelectorBullet, - VoiceSelectorContent, - VoiceSelectorDescription, - VoiceSelectorEmpty, - VoiceSelectorGender, - VoiceSelectorGroup, - VoiceSelectorInput, - VoiceSelectorItem, - VoiceSelectorList, - VoiceSelectorName, - VoiceSelectorPreview, - VoiceSelectorSeparator, - VoiceSelectorTrigger, -} from "ghost-ui"; -import { useState } from "react"; - -const voices = [ - { - id: "alloy", - name: "Alloy", - gender: "non-binary" as const, - accent: "american" as const, - age: "Young Adult", - description: "Versatile, balanced tone", - }, - { - id: "echo", - name: "Echo", - gender: "male" as const, - accent: "american" as const, - age: "Adult", - description: "Warm, resonant baritone", - }, - { - id: "fable", - name: "Fable", - gender: "female" as const, - accent: "british" as const, - age: "Adult", - description: "Expressive storyteller", - }, - { - id: "onyx", - name: "Onyx", - gender: "male" as const, - accent: "american" as const, - age: "Mature", - description: "Deep, authoritative", - }, - { - id: "nova", - name: "Nova", - gender: "female" as const, - accent: "australian" as const, - age: "Young Adult", - description: "Bright, energetic", - }, - { - id: "shimmer", - name: "Shimmer", - gender: "female" as const, - accent: "irish" as const, - age: "Adult", - description: "Soft, calming presence", - }, -]; - -export function VoiceSelectorDemo() { - const [selected, setSelected] = useState(undefined); - - return ( -
-

- A dialog-based voice picker with search, gender, accent, and preview - controls. -

- - - - - - - - - - No voices found. - - {voices.map((voice) => ( - setSelected(voice.id)} - > -
-
-
- {voice.name} - - - - - - {voice.age} - -
- - {voice.description} - -
- { - /* no-op in demo */ - }} - /> -
-
- ))} -
- -
-
-
-
- ); -} diff --git a/apps/docs/src/components/docs/ai-elements/web-preview-demo.tsx b/apps/docs/src/components/docs/ai-elements/web-preview-demo.tsx deleted file mode 100644 index 76c8253b..00000000 --- a/apps/docs/src/components/docs/ai-elements/web-preview-demo.tsx +++ /dev/null @@ -1,52 +0,0 @@ -"use client"; - -import { - WebPreview, - WebPreviewBody, - WebPreviewConsole, - WebPreviewNavigation, - WebPreviewNavigationButton, - WebPreviewUrl, -} from "ghost-ui"; -import { ArrowLeftIcon, ArrowRightIcon, RefreshCwIcon } from "lucide-react"; - -export function WebPreviewDemo() { - return ( -
- - - - - - - - - - - - - - - - -
- ); -} diff --git a/apps/docs/src/components/docs/bento/activity-goal.tsx b/apps/docs/src/components/docs/bento/activity-goal.tsx deleted file mode 100644 index f7f1c2d4..00000000 --- a/apps/docs/src/components/docs/bento/activity-goal.tsx +++ /dev/null @@ -1,63 +0,0 @@ -"use client"; - -import { - Button, - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from "ghost-ui"; -import { Minus, Plus } from "lucide-react"; -import * as React from "react"; - -export function CardsActivityGoal() { - const [amount, setAmount] = React.useState(350); - - function onClick(adjustment: number) { - setAmount(Math.max(200, Math.min(400, amount + adjustment))); - } - - return ( - - - Payment Amount - Set your payment amount. - - -
- -
-
${amount}
-
- USD -
-
- -
-
- - - -
- ); -} diff --git a/apps/docs/src/components/docs/bento/calendar.tsx b/apps/docs/src/components/docs/bento/calendar.tsx deleted file mode 100644 index e1971caf..00000000 --- a/apps/docs/src/components/docs/bento/calendar.tsx +++ /dev/null @@ -1,24 +0,0 @@ -"use client"; - -import { addDays } from "date-fns"; -import { Calendar, Card, CardContent } from "ghost-ui"; - -const start = new Date(2023, 5, 5); - -export function CardsCalendar() { - return ( - - - - - - ); -} diff --git a/apps/docs/src/components/docs/bento/chat.tsx b/apps/docs/src/components/docs/bento/chat.tsx deleted file mode 100644 index 85663470..00000000 --- a/apps/docs/src/components/docs/bento/chat.tsx +++ /dev/null @@ -1,249 +0,0 @@ -"use client"; - -import { - Avatar, - AvatarFallback, - AvatarImage, - Button, - Card, - CardContent, - CardFooter, - CardHeader, - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, - cn, - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - Input, - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "ghost-ui"; -import { Check, Plus, Send } from "lucide-react"; -import * as React from "react"; - -const users = [ - { - name: "Olivia Martin", - email: "m@example.com", - }, - { - name: "Isabella Nguyen", - email: "isabella.nguyen@email.com", - }, - { - name: "Emma Wilson", - email: "emma@example.com", - }, - { - name: "Jackson Lee", - email: "lee@example.com", - }, - { - name: "William Kim", - email: "will@email.com", - }, -] as const; - -type User = (typeof users)[number]; - -export function CardsChat() { - const [open, setOpen] = React.useState(false); - const [selectedUsers, setSelectedUsers] = React.useState([]); - - const [messages, setMessages] = React.useState([ - { - role: "agent", - content: "Hi, how can I help you today?", - }, - { - role: "user", - content: "Hey, I'm having trouble with my account.", - }, - { - role: "agent", - content: "What seems to be the problem?", - }, - { - role: "user", - content: "I can't log in.", - }, - ]); - const [input, setInput] = React.useState(""); - const inputLength = input.trim().length; - - return ( - <> - - -
- - OM - -
-

Sofia Davis

-

m@example.com

-
-
- - - - - - New message - - -
- -
- {messages.map((message, index) => ( -
- {message.content} -
- ))} -
-
- -
{ - event.preventDefault(); - if (inputLength === 0) return; - setMessages([ - ...messages, - { - role: "user", - content: input, - }, - ]); - setInput(""); - }} - className="flex w-full items-center space-x-2" - > - setInput(event.target.value)} - /> - -
-
-
- - - - New message - - Invite a user to this thread. This will create a new group - message. - - - - - - No users found. - - {users.map((user) => ( - { - if (selectedUsers.includes(user)) { - return setSelectedUsers( - selectedUsers.filter( - (selectedUser) => selectedUser !== user, - ), - ); - } - - return setSelectedUsers( - [...users].filter((u) => - [...selectedUsers, user].includes(u), - ), - ); - }} - > - - {user.name[0]} - -
-

- {user.name} -

-

- {user.email} -

-
- {selectedUsers.includes(user) ? ( - - ) : null} -
- ))} -
-
-
- - {selectedUsers.length > 0 ? ( -
- {selectedUsers.map((user) => ( - - {user.name[0]} - - ))} -
- ) : ( -

- Select users to add to this thread. -

- )} - -
-
-
- - ); -} diff --git a/apps/docs/src/components/docs/bento/cookie-settings.tsx b/apps/docs/src/components/docs/bento/cookie-settings.tsx deleted file mode 100644 index 515542a8..00000000 --- a/apps/docs/src/components/docs/bento/cookie-settings.tsx +++ /dev/null @@ -1,60 +0,0 @@ -"use client"; - -import { - Button, - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, - Label, - Switch, -} from "ghost-ui"; - -export function CardsCookieSettings() { - return ( - - - Cookie Settings - Manage your cookie settings here. - - -
- - -
-
- - -
-
- - -
-
- - - -
- ); -} diff --git a/apps/docs/src/components/docs/bento/create-account.tsx b/apps/docs/src/components/docs/bento/create-account.tsx deleted file mode 100644 index 236868cd..00000000 --- a/apps/docs/src/components/docs/bento/create-account.tsx +++ /dev/null @@ -1,60 +0,0 @@ -"use client"; - -import { - Button, - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, - Input, - Label, -} from "ghost-ui"; -import { Icons } from "@/components/docs/icons"; - -export function CardsCreateAccount() { - return ( - - - Create an account - - Enter your email below to create your account - - - -
- - -
-
-
- -
-
- - Or continue with - -
-
-
- - -
-
- - -
-
- - - -
- ); -} diff --git a/apps/docs/src/components/docs/bento/data-table.tsx b/apps/docs/src/components/docs/bento/data-table.tsx deleted file mode 100644 index 239bd1c7..00000000 --- a/apps/docs/src/components/docs/bento/data-table.tsx +++ /dev/null @@ -1,322 +0,0 @@ -"use client"; - -import { - ColumnDef, - ColumnFiltersState, - flexRender, - getCoreRowModel, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - SortingState, - useReactTable, - VisibilityState, -} from "@tanstack/react-table"; -import { - Button, - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, - Checkbox, - DropdownMenu, - DropdownMenuCheckboxItem, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, - Input, - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "ghost-ui"; -import { ArrowUpDown, ChevronDown, MoreHorizontal } from "lucide-react"; -import * as React from "react"; - -const data: Payment[] = [ - { - id: "m5gr84i9", - amount: 316, - status: "success", - email: "ken99@example.com", - }, - { - id: "3u1reuv4", - amount: 242, - status: "success", - email: "Abe45@example.com", - }, - { - id: "derv1ws0", - amount: 837, - status: "processing", - email: "Monserrat44@example.com", - }, - { - id: "bhqecj4p", - amount: 721, - status: "failed", - email: "carmella@example.com", - }, -]; - -export type Payment = { - id: string; - amount: number; - status: "pending" | "processing" | "success" | "failed"; - email: string; -}; - -export const columns: ColumnDef[] = [ - { - id: "select", - header: ({ table }) => ( - table.toggleAllPageRowsSelected(!!value)} - aria-label="Select all" - /> - ), - cell: ({ row }) => ( - row.toggleSelected(!!value)} - aria-label="Select row" - /> - ), - enableSorting: false, - enableHiding: false, - }, - { - accessorKey: "status", - header: "Status", - cell: ({ row }) => ( -
{row.getValue("status")}
- ), - }, - { - accessorKey: "email", - header: ({ column }) => { - return ( - - ); - }, - cell: ({ row }) =>
{row.getValue("email")}
, - }, - { - accessorKey: "amount", - header: () =>
Amount
, - cell: ({ row }) => { - const amount = parseFloat(row.getValue("amount")); - - // Format the amount as a dollar amount - const formatted = new Intl.NumberFormat("en-US", { - style: "currency", - currency: "USD", - }).format(amount); - - return ( -
{formatted}
- ); - }, - }, - { - id: "actions", - enableHiding: false, - cell: ({ row }) => { - const payment = row.original; - - return ( - - - - - - Actions - navigator.clipboard.writeText(payment.id)} - > - Copy payment ID - - - View customer - View payment details - - - ); - }, - }, -]; - -export function CardsDataTable() { - const [sorting, setSorting] = React.useState([]); - const [columnFilters, setColumnFilters] = React.useState( - [], - ); - const [columnVisibility, setColumnVisibility] = - React.useState({}); - const [rowSelection, setRowSelection] = React.useState({}); - - const table = useReactTable({ - data, - columns, - onSortingChange: setSorting, - onColumnFiltersChange: setColumnFilters, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getSortedRowModel: getSortedRowModel(), - getFilteredRowModel: getFilteredRowModel(), - onColumnVisibilityChange: setColumnVisibility, - onRowSelectionChange: setRowSelection, - state: { - sorting, - columnFilters, - columnVisibility, - rowSelection, - }, - }); - - return ( - - - Payments - Manage your payments. - - -
- - table.getColumn("email")?.setFilterValue(event.target.value) - } - className="max-w-sm" - /> - - - - - - {table - .getAllColumns() - .filter((column) => column.getCanHide()) - .map((column) => { - return ( - - column.toggleVisibility(!!value) - } - > - {column.id} - - ); - })} - - -
-
- - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - return ( - - {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ); - })} - - ))} - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ))} - - )) - ) : ( - - - No results. - - - )} - -
-
-
-
- {table.getFilteredSelectedRowModel().rows.length} of{" "} - {table.getFilteredRowModel().rows.length} row(s) selected. -
-
- - -
-
-
-
- ); -} diff --git a/apps/docs/src/components/docs/bento/index.tsx b/apps/docs/src/components/docs/bento/index.tsx deleted file mode 100644 index bf01514f..00000000 --- a/apps/docs/src/components/docs/bento/index.tsx +++ /dev/null @@ -1,100 +0,0 @@ -"use client"; - -import { useIsMobile } from "ghost-ui"; -import { lazy, Suspense } from "react"; -import { CardsChat } from "@/components/docs/bento/chat"; -import { CardsCookieSettings } from "@/components/docs/bento/cookie-settings"; -import { CardsCreateAccount } from "@/components/docs/bento/create-account"; -import { CardsPaymentMethod } from "@/components/docs/bento/payment-method"; -import { CardsReportIssue } from "@/components/docs/bento/report-issue"; -import { CardsShare } from "@/components/docs/bento/share"; -import { CardsTeamMembers } from "@/components/docs/bento/team-members"; - -const CardsStats = lazy(() => - import("@/components/docs/bento/stats").then((m) => ({ - default: m.CardsStats, - })), -); -const CardsCalendar = lazy(() => - import("@/components/docs/bento/calendar").then((m) => ({ - default: m.CardsCalendar, - })), -); -const CardsActivityGoal = lazy(() => - import("@/components/docs/bento/activity-goal").then((m) => ({ - default: m.CardsActivityGoal, - })), -); -const CardsMetric = lazy(() => - import("@/components/docs/bento/metric").then((m) => ({ - default: m.CardsMetric, - })), -); -const CardsDataTable = lazy(() => - import("@/components/docs/bento/data-table").then((m) => ({ - default: m.CardsDataTable, - })), -); - -function CalendarMetricGroup() { - return ( -
- - - -
- - - -
-
- - - -
-
- ); -} - -export function BentoDemo() { - const isMobile = useIsMobile(); - - return ( -
-
- - - - {isMobile && } -
-
- - - -
-
- - -
- -
-
-
-
-
- {!isMobile && ( - <> - - - - - - )} - -
- -
-
-
- ); -} diff --git a/apps/docs/src/components/docs/bento/metric.tsx b/apps/docs/src/components/docs/bento/metric.tsx deleted file mode 100644 index 17d3c52f..00000000 --- a/apps/docs/src/components/docs/bento/metric.tsx +++ /dev/null @@ -1,105 +0,0 @@ -"use client"; - -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, - ChartConfig, - ChartContainer, - ChartTooltip, - ChartTooltipContent, -} from "ghost-ui"; -import { Line, LineChart } from "recharts"; - -const data = [ - { - average: 400, - today: 240, - }, - { - average: 300, - today: 139, - }, - { - average: 200, - today: 980, - }, - { - average: 278, - today: 390, - }, - { - average: 189, - today: 480, - }, - { - average: 239, - today: 380, - }, - { - average: 349, - today: 430, - }, -]; - -const chartConfig = { - today: { - label: "Current Value", - color: "hsl(var(--primary))", - }, - average: { - label: "Average Value", - color: "hsl(var(--primary))", - }, -} satisfies ChartConfig; - -export function CardsMetric() { - return ( - - - Portfolio Value - - Your portfolio is performing above its 7-day average. - - - - - - - - } /> - - - - - ); -} diff --git a/apps/docs/src/components/docs/bento/payment-amount.tsx b/apps/docs/src/components/docs/bento/payment-amount.tsx deleted file mode 100644 index d2b84774..00000000 --- a/apps/docs/src/components/docs/bento/payment-amount.tsx +++ /dev/null @@ -1,63 +0,0 @@ -"use client"; - -import { - Button, - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from "ghost-ui"; -import { Minus, Plus } from "lucide-react"; -import * as React from "react"; - -export function PaymentAmount() { - const [amount, setAmount] = React.useState(350); - - function onClick(adjustment: number) { - setAmount(Math.max(200, Math.min(400, amount + adjustment))); - } - - return ( - - - Payment Amount - Set your payment amount. - - -
- -
-
${amount}
-
- USD -
-
- -
-
- - - -
- ); -} diff --git a/apps/docs/src/components/docs/bento/payment-method.tsx b/apps/docs/src/components/docs/bento/payment-method.tsx deleted file mode 100644 index 7df3c97e..00000000 --- a/apps/docs/src/components/docs/bento/payment-method.tsx +++ /dev/null @@ -1,138 +0,0 @@ -"use client"; - -import { - Button, - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, - Input, - Label, - RadioGroup, - RadioGroupItem, - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "ghost-ui"; -import { Icons } from "@/components/docs/icons"; - -export function CardsPaymentMethod() { - return ( - - - Payment Method - - Add a new payment method to your account. - - - - -
- - -
-
- - -
-
-
- - -
-
- - -
-
- - -
-
-
- - -
-
- - -
-
- - -
-
-
- - - -
- ); -} diff --git a/apps/docs/src/components/docs/bento/report-issue.tsx b/apps/docs/src/components/docs/bento/report-issue.tsx deleted file mode 100644 index 4cdf6b29..00000000 --- a/apps/docs/src/components/docs/bento/report-issue.tsx +++ /dev/null @@ -1,93 +0,0 @@ -"use client"; - -import { - Button, - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, - Input, - Label, - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, - Textarea, -} from "ghost-ui"; -import * as React from "react"; - -export function CardsReportIssue() { - const id = React.useId(); - - return ( - - - Report an issue - - What area are you having problems with? - - - -
-
- - -
-
- - -
-
-
- - -
-
- -