@intutic/sync-daemon 1.6.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.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/dist/brainIndexer.d.ts +51 -0
  4. package/dist/brainIndexer.d.ts.map +1 -0
  5. package/dist/brainIndexer.js +148 -0
  6. package/dist/brainIndexer.js.map +1 -0
  7. package/dist/configReader.d.ts +46 -0
  8. package/dist/configReader.d.ts.map +1 -0
  9. package/dist/configReader.js +133 -0
  10. package/dist/configReader.js.map +1 -0
  11. package/dist/configWriter.d.ts +53 -0
  12. package/dist/configWriter.d.ts.map +1 -0
  13. package/dist/configWriter.js +503 -0
  14. package/dist/configWriter.js.map +1 -0
  15. package/dist/harness/aiderConfigMerger.d.ts +27 -0
  16. package/dist/harness/aiderConfigMerger.d.ts.map +1 -0
  17. package/dist/harness/aiderConfigMerger.js +139 -0
  18. package/dist/harness/aiderConfigMerger.js.map +1 -0
  19. package/dist/harness/antigravityHooks.d.ts +43 -0
  20. package/dist/harness/antigravityHooks.d.ts.map +1 -0
  21. package/dist/harness/antigravityHooks.js +193 -0
  22. package/dist/harness/antigravityHooks.js.map +1 -0
  23. package/dist/harness/claudeCodeHooks.d.ts +59 -0
  24. package/dist/harness/claudeCodeHooks.d.ts.map +1 -0
  25. package/dist/harness/claudeCodeHooks.js +414 -0
  26. package/dist/harness/claudeCodeHooks.js.map +1 -0
  27. package/dist/harness/claudeDesktopHooks.d.ts +30 -0
  28. package/dist/harness/claudeDesktopHooks.d.ts.map +1 -0
  29. package/dist/harness/claudeDesktopHooks.js +267 -0
  30. package/dist/harness/claudeDesktopHooks.js.map +1 -0
  31. package/dist/harness/clineHooks.d.ts +23 -0
  32. package/dist/harness/clineHooks.d.ts.map +1 -0
  33. package/dist/harness/clineHooks.js +169 -0
  34. package/dist/harness/clineHooks.js.map +1 -0
  35. package/dist/harness/continueHooks.d.ts +33 -0
  36. package/dist/harness/continueHooks.d.ts.map +1 -0
  37. package/dist/harness/continueHooks.js +124 -0
  38. package/dist/harness/continueHooks.js.map +1 -0
  39. package/dist/harness/cursorHooks.d.ts +27 -0
  40. package/dist/harness/cursorHooks.d.ts.map +1 -0
  41. package/dist/harness/cursorHooks.js +221 -0
  42. package/dist/harness/cursorHooks.js.map +1 -0
  43. package/dist/harness/cursorHooksJson.d.ts +29 -0
  44. package/dist/harness/cursorHooksJson.d.ts.map +1 -0
  45. package/dist/harness/cursorHooksJson.js +130 -0
  46. package/dist/harness/cursorHooksJson.js.map +1 -0
  47. package/dist/harness/gooseHardener.d.ts +39 -0
  48. package/dist/harness/gooseHardener.d.ts.map +1 -0
  49. package/dist/harness/gooseHardener.js +152 -0
  50. package/dist/harness/gooseHardener.js.map +1 -0
  51. package/dist/harness/gooseHooks.d.ts +24 -0
  52. package/dist/harness/gooseHooks.d.ts.map +1 -0
  53. package/dist/harness/gooseHooks.js +175 -0
  54. package/dist/harness/gooseHooks.js.map +1 -0
  55. package/dist/harness/gooseHooksWriter.d.ts +27 -0
  56. package/dist/harness/gooseHooksWriter.d.ts.map +1 -0
  57. package/dist/harness/gooseHooksWriter.js +147 -0
  58. package/dist/harness/gooseHooksWriter.js.map +1 -0
  59. package/dist/harness/hermesHooks.d.ts +31 -0
  60. package/dist/harness/hermesHooks.d.ts.map +1 -0
  61. package/dist/harness/hermesHooks.js +245 -0
  62. package/dist/harness/hermesHooks.js.map +1 -0
  63. package/dist/harness/mcpAutoWrite.d.ts +35 -0
  64. package/dist/harness/mcpAutoWrite.d.ts.map +1 -0
  65. package/dist/harness/mcpAutoWrite.js +334 -0
  66. package/dist/harness/mcpAutoWrite.js.map +1 -0
  67. package/dist/harness/n8nHooks.d.ts +28 -0
  68. package/dist/harness/n8nHooks.d.ts.map +1 -0
  69. package/dist/harness/n8nHooks.js +205 -0
  70. package/dist/harness/n8nHooks.js.map +1 -0
  71. package/dist/harness/openWebuiHooks.d.ts +31 -0
  72. package/dist/harness/openWebuiHooks.d.ts.map +1 -0
  73. package/dist/harness/openWebuiHooks.js +166 -0
  74. package/dist/harness/openWebuiHooks.js.map +1 -0
  75. package/dist/harness/openclawHooks.d.ts +34 -0
  76. package/dist/harness/openclawHooks.d.ts.map +1 -0
  77. package/dist/harness/openclawHooks.js +296 -0
  78. package/dist/harness/openclawHooks.js.map +1 -0
  79. package/dist/harness/openhandsHooks.d.ts +24 -0
  80. package/dist/harness/openhandsHooks.d.ts.map +1 -0
  81. package/dist/harness/openhandsHooks.js +178 -0
  82. package/dist/harness/openhandsHooks.js.map +1 -0
  83. package/dist/harness/openhandsHooksWriter.d.ts +23 -0
  84. package/dist/harness/openhandsHooksWriter.d.ts.map +1 -0
  85. package/dist/harness/openhandsHooksWriter.js +146 -0
  86. package/dist/harness/openhandsHooksWriter.js.map +1 -0
  87. package/dist/harness/piHooks.d.ts +32 -0
  88. package/dist/harness/piHooks.d.ts.map +1 -0
  89. package/dist/harness/piHooks.js +257 -0
  90. package/dist/harness/piHooks.js.map +1 -0
  91. package/dist/harness/rooCodeHooks.d.ts +31 -0
  92. package/dist/harness/rooCodeHooks.d.ts.map +1 -0
  93. package/dist/harness/rooCodeHooks.js +300 -0
  94. package/dist/harness/rooCodeHooks.js.map +1 -0
  95. package/dist/harness/windsurfHooks.d.ts +27 -0
  96. package/dist/harness/windsurfHooks.d.ts.map +1 -0
  97. package/dist/harness/windsurfHooks.js +202 -0
  98. package/dist/harness/windsurfHooks.js.map +1 -0
  99. package/dist/hashReporter.d.ts +33 -0
  100. package/dist/hashReporter.d.ts.map +1 -0
  101. package/dist/hashReporter.js +69 -0
  102. package/dist/hashReporter.js.map +1 -0
  103. package/dist/index.d.ts +43 -0
  104. package/dist/index.d.ts.map +1 -0
  105. package/dist/index.js +43 -0
  106. package/dist/index.js.map +1 -0
  107. package/dist/integrityStore.d.ts +43 -0
  108. package/dist/integrityStore.d.ts.map +1 -0
  109. package/dist/integrityStore.js +94 -0
  110. package/dist/integrityStore.js.map +1 -0
  111. package/dist/lib/complianceProbes.d.ts +39 -0
  112. package/dist/lib/complianceProbes.d.ts.map +1 -0
  113. package/dist/lib/complianceProbes.js +115 -0
  114. package/dist/lib/complianceProbes.js.map +1 -0
  115. package/dist/lib/processPoller.d.ts +2 -0
  116. package/dist/lib/processPoller.d.ts.map +1 -0
  117. package/dist/lib/processPoller.js +87 -0
  118. package/dist/lib/processPoller.js.map +1 -0
  119. package/dist/lib/runtimeEnv.d.ts +49 -0
  120. package/dist/lib/runtimeEnv.d.ts.map +1 -0
  121. package/dist/lib/runtimeEnv.js +70 -0
  122. package/dist/lib/runtimeEnv.js.map +1 -0
  123. package/dist/skillWriter.d.ts +24 -0
  124. package/dist/skillWriter.d.ts.map +1 -0
  125. package/dist/skillWriter.js +112 -0
  126. package/dist/skillWriter.js.map +1 -0
  127. package/dist/syncLoop.d.ts +70 -0
  128. package/dist/syncLoop.d.ts.map +1 -0
  129. package/dist/syncLoop.js +546 -0
  130. package/dist/syncLoop.js.map +1 -0
  131. package/dist/trajectoryMonitor.d.ts +126 -0
  132. package/dist/trajectoryMonitor.d.ts.map +1 -0
  133. package/dist/trajectoryMonitor.js +291 -0
  134. package/dist/trajectoryMonitor.js.map +1 -0
  135. package/dist/watcher/driftWatcher.d.ts +25 -0
  136. package/dist/watcher/driftWatcher.d.ts.map +1 -0
  137. package/dist/watcher/driftWatcher.js +72 -0
  138. package/dist/watcher/driftWatcher.js.map +1 -0
  139. package/dist/watcher/settingsGuard.d.ts +32 -0
  140. package/dist/watcher/settingsGuard.d.ts.map +1 -0
  141. package/dist/watcher/settingsGuard.js +250 -0
  142. package/dist/watcher/settingsGuard.js.map +1 -0
  143. package/dist/wsClient.d.ts +49 -0
  144. package/dist/wsClient.d.ts.map +1 -0
  145. package/dist/wsClient.js +149 -0
  146. package/dist/wsClient.js.map +1 -0
  147. package/package.json +96 -0
