diff --git a/.cursor/commands/speckit.aftercode.md b/.cursor/commands/speckit.aftercode.md new file mode 100644 index 0000000000..f1db46544b --- /dev/null +++ b/.cursor/commands/speckit.aftercode.md @@ -0,0 +1,63 @@ +--- +description: 'Automatically execute the subsequent code delivery pipeline: changelog → commit → prgenerate, in strict sequential order.' +handoffs: + - label: 'Create Pull Request' + agent: 'speckit.prcreate' + prompt: 'Create the GitHub Pull Request using the generated body' + send: true +--- + +## User Input + +```text +$ARGUMENTS +``` + +## Outline + +This command orchestrates the code delivery pipeline, executing the `changelog`, `commit`, and `prgenerate` phases in a strict, sequential, and non-interactive flow. It ensures that the entire process, from generating change files to preparing the PR body, is automated while maintaining the precise behavior of each individual step. + +**Execution is strictly sequential. No steps will be skipped or run in parallel.** + +### Phase 1: Generate Changelog (`/speckit.changelog`) + +- **Action**: Initiates the delivery pipeline by invoking `/speckit.changelog`. +- **Process**: + - Collects commits since a base branch (defaulting to `develop`). + - Infers the version bump type (`patch`, `minor`, `major`) automatically from commit messages unless an explicit `bumpType` is passed in `$ARGUMENTS`. + - Generates the necessary change files within the `common/changes/` directory. + - Any parameters provided in `$ARGUMENTS` will be passed through to override default behavior. +- **Handoff**: Upon successful completion, automatically triggers the `commit` phase. +- **Output Report**: + - "Phase 1 (Changelog) completed." + - `CREATED_FILES`: [List of paths to generated files in `common/changes/`] + - `VALIDATION`: "Changelog message conforms to Conventional Commits standards." + +### Phase 2: Create Commit (`/speckit.commit`) + +- **Action**: Triggered automatically after `changelog` completes. +- **Process**: + - Stages all current workspace changes (`git add --all`). + - Generates a Conventional Commits-compliant commit message, prioritizing `$ARGUMENTS`, then `common/changes/` content, and finally a generic message. + - Executes `git commit`. + - Pushes the commit to the remote origin by default. + - The `message` and `pushAfterCommit` behaviors can be overridden via `$ARGUMENTS`. +- **Handoff**: Upon successful completion, automatically triggers the `prgenerate` phase. +- **Output Report**: + - "Phase 2 (Commit) completed." + - `COMMIT_MESSAGE`: [The full commit message used] + - `PUSH_STATUS`: "Branch [branch-name] pushed to origin." + +### Phase 3: Generate PR Body (`/speckit.prgenerate`) + +- **Action**: The final phase, realized via the native `handoff` from `/speckit.commit` to `/speckit.prgenerate` after `commit` completes. This `/speckit.aftercode` command does not declare its own `handoff` entry for `/speckit.prgenerate` to avoid duplicate execution. +- **Process**: + - Selects the appropriate PR template (`.github/PULL_REQUEST_TEMPLATE/pr_cn.md` or `.github/PULL_REQUEST_TEMPLATE.md`), defaulting to Chinese unless specified in `$ARGUMENTS`. + - Populates the template with content from `common/changes/`, commit history, and any other available artifacts. + - Saves the final, populated PR body to `.trae/output/pr.body.local.md`. +- **Handoff**: This step retains its original `handoff` to `speckit.prcreate`. The `/speckit.aftercode` command depends strictly on the original single-step handoff chain and does **not** introduce any additional handoffs, preventing `prgenerate` (or downstream steps) from running more than once. +- **Output Report**: + - "Phase 3 (PR Generate) completed." + - `OUTPUT_FILE`: ".trae/output/pr.body.local.md" + - `VALIDATION_SUMMARY`: "PR body generated. Please review the file before creating the pull request." + - `NEXT_STEPS`: "The `speckit.prcreate` command may have been triggered automatically. If not, you can run it manually to create the GitHub Pull Request." diff --git a/.cursor/commands/speckit.auto.md b/.cursor/commands/speckit.auto.md new file mode 100644 index 0000000000..201ae01afd --- /dev/null +++ b/.cursor/commands/speckit.auto.md @@ -0,0 +1,67 @@ +--- +description: Automatically execute the four core phases of the Spec-Driven Development (SDD) pipeline: specify → plan → tasks → implement, in strict sequential order. +handoffs: + - label: Execute After-Code Pipeline + agent: speckit.aftercode + prompt: Execute the after-code pipeline. + send: true +--- + +## User Input + +```text +$ARGUMENTS +``` + +## Outline + +This command orchestrates the full Spec-Driven Development (SDD) lifecycle, executing each of the four core phases in a strict, sequential, and non-interactive manner. It ensures that each phase completes before the next one begins, mirroring the exact semantics of executing each `/speckit.*` command individually. + +**Execution is strictly sequential. Parallel execution of phases is prohibited.** + +### Pre-flight Check + +1. **Validate User Input**: + - If `$ARGUMENTS` is empty, the process will halt with an error. The initial feature description is mandatory to start the `specify` phase. + +### Phase 1: Specify (`/speckit.specify`) + +- **Action**: The workflow begins by invoking `/speckit.specify` with the provided `$ARGUMENTS`. This is the single entry point for user input. +- **Process**: This phase will automatically generate a feature branch, create the `spec.md` file, and run all associated validation and checklist generation steps as defined in the `speckit.specify` command. +- **Handoff**: Upon successful completion, it will automatically trigger the `plan` phase. +- **Output Report**: + - "Phase 1 (Specify) completed." + - `BRANCH_NAME`: [The generated feature branch name] + - `SPEC_FILE`: [Path to the generated spec.md file] + +### Phase 2: Plan (`/speckit.plan`) + +- **Action**: Triggered automatically after `specify` completes. It requires no additional arguments and operates on the context established by the previous phase. +- **Process**: This phase will generate the `plan.md` and all its associated design artifacts (e.g., `research.md`, `data-model.md`, `contracts/`). It strictly follows the "Phase 0" and "Phase 1" steps outlined in the `speckit.plan` command. +- **Handoff**: Upon successful completion, it will automatically trigger the `tasks` phase. +- **Output Report**: + - "Phase 2 (Plan) completed." + - `IMPL_PLAN`: [Path to the generated plan.md file] + - `DERIVED_ARTIFACTS`: [List of paths to other generated files like research.md] + +### Phase 3: Tasks (`/speckit.tasks`) + +- **Action**: Triggered automatically after `plan` completes. +- **Process**: This phase reads the `plan.md` and other design documents to generate a detailed, actionable `tasks.md` file, organizing work into phases based on user stories. The command name `speckit.tasks` is used to align with VChart's existing commands. +- **Handoff**: Upon successful completion, rely on the native `handoffs` of `/speckit.tasks` to automatically trigger `/speckit.implement`; `/speckit.auto` MUST NOT trigger `/speckit.implement` directly to avoid duplicate execution. +- **Output Report**: + - "Phase 3 (Tasks) completed." + - `TASKS_FILE`: [Path to the generated tasks.md file] + - `SUMMARY`: [Total task count and parallel opportunities] + +### Phase 4: Implement (`/speckit.implement`) + +- **Action**: This phase corresponds to the `/speckit.implement` run that is started by the native `handoff` from `/speckit.tasks`. `/speckit.auto` MUST NOT start a separate `/speckit.implement` execution. +- **Process**: Continue (or observe) the implementation based on `tasks.md`, strictly following all rules of the original `speckit.implement` command, including the checklist gate behavior (ask for explicit confirmation before proceeding when checklists are incomplete). If `/speckit.implement` has already finished, do **not** re-run it; only summarize its results. +- **Completion**: The `auto` workflow conceptually ends after the implementation phase has completed. The subsequent `aftercode` pipeline must be initiated manually. +- **Output Report**: + - "Phase 4 (Implement) completed." + - `STATUS`: [Summary of task execution, e.g., "All tasks completed successfully."] + - `NEXT_STEPS`: "Ready to proceed with the code delivery pipeline. Run `/speckit.aftercode` to continue." + +**Note**: If any downstream phase (for example `tasks` or `implement`) has already been completed via the native handoff chain of the upstream commands, do not invoke it again. Simply acknowledge its completion and record the relevant outputs before moving on. diff --git a/.cursor/commands/speckit.changelog.md b/.cursor/commands/speckit.changelog.md index 528928dae0..3df0d58908 100755 --- a/.cursor/commands/speckit.changelog.md +++ b/.cursor/commands/speckit.changelog.md @@ -1,5 +1,5 @@ --- -description: 'Generate Rush changes entries for VChart monorepo based on commits since base branch; infer bump type; aggregate messages.' +description: 'Generate Rush change entries for VChart monorepo using specs//plan.md as the only semantic source; infer bump type from the spec with zero-input defaults.' handoffs: - label: 'Commit Changes' agent: 'speckit.commit' @@ -15,21 +15,49 @@ $ARGUMENTS ## Outline -1. **Read Inputs**: - - `sinceBranch` (default: `develop`): The base branch for collecting commits. - - `bumpType` (default: `auto`): Explicit bump type (`patch`, `minor`, `major`). If `auto`, infer from commit messages. - - `message` (optional): A custom message to use for the changelog entry. +1. **Resolve feature spec from branch**: + - Treat this command as *zero/low-input*: if `$ARGUMENTS` is empty, infer everything from the current branch and `specs` directory. + - Derive the feature prefix from the current branch name (for example, `001-fix-bug` → prefix `001`) and locate the matching directory under `specs/` whose name starts with that prefix. + - From that directory, resolve: + - `plan.md` as the primary source of truth for the change description. + - `checklists/requirements.md` as an optional, secondary source when the plan lacks a clear summary. + - If no matching `specs//` can be found, return an error instead of guessing. -2. **Gather Context**: - - Collect commits and file changes between `sinceBranch` and `HEAD`. - - If `bumpType` is `auto`, analyze commit messages (`feat`, `fix`, `BREAKING CHANGE`) to determine the appropriate version bump. +2. **Extract Summary from specs-only context**: + - From `plan.md`, read the `## Summary` section and take the first non-empty line as the feature summary. + - If the `Summary` section is empty or missing, fall back in order to: + - The top-level title of `plan.md` (for example, `Implementation Plan: ...`). + - A concise line derived from `checklists/requirements.md`. + - The feature directory name or branch name. + - Normalize the final summary to a single line (strip markdown markers, collapse whitespace) without inventing new wording. -3. **Execute Rush Change**: - - The agent will run `rush change`, providing the determined bump type and an aggregated message. - - The message is constructed from the `message` input or summarized from commit history (and enriched with issue titles if `githubToken` is present). - - This action generates changelog files under `common/changes/`. +3. **Infer bump type (spec-driven)**: + - Default `bumpType` to `patch`. + - Scan the content of `plan.md` (case-insensitive) for explicit markers: + - If it contains `BREAKING CHANGE` or a clear `MAJOR` marker → use `major`. + - Else if it contains a clear `MINOR` marker → use `minor`. + - Else if it only contains `PATCH` or no marker at all → keep `patch`. + - If the user passes an explicit bump type argument, validate it against `patch | minor | major | none` and override the inferred value. `none` means "no version bump" while still allowing a change file to be written if Rush supports it. -4. **Report Outputs**: - - List the paths of the generated changelog files. - - Confirm the final message used. - - Verify that the generated message complies with Conventional Commits (`commitlint`) standards. +4. **Construct the Rush change message (no git history)**: + - Build a single-line message using the spec id and the inferred summary, for example: + - `update changes for : ` + - If the user provided an explicit message argument, prefer that over the inferred one. + - Do **not** analyze git commit history, file diffs, or `common/changes` contents when constructing this message; the only semantic source is `specs//`. + +5. **Execute Rush change (no push, no extra commits)**: + - From the repository root, call Rush in bulk mode, for example: + - `rush change --bulk --bump-type --message ""` + - This command is responsible only for generating or updating change files under `common/changes/`. + - It **must not**: + - Push any branch. + - Create additional commits. + - Modify documentation-only changelog files. + +6. **Report outputs (spec-centric)**: + - Echo the resolved values: + - Feature id / spec directory. + - Paths to `plan.md` and `requirements.md` used. + - The final `bumpType` and `message`. + - Optionally, list the `common/changes/*.json` files created or updated by this run (for example, by inspecting the directory or `git status`). + - Ensure the final message is compatible with the repository's `commitlint` conventions when reused downstream by `/speckit.commit`. diff --git a/.cursor/commands/speckit.commit.md b/.cursor/commands/speckit.commit.md index 8cef4d8460..47e3026865 100755 --- a/.cursor/commands/speckit.commit.md +++ b/.cursor/commands/speckit.commit.md @@ -1,5 +1,5 @@ --- -description: "Create an intelligent commit (Conventional Commits) bundling workspace changes; optionally push to origin." +description: "Create a local Conventional Commits-style commit using only specs//plan.md for semantics; do not push to origin." handoffs: - label: "Generate PR Body" agent: "speckit.prgenerate" @@ -15,21 +15,64 @@ $ARGUMENTS ## Outline -1. **Pre-flight Checks**: - * Verify the current branch and check if the working tree is dirty. - * If `commitAllowEmpty=false` (default) and there are no changes, the process will be skipped. +1. **Pre-flight checks (local-only)**: + * Treat this command as zero-input by default: if `$ARGUMENTS` is empty, it should still be able to run end-to-end. + * Verify the current branch name follows the feature convention (e.g. `001-some-feature`) so it can be mapped to a `specs//` directory. + * Confirm there are staged or unstaged changes in the working tree; if there are no changes, abort without creating a commit. + * Interpret any CLI flags only as behaviour toggles (e.g. `--edit`, `--no-verify`) and **not** as a manual commit message. -2. **Generate Commit Message**: - * **Priority 1**: Use the `message` argument if provided. - * **Priority 2**: If no message is provided, extract the subject from the latest entry in `common/changes/`. - * **Priority 3**: If neither is available, generate a generic subject like `chore: sync changes (N files)`. - * The commit type and scope are inferred from file paths and changelog entries. +2. **Load spec context from specs/**: + * Derive the feature prefix from the current branch name and resolve the matching `specs//` directory using prefix-based lookup (e.g. `001-` → `specs/001-...`). + * Read `specs//plan.md` and extract: + - The `## Summary` section — first non-empty line for the natural-language summary. + - The top-level title (e.g. `Implementation Plan: ...`) as a fallback description. + - The `### Source Code (repository root)` code block, which lists the source layout for this feature. -3. **Execute Git Actions**: - * The agent will run `git add --all` to stage all changes. - * It will then execute `git commit` with the generated message. - * If `pushAfterCommit=true` (default), it will push the commit to the remote origin. +3. **Infer `type` from Summary keywords**: + * Build a short text corpus from the Summary sentence and plan title. + * Using **only** that text, map the commit `type` according to the following rules (case-insensitive): + - Contains `bug` or `fix` → `fix` + - Contains `refactor` or `refactoring` → `refactor` + - Contains `perf` or `performance` → `perf` + - Contains `docs`, `doc`, or `documentation` → `docs` + - Contains `test`, `tests`, or `unit` → `test` + - Contains `implement`, `implementation`, `add`, `support`, or `feature` → `feat` + - Otherwise → `chore` + * Do **not** inspect file paths, git history, or `common/changes` when choosing the type. -4. **Report Outputs**: - * `commit_message`: The full commit message used. - * `pushed_branch`: The name of the branch that was pushed (if applicable). +4. **Infer `scope` from Source Code paths**: + * From the `Source Code (repository root)` block in `plan.md`, parse all paths that live under `packages//...`. + * Collect the second-level directory names (e.g. `packages/vchart/` → `vchart`, `packages/vchart-types/` → `vchart-types`), de-duplicate, and sort. + * Build the `scope` as: + - A comma-separated list of all such package names when one or more packages are present. + - The literal string `monorepo` when no `packages/*` paths can be found. + * Do not attempt to infer scope from other folders or git diffs. + +5. **Build a spec-driven `subject` (no AI rewriting)**: + * Take the first sentence from the Summary section of `plan.md` as the base subject (trim markdown, collapse whitespace). + * Enforce a minimum length of 16 characters: + - If the subject is too short, append structured identifiers such as the spec id and primary package names: + - Example: `Fix layout bug` → `Fix layout bug (spec 001-fix-subtitle-layout-bug; vchart)` + * Optionally truncate extremely long subjects to a reasonable maximum length (while keeping them readable). + * The subject must only be **reformatted** from the spec content; do not invent new semantics or free-form text. + +6. **Assemble and validate the commit header**: + * Compose the final header as: + - ``(): `` + e.g. `fix(vchart): Handle subtitle-only title layout` + * If the repository has `commitlint` configured, perform a dry-run check by piping the header into `commitlint` with the local config. + * If validation fails: + - First, clean up the header (e.g. strip non-ASCII control characters, compress spaces) and re-run the dry-run. + - If it still fails and the user requested edit mode (e.g. `--edit`), write the header into a temporary commit message file and proceed with an interactive `git commit -t ` so the user can adjust it manually. + - If edit mode is not enabled, surface a clear error and stop instead of guessing a new message. + +7. **Execute Git commit (no push)**: + * Run `git add -A` from the repository root to stage all changes. + * If edit mode is **not** required, execute `git commit -m "
"` with the validated header. + * If edit mode **is** required, execute `git commit -t ` so the user can refine the message in their editor. + * This command **must not** push to `origin` or any remote; pushing remains a separate, explicit action. + +8. **Report outputs**: + * Return the final commit header string used for `git commit`. + * Indicate whether commitlint validation passed on the first try or required cleanup/edit mode. + * Do not report any `pushed_branch` field, because this command never pushes. diff --git a/.cursor/commands/speckit.prgenerate.md b/.cursor/commands/speckit.prgenerate.md index eeb10ab13a..5bd34b0114 100755 --- a/.cursor/commands/speckit.prgenerate.md +++ b/.cursor/commands/speckit.prgenerate.md @@ -1,5 +1,5 @@ --- -description: 'Generate a well-formed PR body using repo template and local artifacts (changelog, auto-test report). Save to .trae/output/pr.body.local.md by default.' +description: 'Generate a PR body using the GitHub pull request template and specs//plan.md; default to the English template and write to specs//PR_BODY.md.' handoffs: - label: 'Create Pull Request' agent: 'speckit.prcreate' @@ -13,39 +13,63 @@ handoffs: $ARGUMENTS ``` -You **MUST** consider the user input before proceeding (if not empty). +You **MUST** consider the user input before proceeding (if not empty), but treat it only as CLI-style flags (for example, `--lang`, `--out`); the PR content itself must be inferred from the specs directory, not from free-form user text. ## Outline -1. **Determine Template and Context**: - - **Select Template**: - - Check user input for language preference (English or Chinese). - - If Chinese, use template at: `.github/PULL_REQUEST_TEMPLATE/pr_cn.md` - - If English or unspecified, use template at: `.github/PULL_REQUEST_TEMPLATE.md` - - **Infer Context**: - - Get current branch name using `git branch --show-current`. - - Get recent commit messages using `git log -5 --pretty=format:"%s"`. - - Infer PR type (feat, fix, docs, etc.) to verify the checklist items. - -2. **Populate Body Sections**: - - **Changelog**: - - Check `common/changes` directory for change files. - - If files exist, parse them to summarize changes for the `Changelog` section. - - If no files, mark as "N/A" or leave empty. - - **Self-test Summary**: - - Read report from `.trae/output/autotest.report.local.md`. - - If file exists, append summary to the body. - - If missing, add a placeholder indicating no automated test report. - - **Background/Solution**: - - Synthesize a description from commit messages and user input. - - Fill in the "Background and solution" section of the template. - -3. **Generate and Save**: - - **Generate Title**: Create a concise PR title following Conventional Commits (e.g., `feat: add new chart type`). - - **Preview**: Display the generated title and body content to the user for review. - - **Save**: Write the final content to `.trae/output/pr.body.local.md`. - - **Verify**: Check if the file `.trae/output/pr.body.local.md` was created successfully. - -4. **Validation Checklist**: - - Confirm the output file exists. - - Ask user to review the generated body in `.trae/output/pr.body.local.md`. +1. **Determine template and feature context (specs-only)**: + - Treat this command as zero-input by default: if `$ARGUMENTS` is empty, it still must be able to generate a useful PR body. + - Parse `$ARGUMENTS` only for CLI-style options (for example, `--lang`, `--out`): + - If `--lang zh` is present, use the Chinese template at `.github/PULL_REQUEST_TEMPLATE/pr_cn.md`. + - Otherwise, use the English template at `.github/PULL_REQUEST_TEMPLATE.md` (the default; **do not** auto-detect language). + - If an explicit output path is provided (for example, `--out specs/001-foo/PR_BODY.md`), respect it; otherwise, default to `specs//PR_BODY.md`. + - Resolve `specs//` by deriving the numeric prefix from the current branch name and matching it to a directory under `specs/` whose name starts with that prefix. + - From that directory, resolve `plan.md` as the primary context source for the PR. + +2. **Extract PR content from specs**: + - From `plan.md`, read the `## Summary` section and take the first non-empty line as the high-level description of the change. + - Read the `## Technical Context` section and remove any template-only comments, keeping only the concrete technical details. + - Combine these into a structured background text: + - When both are present: `Summary` paragraph followed by a blank line and the `Technical Context` content. + - When only Summary exists: use Summary alone. + - When neither exists: fall back to a short line like `Update for ` derived from the spec directory name. + - Optionally infer a coarse change type (`feat`, `fix`, `docs`, `perf`, `refactor`, `test`, `chore`) from the Summary/Technical Context using the same keyword mapping as `/speckit.commit`. + +3. **Apply type to the template checklist (no structural changes)**: + - Load the chosen PR template as raw markdown and preserve its structure, comments, and placeholders (including any `copilot:summary` markers). + - Locate the section headed `### 🤔 This is a ...` (English) or `### 🤔 这个分支是...` (Chinese). + - Within that section: + - Reset all checklist bullets to unchecked (`- [ ] ...`). + - Identify the line whose label best matches the inferred type (for example, `New feature`, `Bug fix`, `Site / documentation update`, etc.). + - Mark exactly that line as checked (`- [x] ...`). + - Do **not** add, remove, or reorder any checklist items. + +4. **Fill “Background and solution” from specs**: + - For the English template: + - Locate the `### 💡 Background and solution` heading. + - Keep any inline instructions or comments that live directly under the heading (for example, explanatory HTML comments). + - After those instructions, insert the combined background text built from Summary + Technical Context. + - For the Chinese template: + - Locate the `### 💡 问题的背景&解决方案` heading and apply the same approach. + - The inserted text should quote and lightly reformat the spec content but should not invent new requirements or implementation details. + +5. **Fill the Changelog table (English-only content)**: + - Locate the `### 📝 Changelog` section and the language table beneath it. + - Replace the `🇺🇸 English` row’s description cell with a concise English summary derived from the Summary sentence (trimmed to a reasonable length if necessary). + - Leave the `🇨🇳 Chinese` row untouched for the English template; for the Chinese template, you may mirror the same summary there or leave it as a placeholder, depending on the template’s expectations. + - Preserve all table headers, column layout, and any additional rows or comments around the table. + +6. **Write PR body file without touching templates**: + - Render the updated markdown content (with checklist, background, and Changelog injected) into a single PR body string. + - Write this string to the resolved output path (default `specs//PR_BODY.md`), creating parent directories if needed. + - Do **not** modify the original template files under `.github/`. + +7. **Validation checklist**: + - Confirm that the output PR body file exists and is non-empty. + - Confirm that the output PR body file maintains the integrity of the template content, with no additional or deleted part. + - Verify that: + - The “This is a …” / “这个分支是...” section is still present and exactly one checkbox is selected. + - The “Background and solution” / “问题的背景&解决方案” section now references the feature in terms consistent with `plan.md`. + - The Changelog table still renders correctly and has an updated `🇺🇸 English` row. + - Any special placeholders (for example, `copilot:summary`) remain intact and in their original locations. + - Ensure that no content was sourced from git logs, `common/changes`, or `.trae/output`; all semantics must come from the `specs` directory and the chosen PR template.