youmd 0.6.19 → 0.6.26

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 (222) hide show
  1. package/dist/commands/build.d.ts.map +1 -1
  2. package/dist/commands/build.js +0 -1
  3. package/dist/commands/build.js.map +1 -1
  4. package/dist/commands/chat.d.ts.map +1 -1
  5. package/dist/commands/chat.js +604 -199
  6. package/dist/commands/chat.js.map +1 -1
  7. package/dist/commands/init.d.ts.map +1 -1
  8. package/dist/commands/init.js +21 -1
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/keys.d.ts.map +1 -1
  11. package/dist/commands/keys.js +3 -3
  12. package/dist/commands/keys.js.map +1 -1
  13. package/dist/commands/link.d.ts.map +1 -1
  14. package/dist/commands/link.js +3 -3
  15. package/dist/commands/link.js.map +1 -1
  16. package/dist/commands/login.d.ts +29 -0
  17. package/dist/commands/login.d.ts.map +1 -1
  18. package/dist/commands/login.js +257 -128
  19. package/dist/commands/login.js.map +1 -1
  20. package/dist/commands/logs.js +0 -1
  21. package/dist/commands/logs.js.map +1 -1
  22. package/dist/commands/mcp.d.ts +14 -0
  23. package/dist/commands/mcp.d.ts.map +1 -1
  24. package/dist/commands/mcp.js +284 -28
  25. package/dist/commands/mcp.js.map +1 -1
  26. package/dist/commands/private.d.ts.map +1 -1
  27. package/dist/commands/private.js +6 -5
  28. package/dist/commands/private.js.map +1 -1
  29. package/dist/commands/project.d.ts.map +1 -1
  30. package/dist/commands/project.js +9 -5
  31. package/dist/commands/project.js.map +1 -1
  32. package/dist/commands/publish.d.ts.map +1 -1
  33. package/dist/commands/publish.js +0 -1
  34. package/dist/commands/publish.js.map +1 -1
  35. package/dist/commands/pull.d.ts +24 -1
  36. package/dist/commands/pull.d.ts.map +1 -1
  37. package/dist/commands/pull.js +114 -14
  38. package/dist/commands/pull.js.map +1 -1
  39. package/dist/commands/push.d.ts +1 -0
  40. package/dist/commands/push.d.ts.map +1 -1
  41. package/dist/commands/push.js +33 -13
  42. package/dist/commands/push.js.map +1 -1
  43. package/dist/commands/register.d.ts +6 -0
  44. package/dist/commands/register.d.ts.map +1 -1
  45. package/dist/commands/register.js +179 -79
  46. package/dist/commands/register.js.map +1 -1
  47. package/dist/commands/skill.d.ts.map +1 -1
  48. package/dist/commands/skill.js +123 -52
  49. package/dist/commands/skill.js.map +1 -1
  50. package/dist/commands/stack.d.ts +16 -0
  51. package/dist/commands/stack.d.ts.map +1 -0
  52. package/dist/commands/stack.js +670 -0
  53. package/dist/commands/stack.js.map +1 -0
  54. package/dist/commands/status.d.ts.map +1 -1
  55. package/dist/commands/status.js +25 -5
  56. package/dist/commands/status.js.map +1 -1
  57. package/dist/commands/sync.d.ts +23 -0
  58. package/dist/commands/sync.d.ts.map +1 -1
  59. package/dist/commands/sync.js +193 -12
  60. package/dist/commands/sync.js.map +1 -1
  61. package/dist/commands/whoami.d.ts.map +1 -1
  62. package/dist/commands/whoami.js +21 -16
  63. package/dist/commands/whoami.js.map +1 -1
  64. package/dist/create.js +0 -0
  65. package/dist/index.js +128 -7
  66. package/dist/index.js.map +1 -1
  67. package/dist/lib/api.d.ts +94 -5
  68. package/dist/lib/api.d.ts.map +1 -1
  69. package/dist/lib/api.js +122 -5
  70. package/dist/lib/api.js.map +1 -1
  71. package/dist/lib/ascii.d.ts +5 -0
  72. package/dist/lib/ascii.d.ts.map +1 -1
  73. package/dist/lib/ascii.js +21 -30
  74. package/dist/lib/ascii.js.map +1 -1
  75. package/dist/lib/canonical-json.d.ts +8 -0
  76. package/dist/lib/canonical-json.d.ts.map +1 -0
  77. package/dist/lib/canonical-json.js +29 -0
  78. package/dist/lib/canonical-json.js.map +1 -0
  79. package/dist/lib/capability-router.d.ts +58 -0
  80. package/dist/lib/capability-router.d.ts.map +1 -0
  81. package/dist/lib/capability-router.js +54 -0
  82. package/dist/lib/capability-router.js.map +1 -0
  83. package/dist/lib/compiler.d.ts +32 -0
  84. package/dist/lib/compiler.d.ts.map +1 -1
  85. package/dist/lib/compiler.js +150 -0
  86. package/dist/lib/compiler.js.map +1 -1
  87. package/dist/lib/config.d.ts +71 -35
  88. package/dist/lib/config.d.ts.map +1 -1
  89. package/dist/lib/config.js +334 -124
  90. package/dist/lib/config.js.map +1 -1
  91. package/dist/lib/decompile.d.ts +6 -1
  92. package/dist/lib/decompile.d.ts.map +1 -1
  93. package/dist/lib/decompile.js +120 -11
  94. package/dist/lib/decompile.js.map +1 -1
  95. package/dist/lib/first-run.d.ts +14 -0
  96. package/dist/lib/first-run.d.ts.map +1 -0
  97. package/dist/lib/first-run.js +97 -0
  98. package/dist/lib/first-run.js.map +1 -0
  99. package/dist/lib/hash.d.ts.map +1 -1
  100. package/dist/lib/hash.js +2 -19
  101. package/dist/lib/hash.js.map +1 -1
  102. package/dist/lib/heartbeat.d.ts +38 -0
  103. package/dist/lib/heartbeat.d.ts.map +1 -0
  104. package/dist/lib/heartbeat.js +70 -0
  105. package/dist/lib/heartbeat.js.map +1 -0
  106. package/dist/lib/host-link.d.ts +123 -0
  107. package/dist/lib/host-link.d.ts.map +1 -0
  108. package/dist/lib/host-link.js +350 -0
  109. package/dist/lib/host-link.js.map +1 -0
  110. package/dist/lib/merge.d.ts +50 -0
  111. package/dist/lib/merge.d.ts.map +1 -0
  112. package/dist/lib/merge.js +167 -0
  113. package/dist/lib/merge.js.map +1 -0
  114. package/dist/lib/onboarding.d.ts +17 -0
  115. package/dist/lib/onboarding.d.ts.map +1 -1
  116. package/dist/lib/onboarding.js +225 -208
  117. package/dist/lib/onboarding.js.map +1 -1
  118. package/dist/lib/project.d.ts +5 -0
  119. package/dist/lib/project.d.ts.map +1 -1
  120. package/dist/lib/project.js +8 -0
  121. package/dist/lib/project.js.map +1 -1
  122. package/dist/lib/projectContext.d.ts +201 -0
  123. package/dist/lib/projectContext.d.ts.map +1 -0
  124. package/dist/lib/projectContext.js +597 -0
  125. package/dist/lib/projectContext.js.map +1 -0
  126. package/dist/lib/render.d.ts +38 -1
  127. package/dist/lib/render.d.ts.map +1 -1
  128. package/dist/lib/render.js +83 -18
  129. package/dist/lib/render.js.map +1 -1
  130. package/dist/lib/skill-catalog.d.ts.map +1 -1
  131. package/dist/lib/skill-catalog.js +22 -2
  132. package/dist/lib/skill-catalog.js.map +1 -1
  133. package/dist/lib/skills.d.ts +20 -5
  134. package/dist/lib/skills.d.ts.map +1 -1
  135. package/dist/lib/skills.js +116 -58
  136. package/dist/lib/skills.js.map +1 -1
  137. package/dist/lib/stackEval.d.ts +87 -0
  138. package/dist/lib/stackEval.d.ts.map +1 -0
  139. package/dist/lib/stackEval.js +233 -0
  140. package/dist/lib/stackEval.js.map +1 -0
  141. package/dist/lib/stackImprove.d.ts +49 -0
  142. package/dist/lib/stackImprove.d.ts.map +1 -0
  143. package/dist/lib/stackImprove.js +313 -0
  144. package/dist/lib/stackImprove.js.map +1 -0
  145. package/dist/lib/stackInstall.d.ts +59 -0
  146. package/dist/lib/stackInstall.d.ts.map +1 -0
  147. package/dist/lib/stackInstall.js +162 -0
  148. package/dist/lib/stackInstall.js.map +1 -0
  149. package/dist/lib/stackSafety.d.ts +126 -0
  150. package/dist/lib/stackSafety.d.ts.map +1 -0
  151. package/dist/lib/stackSafety.js +486 -0
  152. package/dist/lib/stackSafety.js.map +1 -0
  153. package/dist/lib/stackUpdate.d.ts +44 -0
  154. package/dist/lib/stackUpdate.d.ts.map +1 -0
  155. package/dist/lib/stackUpdate.js +256 -0
  156. package/dist/lib/stackUpdate.js.map +1 -0
  157. package/dist/lib/stream.d.ts +116 -0
  158. package/dist/lib/stream.d.ts.map +1 -0
  159. package/dist/lib/stream.js +368 -0
  160. package/dist/lib/stream.js.map +1 -0
  161. package/dist/lib/youstack.d.ts +219 -0
  162. package/dist/lib/youstack.d.ts.map +1 -0
  163. package/dist/lib/youstack.js +1049 -0
  164. package/dist/lib/youstack.js.map +1 -0
  165. package/dist/mcp/registry.d.ts +133 -0
  166. package/dist/mcp/registry.d.ts.map +1 -0
  167. package/dist/mcp/registry.js +833 -0
  168. package/dist/mcp/registry.js.map +1 -0
  169. package/dist/mcp/server.d.ts +106 -5
  170. package/dist/mcp/server.d.ts.map +1 -1
  171. package/dist/mcp/server.js +851 -498
  172. package/dist/mcp/server.js.map +1 -1
  173. package/dist/postinstall.js +11 -2
  174. package/dist/postinstall.js.map +1 -1
  175. package/dist/you.d.ts +1 -0
  176. package/dist/you.js +41 -5
  177. package/dist/you.js.map +1 -1
  178. package/examples/youstack-bamfstack-public/docs/quickstart.md +34 -0
  179. package/examples/youstack-bamfstack-public/prompts/creator-draft-starter.md +15 -0
  180. package/examples/youstack-bamfstack-public/skills/bamfstack-start/SKILL.md +36 -0
  181. package/examples/youstack-bamfstack-public/tests/smoke.md +19 -0
  182. package/examples/youstack-bamfstack-public/workflows/creator-growth-workflow.md +22 -0
  183. package/examples/youstack-bamfstack-public/youstack.json +172 -0
  184. package/examples/youstack-personal/docs/quickstart.md +10 -0
  185. package/examples/youstack-personal/skills/youstack-start/SKILL.md +9 -0
  186. package/examples/youstack-personal/tests/smoke.md +9 -0
  187. package/examples/youstack-personal/workflows/startup.md +7 -0
  188. package/examples/youstack-personal/youstack.json +123 -0
  189. package/package.json +3 -3
  190. package/skills/claude-md-generator.md +1 -1
  191. package/skills/meta-improve.md +8 -3
  192. package/skills/proactive-context-fill.md +1 -1
  193. package/skills/youstack-maintainer.md +128 -0
  194. package/skills/youstack-start.md +78 -0
  195. package/dist/__tests__/api.test.d.ts +0 -2
  196. package/dist/__tests__/api.test.d.ts.map +0 -1
  197. package/dist/__tests__/api.test.js +0 -87
  198. package/dist/__tests__/api.test.js.map +0 -1
  199. package/dist/__tests__/compiler.test.d.ts +0 -2
  200. package/dist/__tests__/compiler.test.d.ts.map +0 -1
  201. package/dist/__tests__/compiler.test.js +0 -127
  202. package/dist/__tests__/compiler.test.js.map +0 -1
  203. package/dist/__tests__/config.test.d.ts +0 -2
  204. package/dist/__tests__/config.test.d.ts.map +0 -1
  205. package/dist/__tests__/config.test.js +0 -79
  206. package/dist/__tests__/config.test.js.map +0 -1
  207. package/dist/__tests__/decompile.test.d.ts +0 -2
  208. package/dist/__tests__/decompile.test.d.ts.map +0 -1
  209. package/dist/__tests__/decompile.test.js +0 -102
  210. package/dist/__tests__/decompile.test.js.map +0 -1
  211. package/dist/__tests__/hash.test.d.ts +0 -2
  212. package/dist/__tests__/hash.test.d.ts.map +0 -1
  213. package/dist/__tests__/hash.test.js +0 -44
  214. package/dist/__tests__/hash.test.js.map +0 -1
  215. package/dist/__tests__/integration.test.d.ts +0 -2
  216. package/dist/__tests__/integration.test.d.ts.map +0 -1
  217. package/dist/__tests__/integration.test.js +0 -284
  218. package/dist/__tests__/integration.test.js.map +0 -1
  219. package/dist/__tests__/skill-renderer.test.d.ts +0 -2
  220. package/dist/__tests__/skill-renderer.test.d.ts.map +0 -1
  221. package/dist/__tests__/skill-renderer.test.js +0 -68
  222. package/dist/__tests__/skill-renderer.test.js.map +0 -1
