codebakers 2.5.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +54 -255
  2. package/dist/chunk-HOWR3YTF.js +146 -0
  3. package/dist/index.d.ts +0 -3
  4. package/dist/index.js +10489 -7994
  5. package/dist/terminal-6ZQVP6R7.js +10 -0
  6. package/package.json +26 -41
  7. package/AUDIT_REPORT.md +0 -138
  8. package/dist/advisors-RWRTSJRR.js +0 -7
  9. package/dist/chunk-ASIJIQYC.js +0 -320
  10. package/dist/chunk-D44U3IEA.js +0 -565
  11. package/dist/chunk-LANM5XQW.js +0 -326
  12. package/dist/prd-RYITSL6Q.js +0 -7
  13. package/install.bat +0 -9
  14. package/installers/CodeBakers-Install.bat +0 -207
  15. package/installers/CodeBakers-Install.command +0 -232
  16. package/installers/README.md +0 -157
  17. package/installers/mac/assets/README.txt +0 -31
  18. package/installers/mac/build-mac-installer.sh +0 -240
  19. package/installers/windows/CodeBakers.iss +0 -256
  20. package/installers/windows/assets/README.txt +0 -16
  21. package/installers/windows/scripts/post-install.bat +0 -15
  22. package/src/channels/discord.ts +0 -5
  23. package/src/channels/slack.ts +0 -5
  24. package/src/channels/sms.ts +0 -4
  25. package/src/channels/telegram.ts +0 -5
  26. package/src/channels/whatsapp.ts +0 -7
  27. package/src/commands/advisors.ts +0 -699
  28. package/src/commands/build.ts +0 -1025
  29. package/src/commands/check.ts +0 -365
  30. package/src/commands/code.ts +0 -806
  31. package/src/commands/connect.ts +0 -12
  32. package/src/commands/deploy.ts +0 -448
  33. package/src/commands/design.ts +0 -298
  34. package/src/commands/fix.ts +0 -20
  35. package/src/commands/gateway.ts +0 -604
  36. package/src/commands/generate.ts +0 -178
  37. package/src/commands/init.ts +0 -634
  38. package/src/commands/integrate.ts +0 -884
  39. package/src/commands/learn.ts +0 -36
  40. package/src/commands/migrate.ts +0 -419
  41. package/src/commands/prd-maker.ts +0 -588
  42. package/src/commands/prd.ts +0 -419
  43. package/src/commands/security.ts +0 -102
  44. package/src/commands/setup.ts +0 -600
  45. package/src/commands/status.ts +0 -56
  46. package/src/commands/website.ts +0 -741
  47. package/src/index.ts +0 -627
  48. package/src/patterns/loader.ts +0 -337
  49. package/src/services/github.ts +0 -61
  50. package/src/services/supabase.ts +0 -147
  51. package/src/services/vercel.ts +0 -61
  52. package/src/utils/claude-md.ts +0 -287
  53. package/src/utils/config.ts +0 -375
  54. package/src/utils/display.ts +0 -338
  55. package/src/utils/files.ts +0 -418
  56. package/src/utils/nlp.ts +0 -312
  57. package/src/utils/ui.ts +0 -441
  58. package/src/utils/updates.ts +0 -8
  59. package/src/utils/voice.ts +0 -323
  60. package/tsconfig.json +0 -26
@@ -0,0 +1,10 @@
1
+ import {
2
+ Terminal,
3
+ extractPackages,
4
+ parseErrors
5
+ } from "./chunk-HOWR3YTF.js";
6
+ export {
7
+ Terminal,
8
+ extractPackages,
9
+ parseErrors
10
+ };
package/package.json CHANGED
@@ -1,83 +1,68 @@
1
1
  {
2
2
  "name": "codebakers",
3
- "version": "2.5.3",
4
- "description": "AI dev team that follows the rules. Build apps from anywhere with pattern enforcement.",
3
+ "version": "3.0.0",
4
+ "description": "AI-powered product development CLI - Build faster with pattern enforcement, persistent memory, and parallel agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
- "codebakers": "./dist/index.js",
9
- "cb": "./dist/index.js"
8
+ "cb": "./dist/index.js",
9
+ "codebakers": "./dist/index.js"
10
10
  },
