@sema-agent/settings-schema 3.0.1 → 5.0.0
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 +331 -0
- package/README.md +6 -2
- package/conformance/VERSION +1 -1
- package/dist/api/auth.d.ts +30 -6
- package/dist/api/auth.js +24 -2
- package/dist/config-fns.d.ts +72 -7
- package/dist/config-fns.js +76 -21
- package/dist/conformance/contract-adapter.js +37 -0
- package/dist/conformance/entry-origin.d.ts +24 -0
- package/dist/conformance/entry-origin.js +86 -0
- package/dist/conformance/run.js +6 -6
- package/dist/conformance/types.d.ts +5 -1
- package/dist/conformance/warnings.d.ts +7 -48
- package/dist/conformance/warnings.js +17 -40
- package/dist/cross-domain.d.ts +26 -6
- package/dist/cross-domain.js +30 -10
- package/dist/node.d.ts +1 -0
- package/dist/node.js +1 -0
- package/dist/prompts-digest.d.ts +16 -0
- package/dist/prompts-digest.js +48 -0
- package/dist/scheduler-store-node.d.ts +7 -19
- package/dist/scheduler-store-node.js +8 -26
- package/package.json +3 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** [1057]① prompts contentDigest:canonical JSON(stableStringify 同姿势:键序稳定+深度护栏)全量 sha256,
|
|
2
|
+
* **非盐化**(三方可独立复算)。入参=下发形的 `{sections, scenarioOverrides?}`(packId/contentDigest
|
|
3
|
+
* 自身不入 hash)。 */
|
|
4
|
+
export declare function promptsContentDigest(payload: {
|
|
5
|
+
sections: unknown;
|
|
6
|
+
scenarioOverrides?: unknown;
|
|
7
|
+
}): {
|
|
8
|
+
contentDigest: string;
|
|
9
|
+
packId: string;
|
|
10
|
+
/** [1062]③ 顺带:逐 section 对 `text` 铸的 contentHash(与 core 1.315 校验语义同刻度=
|
|
11
|
+
* sha256(text));元素无 string text 位=undefined。center 物化流程=先把这些写回
|
|
12
|
+
* declaration.contentHash,再对含 hash 的终形铸整包 digest(本函数对入参原样铸,两步自洽)。 */
|
|
13
|
+
sectionHashes: Array<string | undefined>;
|
|
14
|
+
};
|
|
15
|
+
/** 逐 section 对账锚(core 1.315 `PromptTextDeclaration.contentHash` 同刻度):sha256(text)。 */
|
|
16
|
+
export declare function sectionContentHash(text: string): string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sema-agent/settings-schema/node — prompts 下发包的**内容摘要**([1057]①/[1062]③)。
|
|
3
|
+
*
|
|
4
|
+
* 这两只是跨仓**对账锚**:center 铸、server 透传、core 的 manifest 归因**独立复算**,三方算出同一个值才
|
|
5
|
+
* 对得上账([1050]② operator 对账位)。所以它们只有一件事要守:**一个刻度**。
|
|
6
|
+
*
|
|
7
|
+
* 4.0.0 从 `scheduler-store-node.ts` 搬到这里(不 breaking —— 仍挂在 `./node` 这条 subpath 上,消费方的
|
|
8
|
+
* import 一个字不用改)。两条理由:①它与调度存储(`scheduled_tasks.json` 的原子读写 + 跨进程变更原语)
|
|
9
|
+
* 零关系,住在一起只是历史;②搬家顺手把**两个** sha256 铸点合成一只 —— 此前整包 digest 与逐 section
|
|
10
|
+
* contentHash 各自 `createHash('sha256')` 一次、各自拼一次 `sha256:` 前缀,哪天有人只改一处就成了两个刻度,
|
|
11
|
+
* 而没有一格会红(门:`test/prompts-digest-4.0.0.test.ts` 逐条看着铸点数与出门前缀数)。
|
|
12
|
+
*
|
|
13
|
+
* 摘要用本包**纯实现**的 sha256(`./sha256.ts`),不是 `node:crypto` —— 那份实现与
|
|
14
|
+
* `createHash("sha256").update(s,"utf8").digest("hex")` 逐字节相同(`test/sha256.test.ts` 逐例压着,
|
|
15
|
+
* 本模块的门再压一遍摘要值本身),于是整个包的 sha256 只有**一份实现**。
|
|
16
|
+
*/
|
|
17
|
+
import { stableStringify } from './hash.js';
|
|
18
|
+
import { sha256Hex } from './sha256.js';
|
|
19
|
+
/**
|
|
20
|
+
* 本模块**唯一**的 sha256 铸点:一段 utf8 文本 → `{ hex, anchor }`。`anchor` = 出门形 `sha256:<hex>`
|
|
21
|
+
* (自描述算法,与 skills 的内容地址同形),`hex` 给需要裸 hex 的那一处(packId 取前 12 位)。
|
|
22
|
+
* 两个出门形从**同一次**摘要派生 —— 这正是本模块存在的理由。
|
|
23
|
+
*/
|
|
24
|
+
function contentAnchor(text) {
|
|
25
|
+
const hex = sha256Hex(text);
|
|
26
|
+
return { hex, anchor: `sha256:${hex}` };
|
|
27
|
+
}
|
|
28
|
+
/** [1057]① prompts contentDigest:canonical JSON(stableStringify 同姿势:键序稳定+深度护栏)全量 sha256,
|
|
29
|
+
* **非盐化**(三方可独立复算)。入参=下发形的 `{sections, scenarioOverrides?}`(packId/contentDigest
|
|
30
|
+
* 自身不入 hash)。 */
|
|
31
|
+
export function promptsContentDigest(payload) {
|
|
32
|
+
const canonical = stableStringify({
|
|
33
|
+
sections: payload.sections,
|
|
34
|
+
...(payload.scenarioOverrides !== undefined ? { scenarioOverrides: payload.scenarioOverrides } : {}),
|
|
35
|
+
});
|
|
36
|
+
const { hex, anchor } = contentAnchor(canonical);
|
|
37
|
+
const sectionHashes = Array.isArray(payload.sections)
|
|
38
|
+
? payload.sections.map((s) => {
|
|
39
|
+
const t = s?.text;
|
|
40
|
+
return typeof t === 'string' ? sectionContentHash(t) : undefined;
|
|
41
|
+
})
|
|
42
|
+
: [];
|
|
43
|
+
return { contentDigest: anchor, packId: `center:${hex.slice(0, 12)}`, sectionHashes };
|
|
44
|
+
}
|
|
45
|
+
/** 逐 section 对账锚(core 1.315 `PromptTextDeclaration.contentHash` 同刻度):sha256(text)。 */
|
|
46
|
+
export function sectionContentHash(text) {
|
|
47
|
+
return contentAnchor(text).anchor;
|
|
48
|
+
}
|
|
@@ -13,8 +13,13 @@ export declare function loadSchedulerStore(path: string): SchedulerRecord[];
|
|
|
13
13
|
* concurrent reader never sees a partial file). Throws on IO failure (caller maps to a domain error).
|
|
14
14
|
*/
|
|
15
15
|
export declare function saveSchedulerStore(path: string, records: SchedulerRecord[]): void;
|
|
16
|
-
/** A filesystem-backed {@link SchedulerStore} bound to a path (convenience for the daemon/backend constructors).
|
|
17
|
-
|
|
16
|
+
/** A filesystem-backed {@link SchedulerStore} bound to a path (convenience for the daemon/backend constructors).
|
|
17
|
+
*
|
|
18
|
+
* 4.0.0 BREAKING 改名(S-571 B5,**零别名**):旧名 `fileSchedulerStore` 已删。它返回一只带 `load`/`save`
|
|
19
|
+
* 的**活对象** ⇒ 按本组工厂命名法(`build*` 出纯数据、`create*` 出活对象)该叫 `create*`;2.0.0 那次照人眼
|
|
20
|
+
* 改只改到了 `createSiblingResolver`,漏了这处 —— 现在由 `test/factory-naming-4.0.0.test.ts` 的门④ 机器看着。
|
|
21
|
+
* 消费方改调 `createFileSchedulerStore`(改名是硬 breaking:消费方的 tsc 红 / 运行期 undefined 就是通知本身)。 */
|
|
22
|
+
export declare function createFileSchedulerStore(path: string): SchedulerStore;
|
|
18
23
|
/** Outcome of {@link mutateSchedulerStore}. `conflict_exhausted` = a concurrent writer kept changing the file
|
|
19
24
|
* faster than the bounded replays; nothing was written on that final attempt (earlier attempts never wrote). */
|
|
20
25
|
export type SchedulerStoreMutation = {
|
|
@@ -53,20 +58,3 @@ export type SchedulerStoreMutation = {
|
|
|
53
58
|
export declare function mutateSchedulerStore(path: string, fn: (records: SchedulerRecord[]) => SchedulerRecord[] | null, opts?: {
|
|
54
59
|
retries?: number;
|
|
55
60
|
}): SchedulerStoreMutation;
|
|
56
|
-
/** [1057]① prompts contentDigest(node 绑定;browser-safe 纯层不带 crypto):
|
|
57
|
-
* canonical JSON(stableStringify 同姿势:键序稳定+深度护栏)全量 sha256,**非盐化**
|
|
58
|
-
* ([1050]② operator 对账位——center 产、server 透传、core manifest 归因三方可独立复算)。
|
|
59
|
-
* 入参=下发形的 {sections, scenarioOverrides?}(packId/contentDigest 自身不入 hash)。 */
|
|
60
|
-
export declare function promptsContentDigest(payload: {
|
|
61
|
-
sections: unknown;
|
|
62
|
-
scenarioOverrides?: unknown;
|
|
63
|
-
}): {
|
|
64
|
-
contentDigest: string;
|
|
65
|
-
packId: string;
|
|
66
|
-
/** [1062]③ 顺带:逐 section 对 `text` 铸的 contentHash(与 core 1.315 校验语义同刻度=
|
|
67
|
-
* sha256(text));元素无 string text 位=undefined。center 物化流程=先把这些写回
|
|
68
|
-
* declaration.contentHash,再对含 hash 的终形铸整包 digest(本函数对入参原样铸,两步自洽)。 */
|
|
69
|
-
sectionHashes: Array<string | undefined>;
|
|
70
|
-
};
|
|
71
|
-
/** 逐 section 对账锚(core 1.315 `PromptTextDeclaration.contentHash` 同刻度):sha256(text)。 */
|
|
72
|
-
export declare function sectionContentHash(text: string): string;
|
|
@@ -8,9 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { mkdirSync, readFileSync, writeFileSync, renameSync } from 'node:fs';
|
|
10
10
|
import { dirname } from 'node:path';
|
|
11
|
-
import { randomBytes
|
|
11
|
+
import { randomBytes } from 'node:crypto';
|
|
12
12
|
import { parseSchedulerStore, serializeSchedulerStore } from './scheduler-store.js';
|
|
13
|
-
import { stableStringify } from './hash.js';
|
|
14
13
|
/**
|
|
15
14
|
* Load the durable store. A MISSING file (ENOENT) ⇒ `[]` (fail-soft, first-run/never-written case); any OTHER
|
|
16
15
|
* read failure (EACCES/EIO/EISDIR/…) RETHROWS — only absence means "empty", not "unreadable for any reason"
|
|
@@ -39,8 +38,13 @@ export function saveSchedulerStore(path, records) {
|
|
|
39
38
|
writeFileSync(tmp, serializeSchedulerStore(records), { mode: 0o600 });
|
|
40
39
|
renameSync(tmp, path); // atomic over the target
|
|
41
40
|
}
|
|
42
|
-
/** A filesystem-backed {@link SchedulerStore} bound to a path (convenience for the daemon/backend constructors).
|
|
43
|
-
|
|
41
|
+
/** A filesystem-backed {@link SchedulerStore} bound to a path (convenience for the daemon/backend constructors).
|
|
42
|
+
*
|
|
43
|
+
* 4.0.0 BREAKING 改名(S-571 B5,**零别名**):旧名 `fileSchedulerStore` 已删。它返回一只带 `load`/`save`
|
|
44
|
+
* 的**活对象** ⇒ 按本组工厂命名法(`build*` 出纯数据、`create*` 出活对象)该叫 `create*`;2.0.0 那次照人眼
|
|
45
|
+
* 改只改到了 `createSiblingResolver`,漏了这处 —— 现在由 `test/factory-naming-4.0.0.test.ts` 的门④ 机器看着。
|
|
46
|
+
* 消费方改调 `createFileSchedulerStore`(改名是硬 breaking:消费方的 tsc 红 / 运行期 undefined 就是通知本身)。 */
|
|
47
|
+
export function createFileSchedulerStore(path) {
|
|
44
48
|
return {
|
|
45
49
|
load: () => loadSchedulerStore(path),
|
|
46
50
|
save: (records) => saveSchedulerStore(path, records),
|
|
@@ -95,25 +99,3 @@ export function mutateSchedulerStore(path, fn, opts) {
|
|
|
95
99
|
return { ok: true, records: next, retries: attempt };
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
|
-
/** [1057]① prompts contentDigest(node 绑定;browser-safe 纯层不带 crypto):
|
|
99
|
-
* canonical JSON(stableStringify 同姿势:键序稳定+深度护栏)全量 sha256,**非盐化**
|
|
100
|
-
* ([1050]② operator 对账位——center 产、server 透传、core manifest 归因三方可独立复算)。
|
|
101
|
-
* 入参=下发形的 {sections, scenarioOverrides?}(packId/contentDigest 自身不入 hash)。 */
|
|
102
|
-
export function promptsContentDigest(payload) {
|
|
103
|
-
const canonical = stableStringify({
|
|
104
|
-
sections: payload.sections,
|
|
105
|
-
...(payload.scenarioOverrides !== undefined ? { scenarioOverrides: payload.scenarioOverrides } : {}),
|
|
106
|
-
});
|
|
107
|
-
const hex = createHash('sha256').update(canonical, 'utf8').digest('hex');
|
|
108
|
-
const sectionHashes = Array.isArray(payload.sections)
|
|
109
|
-
? payload.sections.map((s) => {
|
|
110
|
-
const t = s?.text;
|
|
111
|
-
return typeof t === 'string' ? sectionContentHash(t) : undefined;
|
|
112
|
-
})
|
|
113
|
-
: [];
|
|
114
|
-
return { contentDigest: `sha256:${hex}`, packId: `center:${hex.slice(0, 12)}`, sectionHashes };
|
|
115
|
-
}
|
|
116
|
-
/** 逐 section 对账锚(core 1.315 `PromptTextDeclaration.contentHash` 同刻度):sha256(text)。 */
|
|
117
|
-
export function sectionContentHash(text) {
|
|
118
|
-
return `sha256:${createHash('sha256').update(text, 'utf8').digest('hex')}`;
|
|
119
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/settings-schema",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Sema settings schema — pure config contract (zod domains + effective-config + roster resolution + ref-integrity + remoteExec) shared by sema-registry, sema-server, and the TOC desktop/CLI. One source of truth. (Renamed at 1.0.0 from @sema-agent/registry-core — name and docs only, no behavior change; note the range moves 0.19.0 -> 1.0.0, so a dependency must become ^1.0.0. The old names @sema-agent/registry-core <=0.19.0 and @sema-ai/registry-core remain published, frozen, for migration.)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BUSL-1.1",
|
|
@@ -121,6 +121,8 @@
|
|
|
121
121
|
"test:watch": "vitest",
|
|
122
122
|
"e2e": "node examples/toc-e2e.mjs",
|
|
123
123
|
"drift:cc": "node scripts/extract-cc-hook-events.mjs",
|
|
124
|
+
"conformance:bless": "node scripts/gen-conformance.mjs",
|
|
125
|
+
"conformance:historical": "node scripts/conformance-historical.mjs",
|
|
124
126
|
"prepare": "npm run build",
|
|
125
127
|
"prepublishOnly": "npm run build && npm run test",
|
|
126
128
|
"publish:npm": "npm publish --access public --@sema-agent:registry=https://registry.npmjs.org/ --\"//registry.npmjs.org/:_authToken=${NPM_TOKEN}\""
|