feat(client): Agent Skills value types - #29
Merged
XieX merged 2 commits intoSep 18, 2026
Merged
Conversation
This was referenced Aug 25, 2026
XieX
force-pushed
the
xie/skills-01-types-frontmatter
branch
from
August 28, 2026 18:02
1f29fd5 to
89009c4
Compare
First of a stack that lands Agent Skills as one-way-dependent layers. This is the leaf: nothing here imports another skills module, so it reads on its own. `types.ts` gains the four frozen value types — `SkillReference`, `Skill`, `ReconcileAction`, `ReconcileReport` — plus the untrusted wire shape `RawSkillObject`, the structural `SkillStore` seam, the freezing factories, and the key/version validators. `parseAiConfig` now applies them to a variation's `skills` array, and it fails **closed**: one malformed reference fails the whole parse, because silently dropping it would materialize a partial skill set without telling anyone. Every one of these names, and the camelCase wire field `contentHash`, is an identical string to the Python SDK. A polyglot fleet has to agree on the shape it exchanges, so changing one is a cross-language breaking change. `Skill.content` is `Uint8Array` — the verified verbatim bytes, exactly what was hashed, with no encoding or file-format claim. The SDK never interprets skill content: there is deliberately no frontmatter parser and no YAML dependency anywhere in the package. Consumers that want structure parse the bytes themselves. Client package: 294 -> 342 tests. typecheck and biome clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
XieX
force-pushed
the
xie/skills-01-types-frontmatter
branch
from
August 31, 2026 18:10
89009c4 to
3c6cc27
Compare
andrewklatzke
approved these changes
Sep 14, 2026
XieX
marked this pull request as ready for review
September 14, 2026 20:34
…ific Review feedback: code comments in this SDK should not lean on another SDK as the explanation. SkillOutcomeReason's five-token vocabulary is a real cross-language contract, so the constraint stays — it is just stated as a property of every language implementation rather than of the Python SDK specifically. Same for the integer rule in the schema test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First of seven stacked PRs landing Agent Skills. The feature was built as one-way-dependent layers, and the stack follows that layering so each piece can be read on its own. This one is the leaf: nothing here imports another skills module.
What's here
types.tsgains the four frozen value types —SkillReference,Skill,ReconcileAction,ReconcileReport— plus the untrusted wire shapeRawSkillObject, the structuralSkillStoreseam, the freezing factories, and the key/version validators.parseAiConfignow applies them to a variation'sskillsarray.That validation fails closed: one malformed reference fails the whole parse. Silently dropping it would materialize a partial skill set without telling anyone.
Skills are opaque byte buffers — by construction
Skill.contentis aUint8Array: the verified verbatim bytes, exactly what was hashed, with no encoding or file-format claim attached. The SDK never interprets skill content anywhere — there is deliberately no frontmatter accessor and no YAML dependency in this package. A consumer that wants structure (frontmatter, markdown, anything else) decodes and parses the bytes itself, with whatever parser and bounds it trusts.One TypedArray caveat is documented at the factory:
Object.freezethrows on an array-buffer view, so the frozenSkillwrapper makes thecontentbinding immutable while the bytes themselves are shared with the caller.Cross-language contract
Every type and field name here, including the camelCase wire field
contentHash, is an identical string to the Python SDK, which carries the mirrorbytes-typed content. A polyglot fleet has to agree on the shape it exchanges, so changing one is a cross-language breaking change.The accessor outcome type (security review LA-2)
SkillOutcomeandSkillOutcomeReasonland here with the other value types, plus thecreateSkillOutcomefactory that freezes them like every sibling. They are consumed in #31 bygetSkillResult.SkillOutcomeReasonis a closed five-token vocabulary —absent,integrity_failure,ok,store_unavailable,wrong_version— listed alphabetically, and the Python SDK publishes the same five for the same conditions. It is deliberately coarser than the eight-tokenIntegrityReasonCodefrom the log record: the integrity tokens say which check failed and go to the operator, these say what the caller got.SkillStore.getObjectalso gains its third parameter here —getObject(kind, key, version?), matching Python'sget_object(kind, key, version=None). A store may hold several versions of one key and only the store can pick between them; without the parameter, a pin the store could have satisfied gets reported as a version mismatch. The post-hoc equality check at the accessor boundary is kept regardless, because the store is untrusted.Verification
Client package 294 → 342 tests.
typecheckandbiomeclean.🤖 Generated with Claude Code
Note
Overview
Introduces the Agent Skills foundation in the client package: frozen value types (
SkillReference,Skill, reconcile/report types,SkillOutcome/SkillStoreseam), factories, and strict validators for skill keys (^[a-z0-9][a-z0-9-]*$, max 256 chars) and versions (integer ≥ 1).AiConfigRepgains an optionalskillsarray of{ key, version }references.parseAiConfignow validates that array when present and fails the entire config on any bad entry (no silent partial skill sets).InitBaseClientOptionsdocuments an optionalskillStorehook for later accessors.Public
indexexports the new types pluscreateSkill/createSkillReference. Tests cover exhaustiveskillsparse rules inschema.test.tsand immutability /ReconcileReport.ok/errorsbehavior in newskills.test.ts.Reviewed by Cursor Bugbot for commit 98c9853. Bugbot is set up for automated code reviews on this repo. Configure here.