@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,52 @@
|
|
|
1
|
+
const URL_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
|
|
2
|
+
/**
|
|
3
|
+
* Classify a material locator. `https://…` locators point outside the repo;
|
|
4
|
+
* everything else is a repo-relative path/glob after validation.
|
|
5
|
+
*/
|
|
6
|
+
export function classifyMaterialLocator(value) {
|
|
7
|
+
return value.startsWith("https://")
|
|
8
|
+
? { kind: "url", value }
|
|
9
|
+
: { kind: "local", value };
|
|
10
|
+
}
|
|
11
|
+
/** Return a human-readable validation error, or null when the locator is valid. */
|
|
12
|
+
export function validateMaterialLocator(value) {
|
|
13
|
+
if (value.trim() !== value) {
|
|
14
|
+
return "material locator must not have leading or trailing whitespace";
|
|
15
|
+
}
|
|
16
|
+
if (value.length === 0) {
|
|
17
|
+
return "material locator must not be empty";
|
|
18
|
+
}
|
|
19
|
+
if (URL_SCHEME.test(value)) {
|
|
20
|
+
if (!value.startsWith("https://")) {
|
|
21
|
+
return "material URL locators must use https://";
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const url = new URL(value);
|
|
25
|
+
if (url.protocol !== "https:" || url.hostname.length === 0) {
|
|
26
|
+
return "material URL locators must be absolute https URLs";
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return "material URL locator is not a valid URL";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (value.startsWith("/") || value.startsWith("\\")) {
|
|
35
|
+
return "local material locators must be repo-relative, not absolute paths";
|
|
36
|
+
}
|
|
37
|
+
if (/^[a-zA-Z]:[\\/]/.test(value)) {
|
|
38
|
+
return "local material locators must be repo-relative, not absolute paths";
|
|
39
|
+
}
|
|
40
|
+
const normalized = value.replace(/\\/g, "/");
|
|
41
|
+
if (normalized === ".." ||
|
|
42
|
+
normalized.startsWith("../") ||
|
|
43
|
+
normalized.endsWith("/..") ||
|
|
44
|
+
normalized.includes("/../")) {
|
|
45
|
+
return "local material locators must not escape the repo with '..'";
|
|
46
|
+
}
|
|
47
|
+
if (normalized.startsWith("~/")) {
|
|
48
|
+
return "local material locators must be repo-relative, not home-relative paths";
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=materials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"materials.js","sourceRoot":"","sources":["../../src/ghost-core/materials.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAE1C;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAa;IAEb,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC;QACjC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;QACxB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;QAC3B,OAAO,+DAA+D,CAAC;IACzE,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,oCAAoC,CAAC;IAC9C,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,OAAO,yCAAyC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3D,OAAO,mDAAmD,CAAC;YAC7D,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,yCAAyC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,OAAO,mEAAmE,CAAC;IAC7E,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,mEAAmE,CAAC;IAC7E,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC7C,IACE,UAAU,KAAK,IAAI;QACnB,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC;QAC5B,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC1B,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAC3B,CAAC;QACD,OAAO,4DAA4D,CAAC;IACtE,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,OAAO,wEAAwE,CAAC;IAClF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for `ghost.node/v1` — the node artifact: markdown +
|
|
3
|
+
* frontmatter, the single unit a fingerprint corpus is made of: schema +
|
|
4
|
+
* types + parse + serialize.
|
|
5
|
+
*/
|
|
6
|
+
export { lintGhostNode, type ParseNodeResult, parseNode } from "./parse.js";
|
|
7
|
+
export { GhostNodeFrontmatterSchema, NodeIdSchema, NodeRefSchema, } from "./schema.js";
|
|
8
|
+
export { serializeNode } from "./serialize.js";
|
|
9
|
+
export { carriesConcreteMaterial, extractSkeletonFences, extractSkeletonSections, type FencedBlock, hasSubstantialFencedExample, hasThreeLineFence, type SkeletonSection, stripSkeletonSections, } from "./steering.js";
|
|
10
|
+
export { GHOST_NODE_SCHEMA, type GhostNodeDocument, type GhostNodeFrontmatter, type GhostNodeLintIssue, type GhostNodeLintReport, type GhostNodeLintSeverity, } from "./types.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EACL,0BAA0B,EAC1B,YAAY,EACZ,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,WAAW,EAChB,2BAA2B,EAC3B,iBAAiB,EACjB,KAAK,eAAe,EACpB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for `ghost.node/v1` — the node artifact: markdown +
|
|
3
|
+
* frontmatter, the single unit a fingerprint corpus is made of: schema +
|
|
4
|
+
* types + parse + serialize.
|
|
5
|
+
*/
|
|
6
|
+
export { lintGhostNode, parseNode } from "./parse.js";
|
|
7
|
+
export { GhostNodeFrontmatterSchema, NodeIdSchema, NodeRefSchema, } from "./schema.js";
|
|
8
|
+
export { serializeNode } from "./serialize.js";
|
|
9
|
+
export { carriesConcreteMaterial, extractSkeletonFences, extractSkeletonSections, hasSubstantialFencedExample, hasThreeLineFence, stripSkeletonSections, } from "./steering.js";
|
|
10
|
+
export { GHOST_NODE_SCHEMA, } from "./types.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ghost-core/node/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAwB,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EACL,0BAA0B,EAC1B,YAAY,EACZ,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EAEvB,2BAA2B,EAC3B,iBAAiB,EAEjB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,GAMlB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GhostNodeDocument, GhostNodeLintReport } from "./types.js";
|
|
2
|
+
export interface ParseNodeResult {
|
|
3
|
+
/** The validated node, or null when the artifact failed to parse/validate. */
|
|
4
|
+
node: GhostNodeDocument | null;
|
|
5
|
+
report: GhostNodeLintReport;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Parse and validate a single `ghost.node/v1` markdown artifact (frontmatter +
|
|
9
|
+
* prose body) in isolation. Per-node only: frontmatter shape, material
|
|
10
|
+
* locators, and a non-empty prose body. Corpus-level rules (glossary kind
|
|
11
|
+
* prefixes, check references) are a later phase.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseNode(raw: string): ParseNodeResult;
|
|
14
|
+
/** Lint a node artifact, returning only the report (per-node validation). */
|
|
15
|
+
export declare function lintGhostNode(raw: string): GhostNodeLintReport;
|
|
16
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/parse.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EAEjB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAWD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAuCtD;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAE9D"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { splitMarkdownFrontmatter } from "../markdown.js";
|
|
2
|
+
import { GhostNodeFrontmatterSchema } from "./schema.js";
|
|
3
|
+
function finalize(issues) {
|
|
4
|
+
return {
|
|
5
|
+
issues,
|
|
6
|
+
errors: issues.filter((i) => i.severity === "error").length,
|
|
7
|
+
warnings: issues.filter((i) => i.severity === "warning").length,
|
|
8
|
+
info: issues.filter((i) => i.severity === "info").length,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Parse and validate a single `ghost.node/v1` markdown artifact (frontmatter +
|
|
13
|
+
* prose body) in isolation. Per-node only: frontmatter shape, material
|
|
14
|
+
* locators, and a non-empty prose body. Corpus-level rules (glossary kind
|
|
15
|
+
* prefixes, check references) are a later phase.
|
|
16
|
+
*/
|
|
17
|
+
export function parseNode(raw) {
|
|
18
|
+
const { frontmatter, body } = splitMarkdownFrontmatter(raw);
|
|
19
|
+
if (frontmatter === null) {
|
|
20
|
+
return {
|
|
21
|
+
node: null,
|
|
22
|
+
report: finalize([
|
|
23
|
+
{
|
|
24
|
+
severity: "error",
|
|
25
|
+
rule: "node-missing-frontmatter",
|
|
26
|
+
message: "node must begin with a YAML frontmatter block (---\\n<yaml>\\n---)",
|
|
27
|
+
},
|
|
28
|
+
]),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// The body is design-expression content; surrounding blank lines are not
|
|
32
|
+
// meaningful. Normalize them so serialize → parse round-trips are stable.
|
|
33
|
+
const normalizedBody = body.replace(/^\n+/, "").replace(/\s+$/, "");
|
|
34
|
+
const result = GhostNodeFrontmatterSchema.safeParse(frontmatter);
|
|
35
|
+
if (!result.success) {
|
|
36
|
+
return {
|
|
37
|
+
node: null,
|
|
38
|
+
report: finalize(result.error.issues.map((issue) => ({
|
|
39
|
+
severity: "error",
|
|
40
|
+
rule: `schema/${issue.code}`,
|
|
41
|
+
message: issue.message,
|
|
42
|
+
path: issue.path.length ? issue.path.join(".") : undefined,
|
|
43
|
+
}))),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
node: { frontmatter: result.data, body: normalizedBody },
|
|
48
|
+
report: finalize([]),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** Lint a node artifact, returning only the report (per-node validation). */
|
|
52
|
+
export function lintGhostNode(raw) {
|
|
53
|
+
return parseNode(raw).report;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/ghost-core/node/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAazD,SAAS,QAAQ,CAAC,MAA4B;IAC5C,OAAO;QACL,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM;QAC3D,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM;QAC/D,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM;KACzD,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAC5D,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO;YACL,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,QAAQ,CAAC;gBACf;oBACE,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE,0BAA0B;oBAChC,OAAO,EACL,oEAAoE;iBACvE;aACF,CAAC;SACH,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,0EAA0E;IAC1E,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAEpE,MAAM,MAAM,GAAG,0BAA0B,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO;YACL,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,QAAQ,CACd,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAClC,QAAQ,EAAE,OAAgB;gBAC1B,IAAI,EAAE,UAAU,KAAK,CAAC,IAAI,EAAE;gBAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;aAC3D,CAAC,CAAC,CACJ;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE;QACxD,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;KACrB,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const NodeIdSchema: z.ZodString;
|
|
3
|
+
declare const NodeRefSchema: z.ZodString;
|
|
4
|
+
/**
|
|
5
|
+
* Zod schema for a `ghost.node/v1` frontmatter block.
|
|
6
|
+
*
|
|
7
|
+
* Validates a node in isolation. Identity and containment are not here: they
|
|
8
|
+
* come from the node's file path. Kind is the filename prefix, never a
|
|
9
|
+
* frontmatter field.
|
|
10
|
+
*/
|
|
11
|
+
export declare const GhostNodeFrontmatterSchema: z.ZodObject<{
|
|
12
|
+
description: z.ZodOptional<z.ZodString>;
|
|
13
|
+
materials: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
14
|
+
relates: z.ZodOptional<z.ZodNever>;
|
|
15
|
+
}, z.core.$loose>;
|
|
16
|
+
export { NodeIdSchema, NodeRefSchema };
|
|
17
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,QAAA,MAAM,YAAY,aAGhB,CAAC;AAEH,QAAA,MAAM,aAAa,aAEjB,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B;;;;iBAuBvB,CAAC;AAEjB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { validateMaterialLocator } from "../materials.js";
|
|
3
|
+
/**
|
|
4
|
+
* A node id is its path within the package, `.md` dropped (`marketing/email`).
|
|
5
|
+
* Directory nesting is only file organization; it does not create parents,
|
|
6
|
+
* ancestors, or semantic hierarchy. A segment is a permissive lowercase slug
|
|
7
|
+
* (alphanumeric plus `.` `_` `-`); segments join with `/`. No leading,
|
|
8
|
+
* trailing, or doubled slash. Ids are computed by the loader from the file
|
|
9
|
+
* path, never authored in frontmatter.
|
|
10
|
+
*/
|
|
11
|
+
const NODE_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*(?:\/[a-z0-9][a-z0-9._-]*)*$/;
|
|
12
|
+
const NodeIdSchema = z.string().min(1).regex(NODE_ID_PATTERN, {
|
|
13
|
+
message: "node id must be a path of lowercase slug segments joined by '/' (alphanumeric plus . _ -, no leading/trailing/doubled slash)",
|
|
14
|
+
});
|
|
15
|
+
const NodeRefSchema = z.string().min(1).regex(NODE_ID_PATTERN, {
|
|
16
|
+
message: "node ref must be a path id like 'marketing/email'",
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Zod schema for a `ghost.node/v1` frontmatter block.
|
|
20
|
+
*
|
|
21
|
+
* Validates a node in isolation. Identity and containment are not here: they
|
|
22
|
+
* come from the node's file path. Kind is the filename prefix, never a
|
|
23
|
+
* frontmatter field.
|
|
24
|
+
*/
|
|
25
|
+
export const GhostNodeFrontmatterSchema = z
|
|
26
|
+
.object({
|
|
27
|
+
description: z.string().min(1).optional(),
|
|
28
|
+
materials: z
|
|
29
|
+
.array(z
|
|
30
|
+
.string()
|
|
31
|
+
.min(1)
|
|
32
|
+
.superRefine((locator, ctx) => {
|
|
33
|
+
const message = validateMaterialLocator(locator);
|
|
34
|
+
if (message !== null)
|
|
35
|
+
ctx.addIssue({ code: "custom", message });
|
|
36
|
+
}))
|
|
37
|
+
.optional(),
|
|
38
|
+
// `relates` (and all typed edges) were removed. Reject it with a message
|
|
39
|
+
// that names the key so authors get a clear signal.
|
|
40
|
+
relates: z
|
|
41
|
+
.never({ message: "`relates` is a removed key (edges no longer exist)" })
|
|
42
|
+
.optional(),
|
|
43
|
+
})
|
|
44
|
+
// Passthrough, not strict: authors may add free-form descriptive keys
|
|
45
|
+
// (e.g. `audience`, `stage`) that describe what the node is. Ghost does not
|
|
46
|
+
// gate on them — they ride along as part of the node's descriptive surface.
|
|
47
|
+
.passthrough();
|
|
48
|
+
export { NodeIdSchema, NodeRefSchema };
|
|
49
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/ghost-core/node/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,eAAe,GAAG,mDAAmD,CAAC;AAE5E,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,EAAE;IAC5D,OAAO,EACL,8HAA8H;CACjI,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,EAAE;IAC7D,OAAO,EAAE,mDAAmD;CAC7D,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC;KACxC,MAAM,CAAC;IACN,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,SAAS,EAAE,CAAC;SACT,KAAK,CACJ,CAAC;SACE,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,WAAW,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;QAC5B,MAAM,OAAO,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,OAAO,KAAK,IAAI;YAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CACL;SACA,QAAQ,EAAE;IACb,yEAAyE;IACzE,oDAAoD;IACpD,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,EAAE,OAAO,EAAE,oDAAoD,EAAE,CAAC;SACxE,QAAQ,EAAE;CACd,CAAC;IACF,sEAAsE;IACtE,4EAA4E;IAC5E,4EAA4E;KAC3E,WAAW,EAAE,CAAC;AAEjB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GhostNodeDocument, GhostNodeFrontmatter } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Serialize a node back to its `---\n<yaml>\n---\n<body>` markdown form. Known
|
|
4
|
+
* keys are emitted first in a stable order (description, materials), followed
|
|
5
|
+
* by any free-form descriptive keys in alphabetical order so round-trips and
|
|
6
|
+
* diffs are deterministic. Identity and kind are not serialized — they come
|
|
7
|
+
* from the node's file path and optional filename prefix. Undefined fields are
|
|
8
|
+
* omitted; a node with no frontmatter fields emits an empty block.
|
|
9
|
+
*/
|
|
10
|
+
export declare function serializeNode(node: GhostNodeDocument): string;
|
|
11
|
+
export type { GhostNodeFrontmatter };
|
|
12
|
+
//# sourceMappingURL=serialize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/serialize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAQ1E;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CA0B7D;AAED,YAAY,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
2
|
+
const FRONTMATTER_KEY_ORDER = ["description", "materials"];
|
|
3
|
+
function shouldSerializeFrontmatterValue(value) {
|
|
4
|
+
return value !== undefined;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Serialize a node back to its `---\n<yaml>\n---\n<body>` markdown form. Known
|
|
8
|
+
* keys are emitted first in a stable order (description, materials), followed
|
|
9
|
+
* by any free-form descriptive keys in alphabetical order so round-trips and
|
|
10
|
+
* diffs are deterministic. Identity and kind are not serialized — they come
|
|
11
|
+
* from the node's file path and optional filename prefix. Undefined fields are
|
|
12
|
+
* omitted; a node with no frontmatter fields emits an empty block.
|
|
13
|
+
*/
|
|
14
|
+
export function serializeNode(node) {
|
|
15
|
+
const fm = node.frontmatter;
|
|
16
|
+
const ordered = {};
|
|
17
|
+
const emitted = new Set();
|
|
18
|
+
for (const key of FRONTMATTER_KEY_ORDER) {
|
|
19
|
+
const value = fm[key];
|
|
20
|
+
if (shouldSerializeFrontmatterValue(value)) {
|
|
21
|
+
ordered[key] = value;
|
|
22
|
+
emitted.add(key);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
for (const key of Object.keys(fm).sort()) {
|
|
26
|
+
if (emitted.has(key))
|
|
27
|
+
continue;
|
|
28
|
+
const value = fm[key];
|
|
29
|
+
if (shouldSerializeFrontmatterValue(value))
|
|
30
|
+
ordered[key] = value;
|
|
31
|
+
}
|
|
32
|
+
// An empty frontmatter object stringifies to "{}"; emit a bare block instead.
|
|
33
|
+
const yaml = Object.keys(ordered).length === 0
|
|
34
|
+
? ""
|
|
35
|
+
: `${stringifyYaml(ordered).trimEnd()}\n`;
|
|
36
|
+
const body = node.body.replace(/^\n+/, "");
|
|
37
|
+
return `---\n${yaml}---\n${body.length ? `\n${body}\n` : "\n"}`;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=serialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../../src/ghost-core/node/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC;AAGlD,MAAM,qBAAqB,GAAG,CAAC,aAAa,EAAE,WAAW,CAAU,CAAC;AAEpE,SAAS,+BAA+B,CAAC,KAAc;IACrD,OAAO,KAAK,KAAK,SAAS,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,MAAM,EAAE,GAAG,IAAI,CAAC,WAAsC,CAAC;IACvD,MAAM,OAAO,GAA4B,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,MAAM,GAAG,IAAI,qBAAqB,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,+BAA+B,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC/B,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,+BAA+B,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnE,CAAC;IAED,8EAA8E;IAC9E,MAAM,IAAI,GACR,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;QAC/B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3C,OAAO,QAAQ,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface FencedBlock {
|
|
2
|
+
fence: string;
|
|
3
|
+
info?: string;
|
|
4
|
+
content: string;
|
|
5
|
+
}
|
|
6
|
+
export interface SkeletonSection {
|
|
7
|
+
body: string;
|
|
8
|
+
fences: FencedBlock[];
|
|
9
|
+
}
|
|
10
|
+
export declare function carriesConcreteMaterial(input: {
|
|
11
|
+
materials?: string[];
|
|
12
|
+
body: string;
|
|
13
|
+
}): boolean;
|
|
14
|
+
export declare function hasSubstantialFencedExample(body: string): boolean;
|
|
15
|
+
export declare function hasThreeLineFence(body: string): boolean;
|
|
16
|
+
export declare function extractSkeletonSections(body: string): SkeletonSection[];
|
|
17
|
+
export declare function extractSkeletonFences(body: string): FencedBlock[];
|
|
18
|
+
export declare function stripSkeletonSections(body: string): string;
|
|
19
|
+
//# sourceMappingURL=steering.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steering.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/steering.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAMV;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKvD;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE,CASvE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAEjE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAc1D"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const FENCED_BLOCK_PATTERN = /(^|\n)(`{3,}|~{3,})[^\n]*\n([\s\S]*?)\n\2[ \t]*(?=\n|$)/g;
|
|
2
|
+
const SKELETON_HEADING_PATTERN = /^##[ \t]+Skeleton[ \t]*$/gim;
|
|
3
|
+
export function carriesConcreteMaterial(input) {
|
|
4
|
+
return ((input.materials?.length ?? 0) > 0 ||
|
|
5
|
+
hasSubstantialFencedExample(input.body) ||
|
|
6
|
+
extractSkeletonSections(input.body).length > 0);
|
|
7
|
+
}
|
|
8
|
+
export function hasSubstantialFencedExample(body) {
|
|
9
|
+
return hasThreeLineFence(stripSkeletonSections(body));
|
|
10
|
+
}
|
|
11
|
+
export function hasThreeLineFence(body) {
|
|
12
|
+
for (const block of extractFencedBlocks(body)) {
|
|
13
|
+
if (block.content.split(/\r?\n/).length >= 3)
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
export function extractSkeletonSections(body) {
|
|
19
|
+
const headings = [...body.matchAll(SKELETON_HEADING_PATTERN)];
|
|
20
|
+
return headings.map((heading, index) => {
|
|
21
|
+
const start = (heading.index ?? 0) + heading[0].length;
|
|
22
|
+
const next = headings[index + 1];
|
|
23
|
+
const end = next?.index ?? findNextHeading(body, start);
|
|
24
|
+
const sectionBody = body.slice(start, end).trim();
|
|
25
|
+
return { body: sectionBody, fences: extractFencedBlocks(sectionBody) };
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export function extractSkeletonFences(body) {
|
|
29
|
+
return extractSkeletonSections(body).flatMap((section) => section.fences);
|
|
30
|
+
}
|
|
31
|
+
export function stripSkeletonSections(body) {
|
|
32
|
+
const headings = [...body.matchAll(SKELETON_HEADING_PATTERN)];
|
|
33
|
+
if (headings.length === 0)
|
|
34
|
+
return body;
|
|
35
|
+
let stripped = "";
|
|
36
|
+
let cursor = 0;
|
|
37
|
+
for (const heading of headings) {
|
|
38
|
+
const start = heading.index ?? 0;
|
|
39
|
+
const end = findNextHeading(body, start + heading[0].length);
|
|
40
|
+
stripped += body.slice(cursor, start);
|
|
41
|
+
cursor = end;
|
|
42
|
+
}
|
|
43
|
+
stripped += body.slice(cursor);
|
|
44
|
+
return stripped.replace(/\n{3,}/g, "\n\n").trim();
|
|
45
|
+
}
|
|
46
|
+
function extractFencedBlocks(body) {
|
|
47
|
+
const blocks = [];
|
|
48
|
+
for (const match of body.matchAll(FENCED_BLOCK_PATTERN)) {
|
|
49
|
+
const openingLine = body
|
|
50
|
+
.slice((match.index ?? 0) + (match[1]?.length ?? 0))
|
|
51
|
+
.split(/\r?\n/, 1)[0];
|
|
52
|
+
const open = /^(?<fence>`{3,}|~{3,})(?<info>.*)$/.exec(openingLine);
|
|
53
|
+
const fence = open?.groups?.fence ?? match[2] ?? "```";
|
|
54
|
+
const info = open?.groups?.info?.trim();
|
|
55
|
+
blocks.push({
|
|
56
|
+
fence,
|
|
57
|
+
...(info ? { info } : {}),
|
|
58
|
+
content: match[3] ?? "",
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return blocks;
|
|
62
|
+
}
|
|
63
|
+
function findNextHeading(body, start) {
|
|
64
|
+
const rest = body.slice(start);
|
|
65
|
+
const match = /^#{1,6}[ \t]+.+$/m.exec(rest);
|
|
66
|
+
return match?.index === undefined ? body.length : start + match.index;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=steering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steering.js","sourceRoot":"","sources":["../../../src/ghost-core/node/steering.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export declare const GHOST_NODE_SCHEMA: "ghost.node/v1";
|
|
2
|
+
/**
|
|
3
|
+
* A node's frontmatter: descriptive properties only. Identity, kind, and
|
|
4
|
+
* containment are not here — the file path is the node id, and the optional
|
|
5
|
+
* filename prefix is the kind. The prose body carries the design expression;
|
|
6
|
+
* why / with-what / how-assembled are drafting prompts, never fields.
|
|
7
|
+
*/
|
|
8
|
+
export interface GhostNodeFrontmatter {
|
|
9
|
+
/** Free-form descriptive properties parsed from node frontmatter. */
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
/**
|
|
12
|
+
* Retrieval payload shown by gather: what the node governs, the observable
|
|
13
|
+
* condition under which it applies, and what it contributes where useful.
|
|
14
|
+
* Together with the node's id, it is how an agent decides applicability.
|
|
15
|
+
* Optional, but strongly encouraged on any node worth anchoring a task at.
|
|
16
|
+
*/
|
|
17
|
+
description?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Optional locators for the concrete materials this truth is about: repo-relative
|
|
20
|
+
* paths/globs and absolute https URLs. Guidance stays in prose; this list is
|
|
21
|
+
* only where the agent or review harness can find the material.
|
|
22
|
+
*/
|
|
23
|
+
materials?: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface GhostNodeDocument {
|
|
26
|
+
frontmatter: GhostNodeFrontmatter;
|
|
27
|
+
/** The markdown body: prose design expression. */
|
|
28
|
+
body: string;
|
|
29
|
+
}
|
|
30
|
+
export type GhostNodeLintSeverity = "error" | "warning" | "info";
|
|
31
|
+
export interface GhostNodeLintIssue {
|
|
32
|
+
severity: GhostNodeLintSeverity;
|
|
33
|
+
rule: string;
|
|
34
|
+
message: string;
|
|
35
|
+
path?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface GhostNodeLintReport {
|
|
38
|
+
issues: GhostNodeLintIssue[];
|
|
39
|
+
errors: number;
|
|
40
|
+
warnings: number;
|
|
41
|
+
info: number;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/ghost-core/node/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,EAAG,eAAwB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,oBAAoB,CAAC;IAClC,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,qBAAqB,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/ghost-core/node/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAwB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const GHOST_FINGERPRINT_PACKAGE_SCHEMA: "ghost.fingerprint-package/v1";
|
|
3
|
+
/** `manifest.yml` — anchors a `.ghost/` package. */
|
|
4
|
+
export declare const GhostFingerprintPackageManifestSchema: z.ZodObject<{
|
|
5
|
+
schema: z.ZodLiteral<"ghost.fingerprint-package/v1">;
|
|
6
|
+
id: z.ZodString;
|
|
7
|
+
cover: z.ZodOptional<z.ZodString>;
|
|
8
|
+
}, z.core.$strict>;
|
|
9
|
+
export interface GhostFingerprintPackageManifest {
|
|
10
|
+
schema: typeof GHOST_FINGERPRINT_PACKAGE_SCHEMA;
|
|
11
|
+
id: string;
|
|
12
|
+
/**
|
|
13
|
+
* Optional id of the cover node: the one node gather inlines above the menu on
|
|
14
|
+
* every invocation. Guaranteed presence for content selection cannot retrieve
|
|
15
|
+
* — essence, temperature, brand-level refusals.
|
|
16
|
+
*/
|
|
17
|
+
cover?: string;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=package-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manifest.d.ts","sourceRoot":"","sources":["../../src/ghost-core/package-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gCAAgC,EAC3C,8BAAuC,CAAC;AAe1C,oDAAoD;AACpD,eAAO,MAAM,qCAAqC;;;;kBAWvC,CAAC;AAEZ,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,OAAO,gCAAgC,CAAC;IAChD,EAAE,EAAE,MAAM,CAAC;IACX;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const GHOST_FINGERPRINT_PACKAGE_SCHEMA = "ghost.fingerprint-package/v1";
|
|
3
|
+
const SlugIdSchema = z
|
|
4
|
+
.string()
|
|
5
|
+
.min(1)
|
|
6
|
+
.regex(/^[a-z0-9][a-z0-9._-]*$/, "id must be a lowercase slug (a-z, 0-9, '.', '_', '-')");
|
|
7
|
+
const NodeIdSchema = z
|
|
8
|
+
.string()
|
|
9
|
+
.min(1)
|
|
10
|
+
.regex(/^[a-z0-9][a-z0-9./_-]*$/, "cover must be a node id");
|
|
11
|
+
/** `manifest.yml` — anchors a `.ghost/` package. */
|
|
12
|
+
export const GhostFingerprintPackageManifestSchema = z
|
|
13
|
+
.object({
|
|
14
|
+
schema: z.literal(GHOST_FINGERPRINT_PACKAGE_SCHEMA),
|
|
15
|
+
id: SlugIdSchema,
|
|
16
|
+
/**
|
|
17
|
+
* Optional id of the cover node: the one node gather inlines above the menu
|
|
18
|
+
* on every invocation. Guaranteed presence for content selection cannot
|
|
19
|
+
* retrieve — essence, temperature, brand-level refusals.
|
|
20
|
+
*/
|
|
21
|
+
cover: NodeIdSchema.optional(),
|
|
22
|
+
})
|
|
23
|
+
.strict();
|
|
24
|
+
//# sourceMappingURL=package-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manifest.js","sourceRoot":"","sources":["../../src/ghost-core/package-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gCAAgC,GAC3C,8BAAuC,CAAC;AAE1C,MAAM,YAAY,GAAG,CAAC;KACnB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,KAAK,CACJ,wBAAwB,EACxB,uDAAuD,CACxD,CAAC;AAEJ,MAAM,YAAY,GAAG,CAAC;KACnB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,KAAK,CAAC,yBAAyB,EAAE,yBAAyB,CAAC,CAAC;AAE/D,oDAAoD;AACpD,MAAM,CAAC,MAAM,qCAAqC,GAAG,CAAC;KACnD,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,gCAAgC,CAAC;IACnD,EAAE,EAAE,YAAY;IAChB;;;;OAIG;IACH,KAAK,EAAE,YAAY,CAAC,QAAQ,EAAE;CAC/B,CAAC;KACD,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic loader for an agentskills.io-compatible skill bundle.
|
|
3
|
+
*
|
|
4
|
+
* Each tool in the Ghost monorepo (`ghost`, `ghost`, …) ships
|
|
5
|
+
* its own skill bundle as real markdown under `src/skill-bundle/` and copies
|
|
6
|
+
* it verbatim to `dist/skill-bundle/` at build time. This loader walks any
|
|
7
|
+
* given root directory and returns a flat, deterministically ordered list of
|
|
8
|
+
* files so the unified `ghost skill install` verb can write them into a target
|
|
9
|
+
* project.
|
|
10
|
+
*
|
|
11
|
+
* Spec: https://agentskills.io/specification
|
|
12
|
+
*/
|
|
13
|
+
export interface SkillBundleFile {
|
|
14
|
+
/** Path relative to the skill root (e.g. "SKILL.md", "references/schema.md"). */
|
|
15
|
+
path: string;
|
|
16
|
+
content: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Load a skill bundle from disk.
|
|
20
|
+
*
|
|
21
|
+
* `bundleRoot` should point to a directory containing at least a `SKILL.md`
|
|
22
|
+
* file at the top level (typically `dist/skill-bundle/` after the host
|
|
23
|
+
* package's build step has copied the markdown sources from `src/`).
|
|
24
|
+
*
|
|
25
|
+
* The returned list is sorted with `SKILL.md` first, then alphabetically.
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadSkillBundle(bundleRoot: string): SkillBundleFile[];
|
|
28
|
+
//# sourceMappingURL=skill-bundle-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-bundle-loader.d.ts","sourceRoot":"","sources":["../../src/ghost-core/skill-bundle-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAiBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,EAAE,CASrE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic loader for an agentskills.io-compatible skill bundle.
|
|
3
|
+
*
|
|
4
|
+
* Each tool in the Ghost monorepo (`ghost`, `ghost`, …) ships
|
|
5
|
+
* its own skill bundle as real markdown under `src/skill-bundle/` and copies
|
|
6
|
+
* it verbatim to `dist/skill-bundle/` at build time. This loader walks any
|
|
7
|
+
* given root directory and returns a flat, deterministically ordered list of
|
|
8
|
+
* files so the unified `ghost skill install` verb can write them into a target
|
|
9
|
+
* project.
|
|
10
|
+
*
|
|
11
|
+
* Spec: https://agentskills.io/specification
|
|
12
|
+
*/
|
|
13
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
14
|
+
import { join, relative } from "node:path";
|
|
15
|
+
function walk(dir, root, out) {
|
|
16
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
17
|
+
const absolute = join(dir, entry.name);
|
|
18
|
+
if (entry.isDirectory()) {
|
|
19
|
+
walk(absolute, root, out);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (!entry.isFile())
|
|
23
|
+
continue;
|
|
24
|
+
out.push({
|
|
25
|
+
path: relative(root, absolute),
|
|
26
|
+
content: readFileSync(absolute, "utf-8"),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Load a skill bundle from disk.
|
|
32
|
+
*
|
|
33
|
+
* `bundleRoot` should point to a directory containing at least a `SKILL.md`
|
|
34
|
+
* file at the top level (typically `dist/skill-bundle/` after the host
|
|
35
|
+
* package's build step has copied the markdown sources from `src/`).
|
|
36
|
+
*
|
|
37
|
+
* The returned list is sorted with `SKILL.md` first, then alphabetically.
|
|
38
|
+
*/
|
|
39
|
+
export function loadSkillBundle(bundleRoot) {
|
|
40
|
+
const out = [];
|
|
41
|
+
walk(bundleRoot, bundleRoot, out);
|
|
42
|
+
out.sort((a, b) => {
|
|
43
|
+
if (a.path === "SKILL.md")
|
|
44
|
+
return -1;
|
|
45
|
+
if (b.path === "SKILL.md")
|
|
46
|
+
return 1;
|
|
47
|
+
return a.path.localeCompare(b.path);
|
|
48
|
+
});
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=skill-bundle-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-bundle-loader.js","sourceRoot":"","sources":["../../src/ghost-core/skill-bundle-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAQ3C,SAAS,IAAI,CAAC,GAAW,EAAE,IAAY,EAAE,GAAsB;IAC7D,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YAC1B,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,SAAS;QAC9B,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;YAC9B,OAAO,EAAE,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC;SACzC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAClC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAChB,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,CAAC,CAAC;QACpC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAC9C,iFAAiF;AACjF,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED