youmd 0.6.21 → 0.6.27

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 (218) 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 +283 -184
  6. package/dist/commands/chat.js.map +1 -1
  7. package/dist/commands/export.d.ts +1 -0
  8. package/dist/commands/export.d.ts.map +1 -1
  9. package/dist/commands/export.js +5 -0
  10. package/dist/commands/export.js.map +1 -1
  11. package/dist/commands/init.d.ts.map +1 -1
  12. package/dist/commands/init.js +21 -1
  13. package/dist/commands/init.js.map +1 -1
  14. package/dist/commands/keys.d.ts.map +1 -1
  15. package/dist/commands/keys.js +3 -3
  16. package/dist/commands/keys.js.map +1 -1
  17. package/dist/commands/link.d.ts.map +1 -1
  18. package/dist/commands/link.js +3 -3
  19. package/dist/commands/link.js.map +1 -1
  20. package/dist/commands/login.d.ts +29 -0
  21. package/dist/commands/login.d.ts.map +1 -1
  22. package/dist/commands/login.js +256 -127
  23. package/dist/commands/login.js.map +1 -1
  24. package/dist/commands/logs.js +0 -1
  25. package/dist/commands/logs.js.map +1 -1
  26. package/dist/commands/mcp.d.ts +14 -0
  27. package/dist/commands/mcp.d.ts.map +1 -1
  28. package/dist/commands/mcp.js +284 -28
  29. package/dist/commands/mcp.js.map +1 -1
  30. package/dist/commands/okf.d.ts +12 -0
  31. package/dist/commands/okf.d.ts.map +1 -0
  32. package/dist/commands/okf.js +411 -0
  33. package/dist/commands/okf.js.map +1 -0
  34. package/dist/commands/private.d.ts.map +1 -1
  35. package/dist/commands/private.js +6 -5
  36. package/dist/commands/private.js.map +1 -1
  37. package/dist/commands/project.d.ts.map +1 -1
  38. package/dist/commands/project.js +9 -5
  39. package/dist/commands/project.js.map +1 -1
  40. package/dist/commands/publish.d.ts.map +1 -1
  41. package/dist/commands/publish.js +0 -1
  42. package/dist/commands/publish.js.map +1 -1
  43. package/dist/commands/pull.d.ts +24 -1
  44. package/dist/commands/pull.d.ts.map +1 -1
  45. package/dist/commands/pull.js +114 -14
  46. package/dist/commands/pull.js.map +1 -1
  47. package/dist/commands/push.d.ts +1 -0
  48. package/dist/commands/push.d.ts.map +1 -1
  49. package/dist/commands/push.js +33 -13
  50. package/dist/commands/push.js.map +1 -1
  51. package/dist/commands/register.d.ts +6 -0
  52. package/dist/commands/register.d.ts.map +1 -1
  53. package/dist/commands/register.js +179 -79
  54. package/dist/commands/register.js.map +1 -1
  55. package/dist/commands/skill.d.ts.map +1 -1
  56. package/dist/commands/skill.js +121 -50
  57. package/dist/commands/skill.js.map +1 -1
  58. package/dist/commands/stack.d.ts +16 -0
  59. package/dist/commands/stack.d.ts.map +1 -0
  60. package/dist/commands/stack.js +863 -0
  61. package/dist/commands/stack.js.map +1 -0
  62. package/dist/commands/status.d.ts.map +1 -1
  63. package/dist/commands/status.js +25 -5
  64. package/dist/commands/status.js.map +1 -1
  65. package/dist/commands/sync.d.ts +23 -0
  66. package/dist/commands/sync.d.ts.map +1 -1
  67. package/dist/commands/sync.js +193 -12
  68. package/dist/commands/sync.js.map +1 -1
  69. package/dist/commands/whoami.d.ts.map +1 -1
  70. package/dist/commands/whoami.js +21 -16
  71. package/dist/commands/whoami.js.map +1 -1
  72. package/dist/create.js +0 -0
  73. package/dist/index.js +64 -7
  74. package/dist/index.js.map +1 -1
  75. package/dist/lib/api.d.ts +127 -5
  76. package/dist/lib/api.d.ts.map +1 -1
  77. package/dist/lib/api.js +142 -5
  78. package/dist/lib/api.js.map +1 -1
  79. package/dist/lib/ascii.d.ts +1 -0
  80. package/dist/lib/ascii.d.ts.map +1 -1
  81. package/dist/lib/ascii.js +9 -26
  82. package/dist/lib/ascii.js.map +1 -1
  83. package/dist/lib/canonical-json.d.ts +8 -0
  84. package/dist/lib/canonical-json.d.ts.map +1 -0
  85. package/dist/lib/canonical-json.js +29 -0
  86. package/dist/lib/canonical-json.js.map +1 -0
  87. package/dist/lib/capability-router.d.ts +58 -0
  88. package/dist/lib/capability-router.d.ts.map +1 -0
  89. package/dist/lib/capability-router.js +54 -0
  90. package/dist/lib/capability-router.js.map +1 -0
  91. package/dist/lib/compiler.d.ts +32 -0
  92. package/dist/lib/compiler.d.ts.map +1 -1
  93. package/dist/lib/compiler.js +150 -0
  94. package/dist/lib/compiler.js.map +1 -1
  95. package/dist/lib/config.d.ts +71 -35
  96. package/dist/lib/config.d.ts.map +1 -1
  97. package/dist/lib/config.js +334 -124
  98. package/dist/lib/config.js.map +1 -1
  99. package/dist/lib/decompile.d.ts +6 -1
  100. package/dist/lib/decompile.d.ts.map +1 -1
  101. package/dist/lib/decompile.js +120 -11
  102. package/dist/lib/decompile.js.map +1 -1
  103. package/dist/lib/hash.d.ts.map +1 -1
  104. package/dist/lib/hash.js +2 -19
  105. package/dist/lib/hash.js.map +1 -1
  106. package/dist/lib/heartbeat.d.ts +38 -0
  107. package/dist/lib/heartbeat.d.ts.map +1 -0
  108. package/dist/lib/heartbeat.js +70 -0
  109. package/dist/lib/heartbeat.js.map +1 -0
  110. package/dist/lib/host-link.d.ts +123 -0
  111. package/dist/lib/host-link.d.ts.map +1 -0
  112. package/dist/lib/host-link.js +350 -0
  113. package/dist/lib/host-link.js.map +1 -0
  114. package/dist/lib/merge.d.ts +50 -0
  115. package/dist/lib/merge.d.ts.map +1 -0
  116. package/dist/lib/merge.js +167 -0
  117. package/dist/lib/merge.js.map +1 -0
  118. package/dist/lib/okf-bundle.d.ts +104 -0
  119. package/dist/lib/okf-bundle.d.ts.map +1 -0
  120. package/dist/lib/okf-bundle.js +473 -0
  121. package/dist/lib/okf-bundle.js.map +1 -0
  122. package/dist/lib/okf-health.d.ts +40 -0
  123. package/dist/lib/okf-health.d.ts.map +1 -0
  124. package/dist/lib/okf-health.js +152 -0
  125. package/dist/lib/okf-health.js.map +1 -0
  126. package/dist/lib/okf-stack.d.ts +47 -0
  127. package/dist/lib/okf-stack.d.ts.map +1 -0
  128. package/dist/lib/okf-stack.js +331 -0
  129. package/dist/lib/okf-stack.js.map +1 -0
  130. package/dist/lib/okf-view.d.ts +49 -0
  131. package/dist/lib/okf-view.d.ts.map +1 -0
  132. package/dist/lib/okf-view.js +197 -0
  133. package/dist/lib/okf-view.js.map +1 -0
  134. package/dist/lib/okf.d.ts +130 -0
  135. package/dist/lib/okf.d.ts.map +1 -0
  136. package/dist/lib/okf.js +263 -0
  137. package/dist/lib/okf.js.map +1 -0
  138. package/dist/lib/onboarding.d.ts +17 -0
  139. package/dist/lib/onboarding.d.ts.map +1 -1
  140. package/dist/lib/onboarding.js +224 -207
  141. package/dist/lib/onboarding.js.map +1 -1
  142. package/dist/lib/project.d.ts +5 -0
  143. package/dist/lib/project.d.ts.map +1 -1
  144. package/dist/lib/project.js +8 -0
  145. package/dist/lib/project.js.map +1 -1
  146. package/dist/lib/projectContext.d.ts +201 -0
  147. package/dist/lib/projectContext.d.ts.map +1 -0
  148. package/dist/lib/projectContext.js +597 -0
  149. package/dist/lib/projectContext.js.map +1 -0
  150. package/dist/lib/render.d.ts +38 -1
  151. package/dist/lib/render.d.ts.map +1 -1
  152. package/dist/lib/render.js +83 -18
  153. package/dist/lib/render.js.map +1 -1
  154. package/dist/lib/skill-catalog.d.ts.map +1 -1
  155. package/dist/lib/skill-catalog.js +22 -2
  156. package/dist/lib/skill-catalog.js.map +1 -1
  157. package/dist/lib/skills.d.ts +20 -5
  158. package/dist/lib/skills.d.ts.map +1 -1
  159. package/dist/lib/skills.js +116 -58
  160. package/dist/lib/skills.js.map +1 -1
  161. package/dist/lib/stackEval.d.ts +87 -0
  162. package/dist/lib/stackEval.d.ts.map +1 -0
  163. package/dist/lib/stackEval.js +233 -0
  164. package/dist/lib/stackEval.js.map +1 -0
  165. package/dist/lib/stackImprove.d.ts +49 -0
  166. package/dist/lib/stackImprove.d.ts.map +1 -0
  167. package/dist/lib/stackImprove.js +313 -0
  168. package/dist/lib/stackImprove.js.map +1 -0
  169. package/dist/lib/stackInstall.d.ts +59 -0
  170. package/dist/lib/stackInstall.d.ts.map +1 -0
  171. package/dist/lib/stackInstall.js +162 -0
  172. package/dist/lib/stackInstall.js.map +1 -0
  173. package/dist/lib/stackSafety.d.ts +126 -0
  174. package/dist/lib/stackSafety.d.ts.map +1 -0
  175. package/dist/lib/stackSafety.js +486 -0
  176. package/dist/lib/stackSafety.js.map +1 -0
  177. package/dist/lib/stackUpdate.d.ts +44 -0
  178. package/dist/lib/stackUpdate.d.ts.map +1 -0
  179. package/dist/lib/stackUpdate.js +256 -0
  180. package/dist/lib/stackUpdate.js.map +1 -0
  181. package/dist/lib/stream.d.ts +116 -0
  182. package/dist/lib/stream.d.ts.map +1 -0
  183. package/dist/lib/stream.js +368 -0
  184. package/dist/lib/stream.js.map +1 -0
  185. package/dist/lib/youstack.d.ts +219 -0
  186. package/dist/lib/youstack.d.ts.map +1 -0
  187. package/dist/lib/youstack.js +1049 -0
  188. package/dist/lib/youstack.js.map +1 -0
  189. package/dist/mcp/registry.d.ts +133 -0
  190. package/dist/mcp/registry.d.ts.map +1 -0
  191. package/dist/mcp/registry.js +833 -0
  192. package/dist/mcp/registry.js.map +1 -0
  193. package/dist/mcp/server.d.ts +106 -5
  194. package/dist/mcp/server.d.ts.map +1 -1
  195. package/dist/mcp/server.js +851 -498
  196. package/dist/mcp/server.js.map +1 -1
  197. package/dist/postinstall.js +11 -2
  198. package/dist/postinstall.js.map +1 -1
  199. package/dist/you.d.ts +1 -0
  200. package/dist/you.js +40 -4
  201. package/dist/you.js.map +1 -1
  202. package/examples/youstack-bamfstack-public/docs/quickstart.md +34 -0
  203. package/examples/youstack-bamfstack-public/prompts/creator-draft-starter.md +15 -0
  204. package/examples/youstack-bamfstack-public/skills/bamfstack-start/SKILL.md +36 -0
  205. package/examples/youstack-bamfstack-public/tests/smoke.md +19 -0
  206. package/examples/youstack-bamfstack-public/workflows/creator-growth-workflow.md +22 -0
  207. package/examples/youstack-bamfstack-public/youstack.json +172 -0
  208. package/examples/youstack-personal/docs/quickstart.md +10 -0
  209. package/examples/youstack-personal/skills/youstack-start/SKILL.md +9 -0
  210. package/examples/youstack-personal/tests/smoke.md +9 -0
  211. package/examples/youstack-personal/workflows/startup.md +7 -0
  212. package/examples/youstack-personal/youstack.json +123 -0
  213. package/package.json +3 -3
  214. package/skills/claude-md-generator.md +1 -1
  215. package/skills/meta-improve.md +8 -3
  216. package/skills/proactive-context-fill.md +1 -1
  217. package/skills/youstack-maintainer.md +128 -0
  218. package/skills/youstack-start.md +78 -0
