developer-ai 1.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 (105) hide show
  1. package/README.md +241 -0
  2. package/bin/developer-ai.js +2 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +219 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config/index.d.ts +7 -0
  8. package/dist/config/index.d.ts.map +1 -0
  9. package/dist/config/index.js +82 -0
  10. package/dist/config/index.js.map +1 -0
  11. package/dist/config/schema.d.ts +115 -0
  12. package/dist/config/schema.d.ts.map +1 -0
  13. package/dist/config/schema.js +29 -0
  14. package/dist/config/schema.js.map +1 -0
  15. package/dist/constants.d.ts +8 -0
  16. package/dist/constants.d.ts.map +1 -0
  17. package/dist/constants.js +8 -0
  18. package/dist/constants.js.map +1 -0
  19. package/dist/core/agent.d.ts +38 -0
  20. package/dist/core/agent.d.ts.map +1 -0
  21. package/dist/core/agent.js +155 -0
  22. package/dist/core/agent.js.map +1 -0
  23. package/dist/core/system-prompt.d.ts +6 -0
  24. package/dist/core/system-prompt.d.ts.map +1 -0
  25. package/dist/core/system-prompt.js +44 -0
  26. package/dist/core/system-prompt.js.map +1 -0
  27. package/dist/core/types.d.ts +42 -0
  28. package/dist/core/types.d.ts.map +1 -0
  29. package/dist/core/types.js +6 -0
  30. package/dist/core/types.js.map +1 -0
  31. package/dist/index.d.ts +15 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +12 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/mcp/client.d.ts +13 -0
  36. package/dist/mcp/client.d.ts.map +1 -0
  37. package/dist/mcp/client.js +202 -0
  38. package/dist/mcp/client.js.map +1 -0
  39. package/dist/providers/ollama.d.ts +13 -0
  40. package/dist/providers/ollama.d.ts.map +1 -0
  41. package/dist/providers/ollama.js +60 -0
  42. package/dist/providers/ollama.js.map +1 -0
  43. package/dist/providers/openai.d.ts +9 -0
  44. package/dist/providers/openai.d.ts.map +1 -0
  45. package/dist/providers/openai.js +40 -0
  46. package/dist/providers/openai.js.map +1 -0
  47. package/dist/skills/loader.d.ts +25 -0
  48. package/dist/skills/loader.d.ts.map +1 -0
  49. package/dist/skills/loader.js +93 -0
  50. package/dist/skills/loader.js.map +1 -0
  51. package/dist/tests/tools.test.d.ts +2 -0
  52. package/dist/tests/tools.test.d.ts.map +1 -0
  53. package/dist/tests/tools.test.js +170 -0
  54. package/dist/tests/tools.test.js.map +1 -0
  55. package/dist/tools/index.d.ts +5 -0
  56. package/dist/tools/index.d.ts.map +1 -0
  57. package/dist/tools/index.js +19 -0
  58. package/dist/tools/index.js.map +1 -0
  59. package/dist/tools/list-files.d.ts +3 -0
  60. package/dist/tools/list-files.d.ts.map +1 -0
  61. package/dist/tools/list-files.js +60 -0
  62. package/dist/tools/list-files.js.map +1 -0
  63. package/dist/tools/read-file.d.ts +3 -0
  64. package/dist/tools/read-file.d.ts.map +1 -0
  65. package/dist/tools/read-file.js +46 -0
  66. package/dist/tools/read-file.js.map +1 -0
  67. package/dist/tools/registry.d.ts +24 -0
  68. package/dist/tools/registry.d.ts.map +1 -0
  69. package/dist/tools/registry.js +37 -0
  70. package/dist/tools/registry.js.map +1 -0
  71. package/dist/tools/run-command.d.ts +3 -0
  72. package/dist/tools/run-command.d.ts.map +1 -0
  73. package/dist/tools/run-command.js +114 -0
  74. package/dist/tools/run-command.js.map +1 -0
  75. package/dist/tools/search-text.d.ts +3 -0
  76. package/dist/tools/search-text.d.ts.map +1 -0
  77. package/dist/tools/search-text.js +103 -0
  78. package/dist/tools/search-text.js.map +1 -0
  79. package/dist/tools/utils.d.ts +6 -0
  80. package/dist/tools/utils.d.ts.map +1 -0
  81. package/dist/tools/utils.js +14 -0
  82. package/dist/tools/utils.js.map +1 -0
  83. package/dist/tools/web-search.d.ts +3 -0
  84. package/dist/tools/web-search.d.ts.map +1 -0
  85. package/dist/tools/web-search.js +80 -0
  86. package/dist/tools/web-search.js.map +1 -0
  87. package/dist/tools/write-file.d.ts +3 -0
  88. package/dist/tools/write-file.d.ts.map +1 -0
  89. package/dist/tools/write-file.js +66 -0
  90. package/dist/tools/write-file.js.map +1 -0
  91. package/package.json +54 -0
  92. package/skills/accessibility/SKILL.md +496 -0
  93. package/skills/api-design/SKILL.md +419 -0
  94. package/skills/code-review/SKILL.md +267 -0
  95. package/skills/debugging/SKILL.md +332 -0
  96. package/skills/documentation/SKILL.md +496 -0
  97. package/skills/error-handling/SKILL.md +504 -0
  98. package/skills/git-workflow/SKILL.md +448 -0
  99. package/skills/human-like-coding/SKILL.md +400 -0
  100. package/skills/performance-optimization/SKILL.md +412 -0
  101. package/skills/prompt-engineering/SKILL.md +362 -0
  102. package/skills/refactoring/SKILL.md +457 -0
  103. package/skills/security-audit/SKILL.md +453 -0
  104. package/skills/testing-strategy/SKILL.md +501 -0
  105. package/skills/webapp-testing/SKILL.md +309 -0
