lynkr 9.9.1 → 9.11.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 (93) hide show
  1. package/README.md +50 -9
  2. package/bin/cli.js +2 -0
  3. package/bin/lynkr-init.js +11 -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/public/dashboard.html +29 -0
  8. package/scripts/validate-difficulty-classifier.js +27 -6
  9. package/src/api/providers-handler.js +0 -1
  10. package/src/api/router.js +309 -160
  11. package/src/clients/databricks.js +215 -71
  12. package/src/clients/gpt-utils.js +8 -1
  13. package/src/clients/ollama-utils.js +19 -10
  14. package/src/clients/prompt-cache-injection.js +93 -30
  15. package/src/config/index.js +82 -43
  16. package/src/context/compression.js +27 -8
  17. package/src/context/distill.js +2 -1
  18. package/src/dashboard/api.js +5 -1
  19. package/src/memory/distiller.js +350 -0
  20. package/src/memory/extractor.js +0 -8
  21. package/src/memory/format.js +17 -2
  22. package/src/memory/index.js +10 -0
  23. package/src/memory/retriever.js +7 -2
  24. package/src/memory/skills-cache.js +180 -0
  25. package/src/memory/tencentdb-launcher.js +459 -0
  26. package/src/memory/wiki.js +171 -0
  27. package/src/orchestrator/index.js +202 -1237
  28. package/src/orchestrator/passthrough-stream.js +382 -0
  29. package/src/orchestrator/sse-transformer.js +408 -0
  30. package/src/prompts/system.js +20 -6
  31. package/src/routing/affinity-store.js +85 -4
  32. package/src/routing/agentic-detector.js +9 -1
  33. package/src/routing/cache-economics.js +123 -0
  34. package/src/routing/cache-switch-cost.js +194 -0
  35. package/src/routing/calibration.js +8 -1
  36. package/src/routing/complexity-analyzer.js +7 -1
  37. package/src/routing/context-compressor.js +170 -0
  38. package/src/routing/difficulty-classifier.js +161 -17
  39. package/src/routing/index.js +196 -56
  40. package/src/routing/intent-score.js +20 -2
  41. package/src/routing/model-registry.js +35 -10
  42. package/src/routing/session-affinity.js +68 -1
  43. package/src/routing/side-channel-detector.js +103 -0
  44. package/src/routing/telemetry.js +139 -2
  45. package/src/routing/verifier.js +41 -2
  46. package/src/server.js +36 -49
  47. package/src/tools/code-graph.js +6 -4
  48. package/src/agents/context-manager.js +0 -236
  49. package/src/agents/decomposition/dispatcher.js +0 -185
  50. package/src/agents/decomposition/gate.js +0 -136
  51. package/src/agents/decomposition/index.js +0 -183
  52. package/src/agents/decomposition/model-call.js +0 -75
  53. package/src/agents/decomposition/planner.js +0 -223
  54. package/src/agents/decomposition/synthesizer.js +0 -89
  55. package/src/agents/decomposition/telemetry.js +0 -55
  56. package/src/agents/definitions/loader.js +0 -653
  57. package/src/agents/executor.js +0 -457
  58. package/src/agents/index.js +0 -165
  59. package/src/agents/parallel-coordinator.js +0 -68
  60. package/src/agents/reflector.js +0 -331
  61. package/src/agents/skillbook.js +0 -331
  62. package/src/agents/store.js +0 -259
  63. package/src/edits/index.js +0 -171
  64. package/src/indexer/babel-parser.js +0 -213
  65. package/src/indexer/index.js +0 -1629
  66. package/src/indexer/navigation/index.js +0 -32
  67. package/src/indexer/navigation/providers/treeSitter.js +0 -36
  68. package/src/indexer/parser.js +0 -443
  69. package/src/tasks/store.js +0 -349
  70. package/src/tests/coverage.js +0 -173
  71. package/src/tests/index.js +0 -171
  72. package/src/tests/store.js +0 -213
  73. package/src/tools/agent-task.js +0 -145
  74. package/src/tools/code-mode.js +0 -304
  75. package/src/tools/decompose.js +0 -91
  76. package/src/tools/edits.js +0 -94
  77. package/src/tools/execution.js +0 -171
  78. package/src/tools/git.js +0 -1346
  79. package/src/tools/index.js +0 -306
  80. package/src/tools/indexer.js +0 -360
  81. package/src/tools/lazy-loader.js +0 -366
  82. package/src/tools/mcp-remote.js +0 -88
  83. package/src/tools/mcp.js +0 -116
  84. package/src/tools/process.js +0 -167
  85. package/src/tools/smart-selection.js +0 -180
  86. package/src/tools/stubs.js +0 -55
  87. package/src/tools/tasks.js +0 -260
  88. package/src/tools/tests.js +0 -132
  89. package/src/tools/tinyfish.js +0 -358
  90. package/src/tools/truncate.js +0 -106
  91. package/src/tools/web-client.js +0 -71
  92. package/src/tools/web.js +0 -415
  93. 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
- };