@graphorin/skills 0.6.0 → 0.7.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @graphorin/skills
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#154](https://github.com/o-stepper/graphorin/pull/154) [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04) Thanks [@o-stepper](https://github.com/o-stepper)! - W-072: every export map's `import` condition becomes `default`, and the Node floor rises to `>=22.12.0`.
8
+
9
+ CJS consumers previously hit a bewildering `ERR_PACKAGE_PATH_NOT_EXPORTED` instead of a clear ESM-only signal. With the `default` condition, plain `require('@graphorin/core')` works via Node's stable `require(esm)` - which shipped in 22.12, hence the engines bump across every workspace manifest (packages, examples, benchmarks, docs; enforced by the widened mvp-readiness sweep). No dual-instance hazard: there is no CJS build, `require()` returns the same ESM module instance. ESM consumers are unaffected (`default` serves both paths; `types` stays first). The pack gate now runs attw under the full `node16` profile (was `esm-only`) and adds a runtime `require(esm)` smoke against the packed tarballs. Installs on Node 22.0-22.11 with `engine-strict` will refuse - upgrade Node (see the migration guide).
10
+
11
+ ### Patch Changes
12
+
13
+ - [#162](https://github.com/o-stepper/graphorin/pull/162) [`73b19ca`](https://github.com/o-stepper/graphorin/commit/73b19caeda388bda628a48138cb7d70b1db839a3) Thanks [@o-stepper](https://github.com/o-stepper)! - Remove phantom workspace dependencies that no source file imports: agent no longer depends on provider and observability, mcp/workflow/server no longer depend on observability, sessions no longer depends on security (and its memory edge moves to devDependencies where the single test import lives), skills no longer depends on tools. Dead tsdown `external` entries for the removed edges are gone too, so a future import can no longer build as external without a declared dependency. Consumer install graphs shrink accordingly; a new repo-wide `check-phantom-deps` CI gate keeps the manifest graph honest from here on.
14
+
15
+ - [#164](https://github.com/o-stepper/graphorin/pull/164) [`764239b`](https://github.com/o-stepper/graphorin/commit/764239b97e0e0202442e91272583f13adeb12d00) Thanks [@o-stepper](https://github.com/o-stepper)! - Tarballs now ship `src/` so the published `dist/**/*.d.ts.map` files actually work (W-136): the maps referenced `../src/*.ts` that the `files` whitelist excluded, so go-to-definition fell back into `.d.ts` and the shipped maps were dead weight. The pack gate gains a `map-integrity` leg: every source referenced by a shipped map must resolve inside the tarball (or be embedded via `sourcesContent`), with an anti-vacuous guard - a package whose tsdown config emits declaration maps must contain a non-zero number of `.d.ts.map` files, so a cache-restored dist that silently dropped maps fails the gate instead of passing vacuously. `mvp-readiness` now requires `src` in every publishable `files` array.
16
+
17
+ - [#164](https://github.com/o-stepper/graphorin/pull/164) [`764239b`](https://github.com/o-stepper/graphorin/commit/764239b97e0e0202442e91272583f13adeb12d00) Thanks [@o-stepper](https://github.com/o-stepper)! - Every published package now declares its tree-shaking contract via `sideEffects` (W-137): 18 packages audited to a pure module scope get `false`, the CLI declares its bin entry (`["./dist/bin/*"]`), and `@graphorin/security` gets an explicit `true` - its secrets subsystem registers built-in resolvers and the SecretValue caller-context provider at import time, so marking it pure would let bundlers drop those registrations. `mvp-readiness` now fails any publishable manifest without a declared `sideEffects`, closing the drift for future packages.
18
+
19
+ - Updated dependencies [[`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`832f22e`](https://github.com/o-stepper/graphorin/commit/832f22e570b8c3175c1adeb4c150070cbd131534), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`832f22e`](https://github.com/o-stepper/graphorin/commit/832f22e570b8c3175c1adeb4c150070cbd131534), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`32bbd03`](https://github.com/o-stepper/graphorin/commit/32bbd03b588136a355e4b5ad6ac5e19b36b4d8ab), [`32bbd03`](https://github.com/o-stepper/graphorin/commit/32bbd03b588136a355e4b5ad6ac5e19b36b4d8ab), [`32bbd03`](https://github.com/o-stepper/graphorin/commit/32bbd03b588136a355e4b5ad6ac5e19b36b4d8ab), [`4ee256e`](https://github.com/o-stepper/graphorin/commit/4ee256e30fe9190cef6c48dc6785464757707156), [`4ee256e`](https://github.com/o-stepper/graphorin/commit/4ee256e30fe9190cef6c48dc6785464757707156), [`4ee256e`](https://github.com/o-stepper/graphorin/commit/4ee256e30fe9190cef6c48dc6785464757707156), [`4ee256e`](https://github.com/o-stepper/graphorin/commit/4ee256e30fe9190cef6c48dc6785464757707156), [`32bbd03`](https://github.com/o-stepper/graphorin/commit/32bbd03b588136a355e4b5ad6ac5e19b36b4d8ab), [`32bbd03`](https://github.com/o-stepper/graphorin/commit/32bbd03b588136a355e4b5ad6ac5e19b36b4d8ab), [`764239b`](https://github.com/o-stepper/graphorin/commit/764239b97e0e0202442e91272583f13adeb12d00), [`764239b`](https://github.com/o-stepper/graphorin/commit/764239b97e0e0202442e91272583f13adeb12d00), [`764239b`](https://github.com/o-stepper/graphorin/commit/764239b97e0e0202442e91272583f13adeb12d00), [`764239b`](https://github.com/o-stepper/graphorin/commit/764239b97e0e0202442e91272583f13adeb12d00), [`764239b`](https://github.com/o-stepper/graphorin/commit/764239b97e0e0202442e91272583f13adeb12d00), [`764239b`](https://github.com/o-stepper/graphorin/commit/764239b97e0e0202442e91272583f13adeb12d00), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04), [`fe98522`](https://github.com/o-stepper/graphorin/commit/fe98522ce2477c9a7dc09029f9dcfdb1f7c9aa04)]:
20
+ - @graphorin/core@0.7.0
21
+ - @graphorin/security@0.7.0
22
+
23
+ ## 0.6.1
24
+
25
+ ### Patch Changes
26
+
27
+ - [#142](https://github.com/o-stepper/graphorin/pull/142) [`436d6ca`](https://github.com/o-stepper/graphorin/commit/436d6ca5ebbd16df094e915682d3915c279a8430) Thanks [@o-stepper](https://github.com/o-stepper)! - Version constants and version-bearing strings now derive from each package's manifest at build time (`VERSION = pkg.version`; writer ids, client/server info, OTLP framework attributes, build-info metrics interpolate it). No behavioral change at the current version: the rendered strings are byte-identical. A release bump no longer edits source; the new `check-version-consistency` gate fails any reintroduced hardcoded framework version.
28
+
29
+ - Updated dependencies [[`436d6ca`](https://github.com/o-stepper/graphorin/commit/436d6ca5ebbd16df094e915682d3915c279a8430)]:
30
+ - @graphorin/core@0.6.1
31
+ - @graphorin/security@0.6.1
32
+ - @graphorin/tools@0.6.1
33
+
3
34
  ## 0.6.0
4
35
 
5
36
  ### Patch Changes
package/README.md CHANGED
@@ -82,7 +82,7 @@ import { loadSkillFromSource, createSkillRegistry } from '@graphorin/skills';
82
82
 
83
83
  const skill = await loadSkillFromSource(
84
84
  { kind: 'folder', path: './skills/finance-helper' },
85
- { conflictPolicy: 'warn', runtimeVersion: '0.6.0' },
85
+ { conflictPolicy: 'warn', runtimeVersion: '0.7.0' },
86
86
  );
87
87
 
88
88
  const registry = createSkillRegistry();
@@ -111,7 +111,7 @@ license: MIT
111
111
  disable-model-invocation: false
112
112
 
113
113
  # === Graphorin extensions (namespaced) ===
114
- graphorin-runtime-compat: ^0.6.0
114
+ graphorin-runtime-compat: ^0.7.0
115
115
  graphorin-trust-level: trusted
116
116
  graphorin-sensitivity: internal
117
117
  graphorin-handoff-input-filter: lastUser
@@ -168,4 +168,4 @@ MIT. Copyright © 2026 Oleksiy Stepurenko.
168
168
 
169
169
  ---
170
170
 
171
- **Project Graphorin** · v0.6.0 · MIT License · © 2026 Oleksiy Stepurenko · <https://github.com/o-stepper/graphorin>
171
+ **Project Graphorin** · v0.7.0 · MIT License · © 2026 Oleksiy Stepurenko · <https://github.com/o-stepper/graphorin>
package/dist/index.d.ts CHANGED
@@ -45,8 +45,7 @@ import { FieldStability, GraphorinFieldPolicy, GraphorinMappingEntry, KnownField
45
45
  *
46
46
  * @packageDocumentation
47
47
  */
48
- /** Canonical version constant. Mirrors the `package.json` version. */
49
- declare const VERSION = "0.6.0";
48
+ declare const VERSION: string;
50
49
  //#endregion
51
50
  export { ActivatedSkill, ActivationRequest, FieldResolution, FieldStability, FrontmatterDiagnostic, FrontmatterValidatorPolicy, GraphorinFieldPolicy, GraphorinMappingEntry, GraphorinSkillsError, GraphorinSkillsErrorKind, HandoffInputFilterDeclaration, HandoffInputFilterStep, InlineSkill, InlineSkillTool, InputFilterRequiredError, KnownFieldEntry, LoadSkillOptions, LoadSkillsOptions, MigrateFrontmatterOptions, MigrationResult, MigrationRewrite, ParsedActivationTrigger, RegisteredToolDeclaration, ResolvedSkillTrustPolicy, Skill, SkillFrontmatterConflictError, SkillLoadError, SkillManifestParseError, SkillMetadata, SkillNameCollisionError, SkillRegistry, SkillRegistryOptions, SkillRequiredFieldMissingError, SkillResource, SkillRuntimeCompatError, SkillSignatureVerificationResult, SkillSource, SkillToolDeclaration, SkillToolStamper, SkillTrustLevel, SkillTrustLevelValue, SkillsTrustLevel, SlashCommandActivation, SlashCommandParseError, SpecSnapshot, SplitSkillMd, StampedSkillTool, SupplyChainSkillSource, UnknownFieldPolicy, VERSION, ValidateFrontmatterOptions, ValidatedFrontmatter, _setSpecSnapshotForTesting, compareAuthorSpecHint, createSkillRegistry, getGraphorinMapping, getKnownField, getSpecSnapshot, isRuntimeCompatSatisfied, isSlashCommand, loadSkillFromSource, loadSkills, migrateFrontmatter, parseActivationTrigger, parseAllowedToolsValue, parseFrontmatterYaml, parseHandoffInputFilter, parseSlashCommand, parseToolsField, requireHandoffInputFilter, resolveSkillField, sortKeysAnthropicFirst, splitSkillMd, stampSkillTool, stampSkillToolFromMetadata, validateFrontmatter };
52
51
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAqCA;;;;;;;;;;;;;;;;;;;;;;;;;cAAa,OAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuCA;;;;;;;;;;;;;;;;;;;;;;;;cAAa"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { version } from "./package.js";
1
2
  import { GraphorinSkillsError, InputFilterRequiredError, SkillFrontmatterConflictError, SkillLoadError, SkillManifestParseError, SkillNameCollisionError, SkillRequiredFieldMissingError, SkillRuntimeCompatError, SlashCommandParseError } from "./errors/index.js";
2
3
  import { isSlashCommand, parseSlashCommand } from "./activation/index.js";
3
4
  import { _setSpecSnapshotForTesting, compareAuthorSpecHint, getGraphorinMapping, getKnownField, getSpecSnapshot } from "./spec/index.js";
@@ -43,8 +44,8 @@ import { createSkillRegistry, parseActivationTrigger } from "./registry/index.js
43
44
  *
44
45
  * @packageDocumentation
45
46
  */
46
- /** Canonical version constant. Mirrors the `package.json` version. */
47
- const VERSION = "0.6.0";
47
+ /** Canonical version constant, derived from `package.json` at build time. */
48
+ const VERSION = version;
48
49
 
49
50
  //#endregion
50
51
  export { GraphorinSkillsError, InputFilterRequiredError, SkillFrontmatterConflictError, SkillLoadError, SkillManifestParseError, SkillNameCollisionError, SkillRequiredFieldMissingError, SkillRuntimeCompatError, SlashCommandParseError, VERSION, _setSpecSnapshotForTesting, compareAuthorSpecHint, createSkillRegistry, getGraphorinMapping, getKnownField, getSpecSnapshot, isRuntimeCompatSatisfied, isSlashCommand, loadSkillFromSource, loadSkills, migrateFrontmatter, parseActivationTrigger, parseAllowedToolsValue, parseFrontmatterYaml, parseHandoffInputFilter, parseSlashCommand, parseToolsField, requireHandoffInputFilter, resolveSkillField, sortKeysAnthropicFirst, splitSkillMd, stampSkillTool, stampSkillToolFromMetadata, validateFrontmatter };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@graphorin/skills` - skills surface for the Graphorin framework.\n *\n * The package owns:\n *\n * - `SKILL.md` loader with three-tier progressive disclosure\n * (metadata always available; body and resources lazy-loaded).\n * - Frontmatter validator implementing the field-resolution\n * algorithm and conflict policy from ADR-043.\n * - Bundled snapshot of the publicly published `SKILL.md` packaging-\n * format specification + the framework-specific extension\n * catalogue.\n * - Slash-command parser (`/skill:<name>`) + auto-activation\n * metadata generator.\n * - `SkillRegistry` with name-collision detection, activation\n * resolution, and a typed tool-declaration surface the agent\n * runtime bridges into the `@graphorin/tools` registry.\n * - Idempotent `migrateFrontmatter` library that rewrites legacy\n * `graphorin-*` fields onto their upstream equivalents per the\n * bundled mapping table.\n *\n * Stable sub-paths:\n *\n * ```ts\n * import { loadSkills, loadSkillFromSource } from '@graphorin/skills/loader';\n * import { createSkillRegistry } from '@graphorin/skills/registry';\n * import { validateFrontmatter, resolveSkillField } from '@graphorin/skills/frontmatter';\n * import { migrateFrontmatter } from '@graphorin/skills/migration';\n * import { parseSlashCommand } from '@graphorin/skills/activation';\n * import { getSpecSnapshot, getKnownField } from '@graphorin/skills/spec';\n * import { SkillFrontmatterConflictError } from '@graphorin/skills/errors';\n * ```\n *\n * @packageDocumentation\n */\n\n/** Canonical version constant. Mirrors the `package.json` version. */\nexport const VERSION = '0.6.0';\n\nexport * from './activation/index.js';\nexport * from './errors/index.js';\nexport * from './frontmatter/index.js';\nexport * from './loader/index.js';\nexport * from './migration/index.js';\nexport * from './registry/index.js';\nexport * from './spec/index.js';\nexport * from './types/index.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAa,UAAU"}
1
+ {"version":3,"file":"index.js","names":["VERSION: string","pkg.version"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@graphorin/skills` - skills surface for the Graphorin framework.\n *\n * The package owns:\n *\n * - `SKILL.md` loader with three-tier progressive disclosure\n * (metadata always available; body and resources lazy-loaded).\n * - Frontmatter validator implementing the field-resolution\n * algorithm and conflict policy from ADR-043.\n * - Bundled snapshot of the publicly published `SKILL.md` packaging-\n * format specification + the framework-specific extension\n * catalogue.\n * - Slash-command parser (`/skill:<name>`) + auto-activation\n * metadata generator.\n * - `SkillRegistry` with name-collision detection, activation\n * resolution, and a typed tool-declaration surface the agent\n * runtime bridges into the `@graphorin/tools` registry.\n * - Idempotent `migrateFrontmatter` library that rewrites legacy\n * `graphorin-*` fields onto their upstream equivalents per the\n * bundled mapping table.\n *\n * Stable sub-paths:\n *\n * ```ts\n * import { loadSkills, loadSkillFromSource } from '@graphorin/skills/loader';\n * import { createSkillRegistry } from '@graphorin/skills/registry';\n * import { validateFrontmatter, resolveSkillField } from '@graphorin/skills/frontmatter';\n * import { migrateFrontmatter } from '@graphorin/skills/migration';\n * import { parseSlashCommand } from '@graphorin/skills/activation';\n * import { getSpecSnapshot, getKnownField } from '@graphorin/skills/spec';\n * import { SkillFrontmatterConflictError } from '@graphorin/skills/errors';\n * ```\n *\n * @packageDocumentation\n */\n\n/** Canonical version constant, derived from `package.json` at build time. */\nimport pkg from '../package.json' with { type: 'json' };\n\nexport const VERSION: string = pkg.version;\n\nexport * from './activation/index.js';\nexport * from './errors/index.js';\nexport * from './frontmatter/index.js';\nexport * from './loader/index.js';\nexport * from './migration/index.js';\nexport * from './registry/index.js';\nexport * from './spec/index.js';\nexport * from './types/index.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,MAAaA,UAAkBC"}
@@ -0,0 +1,6 @@
1
+ //#region package.json
2
+ var version = "0.7.0";
3
+
4
+ //#endregion
5
+ export { version };
6
+ //# sourceMappingURL=package.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.js","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@graphorin/skills\",\n \"version\": \"0.7.0\",\n \"description\": \"Skills surface for the Graphorin framework: loader for the SKILL.md packaging format with three-tier progressive disclosure (metadata / body / resources), frontmatter validator implementing the field-resolution algorithm and conflict policy from ADR-043, registry with auto-activation + slash-command activation, supply-chain hardening (signature verification + `--ignore-scripts` enforcement via @graphorin/security), sandbox-tier propagation for untrusted skills, handoff input-filter declaration recognition, and idempotent migrate-frontmatter library.\",\n \"license\": \"MIT\",\n \"author\": \"Oleksiy Stepurenko\",\n \"homepage\": \"https://github.com/o-stepper/graphorin/tree/main/packages/skills\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/o-stepper/graphorin.git\",\n \"directory\": \"packages/skills\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/o-stepper/graphorin/issues\"\n },\n \"keywords\": [\n \"graphorin\",\n \"ai\",\n \"agents\",\n \"framework\",\n \"skills\",\n \"skill-loader\",\n \"skill-registry\",\n \"frontmatter\",\n \"yaml\",\n \"progressive-disclosure\",\n \"supply-chain\",\n \"sandbox\",\n \"ed25519\",\n \"signature-verification\",\n \"migration\"\n ],\n \"type\": \"module\",\n \"sideEffects\": false,\n \"engines\": {\n \"node\": \">=22.12.0\"\n },\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"./loader\": {\n \"types\": \"./dist/loader/index.d.ts\",\n \"default\": \"./dist/loader/index.js\"\n },\n \"./registry\": {\n \"types\": \"./dist/registry/index.d.ts\",\n \"default\": \"./dist/registry/index.js\"\n },\n \"./frontmatter\": {\n \"types\": \"./dist/frontmatter/index.d.ts\",\n \"default\": \"./dist/frontmatter/index.js\"\n },\n \"./migration\": {\n \"types\": \"./dist/migration/index.d.ts\",\n \"default\": \"./dist/migration/index.js\"\n },\n \"./spec\": {\n \"types\": \"./dist/spec/index.d.ts\",\n \"default\": \"./dist/spec/index.js\"\n },\n \"./activation\": {\n \"types\": \"./dist/activation/index.d.ts\",\n \"default\": \"./dist/activation/index.js\"\n },\n \"./errors\": {\n \"types\": \"./dist/errors/index.d.ts\",\n \"default\": \"./dist/errors/index.js\"\n },\n \"./anthropic-spec-snapshot.json\": \"./anthropic-spec-snapshot.json\",\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\",\n \"src\",\n \"anthropic-spec-snapshot.json\",\n \"README.md\",\n \"CHANGELOG.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsdown\",\n \"typecheck\": \"tsc --noEmit && tsc -p tsconfig.tests.json\",\n \"test\": \"vitest run\",\n \"lint\": \"biome check .\",\n \"clean\": \"rimraf dist .turbo *.tsbuildinfo\"\n },\n \"dependencies\": {\n \"@graphorin/core\": \"workspace:*\",\n \"@graphorin/security\": \"workspace:*\",\n \"yaml\": \"^2.8.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"devDependencies\": {\n \"fast-check\": \"^3.23.0\",\n \"zod\": \"^3.25.0\"\n }\n}\n"],"mappings":";cAEa"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphorin/skills",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Skills surface for the Graphorin framework: loader for the SKILL.md packaging format with three-tier progressive disclosure (metadata / body / resources), frontmatter validator implementing the field-resolution algorithm and conflict policy from ADR-043, registry with auto-activation + slash-command activation, supply-chain hardening (signature verification + `--ignore-scripts` enforcement via @graphorin/security), sandbox-tier propagation for untrusted skills, handoff input-filter declaration recognition, and idempotent migrate-frontmatter library.",
5
5
  "license": "MIT",
6
6
  "author": "Oleksiy Stepurenko",
@@ -31,8 +31,9 @@
31
31
  "migration"
32
32
  ],
33
33
  "type": "module",
34
+ "sideEffects": false,
34
35
  "engines": {
35
- "node": ">=22.0.0"
36
+ "node": ">=22.12.0"
36
37
  },
37
38
  "main": "./dist/index.js",
38
39
  "module": "./dist/index.js",
@@ -40,41 +41,42 @@
40
41
  "exports": {
41
42
  ".": {
42
43
  "types": "./dist/index.d.ts",
43
- "import": "./dist/index.js"
44
+ "default": "./dist/index.js"
44
45
  },
45
46
  "./loader": {
46
47
  "types": "./dist/loader/index.d.ts",
47
- "import": "./dist/loader/index.js"
48
+ "default": "./dist/loader/index.js"
48
49
  },
49
50
  "./registry": {
50
51
  "types": "./dist/registry/index.d.ts",
51
- "import": "./dist/registry/index.js"
52
+ "default": "./dist/registry/index.js"
52
53
  },
53
54
  "./frontmatter": {
54
55
  "types": "./dist/frontmatter/index.d.ts",
55
- "import": "./dist/frontmatter/index.js"
56
+ "default": "./dist/frontmatter/index.js"
56
57
  },
57
58
  "./migration": {
58
59
  "types": "./dist/migration/index.d.ts",
59
- "import": "./dist/migration/index.js"
60
+ "default": "./dist/migration/index.js"
60
61
  },
61
62
  "./spec": {
62
63
  "types": "./dist/spec/index.d.ts",
63
- "import": "./dist/spec/index.js"
64
+ "default": "./dist/spec/index.js"
64
65
  },
65
66
  "./activation": {
66
67
  "types": "./dist/activation/index.d.ts",
67
- "import": "./dist/activation/index.js"
68
+ "default": "./dist/activation/index.js"
68
69
  },
69
70
  "./errors": {
70
71
  "types": "./dist/errors/index.d.ts",
71
- "import": "./dist/errors/index.js"
72
+ "default": "./dist/errors/index.js"
72
73
  },
73
74
  "./anthropic-spec-snapshot.json": "./anthropic-spec-snapshot.json",
74
75
  "./package.json": "./package.json"
75
76
  },
76
77
  "files": [
77
78
  "dist",
79
+ "src",
78
80
  "anthropic-spec-snapshot.json",
79
81
  "README.md",
80
82
  "CHANGELOG.md",
@@ -82,9 +84,8 @@
82
84
  ],
83
85
  "dependencies": {
84
86
  "yaml": "^2.8.0",
85
- "@graphorin/core": "0.6.0",
86
- "@graphorin/security": "0.6.0",
87
- "@graphorin/tools": "0.6.0"
87
+ "@graphorin/core": "0.7.0",
88
+ "@graphorin/security": "0.7.0"
88
89
  },
89
90
  "publishConfig": {
90
91
  "access": "public",
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Activation surface for `@graphorin/skills`.
3
+ *
4
+ * Two activation paths are supported per DEC-206:
5
+ *
6
+ * 1. **Auto** - every step the agent runtime injects the metadata of
7
+ * every registered skill into the system prompt; the model elects
8
+ * a skill by invoking the synthetic `activate_skill(name)` tool.
9
+ * Skills with `disable-model-invocation: true` are excluded from
10
+ * the metadata advertisement so the model never sees them.
11
+ * 2. **Slash command** - the user types `/skill:<name>` (optionally
12
+ * followed by free-form arguments) and the agent runtime activates
13
+ * the matched skill regardless of `disable-model-invocation`.
14
+ *
15
+ * The runtime owns the actual activation; this module only parses the
16
+ * inputs into a structured payload.
17
+ *
18
+ * @packageDocumentation
19
+ */
20
+
21
+ import { SlashCommandParseError } from '../errors/index.js';
22
+ import type { SlashCommandActivation } from '../types/index.js';
23
+
24
+ /**
25
+ * Parse a single message body for a `/skill:<name>` invocation. The
26
+ * grammar accepts:
27
+ *
28
+ * ```
29
+ * /skill:<name>
30
+ * /skill:<name> <free-form-args>
31
+ * ```
32
+ *
33
+ * `<name>` must match `^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$` (kebab-case
34
+ * conventional). Whitespace before the leading `/` is tolerated; any
35
+ * other prefix triggers a {@link SlashCommandParseError}.
36
+ *
37
+ * @stable
38
+ */
39
+ export function parseSlashCommand(raw: string): SlashCommandActivation {
40
+ if (typeof raw !== 'string' || raw.length === 0) {
41
+ throw new SlashCommandParseError(raw ?? '', 'message body must be a non-empty string.');
42
+ }
43
+ const trimmed = raw.replace(/^\s+/u, '');
44
+ if (!trimmed.startsWith('/skill:')) {
45
+ throw new SlashCommandParseError(raw, "message must begin with '/skill:'.");
46
+ }
47
+ const remainder = trimmed.slice('/skill:'.length);
48
+ if (remainder.length === 0) {
49
+ throw new SlashCommandParseError(raw, "missing skill name after '/skill:'.");
50
+ }
51
+ const match = /^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})(?:\s+([\s\S]*))?$/u.exec(remainder);
52
+ if (match === null) {
53
+ throw new SlashCommandParseError(
54
+ raw,
55
+ 'skill name must match /^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/.',
56
+ );
57
+ }
58
+ const name = match[1] ?? '';
59
+ const args = (match[2] ?? '').trim();
60
+ return Object.freeze({ name, args, raw });
61
+ }
62
+
63
+ /**
64
+ * Convenience predicate. Returns `true` when {@link parseSlashCommand}
65
+ * would succeed against the supplied body.
66
+ *
67
+ * @stable
68
+ */
69
+ export function isSlashCommand(raw: string): boolean {
70
+ try {
71
+ parseSlashCommand(raw);
72
+ return true;
73
+ } catch {
74
+ return false;
75
+ }
76
+ }
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Typed error hierarchy for `@graphorin/skills`.
3
+ *
4
+ * Every error carries a stable lowercase `kind` discriminator so the
5
+ * agent runtime, the CLI, and the audit emitter can branch without
6
+ * resorting to `instanceof` chains, plus an optional `hint` field with
7
+ * an actionable remediation step (a CLI command or a documentation
8
+ * link).
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+
13
+ /** Base class for every error thrown by `@graphorin/skills`. */
14
+ export abstract class GraphorinSkillsError extends Error {
15
+ abstract readonly kind: string;
16
+ readonly hint?: string;
17
+ override readonly cause?: unknown;
18
+ constructor(message: string, options?: { hint?: string; cause?: unknown }) {
19
+ super(message);
20
+ this.name = new.target.name;
21
+ if (options?.hint !== undefined) this.hint = options.hint;
22
+ if (options?.cause !== undefined) this.cause = options.cause;
23
+ }
24
+ }
25
+
26
+ /**
27
+ * The frontmatter validator detected an Anthropic-base / `graphorin-*`
28
+ * collision and the operator-resolved policy is `'error'`.
29
+ */
30
+ export class SkillFrontmatterConflictError extends GraphorinSkillsError {
31
+ readonly kind = 'frontmatter:conflict' as const;
32
+ readonly skillName: string;
33
+ readonly field: string;
34
+ readonly conflictingFields: ReadonlyArray<string>;
35
+ constructor(
36
+ skillName: string,
37
+ field: string,
38
+ conflictingFields: ReadonlyArray<string>,
39
+ options?: { hint?: string },
40
+ ) {
41
+ super(
42
+ `Skill '${skillName}' frontmatter conflict on '${field}' (also set: ${conflictingFields
43
+ .filter((f) => f !== field)
44
+ .join(', ')}). Validator policy: 'error'.`,
45
+ options,
46
+ );
47
+ this.skillName = skillName;
48
+ this.field = field;
49
+ this.conflictingFields = conflictingFields;
50
+ }
51
+ }
52
+
53
+ /** A skill manifest could not be parsed (missing frontmatter / invalid YAML). */
54
+ export class SkillManifestParseError extends GraphorinSkillsError {
55
+ readonly kind = 'manifest:parse' as const;
56
+ }
57
+
58
+ /**
59
+ * The runtime-compat declaration on a skill does not satisfy the
60
+ * loader's installed runtime version.
61
+ */
62
+ export class SkillRuntimeCompatError extends GraphorinSkillsError {
63
+ readonly kind = 'runtime-compat:mismatch' as const;
64
+ readonly skillName: string;
65
+ readonly declared: string;
66
+ readonly installed: string;
67
+ constructor(skillName: string, declared: string, installed: string, options?: { hint?: string }) {
68
+ super(
69
+ `Skill '${skillName}' declares runtime-compat '${declared}' which does not match installed Graphorin '${installed}'.`,
70
+ options,
71
+ );
72
+ this.skillName = skillName;
73
+ this.declared = declared;
74
+ this.installed = installed;
75
+ }
76
+ }
77
+
78
+ /** A required Anthropic-base field is missing from the frontmatter. */
79
+ export class SkillRequiredFieldMissingError extends GraphorinSkillsError {
80
+ readonly kind = 'frontmatter:missing-required' as const;
81
+ readonly field: string;
82
+ constructor(field: string, options?: { hint?: string }) {
83
+ super(`Skill frontmatter is missing required field '${field}'.`, options);
84
+ this.field = field;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * `Agent.toTool()` / `handoff(...)` would be invoked inside an
90
+ * untrusted skill, but the skill did not declare
91
+ * `graphorin-handoff-input-filter`. Throwing the error at activation
92
+ * time prevents the runtime from materialising a sub-agent without an
93
+ * explicit filter.
94
+ */
95
+ export class InputFilterRequiredError extends GraphorinSkillsError {
96
+ readonly kind = 'handoff:input-filter-required' as const;
97
+ readonly skillName: string;
98
+ constructor(skillName: string, options?: { hint?: string; cause?: unknown }) {
99
+ super(
100
+ `Untrusted skill '${skillName}' uses Agent.toTool()/handoff() but did not declare 'graphorin-handoff-input-filter'.`,
101
+ {
102
+ hint:
103
+ options?.hint ??
104
+ "Add 'graphorin-handoff-input-filter: lastUser' (or another supported value) to the SKILL.md frontmatter.",
105
+ ...(options?.cause === undefined ? {} : { cause: options.cause }),
106
+ },
107
+ );
108
+ this.skillName = skillName;
109
+ }
110
+ }
111
+
112
+ /** A skill source could not be loaded from disk. */
113
+ export class SkillLoadError extends GraphorinSkillsError {
114
+ readonly kind = 'load:failed' as const;
115
+ readonly source: string;
116
+ constructor(source: string, message: string, options?: { hint?: string; cause?: unknown }) {
117
+ super(`Skill load failed (source='${source}'): ${message}`, options);
118
+ this.source = source;
119
+ }
120
+ }
121
+
122
+ /** A skill name in a registry registration collided with another already-loaded skill. */
123
+ export class SkillNameCollisionError extends GraphorinSkillsError {
124
+ readonly kind = 'registry:name-collision' as const;
125
+ readonly skillName: string;
126
+ constructor(skillName: string, options?: { hint?: string; cause?: unknown }) {
127
+ super(`Skill '${skillName}' is already registered.`, {
128
+ hint:
129
+ options?.hint ??
130
+ 'Either rename one of the colliding skills or call `registry.unregister(name)` before re-registering.',
131
+ ...(options?.cause === undefined ? {} : { cause: options.cause }),
132
+ });
133
+ this.skillName = skillName;
134
+ }
135
+ }
136
+
137
+ /**
138
+ * The slash-command parser received a string that did not match the
139
+ * `/skill:<name>` grammar.
140
+ */
141
+ export class SlashCommandParseError extends GraphorinSkillsError {
142
+ readonly kind = 'slash:parse' as const;
143
+ readonly raw: string;
144
+ constructor(raw: string, message: string, options?: { hint?: string; cause?: unknown }) {
145
+ super(`Slash command '${raw}': ${message}`, {
146
+ hint: options?.hint ?? 'Use `/skill:<name>` to activate a registered skill.',
147
+ ...(options?.cause === undefined ? {} : { cause: options.cause }),
148
+ });
149
+ this.raw = raw;
150
+ }
151
+ }
152
+
153
+ /** Convenience union - every `kind` discriminator the package may emit. */
154
+ export type GraphorinSkillsErrorKind =
155
+ | 'frontmatter:conflict'
156
+ | 'manifest:parse'
157
+ | 'runtime-compat:mismatch'
158
+ | 'frontmatter:missing-required'
159
+ | 'handoff:input-filter-required'
160
+ | 'load:failed'
161
+ | 'registry:name-collision'
162
+ | 'slash:parse';