@dollhousemcp/mcp-server 1.7.3 → 1.8.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 (65) hide show
  1. package/dist/collection/CollectionBrowser.js +2 -2
  2. package/dist/collection/CollectionSearch.js +3 -3
  3. package/dist/collection/PersonaDetails.js +2 -2
  4. package/dist/config/ConfigManager.d.ts +20 -0
  5. package/dist/config/ConfigManager.d.ts.map +1 -1
  6. package/dist/config/ConfigManager.js +48 -4
  7. package/dist/config/ConfigWizard.d.ts +78 -0
  8. package/dist/config/ConfigWizard.d.ts.map +1 -0
  9. package/dist/config/ConfigWizard.js +370 -0
  10. package/dist/config/ConfigWizardCheck.d.ts +47 -0
  11. package/dist/config/ConfigWizardCheck.d.ts.map +1 -0
  12. package/dist/config/ConfigWizardCheck.js +208 -0
  13. package/dist/config/portfolioConfig.d.ts +40 -0
  14. package/dist/config/portfolioConfig.d.ts.map +1 -0
  15. package/dist/config/portfolioConfig.js +58 -0
  16. package/dist/config/wizardTemplates.d.ts +84 -0
  17. package/dist/config/wizardTemplates.d.ts.map +1 -0
  18. package/dist/config/wizardTemplates.js +195 -0
  19. package/dist/elements/BaseElement.d.ts +15 -0
  20. package/dist/elements/BaseElement.d.ts.map +1 -1
  21. package/dist/elements/BaseElement.js +38 -5
  22. package/dist/generated/version.d.ts +2 -2
  23. package/dist/generated/version.js +3 -3
  24. package/dist/handlers/ConfigHandler.d.ts +30 -0
  25. package/dist/handlers/ConfigHandler.d.ts.map +1 -1
  26. package/dist/handlers/ConfigHandler.js +149 -21
  27. package/dist/handlers/PortfolioPullHandler.d.ts +69 -0
  28. package/dist/handlers/PortfolioPullHandler.d.ts.map +1 -0
  29. package/dist/handlers/PortfolioPullHandler.js +340 -0
  30. package/dist/index.d.ts +4 -6
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +73 -52
  33. package/dist/portfolio/GitHubPortfolioIndexer.d.ts.map +1 -1
  34. package/dist/portfolio/GitHubPortfolioIndexer.js +8 -5
  35. package/dist/portfolio/PortfolioIndexManager.d.ts +1 -1
  36. package/dist/portfolio/PortfolioIndexManager.js +2 -2
  37. package/dist/portfolio/PortfolioRepoManager.d.ts +16 -2
  38. package/dist/portfolio/PortfolioRepoManager.d.ts.map +1 -1
  39. package/dist/portfolio/PortfolioRepoManager.js +95 -18
  40. package/dist/portfolio/PortfolioSyncManager.d.ts.map +1 -1
  41. package/dist/portfolio/PortfolioSyncManager.js +23 -15
  42. package/dist/security/audit/config/suppressions.d.ts.map +1 -1
  43. package/dist/security/audit/config/suppressions.js +11 -1
  44. package/dist/server/ServerSetup.d.ts.map +1 -1
  45. package/dist/server/ServerSetup.js +11 -6
  46. package/dist/server/tools/CollectionTools.js +6 -6
  47. package/dist/server/tools/ConfigTools.js +2 -2
  48. package/dist/server/tools/ConfigToolsV2.js +5 -5
  49. package/dist/server/tools/PortfolioTools.d.ts.map +1 -1
  50. package/dist/server/tools/PortfolioTools.js +16 -5
  51. package/dist/server/types.d.ts +2 -0
  52. package/dist/server/types.d.ts.map +1 -1
  53. package/dist/server/types.js +1 -1
  54. package/dist/sync/PortfolioDownloader.d.ts +27 -0
  55. package/dist/sync/PortfolioDownloader.d.ts.map +1 -0
  56. package/dist/sync/PortfolioDownloader.js +120 -0
  57. package/dist/sync/PortfolioSyncComparer.d.ts +50 -0
  58. package/dist/sync/PortfolioSyncComparer.d.ts.map +1 -0
  59. package/dist/sync/PortfolioSyncComparer.js +158 -0
  60. package/dist/tools/portfolio/submitToPortfolioTool.d.ts.map +1 -1
  61. package/dist/tools/portfolio/submitToPortfolioTool.js +6 -5
  62. package/dist/utils/TemplateRenderer.d.ts +63 -0
  63. package/dist/utils/TemplateRenderer.d.ts.map +1 -0
  64. package/dist/utils/TemplateRenderer.js +154 -0
  65. package/package.json +7 -6
