@graphorin/skills 0.5.0 → 0.6.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["cached: SpecSnapshot | null","overrideSnapshot: SpecSnapshot | null","lastError: unknown"],"sources":["../../src/spec/index.ts"],"sourcesContent":["/**\n * Bundled snapshot loader for the `SKILL.md` packaging-format\n * specification.\n *\n * The framework ships an offline copy of the upstream specification\n * so the loader can decide which frontmatter fields are recognised,\n * which `graphorin-*` extensions deprecate (or co-exist with) an\n * upstream field, and whether a skill author's\n * `graphorin-anthropic-spec` hint refers to a snapshot newer or older\n * than the bundled one. The snapshot is checked-in to the repository\n * and refreshed via the `pnpm run check-anthropic-spec` CI cron.\n *\n * The loader does not fetch the upstream specification; the only\n * network call lives inside the CI helper script. The snapshot lookup\n * is deterministic and side-effect free at runtime.\n *\n * @packageDocumentation\n */\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/** Stability classification of a known upstream field. */\nexport type FieldStability = 'stable' | 'standardized' | 'experimental';\n\n/** Migration policy applied to a `graphorin-*` field that maps to an upstream field. */\nexport type GraphorinFieldPolicy = 'deprecate-graphorin-prefix' | 'co-exist' | 'graphorin-only';\n\n/** Single entry of the upstream-known fields map. */\nexport interface KnownFieldEntry {\n readonly since: string;\n readonly required: boolean;\n readonly type: string;\n readonly stability: FieldStability;\n}\n\n/** Single entry of the `graphorin-*` mapping map. */\nexport interface GraphorinMappingEntry {\n readonly anthropicEquivalent: string | null;\n readonly policy: GraphorinFieldPolicy;\n readonly since?: string;\n readonly rationale?: string;\n readonly deprecateAt?: string;\n readonly removeAt?: string;\n}\n\n/** Top-level shape of the bundled snapshot. */\nexport interface SpecSnapshot {\n readonly snapshotDate: string;\n readonly specSource: string;\n readonly specCommit: string | null;\n readonly rationale?: string;\n readonly knownFields: Readonly<Record<string, KnownFieldEntry>>;\n readonly graphorinMapping: Readonly<Record<string, GraphorinMappingEntry>>;\n}\n\nlet cached: SpecSnapshot | null = null;\nlet overrideSnapshot: SpecSnapshot | null = null;\n\n/**\n * Override the bundled snapshot. Used by tests that exercise the\n * \"newer / older spec snapshot\" branches of the validator.\n *\n * @experimental\n */\nexport function _setSpecSnapshotForTesting(snapshot: SpecSnapshot | null): void {\n overrideSnapshot = snapshot;\n}\n\n/**\n * Return the currently active snapshot. Loads the bundled JSON file\n * on first call, then caches the parsed object.\n *\n * @stable\n */\nexport function getSpecSnapshot(): SpecSnapshot {\n if (overrideSnapshot !== null) return overrideSnapshot;\n if (cached !== null) return cached;\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const candidates = [\n // Source: packages/skills/src/spec/index.ts → ../../anthropic-spec-snapshot.json\n join(__dirname, '..', '..', 'anthropic-spec-snapshot.json'),\n // Built ESM: packages/skills/dist/spec/index.js → ../../anthropic-spec-snapshot.json\n join(__dirname, '..', '..', 'anthropic-spec-snapshot.json'),\n ];\n let lastError: unknown;\n for (const candidate of candidates) {\n try {\n const raw = readFileSync(candidate, 'utf8');\n const parsed = JSON.parse(raw) as SpecSnapshot;\n cached = parsed;\n return parsed;\n } catch (err) {\n lastError = err;\n }\n }\n throw new Error(\n `Failed to load bundled spec snapshot. Tried: ${candidates.join(', ')}. ` +\n `Cause: ${(lastError as Error).message}`,\n );\n}\n\n/**\n * Resolve a known-field entry by name. Returns `undefined` if the\n * field is not part of the upstream specification.\n *\n * @stable\n */\nexport function getKnownField(field: string): KnownFieldEntry | undefined {\n return getSpecSnapshot().knownFields[field];\n}\n\n/**\n * Resolve the mapping entry for a `graphorin-*` field. Returns\n * `undefined` if the field is not known to the snapshot.\n *\n * @stable\n */\nexport function getGraphorinMapping(field: string): GraphorinMappingEntry | undefined {\n return getSpecSnapshot().graphorinMapping[field];\n}\n\n/**\n * Compare an author's `graphorin-anthropic-spec` value against the\n * bundled snapshot date. Returns:\n *\n * - `'same'` the author targeted the same snapshot.\n * - `'older'` the author targeted an older snapshot.\n * - `'newer'` the author targeted a newer snapshot.\n * - `'unparseable'` the author's value could not be interpreted as\n * an ISO-8601 date.\n *\n * @stable\n */\nexport function compareAuthorSpecHint(\n authorValue: string,\n): 'same' | 'older' | 'newer' | 'unparseable' {\n const snapshot = getSpecSnapshot();\n const author = parseDate(authorValue);\n const local = parseDate(snapshot.snapshotDate);\n if (author === null || local === null) return 'unparseable';\n if (author.getTime() === local.getTime()) return 'same';\n return author.getTime() > local.getTime() ? 'newer' : 'older';\n}\n\nfunction parseDate(value: string): Date | null {\n const trimmed = value.trim();\n if (!/^\\d{4}-\\d{2}-\\d{2}/u.test(trimmed)) return null;\n const date = new Date(trimmed);\n if (Number.isNaN(date.getTime())) return null;\n return date;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyDA,IAAIA,SAA8B;AAClC,IAAIC,mBAAwC;;;;;;;AAQ5C,SAAgB,2BAA2B,UAAqC;AAC9E,oBAAmB;;;;;;;;AASrB,SAAgB,kBAAgC;AAC9C,KAAI,qBAAqB,KAAM,QAAO;AACtC,KAAI,WAAW,KAAM,QAAO;CAE5B,MAAM,YAAY,QADC,cAAc,OAAO,KAAK,IAAI,CACZ;CACrC,MAAM,aAAa,CAEjB,KAAK,WAAW,MAAM,MAAM,+BAA+B,EAE3D,KAAK,WAAW,MAAM,MAAM,+BAA+B,CAC5D;CACD,IAAIC;AACJ,MAAK,MAAM,aAAa,WACtB,KAAI;EACF,MAAM,MAAM,aAAa,WAAW,OAAO;EAC3C,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,WAAS;AACT,SAAO;UACA,KAAK;AACZ,cAAY;;AAGhB,OAAM,IAAI,MACR,gDAAgD,WAAW,KAAK,KAAK,CAAC,WACzD,UAAoB,UAClC;;;;;;;;AASH,SAAgB,cAAc,OAA4C;AACxE,QAAO,iBAAiB,CAAC,YAAY;;;;;;;;AASvC,SAAgB,oBAAoB,OAAkD;AACpF,QAAO,iBAAiB,CAAC,iBAAiB;;;;;;;;;;;;;;AAe5C,SAAgB,sBACd,aAC4C;CAC5C,MAAM,WAAW,iBAAiB;CAClC,MAAM,SAAS,UAAU,YAAY;CACrC,MAAM,QAAQ,UAAU,SAAS,aAAa;AAC9C,KAAI,WAAW,QAAQ,UAAU,KAAM,QAAO;AAC9C,KAAI,OAAO,SAAS,KAAK,MAAM,SAAS,CAAE,QAAO;AACjD,QAAO,OAAO,SAAS,GAAG,MAAM,SAAS,GAAG,UAAU;;AAGxD,SAAS,UAAU,OAA4B;CAC7C,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,CAAC,sBAAsB,KAAK,QAAQ,CAAE,QAAO;CACjD,MAAM,OAAO,IAAI,KAAK,QAAQ;AAC9B,KAAI,OAAO,MAAM,KAAK,SAAS,CAAC,CAAE,QAAO;AACzC,QAAO"}
1
+ {"version":3,"file":"index.js","names":["cached: SpecSnapshot | null","overrideSnapshot: SpecSnapshot | null","lastError: unknown"],"sources":["../../src/spec/index.ts"],"sourcesContent":["/**\n * Bundled snapshot loader for the `SKILL.md` packaging-format\n * specification.\n *\n * The framework ships an offline copy of the upstream specification\n * so the loader can decide which frontmatter fields are recognised,\n * which `graphorin-*` extensions deprecate (or co-exist with) an\n * upstream field, and whether a skill author's\n * `graphorin-anthropic-spec` hint refers to a snapshot newer or older\n * than the bundled one. The snapshot is checked-in to the repository;\n * `pnpm run check-anthropic-spec` diffs it against an upstream snapshot\n * the maintainer supplies via `--upstream` (there is no scheduled CI\n * job and no auto-refresh - the release `mvp-readiness` gate runs the\n * helper in no-upstream skip mode, which only confirms the bundled\n * snapshot parses).\n *\n * Neither the loader nor the helper fetches the upstream specification;\n * the upstream snapshot is fetched manually. The snapshot lookup is\n * deterministic and side-effect free at runtime.\n *\n * @packageDocumentation\n */\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/** Stability classification of a known upstream field. */\nexport type FieldStability = 'stable' | 'standardized' | 'experimental';\n\n/** Migration policy applied to a `graphorin-*` field that maps to an upstream field. */\nexport type GraphorinFieldPolicy = 'deprecate-graphorin-prefix' | 'co-exist' | 'graphorin-only';\n\n/** Single entry of the upstream-known fields map. */\nexport interface KnownFieldEntry {\n readonly since: string;\n readonly required: boolean;\n readonly type: string;\n readonly stability: FieldStability;\n}\n\n/** Single entry of the `graphorin-*` mapping map. */\nexport interface GraphorinMappingEntry {\n readonly anthropicEquivalent: string | null;\n readonly policy: GraphorinFieldPolicy;\n readonly since?: string;\n readonly rationale?: string;\n readonly deprecateAt?: string;\n readonly removeAt?: string;\n}\n\n/** Top-level shape of the bundled snapshot. */\nexport interface SpecSnapshot {\n readonly snapshotDate: string;\n readonly specSource: string;\n readonly specCommit: string | null;\n readonly rationale?: string;\n readonly knownFields: Readonly<Record<string, KnownFieldEntry>>;\n readonly graphorinMapping: Readonly<Record<string, GraphorinMappingEntry>>;\n}\n\nlet cached: SpecSnapshot | null = null;\nlet overrideSnapshot: SpecSnapshot | null = null;\n\n/**\n * Override the bundled snapshot. Used by tests that exercise the\n * \"newer / older spec snapshot\" branches of the validator.\n *\n * @experimental\n */\nexport function _setSpecSnapshotForTesting(snapshot: SpecSnapshot | null): void {\n overrideSnapshot = snapshot;\n}\n\n/**\n * Return the currently active snapshot. Loads the bundled JSON file\n * on first call, then caches the parsed object.\n *\n * @stable\n */\nexport function getSpecSnapshot(): SpecSnapshot {\n if (overrideSnapshot !== null) return overrideSnapshot;\n if (cached !== null) return cached;\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const candidates = [\n // Source: packages/skills/src/spec/index.ts → ../../anthropic-spec-snapshot.json\n join(__dirname, '..', '..', 'anthropic-spec-snapshot.json'),\n // Built ESM: packages/skills/dist/spec/index.js → ../../anthropic-spec-snapshot.json\n join(__dirname, '..', '..', 'anthropic-spec-snapshot.json'),\n ];\n let lastError: unknown;\n for (const candidate of candidates) {\n try {\n const raw = readFileSync(candidate, 'utf8');\n const parsed = JSON.parse(raw) as SpecSnapshot;\n cached = parsed;\n return parsed;\n } catch (err) {\n lastError = err;\n }\n }\n throw new Error(\n `Failed to load bundled spec snapshot. Tried: ${candidates.join(', ')}. ` +\n `Cause: ${(lastError as Error).message}`,\n );\n}\n\n/**\n * Resolve a known-field entry by name. Returns `undefined` if the\n * field is not part of the upstream specification.\n *\n * @stable\n */\nexport function getKnownField(field: string): KnownFieldEntry | undefined {\n return getSpecSnapshot().knownFields[field];\n}\n\n/**\n * Resolve the mapping entry for a `graphorin-*` field. Returns\n * `undefined` if the field is not known to the snapshot.\n *\n * @stable\n */\nexport function getGraphorinMapping(field: string): GraphorinMappingEntry | undefined {\n return getSpecSnapshot().graphorinMapping[field];\n}\n\n/**\n * Compare an author's `graphorin-anthropic-spec` value against the\n * bundled snapshot date. Returns:\n *\n * - `'same'` - the author targeted the same snapshot.\n * - `'older'` - the author targeted an older snapshot.\n * - `'newer'` - the author targeted a newer snapshot.\n * - `'unparseable'` - the author's value could not be interpreted as\n * an ISO-8601 date.\n *\n * @stable\n */\nexport function compareAuthorSpecHint(\n authorValue: string,\n): 'same' | 'older' | 'newer' | 'unparseable' {\n const snapshot = getSpecSnapshot();\n const author = parseDate(authorValue);\n const local = parseDate(snapshot.snapshotDate);\n if (author === null || local === null) return 'unparseable';\n if (author.getTime() === local.getTime()) return 'same';\n return author.getTime() > local.getTime() ? 'newer' : 'older';\n}\n\nfunction parseDate(value: string): Date | null {\n const trimmed = value.trim();\n if (!/^\\d{4}-\\d{2}-\\d{2}/u.test(trimmed)) return null;\n const date = new Date(trimmed);\n if (Number.isNaN(date.getTime())) return null;\n return date;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,IAAIA,SAA8B;AAClC,IAAIC,mBAAwC;;;;;;;AAQ5C,SAAgB,2BAA2B,UAAqC;AAC9E,oBAAmB;;;;;;;;AASrB,SAAgB,kBAAgC;AAC9C,KAAI,qBAAqB,KAAM,QAAO;AACtC,KAAI,WAAW,KAAM,QAAO;CAE5B,MAAM,YAAY,QADC,cAAc,OAAO,KAAK,IAAI,CACZ;CACrC,MAAM,aAAa,CAEjB,KAAK,WAAW,MAAM,MAAM,+BAA+B,EAE3D,KAAK,WAAW,MAAM,MAAM,+BAA+B,CAC5D;CACD,IAAIC;AACJ,MAAK,MAAM,aAAa,WACtB,KAAI;EACF,MAAM,MAAM,aAAa,WAAW,OAAO;EAC3C,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,WAAS;AACT,SAAO;UACA,KAAK;AACZ,cAAY;;AAGhB,OAAM,IAAI,MACR,gDAAgD,WAAW,KAAK,KAAK,CAAC,WACzD,UAAoB,UAClC;;;;;;;;AASH,SAAgB,cAAc,OAA4C;AACxE,QAAO,iBAAiB,CAAC,YAAY;;;;;;;;AASvC,SAAgB,oBAAoB,OAAkD;AACpF,QAAO,iBAAiB,CAAC,iBAAiB;;;;;;;;;;;;;;AAe5C,SAAgB,sBACd,aAC4C;CAC5C,MAAM,WAAW,iBAAiB;CAClC,MAAM,SAAS,UAAU,YAAY;CACrC,MAAM,QAAQ,UAAU,SAAS,aAAa;AAC9C,KAAI,WAAW,QAAQ,UAAU,KAAM,QAAO;AAC9C,KAAI,OAAO,SAAS,KAAK,MAAM,SAAS,CAAE,QAAO;AACjD,QAAO,OAAO,SAAS,GAAG,MAAM,SAAS,GAAG,UAAU;;AAGxD,SAAS,UAAU,OAA4B;CAC7C,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,CAAC,sBAAsB,KAAK,QAAQ,CAAE,QAAO;CACjD,MAAM,OAAO,IAAI,KAAK,QAAQ;AAC9B,KAAI,OAAO,MAAM,KAAK,SAAS,CAAC,CAAE,QAAO;AACzC,QAAO"}
@@ -10,7 +10,7 @@ import { ResolvedTool, Tool } from "@graphorin/core";
10
10
  * sandbox tier resolver treats `'unknown'` like `'untrusted'`
11
11
  * (mandatory `worker-threads + no-net + no-fs`); the supply-chain
12
12
  * installer treats it as untrusted EXCEPT that the signature
13
- * requirement is downgraded from mandatory to optional signature
13
+ * requirement is downgraded from mandatory to optional - signature
14
14
  * is a trust upgrade, not a gate (Phase 08 § Risks & mitigations).
15
15
  *
16
16
  * @stable
@@ -43,11 +43,11 @@ type SkillTrustLevelValue = SkillsTrustLevel;
43
43
  /**
44
44
  * Source descriptor for a {@link loadSkills} request.
45
45
  *
46
- * - `'folder'` load from a directory on disk.
47
- * - `'npm-package'` install via the supply-chain installer + load.
48
- * - `'git-repo'` shallow-clone via the supply-chain installer +
46
+ * - `'folder'` - load from a directory on disk.
47
+ * - `'npm-package'` - install via the supply-chain installer + load.
48
+ * - `'git-repo'` - shallow-clone via the supply-chain installer +
49
49
  * load.
50
- * - `'inline'` the caller supplies a parsed skill structure;
50
+ * - `'inline'` - the caller supplies a parsed skill structure;
51
51
  * useful for tests and embedded fixtures.
52
52
  *
53
53
  * @stable
@@ -59,7 +59,7 @@ type SkillSource = {
59
59
  * Operator-supplied trust level. When present it overrides the
60
60
  * skill's self-declared `graphorin-trust-level`. Without it, a
61
61
  * folder's self-declared `trusted` / `trusted-with-scripts` is
62
- * capped at `'unknown'` a downloaded directory cannot promote
62
+ * capped at `'unknown'` - a downloaded directory cannot promote
63
63
  * itself; trust is granted by the integrator, never the artifact.
64
64
  */
65
65
  readonly trustLevel?: SkillTrustLevel;
@@ -79,7 +79,7 @@ type SkillSource = {
79
79
  };
80
80
  /**
81
81
  * Pre-built tool record accepted by the inline source. The loader
82
- * does not parse the tool it forwards the record to the agent
82
+ * does not parse the tool - it forwards the record to the agent
83
83
  * runtime which feeds it through `stampSkillTool(...)` before
84
84
  * registering with `@graphorin/tools`.
85
85
  *
@@ -104,7 +104,7 @@ interface InlineSkill {
104
104
  * these via {@link Skill.tools} so {@link SkillRegistry.tools}
105
105
  * returns them deduplicated by `tool.name`.
106
106
  *
107
- * Folder / npm / git sources do not carry tool implementations
107
+ * Folder / npm / git sources do not carry tool implementations -
108
108
  * the agent runtime (Phase 12) materialises them from the skill's
109
109
  * `tools/` directory. The inline source is the only path through
110
110
  * which tests + bundled defaults can ship pre-built tools.
@@ -138,7 +138,7 @@ interface FrontmatterDiagnostic {
138
138
  }
139
139
  /**
140
140
  * Validated skill metadata. Always available on the registry without
141
- * loading the body this is the always-present **Tier 1** payload
141
+ * loading the body - this is the always-present **Tier 1** payload
142
142
  * that the system prompt advertises.
143
143
  *
144
144
  * @stable
@@ -161,7 +161,7 @@ interface SkillMetadata {
161
161
  readonly graphorinAnthropicSpec?: string;
162
162
  /** Author-declared graphorin runtime / extension version. */
163
163
  readonly graphorinVersion?: string;
164
- /** Raw frontmatter (read-only) for power users every loader user can re-derive bespoke fields. */
164
+ /** Raw frontmatter (read-only) for power users - every loader user can re-derive bespoke fields. */
165
165
  readonly raw: Readonly<Record<string, unknown>>;
166
166
  }
