@hongmaple0820/scale-engine 0.2.0 → 0.5.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/README.md +976 -64
- package/dist/adapters/ClaudeCodeAdapter.d.ts +2 -2
- package/dist/adapters/ClaudeCodeAdapter.js +33 -45
- package/dist/adapters/ClaudeCodeAdapter.js.map +1 -1
- package/dist/adapters/CursorAdapter.d.ts +14 -0
- package/dist/adapters/CursorAdapter.js +169 -0
- package/dist/adapters/CursorAdapter.js.map +1 -0
- package/dist/adapters/GeminiAdapter.d.ts +13 -0
- package/dist/adapters/GeminiAdapter.js +157 -0
- package/dist/adapters/GeminiAdapter.js.map +1 -0
- package/dist/adapters/HermesAdapter.d.ts +13 -0
- package/dist/adapters/HermesAdapter.js +157 -0
- package/dist/adapters/HermesAdapter.js.map +1 -0
- package/dist/adapters/OpenClawAdapter.d.ts +13 -0
- package/dist/adapters/OpenClawAdapter.js +157 -0
- package/dist/adapters/OpenClawAdapter.js.map +1 -0
- package/dist/adapters/OpenCodeAdapter.d.ts +14 -0
- package/dist/adapters/OpenCodeAdapter.js +170 -0
- package/dist/adapters/OpenCodeAdapter.js.map +1 -0
- package/dist/adapters/index.d.ts +17 -0
- package/dist/adapters/index.js +42 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/api/cli.js +295 -6
- package/dist/api/cli.js.map +1 -1
- package/dist/artifact/fsmDefinitions.js +41 -1
- package/dist/artifact/fsmDefinitions.js.map +1 -1
- package/dist/artifact/types.d.ts +62 -1
- package/dist/artifact/types.js +27 -0
- package/dist/artifact/types.js.map +1 -1
- package/dist/context/ContextBuilder.d.ts +32 -1
- package/dist/context/ContextBuilder.js +135 -5
- package/dist/context/ContextBuilder.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +21 -4
- package/dist/index.js.map +1 -1
- package/dist/skills/SkillDiscovery.d.ts +28 -0
- package/dist/skills/SkillDiscovery.js +171 -0
- package/dist/skills/SkillDiscovery.js.map +1 -0
- package/dist/workflows/presets.d.ts +34 -0
- package/dist/workflows/presets.js +224 -0
- package/dist/workflows/presets.js.map +1 -0
- package/package.json +48 -48
package/dist/artifact/types.d.ts
CHANGED
|
@@ -130,6 +130,11 @@ export interface TaskPayload {
|
|
|
130
130
|
dependsOn: ArtifactId[];
|
|
131
131
|
requiredRole: string;
|
|
132
132
|
requiredCapabilities: string[];
|
|
133
|
+
buildStatus?: 'pending' | 'success' | 'failed';
|
|
134
|
+
buildExitCode?: number;
|
|
135
|
+
lintStatus?: 'pending' | 'success' | 'failed';
|
|
136
|
+
testPassed?: boolean;
|
|
137
|
+
testCoverage?: number;
|
|
133
138
|
}
|
|
134
139
|
/** Change —— 实际代码变更 */
|
|
135
140
|
export interface ChangePayload {
|
|
@@ -235,10 +240,11 @@ export interface GuardFailure {
|
|
|
235
240
|
}
|
|
236
241
|
export interface Session {
|
|
237
242
|
id: SessionId;
|
|
238
|
-
agent:
|
|
243
|
+
agent: AgentPlatform | 'unknown';
|
|
239
244
|
startedAt: Timestamp;
|
|
240
245
|
endedAt?: Timestamp;
|
|
241
246
|
activeRole?: string;
|
|
247
|
+
scenarioMode?: ScenarioMode;
|
|
242
248
|
metadata: Record<string, unknown>;
|
|
243
249
|
}
|
|
244
250
|
export interface ToolUseInput {
|
|
@@ -331,3 +337,58 @@ export declare class RoleDeniedError extends ScaleError {
|
|
|
331
337
|
export declare class ArtifactNotFoundError extends ScaleError {
|
|
332
338
|
constructor(id: string);
|
|
333
339
|
}
|
|
340
|
+
/** 场景模式:控制检测器敏感度、上下文规则、权限级别 */
|
|
341
|
+
export type ScenarioMode = 'sandbox' | 'standard' | 'critical';
|
|
342
|
+
/** 场景模式配置 */
|
|
343
|
+
export interface ScenarioModeConfig {
|
|
344
|
+
mode: ScenarioMode;
|
|
345
|
+
detectorSensitivity: 'low' | 'medium' | 'high';
|
|
346
|
+
verificationRequired: boolean;
|
|
347
|
+
humanConfirmationRequired: boolean;
|
|
348
|
+
auditTrail: boolean;
|
|
349
|
+
maxRetries: number;
|
|
350
|
+
}
|
|
351
|
+
/** 场景模式预设配置 */
|
|
352
|
+
export declare const SCENARIO_MODE_CONFIGS: Record<ScenarioMode, ScenarioModeConfig>;
|
|
353
|
+
/** Agent 平台类型 */
|
|
354
|
+
export type AgentPlatform = 'claude-code' | 'codex' | 'opencode' | 'cursor' | 'gemini' | 'openclaw' | 'hermes';
|
|
355
|
+
/** Skill 引用 */
|
|
356
|
+
export interface SkillRef {
|
|
357
|
+
id: string;
|
|
358
|
+
name: string;
|
|
359
|
+
description: string;
|
|
360
|
+
platform: AgentPlatform;
|
|
361
|
+
path: string;
|
|
362
|
+
enabled: boolean;
|
|
363
|
+
}
|
|
364
|
+
/** Skill 目录扫描结果 */
|
|
365
|
+
export interface SkillScanResult {
|
|
366
|
+
platform: AgentPlatform;
|
|
367
|
+
skillsDir: string;
|
|
368
|
+
skills: SkillRef[];
|
|
369
|
+
exists: boolean;
|
|
370
|
+
}
|
|
371
|
+
/** 工作流步骤 */
|
|
372
|
+
export interface WorkflowStep {
|
|
373
|
+
stepId: string;
|
|
374
|
+
skillId?: string;
|
|
375
|
+
action: string;
|
|
376
|
+
verificationGate?: string;
|
|
377
|
+
isMandatory: boolean;
|
|
378
|
+
description?: string;
|
|
379
|
+
}
|
|
380
|
+
/** 工作流预设 */
|
|
381
|
+
export interface WorkflowPreset {
|
|
382
|
+
id: string;
|
|
383
|
+
name: string;
|
|
384
|
+
nameZh: string;
|
|
385
|
+
description: string;
|
|
386
|
+
steps: WorkflowStep[];
|
|
387
|
+
scenarioMode: ScenarioMode;
|
|
388
|
+
requiredArtifacts: Array<{
|
|
389
|
+
type: ArtifactType;
|
|
390
|
+
status?: string;
|
|
391
|
+
}>;
|
|
392
|
+
}
|
|
393
|
+
/** Agent 类型扩展(支持所有 7 种 Agent) */
|
|
394
|
+
export type AgentType = AgentPlatform;
|
package/dist/artifact/types.js
CHANGED
|
@@ -47,4 +47,31 @@ export class ArtifactNotFoundError extends ScaleError {
|
|
|
47
47
|
super(`Artifact '${id}' not found`, 'ARTIFACT_NOT_FOUND', { id });
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
+
/** 场景模式预设配置 */
|
|
51
|
+
export const SCENARIO_MODE_CONFIGS = {
|
|
52
|
+
sandbox: {
|
|
53
|
+
mode: 'sandbox',
|
|
54
|
+
detectorSensitivity: 'low',
|
|
55
|
+
verificationRequired: false,
|
|
56
|
+
humanConfirmationRequired: false,
|
|
57
|
+
auditTrail: false,
|
|
58
|
+
maxRetries: 10,
|
|
59
|
+
},
|
|
60
|
+
standard: {
|
|
61
|
+
mode: 'standard',
|
|
62
|
+
detectorSensitivity: 'medium',
|
|
63
|
+
verificationRequired: true,
|
|
64
|
+
humanConfirmationRequired: false,
|
|
65
|
+
auditTrail: true,
|
|
66
|
+
maxRetries: 5,
|
|
67
|
+
},
|
|
68
|
+
critical: {
|
|
69
|
+
mode: 'critical',
|
|
70
|
+
detectorSensitivity: 'high',
|
|
71
|
+
verificationRequired: true,
|
|
72
|
+
humanConfirmationRequired: true,
|
|
73
|
+
auditTrail: true,
|
|
74
|
+
maxRetries: 3,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
50
77
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/artifact/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/artifact/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAweH,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E,MAAM,OAAO,UAAW,SAAQ,KAAK;IACC;IAAqB;IAAzD,YAAY,OAAe,EAAS,IAAY,EAAS,OAAiB;QACxE,KAAK,CAAC,OAAO,CAAC,CAAA;QADoB,SAAI,GAAJ,IAAI,CAAQ;QAAS,YAAO,GAAP,OAAO,CAAU;QAExE,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;IAC1B,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,UAAU;IACpD,YAAY,IAAY,EAAE,MAAc;QACtC,KAAK,CAAC,UAAU,IAAI,8BAA8B,MAAM,GAAG,EAAE,oBAAoB,EAAE;YACjF,IAAI;YACJ,MAAM;SACP,CAAC,CAAA;IACJ,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC3B;IAAnB,YAAmB,QAAwB;QACzC,KAAK,CAAC,iCAAiC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,cAAc,EAAE;YAChG,QAAQ;SACT,CAAC,CAAA;QAHe,aAAQ,GAAR,QAAQ,CAAgB;IAI3C,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,UAAU;IAC7C,YAAY,IAAY,EAAE,MAAc;QACtC,KAAK,CAAC,SAAS,IAAI,aAAa,MAAM,EAAE,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IAC5E,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,UAAU;IACnD,YAAY,EAAU;QACpB,KAAK,CAAC,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;IACnE,CAAC;CACF;AAmBD,eAAe;AACf,MAAM,CAAC,MAAM,qBAAqB,GAA6C;IAC7E,OAAO,EAAE;QACP,IAAI,EAAE,SAAS;QACf,mBAAmB,EAAE,KAAK;QAC1B,oBAAoB,EAAE,KAAK;QAC3B,yBAAyB,EAAE,KAAK;QAChC,UAAU,EAAE,KAAK;QACjB,UAAU,EAAE,EAAE;KACf;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,UAAU;QAChB,mBAAmB,EAAE,QAAQ;QAC7B,oBAAoB,EAAE,IAAI;QAC1B,yBAAyB,EAAE,KAAK;QAChC,UAAU,EAAE,IAAI;QAChB,UAAU,EAAE,CAAC;KACd;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,UAAU;QAChB,mBAAmB,EAAE,MAAM;QAC3B,oBAAoB,EAAE,IAAI;QAC1B,yBAAyB,EAAE,IAAI;QAC/B,UAAU,EAAE,IAAI;QAChB,UAAU,EAAE,CAAC;KACd;CACF,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ArtifactId, SessionId } from '../artifact/types.js';
|
|
1
|
+
import type { ArtifactId, SessionId, ScenarioMode } from '../artifact/types.js';
|
|
2
2
|
import type { IArtifactStore } from '../artifact/store.js';
|
|
3
3
|
import type { IKnowledgeBase } from '../knowledge/KnowledgeBase.js';
|
|
4
4
|
import type { IEventBus } from '../core/eventBus.js';
|
|
@@ -13,14 +13,37 @@ export interface BuiltContext {
|
|
|
13
13
|
metadata: {
|
|
14
14
|
totalTokens: number;
|
|
15
15
|
layers: string[];
|
|
16
|
+
scenarioMode?: ScenarioMode;
|
|
16
17
|
};
|
|
17
18
|
}
|
|
19
|
+
export interface ContextStatus {
|
|
20
|
+
sessionId: SessionId;
|
|
21
|
+
role: string;
|
|
22
|
+
allowedTools: string[];
|
|
23
|
+
deniedTools: string[];
|
|
24
|
+
activeArtifacts: Array<{
|
|
25
|
+
id: ArtifactId;
|
|
26
|
+
type: string;
|
|
27
|
+
status: string;
|
|
28
|
+
current?: boolean;
|
|
29
|
+
}>;
|
|
30
|
+
constraints: string[];
|
|
31
|
+
scenarioMode?: ScenarioMode;
|
|
32
|
+
}
|
|
18
33
|
export interface IContextBuilder {
|
|
19
34
|
build(opts: {
|
|
20
35
|
roleId?: string;
|
|
21
36
|
currentArtifactId?: ArtifactId;
|
|
22
37
|
sessionId: SessionId;
|
|
38
|
+
scenarioMode?: ScenarioMode;
|
|
23
39
|
}): Promise<BuiltContext>;
|
|
40
|
+
getStatus(sessionId: SessionId, roleGate: {
|
|
41
|
+
getRole(): {
|
|
42
|
+
id: string;
|
|
43
|
+
allowedTools: string[];
|
|
44
|
+
deniedTools?: string[];
|
|
45
|
+
};
|
|
46
|
+
}): Promise<ContextStatus>;
|
|
24
47
|
}
|
|
25
48
|
export declare class ContextBuilder implements IContextBuilder {
|
|
26
49
|
private store;
|
|
@@ -32,5 +55,13 @@ export declare class ContextBuilder implements IContextBuilder {
|
|
|
32
55
|
roleId?: string;
|
|
33
56
|
currentArtifactId?: ArtifactId;
|
|
34
57
|
sessionId: SessionId;
|
|
58
|
+
scenarioMode?: ScenarioMode;
|
|
35
59
|
}): Promise<BuiltContext>;
|
|
60
|
+
getStatus(sessionId: SessionId, roleGate: {
|
|
61
|
+
getRole(): {
|
|
62
|
+
id: string;
|
|
63
|
+
allowedTools: string[];
|
|
64
|
+
deniedTools?: string[];
|
|
65
|
+
};
|
|
66
|
+
}): Promise<ContextStatus>;
|
|
36
67
|
}
|
|
@@ -1,6 +1,75 @@
|
|
|
1
|
-
// SCALE Engine — Context Builder (
|
|
2
|
-
// 分层上下文加载 + Token 预算
|
|
1
|
+
// SCALE Engine — Context Builder (v0.5.0 完整实现)
|
|
2
|
+
// 分层上下文加载 + Token 预算 + SCALE v10.0 哲学 P1 层 + 场景模式感知
|
|
3
3
|
// 设计参考:docs/03-CORE-MODULES.md §3.6
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// SCALE v10.0 Philosophy — P1 system_rules layer content
|
|
6
|
+
// ============================================================================
|
|
7
|
+
const SCALE_V10_PHILOSOPHY = `## SCALE Engine v10.0 — System Rules
|
|
8
|
+
|
|
9
|
+
You are operating under SCALE Engine governance. These rules are PHYSICALLY ENFORCED — you cannot bypass them by choice.
|
|
10
|
+
|
|
11
|
+
### Core Philosophy
|
|
12
|
+
- **S**caffold — Every action is scaffolded by artifacts (Spec→Plan→Task→Change→Evidence)
|
|
13
|
+
- **C**ontrol — Guardrails physically block dangerous actions; no "soft" suggestions
|
|
14
|
+
- **A**rtifact — All work products are tracked artifacts with FSM state machines
|
|
15
|
+
- **L**earn — Defects auto-extract to Lessons → Rules → Hooks (evolution loop)
|
|
16
|
+
- **E**volve — The system improves itself from mistakes
|
|
17
|
+
|
|
18
|
+
### Physical Constraints (cannot be bypassed)
|
|
19
|
+
🔴 **Dangerous commands** (rm -rf, DROP TABLE, format) are BLOCKED at the gate
|
|
20
|
+
🔴 **Hardcoded secrets** (AWS keys, passwords, tokens) are BLOCKED on Edit/Write
|
|
21
|
+
🔴 **Unapproved code** — Cannot implement until Spec is FROZEN and Plan is APPROVED
|
|
22
|
+
🟡 **Brute retry** — 3+ identical retries detected → forced pause + context injection
|
|
23
|
+
🟡 **Premature completion** — Cannot claim "done" without running tests
|
|
24
|
+
🟡 **Blame shift** — Detected when AI blames environment without evidence
|
|
25
|
+
|
|
26
|
+
### Mandatory Workflow
|
|
27
|
+
1. **Explore** (role: explorer) — Read/Grep only, no edits
|
|
28
|
+
2. **Plan** (role: planner) — Create Spec → refine → approve (guard: ambiguity ≤ 0.2)
|
|
29
|
+
3. **Implement** (role: implementer) — Edit/Write/Bash unlocked only after Plan APPROVED
|
|
30
|
+
4. **Verify** — Must run build+lint+test before marking task complete
|
|
31
|
+
5. **Learn** — Defects auto-extract → lessons → rules → hooks
|
|
32
|
+
|
|
33
|
+
### Artifact Lifecycle
|
|
34
|
+
- Every piece of work is an Artifact with typed FSM transitions
|
|
35
|
+
- Guards check quality gates at each transition (ambiguity score, test coverage, etc.)
|
|
36
|
+
- Artifacts form a DAG: Need→Insight→Spec→Plan→Task→Change→Evidence
|
|
37
|
+
- Challenging a FROZEN Spec invalidates downstream Plans and Tasks
|
|
38
|
+
|
|
39
|
+
### Self-Evolution
|
|
40
|
+
- Defect → Lesson (auto-extracted from root cause)
|
|
41
|
+
- Lesson → Rule (promoted by access count + verification)
|
|
42
|
+
- Rule → Hook (auto-generated enforcement code)
|
|
43
|
+
- The system gets stricter over time, not weaker`;
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// Scenario Mode Context Additions
|
|
46
|
+
// ============================================================================
|
|
47
|
+
const SCENARIO_CONTEXT = {
|
|
48
|
+
sandbox: `### Scenario Mode: SANDBOX 🏖️
|
|
49
|
+
- Lower detector sensitivity — exploratory work allowed
|
|
50
|
+
- Verification NOT required before completion
|
|
51
|
+
- Human confirmation NOT required
|
|
52
|
+
- Audit trail disabled (lighter weight)
|
|
53
|
+
- Max retries: 10 (freedom to experiment)
|
|
54
|
+
- Use for: prototyping, exploration, learning`,
|
|
55
|
+
standard: `### Scenario Mode: STANDARD ⚙️
|
|
56
|
+
- Medium detector sensitivity — production-quality required
|
|
57
|
+
- Verification REQUIRED before completion
|
|
58
|
+
- Human confirmation NOT required (trust the process)
|
|
59
|
+
- Audit trail ENABLED
|
|
60
|
+
- Max retries: 5 (balanced)
|
|
61
|
+
- Use for: feature development, bug fixes, regular work`,
|
|
62
|
+
critical: `### Scenario Mode: CRITICAL 🔒
|
|
63
|
+
- Maximum detector sensitivity — zero tolerance for errors
|
|
64
|
+
- Verification REQUIRED before completion
|
|
65
|
+
- Human confirmation REQUIRED for key transitions
|
|
66
|
+
- Audit trail ENABLED (comprehensive)
|
|
67
|
+
- Max retries: 3 (fail fast, escalate)
|
|
68
|
+
- Use for: security changes, production deployments, data migrations`,
|
|
69
|
+
};
|
|
70
|
+
// ============================================================================
|
|
71
|
+
// ContextBuilder
|
|
72
|
+
// ============================================================================
|
|
4
73
|
export class ContextBuilder {
|
|
5
74
|
store;
|
|
6
75
|
kb;
|
|
@@ -12,11 +81,27 @@ export class ContextBuilder {
|
|
|
12
81
|
this.eventBus = eventBus;
|
|
13
82
|
}
|
|
14
83
|
async build(opts) {
|
|
84
|
+
const scenarioMode = opts.scenarioMode ?? 'standard';
|
|
15
85
|
const layers = [];
|
|
16
|
-
|
|
86
|
+
// P1: System Rules — SCALE v10.0 Philosophy (always present, highest priority)
|
|
87
|
+
layers.push({
|
|
88
|
+
name: 'system_rules',
|
|
89
|
+
content: SCALE_V10_PHILOSOPHY,
|
|
90
|
+
priority: 1,
|
|
91
|
+
estimatedTokens: 3500,
|
|
92
|
+
});
|
|
93
|
+
// P1.5: Scenario Mode awareness
|
|
94
|
+
layers.push({
|
|
95
|
+
name: 'scenario_mode',
|
|
96
|
+
content: SCENARIO_CONTEXT[scenarioMode],
|
|
97
|
+
priority: 1,
|
|
98
|
+
estimatedTokens: 800,
|
|
99
|
+
});
|
|
100
|
+
// P2: Role prompt
|
|
17
101
|
if (opts.roleId) {
|
|
18
102
|
layers.push({ name: 'role_prompt', content: `## Active Role: ${opts.roleId}\n...`, priority: 2, estimatedTokens: 1500 });
|
|
19
103
|
}
|
|
104
|
+
// P3: Current artifact context
|
|
20
105
|
if (opts.currentArtifactId) {
|
|
21
106
|
const artifact = await this.store.get(opts.currentArtifactId);
|
|
22
107
|
if (artifact) {
|
|
@@ -43,10 +128,55 @@ export class ContextBuilder {
|
|
|
43
128
|
selected.push(layer);
|
|
44
129
|
used += layer.estimatedTokens;
|
|
45
130
|
}
|
|
46
|
-
this.eventBus.emit('context.built', { layers: selected.map((l) => l.name), totalTokens: used }, { sessionId: opts.sessionId });
|
|
131
|
+
this.eventBus.emit('context.built', { layers: selected.map((l) => l.name), totalTokens: used, scenarioMode }, { sessionId: opts.sessionId });
|
|
47
132
|
return {
|
|
48
133
|
system: selected.map((l) => l.content).join('\n\n---\n\n'),
|
|
49
|
-
metadata: { totalTokens: used, layers: selected.map((l) => l.name) },
|
|
134
|
+
metadata: { totalTokens: used, layers: selected.map((l) => l.name), scenarioMode },
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
async getStatus(sessionId, roleGate) {
|
|
138
|
+
const role = roleGate.getRole();
|
|
139
|
+
// Query active artifacts for this session (linked via events)
|
|
140
|
+
const events = await this.eventBus.query({
|
|
141
|
+
sessionId,
|
|
142
|
+
types: ['artifact.created', 'artifact.transitioned'],
|
|
143
|
+
limit: 50
|
|
144
|
+
});
|
|
145
|
+
const artifactIds = new Set();
|
|
146
|
+
for (const event of events) {
|
|
147
|
+
if (event.artifactId) {
|
|
148
|
+
artifactIds.add(event.artifactId);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const activeArtifacts = await Promise.all(Array.from(artifactIds).map(async (id) => {
|
|
152
|
+
const artifact = await this.store.get(id);
|
|
153
|
+
return artifact ? {
|
|
154
|
+
id: artifact.id,
|
|
155
|
+
type: artifact.type,
|
|
156
|
+
status: artifact.status,
|
|
157
|
+
} : null;
|
|
158
|
+
}));
|
|
159
|
+
const validArtifacts = activeArtifacts.filter((a) => a !== null);
|
|
160
|
+
// Extract constraints from artifacts and FSM definitions
|
|
161
|
+
const constraints = [];
|
|
162
|
+
for (const artifact of validArtifacts) {
|
|
163
|
+
if (artifact.type === 'Spec' && artifact.status !== 'FROZEN') {
|
|
164
|
+
constraints.push(`Spec must be FROZEN before writing code (current: ${artifact.status})`);
|
|
165
|
+
}
|
|
166
|
+
if (artifact.type === 'Plan' && artifact.status === 'DRAFT') {
|
|
167
|
+
constraints.push(`Plan must be approved before implementation`);
|
|
168
|
+
}
|
|
169
|
+
if (artifact.type === 'Task' && artifact.status === 'TODO') {
|
|
170
|
+
constraints.push(`Task must be READY before implementation`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
sessionId,
|
|
175
|
+
role: role.id,
|
|
176
|
+
allowedTools: role.allowedTools,
|
|
177
|
+
deniedTools: role.deniedTools ?? [],
|
|
178
|
+
activeArtifacts: validArtifacts,
|
|
179
|
+
constraints,
|
|
50
180
|
};
|
|
51
181
|
}
|
|
52
182
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextBuilder.js","sourceRoot":"","sources":["../../src/context/ContextBuilder.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ContextBuilder.js","sourceRoot":"","sources":["../../src/context/ContextBuilder.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,11 +12,13 @@ export { BehaviorTracker } from './evolution/BehaviorTracker.js';
|
|
|
12
12
|
export { LessonExtractor, RuleProposer, HookGenerator, EvolutionEngine } from './evolution/EvolutionEngine.js';
|
|
13
13
|
export { Gateway } from './guardrails/Gateway.js';
|
|
14
14
|
export { ROLES, getRole, listRoles } from './guardrails/roles.js';
|
|
15
|
+
export { BruteRetryDetector, IdleToolDetector, BusyLoopDetector, PrematureDoneDetector, BlameShiftDetector, } from './guardrails/detectors.js';
|
|
15
16
|
export { ContextBuilder } from './context/ContextBuilder.js';
|
|
16
17
|
export { wireEffects } from './orchestration/EffectsWiring.js';
|
|
17
18
|
export { ModelRouter, DEFAULT_MODELS } from './routing/ModelRouter.js';
|
|
18
|
-
export { ClaudeCodeAdapter, createAdapter } from './adapters/
|
|
19
|
-
export {
|
|
19
|
+
export { ClaudeCodeAdapter, CodexAdapter, OpenCodeAdapter, CursorAdapter, GeminiAdapter, OpenClawAdapter, HermesAdapter, createAdapter, SUPPORTED_AGENTS, } from './adapters/index.js';
|
|
20
|
+
export type { IAgentAdapter, AdapterConfig, InitResult, SettingsJson, HookEntry } from './adapters/ClaudeCodeAdapter.js';
|
|
21
|
+
export { SkillDiscovery } from './skills/SkillDiscovery.js';
|
|
22
|
+
export { WORKFLOW_PRESETS, getWorkflowPreset, listWorkflowPresets, getPresetsByScenario, BASIC_DEV, TDD_DEV, BUG_FIX, SDD, CODE_REVIEW, SECURITY_AUDIT, RALPH_LOOP, RAPID_PROTO, MASSIVE_REFACTOR, PARALLEL_EXEC, } from './workflows/presets.js';
|
|
20
23
|
export { Doctor } from './api/doctor.js';
|
|
21
24
|
export { ScaleMCPServer } from './api/mcp.js';
|
|
22
|
-
export { BruteRetryDetector, IdleToolDetector, BusyLoopDetector, PrematureDoneDetector, BlameShiftDetector, } from './guardrails/detectors.js';
|
package/dist/index.js
CHANGED
|
@@ -1,22 +1,39 @@
|
|
|
1
|
-
// SCALE Engine — Public API
|
|
1
|
+
// SCALE Engine v0.5.0 — Public API
|
|
2
|
+
// S · C · A · L · E: Scaffold · Control · Artifact · Learn · Evolve
|
|
3
|
+
// Core types
|
|
2
4
|
export * from './artifact/types.js';
|
|
5
|
+
// FSM
|
|
3
6
|
export { FSM, SpecFSM } from './artifact/fsm.js';
|
|
7
|
+
// Artifact Store
|
|
4
8
|
export { InMemoryArtifactStore } from './artifact/store.js';
|
|
9
|
+
// Core Infrastructure
|
|
5
10
|
export { EventBus } from './core/eventBus.js';
|
|
6
11
|
export { Container, container, createToken } from './core/container.js';
|
|
7
12
|
export { logger } from './core/logger.js';
|
|
13
|
+
// Task Engine
|
|
8
14
|
export { TaskEngine } from './tasks/TaskEngine.js';
|
|
15
|
+
// Knowledge Base
|
|
9
16
|
export { KnowledgeBase } from './knowledge/KnowledgeBase.js';
|
|
17
|
+
// Evolution
|
|
10
18
|
export { BehaviorTracker } from './evolution/BehaviorTracker.js';
|
|
11
19
|
export { LessonExtractor, RuleProposer, HookGenerator, EvolutionEngine } from './evolution/EvolutionEngine.js';
|
|
20
|
+
// Guardrails
|
|
12
21
|
export { Gateway } from './guardrails/Gateway.js';
|
|
13
22
|
export { ROLES, getRole, listRoles } from './guardrails/roles.js';
|
|
23
|
+
export { BruteRetryDetector, IdleToolDetector, BusyLoopDetector, PrematureDoneDetector, BlameShiftDetector, } from './guardrails/detectors.js';
|
|
24
|
+
// Context
|
|
14
25
|
export { ContextBuilder } from './context/ContextBuilder.js';
|
|
26
|
+
// Orchestration
|
|
15
27
|
export { wireEffects } from './orchestration/EffectsWiring.js';
|
|
28
|
+
// Routing
|
|
16
29
|
export { ModelRouter, DEFAULT_MODELS } from './routing/ModelRouter.js';
|
|
17
|
-
|
|
18
|
-
export { CodexAdapter } from './adapters/
|
|
30
|
+
// Adapters (all 7 platforms)
|
|
31
|
+
export { ClaudeCodeAdapter, CodexAdapter, OpenCodeAdapter, CursorAdapter, GeminiAdapter, OpenClawAdapter, HermesAdapter, createAdapter, SUPPORTED_AGENTS, } from './adapters/index.js';
|
|
32
|
+
// Skill Discovery
|
|
33
|
+
export { SkillDiscovery } from './skills/SkillDiscovery.js';
|
|
34
|
+
// Workflow Presets
|
|
35
|
+
export { WORKFLOW_PRESETS, getWorkflowPreset, listWorkflowPresets, getPresetsByScenario, BASIC_DEV, TDD_DEV, BUG_FIX, SDD, CODE_REVIEW, SECURITY_AUDIT, RALPH_LOOP, RAPID_PROTO, MASSIVE_REFACTOR, PARALLEL_EXEC, } from './workflows/presets.js';
|
|
36
|
+
// API
|
|
19
37
|
export { Doctor } from './api/doctor.js';
|
|
20
38
|
export { ScaleMCPServer } from './api/mcp.js';
|
|
21
|
-
export { BruteRetryDetector, IdleToolDetector, BusyLoopDetector, PrematureDoneDetector, BlameShiftDetector, } from './guardrails/detectors.js';
|
|
22
39
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,oEAAoE;AAEpE,aAAa;AACb,cAAc,qBAAqB,CAAA;AAEnC,MAAM;AACN,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAEhD,iBAAiB;AACjB,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAG3D,sBAAsB;AACtB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE7C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAEzC,cAAc;AACd,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAElD,iBAAiB;AACjB,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAE5D,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAE9G,aAAa;AACb,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,EACL,kBAAkB,EAAE,gBAAgB,EAAE,gBAAgB,EACtD,qBAAqB,EAAE,kBAAkB,GAC1C,MAAM,2BAA2B,CAAA;AAElC,UAAU;AACV,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAE5D,gBAAgB;AAChB,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAE9D,UAAU;AACV,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEtE,6BAA6B;AAC7B,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,GACjB,MAAM,qBAAqB,CAAA;AAG5B,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAE3D,mBAAmB;AACnB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,SAAS,EACT,OAAO,EACP,OAAO,EACP,GAAG,EACH,WAAW,EACX,cAAc,EACd,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,aAAa,GACd,MAAM,wBAAwB,CAAA;AAE/B,MAAM;AACN,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AgentPlatform, SkillRef, SkillScanResult } from '../artifact/types.js';
|
|
2
|
+
export declare class SkillDiscovery {
|
|
3
|
+
private projectDir;
|
|
4
|
+
constructor(projectDir?: string);
|
|
5
|
+
/**
|
|
6
|
+
* Detect the active agent platform based on config files present in the project.
|
|
7
|
+
* Returns the most likely platform, or null if indeterminate.
|
|
8
|
+
*/
|
|
9
|
+
detectPlatform(): AgentPlatform | null;
|
|
10
|
+
/**
|
|
11
|
+
* Scan the skills directory for a given platform.
|
|
12
|
+
* Returns structured skill references.
|
|
13
|
+
*/
|
|
14
|
+
scanSkills(platform: AgentPlatform): SkillScanResult;
|
|
15
|
+
/**
|
|
16
|
+
* Generate a skills.md document from discovered skills.
|
|
17
|
+
* Useful for injecting into agent knowledge docs.
|
|
18
|
+
*/
|
|
19
|
+
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
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// SCALE Engine — Skill Discovery
|
|
2
|
+
// 检测平台 → 扫描技能目录 → 生成 skills.md
|
|
3
|
+
// 设计参考:SCALE v10.0 技能生态系统
|
|
4
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Platform Skills Directory Map
|
|
9
|
+
// ============================================================================
|
|
10
|
+
const PLATFORM_SKILLS_DIRS = {
|
|
11
|
+
'claude-code': null, // Claude Code uses .claude/commands/, no dedicated skills dir
|
|
12
|
+
'codex': null, // Codex uses .codex/commands/
|
|
13
|
+
'opencode': join(homedir(), '.config', 'opencode', 'skills'),
|
|
14
|
+
'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
|
+
};
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// SkillDiscovery
|
|
21
|
+
// ============================================================================
|
|
22
|
+
export class SkillDiscovery {
|
|
23
|
+
projectDir;
|
|
24
|
+
constructor(projectDir = '.') {
|
|
25
|
+
this.projectDir = projectDir;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Detect the active agent platform based on config files present in the project.
|
|
29
|
+
* Returns the most likely platform, or null if indeterminate.
|
|
30
|
+
*/
|
|
31
|
+
detectPlatform() {
|
|
32
|
+
const checks = [
|
|
33
|
+
{ platform: 'claude-code', paths: [join(this.projectDir, '.claude', 'settings.json')] },
|
|
34
|
+
{ platform: 'codex', paths: [join(this.projectDir, '.codex', 'hooks.json')] },
|
|
35
|
+
{ platform: 'opencode', paths: [join(homedir(), '.config', 'opencode', 'hooks.json')] },
|
|
36
|
+
{ platform: 'cursor', paths: [join(this.projectDir, '.cursor', 'settings.json')] },
|
|
37
|
+
{ platform: 'gemini', paths: [join(this.projectDir, '.gemini', 'settings.json')] },
|
|
38
|
+
{ platform: 'openclaw', paths: [join(this.projectDir, '.openclaw', 'settings.json')] },
|
|
39
|
+
{ platform: 'hermes', paths: [join(this.projectDir, '.hermes', 'settings.json')] },
|
|
40
|
+
];
|
|
41
|
+
for (const check of checks) {
|
|
42
|
+
if (check.paths.some((p) => existsSync(p))) {
|
|
43
|
+
return check.platform;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Scan the skills directory for a given platform.
|
|
50
|
+
* Returns structured skill references.
|
|
51
|
+
*/
|
|
52
|
+
scanSkills(platform) {
|
|
53
|
+
const skillsDir = PLATFORM_SKILLS_DIRS[platform];
|
|
54
|
+
if (!skillsDir) {
|
|
55
|
+
return {
|
|
56
|
+
platform,
|
|
57
|
+
skillsDir: '',
|
|
58
|
+
skills: [],
|
|
59
|
+
exists: false,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const resolvedDir = platform === 'opencode'
|
|
63
|
+
? skillsDir
|
|
64
|
+
: join(this.projectDir, skillsDir);
|
|
65
|
+
if (!existsSync(resolvedDir)) {
|
|
66
|
+
return {
|
|
67
|
+
platform,
|
|
68
|
+
skillsDir: resolvedDir,
|
|
69
|
+
skills: [],
|
|
70
|
+
exists: false,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const skills = [];
|
|
74
|
+
try {
|
|
75
|
+
const entries = readdirSync(resolvedDir);
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
const entryPath = join(resolvedDir, entry);
|
|
78
|
+
const stat = statSync(entryPath);
|
|
79
|
+
if (stat.isFile() && (entry.endsWith('.md') || entry.endsWith('.json') || entry.endsWith('.yaml') || entry.endsWith('.yml'))) {
|
|
80
|
+
const name = entry.replace(/\.(md|json|ya?ml)$/, '');
|
|
81
|
+
let description = '';
|
|
82
|
+
// Try to extract description from file content
|
|
83
|
+
try {
|
|
84
|
+
const content = readFileSync(entryPath, 'utf-8');
|
|
85
|
+
// Extract first line as description for .md files
|
|
86
|
+
if (entry.endsWith('.md')) {
|
|
87
|
+
const firstLine = content.split('\n').find((l) => l.trim().length > 0) ?? '';
|
|
88
|
+
description = firstLine.replace(/^#+\s*/, '').trim();
|
|
89
|
+
}
|
|
90
|
+
else if (entry.endsWith('.json')) {
|
|
91
|
+
const parsed = JSON.parse(content);
|
|
92
|
+
description = parsed.description ?? parsed.name ?? '';
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
description = '';
|
|
97
|
+
}
|
|
98
|
+
skills.push({
|
|
99
|
+
id: `${platform}-${name}`,
|
|
100
|
+
name,
|
|
101
|
+
description,
|
|
102
|
+
platform,
|
|
103
|
+
path: entryPath,
|
|
104
|
+
enabled: true,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else if (stat.isDirectory()) {
|
|
108
|
+
// Directory-based skills
|
|
109
|
+
skills.push({
|
|
110
|
+
id: `${platform}-${entry}`,
|
|
111
|
+
name: entry,
|
|
112
|
+
description: '',
|
|
113
|
+
platform,
|
|
114
|
+
path: entryPath,
|
|
115
|
+
enabled: true,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Permission or read error
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
platform,
|
|
125
|
+
skillsDir: resolvedDir,
|
|
126
|
+
skills,
|
|
127
|
+
exists: true,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Generate a skills.md document from discovered skills.
|
|
132
|
+
* Useful for injecting into agent knowledge docs.
|
|
133
|
+
*/
|
|
134
|
+
generateSkillsMd(skills) {
|
|
135
|
+
if (skills.length === 0) {
|
|
136
|
+
return '## Available Skills\n\nNo skills discovered.\n';
|
|
137
|
+
}
|
|
138
|
+
const grouped = new Map();
|
|
139
|
+
for (const skill of skills) {
|
|
140
|
+
const group = grouped.get(skill.platform) ?? [];
|
|
141
|
+
group.push(skill);
|
|
142
|
+
grouped.set(skill.platform, group);
|
|
143
|
+
}
|
|
144
|
+
const sections = ['## Available Skills\n'];
|
|
145
|
+
for (const [platform, platformSkills] of grouped) {
|
|
146
|
+
sections.push(`### ${platform}`);
|
|
147
|
+
sections.push('');
|
|
148
|
+
for (const skill of platformSkills) {
|
|
149
|
+
const desc = skill.description ? ` — ${skill.description}` : '';
|
|
150
|
+
const status = skill.enabled ? '✅' : '❌';
|
|
151
|
+
sections.push(`- ${status} **${skill.name}**${desc}`);
|
|
152
|
+
}
|
|
153
|
+
sections.push('');
|
|
154
|
+
}
|
|
155
|
+
return sections.join('\n');
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Full discovery pipeline: detect platform → scan → generate doc.
|
|
159
|
+
*/
|
|
160
|
+
discover() {
|
|
161
|
+
const platform = this.detectPlatform();
|
|
162
|
+
let skills = [];
|
|
163
|
+
if (platform) {
|
|
164
|
+
const result = this.scanSkills(platform);
|
|
165
|
+
skills = result.skills;
|
|
166
|
+
}
|
|
167
|
+
const skillsMd = this.generateSkillsMd(skills);
|
|
168
|
+
return { platform, skills, skillsMd };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=SkillDiscovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillDiscovery.js","sourceRoot":"","sources":["../../src/skills/SkillDiscovery.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,+BAA+B;AAC/B,0BAA0B;AAE1B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAGjC,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;AAE/E,MAAM,oBAAoB,GAAyC;IACjE,aAAa,EAAE,IAAI,EAAE,8DAA8D;IACnF,OAAO,EAAE,IAAI,EAAQ,8BAA8B;IACnD,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC;IAC5D,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC;IACnC,QAAQ,EAAE,IAAI,EAAO,yCAAyC;IAC9D,UAAU,EAAE,IAAI,EAAK,2CAA2C;IAChE,QAAQ,EAAE,IAAI,EAAO,yCAAyC;CAC/D,CAAA;AAED,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,OAAO,cAAc;IACjB,UAAU,CAAQ;IAE1B,YAAY,aAAqB,GAAG;QAClC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9B,CAAC;IAED;;;OAGG;IACH,cAAc;QACZ,MAAM,MAAM,GAAwD;YAClE,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC,EAAE;YACvF,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,EAAE;YAC7E,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,EAAE;YACvF,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC,EAAE;YAClF,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC,EAAE;YAClF,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC,EAAE;YACtF,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC,EAAE;SACnF,CAAA;QAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3C,OAAO,KAAK,CAAC,QAAQ,CAAA;YACvB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,QAAuB;QAChC,MAAM,SAAS,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAA;QAChD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;gBACL,QAAQ;gBACR,SAAS,EAAE,EAAE;gBACb,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,KAAK;aACd,CAAA;QACH,CAAC;QAED,MAAM,WAAW,GAAG,QAAQ,KAAK,UAAU;YACzC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;QAEpC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC7B,OAAO;gBACL,QAAQ;gBACR,SAAS,EAAE,WAAW;gBACtB,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,KAAK;aACd,CAAA;QACH,CAAC;QAED,MAAM,MAAM,GAAe,EAAE,CAAA;QAE7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,CAAC,CAAA;YACxC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;gBAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAA;gBAEhC,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;oBAC7H,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAA;oBACpD,IAAI,WAAW,GAAG,EAAE,CAAA;oBAEpB,+CAA+C;oBAC/C,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;wBAChD,kDAAkD;wBAClD,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;4BAC1B,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;4BAC5E,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;wBACtD,CAAC;6BAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;4BACnC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;4BAClC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,CAAA;wBACvD,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,WAAW,GAAG,EAAE,CAAA;oBAClB,CAAC;oBAED,MAAM,CAAC,IAAI,CAAC;wBACV,EAAE,EAAE,GAAG,QAAQ,IAAI,IAAI,EAAE;wBACzB,IAAI;wBACJ,WAAW;wBACX,QAAQ;wBACR,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,IAAI;qBACd,CAAC,CAAA;gBACJ,CAAC;qBAAM,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;oBAC9B,yBAAyB;oBACzB,MAAM,CAAC,IAAI,CAAC;wBACV,EAAE,EAAE,GAAG,QAAQ,IAAI,KAAK,EAAE;wBAC1B,IAAI,EAAE,KAAK;wBACX,WAAW,EAAE,EAAE;wBACf,QAAQ;wBACR,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,IAAI;qBACd,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;QAED,OAAO;YACL,QAAQ;YACR,SAAS,EAAE,WAAW;YACtB,MAAM;YACN,MAAM,EAAE,IAAI;SACb,CAAA;IACH,CAAC;IAED;;;OAGG;IACH,gBAAgB,CAAC,MAAkB;QACjC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,gDAAgD,CAAA;QACzD,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAA6B,CAAA;QACpD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;YAC/C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QACpC,CAAC;QAED,MAAM,QAAQ,GAAa,CAAC,uBAAuB,CAAC,CAAA;QAEpD,KAAK,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,IAAI,OAAO,EAAE,CAAC;YACjD,QAAQ,CAAC,IAAI,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAA;YAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACjB,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;gBACnC,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;gBAC/D,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;gBACxC,QAAQ,CAAC,IAAI,CAAC,KAAK,MAAM,MAAM,KAAK,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,CAAA;YACvD,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACnB,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;QACtC,IAAI,MAAM,GAAe,EAAE,CAAA;QAE3B,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;YACxC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;QACxB,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAA;QAE9C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;IACvC,CAAC;CACF"}
|