Skip to content
This repository was archived by the owner on Jul 21, 2025. It is now read-only.

Commit 7482b2c

Browse files
committed
refactor: improve configuration handling and discovery server initialization
1 parent 1deaf01 commit 7482b2c

6 files changed

Lines changed: 85 additions & 23 deletions

File tree

.rules

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# DVMCP agent guidelines
2+
DVMCP is a bun monorepo. Each package has its own directory and can be installed and run independently. To execute commands for all packages, run them from the root directory
3+
4+
## Build/Test Commands
5+
6+
- **Install**: `bun install`
7+
- **Run**: `bun start` (specific package)
8+
- **Typecheck**: `bun typecheck` (run in root directory)
9+
- **Test**: `bun test` (runs all tests)
10+
- **Single test**: `bun test path/to/file.test.ts` (specific test file)
11+
12+
## Code Style
13+
14+
- **Runtime**: Bun with TypeScript ESM modules
15+
- **Imports**: Use relative imports for local modules, named imports preferred
16+
- **Types**: Zod schemas for validation, TypeScript interfaces for structure
17+
- **Naming**: camelCase for variables/functions, PascalCase for classes/namespaces
18+
- **Error handling**: Use Result patterns, avoid throwing exceptions in tools
19+
- **File structure**: Namespace-based organization
20+
21+
## IMPORTANT
22+
23+
- Try to keep things in one function unless composable or reusable
24+
- DO NOT do unnecessary destructuring of variables
25+
- DO NOT use `else` statements unless necessary
26+
- DO NOT use `try`/`catch` if it can be avoided
27+
- AVOID `try`/`catch` where possible
28+
- AVOID `else` statements
29+
- AVOID using `any` type
30+
- AVOID `let` statements
31+
- PREFER single word variable names where possible
32+
- If necessary, for external libraries like `modelcontextprotocol/sdk` or questions about the Bun runtime, use context7 to access up-to-date, version-specific documentation and code examples directly from the source.
33+
- Constants such as kind numbers, MCP methods, and other relevant constants are defined in the constants.ts file within the commons/core package. Use these when available, and only create new constants if necessary.
34+
- If necessary, for understanding the DVMCP specification refer to the specification at docs/dvmcp-spec-2025-03-26.md

packages/dvmcp-bridge/cli.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,6 @@ const cliMain = async () => {
183183
return;
184184
}
185185

186-
if (!existsSync(configPath)) {
187-
console.log(
188-
`${CONFIG_EMOJIS.INFO} No configuration file found. Starting setup...`
189-
);
190-
await configure();
191-
}
192-
193186
if (args.verbose) {
194187
const { default: yaml } = await import('yaml');
195188
console.log('\n📋 DVMCP Bridge Configuration:');

packages/dvmcp-bridge/src/config-schema.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ export const dvmcpBridgeConfigSchema: ConfigSchema = {
223223
type: 'array',
224224
itemType: 'string',
225225
required: true,
226-
doc: 'List of relay URLs (must start with ws:// or wss://); at least one.',
226+
doc: 'List of relay URLs (must start with ws:// or wss://)',
227227
minItems: 1,
228228
},
229229
},
@@ -377,7 +377,7 @@ export const dvmcpBridgeConfigSchema: ConfigSchema = {
377377
type: 'boolean',
378378
required: false,
379379
default: false,
380-
doc: 'If true, server will not announce itself publicly to Nostr relays. Clients must use direct initialization to connect.',
380+
doc: 'Is private server? If true, server will not announce itself publicly to Nostr relays.',
381381
},
382382
},
383383
},

