@intutic/sync-daemon 1.10.0 → 2.0.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 +2 -2
- package/dist/agentReporter.d.ts +205 -0
- package/dist/agentReporter.d.ts.map +1 -0
- package/dist/agentReporter.js +394 -0
- package/dist/agentReporter.js.map +1 -0
- package/dist/configReader.d.ts +39 -2
- package/dist/configReader.d.ts.map +1 -1
- package/dist/configReader.js +56 -2
- package/dist/configReader.js.map +1 -1
- package/dist/configWriter.d.ts +51 -1
- package/dist/configWriter.d.ts.map +1 -1
- package/dist/configWriter.js +490 -63
- package/dist/configWriter.js.map +1 -1
- package/dist/harness/antigravityHooks.d.ts.map +1 -1
- package/dist/harness/antigravityHooks.js +33 -55
- package/dist/harness/antigravityHooks.js.map +1 -1
- package/dist/harness/claudeCodeHooks.d.ts +47 -13
- package/dist/harness/claudeCodeHooks.d.ts.map +1 -1
- package/dist/harness/claudeCodeHooks.js +316 -54
- package/dist/harness/claudeCodeHooks.js.map +1 -1
- package/dist/harness/claudeDesktopHooks.d.ts.map +1 -1
- package/dist/harness/claudeDesktopHooks.js +35 -48
- package/dist/harness/claudeDesktopHooks.js.map +1 -1
- package/dist/harness/clineHooks.d.ts.map +1 -1
- package/dist/harness/clineHooks.js +42 -34
- package/dist/harness/clineHooks.js.map +1 -1
- package/dist/harness/codexHooks.d.ts +36 -0
- package/dist/harness/codexHooks.d.ts.map +1 -0
- package/dist/harness/codexHooks.js +227 -0
- package/dist/harness/codexHooks.js.map +1 -0
- package/dist/harness/continueHooks.d.ts +45 -5
- package/dist/harness/continueHooks.d.ts.map +1 -1
- package/dist/harness/continueHooks.js +225 -5
- package/dist/harness/continueHooks.js.map +1 -1
- package/dist/harness/cursorHooks.d.ts +31 -0
- package/dist/harness/cursorHooks.d.ts.map +1 -1
- package/dist/harness/cursorHooks.js +78 -49
- package/dist/harness/cursorHooks.js.map +1 -1
- package/dist/harness/dshHooks.d.ts +198 -0
- package/dist/harness/dshHooks.d.ts.map +1 -0
- package/dist/harness/dshHooks.js +569 -0
- package/dist/harness/dshHooks.js.map +1 -0
- package/dist/harness/gateBody.d.ts +422 -0
- package/dist/harness/gateBody.d.ts.map +1 -0
- package/dist/harness/gateBody.js +1816 -0
- package/dist/harness/gateBody.js.map +1 -0
- package/dist/harness/gateKind.d.ts +164 -0
- package/dist/harness/gateKind.d.ts.map +1 -0
- package/dist/harness/gateKind.js +143 -0
- package/dist/harness/gateKind.js.map +1 -0
- package/dist/harness/githubCopilotHooks.d.ts +54 -0
- package/dist/harness/githubCopilotHooks.d.ts.map +1 -0
- package/dist/harness/githubCopilotHooks.js +218 -0
- package/dist/harness/githubCopilotHooks.js.map +1 -0
- package/dist/harness/gooseHooks.d.ts.map +1 -1
- package/dist/harness/gooseHooks.js +67 -37
- package/dist/harness/gooseHooks.js.map +1 -1
- package/dist/harness/grokHooks.d.ts +77 -0
- package/dist/harness/grokHooks.d.ts.map +1 -0
- package/dist/harness/grokHooks.js +350 -0
- package/dist/harness/grokHooks.js.map +1 -0
- package/dist/harness/hermesHooks.d.ts.map +1 -1
- package/dist/harness/hermesHooks.js +26 -55
- package/dist/harness/hermesHooks.js.map +1 -1
- package/dist/harness/holdRedaction.d.ts +69 -0
- package/dist/harness/holdRedaction.d.ts.map +1 -0
- package/dist/harness/holdRedaction.js +211 -0
- package/dist/harness/holdRedaction.js.map +1 -0
- package/dist/harness/jetbrainsXmlConfig.d.ts +51 -0
- package/dist/harness/jetbrainsXmlConfig.d.ts.map +1 -0
- package/dist/harness/jetbrainsXmlConfig.js +151 -0
- package/dist/harness/jetbrainsXmlConfig.js.map +1 -0
- package/dist/harness/mcpAutoWrite.d.ts +100 -3
- package/dist/harness/mcpAutoWrite.d.ts.map +1 -1
- package/dist/harness/mcpAutoWrite.js +712 -90
- package/dist/harness/mcpAutoWrite.js.map +1 -1
- package/dist/harness/museHooks.d.ts +53 -0
- package/dist/harness/museHooks.d.ts.map +1 -0
- package/dist/harness/museHooks.js +273 -0
- package/dist/harness/museHooks.js.map +1 -0
- package/dist/harness/n8nHooks.d.ts +25 -9
- package/dist/harness/n8nHooks.d.ts.map +1 -1
- package/dist/harness/n8nHooks.js +174 -9
- package/dist/harness/n8nHooks.js.map +1 -1
- package/dist/harness/openCodeHooks.d.ts +93 -0
- package/dist/harness/openCodeHooks.d.ts.map +1 -0
- package/dist/harness/openCodeHooks.js +248 -0
- package/dist/harness/openCodeHooks.js.map +1 -0
- package/dist/harness/openWebuiHooks.d.ts.map +1 -1
- package/dist/harness/openWebuiHooks.js +56 -11
- package/dist/harness/openWebuiHooks.js.map +1 -1
- package/dist/harness/openclawHooks.d.ts.map +1 -1
- package/dist/harness/openclawHooks.js +30 -54
- package/dist/harness/openclawHooks.js.map +1 -1
- package/dist/harness/openhandsHooks.d.ts.map +1 -1
- package/dist/harness/openhandsHooks.js +35 -41
- package/dist/harness/openhandsHooks.js.map +1 -1
- package/dist/harness/piHooks.d.ts.map +1 -1
- package/dist/harness/piHooks.js +31 -58
- package/dist/harness/piHooks.js.map +1 -1
- package/dist/harness/protectedPaths.d.ts +353 -0
- package/dist/harness/protectedPaths.d.ts.map +1 -0
- package/dist/harness/protectedPaths.js +805 -0
- package/dist/harness/protectedPaths.js.map +1 -0
- package/dist/harness/rooCodeHooks.d.ts.map +1 -1
- package/dist/harness/rooCodeHooks.js +34 -48
- package/dist/harness/rooCodeHooks.js.map +1 -1
- package/dist/harness/windsurfHooks.d.ts +72 -0
- package/dist/harness/windsurfHooks.d.ts.map +1 -1
- package/dist/harness/windsurfHooks.js +172 -58
- package/dist/harness/windsurfHooks.js.map +1 -1
- package/dist/harness/windsurfJetBrainsProxy.d.ts +78 -0
- package/dist/harness/windsurfJetBrainsProxy.d.ts.map +1 -0
- package/dist/harness/windsurfJetBrainsProxy.js +159 -0
- package/dist/harness/windsurfJetBrainsProxy.js.map +1 -0
- package/dist/hashReporter.js +1 -1
- package/dist/hashReporter.js.map +1 -1
- package/dist/index.d.ts +12 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -6
- package/dist/index.js.map +1 -1
- package/dist/integrityStore.d.ts +0 -8
- package/dist/integrityStore.d.ts.map +1 -1
- package/dist/integrityStore.js +6 -29
- package/dist/integrityStore.js.map +1 -1
- package/dist/lib/approvedBypasses.d.ts +76 -0
- package/dist/lib/approvedBypasses.d.ts.map +1 -0
- package/dist/lib/approvedBypasses.js +140 -0
- package/dist/lib/approvedBypasses.js.map +1 -0
- package/dist/lib/complianceProbes.d.ts.map +1 -1
- package/dist/lib/complianceProbes.js +5 -0
- package/dist/lib/complianceProbes.js.map +1 -1
- package/dist/lib/decisionsDigest.d.ts +99 -0
- package/dist/lib/decisionsDigest.d.ts.map +1 -0
- package/dist/lib/decisionsDigest.js +199 -0
- package/dist/lib/decisionsDigest.js.map +1 -0
- package/dist/lib/egressPolicy.d.ts +69 -0
- package/dist/lib/egressPolicy.d.ts.map +1 -0
- package/dist/lib/egressPolicy.js +126 -0
- package/dist/lib/egressPolicy.js.map +1 -0
- package/dist/lib/gitWorktrees.d.ts +140 -0
- package/dist/lib/gitWorktrees.d.ts.map +1 -0
- package/dist/lib/gitWorktrees.js +191 -0
- package/dist/lib/gitWorktrees.js.map +1 -0
- package/dist/lib/policySnapshot.d.ts +224 -0
- package/dist/lib/policySnapshot.d.ts.map +1 -0
- package/dist/lib/policySnapshot.js +637 -0
- package/dist/lib/policySnapshot.js.map +1 -0
- package/dist/lib/processPoller.d.ts +44 -0
- package/dist/lib/processPoller.d.ts.map +1 -1
- package/dist/lib/processPoller.js +176 -1
- package/dist/lib/processPoller.js.map +1 -1
- package/dist/lib/runtimeEnv.d.ts +8 -0
- package/dist/lib/runtimeEnv.d.ts.map +1 -1
- package/dist/lib/runtimeEnv.js +3 -0
- package/dist/lib/runtimeEnv.js.map +1 -1
- package/dist/localTrajectoryHeuristics.d.ts +51 -0
- package/dist/localTrajectoryHeuristics.d.ts.map +1 -0
- package/dist/localTrajectoryHeuristics.js +90 -0
- package/dist/localTrajectoryHeuristics.js.map +1 -0
- package/dist/sessionReporter.d.ts +70 -0
- package/dist/sessionReporter.d.ts.map +1 -0
- package/dist/sessionReporter.js +140 -0
- package/dist/sessionReporter.js.map +1 -0
- package/dist/skillWriter.d.ts +1 -1
- package/dist/skillWriter.d.ts.map +1 -1
- package/dist/skillWriter.js +5 -2
- package/dist/skillWriter.js.map +1 -1
- package/dist/syncLoop.d.ts +105 -3
- package/dist/syncLoop.d.ts.map +1 -1
- package/dist/syncLoop.js +397 -65
- package/dist/syncLoop.js.map +1 -1
- package/dist/trajectoryMonitor.d.ts +2 -0
- package/dist/trajectoryMonitor.d.ts.map +1 -1
- package/dist/trajectoryMonitor.js +57 -0
- package/dist/trajectoryMonitor.js.map +1 -1
- package/dist/watcher/driftWatcher.d.ts.map +1 -1
- package/dist/watcher/driftWatcher.js +12 -3
- package/dist/watcher/driftWatcher.js.map +1 -1
- package/dist/watcher/settingsGuard.d.ts +23 -0
- package/dist/watcher/settingsGuard.d.ts.map +1 -1
- package/dist/watcher/settingsGuard.js +202 -17
- package/dist/watcher/settingsGuard.js.map +1 -1
- package/package.json +37 -6
- package/dist/brainIndexer.d.ts +0 -51
- package/dist/brainIndexer.d.ts.map +0 -1
- package/dist/brainIndexer.js +0 -148
- package/dist/brainIndexer.js.map +0 -1
- package/dist/harness/cursorHooksJson.d.ts +0 -29
- package/dist/harness/cursorHooksJson.d.ts.map +0 -1
- package/dist/harness/cursorHooksJson.js +0 -130
- package/dist/harness/cursorHooksJson.js.map +0 -1
- package/dist/harness/gooseHooksWriter.d.ts +0 -27
- package/dist/harness/gooseHooksWriter.d.ts.map +0 -1
- package/dist/harness/gooseHooksWriter.js +0 -147
- package/dist/harness/gooseHooksWriter.js.map +0 -1
- package/dist/harness/openhandsHooksWriter.d.ts +0 -23
- package/dist/harness/openhandsHooksWriter.d.ts.map +0 -1
- package/dist/harness/openhandsHooksWriter.js +0 -146
- package/dist/harness/openhandsHooksWriter.js.map +0 -1
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* gooseHooksWriter.ts — Goose pre_tool_use native hook writer.
|
|
3
|
-
*
|
|
4
|
-
* Writes two artefacts:
|
|
5
|
-
* 1. `~/.intutic/hooks/goose-pre-tool-use.sh` — bash gate script that
|
|
6
|
-
* sources runtime credentials, POSTs to the Intutic hook-gate endpoint,
|
|
7
|
-
* and exits 2 (block) or 0 (allow).
|
|
8
|
-
* 2. `~/.config/goose/config.yaml` — adds `hooks.pre_tool_use` key if it
|
|
9
|
-
* is not already present (string operations only; no yaml dep needed).
|
|
10
|
-
*
|
|
11
|
-
* Fail-open semantics: if curl errors the script exits 0 so Goose continues.
|
|
12
|
-
* On block, a JSONL event line is also appended to
|
|
13
|
-
* `~/.intutic/events/hook-events.jsonl` for local audit.
|
|
14
|
-
*
|
|
15
|
-
* LLD #14 — Phase 4 WS-4C native hook script writers
|
|
16
|
-
* HLD §3.14 — Three-Tier Defense Cascade (Tier 1 Native Gating)
|
|
17
|
-
*
|
|
18
|
-
* @module
|
|
19
|
-
*/
|
|
20
|
-
import * as node_fs from 'node:fs/promises';
|
|
21
|
-
import * as node_path from 'node:path';
|
|
22
|
-
import * as node_os from 'node:os';
|
|
23
|
-
import { createLogger } from '@intutic/logger';
|
|
24
|
-
const log = createLogger('sync-goose-hooks-writer');
|
|
25
|
-
const HOOKS_DIR = node_path.join(node_os.homedir(), '.intutic', 'hooks');
|
|
26
|
-
const EVENTS_DIR = node_path.join(node_os.homedir(), '.intutic', 'events');
|
|
27
|
-
const HOOK_SCRIPT = node_path.join(HOOKS_DIR, 'goose-pre-tool-use.sh');
|
|
28
|
-
const HOOK_EVENTS_LOG = node_path.join(EVENTS_DIR, 'hook-events.jsonl');
|
|
29
|
-
const GOOSE_CONFIG = node_path.join(node_os.homedir(), '.config', 'goose', 'config.yaml');
|
|
30
|
-
/**
|
|
31
|
-
* Build the bash gate script content.
|
|
32
|
-
*
|
|
33
|
-
* Logic:
|
|
34
|
-
* 1. Source ~/.intutic/env/runtime.env for credentials.
|
|
35
|
-
* 2. Read full stdin JSON payload.
|
|
36
|
-
* 3. POST to $INTUTIC_CONTROL_PLANE_URL/api/v1/hook-gate (10 s timeout).
|
|
37
|
-
* 4. If curl fails → fail-open (exit 0).
|
|
38
|
-
* 5. If response body contains `"allowed":false` → append JSONL event, exit 2.
|
|
39
|
-
* 6. Otherwise → exit 0.
|
|
40
|
-
*/
|
|
41
|
-
function buildGooseHookScript() {
|
|
42
|
-
return `#!/usr/bin/env bash
|
|
43
|
-
# Intutic Goose pre_tool_use governance gate.
|
|
44
|
-
# Auto-generated by intutic sync-daemon. DO NOT EDIT.
|
|
45
|
-
set -euo pipefail
|
|
46
|
-
|
|
47
|
-
RUNTIME_ENV="$HOME/.intutic/env/runtime.env"
|
|
48
|
-
HOOK_EVENTS_LOG=${JSON.stringify(HOOK_EVENTS_LOG)}
|
|
49
|
-
INTUTIC_CONTROL_PLANE_URL="https://api.intutic.ai"
|
|
50
|
-
INTUTIC_API_KEY=""
|
|
51
|
-
INTUTIC_WORKSPACE_ID=""
|
|
52
|
-
|
|
53
|
-
# Source runtime credentials (key rotation is automatic on next tool call)
|
|
54
|
-
[ -f "$RUNTIME_ENV" ] && source "$RUNTIME_ENV" 2>/dev/null || true
|
|
55
|
-
|
|
56
|
-
INPUT="$(cat)"
|
|
57
|
-
TOOL_NAME="$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_name',''))" 2>/dev/null || true)"
|
|
58
|
-
|
|
59
|
-
# ── POST to hook-gate ─────────────────────────────────────────────────
|
|
60
|
-
GATE_URL="\${INTUTIC_CONTROL_PLANE_URL}/api/v1/hook-gate"
|
|
61
|
-
RESPONSE=""
|
|
62
|
-
if [ -n "$INTUTIC_API_KEY" ]; then
|
|
63
|
-
RESPONSE="$(curl -s --max-time 10 -X POST \\
|
|
64
|
-
-H "Content-Type: application/json" \\
|
|
65
|
-
-H "Authorization: Bearer $INTUTIC_API_KEY" \\
|
|
66
|
-
-d "$INPUT" \\
|
|
67
|
-
"$GATE_URL" 2>/dev/null)" || true
|
|
68
|
-
fi
|
|
69
|
-
|
|
70
|
-
# Fail-open: empty response (curl error / no key) → allow
|
|
71
|
-
if [ -z "$RESPONSE" ]; then
|
|
72
|
-
exit 0
|
|
73
|
-
fi
|
|
74
|
-
|
|
75
|
-
# Check decision
|
|
76
|
-
ALLOWED="$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(str(d.get('allowed', True)).lower())" 2>/dev/null || echo "true")"
|
|
77
|
-
|
|
78
|
-
if [ "$ALLOWED" = "false" ]; then
|
|
79
|
-
REASON="$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('reason',''))" 2>/dev/null || true)"
|
|
80
|
-
TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
81
|
-
INCIDENT_ID="$(printf '%s' "\${TS}\${TOOL_NAME}\${INTUTIC_WORKSPACE_ID}" | sha1sum 2>/dev/null | cut -c1-16 || echo "$(date +%s)")"
|
|
82
|
-
ENTRY="{\\"event\\":\\"tool_blocked\\",\\"toolName\\":\\"\${TOOL_NAME}\\",\\"reason\\":\\"\${REASON}\\",\\"workspaceId\\":\\"\${INTUTIC_WORKSPACE_ID}\\",\\"harnessType\\":\\"goose\\",\\"timestamp\\":\\"\${TS}\\",\\"incidentId\\":\\"\${INCIDENT_ID}\\"}"
|
|
83
|
-
mkdir -p "$(dirname "$HOOK_EVENTS_LOG")"
|
|
84
|
-
printf '%s\\n' "$ENTRY" >> "$HOOK_EVENTS_LOG" 2>/dev/null || true
|
|
85
|
-
echo "[Intutic Governance] BLOCKED: $REASON" >&2
|
|
86
|
-
exit 2
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
|
-
exit 0
|
|
90
|
-
`;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Merge `hooks.pre_tool_use` into Goose config.yaml using string operations.
|
|
94
|
-
*
|
|
95
|
-
* Reads the existing file (if any), checks if `pre_tool_use:` is already
|
|
96
|
-
* present under a `hooks:` section, and adds it only if absent.
|
|
97
|
-
* Creates the file (with a minimal `hooks:` block) if it does not exist.
|
|
98
|
-
*/
|
|
99
|
-
async function mergeGooseConfig() {
|
|
100
|
-
let existing = '';
|
|
101
|
-
try {
|
|
102
|
-
existing = await node_fs.readFile(GOOSE_CONFIG, 'utf-8');
|
|
103
|
-
}
|
|
104
|
-
catch {
|
|
105
|
-
existing = '';
|
|
106
|
-
}
|
|
107
|
-
const hookLine = ` pre_tool_use: ${HOOK_SCRIPT}`;
|
|
108
|
-
// Already registered — nothing to do
|
|
109
|
-
if (existing.includes('pre_tool_use:') && existing.includes(HOOK_SCRIPT)) {
|
|
110
|
-
log.debug({ action: 'goose_config_noop', path: GOOSE_CONFIG }, 'Goose config already contains pre_tool_use hook');
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (existing.includes('hooks:')) {
|
|
114
|
-
// hooks: block exists — insert our line after the `hooks:` line
|
|
115
|
-
existing = existing.replace(/^hooks:/m, `hooks:\n${hookLine}`);
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
// No hooks: block — append
|
|
119
|
-
existing = existing.trimEnd() + `\nhooks:\n${hookLine}\n`;
|
|
120
|
-
}
|
|
121
|
-
await node_fs.mkdir(node_path.dirname(GOOSE_CONFIG), { recursive: true });
|
|
122
|
-
const tmp = GOOSE_CONFIG + '.intutic-tmp';
|
|
123
|
-
await node_fs.writeFile(tmp, existing, 'utf-8');
|
|
124
|
-
await node_fs.rename(tmp, GOOSE_CONFIG);
|
|
125
|
-
log.info({ action: 'goose_config_written', path: GOOSE_CONFIG }, 'Goose config.yaml updated with pre_tool_use hook');
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Write the Goose pre_tool_use hook script and register it in config.yaml.
|
|
129
|
-
*
|
|
130
|
-
* @param workspaceRoot - Absolute path to the workspace root (unused directly;
|
|
131
|
-
* included for API symmetry with other hook writers).
|
|
132
|
-
*/
|
|
133
|
-
export async function writeGooseHooks(workspaceRoot) {
|
|
134
|
-
// Ensure target directories exist
|
|
135
|
-
await node_fs.mkdir(HOOKS_DIR, { recursive: true });
|
|
136
|
-
await node_fs.mkdir(EVENTS_DIR, { recursive: true });
|
|
137
|
-
// Write hook script atomically
|
|
138
|
-
const tmp = HOOK_SCRIPT + '.intutic-tmp';
|
|
139
|
-
await node_fs.writeFile(tmp, buildGooseHookScript(), 'utf-8');
|
|
140
|
-
await node_fs.rename(tmp, HOOK_SCRIPT);
|
|
141
|
-
await node_fs.chmod(HOOK_SCRIPT, 0o755);
|
|
142
|
-
log.info({ action: 'goose_hook_script_written', path: HOOK_SCRIPT }, 'Goose pre_tool_use hook script written');
|
|
143
|
-
// Register in config.yaml
|
|
144
|
-
await mergeGooseConfig();
|
|
145
|
-
log.info({ action: 'goose_hooks_done', workspaceRoot }, 'Goose native hooks written successfully');
|
|
146
|
-
}
|
|
147
|
-
//# sourceMappingURL=gooseHooksWriter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gooseHooksWriter.js","sourceRoot":"","sources":["../../src/harness/gooseHooksWriter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* openhandsHooksWriter.ts — OpenHands PreToolUse native hook writer.
|
|
3
|
-
*
|
|
4
|
-
* Writes two artefacts:
|
|
5
|
-
* 1. `~/.intutic/hooks/pre-tool-check.sh` — shared bash gate script that
|
|
6
|
-
* sources runtime credentials, POSTs to the Intutic hook-gate endpoint,
|
|
7
|
-
* exits 2 on block (fail-open on curl error). Sets HARNESS=openhands in
|
|
8
|
-
* the request body so the control plane can route correctly.
|
|
9
|
-
* 2. `<workspaceRoot>/.openhands/hooks.json` — registers the script as the
|
|
10
|
-
* PreToolUse handler with a 10-second timeout.
|
|
11
|
-
*
|
|
12
|
-
* LLD #14 — Phase 4 WS-4C native hook script writers
|
|
13
|
-
* HLD §3.14 — Three-Tier Defense Cascade (Tier 1 Native Gating)
|
|
14
|
-
*
|
|
15
|
-
* @module
|
|
16
|
-
*/
|
|
17
|
-
/**
|
|
18
|
-
* Write OpenHands PreToolUse hook script and hooks.json.
|
|
19
|
-
*
|
|
20
|
-
* @param workspaceRoot - Absolute path to the workspace root.
|
|
21
|
-
*/
|
|
22
|
-
export declare function writeOpenHandsHooks(workspaceRoot: string): Promise<void>;
|
|
23
|
-
//# sourceMappingURL=openhandsHooksWriter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openhandsHooksWriter.d.ts","sourceRoot":"","sources":["../../src/harness/openhandsHooksWriter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA+GH;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B9E"}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* openhandsHooksWriter.ts — OpenHands PreToolUse native hook writer.
|
|
3
|
-
*
|
|
4
|
-
* Writes two artefacts:
|
|
5
|
-
* 1. `~/.intutic/hooks/pre-tool-check.sh` — shared bash gate script that
|
|
6
|
-
* sources runtime credentials, POSTs to the Intutic hook-gate endpoint,
|
|
7
|
-
* exits 2 on block (fail-open on curl error). Sets HARNESS=openhands in
|
|
8
|
-
* the request body so the control plane can route correctly.
|
|
9
|
-
* 2. `<workspaceRoot>/.openhands/hooks.json` — registers the script as the
|
|
10
|
-
* PreToolUse handler with a 10-second timeout.
|
|
11
|
-
*
|
|
12
|
-
* LLD #14 — Phase 4 WS-4C native hook script writers
|
|
13
|
-
* HLD §3.14 — Three-Tier Defense Cascade (Tier 1 Native Gating)
|
|
14
|
-
*
|
|
15
|
-
* @module
|
|
16
|
-
*/
|
|
17
|
-
import * as node_fs from 'node:fs/promises';
|
|
18
|
-
import * as node_path from 'node:path';
|
|
19
|
-
import * as node_os from 'node:os';
|
|
20
|
-
import { createLogger } from '@intutic/logger';
|
|
21
|
-
const log = createLogger('sync-openhands-hooks-writer');
|
|
22
|
-
const HOOKS_DIR = node_path.join(node_os.homedir(), '.intutic', 'hooks');
|
|
23
|
-
const EVENTS_DIR = node_path.join(node_os.homedir(), '.intutic', 'events');
|
|
24
|
-
const HOOK_SCRIPT = node_path.join(HOOKS_DIR, 'pre-tool-check.sh');
|
|
25
|
-
const HOOK_EVENTS_LOG = node_path.join(EVENTS_DIR, 'hook-events.jsonl');
|
|
26
|
-
/**
|
|
27
|
-
* Build the shared bash gate script.
|
|
28
|
-
*
|
|
29
|
-
* The script is designed to be shared across harnesses that invoke a bash
|
|
30
|
-
* pre-tool-use hook. It sets HARNESS=openhands in the POST body so the
|
|
31
|
-
* control-plane can distinguish the origin.
|
|
32
|
-
*
|
|
33
|
-
* Logic:
|
|
34
|
-
* 1. Source ~/.intutic/env/runtime.env for credentials.
|
|
35
|
-
* 2. Read full stdin JSON payload.
|
|
36
|
-
* 3. Merge HARNESS=openhands into the payload.
|
|
37
|
-
* 4. POST to $INTUTIC_CONTROL_PLANE_URL/api/v1/hook-gate (10 s timeout).
|
|
38
|
-
* 5. Fail-open if curl returns an error or no API key is set.
|
|
39
|
-
* 6. Exit 2 + append JSONL event if `"allowed":false`.
|
|
40
|
-
* 7. Exit 0 otherwise.
|
|
41
|
-
*/
|
|
42
|
-
function buildPreToolCheckScript() {
|
|
43
|
-
return `#!/usr/bin/env bash
|
|
44
|
-
# Intutic shared pre-tool-check governance gate.
|
|
45
|
-
# Auto-generated by intutic sync-daemon. DO NOT EDIT.
|
|
46
|
-
# Used by: OpenHands (and any other bash-based hook harness).
|
|
47
|
-
set -euo pipefail
|
|
48
|
-
|
|
49
|
-
HARNESS="openhands"
|
|
50
|
-
RUNTIME_ENV="$HOME/.intutic/env/runtime.env"
|
|
51
|
-
HOOK_EVENTS_LOG=${JSON.stringify(HOOK_EVENTS_LOG)}
|
|
52
|
-
INTUTIC_CONTROL_PLANE_URL="https://api.intutic.ai"
|
|
53
|
-
INTUTIC_API_KEY=""
|
|
54
|
-
INTUTIC_WORKSPACE_ID=""
|
|
55
|
-
|
|
56
|
-
# Source runtime credentials (key rotation is automatic on next tool call)
|
|
57
|
-
[ -f "$RUNTIME_ENV" ] && source "$RUNTIME_ENV" 2>/dev/null || true
|
|
58
|
-
|
|
59
|
-
INPUT="$(cat)"
|
|
60
|
-
TOOL_NAME="$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_name',''))" 2>/dev/null || true)"
|
|
61
|
-
|
|
62
|
-
# Augment body with harness identifier
|
|
63
|
-
BODY="$(echo "$INPUT" | python3 -c "
|
|
64
|
-
import sys, json
|
|
65
|
-
d = json.load(sys.stdin)
|
|
66
|
-
d['harness'] = '$HARNESS'
|
|
67
|
-
d['workspaceId'] = '$INTUTIC_WORKSPACE_ID'
|
|
68
|
-
print(json.dumps(d))
|
|
69
|
-
" 2>/dev/null || echo "$INPUT")"
|
|
70
|
-
|
|
71
|
-
# ── POST to hook-gate ─────────────────────────────────────────────────
|
|
72
|
-
GATE_URL="\${INTUTIC_CONTROL_PLANE_URL}/api/v1/hook-gate"
|
|
73
|
-
RESPONSE=""
|
|
74
|
-
if [ -n "$INTUTIC_API_KEY" ]; then
|
|
75
|
-
RESPONSE="$(curl -s --max-time 10 -X POST \\
|
|
76
|
-
-H "Content-Type: application/json" \\
|
|
77
|
-
-H "Authorization: Bearer $INTUTIC_API_KEY" \\
|
|
78
|
-
-d "$BODY" \\
|
|
79
|
-
"$GATE_URL" 2>/dev/null)" || true
|
|
80
|
-
fi
|
|
81
|
-
|
|
82
|
-
# Fail-open: empty response (curl error / no key) → allow
|
|
83
|
-
if [ -z "$RESPONSE" ]; then
|
|
84
|
-
exit 0
|
|
85
|
-
fi
|
|
86
|
-
|
|
87
|
-
# Parse decision
|
|
88
|
-
ALLOWED="$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(str(d.get('allowed', True)).lower())" 2>/dev/null || echo "true")"
|
|
89
|
-
|
|
90
|
-
if [ "$ALLOWED" = "false" ]; then
|
|
91
|
-
REASON="$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('reason',''))" 2>/dev/null || true)"
|
|
92
|
-
TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
93
|
-
INCIDENT_ID="$(printf '%s' "\${TS}\${TOOL_NAME}\${INTUTIC_WORKSPACE_ID}" | sha1sum 2>/dev/null | cut -c1-16 || echo "$(date +%s)")"
|
|
94
|
-
ENTRY="{\\"event\\":\\"tool_blocked\\",\\"toolName\\":\\"\${TOOL_NAME}\\",\\"reason\\":\\"\${REASON}\\",\\"workspaceId\\":\\"\${INTUTIC_WORKSPACE_ID}\\",\\"harnessType\\":\\"\${HARNESS}\\",\\"timestamp\\":\\"\${TS}\\",\\"incidentId\\":\\"\${INCIDENT_ID}\\"}"
|
|
95
|
-
mkdir -p "$(dirname "$HOOK_EVENTS_LOG")"
|
|
96
|
-
printf '%s\\n' "$ENTRY" >> "$HOOK_EVENTS_LOG" 2>/dev/null || true
|
|
97
|
-
echo "[Intutic Governance] BLOCKED: $REASON" >&2
|
|
98
|
-
exit 2
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
exit 0
|
|
102
|
-
`;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Build the .openhands/hooks.json document that registers the PreToolUse hook.
|
|
106
|
-
*
|
|
107
|
-
* @param hookScriptPath - Absolute path to the bash gate script.
|
|
108
|
-
*/
|
|
109
|
-
function buildOpenHandsHooksJson(hookScriptPath) {
|
|
110
|
-
return {
|
|
111
|
-
_comment: 'Intutic governance hooks — auto-generated. DO NOT EDIT.',
|
|
112
|
-
hooks: [
|
|
113
|
-
{
|
|
114
|
-
type: 'PreToolUse',
|
|
115
|
-
command: hookScriptPath,
|
|
116
|
-
timeout: 10,
|
|
117
|
-
},
|
|
118
|
-
],
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Write OpenHands PreToolUse hook script and hooks.json.
|
|
123
|
-
*
|
|
124
|
-
* @param workspaceRoot - Absolute path to the workspace root.
|
|
125
|
-
*/
|
|
126
|
-
export async function writeOpenHandsHooks(workspaceRoot) {
|
|
127
|
-
// ── Ensure directories exist ─────────────────────────────────────────
|
|
128
|
-
await node_fs.mkdir(HOOKS_DIR, { recursive: true });
|
|
129
|
-
await node_fs.mkdir(EVENTS_DIR, { recursive: true });
|
|
130
|
-
// ── 1. Write shared bash gate script ────────────────────────────────
|
|
131
|
-
const tmpScript = HOOK_SCRIPT + '.intutic-tmp';
|
|
132
|
-
await node_fs.writeFile(tmpScript, buildPreToolCheckScript(), 'utf-8');
|
|
133
|
-
await node_fs.rename(tmpScript, HOOK_SCRIPT);
|
|
134
|
-
await node_fs.chmod(HOOK_SCRIPT, 0o755);
|
|
135
|
-
log.info({ action: 'openhands_hook_script_written', path: HOOK_SCRIPT }, 'Shared pre-tool-check.sh written');
|
|
136
|
-
// ── 2. Write .openhands/hooks.json ──────────────────────────────────
|
|
137
|
-
const openhandsDir = node_path.join(workspaceRoot, '.openhands');
|
|
138
|
-
await node_fs.mkdir(openhandsDir, { recursive: true });
|
|
139
|
-
const hooksJsonPath = node_path.join(openhandsDir, 'hooks.json');
|
|
140
|
-
const hooksDoc = buildOpenHandsHooksJson(HOOK_SCRIPT);
|
|
141
|
-
const tmpHooks = hooksJsonPath + '.intutic-tmp';
|
|
142
|
-
await node_fs.writeFile(tmpHooks, JSON.stringify(hooksDoc, null, 2) + '\n', 'utf-8');
|
|
143
|
-
await node_fs.rename(tmpHooks, hooksJsonPath);
|
|
144
|
-
log.info({ action: 'openhands_hooks_json_written', path: hooksJsonPath }, 'OpenHands hooks.json written');
|
|
145
|
-
}
|
|
146
|
-
//# sourceMappingURL=openhandsHooksWriter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openhandsHooksWriter.js","sourceRoot":"","sources":["../../src/harness/openhandsHooksWriter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,GAAG,GAAG,YAAY,CAAC,6BAA6B,CAAC,CAAA;AAEvD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;AACxE,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;AAC1E,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAA;AAClE,MAAM,eAAe,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAA;AAEvE;;;;;;;;;;;;;;;GAeG;AACH,SAAS,uBAAuB;IAC9B,OAAO;;;;;;;;kBAQS,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDhD,CAAA;AACD,CAAC;AAED;;;;GAIG;AACH,SAAS,uBAAuB,CAAC,cAAsB;IACrD,OAAO;QACL,QAAQ,EAAE,yDAAyD;QACnE,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,cAAc;gBACvB,OAAO,EAAE,EAAE;aACZ;SACF;KACF,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,aAAqB;IAC7D,wEAAwE;IACxE,MAAM,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACnD,MAAM,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAEpD,uEAAuE;IACvE,MAAM,SAAS,GAAG,WAAW,GAAG,cAAc,CAAA;IAC9C,MAAM,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,uBAAuB,EAAE,EAAE,OAAO,CAAC,CAAA;IACtE,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;IAC5C,MAAM,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IAEvC,GAAG,CAAC,IAAI,CACN,EAAE,MAAM,EAAE,+BAA+B,EAAE,IAAI,EAAE,WAAW,EAAE,EAC9D,kCAAkC,CACnC,CAAA;IAED,uEAAuE;IACvE,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;IAChE,MAAM,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAEtD,MAAM,aAAa,GAAG,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;IAChE,MAAM,QAAQ,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAA;IAErD,MAAM,QAAQ,GAAG,aAAa,GAAG,cAAc,CAAA;IAC/C,MAAM,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;IACpF,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAA;IAE7C,GAAG,CAAC,IAAI,CACN,EAAE,MAAM,EAAE,8BAA8B,EAAE,IAAI,EAAE,aAAa,EAAE,EAC/D,8BAA8B,CAC/B,CAAA;AACH,CAAC"}
|