@intutic/sync-daemon 1.10.0 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/README.md +2 -2
  2. package/dist/agentReporter.d.ts +205 -0
  3. package/dist/agentReporter.d.ts.map +1 -0
  4. package/dist/agentReporter.js +394 -0
  5. package/dist/agentReporter.js.map +1 -0
  6. package/dist/configReader.d.ts +39 -2
  7. package/dist/configReader.d.ts.map +1 -1
  8. package/dist/configReader.js +56 -2
  9. package/dist/configReader.js.map +1 -1
  10. package/dist/configWriter.d.ts +51 -1
  11. package/dist/configWriter.d.ts.map +1 -1
  12. package/dist/configWriter.js +490 -63
  13. package/dist/configWriter.js.map +1 -1
  14. package/dist/harness/antigravityHooks.d.ts.map +1 -1
  15. package/dist/harness/antigravityHooks.js +33 -55
  16. package/dist/harness/antigravityHooks.js.map +1 -1
  17. package/dist/harness/claudeCodeHooks.d.ts +47 -13
  18. package/dist/harness/claudeCodeHooks.d.ts.map +1 -1
  19. package/dist/harness/claudeCodeHooks.js +316 -54
  20. package/dist/harness/claudeCodeHooks.js.map +1 -1
  21. package/dist/harness/claudeDesktopHooks.d.ts.map +1 -1
  22. package/dist/harness/claudeDesktopHooks.js +35 -48
  23. package/dist/harness/claudeDesktopHooks.js.map +1 -1
  24. package/dist/harness/clineHooks.d.ts.map +1 -1
  25. package/dist/harness/clineHooks.js +42 -34
  26. package/dist/harness/clineHooks.js.map +1 -1
  27. package/dist/harness/codexHooks.d.ts +36 -0
  28. package/dist/harness/codexHooks.d.ts.map +1 -0
  29. package/dist/harness/codexHooks.js +227 -0
  30. package/dist/harness/codexHooks.js.map +1 -0
  31. package/dist/harness/continueHooks.d.ts +45 -5
  32. package/dist/harness/continueHooks.d.ts.map +1 -1
  33. package/dist/harness/continueHooks.js +225 -5
  34. package/dist/harness/continueHooks.js.map +1 -1
  35. package/dist/harness/cursorHooks.d.ts +31 -0
  36. package/dist/harness/cursorHooks.d.ts.map +1 -1
  37. package/dist/harness/cursorHooks.js +78 -49
  38. package/dist/harness/cursorHooks.js.map +1 -1
  39. package/dist/harness/dshHooks.d.ts +198 -0
  40. package/dist/harness/dshHooks.d.ts.map +1 -0
  41. package/dist/harness/dshHooks.js +569 -0
  42. package/dist/harness/dshHooks.js.map +1 -0
  43. package/dist/harness/gateBody.d.ts +422 -0
  44. package/dist/harness/gateBody.d.ts.map +1 -0
  45. package/dist/harness/gateBody.js +1816 -0
  46. package/dist/harness/gateBody.js.map +1 -0
  47. package/dist/harness/gateKind.d.ts +164 -0
  48. package/dist/harness/gateKind.d.ts.map +1 -0
  49. package/dist/harness/gateKind.js +143 -0
  50. package/dist/harness/gateKind.js.map +1 -0
  51. package/dist/harness/githubCopilotHooks.d.ts +54 -0
  52. package/dist/harness/githubCopilotHooks.d.ts.map +1 -0
  53. package/dist/harness/githubCopilotHooks.js +218 -0
  54. package/dist/harness/githubCopilotHooks.js.map +1 -0
  55. package/dist/harness/gooseHooks.d.ts.map +1 -1
  56. package/dist/harness/gooseHooks.js +67 -37
  57. package/dist/harness/gooseHooks.js.map +1 -1
  58. package/dist/harness/grokHooks.d.ts +77 -0
  59. package/dist/harness/grokHooks.d.ts.map +1 -0
  60. package/dist/harness/grokHooks.js +350 -0
  61. package/dist/harness/grokHooks.js.map +1 -0
  62. package/dist/harness/hermesHooks.d.ts.map +1 -1
  63. package/dist/harness/hermesHooks.js +26 -55
  64. package/dist/harness/hermesHooks.js.map +1 -1
  65. package/dist/harness/holdRedaction.d.ts +69 -0
  66. package/dist/harness/holdRedaction.d.ts.map +1 -0
  67. package/dist/harness/holdRedaction.js +211 -0
  68. package/dist/harness/holdRedaction.js.map +1 -0
  69. package/dist/harness/jetbrainsXmlConfig.d.ts +51 -0
  70. package/dist/harness/jetbrainsXmlConfig.d.ts.map +1 -0
  71. package/dist/harness/jetbrainsXmlConfig.js +151 -0
  72. package/dist/harness/jetbrainsXmlConfig.js.map +1 -0
  73. package/dist/harness/mcpAutoWrite.d.ts +100 -3
  74. package/dist/harness/mcpAutoWrite.d.ts.map +1 -1
  75. package/dist/harness/mcpAutoWrite.js +712 -90
  76. package/dist/harness/mcpAutoWrite.js.map +1 -1
  77. package/dist/harness/museHooks.d.ts +53 -0
  78. package/dist/harness/museHooks.d.ts.map +1 -0
  79. package/dist/harness/museHooks.js +273 -0
  80. package/dist/harness/museHooks.js.map +1 -0
  81. package/dist/harness/n8nHooks.d.ts +25 -9
  82. package/dist/harness/n8nHooks.d.ts.map +1 -1
  83. package/dist/harness/n8nHooks.js +174 -9
  84. package/dist/harness/n8nHooks.js.map +1 -1
  85. package/dist/harness/openCodeHooks.d.ts +93 -0
  86. package/dist/harness/openCodeHooks.d.ts.map +1 -0
  87. package/dist/harness/openCodeHooks.js +248 -0
  88. package/dist/harness/openCodeHooks.js.map +1 -0
  89. package/dist/harness/openWebuiHooks.d.ts.map +1 -1
  90. package/dist/harness/openWebuiHooks.js +56 -11
  91. package/dist/harness/openWebuiHooks.js.map +1 -1
  92. package/dist/harness/openclawHooks.d.ts.map +1 -1
  93. package/dist/harness/openclawHooks.js +30 -54
  94. package/dist/harness/openclawHooks.js.map +1 -1
  95. package/dist/harness/openhandsHooks.d.ts.map +1 -1
  96. package/dist/harness/openhandsHooks.js +35 -41
  97. package/dist/harness/openhandsHooks.js.map +1 -1
  98. package/dist/harness/piHooks.d.ts.map +1 -1
  99. package/dist/harness/piHooks.js +31 -58
  100. package/dist/harness/piHooks.js.map +1 -1
  101. package/dist/harness/protectedPaths.d.ts +353 -0
  102. package/dist/harness/protectedPaths.d.ts.map +1 -0
  103. package/dist/harness/protectedPaths.js +805 -0
  104. package/dist/harness/protectedPaths.js.map +1 -0
  105. package/dist/harness/rooCodeHooks.d.ts.map +1 -1
  106. package/dist/harness/rooCodeHooks.js +34 -48
  107. package/dist/harness/rooCodeHooks.js.map +1 -1
  108. package/dist/harness/windsurfHooks.d.ts +72 -0
  109. package/dist/harness/windsurfHooks.d.ts.map +1 -1
  110. package/dist/harness/windsurfHooks.js +172 -58
  111. package/dist/harness/windsurfHooks.js.map +1 -1
  112. package/dist/harness/windsurfJetBrainsProxy.d.ts +78 -0
  113. package/dist/harness/windsurfJetBrainsProxy.d.ts.map +1 -0
  114. package/dist/harness/windsurfJetBrainsProxy.js +159 -0
  115. package/dist/harness/windsurfJetBrainsProxy.js.map +1 -0
  116. package/dist/hashReporter.js +1 -1
  117. package/dist/hashReporter.js.map +1 -1
  118. package/dist/index.d.ts +12 -6
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +14 -6
  121. package/dist/index.js.map +1 -1
  122. package/dist/integrityStore.d.ts +0 -8
  123. package/dist/integrityStore.d.ts.map +1 -1
  124. package/dist/integrityStore.js +6 -29
  125. package/dist/integrityStore.js.map +1 -1
  126. package/dist/lib/approvedBypasses.d.ts +76 -0
  127. package/dist/lib/approvedBypasses.d.ts.map +1 -0
  128. package/dist/lib/approvedBypasses.js +140 -0
  129. package/dist/lib/approvedBypasses.js.map +1 -0
  130. package/dist/lib/complianceProbes.d.ts.map +1 -1
  131. package/dist/lib/complianceProbes.js +5 -0
  132. package/dist/lib/complianceProbes.js.map +1 -1
  133. package/dist/lib/decisionsDigest.d.ts +99 -0
  134. package/dist/lib/decisionsDigest.d.ts.map +1 -0
  135. package/dist/lib/decisionsDigest.js +199 -0
  136. package/dist/lib/decisionsDigest.js.map +1 -0
  137. package/dist/lib/egressPolicy.d.ts +69 -0
  138. package/dist/lib/egressPolicy.d.ts.map +1 -0
  139. package/dist/lib/egressPolicy.js +126 -0
  140. package/dist/lib/egressPolicy.js.map +1 -0
  141. package/dist/lib/gitWorktrees.d.ts +140 -0
  142. package/dist/lib/gitWorktrees.d.ts.map +1 -0
  143. package/dist/lib/gitWorktrees.js +191 -0
  144. package/dist/lib/gitWorktrees.js.map +1 -0
  145. package/dist/lib/policySnapshot.d.ts +224 -0
  146. package/dist/lib/policySnapshot.d.ts.map +1 -0
  147. package/dist/lib/policySnapshot.js +637 -0
  148. package/dist/lib/policySnapshot.js.map +1 -0
  149. package/dist/lib/processPoller.d.ts +44 -0
  150. package/dist/lib/processPoller.d.ts.map +1 -1
  151. package/dist/lib/processPoller.js +176 -1
  152. package/dist/lib/processPoller.js.map +1 -1
  153. package/dist/lib/runtimeEnv.d.ts +8 -0
  154. package/dist/lib/runtimeEnv.d.ts.map +1 -1
  155. package/dist/lib/runtimeEnv.js +3 -0
  156. package/dist/lib/runtimeEnv.js.map +1 -1
  157. package/dist/localTrajectoryHeuristics.d.ts +51 -0
  158. package/dist/localTrajectoryHeuristics.d.ts.map +1 -0
  159. package/dist/localTrajectoryHeuristics.js +90 -0
  160. package/dist/localTrajectoryHeuristics.js.map +1 -0
  161. package/dist/sessionReporter.d.ts +70 -0
  162. package/dist/sessionReporter.d.ts.map +1 -0
  163. package/dist/sessionReporter.js +140 -0
  164. package/dist/sessionReporter.js.map +1 -0
  165. package/dist/skillWriter.d.ts +1 -1
  166. package/dist/skillWriter.d.ts.map +1 -1
  167. package/dist/skillWriter.js +5 -2
  168. package/dist/skillWriter.js.map +1 -1
  169. package/dist/syncLoop.d.ts +105 -3
  170. package/dist/syncLoop.d.ts.map +1 -1
  171. package/dist/syncLoop.js +397 -65
  172. package/dist/syncLoop.js.map +1 -1
  173. package/dist/trajectoryMonitor.d.ts +2 -0
  174. package/dist/trajectoryMonitor.d.ts.map +1 -1
  175. package/dist/trajectoryMonitor.js +57 -0
  176. package/dist/trajectoryMonitor.js.map +1 -1
  177. package/dist/watcher/driftWatcher.d.ts.map +1 -1
  178. package/dist/watcher/driftWatcher.js +12 -3
  179. package/dist/watcher/driftWatcher.js.map +1 -1
  180. package/dist/watcher/settingsGuard.d.ts +23 -0
  181. package/dist/watcher/settingsGuard.d.ts.map +1 -1
  182. package/dist/watcher/settingsGuard.js +202 -17
  183. package/dist/watcher/settingsGuard.js.map +1 -1
  184. package/package.json +37 -6
  185. package/dist/brainIndexer.d.ts +0 -51
  186. package/dist/brainIndexer.d.ts.map +0 -1
  187. package/dist/brainIndexer.js +0 -148
  188. package/dist/brainIndexer.js.map +0 -1
  189. package/dist/harness/cursorHooksJson.d.ts +0 -29
  190. package/dist/harness/cursorHooksJson.d.ts.map +0 -1
  191. package/dist/harness/cursorHooksJson.js +0 -130
  192. package/dist/harness/cursorHooksJson.js.map +0 -1
  193. package/dist/harness/gooseHooksWriter.d.ts +0 -27
  194. package/dist/harness/gooseHooksWriter.d.ts.map +0 -1
  195. package/dist/harness/gooseHooksWriter.js +0 -147
  196. package/dist/harness/gooseHooksWriter.js.map +0 -1
  197. package/dist/harness/openhandsHooksWriter.d.ts +0 -23
  198. package/dist/harness/openhandsHooksWriter.d.ts.map +0 -1
  199. package/dist/harness/openhandsHooksWriter.js +0 -146
  200. 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":"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"}