diff --git a/.gitignore b/.gitignore index 8e7452683..eae60b8f5 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,17 @@ cmd/cue/cue # Note that CI requires a clean git repo when it finishes, # so we don't want it to think the credentials file is untracked. gha-creds-*.json + +# OpenSpec Tooling (Local only) +openspec/ + +# Cursor IDE +.cursor/ + +# AI Agent Skills/Commands (generated by OpenSpec) +.claude/skills/openspec-*/ +.claude/commands/opsx/ +.codex/ +.gemini/ +.github/prompts/opsx-*.prompt.md +.github/skills/openspec-*/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 66e8d5170..a3a5332a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -595,6 +595,42 @@ free to write a comment in GerritHub or GitHub requesting submission. This section collects a number of other comments that are outside the issue/edit/code review/submit process itself. +### AI-assisted development with OpenSpec + +Contributors can optionally use [OpenSpec](https://github.com/Fission-AI/OpenSpec/) +for AI-assisted development. OpenSpec provides a structured workflow for creating +proposals, designs, specs, and implementation tasks with AI coding assistants like +Claude Code, GitHub Copilot, Gemini, and others. + +**Setup:** + +1. Install OpenSpec CLI (requires Node.js 20.19.0+): + ```console + $ npm install -g @fission-ai/openspec@latest + ``` + +2. Run the setup script from the repository root: + ```console + $ ./_scripts/setup-openspec.sh + ``` + +This creates local-only tooling files (gitignored) while specs and context are +tracked in `doc/`: + +- `doc/specs/` - Main specs (source of truth, tracked) +- `doc/context/` - Shared context like language change checklists (tracked) +- `openspec/` - Workflow state and config (local only, gitignored) + +**Quick start commands** (in your AI assistant): +- `/opsx:new` - Start a new change with proposal → design → specs → tasks workflow +- `/opsx:continue` - Continue working on an existing change +- `/opsx:apply` - Implement tasks from a change + +**Updating after OpenSpec upgrades:** +```console +$ ./_scripts/setup-openspec.sh update +``` + ### Copyright headers Files in the CUE repository don't list author names, both to avoid clutter and diff --git a/_scripts/setup-openspec.sh b/_scripts/setup-openspec.sh new file mode 100755 index 000000000..1404d5772 --- /dev/null +++ b/_scripts/setup-openspec.sh @@ -0,0 +1,111 @@ +#!/bin/bash +# Setup OpenSpec tooling for local development +# +# This script initializes the OpenSpec workflow with configurations +# pointing to the tracked doc/ directory for specs and context. +# +# PREREQUISITES +# ============= +# Node.js 20.19.0 or higher is required. +# +# INSTALLATION +# ============ +# Install OpenSpec CLI via npm: +# +# npm install -g @fission-ai/openspec@latest +# +# For more info: https://github.com/Fission-AI/OpenSpec/ +# +# USAGE +# ===== +# ./_scripts/setup-openspec.sh # First-time setup +# ./_scripts/setup-openspec.sh update # Regenerate skills after OpenSpec upgrade +# +# WHAT IT CREATES (all gitignored) +# ================================ +# - openspec/config.yaml - OpenSpec configuration +# - .claude/commands/opsx/* - Claude Code commands +# - .claude/skills/openspec-*/* - Claude Code skills +# - Similar for .codex/, .gemini/, .github/ integrations + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +cd "$REPO_ROOT" + +MODE="$1" + +echo "Setting up OpenSpec tooling..." + +# Create openspec directory structure +mkdir -p openspec + +# Create or update config.yaml pointing to doc/ +if [[ ! -f openspec/config.yaml ]] || [[ $MODE != "update" ]]; then + cat > openspec/config.yaml <<-'EOF' + schema: spec-driven + + # Path to main specs (the source of truth) + specsPath: doc/specs + + # Project context (optional) + # This is shown to AI when creating artifacts. + # Add your tech stack, conventions, style guides, domain knowledge, etc. + context: | + Please refer to doc/context/language-features.md for language rules and the + comprehensive checklist for implementing language changes. + + # Per-artifact rules (optional) + # Add custom rules for specific artifacts. + # Example: + # rules: + # proposal: + # - Keep proposals under 500 words + # - Always include a "Non-goals" section + # tasks: + # - Break tasks into chunks of max 2 hours + EOF + echo "Created openspec/config.yaml" +else + echo "Keeping existing openspec/config.yaml" +fi + +# Check if openspec CLI is available +if command -v openspec &> /dev/null; then + if [[ $MODE == "update" ]]; then + echo "Running 'openspec update' to regenerate AI agent skills..." + openspec update + else + echo "Running 'openspec init' to generate AI agent skills..." + # Use --tools to run non-interactively; config.yaml already exists + openspec init --tools claude,codex,gemini,github-copilot + fi +else + echo "" + echo "ERROR: 'openspec' CLI not found." + echo "" + echo "Install OpenSpec first (requires Node.js 20.19.0+):" + echo " npm install -g @fission-ai/openspec@latest" + echo "" + echo "For more info: https://github.com/Fission-AI/OpenSpec/" + echo "" + echo "Then re-run this script." + exit 1 +fi + +echo "" +echo "Setup complete!" +echo "" +echo "Directory structure:" +echo " doc/specs/ - Main specs (tracked, source of truth)" +echo " doc/context/ - Shared context files (tracked)" +echo " openspec/ - Workflow state and config (local only, gitignored)" +echo "" +echo "Quick start:" +echo " /opsx:new - Start a new change" +echo " /opsx:continue - Continue working on a change" +echo " /opsx:apply - Implement tasks from a change" +echo "" +echo "Run './_scripts/setup-openspec.sh update' after upgrading OpenSpec." diff --git a/doc/context/language-features.md b/doc/context/language-features.md new file mode 100644 index 000000000..5331bacd9 --- /dev/null +++ b/doc/context/language-features.md @@ -0,0 +1,103 @@ +# Language Features Context + +This is the CUE language repository. + +## Language Version Gating + +- New language features MUST be gated on a minimum language version +- Features should specify the minimum version (e.g., v0.16.0) in the design +- Implementation should check c.experiments.LanguageVersion() and use semver.Compare +- Error message format: "feature X requires language version vX.Y.Z or later; current version is vA.B.C" +- The version check should be in internal/core/compile/compile.go +- See verifyVersion() for the pattern used for builtins + +## Experiments + +- New language features are often introduced as experiments before becoming stable +- Experiments are defined in internal/cueexperiment/file.go as fields on the File struct +- Each experiment has a tag: `experiment:"preview:vX.Y.Z"` (when introduced) and optionally `stable:vX.Y.Z` (when graduated) +- Users enable experiments via @experiment(name) attribute in CUE files +- Check experiments via c.experiments.FieldName in the compiler +- Consider using experiments for features that may need refinement based on user feedback + +## Language Change Checklist + +When adding new syntax or AST nodes to the CUE language, the following +packages and files typically need updates. Use this as a comprehensive +checklist when planning tasks: + +### 1. Lexer & Token (cue/token/) +- [ ] token.go: Add new token constants +- [ ] token.go: Add keywords to keyword map if applicable + +### 2. AST (cue/ast/) +- [ ] ast.go: Add new AST node struct(s) +- [ ] ast.go: Implement marker methods (e.g., clauseNode(), exprNode()) +- [ ] ast.go: Add fields to existing structs if extending them +- [ ] walk.go: Add case for new node type in Walk function + +### 3. Parser (cue/parser/) +- [ ] parser.go: Add parsing logic for new syntax +- [ ] parser_test.go: Add parser tests + +### 4. AST Utilities (cue/ast/astutil/) +- [ ] apply.go: Add case for new node type in Apply function +- [ ] resolve.go: Handle new node in scope resolution if it affects scoping + +### 5. AST Debug (internal/astinternal/) +- [ ] debug.go: Add case in DebugStr for new node type + +### 6. Compiler - ADT Structures (internal/core/adt/) +- [ ] expr.go: Add ADT struct for new construct +- [ ] expr.go: Add fields to existing ADT structs if extending them + +### 7. Compiler - Compilation (internal/core/compile/) +- [ ] compile.go: Add compilation logic for AST to ADT conversion +- [ ] compile.go: Add language version check if feature-gated + +### 8. Evaluator (internal/core/adt/) +- [ ] Add evaluation logic in appropriate files (e.g., comprehension.go) + +### 9. Debug Output (internal/core/debug/) +- [ ] debug.go: Add case for new ADT node type +- [ ] compact.go: Add case for new ADT node type + +### 10. Walker (internal/core/walk/) +- [ ] walk.go: Add case for new ADT node type + +### 11. Exporter (internal/core/export/) +- [ ] adt.go: Add export logic for new ADT node to AST conversion + +### 12. Dependency Analysis (internal/core/dep/) +- [ ] dep.go: Handle new construct in dependency marking +- [ ] mixed.go: Handle new construct if applicable + +### 13. Formatter (cue/format/) +- [ ] node.go: Add formatting logic for new AST node + +### 14. Subsumer (internal/core/subsume/) +- [ ] structural.go: Handle new construct if it affects subsumption + +### 15. Tests +- [ ] cue/testdata/: Add evaluation tests (.txtar files) +- [ ] cue/parser/parser_test.go: Add parser tests +- [ ] internal/core/dep/testdata/: Add dependency tracking tests +- [ ] internal/core/export/testdata/main/: Add export tests + +### 16. Documentation +- [ ] doc/ref/spec.md: Update grammar +- [ ] doc/ref/spec.md: Add examples +- [ ] doc/ref/spec.md: Document semantics and scoping rules + +### 17. Experiments (if feature is experimental) +- [ ] internal/cueexperiment/file.go: Add experiment field with tags +- [ ] internal/core/compile/compile.go: Check experiment flag before enabling +- [ ] doc/: Document experiment and how to enable it +- [ ] Consider preview/stable version tags for gradual rollout + +### 18. Other Potential Updates +- [ ] cue/load/tags.go: If feature interacts with build tags +- [ ] internal/encoding/: If feature affects encoding/decoding +- [ ] internal/lsp/: If feature needs LSP support +- [ ] tools/fix/fix.go: If feature needs migration tooling +- [ ] tools/trim/: If feature affects trimming