Add template support for issue creation (bd-164b)
- Built-in templates: epic, bug, feature (embedded in binary) - Custom templates in .beads/templates/ (override built-ins) - Commands: bd template list/show/create - Flag: bd create --from-template <name> "Title" - Template fields: description, type, priority, labels, design, acceptance - Security: sanitize template names to prevent path traversal - Flag precedence: explicit flags override template defaults - Tests: template loading, security, flag precedence - Docs: commands/template.md and README.md updated Closes bd-164b Amp-Thread-ID: https://ampcode.com/threads/T-118fe54f-b112-4f99-a3d9-b7df53fb7284 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -113,10 +113,12 @@ type ResolveIDArgs struct {
|
||||
|
||||
// ReadyArgs represents arguments for the ready operation
|
||||
type ReadyArgs struct {
|
||||
Assignee string `json:"assignee,omitempty"`
|
||||
Priority *int `json:"priority,omitempty"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
SortPolicy string `json:"sort_policy,omitempty"`
|
||||
Assignee string `json:"assignee,omitempty"`
|
||||
Priority *int `json:"priority,omitempty"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
SortPolicy string `json:"sort_policy,omitempty"`
|
||||
Labels []string `json:"labels,omitempty"`
|
||||
LabelsAny []string `json:"labels_any,omitempty"`
|
||||
}
|
||||
|
||||
// StaleArgs represents arguments for the stale command
|
||||
|
||||
@@ -458,6 +458,8 @@ func (s *Server) handleReady(req *Request) Response {
|
||||
Priority: readyArgs.Priority,
|
||||
Limit: readyArgs.Limit,
|
||||
SortPolicy: types.SortPolicy(readyArgs.SortPolicy),
|
||||
Labels: normalizeLabels(readyArgs.Labels),
|
||||
LabelsAny: normalizeLabels(readyArgs.LabelsAny),
|
||||
}
|
||||
if readyArgs.Assignee != "" {
|
||||
wf.Assignee = &readyArgs.Assignee
|
||||
|
||||
@@ -34,6 +34,36 @@ func (s *SQLiteStorage) GetReadyWork(ctx context.Context, filter types.WorkFilte
|
||||
args = append(args, *filter.Assignee)
|
||||
}
|
||||
|
||||
// Label filtering (AND semantics)
|
||||
if len(filter.Labels) > 0 {
|
||||
for _, label := range filter.Labels {
|
||||
whereClauses = append(whereClauses, `
|
||||
EXISTS (
|
||||
SELECT 1 FROM labels
|
||||
WHERE issue_id = i.id AND label = ?
|
||||
)
|
||||
`)
|
||||
args = append(args, label)
|
||||
}
|
||||
}
|
||||
|
||||
// Label filtering (OR semantics)
|
||||
if len(filter.LabelsAny) > 0 {
|
||||
placeholders := make([]string, len(filter.LabelsAny))
|
||||
for i := range filter.LabelsAny {
|
||||
placeholders[i] = "?"
|
||||
}
|
||||
whereClauses = append(whereClauses, fmt.Sprintf(`
|
||||
EXISTS (
|
||||
SELECT 1 FROM labels
|
||||
WHERE issue_id = i.id AND label IN (%s)
|
||||
)
|
||||
`, strings.Join(placeholders, ",")))
|
||||
for _, label := range filter.LabelsAny {
|
||||
args = append(args, label)
|
||||
}
|
||||
}
|
||||
|
||||
// Build WHERE clause properly
|
||||
whereSQL := strings.Join(whereClauses, " AND ")
|
||||
|
||||
|
||||
@@ -305,6 +305,8 @@ type WorkFilter struct {
|
||||
Status Status
|
||||
Priority *int
|
||||
Assignee *string
|
||||
Labels []string // AND semantics: issue must have ALL these labels
|
||||
LabelsAny []string // OR semantics: issue must have AT LEAST ONE of these labels
|
||||
Limit int
|
||||
SortPolicy SortPolicy
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user