Files
beads/cmd/bd/init.go
Steve Yegge 15afb5ad17 Implement JSONL export/import and shift to text-first architecture
This is a fundamental architectural shift from binary SQLite to JSONL as
the source of truth for git workflows.

## New Features

- `bd export --format=jsonl` - Export issues to JSON Lines format
- `bd import` - Import issues from JSONL (create new, update existing)
- `--skip-existing` flag for import to only create new issues

## Architecture Change

**Before:** Binary SQLite database committed to git
**After:** JSONL text files as source of truth, SQLite as ephemeral cache

Benefits:
- Git-friendly text format with clean diffs
- AI-resolvable merge conflicts (append-only is 95% conflict-free)
- Human-readable issue tracking in git
- No binary merge conflicts

## Documentation

- Updated README with JSONL-first workflow and git hooks
- Added TEXT_FORMATS.md analyzing JSONL vs CSV vs binary
- Updated GIT_WORKFLOW.md with historical context
- .gitignore now excludes *.db, includes .beads/*.jsonl

## Implementation Details

- Export sorts issues by ID for consistent diffs
- Import handles both creates and updates atomically
- Proper handling of pointer fields (EstimatedMinutes)
- All tests passing

## Breaking Changes

- Database files (*.db) should now be gitignored
- Use export/import workflow for git collaboration
- Git hooks recommended for automation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-12 01:17:50 -07:00

71 lines
2.0 KiB
Go

package main
import (
"context"
"fmt"
"os"
"path/filepath"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/steveyegge/beads/internal/storage/sqlite"
)
var initCmd = &cobra.Command{
Use: "init",
Short: "Initialize bd in the current directory",
Long: `Initialize bd in the current directory by creating a .beads/ directory
and database file. Optionally specify a custom issue prefix.`,
Run: func(cmd *cobra.Command, args []string) {
prefix, _ := cmd.Flags().GetString("prefix")
if prefix == "" {
// Auto-detect from directory name
cwd, err := os.Getwd()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: failed to get current directory: %v\n", err)
os.Exit(1)
}
prefix = filepath.Base(cwd)
}
// Create .beads directory
beadsDir := ".beads"
if err := os.MkdirAll(beadsDir, 0755); err != nil {
fmt.Fprintf(os.Stderr, "Error: failed to create %s directory: %v\n", beadsDir, err)
os.Exit(1)
}
// Create database
dbPath := filepath.Join(beadsDir, prefix+".db")
store, err := sqlite.New(dbPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: failed to create database: %v\n", err)
os.Exit(1)
}
// Set the issue prefix in config
ctx := context.Background()
if err := store.SetConfig(ctx, "issue_prefix", prefix); err != nil {
fmt.Fprintf(os.Stderr, "Error: failed to set issue prefix: %v\n", err)
store.Close()
os.Exit(1)
}
store.Close()
green := color.New(color.FgGreen).SprintFunc()
cyan := color.New(color.FgCyan).SprintFunc()
fmt.Printf("\n%s bd initialized successfully!\n\n", green("✓"))
fmt.Printf(" Database: %s\n", cyan(dbPath))
fmt.Printf(" Issue prefix: %s\n", cyan(prefix))
fmt.Printf(" Issues will be named: %s\n\n", cyan(prefix+"-1, "+prefix+"-2, ..."))
fmt.Printf("Run %s to get started.\n\n", cyan("bd quickstart"))
},
}
func init() {
initCmd.Flags().StringP("prefix", "p", "", "Issue prefix (default: current directory name)")
rootCmd.AddCommand(initCmd)
}