@dollhousemcp/mcp-server 1.7.1 → 1.7.3

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 (42) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/auth/GitHubAuthManager.js +2 -2
  3. package/dist/config/ConfigManager.d.ts +158 -25
  4. package/dist/config/ConfigManager.d.ts.map +1 -1
  5. package/dist/config/ConfigManager.js +627 -88
  6. package/dist/generated/version.d.ts +2 -2
  7. package/dist/generated/version.js +3 -3
  8. package/dist/handlers/ConfigHandler.d.ts +32 -0
  9. package/dist/handlers/ConfigHandler.d.ts.map +1 -0
  10. package/dist/handlers/ConfigHandler.js +202 -0
  11. package/dist/handlers/SyncHandlerV2.d.ts +42 -0
  12. package/dist/handlers/SyncHandlerV2.d.ts.map +1 -0
  13. package/dist/handlers/SyncHandlerV2.js +231 -0
  14. package/dist/index.d.ts +18 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +19 -3
  17. package/dist/portfolio/GitHubPortfolioIndexer.d.ts +0 -1
  18. package/dist/portfolio/GitHubPortfolioIndexer.d.ts.map +1 -1
  19. package/dist/portfolio/GitHubPortfolioIndexer.js +36 -16
  20. package/dist/portfolio/PortfolioRepoManager.d.ts +2 -1
  21. package/dist/portfolio/PortfolioRepoManager.d.ts.map +1 -1
  22. package/dist/portfolio/PortfolioRepoManager.js +2 -1
  23. package/dist/portfolio/PortfolioSyncManager.d.ts +127 -0
  24. package/dist/portfolio/PortfolioSyncManager.d.ts.map +1 -0
  25. package/dist/portfolio/PortfolioSyncManager.js +818 -0
  26. package/dist/security/audit/config/suppressions.d.ts.map +1 -1
  27. package/dist/security/audit/config/suppressions.js +54 -2
  28. package/dist/security/secureYamlParser.d.ts +46 -2
  29. package/dist/security/secureYamlParser.d.ts.map +1 -1
  30. package/dist/security/secureYamlParser.js +47 -3
  31. package/dist/server/ServerSetup.d.ts.map +1 -1
  32. package/dist/server/ServerSetup.js +16 -10
  33. package/dist/server/tools/ConfigToolsV2.d.ts +10 -0
  34. package/dist/server/tools/ConfigToolsV2.d.ts.map +1 -0
  35. package/dist/server/tools/ConfigToolsV2.js +110 -0
  36. package/dist/server/types.d.ts +2 -0
  37. package/dist/server/types.d.ts.map +1 -1
  38. package/dist/server/types.js +1 -1
  39. package/dist/utils/logger.d.ts +45 -0
  40. package/dist/utils/logger.d.ts.map +1 -1
  41. package/dist/utils/logger.js +202 -9
  42. package/package.json +1 -1
@@ -2,8 +2,8 @@
2
2
  * Auto-generated file - DO NOT EDIT
3
3
  * Generated at build time by scripts/generate-version.js
4
4
  */
5
- export declare const PACKAGE_VERSION = "1.7.1";
6
- export declare const BUILD_TIMESTAMP = "2025-08-31T23:09:37.090Z";
5
+ export declare const PACKAGE_VERSION = "1.7.3";
6
+ export declare const BUILD_TIMESTAMP = "2025-09-09T19:23:32.095Z";
7
7
  export declare const BUILD_TYPE: 'npm' | 'git';
8
8
  export declare const PACKAGE_NAME = "@dollhousemcp/mcp-server";
9
9
  //# sourceMappingURL=version.d.ts.map
@@ -2,8 +2,8 @@
2
2
  * Auto-generated file - DO NOT EDIT
3
3
  * Generated at build time by scripts/generate-version.js
4
4
  */
5
- export const PACKAGE_VERSION = '1.7.1';
6
- export const BUILD_TIMESTAMP = '2025-08-31T23:09:37.090Z';
5
+ export const PACKAGE_VERSION = '1.7.3';
6
+ export const BUILD_TIMESTAMP = '2025-09-09T19:23:32.095Z';
7
7
  export const BUILD_TYPE = 'npm';
