@descix/cli 1.0.6 → 1.0.8
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.
- package/README.md +1 -1
- package/agent-assets/guides/README.md +1 -1
- package/agent-assets/guides/dynamic-site-pattern.md +17 -30
- package/agent-assets/guides/knowledge-only-pattern.md +11 -15
- package/agent-assets/guides/microservice-pattern.md +12 -14
- package/agent-assets/guides/static-site-pattern.md +12 -15
- package/agent-assets/instructions/app-asset-validation.md +1 -1
- package/agent-assets/instructions/onboarding-flow.md +4 -4
- package/agent-assets/reference/app-creation.md +36 -101
- package/agent-assets/reference/architecture.md +43 -51
- package/agent-assets/reference/local-dev.md +1 -6
- package/agent-assets/reference/mcp-integration.md +21 -23
- package/agent-assets/reference/workspace-config.md +97 -340
- package/bin/descix.js +337 -618
- package/lib/api-client.js +30 -22
- package/lib/command-visibility.js +213 -0
- package/lib/commands/airdrop.js +10 -0
- package/lib/commands/auth.js +16 -2
- package/lib/commands/config.js +13 -31
- package/lib/commands/corpus.js +163 -59
- package/lib/commands/health.js +116 -21
- package/lib/commands/init.js +17 -45
- package/lib/commands/kb.js +7 -0
- package/lib/commands/retired-kb-sync.js +5 -27
- package/lib/commands/status.js +0 -9
- package/lib/core/Chunker.js +1 -1
- package/lib/core/CorpusWalker.js +238 -47
- package/lib/core/ManifestLoader.js +68 -0
- package/lib/core/Syncer.js +147 -46
- package/lib/interactive.js +158 -0
- package/lib/origin.js +3 -3
- package/lib/sdk-assets.js +28 -0
- package/lib/verb-invokes.generated.json +233 -0
- package/lib/wallet-file.js +36 -37
- package/lib/workspace-config.js +266 -199
- package/lib/workspace-identity.js +0 -1
- package/package.json +7 -3
- package/templates/agent-claude.md +1 -3
- package/templates/agent-cline.md +1 -2
- package/templates/agent-copilot.md +1 -2
- package/templates/agent-cursor.md +1 -2
- package/templates/scaffolds/microservice/SERVICE_README_sdk.md +1 -1
- package/templates/scaffolds/microservice/templates/SERVICE_README_TEMPLATE.md +2 -3
- package/agent-assets/rules/descix_mcp.template.mdc +0 -243
- package/lib/commands/briefer/errors.js +0 -88
- package/lib/commands/briefer/index.js +0 -319
- package/lib/commands/briefer/sources/canonical-sources.js +0 -129
- package/lib/commands/briefer/sources/entitlements.js +0 -220
- package/lib/commands/briefer/sources/environments.js +0 -205
- package/lib/commands/briefer/sources/identifiers.js +0 -214
- package/lib/commands/briefer/sources/microservice-deploy.js +0 -267
- package/lib/commands/briefer/sources/routing.js +0 -275
- package/lib/commands/briefer/sources/what-is-not.js +0 -223
- package/lib/commands/briefer/stitcher.js +0 -134
- package/lib/commands/briefer/util/source-reader.js +0 -502
- package/lib/commands/mcp.js +0 -273
- package/lib/commands/update.js +0 -581
- package/lib/wizard/setup.js +0 -503
- package/templates/descix_mcp.mdc +0 -122
package/lib/wizard/setup.js
DELETED
|
@@ -1,503 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interactive Setup Wizard
|
|
3
|
-
*
|
|
4
|
-
* Bootstraps MCP connectivity so the AI agent can guide workspace configuration.
|
|
5
|
-
*
|
|
6
|
-
* Steps:
|
|
7
|
-
* 0. API Configuration (select environment)
|
|
8
|
-
* 1. Authentication (device login or wallet)
|
|
9
|
-
* 2. Fetch Entitlements (communities/apps user owns)
|
|
10
|
-
* 3. Pull SDK Agent Assets (instructions, templates, rules)
|
|
11
|
-
* 4. MCP Configuration (mcp.json + rules file with entitlements)
|
|
12
|
-
* 5. Create workspace.json (with _needsAgentSetup flag)
|
|
13
|
-
* 6. Register SDK Service (vectorize for tell_me_how)
|
|
14
|
-
*
|
|
15
|
-
* After setup, the AI agent uses the rules file and local SDK assets
|
|
16
|
-
* to help the user map folders to apps and configure workspace.json.
|
|
17
|
-
*
|
|
18
|
-
* All operations use HTTP API client - no service imports
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
import chalk from 'chalk';
|
|
22
|
-
import ora from 'ora';
|
|
23
|
-
import inquirer from 'inquirer';
|
|
24
|
-
import { DeSciXApiClient } from '../api-client.js';
|
|
25
|
-
import { ENV_ORIGINS } from '@descix/app-sdk/dev';
|
|
26
|
-
import { requireAuth, isAuthenticated } from '../auth-guard.js';
|
|
27
|
-
import * as authCommands from '../commands/auth.js';
|
|
28
|
-
import * as fs from 'fs/promises';
|
|
29
|
-
import * as path from 'path';
|
|
30
|
-
import { fileURLToPath } from 'url';
|
|
31
|
-
import { dirname } from 'path';
|
|
32
|
-
|
|
33
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
34
|
-
const __dirname = dirname(__filename);
|
|
35
|
-
|
|
36
|
-
// SDK version for tracking
|
|
37
|
-
const SDK_VERSION = '2.0.0';
|
|
38
|
-
|
|
39
|
-
// ============ Helper Functions ============
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Copy directory recursively
|
|
43
|
-
* @param {string} src - Source directory
|
|
44
|
-
* @param {string} dest - Destination directory
|
|
45
|
-
*/
|
|
46
|
-
async function copyDir(src, dest) {
|
|
47
|
-
await fs.mkdir(dest, { recursive: true });
|
|
48
|
-
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
49
|
-
|
|
50
|
-
for (const entry of entries) {
|
|
51
|
-
const srcPath = path.join(src, entry.name);
|
|
52
|
-
const destPath = path.join(dest, entry.name);
|
|
53
|
-
|
|
54
|
-
if (entry.isDirectory()) {
|
|
55
|
-
await copyDir(srcPath, destPath);
|
|
56
|
-
} else {
|
|
57
|
-
await fs.copyFile(srcPath, destPath);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Pull SDK agent assets to local workspace
|
|
64
|
-
* Copies agent-assets/ to .descix/sdk-assets/ for local AI agent access
|
|
65
|
-
* @param {string} workspacePath - Workspace root path
|
|
66
|
-
* @returns {Promise<boolean>} True if assets were copied
|
|
67
|
-
*/
|
|
68
|
-
async function pullSdkAssets(workspacePath) {
|
|
69
|
-
// agent-assets is in the SDK root, which is ../../.. from wizard/setup.js
|
|
70
|
-
const sdkAssetsSource = path.join(__dirname, '../../../agent-assets');
|
|
71
|
-
const sdkAssetsTarget = path.join(workspacePath, '.descix/sdk-assets');
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
// Check if source exists
|
|
75
|
-
await fs.access(sdkAssetsSource);
|
|
76
|
-
|
|
77
|
-
// Copy recursively
|
|
78
|
-
await copyDir(sdkAssetsSource, sdkAssetsTarget);
|
|
79
|
-
|
|
80
|
-
return true;
|
|
81
|
-
} catch (error) {
|
|
82
|
-
// Source doesn't exist (development mode or not packaged)
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Generate customized rules file from template
|
|
89
|
-
* Uses agent-assets/rules/descix_mcp.template.mdc with placeholder substitution
|
|
90
|
-
* @param {string} workspacePath - Workspace root path
|
|
91
|
-
* @param {Object} entitlements - User's entitlements from fetch_my_purchases
|
|
92
|
-
* @param {string} primaryCommunity - User's primary community
|
|
93
|
-
* @returns {Promise<boolean>} True if rules file was generated
|
|
94
|
-
*/
|
|
95
|
-
async function generateRulesFile(workspacePath, entitlements, primaryCommunity) {
|
|
96
|
-
const templatePath = path.join(__dirname, '../../../agent-assets/rules/descix_mcp.template.mdc');
|
|
97
|
-
const rulesDir = path.join(workspacePath, '.cursor/rules');
|
|
98
|
-
const rulesPath = path.join(rulesDir, 'descix_mcp.mdc');
|
|
99
|
-
|
|
100
|
-
try {
|
|
101
|
-
// Read template
|
|
102
|
-
const template = await fs.readFile(templatePath, 'utf-8');
|
|
103
|
-
|
|
104
|
-
// Summarize entitlements for embedding (avoid huge JSON in rules file)
|
|
105
|
-
const entitlementsSummary = {
|
|
106
|
-
communities: (entitlements.communities || []).map(c => ({
|
|
107
|
-
id: c.community_id || c.id,
|
|
108
|
-
name: c.community_name || c.name
|
|
109
|
-
})),
|
|
110
|
-
apps: (entitlements.apps || []).map(a => ({
|
|
111
|
-
community: a.community_id,
|
|
112
|
-
id: a.app_id || a.id,
|
|
113
|
-
name: a.app_name || a.name
|
|
114
|
-
}))
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
// Customize with workspace-specific values
|
|
118
|
-
const customized = template
|
|
119
|
-
.replace(/\{\{SDK_ASSETS_PATH\}\}/g, '.descix/sdk-assets')
|
|
120
|
-
.replace(/\{\{PRIMARY_COMMUNITY\}\}/g, primaryCommunity || 'daita')
|
|
121
|
-
.replace(/\{\{ENTITLEMENTS_JSON\}\}/g, JSON.stringify(entitlementsSummary, null, 2))
|
|
122
|
-
.replace(/\{\{SDK_VERSION\}\}/g, SDK_VERSION)
|
|
123
|
-
.replace(/\{\{WORKSPACE_PATH\}\}/g, workspacePath);
|
|
124
|
-
|
|
125
|
-
// Write customized rules
|
|
126
|
-
await fs.mkdir(rulesDir, { recursive: true });
|
|
127
|
-
await fs.writeFile(rulesPath, customized, 'utf-8');
|
|
128
|
-
|
|
129
|
-
return true;
|
|
130
|
-
} catch (error) {
|
|
131
|
-
// Template doesn't exist, fall back to simple template
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Auto-register SDK service for tell_me_how discovery
|
|
138
|
-
* Vectorizes SERVICE_README_sdk.md so SDK tools are discoverable
|
|
139
|
-
* @param {DeSciXApiClient} apiClient - Authenticated API client
|
|
140
|
-
* @returns {Promise<boolean>} True if registration succeeded
|
|
141
|
-
*/
|
|
142
|
-
async function autoRegisterSdkService(apiClient) {
|
|
143
|
-
// SDK SERVICE_README is in the SDK root
|
|
144
|
-
const readmePath = path.join(__dirname, '../../../SERVICE_README_sdk.md');
|
|
145
|
-
|
|
146
|
-
try {
|
|
147
|
-
const readmeContent = await fs.readFile(readmePath, 'utf-8');
|
|
148
|
-
|
|
149
|
-
// Vectorize for tell_me_how discovery
|
|
150
|
-
await apiClient.invoke('vectorize_service_readme', {
|
|
151
|
-
service_name: 'sdk',
|
|
152
|
-
community_id: 'daita',
|
|
153
|
-
app_id: 'docs',
|
|
154
|
-
readme_content: readmeContent
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
return true;
|
|
158
|
-
} catch (error) {
|
|
159
|
-
// README doesn't exist or vectorization failed
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Get MCP server configuration
|
|
166
|
-
* Uses direct command if CLI is installed, otherwise suggests install
|
|
167
|
-
* @returns {Object} { command, args } for MCP server
|
|
168
|
-
*/
|
|
169
|
-
function getMcpServerConfig() {
|
|
170
|
-
// Use direct descix command - simpler and no npm download needed
|
|
171
|
-
// Requires CLI to be installed globally first via:
|
|
172
|
-
// npm install -g https://app.descix.net/sdk/descix-cli-1.0.0.tgz
|
|
173
|
-
// or during development:
|
|
174
|
-
// npm install -g /path/to/descix-cli-1.0.0.tgz
|
|
175
|
-
return {
|
|
176
|
-
command: 'descix',
|
|
177
|
-
args: ['mcp-serve'],
|
|
178
|
-
type: 'global'
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// ============ Main Wizard ============
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Run the interactive setup wizard
|
|
186
|
-
*/
|
|
187
|
-
export async function runSetupWizard(options = {}) {
|
|
188
|
-
console.log(chalk.cyan('\n┌─────────────────────────────────────────────────┐'));
|
|
189
|
-
console.log(chalk.cyan('│ Welcome to DeSciX CLI/MCP Setup │'));
|
|
190
|
-
console.log(chalk.cyan('├─────────────────────────────────────────────────┤'));
|
|
191
|
-
console.log(chalk.cyan('│ This wizard will: │'));
|
|
192
|
-
console.log(chalk.cyan('│ 1. Configure API endpoint │'));
|
|
193
|
-
console.log(chalk.cyan('│ 2. Authenticate with DeSciX (required) │'));
|
|
194
|
-
console.log(chalk.cyan('│ 3. Fetch your entitlements │'));
|
|
195
|
-
console.log(chalk.cyan('│ 4. Pull SDK agent assets locally │'));
|
|
196
|
-
console.log(chalk.cyan('│ 5. Configure Cursor MCP integration │'));
|
|
197
|
-
console.log(chalk.cyan('│ 6. Register SDK for tool discovery │'));
|
|
198
|
-
console.log(chalk.cyan('│ │'));
|
|
199
|
-
console.log(chalk.cyan('│ After setup, the AI agent will help you │'));
|
|
200
|
-
console.log(chalk.cyan('│ configure your workspace folders. │'));
|
|
201
|
-
console.log(chalk.cyan('└─────────────────────────────────────────────────┘\n'));
|
|
202
|
-
|
|
203
|
-
const workspaceRoot = process.cwd();
|
|
204
|
-
const spinner = ora('Initializing...').start();
|
|
205
|
-
|
|
206
|
-
try {
|
|
207
|
-
// Step 0: Configure API endpoint
|
|
208
|
-
spinner.stop();
|
|
209
|
-
console.log(chalk.cyan('\n📋 Step 0: API Configuration\n'));
|
|
210
|
-
|
|
211
|
-
let apiUrl = options.url || process.env.DESCIX_API_URL;
|
|
212
|
-
|
|
213
|
-
if (!apiUrl) {
|
|
214
|
-
const { environment } = await inquirer.prompt([
|
|
215
|
-
{
|
|
216
|
-
type: 'list',
|
|
217
|
-
name: 'environment',
|
|
218
|
-
message: 'Which environment are you connecting to?',
|
|
219
|
-
choices: [
|
|
220
|
-
{ name: `Production (${ENV_ORIGINS.prod})`, value: 'production' },
|
|
221
|
-
{ name: 'Local Development (localhost:4000)', value: 'local' },
|
|
222
|
-
{ name: 'Custom URL', value: 'custom' }
|
|
223
|
-
],
|
|
224
|
-
default: 'production'
|
|
225
|
-
}
|
|
226
|
-
]);
|
|
227
|
-
|
|
228
|
-
if (environment === 'production') {
|
|
229
|
-
apiUrl = ENV_ORIGINS.prod;
|
|
230
|
-
} else if (environment === 'local') {
|
|
231
|
-
apiUrl = 'https://localhost:4000';
|
|
232
|
-
} else {
|
|
233
|
-
const { customUrl } = await inquirer.prompt([
|
|
234
|
-
{
|
|
235
|
-
type: 'input',
|
|
236
|
-
name: 'customUrl',
|
|
237
|
-
message: 'Enter API URL:',
|
|
238
|
-
default: 'https://localhost:4000',
|
|
239
|
-
validate: (input) => {
|
|
240
|
-
if (!input.startsWith('http://') && !input.startsWith('https://')) {
|
|
241
|
-
return 'URL must start with http:// or https://';
|
|
242
|
-
}
|
|
243
|
-
return true;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
]);
|
|
247
|
-
apiUrl = customUrl;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
console.log(chalk.green(`✓ API endpoint: ${apiUrl}\n`));
|
|
252
|
-
|
|
253
|
-
spinner.start('Connecting to DeSciX...');
|
|
254
|
-
const apiClient = new DeSciXApiClient({ baseUrl: apiUrl });
|
|
255
|
-
spinner.succeed('Connected to DeSciX');
|
|
256
|
-
|
|
257
|
-
// Step 1: Authentication (required)
|
|
258
|
-
console.log(chalk.cyan('\n📋 Step 1: Authentication\n'));
|
|
259
|
-
|
|
260
|
-
// Pass the API URL to login commands
|
|
261
|
-
const authOptions = { url: apiUrl };
|
|
262
|
-
|
|
263
|
-
const isAuth = await isAuthenticated(apiClient);
|
|
264
|
-
|
|
265
|
-
if (!isAuth) {
|
|
266
|
-
console.log(chalk.yellow('⚠️ Authentication is required to use DeSciX CLI/MCP.\n'));
|
|
267
|
-
|
|
268
|
-
const { authMethod } = await inquirer.prompt([
|
|
269
|
-
{
|
|
270
|
-
type: 'list',
|
|
271
|
-
name: 'authMethod',
|
|
272
|
-
message: 'How would you like to authenticate?',
|
|
273
|
-
choices: [
|
|
274
|
-
{ name: 'Device Login (recommended - opens browser)', value: 'device' },
|
|
275
|
-
{ name: 'Direct Wallet Connection (advanced)', value: 'wallet' }
|
|
276
|
-
],
|
|
277
|
-
default: 'device'
|
|
278
|
-
}
|
|
279
|
-
]);
|
|
280
|
-
|
|
281
|
-
if (authMethod === 'device') {
|
|
282
|
-
await authCommands.loginDevice(authOptions);
|
|
283
|
-
} else {
|
|
284
|
-
await authCommands.loginWallet();
|
|
285
|
-
}
|
|
286
|
-
} else {
|
|
287
|
-
console.log(chalk.green('✅ Already authenticated\n'));
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Verify authentication
|
|
291
|
-
await requireAuth(apiClient);
|
|
292
|
-
console.log(chalk.green('✅ Authentication verified\n'));
|
|
293
|
-
|
|
294
|
-
// Step 2: Fetch Entitlements
|
|
295
|
-
console.log(chalk.cyan('\n📋 Step 2: Fetching Entitlements\n'));
|
|
296
|
-
|
|
297
|
-
let entitlements = { communities: [], apps: [], service_slots: [] };
|
|
298
|
-
spinner.start('Fetching your entitlements...');
|
|
299
|
-
|
|
300
|
-
try {
|
|
301
|
-
const purchasesResult = await apiClient.invoke('fetch_my_purchases', {});
|
|
302
|
-
if (purchasesResult && purchasesResult.status !== 'ERROR') {
|
|
303
|
-
entitlements = {
|
|
304
|
-
communities: purchasesResult.communities || [],
|
|
305
|
-
apps: purchasesResult.apps || [],
|
|
306
|
-
service_slots: purchasesResult.service_slots || []
|
|
307
|
-
};
|
|
308
|
-
spinner.succeed(`Found ${entitlements.communities.length} communities, ${entitlements.apps.length} apps`);
|
|
309
|
-
|
|
310
|
-
// Display entitlements
|
|
311
|
-
if (entitlements.communities.length > 0) {
|
|
312
|
-
console.log(chalk.gray('\n Communities:'));
|
|
313
|
-
for (const c of entitlements.communities) {
|
|
314
|
-
console.log(chalk.gray(` - ${c.community_name || c.name || c.community_id} (${c.community_id || c.id})`));
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
if (entitlements.apps.length > 0) {
|
|
318
|
-
console.log(chalk.gray('\n Apps:'));
|
|
319
|
-
for (const a of entitlements.apps.slice(0, 5)) {
|
|
320
|
-
console.log(chalk.gray(` - ${a.community_id}/${a.app_id || a.id}`));
|
|
321
|
-
}
|
|
322
|
-
if (entitlements.apps.length > 5) {
|
|
323
|
-
console.log(chalk.gray(` ... and ${entitlements.apps.length - 5} more`));
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
console.log('');
|
|
327
|
-
} else {
|
|
328
|
-
spinner.warn('Could not fetch entitlements (will use defaults)');
|
|
329
|
-
}
|
|
330
|
-
} catch (error) {
|
|
331
|
-
spinner.warn('Could not fetch entitlements: ' + error.message);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// Step 3: Pull SDK Assets
|
|
335
|
-
console.log(chalk.cyan('\n📋 Step 3: Pulling SDK Agent Assets\n'));
|
|
336
|
-
|
|
337
|
-
spinner.start('Pulling SDK agent assets...');
|
|
338
|
-
const assetsPulled = await pullSdkAssets(workspaceRoot);
|
|
339
|
-
|
|
340
|
-
if (assetsPulled) {
|
|
341
|
-
spinner.succeed('SDK agent assets pulled');
|
|
342
|
-
console.log(chalk.gray(' Created: .descix/sdk-assets/'));
|
|
343
|
-
console.log(chalk.gray(' - instructions/ (onboarding, packaging types, etc.)'));
|
|
344
|
-
console.log(chalk.gray(' - templates/ (app scaffolds)'));
|
|
345
|
-
console.log(chalk.gray(' - rules/ (agent instructions template)\n'));
|
|
346
|
-
} else {
|
|
347
|
-
spinner.warn('SDK agent assets not found (development mode)');
|
|
348
|
-
console.log(chalk.gray(' Skipped: .descix/sdk-assets/\n'));
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// Derive primary community from entitlements
|
|
352
|
-
let primaryCommunity = 'daita';
|
|
353
|
-
if (entitlements.communities.length > 0) {
|
|
354
|
-
primaryCommunity = entitlements.communities[0].community_id || entitlements.communities[0].id || 'daita';
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Step 4: MCP Configuration
|
|
358
|
-
console.log(chalk.cyan('\n📋 Step 4: MCP Configuration\n'));
|
|
359
|
-
|
|
360
|
-
const { setupMCP } = await inquirer.prompt([
|
|
361
|
-
{
|
|
362
|
-
type: 'confirm',
|
|
363
|
-
name: 'setupMCP',
|
|
364
|
-
message: 'Set up Cursor MCP integration?',
|
|
365
|
-
default: true
|
|
366
|
-
}
|
|
367
|
-
]);
|
|
368
|
-
|
|
369
|
-
if (setupMCP) {
|
|
370
|
-
spinner.start('Creating MCP configuration...');
|
|
371
|
-
|
|
372
|
-
// Use npx approach for reliability (like Pinecone does)
|
|
373
|
-
const mcpServer = getMcpServerConfig();
|
|
374
|
-
|
|
375
|
-
// Create .cursor/mcp.json
|
|
376
|
-
const cursorDir = path.join(workspaceRoot, '.cursor');
|
|
377
|
-
await fs.mkdir(cursorDir, { recursive: true });
|
|
378
|
-
|
|
379
|
-
// Build MCP server config - npx handles all dependencies
|
|
380
|
-
const mcpServerConfig = {
|
|
381
|
-
command: mcpServer.command,
|
|
382
|
-
args: mcpServer.args
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
// Read existing config if present to preserve other servers
|
|
386
|
-
let existingConfig = { mcpServers: {} };
|
|
387
|
-
const cursorConfigPath = path.join(cursorDir, 'mcp.json');
|
|
388
|
-
try {
|
|
389
|
-
const existing = await fs.readFile(cursorConfigPath, 'utf-8');
|
|
390
|
-
existingConfig = JSON.parse(existing);
|
|
391
|
-
if (!existingConfig.mcpServers) {
|
|
392
|
-
existingConfig.mcpServers = {};
|
|
393
|
-
}
|
|
394
|
-
} catch {
|
|
395
|
-
// No existing config, that's fine
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
// Add/update descix server
|
|
399
|
-
existingConfig.mcpServers['descix'] = mcpServerConfig;
|
|
400
|
-
|
|
401
|
-
await fs.writeFile(cursorConfigPath, JSON.stringify(existingConfig, null, 2));
|
|
402
|
-
|
|
403
|
-
spinner.succeed('MCP configuration created');
|
|
404
|
-
console.log(chalk.gray(` Created: .cursor/mcp.json`));
|
|
405
|
-
console.log(chalk.gray(` Server: ${mcpServer.command} ${mcpServer.args.join(' ')}`));
|
|
406
|
-
|
|
407
|
-
// Deploy customized rules file with entitlements
|
|
408
|
-
spinner.start('Generating customized agent rules...');
|
|
409
|
-
|
|
410
|
-
const rulesGenerated = await generateRulesFile(workspaceRoot, entitlements, primaryCommunity);
|
|
411
|
-
|
|
412
|
-
if (rulesGenerated) {
|
|
413
|
-
spinner.succeed('Agent rules file generated with entitlements');
|
|
414
|
-
console.log(chalk.gray(` Created: .cursor/rules/descix_mcp.mdc`));
|
|
415
|
-
console.log(chalk.gray(` - Embedded ${entitlements.communities.length} communities`));
|
|
416
|
-
console.log(chalk.gray(` - Embedded ${entitlements.apps.length} apps`));
|
|
417
|
-
console.log(chalk.gray(` - References local SDK assets at .descix/sdk-assets/\n`));
|
|
418
|
-
} else {
|
|
419
|
-
// Fall back to simple template
|
|
420
|
-
spinner.info('Using simple rules template');
|
|
421
|
-
const rulesDir = path.join(workspaceRoot, '.cursor', 'rules');
|
|
422
|
-
await fs.mkdir(rulesDir, { recursive: true });
|
|
423
|
-
|
|
424
|
-
const templatePath = path.join(__dirname, '../../templates/descix_mcp.mdc');
|
|
425
|
-
const rulesPath = path.join(rulesDir, 'descix_mcp.mdc');
|
|
426
|
-
|
|
427
|
-
try {
|
|
428
|
-
const templateContent = await fs.readFile(templatePath, 'utf-8');
|
|
429
|
-
await fs.writeFile(rulesPath, templateContent, 'utf-8');
|
|
430
|
-
console.log(chalk.gray(` Created: .cursor/rules/descix_mcp.mdc\n`));
|
|
431
|
-
} catch (error) {
|
|
432
|
-
console.log(chalk.gray(` Skipped: .cursor/rules/descix_mcp.mdc\n`));
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// Step 5: Create workspace config
|
|
438
|
-
spinner.start('Creating workspace configuration...');
|
|
439
|
-
|
|
440
|
-
const config = {
|
|
441
|
-
version: '2.0',
|
|
442
|
-
primaryCommunity,
|
|
443
|
-
directoryMappings: {}, // Empty - AI agent will configure after setup
|
|
444
|
-
additionalContexts: [],
|
|
445
|
-
defaultContext: {
|
|
446
|
-
communityId: primaryCommunity,
|
|
447
|
-
appId: 'daita',
|
|
448
|
-
kbId: 'General'
|
|
449
|
-
},
|
|
450
|
-
apiUrl: apiUrl,
|
|
451
|
-
environment: apiUrl.includes('localhost') ? 'development' : 'production',
|
|
452
|
-
_setupStatus: 'mcp_ready',
|
|
453
|
-
_needsAgentSetup: true, // Flag for AI agent to help with workspace config
|
|
454
|
-
_sdkVersion: SDK_VERSION
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
const descixDir = path.join(workspaceRoot, '.descix');
|
|
458
|
-
await fs.mkdir(descixDir, { recursive: true });
|
|
459
|
-
const configPath = path.join(descixDir, 'workspace.json');
|
|
460
|
-
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
461
|
-
|
|
462
|
-
spinner.succeed('Workspace configured');
|
|
463
|
-
console.log(chalk.gray(` Created: .descix/workspace.json\n`));
|
|
464
|
-
|
|
465
|
-
// Step 6: Auto-register SDK service for tell_me_how discovery
|
|
466
|
-
console.log(chalk.cyan('\n📋 Step 6: Registering SDK Service\n'));
|
|
467
|
-
|
|
468
|
-
spinner.start('Registering SDK for tell_me_how discovery...');
|
|
469
|
-
const sdkRegistered = await autoRegisterSdkService(apiClient);
|
|
470
|
-
|
|
471
|
-
if (sdkRegistered) {
|
|
472
|
-
spinner.succeed('SDK service registered');
|
|
473
|
-
console.log(chalk.gray(' SDK tools now discoverable via tell_me_how\n'));
|
|
474
|
-
} else {
|
|
475
|
-
spinner.warn('Could not register SDK service (will work without discovery)');
|
|
476
|
-
console.log(chalk.gray(' SDK tools available but not indexed for search\n'));
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// Done!
|
|
480
|
-
console.log(chalk.green('\n✅ MCP Setup Complete!\n'));
|
|
481
|
-
console.log(chalk.white('Next steps:'));
|
|
482
|
-
console.log(chalk.gray(' 1. Restart Cursor (Cmd/Ctrl + Shift + P → "Reload Window")'));
|
|
483
|
-
console.log(chalk.gray(' 2. Ask the AI agent: "Help me configure my workspace"\n'));
|
|
484
|
-
|
|
485
|
-
console.log(chalk.white('The AI agent will:'));
|
|
486
|
-
console.log(chalk.gray(' - Read your entitlements and show available apps'));
|
|
487
|
-
console.log(chalk.gray(' - Help you map local folders to DeSciX apps'));
|
|
488
|
-
console.log(chalk.gray(' - Analyze folder structure and recommend packaging types'));
|
|
489
|
-
console.log(chalk.gray(' - Register apps in workspace.json\n'));
|
|
490
|
-
|
|
491
|
-
console.log(chalk.white('If MCP fails, use CLI directly:'));
|
|
492
|
-
console.log(chalk.gray(' descix purchases # View your entitlements'));
|
|
493
|
-
console.log(chalk.gray(' descix tell-me-how "question" # Discover tools'));
|
|
494
|
-
console.log(chalk.gray(' descix app sync-assets -a Y # Sync app assets'));
|
|
495
|
-
console.log(chalk.gray(' descix kb corpus sync -a Y # Sync knowledge base\n'));
|
|
496
|
-
|
|
497
|
-
} catch (error) {
|
|
498
|
-
spinner.fail('Setup failed');
|
|
499
|
-
console.error(chalk.red(error.message));
|
|
500
|
-
throw error;
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
|
package/templates/descix_mcp.mdc
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
alwaysApply: true
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
### DeSciX Intelligent Tool Discovery
|
|
6
|
-
|
|
7
|
-
**IMPORTANT: Use `tell_me_how` before attempting any DeSciX platform operation.**
|
|
8
|
-
|
|
9
|
-
The DeSciX platform uses semantic tool discovery. Instead of memorizing commands:
|
|
10
|
-
1. Ask `tell_me_how` what you want to accomplish
|
|
11
|
-
2. The platform finds relevant tools based on your access level
|
|
12
|
-
3. Execute the recommended tools via `execute_remote_command`
|
|
13
|
-
|
|
14
|
-
### Tool Discovery with Scope Control
|
|
15
|
-
|
|
16
|
-
Use `tell_me_how` with appropriate scope:
|
|
17
|
-
|
|
18
|
-
- **Project scope** (`--scope project`): When working within a specific project context
|
|
19
|
-
```
|
|
20
|
-
tell_me_how({ question: "How do I sync my KB?", scope: "project" })
|
|
21
|
-
```
|
|
22
|
-
Uses communities/apps from `.descix/workspace.json`
|
|
23
|
-
|
|
24
|
-
- **Entitlements scope** (DEFAULT): When you need actionable tools you can use now
|
|
25
|
-
```
|
|
26
|
-
tell_me_how({ question: "How do I deploy a token?" })
|
|
27
|
-
```
|
|
28
|
-
Only returns tools from communities you're a member of and apps you own/purchased
|
|
29
|
-
|
|
30
|
-
- **Discovery scope** (`--scope discovery`): When exploring platform capabilities
|
|
31
|
-
```
|
|
32
|
-
tell_me_how({ question: "What AI training tools exist?", scope: "discovery" })
|
|
33
|
-
```
|
|
34
|
-
Returns all tools; indicates which require purchase
|
|
35
|
-
|
|
36
|
-
### Execution Pattern
|
|
37
|
-
|
|
38
|
-
After `tell_me_how` returns recommended tools:
|
|
39
|
-
|
|
40
|
-
```javascript
|
|
41
|
-
// 1. Ask how to do something
|
|
42
|
-
const plan = await tell_me_how({
|
|
43
|
-
question: "Create a bonding curve for my community",
|
|
44
|
-
scope: "entitlements"
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// 2. Execute the recommended command
|
|
48
|
-
await execute_remote_command({
|
|
49
|
-
command: plan.recommended_tools[0].name,
|
|
50
|
-
params: { /* parameters from plan */ }
|
|
51
|
-
});
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### Local Operations
|
|
55
|
-
|
|
56
|
-
These tools run locally (no `tell_me_how` needed):
|
|
57
|
-
|
|
58
|
-
- `descix_init` - Initialize project with `.descix/workspace.json`
|
|
59
|
-
- `descix_wizard_step` - Multi-step wizards (app creation, etc.)
|
|
60
|
-
- `git_sync_ops` - Git operations with auto-generated commit messages
|
|
61
|
-
|
|
62
|
-
### Knowledge Base Queries
|
|
63
|
-
|
|
64
|
-
For documentation and RAG queries, use `tell_me_how` to discover the right KB:
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
tell_me_how({ question: "Where is the SDK authentication documented?" })
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Or query directly if you know the KB:
|
|
71
|
-
|
|
72
|
-
- `search_knowledge_base` with `communityId`, `appId`, `kbId`
|
|
73
|
-
- `chat_with_kb` for conversational queries
|
|
74
|
-
|
|
75
|
-
### Knowledge Base References
|
|
76
|
-
|
|
77
|
-
The DeSciX platform documentation is organized in the `descix/docs` app:
|
|
78
|
-
|
|
79
|
-
- **sdk** - SDK documentation, CLI commands, MCP integration
|
|
80
|
-
- **architecture** - Platform architecture, design patterns
|
|
81
|
-
- **cloud** - Backend services, API, deployment
|
|
82
|
-
- **pwa** - Frontend React components, state management
|
|
83
|
-
- **contracts** - Smart contracts, token economics
|
|
84
|
-
|
|
85
|
-
### Service Registration
|
|
86
|
-
|
|
87
|
-
When registering a new microservice:
|
|
88
|
-
|
|
89
|
-
1. **Create SERVICE_README_{app_id}.md** in the app's Drive folder
|
|
90
|
-
2. Follow the template provided by `descix service register --help`
|
|
91
|
-
3. The README is vectorized for `tell_me_how` discovery
|
|
92
|
-
|
|
93
|
-
If the README is missing, the CLI provides AI-friendly instructions you can use directly.
|
|
94
|
-
|
|
95
|
-
### Error Recovery
|
|
96
|
-
|
|
97
|
-
If a command fails:
|
|
98
|
-
|
|
99
|
-
1. Use `tell_me_how` to find alternative approaches
|
|
100
|
-
2. Check `search_knowledge_base` for error-specific documentation
|
|
101
|
-
3. Verify scope - you may need `discovery` scope to find the right tool
|
|
102
|
-
|
|
103
|
-
### CLI Quick Reference
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
# Discover tools (primary command)
|
|
107
|
-
descix tell-me-how "What you want to accomplish"
|
|
108
|
-
descix tell-me-how --scope project "sync my knowledge base"
|
|
109
|
-
descix tell-me-how --scope discovery "what tokenomics tools exist"
|
|
110
|
-
|
|
111
|
-
# Local operations
|
|
112
|
-
descix init # Initialize project
|
|
113
|
-
descix setup # One-time setup
|
|
114
|
-
|
|
115
|
-
# Authentication
|
|
116
|
-
descix login # Authenticate
|
|
117
|
-
descix mcp quickstart # Full MCP setup
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
*This rules file is deployed by `descix mcp init`. Regenerate with `descix mcp quickstart`.*
|