Skip to content

Commit 2fd479c

Browse files
authored
feat(skills): ship a consumer skill with the package (#4)
* feat(skills): ship a consumer skill with the package Add skills/<name>-interface/SKILL.md — a lean, source-grounded guide for agents consuming this interface (imports, minimal example, gotchas) — declared via antelopeJs.skills and published through the files array. Consumers receive it automatically: the antelopejs Claude Code plugin syncs package-shipped skills into a project's .claude/skills/, and the cms-ai chatbox loads them at runtime. Content was fact-checked against src/ and docs/ by an adversarial review pass (imports validated against the exports map, examples verified against real signatures). * fix(skills): ship docs with the package and scope the proxy-queuing gotcha Queuing only holds while a provider module is loaded but not yet attached; when no loaded module provides the interface (stubbed optional dependency), the core neutralizes the async proxies and calls reject. * docs(skills): use fictional domains in code examples
1 parent 6c7b356 commit 2fd479c

2 files changed

Lines changed: 90 additions & 2 deletions

File tree

package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
"main": "dist/index.js",
1818
"types": "dist/index.d.ts",
1919
"files": [
20-
"dist"
20+
"dist",
21+
"docs",
22+
"skills"
2123
],
2224
"exports": {
2325
".": {
@@ -58,6 +60,9 @@
5860
"access": "public"
5961
},
6062
"antelopeJs": {
61-
"test": "src/antelope.test.ts"
63+
"test": "src/antelope.test.ts",
64+
"skills": [
65+
"./skills"
66+
]
6267
}
6368
}

skills/auth-interface/SKILL.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
name: auth-interface
3+
description: AntelopeJS interface for token-based authentication - signing and verifying auth tokens (SignRaw, ValidateRaw, SignServerResponse) and injecting the verified payload into interface-api controllers via the @Authentication decorator or custom decorators from CreateAuthDecorator. Use when code imports "@antelopejs/interface-auth", when securing controller routes, generating or validating auth/JWT tokens, injecting authenticated user data into handler parameters, or when implementing an auth provider for internal.Verify/internal.Sign.
4+
category: antelopejs-interface
5+
tags: [antelopejs, auth, jwt, tokens, decorators]
6+
---
7+
8+
# @antelopejs/interface-auth
9+
10+
Token authentication for AntelopeJS modules. Two layers:
11+
12+
- **Proxy crossings** (need a provider module loaded, e.g. a JWT module): `internal.Verify` and `internal.Sign`, wrapped by `SignRaw`, `ValidateRaw`, and `SignServerResponse`. Always async.
13+
- **Consumer-side helpers** (no crossing by themselves): `Authentication` and `CreateAuthDecorator`, which build parameter providers on top of `@antelopejs/interface-api`.
14+
15+
## Imports
16+
17+
All symbols come from the package root (the exports map exposes no other code subpaths):
18+
19+
```ts
20+
import {
21+
Authentication, CreateAuthDecorator,
22+
SignRaw, ValidateRaw, SignServerResponse,
23+
internal, // provider side only
24+
type AuthSource, type AuthVerifier, type AuthValidator,
25+
type SignOptions, type VerifyOptions, type CookieOptions,
26+
} from "@antelopejs/interface-auth";
27+
```
28+
29+
`@antelopejs/interface-api` and `@antelopejs/interface-core` are peerDependencies — the consuming module must have them installed.
30+
31+
## Consuming
32+
33+
```ts
34+
import { Controller, Get, Post } from "@antelopejs/interface-api";
35+
import { Authentication, SignRaw } from "@antelopejs/interface-auth";
36+
37+
interface LibrarianSession { id: string; branch: string; }
38+
39+
class LibrarianController extends Controller("/librarians") {
40+
@Post("login")
41+
async login() {
42+
// Sign a payload into a token (proxy call to the auth provider)
43+
return SignRaw({ id: "lib-7", branch: "riverside" }, { expiresIn: "1h" });
44+
}
45+
46+
@Get("desk")
47+
async getDesk(@Authentication() librarian: LibrarianSession) {
48+
// Token was read from the request, verified, and injected
49+
return { id: librarian.id, branch: librarian.branch };
50+
}
51+
}
52+
```
53+
54+
Custom pipelines use `CreateAuthDecorator({ source?, authenticator?, authenticatorOptions?, validator? })`; the callbacks run as `source(req, res)``authenticator(data, authenticatorOptions)``validator(data)` → injected parameter.
55+
56+
## Providing
57+
58+
An auth backend module implements the two proxy points:
59+
60+
```ts
61+
import { ImplementInterface } from "@antelopejs/interface-core";
62+
import { internal } from "@antelopejs/interface-auth";
63+
64+
ImplementInterface(internal, {
65+
Verify: (token, options) => decodeAndVerify(token, options), // return payload, throw on invalid
66+
Sign: (data, options) => signToken(data, options), // return token string
67+
});
68+
```
69+
70+
Declare `"antelopeJs": { "implements": ["@antelopejs/interface-auth"] }` in the provider's package.json.
71+
72+
## Gotchas
73+
74+
- `SignRaw` / `ValidateRaw` / `SignServerResponse` are interface proxy calls: they return Promises and only resolve once a provider module is attached. While a provider module is loaded but not yet attached, earlier calls are queued, not failed — always `await`. But when no loaded module provides the interface (e.g. a stubbed `optionalDependencies` entry), the core neutralizes the proxies and those calls reject instead of queuing.
75+
- Default token source (`internal.defaultSource`): the `x-antelopejs-auth` request header, falling back to the `ANTELOPEJS_AUTH` cookie. `SignServerResponse` sets that same cookie via `Set-Cookie`.
76+
- `@Authentication(validator?)` accepts an optional validator at the use site; it overrides any validator configured in `CreateAuthDecorator`.
77+
- Decorators from `CreateAuthDecorator` (including `Authentication`) apply to parameters, properties, and whole classes (class-level registers a provider for the controller) — NOT to methods; decorating a method silently registers nothing and can break other parameter decorators on that handler.
78+
- `expiresIn` / `notBefore` (SignOptions) and `maxAge` (VerifyOptions) accept a number of seconds or a timespan string such as `"1h"`.
79+
- Rejection is exception-based: a failed verification or validator throws, it does not return `undefined`.
80+
81+
## Deeper reference
82+
83+
See this package's `docs/` chapters — Introduction, Authentication Basics, Token Handling, Parameter Decoration — and the shipped `dist/index.d.ts` for full TSDoc signatures. Do not duplicate them here.

0 commit comments

Comments
 (0)