kirograph 0.13.0 → 0.14.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/README.md +332 -93
- package/dist/bin/commands/caveman.js +19 -2
- package/dist/bin/commands/caveman.js.map +2 -2
- package/dist/bin/commands/compression.js +109 -0
- package/dist/bin/commands/compression.js.map +7 -0
- package/dist/bin/commands/context.js +31 -24
- package/dist/bin/commands/context.js.map +2 -2
- package/dist/bin/commands/exec.js +107 -0
- package/dist/bin/commands/exec.js.map +7 -0
- package/dist/bin/commands/gain.js +119 -0
- package/dist/bin/commands/gain.js.map +7 -0
- package/dist/bin/commands/help.js +16 -5
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/install.js +8 -2
- package/dist/bin/commands/install.js.map +2 -2
- package/dist/bin/commands/query.js +5 -1
- package/dist/bin/commands/query.js.map +2 -2
- package/dist/bin/commands/serve.js +2 -2
- package/dist/bin/commands/serve.js.map +2 -2
- package/dist/bin/commands/uninit.js +65 -41
- package/dist/bin/commands/uninit.js.map +2 -2
- package/dist/bin/commands/utils.js +16 -0
- package/dist/bin/commands/utils.js.map +2 -2
- package/dist/bin/installer/cli-agent.js +5 -25
- package/dist/bin/installer/cli-agent.js.map +2 -2
- package/dist/bin/installer/common.js +154 -0
- package/dist/bin/installer/common.js.map +7 -0
- package/dist/bin/installer/config-prompt.js +9 -2
- package/dist/bin/installer/config-prompt.js.map +2 -2
- package/dist/bin/installer/hooks.js +19 -1
- package/dist/bin/installer/hooks.js.map +2 -2
- package/dist/bin/installer/index.js +104 -86
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/installer/instructions.js +60 -0
- package/dist/bin/installer/instructions.js.map +7 -0
- package/dist/bin/installer/mcp.js +6 -36
- package/dist/bin/installer/mcp.js.map +2 -2
- package/dist/bin/installer/steering.js +116 -40
- package/dist/bin/installer/steering.js.map +2 -2
- package/dist/bin/installer/targets/claude.js +79 -0
- package/dist/bin/installer/targets/claude.js.map +7 -0
- package/dist/bin/installer/targets/codex.js +77 -0
- package/dist/bin/installer/targets/codex.js.map +7 -0
- package/dist/bin/installer/targets/index.js +57 -0
- package/dist/bin/installer/targets/index.js.map +7 -0
- package/dist/bin/installer/targets/kiro.js +63 -0
- package/dist/bin/installer/targets/kiro.js.map +7 -0
- package/dist/bin/kirograph.js +7 -1
- package/dist/bin/kirograph.js.map +3 -3
- package/dist/compression/filters/aws.js +418 -0
- package/dist/compression/filters/aws.js.map +7 -0
- package/dist/compression/filters/docker.js +153 -0
- package/dist/compression/filters/docker.js.map +7 -0
- package/dist/compression/filters/files.js +150 -0
- package/dist/compression/filters/files.js.map +7 -0
- package/dist/compression/filters/generic.js +86 -0
- package/dist/compression/filters/generic.js.map +7 -0
- package/dist/compression/filters/git.js +272 -0
- package/dist/compression/filters/git.js.map +7 -0
- package/dist/compression/filters/github.js +137 -0
- package/dist/compression/filters/github.js.map +7 -0
- package/dist/compression/filters/lint.js +280 -0
- package/dist/compression/filters/lint.js.map +7 -0
- package/dist/compression/filters/misc.js +212 -0
- package/dist/compression/filters/misc.js.map +7 -0
- package/dist/compression/filters/package.js +151 -0
- package/dist/compression/filters/package.js.map +7 -0
- package/dist/compression/filters/test.js +266 -0
- package/dist/compression/filters/test.js.map +7 -0
- package/dist/compression/index.js +144 -0
- package/dist/compression/index.js.map +7 -0
- package/dist/compression/naive-cost.js +94 -0
- package/dist/compression/naive-cost.js.map +7 -0
- package/dist/compression/tracker.js +228 -0
- package/dist/compression/tracker.js.map +7 -0
- package/dist/compression/types.js +17 -0
- package/dist/compression/types.js.map +7 -0
- package/dist/config.js +18 -1
- package/dist/config.js.map +2 -2
- package/dist/mcp/tool-names.js +50 -0
- package/dist/mcp/tool-names.js.map +7 -0
- package/dist/mcp/tools.js +173 -4
- package/dist/mcp/tools.js.map +3 -3
- package/package.json +2 -2
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var aws_exports = {};
|
|
20
|
+
__export(aws_exports, {
|
|
21
|
+
awsFilter: () => awsFilter
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(aws_exports);
|
|
24
|
+
const awsFilter = {
|
|
25
|
+
name: "aws",
|
|
26
|
+
matches(command) {
|
|
27
|
+
return /\baws\s/.test(command);
|
|
28
|
+
},
|
|
29
|
+
filter(command, rawOutput, level) {
|
|
30
|
+
const subcommand = extractAwsSubcommand(command);
|
|
31
|
+
switch (subcommand) {
|
|
32
|
+
case "sts:get-caller-identity":
|
|
33
|
+
return filterStsIdentity(rawOutput, level);
|
|
34
|
+
case "ec2:describe-instances":
|
|
35
|
+
return filterEc2Instances(rawOutput, level);
|
|
36
|
+
case "lambda:list-functions":
|
|
37
|
+
return filterLambdaFunctions(rawOutput, level);
|
|
38
|
+
case "logs:get-log-events":
|
|
39
|
+
return filterLogEvents(rawOutput, level);
|
|
40
|
+
case "cloudformation:describe-stack-events":
|
|
41
|
+
return filterCfnEvents(rawOutput, level);
|
|
42
|
+
case "dynamodb:scan":
|
|
43
|
+
case "dynamodb:query":
|
|
44
|
+
case "dynamodb:get-item":
|
|
45
|
+
return filterDynamoDB(rawOutput, level);
|
|
46
|
+
case "iam:list-roles":
|
|
47
|
+
return filterIamRoles(rawOutput, level);
|
|
48
|
+
case "iam:list-policies":
|
|
49
|
+
return filterIamPolicies(rawOutput, level);
|
|
50
|
+
case "s3:ls":
|
|
51
|
+
return filterS3Ls(rawOutput, level);
|
|
52
|
+
case "s3:cp":
|
|
53
|
+
case "s3:sync":
|
|
54
|
+
return filterS3Transfer(rawOutput, level);
|
|
55
|
+
case "ecs:list-tasks":
|
|
56
|
+
case "ecs:describe-tasks":
|
|
57
|
+
return filterEcsTasks(rawOutput, level);
|
|
58
|
+
case "ecs:describe-services":
|
|
59
|
+
return filterEcsServices(rawOutput, level);
|
|
60
|
+
case "sqs:list-queues":
|
|
61
|
+
return filterSqsQueues(rawOutput, level);
|
|
62
|
+
case "sns:list-topics":
|
|
63
|
+
return filterSnsTopics(rawOutput, level);
|
|
64
|
+
default:
|
|
65
|
+
return filterGenericAws(rawOutput, level);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
function extractAwsSubcommand(command) {
|
|
70
|
+
const match = command.match(/aws\s+(\S+)\s+(\S+)/);
|
|
71
|
+
if (match) return `${match[1]}:${match[2]}`;
|
|
72
|
+
const serviceOnly = command.match(/aws\s+(\S+)/);
|
|
73
|
+
if (serviceOnly) return serviceOnly[1];
|
|
74
|
+
return "";
|
|
75
|
+
}
|
|
76
|
+
function filterStsIdentity(raw, level) {
|
|
77
|
+
try {
|
|
78
|
+
const data = JSON.parse(raw);
|
|
79
|
+
if (level === "ultra") {
|
|
80
|
+
return { output: `${data.Account} ${data.Arn?.split("/").pop() || ""}`, strategy: "aws:sts:ultra" };
|
|
81
|
+
}
|
|
82
|
+
return { output: `Account: ${data.Account}
|
|
83
|
+
Arn: ${data.Arn}
|
|
84
|
+
UserId: ${data.UserId}`, strategy: "aws:sts" };
|
|
85
|
+
} catch {
|
|
86
|
+
return { output: raw, strategy: "aws:sts:passthrough" };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function filterEc2Instances(raw, level) {
|
|
90
|
+
try {
|
|
91
|
+
const data = JSON.parse(raw);
|
|
92
|
+
const instances = [];
|
|
93
|
+
for (const reservation of data.Reservations || []) {
|
|
94
|
+
for (const inst of reservation.Instances || []) {
|
|
95
|
+
const name = inst.Tags?.find((t) => t.Key === "Name")?.Value || "";
|
|
96
|
+
const id = inst.InstanceId || "";
|
|
97
|
+
const state = inst.State?.Name || "";
|
|
98
|
+
const type = inst.InstanceType || "";
|
|
99
|
+
const ip = inst.PrivateIpAddress || "";
|
|
100
|
+
if (level === "ultra") {
|
|
101
|
+
instances.push(`${id} ${state} ${type}${name ? " " + name : ""}`);
|
|
102
|
+
} else {
|
|
103
|
+
instances.push(`${id} ${state.padEnd(10)} ${type.padEnd(12)} ${ip.padEnd(15)} ${name}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (instances.length === 0) return { output: "no instances", strategy: "aws:ec2:empty" };
|
|
108
|
+
if (level === "ultra") {
|
|
109
|
+
return { output: instances.join("\n"), strategy: "aws:ec2:ultra" };
|
|
110
|
+
}
|
|
111
|
+
const header = `${instances.length} instance(s):`;
|
|
112
|
+
return { output: `${header}
|
|
113
|
+
${instances.join("\n")}`, strategy: "aws:ec2" };
|
|
114
|
+
} catch {
|
|
115
|
+
return filterGenericAws(raw, level);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function filterLambdaFunctions(raw, level) {
|
|
119
|
+
try {
|
|
120
|
+
const data = JSON.parse(raw);
|
|
121
|
+
const functions = data.Functions || [];
|
|
122
|
+
if (functions.length === 0) return { output: "no functions", strategy: "aws:lambda:empty" };
|
|
123
|
+
const lines = functions.map((fn) => {
|
|
124
|
+
const name = fn.FunctionName || "";
|
|
125
|
+
const runtime = fn.Runtime || "";
|
|
126
|
+
const memory = fn.MemorySize || "";
|
|
127
|
+
const timeout = fn.Timeout || "";
|
|
128
|
+
if (level === "ultra") {
|
|
129
|
+
return `${name} ${runtime} ${memory}MB`;
|
|
130
|
+
}
|
|
131
|
+
return `${name.padEnd(40)} ${runtime.padEnd(14)} ${String(memory).padStart(4)}MB ${String(timeout).padStart(3)}s`;
|
|
132
|
+
});
|
|
133
|
+
if (level === "ultra") {
|
|
134
|
+
return { output: `${functions.length} functions:
|
|
135
|
+
${lines.join("\n")}`, strategy: "aws:lambda:ultra" };
|
|
136
|
+
}
|
|
137
|
+
return { output: `${functions.length} function(s):
|
|
138
|
+
${lines.join("\n")}`, strategy: "aws:lambda" };
|
|
139
|
+
} catch {
|
|
140
|
+
return filterGenericAws(raw, level);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function filterLogEvents(raw, level) {
|
|
144
|
+
try {
|
|
145
|
+
const data = JSON.parse(raw);
|
|
146
|
+
const events = data.events || [];
|
|
147
|
+
if (events.length === 0) return { output: "no events", strategy: "aws:logs:empty" };
|
|
148
|
+
const lines = events.map((e) => {
|
|
149
|
+
const ts = new Date(e.timestamp).toISOString().slice(11, 23);
|
|
150
|
+
const msg = (e.message || "").trim();
|
|
151
|
+
return `${ts} ${msg}`;
|
|
152
|
+
});
|
|
153
|
+
const deduped = [];
|
|
154
|
+
let lastPattern = "";
|
|
155
|
+
let repeatCount = 0;
|
|
156
|
+
for (const line of lines) {
|
|
157
|
+
const pattern = line.replace(/\d+/g, "N");
|
|
158
|
+
if (pattern === lastPattern) {
|
|
159
|
+
repeatCount++;
|
|
160
|
+
} else {
|
|
161
|
+
if (repeatCount > 1) deduped.push(` \u2026repeated ${repeatCount}x`);
|
|
162
|
+
deduped.push(line);
|
|
163
|
+
lastPattern = pattern;
|
|
164
|
+
repeatCount = 1;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (repeatCount > 1) deduped.push(` \u2026repeated ${repeatCount}x`);
|
|
168
|
+
const maxLines = level === "ultra" ? 20 : level === "aggressive" ? 40 : 60;
|
|
169
|
+
const shown = deduped.slice(-maxLines);
|
|
170
|
+
const omitted = deduped.length > maxLines ? `\u2026(${deduped.length - maxLines} earlier events omitted)
|
|
171
|
+
` : "";
|
|
172
|
+
return { output: `${omitted}${shown.join("\n")}`, strategy: "aws:logs" };
|
|
173
|
+
} catch {
|
|
174
|
+
return filterGenericAws(raw, level);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function filterCfnEvents(raw, level) {
|
|
178
|
+
try {
|
|
179
|
+
const data = JSON.parse(raw);
|
|
180
|
+
const events = data.StackEvents || [];
|
|
181
|
+
if (events.length === 0) return { output: "no events", strategy: "aws:cfn:empty" };
|
|
182
|
+
const sorted = [...events].sort((a, b) => {
|
|
183
|
+
const aFailed = (a.ResourceStatus || "").includes("FAILED") ? 0 : 1;
|
|
184
|
+
const bFailed = (b.ResourceStatus || "").includes("FAILED") ? 0 : 1;
|
|
185
|
+
if (aFailed !== bFailed) return aFailed - bFailed;
|
|
186
|
+
return new Date(b.Timestamp).getTime() - new Date(a.Timestamp).getTime();
|
|
187
|
+
});
|
|
188
|
+
const lines = sorted.map((e) => {
|
|
189
|
+
const status = e.ResourceStatus || "";
|
|
190
|
+
const logical = e.LogicalResourceId || "";
|
|
191
|
+
const reason = e.ResourceStatusReason || "";
|
|
192
|
+
const isFailed = status.includes("FAILED");
|
|
193
|
+
if (level === "ultra") {
|
|
194
|
+
return `${isFailed ? "\u2717" : "\xB7"} ${logical} ${status}${reason ? ": " + reason.slice(0, 60) : ""}`;
|
|
195
|
+
}
|
|
196
|
+
return `${status.padEnd(28)} ${logical}${reason ? "\n \u2192 " + reason : ""}`;
|
|
197
|
+
});
|
|
198
|
+
const maxLines = level === "ultra" ? 15 : level === "aggressive" ? 25 : 40;
|
|
199
|
+
const shown = lines.slice(0, maxLines).join("\n");
|
|
200
|
+
const extra = lines.length > maxLines ? `
|
|
201
|
+
\u2026+${lines.length - maxLines} more events` : "";
|
|
202
|
+
const failures = events.filter((e) => (e.ResourceStatus || "").includes("FAILED")).length;
|
|
203
|
+
const header = failures > 0 ? `${failures} FAILED, ${events.length} total events:` : `${events.length} events:`;
|
|
204
|
+
return { output: `${header}
|
|
205
|
+
${shown}${extra}`, strategy: "aws:cfn" };
|
|
206
|
+
} catch {
|
|
207
|
+
return filterGenericAws(raw, level);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function filterDynamoDB(raw, level) {
|
|
211
|
+
try {
|
|
212
|
+
const data = JSON.parse(raw);
|
|
213
|
+
const unwrapped = unwrapDynamoTypes(data);
|
|
214
|
+
const output = JSON.stringify(unwrapped, null, level === "ultra" ? 0 : 2);
|
|
215
|
+
return { output, strategy: "aws:dynamodb" };
|
|
216
|
+
} catch {
|
|
217
|
+
return filterGenericAws(raw, level);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function unwrapDynamoTypes(obj) {
|
|
221
|
+
if (obj === null || obj === void 0) return obj;
|
|
222
|
+
if (Array.isArray(obj)) return obj.map(unwrapDynamoTypes);
|
|
223
|
+
if (typeof obj !== "object") return obj;
|
|
224
|
+
const keys = Object.keys(obj);
|
|
225
|
+
if (keys.length === 1) {
|
|
226
|
+
const key = keys[0];
|
|
227
|
+
if (key === "S") return obj.S;
|
|
228
|
+
if (key === "N") return Number(obj.N);
|
|
229
|
+
if (key === "BOOL") return obj.BOOL;
|
|
230
|
+
if (key === "NULL") return null;
|
|
231
|
+
if (key === "L") return obj.L.map(unwrapDynamoTypes);
|
|
232
|
+
if (key === "M") return unwrapDynamoTypes(obj.M);
|
|
233
|
+
if (key === "SS") return obj.SS;
|
|
234
|
+
if (key === "NS") return obj.NS.map(Number);
|
|
235
|
+
if (key === "BS") return obj.BS;
|
|
236
|
+
}
|
|
237
|
+
const result = {};
|
|
238
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
239
|
+
result[k] = unwrapDynamoTypes(v);
|
|
240
|
+
}
|
|
241
|
+
return result;
|
|
242
|
+
}
|
|
243
|
+
function filterIamRoles(raw, level) {
|
|
244
|
+
try {
|
|
245
|
+
const data = JSON.parse(raw);
|
|
246
|
+
const roles = data.Roles || [];
|
|
247
|
+
if (roles.length === 0) return { output: "no roles", strategy: "aws:iam-roles:empty" };
|
|
248
|
+
const lines = roles.map((r) => {
|
|
249
|
+
const name = r.RoleName || "";
|
|
250
|
+
const path = r.Path || "/";
|
|
251
|
+
const created = r.CreateDate ? r.CreateDate.slice(0, 10) : "";
|
|
252
|
+
if (level === "ultra") return name;
|
|
253
|
+
return `${name.padEnd(40)} ${path.padEnd(10)} ${created}`;
|
|
254
|
+
});
|
|
255
|
+
const maxLines = level === "ultra" ? 30 : level === "aggressive" ? 40 : 60;
|
|
256
|
+
const shown = lines.slice(0, maxLines).join("\n");
|
|
257
|
+
const extra = lines.length > maxLines ? `
|
|
258
|
+
\u2026+${lines.length - maxLines} more` : "";
|
|
259
|
+
return { output: `${roles.length} roles:
|
|
260
|
+
${shown}${extra}`, strategy: "aws:iam-roles" };
|
|
261
|
+
} catch {
|
|
262
|
+
return filterGenericAws(raw, level);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function filterIamPolicies(raw, level) {
|
|
266
|
+
try {
|
|
267
|
+
const data = JSON.parse(raw);
|
|
268
|
+
const policies = data.Policies || [];
|
|
269
|
+
if (policies.length === 0) return { output: "no policies", strategy: "aws:iam-policies:empty" };
|
|
270
|
+
const lines = policies.map((p) => {
|
|
271
|
+
if (level === "ultra") return p.PolicyName || "";
|
|
272
|
+
return `${(p.PolicyName || "").padEnd(40)} ${p.Arn || ""}`;
|
|
273
|
+
});
|
|
274
|
+
const maxLines = level === "ultra" ? 30 : 50;
|
|
275
|
+
const shown = lines.slice(0, maxLines).join("\n");
|
|
276
|
+
const extra = lines.length > maxLines ? `
|
|
277
|
+
\u2026+${lines.length - maxLines} more` : "";
|
|
278
|
+
return { output: `${policies.length} policies:
|
|
279
|
+
${shown}${extra}`, strategy: "aws:iam-policies" };
|
|
280
|
+
} catch {
|
|
281
|
+
return filterGenericAws(raw, level);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function filterS3Ls(raw, level) {
|
|
285
|
+
const lines = raw.split("\n").filter((l) => l.trim());
|
|
286
|
+
if (lines.length === 0) return { output: "empty", strategy: "aws:s3-ls:empty" };
|
|
287
|
+
if (lines.length <= 20) return { output: raw, strategy: "aws:s3-ls:short" };
|
|
288
|
+
if (level === "ultra") {
|
|
289
|
+
return { output: `${lines.length} objects`, strategy: "aws:s3-ls:ultra" };
|
|
290
|
+
}
|
|
291
|
+
const maxLines = level === "aggressive" ? 30 : 50;
|
|
292
|
+
const shown = lines.slice(0, maxLines).join("\n");
|
|
293
|
+
const extra = lines.length > maxLines ? `
|
|
294
|
+
\u2026+${lines.length - maxLines} more objects` : "";
|
|
295
|
+
return { output: `${shown}${extra}`, strategy: "aws:s3-ls" };
|
|
296
|
+
}
|
|
297
|
+
function filterS3Transfer(raw, level) {
|
|
298
|
+
const lines = raw.split("\n").filter((l) => l.trim());
|
|
299
|
+
const meaningful = lines.filter((l) => !l.includes("Completed") && !l.includes("upload:") || l.includes("upload: s3://"));
|
|
300
|
+
if (meaningful.length === 0) return { output: "ok", strategy: "aws:s3-transfer" };
|
|
301
|
+
if (level === "ultra") {
|
|
302
|
+
const count = lines.filter((l) => l.includes("upload:") || l.includes("copy:")).length;
|
|
303
|
+
return { output: `ok ${count} objects`, strategy: "aws:s3-transfer:ultra" };
|
|
304
|
+
}
|
|
305
|
+
return { output: meaningful.slice(0, 20).join("\n"), strategy: "aws:s3-transfer" };
|
|
306
|
+
}
|
|
307
|
+
function filterEcsTasks(raw, level) {
|
|
308
|
+
try {
|
|
309
|
+
const data = JSON.parse(raw);
|
|
310
|
+
const tasks = data.tasks || data.taskArns || [];
|
|
311
|
+
if (tasks.length === 0) return { output: "no tasks", strategy: "aws:ecs-tasks:empty" };
|
|
312
|
+
if (Array.isArray(tasks) && typeof tasks[0] === "string") {
|
|
313
|
+
const short = tasks.map((arn) => arn.split("/").pop());
|
|
314
|
+
return { output: `${tasks.length} tasks:
|
|
315
|
+
${short.join("\n")}`, strategy: "aws:ecs-tasks" };
|
|
316
|
+
}
|
|
317
|
+
const lines = tasks.map((t) => {
|
|
318
|
+
const id = (t.taskArn || "").split("/").pop();
|
|
319
|
+
const status = t.lastStatus || "";
|
|
320
|
+
const group = t.group || "";
|
|
321
|
+
if (level === "ultra") return `${id} ${status}`;
|
|
322
|
+
return `${id} ${status.padEnd(10)} ${group}`;
|
|
323
|
+
});
|
|
324
|
+
return { output: `${tasks.length} tasks:
|
|
325
|
+
${lines.join("\n")}`, strategy: "aws:ecs-tasks" };
|
|
326
|
+
} catch {
|
|
327
|
+
return filterGenericAws(raw, level);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function filterEcsServices(raw, level) {
|
|
331
|
+
try {
|
|
332
|
+
const data = JSON.parse(raw);
|
|
333
|
+
const services = data.services || [];
|
|
334
|
+
if (services.length === 0) return { output: "no services", strategy: "aws:ecs-services:empty" };
|
|
335
|
+
const lines = services.map((s) => {
|
|
336
|
+
const name = s.serviceName || "";
|
|
337
|
+
const status = s.status || "";
|
|
338
|
+
const running = s.runningCount ?? 0;
|
|
339
|
+
const desired = s.desiredCount ?? 0;
|
|
340
|
+
if (level === "ultra") return `${name} ${running}/${desired}`;
|
|
341
|
+
return `${name.padEnd(30)} ${status.padEnd(8)} ${running}/${desired} tasks`;
|
|
342
|
+
});
|
|
343
|
+
return { output: `${services.length} services:
|
|
344
|
+
${lines.join("\n")}`, strategy: "aws:ecs-services" };
|
|
345
|
+
} catch {
|
|
346
|
+
return filterGenericAws(raw, level);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function filterSqsQueues(raw, level) {
|
|
350
|
+
try {
|
|
351
|
+
const data = JSON.parse(raw);
|
|
352
|
+
const urls = data.QueueUrls || [];
|
|
353
|
+
if (urls.length === 0) return { output: "no queues", strategy: "aws:sqs:empty" };
|
|
354
|
+
const names = urls.map((url) => url.split("/").pop());
|
|
355
|
+
if (level === "ultra") return { output: `${names.length} queues`, strategy: "aws:sqs:ultra" };
|
|
356
|
+
return { output: `${names.length} queues:
|
|
357
|
+
${names.join("\n")}`, strategy: "aws:sqs" };
|
|
358
|
+
} catch {
|
|
359
|
+
return filterGenericAws(raw, level);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function filterSnsTopics(raw, level) {
|
|
363
|
+
try {
|
|
364
|
+
const data = JSON.parse(raw);
|
|
365
|
+
const topics = data.Topics || [];
|
|
366
|
+
if (topics.length === 0) return { output: "no topics", strategy: "aws:sns:empty" };
|
|
367
|
+
const arns = topics.map((t) => (t.TopicArn || "").split(":").pop());
|
|
368
|
+
if (level === "ultra") return { output: `${arns.length} topics`, strategy: "aws:sns:ultra" };
|
|
369
|
+
return { output: `${arns.length} topics:
|
|
370
|
+
${arns.join("\n")}`, strategy: "aws:sns" };
|
|
371
|
+
} catch {
|
|
372
|
+
return filterGenericAws(raw, level);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
function filterGenericAws(raw, level) {
|
|
376
|
+
try {
|
|
377
|
+
const data = JSON.parse(raw);
|
|
378
|
+
const stripped = stripAwsVerboseFields(data);
|
|
379
|
+
const indent = level === "ultra" ? 0 : 2;
|
|
380
|
+
const output = JSON.stringify(stripped, null, indent);
|
|
381
|
+
const maxChars = level === "ultra" ? 2e3 : level === "aggressive" ? 5e3 : 1e4;
|
|
382
|
+
if (output.length > maxChars) {
|
|
383
|
+
return { output: output.slice(0, maxChars) + "\n\u2026(truncated)", strategy: "aws:generic:truncated" };
|
|
384
|
+
}
|
|
385
|
+
return { output, strategy: "aws:generic:json" };
|
|
386
|
+
} catch {
|
|
387
|
+
const lines = raw.split("\n");
|
|
388
|
+
const maxLines = level === "ultra" ? 20 : level === "aggressive" ? 40 : 60;
|
|
389
|
+
if (lines.length <= maxLines) return { output: raw, strategy: "aws:generic:text" };
|
|
390
|
+
const shown = lines.slice(0, maxLines).join("\n");
|
|
391
|
+
return { output: `${shown}
|
|
392
|
+
\u2026+${lines.length - maxLines} more lines`, strategy: "aws:generic:truncated" };
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
function stripAwsVerboseFields(obj) {
|
|
396
|
+
if (obj === null || obj === void 0) return obj;
|
|
397
|
+
if (Array.isArray(obj)) return obj.map(stripAwsVerboseFields);
|
|
398
|
+
if (typeof obj !== "object") return obj;
|
|
399
|
+
const STRIP_KEYS = /* @__PURE__ */ new Set([
|
|
400
|
+
"AssumeRolePolicyDocument",
|
|
401
|
+
"PolicyDocument",
|
|
402
|
+
"Document",
|
|
403
|
+
"ResponseMetadata",
|
|
404
|
+
"Marker",
|
|
405
|
+
"IsTruncated"
|
|
406
|
+
]);
|
|
407
|
+
const result = {};
|
|
408
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
409
|
+
if (STRIP_KEYS.has(k)) continue;
|
|
410
|
+
result[k] = stripAwsVerboseFields(v);
|
|
411
|
+
}
|
|
412
|
+
return result;
|
|
413
|
+
}
|
|
414
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
415
|
+
0 && (module.exports = {
|
|
416
|
+
awsFilter
|
|
417
|
+
});
|
|
418
|
+
//# sourceMappingURL=aws.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/compression/filters/aws.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * AWS CLI output filters\n *\n * Compresses verbose AWS CLI JSON output into compact, actionable summaries.\n * Strips policy documents, type annotations (DynamoDB), progress bars, and boilerplate.\n */\n\nimport type { CommandFilter, FilterResult, CompressorOptions } from '../types';\n\nexport const awsFilter: CommandFilter = {\n name: 'aws',\n\n matches(command: string): boolean {\n return /\\baws\\s/.test(command);\n },\n\n filter(command: string, rawOutput: string, level: CompressorOptions['level']): FilterResult {\n const subcommand = extractAwsSubcommand(command);\n\n switch (subcommand) {\n case 'sts:get-caller-identity': return filterStsIdentity(rawOutput, level);\n case 'ec2:describe-instances': return filterEc2Instances(rawOutput, level);\n case 'lambda:list-functions': return filterLambdaFunctions(rawOutput, level);\n case 'logs:get-log-events': return filterLogEvents(rawOutput, level);\n case 'cloudformation:describe-stack-events': return filterCfnEvents(rawOutput, level);\n case 'dynamodb:scan':\n case 'dynamodb:query':\n case 'dynamodb:get-item': return filterDynamoDB(rawOutput, level);\n case 'iam:list-roles': return filterIamRoles(rawOutput, level);\n case 'iam:list-policies': return filterIamPolicies(rawOutput, level);\n case 's3:ls': return filterS3Ls(rawOutput, level);\n case 's3:cp':\n case 's3:sync': return filterS3Transfer(rawOutput, level);\n case 'ecs:list-tasks':\n case 'ecs:describe-tasks': return filterEcsTasks(rawOutput, level);\n case 'ecs:describe-services': return filterEcsServices(rawOutput, level);\n case 'sqs:list-queues': return filterSqsQueues(rawOutput, level);\n case 'sns:list-topics': return filterSnsTopics(rawOutput, level);\n default: return filterGenericAws(rawOutput, level);\n }\n },\n};\n\nfunction extractAwsSubcommand(command: string): string {\n // \"aws sts get-caller-identity\" \u2192 \"sts:get-caller-identity\"\n const match = command.match(/aws\\s+(\\S+)\\s+(\\S+)/);\n if (match) return `${match[1]}:${match[2]}`;\n const serviceOnly = command.match(/aws\\s+(\\S+)/);\n if (serviceOnly) return serviceOnly[1];\n return '';\n}\n\n// \u2500\u2500 STS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterStsIdentity(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n if (level === 'ultra') {\n return { output: `${data.Account} ${data.Arn?.split('/').pop() || ''}`, strategy: 'aws:sts:ultra' };\n }\n return { output: `Account: ${data.Account}\\nArn: ${data.Arn}\\nUserId: ${data.UserId}`, strategy: 'aws:sts' };\n } catch {\n return { output: raw, strategy: 'aws:sts:passthrough' };\n }\n}\n\n// \u2500\u2500 EC2 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterEc2Instances(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n const instances: string[] = [];\n\n for (const reservation of data.Reservations || []) {\n for (const inst of reservation.Instances || []) {\n const name = inst.Tags?.find((t: any) => t.Key === 'Name')?.Value || '';\n const id = inst.InstanceId || '';\n const state = inst.State?.Name || '';\n const type = inst.InstanceType || '';\n const ip = inst.PrivateIpAddress || '';\n\n if (level === 'ultra') {\n instances.push(`${id} ${state} ${type}${name ? ' ' + name : ''}`);\n } else {\n instances.push(`${id} ${state.padEnd(10)} ${type.padEnd(12)} ${ip.padEnd(15)} ${name}`);\n }\n }\n }\n\n if (instances.length === 0) return { output: 'no instances', strategy: 'aws:ec2:empty' };\n\n if (level === 'ultra') {\n return { output: instances.join('\\n'), strategy: 'aws:ec2:ultra' };\n }\n\n const header = `${instances.length} instance(s):`;\n return { output: `${header}\\n${instances.join('\\n')}`, strategy: 'aws:ec2' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\n// \u2500\u2500 Lambda \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterLambdaFunctions(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n const functions = data.Functions || [];\n\n if (functions.length === 0) return { output: 'no functions', strategy: 'aws:lambda:empty' };\n\n const lines = functions.map((fn: any) => {\n const name = fn.FunctionName || '';\n const runtime = fn.Runtime || '';\n const memory = fn.MemorySize || '';\n const timeout = fn.Timeout || '';\n\n if (level === 'ultra') {\n return `${name} ${runtime} ${memory}MB`;\n }\n return `${name.padEnd(40)} ${runtime.padEnd(14)} ${String(memory).padStart(4)}MB ${String(timeout).padStart(3)}s`;\n });\n\n if (level === 'ultra') {\n return { output: `${functions.length} functions:\\n${lines.join('\\n')}`, strategy: 'aws:lambda:ultra' };\n }\n\n return { output: `${functions.length} function(s):\\n${lines.join('\\n')}`, strategy: 'aws:lambda' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\n// \u2500\u2500 CloudWatch Logs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterLogEvents(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n const events = data.events || [];\n\n if (events.length === 0) return { output: 'no events', strategy: 'aws:logs:empty' };\n\n const lines = events.map((e: any) => {\n const ts = new Date(e.timestamp).toISOString().slice(11, 23);\n const msg = (e.message || '').trim();\n return `${ts} ${msg}`;\n });\n\n // Deduplicate similar consecutive messages\n const deduped: string[] = [];\n let lastPattern = '';\n let repeatCount = 0;\n\n for (const line of lines) {\n const pattern = line.replace(/\\d+/g, 'N');\n if (pattern === lastPattern) {\n repeatCount++;\n } else {\n if (repeatCount > 1) deduped.push(` \u2026repeated ${repeatCount}x`);\n deduped.push(line);\n lastPattern = pattern;\n repeatCount = 1;\n }\n }\n if (repeatCount > 1) deduped.push(` \u2026repeated ${repeatCount}x`);\n\n const maxLines = level === 'ultra' ? 20 : level === 'aggressive' ? 40 : 60;\n const shown = deduped.slice(-maxLines); // Keep tail (most recent)\n const omitted = deduped.length > maxLines ? `\u2026(${deduped.length - maxLines} earlier events omitted)\\n` : '';\n\n return { output: `${omitted}${shown.join('\\n')}`, strategy: 'aws:logs' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\n// \u2500\u2500 CloudFormation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterCfnEvents(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n const events = data.StackEvents || [];\n\n if (events.length === 0) return { output: 'no events', strategy: 'aws:cfn:empty' };\n\n // Sort: failures first, then by timestamp desc\n const sorted = [...events].sort((a: any, b: any) => {\n const aFailed = (a.ResourceStatus || '').includes('FAILED') ? 0 : 1;\n const bFailed = (b.ResourceStatus || '').includes('FAILED') ? 0 : 1;\n if (aFailed !== bFailed) return aFailed - bFailed;\n return new Date(b.Timestamp).getTime() - new Date(a.Timestamp).getTime();\n });\n\n const lines = sorted.map((e: any) => {\n const status = e.ResourceStatus || '';\n const logical = e.LogicalResourceId || '';\n const reason = e.ResourceStatusReason || '';\n const isFailed = status.includes('FAILED');\n\n if (level === 'ultra') {\n return `${isFailed ? '\u2717' : '\u00B7'} ${logical} ${status}${reason ? ': ' + reason.slice(0, 60) : ''}`;\n }\n return `${status.padEnd(28)} ${logical}${reason ? '\\n \u2192 ' + reason : ''}`;\n });\n\n const maxLines = level === 'ultra' ? 15 : level === 'aggressive' ? 25 : 40;\n const shown = lines.slice(0, maxLines).join('\\n');\n const extra = lines.length > maxLines ? `\\n\u2026+${lines.length - maxLines} more events` : '';\n\n const failures = events.filter((e: any) => (e.ResourceStatus || '').includes('FAILED')).length;\n const header = failures > 0 ? `${failures} FAILED, ${events.length} total events:` : `${events.length} events:`;\n\n return { output: `${header}\\n${shown}${extra}`, strategy: 'aws:cfn' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\n// \u2500\u2500 DynamoDB \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterDynamoDB(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n\n // Unwrap DynamoDB type annotations: {\"S\": \"value\"} \u2192 \"value\", {\"N\": \"123\"} \u2192 123\n const unwrapped = unwrapDynamoTypes(data);\n const output = JSON.stringify(unwrapped, null, level === 'ultra' ? 0 : 2);\n\n return { output, strategy: 'aws:dynamodb' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\nfunction unwrapDynamoTypes(obj: any): any {\n if (obj === null || obj === undefined) return obj;\n if (Array.isArray(obj)) return obj.map(unwrapDynamoTypes);\n if (typeof obj !== 'object') return obj;\n\n // DynamoDB type wrappers: {\"S\": \"...\"}, {\"N\": \"...\"}, {\"BOOL\": true}, {\"L\": [...]}, {\"M\": {...}}, {\"NULL\": true}\n const keys = Object.keys(obj);\n if (keys.length === 1) {\n const key = keys[0];\n if (key === 'S') return obj.S;\n if (key === 'N') return Number(obj.N);\n if (key === 'BOOL') return obj.BOOL;\n if (key === 'NULL') return null;\n if (key === 'L') return (obj.L as any[]).map(unwrapDynamoTypes);\n if (key === 'M') return unwrapDynamoTypes(obj.M);\n if (key === 'SS') return obj.SS;\n if (key === 'NS') return (obj.NS as string[]).map(Number);\n if (key === 'BS') return obj.BS;\n }\n\n // Recurse into regular objects\n const result: any = {};\n for (const [k, v] of Object.entries(obj)) {\n result[k] = unwrapDynamoTypes(v);\n }\n return result;\n}\n\n// \u2500\u2500 IAM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterIamRoles(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n const roles = data.Roles || [];\n\n if (roles.length === 0) return { output: 'no roles', strategy: 'aws:iam-roles:empty' };\n\n // Strip AssumeRolePolicyDocument (verbose, rarely needed in listing)\n const lines = roles.map((r: any) => {\n const name = r.RoleName || '';\n const path = r.Path || '/';\n const created = r.CreateDate ? r.CreateDate.slice(0, 10) : '';\n\n if (level === 'ultra') return name;\n return `${name.padEnd(40)} ${path.padEnd(10)} ${created}`;\n });\n\n const maxLines = level === 'ultra' ? 30 : level === 'aggressive' ? 40 : 60;\n const shown = lines.slice(0, maxLines).join('\\n');\n const extra = lines.length > maxLines ? `\\n\u2026+${lines.length - maxLines} more` : '';\n\n return { output: `${roles.length} roles:\\n${shown}${extra}`, strategy: 'aws:iam-roles' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\nfunction filterIamPolicies(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n const policies = data.Policies || [];\n\n if (policies.length === 0) return { output: 'no policies', strategy: 'aws:iam-policies:empty' };\n\n const lines = policies.map((p: any) => {\n if (level === 'ultra') return p.PolicyName || '';\n return `${(p.PolicyName || '').padEnd(40)} ${p.Arn || ''}`;\n });\n\n const maxLines = level === 'ultra' ? 30 : 50;\n const shown = lines.slice(0, maxLines).join('\\n');\n const extra = lines.length > maxLines ? `\\n\u2026+${lines.length - maxLines} more` : '';\n\n return { output: `${policies.length} policies:\\n${shown}${extra}`, strategy: 'aws:iam-policies' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\n// \u2500\u2500 S3 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterS3Ls(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n\n if (lines.length === 0) return { output: 'empty', strategy: 'aws:s3-ls:empty' };\n if (lines.length <= 20) return { output: raw, strategy: 'aws:s3-ls:short' };\n\n if (level === 'ultra') {\n return { output: `${lines.length} objects`, strategy: 'aws:s3-ls:ultra' };\n }\n\n const maxLines = level === 'aggressive' ? 30 : 50;\n const shown = lines.slice(0, maxLines).join('\\n');\n const extra = lines.length > maxLines ? `\\n\u2026+${lines.length - maxLines} more objects` : '';\n\n return { output: `${shown}${extra}`, strategy: 'aws:s3-ls' };\n}\n\nfunction filterS3Transfer(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n\n // Strip progress lines (Completed X.X MiB/...)\n const meaningful = lines.filter(l => !l.includes('Completed') && !l.includes('upload:') || l.includes('upload: s3://'));\n\n if (meaningful.length === 0) return { output: 'ok', strategy: 'aws:s3-transfer' };\n\n if (level === 'ultra') {\n const count = lines.filter(l => l.includes('upload:') || l.includes('copy:')).length;\n return { output: `ok ${count} objects`, strategy: 'aws:s3-transfer:ultra' };\n }\n\n return { output: meaningful.slice(0, 20).join('\\n'), strategy: 'aws:s3-transfer' };\n}\n\n// \u2500\u2500 ECS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterEcsTasks(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n const tasks = data.tasks || data.taskArns || [];\n\n if (tasks.length === 0) return { output: 'no tasks', strategy: 'aws:ecs-tasks:empty' };\n\n if (Array.isArray(tasks) && typeof tasks[0] === 'string') {\n // taskArns \u2014 just ARNs\n const short = tasks.map((arn: string) => arn.split('/').pop());\n return { output: `${tasks.length} tasks:\\n${short.join('\\n')}`, strategy: 'aws:ecs-tasks' };\n }\n\n const lines = tasks.map((t: any) => {\n const id = (t.taskArn || '').split('/').pop();\n const status = t.lastStatus || '';\n const group = t.group || '';\n if (level === 'ultra') return `${id} ${status}`;\n return `${id} ${status.padEnd(10)} ${group}`;\n });\n\n return { output: `${tasks.length} tasks:\\n${lines.join('\\n')}`, strategy: 'aws:ecs-tasks' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\nfunction filterEcsServices(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n const services = data.services || [];\n\n if (services.length === 0) return { output: 'no services', strategy: 'aws:ecs-services:empty' };\n\n const lines = services.map((s: any) => {\n const name = s.serviceName || '';\n const status = s.status || '';\n const running = s.runningCount ?? 0;\n const desired = s.desiredCount ?? 0;\n if (level === 'ultra') return `${name} ${running}/${desired}`;\n return `${name.padEnd(30)} ${status.padEnd(8)} ${running}/${desired} tasks`;\n });\n\n return { output: `${services.length} services:\\n${lines.join('\\n')}`, strategy: 'aws:ecs-services' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\n// \u2500\u2500 SQS / SNS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterSqsQueues(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n const urls = data.QueueUrls || [];\n if (urls.length === 0) return { output: 'no queues', strategy: 'aws:sqs:empty' };\n\n const names = urls.map((url: string) => url.split('/').pop());\n if (level === 'ultra') return { output: `${names.length} queues`, strategy: 'aws:sqs:ultra' };\n return { output: `${names.length} queues:\\n${names.join('\\n')}`, strategy: 'aws:sqs' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\nfunction filterSnsTopics(raw: string, level: CompressorOptions['level']): FilterResult {\n try {\n const data = JSON.parse(raw);\n const topics = data.Topics || [];\n if (topics.length === 0) return { output: 'no topics', strategy: 'aws:sns:empty' };\n\n const arns = topics.map((t: any) => (t.TopicArn || '').split(':').pop());\n if (level === 'ultra') return { output: `${arns.length} topics`, strategy: 'aws:sns:ultra' };\n return { output: `${arns.length} topics:\\n${arns.join('\\n')}`, strategy: 'aws:sns' };\n } catch {\n return filterGenericAws(raw, level);\n }\n}\n\n// \u2500\u2500 Generic AWS fallback \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction filterGenericAws(raw: string, level: CompressorOptions['level']): FilterResult {\n // Try to parse as JSON and strip common verbose fields\n try {\n const data = JSON.parse(raw);\n const stripped = stripAwsVerboseFields(data);\n const indent = level === 'ultra' ? 0 : 2;\n const output = JSON.stringify(stripped, null, indent);\n\n // Truncate if still too long\n const maxChars = level === 'ultra' ? 2000 : level === 'aggressive' ? 5000 : 10000;\n if (output.length > maxChars) {\n return { output: output.slice(0, maxChars) + '\\n\u2026(truncated)', strategy: 'aws:generic:truncated' };\n }\n\n return { output, strategy: 'aws:generic:json' };\n } catch {\n // Not JSON \u2014 apply line-based truncation\n const lines = raw.split('\\n');\n const maxLines = level === 'ultra' ? 20 : level === 'aggressive' ? 40 : 60;\n if (lines.length <= maxLines) return { output: raw, strategy: 'aws:generic:text' };\n\n const shown = lines.slice(0, maxLines).join('\\n');\n return { output: `${shown}\\n\u2026+${lines.length - maxLines} more lines`, strategy: 'aws:generic:truncated' };\n }\n}\n\n/**\n * Strip commonly verbose AWS fields that add noise without actionable info.\n */\nfunction stripAwsVerboseFields(obj: any): any {\n if (obj === null || obj === undefined) return obj;\n if (Array.isArray(obj)) return obj.map(stripAwsVerboseFields);\n if (typeof obj !== 'object') return obj;\n\n const STRIP_KEYS = new Set([\n 'AssumeRolePolicyDocument',\n 'PolicyDocument',\n 'Document',\n 'ResponseMetadata',\n 'Marker',\n 'IsTruncated',\n ]);\n\n const result: any = {};\n for (const [k, v] of Object.entries(obj)) {\n if (STRIP_KEYS.has(k)) continue;\n result[k] = stripAwsVerboseFields(v);\n }\n return result;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var docker_exports = {};
|
|
20
|
+
__export(docker_exports, {
|
|
21
|
+
dockerFilter: () => dockerFilter
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(docker_exports);
|
|
24
|
+
const dockerFilter = {
|
|
25
|
+
name: "docker",
|
|
26
|
+
matches(command) {
|
|
27
|
+
return /\b(docker|kubectl|podman)\b/.test(command);
|
|
28
|
+
},
|
|
29
|
+
filter(command, rawOutput, level) {
|
|
30
|
+
if (/docker\s+ps/.test(command)) return filterDockerPs(rawOutput, level);
|
|
31
|
+
if (/docker\s+images/.test(command)) return filterDockerImages(rawOutput, level);
|
|
32
|
+
if (/docker\s+logs/.test(command)) return filterDockerLogs(rawOutput, level);
|
|
33
|
+
if (/docker\s+compose\s+ps/.test(command)) return filterComposePs(rawOutput, level);
|
|
34
|
+
if (/kubectl.*pods/.test(command) || /kubectl\s+get\s+po/.test(command)) return filterKubectlPods(rawOutput, level);
|
|
35
|
+
if (/kubectl.*logs/.test(command)) return filterKubectlLogs(rawOutput, level);
|
|
36
|
+
if (/kubectl.*services/.test(command) || /kubectl\s+get\s+svc/.test(command)) return filterKubectlServices(rawOutput, level);
|
|
37
|
+
return { output: rawOutput, strategy: "docker:passthrough" };
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
function filterDockerPs(raw, level) {
|
|
41
|
+
const lines = raw.split("\n").filter((l) => l.trim());
|
|
42
|
+
if (lines.length <= 1) return { output: "no containers running", strategy: "docker-ps:empty" };
|
|
43
|
+
const header = lines[0];
|
|
44
|
+
const rows = lines.slice(1);
|
|
45
|
+
if (level === "ultra") {
|
|
46
|
+
return { output: `${rows.length} containers running`, strategy: "docker-ps:ultra" };
|
|
47
|
+
}
|
|
48
|
+
const containers = rows.map((row) => {
|
|
49
|
+
const parts = row.split(/\s{2,}/);
|
|
50
|
+
const name = parts[parts.length - 1] || "";
|
|
51
|
+
const status = parts.find((p) => /Up|Exited|Created/.test(p)) || "";
|
|
52
|
+
const image = parts[1] || "";
|
|
53
|
+
return { name: name.trim(), status: status.trim(), image: image.trim() };
|
|
54
|
+
}).filter((c) => c.name);
|
|
55
|
+
if (level === "aggressive") {
|
|
56
|
+
const compact = containers.map((c) => `${c.name}: ${c.status}`).join("\n");
|
|
57
|
+
return { output: `${containers.length} containers:
|
|
58
|
+
${compact}`, strategy: "docker-ps:compact" };
|
|
59
|
+
}
|
|
60
|
+
const detailed = containers.map((c) => `${c.name} (${c.image}) - ${c.status}`).join("\n");
|
|
61
|
+
return { output: `${containers.length} containers:
|
|
62
|
+
${detailed}`, strategy: "docker-ps:detailed" };
|
|
63
|
+
}
|
|
64
|
+
function filterDockerImages(raw, level) {
|
|
65
|
+
const lines = raw.split("\n").filter((l) => l.trim());
|
|
66
|
+
if (lines.length <= 1) return { output: "no images", strategy: "docker-images:empty" };
|
|
67
|
+
const rows = lines.slice(1);
|
|
68
|
+
if (level === "ultra") {
|
|
69
|
+
return { output: `${rows.length} images`, strategy: "docker-images:ultra" };
|
|
70
|
+
}
|
|
71
|
+
const images = rows.map((row) => {
|
|
72
|
+
const parts = row.split(/\s{2,}/);
|
|
73
|
+
return { repo: parts[0] || "", tag: parts[1] || "", size: parts[parts.length - 1] || "" };
|
|
74
|
+
}).filter((i) => i.repo && i.repo !== "<none>");
|
|
75
|
+
const compact = images.slice(0, level === "aggressive" ? 10 : 20).map((i) => `${i.repo}:${i.tag} (${i.size})`).join("\n");
|
|
76
|
+
const extra = images.length > 20 ? `
|
|
77
|
+
\u2026+${images.length - 20} more` : "";
|
|
78
|
+
return { output: `${images.length} images:
|
|
79
|
+
${compact}${extra}`, strategy: "docker-images:compact" };
|
|
80
|
+
}
|
|
81
|
+
function filterDockerLogs(raw, level) {
|
|
82
|
+
return deduplicateLogLines(raw, level, "docker-logs");
|
|
83
|
+
}
|
|
84
|
+
function filterComposePs(raw, level) {
|
|
85
|
+
const lines = raw.split("\n").filter((l) => l.trim());
|
|
86
|
+
if (lines.length <= 1) return { output: "no services", strategy: "compose-ps:empty" };
|
|
87
|
+
const rows = lines.slice(1);
|
|
88
|
+
if (level === "ultra") {
|
|
89
|
+
return { output: `${rows.length} services`, strategy: "compose-ps:ultra" };
|
|
90
|
+
}
|
|
91
|
+
return { output: lines.join("\n"), strategy: "compose-ps:table" };
|
|
92
|
+
}
|
|
93
|
+
function filterKubectlPods(raw, level) {
|
|
94
|
+
const lines = raw.split("\n").filter((l) => l.trim());
|
|
95
|
+
if (lines.length <= 1) return { output: "no pods", strategy: "kubectl-pods:empty" };
|
|
96
|
+
const rows = lines.slice(1);
|
|
97
|
+
if (level === "ultra") {
|
|
98
|
+
const running = rows.filter((r) => r.includes("Running")).length;
|
|
99
|
+
const other = rows.length - running;
|
|
100
|
+
return { output: `${rows.length} pods (${running} running${other > 0 ? `, ${other} other` : ""})`, strategy: "kubectl-pods:ultra" };
|
|
101
|
+
}
|
|
102
|
+
const maxRows = level === "aggressive" ? 15 : 30;
|
|
103
|
+
if (rows.length <= maxRows) return { output: raw, strategy: "kubectl-pods:short" };
|
|
104
|
+
const shown = [lines[0], ...rows.slice(0, maxRows)].join("\n");
|
|
105
|
+
return { output: `${shown}
|
|
106
|
+
\u2026+${rows.length - maxRows} more pods`, strategy: "kubectl-pods:truncated" };
|
|
107
|
+
}
|
|
108
|
+
function filterKubectlLogs(raw, level) {
|
|
109
|
+
return deduplicateLogLines(raw, level, "kubectl-logs");
|
|
110
|
+
}
|
|
111
|
+
function filterKubectlServices(raw, level) {
|
|
112
|
+
const lines = raw.split("\n").filter((l) => l.trim());
|
|
113
|
+
if (lines.length <= 1) return { output: "no services", strategy: "kubectl-svc:empty" };
|
|
114
|
+
if (level === "ultra") {
|
|
115
|
+
return { output: `${lines.length - 1} services`, strategy: "kubectl-svc:ultra" };
|
|
116
|
+
}
|
|
117
|
+
return { output: raw, strategy: "kubectl-svc:table" };
|
|
118
|
+
}
|
|
119
|
+
function deduplicateLogLines(raw, level, prefix) {
|
|
120
|
+
const lines = raw.split("\n");
|
|
121
|
+
if (lines.length <= 20) return { output: raw, strategy: `${prefix}:short` };
|
|
122
|
+
const result = [];
|
|
123
|
+
let lastPattern = "";
|
|
124
|
+
let repeatCount = 0;
|
|
125
|
+
for (const line of lines) {
|
|
126
|
+
const pattern = line.replace(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}[.\d]*Z?/g, "<ts>").replace(/\b\d+\b/g, "<n>");
|
|
127
|
+
if (pattern === lastPattern) {
|
|
128
|
+
repeatCount++;
|
|
129
|
+
} else {
|
|
130
|
+
if (repeatCount > 1) {
|
|
131
|
+
result.push(` \u2026repeated ${repeatCount} times`);
|
|
132
|
+
}
|
|
133
|
+
result.push(line);
|
|
134
|
+
lastPattern = pattern;
|
|
135
|
+
repeatCount = 1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (repeatCount > 1) {
|
|
139
|
+
result.push(` \u2026repeated ${repeatCount} times`);
|
|
140
|
+
}
|
|
141
|
+
const maxLines = level === "ultra" ? 20 : level === "aggressive" ? 40 : 60;
|
|
142
|
+
if (result.length <= maxLines) {
|
|
143
|
+
return { output: result.join("\n"), strategy: `${prefix}:deduped` };
|
|
144
|
+
}
|
|
145
|
+
const shown = result.slice(-maxLines).join("\n");
|
|
146
|
+
return { output: `\u2026(${result.length - maxLines} earlier lines omitted)
|
|
147
|
+
${shown}`, strategy: `${prefix}:deduped+truncated` };
|
|
148
|
+
}
|
|
149
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
150
|
+
0 && (module.exports = {
|
|
151
|
+
dockerFilter
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=docker.js.map
|