MCPcopy Create free account
hub / github.com/boringstack-xyz/boringstack / mergeClaudeSettings

Function mergeClaudeSettings

scripts/spec-init.ts:132–179  ·  view source on GitHub ↗
(existing: string)

Source from the content-addressed store, hash-verified

130 * at our gate, and only if no entry already references it.
131 */
132function mergeClaudeSettings(existing: string): string {
133 let parsed: Record<string, unknown>;
134 try {
135 parsed = JSON.parse(existing);
136 } catch {
137 fail(
138 `.claude/settings.json is not valid JSON; refusing to merge automatically. Fix or delete the file and re-run.`
139 );
140 }
141 const hooks = (parsed.hooks ??= {}) as Record<string, unknown>;
142 const pre = (hooks.PreToolUse ??= []) as unknown[];
143 const alreadyWired = pre.some((entry) => {
144 if (typeof entry !== "object" || entry === null) {
145 return false;
146 }
147 const candidate = entry as { hooks?: unknown[] };
148
149 return (
150 Array.isArray(candidate.hooks) &&
151 candidate.hooks.some((inner) => {
152 if (typeof inner !== "object" || inner === null) {
153 return false;
154 }
155 const command = (inner as { command?: unknown }).command;
156
157 return (
158 typeof command === "string" && command.includes("tools/spec-loop/hooks/gate")
159 );
160 })
161 );
162 });
163
164 if (alreadyWired) {
165 return existing;
166 }
167
168 pre.push({
169 matcher: "Write|Edit|MultiEdit",
170 hooks: [
171 {
172 type: "command",
173 command: "bun tools/spec-loop/hooks/gate.ts"
174 }
175 ]
176 });
177
178 return JSON.stringify(parsed, null, 2) + "\n";
179}
180
181const PLAN: IPlan[] = [
182 {

Callers 1

runFunction · 0.85

Calls 1

failFunction · 0.85

Tested by

no test coverage detected