@triedotdev/mcp 1.0.94 → 1.0.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -137
- package/dist/{chunk-JAAIHNOE.js → chunk-APMV77PU.js} +21 -6
- package/dist/chunk-APMV77PU.js.map +1 -0
- package/dist/{chunk-HLSBTOVE.js → chunk-B3MNN3XB.js} +13 -18
- package/dist/{chunk-HLSBTOVE.js.map → chunk-B3MNN3XB.js.map} +1 -1
- package/dist/{chunk-JO6RVXS6.js → chunk-F4NJ4CBP.js} +2 -2
- package/dist/{chunk-AZRCKBGF.js → chunk-FNCCZ3XB.js} +1222 -75
- package/dist/chunk-FNCCZ3XB.js.map +1 -0
- package/dist/chunk-G76DYVGX.js +136 -0
- package/dist/chunk-G76DYVGX.js.map +1 -0
- package/dist/chunk-HSNE46VE.js +956 -0
- package/dist/chunk-HSNE46VE.js.map +1 -0
- package/dist/{chunk-STEFLYPR.js → chunk-IXO4G4D3.js} +2 -2
- package/dist/{chunk-OEYIOOYB.js → chunk-JDHR5BDR.js} +2 -3
- package/dist/chunk-NIASHOAB.js +1304 -0
- package/dist/chunk-NIASHOAB.js.map +1 -0
- package/dist/{chunk-CKM6A3G6.js → chunk-OVRG5RP3.js} +6 -7
- package/dist/chunk-OVRG5RP3.js.map +1 -0
- package/dist/{chunk-RYRVEO2B.js → chunk-R3I2GCZC.js} +3 -3
- package/dist/{chunk-WT3XQCG2.js → chunk-R4AAPFXC.js} +2 -2
- package/dist/{chunk-IIF5XDCJ.js → chunk-SLL2MDJD.js} +786 -4694
- package/dist/chunk-SLL2MDJD.js.map +1 -0
- package/dist/cli/create-agent.js +931 -7
- package/dist/cli/create-agent.js.map +1 -1
- package/dist/cli/main.js +151 -383
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +13 -20
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/{goal-manager-HOZ7R2QV.js → goal-manager-LAOT4QQX.js} +6 -6
- package/dist/guardian-agent-M352CBE5.js +19 -0
- package/dist/index.js +1025 -1550
- package/dist/index.js.map +1 -1
- package/dist/{issue-store-DXIOP6AK.js → issue-store-W2X33X2X.js} +4 -4
- package/dist/{progress-LHI66U7B.js → progress-PQVEM7BR.js} +2 -2
- package/dist/{vibe-code-signatures-C5A4BHXD.js → vibe-code-signatures-ELEWJFGZ.js} +3 -3
- package/dist/{vulnerability-signatures-SVIHJQO5.js → vulnerability-signatures-EIJQX2TS.js} +3 -3
- package/dist/workers/agent-worker.js +2 -11
- package/dist/workers/agent-worker.js.map +1 -1
- package/package.json +2 -2
- package/dist/agent-smith-MYQ35URL.js +0 -14
- package/dist/agent-smith-runner-4TBONXCP.js +0 -573
- package/dist/agent-smith-runner-4TBONXCP.js.map +0 -1
- package/dist/cache-manager-RMPRPD5T.js +0 -10
- package/dist/chunk-AZRCKBGF.js.map +0 -1
- package/dist/chunk-CKM6A3G6.js.map +0 -1
- package/dist/chunk-E2ZATINO.js +0 -10879
- package/dist/chunk-E2ZATINO.js.map +0 -1
- package/dist/chunk-FFWNZUG2.js +0 -266
- package/dist/chunk-FFWNZUG2.js.map +0 -1
- package/dist/chunk-FK6DQKDY.js +0 -175
- package/dist/chunk-FK6DQKDY.js.map +0 -1
- package/dist/chunk-IFGF33R5.js +0 -279
- package/dist/chunk-IFGF33R5.js.map +0 -1
- package/dist/chunk-IIF5XDCJ.js.map +0 -1
- package/dist/chunk-JAAIHNOE.js.map +0 -1
- package/dist/chunk-ODWDESYP.js +0 -141
- package/dist/chunk-ODWDESYP.js.map +0 -1
- package/dist/chunk-OWBWNXSC.js +0 -955
- package/dist/chunk-OWBWNXSC.js.map +0 -1
- package/dist/chunk-Q764X2WD.js +0 -2124
- package/dist/chunk-Q764X2WD.js.map +0 -1
- package/dist/chunk-RE6ZWXJC.js +0 -279
- package/dist/chunk-RE6ZWXJC.js.map +0 -1
- package/dist/chunk-RNJ6JKMA.js +0 -2270
- package/dist/chunk-RNJ6JKMA.js.map +0 -1
- package/dist/chunk-Y62VM3ER.js +0 -536
- package/dist/chunk-Y62VM3ER.js.map +0 -1
- package/dist/git-45LZUUYA.js +0 -29
- package/dist/guardian-agent-RB2UQP5V.js +0 -21
- package/dist/progress-LHI66U7B.js.map +0 -1
- package/dist/vibe-code-signatures-C5A4BHXD.js.map +0 -1
- package/dist/vulnerability-signatures-SVIHJQO5.js.map +0 -1
- /package/dist/{chunk-JO6RVXS6.js.map → chunk-F4NJ4CBP.js.map} +0 -0
- /package/dist/{chunk-STEFLYPR.js.map → chunk-IXO4G4D3.js.map} +0 -0
- /package/dist/{chunk-OEYIOOYB.js.map → chunk-JDHR5BDR.js.map} +0 -0
- /package/dist/{chunk-RYRVEO2B.js.map → chunk-R3I2GCZC.js.map} +0 -0
- /package/dist/{chunk-WT3XQCG2.js.map → chunk-R4AAPFXC.js.map} +0 -0
- /package/dist/{agent-smith-MYQ35URL.js.map → goal-manager-LAOT4QQX.js.map} +0 -0
- /package/dist/{cache-manager-RMPRPD5T.js.map → guardian-agent-M352CBE5.js.map} +0 -0
- /package/dist/{git-45LZUUYA.js.map → issue-store-W2X33X2X.js.map} +0 -0
- /package/dist/{goal-manager-HOZ7R2QV.js.map → progress-PQVEM7BR.js.map} +0 -0
- /package/dist/{guardian-agent-RB2UQP5V.js.map → vibe-code-signatures-ELEWJFGZ.js.map} +0 -0
- /package/dist/{issue-store-DXIOP6AK.js.map → vulnerability-signatures-EIJQX2TS.js.map} +0 -0
package/dist/chunk-IFGF33R5.js
DELETED
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getTrieDirectory,
|
|
3
|
-
getWorkingDirectory
|
|
4
|
-
} from "./chunk-WT3XQCG2.js";
|
|
5
|
-
|
|
6
|
-
// src/utils/command-runner.ts
|
|
7
|
-
import { exec, execFile, execSync } from "child_process";
|
|
8
|
-
import { promisify } from "util";
|
|
9
|
-
|
|
10
|
-
// src/skills/audit-logger.ts
|
|
11
|
-
import { writeFile, mkdir, readdir, readFile } from "fs/promises";
|
|
12
|
-
import { join } from "path";
|
|
13
|
-
async function logSkillExecution(execution) {
|
|
14
|
-
const workDir = getWorkingDirectory(void 0, true);
|
|
15
|
-
const auditDir = join(getTrieDirectory(workDir), "audit");
|
|
16
|
-
await mkdir(auditDir, { recursive: true });
|
|
17
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
18
|
-
const safeSkillName = execution.skillName.replace(/[^a-z0-9-]/gi, "_");
|
|
19
|
-
const filename = `${timestamp}_${safeSkillName}.json`;
|
|
20
|
-
const filepath = join(auditDir, filename);
|
|
21
|
-
if (!execution.endTime) {
|
|
22
|
-
execution.endTime = Date.now();
|
|
23
|
-
}
|
|
24
|
-
if (!execution.duration) {
|
|
25
|
-
execution.duration = execution.endTime - execution.startTime;
|
|
26
|
-
}
|
|
27
|
-
await writeFile(filepath, JSON.stringify(execution, null, 2), "utf-8");
|
|
28
|
-
}
|
|
29
|
-
function createAuditEntry(skillName, skillSource, triggeredBy, targetPath) {
|
|
30
|
-
return {
|
|
31
|
-
skillName,
|
|
32
|
-
skillSource,
|
|
33
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34
|
-
startTime: Date.now(),
|
|
35
|
-
success: false,
|
|
36
|
-
triggeredBy,
|
|
37
|
-
targetPath,
|
|
38
|
-
commands: [],
|
|
39
|
-
networkCalls: [],
|
|
40
|
-
filesAccessed: [],
|
|
41
|
-
filesModified: []
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function completeAuditEntry(entry, success, error) {
|
|
45
|
-
const base = {
|
|
46
|
-
...entry,
|
|
47
|
-
success,
|
|
48
|
-
endTime: Date.now(),
|
|
49
|
-
duration: Date.now() - entry.startTime
|
|
50
|
-
};
|
|
51
|
-
return error ? { ...base, error } : base;
|
|
52
|
-
}
|
|
53
|
-
async function getRecentAuditLogs(limit = 10) {
|
|
54
|
-
const workDir = getWorkingDirectory(void 0, true);
|
|
55
|
-
const auditDir = join(getTrieDirectory(workDir), "audit");
|
|
56
|
-
try {
|
|
57
|
-
const files = await readdir(auditDir);
|
|
58
|
-
const sorted = files.filter((f) => f.endsWith(".json")).sort().reverse().slice(0, limit);
|
|
59
|
-
const logs = [];
|
|
60
|
-
for (const file of sorted) {
|
|
61
|
-
try {
|
|
62
|
-
const content = await readFile(join(auditDir, file), "utf-8");
|
|
63
|
-
logs.push(JSON.parse(content));
|
|
64
|
-
} catch {
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return logs;
|
|
68
|
-
} catch {
|
|
69
|
-
return [];
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
async function getSkillAuditLogs(skillName) {
|
|
73
|
-
const workDir = getWorkingDirectory(void 0, true);
|
|
74
|
-
const auditDir = join(getTrieDirectory(workDir), "audit");
|
|
75
|
-
const safeSkillName = skillName.replace(/[^a-z0-9-]/gi, "_");
|
|
76
|
-
try {
|
|
77
|
-
const files = await readdir(auditDir);
|
|
78
|
-
const skillFiles = files.filter(
|
|
79
|
-
(f) => f.includes(`_${safeSkillName}.json`)
|
|
80
|
-
);
|
|
81
|
-
const logs = [];
|
|
82
|
-
for (const file of skillFiles) {
|
|
83
|
-
try {
|
|
84
|
-
const content = await readFile(join(auditDir, file), "utf-8");
|
|
85
|
-
logs.push(JSON.parse(content));
|
|
86
|
-
} catch {
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return logs.sort(
|
|
90
|
-
(a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
|
91
|
-
);
|
|
92
|
-
} catch {
|
|
93
|
-
return [];
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
async function getAuditStatistics() {
|
|
97
|
-
const logs = await getRecentAuditLogs(1e3);
|
|
98
|
-
const skills = /* @__PURE__ */ new Set();
|
|
99
|
-
let totalCommands = 0;
|
|
100
|
-
let totalNetworkCalls = 0;
|
|
101
|
-
let blockedCommands = 0;
|
|
102
|
-
let blockedNetworkCalls = 0;
|
|
103
|
-
for (const log of logs) {
|
|
104
|
-
skills.add(log.skillName);
|
|
105
|
-
totalCommands += log.commands?.length ?? 0;
|
|
106
|
-
totalNetworkCalls += log.networkCalls?.length ?? 0;
|
|
107
|
-
blockedCommands += log.commands?.filter((c) => c.blockedBy).length ?? 0;
|
|
108
|
-
blockedNetworkCalls += log.networkCalls?.filter((c) => c.blocked).length ?? 0;
|
|
109
|
-
}
|
|
110
|
-
return {
|
|
111
|
-
totalExecutions: logs.length,
|
|
112
|
-
successfulExecutions: logs.filter((l) => l.success).length,
|
|
113
|
-
failedExecutions: logs.filter((l) => !l.success).length,
|
|
114
|
-
uniqueSkills: skills.size,
|
|
115
|
-
totalCommands,
|
|
116
|
-
totalNetworkCalls,
|
|
117
|
-
blockedCommands,
|
|
118
|
-
blockedNetworkCalls
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
function formatAuditLog(log) {
|
|
122
|
-
const lines = [];
|
|
123
|
-
const status = log.success ? "\u2705" : "\u274C";
|
|
124
|
-
const duration = log.duration ? `${log.duration}ms` : "unknown";
|
|
125
|
-
lines.push(`${status} ${log.skillName} (${duration})`);
|
|
126
|
-
lines.push(` Time: ${new Date(log.timestamp).toLocaleString()}`);
|
|
127
|
-
lines.push(` Triggered by: ${log.triggeredBy}`);
|
|
128
|
-
lines.push(` Target: ${log.targetPath}`);
|
|
129
|
-
if (log.commands && log.commands.length > 0) {
|
|
130
|
-
lines.push(` Commands executed: ${log.commands.length}`);
|
|
131
|
-
const blocked = log.commands.filter((c) => c.blockedBy).length;
|
|
132
|
-
if (blocked > 0) {
|
|
133
|
-
lines.push(` \u26A0\uFE0F Commands blocked: ${blocked}`);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (log.networkCalls && log.networkCalls.length > 0) {
|
|
137
|
-
lines.push(` Network calls: ${log.networkCalls.length}`);
|
|
138
|
-
const blocked = log.networkCalls.filter((c) => c.blocked).length;
|
|
139
|
-
if (blocked > 0) {
|
|
140
|
-
lines.push(` \u26A0\uFE0F Network calls blocked: ${blocked}`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
if (log.error) {
|
|
144
|
-
lines.push(` Error: ${log.error}`);
|
|
145
|
-
}
|
|
146
|
-
return lines.join("\n");
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// src/utils/command-runner.ts
|
|
150
|
-
var execAsync = promisify(exec);
|
|
151
|
-
var execFileAsync = promisify(execFile);
|
|
152
|
-
function redact(text) {
|
|
153
|
-
return text.replace(/\b(AWS|ANTHROPIC|OPENAI|GITHUB)_[A-Z0-9_]*\s*=\s*([^\s"'`]+)/gi, "$1_<REDACTED>=<REDACTED>").replace(/\bBearer\s+[A-Za-z0-9\-._~+/]+=*\b/g, "Bearer <REDACTED>").replace(/\bghp_[A-Za-z0-9]{20,}\b/g, "ghp_<REDACTED>").replace(/\b(?:xox[baprs]-)[A-Za-z0-9-]{10,}\b/g, "<REDACTED_SLACK_TOKEN>").replace(/\bAKIA[0-9A-Z]{16}\b/g, "AKIA<REDACTED>");
|
|
154
|
-
}
|
|
155
|
-
function clampOutput(text, maxChars) {
|
|
156
|
-
if (text.length <= maxChars) return text;
|
|
157
|
-
return text.slice(0, maxChars) + `
|
|
158
|
-
\u2026(truncated ${text.length - maxChars} chars)`;
|
|
159
|
-
}
|
|
160
|
-
function buildCommandRecord(command) {
|
|
161
|
-
return {
|
|
162
|
-
command,
|
|
163
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
async function finalizeAndWrite(entry, cmd, outcome, options) {
|
|
167
|
-
const duration = Date.now() - outcome.startedAt;
|
|
168
|
-
cmd.duration = duration;
|
|
169
|
-
if (outcome.exitCode !== void 0) {
|
|
170
|
-
cmd.exitCode = outcome.exitCode;
|
|
171
|
-
}
|
|
172
|
-
const captureOutput = options?.captureOutput ?? false;
|
|
173
|
-
const redactOutput = options?.redactOutput ?? true;
|
|
174
|
-
const maxOutputChars = options?.maxOutputChars ?? 2e3;
|
|
175
|
-
if (captureOutput) {
|
|
176
|
-
const out = outcome.stdout ?? "";
|
|
177
|
-
const err = outcome.stderr ?? "";
|
|
178
|
-
cmd.stdout = redactOutput ? redact(clampOutput(out, maxOutputChars)) : clampOutput(out, maxOutputChars);
|
|
179
|
-
cmd.stderr = redactOutput ? redact(clampOutput(err, maxOutputChars)) : clampOutput(err, maxOutputChars);
|
|
180
|
-
}
|
|
181
|
-
const completed = completeAuditEntry(entry, outcome.success, outcome.error);
|
|
182
|
-
await logSkillExecution(completed);
|
|
183
|
-
}
|
|
184
|
-
async function runShellCommand(command, audit, options) {
|
|
185
|
-
const startedAt = Date.now();
|
|
186
|
-
const entry = createAuditEntry(audit.actor, audit.source ?? "trie", audit.triggeredBy, audit.targetPath);
|
|
187
|
-
const cmd = buildCommandRecord(command);
|
|
188
|
-
entry.commands?.push(cmd);
|
|
189
|
-
try {
|
|
190
|
-
const { stdout, stderr } = await execAsync(command, {
|
|
191
|
-
cwd: options?.cwd,
|
|
192
|
-
timeout: options?.timeoutMs,
|
|
193
|
-
maxBuffer: options?.maxBuffer
|
|
194
|
-
});
|
|
195
|
-
await finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout, stderr, startedAt }, options);
|
|
196
|
-
return { stdout: stdout ?? "", stderr: stderr ?? "", exitCode: 0 };
|
|
197
|
-
} catch (e) {
|
|
198
|
-
const err = e;
|
|
199
|
-
const stdout = typeof err.stdout === "string" ? err.stdout : "";
|
|
200
|
-
const stderr = typeof err.stderr === "string" ? err.stderr : "";
|
|
201
|
-
const exitCode = typeof err.code === "number" ? err.code : 1;
|
|
202
|
-
await finalizeAndWrite(
|
|
203
|
-
entry,
|
|
204
|
-
cmd,
|
|
205
|
-
{ success: false, exitCode, stdout, stderr, error: err.message, startedAt },
|
|
206
|
-
// Capture output for failures by default (so audits are useful)
|
|
207
|
-
{ ...options, captureOutput: options?.captureOutput ?? true }
|
|
208
|
-
);
|
|
209
|
-
return { stdout, stderr, exitCode };
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
function runShellCommandSync(command, audit, options) {
|
|
213
|
-
const startedAt = Date.now();
|
|
214
|
-
const entry = createAuditEntry(audit.actor, audit.source ?? "trie", audit.triggeredBy, audit.targetPath);
|
|
215
|
-
const cmd = buildCommandRecord(command);
|
|
216
|
-
entry.commands?.push(cmd);
|
|
217
|
-
try {
|
|
218
|
-
const stdout = execSync(command, {
|
|
219
|
-
cwd: options?.cwd,
|
|
220
|
-
timeout: options?.timeoutMs,
|
|
221
|
-
maxBuffer: options?.maxBuffer,
|
|
222
|
-
encoding: "utf-8",
|
|
223
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
224
|
-
});
|
|
225
|
-
void finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout, stderr: "", startedAt }, options);
|
|
226
|
-
return { stdout: stdout ?? "", exitCode: 0 };
|
|
227
|
-
} catch (e) {
|
|
228
|
-
const err = e;
|
|
229
|
-
const stdout = typeof err.stdout === "string" ? err.stdout : "";
|
|
230
|
-
const stderr = typeof err.stderr === "string" ? err.stderr : "";
|
|
231
|
-
const exitCode = typeof err.status === "number" ? err.status : 1;
|
|
232
|
-
void finalizeAndWrite(
|
|
233
|
-
entry,
|
|
234
|
-
cmd,
|
|
235
|
-
{ success: false, exitCode, stdout, stderr, error: err.message, startedAt },
|
|
236
|
-
{ ...options, captureOutput: options?.captureOutput ?? true }
|
|
237
|
-
);
|
|
238
|
-
return { stdout, exitCode };
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
async function runExecFile(file, args, audit, options) {
|
|
242
|
-
const startedAt = Date.now();
|
|
243
|
-
const command = [file, ...args].join(" ");
|
|
244
|
-
const entry = createAuditEntry(audit.actor, audit.source ?? "trie", audit.triggeredBy, audit.targetPath);
|
|
245
|
-
const cmd = buildCommandRecord(command);
|
|
246
|
-
entry.commands?.push(cmd);
|
|
247
|
-
try {
|
|
248
|
-
const { stdout, stderr } = await execFileAsync(file, args, {
|
|
249
|
-
cwd: options?.cwd,
|
|
250
|
-
timeout: options?.timeoutMs,
|
|
251
|
-
maxBuffer: options?.maxBuffer
|
|
252
|
-
});
|
|
253
|
-
await finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout: String(stdout ?? ""), stderr: String(stderr ?? ""), startedAt }, options);
|
|
254
|
-
return { stdout: String(stdout ?? ""), stderr: String(stderr ?? ""), exitCode: 0 };
|
|
255
|
-
} catch (e) {
|
|
256
|
-
const err = e;
|
|
257
|
-
const stdout = typeof err.stdout === "string" ? err.stdout : "";
|
|
258
|
-
const stderr = typeof err.stderr === "string" ? err.stderr : "";
|
|
259
|
-
const exitCode = typeof err.code === "number" ? err.code : 1;
|
|
260
|
-
await finalizeAndWrite(
|
|
261
|
-
entry,
|
|
262
|
-
cmd,
|
|
263
|
-
{ success: false, exitCode, stdout, stderr, error: err.message, startedAt },
|
|
264
|
-
{ ...options, captureOutput: options?.captureOutput ?? true }
|
|
265
|
-
);
|
|
266
|
-
return { stdout, stderr, exitCode };
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
export {
|
|
271
|
-
getRecentAuditLogs,
|
|
272
|
-
getSkillAuditLogs,
|
|
273
|
-
getAuditStatistics,
|
|
274
|
-
formatAuditLog,
|
|
275
|
-
runShellCommand,
|
|
276
|
-
runShellCommandSync,
|
|
277
|
-
runExecFile
|
|
278
|
-
};
|
|
279
|
-
//# sourceMappingURL=chunk-IFGF33R5.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/command-runner.ts","../src/skills/audit-logger.ts"],"sourcesContent":["/**\n * Command Runner (with audit logging)\n *\n * Goal: Whenever Trie runs a shell command, record:\n * - command string\n * - exit code\n * - duration\n * - optional (redacted) stdout/stderr\n */\nimport { exec, execFile, execSync, type ExecException } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nimport {\n createAuditEntry,\n completeAuditEntry,\n logSkillExecution,\n type ExecutedCommand,\n type SkillExecution,\n} from '../skills/audit-logger.js';\n\nconst execAsync = promisify(exec);\nconst execFileAsync = promisify(execFile);\n\nexport type AuditTriggeredBy = SkillExecution['triggeredBy'];\n\nexport interface CommandAuditContext {\n /** Shown as `skillName` in audit logs; use something like `tool:pr-review` */\n actor: string;\n /** Where this came from in the product flow */\n triggeredBy: AuditTriggeredBy;\n /** Usually the working directory / repo path */\n targetPath: string;\n /** Optional string for `skillSource` */\n source?: string;\n}\n\nexport interface RunCommandOptions {\n cwd?: string;\n timeoutMs?: number;\n maxBuffer?: number;\n\n /** Capture stdout/stderr in the audit log */\n captureOutput?: boolean;\n /** Redact obvious secrets from captured output */\n redactOutput?: boolean;\n /** Max chars to keep per output stream */\n maxOutputChars?: number;\n}\n\nfunction redact(text: string): string {\n // Keep this conservative to avoid false redaction and avoid expensive processing.\n return text\n // Common key=value secrets\n .replace(/\\b(AWS|ANTHROPIC|OPENAI|GITHUB)_[A-Z0-9_]*\\s*=\\s*([^\\s\"'`]+)/gi, '$1_<REDACTED>=<REDACTED>')\n // Bearer tokens\n .replace(/\\bBearer\\s+[A-Za-z0-9\\-._~+/]+=*\\b/g, 'Bearer <REDACTED>')\n // GitHub tokens / generic tokens\n .replace(/\\bghp_[A-Za-z0-9]{20,}\\b/g, 'ghp_<REDACTED>')\n .replace(/\\b(?:xox[baprs]-)[A-Za-z0-9-]{10,}\\b/g, '<REDACTED_SLACK_TOKEN>')\n // AWS access key id (best-effort)\n .replace(/\\bAKIA[0-9A-Z]{16}\\b/g, 'AKIA<REDACTED>');\n}\n\nfunction clampOutput(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text;\n return text.slice(0, maxChars) + `\\n…(truncated ${text.length - maxChars} chars)`;\n}\n\nfunction buildCommandRecord(command: string): ExecutedCommand {\n return {\n command,\n timestamp: new Date().toISOString(),\n };\n}\n\nasync function finalizeAndWrite(\n entry: SkillExecution,\n cmd: ExecutedCommand,\n outcome: { success: boolean; exitCode?: number; stdout?: string; stderr?: string; error?: string; startedAt: number },\n options?: Pick<RunCommandOptions, 'captureOutput' | 'redactOutput' | 'maxOutputChars'>\n): Promise<void> {\n const duration = Date.now() - outcome.startedAt;\n cmd.duration = duration;\n if (outcome.exitCode !== undefined) {\n cmd.exitCode = outcome.exitCode;\n }\n\n const captureOutput = options?.captureOutput ?? false;\n const redactOutput = options?.redactOutput ?? true;\n const maxOutputChars = options?.maxOutputChars ?? 2000;\n\n if (captureOutput) {\n const out = outcome.stdout ?? '';\n const err = outcome.stderr ?? '';\n cmd.stdout = redactOutput ? redact(clampOutput(out, maxOutputChars)) : clampOutput(out, maxOutputChars);\n cmd.stderr = redactOutput ? redact(clampOutput(err, maxOutputChars)) : clampOutput(err, maxOutputChars);\n }\n\n const completed = completeAuditEntry(entry, outcome.success, outcome.error);\n await logSkillExecution(completed);\n}\n\nexport async function runShellCommand(\n command: string,\n audit: CommandAuditContext,\n options?: RunCommandOptions\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const startedAt = Date.now();\n const entry = createAuditEntry(audit.actor, audit.source ?? 'trie', audit.triggeredBy, audit.targetPath);\n const cmd = buildCommandRecord(command);\n entry.commands?.push(cmd);\n\n try {\n const { stdout, stderr } = await execAsync(command, {\n cwd: options?.cwd,\n timeout: options?.timeoutMs,\n maxBuffer: options?.maxBuffer,\n });\n\n await finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout, stderr, startedAt }, options);\n return { stdout: stdout ?? '', stderr: stderr ?? '', exitCode: 0 };\n } catch (e) {\n const err = e as ExecException & { stdout?: unknown; stderr?: unknown; code?: unknown };\n const stdout = typeof err.stdout === 'string' ? err.stdout : '';\n const stderr = typeof err.stderr === 'string' ? err.stderr : '';\n const exitCode = typeof err.code === 'number' ? err.code : 1;\n\n await finalizeAndWrite(\n entry,\n cmd,\n { success: false, exitCode, stdout, stderr, error: err.message, startedAt },\n // Capture output for failures by default (so audits are useful)\n { ...options, captureOutput: options?.captureOutput ?? true }\n );\n\n return { stdout, stderr, exitCode };\n }\n}\n\nexport function runShellCommandSync(\n command: string,\n audit: CommandAuditContext,\n options?: Omit<RunCommandOptions, 'timeoutMs'> & { timeoutMs?: number }\n): { stdout: string; exitCode: number } {\n const startedAt = Date.now();\n const entry = createAuditEntry(audit.actor, audit.source ?? 'trie', audit.triggeredBy, audit.targetPath);\n const cmd = buildCommandRecord(command);\n entry.commands?.push(cmd);\n\n try {\n const stdout = execSync(command, {\n cwd: options?.cwd,\n timeout: options?.timeoutMs,\n maxBuffer: options?.maxBuffer,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n // Fire-and-forget write; sync APIs can’t await.\n void finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout, stderr: '', startedAt }, options);\n return { stdout: stdout ?? '', exitCode: 0 };\n } catch (e) {\n const err = e as ExecException & { stdout?: unknown; stderr?: unknown; status?: unknown };\n const stdout = typeof err.stdout === 'string' ? err.stdout : '';\n const stderr = typeof err.stderr === 'string' ? err.stderr : '';\n const exitCode = typeof err.status === 'number' ? err.status : 1;\n\n void finalizeAndWrite(\n entry,\n cmd,\n { success: false, exitCode, stdout, stderr, error: err.message, startedAt },\n { ...options, captureOutput: options?.captureOutput ?? true }\n );\n\n return { stdout, exitCode };\n }\n}\n\nexport async function runExecFile(\n file: string,\n args: string[],\n audit: CommandAuditContext,\n options?: Omit<RunCommandOptions, 'timeoutMs'> & { timeoutMs?: number }\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const startedAt = Date.now();\n const command = [file, ...args].join(' ');\n const entry = createAuditEntry(audit.actor, audit.source ?? 'trie', audit.triggeredBy, audit.targetPath);\n const cmd = buildCommandRecord(command);\n entry.commands?.push(cmd);\n\n try {\n const { stdout, stderr } = await execFileAsync(file, args, {\n cwd: options?.cwd,\n timeout: options?.timeoutMs,\n maxBuffer: options?.maxBuffer,\n });\n\n await finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout: String(stdout ?? ''), stderr: String(stderr ?? ''), startedAt }, options);\n return { stdout: String(stdout ?? ''), stderr: String(stderr ?? ''), exitCode: 0 };\n } catch (e) {\n const err = e as ExecException & { stdout?: unknown; stderr?: unknown; code?: unknown };\n const stdout = typeof err.stdout === 'string' ? err.stdout : '';\n const stderr = typeof err.stderr === 'string' ? err.stderr : '';\n const exitCode = typeof err.code === 'number' ? err.code : 1;\n\n await finalizeAndWrite(\n entry,\n cmd,\n { success: false, exitCode, stdout, stderr, error: err.message, startedAt },\n { ...options, captureOutput: options?.captureOutput ?? true }\n );\n return { stdout, stderr, exitCode };\n }\n}\n\n","/**\n * Skill Audit Logger\n * \n * Logs all skill operations for security auditing\n */\n\nimport { writeFile, mkdir, readdir, readFile } from 'fs/promises';\nimport { join } from 'path';\nimport { getWorkingDirectory, getTrieDirectory } from '../utils/workspace.js';\n\nexport interface SkillExecution {\n skillName: string;\n skillSource: string;\n timestamp: string;\n startTime: number;\n endTime?: number;\n duration?: number;\n success: boolean;\n error?: string;\n \n // What the skill did\n commands?: ExecutedCommand[];\n networkCalls?: NetworkCall[];\n filesAccessed?: string[];\n filesModified?: string[];\n \n // Context\n triggeredBy: 'scan' | 'check' | 'manual' | 'watch';\n targetPath: string;\n}\n\nexport interface ExecutedCommand {\n command: string;\n timestamp: string;\n exitCode?: number;\n duration?: number;\n stdout?: string;\n stderr?: string;\n blockedBy?: string; // If blocked, what rule blocked it\n}\n\nexport interface NetworkCall {\n url: string;\n method: string;\n timestamp: string;\n duration?: number;\n statusCode?: number;\n blocked?: boolean;\n blockedReason?: string;\n}\n\n/**\n * Log a skill execution for audit trail\n */\nexport async function logSkillExecution(execution: SkillExecution): Promise<void> {\n const workDir = getWorkingDirectory(undefined, true);\n const auditDir = join(getTrieDirectory(workDir), 'audit');\n \n await mkdir(auditDir, { recursive: true });\n \n // Create filename with timestamp and skill name\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const safeSkillName = execution.skillName.replace(/[^a-z0-9-]/gi, '_');\n const filename = `${timestamp}_${safeSkillName}.json`;\n const filepath = join(auditDir, filename);\n \n // Add end time if not set\n if (!execution.endTime) {\n execution.endTime = Date.now();\n }\n \n // Calculate duration\n if (!execution.duration) {\n execution.duration = execution.endTime - execution.startTime;\n }\n \n await writeFile(filepath, JSON.stringify(execution, null, 2), 'utf-8');\n}\n\n/**\n * Create audit log entry for a skill execution start\n */\nexport function createAuditEntry(\n skillName: string,\n skillSource: string,\n triggeredBy: SkillExecution['triggeredBy'],\n targetPath: string\n): SkillExecution {\n return {\n skillName,\n skillSource,\n timestamp: new Date().toISOString(),\n startTime: Date.now(),\n success: false,\n triggeredBy,\n targetPath,\n commands: [],\n networkCalls: [],\n filesAccessed: [],\n filesModified: [],\n };\n}\n\n/**\n * Mark execution as complete\n */\nexport function completeAuditEntry(\n entry: SkillExecution,\n success: boolean,\n error?: string\n): SkillExecution {\n const base: SkillExecution = {\n ...entry,\n success,\n endTime: Date.now(),\n duration: Date.now() - entry.startTime,\n };\n return error ? { ...base, error } : base;\n}\n\n/**\n * Get recent audit logs\n */\nexport async function getRecentAuditLogs(limit: number = 10): Promise<SkillExecution[]> {\n const workDir = getWorkingDirectory(undefined, true);\n const auditDir = join(getTrieDirectory(workDir), 'audit');\n \n try {\n const files = await readdir(auditDir);\n \n // Sort by filename (which includes timestamp) descending\n const sorted = files\n .filter(f => f.endsWith('.json'))\n .sort()\n .reverse()\n .slice(0, limit);\n \n const logs: SkillExecution[] = [];\n \n for (const file of sorted) {\n try {\n const content = await readFile(join(auditDir, file), 'utf-8');\n logs.push(JSON.parse(content));\n } catch {\n // Skip malformed logs\n }\n }\n \n return logs;\n } catch {\n // Audit directory doesn't exist yet\n return [];\n }\n}\n\n/**\n * Get audit logs for a specific skill\n */\nexport async function getSkillAuditLogs(skillName: string): Promise<SkillExecution[]> {\n const workDir = getWorkingDirectory(undefined, true);\n const auditDir = join(getTrieDirectory(workDir), 'audit');\n const safeSkillName = skillName.replace(/[^a-z0-9-]/gi, '_');\n \n try {\n const files = await readdir(auditDir);\n \n const skillFiles = files.filter(f => \n f.includes(`_${safeSkillName}.json`)\n );\n \n const logs: SkillExecution[] = [];\n \n for (const file of skillFiles) {\n try {\n const content = await readFile(join(auditDir, file), 'utf-8');\n logs.push(JSON.parse(content));\n } catch {\n // Skip malformed logs\n }\n }\n \n return logs.sort((a, b) => \n new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n } catch {\n return [];\n }\n}\n\n/**\n * Get audit statistics\n */\nexport async function getAuditStatistics(): Promise<{\n totalExecutions: number;\n successfulExecutions: number;\n failedExecutions: number;\n uniqueSkills: number;\n totalCommands: number;\n totalNetworkCalls: number;\n blockedCommands: number;\n blockedNetworkCalls: number;\n}> {\n const logs = await getRecentAuditLogs(1000); // Last 1000 executions\n \n const skills = new Set<string>();\n let totalCommands = 0;\n let totalNetworkCalls = 0;\n let blockedCommands = 0;\n let blockedNetworkCalls = 0;\n \n for (const log of logs) {\n skills.add(log.skillName);\n totalCommands += log.commands?.length ?? 0;\n totalNetworkCalls += log.networkCalls?.length ?? 0;\n blockedCommands += log.commands?.filter(c => c.blockedBy).length ?? 0;\n blockedNetworkCalls += log.networkCalls?.filter(c => c.blocked).length ?? 0;\n }\n \n return {\n totalExecutions: logs.length,\n successfulExecutions: logs.filter(l => l.success).length,\n failedExecutions: logs.filter(l => !l.success).length,\n uniqueSkills: skills.size,\n totalCommands,\n totalNetworkCalls,\n blockedCommands,\n blockedNetworkCalls,\n };\n}\n\n/**\n * Format audit log for display\n */\nexport function formatAuditLog(log: SkillExecution): string {\n const lines: string[] = [];\n \n const status = log.success ? '✅' : '❌';\n const duration = log.duration ? `${log.duration}ms` : 'unknown';\n \n lines.push(`${status} ${log.skillName} (${duration})`);\n lines.push(` Time: ${new Date(log.timestamp).toLocaleString()}`);\n lines.push(` Triggered by: ${log.triggeredBy}`);\n lines.push(` Target: ${log.targetPath}`);\n \n if (log.commands && log.commands.length > 0) {\n lines.push(` Commands executed: ${log.commands.length}`);\n const blocked = log.commands.filter(c => c.blockedBy).length;\n if (blocked > 0) {\n lines.push(` ⚠️ Commands blocked: ${blocked}`);\n }\n }\n \n if (log.networkCalls && log.networkCalls.length > 0) {\n lines.push(` Network calls: ${log.networkCalls.length}`);\n const blocked = log.networkCalls.filter(c => c.blocked).length;\n if (blocked > 0) {\n lines.push(` ⚠️ Network calls blocked: ${blocked}`);\n }\n }\n \n if (log.error) {\n lines.push(` Error: ${log.error}`);\n }\n \n return lines.join('\\n');\n}\n"],"mappings":";;;;;;AASA,SAAS,MAAM,UAAU,gBAAoC;AAC7D,SAAS,iBAAiB;;;ACJ1B,SAAS,WAAW,OAAO,SAAS,gBAAgB;AACpD,SAAS,YAAY;AA+CrB,eAAsB,kBAAkB,WAA0C;AAChF,QAAM,UAAU,oBAAoB,QAAW,IAAI;AACnD,QAAM,WAAW,KAAK,iBAAiB,OAAO,GAAG,OAAO;AAExD,QAAM,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAGzC,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,SAAS,GAAG;AAC/D,QAAM,gBAAgB,UAAU,UAAU,QAAQ,gBAAgB,GAAG;AACrE,QAAM,WAAW,GAAG,SAAS,IAAI,aAAa;AAC9C,QAAM,WAAW,KAAK,UAAU,QAAQ;AAGxC,MAAI,CAAC,UAAU,SAAS;AACtB,cAAU,UAAU,KAAK,IAAI;AAAA,EAC/B;AAGA,MAAI,CAAC,UAAU,UAAU;AACvB,cAAU,WAAW,UAAU,UAAU,UAAU;AAAA,EACrD;AAEA,QAAM,UAAU,UAAU,KAAK,UAAU,WAAW,MAAM,CAAC,GAAG,OAAO;AACvE;AAKO,SAAS,iBACd,WACA,aACA,aACA,YACgB;AAChB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,WAAW,KAAK,IAAI;AAAA,IACpB,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,UAAU,CAAC;AAAA,IACX,cAAc,CAAC;AAAA,IACf,eAAe,CAAC;AAAA,IAChB,eAAe,CAAC;AAAA,EAClB;AACF;AAKO,SAAS,mBACd,OACA,SACA,OACgB;AAChB,QAAM,OAAuB;AAAA,IAC3B,GAAG;AAAA,IACH;AAAA,IACA,SAAS,KAAK,IAAI;AAAA,IAClB,UAAU,KAAK,IAAI,IAAI,MAAM;AAAA,EAC/B;AACA,SAAO,QAAQ,EAAE,GAAG,MAAM,MAAM,IAAI;AACtC;AAKA,eAAsB,mBAAmB,QAAgB,IAA+B;AACtF,QAAM,UAAU,oBAAoB,QAAW,IAAI;AACnD,QAAM,WAAW,KAAK,iBAAiB,OAAO,GAAG,OAAO;AAExD,MAAI;AACF,UAAM,QAAQ,MAAM,QAAQ,QAAQ;AAGpC,UAAM,SAAS,MACZ,OAAO,OAAK,EAAE,SAAS,OAAO,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,MAAM,GAAG,KAAK;AAEjB,UAAM,OAAyB,CAAC;AAEhC,eAAW,QAAQ,QAAQ;AACzB,UAAI;AACF,cAAM,UAAU,MAAM,SAAS,KAAK,UAAU,IAAI,GAAG,OAAO;AAC5D,aAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAAA,MAC/B,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO,CAAC;AAAA,EACV;AACF;AAKA,eAAsB,kBAAkB,WAA8C;AACpF,QAAM,UAAU,oBAAoB,QAAW,IAAI;AACnD,QAAM,WAAW,KAAK,iBAAiB,OAAO,GAAG,OAAO;AACxD,QAAM,gBAAgB,UAAU,QAAQ,gBAAgB,GAAG;AAE3D,MAAI;AACF,UAAM,QAAQ,MAAM,QAAQ,QAAQ;AAEpC,UAAM,aAAa,MAAM;AAAA,MAAO,OAC9B,EAAE,SAAS,IAAI,aAAa,OAAO;AAAA,IACrC;AAEA,UAAM,OAAyB,CAAC;AAEhC,eAAW,QAAQ,YAAY;AAC7B,UAAI;AACF,cAAM,UAAU,MAAM,SAAS,KAAK,UAAU,IAAI,GAAG,OAAO;AAC5D,aAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAAA,MAC/B,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,MAAK,CAAC,GAAG,MACnB,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ;AAAA,IAClE;AAAA,EACF,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAKA,eAAsB,qBASnB;AACD,QAAM,OAAO,MAAM,mBAAmB,GAAI;AAE1C,QAAM,SAAS,oBAAI,IAAY;AAC/B,MAAI,gBAAgB;AACpB,MAAI,oBAAoB;AACxB,MAAI,kBAAkB;AACtB,MAAI,sBAAsB;AAE1B,aAAW,OAAO,MAAM;AACtB,WAAO,IAAI,IAAI,SAAS;AACxB,qBAAiB,IAAI,UAAU,UAAU;AACzC,yBAAqB,IAAI,cAAc,UAAU;AACjD,uBAAmB,IAAI,UAAU,OAAO,OAAK,EAAE,SAAS,EAAE,UAAU;AACpE,2BAAuB,IAAI,cAAc,OAAO,OAAK,EAAE,OAAO,EAAE,UAAU;AAAA,EAC5E;AAEA,SAAO;AAAA,IACL,iBAAiB,KAAK;AAAA,IACtB,sBAAsB,KAAK,OAAO,OAAK,EAAE,OAAO,EAAE;AAAA,IAClD,kBAAkB,KAAK,OAAO,OAAK,CAAC,EAAE,OAAO,EAAE;AAAA,IAC/C,cAAc,OAAO;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,eAAe,KAA6B;AAC1D,QAAM,QAAkB,CAAC;AAEzB,QAAM,SAAS,IAAI,UAAU,WAAM;AACnC,QAAM,WAAW,IAAI,WAAW,GAAG,IAAI,QAAQ,OAAO;AAEtD,QAAM,KAAK,GAAG,MAAM,IAAI,IAAI,SAAS,KAAK,QAAQ,GAAG;AACrD,QAAM,KAAK,YAAY,IAAI,KAAK,IAAI,SAAS,EAAE,eAAe,CAAC,EAAE;AACjE,QAAM,KAAK,oBAAoB,IAAI,WAAW,EAAE;AAChD,QAAM,KAAK,cAAc,IAAI,UAAU,EAAE;AAEzC,MAAI,IAAI,YAAY,IAAI,SAAS,SAAS,GAAG;AAC3C,UAAM,KAAK,yBAAyB,IAAI,SAAS,MAAM,EAAE;AACzD,UAAM,UAAU,IAAI,SAAS,OAAO,OAAK,EAAE,SAAS,EAAE;AACtD,QAAI,UAAU,GAAG;AACf,YAAM,KAAK,sCAA4B,OAAO,EAAE;AAAA,IAClD;AAAA,EACF;AAEA,MAAI,IAAI,gBAAgB,IAAI,aAAa,SAAS,GAAG;AACnD,UAAM,KAAK,qBAAqB,IAAI,aAAa,MAAM,EAAE;AACzD,UAAM,UAAU,IAAI,aAAa,OAAO,OAAK,EAAE,OAAO,EAAE;AACxD,QAAI,UAAU,GAAG;AACf,YAAM,KAAK,2CAAiC,OAAO,EAAE;AAAA,IACvD;AAAA,EACF;AAEA,MAAI,IAAI,OAAO;AACb,UAAM,KAAK,aAAa,IAAI,KAAK,EAAE;AAAA,EACrC;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ADrPA,IAAM,YAAY,UAAU,IAAI;AAChC,IAAM,gBAAgB,UAAU,QAAQ;AA4BxC,SAAS,OAAO,MAAsB;AAEpC,SAAO,KAEJ,QAAQ,kEAAkE,0BAA0B,EAEpG,QAAQ,uCAAuC,mBAAmB,EAElE,QAAQ,6BAA6B,gBAAgB,EACrD,QAAQ,yCAAyC,wBAAwB,EAEzE,QAAQ,yBAAyB,gBAAgB;AACtD;AAEA,SAAS,YAAY,MAAc,UAA0B;AAC3D,MAAI,KAAK,UAAU,SAAU,QAAO;AACpC,SAAO,KAAK,MAAM,GAAG,QAAQ,IAAI;AAAA,mBAAiB,KAAK,SAAS,QAAQ;AAC1E;AAEA,SAAS,mBAAmB,SAAkC;AAC5D,SAAO;AAAA,IACL;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACF;AAEA,eAAe,iBACb,OACA,KACA,SACA,SACe;AACf,QAAM,WAAW,KAAK,IAAI,IAAI,QAAQ;AACtC,MAAI,WAAW;AACf,MAAI,QAAQ,aAAa,QAAW;AAClC,QAAI,WAAW,QAAQ;AAAA,EACzB;AAEA,QAAM,gBAAgB,SAAS,iBAAiB;AAChD,QAAM,eAAe,SAAS,gBAAgB;AAC9C,QAAM,iBAAiB,SAAS,kBAAkB;AAElD,MAAI,eAAe;AACjB,UAAM,MAAM,QAAQ,UAAU;AAC9B,UAAM,MAAM,QAAQ,UAAU;AAC9B,QAAI,SAAS,eAAe,OAAO,YAAY,KAAK,cAAc,CAAC,IAAI,YAAY,KAAK,cAAc;AACtG,QAAI,SAAS,eAAe,OAAO,YAAY,KAAK,cAAc,CAAC,IAAI,YAAY,KAAK,cAAc;AAAA,EACxG;AAEA,QAAM,YAAY,mBAAmB,OAAO,QAAQ,SAAS,QAAQ,KAAK;AAC1E,QAAM,kBAAkB,SAAS;AACnC;AAEA,eAAsB,gBACpB,SACA,OACA,SAC+D;AAC/D,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,QAAQ,iBAAiB,MAAM,OAAO,MAAM,UAAU,QAAQ,MAAM,aAAa,MAAM,UAAU;AACvG,QAAM,MAAM,mBAAmB,OAAO;AACtC,QAAM,UAAU,KAAK,GAAG;AAExB,MAAI;AACF,UAAM,EAAE,QAAQ,OAAO,IAAI,MAAM,UAAU,SAAS;AAAA,MAClD,KAAK,SAAS;AAAA,MACd,SAAS,SAAS;AAAA,MAClB,WAAW,SAAS;AAAA,IACtB,CAAC;AAED,UAAM,iBAAiB,OAAO,KAAK,EAAE,SAAS,MAAM,UAAU,GAAG,QAAQ,QAAQ,UAAU,GAAG,OAAO;AACrG,WAAO,EAAE,QAAQ,UAAU,IAAI,QAAQ,UAAU,IAAI,UAAU,EAAE;AAAA,EACnE,SAAS,GAAG;AACV,UAAM,MAAM;AACZ,UAAM,SAAS,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAC7D,UAAM,SAAS,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAC7D,UAAM,WAAW,OAAO,IAAI,SAAS,WAAW,IAAI,OAAO;AAE3D,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,EAAE,SAAS,OAAO,UAAU,QAAQ,QAAQ,OAAO,IAAI,SAAS,UAAU;AAAA;AAAA,MAE1E,EAAE,GAAG,SAAS,eAAe,SAAS,iBAAiB,KAAK;AAAA,IAC9D;AAEA,WAAO,EAAE,QAAQ,QAAQ,SAAS;AAAA,EACpC;AACF;AAEO,SAAS,oBACd,SACA,OACA,SACsC;AACtC,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,QAAQ,iBAAiB,MAAM,OAAO,MAAM,UAAU,QAAQ,MAAM,aAAa,MAAM,UAAU;AACvG,QAAM,MAAM,mBAAmB,OAAO;AACtC,QAAM,UAAU,KAAK,GAAG;AAExB,MAAI;AACF,UAAM,SAAS,SAAS,SAAS;AAAA,MAC/B,KAAK,SAAS;AAAA,MACd,SAAS,SAAS;AAAA,MAClB,WAAW,SAAS;AAAA,MACpB,UAAU;AAAA,MACV,OAAO,CAAC,QAAQ,QAAQ,MAAM;AAAA,IAChC,CAAC;AAGD,SAAK,iBAAiB,OAAO,KAAK,EAAE,SAAS,MAAM,UAAU,GAAG,QAAQ,QAAQ,IAAI,UAAU,GAAG,OAAO;AACxG,WAAO,EAAE,QAAQ,UAAU,IAAI,UAAU,EAAE;AAAA,EAC7C,SAAS,GAAG;AACV,UAAM,MAAM;AACZ,UAAM,SAAS,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAC7D,UAAM,SAAS,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAC7D,UAAM,WAAW,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAE/D,SAAK;AAAA,MACH;AAAA,MACA;AAAA,MACA,EAAE,SAAS,OAAO,UAAU,QAAQ,QAAQ,OAAO,IAAI,SAAS,UAAU;AAAA,MAC1E,EAAE,GAAG,SAAS,eAAe,SAAS,iBAAiB,KAAK;AAAA,IAC9D;AAEA,WAAO,EAAE,QAAQ,SAAS;AAAA,EAC5B;AACF;AAEA,eAAsB,YACpB,MACA,MACA,OACA,SAC+D;AAC/D,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,UAAU,CAAC,MAAM,GAAG,IAAI,EAAE,KAAK,GAAG;AACxC,QAAM,QAAQ,iBAAiB,MAAM,OAAO,MAAM,UAAU,QAAQ,MAAM,aAAa,MAAM,UAAU;AACvG,QAAM,MAAM,mBAAmB,OAAO;AACtC,QAAM,UAAU,KAAK,GAAG;AAExB,MAAI;AACF,UAAM,EAAE,QAAQ,OAAO,IAAI,MAAM,cAAc,MAAM,MAAM;AAAA,MACzD,KAAK,SAAS;AAAA,MACd,SAAS,SAAS;AAAA,MAClB,WAAW,SAAS;AAAA,IACtB,CAAC;AAED,UAAM,iBAAiB,OAAO,KAAK,EAAE,SAAS,MAAM,UAAU,GAAG,QAAQ,OAAO,UAAU,EAAE,GAAG,QAAQ,OAAO,UAAU,EAAE,GAAG,UAAU,GAAG,OAAO;AACjJ,WAAO,EAAE,QAAQ,OAAO,UAAU,EAAE,GAAG,QAAQ,OAAO,UAAU,EAAE,GAAG,UAAU,EAAE;AAAA,EACnF,SAAS,GAAG;AACV,UAAM,MAAM;AACZ,UAAM,SAAS,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAC7D,UAAM,SAAS,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAC7D,UAAM,WAAW,OAAO,IAAI,SAAS,WAAW,IAAI,OAAO;AAE3D,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,EAAE,SAAS,OAAO,UAAU,QAAQ,QAAQ,OAAO,IAAI,SAAS,UAAU;AAAA,MAC1E,EAAE,GAAG,SAAS,eAAe,SAAS,iBAAiB,KAAK;AAAA,IAC9D;AACA,WAAO,EAAE,QAAQ,QAAQ,SAAS;AAAA,EACpC;AACF;","names":[]}
|