@hasna/skills 0.10.71 → 0.10.73
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 +378 -6
- package/bin/index.js +6500 -5264
- package/bin/mcp.js +2080 -1821
- package/bin/migrate.js +2 -2
- package/bin/server.js +2 -2
- package/bin/worker.js +2 -2
- package/dist/cli/commands/context.d.ts +1 -0
- package/dist/index.js +5358 -4592
- package/dist/lib/agent-discovery-directories.d.ts +8 -3
- package/dist/lib/agent-discovery.d.ts +56 -4
- package/dist/lib/agent-integration.d.ts +39 -1
- package/dist/lib/claude-installer-binding.d.ts +65 -0
- package/dist/lib/claude-plugin-cache-marker.d.ts +10 -0
- package/dist/lib/codex-node-modules.d.ts +11 -0
- package/dist/lib/codex-plugin-skill-controls.d.ts +9 -0
- package/dist/lib/codex-settings-witness-v1.d.ts +9 -0
- package/dist/lib/codex-settings-witness.d.ts +18 -0
- package/dist/lib/codex-vendor-refresh.d.ts +54 -0
- package/dist/lib/config.d.ts +20 -0
- package/dist/lib/hook-diagnostics.d.ts +3 -1
- package/dist/lib/native-discovery-witness-change.d.ts +25 -0
- package/dist/lib/selection-cache.d.ts +22 -0
- package/dist/lib/selection-resolver.d.ts +3 -1
- package/dist/lib/session-reconciliation.d.ts +57 -1
- package/dist/runtime-prerequisites.js +188 -102
- package/dist/sdk/index.js +2604 -1857
- package/dist/storage.js +8 -4
- package/docs/plugin-admission.md +65 -4
- package/package.json +1 -1
package/dist/storage.js
CHANGED
|
@@ -53,13 +53,13 @@ import {
|
|
|
53
53
|
mkdirSync as mkdirSync3,
|
|
54
54
|
readFileSync as readFileSync3,
|
|
55
55
|
readdirSync,
|
|
56
|
-
statSync,
|
|
56
|
+
statSync as statSync2,
|
|
57
57
|
writeFileSync as writeFileSync3
|
|
58
58
|
} from "fs";
|
|
59
59
|
import { dirname as dirname2, join as join4, normalize, relative, sep } from "path";
|
|
60
60
|
|
|
61
61
|
// src/lib/config.ts
|
|
62
|
-
import { existsSync as existsSync2, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
62
|
+
import { closeSync, constants, existsSync as existsSync2, fstatSync, lstatSync, openSync, readFileSync, statSync, writeFileSync, mkdirSync } from "fs";
|
|
63
63
|
import { join as join2, dirname } from "path";
|
|
64
64
|
|
|
65
65
|
// src/lib/retired-settings.ts
|
|
@@ -195,7 +195,8 @@ function skillsDataRootForHome(home) {
|
|
|
195
195
|
var ENUM_KEYS = {
|
|
196
196
|
defaultAgent: ["claude", "codex", "gemini", "pi", "opencode", "all"],
|
|
197
197
|
defaultScope: ["global", "project"],
|
|
198
|
-
format: ["compact", "json", "csv"]
|
|
198
|
+
format: ["compact", "json", "csv"],
|
|
199
|
+
sessionPinMigration: ["auto", "off"]
|
|
199
200
|
};
|
|
200
201
|
var STRING_KEYS = ["extensionsDir"];
|
|
201
202
|
function validKeys() {
|
|
@@ -266,6 +267,9 @@ function saveConfig(key, value, scope = "project") {
|
|
|
266
267
|
if (!validKeys().includes(key)) {
|
|
267
268
|
throw new Error(`Unknown config key: ${key}. Valid keys: ${validKeys().join(", ")}`);
|
|
268
269
|
}
|
|
270
|
+
if (key === "sessionPinMigration" && scope !== "global") {
|
|
271
|
+
throw new Error(`${key} is read only from the global configuration. Use: skills config set ${key} <auto|off> --global`);
|
|
272
|
+
}
|
|
269
273
|
const normalized = normalizeConfigValue(key, value);
|
|
270
274
|
if (normalized === undefined) {
|
|
271
275
|
const allowed = allowedValues(key);
|
|
@@ -959,7 +963,7 @@ function walkFiles(dir) {
|
|
|
959
963
|
const files = [];
|
|
960
964
|
for (const entry of readdirSync(dir)) {
|
|
961
965
|
const full = join4(dir, entry);
|
|
962
|
-
const stats =
|
|
966
|
+
const stats = statSync2(full);
|
|
963
967
|
if (stats.isDirectory())
|
|
964
968
|
files.push(...walkFiles(full));
|
|
965
969
|
else
|
package/docs/plugin-admission.md
CHANGED
|
@@ -195,7 +195,7 @@ plugin dependency declarations refuse because this validator does not resolve
|
|
|
195
195
|
or review unselected external plugins.
|
|
196
196
|
The request may declare `functionHooksEnv: "1"`; without that declaration the
|
|
197
197
|
environment document is preserved unchanged. For a measured Claude 2.1.276,
|
|
198
|
-
2.1.278, 2.1.282, 2.1.287, 2.1.293, 2.1.296 or 2.1.
|
|
198
|
+
2.1.278, 2.1.282, 2.1.287, 2.1.293, 2.1.296, 2.1.299 or 2.1.300 user-scoped install,
|
|
199
199
|
`candidate.settingsMarketplaceSource: "directory"`
|
|
200
200
|
explicitly declares the native settings registration. Skills derives
|
|
201
201
|
`extraKnownMarketplaces[candidate.marketplace].source` from the exact frozen
|
|
@@ -249,6 +249,49 @@ structural refusal checks do not prove hook behavior. Recheck all preimages and
|
|
|
249
249
|
candidate closure immediately before the first native mutation. The validator
|
|
250
250
|
does not claim native install atomicity or crash recovery.
|
|
251
251
|
|
|
252
|
+
The reviewed discovery inputs must bind every current Claude settings and
|
|
253
|
+
registration source: the user settings, both project settings files,
|
|
254
|
+
`known_marketplaces.json` and `installed_plugins.json`. A project
|
|
255
|
+
`.claude/settings.json` or `.claude/settings.local.json` that the reviewed
|
|
256
|
+
sources omit is exempt only when no other expected source (the target settings
|
|
257
|
+
or the user settings) shares its path, and it is either:
|
|
258
|
+
|
|
259
|
+
- absent, with a null preimage; or
|
|
260
|
+
- present, and all of the following hold:
|
|
261
|
+
- its current bytes match its preimage SHA-256; a mismatch refuses with
|
|
262
|
+
`<name> preimage changed`;
|
|
263
|
+
- those exact bytes are strict UTF-8 without a byte-order mark and parse as
|
|
264
|
+
one JSON object within the native JSON witness limits (no comments,
|
|
265
|
+
trailing commas, trailing content or duplicate keys at any depth);
|
|
266
|
+
- none of `enabledPlugins`, `extraKnownMarketplaces`,
|
|
267
|
+
`additionalMarketplaces` or `skillOverrides` is present at any value,
|
|
268
|
+
including `null`, `{}` and `[]`;
|
|
269
|
+
- every top-level key is on the exemption allowlist with its type:
|
|
270
|
+
`permissions` (an object), `outputStyle`, `model`, `theme` and
|
|
271
|
+
`effortLevel` (strings), and `verbose` and `spinnerTipsEnabled` (booleans);
|
|
272
|
+
- `permissions` holds only `allow`, `deny` and `ask` (arrays of strings) and
|
|
273
|
+
`defaultMode` (a string).
|
|
274
|
+
|
|
275
|
+
Anything else keeps the file required, including `env` (Claude reads
|
|
276
|
+
`CLAUDE_CODE_PLUGIN_DIRS` from it), `hooks`, `permissions.additionalDirectories`
|
|
277
|
+
(Claude loads skills, commands and agents from those directories), `__proto__`
|
|
278
|
+
and unknown keys. The allowlist names settings reviewed as not configuring
|
|
279
|
+
plugins, marketplaces, skills, hooks, extra directories or the environment. It
|
|
280
|
+
does not prove that Claude cannot discover anything from the file; a setting
|
|
281
|
+
joins it only after that review.
|
|
282
|
+
|
|
283
|
+
This covers the permissions-only `~/.claude/settings.local.json` that Claude
|
|
284
|
+
writes when it saves a permission rule during a user-scope install, whose
|
|
285
|
+
project path is the Claude home. A present unreviewed file that fails the parse,
|
|
286
|
+
discovery-key or allowlist checks refuses and names the reason. Each exempt file
|
|
287
|
+
is re-checked against its exact preimage (still absent, or the same bytes) after
|
|
288
|
+
discovery and again before the result, so a change, creation or removal in
|
|
289
|
+
between refuses. The live hooks' project check still runs on top; it refuses
|
|
290
|
+
any of the four discovery keys (`additionalMarketplaces` included, because
|
|
291
|
+
Claude 2.1.300 rewrites it into `extraKnownMarketplaces` on every settings read)
|
|
292
|
+
and its other project skill and hook settings. The user settings and both
|
|
293
|
+
registries are never exempt.
|
|
294
|
+
|
|
252
295
|
The optional release manifest witness binds the complete supplied release.json
|
|
253
296
|
file bytes, path and SHA-256 in the request/receipt. Harnesses remains
|
|
254
297
|
responsible for verifying that its release options correspond to every
|
|
@@ -270,8 +313,12 @@ skills hook capture-claude-installer --request /absolute/request.json --json
|
|
|
270
313
|
The UTF-8 request is a bounded JSON object with schema
|
|
271
314
|
`skills.claude-installer-capture/v1`, the exact configured `commandPath`, one
|
|
272
315
|
fixed `operation` (`settings`, `marketplace-registry`, `managed-plugin-registry`,
|
|
273
|
-
`path-bytes`, `discovery-directories`, `plugin-manifest`,
|
|
274
|
-
only that operation's documented inputs. The
|
|
316
|
+
`path-bytes`, `discovery-directories`, `plugin-manifest`, `candidate`, or
|
|
317
|
+
`discovery-binding`), and only that operation's documented inputs. The
|
|
318
|
+
`discovery-binding` operation verifies the stored Claude discovery binding as a
|
|
319
|
+
whole, including witnesses retained under an absent retired plugin-cache
|
|
320
|
+
version; its request and result contract is in the README section
|
|
321
|
+
"Claude installer witness CLI". The result uses
|
|
275
322
|
`skills.claude-installer-capture-result/v1` and contains a Skills producer
|
|
276
323
|
receipt plus the selected existing witness result. Candidate manifests include
|
|
277
324
|
their plugin name, canonical path, `hashMode: "claude-plugin-manifest-v1"`, and
|
|
@@ -330,9 +377,23 @@ What the software currently enforces is narrower:
|
|
|
330
377
|
managed row's `installPath` to be `cache/<marketplace>/<plugin>/<version>`,
|
|
331
378
|
checks every file in every retained cache version against the admission
|
|
332
379
|
receipts without the review listing them, and binds unmanaged rows exactly.
|
|
380
|
+
- Claude rewrites the 13-digit millisecond timestamp in
|
|
381
|
+
`.claude/plugins/cache/<marketplace>/<plugin>/<version>/.orphaned_at` when it
|
|
382
|
+
starts. Capturing that exact path with `captureDiscoveryByteSources` or
|
|
383
|
+
`captureDiscoveryPathSources` (including the installer `path-bytes`
|
|
384
|
+
operation) produces a `claude-plugin-orphaned-at-v1` witness, and a fresh
|
|
385
|
+
explicit review converts a plain byte or `path-bytes` witness of it to that
|
|
386
|
+
form. The witness binds the marker's presence or absence, not its bytes or
|
|
387
|
+
inode. Every capture and check still requires a regular, non-symlink file
|
|
388
|
+
owned by the current user, at most 32 bytes, matching `^[1-9][0-9]{12}$`.
|
|
389
|
+
The name stays in `directories` membership, so other added or removed names
|
|
390
|
+
are still detected. A marker at any other depth, any other name, and any
|
|
391
|
+
Skills-owned producer tree keep their exact byte witnesses. A stored review
|
|
392
|
+
that binds the marker's bytes keeps that meaning and needs one fresh review.
|
|
333
393
|
- An entirely absent retired Claude version root exempts only its plain byte
|
|
334
394
|
sources (`hashMode` omitted or `"bytes"`, with no `format`, `fields` or
|
|
335
|
-
`managedPlugins`)
|
|
395
|
+
`managedPlugins`) and a present `claude-plugin-orphaned-at-v1` marker. Such a
|
|
396
|
+
source with a non-null `sha256` is also the only
|
|
336
397
|
thing that identifies the root, and the root qualifies only while it stays
|
|
337
398
|
entirely absent and the reviewed settings and registry select a different,
|
|
338
399
|
verified version. Every other source under that root is re-hashed as usual,
|