@thelogicatelier/sylva 1.0.11 → 1.0.13
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/dist/awareness/braveSearch.js +6 -3
- package/dist/awareness/detector.d.ts +1 -0
- package/dist/awareness/detector.js +13 -33
- package/dist/awareness/index.js +165 -5
- package/dist/awareness/manifestParsers/goParsers.js +2 -11
- package/dist/awareness/manifestParsers/javaParsers.js +4 -22
- package/dist/awareness/manifestParsers/openclawParser.d.ts +16 -2
- package/dist/awareness/manifestParsers/openclawParser.js +532 -19
- package/dist/awareness/manifestParsers/packageJsonParser.js +2 -24
- package/dist/awareness/manifestParsers/pythonParsers.js +5 -21
- package/dist/awareness/manifestParsers/rustParsers.js +2 -12
- package/dist/awareness/manifestScanner.js +10 -69
- package/dist/awareness/sourceScanner.d.ts +5 -0
- package/dist/awareness/sourceScanner.js +179 -0
- package/dist/awareness/types.d.ts +1 -1
- package/dist/constants.d.ts +44 -0
- package/dist/constants.js +328 -1
- package/package.json +3 -2
|
@@ -43,23 +43,7 @@ exports.parsePipfile = parsePipfile;
|
|
|
43
43
|
exports.parseSetupCfg = parseSetupCfg;
|
|
44
44
|
const fs = __importStar(require("fs"));
|
|
45
45
|
const path = __importStar(require("path"));
|
|
46
|
-
|
|
47
|
-
const PYTHON_FRAMEWORKS = [
|
|
48
|
-
{ pkg: "django", frameworkId: "django", frameworkName: "Django" },
|
|
49
|
-
{ pkg: "flask", frameworkId: "flask", frameworkName: "Flask" },
|
|
50
|
-
{ pkg: "fastapi", frameworkId: "fastapi", frameworkName: "FastAPI" },
|
|
51
|
-
{ pkg: "uvicorn", frameworkId: "uvicorn", frameworkName: "Uvicorn" },
|
|
52
|
-
{ pkg: "starlette", frameworkId: "starlette", frameworkName: "Starlette" },
|
|
53
|
-
{ pkg: "celery", frameworkId: "celery", frameworkName: "Celery" },
|
|
54
|
-
{ pkg: "sqlalchemy", frameworkId: "sqlalchemy", frameworkName: "SQLAlchemy" },
|
|
55
|
-
{ pkg: "pandas", frameworkId: "pandas", frameworkName: "Pandas" },
|
|
56
|
-
{ pkg: "numpy", frameworkId: "numpy", frameworkName: "NumPy" },
|
|
57
|
-
{ pkg: "tensorflow", frameworkId: "tensorflow", frameworkName: "TensorFlow" },
|
|
58
|
-
{ pkg: "torch", frameworkId: "pytorch", frameworkName: "PyTorch" },
|
|
59
|
-
{ pkg: "scikit-learn", frameworkId: "scikit-learn", frameworkName: "scikit-learn" },
|
|
60
|
-
{ pkg: "pytest", frameworkId: "pytest", frameworkName: "pytest" },
|
|
61
|
-
{ pkg: "gunicorn", frameworkId: "gunicorn", frameworkName: "Gunicorn" },
|
|
62
|
-
];
|
|
46
|
+
const constants_1 = require("../../constants");
|
|
63
47
|
function parsePythonVersion(versionSpec, sourceFile, pkgName) {
|
|
64
48
|
if (!versionSpec || versionSpec.trim() === "") {
|
|
65
49
|
return { certainty: "unknown", sourceFile, notes: `No version for ${pkgName}` };
|
|
@@ -110,7 +94,7 @@ function parseRequirementsTxt(manifest) {
|
|
|
110
94
|
continue;
|
|
111
95
|
const pkgName = match[1].toLowerCase();
|
|
112
96
|
const versionSpec = match[2] || "";
|
|
113
|
-
const framework = PYTHON_FRAMEWORKS.find((f) => f.pkg === pkgName);
|
|
97
|
+
const framework = constants_1.PYTHON_FRAMEWORKS.find((f) => f.pkg === pkgName);
|
|
114
98
|
if (framework) {
|
|
115
99
|
const versionInfo = parsePythonVersion(versionSpec, manifest.relativePath, pkgName);
|
|
116
100
|
signals.push({
|
|
@@ -179,7 +163,7 @@ function parsePyprojectToml(manifest) {
|
|
|
179
163
|
if (simpleMatch) {
|
|
180
164
|
const pkgName = simpleMatch[1].toLowerCase();
|
|
181
165
|
const versionSpec = simpleMatch[2];
|
|
182
|
-
const framework = PYTHON_FRAMEWORKS.find((f) => f.pkg === pkgName);
|
|
166
|
+
const framework = constants_1.PYTHON_FRAMEWORKS.find((f) => f.pkg === pkgName);
|
|
183
167
|
if (framework) {
|
|
184
168
|
const isPinned = /^\d+\.\d+/.test(versionSpec) && !/[><=~^]/.test(versionSpec);
|
|
185
169
|
const versionInfo = isPinned
|
|
@@ -266,7 +250,7 @@ function parsePipfile(manifest) {
|
|
|
266
250
|
const match = line.trim().match(/^([a-zA-Z0-9_.-]+)\s*=\s*"([^"]*)"/);
|
|
267
251
|
if (match) {
|
|
268
252
|
const pkgName = match[1].toLowerCase();
|
|
269
|
-
const framework = PYTHON_FRAMEWORKS.find((f) => f.pkg === pkgName);
|
|
253
|
+
const framework = constants_1.PYTHON_FRAMEWORKS.find((f) => f.pkg === pkgName);
|
|
270
254
|
if (framework) {
|
|
271
255
|
const versionSpec = match[2];
|
|
272
256
|
const isExact = versionSpec === "*" ? false : /^\d+\.\d+/.test(versionSpec);
|
|
@@ -321,7 +305,7 @@ function parseSetupCfg(manifest) {
|
|
|
321
305
|
const match = trimmed.match(/^([a-zA-Z0-9_.-]+)\s*([><=~!]+.*)?$/);
|
|
322
306
|
if (match) {
|
|
323
307
|
const pkgName = match[1].toLowerCase();
|
|
324
|
-
const framework = PYTHON_FRAMEWORKS.find((f) => f.pkg === pkgName);
|
|
308
|
+
const framework = constants_1.PYTHON_FRAMEWORKS.find((f) => f.pkg === pkgName);
|
|
325
309
|
if (framework) {
|
|
326
310
|
const versionInfo = parsePythonVersion(match[2] || "", manifest.relativePath, pkgName);
|
|
327
311
|
signals.push({
|
|
@@ -40,17 +40,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
40
40
|
exports.parseCargoToml = parseCargoToml;
|
|
41
41
|
const fs = __importStar(require("fs"));
|
|
42
42
|
const path = __importStar(require("path"));
|
|
43
|
-
|
|
44
|
-
const RUST_FRAMEWORKS = [
|
|
45
|
-
{ crate: "actix-web", frameworkId: "actix-web", frameworkName: "Actix Web" },
|
|
46
|
-
{ crate: "rocket", frameworkId: "rocket", frameworkName: "Rocket" },
|
|
47
|
-
{ crate: "axum", frameworkId: "axum", frameworkName: "Axum" },
|
|
48
|
-
{ crate: "tokio", frameworkId: "tokio", frameworkName: "Tokio" },
|
|
49
|
-
{ crate: "serde", frameworkId: "serde", frameworkName: "Serde" },
|
|
50
|
-
{ crate: "diesel", frameworkId: "diesel", frameworkName: "Diesel" },
|
|
51
|
-
{ crate: "sqlx", frameworkId: "sqlx", frameworkName: "SQLx" },
|
|
52
|
-
{ crate: "warp", frameworkId: "warp", frameworkName: "Warp" },
|
|
53
|
-
];
|
|
43
|
+
const constants_1 = require("../../constants");
|
|
54
44
|
/**
|
|
55
45
|
* Parse Cargo.toml
|
|
56
46
|
*/
|
|
@@ -117,7 +107,7 @@ function parseCargoToml(manifest) {
|
|
|
117
107
|
}
|
|
118
108
|
if (!crateName)
|
|
119
109
|
continue;
|
|
120
|
-
const framework = RUST_FRAMEWORKS.find((f) => f.crate === crateName);
|
|
110
|
+
const framework = constants_1.RUST_FRAMEWORKS.find((f) => f.crate === crateName);
|
|
121
111
|
if (framework) {
|
|
122
112
|
let versionInfo;
|
|
123
113
|
if (versionStr) {
|
|
@@ -41,81 +41,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
41
41
|
exports.scanManifests = scanManifests;
|
|
42
42
|
const fs = __importStar(require("fs"));
|
|
43
43
|
const path = __importStar(require("path"));
|
|
44
|
+
const constants_1 = require("../constants");
|
|
44
45
|
/** Directories to skip during scanning */
|
|
45
|
-
const
|
|
46
|
-
".git",
|
|
47
|
-
"node_modules",
|
|
48
|
-
"__pycache__",
|
|
49
|
-
"venv",
|
|
50
|
-
".venv",
|
|
51
|
-
"env",
|
|
52
|
-
".env",
|
|
53
|
-
"dist",
|
|
54
|
-
"build",
|
|
55
|
-
"target",
|
|
56
|
-
"vendor",
|
|
57
|
-
"bin",
|
|
58
|
-
"obj",
|
|
59
|
-
"out",
|
|
60
|
-
"coverage",
|
|
61
|
-
"logs",
|
|
62
|
-
"tmp",
|
|
63
|
-
"temp",
|
|
64
|
-
".idea",
|
|
65
|
-
".vscode",
|
|
66
|
-
".next",
|
|
67
|
-
".nuxt",
|
|
68
|
-
".svelte-kit",
|
|
69
|
-
".angular",
|
|
70
|
-
".DS_Store",
|
|
71
|
-
]);
|
|
46
|
+
const IGNORE_DIRS_SET = new Set(constants_1.SCAN_IGNORE_DIRS);
|
|
72
47
|
/** Exact filenames to match as manifests */
|
|
73
|
-
const MANIFEST_EXACT_NAMES = new Set(
|
|
74
|
-
"package.json",
|
|
75
|
-
"package-lock.json",
|
|
76
|
-
"yarn.lock",
|
|
77
|
-
"pnpm-lock.yaml",
|
|
78
|
-
"openclaw.json",
|
|
79
|
-
".openclaw.json",
|
|
80
|
-
"angular.json",
|
|
81
|
-
"workspace.json",
|
|
82
|
-
"project.json",
|
|
83
|
-
"pyproject.toml",
|
|
84
|
-
"requirements.txt",
|
|
85
|
-
"poetry.lock",
|
|
86
|
-
"Pipfile",
|
|
87
|
-
"Pipfile.lock",
|
|
88
|
-
"setup.cfg",
|
|
89
|
-
"setup.py",
|
|
90
|
-
"pom.xml",
|
|
91
|
-
"build.gradle",
|
|
92
|
-
"build.gradle.kts",
|
|
93
|
-
"settings.gradle",
|
|
94
|
-
"settings.gradle.kts",
|
|
95
|
-
"gradle.properties",
|
|
96
|
-
"go.mod",
|
|
97
|
-
"go.sum",
|
|
98
|
-
"Cargo.toml",
|
|
99
|
-
"Cargo.lock",
|
|
100
|
-
"global.json",
|
|
101
|
-
"packages.lock.json",
|
|
102
|
-
"Dockerfile",
|
|
103
|
-
"docker-compose.yml",
|
|
104
|
-
"docker-compose.yaml",
|
|
105
|
-
"Makefile",
|
|
106
|
-
".gitlab-ci.yml",
|
|
107
|
-
]);
|
|
108
|
-
/** File extension patterns for manifests (e.g. *.csproj) */
|
|
109
|
-
const MANIFEST_EXTENSION_PATTERNS = [".csproj", ".fsproj", ".vbproj"];
|
|
110
|
-
/** Maximum file size in characters to read */
|
|
111
|
-
const MAX_FILE_SIZE = 500_000;
|
|
48
|
+
const MANIFEST_EXACT_NAMES = new Set(constants_1.MANIFEST_EXACT_NAMES);
|
|
112
49
|
/**
|
|
113
50
|
* Check if a filename matches a known manifest pattern.
|
|
114
51
|
*/
|
|
115
52
|
function isManifestFile(filename) {
|
|
116
53
|
if (MANIFEST_EXACT_NAMES.has(filename))
|
|
117
54
|
return true;
|
|
118
|
-
for (const ext of MANIFEST_EXTENSION_PATTERNS) {
|
|
55
|
+
for (const ext of constants_1.MANIFEST_EXTENSION_PATTERNS) {
|
|
119
56
|
if (filename.endsWith(ext))
|
|
120
57
|
return true;
|
|
121
58
|
}
|
|
@@ -142,7 +79,7 @@ function scanManifests(repoPath) {
|
|
|
142
79
|
}
|
|
143
80
|
for (const entry of entries) {
|
|
144
81
|
// Skip ignored directories and hidden dirs (except specific manifest patterns)
|
|
145
|
-
if (
|
|
82
|
+
if (IGNORE_DIRS_SET.has(entry))
|
|
146
83
|
continue;
|
|
147
84
|
const fullPath = path.join(dir, entry);
|
|
148
85
|
let stat;
|
|
@@ -160,7 +97,11 @@ function scanManifests(repoPath) {
|
|
|
160
97
|
walk(fullPath, depth + 1);
|
|
161
98
|
}
|
|
162
99
|
else if (stat.isFile()) {
|
|
163
|
-
if (isManifestFile(entry)
|
|
100
|
+
if (isManifestFile(entry)) {
|
|
101
|
+
if (stat.size > constants_1.MAX_MANIFEST_FILE_SIZE) {
|
|
102
|
+
// File is too large, skip it
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
164
105
|
results.push({
|
|
165
106
|
absolutePath: fullPath,
|
|
166
107
|
relativePath: path.relative(absoluteRoot, fullPath),
|
|
@@ -0,0 +1,179 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.scanSourceFiles = scanSourceFiles;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const ignore_1 = __importDefault(require("ignore"));
|
|
43
|
+
const constants_1 = require("../constants");
|
|
44
|
+
const MAX_SCAN_FILES = 200;
|
|
45
|
+
const MAX_LINES_PER_FILE = 500;
|
|
46
|
+
/**
|
|
47
|
+
* Loads .gitignore rules from the root if available
|
|
48
|
+
*/
|
|
49
|
+
function loadGitIgnore(rootPath) {
|
|
50
|
+
const ig = (0, ignore_1.default)();
|
|
51
|
+
// Add hardcoded global ignores
|
|
52
|
+
for (const item of constants_1.SCAN_IGNORE_DIRS)
|
|
53
|
+
ig.add(`**/${item}/**`);
|
|
54
|
+
for (const item of constants_1.ALWAYS_IGNORE_FILES)
|
|
55
|
+
ig.add(`**/${item}`);
|
|
56
|
+
ig.add("**/*.env*"); // Cover all .env permutations globally
|
|
57
|
+
try {
|
|
58
|
+
const gitignorePath = path.join(rootPath, ".gitignore");
|
|
59
|
+
if (fs.existsSync(gitignorePath)) {
|
|
60
|
+
const content = fs.readFileSync(gitignorePath, "utf-8");
|
|
61
|
+
ig.add(content);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Ignore errors reading .gitignore
|
|
66
|
+
}
|
|
67
|
+
return ig;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Collect source files sequentially via BFS
|
|
71
|
+
*/
|
|
72
|
+
function collectSourceFiles(dir, ig, rootPath, files = []) {
|
|
73
|
+
if (files.length >= MAX_SCAN_FILES)
|
|
74
|
+
return files;
|
|
75
|
+
try {
|
|
76
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
77
|
+
for (const entry of entries) {
|
|
78
|
+
if (files.length >= MAX_SCAN_FILES)
|
|
79
|
+
break;
|
|
80
|
+
const fullPath = path.join(dir, entry.name);
|
|
81
|
+
// Ensure posix path for gitignore matching
|
|
82
|
+
const relPath = path.relative(rootPath, fullPath).split(path.sep).join(path.posix.sep);
|
|
83
|
+
// Skip ignored files/directories
|
|
84
|
+
// Note: ignore().ignores() requires directory paths to end with '/' to match properly sometimes,
|
|
85
|
+
// but relPath works fine for most rules.
|
|
86
|
+
if (ig.ignores(relPath))
|
|
87
|
+
continue;
|
|
88
|
+
if (entry.isDirectory()) {
|
|
89
|
+
if (!ig.ignores(relPath + "/")) {
|
|
90
|
+
collectSourceFiles(fullPath, ig, rootPath, files);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (entry.isFile()) {
|
|
94
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
95
|
+
if (constants_1.SOURCE_EXTENSIONS.includes(ext)) {
|
|
96
|
+
files.push(fullPath);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// access errors skipped
|
|
103
|
+
}
|
|
104
|
+
return files;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Heuristic: check if this phrase occurs in the text
|
|
108
|
+
*/
|
|
109
|
+
function matchPatterns(content, patterns = []) {
|
|
110
|
+
for (const pat of patterns) {
|
|
111
|
+
if (content.includes(pat))
|
|
112
|
+
return pat;
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Scan source codebase for integrations.
|
|
118
|
+
*/
|
|
119
|
+
function scanSourceFiles(rootPath) {
|
|
120
|
+
const ig = loadGitIgnore(rootPath);
|
|
121
|
+
const targetFiles = collectSourceFiles(rootPath, ig, rootPath);
|
|
122
|
+
const signals = [];
|
|
123
|
+
const detectedIntegrationIds = new Set();
|
|
124
|
+
for (const file of targetFiles) {
|
|
125
|
+
try {
|
|
126
|
+
// Read file and limit to N lines to keep it fast
|
|
127
|
+
const contentRaw = fs.readFileSync(file, "utf-8");
|
|
128
|
+
let content = contentRaw;
|
|
129
|
+
const lines = contentRaw.split("\n");
|
|
130
|
+
if (lines.length > MAX_LINES_PER_FILE) {
|
|
131
|
+
content = lines.slice(0, MAX_LINES_PER_FILE).join("\n");
|
|
132
|
+
}
|
|
133
|
+
// Check all integrations against this chunk
|
|
134
|
+
for (const integration of constants_1.INTEGRATIONS) {
|
|
135
|
+
if (detectedIntegrationIds.has(integration.id))
|
|
136
|
+
continue; // Found it already somewhere
|
|
137
|
+
let reason = "";
|
|
138
|
+
let matchedPattern = "";
|
|
139
|
+
matchedPattern = matchPatterns(content, integration.urlPatterns) || "";
|
|
140
|
+
if (matchedPattern) {
|
|
141
|
+
reason = `Found API URL pattern "${matchedPattern}"`;
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
matchedPattern = matchPatterns(content, integration.importPatterns) || "";
|
|
145
|
+
if (matchedPattern) {
|
|
146
|
+
reason = `Found SDK import pattern "${matchedPattern}"`;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
matchedPattern = matchPatterns(content, integration.envPatterns) || "";
|
|
150
|
+
if (matchedPattern) {
|
|
151
|
+
reason = `Found env var reference "${matchedPattern}"`;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (reason) {
|
|
156
|
+
detectedIntegrationIds.add(integration.id);
|
|
157
|
+
signals.push({
|
|
158
|
+
kind: "integration",
|
|
159
|
+
frameworkId: integration.id,
|
|
160
|
+
frameworkName: integration.name,
|
|
161
|
+
version: { certainty: "unknown", value: undefined },
|
|
162
|
+
evidence: {
|
|
163
|
+
file: path.relative(rootPath, file),
|
|
164
|
+
reason: `Source code scanner detected ${integration.name}: ${reason}`,
|
|
165
|
+
},
|
|
166
|
+
scope: { pathRoot: rootPath },
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// If we found everything, stop scanning
|
|
171
|
+
if (detectedIntegrationIds.size === constants_1.INTEGRATIONS.length)
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Ignore unreadable files
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return signals;
|
|
179
|
+
}
|
|
@@ -13,7 +13,7 @@ export interface VersionInfo {
|
|
|
13
13
|
notes?: string;
|
|
14
14
|
}
|
|
15
15
|
/** Signal kinds emitted by manifest parsers */
|
|
16
|
-
export type SignalKind = "framework" | "version" | "orchestrator" | "entrypoint" | "tooling";
|
|
16
|
+
export type SignalKind = "framework" | "version" | "orchestrator" | "entrypoint" | "tooling" | "agent" | "subagent" | "heartbeat" | "cron" | "hook" | "skill" | "plugin" | "integration";
|
|
17
17
|
/** Evidence for a detected signal */
|
|
18
18
|
export interface SignalEvidence {
|
|
19
19
|
file: string;
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared programmatic constants and integration registries for Sylva.
|
|
3
|
+
*/
|
|
1
4
|
export interface ModelMetadata {
|
|
2
5
|
provider: string;
|
|
3
6
|
tier: "primary" | "mini";
|
|
@@ -16,3 +19,44 @@ export declare const IGNORED_DIRS: Set<string>;
|
|
|
16
19
|
* source tree so the AI reads them FIRST, preventing framework hallucination.
|
|
17
20
|
*/
|
|
18
21
|
export declare const DEPENDENCY_MANIFESTS: Set<string>;
|
|
22
|
+
export interface IntegrationDef {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
urlPatterns?: string[];
|
|
26
|
+
importPatterns?: string[];
|
|
27
|
+
envPatterns?: string[];
|
|
28
|
+
}
|
|
29
|
+
export declare const INTEGRATIONS: IntegrationDef[];
|
|
30
|
+
export declare const SOURCE_EXTENSIONS: string[];
|
|
31
|
+
export declare const SCAN_IGNORE_DIRS: string[];
|
|
32
|
+
export declare const ALWAYS_IGNORE_FILES: string[];
|
|
33
|
+
export declare const MANIFEST_EXACT_NAMES: string[];
|
|
34
|
+
export declare const MANIFEST_EXTENSION_PATTERNS: string[];
|
|
35
|
+
export declare const MAX_MANIFEST_FILE_SIZE = 500000;
|
|
36
|
+
/** Confidence scoring rules mapped by framework ID */
|
|
37
|
+
export declare const CONFIDENCE_SCORES: Record<string, number>;
|
|
38
|
+
export declare const NPM_FRAMEWORKS: {
|
|
39
|
+
depPattern: string | RegExp;
|
|
40
|
+
frameworkId: string;
|
|
41
|
+
frameworkName: string;
|
|
42
|
+
}[];
|
|
43
|
+
export declare const PYTHON_FRAMEWORKS: {
|
|
44
|
+
pkg: string;
|
|
45
|
+
frameworkId: string;
|
|
46
|
+
frameworkName: string;
|
|
47
|
+
}[];
|
|
48
|
+
export declare const JAVA_FRAMEWORKS: {
|
|
49
|
+
groupArtifact: string;
|
|
50
|
+
frameworkId: string;
|
|
51
|
+
frameworkName: string;
|
|
52
|
+
}[];
|
|
53
|
+
export declare const GO_FRAMEWORKS: {
|
|
54
|
+
module: string;
|
|
55
|
+
frameworkId: string;
|
|
56
|
+
frameworkName: string;
|
|
57
|
+
}[];
|
|
58
|
+
export declare const RUST_FRAMEWORKS: {
|
|
59
|
+
crate: string;
|
|
60
|
+
frameworkId: string;
|
|
61
|
+
frameworkName: string;
|
|
62
|
+
}[];
|