@@ -0,0 +1,208 @@
1
+ /**
2
+ * ConfigWizardCheck - Handles checking if the configuration wizard should run
3
+ * on first interaction with the MCP server
4
+ */
5
+ import { ConfigManager } from './ConfigManager.js';
6
+ import { logger } from '../utils/logger.js';
7
+ import { readFileSync } from 'fs';
8
+ import { fileURLToPath } from 'url';
9
+ import { dirname, join } from 'path';
10
+ export class ConfigWizardCheck {
11
+ hasCheckedWizard = false;
12
+ configManager;
13
+ currentVersion;
14
+ constructor() {
15
+ this.configManager = ConfigManager.getInstance();
16
+ this.currentVersion = this.getCurrentVersion();
17
+ }
18
+ /**
19
+ * Get the current version from package.json
20
+ */
21
+ getCurrentVersion() {
22
+ try {
23
+ const __filename = fileURLToPath(import.meta.url);
24
+ const __dirname = dirname(__filename);
25
+ const packagePath = join(__dirname, '..', '..', 'package.json');
26
+ const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
27
+ return packageJson.version;
28
+ }
29
+ catch (error) {
30
+ logger.warn('Could not read package.json version', { error });
31
+ return '0.0.0';
32
+ }
33
+ }
34
+ /**
35
+ * Check if configuration wizard should run on first interaction
36
+ * Returns a prompt message if wizard should run, null otherwise
37
+ */
38
+ async checkIfWizardNeeded() {
39
+ // Only check once per session
40
+ if (this.hasCheckedWizard) {
41
+ return null;
42
+ }
43
+ this.hasCheckedWizard = true;
44
+ try {
45
+ // Initialize config if not already done
46
+ await this.configManager.initialize();
47
+ const config = this.configManager.getConfig();
48
+ // Check if this is a first-time user
49
+ if (!config.wizard?.completed && !config.wizard?.dismissed) {
50
+ // First time user - show welcome wizard
51
+ return this.getWizardPrompt();
52
+ }
53
+ // Check if we should show update wizard for existing users
54
+ if (config.wizard?.completed && this.shouldShowUpdateWizard(config.wizard?.lastSeenVersion)) {
55
+ // Update the last seen version
56
+ await this.configManager.updateSetting('wizard.lastSeenVersion', this.currentVersion);
57
+ return this.getUpdateWizardPrompt();
58
+ }
59
+ return null;
60
+ }
61
+ catch (error) {
62
+ logger.error('Error checking config wizard status', { error });
63
+ return null;
64
+ }
65
+ }
66
+ /**
67
+ * Determine if we should show the update wizard based on version changes
68
+ * This logic can be updated with each release to trigger when needed
69
+ */
70
+ shouldShowUpdateWizard(lastSeenVersion) {
71
+ // If no last seen version, they've never seen an update wizard
72
+ if (!lastSeenVersion) {
73
+ return false; // Don't show update to very old users who haven't seen versioning yet
74
+ }
75
+ // DEPLOYMENT NOTE: Update this logic when you want to trigger the wizard
76
+ // Examples:
77
+ // - For emergency notifications: return true;
78
+ // - For major features: return this.currentVersion >= '1.8.0' && lastSeenVersion < '1.8.0';
79
+ // - For breaking changes: return this.currentVersion.startsWith('2.') && lastSeenVersion.startsWith('1.');
80
+ // Currently: Don't trigger update wizard (can be changed in any release)
81
+ return false;
82
+ }
83
+ /**
84
+ * Get the wizard prompt message - friendly for non-technical users
85
+ */
86
+ getWizardPrompt() {
87
+ return `🎨 **Welcome to DollhouseMCP!**
88
+
89
+ Hi there! I see this is your first time here. DollhouseMCP helps you create powerful customization elements for your AI assistant - and it's easier than you might think!
90
+
91
+ **What can you do with DollhouseMCP?**
92
+
93
+ 🎭 **Personas** - Change your AI's personality (make it funny, professional, creative, or anything you imagine)
94
+ 💡 **Skills** - Give your AI new abilities like taking meeting notes, reviewing code, or organizing your thoughts
95
+ 📝 **Templates** - Create reusable formats for emails, documentation, resumes, and more
96
+ 🤖 **Agents** - Build smart assistants that handle specific tasks automatically
97
+ ✨ **And more!** - Just describe what you want, and DollhouseMCP will help you create it
98
+
99
+ The best part? Everything you create is saved and persistent. Your custom tools and assistants will be there whenever you need them. You can modify them anytime just by asking!
100
+
101
+ **Need ideas?** Just ask "What would be the best way to..." and I'll help you figure out the perfect solution.
102
+
103
+ **Ready to get started?** I'll help you:
104
+ - Choose a username (this tags your creations so you can find them later - or stay anonymous, that's totally fine!)
105
+ - Set up your workspace for saving all your customizations
106
+ - Browse examples to spark your creativity
107
+ - Create your first customization element
108
+
109
+ Just say:
110
+ - "Yes" or "Let's get started" → I'll guide you through setup
111
+ - "Skip for now" → You can set up later when you're ready
112
+ - "I'll stay anonymous" → Perfect! You can use everything without signing in
113
+
114
+ **What's a username for?** It simply tags your creations (like "created by: you") so you can find them easily. Staying anonymous means your creations are tagged with a fun random ID instead (like "created by: clever-fox"). Either way, all your work is saved locally on your computer!
115
+
116
+ Don't worry - this only takes a minute, and you can change any settings later! 🌟`;
117
+ }
118
+ /**
119
+ * Get the update wizard prompt for returning users
120
+ * This can be customized for each release that needs to notify users
121
+ */
122
+ getUpdateWizardPrompt() {
123
+ // This template can be customized for each release
124
+ return `🎉 **DollhouseMCP Has New Features!**
125
+
126
+ Welcome back! We've added some exciting new capabilities since you last used DollhouseMCP.
127
+
128
+ **What's New:**
129
+ - Enhanced configuration options
130
+ - Improved user experience
131
+ - Better performance
132
+
133
+ Would you like me to show you what's new, or would you prefer to explore on your own?
134
+
135
+ Just say:
136
+ - "Show me what's new" → I'll guide you through the updates
137
+ - "Skip for now" → Continue with your work
138
+
139
+ You can always ask "What's new in DollhouseMCP?" later to see this again.`;
140
+ }
141
+ /**
142
+ * Wrap tool responses to check for wizard on first interaction
143
+ * CRITICAL FIX: Create new response objects to avoid mutations
144
+ */
145
+ async wrapResponse(response) {
146
+ const wizardPrompt = await this.checkIfWizardNeeded();
147
+ if (!wizardPrompt) {
148
+ return response;
149
+ }
150
+ // Always create new response objects to avoid mutation
151
+ const wizardContent = {
152
+ type: "text",
153
+ text: wizardPrompt
154
+ };
155
+ const separator = {
156
+ type: "text",
157
+ text: "\n\n---\n\n"
158
+ };
159
+ // Handle different response formats
160
+ if (response?.content && Array.isArray(response.content)) {
161
+ // Create new response with spread to avoid mutation
162
+ return {
163
+ ...response,
164
+ content: [wizardContent, separator, ...response.content]
165
+ };
166
+ }
167
+ else if (typeof response === 'object' && response !== null) {
168
+ // Handle non-standard response formats gracefully
169
+ const originalText = response?.content?.[0]?.text ||
170
+ response?.text ||
171
+ response?.message ||
172
+ "Tool executed successfully";
173
+ return {
174
+ content: [
175
+ wizardContent,
176
+ separator,
177
+ { type: "text", text: originalText }
178
+ ]
179
+ };
180
+ }
181
+ else {
182
+ // Fallback for primitive responses (including null/undefined)
183
+ const text = response == null ? "Tool executed successfully" : String(response);
184
+ return {
185
+ content: [
186
+ wizardContent,
187
+ separator,
188
+ { type: "text", text }
189
+ ]
190
+ };
191
+ }
192
+ }
193
+ /**
194
+ * Mark wizard as completed
195
+ */
196
+ async markWizardCompleted() {
197
+ await this.configManager.updateSetting('wizard.completed', true);
198
+ await this.configManager.updateSetting('wizard.completedAt', new Date().toISOString());
199
+ await this.configManager.updateSetting('wizard.lastSeenVersion', this.currentVersion);
200
+ }
201
+ /**
202
+ * Mark wizard as dismissed
203
+ */
204
+ async markWizardDismissed() {
205
+ await this.configManager.updateSetting('wizard.dismissed', true);
206
+ }
207
+ }
208
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uZmlnV2l6YXJkQ2hlY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlnL0NvbmZpZ1dpemFyZENoZWNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDNUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLElBQUksQ0FBQztBQUNsQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJDLE1BQU0sT0FBTyxpQkFBaUI7SUFDcEIsZ0JBQWdCLEdBQVksS0FBSyxDQUFDO0lBQ2xDLGFBQWEsQ0FBZ0I7SUFDN0IsY0FBYyxDQUFTO0lBRS9CO1FBQ0UsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDakQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUNqRCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUI7UUFDdkIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbEQsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3RDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQztZQUNoRSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNuRSxPQUFPLFdBQVcsQ0FBQyxPQUFP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QyxDQUFDO1FBQ3ZGLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsd0JBQXdCLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxtQkFBbUI7UUFDdkIsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNuRSxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbmZpZ1dpemFyZENoZWNrIC0gSGFuZGxlcyBjaGVja2luZyBpZiB0aGUgY29uZmlndXJhdGlvbiB3aXphcmQgc2hvdWxkIHJ1blxuICogb24gZmlyc3QgaW50ZXJhY3Rpb24gd2l0aCB0aGUgTUNQIHNlcnZlclxuICovXG5cbmltcG9ydCB7IENvbmZpZ01hbmFnZXIgfSBmcm9tICcuL0NvbmZpZ01hbmFnZXIuanMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IHJlYWRGaWxlU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tICd1cmwnO1xuaW1wb3J0IHsgZGlybmFtZSwgam9pbiB9IGZyb20gJ3BhdGgnO1xuXG5leHBvcnQgY2xhc3MgQ29uZmlnV2l6YXJkQ2hlY2sge1xuICBwcml2YXRlIGhhc0NoZWNrZWRXaXphcmQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBjb25maWdNYW5hZ2VyOiBDb25maWdNYW5hZ2VyO1xuICBwcml2YXRlIGN1cnJlbnRWZXJzaW9uOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5jb25maWdNYW5hZ2VyID0gQ29uZmlnTWFuYWdlci5nZXRJbnN0YW5jZSgpO1xuICAgIHRoaXMuY3VycmVudFZlcnNpb24gPSB0aGlzLmdldEN1cnJlbnRWZXJzaW9uKCk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1cnJlbnQgdmVyc2lvbiBmcm9tIHBhY2thZ2UuanNvblxuICAgKi9cbiAgcHJpdmF0ZSBnZXRDdXJyZW50VmVyc2lvbigpOiBzdHJpbmcge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBfX2ZpbGVuYW1lID0gZmlsZVVSTFRvUGF0aChpbXBvcnQubWV0YS51cmwpO1xuICAgICAgY29uc3QgX19kaXJuYW1lID0gZGlybmFtZShfX2ZpbGVuYW1lKTtcbiAgICAgIGNvbnN0IHBhY2thZ2VQYXRoID0gam9pbihfX2Rpcm5hbWUsICcuLicsICcuLicsICdwYWNrYWdlLmpzb24nKTtcbiAgICAgIGNvbnN0IHBhY2thZ2VKc29uID0gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMocGFja2FnZVBhdGgsICd1dGYtOCcpKTtcbiAgICAgIHJldHVybiBwYWNrYWdlSnNvbi52ZXJzaW9uO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybignQ291bGQgbm90IHJlYWQgcGFja2FnZS5qc29uIHZlcnNpb24nLCB7IGVycm9yIH0pO1xuICAgICAgcmV0dXJuICcwLjAuMCc7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGNvbmZpZ3VyYXRpb24gd2l6YXJkIHNob3VsZCBydW4gb24gZmlyc3QgaW50ZXJhY3Rpb25cbiAgICogUmV0dXJucyBhIHByb21wdCBtZXNzYWdlIGlmIHdpemFyZCBzaG91bGQgcnVuLCBudWxsIG90aGVyd2lzZVxuICAgKi9cbiAgYXN5bmMgY2hlY2tJZldpemFyZE5lZWRlZCgpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICAvLyBPbmx5IGNoZWNrIG9uY2UgcGVyIHNlc3Npb25cbiAgICBpZiAodGhpcy5oYXNDaGVja2VkV2l6YXJkKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgXG4gICAgdGhpcy5oYXNDaGVja2VkV2l6YXJkID0gdHJ1ZTtcbiAgICBcbiAgICB0cnkge1xuICAgICAgLy8gSW5pdGlhbGl6ZSBjb25maWcgaWYgbm90IGFscmVhZHkgZG9uZVxuICAgICAgYXdhaXQgdGhpcy5jb25maWdNYW5hZ2VyLmluaXRpYWxpemUoKTtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnTWFuYWdlci5nZXRDb25maWcoKTtcbiAgICAgIFxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIGZpcnN0LXRpbWUgdXNlclxuICAgICAgaWYgKCFjb25maWcud2l6YXJkPy5jb21wbGV0ZWQgJiYgIWNvbmZpZy53aXphcmQ/LmRpc21pc3NlZCkge1xuICAgICAgICAvLyBGaXJzdCB0aW1lIHVzZXIgLSBzaG93IHdlbGNvbWUgd2l6YXJkXG4gICAgICAgIHJldHVybiB0aGlzLmdldFdpemFyZFByb21wdCgpO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBDaGVjayBpZiB3ZSBzaG91bGQgc2hvdyB1cGRhdGUgd2l6YXJkIGZvciBleGlzdGluZyB1c2Vyc1xuICAgICAgaWYgKGNvbmZpZy53aXphcmQ/LmNvbXBsZXRlZCAmJiB0aGlzLnNob3VsZFNob3dVcGRhdGVXaXphcmQoY29uZmlnLndpemFyZD8ubGFzdFNlZW5WZXJzaW9uKSkge1xuICAgICAgICAvLyBVcGRhdGUgdGhlIGxhc3Qgc2VlbiB2ZXJzaW9uXG4gICAgICAgIGF3YWl0IHRoaXMuY29uZmlnTWFuYWdlci51cGRhdGVTZXR0aW5nKCd3aXphcmQubGFzdFNlZW5WZXJzaW9uJywgdGhpcy5jdXJyZW50VmVyc2lvbik7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVwZGF0ZVdpemFyZFByb21wdCgpO1xuICAgICAgfVxuICAgICAgXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGNoZWNraW5nIGNvbmZpZyB3aXphcmQgc3RhdHVzJywgeyBlcnJvciB9KTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIERldGVybWluZSBpZiB3ZSBzaG91bGQgc2hvdyB0aGUgdXBkYXRlIHdpemFyZCBiYXNlZCBvbiB2ZXJzaW9uIGNoYW5nZXNcbiAgICogVGhpcyBsb2dpYyBjYW4gYmUgdXBkYXRlZCB3aXRoIGVhY2ggcmVsZWFzZSB0byB0cmlnZ2VyIHdoZW4gbmVlZGVkXG4gICAqL1xuICBwcml2YXRlIHNob3VsZFNob3dVcGRhdGVXaXphcmQobGFzdFNlZW5WZXJzaW9uPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgLy8gSWYgbm8gbGFzdCBzZWVuIHZlcnNpb24sIHRoZXkndmUgbmV2ZXIgc2VlbiBhbiB1cGRhdGUgd2l6YXJkXG4gICAgaWYgKCFsYXN0U2VlblZlcnNpb24pIHtcbiAgICAgIHJldHVybiBmYWxzZTsgLy8gRG9uJ3Qgc2hvdyB1cGRhdGUgdG8gdmVyeSBvbGQgdXNlcnMgd2hvIGhhdmVuJ3Qgc2VlbiB2ZXJzaW9uaW5nIHlldFxuICAgIH1cbiAgICBcbiAgICAvLyBERVBMT1lNRU5UIE5PVEU6IFVwZGF0ZSB0aGlzIGxvZ2ljIHdoZW4geW91IHdhbnQgdG8gdHJpZ2dlciB0aGUgd2l6YXJkXG4gICAgLy8gRXhhbXBsZXM6XG4gICAgLy8gLSBGb3IgZW1lcmdlbmN5IG5vdGlmaWNhdGlvbnM6IHJldHVybiB0cnVlO1xuICAgIC8vIC0gRm9yIG1ham9yIGZlYXR1cmVzOiByZXR1cm4gdGhpcy5jdXJyZW50VmVyc2lvbiA+PSAnMS44LjAnICYmIGxhc3RTZWVuVmVyc2lvbiA8ICcxLjguMCc7XG4gICAgLy8gLSBGb3IgYnJlYWtpbmcgY2hhbmdlczogcmV0dXJuIHRoaXMuY3VycmVudFZlcnNpb24uc3RhcnRzV2l0aCgnMi4nKSAmJiBsYXN0U2VlblZlcnNpb24uc3RhcnRzV2l0aCgnMS4nKTtcbiAgICBcbiAgICAvLyBDdXJyZW50bHk6IERvbid0IHRyaWdnZXIgdXBkYXRlIHdpemFyZCAoY2FuIGJlIGNoYW5nZWQgaW4gYW55IHJlbGVhc2UpXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgd2l6YXJkIHByb21wdCBtZXNzYWdlIC0gZnJpZW5kbHkgZm9yIG5vbi10ZWNobmljYWwgdXNlcnNcbiAgICovXG4gIHByaXZhdGUgZ2V0V2l6YXJkUHJvbXB0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGDwn46oICoqV2VsY29tZSB0byBEb2xsaG91c2VNQ1AhKipcblxuSGkgdGhlcmUhIEkgc2VlIHRoaXMgaXMgeW91ciBmaXJzdCB0aW1lIGhlcmUuIERvbGxob3VzZU1DUCBoZWxwcyB5b3UgY3JlYXRlIHBvd2VyZnVsIGN1c3RvbWl6YXRpb24gZWxlbWVudHMgZm9yIHlvdXIgQUkgYXNzaXN0YW50IC0gYW5kIGl0J3MgZWFzaWVyIHRoYW4geW91IG1pZ2h0IHRoaW5rIVxuXG4qKldoYXQgY2FuIHlvdSBkbyB3aXRoIERvbGxob3VzZU1DUD8qKlxuXG7wn46tICoqUGVyc29uYXMqKiAtIENoYW5nZSB5b3VyIEFJJ3MgcGVyc29uYWxpdHkgKG1ha2UgaXQgZnVubnksIHByb2Zlc3Npb25hbCwgY3JlYXRpdmUsIG9yIGFueXRoaW5nIHlvdSBpbWFnaW5lKVxu8J+SoSAqKlNraWxscyoqIC0gR2l2ZSB5b3VyIEFJIG5ldyBhYmlsaXRpZXMgbGlrZSB0YWtpbmcgbWVldGluZyBub3RlcywgcmV2aWV3aW5nIGNvZGUsIG9yIG9yZ2FuaXppbmcgeW91ciB0aG91Z2h0c1xu8J+TnSAqKlRlbXBsYXRlcyoqIC0gQ3JlYXRlIHJldXNhYmxlIGZvcm1hdHMgZm9yIGVtYWlscywgZG9jdW1lbnRhdGlvbiwgcmVzdW1lcywgYW5kIG1vcmVcbvCfpJYgKipBZ2VudHMqKiAtIEJ1aWxkIHNtYXJ0IGFzc2lzdGFudHMgdGhhdCBoYW5kbGUgc3BlY2lmaWMgdGFza3MgYXV0b21hdGljYWxseVxu4pyoICoqQW5kIG1vcmUhKiogLSBKdXN0IGRlc2NyaWJlIHdoYXQgeW91IHdhbnQsIGFuZCBEb2xsaG91c2VNQ1Agd2lsbCBoZWxwIHlvdSBjcmVhdGUgaXRcblxuVGhlIGJlc3QgcGFydD8gRXZlcnl0aGluZyB5b3UgY3JlYXRlIGlzIHNhdmVkIGFuZCBwZXJzaXN0ZW50LiBZb3VyIGN1c3RvbSB0b29scyBhbmQgYXNzaXN0YW50cyB3aWxsIGJlIHRoZXJlIHdoZW5ldmVyIHlvdSBuZWVkIHRoZW0uIFlvdSBjYW4gbW9kaWZ5IHRoZW0gYW55dGltZSBqdXN0IGJ5IGFza2luZyFcblxuKipOZWVkIGlkZWFzPyoqIEp1c3QgYXNrIFwiV2hhdCB3b3VsZCBiZSB0aGUgYmVzdCB3YXkgdG8uLi5cIiBhbmQgSSdsbCBoZWxwIHlvdSBmaWd1cmUgb3V0IHRoZSBwZXJmZWN0IHNvbHV0aW9uLlxuXG4qKlJlYWR5IHRvIGdldCBzdGFydGVkPyoqIEknbGwgaGVscCB5b3U6XG4tIENob29zZSBhIHVzZXJuYW1lICh0aGlzIHRhZ3MgeW91ciBjcmVhdGlvbnMgc28geW91IGNhbiBmaW5kIHRoZW0gbGF0ZXIgLSBvciBzdGF5IGFub255bW91cywgdGhhdCdzIHRvdGFsbHkgZmluZSEpXG4tIFNldCB1cCB5b3VyIHdvcmtzcGFjZSBmb3Igc2F2aW5nIGFsbCB5b3VyIGN1c3RvbWl6YXRpb25zXG4tIEJyb3dzZSBleGFtcGxlcyB0byBzcGFyayB5b3VyIGNyZWF0aXZpdHlcbi0gQ3JlYXRlIHlvdXIgZmlyc3QgY3VzdG9taXphdGlvbiBlbGVtZW50XG5cbkp1c3Qgc2F5OlxuLSBcIlllc1wiIG9yIFwiTGV0J3MgZ2V0IHN0YXJ0ZWRcIiDihpIgSSdsbCBndWlkZSB5b3UgdGhyb3VnaCBzZXR1cFxuLSBcIlNraXAgZm9yIG5vd1wiIOKGkiBZb3UgY2FuIHNldCB1cCBsYXRlciB3aGVuIHlvdSdyZSByZWFkeVxuLSBcIkknbGwgc3RheSBhbm9ueW1vdXNcIiDihpIgUGVyZmVjdCEgWW91IGNhbiB1c2UgZXZlcnl0aGluZyB3aXRob3V0IHNpZ25pbmcgaW5cblxuKipXaGF0J3MgYSB1c2VybmFtZSBmb3I/KiogSXQgc2ltcGx5IHRhZ3MgeW91ciBjcmVhdGlvbnMgKGxpa2UgXCJjcmVhdGVkIGJ5OiB5b3VcIikgc28geW91IGNhbiBmaW5kIHRoZW0gZWFzaWx5LiBTdGF5aW5nIGFub255bW91cyBtZWFucyB5b3VyIGNyZWF0aW9ucyBhcmUgdGFnZ2VkIHdpdGggYSBmdW4gcmFuZG9tIElEIGluc3RlYWQgKGxpa2UgXCJjcmVhdGVkIGJ5OiBjbGV2ZXItZm94XCIpLiBFaXRoZXIgd2F5LCBhbGwgeW91ciB3b3JrIGlzIHNhdmVkIGxvY2FsbHkgb24geW91ciBjb21wdXRlciFcblxuRG9uJ3Qgd29ycnkgLSB0aGlzIG9ubHkgdGFrZXMgYSBtaW51dGUsIGFuZCB5b3UgY2FuIGNoYW5nZSBhbnkgc2V0dGluZ3MgbGF0ZXIhIPCfjJ9gO1xuICB9XG4gIFxuICAvKipcbiAgICogR2V0IHRoZSB1cGRhdGUgd2l6YXJkIHByb21wdCBmb3IgcmV0dXJuaW5nIHVzZXJzXG4gICAqIFRoaXMgY2FuIGJlIGN1c3RvbWl6ZWQgZm9yIGVhY2ggcmVsZWFzZSB0aGF0IG5lZWRzIHRvIG5vdGlmeSB1c2Vyc1xuICAgKi9cbiAgcHJpdmF0ZSBnZXRVcGRhdGVXaXphcmRQcm9tcHQoKTogc3RyaW5nIHtcbiAgICAvLyBUaGlzIHRlbXBsYXRlIGNhbiBiZSBjdXN0b21pemVkIGZvciBlYWNoIHJlbGVhc2VcbiAgICByZXR1cm4gYPCfjokgKipEb2xsaG91c2VNQ1AgSGFzIE5ldyBGZWF0dXJlcyEqKlxuXG5XZWxjb21lIGJhY2shIFdlJ3ZlIGFkZGVkIHNvbWUgZXhjaXRpbmcgbmV3IGNhcGFiaWxpdGllcyBzaW5jZSB5b3UgbGFzdCB1c2VkIERvbGxob3VzZU1DUC5cblxuKipXaGF0J3MgTmV3OioqXG4tIEVuaGFuY2VkIGNvbmZpZ3VyYXRpb24gb3B0aW9uc1xuLSBJbXByb3ZlZCB1c2VyIGV4cGVyaWVuY2Vcbi0gQmV0dGVyIHBlcmZvcm1hbmNlXG5cbldvdWxkIHlvdSBsaWtlIG1lIHRvIHNob3cgeW91IHdoYXQncyBuZXcsIG9yIHdvdWxkIHlvdSBwcmVmZXIgdG8gZXhwbG9yZSBvbiB5b3VyIG93bj9cblxuSnVzdCBzYXk6XG4tIFwiU2hvdyBtZSB3aGF0J3MgbmV3XCIg4oaSIEknbGwgZ3VpZGUgeW91IHRocm91Z2ggdGhlIHVwZGF0ZXNcbi0gXCJTa2lwIGZvciBub3dcIiDihpIgQ29udGludWUgd2l0aCB5b3VyIHdvcmtcblxuWW91IGNhbiBhbHdheXMgYXNrIFwiV2hhdCdzIG5ldyBpbiBEb2xsaG91c2VNQ1A/XCIgbGF0ZXIgdG8gc2VlIHRoaXMgYWdhaW4uYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXcmFwIHRvb2wgcmVzcG9uc2VzIHRvIGNoZWNrIGZvciB3aXphcmQgb24gZmlyc3QgaW50ZXJhY3Rpb25cbiAgICogQ1JJVElDQUwgRklYOiBDcmVhdGUgbmV3IHJlc3BvbnNlIG9iamVjdHMgdG8gYXZvaWQgbXV0YXRpb25zXG4gICAqL1xuICBhc3luYyB3cmFwUmVzcG9uc2UocmVzcG9uc2U6IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3Qgd2l6YXJkUHJvbXB0ID0gYXdhaXQgdGhpcy5jaGVja0lmV2l6YXJkTmVlZGVkKCk7XG4gICAgXG4gICAgaWYgKCF3aXphcmRQcm9tcHQpIHtcbiAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG5cbiAgICAvLyBBbHdheXMgY3JlYXRlIG5ldyByZXNwb25zZSBvYmplY3RzIHRvIGF2b2lkIG11dGF0aW9uXG4gICAgY29uc3Qgd2l6YXJkQ29udGVudCA9IHtcbiAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgdGV4dDogd2l6YXJkUHJvbXB0XG4gICAgfTtcblxuICAgIGNvbnN0IHNlcGFyYXRvciA9IHtcbiAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgdGV4dDogXCJcXG5cXG4tLS1cXG5cXG5cIlxuICAgIH07XG5cbiAgICAvLyBIYW5kbGUgZGlmZmVyZW50IHJlc3BvbnNlIGZvcm1hdHNcbiAgICBpZiAocmVzcG9uc2U/LmNvbnRlbnQgJiYgQXJyYXkuaXNBcnJheShyZXNwb25zZS5jb250ZW50KSkge1xuICAgICAgLy8gQ3JlYXRlIG5ldyByZXNwb25zZSB3aXRoIHNwcmVhZCB0byBhdm9pZCBtdXRhdGlvblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucmVzcG9uc2UsXG4gICAgICAgIGNvbnRlbnQ6IFt3aXphcmRDb250ZW50LCBzZXBhcmF0b3IsIC4uLnJlc3BvbnNlLmNvbnRlbnRdXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHJlc3BvbnNlID09PSAnb2JqZWN0JyAmJiByZXNwb25zZSAhPT0gbnVsbCkge1xuICAgICAgLy8gSGFuZGxlIG5vbi1zdGFuZGFyZCByZXNwb25zZSBmb3JtYXRzIGdyYWNlZnVsbHlcbiAgICAgIGNvbnN0IG9yaWdpbmFsVGV4dCA9IHJlc3BvbnNlPy5jb250ZW50Py5bMF0/LnRleHQgfHwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlPy50ZXh0IHx8IFxuICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZT8ubWVzc2FnZSB8fCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJUb29sIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseVwiO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgd2l6YXJkQ29udGVudCxcbiAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgeyB0eXBlOiBcInRleHRcIiwgdGV4dDogb3JpZ2luYWxUZXh0IH1cbiAgICAgICAgXVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRmFsbGJhY2sgZm9yIHByaW1pdGl2ZSByZXNwb25zZXMgKGluY2x1ZGluZyBudWxsL3VuZGVmaW5lZClcbiAgICAgIGNvbnN0IHRleHQgPSByZXNwb25zZSA9PSBudWxsID8gXCJUb29sIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseVwiIDogU3RyaW5nKHJlc3BvbnNlKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB3aXphcmRDb250ZW50LFxuICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICB7IHR5cGU6IFwidGV4dFwiLCB0ZXh0IH1cbiAgICAgICAgXVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWFyayB3aXphcmQgYXMgY29tcGxldGVkXG4gICAqL1xuICBhc3luYyBtYXJrV2l6YXJkQ29tcGxldGVkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuY29uZmlnTWFuYWdlci51cGRhdGVTZXR0aW5nKCd3aXphcmQuY29tcGxldGVkJywgdHJ1ZSk7XG4gICAgYXdhaXQgdGhpcy5jb25maWdNYW5hZ2VyLnVwZGF0ZVNldHRpbmcoJ3dpemFyZC5jb21wbGV0ZWRBdCcsIG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSk7XG4gICAgYXdhaXQgdGhpcy5jb25maWdNYW5hZ2VyLnVwZGF0ZVNldHRpbmcoJ3dpemFyZC5sYXN0U2VlblZlcnNpb24nLCB0aGlzLmN1cnJlbnRWZXJzaW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrIHdpemFyZCBhcyBkaXNtaXNzZWRcbiAgICovXG4gIGFzeW5jIG1hcmtXaXphcmREaXNtaXNzZWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5jb25maWdNYW5hZ2VyLnVwZGF0ZVNldHRpbmcoJ3dpemFyZC5kaXNtaXNzZWQnLCB0cnVlKTtcbiAgfVxufSJdfQ==
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Portfolio configuration utilities
3
+ * Handles repository name configuration for portfolio sync
4
+ */
5
+ /**
6
+ * Get the configured portfolio repository name
7
+ * Priority order:
8
+ * 1. TEST_GITHUB_REPO environment variable (for testing)
9
+ * 2. Configured repository name (future: from config file)
10
+ * 3. Default: 'dollhouse-portfolio'
11
+ *
12
+ * @example
13
+ * // Default usage
14
+ * const repo = getPortfolioRepositoryName(); // 'dollhouse-portfolio'
15
+ *
16
+ * @example
17
+ * // With TEST_GITHUB_REPO set
18
+ * process.env.TEST_GITHUB_REPO = 'test-portfolio';
19
+ * const repo = getPortfolioRepositoryName(); // 'test-portfolio'
20
+ *
21
+ * @returns {string} The configured portfolio repository name
22
+ */
23
+ export declare function getPortfolioRepositoryName(): string;
24
+ /**
25
+ * Check if we're in a test environment
26
+ *
27
+ * @example
28
+ * // When TEST_GITHUB_REPO is set
29
+ * process.env.TEST_GITHUB_REPO = 'test-repo';
30
+ * const isTest = isTestEnvironment(); // true
31
+ *
32
+ * @example
33
+ * // In production environment
34
+ * delete process.env.TEST_GITHUB_REPO;
35
+ * const isTest = isTestEnvironment(); // false
36
+ *
37
+ * @returns {boolean} True if running in a test environment
38
+ */
39
+ export declare function isTestEnvironment(): boolean;
40
+ //# sourceMappingURL=portfolioConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portfolioConfig.d.ts","sourceRoot":"","sources":["../../src/config/portfolioConfig.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAgBnD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAI3C"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Portfolio configuration utilities
3
+ * Handles repository name configuration for portfolio sync
4
+ */
5
+ /**
6
+ * Get the configured portfolio repository name
7
+ * Priority order:
8
+ * 1. TEST_GITHUB_REPO environment variable (for testing)
9
+ * 2. Configured repository name (future: from config file)
10
+ * 3. Default: 'dollhouse-portfolio'
11
+ *
12
+ * @example
13
+ * // Default usage
14
+ * const repo = getPortfolioRepositoryName(); // 'dollhouse-portfolio'
15
+ *
16
+ * @example
17
+ * // With TEST_GITHUB_REPO set
18
+ * process.env.TEST_GITHUB_REPO = 'test-portfolio';
19
+ * const repo = getPortfolioRepositoryName(); // 'test-portfolio'
20
+ *
21
+ * @returns {string} The configured portfolio repository name
22
+ */
23
+ export function getPortfolioRepositoryName() {
24
+ // For testing environments, use TEST_GITHUB_REPO if set
25
+ // Trim whitespace to handle edge cases
26
+ const testRepo = process.env.TEST_GITHUB_REPO?.trim();
27
+ if (testRepo) {
28
+ return testRepo;
29
+ }
30
+ // TODO: Add support for reading from config file
31
+ // const config = ConfigManager.getInstance();
32
+ // if (config.github?.portfolio?.repository_name) {
33
+ // return config.github.portfolio.repository_name;
34
+ // }
35
+ // Default repository name
36
+ return 'dollhouse-portfolio';
37
+ }
38
+ /**
39
+ * Check if we're in a test environment
40
+ *
41
+ * @example
42
+ * // When TEST_GITHUB_REPO is set
43
+ * process.env.TEST_GITHUB_REPO = 'test-repo';
44
+ * const isTest = isTestEnvironment(); // true
45
+ *
46
+ * @example
47
+ * // In production environment
48
+ * delete process.env.TEST_GITHUB_REPO;
49
+ * const isTest = isTestEnvironment(); // false
50
+ *
51
+ * @returns {boolean} True if running in a test environment
52
+ */
53
+ export function isTestEnvironment() {
54
+ return process.env.TEST_MODE === 'true' ||
55
+ process.env.NODE_ENV === 'test' ||
56
+ !!process.env.TEST_GITHUB_REPO?.trim();
57
+ }
58
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydGZvbGlvQ29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy9wb3J0Zm9saW9Db25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUg7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQjtJQUN4Qyx3REFBd0Q7SUFDeEQsdUNBQXVDO0lBQ3ZDLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDdEQsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUNiLE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxpREFBaUQ7SUFDakQsOENBQThDO0lBQzlDLG1EQUFtRDtJQUNuRCxvREFBb0Q7SUFDcEQsSUFBSTtJQUVKLDBCQUEwQjtJQUMxQixPQUFPLHFCQUFxQixDQUFDO0FBQy9CLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sVUFBVSxpQkFBaUI7SUFDL0IsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsS0FBSyxNQUFNO1FBQ2hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxLQUFLLE1BQU07UUFDL0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDaEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUG9ydGZvbGlvIGNvbmZpZ3VyYXRpb24gdXRpbGl0aWVzXG4gKiBIYW5kbGVzIHJlcG9zaXRvcnkgbmFtZSBjb25maWd1cmF0aW9uIGZvciBwb3J0Zm9saW8gc3luY1xuICovXG5cbi8qKlxuICogR2V0IHRoZSBjb25maWd1cmVkIHBvcnRmb2xpbyByZXBvc2l0b3J5IG5hbWVcbiAqIFByaW9yaXR5IG9yZGVyOlxuICogMS4gVEVTVF9HSVRIVUJfUkVQTyBlbnZpcm9ubWVudCB2YXJpYWJsZSAoZm9yIHRlc3RpbmcpXG4gKiAyLiBDb25maWd1cmVkIHJlcG9zaXRvcnkgbmFtZSAoZnV0dXJlOiBmcm9tIGNvbmZpZyBmaWxlKVxuICogMy4gRGVmYXVsdDogJ2RvbGxob3VzZS1wb3J0Zm9saW8nXG4gKiBcbiAqIEBleGFtcGxlXG4gKiAvLyBEZWZhdWx0IHVzYWdlXG4gKiBjb25zdCByZXBvID0gZ2V0UG9ydGZvbGlvUmVwb3NpdG9yeU5hbWUoKTsgLy8gJ2RvbGxob3VzZS1wb3J0Zm9saW8nXG4gKiBcbiAqIEBleGFtcGxlXG4gKiAvLyBXaXRoIFRFU1RfR0lUSFVCX1JFUE8gc2V0XG4gKiBwcm9jZXNzLmVudi5URVNUX0dJVEhVQl9SRVBPID0gJ3Rlc3QtcG9ydGZvbGlvJztcbiAqIGNvbnN0IHJlcG8gPSBnZXRQb3J0Zm9saW9SZXBvc2l0b3J5TmFtZSgpOyAvLyAndGVzdC1wb3J0Zm9saW8nXG4gKiBcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb25maWd1cmVkIHBvcnRmb2xpbyByZXBvc2l0b3J5IG5hbWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFBvcnRmb2xpb1JlcG9zaXRvcnlOYW1lKCk6IHN0cmluZyB7XG4gIC8vIEZvciB0ZXN0aW5nIGVudmlyb25tZW50cywgdXNlIFRFU1RfR0lUSFVCX1JFUE8gaWYgc2V0XG4gIC8vIFRyaW0gd2hpdGVzcGFjZSB0byBoYW5kbGUgZWRnZSBjYXNlc1xuICBjb25zdCB0ZXN0UmVwbyA9IHByb2Nlc3MuZW52LlRFU1RfR0lUSFVCX1JFUE8/LnRyaW0oKTtcbiAgaWYgKHRlc3RSZXBvKSB7XG4gICAgcmV0dXJuIHRlc3RSZXBvO1xuICB9XG4gIFxuICAvLyBUT0RPOiBBZGQgc3VwcG9ydCBmb3IgcmVhZGluZyBmcm9tIGNvbmZpZyBmaWxlXG4gIC8vIGNvbnN0IGNvbmZpZyA9IENvbmZpZ01hbmFnZXIuZ2V0SW5zdGFuY2UoKTtcbiAgLy8gaWYgKGNvbmZpZy5naXRodWI/LnBvcnRmb2xpbz8ucmVwb3NpdG9yeV9uYW1lKSB7XG4gIC8vICAgcmV0dXJuIGNvbmZpZy5naXRodWIucG9ydGZvbGlvLnJlcG9zaXRvcnlfbmFtZTtcbiAgLy8gfVxuICBcbiAgLy8gRGVmYXVsdCByZXBvc2l0b3J5IG5hbWVcbiAgcmV0dXJuICdkb2xsaG91c2UtcG9ydGZvbGlvJztcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB3ZSdyZSBpbiBhIHRlc3QgZW52aXJvbm1lbnRcbiAqIFxuICogQGV4YW1wbGVcbiAqIC8vIFdoZW4gVEVTVF9HSVRIVUJfUkVQTyBpcyBzZXRcbiAqIHByb2Nlc3MuZW52LlRFU1RfR0lUSFVCX1JFUE8gPSAndGVzdC1yZXBvJztcbiAqIGNvbnN0IGlzVGVzdCA9IGlzVGVzdEVudmlyb25tZW50KCk7IC8vIHRydWVcbiAqIFxuICogQGV4YW1wbGVcbiAqIC8vIEluIHByb2R1Y3Rpb24gZW52aXJvbm1lbnRcbiAqIGRlbGV0ZSBwcm9jZXNzLmVudi5URVNUX0dJVEhVQl9SRVBPO1xuICogY29uc3QgaXNUZXN0ID0gaXNUZXN0RW52aXJvbm1lbnQoKTsgLy8gZmFsc2VcbiAqIFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgcnVubmluZyBpbiBhIHRlc3QgZW52aXJvbm1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVGVzdEVudmlyb25tZW50KCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcHJvY2Vzcy5lbnYuVEVTVF9NT0RFID09PSAndHJ1ZScgfHwgXG4gICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Rlc3QnIHx8XG4gICAgICAgICAhIXByb2Nlc3MuZW52LlRFU1RfR0lUSFVCX1JFUE8/LnRyaW0oKTtcbn0iXX0=
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Wizard Text Templates
3
+ *
4
+ * Centralized configuration for all wizard text to support:
5
+ * - Internationalization (i18n) in the future
6
+ * - Consistent messaging across the application
7
+ * - Easy updates without modifying business logic
8
+ * - Template reusability
9
+ */
10
+ export interface WizardTemplates {
11
+ title: string;
12
+ currentConfigHeader: string;
13
+ steps: {
14
+ userIdentity: WizardStep;
15
+ githubIntegration: WizardStep;
16
+ portfolioSync: WizardStep;
17
+ displayPreferences: WizardStep;
18
+ };
19
+ instructions: {
20
+ quick: string;
21
+ detailed: string;
22
+ skip: string;
23
+ };
24
+ footer: string;
25
+ }
26
+ export interface WizardStep {
27
+ title: string;
28
+ description: string;
29
+ instructions: string[];
30
+ currentValue: (value: any) => string;
31
+ }
32
+ /**
33
+ * Default English templates
34
+ */
35
+ export declare const defaultWizardTemplates: WizardTemplates;
36
+ /**
37
+ * Friendly value replacements for null/undefined config values
38
+ */
39
+ export declare const friendlyNullValues: Record<string, string>;
40
+ /**
41
+ * Helper function to get wizard text in specified language
42
+ * @param language - Language code (e.g., 'en', 'es', 'fr')
43
+ * @returns Wizard templates for the specified language
44
+ */
45
+ export declare function getWizardTemplates(language?: string): WizardTemplates;
46
+ /**
47
+ * Helper function to get friendly null value
48
+ * @param path - Dot-notation path to the config field
49
+ * @returns Friendly message for null value
50
+ */
51
+ export declare function getFriendlyNullValue(path: string): string;
52
+ /**
53
+ * Template builder for wizard steps
54
+ * Allows for dynamic construction of wizard content
55
+ */
56
+ export declare class WizardTemplateBuilder {
57
+ private templates;
58
+ constructor(language?: string);
59
+ /**
60
+ * Build the complete wizard text
61
+ */
62
+ buildWizardText(currentConfig: any): string;
63
+ /**
64
+ * Build current configuration section
65
+ */
66
+ private buildCurrentConfig;
67
+ /**
68
+ * Build all wizard steps
69
+ */
70
+ private buildSteps;
71
+ /**
72
+ * Format a single wizard step
73
+ */
74
+ private formatStep;
75
+ /**
76
+ * Build instruction options
77
+ */
78
+ private buildInstructions;
79
+ /**
80
+ * Format config as YAML (stub - would use actual yaml library)
81
+ */
82
+ private formatConfigAsYaml;
83
+ }
84
+ //# sourceMappingURL=wizardTemplates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizardTemplates.d.ts","sourceRoot":"","sources":["../../src/config/wizardTemplates.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE;QACL,YAAY,EAAE,UAAU,CAAC;QACzB,iBAAiB,EAAE,UAAU,CAAC;QAC9B,aAAa,EAAE,UAAU,CAAC;QAC1B,kBAAkB,EAAE,UAAU,CAAC;KAChC,CAAC;IACF,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAC;CACtC;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAqDpC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA0BrD,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,GAAE,MAAa,GAAG,eAAe,CAQ3E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;GAGG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,SAAS,CAAkB;gBAEvB,QAAQ,GAAE,MAAa;IAInC;;OAEG;IACH,eAAe,CAAC,aAAa,EAAE,GAAG,GAAG,MAAM;IAgB3C;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,CAAC,UAAU;IAsBlB;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAK3B"}
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Wizard Text Templates
3
+ *
4
+ * Centralized configuration for all wizard text to support:
5
+ * - Internationalization (i18n) in the future
6
+ * - Consistent messaging across the application
7
+ * - Easy updates without modifying business logic
8
+ * - Template reusability
9
+ */
10
+ /**
11
+ * Default English templates
12
+ */
13
+ export const defaultWizardTemplates = {
14
+ title: '🧙 Configuration Wizard',
15
+ currentConfigHeader: '📊 Current Configuration:',
16
+ steps: {
17
+ userIdentity: {
18
+ title: '🎯 Step 1: User Identity',
19
+ description: 'This tags your creations so you can find them later. Everything is saved locally on your computer.',
20
+ instructions: [
21
+ 'To set a username: Say "Set my username to [your-name]"',
22
+ 'To stay anonymous: Say "I\'ll stay anonymous"',
23
+ ],
24
+ currentValue: (value) => value || '(not set - anonymous mode)',
25
+ },
26
+ githubIntegration: {
27
+ title: '🔐 Step 2: GitHub Integration (Optional)',
28
+ description: 'Connect to GitHub to share your creations and browse community content.',
29
+ instructions: [
30
+ 'To connect GitHub: Say "Connect my GitHub account"',
31
+ 'To skip: Say "Skip GitHub for now"',
32
+ ],
33
+ currentValue: (value) => value ? 'Connected' : '(not connected)',
34
+ },
35
+ portfolioSync: {
36
+ title: '🔄 Step 3: Portfolio Sync (Optional)',
37
+ description: 'Automatically backup your creations to GitHub.',
38
+ instructions: [
39
+ 'To enable: Say "Enable auto-sync"',
40
+ 'To keep manual: Say "I\'ll sync manually"',
41
+ ],
42
+ currentValue: (value) => value ? 'Enabled' : 'Manual',
43
+ },
44
+ displayPreferences: {
45
+ title: '🎨 Step 4: Display Preferences',
46
+ description: 'Customize how DollhouseMCP shows information.',
47
+ instructions: [
48
+ 'To show active persona: Say "Show persona indicators"',
49
+ 'To keep minimal: Say "Use minimal display"',
50
+ ],
51
+ currentValue: (value) => value ? 'Enabled' : 'Minimal',
52
+ },
53
+ },
54
+ instructions: {
55
+ quick: '💡 **Quick Setup**: Say "Configure the basics" to set just username and GitHub',
56
+ detailed: '📝 **Detailed Setup**: Say "Configure everything" to go through all options',
57
+ skip: '⏭️ **Skip for Now**: Say "Skip wizard" to use anonymous mode',
58
+ },
59
+ footer: '✨ You can always change these settings later by saying "Open configuration wizard"',
60
+ };
61
+ /**
62
+ * Friendly value replacements for null/undefined config values
63
+ */
64
+ export const friendlyNullValues = {
65
+ // User fields
66
+ 'user.username': '(not set - anonymous mode active)',
67
+ 'user.email': '(optional - not set)',
68
+ 'user.display_name': '(not set - will use username)',
69
+ // GitHub fields
70
+ 'github.auth_token': '(not configured - GitHub features disabled)',
71
+ 'github.oauth_token': '(not authenticated)',
72
+ 'github.default_repository': '(not set - will use default)',
73
+ 'github.username': '(not connected)',
74
+ // Portfolio sync fields
75
+ 'portfolio.sync_status.last_sync': '(never synced)',
76
+ 'portfolio.sync_status.last_push': '(never pushed)',
77
+ 'portfolio.sync_status.last_pull': '(never pulled)',
78
+ 'portfolio.repository_name': `(using default: ${process.env.TEST_GITHUB_REPO || 'dollhouse-portfolio'})`,
79
+ // Collection submission
80
+ 'collection_submission.auto_submit': '(disabled)',
81
+ // Indicator settings
82
+ 'indicator.custom_format': '(using default format)',
83
+ // Default for any other null
84
+ 'default': '(not set)',
85
+ };
86
+ /**
87
+ * Helper function to get wizard text in specified language
88
+ * @param language - Language code (e.g., 'en', 'es', 'fr')
89
+ * @returns Wizard templates for the specified language
90
+ */
91
+ export function getWizardTemplates(language = 'en') {
92
+ // For now, only English is supported
93
+ // Future: Load from language-specific files
94
+ switch (language) {
95
+ case 'en':
96
+ default:
97
+ return defaultWizardTemplates;
98
+ }
99
+ }
100
+ /**
101
+ * Helper function to get friendly null value
102
+ * @param path - Dot-notation path to the config field
103
+ * @returns Friendly message for null value
104
+ */
105
+ export function getFriendlyNullValue(path) {
106
+ return friendlyNullValues[path] || friendlyNullValues['default'];
107
+ }
108
+ /**
109
+ * Template builder for wizard steps
110
+ * Allows for dynamic construction of wizard content
111
+ */
112
+ export class WizardTemplateBuilder {
113
+ templates;
114
+ constructor(language = 'en') {
115
+ this.templates = getWizardTemplates(language);
116
+ }
117
+ /**
118
+ * Build the complete wizard text
119
+ */
120
+ buildWizardText(currentConfig) {
121
+ const parts = [
122
+ this.templates.title,
123
+ '',
124
+ this.buildCurrentConfig(currentConfig),
125
+ '',
126
+ this.buildSteps(currentConfig),
127
+ '',
128
+ this.buildInstructions(),
129
+ '',
130
+ this.templates.footer,
131
+ ];
132
+ return parts.join('\n');
133
+ }
134
+ /**
135
+ * Build current configuration section
136
+ */
137
+ buildCurrentConfig(config) {
138
+ return `${this.templates.currentConfigHeader}
139
+ \`\`\`yaml
140
+ ${this.formatConfigAsYaml(config)}
141
+ \`\`\``;
142
+ }
143
+ /**
144
+ * Build all wizard steps
145
+ */
146
+ buildSteps(config) {
147
+ const steps = [];
148
+ // User Identity
149
+ const userStep = this.templates.steps.userIdentity;
150
+ steps.push(this.formatStep(userStep, config.user?.username));
151
+ // GitHub Integration
152
+ const githubStep = this.templates.steps.githubIntegration;
153
+ steps.push(this.formatStep(githubStep, config.github?.auth_token));
154
+ // Portfolio Sync
155
+ const portfolioStep = this.templates.steps.portfolioSync;
156
+ steps.push(this.formatStep(portfolioStep, config.portfolio?.auto_sync));
157
+ // Display Preferences
158
+ const displayStep = this.templates.steps.displayPreferences;
159
+ steps.push(this.formatStep(displayStep, config.indicator?.enabled));
160
+ return steps.join('\n\n');
161
+ }
162
+ /**
163
+ * Format a single wizard step
164
+ */
165
+ formatStep(step, currentValue) {
166
+ const lines = [
167
+ step.title,
168
+ step.description,
169
+ ];
170
+ for (const instruction of step.instructions) {
171
+ lines.push(`- ${instruction}`);
172
+ }
173
+ lines.push(`- Current: ${step.currentValue(currentValue)}`);
174
+ return lines.join('\n');
175
+ }
176
+ /**
177
+ * Build instruction options
178
+ */
179
+ buildInstructions() {
180
+ return [
181
+ this.templates.instructions.quick,
182
+ this.templates.instructions.detailed,
183
+ this.templates.instructions.skip,
184
+ ].join('\n');
185
+ }
186
+ /**
187
+ * Format config as YAML (stub - would use actual yaml library)
188
+ */
189
+ formatConfigAsYaml(config) {
190
+ // This would use the actual yaml.dump with friendly values
191
+ // For now, return a placeholder
192
+ return 'user:\n username: (not set)\n email: (optional)';
193
+ }
194
+ }
195
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l6YXJkVGVtcGxhdGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy93aXphcmRUZW1wbGF0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0dBUUc7QUEwQkg7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBb0I7SUFDckQsS0FBSyxFQUFFLHlCQUF5QjtJQUNoQyxtQkFBbUIsRUFBRSwyQkFBMkI7SUFFaEQsS0FBSyxFQUFFO1FBQ0wsWUFBWSxFQUFFO1lBQ1osS0FBSyxFQUFFLDBCQUEwQjtZQUNqQyxXQUFXLEVBQUUsb0dBQW9HO1lBQ2pILFlBQVksRUFBRTtnQkFDWix5REFBeUQ7Z0JBQ3pELCtDQUErQzthQUNoRDtZQUNELFlBQVksRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxJQUFJLDRCQUE0QjtTQUMvRDtRQUVELGlCQUFpQixFQUFFO1lBQ2pCLEtBQUssRUFBRSwwQ0FBMEM7WUFDakQsV0FBVyxFQUFFLHlFQUF5RTtZQUN0RixZQUFZLEVBQUU7Z0JBQ1osb0RBQW9EO2dCQUNwRCxvQ0FBb0M7YUFDckM7WUFDRCxZQUFZLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxpQkFBaUI7U0FDakU7UUFFRCxhQUFhLEVBQUU7WUFDYixLQUFLLEVBQUUsc0NBQXNDO1lBQzdDLFdBQVcsRUFBRSxnREFBZ0Q7WUFDN0QsWUFBWSxFQUFFO2dCQUNaLG1DQUFtQztnQkFDbkMsMkNBQTJDO2FBQzVDO1lBQ0QsWUFBWSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUTtTQUN0RDtRQUVELGtCQUFrQixFQUFFO1lBQ2xCLEtBQUssRUFBRSxnQ0FBZ0M7WUFDdkMsV0FBVyxFQUFFLCtDQUErQztZQUM1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RCxLQUFLLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFNUQsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFCLENBQUM7SUFFRDs7T0FFRztJQUNLLGlCQUFpQjtRQUN2QixPQUFPO1lBQ0wsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsS0FBSztZQUNqQyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxRQUFRO1lBQ3BDLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUk7U0FDakMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDZixDQUFDO0lBRUQ7O09BRUc7SUFDSyxrQkFBa0IsQ0FBQyxNQUFXO1FBQ3BDLDJEQUEyRDtRQUMzRCxnQ0FBZ0M7UUFDaEMsT0FBTyxtREFBbUQsQ0FBQztJQUM3RCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFdpemFyZCBUZXh0IFRlbXBsYXRlc1xuICogXG4gKiBDZW50cmFsaXplZCBjb25maWd1cmF0aW9uIGZvciBhbGwgd2l6YXJkIHRleHQgdG8gc3VwcG9ydDpcbiAqIC0gSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIGluIHRoZSBmdXR1cmVcbiAqIC0gQ29uc2lzdGVudCBtZXNzYWdpbmcgYWNyb3NzIHRoZSBhcHBsaWNhdGlvblxuICogLSBFYXN5IHVwZGF0ZXMgd2l0aG91dCBtb2RpZnlpbmcgYnVzaW5lc3MgbG9naWNcbiAqIC0gVGVtcGxhdGUgcmV1c2FiaWxpdHlcbiAqL1xuXG5leHBvcnQgaW50ZXJmYWNlIFdpemFyZFRlbXBsYXRlcyB7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGN1cnJlbnRDb25maWdIZWFkZXI6IHN0cmluZztcbiAgc3RlcHM6IHtcbiAgICB1c2VySWRlbnRpdHk6IFdpemFyZFN0ZXA7XG4gICAgZ2l0aHViSW50ZWdyYXRpb246IFdpemFyZFN0ZXA7XG4gICAgcG9ydGZvbGlvU3luYzogV2l6YXJkU3RlcDtcbiAgICBkaXNwbGF5UHJlZmVyZW5jZXM6IFdpemFyZFN0ZXA7XG4gIH07XG4gIGluc3RydWN0aW9uczoge1xuICAgIHF1aWNrOiBzdHJpbmc7XG4gICAgZGV0YWlsZWQ6IHN0cmluZztcbiAgICBza2lwOiBzdHJpbmc7XG4gIH07XG4gIGZvb3Rlcjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFdpemFyZFN0ZXAge1xuICB0aXRsZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBpbnN0cnVjdGlvbnM6IHN0cmluZ1tdO1xuICBjdXJyZW50VmFsdWU6ICh2YWx1ZTogYW55KSA9PiBzdHJpbmc7XG59XG5cbi8qKlxuICogRGVmYXVsdCBFbmdsaXNoIHRlbXBsYXRlc1xuICovXG5leHBvcnQgY29uc3QgZGVmYXVsdFdpemFyZFRlbXBsYXRlczogV2l6YXJkVGVtcGxhdGVzID0ge1xuICB0aXRsZTogJ/Cfp5kgQ29uZmlndXJhdGlvbiBXaXphcmQnLFxuICBjdXJyZW50Q29uZmlnSGVhZGVyOiAn8J+TiiBDdXJyZW50IENvbmZpZ3VyYXRpb246JyxcbiAgXG4gIHN0ZXBzOiB7XG4gICAgdXNlcklkZW50aXR5OiB7XG4gICAgICB0aXRsZTogJ/Cfjq8gU3RlcCAxOiBVc2VyIElkZW50aXR5JyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyB0YWdzIHlvdXIgY3JlYXRpb25zIHNvIHlvdSBjYW4gZmluZCB0aGVtIGxhdGVyLiBFdmVyeXRoaW5nIGlzIHNhdmVkIGxvY2FsbHkgb24geW91ciBjb21wdXRlci4nLFxuICAgICAgaW5zdHJ1Y3Rpb25zOiBbXG4gICAgICAgICdUbyBzZXQgYSB1c2VybmFtZTogU2F5IFwiU2V0IG15IHVzZXJuYW1lIHRvIFt5b3VyLW5hbWVdXCInLFxuICAgICAgICAnVG8gc3RheSBhbm9ueW1vdXM6IFNheSBcIklcXCdsbCBzdGF5IGFub255bW91c1wiJyxcbiAgICAgIF0sXG4gICAgICBjdXJyZW50VmFsdWU6ICh2YWx1ZSkgPT4gdmFsdWUgfHwgJyhub3Qgc2V0IC0gYW5vbnltb3VzIG1vZGUpJyxcbiAgICB9LFxuICAgIFxuICAgIGdpdGh1YkludGVncmF0aW9uOiB7XG4gICAgICB0aXRsZTogJ/CflJAgU3RlcCAyOiBHaXRIdWIgSW50ZWdyYXRpb24gKE9wdGlvbmFsKScsXG4gICAgICBkZXNjcmlwdGlvbjogJ0Nvbm5lY3QgdG8gR2l0SHViIHRvIHNoYXJlIHlvdXIgY3JlYXRpb25zIGFuZCBicm93c2UgY29tbXVuaXR5IGNvbnRlbnQuJyxcbiAgICAgIGluc3RydWN0aW9uczogW1xuICAgICAgICAnVG8gY29ubmVjdCBHaXRIdWI6IFNheSBcIkNvbm5lY3QgbXkgR2l0SHViIGFjY291bnRcIicsXG4gICAgICAgICdUbyBza2lwOiBTYXkgXCJTa2lwIEdpdEh1YiBmb3Igbm93XCInLFxuICAgICAgXSxcbiAgICAgIGN1cnJlbnRWYWx1ZTogKHZhbHVlKSA9PiB2YWx1ZSA/ICdDb25uZWN0ZWQnIDogJyhub3QgY29ubmVjdGVkKScsXG4gICAgfSxcbiAgICBcbiAgICBwb3J0Zm9saW9TeW5jOiB7XG4gICAgICB0aXRsZTogJ/CflIQgU3RlcCAzOiBQb3J0Zm9saW8gU3luYyAoT3B0aW9uYWwpJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnQXV0b21hdGljYWxseSBiYWNrdXAgeW91ciBjcmVhdGlvbnMgdG8gR2l0SHViLicsXG4gICAgICBpbnN0cnVjdGlvbnM6IFtcbiAgICAgICAgJ1RvIGVuYWJsZTogU2F5IFwiRW5hYmxlIGF1dG8tc3luY1wiJyxcbiAgICAgICAgJ1RvIGtlZXAgbWFudWFsOiBTYXkgXCJJXFwnbGwgc3luYyBtYW51YWxseVwiJyxcbiAgICAgIF0sXG4gICAgICBjdXJyZW50VmFsdWU6ICh2YWx1ZSkgPT4gdmFsdWUgPyAnRW5hYmxlZCcgOiAnTWFudWFsJyxcbiAgICB9LFxuICAgIFxuICAgIGRpc3BsYXlQcmVmZXJlbmNlczoge1xuICAgICAgdGl0bGU6ICfwn46oIFN0ZXAgNDogRGlzcGxheSBQcmVmZXJlbmNlcycsXG4gICAgICBkZXNjcmlwdGlvbjogJ0N1c3RvbWl6ZSBob3cgRG9sbGhvdXNlTUNQIHNob3dzIGluZm9ybWF0aW9uLicsXG4gICAgICBpbnN0cnVjdGlvbnM6IFtcbiAgICAgICAgJ1RvIHNob3cgYWN0aXZlIHBlcnNvbmE6IFNheSBcIlNob3cgcGVyc29uYSBpbmRpY2F0b3JzXCInLFxuICAgICAgICAnVG8ga2VlcCBtaW5pbWFsOiBTYXkgXCJVc2UgbWluaW1hbCBkaXNwbGF5XCInLFxuICAgICAgXSxcbiAgICAgIGN1cnJlbnRWYWx1ZTogKHZhbHVlKSA9PiB2YWx1ZSA/ICdFbmFibGVkJyA6ICdNaW5pbWFsJyxcbiAgICB9LFxuICB9LFxuICBcbiAgaW5zdHJ1Y3Rpb25zOiB7XG4gICAgcXVpY2s6ICfwn5KhICoqUXVpY2sgU2V0dXAqKjogU2F5IFwiQ29uZmlndXJlIHRoZSBiYXNpY3NcIiB0byBzZXQganVzdCB1c2VybmFtZSBhbmQgR2l0SHViJyxcbiAgICBkZXRhaWxlZDogJ/Cfk50gKipEZXRhaWxlZCBTZXR1cCoqOiBTYXkgXCJDb25maWd1cmUgZXZlcnl0aGluZ1wiIHRvIGdvIHRocm91Z2ggYWxsIG9wdGlvbnMnLFxuICAgIHNraXA6ICfij63vuI8gKipTa2lwIGZvciBOb3cqKjogU2F5IFwiU2tpcCB3aXphcmRcIiB0byB1c2UgYW5vbnltb3VzIG1vZGUnLFxuICB9LFxuICBcbiAgZm9vdGVyOiAn4pyoIFlvdSBjYW4gYWx3YXlzIGNoYW5nZSB0aGVzZSBzZXR0aW5ncyBsYXRlciBieSBzYXlpbmcgXCJPcGVuIGNvbmZpZ3VyYXRpb24gd2l6YXJkXCInLFxufTtcblxuLyoqXG4gKiBGcmllbmRseSB2YWx1ZSByZXBsYWNlbWVudHMgZm9yIG51bGwvdW5kZWZpbmVkIGNvbmZpZyB2YWx1ZXNcbiAqL1xuZXhwb3J0IGNvbnN0IGZyaWVuZGx5TnVsbFZhbHVlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgLy8gVXNlciBmaWVsZHNcbiAgJ3VzZXIudXNlcm5hbWUnOiAnKG5vdCBzZXQgLSBhbm9ueW1vdXMgbW9kZSBhY3RpdmUpJyxcbiAgJ3VzZXIuZW1haWwnOiAnKG9wdGlvbmFsIC0gbm90IHNldCknLFxuICAndXNlci5kaXNwbGF5X25hbWUnOiAnKG5vdCBzZXQgLSB3aWxsIHVzZSB1c2VybmFtZSknLFxuICBcbiAgLy8gR2l0SHViIGZpZWxkc1xuICAnZ2l0aHViLmF1dGhfdG9rZW4nOiAnKG5vdCBjb25maWd1cmVkIC0gR2l0SHViIGZlYXR1cmVzIGRpc2FibGVkKScsXG4gICdnaXRodWIub2F1dGhfdG9rZW4nOiAnKG5vdCBhdXRoZW50aWNhdGVkKScsXG4gICdnaXRodWIuZGVmYXVsdF9yZXBvc2l0b3J5JzogJyhub3Qgc2V0IC0gd2lsbCB1c2UgZGVmYXVsdCknLFxuICAnZ2l0aHViLnVzZXJuYW1lJzogJyhub3QgY29ubmVjdGVkKScsXG4gIFxuICAvLyBQb3J0Zm9saW8gc3luYyBmaWVsZHNcbiAgJ3BvcnRmb2xpby5zeW5jX3N0YXR1cy5sYXN0X3N5bmMnOiAnKG5ldmVyIHN5bmNlZCknLFxuICAncG9ydGZvbGlvLnN5bmNfc3RhdHVzLmxhc3RfcHVzaCc6ICcobmV2ZXIgcHVzaGVkKScsXG4gICdwb3J0Zm9saW8uc3luY19zdGF0dXMubGFzdF9wdWxsJzogJyhuZXZlciBwdWxsZWQpJyxcbiAgJ3BvcnRmb2xpby5yZXBvc2l0b3J5X25hbWUnOiBgKHVzaW5nIGRlZmF1bHQ6ICR7cHJvY2Vzcy5lbnYuVEVTVF9HSVRIVUJfUkVQTyB8fCAnZG9sbGhvdXNlLXBvcnRmb2xpbyd9KWAsXG4gIFxuICAvLyBDb2xsZWN0aW9uIHN1Ym1pc3Npb25cbiAgJ2NvbGxlY3Rpb25fc3VibWlzc2lvbi5hdXRvX3N1Ym1pdCc6ICcoZGlzYWJsZWQpJyxcbiAgXG4gIC8vIEluZGljYXRvciBzZXR0aW5nc1xuICAnaW5kaWNhdG9yLmN1c3RvbV9mb3JtYXQnOiAnKHVzaW5nIGRlZmF1bHQgZm9ybWF0KScsXG4gIFxuICAvLyBEZWZhdWx0IGZvciBhbnkgb3RoZXIgbnVsbFxuICAnZGVmYXVsdCc6ICcobm90IHNldCknLFxufTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHdpemFyZCB0ZXh0IGluIHNwZWNpZmllZCBsYW5ndWFnZVxuICogQHBhcmFtIGxhbmd1YWdlIC0gTGFuZ3VhZ2UgY29kZSAoZS5nLiwgJ2VuJywgJ2VzJywgJ2ZyJylcbiAqIEByZXR1cm5zIFdpemFyZCB0ZW1wbGF0ZXMgZm9yIHRoZSBzcGVjaWZpZWQgbGFuZ3VhZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFdpemFyZFRlbXBsYXRlcyhsYW5ndWFnZTogc3RyaW5nID0gJ2VuJyk6IFdpemFyZFRlbXBsYXRlcyB7XG4gIC8vIEZvciBub3csIG9ubHkgRW5nbGlzaCBpcyBzdXBwb3J0ZWRcbiAgLy8gRnV0dXJlOiBMb2FkIGZyb20gbGFuZ3VhZ2Utc3BlY2lmaWMgZmlsZXNcbiAgc3dpdGNoIChsYW5ndWFnZSkge1xuICAgIGNhc2UgJ2VuJzpcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGRlZmF1bHRXaXphcmRUZW1wbGF0ZXM7XG4gIH1cbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IGZyaWVuZGx5IG51bGwgdmFsdWVcbiAqIEBwYXJhbSBwYXRoIC0gRG90LW5vdGF0aW9uIHBhdGggdG8gdGhlIGNvbmZpZyBmaWVsZFxuICogQHJldHVybnMgRnJpZW5kbHkgbWVzc2FnZSBmb3IgbnVsbCB2YWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnJpZW5kbHlOdWxsVmFsdWUocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGZyaWVuZGx5TnVsbFZhbHVlc1twYXRoXSB8fCBmcmllbmRseU51bGxWYWx1ZXNbJ2RlZmF1bHQnXTtcbn1cblxuLyoqXG4gKiBUZW1wbGF0ZSBidWlsZGVyIGZvciB3aXphcmQgc3RlcHNcbiAqIEFsbG93cyBmb3IgZHluYW1pYyBjb25zdHJ1Y3Rpb24gb2Ygd2l6YXJkIGNvbnRlbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFdpemFyZFRlbXBsYXRlQnVpbGRlciB7XG4gIHByaXZhdGUgdGVtcGxhdGVzOiBXaXphcmRUZW1wbGF0ZXM7XG4gIFxuICBjb25zdHJ1Y3RvcihsYW5ndWFnZTogc3RyaW5nID0gJ2VuJykge1xuICAgIHRoaXMudGVtcGxhdGVzID0gZ2V0V2l6YXJkVGVtcGxhdGVzKGxhbmd1YWdlKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEJ1aWxkIHRoZSBjb21wbGV0ZSB3aXphcmQgdGV4dFxuICAgKi9cbiAgYnVpbGRXaXphcmRUZXh0KGN1cnJlbnRDb25maWc6IGFueSk6IHN0cmluZyB7XG4gICAgY29uc3QgcGFydHM6IHN0cmluZ1tdID0gW1xuICAgICAgdGhpcy50ZW1wbGF0ZXMudGl0bGUsXG4gICAgICAnJyxcbiAgICAgIHRoaXMuYnVpbGRDdXJyZW50Q29uZmlnKGN1cnJlbnRDb25maWcpLFxuICAgICAgJycsXG4gICAgICB0aGlzLmJ1aWxkU3RlcHMoY3VycmVudENvbmZpZyksXG4gICAgICAnJyxcbiAgICAgIHRoaXMuYnVpbGRJbnN0cnVjdGlvbnMoKSxcbiAgICAgICcnLFxuICAgICAgdGhpcy50ZW1wbGF0ZXMuZm9vdGVyLFxuICAgIF07XG4gICAgXG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oJ1xcbicpO1xuICB9XG4gIFxuICAvKipcbiAgICogQnVpbGQgY3VycmVudCBjb25maWd1cmF0aW9uIHNlY3Rpb25cbiAgICovXG4gIHByaXZhdGUgYnVpbGRDdXJyZW50Q29uZmlnKGNvbmZpZzogYW55KTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7dGhpcy50ZW1wbGF0ZXMuY3VycmVudENvbmZpZ0hlYWRlcn1cblxcYFxcYFxcYHlhbWxcbiR7dGhpcy5mb3JtYXRDb25maWdBc1lhbWwoY29uZmlnKX1cblxcYFxcYFxcYGA7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBCdWlsZCBhbGwgd2l6YXJkIHN0ZXBzXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkU3RlcHMoY29uZmlnOiBhbnkpOiBzdHJpbmcge1xuICAgIGNvbnN0IHN0ZXBzID0gW107XG4gICAgXG4gICAgLy8gVXNlciBJZGVudGl0eVxuICAgIGNvbnN0IHVzZXJTdGVwID0gdGhpcy50ZW1wbGF0ZXMuc3RlcHMudXNlcklkZW50aXR5O1xuICAgIHN0ZXBzLnB1c2godGhpcy5mb3JtYXRTdGVwKHVzZXJTdGVwLCBjb25maWcudXNlcj8udXNlcm5hbWUpKTtcbiAgICBcbiAgICAvLyBHaXRIdWIgSW50ZWdyYXRpb25cbiAgICBjb25zdCBnaXRodWJTdGVwID0gdGhpcy50ZW1wbGF0ZXMuc3RlcHMuZ2l0aHViSW50ZWdyYXRpb247XG4gICAgc3RlcHMucHVzaCh0aGlzLmZvcm1hdFN0ZXAoZ2l0aHViU3RlcCwgY29uZmlnLmdpdGh1Yj8uYXV0aF90b2tlbikpO1xuICAgIFxuICAgIC8vIFBvcnRmb2xpbyBTeW5jXG4gICAgY29uc3QgcG9ydGZvbGlvU3RlcCA9IHRoaXMudGVtcGxhdGVzLnN0ZXBzLnBvcnRmb2xpb1N5bmM7XG4gICAgc3RlcHMucHVzaCh0aGlzLmZvcm1hdFN0ZXAocG9ydGZvbGlvU3RlcCwgY29uZmlnLnBvcnRmb2xpbz8uYXV0b19zeW5jKSk7XG4gICAgXG4gICAgLy8gRGlzcGxheSBQcmVmZXJlbmNlc1xuICAgIGNvbnN0IGRpc3BsYXlTdGVwID0gdGhpcy50ZW1wbGF0ZXMuc3RlcHMuZGlzcGxheVByZWZlcmVuY2VzO1xuICAgIHN0ZXBzLnB1c2godGhpcy5mb3JtYXRTdGVwKGRpc3BsYXlTdGVwLCBjb25maWcuaW5kaWNhdG9yPy5lbmFibGVkKSk7XG4gICAgXG4gICAgcmV0dXJuIHN0ZXBzLmpvaW4oJ1xcblxcbicpO1xuICB9XG4gIFxuICAvKipcbiAgICogRm9ybWF0IGEgc2luZ2xlIHdpemFyZCBzdGVwXG4gICAqL1xuICBwcml2YXRlIGZvcm1hdFN0ZXAoc3RlcDogV2l6YXJkU3RlcCwgY3VycmVudFZhbHVlOiBhbnkpOiBzdHJpbmcge1xuICAgIGNvbnN0IGxpbmVzID0gW1xuICAgICAgc3RlcC50aXRsZSxcbiAgICAgIHN0ZXAuZGVzY3JpcHRpb24sXG4gICAgXTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IGluc3RydWN0aW9uIG9mIHN0ZXAuaW5zdHJ1Y3Rpb25zKSB7XG4gICAgICBsaW5lcy5wdXNoKGAtICR7aW5zdHJ1Y3Rpb259YCk7XG4gICAgfVxuICAgIFxuICAgIGxpbmVzLnB1c2goYC0gQ3VycmVudDogJHtzdGVwLmN1cnJlbnRWYWx1ZShjdXJyZW50VmFsdWUpfWApO1xuICAgIFxuICAgIHJldHVybiBsaW5lcy5qb2luKCdcXG4nKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEJ1aWxkIGluc3RydWN0aW9uIG9wdGlvbnNcbiAgICovXG4gIHByaXZhdGUgYnVpbGRJbnN0cnVjdGlvbnMoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy50ZW1wbGF0ZXMuaW5zdHJ1Y3Rpb25zLnF1aWNrLFxuICAgICAgdGhpcy50ZW1wbGF0ZXMuaW5zdHJ1Y3Rpb25zLmRldGFpbGVkLFxuICAgICAgdGhpcy50ZW1wbGF0ZXMuaW5zdHJ1Y3Rpb25zLnNraXAsXG4gICAgXS5qb2luKCdcXG4nKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEZvcm1hdCBjb25maWcgYXMgWUFNTCAoc3R1YiAtIHdvdWxkIHVzZSBhY3R1YWwgeWFtbCBsaWJyYXJ5KVxuICAgKi9cbiAgcHJpdmF0ZSBmb3JtYXRDb25maWdBc1lhbWwoY29uZmlnOiBhbnkpOiBzdHJpbmcge1xuICAgIC8vIFRoaXMgd291bGQgdXNlIHRoZSBhY3R1YWwgeWFtbC5kdW1wIHdpdGggZnJpZW5kbHkgdmFsdWVzXG4gICAgLy8gRm9yIG5vdywgcmV0dXJuIGEgcGxhY2Vob2xkZXJcbiAgICByZXR1cm4gJ3VzZXI6XFxuICB1c2VybmFtZTogKG5vdCBzZXQpXFxuICBlbWFpbDogKG9wdGlvbmFsKSc7XG4gIH1cbn0iXX0=