167
167
  /**
@@ -235,12 +235,12 @@ interface SkillResource {
235
235
  * Loaded skill record returned by {@link SkillRegistry.getSkill} and
236
236
  * {@link loadSkills}. Three-tier semantics:
237
237
  *
238
- * - {@link Skill.metadata} always available (parsed at load time).
239
- * - {@link Skill.body} lazy; resolved on first call. Cached for
238
+ * - {@link Skill.metadata} - always available (parsed at load time).
239
+ * - {@link Skill.body} - lazy; resolved on first call. Cached for
240
240
  * subsequent calls.
241
- * - {@link Skill.resources} lazy listing; resource bytes are only
241
+ * - {@link Skill.resources} - lazy listing; resource bytes are only
242
242
  * read when {@link SkillResource.read} is invoked.
243
- * - {@link Skill.tools} derived from the `graphorin-tools`
243
+ * - {@link Skill.tools} - derived from the `graphorin-tools`
244
244
  * declarations; the actual `Tool[]` is materialised by the agent
245
245
  * runtime through the `@graphorin/tools` registry.
246
246
  *
@@ -266,7 +266,7 @@ interface Skill {
266
266
  diagnostics(): ReadonlyArray<FrontmatterDiagnostic>;
267
267
  }
268
268
  /**
269
- * Activated skill what the agent runtime sees after the model (or a
269
+ * Activated skill - what the agent runtime sees after the model (or a
270
270
  * slash command) elects a skill. Carries the loaded body + declared
271
271
  * tools so the runtime can inject them into the conversation.
272
272
  *
@@ -278,7 +278,7 @@ interface ActivatedSkill {
278
278
  readonly resources: ReadonlyArray<SkillResource>;
279
279
  /**
280
280
  * Tools made available to the model while the skill is active.
281
- * The agent runtime (Phase 12) is the canonical producer it
281
+ * The agent runtime (Phase 12) is the canonical producer - it
282
282
  * resolves the skill's `tools/` directory or the inline-supplied
283
283
  * `Tool[]` and feeds each entry through `stampSkillTool(...)` so
284
284
  * the resulting `ResolvedTool` carries the right trust class +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphorin/skills",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
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",
@@ -82,9 +82,9 @@
82
82
  ],
83
83
  "dependencies": {
84
84
  "yaml": "^2.8.0",
85
- "@graphorin/core": "0.5.0",
86
- "@graphorin/tools": "0.5.0",
87
- "@graphorin/security": "0.5.0"
85
+ "@graphorin/core": "0.6.1",
86
+ "@graphorin/security": "0.6.1",
87
+ "@graphorin/tools": "0.6.1"
88
88
  },
89
89
  "publishConfig": {
90
90
  "access": "public",