mover-os 4.0.9 → 4.0.11

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.

Potentially problematic release.


This version of mover-os might be problematic. Click here for more details.

package/install.js CHANGED
@@ -251,7 +251,7 @@ function interactiveSelect(items, { multi = false, preSelected = [], defaultInde
251
251
  let tierLabel = "";
252
252
  if (item.tier === "Full") tierLabel = `${S.green}Full${S.reset}`;
253
253
  else if (item.tier === "Enhanced") tierLabel = `${S.cyan}Enhanced${S.reset}`;
254
- else if (item.tier === "Basic+" || item.tier === "Basic") tierLabel = `${S.gray}${item.tier}${S.reset}`;
254
+ else if (item.tier === "Basic") tierLabel = `${S.gray}Basic${S.reset}`;
255
255
  else if (item.tier === "recommended") tierLabel = `${S.green}recommended${S.reset}`;
256
256
  else if (item.tier) tierLabel = dim(item.tier);
257
257
 
@@ -397,6 +397,9 @@ async function runUninstall(vaultPath) {
397
397
  { label: "Antigravity rules", path: path.join(home, ".gemini", "GEMINI.md") },
398
398
  { label: "Antigravity workflows", path: path.join(home, ".gemini", "antigravity", "global_workflows"), dir: true },
399
399
  { label: "Codex instructions", path: path.join(home, ".codex", "instructions.md") },
400
+ { label: "Codex skills", path: path.join(home, ".codex", "skills"), dir: true },
401
+ { label: "Windsurf skills", path: path.join(home, ".windsurf", "skills"), dir: true },
402
+ { label: "Antigravity skills", path: path.join(home, ".gemini", "antigravity", "skills"), dir: true },
400
403
  { label: "Claude Code hooks", path: path.join(home, ".claude", "hooks"), dir: true },
401
404
  ];
402
405
 
@@ -466,6 +469,7 @@ async function runUninstall(vaultPath) {
466
469
 
467
470
  // ─── Agent definitions ──────────────────────────────────────────────────────
468
471
  const AGENTS = [
472
+ // ── Full (rules + skills + commands/workflows + hooks) ──
469
473
  {
470
474
  id: "claude-code",
471
475
  name: "Claude Code",
@@ -484,54 +488,62 @@ const AGENTS = [
484
488
  tier: "Full",
485
489
  detect: () => globDirExists(path.join(os.homedir(), ".vscode", "extensions"), "saoudrizwan.claude-dev-*"),
486
490
  },
487
- {
488
- id: "codex",
489
- name: "Codex CLI",
490
- tier: "Enhanced",
491
- detect: () => cmdExists("codex") || fs.existsSync(path.join(os.homedir(), ".codex")),
492
- },
493
491
  {
494
492
  id: "windsurf",
495
493
  name: "Windsurf",
496
- tier: "Enhanced",
494
+ tier: "Full",
497
495
  detect: () => fs.existsSync(path.join(os.homedir(), ".windsurf")) || cmdExists("windsurf"),
498
496
  },
499
497
  {
500
- id: "openclaw",
501
- name: "OpenClaw",
498
+ id: "gemini-cli",
499
+ name: "Gemini CLI",
500
+ tier: "Full",
501
+ detect: () => cmdExists("gemini") || fs.existsSync(path.join(os.homedir(), ".gemini", "settings.json")),
502
+ },
503
+ {
504
+ id: "copilot",
505
+ name: "GitHub Copilot",
506
+ tier: "Full",
507
+ detect: () => cmdExists("gh"),
508
+ },
509
+ // ── Enhanced (rules + skills) ──
510
+ {
511
+ id: "codex-cli",
512
+ name: "Codex CLI",
502
513
  tier: "Enhanced",
503
- detect: () => fs.existsSync(path.join(os.homedir(), ".openclaw")) || cmdExists("openclaw"),
514
+ detect: () => cmdExists("codex") || fs.existsSync(path.join(os.homedir(), ".codex")),
504
515
  },
505
516
  {
506
- id: "gemini-cli",
507
- name: "Gemini CLI",
517
+ id: "codex-cloud",
518
+ name: "Codex (Cloud)",
508
519
  tier: "Enhanced",
509
- detect: () => cmdExists("gemini") || fs.existsSync(path.join(os.homedir(), ".gemini", "settings.json")),
520
+ detect: () => false, // Browser-based no local detection possible
510
521
  },
511
522
  {
512
523
  id: "antigravity",
513
524
  name: "Antigravity",
514
- tier: "Basic+",
525
+ tier: "Enhanced",
515
526
  detect: () => fs.existsSync(path.join(os.homedir(), ".gemini", "antigravity")),
516
527
  },
528
+ {
529
+ id: "openclaw",
530
+ name: "OpenClaw",
531
+ tier: "Enhanced",
532
+ detect: () => fs.existsSync(path.join(os.homedir(), ".openclaw")) || cmdExists("openclaw"),
533
+ },
517
534
  {
518
535
  id: "roo-code",
519
536
  name: "Roo Code",
520
- tier: "Basic",
537
+ tier: "Enhanced",
521
538
  detect: () => globDirExists(path.join(os.homedir(), ".vscode", "extensions"), "rooveterinaryinc.roo-cline-*"),
522
539
  },
523
- {
524
- id: "copilot",
525
- name: "GitHub Copilot",
526
- tier: "Basic",
527
- detect: () => cmdExists("gh"),
528
- },
529
540
  {
530
541
  id: "amp",
531
542
  name: "Amp",
532
- tier: "Basic",
543
+ tier: "Enhanced",
533
544
  detect: () => cmdExists("amp") || fs.existsSync(path.join(os.homedir(), ".amp")),
534
545
  },
546
+ // ── Basic (rules only) ──
535
547
  {
536
548
  id: "aider",
537
549
  name: "Aider",
@@ -589,6 +601,72 @@ function copyDirRecursive(src, dest) {
589
601
  }
590
602
  }
591
603
 
604
+ // ─── Skill categories (maps skill folder name → category) ───────────────────
605
+ const SKILL_CATEGORIES = {
606
+ // Development
607
+ "agent-code-reviewer": "development",
608
+ "agent-security-auditor": "development",
609
+ "systematic-debugging": "development",
610
+ "find-bugs": "development",
611
+ "refactoring": "development",
612
+ "react-best-practices": "development",
613
+ "webhook-handler-patterns": "development",
614
+ // Marketing
615
+ "copywriting": "marketing",
616
+ "copy-editing": "marketing",
617
+ "seo-audit": "marketing",
618
+ "seo-content-writer": "marketing",
619
+ "social-content": "marketing",
620
+ "email-sequence": "marketing",
621
+ "paid-ads": "marketing",
622
+ "analytics-tracking": "marketing",
623
+ "human-writer": "marketing",
624
+ "marketing-ideas": "marketing",
625
+ "marketing-psychology": "marketing",
626
+ "ab-test-setup": "marketing",
627
+ // CRO
628
+ "page-cro": "cro",
629
+ "form-cro": "cro",
630
+ "signup-flow-cro": "cro",
631
+ "onboarding-cro": "cro",
632
+ "popup-cro": "cro",
633
+ "paywall-upgrade-cro": "cro",
634
+ // Strategy
635
+ "pricing-strategy": "strategy",
636
+ "launch-strategy": "strategy",
637
+ "competitor-alternatives": "strategy",
638
+ "free-tool-strategy": "strategy",
639
+ "referral-program": "strategy",
640
+ "agent-strategy-analyst": "strategy",
641
+ "agent-research-analyst": "strategy",
642
+ "agent-content-researcher": "strategy",
643
+ // SEO
644
+ "programmatic-seo": "seo",
645
+ "schema-markup": "seo",
646
+ // Design
647
+ "frontend-design": "design",
648
+ "ui-ux-pro-max": "design",
649
+ // Obsidian
650
+ "obsidian-markdown": "obsidian",
651
+ "obsidian-bases": "obsidian",
652
+ "obsidian-cli": "obsidian",
653
+ "json-canvas": "obsidian",
654
+ // Tools (always installed — core utilities)
655
+ "defuddle": "tools",
656
+ "skill-creator": "tools",
657
+ "find-skills": "tools",
658
+ };
659
+
660
+ const CATEGORY_META = [
661
+ { id: "development", name: "Development", desc: "code review, debugging, security" },
662
+ { id: "marketing", name: "Marketing", desc: "copy, SEO, social, email, ads" },
663
+ { id: "cro", name: "CRO", desc: "page optimization, forms, popups" },
664
+ { id: "strategy", name: "Strategy", desc: "pricing, launch, competitors" },
665
+ { id: "seo", name: "SEO", desc: "programmatic SEO, schema markup" },
666
+ { id: "design", name: "Design", desc: "frontend, UI/UX" },
667
+ { id: "obsidian", name: "Obsidian", desc: "markdown, bases, canvas, CLI" },
668
+ ];
669
+
592
670
  function findSkills(bundleDir) {
593
671
  const skillsDir = path.join(bundleDir, "src", "skills");
594
672
  if (!fs.existsSync(skillsDir)) return [];
@@ -598,7 +676,7 @@ function findSkills(bundleDir) {
598
676
  const full = path.join(dir, entry.name);
599
677
  if (entry.isDirectory()) {
600
678
  if (fs.existsSync(path.join(full, "SKILL.md"))) {
601
- skills.push({ name: entry.name, path: full });
679
+ skills.push({ name: entry.name, path: full, category: SKILL_CATEGORIES[entry.name] || "tools" });
602
680
  } else {
603
681
  walk(full);
604
682
  }
@@ -832,11 +910,13 @@ function installRules(bundleDir, destPath) {
832
910
  return linkOrCopy(src, destPath) !== null;
833
911
  }
834
912
 
835
- function installSkillPacks(bundleDir, destDir) {
913
+ function installSkillPacks(bundleDir, destDir, selectedCategories) {
836
914
  const skills = findSkills(bundleDir);
837
915
  fs.mkdirSync(destDir, { recursive: true });
838
916
  let count = 0;
839
917
  for (const skill of skills) {
918
+ // Filter by category if categories were selected (tools always installed)
919
+ if (selectedCategories && skill.category !== "tools" && !selectedCategories.has(skill.category)) continue;
840
920
  const dest = path.join(destDir, skill.name);
841
921
  if (fs.existsSync(dest)) fs.rmSync(dest, { recursive: true, force: true });
842
922
  copyDirRecursive(skill.path, dest);
@@ -870,7 +950,7 @@ function installHooksForClaude(bundleDir, vaultPath) {
870
950
  }
871
951
 
872
952
  // ─── Per-agent install orchestrators ────────────────────────────────────────
873
- function installClaudeCode(bundleDir, vaultPath) {
953
+ function installClaudeCode(bundleDir, vaultPath, skillOpts) {
874
954
  const home = os.homedir();
875
955
  const steps = [];
876
956
 
@@ -882,9 +962,11 @@ function installClaudeCode(bundleDir, vaultPath) {
882
962
  const wfCount = installWorkflows(bundleDir, cmdsDir);
883
963
  if (wfCount > 0) steps.push(`${wfCount} commands`);
884
964
 
885
- const skillsDir = path.join(claudeDir, "skills");
886
- const skCount = installSkillPacks(bundleDir, skillsDir);
887
- if (skCount > 0) steps.push(`${skCount} skills`);
965
+ if (skillOpts && skillOpts.install) {
966
+ const skillsDir = path.join(claudeDir, "skills");
967
+ const skCount = installSkillPacks(bundleDir, skillsDir, skillOpts.categories);
968
+ if (skCount > 0) steps.push(`${skCount} skills`);
969
+ }
888
970
 
889
971
  if (vaultPath) {
890
972
  const hkCount = installHooksForClaude(bundleDir, vaultPath);
@@ -894,7 +976,7 @@ function installClaudeCode(bundleDir, vaultPath) {
894
976
  return steps;
895
977
  }
896
978
 
897
- function installCursor(bundleDir, vaultPath) {
979
+ function installCursor(bundleDir, vaultPath, skillOpts) {
898
980
  const home = os.homedir();
899
981
  const steps = [];
900
982
 
@@ -913,14 +995,16 @@ function installCursor(bundleDir, vaultPath) {
913
995
  const wfCount = installWorkflows(bundleDir, cmdsDir);
914
996
  if (wfCount > 0) steps.push(`${wfCount} commands`);
915
997
 
916
- const skillsDir = path.join(home, ".cursor", "skills");
917
- const skCount = installSkillPacks(bundleDir, skillsDir);
918
- if (skCount > 0) steps.push(`${skCount} skills`);
998
+ if (skillOpts && skillOpts.install) {
999
+ const skillsDir = path.join(home, ".cursor", "skills");
1000
+ const skCount = installSkillPacks(bundleDir, skillsDir, skillOpts.categories);
1001
+ if (skCount > 0) steps.push(`${skCount} skills`);
1002
+ }
919
1003
 
920
1004
  return steps;
921
1005
  }
922
1006
 
923
- function installCline(bundleDir, vaultPath) {
1007
+ function installCline(bundleDir, vaultPath, skillOpts) {
924
1008
  const steps = [];
925
1009
 
926
1010
  if (vaultPath) {
@@ -932,39 +1016,62 @@ function installCline(bundleDir, vaultPath) {
932
1016
  steps.push("rules");
933
1017
  }
934
1018
 
935
- const skillsDir = path.join(vaultPath, ".cline", "skills");
936
- const skCount = installSkillPacks(bundleDir, skillsDir);
937
- if (skCount > 0) steps.push(`${skCount} skills`);
1019
+ if (skillOpts && skillOpts.install) {
1020
+ const skillsDir = path.join(vaultPath, ".cline", "skills");
1021
+ const skCount = installSkillPacks(bundleDir, skillsDir, skillOpts.categories);
1022
+ if (skCount > 0) steps.push(`${skCount} skills`);
1023
+ }
938
1024
  }
939
1025
 
940
1026
  return steps;
941
1027
  }
942
1028
 
943
- function installCodex(bundleDir, vaultPath) {
1029
+ function installCodexCli(bundleDir, vaultPath, skillOpts) {
944
1030
  const home = os.homedir();
945
1031
  const steps = [];
946
1032
 
947
- if (vaultPath) {
948
- fs.writeFileSync(path.join(vaultPath, "AGENTS.md"), generateAgentsMd(), "utf8");
949
- steps.push("AGENTS.md");
950
- }
951
-
952
1033
  const codexDir = path.join(home, ".codex");
953
1034
  fs.mkdirSync(codexDir, { recursive: true });
954
1035
  if (installRules(bundleDir, path.join(codexDir, "instructions.md"))) steps.push("global instructions");
955
1036
 
1037
+ if (skillOpts && skillOpts.install) {
1038
+ const skillsDir = path.join(codexDir, "skills");
1039
+ const skCount = installSkillPacks(bundleDir, skillsDir, skillOpts.categories);
1040
+ if (skCount > 0) steps.push(`${skCount} skills`);
1041
+ }
1042
+
1043
+ return steps;
1044
+ }
1045
+
1046
+ function installCodexCloud(bundleDir, vaultPath, skillOpts) {
1047
+ const steps = [];
1048
+
1049
+ if (vaultPath && installSkills) {
1050
+ const skillsDir = path.join(vaultPath, ".agents", "skills");
1051
+ const skCount = installSkillPacks(bundleDir, skillsDir, skillOpts.categories);
1052
+ if (skCount > 0) steps.push(`${skCount} skills`);
1053
+ }
1054
+
956
1055
  return steps;
957
1056
  }
958
1057
 
959
- function installWindsurf(bundleDir, vaultPath) {
1058
+ function installWindsurf(bundleDir, vaultPath, skillOpts) {
1059
+ const home = os.homedir();
960
1060
  const steps = [];
961
1061
  if (vaultPath) {
962
1062
  if (installRules(bundleDir, path.join(vaultPath, ".windsurfrules"))) steps.push("rules");
963
1063
  }
1064
+
1065
+ if (skillOpts && skillOpts.install) {
1066
+ const skillsDir = path.join(home, ".windsurf", "skills");
1067
+ const skCount = installSkillPacks(bundleDir, skillsDir, skillOpts.categories);
1068
+ if (skCount > 0) steps.push(`${skCount} skills`);
1069
+ }
1070
+
964
1071
  return steps;
965
1072
  }
966
1073
 
967
- function installOpenClaw(bundleDir, vaultPath) {
1074
+ function installOpenClaw(bundleDir, vaultPath, skillOpts) {
968
1075
  const home = os.homedir();
969
1076
  const workspace = path.join(home, ".openclaw", "workspace");
970
1077
  const steps = [];
@@ -988,42 +1095,64 @@ function installOpenClaw(bundleDir, vaultPath) {
988
1095
  steps.push("USER.md");
989
1096
  }
990
1097
 
991
- const skCount = installSkillPacks(bundleDir, path.join(workspace, "skills"));
992
- if (skCount > 0) steps.push(`${skCount} skills`);
1098
+ if (skillOpts && skillOpts.install) {
1099
+ const skCount = installSkillPacks(bundleDir, path.join(workspace, "skills"), skillOpts.categories);
1100
+ if (skCount > 0) steps.push(`${skCount} skills`);
1101
+ }
993
1102
 
994
1103
  return steps;
995
1104
  }
996
1105
 
997
- function installGeminiCli(bundleDir) {
1106
+ function installGeminiCli(bundleDir, vaultPath, skillOpts, writtenFiles) {
998
1107
  const home = os.homedir();
999
1108
  const steps = [];
1000
1109
 
1001
1110
  const geminiDir = path.join(home, ".gemini");
1002
1111
  fs.mkdirSync(geminiDir, { recursive: true });
1003
- if (installRules(bundleDir, path.join(geminiDir, "GEMINI.md"))) steps.push("rules");
1112
+ const geminiMdPath = path.join(geminiDir, "GEMINI.md");
1113
+ if (!writtenFiles.has(geminiMdPath)) {
1114
+ if (installRules(bundleDir, geminiMdPath)) steps.push("rules");
1115
+ writtenFiles.add(geminiMdPath);
1116
+ } else {
1117
+ steps.push("rules (shared)");
1118
+ }
1004
1119
 
1005
- const skCount = installSkillPacks(bundleDir, path.join(geminiDir, "skills"));
1006
- if (skCount > 0) steps.push(`${skCount} skills`);
1120
+ if (skillOpts && skillOpts.install) {
1121
+ const skCount = installSkillPacks(bundleDir, path.join(geminiDir, "skills"), skillOpts.categories);
1122
+ if (skCount > 0) steps.push(`${skCount} skills`);
1123
+ }
1007
1124
 
1008
1125
  return steps;
1009
1126
  }
1010
1127
 
1011
- function installAntigravity(bundleDir) {
1128
+ function installAntigravity(bundleDir, vaultPath, skillOpts, writtenFiles) {
1012
1129
  const home = os.homedir();
1013
1130
  const steps = [];
1014
1131
 
1015
1132
  const geminiDir = path.join(home, ".gemini");
1016
1133
  fs.mkdirSync(geminiDir, { recursive: true });
1017
- if (installRules(bundleDir, path.join(geminiDir, "GEMINI.md"))) steps.push("rules");
1134
+ const geminiMdPath = path.join(geminiDir, "GEMINI.md");
1135
+ if (!writtenFiles.has(geminiMdPath)) {
1136
+ if (installRules(bundleDir, geminiMdPath)) steps.push("rules");
1137
+ writtenFiles.add(geminiMdPath);
1138
+ } else {
1139
+ steps.push("rules (shared)");
1140
+ }
1018
1141
 
1019
1142
  const wfDir = path.join(geminiDir, "antigravity", "global_workflows");
1020
1143
  const wfCount = installWorkflows(bundleDir, wfDir);
1021
1144
  if (wfCount > 0) steps.push(`${wfCount} workflows`);
1022
1145
 
1146
+ if (skillOpts && skillOpts.install) {
1147
+ const skillsDir = path.join(geminiDir, "antigravity", "skills");
1148
+ const skCount = installSkillPacks(bundleDir, skillsDir, skillOpts.categories);
1149
+ if (skCount > 0) steps.push(`${skCount} skills`);
1150
+ }
1151
+
1023
1152
  return steps;
1024
1153
  }
1025
1154
 
1026
- function installRooCode(bundleDir, vaultPath) {
1155
+ function installRooCode(bundleDir, vaultPath, skillOpts) {
1027
1156
  const steps = [];
1028
1157
  if (vaultPath) {
1029
1158
  const rulesDir = path.join(vaultPath, ".roo", "rules");
@@ -1033,11 +1162,17 @@ function installRooCode(bundleDir, vaultPath) {
1033
1162
  fs.copyFileSync(src, path.join(rulesDir, "mover-os.md"));
1034
1163
  steps.push("rules");
1035
1164
  }
1165
+
1166
+ if (skillOpts && skillOpts.install) {
1167
+ const skillsDir = path.join(vaultPath, ".roo", "skills");
1168
+ const skCount = installSkillPacks(bundleDir, skillsDir, skillOpts.categories);
1169
+ if (skCount > 0) steps.push(`${skCount} skills`);
1170
+ }
1036
1171
  }
1037
1172
  return steps;
1038
1173
  }
1039
1174
 
1040
- function installCopilot(bundleDir, vaultPath) {
1175
+ function installCopilot(bundleDir, vaultPath, skillOpts) {
1041
1176
  const steps = [];
1042
1177
  if (vaultPath) {
1043
1178
  const ghDir = path.join(vaultPath, ".github");
@@ -1047,21 +1182,31 @@ function installCopilot(bundleDir, vaultPath) {
1047
1182
  fs.copyFileSync(src, path.join(ghDir, "copilot-instructions.md"));
1048
1183
  steps.push("rules");
1049
1184
  }
1185
+
1186
+ if (skillOpts && skillOpts.install) {
1187
+ const skillsDir = path.join(ghDir, "skills");
1188
+ const skCount = installSkillPacks(bundleDir, skillsDir, skillOpts.categories);
1189
+ if (skCount > 0) steps.push(`${skCount} skills`);
1190
+ }
1050
1191
  }
1051
1192
  return steps;
1052
1193
  }
1053
1194
 
1054
- function installAmp(bundleDir, vaultPath) {
1195
+ function installAmp(bundleDir, vaultPath, skillOpts) {
1055
1196
  const steps = [];
1056
1197
  if (vaultPath) {
1057
- fs.writeFileSync(path.join(vaultPath, "AGENTS.md"), generateAgentsMd(), "utf8");
1058
- steps.push("AGENTS.md");
1059
1198
  if (installRules(bundleDir, path.join(vaultPath, "AMP.md"))) steps.push("AMP.md");
1199
+
1200
+ if (skillOpts && skillOpts.install) {
1201
+ const skillsDir = path.join(vaultPath, ".agents", "skills");
1202
+ const skCount = installSkillPacks(bundleDir, skillsDir, skillOpts.categories);
1203
+ if (skCount > 0) steps.push(`${skCount} skills`);
1204
+ }
1060
1205
  }
1061
1206
  return steps;
1062
1207
  }
1063
1208
 
1064
- function installAider(bundleDir, vaultPath) {
1209
+ function installAider(bundleDir, vaultPath, skillOpts) {
1065
1210
  const steps = [];
1066
1211
  if (vaultPath) {
1067
1212
  const agentsMdPath = path.join(vaultPath, "AGENTS.md");
@@ -1083,7 +1228,8 @@ const AGENT_INSTALLERS = {
1083
1228
  "claude-code": installClaudeCode,
1084
1229
  cursor: installCursor,
1085
1230
  cline: installCline,
1086
- codex: installCodex,
1231
+ "codex-cli": installCodexCli,
1232
+ "codex-cloud": installCodexCloud,
1087
1233
  windsurf: installWindsurf,
1088
1234
  openclaw: installOpenClaw,
1089
1235
  "gemini-cli": installGeminiCli,
@@ -1298,19 +1444,39 @@ async function main() {
1298
1444
  // ── Skills ──
1299
1445
  const allSkills = findSkills(bundleDir);
1300
1446
  let installSkills = false;
1447
+ let selectedCategories = null; // null = all, Set = filtered
1301
1448
 
1302
1449
  if (allSkills.length > 0 && selectedAgents.some((a) => ["Full", "Enhanced"].includes(a.tier))) {
1303
- question(`Install ${bold(String(allSkills.length))} skill packs? ${dim("code review, marketing, security...")}`);
1450
+ // Count skills per category
1451
+ const catCounts = {};
1452
+ for (const sk of allSkills) {
1453
+ catCounts[sk.category] = (catCounts[sk.category] || 0) + 1;
1454
+ }
1455
+
1456
+ question(`${bold(String(allSkills.length))} skill packs available. Select categories:`);
1304
1457
  barLn();
1305
1458
 
1306
- const skillChoice = await interactiveSelect(
1307
- [
1308
- { id: "yes", name: "Yes" },
1309
- { id: "no", name: "No" },
1310
- ],
1311
- { multi: false, defaultIndex: 0 }
1312
- );
1313
- installSkills = skillChoice === "yes";
1459
+ const categoryItems = CATEGORY_META.map((c) => ({
1460
+ id: c.id,
1461
+ name: `${c.name} ${dim(`(${catCounts[c.id] || 0})`)}`,
1462
+ tier: dim(c.desc),
1463
+ }));
1464
+
1465
+ // Pre-select Development + Obsidian (core categories everyone needs)
1466
+ const preSelected = ["development", "obsidian"];
1467
+
1468
+ const selectedCatIds = await interactiveSelect(categoryItems, {
1469
+ multi: true,
1470
+ preSelected,
1471
+ });
1472
+
1473
+ installSkills = selectedCatIds.length > 0;
1474
+ if (skillOpts && skillOpts.install) {
1475
+ selectedCategories = new Set(selectedCatIds);
1476
+ // Count how many skills will be installed (selected categories + tools)
1477
+ const skillCount = allSkills.filter((s) => s.category === "tools" || selectedCategories.has(s.category)).length;
1478
+ barLn(dim(`${skillCount} skills selected`));
1479
+ }
1314
1480
  }
1315
1481
 
1316
1482
  // ── Install with animated spinners ──
@@ -1369,11 +1535,16 @@ async function main() {
1369
1535
  }
1370
1536
 
1371
1537
  // 4. Per-agent installation
1538
+ const writtenFiles = new Set(); // Track shared files to avoid double-writes (e.g. GEMINI.md)
1539
+ const skillOpts = { install: installSkills, categories: selectedCategories };
1372
1540
  for (const agent of selectedAgents) {
1373
1541
  const fn = AGENT_INSTALLERS[agent.id];
1374
1542
  if (!fn) continue;
1375
1543
  sp = spinner(agent.name);
1376
- const steps = (agent.id === "antigravity" || agent.id === "gemini-cli") ? fn(bundleDir) : fn(bundleDir, vaultPath);
1544
+ const usesWrittenFiles = agent.id === "antigravity" || agent.id === "gemini-cli";
1545
+ const steps = usesWrittenFiles
1546
+ ? fn(bundleDir, vaultPath, skillOpts, writtenFiles)
1547
+ : fn(bundleDir, vaultPath, skillOpts);
1377
1548
  await sleep(250);
1378
1549
  if (steps.length > 0) {
1379
1550
  sp.stop(`${agent.name} ${dim(steps.join(", "))}`);
@@ -1384,8 +1555,8 @@ async function main() {
1384
1555
  }
1385
1556
  }
1386
1557
 
1387
- // 5. AGENTS.md — only for agents that need it
1388
- const needsAgentsMd = selectedAgents.some((a) => ["codex", "amp", "aider", "openclaw"].includes(a.id));
1558
+ // 5. AGENTS.md — only for agents that need it (consolidated write)
1559
+ const needsAgentsMd = selectedAgents.some((a) => ["codex-cli", "codex-cloud", "amp", "aider"].includes(a.id));
1389
1560
  if (needsAgentsMd) {
1390
1561
  fs.writeFileSync(path.join(vaultPath, "AGENTS.md"), generateAgentsMd(), "utf8");
1391
1562
  sp = spinner("AGENTS.md");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mover-os",
3
- "version": "4.0.9",
3
+ "version": "4.0.11",
4
4
  "description": "The self-improving OS for AI agents. Turns Obsidian into an execution engine.",
5
5
  "bin": {
6
6
  "mover-os": "install.js"
@@ -65,6 +65,10 @@ Break down the task blocks here
65
65
 
66
66
  - 09:00 -
67
67
 
68
+ **Food:**
69
+
70
+ **Sleep:** Total: | Deep:
71
+
68
72
 
69
73
  ---
70
74
 
@@ -72,7 +72,6 @@
72
72
 
73
73
  | File | Originally | Merged Into |
74
74
  |------|-----------|-------------|
75
- | `context.md` | `/context` | `/analyse-day` Step 8 |
76
75
  | `project-notes.md` | `/project-notes` | `/overview` Step 4 |
77
76
  | `init-plan.md` | `/init-plan` | `/ignite` (plan generation) |
78
77
 
@@ -87,7 +87,6 @@ Engine evolution: /history
87
87
  | `/debrief` | Post-meeting/call capture: actions, decisions, commitments | MEDIUM |
88
88
  | `/history` | View Engine file evolution over time | LOW |
89
89
  | ~~/init-plan~~ | DEPRECATED: merged into `/ignite` Section 12 | - |
90
- | ~~/context~~ | DEPRECATED: merged into `/analyse-day` Step 8 | - |
91
90
  | ~~/project-notes~~ | DEPRECATED: merged into `/overview` Step 4 | - |
92
91
 
93
92
  **Memory Hierarchy (Load Order):**
@@ -117,8 +116,7 @@ All files hard-linked from `src/` (single source of truth). Edit from any locati
117
116
 
118
117
  **MCP Servers:** Check `~/.claude.json` for available servers. Use them when relevant to the task.
119
118
 
120
- **Skills (Claude Code):**
121
- Skills are curated prompt packs in `src/skills/`. Hard-linked to `~/.claude/skills/`. Categories: Obsidian (markdown, bases, canvas, CLI), Marketing (CRO, SEO, copy, ads), n8n (expressions, nodes, workflows), Remotion (video). Skills activate automatically when relevant slash commands are used.
119
+ **Skills:** Curated skill packs are installed in your agent's skills directory. Check it for specialized capabilities (code review, debugging, marketing, CRO, SEO, strategy, Obsidian). Skills activate automatically when relevant to the task.
122
120
 
123
121
  ---
124
122
 
@@ -288,7 +286,7 @@ Before presenting a solution for anything complex, pause: "Is there a more elega
288
286
 
289
287
  **Errors:** No apologies. Analyze > Fix > Explain briefly. Zero hand-holding — point at logs, errors, and failing tests, then resolve them.
290
288
 
291
- **Debugging Protocol (Areeb Framework):**
289
+ **Debugging Protocol:**
292
290
  1. **Self-Critique Loop:** After generating a solution, critique it. Use that critique to produce a better answer. Repeat until no more flaws found.
293
291
  2. **Verbose Logging > Code Reading:** Don't guess from code. Add verbose logging to debug from evidence of what actually happened at runtime.
294
292
  3. **5-Why Against the Data:** Ask "why" 5 times against logs/evidence, not against what you think the code is doing. Go to bedrock (root cause).
@@ -386,43 +384,7 @@ The file is the truth, not the conversation. Chat-only decisions evaporate betwe
386
384
 
387
385
  **Rule:** Never let subagents inherit Opus by default. Every Task tool call must include a `model` parameter.
388
386
 
389
- **Specialist subagents (VoltAgent plugin + fallback skills):**
390
-
391
- If VoltAgent is installed (`~/.claude/plugins/` contains voltagent packages), use the native subagent format. If not, use `subagent_type: "general-purpose"` with the corresponding skill file from `src/skills/agent-*/SKILL.md`.
392
-
393
- **Development & Quality:**
394
-
395
- | Task | VoltAgent | Fallback Skill | Model |
396
- |------|-----------|---------------|-------|
397
- | Code review | `voltagent-qa-sec:code-reviewer` | `agent-code-reviewer` | opus |
398
- | Architecture review | `voltagent-qa-sec:architect-reviewer` | `agent-code-reviewer` | opus |
399
- | Security audit | `voltagent-qa-sec:security-auditor` | `agent-security-auditor` | opus |
400
- | Debugging | `voltagent-qa-sec:debugger` | `systematic-debugging` (inline) | sonnet |
401
- | Performance | `voltagent-qa-sec:performance-engineer` | — | sonnet |
402
-
403
- **Business & Strategy:**
404
-
405
- | Task | VoltAgent | Fallback Skill | Model |
406
- |------|-----------|---------------|-------|
407
- | Market research | `voltagent-research:market-researcher` | `agent-research-analyst` | sonnet |
408
- | Competitive analysis | `voltagent-research:competitive-analyst` | `agent-research-analyst` | sonnet |
409
- | Trend analysis | `voltagent-research:trend-analyst` | `agent-research-analyst` | sonnet |
410
- | Strategy validation | `voltagent-biz:business-analyst` | `agent-strategy-analyst` | opus |
411
- | Product decisions | `voltagent-biz:product-manager` | `agent-strategy-analyst` | opus |
412
- | Content research | `voltagent-biz:content-marketer` | `agent-content-researcher` | sonnet |
413
-
414
- **AI & Data:**
415
-
416
- | Task | VoltAgent | Fallback Skill | Model |
417
- |------|-----------|---------------|-------|
418
- | LLM/AI system design | `voltagent-data-ai:llm-architect` | — | opus |
419
- | Prompt optimization | `voltagent-data-ai:prompt-engineer` | — | sonnet |
420
-
421
- **VoltAgent install (optional but recommended):**
422
- ```bash
423
- claude plugins install voltagent-subagents
424
- ```
425
- Ships with Mover OS as a recommended dependency. Fallback skills in `src/skills/agent-*/` provide the same capability without the plugin.
387
+ **Specialist subagents:** Use skill files from `src/skills/agent-*/SKILL.md` for focused work (code review, security audit, research, strategy analysis). Spawn via subagent with the corresponding skill loaded.
426
388
 
427
389
  ---
428
390
 
@@ -638,9 +600,3 @@ Multiple AI instances may operate on this vault simultaneously (e.g., Claude Cod
638
600
  - `02_Areas/Engine/Auto_Learnings.md`
639
601
  - Any active project's `plan.md` and `project_state.md`
640
602
 
641
- ---
642
-
643
- ## CHANGELOG
644
-
645
- * [2026-01-21] V3 - Initial 17 sections. Mercenary Mode, Architect Mode, Pre-Flight Protocol.
646
- * [2026-02-21] V4 - Complete rewrite. 21 sections + Soul. Single adaptive Architect persona. 17 active workflows + 3 deprecated. 43 skills. 6 hooks. Rule Addition Gate (S11). Passive Detection Protocol (S5). Persona merged into Soul (S1.5). Grounding & Citation (S2), Verification & Confidence (S3), Memory Hierarchy (P0-P5), Model Routing (S10.5), Self-Improvement (S11), Proactive Surfacing (S12), Answer Gating (S13), Library Protocol (S14), AI Behavior (S16), Workflow Continuity (S18), Workflow State (S19), Session Management (S20), Multi-Instance Awareness (S21). Areeb debugging framework (S4). Three domains: Work, Vitality, Faith/Purpose. //turbo mode. Hard-link architecture. Universal installer (11 agents). /update, /ignite --feature, Session Type Detection, Quarterly Review.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: End-of-day analysis. Reads Session Log, audits strategy, updates Dashboard & Rudder, proposes Active_Context updates. Absorbs /context.
2
+ description: End-of-day analysis. Reads Session Log, audits strategy, updates Dashboard & Rudder, proposes Active_Context updates.
3
3
  ---
4
4
 
5
5
  # Daily Analysis (V4)
@@ -322,7 +322,7 @@ If yes: "You've been avoiding [Task] for [X] days. Is it important? Why? Break i
322
322
 
323
323
  ---
324
324
 
325
- ## 8. CONTEXT UPDATE (Absorbed from /context)
325
+ ## 8. CONTEXT UPDATE
326
326
 
327
327
  **Active_Context is NOT optional.** This is the bridge between sessions and days. If it's stale (>2 days since last update), updating it is mandatory, not suggested.
328
328
 
@@ -27,6 +27,12 @@ git rev-parse --show-toplevel
27
27
  ```
28
28
  Save result as VAULT_ROOT. ALL Engine file paths below are relative to this root, NOT to the current working directory.
29
29
 
30
+ WORKING DIRECTORY (capture project context):
31
+ ```bash
32
+ pwd
33
+ ```
34
+ Save as WORKING_DIR. Extract project name: if inside `01_Projects/[Name]/`, capture `[Name]`. Otherwise use the directory basename.
35
+
30
36
  DAILY NOTE PATH (derive from SESSION_END_TIME):
31
37
  ```
32
38
  {VAULT_ROOT}/02_Areas/Engine/Dailies/YYYY-MM/Daily - YYYY-MM-DD.md
@@ -81,7 +87,10 @@ Before reviewing history, determine the session type:
81
87
  - AUTONOMOUS sessions: mark ALL timestamps as `[AUTO]` and add note: "Agent-driven session. User may not have been present."
82
88
  - SEMI-AUTONOMOUS: mark agent-only work timestamps with `[AUTO]`, user-present segments with normal timestamps
83
89
 
84
- Tag the session log section: `### Session Log [ATTENDED]` or `### Session Log [AUTONOMOUS]` or `### Session Log [SEMI-AUTO]`
90
+ Tag the session log section: `### Session Log [ATTENDED] — HH:MM-HH:MM [Platform] [Project]` or `### Session Log [AUTONOMOUS]` or `### Session Log [SEMI-AUTO]`
91
+
92
+ Include WORKING_DIR project name in the session header. If the session spans multiple projects, note the primary one.
93
+ Example: `### Session Log [ATTENDED] — 14:00-15:30 [Claude Code] [Mover OS Bundle]`
85
94
 
86
95
  ---
87
96
 
@@ -75,10 +75,11 @@ This is not the interview. This is context-loading. Don't ask questions yet. Mov
75
75
  Copy `Someday_Maybe.md` template to `02_Areas/Engine/Someday_Maybe.md` if it doesn't exist.
76
76
  2. **Re-Setup Protection:** Check if core Engine files already exist (Identity_Prime.md, Strategy.md, Mover_Dossier.md).
77
77
  - If ANY exist: "Existing Engine files detected: [list]. Options:"
78
- - **(A) Fresh Start:** Archive existing to `04_Archives/Engine_Backup_YYYY-MM-DD/` and start clean.
79
- - **(B) Update Mode:** Interview to fill gaps in existing files. Skip banks already covered.
80
- - **(C) Cancel:** Exit setup.
78
+ - **(A) Update Mode:** Keep existing files. Interview to fill any gaps in existing files. Skip banks already covered. (RECOMMENDED — safe default)
79
+ - **(B) Cancel:** Exit setup.
80
+ - **(C) Fresh Start:** Archive existing to `04_Archives/Engine_Backup_YYYY-MM-DD/` and start clean. (DESTRUCTIVE)
81
81
  - WAIT FOR USER CHOICE. Do not overwrite without explicit consent.
82
+ - **If user selects (C) Fresh Start:** "This will ARCHIVE your existing Engine files (Identity, Strategy, Dossier, Goals) to `04_Archives/Engine_Backup_YYYY-MM-DD/` and start from scratch. Type 'ARCHIVE' to confirm." WAIT for user to type 'ARCHIVE'. If they type anything else, return to option selection.
82
83
  3. **Welcome:**
83
84
  "Welcome to Mover OS. I'm The System — I learn how you work and hold you accountable to your own goals.
84
85
  To set this up properly, I need to understand you — not just what you do, but how you think. The more honest you are, the better this works."
@@ -105,8 +105,7 @@ Three domains: Work, Vitality, Faith/Purpose. Based on identity, not motivation.
105
105
  - **`/log`** - When you finish a session, sync progress and capture lessons.
106
106
 
107
107
  ### End of Day
108
- - **`/analyse-day`** - Audit what you actually did vs Strategy.
109
- Includes context update (formerly separate `/context` command).
108
+ - **`/analyse-day`** - Audit what you actually did vs Strategy. Includes context update.
110
109
  - **`/plan-tomorrow`** - Creates tomorrow's Battle Plan.
111
110
 
112
111
  ### End of Week
@@ -1,24 +0,0 @@
1
- ---
2
- description: DEPRECATED in V4. Functionality merged into /analyse-day. Kept for backwards compatibility.
3
- ---
4
-
5
- # Context Update (DEPRECATED - V4)
6
-
7
- **Status:** This workflow has been merged into `/analyse-day` (V4).
8
-
9
- The context update functionality (quick Active_Context.md capture) now runs as part of Step 8 in `/analyse-day`.
10
-
11
- **If you need a quick context update:** Run `/analyse-day` and it will include the context capture at the end.
12
-
13
- **If you need a standalone context update outside of analysis:** Update `02_Areas/Engine/Active_Context.md` directly with:
14
- 1. Current Project and Phase
15
- 2. Blockers
16
- 3. Energy Level (1-10)
17
- 4. This week's goals
18
- 5. Brain dump
19
-
20
- ---
21
-
22
- ## HANDOFF
23
-
24
- **Next:** Run `/analyse-day` for the full end-of-day flow (includes context update).