cray-code 1.0.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 +316 -0
- package/dist/Tool.d.ts +217 -0
- package/dist/Tool.d.ts.map +1 -0
- package/dist/Tool.js +89 -0
- package/dist/Tool.js.map +1 -0
- package/dist/branding/logo.d.ts +8 -0
- package/dist/branding/logo.d.ts.map +1 -0
- package/dist/branding/logo.js +26 -0
- package/dist/branding/logo.js.map +1 -0
- package/dist/branding/theme.d.ts +27 -0
- package/dist/branding/theme.d.ts.map +1 -0
- package/dist/branding/theme.js +28 -0
- package/dist/branding/theme.js.map +1 -0
- package/dist/commands/registry.d.ts +32 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +759 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/components/MessageView.d.ts +12 -0
- package/dist/components/MessageView.d.ts.map +1 -0
- package/dist/components/MessageView.js +35 -0
- package/dist/components/MessageView.js.map +1 -0
- package/dist/components/PermissionPrompt.d.ts +11 -0
- package/dist/components/PermissionPrompt.d.ts.map +1 -0
- package/dist/components/PermissionPrompt.js +6 -0
- package/dist/components/PermissionPrompt.js.map +1 -0
- package/dist/components/PluginManager.d.ts +27 -0
- package/dist/components/PluginManager.d.ts.map +1 -0
- package/dist/components/PluginManager.js +391 -0
- package/dist/components/PluginManager.js.map +1 -0
- package/dist/components/ThinkingBlock.d.ts +27 -0
- package/dist/components/ThinkingBlock.d.ts.map +1 -0
- package/dist/components/ThinkingBlock.js +29 -0
- package/dist/components/ThinkingBlock.js.map +1 -0
- package/dist/components/ToolCallBlock.d.ts +14 -0
- package/dist/components/ToolCallBlock.d.ts.map +1 -0
- package/dist/components/ToolCallBlock.js +83 -0
- package/dist/components/ToolCallBlock.js.map +1 -0
- package/dist/components/TrustDialog.d.ts +20 -0
- package/dist/components/TrustDialog.d.ts.map +1 -0
- package/dist/components/TrustDialog.js +80 -0
- package/dist/components/TrustDialog.js.map +1 -0
- package/dist/context.d.ts +25 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +268 -0
- package/dist/context.js.map +1 -0
- package/dist/cray.d.ts +114 -0
- package/dist/cray.d.ts.map +1 -0
- package/dist/cray.js +338 -0
- package/dist/cray.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +122 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/registry.d.ts +106 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +695 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/query.d.ts +31 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +637 -0
- package/dist/query.js.map +1 -0
- package/dist/queryStream.d.ts +36 -0
- package/dist/queryStream.d.ts.map +1 -0
- package/dist/queryStream.js +704 -0
- package/dist/queryStream.js.map +1 -0
- package/dist/screens/ReplScreen.d.ts +22 -0
- package/dist/screens/ReplScreen.d.ts.map +1 -0
- package/dist/screens/ReplScreen.js +763 -0
- package/dist/screens/ReplScreen.js.map +1 -0
- package/dist/services/agentRunner.d.ts +39 -0
- package/dist/services/agentRunner.d.ts.map +1 -0
- package/dist/services/agentRunner.js +115 -0
- package/dist/services/agentRunner.js.map +1 -0
- package/dist/services/compact.d.ts +34 -0
- package/dist/services/compact.d.ts.map +1 -0
- package/dist/services/compact.js +179 -0
- package/dist/services/compact.js.map +1 -0
- package/dist/services/loadPluginCommands.d.ts +55 -0
- package/dist/services/loadPluginCommands.d.ts.map +1 -0
- package/dist/services/loadPluginCommands.js +219 -0
- package/dist/services/loadPluginCommands.js.map +1 -0
- package/dist/services/mcp/index.d.ts +3 -0
- package/dist/services/mcp/index.d.ts.map +1 -0
- package/dist/services/mcp/index.js +3 -0
- package/dist/services/mcp/index.js.map +1 -0
- package/dist/services/mcp/manager.d.ts +24 -0
- package/dist/services/mcp/manager.d.ts.map +1 -0
- package/dist/services/mcp/manager.js +138 -0
- package/dist/services/mcp/manager.js.map +1 -0
- package/dist/services/mcp/types.d.ts +52 -0
- package/dist/services/mcp/types.d.ts.map +1 -0
- package/dist/services/mcp/types.js +5 -0
- package/dist/services/mcp/types.js.map +1 -0
- package/dist/services/memory.d.ts +38 -0
- package/dist/services/memory.d.ts.map +1 -0
- package/dist/services/memory.js +181 -0
- package/dist/services/memory.js.map +1 -0
- package/dist/services/permissionPrompt.d.ts +38 -0
- package/dist/services/permissionPrompt.d.ts.map +1 -0
- package/dist/services/permissionPrompt.js +83 -0
- package/dist/services/permissionPrompt.js.map +1 -0
- package/dist/services/permissions.d.ts +15 -0
- package/dist/services/permissions.d.ts.map +1 -0
- package/dist/services/permissions.js +237 -0
- package/dist/services/permissions.js.map +1 -0
- package/dist/services/sessionStorage.d.ts +51 -0
- package/dist/services/sessionStorage.d.ts.map +1 -0
- package/dist/services/sessionStorage.js +266 -0
- package/dist/services/sessionStorage.js.map +1 -0
- package/dist/setup.d.ts +22 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +160 -0
- package/dist/setup.js.map +1 -0
- package/dist/skills/bundledSkills.d.ts +18 -0
- package/dist/skills/bundledSkills.d.ts.map +1 -0
- package/dist/skills/bundledSkills.js +277 -0
- package/dist/skills/bundledSkills.js.map +1 -0
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +3 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/loadSkillsDir.d.ts +45 -0
- package/dist/skills/loadSkillsDir.d.ts.map +1 -0
- package/dist/skills/loadSkillsDir.js +233 -0
- package/dist/skills/loadSkillsDir.js.map +1 -0
- package/dist/state/AppState.d.ts +70 -0
- package/dist/state/AppState.d.ts.map +1 -0
- package/dist/state/AppState.js +106 -0
- package/dist/state/AppState.js.map +1 -0
- package/dist/tools/AgentTool.d.ts +62 -0
- package/dist/tools/AgentTool.d.ts.map +1 -0
- package/dist/tools/AgentTool.js +133 -0
- package/dist/tools/AgentTool.js.map +1 -0
- package/dist/tools/AskUserQuestionTool.d.ts +60 -0
- package/dist/tools/AskUserQuestionTool.d.ts.map +1 -0
- package/dist/tools/AskUserQuestionTool.js +52 -0
- package/dist/tools/AskUserQuestionTool.js.map +1 -0
- package/dist/tools/BashTool.d.ts +33 -0
- package/dist/tools/BashTool.d.ts.map +1 -0
- package/dist/tools/BashTool.js +211 -0
- package/dist/tools/BashTool.js.map +1 -0
- package/dist/tools/EditTool.d.ts +24 -0
- package/dist/tools/EditTool.d.ts.map +1 -0
- package/dist/tools/EditTool.js +102 -0
- package/dist/tools/EditTool.js.map +1 -0
- package/dist/tools/GlobTool.d.ts +17 -0
- package/dist/tools/GlobTool.d.ts.map +1 -0
- package/dist/tools/GlobTool.js +65 -0
- package/dist/tools/GlobTool.js.map +1 -0
- package/dist/tools/GrepTool.d.ts +30 -0
- package/dist/tools/GrepTool.d.ts.map +1 -0
- package/dist/tools/GrepTool.js +140 -0
- package/dist/tools/GrepTool.js.map +1 -0
- package/dist/tools/MCPTool.d.ts +24 -0
- package/dist/tools/MCPTool.d.ts.map +1 -0
- package/dist/tools/MCPTool.js +67 -0
- package/dist/tools/MCPTool.js.map +1 -0
- package/dist/tools/NotebookEditTool.d.ts +28 -0
- package/dist/tools/NotebookEditTool.d.ts.map +1 -0
- package/dist/tools/NotebookEditTool.js +213 -0
- package/dist/tools/NotebookEditTool.js.map +1 -0
- package/dist/tools/NotebookReadTool.d.ts +19 -0
- package/dist/tools/NotebookReadTool.d.ts.map +1 -0
- package/dist/tools/NotebookReadTool.js +191 -0
- package/dist/tools/NotebookReadTool.js.map +1 -0
- package/dist/tools/PlanTools.d.ts +17 -0
- package/dist/tools/PlanTools.d.ts.map +1 -0
- package/dist/tools/PlanTools.js +65 -0
- package/dist/tools/PlanTools.js.map +1 -0
- package/dist/tools/ReadTool.d.ts +21 -0
- package/dist/tools/ReadTool.d.ts.map +1 -0
- package/dist/tools/ReadTool.js +202 -0
- package/dist/tools/ReadTool.js.map +1 -0
- package/dist/tools/SkillTool.d.ts +32 -0
- package/dist/tools/SkillTool.d.ts.map +1 -0
- package/dist/tools/SkillTool.js +217 -0
- package/dist/tools/SkillTool.js.map +1 -0
- package/dist/tools/TodoWriteTool.d.ts +35 -0
- package/dist/tools/TodoWriteTool.d.ts.map +1 -0
- package/dist/tools/TodoWriteTool.js +58 -0
- package/dist/tools/TodoWriteTool.js.map +1 -0
- package/dist/tools/WebFetchTool.d.ts +17 -0
- package/dist/tools/WebFetchTool.d.ts.map +1 -0
- package/dist/tools/WebFetchTool.js +97 -0
- package/dist/tools/WebFetchTool.js.map +1 -0
- package/dist/tools/WebSearchTool.d.ts +18 -0
- package/dist/tools/WebSearchTool.d.ts.map +1 -0
- package/dist/tools/WebSearchTool.js +76 -0
- package/dist/tools/WebSearchTool.js.map +1 -0
- package/dist/tools/WriteTool.d.ts +17 -0
- package/dist/tools/WriteTool.d.ts.map +1 -0
- package/dist/tools/WriteTool.js +84 -0
- package/dist/tools/WriteTool.js.map +1 -0
- package/dist/tools/index.d.ts +21 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +20 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools.d.ts +34 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +102 -0
- package/dist/tools.js.map +1 -0
- package/dist/types/events.d.ts +85 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +12 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/message.d.ts +71 -0
- package/dist/types/message.d.ts.map +1 -0
- package/dist/types/message.js +5 -0
- package/dist/types/message.js.map +1 -0
- package/dist/types/permission.d.ts +56 -0
- package/dist/types/permission.d.ts.map +1 -0
- package/dist/types/permission.js +46 -0
- package/dist/types/permission.js.map +1 -0
- package/dist/types/processUserInput.d.ts +18 -0
- package/dist/types/processUserInput.d.ts.map +1 -0
- package/dist/types/processUserInput.js +8 -0
- package/dist/types/processUserInput.js.map +1 -0
- package/dist/types/tool.d.ts +32 -0
- package/dist/types/tool.d.ts.map +1 -0
- package/dist/types/tool.js +5 -0
- package/dist/types/tool.js.map +1 -0
- package/dist/utils/compactBoundary.d.ts +11 -0
- package/dist/utils/compactBoundary.d.ts.map +1 -0
- package/dist/utils/compactBoundary.js +26 -0
- package/dist/utils/compactBoundary.js.map +1 -0
- package/dist/utils/configStore.d.ts +41 -0
- package/dist/utils/configStore.d.ts.map +1 -0
- package/dist/utils/configStore.js +111 -0
- package/dist/utils/configStore.js.map +1 -0
- package/dist/utils/forkedAgent.d.ts +40 -0
- package/dist/utils/forkedAgent.d.ts.map +1 -0
- package/dist/utils/forkedAgent.js +231 -0
- package/dist/utils/forkedAgent.js.map +1 -0
- package/dist/utils/messages.d.ts +14 -0
- package/dist/utils/messages.d.ts.map +1 -0
- package/dist/utils/messages.js +29 -0
- package/dist/utils/messages.js.map +1 -0
- package/dist/utils/sandbox.d.ts +22 -0
- package/dist/utils/sandbox.d.ts.map +1 -0
- package/dist/utils/sandbox.js +59 -0
- package/dist/utils/sandbox.js.map +1 -0
- package/dist/utils/sideQuestion.d.ts +29 -0
- package/dist/utils/sideQuestion.d.ts.map +1 -0
- package/dist/utils/sideQuestion.js +81 -0
- package/dist/utils/sideQuestion.js.map +1 -0
- package/install.ps1 +86 -0
- package/install.sh +92 -0
- package/package.json +68 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* loadPluginCommands.ts — Plugin Command/Skill Loader for Cray Code.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors Claude Code's plugin loading pattern: walks plugin directories
|
|
5
|
+
* for .md files (commands) and SKILL.md files (skills), parses frontmatter,
|
|
6
|
+
* and returns full Command objects with getPromptForCommand() callbacks.
|
|
7
|
+
*
|
|
8
|
+
* Plugin directory structure:
|
|
9
|
+
* .cray/plugins/<name>/
|
|
10
|
+
* manifest.json — { name, version, description, ... }
|
|
11
|
+
* commands/ — *.md files = commands
|
|
12
|
+
* skills/ — <skill-name>/SKILL.md = skills
|
|
13
|
+
* mcp.json — { servers: { ... } }
|
|
14
|
+
* hooks.js — { onSessionStart, onSessionEnd, ... }
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
|
|
17
|
+
import { join, basename, extname } from 'path';
|
|
18
|
+
/**
|
|
19
|
+
* Walk a directory recursively looking for .md files.
|
|
20
|
+
* Stops at directories that contain their own SKILL.md (skill boundaries).
|
|
21
|
+
*/
|
|
22
|
+
function walkMarkdownDir(dirPath, baseDir) {
|
|
23
|
+
const files = [];
|
|
24
|
+
if (!existsSync(dirPath))
|
|
25
|
+
return files;
|
|
26
|
+
try {
|
|
27
|
+
// Check if this directory is itself a skill (has SKILL.md)
|
|
28
|
+
const skillMd = join(dirPath, 'SKILL.md');
|
|
29
|
+
if (existsSync(skillMd)) {
|
|
30
|
+
const content = readFileSync(skillMd, 'utf-8');
|
|
31
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
32
|
+
files.push({ filePath: skillMd, baseDir: dirPath, frontmatter, content: body });
|
|
33
|
+
// Don't descend further — treat as skill boundary
|
|
34
|
+
return files;
|
|
35
|
+
}
|
|
36
|
+
for (const entry of readdirSync(dirPath)) {
|
|
37
|
+
const full = join(dirPath, entry);
|
|
38
|
+
try {
|
|
39
|
+
const st = statSync(full);
|
|
40
|
+
if (st.isDirectory()) {
|
|
41
|
+
// Recurse into subdirectories
|
|
42
|
+
files.push(...walkMarkdownDir(full, baseDir));
|
|
43
|
+
}
|
|
44
|
+
else if (st.isFile() && extname(entry).toLowerCase() === '.md') {
|
|
45
|
+
const content = readFileSync(full, 'utf-8');
|
|
46
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
47
|
+
files.push({ filePath: full, baseDir, frontmatter, content: body });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch { /* skip unreadable */ }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch { /* dir may not exist */ }
|
|
54
|
+
return files;
|
|
55
|
+
}
|
|
56
|
+
// ─── Frontmatter Parser ───────────────────────────────────────────────
|
|
57
|
+
function parseFrontmatter(raw) {
|
|
58
|
+
const frontmatter = {};
|
|
59
|
+
let body = raw;
|
|
60
|
+
if (raw.startsWith('---')) {
|
|
61
|
+
const endIdx = raw.indexOf('---', 3);
|
|
62
|
+
if (endIdx > 0) {
|
|
63
|
+
body = raw.slice(endIdx + 3).trim();
|
|
64
|
+
const fmBlock = raw.slice(3, endIdx).trim();
|
|
65
|
+
for (const line of fmBlock.split('\n')) {
|
|
66
|
+
const ci = line.indexOf(':');
|
|
67
|
+
if (ci < 0)
|
|
68
|
+
continue;
|
|
69
|
+
const k = line.slice(0, ci).trim();
|
|
70
|
+
const v = line.slice(ci + 1).trim().replace(/^["']|["']$/g, '');
|
|
71
|
+
frontmatter[k] = v;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { frontmatter, body };
|
|
76
|
+
}
|
|
77
|
+
// ─── Plugin Command Loading ───────────────────────────────────────────
|
|
78
|
+
/**
|
|
79
|
+
* Load all command/skill entries from a plugin's commands/ or skills/ directory.
|
|
80
|
+
* Returns SkillInfo objects with full content.
|
|
81
|
+
*/
|
|
82
|
+
function loadPluginEntries(dirPath, pluginName, kind) {
|
|
83
|
+
if (!existsSync(dirPath))
|
|
84
|
+
return [];
|
|
85
|
+
const markdownFiles = walkMarkdownDir(dirPath, dirPath);
|
|
86
|
+
const entries = [];
|
|
87
|
+
for (const file of markdownFiles) {
|
|
88
|
+
const isSkill = basename(file.filePath).toLowerCase() === 'skill.md';
|
|
89
|
+
// Determine the entry name
|
|
90
|
+
let name;
|
|
91
|
+
if (isSkill || kind === 'skill') {
|
|
92
|
+
// For SKILL.md files, use the parent directory name
|
|
93
|
+
name = basename(file.baseDir);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// For commands/*.md files, use filename without .md
|
|
97
|
+
name = basename(file.filePath, '.md');
|
|
98
|
+
}
|
|
99
|
+
// Prepend plugin name namespace to avoid collisions
|
|
100
|
+
const fullName = `${pluginName}:${name}`;
|
|
101
|
+
// Parse frontmatter
|
|
102
|
+
const fm = file.frontmatter;
|
|
103
|
+
const description = fm.description
|
|
104
|
+
|| file.content.split('\n')[0]?.replace(/^#+\s*/, '').trim()
|
|
105
|
+
|| fullName;
|
|
106
|
+
// Parse allowed tools
|
|
107
|
+
let allowedTools;
|
|
108
|
+
const rawTools = fm['allowed-tools'] ?? fm.allowed_tools;
|
|
109
|
+
if (rawTools) {
|
|
110
|
+
allowedTools = rawTools
|
|
111
|
+
.replace(/^\[|\]$/g, '')
|
|
112
|
+
.split(',')
|
|
113
|
+
.map(t => t.trim().replace(/^["']|["']$/g, ''))
|
|
114
|
+
.filter(Boolean);
|
|
115
|
+
}
|
|
116
|
+
// Parse context
|
|
117
|
+
const context = fm.context === 'fork' ? 'fork' : fm.context === 'inline' ? 'inline' : undefined;
|
|
118
|
+
// Substitute ${CLAUDE_PLUGIN_ROOT} in content
|
|
119
|
+
let content = file.content;
|
|
120
|
+
const pluginRoot = file.baseDir.replace(/\\/g, '/');
|
|
121
|
+
content = content.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, pluginRoot);
|
|
122
|
+
content = content.replace(/\$\{CRAY_PLUGIN_ROOT\}/g, pluginRoot);
|
|
123
|
+
// Handle base directory header for skills
|
|
124
|
+
if (kind === 'skill') {
|
|
125
|
+
content = `Base directory for this skill: ${file.baseDir}\n\n${content}`;
|
|
126
|
+
}
|
|
127
|
+
entries.push({
|
|
128
|
+
name: fullName,
|
|
129
|
+
description,
|
|
130
|
+
whenToUse: fm.when_to_use ?? fm['when-to-use'],
|
|
131
|
+
content,
|
|
132
|
+
baseDir: isSkill ? file.baseDir : undefined,
|
|
133
|
+
allowedTools,
|
|
134
|
+
model: fm.model,
|
|
135
|
+
context: context,
|
|
136
|
+
source: 'plugin',
|
|
137
|
+
userInvocable: fm['user-invocable'] !== 'false',
|
|
138
|
+
disableModelInvocation: fm['disable-model-invocation'] === 'true',
|
|
139
|
+
argumentHint: fm['argument-hint'] ?? fm.argumentHint,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return entries;
|
|
143
|
+
}
|
|
144
|
+
// ─── Plugin Discovery ─────────────────────────────────────────────────
|
|
145
|
+
/**
|
|
146
|
+
* Discover a single plugin from its directory.
|
|
147
|
+
*/
|
|
148
|
+
export function discoverPlugin(dirPath) {
|
|
149
|
+
const manifestPath = join(dirPath, 'manifest.json');
|
|
150
|
+
if (!existsSync(manifestPath))
|
|
151
|
+
return null;
|
|
152
|
+
let manifest;
|
|
153
|
+
try {
|
|
154
|
+
manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
// Load skills
|
|
160
|
+
const skillsDir = join(dirPath, 'skills');
|
|
161
|
+
const skills = loadPluginEntries(skillsDir, manifest.name, 'skill');
|
|
162
|
+
// Also load skills from additional directories
|
|
163
|
+
if (manifest.additionalSkillDirs) {
|
|
164
|
+
for (const sd of manifest.additionalSkillDirs) {
|
|
165
|
+
const full = join(dirPath, sd);
|
|
166
|
+
skills.push(...loadPluginEntries(full, manifest.name, 'skill'));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Load commands
|
|
170
|
+
const commandsDir = join(dirPath, 'commands');
|
|
171
|
+
const commands = loadPluginEntries(commandsDir, manifest.name, 'command');
|
|
172
|
+
if (manifest.additionalCommandDirs) {
|
|
173
|
+
for (const cd of manifest.additionalCommandDirs) {
|
|
174
|
+
const full = join(dirPath, cd);
|
|
175
|
+
commands.push(...loadPluginEntries(full, manifest.name, 'command'));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Load MCP config
|
|
179
|
+
let mcpServers = {};
|
|
180
|
+
const mcpPath = join(dirPath, 'mcp.json');
|
|
181
|
+
if (existsSync(mcpPath)) {
|
|
182
|
+
try {
|
|
183
|
+
mcpServers = JSON.parse(readFileSync(mcpPath, 'utf-8')).servers ?? {};
|
|
184
|
+
}
|
|
185
|
+
catch { /* invalid JSON */ }
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
manifest,
|
|
189
|
+
dir: dirPath,
|
|
190
|
+
skills,
|
|
191
|
+
commands,
|
|
192
|
+
mcpServers,
|
|
193
|
+
enabled: true,
|
|
194
|
+
isEnabled() { return this.enabled; },
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Scan all known plugin directories and discover installed plugins.
|
|
199
|
+
*/
|
|
200
|
+
export function discoverAllPlugins(directories) {
|
|
201
|
+
const found = [];
|
|
202
|
+
for (const dir of directories) {
|
|
203
|
+
if (!existsSync(dir))
|
|
204
|
+
continue;
|
|
205
|
+
try {
|
|
206
|
+
for (const entry of readdirSync(dir)) {
|
|
207
|
+
const pluginDir = join(dir, entry);
|
|
208
|
+
if (!statSync(pluginDir).isDirectory())
|
|
209
|
+
continue;
|
|
210
|
+
const plugin = discoverPlugin(pluginDir);
|
|
211
|
+
if (plugin)
|
|
212
|
+
found.push(plugin);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
catch { /* dir read error */ }
|
|
216
|
+
}
|
|
217
|
+
return found;
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=loadPluginCommands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadPluginCommands.js","sourceRoot":"","sources":["../../src/services/loadPluginCommands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mcp/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/mcp/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Connection Manager for Cray Code
|
|
3
|
+
*
|
|
4
|
+
* Manages MCP server connections lifecycle:
|
|
5
|
+
* - Registration, connection, disconnection
|
|
6
|
+
* - Tool discovery and wrapping
|
|
7
|
+
* - Resource discovery
|
|
8
|
+
* - Error handling and reconnection
|
|
9
|
+
*/
|
|
10
|
+
import type { MCPServerConnection, MCPServerConfig, WrappedMCPTool } from './types.js';
|
|
11
|
+
import type { ToolDef } from '../../Tool.js';
|
|
12
|
+
/** Register an MCP server configuration */
|
|
13
|
+
export declare function registerMCPServer(config: MCPServerConfig): MCPServerConnection;
|
|
14
|
+
/** Get all registered MCP server connections */
|
|
15
|
+
export declare function getAllMCPServers(): Map<string, MCPServerConnection>;
|
|
16
|
+
/** Get all MCP-wrapped tools from all connected servers */
|
|
17
|
+
export declare function getAllMCPWrappedTools(): ToolDef<any, any>[];
|
|
18
|
+
/** Get wrapped MCP tools for a specific server */
|
|
19
|
+
export declare function getMCPToolsForServer(serverName: string): WrappedMCPTool[];
|
|
20
|
+
/** Wrap discovered MCP tools as Cray Code ToolDef instances */
|
|
21
|
+
export declare function wrapMCPTool(serverName: string, toolName: string, description: string, inputSchema: Record<string, unknown>): WrappedMCPTool;
|
|
22
|
+
/** Remove all wrapped tools for a server */
|
|
23
|
+
export declare function unwrapMCPServerTools(serverName: string): void;
|
|
24
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/services/mcp/manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEvF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAQ7C,2CAA2C;AAC3C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,mBAAmB,CAI9E;AAED,gDAAgD;AAChD,wBAAgB,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAEnE;AAED,2DAA2D;AAC3D,wBAAgB,qBAAqB,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAM3D;AAED,kDAAkD;AAClD,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE,CAEzE;AAwGD,+DAA+D;AAC/D,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,cAAc,CAQhB;AAED,4CAA4C;AAC5C,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAE7D"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Connection Manager for Cray Code
|
|
3
|
+
*
|
|
4
|
+
* Manages MCP server connections lifecycle:
|
|
5
|
+
* - Registration, connection, disconnection
|
|
6
|
+
* - Tool discovery and wrapping
|
|
7
|
+
* - Resource discovery
|
|
8
|
+
* - Error handling and reconnection
|
|
9
|
+
*/
|
|
10
|
+
import { createMCPTool } from '../../tools/MCPTool.js';
|
|
11
|
+
/** Global MCP server registry */
|
|
12
|
+
const mcpServers = new Map();
|
|
13
|
+
const mcpWrappedTools = new Map();
|
|
14
|
+
// ─── Server Registration ────────────────────────────────────────────────
|
|
15
|
+
/** Register an MCP server configuration */
|
|
16
|
+
export function registerMCPServer(config) {
|
|
17
|
+
const connection = createServerConnection(config);
|
|
18
|
+
mcpServers.set(config.name, connection);
|
|
19
|
+
return connection;
|
|
20
|
+
}
|
|
21
|
+
/** Get all registered MCP server connections */
|
|
22
|
+
export function getAllMCPServers() {
|
|
23
|
+
return mcpServers;
|
|
24
|
+
}
|
|
25
|
+
/** Get all MCP-wrapped tools from all connected servers */
|
|
26
|
+
export function getAllMCPWrappedTools() {
|
|
27
|
+
const allTools = [];
|
|
28
|
+
for (const tools of mcpWrappedTools.values()) {
|
|
29
|
+
allTools.push(...tools);
|
|
30
|
+
}
|
|
31
|
+
return allTools;
|
|
32
|
+
}
|
|
33
|
+
/** Get wrapped MCP tools for a specific server */
|
|
34
|
+
export function getMCPToolsForServer(serverName) {
|
|
35
|
+
return mcpWrappedTools.get(serverName) ?? [];
|
|
36
|
+
}
|
|
37
|
+
// ─── Connection Factory ─────────────────────────────────────────────────
|
|
38
|
+
function createServerConnection(config) {
|
|
39
|
+
const tools = [];
|
|
40
|
+
const resources = [];
|
|
41
|
+
let state = 'disconnected';
|
|
42
|
+
let error;
|
|
43
|
+
let processHandle = null;
|
|
44
|
+
const connection = {
|
|
45
|
+
name: config.name,
|
|
46
|
+
config,
|
|
47
|
+
get state() { return state; },
|
|
48
|
+
get connected() { return state === 'connected'; },
|
|
49
|
+
tools,
|
|
50
|
+
resources,
|
|
51
|
+
get error() { return error; },
|
|
52
|
+
async connect() {
|
|
53
|
+
if (state === 'connected' || state === 'connecting')
|
|
54
|
+
return;
|
|
55
|
+
state = 'connecting';
|
|
56
|
+
error = undefined;
|
|
57
|
+
try {
|
|
58
|
+
if (config.transport === 'stdio' && config.command) {
|
|
59
|
+
// Stdio transport: spawn the MCP server process
|
|
60
|
+
const { spawn } = await import('child_process');
|
|
61
|
+
processHandle = spawn(config.command, config.args ?? [], {
|
|
62
|
+
env: { ...process.env, ...config.env },
|
|
63
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
64
|
+
});
|
|
65
|
+
processHandle.on('exit', (code) => {
|
|
66
|
+
state = 'disconnected';
|
|
67
|
+
error = `Process exited with code ${code}`;
|
|
68
|
+
});
|
|
69
|
+
processHandle.on('error', (err) => {
|
|
70
|
+
state = 'failed';
|
|
71
|
+
error = err.message;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else if (config.transport === 'sse' && config.url) {
|
|
75
|
+
// SSE transport: connect via HTTP
|
|
76
|
+
// For now, just mark as connected (full SSE implemention requires framework)
|
|
77
|
+
// In production, use @modelcontextprotocol/sdk SSE transport
|
|
78
|
+
}
|
|
79
|
+
state = 'connected';
|
|
80
|
+
// Discover tools
|
|
81
|
+
try {
|
|
82
|
+
await this.listTools();
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Tool discovery failed, server may still be usable
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
state = 'failed';
|
|
90
|
+
error = err.message;
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
async disconnect() {
|
|
94
|
+
if (processHandle) {
|
|
95
|
+
processHandle.kill();
|
|
96
|
+
processHandle = null;
|
|
97
|
+
}
|
|
98
|
+
state = 'disconnected';
|
|
99
|
+
mcpWrappedTools.delete(config.name);
|
|
100
|
+
},
|
|
101
|
+
async listTools() {
|
|
102
|
+
// In production, this would call tools/list on the MCP server
|
|
103
|
+
// For the framework, we return tools that were configured
|
|
104
|
+
return tools;
|
|
105
|
+
},
|
|
106
|
+
async listResources() {
|
|
107
|
+
return resources;
|
|
108
|
+
},
|
|
109
|
+
async callTool(toolName, args) {
|
|
110
|
+
if (!processHandle && config.transport === 'stdio') {
|
|
111
|
+
throw new Error(`Server "${config.name}" has no active process`);
|
|
112
|
+
}
|
|
113
|
+
// In production, this would send a tools/call JSON-RPC message
|
|
114
|
+
// For the framework, return structured output
|
|
115
|
+
return JSON.stringify({
|
|
116
|
+
server: config.name,
|
|
117
|
+
tool: toolName,
|
|
118
|
+
args,
|
|
119
|
+
result: 'MCP tool execution placeholder - implement MCP SDK integration',
|
|
120
|
+
}, null, 2);
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
return connection;
|
|
124
|
+
}
|
|
125
|
+
// ─── Tool Wrapping ──────────────────────────────────────────────────────
|
|
126
|
+
/** Wrap discovered MCP tools as Cray Code ToolDef instances */
|
|
127
|
+
export function wrapMCPTool(serverName, toolName, description, inputSchema) {
|
|
128
|
+
const wrapped = createMCPTool(serverName, toolName, description, inputSchema);
|
|
129
|
+
const existing = mcpWrappedTools.get(serverName) ?? [];
|
|
130
|
+
existing.push(wrapped);
|
|
131
|
+
mcpWrappedTools.set(serverName, existing);
|
|
132
|
+
return wrapped;
|
|
133
|
+
}
|
|
134
|
+
/** Remove all wrapped tools for a server */
|
|
135
|
+
export function unwrapMCPServerTools(serverName) {
|
|
136
|
+
mcpWrappedTools.delete(serverName);
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/services/mcp/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP type definitions for Cray Code.
|
|
3
|
+
*/
|
|
4
|
+
import type { ToolDef } from '../../Tool.js';
|
|
5
|
+
export type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'failed' | 'needs_config';
|
|
6
|
+
export interface MCPServerConfig {
|
|
7
|
+
name: string;
|
|
8
|
+
transport: 'stdio' | 'sse' | 'websocket' | 'http';
|
|
9
|
+
command?: string;
|
|
10
|
+
args?: string[];
|
|
11
|
+
url?: string;
|
|
12
|
+
env?: Record<string, string>;
|
|
13
|
+
headers?: Record<string, string>;
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface MCPServerConnection {
|
|
17
|
+
name: string;
|
|
18
|
+
config: MCPServerConfig;
|
|
19
|
+
state: ConnectionState;
|
|
20
|
+
connected: boolean;
|
|
21
|
+
tools: MCPToolInfo[];
|
|
22
|
+
resources: MCPResourceInfo[];
|
|
23
|
+
error?: string;
|
|
24
|
+
/** Call a tool on this MCP server */
|
|
25
|
+
callTool(name: string, args: Record<string, unknown>): Promise<string>;
|
|
26
|
+
/** List available tools */
|
|
27
|
+
listTools(): Promise<MCPToolInfo[]>;
|
|
28
|
+
/** List available resources */
|
|
29
|
+
listResources(): Promise<MCPResourceInfo[]>;
|
|
30
|
+
/** Connect to the server */
|
|
31
|
+
connect(): Promise<void>;
|
|
32
|
+
/** Disconnect from the server */
|
|
33
|
+
disconnect(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export interface MCPToolInfo {
|
|
36
|
+
name: string;
|
|
37
|
+
description: string;
|
|
38
|
+
inputSchema: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
export interface MCPResourceInfo {
|
|
41
|
+
uri: string;
|
|
42
|
+
name: string;
|
|
43
|
+
description?: string;
|
|
44
|
+
mimeType?: string;
|
|
45
|
+
}
|
|
46
|
+
export type WrappedMCPTool = ToolDef<any, string> & {
|
|
47
|
+
mcpInfo: {
|
|
48
|
+
serverName: string;
|
|
49
|
+
toolName: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/mcp/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,YAAY,GACZ,WAAW,GACX,QAAQ,GACR,cAAc,CAAC;AAEnB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,GAAG,KAAK,GAAG,WAAW,GAAG,MAAM,CAAC;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEvE,2BAA2B;IAC3B,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAEpC,+BAA+B;IAC/B,aAAa,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAE5C,4BAA4B;IAC5B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB,iCAAiC;IACjC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG;IAClD,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/services/mcp/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory System for Cray Code.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors Claude Code's memory/ directory design.
|
|
5
|
+
* Persistent memory stored as markdown files in .cray/memory/:
|
|
6
|
+
* user/ — user preferences, role, knowledge
|
|
7
|
+
* project/ — project decisions, constraints, ongoing work
|
|
8
|
+
* feedback/ — user corrections, confirmed approaches
|
|
9
|
+
* reference/ — pointers to external resources (docs, dashboards, etc.)
|
|
10
|
+
*
|
|
11
|
+
* Memories are auto-injected into the system prompt on each turn.
|
|
12
|
+
*/
|
|
13
|
+
export type MemoryType = 'user' | 'project' | 'feedback' | 'reference';
|
|
14
|
+
export interface MemoryEntry {
|
|
15
|
+
type: MemoryType;
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
content: string;
|
|
19
|
+
path: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function getMemoryDirectories(projectRoot?: string): string[];
|
|
22
|
+
export declare function loadAllMemories(projectRoot?: string): MemoryEntry[];
|
|
23
|
+
/** Build the memory prompt block injected into system prompt */
|
|
24
|
+
export declare function buildMemoryPrompt(projectRoot?: string): string;
|
|
25
|
+
/** Build a single memory entry' full content for tool display */
|
|
26
|
+
export declare function buildMemoryContentPrompt(projectRoot?: string): string;
|
|
27
|
+
export declare function saveMemory(type: MemoryType, name: string, description: string, content: string, projectRoot?: string): {
|
|
28
|
+
success: boolean;
|
|
29
|
+
message: string;
|
|
30
|
+
path: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function deleteMemory(type: MemoryType, name: string, projectRoot?: string): {
|
|
33
|
+
success: boolean;
|
|
34
|
+
message: string;
|
|
35
|
+
};
|
|
36
|
+
export declare function listMemories(projectRoot?: string): MemoryEntry[];
|
|
37
|
+
export declare function getMemoryInjectionHint(): string;
|
|
38
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/services/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAEvE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAID,wBAAgB,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAcnE;AAQD,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAuBnE;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CA+B9D;AAED,iEAAiE;AACjE,wBAAgB,wBAAwB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAWrE;AAID,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GACnB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAuBrD;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAUvC;AAED,wBAAgB,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAEhE;AAID,wBAAgB,sBAAsB,IAAI,MAAM,CAQ/C"}
|