q2 create: native CLI command with artifact scaffolding (bd-oa5kd2yr)#409
Merged
Conversation
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>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements
q2 create project website <dir>end-to-end from the native CLI, on anArtifactProviderseam (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
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..gitignoreensured with/.quarto/(Q1's**/*.quarto_ipynbdropped — no Q2 producer).q2 create --jsonreads a JSON directive from stdin, emits one JSON result object on stdout, errors/warnings asJsonDiagnosticlines on stderr (same convention asq2 render --json-errors).q2 create --list [--json]emits the artifact/choice registry.--dry-run/"dry_run": truereport the full file plan without writing.Scaffolds (
quarto-project-create, shared with the hub-client WASM path)_quarto.ymlwithwebsite.title(the oldproject.titleplacement left navbar/sidebar untitled — Q2's website pipeline readswebsite.title), navbar (Home + About),theme: cosmo,css: styles.css,toc: true; newabout.qmd+styles.css.project.resources: [styles.css]ships the stylesheet to_site/until bd-b87tmmi4 (Q2 doesn't auto-copycss:-referenced files; discovered during e2e) is fixed. Nobrandtheme marker — Q2 deliberately hard-errors (Q-14-1) on an unconfigured one.index.qmd.create_projectAPI removed; no external consumer).Testing
TDD throughout (expected failures recorded in the plan before implementation):
_quarto.ymltests/integration/create.rs)cargo xtask verifygreen; clippy cleanAbout – <title>prefixing, and a shipped stylesheetPlan:
claude-notes/plans/2026-07-23-q2-create-command.md🤖 Generated with Claude Code