mover-os 4.7.6 → 4.7.7

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 +75 -2
  2. package/package.json +1 -1
package/install.js CHANGED
@@ -3299,16 +3299,41 @@ function installHooksForClaude(bundleDir, vaultPath) {
3299
3299
  }
3300
3300
  }
3301
3301
  }
3302
+ // v4.7.7: set skillListingBudgetFraction so Mover OS users don't see
3303
+ // skill descriptions truncated by Claude Code's default 1% budget.
3304
+ // Per Claude Code's own /doctor output, Mover's ~63 skills need 2.5%
3305
+ // of context; 0.03 (3%) gives that exact size + small headroom for
3306
+ // user-added skills, without doubling the cost like 0.05 would.
3307
+ //
3308
+ // TRADEOFF: each session uses ~4,000 more system-prompt tokens than
3309
+ // Claude Code's default 1%. That marginally accelerates autocompaction
3310
+ // (~2% sooner) and rate-limit ticker. The benefit (full skill
3311
+ // descriptions available, no truncation message) outweighs the cost
3312
+ // for users who installed Mover OS specifically for the skill packs.
3313
+ //
3314
+ // Only set if not already configured — respect explicit user choice.
3315
+ // To opt out: manually set "skillListingBudgetFraction": 0.01 in your
3316
+ // ~/.claude/settings.json after install.
3317
+ if (existing.skillListingBudgetFraction === undefined) {
3318
+ existing.skillListingBudgetFraction = 0.03;
3319
+ }
3302
3320
  fs.writeFileSync(settingsPath, JSON.stringify(existing, null, 2), "utf8");
3303
3321
  } catch {
3304
3322
  // Corrupt settings — backup before overwrite
3305
3323
  const backupPath = settingsPath + ".bak";
3306
3324
  try { fs.copyFileSync(settingsPath, backupPath); } catch {}
3307
3325
  ln(` ${yellow("!")} Settings file corrupt — backed up to settings.json.bak, writing fresh`);
3308
- fs.writeFileSync(settingsPath, generateClaudeSettings(), "utf8");
3326
+ // Fresh write also sets the budget — combine generated hooks with the
3327
+ // skill budget setting so a fresh install doesn't trigger truncation.
3328
+ const fresh = JSON.parse(generateClaudeSettings());
3329
+ fresh.skillListingBudgetFraction = 0.03;
3330
+ fs.writeFileSync(settingsPath, JSON.stringify(fresh, null, 2), "utf8");
3309
3331
  }
3310
3332
  } else {
3311
- fs.writeFileSync(settingsPath, generateClaudeSettings(), "utf8");
3333
+ // Fresh install — write hooks AND the skill listing budget together.
3334
+ const fresh = JSON.parse(generateClaudeSettings());
3335
+ fresh.skillListingBudgetFraction = 0.03;
3336
+ fs.writeFileSync(settingsPath, JSON.stringify(fresh, null, 2), "utf8");
3312
3337
  }
3313
3338
 
3314
3339
  return count;
@@ -4200,6 +4225,54 @@ async function cmdDoctor(opts) {
4200
4225
  statusLine(allOk ? "ok" : "warn", ` ${reg.name}`, checks.join(", "));
4201
4226
  }
4202
4227
 
4228
+ // ── Claude Code skill listing budget (v4.7.7) ────────────────────────
4229
+ // Claude Code 2.1.x truncates skill descriptions when the total exceeds
4230
+ // skillListingBudgetFraction (default 0.01 = 1% of context, ~2K tokens).
4231
+ // Users with 50+ skills installed see the "X descriptions dropped" message.
4232
+ // This is a Claude Code feature, not a Mover OS bug — but Mover users hit
4233
+ // it because we ship many skills. Help the user diagnose + tune.
4234
+ barLn();
4235
+ barLn(dim(" Claude Code:"));
4236
+ const claudeSkillsDir = path.join(home, ".claude", "skills");
4237
+ if (fs.existsSync(claudeSkillsDir)) {
4238
+ const skillCount = fs.readdirSync(claudeSkillsDir).filter(n => !n.startsWith(".")).length;
4239
+ statusLine(
4240
+ skillCount > 70 ? "warn" : "ok",
4241
+ " Skill count",
4242
+ `${skillCount} in ~/.claude/skills/`
4243
+ );
4244
+ if (skillCount > 50) {
4245
+ // Try to read settings.json to report current value.
4246
+ let currentFraction = null;
4247
+ try {
4248
+ const s = JSON.parse(fs.readFileSync(path.join(home, ".claude", "settings.json"), "utf8"));
4249
+ if (typeof s.skillListingBudgetFraction === "number") currentFraction = s.skillListingBudgetFraction;
4250
+ } catch {}
4251
+ const fracDisplay = currentFraction === null ? "unset (Claude Code default 0.01)" : String(currentFraction);
4252
+ barLn(dim(` Skill listing budget: ${fracDisplay}`));
4253
+ if (currentFraction === null || currentFraction < 0.025) {
4254
+ barLn(dim(` With ${skillCount} skills, Claude Code's default 1% budget truncates`));
4255
+ barLn(dim(` less-used skill descriptions ("X descriptions dropped" message).`));
4256
+ barLn(dim(` 'moveros install' sets skillListingBudgetFraction: 0.03 (3%) to fit`));
4257
+ barLn(dim(` Mover's manifest. Trade: ~4K extra tokens per session, all skills`));
4258
+ barLn(dim(` visible. To opt back to 1% default: edit ~/.claude/settings.json.`));
4259
+ } else {
4260
+ barLn(dim(` Budget covers ~${Math.floor(currentFraction * 100 * 25)} skills before truncation. Run /skills`));
4261
+ barLn(dim(` in Claude Code to disable specific skills.`));
4262
+ }
4263
+ }
4264
+ }
4265
+ // CLAUDE.md size check — Claude Code flags > 40K as "Large CLAUDE.md".
4266
+ const claudeMd = path.join(home, ".claude", "CLAUDE.md");
4267
+ if (fs.existsSync(claudeMd)) {
4268
+ const claudeMdSize = fs.statSync(claudeMd).size;
4269
+ statusLine(
4270
+ claudeMdSize > 40000 ? "warn" : "ok",
4271
+ " CLAUDE.md size",
4272
+ `${claudeMdSize.toLocaleString()} chars` + (claudeMdSize > 40000 ? " (Claude Code flags >40K)" : "")
4273
+ );
4274
+ }
4275
+
4203
4276
  // Engine Git
4204
4277
  barLn();
4205
4278
  const engineGit = fs.existsSync(path.join(engineDir, ".git"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mover-os",
3
- "version": "4.7.6",
3
+ "version": "4.7.7",
4
4
  "description": "Your AI co-founder. Remembers your goals, pushes back when you drift. Works with 15 AI agents.",
5
5
  "bin": {
6
6
  "moveros": "install.js"