@design-intelligence/ghost 0.0.0-next-20260715121453

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 (327) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +89 -0
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +19 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/cli.d.ts +4 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +29 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/commands/checks-command.d.ts +9 -0
  12. package/dist/commands/checks-command.d.ts.map +1 -0
  13. package/dist/commands/checks-command.js +52 -0
  14. package/dist/commands/checks-command.js.map +1 -0
  15. package/dist/commands/command-discovery.d.ts +57 -0
  16. package/dist/commands/command-discovery.d.ts.map +1 -0
  17. package/dist/commands/command-discovery.js +220 -0
  18. package/dist/commands/command-discovery.js.map +1 -0
  19. package/dist/commands/errors.d.ts +7 -0
  20. package/dist/commands/errors.d.ts.map +1 -0
  21. package/dist/commands/errors.js +19 -0
  22. package/dist/commands/errors.js.map +1 -0
  23. package/dist/commands/export-command.d.ts +3 -0
  24. package/dist/commands/export-command.d.ts.map +1 -0
  25. package/dist/commands/export-command.js +157 -0
  26. package/dist/commands/export-command.js.map +1 -0
  27. package/dist/commands/fingerprint-commands.d.ts +10 -0
  28. package/dist/commands/fingerprint-commands.d.ts.map +1 -0
  29. package/dist/commands/fingerprint-commands.js +69 -0
  30. package/dist/commands/fingerprint-commands.js.map +1 -0
  31. package/dist/commands/gather-command.d.ts +3 -0
  32. package/dist/commands/gather-command.d.ts.map +1 -0
  33. package/dist/commands/gather-command.js +214 -0
  34. package/dist/commands/gather-command.js.map +1 -0
  35. package/dist/commands/init-command.d.ts +3 -0
  36. package/dist/commands/init-command.d.ts.map +1 -0
  37. package/dist/commands/init-command.js +89 -0
  38. package/dist/commands/init-command.js.map +1 -0
  39. package/dist/commands/manifest-command.d.ts +9 -0
  40. package/dist/commands/manifest-command.d.ts.map +1 -0
  41. package/dist/commands/manifest-command.js +33 -0
  42. package/dist/commands/manifest-command.js.map +1 -0
  43. package/dist/commands/pull-command.d.ts +3 -0
  44. package/dist/commands/pull-command.d.ts.map +1 -0
  45. package/dist/commands/pull-command.js +230 -0
  46. package/dist/commands/pull-command.js.map +1 -0
  47. package/dist/commands/pulse-command.d.ts +3 -0
  48. package/dist/commands/pulse-command.d.ts.map +1 -0
  49. package/dist/commands/pulse-command.js +248 -0
  50. package/dist/commands/pulse-command.js.map +1 -0
  51. package/dist/commands/review-command.d.ts +3 -0
  52. package/dist/commands/review-command.d.ts.map +1 -0
  53. package/dist/commands/review-command.js +78 -0
  54. package/dist/commands/review-command.js.map +1 -0
  55. package/dist/commands/skill-command.d.ts +3 -0
  56. package/dist/commands/skill-command.d.ts.map +1 -0
  57. package/dist/commands/skill-command.js +96 -0
  58. package/dist/commands/skill-command.js.map +1 -0
  59. package/dist/fingerprint.d.ts +5 -0
  60. package/dist/fingerprint.d.ts.map +1 -0
  61. package/dist/fingerprint.js +3 -0
  62. package/dist/fingerprint.js.map +1 -0
  63. package/dist/ghost-core/catalog/assemble.d.ts +26 -0
  64. package/dist/ghost-core/catalog/assemble.d.ts.map +1 -0
  65. package/dist/ghost-core/catalog/assemble.js +29 -0
  66. package/dist/ghost-core/catalog/assemble.js.map +1 -0
  67. package/dist/ghost-core/catalog/closest.d.ts +16 -0
  68. package/dist/ghost-core/catalog/closest.d.ts.map +1 -0
  69. package/dist/ghost-core/catalog/closest.js +63 -0
  70. package/dist/ghost-core/catalog/closest.js.map +1 -0
  71. package/dist/ghost-core/catalog/index.d.ts +10 -0
  72. package/dist/ghost-core/catalog/index.d.ts.map +1 -0
  73. package/dist/ghost-core/catalog/index.js +9 -0
  74. package/dist/ghost-core/catalog/index.js.map +1 -0
  75. package/dist/ghost-core/catalog/menu.d.ts +28 -0
  76. package/dist/ghost-core/catalog/menu.d.ts.map +1 -0
  77. package/dist/ghost-core/catalog/menu.js +23 -0
  78. package/dist/ghost-core/catalog/menu.js.map +1 -0
  79. package/dist/ghost-core/catalog/types.d.ts +33 -0
  80. package/dist/ghost-core/catalog/types.d.ts.map +1 -0
  81. package/dist/ghost-core/catalog/types.js +2 -0
  82. package/dist/ghost-core/catalog/types.js.map +1 -0
  83. package/dist/ghost-core/check/index.d.ts +12 -0
  84. package/dist/ghost-core/check/index.d.ts.map +1 -0
  85. package/dist/ghost-core/check/index.js +12 -0
  86. package/dist/ghost-core/check/index.js.map +1 -0
  87. package/dist/ghost-core/check/lint.d.ts +9 -0
  88. package/dist/ghost-core/check/lint.d.ts.map +1 -0
  89. package/dist/ghost-core/check/lint.js +119 -0
  90. package/dist/ghost-core/check/lint.js.map +1 -0
  91. package/dist/ghost-core/check/load.d.ts +7 -0
  92. package/dist/ghost-core/check/load.d.ts.map +1 -0
  93. package/dist/ghost-core/check/load.js +44 -0
  94. package/dist/ghost-core/check/load.js.map +1 -0
  95. package/dist/ghost-core/check/parse.d.ts +12 -0
  96. package/dist/ghost-core/check/parse.d.ts.map +1 -0
  97. package/dist/ghost-core/check/parse.js +13 -0
  98. package/dist/ghost-core/check/parse.js.map +1 -0
  99. package/dist/ghost-core/check/source-ref.d.ts +27 -0
  100. package/dist/ghost-core/check/source-ref.d.ts.map +1 -0
  101. package/dist/ghost-core/check/source-ref.js +58 -0
  102. package/dist/ghost-core/check/source-ref.js.map +1 -0
  103. package/dist/ghost-core/check/types.d.ts +48 -0
  104. package/dist/ghost-core/check/types.d.ts.map +1 -0
  105. package/dist/ghost-core/check/types.js +4 -0
  106. package/dist/ghost-core/check/types.js.map +1 -0
  107. package/dist/ghost-core/errors.d.ts +30 -0
  108. package/dist/ghost-core/errors.d.ts.map +1 -0
  109. package/dist/ghost-core/errors.js +33 -0
  110. package/dist/ghost-core/errors.js.map +1 -0
  111. package/dist/ghost-core/glob.d.ts +5 -0
  112. package/dist/ghost-core/glob.d.ts.map +1 -0
  113. package/dist/ghost-core/glob.js +68 -0
  114. package/dist/ghost-core/glob.js.map +1 -0
  115. package/dist/ghost-core/glossary.d.ts +25 -0
  116. package/dist/ghost-core/glossary.d.ts.map +1 -0
  117. package/dist/ghost-core/glossary.js +69 -0
  118. package/dist/ghost-core/glossary.js.map +1 -0
  119. package/dist/ghost-core/index.d.ts +13 -0
  120. package/dist/ghost-core/index.d.ts.map +1 -0
  121. package/dist/ghost-core/index.js +19 -0
  122. package/dist/ghost-core/index.js.map +1 -0
  123. package/dist/ghost-core/markdown.d.ts +15 -0
  124. package/dist/ghost-core/markdown.d.ts.map +1 -0
  125. package/dist/ghost-core/markdown.js +30 -0
  126. package/dist/ghost-core/markdown.js.map +1 -0
  127. package/dist/ghost-core/material-transport.d.ts +43 -0
  128. package/dist/ghost-core/material-transport.d.ts.map +1 -0
  129. package/dist/ghost-core/material-transport.js +231 -0
  130. package/dist/ghost-core/material-transport.js.map +1 -0
  131. package/dist/ghost-core/materials.d.ts +14 -0
  132. package/dist/ghost-core/materials.d.ts.map +1 -0
  133. package/dist/ghost-core/materials.js +52 -0
  134. package/dist/ghost-core/materials.js.map +1 -0
  135. package/dist/ghost-core/node/index.d.ts +11 -0
  136. package/dist/ghost-core/node/index.d.ts.map +1 -0
  137. package/dist/ghost-core/node/index.js +11 -0
  138. package/dist/ghost-core/node/index.js.map +1 -0
  139. package/dist/ghost-core/node/parse.d.ts +16 -0
  140. package/dist/ghost-core/node/parse.d.ts.map +1 -0
  141. package/dist/ghost-core/node/parse.js +55 -0
  142. package/dist/ghost-core/node/parse.js.map +1 -0
  143. package/dist/ghost-core/node/schema.d.ts +17 -0
  144. package/dist/ghost-core/node/schema.d.ts.map +1 -0
  145. package/dist/ghost-core/node/schema.js +49 -0
  146. package/dist/ghost-core/node/schema.js.map +1 -0
  147. package/dist/ghost-core/node/serialize.d.ts +12 -0
  148. package/dist/ghost-core/node/serialize.d.ts.map +1 -0
  149. package/dist/ghost-core/node/serialize.js +39 -0
  150. package/dist/ghost-core/node/serialize.js.map +1 -0
  151. package/dist/ghost-core/node/steering.d.ts +19 -0
  152. package/dist/ghost-core/node/steering.d.ts.map +1 -0
  153. package/dist/ghost-core/node/steering.js +68 -0
  154. package/dist/ghost-core/node/steering.js.map +1 -0
  155. package/dist/ghost-core/node/types.d.ts +43 -0
  156. package/dist/ghost-core/node/types.d.ts.map +1 -0
  157. package/dist/ghost-core/node/types.js +2 -0
  158. package/dist/ghost-core/node/types.js.map +1 -0
  159. package/dist/ghost-core/package-manifest.d.ts +19 -0
  160. package/dist/ghost-core/package-manifest.d.ts.map +1 -0
  161. package/dist/ghost-core/package-manifest.js +24 -0
  162. package/dist/ghost-core/package-manifest.js.map +1 -0
  163. package/dist/ghost-core/skill-bundle-loader.d.ts +28 -0
  164. package/dist/ghost-core/skill-bundle-loader.d.ts.map +1 -0
  165. package/dist/ghost-core/skill-bundle-loader.js +51 -0
  166. package/dist/ghost-core/skill-bundle-loader.js.map +1 -0
  167. package/dist/index.d.ts +5 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +5 -0
  170. package/dist/index.js.map +1 -0
  171. package/dist/init-payloads/median/cliche.median.md +86 -0
  172. package/dist/init-payloads/median/median-tells.md +117 -0
  173. package/dist/init-payloads/skeleton/brand.md +23 -0
  174. package/dist/init-payloads/skeleton/context.conversation.md +24 -0
  175. package/dist/init-payloads/skeleton/foundation.color.md +39 -0
  176. package/dist/init-payloads/skeleton/foundation.composition.md +30 -0
  177. package/dist/init-payloads/skeleton/foundation.controls.md +29 -0
  178. package/dist/init-payloads/skeleton/foundation.layout.md +45 -0
  179. package/dist/init-payloads/skeleton/foundation.motion.md +34 -0
  180. package/dist/init-payloads/skeleton/foundation.type.md +44 -0
  181. package/dist/init-payloads/skeleton/foundation.voice.md +29 -0
  182. package/dist/init-payloads/skeleton/glossary.md +39 -0
  183. package/dist/init-payloads/vessel-light/anti-goal.median.md +86 -0
  184. package/dist/init-payloads/vessel-light/anti-goal.tells.md +38 -0
  185. package/dist/init-payloads/vessel-light/checks/conversation-grammar.md +20 -0
  186. package/dist/init-payloads/vessel-light/checks/median-tells.md +103 -0
  187. package/dist/init-payloads/vessel-light/checks/motion-restraint.md +20 -0
  188. package/dist/init-payloads/vessel-light/checks/relationships.md +33 -0
  189. package/dist/init-payloads/vessel-light/checks/shape-matches-job.md +43 -0
  190. package/dist/init-payloads/vessel-light/checks/values.md +51 -0
  191. package/dist/init-payloads/vessel-light/glossary.md +44 -0
  192. package/dist/init-payloads/vessel-light/grammar.color-roles.md +30 -0
  193. package/dist/init-payloads/vessel-light/grammar.conversation.md +30 -0
  194. package/dist/init-payloads/vessel-light/grammar.deletion.md +35 -0
  195. package/dist/init-payloads/vessel-light/grammar.hierarchy.md +58 -0
  196. package/dist/init-payloads/vessel-light/grammar.job.md +54 -0
  197. package/dist/init-payloads/vessel-light/grammar.motion.md +27 -0
  198. package/dist/init-payloads/vessel-light/grammar.rhythm.md +27 -0
  199. package/dist/init-payloads/vessel-light/grammar.surfaces.md +35 -0
  200. package/dist/init-payloads/vessel-light/index.md +33 -0
  201. package/dist/init-payloads/vessel-light/manifest.yml +3 -0
  202. package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Black.woff2 +0 -0
  203. package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Bold.woff2 +0 -0
  204. package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-ExtraBold.woff2 +0 -0
  205. package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Light.woff2 +0 -0
  206. package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Medium.woff2 +0 -0
  207. package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Regular.woff2 +0 -0
  208. package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-SemiBold.woff2 +0 -0
  209. package/dist/init-payloads/vessel-light/materials/primitives.css +351 -0
  210. package/dist/init-payloads/vessel-light/materials/ref/composition.conversation.html +63 -0
  211. package/dist/init-payloads/vessel-light/materials/ref/composition.editorial.html +74 -0
  212. package/dist/init-payloads/vessel-light/materials/ref/composition.form.html +89 -0
  213. package/dist/init-payloads/vessel-light/materials/ref/composition.overlay.html +66 -0
  214. package/dist/init-payloads/vessel-light/materials/ref/composition.table.html +104 -0
  215. package/dist/init-payloads/vessel-light/materials/ref/email.html +80 -0
  216. package/dist/init-payloads/vessel-light/materials/tokens.css +191 -0
  217. package/dist/init-payloads/vessel-light/register.data-density.md +39 -0
  218. package/dist/init-payloads/vessel-light/register.editorial.md +41 -0
  219. package/dist/init-payloads/vessel-light/register.email.md +43 -0
  220. package/dist/init-payloads/vessel-light/signature.palette.md +45 -0
  221. package/dist/init-payloads/vessel-light/signature.shape.md +27 -0
  222. package/dist/init-payloads/vessel-light/signature.temperature.md +44 -0
  223. package/dist/init-payloads/vessel-light/signature.type.md +37 -0
  224. package/dist/internal/fs.d.ts +4 -0
  225. package/dist/internal/fs.d.ts.map +1 -0
  226. package/dist/internal/fs.js +24 -0
  227. package/dist/internal/fs.js.map +1 -0
  228. package/dist/observability-events.d.ts +34 -0
  229. package/dist/observability-events.d.ts.map +1 -0
  230. package/dist/observability-events.js +68 -0
  231. package/dist/observability-events.js.map +1 -0
  232. package/dist/package-version.d.ts +3 -0
  233. package/dist/package-version.d.ts.map +1 -0
  234. package/dist/package-version.js +10 -0
  235. package/dist/package-version.js.map +1 -0
  236. package/dist/review/baseline.d.ts +11 -0
  237. package/dist/review/baseline.d.ts.map +1 -0
  238. package/dist/review/baseline.js +35 -0
  239. package/dist/review/baseline.js.map +1 -0
  240. package/dist/review/diff.d.ts +7 -0
  241. package/dist/review/diff.d.ts.map +1 -0
  242. package/dist/review/diff.js +41 -0
  243. package/dist/review/diff.js.map +1 -0
  244. package/dist/review/glob.d.ts +2 -0
  245. package/dist/review/glob.d.ts.map +1 -0
  246. package/dist/review/glob.js +2 -0
  247. package/dist/review/glob.js.map +1 -0
  248. package/dist/review/probes.d.ts +13 -0
  249. package/dist/review/probes.d.ts.map +1 -0
  250. package/dist/review/probes.js +45 -0
  251. package/dist/review/probes.js.map +1 -0
  252. package/dist/review/resolve.d.ts +28 -0
  253. package/dist/review/resolve.d.ts.map +1 -0
  254. package/dist/review/resolve.js +90 -0
  255. package/dist/review/resolve.js.map +1 -0
  256. package/dist/review/review-packet.d.ts +41 -0
  257. package/dist/review/review-packet.d.ts.map +1 -0
  258. package/dist/review/review-packet.js +128 -0
  259. package/dist/review/review-packet.js.map +1 -0
  260. package/dist/scan/check-files.d.ts +23 -0
  261. package/dist/scan/check-files.d.ts.map +1 -0
  262. package/dist/scan/check-files.js +75 -0
  263. package/dist/scan/check-files.js.map +1 -0
  264. package/dist/scan/check-scaffold.d.ts +8 -0
  265. package/dist/scan/check-scaffold.d.ts.map +1 -0
  266. package/dist/scan/check-scaffold.js +53 -0
  267. package/dist/scan/check-scaffold.js.map +1 -0
  268. package/dist/scan/constants.d.ts +21 -0
  269. package/dist/scan/constants.d.ts.map +1 -0
  270. package/dist/scan/constants.js +21 -0
  271. package/dist/scan/constants.js.map +1 -0
  272. package/dist/scan/file-kind.d.ts +12 -0
  273. package/dist/scan/file-kind.d.ts.map +1 -0
  274. package/dist/scan/file-kind.js +114 -0
  275. package/dist/scan/file-kind.js.map +1 -0
  276. package/dist/scan/fingerprint-package-lint.d.ts +8 -0
  277. package/dist/scan/fingerprint-package-lint.d.ts.map +1 -0
  278. package/dist/scan/fingerprint-package-lint.js +284 -0
  279. package/dist/scan/fingerprint-package-lint.js.map +1 -0
  280. package/dist/scan/fingerprint-package-loader.d.ts +5 -0
  281. package/dist/scan/fingerprint-package-loader.d.ts.map +1 -0
  282. package/dist/scan/fingerprint-package-loader.js +78 -0
  283. package/dist/scan/fingerprint-package-loader.js.map +1 -0
  284. package/dist/scan/fingerprint-package.d.ts +66 -0
  285. package/dist/scan/fingerprint-package.d.ts.map +1 -0
  286. package/dist/scan/fingerprint-package.js +101 -0
  287. package/dist/scan/fingerprint-package.js.map +1 -0
  288. package/dist/scan/index.d.ts +3 -0
  289. package/dist/scan/index.d.ts.map +1 -0
  290. package/dist/scan/index.js +3 -0
  291. package/dist/scan/index.js.map +1 -0
  292. package/dist/scan/lint.d.ts +15 -0
  293. package/dist/scan/lint.d.ts.map +1 -0
  294. package/dist/scan/lint.js +2 -0
  295. package/dist/scan/lint.js.map +1 -0
  296. package/dist/scan/node-files.d.ts +25 -0
  297. package/dist/scan/node-files.d.ts.map +1 -0
  298. package/dist/scan/node-files.js +112 -0
  299. package/dist/scan/node-files.js.map +1 -0
  300. package/dist/scan/package-paths.d.ts +10 -0
  301. package/dist/scan/package-paths.d.ts.map +1 -0
  302. package/dist/scan/package-paths.js +49 -0
  303. package/dist/scan/package-paths.js.map +1 -0
  304. package/dist/scan/packed-payloads.d.ts +4 -0
  305. package/dist/scan/packed-payloads.d.ts.map +1 -0
  306. package/dist/scan/packed-payloads.js +55 -0
  307. package/dist/scan/packed-payloads.js.map +1 -0
  308. package/dist/scan/tarball.d.ts +23 -0
  309. package/dist/scan/tarball.d.ts.map +1 -0
  310. package/dist/scan/tarball.js +145 -0
  311. package/dist/scan/tarball.js.map +1 -0
  312. package/dist/scan/templates.d.ts +42 -0
  313. package/dist/scan/templates.d.ts.map +1 -0
  314. package/dist/scan/templates.js +375 -0
  315. package/dist/scan/templates.js.map +1 -0
  316. package/dist/skill-bundle/SKILL.md +146 -0
  317. package/dist/skill-bundle/references/adapting-a-starter.md +104 -0
  318. package/dist/skill-bundle/references/authoring-scenarios.md +184 -0
  319. package/dist/skill-bundle/references/blocks.md +179 -0
  320. package/dist/skill-bundle/references/brief.md +50 -0
  321. package/dist/skill-bundle/references/capture.md +392 -0
  322. package/dist/skill-bundle/references/concrete-tiers.md +95 -0
  323. package/dist/skill-bundle/references/recall.md +36 -0
  324. package/dist/skill-bundle/references/schema.md +114 -0
  325. package/dist/skill-bundle/references/self-check.md +65 -0
  326. package/dist/skill-bundle/references/steering-audit.md +60 -0
  327. package/package.json +79 -0
