specify

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

CANARY: REQ=CBIN-134; FEATURE="SpecModification"; ASPECT=CLI; STATUS=IMPL; DOC=user:docs/user/spec-modification-guide.md; DOC_HASH=676eb2a18c9d002a; UPDATED=2025-10-17

Index

Constants

This section is empty.

Variables

View Source
var SpecifyCmd = &cobra.Command{
	Use:   "specify <feature-description>",
	Short: "Create a new requirement specification",
	Long: `Create a new CANARY requirement specification from a feature description.

Generates a new requirement ID with aspect-based format (CBIN-SECURITY_REVIEW-XXX),
creates a spec directory, and populates it with a specification template.`,
	Args: cobra.MinimumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		prompt, _ := cmd.Flags().GetString("prompt")
		if prompt != "" {
			if _, err := utils.LoadPrompt(prompt); err != nil {
				return err
			}
		}
		featureDesc := strings.Join(args, " ")
		aspect, _ := cmd.Flags().GetString("aspect")

		if err := reqid.ValidateAspect(aspect); err != nil {
			return fmt.Errorf("invalid aspect: %w", err)
		}

		aspect = reqid.NormalizeAspect(aspect)

		generatedID, err := reqid.GenerateNextID("CBIN", aspect)
		if err != nil {
			return fmt.Errorf("generate requirement ID: %w", err)
		}

		featureName := strings.Map(func(r rune) rune {
			if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') {
				return r
			}
			return '-'
		}, featureDesc)
		if len(featureName) > 50 {
			featureName = featureName[:50]
		}
		featureName = strings.Trim(featureName, "-")

		specsDir := ".canary/specs"
		specDir := filepath.Join(specsDir, fmt.Sprintf("%s-%s", generatedID, featureName))
		specFile := filepath.Join(specDir, "spec.md")

		if err := os.MkdirAll(specDir, 0750); err != nil {
			return fmt.Errorf("create spec directory: %w", err)
		}

		templateContent, err := utils.ReadEmbeddedFile("base/templates/spec-template.md")
		if err != nil {
			return fmt.Errorf("read spec template: %w", err)
		}

		content := string(templateContent)
		content = strings.ReplaceAll(content, "CBIN-XXX", generatedID)
		content = strings.ReplaceAll(content, "[FEATURE NAME]", featureDesc)
		content = strings.ReplaceAll(content, "YYYY-MM-DD", time.Now().UTC().Format("2006-01-02"))
		content = strings.ReplaceAll(content, "SECURITY_REVIEW", aspect)

		if err := os.WriteFile(specFile, []byte(content), 0640); err != nil {
			return fmt.Errorf("write spec file: %w", err)
		}

		fmt.Printf("✅ Created specification: %s\n", specFile)
		fmt.Printf("\nRequirement ID: %s\n", generatedID)
		fmt.Printf("Aspect: %s\n", aspect)
		fmt.Printf("Feature: %s\n", featureDesc)
		fmt.Println("\nNext steps:")
		fmt.Printf("  1. Edit %s to complete the specification\n", specFile)
		fmt.Printf("  2. Run: canary plan %s\n", generatedID)

		return nil
	},
}

CANARY: REQ=CBIN-120; FEATURE="SpecifyCmd"; ASPECT=CLI; STATUS=IMPL; OWNER=canary; UPDATED=2025-10-16

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL