@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.
- package/LICENSE +201 -0
- package/README.md +89 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +19 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +29 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/checks-command.d.ts +9 -0
- package/dist/commands/checks-command.d.ts.map +1 -0
- package/dist/commands/checks-command.js +52 -0
- package/dist/commands/checks-command.js.map +1 -0
- package/dist/commands/command-discovery.d.ts +57 -0
- package/dist/commands/command-discovery.d.ts.map +1 -0
- package/dist/commands/command-discovery.js +220 -0
- package/dist/commands/command-discovery.js.map +1 -0
- package/dist/commands/errors.d.ts +7 -0
- package/dist/commands/errors.d.ts.map +1 -0
- package/dist/commands/errors.js +19 -0
- package/dist/commands/errors.js.map +1 -0
- package/dist/commands/export-command.d.ts +3 -0
- package/dist/commands/export-command.d.ts.map +1 -0
- package/dist/commands/export-command.js +157 -0
- package/dist/commands/export-command.js.map +1 -0
- package/dist/commands/fingerprint-commands.d.ts +10 -0
- package/dist/commands/fingerprint-commands.d.ts.map +1 -0
- package/dist/commands/fingerprint-commands.js +69 -0
- package/dist/commands/fingerprint-commands.js.map +1 -0
- package/dist/commands/gather-command.d.ts +3 -0
- package/dist/commands/gather-command.d.ts.map +1 -0
- package/dist/commands/gather-command.js +214 -0
- package/dist/commands/gather-command.js.map +1 -0
- package/dist/commands/init-command.d.ts +3 -0
- package/dist/commands/init-command.d.ts.map +1 -0
- package/dist/commands/init-command.js +89 -0
- package/dist/commands/init-command.js.map +1 -0
- package/dist/commands/manifest-command.d.ts +9 -0
- package/dist/commands/manifest-command.d.ts.map +1 -0
- package/dist/commands/manifest-command.js +33 -0
- package/dist/commands/manifest-command.js.map +1 -0
- package/dist/commands/pull-command.d.ts +3 -0
- package/dist/commands/pull-command.d.ts.map +1 -0
- package/dist/commands/pull-command.js +230 -0
- package/dist/commands/pull-command.js.map +1 -0
- package/dist/commands/pulse-command.d.ts +3 -0
- package/dist/commands/pulse-command.d.ts.map +1 -0
- package/dist/commands/pulse-command.js +248 -0
- package/dist/commands/pulse-command.js.map +1 -0
- package/dist/commands/review-command.d.ts +3 -0
- package/dist/commands/review-command.d.ts.map +1 -0
- package/dist/commands/review-command.js +78 -0
- package/dist/commands/review-command.js.map +1 -0
- package/dist/commands/skill-command.d.ts +3 -0
- package/dist/commands/skill-command.d.ts.map +1 -0
- package/dist/commands/skill-command.js +96 -0
- package/dist/commands/skill-command.js.map +1 -0
- package/dist/fingerprint.d.ts +5 -0
- package/dist/fingerprint.d.ts.map +1 -0
- package/dist/fingerprint.js +3 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/ghost-core/catalog/assemble.d.ts +26 -0
- package/dist/ghost-core/catalog/assemble.d.ts.map +1 -0
- package/dist/ghost-core/catalog/assemble.js +29 -0
- package/dist/ghost-core/catalog/assemble.js.map +1 -0
- package/dist/ghost-core/catalog/closest.d.ts +16 -0
- package/dist/ghost-core/catalog/closest.d.ts.map +1 -0
- package/dist/ghost-core/catalog/closest.js +63 -0
- package/dist/ghost-core/catalog/closest.js.map +1 -0
- package/dist/ghost-core/catalog/index.d.ts +10 -0
- package/dist/ghost-core/catalog/index.d.ts.map +1 -0
- package/dist/ghost-core/catalog/index.js +9 -0
- package/dist/ghost-core/catalog/index.js.map +1 -0
- package/dist/ghost-core/catalog/menu.d.ts +28 -0
- package/dist/ghost-core/catalog/menu.d.ts.map +1 -0
- package/dist/ghost-core/catalog/menu.js +23 -0
- package/dist/ghost-core/catalog/menu.js.map +1 -0
- package/dist/ghost-core/catalog/types.d.ts +33 -0
- package/dist/ghost-core/catalog/types.d.ts.map +1 -0
- package/dist/ghost-core/catalog/types.js +2 -0
- package/dist/ghost-core/catalog/types.js.map +1 -0
- package/dist/ghost-core/check/index.d.ts +12 -0
- package/dist/ghost-core/check/index.d.ts.map +1 -0
- package/dist/ghost-core/check/index.js +12 -0
- package/dist/ghost-core/check/index.js.map +1 -0
- package/dist/ghost-core/check/lint.d.ts +9 -0
- package/dist/ghost-core/check/lint.d.ts.map +1 -0
- package/dist/ghost-core/check/lint.js +119 -0
- package/dist/ghost-core/check/lint.js.map +1 -0
- package/dist/ghost-core/check/load.d.ts +7 -0
- package/dist/ghost-core/check/load.d.ts.map +1 -0
- package/dist/ghost-core/check/load.js +44 -0
- package/dist/ghost-core/check/load.js.map +1 -0
- package/dist/ghost-core/check/parse.d.ts +12 -0
- package/dist/ghost-core/check/parse.d.ts.map +1 -0
- package/dist/ghost-core/check/parse.js +13 -0
- package/dist/ghost-core/check/parse.js.map +1 -0
- package/dist/ghost-core/check/source-ref.d.ts +27 -0
- package/dist/ghost-core/check/source-ref.d.ts.map +1 -0
- package/dist/ghost-core/check/source-ref.js +58 -0
- package/dist/ghost-core/check/source-ref.js.map +1 -0
- package/dist/ghost-core/check/types.d.ts +48 -0
- package/dist/ghost-core/check/types.d.ts.map +1 -0
- package/dist/ghost-core/check/types.js +4 -0
- package/dist/ghost-core/check/types.js.map +1 -0
- package/dist/ghost-core/errors.d.ts +30 -0
- package/dist/ghost-core/errors.d.ts.map +1 -0
- package/dist/ghost-core/errors.js +33 -0
- package/dist/ghost-core/errors.js.map +1 -0
- package/dist/ghost-core/glob.d.ts +5 -0
- package/dist/ghost-core/glob.d.ts.map +1 -0
- package/dist/ghost-core/glob.js +68 -0
- package/dist/ghost-core/glob.js.map +1 -0
- package/dist/ghost-core/glossary.d.ts +25 -0
- package/dist/ghost-core/glossary.d.ts.map +1 -0
- package/dist/ghost-core/glossary.js +69 -0
- package/dist/ghost-core/glossary.js.map +1 -0
- package/dist/ghost-core/index.d.ts +13 -0
- package/dist/ghost-core/index.d.ts.map +1 -0
- package/dist/ghost-core/index.js +19 -0
- package/dist/ghost-core/index.js.map +1 -0
- package/dist/ghost-core/markdown.d.ts +15 -0
- package/dist/ghost-core/markdown.d.ts.map +1 -0
- package/dist/ghost-core/markdown.js +30 -0
- package/dist/ghost-core/markdown.js.map +1 -0
- package/dist/ghost-core/material-transport.d.ts +43 -0
- package/dist/ghost-core/material-transport.d.ts.map +1 -0
- package/dist/ghost-core/material-transport.js +231 -0
- package/dist/ghost-core/material-transport.js.map +1 -0
- package/dist/ghost-core/materials.d.ts +14 -0
- package/dist/ghost-core/materials.d.ts.map +1 -0
- package/dist/ghost-core/materials.js +52 -0
- package/dist/ghost-core/materials.js.map +1 -0
- package/dist/ghost-core/node/index.d.ts +11 -0
- package/dist/ghost-core/node/index.d.ts.map +1 -0
- package/dist/ghost-core/node/index.js +11 -0
- package/dist/ghost-core/node/index.js.map +1 -0
- package/dist/ghost-core/node/parse.d.ts +16 -0
- package/dist/ghost-core/node/parse.d.ts.map +1 -0
- package/dist/ghost-core/node/parse.js +55 -0
- package/dist/ghost-core/node/parse.js.map +1 -0
- package/dist/ghost-core/node/schema.d.ts +17 -0
- package/dist/ghost-core/node/schema.d.ts.map +1 -0
- package/dist/ghost-core/node/schema.js +49 -0
- package/dist/ghost-core/node/schema.js.map +1 -0
- package/dist/ghost-core/node/serialize.d.ts +12 -0
- package/dist/ghost-core/node/serialize.d.ts.map +1 -0
- package/dist/ghost-core/node/serialize.js +39 -0
- package/dist/ghost-core/node/serialize.js.map +1 -0
- package/dist/ghost-core/node/steering.d.ts +19 -0
- package/dist/ghost-core/node/steering.d.ts.map +1 -0
- package/dist/ghost-core/node/steering.js +68 -0
- package/dist/ghost-core/node/steering.js.map +1 -0
- package/dist/ghost-core/node/types.d.ts +43 -0
- package/dist/ghost-core/node/types.d.ts.map +1 -0
- package/dist/ghost-core/node/types.js +2 -0
- package/dist/ghost-core/node/types.js.map +1 -0
- package/dist/ghost-core/package-manifest.d.ts +19 -0
- package/dist/ghost-core/package-manifest.d.ts.map +1 -0
- package/dist/ghost-core/package-manifest.js +24 -0
- package/dist/ghost-core/package-manifest.js.map +1 -0
- package/dist/ghost-core/skill-bundle-loader.d.ts +28 -0
- package/dist/ghost-core/skill-bundle-loader.d.ts.map +1 -0
- package/dist/ghost-core/skill-bundle-loader.js +51 -0
- package/dist/ghost-core/skill-bundle-loader.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/init-payloads/median/cliche.median.md +86 -0
- package/dist/init-payloads/median/median-tells.md +117 -0
- package/dist/init-payloads/skeleton/brand.md +23 -0
- package/dist/init-payloads/skeleton/context.conversation.md +24 -0
- package/dist/init-payloads/skeleton/foundation.color.md +39 -0
- package/dist/init-payloads/skeleton/foundation.composition.md +30 -0
- package/dist/init-payloads/skeleton/foundation.controls.md +29 -0
- package/dist/init-payloads/skeleton/foundation.layout.md +45 -0
- package/dist/init-payloads/skeleton/foundation.motion.md +34 -0
- package/dist/init-payloads/skeleton/foundation.type.md +44 -0
- package/dist/init-payloads/skeleton/foundation.voice.md +29 -0
- package/dist/init-payloads/skeleton/glossary.md +39 -0
- package/dist/init-payloads/vessel-light/anti-goal.median.md +86 -0
- package/dist/init-payloads/vessel-light/anti-goal.tells.md +38 -0
- package/dist/init-payloads/vessel-light/checks/conversation-grammar.md +20 -0
- package/dist/init-payloads/vessel-light/checks/median-tells.md +103 -0
- package/dist/init-payloads/vessel-light/checks/motion-restraint.md +20 -0
- package/dist/init-payloads/vessel-light/checks/relationships.md +33 -0
- package/dist/init-payloads/vessel-light/checks/shape-matches-job.md +43 -0
- package/dist/init-payloads/vessel-light/checks/values.md +51 -0
- package/dist/init-payloads/vessel-light/glossary.md +44 -0
- package/dist/init-payloads/vessel-light/grammar.color-roles.md +30 -0
- package/dist/init-payloads/vessel-light/grammar.conversation.md +30 -0
- package/dist/init-payloads/vessel-light/grammar.deletion.md +35 -0
- package/dist/init-payloads/vessel-light/grammar.hierarchy.md +58 -0
- package/dist/init-payloads/vessel-light/grammar.job.md +54 -0
- package/dist/init-payloads/vessel-light/grammar.motion.md +27 -0
- package/dist/init-payloads/vessel-light/grammar.rhythm.md +27 -0
- package/dist/init-payloads/vessel-light/grammar.surfaces.md +35 -0
- package/dist/init-payloads/vessel-light/index.md +33 -0
- package/dist/init-payloads/vessel-light/manifest.yml +3 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Black.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Bold.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-ExtraBold.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Light.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Medium.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Regular.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-SemiBold.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/primitives.css +351 -0
- package/dist/init-payloads/vessel-light/materials/ref/composition.conversation.html +63 -0
- package/dist/init-payloads/vessel-light/materials/ref/composition.editorial.html +74 -0
- package/dist/init-payloads/vessel-light/materials/ref/composition.form.html +89 -0
- package/dist/init-payloads/vessel-light/materials/ref/composition.overlay.html +66 -0
- package/dist/init-payloads/vessel-light/materials/ref/composition.table.html +104 -0
- package/dist/init-payloads/vessel-light/materials/ref/email.html +80 -0
- package/dist/init-payloads/vessel-light/materials/tokens.css +191 -0
- package/dist/init-payloads/vessel-light/register.data-density.md +39 -0
- package/dist/init-payloads/vessel-light/register.editorial.md +41 -0
- package/dist/init-payloads/vessel-light/register.email.md +43 -0
- package/dist/init-payloads/vessel-light/signature.palette.md +45 -0
- package/dist/init-payloads/vessel-light/signature.shape.md +27 -0
- package/dist/init-payloads/vessel-light/signature.temperature.md +44 -0
- package/dist/init-payloads/vessel-light/signature.type.md +37 -0
- package/dist/internal/fs.d.ts +4 -0
- package/dist/internal/fs.d.ts.map +1 -0
- package/dist/internal/fs.js +24 -0
- package/dist/internal/fs.js.map +1 -0
- package/dist/observability-events.d.ts +34 -0
- package/dist/observability-events.d.ts.map +1 -0
- package/dist/observability-events.js +68 -0
- package/dist/observability-events.js.map +1 -0
- package/dist/package-version.d.ts +3 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +10 -0
- package/dist/package-version.js.map +1 -0
- package/dist/review/baseline.d.ts +11 -0
- package/dist/review/baseline.d.ts.map +1 -0
- package/dist/review/baseline.js +35 -0
- package/dist/review/baseline.js.map +1 -0
- package/dist/review/diff.d.ts +7 -0
- package/dist/review/diff.d.ts.map +1 -0
- package/dist/review/diff.js +41 -0
- package/dist/review/diff.js.map +1 -0
- package/dist/review/glob.d.ts +2 -0
- package/dist/review/glob.d.ts.map +1 -0
- package/dist/review/glob.js +2 -0
- package/dist/review/glob.js.map +1 -0
- package/dist/review/probes.d.ts +13 -0
- package/dist/review/probes.d.ts.map +1 -0
- package/dist/review/probes.js +45 -0
- package/dist/review/probes.js.map +1 -0
- package/dist/review/resolve.d.ts +28 -0
- package/dist/review/resolve.d.ts.map +1 -0
- package/dist/review/resolve.js +90 -0
- package/dist/review/resolve.js.map +1 -0
- package/dist/review/review-packet.d.ts +41 -0
- package/dist/review/review-packet.d.ts.map +1 -0
- package/dist/review/review-packet.js +128 -0
- package/dist/review/review-packet.js.map +1 -0
- package/dist/scan/check-files.d.ts +23 -0
- package/dist/scan/check-files.d.ts.map +1 -0
- package/dist/scan/check-files.js +75 -0
- package/dist/scan/check-files.js.map +1 -0
- package/dist/scan/check-scaffold.d.ts +8 -0
- package/dist/scan/check-scaffold.d.ts.map +1 -0
- package/dist/scan/check-scaffold.js +53 -0
- package/dist/scan/check-scaffold.js.map +1 -0
- package/dist/scan/constants.d.ts +21 -0
- package/dist/scan/constants.d.ts.map +1 -0
- package/dist/scan/constants.js +21 -0
- package/dist/scan/constants.js.map +1 -0
- package/dist/scan/file-kind.d.ts +12 -0
- package/dist/scan/file-kind.d.ts.map +1 -0
- package/dist/scan/file-kind.js +114 -0
- package/dist/scan/file-kind.js.map +1 -0
- package/dist/scan/fingerprint-package-lint.d.ts +8 -0
- package/dist/scan/fingerprint-package-lint.d.ts.map +1 -0
- package/dist/scan/fingerprint-package-lint.js +284 -0
- package/dist/scan/fingerprint-package-lint.js.map +1 -0
- package/dist/scan/fingerprint-package-loader.d.ts +5 -0
- package/dist/scan/fingerprint-package-loader.d.ts.map +1 -0
- package/dist/scan/fingerprint-package-loader.js +78 -0
- package/dist/scan/fingerprint-package-loader.js.map +1 -0
- package/dist/scan/fingerprint-package.d.ts +66 -0
- package/dist/scan/fingerprint-package.d.ts.map +1 -0
- package/dist/scan/fingerprint-package.js +101 -0
- package/dist/scan/fingerprint-package.js.map +1 -0
- package/dist/scan/index.d.ts +3 -0
- package/dist/scan/index.d.ts.map +1 -0
- package/dist/scan/index.js +3 -0
- package/dist/scan/index.js.map +1 -0
- package/dist/scan/lint.d.ts +15 -0
- package/dist/scan/lint.d.ts.map +1 -0
- package/dist/scan/lint.js +2 -0
- package/dist/scan/lint.js.map +1 -0
- package/dist/scan/node-files.d.ts +25 -0
- package/dist/scan/node-files.d.ts.map +1 -0
- package/dist/scan/node-files.js +112 -0
- package/dist/scan/node-files.js.map +1 -0
- package/dist/scan/package-paths.d.ts +10 -0
- package/dist/scan/package-paths.d.ts.map +1 -0
- package/dist/scan/package-paths.js +49 -0
- package/dist/scan/package-paths.js.map +1 -0
- package/dist/scan/packed-payloads.d.ts +4 -0
- package/dist/scan/packed-payloads.d.ts.map +1 -0
- package/dist/scan/packed-payloads.js +55 -0
- package/dist/scan/packed-payloads.js.map +1 -0
- package/dist/scan/tarball.d.ts +23 -0
- package/dist/scan/tarball.d.ts.map +1 -0
- package/dist/scan/tarball.js +145 -0
- package/dist/scan/tarball.js.map +1 -0
- package/dist/scan/templates.d.ts +42 -0
- package/dist/scan/templates.d.ts.map +1 -0
- package/dist/scan/templates.js +375 -0
- package/dist/scan/templates.js.map +1 -0
- package/dist/skill-bundle/SKILL.md +146 -0
- package/dist/skill-bundle/references/adapting-a-starter.md +104 -0
- package/dist/skill-bundle/references/authoring-scenarios.md +184 -0
- package/dist/skill-bundle/references/blocks.md +179 -0
- package/dist/skill-bundle/references/brief.md +50 -0
- package/dist/skill-bundle/references/capture.md +392 -0
- package/dist/skill-bundle/references/concrete-tiers.md +95 -0
- package/dist/skill-bundle/references/recall.md +36 -0
- package/dist/skill-bundle/references/schema.md +114 -0
- package/dist/skill-bundle/references/self-check.md +65 -0
- package/dist/skill-bundle/references/steering-audit.md +60 -0
- 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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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
|