lynkr 9.9.1 → 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 (67) hide show
  1. package/README.md +50 -9
  2. package/bin/cli.js +2 -0
  3. package/bin/lynkr-init.js +4 -12
  4. package/bin/lynkr-reset.js +71 -0
  5. package/config/model-tiers.json +199 -52
  6. package/package.json +2 -2
  7. package/scripts/validate-difficulty-classifier.js +27 -6
  8. package/src/api/providers-handler.js +0 -1
  9. package/src/api/router.js +275 -160
  10. package/src/clients/databricks.js +95 -6
  11. package/src/config/index.js +3 -43
  12. package/src/orchestrator/index.js +117 -1235
  13. package/src/orchestrator/passthrough-stream.js +382 -0
  14. package/src/orchestrator/sse-transformer.js +408 -0
  15. package/src/routing/affinity-store.js +17 -3
  16. package/src/routing/difficulty-classifier.js +52 -10
  17. package/src/routing/index.js +35 -3
  18. package/src/routing/intent-score.js +20 -2
  19. package/src/routing/session-affinity.js +8 -1
  20. package/src/routing/side-channel-detector.js +103 -0
  21. package/src/server.js +0 -46
  22. package/src/agents/context-manager.js +0 -236
  23. package/src/agents/decomposition/dispatcher.js +0 -185
  24. package/src/agents/decomposition/gate.js +0 -136
  25. package/src/agents/decomposition/index.js +0 -183
  26. package/src/agents/decomposition/model-call.js +0 -75
  27. package/src/agents/decomposition/planner.js +0 -223
  28. package/src/agents/decomposition/synthesizer.js +0 -89
  29. package/src/agents/decomposition/telemetry.js +0 -55
  30. package/src/agents/definitions/loader.js +0 -653
  31. package/src/agents/executor.js +0 -457
  32. package/src/agents/index.js +0 -165
  33. package/src/agents/parallel-coordinator.js +0 -68
  34. package/src/agents/reflector.js +0 -331
  35. package/src/agents/skillbook.js +0 -331
  36. package/src/agents/store.js +0 -259
  37. package/src/edits/index.js +0 -171
  38. package/src/indexer/babel-parser.js +0 -213
  39. package/src/indexer/index.js +0 -1629
  40. package/src/indexer/navigation/index.js +0 -32
  41. package/src/indexer/navigation/providers/treeSitter.js +0 -36
  42. package/src/indexer/parser.js +0 -443
  43. package/src/tasks/store.js +0 -349
  44. package/src/tests/coverage.js +0 -173
  45. package/src/tests/index.js +0 -171
  46. package/src/tests/store.js +0 -213
  47. package/src/tools/agent-task.js +0 -145
  48. package/src/tools/code-mode.js +0 -304
  49. package/src/tools/decompose.js +0 -91
  50. package/src/tools/edits.js +0 -94
  51. package/src/tools/execution.js +0 -171
  52. package/src/tools/git.js +0 -1346
  53. package/src/tools/index.js +0 -306
  54. package/src/tools/indexer.js +0 -360
  55. package/src/tools/lazy-loader.js +0 -366
  56. package/src/tools/mcp-remote.js +0 -88
  57. package/src/tools/mcp.js +0 -116
  58. package/src/tools/process.js +0 -167
  59. package/src/tools/smart-selection.js +0 -180
  60. package/src/tools/stubs.js +0 -55
  61. package/src/tools/tasks.js +0 -260
  62. package/src/tools/tests.js +0 -132
  63. package/src/tools/tinyfish.js +0 -358
  64. package/src/tools/truncate.js +0 -106
  65. package/src/tools/web-client.js +0 -71
  66. package/src/tools/web.js +0 -415
  67. 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
- };