@@ -0,0 +1,52 @@
1
+ const URL_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
2
+ /**
3
+ * Classify a material locator. `https://…` locators point outside the repo;
4
+ * everything else is a repo-relative path/glob after validation.
5
+ */
6
+ export function classifyMaterialLocator(value) {
7
+ return value.startsWith("https://")
8
+ ? { kind: "url", value }
9
+ : { kind: "local", value };
10
+ }
11
+ /** Return a human-readable validation error, or null when the locator is valid. */
12
+ export function validateMaterialLocator(value) {
13
+ if (value.trim() !== value) {
14
+ return "material locator must not have leading or trailing whitespace";
15
+ }
16
+ if (value.length === 0) {
17
+ return "material locator must not be empty";
18
+ }
19
+ if (URL_SCHEME.test(value)) {
20
+ if (!value.startsWith("https://")) {
21
+ return "material URL locators must use https://";
22
+ }
23
+ try {
24
+ const url = new URL(value);
25
+ if (url.protocol !== "https:" || url.hostname.length === 0) {
26
+ return "material URL locators must be absolute https URLs";
27
+ }
28
+ return null;
29
+ }
30
+ catch {
31
+ return "material URL locator is not a valid URL";
32
+ }
33
+ }
34
+ if (value.startsWith("/") || value.startsWith("\\")) {
35
+ return "local material locators must be repo-relative, not absolute paths";
36
+ }
37
+ if (/^[a-zA-Z]:[\\/]/.test(value)) {
38
+ return "local material locators must be repo-relative, not absolute paths";
39
+ }
40
+ const normalized = value.replace(/\\/g, "/");
41
+ if (normalized === ".." ||
42
+ normalized.startsWith("../") ||
43
+ normalized.endsWith("/..") ||
44
+ normalized.includes("/../")) {
45
+ return "local material locators must not escape the repo with '..'";
46
+ }
47
+ if (normalized.startsWith("~/")) {
48
+ return "local material locators must be repo-relative, not home-relative paths";
49
+ }
50
+ return null;
51
+ }
52
+ //# sourceMappingURL=materials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"materials.js","sourceRoot":"","sources":["../../src/ghost-core/materials.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAE1C;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAa;IAEb,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC;QACjC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;QACxB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;QAC3B,OAAO,+DAA+D,CAAC;IACzE,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,oCAAoC,CAAC;IAC9C,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,OAAO,yCAAyC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3D,OAAO,mDAAmD,CAAC;YAC7D,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,yCAAyC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,OAAO,mEAAmE,CAAC;IAC7E,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,mEAAmE,CAAC;IAC7E,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC7C,IACE,UAAU,KAAK,IAAI;QACnB,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC;QAC5B,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC1B,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAC3B,CAAC;QACD,OAAO,4DAA4D,CAAC;IACtE,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,OAAO,wEAAwE,CAAC;IAClF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Public surface for `ghost.node/v1` — the node artifact: markdown +
3
+ * frontmatter, the single unit a fingerprint corpus is made of: schema +
4
+ * types + parse + serialize.
5
+ */
6
+ export { lintGhostNode, type ParseNodeResult, parseNode } from "./parse.js";
7
+ export { GhostNodeFrontmatterSchema, NodeIdSchema, NodeRefSchema, } from "./schema.js";
8
+ export { serializeNode } from "./serialize.js";
9
+ export { carriesConcreteMaterial, extractSkeletonFences, extractSkeletonSections, type FencedBlock, hasSubstantialFencedExample, hasThreeLineFence, type SkeletonSection, stripSkeletonSections, } from "./steering.js";
10
+ export { GHOST_NODE_SCHEMA, type GhostNodeDocument, type GhostNodeFrontmatter, type GhostNodeLintIssue, type GhostNodeLintReport, type GhostNodeLintSeverity, } from "./types.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EACL,0BAA0B,EAC1B,YAAY,EACZ,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,WAAW,EAChB,2BAA2B,EAC3B,iBAAiB,EACjB,KAAK,eAAe,EACpB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Public surface for `ghost.node/v1` — the node artifact: markdown +
3
+ * frontmatter, the single unit a fingerprint corpus is made of: schema +
4
+ * types + parse + serialize.
5
+ */
6
+ export { lintGhostNode, parseNode } from "./parse.js";
7
+ export { GhostNodeFrontmatterSchema, NodeIdSchema, NodeRefSchema, } from "./schema.js";
8
+ export { serializeNode } from "./serialize.js";
9
+ export { carriesConcreteMaterial, extractSkeletonFences, extractSkeletonSections, hasSubstantialFencedExample, hasThreeLineFence, stripSkeletonSections, } from "./steering.js";
10
+ export { GHOST_NODE_SCHEMA, } from "./types.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ghost-core/node/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAwB,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EACL,0BAA0B,EAC1B,YAAY,EACZ,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EAEvB,2BAA2B,EAC3B,iBAAiB,EAEjB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,GAMlB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { GhostNodeDocument, GhostNodeLintReport } from "./types.js";
2
+ export interface ParseNodeResult {
3
+ /** The validated node, or null when the artifact failed to parse/validate. */
4
+ node: GhostNodeDocument | null;
5
+ report: GhostNodeLintReport;
6
+ }
7
+ /**
8
+ * Parse and validate a single `ghost.node/v1` markdown artifact (frontmatter +
9
+ * prose body) in isolation. Per-node only: frontmatter shape, material
10
+ * locators, and a non-empty prose body. Corpus-level rules (glossary kind
11
+ * prefixes, check references) are a later phase.
12
+ */
13
+ export declare function parseNode(raw: string): ParseNodeResult;
14
+ /** Lint a node artifact, returning only the report (per-node validation). */
15
+ export declare function lintGhostNode(raw: string): GhostNodeLintReport;
16
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/parse.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EAEjB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAWD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAuCtD;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAE9D"}
@@ -0,0 +1,55 @@
1
+ import { splitMarkdownFrontmatter } from "../markdown.js";
2
+ import { GhostNodeFrontmatterSchema } from "./schema.js";
3
+ function finalize(issues) {
4
+ return {
5
+ issues,
6
+ errors: issues.filter((i) => i.severity === "error").length,
7
+ warnings: issues.filter((i) => i.severity === "warning").length,
8
+ info: issues.filter((i) => i.severity === "info").length,
9
+ };
10
+ }
11
+ /**
12
+ * Parse and validate a single `ghost.node/v1` markdown artifact (frontmatter +
13
+ * prose body) in isolation. Per-node only: frontmatter shape, material
14
+ * locators, and a non-empty prose body. Corpus-level rules (glossary kind
15
+ * prefixes, check references) are a later phase.
16
+ */
17
+ export function parseNode(raw) {
18
+ const { frontmatter, body } = splitMarkdownFrontmatter(raw);
19
+ if (frontmatter === null) {
20
+ return {
21
+ node: null,
22
+ report: finalize([
23
+ {
24
+ severity: "error",
25
+ rule: "node-missing-frontmatter",
26
+ message: "node must begin with a YAML frontmatter block (---\\n<yaml>\\n---)",
27
+ },
28
+ ]),
29
+ };
30
+ }
31
+ // The body is design-expression content; surrounding blank lines are not
32
+ // meaningful. Normalize them so serialize → parse round-trips are stable.
33
+ const normalizedBody = body.replace(/^\n+/, "").replace(/\s+$/, "");
34
+ const result = GhostNodeFrontmatterSchema.safeParse(frontmatter);
35
+ if (!result.success) {
36
+ return {
37
+ node: null,
38
+ report: finalize(result.error.issues.map((issue) => ({
39
+ severity: "error",
40
+ rule: `schema/${issue.code}`,
41
+ message: issue.message,
42
+ path: issue.path.length ? issue.path.join(".") : undefined,
43
+ }))),
44
+ };
45
+ }
46
+ return {
47
+ node: { frontmatter: result.data, body: normalizedBody },
48
+ report: finalize([]),
49
+ };
50
+ }
51
+ /** Lint a node artifact, returning only the report (per-node validation). */
52
+ export function lintGhostNode(raw) {
53
+ return parseNode(raw).report;
54
+ }
55
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/ghost-core/node/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAazD,SAAS,QAAQ,CAAC,MAA4B;IAC5C,OAAO;QACL,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM;QAC3D,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM;QAC/D,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM;KACzD,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAC5D,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO;YACL,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,QAAQ,CAAC;gBACf;oBACE,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE,0BAA0B;oBAChC,OAAO,EACL,oEAAoE;iBACvE;aACF,CAAC;SACH,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,0EAA0E;IAC1E,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAEpE,MAAM,MAAM,GAAG,0BAA0B,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO;YACL,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,QAAQ,CACd,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAClC,QAAQ,EAAE,OAAgB;gBAC1B,IAAI,EAAE,UAAU,KAAK,CAAC,IAAI,EAAE;gBAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;aAC3D,CAAC,CAAC,CACJ;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE;QACxD,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;KACrB,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ declare const NodeIdSchema: z.ZodString;
3
+ declare const NodeRefSchema: z.ZodString;
4
+ /**
5
+ * Zod schema for a `ghost.node/v1` frontmatter block.
6
+ *
7
+ * Validates a node in isolation. Identity and containment are not here: they
8
+ * come from the node's file path. Kind is the filename prefix, never a
9
+ * frontmatter field.
10
+ */
11
+ export declare const GhostNodeFrontmatterSchema: z.ZodObject<{
12
+ description: z.ZodOptional<z.ZodString>;
13
+ materials: z.ZodOptional<z.ZodArray<z.ZodString>>;
14
+ relates: z.ZodOptional<z.ZodNever>;
15
+ }, z.core.$loose>;
16
+ export { NodeIdSchema, NodeRefSchema };
17
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,QAAA,MAAM,YAAY,aAGhB,CAAC;AAEH,QAAA,MAAM,aAAa,aAEjB,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B;;;;iBAuBvB,CAAC;AAEjB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ import { validateMaterialLocator } from "../materials.js";
3
+ /**
4
+ * A node id is its path within the package, `.md` dropped (`marketing/email`).
5
+ * Directory nesting is only file organization; it does not create parents,
6
+ * ancestors, or semantic hierarchy. A segment is a permissive lowercase slug
7
+ * (alphanumeric plus `.` `_` `-`); segments join with `/`. No leading,
8
+ * trailing, or doubled slash. Ids are computed by the loader from the file
9
+ * path, never authored in frontmatter.
10
+ */
11
+ const NODE_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*(?:\/[a-z0-9][a-z0-9._-]*)*$/;
12
+ const NodeIdSchema = z.string().min(1).regex(NODE_ID_PATTERN, {
13
+ message: "node id must be a path of lowercase slug segments joined by '/' (alphanumeric plus . _ -, no leading/trailing/doubled slash)",
14
+ });
15
+ const NodeRefSchema = z.string().min(1).regex(NODE_ID_PATTERN, {
16
+ message: "node ref must be a path id like 'marketing/email'",
17
+ });
18
+ /**
19
+ * Zod schema for a `ghost.node/v1` frontmatter block.
20
+ *
21
+ * Validates a node in isolation. Identity and containment are not here: they
22
+ * come from the node's file path. Kind is the filename prefix, never a
23
+ * frontmatter field.
24
+ */
25
+ export const GhostNodeFrontmatterSchema = z
26
+ .object({
27
+ description: z.string().min(1).optional(),
28
+ materials: z
29
+ .array(z
30
+ .string()
31
+ .min(1)
32
+ .superRefine((locator, ctx) => {
33
+ const message = validateMaterialLocator(locator);
34
+ if (message !== null)
35
+ ctx.addIssue({ code: "custom", message });
36
+ }))
37
+ .optional(),
38
+ // `relates` (and all typed edges) were removed. Reject it with a message
39
+ // that names the key so authors get a clear signal.
40
+ relates: z
41
+ .never({ message: "`relates` is a removed key (edges no longer exist)" })
42
+ .optional(),
43
+ })
44
+ // Passthrough, not strict: authors may add free-form descriptive keys
45
+ // (e.g. `audience`, `stage`) that describe what the node is. Ghost does not
46
+ // gate on them — they ride along as part of the node's descriptive surface.
47
+ .passthrough();
48
+ export { NodeIdSchema, NodeRefSchema };
49
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/ghost-core/node/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,eAAe,GAAG,mDAAmD,CAAC;AAE5E,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,EAAE;IAC5D,OAAO,EACL,8HAA8H;CACjI,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,EAAE;IAC7D,OAAO,EAAE,mDAAmD;CAC7D,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC;KACxC,MAAM,CAAC;IACN,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,SAAS,EAAE,CAAC;SACT,KAAK,CACJ,CAAC;SACE,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,WAAW,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;QAC5B,MAAM,OAAO,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,OAAO,KAAK,IAAI;YAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CACL;SACA,QAAQ,EAAE;IACb,yEAAyE;IACzE,oDAAoD;IACpD,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,EAAE,OAAO,EAAE,oDAAoD,EAAE,CAAC;SACxE,QAAQ,EAAE;CACd,CAAC;IACF,sEAAsE;IACtE,4EAA4E;IAC5E,4EAA4E;KAC3E,WAAW,EAAE,CAAC;AAEjB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { GhostNodeDocument, GhostNodeFrontmatter } from "./types.js";
2
+ /**
3
+ * Serialize a node back to its `---\n<yaml>\n---\n<body>` markdown form. Known
4
+ * keys are emitted first in a stable order (description, materials), followed
5
+ * by any free-form descriptive keys in alphabetical order so round-trips and
6
+ * diffs are deterministic. Identity and kind are not serialized — they come
7
+ * from the node's file path and optional filename prefix. Undefined fields are
8
+ * omitted; a node with no frontmatter fields emits an empty block.
9
+ */
10
+ export declare function serializeNode(node: GhostNodeDocument): string;
11
+ export type { GhostNodeFrontmatter };
12
+ //# sourceMappingURL=serialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/serialize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAQ1E;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CA0B7D;AAED,YAAY,EAAE,oBAAoB,EAAE,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { stringify as stringifyYaml } from "yaml";
2
+ const FRONTMATTER_KEY_ORDER = ["description", "materials"];
3
+ function shouldSerializeFrontmatterValue(value) {
4
+ return value !== undefined;
5
+ }
6
+ /**
7
+ * Serialize a node back to its `---\n<yaml>\n---\n<body>` markdown form. Known
8
+ * keys are emitted first in a stable order (description, materials), followed
9
+ * by any free-form descriptive keys in alphabetical order so round-trips and
10
+ * diffs are deterministic. Identity and kind are not serialized — they come
11
+ * from the node's file path and optional filename prefix. Undefined fields are
12
+ * omitted; a node with no frontmatter fields emits an empty block.
13
+ */
14
+ export function serializeNode(node) {
15
+ const fm = node.frontmatter;
16
+ const ordered = {};
17
+ const emitted = new Set();
18
+ for (const key of FRONTMATTER_KEY_ORDER) {
19
+ const value = fm[key];
20
+ if (shouldSerializeFrontmatterValue(value)) {
21
+ ordered[key] = value;
22
+ emitted.add(key);
23
+ }
24
+ }
25
+ for (const key of Object.keys(fm).sort()) {
26
+ if (emitted.has(key))
27
+ continue;
28
+ const value = fm[key];
29
+ if (shouldSerializeFrontmatterValue(value))
30
+ ordered[key] = value;
31
+ }
32
+ // An empty frontmatter object stringifies to "{}"; emit a bare block instead.
33
+ const yaml = Object.keys(ordered).length === 0
34
+ ? ""
35
+ : `${stringifyYaml(ordered).trimEnd()}\n`;
36
+ const body = node.body.replace(/^\n+/, "");
37
+ return `---\n${yaml}---\n${body.length ? `\n${body}\n` : "\n"}`;
38
+ }
39
+ //# sourceMappingURL=serialize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../../src/ghost-core/node/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC;AAGlD,MAAM,qBAAqB,GAAG,CAAC,aAAa,EAAE,WAAW,CAAU,CAAC;AAEpE,SAAS,+BAA+B,CAAC,KAAc;IACrD,OAAO,KAAK,KAAK,SAAS,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,MAAM,EAAE,GAAG,IAAI,CAAC,WAAsC,CAAC;IACvD,MAAM,OAAO,GAA4B,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,MAAM,GAAG,IAAI,qBAAqB,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,+BAA+B,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC/B,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,+BAA+B,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnE,CAAC;IAED,8EAA8E;IAC9E,MAAM,IAAI,GACR,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;QAC/B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3C,OAAO,QAAQ,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAClE,CAAC"}
@@ -0,0 +1,19 @@
1
+ export interface FencedBlock {
2
+ fence: string;
3
+ info?: string;
4
+ content: string;
5
+ }
6
+ export interface SkeletonSection {
7
+ body: string;
8
+ fences: FencedBlock[];
9
+ }
10
+ export declare function carriesConcreteMaterial(input: {
11
+ materials?: string[];
12
+ body: string;
13
+ }): boolean;
14
+ export declare function hasSubstantialFencedExample(body: string): boolean;
15
+ export declare function hasThreeLineFence(body: string): boolean;
16
+ export declare function extractSkeletonSections(body: string): SkeletonSection[];
17
+ export declare function extractSkeletonFences(body: string): FencedBlock[];
18
+ export declare function stripSkeletonSections(body: string): string;
19
+ //# sourceMappingURL=steering.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steering.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/steering.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAMV;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKvD;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE,CASvE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAEjE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAc1D"}
@@ -0,0 +1,68 @@
1
+ const FENCED_BLOCK_PATTERN = /(^|\n)(`{3,}|~{3,})[^\n]*\n([\s\S]*?)\n\2[ \t]*(?=\n|$)/g;
2
+ const SKELETON_HEADING_PATTERN = /^##[ \t]+Skeleton[ \t]*$/gim;
3
+ export function carriesConcreteMaterial(input) {
4
+ return ((input.materials?.length ?? 0) > 0 ||
5
+ hasSubstantialFencedExample(input.body) ||
6
+ extractSkeletonSections(input.body).length > 0);
7
+ }
8
+ export function hasSubstantialFencedExample(body) {
9
+ return hasThreeLineFence(stripSkeletonSections(body));
10
+ }
11
+ export function hasThreeLineFence(body) {
12
+ for (const block of extractFencedBlocks(body)) {
13
+ if (block.content.split(/\r?\n/).length >= 3)
14
+ return true;
15
+ }
16
+ return false;
17
+ }
18
+ export function extractSkeletonSections(body) {
19
+ const headings = [...body.matchAll(SKELETON_HEADING_PATTERN)];
20
+ return headings.map((heading, index) => {
21
+ const start = (heading.index ?? 0) + heading[0].length;
22
+ const next = headings[index + 1];
23
+ const end = next?.index ?? findNextHeading(body, start);
24
+ const sectionBody = body.slice(start, end).trim();
25
+ return { body: sectionBody, fences: extractFencedBlocks(sectionBody) };
26
+ });
27
+ }
28
+ export function extractSkeletonFences(body) {
29
+ return extractSkeletonSections(body).flatMap((section) => section.fences);
30
+ }
31
+ export function stripSkeletonSections(body) {
32
+ const headings = [...body.matchAll(SKELETON_HEADING_PATTERN)];
33
+ if (headings.length === 0)
34
+ return body;
35
+ let stripped = "";
36
+ let cursor = 0;
37
+ for (const heading of headings) {
38
+ const start = heading.index ?? 0;
39
+ const end = findNextHeading(body, start + heading[0].length);
40
+ stripped += body.slice(cursor, start);
41
+ cursor = end;
42
+ }
43
+ stripped += body.slice(cursor);
44
+ return stripped.replace(/\n{3,}/g, "\n\n").trim();
45
+ }
46
+ function extractFencedBlocks(body) {
47
+ const blocks = [];
48
+ for (const match of body.matchAll(FENCED_BLOCK_PATTERN)) {
49
+ const openingLine = body
50
+ .slice((match.index ?? 0) + (match[1]?.length ?? 0))
51
+ .split(/\r?\n/, 1)[0];
52
+ const open = /^(?<fence>`{3,}|~{3,})(?<info>.*)$/.exec(openingLine);
53
+ const fence = open?.groups?.fence ?? match[2] ?? "```";
54
+ const info = open?.groups?.info?.trim();
55
+ blocks.push({
56
+ fence,
57
+ ...(info ? { info } : {}),
58
+ content: match[3] ?? "",
59
+ });
60
+ }
61
+ return blocks;
62
+ }
63
+ function findNextHeading(body, start) {
64
+ const rest = body.slice(start);
65
+ const match = /^#{1,6}[ \t]+.+$/m.exec(rest);
66
+ return match?.index === undefined ? body.length : start + match.index;
67
+ }
68
+ //# sourceMappingURL=steering.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steering.js","sourceRoot":"","sources":["../../../src/ghost-core/node/steering.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export declare const GHOST_NODE_SCHEMA: "ghost.node/v1";
2
+ /**
3
+ * A node's frontmatter: descriptive properties only. Identity, kind, and
4
+ * containment are not here — the file path is the node id, and the optional
5
+ * filename prefix is the kind. The prose body carries the design expression;
6
+ * why / with-what / how-assembled are drafting prompts, never fields.
7
+ */
8
+ export interface GhostNodeFrontmatter {
9
+ /** Free-form descriptive properties parsed from node frontmatter. */
10
+ [key: string]: unknown;
11
+ /**
12
+ * Retrieval payload shown by gather: what the node governs, the observable
13
+ * condition under which it applies, and what it contributes where useful.
14
+ * Together with the node's id, it is how an agent decides applicability.
15
+ * Optional, but strongly encouraged on any node worth anchoring a task at.
16
+ */
17
+ description?: string;
18
+ /**
19
+ * Optional locators for the concrete materials this truth is about: repo-relative
20
+ * paths/globs and absolute https URLs. Guidance stays in prose; this list is
21
+ * only where the agent or review harness can find the material.
22
+ */
23
+ materials?: string[];
24
+ }
25
+ export interface GhostNodeDocument {
26
+ frontmatter: GhostNodeFrontmatter;
27
+ /** The markdown body: prose design expression. */
28
+ body: string;
29
+ }
30
+ export type GhostNodeLintSeverity = "error" | "warning" | "info";
31
+ export interface GhostNodeLintIssue {
32
+ severity: GhostNodeLintSeverity;
33
+ rule: string;
34
+ message: string;
35
+ path?: string;
36
+ }
37
+ export interface GhostNodeLintReport {
38
+ issues: GhostNodeLintIssue[];
39
+ errors: number;
40
+ warnings: number;
41
+ info: number;
42
+ }
43
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,EAAG,eAAwB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,oBAAoB,CAAC;IAClC,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,qBAAqB,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd"}
@@ -0,0 +1,2 @@
1
+ export const GHOST_NODE_SCHEMA = "ghost.node/v1";
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/ghost-core/node/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAwB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+ export declare const GHOST_FINGERPRINT_PACKAGE_SCHEMA: "ghost.fingerprint-package/v1";
3
+ /** `manifest.yml` — anchors a `.ghost/` package. */
4
+ export declare const GhostFingerprintPackageManifestSchema: z.ZodObject<{
5
+ schema: z.ZodLiteral<"ghost.fingerprint-package/v1">;
6
+ id: z.ZodString;
7
+ cover: z.ZodOptional<z.ZodString>;
8
+ }, z.core.$strict>;
9
+ export interface GhostFingerprintPackageManifest {
10
+ schema: typeof GHOST_FINGERPRINT_PACKAGE_SCHEMA;
11
+ id: string;
12
+ /**
13
+ * Optional id of the cover node: the one node gather inlines above the menu on
14
+ * every invocation. Guaranteed presence for content selection cannot retrieve
15
+ * — essence, temperature, brand-level refusals.
16
+ */
17
+ cover?: string;
18
+ }
19
+ //# sourceMappingURL=package-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-manifest.d.ts","sourceRoot":"","sources":["../../src/ghost-core/package-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gCAAgC,EAC3C,8BAAuC,CAAC;AAe1C,oDAAoD;AACpD,eAAO,MAAM,qCAAqC;;;;kBAWvC,CAAC;AAEZ,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,OAAO,gCAAgC,CAAC;IAChD,EAAE,EAAE,MAAM,CAAC;IACX;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ export const GHOST_FINGERPRINT_PACKAGE_SCHEMA = "ghost.fingerprint-package/v1";
3
+ const SlugIdSchema = z
4
+ .string()
5
+ .min(1)
6
+ .regex(/^[a-z0-9][a-z0-9._-]*$/, "id must be a lowercase slug (a-z, 0-9, '.', '_', '-')");
7
+ const NodeIdSchema = z
8
+ .string()
9
+ .min(1)
10
+ .regex(/^[a-z0-9][a-z0-9./_-]*$/, "cover must be a node id");
11
+ /** `manifest.yml` — anchors a `.ghost/` package. */
12
+ export const GhostFingerprintPackageManifestSchema = z
13
+ .object({
14
+ schema: z.literal(GHOST_FINGERPRINT_PACKAGE_SCHEMA),
15
+ id: SlugIdSchema,
16
+ /**
17
+ * Optional id of the cover node: the one node gather inlines above the menu
18
+ * on every invocation. Guaranteed presence for content selection cannot
19
+ * retrieve — essence, temperature, brand-level refusals.
20
+ */
21
+ cover: NodeIdSchema.optional(),
22
+ })
23
+ .strict();
24
+ //# sourceMappingURL=package-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-manifest.js","sourceRoot":"","sources":["../../src/ghost-core/package-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gCAAgC,GAC3C,8BAAuC,CAAC;AAE1C,MAAM,YAAY,GAAG,CAAC;KACnB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,KAAK,CACJ,wBAAwB,EACxB,uDAAuD,CACxD,CAAC;AAEJ,MAAM,YAAY,GAAG,CAAC;KACnB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,KAAK,CAAC,yBAAyB,EAAE,yBAAyB,CAAC,CAAC;AAE/D,oDAAoD;AACpD,MAAM,CAAC,MAAM,qCAAqC,GAAG,CAAC;KACnD,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,gCAAgC,CAAC;IACnD,EAAE,EAAE,YAAY;IAChB;;;;OAIG;IACH,KAAK,EAAE,YAAY,CAAC,QAAQ,EAAE;CAC/B,CAAC;KACD,MAAM,EAAE,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Generic loader for an agentskills.io-compatible skill bundle.
3
+ *
4
+ * Each tool in the Ghost monorepo (`ghost`, `ghost`, …) ships
5
+ * its own skill bundle as real markdown under `src/skill-bundle/` and copies
6
+ * it verbatim to `dist/skill-bundle/` at build time. This loader walks any
7
+ * given root directory and returns a flat, deterministically ordered list of
8
+ * files so the unified `ghost skill install` verb can write them into a target
9
+ * project.
10
+ *
11
+ * Spec: https://agentskills.io/specification
12
+ */
13
+ export interface SkillBundleFile {
14
+ /** Path relative to the skill root (e.g. "SKILL.md", "references/schema.md"). */
15
+ path: string;
16
+ content: string;
17
+ }
18
+ /**
19
+ * Load a skill bundle from disk.
20
+ *
21
+ * `bundleRoot` should point to a directory containing at least a `SKILL.md`
22
+ * file at the top level (typically `dist/skill-bundle/` after the host
23
+ * package's build step has copied the markdown sources from `src/`).
24
+ *
25
+ * The returned list is sorted with `SKILL.md` first, then alphabetically.
26
+ */
27
+ export declare function loadSkillBundle(bundleRoot: string): SkillBundleFile[];
28
+ //# sourceMappingURL=skill-bundle-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-bundle-loader.d.ts","sourceRoot":"","sources":["../../src/ghost-core/skill-bundle-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAiBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,EAAE,CASrE"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Generic loader for an agentskills.io-compatible skill bundle.
3
+ *
4
+ * Each tool in the Ghost monorepo (`ghost`, `ghost`, …) ships
5
+ * its own skill bundle as real markdown under `src/skill-bundle/` and copies
6
+ * it verbatim to `dist/skill-bundle/` at build time. This loader walks any
7
+ * given root directory and returns a flat, deterministically ordered list of
8
+ * files so the unified `ghost skill install` verb can write them into a target
9
+ * project.
10
+ *
11
+ * Spec: https://agentskills.io/specification
12
+ */
13
+ import { readdirSync, readFileSync } from "node:fs";
14
+ import { join, relative } from "node:path";
15
+ function walk(dir, root, out) {
16
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
17
+ const absolute = join(dir, entry.name);
18
+ if (entry.isDirectory()) {
19
+ walk(absolute, root, out);
20
+ continue;
21
+ }
22
+ if (!entry.isFile())
23
+ continue;
24
+ out.push({
25
+ path: relative(root, absolute),
26
+ content: readFileSync(absolute, "utf-8"),
27
+ });
28
+ }
29
+ }
30
+ /**
31
+ * Load a skill bundle from disk.
32
+ *
33
+ * `bundleRoot` should point to a directory containing at least a `SKILL.md`
34
+ * file at the top level (typically `dist/skill-bundle/` after the host
35
+ * package's build step has copied the markdown sources from `src/`).
36
+ *
37
+ * The returned list is sorted with `SKILL.md` first, then alphabetically.
38
+ */
39
+ export function loadSkillBundle(bundleRoot) {
40
+ const out = [];
41
+ walk(bundleRoot, bundleRoot, out);
42
+ out.sort((a, b) => {
43
+ if (a.path === "SKILL.md")
44
+ return -1;
45
+ if (b.path === "SKILL.md")
46
+ return 1;
47
+ return a.path.localeCompare(b.path);
48
+ });
49
+ return out;
50
+ }
51
+ //# sourceMappingURL=skill-bundle-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-bundle-loader.js","sourceRoot":"","sources":["../../src/ghost-core/skill-bundle-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAQ3C,SAAS,IAAI,CAAC,GAAW,EAAE,IAAY,EAAE,GAAsB;IAC7D,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YAC1B,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,SAAS;QAC9B,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;YAC9B,OAAO,EAAE,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC;SACzC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAClC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAChB,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,CAAC,CAAC;QACpC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * as fingerprint from "./fingerprint.js";
2
+ export * as core from "./ghost-core/index.js";
3
+ /** @deprecated Use `fingerprint` or `@design-intelligence/ghost/fingerprint`. */
4
+ export * as scan from "./scan/index.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAC9C,iFAAiF;AACjF,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * as fingerprint from "./fingerprint.js";
2
+ export * as core from "./ghost-core/index.js";
3
+ /** @deprecated Use `fingerprint` or `@design-intelligence/ghost/fingerprint`. */
4
+ export * as scan from "./scan/index.js";
5
+ //# sourceMappingURL=index.js.map