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.
Files changed (84) hide show
  1. package/README.md +332 -93
  2. package/dist/bin/commands/caveman.js +19 -2
  3. package/dist/bin/commands/caveman.js.map +2 -2
  4. package/dist/bin/commands/compression.js +109 -0
  5. package/dist/bin/commands/compression.js.map +7 -0
  6. package/dist/bin/commands/context.js +31 -24
  7. package/dist/bin/commands/context.js.map +2 -2
  8. package/dist/bin/commands/exec.js +107 -0
  9. package/dist/bin/commands/exec.js.map +7 -0
  10. package/dist/bin/commands/gain.js +119 -0
  11. package/dist/bin/commands/gain.js.map +7 -0
  12. package/dist/bin/commands/help.js +16 -5
  13. package/dist/bin/commands/help.js.map +2 -2
  14. package/dist/bin/commands/install.js +8 -2
  15. package/dist/bin/commands/install.js.map +2 -2
  16. package/dist/bin/commands/query.js +5 -1
  17. package/dist/bin/commands/query.js.map +2 -2
  18. package/dist/bin/commands/serve.js +2 -2
  19. package/dist/bin/commands/serve.js.map +2 -2
  20. package/dist/bin/commands/uninit.js +65 -41
  21. package/dist/bin/commands/uninit.js.map +2 -2
  22. package/dist/bin/commands/utils.js +16 -0
  23. package/dist/bin/commands/utils.js.map +2 -2
  24. package/dist/bin/installer/cli-agent.js +5 -25
  25. package/dist/bin/installer/cli-agent.js.map +2 -2
  26. package/dist/bin/installer/common.js +154 -0
  27. package/dist/bin/installer/common.js.map +7 -0
  28. package/dist/bin/installer/config-prompt.js +9 -2
  29. package/dist/bin/installer/config-prompt.js.map +2 -2
  30. package/dist/bin/installer/hooks.js +19 -1
  31. package/dist/bin/installer/hooks.js.map +2 -2
  32. package/dist/bin/installer/index.js +104 -86
  33. package/dist/bin/installer/index.js.map +2 -2
  34. package/dist/bin/installer/instructions.js +60 -0
  35. package/dist/bin/installer/instructions.js.map +7 -0
  36. package/dist/bin/installer/mcp.js +6 -36
  37. package/dist/bin/installer/mcp.js.map +2 -2
  38. package/dist/bin/installer/steering.js +116 -40
  39. package/dist/bin/installer/steering.js.map +2 -2
  40. package/dist/bin/installer/targets/claude.js +79 -0
  41. package/dist/bin/installer/targets/claude.js.map +7 -0
  42. package/dist/bin/installer/targets/codex.js +77 -0
  43. package/dist/bin/installer/targets/codex.js.map +7 -0
  44. package/dist/bin/installer/targets/index.js +57 -0
  45. package/dist/bin/installer/targets/index.js.map +7 -0
  46. package/dist/bin/installer/targets/kiro.js +63 -0
  47. package/dist/bin/installer/targets/kiro.js.map +7 -0
  48. package/dist/bin/kirograph.js +7 -1
  49. package/dist/bin/kirograph.js.map +3 -3
  50. package/dist/compression/filters/aws.js +418 -0
  51. package/dist/compression/filters/aws.js.map +7 -0
  52. package/dist/compression/filters/docker.js +153 -0
  53. package/dist/compression/filters/docker.js.map +7 -0
  54. package/dist/compression/filters/files.js +150 -0
  55. package/dist/compression/filters/files.js.map +7 -0
  56. package/dist/compression/filters/generic.js +86 -0
  57. package/dist/compression/filters/generic.js.map +7 -0
  58. package/dist/compression/filters/git.js +272 -0
  59. package/dist/compression/filters/git.js.map +7 -0
  60. package/dist/compression/filters/github.js +137 -0
  61. package/dist/compression/filters/github.js.map +7 -0
  62. package/dist/compression/filters/lint.js +280 -0
  63. package/dist/compression/filters/lint.js.map +7 -0
  64. package/dist/compression/filters/misc.js +212 -0
  65. package/dist/compression/filters/misc.js.map +7 -0
  66. package/dist/compression/filters/package.js +151 -0
  67. package/dist/compression/filters/package.js.map +7 -0
  68. package/dist/compression/filters/test.js +266 -0
  69. package/dist/compression/filters/test.js.map +7 -0
  70. package/dist/compression/index.js +144 -0
  71. package/dist/compression/index.js.map +7 -0
  72. package/dist/compression/naive-cost.js +94 -0
  73. package/dist/compression/naive-cost.js.map +7 -0
  74. package/dist/compression/tracker.js +228 -0
  75. package/dist/compression/tracker.js.map +7 -0
  76. package/dist/compression/types.js +17 -0
  77. package/dist/compression/types.js.map +7 -0
  78. package/dist/config.js +18 -1
  79. package/dist/config.js.map +2 -2
  80. package/dist/mcp/tool-names.js +50 -0
  81. package/dist/mcp/tool-names.js.map +7 -0
  82. package/dist/mcp/tools.js +173 -4
  83. package/dist/mcp/tools.js.map +3 -3
  84. package/package.json +2 -2
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/compression/filters/docker.ts"],
4
+ "sourcesContent": ["/**\n * Docker and container output filters\n */\n\nimport type { CommandFilter, FilterResult, CompressorOptions } from '../types';\n\nexport const dockerFilter: CommandFilter = {\n name: 'docker',\n\n matches(command: string): boolean {\n return /\\b(docker|kubectl|podman)\\b/.test(command);\n },\n\n filter(command: string, rawOutput: string, level: CompressorOptions['level']): FilterResult {\n if (/docker\\s+ps/.test(command)) return filterDockerPs(rawOutput, level);\n if (/docker\\s+images/.test(command)) return filterDockerImages(rawOutput, level);\n if (/docker\\s+logs/.test(command)) return filterDockerLogs(rawOutput, level);\n if (/docker\\s+compose\\s+ps/.test(command)) return filterComposePs(rawOutput, level);\n if (/kubectl.*pods/.test(command) || /kubectl\\s+get\\s+po/.test(command)) return filterKubectlPods(rawOutput, level);\n if (/kubectl.*logs/.test(command)) return filterKubectlLogs(rawOutput, level);\n if (/kubectl.*services/.test(command) || /kubectl\\s+get\\s+svc/.test(command)) return filterKubectlServices(rawOutput, level);\n\n return { output: rawOutput, strategy: 'docker:passthrough' };\n },\n};\n\nfunction filterDockerPs(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n if (lines.length <= 1) return { output: 'no containers running', strategy: 'docker-ps:empty' };\n\n // Parse table format\n const header = lines[0];\n const rows = lines.slice(1);\n\n if (level === 'ultra') {\n return { output: `${rows.length} containers running`, strategy: 'docker-ps:ultra' };\n }\n\n // Extract key columns: NAMES, STATUS, PORTS\n const containers = rows.map(row => {\n const parts = row.split(/\\s{2,}/);\n // Typical: CONTAINER ID, IMAGE, COMMAND, CREATED, STATUS, PORTS, NAMES\n const name = parts[parts.length - 1] || '';\n const status = parts.find(p => /Up|Exited|Created/.test(p)) || '';\n const image = parts[1] || '';\n return { name: name.trim(), status: status.trim(), image: image.trim() };\n }).filter(c => c.name);\n\n if (level === 'aggressive') {\n const compact = containers.map(c => `${c.name}: ${c.status}`).join('\\n');\n return { output: `${containers.length} containers:\\n${compact}`, strategy: 'docker-ps:compact' };\n }\n\n const detailed = containers.map(c => `${c.name} (${c.image}) - ${c.status}`).join('\\n');\n return { output: `${containers.length} containers:\\n${detailed}`, strategy: 'docker-ps:detailed' };\n}\n\nfunction filterDockerImages(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n if (lines.length <= 1) return { output: 'no images', strategy: 'docker-images:empty' };\n\n const rows = lines.slice(1);\n\n if (level === 'ultra') {\n return { output: `${rows.length} images`, strategy: 'docker-images:ultra' };\n }\n\n // Extract REPOSITORY, TAG, SIZE\n const images = rows.map(row => {\n const parts = row.split(/\\s{2,}/);\n return { repo: parts[0] || '', tag: parts[1] || '', size: parts[parts.length - 1] || '' };\n }).filter(i => i.repo && i.repo !== '<none>');\n\n const compact = images.slice(0, level === 'aggressive' ? 10 : 20)\n .map(i => `${i.repo}:${i.tag} (${i.size})`)\n .join('\\n');\n const extra = images.length > 20 ? `\\n\u2026+${images.length - 20} more` : '';\n\n return { output: `${images.length} images:\\n${compact}${extra}`, strategy: 'docker-images:compact' };\n}\n\nfunction filterDockerLogs(raw: string, level: CompressorOptions['level']): FilterResult {\n return deduplicateLogLines(raw, level, 'docker-logs');\n}\n\nfunction filterComposePs(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n if (lines.length <= 1) return { output: 'no services', strategy: 'compose-ps:empty' };\n\n const rows = lines.slice(1);\n if (level === 'ultra') {\n return { output: `${rows.length} services`, strategy: 'compose-ps:ultra' };\n }\n\n return { output: lines.join('\\n'), strategy: 'compose-ps:table' };\n}\n\nfunction filterKubectlPods(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n if (lines.length <= 1) return { output: 'no pods', strategy: 'kubectl-pods:empty' };\n\n const rows = lines.slice(1);\n\n if (level === 'ultra') {\n const running = rows.filter(r => r.includes('Running')).length;\n const other = rows.length - running;\n return { output: `${rows.length} pods (${running} running${other > 0 ? `, ${other} other` : ''})`, strategy: 'kubectl-pods:ultra' };\n }\n\n // Keep header + rows, but truncate\n const maxRows = level === 'aggressive' ? 15 : 30;\n if (rows.length <= maxRows) return { output: raw, strategy: 'kubectl-pods:short' };\n\n const shown = [lines[0], ...rows.slice(0, maxRows)].join('\\n');\n return { output: `${shown}\\n\u2026+${rows.length - maxRows} more pods`, strategy: 'kubectl-pods:truncated' };\n}\n\nfunction filterKubectlLogs(raw: string, level: CompressorOptions['level']): FilterResult {\n return deduplicateLogLines(raw, level, 'kubectl-logs');\n}\n\nfunction filterKubectlServices(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n if (lines.length <= 1) return { output: 'no services', strategy: 'kubectl-svc:empty' };\n\n if (level === 'ultra') {\n return { output: `${lines.length - 1} services`, strategy: 'kubectl-svc:ultra' };\n }\n\n return { output: raw, strategy: 'kubectl-svc:table' };\n}\n\n// \u2500\u2500 Shared log deduplication \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 deduplicateLogLines(raw: string, level: CompressorOptions['level'], prefix: string): FilterResult {\n const lines = raw.split('\\n');\n\n if (lines.length <= 20) return { output: raw, strategy: `${prefix}:short` };\n\n // Deduplicate consecutive similar lines\n const result: string[] = [];\n let lastPattern = '';\n let repeatCount = 0;\n\n for (const line of lines) {\n // Normalize: strip timestamps and numbers for comparison\n const pattern = line.replace(/\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}[.\\d]*Z?/g, '<ts>')\n .replace(/\\b\\d+\\b/g, '<n>');\n\n if (pattern === lastPattern) {\n repeatCount++;\n } else {\n if (repeatCount > 1) {\n result.push(` \u2026repeated ${repeatCount} times`);\n }\n result.push(line);\n lastPattern = pattern;\n repeatCount = 1;\n }\n }\n if (repeatCount > 1) {\n result.push(` \u2026repeated ${repeatCount} times`);\n }\n\n // Truncate\n const maxLines = level === 'ultra' ? 20 : level === 'aggressive' ? 40 : 60;\n if (result.length <= maxLines) {\n return { output: result.join('\\n'), strategy: `${prefix}:deduped` };\n }\n\n const shown = result.slice(-maxLines).join('\\n'); // Keep tail (most recent)\n return { output: `\u2026(${result.length - maxLines} earlier lines omitted)\\n${shown}`, strategy: `${prefix}:deduped+truncated` };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,150 @@
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 files_exports = {};
20
+ __export(files_exports, {
21
+ filesFilter: () => filesFilter
22
+ });
23
+ module.exports = __toCommonJS(files_exports);
24
+ const filesFilter = {
25
+ name: "files",
26
+ matches(command) {
27
+ return /^\s*(ls|find|tree|dir)\b/.test(command);
28
+ },
29
+ filter(command, rawOutput, level) {
30
+ if (/^\s*tree\b/.test(command)) return filterTree(rawOutput, level);
31
+ if (/^\s*find\b/.test(command)) return filterFind(rawOutput, level);
32
+ if (/^\s*ls\b/.test(command)) return filterLs(rawOutput, level);
33
+ return { output: rawOutput, strategy: "files:passthrough" };
34
+ }
35
+ };
36
+ function filterLs(raw, level) {
37
+ const lines = raw.split("\n").filter((l) => l.trim());
38
+ if (lines.length <= 10) {
39
+ return { output: raw, strategy: "ls:short" };
40
+ }
41
+ const isLongFormat = lines.some((l) => /^[drwx-]{10}/.test(l));
42
+ if (isLongFormat) {
43
+ const dirs = [];
44
+ const files = [];
45
+ for (const line of lines) {
46
+ if (line.startsWith("total")) continue;
47
+ const parts2 = line.split(/\s+/);
48
+ const name = parts2[parts2.length - 1];
49
+ if (!name || name === "." || name === "..") continue;
50
+ if (line.startsWith("d")) {
51
+ dirs.push(name + "/");
52
+ } else {
53
+ files.push(name);
54
+ }
55
+ }
56
+ if (level === "ultra") {
57
+ return {
58
+ output: `${dirs.length} dirs, ${files.length} files`,
59
+ strategy: "ls:ultra"
60
+ };
61
+ }
62
+ if (level === "aggressive") {
63
+ const dirList = dirs.length > 0 ? `Dirs (${dirs.length}): ${dirs.slice(0, 10).join(", ")}${dirs.length > 10 ? "\u2026" : ""}` : "";
64
+ const fileList = files.length > 0 ? `Files (${files.length}): ${groupFilesByExt(files)}` : "";
65
+ return { output: [dirList, fileList].filter(Boolean).join("\n"), strategy: "ls:grouped" };
66
+ }
67
+ const parts = [];
68
+ if (dirs.length > 0) {
69
+ parts.push(`Directories (${dirs.length}): ${dirs.join(", ")}`);
70
+ }
71
+ if (files.length > 0) {
72
+ const maxFiles = 20;
73
+ parts.push(`Files (${files.length}):`);
74
+ parts.push(...files.slice(0, maxFiles).map((f) => ` ${f}`));
75
+ if (files.length > maxFiles) parts.push(` \u2026+${files.length - maxFiles} more`);
76
+ }
77
+ return { output: parts.join("\n"), strategy: "ls:structured" };
78
+ }
79
+ if (level === "ultra") {
80
+ return { output: `${lines.length} entries`, strategy: "ls:count:ultra" };
81
+ }
82
+ const maxLines = level === "aggressive" ? 20 : 40;
83
+ if (lines.length <= maxLines) return { output: raw, strategy: "ls:short" };
84
+ const shown = lines.slice(0, maxLines).join("\n");
85
+ return { output: `${shown}
86
+ \u2026+${lines.length - maxLines} more entries`, strategy: "ls:truncated" };
87
+ }
88
+ function filterFind(raw, level) {
89
+ const lines = raw.split("\n").filter((l) => l.trim());
90
+ if (lines.length === 0) return { output: "no matches", strategy: "find:empty" };
91
+ if (lines.length <= 10) return { output: raw, strategy: "find:short" };
92
+ const byDir = /* @__PURE__ */ new Map();
93
+ for (const line of lines) {
94
+ const dir = line.includes("/") ? line.slice(0, line.lastIndexOf("/")) : ".";
95
+ if (!byDir.has(dir)) byDir.set(dir, []);
96
+ byDir.get(dir).push(line.slice(line.lastIndexOf("/") + 1));
97
+ }
98
+ if (level === "ultra") {
99
+ const summary = [...byDir.entries()].sort((a, b) => b[1].length - a[1].length).slice(0, 5).map(([d, f]) => `${d}/ (${f.length})`).join(", ");
100
+ return { output: `${lines.length} matches: ${summary}`, strategy: "find:ultra" };
101
+ }
102
+ if (level === "aggressive") {
103
+ const grouped = [...byDir.entries()].sort((a, b) => b[1].length - a[1].length).slice(0, 10).map(([dir, files]) => `${dir}/ (${files.length} files)`).join("\n");
104
+ const extra = byDir.size > 10 ? `
105
+ \u2026+${byDir.size - 10} more directories` : "";
106
+ return { output: `${lines.length} matches in ${byDir.size} directories:
107
+ ${grouped}${extra}`, strategy: "find:grouped" };
108
+ }
109
+ const parts = [`${lines.length} matches in ${byDir.size} directories:
110
+ `];
111
+ let shown = 0;
112
+ for (const [dir, files] of [...byDir.entries()].sort((a, b) => b[1].length - a[1].length)) {
113
+ if (shown >= 15) break;
114
+ parts.push(`${dir}/ (${files.length}):`);
115
+ for (const f of files.slice(0, 3)) parts.push(` ${f}`);
116
+ if (files.length > 3) parts.push(` \u2026+${files.length - 3} more`);
117
+ shown++;
118
+ }
119
+ if (byDir.size > 15) parts.push(`
120
+ \u2026+${byDir.size - 15} more directories`);
121
+ return { output: parts.join("\n"), strategy: "find:structured" };
122
+ }
123
+ function filterTree(raw, level) {
124
+ const lines = raw.split("\n").filter((l) => l.trim());
125
+ if (lines.length <= 20) return { output: raw, strategy: "tree:short" };
126
+ const summaryLine = lines.find((l) => /\d+\s+director/.test(l));
127
+ if (level === "ultra") {
128
+ return { output: summaryLine || `${lines.length} lines`, strategy: "tree:ultra" };
129
+ }
130
+ const maxLines = level === "aggressive" ? 30 : 50;
131
+ if (lines.length <= maxLines) return { output: raw, strategy: "tree:short" };
132
+ const shown = lines.slice(0, maxLines).join("\n");
133
+ const summary = summaryLine ? `
134
+ ${summaryLine}` : `
135
+ \u2026+${lines.length - maxLines} more lines`;
136
+ return { output: `${shown}${summary}`, strategy: "tree:truncated" };
137
+ }
138
+ function groupFilesByExt(files) {
139
+ const byExt = /* @__PURE__ */ new Map();
140
+ for (const f of files) {
141
+ const ext = f.includes(".") ? f.slice(f.lastIndexOf(".")) : "(no ext)";
142
+ byExt.set(ext, (byExt.get(ext) || 0) + 1);
143
+ }
144
+ return [...byExt.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([ext, count]) => `${ext}: ${count}`).join(", ");
145
+ }
146
+ // Annotate the CommonJS export names for ESM import in node:
147
+ 0 && (module.exports = {
148
+ filesFilter
149
+ });
150
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/compression/filters/files.ts"],
4
+ "sourcesContent": ["/**\n * File listing output filters (ls, find, tree)\n */\n\nimport type { CommandFilter, FilterResult, CompressorOptions } from '../types';\n\nexport const filesFilter: CommandFilter = {\n name: 'files',\n\n matches(command: string): boolean {\n return /^\\s*(ls|find|tree|dir)\\b/.test(command);\n },\n\n filter(command: string, rawOutput: string, level: CompressorOptions['level']): FilterResult {\n if (/^\\s*tree\\b/.test(command)) return filterTree(rawOutput, level);\n if (/^\\s*find\\b/.test(command)) return filterFind(rawOutput, level);\n if (/^\\s*ls\\b/.test(command)) return filterLs(rawOutput, level);\n return { output: rawOutput, strategy: 'files:passthrough' };\n },\n};\n\nfunction filterLs(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n\n // Short ls output \u2014 don't compress\n if (lines.length <= 10) {\n return { output: raw, strategy: 'ls:short' };\n }\n\n // ls -la format: detect by permission string\n const isLongFormat = lines.some(l => /^[drwx-]{10}/.test(l));\n\n if (isLongFormat) {\n const dirs: string[] = [];\n const files: string[] = [];\n\n for (const line of lines) {\n if (line.startsWith('total')) continue;\n const parts = line.split(/\\s+/);\n const name = parts[parts.length - 1];\n if (!name || name === '.' || name === '..') continue;\n\n if (line.startsWith('d')) {\n dirs.push(name + '/');\n } else {\n files.push(name);\n }\n }\n\n if (level === 'ultra') {\n return {\n output: `${dirs.length} dirs, ${files.length} files`,\n strategy: 'ls:ultra',\n };\n }\n\n if (level === 'aggressive') {\n const dirList = dirs.length > 0 ? `Dirs (${dirs.length}): ${dirs.slice(0, 10).join(', ')}${dirs.length > 10 ? '\u2026' : ''}` : '';\n const fileList = files.length > 0 ? `Files (${files.length}): ${groupFilesByExt(files)}` : '';\n return { output: [dirList, fileList].filter(Boolean).join('\\n'), strategy: 'ls:grouped' };\n }\n\n // Normal: show dirs + limited files\n const parts: string[] = [];\n if (dirs.length > 0) {\n parts.push(`Directories (${dirs.length}): ${dirs.join(', ')}`);\n }\n if (files.length > 0) {\n const maxFiles = 20;\n parts.push(`Files (${files.length}):`);\n parts.push(...files.slice(0, maxFiles).map(f => ` ${f}`));\n if (files.length > maxFiles) parts.push(` \u2026+${files.length - maxFiles} more`);\n }\n return { output: parts.join('\\n'), strategy: 'ls:structured' };\n }\n\n // Simple ls (no -l): just truncate\n if (level === 'ultra') {\n return { output: `${lines.length} entries`, strategy: 'ls:count:ultra' };\n }\n\n const maxLines = level === 'aggressive' ? 20 : 40;\n if (lines.length <= maxLines) return { output: raw, strategy: 'ls:short' };\n\n const shown = lines.slice(0, maxLines).join('\\n');\n return { output: `${shown}\\n\u2026+${lines.length - maxLines} more entries`, strategy: 'ls:truncated' };\n}\n\nfunction filterFind(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n\n if (lines.length === 0) return { output: 'no matches', strategy: 'find:empty' };\n if (lines.length <= 10) return { output: raw, strategy: 'find:short' };\n\n // Group by directory\n const byDir = new Map<string, string[]>();\n for (const line of lines) {\n const dir = line.includes('/') ? line.slice(0, line.lastIndexOf('/')) : '.';\n if (!byDir.has(dir)) byDir.set(dir, []);\n byDir.get(dir)!.push(line.slice(line.lastIndexOf('/') + 1));\n }\n\n if (level === 'ultra') {\n const summary = [...byDir.entries()]\n .sort((a, b) => b[1].length - a[1].length)\n .slice(0, 5)\n .map(([d, f]) => `${d}/ (${f.length})`)\n .join(', ');\n return { output: `${lines.length} matches: ${summary}`, strategy: 'find:ultra' };\n }\n\n if (level === 'aggressive') {\n const grouped = [...byDir.entries()]\n .sort((a, b) => b[1].length - a[1].length)\n .slice(0, 10)\n .map(([dir, files]) => `${dir}/ (${files.length} files)`)\n .join('\\n');\n const extra = byDir.size > 10 ? `\\n\u2026+${byDir.size - 10} more directories` : '';\n return { output: `${lines.length} matches in ${byDir.size} directories:\\n${grouped}${extra}`, strategy: 'find:grouped' };\n }\n\n // Normal: show grouped with some file names\n const parts: string[] = [`${lines.length} matches in ${byDir.size} directories:\\n`];\n let shown = 0;\n for (const [dir, files] of [...byDir.entries()].sort((a, b) => b[1].length - a[1].length)) {\n if (shown >= 15) break;\n parts.push(`${dir}/ (${files.length}):`);\n for (const f of files.slice(0, 3)) parts.push(` ${f}`);\n if (files.length > 3) parts.push(` \u2026+${files.length - 3} more`);\n shown++;\n }\n if (byDir.size > 15) parts.push(`\\n\u2026+${byDir.size - 15} more directories`);\n\n return { output: parts.join('\\n'), strategy: 'find:structured' };\n}\n\nfunction filterTree(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n\n if (lines.length <= 20) return { output: raw, strategy: 'tree:short' };\n\n // Extract summary line (usually last: \"X directories, Y files\")\n const summaryLine = lines.find(l => /\\d+\\s+director/.test(l));\n\n if (level === 'ultra') {\n return { output: summaryLine || `${lines.length} lines`, strategy: 'tree:ultra' };\n }\n\n // Truncate to depth\n const maxLines = level === 'aggressive' ? 30 : 50;\n if (lines.length <= maxLines) return { output: raw, strategy: 'tree:short' };\n\n const shown = lines.slice(0, maxLines).join('\\n');\n const summary = summaryLine ? `\\n${summaryLine}` : `\\n\u2026+${lines.length - maxLines} more lines`;\n\n return { output: `${shown}${summary}`, strategy: 'tree:truncated' };\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 groupFilesByExt(files: string[]): string {\n const byExt = new Map<string, number>();\n for (const f of files) {\n const ext = f.includes('.') ? f.slice(f.lastIndexOf('.')) : '(no ext)';\n byExt.set(ext, (byExt.get(ext) || 0) + 1);\n }\n return [...byExt.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([ext, count]) => `${ext}: ${count}`)\n .join(', ');\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["parts"]
7
+ }
@@ -0,0 +1,86 @@
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 generic_exports = {};
20
+ __export(generic_exports, {
21
+ genericFilter: () => genericFilter
22
+ });
23
+ module.exports = __toCommonJS(generic_exports);
24
+ const genericFilter = {
25
+ name: "generic",
26
+ matches(_command) {
27
+ return true;
28
+ },
29
+ filter(_command, rawOutput, level) {
30
+ const lines = rawOutput.split("\n");
31
+ if (lines.length <= 15) {
32
+ return { output: rawOutput, strategy: "generic:short" };
33
+ }
34
+ let filtered = lines.filter((l) => {
35
+ const trimmed = l.trim();
36
+ if (!trimmed) return false;
37
+ if (/^[▓░█▒■□●○◐◑◒◓⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]/.test(trimmed)) return false;
38
+ if (/^\d+%\s*[|█▓░]/.test(trimmed)) return false;
39
+ if (/^[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⣾⣽⣻⢿⡿⣟⣯⣷]/.test(trimmed)) return false;
40
+ return true;
41
+ });
42
+ const deduped = [];
43
+ let lastPattern = "";
44
+ let repeatCount = 0;
45
+ for (const line of filtered) {
46
+ const pattern = normalizeForComparison(line);
47
+ if (pattern === lastPattern) {
48
+ repeatCount++;
49
+ } else {
50
+ if (repeatCount > 2) {
51
+ deduped.push(` \u2026repeated ${repeatCount} times`);
52
+ } else if (repeatCount === 2) {
53
+ deduped.push(filtered[deduped.length] || "");
54
+ }
55
+ deduped.push(line);
56
+ lastPattern = pattern;
57
+ repeatCount = 1;
58
+ }
59
+ }
60
+ if (repeatCount > 2) {
61
+ deduped.push(` \u2026repeated ${repeatCount} times`);
62
+ }
63
+ filtered = deduped;
64
+ const maxLines = level === "ultra" ? 30 : level === "aggressive" ? 60 : 100;
65
+ if (filtered.length <= maxLines) {
66
+ return { output: filtered.join("\n"), strategy: "generic:deduped" };
67
+ }
68
+ const headSize = Math.floor(maxLines * 0.6);
69
+ const tailSize = maxLines - headSize;
70
+ const head = filtered.slice(0, headSize);
71
+ const tail = filtered.slice(-tailSize);
72
+ const omitted = filtered.length - headSize - tailSize;
73
+ const output = [...head, `
74
+ \u2026(${omitted} lines omitted)
75
+ `, ...tail].join("\n");
76
+ return { output, strategy: "generic:truncated" };
77
+ }
78
+ };
79
+ function normalizeForComparison(line) {
80
+ return line.replace(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}[.\d]*Z?/g, "<ts>").replace(/\b\d{10,13}\b/g, "<ts>").replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, "<uuid>").replace(/\b[0-9a-f]{7,40}\b/g, "<hash>").replace(/(?<![a-zA-Z_])\d+(?![a-zA-Z_])/g, "<n>");
81
+ }
82
+ // Annotate the CommonJS export names for ESM import in node:
83
+ 0 && (module.exports = {
84
+ genericFilter
85
+ });
86
+ //# sourceMappingURL=generic.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/compression/filters/generic.ts"],
4
+ "sourcesContent": ["/**\n * Generic output filter \u2014 fallback for unrecognized commands.\n * Applies deduplication, truncation, and noise removal.\n */\n\nimport type { CommandFilter, FilterResult, CompressorOptions } from '../types';\n\nexport const genericFilter: CommandFilter = {\n name: 'generic',\n\n matches(_command: string): boolean {\n // Always matches as fallback\n return true;\n },\n\n filter(_command: string, rawOutput: string, level: CompressorOptions['level']): FilterResult {\n const lines = rawOutput.split('\\n');\n\n // Short output \u2014 don't compress\n if (lines.length <= 15) {\n return { output: rawOutput, strategy: 'generic:short' };\n }\n\n // Step 1: Remove blank lines and common noise\n let filtered = lines.filter(l => {\n const trimmed = l.trim();\n if (!trimmed) return false;\n // Remove common progress indicators\n if (/^[\u2593\u2591\u2588\u2592\u25A0\u25A1\u25CF\u25CB\u25D0\u25D1\u25D2\u25D3\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F]/.test(trimmed)) return false;\n if (/^\\d+%\\s*[|\u2588\u2593\u2591]/.test(trimmed)) return false;\n // Remove spinner lines\n if (/^[\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F\u28FE\u28FD\u28FB\u28BF\u287F\u28DF\u28EF\u28F7]/.test(trimmed)) return false;\n return true;\n });\n\n // Step 2: Deduplicate consecutive similar lines\n const deduped: string[] = [];\n let lastPattern = '';\n let repeatCount = 0;\n\n for (const line of filtered) {\n const pattern = normalizeForComparison(line);\n if (pattern === lastPattern) {\n repeatCount++;\n } else {\n if (repeatCount > 2) {\n deduped.push(` \u2026repeated ${repeatCount} times`);\n } else if (repeatCount === 2) {\n deduped.push(filtered[deduped.length] || '');\n }\n deduped.push(line);\n lastPattern = pattern;\n repeatCount = 1;\n }\n }\n if (repeatCount > 2) {\n deduped.push(` \u2026repeated ${repeatCount} times`);\n }\n\n filtered = deduped;\n\n // Step 3: Truncate based on level\n const maxLines = level === 'ultra' ? 30 : level === 'aggressive' ? 60 : 100;\n\n if (filtered.length <= maxLines) {\n return { output: filtered.join('\\n'), strategy: 'generic:deduped' };\n }\n\n // Keep head and tail\n const headSize = Math.floor(maxLines * 0.6);\n const tailSize = maxLines - headSize;\n const head = filtered.slice(0, headSize);\n const tail = filtered.slice(-tailSize);\n const omitted = filtered.length - headSize - tailSize;\n\n const output = [...head, `\\n\u2026(${omitted} lines omitted)\\n`, ...tail].join('\\n');\n return { output, strategy: 'generic:truncated' };\n },\n};\n\n/**\n * Normalize a line for deduplication comparison.\n * Strips timestamps, numbers, and UUIDs to detect repeated patterns.\n */\nfunction normalizeForComparison(line: string): string {\n return line\n // Strip ISO timestamps\n .replace(/\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}[.\\d]*Z?/g, '<ts>')\n // Strip Unix timestamps\n .replace(/\\b\\d{10,13}\\b/g, '<ts>')\n // Strip UUIDs\n .replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '<uuid>')\n // Strip hex hashes\n .replace(/\\b[0-9a-f]{7,40}\\b/g, '<hash>')\n // Strip standalone numbers (but keep those in identifiers)\n .replace(/(?<![a-zA-Z_])\\d+(?![a-zA-Z_])/g, '<n>');\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOO,MAAM,gBAA+B;AAAA,EAC1C,MAAM;AAAA,EAEN,QAAQ,UAA2B;AAEjC,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,UAAkB,WAAmB,OAAiD;AAC3F,UAAM,QAAQ,UAAU,MAAM,IAAI;AAGlC,QAAI,MAAM,UAAU,IAAI;AACtB,aAAO,EAAE,QAAQ,WAAW,UAAU,gBAAgB;AAAA,IACxD;AAGA,QAAI,WAAW,MAAM,OAAO,OAAK;AAC/B,YAAM,UAAU,EAAE,KAAK;AACvB,UAAI,CAAC,QAAS,QAAO;AAErB,UAAI,4BAA4B,KAAK,OAAO,EAAG,QAAO;AACtD,UAAI,iBAAiB,KAAK,OAAO,EAAG,QAAO;AAE3C,UAAI,wBAAwB,KAAK,OAAO,EAAG,QAAO;AAClD,aAAO;AAAA,IACT,CAAC;AAGD,UAAM,UAAoB,CAAC;AAC3B,QAAI,cAAc;AAClB,QAAI,cAAc;AAElB,eAAW,QAAQ,UAAU;AAC3B,YAAM,UAAU,uBAAuB,IAAI;AAC3C,UAAI,YAAY,aAAa;AAC3B;AAAA,MACF,OAAO;AACL,YAAI,cAAc,GAAG;AACnB,kBAAQ,KAAK,oBAAe,WAAW,QAAQ;AAAA,QACjD,WAAW,gBAAgB,GAAG;AAC5B,kBAAQ,KAAK,SAAS,QAAQ,MAAM,KAAK,EAAE;AAAA,QAC7C;AACA,gBAAQ,KAAK,IAAI;AACjB,sBAAc;AACd,sBAAc;AAAA,MAChB;AAAA,IACF;AACA,QAAI,cAAc,GAAG;AACnB,cAAQ,KAAK,oBAAe,WAAW,QAAQ;AAAA,IACjD;AAEA,eAAW;AAGX,UAAM,WAAW,UAAU,UAAU,KAAK,UAAU,eAAe,KAAK;AAExE,QAAI,SAAS,UAAU,UAAU;AAC/B,aAAO,EAAE,QAAQ,SAAS,KAAK,IAAI,GAAG,UAAU,kBAAkB;AAAA,IACpE;AAGA,UAAM,WAAW,KAAK,MAAM,WAAW,GAAG;AAC1C,UAAM,WAAW,WAAW;AAC5B,UAAM,OAAO,SAAS,MAAM,GAAG,QAAQ;AACvC,UAAM,OAAO,SAAS,MAAM,CAAC,QAAQ;AACrC,UAAM,UAAU,SAAS,SAAS,WAAW;AAE7C,UAAM,SAAS,CAAC,GAAG,MAAM;AAAA,SAAO,OAAO;AAAA,GAAqB,GAAG,IAAI,EAAE,KAAK,IAAI;AAC9E,WAAO,EAAE,QAAQ,UAAU,oBAAoB;AAAA,EACjD;AACF;AAMA,SAAS,uBAAuB,MAAsB;AACpD,SAAO,KAEJ,QAAQ,mDAAmD,MAAM,EAEjE,QAAQ,kBAAkB,MAAM,EAEhC,QAAQ,kEAAkE,QAAQ,EAElF,QAAQ,uBAAuB,QAAQ,EAEvC,QAAQ,mCAAmC,KAAK;AACrD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,272 @@
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 git_exports = {};
20
+ __export(git_exports, {
21
+ gitFilter: () => gitFilter
22
+ });
23
+ module.exports = __toCommonJS(git_exports);
24
+ const gitFilter = {
25
+ name: "git",
26
+ matches(command) {
27
+ return /^\s*(git\s|rtk\s+git\s)/.test(command);
28
+ },
29
+ filter(command, rawOutput, level) {
30
+ const subcommand = extractGitSubcommand(command);
31
+ switch (subcommand) {
32
+ case "status":
33
+ return filterGitStatus(rawOutput, level);
34
+ case "log":
35
+ return filterGitLog(rawOutput, level);
36
+ case "diff":
37
+ return filterGitDiff(rawOutput, level);
38
+ case "push":
39
+ return filterGitPush(rawOutput);
40
+ case "pull":
41
+ return filterGitPull(rawOutput);
42
+ case "add":
43
+ return filterGitAdd(rawOutput);
44
+ case "commit":
45
+ return filterGitCommit(rawOutput);
46
+ case "fetch":
47
+ return filterGitFetch(rawOutput);
48
+ case "branch":
49
+ return filterGitBranch(rawOutput, level);
50
+ case "stash":
51
+ return filterGitStash(rawOutput);
52
+ default:
53
+ return { output: rawOutput, strategy: "git:passthrough" };
54
+ }
55
+ }
56
+ };
57
+ function extractGitSubcommand(command) {
58
+ const match = command.match(/git\s+(\w+)/);
59
+ return match ? match[1] : "";
60
+ }
61
+ function filterGitStatus(raw, level) {
62
+ const lines = raw.split("\n").filter((l) => l.trim());
63
+ if (raw.includes("nothing to commit") || raw.includes("working tree clean")) {
64
+ return { output: "clean", strategy: "git:status:clean" };
65
+ }
66
+ const staged = [];
67
+ const modified = [];
68
+ const untracked = [];
69
+ const deleted = [];
70
+ const renamed = [];
71
+ let section = "";
72
+ for (const line of lines) {
73
+ if (line.includes("Changes to be committed")) {
74
+ section = "staged";
75
+ continue;
76
+ }
77
+ if (line.includes("Changes not staged")) {
78
+ section = "unstaged";
79
+ continue;
80
+ }
81
+ if (line.includes("Untracked files")) {
82
+ section = "untracked";
83
+ continue;
84
+ }
85
+ if (line.startsWith(" (use")) continue;
86
+ if (line.startsWith("On branch") || line.startsWith("Your branch")) continue;
87
+ const trimmed = line.trim();
88
+ if (!trimmed) continue;
89
+ const shortMatch = trimmed.match(/^([MADRCU?! ]{1,2})\s+(.+)$/);
90
+ if (shortMatch) {
91
+ const [, status, file] = shortMatch;
92
+ if (status.includes("M")) modified.push(file);
93
+ else if (status.includes("A")) staged.push(file);
94
+ else if (status.includes("D")) deleted.push(file);
95
+ else if (status.includes("R")) renamed.push(file);
96
+ else if (status.includes("?")) untracked.push(file);
97
+ continue;
98
+ }
99
+ if (section === "staged") {
100
+ const m = trimmed.match(/(?:new file|modified|deleted|renamed):\s+(.+)/);
101
+ if (m) staged.push(m[1]);
102
+ } else if (section === "unstaged") {
103
+ const m = trimmed.match(/(?:modified|deleted):\s+(.+)/);
104
+ if (m) modified.push(m[1]);
105
+ } else if (section === "untracked") {
106
+ if (!trimmed.startsWith("(")) untracked.push(trimmed);
107
+ }
108
+ }
109
+ if (level === "ultra") {
110
+ const parts2 = [];
111
+ if (staged.length) parts2.push(`S:${staged.length}`);
112
+ if (modified.length) parts2.push(`M:${modified.length}`);
113
+ if (deleted.length) parts2.push(`D:${deleted.length}`);
114
+ if (untracked.length) parts2.push(`?:${untracked.length}`);
115
+ if (renamed.length) parts2.push(`R:${renamed.length}`);
116
+ return { output: parts2.join(" ") || "clean", strategy: "git:status:ultra" };
117
+ }
118
+ const parts = [];
119
+ if (staged.length) parts.push(`Staged (${staged.length}): ${groupByDir(staged, level)}`);
120
+ if (modified.length) parts.push(`Modified (${modified.length}): ${groupByDir(modified, level)}`);
121
+ if (deleted.length) parts.push(`Deleted (${deleted.length}): ${groupByDir(deleted, level)}`);
122
+ if (untracked.length) parts.push(`Untracked (${untracked.length}): ${groupByDir(untracked, level)}`);
123
+ if (renamed.length) parts.push(`Renamed (${renamed.length}): ${groupByDir(renamed, level)}`);
124
+ return { output: parts.join("\n") || raw, strategy: "git:status" };
125
+ }
126
+ function filterGitLog(raw, level) {
127
+ const lines = raw.split("\n");
128
+ if (lines.every((l) => !l.startsWith("commit ") && !l.startsWith("Author:"))) {
129
+ const filtered = lines.filter((l) => l.trim()).slice(0, level === "ultra" ? 10 : 20);
130
+ return { output: filtered.join("\n"), strategy: "git:log:oneline" };
131
+ }
132
+ const commits = [];
133
+ let currentHash = "";
134
+ let currentMsg = "";
135
+ for (const line of lines) {
136
+ if (line.startsWith("commit ")) {
137
+ if (currentHash && currentMsg) {
138
+ commits.push(`${currentHash.slice(0, 7)} ${currentMsg.trim()}`);
139
+ }
140
+ currentHash = line.replace("commit ", "").trim();
141
+ currentMsg = "";
142
+ } else if (!line.startsWith("Author:") && !line.startsWith("Date:") && !line.startsWith("Merge:")) {
143
+ if (line.trim()) currentMsg = currentMsg || line.trim();
144
+ }
145
+ }
146
+ if (currentHash && currentMsg) {
147
+ commits.push(`${currentHash.slice(0, 7)} ${currentMsg.trim()}`);
148
+ }
149
+ const limit = level === "ultra" ? 10 : 20;
150
+ const output = commits.slice(0, limit).join("\n");
151
+ return { output: output || raw, strategy: "git:log" };
152
+ }
153
+ function filterGitDiff(raw, level) {
154
+ const lines = raw.split("\n");
155
+ const result = [];
156
+ let contextLines = level === "ultra" ? 1 : level === "aggressive" ? 2 : 3;
157
+ let inHunk = false;
158
+ let afterChange = 0;
159
+ let contextBuffer = [];
160
+ for (const line of lines) {
161
+ if (line.startsWith("diff --git") || line.startsWith("---") || line.startsWith("+++")) {
162
+ result.push(line);
163
+ inHunk = false;
164
+ contextBuffer = [];
165
+ continue;
166
+ }
167
+ if (line.startsWith("@@")) {
168
+ result.push(line);
169
+ inHunk = true;
170
+ afterChange = 0;
171
+ contextBuffer = [];
172
+ continue;
173
+ }
174
+ if (!inHunk) continue;
175
+ if (line.startsWith("+") || line.startsWith("-")) {
176
+ if (contextBuffer.length > 0) {
177
+ const keep = contextBuffer.slice(-contextLines);
178
+ result.push(...keep);
179
+ contextBuffer = [];
180
+ }
181
+ result.push(line);
182
+ afterChange = 0;
183
+ continue;
184
+ }
185
+ afterChange++;
186
+ if (afterChange <= contextLines) {
187
+ result.push(line);
188
+ } else {
189
+ contextBuffer.push(line);
190
+ }
191
+ }
192
+ return { output: result.join("\n"), strategy: "git:diff" };
193
+ }
194
+ function filterGitPush(raw) {
195
+ const branchMatch = raw.match(/(\S+)\s*->\s*(\S+)/);
196
+ if (branchMatch) {
197
+ return { output: `ok ${branchMatch[1]} \u2192 ${branchMatch[2]}`, strategy: "git:push" };
198
+ }
199
+ if (raw.includes("Everything up-to-date")) {
200
+ return { output: "ok (up-to-date)", strategy: "git:push" };
201
+ }
202
+ const meaningful = raw.split("\n").filter((l) => l.trim() && !l.includes("Enumerating") && !l.includes("Counting") && !l.includes("Compressing") && !l.includes("Writing"));
203
+ return { output: meaningful.pop() || "ok", strategy: "git:push" };
204
+ }
205
+ function filterGitPull(raw) {
206
+ if (raw.includes("Already up to date")) {
207
+ return { output: "ok (up-to-date)", strategy: "git:pull" };
208
+ }
209
+ const filesMatch = raw.match(/(\d+)\s+file/);
210
+ const insertMatch = raw.match(/(\d+)\s+insertion/);
211
+ const deleteMatch = raw.match(/(\d+)\s+deletion/);
212
+ const files = filesMatch ? filesMatch[1] : "0";
213
+ const ins = insertMatch ? `+${insertMatch[1]}` : "+0";
214
+ const del = deleteMatch ? `-${deleteMatch[1]}` : "-0";
215
+ return { output: `ok ${files} files ${ins} ${del}`, strategy: "git:pull" };
216
+ }
217
+ function filterGitAdd(raw) {
218
+ if (!raw.trim()) return { output: "ok", strategy: "git:add" };
219
+ return { output: raw.trim() || "ok", strategy: "git:add" };
220
+ }
221
+ function filterGitCommit(raw) {
222
+ const hashMatch = raw.match(/\[[\w/]+\s+([a-f0-9]+)\]/);
223
+ if (hashMatch) {
224
+ return { output: `ok ${hashMatch[1]}`, strategy: "git:commit" };
225
+ }
226
+ const firstLine = raw.split("\n").find((l) => l.trim());
227
+ return { output: firstLine || "ok", strategy: "git:commit" };
228
+ }
229
+ function filterGitFetch(raw) {
230
+ if (!raw.trim()) return { output: "ok", strategy: "git:fetch" };
231
+ const lines = raw.split("\n").filter((l) => l.trim() && !l.startsWith("remote:"));
232
+ return { output: lines.length > 0 ? lines.join("\n") : "ok", strategy: "git:fetch" };
233
+ }
234
+ function filterGitBranch(raw, level) {
235
+ const lines = raw.split("\n").filter((l) => l.trim());
236
+ const current = lines.find((l) => l.startsWith("*"));
237
+ const others = lines.filter((l) => !l.startsWith("*")).map((l) => l.trim());
238
+ if (level === "ultra") {
239
+ return {
240
+ output: `* ${current?.replace("*", "").trim() || "?"} (+${others.length} branches)`,
241
+ strategy: "git:branch:ultra"
242
+ };
243
+ }
244
+ const limit = level === "aggressive" ? 10 : 20;
245
+ const shown = others.slice(0, limit);
246
+ const parts = [current || "* (unknown)"];
247
+ parts.push(...shown);
248
+ if (others.length > limit) parts.push(` \u2026and ${others.length - limit} more`);
249
+ return { output: parts.join("\n"), strategy: "git:branch" };
250
+ }
251
+ function filterGitStash(raw) {
252
+ const lines = raw.split("\n").filter((l) => l.trim());
253
+ if (lines.length === 0) return { output: "ok", strategy: "git:stash" };
254
+ return { output: lines.slice(0, 10).join("\n"), strategy: "git:stash" };
255
+ }
256
+ function groupByDir(files, level) {
257
+ if (level === "aggressive" || level === "ultra") {
258
+ const dirs = /* @__PURE__ */ new Map();
259
+ for (const f of files) {
260
+ const dir = f.includes("/") ? f.slice(0, f.lastIndexOf("/")) : ".";
261
+ dirs.set(dir, (dirs.get(dir) || 0) + 1);
262
+ }
263
+ return [...dirs.entries()].map(([d, c]) => `${d}/ (${c})`).join(", ");
264
+ }
265
+ if (files.length <= 5) return files.join(", ");
266
+ return files.slice(0, 5).join(", ") + ` \u2026+${files.length - 5} more`;
267
+ }
268
+ // Annotate the CommonJS export names for ESM import in node:
269
+ 0 && (module.exports = {
270
+ gitFilter
271
+ });
272
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/compression/filters/git.ts"],
4
+ "sourcesContent": ["/**\n * Git command output filters\n */\n\nimport type { CommandFilter, FilterResult, CompressorOptions } from '../types';\n\nexport const gitFilter: CommandFilter = {\n name: 'git',\n\n matches(command: string): boolean {\n return /^\\s*(git\\s|rtk\\s+git\\s)/.test(command);\n },\n\n filter(command: string, rawOutput: string, level: CompressorOptions['level']): FilterResult {\n const subcommand = extractGitSubcommand(command);\n\n switch (subcommand) {\n case 'status': return filterGitStatus(rawOutput, level);\n case 'log': return filterGitLog(rawOutput, level);\n case 'diff': return filterGitDiff(rawOutput, level);\n case 'push': return filterGitPush(rawOutput);\n case 'pull': return filterGitPull(rawOutput);\n case 'add': return filterGitAdd(rawOutput);\n case 'commit': return filterGitCommit(rawOutput);\n case 'fetch': return filterGitFetch(rawOutput);\n case 'branch': return filterGitBranch(rawOutput, level);\n case 'stash': return filterGitStash(rawOutput);\n default: return { output: rawOutput, strategy: 'git:passthrough' };\n }\n },\n};\n\nfunction extractGitSubcommand(command: string): string {\n const match = command.match(/git\\s+(\\w+)/);\n return match ? match[1] : '';\n}\n\nfunction filterGitStatus(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n\n // Detect clean state\n if (raw.includes('nothing to commit') || raw.includes('working tree clean')) {\n return { output: 'clean', strategy: 'git:status:clean' };\n }\n\n const staged: string[] = [];\n const modified: string[] = [];\n const untracked: string[] = [];\n const deleted: string[] = [];\n const renamed: string[] = [];\n\n let section = '';\n for (const line of lines) {\n if (line.includes('Changes to be committed')) { section = 'staged'; continue; }\n if (line.includes('Changes not staged')) { section = 'unstaged'; continue; }\n if (line.includes('Untracked files')) { section = 'untracked'; continue; }\n if (line.startsWith(' (use')) continue; // hint lines\n if (line.startsWith('On branch') || line.startsWith('Your branch')) continue;\n\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n // Short format (git status -s) or porcelain\n const shortMatch = trimmed.match(/^([MADRCU?! ]{1,2})\\s+(.+)$/);\n if (shortMatch) {\n const [, status, file] = shortMatch;\n if (status.includes('M')) modified.push(file);\n else if (status.includes('A')) staged.push(file);\n else if (status.includes('D')) deleted.push(file);\n else if (status.includes('R')) renamed.push(file);\n else if (status.includes('?')) untracked.push(file);\n continue;\n }\n\n // Long format\n if (section === 'staged') {\n const m = trimmed.match(/(?:new file|modified|deleted|renamed):\\s+(.+)/);\n if (m) staged.push(m[1]);\n } else if (section === 'unstaged') {\n const m = trimmed.match(/(?:modified|deleted):\\s+(.+)/);\n if (m) modified.push(m[1]);\n } else if (section === 'untracked') {\n if (!trimmed.startsWith('(')) untracked.push(trimmed);\n }\n }\n\n if (level === 'ultra') {\n const parts: string[] = [];\n if (staged.length) parts.push(`S:${staged.length}`);\n if (modified.length) parts.push(`M:${modified.length}`);\n if (deleted.length) parts.push(`D:${deleted.length}`);\n if (untracked.length) parts.push(`?:${untracked.length}`);\n if (renamed.length) parts.push(`R:${renamed.length}`);\n return { output: parts.join(' ') || 'clean', strategy: 'git:status:ultra' };\n }\n\n const parts: string[] = [];\n if (staged.length) parts.push(`Staged (${staged.length}): ${groupByDir(staged, level)}`);\n if (modified.length) parts.push(`Modified (${modified.length}): ${groupByDir(modified, level)}`);\n if (deleted.length) parts.push(`Deleted (${deleted.length}): ${groupByDir(deleted, level)}`);\n if (untracked.length) parts.push(`Untracked (${untracked.length}): ${groupByDir(untracked, level)}`);\n if (renamed.length) parts.push(`Renamed (${renamed.length}): ${groupByDir(renamed, level)}`);\n\n return { output: parts.join('\\n') || raw, strategy: 'git:status' };\n}\n\nfunction filterGitLog(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n');\n\n // Already one-line format\n if (lines.every(l => !l.startsWith('commit ') && !l.startsWith('Author:'))) {\n const filtered = lines.filter(l => l.trim()).slice(0, level === 'ultra' ? 10 : 20);\n return { output: filtered.join('\\n'), strategy: 'git:log:oneline' };\n }\n\n // Parse full format into one-line\n const commits: string[] = [];\n let currentHash = '';\n let currentMsg = '';\n\n for (const line of lines) {\n if (line.startsWith('commit ')) {\n if (currentHash && currentMsg) {\n commits.push(`${currentHash.slice(0, 7)} ${currentMsg.trim()}`);\n }\n currentHash = line.replace('commit ', '').trim();\n currentMsg = '';\n } else if (!line.startsWith('Author:') && !line.startsWith('Date:') && !line.startsWith('Merge:')) {\n if (line.trim()) currentMsg = currentMsg || line.trim();\n }\n }\n if (currentHash && currentMsg) {\n commits.push(`${currentHash.slice(0, 7)} ${currentMsg.trim()}`);\n }\n\n const limit = level === 'ultra' ? 10 : 20;\n const output = commits.slice(0, limit).join('\\n');\n return { output: output || raw, strategy: 'git:log' };\n}\n\nfunction filterGitDiff(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n');\n const result: string[] = [];\n let contextLines = level === 'ultra' ? 1 : level === 'aggressive' ? 2 : 3;\n let inHunk = false;\n let afterChange = 0;\n let contextBuffer: string[] = [];\n\n for (const line of lines) {\n // Keep file headers\n if (line.startsWith('diff --git') || line.startsWith('---') || line.startsWith('+++')) {\n result.push(line);\n inHunk = false;\n contextBuffer = [];\n continue;\n }\n\n // Keep hunk headers\n if (line.startsWith('@@')) {\n result.push(line);\n inHunk = true;\n afterChange = 0;\n contextBuffer = [];\n continue;\n }\n\n if (!inHunk) continue;\n\n // Changed lines \u2014 always keep\n if (line.startsWith('+') || line.startsWith('-')) {\n // Flush context buffer (last N lines before change)\n if (contextBuffer.length > 0) {\n const keep = contextBuffer.slice(-contextLines);\n result.push(...keep);\n contextBuffer = [];\n }\n result.push(line);\n afterChange = 0;\n continue;\n }\n\n // Context lines after a change\n afterChange++;\n if (afterChange <= contextLines) {\n result.push(line);\n } else {\n contextBuffer.push(line);\n }\n }\n\n return { output: result.join('\\n'), strategy: 'git:diff' };\n}\n\nfunction filterGitPush(raw: string): FilterResult {\n // Extract branch and remote info\n const branchMatch = raw.match(/(\\S+)\\s*->\\s*(\\S+)/);\n if (branchMatch) {\n return { output: `ok ${branchMatch[1]} \u2192 ${branchMatch[2]}`, strategy: 'git:push' };\n }\n if (raw.includes('Everything up-to-date')) {\n return { output: 'ok (up-to-date)', strategy: 'git:push' };\n }\n // Fallback: just show last meaningful line\n const meaningful = raw.split('\\n').filter(l => l.trim() && !l.includes('Enumerating') && !l.includes('Counting') && !l.includes('Compressing') && !l.includes('Writing'));\n return { output: meaningful.pop() || 'ok', strategy: 'git:push' };\n}\n\nfunction filterGitPull(raw: string): FilterResult {\n if (raw.includes('Already up to date')) {\n return { output: 'ok (up-to-date)', strategy: 'git:pull' };\n }\n\n const filesMatch = raw.match(/(\\d+)\\s+file/);\n const insertMatch = raw.match(/(\\d+)\\s+insertion/);\n const deleteMatch = raw.match(/(\\d+)\\s+deletion/);\n\n const files = filesMatch ? filesMatch[1] : '0';\n const ins = insertMatch ? `+${insertMatch[1]}` : '+0';\n const del = deleteMatch ? `-${deleteMatch[1]}` : '-0';\n\n return { output: `ok ${files} files ${ins} ${del}`, strategy: 'git:pull' };\n}\n\nfunction filterGitAdd(raw: string): FilterResult {\n // git add produces no output on success\n if (!raw.trim()) return { output: 'ok', strategy: 'git:add' };\n return { output: raw.trim() || 'ok', strategy: 'git:add' };\n}\n\nfunction filterGitCommit(raw: string): FilterResult {\n const hashMatch = raw.match(/\\[[\\w/]+\\s+([a-f0-9]+)\\]/);\n if (hashMatch) {\n return { output: `ok ${hashMatch[1]}`, strategy: 'git:commit' };\n }\n // Fallback\n const firstLine = raw.split('\\n').find(l => l.trim());\n return { output: firstLine || 'ok', strategy: 'git:commit' };\n}\n\nfunction filterGitFetch(raw: string): FilterResult {\n if (!raw.trim()) return { output: 'ok', strategy: 'git:fetch' };\n const lines = raw.split('\\n').filter(l => l.trim() && !l.startsWith('remote:'));\n return { output: lines.length > 0 ? lines.join('\\n') : 'ok', strategy: 'git:fetch' };\n}\n\nfunction filterGitBranch(raw: string, level: CompressorOptions['level']): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n const current = lines.find(l => l.startsWith('*'));\n const others = lines.filter(l => !l.startsWith('*')).map(l => l.trim());\n\n if (level === 'ultra') {\n return {\n output: `* ${current?.replace('*', '').trim() || '?'} (+${others.length} branches)`,\n strategy: 'git:branch:ultra',\n };\n }\n\n const limit = level === 'aggressive' ? 10 : 20;\n const shown = others.slice(0, limit);\n const parts = [current || '* (unknown)'];\n parts.push(...shown);\n if (others.length > limit) parts.push(` \u2026and ${others.length - limit} more`);\n\n return { output: parts.join('\\n'), strategy: 'git:branch' };\n}\n\nfunction filterGitStash(raw: string): FilterResult {\n const lines = raw.split('\\n').filter(l => l.trim());\n if (lines.length === 0) return { output: 'ok', strategy: 'git:stash' };\n return { output: lines.slice(0, 10).join('\\n'), strategy: 'git:stash' };\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 groupByDir(files: string[], level: CompressorOptions['level']): string {\n if (level === 'aggressive' || level === 'ultra') {\n const dirs = new Map<string, number>();\n for (const f of files) {\n const dir = f.includes('/') ? f.slice(0, f.lastIndexOf('/')) : '.';\n dirs.set(dir, (dirs.get(dir) || 0) + 1);\n }\n return [...dirs.entries()].map(([d, c]) => `${d}/ (${c})`).join(', ');\n }\n // Normal: show up to 5 files, then count\n if (files.length <= 5) return files.join(', ');\n return files.slice(0, 5).join(', ') + ` \u2026+${files.length - 5} more`;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,MAAM,YAA2B;AAAA,EACtC,MAAM;AAAA,EAEN,QAAQ,SAA0B;AAChC,WAAO,0BAA0B,KAAK,OAAO;AAAA,EAC/C;AAAA,EAEA,OAAO,SAAiB,WAAmB,OAAiD;AAC1F,UAAM,aAAa,qBAAqB,OAAO;AAE/C,YAAQ,YAAY;AAAA,MAClB,KAAK;AAAU,eAAO,gBAAgB,WAAW,KAAK;AAAA,MACtD,KAAK;AAAO,eAAO,aAAa,WAAW,KAAK;AAAA,MAChD,KAAK;AAAQ,eAAO,cAAc,WAAW,KAAK;AAAA,MAClD,KAAK;AAAQ,eAAO,cAAc,SAAS;AAAA,MAC3C,KAAK;AAAQ,eAAO,cAAc,SAAS;AAAA,MAC3C,KAAK;AAAO,eAAO,aAAa,SAAS;AAAA,MACzC,KAAK;AAAU,eAAO,gBAAgB,SAAS;AAAA,MAC/C,KAAK;AAAS,eAAO,eAAe,SAAS;AAAA,MAC7C,KAAK;AAAU,eAAO,gBAAgB,WAAW,KAAK;AAAA,MACtD,KAAK;AAAS,eAAO,eAAe,SAAS;AAAA,MAC7C;AAAS,eAAO,EAAE,QAAQ,WAAW,UAAU,kBAAkB;AAAA,IACnE;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,SAAyB;AACrD,QAAM,QAAQ,QAAQ,MAAM,aAAa;AACzC,SAAO,QAAQ,MAAM,CAAC,IAAI;AAC5B;AAEA,SAAS,gBAAgB,KAAa,OAAiD;AACrF,QAAM,QAAQ,IAAI,MAAM,IAAI,EAAE,OAAO,OAAK,EAAE,KAAK,CAAC;AAGlD,MAAI,IAAI,SAAS,mBAAmB,KAAK,IAAI,SAAS,oBAAoB,GAAG;AAC3E,WAAO,EAAE,QAAQ,SAAS,UAAU,mBAAmB;AAAA,EACzD;AAEA,QAAM,SAAmB,CAAC;AAC1B,QAAM,WAAqB,CAAC;AAC5B,QAAM,YAAsB,CAAC;AAC7B,QAAM,UAAoB,CAAC;AAC3B,QAAM,UAAoB,CAAC;AAE3B,MAAI,UAAU;AACd,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,yBAAyB,GAAG;AAAE,gBAAU;AAAU;AAAA,IAAU;AAC9E,QAAI,KAAK,SAAS,oBAAoB,GAAG;AAAE,gBAAU;AAAY;AAAA,IAAU;AAC3E,QAAI,KAAK,SAAS,iBAAiB,GAAG;AAAE,gBAAU;AAAa;AAAA,IAAU;AACzE,QAAI,KAAK,WAAW,QAAQ,EAAG;AAC/B,QAAI,KAAK,WAAW,WAAW,KAAK,KAAK,WAAW,aAAa,EAAG;AAEpE,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,QAAS;AAGd,UAAM,aAAa,QAAQ,MAAM,6BAA6B;AAC9D,QAAI,YAAY;AACd,YAAM,CAAC,EAAE,QAAQ,IAAI,IAAI;AACzB,UAAI,OAAO,SAAS,GAAG,EAAG,UAAS,KAAK,IAAI;AAAA,eACnC,OAAO,SAAS,GAAG,EAAG,QAAO,KAAK,IAAI;AAAA,eACtC,OAAO,SAAS,GAAG,EAAG,SAAQ,KAAK,IAAI;AAAA,eACvC,OAAO,SAAS,GAAG,EAAG,SAAQ,KAAK,IAAI;AAAA,eACvC,OAAO,SAAS,GAAG,EAAG,WAAU,KAAK,IAAI;AAClD;AAAA,IACF;AAGA,QAAI,YAAY,UAAU;AACxB,YAAM,IAAI,QAAQ,MAAM,+CAA+C;AACvE,UAAI,EAAG,QAAO,KAAK,EAAE,CAAC,CAAC;AAAA,IACzB,WAAW,YAAY,YAAY;AACjC,YAAM,IAAI,QAAQ,MAAM,8BAA8B;AACtD,UAAI,EAAG,UAAS,KAAK,EAAE,CAAC,CAAC;AAAA,IAC3B,WAAW,YAAY,aAAa;AAClC,UAAI,CAAC,QAAQ,WAAW,GAAG,EAAG,WAAU,KAAK,OAAO;AAAA,IACtD;AAAA,EACF;AAEA,MAAI,UAAU,SAAS;AACrB,UAAMA,SAAkB,CAAC;AACzB,QAAI,OAAO,OAAQ,CAAAA,OAAM,KAAK,KAAK,OAAO,MAAM,EAAE;AAClD,QAAI,SAAS,OAAQ,CAAAA,OAAM,KAAK,KAAK,SAAS,MAAM,EAAE;AACtD,QAAI,QAAQ,OAAQ,CAAAA,OAAM,KAAK,KAAK,QAAQ,MAAM,EAAE;AACpD,QAAI,UAAU,OAAQ,CAAAA,OAAM,KAAK,KAAK,UAAU,MAAM,EAAE;AACxD,QAAI,QAAQ,OAAQ,CAAAA,OAAM,KAAK,KAAK,QAAQ,MAAM,EAAE;AACpD,WAAO,EAAE,QAAQA,OAAM,KAAK,GAAG,KAAK,SAAS,UAAU,mBAAmB;AAAA,EAC5E;AAEA,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAO,OAAQ,OAAM,KAAK,WAAW,OAAO,MAAM,MAAM,WAAW,QAAQ,KAAK,CAAC,EAAE;AACvF,MAAI,SAAS,OAAQ,OAAM,KAAK,aAAa,SAAS,MAAM,MAAM,WAAW,UAAU,KAAK,CAAC,EAAE;AAC/F,MAAI,QAAQ,OAAQ,OAAM,KAAK,YAAY,QAAQ,MAAM,MAAM,WAAW,SAAS,KAAK,CAAC,EAAE;AAC3F,MAAI,UAAU,OAAQ,OAAM,KAAK,cAAc,UAAU,MAAM,MAAM,WAAW,WAAW,KAAK,CAAC,EAAE;AACnG,MAAI,QAAQ,OAAQ,OAAM,KAAK,YAAY,QAAQ,MAAM,MAAM,WAAW,SAAS,KAAK,CAAC,EAAE;AAE3F,SAAO,EAAE,QAAQ,MAAM,KAAK,IAAI,KAAK,KAAK,UAAU,aAAa;AACnE;AAEA,SAAS,aAAa,KAAa,OAAiD;AAClF,QAAM,QAAQ,IAAI,MAAM,IAAI;AAG5B,MAAI,MAAM,MAAM,OAAK,CAAC,EAAE,WAAW,SAAS,KAAK,CAAC,EAAE,WAAW,SAAS,CAAC,GAAG;AAC1E,UAAM,WAAW,MAAM,OAAO,OAAK,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU,UAAU,KAAK,EAAE;AACjF,WAAO,EAAE,QAAQ,SAAS,KAAK,IAAI,GAAG,UAAU,kBAAkB;AAAA,EACpE;AAGA,QAAM,UAAoB,CAAC;AAC3B,MAAI,cAAc;AAClB,MAAI,aAAa;AAEjB,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,SAAS,GAAG;AAC9B,UAAI,eAAe,YAAY;AAC7B,gBAAQ,KAAK,GAAG,YAAY,MAAM,GAAG,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,EAAE;AAAA,MAChE;AACA,oBAAc,KAAK,QAAQ,WAAW,EAAE,EAAE,KAAK;AAC/C,mBAAa;AAAA,IACf,WAAW,CAAC,KAAK,WAAW,SAAS,KAAK,CAAC,KAAK,WAAW,OAAO,KAAK,CAAC,KAAK,WAAW,QAAQ,GAAG;AACjG,UAAI,KAAK,KAAK,EAAG,cAAa,cAAc,KAAK,KAAK;AAAA,IACxD;AAAA,EACF;AACA,MAAI,eAAe,YAAY;AAC7B,YAAQ,KAAK,GAAG,YAAY,MAAM,GAAG,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,EAAE;AAAA,EAChE;AAEA,QAAM,QAAQ,UAAU,UAAU,KAAK;AACvC,QAAM,SAAS,QAAQ,MAAM,GAAG,KAAK,EAAE,KAAK,IAAI;AAChD,SAAO,EAAE,QAAQ,UAAU,KAAK,UAAU,UAAU;AACtD;AAEA,SAAS,cAAc,KAAa,OAAiD;AACnF,QAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,QAAM,SAAmB,CAAC;AAC1B,MAAI,eAAe,UAAU,UAAU,IAAI,UAAU,eAAe,IAAI;AACxE,MAAI,SAAS;AACb,MAAI,cAAc;AAClB,MAAI,gBAA0B,CAAC;AAE/B,aAAW,QAAQ,OAAO;AAExB,QAAI,KAAK,WAAW,YAAY,KAAK,KAAK,WAAW,KAAK,KAAK,KAAK,WAAW,KAAK,GAAG;AACrF,aAAO,KAAK,IAAI;AAChB,eAAS;AACT,sBAAgB,CAAC;AACjB;AAAA,IACF;AAGA,QAAI,KAAK,WAAW,IAAI,GAAG;AACzB,aAAO,KAAK,IAAI;AAChB,eAAS;AACT,oBAAc;AACd,sBAAgB,CAAC;AACjB;AAAA,IACF;AAEA,QAAI,CAAC,OAAQ;AAGb,QAAI,KAAK,WAAW,GAAG,KAAK,KAAK,WAAW,GAAG,GAAG;AAEhD,UAAI,cAAc,SAAS,GAAG;AAC5B,cAAM,OAAO,cAAc,MAAM,CAAC,YAAY;AAC9C,eAAO,KAAK,GAAG,IAAI;AACnB,wBAAgB,CAAC;AAAA,MACnB;AACA,aAAO,KAAK,IAAI;AAChB,oBAAc;AACd;AAAA,IACF;AAGA;AACA,QAAI,eAAe,cAAc;AAC/B,aAAO,KAAK,IAAI;AAAA,IAClB,OAAO;AACL,oBAAc,KAAK,IAAI;AAAA,IACzB;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,OAAO,KAAK,IAAI,GAAG,UAAU,WAAW;AAC3D;AAEA,SAAS,cAAc,KAA2B;AAEhD,QAAM,cAAc,IAAI,MAAM,oBAAoB;AAClD,MAAI,aAAa;AACf,WAAO,EAAE,QAAQ,MAAM,YAAY,CAAC,CAAC,WAAM,YAAY,CAAC,CAAC,IAAI,UAAU,WAAW;AAAA,EACpF;AACA,MAAI,IAAI,SAAS,uBAAuB,GAAG;AACzC,WAAO,EAAE,QAAQ,mBAAmB,UAAU,WAAW;AAAA,EAC3D;AAEA,QAAM,aAAa,IAAI,MAAM,IAAI,EAAE,OAAO,OAAK,EAAE,KAAK,KAAK,CAAC,EAAE,SAAS,aAAa,KAAK,CAAC,EAAE,SAAS,UAAU,KAAK,CAAC,EAAE,SAAS,aAAa,KAAK,CAAC,EAAE,SAAS,SAAS,CAAC;AACxK,SAAO,EAAE,QAAQ,WAAW,IAAI,KAAK,MAAM,UAAU,WAAW;AAClE;AAEA,SAAS,cAAc,KAA2B;AAChD,MAAI,IAAI,SAAS,oBAAoB,GAAG;AACtC,WAAO,EAAE,QAAQ,mBAAmB,UAAU,WAAW;AAAA,EAC3D;AAEA,QAAM,aAAa,IAAI,MAAM,cAAc;AAC3C,QAAM,cAAc,IAAI,MAAM,mBAAmB;AACjD,QAAM,cAAc,IAAI,MAAM,kBAAkB;AAEhD,QAAM,QAAQ,aAAa,WAAW,CAAC,IAAI;AAC3C,QAAM,MAAM,cAAc,IAAI,YAAY,CAAC,CAAC,KAAK;AACjD,QAAM,MAAM,cAAc,IAAI,YAAY,CAAC,CAAC,KAAK;AAEjD,SAAO,EAAE,QAAQ,MAAM,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,UAAU,WAAW;AAC3E;AAEA,SAAS,aAAa,KAA2B;AAE/C,MAAI,CAAC,IAAI,KAAK,EAAG,QAAO,EAAE,QAAQ,MAAM,UAAU,UAAU;AAC5D,SAAO,EAAE,QAAQ,IAAI,KAAK,KAAK,MAAM,UAAU,UAAU;AAC3D;AAEA,SAAS,gBAAgB,KAA2B;AAClD,QAAM,YAAY,IAAI,MAAM,0BAA0B;AACtD,MAAI,WAAW;AACb,WAAO,EAAE,QAAQ,MAAM,UAAU,CAAC,CAAC,IAAI,UAAU,aAAa;AAAA,EAChE;AAEA,QAAM,YAAY,IAAI,MAAM,IAAI,EAAE,KAAK,OAAK,EAAE,KAAK,CAAC;AACpD,SAAO,EAAE,QAAQ,aAAa,MAAM,UAAU,aAAa;AAC7D;AAEA,SAAS,eAAe,KAA2B;AACjD,MAAI,CAAC,IAAI,KAAK,EAAG,QAAO,EAAE,QAAQ,MAAM,UAAU,YAAY;AAC9D,QAAM,QAAQ,IAAI,MAAM,IAAI,EAAE,OAAO,OAAK,EAAE,KAAK,KAAK,CAAC,EAAE,WAAW,SAAS,CAAC;AAC9E,SAAO,EAAE,QAAQ,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,UAAU,YAAY;AACrF;AAEA,SAAS,gBAAgB,KAAa,OAAiD;AACrF,QAAM,QAAQ,IAAI,MAAM,IAAI,EAAE,OAAO,OAAK,EAAE,KAAK,CAAC;AAClD,QAAM,UAAU,MAAM,KAAK,OAAK,EAAE,WAAW,GAAG,CAAC;AACjD,QAAM,SAAS,MAAM,OAAO,OAAK,CAAC,EAAE,WAAW,GAAG,CAAC,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAEtE,MAAI,UAAU,SAAS;AACrB,WAAO;AAAA,MACL,QAAQ,KAAK,SAAS,QAAQ,KAAK,EAAE,EAAE,KAAK,KAAK,GAAG,MAAM,OAAO,MAAM;AAAA,MACvE,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,QAAQ,UAAU,eAAe,KAAK;AAC5C,QAAM,QAAQ,OAAO,MAAM,GAAG,KAAK;AACnC,QAAM,QAAQ,CAAC,WAAW,aAAa;AACvC,QAAM,KAAK,GAAG,KAAK;AACnB,MAAI,OAAO,SAAS,MAAO,OAAM,KAAK,eAAU,OAAO,SAAS,KAAK,OAAO;AAE5E,SAAO,EAAE,QAAQ,MAAM,KAAK,IAAI,GAAG,UAAU,aAAa;AAC5D;AAEA,SAAS,eAAe,KAA2B;AACjD,QAAM,QAAQ,IAAI,MAAM,IAAI,EAAE,OAAO,OAAK,EAAE,KAAK,CAAC;AAClD,MAAI,MAAM,WAAW,EAAG,QAAO,EAAE,QAAQ,MAAM,UAAU,YAAY;AACrE,SAAO,EAAE,QAAQ,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,GAAG,UAAU,YAAY;AACxE;AAIA,SAAS,WAAW,OAAiB,OAA2C;AAC9E,MAAI,UAAU,gBAAgB,UAAU,SAAS;AAC/C,UAAM,OAAO,oBAAI,IAAoB;AACrC,eAAW,KAAK,OAAO;AACrB,YAAM,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,MAAM,GAAG,EAAE,YAAY,GAAG,CAAC,IAAI;AAC/D,WAAK,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;AAAA,IACxC;AACA,WAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI;AAAA,EACtE;AAEA,MAAI,MAAM,UAAU,EAAG,QAAO,MAAM,KAAK,IAAI;AAC7C,SAAO,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,IAAI,WAAM,MAAM,SAAS,CAAC;AAC9D;",
6
+ "names": ["parts"]
7
+ }