wherehouse

command module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 3 Imported by: 0

README

wherehouse

Event-sourced CLI inventory tracker: "Where did I put my 10mm socket?"

GitHub release (with filter) go.mod GitHub License


Quick Example

# Add locations (places are immovable; containers can hold things and be moved)
wherehouse add "Garage" --type place
wherehouse add "Toolbox" --type container
wherehouse add "Garage:Toolbox:10mm socket" --type leaf

# Search by name
wherehouse scry "socket"
# → Garage:Toolbox:10mm socket

# Move something
wherehouse move "Garage:Toolbox" --to "Basement"

# View full event history
wherehouse history "Basement:Toolbox:10mm socket"

# Browse everything in a web UI
wherehouse serve

Why Wherehouse?

You know you own a 10mm socket wrench. You used it last week. Where is it now?

Wherehouse tracks every entity's location with a complete audit trail. Event-sourced architecture means you can see where things were, when they moved, and rebuild the entire state from history.

Key Features
  • Event-Sourced — append-only event log; projections are derived and rebuildable
  • Unified Entity Model — locations and items are both entities; hierarchy via colon-separated paths (Garage:Toolbox:Wrench)
  • Hierarchical Paths — place > container > leaf nesting with colon-path addressing
  • Status Tracking — mark entities as ok, missing, borrowed, loaned, or removed
  • Full History — every move, rename, and status change is recorded with actor and timestamp
  • Web UI — local HTTP server for browsing, searching, adding, and editing inventory
  • Network Storage Ready — SQLite WAL mode works with NFS/SMB mounts
  • Multi-User Attribution — trust-based; tracks who made changes, no permissions enforcement
  • Single File Database — entire inventory in one portable SQLite file

Installation

Build from Source

Requirements: Go 1.25+, SQLite 3.x (embedded via modernc.org/sqlite)

git clone https://github.com/asphaltbuffet/wherehouse.git
cd wherehouse

# Build
go build -o dist/wherehouse .

# Or with mise
mise run build

# Install to user bin
mkdir -p ~/.local/bin
cp dist/wherehouse ~/.local/bin/
Nix

Standalone install:

nix profile install github:asphaltbuffet/wherehouse/v0.6.0

Home Manager — add as an input and load the bundled module:

