@aiready/context-analyzer 0.22.9 → 0.22.12
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.
- package/.turbo/turbo-build.log +33 -32
- package/.turbo/turbo-format-check.log +1 -1
- package/.turbo/turbo-lint.log +8 -0
- package/dist/chunk-HD4Y3GYL.mjs +124 -0
- package/dist/{chunk-M2EGQ36M.mjs → chunk-ISWPFG2C.mjs} +43 -98
- package/dist/{chunk-BQCISA2F.mjs → chunk-QW6ULRML.mjs} +32 -6
- package/dist/{chunk-WHB7QI7N.mjs → chunk-T733LS62.mjs} +23 -4
- package/dist/{cli-action-CXIHOVAC.mjs → cli-action-FV4G4OB6.mjs} +3 -3
- package/dist/{cli-action-3CWN7PBE.mjs → cli-action-HYSWE7F4.mjs} +3 -3
- package/dist/{cli-action-MLFCIW2O.mjs → cli-action-VIQZSWSP.mjs} +3 -3
- package/dist/{cli-action-E7UGP4KE.mjs → cli-action-W7TESWAV.mjs} +6 -8
- package/dist/cli.js +236 -191
- package/dist/cli.mjs +1 -1
- package/dist/console-report-AP4JYNQY.mjs +74 -0
- package/dist/html-report-ULELSIYG.mjs +73 -0
- package/dist/index.d.mts +69 -337
- package/dist/index.d.ts +69 -337
- package/dist/index.js +90 -452
- package/dist/index.mjs +9 -157
- package/dist/interactive-setup-JGFBFI3M.mjs +75 -0
- package/dist/{orchestrator-3ERQS3NW.mjs → orchestrator-QNE2E4TE.mjs} +2 -2
- package/dist/summary-GQRWW3A2.mjs +7 -0
- package/dist/summary-JTBS7CPM.mjs +7 -0
- package/dist/summary-TZFB6ZFM.mjs +7 -0
- package/package.json +2 -2
- package/src/__tests__/file-classification.fixtures.ts +57 -0
- package/src/__tests__/file-classification.test.ts +24 -929
- package/src/__tests__/provider.test.ts +6 -72
- package/src/classifier.ts +42 -42
- package/src/cli-action.ts +11 -6
- package/src/index.ts +30 -27
- package/src/provider.ts +1 -1
- package/src/summary.ts +65 -10
- package/dist/__tests__/analyzer.test.d.ts +0 -2
- package/dist/__tests__/analyzer.test.d.ts.map +0 -1
- package/dist/__tests__/analyzer.test.js +0 -198
- package/dist/__tests__/analyzer.test.js.map +0 -1
- package/dist/__tests__/auto-detection.test.d.ts +0 -2
- package/dist/__tests__/auto-detection.test.d.ts.map +0 -1
- package/dist/__tests__/auto-detection.test.js +0 -132
- package/dist/__tests__/auto-detection.test.js.map +0 -1
- package/dist/__tests__/cluster-detector.test.d.ts +0 -2
- package/dist/__tests__/cluster-detector.test.d.ts.map +0 -1
- package/dist/__tests__/cluster-detector.test.js +0 -121
- package/dist/__tests__/cluster-detector.test.js.map +0 -1
- package/dist/__tests__/contract.test.d.ts +0 -2
- package/dist/__tests__/contract.test.d.ts.map +0 -1
- package/dist/__tests__/contract.test.js +0 -59
- package/dist/__tests__/contract.test.js.map +0 -1
- package/dist/__tests__/enhanced-cohesion.test.d.ts +0 -2
- package/dist/__tests__/enhanced-cohesion.test.d.ts.map +0 -1
- package/dist/__tests__/enhanced-cohesion.test.js +0 -119
- package/dist/__tests__/enhanced-cohesion.test.js.map +0 -1
- package/dist/__tests__/file-classification.test.d.ts +0 -2
- package/dist/__tests__/file-classification.test.d.ts.map +0 -1
- package/dist/__tests__/file-classification.test.js +0 -749
- package/dist/__tests__/file-classification.test.js.map +0 -1
- package/dist/__tests__/fragmentation-advanced.test.d.ts +0 -2
- package/dist/__tests__/fragmentation-advanced.test.d.ts.map +0 -1
- package/dist/__tests__/fragmentation-advanced.test.js +0 -44
- package/dist/__tests__/fragmentation-advanced.test.js.map +0 -1
- package/dist/__tests__/fragmentation-coupling.test.d.ts +0 -2
- package/dist/__tests__/fragmentation-coupling.test.d.ts.map +0 -1
- package/dist/__tests__/fragmentation-coupling.test.js +0 -52
- package/dist/__tests__/fragmentation-coupling.test.js.map +0 -1
- package/dist/__tests__/fragmentation-log.test.d.ts +0 -2
- package/dist/__tests__/fragmentation-log.test.d.ts.map +0 -1
- package/dist/__tests__/fragmentation-log.test.js +0 -29
- package/dist/__tests__/fragmentation-log.test.js.map +0 -1
- package/dist/__tests__/provider.test.d.ts +0 -2
- package/dist/__tests__/provider.test.d.ts.map +0 -1
- package/dist/__tests__/provider.test.js +0 -72
- package/dist/__tests__/provider.test.js.map +0 -1
- package/dist/__tests__/remediation.test.d.ts +0 -2
- package/dist/__tests__/remediation.test.d.ts.map +0 -1
- package/dist/__tests__/remediation.test.js +0 -61
- package/dist/__tests__/remediation.test.js.map +0 -1
- package/dist/__tests__/scoring.test.d.ts +0 -2
- package/dist/__tests__/scoring.test.d.ts.map +0 -1
- package/dist/__tests__/scoring.test.js +0 -298
- package/dist/__tests__/scoring.test.js.map +0 -1
- package/dist/__tests__/structural-cohesion.test.d.ts +0 -2
- package/dist/__tests__/structural-cohesion.test.d.ts.map +0 -1
- package/dist/__tests__/structural-cohesion.test.js +0 -35
- package/dist/__tests__/structural-cohesion.test.js.map +0 -1
- package/dist/analyzer.d.ts +0 -37
- package/dist/analyzer.d.ts.map +0 -1
- package/dist/analyzer.js +0 -283
- package/dist/analyzer.js.map +0 -1
- package/dist/analyzers/python-context.d.ts +0 -38
- package/dist/analyzers/python-context.d.ts.map +0 -1
- package/dist/analyzers/python-context.js +0 -234
- package/dist/analyzers/python-context.js.map +0 -1
- package/dist/ast-utils.d.ts +0 -16
- package/dist/ast-utils.d.ts.map +0 -1
- package/dist/ast-utils.js +0 -81
- package/dist/ast-utils.js.map +0 -1
- package/dist/chunk-22ZO4EKZ.mjs +0 -1297
- package/dist/chunk-2HE27YEV.mjs +0 -1739
- package/dist/chunk-45P4RDYP.mjs +0 -607
- package/dist/chunk-474DEGWW.mjs +0 -1792
- package/dist/chunk-4SYIJ7CU.mjs +0 -1538
- package/dist/chunk-4U4LDWGF.mjs +0 -360
- package/dist/chunk-4XQVYYPC.mjs +0 -1470
- package/dist/chunk-5CLU3HYU.mjs +0 -1475
- package/dist/chunk-5K73Q3OQ.mjs +0 -1520
- package/dist/chunk-5N5DCJOV.mjs +0 -583
- package/dist/chunk-6AVS4KTM.mjs +0 -1536
- package/dist/chunk-6FQYIG6I.mjs +0 -1298
- package/dist/chunk-6I4552YB.mjs +0 -1467
- package/dist/chunk-6LPITDKG.mjs +0 -1539
- package/dist/chunk-72QC5QUS.mjs +0 -549
- package/dist/chunk-736QSHJP.mjs +0 -1807
- package/dist/chunk-7LUSCLGR.mjs +0 -2058
- package/dist/chunk-7VK3XTSH.mjs +0 -1756
- package/dist/chunk-7ZEJGWLN.mjs +0 -1363
- package/dist/chunk-AECWO7NQ.mjs +0 -1539
- package/dist/chunk-AEK3MZC5.mjs +0 -709
- package/dist/chunk-AJC3FR6G.mjs +0 -1509
- package/dist/chunk-AMPK6SWS.mjs +0 -1754
- package/dist/chunk-BA7QGUHN.mjs +0 -1722
- package/dist/chunk-BCEZGRXI.mjs +0 -1297
- package/dist/chunk-BD4NWUVG.mjs +0 -1242
- package/dist/chunk-BEZPBI5C.mjs +0 -1829
- package/dist/chunk-BHCRDEE4.mjs +0 -1745
- package/dist/chunk-BW463GQB.mjs +0 -1767
- package/dist/chunk-CAX2MOUZ.mjs +0 -1801
- package/dist/chunk-CBWM3EK5.mjs +0 -1854
- package/dist/chunk-CCBNKQYB.mjs +0 -1812
- package/dist/chunk-CDIVYADN.mjs +0 -2110
- package/dist/chunk-CVGIDSMN.mjs +0 -1522
- package/dist/chunk-D25B5LZR.mjs +0 -1739
- package/dist/chunk-D3SIHB2V.mjs +0 -2118
- package/dist/chunk-DD7UVNE3.mjs +0 -678
- package/dist/chunk-DMRZMS2U.mjs +0 -964
- package/dist/chunk-DXG5NIYL.mjs +0 -1527
- package/dist/chunk-EBXG2Q5Y.mjs +0 -2059
- package/dist/chunk-EH3PMNZQ.mjs +0 -569
- package/dist/chunk-EMYD7NS6.mjs +0 -137
- package/dist/chunk-EVX2W2BK.mjs +0 -1896
- package/dist/chunk-EWFR366Y.mjs +0 -1740
- package/dist/chunk-EX7HCWAO.mjs +0 -625
- package/dist/chunk-FNPSK3CG.mjs +0 -1760
- package/dist/chunk-FO6YT6RG.mjs +0 -1751
- package/dist/chunk-FYI56A5M.mjs +0 -1892
- package/dist/chunk-G3CCJCBI.mjs +0 -1521
- package/dist/chunk-G7PO3DNK.mjs +0 -1072
- package/dist/chunk-GFADGYXZ.mjs +0 -1752
- package/dist/chunk-GTRIBVS6.mjs +0 -1467
- package/dist/chunk-GXTGOLZT.mjs +0 -92
- package/dist/chunk-H4HWBQU6.mjs +0 -1530
- package/dist/chunk-HDFXSEFW.mjs +0 -605
- package/dist/chunk-HOUDVRG2.mjs +0 -1422
- package/dist/chunk-HQNHM2X7.mjs +0 -997
- package/dist/chunk-I54HL4FZ.mjs +0 -781
- package/dist/chunk-I77HFFZU.mjs +0 -1876
- package/dist/chunk-IKRP7ECY.mjs +0 -1754
- package/dist/chunk-ILMLGJGI.mjs +0 -1295
- package/dist/chunk-IPIE5TXJ.mjs +0 -1741
- package/dist/chunk-IRWCPDWD.mjs +0 -779
- package/dist/chunk-J3MUOWHC.mjs +0 -1747
- package/dist/chunk-J5TA3AZU.mjs +0 -1795
- package/dist/chunk-JH535NPP.mjs +0 -1619
- package/dist/chunk-JUHHOSHG.mjs +0 -1808
- package/dist/chunk-JZ2SE4DB.mjs +0 -1116
- package/dist/chunk-K2WFOBAZ.mjs +0 -1821
- package/dist/chunk-K6U64EL3.mjs +0 -517
- package/dist/chunk-KDUUZQBK.mjs +0 -1692
- package/dist/chunk-KGFWKSGJ.mjs +0 -1442
- package/dist/chunk-KGVMS4R5.mjs +0 -1750
- package/dist/chunk-KWIS5FQP.mjs +0 -1739
- package/dist/chunk-KYSZF5N6.mjs +0 -1876
- package/dist/chunk-LERPI33Y.mjs +0 -2060
- package/dist/chunk-M64RHH4D.mjs +0 -1896
- package/dist/chunk-MBE4AQP5.mjs +0 -1362
- package/dist/chunk-MR7WXHIE.mjs +0 -1833
- package/dist/chunk-MZP3G7TF.mjs +0 -2118
- package/dist/chunk-N2GQWNFG.mjs +0 -1527
- package/dist/chunk-N6XBOOVA.mjs +0 -564
- package/dist/chunk-NJUW6VED.mjs +0 -610
- package/dist/chunk-NOHK5DLU.mjs +0 -2173
- package/dist/chunk-NQA3F2HJ.mjs +0 -1532
- package/dist/chunk-NXXQ2U73.mjs +0 -1467
- package/dist/chunk-OP4G6GLN.mjs +0 -1876
- package/dist/chunk-ORLC5Y4J.mjs +0 -1787
- package/dist/chunk-OTCQL7DY.mjs +0 -2045
- package/dist/chunk-OUYSZZ7X.mjs +0 -1846
- package/dist/chunk-OZE3FVZT.mjs +0 -1089
- package/dist/chunk-P3T3H27S.mjs +0 -1895
- package/dist/chunk-P5YV5WIX.mjs +0 -1803
- package/dist/chunk-P74BO725.mjs +0 -1296
- package/dist/chunk-PDN74MG3.mjs +0 -1834
- package/dist/chunk-PJD4VCIH.mjs +0 -1722
- package/dist/chunk-PVVCCE6W.mjs +0 -755
- package/dist/chunk-PVVMK56C.mjs +0 -1793
- package/dist/chunk-Q2GDZ2FZ.mjs +0 -1794
- package/dist/chunk-QDGPR3L6.mjs +0 -1518
- package/dist/chunk-RQCIJO5Z.mjs +0 -1116
- package/dist/chunk-RRB2C34Q.mjs +0 -1738
- package/dist/chunk-RYIB5CWD.mjs +0 -781
- package/dist/chunk-S6OPP4L5.mjs +0 -1791
- package/dist/chunk-SAVOSPM3.mjs +0 -1522
- package/dist/chunk-SFK6XTJE.mjs +0 -2110
- package/dist/chunk-SIX4KMF2.mjs +0 -1468
- package/dist/chunk-SPAM2YJE.mjs +0 -1537
- package/dist/chunk-T6ZCOPPI.mjs +0 -538
- package/dist/chunk-TPF75CNP.mjs +0 -581
- package/dist/chunk-TWWPY7FD.mjs +0 -1754
- package/dist/chunk-U5R2FTCR.mjs +0 -1803
- package/dist/chunk-UG7OPVHB.mjs +0 -1521
- package/dist/chunk-UMZTAWDA.mjs +0 -1812
- package/dist/chunk-UU4HZ7ZT.mjs +0 -1849
- package/dist/chunk-UXC6QUZ7.mjs +0 -1801
- package/dist/chunk-VBWXHKGD.mjs +0 -1895
- package/dist/chunk-VIJTZPBI.mjs +0 -1470
- package/dist/chunk-VLV6MXPL.mjs +0 -1750
- package/dist/chunk-VTALAPQZ.mjs +0 -1241
- package/dist/chunk-W2KNBN6W.mjs +0 -1849
- package/dist/chunk-W37E7MW5.mjs +0 -1403
- package/dist/chunk-W76FEISE.mjs +0 -1538
- package/dist/chunk-WCFQYXQA.mjs +0 -1532
- package/dist/chunk-WKOZOHOU.mjs +0 -2060
- package/dist/chunk-WTQJNY4U.mjs +0 -1785
- package/dist/chunk-XBFM2Z4O.mjs +0 -1792
- package/dist/chunk-XIXAWCMS.mjs +0 -1760
- package/dist/chunk-XTAXUNQN.mjs +0 -1742
- package/dist/chunk-XY77XABG.mjs +0 -1545
- package/dist/chunk-XZ645X5U.mjs +0 -1425
- package/dist/chunk-Y6FXYEAI.mjs +0 -10
- package/dist/chunk-YCGDIGOG.mjs +0 -1467
- package/dist/chunk-YYB6NZE3.mjs +0 -1869
- package/dist/chunk-Z5WY6A4P.mjs +0 -1754
- package/dist/chunk-ZAMFWKIB.mjs +0 -1842
- package/dist/classifier.d.ts +0 -114
- package/dist/classifier.d.ts.map +0 -1
- package/dist/classifier.js +0 -439
- package/dist/classifier.js.map +0 -1
- package/dist/cli-action-SA7SCYNV.mjs +0 -95
- package/dist/cli-action-VCXBZGZP.mjs +0 -95
- package/dist/cli-action-YAJOJCXJ.mjs +0 -95
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/cluster-detector.d.ts +0 -8
- package/dist/cluster-detector.d.ts.map +0 -1
- package/dist/cluster-detector.js +0 -70
- package/dist/cluster-detector.js.map +0 -1
- package/dist/defaults.d.ts +0 -7
- package/dist/defaults.d.ts.map +0 -1
- package/dist/defaults.js +0 -54
- package/dist/defaults.js.map +0 -1
- package/dist/graph-builder.d.ts +0 -33
- package/dist/graph-builder.d.ts.map +0 -1
- package/dist/graph-builder.js +0 -225
- package/dist/graph-builder.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/metrics.d.ts +0 -34
- package/dist/metrics.d.ts.map +0 -1
- package/dist/metrics.js +0 -170
- package/dist/metrics.js.map +0 -1
- package/dist/orchestrator-3L3NAZYP.mjs +0 -10
- package/dist/orchestrator-5AL3XBPZ.mjs +0 -10
- package/dist/orchestrator-KMAKMHTD.mjs +0 -10
- package/dist/orchestrator-MONOZHVW.mjs +0 -10
- package/dist/orchestrator-R6MZT4Z2.mjs +0 -10
- package/dist/orchestrator-ZR7JSKWI.mjs +0 -10
- package/dist/provider.d.ts +0 -6
- package/dist/provider.d.ts.map +0 -1
- package/dist/provider.js +0 -48
- package/dist/provider.js.map +0 -1
- package/dist/python-context-3GZKN3LR.mjs +0 -162
- package/dist/python-context-GOH747QU.mjs +0 -202
- package/dist/python-context-O2EN3M6Z.mjs +0 -162
- package/dist/python-context-PAETRLDY.mjs +0 -185
- package/dist/python-context-TBI5FVFY.mjs +0 -203
- package/dist/python-context-UOPTQH44.mjs +0 -192
- package/dist/remediation.d.ts +0 -25
- package/dist/remediation.d.ts.map +0 -1
- package/dist/remediation.js +0 -98
- package/dist/remediation.js.map +0 -1
- package/dist/scoring.d.ts +0 -9
- package/dist/scoring.d.ts.map +0 -1
- package/dist/scoring.js +0 -142
- package/dist/scoring.js.map +0 -1
- package/dist/semantic-analysis.d.ts +0 -33
- package/dist/semantic-analysis.d.ts.map +0 -1
- package/dist/semantic-analysis.js +0 -303
- package/dist/semantic-analysis.js.map +0 -1
- package/dist/summary-7PZVW72O.mjs +0 -7
- package/dist/summary-LKUCJAIS.mjs +0 -7
- package/dist/summary.d.ts +0 -6
- package/dist/summary.d.ts.map +0 -1
- package/dist/summary.js +0 -92
- package/dist/summary.js.map +0 -1
- package/dist/types.d.ts +0 -124
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/output-formatter.d.ts +0 -14
- package/dist/utils/output-formatter.d.ts.map +0 -1
- package/dist/utils/output-formatter.js +0 -338
- package/dist/utils/output-formatter.js.map +0 -1
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
// src/analyzers/python-context.ts
|
|
2
|
-
import { getParser, estimateTokens } from "@aiready/core";
|
|
3
|
-
import { resolve, relative, dirname, join } from "path";
|
|
4
|
-
import fs from "fs";
|
|
5
|
-
async function analyzePythonContext(files, rootDir) {
|
|
6
|
-
const results = [];
|
|
7
|
-
const parser = getParser("dummy.py");
|
|
8
|
-
if (!parser) {
|
|
9
|
-
console.warn("Python parser not available");
|
|
10
|
-
return results;
|
|
11
|
-
}
|
|
12
|
-
const pythonFiles = files.filter((f) => f.toLowerCase().endsWith(".py"));
|
|
13
|
-
void relative;
|
|
14
|
-
void join;
|
|
15
|
-
const dependencyGraph = await buildPythonDependencyGraph(
|
|
16
|
-
pythonFiles,
|
|
17
|
-
rootDir
|
|
18
|
-
);
|
|
19
|
-
for (const file of pythonFiles) {
|
|
20
|
-
try {
|
|
21
|
-
const code = await fs.promises.readFile(file, "utf-8");
|
|
22
|
-
const result = parser.parse(code, file);
|
|
23
|
-
const imports = result.imports.map((imp) => ({
|
|
24
|
-
source: imp.source,
|
|
25
|
-
specifiers: imp.specifiers,
|
|
26
|
-
isRelative: imp.source.startsWith("."),
|
|
27
|
-
resolvedPath: resolvePythonImport(file, imp.source, rootDir)
|
|
28
|
-
}));
|
|
29
|
-
const exports = result.exports.map((exp) => ({
|
|
30
|
-
name: exp.name,
|
|
31
|
-
type: exp.type
|
|
32
|
-
}));
|
|
33
|
-
const linesOfCode = code.split("\n").length;
|
|
34
|
-
const importDepth = await calculatePythonImportDepth(
|
|
35
|
-
file,
|
|
36
|
-
dependencyGraph,
|
|
37
|
-
/* @__PURE__ */ new Set()
|
|
38
|
-
);
|
|
39
|
-
const contextBudget = estimateContextBudget(
|
|
40
|
-
code,
|
|
41
|
-
imports,
|
|
42
|
-
dependencyGraph
|
|
43
|
-
);
|
|
44
|
-
const cohesion = calculatePythonCohesion(exports, imports);
|
|
45
|
-
const circularDependencies = detectCircularDependencies(
|
|
46
|
-
file,
|
|
47
|
-
dependencyGraph
|
|
48
|
-
);
|
|
49
|
-
results.push({
|
|
50
|
-
file,
|
|
51
|
-
importDepth,
|
|
52
|
-
contextBudget,
|
|
53
|
-
cohesion,
|
|
54
|
-
imports,
|
|
55
|
-
exports,
|
|
56
|
-
metrics: {
|
|
57
|
-
linesOfCode,
|
|
58
|
-
importCount: imports.length,
|
|
59
|
-
exportCount: exports.length,
|
|
60
|
-
circularDependencies
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
} catch (error) {
|
|
64
|
-
console.warn(`Failed to analyze ${file}:`, error);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return results;
|
|
68
|
-
}
|
|
69
|
-
async function buildPythonDependencyGraph(files, rootDir) {
|
|
70
|
-
const graph = /* @__PURE__ */ new Map();
|
|
71
|
-
const parser = getParser("dummy.py");
|
|
72
|
-
if (!parser) return graph;
|
|
73
|
-
for (const file of files) {
|
|
74
|
-
try {
|
|
75
|
-
const code = await fs.promises.readFile(file, "utf-8");
|
|
76
|
-
const result = parser.parse(code, file);
|
|
77
|
-
const dependencies = /* @__PURE__ */ new Set();
|
|
78
|
-
for (const imp of result.imports) {
|
|
79
|
-
const resolved = resolvePythonImport(file, imp.source, rootDir);
|
|
80
|
-
if (resolved && files.includes(resolved)) {
|
|
81
|
-
dependencies.add(resolved);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
graph.set(file, dependencies);
|
|
85
|
-
} catch (error) {
|
|
86
|
-
void error;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return graph;
|
|
90
|
-
}
|
|
91
|
-
function resolvePythonImport(fromFile, importPath, rootDir) {
|
|
92
|
-
const dir = dirname(fromFile);
|
|
93
|
-
if (importPath.startsWith(".")) {
|
|
94
|
-
const parts = importPath.split(".");
|
|
95
|
-
let upCount = 0;
|
|
96
|
-
while (parts[0] === "") {
|
|
97
|
-
upCount++;
|
|
98
|
-
parts.shift();
|
|
99
|
-
}
|
|
100
|
-
let targetDir = dir;
|
|
101
|
-
for (let i = 0; i < upCount - 1; i++) {
|
|
102
|
-
targetDir = dirname(targetDir);
|
|
103
|
-
}
|
|
104
|
-
const modulePath = parts.join("/");
|
|
105
|
-
const possiblePaths = [
|
|
106
|
-
resolve(targetDir, `${modulePath}.py`),
|
|
107
|
-
resolve(targetDir, modulePath, "__init__.py")
|
|
108
|
-
];
|
|
109
|
-
for (const path of possiblePaths) {
|
|
110
|
-
if (fs.existsSync(path)) {
|
|
111
|
-
return path;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
} else {
|
|
115
|
-
const modulePath = importPath.replace(/\./g, "/");
|
|
116
|
-
const possiblePaths = [
|
|
117
|
-
resolve(rootDir, `${modulePath}.py`),
|
|
118
|
-
resolve(rootDir, modulePath, "__init__.py")
|
|
119
|
-
];
|
|
120
|
-
for (const path of possiblePaths) {
|
|
121
|
-
if (fs.existsSync(path)) {
|
|
122
|
-
return path;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return void 0;
|
|
127
|
-
}
|
|
128
|
-
async function calculatePythonImportDepth(file, dependencyGraph, visited, depth = 0) {
|
|
129
|
-
if (visited.has(file)) {
|
|
130
|
-
return depth;
|
|
131
|
-
}
|
|
132
|
-
visited.add(file);
|
|
133
|
-
const dependencies = dependencyGraph.get(file) || /* @__PURE__ */ new Set();
|
|
134
|
-
if (dependencies.size === 0) {
|
|
135
|
-
return depth;
|
|
136
|
-
}
|
|
137
|
-
let maxDepth = depth;
|
|
138
|
-
for (const dep of dependencies) {
|
|
139
|
-
const depDepth = await calculatePythonImportDepth(
|
|
140
|
-
dep,
|
|
141
|
-
dependencyGraph,
|
|
142
|
-
new Set(visited),
|
|
143
|
-
depth + 1
|
|
144
|
-
);
|
|
145
|
-
maxDepth = Math.max(maxDepth, depDepth);
|
|
146
|
-
}
|
|
147
|
-
return maxDepth;
|
|
148
|
-
}
|
|
149
|
-
function estimateContextBudget(code, imports, dependencyGraph) {
|
|
150
|
-
let budget = estimateTokens(code);
|
|
151
|
-
const avgTokensPerDep = 500;
|
|
152
|
-
budget += imports.length * avgTokensPerDep;
|
|
153
|
-
return budget;
|
|
154
|
-
}
|
|
155
|
-
function calculatePythonCohesion(exports, imports) {
|
|
156
|
-
if (exports.length === 0) return 1;
|
|
157
|
-
const exportCount = exports.length;
|
|
158
|
-
const importCount = imports.length;
|
|
159
|
-
let cohesion = 1;
|
|
160
|
-
if (exportCount > 10) {
|
|
161
|
-
cohesion *= 0.6;
|
|
162
|
-
} else if (exportCount > 5) {
|
|
163
|
-
cohesion *= 0.8;
|
|
164
|
-
}
|
|
165
|
-
if (exportCount > 0) {
|
|
166
|
-
const ratio = importCount / exportCount;
|
|
167
|
-
if (ratio > 2) {
|
|
168
|
-
cohesion *= 1.1;
|
|
169
|
-
} else if (ratio < 0.5) {
|
|
170
|
-
cohesion *= 0.9;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
return Math.min(1, Math.max(0, cohesion));
|
|
174
|
-
}
|
|
175
|
-
function detectCircularDependencies(file, dependencyGraph) {
|
|
176
|
-
const circular = [];
|
|
177
|
-
const visited = /* @__PURE__ */ new Set();
|
|
178
|
-
const recursionStack = /* @__PURE__ */ new Set();
|
|
179
|
-
function dfs(current, path) {
|
|
180
|
-
if (recursionStack.has(current)) {
|
|
181
|
-
const cycleStart = path.indexOf(current);
|
|
182
|
-
const cycle = path.slice(cycleStart).concat([current]);
|
|
183
|
-
circular.push(cycle.join(" \u2192 "));
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
if (visited.has(current)) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
visited.add(current);
|
|
190
|
-
recursionStack.add(current);
|
|
191
|
-
const dependencies = dependencyGraph.get(current) || /* @__PURE__ */ new Set();
|
|
192
|
-
for (const dep of dependencies) {
|
|
193
|
-
dfs(dep, [...path, current]);
|
|
194
|
-
}
|
|
195
|
-
recursionStack.delete(current);
|
|
196
|
-
}
|
|
197
|
-
dfs(file, []);
|
|
198
|
-
return [...new Set(circular)];
|
|
199
|
-
}
|
|
200
|
-
export {
|
|
201
|
-
analyzePythonContext
|
|
202
|
-
};
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
calculateImportDepthFromEdges,
|
|
3
|
-
detectGraphCyclesFromFile
|
|
4
|
-
} from "./chunk-GXTGOLZT.mjs";
|
|
5
|
-
|
|
6
|
-
// src/analyzers/python-context.ts
|
|
7
|
-
import { getParser, estimateTokens } from "@aiready/core";
|
|
8
|
-
import { resolve, relative, dirname, join } from "path";
|
|
9
|
-
import fs from "fs";
|
|
10
|
-
async function analyzePythonContext(files, rootDir) {
|
|
11
|
-
const results = [];
|
|
12
|
-
const parser = getParser("dummy.py");
|
|
13
|
-
if (!parser) {
|
|
14
|
-
console.warn("Python parser not available");
|
|
15
|
-
return results;
|
|
16
|
-
}
|
|
17
|
-
const pythonFiles = files.filter((f) => f.toLowerCase().endsWith(".py"));
|
|
18
|
-
void relative;
|
|
19
|
-
void join;
|
|
20
|
-
const dependencyGraph = await buildPythonDependencyGraph(
|
|
21
|
-
pythonFiles,
|
|
22
|
-
rootDir
|
|
23
|
-
);
|
|
24
|
-
for (const file of pythonFiles) {
|
|
25
|
-
try {
|
|
26
|
-
const code = await fs.promises.readFile(file, "utf-8");
|
|
27
|
-
const result = parser.parse(code, file);
|
|
28
|
-
const imports = result.imports.map((imp) => ({
|
|
29
|
-
source: imp.source,
|
|
30
|
-
specifiers: imp.specifiers,
|
|
31
|
-
isRelative: imp.source.startsWith("."),
|
|
32
|
-
resolvedPath: resolvePythonImport(file, imp.source, rootDir)
|
|
33
|
-
}));
|
|
34
|
-
const exports = result.exports.map((exp) => ({
|
|
35
|
-
name: exp.name,
|
|
36
|
-
type: exp.type
|
|
37
|
-
}));
|
|
38
|
-
const linesOfCode = code.split("\n").length;
|
|
39
|
-
const importDepth = calculateImportDepthFromEdges(
|
|
40
|
-
file,
|
|
41
|
-
dependencyGraph,
|
|
42
|
-
/* @__PURE__ */ new Set()
|
|
43
|
-
);
|
|
44
|
-
const contextBudget = estimateContextBudget(
|
|
45
|
-
code,
|
|
46
|
-
imports,
|
|
47
|
-
dependencyGraph
|
|
48
|
-
);
|
|
49
|
-
const cohesion = calculatePythonCohesion(exports, imports);
|
|
50
|
-
const circularDependencies = detectGraphCyclesFromFile(
|
|
51
|
-
file,
|
|
52
|
-
dependencyGraph
|
|
53
|
-
).map((cycle) => cycle.join(" -> "));
|
|
54
|
-
results.push({
|
|
55
|
-
file,
|
|
56
|
-
importDepth,
|
|
57
|
-
contextBudget,
|
|
58
|
-
cohesion,
|
|
59
|
-
imports,
|
|
60
|
-
exports,
|
|
61
|
-
metrics: {
|
|
62
|
-
linesOfCode,
|
|
63
|
-
importCount: imports.length,
|
|
64
|
-
exportCount: exports.length,
|
|
65
|
-
circularDependencies
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
} catch (error) {
|
|
69
|
-
console.warn(`Failed to analyze ${file}:`, error);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return results;
|
|
73
|
-
}
|
|
74
|
-
async function buildPythonDependencyGraph(files, rootDir) {
|
|
75
|
-
const graph = /* @__PURE__ */ new Map();
|
|
76
|
-
const parser = getParser("dummy.py");
|
|
77
|
-
if (!parser) return graph;
|
|
78
|
-
for (const file of files) {
|
|
79
|
-
try {
|
|
80
|
-
const code = await fs.promises.readFile(file, "utf-8");
|
|
81
|
-
const result = parser.parse(code, file);
|
|
82
|
-
const dependencies = /* @__PURE__ */ new Set();
|
|
83
|
-
for (const imp of result.imports) {
|
|
84
|
-
const resolved = resolvePythonImport(file, imp.source, rootDir);
|
|
85
|
-
if (resolved && files.includes(resolved)) {
|
|
86
|
-
dependencies.add(resolved);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
graph.set(file, dependencies);
|
|
90
|
-
} catch (error) {
|
|
91
|
-
void error;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return graph;
|
|
95
|
-
}
|
|
96
|
-
function resolvePythonImport(fromFile, importPath, rootDir) {
|
|
97
|
-
const dir = dirname(fromFile);
|
|
98
|
-
if (importPath.startsWith(".")) {
|
|
99
|
-
const parts = importPath.split(".");
|
|
100
|
-
let upCount = 0;
|
|
101
|
-
while (parts[0] === "") {
|
|
102
|
-
upCount++;
|
|
103
|
-
parts.shift();
|
|
104
|
-
}
|
|
105
|
-
let targetDir = dir;
|
|
106
|
-
for (let i = 0; i < upCount - 1; i++) {
|
|
107
|
-
targetDir = dirname(targetDir);
|
|
108
|
-
}
|
|
109
|
-
const modulePath = parts.join("/");
|
|
110
|
-
const possiblePaths = [
|
|
111
|
-
resolve(targetDir, `${modulePath}.py`),
|
|
112
|
-
resolve(targetDir, modulePath, "__init__.py")
|
|
113
|
-
];
|
|
114
|
-
for (const path of possiblePaths) {
|
|
115
|
-
if (fs.existsSync(path)) {
|
|
116
|
-
return path;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
const modulePath = importPath.replace(/\./g, "/");
|
|
121
|
-
const possiblePaths = [
|
|
122
|
-
resolve(rootDir, `${modulePath}.py`),
|
|
123
|
-
resolve(rootDir, modulePath, "__init__.py")
|
|
124
|
-
];
|
|
125
|
-
for (const path of possiblePaths) {
|
|
126
|
-
if (fs.existsSync(path)) {
|
|
127
|
-
return path;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return void 0;
|
|
132
|
-
}
|
|
133
|
-
function estimateContextBudget(code, imports, dependencyGraph) {
|
|
134
|
-
void dependencyGraph;
|
|
135
|
-
let budget = estimateTokens(code);
|
|
136
|
-
const avgTokensPerDep = 500;
|
|
137
|
-
budget += imports.length * avgTokensPerDep;
|
|
138
|
-
return budget;
|
|
139
|
-
}
|
|
140
|
-
function calculatePythonCohesion(exports, imports) {
|
|
141
|
-
if (exports.length === 0) return 1;
|
|
142
|
-
const exportCount = exports.length;
|
|
143
|
-
const importCount = imports.length;
|
|
144
|
-
let cohesion = 1;
|
|
145
|
-
if (exportCount > 10) {
|
|
146
|
-
cohesion *= 0.6;
|
|
147
|
-
} else if (exportCount > 5) {
|
|
148
|
-
cohesion *= 0.8;
|
|
149
|
-
}
|
|
150
|
-
if (exportCount > 0) {
|
|
151
|
-
const ratio = importCount / exportCount;
|
|
152
|
-
if (ratio > 2) {
|
|
153
|
-
cohesion *= 1.1;
|
|
154
|
-
} else if (ratio < 0.5) {
|
|
155
|
-
cohesion *= 0.9;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return Math.min(1, Math.max(0, cohesion));
|
|
159
|
-
}
|
|
160
|
-
export {
|
|
161
|
-
analyzePythonContext
|
|
162
|
-
};
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
// src/analyzers/python-context.ts
|
|
2
|
-
import { getParser, estimateTokens } from "@aiready/core";
|
|
3
|
-
import { resolve, dirname } from "path";
|
|
4
|
-
import fs from "fs";
|
|
5
|
-
async function analyzePythonContext(files, rootDir) {
|
|
6
|
-
const results = [];
|
|
7
|
-
const parser = getParser("dummy.py");
|
|
8
|
-
if (!parser) {
|
|
9
|
-
console.warn("Python parser not available");
|
|
10
|
-
return results;
|
|
11
|
-
}
|
|
12
|
-
const pythonFiles = files.filter((f) => f.toLowerCase().endsWith(".py"));
|
|
13
|
-
const dependencyGraph = await buildPythonDependencyGraph(pythonFiles, rootDir);
|
|
14
|
-
for (const file of pythonFiles) {
|
|
15
|
-
try {
|
|
16
|
-
const code = await fs.promises.readFile(file, "utf-8");
|
|
17
|
-
const result = parser.parse(code, file);
|
|
18
|
-
const imports = result.imports.map((imp) => ({
|
|
19
|
-
source: imp.source,
|
|
20
|
-
specifiers: imp.specifiers,
|
|
21
|
-
isRelative: imp.source.startsWith("."),
|
|
22
|
-
resolvedPath: resolvePythonImport(file, imp.source, rootDir)
|
|
23
|
-
}));
|
|
24
|
-
const exports = result.exports.map((exp) => ({
|
|
25
|
-
name: exp.name,
|
|
26
|
-
type: exp.type
|
|
27
|
-
}));
|
|
28
|
-
const linesOfCode = code.split("\n").length;
|
|
29
|
-
const importDepth = await calculatePythonImportDepth(file, dependencyGraph, /* @__PURE__ */ new Set());
|
|
30
|
-
const contextBudget = estimateContextBudget(code, imports, dependencyGraph);
|
|
31
|
-
const cohesion = calculatePythonCohesion(exports, imports);
|
|
32
|
-
const circularDependencies = detectCircularDependencies(file, dependencyGraph);
|
|
33
|
-
results.push({
|
|
34
|
-
file,
|
|
35
|
-
importDepth,
|
|
36
|
-
contextBudget,
|
|
37
|
-
cohesion,
|
|
38
|
-
imports,
|
|
39
|
-
exports,
|
|
40
|
-
metrics: {
|
|
41
|
-
linesOfCode,
|
|
42
|
-
importCount: imports.length,
|
|
43
|
-
exportCount: exports.length,
|
|
44
|
-
circularDependencies
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
} catch (error) {
|
|
48
|
-
console.warn(`Failed to analyze ${file}:`, error);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return results;
|
|
52
|
-
}
|
|
53
|
-
async function buildPythonDependencyGraph(files, rootDir) {
|
|
54
|
-
const graph = /* @__PURE__ */ new Map();
|
|
55
|
-
const parser = getParser("dummy.py");
|
|
56
|
-
if (!parser) return graph;
|
|
57
|
-
for (const file of files) {
|
|
58
|
-
try {
|
|
59
|
-
const code = await fs.promises.readFile(file, "utf-8");
|
|
60
|
-
const result = parser.parse(code, file);
|
|
61
|
-
const dependencies = /* @__PURE__ */ new Set();
|
|
62
|
-
for (const imp of result.imports) {
|
|
63
|
-
const resolved = resolvePythonImport(file, imp.source, rootDir);
|
|
64
|
-
if (resolved && files.includes(resolved)) {
|
|
65
|
-
dependencies.add(resolved);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
graph.set(file, dependencies);
|
|
69
|
-
} catch (error) {
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return graph;
|
|
73
|
-
}
|
|
74
|
-
function resolvePythonImport(fromFile, importPath, rootDir) {
|
|
75
|
-
const dir = dirname(fromFile);
|
|
76
|
-
if (importPath.startsWith(".")) {
|
|
77
|
-
const parts = importPath.split(".");
|
|
78
|
-
let upCount = 0;
|
|
79
|
-
while (parts[0] === "") {
|
|
80
|
-
upCount++;
|
|
81
|
-
parts.shift();
|
|
82
|
-
}
|
|
83
|
-
let targetDir = dir;
|
|
84
|
-
for (let i = 0; i < upCount - 1; i++) {
|
|
85
|
-
targetDir = dirname(targetDir);
|
|
86
|
-
}
|
|
87
|
-
const modulePath = parts.join("/");
|
|
88
|
-
const possiblePaths = [
|
|
89
|
-
resolve(targetDir, `${modulePath}.py`),
|
|
90
|
-
resolve(targetDir, modulePath, "__init__.py")
|
|
91
|
-
];
|
|
92
|
-
for (const path of possiblePaths) {
|
|
93
|
-
if (fs.existsSync(path)) {
|
|
94
|
-
return path;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
} else {
|
|
98
|
-
const modulePath = importPath.replace(/\./g, "/");
|
|
99
|
-
const possiblePaths = [
|
|
100
|
-
resolve(rootDir, `${modulePath}.py`),
|
|
101
|
-
resolve(rootDir, modulePath, "__init__.py")
|
|
102
|
-
];
|
|
103
|
-
for (const path of possiblePaths) {
|
|
104
|
-
if (fs.existsSync(path)) {
|
|
105
|
-
return path;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return void 0;
|
|
110
|
-
}
|
|
111
|
-
async function calculatePythonImportDepth(file, dependencyGraph, visited, depth = 0) {
|
|
112
|
-
if (visited.has(file)) {
|
|
113
|
-
return depth;
|
|
114
|
-
}
|
|
115
|
-
visited.add(file);
|
|
116
|
-
const dependencies = dependencyGraph.get(file) || /* @__PURE__ */ new Set();
|
|
117
|
-
if (dependencies.size === 0) {
|
|
118
|
-
return depth;
|
|
119
|
-
}
|
|
120
|
-
let maxDepth = depth;
|
|
121
|
-
for (const dep of dependencies) {
|
|
122
|
-
const depDepth = await calculatePythonImportDepth(
|
|
123
|
-
dep,
|
|
124
|
-
dependencyGraph,
|
|
125
|
-
new Set(visited),
|
|
126
|
-
depth + 1
|
|
127
|
-
);
|
|
128
|
-
maxDepth = Math.max(maxDepth, depDepth);
|
|
129
|
-
}
|
|
130
|
-
return maxDepth;
|
|
131
|
-
}
|
|
132
|
-
function estimateContextBudget(code, imports, dependencyGraph) {
|
|
133
|
-
let budget = estimateTokens(code);
|
|
134
|
-
const avgTokensPerDep = 500;
|
|
135
|
-
budget += imports.length * avgTokensPerDep;
|
|
136
|
-
return budget;
|
|
137
|
-
}
|
|
138
|
-
function calculatePythonCohesion(exports, imports) {
|
|
139
|
-
if (exports.length === 0) return 1;
|
|
140
|
-
const exportCount = exports.length;
|
|
141
|
-
const importCount = imports.length;
|
|
142
|
-
let cohesion = 1;
|
|
143
|
-
if (exportCount > 10) {
|
|
144
|
-
cohesion *= 0.6;
|
|
145
|
-
} else if (exportCount > 5) {
|
|
146
|
-
cohesion *= 0.8;
|
|
147
|
-
}
|
|
148
|
-
if (exportCount > 0) {
|
|
149
|
-
const ratio = importCount / exportCount;
|
|
150
|
-
if (ratio > 2) {
|
|
151
|
-
cohesion *= 1.1;
|
|
152
|
-
} else if (ratio < 0.5) {
|
|
153
|
-
cohesion *= 0.9;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return Math.min(1, Math.max(0, cohesion));
|
|
157
|
-
}
|
|
158
|
-
function detectCircularDependencies(file, dependencyGraph) {
|
|
159
|
-
const circular = [];
|
|
160
|
-
const visited = /* @__PURE__ */ new Set();
|
|
161
|
-
const recursionStack = /* @__PURE__ */ new Set();
|
|
162
|
-
function dfs(current, path) {
|
|
163
|
-
if (recursionStack.has(current)) {
|
|
164
|
-
const cycleStart = path.indexOf(current);
|
|
165
|
-
const cycle = path.slice(cycleStart).concat([current]);
|
|
166
|
-
circular.push(cycle.join(" \u2192 "));
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (visited.has(current)) {
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
visited.add(current);
|
|
173
|
-
recursionStack.add(current);
|
|
174
|
-
const dependencies = dependencyGraph.get(current) || /* @__PURE__ */ new Set();
|
|
175
|
-
for (const dep of dependencies) {
|
|
176
|
-
dfs(dep, [...path, current]);
|
|
177
|
-
}
|
|
178
|
-
recursionStack.delete(current);
|
|
179
|
-
}
|
|
180
|
-
dfs(file, []);
|
|
181
|
-
return [...new Set(circular)];
|
|
182
|
-
}
|
|
183
|
-
export {
|
|
184
|
-
analyzePythonContext
|
|
185
|
-
};
|