@@ -45,6 +45,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.skillCommand = skillCommand;
46
46
  const fs = __importStar(require("fs"));
47
47
  const path = __importStar(require("path"));
48
+ const os = __importStar(require("os"));
49
+ const readline = __importStar(require("readline"));
50
+ const yaml = __importStar(require("js-yaml"));
48
51
  const chalk_1 = __importDefault(require("chalk"));
49
52
  const skill_catalog_1 = require("../lib/skill-catalog");
50
53
  const skills_1 = require("../lib/skills");
@@ -53,6 +56,7 @@ const render_1 = require("../lib/render");
53
56
  const config_1 = require("../lib/config");
54
57
  const api_1 = require("../lib/api");
55
58
  const skills_2 = require("../lib/skills");
59
+ const host_link_1 = require("../lib/host-link");
56
60
  const ACCENT = chalk_1.default.hex("#C46A3A");
57
61
  const DIM = chalk_1.default.dim;
58
62
  // ─── Personality spinner labels ──────────────────────────────────────
@@ -107,7 +111,7 @@ function truncateAtWord(text, max) {
107
111
  return (lastSpace > max * 0.5 ? truncated.slice(0, lastSpace) : truncated) + "...";
108
112
  }
109
113
  // ─── Subcommands ──────────────────────────────────────────────────────