11
+ "files": [
12
+ "dist"
13
+ ],
11
14
  "scripts": {
12
15
  "build": "tsup src/index.ts --format esm --dts --clean",
13
16
  "dev": "tsup src/index.ts --format esm --watch",
14
17
  "start": "node dist/index.js",
15
- "typecheck": "tsc --noEmit",
16
- "lint": "eslint src/",
17
- "test": "vitest",
18
18
  "prepublishOnly": "npm run build"
19
19
  },
20
20
  "keywords": [
21
21
  "cli",
22
22
  "ai",
23
23
  "codebakers",
24
+ "claude",
25
+ "anthropic",
24
26
  "code-generation",
25
- "pattern-enforcement",
27
+ "patterns",
26
28
  "developer-tools",
27
- "automation",
28
- "nextjs",
29
- "supabase",
30
- "vercel"
29
+ "productivity"
31
30
  ],
32
- "author": "BotMakers Inc",
31
+ "author": "BotMakers Inc <support@botmakers.ai>",
33
32
  "license": "MIT",
33
+ "homepage": "https://codebakers.ai",
34
34
  "repository": {
35
35
  "type": "git",
36
36
  "url": "https://github.com/botmakers/codebakers-cli"
37
37
  },
38
- "homepage": "https://codebakers.dev",
38
+ "bugs": {
39
+ "url": "https://github.com/botmakers/codebakers-cli/issues"
40
+ },
39
41
  "engines": {
40
42
  "node": ">=18.0.0"
41
43
  },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
42
47
  "dependencies": {
43
48
  "@anthropic-ai/sdk": "^0.32.1",
44
49
  "@clack/prompts": "^0.7.0",
45
- "@octokit/rest": "^21.0.0",
46
- "@supabase/supabase-js": "^2.45.0",
47
- "axios": "^1.7.0",
48
- "boxen": "^8.0.0",
50
+ "@supabase/supabase-js": "^2.39.0",
49
51
  "chalk": "^5.3.0",
50
- "cli-table3": "^0.6.5",
51
- "commander": "^12.1.0",
52
52
  "conf": "^13.0.0",
53
- "dotenv": "^16.4.5",
54
- "execa": "^9.3.0",
55
- "fast-glob": "^3.3.2",
56
- "figures": "^6.1.0",
53
+ "execa": "^8.0.1",
57
54
  "fs-extra": "^11.2.0",
58
- "gradient-string": "^2.0.2",
59
- "inquirer": "^10.0.0",
60
- "node-fetch": "^3.3.2",
61
- "open": "^10.1.0",
55
+ "glob": "^10.3.10",
56
+ "ignore": "^5.3.0",
57
+ "open": "^11.0.0",
62
58
  "ora": "^8.0.1",
63
- "picocolors": "^1.0.1",
64
- "simple-git": "^3.25.0",
65
- "strip-ansi": "^7.1.0",
66
- "terminal-link": "^3.0.0",
67
- "update-notifier": "^7.1.0",
68
- "which": "^4.0.0",
59
+ "simple-git": "^3.22.0",
69
60
  "zod": "^3.23.8"
70
61
  },
71
62
  "devDependencies": {
72
63
  "@types/fs-extra": "^11.0.4",
73
- "@types/gradient-string": "^1.1.6",
74
- "@types/inquirer": "^9.0.7",
75
64
  "@types/node": "^22.0.0",
76
- "@types/update-notifier": "^6.0.8",
77
- "@types/which": "^3.0.4",
78
- "eslint": "^9.8.0",
79
65
  "tsup": "^8.2.0",
80
- "typescript": "^5.5.0",
81
- "vitest": "^2.0.0"
66
+ "typescript": "^5.5.0"
82
67
  }
83
68
  }
