Commit Graph

23 Commits

Author SHA1 Message Date
teernisse
c2bdc01eac feat: implement 5 CLI-IMP beads — hybrid search, robot-docs, data gaps, drift, skill rewrite
Wire hybrid search (FTS5 + vector + RRF) to CLI search command.
Enhance robot-docs with quick_start guide and example_output.
Fill data gaps in issue detail (references, note counts, closed_at).
Add lore drift command for discussion divergence detection.
Rewrite agent skills to mandate lore for reads, glab for writes.

Closes: bd-1ksf, bd-91j1, bd-2g50, bd-1cjx, bd-kvij
2026-02-12 11:51:02 -05:00
teernisse
3a1307dcdc feat(cli): wire defaultProject through init and all commands
Integrates the defaultProject config field across the entire CLI
surface so that omitting `-p` now falls back to the configured default.

Init command:
- New `--default-project` flag on `lore init` (and robot-mode variant)
- InitInputs.default_project: Option<String> passed through to run_init
- Validation in run_init ensures the default matches a configured path
- Interactive mode: when multiple projects are configured, prompts
  whether to set a default and which project to use
- Robot mode: InitOutputJson now includes default_project (omitted when
  null) for downstream automation
- Autocorrect dictionary updated with `--default-project`

Command handlers applying effective_project():
- handle_issues: list filters use config default when -p omitted
- handle_mrs: same cascading resolution for MR listing
- handle_ingest: dry-run and full sync respect the default
- handle_timeline: TimelineParams.project resolved via effective_project
- handle_search: SearchCliFilters.project resolved via effective_project
- handle_generate_docs: project filter cascades
- handle_who: falls back to config.default_project when -p omitted
- handle_count: both count subcommands respect the default
- handle_discussions: discussion count filters respect the default

Robot-docs:
- init command schema updated with --default-project flag and
  response_schema showing default_project as string?
- New config_notes section documents the defaultProject field with
  type, description, and example

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 15:09:46 -05:00
Taylor Eernisse
d9f99ef21d feat(cli): status display/filtering, expanded --fields, and robot-docs --brief
Work item status integration across all CLI output:

Issue listing (lore list issues):
- New Status column appears when any issue has status data, with
  hex-color rendering using ANSI 256-color approximation
- New --status flag for case-insensitive filtering (OR logic for
  multiple values): lore issues --status "In progress" --status "To do"
- Status fields (name, category, color, icon_name, synced_at) in issue
  list query and JSON output with conditional serialization

Issue detail (lore show issue):
- Displays "Status: In progress (in_progress)" with color-coded output
  using ANSI 256-color approximation from hex color values
- Status fields included in robot mode JSON with ISO timestamps
- IssueRow, IssueDetail, IssueDetailJson all carry status columns

Robot mode field selection expanded to new commands:
- search: --fields with "minimal" preset (document_id, title, source_type, score)
- timeline: --fields with "minimal" preset (timestamp, type, entity_iid, detail)
- who: --fields with per-mode presets (expert_minimal, workload_minimal, etc.)
- robot-docs: new --brief flag strips response_schema from output (~60% smaller)
- strip_schemas() utility in robot.rs for --brief mode
- expand_fields_preset() extended for search, timeline, and all who modes

Robot-docs manifest updated with --status flag documentation, --fields
flags for search/timeline/who, fields_presets sections, and corrected
search response schema field names.

Note: replaces empty commit dcfd449 which lost staging during hook execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 08:13:37 -05:00
Taylor Eernisse
41504b4941 feat(who): configurable scoring weights, MR refs, detail mode, and suffix path resolution
Expert mode now surfaces the specific MR references (project/path!iid) that
contributed to each expert's score, capped at 50 per user. A new --detail flag
adds per-MR breakdowns showing role (Author/Reviewer/both), note count, and
last activity timestamp.

Scoring weights (author_weight, reviewer_weight, note_bonus) are now
configurable via the config file's `scoring` section with validation that
rejects negative values. Defaults shift to author_weight=25, reviewer_weight=10,
note_bonus=1 — better reflecting that code authorship is a stronger expertise
signal than review assignment alone.

Path resolution gains suffix matching: typing "login.rs" auto-resolves to
"src/auth/login.rs" when unambiguous, with clear disambiguation errors when
multiple paths match. Project-scoping (-p) narrows the candidate set.

