@hasna/skills 0.10.80 → 0.10.81
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 +225 -0
- package/bin/index.js +3140 -1734
- package/bin/mcp.js +698 -484
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/cli/commands/metadata.d.ts +2 -0
- package/dist/index.js +1962 -912
- package/dist/lib/agent-discovery.d.ts +11 -0
- package/dist/lib/agent-integration.d.ts +119 -1
- package/dist/lib/codex-native-skill-catalog.d.ts +38 -0
- package/dist/lib/codex-plugin-capability-paths.d.ts +8 -0
- package/dist/lib/codex-plugin-reconcile.d.ts +74 -0
- package/dist/lib/codex-plugin-skill-controls.d.ts +68 -1
- package/dist/lib/remote-client.d.ts +10 -0
- package/dist/lib/skill-metadata-update.d.ts +46 -0
- package/dist/lib/skill-validation.d.ts +3 -1
- package/dist/runtime-prerequisites.js +1 -1
- package/dist/sdk/index.d.ts +1 -0
- package/dist/sdk/index.js +2146 -1095
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1109,6 +1109,230 @@ reports an incomplete outcome, inspect `sessions show` and the preserved
|
|
|
1109
1109
|
operation receipt before retrying. The archive contains both original and
|
|
1110
1110
|
prepared bytes even if the final receipt write fails.
|
|
1111
1111
|
|
|
1112
|
+
### Codex plugin skill name reconcile (`hook codex-reconcile`)
|
|
1113
|
+
|
|
1114
|
+
A Codex or plugin update can add skill names to a plugin Skills already
|
|
1115
|
+
enrolled, or bump its manifest version. The strict guard then refuses with
|
|
1116
|
+
`NATIVE_SKILL_DRIFT`. Run the package-owned reconcile instead of turning guards
|
|
1117
|
+
off:
|
|
1118
|
+
|
|
1119
|
+
```bash
|
|
1120
|
+
skills hook codex-reconcile --json # read-only preview
|
|
1121
|
+
skills hook codex-reconcile --apply --json # write, then prove the guard passes
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
It reads Codex's qualified skill and installed-plugin catalog through the same
|
|
1125
|
+
owned client as `skills hook native-catalog` (`--codex-command <path>`, default
|
|
1126
|
+
`codex`). It then runs the full strict guard and collects the plugin-cache copies
|
|
1127
|
+
the guard refuses. The work it does:
|
|
1128
|
+
|
|
1129
|
+
- It enrolls each new qualified name of an enrolled plugin whose capability
|
|
1130
|
+
tuple is unchanged, and denies it in `~/.codex/config.toml` with
|
|
1131
|
+
`[[skills.config]] name = "<plugin>:<skill>"` and `enabled = false`.
|
|
1132
|
+
- It enrolls a plugin Skills had not enrolled only when every version is
|
|
1133
|
+
skills-only. A plugin is remote when the native catalog reports a remote
|
|
1134
|
+
source or any remote identity (`remotePluginId`), whatever else it says about
|
|
1135
|
+
the source; this one rule also governs the install review and the inactive
|
|
1136
|
+
rule. A remote plugin's install receipt is bound only when the receipt read
|
|
1137
|
+
before Codex started named the catalog's identity and the current receipt
|
|
1138
|
+
still does, because starting Codex rewrites receipts. Any other remote plugin,
|
|
1139
|
+
and a receipt beside a plugin the catalog does not report as remote, refuses
|
|
1140
|
+
as `remote`.
|
|
1141
|
+
- It binds the verified install receipt onto every control of an enrolled
|
|
1142
|
+
remote plugin whose stored controls lack it (policies written before every
|
|
1143
|
+
control recorded one), and lists the plugin in `bound`. The proof is the one
|
|
1144
|
+
a fresh `hook install` uses: the pre-start reading and the current receipt
|
|
1145
|
+
both name the catalog's identity, and every control that already carries one
|
|
1146
|
+
agrees. Otherwise it refuses with `CODEX_REMOTE_RECEIPT_MISSING`,
|
|
1147
|
+
`CODEX_REMOTE_RECEIPT_MISMATCH` or reason `remote`, and writes nothing. A new
|
|
1148
|
+
name of an enrolled plugin always carries the plugin's receipt. A plugin the
|
|
1149
|
+
catalog no longer reports as remote whose controls are only partly bound
|
|
1150
|
+
refuses as `remote`. An enrolled plugin whose bound receipt was absent or
|
|
1151
|
+
named another installation before Codex started refuses as `remote`, even
|
|
1152
|
+
when nothing else needs writing.
|
|
1153
|
+
- It denies skills that Codex loads from its runtime cache
|
|
1154
|
+
(`~/.cache/codex-runtimes`) by their stable qualified name. A skill there with
|
|
1155
|
+
no stable qualified name gets an exact path deny instead, listed in
|
|
1156
|
+
`pathDenied` with the reason `no-qualified-name`. No plugin control exists for
|
|
1157
|
+
runtime-cache skills.
|
|
1158
|
+
- It classifies every installed plugin that is active, including plugins the
|
|
1159
|
+
saved binding does not know: each one enabled with `enabled = true` under
|
|
1160
|
+
`[plugins]`, each one config disables that is not inactive by the rule
|
|
1161
|
+
below, and each one the native catalog reports installed and enabled. That
|
|
1162
|
+
holds even when none of the plugin's skills block today. Installed means the
|
|
1163
|
+
plugin has a directory in the plugin cache; an enabled plugin with no cache
|
|
1164
|
+
directory has nothing to classify yet. An enabled plugin id that is not
|
|
1165
|
+
`<name>@<marketplace>` (letters, digits, `_` and `-`) refuses as
|
|
1166
|
+
`unsupported`. A known plugin is enrolled, reviewed inactive, an installation
|
|
1167
|
+
input, or a semantic-cache role. It can also be known through a full witness
|
|
1168
|
+
under its exact cache parent, or through a full witness of a reviewed local
|
|
1169
|
+
marketplace that maps exactly that plugin, together with a full witness of the
|
|
1170
|
+
manifest that marketplace row points to. A manifest witness elsewhere that
|
|
1171
|
+
only shares the plugin's name does not count. Every other enabled plugin is
|
|
1172
|
+
scanned like a new plugin, and one that carries a capability refuses.
|
|
1173
|
+
- It leaves an inactive plugin unenrolled and never refuses because of one.
|
|
1174
|
+
Inactive uses the same rule as the reviewed plugin controls, because config
|
|
1175
|
+
alone cannot prove a plugin is off (remote reconciliation can enable a plugin
|
|
1176
|
+
while config still disables it): `[plugins]` sets `enabled = false`, the
|
|
1177
|
+
native catalog reports the plugin installed and disabled, its source is
|
|
1178
|
+
config-controlled (a local, git or npm source with a source fingerprint, no
|
|
1179
|
+
remote identity and not a remote marketplace), and the catalog lists none of
|
|
1180
|
+
its skills. Any other plugin is active and gets every capability and receipt
|
|
1181
|
+
check. The guard does not trust a plugin-level disable alone, so an inactive
|
|
1182
|
+
plugin's cache copies keep exact path denies, listed with the reason
|
|
1183
|
+
`plugin-disabled`.
|
|
1184
|
+
- For a reviewed binding whose full-byte witnesses name an enrolled plugin's
|
|
1185
|
+
manifest, app, MCP or skill files (byte-witness bindings), it re-captures
|
|
1186
|
+
those witnesses in the new version root once the capability tuple is proven
|
|
1187
|
+
unchanged and the strict scan below finds nothing beyond that tuple. This
|
|
1188
|
+
reconcile handles skills-only manifest bumps for byte-witness bindings. `skills hook rebind-cache` does not: it still refuses bindings that
|
|
1189
|
+
never had exact cache-directory coverage.
|
|
1190
|
+
|
|
1191
|
+
The plan comes from the reviewed `hook install` planner. Apply holds the corpus
|
|
1192
|
+
lock, re-plans from the same catalog, checks every preimage and keeps private
|
|
1193
|
+
backups with readback. The deny rows are written by Codex's own writer, not by
|
|
1194
|
+
Skills: an owned `codex app-server` reads the user layer (`config/read`), and
|
|
1195
|
+
`config/batchWrite` writes `skills.config` with that layer's `expectedVersion`
|
|
1196
|
+
and `reloadUserConfig: true`. A concurrent Codex writer, such as the desktop
|
|
1197
|
+
app, makes the write refuse with `CODEX_RECONCILE_NATIVE_WRITE_REFUSED` instead
|
|
1198
|
+
of being overwritten, and this run writes nothing else. With no Codex writer
|
|
1199
|
+
reachable the run refuses with `CODEX_RECONCILE_NATIVE_WRITER_UNAVAILABLE`; it
|
|
1200
|
+
never falls back to a direct file write. The managed policy is written in the
|
|
1201
|
+
Skills transaction only after `config.toml` reads back as exactly the planned
|
|
1202
|
+
configuration. If a step fails, the policy is restored while it still holds this
|
|
1203
|
+
run's bytes, and `config.toml` is restored only through Codex's writer, only
|
|
1204
|
+
while Codex still reports this run's version; otherwise the result is
|
|
1205
|
+
`CODEX_RECONCILE_COMPENSATION_INCOMPLETE` and names the private backup. Only an
|
|
1206
|
+
error answer from Codex counts as a refusal. When Codex does not answer (a
|
|
1207
|
+
timeout or a lost app-server), or answers without a valid config version, the
|
|
1208
|
+
write cannot be verified: the result is `CODEX_RECONCILE_NATIVE_WRITE_UNCERTAIN`,
|
|
1209
|
+
naming the deny rows that may remain and the private backup, and the policy is
|
|
1210
|
+
not written. The next run finishes the policy without another config write once
|
|
1211
|
+
Codex reports those skills disabled. After the policy write, the run re-checks
|
|
1212
|
+
the written state, and either outcome below compensates both writes. A new
|
|
1213
|
+
capability location that appeared while Codex was writing (a root `hooks.json`,
|
|
1214
|
+
`commands/`, `agents/` or another manifest directory) refuses with
|
|
1215
|
+
`CODEX_PLUGIN_CAPABILITY_REVIEW_REQUIRED`. A change to a manifest, `.app.json`
|
|
1216
|
+
or remote install receipt that the plan observed ends as the error
|
|
1217
|
+
`CODEX_RECONCILE_FAILED` ("Native identity source changed during application").
|
|
1218
|
+
A plugin Codex uninstalled after it was enrolled stays unchanged, as the guard
|
|
1219
|
+
treats it, while its retained controls are remote, skills-only and denied by
|
|
1220
|
+
name, and the native catalog no longer reports it enabled. The receipt records each writer and Codex's new
|
|
1221
|
+
config version. The run finishes only when the strict guard accepts the written
|
|
1222
|
+
state. The plan may
|
|
1223
|
+
append disable rows to the Codex configuration. In the managed policy it may
|
|
1224
|
+
only add the new controls and refresh the configuration and re-captured cache
|
|
1225
|
+
witnesses, and bind a verified receipt onto stored controls that lack one.
|
|
1226
|
+
Anything else refuses with `CODEX_RECONCILE_SCOPE_EXCEEDED`. The reconcile
|
|
1227
|
+
never adds an allow entry.
|
|
1228
|
+
|
|
1229
|
+
Residual: the strict guard checks every control that carries a receipt, and it
|
|
1230
|
+
still tolerates a plugin none of whose controls carries one, because policies
|
|
1231
|
+
written before receipts were recorded have none and refusing them would block
|
|
1232
|
+
every Codex session on upgrade. Such a plugin is receipt-protected only after a
|
|
1233
|
+
reconcile or `skills hook install` binds its receipt.
|
|
1234
|
+
|
|
1235
|
+
The allowed set is computed from Codex's own report, not from a simulation of
|
|
1236
|
+
the existing configuration. Every skill the native catalog reports as enabled
|
|
1237
|
+
counts as allowed unless a disable row this run appends matches it. The run
|
|
1238
|
+
succeeds only when that leaves exactly the bridge. A skill Codex still reports
|
|
1239
|
+
enabled despite a deny row already in the configuration it read (an ineffective
|
|
1240
|
+
deny, or a wrong name) refuses with `CODEX_NATIVE_SKILL_ALLOWED_SET_INVALID`.
|
|
1241
|
+
The catalog is read before the write, so the result shows what Codex reported
|
|
1242
|
+
then plus the rows this run appended. Run the reconcile again to confirm Codex
|
|
1243
|
+
applied them: `unchanged` means a fresh catalog reports every denied skill
|
|
1244
|
+
disabled.
|
|
1245
|
+
|
|
1246
|
+
Unsupported boundary: a change that touches more than skill names stays
|
|
1247
|
+
quarantined until a person reviews it. That covers a new or changed app, MCP
|
|
1248
|
+
declaration, hooks, manifest content other than `version`, or remote install
|
|
1249
|
+
receipt of an enrolled plugin. It also covers a plugin Skills has not enrolled
|
|
1250
|
+
that carries an app, MCP or hooks. The plugin stays disabled, or its skills stay
|
|
1251
|
+
denied, as they already were. The command refuses with
|
|
1252
|
+
`CODEX_PLUGIN_CAPABILITY_REVIEW_REQUIRED`, writes nothing, and lists each plugin
|
|
1253
|
+
with its capability kinds (`app`, `mcp`, `hooks`, `commands`, `agents`,
|
|
1254
|
+
`manifest`, `manifest-location`, `remote`, `unsupported`). The reconcile is what
|
|
1255
|
+
refuses these cases; the guard alone does not catch every one yet. The guard
|
|
1256
|
+
blocks new skill copies of a plugin it does not know, and blocks with
|
|
1257
|
+
`NATIVE_SKILL_DRIFT: CODEX_PLUGIN_CAPABILITY_REVIEW_REQUIRED: ...` when an
|
|
1258
|
+
enrolled plugin's reviewed tuple changes (its manifest apart from `version`, a
|
|
1259
|
+
declared app or MCP file, or its remote receipt). It does not yet notice an
|
|
1260
|
+
enrolled plugin gaining a root `hooks.json`, `commands/`, `agents/` or another
|
|
1261
|
+
manifest directory in place, without a version or skill change. The reconcile
|
|
1262
|
+
refuses those, including when they appear while it is writing, and the guard
|
|
1263
|
+
gap is tracked as a follow-up (UW-00793). Review the plugin with
|
|
1264
|
+
`skills hook install --agent codex --discovery-inputs <reviewed-file>
|
|
1265
|
+
--codex-native-catalog <reviewed-catalog> --apply`.
|
|
1266
|
+
|
|
1267
|
+
Reviewer check, the method rule for capability classification. Confirm each
|
|
1268
|
+
point before accepting a reconcile result or a change to it:
|
|
1269
|
+
|
|
1270
|
+
- Every version root is scanned against the shared location sets in
|
|
1271
|
+
`codex-plugin-capability-paths.ts`, the single source, without regard to
|
|
1272
|
+
case. The scan covers every manifest location Codex reads. The Agent Plugins
|
|
1273
|
+
root `plugin.json` comes first, then `.codex-plugin`, `.claude-plugin` and
|
|
1274
|
+
`.cursor-plugin`. It also covers `hooks/`, `hooks.json`, `.mcp.json`,
|
|
1275
|
+
`.app.json`, `commands/` and `agents/`. Declaration files and manifest
|
|
1276
|
+
directories count at any depth. A skill document not spelled exactly
|
|
1277
|
+
`SKILL.md` counts, and so does any link or special file. Capability-named
|
|
1278
|
+
entries beside the versions count too.
|
|
1279
|
+
- `.codex-plugin` must hold exactly `plugin.json`. A new plugin's manifest may
|
|
1280
|
+
carry only the shared metadata keys. `apps` counts as the app capability,
|
|
1281
|
+
every other key counts as a capability or unsupported, and `skills` must be
|
|
1282
|
+
the default `./skills` root. Inline manifest hooks count: a missing
|
|
1283
|
+
`hooks.json` is never evidence of no hooks. `chrome@openai-bundled` declares
|
|
1284
|
+
its `mcp_tool` hooks only in its manifest.
|
|
1285
|
+
- An enrolled plugin gets the same strict scan over every current version root,
|
|
1286
|
+
as well as the reviewed-tuple check. Only the reviewed `.codex-plugin`
|
|
1287
|
+
manifest, and an exact root `.app.json` or `.mcp.json` its tuple declares, are
|
|
1288
|
+
bound. Anything else refuses. The witness rebase runs only for a plugin that
|
|
1289
|
+
passes both checks.
|
|
1290
|
+
- Every skills-only result cites the manifest paths that were read, in
|
|
1291
|
+
`classified[].manifests`. Every refusal entry carries `manifests` the same
|
|
1292
|
+
way. A root whose manifest cannot be read is `unsupported`, never skills-only.
|
|
1293
|
+
- Every installed plugin enabled in `[plugins]` is classified, not only the
|
|
1294
|
+
ones the current binding knows, and an enabled id that does not parse
|
|
1295
|
+
refuses.
|
|
1296
|
+
|
|
1297
|
+
These also refuse and write nothing:
|
|
1298
|
+
|
|
1299
|
+
- `CODEX_RECONCILE_DISCOVERY_REVIEW_REQUIRED`: a binding with no recorded
|
|
1300
|
+
installed-plugin catalog review. That is the older shape. It needs a fresh full
|
|
1301
|
+
discovery review.
|
|
1302
|
+
- `CODEX_NATIVE_SKILL_NAME_CONFLICT`: an existing `[[skills.config]]` rule that
|
|
1303
|
+
is not `enabled = false` and either names a skill this run enrolls, denies or
|
|
1304
|
+
already controls (including the catalog name of a skill it denies by path),
|
|
1305
|
+
or has a path that resolves to a document this run denies. Those documents
|
|
1306
|
+
are the plugin-cache copies it handles and the runtime-cache skills it denies,
|
|
1307
|
+
by name or by path. Enable rules for any other skill are left to the strict
|
|
1308
|
+
guard.
|
|
1309
|
+
- `CODEX_NATIVE_SKILL_ALLOWED_SET_INVALID`: a skill other than the bridge that
|
|
1310
|
+
the native catalog reports enabled and no row appended by this run disables.
|
|
1311
|
+
- `CODEX_NATIVE_SKILL_CATALOG_UNSUPPORTED_VERSION` or
|
|
1312
|
+
`CODEX_HOOK_TRUST_NATIVE_UNSUPPORTED_VERSION`: an unmeasured Codex release.
|
|
1313
|
+
- `NATIVE_SKILL_DRIFT`: copies outside the plugin cache, or any other drift.
|
|
1314
|
+
- `CODEX_RECONCILE_SYMLINK_REFUSED`: a link in a native path.
|
|
1315
|
+
- `CODEX_RECONCILE_NATIVE_WRITER_UNAVAILABLE`: no Codex app-server could be
|
|
1316
|
+
started to write the deny rows.
|
|
1317
|
+
- `CODEX_RECONCILE_NATIVE_CONFIG_MISMATCH`: Codex reports a user configuration
|
|
1318
|
+
other than the one the run planned against.
|
|
1319
|
+
- `CODEX_RECONCILE_NATIVE_WRITE_REFUSED`: Codex refused the versioned write, for
|
|
1320
|
+
example because `config.toml` changed after Codex read it.
|
|
1321
|
+
- `CODEX_RECONCILE_SEMANTIC_CACHE_UNSUPPORTED`: a binding that uses the semantic
|
|
1322
|
+
cache witness.
|
|
1323
|
+
|
|
1324
|
+
Every invocation prints exactly one JSON line with `schema`
|
|
1325
|
+
(`hasna.skills-codex-reconcile.v1`), `mode` (`preview` or `apply`) and
|
|
1326
|
+
`outcome`. The outcome is `applied`, `unchanged`, `planned` (preview only),
|
|
1327
|
+
`refused` or `error`. `code` and `message` are present exactly when the outcome
|
|
1328
|
+
is refused or error. The line also carries `counts` (`enrolled`,
|
|
1329
|
+
`alreadyEnrolled`, `denied`, `pathDenied`, `skipped`, `allowed`), `enrolled`,
|
|
1330
|
+
`denied`, `pathDenied`, `inactive`, `classified`, `rebasedWitnesses`, `bound`, `allowed` (always
|
|
1331
|
+
`["skills-cli"]` on success), `refusals`, `changes`, and on apply `receipt` and
|
|
1332
|
+
`backups`. The exit status is 0 for applied, unchanged and planned, 2 for
|
|
1333
|
+
refused and 1 for error. A second apply returns `unchanged`. The command never
|
|
1334
|
+
retries within one invocation and never disables a guard.
|
|
1335
|
+
|
|
1112
1336
|
### Claude installer witness CLI (`capture-claude-installer`)
|
|
1113
1337
|
|
|
1114
1338
|
```text
|
|
@@ -1795,6 +2019,7 @@ of app folders, and `XDG_CONFIG_HOME` is not consulted at all.
|
|
|
1795
2019
|
| `skills provenance [--session <id>] [--station <id>] --json` | `--cached` | Read-only receipt of the selected, activated, applied, pinned and actually loaded skill versions, each with its status and reason; writes nothing |
|
|
1796
2020
|
| `skills sessions reconcile <id> --from-profile <id> --from-revision <rev> --receipt-sha256 <sha> --selection-profile <id> --profile-revision <rev>` | | Plan an explicit migration of one live session; `--apply --plan-digest <digest> --plan-issued-at <time> --plan-expires-at <time>` (within five minutes) preserves its old receipt and applies the reviewed replacement |
|
|
1797
2021
|
| `skills hook agents --json` | | Report maintained adapters and explicit coverage limits |
|
|
2022
|
+
| `skills hook codex-reconcile` | `--apply`, `--codex-command <path>`, `--json` | Deny every Codex plugin skill except the bridge by stable qualified name; enroll skills-only plugin changes, refuse capability changes with `CODEX_PLUGIN_CAPABILITY_REVIEW_REQUIRED`; one JSON line per run |
|
|
1798
2023
|
| `skills migrate native` | | Inventory native copies; `--apply` archives managed copies, with explicit `--include-unmanaged`, `--include-vendor`, or reviewed `--target-manifest` selection |
|
|
1799
2024
|
| `skills pull --all --selection-profile <id>` | | With CLI loading active, refresh the selected profile into the verified cache |
|
|
1800
2025
|
| `skills review-export <slug@version> --output <path>` | | Export one immutable hosted bundle to a private archive for review without selecting it |
|