@hasna/skills 0.10.72 → 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 +270 -2
- package/bin/index.js +1687 -1238
- package/bin/mcp.js +116 -35
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.js +947 -696
- package/dist/lib/agent-discovery.d.ts +36 -0
- package/dist/lib/claude-installer-binding.d.ts +65 -0
- package/dist/lib/codex-node-modules.d.ts +11 -0
- package/dist/lib/codex-settings-witness-v1.d.ts +9 -0
- package/dist/lib/codex-settings-witness.d.ts +18 -0
- package/dist/runtime-prerequisites.js +1 -1
- package/dist/sdk/index.js +1056 -820
- package/docs/plugin-admission.md +50 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -113,6 +113,27 @@ skills hook install --selection-profile default --json
|
|
|
113
113
|
skills hook install --selection-profile default --apply --json
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
+
`--include-vendor` resolves configured plugin discovery, so it needs a reviewed
|
|
117
|
+
`--discovery-inputs` file when a configured plugin declares hooks. Without it,
|
|
118
|
+
`skills migrate native --include-unmanaged` archives user and project copies
|
|
119
|
+
only. Migration never archives Codex system skills (`.codex/skills/.system`),
|
|
120
|
+
even with `--include-vendor`. Codex refreshes its OpenAI marketplace plugin
|
|
121
|
+
caches on its own; retire those copies with a Codex `[[skills.config]]` rule
|
|
122
|
+
(`name = "<plugin>:<skill>"` or the exact `path` of the `SKILL.md`, with
|
|
123
|
+
`enabled = false`) rather than by archiving. The live Codex prompt hook accepts
|
|
124
|
+
a name rule only for a copy with no Hasna marker, its remote install receipt, a
|
|
125
|
+
refresh-safe plugin and no rule that enables it. Other checks (`skills hook
|
|
126
|
+
install` reusing a saved review, `skills hook trust`) do not accept a
|
|
127
|
+
hand-added name rule; for them, and for system skills, run `skills hook install
|
|
128
|
+
--agent codex --discovery-inputs <file> --apply` with a fresh discovery review
|
|
129
|
+
(no `--discovery-inputs` on an automatic binding; add a fresh
|
|
130
|
+
`--codex-native-catalog <file>` for a plugin Skills has enrolled), which writes
|
|
131
|
+
and records the disables. Run the same refresh after editing `config.toml` when
|
|
132
|
+
the binding's recorded configuration witness counts the edit: on automatic
|
|
133
|
+
bindings, after removing a rule that enables skills, and on reviewed bindings
|
|
134
|
+
whose witness counts disable rows. A `NATIVE_SKILL_DRIFT` refusal names the
|
|
135
|
+
step for each copy it lists, including that follow-up.
|
|
136
|
+
|
|
116
137
|
Without `--agent`, hook installation selects configured or detected consumers:
|
|
117
138
|
existing managed bridge bindings, provider-specific home configuration, or an
|
|
118
139
|
installed native CLI found through PATH. Detection reads metadata and never
|
|
@@ -264,8 +285,8 @@ discovery-witness changes such a refresh provably makes:
|
|
|
264
285
|
unknown keys refuse. There is no `hooks`, `commands` or `agents` directory, no
|
|
265
286
|
`hooks.json` or `.mcp.json` (names compared without regard to case), no root,
|
|
266
287
|
`.claude-plugin` or `.cursor-plugin` manifest, no link
|
|
267
|
-
and no `SKILL.md`
|
|
268
|
-
|
|
288
|
+
and no `SKILL.md` below a dot-named or `node_modules` directory, or nested
|
|
289
|
+
in another skill. One exception keeps
|
|
269
290
|
today's vendor plugins working: every current OpenAI vendor plugin declares
|
|
270
291
|
its connector as `apps = "./.app.json"`, so exactly that declaration is
|
|
271
292
|
allowed when `.app.json` is a regular file of at most 1 MiB, strict UTF-8, that
|
|
@@ -541,6 +562,20 @@ is bounded to 20,000 discovery entries and 4 MiB of UTF-8 path metadata before
|
|
|
541
562
|
directory entries are retained or sorted. Unsupported special files and unsafe
|
|
542
563
|
directory links are refused.
|
|
543
564
|
|
|
565
|
+
Codex 0.162.1 loads `SKILL.md` files below `node_modules` inside its skill
|
|
566
|
+
roots, so Codex inventory and the prompt guard walk `node_modules` in
|
|
567
|
+
`~/.codex/skills`, `~/.agents/skills`, each project's `.codex/skills` and
|
|
568
|
+
`.agents/skills` and configured plugin skill roots. In `~/.codex/plugins/cache`
|
|
569
|
+
they walk it only where it can lie in a plugin skill root: below a version's
|
|
570
|
+
default `skills` directory or a manifest-declared skills path, or as a
|
|
571
|
+
marketplace, plugin or version directory named `node_modules`; an unreadable
|
|
572
|
+
manifest walks every `node_modules` in its version. Dot-named directories such
|
|
573
|
+
as `node_modules/.pnpm`, a plugin version's own dependencies and any
|
|
574
|
+
`node_modules` outside a skill root stay unscanned, because Codex does not load
|
|
575
|
+
them; other agents' roots keep skipping `node_modules`. Depth limits are
|
|
576
|
+
unchanged: Codex reads six directory levels below a root, and an ordinary root
|
|
577
|
+
records a skill four levels down and refuses anything deeper.
|
|
578
|
+
|
|
544
579
|
Native archives persist a version 2 recovery journal before moving payloads;
|
|
545
580
|
`migrate native --json --apply` returns its `receiptPath`. The journal records
|
|
546
581
|
every source, archive path, expected hash, and move status, then marks successful
|
|
@@ -702,6 +737,25 @@ receipt permits only verified registry/cache transitions. See
|
|
|
702
737
|
[plugin admission](docs/plugin-admission.md) for the package, review and runtime
|
|
703
738
|
contracts; these commands do not change live agent registrations or settings.
|
|
704
739
|
|
|
740
|
+
The read-only `skills hook review-claude-candidate` check requires its reviewed
|
|
741
|
+
discovery inputs to bind the user settings, both project settings files and
|
|
742
|
+
both plugin registries. A project `.claude/settings.json` or
|
|
743
|
+
`.claude/settings.local.json` that the review omits is exempt only when no other
|
|
744
|
+
expected source shares its path and it is either absent, or present with exact
|
|
745
|
+
preimage bytes that parse strictly as one JSON object (strict UTF-8, no
|
|
746
|
+
byte-order mark, comments, trailing content or duplicate keys) and carry only
|
|
747
|
+
allowlisted settings: `permissions` with `allow`, `deny`, `ask` and
|
|
748
|
+
`defaultMode`, plus `outputStyle`, `model`, `theme`, `effortLevel`, `verbose`
|
|
749
|
+
and `spinnerTipsEnabled`. Any discovery key (`enabledPlugins`,
|
|
750
|
+
`extraKnownMarketplaces`, `additionalMarketplaces`, `skillOverrides`), `env`,
|
|
751
|
+
`hooks`, `permissions.additionalDirectories` or unknown key keeps the file
|
|
752
|
+
required. The allowlist is a reviewed list of settings, not a proof that Claude
|
|
753
|
+
cannot discover anything from the file. This admits the permissions-only
|
|
754
|
+
`~/.claude/settings.local.json` that Claude writes when it saves a permission
|
|
755
|
+
rule. Each exempt file is re-checked against its exact preimage until the
|
|
756
|
+
result; user settings and the registries are never exempt. See
|
|
757
|
+
[prospective Claude candidate review](docs/plugin-admission.md#prospective-claude-candidate-review).
|
|
758
|
+
|
|
705
759
|
If your home `.claude` or `.codex` directory intentionally links to another
|
|
706
760
|
directory within your home, add `--allow-root-aliases` to hook installation and
|
|
707
761
|
native migration. The plan records and rechecks the exact link and target;
|
|
@@ -1009,6 +1063,209 @@ reports an incomplete outcome, inspect `sessions show` and the preserved
|
|
|
1009
1063
|
operation receipt before retrying. The archive contains both original and
|
|
1010
1064
|
prepared bytes even if the final receipt write fails.
|
|
1011
1065
|
|
|
1066
|
+
### Claude installer witness CLI (`capture-claude-installer`)
|
|
1067
|
+
|
|
1068
|
+
```text
|
|
1069
|
+
skills hook capture-claude-installer --request /absolute/request.json --json
|
|
1070
|
+
```
|
|
1071
|
+
|
|
1072
|
+
Installers obtain Skills-owned witnesses through the configured Skills command
|
|
1073
|
+
instead of reimplementing them. Every request is a JSON object of at most
|
|
1074
|
+
64 KiB with exactly the keys of one operation: `schema`
|
|
1075
|
+
(`skills.claude-installer-capture/v1`), `commandPath` (the normalized absolute
|
|
1076
|
+
path of the configured Skills command), `operation`, and that operation's
|
|
1077
|
+
inputs. The command checks that `commandPath` resolves to this installed
|
|
1078
|
+
`@hasna/skills` CLI and runtime, before and after the operation, and prints
|
|
1079
|
+
one receipt on stdout with exit status 0:
|
|
1080
|
+
|
|
1081
|
+
```json
|
|
1082
|
+
{
|
|
1083
|
+
"schema": "skills.claude-installer-capture-result/v1",
|
|
1084
|
+
"producer": {
|
|
1085
|
+
"schema": "skills.cli-producer-identity/v1",
|
|
1086
|
+
"configuredCommandPath": "<commandPath>",
|
|
1087
|
+
"physicalLauncher": { "path": "<absolute>", "sha256": "<64 hex>" },
|
|
1088
|
+
"runtimeEntry": { "path": "<absolute>", "sha256": "<64 hex>" },
|
|
1089
|
+
"runtime": { "path": "<absolute>", "sha256": "<64 hex>" },
|
|
1090
|
+
"package": { "name": "@hasna/skills", "version": "<x.y.z>", "manifestSha256": "<64 hex>" }
|
|
1091
|
+
},
|
|
1092
|
+
"operation": "<operation>",
|
|
1093
|
+
"result": {}
|
|
1094
|
+
}
|
|
1095
|
+
```
|
|
1096
|
+
|
|
1097
|
+
A refusal prints nothing on stdout, exits 1 and writes one line to stderr,
|
|
1098
|
+
`CODE: fixed text`, which never echoes request or file contents. The
|
|
1099
|
+
per-file operations (`settings`, `marketplace-registry`,
|
|
1100
|
+
`managed-plugin-registry`, `path-bytes`, `discovery-directories`,
|
|
1101
|
+
`plugin-manifest` and `candidate`) are described in
|
|
1102
|
+
[docs/plugin-admission.md](docs/plugin-admission.md#claude-installer-witness-cli).
|
|
1103
|
+
|
|
1104
|
+
#### Verify the stored Claude discovery binding (`discovery-binding`)
|
|
1105
|
+
|
|
1106
|
+
`discovery-binding` checks the Claude discovery binding stored in the Skills
|
|
1107
|
+
policy (`bridge.discovery.claude` in `agent-policy.json`) with the discovery
|
|
1108
|
+
verification the managed prompt hook runs on it: the root alias recheck,
|
|
1109
|
+
`verifyAgentDiscovery` and, for an automatic binding, the automatic closure
|
|
1110
|
+
check. It then reports every stored witness. An installer calls it once
|
|
1111
|
+
instead of re-capturing each stored witness. Per-file capture requires every
|
|
1112
|
+
file to exist, so it refuses witnesses that Skills keeps on purpose after
|
|
1113
|
+
Claude deletes a retired plugin-cache version; this operation reports those as
|
|
1114
|
+
`retained-absent`. It does not check the bridge files, hook commands or
|
|
1115
|
+
project-directory settings, which the hook checks separately.
|
|
1116
|
+
|
|
1117
|
+
The request has exactly these keys:
|
|
1118
|
+
|
|
1119
|
+
```json
|
|
1120
|
+
{
|
|
1121
|
+
"schema": "skills.claude-installer-capture/v1",
|
|
1122
|
+
"commandPath": "/home/me/.local/bin/skills",
|
|
1123
|
+
"operation": "discovery-binding",
|
|
1124
|
+
"policyPath": "/home/me/.hasna/skills/agent-policy.json"
|
|
1125
|
+
}
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
`policyPath` must equal `agent-policy.json` in the data directory the installed
|
|
1129
|
+
package resolves (`$HASNA_SKILLS_DIR`, default `~/.hasna/skills`), as for the
|
|
1130
|
+
`candidate` operation.
|
|
1131
|
+
|
|
1132
|
+
The receipt's `result`:
|
|
1133
|
+
|
|
1134
|
+
```json
|
|
1135
|
+
{
|
|
1136
|
+
"schema": "skills.claude-discovery-binding-verification/v1",
|
|
1137
|
+
"ok": true,
|
|
1138
|
+
"policySha256": "<64 hex>",
|
|
1139
|
+
"discoverySha256": "<64 hex>",
|
|
1140
|
+
"agent": "claude",
|
|
1141
|
+
"method": "reviewed",
|
|
1142
|
+
"rootCount": 2,
|
|
1143
|
+
"sources": [
|
|
1144
|
+
{ "index": 0, "path": "/home/me/.claude/settings.json", "hashMode": "claude-settings-v4", "format": null, "sha256": "<64 hex>", "status": "current" },
|
|
1145
|
+
{ "index": 3, "path": "/home/me/.claude/plugins/cache/market/plugin/1.0.0/.claude-plugin/plugin.json", "hashMode": "claude-plugin-manifest-v1", "format": null, "sha256": "<64 hex>",
|
|
1146
|
+
"status": "retained-absent", "retention": { "rule": "absent-retired-claude-version", "root": "/home/me/.claude/plugins/cache/market/plugin/1.0.0", "witness": "claude-plugin-manifest-v1" } }
|
|
1147
|
+
],
|
|
1148
|
+
"directories": [ { "index": 0, "path": "/home/me/.claude/plugins/cache/market/plugin/2.0.0", "status": "current" } ],
|
|
1149
|
+
"failures": []
|
|
1150
|
+
}
|
|
1151
|
+
```
|
|
1152
|
+
|
|
1153
|
+
- `policySha256` is the SHA-256 of the exact policy file bytes that were
|
|
1154
|
+
verified. It is the value a prospective review request passes as
|
|
1155
|
+
`skills.policySha256`. The policy is read again before the result is
|
|
1156
|
+
returned; if it changed, the request is refused.
|
|
1157
|
+
- `discoverySha256` is `hashClaudeDiscoveryBinding` of the stored binding, the
|
|
1158
|
+
same digest the `candidate` operation returns.
|
|
1159
|
+
- `agent`, `method` (`reviewed` or `automatic`) and `rootCount` (the number of
|
|
1160
|
+
stored discovery roots) come from the stored binding.
|
|
1161
|
+
- `sources` has one row per stored source, in stored order. `index` is the
|
|
1162
|
+
position in `bridge.discovery.claude.sources`. `path`, `hashMode`, `format`
|
|
1163
|
+
and `sha256` repeat the stored values: `hashMode` is `null` for a legacy
|
|
1164
|
+
full-file witness without a mode, `format` is `null` unless the source is a
|
|
1165
|
+
field projection (Claude reviews also keep the automatic `json` projection of
|
|
1166
|
+
`settings.json`), and a `null` `sha256` pins absence. `status` is one of:
|
|
1167
|
+
- `current`: the source's own witness reproduces the stored digest now.
|
|
1168
|
+
- `retained-absent`: the file was not read, because the
|
|
1169
|
+
`absent-retired-claude-version` rule keeps its stored digest. The rule
|
|
1170
|
+
holds when the whole version directory `retention.root`
|
|
1171
|
+
(`<...>/.claude/plugins/cache/<marketplace>/<plugin>/<version>`) is absent,
|
|
1172
|
+
the reviewed witnesses of `settings.json` and
|
|
1173
|
+
`plugins/installed_plugins.json` are current, settings enable the plugin
|
|
1174
|
+
and no settings hook names that directory, every registration of the
|
|
1175
|
+
plugin is a valid user or project row for one existing sibling version in
|
|
1176
|
+
the same plugin directory (with a user row among them), no registration of
|
|
1177
|
+
any plugin points into or contains the absent directory, and the sibling's
|
|
1178
|
+
`.claude-plugin/plugin.json` is bound and current. It applies only to
|
|
1179
|
+
reviewed bindings. `retention.witness` names the retained witness class:
|
|
1180
|
+
`bytes` (a full byte witness, `hashMode` `null` or `bytes`),
|
|
1181
|
+
`claude-plugin-manifest-v1` or `claude-plugin-orphaned-at-v1` (the typed
|
|
1182
|
+
presence witness of a version-root `.orphaned_at` marker). No other
|
|
1183
|
+
witness is retained: `path-bytes`, field projections and typed settings
|
|
1184
|
+
or registry witnesses stay checked. Settings and registry files are
|
|
1185
|
+
never retained.
|
|
1186
|
+
- `drift`, with `reason`: `MISSING` (the path is absent and the rule does
|
|
1187
|
+
not retain it), `APPEARED` (the stored witness pins absence and the path
|
|
1188
|
+
now exists), `CHANGED` (the path exists but its witness does not
|
|
1189
|
+
reproduce the stored digest or refuses the current file, for example
|
|
1190
|
+
edited settings or a symlink), `MARKER_INVALID` (a
|
|
1191
|
+
`claude-plugin-orphaned-at-v1` marker exists but is not a valid Claude
|
|
1192
|
+
marker; see below) or `REFUSED` (the path's presence could not be
|
|
1193
|
+
determined).
|
|
1194
|
+
- `directories` has one row per stored directory membership witness, with
|
|
1195
|
+
`status` `current`, or `drift` with `reason` `MEMBERSHIP_CHANGED` or
|
|
1196
|
+
`REFUSED`.
|
|
1197
|
+
- `failures` lists every drifted source and directory as
|
|
1198
|
+
`{ "kind": "source" | "directory", "index", "path", "reason" }`, followed by
|
|
1199
|
+
`{ "kind": "binding", "reason": "DISCOVERY_REFUSED" }` whenever the hook's
|
|
1200
|
+
own discovery verification refuses the binding. That covers checks no single
|
|
1201
|
+
row shows, such as a changed root alias, a retired directory that reappeared
|
|
1202
|
+
during verification or an invalid witness combination.
|
|
1203
|
+
- `ok` is `true` only when `failures` is empty: the hook's verification
|
|
1204
|
+
accepts the binding, every source is `current` or `retained-absent` and
|
|
1205
|
+
every directory is `current`.
|
|
1206
|
+
|
|
1207
|
+
`ok: false` is a completed verification and still exits 0, so the caller
|
|
1208
|
+
reads which witnesses drifted and why. Installers must require `ok === true`.
|
|
1209
|
+
To bind the result, compare each `sources` row (`index`, `path`, `hashMode`,
|
|
1210
|
+
`format`, `sha256`) with the binding they read themselves, compare
|
|
1211
|
+
`discoverySha256` with the `candidate` capture and `policySha256` with the
|
|
1212
|
+
policy bytes they review, and repeat the call immediately before the first
|
|
1213
|
+
native change, because the verdict describes one moment.
|
|
1214
|
+
|
|
1215
|
+
Claude writes `.orphaned_at` at the root of a plugin-cache version it plans to
|
|
1216
|
+
delete (`<...>/.claude/plugins/cache/<marketplace>/<plugin>/<version>/.orphaned_at`),
|
|
1217
|
+
rewrites its timestamp at each start, may replace the file, and later deletes
|
|
1218
|
+
the marker or the whole version. A fresh Skills discovery review binds such a
|
|
1219
|
+
marker as `claude-plugin-orphaned-at-v1`, a witness of its presence only, and
|
|
1220
|
+
`discovery-binding` reports it with that witness's own check, exactly as the
|
|
1221
|
+
hook does:
|
|
1222
|
+
|
|
1223
|
+
- A rewritten timestamp or a replaced file (new inode) is `current`, provided
|
|
1224
|
+
the marker is a regular, non-symlink file owned by the current user whose
|
|
1225
|
+
content is exactly 13 ASCII digits without a leading zero (no byte-order
|
|
1226
|
+
mark, no newline).
|
|
1227
|
+
- Any other content, a symlink or another owner is `drift` with
|
|
1228
|
+
`MARKER_INVALID`.
|
|
1229
|
+
- A deleted marker whose version directory still exists is `drift` with
|
|
1230
|
+
`MISSING`; the hook refuses this state too.
|
|
1231
|
+
- When Claude deletes the whole version directory and the registered sibling
|
|
1232
|
+
version stays bound and current, the marker and every other retainable
|
|
1233
|
+
witness below that directory are `retained-absent` under
|
|
1234
|
+
`absent-retired-claude-version`.
|
|
1235
|
+
- A recreated version directory is no longer absent, so each of its witnesses
|
|
1236
|
+
is checked again: a valid marker and an unchanged manifest are `current`,
|
|
1237
|
+
and a missing marker is `drift` with `MISSING`.
|
|
1238
|
+
- Marker witnesses stored by an older review as `bytes` or `path-bytes` keep
|
|
1239
|
+
their exact meaning and report `CHANGED` once Claude rewrites the marker,
|
|
1240
|
+
until a fresh discovery review rebinds them as typed witnesses.
|
|
1241
|
+
|
|
1242
|
+
Installers must not restore, copy back or rewrite `.orphaned_at` files, or any
|
|
1243
|
+
other witness file, to make a binding verify. A restored file has a new inode,
|
|
1244
|
+
which a `path-bytes` witness rejects, and it can hide a change Claude made. Act
|
|
1245
|
+
on the `discovery-binding` result instead. When it reports drift, the binding
|
|
1246
|
+
needs a fresh Skills discovery review (`skills hook install` with fresh
|
|
1247
|
+
`--discovery-inputs`), not a file repair.
|
|
1248
|
+
|
|
1249
|
+
Refusal codes for this operation, besides the shared request and producer
|
|
1250
|
+
codes (`INVALID_REQUEST_FILE`, `INVALID_REQUEST_JSON`, `INVALID_REQUEST`,
|
|
1251
|
+
`INVALID_SCHEMA`, `INVALID_REQUEST_FIELDS`, `INVALID_PATH`,
|
|
1252
|
+
`PRODUCER_UNVERIFIED`, `PRODUCER_CHANGED` and `CAPTURE_REJECTED`):
|
|
1253
|
+
|
|
1254
|
+
- `POLICY_PATH_MISMATCH`: `policyPath` is not the package-owned policy path.
|
|
1255
|
+
- `POLICY_UNAVAILABLE`: the policy file is absent.
|
|
1256
|
+
- `POLICY_UNREADABLE`: the policy is not a regular, bounded, valid managed
|
|
1257
|
+
policy file.
|
|
1258
|
+
- `BINDING_UNAVAILABLE`: the policy stores no Claude discovery binding.
|
|
1259
|
+
- `BINDING_INVALID`: the stored binding is not a Claude binding with a
|
|
1260
|
+
`reviewed` or `automatic` method, or its sources, directories or root
|
|
1261
|
+
aliases do not match the binding schema.
|
|
1262
|
+
- `POLICY_CHANGED`: the policy changed while it was being verified.
|
|
1263
|
+
- `DISCOVERY_BINDING_REJECTED`: any other failure.
|
|
1264
|
+
|
|
1265
|
+
The operation is read-only. It reads the policy and the stored witness paths
|
|
1266
|
+
and directories. It writes no file, cache, selection pin or policy, and it does
|
|
1267
|
+
not start Claude or change native state.
|
|
1268
|
+
|
|
1012
1269
|
## Profiles, station sync and rollback
|
|
1013
1270
|
|
|
1014
1271
|
```bash
|
|
@@ -2850,6 +3107,17 @@ Review the plan before adding `--apply`; the original review preimage must match
|
|
|
2850
3107
|
its original mode, and unrelated changes refuse. This preserves the native
|
|
2851
3108
|
configuration, root aliases, other witnesses and active session pins.
|
|
2852
3109
|
|
|
3110
|
+
Verifying a typed Codex settings witness from `codex-settings-v1` to
|
|
3111
|
+
`codex-settings-v5` also accepts the one write Codex 0.162.1 makes on its own
|
|
3112
|
+
first TUI or desktop launch: the boolean `tui.screen_reader_detection_done`
|
|
3113
|
+
receipt, added, removed or flipped (V6 already omits it). No digest changes
|
|
3114
|
+
meaning, and verification alone records or rebinds nothing. A non-boolean receipt, any other TUI key
|
|
3115
|
+
(including the `animations = false` Codex adds when it detects a screen
|
|
3116
|
+
reader) and every other change still drift, including Codex's
|
|
3117
|
+
`[projects."<dir>"]` trust entries. A planned Skills write to `config.toml`
|
|
3118
|
+
rebinds the witness to the written document, which adopts at most that
|
|
3119
|
+
receipt.
|
|
3120
|
+
|
|
2853
3121
|
`claude-settings-v4` is an explicit successor to `claude-settings-v3`. It
|
|
2854
3122
|
additionally ignores only a top-level `theme` whose value is exactly one of the
|
|
2855
3123
|
documented built-in values (`auto`, `dark`, `light`, `dark-daltonized`,
|