The MAX_MR_REFS_PER_USER constant is promoted to module scope for reuse
across expert and overlap modes. Human output shows MR refs inline and detail
sub-rows when requested. Robot JSON includes mr_refs, mr_refs_total,
mr_refs_truncated, and optional details array.

Includes comprehensive tests for suffix resolution, scoring weight
configurability, MR ref aggregation across projects, and detail mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 10:15:15 -05:00
Taylor Eernisse
940a96375a refactor(search): rename --after/--updated-after to --since/--updated-since
The --since naming is more intuitive (matches git log --since) and
consistent with the list commands which already use --since. Renames
the CLI flags, SearchCliFilters fields, SearchFilters fields,
autocorrect registry, and robot-docs manifest. No behavioral change.

Affected paths:
- cli/mod.rs: SearchArgs field + clap attribute rename
- cli/commands/search.rs: SearchCliFilters + run_search plumbing
- search/filters.rs: SearchFilters struct + apply_filters logic
- main.rs: handle_search + robot-docs JSON
- cli/autocorrect.rs: COMMAND_FLAGS entry for search

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 14:33:24 -05:00
Taylor Eernisse
95b7183add feat(who): expand expert + overlap queries with mr_file_changes and mr_reviewers
Chain: bd-jec (config flag) -> bd-2yo (fetch MR diffs) -> bd-3qn6 (rewrite who queries)

- Add fetch_mr_file_changes config option and --no-file-changes CLI flag
- Add GitLab MR diffs API fetch pipeline with watermark-based sync
- Create migration 020 for diffs_synced_for_updated_at watermark column
- Rewrite query_expert() and query_overlap() to use 4-signal UNION ALL:
  DiffNote reviewers, DiffNote MR authors, file-change authors, file-change reviewers
- Deduplicate across signal types via COUNT(DISTINCT CASE WHEN ... THEN mr_id END)
- Add insert_file_change test helper, 8 new who tests, all 397 tests pass
- Also includes: list performance migration 019, autocorrect module, README updates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:35:14 -05:00
Taylor Eernisse
f267578aab feat: implement lore who — people intelligence commands (5 modes)
Add `lore who` command with 5 query modes answering collaboration questions
using existing DB data (280K notes, 210K discussions, 33K DiffNotes):

- Expert: who knows about a file/directory (DiffNote path analysis + MR breadth scoring)
- Workload: what is a person working on (assigned issues, authored/reviewing MRs, discussions)
- Active: what discussions need attention (unresolved resolvable, global/project-scoped)
- Overlap: who else is touching these files (dual author+reviewer role tracking)
- Reviews: what review patterns does a person have (prefix-based category extraction)

Includes migration 017 (5 composite indexes), CLI skeleton with clap conflicts_with
validation, robot JSON output with input+resolved_input reproducibility, human terminal
output, and 20 unit tests. All quality gates pass.

Closes: bd-1q8z, bd-34rr, bd-2rk9, bd-2ldg, bd-zqpf, bd-s3rc, bd-m7k1, bd-b51e,
bd-2711, bd-1rdi, bd-3mj2, bd-tfh3, bd-zibc, bd-g0d5

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:11:14 -05:00
Taylor Eernisse
b5f78e31a8 fix(cli): audit-driven improvements to flags, help, exit codes, and deprecation
Addresses findings from a comprehensive CLI readiness audit:

Flag design (I2):
- Add hidden --no-verbose flag with overrides_with semantics, matching
  the --no-quiet pattern already established for all other boolean flags.

Help text (I3):
- Add after_help examples to issues, mrs, search, sync, and timeline
  subcommands. Each shows 3-4 concrete, runnable commands with comments.

Help headings (I4/P5):
- Move --mode and --fts-mode from "Output" heading to "Mode" heading
  in the search subcommand. These control search strategy, not output
  format — "Output" is reserved for --limit, --explain, --fields.

Exit codes (I5):
- Health check failure now exits 19 (was 1). Exit code 1 is reserved
  for internal errors only. robot-docs updated to document code 19.

Deprecation visibility (P4):
- Deprecated commands (list, show, auth-test, sync-status) now emit
  structured JSON warnings to stderr in robot mode:
  {"warning":{"type":"DEPRECATED","message":"...","successor":"..."}}
  Previously these were silently swallowed in robot mode.

Version string (P1):
- Cli struct uses env!("LORE_VERSION") from build.rs so --version shows
  git hash (see previous commit).

