@contractspec/lib.ai-agent 1.45.5 → 1.46.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 (77) hide show
  1. package/dist/_virtual/rolldown_runtime.js +8 -0
  2. package/dist/agent/index.d.ts +2 -2
  3. package/dist/agent/index.js +2 -2
  4. package/dist/agent/unified-agent.d.ts +131 -0
  5. package/dist/agent/unified-agent.d.ts.map +1 -0
  6. package/dist/agent/unified-agent.js +267 -0
  7. package/dist/agent/unified-agent.js.map +1 -0
  8. package/dist/exporters/claude-agent-exporter.d.ts +64 -0
  9. package/dist/exporters/claude-agent-exporter.d.ts.map +1 -0
  10. package/dist/exporters/claude-agent-exporter.js +210 -0
  11. package/dist/exporters/claude-agent-exporter.js.map +1 -0
  12. package/dist/exporters/index.d.ts +4 -0
  13. package/dist/exporters/index.js +4 -0
  14. package/dist/exporters/opencode-exporter.d.ts +64 -0
  15. package/dist/exporters/opencode-exporter.d.ts.map +1 -0
  16. package/dist/exporters/opencode-exporter.js +200 -0
  17. package/dist/exporters/opencode-exporter.js.map +1 -0
  18. package/dist/exporters/types.d.ts +239 -0
  19. package/dist/exporters/types.d.ts.map +1 -0
  20. package/dist/exporters/types.js +0 -0
  21. package/dist/index.d.ts +16 -3
  22. package/dist/index.js +11 -2
  23. package/dist/interop/index.d.ts +4 -0
  24. package/dist/interop/index.js +4 -0
  25. package/dist/interop/spec-consumer.d.ts +81 -0
  26. package/dist/interop/spec-consumer.d.ts.map +1 -0
  27. package/dist/interop/spec-consumer.js +287 -0
  28. package/dist/interop/spec-consumer.js.map +1 -0
  29. package/dist/interop/tool-consumer.d.ts +68 -0
  30. package/dist/interop/tool-consumer.d.ts.map +1 -0
  31. package/dist/interop/tool-consumer.js +220 -0
  32. package/dist/interop/tool-consumer.js.map +1 -0
  33. package/dist/interop/types.d.ts +262 -0
  34. package/dist/interop/types.d.ts.map +1 -0
  35. package/dist/interop/types.js +0 -0
  36. package/dist/providers/claude-agent-sdk/adapter.d.ts +58 -0
  37. package/dist/providers/claude-agent-sdk/adapter.d.ts.map +1 -0
  38. package/dist/providers/claude-agent-sdk/adapter.js +306 -0
  39. package/dist/providers/claude-agent-sdk/adapter.js.map +1 -0
  40. package/dist/providers/claude-agent-sdk/index.d.ts +4 -0
  41. package/dist/providers/claude-agent-sdk/index.js +5 -0
  42. package/dist/providers/claude-agent-sdk/session-bridge.d.ts +101 -0
  43. package/dist/providers/claude-agent-sdk/session-bridge.d.ts.map +1 -0
  44. package/dist/providers/claude-agent-sdk/session-bridge.js +158 -0
  45. package/dist/providers/claude-agent-sdk/session-bridge.js.map +1 -0
  46. package/dist/providers/claude-agent-sdk/tool-bridge.d.ts +110 -0
  47. package/dist/providers/claude-agent-sdk/tool-bridge.d.ts.map +1 -0
  48. package/dist/providers/claude-agent-sdk/tool-bridge.js +122 -0
  49. package/dist/providers/claude-agent-sdk/tool-bridge.js.map +1 -0
  50. package/dist/providers/index.d.ts +7 -0
  51. package/dist/providers/index.js +8 -0
  52. package/dist/providers/opencode-sdk/adapter.d.ts +54 -0
  53. package/dist/providers/opencode-sdk/adapter.d.ts.map +1 -0
  54. package/dist/providers/opencode-sdk/adapter.js +276 -0
  55. package/dist/providers/opencode-sdk/adapter.js.map +1 -0
  56. package/dist/providers/opencode-sdk/agent-bridge.d.ts +94 -0
  57. package/dist/providers/opencode-sdk/agent-bridge.d.ts.map +1 -0
  58. package/dist/providers/opencode-sdk/agent-bridge.js +165 -0
  59. package/dist/providers/opencode-sdk/agent-bridge.js.map +1 -0
  60. package/dist/providers/opencode-sdk/index.d.ts +4 -0
  61. package/dist/providers/opencode-sdk/index.js +5 -0
  62. package/dist/providers/opencode-sdk/tool-bridge.d.ts +81 -0
  63. package/dist/providers/opencode-sdk/tool-bridge.d.ts.map +1 -0
  64. package/dist/providers/opencode-sdk/tool-bridge.js +127 -0
  65. package/dist/providers/opencode-sdk/tool-bridge.js.map +1 -0
  66. package/dist/providers/registry.d.ts +22 -0
  67. package/dist/providers/registry.d.ts.map +1 -0
  68. package/dist/providers/registry.js +52 -0
  69. package/dist/providers/registry.js.map +1 -0
  70. package/dist/providers/types.d.ts +243 -0
  71. package/dist/providers/types.d.ts.map +1 -0
  72. package/dist/providers/types.js +44 -0
  73. package/dist/providers/types.js.map +1 -0
  74. package/dist/tools/index.d.ts +1 -1
  75. package/dist/types.d.ts +1 -1
  76. package/dist/types.d.ts.map +1 -1
  77. package/package.json +37 -5
