agentopology 0.2.0 → 0.2.3
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 +7 -5
- package/dist/analyzer/__tests__/observability-gap.test.d.ts +8 -0
- package/dist/analyzer/__tests__/observability-gap.test.d.ts.map +1 -0
- package/dist/analyzer/__tests__/observability-gap.test.js +132 -0
- package/dist/analyzer/__tests__/observability-gap.test.js.map +1 -0
- package/dist/analyzer/index.d.ts +1 -1
- package/dist/analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/index.js +26 -0
- package/dist/analyzer/index.js.map +1 -1
- package/dist/bindings/__tests__/bindings.test.js +288 -11
- package/dist/bindings/__tests__/bindings.test.js.map +1 -1
- package/dist/bindings/__tests__/observability.test.d.ts +9 -0
- package/dist/bindings/__tests__/observability.test.d.ts.map +1 -0
- package/dist/bindings/__tests__/observability.test.js +136 -0
- package/dist/bindings/__tests__/observability.test.js.map +1 -0
- package/dist/bindings/__tests__/stub-generation.test.d.ts +16 -0
- package/dist/bindings/__tests__/stub-generation.test.d.ts.map +1 -0
- package/dist/bindings/__tests__/stub-generation.test.js +117 -0
- package/dist/bindings/__tests__/stub-generation.test.js.map +1 -0
- package/dist/bindings/claude-code.d.ts.map +1 -1
- package/dist/bindings/claude-code.js +159 -110
- package/dist/bindings/claude-code.js.map +1 -1
- package/dist/bindings/codex.d.ts.map +1 -1
- package/dist/bindings/codex.js +1 -12
- package/dist/bindings/codex.js.map +1 -1
- package/dist/bindings/cursor.d.ts.map +1 -1
- package/dist/bindings/cursor.js +0 -12
- package/dist/bindings/cursor.js.map +1 -1
- package/dist/bindings/gemini-cli.d.ts.map +1 -1
- package/dist/bindings/gemini-cli.js +1 -12
- package/dist/bindings/gemini-cli.js.map +1 -1
- package/dist/bindings/kiro.d.ts.map +1 -1
- package/dist/bindings/kiro.js +1 -12
- package/dist/bindings/kiro.js.map +1 -1
- package/dist/bindings/lib/__tests__/stub.test.d.ts +8 -0
- package/dist/bindings/lib/__tests__/stub.test.d.ts.map +1 -0
- package/dist/bindings/lib/__tests__/stub.test.js +66 -0
- package/dist/bindings/lib/__tests__/stub.test.js.map +1 -0
- package/dist/bindings/lib/stub.d.ts +56 -0
- package/dist/bindings/lib/stub.d.ts.map +1 -0
- package/dist/bindings/lib/stub.js +69 -0
- package/dist/bindings/lib/stub.js.map +1 -0
- package/dist/bindings/openclaw.d.ts.map +1 -1
- package/dist/bindings/openclaw.js +1 -12
- package/dist/bindings/openclaw.js.map +1 -1
- package/dist/bindings/types.d.ts +5 -0
- package/dist/bindings/types.d.ts.map +1 -1
- package/dist/bindings/types.js.map +1 -1
- package/dist/cli/index.js +89 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/docs/content.d.ts.map +1 -1
- package/dist/docs/content.js +9 -5
- package/dist/docs/content.js.map +1 -1
- package/dist/import/__tests__/import.test.js +2 -2
- package/dist/import/__tests__/import.test.js.map +1 -1
- package/dist/parser/__tests__/parser.test.js +31 -3
- package/dist/parser/__tests__/parser.test.js.map +1 -1
- package/dist/parser/validator.d.ts.map +1 -1
- package/dist/parser/validator.js +28 -8
- package/dist/parser/validator.js.map +1 -1
- package/dist/scaffold/__tests__/scaffold.test.js +20 -0
- package/dist/scaffold/__tests__/scaffold.test.js.map +1 -1
- package/dist/scaffold/__tests__/settings-merge.test.d.ts +15 -0
- package/dist/scaffold/__tests__/settings-merge.test.d.ts.map +1 -0
- package/dist/scaffold/__tests__/settings-merge.test.js +127 -0
- package/dist/scaffold/__tests__/settings-merge.test.js.map +1 -0
- package/dist/scaffold/incremental.d.ts.map +1 -1
- package/dist/scaffold/incremental.js +11 -2
- package/dist/scaffold/incremental.js.map +1 -1
- package/dist/scaffold/merge.d.ts +16 -0
- package/dist/scaffold/merge.d.ts.map +1 -1
- package/dist/scaffold/merge.js +77 -0
- package/dist/scaffold/merge.js.map +1 -1
- package/dist/scaffold/types.d.ts +2 -0
- package/dist/scaffold/types.d.ts.map +1 -1
- package/examples/simple-pipeline-topology.html +5700 -0
- package/package.json +2 -1
- package/skill/SKILL.md +7 -7
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Change 3: Non-destructive scaffold of settings.json.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that when settings.json already exists on disk, re-scaffolding
|
|
5
|
+
* without --force performs a MERGE:
|
|
6
|
+
* - permissions.allow is union-merged (existing entries survive)
|
|
7
|
+
* - permissions.deny is union-merged
|
|
8
|
+
* - env is merged (generated wins on conflict)
|
|
9
|
+
* - hooks are rewritten (topology owns hooks)
|
|
10
|
+
* - user-only keys survive
|
|
11
|
+
*
|
|
12
|
+
* Also verifies that invalid existing JSON fails loudly.
|
|
13
|
+
*/
|
|
14
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
15
|
+
import * as fs from "node:fs";
|
|
16
|
+
import * as path from "node:path";
|
|
17
|
+
import * as os from "node:os";
|
|
18
|
+
import { deepMergeSettingsJson } from "../merge.js";
|
|
19
|
+
let tmpDir;
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "settings-merge-test-"));
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
25
|
+
});
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// deepMergeSettingsJson — the core merge function for settings.json
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
describe("Change 3 — deepMergeSettingsJson", () => {
|
|
30
|
+
it("union-merges permissions.allow arrays", () => {
|
|
31
|
+
const existing = JSON.stringify({
|
|
32
|
+
permissions: { allow: ["Read(/tmp/**)", "Write(/tmp/**)"] },
|
|
33
|
+
hooks: {},
|
|
34
|
+
});
|
|
35
|
+
const generated = JSON.stringify({
|
|
36
|
+
permissions: { allow: ["Read(**)", "Bash"] },
|
|
37
|
+
hooks: { PostToolUse: [] },
|
|
38
|
+
});
|
|
39
|
+
const merged = JSON.parse(deepMergeSettingsJson(existing, generated));
|
|
40
|
+
// All entries from both must be present
|
|
41
|
+
expect(merged.permissions.allow).toContain("Read(/tmp/**)");
|
|
42
|
+
expect(merged.permissions.allow).toContain("Write(/tmp/**)");
|
|
43
|
+
expect(merged.permissions.allow).toContain("Read(**)");
|
|
44
|
+
expect(merged.permissions.allow).toContain("Bash");
|
|
45
|
+
});
|
|
46
|
+
it("union-merges permissions.deny arrays", () => {
|
|
47
|
+
const existing = JSON.stringify({
|
|
48
|
+
permissions: { deny: ["Bash", "Write"] },
|
|
49
|
+
});
|
|
50
|
+
const generated = JSON.stringify({
|
|
51
|
+
permissions: { deny: ["Edit"] },
|
|
52
|
+
});
|
|
53
|
+
const merged = JSON.parse(deepMergeSettingsJson(existing, generated));
|
|
54
|
+
expect(merged.permissions.deny).toContain("Bash");
|
|
55
|
+
expect(merged.permissions.deny).toContain("Write");
|
|
56
|
+
expect(merged.permissions.deny).toContain("Edit");
|
|
57
|
+
});
|
|
58
|
+
it("deduplicates union-merged permission arrays", () => {
|
|
59
|
+
const existing = JSON.stringify({
|
|
60
|
+
permissions: { allow: ["Read(**)", "Bash"] },
|
|
61
|
+
});
|
|
62
|
+
const generated = JSON.stringify({
|
|
63
|
+
permissions: { allow: ["Read(**)", "Write"] },
|
|
64
|
+
});
|
|
65
|
+
const merged = JSON.parse(deepMergeSettingsJson(existing, generated));
|
|
66
|
+
const count = merged.permissions.allow.filter((a) => a === "Read(**)").length;
|
|
67
|
+
expect(count).toBe(1);
|
|
68
|
+
});
|
|
69
|
+
it("generated wins on env key conflicts", () => {
|
|
70
|
+
const existing = JSON.stringify({
|
|
71
|
+
env: { FOO: "old-value", BAR: "preserved" },
|
|
72
|
+
});
|
|
73
|
+
const generated = JSON.stringify({
|
|
74
|
+
env: { FOO: "new-value", BAZ: "added" },
|
|
75
|
+
});
|
|
76
|
+
const merged = JSON.parse(deepMergeSettingsJson(existing, generated));
|
|
77
|
+
// Generated wins on conflict
|
|
78
|
+
expect(merged.env.FOO).toBe("new-value");
|
|
79
|
+
// Existing-only key preserved
|
|
80
|
+
expect(merged.env.BAR).toBe("preserved");
|
|
81
|
+
// Generated-only key added
|
|
82
|
+
expect(merged.env.BAZ).toBe("added");
|
|
83
|
+
});
|
|
84
|
+
it("hooks are REWRITTEN by generated (topology owns hooks)", () => {
|
|
85
|
+
const existing = JSON.stringify({
|
|
86
|
+
hooks: {
|
|
87
|
+
PreToolUse: [{ matcher: "old", hooks: [{ type: "command", command: "old.sh" }] }],
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
const generated = JSON.stringify({
|
|
91
|
+
hooks: {
|
|
92
|
+
SubagentStop: [{ matcher: "new", hooks: [{ type: "command", command: "new.sh" }] }],
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
const merged = JSON.parse(deepMergeSettingsJson(existing, generated));
|
|
96
|
+
// Old hooks gone — topology owns hooks
|
|
97
|
+
expect(merged.hooks.PreToolUse).toBeUndefined();
|
|
98
|
+
// New hooks present
|
|
99
|
+
expect(merged.hooks.SubagentStop).toBeDefined();
|
|
100
|
+
});
|
|
101
|
+
it("preserves user-only top-level keys", () => {
|
|
102
|
+
const existing = JSON.stringify({
|
|
103
|
+
model: "claude-opus-4-5",
|
|
104
|
+
theme: "dark",
|
|
105
|
+
});
|
|
106
|
+
const generated = JSON.stringify({
|
|
107
|
+
permissions: { allow: ["Read"] },
|
|
108
|
+
});
|
|
109
|
+
const merged = JSON.parse(deepMergeSettingsJson(existing, generated));
|
|
110
|
+
expect(merged.model).toBe("claude-opus-4-5");
|
|
111
|
+
expect(merged.theme).toBe("dark");
|
|
112
|
+
expect(merged.permissions.allow).toContain("Read");
|
|
113
|
+
});
|
|
114
|
+
it("throws a descriptive error when existing JSON is invalid", () => {
|
|
115
|
+
const existing = `{ "permissions": { "allow": ["Read"] `; // truncated
|
|
116
|
+
const generated = JSON.stringify({ permissions: { allow: ["Write"] } });
|
|
117
|
+
expect(() => deepMergeSettingsJson(existing, generated)).toThrow(/invalid JSON/i);
|
|
118
|
+
});
|
|
119
|
+
it("returns generated as-is when existing is empty string", () => {
|
|
120
|
+
const existing = "";
|
|
121
|
+
const generated = JSON.stringify({ permissions: { allow: ["Read"] } });
|
|
122
|
+
// Empty string means no prior settings — just use generated
|
|
123
|
+
const result = deepMergeSettingsJson(existing, generated);
|
|
124
|
+
expect(JSON.parse(result)).toEqual(JSON.parse(generated));
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=settings-merge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-merge.test.js","sourceRoot":"","sources":["../../../src/scaffold/__tests__/settings-merge.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incremental.d.ts","sourceRoot":"","sources":["../../src/scaffold/incremental.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG/D;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,aAAa,EAAE,EAC/B,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAChC,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"incremental.d.ts","sourceRoot":"","sources":["../../src/scaffold/incremental.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG/D;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,aAAa,EAAE,EAC/B,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAChC,UAAU,EAAE,CAgHd;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC1C;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAyDA"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
|
-
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { dirname, join } from "node:path";
|
|
12
12
|
import { mergeAgentFile, shouldOverwriteScript, deepMergeJson } from "./merge.js";
|
|
13
13
|
/**
|
|
@@ -35,7 +35,12 @@ export function computeIncrementalPlan(basePath, target, generatedFiles, manifes
|
|
|
35
35
|
const category = file.category ?? "machine";
|
|
36
36
|
const onDisk = existsSync(absPath);
|
|
37
37
|
if (!onDisk) {
|
|
38
|
-
actions.push({
|
|
38
|
+
actions.push({
|
|
39
|
+
type: "create",
|
|
40
|
+
path: file.path,
|
|
41
|
+
content: file.content,
|
|
42
|
+
...(file.executable ? { executable: true } : {}),
|
|
43
|
+
});
|
|
39
44
|
continue;
|
|
40
45
|
}
|
|
41
46
|
const existingContent = readFileSync(absPath, "utf-8");
|
|
@@ -144,6 +149,8 @@ export function executeActions(basePath, actions, options) {
|
|
|
144
149
|
mkdirSync(dir, { recursive: true });
|
|
145
150
|
}
|
|
146
151
|
writeFileSync(absPath, action.content, "utf-8");
|
|
152
|
+
if (action.executable)
|
|
153
|
+
chmodSync(absPath, 0o755);
|
|
147
154
|
counts.created++;
|
|
148
155
|
break;
|
|
149
156
|
}
|
|
@@ -153,6 +160,8 @@ export function executeActions(basePath, actions, options) {
|
|
|
153
160
|
mkdirSync(dir, { recursive: true });
|
|
154
161
|
}
|
|
155
162
|
writeFileSync(absPath, action.content, "utf-8");
|
|
163
|
+
if (action.executable)
|
|
164
|
+
chmodSync(absPath, 0o755);
|
|
156
165
|
counts.updated++;
|
|
157
166
|
break;
|
|
158
167
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incremental.js","sourceRoot":"","sources":["../../src/scaffold/incremental.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"incremental.js","sourceRoot":"","sources":["../../src/scaffold/incremental.ts"],"names":[],"mappings":"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"}
|
package/dist/scaffold/merge.d.ts
CHANGED
|
@@ -49,4 +49,20 @@ export declare function shouldOverwriteScript(existingContent: string, manifestH
|
|
|
49
49
|
* @returns Merged JSON string, or existingRaw if parse fails
|
|
50
50
|
*/
|
|
51
51
|
export declare function deepMergeJson(existingRaw: string, generatedRaw: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* Merge settings.json files with domain-aware logic for Claude Code settings.
|
|
54
|
+
*
|
|
55
|
+
* Rules:
|
|
56
|
+
* - permissions.allow: union-merge (deduplicated)
|
|
57
|
+
* - permissions.deny: union-merge (deduplicated)
|
|
58
|
+
* - env: shallow-merge (generated wins on key conflict)
|
|
59
|
+
* - hooks: rewritten entirely from generated (topology owns hooks)
|
|
60
|
+
* - All other top-level keys: existing wins (user-only keys preserved)
|
|
61
|
+
*
|
|
62
|
+
* @param existingRaw - Current settings.json content on disk (JSON string, or empty string)
|
|
63
|
+
* @param generatedRaw - Freshly generated settings.json content (JSON string)
|
|
64
|
+
* @returns Merged JSON string
|
|
65
|
+
* @throws {Error} if existingRaw is non-empty and is invalid JSON
|
|
66
|
+
*/
|
|
67
|
+
export declare function deepMergeSettingsJson(existingRaw: string, generatedRaw: string): string;
|
|
52
68
|
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/scaffold/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,MAAM,CA4CR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAET;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAc/E"}
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/scaffold/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,MAAM,CA4CR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAET;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAc/E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAmEvF"}
|
package/dist/scaffold/merge.js
CHANGED
|
@@ -109,6 +109,83 @@ export function deepMergeJson(existingRaw, generatedRaw) {
|
|
|
109
109
|
const merged = mergeObjects(existing, generated);
|
|
110
110
|
return JSON.stringify(merged, null, 2) + "\n";
|
|
111
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Merge settings.json files with domain-aware logic for Claude Code settings.
|
|
114
|
+
*
|
|
115
|
+
* Rules:
|
|
116
|
+
* - permissions.allow: union-merge (deduplicated)
|
|
117
|
+
* - permissions.deny: union-merge (deduplicated)
|
|
118
|
+
* - env: shallow-merge (generated wins on key conflict)
|
|
119
|
+
* - hooks: rewritten entirely from generated (topology owns hooks)
|
|
120
|
+
* - All other top-level keys: existing wins (user-only keys preserved)
|
|
121
|
+
*
|
|
122
|
+
* @param existingRaw - Current settings.json content on disk (JSON string, or empty string)
|
|
123
|
+
* @param generatedRaw - Freshly generated settings.json content (JSON string)
|
|
124
|
+
* @returns Merged JSON string
|
|
125
|
+
* @throws {Error} if existingRaw is non-empty and is invalid JSON
|
|
126
|
+
*/
|
|
127
|
+
export function deepMergeSettingsJson(existingRaw, generatedRaw) {
|
|
128
|
+
// Empty existing means first scaffold — return generated unchanged
|
|
129
|
+
if (existingRaw.trim() === "") {
|
|
130
|
+
return generatedRaw;
|
|
131
|
+
}
|
|
132
|
+
let existing;
|
|
133
|
+
let generated;
|
|
134
|
+
try {
|
|
135
|
+
existing = JSON.parse(existingRaw);
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
throw new Error(`invalid JSON in existing settings.json: ${err.message}`);
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
generated = JSON.parse(generatedRaw);
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
throw new Error(`invalid JSON in generated settings.json: ${err.message}`);
|
|
145
|
+
}
|
|
146
|
+
// Start with existing (preserves all user-only top-level keys)
|
|
147
|
+
const merged = { ...existing };
|
|
148
|
+
// --- permissions: union-merge allow and deny arrays ---
|
|
149
|
+
const existingPerms = (existing.permissions ?? {});
|
|
150
|
+
const generatedPerms = (generated.permissions ?? {});
|
|
151
|
+
if (generated.permissions !== undefined || existing.permissions !== undefined) {
|
|
152
|
+
const mergedPerms = {};
|
|
153
|
+
for (const key of ["allow", "deny"]) {
|
|
154
|
+
const ex = Array.isArray(existingPerms[key]) ? existingPerms[key] : [];
|
|
155
|
+
const gen = Array.isArray(generatedPerms[key]) ? generatedPerms[key] : [];
|
|
156
|
+
const union = Array.from(new Set([...ex, ...gen]));
|
|
157
|
+
if (union.length > 0) {
|
|
158
|
+
mergedPerms[key] = union;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (Object.keys(mergedPerms).length > 0) {
|
|
162
|
+
merged.permissions = mergedPerms;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// --- env: shallow-merge, generated wins on conflict ---
|
|
166
|
+
if (generated.env !== undefined) {
|
|
167
|
+
const existingEnv = (existing.env ?? {});
|
|
168
|
+
const generatedEnv = generated.env;
|
|
169
|
+
merged.env = { ...existingEnv, ...generatedEnv };
|
|
170
|
+
}
|
|
171
|
+
// --- hooks: rewritten entirely from generated (topology owns hooks) ---
|
|
172
|
+
if (generated.hooks !== undefined) {
|
|
173
|
+
merged.hooks = generated.hooks;
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
// No hooks in generated — remove the hooks key (topology no longer declares any)
|
|
177
|
+
delete merged.hooks;
|
|
178
|
+
}
|
|
179
|
+
// --- all other generated keys: add if missing, do NOT overwrite existing ---
|
|
180
|
+
for (const [key, value] of Object.entries(generated)) {
|
|
181
|
+
if (key === "permissions" || key === "env" || key === "hooks")
|
|
182
|
+
continue;
|
|
183
|
+
if (merged[key] === undefined) {
|
|
184
|
+
merged[key] = value;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return JSON.stringify(merged, null, 2) + "\n";
|
|
188
|
+
}
|
|
112
189
|
function mergeObjects(existing, generated) {
|
|
113
190
|
// Start with a copy of existing (preserves user-only keys)
|
|
114
191
|
const result = { ...existing };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/scaffold/merge.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/scaffold/merge.ts"],"names":[],"mappings":"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"}
|
package/dist/scaffold/types.d.ts
CHANGED
|
@@ -31,11 +31,13 @@ export type FileAction = {
|
|
|
31
31
|
type: "create";
|
|
32
32
|
path: string;
|
|
33
33
|
content: string;
|
|
34
|
+
executable?: boolean;
|
|
34
35
|
} | {
|
|
35
36
|
type: "update";
|
|
36
37
|
path: string;
|
|
37
38
|
content: string;
|
|
38
39
|
detail: string;
|
|
40
|
+
executable?: boolean;
|
|
39
41
|
} | {
|
|
40
42
|
type: "delete";
|
|
41
43
|
path: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scaffold/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,eAAe,CAAC;CAC5D;AAED,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACtC;AAED,yEAAyE;AACzE,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scaffold/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,eAAe,CAAC;CAC5D;AAED,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACtC;AAED,yEAAyE;AACzE,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACvE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACvF;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC"}
|