@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
|
@@ -83,21 +83,24 @@ async function braveSearch(query, options) {
|
|
|
83
83
|
});
|
|
84
84
|
if (!response.ok) {
|
|
85
85
|
const statusText = response.statusText || "Unknown error";
|
|
86
|
+
const errorMsg = `HTTP ${response.status} (${statusText})`;
|
|
86
87
|
if (response.status === 401 || response.status === 403) {
|
|
87
88
|
console.warn(`❌ Brave Search API authentication failed (HTTP ${response.status}: ${statusText}).\n` +
|
|
88
89
|
` Your BRAVE_API_KEY may be invalid or expired.\n` +
|
|
89
90
|
` Get a valid key at: https://brave.com/search/api/\n` +
|
|
90
91
|
` Framework detection still works — only web doc references are affected.`);
|
|
92
|
+
throw new Error(`Authentication failed ${errorMsg}. Valid API key required.`);
|
|
91
93
|
}
|
|
92
94
|
else if (response.status === 429) {
|
|
93
95
|
console.warn(`⚠️ Brave Search API rate limit exceeded (HTTP 429).\n` +
|
|
94
96
|
` Query: "${query}"\n` +
|
|
95
97
|
` Wait a moment and retry, or check your Brave API plan limits.`);
|
|
98
|
+
throw new Error(`Rate limit exceeded ${errorMsg}.`);
|
|
96
99
|
}
|
|
97
100
|
else {
|
|
98
101
|
console.warn(`⚠️ Brave Search API returned HTTP ${response.status} (${statusText}) for query: "${query}"`);
|
|
102
|
+
throw new Error(`Brave Search API error: ${errorMsg}`);
|
|
99
103
|
}
|
|
100
|
-
return [];
|
|
101
104
|
}
|
|
102
105
|
const data = (await response.json());
|
|
103
106
|
const webResults = data.web?.results || [];
|
|
@@ -120,10 +123,10 @@ async function braveSearch(query, options) {
|
|
|
120
123
|
console.warn(`⚠️ Brave Search network error for query "${query}": ${errMsg}\n` +
|
|
121
124
|
` Check your internet connection. Framework detection is unaffected.`);
|
|
122
125
|
}
|
|
123
|
-
else {
|
|
126
|
+
else if (!errMsg.includes("HTTP")) {
|
|
124
127
|
console.warn(`⚠️ Brave Search failed for query "${query}": ${errMsg}`);
|
|
125
128
|
}
|
|
126
|
-
|
|
129
|
+
throw error;
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
132
|
/**
|
|
@@ -8,37 +8,8 @@ exports.detectStacks = detectStacks;
|
|
|
8
8
|
exports.detectArchitecture = detectArchitecture;
|
|
9
9
|
exports.formatVersionForDisplay = formatVersionForDisplay;
|
|
10
10
|
const versionResolver_1 = require("./versionResolver");
|
|
11
|
+
const constants_1 = require("../constants");
|
|
11
12
|
/** Confidence scoring rules */
|
|
12
|
-
const CONFIDENCE_SCORES = {
|
|
13
|
-
orchestrator: 95,
|
|
14
|
-
angular: 85,
|
|
15
|
-
react: 80,
|
|
16
|
-
nextjs: 85,
|
|
17
|
-
vue: 80,
|
|
18
|
-
nuxt: 85,
|
|
19
|
-
svelte: 80,
|
|
20
|
-
sveltekit: 85,
|
|
21
|
-
express: 75,
|
|
22
|
-
nestjs: 85,
|
|
23
|
-
fastify: 75,
|
|
24
|
-
django: 85,
|
|
25
|
-
flask: 75,
|
|
26
|
-
fastapi: 80,
|
|
27
|
-
"spring-boot": 90,
|
|
28
|
-
spring: 80,
|
|
29
|
-
"java-maven": 70,
|
|
30
|
-
"java-gradle": 70,
|
|
31
|
-
dotnet: 80,
|
|
32
|
-
"aspnet-core": 85,
|
|
33
|
-
go: 80,
|
|
34
|
-
rust: 80,
|
|
35
|
-
"actix-web": 85,
|
|
36
|
-
axum: 85,
|
|
37
|
-
nodejs: 60,
|
|
38
|
-
python: 60,
|
|
39
|
-
typescript: 65,
|
|
40
|
-
docker: 50,
|
|
41
|
-
};
|
|
42
13
|
/**
|
|
43
14
|
* Detect stacks from signals.
|
|
44
15
|
* Groups signals by frameworkId and scores confidence.
|
|
@@ -46,8 +17,17 @@ const CONFIDENCE_SCORES = {
|
|
|
46
17
|
function detectStacks(signals) {
|
|
47
18
|
const grouped = new Map();
|
|
48
19
|
for (const signal of signals) {
|
|
49
|
-
// Skip
|
|
50
|
-
if (signal.kind === "tooling" ||
|
|
20
|
+
// Skip non-framework signals from stack detection
|
|
21
|
+
if (signal.kind === "tooling" ||
|
|
22
|
+
signal.kind === "entrypoint" ||
|
|
23
|
+
signal.kind === "agent" ||
|
|
24
|
+
signal.kind === "subagent" ||
|
|
25
|
+
signal.kind === "heartbeat" ||
|
|
26
|
+
signal.kind === "cron" ||
|
|
27
|
+
signal.kind === "hook" ||
|
|
28
|
+
signal.kind === "skill" ||
|
|
29
|
+
signal.kind === "plugin" ||
|
|
30
|
+
signal.kind === "integration")
|
|
51
31
|
continue;
|
|
52
32
|
if (!grouped.has(signal.frameworkId)) {
|
|
53
33
|
grouped.set(signal.frameworkId, []);
|
|
@@ -57,7 +37,7 @@ function detectStacks(signals) {
|
|
|
57
37
|
const stacks = [];
|
|
58
38
|
for (const [frameworkId, frameworkSignals] of grouped) {
|
|
59
39
|
const frameworkName = frameworkSignals[0].frameworkName;
|
|
60
|
-
const confidence = CONFIDENCE_SCORES[frameworkId] || 50;
|
|
40
|
+
const confidence = constants_1.CONFIDENCE_SCORES[frameworkId] || 50;
|
|
61
41
|
const version = (0, versionResolver_1.resolveVersion)(frameworkSignals);
|
|
62
42
|
// Determine rootPath — use the shallowest signal's scope
|
|
63
43
|
const rootPaths = frameworkSignals.map((s) => s.scope.pathRoot).filter(Boolean);
|
package/dist/awareness/index.js
CHANGED
|
@@ -46,11 +46,12 @@ const manifestParsers_1 = require("./manifestParsers");
|
|
|
46
46
|
const versionResolver_1 = require("./versionResolver");
|
|
47
47
|
const detector_1 = require("./detector");
|
|
48
48
|
const webGrounding_1 = require("./webGrounding");
|
|
49
|
+
const sourceScanner_1 = require("./sourceScanner");
|
|
49
50
|
/**
|
|
50
51
|
* The ARCHITECTURE CONSTRAINTS block injected into LLM context.
|
|
51
52
|
* This is authoritative and must not be overridden by the model.
|
|
52
53
|
*/
|
|
53
|
-
function buildConstraintsBlock(stacks, resolvedVersions, hasOrchestrator) {
|
|
54
|
+
function buildConstraintsBlock(stacks, resolvedVersions, hasOrchestrator, signals) {
|
|
54
55
|
const lines = [
|
|
55
56
|
"=== ARCHITECTURE CONSTRAINTS (AUTHORITATIVE) ===",
|
|
56
57
|
"1) The detected frameworks/stacks listed below are authoritative because they were derived from repository manifest/config files.",
|
|
@@ -78,9 +79,80 @@ function buildConstraintsBlock(stacks, resolvedVersions, hasOrchestrator) {
|
|
|
78
79
|
lines.push(` Evidence: ${ev.evidence.reason} [${ev.evidence.file}]`);
|
|
79
80
|
}
|
|
80
81
|
}
|
|
82
|
+
// OpenClaw-specific constraint sections (only when detected)
|
|
83
|
+
if (hasOrchestrator) {
|
|
84
|
+
appendOpenClawConstraints(lines, signals);
|
|
85
|
+
}
|
|
86
|
+
// External Integrations (source code scanner)
|
|
87
|
+
const integrations = signals.filter((s) => s.kind === "integration");
|
|
88
|
+
if (integrations.length > 0) {
|
|
89
|
+
lines.push("", "EXTERNAL INTEGRATIONS (Discovered in Source Code):");
|
|
90
|
+
for (const sig of integrations) {
|
|
91
|
+
lines.push(` - ${sig.frameworkName}`);
|
|
92
|
+
lines.push(` Evidence: ${sig.evidence.reason} [${sig.evidence.file}]`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
81
95
|
lines.push("=== END ARCHITECTURE CONSTRAINTS ===");
|
|
82
96
|
return lines.join("\n");
|
|
83
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Append OpenClaw-specific sections to the constraints block.
|
|
100
|
+
* Groups signals by kind (agent, hook, skill, subagent, plugin, heartbeat).
|
|
101
|
+
*/
|
|
102
|
+
function appendOpenClawConstraints(lines, signals) {
|
|
103
|
+
// Agent config
|
|
104
|
+
const agentSignals = signals.filter((s) => s.kind === "agent");
|
|
105
|
+
if (agentSignals.length > 0) {
|
|
106
|
+
lines.push("", "OPENCLAW AGENT CONFIG:");
|
|
107
|
+
for (const sig of agentSignals) {
|
|
108
|
+
lines.push(` - ${sig.frameworkName}: ${sig.evidence.excerpt}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Hooks
|
|
112
|
+
const hookSignals = signals.filter((s) => s.kind === "hook");
|
|
113
|
+
if (hookSignals.length > 0) {
|
|
114
|
+
lines.push("", "OPENCLAW HOOKS:");
|
|
115
|
+
for (const sig of hookSignals) {
|
|
116
|
+
const name = sig.frameworkName.replace("OpenClaw Hook: ", "");
|
|
117
|
+
lines.push(` - /${name}: ${sig.evidence.reason}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Skills
|
|
121
|
+
const skillSignals = signals.filter((s) => s.kind === "skill");
|
|
122
|
+
if (skillSignals.length > 0) {
|
|
123
|
+
lines.push("", "OPENCLAW SKILLS:");
|
|
124
|
+
for (const sig of skillSignals) {
|
|
125
|
+
lines.push(` - ${sig.frameworkName.replace("OpenClaw Skill: ", "")}: ${sig.evidence.reason}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Subagents
|
|
129
|
+
const subagentSignals = signals.filter((s) => s.kind === "subagent");
|
|
130
|
+
if (subagentSignals.length > 0) {
|
|
131
|
+
lines.push("", "OPENCLAW SUBAGENTS:");
|
|
132
|
+
for (const sig of subagentSignals) {
|
|
133
|
+
lines.push(` - ${sig.frameworkName.replace("OpenClaw Subagent: ", "")}: ${sig.evidence.reason}`);
|
|
134
|
+
if (sig.evidence.excerpt) {
|
|
135
|
+
lines.push(` ${sig.evidence.excerpt}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Plugins
|
|
140
|
+
const pluginSignals = signals.filter((s) => s.kind === "plugin");
|
|
141
|
+
if (pluginSignals.length > 0) {
|
|
142
|
+
lines.push("", "OPENCLAW PLUGINS:");
|
|
143
|
+
for (const sig of pluginSignals) {
|
|
144
|
+
lines.push(` - ${sig.frameworkName.replace("OpenClaw Plugin: ", "")}: ${sig.evidence.excerpt}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Heartbeat
|
|
148
|
+
const heartbeatSignals = signals.filter((s) => s.kind === "heartbeat");
|
|
149
|
+
if (heartbeatSignals.length > 0) {
|
|
150
|
+
lines.push("", "OPENCLAW HEARTBEAT:");
|
|
151
|
+
for (const sig of heartbeatSignals) {
|
|
152
|
+
lines.push(` - ${sig.evidence.excerpt}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
84
156
|
/**
|
|
85
157
|
* Build the full awareness context string for LLM prompts.
|
|
86
158
|
*/
|
|
@@ -170,6 +242,65 @@ function saveAwarenessJson(repoName, result, baseDir = "projects") {
|
|
|
170
242
|
` Check disk space and directory write permissions if you need this output.`);
|
|
171
243
|
}
|
|
172
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* Save grounding.json for web grounding transparency.
|
|
247
|
+
* Always saved — contains references + structured errors.
|
|
248
|
+
*/
|
|
249
|
+
function saveGroundingJson(repoName, webReferences, errors, baseDir = "projects") {
|
|
250
|
+
const folderName = repoName.toLowerCase().replace(/\s+/g, "-");
|
|
251
|
+
const targetDir = path.join(baseDir, folderName);
|
|
252
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
253
|
+
const filePath = path.join(targetDir, "grounding.json");
|
|
254
|
+
try {
|
|
255
|
+
// Build structured error entries
|
|
256
|
+
const structuredErrors = errors.map((err) => {
|
|
257
|
+
// Parse known error patterns
|
|
258
|
+
if (err.includes("BRAVE_API_KEY not set")) {
|
|
259
|
+
return {
|
|
260
|
+
reason: "BRAVE_API_KEY not set",
|
|
261
|
+
impact: "Web grounding disabled — no documentation references gathered",
|
|
262
|
+
resolution: "Set BRAVE_API_KEY in your .env file. Get a free key at https://brave.com/search/api/",
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
if (err.includes("rate limit") || err.includes("HTTP 429")) {
|
|
266
|
+
const queryMatch = err.match(/Query: "([^"]+)"/);
|
|
267
|
+
return {
|
|
268
|
+
query: queryMatch ? queryMatch[1] : undefined,
|
|
269
|
+
reason: "Brave Search API rate limit exceeded (HTTP 429)",
|
|
270
|
+
impact: "Results missing for this query",
|
|
271
|
+
resolution: "Wait a moment and retry, or check your Brave API plan limits",
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
if (err.includes("Web search failed")) {
|
|
275
|
+
const queryMatch = err.match(/for "([^"]+)"/);
|
|
276
|
+
const reasonMatch = err.match(/: (.+)$/);
|
|
277
|
+
return {
|
|
278
|
+
query: queryMatch ? queryMatch[1] : undefined,
|
|
279
|
+
reason: reasonMatch ? reasonMatch[1] : err,
|
|
280
|
+
impact: "Results missing for this query",
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
reason: err,
|
|
285
|
+
impact: "Unknown web grounding error",
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
const grounding = {
|
|
289
|
+
generatedAt: new Date().toISOString(),
|
|
290
|
+
totalReferences: webReferences.reduce((sum, ref) => sum + ref.results.length, 0),
|
|
291
|
+
frameworksCovered: webReferences.length,
|
|
292
|
+
references: webReferences,
|
|
293
|
+
errors: structuredErrors,
|
|
294
|
+
};
|
|
295
|
+
fs.writeFileSync(filePath, JSON.stringify(grounding, null, 2), "utf-8");
|
|
296
|
+
console.log(`✅ Saved grounding.json to: ${filePath}`);
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
console.warn(`⚠️ Could not save grounding.json to ${filePath}: ${error.message}\n` +
|
|
300
|
+
` This is a debug file and does not affect AGENTS.md generation.\n` +
|
|
301
|
+
` Check disk space and directory write permissions if you need this output.`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
173
304
|
/**
|
|
174
305
|
* Run the full awareness pipeline.
|
|
175
306
|
* This is the main entry point called from the CLI.
|
|
@@ -190,8 +321,16 @@ async function runAwareness(repoPath, repoName) {
|
|
|
190
321
|
}
|
|
191
322
|
// Step 2: Parse all manifests into signals
|
|
192
323
|
console.log(" → Parsing manifests...");
|
|
193
|
-
const
|
|
194
|
-
console.log(` → Generated ${
|
|
324
|
+
const manifestSignals = (0, manifestParsers_1.parseAllManifests)(manifests);
|
|
325
|
+
console.log(` → Generated ${manifestSignals.length} signal(s) from manifests`);
|
|
326
|
+
// Step 2.5: Scan source code for external integrations
|
|
327
|
+
console.log(" → Scanning source code for external integrations...");
|
|
328
|
+
const integrationSignals = (0, sourceScanner_1.scanSourceFiles)(repoPath);
|
|
329
|
+
if (integrationSignals.length > 0) {
|
|
330
|
+
console.log(` → Discovered ${integrationSignals.length} integration(s) in source code`);
|
|
331
|
+
}
|
|
332
|
+
// Merge all signals
|
|
333
|
+
const signals = [...manifestSignals, ...integrationSignals];
|
|
195
334
|
// Step 3: Resolve versions
|
|
196
335
|
console.log(" → Resolving versions...");
|
|
197
336
|
const resolvedVersions = (0, versionResolver_1.resolveAllVersions)(signals);
|
|
@@ -210,9 +349,28 @@ async function runAwareness(repoPath, repoName) {
|
|
|
210
349
|
}
|
|
211
350
|
if (hasOrchestrator) {
|
|
212
351
|
console.log(" 🎯 OpenClaw orchestrator detected");
|
|
352
|
+
// Log OpenClaw-specific discoveries
|
|
353
|
+
const hookCount = signals.filter((s) => s.kind === "hook").length;
|
|
354
|
+
const skillCount = signals.filter((s) => s.kind === "skill").length;
|
|
355
|
+
const subagentCount = signals.filter((s) => s.kind === "subagent").length;
|
|
356
|
+
const pluginCount = signals.filter((s) => s.kind === "plugin").length;
|
|
357
|
+
if (hookCount > 0)
|
|
358
|
+
console.log(` 🪝 ${hookCount} hook(s) detected`);
|
|
359
|
+
if (skillCount > 0)
|
|
360
|
+
console.log(` 🎯 ${skillCount} skill(s) detected`);
|
|
361
|
+
if (subagentCount > 0)
|
|
362
|
+
console.log(` 🤖 ${subagentCount} subagent(s) detected`);
|
|
363
|
+
if (pluginCount > 0)
|
|
364
|
+
console.log(` 🔌 ${pluginCount} plugin(s) detected`);
|
|
365
|
+
const heartbeat = signals.find((s) => s.kind === "heartbeat");
|
|
366
|
+
if (heartbeat) {
|
|
367
|
+
const active = heartbeat.evidence.excerpt?.includes("ACTIVE") &&
|
|
368
|
+
!heartbeat.evidence.excerpt?.includes("INACTIVE");
|
|
369
|
+
console.log(` 💓 Heartbeat: ${active ? "ACTIVE" : "INACTIVE"}`);
|
|
370
|
+
}
|
|
213
371
|
}
|
|
214
|
-
// Step 5: Build constraints block
|
|
215
|
-
const constraintsBlock = buildConstraintsBlock(stacks, resolvedVersions, hasOrchestrator);
|
|
372
|
+
// Step 5: Build constraints block (now includes OpenClaw-specific sections)
|
|
373
|
+
const constraintsBlock = buildConstraintsBlock(stacks, resolvedVersions, hasOrchestrator, signals);
|
|
216
374
|
// Step 6: Web grounding
|
|
217
375
|
console.log(" → Gathering web references...");
|
|
218
376
|
const cacheDir = path.join("projects", repoName.toLowerCase().replace(/\s+/g, "-"), "cache", "brave");
|
|
@@ -254,6 +412,8 @@ async function runAwareness(repoPath, repoName) {
|
|
|
254
412
|
};
|
|
255
413
|
// Step 8: Save awareness.json
|
|
256
414
|
saveAwarenessJson(repoName, result);
|
|
415
|
+
// Step 9: Save grounding.json (always, even on errors)
|
|
416
|
+
saveGroundingJson(repoName, webReferences, errors);
|
|
257
417
|
console.log("✅ Framework Awareness scan complete\n");
|
|
258
418
|
return result;
|
|
259
419
|
}
|
|
@@ -40,16 +40,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
40
40
|
exports.parseGoMod = parseGoMod;
|
|
41
41
|
const fs = __importStar(require("fs"));
|
|
42
42
|
const path = __importStar(require("path"));
|
|
43
|
-
|
|
44
|
-
const GO_FRAMEWORKS = [
|
|
45
|
-
{ module: "github.com/gin-gonic/gin", frameworkId: "gin", frameworkName: "Gin" },
|
|
46
|
-
{ module: "github.com/labstack/echo", frameworkId: "echo", frameworkName: "Echo" },
|
|
47
|
-
{ module: "github.com/gofiber/fiber", frameworkId: "fiber", frameworkName: "Fiber" },
|
|
48
|
-
{ module: "github.com/gorilla/mux", frameworkId: "gorilla-mux", frameworkName: "Gorilla Mux" },
|
|
49
|
-
{ module: "gorm.io/gorm", frameworkId: "gorm", frameworkName: "GORM" },
|
|
50
|
-
{ module: "github.com/stretchr/testify", frameworkId: "testify", frameworkName: "Testify" },
|
|
51
|
-
{ module: "google.golang.org/grpc", frameworkId: "grpc-go", frameworkName: "gRPC-Go" },
|
|
52
|
-
];
|
|
43
|
+
const constants_1 = require("../../constants");
|
|
53
44
|
/**
|
|
54
45
|
* Parse go.mod
|
|
55
46
|
*/
|
|
@@ -117,7 +108,7 @@ function parseGoMod(manifest) {
|
|
|
117
108
|
continue;
|
|
118
109
|
const modulePath = match[1];
|
|
119
110
|
const version = match[2];
|
|
120
|
-
const framework = GO_FRAMEWORKS.find((f) => modulePath.startsWith(f.module));
|
|
111
|
+
const framework = constants_1.GO_FRAMEWORKS.find((f) => modulePath.startsWith(f.module));
|
|
121
112
|
if (framework) {
|
|
122
113
|
signals.push({
|
|
123
114
|
kind: "framework",
|
|
@@ -41,25 +41,7 @@ exports.parsePomXml = parsePomXml;
|
|
|
41
41
|
exports.parseBuildGradle = parseBuildGradle;
|
|
42
42
|
const fs = __importStar(require("fs"));
|
|
43
43
|
const path = __importStar(require("path"));
|
|
44
|
-
|
|
45
|
-
const JAVA_FRAMEWORKS = [
|
|
46
|
-
{
|
|
47
|
-
groupArtifact: "org.springframework.boot",
|
|
48
|
-
frameworkId: "spring-boot",
|
|
49
|
-
frameworkName: "Spring Boot",
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
groupArtifact: "org.springframework",
|
|
53
|
-
frameworkId: "spring",
|
|
54
|
-
frameworkName: "Spring Framework",
|
|
55
|
-
},
|
|
56
|
-
{ groupArtifact: "io.quarkus", frameworkId: "quarkus", frameworkName: "Quarkus" },
|
|
57
|
-
{ groupArtifact: "io.micronaut", frameworkId: "micronaut", frameworkName: "Micronaut" },
|
|
58
|
-
{ groupArtifact: "org.hibernate", frameworkId: "hibernate", frameworkName: "Hibernate" },
|
|
59
|
-
{ groupArtifact: "junit", frameworkId: "junit", frameworkName: "JUnit" },
|
|
60
|
-
{ groupArtifact: "org.junit", frameworkId: "junit5", frameworkName: "JUnit 5" },
|
|
61
|
-
{ groupArtifact: "org.apache.kafka", frameworkId: "kafka", frameworkName: "Apache Kafka" },
|
|
62
|
-
];
|
|
44
|
+
const constants_1 = require("../../constants");
|
|
63
45
|
/**
|
|
64
46
|
* Parse pom.xml (Maven)
|
|
65
47
|
*/
|
|
@@ -108,7 +90,7 @@ function parsePomXml(manifest) {
|
|
|
108
90
|
if (parentMatch) {
|
|
109
91
|
const parentGroup = parentMatch[1];
|
|
110
92
|
const parentVersion = parentMatch[2];
|
|
111
|
-
const framework = JAVA_FRAMEWORKS.find((f) => parentGroup.includes(f.groupArtifact));
|
|
93
|
+
const framework = constants_1.JAVA_FRAMEWORKS.find((f) => parentGroup.includes(f.groupArtifact));
|
|
112
94
|
if (framework) {
|
|
113
95
|
const resolvedVersion = parentVersion.startsWith("${")
|
|
114
96
|
? properties[parentVersion.slice(2, -1)]
|
|
@@ -141,7 +123,7 @@ function parsePomXml(manifest) {
|
|
|
141
123
|
const groupId = depMatch[1];
|
|
142
124
|
const artifactId = depMatch[2];
|
|
143
125
|
const version = depMatch[3];
|
|
144
|
-
const framework = JAVA_FRAMEWORKS.find((f) => groupId.includes(f.groupArtifact));
|
|
126
|
+
const framework = constants_1.JAVA_FRAMEWORKS.find((f) => groupId.includes(f.groupArtifact));
|
|
145
127
|
if (framework) {
|
|
146
128
|
let versionInfo;
|
|
147
129
|
if (version) {
|
|
@@ -223,7 +205,7 @@ function parseBuildGradle(manifest) {
|
|
|
223
205
|
while ((m = depRegex.exec(content)) !== null) {
|
|
224
206
|
const groupId = m[1];
|
|
225
207
|
const version = m[3];
|
|
226
|
-
const framework = JAVA_FRAMEWORKS.find((f) => groupId.includes(f.groupArtifact));
|
|
208
|
+
const framework = constants_1.JAVA_FRAMEWORKS.find((f) => groupId.includes(f.groupArtifact));
|
|
227
209
|
if (framework) {
|
|
228
210
|
signals.push({
|
|
229
211
|
kind: "framework",
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OpenClaw manifest parser.
|
|
3
|
-
* Parses openclaw.json to extract
|
|
2
|
+
* OpenClaw manifest parser — deep extraction.
|
|
3
|
+
* Parses openclaw.json / .openclaw.json to extract:
|
|
4
|
+
* - Orchestrator signal with version from meta
|
|
5
|
+
* - Agent config (models, workspace, concurrency)
|
|
6
|
+
* - Hooks (internal event scripts with paths + descriptions)
|
|
7
|
+
* - Plugins (enabled extensions)
|
|
8
|
+
* - Gateway config (port, auth, denied commands)
|
|
9
|
+
* - Channels (policies, stream modes)
|
|
10
|
+
* - Tools (web search, fetch)
|
|
11
|
+
* - Commands / messages config
|
|
12
|
+
*
|
|
13
|
+
* Also scans the OpenClaw workspace directory for:
|
|
14
|
+
* - Skills (reusable .md workflows)
|
|
15
|
+
* - Subagents (background agent directories)
|
|
16
|
+
* - Workspace .md files (AGENTS.md, IDENTITY.md, HEARTBEAT.md, etc.)
|
|
17
|
+
* - Hook scripts
|
|
4
18
|
*/
|
|
5
19
|
import { Signal, ManifestFile } from "../types";
|
|
6
20
|
export declare function parseOpenclawJson(manifest: ManifestFile): Signal[];
|