mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-01 15:03:57 +08:00
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:
@@ -11,7 +11,7 @@ import chalk from 'chalk';
|
||||
|
||||
interface SpecOptions {
|
||||
dimension?: string;
|
||||
context?: string;
|
||||
keywords?: string;
|
||||
stdin?: boolean;
|
||||
json?: boolean;
|
||||
}
|
||||
@@ -60,11 +60,11 @@ function getProjectPath(hookCwd?: string): string {
|
||||
/**
|
||||
* Load action - load specs matching dimension/keywords.
|
||||
*
|
||||
* CLI mode: --dimension and --context options, outputs formatted markdown.
|
||||
* CLI mode: --dimension and --keywords options, outputs formatted markdown.
|
||||
* Hook mode: --stdin reads JSON {session_id, cwd, user_prompt}, outputs JSON {continue, systemMessage}.
|
||||
*/
|
||||
async function loadAction(options: SpecOptions): Promise<void> {
|
||||
const { stdin, dimension, context } = options;
|
||||
const { stdin, dimension, keywords: keywordsInput } = options;
|
||||
let projectPath: string;
|
||||
let stdinData: StdinData | undefined;
|
||||
|
||||
@@ -89,8 +89,8 @@ async function loadAction(options: SpecOptions): Promise<void> {
|
||||
try {
|
||||
const { loadSpecs } = await import('../tools/spec-loader.js');
|
||||
|
||||
const keywords = context
|
||||
? context.split(/[\s,]+/).filter(Boolean)
|
||||
const keywords = keywordsInput
|
||||
? keywordsInput.split(/[\s,]+/).filter(Boolean)
|
||||
: undefined;
|
||||
|
||||
const result = await loadSpecs({
|
||||
@@ -361,19 +361,31 @@ ${chalk.bold('SUBCOMMANDS')}
|
||||
|
||||
${chalk.bold('OPTIONS')}
|
||||
--dimension <dim> Target dimension: specs, roadmap, changelog, personal
|
||||
--context <text> Context text for keyword extraction (CLI mode)
|
||||
--keywords <text> Keywords for spec matching (space or comma separated)
|
||||
--stdin Read input from stdin (Hook mode)
|
||||
--json Output as JSON
|
||||
|
||||
${chalk.bold('KEYWORD CATEGORIES')}
|
||||
Use these predefined keywords to load specs for specific workflow stages:
|
||||
${chalk.cyan('exploration')} - Code exploration, analysis, debugging context
|
||||
${chalk.cyan('planning')} - Task planning, roadmap, requirements context
|
||||
${chalk.cyan('execution')} - Implementation, testing, deployment context
|
||||
|
||||
${chalk.bold('EXAMPLES')}
|
||||
${chalk.gray('# Initialize spec system:')}
|
||||
ccw spec init
|
||||
|
||||
${chalk.gray('# Load specs for a topic (CLI mode):')}
|
||||
ccw spec load --dimension specs --context "auth jwt security"
|
||||
${chalk.gray('# Load exploration-phase specs:')}
|
||||
ccw spec load --keywords exploration
|
||||
|
||||
${chalk.gray('# Load all matching specs:')}
|
||||
ccw spec load --context "implement user authentication"
|
||||
${chalk.gray('# Load planning-phase specs with auth topic:')}
|
||||
ccw spec load --keywords "planning auth"
|
||||
|
||||
${chalk.gray('# Load execution-phase specs:')}
|
||||
ccw spec load --keywords execution
|
||||
|
||||
${chalk.gray('# Load specs for a topic (CLI mode):')}
|
||||
ccw spec load --dimension specs --keywords "auth jwt security"
|
||||
|
||||
${chalk.gray('# Use as Claude Code hook (settings.json):')}
|
||||
ccw spec load --stdin
|
||||
@@ -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 });
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
SpecIndexEntry,
|
||||
DimensionIndex,
|
||||
SPEC_DIMENSIONS,
|
||||
SPEC_CATEGORIES,
|
||||
type SpecDimension,
|
||||
} from './spec-index-builder.js';
|
||||
|
||||
Reference in New Issue
Block a user