@intutic/sync-daemon 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/brainIndexer.d.ts +51 -0
- package/dist/brainIndexer.d.ts.map +1 -0
- package/dist/brainIndexer.js +148 -0
- package/dist/brainIndexer.js.map +1 -0
- package/dist/configReader.d.ts +46 -0
- package/dist/configReader.d.ts.map +1 -0
- package/dist/configReader.js +133 -0
- package/dist/configReader.js.map +1 -0
- package/dist/configWriter.d.ts +53 -0
- package/dist/configWriter.d.ts.map +1 -0
- package/dist/configWriter.js +503 -0
- package/dist/configWriter.js.map +1 -0
- package/dist/harness/aiderConfigMerger.d.ts +27 -0
- package/dist/harness/aiderConfigMerger.d.ts.map +1 -0
- package/dist/harness/aiderConfigMerger.js +139 -0
- package/dist/harness/aiderConfigMerger.js.map +1 -0
- package/dist/harness/antigravityHooks.d.ts +43 -0
- package/dist/harness/antigravityHooks.d.ts.map +1 -0
- package/dist/harness/antigravityHooks.js +193 -0
- package/dist/harness/antigravityHooks.js.map +1 -0
- package/dist/harness/claudeCodeHooks.d.ts +59 -0
- package/dist/harness/claudeCodeHooks.d.ts.map +1 -0
- package/dist/harness/claudeCodeHooks.js +414 -0
- package/dist/harness/claudeCodeHooks.js.map +1 -0
- package/dist/harness/claudeDesktopHooks.d.ts +30 -0
- package/dist/harness/claudeDesktopHooks.d.ts.map +1 -0
- package/dist/harness/claudeDesktopHooks.js +267 -0
- package/dist/harness/claudeDesktopHooks.js.map +1 -0
- package/dist/harness/clineHooks.d.ts +23 -0
- package/dist/harness/clineHooks.d.ts.map +1 -0
- package/dist/harness/clineHooks.js +169 -0
- package/dist/harness/clineHooks.js.map +1 -0
- package/dist/harness/continueHooks.d.ts +33 -0
- package/dist/harness/continueHooks.d.ts.map +1 -0
- package/dist/harness/continueHooks.js +124 -0
- package/dist/harness/continueHooks.js.map +1 -0
- package/dist/harness/cursorHooks.d.ts +27 -0
- package/dist/harness/cursorHooks.d.ts.map +1 -0
- package/dist/harness/cursorHooks.js +221 -0
- package/dist/harness/cursorHooks.js.map +1 -0
- package/dist/harness/cursorHooksJson.d.ts +29 -0
- package/dist/harness/cursorHooksJson.d.ts.map +1 -0
- package/dist/harness/cursorHooksJson.js +130 -0
- package/dist/harness/cursorHooksJson.js.map +1 -0
- package/dist/harness/gooseHardener.d.ts +39 -0
- package/dist/harness/gooseHardener.d.ts.map +1 -0
- package/dist/harness/gooseHardener.js +152 -0
- package/dist/harness/gooseHardener.js.map +1 -0
- package/dist/harness/gooseHooks.d.ts +24 -0
- package/dist/harness/gooseHooks.d.ts.map +1 -0
- package/dist/harness/gooseHooks.js +175 -0
- package/dist/harness/gooseHooks.js.map +1 -0
- package/dist/harness/gooseHooksWriter.d.ts +27 -0
- package/dist/harness/gooseHooksWriter.d.ts.map +1 -0
- package/dist/harness/gooseHooksWriter.js +147 -0
- package/dist/harness/gooseHooksWriter.js.map +1 -0
- package/dist/harness/hermesHooks.d.ts +31 -0
- package/dist/harness/hermesHooks.d.ts.map +1 -0
- package/dist/harness/hermesHooks.js +245 -0
- package/dist/harness/hermesHooks.js.map +1 -0
- package/dist/harness/mcpAutoWrite.d.ts +35 -0
- package/dist/harness/mcpAutoWrite.d.ts.map +1 -0
- package/dist/harness/mcpAutoWrite.js +334 -0
- package/dist/harness/mcpAutoWrite.js.map +1 -0
- package/dist/harness/n8nHooks.d.ts +28 -0
- package/dist/harness/n8nHooks.d.ts.map +1 -0
- package/dist/harness/n8nHooks.js +205 -0
- package/dist/harness/n8nHooks.js.map +1 -0
- package/dist/harness/openWebuiHooks.d.ts +31 -0
- package/dist/harness/openWebuiHooks.d.ts.map +1 -0
- package/dist/harness/openWebuiHooks.js +166 -0
- package/dist/harness/openWebuiHooks.js.map +1 -0
- package/dist/harness/openclawHooks.d.ts +34 -0
- package/dist/harness/openclawHooks.d.ts.map +1 -0
- package/dist/harness/openclawHooks.js +296 -0
- package/dist/harness/openclawHooks.js.map +1 -0
- package/dist/harness/openhandsHooks.d.ts +24 -0
- package/dist/harness/openhandsHooks.d.ts.map +1 -0
- package/dist/harness/openhandsHooks.js +178 -0
- package/dist/harness/openhandsHooks.js.map +1 -0
- package/dist/harness/openhandsHooksWriter.d.ts +23 -0
- package/dist/harness/openhandsHooksWriter.d.ts.map +1 -0
- package/dist/harness/openhandsHooksWriter.js +146 -0
- package/dist/harness/openhandsHooksWriter.js.map +1 -0
- package/dist/harness/piHooks.d.ts +32 -0
- package/dist/harness/piHooks.d.ts.map +1 -0
- package/dist/harness/piHooks.js +257 -0
- package/dist/harness/piHooks.js.map +1 -0
- package/dist/harness/rooCodeHooks.d.ts +31 -0
- package/dist/harness/rooCodeHooks.d.ts.map +1 -0
- package/dist/harness/rooCodeHooks.js +300 -0
- package/dist/harness/rooCodeHooks.js.map +1 -0
- package/dist/harness/windsurfHooks.d.ts +27 -0
- package/dist/harness/windsurfHooks.d.ts.map +1 -0
- package/dist/harness/windsurfHooks.js +202 -0
- package/dist/harness/windsurfHooks.js.map +1 -0
- package/dist/hashReporter.d.ts +33 -0
- package/dist/hashReporter.d.ts.map +1 -0
- package/dist/hashReporter.js +69 -0
- package/dist/hashReporter.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/integrityStore.d.ts +43 -0
- package/dist/integrityStore.d.ts.map +1 -0
- package/dist/integrityStore.js +94 -0
- package/dist/integrityStore.js.map +1 -0
- package/dist/lib/complianceProbes.d.ts +39 -0
- package/dist/lib/complianceProbes.d.ts.map +1 -0
- package/dist/lib/complianceProbes.js +115 -0
- package/dist/lib/complianceProbes.js.map +1 -0
- package/dist/lib/processPoller.d.ts +2 -0
- package/dist/lib/processPoller.d.ts.map +1 -0
- package/dist/lib/processPoller.js +87 -0
- package/dist/lib/processPoller.js.map +1 -0
- package/dist/lib/runtimeEnv.d.ts +49 -0
- package/dist/lib/runtimeEnv.d.ts.map +1 -0
- package/dist/lib/runtimeEnv.js +70 -0
- package/dist/lib/runtimeEnv.js.map +1 -0
- package/dist/skillWriter.d.ts +24 -0
- package/dist/skillWriter.d.ts.map +1 -0
- package/dist/skillWriter.js +112 -0
- package/dist/skillWriter.js.map +1 -0
- package/dist/syncLoop.d.ts +70 -0
- package/dist/syncLoop.d.ts.map +1 -0
- package/dist/syncLoop.js +546 -0
- package/dist/syncLoop.js.map +1 -0
- package/dist/trajectoryMonitor.d.ts +126 -0
- package/dist/trajectoryMonitor.d.ts.map +1 -0
- package/dist/trajectoryMonitor.js +291 -0
- package/dist/trajectoryMonitor.js.map +1 -0
- package/dist/watcher/driftWatcher.d.ts +25 -0
- package/dist/watcher/driftWatcher.d.ts.map +1 -0
- package/dist/watcher/driftWatcher.js +72 -0
- package/dist/watcher/driftWatcher.js.map +1 -0
- package/dist/watcher/settingsGuard.d.ts +32 -0
- package/dist/watcher/settingsGuard.d.ts.map +1 -0
- package/dist/watcher/settingsGuard.js +250 -0
- package/dist/watcher/settingsGuard.js.map +1 -0
- package/dist/wsClient.d.ts +49 -0
- package/dist/wsClient.d.ts.map +1 -0
- package/dist/wsClient.js +149 -0
- package/dist/wsClient.js.map +1 -0
- package/package.json +96 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* aiderConfigMerger.ts — Safe YAML merge for .aider.conf.yml.
|
|
3
|
+
*
|
|
4
|
+
* Reads any existing .aider.conf.yml, STRIPS dangerous auto-exec keys
|
|
5
|
+
* (test-cmd, lint-cmd, auto-test, auto-lint), merges in Intutic governance
|
|
6
|
+
* keys (openai-api-base, anthropic-api-base), and writes back atomically.
|
|
7
|
+
*
|
|
8
|
+
* Each strip emits a governance_config_sanitized log entry visible in
|
|
9
|
+
* the control plane audit feed.
|
|
10
|
+
*
|
|
11
|
+
* LLD #14 — Phase 3 cross-harness defence
|
|
12
|
+
* HLD §3.14 — Three-Tier Defense Cascade
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import * as fs from 'node:fs/promises';
|
|
17
|
+
import * as path from 'node:path';
|
|
18
|
+
import { createLogger } from '@intutic/logger';
|
|
19
|
+
import { newIso } from '@intutic/id';
|
|
20
|
+
const log = createLogger('sync-aider-merger');
|
|
21
|
+
/**
|
|
22
|
+
* Keys that Aider auto-executes on startup without user confirmation.
|
|
23
|
+
* Stripping these prevents supply-chain persistence attacks.
|
|
24
|
+
*/
|
|
25
|
+
const SUPPRESSED_KEYS = ['test-cmd', 'lint-cmd', 'auto-test', 'auto-lint', 'test_cmd', 'lint_cmd'];
|
|
26
|
+
/**
|
|
27
|
+
* Minimal YAML parser for .aider.conf.yml — handles simple key: value lines
|
|
28
|
+
* and multi-line strings. Does not handle complex YAML. Good enough for the
|
|
29
|
+
* flat structure of .aider.conf.yml.
|
|
30
|
+
*/
|
|
31
|
+
function parseAiderYaml(raw) {
|
|
32
|
+
const result = {};
|
|
33
|
+
const lines = raw.split('\n');
|
|
34
|
+
let i = 0;
|
|
35
|
+
while (i < lines.length) {
|
|
36
|
+
const line = lines[i];
|
|
37
|
+
// Skip comments and blank lines
|
|
38
|
+
if (!line || line.trim().startsWith('#')) {
|
|
39
|
+
i++;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const colonIdx = line.indexOf(':');
|
|
43
|
+
if (colonIdx === -1) {
|
|
44
|
+
i++;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const key = line.slice(0, colonIdx).trim();
|
|
48
|
+
const rest = line.slice(colonIdx + 1).trim();
|
|
49
|
+
if (rest === '|' || rest === '>') {
|
|
50
|
+
// Multi-line block scalar — collect until next key or EOF
|
|
51
|
+
const blockLines = [];
|
|
52
|
+
i++;
|
|
53
|
+
while (i < lines.length && (lines[i].startsWith(' ') || lines[i] === '')) {
|
|
54
|
+
blockLines.push(lines[i].startsWith(' ') ? lines[i].slice(2) : '');
|
|
55
|
+
i++;
|
|
56
|
+
}
|
|
57
|
+
result[key] = blockLines.join('\n').trimEnd();
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// Strip inline quotes
|
|
61
|
+
result[key] = rest.replace(/^["']|["']$/g, '');
|
|
62
|
+
i++;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Minimal YAML serializer — writes flat key: value pairs.
|
|
69
|
+
* Multi-line values use the | block scalar style.
|
|
70
|
+
*/
|
|
71
|
+
function serializeAiderYaml(obj) {
|
|
72
|
+
const lines = [];
|
|
73
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
74
|
+
if (typeof value === 'string' && value.includes('\n')) {
|
|
75
|
+
lines.push(`${key}: |`);
|
|
76
|
+
for (const ln of value.split('\n')) {
|
|
77
|
+
lines.push(` ${ln}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else if (typeof value === 'boolean') {
|
|
81
|
+
lines.push(`${key}: ${value}`);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
lines.push(`${key}: ${String(value)}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return lines.join('\n');
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Merge Intutic governance settings into .aider.conf.yml.
|
|
91
|
+
*
|
|
92
|
+
* Preserves all user keys EXCEPT the suppressed auto-exec keys.
|
|
93
|
+
* Adds/updates openai-api-base and anthropic-api-base.
|
|
94
|
+
*
|
|
95
|
+
* @param configPath - Absolute path to .aider.conf.yml
|
|
96
|
+
* @param proxyUrl - Intutic proxy URL
|
|
97
|
+
* @param sopsText - Optional SOP instructions for extra-instructions field
|
|
98
|
+
*/
|
|
99
|
+
export async function mergeAiderConfig(configPath, proxyUrl, sopsText) {
|
|
100
|
+
// Read existing config if present
|
|
101
|
+
let existing = {};
|
|
102
|
+
try {
|
|
103
|
+
const raw = await fs.readFile(configPath, 'utf-8');
|
|
104
|
+
existing = parseAiderYaml(raw);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// No existing file — start fresh
|
|
108
|
+
}
|
|
109
|
+
// Strip dangerous auto-exec keys
|
|
110
|
+
const stripped = [];
|
|
111
|
+
for (const key of SUPPRESSED_KEYS) {
|
|
112
|
+
if (key in existing) {
|
|
113
|
+
stripped.push(key);
|
|
114
|
+
delete existing[key];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (stripped.length > 0) {
|
|
118
|
+
log.warn({ action: 'aider_keys_stripped', keys: stripped, path: configPath }, `Stripped dangerous auto-exec keys from .aider.conf.yml: ${stripped.join(', ')}`);
|
|
119
|
+
}
|
|
120
|
+
// Merge governance keys
|
|
121
|
+
existing['openai-api-base'] = proxyUrl;
|
|
122
|
+
existing['anthropic-api-base'] = proxyUrl;
|
|
123
|
+
if (sopsText) {
|
|
124
|
+
existing['extra-instructions'] = sopsText;
|
|
125
|
+
}
|
|
126
|
+
const header = [
|
|
127
|
+
'# Intutic Governance Rules (auto-generated — do not edit proxy keys)',
|
|
128
|
+
`# Last sync: ${newIso()}`,
|
|
129
|
+
`# WARNING: test-cmd and lint-cmd keys are suppressed by Intutic governance`,
|
|
130
|
+
'',
|
|
131
|
+
].join('\n');
|
|
132
|
+
const content = header + serializeAiderYaml(existing) + '\n';
|
|
133
|
+
const tmpPath = configPath + '.intutic-tmp';
|
|
134
|
+
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
135
|
+
await fs.writeFile(tmpPath, content, 'utf-8');
|
|
136
|
+
await fs.rename(tmpPath, configPath);
|
|
137
|
+
log.info({ action: 'aider_config_written', path: configPath, stripped }, 'Aider config merged with proxy URL and dangerous keys stripped');
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=aiderConfigMerger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aiderConfigMerger.js","sourceRoot":"","sources":["../../src/harness/aiderConfigMerger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* antigravityHooks.ts — Gemini CLI (Antigravity) governance hook injection.
|
|
3
|
+
*
|
|
4
|
+
* Antigravity (Google DeepMind's Gemini CLI) supports a tool-level governance
|
|
5
|
+
* hook via the `ANTIGRAVITY_PRE_TOOL_HOOK` environment variable and an optional
|
|
6
|
+
* hook configuration file at `~/.gemini/settings.json`. This module:
|
|
7
|
+
*
|
|
8
|
+
* 1. Writes a pre-tool-check.sh script to `.intutic/hooks/antigravity-check.sh`
|
|
9
|
+
* (same pattern as Goose / OpenHands bash hooks).
|
|
10
|
+
* 2. Merges the hook path into `~/.gemini/settings.json` under the
|
|
11
|
+
* `hooks.preTool` key.
|
|
12
|
+
* 3. Optionally writes an `ANTIGRAVITY_PROXY_URL` env snippet to
|
|
13
|
+
* `.intutic/env/antigravity.env` for IDE/shell integration.
|
|
14
|
+
*
|
|
15
|
+
* Why bash and not Node.js?
|
|
16
|
+
* The Gemini CLI (antigravity) is a standalone binary; when it invokes
|
|
17
|
+
* a pre-tool hook it sets the current directory to the workspace root.
|
|
18
|
+
* A bash script is the most portable solution for the widest range of
|
|
19
|
+
* user configurations (no Node.js version dependency, no CJS/ESM split).
|
|
20
|
+
*
|
|
21
|
+
* Hook events:
|
|
22
|
+
* Every block/allow is appended to `.intutic/events/hook-events.jsonl`
|
|
23
|
+
* and drained to the control plane via FSEvents-driven drain.
|
|
24
|
+
*
|
|
25
|
+
* LLD #14 — Phase 3 cross-harness defence (Gap 3)
|
|
26
|
+
* HLD §3.14 — Three-Tier Defense Cascade (Tier 1 Native Gating)
|
|
27
|
+
* HLD §3.x — Gemini CLI / Antigravity harness
|
|
28
|
+
*
|
|
29
|
+
* @module
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Write the Antigravity (Gemini CLI) governance hook script and merge
|
|
33
|
+
* hook configuration into `~/.gemini/settings.json`.
|
|
34
|
+
*
|
|
35
|
+
* Safe to call repeatedly — uses atomic rename (`.intutic-tmp` → final path)
|
|
36
|
+
* so partial writes never leave a corrupt script in place.
|
|
37
|
+
*
|
|
38
|
+
* @param workspaceRoot - Absolute workspace root path.
|
|
39
|
+
* @param proxyUrl - Intutic proxy URL written into the hook script header.
|
|
40
|
+
* @param workspaceId - Workspace ID embedded in every hook event payload.
|
|
41
|
+
*/
|
|
42
|
+
export declare function writeAntigravityHooks(workspaceRoot: string, proxyUrl: string, workspaceId?: string): Promise<void>;
|
|
43
|
+
//# sourceMappingURL=antigravityHooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"antigravityHooks.d.ts","sourceRoot":"","sources":["../../src/harness/antigravityHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAgHH;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,WAAW,SAAK,GACf,OAAO,CAAC,IAAI,CAAC,CAsEf"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* antigravityHooks.ts — Gemini CLI (Antigravity) governance hook injection.
|
|
3
|
+
*
|
|
4
|
+
* Antigravity (Google DeepMind's Gemini CLI) supports a tool-level governance
|
|
5
|
+
* hook via the `ANTIGRAVITY_PRE_TOOL_HOOK` environment variable and an optional
|
|
6
|
+
* hook configuration file at `~/.gemini/settings.json`. This module:
|
|
7
|
+
*
|
|
8
|
+
* 1. Writes a pre-tool-check.sh script to `.intutic/hooks/antigravity-check.sh`
|
|
9
|
+
* (same pattern as Goose / OpenHands bash hooks).
|
|
10
|
+
* 2. Merges the hook path into `~/.gemini/settings.json` under the
|
|
11
|
+
* `hooks.preTool` key.
|
|
12
|
+
* 3. Optionally writes an `ANTIGRAVITY_PROXY_URL` env snippet to
|
|
13
|
+
* `.intutic/env/antigravity.env` for IDE/shell integration.
|
|
14
|
+
*
|
|
15
|
+
* Why bash and not Node.js?
|
|
16
|
+
* The Gemini CLI (antigravity) is a standalone binary; when it invokes
|
|
17
|
+
* a pre-tool hook it sets the current directory to the workspace root.
|
|
18
|
+
* A bash script is the most portable solution for the widest range of
|
|
19
|
+
* user configurations (no Node.js version dependency, no CJS/ESM split).
|
|
20
|
+
*
|
|
21
|
+
* Hook events:
|
|
22
|
+
* Every block/allow is appended to `.intutic/events/hook-events.jsonl`
|
|
23
|
+
* and drained to the control plane via FSEvents-driven drain.
|
|
24
|
+
*
|
|
25
|
+
* LLD #14 — Phase 3 cross-harness defence (Gap 3)
|
|
26
|
+
* HLD §3.14 — Three-Tier Defense Cascade (Tier 1 Native Gating)
|
|
27
|
+
* HLD §3.x — Gemini CLI / Antigravity harness
|
|
28
|
+
*
|
|
29
|
+
* @module
|
|
30
|
+
*/
|
|
31
|
+
import * as fs from 'node:fs/promises';
|
|
32
|
+
import * as path from 'node:path';
|
|
33
|
+
import * as os from 'node:os';
|
|
34
|
+
import { createLogger } from '@intutic/logger';
|
|
35
|
+
import { newIso } from '@intutic/id';
|
|
36
|
+
const log = createLogger('sync-antigravity-hooks');
|
|
37
|
+
/** Default path to the Gemini CLI global settings file. */
|
|
38
|
+
const GEMINI_SETTINGS = path.join(os.homedir(), '.gemini', 'settings.json');
|
|
39
|
+
/** Governance-sensitive paths that the hook gate protects. */
|
|
40
|
+
const PROTECTED_PATHS = [
|
|
41
|
+
'.gemini/settings.json',
|
|
42
|
+
'.intutic/hooks',
|
|
43
|
+
'.intutic/integrity.json',
|
|
44
|
+
'.intutic/events',
|
|
45
|
+
'.claude/settings.json',
|
|
46
|
+
'.cursor/hooks.json',
|
|
47
|
+
'.codeium/windsurf/hooks.json',
|
|
48
|
+
'.cline/hooks',
|
|
49
|
+
'.agents/plugins/intutic-governance',
|
|
50
|
+
'.openhands/hooks.json',
|
|
51
|
+
];
|
|
52
|
+
// ─── Bash hook script template ────────────────────────────────────────────────
|
|
53
|
+
function buildAntigravityCheckScript(proxyUrl, workspaceRoot, workspaceId) {
|
|
54
|
+
const hookEventsLog = path.join(workspaceRoot, '.intutic', 'events', 'hook-events.jsonl');
|
|
55
|
+
return `#!/usr/bin/env bash
|
|
56
|
+
# Intutic Antigravity (Gemini CLI) PreToolUse governance gate.
|
|
57
|
+
# Auto-generated by intutic sync-daemon. DO NOT EDIT.
|
|
58
|
+
# Proxy: ${proxyUrl}
|
|
59
|
+
# Generated: ${newIso()}
|
|
60
|
+
# Workspace: ${workspaceId}
|
|
61
|
+
set -euo pipefail
|
|
62
|
+
|
|
63
|
+
INPUT="$(cat)"
|
|
64
|
+
TOOL_NAME="$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_name',''))" 2>/dev/null || true)"
|
|
65
|
+
TARGET_PATH="$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); i=d.get('tool_input',{}); print(i.get('path',i.get('file_path','')))" 2>/dev/null || true)"
|
|
66
|
+
COMMAND="$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); i=d.get('tool_input',{}); print(i.get('command',i.get('cmd','')))" 2>/dev/null || true)"
|
|
67
|
+
|
|
68
|
+
HOOK_EVENTS_LOG=${JSON.stringify(hookEventsLog)}
|
|
69
|
+
|
|
70
|
+
# Runtime credentials
|
|
71
|
+
RUNTIME_ENV="$HOME/.intutic/env/runtime.env"
|
|
72
|
+
INTUITIC_HOST="https://api.intutic.ai"
|
|
73
|
+
INTUITIC_API_KEY=""
|
|
74
|
+
INTUITIC_WORKSPACE_ID=${JSON.stringify(workspaceId)}
|
|
75
|
+
[ -f "$RUNTIME_ENV" ] && source "$RUNTIME_ENV" 2>/dev/null || true
|
|
76
|
+
|
|
77
|
+
log_event() {
|
|
78
|
+
local verdict="\$1" tool="\$2" reason="\$3"
|
|
79
|
+
local ts; ts="\$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
80
|
+
local incident_id; incident_id="\$(printf '%s' "\${ts}\${tool}\${INTUTIC_WORKSPACE_ID}" | sha1sum 2>/dev/null | cut -c1-16 || echo \"\$(date +%s)\")"
|
|
81
|
+
local entry="{\\"event\\":\\"\${verdict}\\",\\"toolName\\":\\"\${tool}\\",\\"reason\\":\\"\${reason}\\",\\"workspaceId\\":\\"\${INTUTIC_WORKSPACE_ID}\\",\\"harnessType\\":\\"antigravity\\",\\"timestamp\\":\\"\${ts}\\",\\"incidentId\\":\\"\${incident_id}\\"}"
|
|
82
|
+
printf '%s\\n' "\$entry" >> "\$HOOK_EVENTS_LOG" 2>/dev/null || true
|
|
83
|
+
if [ -n "\$INTUTIC_API_KEY" ]; then
|
|
84
|
+
curl -s -o /dev/null --max-time 3 -X POST \\
|
|
85
|
+
-H "Content-Type: application/json" \\
|
|
86
|
+
-H "Authorization: Bearer \$INTUTIC_API_KEY" \\
|
|
87
|
+
-d "{\"events\":[\$entry]}" \\
|
|
88
|
+
"\${INTUTIC_HOST}/api/v1/hook-events" & disown 2>/dev/null || true
|
|
89
|
+
fi
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
PROTECTED_PATHS=(
|
|
93
|
+
${PROTECTED_PATHS.map((p) => ` "${p}"`).join('\n')}
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# 1. Protected-path guard
|
|
97
|
+
for p in "\${PROTECTED_PATHS[@]}"; do
|
|
98
|
+
if echo "$TARGET_PATH" | grep -qF "$p"; then
|
|
99
|
+
REASON="Attempt to modify governance-protected path \\"$TARGET_PATH\\""
|
|
100
|
+
echo "[Intutic Governance] BLOCKED: $REASON" >&2
|
|
101
|
+
log_event "tool_blocked" "$TOOL_NAME" "$REASON"
|
|
102
|
+
exit 2
|
|
103
|
+
fi
|
|
104
|
+
done
|
|
105
|
+
|
|
106
|
+
# 2. Bash/shell command guard — block governance bypass patterns
|
|
107
|
+
if [ -n "$COMMAND" ]; then
|
|
108
|
+
BYPASS_PATTERNS=(
|
|
109
|
+
"chflags nouchg"
|
|
110
|
+
"chattr -i"
|
|
111
|
+
"rm -rf .intutic"
|
|
112
|
+
"rm -rf .gemini/settings"
|
|
113
|
+
"ANTIGRAVITY_PRE_TOOL_HOOK="
|
|
114
|
+
)
|
|
115
|
+
for pattern in "\${BYPASS_PATTERNS[@]}"; do
|
|
116
|
+
if echo "$COMMAND" | grep -qF "$pattern"; then
|
|
117
|
+
REASON="Shell command matches governance bypass pattern: \\"$pattern\\""
|
|
118
|
+
echo "[Intutic Governance] BLOCKED: $REASON" >&2
|
|
119
|
+
log_event "tool_blocked" "$TOOL_NAME" "$REASON"
|
|
120
|
+
exit 2
|
|
121
|
+
fi
|
|
122
|
+
done
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
log_event "tool_allowed" "$TOOL_NAME" ""
|
|
126
|
+
exit 0
|
|
127
|
+
`;
|
|
128
|
+
}
|
|
129
|
+
// ─── Main export ──────────────────────────────────────────────────────────────
|
|
130
|
+
/**
|
|
131
|
+
* Write the Antigravity (Gemini CLI) governance hook script and merge
|
|
132
|
+
* hook configuration into `~/.gemini/settings.json`.
|
|
133
|
+
*
|
|
134
|
+
* Safe to call repeatedly — uses atomic rename (`.intutic-tmp` → final path)
|
|
135
|
+
* so partial writes never leave a corrupt script in place.
|
|
136
|
+
*
|
|
137
|
+
* @param workspaceRoot - Absolute workspace root path.
|
|
138
|
+
* @param proxyUrl - Intutic proxy URL written into the hook script header.
|
|
139
|
+
* @param workspaceId - Workspace ID embedded in every hook event payload.
|
|
140
|
+
*/
|
|
141
|
+
export async function writeAntigravityHooks(workspaceRoot, proxyUrl, workspaceId = '') {
|
|
142
|
+
// ── 1. Ensure directories ──────────────────────────────────────────────────
|
|
143
|
+
const hookScriptDir = path.join(workspaceRoot, '.intutic', 'hooks');
|
|
144
|
+
const hookEventsDir = path.join(workspaceRoot, '.intutic', 'events');
|
|
145
|
+
const envDir = path.join(workspaceRoot, '.intutic', 'env');
|
|
146
|
+
await Promise.all([
|
|
147
|
+
fs.mkdir(hookScriptDir, { recursive: true }),
|
|
148
|
+
fs.mkdir(hookEventsDir, { recursive: true }),
|
|
149
|
+
fs.mkdir(envDir, { recursive: true }),
|
|
150
|
+
fs.mkdir(path.join(os.homedir(), '.gemini'), { recursive: true }),
|
|
151
|
+
]);
|
|
152
|
+
// ── 2. Write hook script ───────────────────────────────────────────────────
|
|
153
|
+
const hookScriptPath = path.join(hookScriptDir, 'antigravity-check.sh');
|
|
154
|
+
const tmpScript = hookScriptPath + '.intutic-tmp';
|
|
155
|
+
await fs.writeFile(tmpScript, buildAntigravityCheckScript(proxyUrl, workspaceRoot, workspaceId), 'utf-8');
|
|
156
|
+
await fs.rename(tmpScript, hookScriptPath);
|
|
157
|
+
await fs.chmod(hookScriptPath, 0o755);
|
|
158
|
+
log.info({ action: 'antigravity_hook_script_written', path: hookScriptPath }, 'Antigravity hook script written');
|
|
159
|
+
// ── 3. Merge into ~/.gemini/settings.json ─────────────────────────────────
|
|
160
|
+
let existingSettings = {};
|
|
161
|
+
try {
|
|
162
|
+
const raw = await fs.readFile(GEMINI_SETTINGS, 'utf-8');
|
|
163
|
+
existingSettings = JSON.parse(raw);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// File doesn't exist yet — start fresh
|
|
167
|
+
}
|
|
168
|
+
const mergedSettings = {
|
|
169
|
+
...existingSettings,
|
|
170
|
+
hooks: {
|
|
171
|
+
...existingSettings.hooks,
|
|
172
|
+
// Register the pre-tool hook command
|
|
173
|
+
preTool: hookScriptPath,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
const tmpSettings = GEMINI_SETTINGS + '.intutic-tmp';
|
|
177
|
+
await fs.writeFile(tmpSettings, JSON.stringify(mergedSettings, null, 2) + '\n', 'utf-8');
|
|
178
|
+
await fs.rename(tmpSettings, GEMINI_SETTINGS);
|
|
179
|
+
log.info({ action: 'antigravity_settings_written', path: GEMINI_SETTINGS }, 'Merged Intutic hook into ~/.gemini/settings.json');
|
|
180
|
+
// ── 4. Write env snippet (optional — for shell profiles / IDE env) ─────────
|
|
181
|
+
const envSnippet = [
|
|
182
|
+
`# Intutic Antigravity governance hook — auto-generated ${newIso()}`,
|
|
183
|
+
`# Source this file in ~/.bashrc or ~/.zshrc to apply governance to Gemini CLI.`,
|
|
184
|
+
`export ANTIGRAVITY_PRE_TOOL_HOOK=${JSON.stringify(hookScriptPath)}`,
|
|
185
|
+
proxyUrl ? `export ANTIGRAVITY_PROXY_URL=${JSON.stringify(proxyUrl)}` : '',
|
|
186
|
+
].filter(Boolean).join('\n') + '\n';
|
|
187
|
+
const envFilePath = path.join(envDir, 'antigravity.env');
|
|
188
|
+
const tmpEnv = envFilePath + '.intutic-tmp';
|
|
189
|
+
await fs.writeFile(tmpEnv, envSnippet, 'utf-8');
|
|
190
|
+
await fs.rename(tmpEnv, envFilePath);
|
|
191
|
+
log.info({ action: 'antigravity_env_written', path: envFilePath }, 'Antigravity env snippet written');
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=antigravityHooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"antigravityHooks.js","sourceRoot":"","sources":["../../src/harness/antigravityHooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* claudeCodeHooks.ts — Claude Code PreToolUse hook generator.
|
|
3
|
+
*
|
|
4
|
+
* Compiles SOP evaluation criteria and high risk tools into native Claude Code
|
|
5
|
+
* settings.json configurations (both permissions.deny rules and PreToolUse hooks).
|
|
6
|
+
* Writes configurations locally to the workspace and globally to ~/.claude/.
|
|
7
|
+
*
|
|
8
|
+
* LLD #14 — claudeCodeHooks.ts
|
|
9
|
+
* HLD §3.14 — Three-Tier Defense Cascade (Tier 1 Native Gating)
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import type { SyncSopEntry } from '@intutic/shared-types';
|
|
15
|
+
/** Path to the local hook event log file appended by generated hook scripts. */
|
|
16
|
+
export declare const HOOK_EVENTS_LOG = ".intutic/events/hook-events.jsonl";
|
|
17
|
+
export declare const SopHookConstraintsSchema: z.ZodObject<{
|
|
18
|
+
highRiskTools: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
19
|
+
patterns: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
20
|
+
}, "strip", z.ZodTypeAny, {
|
|
21
|
+
highRiskTools: string[];
|
|
22
|
+
patterns: string[];
|
|
23
|
+
}, {
|
|
24
|
+
highRiskTools?: string[] | undefined;
|
|
25
|
+
patterns?: string[] | undefined;
|
|
26
|
+
}>;
|
|
27
|
+
export type SopHookConstraints = z.infer<typeof SopHookConstraintsSchema>;
|
|
28
|
+
/**
|
|
29
|
+
* Extracts constraints from SOP registry entries.
|
|
30
|
+
* Looks inside SOP markdown content for structured JSON/YAML blocks or parses settings.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseSopConstraints(sops: SyncSopEntry[], settings?: Record<string, unknown> | import('@intutic/shared-types').WorkspaceSettings): SopHookConstraints;
|
|
33
|
+
/**
|
|
34
|
+
* Compiles constraints into Claude Code settings.json format and writes it.
|
|
35
|
+
*
|
|
36
|
+
* @param workspaceRoot - Workspace root path.
|
|
37
|
+
* @param sops - The sync SOP list.
|
|
38
|
+
* @param settings - Passthrough settings.
|
|
39
|
+
* @param controlPlaneUrl - Control plane base URL embedded into the hook events log path comment.
|
|
40
|
+
* @param workspaceId - Workspace ID embedded into hook event payloads.
|
|
41
|
+
* @param harnessType - Harness type tag written into each hook event.
|
|
42
|
+
*/
|
|
43
|
+
export declare function updatePreToolUseHooks(workspaceRoot: string, sops: SyncSopEntry[], settings?: Record<string, unknown> | import('@intutic/shared-types').WorkspaceSettings, controlPlaneUrl?: string, workspaceId?: string, harnessType?: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Drains the local hook-events log file and POSTs all accumulated governance
|
|
46
|
+
* events to the control plane in a single batch request.
|
|
47
|
+
*
|
|
48
|
+
* Called by the sync-daemon's main loop (syncLoop.ts) on every cycle, after
|
|
49
|
+
* the main sync operations. On success, the log file is truncated to prevent
|
|
50
|
+
* unbounded growth. On network failure, events remain in the log and will be
|
|
51
|
+
* retried on the next cycle.
|
|
52
|
+
*
|
|
53
|
+
* @param workspaceRoot - Workspace root (log file is at workspaceRoot/.intutic/events/hook-events.jsonl)
|
|
54
|
+
* @param controlPlaneUrl - Control plane base URL
|
|
55
|
+
* @param apiKey - Workspace API key (Bearer token)
|
|
56
|
+
* @returns number of events drained (0 if log was empty or network failed)
|
|
57
|
+
*/
|
|
58
|
+
export declare function drainHookEvents(workspaceRoot: string, controlPlaneUrl: string, apiKey: string): Promise<number>;
|
|
59
|
+
//# sourceMappingURL=claudeCodeHooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudeCodeHooks.d.ts","sourceRoot":"","sources":["../../src/harness/claudeCodeHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAKzD,gFAAgF;AAChF,eAAO,MAAM,eAAe,sCAAsC,CAAA;AAGlE,eAAO,MAAM,wBAAwB;;;;;;;;;EAGnC,CAAA;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAA;AAEzE;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,YAAY,EAAE,EACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,uBAAuB,EAAE,iBAAiB,GACrF,kBAAkB,CAiEpB;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,YAAY,EAAE,EACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,uBAAuB,EAAE,iBAAiB,EACtF,eAAe,CAAC,EAAE,MAAM,EACxB,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,SAAgB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA2Qf;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAwDjB"}
|