@@ -0,0 +1,503 @@
1
+ /**
2
+ * configWriter.ts — Write SOP content to harness config files.
3
+ *
4
+ * Each harness (Cursor, Claude Code, Antigravity, Windsurf, Aider,
5
+ * OpenHands, Codex) has a distinct config file format. This module
6
+ * resolves paths, formats content, and performs atomic writes
7
+ * (write-to-tmp → rename) to prevent partial/corrupt files.
8
+ *
9
+ * HLD §3.14 — Real-Time State Mirroring
10
+ * LLD #8 — Sync Daemon / CLI
11
+ *
12
+ * @module
13
+ */
14
+ import * as node_fs from 'node:fs/promises';
15
+ import * as node_path from 'node:path';
16
+ import { execFile as _execFile } from 'node:child_process';
17
+ import { promisify } from 'node:util';
18
+ import { newIso } from '@intutic/id';
19
+ const execFile = promisify(_execFile);
20
+ /**
21
+ * Clear the macOS user-immutable flag before writing a file.
22
+ * No-op on non-macOS platforms or if the file doesn't exist yet.
23
+ * Called when bypassEnforcementTier === 'immutable'. (WS-5 Q3)
24
+ */
25
+ async function clearImmutable(filePath) {
26
+ if (process.platform !== 'darwin')
27
+ return;
28
+ try {
29
+ await execFile('chflags', ['nouchg', filePath]);
30
+ }
31
+ catch { /* file may not exist yet */ }
32
+ }
33
+ /**
34
+ * Set the macOS user-immutable flag after writing a file.
35
+ * Prevents direct edits from succeeding — any attempt gets EPERM.
36
+ * The flag is cleared before the next sync write.
37
+ * No-op on non-macOS platforms. (WS-5 Q3)
38
+ */
39
+ async function setImmutable(filePath) {
40
+ if (process.platform !== 'darwin')
41
+ return;
42
+ try {
43
+ await execFile('chflags', ['uchg', filePath]);
44
+ }
45
+ catch { /* non-fatal */ }
46
+ }
47
+ import { writeAntigravityHooks } from './harness/antigravityHooks.js';
48
+ import { writeClaudeDesktopHooks } from './harness/claudeDesktopHooks.js';
49
+ import { writeRooCodeHooks } from './harness/rooCodeHooks.js';
50
+ import { writeContinueHooks } from './harness/continueHooks.js';
51
+ import { writeOpenWebuiHooks } from './harness/openWebuiHooks.js';
52
+ import { writeN8nHooks } from './harness/n8nHooks.js';
53
+ import { writeHermesHooks } from './harness/hermesHooks.js';
54
+ import { writeOpenclawHooks } from './harness/openclawHooks.js';
55
+ import { writePiHooks } from './harness/piHooks.js';
56
+ import { writeCursorHooksJson } from './harness/cursorHooksJson.js';
57
+ import { writeGooseHooks as writeGooseHooksNative } from './harness/gooseHooksWriter.js';
58
+ import { writeOpenHandsHooks as writeOpenHandsHooksNative } from './harness/openhandsHooksWriter.js';
59
+ // ─── Harness config file mapping ─────────────────────────────────────
60
+ /**
61
+ * Maps each harness type to its expected config filename relative to
62
+ * the workspace root. Empty string means the harness is deferred to
63
+ * Phase 2 (e.g., n8n — TD-037).
64
+ */
65
+ export const HARNESS_FILES = {
66
+ cursor: '.cursorrules',
67
+ 'claude-code': 'CLAUDE.md',
68
+ antigravity: '.gemini/settings.json',
69
+ windsurf: '.windsurfrules',
70
+ aider: '.aider.conf.yml',
71
+ openhands: 'config.toml',
72
+ codex: '.env.intutic',
73
+ n8n: '.intutic/n8n/governance-workflow.json',
74
+ openclaw: '.openclaw/openclaw.json',
75
+ hermes: '.hermes/config.yaml',
76
+ pi: '.pi/hooks.json',
77
+ 'github-copilot': '.github/copilot-instructions.md',
78
+ cline: '.cline/hooks/hooks.json',
79
+ 'roo-code': '.roorules',
80
+ continue: '.continue/config.json',
81
+ 'claude-desktop': 'claude_desktop_config.json',
82
+ goose: '.agents/plugins/intutic-governance/hooks/hooks.json',
83
+ 'open-webui': '.open-webui/intutic-governance-filter.py',
84
+ };
85
+ /**
86
+ * Write SOP content to all targeted harness config files.
87
+ *
88
+ * For each harness type, resolves the config file path, formats the
89
+ * content according to the harness-specific format, and performs an
90
+ * atomic write (tmp file → rename).
91
+ *
92
+ * @param workspaceRoot - Absolute path to the workspace root.
93
+ * @param sops - SOPs to write, each specifying which harnesses to target.
94
+ * @param proxyUrl - Intutic proxy URL for LLM API redirect.
95
+ * @param harnesses - Harness types detected in the workspace.
96
+ * @returns WriteResult with written and skipped file paths.
97
+ */
98
+ export async function writeConfigFiles(workspaceRoot, sops, proxyUrl, harnesses, workspaceId = '',
99
+ /** WS-5 Q3: 'rewrite' (default) | 'immutable' | 'alert-only' */
100
+ bypassEnforcementTier) {
101
+ const filesWritten = [];
102
+ const filesSkipped = [];
103
+ // Bundled agent skills — write-if-missing, not drift-enforced
104
+ try {
105
+ const { writeBundledSkills } = await import('./skillWriter.js');
106
+ await writeBundledSkills(workspaceRoot);
107
+ }
108
+ catch (e) {
109
+ console.warn('[sync-daemon] writeBundledSkills failed (non-fatal):', e);
110
+ }
111
+ // Load and compile local SOP entries
112
+ const localSopEntries = [];
113
+ try {
114
+ const sessionContextPath = node_path.join(workspaceRoot, '.intutic', 'session-context.json');
115
+ let activeLocalSops;
116
+ try {
117
+ const raw = await node_fs.readFile(sessionContextPath, 'utf-8');
118
+ const parsed = JSON.parse(raw);
119
+ activeLocalSops = parsed.activeLocalSops;
120
+ }
121
+ catch {
122
+ // not configured yet
123
+ }
124
+ const sopsDir = node_path.join(workspaceRoot, '.intutic', 'sops');
125
+ const entries = await node_fs.readdir(sopsDir, { withFileTypes: true });
126
+ const dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
127
+ const activeDirs = activeLocalSops !== undefined
128
+ ? dirs.filter((d) => activeLocalSops.includes(d))
129
+ : dirs;
130
+ for (const dirName of activeDirs) {
131
+ const dirPath = node_path.join(sopsDir, dirName);
132
+ const files = await node_fs.readdir(dirPath);
133
+ const mdFiles = files.filter((f) => f.endsWith('.md'));
134
+ for (const file of mdFiles) {
135
+ const filePath = node_path.join(dirPath, file);
136
+ const content = await node_fs.readFile(filePath, 'utf-8');
137
+ localSopEntries.push({
138
+ sopId: `local:${dirName}:${file}`,
139
+ title: `Local SOP: ${dirName}/${file}`,
140
+ content,
141
+ contentHash: '',
142
+ harnessTargets: harnesses,
143
+ });
144
+ }
145
+ }
146
+ }
147
+ catch (err) {
148
+ // ignore directory read errors (e.g. if sops folder doesn't exist)
149
+ }
150
+ const combinedSops = [...sops, ...localSopEntries];
151
+ for (const harness of harnesses) {
152
+ const filename = HARNESS_FILES[harness];
153
+ // Phase 3 proprietary harnesses — no config file path needed (handled below)
154
+ if (harness === 'hermes') {
155
+ try {
156
+ await writeHermesHooks(workspaceRoot, proxyUrl, workspaceId);
157
+ }
158
+ catch (e) {
159
+ console.warn('[sync-daemon] writeHermesHooks failed (non-fatal):', e);
160
+ }
161
+ continue;
162
+ }
163
+ if (harness === 'openclaw') {
164
+ try {
165
+ await writeOpenclawHooks(workspaceRoot, proxyUrl, workspaceId);
166
+ }
167
+ catch (e) {
168
+ console.warn('[sync-daemon] writeOpenclawHooks failed (non-fatal):', e);
169
+ }
170
+ continue;
171
+ }
172
+ if (harness === 'pi') {
173
+ try {
174
+ await writePiHooks(workspaceRoot, proxyUrl, workspaceId);
175
+ }
176
+ catch (e) {
177
+ console.warn('[sync-daemon] writePiHooks failed (non-fatal):', e);
178
+ }
179
+ continue;
180
+ }
181
+ // Phase 4 WS-4C — native hook script writers
182
+ if (harness === 'cursor') {
183
+ try {
184
+ await writeCursorHooksJson(workspaceRoot);
185
+ }
186
+ catch (e) {
187
+ console.warn('[sync-daemon] writeCursorHooksJson failed (non-fatal):', e);
188
+ }
189
+ }
190
+ if (harness === 'goose') {
191
+ try {
192
+ await writeGooseHooksNative(workspaceRoot);
193
+ }
194
+ catch (e) {
195
+ console.warn('[sync-daemon] writeGooseHooksNative failed (non-fatal):', e);
196
+ }
197
+ }
198
+ if (harness === 'openhands') {
199
+ try {
200
+ await writeOpenHandsHooksNative(workspaceRoot);
201
+ }
202
+ catch (e) {
203
+ console.warn('[sync-daemon] writeOpenHandsHooksNative failed (non-fatal):', e);
204
+ }
205
+ }
206
+ // Phase 2 deferred or unknown harness
207
+ if (!filename) {
208
+ filesSkipped.push(`[${harness}] (deferred)`);
209
+ continue;
210
+ }
211
+ const configPath = node_path.join(workspaceRoot, filename);
212
+ // Filter SOPs that target this harness
213
+ const targetedSops = combinedSops.filter((sop) => sop.harnessTargets.includes(harness));
214
+ if (targetedSops.length === 0) {
215
+ filesSkipped.push(configPath);
216
+ continue;
217
+ }
218
+ const content = formatContent(harness, targetedSops, proxyUrl);
219
+ try {
220
+ await atomicWrite(configPath, content, bypassEnforcementTier);
221
+ filesWritten.push(configPath);
222
+ // For 'antigravity', also write the governance hook script and settings.json merge.
223
+ // This is separate from the SOP content write above (which writes customInstructions).
224
+ if (harness === 'antigravity') {
225
+ try {
226
+ await writeAntigravityHooks(workspaceRoot, proxyUrl, workspaceId);
227
+ }
228
+ catch (hookErr) {
229
+ // Non-fatal — SOP content was written, only the hook script failed
230
+ console.warn('[sync-daemon] writeAntigravityHooks failed (non-fatal):', hookErr);
231
+ }
232
+ }
233
+ if (harness === 'claude-desktop') {
234
+ try {
235
+ await writeClaudeDesktopHooks(workspaceRoot, proxyUrl, workspaceId);
236
+ }
237
+ catch (e) {
238
+ console.warn('[sync-daemon] writeClaudeDesktopHooks failed (non-fatal):', e);
239
+ }
240
+ }
241
+ if (harness === 'roo-code') {
242
+ try {
243
+ await writeRooCodeHooks(workspaceRoot, proxyUrl, workspaceId);
244
+ }
245
+ catch (e) {
246
+ console.warn('[sync-daemon] writeRooCodeHooks failed (non-fatal):', e);
247
+ }
248
+ }
249
+ if (harness === 'continue') {
250
+ try {
251
+ await writeContinueHooks(workspaceRoot, proxyUrl, workspaceId);
252
+ }
253
+ catch (e) {
254
+ console.warn('[sync-daemon] writeContinueHooks failed (non-fatal):', e);
255
+ }
256
+ }
257
+ if (harness === 'open-webui') {
258
+ try {
259
+ await writeOpenWebuiHooks(workspaceRoot, proxyUrl, workspaceId);
260
+ }
261
+ catch (e) {
262
+ console.warn('[sync-daemon] writeOpenWebuiHooks failed (non-fatal):', e);
263
+ }
264
+ }
265
+ if (harness === 'n8n') {
266
+ try {
267
+ await writeN8nHooks(workspaceRoot, proxyUrl, workspaceId);
268
+ }
269
+ catch (e) {
270
+ console.warn('[sync-daemon] writeN8nHooks failed (non-fatal):', e);
271
+ }
272
+ }
273
+ }
274
+ catch (err) {
275
+ console.warn(`[sync-daemon] writeConfigFiles failed for ${filename}:`, err);
276
+ // Don't crash the loop — report as skipped
277
+ filesSkipped.push(configPath);
278
+ }
279
+ }
280
+ return { filesWritten, filesSkipped };
281
+ }
282
+ /**
283
+ * Finds a match for a target block in content, tolerating line ending and whitespace variations.
284
+ */
285
+ function findFuzzyMatch(content, target) {
286
+ if (content.includes(target))
287
+ return target;
288
+ const normalize = (s) => s.replace(/\r\n/g, '\n').replace(/\s+/g, ' ').trim();
289
+ const normalizedTarget = normalize(target);
290
+ if (!normalizedTarget)
291
+ return null;
292
+ // Line-by-line normalized search
293
+ const targetLines = target.split(/\r?\n/).map(l => normalize(l)).filter(Boolean);
294
+ if (targetLines.length === 0)
295
+ return null;
296
+ const contentLines = content.split(/\r?\n/);
297
+ for (let i = 0; i <= contentLines.length - targetLines.length; i++) {
298
+ let match = true;
299
+ for (let j = 0; j < targetLines.length; j++) {
300
+ const contentLineNorm = normalize(contentLines[i + j] || '');
301
+ if (contentLineNorm !== targetLines[j]) {
302
+ match = false;
303
+ break;
304
+ }
305
+ }
306
+ if (match) {
307
+ // Reconstruct matching section using original line endings from content
308
+ return contentLines.slice(i, i + targetLines.length).join('\n');
309
+ }
310
+ }
311
+ return null;
312
+ }
313
+ /**
314
+ * Apply a list of custom config edits (ADD, DELETE, REPLACE) to a workspace rule file.
315
+ */
316
+ export async function applyConfigEdits(workspaceRoot, appliedEdits, bypassEnforcementTier) {
317
+ for (const applied of appliedEdits) {
318
+ const filename = HARNESS_FILES[applied.harnessType] || applied.filePath;
319
+ if (!filename)
320
+ continue;
321
+ const filePath = node_path.join(workspaceRoot, filename);
322
+ let currentContent = '';
323
+ try {
324
+ currentContent = await node_fs.readFile(filePath, 'utf-8');
325
+ }
326
+ catch {
327
+ // file doesn't exist
328
+ }
329
+ let updatedContent = currentContent;
330
+ const editsList = typeof applied.edits === 'string'
331
+ ? JSON.parse(applied.edits)
332
+ : applied.edits;
333
+ for (const edit of editsList) {
334
+ if (edit.operation === 'ADD') {
335
+ // Idempotency: skip if edit content already exists in file
336
+ if (edit.content && updatedContent.includes(edit.content)) {
337
+ continue;
338
+ }
339
+ const header = `## ${edit.section}`;
340
+ if (updatedContent.includes(header)) {
341
+ updatedContent = updatedContent.replace(header, `${header}\n${edit.content ?? ''}`);
342
+ }
343
+ else {
344
+ updatedContent += `\n\n${header}\n${edit.content ?? ''}`;
345
+ }
346
+ }
347
+ else if (edit.operation === 'DELETE') {
348
+ if (edit.content) {
349
+ const match = findFuzzyMatch(updatedContent, edit.content);
350
+ if (match) {
351
+ updatedContent = updatedContent.replace(match, '');
352
+ }
353
+ else {
354
+ console.warn(`[sync-daemon] [DELETE] Pattern not found in ${filename}:`, edit.content.slice(0, 100));
355
+ }
356
+ }
357
+ }
358
+ else if (edit.operation === 'REPLACE') {
359
+ if (edit.target) {
360
+ const match = findFuzzyMatch(updatedContent, edit.target);
361
+ if (match) {
362
+ updatedContent = updatedContent.replace(match, edit.content ?? '');
363
+ }
364
+ else {
365
+ console.warn(`[sync-daemon] [REPLACE] Target pattern not found in ${filename}:`, edit.target.slice(0, 100));
366
+ }
367
+ }
368
+ }
369
+ }
370
+ try {
371
+ await atomicWrite(filePath, updatedContent, bypassEnforcementTier);
372
+ console.log(`[sync-daemon] Applied SkillOpt config edits to ${filename} (suggestion: ${applied.suggestionId})`);
373
+ }
374
+ catch (err) {
375
+ console.warn(`[sync-daemon] Failed to apply config edits to ${filename}:`, err);
376
+ }
377
+ }
378
+ }
379
+ // ─── Formatters ──────────────────────────────────────────────────────
380
+ /** Standard file header injected at the top of every auto-generated file. */
381
+ function fileHeader() {
382
+ return [
383
+ '# Intutic Governance Rules (auto-generated)',
384
+ '# DO NOT EDIT — managed by intutic sync daemon',
385
+ `# Last sync: ${newIso()}`,
386
+ '',
387
+ '',
388
+ ].join('\n');
389
+ }
390
+ /**
391
+ * Format SOP content for a specific harness type.
392
+ *
393
+ * Each harness has a distinct format:
394
+ * - Cursor / Claude Code / Windsurf → Markdown with `---` separators
395
+ * - Antigravity → JSON with `customInstructions` field
396
+ * - Aider → YAML with `extra-instructions` field
397
+ * - OpenHands → TOML with `[intutic]` section
398
+ * - Codex → `.env.intutic` with proxy URL vars
399
+ */
400
+ function formatContent(harness, sops, proxyUrl) {
401
+ switch (harness) {
402
+ case 'cursor':
403
+ case 'claude-code':
404
+ case 'windsurf':
405
+ case 'github-copilot':
406
+ return formatMarkdown(sops);
407
+ case 'antigravity':
408
+ return formatAntigravity(sops);
409
+ case 'aider':
410
+ return formatAider(sops);
411
+ case 'openhands':
412
+ return formatOpenHands(sops);
413
+ case 'codex':
414
+ return formatCodex(sops, proxyUrl);
415
+ default:
416
+ return formatMarkdown(sops);
417
+ }
418
+ }
419
+ /** Cursor / Claude Code / Windsurf: Markdown with `---` separators. */
420
+ function formatMarkdown(sops) {
421
+ const header = fileHeader();
422
+ const sections = sops.map((sop) => {
423
+ // Hybrid approach: full SOP content + sop:// pointer comment for traceability
424
+ const ref = sop.sopRef ? `\n${sop.sopRef}` : '';
425
+ return [`## ${sop.title}`, '', sop.content + ref].join('\n');
426
+ });
427
+ return header + sections.join('\n\n---\n\n') + '\n';
428
+ }
429
+ /** Antigravity: JSON with `customInstructions` field. */
430
+ function formatAntigravity(sops) {
431
+ const combinedContent = sops
432
+ .map((sop) => `## ${sop.title}\n\n${sop.content}`)
433
+ .join('\n\n---\n\n');
434
+ const payload = {
435
+ _comment: 'Intutic Governance Rules (auto-generated) — DO NOT EDIT',
436
+ _lastSync: newIso(),
437
+ customInstructions: combinedContent,
438
+ };
439
+ return JSON.stringify(payload, null, 2) + '\n';
440
+ }
441
+ /** Aider: YAML with `extra-instructions` field. */
442
+ function formatAider(sops) {
443
+ const header = fileHeader();
444
+ const combinedContent = sops
445
+ .map((sop) => `## ${sop.title}\n\n${sop.content}`)
446
+ .join('\n\n---\n\n');
447
+ // YAML multiline block scalar using `|`
448
+ const indented = combinedContent
449
+ .split('\n')
450
+ .map((line) => ` ${line}`)
451
+ .join('\n');
452
+ return header + `extra-instructions: |\n${indented}\n`;
453
+ }
454
+ /** OpenHands: TOML with `[intutic]` section. */
455
+ function formatOpenHands(sops) {
456
+ const header = fileHeader();
457
+ const combinedContent = sops
458
+ .map((sop) => `## ${sop.title}\n\n${sop.content}`)
459
+ .join('\n\n---\n\n');
460
+ // TOML multiline basic string uses triple quotes
461
+ const escaped = combinedContent
462
+ .replace(/\\/g, '\\\\')
463
+ .replace(/"""/g, '\\"\\"\\"');
464
+ return (header +
465
+ `[intutic]\n` +
466
+ `last_sync = "${newIso()}"\n` +
467
+ `governance_rules = """\n${escaped}\n"""\n`);
468
+ }
469
+ /** Codex: `.env.intutic` with proxy URL vars. */
470
+ function formatCodex(sops, proxyUrl) {
471
+ const header = fileHeader();
472
+ const sopIds = sops.map((sop) => sop.sopId).join(',');
473
+ return (header +
474
+ `INTUTIC_PROXY_URL=${proxyUrl}\n` +
475
+ `INTUTIC_SOP_IDS=${sopIds}\n` +
476
+ `INTUTIC_LAST_SYNC=${newIso()}\n`);
477
+ }
478
+ // ─── Atomic file write ───────────────────────────────────────────────
479
+ /**
480
+ * Write content to a file atomically.
481
+ *
482
+ * Writes to a `.tmp` sibling first, then renames to the target path.
483
+ * This prevents partial/corrupt files if the process is interrupted mid-write.
484
+ *
485
+ * If bypassEnforcementTier === 'immutable', clears the macOS user-immutable
486
+ * flag before writing and re-sets it after (WS-5 Q3).
487
+ */
488
+ async function atomicWrite(filePath, content, bypassEnforcementTier) {
489
+ const dir = node_path.dirname(filePath);
490
+ await node_fs.mkdir(dir, { recursive: true });
491
+ // Clear immutable flag before writing (macOS only, opt-in)
492
+ if (bypassEnforcementTier === 'immutable') {
493
+ await clearImmutable(filePath);
494
+ }
495
+ const tmpPath = `${filePath}.tmp`;
496
+ await node_fs.writeFile(tmpPath, content, 'utf-8');
497
+ await node_fs.rename(tmpPath, filePath);
498
+ // Re-set immutable flag after writing (macOS only, opt-in)
499
+ if (bypassEnforcementTier === 'immutable') {
500
+ await setImmutable(filePath);
501
+ }
502
+ }
503
+ //# sourceMappingURL=configWriter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configWriter.js","sourceRoot":"","sources":["../src/configWriter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * aiderConfigMerger.ts — Safe YAML merge for .aider.conf.yml.
3
+ *
4
+ * Reads any existing .aider.conf.yml, STRIPS dangerous auto-exec keys
5
+ * (test-cmd, lint-cmd, auto-test, auto-lint), merges in Intutic governance
6
+ * keys (openai-api-base, anthropic-api-base), and writes back atomically.
7
+ *
8
+ * Each strip emits a governance_config_sanitized log entry visible in
9
+ * the control plane audit feed.
10
+ *
11
+ * LLD #14 — Phase 3 cross-harness defence
12
+ * HLD §3.14 — Three-Tier Defense Cascade
13
+ *
14
+ * @module
15
+ */
16
+ /**
17
+ * Merge Intutic governance settings into .aider.conf.yml.
18
+ *
19
+ * Preserves all user keys EXCEPT the suppressed auto-exec keys.
20
+ * Adds/updates openai-api-base and anthropic-api-base.
21
+ *
22
+ * @param configPath - Absolute path to .aider.conf.yml
23
+ * @param proxyUrl - Intutic proxy URL
24
+ * @param sopsText - Optional SOP instructions for extra-instructions field
25
+ */
26
+ export declare function mergeAiderConfig(configPath: string, proxyUrl: string, sopsText?: string): Promise<void>;
27
+ //# sourceMappingURL=aiderConfigMerger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aiderConfigMerger.d.ts","sourceRoot":"","sources":["../../src/harness/aiderConfigMerger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA0EH;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAmDf"}