8
8
  export const PACKAGE_NAME = '@dollhousemcp/mcp-server';
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nZW5lcmF0ZWQvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDO0FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRywwQkFBMEIsQ0FBQztBQUMxRCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQWtCLEtBQUssQ0FBQztBQUMvQyxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsMEJBQTBCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIGZpbGUgLSBETyBOT1QgRURJVFxuICogR2VuZXJhdGVkIGF0IGJ1aWxkIHRpbWUgYnkgc2NyaXB0cy9nZW5lcmF0ZS12ZXJzaW9uLmpzXG4gKi9cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9ICcxLjcuMSc7XG5leHBvcnQgY29uc3QgQlVJTERfVElNRVNUQU1QID0gJzIwMjUtMDgtMzFUMjM6MDk6MzcuMDkwWic7XG5leHBvcnQgY29uc3QgQlVJTERfVFlQRTogJ25wbScgfCAnZ2l0JyA9ICducG0nO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfTkFNRSA9ICdAZG9sbGhvdXNlbWNwL21jcC1zZXJ2ZXInO1xuIl19
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nZW5lcmF0ZWQvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDO0FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRywwQkFBMEIsQ0FBQztBQUMxRCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQWtCLEtBQUssQ0FBQztBQUMvQyxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsMEJBQTBCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIGZpbGUgLSBETyBOT1QgRURJVFxuICogR2VuZXJhdGVkIGF0IGJ1aWxkIHRpbWUgYnkgc2NyaXB0cy9nZW5lcmF0ZS12ZXJzaW9uLmpzXG4gKi9cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9ICcxLjcuMyc7XG5leHBvcnQgY29uc3QgQlVJTERfVElNRVNUQU1QID0gJzIwMjUtMDktMDlUMTk6MjM6MzIuMDk1Wic7XG5leHBvcnQgY29uc3QgQlVJTERfVFlQRTogJ25wbScgfCAnZ2l0JyA9ICducG0nO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfTkFNRSA9ICdAZG9sbGhvdXNlbWNwL21jcC1zZXJ2ZXInO1xuIl19
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Configuration handler for the dollhouse_config MCP tool
3
+ * Provides unified interface for all configuration management operations
4
+ */
5
+ export interface ConfigOperationOptions {
6
+ action: 'get' | 'set' | 'reset' | 'export' | 'import' | 'wizard';
7
+ setting?: string;
8
+ value?: any;
9
+ section?: string;
10
+ format?: 'yaml' | 'json';
11
+ data?: string;
12
+ }
13
+ export declare class ConfigHandler {
14
+ private configManager;
15
+ constructor();
16
+ /**
17
+ * Handle configuration operations via the dollhouse_config tool
18
+ */
19
+ handleConfigOperation(options: ConfigOperationOptions, indicator?: string): Promise<{
20
+ content: {
21
+ type: string;
22
+ text: string;
23
+ }[];
24
+ }>;
25
+ private handleGet;
26
+ private handleSet;
27
+ private handleReset;
28
+ private handleExport;
29
+ private handleImport;
30
+ private handleWizard;
31
+ }
32
+ //# sourceMappingURL=ConfigHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/ConfigHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAAgB;;IAMrC;;OAEG;IACG,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,EAAE,SAAS,GAAE,MAAW;;;;;;YA4CrE,SAAS;YAkCT,SAAS;YA2CT,WAAW;YAyBX,YAAY;YAeZ,YAAY;IAuB1B,OAAO,CAAC,YAAY;CAsBrB"}
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Configuration handler for the dollhouse_config MCP tool
3
+ * Provides unified interface for all configuration management operations
4
+ */
5
+ import { ConfigManager } from '../config/ConfigManager.js';
6
+ import { SecureErrorHandler } from '../security/errorHandler.js';
7
+ import * as yaml from 'js-yaml';
8
+ export class ConfigHandler {
9
+ configManager;
10
+ constructor() {
11
+ this.configManager = ConfigManager.getInstance();
12
+ }
13
+ /**
14
+ * Handle configuration operations via the dollhouse_config tool
15
+ */
16
+ async handleConfigOperation(options, indicator = '') {
17
+ try {
18
+ await this.configManager.initialize();
19
+ switch (options.action) {
20
+ case 'get':
21
+ return this.handleGet(options, indicator);
22
+ case 'set':
23
+ return this.handleSet(options, indicator);
24
+ case 'reset':
25
+ return this.handleReset(options, indicator);
26
+ case 'export':
27
+ return this.handleExport(options, indicator);
28
+ case 'import':
29
+ return this.handleImport(options, indicator);
30
+ case 'wizard':
31
+ return this.handleWizard(indicator);
32
+ default:
33
+ return {
34
+ content: [{
35
+ type: "text",
36
+ text: `${indicator}❌ Invalid action '${options.action}'.\n\n` +
37
+ `Valid actions: get, set, reset, export, import, wizard`
38
+ }]
39
+ };
40
+ }
41
+ }
42
+ catch (error) {
43
+ const sanitizedError = SecureErrorHandler.sanitizeError(error);
44
+ return {
45
+ content: [{
46
+ type: "text",
47
+ text: `${indicator}❌ Configuration operation failed: ${sanitizedError.message}`
48
+ }]
49
+ };
50
+ }
51
+ }
52
+ async handleGet(options, indicator) {
53
+ // Get a specific setting or all settings
54
+ if (options.setting) {
55
+ const value = this.configManager.getSetting(options.setting);
56
+ if (value === undefined) {
57
+ return {
58
+ content: [{
59
+ type: "text",
60
+ text: `${indicator}❌ Setting '${options.setting}' not found.\n\n` +
61
+ `Use \`dollhouse_config action: "get"\` to see all available settings.`
62
+ }]
63
+ };
64
+ }
65
+ return {
66
+ content: [{
67
+ type: "text",
68
+ text: `${indicator}⚙️ **Configuration Setting**\n\n` +
69
+ `**${options.setting}**: ${JSON.stringify(value, null, 2)}`
70
+ }]
71
+ };
72
+ }
73
+ // Get all settings
74
+ const config = this.configManager.getConfig();
75
+ return {
76
+ content: [{
77
+ type: "text",
78
+ text: `${indicator}⚙️ **DollhouseMCP Configuration**\n\n` +
79
+ `\`\`\`yaml\n${yaml.dump(config, { lineWidth: -1 })}\`\`\``
80
+ }]
81
+ };
82
+ }
83
+ async handleSet(options, indicator) {
84
+ // Set a configuration value
85
+ if (!options.setting || options.value === undefined) {
86
+ return {
87
+ content: [{
88
+ type: "text",
89
+ text: `${indicator}❌ Both 'setting' and 'value' are required for set operation.\n\n` +
90
+ `Example: \`dollhouse_config action: "set", setting: "sync.enabled", value: true\``
91
+ }]
92
+ };
93
+ }
94
+ // Type coercion for common string-to-type conversions
95
+ let coercedValue = options.value;
96
+ // Convert string booleans to actual booleans
97
+ if (typeof coercedValue === 'string') {
98
+ const lowerValue = coercedValue.toLowerCase();
99
+ if (lowerValue === 'true') {
100
+ coercedValue = true;
101
+ }
102
+ else if (lowerValue === 'false') {
103
+ coercedValue = false;
104
+ }
105
+ else if (/^\d+$/.test(coercedValue)) {
106
+ // Convert numeric strings to numbers
107
+ const numValue = parseInt(coercedValue, 10);
108
+ if (!isNaN(numValue)) {
109
+ coercedValue = numValue;
110
+ }
111
+ }
112
+ }
113
+ await this.configManager.updateSetting(options.setting, coercedValue);
114
+ return {
115
+ content: [{
116
+ type: "text",
117
+ text: `${indicator}✅ **Configuration Updated**\n\n` +
118
+ `**${options.setting}** set to: ${JSON.stringify(coercedValue, null, 2)}\n\n` +
119
+ `Changes have been saved to the configuration file.`
120
+ }]
121
+ };
122
+ }
123
+ async handleReset(options, indicator) {
124
+ // Reset configuration to defaults
125
+ if (options.section) {
126
+ await this.configManager.resetConfig(options.section);
127
+ return {
128
+ content: [{
129
+ type: "text",
130
+ text: `${indicator}🔄 **Configuration Reset**\n\n` +
131
+ `Section '${options.section}' has been reset to default values.`
132
+ }]
133
+ };
134
+ }
135
+ // Reset all configuration
136
+ await this.configManager.resetConfig();
137
+ return {
138
+ content: [{
139
+ type: "text",
140
+ text: `${indicator}🔄 **Configuration Reset**\n\n` +
141
+ `All settings have been reset to default values.\n\n` +
142
+ `Note: User identity and GitHub authentication are preserved.`
143
+ }]
144
+ };
145
+ }
146
+ async handleExport(options, indicator) {
147
+ // Export configuration
148
+ const format = options.format || 'yaml';
149
+ const exported = await this.configManager.exportConfig(format);
150
+ return {
151
+ content: [{
152
+ type: "text",
153
+ text: `${indicator}📤 **Configuration Export**\n\n` +
154
+ `\`\`\`${format}\n${exported}\`\`\`\n\n` +
155
+ `You can save this configuration and import it later.`
156
+ }]
157
+ };
158
+ }
159
+ async handleImport(options, indicator) {
160
+ // Import configuration
161
+ if (!options.data) {
162
+ return {
163
+ content: [{
164
+ type: "text",
165
+ text: `${indicator}❌ Configuration data is required for import.\n\n` +
166
+ `Provide YAML or JSON configuration in the 'data' parameter.`
167
+ }]
168
+ };
169
+ }
170
+ await this.configManager.importConfig(options.data);
171
+ return {
172
+ content: [{
173
+ type: "text",
174
+ text: `${indicator}✅ **Configuration Imported**\n\n` +
175
+ `Configuration has been successfully imported and saved.`
176
+ }]
177
+ };
178
+ }
179
+ handleWizard(indicator) {
180
+ // Interactive configuration wizard
181
+ return {
182
+ content: [{
183
+ type: "text",
184
+ text: `${indicator}🧙 **Configuration Wizard**\n\n` +
185
+ `The configuration wizard helps you set up DollhouseMCP.\n\n` +
186
+ `**Key Settings to Configure:**\n\n` +
187
+ `1. **User Identity**\n` +
188
+ ` \`dollhouse_config action: "set", setting: "user.username", value: "your-username"\`\n\n` +
189
+ `2. **GitHub Portfolio**\n` +
190
+ ` \`dollhouse_config action: "set", setting: "github.portfolio.repository_name", value: "dollhouse-portfolio"\`\n\n` +
191
+ `3. **Sync Settings**\n` +
192
+ ` \`dollhouse_config action: "set", setting: "sync.enabled", value: true\`\n` +
193
+ ` \`dollhouse_config action: "set", setting: "sync.bulk.upload_enabled", value: true\`\n\n` +
194
+ `4. **Privacy Settings**\n` +
195
+ ` \`dollhouse_config action: "set", setting: "sync.privacy.scan_for_secrets", value: true\`\n` +
196
+ ` \`dollhouse_config action: "set", setting: "sync.privacy.respect_local_only", value: true\`\n\n` +
197
+ `Run \`dollhouse_config action: "get"\` to see current settings.`
198
+ }]
199
+ };
200
+ }
201
+ }
202
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uZmlnSGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oYW5kbGVycy9Db25maWdIYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNqRSxPQUFPLEtBQUssSUFBSSxNQUFNLFNBQVMsQ0FBQztBQVdoQyxNQUFNLE9BQU8sYUFBYTtJQUNoQixhQUFhLENBQWdCO0lBRXJDO1FBQ0UsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDbkQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLHFCQUFxQixDQUFDLE9BQStCLEVBQUUsWUFBb0IsRUFBRTtRQUNqRixJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLENBQUM7WUFFdEMsUUFBUSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3ZCLEtBQUssS0FBSztvQkFDUixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUU1QyxLQUFLLEtBQUs7b0JBQ1IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFFNUMsS0FBSyxPQUFPO29CQUNWLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBRTlDLEtBQUssUUFBUTtvQkFDWCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUUvQyxLQUFLLFFBQVE7b0JBQ1gsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFFL0MsS0FB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QUF5RDtpQkFDaEUsQ0FBQztTQUNILENBQUM7SUFDSixDQUFDO0lBRU8sWUFBWSxDQUFDLFNBQWlCO1FBQ3BDLG1DQUFtQztRQUNuQyxPQUFPO1lBQ0wsT0FBTyxFQUFFLENBQUM7b0JBQ1IsSUFBSSxFQUFFLE1BQU07b0JBQ1osSUFBSSxFQUFFLEdBQUcsU0FBUyxpQ0FBaUM7d0JBQzdDLDZEQUE2RDt3QkFDN0Qsb0NBQW9DO3dCQUNwQyx3QkFBd0I7d0JBQ3hCLDZGQUE2Rjt3QkFDN0YsMkJBQTJCO3dCQUMzQixzSEFBc0g7d0JBQ3RILHdCQUF3Qjt3QkFDeEIsK0VBQStFO3dCQUMvRSw2RkFBNkY7d0JBQzdGLDJCQUEyQjt3QkFDM0IsZ0dBQWdHO3dCQUNoRyxvR0FBb0c7d0JBQ3BHLGlFQUFpRTtpQkFDeEUsQ0FBQztTQUNILENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbmZpZ3VyYXRpb24gaGFuZGxlciBmb3IgdGhlIGRvbGxob3VzZV9jb25maWcgTUNQIHRvb2xcbiAqIFByb3ZpZGVzIHVuaWZpZWQgaW50ZXJmYWNlIGZvciBhbGwgY29uZmlndXJhdGlvbiBtYW5hZ2VtZW50IG9wZXJhdGlvbnNcbiAqL1xuXG5pbXBvcnQgeyBDb25maWdNYW5hZ2VyIH0gZnJvbSAnLi4vY29uZmlnL0NvbmZpZ01hbmFnZXIuanMnO1xuaW1wb3J0IHsgU2VjdXJlRXJyb3JIYW5kbGVyIH0gZnJvbSAnLi4vc2VjdXJpdHkvZXJyb3JIYW5kbGVyLmpzJztcbmltcG9ydCAqIGFzIHlhbWwgZnJvbSAnanMteWFtbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnT3BlcmF0aW9uT3B0aW9ucyB7XG4gIGFjdGlvbjogJ2dldCcgfCAnc2V0JyB8ICdyZXNldCcgfCAnZXhwb3J0JyB8ICdpbXBvcnQnIHwgJ3dpemFyZCc7XG4gIHNldHRpbmc/OiBzdHJpbmc7XG4gIHZhbHVlPzogYW55O1xuICBzZWN0aW9uPzogc3RyaW5nO1xuICBmb3JtYXQ/OiAneWFtbCcgfCAnanNvbic7XG4gIGRhdGE/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBDb25maWdIYW5kbGVyIHtcbiAgcHJpdmF0ZSBjb25maWdNYW5hZ2VyOiBDb25maWdNYW5hZ2VyO1xuICBcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5jb25maWdNYW5hZ2VyID0gQ29uZmlnTWFuYWdlci5nZXRJbnN0YW5jZSgpO1xuICB9XG4gIFxuICAvKipcbiAgICogSGFuZGxlIGNvbmZpZ3VyYXRpb24gb3BlcmF0aW9ucyB2aWEgdGhlIGRvbGxob3VzZV9jb25maWcgdG9vbFxuICAgKi9cbiAgYXN5bmMgaGFuZGxlQ29uZmlnT3BlcmF0aW9uKG9wdGlvbnM6IENvbmZpZ09wZXJhdGlvbk9wdGlvbnMsIGluZGljYXRvcjogc3RyaW5nID0gJycpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5jb25maWdNYW5hZ2VyLmluaXRpYWxpemUoKTtcbiAgICAgIFxuICAgICAgc3dpdGNoIChvcHRpb25zLmFjdGlvbikge1xuICAgICAgICBjYXNlICdnZXQnOlxuICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZUdldChvcHRpb25zLCBpbmRpY2F0b3IpO1xuICAgICAgICBcbiAgICAgICAgY2FzZSAnc2V0JzpcbiAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVTZXQob3B0aW9ucywgaW5kaWNhdG9yKTtcbiAgICAgICAgXG4gICAgICAgIGNhc2UgJ3Jlc2V0JzpcbiAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZXNldChvcHRpb25zLCBpbmRpY2F0b3IpO1xuICAgICAgICBcbiAgICAgICAgY2FzZSAnZXhwb3J0JzpcbiAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVFeHBvcnQob3B0aW9ucywgaW5kaWNhdG9yKTtcbiAgICAgICAgXG4gICAgICAgIGNhc2UgJ2ltcG9ydCc6XG4gICAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlSW1wb3J0KG9wdGlvbnMsIGluZGljYXRvcik7XG4gICAgICAgIFxuICAgICAgICBjYXNlICd3aXphcmQnOlxuICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVdpemFyZChpbmRpY2F0b3IpO1xuICAgICAgICBcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgIHRleHQ6IGAke2luZGljYXRvcn3inYwgSW52YWxpZCBhY3Rpb24gJyR7b3B0aW9ucy5hY3Rpb259Jy5cXG5cXG5gICtcbiAgICAgICAgICAgICAgICAgICAgYFZhbGlkIGFjdGlvbnM6IGdldCwgc2V0LCByZXNldCwgZXhwb3J0LCBpbXBvcnQsIHdpemFyZGBcbiAgICAgICAgICAgIH1dXG4gICAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCBzYW5pdGl6ZWRFcnJvciA9IFNlY3VyZUVycm9ySGFuZGxlci5zYW5pdGl6ZUVycm9yKGVycm9yKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yfeKdjCBDb25maWd1cmF0aW9uIG9wZXJhdGlvbiBmYWlsZWQ6ICR7c2FuaXRpemVkRXJyb3IubWVzc2FnZX1gXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBcbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVHZXQob3B0aW9uczogQ29uZmlnT3BlcmF0aW9uT3B0aW9ucywgaW5kaWNhdG9yOiBzdHJpbmcpIHtcbiAgICAvLyBHZXQgYSBzcGVjaWZpYyBzZXR0aW5nIG9yIGFsbCBzZXR0aW5nc1xuICAgIGlmIChvcHRpb25zLnNldHRpbmcpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5jb25maWdNYW5hZ2VyLmdldFNldHRpbmcob3B0aW9ucy5zZXR0aW5nKTtcbiAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yfeKdjCBTZXR0aW5nICcke29wdGlvbnMuc2V0dGluZ30nIG5vdCBmb3VuZC5cXG5cXG5gICtcbiAgICAgICAgICAgICAgICAgIGBVc2UgXFxgZG9sbGhvdXNlX2NvbmZpZyBhY3Rpb246IFwiZ2V0XCJcXGAgdG8gc2VlIGFsbCBhdmFpbGFibGUgc2V0dGluZ3MuYFxuICAgICAgICAgIH1dXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yfeKame+4jyAqKkNvbmZpZ3VyYXRpb24gU2V0dGluZyoqXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYCoqJHtvcHRpb25zLnNldHRpbmd9Kio6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUsIG51bGwsIDIpfWBcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuICAgIFxuICAgIC8vIEdldCBhbGwgc2V0dGluZ3NcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZ01hbmFnZXIuZ2V0Q29uZmlnKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBgJHtpbmRpY2F0b3J94pqZ77iPICoqRG9sbGhvdXNlTUNQIENvbmZpZ3VyYXRpb24qKlxcblxcbmAgK1xuICAgICAgICAgICAgICBgXFxgXFxgXFxgeWFtbFxcbiR7eWFtbC5kdW1wKGNvbmZpZywgeyBsaW5lV2lkdGg6IC0xIH0pfVxcYFxcYFxcYGBcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxuICBcbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVTZXQob3B0aW9uczogQ29uZmlnT3BlcmF0aW9uT3B0aW9ucywgaW5kaWNhdG9yOiBzdHJpbmcpIHtcbiAgICAvLyBTZXQgYSBjb25maWd1cmF0aW9uIHZhbHVlXG4gICAgaWYgKCFvcHRpb25zLnNldHRpbmcgfHwgb3B0aW9ucy52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke2luZGljYXRvcn3inYwgQm90aCAnc2V0dGluZycgYW5kICd2YWx1ZScgYXJlIHJlcXVpcmVkIGZvciBzZXQgb3BlcmF0aW9uLlxcblxcbmAgK1xuICAgICAgICAgICAgICAgIGBFeGFtcGxlOiBcXGBkb2xsaG91c2VfY29uZmlnIGFjdGlvbjogXCJzZXRcIiwgc2V0dGluZzogXCJzeW5jLmVuYWJsZWRcIiwgdmFsdWU6IHRydWVcXGBgXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgICBcbiAgICAvLyBUeXBlIGNvZXJjaW9uIGZvciBjb21tb24gc3RyaW5nLXRvLXR5cGUgY29udmVyc2lvbnNcbiAgICBsZXQgY29lcmNlZFZhbHVlID0gb3B0aW9ucy52YWx1ZTtcbiAgICBcbiAgICAvLyBDb252ZXJ0IHN0cmluZyBib29sZWFucyB0byBhY3R1YWwgYm9vbGVhbnNcbiAgICBpZiAodHlwZW9mIGNvZXJjZWRWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IGxvd2VyVmFsdWUgPSBjb2VyY2VkVmFsdWUudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChsb3dlclZhbHVlID09PSAndHJ1ZScpIHtcbiAgICAgICAgY29lcmNlZFZhbHVlID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSBpZiAobG93ZXJWYWx1ZSA9PT0gJ2ZhbHNlJykge1xuICAgICAgICBjb2VyY2VkVmFsdWUgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAoL15cXGQrJC8udGVzdChjb2VyY2VkVmFsdWUpKSB7XG4gICAgICAgIC8vIENvbnZlcnQgbnVtZXJpYyBzdHJpbmdzIHRvIG51bWJlcnNcbiAgICAgICAgY29uc3QgbnVtVmFsdWUgPSBwYXJzZUludChjb2VyY2VkVmFsdWUsIDEwKTtcbiAgICAgICAgaWYgKCFpc05hTihudW1WYWx1ZSkpIHtcbiAgICAgICAgICBjb2VyY2VkVmFsdWUgPSBudW1WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICBhd2FpdCB0aGlzLmNvbmZpZ01hbmFnZXIudXBkYXRlU2V0dGluZyhvcHRpb25zLnNldHRpbmcsIGNvZXJjZWRWYWx1ZSk7XG4gICAgXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBgJHtpbmRpY2F0b3J94pyFICoqQ29uZmlndXJhdGlvbiBVcGRhdGVkKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYCoqJHtvcHRpb25zLnNldHRpbmd9Kiogc2V0IHRvOiAke0pTT04uc3RyaW5naWZ5KGNvZXJjZWRWYWx1ZSwgbnVsbCwgMil9XFxuXFxuYCArXG4gICAgICAgICAgICAgIGBDaGFuZ2VzIGhhdmUgYmVlbiBzYXZlZCB0byB0aGUgY29uZmlndXJhdGlvbiBmaWxlLmBcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxuICBcbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVSZXNldChvcHRpb25zOiBDb25maWdPcGVyYXRpb25PcHRpb25zLCBpbmRpY2F0b3I6IHN0cmluZykge1xuICAgIC8vIFJlc2V0IGNvbmZpZ3VyYXRpb24gdG8gZGVmYXVsdHNcbiAgICBpZiAob3B0aW9ucy5zZWN0aW9uKSB7XG4gICAgICBhd2FpdCB0aGlzLmNvbmZpZ01hbmFnZXIucmVzZXRDb25maWcob3B0aW9ucy5zZWN0aW9uKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yffCflIQgKipDb25maWd1cmF0aW9uIFJlc2V0KipcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgU2VjdGlvbiAnJHtvcHRpb25zLnNlY3Rpb259JyBoYXMgYmVlbiByZXNldCB0byBkZWZhdWx0IHZhbHVlcy5gXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgICBcbiAgICAvLyBSZXNldCBhbGwgY29uZmlndXJhdGlvblxuICAgIGF3YWl0IHRoaXMuY29uZmlnTWFuYWdlci5yZXNldENvbmZpZygpO1xuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbe1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yffCflIQgKipDb25maWd1cmF0aW9uIFJlc2V0KipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYEFsbCBzZXR0aW5ncyBoYXZlIGJlZW4gcmVzZXQgdG8gZGVmYXVsdCB2YWx1ZXMuXFxuXFxuYCArXG4gICAgICAgICAgICAgIGBOb3RlOiBVc2VyIGlkZW50aXR5IGFuZCBHaXRIdWIgYXV0aGVudGljYXRpb24gYXJlIHByZXNlcnZlZC5gXG4gICAgICB9XVxuICAgIH07XG4gIH1cbiAgXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlRXhwb3J0KG9wdGlvbnM6IENvbmZpZ09wZXJhdGlvbk9wdGlvbnMsIGluZGljYXRvcjogc3RyaW5nKSB7XG4gICAgLy8gRXhwb3J0IGNvbmZpZ3VyYXRpb25cbiAgICBjb25zdCBmb3JtYXQgPSBvcHRpb25zLmZvcm1hdCB8fCAneWFtbCc7XG4gICAgY29uc3QgZXhwb3J0ZWQgPSBhd2FpdCB0aGlzLmNvbmZpZ01hbmFnZXIuZXhwb3J0Q29uZmlnKGZvcm1hdCk7XG4gICAgXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBgJHtpbmRpY2F0b3J98J+TpCAqKkNvbmZpZ3VyYXRpb24gRXhwb3J0KipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYFxcYFxcYFxcYCR7Zm9ybWF0fVxcbiR7ZXhwb3J0ZWR9XFxgXFxgXFxgXFxuXFxuYCArXG4gICAgICAgICAgICAgIGBZb3UgY2FuIHNhdmUgdGhpcyBjb25maWd1cmF0aW9uIGFuZCBpbXBvcnQgaXQgbGF0ZXIuYFxuICAgICAgfV1cbiAgICB9O1xuICB9XG4gIFxuICBwcml2YXRlIGFzeW5jIGhhbmRsZUltcG9ydChvcHRpb25zOiBDb25maWdPcGVyYXRpb25PcHRpb25zLCBpbmRpY2F0b3I6IHN0cmluZykge1xuICAgIC8vIEltcG9ydCBjb25maWd1cmF0aW9uXG4gICAgaWYgKCFvcHRpb25zLmRhdGEpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yfeKdjCBDb25maWd1cmF0aW9uIGRhdGEgaXMgcmVxdWlyZWQgZm9yIGltcG9ydC5cXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgUHJvdmlkZSBZQU1MIG9yIEpTT04gY29uZmlndXJhdGlvbiBpbiB0aGUgJ2RhdGEnIHBhcmFtZXRlci5gXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgICBcbiAgICBhd2FpdCB0aGlzLmNvbmZpZ01hbmFnZXIuaW1wb3J0Q29uZmlnKG9wdGlvbnMuZGF0YSk7XG4gICAgXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBgJHtpbmRpY2F0b3J94pyFICoqQ29uZmlndXJhdGlvbiBJbXBvcnRlZCoqXFxuXFxuYCArXG4gICAgICAgICAgICAgIGBDb25maWd1cmF0aW9uIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBpbXBvcnRlZCBhbmQgc2F2ZWQuYFxuICAgICAgfV1cbiAgICB9O1xuICB9XG4gIFxuICBwcml2YXRlIGhhbmRsZVdpemFyZChpbmRpY2F0b3I6IHN0cmluZykge1xuICAgIC8vIEludGVyYWN0aXZlIGNvbmZpZ3VyYXRpb24gd2l6YXJkXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBgJHtpbmRpY2F0b3J98J+nmSAqKkNvbmZpZ3VyYXRpb24gV2l6YXJkKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYFRoZSBjb25maWd1cmF0aW9uIHdpemFyZCBoZWxwcyB5b3Ugc2V0IHVwIERvbGxob3VzZU1DUC5cXG5cXG5gICtcbiAgICAgICAgICAgICAgYCoqS2V5IFNldHRpbmdzIHRvIENvbmZpZ3VyZToqKlxcblxcbmAgK1xuICAgICAgICAgICAgICBgMS4gKipVc2VyIElkZW50aXR5KipcXG5gICtcbiAgICAgICAgICAgICAgYCAgIFxcYGRvbGxob3VzZV9jb25maWcgYWN0aW9uOiBcInNldFwiLCBzZXR0aW5nOiBcInVzZXIudXNlcm5hbWVcIiwgdmFsdWU6IFwieW91ci11c2VybmFtZVwiXFxgXFxuXFxuYCArXG4gICAgICAgICAgICAgIGAyLiAqKkdpdEh1YiBQb3J0Zm9saW8qKlxcbmAgK1xuICAgICAgICAgICAgICBgICAgXFxgZG9sbGhvdXNlX2NvbmZpZyBhY3Rpb246IFwic2V0XCIsIHNldHRpbmc6IFwiZ2l0aHViLnBvcnRmb2xpby5yZXBvc2l0b3J5X25hbWVcIiwgdmFsdWU6IFwiZG9sbGhvdXNlLXBvcnRmb2xpb1wiXFxgXFxuXFxuYCArXG4gICAgICAgICAgICAgIGAzLiAqKlN5bmMgU2V0dGluZ3MqKlxcbmAgK1xuICAgICAgICAgICAgICBgICAgXFxgZG9sbGhvdXNlX2NvbmZpZyBhY3Rpb246IFwic2V0XCIsIHNldHRpbmc6IFwic3luYy5lbmFibGVkXCIsIHZhbHVlOiB0cnVlXFxgXFxuYCArXG4gICAgICAgICAgICAgIGAgICBcXGBkb2xsaG91c2VfY29uZmlnIGFjdGlvbjogXCJzZXRcIiwgc2V0dGluZzogXCJzeW5jLmJ1bGsudXBsb2FkX2VuYWJsZWRcIiwgdmFsdWU6IHRydWVcXGBcXG5cXG5gICtcbiAgICAgICAgICAgICAgYDQuICoqUHJpdmFjeSBTZXR0aW5ncyoqXFxuYCArXG4gICAgICAgICAgICAgIGAgICBcXGBkb2xsaG91c2VfY29uZmlnIGFjdGlvbjogXCJzZXRcIiwgc2V0dGluZzogXCJzeW5jLnByaXZhY3kuc2Nhbl9mb3Jfc2VjcmV0c1wiLCB2YWx1ZTogdHJ1ZVxcYFxcbmAgK1xuICAgICAgICAgICAgICBgICAgXFxgZG9sbGhvdXNlX2NvbmZpZyBhY3Rpb246IFwic2V0XCIsIHNldHRpbmc6IFwic3luYy5wcml2YWN5LnJlc3BlY3RfbG9jYWxfb25seVwiLCB2YWx1ZTogdHJ1ZVxcYFxcblxcbmAgK1xuICAgICAgICAgICAgICBgUnVuIFxcYGRvbGxob3VzZV9jb25maWcgYWN0aW9uOiBcImdldFwiXFxgIHRvIHNlZSBjdXJyZW50IHNldHRpbmdzLmBcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxufSJdfQ==
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Portfolio sync handler for the sync_portfolio MCP tool
3
+ * Manages bi-directional synchronization between local portfolio and GitHub
4
+ * This V2 version works with the actual PortfolioSyncManager implementation
5
+ */
6
+ import { ElementType } from '../portfolio/PortfolioManager.js';
7
+ export interface SyncOperationOptions {
8
+ operation: 'list-remote' | 'download' | 'upload' | 'compare' | 'bulk-download' | 'bulk-upload';
9
+ element_name?: string;
10
+ element_type?: ElementType;
11
+ filter?: {
12
+ type?: ElementType;
13
+ author?: string;
14
+ updated_after?: string;
15
+ };
16
+ options?: {
17
+ force?: boolean;
18
+ dry_run?: boolean;
19
+ include_private?: boolean;
20
+ };
21
+ }
22
+ export declare class SyncHandler {
23
+ private syncManager;
24
+ private configManager;
25
+ constructor();
26
+ /**
27
+ * Handle portfolio sync operations
28
+ */
29
+ handleSyncOperation(options: SyncOperationOptions, indicator?: string): Promise<{
30
+ content: {
31
+ type: string;
32
+ text: string;
33
+ }[];
34
+ }>;
35
+ private mapOperation;
36
+ private formatResult;
37
+ private formatListResult;
38
+ private formatDownloadResult;
39
+ private formatUploadResult;
40
+ private formatCompareResult;
41
+ }
42
+ //# sourceMappingURL=SyncHandlerV2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyncHandlerV2.d.ts","sourceRoot":"","sources":["../../src/handlers/SyncHandlerV2.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAG/D,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,aAAa,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,eAAe,GAAG,aAAa,CAAC;IAC/F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,WAAW,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,CAAC;CACH;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAAgB;;IAOrC;;OAEG;IACG,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,EAAE,SAAS,GAAE,MAAW;;;;;;IAgD/E,OAAO,CAAC,YAAY;IAiBpB,OAAO,CAAC,YAAY;IAmCpB,OAAO,CAAC,gBAAgB;IAgDxB,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,kBAAkB;IA2B1B,OAAO,CAAC,mBAAmB;CAmC5B"}
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Portfolio sync handler for the sync_portfolio MCP tool
3
+ * Manages bi-directional synchronization between local portfolio and GitHub
4
+ * This V2 version works with the actual PortfolioSyncManager implementation
5
+ */
6
+ import { PortfolioSyncManager } from '../portfolio/PortfolioSyncManager.js';
7
+ import { ConfigManager } from '../config/ConfigManager.js';
8
+ import { SecureErrorHandler } from '../security/errorHandler.js';
9
+ export class SyncHandler {
10
+ syncManager;
11
+ configManager;
12
+ constructor() {
13
+ this.syncManager = new PortfolioSyncManager();
14
+ this.configManager = ConfigManager.getInstance();
15
+ }
16
+ /**
17
+ * Handle portfolio sync operations
18
+ */
19
+ async handleSyncOperation(options, indicator = '') {
20
+ try {
21
+ await this.configManager.initialize();
22
+ // Check if sync is enabled (allow list-remote and compare even when disabled)
23
+ const syncEnabled = this.configManager.getSetting('sync.enabled');
24
+ const readOnlyOperations = ['list-remote', 'compare'];
25
+ if (!syncEnabled && !readOnlyOperations.includes(options.operation)) {
26
+ return {
27
+ content: [{
28
+ type: "text",
29
+ text: `${indicator}⚠️ **Sync is Disabled**\n\n` +
30
+ `Portfolio sync is currently disabled for privacy.\n\n` +
31
+ `To enable sync:\n` +
32
+ `\`dollhouse_config action: "set", setting: "sync.enabled", value: true\`\n\n` +
33
+ `You can still use \`list-remote\` and \`compare\` to view differences.`
34
+ }]
35
+ };
36
+ }
37
+ // Map our operation to PortfolioSyncManager's SyncOperation format
38
+ const syncOp = {
39
+ operation: this.mapOperation(options.operation),
40
+ element_name: options.element_name,
41
+ element_type: options.element_type || options.filter?.type, // Use filter.type if element_type not provided
42
+ bulk: options.operation.includes('bulk'),
43
+ show_diff: options.operation === 'compare',
44
+ force: options.options?.force,
45
+ confirm: options.options?.force || options.options?.dry_run === false // force implies confirm, dry_run=false means confirm
46
+ };
47
+ // Call the unified handleSyncOperation method
48
+ const result = await this.syncManager.handleSyncOperation(syncOp);
49
+ // Format the result based on the operation type
50
+ return this.formatResult(result, options, indicator);
51
+ }
52
+ catch (error) {
53
+ const sanitizedError = SecureErrorHandler.sanitizeError(error);
54
+ return {
55
+ content: [{
56
+ type: "text",
57
+ text: `${indicator}❌ Sync operation failed: ${sanitizedError.message}`
58
+ }]
59
+ };
60
+ }
61
+ }
62
+ mapOperation(operation) {
63
+ switch (operation) {
64
+ case 'list-remote':
65
+ return 'list-remote';
66
+ case 'download':
67
+ case 'bulk-download':
68
+ return 'download';
69
+ case 'upload':
70
+ case 'bulk-upload':
71
+ return 'upload';
72
+ case 'compare':
73
+ return 'compare';
74
+ default:
75
+ return 'list-remote';
76
+ }
77
+ }
78
+ formatResult(result, options, indicator) {
79
+ if (!result.success) {
80
+ return {
81
+ content: [{
82
+ type: "text",
83
+ text: `${indicator}❌ ${result.message}`
84
+ }]
85
+ };
86
+ }
87
+ switch (options.operation) {
88
+ case 'list-remote':
89
+ return this.formatListResult(result, indicator);
90
+ case 'download':
91
+ case 'bulk-download':
92
+ return this.formatDownloadResult(result, options, indicator);
93
+ case 'upload':
94
+ case 'bulk-upload':
95
+ return this.formatUploadResult(result, options, indicator);
96
+ case 'compare':
97
+ return this.formatCompareResult(result, options, indicator);
98
+ default:
99
+ return {
100
+ content: [{
101
+ type: "text",
102
+ text: `${indicator}✅ ${result.message}`
103
+ }]
104
+ };
105
+ }
106
+ }
107
+ formatListResult(result, indicator) {
108
+ if (!result.elements || result.elements.length === 0) {
109
+ return {
110
+ content: [{
111
+ type: "text",
112
+ text: `${indicator}📋 **GitHub Portfolio is Empty**\n\n` +
113
+ `No elements found in your GitHub portfolio.\n\n` +
114
+ `Upload elements using:\n` +
115
+ `\`sync_portfolio operation: "upload", element_name: "name", element_type: "type"\``
116
+ }]
117
+ };
118
+ }
119
+ let text = `${indicator}📋 **GitHub Portfolio Contents**\n\n`;
120
+ text += `Found ${result.elements.length} elements:\n\n`;
121
+ // Group by type
122
+ const byType = {};
123
+ for (const element of result.elements) {
124
+ if (!byType[element.type]) {
125
+ byType[element.type] = [];
126
+ }
127
+ byType[element.type].push(element);
128
+ }
129
+ for (const [type, elements] of Object.entries(byType)) {
130
+ text += `**${type}** (${elements.length}):\n`;
131
+ for (const element of elements) {
132
+ text += ` • ${element.name}`;
133
+ if (element.remoteVersion) {
134
+ text += ` v${element.remoteVersion}`;
135
+ }
136
+ if (element.status) {
137
+ text += ` (${element.status})`;
138
+ }
139
+ text += '\n';
140
+ }
141
+ text += '\n';
142
+ }
143
+ return {
144
+ content: [{
145
+ type: "text",
146
+ text
147
+ }]
148
+ };
149
+ }
150
+ formatDownloadResult(result, options, indicator) {
151
+ if (options.operation === 'bulk-download') {
152
+ const elements = result.elements || [];
153
+ const downloaded = elements.filter(e => e.action === 'download').length;
154
+ const skipped = elements.filter(e => e.action === 'skip').length;
155
+ return {
156
+ content: [{
157
+ type: "text",
158
+ text: `${indicator}✅ **Bulk Download Complete**\n\n` +
159
+ `Downloaded: ${downloaded} elements\n` +
160
+ `Skipped: ${skipped} elements\n\n` +
161
+ result.message
162
+ }]
163
+ };
164
+ }
165
+ return {
166
+ content: [{
167
+ type: "text",
168
+ text: `${indicator}✅ **Element Downloaded**\n\n` +
169
+ `Element: ${options.element_name} (${options.element_type})\n\n` +
170
+ result.message
171
+ }]
172
+ };
173
+ }
174
+ formatUploadResult(result, options, indicator) {
175
+ if (options.operation === 'bulk-upload') {
176
+ const elements = result.elements || [];
177
+ const uploaded = elements.filter(e => e.action === 'upload').length;
178
+ const skipped = elements.filter(e => e.action === 'skip').length;
179
+ return {
180
+ content: [{
181
+ type: "text",
182
+ text: `${indicator}✅ **Bulk Upload Complete**\n\n` +
183
+ `Uploaded: ${uploaded} elements\n` +
184
+ `Skipped: ${skipped} elements\n\n` +
185
+ result.message
186
+ }]
187
+ };
188
+ }
189
+ return {
190
+ content: [{
191
+ type: "text",
192
+ text: `${indicator}✅ **Element Uploaded**\n\n` +
193
+ `Element: ${options.element_name} (${options.element_type})\n\n` +
194
+ result.message
195
+ }]
196
+ };
197
+ }
198
+ formatCompareResult(result, options, indicator) {
199
+ let text = `${indicator}🔍 **Version Comparison**\n\n`;
200
+ text += `Element: ${options.element_name} (${options.element_type})\n\n`;
201
+ if (result.data) {
202
+ // If we have detailed comparison data
203
+ const data = result.data;
204
+ if (data.local) {
205
+ text += `**Local Version**: ${data.local.version}\n`;
206
+ text += ` Modified: ${new Date(data.local.timestamp).toLocaleString()}\n`;
207
+ }
208
+ else {
209
+ text += `**Local Version**: Not found\n`;
210
+ }
211
+ if (data.remote) {
212
+ text += `\n**Remote Version**: ${data.remote.version}\n`;
213
+ text += ` Modified: ${new Date(data.remote.timestamp).toLocaleString()}\n`;
214
+ }
215
+ else {
216
+ text += `\n**Remote Version**: Not found\n`;
217
+ }
218
+ if (data.diff) {
219
+ text += `\n**Differences**:\n${data.diff}`;
220
+ }
221
+ }
222
+ text += `\n\n${result.message}`;
223
+ return {
224
+ content: [{
225
+ type: "text",
226
+ text
227
+ }]
228
+ };
229
+ }
230
+ }
231
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3luY0hhbmRsZXJWMi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oYW5kbGVycy9TeW5jSGFuZGxlclYyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQUUsb0JBQW9CLEVBQTZCLE1BQU0sc0NBQXNDLENBQUM7QUFDdkcsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzNELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBb0JqRSxNQUFNLE9BQU8sV0FBVztJQUNkLFdBQVcsQ0FBdUI7SUFDbEMsYUFBYSxDQUFnQjtJQUVyQztRQUNFLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxvQkFBb0IsRUFBRSxDQUFDO1FBQzlDLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ25ELENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxPQUE2QixFQUFFLFlBQW9CLEVBQUU7UUFDN0UsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBRXRDLDhFQUE4RTtZQUM5RSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNsRSxNQUFNLGtCQUFrQixHQUFHLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3RELElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BFLE9BQU87b0JBQ0wsT0FBTyxFQUFFLENBQUM7NEJBQ1IsSUFBSSxFQUFFLE1BQU07NEJBQ1osSUFBSSxFQUFFLEdBQUcsU0FBUyw2QkFBNkI7Z0NBQ3pDLHVEQUF1RDtnQ0FDdkQsbUJBQW1CO2dDQUNu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QztZQUM5QyxDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2QsSUFBSSxJQUFJLHVCQUF1QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDN0MsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLElBQUksT0FBTyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFaEMsT0FBTztZQUNMLE9BQU8sRUFBRSxDQUFDO29CQUNSLElBQUksRUFBRSxNQUFNO29CQUNaLElBQUk7aUJBQ0wsQ0FBQztTQUNILENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBvcnRmb2xpbyBzeW5jIGhhbmRsZXIgZm9yIHRoZSBzeW5jX3BvcnRmb2xpbyBNQ1AgdG9vbFxuICogTWFuYWdlcyBiaS1kaXJlY3Rpb25hbCBzeW5jaHJvbml6YXRpb24gYmV0d2VlbiBsb2NhbCBwb3J0Zm9saW8gYW5kIEdpdEh1YlxuICogVGhpcyBWMiB2ZXJzaW9uIHdvcmtzIHdpdGggdGhlIGFjdHVhbCBQb3J0Zm9saW9TeW5jTWFuYWdlciBpbXBsZW1lbnRhdGlvblxuICovXG5cbmltcG9ydCB7IFBvcnRmb2xpb1N5bmNNYW5hZ2VyLCBTeW5jT3BlcmF0aW9uLCBTeW5jUmVzdWx0IH0gZnJvbSAnLi4vcG9ydGZvbGlvL1BvcnRmb2xpb1N5bmNNYW5hZ2VyLmpzJztcbmltcG9ydCB7IENvbmZpZ01hbmFnZXIgfSBmcm9tICcuLi9jb25maWcvQ29uZmlnTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBTZWN1cmVFcnJvckhhbmRsZXIgfSBmcm9tICcuLi9zZWN1cml0eS9lcnJvckhhbmRsZXIuanMnO1xuaW1wb3J0IHsgRWxlbWVudFR5cGUgfSBmcm9tICcuLi9wb3J0Zm9saW8vUG9ydGZvbGlvTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN5bmNPcGVyYXRpb25PcHRpb25zIHtcbiAgb3BlcmF0aW9uOiAnbGlzdC1yZW1vdGUnIHwgJ2Rvd25sb2FkJyB8ICd1cGxvYWQnIHwgJ2NvbXBhcmUnIHwgJ2J1bGstZG93bmxvYWQnIHwgJ2J1bGstdXBsb2FkJztcbiAgZWxlbWVudF9uYW1lPzogc3RyaW5nO1xuICBlbGVtZW50X3R5cGU/OiBFbGVtZW50VHlwZTtcbiAgZmlsdGVyPzoge1xuICAgIHR5cGU/OiBFbGVtZW50VHlwZTtcbiAgICBhdXRob3I/OiBzdHJpbmc7XG4gICAgdXBkYXRlZF9hZnRlcj86IHN0cmluZztcbiAgfTtcbiAgb3B0aW9ucz86IHtcbiAgICBmb3JjZT86IGJvb2xlYW47XG4gICAgZHJ5X3J1bj86IGJvb2xlYW47XG4gICAgaW5jbHVkZV9wcml2YXRlPzogYm9vbGVhbjtcbiAgfTtcbn1cblxuZXhwb3J0IGNsYXNzIFN5bmNIYW5kbGVyIHtcbiAgcHJpdmF0ZSBzeW5jTWFuYWdlcjogUG9ydGZvbGlvU3luY01hbmFnZXI7XG4gIHByaXZhdGUgY29uZmlnTWFuYWdlcjogQ29uZmlnTWFuYWdlcjtcbiAgXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuc3luY01hbmFnZXIgPSBuZXcgUG9ydGZvbGlvU3luY01hbmFnZXIoKTtcbiAgICB0aGlzLmNvbmZpZ01hbmFnZXIgPSBDb25maWdNYW5hZ2VyLmdldEluc3RhbmNlKCk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBIYW5kbGUgcG9ydGZvbGlvIHN5bmMgb3BlcmF0aW9uc1xuICAgKi9cbiAgYXN5bmMgaGFuZGxlU3luY09wZXJhdGlvbihvcHRpb25zOiBTeW5jT3BlcmF0aW9uT3B0aW9ucywgaW5kaWNhdG9yOiBzdHJpbmcgPSAnJykge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNvbmZpZ01hbmFnZXIuaW5pdGlhbGl6ZSgpO1xuICAgICAgXG4gICAgICAvLyBDaGVjayBpZiBzeW5jIGlzIGVuYWJsZWQgKGFsbG93IGxpc3QtcmVtb3RlIGFuZCBjb21wYXJlIGV2ZW4gd2hlbiBkaXNhYmxlZClcbiAgICAgIGNvbnN0IHN5bmNFbmFibGVkID0gdGhpcy5jb25maWdNYW5hZ2VyLmdldFNldHRpbmcoJ3N5bmMuZW5hYmxlZCcpO1xuICAgICAgY29uc3QgcmVhZE9ubHlPcGVyYXRpb25zID0gWydsaXN0LXJlbW90ZScsICdjb21wYXJlJ107XG4gICAgICBpZiAoIXN5bmNFbmFibGVkICYmICFyZWFkT25seU9wZXJhdGlvbnMuaW5jbHVkZXMob3B0aW9ucy5vcGVyYXRpb24pKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yfeKaoO+4jyAqKlN5bmMgaXMgRGlzYWJsZWQqKlxcblxcbmAgK1xuICAgICAgICAgICAgICAgICAgYFBvcnRmb2xpbyBzeW5jIGlzIGN1cnJlbnRseSBkaXNhYmxlZCBmb3IgcHJpdmFjeS5cXG5cXG5gICtcbiAgICAgICAgICAgICAgICAgIGBUbyBlbmFibGUgc3luYzpcXG5gICtcbiAgICAgICAgICAgICAgICAgIGBcXGBkb2xsaG91c2VfY29uZmlnIGFjdGlvbjogXCJzZXRcIiwgc2V0dGluZzogXCJzeW5jLmVuYWJsZWRcIiwgdmFsdWU6IHRydWVcXGBcXG5cXG5gICtcbiAgICAgICAgICAgICAgICAgIGBZb3UgY2FuIHN0aWxsIHVzZSBcXGBsaXN0LXJlbW90ZVxcYCBhbmQgXFxgY29tcGFyZVxcYCB0byB2aWV3IGRpZmZlcmVuY2VzLmBcbiAgICAgICAgICB9XVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBNYXAgb3VyIG9wZXJhdGlvbiB0byBQb3J0Zm9saW9TeW5jTWFuYWdlcidzIFN5bmNPcGVyYXRpb24gZm9ybWF0XG4gICAgICBjb25zdCBzeW5jT3A6IFN5bmNPcGVyYXRpb24gPSB7XG4gICAgICAgIG9wZXJhdGlvbjogdGhpcy5tYXBPcGVyYXRpb24ob3B0aW9ucy5vcGVyYXRpb24pLFxuICAgICAgICBlbGVtZW50X25hbWU6IG9wdGlvbnMuZWxlbWVudF9uYW1lLFxuICAgICAgICBlbGVtZW50X3R5cGU6IG9wdGlvbnMuZWxlbWVudF90eXBlIHx8IG9wdGlvbnMuZmlsdGVyPy50eXBlLCAvLyBVc2UgZmlsdGVyLnR5cGUgaWYgZWxlbWVudF90eXBlIG5vdCBwcm92aWRlZFxuICAgICAgICBidWxrOiBvcHRpb25zLm9wZXJhdGlvbi5pbmNsdWRlcygnYnVsaycpLFxuICAgICAgICBzaG93X2RpZmY6IG9wdGlvbnMub3BlcmF0aW9uID09PSAnY29tcGFyZScsXG4gICAgICAgIGZvcmNlOiBvcHRpb25zLm9wdGlvbnM/LmZvcmNlLFxuICAgICAgICBjb25maXJtOiBvcHRpb25zLm9wdGlvbnM/LmZvcmNlIHx8IG9wdGlvbnMub3B0aW9ucz8uZHJ5X3J1biA9PT0gZmFsc2UgLy8gZm9yY2UgaW1wbGllcyBjb25maXJtLCBkcnlfcnVuPWZhbHNlIG1lYW5zIGNvbmZpcm1cbiAgICAgIH07XG4gICAgICBcbiAgICAgIC8vIENhbGwgdGhlIHVuaWZpZWQgaGFuZGxlU3luY09wZXJhdGlvbiBtZXRob2RcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc3luY01hbmFnZXIuaGFuZGxlU3luY09wZXJhdGlvbihzeW5jT3ApO1xuICAgICAgXG4gICAgICAvLyBGb3JtYXQgdGhlIHJlc3VsdCBiYXNlZCBvbiB0aGUgb3BlcmF0aW9uIHR5cGVcbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdFJlc3VsdChyZXN1bHQsIG9wdGlvbnMsIGluZGljYXRvcik7XG4gICAgICBcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc3Qgc2FuaXRpemVkRXJyb3IgPSBTZWN1cmVFcnJvckhhbmRsZXIuc2FuaXRpemVFcnJvcihlcnJvcik7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke2luZGljYXRvcn3inYwgU3luYyBvcGVyYXRpb24gZmFpbGVkOiAke3Nhbml0aXplZEVycm9yLm1lc3NhZ2V9YFxuICAgICAgICB9XVxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgXG4gIHByaXZhdGUgbWFwT3BlcmF0aW9uKG9wZXJhdGlvbjogc3RyaW5nKTogJ2Rvd25sb2FkJyB8ICd1cGxvYWQnIHwgJ2NvbXBhcmUnIHwgJ2xpc3QtcmVtb3RlJyB7XG4gICAgc3dpdGNoIChvcGVyYXRpb24pIHtcbiAgICAgIGNhc2UgJ2xpc3QtcmVtb3RlJzpcbiAgICAgICAgcmV0dXJuICdsaXN0LXJlbW90ZSc7XG4gICAgICBjYXNlICdkb3dubG9hZCc6XG4gICAgICBjYXNlICdidWxrLWRvd25sb2FkJzpcbiAgICAgICAgcmV0dXJuICdkb3dubG9hZCc7XG4gICAgICBjYXNlICd1cGxvYWQnOlxuICAgICAgY2FzZSAnYnVsay11cGxvYWQnOlxuICAgICAgICByZXR1cm4gJ3VwbG9hZCc7XG4gICAgICBjYXNlICdjb21wYXJlJzpcbiAgICAgICAgcmV0dXJuICdjb21wYXJlJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnbGlzdC1yZW1vdGUnO1xuICAgIH1cbiAgfVxuICBcbiAgcHJpdmF0ZSBmb3JtYXRSZXN1bHQocmVzdWx0OiBTeW5jUmVzdWx0LCBvcHRpb25zOiBTeW5jT3BlcmF0aW9uT3B0aW9ucywgaW5kaWNhdG9yOiBzdHJpbmcpIHtcbiAgICBpZiAoIXJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke2luZGljYXRvcn3inYwgJHtyZXN1bHQubWVzc2FnZX1gXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgICBcbiAgICBzd2l0Y2ggKG9wdGlvbnMub3BlcmF0aW9uKSB7XG4gICAgICBjYXNlICdsaXN0LXJlbW90ZSc6XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1hdExpc3RSZXN1bHQocmVzdWx0LCBpbmRpY2F0b3IpO1xuICAgICAgXG4gICAgICBjYXNlICdkb3dubG9hZCc6XG4gICAgICBjYXNlICdidWxrLWRvd25sb2FkJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0RG93bmxvYWRSZXN1bHQocmVzdWx0LCBvcHRpb25zLCBpbmRpY2F0b3IpO1xuICAgICAgXG4gICAgICBjYXNlICd1cGxvYWQnOlxuICAgICAgY2FzZSAnYnVsay11cGxvYWQnOlxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRVcGxvYWRSZXN1bHQocmVzdWx0LCBvcHRpb25zLCBpbmRpY2F0b3IpO1xuICAgICAgXG4gICAgICBjYXNlICdjb21wYXJlJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0Q29tcGFyZVJlc3VsdChyZXN1bHQsIG9wdGlvbnMsIGluZGljYXRvcik7XG4gICAgICBcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yfeKchSAke3Jlc3VsdC5tZXNzYWdlfWBcbiAgICAgICAgICB9XVxuICAgICAgICB9O1xuICAgIH1cbiAgfVxuICBcbiAgcHJpdmF0ZSBmb3JtYXRMaXN0UmVzdWx0KHJlc3VsdDogU3luY1Jlc3VsdCwgaW5kaWNhdG9yOiBzdHJpbmcpIHtcbiAgICBpZiAoIXJlc3VsdC5lbGVtZW50cyB8fCByZXN1bHQuZWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke2luZGljYXRvcn3wn5OLICoqR2l0SHViIFBvcnRmb2xpbyBpcyBFbXB0eSoqXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYE5vIGVsZW1lbnRzIGZvdW5kIGluIHlvdXIgR2l0SHViIHBvcnRmb2xpby5cXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgVXBsb2FkIGVsZW1lbnRzIHVzaW5nOlxcbmAgK1xuICAgICAgICAgICAgICAgIGBcXGBzeW5jX3BvcnRmb2xpbyBvcGVyYXRpb246IFwidXBsb2FkXCIsIGVsZW1lbnRfbmFtZTogXCJuYW1lXCIsIGVsZW1lbnRfdHlwZTogXCJ0eXBlXCJcXGBgXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgICBcbiAgICBsZXQgdGV4dCA9IGAke2luZGljYXRvcn3wn5OLICoqR2l0SHViIFBvcnRmb2xpbyBDb250ZW50cyoqXFxuXFxuYDtcbiAgICB0ZXh0ICs9IGBGb3VuZCAke3Jlc3VsdC5lbGVtZW50cy5sZW5ndGh9IGVsZW1lbnRzOlxcblxcbmA7XG4gICAgXG4gICAgLy8gR3JvdXAgYnkgdHlwZVxuICAgIGNvbnN0IGJ5VHlwZTogUmVjb3JkPHN0cmluZywgYW55W10+ID0ge307XG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHJlc3VsdC5lbGVtZW50cykge1xuICAgICAgaWYgKCFieVR5cGVbZWxlbWVudC50eXBlXSkge1xuICAgICAgICBieVR5cGVbZWxlbWVudC50eXBlXSA9IFtdO1xuICAgICAgfVxuICAgICAgYnlUeXBlW2VsZW1lbnQudHlwZV0ucHVzaChlbGVtZW50KTtcbiAgICB9XG4gICAgXG4gICAgZm9yIChjb25zdCBbdHlwZSwgZWxlbWVudHNdIG9mIE9iamVjdC5lbnRyaWVzKGJ5VHlwZSkpIHtcbiAgICAgIHRleHQgKz0gYCoqJHt0eXBlfSoqICgke2VsZW1lbnRzLmxlbmd0aH0pOlxcbmA7XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpIHtcbiAgICAgICAgdGV4dCArPSBgICDigKIgJHtlbGVtZW50Lm5hbWV9YDtcbiAgICAgICAgaWYgKGVsZW1lbnQucmVtb3RlVmVyc2lvbikge1xuICAgICAgICAgIHRleHQgKz0gYCB2JHtlbGVtZW50LnJlbW90ZVZlcnNpb259YDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZWxlbWVudC5zdGF0dXMpIHtcbiAgICAgICAgICB0ZXh0ICs9IGAgKCR7ZWxlbWVudC5zdGF0dXN9KWA7XG4gICAgICAgIH1cbiAgICAgICAgdGV4dCArPSAnXFxuJztcbiAgICAgIH1cbiAgICAgIHRleHQgKz0gJ1xcbic7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbe1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dFxuICAgICAgfV1cbiAgICB9O1xuICB9XG4gIFxuICBwcml2YXRlIGZvcm1hdERvd25sb2FkUmVzdWx0KHJlc3VsdDogU3luY1Jlc3VsdCwgb3B0aW9uczogU3luY09wZXJhdGlvbk9wdGlvbnMsIGluZGljYXRvcjogc3RyaW5nKSB7XG4gICAgaWYgKG9wdGlvbnMub3BlcmF0aW9uID09PSAnYnVsay1kb3dubG9hZCcpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gcmVzdWx0LmVsZW1lbnRzIHx8IFtdO1xuICAgICAgY29uc3QgZG93bmxvYWRlZCA9IGVsZW1lbnRzLmZpbHRlcihlID0+IGUuYWN0aW9uID09PSAnZG93bmxvYWQnKS5sZW5ndGg7XG4gICAgICBjb25zdCBza2lwcGVkID0gZWxlbWVudHMuZmlsdGVyKGUgPT4gZS5hY3Rpb24gPT09ICdza2lwJykubGVuZ3RoO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke2luZGljYXRvcn3inIUgKipCdWxrIERvd25sb2FkIENvbXBsZXRlKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgRG93bmxvYWRlZDogJHtkb3dubG9hZGVkfSBlbGVtZW50c1xcbmAgK1xuICAgICAgICAgICAgICAgIGBTa2lwcGVkOiAke3NraXBwZWR9IGVsZW1lbnRzXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgcmVzdWx0Lm1lc3NhZ2VcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuICAgIFxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbe1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yfeKchSAqKkVsZW1lbnQgRG93bmxvYWRlZCoqXFxuXFxuYCArXG4gICAgICAgICAgICAgIGBFbGVtZW50OiAke29wdGlvbnMuZWxlbWVudF9uYW1lfSAoJHtvcHRpb25zLmVsZW1lbnRfdHlwZX0pXFxuXFxuYCArXG4gICAgICAgICAgICAgIHJlc3VsdC5tZXNzYWdlXG4gICAgICB9XVxuICAgIH07XG4gIH1cbiAgXG4gIHByaXZhdGUgZm9ybWF0VXBsb2FkUmVzdWx0KHJlc3VsdDogU3luY1Jlc3VsdCwgb3B0aW9uczogU3luY09wZXJhdGlvbk9wdGlvbnMsIGluZGljYXRvcjogc3RyaW5nKSB7XG4gICAgaWYgKG9wdGlvbnMub3BlcmF0aW9uID09PSAnYnVsay11cGxvYWQnKSB7XG4gICAgICBjb25zdCBlbGVtZW50cyA9IHJlc3VsdC5lbGVtZW50cyB8fCBbXTtcbiAgICAgIGNvbnN0IHVwbG9hZGVkID0gZWxlbWVudHMuZmlsdGVyKGUgPT4gZS5hY3Rpb24gPT09ICd1cGxvYWQnKS5sZW5ndGg7XG4gICAgICBjb25zdCBza2lwcGVkID0gZWxlbWVudHMuZmlsdGVyKGUgPT4gZS5hY3Rpb24gPT09ICdza2lwJykubGVuZ3RoO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke2luZGljYXRvcn3inIUgKipCdWxrIFVwbG9hZCBDb21wbGV0ZSoqXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYFVwbG9hZGVkOiAke3VwbG9hZGVkfSBlbGVtZW50c1xcbmAgK1xuICAgICAgICAgICAgICAgIGBTa2lwcGVkOiAke3NraXBwZWR9IGVsZW1lbnRzXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgcmVzdWx0Lm1lc3NhZ2VcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuICAgIFxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbe1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yfeKchSAqKkVsZW1lbnQgVXBsb2FkZWQqKlxcblxcbmAgK1xuICAgICAgICAgICAgICBgRWxlbWVudDogJHtvcHRpb25zLmVsZW1lbnRfbmFtZX0gKCR7b3B0aW9ucy5lbGVtZW50X3R5cGV9KVxcblxcbmAgK1xuICAgICAgICAgICAgICByZXN1bHQubWVzc2FnZVxuICAgICAgfV1cbiAgICB9O1xuICB9XG4gIFxuICBwcml2YXRlIGZvcm1hdENvbXBhcmVSZXN1bHQocmVzdWx0OiBTeW5jUmVzdWx0LCBvcHRpb25zOiBTeW5jT3BlcmF0aW9uT3B0aW9ucywgaW5kaWNhdG9yOiBzdHJpbmcpIHtcbiAgICBsZXQgdGV4dCA9IGAke2luZGljYXRvcn3wn5SNICoqVmVyc2lvbiBDb21wYXJpc29uKipcXG5cXG5gO1xuICAgIHRleHQgKz0gYEVsZW1lbnQ6ICR7b3B0aW9ucy5lbGVtZW50X25hbWV9ICgke29wdGlvbnMuZWxlbWVudF90eXBlfSlcXG5cXG5gO1xuICAgIFxuICAgIGlmIChyZXN1bHQuZGF0YSkge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBkZXRhaWxlZCBjb21wYXJpc29uIGRhdGFcbiAgICAgIGNvbnN0IGRhdGEgPSByZXN1bHQuZGF0YTtcbiAgICAgIGlmIChkYXRhLmxvY2FsKSB7XG4gICAgICAgIHRleHQgKz0gYCoqTG9jYWwgVmVyc2lvbioqOiAke2RhdGEubG9jYWwudmVyc2lvbn1cXG5gO1xuICAgICAgICB0ZXh0ICs9IGAgIE1vZGlmaWVkOiAke25ldyBEYXRlKGRhdGEubG9jYWwudGltZXN0YW1wKS50b0xvY2FsZVN0cmluZygpfVxcbmA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZXh0ICs9IGAqKkxvY2FsIFZlcnNpb24qKjogTm90IGZvdW5kXFxuYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGRhdGEucmVtb3RlKSB7XG4gICAgICAgIHRleHQgKz0gYFxcbioqUmVtb3RlIFZlcnNpb24qKjogJHtkYXRhLnJlbW90ZS52ZXJzaW9ufVxcbmA7XG4gICAgICAgIHRleHQgKz0gYCAgTW9kaWZpZWQ6ICR7bmV3IERhdGUoZGF0YS5yZW1vdGUudGltZXN0YW1wKS50b0xvY2FsZVN0cmluZygpfVxcbmA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZXh0ICs9IGBcXG4qKlJlbW90ZSBWZXJzaW9uKio6IE5vdCBmb3VuZFxcbmA7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGlmIChkYXRhLmRpZmYpIHtcbiAgICAgICAgdGV4dCArPSBgXFxuKipEaWZmZXJlbmNlcyoqOlxcbiR7ZGF0YS5kaWZmfWA7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHRleHQgKz0gYFxcblxcbiR7cmVzdWx0Lm1lc3NhZ2V9YDtcbiAgICBcbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3tcbiAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgIHRleHRcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxufSJdfQ==
package/dist/index.d.ts CHANGED
@@ -416,6 +416,24 @@ export declare class DollhouseMCPServer implements IToolHandler {
416
416
  text: string;
417
417
  }[];
418
418
  }>;
419
+ /**
420
+ * Handle configuration operations - delegates to ConfigHandler
421
+ */
422
+ handleConfigOperation(options: any): Promise<{
423
+ content: {
424
+ type: string;
425
+ text: string;
426
+ }[];
427
+ }>;
428
+ /**
429
+ * Handle sync operations - delegates to SyncHandler
430
+ */
431
+ handleSyncOperation(options: any): Promise<{
432
+ content: {
433
+ type: string;
434
+ text: string;
435
+ }[];
436
+ }>;
419
437
  /**
420
438
  * Search local portfolio using the metadata index system
421
439
  * This provides fast, comprehensive search across all element types