feat: Enhance spec management with new hooks and settings features

- Updated test cycle execution steps to streamline agent execution.
- Improved HookDialog component with enhanced validation messages and localization.
- Introduced SpecDialog component for better spec management.
- Added new hooks for fetching and updating specs list and frontmatter.
- Implemented API functions for specs list retrieval and index rebuilding.
- Added localization support for new specs settings and hooks.
- Enhanced SpecsSettingsPage to manage project and personal specs effectively.
- Updated CLI commands to support keyword-based spec loading.
- Improved spec index builder to categorize specs by workflow stages.
This commit is contained in:
catlog22
2026-02-26 22:52:33 +08:00
parent 6155fcc7b8
commit 151b81ee4a
51 changed files with 731 additions and 690 deletions

View File

@@ -24,6 +24,19 @@ import { join, basename, extname, relative } from 'path';
// Types
// ============================================================================
/**
* Spec categories for workflow stage-based loading (used as keywords).
* - exploration: Code exploration, analysis, debugging context
* - planning: Task planning, roadmap, requirements context
* - execution: Implementation, testing, deployment context
*
* Usage: Add these as keywords in spec frontmatter, e.g.:
* keywords: [exploration, auth, security]
*/
export const SPEC_CATEGORIES = ['exploration', 'planning', 'execution'] as const;
export type SpecCategory = typeof SPEC_CATEGORIES[number];
/**
* YAML frontmatter schema for spec MD files.
*/
@@ -45,7 +58,7 @@ export interface SpecIndexEntry {
file: string;
/** Dimension this spec belongs to */
dimension: string;
/** Keywords for matching against user prompts */
/** Keywords for matching against user prompts (may include category markers) */
keywords: string[];
/** Whether this spec is required or optional */
readMode: 'required' | 'optional';
@@ -87,8 +100,9 @@ const VALID_READ_MODES = ['required', 'optional'] as const;
const VALID_PRIORITIES = ['critical', 'high', 'medium', 'low'] as const;
/**
* Directory name for spec index cache files.
* Directory name for spec index cache files (inside .workflow/).
*/
const WORKFLOW_DIR = '.workflow';
const SPEC_INDEX_DIR = '.spec-index';
// ============================================================================
@@ -100,10 +114,10 @@ const SPEC_INDEX_DIR = '.spec-index';
*
* @param projectPath - Project root directory
* @param dimension - The dimension name
* @returns Absolute path to .spec-index/{dimension}.index.json
* @returns Absolute path to .workflow/.spec-index/{dimension}.index.json
*/
export function getIndexPath(projectPath: string, dimension: string): string {
return join(projectPath, SPEC_INDEX_DIR, `${dimension}.index.json`);
return join(projectPath, WORKFLOW_DIR, SPEC_INDEX_DIR, `${dimension}.index.json`);
}
/**
@@ -188,7 +202,7 @@ export async function buildDimensionIndex(
* @param projectPath - Project root directory
*/
export async function buildAllIndices(projectPath: string): Promise<void> {
const indexDir = join(projectPath, SPEC_INDEX_DIR);
const indexDir = join(projectPath, WORKFLOW_DIR, SPEC_INDEX_DIR);
// Ensure .spec-index directory exists
if (!existsSync(indexDir)) {
@@ -269,7 +283,7 @@ export async function getDimensionIndex(
// Build fresh and cache
const index = await buildDimensionIndex(projectPath, dimension);
const indexDir = join(projectPath, SPEC_INDEX_DIR);
const indexDir = join(projectPath, WORKFLOW_DIR, SPEC_INDEX_DIR);
if (!existsSync(indexDir)) {
mkdirSync(indexDir, { recursive: true });
}

View File

@@ -22,6 +22,7 @@ import {
SpecIndexEntry,
DimensionIndex,
SPEC_DIMENSIONS,
SPEC_CATEGORIES,
type SpecDimension,
} from './spec-index-builder.js';