@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 @@
1
+ {"version":3,"file":"node-files.d.ts","sourceRoot":"","sources":["../../src/scan/node-files.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAa,MAAM,aAAa,CAAC;AAqBzD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,iFAAiF;IACjF,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC,CAU1B"}
@@ -0,0 +1,112 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { parseNode } from "#ghost-core";
4
+ import { FINGERPRINT_MANIFEST_FILENAME, GHOST_GLOSSARY_FILENAME, GHOST_MATERIALS_DIR, } from "./constants.js";
5
+ /**
6
+ * Reserved package-root entries that are never nodes: the manifest (the
7
+ * package anchor), the glossary, `materials/` (bundled materials), and
8
+ * `checks/` (review checks — feed-back only, never generation context). The
9
+ * list is closed.
10
+ */
11
+ const RESERVED_ROOT_ENTRIES = new Set([
12
+ FINGERPRINT_MANIFEST_FILENAME,
13
+ "manifest.yaml",
14
+ GHOST_GLOSSARY_FILENAME,
15
+ GHOST_MATERIALS_DIR,
16
+ "checks",
17
+ ]);
18
+ /**
19
+ * Load authored prose nodes from the package directory. The corpus is flat:
20
+ * there is no hierarchy, no inheritance, no edges. Nesting into directories is a
21
+ * browsing convenience only.
22
+ *
23
+ * Every `*.md` file under the package directory is a node. Its id is its path
24
+ * with `.md` dropped, uniformly (`marketing/email.md` → `marketing/email`,
25
+ * `index.md` → `index`). The reserved root entries — `manifest.yml`,
26
+ * `glossary.md`, `materials/`, and `checks/` — are skipped.
27
+ *
28
+ * A file that fails per-node lint is collected in `invalid` (with its first
29
+ * error) and skipped rather than throwing, so one bad node does not block
30
+ * loading the rest. A missing package directory or empty corpus yields no nodes.
31
+ */
32
+ export async function loadNodeFiles(packageDir) {
33
+ const nodes = [];
34
+ const invalid = [];
35
+ await walk(packageDir, "", true, nodes, invalid);
36
+ // Deterministic order by id, mirroring the old sorted readdir.
37
+ nodes.sort((a, b) => a.id.localeCompare(b.id));
38
+ invalid.sort((a, b) => a.file.localeCompare(b.file));
39
+ return { nodes, invalid };
40
+ }
41
+ async function walk(packageDir, relDir, isRoot, nodes, invalid) {
42
+ const absDir = relDir === "" ? packageDir : join(packageDir, relDir);
43
+ let entries;
44
+ try {
45
+ const dirents = await readdir(absDir, { withFileTypes: true });
46
+ entries = dirents.map((d) => ({ name: d.name, isDir: d.isDirectory() }));
47
+ }
48
+ catch {
49
+ return;
50
+ }
51
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
52
+ if (isRoot && RESERVED_ROOT_ENTRIES.has(entry.name))
53
+ continue;
54
+ if (entry.name.startsWith("."))
55
+ continue;
56
+ const relPath = relDir === "" ? entry.name : `${relDir}/${entry.name}`;
57
+ if (entry.isDir) {
58
+ await walk(packageDir, relPath, false, nodes, invalid);
59
+ continue;
60
+ }
61
+ if (!entry.name.endsWith(".md"))
62
+ continue;
63
+ const raw = await readFile(join(packageDir, relPath), "utf-8");
64
+ const { node, report } = parseNode(raw);
65
+ if (node === null || report.errors > 0) {
66
+ const first = report.issues.find((issue) => issue.severity === "error");
67
+ invalid.push({
68
+ file: relPath,
69
+ message: first?.message ?? "invalid node",
70
+ });
71
+ continue;
72
+ }
73
+ const { id, kind, slug } = locate(relPath);
74
+ nodes.push({
75
+ id,
76
+ ...(kind !== undefined ? { kind } : {}),
77
+ slug,
78
+ doc: node,
79
+ });
80
+ }
81
+ }
82
+ /**
83
+ * Compute a node's id and filename kind/slug from its package-relative path.
84
+ *
85
+ * The rule is uniform: the **id** is the path with `.md` dropped. The **kind**
86
+ * is the leaf filename's first dotted segment, and only exists when the leaf
87
+ * has a dot; the **slug** is the rest of the leaf. A kind never changes a
88
+ * node's identity path. `index.md` is an ordinary node with id `index` — by
89
+ * convention the human-curated front door, but nothing special to the loader.
90
+ * - `index.md` → id `index`, slug `index` (no kind).
91
+ * - `voice.md` → id `voice`, slug `voice` (no kind).
92
+ * - `principle.density.md` → id `principle.density`, kind `principle`, slug `density`.
93
+ * - `a/principle.trust.md` → id `a/principle.trust`, kind `principle`, slug `trust`.
94
+ */
95
+ function locate(relPath) {
96
+ const withoutExt = relPath.replace(/\.md$/, "");
97
+ const segments = withoutExt.split("/");
98
+ const leaf = segments[segments.length - 1] ?? "";
99
+ const id = withoutExt;
100
+ // A dotted leaf splits into kind (first segment) and slug (the remainder);
101
+ // a bare leaf is all slug with no kind.
102
+ const dot = leaf.indexOf(".");
103
+ if (dot > 0) {
104
+ return {
105
+ id,
106
+ kind: leaf.slice(0, dot),
107
+ slug: leaf.slice(dot + 1),
108
+ };
109
+ }
110
+ return { id, slug: leaf };
111
+ }
112
+ //# sourceMappingURL=node-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-files.js","sourceRoot":"","sources":["../../src/scan/node-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Neutral home for the load-bearing package-path helpers: direct package
3
+ * addressing (no nesting machinery), consumed by fingerprint-commands,
4
+ * init-command, monorepo-init-command, and the scan/index re-exports.
5
+ */
6
+ export declare function resolveGitRoot(cwd?: string): Promise<string>;
7
+ export declare function normalizeGhostDir(ghostDir?: string): string;
8
+ export declare const GHOST_PACKAGE_DIR_ENV = "GHOST_PACKAGE_DIR";
9
+ export declare function resolveGhostDirDefault(explicitGhostDir?: unknown, env?: NodeJS.ProcessEnv): string;
10
+ //# sourceMappingURL=package-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-paths.d.ts","sourceRoot":"","sources":["../../src/scan/package-paths.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AAEH,wBAAsB,cAAc,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAazE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,SAA0B,GAAG,MAAM,CA2B5E;AAED,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD,wBAAgB,sBAAsB,CACpC,gBAAgB,CAAC,EAAE,OAAO,EAC1B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAMR"}
@@ -0,0 +1,49 @@
1
+ import { execFile } from "node:child_process";
2
+ import { isAbsolute, resolve } from "node:path";
3
+ import { promisify } from "node:util";
4
+ import { UsageError } from "#ghost-core";
5
+ import { FINGERPRINT_PACKAGE_DIR } from "./constants.js";
6
+ const execFileAsync = promisify(execFile);
7
+ /**
8
+ * Neutral home for the load-bearing package-path helpers: direct package
9
+ * addressing (no nesting machinery), consumed by fingerprint-commands,
10
+ * init-command, monorepo-init-command, and the scan/index re-exports.
11
+ */
12
+ export async function resolveGitRoot(cwd = process.cwd()) {
13
+ try {
14
+ const { stdout } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], {
15
+ cwd,
16
+ });
17
+ return resolve(stdout.trim());
18
+ }
19
+ catch {
20
+ return resolve(cwd);
21
+ }
22
+ }
23
+ export function normalizeGhostDir(ghostDir = FINGERPRINT_PACKAGE_DIR) {
24
+ const normalized = ghostDir
25
+ .trim()
26
+ .replaceAll("\\", "/")
27
+ .replace(/\/+/g, "/")
28
+ .replace(/\/$/g, "");
29
+ if (!normalized) {
30
+ throw new UsageError("GHOST_PACKAGE_DIR must not be empty");
31
+ }
32
+ if (isAbsolute(ghostDir) ||
33
+ normalized.startsWith("/") ||
34
+ /^[A-Za-z]:/.test(normalized)) {
35
+ throw new UsageError("GHOST_PACKAGE_DIR must be a relative directory path");
36
+ }
37
+ const segments = normalized.split("/");
38
+ if (segments.some((segment) => segment === "." || segment === ".." || segment === "")) {
39
+ throw new UsageError("GHOST_PACKAGE_DIR must not contain '.', '..', or empty path segments");
40
+ }
41
+ return normalized;
42
+ }
43
+ export const GHOST_PACKAGE_DIR_ENV = "GHOST_PACKAGE_DIR";
44
+ export function resolveGhostDirDefault(explicitGhostDir, env = process.env) {
45
+ return normalizeGhostDir(typeof explicitGhostDir === "string"
46
+ ? explicitGhostDir
47
+ : env[GHOST_PACKAGE_DIR_ENV]);
48
+ }
49
+ //# sourceMappingURL=package-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-paths.js","sourceRoot":"","sources":["../../src/scan/package-paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C;;;;GAIG;AAEH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IACtD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,KAAK,EACL,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAChC;YACE,GAAG;SACJ,CACF,CAAC;QACF,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAQ,GAAG,uBAAuB;IAClE,MAAM,UAAU,GAAG,QAAQ;SACxB,IAAI,EAAE;SACN,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACvB,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,UAAU,CAAC,qCAAqC,CAAC,CAAC;IAC9D,CAAC;IACD,IACE,UAAU,CAAC,QAAQ,CAAC;QACpB,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC;QAC1B,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,EAC7B,CAAC;QACD,MAAM,IAAI,UAAU,CAAC,qDAAqD,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvC,IACE,QAAQ,CAAC,IAAI,CACX,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,EAAE,CACnE,EACD,CAAC;QACD,MAAM,IAAI,UAAU,CAClB,sEAAsE,CACvE,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,mBAAmB,CAAC;AAEzD,MAAM,UAAU,sBAAsB,CACpC,gBAA0B,EAC1B,MAAyB,OAAO,CAAC,GAAG;IAEpC,OAAO,iBAAiB,CACtB,OAAO,gBAAgB,KAAK,QAAQ;QAClC,CAAC,CAAC,gBAAgB;QAClB,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { TemplateFile } from "./templates.js";
2
+ export declare function loadPackedPayload(name: string): Promise<TemplateFile[]>;
3
+ export declare function loadPayloadFile(payload: string, relativePath: string): Promise<string>;
4
+ //# sourceMappingURL=packed-payloads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packed-payloads.d.ts","sourceRoot":"","sources":["../../src/scan/packed-payloads.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAgBnD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAU7E;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAEjB"}
@@ -0,0 +1,55 @@
1
+ import { existsSync } from "node:fs";
2
+ import { readdir, readFile } from "node:fs/promises";
3
+ import { join, relative } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ /**
6
+ * Payload roots, first match wins. At runtime this module lives in
7
+ * `dist/scan/`, so `../init-payloads` is the packed payload dir. Under
8
+ * vitest it runs from `src/scan/`, where only committed payloads (skeleton)
9
+ * exist — synced payloads (vessel-light) resolve through the built
10
+ * `dist/init-payloads` sibling.
11
+ */
12
+ const INIT_PAYLOAD_ROOTS = [
13
+ fileURLToPath(new URL("../init-payloads", import.meta.url)),
14
+ fileURLToPath(new URL("../../dist/init-payloads", import.meta.url)),
15
+ ];
16
+ const BINARY_EXTENSIONS = new Set([".woff", ".woff2"]);
17
+ export async function loadPackedPayload(name) {
18
+ const payloadDir = resolvePayloadDir(name);
19
+ const files = await listPayloadFiles(payloadDir);
20
+ return Promise.all(files.map(async (path) => ({
21
+ relativePath: relative(payloadDir, path),
22
+ content: await readPayloadFile(path),
23
+ })));
24
+ }
25
+ export async function loadPayloadFile(payload, relativePath) {
26
+ return readFile(join(resolvePayloadDir(payload), relativePath), "utf-8");
27
+ }
28
+ function resolvePayloadDir(name) {
29
+ return (INIT_PAYLOAD_ROOTS.map((root) => join(root, name)).find((dir) => existsSync(dir)) ?? join(INIT_PAYLOAD_ROOTS[0], name));
30
+ }
31
+ async function listPayloadFiles(dir) {
32
+ const entries = await readdir(dir, { withFileTypes: true });
33
+ const files = await Promise.all(entries.map(async (entry) => {
34
+ const path = join(dir, entry.name);
35
+ if (entry.isDirectory())
36
+ return listPayloadFiles(path);
37
+ if (entry.isFile())
38
+ return [path];
39
+ return [];
40
+ }));
41
+ return files.flat().sort((a, b) => a.localeCompare(b));
42
+ }
43
+ async function readPayloadFile(path) {
44
+ const bytes = await readFile(path);
45
+ if (isBinaryPayloadPath(path))
46
+ return bytes;
47
+ return bytes.toString("utf-8");
48
+ }
49
+ function isBinaryPayloadPath(path) {
50
+ const dot = path.lastIndexOf(".");
51
+ if (dot === -1)
52
+ return false;
53
+ return BINARY_EXTENSIONS.has(path.slice(dot).toLowerCase());
54
+ }
55
+ //# sourceMappingURL=packed-payloads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packed-payloads.js","sourceRoot":"","sources":["../../src/scan/packed-payloads.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface TarballEntryInput {
2
+ /** Archive path, using forward slashes and no leading slash. */
3
+ path: string;
4
+ data: Buffer | string;
5
+ mtime?: Date;
6
+ mode?: number;
7
+ }
8
+ export interface CreateDirectoryTarballOptions {
9
+ rootDir: string;
10
+ outFile: string;
11
+ extraEntries?: TarballEntryInput[];
12
+ exclude?: (relativePath: string) => boolean;
13
+ }
14
+ /**
15
+ * Write a dependency-free `.tgz` archive for a Ghost package directory.
16
+ *
17
+ * This intentionally implements only the portable subset Ghost needs: ustar
18
+ * regular-file entries, deterministic path ordering, no symlink traversal.
19
+ */
20
+ export declare function writeDirectoryTarball(options: CreateDirectoryTarballOptions): Promise<void>;
21
+ export declare function createTarArchive(entries: TarballEntryInput[]): Buffer;
22
+ export declare function defaultArchiveName(id: string): string;
23
+ //# sourceMappingURL=tarball.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tarball.d.ts","sourceRoot":"","sources":["../../src/scan/tarball.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;CAC7C;AAYD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAyBrE;AA+HD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAErD"}
@@ -0,0 +1,145 @@
1
+ import { readdir, readFile, stat, writeFile } from "node:fs/promises";
2
+ import { join, relative } from "node:path";
3
+ import { gzipSync } from "node:zlib";
4
+ const BLOCK_SIZE = 512;
5
+ /**
6
+ * Write a dependency-free `.tgz` archive for a Ghost package directory.
7
+ *
8
+ * This intentionally implements only the portable subset Ghost needs: ustar
9
+ * regular-file entries, deterministic path ordering, no symlink traversal.
10
+ */
11
+ export async function writeDirectoryTarball(options) {
12
+ const files = await listRegularFiles(options.rootDir, options.exclude);
13
+ const fileEntries = await Promise.all(files.map(async (file) => ({
14
+ path: file.path,
15
+ data: await readFile(file.absolutePath),
16
+ mtime: file.mtime,
17
+ mode: file.mode,
18
+ })));
19
+ const archive = createTarArchive([
20
+ ...(options.extraEntries ?? []),
21
+ ...fileEntries,
22
+ ]);
23
+ await writeFile(options.outFile, gzipSync(archive));
24
+ }
25
+ export function createTarArchive(entries) {
26
+ const sorted = entries
27
+ .map(normalizeEntry)
28
+ .sort((a, b) => a.path.localeCompare(b.path));
29
+ const chunks = [];
30
+ for (const entry of sorted) {
31
+ const data = Buffer.isBuffer(entry.data)
32
+ ? entry.data
33
+ : Buffer.from(entry.data, "utf-8");
34
+ chunks.push(createHeader({
35
+ path: entry.path,
36
+ size: data.byteLength,
37
+ mode: entry.mode ?? 0o644,
38
+ mtime: entry.mtime ?? new Date(0),
39
+ }));
40
+ chunks.push(data);
41
+ const remainder = data.byteLength % BLOCK_SIZE;
42
+ if (remainder !== 0)
43
+ chunks.push(Buffer.alloc(BLOCK_SIZE - remainder));
44
+ }
45
+ chunks.push(Buffer.alloc(BLOCK_SIZE * 2));
46
+ return Buffer.concat(chunks);
47
+ }
48
+ async function listRegularFiles(rootDir, exclude) {
49
+ const files = [];
50
+ await walk(rootDir, rootDir, exclude, files);
51
+ files.sort((a, b) => a.path.localeCompare(b.path));
52
+ return files;
53
+ }
54
+ async function walk(rootDir, dir, exclude, files) {
55
+ const entries = await readdir(dir, { withFileTypes: true });
56
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
57
+ const absolutePath = join(dir, entry.name);
58
+ const relPath = normalizeTarPath(relative(rootDir, absolutePath));
59
+ if (exclude?.(relPath))
60
+ continue;
61
+ if (entry.isDirectory()) {
62
+ await walk(rootDir, absolutePath, exclude, files);
63
+ continue;
64
+ }
65
+ if (!entry.isFile())
66
+ continue;
67
+ const s = await stat(absolutePath);
68
+ if (!s.isFile())
69
+ continue;
70
+ files.push({
71
+ path: relPath,
72
+ absolutePath,
73
+ size: s.size,
74
+ mode: s.mode & 0o777,
75
+ mtime: s.mtime,
76
+ });
77
+ }
78
+ }
79
+ function normalizeEntry(entry) {
80
+ const path = normalizeTarPath(entry.path);
81
+ if (path === "" || path.startsWith("../") || path.includes("/../")) {
82
+ throw new Error(`Invalid tar entry path: ${entry.path}`);
83
+ }
84
+ return { ...entry, path };
85
+ }
86
+ function createHeader(entry) {
87
+ const header = Buffer.alloc(BLOCK_SIZE, 0);
88
+ const path = splitUstarPath(entry.path);
89
+ writeString(header, path.name, 0, 100);
90
+ writeOctal(header, entry.mode, 100, 8);
91
+ writeOctal(header, 0, 108, 8);
92
+ writeOctal(header, 0, 116, 8);
93
+ writeOctal(header, entry.size, 124, 12);
94
+ writeOctal(header, Math.floor(entry.mtime.getTime() / 1000), 136, 12);
95
+ header.fill(0x20, 148, 156);
96
+ writeString(header, "0", 156, 1);
97
+ writeString(header, "ustar", 257, 6);
98
+ writeString(header, "00", 263, 2);
99
+ if (path.prefix !== undefined)
100
+ writeString(header, path.prefix, 345, 155);
101
+ const checksum = header.reduce((sum, byte) => sum + byte, 0);
102
+ writeChecksum(header, checksum);
103
+ return header;
104
+ }
105
+ function splitUstarPath(path) {
106
+ const byteLength = Buffer.byteLength(path);
107
+ if (byteLength <= 100)
108
+ return { name: path };
109
+ const parts = path.split("/");
110
+ for (let index = 1; index < parts.length; index++) {
111
+ const prefix = parts.slice(0, index).join("/");
112
+ const name = parts.slice(index).join("/");
113
+ if (Buffer.byteLength(prefix) <= 155 && Buffer.byteLength(name) <= 100) {
114
+ return { prefix, name };
115
+ }
116
+ }
117
+ throw new Error(`Tar entry path is too long for ustar: ${path}`);
118
+ }
119
+ function writeString(buffer, value, offset, length) {
120
+ const bytes = Buffer.from(value, "utf-8");
121
+ if (bytes.byteLength > length) {
122
+ throw new Error(`Tar header value is too long: ${value}`);
123
+ }
124
+ bytes.copy(buffer, offset);
125
+ }
126
+ function writeOctal(buffer, value, offset, length) {
127
+ const text = value.toString(8).padStart(length - 1, "0");
128
+ if (text.length > length - 1) {
129
+ throw new Error(`Tar numeric value is too large: ${value}`);
130
+ }
131
+ buffer.write(text, offset, length - 1, "ascii");
132
+ }
133
+ function writeChecksum(buffer, checksum) {
134
+ const text = checksum.toString(8).padStart(6, "0");
135
+ buffer.write(text, 148, 6, "ascii");
136
+ buffer[154] = 0;
137
+ buffer[155] = 0x20;
138
+ }
139
+ function normalizeTarPath(path) {
140
+ return path.replace(/\\/g, "/").replace(/^\.\//, "").replace(/^\/+/, "");
141
+ }
142
+ export function defaultArchiveName(id) {
143
+ return `${id}-fingerprint.tgz`;
144
+ }
145
+ //# sourceMappingURL=tarball.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tarball.js","sourceRoot":"","sources":["../../src/scan/tarball.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * A single seed file an `init` template writes, relative to the package dir.
3
+ */
4
+ export interface TemplateFile {
5
+ /** Path relative to the package directory (e.g. "principle.voice.md"). */
6
+ relativePath: string;
7
+ content: string | Uint8Array;
8
+ }
9
+ /**
10
+ * An `init` template: a pure description of the seed files a fresh node package
11
+ * starts with. Templates are the extension seam — adding a `marketing` / `voice`
12
+ * / `dashboard` starter later is just registering another entry here; `init`
13
+ * needs no change.
14
+ */
15
+ export interface GhostInitTemplate {
16
+ name: string;
17
+ description: string;
18
+ files(): TemplateFile[] | Promise<TemplateFile[]>;
19
+ }
20
+ /**
21
+ * An init body: a full inhabited fingerprint package — answered signature
22
+ * dials, materials, refs, and its own checks. Templates are shapes of
23
+ * emptiness awaiting the owner's truths; a body is the same anatomy with a
24
+ * real brand's values plugged in. Bodies keep their own manifest id (e.g.
25
+ * `vessel-light`) so an unadapted install stays honestly labeled — changing
26
+ * the id is step one of adapting the starter, an explicit human act.
27
+ */
28
+ export interface GhostInitBody {
29
+ name: string;
30
+ description: string;
31
+ /** Whether the body payload ships its own `checks/` directory. */
32
+ includesChecks: boolean;
33
+ files(): Promise<TemplateFile[]>;
34
+ }
35
+ /** Look up a registered init body by name. */
36
+ export declare function getInitBody(name: string): GhostInitBody | undefined;
37
+ export declare function listInitBodies(): string[];
38
+ export declare const DEFAULT_TEMPLATE_NAME: string;
39
+ /** Look up a registered init template by name. */
40
+ export declare function getInitTemplate(name: string): GhostInitTemplate | undefined;
41
+ export declare function listInitTemplates(): string[];
42
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scan/templates.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;CAC9B;AACD;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,IAAI,YAAY,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CACnD;AA0VD;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAClC;AAgCD,8CAA8C;AAC9C,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEnE;AAED,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AAED,eAAO,MAAM,qBAAqB,QAAyB,CAAC;AAE5D,kDAAkD;AAClD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAM3E;AAED,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAE5C"}