@aexol/spectral 0.9.128 → 0.9.130

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 (36) hide show
  1. package/dist/agent/index.js +2 -2
  2. package/dist/extensions/code-order/analyzer.d.ts +47 -0
  3. package/dist/extensions/code-order/analyzer.d.ts.map +1 -0
  4. package/dist/extensions/code-order/analyzer.js +315 -0
  5. package/dist/extensions/code-order/heuristics.d.ts +37 -0
  6. package/dist/extensions/code-order/heuristics.d.ts.map +1 -0
  7. package/dist/extensions/code-order/heuristics.js +188 -0
  8. package/dist/extensions/code-order/index.d.ts +15 -0
  9. package/dist/extensions/code-order/index.d.ts.map +1 -0
  10. package/dist/extensions/code-order/index.js +76 -0
  11. package/dist/extensions/code-order/report.d.ts +14 -0
  12. package/dist/extensions/code-order/report.d.ts.map +1 -0
  13. package/dist/extensions/code-order/report.js +140 -0
  14. package/dist/extensions/code-order/types.d.ts +63 -0
  15. package/dist/extensions/code-order/types.d.ts.map +1 -0
  16. package/dist/extensions/code-order/types.js +7 -0
  17. package/dist/mcp/ui-stream-types.d.ts +2 -2
  18. package/dist/relay/dispatcher.d.ts.map +1 -1
  19. package/dist/relay/dispatcher.js +5 -4
  20. package/dist/sdk/coding-agent/core/extensions/native-extensions.d.ts.map +1 -1
  21. package/dist/sdk/coding-agent/core/extensions/native-extensions.js +11 -0
  22. package/dist/sdk/coding-agent/core/system-prompt.d.ts.map +1 -1
  23. package/dist/sdk/coding-agent/core/system-prompt.js +2 -0
  24. package/dist/sdk/coding-agent/core/tools/bash-blocklist.d.ts +42 -0
  25. package/dist/sdk/coding-agent/core/tools/bash-blocklist.d.ts.map +1 -0
  26. package/dist/sdk/coding-agent/core/tools/bash-blocklist.js +141 -0
  27. package/dist/sdk/coding-agent/core/tools/bash.d.ts.map +1 -1
  28. package/dist/sdk/coding-agent/core/tools/bash.js +5 -0
  29. package/dist/server/agent-bridge.d.ts.map +1 -1
  30. package/dist/server/agent-bridge.js +6 -3
  31. package/dist/server/error-humanizer.d.ts +31 -0
  32. package/dist/server/error-humanizer.d.ts.map +1 -0
  33. package/dist/server/error-humanizer.js +77 -0
  34. package/dist/server/session-stream.d.ts.map +1 -1
  35. package/dist/server/session-stream.js +7 -6
  36. package/package.json +1 -1
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Code Order — native spectral extension.
3
+ *
4
+ * Registers a single tool, `code_order_report`, that scans the current
5
+ * project's directory tree and returns a Markdown cleanup report: oversized
6
+ * files, deep nesting, empty folders/files, duplicate sibling names and
7
+ * single-child folders. Language-agnostic, read-only, zero configuration.
8
+ *
9
+ * The report is input for the agent — it deduces what to split or flatten
10
+ * outside of this extension. Tree-like structure is enforced separately via
11
+ * the system prompt guidelines (see system-prompt.ts).
12
+ */
13
+ import { resolve } from "node:path";
14
+ import { walkTree, computeMetrics } from "./analyzer.js";
15
+ import { runAllHeuristics } from "./heuristics.js";
16
+ import { renderReport } from "./report.js";
17
+ export default async function codeOrderExtension(ext) {
18
+ const tool = {
19
+ name: "code_order_report",
20
+ label: "Code Order Report",
21
+ description: "Analyze the current project's folder structure and file sizes, " +
22
+ "then generate a cleanup report with actionable findings: " +
23
+ "oversized files, deep nesting, empty folders, duplicate sibling names, single-child folders. " +
24
+ "Read-only, zero config. Use this to get input data before reorganizing code.",
25
+ promptSnippet: "`code_order_report` — analyze folder structure & sizes, generate cleanup report",
26
+ parameters: {
27
+ type: "object",
28
+ properties: {
29
+ path: {
30
+ type: "string",
31
+ description: "Directory to analyze. Default: current working directory.",
32
+ },
33
+ },
34
+ },
35
+ async execute(_toolCallId, params) {
36
+ const rawPath = params.path ?? process.cwd();
37
+ const root = resolve(rawPath);
38
+ try {
39
+ const { tree, allFiles, allFolders, maxDepth, fileCount } = await walkTree(root);
40
+ const metrics = computeMetrics(allFiles, allFolders, maxDepth);
41
+ const issues = runAllHeuristics(tree, allFiles, allFolders, metrics);
42
+ const result = {
43
+ root,
44
+ generatedAt: new Date().toISOString(),
45
+ metrics,
46
+ issues,
47
+ };
48
+ const report = renderReport(result);
49
+ const summary = `Analyzed ${fileCount.toLocaleString()} files across ` +
50
+ `${metrics.totalFolders.toLocaleString()} folders ` +
51
+ `(${(metrics.totalSize / (1024 * 1024)).toFixed(1)} MB). ` +
52
+ `Found ${issues.length} structural issue(s).`;
53
+ return {
54
+ content: [{ type: "text", text: report }],
55
+ details: {
56
+ summary,
57
+ fileCount,
58
+ folderCount: metrics.totalFolders,
59
+ totalSize: metrics.totalSize,
60
+ issueCount: issues.length,
61
+ root,
62
+ },
63
+ };
64
+ }
65
+ catch (err) {
66
+ const msg = err instanceof Error ? err.message : String(err);
67
+ return {
68
+ content: [{ type: "text", text: `❌ Code Order analysis failed: ${msg}` }],
69
+ details: { isError: true, error: msg, root },
70
+ };
71
+ }
72
+ },
73
+ };
74
+ ext.registerTool(tool);
75
+ process.stderr.write("[code-order] Registered code_order_report tool.\n");
76
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Code Order — Markdown report generator.
3
+ *
4
+ * Turns an {@link AnalysisResult} into a human/agent-readable Markdown report
5
+ * with a summary, prioritized issues, top largest files, and the extension
6
+ * distribution. The report is returned to the session so the LLM can deduce
7
+ * what to reorganize next.
8
+ */
9
+ import type { AnalysisResult } from "./types.js";
10
+ /**
11
+ * Render the full cleanup report as Markdown.
12
+ */
13
+ export declare function renderReport(result: AnalysisResult): string;
14
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/extensions/code-order/report.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,YAAY,CAAC;AAgDxE;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA0F3D"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Code Order — Markdown report generator.
3
+ *
4
+ * Turns an {@link AnalysisResult} into a human/agent-readable Markdown report
5
+ * with a summary, prioritized issues, top largest files, and the extension
6
+ * distribution. The report is returned to the session so the LLM can deduce
7
+ * what to reorganize next.
8
+ */
9
+ function formatBytes(n) {
10
+ if (n < 1024)
11
+ return `${n} B`;
12
+ if (n < 1024 * 1024)
13
+ return `${(n / 1024).toFixed(1)} KB`;
14
+ if (n < 1024 * 1024 * 1024)
15
+ return `${(n / (1024 * 1024)).toFixed(1)} MB`;
16
+ return `${(n / (1024 * 1024 * 1024)).toFixed(2)} GB`;
17
+ }
18
+ function severityEmoji(sev) {
19
+ switch (sev) {
20
+ case "critical":
21
+ return "🔴";
22
+ case "warning":
23
+ return "🟡";
24
+ default:
25
+ return "ℹ️";
26
+ }
27
+ }
28
+ function groupByType(issues) {
29
+ const out = new Map();
30
+ for (const i of issues) {
31
+ const arr = out.get(i.type) ?? [];
32
+ arr.push(i);
33
+ out.set(i.type, arr);
34
+ }
35
+ return out;
36
+ }
37
+ const ISSUE_TITLES = {
38
+ oversized_file: "Oversized files",
39
+ deep_nesting: "Deep nesting",
40
+ empty_folder: "Empty folders",
41
+ empty_file: "Empty files",
42
+ duplicate_names: "Duplicate sibling folder names",
43
+ single_child_folder: "Single-child folders",
44
+ };
45
+ const ISSUE_ORDER = [
46
+ "oversized_file",
47
+ "deep_nesting",
48
+ "duplicate_names",
49
+ "empty_folder",
50
+ "empty_file",
51
+ "single_child_folder",
52
+ ];
53
+ /**
54
+ * Render the full cleanup report as Markdown.
55
+ */
56
+ export function renderReport(result) {
57
+ const { root, generatedAt, metrics, issues } = result;
58
+ const lines = [];
59
+ lines.push(`# Code Order Report — ${root}`);
60
+ lines.push("");
61
+ lines.push(`_Generated: ${generatedAt}_`);
62
+ lines.push("");
63
+ // Summary
64
+ lines.push("## Summary");
65
+ lines.push("");
66
+ lines.push(`**${metrics.totalFiles.toLocaleString()} files** | ` +
67
+ `**${metrics.totalFolders.toLocaleString()} folders** | ` +
68
+ `**${formatBytes(metrics.totalSize)} total** | ` +
69
+ `max depth ${metrics.maxDepth}`);
70
+ lines.push("");
71
+ // Issues
72
+ if (issues.length === 0) {
73
+ lines.push("## Issues");
74
+ lines.push("");
75
+ lines.push("✅ No structural issues detected. The project looks tidy.");
76
+ lines.push("");
77
+ }
78
+ else {
79
+ const grouped = groupByType(issues);
80
+ const counts = { critical: 0, warning: 0, info: 0 };
81
+ for (const i of issues)
82
+ counts[i.severity]++;
83
+ lines.push(`## Issues (${issues.length})`);
84
+ lines.push("");
85
+ lines.push(`**${counts.critical} critical** · **${counts.warning} warnings** · **${counts.info} info**`);
86
+ lines.push("");
87
+ for (const type of ISSUE_ORDER) {
88
+ const group = grouped.get(type);
89
+ if (!group || group.length === 0)
90
+ continue;
91
+ const sev = group[0].severity;
92
+ lines.push(`### ${severityEmoji(sev)} ${ISSUE_TITLES[type]} (${group.length})`);
93
+ lines.push("");
94
+ if (type === "oversized_file") {
95
+ lines.push("| Size | Path | Suggestion |");
96
+ lines.push("|------|------|------------|");
97
+ for (const i of group) {
98
+ const size = i.message.match(/is ([\d.]+ [KMG]?B)/)?.[1] ?? "?";
99
+ lines.push(`| ${size} | \`${i.path}\` | ${i.suggestion ?? ""} |`);
100
+ }
101
+ lines.push("");
102
+ }
103
+ else {
104
+ for (const i of group) {
105
+ lines.push(`- \`${i.path}\` — ${i.message}`);
106
+ if (i.suggestion)
107
+ lines.push(` - ${i.suggestion}`);
108
+ }
109
+ lines.push("");
110
+ }
111
+ }
112
+ }
113
+ // Top largest files
114
+ if (metrics.topLargestFiles.length > 0) {
115
+ lines.push(`## Top ${metrics.topLargestFiles.length} largest files`);
116
+ lines.push("");
117
+ lines.push("| Size | Path |");
118
+ lines.push("|------|------|");
119
+ for (const f of metrics.topLargestFiles) {
120
+ lines.push(`| ${formatBytes(f.size)} | \`${f.path}\` |`);
121
+ }
122
+ lines.push("");
123
+ }
124
+ // Extension distribution
125
+ if (metrics.extensions.length > 0) {
126
+ lines.push("## Extension distribution");
127
+ lines.push("");
128
+ lines.push("| Extension | Files | Total size |");
129
+ lines.push("|-----------|-------|------------|");
130
+ for (const e of metrics.extensions.slice(0, 20)) {
131
+ lines.push(`| .${e.extension} | ${e.count} | ${formatBytes(e.size)} |`);
132
+ }
133
+ if (metrics.extensions.length > 20) {
134
+ lines.push(`| … | … | … |`);
135
+ lines.push(`| _total_ | ${metrics.totalFiles} | ${formatBytes(metrics.totalSize)} |`);
136
+ }
137
+ lines.push("");
138
+ }
139
+ return lines.join("\n");
140
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Code Order — shared types.
3
+ *
4
+ * Tree-like representation of a scanned directory. Every node is either a file
5
+ * or a folder; folders aggregate size/file/folder counts from their children.
6
+ */
7
+ export interface FileNode {
8
+ readonly path: string;
9
+ readonly name: string;
10
+ readonly size: number;
11
+ /** Lowercase extension without the leading dot. Empty string when none. */
12
+ readonly extension: string;
13
+ readonly isFile: true;
14
+ readonly mtime: number;
15
+ }
16
+ export interface FolderNode {
17
+ path: string;
18
+ name: string;
19
+ isFile: false;
20
+ totalSize: number;
21
+ fileCount: number;
22
+ folderCount: number;
23
+ maxDepth: number;
24
+ children: TreeNode[];
25
+ }
26
+ export type TreeNode = FileNode | FolderNode;
27
+ export type IssueType = "oversized_file" | "deep_nesting" | "empty_folder" | "empty_file" | "duplicate_names" | "single_child_folder";
28
+ export type IssueSeverity = "info" | "warning" | "critical";
29
+ export interface Issue {
30
+ type: IssueType;
31
+ severity: IssueSeverity;
32
+ path: string;
33
+ message: string;
34
+ suggestion?: string;
35
+ }
36
+ export interface ExtensionEntry {
37
+ extension: string;
38
+ count: number;
39
+ size: number;
40
+ }
41
+ export interface ProjectMetrics {
42
+ totalFiles: number;
43
+ totalFolders: number;
44
+ totalSize: number;
45
+ maxDepth: number;
46
+ avgFileSize: number;
47
+ medianFileSize: number;
48
+ extensions: ExtensionEntry[];
49
+ topLargestFiles: FileNode[];
50
+ emptyFolders: string[];
51
+ emptyFiles: string[];
52
+ }
53
+ export interface AnalysisResult {
54
+ root: string;
55
+ generatedAt: string;
56
+ metrics: ProjectMetrics;
57
+ issues: Issue[];
58
+ }
59
+ export interface AnalysisOptions {
60
+ /** Absolute directory to analyze. Defaults to process.cwd(). */
61
+ root: string;
62
+ }
63
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/extensions/code-order/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE7C,MAAM,MAAM,SAAS,GAClB,gBAAgB,GAChB,cAAc,GACd,cAAc,GACd,YAAY,GACZ,iBAAiB,GACjB,qBAAqB,CAAC;AAEzB,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;AAE5D,MAAM,WAAW,KAAK;IACrB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,eAAe,EAAE,QAAQ,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,KAAK,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC/B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;CACb"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Code Order — shared types.
3
+ *
4
+ * Tree-like representation of a scanned directory. Every node is either a file
5
+ * or a folder; folders aggregate size/file/folder counts from their children.
6
+ */
7
+ export {};
@@ -43,7 +43,7 @@ export declare const visualizationStreamEnvelopeSchema: z.ZodObject<{
43
43
  streamId: string;
44
44
  sequence: number;
45
45
  frameType: "patch" | "checkpoint" | "final";
46
- phase: "settled" | "shell" | "narrative" | "structure" | "detail";
46
+ phase: "structure" | "settled" | "shell" | "narrative" | "detail";
47
47
  message?: string | undefined;
48
48
  spec?: Record<string, unknown> | undefined;
49
49
  checkpoint?: Record<string, unknown> | undefined;
@@ -52,7 +52,7 @@ export declare const visualizationStreamEnvelopeSchema: z.ZodObject<{
52
52
  streamId: string;
53
53
  sequence: number;
54
54
  frameType: "patch" | "checkpoint" | "final";
55
- phase: "settled" | "shell" | "narrative" | "structure" | "detail";
55
+ phase: "structure" | "settled" | "shell" | "narrative" | "detail";
56
56
  message?: string | undefined;
57
57
  spec?: Record<string, unknown> | undefined;
58
58
  checkpoint?: Record<string, unknown> | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/relay/dispatcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/relay/dispatcher.ts"],"names":[],"mappings":"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"}
@@ -58,6 +58,7 @@ import { handleGetAgentSettings, handleListAgents, handlePutAgentSettings, } fro
58
58
  import { handleGetSettings, handlePutSettings, } from "../server/handlers/settings.js";
59
59
  import { handleGetPromptMutationSettings, handlePutPromptMutationSettings, } from "../server/handlers/prompt-mutation-settings.js";
60
60
  import { shutdownState } from "../server/shutdown.js";
61
+ import { humanizeProviderError } from "../server/error-humanizer.js";
61
62
  import { handleAutoResearch } from "./auto-research.js";
62
63
  import { handleAutoOptimize } from "./auto-optimizer.js";
63
64
  /**
@@ -1212,7 +1213,7 @@ export function handleClientMessage(frame, deps) {
1212
1213
  relay.send({
1213
1214
  kind: "ws_event",
1214
1215
  sessionId,
1215
- event: { type: "error", message: msg },
1216
+ event: { type: "error", message: humanizeProviderError(err) },
1216
1217
  });
1217
1218
  return;
1218
1219
  }
@@ -1250,7 +1251,7 @@ export function handleClientMessage(frame, deps) {
1250
1251
  relay.send({
1251
1252
  kind: "ws_event",
1252
1253
  sessionId,
1253
- event: { type: "error", message: msg },
1254
+ event: { type: "error", message: humanizeProviderError(err) },
1254
1255
  });
1255
1256
  });
1256
1257
  }
@@ -1311,7 +1312,7 @@ export function handleSubscribe(frame, deps) {
1311
1312
  relay.send({
1312
1313
  kind: "ws_event",
1313
1314
  sessionId,
1314
- event: { type: "error", message: msg },
1315
+ event: { type: "error", message: humanizeProviderError(err) },
1315
1316
  });
1316
1317
  return;
1317
1318
  }
@@ -1342,7 +1343,7 @@ export function handleSubscribe(frame, deps) {
1342
1343
  relay.send({
1343
1344
  kind: "ws_event",
1344
1345
  sessionId,
1345
- event: { type: "error", message: msg },
1346
+ event: { type: "error", message: humanizeProviderError(err) },
1346
1347
  });
1347
1348
  });
1348
1349
  }
@@ -1 +1 @@
1
- {"version":3,"file":"native-extensions.d.ts","sourceRoot":"","sources":["../../../../../src/sdk/coding-agent/core/extensions/native-extensions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,aAAa,CAAC;IAChD;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,cAAc,EAAE,OAAO,CAAC;IACxB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,uBAAuB,EA0HtD,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS,CAElF;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAI1G;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;IAClG,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC,CAUD"}
1
+ {"version":3,"file":"native-extensions.d.ts","sourceRoot":"","sources":["../../../../../src/sdk/coding-agent/core/extensions/native-extensions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,aAAa,CAAC;IAChD;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,cAAc,EAAE,OAAO,CAAC;IACxB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,uBAAuB,EAsItD,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS,CAElF;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAI1G;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;IAClG,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC,CAUD"}
@@ -129,6 +129,17 @@ export const NATIVE_EXTENSIONS = [
129
129
  defaultEnabled: true,
130
130
  tags: ["screenshot", "desktop", "vision", "screen"],
131
131
  },
132
+ {
133
+ id: "code-order",
134
+ label: "Code Order",
135
+ description: "Analyzes folder structure and file sizes, then generates a cleanup report " +
136
+ "(oversized files, deep nesting, empty folders, duplicates, single-child folders). " +
137
+ "Language-agnostic, read-only, zero config. Input for reorganizing code.",
138
+ category: "automation",
139
+ entryPath: "src/extensions/code-order/index.ts",
140
+ defaultEnabled: true,
141
+ tags: ["structure", "analysis", "cleanup", "tree", "audit"],
142
+ },
132
143
  ];
133
144
  /**
134
145
  * Look up a native extension by id. Returns undefined for unknown ids.
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../../../src/sdk/coding-agent/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,wBAAwB;IACxC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,gCAAgC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,yBAAyB;IACzB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAwK3E"}
1
+ {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../../../src/sdk/coding-agent/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,wBAAwB;IACxC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,gCAAgC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,yBAAyB;IACzB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CA4K3E"}
@@ -86,6 +86,8 @@ export function buildSystemPrompt(options) {
86
86
  addGuideline(normalized);
87
87
  }
88
88
  }
89
+ addGuideline("When creating new files, maintain a tree-like directory structure. Place files in semantically meaningful subdirectories (e.g. `handlers/auth/`, `utils/string/`) rather than dumping them at the project root or in shallow flat folders. Group related files into dedicated folders, prefer `feature/module/file.ts` over `feature-file.ts` at root. Avoid creating files directly in root unless they are truly project-wide (e.g. config, package.json). Keep folder depth reasonable (max 5–6 levels) but prefer nesting over flattening — tree-like structure improves LLM navigability and agentic coding efficiency.");
90
+ addGuideline("When editing code, first inspect nearby files and existing patterns; follow the codebase’s conventions and libraries");
89
91
  addGuideline("When editing code, first inspect nearby files and existing patterns; follow the codebase’s conventions and libraries");
90
92
  // Always include these
91
93
  if (hasSubagent) {
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Bash command blocklist for filesystem-wide scans.
3
+ *
4
+ * Blocks recursive scans originating from the filesystem root `/` or other
5
+ * system directories (e.g. `/etc`, `/home`, `/usr`, `/var`) because they can
6
+ * take a very long time and are almost never the intended action inside a
7
+ * workspace-scoped bash tool. Scoped scans (e.g. `find .`, `grep -r src/`,
8
+ * `ls -R src/`) remain allowed.
9
+ *
10
+ * This is intentionally a regex-based heuristic, not a full shell parser. It
11
+ * targets the common scan shapes; exotic obfuscation is out of scope.
12
+ */
13
+ /** Result of a blocklist check. */
14
+ export interface BashBlocklistResult {
15
+ /** Whether the command should be blocked. */
16
+ blocked: boolean;
17
+ /** Human-readable reason (empty when not blocked). */
18
+ reason: string;
19
+ }
20
+ /**
21
+ * Default, reusable explanation returned to the LLM when a command is blocked.
22
+ * Phrased to steer the model toward a scoped alternative.
23
+ */
24
+ export declare const BASH_BLOCKLIST_REASON: string;
25
+ /**
26
+ * Check a bash command against the filesystem-scan blocklist.
27
+ *
28
+ * @param command The raw command string passed to the bash tool (after any
29
+ * command prefix has been applied).
30
+ * @returns `{ blocked: true, reason }` when the command matches a blocked
31
+ * pattern, otherwise `{ blocked: false, reason: "" }`.
32
+ *
33
+ * @example
34
+ * checkBashBlocklist("find /") // { blocked: true, ... }
35
+ * checkBashBlocklist("find / -name foo") // { blocked: true, ... }
36
+ * checkBashBlocklist("find .") // { blocked: false, reason: "" }
37
+ * checkBashBlocklist("grep -r /") // { blocked: true, ... }
38
+ * checkBashBlocklist("grep -r src/") // { blocked: false, reason: "" }
39
+ * checkBashBlocklist("cat /etc/hosts") // { blocked: false, reason: "" }
40
+ */
41
+ export declare function checkBashBlocklist(command: string): BashBlocklistResult;
42
+ //# sourceMappingURL=bash-blocklist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-blocklist.d.ts","sourceRoot":"","sources":["../../../../../src/sdk/coding-agent/core/tools/bash-blocklist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,mCAAmC;AACnC,MAAM,WAAW,mBAAmB;IACnC,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;CACf;AA0GD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAGgD,CAAC;AAEnF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAevE"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Bash command blocklist for filesystem-wide scans.
3
+ *
4
+ * Blocks recursive scans originating from the filesystem root `/` or other
5
+ * system directories (e.g. `/etc`, `/home`, `/usr`, `/var`) because they can
6
+ * take a very long time and are almost never the intended action inside a
7
+ * workspace-scoped bash tool. Scoped scans (e.g. `find .`, `grep -r src/`,
8
+ * `ls -R src/`) remain allowed.
9
+ *
10
+ * This is intentionally a regex-based heuristic, not a full shell parser. It
11
+ * targets the common scan shapes; exotic obfuscation is out of scope.
12
+ */
13
+ /**
14
+ * Absolute system paths that a workspace bash tool should never recursively
15
+ * scan. Each entry is matched as a literal path token (anchored or
16
+ * space/quote-delimited) and is also the prefix of a directory subtree.
17
+ *
18
+ * Notes:
19
+ * - `/` is the root.
20
+ * - We deliberately exclude `/tmp` and `/Users` style home roots here; they
21
+ * are handled by the recursive-root rules where relevant, but blocking every
22
+ * `/Users/...` access would also block legitimate `cat /Users/.../file`
23
+ * reads. We only block *recursive scans* against `/`, not arbitrary reads.
24
+ */
25
+ const SYSTEM_SCAN_ROOTS = [
26
+ "/",
27
+ "/etc",
28
+ "/home",
29
+ "/usr",
30
+ "/var",
31
+ "/bin",
32
+ "/sbin",
33
+ "/lib",
34
+ "/lib64",
35
+ "/opt",
36
+ "/root",
37
+ "/sys",
38
+ "/proc",
39
+ "/dev",
40
+ "/boot",
41
+ "/srv",
42
+ "/mnt",
43
+ "/media",
44
+ ];
45
+ /**
46
+ * Build an alternation of system roots, escaping regex metacharacters. `/` has
47
+ * no special regex meaning so it does not need escaping, but we escape it for
48
+ * safety/generality. Longest entries first so `/etc` matches before `/`.
49
+ */
50
+ const ROOTS_ALT = SYSTEM_SCAN_ROOTS.slice()
51
+ .sort((a, b) => b.length - a.length)
52
+ .map((r) => r.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
53
+ .join("|");
54
+ /**
55
+ * Match a command token that starts with one of the system roots.
56
+ *
57
+ * The token is anchored by start-of-string, a preceding space, or an opening
58
+ * quote, and extends to the next whitespace or end-of-string. This prevents
59
+ * false positives like `cat /etc/hosts` being treated as a scan of `/etc`,
60
+ * because we only apply this pattern to recursive-scan commands (find/grep -r
61
+ * / ls -R) below.
62
+ *
63
+ * Captured group 1 is the matched root path token.
64
+ */
65
+ const SYSTEM_ROOT_TOKEN = new RegExp(`(?:^|\\s|['"])(?<root>${ROOTS_ALT})[^\\s'"]*(?=\\s|$|['"])`);
66
+ /**
67
+ * `find <root>` — `find` invoked with a system root as one of its path
68
+ * arguments. We match `find` followed by optional flags/options and then a
69
+ * system-root token anywhere in the argument list.
70
+ *
71
+ * `find` is inherently recursive, so any `find /` (or `find /etc ...`) is a
72
+ * filesystem scan. Scoped forms (`find .`, `find src/`, `find ./packages`)
73
+ * are not matched because their path tokens are not system roots.
74
+ */
75
+ const FIND_SYSTEM_ROOT = new RegExp(
76
+ // `find` as its own token, followed by anything, then a system-root token.
77
+ `(?:^|[\\s;&|]+)(?:sudo\\s+)?find\\b.*${SYSTEM_ROOT_TOKEN.source}`);
78
+ /**
79
+ * Recursive grep targeting a system root. Requires a recursive flag
80
+ * (`-r`, `-R`, `--recursive`, or a combined short flag containing `r`/`R`
81
+ * such as `-rn`, `-RI`, `-rnI`) and a system-root path token.
82
+ *
83
+ * Supports `grep`, `ggrep`, `egrep`, `fgrep`, `rg` (ripgrep), and `ack`.
84
+ */
85
+ const GREP_SYSTEM_ROOT = new RegExp(`(?:^|[\\s;&|]+)(?:sudo\\s+)?(?:g?grep|egrep|fgrep)\\b` +
86
+ // require a recursive flag somewhere before/after — combined short flags
87
+ // like -rn, -RI are covered by [-][A-Za-z]*[rR][A-Za-z]*
88
+ `.*(?:-r\\b|-R\\b|--recursive\\b|-[A-Za-z]*[rR][A-Za-z]*)` +
89
+ `.*${SYSTEM_ROOT_TOKEN.source}`);
90
+ /**
91
+ * Recursive `ls` targeting a system root. `ls` is only a scan when `-R`
92
+ * (or a combined short flag containing `R`, e.g. `-laR`, `-AR`) is present
93
+ * AND the target is a system root.
94
+ */
95
+ const LS_SYSTEM_ROOT = new RegExp(`(?:^|[\\s;&|]+)(?:sudo\\s+)?ls\\b` +
96
+ `.*(?:-R\\b|--recursive\\b|-[A-Za-z]*R[A-Za-z]*)` +
97
+ `.*${SYSTEM_ROOT_TOKEN.source}`);
98
+ const BLOCKED_PATTERNS = [
99
+ { name: "find on system root", pattern: FIND_SYSTEM_ROOT },
100
+ { name: "recursive grep on system root", pattern: GREP_SYSTEM_ROOT },
101
+ { name: "recursive ls on system root", pattern: LS_SYSTEM_ROOT },
102
+ ];
103
+ /**
104
+ * Default, reusable explanation returned to the LLM when a command is blocked.
105
+ * Phrased to steer the model toward a scoped alternative.
106
+ */
107
+ export const BASH_BLOCKLIST_REASON = "Command blocked: a filesystem-wide scan starting from a system root ('/' or a system directory such as /etc, /usr, /home) was detected. " +
108
+ "Such scans can take a very long time. Use the find/grep/ls tools with a scoped path within the workspace " +
109
+ "(e.g. '.', 'src/', './packages') instead of scanning '/' or system directories.";
110
+ /**
111
+ * Check a bash command against the filesystem-scan blocklist.
112
+ *
113
+ * @param command The raw command string passed to the bash tool (after any
114
+ * command prefix has been applied).
115
+ * @returns `{ blocked: true, reason }` when the command matches a blocked
116
+ * pattern, otherwise `{ blocked: false, reason: "" }`.
117
+ *
118
+ * @example
119
+ * checkBashBlocklist("find /") // { blocked: true, ... }
120
+ * checkBashBlocklist("find / -name foo") // { blocked: true, ... }
121
+ * checkBashBlocklist("find .") // { blocked: false, reason: "" }
122
+ * checkBashBlocklist("grep -r /") // { blocked: true, ... }
123
+ * checkBashBlocklist("grep -r src/") // { blocked: false, reason: "" }
124
+ * checkBashBlocklist("cat /etc/hosts") // { blocked: false, reason: "" }
125
+ */
126
+ export function checkBashBlocklist(command) {
127
+ if (typeof command !== "string" || command.length === 0) {
128
+ return { blocked: false, reason: "" };
129
+ }
130
+ // Strip quoted substrings before matching so that system-root tokens that
131
+ // appear only inside a quoted option value (e.g. `find . -name '/etc/hosts'`)
132
+ // do not false-positive. A real scan target like `find /` or `grep -r /etc`
133
+ // is an unquoted path token and survives this stripping.
134
+ const normalized = command.replace(/'[^']*'|"[^"]*"/g, "");
135
+ for (const { pattern } of BLOCKED_PATTERNS) {
136
+ if (pattern.test(normalized)) {
137
+ return { blocked: true, reason: BASH_BLOCKLIST_REASON };
138
+ }
139
+ }
140
+ return { blocked: false, reason: "" };
141
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../../src/sdk/coding-agent/core/tools/bash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAU5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAI7D,OAAO,EAAoD,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAExG,QAAA,MAAM,UAAU;;;EAGd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;;;OAMG;IACH,IAAI,EAAE,CACL,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;QACR,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QAC/B,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;KACxB,KACG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CAC1C;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAkF1F;AAED,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,gBAAgB,CAAC;AAO5E,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,aAAa,CAAC;CAC1B;AAyFD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAsIhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../../src/sdk/coding-agent/core/tools/bash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAU5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAK7D,OAAO,EAAoD,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAExG,QAAA,MAAM,UAAU;;;EAGd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;;;OAMG;IACH,IAAI,EAAE,CACL,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;QACR,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QAC/B,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;KACxB,KACG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CAC1C;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAkF1F;AAED,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,gBAAgB,CAAC;AAO5E,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,aAAa,CAAC;CAC1B;AAyFD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CA0IhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG"}