@@ -0,0 +1,210 @@
1
+ import { agentKey } from "../spec/spec.js";
2
+
3
+ //#region src/exporters/claude-agent-exporter.ts
4
+ /**
5
+ * Claude Agent SDK Exporter.
6
+ */
7
+ var ClaudeAgentExporter = class {
8
+ format = "claude-agent";
9
+ /**
10
+ * Export an AgentSpec to Claude Agent SDK format.
11
+ */
12
+ export(spec, options = {}) {
13
+ const tools = this.exportTools(spec);
14
+ return {
15
+ config: this.buildConfig(spec, tools, options),
16
+ claudeMd: options.generateClaudeMd ? this.generateClaudeMd(spec, options) : void 0,
17
+ tools,
18
+ exportedAt: /* @__PURE__ */ new Date(),
19
+ sourceSpec: agentKey(spec.meta)
20
+ };
21
+ }
22
+ /**
23
+ * Export multiple specs.
24
+ */
25
+ exportMany(specs, options = {}) {
26
+ return specs.map((spec) => this.export(spec, options));
27
+ }
28
+ /**
29
+ * Validate that a spec can be exported.
30
+ */
31
+ validate(spec) {
32
+ const errors = [];
33
+ if (!spec.meta?.key) errors.push("Spec must have a meta.key");
34
+ if (!spec.instructions) errors.push("Spec must have instructions");
35
+ if (!spec.tools || spec.tools.length === 0) errors.push("Spec must have at least one tool");
36
+ for (const tool of spec.tools ?? []) {
37
+ if (!tool.name) errors.push("All tools must have a name");
38
+ if (!tool.description && !tool.name) errors.push(`Tool must have a description or name`);
39
+ }
40
+ return {
41
+ valid: errors.length === 0,
42
+ errors
43
+ };
44
+ }
45
+ /**
46
+ * Build Claude Agent SDK configuration.
47
+ */
48
+ buildConfig(spec, tools, options) {
49
+ const config = {
50
+ model: options.model ?? "claude-sonnet-4-20250514",
51
+ system: this.buildSystemPrompt(spec, options),
52
+ tools,
53
+ max_turns: spec.maxSteps ?? 10
54
+ };
55
+ if (options.computerUse) config.computer_use = true;
56
+ if (options.extendedThinking) config.extended_thinking = true;
57
+ if (options.mcpServers && options.mcpServers.length > 0) config.mcp_servers = options.mcpServers;
58
+ return config;
59
+ }
60
+ /**
61
+ * Build system prompt from spec.
62
+ */
63
+ buildSystemPrompt(spec, options) {
64
+ const parts = [];
65
+ parts.push(spec.instructions);
66
+ if (spec.knowledge && spec.knowledge.length > 0) {
67
+ parts.push("");
68
+ parts.push("## Knowledge Sources");
69
+ for (const k of spec.knowledge) if (k.instructions) parts.push(`- ${k.key}: ${k.instructions}`);
70
+ }
71
+ if (spec.policy) {
72
+ parts.push("");
73
+ parts.push("## Policy");
74
+ if (spec.policy.confidence?.min) parts.push(`- Minimum confidence: ${spec.policy.confidence.min}`);
75
+ if (spec.policy.escalation) parts.push("- Escalation policy is configured");
76
+ }
77
+ if (options.metadata) {
78
+ parts.push("");
79
+ parts.push("## Additional Context");
80
+ for (const [key, value] of Object.entries(options.metadata)) parts.push(`- ${key}: ${String(value)}`);
81
+ }
82
+ return parts.join("\n");
83
+ }
84
+ /**
85
+ * Export tools to Claude Agent SDK format.
86
+ */
87
+ exportTools(spec) {
88
+ return spec.tools.map((tool) => ({
89
+ name: tool.name,
90
+ description: tool.description ?? `Execute ${tool.name}`,
91
+ input_schema: this.normalizeSchema(tool.schema),
92
+ requires_confirmation: tool.requiresApproval ?? !tool.automationSafe
93
+ }));
94
+ }
95
+ /**
96
+ * Normalize schema to Claude Agent SDK format.
97
+ */
98
+ normalizeSchema(schema) {
99
+ if (!schema) return { type: "object" };
100
+ if (schema.type === "object") return {
101
+ type: "object",
102
+ properties: schema.properties,
103
+ required: schema.required
104
+ };
105
+ return {
106
+ type: "object",
107
+ properties: { value: schema },
108
+ required: ["value"]
109
+ };
110
+ }
111
+ /**
112
+ * Generate CLAUDE.md content for Claude Code CLI integration.
113
+ */
114
+ generateClaudeMd(spec, options) {
115
+ const lines = [];
116
+ lines.push("# Agent Configuration");
117
+ lines.push("");
118
+ if (spec.description) {
119
+ lines.push(`> ${spec.description}`);
120
+ lines.push("");
121
+ }
122
+ lines.push("## Metadata");
123
+ lines.push("");
124
+ lines.push(`- **Name**: ${spec.meta.key}`);
125
+ lines.push(`- **Version**: ${spec.meta.version}`);
126
+ if (spec.meta.owners && spec.meta.owners.length > 0) lines.push(`- **Owners**: ${spec.meta.owners.join(", ")}`);
127
+ if (options.model) lines.push(`- **Model**: ${options.model}`);
128
+ lines.push("");
129
+ lines.push("## Instructions");
130
+ lines.push("");
131
+ lines.push(spec.instructions);
132
+ lines.push("");
133
+ if (spec.tools.length > 0) {
134
+ lines.push("## Available Tools");
135
+ lines.push("");
136
+ for (const tool of spec.tools) {
137
+ const flags = [];
138
+ if (tool.requiresApproval) flags.push("requires approval");
139
+ if (tool.automationSafe === false) flags.push("not automation safe");
140
+ const flagStr = flags.length > 0 ? ` (${flags.join(", ")})` : "";
141
+ lines.push(`### ${tool.name}${flagStr}`);
142
+ lines.push("");
143
+ if (tool.description) {
144
+ lines.push(tool.description);
145
+ lines.push("");
146
+ }
147
+ if (tool.schema) {
148
+ lines.push("**Parameters:**");
149
+ lines.push("```json");
150
+ lines.push(JSON.stringify(tool.schema, null, 2));
151
+ lines.push("```");
152
+ lines.push("");
153
+ }
154
+ }
155
+ }
156
+ if (spec.knowledge && spec.knowledge.length > 0) {
157
+ lines.push("## Knowledge Sources");
158
+ lines.push("");
159
+ for (const k of spec.knowledge) {
160
+ const required = k.required ? "(required)" : "(optional)";
161
+ lines.push(`- **${k.key}** ${required}`);
162
+ if (k.instructions) lines.push(` - ${k.instructions}`);
163
+ }
164
+ lines.push("");
165
+ }
166
+ if (spec.policy) {
167
+ lines.push("## Policy");
168
+ lines.push("");
169
+ if (spec.policy.confidence?.min) lines.push(`- Minimum confidence: ${spec.policy.confidence.min}`);
170
+ if (spec.policy.escalation) lines.push("- Escalation policy configured");
171
+ if (spec.policy.flags && spec.policy.flags.length > 0) lines.push(`- Feature flags: ${spec.policy.flags.join(", ")}`);
172
+ lines.push("");
173
+ }
174
+ if (options.mcpServers && options.mcpServers.length > 0) {
175
+ lines.push("## MCP Servers");
176
+ lines.push("");
177
+ for (const server of options.mcpServers) lines.push(`- **${server.name}**: \`${server.command}${server.args ? " " + server.args.join(" ") : ""}\``);
178
+ lines.push("");
179
+ }
180
+ lines.push("---");
181
+ lines.push("");
182
+ lines.push(`*Generated from ContractSpec: ${agentKey(spec.meta)}*`);
183
+ return lines.join("\n");
184
+ }
185
+ };
186
+ /**
187
+ * Export an AgentSpec to Claude Agent SDK format.
188
+ */
189
+ function exportToClaudeAgent(spec, options) {
190
+ return new ClaudeAgentExporter().export(spec, options);
191
+ }
192
+ /**
193
+ * Generate CLAUDE.md content from an AgentSpec.
194
+ */
195
+ function generateClaudeMd(spec, options) {
196
+ return new ClaudeAgentExporter().export(spec, {
197
+ ...options,
198
+ generateClaudeMd: true
199
+ }).claudeMd ?? "";
200
+ }
201
+ /**
202
+ * Validate an AgentSpec for Claude Agent SDK export.
203
+ */
204
+ function validateForClaudeAgent(spec) {
205
+ return new ClaudeAgentExporter().validate(spec);
206
+ }
207
+
208
+ //#endregion
209
+ export { ClaudeAgentExporter, exportToClaudeAgent, generateClaudeMd, validateForClaudeAgent };
210
+ //# sourceMappingURL=claude-agent-exporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-agent-exporter.js","names":["errors: string[]","config: ClaudeAgentConfig","parts: string[]","lines: string[]","flags: string[]"],"sources":["../../src/exporters/claude-agent-exporter.ts"],"sourcesContent":["/**\n * Claude Agent SDK Exporter\n *\n * Exports ContractSpec AgentSpec definitions to formats compatible with\n * @anthropic-ai/claude-agent-sdk and Claude Code CLI.\n */\n\nimport type { AgentSpec } from '../spec/spec';\nimport { agentKey } from '../spec/spec';\nimport type {\n Exporter,\n ClaudeAgentExportOptions,\n ClaudeAgentExportResult,\n ClaudeAgentConfig,\n ClaudeToolDefinition,\n} from './types';\n\n// ============================================================================\n// Exporter Implementation\n// ============================================================================\n\n/**\n * Claude Agent SDK Exporter.\n */\nexport class ClaudeAgentExporter implements Exporter<\n ClaudeAgentExportOptions,\n ClaudeAgentExportResult\n> {\n readonly format = 'claude-agent' as const;\n\n /**\n * Export an AgentSpec to Claude Agent SDK format.\n */\n export(\n spec: AgentSpec,\n options: ClaudeAgentExportOptions = {}\n ): ClaudeAgentExportResult {\n const tools = this.exportTools(spec);\n const config = this.buildConfig(spec, tools, options);\n const claudeMd = options.generateClaudeMd\n ? this.generateClaudeMd(spec, options)\n : undefined;\n\n return {\n config,\n claudeMd,\n tools,\n exportedAt: new Date(),\n sourceSpec: agentKey(spec.meta),\n };\n }\n\n /**\n * Export multiple specs.\n */\n exportMany(\n specs: AgentSpec[],\n options: ClaudeAgentExportOptions = {}\n ): ClaudeAgentExportResult[] {\n return specs.map((spec) => this.export(spec, options));\n }\n\n /**\n * Validate that a spec can be exported.\n */\n validate(spec: AgentSpec): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n if (!spec.meta?.key) {\n errors.push('Spec must have a meta.key');\n }\n\n if (!spec.instructions) {\n errors.push('Spec must have instructions');\n }\n\n if (!spec.tools || spec.tools.length === 0) {\n errors.push('Spec must have at least one tool');\n }\n\n for (const tool of spec.tools ?? []) {\n if (!tool.name) {\n errors.push('All tools must have a name');\n }\n if (!tool.description && !tool.name) {\n errors.push(`Tool must have a description or name`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Build Claude Agent SDK configuration.\n */\n private buildConfig(\n spec: AgentSpec,\n tools: ClaudeToolDefinition[],\n options: ClaudeAgentExportOptions\n ): ClaudeAgentConfig {\n const config: ClaudeAgentConfig = {\n model: options.model ?? 'claude-sonnet-4-20250514',\n system: this.buildSystemPrompt(spec, options),\n tools,\n max_turns: spec.maxSteps ?? 10,\n };\n\n if (options.computerUse) {\n config.computer_use = true;\n }\n\n if (options.extendedThinking) {\n config.extended_thinking = true;\n }\n\n if (options.mcpServers && options.mcpServers.length > 0) {\n config.mcp_servers = options.mcpServers;\n }\n\n return config;\n }\n\n /**\n * Build system prompt from spec.\n */\n private buildSystemPrompt(\n spec: AgentSpec,\n options: ClaudeAgentExportOptions\n ): string {\n const parts: string[] = [];\n\n // Base instructions\n parts.push(spec.instructions);\n\n // Add knowledge context if available\n if (spec.knowledge && spec.knowledge.length > 0) {\n parts.push('');\n parts.push('## Knowledge Sources');\n for (const k of spec.knowledge) {\n if (k.instructions) {\n parts.push(`- ${k.key}: ${k.instructions}`);\n }\n }\n }\n\n // Add policy information if available\n if (spec.policy) {\n parts.push('');\n parts.push('## Policy');\n if (spec.policy.confidence?.min) {\n parts.push(`- Minimum confidence: ${spec.policy.confidence.min}`);\n }\n if (spec.policy.escalation) {\n parts.push('- Escalation policy is configured');\n }\n }\n\n // Add custom metadata if provided\n if (options.metadata) {\n parts.push('');\n parts.push('## Additional Context');\n for (const [key, value] of Object.entries(options.metadata)) {\n parts.push(`- ${key}: ${String(value)}`);\n }\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Export tools to Claude Agent SDK format.\n */\n private exportTools(spec: AgentSpec): ClaudeToolDefinition[] {\n return spec.tools.map((tool) => ({\n name: tool.name,\n description: tool.description ?? `Execute ${tool.name}`,\n input_schema: this.normalizeSchema(tool.schema),\n requires_confirmation: tool.requiresApproval ?? !tool.automationSafe,\n }));\n }\n\n /**\n * Normalize schema to Claude Agent SDK format.\n */\n private normalizeSchema(\n schema?: Record<string, unknown>\n ): ClaudeToolDefinition['input_schema'] {\n if (!schema) {\n return { type: 'object' };\n }\n\n if (schema.type === 'object') {\n return {\n type: 'object',\n properties: schema.properties as Record<string, unknown> | undefined,\n required: schema.required as string[] | undefined,\n };\n }\n\n // Wrap non-object schemas\n return {\n type: 'object',\n properties: { value: schema },\n required: ['value'],\n };\n }\n\n /**\n * Generate CLAUDE.md content for Claude Code CLI integration.\n */\n private generateClaudeMd(\n spec: AgentSpec,\n options: ClaudeAgentExportOptions\n ): string {\n const lines: string[] = [];\n\n // Header\n lines.push('# Agent Configuration');\n lines.push('');\n\n // Description\n if (spec.description) {\n lines.push(`> ${spec.description}`);\n lines.push('');\n }\n\n // Metadata\n lines.push('## Metadata');\n lines.push('');\n lines.push(`- **Name**: ${spec.meta.key}`);\n lines.push(`- **Version**: ${spec.meta.version}`);\n if (spec.meta.owners && spec.meta.owners.length > 0) {\n lines.push(`- **Owners**: ${spec.meta.owners.join(', ')}`);\n }\n if (options.model) {\n lines.push(`- **Model**: ${options.model}`);\n }\n lines.push('');\n\n // Instructions\n lines.push('## Instructions');\n lines.push('');\n lines.push(spec.instructions);\n lines.push('');\n\n // Tools\n if (spec.tools.length > 0) {\n lines.push('## Available Tools');\n lines.push('');\n for (const tool of spec.tools) {\n const flags: string[] = [];\n if (tool.requiresApproval) {\n flags.push('requires approval');\n }\n if (tool.automationSafe === false) {\n flags.push('not automation safe');\n }\n const flagStr = flags.length > 0 ? ` (${flags.join(', ')})` : '';\n\n lines.push(`### ${tool.name}${flagStr}`);\n lines.push('');\n if (tool.description) {\n lines.push(tool.description);\n lines.push('');\n }\n if (tool.schema) {\n lines.push('**Parameters:**');\n lines.push('```json');\n lines.push(JSON.stringify(tool.schema, null, 2));\n lines.push('```');\n lines.push('');\n }\n }\n }\n\n // Knowledge\n if (spec.knowledge && spec.knowledge.length > 0) {\n lines.push('## Knowledge Sources');\n lines.push('');\n for (const k of spec.knowledge) {\n const required = k.required ? '(required)' : '(optional)';\n lines.push(`- **${k.key}** ${required}`);\n if (k.instructions) {\n lines.push(` - ${k.instructions}`);\n }\n }\n lines.push('');\n }\n\n // Policy\n if (spec.policy) {\n lines.push('## Policy');\n lines.push('');\n if (spec.policy.confidence?.min) {\n lines.push(`- Minimum confidence: ${spec.policy.confidence.min}`);\n }\n if (spec.policy.escalation) {\n lines.push('- Escalation policy configured');\n }\n if (spec.policy.flags && spec.policy.flags.length > 0) {\n lines.push(`- Feature flags: ${spec.policy.flags.join(', ')}`);\n }\n lines.push('');\n }\n\n // MCP Servers\n if (options.mcpServers && options.mcpServers.length > 0) {\n lines.push('## MCP Servers');\n lines.push('');\n for (const server of options.mcpServers) {\n lines.push(\n `- **${server.name}**: \\`${server.command}${server.args ? ' ' + server.args.join(' ') : ''}\\``\n );\n }\n lines.push('');\n }\n\n // Footer\n lines.push('---');\n lines.push('');\n lines.push(`*Generated from ContractSpec: ${agentKey(spec.meta)}*`);\n\n return lines.join('\\n');\n }\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Export an AgentSpec to Claude Agent SDK format.\n */\nexport function exportToClaudeAgent(\n spec: AgentSpec,\n options?: ClaudeAgentExportOptions\n): ClaudeAgentExportResult {\n const exporter = new ClaudeAgentExporter();\n return exporter.export(spec, options);\n}\n\n/**\n * Generate CLAUDE.md content from an AgentSpec.\n */\nexport function generateClaudeMd(\n spec: AgentSpec,\n options?: Omit<ClaudeAgentExportOptions, 'generateClaudeMd'>\n): string {\n const exporter = new ClaudeAgentExporter();\n const result = exporter.export(spec, { ...options, generateClaudeMd: true });\n return result.claudeMd ?? '';\n}\n\n/**\n * Validate an AgentSpec for Claude Agent SDK export.\n */\nexport function validateForClaudeAgent(spec: AgentSpec): {\n valid: boolean;\n errors: string[];\n} {\n const exporter = new ClaudeAgentExporter();\n return exporter.validate(spec);\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { ClaudeAgentConfig, ClaudeAgentExportOptions, ClaudeAgentExportResult, ClaudeToolDefinition, ExportFormat, ExportOptions, Exporter, MCPExportOptions, MCPExportResult, MCPPromptDefinition, MCPResourceDefinition, MCPServerDefinition, MCPToolDefinition, OpenCodeAgentJSON, OpenCodeExportOptions, OpenCodeExportResult, OpenCodeToolJSON } from "./types.js";
2
+ import { ClaudeAgentExporter, exportToClaudeAgent, generateClaudeMd, validateForClaudeAgent } from "./claude-agent-exporter.js";
3
+ import { OpenCodeExporter, exportToOpenCode, generateOpenCodeJSON, generateOpenCodeMarkdown, validateForOpenCode } from "./opencode-exporter.js";
4
+ export { ClaudeAgentConfig, ClaudeAgentExportOptions, ClaudeAgentExportResult, ClaudeAgentExporter, ClaudeToolDefinition, ExportFormat, ExportOptions, Exporter, MCPExportOptions, MCPExportResult, MCPPromptDefinition, MCPResourceDefinition, MCPServerDefinition, MCPToolDefinition, OpenCodeAgentJSON, OpenCodeExportOptions, OpenCodeExportResult, OpenCodeExporter, OpenCodeToolJSON, exportToClaudeAgent, exportToOpenCode, generateClaudeMd, generateOpenCodeJSON, generateOpenCodeMarkdown, validateForClaudeAgent, validateForOpenCode };
@@ -0,0 +1,4 @@
1
+ import { ClaudeAgentExporter, exportToClaudeAgent, generateClaudeMd, validateForClaudeAgent } from "./claude-agent-exporter.js";
2
+ import { OpenCodeExporter, exportToOpenCode, generateOpenCodeJSON, generateOpenCodeMarkdown, validateForOpenCode } from "./opencode-exporter.js";
3
+
4
+ export { ClaudeAgentExporter, OpenCodeExporter, exportToClaudeAgent, exportToOpenCode, generateClaudeMd, generateOpenCodeJSON, generateOpenCodeMarkdown, validateForClaudeAgent, validateForOpenCode };
@@ -0,0 +1,64 @@
1
+ import { AgentSpec } from "../spec/spec.js";
2
+ import { Exporter, OpenCodeAgentJSON, OpenCodeExportOptions, OpenCodeExportResult } from "./types.js";
3
+
4
+ //#region src/exporters/opencode-exporter.d.ts
5
+
6
+ /**
7
+ * OpenCode SDK Exporter.
8
+ */
9
+ declare class OpenCodeExporter implements Exporter<OpenCodeExportOptions, OpenCodeExportResult> {
10
+ readonly format: "opencode";
11
+ /**
12
+ * Export an AgentSpec to OpenCode SDK format.
13
+ */
14
+ export(spec: AgentSpec, options?: OpenCodeExportOptions): OpenCodeExportResult;
15
+ /**
16
+ * Export multiple specs.
17
+ */
18
+ exportMany(specs: AgentSpec[], options?: OpenCodeExportOptions): OpenCodeExportResult[];
19
+ /**
20
+ * Validate that a spec can be exported.
21
+ */
22
+ validate(spec: AgentSpec): {
23
+ valid: boolean;
24
+ errors: string[];
25
+ };
26
+ /**
27
+ * Build OpenCode agent JSON configuration.
28
+ */
29
+ private buildJsonConfig;
30
+ /**
31
+ * Export tools to OpenCode format.
32
+ */
33
+ private exportTools;
34
+ /**
35
+ * Generate markdown agent file content.
36
+ */
37
+ private generateMarkdown;
38
+ /**
39
+ * Get description for agent type.
40
+ */
41
+ private getAgentTypeDescription;
42
+ }
43
+ /**
44
+ * Export an AgentSpec to OpenCode SDK format.
45
+ */
46
+ declare function exportToOpenCode(spec: AgentSpec, options?: OpenCodeExportOptions): OpenCodeExportResult;
47
+ /**
48
+ * Generate OpenCode agent markdown from an AgentSpec.
49
+ */
50
+ declare function generateOpenCodeMarkdown(spec: AgentSpec, options?: OpenCodeExportOptions): string;
51
+ /**
52
+ * Generate OpenCode agent JSON from an AgentSpec.
53
+ */
54
+ declare function generateOpenCodeJSON(spec: AgentSpec, options?: OpenCodeExportOptions): OpenCodeAgentJSON;
55
+ /**
56
+ * Validate an AgentSpec for OpenCode SDK export.
57
+ */
58
+ declare function validateForOpenCode(spec: AgentSpec): {
59
+ valid: boolean;
60
+ errors: string[];
61
+ };
62
+ //#endregion
63
+ export { OpenCodeExporter, exportToOpenCode, generateOpenCodeJSON, generateOpenCodeMarkdown, validateForOpenCode };
64
+ //# sourceMappingURL=opencode-exporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-exporter.d.ts","names":[],"sources":["../../src/exporters/opencode-exporter.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAuDa,cA7BA,gBAAA,YAA4B,QA6B5B,CA5BX,qBA4BW,EA3BX,oBA2BW,CAAA,CAAA;EACR,SAAA,MAAA,EAAA,UAAA;EAOY;;;EAgPD,MAAA,CAAA,IAAA,EA3QN,SA2QsB,EAAA,OAAA,CAAA,EA1QnB,qBA0QmB,CAAA,EAzQ3B,oBAyQ2B;EACxB;;;EAEe,UAAA,CAAA,KAAA,EA5PZ,SA4PY,EAAA,EAAA,OAAA,CAAA,EA3PV,qBA2PU,CAAA,EA1PlB,oBA0PkB,EAAA;EAQP;AAYhB;;EAEY,QAAA,CAAA,IAAA,EAzQK,SAyQL,CAAA,EAAA;IACT,KAAA,EAAA,OAAA;IAAiB,MAAA,EAAA,MAAA,EAAA;EASJ,CAAA;;;;;;;;;;;;;;;;;;;;;iBAnCA,gBAAA,OACR,qBACI,wBACT;;;;iBAQa,wBAAA,OACR,qBACI;;;;iBAUI,oBAAA,OACR,qBACI,wBACT;;;;iBASa,mBAAA,OAA0B"}
@@ -0,0 +1,200 @@
1
+ import { agentKey } from "../spec/spec.js";
2
+ import { inferAgentType } from "../providers/opencode-sdk/agent-bridge.js";
3
+
4
+ //#region src/exporters/opencode-exporter.ts
5
+ /**
6
+ * OpenCode SDK Exporter.
7
+ */
8
+ var OpenCodeExporter = class {
9
+ format = "opencode";
10
+ /**
11
+ * Export an AgentSpec to OpenCode SDK format.
12
+ */
13
+ export(spec, options = {}) {
14
+ const jsonConfig = this.buildJsonConfig(spec, options);
15
+ return {
16
+ jsonConfig,
17
+ markdownConfig: this.generateMarkdown(spec, jsonConfig, options),
18
+ exportedAt: /* @__PURE__ */ new Date(),
19
+ sourceSpec: agentKey(spec.meta)
20
+ };
21
+ }
22
+ /**
23
+ * Export multiple specs.
24
+ */
25
+ exportMany(specs, options = {}) {
26
+ return specs.map((spec) => this.export(spec, options));
27
+ }
28
+ /**
29
+ * Validate that a spec can be exported.
30
+ */
31
+ validate(spec) {
32
+ const errors = [];
33
+ if (!spec.meta?.key) errors.push("Spec must have a meta.key");
34
+ if (!spec.instructions) errors.push("Spec must have instructions");
35
+ for (const tool of spec.tools ?? []) {
36
+ if (!tool.name) errors.push("All tools must have a name");
37
+ if (tool.name && !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tool.name)) errors.push(`Tool name '${tool.name}' should be a valid identifier (letters, numbers, underscores)`);
38
+ }
39
+ return {
40
+ valid: errors.length === 0,
41
+ errors
42
+ };
43
+ }
44
+ /**
45
+ * Build OpenCode agent JSON configuration.
46
+ */
47
+ buildJsonConfig(spec, options) {
48
+ const agentType = options.agentType ?? inferAgentType(spec);
49
+ return {
50
+ name: spec.meta.key,
51
+ version: spec.meta.version,
52
+ description: spec.description,
53
+ type: agentType,
54
+ instructions: spec.instructions,
55
+ tools: this.exportTools(spec),
56
+ config: {
57
+ max_steps: options.maxSteps ?? spec.maxSteps ?? 10,
58
+ temperature: options.temperature ?? .7,
59
+ model: options.model
60
+ }
61
+ };
62
+ }
63
+ /**
64
+ * Export tools to OpenCode format.
65
+ */
66
+ exportTools(spec) {
67
+ return spec.tools.map((tool) => ({
68
+ name: tool.name,
69
+ description: tool.description ?? `Execute ${tool.name}`,
70
+ schema: tool.schema ?? { type: "object" },
71
+ requires_approval: tool.requiresApproval ?? !tool.automationSafe
72
+ }));
73
+ }
74
+ /**
75
+ * Generate markdown agent file content.
76
+ */
77
+ generateMarkdown(spec, jsonConfig, options) {
78
+ const lines = [];
79
+ lines.push("---");
80
+ lines.push(`name: ${jsonConfig.name}`);
81
+ lines.push(`type: ${jsonConfig.type}`);
82
+ if (jsonConfig.version) lines.push(`version: ${jsonConfig.version}`);
83
+ if (jsonConfig.config.model) lines.push(`model: ${jsonConfig.config.model}`);
84
+ if (jsonConfig.config.temperature !== void 0) lines.push(`temperature: ${jsonConfig.config.temperature}`);
85
+ if (jsonConfig.config.max_steps !== void 0) lines.push(`max_steps: ${jsonConfig.config.max_steps}`);
86
+ if (jsonConfig.tools.length > 0) {
87
+ lines.push("tools:");
88
+ for (const tool of jsonConfig.tools) {
89
+ const permission = tool.requires_approval ? " # requires approval" : "";
90
+ lines.push(` - ${tool.name}${permission}`);
91
+ }
92
+ }
93
+ lines.push("---");
94
+ lines.push("");
95
+ lines.push(`# ${spec.meta.key}`);
96
+ lines.push("");
97
+ if (spec.description) {
98
+ lines.push(spec.description);
99
+ lines.push("");
100
+ }
101
+ lines.push(`> Agent type: **${jsonConfig.type}**`);
102
+ lines.push("");
103
+ lines.push(this.getAgentTypeDescription(jsonConfig.type));
104
+ lines.push("");
105
+ lines.push("## Instructions");
106
+ lines.push("");
107
+ lines.push(spec.instructions);
108
+ lines.push("");
109
+ if (spec.tools.length > 0) {
110
+ lines.push("## Tools");
111
+ lines.push("");
112
+ for (const tool of spec.tools) {
113
+ const approval = tool.requiresApproval ? " *(requires approval)*" : "";
114
+ const safe = tool.automationSafe === false ? " *(not automation safe)*" : "";
115
+ lines.push(`### ${tool.name}${approval}${safe}`);
116
+ lines.push("");
117
+ if (tool.description) {
118
+ lines.push(tool.description);
119
+ lines.push("");
120
+ }
121
+ if (tool.schema && options.includeComments !== false) {
122
+ lines.push("**Parameters:**");
123
+ lines.push("");
124
+ lines.push("```json");
125
+ lines.push(JSON.stringify(tool.schema, null, options.prettyPrint !== false ? 2 : 0));
126
+ lines.push("```");
127
+ lines.push("");
128
+ }
129
+ }
130
+ }
131
+ if (spec.knowledge && spec.knowledge.length > 0) {
132
+ lines.push("## Knowledge Sources");
133
+ lines.push("");
134
+ for (const k of spec.knowledge) {
135
+ const required = k.required ? "(required)" : "(optional)";
136
+ lines.push(`- **${k.key}** ${required}`);
137
+ if (k.instructions) lines.push(` - ${k.instructions}`);
138
+ }
139
+ lines.push("");
140
+ }
141
+ if (spec.policy) {
142
+ lines.push("## Policy");
143
+ lines.push("");
144
+ if (spec.policy.confidence?.min) lines.push(`- Minimum confidence: ${spec.policy.confidence.min}`);
145
+ if (spec.policy.escalation) lines.push("- Escalation policy configured");
146
+ lines.push("");
147
+ }
148
+ lines.push("## Configuration");
149
+ lines.push("");
150
+ lines.push("```json");
151
+ lines.push(JSON.stringify(jsonConfig.config, null, options.prettyPrint !== false ? 2 : 0));
152
+ lines.push("```");
153
+ lines.push("");
154
+ lines.push("---");
155
+ lines.push("");
156
+ lines.push(`*Generated from ContractSpec: ${agentKey(spec.meta)}*`);
157
+ lines.push(`*Exported at: ${(/* @__PURE__ */ new Date()).toISOString()}*`);
158
+ return lines.join("\n");
159
+ }
160
+ /**
161
+ * Get description for agent type.
162
+ */
163
+ getAgentTypeDescription(type) {
164
+ switch (type) {
165
+ case "build": return "Primary agent with full tool access for code generation and modification.";
166
+ case "plan": return "Restricted agent for analysis and planning. File edits and bash commands require approval.";
167
+ case "general": return "General-purpose subagent for complex questions and multi-step tasks.";
168
+ case "explore": return "Fast subagent optimized for codebase exploration and pattern searching.";
169
+ default: return "";
170
+ }
171
+ }
172
+ };
173
+ /**
174
+ * Export an AgentSpec to OpenCode SDK format.
175
+ */
176
+ function exportToOpenCode(spec, options) {
177
+ return new OpenCodeExporter().export(spec, options);
178
+ }
179
+ /**
180
+ * Generate OpenCode agent markdown from an AgentSpec.
181
+ */
182
+ function generateOpenCodeMarkdown(spec, options) {
183
+ return new OpenCodeExporter().export(spec, options).markdownConfig;
184
+ }
185
+ /**
186
+ * Generate OpenCode agent JSON from an AgentSpec.
187
+ */
188
+ function generateOpenCodeJSON(spec, options) {
189
+ return new OpenCodeExporter().export(spec, options).jsonConfig;
190
+ }
191
+ /**
192
+ * Validate an AgentSpec for OpenCode SDK export.
193
+ */
194
+ function validateForOpenCode(spec) {
195
+ return new OpenCodeExporter().validate(spec);
196
+ }
197
+
198
+ //#endregion
199
+ export { OpenCodeExporter, exportToOpenCode, generateOpenCodeJSON, generateOpenCodeMarkdown, validateForOpenCode };
200
+ //# sourceMappingURL=opencode-exporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-exporter.js","names":["errors: string[]","agentType: OpenCodeAgentType","lines: string[]"],"sources":["../../src/exporters/opencode-exporter.ts"],"sourcesContent":["/**\n * OpenCode SDK Exporter\n *\n * Exports ContractSpec AgentSpec definitions to formats compatible with\n * @opencode-ai/sdk (JSON config and markdown agent files).\n */\n\nimport type { AgentSpec } from '../spec/spec';\nimport { agentKey } from '../spec/spec';\nimport type {\n Exporter,\n OpenCodeAgentJSON,\n OpenCodeExportOptions,\n OpenCodeExportResult,\n OpenCodeToolJSON,\n} from './types';\nimport type { OpenCodeAgentType } from '../providers/types';\nimport { inferAgentType } from '../providers/opencode-sdk/agent-bridge';\n\n// ============================================================================\n// Exporter Implementation\n// ============================================================================\n\n/**\n * OpenCode SDK Exporter.\n */\nexport class OpenCodeExporter implements Exporter<\n OpenCodeExportOptions,\n OpenCodeExportResult\n> {\n readonly format = 'opencode' as const;\n\n /**\n * Export an AgentSpec to OpenCode SDK format.\n */\n export(\n spec: AgentSpec,\n options: OpenCodeExportOptions = {}\n ): OpenCodeExportResult {\n const jsonConfig = this.buildJsonConfig(spec, options);\n const markdownConfig = this.generateMarkdown(spec, jsonConfig, options);\n\n return {\n jsonConfig,\n markdownConfig,\n exportedAt: new Date(),\n sourceSpec: agentKey(spec.meta),\n };\n }\n\n /**\n * Export multiple specs.\n */\n exportMany(\n specs: AgentSpec[],\n options: OpenCodeExportOptions = {}\n ): OpenCodeExportResult[] {\n return specs.map((spec) => this.export(spec, options));\n }\n\n /**\n * Validate that a spec can be exported.\n */\n validate(spec: AgentSpec): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n if (!spec.meta?.key) {\n errors.push('Spec must have a meta.key');\n }\n\n if (!spec.instructions) {\n errors.push('Spec must have instructions');\n }\n\n // OpenCode doesn't require tools, but we check for valid tool names\n for (const tool of spec.tools ?? []) {\n if (!tool.name) {\n errors.push('All tools must have a name');\n }\n // OpenCode tool names should be valid identifiers\n if (tool.name && !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tool.name)) {\n errors.push(\n `Tool name '${tool.name}' should be a valid identifier (letters, numbers, underscores)`\n );\n }\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Build OpenCode agent JSON configuration.\n */\n private buildJsonConfig(\n spec: AgentSpec,\n options: OpenCodeExportOptions\n ): OpenCodeAgentJSON {\n const agentType: OpenCodeAgentType =\n options.agentType ?? inferAgentType(spec);\n\n return {\n name: spec.meta.key,\n version: spec.meta.version,\n description: spec.description,\n type: agentType,\n instructions: spec.instructions,\n tools: this.exportTools(spec),\n config: {\n max_steps: options.maxSteps ?? spec.maxSteps ?? 10,\n temperature: options.temperature ?? 0.7,\n model: options.model,\n },\n };\n }\n\n /**\n * Export tools to OpenCode format.\n */\n private exportTools(spec: AgentSpec): OpenCodeToolJSON[] {\n return spec.tools.map((tool) => ({\n name: tool.name,\n description: tool.description ?? `Execute ${tool.name}`,\n schema: tool.schema ?? { type: 'object' },\n requires_approval: tool.requiresApproval ?? !tool.automationSafe,\n }));\n }\n\n /**\n * Generate markdown agent file content.\n */\n private generateMarkdown(\n spec: AgentSpec,\n jsonConfig: OpenCodeAgentJSON,\n options: OpenCodeExportOptions\n ): string {\n const lines: string[] = [];\n\n // Frontmatter\n lines.push('---');\n lines.push(`name: ${jsonConfig.name}`);\n lines.push(`type: ${jsonConfig.type}`);\n\n if (jsonConfig.version) {\n lines.push(`version: ${jsonConfig.version}`);\n }\n\n if (jsonConfig.config.model) {\n lines.push(`model: ${jsonConfig.config.model}`);\n }\n\n if (jsonConfig.config.temperature !== undefined) {\n lines.push(`temperature: ${jsonConfig.config.temperature}`);\n }\n\n if (jsonConfig.config.max_steps !== undefined) {\n lines.push(`max_steps: ${jsonConfig.config.max_steps}`);\n }\n\n // Tool list in frontmatter\n if (jsonConfig.tools.length > 0) {\n lines.push('tools:');\n for (const tool of jsonConfig.tools) {\n const permission = tool.requires_approval ? ' # requires approval' : '';\n lines.push(` - ${tool.name}${permission}`);\n }\n }\n\n lines.push('---');\n lines.push('');\n\n // Title\n lines.push(`# ${spec.meta.key}`);\n lines.push('');\n\n // Description\n if (spec.description) {\n lines.push(spec.description);\n lines.push('');\n }\n\n // Agent type explanation\n lines.push(`> Agent type: **${jsonConfig.type}**`);\n lines.push('');\n lines.push(this.getAgentTypeDescription(jsonConfig.type));\n lines.push('');\n\n // Instructions\n lines.push('## Instructions');\n lines.push('');\n lines.push(spec.instructions);\n lines.push('');\n\n // Tools section\n if (spec.tools.length > 0) {\n lines.push('## Tools');\n lines.push('');\n for (const tool of spec.tools) {\n const approval = tool.requiresApproval ? ' *(requires approval)*' : '';\n const safe =\n tool.automationSafe === false ? ' *(not automation safe)*' : '';\n lines.push(`### ${tool.name}${approval}${safe}`);\n lines.push('');\n if (tool.description) {\n lines.push(tool.description);\n lines.push('');\n }\n if (tool.schema && options.includeComments !== false) {\n lines.push('**Parameters:**');\n lines.push('');\n lines.push('```json');\n lines.push(\n JSON.stringify(\n tool.schema,\n null,\n options.prettyPrint !== false ? 2 : 0\n )\n );\n lines.push('```');\n lines.push('');\n }\n }\n }\n\n // Knowledge sources\n if (spec.knowledge && spec.knowledge.length > 0) {\n lines.push('## Knowledge Sources');\n lines.push('');\n for (const k of spec.knowledge) {\n const required = k.required ? '(required)' : '(optional)';\n lines.push(`- **${k.key}** ${required}`);\n if (k.instructions) {\n lines.push(` - ${k.instructions}`);\n }\n }\n lines.push('');\n }\n\n // Policy\n if (spec.policy) {\n lines.push('## Policy');\n lines.push('');\n if (spec.policy.confidence?.min) {\n lines.push(`- Minimum confidence: ${spec.policy.confidence.min}`);\n }\n if (spec.policy.escalation) {\n lines.push('- Escalation policy configured');\n }\n lines.push('');\n }\n\n // Configuration (JSON)\n lines.push('## Configuration');\n lines.push('');\n lines.push('```json');\n lines.push(\n JSON.stringify(\n jsonConfig.config,\n null,\n options.prettyPrint !== false ? 2 : 0\n )\n );\n lines.push('```');\n lines.push('');\n\n // Footer\n lines.push('---');\n lines.push('');\n lines.push(`*Generated from ContractSpec: ${agentKey(spec.meta)}*`);\n lines.push(`*Exported at: ${new Date().toISOString()}*`);\n\n return lines.join('\\n');\n }\n\n /**\n * Get description for agent type.\n */\n private getAgentTypeDescription(type: OpenCodeAgentType): string {\n switch (type) {\n case 'build':\n return 'Primary agent with full tool access for code generation and modification.';\n case 'plan':\n return 'Restricted agent for analysis and planning. File edits and bash commands require approval.';\n case 'general':\n return 'General-purpose subagent for complex questions and multi-step tasks.';\n case 'explore':\n return 'Fast subagent optimized for codebase exploration and pattern searching.';\n default:\n return '';\n }\n }\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Export an AgentSpec to OpenCode SDK format.\n */\nexport function exportToOpenCode(\n spec: AgentSpec,\n options?: OpenCodeExportOptions\n): OpenCodeExportResult {\n const exporter = new OpenCodeExporter();\n return exporter.export(spec, options);\n}\n\n/**\n * Generate OpenCode agent markdown from an AgentSpec.\n */\nexport function generateOpenCodeMarkdown(\n spec: AgentSpec,\n options?: OpenCodeExportOptions\n): string {\n const exporter = new OpenCodeExporter();\n const result = exporter.export(spec, options);\n return result.markdownConfig;\n}\n\n/**\n * Generate OpenCode agent JSON from an AgentSpec.\n */\nexport function generateOpenCodeJSON(\n spec: AgentSpec,\n options?: OpenCodeExportOptions\n): OpenCodeAgentJSON {\n const exporter = new OpenCodeExporter();\n const result = exporter.export(spec, options);\n return result.jsonConfig;\n}\n\n/**\n * Validate an AgentSpec for OpenCode SDK export.\n */\nexport function validateForOpenCode(spec: AgentSpec): {\n valid: boolean;\n errors: string[];\n} {\n const exporter = new OpenCodeExporter();\n return exporter.validate(spec);\n}\n"],"mappings":";;;;;;;AA0BA,IAAa,mBAAb,MAGE;CACA,AAAS,SAAS;;;;CAKlB,OACE,MACA,UAAiC,EAAE,EACb;EACtB,MAAM,aAAa,KAAK,gBAAgB,MAAM,QAAQ;AAGtD,SAAO;GACL;GACA,gBAJqB,KAAK,iBAAiB,MAAM,YAAY,QAAQ;GAKrE,4BAAY,IAAI,MAAM;GACtB,YAAY,SAAS,KAAK,KAAK;GAChC;;;;;CAMH,WACE,OACA,UAAiC,EAAE,EACX;AACxB,SAAO,MAAM,KAAK,SAAS,KAAK,OAAO,MAAM,QAAQ,CAAC;;;;;CAMxD,SAAS,MAAuD;EAC9D,MAAMA,SAAmB,EAAE;AAE3B,MAAI,CAAC,KAAK,MAAM,IACd,QAAO,KAAK,4BAA4B;AAG1C,MAAI,CAAC,KAAK,aACR,QAAO,KAAK,8BAA8B;AAI5C,OAAK,MAAM,QAAQ,KAAK,SAAS,EAAE,EAAE;AACnC,OAAI,CAAC,KAAK,KACR,QAAO,KAAK,6BAA6B;AAG3C,OAAI,KAAK,QAAQ,CAAC,2BAA2B,KAAK,KAAK,KAAK,CAC1D,QAAO,KACL,cAAc,KAAK,KAAK,gEACzB;;AAIL,SAAO;GAAE,OAAO,OAAO,WAAW;GAAG;GAAQ;;;;;CAU/C,AAAQ,gBACN,MACA,SACmB;EACnB,MAAMC,YACJ,QAAQ,aAAa,eAAe,KAAK;AAE3C,SAAO;GACL,MAAM,KAAK,KAAK;GAChB,SAAS,KAAK,KAAK;GACnB,aAAa,KAAK;GAClB,MAAM;GACN,cAAc,KAAK;GACnB,OAAO,KAAK,YAAY,KAAK;GAC7B,QAAQ;IACN,WAAW,QAAQ,YAAY,KAAK,YAAY;IAChD,aAAa,QAAQ,eAAe;IACpC,OAAO,QAAQ;IAChB;GACF;;;;;CAMH,AAAQ,YAAY,MAAqC;AACvD,SAAO,KAAK,MAAM,KAAK,UAAU;GAC/B,MAAM,KAAK;GACX,aAAa,KAAK,eAAe,WAAW,KAAK;GACjD,QAAQ,KAAK,UAAU,EAAE,MAAM,UAAU;GACzC,mBAAmB,KAAK,oBAAoB,CAAC,KAAK;GACnD,EAAE;;;;;CAML,AAAQ,iBACN,MACA,YACA,SACQ;EACR,MAAMC,QAAkB,EAAE;AAG1B,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,SAAS,WAAW,OAAO;AACtC,QAAM,KAAK,SAAS,WAAW,OAAO;AAEtC,MAAI,WAAW,QACb,OAAM,KAAK,YAAY,WAAW,UAAU;AAG9C,MAAI,WAAW,OAAO,MACpB,OAAM,KAAK,UAAU,WAAW,OAAO,QAAQ;AAGjD,MAAI,WAAW,OAAO,gBAAgB,OACpC,OAAM,KAAK,gBAAgB,WAAW,OAAO,cAAc;AAG7D,MAAI,WAAW,OAAO,cAAc,OAClC,OAAM,KAAK,cAAc,WAAW,OAAO,YAAY;AAIzD,MAAI,WAAW,MAAM,SAAS,GAAG;AAC/B,SAAM,KAAK,SAAS;AACpB,QAAK,MAAM,QAAQ,WAAW,OAAO;IACnC,MAAM,aAAa,KAAK,oBAAoB,yBAAyB;AACrE,UAAM,KAAK,OAAO,KAAK,OAAO,aAAa;;;AAI/C,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,GAAG;AAGd,QAAM,KAAK,KAAK,KAAK,KAAK,MAAM;AAChC,QAAM,KAAK,GAAG;AAGd,MAAI,KAAK,aAAa;AACpB,SAAM,KAAK,KAAK,YAAY;AAC5B,SAAM,KAAK,GAAG;;AAIhB,QAAM,KAAK,mBAAmB,WAAW,KAAK,IAAI;AAClD,QAAM,KAAK,GAAG;AACd,QAAM,KAAK,KAAK,wBAAwB,WAAW,KAAK,CAAC;AACzD,QAAM,KAAK,GAAG;AAGd,QAAM,KAAK,kBAAkB;AAC7B,QAAM,KAAK,GAAG;AACd,QAAM,KAAK,KAAK,aAAa;AAC7B,QAAM,KAAK,GAAG;AAGd,MAAI,KAAK,MAAM,SAAS,GAAG;AACzB,SAAM,KAAK,WAAW;AACtB,SAAM,KAAK,GAAG;AACd,QAAK,MAAM,QAAQ,KAAK,OAAO;IAC7B,MAAM,WAAW,KAAK,mBAAmB,2BAA2B;IACpE,MAAM,OACJ,KAAK,mBAAmB,QAAQ,6BAA6B;AAC/D,UAAM,KAAK,OAAO,KAAK,OAAO,WAAW,OAAO;AAChD,UAAM,KAAK,GAAG;AACd,QAAI,KAAK,aAAa;AACpB,WAAM,KAAK,KAAK,YAAY;AAC5B,WAAM,KAAK,GAAG;;AAEhB,QAAI,KAAK,UAAU,QAAQ,oBAAoB,OAAO;AACpD,WAAM,KAAK,kBAAkB;AAC7B,WAAM,KAAK,GAAG;AACd,WAAM,KAAK,UAAU;AACrB,WAAM,KACJ,KAAK,UACH,KAAK,QACL,MACA,QAAQ,gBAAgB,QAAQ,IAAI,EACrC,CACF;AACD,WAAM,KAAK,MAAM;AACjB,WAAM,KAAK,GAAG;;;;AAMpB,MAAI,KAAK,aAAa,KAAK,UAAU,SAAS,GAAG;AAC/C,SAAM,KAAK,uBAAuB;AAClC,SAAM,KAAK,GAAG;AACd,QAAK,MAAM,KAAK,KAAK,WAAW;IAC9B,MAAM,WAAW,EAAE,WAAW,eAAe;AAC7C,UAAM,KAAK,OAAO,EAAE,IAAI,KAAK,WAAW;AACxC,QAAI,EAAE,aACJ,OAAM,KAAK,OAAO,EAAE,eAAe;;AAGvC,SAAM,KAAK,GAAG;;AAIhB,MAAI,KAAK,QAAQ;AACf,SAAM,KAAK,YAAY;AACvB,SAAM,KAAK,GAAG;AACd,OAAI,KAAK,OAAO,YAAY,IAC1B,OAAM,KAAK,yBAAyB,KAAK,OAAO,WAAW,MAAM;AAEnE,OAAI,KAAK,OAAO,WACd,OAAM,KAAK,iCAAiC;AAE9C,SAAM,KAAK,GAAG;;AAIhB,QAAM,KAAK,mBAAmB;AAC9B,QAAM,KAAK,GAAG;AACd,QAAM,KAAK,UAAU;AACrB,QAAM,KACJ,KAAK,UACH,WAAW,QACX,MACA,QAAQ,gBAAgB,QAAQ,IAAI,EACrC,CACF;AACD,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,GAAG;AAGd,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,GAAG;AACd,QAAM,KAAK,iCAAiC,SAAS,KAAK,KAAK,CAAC,GAAG;AACnE,QAAM,KAAK,kCAAiB,IAAI,MAAM,EAAC,aAAa,CAAC,GAAG;AAExD,SAAO,MAAM,KAAK,KAAK;;;;;CAMzB,AAAQ,wBAAwB,MAAiC;AAC/D,UAAQ,MAAR;GACE,KAAK,QACH,QAAO;GACT,KAAK,OACH,QAAO;GACT,KAAK,UACH,QAAO;GACT,KAAK,UACH,QAAO;GACT,QACE,QAAO;;;;;;;AAYf,SAAgB,iBACd,MACA,SACsB;AAEtB,QADiB,IAAI,kBAAkB,CACvB,OAAO,MAAM,QAAQ;;;;;AAMvC,SAAgB,yBACd,MACA,SACQ;AAGR,QAFiB,IAAI,kBAAkB,CACf,OAAO,MAAM,QAAQ,CAC/B;;;;;AAMhB,SAAgB,qBACd,MACA,SACmB;AAGnB,QAFiB,IAAI,kBAAkB,CACf,OAAO,MAAM,QAAQ,CAC/B;;;;;AAMhB,SAAgB,oBAAoB,MAGlC;AAEA,QADiB,IAAI,kBAAkB,CACvB,SAAS,KAAK"}