mover-os 4.4.1 → 4.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/install.js +260 -172
  2. package/package.json +1 -1
package/install.js CHANGED
@@ -182,7 +182,17 @@ async function printHeader(animate = IS_TTY) {
182
182
  }
183
183
  } catch {}
184
184
 
185
- ln(` ${dim(`v${VERSION}`)} ${gray("the agentic operating system for obsidian")}${infoRight ? ` ${infoRight}` : ""}`);
185
+ const pkgVer = require("./package.json").version;
186
+ ln(` ${dim(`v${pkgVer}`)} ${gray("the agentic operating system for obsidian")}${infoRight ? ` ${infoRight}` : ""}`);
187
+
188
+ // Non-blocking update check
189
+ try {
190
+ const latest = execSync("npm view mover-os version", { encoding: "utf8", timeout: 5000 }).trim();
191
+ if (latest && latest !== pkgVer && compareVersions(latest, pkgVer) > 0) {
192
+ ln(` ${yellow(`Update available: v${pkgVer} → v${latest}`)} ${dim(`run ${bold("moveros update")}`)}`);
193
+ }
194
+ } catch {}
195
+
186
196
  ln();
187
197
  ln(gray(" ─────────────────────────────────────────────"));
188
198
  ln();
@@ -343,7 +353,16 @@ function textInput({ label = "", initial = "", mask = null, placeholder = "" })
343
353
  value = value.slice(0, pos) + value.slice(pos + 1);
344
354
  }
345
355
  }
