feat: enhance spec loading capabilities and add new categories

- Added support for loading specs from new categories: debug, test, review, and validation.
- Updated various agents and skills to include instructions for loading project context from the new spec categories.
- Introduced new spec documents for test conventions, review standards, and validation rules to improve project guidelines.
- Enhanced the frontend to support new watcher settings and display auto-watch status.
- Improved the spec index builder to accommodate new categories and ensure proper loading of specifications.
This commit is contained in:
catlog22
2026-03-20 15:06:57 +08:00
parent 2b43b6be7b
commit d843112094
39 changed files with 356 additions and 29 deletions

View File

@@ -66,11 +66,19 @@ const ENV_GROUPS: EnvGroup[] = [
{ key: 'CODEXLENS_DB_PATH', label: 'DB Path' },
{ key: 'CODEXLENS_INDEX_WORKERS', label: 'Index Workers' },
{ key: 'CODEXLENS_CODE_AWARE_CHUNKING', label: 'Code Aware Chunking' },
{ key: 'CODEXLENS_AST_CHUNKING', label: 'AST Chunking' },
{ key: 'CODEXLENS_MAX_FILE_SIZE', label: 'Max File Size' },
{ key: 'CODEXLENS_HNSW_EF', label: 'HNSW EF' },
{ key: 'CODEXLENS_HNSW_M', label: 'HNSW M' },
],
},
{
title: 'watcher',
fields: [
{ key: 'CODEXLENS_AUTO_WATCH', label: 'Auto Watch' },
{ key: 'CODEXLENS_WATCHER_DEBOUNCE_MS', label: 'Watch Debounce (ms)' },
],
},
];
// Fields that are only relevant in API mode
@@ -95,6 +103,9 @@ const FIELD_DEFAULTS: Record<string, string> = {
CODEXLENS_RERANKER_BATCH_SIZE: '32',
CODEXLENS_INDEX_WORKERS: '2',
CODEXLENS_CODE_AWARE_CHUNKING: 'true',
CODEXLENS_AST_CHUNKING: 'true',
CODEXLENS_AUTO_WATCH: 'false',
CODEXLENS_WATCHER_DEBOUNCE_MS: '1000',
CODEXLENS_MAX_FILE_SIZE: '1000000',
CODEXLENS_HNSW_EF: '150',
CODEXLENS_HNSW_M: '32',

View File

@@ -10,7 +10,7 @@ import { useQueryClient } from '@tanstack/react-query';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { useIndexStatus, useSyncIndex, useRebuildIndex, codexLensKeys, type IndexStatusData } from '@/hooks/useCodexLens';
import { useIndexStatus, useSyncIndex, useRebuildIndex, useWatcherStatus, codexLensKeys, type IndexStatusData } from '@/hooks/useCodexLens';
import { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';
interface ProjectStatusCardProps {
@@ -131,8 +131,17 @@ export function IndexManagerTab() {
}
};
const { autoWatch } = useWatcherStatus();
return (
<div className="space-y-4">
{/* Global watcher status */}
<div className="flex items-center gap-2">
<span className={`text-xs px-2 py-0.5 rounded-full ${autoWatch ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'}`}>
{autoWatch ? 'Auto-watch ON' : 'Auto-watch OFF'}
</span>
</div>
{/* Add project path */}
<div className="flex gap-2">
<Input

View File

@@ -204,3 +204,18 @@ export function useCodexLensMcpConfig() {
staleTime: 30_000,
});
}
// ========================================
// Watcher Status Hook
// ========================================
export function useWatcherStatus() {
const { data: envData } = useCodexLensEnv();
const autoWatch = envData?.values?.CODEXLENS_AUTO_WATCH === 'true';
const debounceMs = envData?.values?.CODEXLENS_WATCHER_DEBOUNCE_MS || '1000';
return {
autoWatch,
debounceMs,
};
}

View File

@@ -97,7 +97,7 @@ async function loadAction(options: SpecOptions): Promise<void> {
const result = await loadSpecs({
projectPath,
dimension: dimension as 'specs' | 'personal' | undefined,
category: category as 'general' | 'exploration' | 'planning' | 'execution' | undefined,
category: category as 'general' | 'exploration' | 'planning' | 'execution' | 'debug' | 'test' | 'review' | 'validation' | undefined,
keywords,
outputFormat: stdin ? 'hook' : 'cli',
stdinData,
@@ -367,11 +367,16 @@ ${chalk.bold('OPTIONS')}
--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.bold('CATEGORIES')}
Use --category to load specs for specific workflow stages:
${chalk.cyan('general')} - Applies to all stages (always included)
${chalk.cyan('exploration')} - Code exploration, analysis, codebase understanding
${chalk.cyan('planning')} - Task planning, requirements context
${chalk.cyan('execution')} - Implementation, testing, deployment context
${chalk.cyan('execution')} - Implementation, coding, deployment context
${chalk.cyan('debug')} - Debugging, known issues, workarounds
${chalk.cyan('test')} - Test conventions, frameworks, coverage
${chalk.cyan('review')} - Code review standards, checklists, gates
${chalk.cyan('validation')} - Verification rules, acceptance criteria
${chalk.bold('EXAMPLES')}
${chalk.gray('# Initialize spec system:')}

View File

@@ -101,6 +101,8 @@ const CODEXLENS_ENV_DEFAULTS: Record<string, string> = {
CODEXLENS_CODE_AWARE_CHUNKING: 'true',
CODEXLENS_AST_CHUNKING: 'true',
CODEXLENS_MAX_FILE_SIZE: '1000000',
CODEXLENS_AUTO_WATCH: 'false',
CODEXLENS_WATCHER_DEBOUNCE_MS: '1000',
CODEXLENS_HNSW_EF: '150',
CODEXLENS_HNSW_M: '32',
};
@@ -147,7 +149,7 @@ function buildMcpServerConfig(savedEnv: Record<string, string>): Record<string,
return {
command: 'uvx',
args: ['--from', 'codexlens-search[mcp,ast]', 'codexlens-mcp'],
args: ['--from', 'codexlens-search[mcp,ast,watcher]', 'codexlens-mcp'],
...(Object.keys(filteredEnv).length > 0 ? { env: filteredEnv } : {}),
};
}

View File

@@ -28,17 +28,21 @@ import { homedir } from 'os';
/**
* Spec categories for workflow stage-based loading.
* - general: Applies to all stages (e.g. coding conventions)
* - exploration: Code exploration, analysis, debugging context
* - general: Applies to all stages (e.g. coding conventions) — always included
* - exploration: Code exploration, analysis, codebase understanding
* - planning: Task planning, roadmap, requirements context
* - execution: Implementation, testing, deployment context
* - execution: Implementation, coding, deployment context
* - debug: Debugging, known issues, workarounds, root-cause notes
* - test: Test conventions, frameworks, coverage, fixtures
* - review: Code review standards, checklists, approval gates
* - validation: Verification rules, acceptance criteria, quality checks
*
* Usage: Set category field in spec frontmatter:
* category: exploration
*
* System-level loading by stage: ccw spec load --category exploration
*/
export const SPEC_CATEGORIES = ['general', 'exploration', 'planning', 'execution'] as const;
export const SPEC_CATEGORIES = ['general', 'exploration', 'planning', 'execution', 'debug', 'test', 'review', 'validation'] as const;
export type SpecCategory = typeof SPEC_CATEGORIES[number];

View File

@@ -18,7 +18,7 @@ import { join } from 'path';
export interface SpecFrontmatter {
title: string;
dimension: string;
category?: 'general' | 'exploration' | 'planning' | 'execution';
category?: 'general' | 'exploration' | 'planning' | 'execution' | 'debug' | 'test' | 'review' | 'validation';
keywords: string[];
readMode: 'required' | 'optional';
priority: 'high' | 'medium' | 'low';
@@ -117,6 +117,133 @@ export const SEED_DOCS: Map<string, SeedDoc[]> = new Map([
- External dependencies require justification
- Prefer standard library when available
- Pin dependency versions for reproducibility
`,
},
{
filename: 'debug-notes.md',
frontmatter: {
title: 'Debug Notes',
dimension: 'specs',
category: 'debug',
keywords: ['debug', 'issue', 'workaround', 'root-cause', 'gotcha'],
readMode: 'optional',
priority: 'medium',
},
body: `# Debug Notes
## Known Issues
- Document known bugs and their workarounds here
- Include root-cause analysis for resolved issues
## Common Gotchas
- List environment-specific pitfalls
- Note platform differences that cause unexpected behavior
## Debugging Tips
- Preferred debugging workflows for this project
- Key log locations and diagnostic commands
`,
},
{
filename: 'test-conventions.md',
frontmatter: {
title: 'Test Conventions',
dimension: 'specs',
category: 'test',
keywords: ['test', 'coverage', 'mock', 'fixture', 'assertion', 'framework'],
readMode: 'required',
priority: 'high',
},
body: `# Test Conventions
## Framework
- Test runner and assertion library used in this project
- Configuration file locations
## Structure
- Test file naming conventions (e.g., *.test.ts, *.spec.ts)
- Test directory organization
- Fixture and mock patterns
## Coverage
- Minimum coverage thresholds
- Coverage report configuration
- Files excluded from coverage
## Best Practices
- Prefer unit tests for business logic
- Use integration tests for API boundaries
- Mock external dependencies, not internal modules
`,
},
{
filename: 'review-standards.md',
frontmatter: {
title: 'Review Standards',
dimension: 'specs',
category: 'review',
keywords: ['review', 'checklist', 'gate', 'approval', 'standard'],
readMode: 'required',
priority: 'medium',
},
body: `# Review Standards
## Code Review Checklist
- Correctness: Does it do what it claims?
- Clarity: Is the intent obvious without comments?
- Tests: Are changes covered by tests?
- Security: No new vulnerabilities introduced?
- Performance: No unnecessary allocations or O(n²) loops?
## Approval Gates
- All CI checks must pass
- At least one approving review required
- No unresolved conversations
## Style
- Follow existing project conventions
- Keep PRs focused and reviewable (< 400 lines preferred)
`,
},
{
filename: 'validation-rules.md',
frontmatter: {
title: 'Validation Rules',
dimension: 'specs',
category: 'validation',
keywords: ['validation', 'verification', 'acceptance', 'criteria', 'check'],
readMode: 'required',
priority: 'high',
},
body: `# Validation Rules
## Acceptance Criteria
- Define clear pass/fail conditions for each feature
- Include edge cases in acceptance criteria
- Specify performance thresholds where applicable
## Verification Steps
- Build must succeed without warnings
- All existing tests must continue to pass
- New features must include corresponding tests
## Quality Checks
- No TypeScript strict mode errors
- No linter warnings in changed files
- Bundle size regression checks (if applicable)
`,
},
],

View File

@@ -255,7 +255,8 @@ export function filterSpecs(
for (const entry of index.entries) {
// Category filter: skip if category specified and doesn't match
if (category && entry.category !== category) {
// 'general' category always passes through (applies to all stages)
if (category && entry.category !== category && entry.category !== 'general') {
continue;
}