@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.
Files changed (207) hide show
  1. package/dist/adapters/ClaudeCodeAdapter.js +5 -3
  2. package/dist/adapters/ClaudeCodeAdapter.js.map +1 -1
  3. package/dist/adapters/CodexAdapter.js +5 -3
  4. package/dist/adapters/CodexAdapter.js.map +1 -1
  5. package/dist/adapters/CursorAdapter.js +5 -3
  6. package/dist/adapters/CursorAdapter.js.map +1 -1
  7. package/dist/adapters/GeminiAdapter.js +5 -3
  8. package/dist/adapters/GeminiAdapter.js.map +1 -1
  9. package/dist/adapters/HermesAdapter.js +5 -3
  10. package/dist/adapters/HermesAdapter.js.map +1 -1
  11. package/dist/adapters/OpenClawAdapter.js +5 -3
  12. package/dist/adapters/OpenClawAdapter.js.map +1 -1
  13. package/dist/adapters/OpenCodeAdapter.js +5 -3
  14. package/dist/adapters/OpenCodeAdapter.js.map +1 -1
  15. package/dist/adapters/QCoderAdapter.js +5 -3
  16. package/dist/adapters/QCoderAdapter.js.map +1 -1
  17. package/dist/adapters/TraeAdapter.js +5 -3
  18. package/dist/adapters/TraeAdapter.js.map +1 -1
  19. package/dist/adapters/VSCAdapter.js +5 -3
  20. package/dist/adapters/VSCAdapter.js.map +1 -1
  21. package/dist/adapters/WorkBuddyAdapter.js +5 -3
  22. package/dist/adapters/WorkBuddyAdapter.js.map +1 -1
  23. package/dist/agents/AgentChannel.d.ts +43 -0
  24. package/dist/agents/AgentChannel.js +136 -0
  25. package/dist/agents/AgentChannel.js.map +1 -0
  26. package/dist/agents/AgentCoordinator.d.ts +29 -0
  27. package/dist/agents/AgentCoordinator.js +136 -0
  28. package/dist/agents/AgentCoordinator.js.map +1 -0
  29. package/dist/agents/AgentDispatcher.d.ts +24 -0
  30. package/dist/agents/AgentDispatcher.js +112 -0
  31. package/dist/agents/AgentDispatcher.js.map +1 -0
  32. package/dist/agents/AgentManager.d.ts +14 -0
  33. package/dist/agents/AgentManager.js +85 -0
  34. package/dist/agents/AgentManager.js.map +1 -0
  35. package/dist/agents/AgentPool.d.ts +59 -0
  36. package/dist/agents/AgentPool.js +192 -0
  37. package/dist/agents/AgentPool.js.map +1 -0
  38. package/dist/agents/AgentRegistry.d.ts +20 -0
  39. package/dist/agents/AgentRegistry.js +36 -0
  40. package/dist/agents/AgentRegistry.js.map +1 -0
  41. package/dist/agents/AgentSourceLoader.d.ts +73 -0
  42. package/dist/agents/AgentSourceLoader.js +101 -0
  43. package/dist/agents/AgentSourceLoader.js.map +1 -0
  44. package/dist/agents/IAgent.d.ts +53 -0
  45. package/dist/agents/IAgent.js +4 -0
  46. package/dist/agents/IAgent.js.map +1 -0
  47. package/dist/agents/definitions/debugger.d.ts +2 -0
  48. package/dist/agents/definitions/debugger.js +6 -0
  49. package/dist/agents/definitions/debugger.js.map +1 -0
  50. package/dist/agents/definitions/doc-writer.d.ts +2 -0
  51. package/dist/agents/definitions/doc-writer.js +6 -0
  52. package/dist/agents/definitions/doc-writer.js.map +1 -0
  53. package/dist/agents/definitions/implementer.d.ts +2 -0
  54. package/dist/agents/definitions/implementer.js +6 -0
  55. package/dist/agents/definitions/implementer.js.map +1 -0
  56. package/dist/agents/definitions/planner.d.ts +2 -0
  57. package/dist/agents/definitions/planner.js +6 -0
  58. package/dist/agents/definitions/planner.js.map +1 -0
  59. package/dist/agents/definitions/researcher.d.ts +2 -0
  60. package/dist/agents/definitions/researcher.js +6 -0
  61. package/dist/agents/definitions/researcher.js.map +1 -0
  62. package/dist/agents/definitions/reviewer.d.ts +2 -0
  63. package/dist/agents/definitions/reviewer.js +6 -0
  64. package/dist/agents/definitions/reviewer.js.map +1 -0
  65. package/dist/agents/definitions/security.d.ts +2 -0
  66. package/dist/agents/definitions/security.js +6 -0
  67. package/dist/agents/definitions/security.js.map +1 -0
  68. package/dist/agents/definitions/tester.d.ts +2 -0
  69. package/dist/agents/definitions/tester.js +6 -0
  70. package/dist/agents/definitions/tester.js.map +1 -0
  71. package/dist/agents/index.d.ts +23 -0
  72. package/dist/agents/index.js +44 -0
  73. package/dist/agents/index.js.map +1 -0
  74. package/dist/agents/profiles.d.ts +26 -0
  75. package/dist/agents/profiles.js +197 -0
  76. package/dist/agents/profiles.js.map +1 -0
  77. package/dist/agents/types.d.ts +262 -0
  78. package/dist/agents/types.js +4 -0
  79. package/dist/agents/types.js.map +1 -0
  80. package/dist/api/cli.js +121 -3
  81. package/dist/api/cli.js.map +1 -1
  82. package/dist/api/doctor.js +0 -2
  83. package/dist/api/doctor.js.map +1 -1
  84. package/dist/api/mcp.js +0 -5
  85. package/dist/api/mcp.js.map +1 -1
  86. package/dist/artifact/fsm.js +3 -5
  87. package/dist/artifact/fsm.js.map +1 -1
  88. package/dist/artifact/sqliteStore.js +1 -14
  89. package/dist/artifact/sqliteStore.js.map +1 -1
  90. package/dist/artifact/store.js +2 -4
  91. package/dist/artifact/store.js.map +1 -1
  92. package/dist/artifact/types.d.ts +94 -1
  93. package/dist/artifact/types.js +0 -3
  94. package/dist/artifact/types.js.map +1 -1
  95. package/dist/context/AntiPatternRegistry.d.ts +38 -0
  96. package/dist/context/AntiPatternRegistry.js +203 -0
  97. package/dist/context/AntiPatternRegistry.js.map +1 -0
  98. package/dist/context/CavemanCompressor.d.ts +20 -0
  99. package/dist/context/CavemanCompressor.js +14 -0
  100. package/dist/context/CavemanCompressor.js.map +1 -0
  101. package/dist/context/ContextBuilder.js +132 -4
  102. package/dist/context/ContextBuilder.js.map +1 -1
  103. package/dist/context/SessionStartSequence.d.ts +54 -0
  104. package/dist/context/SessionStartSequence.js +153 -0
  105. package/dist/context/SessionStartSequence.js.map +1 -0
  106. package/dist/core/container.js +4 -2
  107. package/dist/core/container.js.map +1 -1
  108. package/dist/core/eventBus.js +5 -6
  109. package/dist/core/eventBus.js.map +1 -1
  110. package/dist/dashboard/DashboardServer.js +3 -6
  111. package/dist/dashboard/DashboardServer.js.map +1 -1
  112. package/dist/dashboard/index.d.ts +2 -0
  113. package/dist/dashboard/index.js +2 -0
  114. package/dist/dashboard/index.js.map +1 -0
  115. package/dist/dashboard/server.d.ts +52 -0
  116. package/dist/dashboard/server.js +83 -0
  117. package/dist/dashboard/server.js.map +1 -0
  118. package/dist/evolution/AutoDefectCreator.js +2 -4
  119. package/dist/evolution/AutoDefectCreator.js.map +1 -1
  120. package/dist/evolution/BehaviorTracker.js +3 -5
  121. package/dist/evolution/BehaviorTracker.js.map +1 -1
  122. package/dist/evolution/EvolutionEngine.js +3 -14
  123. package/dist/evolution/EvolutionEngine.js.map +1 -1
  124. package/dist/evolution/EvolutionEvaluator.js +1 -4
  125. package/dist/evolution/EvolutionEvaluator.js.map +1 -1
  126. package/dist/evolution/LessonValidator.js +0 -4
  127. package/dist/evolution/LessonValidator.js.map +1 -1
  128. package/dist/evolution/PatternExtractor.d.ts +40 -0
  129. package/dist/evolution/PatternExtractor.js +83 -0
  130. package/dist/evolution/PatternExtractor.js.map +1 -0
  131. package/dist/evolution/SkillCreator.d.ts +75 -0
  132. package/dist/evolution/SkillCreator.js +219 -0
  133. package/dist/evolution/SkillCreator.js.map +1 -0
  134. package/dist/fsm/FSMAgentBridge.js +11 -13
  135. package/dist/fsm/FSMAgentBridge.js.map +1 -1
  136. package/dist/guardrails/DetectorEnhanced.js +32 -30
  137. package/dist/guardrails/DetectorEnhanced.js.map +1 -1
  138. package/dist/guardrails/GateEvaluator.d.ts +18 -0
  139. package/dist/guardrails/GateEvaluator.js +129 -0
  140. package/dist/guardrails/GateEvaluator.js.map +1 -0
  141. package/dist/guardrails/Gateway.js +6 -7
  142. package/dist/guardrails/Gateway.js.map +1 -1
  143. package/dist/guardrails/ReviewEnforcer.d.ts +52 -0
  144. package/dist/guardrails/ReviewEnforcer.js +117 -0
  145. package/dist/guardrails/ReviewEnforcer.js.map +1 -0
  146. package/dist/guardrails/advancedDetectors.js +33 -31
  147. package/dist/guardrails/advancedDetectors.js.map +1 -1
  148. package/dist/guardrails/detectors.js +76 -16
  149. package/dist/guardrails/detectors.js.map +1 -1
  150. package/dist/hooks/HookDeployer.js +2 -3
  151. package/dist/hooks/HookDeployer.js.map +1 -1
  152. package/dist/hooks/HookGeneratorEnhanced.js +2 -3
  153. package/dist/hooks/HookGeneratorEnhanced.js.map +1 -1
  154. package/dist/index.d.ts +20 -2
  155. package/dist/index.js +19 -2
  156. package/dist/index.js.map +1 -1
  157. package/dist/knowledge/KnowledgeBase.d.ts +26 -0
  158. package/dist/knowledge/KnowledgeBase.js +109 -8
  159. package/dist/knowledge/KnowledgeBase.js.map +1 -1
  160. package/dist/knowledge/SQLiteKnowledgeBase.js +1 -3
  161. package/dist/knowledge/SQLiteKnowledgeBase.js.map +1 -1
  162. package/dist/knowledge/UbiquitousLanguageManager.d.ts +49 -0
  163. package/dist/knowledge/UbiquitousLanguageManager.js +133 -0
  164. package/dist/knowledge/UbiquitousLanguageManager.js.map +1 -0
  165. package/dist/routing/ModelRouter.js +0 -2
  166. package/dist/routing/ModelRouter.js.map +1 -1
  167. package/dist/skills/ExternalSkills.d.ts +3 -0
  168. package/dist/skills/ExternalSkills.js +20 -0
  169. package/dist/skills/ExternalSkills.js.map +1 -0
  170. package/dist/skills/GrillingSessionSkill.d.ts +65 -0
  171. package/dist/skills/GrillingSessionSkill.js +113 -0
  172. package/dist/skills/GrillingSessionSkill.js.map +1 -0
  173. package/dist/skills/GrillingTemplates.d.ts +7 -0
  174. package/dist/skills/GrillingTemplates.js +38 -0
  175. package/dist/skills/GrillingTemplates.js.map +1 -0
  176. package/dist/skills/SkillDiscovery.d.ts +45 -20
  177. package/dist/skills/SkillDiscovery.js +201 -117
  178. package/dist/skills/SkillDiscovery.js.map +1 -1
  179. package/dist/skills/SkillExecutor.js +1 -3
  180. package/dist/skills/SkillExecutor.js.map +1 -1
  181. package/dist/skills/SkillInstaller.d.ts +40 -0
  182. package/dist/skills/SkillInstaller.js +112 -0
  183. package/dist/skills/SkillInstaller.js.map +1 -0
  184. package/dist/skills/SkillRegistry.js +1 -2
  185. package/dist/skills/SkillRegistry.js.map +1 -1
  186. package/dist/skills/TriggerEngine.js +3 -5
  187. package/dist/skills/TriggerEngine.js.map +1 -1
  188. package/dist/skills/index.d.ts +3 -0
  189. package/dist/skills/index.js +3 -0
  190. package/dist/skills/index.js.map +1 -1
  191. package/dist/tasks/IssueTriageFSM.d.ts +26 -0
  192. package/dist/tasks/IssueTriageFSM.js +107 -0
  193. package/dist/tasks/IssueTriageFSM.js.map +1 -0
  194. package/dist/tasks/TaskEngine.js +1 -5
  195. package/dist/tasks/TaskEngine.js.map +1 -1
  196. package/dist/workflows/DAGBuilder.d.ts +52 -0
  197. package/dist/workflows/DAGBuilder.js +169 -0
  198. package/dist/workflows/DAGBuilder.js.map +1 -0
  199. package/dist/workflows/WorkflowExecutor.js +2 -4
  200. package/dist/workflows/WorkflowExecutor.js.map +1 -1
  201. package/dist/workflows/WorkflowOrchestrator.d.ts +48 -0
  202. package/dist/workflows/WorkflowOrchestrator.js +181 -0
  203. package/dist/workflows/WorkflowOrchestrator.js.map +1 -0
  204. package/dist/workflows/index.d.ts +2 -4
  205. package/dist/workflows/index.js +4 -4
  206. package/dist/workflows/index.js.map +1 -1
  207. 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
