@dsh-cc/settings-cascade 0.5.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/LICENSE +201 -0
- package/README.i18n.yaml +6 -0
- package/README.md +57 -0
- package/README.zh.md +56 -0
- package/lib/auto-mode.d.ts +47 -0
- package/lib/auto-mode.d.ts.map +1 -0
- package/lib/auto-mode.js +46 -0
- package/lib/auto-mode.js.map +1 -0
- package/lib/cc-key-aliases.d.ts +22 -0
- package/lib/cc-key-aliases.d.ts.map +1 -0
- package/lib/cc-key-aliases.js +43 -0
- package/lib/cc-key-aliases.js.map +1 -0
- package/lib/env.d.ts +38 -0
- package/lib/env.d.ts.map +1 -0
- package/lib/env.js +69 -0
- package/lib/env.js.map +1 -0
- package/lib/index.d.ts +190 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +414 -0
- package/lib/index.js.map +1 -0
- package/lib/invariant.d.ts +16 -0
- package/lib/invariant.d.ts.map +1 -0
- package/lib/invariant.js +23 -0
- package/lib/invariant.js.map +1 -0
- package/lib/local-root.d.ts +59 -0
- package/lib/local-root.d.ts.map +1 -0
- package/lib/local-root.js +140 -0
- package/lib/local-root.js.map +1 -0
- package/lib/merge.d.ts +53 -0
- package/lib/merge.d.ts.map +1 -0
- package/lib/merge.js +126 -0
- package/lib/merge.js.map +1 -0
- package/lib/permissions.d.ts +37 -0
- package/lib/permissions.d.ts.map +1 -0
- package/lib/permissions.js +26 -0
- package/lib/permissions.js.map +1 -0
- package/lib/persist.d.ts +64 -0
- package/lib/persist.d.ts.map +1 -0
- package/lib/persist.js +183 -0
- package/lib/persist.js.map +1 -0
- package/package.json +55 -0
package/lib/persist.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Surgical-delta persistence for the settings cascade. When a write reaches
|
|
3
|
+
* the provider it carries the full merged section for one namespace; writing
|
|
4
|
+
* that whole section into the user settings file would smear higher-layer
|
|
5
|
+
* (project/local/flag/policy) contributions into the user layer. Instead the
|
|
6
|
+
* section is diffed against the last-published shadow and only the leaf-level
|
|
7
|
+
* change ops are applied onto the user file's own section. File writes are
|
|
8
|
+
* atomic (temp + rename) so a crash never leaves a half-written document.
|
|
9
|
+
* @module @dsh-cc/settings-cascade/persist
|
|
10
|
+
*/
|
|
11
|
+
import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
12
|
+
import { randomBytes } from 'node:crypto';
|
|
13
|
+
import { dirname } from 'node:path';
|
|
14
|
+
/** Whether a value is a plain data object (not an array, null, or instance). */
|
|
15
|
+
function isPlainObject(value) {
|
|
16
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
17
|
+
return false;
|
|
18
|
+
const proto = Object.getPrototypeOf(value);
|
|
19
|
+
return proto === Object.prototype || proto === null;
|
|
20
|
+
}
|
|
21
|
+
/** Deep value equality, stable across JSON-shaped leaves (objects recurse). */
|
|
22
|
+
function deepEqual(a, b) {
|
|
23
|
+
if (Object.is(a, b))
|
|
24
|
+
return true;
|
|
25
|
+
if (isPlainObject(a) && isPlainObject(b)) {
|
|
26
|
+
const aKeys = Object.keys(a);
|
|
27
|
+
const bKeys = Object.keys(b);
|
|
28
|
+
if (aKeys.length !== bKeys.length)
|
|
29
|
+
return false;
|
|
30
|
+
return aKeys.every(key => Object.prototype.hasOwnProperty.call(b, key) && deepEqual(a[key], b[key]));
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Diff two JSON sections into leaf-level ops. Leaves equal by deep value
|
|
36
|
+
* equality produce no op; changed or added leaves produce `set`; keys present
|
|
37
|
+
* in `prev` but absent in `next` produce `unset`. Arrays compare as whole
|
|
38
|
+
* leaves. When both sides are plain objects the diff recurses; when one side
|
|
39
|
+
* is not a plain object while the other is, the node is replaced wholesale.
|
|
40
|
+
* Neither input is mutated.
|
|
41
|
+
* @param prev - the earlier section (the shadow of what was published before).
|
|
42
|
+
* @param next - the desired section (the merged write target).
|
|
43
|
+
* @param path - the JSON path accumulated so far; defaults to the root `[]`.
|
|
44
|
+
* @returns the ordered ops that transform `prev` into `next`.
|
|
45
|
+
*/
|
|
46
|
+
export function diffSections(prev, next, path = []) {
|
|
47
|
+
if (isPlainObject(prev) && isPlainObject(next)) {
|
|
48
|
+
const ops = [];
|
|
49
|
+
for (const [key, value] of Object.entries(next)) {
|
|
50
|
+
if (Object.prototype.hasOwnProperty.call(prev, key)) {
|
|
51
|
+
ops.push(...diffSections(prev[key], value, [...path, key]));
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
ops.push({ op: 'set', path: [...path, key], value });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
for (const key of Object.keys(prev)) {
|
|
58
|
+
if (!Object.prototype.hasOwnProperty.call(next, key)) {
|
|
59
|
+
ops.push({ op: 'unset', path: [...path, key] });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return ops;
|
|
63
|
+
}
|
|
64
|
+
if (deepEqual(prev, next))
|
|
65
|
+
return [];
|
|
66
|
+
return [{ op: 'set', path, value: next }];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Apply a list of ops onto a detached JSON section, returning the next
|
|
70
|
+
* section. Mirrors the seam's `applyPathOp`: a nested `set` that meets a
|
|
71
|
+
* non-plain-object intermediate node replaces that node wholesale with an
|
|
72
|
+
* object built around the remaining path; `unset` on a missing key is a
|
|
73
|
+
* no-op; a `set` with an empty path requires a plain object and replaces the
|
|
74
|
+
* whole section; an `unset` with an empty path yields `{}`. The input is not
|
|
75
|
+
* mutated.
|
|
76
|
+
* @param section - the current section (`undefined` when the namespace is absent).
|
|
77
|
+
* @param ops - the ops to apply in order.
|
|
78
|
+
* @returns the resulting section.
|
|
79
|
+
*/
|
|
80
|
+
export function applyOpsToSection(section, ops) {
|
|
81
|
+
let out = section;
|
|
82
|
+
for (const op of ops) {
|
|
83
|
+
out = applyPathOp(out, op);
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
/** Apply one path op to a detached section, returning the next section. */
|
|
88
|
+
function applyPathOp(section, op) {
|
|
89
|
+
const [head, ...rest] = op.path;
|
|
90
|
+
if (head === undefined) {
|
|
91
|
+
if (op.op === 'unset')
|
|
92
|
+
return {};
|
|
93
|
+
if (!isPlainObject(op.value))
|
|
94
|
+
throw new TypeError('settings-cascade: setting the section root requires a plain object');
|
|
95
|
+
return { ...op.value };
|
|
96
|
+
}
|
|
97
|
+
if (rest.length === 0) {
|
|
98
|
+
const base = isPlainObject(section) ? section : {};
|
|
99
|
+
if (op.op === 'set')
|
|
100
|
+
return { ...base, [head]: op.value };
|
|
101
|
+
if (!isPlainObject(section))
|
|
102
|
+
return section;
|
|
103
|
+
const { [head]: _removed, ...kept } = section;
|
|
104
|
+
return kept;
|
|
105
|
+
}
|
|
106
|
+
const child = isPlainObject(section) ? section[head] : undefined;
|
|
107
|
+
if (!isPlainObject(child)) {
|
|
108
|
+
if (op.op === 'unset')
|
|
109
|
+
return section;
|
|
110
|
+
return {
|
|
111
|
+
...(isPlainObject(section) ? section : {}),
|
|
112
|
+
[head]: applyPathOp({}, restOp(op, rest)),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const base = isPlainObject(section) ? section : {};
|
|
116
|
+
return {
|
|
117
|
+
...base,
|
|
118
|
+
[head]: applyPathOp(child, restOp(op, rest)),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** Rebuild an op focused on the remaining path of a nested traversal. */
|
|
122
|
+
function restOp(op, path) {
|
|
123
|
+
if (op.op === 'set')
|
|
124
|
+
return { op: 'set', path, value: op.value };
|
|
125
|
+
return { op: 'unset', path };
|
|
126
|
+
}
|
|
127
|
+
/** Whether a filesystem error simply means the file is absent. */
|
|
128
|
+
function isENOENT(error) {
|
|
129
|
+
return error?.code === 'ENOENT';
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Read one settings document into a plain object. Absence and whitespace-only
|
|
133
|
+
* content read as `{}`; invalid JSON or a non-object root fail loud with the
|
|
134
|
+
* path, mirroring the cascade provider's load-time parse.
|
|
135
|
+
* @param path - the absolute settings file path.
|
|
136
|
+
* @returns the parsed root document, or `{}` when the file is absent or blank.
|
|
137
|
+
*/
|
|
138
|
+
export async function readUserFile(path) {
|
|
139
|
+
let text;
|
|
140
|
+
try {
|
|
141
|
+
text = await readFile(path, 'utf8');
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (isENOENT(error))
|
|
145
|
+
return {};
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
if (text.trim().length === 0)
|
|
149
|
+
return {};
|
|
150
|
+
let root;
|
|
151
|
+
try {
|
|
152
|
+
root = JSON.parse(text);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throw new Error(`settings-cascade: invalid settings document at ${path}: ${error.message}`, { cause: error });
|
|
156
|
+
}
|
|
157
|
+
if (!isPlainObject(root)) {
|
|
158
|
+
throw new TypeError(`settings-cascade: ${path} must be a JSON object of namespace sections`);
|
|
159
|
+
}
|
|
160
|
+
return root;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Write a JSON root document atomically. The parent directory is created with
|
|
164
|
+
* mode `0o700`, the document is written to a random temp sibling under mode
|
|
165
|
+
* `0o600`, then renamed over the target. On any failure after the temp file is
|
|
166
|
+
* created it is best-effort removed before the error rethrows. The temp name
|
|
167
|
+
* is random (rather than fixed) so concurrent writers never collide on it.
|
|
168
|
+
* @param path - the absolute target settings file path.
|
|
169
|
+
* @param root - the plain-object document to serialize.
|
|
170
|
+
*/
|
|
171
|
+
export async function writeJsonAtomic(path, root) {
|
|
172
|
+
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
173
|
+
const tmp = `${path}.${randomBytes(6).toString('hex')}.tmp`;
|
|
174
|
+
try {
|
|
175
|
+
await writeFile(tmp, JSON.stringify(root, null, 2) + '\n', { flag: 'wx', mode: 0o600 });
|
|
176
|
+
await rename(tmp, path);
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
await rm(tmp, { force: true }).catch(() => undefined);
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=persist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persist.js","sourceRoot":"","sources":["../src/persist.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dsh-cc/settings-cascade",
|
|
3
|
+
"description": "Claude Code-style five-level settings cascade provider (ctx.settings) for the DeepSeek Harness",
|
|
4
|
+
"version": "0.5.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/dsh-cc/dsh-cc.git",
|
|
8
|
+
"directory": "packages/settings/settings-cascade"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./lib/index.d.ts",
|
|
14
|
+
"default": "./lib/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./invariant": {
|
|
17
|
+
"types": "./lib/invariant.d.ts",
|
|
18
|
+
"default": "./lib/invariant.js"
|
|
19
|
+
},
|
|
20
|
+
"./permissions": {
|
|
21
|
+
"types": "./lib/permissions.d.ts",
|
|
22
|
+
"default": "./lib/permissions.js"
|
|
23
|
+
},
|
|
24
|
+
"./local-root": {
|
|
25
|
+
"types": "./lib/local-root.d.ts",
|
|
26
|
+
"default": "./lib/local-root.js"
|
|
27
|
+
},
|
|
28
|
+
"./src/*": "./src/*",
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"chokidar": "^4.0.3"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"lib"
|
|
36
|
+
],
|
|
37
|
+
"license": "Apache-2.0",
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@deepseek-ai/dsh-home-paths": ">=0.1.1-rc.2",
|
|
40
|
+
"@deepseek-ai/dsh-invariants": ">=0.1.1-rc.2",
|
|
41
|
+
"@deepseek-ai/dsh-settings": ">=0.1.1-rc.2",
|
|
42
|
+
"@deepseek-ai/cordis": ">=0.1.1-rc.2",
|
|
43
|
+
"@deepseek-ai/schemastery": ">=0.1.1-rc.2"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@deepseek-ai/dsh-home-paths": "link:../../../../deepseek-harness/packages/util/home-paths",
|
|
47
|
+
"@deepseek-ai/dsh-invariants": "link:../../../../deepseek-harness/packages/runtime-diagnostics/invariants",
|
|
48
|
+
"@deepseek-ai/dsh-settings": "link:../../../../deepseek-harness/packages/settings/settings",
|
|
49
|
+
"@deepseek-ai/cordis": "link:../../../../deepseek-harness/vendor/cordis",
|
|
50
|
+
"@deepseek-ai/schemastery": "link:../../../../deepseek-harness/vendor/schemastery"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
}
|
|
55
|
+
}
|