@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,44 @@
1
+ ---
2
+ description: "Gather for any copy and for motion character. The temperature dial: how the brand sounds and how it moves — this brand's current answer is factual, quiet, never celebratory, with resolved spring motion."
3
+ materials:
4
+ - materials/tokens.css
5
+ ---
6
+
7
+ This is Vessel's answer to temperature — it stands until you replace it.
8
+
9
+ The relationship is fixed: voice and motion carry the same temperature. Copy
10
+ states what happened, what is possible, or what the user must decide — it
11
+ does not perform personality — and motion confirms rather than entertains.
12
+
13
+ Vessel's current answer in words: product UI is the default register —
14
+ factual, quiet, sentence case, and free of applause. No exclamation marks;
15
+ celebration is not reassurance. Confirmations are quiet: "Changes saved",
16
+ never "Awesome!" The system should sound reliable, not excited by basic
17
+ competence. Errors name the problem and the fix in the place where the user
18
+ can act; a vague failure banner is evasion. Buttons name the act — "Delete
19
+ account", "Save changes", "Invite member", not "Do it" or "Let's go".
20
+ Destructive copy is direct because the risk is direct; softening the verb
21
+ makes the interface less honest. Vessel never celebrates at the user. Trust
22
+ comes from precision, restraint, and naming the truth plainly.
23
+
24
+ The voice is a mechanical edit, not a mood — apply it as transformations:
25
+ "Sorry, nothing here yet!" → "Nothing yet". "Awesome, your changes have been
26
+ saved!" → "Changes saved". "Oops! Something went wrong" → "Payment failed —
27
+ card expired". "You might want to consider updating your billing info" →
28
+ "Update your billing info". Strip the apology, the applause, and the hedge;
29
+ keep the fact and the fix.
30
+
31
+ Vessel's current answer in motion: three durations — `--duration-fast`,
32
+ `--duration-normal`, `--duration-slow` — and one ease, `--ease-spring`, which
33
+ should feel resolved without feeling elastic. Hover confirms with color and
34
+ background shifts at the fast duration, not levitation.
35
+
36
+ Condition: editorial surfaces switch register. Short declarative confident
37
+ fragments are correct in heroes and section headings. That same editorial
38
+ confidence is wrong in a settings form — product copy serves the task before
39
+ it serves the voice. Email copy uses the product voice: factual, not
40
+ campaign-like.
41
+
42
+ To adapt: rewrite this node's current answers in your brand's voice and edit
43
+ the duration and ease values in `materials/tokens.css`. The coupling — words
44
+ and motion sharing one temperature — is the part worth keeping.
@@ -0,0 +1,37 @@
1
+ ---
2
+ description: "Gather for any text, and for heroes, landing pages, and editorial moments. The type dial: one voice typeface plus a mono for machine detail, with an editorial heading scale kept separate from product text — this brand's current answer is HK Grotesk."
3
+ materials:
4
+ - materials/tokens.css
5
+ - materials/fonts/*.woff2
6
+ ---
7
+
8
+ This is Vessel's answer to type — it stands until you replace it.
9
+
10
+ The relationship is fixed: one typeface is the voice of the interface,
11
+ everywhere, with a mono variant only for code, tool detail, and machine
12
+ output. The heading scale is editorial — its tokens exist for pages composed
13
+ outside the text variants — and product UI never mixes the two vocabularies
14
+ in one view.
15
+
16
+ Vessel's current answer: HK Grotesk. vessel-light ships it as its embedded
17
+ voice — here, `tokens.css` is canonical.
18
+
19
+ The heading scale is editorial: display, section, and sub each carry their
20
+ own rhythm (`--heading-display-*`, `--heading-section-*`, `--heading-sub-*`).
21
+ Display sizes use tight tracking and sub-1 line heights because the words
22
+ behave like composition, not paragraph text. Card-level headings inside
23
+ editorial features use the product `title` variant — the scale does not reach
24
+ below sub.
25
+
26
+ Labels are small, semibold, and tracked wide. They should feel precise, never
27
+ loud. Body text keeps the established reading sizes with relaxed line height;
28
+ do not shrink important prose until it becomes legal copy.
29
+
30
+ Condition: display and section scale are for editorial or hero moments.
31
+ Product UI lives in headline, title, body, label, and mono. A modal title is
32
+ not a poster. When in doubt, make type quieter and layout clearer.
33
+
34
+ To adapt: swap the font files, edit `--font-sans`, `--font-mono`, and the
35
+ heading tokens in `materials/tokens.css`, and restate this node's current
36
+ answer. The one-voice rule and the editorial/product vocabulary split are the
37
+ parts worth keeping.
@@ -0,0 +1,4 @@
1
+ export declare function readOptionalUtf8(path: string): Promise<string | undefined>;
2
+ export declare function isMissingPathError(err: unknown): boolean;
3
+ export declare function isExistingPathError(err: unknown): boolean;
4
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/internal/fs.ts"],"names":[],"mappings":"AAEA,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO7B;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAExD;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAEzD"}
@@ -0,0 +1,24 @@
1
+ import { readFile } from "node:fs/promises";
2
+ export async function readOptionalUtf8(path) {
3
+ try {
4
+ return await readFile(path, "utf-8");
5
+ }
6
+ catch (err) {
7
+ if (isMissingPathError(err))
8
+ return undefined;
9
+ throw err;
10
+ }
11
+ }
12
+ export function isMissingPathError(err) {
13
+ return hasErrnoCode(err, "ENOENT");
14
+ }
15
+ export function isExistingPathError(err) {
16
+ return hasErrnoCode(err, "EEXIST");
17
+ }
18
+ function hasErrnoCode(err, code) {
19
+ return (typeof err === "object" &&
20
+ err !== null &&
21
+ "code" in err &&
22
+ err.code === code);
23
+ }
24
+ //# sourceMappingURL=fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/internal/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY;IAEZ,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,kBAAkB,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAC9C,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,OAAO,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,OAAO,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,GAAY,EAAE,IAAY;IAC9C,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,MAAM,IAAI,GAAG;QACZ,GAA6B,CAAC,IAAI,KAAK,IAAI,CAC7C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ export type GatherObservabilityEvent = {
2
+ ts: string;
3
+ event: "gather";
4
+ /** Caller-supplied run identifier (--run or GHOST_RUN_ID); attribution only. */
5
+ run?: string;
6
+ ask?: string;
7
+ menu: string[];
8
+ materials?: string[];
9
+ };
10
+ export type PullMiss = {
11
+ requested: string;
12
+ suggested: string[];
13
+ };
14
+ export type PullObservabilityEvent = {
15
+ ts: string;
16
+ event: "pull";
17
+ /** Caller-supplied run identifier (--run or GHOST_RUN_ID); attribution only. */
18
+ run?: string;
19
+ ids: string[];
20
+ missed?: PullMiss[];
21
+ inlinedMaterials?: number;
22
+ omittedMaterials?: number;
23
+ };
24
+ export type GhostObservabilityEvent = GatherObservabilityEvent | PullObservabilityEvent;
25
+ export type NewGhostObservabilityEvent = Omit<GatherObservabilityEvent, "ts"> | Omit<PullObservabilityEvent, "ts">;
26
+ /**
27
+ * Resolve the run identifier for event attribution: explicit --run flag
28
+ * wins, then GHOST_RUN_ID from the environment. Returns undefined when
29
+ * neither is set — the tape line then looks exactly as it does today.
30
+ */
31
+ export declare function resolveRunId(flagValue?: unknown): string | undefined;
32
+ export declare function appendGhostEvent(packageDir: string, event: NewGhostObservabilityEvent): Promise<void>;
33
+ export declare function readGhostEvents(packageDir: string): Promise<GhostObservabilityEvent[]>;
34
+ //# sourceMappingURL=observability-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observability-events.d.ts","sourceRoot":"","sources":["../src/observability-events.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,wBAAwB,GAAG;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,QAAQ,CAAC;IAChB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAC/B,wBAAwB,GACxB,sBAAsB,CAAC;AAE3B,MAAM,MAAM,0BAA0B,GAClC,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC,GACpC,IAAI,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;AAEvC;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAKpE;AAED,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAmBpC"}
@@ -0,0 +1,68 @@
1
+ import { access, appendFile, readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { GHOST_EVENTS_FILENAME } from "./scan/constants.js";
4
+ const FIRST_WRITE_NOTICE = `ghost: logging selection events locally to .ghost/${GHOST_EVENTS_FILENAME} (gitignored; never leaves your machine). Summarize with \`ghost pulse\`.`;
5
+ /**
6
+ * Resolve the run identifier for event attribution: explicit --run flag
7
+ * wins, then GHOST_RUN_ID from the environment. Returns undefined when
8
+ * neither is set — the tape line then looks exactly as it does today.
9
+ */
10
+ export function resolveRunId(flagValue) {
11
+ const fromFlag = typeof flagValue === "string" ? flagValue.trim() : "";
12
+ if (fromFlag)
13
+ return fromFlag;
14
+ const fromEnv = process.env.GHOST_RUN_ID?.trim();
15
+ return fromEnv || undefined;
16
+ }
17
+ export async function appendGhostEvent(packageDir, event) {
18
+ const line = `${JSON.stringify({ ts: new Date().toISOString(), ...event })}\n`;
19
+ const tapePath = join(packageDir, GHOST_EVENTS_FILENAME);
20
+ try {
21
+ const isFirstWrite = await access(tapePath).then(() => false, () => true);
22
+ await appendFile(tapePath, line, "utf8");
23
+ if (isFirstWrite) {
24
+ // One-time notice on tape creation. Stderr so piped gather/pull
25
+ // output stays clean; silent on every subsequent write.
26
+ process.stderr.write(`${FIRST_WRITE_NOTICE}\n`);
27
+ }
28
+ }
29
+ catch {
30
+ // Local observability is advisory. It must never break gather/pull.
31
+ }
32
+ }
33
+ export async function readGhostEvents(packageDir) {
34
+ let raw;
35
+ try {
36
+ raw = await readFile(join(packageDir, GHOST_EVENTS_FILENAME), "utf8");
37
+ }
38
+ catch {
39
+ return [];
40
+ }
41
+ const events = [];
42
+ for (const line of raw.split(/\r?\n/)) {
43
+ if (!line.trim())
44
+ continue;
45
+ try {
46
+ const parsed = JSON.parse(line);
47
+ if (isGhostEvent(parsed))
48
+ events.push(parsed);
49
+ }
50
+ catch {
51
+ // Ignore malformed events tape lines; pulse should still be useful.
52
+ }
53
+ }
54
+ return events;
55
+ }
56
+ function isGhostEvent(value) {
57
+ if (!value || typeof value !== "object")
58
+ return false;
59
+ const event = value;
60
+ if (typeof event.ts !== "string")
61
+ return false;
62
+ if (event.event === "gather")
63
+ return Array.isArray(event.menu);
64
+ if (event.event === "pull")
65
+ return Array.isArray(event.ids);
66
+ return false;
67
+ }
68
+ //# sourceMappingURL=observability-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observability-events.js","sourceRoot":"","sources":["../src/observability-events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Read this package's published version from package.json. */
2
+ export declare function readPackageVersion(): string;
3
+ //# sourceMappingURL=package-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-version.d.ts","sourceRoot":"","sources":["../src/package-version.ts"],"names":[],"mappings":"AAIA,+DAA+D;AAC/D,wBAAgB,kBAAkB,IAAI,MAAM,CAM3C"}
@@ -0,0 +1,10 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /** Read this package's published version from package.json. */
5
+ export function readPackageVersion() {
6
+ const here = dirname(fileURLToPath(import.meta.url));
7
+ const pkg = JSON.parse(readFileSync(resolve(here, "../package.json"), "utf8"));
8
+ return pkg.version;
9
+ }
10
+ //# sourceMappingURL=package-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-version.js","sourceRoot":"","sources":["../src/package-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,+DAA+D;AAC/D,MAAM,UAAU,kBAAkB;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CACvD,CAAC;IACF,OAAO,GAAG,CAAC,OAAiB,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type GhostCatalog } from "#ghost-core";
2
+ export interface BaselineProse {
3
+ ref: string;
4
+ nodeId: string;
5
+ heading?: string;
6
+ description?: string;
7
+ body: string;
8
+ warning?: string;
9
+ }
10
+ export declare function resolveBaseline(raw: string, catalog: GhostCatalog): BaselineProse | null;
11
+ //# sourceMappingURL=baseline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../src/review/baseline.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,YAAY,GACpB,aAAa,GAAG,IAAI,CA8BtB"}
@@ -0,0 +1,35 @@
1
+ import { parseSourceRef, sliceNodeSection, } from "#ghost-core";
2
+ export function resolveBaseline(raw, catalog) {
3
+ const ref = parseSourceRef(raw);
4
+ if (ref === null)
5
+ return null;
6
+ const node = catalog.nodes.get(ref.nodeId);
7
+ if (node === undefined)
8
+ return null;
9
+ if (ref.heading === undefined) {
10
+ return {
11
+ ref: raw,
12
+ nodeId: ref.nodeId,
13
+ ...(node.description !== undefined
14
+ ? { description: node.description }
15
+ : {}),
16
+ body: node.body,
17
+ };
18
+ }
19
+ const section = sliceNodeSection(node.body, ref.heading);
20
+ return {
21
+ ref: raw,
22
+ nodeId: ref.nodeId,
23
+ heading: ref.heading,
24
+ ...(node.description !== undefined
25
+ ? { description: node.description }
26
+ : {}),
27
+ body: section ?? node.body,
28
+ ...(section === null
29
+ ? {
30
+ warning: `heading '${ref.heading}' not found in node '${ref.nodeId}' — embedding the whole body`,
31
+ }
32
+ : {}),
33
+ };
34
+ }
35
+ //# sourceMappingURL=baseline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../src/review/baseline.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAWrB,MAAM,UAAU,eAAe,CAC7B,GAAW,EACX,OAAqB;IAErB,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;YACL,GAAG,EAAE,GAAG;YACR,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS;gBAChC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;gBACnC,CAAC,CAAC,EAAE,CAAC;YACP,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACzD,OAAO;QACL,GAAG,EAAE,GAAG;QACR,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS;YAChC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;YACnC,CAAC,CAAC,EAAE,CAAC;QACP,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,IAAI;QAC1B,GAAG,CAAC,OAAO,KAAK,IAAI;YAClB,CAAC,CAAC;gBACE,OAAO,EAAE,YAAY,GAAG,CAAC,OAAO,wBAAwB,GAAG,CAAC,MAAM,8BAA8B;aACjG;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface TouchedFile {
2
+ path: string;
3
+ patch: string;
4
+ }
5
+ /** Extract touched file paths from a unified diff. */
6
+ export declare function parseTouchedFiles(diffText: string): TouchedFile[];
7
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/review/diff.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,sDAAsD;AACtD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CAuCjE"}
@@ -0,0 +1,41 @@
1
+ /** Extract touched file paths from a unified diff. */
2
+ export function parseTouchedFiles(diffText) {
3
+ const files = [];
4
+ const lines = diffText.split(/\r?\n/);
5
+ let current = null;
6
+ const flush = (endExclusive) => {
7
+ if (current) {
8
+ files.push({
9
+ path: current.path,
10
+ patch: lines.slice(current.start, endExclusive).join("\n"),
11
+ });
12
+ current = null;
13
+ }
14
+ };
15
+ for (let i = 0; i < lines.length; i++) {
16
+ const line = lines[i];
17
+ const gitHeader = line.match(/^diff --git a\/(.+?) b\/(.+)$/);
18
+ if (gitHeader) {
19
+ flush(i);
20
+ current = { path: gitHeader[2], start: i };
21
+ continue;
22
+ }
23
+ const plusPlus = line.match(/^\+\+\+ b?\/?(.+)$/);
24
+ if (plusPlus && current === null) {
25
+ const p = plusPlus[1].trim();
26
+ if (p !== "/dev/null")
27
+ current = { path: p, start: i };
28
+ }
29
+ }
30
+ flush(lines.length);
31
+ const seen = new Set();
32
+ const out = [];
33
+ for (const file of files) {
34
+ if (file.path === "/dev/null" || seen.has(file.path))
35
+ continue;
36
+ seen.add(file.path);
37
+ out.push(file);
38
+ }
39
+ return out;
40
+ }
41
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/review/diff.ts"],"names":[],"mappings":"AAKA,sDAAsD;AACtD,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,OAAO,GAA2C,IAAI,CAAC;IAE3D,MAAM,KAAK,GAAG,CAAC,YAAoB,EAAE,EAAE;QACrC,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;aAC3D,CAAC,CAAC;YACH,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC9D,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,CAAC,CAAC,CAAC,CAAC;YACT,OAAO,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAC3C,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAClD,IAAI,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACjC,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,KAAK,WAAW;gBAAE,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACzD,CAAC;IACH,CAAC;IACD,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEpB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAC/D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { hasGlobMagic, matchesGlob, normalizeGlobPath } from "#ghost-core";
2
+ //# sourceMappingURL=glob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/review/glob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { hasGlobMagic, matchesGlob, normalizeGlobPath } from "#ghost-core";
2
+ //# sourceMappingURL=glob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.js","sourceRoot":"","sources":["../../src/review/glob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface ProbeEvidence {
2
+ command: string;
3
+ timedOut: boolean;
4
+ exitCode: number | null;
5
+ stdout: string;
6
+ stderr: string;
7
+ }
8
+ export declare function runProbe(command: string, options: {
9
+ cwd: string;
10
+ timeoutMs?: number;
11
+ truncateChars?: number;
12
+ }): Promise<ProbeEvidence>;
13
+ //# sourceMappingURL=probes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probes.d.ts","sourceRoot":"","sources":["../../src/review/probes.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACA,OAAO,CAAC,aAAa,CAAC,CAiCxB"}
@@ -0,0 +1,45 @@
1
+ import { exec } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ const execAsync = promisify(exec);
4
+ const DEFAULT_PROBE_TIMEOUT_MS = 30_000;
5
+ const DEFAULT_PROBE_TRUNCATE_CHARS = 4_000;
6
+ export async function runProbe(command, options) {
7
+ const timeout = options.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
8
+ const truncateChars = options.truncateChars ?? DEFAULT_PROBE_TRUNCATE_CHARS;
9
+ try {
10
+ const { stdout, stderr } = await execAsync(command, {
11
+ cwd: options.cwd,
12
+ timeout,
13
+ maxBuffer: 8 * 1024 * 1024,
14
+ });
15
+ return {
16
+ command,
17
+ timedOut: false,
18
+ exitCode: 0,
19
+ stdout: truncate(stdout, truncateChars),
20
+ stderr: truncate(stderr, truncateChars),
21
+ };
22
+ }
23
+ catch (err) {
24
+ const error = err;
25
+ const timedOut = error.signal === "SIGTERM" || error.killed === true;
26
+ return {
27
+ command,
28
+ timedOut,
29
+ exitCode: typeof error.code === "number" ? error.code : null,
30
+ stdout: truncate(streamToString(error.stdout), truncateChars),
31
+ stderr: truncate(streamToString(error.stderr), truncateChars),
32
+ };
33
+ }
34
+ }
35
+ function streamToString(value) {
36
+ if (value === undefined)
37
+ return "";
38
+ return Buffer.isBuffer(value) ? value.toString("utf8") : value;
39
+ }
40
+ function truncate(value, limit) {
41
+ if (value.length <= limit)
42
+ return value;
43
+ return `${value.slice(0, limit)}\n… truncated to ${limit} characters`;
44
+ }
45
+ //# sourceMappingURL=probes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probes.js","sourceRoot":"","sources":["../../src/review/probes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAClC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AACxC,MAAM,4BAA4B,GAAG,KAAK,CAAC;AAU3C,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,OAAe,EACf,OAIC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,wBAAwB,CAAC;IAC9D,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,4BAA4B,CAAC;IAC5E,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE;YAClD,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,OAAO;YACP,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;SAC3B,CAAC,CAAC;QACH,OAAO;YACL,OAAO;YACP,QAAQ,EAAE,KAAK;YACf,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;YACvC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;SACxC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,GAMb,CAAC;QACF,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC;QACrE,OAAO;YACL,OAAO;YACP,QAAQ;YACR,QAAQ,EAAE,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;YAC5D,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;YAC7D,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;SAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,KAAkC;IACxD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACjE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,KAAa;IAC5C,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,oBAAoB,KAAK,aAAa,CAAC;AACxE,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { type GhostCatalog, type MaterialTransportOptions } from "#ghost-core";
2
+ import type { LoadedCheck } from "../scan/check-files.js";
3
+ import { type TouchedFile } from "./diff.js";
4
+ export interface MatchedMaterialNode {
5
+ id: string;
6
+ files: string[];
7
+ locators: string[];
8
+ }
9
+ export interface OfferedCheck {
10
+ id: string;
11
+ severity: string | undefined;
12
+ offered: "matched" | "always";
13
+ via: string[];
14
+ }
15
+ export interface CoverageGap {
16
+ kind: "unmatched-file" | "unchecked-material";
17
+ detail: string;
18
+ files?: string[];
19
+ nodes?: string[];
20
+ }
21
+ export interface ReviewResolution {
22
+ touchedFiles: TouchedFile[];
23
+ materialNodes: MatchedMaterialNode[];
24
+ offeredChecks: OfferedCheck[];
25
+ gaps: CoverageGap[];
26
+ }
27
+ export declare function resolveReview(catalog: GhostCatalog, checks: Map<string, LoadedCheck>, diffText: string, transport: MaterialTransportOptions): ReviewResolution;
28
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/review/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAG9B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC9B,GAAG,EAAE,MAAM,EAAE,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,gBAAgB,GAAG,oBAAoB,CAAC;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,IAAI,EAAE,WAAW,EAAE,CAAC;CACrB;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,wBAAwB,GAClC,gBAAgB,CAmGlB"}
@@ -0,0 +1,90 @@
1
+ import { classifyMaterialLocator, materialLocatorClaimsPath, parseSourceRef, } from "#ghost-core";
2
+ import { parseTouchedFiles } from "./diff.js";
3
+ export function resolveReview(catalog, checks, diffText, transport) {
4
+ const touchedFiles = parseTouchedFiles(diffText);
5
+ const materialNodeIds = new Set();
6
+ const matched = new Map();
7
+ const claimedFiles = new Set();
8
+ for (const node of catalog.nodes.values()) {
9
+ const localLocators = (node.materials ?? []).filter((locator) => classifyMaterialLocator(locator).kind === "local");
10
+ if (localLocators.length === 0)
11
+ continue;
12
+ materialNodeIds.add(node.id);
13
+ for (const file of touchedFiles) {
14
+ // Resolve each locator the same way validate does: package-relative
15
+ // `materials/…` locators expand to their repo-relative form before
16
+ // matching diff paths (which git emits repo-relative). Matching the
17
+ // raw locator text silently missed every exact-path locator whenever
18
+ // the package lives below the repo root.
19
+ const locators = localLocators.filter((locator) => materialLocatorClaimsPath(locator, file.path, transport));
20
+ if (locators.length === 0)
21
+ continue;
22
+ claimedFiles.add(file.path);
23
+ const entry = matched.get(node.id) ?? {
24
+ files: new Set(),
25
+ locators: new Set(),
26
+ };
27
+ entry.files.add(file.path);
28
+ for (const locator of locators)
29
+ entry.locators.add(locator);
30
+ matched.set(node.id, entry);
31
+ }
32
+ }
33
+ const touchedMaterialNodes = new Set(matched.keys());
34
+ const referencedMaterialNodes = new Set();
35
+ const offeredChecks = [];
36
+ for (const check of checks.values()) {
37
+ const matchedRefs = [];
38
+ let referencesMaterial = false;
39
+ for (const raw of check.references) {
40
+ const ref = parseSourceRef(raw);
41
+ if (ref === null)
42
+ continue;
43
+ if (materialNodeIds.has(ref.nodeId)) {
44
+ referencesMaterial = true;
45
+ referencedMaterialNodes.add(ref.nodeId);
46
+ if (touchedMaterialNodes.has(ref.nodeId))
47
+ matchedRefs.push(raw);
48
+ }
49
+ }
50
+ if (matchedRefs.length > 0 || !referencesMaterial) {
51
+ offeredChecks.push({
52
+ id: check.id,
53
+ severity: check.doc.frontmatter.severity,
54
+ offered: matchedRefs.length > 0 ? "matched" : "always",
55
+ via: matchedRefs.length > 0 ? matchedRefs : check.references.slice(),
56
+ });
57
+ }
58
+ }
59
+ const gaps = [];
60
+ const unmatched = touchedFiles
61
+ .map((file) => file.path)
62
+ .filter((path) => !claimedFiles.has(path));
63
+ if (unmatched.length > 0) {
64
+ gaps.push({
65
+ kind: "unmatched-file",
66
+ detail: "changed files match no node `materials` locators — no fingerprint material claims them",
67
+ files: unmatched,
68
+ });
69
+ }
70
+ const unchecked = [...touchedMaterialNodes].filter((id) => !referencedMaterialNodes.has(id));
71
+ if (unchecked.length > 0) {
72
+ gaps.push({
73
+ kind: "unchecked-material",
74
+ detail: "touched material-backed nodes have no check referencing them — review coverage is missing",
75
+ nodes: unchecked,
76
+ });
77
+ }
78
+ const matchedNodes = [...matched].map(([id, entry]) => ({
79
+ id,
80
+ files: [...entry.files].sort(),
81
+ locators: [...entry.locators].sort(),
82
+ }));
83
+ return {
84
+ touchedFiles,
85
+ materialNodes: matchedNodes,
86
+ offeredChecks,
87
+ gaps,
88
+ };
89
+ }
90
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/review/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { LoadedFingerprintPackage } from "../scan/fingerprint-package.js";
2
+ import { type BaselineProse } from "./baseline.js";
3
+ import { type ProbeEvidence } from "./probes.js";
4
+ import type { CoverageGap } from "./resolve.js";
5
+ export type { BaselineProse, ProbeEvidence };
6
+ export interface PacketMaterialNode {
7
+ id: string;
8
+ kind?: string;
9
+ description?: string;
10
+ prose: string;
11
+ materials: string[];
12
+ matchedMaterials: string[];
13
+ files: string[];
14
+ }
15
+ export interface PacketCheck {
16
+ id: string;
17
+ severity: string | undefined;
18
+ offered: "matched" | "always";
19
+ via: string[];
20
+ prose: string;
21
+ baseline: BaselineProse[];
22
+ probe?: ProbeEvidence;
23
+ }
24
+ export interface ReviewPacket {
25
+ fingerprintId: string;
26
+ touchedFiles: string[];
27
+ materialNodes: PacketMaterialNode[];
28
+ checks: PacketCheck[];
29
+ gaps: CoverageGap[];
30
+ diff: string;
31
+ }
32
+ export interface BuildReviewPacketOptions {
33
+ /** Absolute path of the fingerprint package directory (default: cwd/.ghost). */
34
+ packageDir?: string;
35
+ runProbes?: boolean;
36
+ cwd?: string;
37
+ probeTimeoutMs?: number;
38
+ }
39
+ export declare function buildReviewPacket(fingerprint: LoadedFingerprintPackage, diffText: string, options?: BuildReviewPacketOptions): Promise<ReviewPacket>;
40
+ export declare function formatReviewPacket(packet: ReviewPacket): string;
41
+ //# sourceMappingURL=review-packet.d.ts.map