@@ -0,0 +1,350 @@
1
+ "use strict";
2
+ /**
3
+ * Host-link engine — the ONE implementation that links You.md skills and
4
+ * YouStack adapters into agent hosts (Claude Code, Codex, Cursor, fallback).
5
+ *
6
+ * P11 / PRODUCT-AUDIT #13 / FEATURE-ROADMAP 3.7: there used to be multiple
7
+ * drifting per-host link code paths (youstack.ts switch + skills.ts switch).
8
+ * They are consolidated here. Hosts differ ONLY by adapter config (target
9
+ * dir, file naming, frontmatter shape) — never by separate code paths.
10
+ *
11
+ * Claude Code discovery contract (the empirical release gate):
12
+ * - every linked skill lands at `.claude/skills/<skill-name>/SKILL.md`
13
+ * - SKILL.md frontmatter parses and has non-empty `name` + `description`
14
+ * - frontmatter `name` matches the skill directory name
15
+ * - the skill body is non-empty
16
+ */
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || (function () {
34
+ var ownKeys = function(o) {
35
+ ownKeys = Object.getOwnPropertyNames || function (o) {
36
+ var ar = [];
37
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
38
+ return ar;
39
+ };
40
+ return ownKeys(o);
41
+ };
42
+ return function (mod) {
43
+ if (mod && mod.__esModule) return mod;
44
+ var result = {};
45
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
46
+ __setModuleDefault(result, mod);
47
+ return result;
48
+ };
49
+ })();
50
+ var __importDefault = (this && this.__importDefault) || function (mod) {
51
+ return (mod && mod.__esModule) ? mod : { "default": mod };
52
+ };
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.youStackHostAdapterConfig = youStackHostAdapterConfig;
55
+ exports.installedSkillsHostAdapterConfig = installedSkillsHostAdapterConfig;
56
+ exports.isSafeHostRelativePath = isSafeHostRelativePath;
57
+ exports.ensureSkillFrontmatter = ensureSkillFrontmatter;
58
+ exports.hostLinkRelativePath = hostLinkRelativePath;
59
+ exports.buildHostLinkPlan = buildHostLinkPlan;
60
+ exports.writeHostLinkPlan = writeHostLinkPlan;
61
+ exports.verifySkillDiscoveryEntry = verifySkillDiscoveryEntry;
62
+ exports.verifySkillDiscovery = verifySkillDiscovery;
63
+ exports.verifySkillFilesOnDisk = verifySkillFilesOnDisk;
64
+ exports.hasLinkedClaudeSkills = hasLinkedClaudeSkills;
65
+ const fs = __importStar(require("fs"));
66
+ const path = __importStar(require("path"));
67
+ const gray_matter_1 = __importDefault(require("gray-matter"));
68
+ // ─── Built-in adapter configs ─────────────────────────────────────────
69
+ /** Adapter configs for YouStack manifest links (`youmd stack link`). */
70
+ function youStackHostAdapterConfig(host) {
71
+ switch (host) {
72
+ case "claude-code":
73
+ // P11 fix: Claude Code only discovers `.claude/skills/<name>/SKILL.md`.
74
+ // The legacy `.claude/skills/youstacks/<slug>/SKILL.md` nesting was
75
+ // never picked up by the host.
76
+ return {
77
+ host,
78
+ layout: "skill-dir",
79
+ rootSegments: [".claude", "skills"],
80
+ frontmatter: "ensure",
81
+ };
82
+ case "codex":
83
+ return {
84
+ host,
85
+ layout: "skill-dir",
86
+ rootSegments: [".codex", "skills", "youstacks"],
87
+ frontmatter: "ensure",
88
+ };
89
+ case "cursor":
90
+ return {
91
+ host,
92
+ layout: "flat-file",
93
+ rootSegments: [".cursor", "rules"],
94
+ filePrefix: "youstacks-",
95
+ frontmatter: "none",
96
+ };
97
+ default:
98
+ return {
99
+ host,
100
+ layout: "flat-file",
101
+ rootSegments: [".you", "adapters", host],
102
+ frontmatter: "none",
103
+ };
104
+ }
105
+ }
106
+ /** Adapter configs for installed-skill links (`youmd skill link`). */
107
+ function installedSkillsHostAdapterConfig(target) {
108
+ switch (target) {
109
+ case "claude":
110
+ // P11 fix: was `.claude/skills/youmd/<name>.md` — flat .md files that
111
+ // Claude Code never discovers. Now `.claude/skills/<name>/SKILL.md`.
112
+ return {
113
+ host: "claude-code",
114
+ layout: "skill-dir",
115
+ rootSegments: [".claude", "skills"],
116
+ frontmatter: "ensure",
117
+ };
118
+ case "codex":
119
+ return {
120
+ host: "codex",
121
+ layout: "flat-file",
122
+ rootSegments: [".codex", "skills", "youmd"],
123
+ frontmatter: "none",
124
+ };
125
+ case "cursor":
126
+ return {
127
+ host: "cursor",
128
+ layout: "concat-file",
129
+ rootSegments: [".cursor", "rules"],
130
+ concatFileName: "youmd.md",
131
+ concatHeaderParts: [
132
+ "# You.md Identity Skills\n",
133
+ "> Auto-generated by youmd skill link. Do not edit manually.\n",
134
+ ],
135
+ frontmatter: "none",
136
+ };
137
+ }
138
+ }
139
+ // ─── Helpers ──────────────────────────────────────────────────────────
140
+ function isSafeHostRelativePath(value) {
141
+ if (!value || path.isAbsolute(value) || value.startsWith("~"))
142
+ return false;
143
+ const parts = value.split(/[\\/]+/);
144
+ return !parts.includes("..");
145
+ }
146
+ function isSafeUnitName(name) {
147
+ return isSafeHostRelativePath(name) && !name.includes("/") && !name.includes("\\");
148
+ }
149
+ function parseFrontmatter(content) {
150
+ try {
151
+ const parsed = (0, gray_matter_1.default)(content);
152
+ return { data: parsed.data, body: parsed.content };
153
+ }
154
+ catch {
155
+ return null;
156
+ }
157
+ }
158
+ function hasFrontmatterBlock(content) {
159
+ return /^---\r?\n/.test(content);
160
+ }
161
+ /**
162
+ * Guarantee that skill content carries parseable frontmatter with a `name`
163
+ * matching the skill's directory and a non-empty `description` — the
164
+ * conditions Claude Code requires for discovery.
165
+ *
166
+ * Content that already satisfies the contract passes through byte-identical.
167
+ */
168
+ function ensureSkillFrontmatter(content, name, fallbackDescription) {
169
+ const parsed = parseFrontmatter(content);
170
+ if (parsed && hasFrontmatterBlock(content)) {
171
+ const fmName = typeof parsed.data.name === "string" ? parsed.data.name.trim() : "";
172
+ const fmDescription = typeof parsed.data.description === "string" ? parsed.data.description.trim() : "";
173
+ if (fmName === name && fmDescription && parsed.body.trim().length > 0) {
174
+ return content;
175
+ }
176
+ }
177
+ const body = parsed ? parsed.body : content;
178
+ const data = parsed ? { ...parsed.data } : {};
179
+ const description = typeof data.description === "string" && data.description.trim().length > 0
180
+ ? data.description
181
+ : fallbackDescription || `${name} (linked by You.md)`;
182
+ const extraKeys = Object.keys(data).filter((key) => key !== "name" && key !== "description");
183
+ if (extraKeys.length === 0) {
184
+ // Deterministic minimal emission — byte-compatible with the legacy
185
+ // stack-adapter frontmatter shape.
186
+ return `---\nname: ${name}\ndescription: ${description}\n---\n\n${body.replace(/^\r?\n/, "")}`;
187
+ }
188
+ return gray_matter_1.default.stringify(body.replace(/^\r?\n/, ""), { ...data, name, description });
189
+ }
190
+ function renderUnitContent(unit, config) {
191
+ if (config.frontmatter === "ensure") {
192
+ return ensureSkillFrontmatter(unit.content, unit.name, unit.description);
193
+ }
194
+ return unit.content;
195
+ }
196
+ /** Default relative path the engine emits for one skill on a host. */
197
+ function hostLinkRelativePath(config, name) {
198
+ if (config.layout === "skill-dir") {
199
+ return path.join(...config.rootSegments, name, "SKILL.md");
200
+ }
201
+ if (config.layout === "concat-file") {
202
+ return path.join(...config.rootSegments, config.concatFileName || "youmd.md");
203
+ }
204
+ return path.join(...config.rootSegments, `${config.filePrefix || ""}${name}.md`);
205
+ }
206
+ // ─── Plan + write ─────────────────────────────────────────────────────
207
+ /**
208
+ * Build the per-host link plan: paths + rendered content.
209
+ *
210
+ * `explicitRelativePaths` lets a manifest declare adapter output paths that
211
+ * override the host's default layout (existing youstack.json behavior).
212
+ */
213
+ function buildHostLinkPlan(units, config, options = {}) {
214
+ for (const unit of units) {
215
+ if (!isSafeUnitName(unit.name)) {
216
+ throw new Error(`Unsafe skill name for ${config.host}: ${unit.name}`);
217
+ }
218
+ }
219
+ let entries;
220
+ if (options.explicitRelativePaths && options.explicitRelativePaths.length > 0) {
221
+ // Declared adapter paths share the host-rendered content of the unit.
222
+ const content = units.length > 0 ? renderUnitContent(units[0], config) : "";
223
+ entries = options.explicitRelativePaths.map((relativePath) => ({
224
+ host: config.host,
225
+ relativePath,
226
+ content,
227
+ }));
228
+ }
229
+ else if (config.layout === "concat-file") {
230
+ const parts = [...(config.concatHeaderParts || [])];
231
+ for (const unit of units) {
232
+ parts.push(`\n---\n\n## ${unit.name}\n\n${renderUnitContent(unit, config)}`);
233
+ }
234
+ entries = [
235
+ {
236
+ host: config.host,
237
+ relativePath: hostLinkRelativePath(config, ""),
238
+ content: parts.join("\n"),
239
+ },
240
+ ];
241
+ }
242
+ else {
243
+ entries = units.map((unit) => ({
244
+ host: config.host,
245
+ relativePath: hostLinkRelativePath(config, unit.name),
246
+ content: renderUnitContent(unit, config),
247
+ }));
248
+ }
249
+ for (const entry of entries) {
250
+ if (!isSafeHostRelativePath(entry.relativePath)) {
251
+ throw new Error(`Unsafe adapter path for ${config.host}: ${entry.relativePath}`);
252
+ }
253
+ }
254
+ return entries;
255
+ }
256
+ /** Write a link plan under `targetDir` (or preview it with dryRun). */
257
+ function writeHostLinkPlan(plan, targetDir, options = {}) {
258
+ const resolvedTarget = path.resolve(targetDir);
259
+ return plan.map((entry) => {
260
+ const targetPath = path.join(resolvedTarget, entry.relativePath);
261
+ if (!options.dryRun) {
262
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
263
+ fs.writeFileSync(targetPath, entry.content);
264
+ }
265
+ return { ...entry, targetPath, wrote: !options.dryRun };
266
+ });
267
+ }
268
+ // ─── Empirical discovery release gate ─────────────────────────────────
269
+ /**
270
+ * Verify one emitted SKILL.md against the Claude Code discovery contract:
271
+ * parseable frontmatter, non-empty name + description, name matching the
272
+ * parent directory, non-empty body.
273
+ */
274
+ function verifySkillDiscoveryEntry(filePath, content) {
275
+ const problems = [];
276
+ let data = {};
277
+ let body = "";
278
+ try {
279
+ const parsed = (0, gray_matter_1.default)(content);
280
+ data = parsed.data;
281
+ body = parsed.content;
282
+ }
283
+ catch (error) {
284
+ const message = error instanceof Error ? error.message.split("\n")[0] : String(error);
285
+ problems.push(`frontmatter does not parse: ${message}`);
286
+ }
287
+ let fmName = "";
288
+ if (problems.length === 0) {
289
+ if (!hasFrontmatterBlock(content)) {
290
+ problems.push("missing frontmatter block (--- ... ---)");
291
+ }
292
+ fmName = typeof data.name === "string" ? data.name.trim() : "";
293
+ const fmDescription = typeof data.description === "string" ? data.description.trim() : "";
294
+ if (!fmName)
295
+ problems.push("frontmatter is missing name");
296
+ if (!fmDescription)
297
+ problems.push("frontmatter is missing description");
298
+ const dirName = path.basename(path.dirname(filePath));
299
+ if (fmName && path.basename(filePath) === "SKILL.md" && fmName !== dirName) {
300
+ problems.push(`frontmatter name "${fmName}" does not match its directory "${dirName}"`);
301
+ }
302
+ if (body.trim().length === 0)
303
+ problems.push("skill body is empty");
304
+ }
305
+ return { path: filePath, name: fmName, ok: problems.length === 0, problems };
306
+ }
307
+ /**
308
+ * Verify every SKILL.md in a set of emitted link entries (plan entries or
309
+ * write results). Non-SKILL.md outputs (cursor rules, fallback adapters)
310
+ * are not discovery surfaces and are skipped.
311
+ */
312
+ function verifySkillDiscovery(entries) {
313
+ const checks = entries
314
+ .map((entry) => ({ filePath: entry.targetPath || entry.relativePath || "", content: entry.content }))
315
+ .filter((entry) => path.basename(entry.filePath) === "SKILL.md")
316
+ .map((entry) => verifySkillDiscoveryEntry(entry.filePath, entry.content));
317
+ return { ok: checks.every((check) => check.ok), checks };
318
+ }
319
+ /**
320
+ * CI helper: verify every `<skillsRoot>/<name>/SKILL.md` on disk (e.g.
321
+ * `.claude/skills/`) against the discovery contract.
322
+ */
323
+ function verifySkillFilesOnDisk(skillsRoot) {
324
+ const checks = [];
325
+ if (fs.existsSync(skillsRoot) && fs.statSync(skillsRoot).isDirectory()) {
326
+ for (const entry of fs.readdirSync(skillsRoot, { withFileTypes: true })) {
327
+ if (!entry.isDirectory())
328
+ continue;
329
+ const skillPath = path.join(skillsRoot, entry.name, "SKILL.md");
330
+ if (!fs.existsSync(skillPath))
331
+ continue;
332
+ checks.push(verifySkillDiscoveryEntry(skillPath, fs.readFileSync(skillPath, "utf-8")));
333
+ }
334
+ }
335
+ return { ok: checks.every((check) => check.ok), checks };
336
+ }
337
+ /**
338
+ * Detection helper: have any of the given skills been linked into the
339
+ * Claude Code discovery layout under `root`? Also recognizes the legacy
340
+ * `.claude/skills/youmd/` directory so older links still count.
341
+ */
342
+ function hasLinkedClaudeSkills(root, skillNames) {
343
+ const skillsRoot = path.join(root, ".claude", "skills");
344
+ for (const name of skillNames) {
345
+ if (fs.existsSync(path.join(skillsRoot, name, "SKILL.md")))
346
+ return true;
347
+ }
348
+ return fs.existsSync(path.join(skillsRoot, "youmd"));
349
+ }
350
+ //# sourceMappingURL=host-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-link.js","sourceRoot":"","sources":["../../src/lib/host-link.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Per-section 3-way merge for identity bundles (you-md/v1).
3
+ *
4
+ * Pure functions — no fs, no network — so the merge logic is unit-testable
5
+ * in isolation. The caller (sync) is responsible for loading base.json,
6
+ * compiling the local bundle, fetching the remote bundle, and writing the
7
+ * merged result to disk (atomically: all-or-nothing).
8
+ *
9
+ * A "section" is a top-level key of the nested you.json format (identity,
10
+ * now, projects, values, links, preferences, voice, agent_directives,
11
+ * custom_sections, ...). For each section we compare base vs local vs remote:
12
+ *
13
+ * - neither changed → keep as-is
14
+ * - only local changed → keep local
15
+ * - only remote changed → take remote
16
+ * - both changed identically → keep (no conflict)
17
+ * - both changed differently → CONFLICT (section listed, merge not clean)
18
+ */
19
+ export type SectionDecision = "unchanged" | "keep-local" | "take-remote" | "both-equal" | "conflict";
20
+ export interface SectionResult {
21
+ section: string;
22
+ decision: SectionDecision;
23
+ }
24
+ export interface MergeResult {
25
+ /** The merged bundle. Only meaningful when `clean` is true. */
26
+ merged: Record<string, unknown>;
27
+ /** Sections where local and remote both changed, differently. */
28
+ conflicts: string[];
29
+ /** Per-section decision detail (scaffold keys excluded). */
30
+ sections: SectionResult[];
31
+ /** True when every section merged without conflict. */
32
+ clean: boolean;
33
+ }
34
+ /**
35
+ * Normalize a section value for change detection, stripping fields the
36
+ * compiler re-stamps on every compile (so a recompile alone never reads as
37
+ * an edit). Currently: `now.updated_at`.
38
+ */
39
+ export declare function normalizeSection(section: string, value: unknown): string;
40
+ /**
41
+ * Per-section 3-way merge of base (common ancestor) vs local vs remote.
42
+ *
43
+ * Returns the merged bundle plus the list of conflicting sections. Callers
44
+ * MUST treat the merge as atomic: if `conflicts` is non-empty (`clean` is
45
+ * false), write nothing and surface the conflicts to the user.
46
+ */
47
+ export declare function mergeSections(base: Record<string, unknown> | null | undefined, local: Record<string, unknown> | null | undefined, remote: Record<string, unknown> | null | undefined): MergeResult;
48
+ /** Human-readable label for a section decision (terminal output). */
49
+ export declare function decisionLabel(decision: SectionDecision): string;
50
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/lib/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAyBH,MAAM,MAAM,eAAe,GACvB,WAAW,GACX,YAAY,GACZ,aAAa,GACb,YAAY,GACZ,UAAU,CAAC;AAEf,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,iEAAiE;IACjE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,4DAA4D;IAC5D,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,uDAAuD;IACvD,KAAK,EAAE,OAAO,CAAC;CAChB;AAsBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAQxE;AAWD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACjD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GACjD,WAAW,CAyDb;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAa/D"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /**
3
+ * Per-section 3-way merge for identity bundles (you-md/v1).
4
+ *
5
+ * Pure functions — no fs, no network — so the merge logic is unit-testable
6
+ * in isolation. The caller (sync) is responsible for loading base.json,
7
+ * compiling the local bundle, fetching the remote bundle, and writing the
8
+ * merged result to disk (atomically: all-or-nothing).
9
+ *
10
+ * A "section" is a top-level key of the nested you.json format (identity,
11
+ * now, projects, values, links, preferences, voice, agent_directives,
12
+ * custom_sections, ...). For each section we compare base vs local vs remote:
13
+ *
14
+ * - neither changed → keep as-is
15
+ * - only local changed → keep local
16
+ * - only remote changed → take remote
17
+ * - both changed identically → keep (no conflict)
18
+ * - both changed differently → CONFLICT (section listed, merge not clean)
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.normalizeSection = normalizeSection;
22
+ exports.mergeSections = mergeSections;
23
+ exports.decisionLabel = decisionLabel;
24
+ // Scaffolding/volatile keys are never merged per-section — they are stamped
25
+ // by the compiler on every compile (generated_at, meta.last_updated) or are
26
+ // structural (schema, username). The merged bundle takes them from remote,
27
+ // falling back to local, falling back to base.
28
+ const SCAFFOLD_KEYS = new Set(["schema", "username", "generated_at", "meta"]);
29
+ // Canonical section ordering so merged you.json reads like compiler output.
30
+ const KNOWN_SECTION_ORDER = [
31
+ "identity",
32
+ "now",
33
+ "projects",
34
+ "values",
35
+ "links",
36
+ "preferences",
37
+ "voice",
38
+ "analysis",
39
+ "social_images",
40
+ "agent_directives",
41
+ "agent_guide",
42
+ "custom_sections",
43
+ "verification",
44
+ ];
45
+ /**
46
+ * Deterministic stringification for equality comparison only (object keys
47
+ * sorted recursively). Does NOT need to match the server's canonical hash
48
+ * format — it is never hashed or persisted.
49
+ */
50
+ function stableStringify(value) {
51
+ if (value === null || value === undefined)
52
+ return "null";
53
+ if (typeof value === "string")
54
+ return JSON.stringify(value);
55
+ if (typeof value === "number" || typeof value === "boolean")
56
+ return String(value);
57
+ if (Array.isArray(value)) {
58
+ return "[" + value.map(stableStringify).join(",") + "]";
59
+ }
60
+ if (typeof value === "object") {
61
+ const obj = value;
62
+ const keys = Object.keys(obj).sort();
63
+ return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
64
+ }
65
+ return String(value);
66
+ }
67
+ /**
68
+ * Normalize a section value for change detection, stripping fields the
69
+ * compiler re-stamps on every compile (so a recompile alone never reads as
70
+ * an edit). Currently: `now.updated_at`.
71
+ */
72
+ function normalizeSection(section, value) {
73
+ let v = value;
74
+ if (section === "now" && v && typeof v === "object" && !Array.isArray(v)) {
75
+ const cleaned = { ...v };
76
+ delete cleaned.updated_at;
77
+ v = cleaned;
78
+ }
79
+ return stableStringify(v);
80
+ }
81
+ function orderSectionKeys(keys) {
82
+ const ordered = [];
83
+ for (const k of KNOWN_SECTION_ORDER) {
84
+ if (keys.has(k))
85
+ ordered.push(k);
86
+ }
87
+ const rest = [...keys].filter((k) => !KNOWN_SECTION_ORDER.includes(k)).sort();
88
+ return [...ordered, ...rest];
89
+ }
90
+ /**
91
+ * Per-section 3-way merge of base (common ancestor) vs local vs remote.
92
+ *
93
+ * Returns the merged bundle plus the list of conflicting sections. Callers
94
+ * MUST treat the merge as atomic: if `conflicts` is non-empty (`clean` is
95
+ * false), write nothing and surface the conflicts to the user.
96
+ */
97
+ function mergeSections(base, local, remote) {
98
+ const b = base || {};
99
+ const l = local || {};
100
+ const r = remote || {};
101
+ const allKeys = new Set([...Object.keys(b), ...Object.keys(l), ...Object.keys(r)]);
102
+ const merged = {};
103
+ const conflicts = [];
104
+ const sections = [];
105
+ // Scaffold keys first (schema/username/generated_at/meta), in known order.
106
+ for (const key of ["schema", "username", "generated_at"]) {
107
+ if (!allKeys.has(key))
108
+ continue;
109
+ merged[key] = key in r ? r[key] : key in l ? l[key] : b[key];
110
+ }
111
+ for (const key of orderSectionKeys(allKeys)) {
112
+ if (SCAFFOLD_KEYS.has(key))
113
+ continue;
114
+ const baseN = normalizeSection(key, key in b ? b[key] : undefined);
115
+ const localN = normalizeSection(key, key in l ? l[key] : undefined);
116
+ const remoteN = normalizeSection(key, key in r ? r[key] : undefined);
117
+ const localChanged = localN !== baseN;
118
+ const remoteChanged = remoteN !== baseN;
119
+ let decision;
120
+ let value;
121
+ if (!localChanged && !remoteChanged) {
122
+ decision = "unchanged";
123
+ value = key in l ? l[key] : key in r ? r[key] : b[key];
124
+ }
125
+ else if (localChanged && !remoteChanged) {
126
+ decision = "keep-local";
127
+ value = l[key];
128
+ }
129
+ else if (!localChanged && remoteChanged) {
130
+ decision = "take-remote";
131
+ value = r[key];
132
+ }
133
+ else if (localN === remoteN) {
134
+ decision = "both-equal";
135
+ value = l[key];
136
+ }
137
+ else {
138
+ decision = "conflict";
139
+ conflicts.push(key);
140
+ value = l[key]; // placeholder — merged must not be written when dirty
141
+ }
142
+ sections.push({ section: key, decision });
143
+ if (value !== undefined)
144
+ merged[key] = value;
145
+ }
146
+ // meta last — taken from remote (compiler re-stamps it on next compile).
147
+ if (allKeys.has("meta")) {
148
+ merged.meta = "meta" in r ? r.meta : "meta" in l ? l.meta : b.meta;
149
+ }
150
+ return { merged, conflicts, sections, clean: conflicts.length === 0 };
151
+ }
152
+ /** Human-readable label for a section decision (terminal output). */
153
+ function decisionLabel(decision) {
154
+ switch (decision) {
155
+ case "unchanged":
156
+ return "unchanged";
157
+ case "keep-local":
158
+ return "kept local";
159
+ case "take-remote":
160
+ return "took remote";
161
+ case "both-equal":
162
+ return "both sides match";
163
+ case "conflict":
164
+ return "conflict";
165
+ }
166
+ }
167
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/lib/merge.ts"],"names":[],"mappings":"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"}