package/README.md ADDED
@@ -0,0 +1,241 @@
1
+ # Developer-AI
2
+
3
+ A production-grade, terminal-based AI coding assistant. Think of it as GitHub Copilot for your terminal — it reads and writes files, runs commands, searches your codebase, and iterates on tasks using structured tool calls.
4
+
5
+ ## Features
6
+
7
+ - **Interactive REPL** — chat with the agent in your terminal
8
+ - **One-shot mode** — pass an instruction as an argument
9
+ - **Multi-provider** — OpenAI (cloud) or Ollama (local)
10
+ - **Tool-driven agent** — structured tool calls for file I/O, shell commands, text search
11
+ - **MCP support** — connect Model Context Protocol servers for additional tools
12
+ - **Web search** — Brave Search or Serper integration
13
+ - **Agent Skills** — loads SKILL.md files for domain-specific guidance
14
+ - **Safety first** — path sandboxing, command allowlists, confirmation prompts
15
+
16
+ ## Quick Start
17
+
18
+ ```bash
19
+ # Install globally
20
+ npm install -g developer-ai
21
+
22
+ # First-time setup
23
+ developer-ai onboard
24
+
25
+ # Interactive mode
26
+ developer-ai
27
+
28
+ # One-shot mode
29
+ developer-ai "Create a landing page for an AI startup called Inferencia"
30
+ ```
31
+
32
+ ## Installation
33
+
34
+ ### From npm
35
+
36
+ ```bash
37
+ npm install -g developer-ai
38
+ ```
39
+
40
+ ### From source
41
+
42
+ ```bash
43
+ git clone https://github.com/your-username/developer-ai.git
44
+ cd developer-ai/coder
45
+ npm install
46
+ npm run build
47
+ npm link # makes `developer-ai` available globally
48
+ ```
49
+
50
+ ## Configuration
51
+
52
+ ### Onboarding
53
+
54
+ Run `developer-ai onboard` to set up:
55
+ 1. **Provider** — choose between Ollama (local) or OpenAI (cloud)
56
+ 2. **API key** — for OpenAI (stored in `~/.developer-ai/config.json` with 0600 permissions)
57
+ 3. **Web search** — optional Brave Search or Serper API key
58
+
59
+ ### Config File
60
+
61
+ Located at `~/.developer-ai/config.json`:
62
+
63
+ ```json
64
+ {
65
+ "provider": "openai",
66
+ "openai": {
67
+ "apiKey": "sk-...",
68
+ "model": "gpt-4o"
69
+ },
70
+ "ollama": {
71
+ "model": "llama3.1",
72
+ "baseUrl": "http://localhost:11434"
73
+ },
74
+ "webSearch": {
75
+ "provider": "brave",
76
+ "braveApiKey": "BSA..."
77
+ }
78
+ }
79
+ ```
80
+
81
+ ### Environment Variables
82
+
83
+ Environment variables override config file values:
84
+
85
+ | Variable | Description |
86
+ |----------|-------------|
87
+ | `OPENAI_API_KEY` | OpenAI API key (auto-selects OpenAI provider) |
88
+ | `OPENAI_MODEL` | OpenAI model override |
89
+ | `OLLAMA_MODEL` | Ollama model name |
90
+ | `OLLAMA_BASE_URL` | Ollama server URL |
91
+ | `BRAVE_SEARCH_API_KEY` | Brave Search API key |
92
+ | `SERPER_API_KEY` | Serper.dev API key |
93
+
94
+ ## Providers
95
+
96
+ ### OpenAI
97
+
98
+ Uses the official `openai` Node.js SDK. Requires an API key.
99
+
100
+ ```bash
101
+ export OPENAI_API_KEY=sk-...
102
+ developer-ai "Explain this codebase"
103
+ ```
104
+
105
+ ### Ollama
106
+
107
+ Connects to a local Ollama instance via HTTP. No API key needed.
108
+
109
+ ```bash
110
+ # Make sure Ollama is running
111
+ ollama serve
112
+
113
+ # Use a specific model
114
+ export OLLAMA_MODEL=qwen2.5:14b
115
+ developer-ai
116
+ ```
117
+
118
+ ## Tools
119
+
120
+ The agent has access to these tools:
121
+
122
+ | Tool | Description |
123
+ |------|-------------|
124
+ | `read_file` | Read a file from the workspace |
125
+ | `write_file` | Create or update a file (with overwrite confirmation) |
126
+ | `list_files` | List directory contents with glob filtering |
127
+ | `search_text` | Search across files with string or regex |
128
+ | `run_command` | Execute shell commands (with safety gates) |
129
+ | `web_search` | Search the web via Brave or Serper |
130
+
131
+ ### Safety
132
+
133
+ - **Path sandboxing** — all file operations are restricted to the workspace directory
134
+ - **Command allowlist** — safe commands (`ls`, `cat`, `npm`, `git`, etc.) run automatically; others require confirmation
135
+ - **Dangerous command detection** — patterns like `rm -rf`, `curl | sh`, etc. are always flagged
136
+ - **Overwrite protection** — existing files require explicit confirmation
137
+
138
+ ## MCP (Model Context Protocol)
139
+
140
+ Developer-AI supports MCP servers, exposing their tools to the agent with namespaced names.
141
+
142
+ ### Configuration
143
+
144
+ Create `~/.developer-ai/mcp.json` (global) or `.developer-ai/mcp.json` (per-project):
145
+
146
+ ```json
147
+ {
148
+ "servers": {
149
+ "filesystem": {
150
+ "command": "npx",
151
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"],
152
+ "env": {}
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ MCP tools appear as `mcp_<server>_<tool>` in the agent's tool registry.
159
+
160
+ ## Skills
161
+
162
+ Developer-AI loads SKILL.md files to provide domain-specific guidance. Skills are matched to queries using lightweight keyword scoring.
163
+
164
+ ### Bundled Skills
165
+
166
+ The package includes skills for: accessibility, API design, code review, debugging, documentation, error handling, git workflow, human-like coding, performance optimization, prompt engineering, refactoring, security audit, testing strategy, and webapp testing.
167
+
168
+ ### Skill Locations (priority order)
169
+
170
+ 1. Package built-in: `<package>/skills/`
171
+ 2. Workspace: `.github/skills/`
172
+ 3. Workspace: `skills/`
173
+
174
+ ## CLI Reference
175
+
176
+ ```
177
+ Usage: developer-ai [options] [command] [instruction...]
178
+
179
+ Terminal-based AI coding assistant.
180
+
181
+ Arguments:
182
+ instruction One-shot instruction (non-interactive)
183
+
184
+ Options:
185
+ -V, --version output the version number
186
+ --yes Auto-confirm all prompts (non-interactive)
187
+ --allow-dangerous Allow dangerous commands without confirmation
188
+ -h, --help display help for command
189
+
190
+ Commands:
191
+ onboard Configure provider, API keys, and web search
192
+ ```
193
+
194
+ ## Development
195
+
196
+ ```bash
197
+ cd coder
198
+ npm install
199
+ npm run build # Compile TypeScript → dist/
200
+ npm run lint # Type-check without emitting
201
+ npm test # Run test suite
202
+ npm run dev # Watch mode
203
+ ```
204
+
205
+ ## Example Session
206
+
207
+ ```
208
+ $ developer-ai "Create a website named inferencia, which is AI service providing agency"
209
+
210
+ Processing...
211
+
212
+ ✓ [write_file] index.html
213
+ ✓ [write_file] styles.css
214
+ ✓ [write_file] script.js
215
+
216
+ I've created a complete website for Inferencia with 3 files:
217
+
218
+ 1. **index.html** — Main page with hero, services, about, team, and contact sections
219
+ 2. **styles.css** — Modern responsive styling with dark theme
220
+ 3. **script.js** — Smooth scrolling, animations, mobile menu, and contact form
221
+
222
+ Open `index.html` in your browser to preview.
223
+ ```
224
+
225
+ ## Troubleshooting
226
+
227
+ ### "OpenAI API key not configured"
228
+ Run `developer-ai onboard` or set `OPENAI_API_KEY` environment variable.
229
+
230
+ ### "Ollama API error"
231
+ Make sure Ollama is running (`ollama serve`) and the model is pulled (`ollama pull llama3.1`).
232
+
233
+ ### "Web search not configured"
234
+ Web search is optional. Set `BRAVE_SEARCH_API_KEY` or `SERPER_API_KEY` to enable it.
235
+
236
+ ### MCP server fails to connect
237
+ Check that the command in your MCP config is correct and the server binary is installed.
238
+
239
+ ## License
240
+
241
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/cli.js';
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import readline from 'node:readline';
5
+ import path from 'node:path';
6
+ import fs from 'node:fs';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { Agent } from './core/agent.js';
9
+ import { loadConfig, saveConfig, loadMcpConfig } from './config/index.js';
10
+ import { createToolRegistry } from './tools/index.js';
11
+ import { McpManager } from './mcp/client.js';
12
+ import { SkillsLoader } from './skills/loader.js';
13
+ import { OpenAIProvider } from './providers/openai.js';
14
+ import { OllamaProvider } from './providers/ollama.js';
15
+ import { VERSION } from './constants.js';
16
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
+ // ---- Helpers ----
18
+ function getSkillsDirs() {
19
+ const dirs = [];
20
+ // Skills bundled with the package
21
+ const pkgSkills = path.resolve(__dirname, '..', 'skills');
22
+ if (fs.existsSync(pkgSkills))
23
+ dirs.push(pkgSkills);
24
+ // Local workspace skills (.github/skills)
25
+ const ghSkills = path.join(process.cwd(), '.github', 'skills');
26
+ if (fs.existsSync(ghSkills))
27
+ dirs.push(ghSkills);
28
+ // Local workspace skills (top-level)
29
+ const topSkills = path.join(process.cwd(), 'skills');
30
+ if (fs.existsSync(topSkills) && topSkills !== pkgSkills)
31
+ dirs.push(topSkills);
32
+ return dirs;
33
+ }
34
+ function createProvider() {
35
+ const config = loadConfig();
36
+ if (config.provider === 'openai') {
37
+ const apiKey = config.openai.apiKey ?? process.env['OPENAI_API_KEY'];
38
+ if (!apiKey) {
39
+ console.error(chalk.red('Error: OpenAI API key not configured.\n') +
40
+ chalk.dim('Run: developer-ai onboard'));
41
+ process.exit(1);
42
+ }
43
+ return new OpenAIProvider(apiKey, config.openai.model);
44
+ }
45
+ return new OllamaProvider(config.ollama.model, config.ollama.baseUrl);
46
+ }
47
+ async function createAgent(opts, confirmFn) {
48
+ const config = loadConfig();
49
+ const mcpConfig = loadMcpConfig();
50
+ const provider = createProvider();
51
+ const toolRegistry = createToolRegistry();
52
+ const mcpManager = new McpManager();
53
+ const skillsLoader = new SkillsLoader(getSkillsDirs());
54
+ // MCP init (non-fatal)
55
+ if (Object.keys(mcpConfig.servers).length > 0) {
56
+ await mcpManager.initialize(mcpConfig);
57
+ }
58
+ const agent = new Agent({
59
+ provider,
60
+ toolRegistry,
61
+ mcpManager,
62
+ skillsLoader,
63
+ workspaceDir: process.cwd(),
64
+ autoYes: opts.yes ?? false,
65
+ allowDangerous: opts.allowDangerous ?? false,
66
+ maxIterations: 30,
67
+ confirmFn,
68
+ });
69
+ await agent.initialize();
70
+ return agent;
71
+ }
72
+ // ---- REPL ----
73
+ async function runRepl(opts) {
74
+ const rl = readline.createInterface({
75
+ input: process.stdin,
76
+ output: process.stdout,
77
+ prompt: chalk.green('you › '),
78
+ });
79
+ // Confirmation via the same readline interface
80
+ const confirmFn = (message) => new Promise((resolve) => {
81
+ rl.question(chalk.yellow(`\n${message} (y/N) `), (answer) => {
82
+ resolve(answer.trim().toLowerCase().startsWith('y'));
83
+ });
84
+ });
85
+ console.log(chalk.bold.cyan('\n Developer-AI') +
86
+ chalk.dim(` v${VERSION}`) +
87
+ chalk.dim(` · provider: ${loadConfig().provider}`));
88
+ console.log(chalk.dim(` Workspace: ${process.cwd()}`));
89
+ console.log(chalk.dim(' Type "exit" to quit, "clear" to reset context.\n'));
90
+ const agent = await createAgent(opts, confirmFn);
91
+ rl.prompt();
92
+ rl.on('line', async (line) => {
93
+ const input = line.trim();
94
+ if (!input) {
95
+ rl.prompt();
96
+ return;
97
+ }
98
+ if (input === 'exit' || input === 'quit' || input === '.exit') {
99
+ console.log(chalk.dim('Goodbye!'));
100
+ rl.close();
101
+ process.exit(0);
102
+ }
103
+ if (input === 'clear') {
104
+ agent.resetHistory();
105
+ console.log(chalk.dim('Context cleared.\n'));
106
+ rl.prompt();
107
+ return;
108
+ }
109
+ // Pause readline while the agent is working
110
+ rl.pause();
111
+ try {
112
+ process.stderr.write(chalk.dim('\nThinking...\n\n'));
113
+ const response = await agent.chat(input);
114
+ console.log('\n' + response + '\n');
115
+ }
116
+ catch (err) {
117
+ console.error(chalk.red(`\nError: ${err.message}\n`));
118
+ }
119
+ rl.resume();
120
+ rl.prompt();
121
+ });
122
+ rl.on('close', () => process.exit(0));
123
+ }
124
+ // ---- One-shot mode ----
125
+ async function runOneShot(instruction, opts) {
126
+ // In one-shot mode, stdin confirm uses a temporary readline
127
+ const confirmFn = (message) => new Promise((resolve) => {
128
+ const tmpRl = readline.createInterface({
129
+ input: process.stdin,
130
+ output: process.stderr,
131
+ });
132
+ tmpRl.question(chalk.yellow(`${message} (y/N) `), (answer) => {
133
+ tmpRl.close();
134
+ resolve(answer.trim().toLowerCase().startsWith('y'));
135
+ });
136
+ });
137
+ try {
138
+ const agent = await createAgent(opts, confirmFn);
139
+ process.stderr.write(chalk.dim('Processing...\n\n'));
140
+ const response = await agent.chat(instruction);
141
+ console.log(response);
142
+ }
143
+ catch (err) {
144
+ console.error(chalk.red(`Error: ${err.message}`));
145
+ process.exit(1);
146
+ }
147
+ }
148
+ // ---- Onboard command ----
149
+ async function runOnboard() {
150
+ console.log(chalk.bold.cyan('\n Developer-AI Setup\n'));
151
+ const rl = readline.createInterface({
152
+ input: process.stdin,
153
+ output: process.stdout,
154
+ });
155
+ const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
156
+ const config = loadConfig();
157
+ // Provider
158
+ const providerChoice = await ask(chalk.white(' Choose provider (1 = Ollama, 2 = OpenAI) [1]: '));
159
+ if (providerChoice.trim() === '2') {
160
+ config.provider = 'openai';
161
+ const apiKey = await ask(chalk.white(' OpenAI API key: '));
162
+ if (apiKey.trim())
163
+ config.openai.apiKey = apiKey.trim();
164
+ const model = await ask(chalk.white(` Model [${config.openai.model}]: `));
165
+ if (model.trim())
166
+ config.openai.model = model.trim();
167
+ }
168
+ else {
169
+ config.provider = 'ollama';
170
+ const model = await ask(chalk.white(` Ollama model [${config.ollama.model}]: `));
171
+ if (model.trim())
172
+ config.ollama.model = model.trim();
173
+ const baseUrl = await ask(chalk.white(` Ollama URL [${config.ollama.baseUrl}]: `));
174
+ if (baseUrl.trim())
175
+ config.ollama.baseUrl = baseUrl.trim();
176
+ }
177
+ // Web search
178
+ const searchChoice = await ask(chalk.white(' Web search (1 = none, 2 = Brave, 3 = Serper) [1]: '));
179
+ if (searchChoice.trim() === '2') {
180
+ config.webSearch.provider = 'brave';
181
+ const key = await ask(chalk.white(' Brave Search API key: '));
182
+ if (key.trim())
183
+ config.webSearch.braveApiKey = key.trim();
184
+ }
185
+ else if (searchChoice.trim() === '3') {
186
+ config.webSearch.provider = 'serper';
187
+ const key = await ask(chalk.white(' Serper API key: '));
188
+ if (key.trim())
189
+ config.webSearch.serperApiKey = key.trim();
190
+ }
191
+ saveConfig(config);
192
+ console.log(chalk.green('\n ✓ Configuration saved to ~/.developer-ai/config.json'));
193
+ console.log(chalk.dim(' ⚠ File permissions set to owner-only (0600).\n'));
194
+ rl.close();
195
+ }
196
+ // ---- Program definition ----
197
+ const program = new Command();
198
+ program
199
+ .name('developer-ai')
200
+ .description('Terminal-based AI coding assistant. Run interactively or provide a one-shot instruction.')
201
+ .version(VERSION)
202
+ .option('--yes', 'Auto-confirm all prompts (non-interactive)', false)
203
+ .option('--allow-dangerous', 'Allow dangerous commands without confirmation', false)
204
+ .argument('[instruction...]', 'One-shot instruction (non-interactive)')
205
+ .action(async (instructionParts, options) => {
206
+ const instruction = instructionParts.join(' ').trim();
207
+ if (instruction) {
208
+ await runOneShot(instruction, options);
209
+ }
210
+ else {
211
+ await runRepl(options);
212
+ }
213
+ });
214
+ program
215
+ .command('onboard')
216
+ .description('Configure provider, API keys, and web search')
217
+ .action(runOnboard);
218
+ program.parse();
219
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,oBAAoB;AAEpB,SAAS,aAAa;IACpB,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,kCAAkC;IAClC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1D,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEnD,0CAA0C;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC/D,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEjD,qCAAqC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IACrD,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,SAAS,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE9E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACrE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,yCAAyC,CAAC;gBAClD,KAAK,CAAC,GAAG,CAAC,2BAA2B,CAAC,CACzC,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACxE,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,IAAiD,EACjD,SAA4C;IAE5C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,MAAM,YAAY,GAAG,kBAAkB,EAAE,CAAC;IAC1C,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;IACpC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,aAAa,EAAE,CAAC,CAAC;IAEvD,uBAAuB;IACvB,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,QAAQ;QACR,YAAY;QACZ,UAAU;QACV,YAAY;QACZ,YAAY,EAAE,OAAO,CAAC,GAAG,EAAE;QAC3B,OAAO,EAAE,IAAI,CAAC,GAAG,IAAI,KAAK;QAC1B,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,KAAK;QAC5C,aAAa,EAAE,EAAE;QACjB,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,KAAK,CAAC,UAAU,EAAE,CAAC;IACzB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iBAAiB;AAEjB,KAAK,UAAU,OAAO,CAAC,IAGtB;IACC,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;KAC9B,CAAC,CAAC;IAEH,+CAA+C;IAC/C,MAAM,SAAS,GAAG,CAAC,OAAe,EAAoB,EAAE,CACtD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACtB,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,OAAO,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;YAC1D,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACjC,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC;QACzB,KAAK,CAAC,GAAG,CAAC,kBAAkB,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,CACvD,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAChE,CAAC;IAEF,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAEjD,EAAE,CAAC,MAAM,EAAE,CAAC;IAEZ,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,EAAE,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;YACnC,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,KAAK,CAAC,YAAY,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,4CAA4C;QAC5C,EAAE,CAAC,KAAK,EAAE,CAAC;QAEX,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACrD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAa,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;QACnE,CAAC;QAED,EAAE,CAAC,MAAM,EAAE,CAAC;QACZ,EAAE,CAAC,MAAM,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,0BAA0B;AAE1B,KAAK,UAAU,UAAU,CACvB,WAAmB,EACnB,IAAiD;IAEjD,4DAA4D;IAC5D,MAAM,SAAS,GAAG,CAAC,OAAe,EAAoB,EAAE,CACtD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC;YACrC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;YAC3D,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAW,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,4BAA4B;AAE5B,KAAK,UAAU,UAAU;IACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAEzD,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,CAAC,CAAS,EAAmB,EAAE,CACzC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAEpD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,WAAW;IACX,MAAM,cAAc,GAAG,MAAM,GAAG,CAC9B,KAAK,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAChE,CAAC;IAEF,IAAI,cAAc,CAAC,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;QAClC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAC5D,IAAI,MAAM,CAAC,IAAI,EAAE;YAAE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,MAAM,GAAG,CACrB,KAAK,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,CAClD,CAAC;QACF,IAAI,KAAK,CAAC,IAAI,EAAE;YAAE,MAAM,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,GAAG,CACrB,KAAK,CAAC,KAAK,CAAC,mBAAmB,MAAM,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,CACzD,CAAC;QACF,IAAI,KAAK,CAAC,IAAI,EAAE;YAAE,MAAM,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,GAAG,CACvB,KAAK,CAAC,KAAK,CAAC,iBAAiB,MAAM,CAAC,MAAM,CAAC,OAAO,KAAK,CAAC,CACzD,CAAC;QACF,IAAI,OAAO,CAAC,IAAI,EAAE;YAAE,MAAM,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC7D,CAAC;IAED,aAAa;IACb,MAAM,YAAY,GAAG,MAAM,GAAG,CAC5B,KAAK,CAAC,KAAK,CAAC,sDAAsD,CAAC,CACpE,CAAC;IACF,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;QAChC,MAAM,CAAC,SAAS,CAAC,QAAQ,GAAG,OAAO,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;QAC/D,IAAI,GAAG,CAAC,IAAI,EAAE;YAAE,MAAM,CAAC,SAAS,CAAC,WAAW,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC5D,CAAC;SAAM,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;QACvC,MAAM,CAAC,SAAS,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACrC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;QACzD,IAAI,GAAG,CAAC,IAAI,EAAE;YAAE,MAAM,CAAC,SAAS,CAAC,YAAY,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC7D,CAAC;IAED,UAAU,CAAC,MAAM,CAAC,CAAC;IAEnB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CAAC,0DAA0D,CAAC,CACxE,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC,CAAC;IAE3E,EAAE,CAAC,KAAK,EAAE,CAAC;AACb,CAAC;AAED,+BAA+B;AAE/B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CACV,0FAA0F,CAC3F;KACA,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,OAAO,EAAE,4CAA4C,EAAE,KAAK,CAAC;KACpE,MAAM,CACL,mBAAmB,EACnB,+CAA+C,EAC/C,KAAK,CACN;KACA,QAAQ,CAAC,kBAAkB,EAAE,wCAAwC,CAAC;KACtE,MAAM,CAAC,KAAK,EAAE,gBAA0B,EAAE,OAAO,EAAE,EAAE;IACpD,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,8CAA8C,CAAC;KAC3D,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type Config, type McpConfig } from './schema.js';
2
+ export declare function ensureConfigDir(): void;
3
+ export declare function loadConfig(): Config;
4
+ export declare function saveConfig(config: Config): void;
5
+ export declare function loadMcpConfig(): McpConfig;
6
+ export declare function getConfigDir(): string;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAMzF,wBAAgB,eAAe,IAAI,IAAI,CAItC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAwCnC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAG/C;AAED,wBAAgB,aAAa,IAAI,SAAS,CAuBzC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
@@ -0,0 +1,82 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import { ConfigSchema, McpConfigSchema } from './schema.js';
5
+ const CONFIG_DIR = path.join(os.homedir(), '.developer-ai');
6
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
7
+ const MCP_FILE = path.join(CONFIG_DIR, 'mcp.json');
8
+ export function ensureConfigDir() {
9
+ if (!fs.existsSync(CONFIG_DIR)) {
10
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
11
+ }
12
+ }
13
+ export function loadConfig() {
14
+ ensureConfigDir();
15
+ let config;
16
+ if (fs.existsSync(CONFIG_FILE)) {
17
+ try {
18
+ const raw = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
19
+ config = ConfigSchema.parse(raw);
20
+ }
21
+ catch {
22
+ config = ConfigSchema.parse({});
23
+ }
24
+ }
25
+ else {
26
+ config = ConfigSchema.parse({});
27
+ }
28
+ // Environment variable overrides — higher priority than config file
29
+ if (process.env['OPENAI_API_KEY']) {
30
+ config.provider = 'openai';
31
+ config.openai.apiKey = process.env['OPENAI_API_KEY'];
32
+ }
33
+ if (process.env['OPENAI_MODEL']) {
34
+ config.openai.model = process.env['OPENAI_MODEL'];
35
+ }
36
+ if (process.env['OLLAMA_MODEL']) {
37
+ config.ollama.model = process.env['OLLAMA_MODEL'];
38
+ }
39
+ if (process.env['OLLAMA_BASE_URL']) {
40
+ config.ollama.baseUrl = process.env['OLLAMA_BASE_URL'];
41
+ }
42
+ if (process.env['BRAVE_SEARCH_API_KEY']) {
43
+ config.webSearch.provider = 'brave';
44
+ config.webSearch.braveApiKey = process.env['BRAVE_SEARCH_API_KEY'];
45
+ }
46
+ if (process.env['SERPER_API_KEY']) {
47
+ config.webSearch.provider = 'serper';
48
+ config.webSearch.serperApiKey = process.env['SERPER_API_KEY'];
49
+ }
50
+ return config;
51
+ }
52
+ export function saveConfig(config) {
53
+ ensureConfigDir();
54
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
55
+ }
56
+ export function loadMcpConfig() {
57
+ const merged = { servers: {} };
58
+ // Global MCP config
59
+ if (fs.existsSync(MCP_FILE)) {
60
+ try {
61
+ const raw = JSON.parse(fs.readFileSync(MCP_FILE, 'utf-8'));
62
+ const parsed = McpConfigSchema.parse(raw);
63
+ Object.assign(merged.servers, parsed.servers);
64
+ }
65
+ catch { /* ignore malformed config */ }
66
+ }
67
+ // Local MCP config (workspace-level)
68
+ const localMcp = path.join(process.cwd(), '.developer-ai', 'mcp.json');
69
+ if (fs.existsSync(localMcp)) {
70
+ try {
71
+ const raw = JSON.parse(fs.readFileSync(localMcp, 'utf-8'));
72
+ const parsed = McpConfigSchema.parse(raw);
73
+ Object.assign(merged.servers, parsed.servers);
74
+ }
75
+ catch { /* ignore malformed config */ }
76
+ }
77
+ return merged;
78
+ }
79
+ export function getConfigDir() {
80
+ return CONFIG_DIR;
81
+ }
82
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}