@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
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* gooseHooks.ts — Goose PreToolUse governance plugin injection.
|
|
3
3
|
*
|
|
4
4
|
* Writes the Intutic governance plugin to the Goose plugin directory:
|
|
5
|
+
* ~/.agents/plugins/intutic-governance/plugin.json
|
|
5
6
|
* ~/.agents/plugins/intutic-governance/hooks/hooks.json
|
|
6
7
|
* ~/.agents/plugins/intutic-governance/scripts/intutic-check.sh
|
|
7
8
|
*
|
|
8
9
|
* Also merges the Intutic proxy URL into ~/.config/goose/config.yaml.
|
|
9
10
|
* After writing, calls gooseHardener to apply chmod 444 + immutable flags.
|
|
10
11
|
*
|
|
11
|
-
* LLD #14 — Phase 3 cross-harness defence
|
|
12
12
|
* HLD §3.14 — Three-Tier Defense Cascade
|
|
13
13
|
*
|
|
14
14
|
* @module
|
|
@@ -17,12 +17,48 @@ import * as fs from 'node:fs/promises';
|
|
|
17
17
|
import * as path from 'node:path';
|
|
18
18
|
import * as os from 'node:os';
|
|
19
19
|
import { createLogger } from '@intutic/logger';
|
|
20
|
+
import { keepOriginal, noteWritten } from '../disconnect/originals.js';
|
|
20
21
|
import { newIso } from '@intutic/id';
|
|
21
22
|
import { hardenGoosePlugin, unharden } from './gooseHardener.js';
|
|
22
|
-
import {
|
|
23
|
+
import { HOOK_TIMEOUT_SECONDS } from '@intutic/shared-types';
|
|
24
|
+
import { emitShellGate, SHELL_EXTRACT, emitShellFailClosed, REVIEW_REQUESTS_BASENAME } from './gateBody.js';
|
|
25
|
+
import { parseDocument, isMap, isScalar } from 'yaml';
|
|
23
26
|
const log = createLogger('sync-goose-hooks');
|
|
24
27
|
const PLUGIN_DIR = path.join(os.homedir(), '.agents', 'plugins', 'intutic-governance');
|
|
25
28
|
const GOOSE_CONFIG = path.join(os.homedir(), '.config', 'goose', 'config.yaml');
|
|
29
|
+
/** The plugin manifest Goose identifies the plugin by. */
|
|
30
|
+
export function gooseManifest() {
|
|
31
|
+
return {
|
|
32
|
+
name: 'intutic-governance',
|
|
33
|
+
version: '1.0.0',
|
|
34
|
+
description: 'Intutic governance gate — auto-generated. DO NOT EDIT.',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The plugin's `hooks/hooks.json`, in Goose's schema: each event a list of
|
|
39
|
+
* rules, each rule a list of command actions. Every tool call goes to the
|
|
40
|
+
* gate (no matcher). \`on_failure: "block"\` makes Goose deny a call whose
|
|
41
|
+
* gate fails — times out, crashes, or answers nothing it reads — where the
|
|
42
|
+
* default would run it; \`timeout\` replaces Goose's 30 s default, and the gate
|
|
43
|
+
* refuses at its own deadline inside it. A PostToolUse action cannot block,
|
|
44
|
+
* so it carries neither. The shape used before (\`{PreToolUse: {command,
|
|
45
|
+
* failClosed}}\`) is not one Goose loads: it skipped the file with a warning.
|
|
46
|
+
*/
|
|
47
|
+
export function gooseHooksConfig(scriptPath) {
|
|
48
|
+
const command = shellQuote(scriptPath);
|
|
49
|
+
return {
|
|
50
|
+
_comment: 'Intutic governance plugin — auto-generated. DO NOT EDIT.',
|
|
51
|
+
_lastSync: newIso(),
|
|
52
|
+
hooks: {
|
|
53
|
+
PreToolUse: [{ hooks: [{ type: 'command', command, timeout: HOOK_TIMEOUT_SECONDS, on_failure: 'block' }] }],
|
|
54
|
+
PostToolUse: [{ hooks: [{ type: 'command', command: `${command} --event post`, timeout: HOOK_TIMEOUT_SECONDS }] }],
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** Single-quotes a path for the shell Goose runs a command through. */
|
|
59
|
+
function shellQuote(s) {
|
|
60
|
+
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
61
|
+
}
|
|
26
62
|
/**
|
|
27
63
|
* Write Goose governance plugin and harden it.
|
|
28
64
|
*
|
|
@@ -33,31 +69,23 @@ const GOOSE_CONFIG = path.join(os.homedir(), '.config', 'goose', 'config.yaml');
|
|
|
33
69
|
export async function writeGooseHooks(proxyUrl, workspaceRoot = os.homedir(), workspaceId = '') {
|
|
34
70
|
const hooksDir = path.join(PLUGIN_DIR, 'hooks');
|
|
35
71
|
const scriptsDir = path.join(PLUGIN_DIR, 'scripts');
|
|
72
|
+
await keepOriginal(path.join(PLUGIN_DIR, 'plugin.json'), workspaceRoot);
|
|
73
|
+
await keepOriginal(path.join(hooksDir, 'hooks.json'), workspaceRoot);
|
|
74
|
+
await keepOriginal(path.join(scriptsDir, 'intutic-check.sh'), workspaceRoot);
|
|
36
75
|
await fs.mkdir(hooksDir, { recursive: true });
|
|
37
76
|
await fs.mkdir(scriptsDir, { recursive: true });
|
|
38
|
-
// ── hooks.json
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
command: path.join(scriptsDir, 'intutic-check.sh --event post'),
|
|
51
|
-
failClosed: false,
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
const hooksJsonPath = path.join(hooksDir, 'hooks.json');
|
|
56
|
-
// Unharden before writing (in case we're refreshing an existing install)
|
|
57
|
-
await unharden(hooksJsonPath);
|
|
58
|
-
const tmpHooks = hooksJsonPath + '.intutic-tmp';
|
|
59
|
-
await fs.writeFile(tmpHooks, JSON.stringify(hooksConfig, null, 2) + '\n', 'utf-8');
|
|
60
|
-
await fs.rename(tmpHooks, hooksJsonPath);
|
|
77
|
+
// ── plugin.json + hooks.json ────────────────────────────────────────
|
|
78
|
+
for (const [file, content] of [
|
|
79
|
+
[path.join(PLUGIN_DIR, 'plugin.json'), JSON.stringify(gooseManifest(), null, 2) + '\n'],
|
|
80
|
+
[path.join(hooksDir, 'hooks.json'), JSON.stringify(gooseHooksConfig(path.join(scriptsDir, 'intutic-check.sh')), null, 2) + '\n'],
|
|
81
|
+
]) {
|
|
82
|
+
// Unharden before writing (in case we're refreshing an existing install)
|
|
83
|
+
await unharden(file);
|
|
84
|
+
const tmp = file + '.intutic-tmp';
|
|
85
|
+
await fs.writeFile(tmp, content, 'utf-8');
|
|
86
|
+
await fs.rename(tmp, file);
|
|
87
|
+
await noteWritten(file, workspaceRoot, content);
|
|
88
|
+
}
|
|
61
89
|
// ── intutic-check.sh ─────────────────────────────────────────────────
|
|
62
90
|
const checkScriptPath = path.join(scriptsDir, 'intutic-check.sh');
|
|
63
91
|
await unharden(checkScriptPath);
|
|
@@ -70,7 +98,7 @@ export async function writeGooseHooks(proxyUrl, workspaceRoot = os.homedir(), wo
|
|
|
70
98
|
# Proxy: ${proxyUrl}
|
|
71
99
|
# Generated: ${newIso()}
|
|
72
100
|
set -euo pipefail
|
|
73
|
-
${
|
|
101
|
+
${emitShellFailClosed('goose')}
|
|
74
102
|
EVENT="\${1:-pre}"
|
|
75
103
|
INPUT="\$(cat)"
|
|
76
104
|
${SHELL_EXTRACT}
|
|
@@ -111,7 +139,11 @@ log_event() {
|
|
|
111
139
|
ws="\${ws//\\\\/\\\\\\\\}"; ws="\${ws//\\"/\\\\\\"}"; ws="\${ws//[\$'\\x01'-\$'\\x1f']/ }"
|
|
112
140
|
local ts; ts="\$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
113
141
|
local incident_id; incident_id="\$(printf '%s' "\${ts}\${tool}\${INTUTIC_WORKSPACE_ID}" | sha1sum 2>/dev/null | cut -c1-16 || echo \"\$(date +%s)\")"
|
|
114
|
-
|
|
142
|
+
# The event's id: random, made once here, and resent with the line it is
|
|
143
|
+
# written into, so the control plane processes the event once.
|
|
144
|
+
local event_id; event_id="\$(od -An -N16 -tx1 /dev/urandom 2>/dev/null | tr -d ' \\n' || true)"
|
|
145
|
+
[ -n "\$event_id" ] || event_id="\$(date +%s)\$\$\${RANDOM}\${RANDOM}\${RANDOM}"
|
|
146
|
+
local entry="{\\"event\\":\\"\${verdict}\\",\\"toolName\\":\\"\${tool}\\",\\"reason\\":\\"\${reason}\\",\\"workspaceId\\":\\"\${ws}\\",\\"harnessType\\":\\"goose\\",\\"timestamp\\":\\"\${ts}\\",\\"incidentId\\":\\"\${incident_id}\\",\\"eventId\\":\\"\${event_id}\\"}"
|
|
115
147
|
# Path B: reliable file append
|
|
116
148
|
printf '%s\\n' "\$entry" >> "\$HOOK_EVENTS_LOG" 2>/dev/null || true
|
|
117
149
|
# Path A: fire-and-forget HTTP (non-blocking, near-real-time)
|
|
@@ -133,12 +165,48 @@ exit 0
|
|
|
133
165
|
await fs.writeFile(tmpScript, checkScript, 'utf-8');
|
|
134
166
|
await fs.rename(tmpScript, checkScriptPath);
|
|
135
167
|
await fs.chmod(checkScriptPath, 0o755);
|
|
168
|
+
await noteWritten(checkScriptPath, workspaceRoot, checkScript);
|
|
136
169
|
// Apply immutable flags after writing
|
|
137
170
|
await hardenGoosePlugin(PLUGIN_DIR);
|
|
138
171
|
log.info({ action: 'goose_plugin_written', pluginDir: PLUGIN_DIR }, 'Goose governance plugin written and hardened');
|
|
139
172
|
// ── Merge proxy URL into goose config.yaml ───────────────────────────
|
|
140
173
|
await mergeGooseConfig(proxyUrl);
|
|
141
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Set Intutic's two keys in goose's `config.yaml` text: `provider.host` (the
|
|
177
|
+
* proxy) and `hooks.pre_tool_use` (the gate script). Edited through the
|
|
178
|
+
* `yaml` document model, so every other key, comment and list is kept. A text
|
|
179
|
+
* replace of the first `host:` line used to rewrite whichever key of that name
|
|
180
|
+
* came first, such as an extension's or an MCP server's.
|
|
181
|
+
*
|
|
182
|
+
* An empty `proxyUrl` leaves `provider.host` alone: the settings guard
|
|
183
|
+
* re-runs this writer to restore the plugin without a URL to hand.
|
|
184
|
+
*
|
|
185
|
+
* Returns `null`, to leave the file untouched, when the text is not YAML, is
|
|
186
|
+
* not a mapping, or holds `provider` or `hooks` as something other than a
|
|
187
|
+
* mapping.
|
|
188
|
+
*/
|
|
189
|
+
export function mergeGooseConfigYaml(raw, proxyUrl, hookScript) {
|
|
190
|
+
const doc = parseDocument(raw);
|
|
191
|
+
if (doc.errors.length > 0)
|
|
192
|
+
return null;
|
|
193
|
+
if (doc.contents !== null && !isMap(doc.contents))
|
|
194
|
+
return null;
|
|
195
|
+
for (const key of ['provider', 'hooks']) {
|
|
196
|
+
const node = doc.get(key, true);
|
|
197
|
+
if (node === undefined || isMap(node))
|
|
198
|
+
continue;
|
|
199
|
+
// `provider:` with no value: replaced by the mapping below.
|
|
200
|
+
if (isScalar(node) && node.value === null)
|
|
201
|
+
doc.delete(key);
|
|
202
|
+
else
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
if (proxyUrl)
|
|
206
|
+
doc.setIn(['provider', 'host'], proxyUrl);
|
|
207
|
+
doc.setIn(['hooks', 'pre_tool_use'], hookScript);
|
|
208
|
+
return doc.toString();
|
|
209
|
+
}
|
|
142
210
|
/**
|
|
143
211
|
* Merge the provider host **and** the `hooks.pre_tool_use` registration into
|
|
144
212
|
* `~/.config/goose/config.yaml`.
|
|
@@ -147,56 +215,26 @@ exit 0
|
|
|
147
215
|
* which wrote its own gate script and registered *that* one here — so goose had
|
|
148
216
|
* two co-installed gates with contradictory models: this one, which enforces
|
|
149
217
|
* locally and fails closed, and that one, which POSTed to the control plane and
|
|
150
|
-
* failed open.
|
|
151
|
-
*
|
|
152
|
-
* which.
|
|
153
|
-
*
|
|
154
|
-
* Absorbing the registration here settles it without needing to know: both
|
|
155
|
-
* mechanisms now name the same script. That is why the answer to "which one does
|
|
156
|
-
* goose read" stopped mattering, rather than being looked up.
|
|
218
|
+
* failed open. Absorbing the registration here settles it: both mechanisms
|
|
219
|
+
* name the same script.
|
|
157
220
|
*/
|
|
158
221
|
async function mergeGooseConfig(proxyUrl) {
|
|
159
|
-
let
|
|
222
|
+
let raw = '';
|
|
160
223
|
try {
|
|
161
|
-
|
|
224
|
+
raw = await fs.readFile(GOOSE_CONFIG, 'utf-8');
|
|
162
225
|
}
|
|
163
226
|
catch {
|
|
164
|
-
//
|
|
165
|
-
// Fall through with `existing` at its '' initialiser so the block below
|
|
166
|
-
// writes a fresh provider stanza rather than aborting the whole sync.
|
|
167
|
-
}
|
|
168
|
-
// Inject or update provider.host
|
|
169
|
-
// Goose config.yaml format: provider.host or OPENAI_HOST env var
|
|
170
|
-
if (existing.includes('provider:')) {
|
|
171
|
-
if (existing.includes(' host:')) {
|
|
172
|
-
existing = existing.replace(/^\s*host:\s*.*/m, ` host: "${proxyUrl}"`);
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
existing = existing.replace(/^provider:/m, `provider:\n host: "${proxyUrl}"`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
existing += `\nprovider:\n host: "${proxyUrl}"\n`;
|
|
227
|
+
// No config.yaml yet (first run) or unreadable: written fresh below.
|
|
180
228
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (!(existing.includes('pre_tool_use:') && existing.includes(hookScript))) {
|
|
186
|
-
// Replace any stale pre_tool_use line rather than adding a second one — an
|
|
187
|
-
// earlier install pointed this at gooseHooksWriter's script, and two
|
|
188
|
-
// registrations under one key is how the double gate started.
|
|
189
|
-
if (/^\s*pre_tool_use:.*$/m.test(existing)) {
|
|
190
|
-
existing = existing.replace(/^\s*pre_tool_use:.*$/m, hookLine);
|
|
191
|
-
}
|
|
192
|
-
else if (/^hooks:/m.test(existing)) {
|
|
193
|
-
existing = existing.replace(/^hooks:/m, `hooks:\n${hookLine}`);
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
existing = existing.trimEnd() + `\nhooks:\n${hookLine}\n`;
|
|
197
|
-
}
|
|
229
|
+
const existing = mergeGooseConfigYaml(raw, proxyUrl, path.join(PLUGIN_DIR, 'scripts', 'intutic-check.sh'));
|
|
230
|
+
if (existing === null) {
|
|
231
|
+
log.warn({ action: 'goose_config_merge_skipped', path: GOOSE_CONFIG }, `${GOOSE_CONFIG} is not a YAML mapping Intutic can merge into — left untouched`);
|
|
232
|
+
return;
|
|
198
233
|
}
|
|
234
|
+
if (existing === raw)
|
|
235
|
+
return;
|
|
199
236
|
const tmpConfig = GOOSE_CONFIG + '.intutic-tmp';
|
|
237
|
+
await keepOriginal(GOOSE_CONFIG, os.homedir());
|
|
200
238
|
await fs.mkdir(path.dirname(GOOSE_CONFIG), { recursive: true });
|
|
201
239
|
await fs.writeFile(tmpConfig, existing, 'utf-8');
|
|
202
240
|
await fs.rename(tmpConfig, GOOSE_CONFIG);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gooseHooks.js","sourceRoot":"","sources":["../../src/harness/gooseHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;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,iBAAiB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"gooseHooks.js","sourceRoot":"","sources":["../../src/harness/gooseHooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
* policy-snapshot evaluation), and — this is the part that is independently
|
|
21
21
|
* confirmed, unlike Muse Code's — signals a block by writing
|
|
22
22
|
* `{"decision":"deny","reason":"..."}` as JSON on **stdout** and exiting 0.
|
|
23
|
-
* That is a *different* stdout shape from Cline
|
|
24
|
-
* — Grok Build does not recognise `cancel`, and Cline
|
|
23
|
+
* That is a *different* stdout shape from Cline's `{"cancel":true}`
|
|
24
|
+
* — Grok Build does not recognise `cancel`, and Cline does not
|
|
25
25
|
* recognise `decision` — so this writer uses its own `BlockContract` value,
|
|
26
26
|
* `'stdout-decision-deny'` (see gateBody.ts's module doc for why the two
|
|
27
27
|
* stdout shapes are not folded into one contract), rather than reusing
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grokHooks.d.ts","sourceRoot":"","sources":["../../src/harness/grokHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;
|
|
1
|
+
{"version":3,"file":"grokHooks.d.ts","sourceRoot":"","sources":["../../src/harness/grokHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AAiSH;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,WAAW,SAAK,GACf,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
* policy-snapshot evaluation), and — this is the part that is independently
|
|
21
21
|
* confirmed, unlike Muse Code's — signals a block by writing
|
|
22
22
|
* `{"decision":"deny","reason":"..."}` as JSON on **stdout** and exiting 0.
|
|
23
|
-
* That is a *different* stdout shape from Cline
|
|
24
|
-
* — Grok Build does not recognise `cancel`, and Cline
|
|
23
|
+
* That is a *different* stdout shape from Cline's `{"cancel":true}`
|
|
24
|
+
* — Grok Build does not recognise `cancel`, and Cline does not
|
|
25
25
|
* recognise `decision` — so this writer uses its own `BlockContract` value,
|
|
26
26
|
* `'stdout-decision-deny'` (see gateBody.ts's module doc for why the two
|
|
27
27
|
* stdout shapes are not folded into one contract), rather than reusing
|
|
@@ -70,7 +70,8 @@ import * as path from 'node:path';
|
|
|
70
70
|
import * as os from 'node:os';
|
|
71
71
|
import { parse as parseToml, stringify as stringifyToml } from 'smol-toml';
|
|
72
72
|
import { createLogger } from '@intutic/logger';
|
|
73
|
-
import {
|
|
73
|
+
import { keepOriginal, writeOwnedFile } from '../disconnect/originals.js';
|
|
74
|
+
import { HOOK_GATE_TIMEOUTS, openaiBaseUrl } from '@intutic/shared-types';
|
|
74
75
|
import { newIso } from '@intutic/id';
|
|
75
76
|
import { emitJsGate, emitJsFailClosedPrelude } from './gateBody.js';
|
|
76
77
|
const log = createLogger('sync-grok-hooks');
|
|
@@ -118,8 +119,9 @@ function buildHookRegistration(hookScriptPath) {
|
|
|
118
119
|
// Grok Build's documented default; stated explicitly rather than
|
|
119
120
|
// left to fall back, since a local policy-snapshot evaluation is
|
|
120
121
|
// cheap but a future default change upstream should not silently
|
|
121
|
-
// starve this hook.
|
|
122
|
-
|
|
122
|
+
// starve this hook. The gate's deadline is derived from it
|
|
123
|
+
// (gateDeadlineMs), because Grok Build runs the call when it expires.
|
|
124
|
+
timeout: HOOK_GATE_TIMEOUTS.grok.timeoutMs / 1000,
|
|
123
125
|
},
|
|
124
126
|
],
|
|
125
127
|
},
|
|
@@ -161,6 +163,9 @@ function logEvent(verdict, toolName, reason) {
|
|
|
161
163
|
try {
|
|
162
164
|
const ts = new Date().toISOString();
|
|
163
165
|
const incidentId = crypto.createHash('sha1').update(ts + toolName + _intuticWsId).digest('hex').slice(0, 16);
|
|
166
|
+
// The event's id: random, made once here, and resent with the line it is
|
|
167
|
+
// written into, so the control plane processes the event once.
|
|
168
|
+
const eventId = crypto.randomBytes(16).toString('hex');
|
|
164
169
|
const entry = JSON.stringify({
|
|
165
170
|
// Passed through, not collapsed to two values: the advisory tier emits
|
|
166
171
|
// 'tool_flagged', and a ternary here silently recorded it as an allow.
|
|
@@ -170,6 +175,7 @@ function logEvent(verdict, toolName, reason) {
|
|
|
170
175
|
harnessType: 'grok',
|
|
171
176
|
timestamp: ts,
|
|
172
177
|
incidentId,
|
|
178
|
+
eventId,
|
|
173
179
|
...(_intuticSessionId ? { sessionId: _intuticSessionId } : {}),
|
|
174
180
|
}) + '\\n';
|
|
175
181
|
fs.appendFileSync(${JSON.stringify(hookEventsLog)}, entry, { flag: 'a' });
|
|
@@ -211,18 +217,12 @@ process.stdin.on('end', () => {
|
|
|
211
217
|
const errMsg = String(err);
|
|
212
218
|
process.stderr.write('[Intutic Governance] Hook error (fail-closed): ' + errMsg + '\\n');
|
|
213
219
|
logEvent('tool_blocked', 'unknown', errMsg);
|
|
214
|
-
process.stdout.write(JSON.stringify({ decision: 'deny', reason: '[Intutic Governance] Hook error (fail-closed): ' + errMsg }) + '\\n');
|
|
220
|
+
process.stdout.write(JSON.stringify({ decision: 'deny', reason: '[Intutic Governance] Hook error (fail-closed): ' + errMsg, code: 'GATE_CRASHED', ruleId: null }) + '\\n');
|
|
215
221
|
process.exit(0);
|
|
216
222
|
}
|
|
217
223
|
});
|
|
218
224
|
`;
|
|
219
225
|
}
|
|
220
|
-
async function atomicWriteJson(filePath, data) {
|
|
221
|
-
const tmp = filePath + '.intutic-tmp';
|
|
222
|
-
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
223
|
-
await fs.writeFile(tmp, JSON.stringify(data, null, 2) + '\n', 'utf-8');
|
|
224
|
-
await fs.rename(tmp, filePath);
|
|
225
|
-
}
|
|
226
226
|
/**
|
|
227
227
|
* Grok Build's compiled-in default model id — CONFIRMED live (2026-08-20)
|
|
228
228
|
* against `github.com/xai-org/grok-build`'s `crates/codegen/xai-grok-models/default_models.json`
|
|
@@ -267,7 +267,7 @@ async function mergeGrokConfigTomlAppendOnly(configPath, existingRaw, proxyUrl)
|
|
|
267
267
|
* table (`GROK_DEFAULT_MODEL_ID` below) — see this module's doc comment for
|
|
268
268
|
* why that id is CONFIRMED against the real open-sourced default, not a guess.
|
|
269
269
|
*/
|
|
270
|
-
async function mergeGrokConfigToml(configPath, proxyUrl) {
|
|
270
|
+
async function mergeGrokConfigToml(configPath, proxyUrl, workspaceRoot) {
|
|
271
271
|
let existing = '';
|
|
272
272
|
try {
|
|
273
273
|
existing = await fs.readFile(configPath, 'utf-8');
|
|
@@ -282,6 +282,7 @@ async function mergeGrokConfigToml(configPath, proxyUrl) {
|
|
|
282
282
|
}
|
|
283
283
|
catch (err) {
|
|
284
284
|
log.warn({ action: 'grok_toml_unparseable', path: configPath, err: err.message }, 'Grok config.toml did not parse as TOML — falling back to append-only text injection');
|
|
285
|
+
await keepOriginal(configPath, workspaceRoot);
|
|
285
286
|
await mergeGrokConfigTomlAppendOnly(configPath, existing, proxyUrl);
|
|
286
287
|
return;
|
|
287
288
|
}
|
|
@@ -311,6 +312,7 @@ async function mergeGrokConfigToml(configPath, proxyUrl) {
|
|
|
311
312
|
return;
|
|
312
313
|
}
|
|
313
314
|
doc.model = model;
|
|
315
|
+
await keepOriginal(configPath, workspaceRoot);
|
|
314
316
|
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
315
317
|
const tmp = configPath + '.intutic-tmp';
|
|
316
318
|
await fs.writeFile(tmp, stringifyToml(doc), 'utf-8');
|
|
@@ -335,21 +337,21 @@ export async function writeGrokHooks(workspaceRoot, proxyUrl, workspaceId = '')
|
|
|
335
337
|
await fs.writeFile(tmpScript, buildHookScript(proxyUrl, workspaceRoot, workspaceId), 'utf-8');
|
|
336
338
|
await fs.rename(tmpScript, hookScriptPath);
|
|
337
339
|
await fs.chmod(hookScriptPath, 0o755);
|
|
338
|
-
const registration = buildHookRegistration(hookScriptPath);
|
|
340
|
+
const registration = JSON.stringify(buildHookRegistration(hookScriptPath), null, 2) + '\n';
|
|
339
341
|
// 1. Project-level: <root>/.grok/hooks/intutic-governance.json
|
|
340
342
|
const projectHooksDir = path.join(workspaceRoot, '.grok', 'hooks');
|
|
341
|
-
await
|
|
343
|
+
await writeOwnedFile(path.join(projectHooksDir, HOOK_FILENAME), workspaceRoot, registration);
|
|
342
344
|
log.info({ action: 'grok_hooks_written', level: 'project', path: projectHooksDir }, 'Grok project-level hooks written');
|
|
343
345
|
// 2. User-level: ~/.grok/hooks/intutic-governance.json
|
|
344
346
|
const userHooksDir = path.join(GROK_USER_DIR, 'hooks');
|
|
345
|
-
await
|
|
347
|
+
await writeOwnedFile(path.join(userHooksDir, HOOK_FILENAME), workspaceRoot, registration);
|
|
346
348
|
log.info({ action: 'grok_hooks_written', level: 'user', path: userHooksDir }, 'Grok user-level hooks written');
|
|
347
349
|
// 3. config.toml model base_url — project and user level.
|
|
348
350
|
// Grok Build talks to xAI's OpenAI-compatible API (its own default base_url
|
|
349
351
|
// is https://api.x.ai/v1) and appends /chat/completions, so the proxy URL it
|
|
350
352
|
// needs is the OpenAI-style one, ending in /v1.
|
|
351
353
|
const modelBaseUrl = openaiBaseUrl(proxyUrl);
|
|
352
|
-
await mergeGrokConfigToml(path.join(workspaceRoot, '.grok', 'config.toml'), modelBaseUrl);
|
|
353
|
-
await mergeGrokConfigToml(path.join(GROK_USER_DIR, 'config.toml'), modelBaseUrl);
|
|
354
|
+
await mergeGrokConfigToml(path.join(workspaceRoot, '.grok', 'config.toml'), modelBaseUrl, workspaceRoot);
|
|
355
|
+
await mergeGrokConfigToml(path.join(GROK_USER_DIR, 'config.toml'), modelBaseUrl, workspaceRoot);
|
|
354
356
|
}
|
|
355
357
|
//# sourceMappingURL=grokHooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grokHooks.js","sourceRoot":"","sources":["../../src/harness/grokHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,WAAW,CAAA;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"grokHooks.js","sourceRoot":"","sources":["../../src/harness/grokHooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* hermesHooks.ts — Hermes AI agent governance hook injection.
|
|
3
3
|
*
|
|
4
4
|
* Hermes is a skills-based AI agent that reads `~/.hermes/config.yaml`
|
|
5
|
-
* for configuration.
|
|
5
|
+
* for configuration. The gate is a shell hook under `hooks.pre_tool_call`.
|
|
6
6
|
* This module:
|
|
7
7
|
*
|
|
8
8
|
* 1. YAML-safe-merges `~/.hermes/config.yaml` to register the hook command.
|
|
@@ -11,18 +11,28 @@
|
|
|
11
11
|
* 4. Writes `.intutic/env/hermes.env` — env snippet for IDE/shell integration.
|
|
12
12
|
*
|
|
13
13
|
* WS-C1 — Hermes harness (Phase 3 cross-harness defence)
|
|
14
|
-
* LLD #14 — Phase 3 cross-harness defence (Gap 3)
|
|
15
14
|
* HLD §3.14 — Three-Tier Defense Cascade (Tier 1 Native Gating)
|
|
16
15
|
*
|
|
17
16
|
* @module
|
|
18
17
|
*/
|
|
19
18
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
|
|
19
|
+
* The gate's shell-hook entry: \`fail_closed\` makes Hermes refuse the call
|
|
20
|
+
* when the gate times out, crashes or prints something it cannot read, where
|
|
21
|
+
* its default runs it; \`timeout\` replaces Hermes's 60 s default, and the
|
|
22
|
+
* gate refuses at its own deadline inside it. Hermes splits \`command\` with
|
|
23
|
+
* shlex, so a path with a space or a quote in it is quoted.
|
|
24
|
+
*/
|
|
25
|
+
export declare function hermesHookEntry(hookScriptPath: string): Record<string, unknown>;
|
|
26
|
+
/**
|
|
27
|
+
* Merge the hook registration into the Hermes config: the gate's entry is put
|
|
28
|
+
* in the \`hooks.pre_tool_call\` list, replacing an earlier one of ours, and
|
|
29
|
+
* everything else in the file — other hooks, MCP servers, comments — is kept.
|
|
30
|
+
* Edited through the \`yaml\` document model. A file that does not parse, or
|
|
31
|
+
* is not a mapping, or holds \`hooks\` or \`pre_tool_call\` in a shape Hermes
|
|
32
|
+
* would not read, is left untouched and reported.
|
|
33
|
+
*
|
|
34
|
+
* Earlier versions wrote \`hooks.preToolUse.command\`, which Hermes skips as an
|
|
35
|
+
* unknown event: that registration is removed.
|
|
26
36
|
*/
|
|
27
37
|
export declare function mergeHermesYaml(existing: string, hookScriptPath: string): string | null;
|
|
28
38
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hermesHooks.d.ts","sourceRoot":"","sources":["../../src/harness/hermesHooks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hermesHooks.d.ts","sourceRoot":"","sources":["../../src/harness/hermesHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAmGH;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAG/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsBvF;AA6CD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,WAAW,SAAK,GACf,OAAO,CAAC,IAAI,CAAC,CAqEf"}
|