@hongmaple0820/scale-engine 0.7.2 → 0.8.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.
- package/dist/adapters/ClaudeCodeAdapter.js +5 -3
- package/dist/adapters/ClaudeCodeAdapter.js.map +1 -1
- package/dist/adapters/CodexAdapter.js +5 -3
- package/dist/adapters/CodexAdapter.js.map +1 -1
- package/dist/adapters/CursorAdapter.js +5 -3
- package/dist/adapters/CursorAdapter.js.map +1 -1
- package/dist/adapters/GeminiAdapter.js +5 -3
- package/dist/adapters/GeminiAdapter.js.map +1 -1
- package/dist/adapters/HermesAdapter.js +5 -3
- package/dist/adapters/HermesAdapter.js.map +1 -1
- package/dist/adapters/OpenClawAdapter.js +5 -3
- package/dist/adapters/OpenClawAdapter.js.map +1 -1
- package/dist/adapters/OpenCodeAdapter.js +5 -3
- package/dist/adapters/OpenCodeAdapter.js.map +1 -1
- package/dist/adapters/QCoderAdapter.js +5 -3
- package/dist/adapters/QCoderAdapter.js.map +1 -1
- package/dist/adapters/TraeAdapter.js +5 -3
- package/dist/adapters/TraeAdapter.js.map +1 -1
- package/dist/adapters/VSCAdapter.js +5 -3
- package/dist/adapters/VSCAdapter.js.map +1 -1
- package/dist/adapters/WorkBuddyAdapter.js +5 -3
- package/dist/adapters/WorkBuddyAdapter.js.map +1 -1
- package/dist/agents/AgentChannel.d.ts +43 -0
- package/dist/agents/AgentChannel.js +136 -0
- package/dist/agents/AgentChannel.js.map +1 -0
- package/dist/agents/AgentCoordinator.d.ts +29 -0
- package/dist/agents/AgentCoordinator.js +136 -0
- package/dist/agents/AgentCoordinator.js.map +1 -0
- package/dist/agents/AgentDispatcher.d.ts +24 -0
- package/dist/agents/AgentDispatcher.js +112 -0
- package/dist/agents/AgentDispatcher.js.map +1 -0
- package/dist/agents/AgentManager.d.ts +14 -0
- package/dist/agents/AgentManager.js +85 -0
- package/dist/agents/AgentManager.js.map +1 -0
- package/dist/agents/AgentPool.d.ts +59 -0
- package/dist/agents/AgentPool.js +192 -0
- package/dist/agents/AgentPool.js.map +1 -0
- package/dist/agents/AgentRegistry.d.ts +20 -0
- package/dist/agents/AgentRegistry.js +36 -0
- package/dist/agents/AgentRegistry.js.map +1 -0
- package/dist/agents/AgentSourceLoader.d.ts +73 -0
- package/dist/agents/AgentSourceLoader.js +101 -0
- package/dist/agents/AgentSourceLoader.js.map +1 -0
- package/dist/agents/IAgent.d.ts +53 -0
- package/dist/agents/IAgent.js +4 -0
- package/dist/agents/IAgent.js.map +1 -0
- package/dist/agents/definitions/debugger.d.ts +2 -0
- package/dist/agents/definitions/debugger.js +6 -0
- package/dist/agents/definitions/debugger.js.map +1 -0
- package/dist/agents/definitions/doc-writer.d.ts +2 -0
- package/dist/agents/definitions/doc-writer.js +6 -0
- package/dist/agents/definitions/doc-writer.js.map +1 -0
- package/dist/agents/definitions/implementer.d.ts +2 -0
- package/dist/agents/definitions/implementer.js +6 -0
- package/dist/agents/definitions/implementer.js.map +1 -0
- package/dist/agents/definitions/planner.d.ts +2 -0
- package/dist/agents/definitions/planner.js +6 -0
- package/dist/agents/definitions/planner.js.map +1 -0
- package/dist/agents/definitions/researcher.d.ts +2 -0
- package/dist/agents/definitions/researcher.js +6 -0
- package/dist/agents/definitions/researcher.js.map +1 -0
- package/dist/agents/definitions/reviewer.d.ts +2 -0
- package/dist/agents/definitions/reviewer.js +6 -0
- package/dist/agents/definitions/reviewer.js.map +1 -0
- package/dist/agents/definitions/security.d.ts +2 -0
- package/dist/agents/definitions/security.js +6 -0
- package/dist/agents/definitions/security.js.map +1 -0
- package/dist/agents/definitions/tester.d.ts +2 -0
- package/dist/agents/definitions/tester.js +6 -0
- package/dist/agents/definitions/tester.js.map +1 -0
- package/dist/agents/index.d.ts +23 -0
- package/dist/agents/index.js +44 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/profiles.d.ts +26 -0
- package/dist/agents/profiles.js +197 -0
- package/dist/agents/profiles.js.map +1 -0
- package/dist/agents/types.d.ts +262 -0
- package/dist/agents/types.js +4 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/api/cli.js +121 -3
- package/dist/api/cli.js.map +1 -1
- package/dist/api/doctor.js +0 -2
- package/dist/api/doctor.js.map +1 -1
- package/dist/api/mcp.js +0 -5
- package/dist/api/mcp.js.map +1 -1
- package/dist/artifact/fsm.js +3 -5
- package/dist/artifact/fsm.js.map +1 -1
- package/dist/artifact/sqliteStore.js +1 -14
- package/dist/artifact/sqliteStore.js.map +1 -1
- package/dist/artifact/store.js +2 -4
- package/dist/artifact/store.js.map +1 -1
- package/dist/artifact/types.d.ts +94 -1
- package/dist/artifact/types.js +0 -3
- package/dist/artifact/types.js.map +1 -1
- package/dist/context/AntiPatternRegistry.d.ts +38 -0
- package/dist/context/AntiPatternRegistry.js +203 -0
- package/dist/context/AntiPatternRegistry.js.map +1 -0
- package/dist/context/CavemanCompressor.d.ts +20 -0
- package/dist/context/CavemanCompressor.js +14 -0
- package/dist/context/CavemanCompressor.js.map +1 -0
- package/dist/context/ContextBuilder.js +132 -4
- package/dist/context/ContextBuilder.js.map +1 -1
- package/dist/context/SessionStartSequence.d.ts +54 -0
- package/dist/context/SessionStartSequence.js +153 -0
- package/dist/context/SessionStartSequence.js.map +1 -0
- package/dist/core/container.js +4 -2
- package/dist/core/container.js.map +1 -1
- package/dist/core/eventBus.js +5 -6
- package/dist/core/eventBus.js.map +1 -1
- package/dist/dashboard/DashboardServer.js +3 -6
- package/dist/dashboard/DashboardServer.js.map +1 -1
- package/dist/dashboard/index.d.ts +2 -0
- package/dist/dashboard/index.js +2 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/server.d.ts +52 -0
- package/dist/dashboard/server.js +83 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/evolution/AutoDefectCreator.js +2 -4
- package/dist/evolution/AutoDefectCreator.js.map +1 -1
- package/dist/evolution/BehaviorTracker.js +3 -5
- package/dist/evolution/BehaviorTracker.js.map +1 -1
- package/dist/evolution/EvolutionEngine.js +3 -14
- package/dist/evolution/EvolutionEngine.js.map +1 -1
- package/dist/evolution/EvolutionEvaluator.js +1 -4
- package/dist/evolution/EvolutionEvaluator.js.map +1 -1
- package/dist/evolution/LessonValidator.js +0 -4
- package/dist/evolution/LessonValidator.js.map +1 -1
- package/dist/evolution/PatternExtractor.d.ts +40 -0
- package/dist/evolution/PatternExtractor.js +83 -0
- package/dist/evolution/PatternExtractor.js.map +1 -0
- package/dist/evolution/SkillCreator.d.ts +75 -0
- package/dist/evolution/SkillCreator.js +219 -0
- package/dist/evolution/SkillCreator.js.map +1 -0
- package/dist/fsm/FSMAgentBridge.js +11 -13
- package/dist/fsm/FSMAgentBridge.js.map +1 -1
- package/dist/guardrails/DetectorEnhanced.js +32 -30
- package/dist/guardrails/DetectorEnhanced.js.map +1 -1
- package/dist/guardrails/GateEvaluator.d.ts +18 -0
- package/dist/guardrails/GateEvaluator.js +129 -0
- package/dist/guardrails/GateEvaluator.js.map +1 -0
- package/dist/guardrails/Gateway.js +6 -7
- package/dist/guardrails/Gateway.js.map +1 -1
- package/dist/guardrails/ReviewEnforcer.d.ts +52 -0
- package/dist/guardrails/ReviewEnforcer.js +117 -0
- package/dist/guardrails/ReviewEnforcer.js.map +1 -0
- package/dist/guardrails/advancedDetectors.js +33 -31
- package/dist/guardrails/advancedDetectors.js.map +1 -1
- package/dist/guardrails/detectors.js +76 -16
- package/dist/guardrails/detectors.js.map +1 -1
- package/dist/hooks/HookDeployer.js +2 -3
- package/dist/hooks/HookDeployer.js.map +1 -1
- package/dist/hooks/HookGeneratorEnhanced.js +2 -3
- package/dist/hooks/HookGeneratorEnhanced.js.map +1 -1
- package/dist/index.d.ts +20 -2
- package/dist/index.js +19 -2
- package/dist/index.js.map +1 -1
- package/dist/knowledge/KnowledgeBase.d.ts +26 -0
- package/dist/knowledge/KnowledgeBase.js +109 -8
- package/dist/knowledge/KnowledgeBase.js.map +1 -1
- package/dist/knowledge/SQLiteKnowledgeBase.js +1 -3
- package/dist/knowledge/SQLiteKnowledgeBase.js.map +1 -1
- package/dist/knowledge/UbiquitousLanguageManager.d.ts +49 -0
- package/dist/knowledge/UbiquitousLanguageManager.js +133 -0
- package/dist/knowledge/UbiquitousLanguageManager.js.map +1 -0
- package/dist/routing/ModelRouter.js +0 -2
- package/dist/routing/ModelRouter.js.map +1 -1
- package/dist/skills/ExternalSkills.d.ts +3 -0
- package/dist/skills/ExternalSkills.js +20 -0
- package/dist/skills/ExternalSkills.js.map +1 -0
- package/dist/skills/GrillingSessionSkill.d.ts +65 -0
- package/dist/skills/GrillingSessionSkill.js +113 -0
- package/dist/skills/GrillingSessionSkill.js.map +1 -0
- package/dist/skills/GrillingTemplates.d.ts +7 -0
- package/dist/skills/GrillingTemplates.js +38 -0
- package/dist/skills/GrillingTemplates.js.map +1 -0
- package/dist/skills/SkillDiscovery.d.ts +45 -20
- package/dist/skills/SkillDiscovery.js +201 -117
- package/dist/skills/SkillDiscovery.js.map +1 -1
- package/dist/skills/SkillExecutor.js +1 -3
- package/dist/skills/SkillExecutor.js.map +1 -1
- package/dist/skills/SkillInstaller.d.ts +40 -0
- package/dist/skills/SkillInstaller.js +112 -0
- package/dist/skills/SkillInstaller.js.map +1 -0
- package/dist/skills/SkillRegistry.js +1 -2
- package/dist/skills/SkillRegistry.js.map +1 -1
- package/dist/skills/TriggerEngine.js +3 -5
- package/dist/skills/TriggerEngine.js.map +1 -1
- package/dist/skills/index.d.ts +3 -0
- package/dist/skills/index.js +3 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/tasks/IssueTriageFSM.d.ts +26 -0
- package/dist/tasks/IssueTriageFSM.js +107 -0
- package/dist/tasks/IssueTriageFSM.js.map +1 -0
- package/dist/tasks/TaskEngine.js +1 -5
- package/dist/tasks/TaskEngine.js.map +1 -1
- package/dist/workflows/DAGBuilder.d.ts +52 -0
- package/dist/workflows/DAGBuilder.js +169 -0
- package/dist/workflows/DAGBuilder.js.map +1 -0
- package/dist/workflows/WorkflowExecutor.js +2 -4
- package/dist/workflows/WorkflowExecutor.js.map +1 -1
- package/dist/workflows/WorkflowOrchestrator.d.ts +48 -0
- package/dist/workflows/WorkflowOrchestrator.js +181 -0
- package/dist/workflows/WorkflowOrchestrator.js.map +1 -0
- package/dist/workflows/index.d.ts +2 -4
- package/dist/workflows/index.js +4 -4
- package/dist/workflows/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// SCALE Engine - Grilling Session Skill (mattpocock/skills style)
|
|
2
|
+
// 递归决策树探索,一次一个问题
|
|
3
|
+
import { getGrillingTemplate } from "./GrillingTemplates.js";
|
|
4
|
+
import { logger } from "../core/logger.js";
|
|
5
|
+
export class GrillingSessionManager {
|
|
6
|
+
constructor(eventBus) {
|
|
7
|
+
this.sessions = new Map();
|
|
8
|
+
this.eventBus = eventBus ?? null;
|
|
9
|
+
this.templates = getGrillingTemplate;
|
|
10
|
+
}
|
|
11
|
+
startSession(topic) {
|
|
12
|
+
const template = this.templates[topic] ?? getGrillingTemplate(topic);
|
|
13
|
+
const id = "GRILL-" + Date.now() + "-" + Math.random().toString(36).slice(2, 6);
|
|
14
|
+
const session = { id, topic, currentNodeId: template[0]?.id ?? "Q1", history: [], concluded: false };
|
|
15
|
+
this.sessions.set(id, session);
|
|
16
|
+
logger.info({ sessionId: id, topic }, "Grilling session started");
|
|
17
|
+
this.eventBus?.emit("grilling.session_started", { sessionId: id, topic });
|
|
18
|
+
return session;
|
|
19
|
+
}
|
|
20
|
+
handleAnswer(sessionId, selectedOption) {
|
|
21
|
+
const session = this.sessions.get(sessionId);
|
|
22
|
+
if (!session || session.concluded)
|
|
23
|
+
return { type: "conclusion", conclusion: session?.conclusion };
|
|
24
|
+
session.history.push({ questionId: session.currentNodeId, selectedOption, timestamp: Date.now() });
|
|
25
|
+
const currentQuestion = this.getCurrentQuestion(session);
|
|
26
|
+
if (!currentQuestion)
|
|
27
|
+
return this.concludeSession(session);
|
|
28
|
+
const nextNodeId = currentQuestion.branchMap[selectedOption];
|
|
29
|
+
if (nextNodeId === "CONCLUSION" || !nextNodeId)
|
|
30
|
+
return this.concludeSession(session);
|
|
31
|
+
session.currentNodeId = nextNodeId;
|
|
32
|
+
const nextQuestion = this.getCurrentQuestion(session);
|
|
33
|
+
return { type: "question", question: nextQuestion };
|
|
34
|
+
}
|
|
35
|
+
getSession(sessionId) { return this.sessions.get(sessionId); }
|
|
36
|
+
endSession(sessionId) {
|
|
37
|
+
const session = this.sessions.get(sessionId);
|
|
38
|
+
if (!session)
|
|
39
|
+
return undefined;
|
|
40
|
+
if (!session.concluded)
|
|
41
|
+
this.concludeSession(session);
|
|
42
|
+
this.sessions.delete(sessionId);
|
|
43
|
+
this.eventBus?.emit("grilling.session_ended", { sessionId });
|
|
44
|
+
return session.conclusion;
|
|
45
|
+
}
|
|
46
|
+
getCurrentQuestion(session) {
|
|
47
|
+
const template = this.templates[session.topic];
|
|
48
|
+
return template?.find(q => q.id === session.currentNodeId);
|
|
49
|
+
}
|
|
50
|
+
concludeSession(session) {
|
|
51
|
+
session.concluded = true;
|
|
52
|
+
const decisions = this.extractDecisions(session.history);
|
|
53
|
+
const risks = this.extractRisks(session.history);
|
|
54
|
+
session.conclusion = {
|
|
55
|
+
summary: this.generateSummary(decisions),
|
|
56
|
+
decisions,
|
|
57
|
+
risks,
|
|
58
|
+
nextSteps: this.generateNextSteps(decisions),
|
|
59
|
+
artifactsToUpdate: this.suggestArtifactUpdates(decisions),
|
|
60
|
+
};
|
|
61
|
+
logger.info({ sessionId: session.id, decisions: decisions.length }, "Grilling concluded");
|
|
62
|
+
this.eventBus?.emit("grilling.concluded", { sessionId: session.id, conclusion: session.conclusion });
|
|
63
|
+
return { type: "conclusion", conclusion: session.conclusion };
|
|
64
|
+
}
|
|
65
|
+
extractDecisions(history) {
|
|
66
|
+
return history.map(h => h.selectedOption);
|
|
67
|
+
}
|
|
68
|
+
extractRisks(history) {
|
|
69
|
+
const risks = [];
|
|
70
|
+
for (const h of history) {
|
|
71
|
+
const question = this.findQuestion(h.questionId);
|
|
72
|
+
const option = question?.options.find(o => o.id === h.selectedOption);
|
|
73
|
+
if (option?.risk)
|
|
74
|
+
risks.push(option.risk);
|
|
75
|
+
}
|
|
76
|
+
return risks;
|
|
77
|
+
}
|
|
78
|
+
findQuestion(id) {
|
|
79
|
+
for (const template of Object.values(this.templates)) {
|
|
80
|
+
const q = template.find(t => t.id === id);
|
|
81
|
+
if (q)
|
|
82
|
+
return q;
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
generateSummary(decisions) {
|
|
87
|
+
return "Decisions made: " + decisions.join(" -> ");
|
|
88
|
+
}
|
|
89
|
+
generateNextSteps(decisions) {
|
|
90
|
+
const steps = [];
|
|
91
|
+
if (decisions.includes("internal"))
|
|
92
|
+
steps.push("Review internal user workflow");
|
|
93
|
+
if (decisions.includes("external"))
|
|
94
|
+
steps.push("Design public UX");
|
|
95
|
+
if (decisions.includes("deep"))
|
|
96
|
+
steps.push("Define interface contract");
|
|
97
|
+
if (decisions.includes("shallow"))
|
|
98
|
+
steps.push("Plan module composition");
|
|
99
|
+
return steps;
|
|
100
|
+
}
|
|
101
|
+
suggestArtifactUpdates(decisions) {
|
|
102
|
+
const artifacts = [];
|
|
103
|
+
if (decisions.length > 3)
|
|
104
|
+
artifacts.push("CONTEXT.md");
|
|
105
|
+
if (decisions.includes("enterprise") || decisions.includes("k8s"))
|
|
106
|
+
artifacts.push("ADR");
|
|
107
|
+
return artifacts;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function createGrillingSessionManager(eventBus) {
|
|
111
|
+
return new GrillingSessionManager(eventBus);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=GrillingSessionSkill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrillingSessionSkill.js","sourceRoot":"","sources":["../../src/skills/GrillingSessionSkill.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { GrillingQuestion } from "./GrillingSessionSkill.js";
|
|
2
|
+
export declare const REQUIREMENT_CLARITY_TREE: GrillingQuestion[];
|
|
3
|
+
export declare const DESIGN_DEPTH_TREE: GrillingQuestion[];
|
|
4
|
+
export declare const TECH_SELECTION_TREE: GrillingQuestion[];
|
|
5
|
+
export type GrillingTopic = "requirement-clarity" | "design-depth" | "tech-selection";
|
|
6
|
+
export declare const GRILLING_TEMPLATES: Record<GrillingTopic, GrillingQuestion[]>;
|
|
7
|
+
export declare function getGrillingTemplate(topic: GrillingTopic): GrillingQuestion[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// SCALE Engine - Grilling Templates (mattpocock/skills style)
|
|
2
|
+
// 预定义决策树模板
|
|
3
|
+
// ========== Requirement Clarity 决策树 ==========
|
|
4
|
+
export const REQUIREMENT_CLARITY_TREE = [
|
|
5
|
+
{ id: "Q1", question: "Target users?", options: [{ id: "internal", label: "Internal users", explanation: "Team/company internal" }, { id: "external", label: "External users", explanation: "Public users" }, { id: "both", label: "Mixed", explanation: "Both types" }], branchMap: { internal: "Q2", external: "Q3", both: "Q4" } },
|
|
6
|
+
{ id: "Q2", question: "Internal complexity level?", options: [{ id: "simple", label: "Simple", explanation: "Basic workflow" }, { id: "moderate", label: "Moderate", explanation: "Multiple steps" }, { id: "complex", label: "Complex", explanation: "Enterprise-grade" }], branchMap: { simple: "CONCLUSION", moderate: "CONCLUSION", complex: "Q5" } },
|
|
7
|
+
{ id: "Q3", question: "External user scale?", options: [{ id: "small", label: "Small (<100)", explanation: "Limited user base" }, { id: "medium", label: "Medium (100-10k)", explanation: "Growing user base" }, { id: "large", label: "Large (>10k)", explanation: "High scale, need optimization" }], branchMap: { small: "CONCLUSION", medium: "Q6", large: "Q7" } },
|
|
8
|
+
{ id: "Q4", question: "Primary user focus?", options: [{ id: "internal", label: "Internal priority", explanation: "Internal needs first" }, { id: "external", label: "External priority", explanation: "Public users first" }, { id: "balanced", label: "Balanced", explanation: "Equal consideration" }], branchMap: { internal: "Q2", external: "Q3", balanced: "Q8" } },
|
|
9
|
+
{ id: "Q5", question: "Security requirements?", options: [{ id: "basic", label: "Basic auth", explanation: "Simple authentication" }, { id: "advanced", label: "Role-based", explanation: "RBAC permissions" }, { id: "enterprise", label: "Enterprise SSO", explanation: "SSO integration required" }], branchMap: { basic: "CONCLUSION", advanced: "CONCLUSION", enterprise: "CONCLUSION" } },
|
|
10
|
+
{ id: "Q6", question: "User registration needed?", options: [{ id: "optional", label: "Optional", explanation: "Guest access available" }, { id: "required", label: "Required", explanation: "Must register to use" }, { id: "social", label: "Social login", explanation: "OAuth/Social auth" }], branchMap: { optional: "CONCLUSION", required: "CONCLUSION", social: "CONCLUSION" } },
|
|
11
|
+
{ id: "Q7", question: "Performance critical?", options: [{ id: "yes", label: "Yes - high traffic", explanation: "Need high performance" }, { id: "no", label: "No - normal traffic", explanation: "Standard performance OK" }], branchMap: { yes: "CONCLUSION", no: "CONCLUSION" } },
|
|
12
|
+
{ id: "Q8", question: "UX consistency priority?", options: [{ id: "high", label: "High - unified UX", explanation: "Consistent across all" }, { id: "medium", label: "Medium", explanation: "Some variation OK" }, { id: "low", label: "Low - separate UX", explanation: "Different UX per segment" }], branchMap: { high: "CONCLUSION", medium: "CONCLUSION", low: "CONCLUSION" } },
|
|
13
|
+
];
|
|
14
|
+
// ========== Design Depth 决策树 ==========
|
|
15
|
+
export const DESIGN_DEPTH_TREE = [
|
|
16
|
+
{ id: "Q1", question: "Interface depth preference?", options: [{ id: "shallow", label: "Shallow (single responsibility)", explanation: "Simple interfaces, compose multiple calls" }, { id: "deep", label: "Deep (rich functionality)", explanation: "Rich interfaces, one call does more" }], branchMap: { shallow: "Q2", deep: "Q3" }, contextHint: "Deep Modules: interface depth = caller leverage + maintainer locality" },
|
|
17
|
+
{ id: "Q2", question: "Composition approach?", options: [{ id: "chain", label: "Chain pattern", explanation: "Sequential composition" }, { id: "pipeline", label: "Pipeline", explanation: "Data flow pipeline" }, { id: "orchestrator", label: "Orchestrator", explanation: "Central coordinator" }], branchMap: { chain: "CONCLUSION", pipeline: "CONCLUSION", orchestrator: "CONCLUSION" } },
|
|
18
|
+
{ id: "Q3", question: "Parameter count tolerance?", options: [{ id: "low", label: "Low (<=3 params)", explanation: "Minimal parameters" }, { id: "medium", label: "Medium (3-7)", explanation: "Moderate parameters" }, { id: "high", label: "High (>=7)", explanation: "Many parameters acceptable" }], branchMap: { low: "Q4", medium: "CONCLUSION", high: "Q5" } },
|
|
19
|
+
{ id: "Q4", question: "Object pattern acceptable?", options: [{ id: "yes", label: "Yes - options object", explanation: "Use options object pattern" }, { id: "no", label: "No - explicit params", explanation: "Prefer explicit parameters" }], branchMap: { yes: "CONCLUSION", no: "CONCLUSION" } },
|
|
20
|
+
{ id: "Q5", question: "Builder pattern needed?", options: [{ id: "yes", label: "Yes - fluent API", explanation: "Builder pattern for complex construction" }, { id: "no", label: "No - direct call", explanation: "Direct constructor call" }], branchMap: { yes: "CONCLUSION", no: "CONCLUSION" } },
|
|
21
|
+
];
|
|
22
|
+
// ========== Tech Selection 决策树 ==========
|
|
23
|
+
export const TECH_SELECTION_TREE = [
|
|
24
|
+
{ id: "Q1", question: "Technology domain?", options: [{ id: "frontend", label: "Frontend", explanation: "UI/UX, client-side" }, { id: "backend", label: "Backend", explanation: "Server-side, APIs" }, { id: "testing", label: "Testing", explanation: "Test frameworks" }, { id: "infra", label: "Infrastructure", explanation: "Deployment, DevOps" }], branchMap: { frontend: "Q2", backend: "Q3", testing: "Q4", infra: "Q5" } },
|
|
25
|
+
{ id: "Q2", question: "Framework preference?", options: [{ id: "react", label: "React", explanation: "Component-based, Facebook" }, { id: "vue", label: "Vue", explanation: "Progressive, easy learning" }, { id: "svelte", label: "Svelte", explanation: "Compile-time, no runtime" }, { id: "vanilla", label: "Vanilla JS", explanation: "No framework, pure JS" }], branchMap: { react: "CONCLUSION", vue: "CONCLUSION", svelte: "CONCLUSION", vanilla: "CONCLUSION" } },
|
|
26
|
+
{ id: "Q3", question: "Runtime preference?", options: [{ id: "nodejs", label: "Node.js", explanation: "Established, large ecosystem" }, { id: "deno", label: "Deno", explanation: "Modern, TypeScript-first" }, { id: "bun", label: "Bun", explanation: "Fast, native bundler" }], branchMap: { nodejs: "CONCLUSION", deno: "CONCLUSION", bun: "CONCLUSION" } },
|
|
27
|
+
{ id: "Q4", question: "Test framework?", options: [{ id: "vitest", label: "Vitest", explanation: "Fast, Vite-native" }, { id: "jest", label: "Jest", explanation: "Established, feature-rich" }, { id: "playwright", label: "Playwright", explanation: "E2E, cross-browser" }], branchMap: { vitest: "CONCLUSION", jest: "CONCLUSION", playwright: "CONCLUSION" } },
|
|
28
|
+
{ id: "Q5", question: "Deployment target?", options: [{ id: "vercel", label: "Vercel", explanation: "Edge, serverless" }, { id: "docker", label: "Docker", explanation: "Containerized" }, { id: "k8s", label: "Kubernetes", explanation: "Orchestrated containers" }, { id: "bare", label: "Bare metal", explanation: "Direct server deploy" }], branchMap: { vercel: "CONCLUSION", docker: "CONCLUSION", k8s: "CONCLUSION", bare: "CONCLUSION" } },
|
|
29
|
+
];
|
|
30
|
+
export const GRILLING_TEMPLATES = {
|
|
31
|
+
"requirement-clarity": REQUIREMENT_CLARITY_TREE,
|
|
32
|
+
"design-depth": DESIGN_DEPTH_TREE,
|
|
33
|
+
"tech-selection": TECH_SELECTION_TREE,
|
|
34
|
+
};
|
|
35
|
+
export function getGrillingTemplate(topic) {
|
|
36
|
+
return GRILLING_TEMPLATES[topic] ?? REQUIREMENT_CLARITY_TREE;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=GrillingTemplates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrillingTemplates.js","sourceRoot":"","sources":["../../src/skills/GrillingTemplates.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,28 +1,53 @@
|
|
|
1
|
+
import type { IEventBus } from '../core/eventBus.js';
|
|
2
|
+
import type { SkillRegistry } from './SkillRegistry.js';
|
|
3
|
+
import type { SkillInstallConfig, ISkillInstaller } from './SkillInstaller.js';
|
|
1
4
|
import type { AgentPlatform, SkillRef, SkillScanResult } from '../artifact/types.js';
|
|
2
|
-
|
|
5
|
+
/** 发现上下文 - Agent 执行任务时的场景 */
|
|
6
|
+
export interface DiscoveryContext {
|
|
7
|
+
taskType: string;
|
|
8
|
+
missingCapabilities: string[];
|
|
9
|
+
phase: 'explore' | 'plan' | 'execute' | 'verify' | 'deliver';
|
|
10
|
+
keywords: string[];
|
|
11
|
+
}
|
|
12
|
+
/** 发现结果 */
|
|
13
|
+
export interface DiscoveryResult {
|
|
14
|
+
skillId: string;
|
|
15
|
+
sourceUrl: string;
|
|
16
|
+
quality: number;
|
|
17
|
+
relevance: number;
|
|
18
|
+
description: string;
|
|
19
|
+
alreadyInstalled: boolean;
|
|
20
|
+
installConfig?: SkillInstallConfig;
|
|
21
|
+
}
|
|
22
|
+
/** Agent 主动技能发现接口 */
|
|
23
|
+
export interface ISkillDiscovery {
|
|
24
|
+
discover(context: DiscoveryContext): Promise<DiscoveryResult[]>;
|
|
25
|
+
recommendInstall(context: DiscoveryContext): Promise<SkillInstallConfig[]>;
|
|
26
|
+
periodicScan(): Promise<DiscoveryResult[]>;
|
|
27
|
+
checkDuringExecution(taskType: string, capabilities: string[]): Promise<DiscoveryResult[]>;
|
|
28
|
+
scanSkills(platform: AgentPlatform): SkillScanResult;
|
|
29
|
+
detectPlatform(): AgentPlatform | null;
|
|
30
|
+
}
|
|
31
|
+
export declare class SkillDiscovery implements ISkillDiscovery {
|
|
32
|
+
private registry;
|
|
33
|
+
private installer;
|
|
34
|
+
private eventBus;
|
|
3
35
|
private projectDir;
|
|
4
|
-
constructor(projectDir?: string);
|
|
5
36
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
37
|
+
* 构造函数支持两种模式:
|
|
38
|
+
* 1. 独立模式(仅 projectDir):用于平台检测和技能扫描
|
|
39
|
+
* 2. 增强模式(完整参数):用于 Agent 主动发现和推荐安装
|
|
8
40
|
*/
|
|
41
|
+
constructor(registryOrProjectDir: SkillRegistry | string, installer?: ISkillInstaller, eventBus?: IEventBus, projectDir?: string);
|
|
42
|
+
discover(context: DiscoveryContext): Promise<DiscoveryResult[]>;
|
|
43
|
+
recommendInstall(context: DiscoveryContext): Promise<SkillInstallConfig[]>;
|
|
44
|
+
periodicScan(): Promise<DiscoveryResult[]>;
|
|
45
|
+
checkDuringExecution(taskType: string, capabilities: string[]): Promise<DiscoveryResult[]>;
|
|
9
46
|
detectPlatform(): AgentPlatform | null;
|
|
10
|
-
/**
|
|
11
|
-
* Scan the skills directory for a given platform.
|
|
12
|
-
* Returns structured skill references.
|
|
13
|
-
*/
|
|
14
47
|
scanSkills(platform: AgentPlatform): SkillScanResult;
|
|
15
|
-
/**
|
|
16
|
-
* Generate a skills.md document from discovered skills.
|
|
17
|
-
* Useful for injecting into agent knowledge docs.
|
|
18
|
-
*/
|
|
19
48
|
generateSkillsMd(skills: SkillRef[]): string;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
platform: AgentPlatform | null;
|
|
25
|
-
skills: SkillRef[];
|
|
26
|
-
skillsMd: string;
|
|
27
|
-
};
|
|
49
|
+
private matchCategory;
|
|
50
|
+
private calculateRelevance;
|
|
51
|
+
private detectMissingCapabilities;
|
|
52
|
+
private createInstallConfig;
|
|
28
53
|
}
|
|
@@ -1,37 +1,146 @@
|
|
|
1
|
-
// SCALE Engine
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
import { existsSync, readdirSync,
|
|
1
|
+
// SCALE Engine - Agent Proactive Skill Discovery + Platform Scanner
|
|
2
|
+
// 让 Agent 在执行任务时主动发现缺失能力,推荐安装优秀技能
|
|
3
|
+
// 同时支持扫描平台已有技能目录
|
|
4
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { homedir } from 'node:os';
|
|
7
7
|
// ============================================================================
|
|
8
|
+
// 技能来源知识库 - Agent 知道去哪里找优秀技能
|
|
9
|
+
// ============================================================================
|
|
10
|
+
const KNOWN_SKILL_SOURCES = {
|
|
11
|
+
browserAutomation: [
|
|
12
|
+
{ id: 'web-access', source: 'https://github.com/anthropics/claude-code/tree/main/skills/web-access', quality: 95, description: 'CDP browser automation' },
|
|
13
|
+
{ id: 'playwright', source: 'https://github.com/microsoft/playwright', quality: 92, description: 'CLI browser automation' },
|
|
14
|
+
{ id: 'cua', source: 'https://github.com/trycua/cua', quality: 90, description: 'Computer use agent' },
|
|
15
|
+
],
|
|
16
|
+
uiDesign: [
|
|
17
|
+
{ id: 'awesome-design-md', source: 'https://github.com/anthropics/anthropic-cookbook/tree/main/skills/awesome-design-md', quality: 88, description: 'Brand design specs' },
|
|
18
|
+
{ id: 'ui-ux-pro-max', source: 'https://github.com/anthropics/claude-code/tree/main/skills/ui-ux-pro-max', quality: 85, description: 'UX guidelines database' },
|
|
19
|
+
],
|
|
20
|
+
diagrams: [
|
|
21
|
+
{ id: 'fireworks-tech-graph', source: 'https://github.com/yizhiyanhua-ai/fireworks-tech-graph', quality: 82, description: 'Tech flow diagrams' },
|
|
22
|
+
{ id: 'architecture-diagram-generator', source: 'https://github.com/Cocoon-AI/architecture-diagram-generator', quality: 85, description: 'System architecture diagrams' },
|
|
23
|
+
],
|
|
24
|
+
videoGeneration: [
|
|
25
|
+
{ id: 'hyperframes', source: 'https://github.com/heygen-com/hyperframes', quality: 75, description: 'HeyGen video generation' },
|
|
26
|
+
],
|
|
27
|
+
pptGeneration: [
|
|
28
|
+
{ id: 'guizang-ppt-skill', source: 'https://github.com/op7418/guizang-ppt-skill', quality: 70, description: 'PPT auto generation' },
|
|
29
|
+
],
|
|
30
|
+
knowledgeGraph: [
|
|
31
|
+
{ id: 'graphify', source: 'https://github.com/anthropics/claude-code/tree/main/skills/graphify', quality: 90, description: 'Knowledge graph generator' },
|
|
32
|
+
],
|
|
33
|
+
testing: [
|
|
34
|
+
{ id: 'playwright-interactive', source: 'https://github.com/anthropics/claude-code/tree/main/skills/playwright-interactive', quality: 80, description: 'Persistent session UI debug' },
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
// ============================================================================
|
|
8
38
|
// Platform Skills Directory Map
|
|
9
39
|
// ============================================================================
|
|
10
40
|
const PLATFORM_SKILLS_DIRS = {
|
|
11
|
-
'claude-code':
|
|
12
|
-
'codex':
|
|
41
|
+
'claude-code': join(homedir(), '.claude', 'skills'),
|
|
42
|
+
'codex': join(homedir(), '.omx', 'skills'),
|
|
13
43
|
'opencode': join(homedir(), '.config', 'opencode', 'skills'),
|
|
14
44
|
'cursor': join('.cursor', 'skills'),
|
|
15
|
-
'gemini': null,
|
|
16
|
-
'openclaw': null,
|
|
17
|
-
'hermes': null,
|
|
18
|
-
'trae': null,
|
|
19
|
-
'workbuddy': null,
|
|
20
|
-
'vsc': null,
|
|
21
|
-
'qcoder': null,
|
|
45
|
+
'gemini': null,
|
|
46
|
+
'openclaw': null,
|
|
47
|
+
'hermes': null,
|
|
48
|
+
'trae': null,
|
|
49
|
+
'workbuddy': null,
|
|
50
|
+
'vsc': null,
|
|
51
|
+
'qcoder': null,
|
|
22
52
|
};
|
|
23
|
-
// ============================================================================
|
|
24
|
-
// SkillDiscovery
|
|
25
|
-
// ============================================================================
|
|
26
53
|
export class SkillDiscovery {
|
|
27
|
-
projectDir;
|
|
28
|
-
constructor(projectDir = '.') {
|
|
29
|
-
this.projectDir = projectDir;
|
|
30
|
-
}
|
|
31
54
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
55
|
+
* 构造函数支持两种模式:
|
|
56
|
+
* 1. 独立模式(仅 projectDir):用于平台检测和技能扫描
|
|
57
|
+
* 2. 增强模式(完整参数):用于 Agent 主动发现和推荐安装
|
|
34
58
|
*/
|
|
59
|
+
constructor(registryOrProjectDir, installer, eventBus, projectDir) {
|
|
60
|
+
// 判断是独立模式还是增强模式
|
|
61
|
+
if (typeof registryOrProjectDir === 'string') {
|
|
62
|
+
// 独立模式
|
|
63
|
+
this.registry = null;
|
|
64
|
+
this.installer = null;
|
|
65
|
+
this.eventBus = null;
|
|
66
|
+
this.projectDir = registryOrProjectDir;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// 增强模式
|
|
70
|
+
this.registry = registryOrProjectDir;
|
|
71
|
+
this.installer = installer ?? null;
|
|
72
|
+
this.eventBus = eventBus ?? null;
|
|
73
|
+
this.projectDir = projectDir ?? '.';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// ========== 主动发现功能 ==========
|
|
77
|
+
async discover(context) {
|
|
78
|
+
// 独立模式下无法执行发现功能
|
|
79
|
+
if (!this.registry) {
|
|
80
|
+
console.warn('SkillDiscovery: registry not initialized, discover disabled');
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
const results = [];
|
|
84
|
+
const category = this.matchCategory(context.taskType, context.keywords);
|
|
85
|
+
if (!category)
|
|
86
|
+
return [];
|
|
87
|
+
const candidates = KNOWN_SKILL_SOURCES[category] || [];
|
|
88
|
+
for (const candidate of candidates) {
|
|
89
|
+
const registered = this.registry.get(candidate.id);
|
|
90
|
+
const relevance = this.calculateRelevance(context, candidate);
|
|
91
|
+
results.push({
|
|
92
|
+
skillId: candidate.id,
|
|
93
|
+
sourceUrl: candidate.source,
|
|
94
|
+
quality: candidate.quality,
|
|
95
|
+
relevance,
|
|
96
|
+
description: candidate.description,
|
|
97
|
+
alreadyInstalled: registered?.installed ?? false,
|
|
98
|
+
installConfig: !registered?.installed ? this.createInstallConfig(candidate) : undefined,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
results.sort((a, b) => (b.quality * b.relevance) - (a.quality * a.relevance));
|
|
102
|
+
if (this.eventBus) {
|
|
103
|
+
this.eventBus.emit('skill.recommended', { context, recommendations: results.filter(r => !r.alreadyInstalled) });
|
|
104
|
+
}
|
|
105
|
+
return results;
|
|
106
|
+
}
|
|
107
|
+
async recommendInstall(context) {
|
|
108
|
+
if (!this.registry)
|
|
109
|
+
return [];
|
|
110
|
+
const discoveries = await this.discover(context);
|
|
111
|
+
return discoveries.filter(r => !r.alreadyInstalled && r.quality >= 80 && r.relevance >= 0.7 && r.installConfig)
|
|
112
|
+
.map(r => r.installConfig);
|
|
113
|
+
}
|
|
114
|
+
async periodicScan() {
|
|
115
|
+
if (!this.registry)
|
|
116
|
+
return [];
|
|
117
|
+
const allResults = [];
|
|
118
|
+
for (const category of Object.keys(KNOWN_SKILL_SOURCES)) {
|
|
119
|
+
for (const candidate of KNOWN_SKILL_SOURCES[category]) {
|
|
120
|
+
if (!this.registry.get(candidate.id)) {
|
|
121
|
+
allResults.push({
|
|
122
|
+
skillId: candidate.id,
|
|
123
|
+
sourceUrl: candidate.source,
|
|
124
|
+
quality: candidate.quality,
|
|
125
|
+
relevance: 1.0,
|
|
126
|
+
description: candidate.description,
|
|
127
|
+
alreadyInstalled: false,
|
|
128
|
+
installConfig: this.createInstallConfig(candidate),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return allResults;
|
|
134
|
+
}
|
|
135
|
+
async checkDuringExecution(taskType, capabilities) {
|
|
136
|
+
if (!this.registry)
|
|
137
|
+
return [];
|
|
138
|
+
const missing = this.detectMissingCapabilities(capabilities);
|
|
139
|
+
if (missing.length === 0)
|
|
140
|
+
return [];
|
|
141
|
+
return this.discover({ taskType, missingCapabilities: missing, phase: 'execute', keywords: missing });
|
|
142
|
+
}
|
|
143
|
+
// ========== 原有平台扫描功能 ==========
|
|
35
144
|
detectPlatform() {
|
|
36
145
|
const checks = [
|
|
37
146
|
{ platform: 'claude-code', paths: [join(this.projectDir, '.claude', 'settings.json')] },
|
|
@@ -47,102 +156,34 @@ export class SkillDiscovery {
|
|
|
47
156
|
{ platform: 'qcoder', paths: [join(this.projectDir, '.qwen', 'settings.json')] },
|
|
48
157
|
];
|
|
49
158
|
for (const check of checks) {
|
|
50
|
-
if (check.paths.some(
|
|
159
|
+
if (check.paths.some(p => existsSync(p)))
|
|
51
160
|
return check.platform;
|
|
52
|
-
}
|
|
53
161
|
}
|
|
54
162
|
return null;
|
|
55
163
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Scan the skills directory for a given platform.
|
|
58
|
-
* Returns structured skill references.
|
|
59
|
-
*/
|
|
60
164
|
scanSkills(platform) {
|
|
61
165
|
const skillsDir = PLATFORM_SKILLS_DIRS[platform];
|
|
62
|
-
if (!skillsDir)
|
|
63
|
-
return {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
exists: false,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
const resolvedDir = platform === 'opencode'
|
|
71
|
-
? skillsDir
|
|
72
|
-
: join(this.projectDir, skillsDir);
|
|
73
|
-
if (!existsSync(resolvedDir)) {
|
|
74
|
-
return {
|
|
75
|
-
platform,
|
|
76
|
-
skillsDir: resolvedDir,
|
|
77
|
-
skills: [],
|
|
78
|
-
exists: false,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
166
|
+
if (!skillsDir)
|
|
167
|
+
return { platform, skillsDir: '', skills: [], exists: false };
|
|
168
|
+
const resolvedDir = platform === 'opencode' ? skillsDir : join(this.projectDir, skillsDir);
|
|
169
|
+
if (!existsSync(resolvedDir))
|
|
170
|
+
return { platform, skillsDir: resolvedDir, skills: [], exists: false };
|
|
81
171
|
const skills = [];
|
|
82
172
|
try {
|
|
83
|
-
const
|
|
84
|
-
for (const entry of entries) {
|
|
173
|
+
for (const entry of readdirSync(resolvedDir)) {
|
|
85
174
|
const entryPath = join(resolvedDir, entry);
|
|
86
175
|
const stat = statSync(entryPath);
|
|
87
|
-
if (stat.
|
|
88
|
-
|
|
89
|
-
let description = '';
|
|
90
|
-
// Try to extract description from file content
|
|
91
|
-
try {
|
|
92
|
-
const content = readFileSync(entryPath, 'utf-8');
|
|
93
|
-
// Extract first line as description for .md files
|
|
94
|
-
if (entry.endsWith('.md')) {
|
|
95
|
-
const firstLine = content.split('\n').find((l) => l.trim().length > 0) ?? '';
|
|
96
|
-
description = firstLine.replace(/^#+\s*/, '').trim();
|
|
97
|
-
}
|
|
98
|
-
else if (entry.endsWith('.json')) {
|
|
99
|
-
const parsed = JSON.parse(content);
|
|
100
|
-
description = parsed.description ?? parsed.name ?? '';
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
description = '';
|
|
105
|
-
}
|
|
106
|
-
skills.push({
|
|
107
|
-
id: `${platform}-${name}`,
|
|
108
|
-
name,
|
|
109
|
-
description,
|
|
110
|
-
platform,
|
|
111
|
-
path: entryPath,
|
|
112
|
-
enabled: true,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
else if (stat.isDirectory()) {
|
|
116
|
-
// Directory-based skills
|
|
117
|
-
skills.push({
|
|
118
|
-
id: `${platform}-${entry}`,
|
|
119
|
-
name: entry,
|
|
120
|
-
description: '',
|
|
121
|
-
platform,
|
|
122
|
-
path: entryPath,
|
|
123
|
-
enabled: true,
|
|
124
|
-
});
|
|
176
|
+
if (stat.isDirectory()) {
|
|
177
|
+
skills.push({ id: `${platform}-${entry}`, name: entry, description: '', platform, path: entryPath, enabled: true });
|
|
125
178
|
}
|
|
126
179
|
}
|
|
127
180
|
}
|
|
128
|
-
catch {
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
return {
|
|
132
|
-
platform,
|
|
133
|
-
skillsDir: resolvedDir,
|
|
134
|
-
skills,
|
|
135
|
-
exists: true,
|
|
136
|
-
};
|
|
181
|
+
catch { /* Permission error */ }
|
|
182
|
+
return { platform, skillsDir: resolvedDir, skills, exists: true };
|
|
137
183
|
}
|
|
138
|
-
/**
|
|
139
|
-
* Generate a skills.md document from discovered skills.
|
|
140
|
-
* Useful for injecting into agent knowledge docs.
|
|
141
|
-
*/
|
|
142
184
|
generateSkillsMd(skills) {
|
|
143
|
-
if (skills.length === 0)
|
|
185
|
+
if (skills.length === 0)
|
|
144
186
|
return '## Available Skills\n\nNo skills discovered.\n';
|
|
145
|
-
}
|
|
146
187
|
const grouped = new Map();
|
|
147
188
|
for (const skill of skills) {
|
|
148
189
|
const group = grouped.get(skill.platform) ?? [];
|
|
@@ -151,29 +192,72 @@ export class SkillDiscovery {
|
|
|
151
192
|
}
|
|
152
193
|
const sections = ['## Available Skills\n'];
|
|
153
194
|
for (const [platform, platformSkills] of grouped) {
|
|
154
|
-
sections.push(`### ${platform}`);
|
|
155
|
-
sections.push('');
|
|
195
|
+
sections.push(`### ${platform}\n`);
|
|
156
196
|
for (const skill of platformSkills) {
|
|
157
197
|
const desc = skill.description ? ` — ${skill.description}` : '';
|
|
158
|
-
|
|
159
|
-
sections.push(`- ${status} **${skill.name}**${desc}`);
|
|
198
|
+
sections.push(`- ✅ **${skill.name}**${desc}`);
|
|
160
199
|
}
|
|
161
200
|
sections.push('');
|
|
162
201
|
}
|
|
163
202
|
return sections.join('\n');
|
|
164
203
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
204
|
+
// ========== Private Methods ==========
|
|
205
|
+
matchCategory(taskType, keywords) {
|
|
206
|
+
const typeToCategory = {
|
|
207
|
+
'web-scraping': 'browserAutomation', 'e2e-testing': 'testing', 'ui-design': 'uiDesign',
|
|
208
|
+
'diagram': 'diagrams', 'video-generation': 'videoGeneration', 'ppt-generation': 'pptGeneration',
|
|
209
|
+
'knowledge-graph': 'knowledgeGraph',
|
|
210
|
+
};
|
|
211
|
+
if (typeToCategory[taskType])
|
|
212
|
+
return typeToCategory[taskType];
|
|
213
|
+
for (const kw of keywords) {
|
|
214
|
+
if (kw.includes('browser'))
|
|
215
|
+
return 'browserAutomation';
|
|
216
|
+
if (kw.includes('design'))
|
|
217
|
+
return 'uiDesign';
|
|
218
|
+
if (kw.includes('diagram'))
|
|
219
|
+
return 'diagrams';
|
|
220
|
+
if (kw.includes('test'))
|
|
221
|
+
return 'testing';
|
|
174
222
|
}
|
|
175
|
-
|
|
176
|
-
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
calculateRelevance(ctx, candidate) {
|
|
226
|
+
const descLower = candidate.description.toLowerCase();
|
|
227
|
+
let matchCount = 0;
|
|
228
|
+
for (const kw of ctx.keywords)
|
|
229
|
+
if (descLower.includes(kw.toLowerCase()))
|
|
230
|
+
matchCount++;
|
|
231
|
+
for (const cap of ctx.missingCapabilities)
|
|
232
|
+
if (descLower.includes(cap.toLowerCase()))
|
|
233
|
+
matchCount++;
|
|
234
|
+
const total = ctx.keywords.length + ctx.missingCapabilities.length;
|
|
235
|
+
return total > 0 ? matchCount / total : 0.5;
|
|
236
|
+
}
|
|
237
|
+
detectMissingCapabilities(capabilities) {
|
|
238
|
+
if (!this.registry)
|
|
239
|
+
return capabilities; // 无 registry 时返回全部
|
|
240
|
+
const missing = [];
|
|
241
|
+
const allSkills = this.registry.listAll();
|
|
242
|
+
for (const cap of capabilities) {
|
|
243
|
+
const hasIt = allSkills.some(s => s.installed && (s.id.includes(cap) || s.description.toLowerCase().includes(cap)));
|
|
244
|
+
if (!hasIt)
|
|
245
|
+
missing.push(cap);
|
|
246
|
+
}
|
|
247
|
+
return missing;
|
|
248
|
+
}
|
|
249
|
+
createInstallConfig(candidate) {
|
|
250
|
+
const method = candidate.source.includes('github') ? 'git-clone' : 'manual';
|
|
251
|
+
const command = method === 'git-clone'
|
|
252
|
+
? `git clone ${candidate.source} ~/.claude/skills/${candidate.id}`
|
|
253
|
+
: `create ~/.claude/skills/${candidate.id}/SKILL.md`;
|
|
254
|
+
return {
|
|
255
|
+
skillId: candidate.id,
|
|
256
|
+
method,
|
|
257
|
+
sourceUrl: candidate.source,
|
|
258
|
+
command,
|
|
259
|
+
verification: `test -f ~/.claude/skills/${candidate.id}/SKILL.md`,
|
|
260
|
+
};
|
|
177
261
|
}
|
|
178
262
|
}
|
|
179
263
|
//# sourceMappingURL=SkillDiscovery.js.map
|