Fields flag (P3):
- --fields help text updated to document the "minimal" preset.

Robot-docs (parallel work):
- response_schema added for every command, documenting the JSON shape
  agents will receive. Agents can now introspect expected fields before
  calling a command.
- error_format documents the new "actions" array.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 23:47:04 -05:00
Taylor Eernisse
a855759bf8 fix: shutdown safety, CLI hardening, exit code collision
Shutdown signal improvements:
- Upgrade ShutdownSignal from Relaxed to Release/Acquire ordering.
  Relaxed was technically sufficient for a single flag but
  Release/Acquire is the textbook correct pattern and ensures
  visibility guarantees across threads without relying on x86 TSO.
- Add double Ctrl+C support to all three signal handlers (ingest,
  embed, sync). First Ctrl+C sets cooperative flag with user message;
  second Ctrl+C force-exits with code 130 (standard SIGINT convention).

CLI hardening:
- LORE_ROBOT env var now checks for truthy values (!empty, !="0",
  !="false") instead of mere existence. Setting LORE_ROBOT=0 or
  LORE_ROBOT=false no longer activates robot mode.
- Replace unreachable!() in color mode match with defensive warning
  and fallback to auto. Clap validates the values but defense in depth
  prevents panics if the value_parser is ever changed.
- Replace unreachable!() in completions shell match with proper error
  return for unsupported shells.

Exit code collision fix:
- ConfigNotFound was mapped to exit code 2 (error.rs:56) which
  collided with handle_clap_error() also using exit code 2 for parse
  errors. Agents calling lore --robot could not distinguish "bad
  arguments" from "missing config file."
- Restore ConfigNotFound to exit code 20 (its original dedicated code).
- Update robot-docs exit code table: code 2 = "Usage error", code 20 =
  "Config not found".

Build script:
- Track .git/refs/heads directory for Cargo rebuild triggers. Ensures
  GIT_HASH env var updates when branch refs change, not just HEAD.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:42:59 -05:00
Taylor Eernisse
69df8a5603 feat(timeline): wire up lore timeline command with human + robot renderers
Complete Gate 3 by implementing the final three beads:
- bd-2f2: Human output renderer with colored event tags, entity refs,
  evidence snippets, and expansion summary footer
- bd-dty: Robot JSON output with {ok,data,meta} envelope, ISO timestamps,
  nested via provenance, and per-event-type details objects
- bd-1nf: CLI wiring with TimelineArgs (9 flags), Commands::Timeline
  variant, handle_timeline handler, VALID_COMMANDS entry, and robot-docs
  manifest with temporal_intelligence workflow

All 7 Gate 3 children now closed. Pipeline: SEED -> HYDRATE -> EXPAND ->
COLLECT -> RENDER fully operational.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 08:49:48 -05:00
Taylor Eernisse
c730b0ec54 feat(cli): Improve help text, error handling, and add fuzzy command suggestions
CLI help improvements (cli/mod.rs):
- Add descriptive help text to all global flags (-c, --robot, -J, etc.)
- Add descriptions to all subcommands (Issues, Mrs, Sync, etc.)
- Add --no-quiet flag for explicit quiet override
- Shell completions now shows installation instructions for each shell
- Optional subcommand: running bare 'lore' shows help in terminal mode,
  robot-docs in robot mode

Structured clap error handling (main.rs):
- Early robot mode detection before parsing (env + args)
- JSON error output for parse failures in robot mode
- Semantic error codes: UNKNOWN_COMMAND, UNKNOWN_FLAG, MISSING_REQUIRED,
  INVALID_VALUE, ARGUMENT_CONFLICT, etc.
- Fuzzy command suggestion using Jaro-Winkler similarity (>0.7 threshold)
- Help/version requests handled normally (exit 0, not error)

Robot-docs enhancements (main.rs):
- Document deprecated command aliases (list issues -> issues, etc.)
- Document clap error codes for programmatic error handling
- Include completions command in manifest
- Update flag documentation to show short forms (-n, -s, -p, etc.)

