diff --git a/CLAUDE.md b/CLAUDE.md index bcc27f2f..8fcc8e5a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,9 +23,12 @@ bd create "Issue title" --id worker1-100 -p 1 --json # Update issue status bd update --status in_progress --json -# Link discovered work +# Link discovered work (old way) bd dep add --type discovered-from +# Create and link in one command (new way) +bd create "Issue title" -t bug -p 1 --deps discovered-from: --json + # Complete work bd close --reason "Done" --json @@ -46,8 +49,8 @@ bd import -i .beads/issues.jsonl --resolve-collisions # Auto-resolve 2. **Claim your task**: `bd update --status in_progress` 3. **Work on it**: Implement, test, document 4. **Discover new work**: If you find bugs or TODOs, create issues: - - `bd create "Found bug in auth" -t bug -p 1 --json` - - Link it: `bd dep add --type discovered-from` + - Old way (two commands): `bd create "Found bug in auth" -t bug -p 1 --json` then `bd dep add --type discovered-from` + - New way (one command): `bd create "Found bug in auth" -t bug -p 1 --deps discovered-from: --json` 5. **Complete**: `bd close --reason "Implemented"` 6. **Export**: Changes auto-sync to `.beads/issues.jsonl` (5-second debounce) diff --git a/README.md b/README.md index 473ed911..592b0b64 100644 --- a/README.md +++ b/README.md @@ -313,8 +313,12 @@ Only `blocks` dependencies affect the ready work queue. - **discovered-from**: Use when you discover new work while working on an issue ```bash # While working on bd-20, you discover a bug + # Old way (two commands): bd create "Fix edge case bug" -t bug -p 1 bd dep add bd-21 bd-20 --type discovered-from # bd-21 discovered from bd-20 + + # New way (single command with --deps): + bd create "Fix edge case bug" -t bug -p 1 --deps discovered-from:bd-20 ``` The `discovered-from` type is particularly useful for AI-supervised workflows, where the AI can automatically create issues for discovered work and link them back to the parent task. diff --git a/cmd/bd/main.go b/cmd/bd/main.go index 7ccc7152..984d26c4 100644 --- a/cmd/bd/main.go +++ b/cmd/bd/main.go @@ -538,6 +538,7 @@ var createCmd = &cobra.Command{ labels, _ := cmd.Flags().GetStringSlice("labels") explicitID, _ := cmd.Flags().GetString("id") externalRef, _ := cmd.Flags().GetString("external-ref") + deps, _ := cmd.Flags().GetStringSlice("deps") // Validate explicit ID format if provided (prefix-number) if explicitID != "" { @@ -585,6 +586,43 @@ var createCmd = &cobra.Command{ } } + // Add dependencies if specified (format: type:id or just id for default "blocks" type) + for _, depSpec := range deps { + var depType types.DependencyType + var dependsOnID string + + // Parse format: "type:id" or just "id" (defaults to "blocks") + if strings.Contains(depSpec, ":") { + parts := strings.SplitN(depSpec, ":", 2) + if len(parts) != 2 { + fmt.Fprintf(os.Stderr, "Warning: invalid dependency format '%s', expected 'type:id' or 'id'\n", depSpec) + continue + } + depType = types.DependencyType(parts[0]) + dependsOnID = parts[1] + } else { + // Default to "blocks" if no type specified + depType = types.DepBlocks + dependsOnID = depSpec + } + + // Validate dependency type + if !depType.IsValid() { + fmt.Fprintf(os.Stderr, "Warning: invalid dependency type '%s' (valid: blocks, related, parent-child, discovered-from)\n", depType) + continue + } + + // Add the dependency + dep := &types.Dependency{ + IssueID: issue.ID, + DependsOnID: dependsOnID, + Type: depType, + } + if err := store.AddDependency(ctx, dep, actor); err != nil { + fmt.Fprintf(os.Stderr, "Warning: failed to add dependency %s -> %s: %v\n", issue.ID, dependsOnID, err) + } + } + // Schedule auto-flush markDirtyAndScheduleFlush() @@ -610,6 +648,7 @@ func init() { createCmd.Flags().StringSliceP("labels", "l", []string{}, "Labels (comma-separated)") createCmd.Flags().String("id", "", "Explicit issue ID (e.g., 'bd-42' for partitioning)") createCmd.Flags().String("external-ref", "", "External reference (e.g., 'gh-9', 'jira-ABC')") + createCmd.Flags().StringSlice("deps", []string{}, "Dependencies in format 'type:id' or 'id' (e.g., 'discovered-from:bd-20,blocks:bd-15' or 'bd-20')") rootCmd.AddCommand(createCmd) }