@sema-agent/settings-schema 13.0.0 → 13.0.1
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/CHANGELOG.md +18 -0
- package/README.md +2 -1
- package/conformance/VERSION +1 -1
- package/dist/hooks-config.d.ts +9 -1
- package/dist/hooks-config.js +23 -15
- package/docs/API-SURFACE.md +1395 -0
- package/docs/CC-DIVERGENCE.md +42 -0
- package/docs/CONFORMANCE.md +344 -0
- package/docs/CONSUMER-INTEGRATION.md +282 -0
- package/docs/openapi-auth.yaml +357 -0
- package/docs/openapi-scopes.yaml +281 -0
- package/llms-full.txt +656 -0
- package/llms.txt +174 -0
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,24 @@
|
|
|
6
6
|
> `@sema-agent/registry-core`(更早还曾是 `@sema-ai/registry-core`)。本档 `0.19.0` 以下各节里的
|
|
7
7
|
> 包名是**历史记录**,如实保留不追改。
|
|
8
8
|
|
|
9
|
+
## 13.0.1 — 2026-10-16 — patch:`classifyHooksConfig` 对「未知字段里藏守卫迹象」的拒绝项补 `field`(点名藏迹象的那个键)· 随包文字引用的 `docs/` 与 `llms.txt` / `llms-full.txt` 进 tarball
|
|
10
|
+
|
|
11
|
+
- **行为修复(拒绝项 `field`)**。13.0.0 写了「条目 / 匹配器的坏块另带坏字段名 `field`」,而实码只对「契约字段值写错」一形给了 `field`;「本会被剥掉的未知字段里藏着守卫迹象 ⇒ 拒」这一形
|
|
12
|
+
(`guard-matcher-invalid` / `guard-entry-invalid`)的拒绝项没有。现在一条律,两形相同:坏块是对象(匹配器 / 条目)⇒ `field` = 它上面出问题的那个键 —— 契约字段值错的那个字段,
|
|
13
|
+
或装着迹象的那个成员(契约不认识的未知字段;装得下比字段类型更多东西的契约字段,如 http 条目的 `headers`;条目自己就是匹配器形时取 `hooks`);只有块本身不是对象才缺席。
|
|
14
|
+
一块一条拒绝项、一个 `field`:迹象按文档序取第一个;同一块上迹象先于契约字段错判(它是「拒」而不是「剔」的缘由)。
|
|
15
|
+
结局、码、坐标、剔点、装上的那一份逐字节不变(30 万份文档新旧对拍,判断面零差);变的只有这一形的拒绝项多一个 `field`,以及 zod 面对应 issue 的 `path` 多最后一段
|
|
16
|
+
(坐标 + `field`,与契约字段写错的 issue 同形)。型面不变(`HooksRejection.field` 本就是 `field?: string`);`HooksDroppedPiece` / 剔点读数不动。
|
|
17
|
+
三问 —— **谁需要**:拿 `field` 告诉用户「改哪一个键」的消费方:藏迹象这一形此前只能指到匹配器 / 条目那一整块,用户要自己在块里找;**谁受伤**:断言「该形拒绝项没有 `field`」的消费方测试,
|
|
18
|
+
或把 zod issue `path` 当定长坐标读的点,会多一段;**补偿**:`field` 缺席现在只有一种意思(块不是对象),读 `field` 前不必再区分是哪一形。
|
|
19
|
+
钉:`test/hooks-classify-13.0.0.test.ts` ⑥(七形 + 两加试各自点名藏迹象的键 · 同族几形 · 多键取先出现的 · 文档序 · 正控 / 负控 · zod 面 issue path)。
|
|
20
|
+
- **随包文件补齐(`package.json` `files`)**。README / CHANGELOG / 源码注释(随 `dist/*.d.ts` 出包)里写着「见 `docs/…`」「见 `llms.txt`」的档此前不在 tarball 里,装了包的人顺着指路点不到。
|
|
21
|
+
`files` 加 `docs`(`API-SURFACE` · `CC-DIVERGENCE` · `CONFORMANCE` · `CONSUMER-INTEGRATION` · `openapi-auth` · `openapi-scopes` 六份)、`llms.txt`、`llms-full.txt`;
|
|
22
|
+
tarball 文件数 437 → 445,包体积约 +88 kB(851 kB → 938 kB)。
|
|
23
|
+
三问 —— **谁需要**:读包内文字、顺着指路找契约档的人和 AI;**谁受伤**:无(只多文件,导出面与运行期零变化,下载多约 88 kB);**补偿**:无需。
|
|
24
|
+
钉:`test/package-surface.test.ts`「随包文字引用的仓内文件都随包」—— 扫 README / CHANGELOG / `bin` / 源码注释里指到的、本仓真有的 `docs/…` 与 `llms` 档,逐个核落在 `files` 覆盖的路径里(今天恰 8 个);
|
|
25
|
+
门有牙一格(去掉三项后同一扫描点名它们)。
|
|
26
|
+
|
|
9
27
|
## 13.0.0 — 2026-10-16 — major:hooks 坏形一只读者 `classifyHooksConfig` · 设置源表 + 层准入 `layerAdmission`(层档只有源表一个读者)· URL 名单判官两出口 · 新类目 `httpHookAllowlists` + http hook 两张名单跨层取交 · MCP 名单判决 `mcpServerPolicyVerdict` · 界面语言设置片段 · 模型能力位三态(major)
|
|
10
28
|
|
|
11
29
|
> 档位:**major**。按「发版纪律」三处是破坏性(B1 `HooksConfig` 族受理面收紧且读数变 · B2 八只 hooks zod 面改形 · B3 `ModelEntry.reasoning` / `vision`
|
package/README.md
CHANGED
|
@@ -431,7 +431,8 @@ therefore shows only `zod`. Node built-ins only (`node:crypto`, `node:fs`).
|
|
|
431
431
|
the config surface (defined in `hooks-config.ts`, re-exported by `./hooks`): `HOOK_ENTRY_TYPES` (CC 2.1.296's five: command / prompt / agent / http /
|
|
432
432
|
`mcp_tool`) and the ONE classifier `classifyHooksConfig(settingsDoc)` — which pieces of a settings document's `hooks` drop
|
|
433
433
|
(`HOOKS_DROPPED_PIECE_CODES`), whether the whole document is rejected because a guard (`PreToolUse` / `PermissionRequest`) may be
|
|
434
|
-
in a bad piece (`HOOKS_REJECTION_CODES`), and what loads; codes + `ConfigPath` coordinates
|
|
434
|
+
in a bad piece (`HOOKS_REJECTION_CODES`), and what loads; codes + `ConfigPath` coordinates + the wrong key's name (`field`: for a matcher / entry, the contract
|
|
435
|
+
field whose value is wrong, or the member that holds a guard sign; absent only when the piece is not an object), no sentences, self-contained (no zod;
|
|
435
436
|
its one free name besides JS built-ins is `HOOK_EVENTS` — a generator that copies the function must inject this package's runtime
|
|
436
437
|
`HOOK_EVENTS` into the copy, never paste a literal event list).
|
|
437
438
|
`HooksConfig` / `HookMatcherEntry` / `HookEntry` (the `settings.json` `hooks` shape — event names a CLOSED set) are its zod
|
package/conformance/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
13.0.
|
|
1
|
+
13.0.1
|
package/dist/hooks-config.d.ts
CHANGED
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
* that merely spells `PreToolUse` is not a sign. A piece holding a sign is never dropped — dropping it could make a misplaced guard vanish —
|
|
21
21
|
* the document is rejected instead, wherever the sign sits: outside `hooks`, under an unknown event, in a non-array event value, in a matcher's
|
|
22
22
|
* or an entry's fields (including fields the contract does not know and would otherwise not carry).
|
|
23
|
+
* · `field` — ONE LAW for drops and rejections alike: when the bad piece is a matcher or an entry (an object), `field` is the KEY on it that makes it
|
|
24
|
+
* bad — a contract field whose value is wrong, or, for a piece rejected because it holds a guard sign, the member that holds the sign (an unknown
|
|
25
|
+
* field the contract would strip; a contract field carrying more than its kind, such as `headers` or `input`; `hooks` for an entry that is itself
|
|
26
|
+
* matcher-shaped). Absent only when the piece is not an object — and for the pieces above matchers, which have no fields to name. One piece, one
|
|
27
|
+
* `field`: the first wrong contract field, or the first sign in document order; a sign on the piece itself decides before a wrong contract field
|
|
28
|
+
* of the same piece does (it is why the piece is rejected rather than dropped).
|
|
23
29
|
*
|
|
24
30
|
* CC 2.1.296 DIVERGENCES (each in the stricter direction — a document CC would load may be rejected here, never the reverse): listed once,
|
|
25
31
|
* in `docs/CC-DIVERGENCE.md` (section "hooks classifier", H1–H7) — the whole-subtree guard-sign scan is the first of them.
|
|
@@ -173,7 +179,9 @@ export interface HooksDroppedPiece {
|
|
|
173
179
|
readonly path: ConfigPath;
|
|
174
180
|
readonly field?: string;
|
|
175
181
|
}
|
|
176
|
-
/** One reason the document was rejected: `path` = the offending piece (for `guard-outside-hooks`: the guard sign itself); `field`
|
|
182
|
+
/** One reason the document was rejected: `path` = the offending piece (for `guard-outside-hooks`: the guard sign itself); `field` = for a matcher / entry,
|
|
183
|
+
* the key on it that makes it bad — the contract field whose value is wrong, or the member that holds a guard sign (see the file header's `field` law);
|
|
184
|
+
* absent when the piece is not an object, and for the codes above matchers. */
|
|
177
185
|
export interface HooksRejection {
|
|
178
186
|
readonly code: HooksRejectionCode;
|
|
179
187
|
readonly path: ConfigPath;
|
package/dist/hooks-config.js
CHANGED
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
* that merely spells `PreToolUse` is not a sign. A piece holding a sign is never dropped — dropping it could make a misplaced guard vanish —
|
|
21
21
|
* the document is rejected instead, wherever the sign sits: outside `hooks`, under an unknown event, in a non-array event value, in a matcher's
|
|
22
22
|
* or an entry's fields (including fields the contract does not know and would otherwise not carry).
|
|
23
|
+
* · `field` — ONE LAW for drops and rejections alike: when the bad piece is a matcher or an entry (an object), `field` is the KEY on it that makes it
|
|
24
|
+
* bad — a contract field whose value is wrong, or, for a piece rejected because it holds a guard sign, the member that holds the sign (an unknown
|
|
25
|
+
* field the contract would strip; a contract field carrying more than its kind, such as `headers` or `input`; `hooks` for an entry that is itself
|
|
26
|
+
* matcher-shaped). Absent only when the piece is not an object — and for the pieces above matchers, which have no fields to name. One piece, one
|
|
27
|
+
* `field`: the first wrong contract field, or the first sign in document order; a sign on the piece itself decides before a wrong contract field
|
|
28
|
+
* of the same piece does (it is why the piece is rejected rather than dropped).
|
|
23
29
|
*
|
|
24
30
|
* CC 2.1.296 DIVERGENCES (each in the stricter direction — a document CC would load may be rejected here, never the reverse): listed once,
|
|
25
31
|
* in `docs/CC-DIVERGENCE.md` (section "hooks classifier", H1–H7) — the whole-subtree guard-sign scan is the first of them.
|
|
@@ -214,6 +220,12 @@ function hookGuardSignIn(root, rootPath, place) {
|
|
|
214
220
|
}
|
|
215
221
|
return undefined;
|
|
216
222
|
}
|
|
223
|
+
/** The key of the object piece at `at` that holds `sign` (a coordinate at or below `at`, as {@link hookGuardSignIn} reports it): the first segment
|
|
224
|
+
* below `at`; `hooks` when the sign IS the piece itself (a matcher-shaped object — its `hooks` member is what makes it one). */
|
|
225
|
+
function hookSignKeyOf(at, sign) {
|
|
226
|
+
const key = sign[at.length];
|
|
227
|
+
return key === undefined ? "hooks" : String(key);
|
|
228
|
+
}
|
|
217
229
|
/** Does `value` fit the field kind `base` (the kind without its `?`)? */
|
|
218
230
|
function hookFieldFits(base, value) {
|
|
219
231
|
switch (base) {
|
|
@@ -279,27 +291,22 @@ function hookMatcherRead(matcher, at, guardEvent, reject, drop) {
|
|
|
279
291
|
return undefined;
|
|
280
292
|
}
|
|
281
293
|
const entries = Object.hasOwn(matcher, "hooks") ? matcher.hooks : undefined;
|
|
282
|
-
// a sign at the matcher level: a guard-event key on the matcher itself, or anywhere in its fields other than a well-formed entry list
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
continue;
|
|
289
|
-
matcherSign = hookGuardSignIn(matcher[key], [...at, key], "other") !== undefined;
|
|
290
|
-
}
|
|
291
|
-
if (matcherSign) {
|
|
292
|
-
reject("guard-matcher-invalid", at);
|
|
294
|
+
// a sign at the matcher level: a guard-event key on the matcher itself, or anywhere in its fields other than a well-formed entry list;
|
|
295
|
+
// the member that holds the first one (document order — the order hookGuardSignIn reports) is the rejection's `field`
|
|
296
|
+
const signField = hookGuardKeyOf(matcher) ??
|
|
297
|
+
Object.keys(matcher).find((key) => !(key === "hooks" && Array.isArray(entries)) && hookGuardSignIn(matcher[key], [...at, key], "other") !== undefined);
|
|
298
|
+
if (signField !== undefined) {
|
|
299
|
+
reject("guard-matcher-invalid", at, signField);
|
|
293
300
|
return undefined;
|
|
294
301
|
}
|
|
295
302
|
const entrySigns = [];
|
|
296
303
|
if (Array.isArray(entries))
|
|
297
304
|
for (let j = 0; j < entries.length; j++)
|
|
298
|
-
entrySigns.push(hookGuardSignIn(entries[j], [...at, "hooks", j], "other")
|
|
305
|
+
entrySigns.push(hookGuardSignIn(entries[j], [...at, "hooks", j], "other"));
|
|
299
306
|
const name = Object.hasOwn(matcher, "matcher") ? matcher.matcher : undefined;
|
|
300
307
|
const badField = name !== undefined && typeof name !== "string" ? "matcher" : !Array.isArray(entries) ? "hooks" : undefined;
|
|
301
308
|
if (badField !== undefined || !Array.isArray(entries)) {
|
|
302
|
-
if (guardEvent || entrySigns.
|
|
309
|
+
if (guardEvent || entrySigns.some((sign) => sign !== undefined))
|
|
303
310
|
reject("guard-matcher-invalid", at, badField);
|
|
304
311
|
else
|
|
305
312
|
drop("matcher-invalid", at, badField);
|
|
@@ -308,8 +315,9 @@ function hookMatcherRead(matcher, at, guardEvent, reject, drop) {
|
|
|
308
315
|
const kept = [];
|
|
309
316
|
for (let j = 0; j < entries.length; j++) {
|
|
310
317
|
const where = [...at, "hooks", j];
|
|
311
|
-
|
|
312
|
-
|
|
318
|
+
const sign = entrySigns[j];
|
|
319
|
+
if (sign !== undefined) {
|
|
320
|
+
reject("guard-entry-invalid", where, hookIsRecord(entries[j]) ? hookSignKeyOf(where, sign) : undefined);
|
|
313
321
|
continue;
|
|
314
322
|
}
|
|
315
323
|
const read = hookEntryRead(entries[j]);
|