Skip to content

q2 create: native CLI command with artifact scaffolding (bd-oa5kd2yr)#409

Merged
cscheid merged 4 commits into
mainfrom
feature/bd-oa5kd2yr-q2-create-command
Jul 23, 2026
Merged

q2 create: native CLI command with artifact scaffolding (bd-oa5kd2yr)#409
cscheid merged 4 commits into
mainfrom
feature/bd-oa5kd2yr-q2-create-command

Conversation

@cscheid

@cscheid cscheid commented Jul 23, 2026

Copy link
Copy Markdown
Member

Implements q2 create project website <dir> end-to-end from the native CLI, on an ArtifactProvider seam (Rust port of Q1's ArtifactCreator) so future artifact types (extension, more project types) slot into the same registry. Follow-up strands (interactive prompting, extension artifact, blog scaffold, docs page) will land on this branch.

CLI

  • Positional path: q2 create project <type> <directory> [title], non-interactive. Title defaults to the directory name (choice id for .) with a warning. Q1 directory semantics: merge into an existing dir, hard error on an existing _quarto.yml/_quarto.yaml, per-file skip-if-exists. .gitignore ensured with /.quarto/ (Q1's **/*.quarto_ipynb dropped — no Q2 producer).
  • Machine path (for MCP/LSP/tooling): q2 create --json reads a JSON directive from stdin, emits one JSON result object on stdout, errors/warnings as JsonDiagnostic lines on stderr (same convention as q2 render --json-errors). q2 create --list [--json] emits the artifact/choice registry. --dry-run / "dry_run": true report the full file plan without writing.

Scaffolds (quarto-project-create, shared with the hub-client WASM path)

  • Website scaffold at Q1-familiar shape: _quarto.yml with website.title (the old project.title placement left navbar/sidebar untitled — Q2's website pipeline reads website.title), navbar (Home + About), theme: cosmo, css: styles.css, toc: true; new about.qmd + styles.css. project.resources: [styles.css] ships the stylesheet to _site/ until bd-b87tmmi4 (Q2 doesn't auto-copy css:-referenced files; discovered during e2e) is fixed. No brand theme marker — Q2 deliberately hard-errors (Q-14-1) on an unconfigured one.
  • Default scaffold gains a starter index.qmd.
  • Crate consolidated to one scaffold registry (legacy create_project API removed; no external consumer).

Testing

TDD throughout (expected failures recorded in the plan before implementation):

  • 26 crate tests, incl. serde_yaml round-trips of the rendered _quarto.yml
  • 27 binary-driven CLI integration tests (tests/integration/create.rs)
  • WASM test expectations updated, 6/6 against the rebuilt module
  • Workspace suite 10377/10377; full cargo xtask verify green; clippy clean
  • E2E through the real binary (transcripts in the plan): website create → render produces a working navbar, About – <title> prefixing, and a shipped stylesheet

Plan: claude-notes/plans/2026-07-23-q2-create-command.md

🤖 Generated with Claude Code

cscheid and others added 2 commits July 23, 2026 14:39
Implement `q2 create project website <dir>` end-to-end from the native
CLI, on an ArtifactProvider seam (Rust port of Q1's ArtifactCreator)
so future artifact types slot into the same registry.

CLI (crates/quarto/src/commands/create/):
- Positional path: `q2 create project <type> <directory> [title]`,
  non-interactive; title defaults to the directory name (choice id for
  ".") with a warning; Q1 directory semantics (merge into existing dir,
  hard error on existing _quarto.yml/_quarto.yaml, per-file
  skip-if-exists); .gitignore ensured with `/.quarto/` (Q1's
  `**/*.quarto_ipynb` dropped — no Q2 producer exists).
- Machine path: `q2 create --json` reads a JSON directive from stdin,
  emits a single JSON result on stdout, and reports errors/warnings as
  JsonDiagnostic lines on stderr (the `--json-errors` convention);
  `q2 create --list [--json]` lists the artifact/choice registry;
  `--dry-run` / `"dry_run": true` report the file plan without writing.

quarto-project-create:
- Website scaffold brought to Q1-familiar shape: _quarto.yml with
  website.title (Q2's website pipeline reads website.title — the old
  project.title placement left navbar/sidebar untitled), navbar,
  theme: cosmo, css: styles.css, toc: true; new about.qmd + styles.css.
  project.resources declares styles.css so it reaches _site/ until
  bd-b87tmmi4 (css:-referenced files not auto-copied) is fixed. No
  `brand` marker: Q2 deliberately hard-errors (Q-14-1) on an
  unconfigured brand theme entry.
- Default scaffold gains a starter index.qmd.
- Consolidated to one scaffold registry: removed the legacy
  create_project/CreateProjectOptions/ProjectFile/TemplateFile/
  get_templates path (no external consumer); templates.rs is
  constants-only.

Tests (TDD; failures recorded in the plan before implementation):
- 26 crate tests incl. serde_yaml round-trips of rendered _quarto.yml.
- 27 binary-driven CLI tests (tests/integration/create.rs) covering
  positional/JSON/list/dry-run paths and error contracts.
- projectCreate.wasm.test.ts updated for the new scaffolds (6/6
  against the rebuilt WASM module).
- Workspace suite 10377/10377; full `cargo xtask verify` passed.

Follow-ups filed: bd-hh1erpfx (interactive prompting), bd-j9qz7h25
(extension artifact), bd-r1by4u2a (blog scaffold), bd-1h5r22my (docs
page), bd-b87tmmi4 (css copy bug, discovered during e2e).

Plan: claude-notes/plans/2026-07-23-q2-create-command.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@posit-snyk-bot

posit-snyk-bot commented Jul 23, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

cscheid and others added 2 commits July 23, 2026 14:53
On a real terminal with arguments missing, `q2 create` now prompts
Q1-style instead of erroring: Artifact type -> Project type (select
over implemented choices) -> Directory -> Title (default shown =
directory name, choice id for "."). Accepting the prompted default is
explicit consent, so the interactive path emits no defaulted-title
warning; the non-interactive warning is unchanged.

Gate (Q1 cmd.ts:62-74 parity): prompts fire only when stdin AND stderr
are TTYs, CI is unset, and --no-prompt / --json / --list are absent.
Piped/CI invocations keep the exact previous error contract (all 27
prior integration tests unchanged); new --no-prompt flag forces it.

Implementation: a small Prompter trait seam (commands/create/
prompter.rs) keeps the flow unit-testable without a PTY; the real
prompter uses inquire 0.9.4, chosen because its crossterm backend
matches the crossterm 0.29 already in the runtime tree via pampa (adds
only inquire + dyn-clone + fuzzy-matcher). Prompt UI renders on
stderr; stdout stays reserved for command output. Esc/Ctrl-C maps to
"Create cancelled", exit 1, nothing written. A typed choice is
validated before any prompting, so `q2 create project blog` errors
immediately on a TTY.

Tests (TDD; failures recorded in the plan before implementation):
- 8 scripted-prompter unit tests (flow order, implemented-only select,
  defaults, dry-run propagation, cancellation, early validation)
- 2 integration tests pinning --no-prompt and CI=1 gating
- Real-PTY e2e via expect (transcripts in the plan): full flow with
  arrow-key select, stdout-purity check, --json-on-TTY no-prompt,
  Esc cancel
- Workspace 10387/10387; cargo xtask verify --skip-hub-build passed

Plan: claude-notes/plans/2026-07-23-q2-create-interactive.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…create-command

# Conflicts:
#	hub-client/changelog.md
@cscheid
cscheid merged commit b57d4c8 into main Jul 23, 2026
8 checks passed
@cscheid
cscheid deleted the feature/bd-oa5kd2yr-q2-create-command branch July 23, 2026 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants