These instructions are for AI assistants working in this project.
Always open @/openspec/AGENTS.md when the request:
- Mentions planning or proposals (words like proposal, spec, change, plan)
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
- Sounds ambiguous and you need the authoritative spec before coding
Use @/openspec/AGENTS.md to learn:
- How to create and apply change proposals
- Spec format and conventions
- Project structure and guidelines
Keep this managed block so 'openspec update' can refresh the instructions.
All file-based data MUST use the reactive file system (@openspecui/core/reactive-fs).
- File reads: Use
reactiveReadFile,reactiveReadDir,reactiveExists,reactiveStat - Never use:
fs.existsSync,fs.readFileSync, or non-reactive async fs methods for data that needs real-time updates - Subscriptions: Every query that reads files should have a corresponding subscription using
createReactiveSubscription
// packages/server/src/router.ts
// Query (for initial load)
getData: publicProcedure.query(async ({ ctx }) => {
return someReactiveFunction(ctx.projectDir)
}),
// Subscription (for real-time updates)
subscribe: publicProcedure.subscription(({ ctx }) => {
return createReactiveSubscription(() => someReactiveFunction(ctx.projectDir))
}),// packages/web/src/lib/use-subscription.ts
// Use subscription hooks instead of useQuery for reactive data
const { data } = useConfiguredToolsSubscription() // Reactive
// NOT: useQuery(trpc.cli.getConfiguredTools.queryOptions()) // Non-reactivepackages/core- Reactive file system, adapters, schemaspackages/server- tRPC router with HTTP/WebSocketpackages/web- React frontendpackages/cli- CLI entry pointreferences/openspec- Official OpenSpec CLI reference
packages/core/src/reactive-fs/- Reactive file system implementationpackages/server/src/reactive-subscription.ts- tRPC subscription helperpackages/web/src/lib/use-subscription.ts- React subscription hooks
Always use yargs for CLI argument parsing. Never write custom parseArgs functions.
- Use
yargs+yargs/helpersfor consistent argument handling - Use
INIT_CWDenvironment variable to resolve paths relative to original working directory - Support both
--option valueand--option=valueformats (yargs handles this automatically) - Filter out
--separator when using with pnpm/tsx (they add--before script arguments)
import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'
import { resolve } from 'node:path'
const originalCwd = process.env.INIT_CWD || process.cwd()
// Filter out '--' separator that pnpm/tsx adds
const args = hideBin(process.argv).filter((arg) => arg !== '--')
const argv = await yargs(args)
.option('dir', {
alias: 'd',
type: 'string',
default: '.',
})
.parse()
const projectDir = resolve(originalCwd, argv.dir)OpenSpec UI is a visual interface for the OpenSpec CLI. Prefer using CLI commands over custom implementations.
- Use CLI when available: For operations like
init,archive,validate- call the OpenSpec CLI viaCliExecutor - Custom logic only when necessary: Only implement custom logic when CLI doesn't support the operation (e.g., file reading, task toggling)
- Reference implementation: Check
references/openspec/for the official CLI implementation when building custom logic - Streaming output: Use
executeStreamfor long-running CLI commands to show real-time terminal output
# Check available commands
openspec --help
# Init with tools
openspec init --tools=claude,cursor
# Archive a change
openspec archive -y <change-name> [--skip-specs] [--no-validate]
# Validate
openspec validate [spec|change] [id]// Use CLI for operations
const result = await ctx.cliExecutor.archive(changeId, { skipSpecs: true })
// Use streaming for real-time output
await ctx.cliExecutor.archiveStream(changeId, options, (event) => {
emit.next(event) // Send to frontend via WebSocket
})At the start of each session, read references/openspec-cognitive-report.md to understand the OpenSpec domain model and architecture.
This file contains:
- OpenSpec core concepts and terminology
- File structure and naming conventions
- Workflow patterns (proposal → implementation → archive)
- Relationship between specs, changes, and tasks