@hiro-c/agent-gate 1.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/AGENTS.md +76 -0
- package/LICENSE +21 -0
- package/README.md +205 -0
- package/dist/adapters/Adapter.d.ts +32 -0
- package/dist/adapters/Adapter.d.ts.map +1 -0
- package/dist/adapters/Adapter.js +2 -0
- package/dist/adapters/claude-code/adapter.d.ts +3 -0
- package/dist/adapters/claude-code/adapter.d.ts.map +1 -0
- package/dist/adapters/claude-code/adapter.js +45 -0
- package/dist/adapters/claude-code/transcript.d.ts +16 -0
- package/dist/adapters/claude-code/transcript.d.ts.map +1 -0
- package/dist/adapters/claude-code/transcript.js +104 -0
- package/dist/adapters/cursor/adapter.d.ts +3 -0
- package/dist/adapters/cursor/adapter.d.ts.map +1 -0
- package/dist/adapters/cursor/adapter.js +89 -0
- package/dist/adapters/index.d.ts +8 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +20 -0
- package/dist/cli/agent-gate.d.ts +13 -0
- package/dist/cli/agent-gate.d.ts.map +1 -0
- package/dist/cli/agent-gate.js +226 -0
- package/dist/cli/installer.d.ts +21 -0
- package/dist/cli/installer.d.ts.map +1 -0
- package/dist/cli/installer.js +71 -0
- package/dist/collector/collectClaudeMd.d.ts +3 -0
- package/dist/collector/collectClaudeMd.d.ts.map +1 -0
- package/dist/collector/collectClaudeMd.js +87 -0
- package/dist/collector/collectRuleSources.d.ts +3 -0
- package/dist/collector/collectRuleSources.d.ts.map +1 -0
- package/dist/collector/collectRuleSources.js +151 -0
- package/dist/config/AgentGateConfig.d.ts +18 -0
- package/dist/config/AgentGateConfig.d.ts.map +1 -0
- package/dist/config/AgentGateConfig.js +34 -0
- package/dist/config/Config.d.ts +26 -0
- package/dist/config/Config.d.ts.map +1 -0
- package/dist/config/Config.js +25 -0
- package/dist/config/PluginConfigLoader.d.ts +3 -0
- package/dist/config/PluginConfigLoader.d.ts.map +1 -0
- package/dist/config/PluginConfigLoader.js +85 -0
- package/dist/config/defineConfig.d.ts +23 -0
- package/dist/config/defineConfig.d.ts.map +1 -0
- package/dist/config/defineConfig.js +10 -0
- package/dist/contracts/schemas/hookDataSchema.d.ts +7 -0
- package/dist/contracts/schemas/hookDataSchema.d.ts.map +1 -0
- package/dist/contracts/schemas/hookDataSchema.js +9 -0
- package/dist/contracts/types/Action.d.ts +23 -0
- package/dist/contracts/types/Action.d.ts.map +1 -0
- package/dist/contracts/types/Action.js +2 -0
- package/dist/contracts/types/ClaudeMdFile.d.ts +5 -0
- package/dist/contracts/types/ClaudeMdFile.d.ts.map +1 -0
- package/dist/contracts/types/ClaudeMdFile.js +2 -0
- package/dist/contracts/types/HookData.d.ts +6 -0
- package/dist/contracts/types/HookData.d.ts.map +1 -0
- package/dist/contracts/types/HookData.js +2 -0
- package/dist/contracts/types/ModelClient.d.ts +4 -0
- package/dist/contracts/types/ModelClient.d.ts.map +1 -0
- package/dist/contracts/types/ModelClient.js +2 -0
- package/dist/contracts/types/RuleSource.d.ts +7 -0
- package/dist/contracts/types/RuleSource.d.ts.map +1 -0
- package/dist/contracts/types/RuleSource.js +2 -0
- package/dist/contracts/types/SessionContext.d.ts +25 -0
- package/dist/contracts/types/SessionContext.d.ts.map +1 -0
- package/dist/contracts/types/SessionContext.js +2 -0
- package/dist/contracts/types/ValidationResult.d.ts +5 -0
- package/dist/contracts/types/ValidationResult.d.ts.map +1 -0
- package/dist/contracts/types/ValidationResult.js +2 -0
- package/dist/daemon/client.d.ts +17 -0
- package/dist/daemon/client.d.ts.map +1 -0
- package/dist/daemon/client.js +59 -0
- package/dist/daemon/protocol.d.ts +17 -0
- package/dist/daemon/protocol.d.ts.map +1 -0
- package/dist/daemon/protocol.js +8 -0
- package/dist/daemon/server.d.ts +27 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +100 -0
- package/dist/deterministic/defaultRules.d.ts +11 -0
- package/dist/deterministic/defaultRules.d.ts.map +1 -0
- package/dist/deterministic/defaultRules.js +33 -0
- package/dist/deterministic/engine.d.ts +11 -0
- package/dist/deterministic/engine.d.ts.map +1 -0
- package/dist/deterministic/engine.js +12 -0
- package/dist/deterministic/factories.d.ts +20 -0
- package/dist/deterministic/factories.d.ts.map +1 -0
- package/dist/deterministic/factories.js +56 -0
- package/dist/deterministic/rules/preventBashSecretWrite.d.ts +3 -0
- package/dist/deterministic/rules/preventBashSecretWrite.d.ts.map +1 -0
- package/dist/deterministic/rules/preventBashSecretWrite.js +75 -0
- package/dist/deterministic/rules/preventForcePushMain.d.ts +7 -0
- package/dist/deterministic/rules/preventForcePushMain.d.ts.map +1 -0
- package/dist/deterministic/rules/preventForcePushMain.js +85 -0
- package/dist/deterministic/rules/preventRmRfRoot.d.ts +3 -0
- package/dist/deterministic/rules/preventRmRfRoot.d.ts.map +1 -0
- package/dist/deterministic/rules/preventRmRfRoot.js +68 -0
- package/dist/deterministic/rules/preventSecretFileWrite.d.ts +7 -0
- package/dist/deterministic/rules/preventSecretFileWrite.d.ts.map +1 -0
- package/dist/deterministic/rules/preventSecretFileWrite.js +55 -0
- package/dist/deterministic/rules/preventSystemPathWrite.d.ts +3 -0
- package/dist/deterministic/rules/preventSystemPathWrite.d.ts.map +1 -0
- package/dist/deterministic/rules/preventSystemPathWrite.js +38 -0
- package/dist/deterministic/types.d.ts +20 -0
- package/dist/deterministic/types.d.ts.map +1 -0
- package/dist/deterministic/types.js +2 -0
- package/dist/doctor/findings.d.ts +15 -0
- package/dist/doctor/findings.d.ts.map +1 -0
- package/dist/doctor/findings.js +2 -0
- package/dist/doctor/formatFindings.d.ts +3 -0
- package/dist/doctor/formatFindings.d.ts.map +1 -0
- package/dist/doctor/formatFindings.js +37 -0
- package/dist/doctor/lintRuleSources.d.ts +4 -0
- package/dist/doctor/lintRuleSources.d.ts.map +1 -0
- package/dist/doctor/lintRuleSources.js +87 -0
- package/dist/hooks/processHookData.d.ts +37 -0
- package/dist/hooks/processHookData.d.ts.map +1 -0
- package/dist/hooks/processHookData.js +181 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/observability/decisionLogger.d.ts +15 -0
- package/dist/observability/decisionLogger.d.ts.map +1 -0
- package/dist/observability/decisionLogger.js +20 -0
- package/dist/observability/eventBus.d.ts +15 -0
- package/dist/observability/eventBus.d.ts.map +1 -0
- package/dist/observability/eventBus.js +33 -0
- package/dist/observability/sinks/JsonlFileSink.d.ts +13 -0
- package/dist/observability/sinks/JsonlFileSink.d.ts.map +1 -0
- package/dist/observability/sinks/JsonlFileSink.js +36 -0
- package/dist/observability/sinks/Sink.d.ts +46 -0
- package/dist/observability/sinks/Sink.d.ts.map +1 -0
- package/dist/observability/sinks/Sink.js +2 -0
- package/dist/observability/stats.d.ts +14 -0
- package/dist/observability/stats.d.ts.map +1 -0
- package/dist/observability/stats.js +78 -0
- package/dist/validation/models/AnthropicApi.d.ts +9 -0
- package/dist/validation/models/AnthropicApi.d.ts.map +1 -0
- package/dist/validation/models/AnthropicApi.js +44 -0
- package/dist/validation/models/ClaudeCli.d.ts +10 -0
- package/dist/validation/models/ClaudeCli.d.ts.map +1 -0
- package/dist/validation/models/ClaudeCli.js +64 -0
- package/dist/validation/models/CompositeModelClient.d.ts +20 -0
- package/dist/validation/models/CompositeModelClient.d.ts.map +1 -0
- package/dist/validation/models/CompositeModelClient.js +53 -0
- package/dist/validation/prompts/context.d.ts +3 -0
- package/dist/validation/prompts/context.d.ts.map +1 -0
- package/dist/validation/prompts/context.js +29 -0
- package/dist/validation/prompts/response.d.ts +2 -0
- package/dist/validation/prompts/response.d.ts.map +1 -0
- package/dist/validation/prompts/response.js +20 -0
- package/dist/validation/prompts/system-prompt.d.ts +7 -0
- package/dist/validation/prompts/system-prompt.d.ts.map +1 -0
- package/dist/validation/prompts/system-prompt.js +69 -0
- package/dist/validation/validator.d.ts +5 -0
- package/dist/validation/validator.d.ts.map +1 -0
- package/dist/validation/validator.js +98 -0
- package/package.json +67 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { ValidationResult } from '../contracts/types/ValidationResult';
|
|
3
|
+
import { Adapter } from '../adapters/Adapter';
|
|
4
|
+
export declare function run(input: string, adapter?: Adapter): Promise<ValidationResult>;
|
|
5
|
+
interface ParsedArgs {
|
|
6
|
+
positional: string[];
|
|
7
|
+
agentId: string;
|
|
8
|
+
showHelp: boolean;
|
|
9
|
+
showVersion: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function parseArgs(args: string[]): ParsedArgs;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=agent-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-gate.d.ts","sourceRoot":"","sources":["../../src/cli/agent-gate.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAA;AAYtE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAsC7C,wBAAsB,GAAG,CACvB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,gBAAgB,CAAC,CAE3B;AAsGD,UAAU,UAAU;IAClB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAgCpD"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.run = run;
|
|
5
|
+
exports.parseArgs = parseArgs;
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const processHookData_1 = require("../hooks/processHookData");
|
|
8
|
+
const installer_1 = require("./installer");
|
|
9
|
+
const adapters_1 = require("../adapters");
|
|
10
|
+
const stats_1 = require("../observability/stats");
|
|
11
|
+
const decisionLogger_1 = require("../observability/decisionLogger");
|
|
12
|
+
const collectRuleSources_1 = require("../collector/collectRuleSources");
|
|
13
|
+
const lintRuleSources_1 = require("../doctor/lintRuleSources");
|
|
14
|
+
const formatFindings_1 = require("../doctor/formatFindings");
|
|
15
|
+
const server_1 = require("../daemon/server");
|
|
16
|
+
const client_1 = require("../daemon/client");
|
|
17
|
+
const protocol_1 = require("../daemon/protocol");
|
|
18
|
+
const HELP_TEXT = `agent-gate — runtime enforcer for AI coding agent rules
|
|
19
|
+
|
|
20
|
+
Usage:
|
|
21
|
+
agent-gate Run as a hook (reads JSON from stdin)
|
|
22
|
+
agent-gate --agent <id> Use the named adapter (default: claude-code)
|
|
23
|
+
agent-gate install Register the hook in ~/.claude/settings.json
|
|
24
|
+
agent-gate uninstall Remove the hook from ~/.claude/settings.json
|
|
25
|
+
agent-gate stats Summarize decisions from the log file
|
|
26
|
+
agent-gate lint Audit CLAUDE.md / AGENTS.md / etc. for AI-friendliness
|
|
27
|
+
agent-gate daemon Start the long-lived daemon (Unix socket)
|
|
28
|
+
agent-gate --help Show this help
|
|
29
|
+
agent-gate --version Show version
|
|
30
|
+
|
|
31
|
+
Adapters (use with --agent):
|
|
32
|
+
${(0, adapters_1.availableAdapterIds)().join(', ')}
|
|
33
|
+
|
|
34
|
+
Environment:
|
|
35
|
+
AGENT_GATE_MODEL Validation model (default: claude-sonnet-4-6)
|
|
36
|
+
AGENT_GATE_API_KEY Use Anthropic API directly when set
|
|
37
|
+
AGENT_GATE_COOLDOWN Cooldown in seconds between AI validations
|
|
38
|
+
AGENT_GATE_DISABLED Set to "true" to disable the whole tool
|
|
39
|
+
AGENT_GATE_DISABLED_RULES Comma-separated rule ids to disable
|
|
40
|
+
AGENT_GATE_LOG Set to "1" to write decisions to ~/.agent-gate/log.jsonl
|
|
41
|
+
AGENT_GATE_DAEMON Set to "1" to route hook calls through the daemon
|
|
42
|
+
AGENT_GATE_SOCKET_PATH Daemon socket path (default: $TMPDIR/agent-gate.sock)
|
|
43
|
+
USE_SYSTEM_CLAUDE Set to "true" to force PATH claude binary
|
|
44
|
+
`;
|
|
45
|
+
async function run(input, adapter) {
|
|
46
|
+
return (0, processHookData_1.processHookData)(input, adapter ? { adapter } : undefined);
|
|
47
|
+
}
|
|
48
|
+
function runHookMode(adapter) {
|
|
49
|
+
let inputData = '';
|
|
50
|
+
process.stdin.setEncoding('utf8');
|
|
51
|
+
process.stdin.on('data', (chunk) => {
|
|
52
|
+
inputData += chunk;
|
|
53
|
+
});
|
|
54
|
+
process.stdin.on('end', async () => {
|
|
55
|
+
try {
|
|
56
|
+
if (process.env.AGENT_GATE_DAEMON === '1') {
|
|
57
|
+
const socketPath = process.env.AGENT_GATE_SOCKET_PATH ?? (0, protocol_1.defaultSocketPath)();
|
|
58
|
+
const resp = await (0, client_1.sendToDaemon)({ adapter: adapter.id, payload: inputData, cwd: process.cwd() }, { socketPath, timeoutMs: 2000 });
|
|
59
|
+
if (resp !== null) {
|
|
60
|
+
console.log(resp.output);
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
// Daemon unreachable: fall through to direct mode.
|
|
64
|
+
}
|
|
65
|
+
const result = await run(inputData, adapter);
|
|
66
|
+
console.log(adapter.formatResponse(result));
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error('agent-gate error:', error);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
process.exit(0);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async function runDaemon() {
|
|
77
|
+
const socketPath = process.env.AGENT_GATE_SOCKET_PATH ?? (0, protocol_1.defaultSocketPath)();
|
|
78
|
+
const server = new server_1.DaemonServer({
|
|
79
|
+
socketPath,
|
|
80
|
+
handler: async (req) => {
|
|
81
|
+
const adapter = (0, adapters_1.getAdapter)(req.adapter);
|
|
82
|
+
if (!adapter) {
|
|
83
|
+
return {
|
|
84
|
+
output: JSON.stringify({
|
|
85
|
+
error: `unknown adapter: ${req.adapter}`,
|
|
86
|
+
}),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const result = await (0, processHookData_1.processHookData)(req.payload, {
|
|
90
|
+
adapter,
|
|
91
|
+
cwd: req.cwd,
|
|
92
|
+
});
|
|
93
|
+
return { output: adapter.formatResponse(result) };
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
await server.start();
|
|
97
|
+
console.log(`agent-gate daemon listening on ${socketPath}`);
|
|
98
|
+
const shutdown = async () => {
|
|
99
|
+
await server.stop();
|
|
100
|
+
process.exit(0);
|
|
101
|
+
};
|
|
102
|
+
process.on('SIGINT', () => void shutdown());
|
|
103
|
+
process.on('SIGTERM', () => void shutdown());
|
|
104
|
+
}
|
|
105
|
+
function runInstall() {
|
|
106
|
+
const rawScriptPath = process.argv[1] ?? '';
|
|
107
|
+
let effectivePath = '';
|
|
108
|
+
try {
|
|
109
|
+
if (rawScriptPath) {
|
|
110
|
+
effectivePath = (0, fs_1.realpathSync)(rawScriptPath);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
effectivePath = '';
|
|
115
|
+
}
|
|
116
|
+
const hookCommand = (0, installer_1.resolveHookCommand)(effectivePath);
|
|
117
|
+
const settingsFile = (0, installer_1.defaultSettingsPath)();
|
|
118
|
+
(0, installer_1.installHook)(hookCommand, settingsFile);
|
|
119
|
+
console.log(`agent-gate installed.`);
|
|
120
|
+
console.log(` settings: ${settingsFile}`);
|
|
121
|
+
console.log(` command: ${hookCommand}`);
|
|
122
|
+
console.log(`Restart Claude Code to activate.`);
|
|
123
|
+
}
|
|
124
|
+
function runUninstall() {
|
|
125
|
+
const settingsFile = (0, installer_1.defaultSettingsPath)();
|
|
126
|
+
(0, installer_1.uninstallHook)(settingsFile);
|
|
127
|
+
console.log(`agent-gate uninstalled.`);
|
|
128
|
+
console.log(` settings: ${settingsFile}`);
|
|
129
|
+
console.log(`Restart Claude Code to deactivate.`);
|
|
130
|
+
}
|
|
131
|
+
function printVersion() {
|
|
132
|
+
const pkg = require('../../package.json');
|
|
133
|
+
console.log(pkg.version ?? 'unknown');
|
|
134
|
+
}
|
|
135
|
+
function parseArgs(args) {
|
|
136
|
+
let agentId = adapters_1.DEFAULT_ADAPTER_ID;
|
|
137
|
+
let showHelp = false;
|
|
138
|
+
let showVersion = false;
|
|
139
|
+
const positional = [];
|
|
140
|
+
for (let i = 0; i < args.length; i++) {
|
|
141
|
+
const a = args[i];
|
|
142
|
+
if (a === '--agent') {
|
|
143
|
+
const next = args[i + 1];
|
|
144
|
+
if (next) {
|
|
145
|
+
agentId = next;
|
|
146
|
+
i++;
|
|
147
|
+
}
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (a.startsWith('--agent=')) {
|
|
151
|
+
agentId = a.slice('--agent='.length);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (a === '--help' || a === '-h' || a === 'help') {
|
|
155
|
+
showHelp = true;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (a === '--version' || a === '-v') {
|
|
159
|
+
showVersion = true;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
positional.push(a);
|
|
163
|
+
}
|
|
164
|
+
return { positional, agentId, showHelp, showVersion };
|
|
165
|
+
}
|
|
166
|
+
function main() {
|
|
167
|
+
const parsedArgs = parseArgs(process.argv.slice(2));
|
|
168
|
+
if (parsedArgs.showHelp) {
|
|
169
|
+
console.log(HELP_TEXT);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (parsedArgs.showVersion) {
|
|
173
|
+
printVersion();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const adapter = (0, adapters_1.getAdapter)(parsedArgs.agentId);
|
|
177
|
+
if (!adapter) {
|
|
178
|
+
console.error(`Unknown adapter: ${parsedArgs.agentId}. Available: ${(0, adapters_1.availableAdapterIds)().join(', ')}`);
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
const subcommand = parsedArgs.positional[0];
|
|
182
|
+
switch (subcommand) {
|
|
183
|
+
case undefined:
|
|
184
|
+
runHookMode(adapter);
|
|
185
|
+
return;
|
|
186
|
+
case 'install':
|
|
187
|
+
runInstall();
|
|
188
|
+
return;
|
|
189
|
+
case 'uninstall':
|
|
190
|
+
runUninstall();
|
|
191
|
+
return;
|
|
192
|
+
case 'stats':
|
|
193
|
+
runStats();
|
|
194
|
+
return;
|
|
195
|
+
case 'lint':
|
|
196
|
+
runLint();
|
|
197
|
+
return;
|
|
198
|
+
case 'daemon':
|
|
199
|
+
void runDaemon();
|
|
200
|
+
return;
|
|
201
|
+
default:
|
|
202
|
+
console.error(`Unknown subcommand: ${subcommand}`);
|
|
203
|
+
console.error(HELP_TEXT);
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function runStats() {
|
|
208
|
+
const stats = (0, stats_1.readStats)((0, decisionLogger_1.defaultLogPath)());
|
|
209
|
+
console.log((0, stats_1.formatStats)(stats));
|
|
210
|
+
}
|
|
211
|
+
function runLint() {
|
|
212
|
+
const sources = (0, collectRuleSources_1.collectRuleSources)(process.cwd());
|
|
213
|
+
if (sources.length === 0) {
|
|
214
|
+
console.log('No instruction files found (looked for CLAUDE.md, AGENTS.md, .cursorrules, .cursor/rules/*.mdc, .clinerules/*.md, .windsurf/rules/*.md, .github/copilot-instructions.md, CONVENTIONS.md).');
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const findings = (0, lintRuleSources_1.lintRuleSources)(sources);
|
|
218
|
+
console.log((0, formatFindings_1.formatFindings)(findings));
|
|
219
|
+
const hasError = findings.some((f) => f.severity === 'error');
|
|
220
|
+
if (hasError) {
|
|
221
|
+
process.exitCode = 1;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (require.main === module) {
|
|
225
|
+
main();
|
|
226
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const DEFAULT_HOOK_MATCHER = "Edit|Write|Bash";
|
|
2
|
+
export interface HookCommandEntry {
|
|
3
|
+
type: string;
|
|
4
|
+
command: string;
|
|
5
|
+
}
|
|
6
|
+
export interface HookMatcherEntry {
|
|
7
|
+
matcher?: string;
|
|
8
|
+
hooks?: HookCommandEntry[];
|
|
9
|
+
}
|
|
10
|
+
export interface ClaudeSettings {
|
|
11
|
+
hooks?: {
|
|
12
|
+
PreToolUse?: HookMatcherEntry[];
|
|
13
|
+
[key: string]: HookMatcherEntry[] | undefined;
|
|
14
|
+
};
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export declare function defaultSettingsPath(): string;
|
|
18
|
+
export declare function resolveHookCommand(resolvedScriptPath: string): string;
|
|
19
|
+
export declare function installHook(hookCommand: string, settingsFile?: string, matcher?: string): ClaudeSettings;
|
|
20
|
+
export declare function uninstallHook(settingsFile?: string): ClaudeSettings;
|
|
21
|
+
//# sourceMappingURL=installer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/cli/installer.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,oBAAoB,oBAAoB,CAAA;AAErD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE;QACN,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAA;QAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,EAAE,GAAG,SAAS,CAAA;KAC9C,CAAA;IACD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,kBAAkB,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAKrE;AAwBD,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,MAA8B,EAC5C,OAAO,GAAE,MAA6B,GACrC,cAAc,CAiBhB;AAED,wBAAgB,aAAa,CAC3B,YAAY,GAAE,MAA8B,GAC3C,cAAc,CAyBhB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_HOOK_MATCHER = void 0;
|
|
4
|
+
exports.defaultSettingsPath = defaultSettingsPath;
|
|
5
|
+
exports.resolveHookCommand = resolveHookCommand;
|
|
6
|
+
exports.installHook = installHook;
|
|
7
|
+
exports.uninstallHook = uninstallHook;
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const os_1 = require("os");
|
|
11
|
+
exports.DEFAULT_HOOK_MATCHER = 'Edit|Write|Bash';
|
|
12
|
+
function defaultSettingsPath() {
|
|
13
|
+
return (0, path_1.join)((0, os_1.homedir)(), '.claude', 'settings.json');
|
|
14
|
+
}
|
|
15
|
+
function resolveHookCommand(resolvedScriptPath) {
|
|
16
|
+
if (!resolvedScriptPath) {
|
|
17
|
+
return 'agent-gate';
|
|
18
|
+
}
|
|
19
|
+
return `node ${resolvedScriptPath}`;
|
|
20
|
+
}
|
|
21
|
+
function readSettings(settingsFile) {
|
|
22
|
+
if (!(0, fs_1.existsSync)(settingsFile)) {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
const content = (0, fs_1.readFileSync)(settingsFile, 'utf-8');
|
|
26
|
+
if (content.trim() === '') {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
return JSON.parse(content);
|
|
30
|
+
}
|
|
31
|
+
function writeSettings(settingsFile, settings) {
|
|
32
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(settingsFile), { recursive: true });
|
|
33
|
+
(0, fs_1.writeFileSync)(settingsFile, JSON.stringify(settings, null, 2) + '\n');
|
|
34
|
+
}
|
|
35
|
+
function isAgentGateEntry(entry) {
|
|
36
|
+
return (entry.hooks ?? []).some((h) => typeof h.command === 'string' && h.command.includes('agent-gate'));
|
|
37
|
+
}
|
|
38
|
+
function installHook(hookCommand, settingsFile = defaultSettingsPath(), matcher = exports.DEFAULT_HOOK_MATCHER) {
|
|
39
|
+
const settings = readSettings(settingsFile);
|
|
40
|
+
if (!settings.hooks)
|
|
41
|
+
settings.hooks = {};
|
|
42
|
+
const preToolUse = settings.hooks.PreToolUse ?? [];
|
|
43
|
+
const filtered = preToolUse.filter((entry) => !isAgentGateEntry(entry));
|
|
44
|
+
filtered.push({
|
|
45
|
+
matcher,
|
|
46
|
+
hooks: [{ type: 'command', command: hookCommand }],
|
|
47
|
+
});
|
|
48
|
+
settings.hooks.PreToolUse = filtered;
|
|
49
|
+
writeSettings(settingsFile, settings);
|
|
50
|
+
return settings;
|
|
51
|
+
}
|
|
52
|
+
function uninstallHook(settingsFile = defaultSettingsPath()) {
|
|
53
|
+
if (!(0, fs_1.existsSync)(settingsFile)) {
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
const settings = readSettings(settingsFile);
|
|
57
|
+
if (settings.hooks?.PreToolUse) {
|
|
58
|
+
const cleaned = settings.hooks.PreToolUse.filter((entry) => !isAgentGateEntry(entry));
|
|
59
|
+
if (cleaned.length === 0) {
|
|
60
|
+
delete settings.hooks.PreToolUse;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
settings.hooks.PreToolUse = cleaned;
|
|
64
|
+
}
|
|
65
|
+
if (settings.hooks && Object.keys(settings.hooks).length === 0) {
|
|
66
|
+
delete settings.hooks;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
writeSettings(settingsFile, settings);
|
|
70
|
+
return settings;
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collectClaudeMd.d.ts","sourceRoot":"","sources":["../../src/collector/collectClaudeMd.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAe9D,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAY3D"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.collectClaudeMd = collectClaudeMd;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const EXCLUDED_DIRS = new Set([
|
|
7
|
+
'node_modules',
|
|
8
|
+
'.git',
|
|
9
|
+
'target',
|
|
10
|
+
'.venv',
|
|
11
|
+
'vendor',
|
|
12
|
+
'__pycache__',
|
|
13
|
+
'dist',
|
|
14
|
+
'build',
|
|
15
|
+
]);
|
|
16
|
+
const MAX_DEPTH = 3;
|
|
17
|
+
function collectClaudeMd(cwd) {
|
|
18
|
+
const upward = collectUpward(cwd);
|
|
19
|
+
const downward = collectDownward(cwd);
|
|
20
|
+
// Deduplicate: upward already includes cwd/CLAUDE.md
|
|
21
|
+
const upwardPaths = new Set(upward.map((f) => f.path));
|
|
22
|
+
const combined = [
|
|
23
|
+
...upward,
|
|
24
|
+
...downward.filter((f) => !upwardPaths.has(f.path)),
|
|
25
|
+
];
|
|
26
|
+
return combined;
|
|
27
|
+
}
|
|
28
|
+
function collectUpward(cwd) {
|
|
29
|
+
const files = [];
|
|
30
|
+
let dir = cwd;
|
|
31
|
+
while (true) {
|
|
32
|
+
const claudeMdPath = (0, path_1.join)(dir, 'CLAUDE.md');
|
|
33
|
+
const content = readFileSafe(claudeMdPath);
|
|
34
|
+
if (content !== null) {
|
|
35
|
+
files.push({ path: claudeMdPath, content });
|
|
36
|
+
}
|
|
37
|
+
const parent = (0, path_1.dirname)(dir);
|
|
38
|
+
if (parent === dir)
|
|
39
|
+
break;
|
|
40
|
+
dir = parent;
|
|
41
|
+
}
|
|
42
|
+
return files;
|
|
43
|
+
}
|
|
44
|
+
function collectDownward(cwd) {
|
|
45
|
+
const files = [];
|
|
46
|
+
walkDir(cwd, 0, files);
|
|
47
|
+
return files;
|
|
48
|
+
}
|
|
49
|
+
function walkDir(dir, depth, files) {
|
|
50
|
+
if (depth > MAX_DEPTH)
|
|
51
|
+
return;
|
|
52
|
+
let entries;
|
|
53
|
+
try {
|
|
54
|
+
entries = (0, fs_1.readdirSync)(dir);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
if (EXCLUDED_DIRS.has(entry))
|
|
61
|
+
continue;
|
|
62
|
+
const fullPath = (0, path_1.join)(dir, entry);
|
|
63
|
+
if (entry === 'CLAUDE.md') {
|
|
64
|
+
const content = readFileSafe(fullPath);
|
|
65
|
+
if (content !== null) {
|
|
66
|
+
files.push({ path: fullPath, content });
|
|
67
|
+
}
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
if ((0, fs_1.statSync)(fullPath).isDirectory()) {
|
|
72
|
+
walkDir(fullPath, depth + 1, files);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Skip inaccessible entries
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function readFileSafe(filePath) {
|
|
81
|
+
try {
|
|
82
|
+
return (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collectRuleSources.d.ts","sourceRoot":"","sources":["../../src/collector/collectRuleSources.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAkB,MAAM,+BAA+B,CAAA;AA4D1E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,CAM5D"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.collectRuleSources = collectRuleSources;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const EXCLUDED_DIRS = new Set([
|
|
7
|
+
'node_modules',
|
|
8
|
+
'.git',
|
|
9
|
+
'target',
|
|
10
|
+
'.venv',
|
|
11
|
+
'vendor',
|
|
12
|
+
'__pycache__',
|
|
13
|
+
'dist',
|
|
14
|
+
'build',
|
|
15
|
+
]);
|
|
16
|
+
const MAX_DEPTH = 3;
|
|
17
|
+
// Files looked up directly inside a candidate directory
|
|
18
|
+
const DIRECT_FILES = [
|
|
19
|
+
{ filename: 'CLAUDE.md', kind: 'claude-md' },
|
|
20
|
+
{ filename: 'AGENTS.md', kind: 'agents-md' },
|
|
21
|
+
{ filename: '.cursorrules', kind: 'cursorrules' },
|
|
22
|
+
{ filename: 'CONVENTIONS.md', kind: 'aider-conventions' },
|
|
23
|
+
];
|
|
24
|
+
// Files looked up inside a known subdirectory of a candidate directory.
|
|
25
|
+
// e.g. `<dir>/.cursor/rules/*.mdc` ; the parentDir here is `.cursor/rules`
|
|
26
|
+
// or `.github` for copilot-instructions.md.
|
|
27
|
+
const NESTED_FILES = [
|
|
28
|
+
{
|
|
29
|
+
parentDir: '.cursor/rules',
|
|
30
|
+
fileMatcher: (name) => name.endsWith('.mdc'),
|
|
31
|
+
kind: 'cursor-mdc',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
parentDir: '.clinerules',
|
|
35
|
+
fileMatcher: (name) => name.endsWith('.md'),
|
|
36
|
+
kind: 'clinerules',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
parentDir: '.windsurf/rules',
|
|
40
|
+
fileMatcher: (name) => name.endsWith('.md'),
|
|
41
|
+
kind: 'windsurf-rule',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
parentDir: '.github',
|
|
45
|
+
fileMatcher: (name) => name === 'copilot-instructions.md',
|
|
46
|
+
kind: 'copilot-instructions',
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
function collectRuleSources(cwd) {
|
|
50
|
+
const upward = collectUpward(cwd);
|
|
51
|
+
const downward = collectDownward(cwd);
|
|
52
|
+
const upwardPaths = new Set(upward.map((f) => f.path));
|
|
53
|
+
return [...upward, ...downward.filter((f) => !upwardPaths.has(f.path))];
|
|
54
|
+
}
|
|
55
|
+
function collectUpward(cwd) {
|
|
56
|
+
const files = [];
|
|
57
|
+
let dir = cwd;
|
|
58
|
+
while (true) {
|
|
59
|
+
collectDirectFiles(dir, files);
|
|
60
|
+
collectNestedFiles(dir, files);
|
|
61
|
+
const parent = (0, path_1.dirname)(dir);
|
|
62
|
+
if (parent === dir)
|
|
63
|
+
break;
|
|
64
|
+
dir = parent;
|
|
65
|
+
}
|
|
66
|
+
return files;
|
|
67
|
+
}
|
|
68
|
+
function collectDownward(cwd) {
|
|
69
|
+
const files = [];
|
|
70
|
+
walkDir(cwd, 0, files);
|
|
71
|
+
return files;
|
|
72
|
+
}
|
|
73
|
+
function walkDir(dir, depth, files) {
|
|
74
|
+
if (depth > MAX_DEPTH)
|
|
75
|
+
return;
|
|
76
|
+
let entries;
|
|
77
|
+
try {
|
|
78
|
+
entries = (0, fs_1.readdirSync)(dir);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
for (const entry of entries) {
|
|
84
|
+
if (EXCLUDED_DIRS.has(entry))
|
|
85
|
+
continue;
|
|
86
|
+
const fullPath = (0, path_1.join)(dir, entry);
|
|
87
|
+
const directSpec = DIRECT_FILES.find((s) => s.filename === entry);
|
|
88
|
+
if (directSpec) {
|
|
89
|
+
const content = readFileSafe(fullPath);
|
|
90
|
+
if (content !== null) {
|
|
91
|
+
files.push({ path: fullPath, content, kind: directSpec.kind });
|
|
92
|
+
}
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
let isDir = false;
|
|
96
|
+
try {
|
|
97
|
+
isDir = (0, fs_1.statSync)(fullPath).isDirectory();
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (isDir) {
|
|
103
|
+
const nestedSpec = NESTED_FILES.find((s) => s.parentDir === entry);
|
|
104
|
+
if (nestedSpec) {
|
|
105
|
+
collectFromNestedDir(fullPath, nestedSpec, files);
|
|
106
|
+
}
|
|
107
|
+
walkDir(fullPath, depth + 1, files);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function collectDirectFiles(dir, files) {
|
|
112
|
+
for (const spec of DIRECT_FILES) {
|
|
113
|
+
const filePath = (0, path_1.join)(dir, spec.filename);
|
|
114
|
+
const content = readFileSafe(filePath);
|
|
115
|
+
if (content !== null) {
|
|
116
|
+
files.push({ path: filePath, content, kind: spec.kind });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function collectNestedFiles(dir, files) {
|
|
121
|
+
for (const spec of NESTED_FILES) {
|
|
122
|
+
const nestedDir = (0, path_1.join)(dir, spec.parentDir);
|
|
123
|
+
collectFromNestedDir(nestedDir, spec, files);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function collectFromNestedDir(nestedDir, spec, files) {
|
|
127
|
+
let entries;
|
|
128
|
+
try {
|
|
129
|
+
entries = (0, fs_1.readdirSync)(nestedDir);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
for (const entry of entries) {
|
|
135
|
+
if (!spec.fileMatcher(entry))
|
|
136
|
+
continue;
|
|
137
|
+
const fullPath = (0, path_1.join)(nestedDir, entry);
|
|
138
|
+
const content = readFileSafe(fullPath);
|
|
139
|
+
if (content !== null) {
|
|
140
|
+
files.push({ path: fullPath, content, kind: spec.kind });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function readFileSafe(filePath) {
|
|
145
|
+
try {
|
|
146
|
+
return (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AgentGatePluginConfig } from './defineConfig';
|
|
2
|
+
/**
|
|
3
|
+
* The resolved configuration that the hook pipeline consumes.
|
|
4
|
+
*
|
|
5
|
+
* This is the same shape as AgentGatePluginConfig; both names exist
|
|
6
|
+
* so callers can pick the more descriptive one for their context.
|
|
7
|
+
*/
|
|
8
|
+
export type AgentGateConfig = AgentGatePluginConfig;
|
|
9
|
+
/**
|
|
10
|
+
* Resolves the effective AgentGateConfig for the given cwd.
|
|
11
|
+
*
|
|
12
|
+
* Reads `.agent-gate.config.{ts,mts,mjs,cjs,js}` (preferred) or the
|
|
13
|
+
* legacy `.agent-gate.json`, walking upward from cwd. Merges the
|
|
14
|
+
* AGENT_GATE_DISABLED_RULES env var into disabledRules so command-line
|
|
15
|
+
* users can disable rules without touching the config file.
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadAgentGateConfig(cwd: string): AgentGateConfig;
|
|
18
|
+
//# sourceMappingURL=AgentGateConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentGateConfig.d.ts","sourceRoot":"","sources":["../../src/config/AgentGateConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAGtD;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,qBAAqB,CAAA;AAanD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAWhE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadAgentGateConfig = loadAgentGateConfig;
|
|
4
|
+
const PluginConfigLoader_1 = require("./PluginConfigLoader");
|
|
5
|
+
const ENV_DISABLED_RULES = 'AGENT_GATE_DISABLED_RULES';
|
|
6
|
+
function disabledFromEnv() {
|
|
7
|
+
const raw = process.env[ENV_DISABLED_RULES];
|
|
8
|
+
if (!raw)
|
|
9
|
+
return [];
|
|
10
|
+
return raw
|
|
11
|
+
.split(',')
|
|
12
|
+
.map((s) => s.trim())
|
|
13
|
+
.filter((s) => s.length > 0);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolves the effective AgentGateConfig for the given cwd.
|
|
17
|
+
*
|
|
18
|
+
* Reads `.agent-gate.config.{ts,mts,mjs,cjs,js}` (preferred) or the
|
|
19
|
+
* legacy `.agent-gate.json`, walking upward from cwd. Merges the
|
|
20
|
+
* AGENT_GATE_DISABLED_RULES env var into disabledRules so command-line
|
|
21
|
+
* users can disable rules without touching the config file.
|
|
22
|
+
*/
|
|
23
|
+
function loadAgentGateConfig(cwd) {
|
|
24
|
+
const fromFile = (0, PluginConfigLoader_1.loadPluginConfig)(cwd);
|
|
25
|
+
const fromEnv = disabledFromEnv();
|
|
26
|
+
const combinedDisabled = new Set([
|
|
27
|
+
...(fromFile.disabledRules ?? []),
|
|
28
|
+
...fromEnv,
|
|
29
|
+
]);
|
|
30
|
+
return {
|
|
31
|
+
...fromFile,
|
|
32
|
+
disabledRules: Array.from(combinedDisabled),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
2
|
+
export type ConfigOptions = {
|
|
3
|
+
model?: string;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
cooldown?: number;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
useSystemClaude?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Language for the AI validator's "reason" field.
|
|
10
|
+
* - "auto" (or undefined): match the dominant language of the instruction
|
|
11
|
+
* files, falling back to English when ambiguous.
|
|
12
|
+
* - "en", "ja", "zh", "ko", etc.: write reasons in that language.
|
|
13
|
+
*/
|
|
14
|
+
reasonLang?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare class Config {
|
|
17
|
+
readonly model: string;
|
|
18
|
+
readonly apiKey: string | undefined;
|
|
19
|
+
readonly cooldown: number;
|
|
20
|
+
readonly disabled: boolean;
|
|
21
|
+
readonly useSystemClaude: boolean;
|
|
22
|
+
readonly reasonLang: string | undefined;
|
|
23
|
+
constructor(options?: ConfigOptions);
|
|
24
|
+
get useApi(): boolean;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=Config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/config/Config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,sBAAsB,CAAA;AAEhD,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,qBAAa,MAAM;IACjB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;gBAE3B,OAAO,CAAC,EAAE,aAAa;IAUnC,IAAI,MAAM,IAAI,OAAO,CAEpB;CACF"}
|