flowseeker 0.1.7

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 (82) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/COMPATIBILITY.md +281 -0
  3. package/LICENSE +21 -0
  4. package/README.md +375 -0
  5. package/dist/adapters/frameworkEdges.js +586 -0
  6. package/dist/agent/approvalPolicy.js +81 -0
  7. package/dist/agent/commandRunner.js +166 -0
  8. package/dist/agent/flowCommandRunner.js +124 -0
  9. package/dist/agent/mcpToolRunner.js +167 -0
  10. package/dist/auth/githubAuth.js +71 -0
  11. package/dist/auth/modelList.js +127 -0
  12. package/dist/auth/oauthHandler.js +377 -0
  13. package/dist/chat/nativeChatParticipant.js +616 -0
  14. package/dist/cli/mcpServer.js +383 -0
  15. package/dist/cli/runEvaluation.js +789 -0
  16. package/dist/cli/runReplay.js +481 -0
  17. package/dist/commands/checkHostCompatibility.js +149 -0
  18. package/dist/commands/copyAgentPrompt.js +52 -0
  19. package/dist/commands/copyContext.js +54 -0
  20. package/dist/commands/explainSelectionRelevance.js +57 -0
  21. package/dist/commands/findRelevantContext.js +127 -0
  22. package/dist/commands/openEvidence.js +49 -0
  23. package/dist/commands/openMcpConfig.js +81 -0
  24. package/dist/commands/openRelatedTests.js +54 -0
  25. package/dist/commands/rebuildIndex.js +45 -0
  26. package/dist/commands/runEvaluationSuite.js +323 -0
  27. package/dist/commands/runReplaySuite.js +228 -0
  28. package/dist/config/defaultConfig.js +72 -0
  29. package/dist/config/loadConfig.js +84 -0
  30. package/dist/config/loadConfigFromPath.js +60 -0
  31. package/dist/extension.js +513 -0
  32. package/dist/gateway/agentPrompts.js +176 -0
  33. package/dist/gateway/aiGateway.js +1255 -0
  34. package/dist/gateway/aiProviders.js +901 -0
  35. package/dist/gateway/contextExpansion.js +331 -0
  36. package/dist/gateway/editProposalStore.js +238 -0
  37. package/dist/gateway/planProposalStore.js +28 -0
  38. package/dist/index/cacheStore.js +51 -0
  39. package/dist/index/chunker.js +45 -0
  40. package/dist/index/dependencyExtractor.js +107 -0
  41. package/dist/index/fileDiscovery.js +177 -0
  42. package/dist/index/structuredExtractor.js +256 -0
  43. package/dist/index/workspaceIndex.js +518 -0
  44. package/dist/mcp/mcpConfig.js +154 -0
  45. package/dist/mcp/mcpProvider.js +109 -0
  46. package/dist/mcp/mcpTools.js +215 -0
  47. package/dist/pipeline/agentPrompt.js +79 -0
  48. package/dist/pipeline/agentPromptHeadless.js +85 -0
  49. package/dist/pipeline/contextBlueprint.js +346 -0
  50. package/dist/pipeline/contextPack.js +80 -0
  51. package/dist/pipeline/diffPreview.js +79 -0
  52. package/dist/pipeline/evaluationMetrics.js +154 -0
  53. package/dist/pipeline/evidenceGraph.js +389 -0
  54. package/dist/pipeline/feedback.js +215 -0
  55. package/dist/pipeline/fileGroups.js +84 -0
  56. package/dist/pipeline/fileScanner.js +866 -0
  57. package/dist/pipeline/nodeScan.js +219 -0
  58. package/dist/pipeline/ranker.js +563 -0
  59. package/dist/pipeline/responseLanguage.js +39 -0
  60. package/dist/pipeline/retrievalPlan.js +163 -0
  61. package/dist/pipeline/runHeadless.js +54 -0
  62. package/dist/pipeline/runPipeline.js +114 -0
  63. package/dist/pipeline/solvePacket.js +382 -0
  64. package/dist/pipeline/subsystem.js +257 -0
  65. package/dist/pipeline/taskUnderstanding.js +453 -0
  66. package/dist/pipeline/tokenSavings.js +146 -0
  67. package/dist/pipeline/universalScan.js +216 -0
  68. package/dist/pipeline/verifyAfterApply.js +233 -0
  69. package/dist/runtime/capabilities.js +71 -0
  70. package/dist/runtime/hostDetect.js +98 -0
  71. package/dist/runtime/hostTier.js +68 -0
  72. package/dist/runtime/statusBar.js +80 -0
  73. package/dist/skills/skillRegistry.js +208 -0
  74. package/dist/types.js +3 -0
  75. package/dist/ui/chatViewProvider.js +3899 -0
  76. package/dist/ui/resultTreeProvider.js +174 -0
  77. package/dist/usage/quotaTracker.js +358 -0
  78. package/dist/utils/async.js +30 -0
  79. package/dist/utils/logger.js +64 -0
  80. package/dist/utils/text.js +364 -0
  81. package/dist/utils/updateChecker.js +140 -0
  82. package/package.json +561 -0
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.extractImports = extractImports;
37
+ exports.normalizeImportSource = normalizeImportSource;
38
+ exports.fileMatchesImport = fileMatchesImport;
39
+ const path = __importStar(require("path"));
40
+ const importPatterns = [
41
+ /\bimport\s+(?:type\s+)?(?:[^'";]+\s+from\s+)?["']([^"']+)["']/g,
42
+ /\bexport\s+(?:type\s+)?[^'";]+\s+from\s+["']([^"']+)["']/g,
43
+ /\brequire\s*\(\s*["']([^"']+)["']\s*\)/g,
44
+ /\bfrom\s+([a-zA-Z0-9_.]+)\s+import\b/g,
45
+ /\bimport\s+([a-zA-Z0-9_.]+)\b/g,
46
+ /\binclude(?:_once)?\s*(?:\(\s*)?["']([^"']+)["']/g,
47
+ /\brequire(?:_once)?\s*(?:\(\s*)?["']([^"']+)["']/g,
48
+ /\buse\s+([A-Za-z0-9_\\]+)\s*;/g,
49
+ /#include\s+[<"]([^>"]+)[>"]/g
50
+ ];
51
+ const maxImportScanLineLength = 8000;
52
+ const importSignalPattern = /\b(import|export|require|include|include_once|require_once|from|use)\b|#include/;
53
+ function extractImports(content) {
54
+ const imports = [];
55
+ const lines = content.split(/\r?\n/);
56
+ lines.forEach((line, index) => {
57
+ if (line.length > maxImportScanLineLength || !importSignalPattern.test(line)) {
58
+ return;
59
+ }
60
+ for (const pattern of importPatterns) {
61
+ pattern.lastIndex = 0;
62
+ let match = pattern.exec(line);
63
+ while (match?.[1]) {
64
+ imports.push({
65
+ source: match[1],
66
+ normalizedSource: normalizeImportSource(match[1]),
67
+ line: index + 1
68
+ });
69
+ match = pattern.exec(line);
70
+ }
71
+ }
72
+ });
73
+ return dedupeImports(imports);
74
+ }
75
+ function normalizeImportSource(source) {
76
+ return source
77
+ .replace(/\\/g, "/")
78
+ .replace(/^@\//, "")
79
+ .replace(/^~\//, "")
80
+ .replace(/^\.\//, "")
81
+ .replace(/^\.\.\//, "")
82
+ .replace(/\.(ts|tsx|js|jsx|mjs|cjs|py|php|java|kt|go|cs|rb|rs|vue|svelte|json|yaml|yml|toml|sql)$/i, "")
83
+ .toLowerCase();
84
+ }
85
+ function fileMatchesImport(relativePath, importSource) {
86
+ const normalizedFile = relativePath.replace(/\\/g, "/").replace(/\.[^.]+$/, "").toLowerCase();
87
+ const normalizedImport = normalizeImportSource(importSource);
88
+ const basename = path.posix.basename(normalizedFile);
89
+ const importBase = path.posix.basename(normalizedImport);
90
+ return (normalizedFile.endsWith(normalizedImport) ||
91
+ normalizedFile.includes(`/${normalizedImport}/`) ||
92
+ normalizedImport.endsWith(basename) ||
93
+ (importBase.length > 2 && basename === importBase));
94
+ }
95
+ function dedupeImports(imports) {
96
+ const seen = new Set();
97
+ const result = [];
98
+ for (const item of imports) {
99
+ const key = `${item.normalizedSource}:${item.line}`;
100
+ if (!seen.has(key)) {
101
+ seen.add(key);
102
+ result.push(item);
103
+ }
104
+ }
105
+ return result;
106
+ }
107
+ //# sourceMappingURL=dependencyExtractor.js.map
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.discoverWorkspaceFiles = discoverWorkspaceFiles;
37
+ exports.matchesInclude = matchesInclude;
38
+ exports.matchesExclude = matchesExclude;
39
+ exports.matchesPattern = matchesPattern;
40
+ const fs = __importStar(require("fs/promises"));
41
+ const path = __importStar(require("path"));
42
+ const text_1 = require("../utils/text");
43
+ async function discoverWorkspaceFiles(rootPath, config, options) {
44
+ const files = [];
45
+ let stopReason;
46
+ const includeMatchers = compilePatterns(config.project.include);
47
+ const excludeMatchers = compilePatterns(config.project.exclude);
48
+ const directoryBatchSize = 8;
49
+ const queue = [path.resolve(rootPath)];
50
+ while (queue.length > 0 && !stopReason) {
51
+ const batch = queue.splice(0, directoryBatchSize);
52
+ const childDirectories = await Promise.all(batch.map((directoryPath) => visitDirectory(directoryPath)));
53
+ queue.push(...childDirectories.flat());
54
+ }
55
+ async function visitDirectory(directoryPath) {
56
+ if (stopReason) {
57
+ return [];
58
+ }
59
+ if (options.shouldCancel?.()) {
60
+ stopReason = "cancelled";
61
+ return [];
62
+ }
63
+ if (Date.now() - options.startedAt > config.pipeline.maxScanMs) {
64
+ stopReason = `maxScanMs ${config.pipeline.maxScanMs} reached during discovery`;
65
+ return [];
66
+ }
67
+ let entries;
68
+ try {
69
+ entries = await fs.readdir(directoryPath, { withFileTypes: true });
70
+ }
71
+ catch {
72
+ return [];
73
+ }
74
+ const childDirectories = [];
75
+ for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
76
+ if (stopReason) {
77
+ return childDirectories;
78
+ }
79
+ const absolutePath = path.join(directoryPath, entry.name);
80
+ const relativePath = toRelativePath(rootPath, absolutePath);
81
+ if (entry.isDirectory()) {
82
+ if (!matchesCompiled(relativePath, excludeMatchers, false)) {
83
+ childDirectories.push(absolutePath);
84
+ }
85
+ continue;
86
+ }
87
+ if (!entry.isFile()) {
88
+ continue;
89
+ }
90
+ if (matchesCompiled(relativePath, includeMatchers, true) && !matchesCompiled(relativePath, excludeMatchers, false)) {
91
+ files.push({ absolutePath, relativePath });
92
+ if (files.length >= config.pipeline.maxFiles) {
93
+ stopReason = `maxFiles ${config.pipeline.maxFiles} reached during discovery`;
94
+ return childDirectories;
95
+ }
96
+ }
97
+ }
98
+ return childDirectories;
99
+ }
100
+ return { files, stopReason };
101
+ }
102
+ function matchesInclude(relativePath, includePatterns) {
103
+ if (includePatterns.length === 0) {
104
+ return true;
105
+ }
106
+ return includePatterns.some((pattern) => matchesPattern(relativePath, pattern, true));
107
+ }
108
+ function matchesExclude(relativePath, excludePatterns) {
109
+ return excludePatterns.some((pattern) => matchesPattern(relativePath, pattern, false));
110
+ }
111
+ function matchesPattern(relativePath, pattern, includeMode) {
112
+ const matcher = compilePattern(pattern);
113
+ if (!matcher.normalized || matcher.normalized === "**/*") {
114
+ return includeMode;
115
+ }
116
+ return matchesCompiledPattern(normalizePath(relativePath), matcher);
117
+ }
118
+ function compilePatterns(patterns) {
119
+ return patterns.map(compilePattern);
120
+ }
121
+ function compilePattern(pattern) {
122
+ const normalized = normalizePattern(pattern);
123
+ const hasMagic = (0, text_1.hasGlobMagic)(normalized);
124
+ const looksLikeFile = looksLikeFilePattern(normalized);
125
+ return {
126
+ normalized,
127
+ hasMagic,
128
+ looksLikeFile,
129
+ regex: hasMagic ? globToRegExp(normalized) : undefined,
130
+ directoryRegex: hasMagic && !looksLikeFile ? globToRegExp(`${normalized}/**`) : undefined
131
+ };
132
+ }
133
+ function matchesCompiled(relativePath, matchers, includeMode) {
134
+ if (matchers.length === 0) {
135
+ return includeMode;
136
+ }
137
+ const normalizedPath = normalizePath(relativePath);
138
+ return matchers.some((matcher) => {
139
+ if (!matcher.normalized || matcher.normalized === "**/*") {
140
+ return includeMode;
141
+ }
142
+ return matchesCompiledPattern(normalizedPath, matcher);
143
+ });
144
+ }
145
+ function matchesCompiledPattern(normalizedPath, matcher) {
146
+ if (!matcher.hasMagic) {
147
+ return (normalizedPath === matcher.normalized ||
148
+ normalizedPath.startsWith(`${matcher.normalized}/`) ||
149
+ normalizedPath.includes(`/${matcher.normalized}/`) ||
150
+ normalizedPath.endsWith(`/${matcher.normalized}`));
151
+ }
152
+ return Boolean(matcher.regex?.test(normalizedPath) || matcher.directoryRegex?.test(normalizedPath));
153
+ }
154
+ function globToRegExp(pattern) {
155
+ const marker = "\u0000";
156
+ const escaped = pattern
157
+ .replace(/[.+^${}()|[\]\\]/g, "\\$&")
158
+ .replace(/\*\*/g, marker)
159
+ .replace(/\*/g, "[^/]*")
160
+ .replace(new RegExp(marker, "g"), ".*")
161
+ .replace(/\?/g, ".");
162
+ return new RegExp(`^${escaped}$`);
163
+ }
164
+ function normalizePattern(pattern) {
165
+ return normalizePath(pattern).replace(/^\.\//, "").replace(/\/$/, "");
166
+ }
167
+ function looksLikeFilePattern(pattern) {
168
+ const basename = pattern.split("/").at(-1) ?? pattern;
169
+ return basename.includes(".");
170
+ }
171
+ function normalizePath(filePath) {
172
+ return (0, text_1.normalizeText)(filePath).replace(/\\/g, "/").replace(/^\/+/, "");
173
+ }
174
+ function toRelativePath(rootPath, absolutePath) {
175
+ return path.relative(path.resolve(rootPath), absolutePath).replace(/\\/g, "/");
176
+ }
177
+ //# sourceMappingURL=fileDiscovery.js.map
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectLanguage = detectLanguage;
4
+ exports.extractStructuredNodes = extractStructuredNodes;
5
+ exports.getDeclarationSnippet = getDeclarationSnippet;
6
+ const maxStructuredLineChars = 12000;
7
+ const languagePatterns = {
8
+ typescript: {
9
+ extensions: [".ts", ".tsx"],
10
+ declaration: /^\s*(?:export\s+)?(?:async\s+)?(?:function|class|interface|type|enum|const)\s+(\w+)/gm,
11
+ call: /(\w+(?:\.\w+)*)\s*\(/g,
12
+ stringLiteral: /(["'`])((?:\\.|(?!\1).)*?)\1/g,
13
+ comment: /\/\*\*[\s\S]*?\*\/|\/\/.*$/gm,
14
+ annotation: /@\w+/g
15
+ },
16
+ javascript: {
17
+ extensions: [".js", ".jsx", ".mjs", ".cjs"],
18
+ declaration: /^\s*(?:export\s+)?(?:async\s+)?(?:function|class)\s+(\w+)/gm,
19
+ call: /(\w+(?:\.\w+)*)\s*\(/g,
20
+ stringLiteral: /(["'`])((?:\\.|(?!\1).)*?)\1/g,
21
+ comment: /\/\*\*[\s\S]*?\*\/|\/\/.*$/gm,
22
+ annotation: /@\w+/g
23
+ },
24
+ python: {
25
+ extensions: [".py"],
26
+ declaration: /^\s*(?:async\s+)?(?:def|class)\s+(\w+)/gm,
27
+ call: /(\w+(?:\.\w+)*)\s*\(/g,
28
+ stringLiteral: /(["'])((?:\\.|(?!\1).)*?)\1/g,
29
+ comment: /#.*$/gm,
30
+ annotation: /@\w+/g
31
+ },
32
+ php: {
33
+ extensions: [".php"],
34
+ declaration: /^\s*(?:(?:public|private|protected|static)\s+)*function\s+(\w+)/gm,
35
+ call: /(\w+(?:->\w+)*(?:::w+)*)\s*\(/g,
36
+ stringLiteral: /(["'])((?:\\.|(?!\1).)*?)\1/g,
37
+ comment: /\/\*\*[\s\S]*?\*\/|\/\/.*$|#.*$/gm,
38
+ annotation: /#\[[\s\S]*?\]|@\w+/g
39
+ },
40
+ java: {
41
+ extensions: [".java"],
42
+ declaration: /^\s*(?:(?:public|private|protected|static|final|abstract)\s+)*(?:class|interface|enum)\s+(\w+)/gm,
43
+ call: /(\w+(?:\.\w+)*)\s*\(/g,
44
+ stringLiteral: /"((?:\\.|[^"\\])*)"/g,
45
+ comment: /\/\*\*[\s\S]*?\*\/|\/\/.*$/gm,
46
+ annotation: /@\w+(?:\([^)]*\))?/g
47
+ },
48
+ go: {
49
+ extensions: [".go"],
50
+ declaration: /^\s*func\s+(?:\(\w+\s+\*?\w+\)\s+)?(\w+)/gm,
51
+ call: /(\w+(?:\.\w+)*)\s*\(/g,
52
+ stringLiteral: /"((?:\\.|[^"\\])*)"|`[^`]*`/g,
53
+ comment: /\/\/.*$/gm,
54
+ annotation: /\/\/\s*@\w+/g
55
+ },
56
+ csharp: {
57
+ extensions: [".cs"],
58
+ declaration: /^\s*(?:(?:public|private|protected|internal|static|virtual|override|abstract|sealed)\s+)*(?:class|interface|struct|enum|record)\s+(\w+)/gm,
59
+ call: /(\w+(?:\.\w+)*)\s*\(/g,
60
+ stringLiteral: /"((?:\\.|[^"\\])*)"|@"[^"]*"/g,
61
+ comment: /\/\*\*[\s\S]*?\*\/|\/\/.*$/gm,
62
+ annotation: /\[[\s\S]*?\]/g
63
+ },
64
+ ruby: {
65
+ extensions: [".rb"],
66
+ declaration: /^\s*def\s+(?:self\.)?(\w+)/gm,
67
+ call: /(\w+(?:\.\w+)*)\s*(?:\(|\s)/g,
68
+ stringLiteral: /(["'])((?:\\.|(?!\1).)*?)\1/g,
69
+ comment: /#.*$/gm,
70
+ annotation: /#\s*@\w+/g
71
+ },
72
+ rust: {
73
+ extensions: [".rs"],
74
+ declaration: /^\s*(?:pub\s+)?(?:async\s+)?fn\s+(\w+)/gm,
75
+ call: /(\w+(?:::w+)*(?:\.\w+)*)\s*\(/g,
76
+ stringLiteral: /"((?:\\.|[^"\\])*)"/g,
77
+ comment: /\/\/.*$|\/\/!.*$/gm,
78
+ annotation: /#\[[\s\S]*?\]/g
79
+ },
80
+ kotlin: {
81
+ extensions: [".kt", ".kts"],
82
+ declaration: /^\s*(?:(?:private|protected|internal|public)\s+)?(?:suspend\s+)?fun\s+(\w+)/gm,
83
+ call: /(\w+(?:\.\w+)*)\s*\(/g,
84
+ stringLiteral: /"((?:\\.|[^"\\])*)"/g,
85
+ comment: /\/\*[\s\S]*?\*\/|\/\/.*$/gm,
86
+ annotation: /@\w+/g
87
+ }
88
+ };
89
+ function detectLanguage(filePath) {
90
+ const lower = filePath.toLowerCase();
91
+ for (const [language, patterns] of Object.entries(languagePatterns)) {
92
+ if (patterns.extensions.some((ext) => lower.endsWith(ext))) {
93
+ return language;
94
+ }
95
+ }
96
+ return undefined;
97
+ }
98
+ function extractStructuredNodes(content, language) {
99
+ const patterns = languagePatterns[language];
100
+ if (!patterns) {
101
+ return [];
102
+ }
103
+ const lines = content.split(/\r?\n/);
104
+ const nodes = [];
105
+ nodes.push(...extractDeclarations(lines, patterns.declaration, language));
106
+ nodes.push(...extractCalls(lines, patterns.call));
107
+ nodes.push(...extractStringLiterals(lines, patterns.stringLiteral));
108
+ nodes.push(...extractComments(lines, patterns.comment));
109
+ nodes.push(...extractAnnotations(lines, patterns.annotation));
110
+ return dedupeNodes(nodes);
111
+ }
112
+ function extractDeclarations(lines, pattern, language) {
113
+ const nodes = [];
114
+ lines.forEach((line, index) => {
115
+ if (line.length > maxStructuredLineChars) {
116
+ return;
117
+ }
118
+ pattern.lastIndex = 0;
119
+ let match = pattern.exec(line);
120
+ while (match) {
121
+ const name = match[1];
122
+ const isExported = /\bexport\b/.test(line) || /\bpub\b/.test(line) || /\bpublic\b/.test(line);
123
+ const nodeKind = isClassDecl(line, language) ? "declaration" : "declaration";
124
+ nodes.push({
125
+ kind: nodeKind,
126
+ name,
127
+ range: { startLine: index + 1, endLine: index + 1 },
128
+ text: line.trim(),
129
+ parent: isExported ? "exported" : undefined
130
+ });
131
+ match = pattern.exec(line);
132
+ }
133
+ });
134
+ return nodes;
135
+ }
136
+ function isClassDecl(line, language) {
137
+ const classKeywords = {
138
+ typescript: /\bclass\b/,
139
+ javascript: /\bclass\b/,
140
+ python: /\bclass\b/,
141
+ php: /\bclass\b/,
142
+ java: /\bclass\b/,
143
+ csharp: /\bclass\b/,
144
+ kotlin: /\bclass\b/
145
+ };
146
+ return classKeywords[language]?.test(line) ?? false;
147
+ }
148
+ function extractCalls(lines, pattern) {
149
+ const nodes = [];
150
+ const callNames = new Set();
151
+ lines.forEach((line, index) => {
152
+ if (line.length > maxStructuredLineChars) {
153
+ return;
154
+ }
155
+ pattern.lastIndex = 0;
156
+ let match = pattern.exec(line);
157
+ while (match) {
158
+ const name = match[1];
159
+ if (!callNames.has(name) && name.length > 1) {
160
+ callNames.add(name);
161
+ nodes.push({
162
+ kind: "call",
163
+ name,
164
+ range: { startLine: index + 1, endLine: index + 1 },
165
+ text: line.trim()
166
+ });
167
+ }
168
+ match = pattern.exec(line);
169
+ }
170
+ });
171
+ return nodes.slice(0, 100);
172
+ }
173
+ function extractStringLiterals(lines, pattern) {
174
+ const nodes = [];
175
+ lines.forEach((line, index) => {
176
+ if (line.length > maxStructuredLineChars) {
177
+ return;
178
+ }
179
+ pattern.lastIndex = 0;
180
+ let match = pattern.exec(line);
181
+ while (match) {
182
+ const text = match[2] ?? match[0];
183
+ if (text.length > 8 && text.length < 500) {
184
+ nodes.push({
185
+ kind: "string_literal",
186
+ name: text.slice(0, 60),
187
+ range: { startLine: index + 1, endLine: index + 1 },
188
+ text: line.trim()
189
+ });
190
+ }
191
+ match = pattern.exec(line);
192
+ }
193
+ });
194
+ return nodes.slice(0, 80);
195
+ }
196
+ function extractComments(lines, pattern) {
197
+ const nodes = [];
198
+ lines.forEach((line, index) => {
199
+ if (line.length > maxStructuredLineChars) {
200
+ return;
201
+ }
202
+ pattern.lastIndex = 0;
203
+ const match = pattern.exec(line);
204
+ if (match) {
205
+ const text = match[0].trim();
206
+ if (text.length > 10) {
207
+ nodes.push({
208
+ kind: "comment",
209
+ name: text.slice(0, 80),
210
+ range: { startLine: index + 1, endLine: index + 1 },
211
+ text: line.trim()
212
+ });
213
+ }
214
+ }
215
+ });
216
+ return nodes.slice(0, 60);
217
+ }
218
+ function extractAnnotations(lines, pattern) {
219
+ const nodes = [];
220
+ lines.forEach((line, index) => {
221
+ if (line.length > maxStructuredLineChars) {
222
+ return;
223
+ }
224
+ pattern.lastIndex = 0;
225
+ let match = pattern.exec(line);
226
+ while (match) {
227
+ nodes.push({
228
+ kind: "annotation",
229
+ name: match[0],
230
+ range: { startLine: index + 1, endLine: index + 1 },
231
+ text: line.trim()
232
+ });
233
+ match = pattern.exec(line);
234
+ }
235
+ });
236
+ return nodes.slice(0, 40);
237
+ }
238
+ function dedupeNodes(nodes) {
239
+ const seen = new Set();
240
+ const result = [];
241
+ for (const node of nodes) {
242
+ const key = `${node.kind}:${node.range.startLine}:${node.name ?? ""}`;
243
+ if (!seen.has(key)) {
244
+ seen.add(key);
245
+ result.push(node);
246
+ }
247
+ }
248
+ return result;
249
+ }
250
+ function getDeclarationSnippet(content, node, contextLines = 5) {
251
+ const lines = content.split(/\r?\n/);
252
+ const start = Math.max(0, node.range.startLine - 1 - contextLines);
253
+ const end = Math.min(lines.length, node.range.endLine + contextLines);
254
+ return lines.slice(start, end).join("\n");
255
+ }
256
+ //# sourceMappingURL=structuredExtractor.js.map