You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Base commit: 6820b59 is already in main (#57, #18 done); this PR's net diff is the two commits above it (#54 setup wizard + #45 headless).
Note on PR #57: it was the Candle-only slice (issue #18) and has merged into main. This PR (#58, draft) is its superset — it is not a duplicate once #57 is merged; #58 only adds #54 + #45 on top.
bin/memayu/src/main.rs: before default-frontend dispatch, compute #[cfg(feature = "web")] let headless = !is_terminal(stdin) && !is_terminal(stdout). When headless + no subcommand + no TTY → fall back to cmd_serve(config) (web dashboard), printing No TTY detected; falling back to serve mode. If config is invalid in headless mode, prints a helpful hint (run memayu setup / set MEMAYU_* env) and exits 1. TTY present → behavior unchanged.
Uses std::io::IsTerminal (no isatty syscall drift).
bin/memayu/src/main.rs: setup subcommand dispatches to wizard::run_cli_setup(..) (default) or tui_setup::run_full_tui_setup() (--tui); setup --tui without the tui feature prints a clean message.
crates/memayu-identity/src/lib.rs: exposes create_admin_account, resolve_self_hosted_account_id, backfill_placeholder_memories (bootstrap shared with the web POST /api/auth/setup path).
crates/memayu-api/src/modules/api_keys/service.rs: programmatic API-key generation so the wizard can provision the admin key locally.
CI green (build 2m10s, clippy 1m19s, fmt, test 2m19s, audit 3m10s). Tests include the existing cli.rs/doctor.rs subprocess suites + updated roundtrips against raw-mode mock embedder; setup-wizard and headless paths verified via subprocess invocation in bin/memayu/tests/.
Checklist
headless uses IsTerminal only (no syscall drift); only with web feature.
Review of PR #58 at e8f94d8b75b36834df6783bbecc5567e3f82c10e (base d0cf190 + PR #41; includes the already-merged #57/#18), limited to origin/main...HEAD.
🔴 Blocking
None. CI: cargo build, clippy, fmt, test, audit all green (build 2m10s, test 2m19s, audit 3m10s).
🟡 Warning — setup_flow.rs imports local_embedder without a #[cfg(feature = "local-embedding")] guard
bin/memayu/src/setup_flow.rs:14 does use memayu_llm_client::local_embedder::DEFAULT_MODEL_ID; unconditionally, while lib.rs only exposes local_embedder under #[cfg(feature = "local-embedding")]. This compiles today because Cargo.toml ships default = ["local-embedding"], but a --no-default-features build (e.g. for a smaller HTTP-only binary) will break the CLI wizard at compile time. Trivial to guard with #[cfg(feature = "local-embedding")] + a non-local fallback constant; worth fixing pre-merge.
Headless fallback (e8f94d8, issue TUI requires a TTY and cannot run headless — binary must detect this and fall back to serve mode automatically #45): main.rs detects !IsTerminal(stdin) && !IsTerminal(stdout) before default-frontend dispatch; with the web feature and no subcommand, falls back to cmd_serve(config) with a No TTY detected; falling back to serve mode notice. TTY present or subcommand given → behavior unchanged. Invalid config in headless → helpful hint + exit 1.
Interactive setup wizard (9a1bbb6, issue Setup wizard CLI-interactive (stdin/stdout) by default + --tui flag with identical flow; include admin account + API key generation #54): new setup_flow.rs (590 lines) with a shared SetupStep enum + SETUP_STEPS const array — both presenters iterate the same ordered question list, so CLI (dialoguer) and TUI (--tui, ratatui) cannot drift. Steps: device check (sysinfo: arch/RAM/free-disk; gates local-embedding eligibility) → storage → path → embedder (local reuse / http) → local-model picker (local-only) → http-embedder config (http-only) → extraction mode → LLM config (llm-only) → admin email/password/+confirm → bind-addr → port → API-key label. finalize writes config + creates admin via memayu-identity + mints an API key. main.rs dispatches setup (default CLI) vs setup --tui, and prints a clean message when --tui is requested without the tui feature.
crates/memayu-llm-client: #[cfg(feature = "local-embedding")] pub mod local_embedder; (feature-gated, default-on), plus models.rs (new check_models/ModelsCheck) used by the wizard's device/step gating.
crates/memayu-identity: exposes create_admin_account, resolve_self_hosted_account_id, backfill_placeholder_memories (reused by the web POST /api/auth/setup path — no bootstrap duplication).
crates/memayu-api/src/modules/api_keys/service.rs: programmatic API-key generation so the wizard can mint the admin key locally.
LocalEmbedder (Candle, quantized GGUF, pure-Rust — no external C lib); model download via direct ureq to HF (avoids hf-hub 0.3.x relative-Location crash bug), cached under memayu_config::model_dir; unique-temp-file download to avoid clobber; embed output dims match config.
Migration / behavior
Headless: opt-in-by-default for piped/non-TTY; fully backward compatible.
Wizard: memayu setup / setup --tui; writes the same config shape; no new runtime fields.
Subprocess suites in bin/memayu/tests/: version flag, add→list→get→search→delete roundtrip, and doctor_* diagnostics — all pass with a fixed-vector mock embedder over raw mode.
CI green incl. cargo test (2m19s).
Checklist
headless uses IsTerminal only; gated behind web feature.
setup wizard uses a single SETUP_STEPS source of truth for both presenters.
Description was updated pre-review (corrected the merge-state note: #57/#18 is already merged; this PR's net diff is only #54 + #45; clarified the local-embedding feature is default-on but the setup_flow.rs import is unguarded).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
corememayu-core domain logicfeatureNew feature or capabilityinfraCI/release/distributionpriority-mediumMedium priority — important but not blockingstoragelibsql storage provider
1 participant
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two feature additions on top of
main(which already includes PR #57, the local Candle embedder that closed #18):memayu setup) that walks the same orderedSetupSteps as the shared flow, with a TUI variant behindmemayu setup --tui(issue Setup wizard CLI-interactive (stdin/stdout) by default + --tui flag with identical flow; include admin account + API key generation #54 asks for both). Collects storage backend, embedder (reuse the local Candle option from feat: local embedding backend via Candle (#18) #57 OR bring-your-own-key HTTP), extraction mode, admin account (viamemayu-identity), and an API key — writing the resolved config to disk.memayuis invoked with no subcommand and stdout/stdin are not a TTY (no TTY detected → headless mode), fall back from the (unrenderable) TUI toservemode, with a yellow notice line, instead of hanging/errors. Only triggers with thewebfeature compiled in.Base commit:
6820b59is already inmain(#57, #18 done); this PR's net diff is the two commits above it (#54setup wizard +#45headless).Changes
Headless fallback — commit
e8f94d8(#45)bin/memayu/src/main.rs: before default-frontend dispatch, compute#[cfg(feature = "web")] let headless = !is_terminal(stdin) && !is_terminal(stdout). When headless + no subcommand + no TTY → fall back tocmd_serve(config)(web dashboard), printingNo TTY detected; falling back to serve mode. If config is invalid in headless mode, prints a helpful hint (run memayu setup/ setMEMAYU_*env) and exits 1. TTY present → behavior unchanged.std::io::IsTerminal(noisattysyscall drift).Interactive CLI setup wizard — commit
9a1bbb6(#54)bin/memayu/src/setup_flow.rs(~590 lines): shared first-run setup logic — both presenters (CLI + TUI) iterate the sameSETUP_STEPSconst +SetupStepenum +SetupAnswers, so question set/order/result diverge by zero. Steps: device check (sysinfo: arch/RAM/free disk, gates local embedding eligibility) → storage (libsql/postgres) → path → embedder (local/http) → local model picker (only if local) → http embedder config (only if http) → extraction mode → LLM config (onlyllm) → admin email → admin password → confirm → bind addr → port → API-key label.bin/memayu/src/wizard.rs(refactored): defaultmemayu setuppresenter — dialoguer stdin/stdout, reads existing config as preseed defaults, walksSETUP_STEPS, skips branch-inactive steps viastep_active, callsfinalize(writes config + creates admin viamemayu-identity+ mints API key).bin/memayu/src/tui_setup.rs(refactored):memayu setup --tuipresenter — ratatui, sameSetupSteps, ratatui widgets instead of dialoguer prompts, cancellation → returnNonecleanly.bin/memayu/src/main.rs:setupsubcommand dispatches towizard::run_cli_setup(..)(default) ortui_setup::run_full_tui_setup()(--tui);setup --tuiwithout thetuifeature prints a clean message.crates/memayu-identity/src/lib.rs: exposescreate_admin_account,resolve_self_hosted_account_id,backfill_placeholder_memories(bootstrap shared with the webPOST /api/auth/setuppath).crates/memayu-api/src/modules/api_keys/service.rs: programmatic API-key generation so the wizard can provision the admin key locally.Migration / behavior
memayu setup+setup --tui; writes the same config shape.Tests
CI green (build 2m10s, clippy 1m19s, fmt, test 2m19s, audit 3m10s). Tests include the existing
cli.rs/doctor.rssubprocess suites + updated roundtrips against raw-mode mock embedder; setup-wizard and headless paths verified via subprocess invocation inbin/memayu/tests/.Checklist
IsTerminalonly (no syscall drift); only withwebfeature.SETUP_STEPS— CLI & TUI cannot drift.Fixes #45 #54