110
- const RECOMMENDED_SKILLS = new Set(["claude-md-generator", "voice-sync"]);
114
+ const RECOMMENDED_SKILLS = new Set(["youstack-start", "claude-md-generator", "voice-sync"]);
111
115
  async function listSkills() {
112
116
  const catalog = (0, skill_catalog_1.readSkillCatalog)();
113
117
  console.log("");
@@ -165,7 +169,7 @@ async function listSkills() {
165
169
  if (installed === 0) {
166
170
  console.log("");
167
171
  console.log(DIM(" get started: ") +
168
- chalk_1.default.cyan("youmd skill install claude-md-generator"));
172
+ chalk_1.default.cyan("youmd skill install youstack-start"));
169
173
  }
170
174
  console.log("");
171
175
  }
@@ -184,11 +188,10 @@ async function installSkillCmd(args) {
184
188
  console.log("");
185
189
  const spinner = new render_1.BrailleSpinner(randomSpinner("install"));
186
190
  spinner.start();
187
- await new Promise((r) => setTimeout(r, 300));
188
191
  let installed = 0;
189
192
  for (const entry of toInstall) {
190
193
  let result = (0, skills_1.installSkill)(entry.name);
191
- if (!result.ok && (entry.source.startsWith("github:") || entry.source.startsWith("https://"))) {
194
+ if (!result.ok && (0, skills_1.isRemoteSkillSource)(entry.source)) {
192
195
  result = await (0, skills_1.installSkillAsync)(entry.name);
193
196
  }
194
197
  if (result.ok)
@@ -213,7 +216,6 @@ async function installSkillCmd(args) {
213
216
  console.log("");
214
217
  const regSpinner = new render_1.BrailleSpinner("checking the skill registry");
215
218
  regSpinner.start();
216
- await new Promise((r) => setTimeout(r, 200));
217
219
  try {
218
220
  const regRes = await (0, api_1.browseSkills)();
219
221
  if (regRes.ok) {
@@ -228,8 +230,7 @@ async function installSkillCmd(args) {
228
230
  fs.mkdirSync(skillDir, { recursive: true });
229
231
  fs.writeFileSync(path.join(skillDir, "SKILL.md"), contentRes.data.content);
230
232
  // Render with identity
231
- const { renderSkillTemplate, loadIdentityData: loadId } = require("../lib/skill-renderer");
232
- const rendered = renderSkillTemplate(contentRes.data.content, loadId());
233
+ const rendered = (0, skill_renderer_1.renderSkillTemplate)(contentRes.data.content, (0, skill_renderer_1.loadIdentityData)());
233
234
  fs.writeFileSync(path.join(skillDir, "RENDERED.md"), rendered);
234
235
  // Add to catalog and mark installed
235
236
  (0, skill_catalog_1.addSkillEntry)((0, skill_catalog_1.readSkillCatalog)(), {
@@ -289,10 +290,9 @@ async function installSkillCmd(args) {
289
290
  console.log("");
290
291
  const spinner = new render_1.BrailleSpinner(randomSpinner("install"));
291
292
  spinner.start();
292
- await new Promise((r) => setTimeout(r, 300));
293
293
  // Try sync install, fall back to async for remote sources
294
294
  let result = (0, skills_1.installSkill)(entry.name);
295
- if (!result.ok && (entry.source.startsWith("github:") || entry.source.startsWith("https://"))) {
295
+ if (!result.ok && (0, skills_1.isRemoteSkillSource)(entry.source)) {
296
296
  result = await (0, skills_1.installSkillAsync)(entry.name);
297
297
  }
298
298
  if (result.ok) {
@@ -324,7 +324,6 @@ async function removeSkillCmd(args) {
324
324
  console.log("");
325
325
  const spinner = new render_1.BrailleSpinner(randomSpinner("remove"));
326
326
  spinner.start();
327
- await new Promise((r) => setTimeout(r, 200));
328
327
  let removed = 0;
329
328
  for (const entry of toRemove) {
330
329
  const result = (0, skills_1.removeSkill)(entry.name);
@@ -345,7 +344,6 @@ async function removeSkillCmd(args) {
345
344
  console.log("");
346
345
  const spinner = new render_1.BrailleSpinner(randomSpinner("remove"));
347
346
  spinner.start();
348
- await new Promise((r) => setTimeout(r, 200));
349
347
  const result = (0, skills_1.removeSkill)(name);
350
348
  if (result.ok) {
351
349
  spinner.stop("removed");
@@ -355,7 +353,7 @@ async function removeSkillCmd(args) {
355
353
  }
356
354
  console.log("");
357
355
  }
358
- async function useSkillCmd(args) {
356
+ async function skillUseCmd(args) {
359
357
  const name = args[0];
360
358
  if (!name) {
361
359
  console.log("");
@@ -366,8 +364,7 @@ async function useSkillCmd(args) {
366
364
  console.log("");
367
365
  const spinner = new render_1.BrailleSpinner(randomSpinner("use"));
368
366
  spinner.start();
369
- await new Promise((r) => setTimeout(r, 400));
370
- const result = (0, skills_1.useSkill)(name);
367
+ const result = (0, skills_1.applySkill)(name);
371
368
  if (!result.ok) {
372
369
  spinner.fail(result.error);
373
370
  console.log("");
@@ -381,7 +378,7 @@ async function useSkillCmd(args) {
381
378
  console.log("");
382
379
  console.log(ACCENT(` ${filled}/${total} identity fields resolved.`) +
383
380
  DIM(` missing: ${missing.join(", ")}`));
384
- console.log(DIM(" fill these via ") + chalk_1.default.cyan("youmd chat") + DIM(" or edit .youmd/preferences/"));
381
+ console.log(DIM(" fill these via ") + chalk_1.default.cyan("you") + DIM(" or edit .youmd/preferences/"));
385
382
  }
386
383
  else {
387
384
  console.log(DIM(` ${total}/${total} identity fields resolved.`));
@@ -408,7 +405,6 @@ async function syncSkillsCmd() {
408
405
  console.log("");
409
406
  const spinner = new render_1.BrailleSpinner(randomSpinner("sync"));
410
407
  spinner.start();
411
- await new Promise((r) => setTimeout(r, 400));
412
408
  const result = (0, skills_1.syncAllSkills)();
413
409
  if (result.synced.length > 0) {
414
410
  spinner.stop(`${result.synced.length} skills synced`);
@@ -433,7 +429,7 @@ function addSkillCmd(args) {
433
429
  if (!name || !source) {
434
430
  console.log("");
435
431
  console.log(chalk_1.default.yellow(" usage: youmd skill add <name> <source>"));
436
- console.log(DIM(" source: local:/path/to/skill.md or github:owner/repo/path"));
432
+ console.log(DIM(" source: local:/path/to/skill.md, github:owner/repo/path, or registry:<name>"));
437
433
  console.log("");
438
434
  return;
439
435
  }
@@ -454,7 +450,6 @@ function addSkillCmd(args) {
454
450
  console.log("");
455
451
  }
456
452
  async function createSkillCmd(args) {
457
- const readline = require("readline");
458
453
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
459
454
  const ask = (q) => new Promise((res) => rl.question(q, (a) => res(a.trim())));
460
455
  console.log("");
@@ -513,7 +508,6 @@ async function createSkillCmd(args) {
513
508
  "",
514
509
  ].join("\n");
515
510
  // Write to ~/.youmd/skills/<name>/SKILL.md
516
- const os = require("os");
517
511
  const skillDir = path.join(os.homedir(), ".youmd", "skills", slug);
518
512
  fs.mkdirSync(skillDir, { recursive: true });
519
513
  fs.writeFileSync(path.join(skillDir, "SKILL.md"), skillContent);
@@ -561,7 +555,7 @@ function pushSkillCmd(args) {
561
555
  console.log("");
562
556
  return;
563
557
  }
564
- const skillPath = path.join(require("os").homedir(), ".youmd", "skills", entry.name, "SKILL.md");
558
+ const skillPath = path.join(os.homedir(), ".youmd", "skills", entry.name, "SKILL.md");
565
559
  if (!fs.existsSync(skillPath)) {
566
560
  console.log(chalk_1.default.yellow(` SKILL.md not found for "${name}". install first.`));
567
561
  return;
@@ -600,7 +594,6 @@ async function linkSkillsCmd(args) {
600
594
  console.log("");
601
595
  const spinner = new render_1.BrailleSpinner(randomSpinner("link"));
602
596
  spinner.start();
603
- await new Promise((r) => setTimeout(r, 300));
604
597
  const result = (0, skills_1.linkToAgent)(target);
605
598
  if (result.ok) {
606
599
  spinner.stop(result.path);
@@ -639,11 +632,10 @@ async function initProjectCmd(args = []) {
639
632
  if (toInstall.length > 0) {
640
633
  const installSpinner = new render_1.BrailleSpinner(randomSpinner("install"));
641
634
  installSpinner.start();
642
- await new Promise((r) => setTimeout(r, 300));
643
635
  let installed = 0;
644
636
  for (const entry of toInstall) {
645
637
  let result = (0, skills_1.installSkill)(entry.name);
646
- if (!result.ok && (entry.source.startsWith("github:") || entry.source.startsWith("https://"))) {
638
+ if (!result.ok && (0, skills_1.isRemoteSkillSource)(entry.source)) {
647
639
  result = await (0, skills_1.installSkillAsync)(entry.name);
648
640
  }
649
641
  if (result.ok)
@@ -653,7 +645,6 @@ async function initProjectCmd(args = []) {
653
645
  }
654
646
  const spinner = new render_1.BrailleSpinner(randomSpinner("init"));
655
647
  spinner.start();
656
- await new Promise((r) => setTimeout(r, 500));
657
648
  const result = (0, skills_1.initProject)({ mode });
658
649
  spinner.stop();
659
650
  console.log("");
@@ -702,7 +693,7 @@ function metricsCmd() {
702
693
  console.log("");
703
694
  }
704
695
  }
705
- function improveCmd() {
696
+ async function improveCmd() {
706
697
  const metrics = (0, skills_1.getMetrics)();
707
698
  const catalog = (0, skill_catalog_1.readSkillCatalog)();
708
699
  const identity = (0, skill_renderer_1.loadIdentityData)();
@@ -711,19 +702,90 @@ function improveCmd() {
711
702
  console.log("");
712
703
  const installed = catalog.skills.filter((s) => s.installed);
713
704
  const notInstalled = catalog.skills.filter((s) => !s.installed);
705
+ // ─── Live outcome insights (L10) ──────────────────────────────────
706
+ let liveInsights = null;
707
+ if ((0, config_1.isAuthenticated)()) {
708
+ const insightSpinner = new render_1.BrailleSpinner("fetching outcome telemetry");
709
+ insightSpinner.start();
710
+ try {
711
+ const res = await (0, api_1.getSkillInsights)();
712
+ if (res.ok && Array.isArray(res.data?.insights) && res.data.insights.length > 0) {
713
+ liveInsights = res.data.insights;
714
+ insightSpinner.stop(`${liveInsights.length} skill${liveInsights.length === 1 ? "" : "s"} with outcome data`);
715
+ }
716
+ else {
717
+ insightSpinner.stop("no outcome data yet");
718
+ }
719
+ }
720
+ catch {
721
+ insightSpinner.stop("offline — using local metrics");
722
+ }
723
+ }
724
+ // ─── Fleet snapshot (L22) ────────────────────────────────────────
725
+ let fleetLines = [];
726
+ if ((0, config_1.isAuthenticated)()) {
727
+ try {
728
+ const fleetRes = await (0, api_1.getFleetSnapshot)();
729
+ if (fleetRes.ok && Array.isArray(fleetRes.data?.skills)) {
730
+ fleetLines = fleetRes.data.skills
731
+ .filter((s) => s.fleetInstallCount !== null)
732
+ .map((s) => DIM(` ${s.skill}: shared by ~${s.fleetInstallCount} others`));
733
+ }
734
+ }
735
+ catch {
736
+ // fleet data is best-effort — silently skip on error
737
+ }
738
+ }
739
+ // ─── Live outcome table ───────────────────────────────────────────
740
+ if (liveInsights && liveInsights.length > 0) {
741
+ console.log(" " + ACCENT("outcome history:"));
742
+ console.log("");
743
+ const maxName = Math.max(...liveInsights.map((s) => s.skill.length), 5);
744
+ const headerStr = ` ${"skill".padEnd(maxName + 2)}` +
745
+ `${"uses".padStart(6)} ` +
746
+ `${"success rate".padEnd(13)} ` +
747
+ `last used`;
748
+ console.log(DIM(headerStr));
749
+ console.log(DIM(" " + "-".repeat(headerStr.length - 2)));
750
+ const lowPerformers = [];
751
+ for (const s of liveInsights) {
752
+ const ratePct = Math.round(s.successRate * 100);
753
+ const rateStr = `${ratePct}%`.padStart(4);
754
+ const rateColored = s.successRate >= 0.8
755
+ ? chalk_1.default.green(rateStr)
756
+ : ACCENT(rateStr);
757
+ const lastUsed = s.lastUsedAt > 0
758
+ ? new Date(s.lastUsedAt).toISOString().slice(0, 10)
759
+ : "never";
760
+ console.log(` ${chalk_1.default.cyan(s.skill.padEnd(maxName + 2))}` +
761
+ `${String(s.uses).padStart(6)} ` +
762
+ `${rateColored.padEnd(13)} ` +
763
+ `${DIM(lastUsed)}`);
764
+ if (s.successRate < 0.8 && s.failure + s.partial > 0) {
765
+ lowPerformers.push(s);
766
+ }
767
+ }
768
+ console.log("");
769
+ for (const s of lowPerformers) {
770
+ const failCount = s.failure + s.partial;
771
+ console.log(DIM(` consider revising ${s.skill} — ${failCount} failure${failCount === 1 ? "" : "s"} recently`));
772
+ }
773
+ if (lowPerformers.length > 0)
774
+ console.log("");
775
+ }
714
776
  // ─── Activity Analysis ────────────────────────────────────────────
715
777
  const totalUses = Object.values(metrics.skills).reduce((sum, s) => sum + s.uses, 0);
716
778
  console.log(" " + ACCENT("overview: ") +
717
- `${installed.length} installed, ${totalUses} total uses, ` +
779
+ `${installed.length} installed, ${totalUses} total local uses, ` +
718
780
  `${Object.keys(metrics.identityFields).length} identity fields tracked`);
719
781
  console.log("");
720
- // Most used
782
+ // Most used (local — only show when no live insights available)
721
783
  const mostUsed = Object.entries(metrics.skills)
722
784
  .filter(([, data]) => data.uses > 0)
723
785
  .sort((a, b) => b[1].uses - a[1].uses)
724
786
  .slice(0, 5);
725
- if (mostUsed.length > 0) {
726
- console.log(" " + ACCENT("most active:"));
787
+ if (mostUsed.length > 0 && !liveInsights) {
788
+ console.log(" " + ACCENT("most active (local):"));
727
789
  for (const [name, data] of mostUsed) {
728
790
  const bar = ACCENT("\u2588".repeat(Math.min(data.uses, 20))) + DIM("\u2591".repeat(Math.max(0, 20 - data.uses)));
729
791
  console.log(` ${chalk_1.default.cyan(name.padEnd(24))} ${bar} ${data.uses}`);
@@ -781,7 +843,7 @@ function improveCmd() {
781
843
  for (const f of missing) {
782
844
  console.log(` ${chalk_1.default.yellow(f)}`);
783
845
  }
784
- console.log(DIM("\n fill via ") + chalk_1.default.cyan("youmd chat") + DIM(" or edit .youmd/preferences/"));
846
+ console.log(DIM("\n fill via ") + chalk_1.default.cyan("you") + DIM(" or edit .youmd/preferences/"));
785
847
  console.log("");
786
848
  }
787
849
  else if (allFields.size > 0) {
@@ -805,17 +867,23 @@ function improveCmd() {
805
867
  if (identity.voice.overall && !(0, skill_catalog_1.findSkill)(catalog, "voice-sync")?.installed) {
806
868
  proposals.push("install voice-sync — you have voice data that could propagate to all agents");
807
869
  }
808
- // Propose running sync if skills are installed but metrics show 0 syncs
809
- const syncCount = Object.values(metrics.skills).reduce((sum, s) => sum + s.uses, 0);
810
- if (installed.length > 0 && syncCount === 0) {
811
- proposals.push("run \"youmd skill sync\" — installed skills haven't been synced yet");
812
- }
813
- // Propose linking if skills installed but no .claude/skills/youmd exists
814
- if (installed.length > 0) {
815
- const claudeSkillsDir = path.join(process.cwd(), ".claude", "skills", "youmd");
816
- if (!fs.existsSync(claudeSkillsDir)) {
817
- proposals.push("run \"youmd skill link claude\" — skills aren't linked to this project's agent");
818
- }
870
+ // Propose running sync only when identity actually changed after the last
871
+ // skill sync (lastSyncedAt is recorded by the sync paths in lib/skills).
872
+ // Previously this keyed off total uses, which is unrelated to sync state.
873
+ const identityChangedAt = (0, skills_1.getIdentityLastChangedAt)();
874
+ const lastSyncedAtMs = metrics.lastSyncedAt ? Date.parse(metrics.lastSyncedAt) : NaN;
875
+ if (installed.length > 0 &&
876
+ identityChangedAt !== null &&
877
+ (Number.isNaN(lastSyncedAtMs) || identityChangedAt > lastSyncedAtMs)) {
878
+ proposals.push(Number.isNaN(lastSyncedAtMs)
879
+ ? "run \"youmd skill sync\" — installed skills haven't been synced against your identity yet"
880
+ : "run \"youmd skill sync\" — your identity changed after the last skill sync");
881
+ }
882
+ // Propose linking if skills are installed but not linked into the Claude
883
+ // Code discovery layout (.claude/skills/<name>/SKILL.md)
884
+ if (installed.length > 0 &&
885
+ !(0, host_link_1.hasLinkedClaudeSkills)(process.cwd(), installed.map((s) => s.name))) {
886
+ proposals.push("run \"youmd skill link claude\" — skills aren't linked to this project's agent");
819
887
  }
820
888
  if (proposals.length > 0) {
821
889
  console.log(" " + chalk_1.default.bold("proposals:"));
@@ -828,6 +896,13 @@ function improveCmd() {
828
896
  console.log(" " + chalk_1.default.green("\u2713") + DIM(" no improvements to suggest right now."));
829
897
  console.log("");
830
898
  }
899
+ // \u2500\u2500\u2500 Fleet context (L22) \u2014 one dim line per skill with fleet data \u2500\u2500\u2500\u2500\u2500
900
+ if (fleetLines.length > 0) {
901
+ for (const line of fleetLines) {
902
+ console.log(line);
903
+ }
904
+ console.log("");
905
+ }
831
906
  }
832
907
  function searchCmd(args) {
833
908
  const query = args.join(" ");
@@ -863,7 +938,6 @@ async function browseCmd() {
863
938
  console.log("");
864
939
  const spinner = new render_1.BrailleSpinner("scanning the skill registry");
865
940
  spinner.start();
866
- await new Promise((r) => setTimeout(r, 300));
867
941
  try {
868
942
  const res = await (0, api_1.browseSkills)();
869
943
  if (!res.ok) {
@@ -888,7 +962,7 @@ async function browseCmd() {
888
962
  console.log(` ${DIM("v" + s.version)} ${DIM(s.scope)} ${DIM(`[${s.identityFields.join(", ")}]`)}`);
889
963
  }
890
964
  console.log("");
891
- console.log(DIM(` install with: youmd skill add <name> registry:<name>`));
965
+ console.log(DIM(` install with: youmd skill install <name>`));
892
966
  }
893
967
  catch {
894
968
  spinner.fail("registry unreachable");
@@ -928,7 +1002,6 @@ async function publishSkillCmd(args) {
928
1002
  console.log("");
929
1003
  const spinner = new render_1.BrailleSpinner("publishing to the skill registry");
930
1004
  spinner.start();
931
- await new Promise((r) => setTimeout(r, 400));
932
1005
  try {
933
1006
  const res = await (0, api_1.publishSkill)({
934
1007
  name: entry.name,
@@ -942,10 +1015,10 @@ async function publishSkillCmd(args) {
942
1015
  spinner.stop(res.data.updated ? "updated" : "published");
943
1016
  console.log("");
944
1017
  console.log(chalk_1.default.green(" \u2713") + ` ${chalk_1.default.bold(entry.name)} is live on the registry`);
945
- console.log(DIM(` others can install with: youmd skill add ${entry.name} registry:${entry.name}`));
1018
+ console.log(DIM(` others can install with: youmd skill install ${entry.name}`));
946
1019
  }
947
1020
  else {
948
- spinner.fail(String(res.data?.error || "publish failed"));
1021
+ spinner.fail((0, api_1.apiErrorMessage)(res.data) || "publish failed");
949
1022
  }
950
1023
  }
951
1024
  catch (err) {
@@ -963,7 +1036,6 @@ async function remoteStatusCmd() {
963
1036
  console.log("");
964
1037
  const spinner = new render_1.BrailleSpinner("fetching your skill profile from the cloud");
965
1038
  spinner.start();
966
- await new Promise((r) => setTimeout(r, 300));
967
1039
  try {
968
1040
  const res = await (0, api_1.getMySkills)();
969
1041
  if (!res.ok) {
@@ -1070,10 +1142,10 @@ function exportSkillsCmd(args) {
1070
1142
  continue;
1071
1143
  // Export the raw SKILL.md
1072
1144
  const outPath = path.join(outputDir, `${entry.name}.md`);
1073
- const raw = fs.readFileSync(path.join(require("os").homedir(), ".youmd", "skills", entry.name, "SKILL.md"), "utf-8");
1145
+ const raw = fs.readFileSync(path.join(os.homedir(), ".youmd", "skills", entry.name, "SKILL.md"), "utf-8");
1074
1146
  fs.writeFileSync(outPath, raw);
1075
1147
  // Also export the rendered version
1076
- const renderedPath = path.join(require("os").homedir(), ".youmd", "skills", entry.name, "RENDERED.md");
1148
+ const renderedPath = path.join(os.homedir(), ".youmd", "skills", entry.name, "RENDERED.md");
1077
1149
  if (fs.existsSync(renderedPath)) {
1078
1150
  fs.writeFileSync(path.join(outputDir, `${entry.name}.rendered.md`), fs.readFileSync(renderedPath, "utf-8"));
1079
1151
  }
@@ -1081,7 +1153,6 @@ function exportSkillsCmd(args) {
1081
1153
  exported++;
1082
1154
  }
1083
1155
  // Write catalog.yaml
1084
- const yaml = require("js-yaml");
1085
1156
  const exportCatalog = {
1086
1157
  version: 1,
1087
1158
  exported: new Date().toISOString(),
@@ -1116,7 +1187,7 @@ async function skillCommand(subcommand, ...args) {
1116
1187
  break;
1117
1188
  case "use":
1118
1189
  case "run":
1119
- await useSkillCmd(args);
1190
+ await skillUseCmd(args);
1120
1191
  break;
1121
1192
  case "sync":
1122
1193
  await syncSkillsCmd();
@@ -1139,7 +1210,7 @@ async function skillCommand(subcommand, ...args) {
1139
1210
  await initProjectCmd(args);
1140
1211
  break;
1141
1212
  case "improve":
1142
- improveCmd();
1213
+ await improveCmd();
1143
1214
  break;
1144
1215
  case "metrics":
1145
1216
  case "stats":