package/AUDIT_REPORT.md DELETED
@@ -1,138 +0,0 @@
1
- # CodeBakers CLI Audit Report
2
-
3
- ## Summary
4
- - **Total TypeScript Errors**: 206 (mostly non-critical type issues)
5
- - **Critical Runtime Bugs Found**: 3
6
- - **Moderate Issues**: 12
7
- - **Minor Issues**: Many (type annotations)
8
-
9
- ---
10
-
11
- ## 🔴 CRITICAL ISSUES (Will crash at runtime)
12
-
13
- ### 1. ~~Missing `execa` import in prd-maker.ts~~ ✅ FIXED
14
- **File**: `src/commands/prd-maker.ts`
15
- **Issue**: `execa` was used but not imported
16
- **Status**: Fixed
17
-
18
- ### 2. ~~Duplicate function declarations in prd-maker.ts~~ ✅ FIXED
19
- **File**: `src/commands/prd-maker.ts`
20
- **Issue**: `getVoiceInput` and `checkVoiceAvailability` were both imported AND defined locally
21
- **Status**: Fixed (removed imports, kept local implementations)
22
-
23
- ### 3. ~~fs-extra import style causing writeJson to fail~~ ✅ FIXED (Previous session)
24
- **Files**: All command files
25
- **Issue**: `import * as fs from 'fs-extra'` doesn't work in ESM
26
- **Status**: Fixed to `import fs from 'fs-extra'`
27
-
28
- ---
29
-
30
- ## 🟡 MODERATE ISSUES (May cause unexpected behavior)
31
-
32
- ### 4. Missing try-catch around async operations
33
- **Files affected**:
34
- - `build.ts`: 15 async calls, only 5 try blocks
35
- - `deploy.ts`: 10 async calls, only 8 try blocks
36
- - `migrate.ts`: 17 async calls, only 7 try blocks
37
- - `website.ts`: 8 async calls, only 4 try blocks
38
-
39
- **Risk**: Unhandled promise rejections can crash the CLI
40
- **Recommendation**: Add try-catch or handle with .catch()
41
-
42
- ### 5. Silent failures with `reject: false`
43
- **Files**: `build.ts`, `deploy.ts`, `integrate.ts`, `migrate.ts`
44
- **Locations**:
45
- ```
46
- build.ts:541, 554, 578, 890, 904, 908
47
- deploy.ts:320
48
- integrate.ts:685
49
- migrate.ts:105, 108
50
- ```
51
- **Risk**: Commands may appear to succeed when they actually failed
52
- **Recommendation**: Log failures or show warnings to users
53
-
54
- ### 6. Vercel deploy returns incomplete object
55
- **File**: `src/commands/deploy.ts:233`
56
- **Issue**: Accesses `deployment.dashboardUrl` but Vercel service only returns `{ url: string }`
57
- **Fix needed**: Update VercelService to return dashboardUrl or remove that line
58
-
59
- ### 7. Type issues with package.json generation in init.ts
60
- **File**: `src/commands/init.ts:394-423`
61
- **Issue**: Dynamic property assignment to typed objects
62
- **Risk**: TypeScript errors, but works at runtime
63
- **Recommendation**: Type the objects as `Record<string, string>`
64
-
65
- ---
66
-
67
- ## 🟢 MINOR ISSUES (Won't crash, but should fix)
68
-
69
- ### 8. Anthropic response type checking
70
- **Files**: Most AI command files
71
- **Current code**:
72
- ```typescript
73
- const text = response.content[0].type === 'text' ? response.content[0].text : '';
74
- ```
75
- **Issue**: Accesses `[0]` without checking if array has elements
76
- **Better**:
77
- ```typescript
78
- const firstContent = response.content?.[0];
79
- const text = firstContent?.type === 'text' ? firstContent.text : '';
80
- ```
81
-
82
- ### 9. Potential null pointer on string operations
83
- **Files**: Multiple
84
- **Examples**:
85
- - `advisors.ts:488`: `projectName.toUpperCase()` - projectName could be undefined
86
- - `code.ts:135`: `input.trim()` - input could be undefined
87
-
88
- ### 10. Symbol to string conversion
89
- **File**: `code.ts:590`
90
- **Issue**: Implicit symbol to string conversion will fail
91
- **Recommendation**: Wrap in `String(...)`
92
-
93
- ---
94
-
95
- ## 📊 TypeScript Error Categories
96
-
97
- | Error Code | Count | Description | Severity |
98
- |------------|-------|-------------|----------|
99
- | TS2532 | 72 | Object possibly undefined | Low |
100
- | TS2339 | 22 | Property doesn't exist on type | Low |
101
- | TS7053 | 15 | Dynamic index signature | Low |
102
- | TS2345 | 11 | Type assignment mismatch | Low |
103
- | TS2322 | 10 | Type mismatch | Low |
104
- | TS18048 | 7 | Possibly undefined | Low |
105
- | TS2440 | 2 | Duplicate declarations | Fixed |
106
- | TS7006 | 1 | Implicit any | Low |
107
- | TS2769 | 1 | No overload matches | Medium |
108
- | TS2731 | 1 | Symbol conversion | Medium |
109
-
110
- ---
111
-
112
- ## ✅ Already Working Well
113
-
114
- 1. **Config system** - Solid implementation with Zod validation
115
- 2. **Service classes** - GitHub, Vercel, Supabase all properly structured
116
- 3. **CLI structure** - Commander.js setup is correct
117
- 4. **Error display utilities** - New display.ts is well-implemented
118
- 5. **Voice input** - Has fallback to text input
119
-
120
- ---
121
-
122
- ## 🔧 Recommended Fixes Priority
123
-
124
- 1. ✅ ~~Fix prd-maker.ts imports~~ DONE
125
- 2. 🔴 Fix deploy.ts dashboardUrl issue
126
- 3. 🔴 Add better error handling to build.ts and migrate.ts
127
- 4. 🟡 Add null checks for Anthropic responses
128
- 5. 🟡 Fix init.ts type issues
129
- 6. 🟢 Add strict TypeScript checks gradually
130
-
131
- ---
132
-
133
- ## Next Steps
134
-
135
- 1. Test all commands manually
136
- 2. Add integration tests
137
- 3. Gradually enable stricter TypeScript
138
- 4. Add more comprehensive error handling
@@ -1,7 +0,0 @@
1
- import {
2
- advisorsCommand
3
- } from "./chunk-D44U3IEA.js";
4
- import "./chunk-ASIJIQYC.js";
5
- export {
6
- advisorsCommand
7
- };
@@ -1,320 +0,0 @@
1
- // src/utils/config.ts
2
- import Conf from "conf";
3
- import fsExtra from "fs-extra";
4
- import { existsSync, readFileSync, appendFileSync } from "fs";
5
- import * as path from "path";
6
- import os from "os";
7
- import { z } from "zod";
8
- var ConfigSchema = z.object({
9
- version: z.string().default("1.0.0"),
10
- credentials: z.object({
11
- github: z.object({
12
- token: z.string().optional(),
13
- username: z.string().optional()
14
- }).optional(),
15
- vercel: z.object({
16
- token: z.string().optional(),
17
- teamId: z.string().optional()
18
- }).optional(),
19
- supabase: z.object({
20
- accessToken: z.string().optional(),
21
- orgId: z.string().optional()
22
- }).optional(),
23
- anthropic: z.object({
24
- apiKey: z.string().optional()
25
- }).optional(),
26
- openai: z.object({
27
- apiKey: z.string().optional()
28
- }).optional(),
29
- stripe: z.object({
30
- secretKey: z.string().optional(),
31
- publishableKey: z.string().optional(),
32
- webhookSecret: z.string().optional()
33
- }).optional(),
34
- twilio: z.object({
35
- accountSid: z.string().optional(),
36
- authToken: z.string().optional(),
37
- phoneNumber: z.string().optional()
38
- }).optional(),
39
- vapi: z.object({
40
- apiKey: z.string().optional()
41
- }).optional(),
42
- resend: z.object({
43
- apiKey: z.string().optional()
44
- }).optional(),
45
- elevenLabs: z.object({
46
- apiKey: z.string().optional()
47
- }).optional(),
48
- microsoft: z.object({
49
- clientId: z.string().optional(),
50
- clientSecret: z.string().optional(),
51
- tenantId: z.string().optional()
52
- }).optional(),
53
- google: z.object({
54
- clientId: z.string().optional(),
55
- clientSecret: z.string().optional()
56
- }).optional()
57
- }).default({}),
58
- preferences: z.object({
59
- defaultFramework: z.string().optional(),
60
- defaultUI: z.string().optional(),
61
- defaultPackages: z.array(z.string()).optional(),
62
- deployToPreviewFirst: z.boolean().default(true)
63
- }).default({}),
64
- learning: z.object({
65
- enabled: z.boolean().default(true),
66
- shortcuts: z.record(z.string()).default({}),
67
- preferences: z.record(z.any()).default({}),
68
- rejections: z.array(z.string()).default([]),
69
- workflows: z.record(z.array(z.string())).default({})
70
- }).default({}),
71
- projects: z.array(z.object({
72
- name: z.string(),
73
- path: z.string(),
74
- github: z.string().optional(),
75
- vercel: z.string().optional(),
76
- supabase: z.string().optional(),
77
- createdAt: z.string()
78
- })).default([]),
79
- channels: z.object({
80
- whatsapp: z.object({
81
- enabled: z.boolean().default(false),
82
- phoneNumber: z.string().optional()
83
- }).optional(),
84
- telegram: z.object({
85
- enabled: z.boolean().default(false),
86
- botToken: z.string().optional()
87
- }).optional(),
88
- discord: z.object({
89
- enabled: z.boolean().default(false),
90
- botToken: z.string().optional()
91
- }).optional(),
92
- slack: z.object({
93
- enabled: z.boolean().default(false),
94
- botToken: z.string().optional()
95
- }).optional()
96
- }).default({})
97
- });
98
- var Config = class {
99
- conf;
100
- configDir;
101
- constructor() {
102
- this.configDir = path.join(os.homedir(), ".codebakers");
103
- fsExtra.ensureDirSync(this.configDir);
104
- fsExtra.ensureDirSync(path.join(this.configDir, "patterns"));
105
- fsExtra.ensureDirSync(path.join(this.configDir, "templates"));
106
- fsExtra.ensureDirSync(path.join(this.configDir, "learning"));
107
- this.conf = new Conf({
108
- projectName: "codebakers",
109
- cwd: this.configDir,
110
- schema: {
111
- version: { type: "string", default: "1.0.0" },
112
- credentials: { type: "object", default: {} },
113
- preferences: { type: "object", default: {} },
114
- learning: { type: "object", default: { enabled: true, shortcuts: {}, preferences: {}, rejections: [], workflows: {} } },
115
- projects: { type: "array", default: [] },
116
- channels: { type: "object", default: {} }
117
- }
118
- });
119
- }
120
- // Check if initial setup is complete
121
- isConfigured() {
122
- const creds = this.conf.get("credentials") || {};
123
- return !!(creds.github?.token && creds.vercel?.token && creds.supabase?.accessToken && creds.anthropic?.apiKey);
124
- }
125
- // Check if current directory is a CodeBakers project
126
- isInProject() {
127
- const cwd = process.cwd();
128
- const codebakersDir = path.join(cwd, ".codebakers");
129
- const claudeFile = path.join(cwd, "CLAUDE.md");
130
- if (existsSync(codebakersDir) || existsSync(claudeFile)) {
131
- return true;
132
- }
133
- const projectIndicators = [
134
- "package.json",
135
- "next.config.js",
136
- "next.config.mjs",
137
- "next.config.ts",
138
- "vite.config.ts",
139
- "vite.config.js",
140
- "remix.config.js",
141
- "astro.config.mjs"
142
- ];
143
- const hasProjectFile = projectIndicators.some(
144
- (file) => existsSync(path.join(cwd, file))
145
- );
146
- if (hasProjectFile) {
147
- this.autoInitExisting(cwd);
148
- return true;
149
- }
150
- return false;
151
- }
152
- // Auto-initialize CodeBakers in an existing project
153
- autoInitExisting(cwd) {
154
- try {
155
- let framework = "unknown";
156
- let ui = "unknown";
157
- if (existsSync(path.join(cwd, "next.config.js")) || existsSync(path.join(cwd, "next.config.mjs")) || existsSync(path.join(cwd, "next.config.ts"))) {
158
- framework = "nextjs";
159
- } else if (existsSync(path.join(cwd, "vite.config.ts")) || existsSync(path.join(cwd, "vite.config.js"))) {
160
- framework = "vite";
161
- } else if (existsSync(path.join(cwd, "remix.config.js"))) {
162
- framework = "remix";
163
- } else if (existsSync(path.join(cwd, "astro.config.mjs"))) {
164
- framework = "astro";
165
- }
166
- const pkgPath = path.join(cwd, "package.json");
167
- if (existsSync(pkgPath)) {
168
- const pkg = fsExtra.readJsonSync(pkgPath);
169
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
170
- if (deps["@shadcn/ui"] || deps["class-variance-authority"]) {
171
- ui = "shadcn";
172
- } else if (deps["@chakra-ui/react"]) {
173
- ui = "chakra";
174
- } else if (deps["@mantine/core"]) {
175
- ui = "mantine";
176
- } else if (deps["@mui/material"]) {
177
- ui = "mui";
178
- }
179
- }
180
- const configDir = path.join(cwd, ".codebakers");
181
- fsExtra.ensureDirSync(configDir);
182
- const config = {
183
- name: path.basename(cwd),
184
- framework,
185
- ui,
186
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
187
- autoDetected: true
188
- };
189
- fsExtra.writeJsonSync(path.join(configDir, "config.json"), config, { spaces: 2 });
190
- const gitignorePath = path.join(cwd, ".gitignore");
191
- if (existsSync(gitignorePath)) {
192
- const gitignore = readFileSync(gitignorePath, "utf-8");
193
- if (!gitignore.includes(".codebakers")) {
194
- appendFileSync(gitignorePath, "\n# CodeBakers\n.codebakers/\n");
195
- }
196
- }
197
- } catch {
198
- }
199
- }
200
- // Get current project config
201
- getProjectConfig() {
202
- const cwd = process.cwd();
203
- const configPath = path.join(cwd, ".codebakers", "config.json");
204
- if (existsSync(configPath)) {
205
- return fsExtra.readJsonSync(configPath);
206
- }
207
- return null;
208
- }
209
- // Credentials
210
- getCredentials(service) {
211
- const creds = this.conf.get("credentials") || {};
212
- return creds[service];
213
- }
214
- setCredentials(service, credentials) {
215
- const current = this.conf.get("credentials") || {};
216
- this.conf.set("credentials", {
217
- ...current,
218
- [service]: { ...current[service], ...credentials }
219
- });
220
- }
221
- // Preferences
222
- getPreference(key) {
223
- const prefs = this.conf.get("preferences") || {};
224
- return prefs[key];
225
- }
226
- setPreference(key, value) {
227
- const current = this.conf.get("preferences") || {};
228
- this.conf.set("preferences", { ...current, [key]: value });
229
- }
230
- // Learning
231
- getLearning() {
232
- return this.conf.get("learning") || { enabled: true, shortcuts: {}, preferences: {}, rejections: [], workflows: {} };
233
- }
234
- addShortcut(shortcut, expansion) {
235
- const learning = this.getLearning();
236
- learning.shortcuts[shortcut] = expansion;
237
- this.conf.set("learning", learning);
238
- }
239
- addRejection(item) {
240
- const learning = this.getLearning();
241
- if (!learning.rejections.includes(item)) {
242
- learning.rejections.push(item);
243
- this.conf.set("learning", learning);
244
- }
245
- }
246
- addWorkflow(name, steps) {
247
- const learning = this.getLearning();
248
- learning.workflows[name] = steps;
249
- this.conf.set("learning", learning);
250
- }
251
- learnPreference(key, value) {
252
- const learning = this.getLearning();
253
- learning.preferences[key] = value;
254
- this.conf.set("learning", learning);
255
- }
256
- forgetPreference(key) {
257
- const learning = this.getLearning();
258
- delete learning.preferences[key];
259
- this.conf.set("learning", learning);
260
- }
261
- resetLearning() {
262
- this.conf.set("learning", { enabled: true, shortcuts: {}, preferences: {}, rejections: [], workflows: {} });
263
- }
264
- // Projects
265
- getProjects() {
266
- return this.conf.get("projects") || [];
267
- }
268
- addProject(project) {
269
- const projects = this.getProjects();
270
- projects.push(project);
271
- this.conf.set("projects", projects);
272
- }
273
- // Channels
274
- getChannelConfig(channel) {
275
- const channels = this.conf.get("channels") || {};
276
- return channels[channel];
277
- }
278
- setChannelConfig(channel, config) {
279
- const current = this.conf.get("channels") || {};
280
- this.conf.set("channels", { ...current, [channel]: config });
281
- }
282
- // Config directory access
283
- getConfigDir() {
284
- return this.configDir;
285
- }
286
- getPatternsDir() {
287
- return path.join(this.configDir, "patterns");
288
- }
289
- getTemplatesDir() {
290
- return path.join(this.configDir, "templates");
291
- }
292
- getLearningDir() {
293
- return path.join(this.configDir, "learning");
294
- }
295
- // Export/Import
296
- exportConfig() {
297
- return {
298
- version: this.conf.get("version") || "1.0.0",
299
- credentials: {},
300
- // Don't export credentials
301
- preferences: this.conf.get("preferences") || {},
302
- learning: this.getLearning(),
303
- projects: this.getProjects(),
304
- channels: {}
305
- // Don't export channel tokens
306
- };
307
- }
308
- importConfig(config) {
309
- if (config.preferences) {
310
- this.conf.set("preferences", config.preferences);
311
- }
312
- if (config.learning) {
313
- this.conf.set("learning", config.learning);
314
- }
315
- }
316
- };
317
-
318
- export {
319
- Config
320
- };