@hasna/skills 0.8.9 → 0.8.11
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/README.md +103 -1
- package/bin/index.js +26509 -24016
- package/bin/mcp.js +596 -222
- package/bin/migrate.js +7 -5
- package/bin/server.js +12313 -73626
- package/bin/worker.js +7636 -60520
- package/dist/cli/commands/plugin-admission.d.ts +2 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.js +23559 -21779
- package/dist/lib/agent-adapters.d.ts +1 -0
- package/dist/lib/agent-codex-trust.d.ts +42 -0
- package/dist/lib/agent-discovery.d.ts +4 -2
- package/dist/lib/claude-marketplace-registry.d.ts +17 -0
- package/dist/lib/codex-hook-rpc.d.ts +13 -0
- package/dist/lib/codex-hook-trust-files.d.ts +15 -0
- package/dist/lib/codex-hook-trust-identity.d.ts +16 -0
- package/dist/lib/codex-hook-trust-layout.d.ts +3 -0
- package/dist/lib/fleet-credentials.d.ts +18 -0
- package/dist/lib/hook-diagnostics.d.ts +7 -0
- package/dist/lib/plugin-admission.d.ts +101 -0
- package/dist/lib/plugin-discovery.d.ts +13 -0
- package/dist/lib/plugin-projection-store.d.ts +14 -0
- package/dist/lib/plugin-projection.d.ts +80 -0
- package/dist/lib/profile-client.d.ts +10 -0
- package/dist/lib/recurring-recovery.d.ts +2 -2
- package/dist/lib/recurring-surface.d.ts +1 -1
- package/dist/lib/remote-client.d.ts +14 -4
- package/dist/lib/remote-credit-checkout.d.ts +22 -0
- package/dist/lib/remote-customer-operations.d.ts +3 -4
- package/dist/lib/remote-permissions.d.ts +24 -0
- package/dist/lib/selection-cache.d.ts +32 -0
- package/dist/lib/selection-resolver.d.ts +3 -1
- package/dist/lib/session-reconciliation.d.ts +100 -0
- package/dist/sdk/index.d.ts +5 -2
- package/dist/sdk/index.js +18528 -78089
- package/docs/plugin-admission.md +221 -0
- package/package.json +7 -5
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Reviewed plugin admission
|
|
2
|
+
|
|
3
|
+
`skills integration plugin` prepares a plugin before a coding agent discovers
|
|
4
|
+
it. Projection contracts support schema versions 1 and 2; targets use schema
|
|
5
|
+
version 1, bindings use schema version 2, and admission plans and receipts use
|
|
6
|
+
schema version 3. Claude command sources use `copy` mode, certified against
|
|
7
|
+
Claude 2.1.274 and 2.1.276 on Linux ARM64. It removes native skill and command prompts while preserving
|
|
8
|
+
reviewed agents, tools, MCP, LSP, hooks and assets. Prompt hooks enforce drift;
|
|
9
|
+
they do not clean an already loaded plugin catalog.
|
|
10
|
+
|
|
11
|
+
All packages and migration mappings belong in the owner's private Skills
|
|
12
|
+
instance. The public Skills package ships this software and synthetic tests;
|
|
13
|
+
it contains no operational plugin catalog or skill payloads. The Skills server
|
|
14
|
+
can use its supported storage backend. Plugin admission does not require S3.
|
|
15
|
+
|
|
16
|
+
## Private package contract
|
|
17
|
+
|
|
18
|
+
Publish migrated prompts through the normal versioned Skills authoring flow.
|
|
19
|
+
Then publish a separate instruction bundle containing `plugin-projection.json`
|
|
20
|
+
and the original regular-file plugin tree under `original/`. Keep its root
|
|
21
|
+
instruction and package metadata outside that tree. Select the integration
|
|
22
|
+
bundle and all its mapped payload versions in a dedicated integration profile.
|
|
23
|
+
These operations do not silently publish or change a selection profile.
|
|
24
|
+
|
|
25
|
+
The exported `PluginProjectionManifest` retains this strict version 1 contract:
|
|
26
|
+
|
|
27
|
+
| Field | Meaning |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| `schemaVersion`, `agent` | `1`, `"claude"` |
|
|
30
|
+
| `pluginId` | Exact `plugin-name@marketplace-name` |
|
|
31
|
+
| `upstream` | Credential-free HTTPS source, revision, version, license, and original `treeDigest` |
|
|
32
|
+
| `review.hooks` | `"reviewed-no-skill-injection"` |
|
|
33
|
+
| `review.dependencies` | `"reviewed-no-retired-payload-dependency"` |
|
|
34
|
+
| `payloads` | Every original skill and command prompt, with source path, kind, source digest and exact hosted target slug/version/bundle digest |
|
|
35
|
+
|
|
36
|
+
Schema version 2 also supports original manifests that omit `version`. It uses
|
|
37
|
+
`upstream.version: null`, requires a full lowercase 40- or 64-character Git
|
|
38
|
+
commit in `upstream.revision`, and still binds the complete original tree digest.
|
|
39
|
+
A null version refuses an original manifest with any `version` field, including
|
|
40
|
+
null or an empty string. A declared version must still match exactly. No vendor
|
|
41
|
+
version is invented or written into the projection. Claude's command-copy cache
|
|
42
|
+
uses a bare 12-character content hash when the manifest has no version; declared
|
|
43
|
+
versions retain their version-plus-hash form. Both forms require the exact
|
|
44
|
+
admitted producer receipt and complete file witnesses.
|
|
45
|
+
|
|
46
|
+
Version 2 requires `review.documentation`, an array containing zero or one
|
|
47
|
+
`{ path, sourceDigest }` entries. Only an exact root `README.md` (case-insensitive
|
|
48
|
+
spelling), with mode 0644 and its one-file tree digest, can be declared inert
|
|
49
|
+
documentation. Its original bytes may describe a retired prompt. The exception
|
|
50
|
+
refuses a README selected by a native component, referenced by native configuration,
|
|
51
|
+
or referenced by another retained text file. Other Markdown, including agents,
|
|
52
|
+
keeps the strict removed-file and native skill-preload checks. An undeclared README
|
|
53
|
+
also keeps those checks. This explicit review does not certify arbitrary dynamic
|
|
54
|
+
runtime behavior: dependency review must still establish that the README is not
|
|
55
|
+
an indirect runtime input. Version 1 gains no documentation exception.
|
|
56
|
+
|
|
57
|
+
`pluginTreeDigest(entries)` hashes sorted file witnesses: path, normalized mode,
|
|
58
|
+
size and SHA-256. A payload's `sourceDigest` is that function applied to its
|
|
59
|
+
single original file. The source is preserved byte-for-byte in the private
|
|
60
|
+
archive; the native projection is derived from it. Default and custom command
|
|
61
|
+
paths, dormant default commands, root skills and case-insensitive aliases are
|
|
62
|
+
covered. Custom skill trees are removed, including their support files. The
|
|
63
|
+
only rewritten ordinary file is the plugin manifest when its `skills` or
|
|
64
|
+
`commands` declarations need removal.
|
|
65
|
+
|
|
66
|
+
Overlapping ordinary components, runtime references to removed files, native agent
|
|
67
|
+
skill preloads, unsupported manifest fields and upstream package installation
|
|
68
|
+
requirements refuse admission. Review must cover indirect/dynamic dependencies
|
|
69
|
+
as well as the direct references checked by software. Admission never executes
|
|
70
|
+
an upstream shell command or installation script. Preserved plugin tools and
|
|
71
|
+
hooks still run under the native agent's normal trust controls when used.
|
|
72
|
+
|
|
73
|
+
## Plan, admit and resolve
|
|
74
|
+
|
|
75
|
+
Prepare an owner-only JSON `PluginAdmissionTarget` with schema version 1,
|
|
76
|
+
plugin ID, exact `registrations` (user and/or canonical project paths), certified
|
|
77
|
+
native executable/version/digest, and the absolute Skills executable/digest.
|
|
78
|
+
One marketplace command serves that complete reviewed registration set.
|
|
79
|
+
Executable digests use `sha256:<hex>`; symlink aliases must be resolved to their
|
|
80
|
+
reviewed canonical file paths. No executable is invoked while planning.
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
skills integration plugin plan plugin-container --selection-profile integrations --target /absolute/private/target.json
|
|
84
|
+
skills integration plugin admit plugin-container --selection-profile integrations --target /absolute/private/target.json --plan-digest sha256:REVIEWED_DIGEST --evidence-digest sha256:REVIEWED_EVIDENCE
|
|
85
|
+
skills integration plugin resolve --binding REVIEWED_BINDING_ID
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Plan and admit emit JSON. Review the exact plan digest, retained/removed file
|
|
89
|
+
witnesses, provenance and hosted payload mappings. Admit refetches the profile
|
|
90
|
+
and exact bundles before accepting that digest. Its owner-only immutable receipt
|
|
91
|
+
binds authority, workspace, profile ID, exact canonical container and mapped
|
|
92
|
+
payload versions/digests, source and projection digests, scope set, executable
|
|
93
|
+
witnesses, resolver command, authenticated owner identity, exact profile
|
|
94
|
+
revision, aliases and triggers. `observation` records the same freshly observed
|
|
95
|
+
principal and routing state. `evidenceDigest` hashes that complete authenticated
|
|
96
|
+
evidence snapshot, and `planDigest` hashes the admission identity including the
|
|
97
|
+
evidence digest. Admission requires both reviewed digests. Receipt reads validate
|
|
98
|
+
both hashes, strict field schemas and agreement between mapped and observed
|
|
99
|
+
identities. Legacy binding, plan and receipt schemas are refused rather than
|
|
100
|
+
upgraded implicitly. Originals remain in the
|
|
101
|
+
private hosted bundle; local native materializations contain only the projection.
|
|
102
|
+
|
|
103
|
+
The owner-local store is `~/.hasna/skills/plugin-admission/`: `bindings/` holds
|
|
104
|
+
content-addressed bindings, `receipts/<binding>/` holds approved plans, and
|
|
105
|
+
`objects/<binding>/<plan-digest>/` holds complete immutable projections. The
|
|
106
|
+
resolver freshly authenticates through normal owner credential configuration
|
|
107
|
+
on every call, including exact payload bundle reads. It refuses environment
|
|
108
|
+
authority/local-storage overrides. No `--cached`, API URL/key or local fallback
|
|
109
|
+
option exists. The resolver calls authenticated `whoami` before and after profile,
|
|
110
|
+
bundle and executable verification. The stable user/account identity and required
|
|
111
|
+
`owner` role must remain unchanged, and the account must equal the selected
|
|
112
|
+
workspace. Credential rotation remains valid because receipts never bind a raw
|
|
113
|
+
API-key identifier. Any profile revision, alias or trigger change requires a new
|
|
114
|
+
plan and explicit approval, including edits made after review. Missing
|
|
115
|
+
canonical selections, changed versions/digests, authority/workspace/profile
|
|
116
|
+
changes, revoked API access, changed package content or executable witnesses
|
|
117
|
+
still refuse or require renewed admission. A mapped canonical slug cannot be
|
|
118
|
+
replaced through an alias, even with identical content. Human plan/admit input
|
|
119
|
+
may use an integration alias; the resulting binding uses its canonical slug.
|
|
120
|
+
|
|
121
|
+
Re-admitting an unchanged identity and evidence returns its original receipt.
|
|
122
|
+
A new plan reports current principal and routing evidence. Resolver calls remain
|
|
123
|
+
write-free. Canonical object keys and
|
|
124
|
+
registration-set ordering keep binding IDs, plan digests and persisted binding
|
|
125
|
+
bytes stable.
|
|
126
|
+
|
|
127
|
+
Configure the private marketplace source using the receipt's exact
|
|
128
|
+
`sourceCommand`, `source: "command"`, `mode: "copy"` and `timeout: 30`.
|
|
129
|
+
On certified Linux hosts, that accepted command opens the reviewed resolver,
|
|
130
|
+
hashes `/proc/self/fd/9` with the absolute system SHA-256 utility, and executes
|
|
131
|
+
the same pinned descriptor. A pathname replacement before the open is rejected;
|
|
132
|
+
a replacement after hashing cannot become the executed resolver. The resolver
|
|
133
|
+
has a 25-second API deadline and prints exactly one absolute
|
|
134
|
+
directory path on success. Errors produce sanitized stderr and a nonzero exit.
|
|
135
|
+
Only explicit admission writes artifacts; resolve cannot publish or materialize
|
|
136
|
+
an unapproved revision. Concurrent admission uses a nonwaiting publication lock.
|
|
137
|
+
Interrupted attempts cannot expose partial directories as successful results.
|
|
138
|
+
|
|
139
|
+
Registration and activation remain explicit operations. Review the command
|
|
140
|
+
shown by Claude's JSON install/update response and pass its exact
|
|
141
|
+
`--accept-command` hash; never substitute blanket approval. Command-source
|
|
142
|
+
support begins at 2.1.229 and exact CLI acceptance at 2.1.271, but version 1
|
|
143
|
+
certifies 2.1.274 and 2.1.276. Claude invokes the source during installation and updates;
|
|
144
|
+
this does not imply a resolver invocation on every agent startup. This command does not upgrade Claude, register a
|
|
145
|
+
marketplace, change native settings, disable other plugins or restart agents.
|
|
146
|
+
|
|
147
|
+
## Discovery transition contract
|
|
148
|
+
|
|
149
|
+
After explicit native registration, use `captureManagedPluginRegistry()` in a
|
|
150
|
+
reviewed discovery input. It emits a `claude-plugin-registry` source witness with
|
|
151
|
+
the registry path and exact admission bindings. Keep the normal full witnesses
|
|
152
|
+
for native settings, marketplace catalog/source configuration and other loader
|
|
153
|
+
inputs. Do not retain a competing whole-registry byte witness when intentionally
|
|
154
|
+
admitting receipt-backed transitions; unmanaged entries remain covered by the
|
|
155
|
+
structured registry witness itself.
|
|
156
|
+
|
|
157
|
+
Only these managed row fields can vary after validation: `version`,
|
|
158
|
+
`installPath`, `sourceProducerPath`, `previousProducerPaths`, `lastUpdated`.
|
|
159
|
+
Every current row must match its own producer receipt and exact reviewed scope.
|
|
160
|
+
All retained native cache versions must match approved immutable projections,
|
|
161
|
+
including their command files, ordinary components, paths, modes and membership.
|
|
162
|
+
The certified native adapter separately validates root `.in_use/<pid>` process
|
|
163
|
+
markers and `.orphaned_at` epoch-millisecond pruning markers. These bounded
|
|
164
|
+
metadata records cannot authorize content, and cannot come from the original
|
|
165
|
+
package. Links, unknown keys, payload files and nested directories still refuse.
|
|
166
|
+
Every unmanaged row and every unknown field remains in the witness. New
|
|
167
|
+
registrations, changed commands, cross-scope substitutions or modified caches
|
|
168
|
+
refuse. Old receipts and projections remain until separately reviewed retirement.
|
|
169
|
+
|
|
170
|
+
Project plugin enablement requires a full reviewed settings-file witness and
|
|
171
|
+
matching admitted project registration. Other project discovery overrides and
|
|
172
|
+
new loaders still require their dedicated review. API failure refuses an update; it does not report a
|
|
173
|
+
stale projection as synchronized. Claude may retain its previous installation
|
|
174
|
+
after a refused update, whose existing local drift checks continue to apply.
|
|
175
|
+
|
|
176
|
+
## Marketplace registry timestamps
|
|
177
|
+
|
|
178
|
+
For an explicitly reviewed `known_marketplaces.json`,
|
|
179
|
+
`captureClaudeMarketplaceRegistry(path)` emits a separate
|
|
180
|
+
`claude-marketplace-registry` witness. It preserves every marketplace name,
|
|
181
|
+
source, install location and unknown value. Only a valid UTC `lastUpdated`
|
|
182
|
+
timestamp can vary, and only for exact rows containing `source`,
|
|
183
|
+
`installLocation` and `lastUpdated`, with a recognized GitHub repository or local
|
|
184
|
+
directory source. Rows with any extra field, including `autoUpdate`, retain
|
|
185
|
+
their entire contents in the digest. Registration changes still refuse.
|
|
186
|
+
|
|
187
|
+
This mode is opt-in for reviewed Claude discovery. It cannot project fields,
|
|
188
|
+
carry managed-plugin rules, accept an absent registry or synthesize registry
|
|
189
|
+
changes during hook installation. It does not replace the separate settings,
|
|
190
|
+
installed-plugin, marketplace catalog, loader, root or payload witnesses.
|
|
191
|
+
Capture requires a bounded regular file with strict UTF-8 and unambiguous JSON;
|
|
192
|
+
links, duplicate keys and concurrent file replacement refuse.
|
|
193
|
+
|
|
194
|
+
Existing byte witnesses retain their exact behavior. A prior hash mismatch is
|
|
195
|
+
not proof of a timestamp-only change: review the complete current registration
|
|
196
|
+
and its complementary sources before explicitly replacing an old witness.
|
|
197
|
+
Capturing this witness does not write a policy or approve native registration.
|
|
198
|
+
|
|
199
|
+
## Verification and limits
|
|
200
|
+
|
|
201
|
+
Unit tests cover provenance and mapping failures, offline/revoked authorities,
|
|
202
|
+
timeouts, concurrent publication, symlinks/special files, cache mutation, retained
|
|
203
|
+
history, and exact unmanaged registry coverage. Synthetic native tests exercise
|
|
204
|
+
actual Claude with a disposable home and loopback mock authority in a separate
|
|
205
|
+
network namespace. They contact no real provider and require explicit opt-in:
|
|
206
|
+
`SKILLS_TEST_CLAUDE_BIN`, `SKILLS_TEST_CLAUDE_SHA256` (reviewed native executable
|
|
207
|
+
digest), `SKILLS_TEST_CLAUDE_VERSION` (defaults to 2.1.274), and
|
|
208
|
+
`SKILLS_TEST_NETWORK_ISOLATED=1`. Both versioned and versionless upstream
|
|
209
|
+
manifests run through install, unchanged and changed updates, refusal and drift checks. Before native execution, the test
|
|
210
|
+
checks the source before/after copying, complete copied digest, size and ELF
|
|
211
|
+
format, then atomically publishes its private executable fixture.
|
|
212
|
+
|
|
213
|
+
The initial implementation is a reviewed admission boundary, not an upstream
|
|
214
|
+
ingestion scheduler or a general plugin execution sandbox. MacOS runtime proof,
|
|
215
|
+
additional native versions and providers require their own canary evidence.
|
|
216
|
+
Package data is bounded to 1,024 files, 64 MiB total and 16 MiB per file. Native
|
|
217
|
+
cache history is bounded to 128 entries and an aggregate 256 MiB per witness.
|
|
218
|
+
|
|
219
|
+
Primary runtime references: [command sources](https://code.claude.com/docs/en/plugin-marketplaces#command-sources),
|
|
220
|
+
[plugin components](https://code.claude.com/docs/en/plugins-reference), and
|
|
221
|
+
[exact command acceptance](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md#21271).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/skills",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.11",
|
|
4
4
|
"description": "Skills library for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"bin/",
|
|
39
39
|
"migrations/",
|
|
40
40
|
"docs/skill-standard.md",
|
|
41
|
+
"docs/plugin-admission.md",
|
|
41
42
|
"schemas/",
|
|
42
43
|
"LICENSE",
|
|
43
44
|
"README.md",
|
|
@@ -61,10 +62,11 @@
|
|
|
61
62
|
"typecheck": "tsc --noEmit",
|
|
62
63
|
"verify:release": "bun run scripts/release-guard.ts",
|
|
63
64
|
"verify:consumer-types": "bun run scripts/consumer-types.ts",
|
|
64
|
-
"
|
|
65
|
-
"prepack": "bun run build && bun run verify:release && bun run verify:consumer-types",
|
|
65
|
+
"prepack": "bun run verify:generated && bun run verify:release && bun run verify:consumer-types",
|
|
66
66
|
"prepublishOnly": "bun run verify:producer && bun run typecheck && bun run test",
|
|
67
|
-
"verify:producer": "bun run scripts/release-dependencies.ts"
|
|
67
|
+
"verify:producer": "bun run scripts/release-dependencies.ts",
|
|
68
|
+
"verify:generated": "HASNA_SKILLS_RELEASE_ARTIFACT_TEST=1 bun test src/lib/release-artifacts.test.ts",
|
|
69
|
+
"verify:consumer-credentials": "bun run scripts/consumer-credentials.ts"
|
|
68
70
|
},
|
|
69
71
|
"keywords": [
|
|
70
72
|
"skills",
|
|
@@ -86,7 +88,6 @@
|
|
|
86
88
|
"license": "Apache-2.0",
|
|
87
89
|
"devDependencies": {
|
|
88
90
|
"@hasna/contracts": "1.1.0",
|
|
89
|
-
"@hasna/secrets": "0.4.2",
|
|
90
91
|
"@types/bun": "1.3.14",
|
|
91
92
|
"@types/node": "25.2.3",
|
|
92
93
|
"@types/react": "^18.2.0",
|
|
@@ -99,6 +100,7 @@
|
|
|
99
100
|
"@aws-sdk/client-ecs": "^3.1079.0",
|
|
100
101
|
"@aws-sdk/client-s3": "^3.1079.0",
|
|
101
102
|
"@hasna/events": "0.1.18",
|
|
103
|
+
"@hasna/secrets": "0.4.2",
|
|
102
104
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
103
105
|
"chalk": "^5.3.0",
|
|
104
106
|
"commander": "^12.1.0",
|