Fix GH#367: bd import defaulting to stdin is confusing
Changes: 1. Add TTY detection to bd import - prevents silent hang when run interactively without arguments. Shows helpful usage message instead. 2. Fix misleading error messages - change "Run 'bd import'" to "Run 'bd sync --import-only'" or explicit file path throughout. Technical details: - Added golang.org/x/term dependency for IsTerminal() - When stdin is a TTY and no -i flag: show usage and exit - When stdin is piped: works as before (supports script pipelines) - Preserved all legitimate stdin uses: * python gh2jsonl.py --repo owner/repo | bd import * python md2jsonl.py feature.md | bd import * git show HEAD:.beads/beads.jsonl | bd import -i /dev/stdin Updated error messages in: - cmd/bd/staleness.go - main "out of sync" error - cmd/bd/sync.go - merge completion suggestions - internal/rpc/server_export_import_auto.go - daemon warnings 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/steveyegge/beads/internal/debug"
|
"github.com/steveyegge/beads/internal/debug"
|
||||||
"github.com/steveyegge/beads/internal/storage/sqlite"
|
"github.com/steveyegge/beads/internal/storage/sqlite"
|
||||||
"github.com/steveyegge/beads/internal/types"
|
"github.com/steveyegge/beads/internal/types"
|
||||||
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
var importCmd = &cobra.Command{
|
var importCmd = &cobra.Command{
|
||||||
@@ -71,6 +72,18 @@ NOTE: Import requires direct database access and does not work with daemon mode.
|
|||||||
orphanHandling, _ := cmd.Flags().GetString("orphan-handling")
|
orphanHandling, _ := cmd.Flags().GetString("orphan-handling")
|
||||||
force, _ := cmd.Flags().GetBool("force")
|
force, _ := cmd.Flags().GetBool("force")
|
||||||
|
|
||||||
|
// Check if stdin is being used interactively (not piped)
|
||||||
|
if input == "" && term.IsTerminal(int(os.Stdin.Fd())) {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error: No input specified.\n\n")
|
||||||
|
fmt.Fprintf(os.Stderr, "Usage:\n")
|
||||||
|
fmt.Fprintf(os.Stderr, " bd import -i .beads/beads.jsonl # Import from file\n")
|
||||||
|
fmt.Fprintf(os.Stderr, " bd import -i .beads/beads.jsonl --dry-run # Preview changes\n")
|
||||||
|
fmt.Fprintf(os.Stderr, " cat data.jsonl | bd import # Import from pipe\n")
|
||||||
|
fmt.Fprintf(os.Stderr, " bd sync --import-only # Import latest JSONL\n\n")
|
||||||
|
fmt.Fprintf(os.Stderr, "For more information, run: bd import --help\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
// Open input
|
// Open input
|
||||||
in := os.Stdin
|
in := os.Stdin
|
||||||
if input != "" {
|
if input != "" {
|
||||||
|
|||||||
@@ -44,14 +44,14 @@ func ensureDatabaseFresh(ctx context.Context) error {
|
|||||||
|
|
||||||
// Database is stale - refuse to operate
|
// Database is stale - refuse to operate
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"Database out of sync with JSONL. Run 'bd import' first.\n\n"+
|
"Database out of sync with JSONL. Run 'bd sync --import-only' to fix.\n\n"+
|
||||||
"The JSONL file has been updated (e.g., after 'git pull') but the database\n"+
|
"The JSONL file has been updated (e.g., after 'git pull') but the database\n"+
|
||||||
"hasn't been imported yet. This would cause you to see stale/incomplete data.\n\n"+
|
"hasn't been imported yet. This would cause you to see stale/incomplete data.\n\n"+
|
||||||
"To fix:\n"+
|
"To fix:\n"+
|
||||||
" bd import -i .beads/beads.jsonl # Import JSONL updates to database\n\n"+
|
" bd sync --import-only # Import JSONL updates to database\n"+
|
||||||
|
" bd import -i .beads/beads.jsonl # Alternative: specify file explicitly\n\n"+
|
||||||
"If in a sandboxed environment (e.g., Codex) where daemon can't be stopped:\n"+
|
"If in a sandboxed environment (e.g., Codex) where daemon can't be stopped:\n"+
|
||||||
" bd --sandbox ready # Use direct mode (no daemon)\n"+
|
" bd --sandbox ready # Use direct mode (no daemon)\n"+
|
||||||
" bd import --force # Force metadata update\n"+
|
|
||||||
" bd ready --allow-stale # Skip staleness check (use with caution)\n\n"+
|
" bd ready --allow-stale # Skip staleness check (use with caution)\n\n"+
|
||||||
"Or use daemon mode (auto-imports on every operation):\n"+
|
"Or use daemon mode (auto-imports on every operation):\n"+
|
||||||
" bd daemon start\n"+
|
" bd daemon start\n"+
|
||||||
|
|||||||
@@ -862,7 +862,7 @@ func mergeSyncBranch(ctx context.Context, dryRun bool) error {
|
|||||||
// Suggest next steps
|
// Suggest next steps
|
||||||
fmt.Println("\nNext steps:")
|
fmt.Println("\nNext steps:")
|
||||||
fmt.Println("1. Review the merged changes")
|
fmt.Println("1. Review the merged changes")
|
||||||
fmt.Println("2. Run 'bd import' to sync the database with merged JSONL")
|
fmt.Println("2. Run 'bd sync --import-only' to sync the database with merged JSONL")
|
||||||
fmt.Println("3. Run 'bd sync' to push changes to remote")
|
fmt.Println("3. Run 'bd sync' to push changes to remote")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -38,6 +38,7 @@ require (
|
|||||||
github.com/tidwall/pretty v1.2.1 // indirect
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
github.com/tidwall/sjson v1.2.5 // indirect
|
github.com/tidwall/sjson v1.2.5 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
golang.org/x/text v0.30.0 // indirect
|
golang.org/x/text v0.30.0 // indirect
|
||||||
golang.org/x/tools v0.38.0 // indirect
|
golang.org/x/tools v0.38.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -74,6 +74,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ func (s *Server) checkAndAutoImportIfStale(req *Request) error {
|
|||||||
s.importInProgress.Store(false)
|
s.importInProgress.Store(false)
|
||||||
shouldDeferRelease = false
|
shouldDeferRelease = false
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Warning: auto-import skipped - .beads files have uncommitted changes. Run 'bd import' manually after committing.\n")
|
fmt.Fprintf(os.Stderr, "Warning: auto-import skipped - .beads files have uncommitted changes. Run 'bd sync' after committing.\n")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,7 +292,7 @@ func (s *Server) checkAndAutoImportIfStale(req *Request) error {
|
|||||||
err = autoimport.AutoImportIfNewer(importCtx, store, dbPath, notify, importFunc, onChanged)
|
err = autoimport.AutoImportIfNewer(importCtx, store, dbPath, notify, importFunc, onChanged)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if importCtx.Err() == context.DeadlineExceeded {
|
if importCtx.Err() == context.DeadlineExceeded {
|
||||||
fmt.Fprintf(os.Stderr, "Error: auto-import timed out after 5s. Run 'bd import' manually.\n")
|
fmt.Fprintf(os.Stderr, "Error: auto-import timed out after 5s. Run 'bd sync --import-only' manually.\n")
|
||||||
return fmt.Errorf("auto-import timed out")
|
return fmt.Errorf("auto-import timed out")
|
||||||
}
|
}
|
||||||
// Log but don't fail the request - let it proceed with stale data
|
// Log but don't fail the request - let it proceed with stale data
|
||||||
|
|||||||
Reference in New Issue
Block a user