346
- else if (data.startsWith("\x1b")) { /* ignore escape sequences */ }
356
+ else if (data === "\x1b") {
357
+ // Escape — cancel input
358
+ stdin.removeListener("data", handler);
359
+ stdin.setRawMode(false);
360
+ stdin.pause();
361
+ ln();
362
+ resolve(null);
363
+ return;
364
+ }
365
+ else if (data.startsWith("\x1b")) { /* ignore other escape sequences */ }
347
366
  else {
348
367
  for (const ch of data) {
349
368
  if (ch.charCodeAt(0) >= 32) {
@@ -3024,6 +3043,7 @@ async function cmdCapture(opts) {
3024
3043
  if (!type) return;
3025
3044
  }
3026
3045
  content = await textInput({ label: `Enter ${type}:` });
3046
+ if (content === null) return;
3027
3047
  }
3028
3048
  if (!type) type = "task";
3029
3049
 
@@ -3536,7 +3556,9 @@ async function cmdPrayer(opts) {
3536
3556
  if (choice === "fetch") {
3537
3557
  barLn();
3538
3558
  const city = await textInput({ label: "City", placeholder: "London" });
3559
+ if (city === null) return;
3539
3560
  const country = await textInput({ label: "Country", placeholder: "United Kingdom" });
3561
+ if (country === null) return;
3540
3562
  barLn();
3541
3563
 
3542
3564
  if (city && country) {
@@ -3562,7 +3584,7 @@ async function cmdPrayer(opts) {
3562
3584
  barLn(dim(" Format examples:"));
3563
3585
  barLn(dim(" 2026-03-08 05:20 13:00 16:15 18:01 19:45"));
3564
3586
  barLn(dim(" March 8: Fajr 05:20, Dhuhr 13:00, Asr 16:15, Maghrib 18:01, Isha 19:45"));
3565
- barLn(dim(" Type 'done' on a new line when finished."));
3587
+ barLn(dim(" Type 'done' or press Enter on empty line to finish. 'back' to cancel."));
3566
3588
  barLn();
3567
3589
 
3568
3590
  const lines = [];
@@ -3570,7 +3592,14 @@ async function cmdPrayer(opts) {
3570
3592
  await new Promise((resolve) => {
3571
3593
  const ask = () => {
3572
3594
  rl.question(`${BAR_COLOR}\u2502${S.reset} `, (line) => {
3573
- if (line.trim().toLowerCase() === "done" || line.trim() === "") {
3595
+ const t = line.trim().toLowerCase();
3596
+ if (t === "done" || t === "") {
3597
+ rl.close();
3598
+ resolve();
3599
+ return;
3600
+ }
3601
+ if (t === "back" || t === "cancel") {
3602
+ lines.length = 0; // clear
3574
3603
  rl.close();
3575
3604
  resolve();
3576
3605
  return;
@@ -3828,230 +3857,270 @@ async function cmdRestore(opts) {
3828
3857
 
3829
3858
  // ─── moveros help ──────────────────────────────────────────────────────────
3830
3859
  async function cmdHelp(opts) {
3831
- // Interactive animated guide — paginated walkthrough of Mover OS
3860
+ // Animated typing helper
3861
+ const typeOut = async (text, speed = 12) => {
3862
+ if (!IS_TTY) { ln(text); return; }
3863
+ const raw = strip(text);
3864
+ let rawIdx = 0, ansiIdx = 0;
3865
+ // Build mapping of raw char positions to the styled string slices
3866
+ while (rawIdx < raw.length) {
3867
+ w(text[ansiIdx] || "");
3868
+ if (text[ansiIdx] && text[ansiIdx] !== "\x1b" && !text.slice(Math.max(0, ansiIdx - 10), ansiIdx).match(/\x1b\[[^m]*$/)) {
3869
+ rawIdx++;
3870
+ }
3871
+ ansiIdx++;
3872
+ if (rawIdx % 2 === 0) await sleep(speed);
3873
+ }
3874
+ // flush remaining ANSI codes
3875
+ while (ansiIdx < text.length) { w(text[ansiIdx]); ansiIdx++; }
3876
+ w("\n");
3877
+ };
3878
+
3879
+ const typeLine = async (text, speed = 8) => {
3880
+ if (!IS_TTY) { ln(` ${text}`); return; }
3881
+ w(" ");
3882
+ for (let i = 0; i < text.length; i++) {
3883
+ w(text[i]);
3884
+ if (text[i] !== "\x1b" && i % 3 === 0) await sleep(speed);
3885
+ }
3886
+ w("\n");
3887
+ };
3888
+
3832
3889
  const pages = [
3833
3890
  {
3834
- title: "Welcome to Mover OS",
3891
+ title: "What is Mover OS?",
3835
3892
  body: [
3836
- `${bold("The agentic operating system for Obsidian.")}`,
3893
+ `${bold("Your second brain, but it actually works.")}`,
3894
+ "",
3895
+ "Most productivity systems fail because you have to maintain them.",
3896
+ "Mover OS is different — your AI agents maintain it for you.",
3837
3897
  "",
3838
- "Mover OS turns your Obsidian vault into an AI-powered execution engine.",
3839
- "It works across 16 AI coding agents — Claude Code, Cursor, Gemini,",
3840
- "Copilot, Codex, and more. Same brain, every editor.",
3898
+ "You tell your AI who you are, what you're building, and where",
3899
+ "you're going. It remembers across every session, every editor.",
3841
3900
  "",
3842
- `${dim("How it works:")}`,
3843
- ` ${cyan("1.")} Your ${bold("Engine")} stores who you are identity, strategy, goals`,
3844
- ` ${cyan("2.")} ${bold("Workflows")} run your day plan, execute, log, analyse, repeat`,
3845
- ` ${cyan("3.")} ${bold("Skills")} give your AI agents deep domain knowledge`,
3846
- ` ${cyan("4.")} The system ${bold("learns")} from your behavior and adapts`,
3901
+ `${dim("Three things make it work:")}`,
3902
+ ` ${cyan("1.")} The ${bold("Engine")} files that store your identity, strategy, goals`,
3903
+ ` ${cyan("2.")} ${bold("Workflows")} — 23 commands that run your day (plan, build, log, repeat)`,
3904
+ ` ${cyan("3.")} ${bold("Skills")} 61 packs that make your AI genuinely useful`,
3847
3905
  "",
3848
- `${dim("This guide walks through everything. Use to navigate.")}`,
3906
+ `Works across 16 agents. Claude Code, Cursor, Gemini, all of them.`,
3907
+ `Same context, every editor. ${dim("Press → to continue.")}`,
3849
3908
  ],
3850
3909
  },
3851
3910
  {
3852
- title: "The Engine — Your Brain",
3911
+ title: "The Engine",
3853
3912
  body: [
3854
- `${dim("Location:")} 02_Areas/Engine/`,
3913
+ `${dim("Your identity, stored as markdown. Read by every AI session.")}`,
3855
3914
  "",
3856
- `${bold("Core files that define you:")}`,
3915
+ ` ${cyan("Identity_Prime.md")} Who you are values, strengths, anti-patterns`,
3916
+ ` ${cyan("Strategy.md")} What you're betting on right now`,
3917
+ ` ${cyan("Active_Context.md")} What's happening today — focus, blockers, energy`,
3918
+ ` ${cyan("Goals.md")} Where you're heading — 90 days to 10 years`,
3919
+ ` ${cyan("Mover_Dossier.md")} What you've got — skills, audience, assets`,
3920
+ ` ${cyan("Auto_Learnings.md")} What the AI has noticed about your behavior`,
3857
3921
  "",
3858
- ` ${cyan("Identity_Prime.md")} Who you are values, psychology, anti-identity`,
3859
- ` ${cyan("Strategy.md")} What you're testing current hypothesis`,
3860
- ` ${cyan("Active_Context.md")} What's happening NOW — blockers, focus, state`,
3861
- ` ${cyan("Goals.md")} Where you're going — 90d, 1yr, 10yr targets`,
3862
- ` ${cyan("Mover_Dossier.md")} What you have — skills, capital, network`,
3863
- ` ${cyan("Auto_Learnings.md")} What the AI notices — behavioral patterns`,
3922
+ "These files are yours. The system never overwrites them.",
3923
+ "Every workflow reads them. They evolve as you do.",
3864
3924
  "",
3865
- `These files are ${bold("irreplaceable")}. The system never overwrites them.`,
3866
- "Every AI session reads them. Every workflow updates them.",
3867
- `Your Engine ${bold("evolves")} as you do.`,
3925
+ `${dim("Location:")} 02_Areas/Engine/`,
3868
3926
  ],
3869
3927
  },
3870
3928
  {
3871
- title: "Daily Rhythm — The Loop",
3929
+ title: "Your Daily Loop",
3872
3930
  body: [
3873
- `${bold("The daily execution cycle:")}`,
3931
+ `${dim("The rhythm that makes it stick:")}`,
3874
3932
  "",
3875
- ` ${green("→")} ${bold("/morning")} Start your day energy check, set focus`,
3876
- ` ${green("→")} ${bold("[WORK]")} Build, ship, create`,
3877
- ` ${green("→")} ${bold("/log")} Capture what happened syncs plan + state`,
3878
- ` ${green("→")} ${bold("/analyse-day")} Brutal daily audit patterns + verdict`,
3879
- ` ${green("→")} ${bold("/plan-tomorrow")} Generate tomorrow's battle plan`,
3933
+ ` ${green("→")} ${bold("/morning")} Check in. Set your one thing for the day.`,
3934
+ ` ${green("→")} ${bold("[WORK]")} Build, ship, create.`,
3935
+ ` ${green("→")} ${bold("/log")} Capture what happened. Plan syncs automatically.`,
3936
+ ` ${green("→")} ${bold("/analyse-day")} Honest audit. What worked, what didn't.`,
3937
+ ` ${green("→")} ${bold("/plan-tomorrow")} Set up tomorrow before you close the laptop.`,
3880
3938
  "",
3881
- `${dim("Weekly:")}`,
3882
- ` ${green("→")} ${bold("/review-week")} Sunday deep review + strategy validation`,
3939
+ ` ${dim("Sundays:")} ${bold("/review-week")} — zoom out, validate strategy, clean the system.`,
3883
3940
  "",
3884
- `${dim("The rhythm is the system.")} Miss a day, patterns detect it.`,
3885
- "Miss three, /reboot triggers recovery protocol.",
3886
- `Every workflow hands off to the next — ${bold("no dead ends")}.`,
3941
+ "Miss a day, the system notices. Miss three, /reboot kicks in.",
3942
+ "Each workflow hands off to the next. No dead ends.",
3887
3943
  ],
3888
3944
  },
3889
3945
  {
3890
- title: "Workflows — 23 Commands",
3946
+ title: "23 Workflows",
3891
3947
  body: [
3892
- `${bold("Daily:")} /morning /log /analyse-day /plan-tomorrow /review-week`,
3893
- `${bold("Build:")} /ignite /overview /refactor-plan /capture /debrief`,
3894
- `${bold("Think:")} /debug-resistance /pivot-strategy /mover-ideas /screenshot`,
3895
- `${bold("Grow:")} /harvest /history /reboot`,
3896
- `${bold("Meta:")} /setup /update /walkthrough /migrate /mover-check /mover-report`,
3948
+ `${dim("Slash commands inside your AI agent. Type / and go.")}`,
3897
3949
  "",
3898
- `${dim("Key concepts:")}`,
3899
- ` ${cyan("")} ${bold("/ignite")} creates projects — brief + plan in one workflow`,
3900
- ` ${cyan("")} ${bold("/debug-resistance")} diagnoses WHY you're avoiding something`,
3901
- ` ${cyan("")} ${bold("/pivot-strategy")} formally changes direction with logging`,
3902
- ` ${cyan("")} ${bold("/harvest")} extracts permanent knowledge to your Library`,
3903
- ` ${cyan("•")} ${bold("/screenshot")} does meta-analysis of your AI session patterns`,
3950
+ `${bold("Daily:")} /morning /log /analyse-day /plan-tomorrow /review-week`,
3951
+ `${bold("Projects:")} /ignite /overview /refactor-plan /capture /debrief`,
3952
+ `${bold("Strategy:")} /debug-resistance /pivot-strategy /mover-ideas /screenshot`,
3953
+ `${bold("Growth:")} /harvest /history /reboot`,
3954
+ `${bold("System:")} /setup /update /walkthrough /migrate /mover-check`,
3904
3955
  "",
3905
- "Every command reads your Engine context and adapts to your state.",
3956
+ `${dim("Highlights:")}`,
3957
+ ` ${bold("/ignite")} Starts any project — interrogation, brief, plan`,
3958
+ ` ${bold("/debug-resistance")} Figures out WHY you're avoiding something`,
3959
+ ` ${bold("/harvest")} Turns conversations into permanent knowledge`,
3960
+ ` ${bold("/screenshot")} Meta-analysis of how you actually use AI`,
3906
3961
  ],
3907
3962
  },
3908
3963
  {
3909
- title: "Skills Domain Intelligence",
3964
+ title: "61 Skill Packs",
3910
3965
  body: [
3911
- `${bold("Skills give your AI agents specialized knowledge.")}`,
3966
+ `${dim("Specialized knowledge your AI loads automatically.")}`,
3912
3967
  "",
3913
- `${dim("Categories:")}`,
3914
- ` ${cyan("dev")} Debugging, TDD, refactoring, error handling, React`,
3915
- ` ${cyan("marketing")} Copywriting, SEO, CRO, social content, email`,
3916
- ` ${cyan("cro")} Page optimization, forms, popups, paywalls, onboarding`,
3917
- ` ${cyan("strategy")} Pricing, launch, competitors, referrals, analytics`,
3918
- ` ${cyan("seo")} Audits, schema markup, programmatic SEO, content`,
3919
- ` ${cyan("design")} UI/UX, frontend design, Obsidian markdown/canvas`,
3920
- ` ${cyan("obsidian")} JSON Canvas, Bases, Obsidian CLI, markdown`,
3968
+ ` ${cyan("dev")} TDD, debugging, refactoring, error handling, React`,
3969
+ ` ${cyan("marketing")} Copywriting, SEO, CRO, social media, email sequences`,
3970
+ ` ${cyan("strategy")} Pricing, launch strategy, competitor analysis`,
3971
+ ` ${cyan("design")} UI/UX, frontend patterns, accessibility`,
3972
+ ` ${cyan("obsidian")} Canvas, Bases, markdown, CLI automation`,
3921
3973
  "",
3922
- `${dim("System skills (always active):")}`,
3923
- ` friction-enforcer pattern-detector plan-md-guardian`,
3924
- ` mover-os-context workflow-router daily-note-writer`,
3974
+ `${dim("System skills (always watching):")}`,
3975
+ ` ${bold("friction-enforcer")} Pushes back when you drift from your plan`,
3976
+ ` ${bold("pattern-detector")} Spots recurring behavior across sessions`,
3977
+ ` ${bold("plan-md-guardian")} Protects your roadmap from corruption`,
3978
+ ` ${bold("workflow-router")} Suggests the right workflow for the moment`,
3925
3979
  "",
3926
- "Skills trigger automatically based on what you're doing.",
3980
+ "You choose categories during install. Skills activate on context.",
3927
3981
  ],
3928
3982
  },
3929
3983
  {
3930
3984
  title: "The Friction System",
3931
3985
  body: [
3932
- `${bold("Your AI pushes back when you drift from your plan.")}`,
3986
+ `${dim("Your AI has opinions. That's the point.")}`,
3933
3987
  "",
3934
- ` ${dim("Level 1")} ${cyan("Surface")} \"Your plan says X. You're working on Y.\"`,
3935
- ` ${dim("Level 2")} ${yellow("Justify")} \"Why is this more important than your Single Test?\"`,
3936
- ` ${dim("Level 3")} ${red("Earn It")} AI stops helping with off-plan work.`,
3937
- ` ${dim("Level 4")} ${red("Hard Block")} Destructive actions require explicit reason.`,
3988
+ ` ${dim("Level 1")} ${cyan("Surface")} "Your plan says X. You're doing Y. Intentional?"`,
3989
+ ` ${dim("Level 2")} ${yellow("Justify")} "Why is this more important than your Single Test?"`,
3990
+ ` ${dim("Level 3")} ${red("Earn It")} Stops helping with off-plan work entirely.`,
3991
+ ` ${dim("Level 4")} ${red("Hard Block")} Won't delete Engine files without a reason.`,
3938
3992
  "",
3939
- `You can always push through Levels 1-3. Friction creates`,
3940
- `${bold("awareness")}, not walls. But the AI won't silently comply`,
3941
- "when you're avoiding the hard thing.",
3993
+ "You can always push through. It's awareness, not a wall.",
3994
+ "But if you're avoiding the hard thing, the AI won't pretend.",
3942
3995
  "",
3943
- `${dim("Pre-Escalation Gate:")} If the work is exploration or compound`,
3944
- `value (not avoidance), it logs as ${dim("[COMPOUND]")} and doesn't escalate.`,
3996
+ `${dim("Smart gate:")} If the work is genuinely useful (compound value,`,
3997
+ `exploration), it logs ${dim("[COMPOUND]")} and doesn't escalate.`,
3945
3998
  ],
3946
3999
  },
3947
4000
  {
3948
- title: "Pattern Detection",
4001
+ title: "What is this CLI?",
3949
4002
  body: [
3950
- `${bold("The system watches your behavior across sessions.")}`,
4003
+ `${bold("Terminal utilities that don't need an AI session.")}`,
3951
4004
  "",
3952
- `${dim("How it works:")}`,
3953
- ` ${cyan("1.")} AI observes recurring behavior (3+ data points)`,
3954
- ` ${cyan("2.")} Logs to Auto_Learnings.md with confidence score (1-5)`,
3955
- ` ${cyan("3.")} Patterns surface proactively in workflows`,
3956
- ` ${cyan("4.")} You confirm or dismiss — the system adapts`,
4005
+ "Your AI agents handle the complex stuff — planning, analysis,",
4006
+ "writing. This CLI handles everything else: quick lookups, status",
4007
+ "checks, maintenance, things you want instantly.",
3957
4008
  "",
3958
- `${dim("Pattern types:")}`,
3959
- ` ${yellow("Avoidance")} Dodging specific tasks repeatedly`,
3960
- ` ${yellow("Time Drift")} Working past shutdown, skipping rest`,
3961
- ` ${yellow("System Spree")} Building tools instead of shipping`,
3962
- ` ${yellow("Scope Creep")} Tasks growing beyond plan boundaries`,
3963
- ` ${yellow("Energy Cycles")} Performance tied to sleep/food/time`,
4009
+ `${dim("How it fits together:")}`,
4010
+ ` ${cyan("Workflows")} Run inside AI agents (/morning, /log, /ignite)`,
4011
+ ` ${cyan("Skills")} Loaded by AI agents automatically`,
4012
+ ` ${cyan("CLI")} Runs in your terminal, no AI needed`,
3964
4013
  "",
3965
- `Confidence 3+ patterns route to the workflow that fixes them.`,
4014
+ "The CLI supplements your agents. It never replaces them.",
4015
+ `Think of it as ${bold("htop for your productivity")} — instant, free, always there.`,
3966
4016
  ],
3967
4017
  },
3968
4018
  {
3969
- title: "16 AI Agents One Brain",
4019
+ title: "CLI Status & Insight",
3970
4020
  body: [
3971
- `${bold("Mover OS installs to every major AI coding agent.")}`,
4021
+ `${dim("See what's happening without opening an AI session.")}`,
3972
4022
  "",
3973
- `${dim("Full tier (rules + skills + commands + hooks):")}`,
3974
- ` Claude Code Cursor Cline Windsurf Gemini CLI`,
3975
- ` Copilot Amazon Q OpenCode Kilo Code`,
4023
+ ` ${cyan("pulse")} Dashboard tasks, streaks, energy, blockers`,
4024
+ ` ${dim("Like htop for your day. One glance.")}`,
3976
4025
  "",
3977
- `${dim("Enhanced tier (rules + skills):")}`,
3978
- ` Codex Amp Roo Code Antigravity`,
4026
+ ` ${cyan("replay")} Session replay what you did, when, drift analysis`,
4027
+ ` ${dim("\"You planned 4 tasks, completed 2, drifted into 3.\"")}`,
3979
4028
  "",
3980
- `${dim("Basic tier (rules only):")}`,
3981
- ` Continue Aider`,
4029
+ ` ${cyan("diff")} Engine evolution how your strategy changed over time`,
4030
+ ` ${dim("Git-powered. Shows exactly when and why.")}`,
4031
+ "",
4032
+ ` ${cyan("context")} What each agent sees — loaded rules, skills, token count`,
4033
+ ` ${dim("Debug why an agent is behaving differently.")}`,
3982
4034
  "",
3983
- "Switch editors freely. Your identity, strategy, and patterns",
3984
- `follow you everywhere. The ${bold("Engine is the constant")}.`,
3985
- `Run ${cyan("moveros sync")} to update all agents at once.`,
4035
+ ` ${cyan("doctor")} Health check are all agents configured correctly?`,
3986
4036
  ],
3987
4037
  },
3988
4038
  {
3989
- title: "CLI Commands",
4039
+ title: "CLI — Quick Actions",
3990
4040
  body: [
3991
- `${bold("Terminal utilities no AI session needed.")}`,
4041
+ `${dim("Do things fast without starting a session.")}`,
3992
4042
  "",
3993
- ` ${cyan("moveros pulse")} Dashboardenergy, tasks, streaks, blockers`,
3994
- ` ${cyan("moveros doctor")} Health check across all installed agents`,
3995
- ` ${cyan("moveros capture")} Quick capture — tasks, links, ideas from terminal`,
3996
- ` ${cyan("moveros who")} Entity memory lookup — people, orgs, places`,
3997
- ` ${cyan("moveros sync")} Update all agents to latest rules/skills`,
3998
- ` ${cyan("moveros context")} See what each agent loads — rules, skills, tokens`,
3999
- ` ${cyan("moveros diff")} Engine file evolution via git history`,
4000
- ` ${cyan("moveros replay")} Session replay from Daily Notes`,
4001
- ` ${cyan("moveros settings")} View/edit config — ${dim("settings set <key> <val>")}`,
4002
- ` ${cyan("moveros backup")} Manual backup wizard (engine, areas, agents)`,
4003
- ` ${cyan("moveros restore")} Restore from backup`,
4004
- ` ${cyan("moveros warm")} Pre-warm an AI session with context`,
4043
+ ` ${cyan("capture")} Quick capture task, idea, link, brain dump`,
4044
+ ` ${dim("moveros capture --task \"Fix the login bug\"")}`,
4045
+ "",
4046
+ ` ${cyan("who")} Entity lookup — search People, Orgs, Places`,
4047
+ ` ${dim("moveros who \"Ishaaq\" everything you know about them")}`,
4048
+ "",
4049
+ ` ${cyan("warm")} Pre-warm an AI session with fresh context`,
4050
+ ` ${dim("Run before opening Claude/Cursor. Eliminates cold start.")}`,
4051
+ "",
4052
+ ` ${cyan("prayer")} Mosque timetable next prayer in your status line`,
4053
+ ` ${dim("Paste or fetch. Shows countdown. Optional.")}`,
4005
4054
  ],
4006
4055
  },
4007
4056
  {
4008
- title: "The Status Line",
4057
+ title: "CLI Maintenance",
4009
4058
  body: [
4010
- `${bold("Your life, glanceable. Always visible in Claude Code.")}`,
4059
+ `${dim("Keep everything in sync without thinking about it.")}`,
4060
+ "",
4061
+ ` ${cyan("sync")} Update all agents to latest rules and skills`,
4062
+ ` ${dim("One command updates 16 agents. Shows what changed.")}`,
4063
+ "",
4064
+ ` ${cyan("backup")} Backup Engine, Areas, or agent configs`,
4065
+ ` ${dim("With manifest. Knows what's in each backup.")}`,
4066
+ "",
4067
+ ` ${cyan("restore")} Restore from any backup — selective, safe`,
4068
+ ` ${dim("Creates a safety backup before restoring.")}`,
4069
+ "",
4070
+ ` ${cyan("settings")} View/edit config from terminal`,
4071
+ ` ${dim("moveros settings set review_day sunday")}`,
4072
+ "",
4073
+ ` ${cyan("update")} Update CLI + workflows + skills in one go`,
4074
+ ` ${dim("Self-updates the CLI, then pulls latest payload.")}`,
4075
+ ],
4076
+ },
4077
+ {
4078
+ title: "16 Agents, One Brain",
4079
+ body: [
4080
+ `${dim("Install once. Every agent gets the same context.")}`,
4081
+ "",
4082
+ `${dim("Full tier")} ${dim("(rules + skills + commands + hooks):")}`,
4083
+ ` Claude Code Cursor Cline Windsurf Gemini CLI`,
4084
+ ` Copilot Amazon Q OpenCode Kilo Code`,
4011
4085
  "",
4012
- ` ${dim("Line 1:")} Model · Context% · Project(branch) · Lines · Time · Cost`,
4013
- ` ${dim("Line 2:")} Next task · Progress · Vitality · Prayer · Last log`,
4014
- ` ${dim("Line 3:")} Rate limits (5hr + 7day + extra usage)`,
4086
+ `${dim("Enhanced tier")} ${dim("(rules + skills):")}`,
4087
+ ` Codex Amp Roo Code Antigravity`,
4015
4088
  "",
4016
- `${dim("Features:")}`,
4017
- ` ${cyan("•")} Next unchecked task from today's Daily Note`,
4018
- ` ${cyan("•")} Strategic task count (vitality excluded)`,
4019
- ` ${cyan("•")} Vitality slot machine — rotates reminders every minute`,
4020
- ` ${cyan("•")} Next prayer time (if ${dim("show_prayer_times: true")} in settings)`,
4021
- ` ${cyan("•")} Time since last /log — so you never forget`,
4022
- ` ${cyan("•")} Rate limit bars with reset times`,
4089
+ `${dim("Basic tier")} ${dim("(rules only):")}`,
4090
+ ` Continue Aider`,
4023
4091
  "",
4024
- `All data from your vault. ${bold("No API calls")} except rate limits.`,
4092
+ "Switch editors whenever. Your Engine follows you.",
4093
+ `${cyan("moveros sync")} keeps them all current.`,
4025
4094
  ],
4026
4095
  },
4027
4096
  {
4028
- title: "Getting Started",
4097
+ title: "Get Started",
4029
4098
  body: [
4030
- `${bold("You're ready.")}`,
4099
+ `${bold("Five minutes to a system that remembers everything.")}`,
4031
4100
  "",
4032
- ` ${cyan("1.")} Run ${bold("/setup")} in any AI agent to build your Engine`,
4101
+ ` ${cyan("1.")} Run ${bold("/setup")} in your AI agent it'll interview you`,
4033
4102
  ` ${cyan("2.")} Run ${bold("/morning")} to start your first session`,
4034
4103
  ` ${cyan("3.")} Work. Build. Ship.`,
4035
- ` ${cyan("4.")} Run ${bold("/log")} to capture what happened`,
4104
+ ` ${cyan("4.")} Run ${bold("/log")} when you're done — captures everything`,
4036
4105
  ` ${cyan("5.")} Run ${bold("/plan-tomorrow")} before bed`,
4037
4106
  "",
4038
- `${dim("Quick tips:")}`,
4039
- ` ${cyan("•")} ${bold("Single Test")} — one thing that makes the day a win`,
4040
- ` ${cyan("•")} ${bold("Sacrifice")} — what you won't do today (as important as what you will)`,
4041
- ` ${cyan("•")} The system gets smarter the more you use it`,
4042
- ` ${cyan("•")} Trust the Engine files — they're your memory between sessions`,
4107
+ `${dim("Two things to know:")}`,
4108
+ ` ${bold("Single Test")} the one thing that makes today a win`,
4109
+ ` ${bold("Sacrifice")} — what you won't do (just as important)`,
4043
4110
  "",
4044
- `${dim("moveros.dev")} ${dim("·")} ${dim("$49 one-time")} ${dim("·")} ${dim("updates included")}`,
4111
+ "The system learns from you. The more you use it, the sharper it gets.",
4112
+ "",
4113
+ `${dim("moveros.dev")}`,
4045
4114
  ],
4046
4115
  },
4047
4116
  ];
4048
4117
 
4049
4118
  // Paginated display with keyboard navigation
4050
4119
  let page = 0;
4120
+ const seen = new Set();
4051
4121
 
4052
- function renderPage() {
4122
+ async function renderPage(animate) {
4053
4123
  const p = pages[page];
4054
- // Clear screen area
4055
4124
  w("\x1b[2J\x1b[H"); // clear screen, cursor to top
4056
4125
  ln();
4057
4126
 
@@ -4067,9 +4136,14 @@ async function cmdHelp(opts) {
4067
4136
  ln(` ${S.cyan}└${"─".repeat(56)}┘${S.reset}`);
4068
4137
  ln();
4069
4138
 
4070
- // Body
4071
- for (const line of p.body) {
4072
- ln(` ${line}`);
4139
+ // Body — animate on first visit, instant on revisit
4140
+ if (animate && !seen.has(page)) {
4141
+ for (const line of p.body) {
4142
+ await typeLine(line, 6);
4143
+ }
4144
+ seen.add(page);
4145
+ } else {
4146
+ for (const line of p.body) ln(` ${line}`);
4073
4147
  }
4074
4148
  ln();
4075
4149
  ln();
@@ -4084,7 +4158,6 @@ async function cmdHelp(opts) {
4084
4158
 
4085
4159
  return new Promise((resolve) => {
4086
4160
  if (!IS_TTY) {
4087
- // Non-interactive: dump all pages
4088
4161
  for (const p of pages) {
4089
4162
  ln(bold(`\n## ${p.title}\n`));
4090
4163
  for (const line of p.body) ln(` ${line}`);
@@ -4099,22 +4172,32 @@ async function cmdHelp(opts) {
4099
4172
  stdin.setEncoding("utf8");
4100
4173
  w(S.hide);
4101
4174
 
4102
- renderPage();
4175
+ let navigating = false;
4176
+ const go = async (newPage) => {
4177
+ if (navigating) return;
4178
+ navigating = true;
4179
+ page = newPage;
4180
+ await renderPage(true);
4181
+ navigating = false;
4182
+ };
4183
+
4184
+ go(0); // initial render with animation
4103
4185
 
4104
4186
  const handler = (data) => {
4187
+ if (navigating) return; // ignore input during animation
4105
4188
  if (data === "\x1b[C" || data === "l" || data === " ") {
4106
- if (page < pages.length - 1) { page++; renderPage(); }
4189
+ if (page < pages.length - 1) go(page + 1);
4107
4190
  } else if (data === "\x1b[D" || data === "h") {
4108
- if (page > 0) { page--; renderPage(); }
4191
+ if (page > 0) go(page - 1);
4109
4192
  } else if (data === "q" || data === "\x1b" || data === "\x03") {
4110
4193
  stdin.removeListener("data", handler);
4111
4194
  stdin.setRawMode(false);
4112
4195
  stdin.pause();
4113
4196
  w(S.show);
4114
- w("\x1b[2J\x1b[H"); // clear
4197
+ w("\x1b[2J\x1b[H");
4115
4198
  resolve();
4116
4199
  } else if (data === "\r" || data === "\n") {
4117
- if (page < pages.length - 1) { page++; renderPage(); }
4200
+ if (page < pages.length - 1) go(page + 1);
4118
4201
  else {
4119
4202
  stdin.removeListener("data", handler);
4120
4203
  stdin.setRawMode(false);
@@ -4135,27 +4218,20 @@ async function cmdTest(opts) { barLn(yellow("moveros test — not yet implemente
4135
4218
 
4136
4219
  // ─── Interactive Main Menu ────────────────────────────────────────────────────
4137
4220
  async function cmdMainMenu() {
4138
- const categories = [
4139
- { header: "Setup", cmds: ["install", "update"] },
4140
- { header: "Dashboard", cmds: ["pulse", "replay", "diff"] },
4141
- { header: "Agents", cmds: ["doctor", "sync", "context", "warm"] },
4142
- { header: "Capture", cmds: ["capture", "who"] },
4143
- { header: "System", cmds: ["settings", "prayer", "backup", "restore", "help"] },
4221
+ const menuOrder = [
4222
+ "install", "update",
4223
+ "pulse", "replay", "diff",
4224
+ "doctor", "sync", "context", "warm",
4225
+ "capture", "who",
4226
+ "settings", "prayer", "backup", "restore", "help",
4144
4227
  ];
4145
4228
 
4146
- const menuItems = [];
4147
- for (const cat of categories) {
4148
- menuItems.push({ id: `_sep_${cat.header}`, name: `── ${cat.header}`, _separator: true });
4149
- for (const cmd of cat.cmds) {
4150
- const meta = CLI_COMMANDS[cmd];
4151
- if (!meta || meta.hidden) continue;
4152
- menuItems.push({
4153
- id: cmd,
4154
- name: `${cmd.padEnd(12)} ${dim(meta.desc)}`,
4155
- tier: `${cat.header}`,
4156
- });
4157
- }
4158
- }
4229
+ const menuItems = menuOrder
4230
+ .filter(cmd => { const m = CLI_COMMANDS[cmd]; return m && !m.hidden; })
4231
+ .map(cmd => ({
4232
+ id: cmd,
4233
+ name: `${cmd.padEnd(12)} ${dim(CLI_COMMANDS[cmd].desc)}`,
4234
+ }));
4159
4235
 
4160
4236
  question(`${bold("moveros")} ${dim("— choose a command")}`);
4161
4237
  barLn();
@@ -4410,6 +4486,7 @@ async function main() {
4410
4486
  mask: "\u25AA",
4411
4487
  placeholder: "MOVER-XXXX-XXXX",
4412
4488
  });
4489
+ if (key === null) return;
4413
4490
 
4414
4491
  const sp = spinner("Validating...");
4415
4492
  const valid = await validateKey(key);
@@ -4503,6 +4580,7 @@ async function main() {
4503
4580
  label: "Where is your Obsidian vault?",
4504
4581
  initial: path.join(os.homedir(), "Mover-OS"),
4505
4582
  });
4583
+ if (vaultPath === null) return;
4506
4584
  } else {
4507
4585
  vaultPath = selected;
4508
4586
  }
@@ -4511,6 +4589,7 @@ async function main() {
4511
4589
  label: "Where is your Obsidian vault?",
4512
4590
  initial: path.join(os.homedir(), "Mover-OS"),
4513
4591
  });
4592
+ if (vaultPath === null) return;
4514
4593
  }
4515
4594
  } else {
4516
4595
  barLn(dim(`Vault: ${vaultPath}`));
@@ -4958,7 +5037,7 @@ async function main() {
4958
5037
  barLn(dim(" 2026-03-08 05:20 13:00 16:15 18:01 19:45"));
4959
5038
  barLn(dim(" March 8: Fajr 05:20, Dhuhr 13:00, Asr 16:15, Maghrib 18:01, Isha 19:45"));
4960
5039
  barLn(dim(" Or paste a whole table — the system will parse it."));
4961
- barLn(dim(" When done, type 'done' on a new line and press Enter."));
5040
+ barLn(dim(" Type 'done' or press Enter on empty line to finish. 'back' to cancel."));
4962
5041
  barLn();
4963
5042
 
4964
5043
  const lines = [];
@@ -4966,7 +5045,14 @@ async function main() {
4966
5045
  await new Promise((resolve) => {
4967
5046
  const ask = () => {
4968
5047
  rl.question(`${BAR_COLOR}\u2502${S.reset} `, (line) => {
4969
- if (line.trim().toLowerCase() === "done" || line.trim() === "") {
5048
+ const t = line.trim().toLowerCase();
5049
+ if (t === "done" || t === "") {
5050
+ rl.close();
5051
+ resolve();
5052
+ return;
5053
+ }
5054
+ if (t === "back" || t === "cancel") {
5055
+ lines.length = 0;
4970
5056
  rl.close();
4971
5057
  resolve();
4972
5058
  return;
@@ -4991,7 +5077,9 @@ async function main() {
4991
5077
  } else if (method === "fetch") {
4992
5078
  barLn();
4993
5079
  const city = await textInput({ label: "City (e.g. London, Watford, Istanbul)", placeholder: "London" });
5080
+ if (city === null) return;
4994
5081
  const country = await textInput({ label: "Country", placeholder: "United Kingdom" });
5082
+ if (country === null) return;
4995
5083
  barLn();
4996
5084
 
4997
5085
  if (city && country) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mover-os",
3
- "version": "4.4.1",
3
+ "version": "4.4.3",
4
4
  "description": "The self-improving OS for AI agents. Turns Obsidian into an execution engine.",
5
5
  "bin": {
6
6
  "moveros": "install.js"