feat: Distinct prefixes for protos, molecules, wisps (bd-hobo)
Added type-specific ID prefixes for better visual recognition: - `bd pour` now generates IDs with "mol-" prefix - `bd wisp create` now generates IDs with "wisp-" prefix - Regular issues continue using the configured prefix Implementation: - Added IDPrefix field to types.Issue (internal, not exported to JSONL) - Added Prefix field to CloneOptions for spawning operations - Added IDPrefix to RPC CreateArgs for daemon communication - Updated storage layer to use issue.IDPrefix when generating IDs - Updated pour.go and wisp.go to pass appropriate prefixes This enables instant visual recognition of entity types and prevents accidental modification of templates. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,8 @@ type CreateArgs struct {
|
||||
Sender string `json:"sender,omitempty"` // Who sent this (for messages)
|
||||
Wisp bool `json:"wisp,omitempty"` // Wisp = ephemeral vapor from the Steam Engine; bulk-deleted when closed
|
||||
RepliesTo string `json:"replies_to,omitempty"` // Issue ID for conversation threading
|
||||
// ID generation (bd-hobo)
|
||||
IDPrefix string `json:"id_prefix,omitempty"` // Override prefix for ID generation (mol, wisp, etc.)
|
||||
}
|
||||
|
||||
// UpdateArgs represents arguments for the update operation
|
||||
|
||||
@@ -179,6 +179,8 @@ func (s *Server) handleCreate(req *Request) Response {
|
||||
Sender: createArgs.Sender,
|
||||
Wisp: createArgs.Wisp,
|
||||
// NOTE: RepliesTo now handled via replies-to dependency (Decision 004)
|
||||
// ID generation (bd-hobo)
|
||||
IDPrefix: createArgs.IDPrefix,
|
||||
}
|
||||
|
||||
// Check if any dependencies are discovered-from type
|
||||
|
||||
@@ -153,9 +153,9 @@ func (s *SQLiteStorage) CreateIssue(ctx context.Context, issue *types.Issue, act
|
||||
}()
|
||||
|
||||
// Get prefix from config (needed for both ID generation and validation)
|
||||
var prefix string
|
||||
err = conn.QueryRowContext(ctx, `SELECT value FROM config WHERE key = ?`, "issue_prefix").Scan(&prefix)
|
||||
if err == sql.ErrNoRows || prefix == "" {
|
||||
var configPrefix string
|
||||
err = conn.QueryRowContext(ctx, `SELECT value FROM config WHERE key = ?`, "issue_prefix").Scan(&configPrefix)
|
||||
if err == sql.ErrNoRows || configPrefix == "" {
|
||||
// CRITICAL: Reject operation if issue_prefix config is missing (bd-166)
|
||||
// This prevents duplicate issues with wrong prefix
|
||||
return fmt.Errorf("database not initialized: issue_prefix config is missing (run 'bd init --prefix <prefix>' first)")
|
||||
@@ -163,6 +163,12 @@ func (s *SQLiteStorage) CreateIssue(ctx context.Context, issue *types.Issue, act
|
||||
return fmt.Errorf("failed to get config: %w", err)
|
||||
}
|
||||
|
||||
// Use IDPrefix override if set, otherwise use config prefix (bd-hobo)
|
||||
prefix := configPrefix
|
||||
if issue.IDPrefix != "" {
|
||||
prefix = issue.IDPrefix
|
||||
}
|
||||
|
||||
// Generate or validate ID
|
||||
if issue.ID == "" {
|
||||
// Generate hash-based ID with adaptive length based on database size (bd-ea2a13)
|
||||
|
||||
@@ -138,15 +138,21 @@ func (t *sqliteTxStorage) CreateIssue(ctx context.Context, issue *types.Issue, a
|
||||
}
|
||||
|
||||
// Get prefix from config (needed for both ID generation and validation)
|
||||
var prefix string
|
||||
err = t.conn.QueryRowContext(ctx, `SELECT value FROM config WHERE key = ?`, "issue_prefix").Scan(&prefix)
|
||||
if err == sql.ErrNoRows || prefix == "" {
|
||||
var configPrefix string
|
||||
err = t.conn.QueryRowContext(ctx, `SELECT value FROM config WHERE key = ?`, "issue_prefix").Scan(&configPrefix)
|
||||
if err == sql.ErrNoRows || configPrefix == "" {
|
||||
// CRITICAL: Reject operation if issue_prefix config is missing (bd-166)
|
||||
return fmt.Errorf("database not initialized: issue_prefix config is missing (run 'bd init --prefix <prefix>' first)")
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to get config: %w", err)
|
||||
}
|
||||
|
||||
// Use IDPrefix override if set, otherwise use config prefix (bd-hobo)
|
||||
prefix := configPrefix
|
||||
if issue.IDPrefix != "" {
|
||||
prefix = issue.IDPrefix
|
||||
}
|
||||
|
||||
// Generate or validate ID
|
||||
if issue.ID == "" {
|
||||
// Generate hash-based ID with adaptive length based on database size (bd-ea2a13)
|
||||
|
||||
@@ -32,6 +32,7 @@ type Issue struct {
|
||||
CompactedAtCommit *string `json:"compacted_at_commit,omitempty"` // Git commit hash when compacted
|
||||
OriginalSize int `json:"original_size,omitempty"`
|
||||
SourceRepo string `json:"-"` // Internal: Which repo owns this issue (multi-repo support) - NOT exported to JSONL
|
||||
IDPrefix string `json:"-"` // Internal: Override prefix for ID generation (bd-hobo) - NOT exported to JSONL
|
||||
Labels []string `json:"labels,omitempty"` // Populated only for export/import
|
||||
Dependencies []*Dependency `json:"dependencies,omitempty"` // Populated only for export/import
|
||||
Comments []*Comment `json:"comments,omitempty"` // Populated only for export/import
|
||||
|
||||
Reference in New Issue
Block a user