packages/dvmcp-commons/src/config/config-generator.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export class ConfigGenerator<T extends Record<string, any>> {
125125
if (
126126
await this.promptYesNo(
127127
`${CONFIG_EMOJIS.SERVER} Add ${fieldName} price?`,
128-
false
128+
fieldConfig.default || false
129129
)
130130
) {
131131
const value = await this.handleField(fieldName, fieldConfig, false);
@@ -135,7 +135,7 @@ export class ConfigGenerator<T extends Record<string, any>> {
135135
if (
136136
await this.promptYesNo(
137137
`${CONFIG_EMOJIS.SERVER} Add environment variables?`,
138-
false
138+
fieldConfig.default || false
139139
)
140140
) {
141141
const env: Record<string, string> = {};
@@ -176,7 +176,6 @@ export class ConfigGenerator<T extends Record<string, any>> {
176176
private async handleField(
177177
fieldName: string,
178178
config: FieldConfig,
179-
showFieldName = true,
180179
currentValue?: any
181180
): Promise<any> {
182181
const emoji = config.emoji || CONFIG_EMOJIS.PROMPT;
@@ -195,7 +194,7 @@ export class ConfigGenerator<T extends Record<string, any>> {
195194

196195
const keepCurrent = await this.promptYesNo(
197196
`${emoji} Keep current ${description}?`,
198-
true
197+
config.default || false
199198
);
200199

201200
if (keepCurrent) {
@@ -218,7 +217,10 @@ export class ConfigGenerator<T extends Record<string, any>> {
218217
hex: async () => {
219218
if (
220219
config.generator &&
221-
(await this.promptYesNo(`${emoji} Generate new ${description}?`))
220+
(await this.promptYesNo(
221+
`${emoji} Generate new ${description}?`,
222+
config.required || false
223+
))
222224
) {
223225
const value = config.generator();
224226
console.log(`${CONFIG_EMOJIS.PROMPT} ${value}`);
@@ -260,7 +262,12 @@ export class ConfigGenerator<T extends Record<string, any>> {
260262
}
261263
}
262264

263-
if (await this.promptYesNo(`${emoji} Add ${description}?`, true)) {
265+
if (
266+
await this.promptYesNo(
267+
`${emoji} Add ${description}?`,
268+
(config.default && config.required) || false
269+
)
270+
) {
264271
while (true) {
265272
const item = await this.promptWithValidation(
266273
`${emoji} Enter value for ${description} (empty to finish):`,
@@ -277,7 +284,12 @@ export class ConfigGenerator<T extends Record<string, any>> {
277284

278285
set: async () => {
279286
const items: string[] = Array.from(currentValue || []);
280-
if (await this.promptYesNo('Would you like to add items?', false)) {
287+
if (
288+
await this.promptYesNo(
289+
'Would you like to add items?',
290+
(config.default && config.required) || false
291+
)
292+
) {
281293
while (true) {
282294
const item = await this.promptWithValidation(
283295
'Enter item (empty to finish):',
@@ -312,7 +324,7 @@ export class ConfigGenerator<T extends Record<string, any>> {
312324
console.log('');
313325
const keepCurrent = await this.promptYesNo(
314326
`${emoji} Keep current ${fieldName}?`,
315-
true
327+
(config.default && config.required) || false
316328
);
317329
if (!keepCurrent) {
318330
array = [];
@@ -321,7 +333,7 @@ export class ConfigGenerator<T extends Record<string, any>> {
321333
if (
322334
await this.promptYesNo(
323335
`${emoji} Remove any existing ${fieldName}?`,
324-
false
336+
(config.default && config.required) || false
325337
)
326338
) {
327339
while (true) {
@@ -344,7 +356,12 @@ export class ConfigGenerator<T extends Record<string, any>> {
344356
}
345357
}
346358

347-
if (await this.promptYesNo(`${emoji} Add new ${fieldName}?`, true)) {
359+
if (
360+
await this.promptYesNo(
361+
`${emoji} Add new ${fieldName}?`,
362+
(config.default && config.required) || false
363+
)
364+
) {
348365
while (true) {
349366
const item = await this.handleObjectArrayItem(
350367
config.fields!,
@@ -370,15 +387,15 @@ export class ConfigGenerator<T extends Record<string, any>> {
370387
nestedObj[key] = await this.handleField(
371388
key,
372389
fieldConfig,
373-
true,
374390
currentValue?.[key]
375391
);
376392
}
377393
}
378394
return nestedObj;
379395
},
380396

381-
boolean: async () => false,
397+
boolean: async () =>
398+
this.promptYesNo(`${emoji} ${description}:`, config.default || false),
382399
url: async () =>
383400
this.promptWithValidation(
384401
`${emoji} Enter URL:`,
@@ -456,7 +473,6 @@ export class ConfigGenerator<T extends Record<string, any>> {
456473
config[fieldName] = await this.handleField(
457474
fieldName,
458475
fieldConfig,
459-
true,
460476
currentValue
461477
);
462478
}

packages/dvmcp-discovery/cli.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env bun
2+
import { existsSync } from 'node:fs';
23
import { join, resolve } from 'path';
34
import process from 'process';
45
import yargs from 'yargs';
@@ -336,6 +337,24 @@ const cliMain = async (): Promise<void> => {
336337
await configure();
337338
return;
338339
}
340+
341+
if (!existsSync(configPath)) {
342+
console.log(
343+
`${CONFIG_EMOJIS.INFO} No configuration file found at ${configPath}`
344+
);
345+
console.log(
346+
`${CONFIG_EMOJIS.INFO} You can create one by copying config.example.yml to config.dvmcp.yml and editing it.`
347+
);
348+
console.log(
349+
`${CONFIG_EMOJIS.INFO} Alternatively, you can run with --configure to set up a new configuration.`
350+
);
351+
console.log(`${CONFIG_EMOJIS.INFO} Starting configuration wizard...`);
352+
await configure();
353+
console.log(
354+
`${CONFIG_EMOJIS.INFO} Configuration created, attempting to load...`
355+
);
356+
}
357+
339358
if (args.provider) {
340359
await setupFromProvider(args.provider as string);
341360
await runApp();

packages/dvmcp-discovery/src/discovery-server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ export class DiscoveryServer {
148148
this.serverRegistry
149149
);
150150

151-
// Initialize built-in tools if interactive mode is enabled
152151
// Setup private discovery helper if configured
153152
if (this.config.discovery?.privateServers?.length) {
154153
this.privateDiscovery = new PrivateDiscovery(
@@ -160,6 +159,7 @@ export class DiscoveryServer {
160159
);
161160
}
162161

162+
// Initialize built-in tools if interactive mode is enabled
163163
if (this.config.featureFlags?.interactive) {
164164
loggerDiscovery('Interactive mode enabled: Registering built-in tools.');
165165
initBuiltInTools(this.mcpServer, this.toolRegistry, this);

0 commit comments

Comments
 (0)