- export declare class SkillDiscovery {
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
- * Detect the active agent platform based on config files present in the project.
7
- * Returns the most likely platform, or null if indeterminate.
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
- * Full discovery pipeline: detect platform → scan → generate doc.
22
- */
23
- discover(): {
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 Skill Discovery
2
- // 检测平台 扫描技能目录 → 生成 skills.md
3
- // 设计参考:SCALE v10.0 技能生态系统
4
- import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
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': null, // Claude Code uses .claude/commands/, no dedicated skills dir
12
- 'codex': null, // Codex uses .codex/commands/
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, // Gemini has no skills directory concept
16
- 'openclaw': null, // OpenClaw has no skills directory concept
17
- 'hermes': null, // Hermes has no skills directory concept
18
- 'trae': null, // Trae has no skills directory concept
19
- 'workbuddy': null, // WorkBuddy has no skills directory concept
20
- 'vsc': null, // VSC has no skills directory concept
21
- 'qcoder': null, // QCoder has no skills directory concept
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
- * Detect the active agent platform based on config files present in the project.
33
- * Returns the most likely platform, or null if indeterminate.
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((p) => existsSync(p))) {
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
- platform,
65
- skillsDir: '',
66
- skills: [],
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 entries = readdirSync(resolvedDir);
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.isFile() && (entry.endsWith('.md') || entry.endsWith('.json') || entry.endsWith('.yaml') || entry.endsWith('.yml'))) {
88
- const name = entry.replace(/\.(md|json|ya?ml)$/, '');
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
- // Permission or read error
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
- const status = skill.enabled ? '✅' : '❌';
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
- * Full discovery pipeline: detect platform → scan → generate doc.
167
- */
168
- discover() {
169
- const platform = this.detectPlatform();
170
- let skills = [];
171
- if (platform) {
172
- const result = this.scanSkills(platform);
173
- skills = result.skills;
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
- const skillsMd = this.generateSkillsMd(skills);
176
- return { platform, skills, skillsMd };
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