@sudocode-ai/cli 0.1.12 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/init-commands.d.ts.map +1 -1
- package/dist/cli/init-commands.js +6 -2
- package/dist/cli/init-commands.js.map +1 -1
- package/dist/cli/plugin-commands.d.ts +62 -0
- package/dist/cli/plugin-commands.d.ts.map +1 -0
- package/dist/cli/plugin-commands.js +595 -0
- package/dist/cli/plugin-commands.js.map +1 -0
- package/dist/cli.js +73 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +40 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +35 -0
- package/dist/config.js.map +1 -1
- package/dist/export.d.ts +10 -5
- package/dist/export.d.ts.map +1 -1
- package/dist/export.js +88 -18
- package/dist/export.js.map +1 -1
- package/dist/import.d.ts.map +1 -1
- package/dist/import.js +20 -0
- package/dist/import.js.map +1 -1
- package/dist/integrations/base-provider.d.ts +108 -0
- package/dist/integrations/base-provider.d.ts.map +1 -0
- package/dist/integrations/base-provider.js +80 -0
- package/dist/integrations/base-provider.js.map +1 -0
- package/dist/integrations/config-resolver.d.ts +62 -0
- package/dist/integrations/config-resolver.d.ts.map +1 -0
- package/dist/integrations/config-resolver.js +69 -0
- package/dist/integrations/config-resolver.js.map +1 -0
- package/dist/integrations/config-validator.d.ts +75 -0
- package/dist/integrations/config-validator.d.ts.map +1 -0
- package/dist/integrations/config-validator.js +129 -0
- package/dist/integrations/config-validator.js.map +1 -0
- package/dist/integrations/index.d.ts +14 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +20 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/plugin-loader.d.ts +69 -0
- package/dist/integrations/plugin-loader.d.ts.map +1 -0
- package/dist/integrations/plugin-loader.js +172 -0
- package/dist/integrations/plugin-loader.js.map +1 -0
- package/dist/integrations/registry.d.ts +67 -0
- package/dist/integrations/registry.d.ts.map +1 -0
- package/dist/integrations/registry.js +77 -0
- package/dist/integrations/registry.js.map +1 -0
- package/dist/integrations/sync-coordinator.d.ts +186 -0
- package/dist/integrations/sync-coordinator.d.ts.map +1 -0
- package/dist/integrations/sync-coordinator.js +776 -0
- package/dist/integrations/sync-coordinator.js.map +1 -0
- package/dist/integrations/types.d.ts +142 -0
- package/dist/integrations/types.d.ts.map +1 -0
- package/dist/integrations/types.js +6 -0
- package/dist/integrations/types.js.map +1 -0
- package/dist/integrations/utils/conflict-resolver.d.ts +79 -0
- package/dist/integrations/utils/conflict-resolver.d.ts.map +1 -0
- package/dist/integrations/utils/conflict-resolver.js +106 -0
- package/dist/integrations/utils/conflict-resolver.js.map +1 -0
- package/dist/operations/external-links.d.ts +106 -0
- package/dist/operations/external-links.d.ts.map +1 -0
- package/dist/operations/external-links.js +300 -0
- package/dist/operations/external-links.js.map +1 -0
- package/dist/operations/feedback.d.ts.map +1 -1
- package/dist/operations/feedback.js +3 -1
- package/dist/operations/feedback.js.map +1 -1
- package/dist/operations/index.d.ts +1 -0
- package/dist/operations/index.d.ts.map +1 -1
- package/dist/operations/index.js +1 -0
- package/dist/operations/index.js.map +1 -1
- package/dist/operations/issues.d.ts +2 -0
- package/dist/operations/issues.d.ts.map +1 -1
- package/dist/operations/issues.js +34 -5
- package/dist/operations/issues.js.map +1 -1
- package/dist/operations/relationships.d.ts.map +1 -1
- package/dist/operations/relationships.js +6 -2
- package/dist/operations/relationships.js.map +1 -1
- package/dist/operations/specs.d.ts +2 -0
- package/dist/operations/specs.d.ts.map +1 -1
- package/dist/operations/specs.js +32 -4
- package/dist/operations/specs.js.map +1 -1
- package/dist/sync.d.ts +3 -3
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +2 -0
- package/dist/sync.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/watcher.d.ts.map +1 -1
- package/dist/watcher.js +11 -6
- package/dist/watcher.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-validator.js","sourceRoot":"","sources":["../../src/integrations/config-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration module for sudocode
|
|
3
|
+
* Provides plugin loading, configuration validation, path resolution,
|
|
4
|
+
* provider interfaces, sync coordination, and registry for external integrations
|
|
5
|
+
*/
|
|
6
|
+
export { loadPlugin, loadConfiguredPlugins, resolvePluginPath, validateProviderConfig, testProviderConnection, getFirstPartyPlugins, clearPluginCache, } from "./plugin-loader.js";
|
|
7
|
+
export { validateIntegrationsConfig, validateIntegrationsConfigWithPlugins, type ValidationResult, } from "./config-validator.js";
|
|
8
|
+
export { resolveIntegrationPaths, getEnabledProviders, type ResolvedConfig, type ResolvedProviderConfig, type ResolvedJiraConfig, type ResolvedBeadsConfig, type ResolvedSpecKitConfig, type ResolvedOpenSpecConfig, } from "./config-resolver.js";
|
|
9
|
+
export type { IntegrationProvider, ProviderRegistry } from "./types.js";
|
|
10
|
+
export { BaseIntegrationProvider } from "./base-provider.js";
|
|
11
|
+
export { DefaultProviderRegistry } from "./registry.js";
|
|
12
|
+
export { SyncCoordinator, type SyncCoordinatorOptions, } from "./sync-coordinator.js";
|
|
13
|
+
export { resolveByStrategy, logConflict, createConflictLog, isConflict, type ConflictLog, } from "./utils/conflict-resolver.js";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,0BAA0B,EAC1B,qCAAqC,EACrC,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAE3B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAGxD,OAAO,EACL,eAAe,EACf,KAAK,sBAAsB,GAC5B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,KAAK,WAAW,GACjB,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration module for sudocode
|
|
3
|
+
* Provides plugin loading, configuration validation, path resolution,
|
|
4
|
+
* provider interfaces, sync coordination, and registry for external integrations
|
|
5
|
+
*/
|
|
6
|
+
// Plugin loading (dynamic imports)
|
|
7
|
+
export { loadPlugin, loadConfiguredPlugins, resolvePluginPath, validateProviderConfig, testProviderConnection, getFirstPartyPlugins, clearPluginCache, } from "./plugin-loader.js";
|
|
8
|
+
// Configuration validation
|
|
9
|
+
export { validateIntegrationsConfig, validateIntegrationsConfigWithPlugins, } from "./config-validator.js";
|
|
10
|
+
// Configuration path resolution
|
|
11
|
+
export { resolveIntegrationPaths, getEnabledProviders, } from "./config-resolver.js";
|
|
12
|
+
// Base provider class
|
|
13
|
+
export { BaseIntegrationProvider } from "./base-provider.js";
|
|
14
|
+
// Provider registry
|
|
15
|
+
export { DefaultProviderRegistry } from "./registry.js";
|
|
16
|
+
// Sync coordinator
|
|
17
|
+
export { SyncCoordinator, } from "./sync-coordinator.js";
|
|
18
|
+
// Conflict resolution utilities
|
|
19
|
+
export { resolveByStrategy, logConflict, createConflictLog, isConflict, } from "./utils/conflict-resolver.js";
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,mCAAmC;AACnC,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,2BAA2B;AAC3B,OAAO,EACL,0BAA0B,EAC1B,qCAAqC,GAEtC,MAAM,uBAAuB,CAAC;AAE/B,gCAAgC;AAChC,OAAO,EACL,uBAAuB,EACvB,mBAAmB,GAQpB,MAAM,sBAAsB,CAAC;AAK9B,sBAAsB;AACtB,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,oBAAoB;AACpB,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAExD,mBAAmB;AACnB,OAAO,EACL,eAAe,GAEhB,MAAM,uBAAuB,CAAC;AAE/B,gCAAgC;AAChC,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,UAAU,GAEX,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin loader for integration plugins
|
|
3
|
+
*
|
|
4
|
+
* Handles dynamic loading of integration plugins via:
|
|
5
|
+
* - npm packages (e.g., "@sudocode-ai/integration-beads")
|
|
6
|
+
* - Local paths (e.g., "./plugins/my-integration")
|
|
7
|
+
*
|
|
8
|
+
* First-party plugins are loaded by short name:
|
|
9
|
+
* - "beads" -> "@sudocode-ai/integration-beads"
|
|
10
|
+
*/
|
|
11
|
+
import type { IntegrationPlugin, IntegrationProviderConfig, IntegrationsConfig, PluginValidationResult, PluginTestResult } from "@sudocode-ai/types";
|
|
12
|
+
/**
|
|
13
|
+
* Resolve a plugin identifier to an importable module path
|
|
14
|
+
*
|
|
15
|
+
* @param pluginId - Plugin identifier (short name, npm package, or local path)
|
|
16
|
+
* @returns Module path that can be passed to import()
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolvePluginPath(pluginId: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Load a plugin by its identifier
|
|
21
|
+
*
|
|
22
|
+
* @param pluginId - Plugin identifier (short name, npm package, or local path)
|
|
23
|
+
* @returns The loaded plugin, or null if loading failed
|
|
24
|
+
*/
|
|
25
|
+
export declare function loadPlugin(pluginId: string): Promise<IntegrationPlugin | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Load all configured plugins
|
|
28
|
+
*
|
|
29
|
+
* @param config - Integrations configuration
|
|
30
|
+
* @returns Map of provider name to loaded plugin
|
|
31
|
+
*/
|
|
32
|
+
export declare function loadConfiguredPlugins(config: IntegrationsConfig): Promise<Map<string, IntegrationPlugin>>;
|
|
33
|
+
/**
|
|
34
|
+
* Validate a provider's configuration using its plugin
|
|
35
|
+
*
|
|
36
|
+
* @param providerName - Name of the provider in config
|
|
37
|
+
* @param providerConfig - The provider's configuration
|
|
38
|
+
* @returns Validation result from the plugin, or error if plugin not loaded
|
|
39
|
+
*/
|
|
40
|
+
export declare function validateProviderConfig(providerName: string, providerConfig: IntegrationProviderConfig): Promise<PluginValidationResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Test a provider's connection using its plugin
|
|
43
|
+
*
|
|
44
|
+
* @param providerName - Name of the provider in config
|
|
45
|
+
* @param providerConfig - The provider's configuration
|
|
46
|
+
* @param projectPath - Path to the sudocode project
|
|
47
|
+
* @returns Test result from the plugin
|
|
48
|
+
*/
|
|
49
|
+
export declare function testProviderConnection(providerName: string, providerConfig: IntegrationProviderConfig, projectPath: string): Promise<PluginTestResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Get a list of available first-party plugins
|
|
52
|
+
*/
|
|
53
|
+
export declare function getFirstPartyPlugins(): Array<{
|
|
54
|
+
name: string;
|
|
55
|
+
package: string;
|
|
56
|
+
}>;
|
|
57
|
+
/**
|
|
58
|
+
* Clear the plugin cache (useful for testing)
|
|
59
|
+
*/
|
|
60
|
+
export declare function clearPluginCache(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Extend Error to include 'code' property for module not found errors
|
|
63
|
+
*/
|
|
64
|
+
declare global {
|
|
65
|
+
interface Error {
|
|
66
|
+
code?: string;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=plugin-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-loader.d.ts","sourceRoot":"","sources":["../../src/integrations/plugin-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,oBAAoB,CAAC;AAc5B;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAa1D;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA0CnC;AAqBD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAkBzC;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,yBAAyB,GACxC,OAAO,CAAC,sBAAsB,CAAC,CAcjC;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,yBAAyB,EACzC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAe3B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,KAAK,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAKD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,KAAK;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;CACF"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin loader for integration plugins
|
|
3
|
+
*
|
|
4
|
+
* Handles dynamic loading of integration plugins via:
|
|
5
|
+
* - npm packages (e.g., "@sudocode-ai/integration-beads")
|
|
6
|
+
* - Local paths (e.g., "./plugins/my-integration")
|
|
7
|
+
*
|
|
8
|
+
* First-party plugins are loaded by short name:
|
|
9
|
+
* - "beads" -> "@sudocode-ai/integration-beads"
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Mapping of first-party plugin short names to npm package names
|
|
13
|
+
*/
|
|
14
|
+
const FIRST_PARTY_PLUGINS = {
|
|
15
|
+
beads: "@sudocode-ai/integration-beads",
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Cache for loaded plugins
|
|
19
|
+
*/
|
|
20
|
+
const pluginCache = new Map();
|
|
21
|
+
/**
|
|
22
|
+
* Resolve a plugin identifier to an importable module path
|
|
23
|
+
*
|
|
24
|
+
* @param pluginId - Plugin identifier (short name, npm package, or local path)
|
|
25
|
+
* @returns Module path that can be passed to import()
|
|
26
|
+
*/
|
|
27
|
+
export function resolvePluginPath(pluginId) {
|
|
28
|
+
// Check if it's a first-party plugin short name
|
|
29
|
+
if (FIRST_PARTY_PLUGINS[pluginId]) {
|
|
30
|
+
return FIRST_PARTY_PLUGINS[pluginId];
|
|
31
|
+
}
|
|
32
|
+
// If it starts with @ or contains /, treat as npm package or path
|
|
33
|
+
if (pluginId.startsWith("@") || pluginId.includes("/")) {
|
|
34
|
+
return pluginId;
|
|
35
|
+
}
|
|
36
|
+
// Otherwise, assume it's a first-party plugin
|
|
37
|
+
return `@sudocode-ai/integration-${pluginId}`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Load a plugin by its identifier
|
|
41
|
+
*
|
|
42
|
+
* @param pluginId - Plugin identifier (short name, npm package, or local path)
|
|
43
|
+
* @returns The loaded plugin, or null if loading failed
|
|
44
|
+
*/
|
|
45
|
+
export async function loadPlugin(pluginId) {
|
|
46
|
+
// Check cache first
|
|
47
|
+
const cached = pluginCache.get(pluginId);
|
|
48
|
+
if (cached) {
|
|
49
|
+
return cached;
|
|
50
|
+
}
|
|
51
|
+
const modulePath = resolvePluginPath(pluginId);
|
|
52
|
+
try {
|
|
53
|
+
// Dynamic import
|
|
54
|
+
const module = await import(modulePath);
|
|
55
|
+
// Plugin should be the default export
|
|
56
|
+
const plugin = module.default || module;
|
|
57
|
+
// Validate plugin has required fields
|
|
58
|
+
if (!isValidPlugin(plugin)) {
|
|
59
|
+
console.error(`Invalid plugin '${pluginId}': missing required fields (name, displayName, version, validateConfig, testConnection, createProvider)`);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
// Cache the plugin
|
|
63
|
+
pluginCache.set(pluginId, plugin);
|
|
64
|
+
return plugin;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
// Plugin not installed or failed to load
|
|
68
|
+
const err = error;
|
|
69
|
+
if (err.code === "ERR_MODULE_NOT_FOUND" ||
|
|
70
|
+
err.code === "MODULE_NOT_FOUND") {
|
|
71
|
+
console.warn(`Plugin '${pluginId}' not installed. Install with: npm install ${modulePath}`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.error(`Failed to load plugin '${pluginId}':`, err.message);
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if an object is a valid IntegrationPlugin
|
|
81
|
+
*/
|
|
82
|
+
function isValidPlugin(plugin) {
|
|
83
|
+
if (!plugin || typeof plugin !== "object") {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const p = plugin;
|
|
87
|
+
return (typeof p.name === "string" &&
|
|
88
|
+
typeof p.displayName === "string" &&
|
|
89
|
+
typeof p.version === "string" &&
|
|
90
|
+
typeof p.validateConfig === "function" &&
|
|
91
|
+
typeof p.testConnection === "function" &&
|
|
92
|
+
typeof p.createProvider === "function");
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Load all configured plugins
|
|
96
|
+
*
|
|
97
|
+
* @param config - Integrations configuration
|
|
98
|
+
* @returns Map of provider name to loaded plugin
|
|
99
|
+
*/
|
|
100
|
+
export async function loadConfiguredPlugins(config) {
|
|
101
|
+
const plugins = new Map();
|
|
102
|
+
for (const [providerName, providerConfig] of Object.entries(config)) {
|
|
103
|
+
if (!providerConfig?.enabled) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
// Determine plugin ID: use explicit plugin field, or fall back to provider name
|
|
107
|
+
const pluginId = providerConfig.plugin || providerName;
|
|
108
|
+
const plugin = await loadPlugin(pluginId);
|
|
109
|
+
if (plugin) {
|
|
110
|
+
plugins.set(providerName, plugin);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return plugins;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Validate a provider's configuration using its plugin
|
|
117
|
+
*
|
|
118
|
+
* @param providerName - Name of the provider in config
|
|
119
|
+
* @param providerConfig - The provider's configuration
|
|
120
|
+
* @returns Validation result from the plugin, or error if plugin not loaded
|
|
121
|
+
*/
|
|
122
|
+
export async function validateProviderConfig(providerName, providerConfig) {
|
|
123
|
+
const pluginId = providerConfig.plugin || providerName;
|
|
124
|
+
const plugin = await loadPlugin(pluginId);
|
|
125
|
+
if (!plugin) {
|
|
126
|
+
return {
|
|
127
|
+
valid: false,
|
|
128
|
+
errors: [`Plugin '${pluginId}' not installed or failed to load`],
|
|
129
|
+
warnings: [],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
// Delegate validation to plugin
|
|
133
|
+
return plugin.validateConfig(providerConfig.options || {});
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Test a provider's connection using its plugin
|
|
137
|
+
*
|
|
138
|
+
* @param providerName - Name of the provider in config
|
|
139
|
+
* @param providerConfig - The provider's configuration
|
|
140
|
+
* @param projectPath - Path to the sudocode project
|
|
141
|
+
* @returns Test result from the plugin
|
|
142
|
+
*/
|
|
143
|
+
export async function testProviderConnection(providerName, providerConfig, projectPath) {
|
|
144
|
+
const pluginId = providerConfig.plugin || providerName;
|
|
145
|
+
const plugin = await loadPlugin(pluginId);
|
|
146
|
+
if (!plugin) {
|
|
147
|
+
return {
|
|
148
|
+
success: false,
|
|
149
|
+
configured: true,
|
|
150
|
+
enabled: providerConfig.enabled,
|
|
151
|
+
error: `Plugin '${pluginId}' not installed or failed to load`,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// Delegate test to plugin
|
|
155
|
+
return plugin.testConnection(providerConfig.options || {}, projectPath);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get a list of available first-party plugins
|
|
159
|
+
*/
|
|
160
|
+
export function getFirstPartyPlugins() {
|
|
161
|
+
return Object.entries(FIRST_PARTY_PLUGINS).map(([name, pkg]) => ({
|
|
162
|
+
name,
|
|
163
|
+
package: pkg,
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Clear the plugin cache (useful for testing)
|
|
168
|
+
*/
|
|
169
|
+
export function clearPluginCache() {
|
|
170
|
+
pluginCache.clear();
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=plugin-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-loader.js","sourceRoot":"","sources":["../../src/integrations/plugin-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration provider registry
|
|
3
|
+
* Central place to register and look up integration providers
|
|
4
|
+
*/
|
|
5
|
+
import type { IntegrationProvider, ProviderRegistry } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Default implementation of the provider registry
|
|
8
|
+
*
|
|
9
|
+
* Stores providers in a Map keyed by provider name.
|
|
10
|
+
* Throws on duplicate registration to prevent accidental overwrites.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const registry = new DefaultProviderRegistry();
|
|
15
|
+
*
|
|
16
|
+
* // Register providers
|
|
17
|
+
* registry.register(new JiraProvider());
|
|
18
|
+
* registry.register(new BeadsProvider());
|
|
19
|
+
*
|
|
20
|
+
* // Look up a provider
|
|
21
|
+
* const jira = registry.get('jira');
|
|
22
|
+
* if (jira) {
|
|
23
|
+
* await jira.initialize(config);
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* // Check if provider exists
|
|
27
|
+
* if (registry.has('beads')) {
|
|
28
|
+
* console.log('Beads integration available');
|
|
29
|
+
* }
|
|
30
|
+
*
|
|
31
|
+
* // Get all providers
|
|
32
|
+
* for (const provider of registry.getAll()) {
|
|
33
|
+
* console.log(`Provider: ${provider.name}`);
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare class DefaultProviderRegistry implements ProviderRegistry {
|
|
38
|
+
private providers;
|
|
39
|
+
/**
|
|
40
|
+
* Register a provider in the registry
|
|
41
|
+
*
|
|
42
|
+
* @param provider - The provider to register
|
|
43
|
+
* @throws Error if a provider with the same name is already registered
|
|
44
|
+
*/
|
|
45
|
+
register(provider: IntegrationProvider): void;
|
|
46
|
+
/**
|
|
47
|
+
* Get a provider by name
|
|
48
|
+
*
|
|
49
|
+
* @param name - The provider name (e.g., "jira", "beads")
|
|
50
|
+
* @returns The provider, or undefined if not found
|
|
51
|
+
*/
|
|
52
|
+
get(name: string): IntegrationProvider | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Get all registered providers
|
|
55
|
+
*
|
|
56
|
+
* @returns Array of all registered providers
|
|
57
|
+
*/
|
|
58
|
+
getAll(): IntegrationProvider[];
|
|
59
|
+
/**
|
|
60
|
+
* Check if a provider is registered
|
|
61
|
+
*
|
|
62
|
+
* @param name - The provider name
|
|
63
|
+
* @returns True if a provider with this name is registered
|
|
64
|
+
*/
|
|
65
|
+
has(name: string): boolean;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/integrations/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,uBAAwB,YAAW,gBAAgB;IAC9D,OAAO,CAAC,SAAS,CAA0C;IAE3D;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAO7C;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAIlD;;;;OAIG;IACH,MAAM,IAAI,mBAAmB,EAAE;IAI/B;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAG3B"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration provider registry
|
|
3
|
+
* Central place to register and look up integration providers
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Default implementation of the provider registry
|
|
7
|
+
*
|
|
8
|
+
* Stores providers in a Map keyed by provider name.
|
|
9
|
+
* Throws on duplicate registration to prevent accidental overwrites.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const registry = new DefaultProviderRegistry();
|
|
14
|
+
*
|
|
15
|
+
* // Register providers
|
|
16
|
+
* registry.register(new JiraProvider());
|
|
17
|
+
* registry.register(new BeadsProvider());
|
|
18
|
+
*
|
|
19
|
+
* // Look up a provider
|
|
20
|
+
* const jira = registry.get('jira');
|
|
21
|
+
* if (jira) {
|
|
22
|
+
* await jira.initialize(config);
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* // Check if provider exists
|
|
26
|
+
* if (registry.has('beads')) {
|
|
27
|
+
* console.log('Beads integration available');
|
|
28
|
+
* }
|
|
29
|
+
*
|
|
30
|
+
* // Get all providers
|
|
31
|
+
* for (const provider of registry.getAll()) {
|
|
32
|
+
* console.log(`Provider: ${provider.name}`);
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export class DefaultProviderRegistry {
|
|
37
|
+
providers = new Map();
|
|
38
|
+
/**
|
|
39
|
+
* Register a provider in the registry
|
|
40
|
+
*
|
|
41
|
+
* @param provider - The provider to register
|
|
42
|
+
* @throws Error if a provider with the same name is already registered
|
|
43
|
+
*/
|
|
44
|
+
register(provider) {
|
|
45
|
+
if (this.providers.has(provider.name)) {
|
|
46
|
+
throw new Error(`Provider '${provider.name}' already registered`);
|
|
47
|
+
}
|
|
48
|
+
this.providers.set(provider.name, provider);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get a provider by name
|
|
52
|
+
*
|
|
53
|
+
* @param name - The provider name (e.g., "jira", "beads")
|
|
54
|
+
* @returns The provider, or undefined if not found
|
|
55
|
+
*/
|
|
56
|
+
get(name) {
|
|
57
|
+
return this.providers.get(name);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get all registered providers
|
|
61
|
+
*
|
|
62
|
+
* @returns Array of all registered providers
|
|
63
|
+
*/
|
|
64
|
+
getAll() {
|
|
65
|
+
return Array.from(this.providers.values());
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if a provider is registered
|
|
69
|
+
*
|
|
70
|
+
* @param name - The provider name
|
|
71
|
+
* @returns True if a provider with this name is registered
|
|
72
|
+
*/
|
|
73
|
+
has(name) {
|
|
74
|
+
return this.providers.has(name);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/integrations/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,OAAO,uBAAuB;IAC1B,SAAS,GAAG,IAAI,GAAG,EAA+B,CAAC;IAE3D;;;;;OAKG;IACH,QAAQ,CAAC,QAA6B;QACpC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,aAAa,QAAQ,CAAC,IAAI,sBAAsB,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACH,MAAM;QACJ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SyncCoordinator - Orchestrates sync between sudocode and external integration providers
|
|
3
|
+
*
|
|
4
|
+
* Manages provider lifecycle, handles change detection, and resolves conflicts
|
|
5
|
+
* during bidirectional synchronization.
|
|
6
|
+
*/
|
|
7
|
+
import type { IntegrationsConfig, ExternalLink, SyncResult, SyncConflict, SyncDirection } from "@sudocode-ai/types";
|
|
8
|
+
import type { IntegrationProvider } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Options for creating a SyncCoordinator
|
|
11
|
+
*/
|
|
12
|
+
export interface SyncCoordinatorOptions {
|
|
13
|
+
/** Project root path (where .sudocode is located) */
|
|
14
|
+
projectPath: string;
|
|
15
|
+
/** Integration configurations */
|
|
16
|
+
config: IntegrationsConfig;
|
|
17
|
+
/** Custom conflict resolution callback (for manual resolution) */
|
|
18
|
+
onConflict?: (conflict: SyncConflict) => Promise<"sudocode" | "external" | "skip">;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* SyncCoordinator manages integration providers and synchronization
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const coordinator = new SyncCoordinator({
|
|
26
|
+
* projectPath: '/path/to/project',
|
|
27
|
+
* config: { jira: { enabled: true, ... } },
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* coordinator.registerProvider(new JiraProvider());
|
|
31
|
+
* await coordinator.start();
|
|
32
|
+
*
|
|
33
|
+
* // Sync all providers
|
|
34
|
+
* const results = await coordinator.syncAll();
|
|
35
|
+
*
|
|
36
|
+
* // Link a sudocode entity to an external entity
|
|
37
|
+
* await coordinator.linkEntity('i-abc', 'PROJ-123', 'jira');
|
|
38
|
+
*
|
|
39
|
+
* await coordinator.stop();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare class SyncCoordinator {
|
|
43
|
+
private options;
|
|
44
|
+
private providers;
|
|
45
|
+
private lastSyncTimes;
|
|
46
|
+
constructor(options: SyncCoordinatorOptions);
|
|
47
|
+
/**
|
|
48
|
+
* Register an integration provider
|
|
49
|
+
* @param provider - The provider to register
|
|
50
|
+
*/
|
|
51
|
+
registerProvider(provider: IntegrationProvider): void;
|
|
52
|
+
/**
|
|
53
|
+
* Get a registered provider by name
|
|
54
|
+
* @param name - Provider name
|
|
55
|
+
* @returns The provider, or undefined if not found
|
|
56
|
+
*/
|
|
57
|
+
getProvider(name: string): IntegrationProvider | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Get all registered provider names
|
|
60
|
+
*/
|
|
61
|
+
getProviderNames(): string[];
|
|
62
|
+
/**
|
|
63
|
+
* Start the coordinator and initialize all enabled providers
|
|
64
|
+
*
|
|
65
|
+
* For each registered provider:
|
|
66
|
+
* 1. Skip if not enabled in config
|
|
67
|
+
* 2. Initialize with config
|
|
68
|
+
* 3. Validate connection
|
|
69
|
+
* 4. Start watching if auto_sync is enabled and provider supports it
|
|
70
|
+
*/
|
|
71
|
+
start(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Stop the coordinator and dispose all providers
|
|
74
|
+
*/
|
|
75
|
+
stop(): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Sync all registered and enabled providers
|
|
78
|
+
* @returns Array of sync results from all providers
|
|
79
|
+
*/
|
|
80
|
+
syncAll(): Promise<SyncResult[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Sync a specific provider
|
|
83
|
+
* @param providerName - Name of the provider to sync
|
|
84
|
+
* @returns Array of sync results
|
|
85
|
+
*/
|
|
86
|
+
syncProvider(providerName: string): Promise<SyncResult[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Sync a specific entity's external links
|
|
89
|
+
* @param entityId - Sudocode entity ID (s-xxxx or i-xxxx)
|
|
90
|
+
* @returns Array of sync results for each link
|
|
91
|
+
*/
|
|
92
|
+
syncEntity(entityId: string): Promise<SyncResult[]>;
|
|
93
|
+
/**
|
|
94
|
+
* Link a sudocode entity to an external entity
|
|
95
|
+
*
|
|
96
|
+
* @param entityId - Sudocode entity ID
|
|
97
|
+
* @param externalId - External system entity ID
|
|
98
|
+
* @param provider - Provider name
|
|
99
|
+
* @param options - Link options (sync direction, enabled)
|
|
100
|
+
*/
|
|
101
|
+
linkEntity(entityId: string, externalId: string, provider: string, options?: {
|
|
102
|
+
sync_direction?: SyncDirection;
|
|
103
|
+
sync_enabled?: boolean;
|
|
104
|
+
}): Promise<void>;
|
|
105
|
+
/**
|
|
106
|
+
* Remove a link between a sudocode entity and an external entity
|
|
107
|
+
*
|
|
108
|
+
* @param entityId - Sudocode entity ID
|
|
109
|
+
* @param externalId - External system entity ID
|
|
110
|
+
*/
|
|
111
|
+
unlinkEntity(entityId: string, externalId: string): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Handle deletion of a sudocode entity - propagate to external systems
|
|
114
|
+
*
|
|
115
|
+
* Call this when a sudocode entity is deleted to propagate the deletion
|
|
116
|
+
* to all linked external systems.
|
|
117
|
+
*
|
|
118
|
+
* @param entityId - Sudocode entity ID that was deleted
|
|
119
|
+
* @param externalLinks - The external_links from the deleted entity
|
|
120
|
+
* @returns Array of sync results
|
|
121
|
+
*/
|
|
122
|
+
handleEntityDeleted(entityId: string, externalLinks: ExternalLink[]): Promise<SyncResult[]>;
|
|
123
|
+
/**
|
|
124
|
+
* Handle inbound changes from an external provider
|
|
125
|
+
*/
|
|
126
|
+
private handleInboundChanges;
|
|
127
|
+
/**
|
|
128
|
+
* Process a single inbound change
|
|
129
|
+
*/
|
|
130
|
+
private processInboundChange;
|
|
131
|
+
/**
|
|
132
|
+
* Sync a single external link
|
|
133
|
+
*/
|
|
134
|
+
private syncSingleLink;
|
|
135
|
+
/**
|
|
136
|
+
* Detect if there's a conflict between sudocode and external versions
|
|
137
|
+
*/
|
|
138
|
+
private detectConflict;
|
|
139
|
+
/**
|
|
140
|
+
* Resolve a sync conflict based on configured strategy
|
|
141
|
+
*/
|
|
142
|
+
private resolveConflict;
|
|
143
|
+
/**
|
|
144
|
+
* Get provider config from options
|
|
145
|
+
*/
|
|
146
|
+
private getProviderConfig;
|
|
147
|
+
/**
|
|
148
|
+
* Determine if an ID is for a spec or issue
|
|
149
|
+
*/
|
|
150
|
+
private getEntityType;
|
|
151
|
+
/**
|
|
152
|
+
* Get the JSONL file path for an entity type
|
|
153
|
+
*/
|
|
154
|
+
private getEntityFilePath;
|
|
155
|
+
/**
|
|
156
|
+
* Load an entity from JSONL storage
|
|
157
|
+
*/
|
|
158
|
+
/**
|
|
159
|
+
* Load an entity from JSONL storage
|
|
160
|
+
*/
|
|
161
|
+
private loadEntity;
|
|
162
|
+
/**
|
|
163
|
+
* Convert JSONL entity to domain Entity
|
|
164
|
+
*/
|
|
165
|
+
private toEntity;
|
|
166
|
+
/**
|
|
167
|
+
* Find a sudocode entity linked to an external entity
|
|
168
|
+
*/
|
|
169
|
+
private findLinkedEntity;
|
|
170
|
+
/**
|
|
171
|
+
* Update external_links on an entity
|
|
172
|
+
*/
|
|
173
|
+
private updateEntityLinks;
|
|
174
|
+
/**
|
|
175
|
+
* Update the last_synced_at timestamp on a link
|
|
176
|
+
*/
|
|
177
|
+
/**
|
|
178
|
+
* Update the last_synced_at timestamp on a link
|
|
179
|
+
*/
|
|
180
|
+
private updateLinkSyncTime;
|
|
181
|
+
/**
|
|
182
|
+
* Apply partial updates to an entity
|
|
183
|
+
*/
|
|
184
|
+
private applyUpdatesToEntity;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=sync-coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-coordinator.d.ts","sourceRoot":"","sources":["../../src/integrations/sync-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAEV,kBAAkB,EAElB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,aAAa,EAMd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAiBtD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,kEAAkE;IAClE,UAAU,CAAC,EAAE,CACX,QAAQ,EAAE,YAAY,KACnB,OAAO,CAAC,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC,CAAC;CAChD;AAQD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,eAAe;IAId,OAAO,CAAC,OAAO;IAH3B,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,aAAa,CAA2B;gBAE5B,OAAO,EAAE,sBAAsB;IAMnD;;;OAGG;IACH,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAIrD;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAI1D;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAQ5B;;;;;;;;OAQG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAwBtC;;;;OAIG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAe/D;;;;OAIG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAuCzD;;;;;;;OAOG;IACG,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,aAAa,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,GACnE,OAAO,CAAC,IAAI,CAAC;IAgChB;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUvE;;;;;;;;;OASG;IACG,mBAAmB,CACvB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,UAAU,EAAE,CAAC;IA6DxB;;OAEG;YACW,oBAAoB;IA8BlC;;OAEG;YACW,oBAAoB;IA2KlC;;OAEG;YACW,cAAc;IA2H5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAyBtB;;OAEG;YACW,eAAe;IA+B7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;OAEG;IACH,OAAO,CAAC,aAAa;IAIrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH;;OAEG;IACH,OAAO,CAAC,UAAU;IAclB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAMhB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmCxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;OAEG;IACH;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAsB7B"}
|