# flake.nix
{
  inputs = {
    nixpkgs.url      = "github:NixOS/nixpkgs/nixpkgs-unstable";
    home-manager.url = "github:nix-community/home-manager";
    wherehouse.url   = "github:asphaltbuffet/wherehouse/v0.6.0";
    wherehouse.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = { nixpkgs, home-manager, wherehouse, ... }: {
    homeConfigurations."alice" = home-manager.lib.homeManagerConfiguration {
      pkgs = nixpkgs.legacyPackages.x86_64-linux;
      modules = [
        wherehouse.homeManagerModules.default
        { programs.wherehouse.enable = true; }
      ];
    };
  };
}

Quick Start

1. Initialize Config
wherehouse config init
# → Created config at ~/.config/wherehouse/wherehouse.toml

The database is created automatically on first use at ~/.local/share/wherehouse/wherehouse.db.

2. Add Entities

Entities have three types:

Type Description
place Immovable location (room, building, shelf)
container Movable holder (box, toolbox, bag)
leaf Individual item that holds nothing
# Build a hierarchy
wherehouse add "Garage" --type place
wherehouse add "Toolbox" --type container
wherehouse add "Garage:Toolbox" --type container   # nested path creates under Toolbox

# Add individual items
wherehouse add "Garage:Toolbox:10mm socket" --type leaf
wherehouse add "Garage:Toolbox:Ratchet" --type leaf

Paths are colon-separated from the root. Providing a nested path like Garage:Toolbox:Wrench will add Wrench under the existing Garage:Toolbox entity.

# Search by name (substring matching)
wherehouse scry "socket"
# → Garage:Toolbox:10mm socket

# List all entities
wherehouse scry

# JSON output for scripting
wherehouse scry "socket" --json
4. Move Entities
# Move a container (and everything in it) to a new parent
wherehouse move "Garage:Toolbox" --to "Basement"

# Move a single item
wherehouse move "Garage:Toolbox:Ratchet" --to "Garage:Pegboard"

Only container and leaf entities are movable. place entities cannot be moved.

5. View History
# Full event timeline for an entity (newest first)
wherehouse history "Basement:Toolbox:10mm socket"

# JSON output
wherehouse history "Basement:Toolbox" --json
6. Track Status
# Mark something as missing
wherehouse status "Basement:Toolbox:10mm socket" --set missing

# Mark it found again
wherehouse status "Basement:Toolbox:10mm socket" --set ok

# Record a loan with a note
wherehouse status "Garage:Ladder" --set loaned --note "lent to Bob"

# Valid statuses: ok, missing, borrowed, loaned, removed
7. List Entities
# List everything
wherehouse list

# List under a specific path
wherehouse list --under "Garage:Toolbox"

# Filter by type or status
wherehouse list --type container
wherehouse list --status missing
8. Rename Entities
wherehouse rename "Garage:Toolbox" --to "Tool Chest"
9. Remove Entities
wherehouse remove "Garage:Tool Chest:Broken Wrench"
wherehouse remove "Garage:Old Box" --note "disposed"
10. Export Event Log
# Export all events as NDJSON (one JSON object per line)
wherehouse export

# Suppress the "no events" warning when the database is empty
wherehouse export --quiet

The --json flag is accepted silently (the command always emits NDJSON).

11. Check Inventory Health
# Run all checks (config, event log, projection consistency)
wherehouse doctor

# Rebuild the projection from the event log when checks pass
wherehouse doctor --rebuild

# Rebuild even if issues are found
wherehouse doctor --rebuild --force

# JSON output (healthy flag + issue list)
wherehouse doctor --json

Exit code is non-zero when any issue is found, making it safe to use in scripts.

12. Web UI
# Start local web server (default: http://127.0.0.1:8080)
wherehouse serve

# Custom port or bind address
wherehouse serve --port 9090
wherehouse serve --bind 0.0.0.0   # share on LAN

Open http://localhost:8080 in your browser. From the UI you can browse the full entity tree, search, add entities, edit names, and toggle item status.


Commands

wherehouse <command> [flags]

Entity Management:
  add <path>           Add an entity (--type place|container|leaf)
  move <path>          Move an entity to a new parent (--to <dest>)
  rename <path>        Rename an entity (--to <new-name>)
  remove <path>        Remove an entity from the inventory
  status <path>        Change entity status (--set ok|missing|borrowed|loaned|removed)
  list                 List entities (--under, --type, --status filters)
  scry [<name>]        Search entities by name, or list all
  history <path>       Show full event timeline for an entity
  export               Export all events as NDJSON to stdout
  doctor               Check inventory health (--rebuild, --rebuild --force)

Web UI:
  serve                Start local web server (--port, --bind)

Configuration:
  config init          Create config file with defaults (--local, --force)
  config check         Validate config file(s)
  config path          Show config file path(s)

Global Flags:
  -h, --help           Show help
  --version            Show version
  --config <path>      Custom config file path
  --no-config          Skip all config files (use defaults only)
  --db <path>          Override database path
  --as <identity>      Override user identity
  --json               Output as JSON
  -q, --quiet          Quiet mode (-q minimal, -qq silent)

Configuration

File Locations (XDG-Compliant)

Config file (in priority order):

  1. --config <path> flag
  2. $WHEREHOUSE_CONFIG environment variable
  3. ./wherehouse.toml (current directory)
  4. ~/.config/wherehouse/wherehouse.toml (default)

Data: ~/.local/share/wherehouse/wherehouse.db

Config File
wherehouse config init

Generated ~/.config/wherehouse/wherehouse.toml:

[database]
path = "~/.local/share/wherehouse/wherehouse.db"

[logging]
level = "warn"
# file_path = "~/.local/state/wherehouse/wherehouse.log"
# max_size_mb = 10
# max_backups = 3

[user]
default_identity = ""
os_username_map = {}

[output]
default_format = "human"
quiet = false
Environment Variables
export WHEREHOUSE_DATABASE_PATH="/mnt/nas/wherehouse.db"
export WHEREHOUSE_CONFIG="$HOME/projects/workshop/wherehouse.toml"
export WHEREHOUSE_LOG_PATH="/var/log/wherehouse/wherehouse.log"
export WHEREHOUSE_OUTPUT_DEFAULT_FORMAT="json"
Home Manager
programs.wherehouse = {
  enable = true;

  settings = {
    database.path = "~/.local/share/wherehouse/wherehouse.db";

    user = {
      defaultIdentity = "";
      osUsernameMap = { jdoe = "John Doe"; };
    };

    logging = {
      level = "warn";
    };

    output = {
      defaultFormat = "human";
      quiet = false;
    };
  };
};
Option Type Default Description
settings.database.path string XDG data dir Path to SQLite database file
settings.logging.filePath string XDG state dir Path to log file
settings.logging.level "debug""error" "warn" Minimum log level
settings.logging.maxSizeMB int 0 (disabled) Max log size before rotation
settings.logging.maxBackups int 3 Old rotated files to keep
settings.user.defaultIdentity string OS username Display name for attribution
settings.user.osUsernameMap attrset {} Map OS usernames to display names
settings.output.defaultFormat "human" | "json" "human" Default output format
settings.output.quiet bool false Suppress non-essential output

Architecture

Event Sourcing
  • Events are the source of truth (append-only log, never modified)
  • Projections are derived state (rebuildable from events)
  • Replay ordered strictly by event_id — timestamps are informational only
  • No undo — corrections create new compensating events

Events table (source of truth):

CREATE TABLE events (
  event_id         INTEGER PRIMARY KEY AUTOINCREMENT,
  event_type       TEXT NOT NULL,
  timestamp_utc    TEXT NOT NULL,
  actor_user_id    TEXT NOT NULL,
  payload          TEXT NOT NULL,  -- JSON
  note             TEXT
);

Projection tables (derived, rebuildable):

  • locations_current — current entity hierarchy
  • items_current — current entity state
  • projects_current — active and completed projects

Development

Prerequisites
  • Go 1.25+
  • mise (recommended for task automation)
Build & Test
# Build
mise run build        # → dist/wherehouse

# Test (race detector + coverage)
mise run test

# Lint
mise run lint

# Full pipeline
mise run dev        # binary lands in dist/<os>_<arch>_<variant>/wherehouse

Releasing

The changelog (.changes/) is the single source of truth for versions. Releases are triggered by pushing a version tag to GitHub — there is no VERSION file.

To cut a release:

  1. As you work, use changie new to record user-facing changes in .changes/unreleased/. This is optional for non-user-facing changes (tooling, CI, docs) — but at least one fragment must exist before a release.
  2. Run mise run pre-release <major|minor|patch> — this:
    • Hard-fails if no unreleased fragments exist
    • Runs changie batch <bump> to create .changes/<version>.md
    • Runs changie merge to update CHANGELOG.md
    • Updates nix flake pins in this file
  3. Commit .changes/, CHANGELOG.md, and README.md together and open a PR
  4. After the PR merges, run mise run release — this:
    • Asserts the working copy is clean and @ is on trunk
    • Asserts the tag doesn't already exist
    • Asserts CHANGELOG.md has an entry for the version
    • Creates and pushes the v<version> tag

When the tag push lands, CI:

  • Extracts the version from the tag name
  • Asserts CHANGELOG.md has a matching entry
  • Runs goreleaser with .changes/<version>.md as the release notes

Non-user-facing changes (dependency bumps, CI fixes, tooling) should not trigger a release. Merge them to main without running pre-release — they will be bundled into the next release that does have user-facing changes.


Troubleshooting

SQLITE_BUSY / lock errors

Multiple processes accessing the same database, or a network mount with locking issues.

ps aux | grep wherehouse

For network storage, verify NFSv4/SMB file locking support.

Performance degradation
# Check database size
ls -lh ~/.local/share/wherehouse/wherehouse.db

Documentation

Overview

Package main is the entrypoint of the wherehouse application.

Directories

Path Synopsis
cmd
Package cmd provides the cobra command implementations for wherehouse.
Package cmd provides the cobra command implementations for wherehouse.
add
Package add implements adding entities to inventory.
Package add implements adding entities to inventory.
config
Package config implements configuration management commands for wherehouse.
Package config implements configuration management commands for wherehouse.
doctor
Package doctor implements the "wherehouse doctor" command
Package doctor implements the "wherehouse doctor" command
export
Package export implements the export subcommand.
Package export implements the export subcommand.
history
Package history implements the history subcommand.
Package history implements the history subcommand.
import
Package importcmd implements the import subcommand.
Package importcmd implements the import subcommand.
list
Package listcmd implements the wherehouse list command for displaying entities.
Package listcmd implements the wherehouse list command for displaying entities.
man
Package man provides the "wherehouse man" command.
Package man provides the "wherehouse man" command.
move
Package move implements the move subcommand.
Package move implements the move subcommand.
remove
Package remove implements the remove command for marking entities as removed.
Package remove implements the remove command for marking entities as removed.
rename
Package rename implements the rename subcommand.
Package rename implements the rename subcommand.
scry
Package scry implements the "wherehouse scry" command
Package scry implements the "wherehouse scry" command
serve
Package serve provides the "wherehouse serve" command.
Package serve provides the "wherehouse serve" command.
status
Package status implements the status subcommand.
Package status implements the status subcommand.
tag
Package tag implements the wherehouse tag command for adding, removing, and listing entity tags.
Package tag implements the wherehouse tag command for adding, removing, and listing entity tags.
internal
app
Package app provides the use-case entry points for wherehouse.
Package app provides the use-case entry points for wherehouse.
apptesting
Package apptesting provides test helpers for constructing a real *app.App over in-memory SQLite.
Package apptesting provides test helpers for constructing a real *app.App over in-memory SQLite.
cli
Package cli provides shared command-line interface utilities for wherehouse commands.
Package cli provides shared command-line interface utilities for wherehouse commands.
config
Package config provides configuration loading and management for wherehouse.
Package config provides configuration loading and management for wherehouse.
entitypath
Package entitypath provides filepath-like manipulation of wherehouse entity paths.
Package entitypath provides filepath-like manipulation of wherehouse entity paths.
eventbus
Package eventbus owns all event processing for wherehouse.
Package eventbus owns all event processing for wherehouse.
inventory
Package inventory defines the core domain types for wherehouse: entity types and statuses, event types, and the canonical naming rules.
Package inventory defines the core domain types for wherehouse: entity types and statuses, event types, and the canonical naming rules.
logging
Package logging provides a structured, leveled, file-only logger for wherehouse.
Package logging provides a structured, leveled, file-only logger for wherehouse.
nanoid
Package nanoid provides a wrapper around the go-nanoid library for generating secure, URL-friendly unique string IDs.
Package nanoid provides a wrapper around the go-nanoid library for generating secure, URL-friendly unique string IDs.
store
Package store provides mechanical SQLite persistence for wherehouse.
Package store provides mechanical SQLite persistence for wherehouse.
styles
Package styles provides common color styles for user-facing output.
Package styles provides common color styles for user-facing output.
version
Package versioncmd provides version information for the wherehouse application.
Package versioncmd provides version information for the wherehouse application.
web
Package web provides the HTTP server and web UI for wherehouse.
Package web provides the HTTP server and web UI for wherehouse.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL