lynkr 9.9.0 → 9.10.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 (73) hide show
  1. package/README.md +92 -23
  2. package/bin/cli.js +13 -7
  3. package/bin/lynkr-init.js +34 -12
  4. package/bin/lynkr-reset.js +71 -0
  5. package/config/model-tiers.json +199 -52
  6. package/package.json +3 -3
  7. package/scripts/build-eval-set.js +256 -0
  8. package/scripts/mine-difficulty-anchors.js +288 -0
  9. package/scripts/validate-difficulty-classifier.js +144 -0
  10. package/scripts/validate-intent-anchors.js +186 -0
  11. package/src/api/providers-handler.js +0 -1
  12. package/src/api/router.js +292 -160
  13. package/src/clients/databricks.js +95 -6
  14. package/src/config/index.js +3 -43
  15. package/src/context/tool-result-compressor.js +883 -40
  16. package/src/orchestrator/index.js +117 -1235
  17. package/src/orchestrator/passthrough-stream.js +382 -0
  18. package/src/orchestrator/sse-transformer.js +408 -0
  19. package/src/routing/affinity-store.js +17 -3
  20. package/src/routing/classifier-setup.js +207 -0
  21. package/src/routing/complexity-analyzer.js +40 -4
  22. package/src/routing/difficulty-classifier.js +261 -0
  23. package/src/routing/index.js +70 -7
  24. package/src/routing/intent-score.js +132 -12
  25. package/src/routing/session-affinity.js +8 -1
  26. package/src/routing/side-channel-detector.js +103 -0
  27. package/src/server.js +20 -46
  28. package/src/agents/context-manager.js +0 -236
  29. package/src/agents/decomposition/dispatcher.js +0 -185
  30. package/src/agents/decomposition/gate.js +0 -136
  31. package/src/agents/decomposition/index.js +0 -183
  32. package/src/agents/decomposition/model-call.js +0 -75
  33. package/src/agents/decomposition/planner.js +0 -223
  34. package/src/agents/decomposition/synthesizer.js +0 -89
  35. package/src/agents/decomposition/telemetry.js +0 -55
  36. package/src/agents/definitions/loader.js +0 -653
  37. package/src/agents/executor.js +0 -457
  38. package/src/agents/index.js +0 -165
  39. package/src/agents/parallel-coordinator.js +0 -68
  40. package/src/agents/reflector.js +0 -331
  41. package/src/agents/skillbook.js +0 -331
  42. package/src/agents/store.js +0 -259
  43. package/src/edits/index.js +0 -171
  44. package/src/indexer/babel-parser.js +0 -213
  45. package/src/indexer/index.js +0 -1629
  46. package/src/indexer/navigation/index.js +0 -32
  47. package/src/indexer/navigation/providers/treeSitter.js +0 -36
  48. package/src/indexer/parser.js +0 -443
  49. package/src/tasks/store.js +0 -349
  50. package/src/tests/coverage.js +0 -173
  51. package/src/tests/index.js +0 -171
  52. package/src/tests/store.js +0 -213
  53. package/src/tools/agent-task.js +0 -145
  54. package/src/tools/code-mode.js +0 -304
  55. package/src/tools/decompose.js +0 -91
  56. package/src/tools/edits.js +0 -94
  57. package/src/tools/execution.js +0 -171
  58. package/src/tools/git.js +0 -1346
  59. package/src/tools/index.js +0 -306
  60. package/src/tools/indexer.js +0 -360
  61. package/src/tools/lazy-loader.js +0 -366
  62. package/src/tools/mcp-remote.js +0 -88
  63. package/src/tools/mcp.js +0 -116
  64. package/src/tools/process.js +0 -167
  65. package/src/tools/smart-selection.js +0 -180
  66. package/src/tools/stubs.js +0 -55
  67. package/src/tools/tasks.js +0 -260
  68. package/src/tools/tests.js +0 -132
  69. package/src/tools/tinyfish.js +0 -358
  70. package/src/tools/truncate.js +0 -106
  71. package/src/tools/web-client.js +0 -71
  72. package/src/tools/web.js +0 -415
  73. package/src/tools/workspace.js +0 -204
@@ -1,32 +0,0 @@
1
- const logger = require("../../logger");
2
- const { analyzeWithTreeSitter } = require("./providers/treeSitter");
3
-
4
- const PROVIDERS = [analyzeWithTreeSitter];
5
-
6
- function analyzeFile({ relativePath, content, language }) {
7
- for (const provider of PROVIDERS) {
8
- try {
9
- const result = provider({ relativePath, content, language });
10
- if (result && result.definitions && result.definitions.length) {
11
- return result;
12
- }
13
- if (result) {
14
- return result;
15
- }
16
- } catch (err) {
17
- logger.debug(
18
- {
19
- err,
20
- provider: provider.name,
21
- file: relativePath,
22
- },
23
- "Navigation provider failed",
24
- );
25
- }
26
- }
27
- return null;
28
- }
29
-
30
- module.exports = {
31
- analyzeFile,
32
- };
@@ -1,36 +0,0 @@
1
- const { parseFile } = require("../../parser");
2
-
3
- function analyzeWithTreeSitter({ relativePath, content, language }) {
4
- if (typeof content !== "string") {
5
- return null;
6
- }
7
- const analysis = parseFile(relativePath, content, language);
8
- if (!analysis) {
9
- return null;
10
- }
11
- const engine = "tree_sitter";
12
- const withEngine = (items) =>
13
- Array.isArray(items)
14
- ? items.map((item) => ({
15
- ...item,
16
- engine,
17
- }))
18
- : [];
19
- return {
20
- engine,
21
- language: analysis.language ?? language,
22
- symbols: analysis.symbols ?? [],
23
- definitions: analysis.definitions ?? analysis.symbols ?? [],
24
- references: withEngine(analysis.references),
25
- dependencies: analysis.dependencies ?? [],
26
- exports: withEngine(analysis.exports),
27
- imports: withEngine(analysis.imports),
28
- metadata: {
29
- relativePath,
30
- },
31
- };
32
- }
33
-
34
- module.exports = {
35
- analyzeWithTreeSitter,
36
- };
@@ -1,443 +0,0 @@
1
- const logger = require("../logger");
2
-
3
- // Lazy load heavy dependencies
4
- let Parser = null;
5
- let JavaScript = null;
6
- let TypeScript = null;
7
- let TSX = null;
8
- let Python = null;
9
- let treeSitterAvailable = null; // null = not checked, true/false = result
10
-
11
- function isTreeSitterAvailable() {
12
- if (treeSitterAvailable !== null) {
13
- return treeSitterAvailable;
14
- }
15
- try {
16
- require.resolve("tree-sitter");
17
- treeSitterAvailable = true;
18
- logger.info("[Parser] tree-sitter available");
19
- } catch {
20
- treeSitterAvailable = false;
21
- logger.info("[Parser] tree-sitter not available - using babel fallback for JS/TS (Python parsing disabled)");
22
- }
23
- return treeSitterAvailable;
24
- }
25
-
26
- function getTreeSitterParser() {
27
- if (!isTreeSitterAvailable()) {
28
- return null;
29
- }
30
- if (!Parser) {
31
- try {
32
- Parser = require("tree-sitter");
33
- } catch (err) {
34
- logger.warn({ err: err.message }, "[Parser] Failed to load tree-sitter");
35
- treeSitterAvailable = false;
36
- return null;
37
- }
38
- }
39
- return Parser;
40
- }
41
-
42
- function getLanguageModule(language) {
43
- if (!isTreeSitterAvailable()) {
44
- return null;
45
- }
46
- try {
47
- switch (language) {
48
- case "javascript":
49
- case "javascript-react":
50
- if (!JavaScript) {
51
- JavaScript = require("tree-sitter-javascript");
52
- }
53
- return JavaScript;
54
- case "typescript":
55
- if (!TypeScript) {
56
- const ts = require("tree-sitter-typescript");
57
- TypeScript = ts.typescript;
58
- }
59
- return TypeScript;
60
- case "typescript-react":
61
- if (!TSX) {
62
- const ts = require("tree-sitter-typescript");
63
- TSX = ts.tsx;
64
- }
65
- return TSX;
66
- case "python":
67
- if (!Python) {
68
- Python = require("tree-sitter-python");
69
- }
70
- return Python;
71
- default:
72
- return null;
73
- }
74
- } catch (err) {
75
- logger.warn({ err: err.message, language }, "[Parser] Failed to load language module");
76
- return null;
77
- }
78
- }
79
-
80
- const parserCache = {};
81
-
82
- const LANGUAGE_MAP = {
83
- javascript: { getLanguage: () => getLanguageModule("javascript"), type: "javascript" },
84
- "javascript-react": { getLanguage: () => getLanguageModule("javascript-react"), type: "javascript" },
85
- typescript: { getLanguage: () => getLanguageModule("typescript"), type: "typescript" },
86
- "typescript-react": { getLanguage: () => getLanguageModule("typescript-react"), type: "typescript" },
87
- python: { getLanguage: () => getLanguageModule("python"), type: "python" },
88
- };
89
-
90
- function getParser(languageKey) {
91
- if (!isTreeSitterAvailable()) {
92
- return null;
93
- }
94
- const entry = LANGUAGE_MAP[languageKey];
95
- if (!entry) return null;
96
- if (!parserCache[languageKey]) {
97
- const ParserClass = getTreeSitterParser();
98
- if (!ParserClass) return null;
99
- const parser = new ParserClass();
100
- const language = entry.getLanguage();
101
- if (!language) return null;
102
- parser.setLanguage(language);
103
- parserCache[languageKey] = parser;
104
- }
105
- return parserCache[languageKey];
106
- }
107
-
108
- function nodeText(node, source) {
109
- return source.slice(node.startIndex, node.endIndex);
110
- }
111
-
112
- function positionOf(node) {
113
- return {
114
- line: node.startPosition.row + 1,
115
- column: node.startPosition.column + 1,
116
- };
117
- }
118
-
119
- function identifierName(node, source) {
120
- if (!node) return null;
121
- if (node.type === "identifier" || node.type === "property_identifier") {
122
- return nodeText(node, source);
123
- }
124
- return null;
125
- }
126
-
127
- function extractJavaScript(tree, source) {
128
- const symbols = [];
129
- const dependencies = [];
130
- const references = [];
131
- const imports = [];
132
- const exports = [];
133
-
134
- const registerReference = (nameNode, refNode) => {
135
- if (!nameNode || !refNode) return;
136
- const name = identifierName(nameNode, source);
137
- if (!name) return;
138
- references.push({
139
- name,
140
- line: refNode.startPosition.row + 1,
141
- column: refNode.startPosition.column + 1,
142
- snippet: nodeText(refNode, source),
143
- });
144
- };
145
-
146
- const visit = (node) => {
147
- switch (node.type) {
148
- case "function_declaration": {
149
- const nameNode = node.childForFieldName("name");
150
- if (nameNode) {
151
- symbols.push({
152
- name: nodeText(nameNode, source),
153
- kind: "function",
154
- ...positionOf(nameNode),
155
- });
156
- }
157
- break;
158
- }
159
- case "class_declaration": {
160
- const nameNode = node.childForFieldName("name");
161
- if (nameNode) {
162
- symbols.push({
163
- name: nodeText(nameNode, source),
164
- kind: "class",
165
- ...positionOf(nameNode),
166
- });
167
- }
168
- break;
169
- }
170
- case "method_definition": {
171
- const nameNode = node.childForFieldName("name");
172
- if (nameNode) {
173
- symbols.push({
174
- name: nodeText(nameNode, source),
175
- kind: "method",
176
- ...positionOf(nameNode),
177
- });
178
- }
179
- break;
180
- }
181
- case "arrow_function": {
182
- const parent = node.parent;
183
- if (parent && parent.type === "variable_declarator") {
184
- const nameNode = parent.childForFieldName("name");
185
- if (nameNode) {
186
- symbols.push({
187
- name: nodeText(nameNode, source),
188
- kind: "function",
189
- ...positionOf(nameNode),
190
- });
191
- }
192
- }
193
- break;
194
- }
195
- case "identifier": {
196
- registerReference(node, node);
197
- break;
198
- }
199
- case "import_statement": {
200
- const sourceNode = node.childForFieldName("source");
201
- if (sourceNode) {
202
- const importPath = nodeText(sourceNode, source).replace(/['"]/g, "");
203
- dependencies.push({
204
- kind: "import",
205
- path: importPath,
206
- metadata: {
207
- clause: nodeText(node, source),
208
- },
209
- });
210
- imports.push({
211
- path: importPath,
212
- clause: nodeText(node, source),
213
- line: sourceNode.startPosition.row + 1,
214
- column: sourceNode.startPosition.column + 1,
215
- });
216
- }
217
- break;
218
- }
219
- case "call_expression": {
220
- const funcNode = node.child(0);
221
- if (funcNode && funcNode.type === "identifier" && nodeText(funcNode, source) === "require") {
222
- const argsNode = node.child(1);
223
- if (argsNode && argsNode.firstChild) {
224
- const required = nodeText(argsNode.firstChild, source).replace(/['"]/g, "");
225
- dependencies.push({
226
- kind: "require",
227
- path: required,
228
- metadata: {
229
- clause: nodeText(node, source),
230
- },
231
- });
232
- imports.push({
233
- path: required,
234
- clause: nodeText(node, source),
235
- line: node.startPosition.row + 1,
236
- column: node.startPosition.column + 1,
237
- });
238
- }
239
- }
240
- break;
241
- }
242
- case "export_statement":
243
- case "export_clause":
244
- case "export_default_declaration": {
245
- exports.push({
246
- clause: nodeText(node, source),
247
- line: node.startPosition.row + 1,
248
- column: node.startPosition.column + 1,
249
- });
250
- break;
251
- }
252
- default:
253
- break;
254
- }
255
- for (const child of node.children) {
256
- visit(child);
257
- }
258
- };
259
-
260
- visit(tree.rootNode);
261
- return {
262
- symbols,
263
- dependencies,
264
- references,
265
- imports,
266
- exports,
267
- };
268
- }
269
-
270
- function extractPython(tree, source) {
271
- const symbols = [];
272
- const dependencies = [];
273
- const references = [];
274
- const imports = [];
275
-
276
- const registerReference = (nameNode) => {
277
- if (!nameNode) return;
278
- const name = nodeText(nameNode, source);
279
- if (!name) return;
280
- references.push({
281
- name,
282
- line: nameNode.startPosition.row + 1,
283
- column: nameNode.startPosition.column + 1,
284
- snippet: nodeText(nameNode, source),
285
- });
286
- };
287
-
288
- const visit = (node) => {
289
- switch (node.type) {
290
- case "function_definition": {
291
- const nameNode = node.childForFieldName("name");
292
- if (nameNode) {
293
- symbols.push({
294
- name: nodeText(nameNode, source),
295
- kind: "function",
296
- ...positionOf(nameNode),
297
- });
298
- }
299
- break;
300
- }
301
- case "class_definition": {
302
- const nameNode = node.childForFieldName("name");
303
- if (nameNode) {
304
- symbols.push({
305
- name: nodeText(nameNode, source),
306
- kind: "class",
307
- ...positionOf(nameNode),
308
- });
309
- }
310
- break;
311
- }
312
- case "import_statement": {
313
- const moduleNode = node.childForFieldName("module");
314
- if (moduleNode) {
315
- dependencies.push({
316
- kind: "import",
317
- path: nodeText(moduleNode, source),
318
- metadata: {
319
- clause: nodeText(node, source),
320
- },
321
- });
322
- }
323
- break;
324
- }
325
- case "import_from_statement": {
326
- const moduleNode = node.childForFieldName("module");
327
- if (moduleNode) {
328
- dependencies.push({
329
- kind: "import_from",
330
- path: nodeText(moduleNode, source),
331
- metadata: {
332
- clause: nodeText(node, source),
333
- },
334
- });
335
- }
336
- break;
337
- }
338
- case "call": // older parser versions
339
- case "function_call": {
340
- const nameNode =
341
- node.childForFieldName("name") ??
342
- node.namedChildren?.find((child) => child.type === "identifier") ??
343
- node.child(0);
344
- registerReference(nameNode);
345
- break;
346
- }
347
- case "identifier": {
348
- registerReference(node);
349
- break;
350
- }
351
- default:
352
- break;
353
- }
354
- for (const child of node.children) {
355
- visit(child);
356
- }
357
- };
358
-
359
- visit(tree.rootNode);
360
- return {
361
- symbols,
362
- dependencies,
363
- references,
364
- imports,
365
- exports: [],
366
- };
367
- }
368
-
369
- function parseFile(relativePath, content, language) {
370
- // Try tree-sitter first (faster, more accurate)
371
- const parser = getParser(language);
372
- if (parser) {
373
- try {
374
- const tree = parser.parse(content);
375
- const langType = LANGUAGE_MAP[language]?.type;
376
- if (langType === "javascript" || langType === "typescript") {
377
- const analysis = extractJavaScript(tree, content);
378
- return {
379
- ...analysis,
380
- language: langType,
381
- definitions: analysis.symbols,
382
- parser: "tree-sitter",
383
- };
384
- }
385
- if (langType === "python") {
386
- const analysis = extractPython(tree, content);
387
- return {
388
- ...analysis,
389
- language: langType,
390
- definitions: analysis.symbols,
391
- parser: "tree-sitter",
392
- };
393
- }
394
- } catch (err) {
395
- logger.warn({ err, file: relativePath, language }, "Tree-sitter parse failed, trying babel fallback");
396
- }
397
- }
398
-
399
- // Fallback to Babel parser for JS/TS (pure JS, no native modules)
400
- const langType = LANGUAGE_MAP[language]?.type;
401
- if (langType === "javascript" || langType === "typescript") {
402
- try {
403
- const babelParser = require("./babel-parser");
404
- const result = babelParser.parseFile(relativePath, content, language);
405
- if (result) {
406
- logger.debug({ file: relativePath, parser: "babel" }, "Parsed with babel fallback");
407
- return result;
408
- }
409
- } catch (err) {
410
- logger.debug({ err: err.message }, "Babel parser fallback not available");
411
- }
412
- }
413
-
414
- return null;
415
- }
416
-
417
- /**
418
- * Get info about available parsers
419
- */
420
- function getParserInfo() {
421
- const treeSitter = isTreeSitterAvailable();
422
- let babel = false;
423
- try {
424
- const babelParser = require("./babel-parser");
425
- babel = babelParser.isBabelAvailable();
426
- } catch {
427
- babel = false;
428
- }
429
- return {
430
- treeSitter,
431
- babel,
432
- jsTs: treeSitter || babel, // JS/TS parsing available
433
- python: treeSitter, // Python only via tree-sitter
434
- };
435
- }
436
-
437
- module.exports = {
438
- parseFile,
439
- LANGUAGE_MAP,
440
- getParser,
441
- isTreeSitterAvailable,
442
- getParserInfo,
443
- };