@aictrl/hush 0.1.7 → 0.1.8
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/.github/workflows/opencode-review.yml +52 -7
- package/dist/commands/init.d.ts +3 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +80 -26
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/redact-hook.d.ts +13 -4
- package/dist/commands/redact-hook.d.ts.map +1 -1
- package/dist/commands/redact-hook.js +162 -26
- package/dist/commands/redact-hook.js.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/plugins/opencode-hush.d.ts +15 -4
- package/dist/plugins/opencode-hush.d.ts.map +1 -1
- package/dist/plugins/opencode-hush.js +37 -4
- package/dist/plugins/opencode-hush.js.map +1 -1
- package/examples/team-config/.claude/settings.json +22 -0
- package/examples/team-config/.gemini/settings.json +38 -0
- package/examples/team-config/.opencode/plugins/hush.ts +9 -6
- package/package.json +1 -1
- package/src/commands/init.ts +110 -31
- package/src/commands/redact-hook.ts +206 -33
- package/src/index.ts +7 -2
- package/src/plugins/opencode-hush.ts +44 -4
- package/tests/init.test.ts +159 -5
- package/tests/opencode-plugin.test.ts +71 -0
- package/tests/redact-hook.test.ts +356 -0
|
@@ -69,33 +69,78 @@ jobs:
|
|
|
69
69
|
echo "skip=false" >> $GITHUB_OUTPUT
|
|
70
70
|
fi
|
|
71
71
|
|
|
72
|
+
- name: Setup Node.js
|
|
73
|
+
if: steps.check_changes.outputs.skip != 'true'
|
|
74
|
+
uses: actions/setup-node@v4
|
|
75
|
+
with:
|
|
76
|
+
node-version: 22
|
|
77
|
+
|
|
78
|
+
- name: Start Hush Gateway
|
|
79
|
+
if: steps.check_changes.outputs.skip != 'true'
|
|
80
|
+
run: |
|
|
81
|
+
npm ci && npm run build
|
|
82
|
+
PORT=4000 HUSH_HOST=127.0.0.1 node dist/cli.js > /tmp/hush-gateway.log 2>&1 &
|
|
83
|
+
for i in $(seq 1 20); do
|
|
84
|
+
curl -sf http://127.0.0.1:4000/health > /dev/null 2>&1 && break
|
|
85
|
+
sleep 0.5
|
|
86
|
+
done
|
|
87
|
+
curl -sf http://127.0.0.1:4000/health || { echo "::error::Hush gateway failed to start"; exit 1; }
|
|
88
|
+
echo "Hush gateway running on :4000"
|
|
89
|
+
|
|
72
90
|
- name: Setup OpenCode
|
|
73
91
|
if: steps.check_changes.outputs.skip != 'true'
|
|
74
92
|
env:
|
|
75
93
|
ZHIPU_API_KEY: ${{ secrets.ZHIPUAI_API_KEY }}
|
|
76
94
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
77
95
|
run: |
|
|
78
|
-
# Use GITHUB_TOKEN to avoid rate limits when fetching version info
|
|
79
96
|
curl -fsSL https://opencode.ai/install | bash -s -- --no-modify-path
|
|
80
97
|
echo "$HOME/.opencode/bin" >> $GITHUB_PATH
|
|
81
98
|
|
|
99
|
+
# Route the built-in zai-coding-plan provider through the hush proxy
|
|
100
|
+
# by overriding baseURL. No custom provider needed — the provider
|
|
101
|
+
# auto-detects apiKey from ZHIPU_API_KEY env var.
|
|
102
|
+
mkdir -p .opencode/plugins
|
|
103
|
+
cp examples/team-config/.opencode/plugins/hush.ts .opencode/plugins/hush.ts
|
|
104
|
+
printf '%s\n' '{"provider":{"zai-coding-plan":{"options":{"baseURL":"http://127.0.0.1:4000/api/coding/paas/v4"}}},"plugin":[".opencode/plugins/hush.ts"]}' > opencode.json
|
|
105
|
+
|
|
82
106
|
- name: Direct OpenCode Review
|
|
83
107
|
if: steps.check_changes.outputs.skip != 'true'
|
|
108
|
+
timeout-minutes: 15
|
|
84
109
|
env:
|
|
85
110
|
ZHIPU_API_KEY: ${{ secrets.ZHIPUAI_API_KEY }}
|
|
86
111
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
87
112
|
run: |
|
|
88
113
|
SHA=${{ github.event.pull_request.head.sha || github.sha }}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
114
|
+
PR_NUMBER=${{ github.event.pull_request.number }}
|
|
115
|
+
echo "Starting review with zai-coding-plan/glm-5 via hush proxy for PR #$PR_NUMBER SHA $SHA..."
|
|
116
|
+
echo "opencode.json:"; cat opencode.json
|
|
117
|
+
echo "Hush health:"; curl -sf http://127.0.0.1:4000/health || echo "gateway unreachable"
|
|
118
|
+
|
|
119
|
+
$HOME/.opencode/bin/opencode run --model zai-coding-plan/glm-5 "Review the changes in PR #$PR_NUMBER for the Hush Semantic Gateway.
|
|
120
|
+
|
|
121
|
+
**IMPORTANT**: This is a code review only. Do NOT run tests, npm commands, or build commands. Only read source files and git diffs.
|
|
92
122
|
|
|
93
123
|
Focus areas:
|
|
94
124
|
1. **Redaction Logic**: Ensure PII patterns are robust and handle edge cases in tool outputs (like JSON or CLI tables).
|
|
95
125
|
2. **Streaming Integrity**: Check that the SSE/streaming proxy logic doesn't buffer unnecessarily or break the rehydration flow.
|
|
96
126
|
3. **Security**: Look for potential PII leaks or insecure token handling in the vault.
|
|
97
127
|
4. **Reliability**: Ensure the proxy handles upstream errors gracefully.
|
|
98
|
-
|
|
99
|
-
Keep the
|
|
100
|
-
|
|
128
|
+
|
|
129
|
+
Keep the review concise. Post findings as a single markdown comment using:
|
|
130
|
+
gh pr comment $PR_NUMBER --body \"<your review>\"
|
|
131
|
+
|
|
132
|
+
Do NOT try to auto-detect the PR number — use exactly $PR_NUMBER.
|
|
133
|
+
|
|
101
134
|
**CRITICAL**: Include the string 'Reviewed SHA: $SHA' at the very end of your comment so I can track which commits have been reviewed."
|
|
135
|
+
|
|
136
|
+
- name: Verify Hush Proxy Was Used
|
|
137
|
+
if: always() && steps.check_changes.outputs.skip != 'true'
|
|
138
|
+
run: |
|
|
139
|
+
echo "=== Hush Gateway Logs ==="
|
|
140
|
+
cat /tmp/hush-gateway.log 2>/dev/null || echo "No gateway log found"
|
|
141
|
+
echo ""
|
|
142
|
+
if grep -q "Starting stream proxy" /tmp/hush-gateway.log 2>/dev/null; then
|
|
143
|
+
echo "Hush proxy intercepted traffic"
|
|
144
|
+
else
|
|
145
|
+
echo "::warning::No proxy traffic detected in hush logs — review may have bypassed the gateway"
|
|
146
|
+
fi
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* hush init — Generate Claude Code
|
|
2
|
+
* hush init — Generate hook configuration for Claude Code or Gemini CLI
|
|
3
3
|
*
|
|
4
4
|
* Usage:
|
|
5
5
|
* hush init --hooks Write to .claude/settings.json
|
|
6
6
|
* hush init --hooks --local Write to .claude/settings.local.json
|
|
7
|
+
* hush init --hooks --gemini Write to .gemini/settings.json
|
|
8
|
+
* hush init --hooks --gemini --local Write to .gemini/settings.local.json
|
|
7
9
|
*/
|
|
8
10
|
export declare function run(args: string[]): void;
|
|
9
11
|
//# sourceMappingURL=init.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiIH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgDxC"}
|
package/dist/commands/init.js
CHANGED
|
@@ -1,62 +1,114 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* hush init — Generate Claude Code
|
|
2
|
+
* hush init — Generate hook configuration for Claude Code or Gemini CLI
|
|
3
3
|
*
|
|
4
4
|
* Usage:
|
|
5
5
|
* hush init --hooks Write to .claude/settings.json
|
|
6
6
|
* hush init --hooks --local Write to .claude/settings.local.json
|
|
7
|
+
* hush init --hooks --gemini Write to .gemini/settings.json
|
|
8
|
+
* hush init --hooks --gemini --local Write to .gemini/settings.local.json
|
|
7
9
|
*/
|
|
8
10
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
9
11
|
import { join } from 'path';
|
|
10
|
-
const
|
|
12
|
+
const HUSH_HOOK = {
|
|
13
|
+
type: 'command',
|
|
14
|
+
command: 'hush redact-hook',
|
|
15
|
+
timeout: 10,
|
|
16
|
+
};
|
|
17
|
+
const CLAUDE_HOOK_CONFIG = {
|
|
11
18
|
hooks: {
|
|
19
|
+
PreToolUse: [
|
|
20
|
+
{
|
|
21
|
+
matcher: 'mcp__.*',
|
|
22
|
+
hooks: [HUSH_HOOK],
|
|
23
|
+
},
|
|
24
|
+
],
|
|
12
25
|
PostToolUse: [
|
|
13
26
|
{
|
|
14
27
|
matcher: 'Bash|Read|Grep|WebFetch',
|
|
15
|
-
hooks: [
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
],
|
|
28
|
+
hooks: [HUSH_HOOK],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
matcher: 'mcp__.*',
|
|
32
|
+
hooks: [HUSH_HOOK],
|
|
22
33
|
},
|
|
23
34
|
],
|
|
24
35
|
},
|
|
25
36
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
const GEMINI_HOOK_CONFIG = {
|
|
38
|
+
hooks: {
|
|
39
|
+
BeforeTool: [
|
|
40
|
+
{
|
|
41
|
+
matcher: 'mcp__.*',
|
|
42
|
+
hooks: [HUSH_HOOK],
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
AfterTool: [
|
|
46
|
+
{
|
|
47
|
+
matcher: 'run_shell_command|read_file|read_many_files|search_file_content|web_fetch',
|
|
48
|
+
hooks: [HUSH_HOOK],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
matcher: 'mcp__.*',
|
|
52
|
+
hooks: [HUSH_HOOK],
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
function hasHushHookInEntries(entries) {
|
|
58
|
+
if (!Array.isArray(entries))
|
|
29
59
|
return false;
|
|
30
|
-
return
|
|
60
|
+
return entries.some((entry) => entry.hooks?.some((h) => h.command?.includes('hush redact-hook')));
|
|
61
|
+
}
|
|
62
|
+
function hasHushHookClaude(settings) {
|
|
63
|
+
return (hasHushHookInEntries(settings.hooks?.PreToolUse) &&
|
|
64
|
+
hasHushHookInEntries(settings.hooks?.PostToolUse));
|
|
65
|
+
}
|
|
66
|
+
function hasHushHookGemini(settings) {
|
|
67
|
+
return (hasHushHookInEntries(settings.hooks?.BeforeTool) &&
|
|
68
|
+
hasHushHookInEntries(settings.hooks?.AfterTool));
|
|
69
|
+
}
|
|
70
|
+
function mergeHookEntries(existing, newEntries) {
|
|
71
|
+
const merged = Array.isArray(existing) ? [...existing] : [];
|
|
72
|
+
for (const entry of newEntries) {
|
|
73
|
+
const alreadyHas = merged.some((e) => e.matcher === entry.matcher &&
|
|
74
|
+
e.hooks?.some((h) => h.command?.includes('hush redact-hook')));
|
|
75
|
+
if (!alreadyHas) {
|
|
76
|
+
merged.push(entry);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return merged;
|
|
31
80
|
}
|
|
32
|
-
function mergeHooks(existing) {
|
|
81
|
+
function mergeHooks(existing, hookConfig) {
|
|
33
82
|
const merged = { ...existing };
|
|
34
83
|
if (!merged.hooks) {
|
|
35
84
|
merged.hooks = {};
|
|
36
85
|
}
|
|
37
|
-
|
|
38
|
-
merged.hooks
|
|
86
|
+
for (const [eventName, entries] of Object.entries(hookConfig.hooks)) {
|
|
87
|
+
const existingEntries = merged.hooks[eventName];
|
|
88
|
+
merged.hooks[eventName] = mergeHookEntries(existingEntries, entries);
|
|
39
89
|
}
|
|
40
|
-
merged.hooks = { ...merged.hooks, PostToolUse: [...merged.hooks.PostToolUse, ...HOOK_CONFIG.hooks.PostToolUse] };
|
|
41
90
|
return merged;
|
|
42
91
|
}
|
|
43
92
|
export function run(args) {
|
|
44
93
|
const hasHooksFlag = args.includes('--hooks');
|
|
45
94
|
const isLocal = args.includes('--local');
|
|
95
|
+
const isGemini = args.includes('--gemini');
|
|
46
96
|
if (!hasHooksFlag) {
|
|
47
|
-
process.stderr.write('Usage: hush init --hooks [--local]\n');
|
|
97
|
+
process.stderr.write('Usage: hush init --hooks [--local] [--gemini]\n');
|
|
48
98
|
process.stderr.write('\n');
|
|
49
99
|
process.stderr.write('Options:\n');
|
|
50
|
-
process.stderr.write(' --hooks Generate
|
|
100
|
+
process.stderr.write(' --hooks Generate hook config (PreToolUse + PostToolUse or BeforeTool + AfterTool)\n');
|
|
51
101
|
process.stderr.write(' --local Write to settings.local.json instead of settings.json\n');
|
|
102
|
+
process.stderr.write(' --gemini Write Gemini CLI hooks instead of Claude Code hooks\n');
|
|
52
103
|
process.exit(1);
|
|
53
104
|
}
|
|
54
|
-
const
|
|
105
|
+
const dirName = isGemini ? '.gemini' : '.claude';
|
|
106
|
+
const configDir = join(process.cwd(), dirName);
|
|
55
107
|
const filename = isLocal ? 'settings.local.json' : 'settings.json';
|
|
56
|
-
const filePath = join(
|
|
57
|
-
// Ensure
|
|
58
|
-
if (!existsSync(
|
|
59
|
-
mkdirSync(
|
|
108
|
+
const filePath = join(configDir, filename);
|
|
109
|
+
// Ensure config dir exists
|
|
110
|
+
if (!existsSync(configDir)) {
|
|
111
|
+
mkdirSync(configDir, { recursive: true });
|
|
60
112
|
}
|
|
61
113
|
// Read existing settings or start fresh
|
|
62
114
|
let settings = {};
|
|
@@ -70,11 +122,13 @@ export function run(args) {
|
|
|
70
122
|
}
|
|
71
123
|
}
|
|
72
124
|
// Idempotency check
|
|
73
|
-
|
|
125
|
+
const hookConfig = isGemini ? GEMINI_HOOK_CONFIG : CLAUDE_HOOK_CONFIG;
|
|
126
|
+
const hasHook = isGemini ? hasHushHookGemini : hasHushHookClaude;
|
|
127
|
+
if (hasHook(settings)) {
|
|
74
128
|
process.stdout.write(`hush hooks already configured in ${filePath}\n`);
|
|
75
129
|
return;
|
|
76
130
|
}
|
|
77
|
-
const merged = mergeHooks(settings);
|
|
131
|
+
const merged = mergeHooks(settings, hookConfig);
|
|
78
132
|
writeFileSync(filePath, JSON.stringify(merged, null, 2) + '\n');
|
|
79
133
|
process.stdout.write(`Wrote hush hooks config to ${filePath}\n`);
|
|
80
134
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,SAAS,GAAG;IAChB,IAAI,EAAE,SAAkB;IACxB,OAAO,EAAE,kBAAkB;IAC3B,OAAO,EAAE,EAAE;CACZ,CAAC;AAEF,MAAM,kBAAkB,GAAG;IACzB,KAAK,EAAE;QACL,UAAU,EAAE;YACV;gBACE,OAAO,EAAE,SAAS;gBAClB,KAAK,EAAE,CAAC,SAAS,CAAC;aACnB;SACF;QACD,WAAW,EAAE;YACX;gBACE,OAAO,EAAE,yBAAyB;gBAClC,KAAK,EAAE,CAAC,SAAS,CAAC;aACnB;YACD;gBACE,OAAO,EAAE,SAAS;gBAClB,KAAK,EAAE,CAAC,SAAS,CAAC;aACnB;SACF;KACF;CACF,CAAC;AAEF,MAAM,kBAAkB,GAAG;IACzB,KAAK,EAAE;QACL,UAAU,EAAE;YACV;gBACE,OAAO,EAAE,SAAS;gBAClB,KAAK,EAAE,CAAC,SAAS,CAAC;aACnB;SACF;QACD,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,2EAA2E;gBACpF,KAAK,EAAE,CAAC,SAAS,CAAC;aACnB;YACD;gBACE,OAAO,EAAE,SAAS;gBAClB,KAAK,EAAE,CAAC,SAAS,CAAC;aACnB;SACF;KACF;CACF,CAAC;AAsBF,SAAS,oBAAoB,CAAC,OAAgC;IAC5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC5B,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAClE,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAsB;IAC/C,OAAO,CACL,oBAAoB,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;QAChD,oBAAoB,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAClD,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAsB;IAC/C,OAAO,CACL,oBAAoB,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;QAChD,oBAAoB,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAChD,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CACvB,QAAiC,EACjC,UAAuB;IAEvB,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5D,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAC5B,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO;YAC3B,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAChE,CAAC;QACF,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,QAAsB,EAAE,UAAsB;IAChE,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAE/B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACpE,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAA4B,CAAC;QAC3E,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,gBAAgB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAc;IAChC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAE3C,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACxE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yFAAyF,CAAC,CAAC;QAChH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAC5F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QAC1F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,eAAe,CAAC;IACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAE3C,2BAA2B;IAC3B,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,wCAAwC;IACxC,IAAI,QAAQ,GAAiB,EAAE,CAAC;IAChC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC5C,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,QAAQ,oBAAoB,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACtE,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CAAC;IAEjE,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,QAAQ,IAAI,CAAC,CAAC;QACvE,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAChD,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAChE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,QAAQ,IAAI,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* hush redact-hook — Claude Code
|
|
2
|
+
* hush redact-hook — Hook handler for Claude Code and Gemini CLI
|
|
3
3
|
*
|
|
4
|
-
* Reads the hook payload from stdin, redacts PII
|
|
5
|
-
*
|
|
4
|
+
* Reads the hook payload from stdin, redacts PII, and returns the
|
|
5
|
+
* appropriate response format depending on the hook event type:
|
|
6
|
+
*
|
|
7
|
+
* Claude Code:
|
|
8
|
+
* PreToolUse — redacts outbound MCP tool arguments (updatedInput)
|
|
9
|
+
* PostToolUse — redacts inbound MCP tool results (updatedMCPToolOutput)
|
|
10
|
+
* or blocks built-in tool output (decision: "block")
|
|
11
|
+
*
|
|
12
|
+
* Gemini CLI:
|
|
13
|
+
* BeforeTool — redacts outbound MCP tool arguments (hookSpecificOutput.tool_input)
|
|
14
|
+
* AfterTool — redacts inbound tool results (decision: "deny")
|
|
6
15
|
*
|
|
7
16
|
* Exit codes:
|
|
8
|
-
* 0 — success (may or may not
|
|
17
|
+
* 0 — success (may or may not redact)
|
|
9
18
|
* 2 — malformed input (blocks the tool call per hooks spec)
|
|
10
19
|
*/
|
|
11
20
|
export declare function run(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redact-hook.d.ts","sourceRoot":"","sources":["../../src/commands/redact-hook.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"redact-hook.d.ts","sourceRoot":"","sources":["../../src/commands/redact-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA8NH,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAwDzC"}
|
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* hush redact-hook — Claude Code
|
|
2
|
+
* hush redact-hook — Hook handler for Claude Code and Gemini CLI
|
|
3
3
|
*
|
|
4
|
-
* Reads the hook payload from stdin, redacts PII
|
|
5
|
-
*
|
|
4
|
+
* Reads the hook payload from stdin, redacts PII, and returns the
|
|
5
|
+
* appropriate response format depending on the hook event type:
|
|
6
|
+
*
|
|
7
|
+
* Claude Code:
|
|
8
|
+
* PreToolUse — redacts outbound MCP tool arguments (updatedInput)
|
|
9
|
+
* PostToolUse — redacts inbound MCP tool results (updatedMCPToolOutput)
|
|
10
|
+
* or blocks built-in tool output (decision: "block")
|
|
11
|
+
*
|
|
12
|
+
* Gemini CLI:
|
|
13
|
+
* BeforeTool — redacts outbound MCP tool arguments (hookSpecificOutput.tool_input)
|
|
14
|
+
* AfterTool — redacts inbound tool results (decision: "deny")
|
|
6
15
|
*
|
|
7
16
|
* Exit codes:
|
|
8
|
-
* 0 — success (may or may not
|
|
17
|
+
* 0 — success (may or may not redact)
|
|
9
18
|
* 2 — malformed input (blocks the tool call per hooks spec)
|
|
10
19
|
*/
|
|
11
20
|
import { Redactor } from '../middleware/redactor.js';
|
|
12
|
-
/** Collect all text from a tool_response object. */
|
|
21
|
+
/** Collect all text from a built-in tool_response object. */
|
|
13
22
|
function extractText(toolResponse) {
|
|
14
23
|
if (!toolResponse || typeof toolResponse !== 'object')
|
|
15
24
|
return null;
|
|
@@ -32,13 +41,124 @@ function extractText(toolResponse) {
|
|
|
32
41
|
}
|
|
33
42
|
return parts.length > 0 ? parts.join('\n') : null;
|
|
34
43
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
// ── Shared helpers ──────────────────────────────────────────────────────
|
|
45
|
+
/**
|
|
46
|
+
* Redact PII from tool_input and format the response.
|
|
47
|
+
* Shared by PreToolUse (Claude) and BeforeTool (Gemini).
|
|
48
|
+
*/
|
|
49
|
+
function redactToolInput(payload, redactor, formatResponse) {
|
|
50
|
+
if (!payload.tool_input || typeof payload.tool_input !== 'object') {
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
const { content, hasRedacted } = redactor.redact(payload.tool_input);
|
|
54
|
+
if (!hasRedacted) {
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
const response = formatResponse(content);
|
|
58
|
+
process.stdout.write(JSON.stringify(response) + '\n');
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Redact PII from a built-in tool response and format the response.
|
|
63
|
+
* Shared by PostToolUse (Claude, decision:"block") and AfterTool (Gemini, decision:"deny").
|
|
64
|
+
*/
|
|
65
|
+
function redactBuiltinResponse(payload, redactor, decision) {
|
|
66
|
+
if (!payload.tool_response) {
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
const text = extractText(payload.tool_response);
|
|
70
|
+
if (!text) {
|
|
71
|
+
process.exit(0);
|
|
72
|
+
}
|
|
40
73
|
const { content, hasRedacted } = redactor.redact(text);
|
|
41
|
-
|
|
74
|
+
if (!hasRedacted) {
|
|
75
|
+
process.exit(0);
|
|
76
|
+
}
|
|
77
|
+
const response = {
|
|
78
|
+
decision,
|
|
79
|
+
reason: content,
|
|
80
|
+
};
|
|
81
|
+
process.stdout.write(JSON.stringify(response) + '\n');
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
// ── Claude Code handlers ────────────────────────────────────────────────
|
|
85
|
+
/** Handle PreToolUse — redact outbound MCP tool arguments. */
|
|
86
|
+
function handlePreToolUse(payload, redactor) {
|
|
87
|
+
redactToolInput(payload, redactor, (redactedInput) => ({
|
|
88
|
+
hookSpecificOutput: {
|
|
89
|
+
hookEventName: 'PreToolUse',
|
|
90
|
+
permissionDecision: 'allow',
|
|
91
|
+
updatedInput: redactedInput,
|
|
92
|
+
},
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
/** Handle PostToolUse for MCP tools — redact inbound content blocks. */
|
|
96
|
+
function handlePostToolUseMCP(payload, redactor) {
|
|
97
|
+
const toolResponse = payload.tool_response;
|
|
98
|
+
if (!toolResponse || typeof toolResponse !== 'object') {
|
|
99
|
+
process.exit(0);
|
|
100
|
+
}
|
|
101
|
+
const contentArray = toolResponse.content;
|
|
102
|
+
if (!Array.isArray(contentArray)) {
|
|
103
|
+
process.exit(0);
|
|
104
|
+
}
|
|
105
|
+
const { content: redactedArray, hasRedacted } = redactor.redact(contentArray);
|
|
106
|
+
if (!hasRedacted) {
|
|
107
|
+
process.exit(0);
|
|
108
|
+
}
|
|
109
|
+
const response = {
|
|
110
|
+
updatedMCPToolOutput: {
|
|
111
|
+
content: redactedArray,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
process.stdout.write(JSON.stringify(response) + '\n');
|
|
115
|
+
process.exit(0);
|
|
116
|
+
}
|
|
117
|
+
/** Handle PostToolUse for built-in tools — decision: "block". */
|
|
118
|
+
function handlePostToolUseBuiltin(payload, redactor) {
|
|
119
|
+
redactBuiltinResponse(payload, redactor, 'block');
|
|
120
|
+
}
|
|
121
|
+
// ── Gemini CLI handlers ─────────────────────────────────────────────────
|
|
122
|
+
/** Handle BeforeTool — redact outbound MCP tool arguments (Gemini format). */
|
|
123
|
+
function handleBeforeTool(payload, redactor) {
|
|
124
|
+
redactToolInput(payload, redactor, (redactedInput) => ({
|
|
125
|
+
hookSpecificOutput: {
|
|
126
|
+
tool_input: redactedInput,
|
|
127
|
+
},
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
/** Handle AfterTool for MCP tools — redact content array, flatten to deny/reason. */
|
|
131
|
+
function handleAfterToolMCP(payload, redactor) {
|
|
132
|
+
const toolResponse = payload.tool_response;
|
|
133
|
+
if (!toolResponse || typeof toolResponse !== 'object') {
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}
|
|
136
|
+
const contentArray = toolResponse.content;
|
|
137
|
+
if (!Array.isArray(contentArray)) {
|
|
138
|
+
process.exit(0);
|
|
139
|
+
}
|
|
140
|
+
const { content: redactedArray, hasRedacted } = redactor.redact(contentArray);
|
|
141
|
+
if (!hasRedacted) {
|
|
142
|
+
process.exit(0);
|
|
143
|
+
}
|
|
144
|
+
// Flatten content blocks to a single text for Gemini's deny/reason format
|
|
145
|
+
const textParts = redactedArray
|
|
146
|
+
.filter((b) => typeof b.text === 'string')
|
|
147
|
+
.map((b) => b.text);
|
|
148
|
+
const response = {
|
|
149
|
+
decision: 'deny',
|
|
150
|
+
reason: textParts.join('\n'),
|
|
151
|
+
};
|
|
152
|
+
process.stdout.write(JSON.stringify(response) + '\n');
|
|
153
|
+
process.exit(0);
|
|
154
|
+
}
|
|
155
|
+
/** Handle AfterTool for built-in tools — decision: "deny". */
|
|
156
|
+
function handleAfterToolBuiltin(payload, redactor) {
|
|
157
|
+
redactBuiltinResponse(payload, redactor, 'deny');
|
|
158
|
+
}
|
|
159
|
+
// ── Utilities ───────────────────────────────────────────────────────────
|
|
160
|
+
function isMCPTool(toolName) {
|
|
161
|
+
return typeof toolName === 'string' && toolName.startsWith('mcp__');
|
|
42
162
|
}
|
|
43
163
|
function readStdin() {
|
|
44
164
|
return new Promise((resolve, reject) => {
|
|
@@ -48,6 +168,7 @@ function readStdin() {
|
|
|
48
168
|
process.stdin.on('error', reject);
|
|
49
169
|
});
|
|
50
170
|
}
|
|
171
|
+
// ── Entry point ─────────────────────────────────────────────────────────
|
|
51
172
|
export async function run() {
|
|
52
173
|
let raw;
|
|
53
174
|
try {
|
|
@@ -58,7 +179,6 @@ export async function run() {
|
|
|
58
179
|
process.exit(2);
|
|
59
180
|
}
|
|
60
181
|
if (!raw.trim()) {
|
|
61
|
-
// Empty stdin — nothing to redact
|
|
62
182
|
process.exit(0);
|
|
63
183
|
}
|
|
64
184
|
let payload;
|
|
@@ -69,21 +189,37 @@ export async function run() {
|
|
|
69
189
|
process.stderr.write('hush redact-hook: invalid JSON on stdin\n');
|
|
70
190
|
process.exit(2);
|
|
71
191
|
}
|
|
72
|
-
if (!payload.tool_response) {
|
|
73
|
-
// No tool_response to redact
|
|
74
|
-
process.exit(0);
|
|
75
|
-
}
|
|
76
192
|
const redactor = new Redactor();
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
193
|
+
const eventName = payload.hook_event_name;
|
|
194
|
+
// Claude Code events
|
|
195
|
+
if (eventName === 'PreToolUse') {
|
|
196
|
+
handlePreToolUse(payload, redactor);
|
|
197
|
+
return;
|
|
81
198
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
199
|
+
if (eventName === 'PostToolUse') {
|
|
200
|
+
if (isMCPTool(payload.tool_name)) {
|
|
201
|
+
handlePostToolUseMCP(payload, redactor);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
handlePostToolUseBuiltin(payload, redactor);
|
|
205
|
+
}
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
// Gemini CLI events
|
|
209
|
+
if (eventName === 'BeforeTool') {
|
|
210
|
+
handleBeforeTool(payload, redactor);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (eventName === 'AfterTool') {
|
|
214
|
+
if (isMCPTool(payload.tool_name)) {
|
|
215
|
+
handleAfterToolMCP(payload, redactor);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
handleAfterToolBuiltin(payload, redactor);
|
|
219
|
+
}
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
// Backward compat: no hook_event_name → treat as PostToolUse built-in
|
|
223
|
+
handlePostToolUseBuiltin(payload, redactor);
|
|
88
224
|
}
|
|
89
225
|
//# sourceMappingURL=redact-hook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redact-hook.js","sourceRoot":"","sources":["../../src/commands/redact-hook.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"redact-hook.js","sourceRoot":"","sources":["../../src/commands/redact-hook.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -83,7 +83,7 @@ async function proxyRequest(req, res, targetUrl, headers) {
|
|
|
83
83
|
method: req.method,
|
|
84
84
|
headers: fetchHeaders,
|
|
85
85
|
body: hasBody ? JSON.stringify(redactedBody) : undefined,
|
|
86
|
-
signal: AbortSignal.timeout(
|
|
86
|
+
signal: AbortSignal.timeout(120000), // 120s timeout for long LLM responses
|
|
87
87
|
});
|
|
88
88
|
// Handle Upstream Errors (4xx, 5xx)
|
|
89
89
|
if (!response.ok) {
|
|
@@ -131,7 +131,13 @@ async function proxyRequest(req, res, targetUrl, headers) {
|
|
|
131
131
|
}
|
|
132
132
|
catch (error) {
|
|
133
133
|
log.error({ err: error, path: req.path }, 'Failed to forward request');
|
|
134
|
-
res.
|
|
134
|
+
if (!res.headersSent) {
|
|
135
|
+
res.status(502).json({ error: 'Gateway forwarding failed' });
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// Headers already sent (streaming in progress) — just end the response
|
|
139
|
+
res.end();
|
|
140
|
+
}
|
|
135
141
|
}
|
|
136
142
|
}
|
|
137
143
|
/**
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;AACvC,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;AAChC,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;AAE/B,0EAA0E;AAC1E,IAAI,UAAU,GAAqB,IAAI,CAAC;AACxC,SAAS,YAAY;IACnB,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QAClF,UAAU,GAAG,IAAI,SAAS,EAAE,CAAC;IAC/B,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,8DAA8D;AAC9D,YAAY,EAAE,CAAC;AAEf,MAAM,CAAC,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAE7B,0EAA0E;AAC1E,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,WAAW,CAAC;AAE1D,uDAAuD;AACvD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;AAE/C,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB;AAC/D,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAEzC;;GAEG;AACH,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IACzB,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,EAAE,CAAC;IAE1C,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC/E,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QAE7E,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,KAAK,UAAU,IAAI,aAAa,KAAK,UAAU,UAAU,EAAE,CAAC,EAAE,CAAC;YACjG,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,6BAA6B,CAAC,CAAC;YACxD,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uCAAuC,EAAE,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IACD,IAAI,EAAE,CAAC;AACT,CAAC,CAAC,CAAC;AAEH;;GAEG;AACH,KAAK,UAAU,YAAY,CACzB,GAAoB,EACpB,GAAqB,EACrB,SAAiB,EACjB,OAA+B;IAE/B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IAEjC,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAE9D,gFAAgF;IAChF,IAAI,YAAiB,CAAC;IACtB,IAAI,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QACvB,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACnC,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;IAEpE,gCAAgC;IAChC,IAAI,SAAS,EAAE,CAAC;QACd,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,iBAAiB,EAAE,EAAE,sCAAsC,CAAC,CAAC;QAC3H,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAEzB,uBAAuB;QACvB,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,mCAAmC;gBAC9E,SAAU,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAY,GAA2B,EAAE,GAAG,OAAO,EAAE,CAAC;QAC5D,IAAI,OAAO;YAAE,YAAY,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;QAE/D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;YACtC,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,OAAO,EAAE,YAAY;YACrB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS;YACxD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|