feat: Add --deps flag to bd create for one-command issue creation
Implements GH-18: Allow creating issues with dependencies in a single command. Changes: - Add --deps flag to bd create command - Support format: 'type:id' or just 'id' (defaults to 'blocks') - Multiple dependencies supported via comma-separated values - Example: bd create "Fix bug" --deps discovered-from:bd-20,blocks:bd-15 - Updated README.md and CLAUDE.md with examples This improves the UX for AI agents by reducing two commands (create + dep add) to a single command, making discovered-from workflows much smoother. Fixes #18 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -23,9 +23,12 @@ bd create "Issue title" --id worker1-100 -p 1 --json
|
|||||||
# Update issue status
|
# Update issue status
|
||||||
bd update <id> --status in_progress --json
|
bd update <id> --status in_progress --json
|
||||||
|
|
||||||
# Link discovered work
|
# Link discovered work (old way)
|
||||||
bd dep add <discovered-id> <parent-id> --type discovered-from
|
bd dep add <discovered-id> <parent-id> --type discovered-from
|
||||||
|
|
||||||
|
# Create and link in one command (new way)
|
||||||
|
bd create "Issue title" -t bug -p 1 --deps discovered-from:<parent-id> --json
|
||||||
|
|
||||||
# Complete work
|
# Complete work
|
||||||
bd close <id> --reason "Done" --json
|
bd close <id> --reason "Done" --json
|
||||||
|
|
||||||
@@ -46,8 +49,8 @@ bd import -i .beads/issues.jsonl --resolve-collisions # Auto-resolve
|
|||||||
2. **Claim your task**: `bd update <id> --status in_progress`
|
2. **Claim your task**: `bd update <id> --status in_progress`
|
||||||
3. **Work on it**: Implement, test, document
|
3. **Work on it**: Implement, test, document
|
||||||
4. **Discover new work**: If you find bugs or TODOs, create issues:
|
4. **Discover new work**: If you find bugs or TODOs, create issues:
|
||||||
- `bd create "Found bug in auth" -t bug -p 1 --json`
|
- Old way (two commands): `bd create "Found bug in auth" -t bug -p 1 --json` then `bd dep add <new-id> <current-id> --type discovered-from`
|
||||||
- Link it: `bd dep add <new-id> <current-id> --type discovered-from`
|
- New way (one command): `bd create "Found bug in auth" -t bug -p 1 --deps discovered-from:<current-id> --json`
|
||||||
5. **Complete**: `bd close <id> --reason "Implemented"`
|
5. **Complete**: `bd close <id> --reason "Implemented"`
|
||||||
6. **Export**: Changes auto-sync to `.beads/issues.jsonl` (5-second debounce)
|
6. **Export**: Changes auto-sync to `.beads/issues.jsonl` (5-second debounce)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
- **discovered-from**: Use when you discover new work while working on an issue
|
||||||
```bash
|
```bash
|
||||||
# While working on bd-20, you discover a bug
|
# While working on bd-20, you discover a bug
|
||||||
|
# Old way (two commands):
|
||||||
bd create "Fix edge case bug" -t bug -p 1
|
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
|
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.
|
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.
|
||||||
|
|||||||
@@ -538,6 +538,7 @@ var createCmd = &cobra.Command{
|
|||||||
labels, _ := cmd.Flags().GetStringSlice("labels")
|
labels, _ := cmd.Flags().GetStringSlice("labels")
|
||||||
explicitID, _ := cmd.Flags().GetString("id")
|
explicitID, _ := cmd.Flags().GetString("id")
|
||||||
externalRef, _ := cmd.Flags().GetString("external-ref")
|
externalRef, _ := cmd.Flags().GetString("external-ref")
|
||||||
|
deps, _ := cmd.Flags().GetStringSlice("deps")
|
||||||
|
|
||||||
// Validate explicit ID format if provided (prefix-number)
|
// Validate explicit ID format if provided (prefix-number)
|
||||||
if explicitID != "" {
|
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
|
// Schedule auto-flush
|
||||||
markDirtyAndScheduleFlush()
|
markDirtyAndScheduleFlush()
|
||||||
|
|
||||||
@@ -610,6 +648,7 @@ func init() {
|
|||||||
createCmd.Flags().StringSliceP("labels", "l", []string{}, "Labels (comma-separated)")
|
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("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().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)
|
rootCmd.AddCommand(createCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user