Dependencies:
- Add strsim 0.11 for Jaro-Winkler fuzzy matching

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 11:22:38 -05:00
Taylor Eernisse
65583ed5d6 refactor: Remove redundant doc comments throughout codebase
Removes module-level doc comments (//! lines) and excessive inline doc
comments that were duplicating information already evident from:
- Function/struct names (self-documenting code)
- Type signatures (the what is clear from types)
- Implementation context (the how is clear from code)

Affected modules:
- cli/* - Removed command descriptions duplicating clap help text
- core/* - Removed module headers and obvious function docs
- documents/* - Removed extractor/regenerator/truncation docs
- embedding/* - Removed pipeline and chunking docs
- gitlab/* - Removed client and transformer docs (kept type definitions)
- ingestion/* - Removed orchestrator and ingestion docs
- search/* - Removed FTS and vector search docs

Philosophy: Code should be self-documenting. Comments should explain
"why" (business decisions, non-obvious constraints) not "what" (which
the code itself shows). This change reduces noise and maintenance burden
while keeping the codebase just as understandable.

Retains comments for:
- Non-obvious business logic
- Important safety invariants
- Complex algorithm explanations
- Public API boundaries where generated docs matter

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 00:04:32 -05:00
teernisse
362503d3bf feat(cli): Add verbosity controls, JSON log format, and triple-layer subscriber
Overhaul the CLI logging infrastructure for production observability:

CLI flags:
- Add -v/-vv/-vvv (--verbose) for progressive stderr verbosity control:
  0=INFO, 1=DEBUG app, 2=DEBUG all, 3+=TRACE
- Add --log-format text|json for structured stderr output in automation
- Existing -q/--quiet overrides verbosity for silent operation

Subscriber architecture (main.rs):
- Replace single-layer subscriber with triple-layer setup:
  1. stderr layer: human-readable or JSON, filtered by -v flags
  2. file layer: always-on JSON to daily-rotated logs (lore.YYYY-MM-DD.log)
  3. MetricsLayer: captures span timing for robot-mode performance payloads
- Parse CLI before subscriber init so verbosity is known at setup time
- Load LoggingConfig early (with graceful fallback for pre-init commands)
- Clean up old log files before subscriber init to avoid holding deleted handles
- Hold WorkerGuard at function scope to ensure flush on exit

Doctor command:
- Add logging health check: validates log directory exists, reports file
  count and total size, warns on missing or inaccessible log directory

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 13:38:43 -05:00
Taylor Eernisse
c35f485e0e refactor(cli): Replace tracing-indicatif with shared MultiProgress
tracing-indicatif pulled in vt100, arrayvec, and its own indicatif
integration layer. Replace it with a minimal SuspendingWriter that
coordinates tracing output with progress bars via a global LazyLock
MultiProgress.

- Add src/cli/progress.rs: shared MultiProgress singleton via LazyLock
  and a SuspendingWriter that suspends bars before writing log lines,
  preventing interleaving/flicker
- Wire all progress bar creation through multi().add() in sync and
  ingest commands
- Replace IndicatifLayer in main.rs with SuspendingWriter for
  tracing-subscriber's fmt layer
- Remove tracing-indicatif from Cargo.toml (drops vt100 and arrayvec
  transitive deps)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:36:31 -05:00
Taylor Eernisse
a50fc78823 style: Apply cargo fmt and clippy fixes across codebase
Automated formatting and lint corrections from parallel agent work:

- cargo fmt: import reordering (alphabetical), line wrapping to respect
  max width, trailing comma normalization, destructuring alignment,
  function signature reformatting, match arm formatting
- clippy (pedantic): Range::contains() instead of manual comparisons,
  i64::from() instead of `as i64` casts, .clamp() instead of
  .max().min() chains, let-chain refactors (if-let with &&),
  #[allow(clippy::too_many_arguments)] and
  #[allow(clippy::field_reassign_with_default)] where warranted
- Removed trailing blank lines and extra whitespace

No behavioral changes. All existing tests pass unmodified.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 13:01:59 -05:00
Taylor Eernisse
9d4755521f feat(config): Add fetchResourceEvents config flag with --no-events CLI override
Adds a new boolean field to SyncConfig that controls whether resource
event fetching is performed during sync:

- SyncConfig.fetch_resource_events: defaults to true via serde
  default_true helper, serialized as "fetchResourceEvents" in JSON
- SyncArgs.no_events: --no-events CLI flag that overrides the config
  value to false when present
- SyncOptions.no_events: propagates the flag through the sync pipeline
- handle_sync_cmd: mutates loaded config when --no-events is set,
  ensuring the flag takes effect regardless of config file contents

This follows the existing pattern established by --no-embed and
--no-docs flags, where CLI flags override config file defaults.
The config is loaded as mutable specifically to support this override.

Also adds "events" to the count command's entity type value_parser,
enabling `lore count events` (implementation in a separate commit).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 12:07:06 -05:00
Taylor Eernisse
aebbe6b795 feat(cli): Wire --full flag for embed, add sync stage spinners
- Add --full / --no-full flag pair to EmbedArgs with overrides_with
  semantics matching the existing flag pattern. When active, atomically
  DELETEs all embedding_metadata and embeddings before re-embedding.

- Thread the full flag through run_embed -> run_sync so that
  'lore sync --full' triggers a complete re-embed alongside the full
  re-ingest it already performed.

- Add indicatif spinners to sync stages with dynamic stage numbering
  that adjusts when --no-docs or --no-embed skip stages. Spinners are
  hidden in robot mode.

- Update robot-docs manifest to advertise the new --full flag on the
  embed command.

- Replace hardcoded schema version 9 in health check with the
  LATEST_SCHEMA_VERSION constant from db.rs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 09:35:22 -05:00
Taylor Eernisse
585b746461 feat(cli): Add --color, --quiet, --no-X negations, completions, and help headings
Global flags:
- --color (auto|always|never) for explicit color control
- --quiet/-q to suppress non-essential output
- Hidden Completions subcommand for bash/zsh/fish/powershell

Flag negation (--no-X) with overrides_with for: has-due, asc, open
(issues/mrs), force/full (ingest/sync), check (stats), explain (search),
retry-failed (embed). Enables scripted flag composition where later flags
override earlier ones.

Validation:
- value_parser on search --mode, --type, --fts-mode for early rejection
- Remove requires="check" from --repair (auto-enabled in handler)

Polish:
- help_heading groups (Filters, Sorting, Output, Actions) on issues,
  mrs, and search args for cleaner --help output
- Hide Backup, Reset, and Completions from --help

Co-Authored-By: Claude (us.anthropic.claude-opus-4-5-20251101-v1:0) <noreply@anthropic.com>
2026-01-30 16:54:18 -05:00
Taylor Eernisse
daf5a73019 feat(cli): Add search, stats, embed, sync, health, and robot-docs commands
Extends the CLI with six new commands that complete the search pipeline:

- lore search <QUERY>: Hybrid search with mode selection (lexical,
  hybrid, semantic), rich filtering (--type, --author, --project,
  --label, --path, --after, --updated-after), result limits, and
  optional explain mode showing RRF score breakdowns. Safe FTS mode
  sanitizes user input; raw mode passes through for power users.

- lore stats: Document and index statistics with optional --check
  for integrity verification and --repair to fix inconsistencies
  (orphaned documents, missing FTS entries, stale dirty queue items).

- lore embed: Generate vector embeddings via Ollama. Supports
  --retry-failed to re-attempt previously failed embeddings.

- lore generate-docs: Drain the dirty queue to regenerate documents.
  --full seeds all entities for complete rebuild. --project scopes
  to a single project.

- lore sync: Full pipeline orchestration (ingest issues + MRs,
  generate-docs, embed) with --no-embed and --no-docs flags for
  partial runs. Reports per-stage results and total elapsed time.

- lore health: Quick pre-flight check (config exists, DB exists,
  schema current). Returns exit code 1 if unhealthy. Designed for
  agent pre-flight scripts.

- lore robot-docs: Machine-readable command manifest for agent
  self-discovery. Returns all commands, flags, examples, exit codes,
  and recommended workflows as structured JSON.

Also enhances lore init with --gitlab-url, --token-env-var, and
--projects flags for fully non-interactive robot-mode initialization.
Fixes init's force/non-interactive precedence logic and adds JSON
output for robot mode.

Updates all command files for the GiError -> LoreError rename.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 15:47:10 -05:00
Taylor Eernisse
856aad1641 feat(cli): Redesign CLI with noun-first subcommands
Replaces the verb-first pattern ('lore list issues', 'lore show
issue 42') with noun-first subcommands that feel more natural:

  lore issues          # list issues
  lore issues 42       # show issue #42
  lore mrs             # list merge requests
  lore mrs 99          # show MR #99
  lore ingest          # ingest everything
  lore ingest issues   # ingest only issues
  lore count issues    # count issues
  lore status          # sync status
  lore auth            # verify auth
  lore doctor          # health check

Key changes:
- New IssuesArgs, MrsArgs, IngestArgs, CountArgs structs with
  short flags (-n, -s, -p, -a, -l, -o, -f, -J, etc.)
- Global -J/--json flag as shorthand for --robot
- 'lore ingest' with no argument ingests both issues and MRs,
  emitting combined JSON summary in robot mode
- --asc flag replaces --order=asc/desc for brevity
- Renamed flags: --has-due-date -> --has-due, --type -> --for,
  --confirm -> --yes, target_branch -> --target, etc.

Old commands (list, show, auth-test, sync-status) are preserved
as hidden backward-compat aliases that emit deprecation warnings
to stderr before delegating to the new handlers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 08:42:26 -05:00
teernisse
55b895a2eb Update name to gitlore instead of gitlab-inbox 2026-01-28 15:49:14 -05:00
Taylor Eernisse
7d0d586932 feat(cli): Add global robot mode for machine-readable output
Introduces a unified robot mode that enables JSON output across all
commands, designed for AI agent and script consumption.

Robot mode activation (any of):
- --robot flag: Explicit opt-in
- GI_ROBOT=1 env var: For persistent configuration
- Non-TTY stdout: Auto-detect when piped (e.g., gi list issues | jq)

Implementation:
- Cli::is_robot_mode(): Centralized detection logic
- All command handlers receive robot_mode boolean
- Errors emit structured JSON to stderr with exit codes
- Success responses emit JSON to stdout

Behavior changes in robot mode:
- No color/emoji output (no ANSI escapes)
- No progress spinners or interactive prompts
- Timestamps as ISO 8601 strings (not relative "2 hours ago")
- Full content (no truncation of descriptions/notes)
- Structured error objects with code, message, suggestion

This enables reliable parsing by Claude Code, shell scripts, and
automation pipelines. The auto-detect on non-TTY means simple piping
"just works" without explicit flags.

Per-command --json flags remain for explicit control and override
robot mode when needed for human-friendly terminal + JSON file output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 22:46:27 -05:00
Taylor Eernisse
8fb890c528 feat(cli): Implement complete command-line interface
Provides a user-friendly CLI for all GitLab Inbox operations.

src/cli/mod.rs - Clap command definitions:
- Global --config flag for alternate config path
- Subcommands: init, auth-test, doctor, version, backup, reset,
  migrate, sync-status, ingest, list, count, show
- Ingest supports --type (issues/merge_requests), --project filter,
  --force lock override, --full resync
- List supports rich filtering: --state, --author, --assignee,
  --label, --milestone, --since, --due-before, --has-due-date
- List supports --sort (updated/created/iid), --order (asc/desc)
- List supports --open to launch browser, --json for scripting

src/cli/commands/ - Command implementations:

init.rs: Interactive configuration wizard
- Prompts for GitLab URL, token env var, projects to track
- Creates config file and initializes database
- Supports --force overwrite and --non-interactive mode

auth_test.rs: Verify GitLab authentication
- Calls /api/v4/user to validate token
- Displays username and GitLab instance URL

doctor.rs: Environment health check
- Validates config file exists and parses correctly
- Checks database connectivity and migration state
- Verifies GitLab authentication
- Reports token environment variable status
- Supports --json output for CI integration

ingest.rs: Data synchronization from GitLab
- Acquires sync lock with stale detection
- Shows progress bars for issues and discussions
- Reports sync statistics on completion
- Supports --full flag to reset cursors and refetch all data

list.rs: Query local database
- Formatted table output with comfy-table
- Filters build dynamic SQL with parameterized queries
- Username filters normalize @ prefix automatically
- --open flag uses 'open' crate for cross-platform browser launch
- --json outputs array of issue objects

show.rs: Detailed entity view
- Displays issue metadata in structured format
- Shows full description with markdown
- Lists labels, assignees, milestone
- Shows discussion threads with notes

count.rs: Entity statistics
- Counts issues, discussions, or notes
- Supports --type filter for discussions/notes

sync_status.rs: Display sync watermarks
- Shows last sync time per project
- Displays cursor positions for debugging

src/main.rs - Application entry point:
- Initializes tracing subscriber with env-filter
- Parses CLI arguments via clap
- Dispatches to appropriate command handler
- Consistent error formatting for all failure modes

src/lib.rs - Library entry point:
- Exports cli, core, gitlab, ingestion modules
- Re-exports Config, GiError, Result for convenience

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 11:28:52 -05:00