@intutic/sync-daemon 2.1.0 → 2.3.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/README.md +1 -1
- package/dist/agentReporter.d.ts +24 -11
- package/dist/agentReporter.d.ts.map +1 -1
- package/dist/agentReporter.js +20 -13
- package/dist/agentReporter.js.map +1 -1
- package/dist/configReader.d.ts +45 -25
- package/dist/configReader.d.ts.map +1 -1
- package/dist/configReader.js +70 -46
- package/dist/configReader.js.map +1 -1
- package/dist/configWriter.d.ts +32 -45
- package/dist/configWriter.d.ts.map +1 -1
- package/dist/configWriter.js +52 -686
- package/dist/configWriter.js.map +1 -1
- package/dist/disconnect/harnesses.d.ts +29 -0
- package/dist/disconnect/harnesses.d.ts.map +1 -0
- package/dist/disconnect/harnesses.js +805 -0
- package/dist/disconnect/harnesses.js.map +1 -0
- package/dist/disconnect/index.d.ts +25 -0
- package/dist/disconnect/index.d.ts.map +1 -0
- package/dist/disconnect/index.js +92 -0
- package/dist/disconnect/index.js.map +1 -0
- package/dist/disconnect/mcp.d.ts +81 -0
- package/dist/disconnect/mcp.d.ts.map +1 -0
- package/dist/disconnect/mcp.js +354 -0
- package/dist/disconnect/mcp.js.map +1 -0
- package/dist/disconnect/originals.d.ts +88 -0
- package/dist/disconnect/originals.d.ts.map +1 -0
- package/dist/disconnect/originals.js +257 -0
- package/dist/disconnect/originals.js.map +1 -0
- package/dist/disconnect/plan.d.ts +175 -0
- package/dist/disconnect/plan.d.ts.map +1 -0
- package/dist/disconnect/plan.js +580 -0
- package/dist/disconnect/plan.js.map +1 -0
- package/dist/disconnect/recognise.d.ts +43 -0
- package/dist/disconnect/recognise.d.ts.map +1 -0
- package/dist/disconnect/recognise.js +108 -0
- package/dist/disconnect/recognise.js.map +1 -0
- package/dist/disconnect/tomlLines.d.ts +39 -0
- package/dist/disconnect/tomlLines.d.ts.map +1 -0
- package/dist/disconnect/tomlLines.js +105 -0
- package/dist/disconnect/tomlLines.js.map +1 -0
- package/dist/harness/aiderConfigMerger.d.ts +29 -8
- package/dist/harness/aiderConfigMerger.d.ts.map +1 -1
- package/dist/harness/aiderConfigMerger.js +63 -12
- package/dist/harness/aiderConfigMerger.js.map +1 -1
- package/dist/harness/antigravityCliHooks.d.ts +61 -0
- package/dist/harness/antigravityCliHooks.d.ts.map +1 -0
- package/dist/harness/antigravityCliHooks.js +207 -0
- package/dist/harness/antigravityCliHooks.js.map +1 -0
- package/dist/harness/antigravityHooks.d.ts +12 -2
- package/dist/harness/antigravityHooks.d.ts.map +1 -1
- package/dist/harness/antigravityHooks.js +38 -16
- package/dist/harness/antigravityHooks.js.map +1 -1
- package/dist/harness/antigravityProducts.d.ts +40 -0
- package/dist/harness/antigravityProducts.d.ts.map +1 -0
- package/dist/harness/antigravityProducts.js +109 -0
- package/dist/harness/antigravityProducts.js.map +1 -0
- package/dist/harness/claudeAgentsMd.d.ts +29 -0
- package/dist/harness/claudeAgentsMd.d.ts.map +1 -0
- package/dist/harness/claudeAgentsMd.js +80 -0
- package/dist/harness/claudeAgentsMd.js.map +1 -0
- package/dist/harness/claudeCodeHooks.d.ts +6 -6
- package/dist/harness/claudeCodeHooks.d.ts.map +1 -1
- package/dist/harness/claudeCodeHooks.js +115 -28
- package/dist/harness/claudeCodeHooks.js.map +1 -1
- package/dist/harness/claudeProjectApproval.d.ts +53 -0
- package/dist/harness/claudeProjectApproval.d.ts.map +1 -0
- package/dist/harness/claudeProjectApproval.js +159 -0
- package/dist/harness/claudeProjectApproval.js.map +1 -0
- package/dist/harness/clineHooks.d.ts +0 -1
- package/dist/harness/clineHooks.d.ts.map +1 -1
- package/dist/harness/clineHooks.js +13 -4
- package/dist/harness/clineHooks.js.map +1 -1
- package/dist/harness/codexConfigMerger.d.ts.map +1 -1
- package/dist/harness/codexConfigMerger.js +4 -0
- package/dist/harness/codexConfigMerger.js.map +1 -1
- package/dist/harness/codexHooks.d.ts +2 -0
- package/dist/harness/codexHooks.d.ts.map +1 -1
- package/dist/harness/codexHooks.js +15 -4
- package/dist/harness/codexHooks.js.map +1 -1
- package/dist/harness/continueConfigMerger.d.ts.map +1 -1
- package/dist/harness/continueConfigMerger.js +4 -0
- package/dist/harness/continueConfigMerger.js.map +1 -1
- package/dist/harness/cursorHooks.d.ts +5 -2
- package/dist/harness/cursorHooks.d.ts.map +1 -1
- package/dist/harness/cursorHooks.js +12 -3
- package/dist/harness/cursorHooks.js.map +1 -1
- package/dist/harness/dshHooks.d.ts +5 -5
- package/dist/harness/dshHooks.d.ts.map +1 -1
- package/dist/harness/dshHooks.js +12 -5
- package/dist/harness/dshHooks.js.map +1 -1
- package/dist/harness/gateArtifacts.d.ts +35 -0
- package/dist/harness/gateArtifacts.d.ts.map +1 -0
- package/dist/harness/gateArtifacts.js +88 -0
- package/dist/harness/gateArtifacts.js.map +1 -0
- package/dist/harness/gateBody.d.ts +195 -69
- package/dist/harness/gateBody.d.ts.map +1 -1
- package/dist/harness/gateBody.js +847 -182
- package/dist/harness/gateBody.js.map +1 -1
- package/dist/harness/gateSightings.d.ts +47 -0
- package/dist/harness/gateSightings.d.ts.map +1 -0
- package/dist/harness/gateSightings.js +159 -0
- package/dist/harness/gateSightings.js.map +1 -0
- package/dist/harness/githubCopilotHooks.d.ts.map +1 -1
- package/dist/harness/githubCopilotHooks.js +11 -10
- package/dist/harness/githubCopilotHooks.js.map +1 -1
- package/dist/harness/gooseHardener.d.ts +0 -1
- package/dist/harness/gooseHardener.d.ts.map +1 -1
- package/dist/harness/gooseHardener.js +1 -1
- package/dist/harness/gooseHardener.js.map +1 -1
- package/dist/harness/gooseHooks.d.ts +29 -1
- package/dist/harness/gooseHooks.d.ts.map +1 -1
- package/dist/harness/gooseHooks.js +107 -69
- package/dist/harness/gooseHooks.js.map +1 -1
- package/dist/harness/grokHooks.d.ts +2 -2
- package/dist/harness/grokHooks.d.ts.map +1 -1
- package/dist/harness/grokHooks.js +20 -18
- package/dist/harness/grokHooks.js.map +1 -1
- package/dist/harness/hermesHooks.d.ts +18 -8
- package/dist/harness/hermesHooks.d.ts.map +1 -1
- package/dist/harness/hermesHooks.js +55 -19
- package/dist/harness/hermesHooks.js.map +1 -1
- package/dist/harness/holdRedaction.d.ts +4 -1
- package/dist/harness/holdRedaction.d.ts.map +1 -1
- package/dist/harness/holdRedaction.js +32 -8
- package/dist/harness/holdRedaction.js.map +1 -1
- package/dist/harness/jetbrainsXmlConfig.d.ts +20 -0
- package/dist/harness/jetbrainsXmlConfig.d.ts.map +1 -1
- package/dist/harness/jetbrainsXmlConfig.js +39 -18
- package/dist/harness/jetbrainsXmlConfig.js.map +1 -1
- package/dist/harness/mcpAutoWrite.d.ts +62 -25
- package/dist/harness/mcpAutoWrite.d.ts.map +1 -1
- package/dist/harness/mcpAutoWrite.js +406 -95
- package/dist/harness/mcpAutoWrite.js.map +1 -1
- package/dist/harness/museHooks.d.ts +3 -3
- package/dist/harness/museHooks.d.ts.map +1 -1
- package/dist/harness/museHooks.js +15 -7
- package/dist/harness/museHooks.js.map +1 -1
- package/dist/harness/n8nHooks.d.ts +0 -1
- package/dist/harness/n8nHooks.d.ts.map +1 -1
- package/dist/harness/n8nHooks.js +4 -1
- package/dist/harness/n8nHooks.js.map +1 -1
- package/dist/harness/openCodeHooks.d.ts +2 -2
- package/dist/harness/openCodeHooks.d.ts.map +1 -1
- package/dist/harness/openCodeHooks.js +9 -8
- package/dist/harness/openCodeHooks.js.map +1 -1
- package/dist/harness/openWebuiHooks.d.ts +0 -1
- package/dist/harness/openWebuiHooks.d.ts.map +1 -1
- package/dist/harness/openWebuiHooks.js +11 -3
- package/dist/harness/openWebuiHooks.js.map +1 -1
- package/dist/harness/openclawHooks.d.ts +75 -18
- package/dist/harness/openclawHooks.d.ts.map +1 -1
- package/dist/harness/openclawHooks.js +214 -160
- package/dist/harness/openclawHooks.js.map +1 -1
- package/dist/harness/openhandsHooks.d.ts +37 -11
- package/dist/harness/openhandsHooks.d.ts.map +1 -1
- package/dist/harness/openhandsHooks.js +148 -97
- package/dist/harness/openhandsHooks.js.map +1 -1
- package/dist/harness/piHooks.d.ts +52 -17
- package/dist/harness/piHooks.d.ts.map +1 -1
- package/dist/harness/piHooks.js +177 -163
- package/dist/harness/piHooks.js.map +1 -1
- package/dist/harness/protectedPaths.d.ts +107 -25
- package/dist/harness/protectedPaths.d.ts.map +1 -1
- package/dist/harness/protectedPaths.js +342 -48
- package/dist/harness/protectedPaths.js.map +1 -1
- package/dist/harness/rulesSection.d.ts +62 -0
- package/dist/harness/rulesSection.d.ts.map +1 -0
- package/dist/harness/rulesSection.js +145 -0
- package/dist/harness/rulesSection.js.map +1 -0
- package/dist/harness/windsurfHooks.d.ts +18 -3
- package/dist/harness/windsurfHooks.d.ts.map +1 -1
- package/dist/harness/windsurfHooks.js +41 -8
- package/dist/harness/windsurfHooks.js.map +1 -1
- package/dist/harness/windsurfJetBrainsProxy.d.ts +1 -1
- package/dist/harness/windsurfJetBrainsProxy.d.ts.map +1 -1
- package/dist/harness/windsurfJetBrainsProxy.js +5 -1
- package/dist/harness/windsurfJetBrainsProxy.js.map +1 -1
- package/dist/index.d.ts +21 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -19
- package/dist/index.js.map +1 -1
- package/dist/inventory.d.ts +53 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +133 -0
- package/dist/inventory.js.map +1 -0
- package/dist/lib/complianceProbes.d.ts +2 -1
- package/dist/lib/complianceProbes.d.ts.map +1 -1
- package/dist/lib/complianceProbes.js +1 -1
- package/dist/lib/complianceProbes.js.map +1 -1
- package/dist/lib/decisionsDigest.d.ts +35 -17
- package/dist/lib/decisionsDigest.d.ts.map +1 -1
- package/dist/lib/decisionsDigest.js +106 -47
- package/dist/lib/decisionsDigest.js.map +1 -1
- package/dist/lib/egressPolicy.d.ts +2 -2
- package/dist/lib/egressPolicy.js +2 -2
- package/dist/lib/mcpRegistryPy.d.ts +11 -0
- package/dist/lib/mcpRegistryPy.d.ts.map +1 -0
- package/dist/lib/mcpRegistryPy.js +173 -0
- package/dist/lib/mcpRegistryPy.js.map +1 -0
- package/dist/lib/phrasesPy.d.ts +11 -0
- package/dist/lib/phrasesPy.d.ts.map +1 -0
- package/dist/lib/phrasesPy.js +351 -0
- package/dist/lib/phrasesPy.js.map +1 -0
- package/dist/lib/policySnapshot.d.ts +63 -9
- package/dist/lib/policySnapshot.d.ts.map +1 -1
- package/dist/lib/policySnapshot.js +269 -45
- package/dist/lib/policySnapshot.js.map +1 -1
- package/dist/lib/processPoller.d.ts.map +1 -1
- package/dist/lib/processPoller.js +9 -2
- package/dist/lib/processPoller.js.map +1 -1
- package/dist/lib/regexLinearity.d.ts +43 -0
- package/dist/lib/regexLinearity.d.ts.map +1 -0
- package/dist/lib/regexLinearity.js +275 -0
- package/dist/lib/regexLinearity.js.map +1 -0
- package/dist/lib/runtimeEnv.d.ts +1 -3
- package/dist/lib/runtimeEnv.d.ts.map +1 -1
- package/dist/lib/runtimeEnv.js +0 -2
- package/dist/lib/runtimeEnv.js.map +1 -1
- package/dist/lib/sequencePy.d.ts +10 -0
- package/dist/lib/sequencePy.d.ts.map +1 -0
- package/dist/lib/sequencePy.js +102 -0
- package/dist/lib/sequencePy.js.map +1 -0
- package/dist/sessionReporter.d.ts +18 -12
- package/dist/sessionReporter.d.ts.map +1 -1
- package/dist/sessionReporter.js +37 -24
- package/dist/sessionReporter.js.map +1 -1
- package/dist/skillWriter.d.ts +23 -5
- package/dist/skillWriter.d.ts.map +1 -1
- package/dist/skillWriter.js +159 -16
- package/dist/skillWriter.js.map +1 -1
- package/dist/syncCycle.d.ts +142 -0
- package/dist/syncCycle.d.ts.map +1 -0
- package/dist/syncCycle.js +327 -0
- package/dist/syncCycle.js.map +1 -0
- package/dist/trajectoryMonitor.d.ts +2 -4
- package/dist/trajectoryMonitor.d.ts.map +1 -1
- package/dist/trajectoryMonitor.js +2 -5
- package/dist/trajectoryMonitor.js.map +1 -1
- package/dist/watcher/driftWatcher.d.ts +0 -1
- package/dist/watcher/driftWatcher.d.ts.map +1 -1
- package/dist/watcher/driftWatcher.js +1 -2
- package/dist/watcher/driftWatcher.js.map +1 -1
- package/dist/watcher/settingsGuard.d.ts +36 -7
- package/dist/watcher/settingsGuard.d.ts.map +1 -1
- package/dist/watcher/settingsGuard.js +397 -60
- package/dist/watcher/settingsGuard.js.map +1 -1
- package/dist/watcher/vscodeHookSettings.d.ts +30 -0
- package/dist/watcher/vscodeHookSettings.d.ts.map +1 -0
- package/dist/watcher/vscodeHookSettings.js +170 -0
- package/dist/watcher/vscodeHookSettings.js.map +1 -0
- package/dist/wsClient.d.ts +0 -1
- package/dist/wsClient.d.ts.map +1 -1
- package/dist/wsClient.js +0 -1
- package/dist/wsClient.js.map +1 -1
- package/package.json +5 -5
- package/dist/harness/claudeDesktopHooks.d.ts +0 -30
- package/dist/harness/claudeDesktopHooks.d.ts.map +0 -1
- package/dist/harness/claudeDesktopHooks.js +0 -254
- package/dist/harness/claudeDesktopHooks.js.map +0 -1
- package/dist/harness/continueHooks.d.ts +0 -63
- package/dist/harness/continueHooks.d.ts.map +0 -1
- package/dist/harness/continueHooks.js +0 -247
- package/dist/harness/continueHooks.js.map +0 -1
- package/dist/harness/gateKind.d.ts +0 -164
- package/dist/harness/gateKind.d.ts.map +0 -1
- package/dist/harness/gateKind.js +0 -144
- package/dist/harness/gateKind.js.map +0 -1
- package/dist/harness/rooCodeHooks.d.ts +0 -31
- package/dist/harness/rooCodeHooks.d.ts.map +0 -1
- package/dist/harness/rooCodeHooks.js +0 -286
- package/dist/harness/rooCodeHooks.js.map +0 -1
- package/dist/hashReporter.d.ts +0 -33
- package/dist/hashReporter.d.ts.map +0 -1
- package/dist/hashReporter.js +0 -69
- package/dist/hashReporter.js.map +0 -1
- package/dist/integrityStore.d.ts +0 -35
- package/dist/integrityStore.d.ts.map +0 -1
- package/dist/integrityStore.js +0 -71
- package/dist/integrityStore.js.map +0 -1
- package/dist/lib/gitWorktrees.d.ts +0 -140
- package/dist/lib/gitWorktrees.d.ts.map +0 -1
- package/dist/lib/gitWorktrees.js +0 -191
- package/dist/lib/gitWorktrees.js.map +0 -1
- package/dist/syncLoop.d.ts +0 -172
- package/dist/syncLoop.d.ts.map +0 -1
- package/dist/syncLoop.js +0 -878
- package/dist/syncLoop.js.map +0 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* claudeProjectApproval.ts — which of a repo's `.mcp.json` servers Claude Code
|
|
3
|
+
* would start, decided the way Claude Code decides it.
|
|
4
|
+
*
|
|
5
|
+
* The sync daemon governs project-scope servers through wrapped local-scope
|
|
6
|
+
* copies (mcpAutoWrite.ts's `shadowProjectServers`), and a local-scope server
|
|
7
|
+
* starts without Claude Code's project-server approval. So a copy may exist
|
|
8
|
+
* only for a server Claude Code would itself start; anything looser would let
|
|
9
|
+
* a cloned repository approve its own server and have us wrap and start it.
|
|
10
|
+
*
|
|
11
|
+
* Claude Code's rules (https://code.claude.com/docs/en/mcp, "Project server
|
|
12
|
+
* approvals and workspace trust"):
|
|
13
|
+
*
|
|
14
|
+
* - Approvals (`enableAllProjectMcpServers`, `enabledMcpjsonServers`) from
|
|
15
|
+
* the user's `~/.claude/settings.json`, managed settings and the user's own
|
|
16
|
+
* record in `~/.claude.json` always apply.
|
|
17
|
+
* - Approvals from the project's `.claude/settings.json` and
|
|
18
|
+
* `.claude/settings.local.json` apply only once the folder is trusted.
|
|
19
|
+
* Trust is `projects[<repository root>].hasTrustDialogAccepted` in
|
|
20
|
+
* `~/.claude.json` — keyed on the git root, or the main checkout's root for
|
|
21
|
+
* a worktree, or the folder itself outside a repository. Anything we cannot
|
|
22
|
+
* confirm counts as untrusted.
|
|
23
|
+
* - `disabledMcpjsonServers` in any of those files rejects the server,
|
|
24
|
+
* trusted folder or not.
|
|
25
|
+
*
|
|
26
|
+
* Managed policy can also arrive through MDM (a macOS configuration profile)
|
|
27
|
+
* or the Windows registry, neither of which this module reads. Where one may
|
|
28
|
+
* be present, no project server is approved here: missing an organization's
|
|
29
|
+
* disable is the one mistake this check must not make.
|
|
30
|
+
*
|
|
31
|
+
* @module
|
|
32
|
+
*/
|
|
33
|
+
import * as node_fs from 'node:fs/promises';
|
|
34
|
+
import * as node_path from 'node:path';
|
|
35
|
+
import * as node_os from 'node:os';
|
|
36
|
+
import { existsSync, realpathSync } from 'node:fs';
|
|
37
|
+
import { execFileSync } from 'node:child_process';
|
|
38
|
+
function defaultManagedDir(platform) {
|
|
39
|
+
if (platform === 'darwin')
|
|
40
|
+
return '/Library/Application Support/ClaudeCode';
|
|
41
|
+
if (platform === 'win32')
|
|
42
|
+
return 'C:\\Program Files\\ClaudeCode';
|
|
43
|
+
return '/etc/claude-code';
|
|
44
|
+
}
|
|
45
|
+
function defaultMdmProfiles(platform) {
|
|
46
|
+
if (platform !== 'darwin')
|
|
47
|
+
return [];
|
|
48
|
+
const user = (() => {
|
|
49
|
+
try {
|
|
50
|
+
return node_os.userInfo().username;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return '';
|
|
54
|
+
}
|
|
55
|
+
})();
|
|
56
|
+
return [
|
|
57
|
+
'/Library/Managed Preferences/com.anthropic.claudecode.plist',
|
|
58
|
+
...(user ? [`/Library/Managed Preferences/${user}/com.anthropic.claudecode.plist`] : []),
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
async function readObject(file) {
|
|
62
|
+
try {
|
|
63
|
+
const parsed = JSON.parse(await node_fs.readFile(file, 'utf-8'));
|
|
64
|
+
return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** The managed-settings documents: `managed-settings.json` and the `managed-settings.d/` drop-ins. */
|
|
71
|
+
async function readManaged(dir) {
|
|
72
|
+
const out = [];
|
|
73
|
+
const main = await readObject(node_path.join(dir, 'managed-settings.json'));
|
|
74
|
+
if (main)
|
|
75
|
+
out.push(main);
|
|
76
|
+
try {
|
|
77
|
+
const dropIns = (await node_fs.readdir(node_path.join(dir, 'managed-settings.d'))).filter((f) => f.endsWith('.json')).sort();
|
|
78
|
+
for (const f of dropIns) {
|
|
79
|
+
const doc = await readObject(node_path.join(dir, 'managed-settings.d', f));
|
|
80
|
+
if (doc)
|
|
81
|
+
out.push(doc);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// No drop-in directory.
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The path(s) Claude Code may key this folder's trust on: the repository root
|
|
91
|
+
* (the main checkout's root for a worktree), or the folder itself outside a
|
|
92
|
+
* repository — each as given and as its real path, since `projects` keys are
|
|
93
|
+
* whatever path Claude Code was started with.
|
|
94
|
+
*/
|
|
95
|
+
function trustKeys(workspaceRoot) {
|
|
96
|
+
const keys = new Set([workspaceRoot]);
|
|
97
|
+
try {
|
|
98
|
+
const common = execFileSync('git', ['-C', workspaceRoot, 'rev-parse', '--path-format=absolute', '--git-common-dir'], {
|
|
99
|
+
encoding: 'utf-8',
|
|
100
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
101
|
+
timeout: 2000,
|
|
102
|
+
}).trim();
|
|
103
|
+
if (common)
|
|
104
|
+
keys.add(node_path.dirname(common));
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Not a repository, or no git: the folder itself is the key.
|
|
108
|
+
}
|
|
109
|
+
for (const k of [...keys]) {
|
|
110
|
+
try {
|
|
111
|
+
keys.add(realpathSync(k));
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// A key that does not resolve stays as given.
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return [...keys];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Decides which project servers Claude Code would start for `workspaceRoot`,
|
|
121
|
+
* given the parsed `~/.claude.json` (`claudeState`).
|
|
122
|
+
*/
|
|
123
|
+
export async function projectServerApproval(workspaceRoot, claudeState, env = {}) {
|
|
124
|
+
const platform = env.platform ?? process.platform;
|
|
125
|
+
const mdmProfiles = env.mdmProfiles ?? defaultMdmProfiles(platform);
|
|
126
|
+
if (platform === 'win32' || mdmProfiles.some((p) => existsSync(p))) {
|
|
127
|
+
return {
|
|
128
|
+
approved: () => false,
|
|
129
|
+
blockedReason: 'Claude Code managed policy may be deployed through MDM or the registry, which Intutic cannot read, so no project server is copied',
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const projectEntry = (key) => {
|
|
133
|
+
const entry = claudeState.projects?.[key];
|
|
134
|
+
return entry !== null && typeof entry === 'object' && !Array.isArray(entry) ? entry : {};
|
|
135
|
+
};
|
|
136
|
+
const keys = trustKeys(workspaceRoot);
|
|
137
|
+
const trusted = keys.some((k) => projectEntry(k).hasTrustDialogAccepted === true);
|
|
138
|
+
const userSources = [
|
|
139
|
+
projectEntry(workspaceRoot),
|
|
140
|
+
...(await readManaged(env.managedDir ?? defaultManagedDir(platform))),
|
|
141
|
+
];
|
|
142
|
+
const userSettings = await readObject(node_path.join(node_os.homedir(), '.claude', 'settings.json'));
|
|
143
|
+
if (userSettings)
|
|
144
|
+
userSources.push(userSettings);
|
|
145
|
+
const projectSources = [];
|
|
146
|
+
for (const file of ['settings.json', 'settings.local.json']) {
|
|
147
|
+
const doc = await readObject(node_path.join(workspaceRoot, '.claude', file));
|
|
148
|
+
if (doc)
|
|
149
|
+
projectSources.push(doc);
|
|
150
|
+
}
|
|
151
|
+
const names = (v) => (Array.isArray(v) ? v.filter((n) => typeof n === 'string') : []);
|
|
152
|
+
const approving = trusted ? [...userSources, ...projectSources] : userSources;
|
|
153
|
+
const all = approving.some((src) => src.enableAllProjectMcpServers === true);
|
|
154
|
+
const enabled = new Set(approving.flatMap((src) => names(src.enabledMcpjsonServers)));
|
|
155
|
+
// A disable counts from every file, the committed ones included.
|
|
156
|
+
const disabled = new Set([...userSources, ...projectSources].flatMap((src) => names(src.disabledMcpjsonServers)));
|
|
157
|
+
return { approved: (name) => !disabled.has(name) && (all || enabled.has(name)) };
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=claudeProjectApproval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudeProjectApproval.js","sourceRoot":"","sources":["../../src/harness/claudeProjectApproval.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clineHooks.d.ts","sourceRoot":"","sources":["../../src/harness/clineHooks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"clineHooks.d.ts","sourceRoot":"","sources":["../../src/harness/clineHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAiBH;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAuBvF;AAkBD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,WAAW,SAAK,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0KxB"}
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
* product wrote, and leaves a flat `.clinerules` the user wrote alone — in
|
|
28
28
|
* that case no gate can be installed and a warning says why.
|
|
29
29
|
*
|
|
30
|
-
* LLD #14 — Phase 3 cross-harness defence
|
|
31
30
|
* HLD §3.14 — Three-Tier Defense Cascade
|
|
32
31
|
*
|
|
33
32
|
* @module
|
|
@@ -35,6 +34,7 @@
|
|
|
35
34
|
import * as fs from 'node:fs/promises';
|
|
36
35
|
import * as path from 'node:path';
|
|
37
36
|
import { createLogger } from '@intutic/logger';
|
|
37
|
+
import { keepOriginal, noteWritten } from '../disconnect/originals.js';
|
|
38
38
|
import { newIso } from '@intutic/id';
|
|
39
39
|
import { emitJsGate, emitJsFailClosedPrelude, REVIEW_REQUESTS_BASENAME } from './gateBody.js';
|
|
40
40
|
const log = createLogger('sync-cline-hooks');
|
|
@@ -98,10 +98,13 @@ async function removeLegacyRegistration(workspaceRoot) {
|
|
|
98
98
|
*/
|
|
99
99
|
export async function writeClineHooks(workspaceRoot, proxyUrl, workspaceId = '') {
|
|
100
100
|
await removeLegacyRegistration(workspaceRoot);
|
|
101
|
-
if (!(await ensureClinerulesDirectory(workspaceRoot)))
|
|
102
|
-
return null;
|
|
103
101
|
const hooksDir = path.join(workspaceRoot, '.clinerules', 'hooks');
|
|
104
102
|
const checkScriptPath = path.join(hooksDir, 'PreToolUse');
|
|
103
|
+
// Kept before `.clinerules` is created, so disconnect knows it made the
|
|
104
|
+
// directory: the gate is installed before any rules file is written.
|
|
105
|
+
await keepOriginal(checkScriptPath, workspaceRoot);
|
|
106
|
+
if (!(await ensureClinerulesDirectory(workspaceRoot)))
|
|
107
|
+
return null;
|
|
105
108
|
await fs.mkdir(hooksDir, { recursive: true });
|
|
106
109
|
try {
|
|
107
110
|
const existing = await fs.readFile(checkScriptPath, 'utf-8');
|
|
@@ -149,9 +152,12 @@ function logEvent(verdict, toolName, reason) {
|
|
|
149
152
|
try {
|
|
150
153
|
const ts = new Date().toISOString();
|
|
151
154
|
const incidentId = crypto.createHash('sha1').update(ts + toolName + _intuticWsId).digest('hex').slice(0, 16);
|
|
155
|
+
// The event's id: random, made once here, and resent with the line it is
|
|
156
|
+
// written into, so the control plane processes the event once.
|
|
157
|
+
const eventId = crypto.randomBytes(16).toString('hex');
|
|
152
158
|
const entry = JSON.stringify({ // Passed through, not collapsed to two values: the advisory tier emits
|
|
153
159
|
// 'tool_flagged', and a ternary here silently recorded it as an allow.
|
|
154
|
-
event: verdict, toolName, reason: reason || '', workspaceId: _intuticWsId, harnessType: 'cline', timestamp: ts, incidentId, ...(_intuticSessionId ? { sessionId: _intuticSessionId } : {}) }) + '\\n';
|
|
160
|
+
event: verdict, toolName, reason: reason || '', workspaceId: _intuticWsId, harnessType: 'cline', timestamp: ts, incidentId, eventId, ...(_intuticSessionId ? { sessionId: _intuticSessionId } : {}) }) + '\\n';
|
|
155
161
|
// mkdir first. This was a bare appendFileSync inside a swallowing catch, so
|
|
156
162
|
// on any machine where nothing else had created ~/.intutic/events the append
|
|
157
163
|
// threw ENOENT and was discarded — every Cline audit line, including blocks,
|
|
@@ -239,6 +245,8 @@ process.stdin.on('end', () => {
|
|
|
239
245
|
process.stdout.write(JSON.stringify({
|
|
240
246
|
cancel: true,
|
|
241
247
|
errorMessage: '[Intutic Governance] Hook error (fail-closed): ' + String(err),
|
|
248
|
+
code: 'GATE_CRASHED',
|
|
249
|
+
ruleId: null,
|
|
242
250
|
}));
|
|
243
251
|
process.exit(0);
|
|
244
252
|
}
|
|
@@ -250,6 +258,7 @@ process.stdin.on('end', () => {
|
|
|
250
258
|
// Executable is what enables the hook: Cline creates new hook files 0644,
|
|
251
259
|
// i.e. toggled off.
|
|
252
260
|
await fs.chmod(checkScriptPath, 0o755);
|
|
261
|
+
await noteWritten(checkScriptPath, workspaceRoot, checkScript);
|
|
253
262
|
log.info({ action: 'cline_hooks_written', path: checkScriptPath }, 'Cline PreToolUse governance hook written');
|
|
254
263
|
return checkScriptPath;
|
|
255
264
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clineHooks.js","sourceRoot":"","sources":["../../src/harness/clineHooks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"clineHooks.js","sourceRoot":"","sources":["../../src/harness/clineHooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codexConfigMerger.d.ts","sourceRoot":"","sources":["../../src/harness/codexConfigMerger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;
|
|
1
|
+
{"version":3,"file":"codexConfigMerger.d.ts","sourceRoot":"","sources":["../../src/harness/codexConfigMerger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AA2BH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuBjF;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA0B5F"}
|
|
@@ -23,8 +23,10 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import * as fs from 'node:fs/promises';
|
|
25
25
|
import * as path from 'node:path';
|
|
26
|
+
import * as os from 'node:os';
|
|
26
27
|
import { parse as parseToml } from 'smol-toml';
|
|
27
28
|
import { createLogger } from '@intutic/logger';
|
|
29
|
+
import { keepOriginal } from '../disconnect/originals.js';
|
|
28
30
|
const log = createLogger('sync-codex-config');
|
|
29
31
|
/** First line of the file the previous adapter wrote over the user's config. */
|
|
30
32
|
const LEGACY_HEADER = '# Intutic proxy config (auto-generated)';
|
|
@@ -91,6 +93,8 @@ export async function mergeCodexConfig(configPath, baseUrl) {
|
|
|
91
93
|
}
|
|
92
94
|
if (next === raw)
|
|
93
95
|
return true;
|
|
96
|
+
// A user-level file: its record lives under the home directory.
|
|
97
|
+
await keepOriginal(configPath, os.homedir());
|
|
94
98
|
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
95
99
|
const tmp = configPath + '.intutic-tmp';
|
|
96
100
|
await fs.writeFile(tmp, next, 'utf-8');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codexConfigMerger.js","sourceRoot":"","sources":["../../src/harness/codexConfigMerger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"codexConfigMerger.js","sourceRoot":"","sources":["../../src/harness/codexConfigMerger.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codexHooks.d.ts","sourceRoot":"","sources":["../../src/harness/codexHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;
|
|
1
|
+
{"version":3,"file":"codexHooks.d.ts","sourceRoot":"","sources":["../../src/harness/codexHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAcH,qEAAqE;AACrE,wBAAgB,YAAY,IAAI,MAAM,CAErC;AA+KD;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,WAAW,SAAK,GACf,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
|
|
@@ -28,10 +28,16 @@ import * as fs from 'node:fs/promises';
|
|
|
28
28
|
import * as path from 'node:path';
|
|
29
29
|
import * as os from 'node:os';
|
|
30
30
|
import { createLogger } from '@intutic/logger';
|
|
31
|
+
import { keepOriginal } from '../disconnect/originals.js';
|
|
31
32
|
import { newIso } from '@intutic/id';
|
|
33
|
+
import { HOOK_TIMEOUT_SECONDS } from '@intutic/shared-types';
|
|
32
34
|
import { emitJsGate, emitJsFailClosedPrelude } from './gateBody.js';
|
|
33
35
|
import { readJsonObjectForMerge } from './jsonMergeTarget.js';
|
|
34
36
|
const log = createLogger('sync-codex-hooks');
|
|
37
|
+
/** Codex's user config directory: `$CODEX_HOME`, else `~/.codex`. */
|
|
38
|
+
export function codexUserDir() {
|
|
39
|
+
return process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
40
|
+
}
|
|
35
41
|
/**
|
|
36
42
|
* The pre-tool gate script — receives Codex's PreToolUse JSON on stdin,
|
|
37
43
|
* exits 0 to allow or 2 to block.
|
|
@@ -72,6 +78,9 @@ function logEvent(verdict, toolName, reason) {
|
|
|
72
78
|
try {
|
|
73
79
|
const ts = new Date().toISOString();
|
|
74
80
|
const incidentId = crypto.createHash('sha1').update(ts + toolName + _intuticWsId).digest('hex').slice(0, 16);
|
|
81
|
+
// The event's id: random, made once here, and resent with the line it is
|
|
82
|
+
// written into, so the control plane processes the event once.
|
|
83
|
+
const eventId = crypto.randomBytes(16).toString('hex');
|
|
75
84
|
const entry = JSON.stringify({
|
|
76
85
|
// Passed through, not collapsed to two values: the advisory tier emits
|
|
77
86
|
// 'tool_flagged', and a ternary here silently recorded it as an allow.
|
|
@@ -81,6 +90,7 @@ function logEvent(verdict, toolName, reason) {
|
|
|
81
90
|
harnessType: 'codex',
|
|
82
91
|
timestamp: ts,
|
|
83
92
|
incidentId,
|
|
93
|
+
eventId,
|
|
84
94
|
...(_intuticSessionId ? { sessionId: _intuticSessionId } : {}),
|
|
85
95
|
}) + '\\n';
|
|
86
96
|
fs.appendFileSync(${JSON.stringify(hookEventsLog)}, entry, { flag: 'a' });
|
|
@@ -182,7 +192,7 @@ async function mergeCodexHooksJson(configPath, hookScriptPath) {
|
|
|
182
192
|
// decides from the arguments, so a tool name nobody anticipated is
|
|
183
193
|
// still evaluated rather than silently unmatched.
|
|
184
194
|
matcher: '.*',
|
|
185
|
-
hooks: [{ type: 'command', command: intuticCmd }],
|
|
195
|
+
hooks: [{ type: 'command', command: intuticCmd, timeout: HOOK_TIMEOUT_SECONDS }],
|
|
186
196
|
},
|
|
187
197
|
],
|
|
188
198
|
},
|
|
@@ -214,12 +224,13 @@ export async function writeCodexHooks(workspaceRoot, proxyUrl, workspaceId = '')
|
|
|
214
224
|
await fs.chmod(hookScriptPath, 0o755);
|
|
215
225
|
// 1. Project-level: <root>/.codex/hooks.json
|
|
216
226
|
const projectCodexDir = path.join(workspaceRoot, '.codex');
|
|
227
|
+
await keepOriginal(path.join(projectCodexDir, 'hooks.json'), workspaceRoot);
|
|
217
228
|
await fs.mkdir(projectCodexDir, { recursive: true });
|
|
218
229
|
await mergeCodexHooksJson(path.join(projectCodexDir, 'hooks.json'), hookScriptPath);
|
|
219
230
|
log.info({ action: 'codex_hooks_written', level: 'project', path: projectCodexDir }, 'Codex project-level hooks written');
|
|
220
|
-
// 2. User-level: $CODEX_HOME/hooks.json
|
|
221
|
-
|
|
222
|
-
|
|
231
|
+
// 2. User-level: $CODEX_HOME/hooks.json.
|
|
232
|
+
const userCodexDir = codexUserDir();
|
|
233
|
+
await keepOriginal(path.join(userCodexDir, 'hooks.json'), workspaceRoot);
|
|
223
234
|
await fs.mkdir(userCodexDir, { recursive: true });
|
|
224
235
|
await mergeCodexHooksJson(path.join(userCodexDir, 'hooks.json'), hookScriptPath);
|
|
225
236
|
log.info({ action: 'codex_hooks_written', level: 'user', path: userCodexDir }, 'Codex user-level hooks written');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codexHooks.js","sourceRoot":"","sources":["../../src/harness/codexHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,MAAM,GAAG,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAA;AAE5C;;;GAGG;AACH,SAAS,eAAe,CAAC,QAAgB,EAAE,aAAqB,EAAE,WAAmB;IACnF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAA;IACzF,OAAO;;;;YAIG,QAAQ;gBACJ,MAAM,EAAE;;EAEtB,uBAAuB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;;;;;;;;;gFASc,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;;;;;;;;;;;EAWzG,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC
|
|
1
|
+
{"version":3,"file":"codexHooks.js","sourceRoot":"","sources":["../../src/harness/codexHooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continueConfigMerger.d.ts","sourceRoot":"","sources":["../../src/harness/continueConfigMerger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;
|
|
1
|
+
{"version":3,"file":"continueConfigMerger.d.ts","sourceRoot":"","sources":["../../src/harness/continueConfigMerger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAcH,wEAAwE;AACxE,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAA;IACd,iEAAiE;IACjE,OAAO,CAAC,EAAE,aAAa,GAAG,WAAW,CAAA;CACtC;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAkBpF;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6B9F"}
|
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import * as fs from 'node:fs/promises';
|
|
24
24
|
import * as path from 'node:path';
|
|
25
|
+
import * as os from 'node:os';
|
|
25
26
|
import { parseDocument, isMap, isSeq } from 'yaml';
|
|
26
27
|
import { createLogger } from '@intutic/logger';
|
|
28
|
+
import { keepOriginal } from '../disconnect/originals.js';
|
|
27
29
|
const log = createLogger('sync-continue-config');
|
|
28
30
|
/** Providers whose wire protocol the proxy serves. */
|
|
29
31
|
const PROXIED_PROVIDERS = new Set(['openai', 'anthropic']);
|
|
@@ -79,6 +81,8 @@ export async function mergeContinueConfig(configPath, apiBase) {
|
|
|
79
81
|
return 0;
|
|
80
82
|
}
|
|
81
83
|
if (result.content !== raw) {
|
|
84
|
+
// A user-level file: its record lives under the home directory.
|
|
85
|
+
await keepOriginal(configPath, os.homedir());
|
|
82
86
|
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
83
87
|
const tmp = configPath + '.intutic-tmp';
|
|
84
88
|
await fs.writeFile(tmp, result.content, 'utf-8');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continueConfigMerger.js","sourceRoot":"","sources":["../../src/harness/continueConfigMerger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,MAAM,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"continueConfigMerger.js","sourceRoot":"","sources":["../../src/harness/continueConfigMerger.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* cursorHooks.ts — Cursor hook injection.
|
|
3
3
|
*
|
|
4
4
|
* Registers the gate in Cursor's hooks.json (schema per cursor.com/docs/agent/
|
|
5
|
-
* hooks: `{version: 1, hooks: {<event>: [{command, matcher?, failClosed?}]}}`)
|
|
5
|
+
* hooks: `{version: 1, hooks: {<event>: [{command, matcher?, timeout?, failClosed?}]}}`)
|
|
6
6
|
* for three events:
|
|
7
7
|
* - `beforeShellExecution` — every shell command;
|
|
8
8
|
* - `beforeMCPExecution` — every MCP tool call;
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* The gate refuses with exit code 2 and allows by printing
|
|
13
13
|
* `{"permission":"allow"}`: with `failClosed: true` Cursor blocks on a hook
|
|
14
14
|
* that crashes, times out or prints nothing, so an allow must be explicit.
|
|
15
|
+
* `timeout` (seconds) is set because Cursor does not state its default, and
|
|
16
|
+
* the gate's deadline is derived from it.
|
|
15
17
|
*
|
|
16
18
|
* Levels: project (`<workspaceRoot>/.cursor/hooks.json`) and user
|
|
17
19
|
* (`~/.cursor/hooks.json`) on every sync; system level
|
|
@@ -19,7 +21,6 @@
|
|
|
19
21
|
* only through `intutic enterprise install`, which needs root. The project and
|
|
20
22
|
* user files are merged — hooks the user registered are kept.
|
|
21
23
|
*
|
|
22
|
-
* LLD #14 — Phase 3 cross-harness defence
|
|
23
24
|
* HLD §3.14 — Three-Tier Defense Cascade
|
|
24
25
|
*
|
|
25
26
|
* @module
|
|
@@ -52,6 +53,8 @@ export declare function buildHooksConfig(hookScriptPath: string): {
|
|
|
52
53
|
export interface CursorHookEntry {
|
|
53
54
|
command: string;
|
|
54
55
|
matcher?: string;
|
|
56
|
+
/** Seconds. */
|
|
57
|
+
timeout?: number;
|
|
55
58
|
failClosed?: boolean;
|
|
56
59
|
}
|
|
57
60
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursorHooks.d.ts","sourceRoot":"","sources":["../../src/harness/cursorHooks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cursorHooks.d.ts","sourceRoot":"","sources":["../../src/harness/cursorHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAqBH;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAEnE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;CAAE,CAUtH;AAED,mDAAmD;AACnD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,eAAe;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBnH;AA0ID;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,WAAW,SAAK,EAChB,gBAAgB,UAAQ,GACvB,OAAO,CAAC,IAAI,CAAC,CA8Cf"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* cursorHooks.ts — Cursor hook injection.
|
|
3
3
|
*
|
|
4
4
|
* Registers the gate in Cursor's hooks.json (schema per cursor.com/docs/agent/
|
|
5
|
-
* hooks: `{version: 1, hooks: {<event>: [{command, matcher?, failClosed?}]}}`)
|
|
5
|
+
* hooks: `{version: 1, hooks: {<event>: [{command, matcher?, timeout?, failClosed?}]}}`)
|
|
6
6
|
* for three events:
|
|
7
7
|
* - `beforeShellExecution` — every shell command;
|
|
8
8
|
* - `beforeMCPExecution` — every MCP tool call;
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* The gate refuses with exit code 2 and allows by printing
|
|
13
13
|
* `{"permission":"allow"}`: with `failClosed: true` Cursor blocks on a hook
|
|
14
14
|
* that crashes, times out or prints nothing, so an allow must be explicit.
|
|
15
|
+
* `timeout` (seconds) is set because Cursor does not state its default, and
|
|
16
|
+
* the gate's deadline is derived from it.
|
|
15
17
|
*
|
|
16
18
|
* Levels: project (`<workspaceRoot>/.cursor/hooks.json`) and user
|
|
17
19
|
* (`~/.cursor/hooks.json`) on every sync; system level
|
|
@@ -19,7 +21,6 @@
|
|
|
19
21
|
* only through `intutic enterprise install`, which needs root. The project and
|
|
20
22
|
* user files are merged — hooks the user registered are kept.
|
|
21
23
|
*
|
|
22
|
-
* LLD #14 — Phase 3 cross-harness defence
|
|
23
24
|
* HLD §3.14 — Three-Tier Defense Cascade
|
|
24
25
|
*
|
|
25
26
|
* @module
|
|
@@ -28,7 +29,9 @@ import * as fs from 'node:fs/promises';
|
|
|
28
29
|
import * as path from 'node:path';
|
|
29
30
|
import * as os from 'node:os';
|
|
30
31
|
import { createLogger } from '@intutic/logger';
|
|
32
|
+
import { keepOriginal } from '../disconnect/originals.js';
|
|
31
33
|
import { newIso } from '@intutic/id';
|
|
34
|
+
import { HOOK_TIMEOUT_SECONDS } from '@intutic/shared-types';
|
|
32
35
|
import { emitJsGate, emitJsFailClosedPrelude } from './gateBody.js';
|
|
33
36
|
import { readJsonObjectForMerge } from './jsonMergeTarget.js';
|
|
34
37
|
const log = createLogger('sync-cursor-hooks');
|
|
@@ -65,7 +68,7 @@ export function buildHooksConfig(hookScriptPath) {
|
|
|
65
68
|
version: 1,
|
|
66
69
|
hooks: Object.fromEntries(HOOK_EVENTS.map(({ event, matcher }) => [
|
|
67
70
|
event,
|
|
68
|
-
[{ command: `node "${hookScriptPath}"`, ...(matcher ? { matcher } : {}), failClosed: true }],
|
|
71
|
+
[{ command: `node "${hookScriptPath}"`, ...(matcher ? { matcher } : {}), timeout: HOOK_TIMEOUT_SECONDS, failClosed: true }],
|
|
69
72
|
])),
|
|
70
73
|
};
|
|
71
74
|
}
|
|
@@ -135,6 +138,9 @@ function logEvent(verdict, toolName, reason) {
|
|
|
135
138
|
try {
|
|
136
139
|
const ts = new Date().toISOString();
|
|
137
140
|
const incidentId = crypto.createHash('sha1').update(ts + toolName + _intuticWsId).digest('hex').slice(0, 16);
|
|
141
|
+
// The event's id: random, made once here, and resent with the line it is
|
|
142
|
+
// written into, so the control plane processes the event once.
|
|
143
|
+
const eventId = crypto.randomBytes(16).toString('hex');
|
|
138
144
|
const entry = JSON.stringify({
|
|
139
145
|
// Passed through, not collapsed to two values: the advisory tier emits
|
|
140
146
|
// 'tool_flagged', and a ternary here silently recorded it as an allow.
|
|
@@ -144,6 +150,7 @@ function logEvent(verdict, toolName, reason) {
|
|
|
144
150
|
harnessType: 'cursor',
|
|
145
151
|
timestamp: ts,
|
|
146
152
|
incidentId,
|
|
153
|
+
eventId,
|
|
147
154
|
...(_intuticSessionId ? { sessionId: _intuticSessionId } : {}),
|
|
148
155
|
}) + '\\n';
|
|
149
156
|
fs.appendFileSync(${JSON.stringify(hookEventsLog)}, entry, { flag: 'a' });
|
|
@@ -250,11 +257,13 @@ export async function writeCursorHooks(workspaceRoot, proxyUrl, workspaceId = ''
|
|
|
250
257
|
await fs.chmod(hookScriptPath, 0o755);
|
|
251
258
|
// 1. Project-level: .cursor/hooks.json
|
|
252
259
|
const projectCursorDir = path.join(workspaceRoot, '.cursor');
|
|
260
|
+
await keepOriginal(path.join(projectCursorDir, 'hooks.json'), workspaceRoot);
|
|
253
261
|
await fs.mkdir(projectCursorDir, { recursive: true });
|
|
254
262
|
await mergeHooksJsonFile(path.join(projectCursorDir, 'hooks.json'), hookScriptPath);
|
|
255
263
|
log.info({ action: 'cursor_hooks_written', level: 'project', path: projectCursorDir }, 'Cursor project-level hooks written');
|
|
256
264
|
// 2. User-level: ~/.cursor/hooks.json
|
|
257
265
|
const userCursorDir = path.join(os.homedir(), '.cursor');
|
|
266
|
+
await keepOriginal(path.join(userCursorDir, 'hooks.json'), workspaceRoot);
|
|
258
267
|
await fs.mkdir(userCursorDir, { recursive: true });
|
|
259
268
|
await mergeHooksJsonFile(path.join(userCursorDir, 'hooks.json'), hookScriptPath);
|
|
260
269
|
log.info({ action: 'cursor_hooks_written', level: 'user', path: userCursorDir }, 'Cursor user-level hooks written');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursorHooks.js","sourceRoot":"","sources":["../../src/harness/cursorHooks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cursorHooks.js","sourceRoot":"","sources":["../../src/harness/cursorHooks.ts"],"names":[],"mappings":"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"}
|