@descix/cli 1.0.1 → 1.0.4
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/LICENSE.md +671 -0
- package/README.md +43 -4
- package/agent-assets/guides/README.md +2 -2
- package/agent-assets/guides/dynamic-site-pattern.md +29 -14
- package/agent-assets/guides/knowledge-only-pattern.md +5 -5
- package/agent-assets/guides/microservice-pattern.md +48 -4
- package/agent-assets/guides/static-site-pattern.md +8 -0
- package/agent-assets/instructions/app-asset-validation.md +5 -5
- package/agent-assets/instructions/onboarding-flow.md +4 -4
- package/agent-assets/instructions/standard-folder-structure.md +20 -11
- package/agent-assets/reference/app-creation.md +42 -20
- package/agent-assets/reference/architecture.md +24 -22
- package/agent-assets/reference/local-dev.md +230 -67
- package/agent-assets/reference/mcp-integration.md +21 -15
- package/agent-assets/reference/platform-api-consumer.md +244 -0
- package/agent-assets/reference/workspace-config.md +7 -7
- package/agent-assets/rules/descix_mcp.template.mdc +8 -8
- package/bin/descix.js +2559 -1435
- package/bin/kb-deny-lint.mjs +91 -0
- package/bin/mcp-server.js +175 -91
- package/lib/agent-files.js +37 -25
- package/lib/api-client.js +223 -56
- package/lib/auth-guard.js +13 -3
- package/lib/chat-session.js +187 -0
- package/lib/cli-version.js +59 -0
- package/lib/commands/airdrop.js +251 -0
- package/lib/commands/auth.js +254 -72
- package/lib/commands/briefer/errors.js +88 -0
- package/lib/commands/briefer/index.js +319 -0
- package/lib/commands/briefer/sources/canonical-sources.js +129 -0
- package/lib/commands/briefer/sources/entitlements.js +220 -0
- package/lib/commands/briefer/sources/environments.js +205 -0
- package/lib/commands/briefer/sources/identifiers.js +214 -0
- package/lib/commands/briefer/sources/microservice-deploy.js +267 -0
- package/lib/commands/briefer/sources/routing.js +275 -0
- package/lib/commands/briefer/sources/what-is-not.js +223 -0
- package/lib/commands/briefer/stitcher.js +134 -0
- package/lib/commands/briefer/util/source-reader.js +502 -0
- package/lib/commands/config.js +210 -90
- package/lib/commands/corpus.js +978 -0
- package/lib/commands/credits.js +122 -0
- package/lib/commands/health.js +627 -0
- package/lib/commands/kb-list-render.js +32 -0
- package/lib/commands/kb.js +190 -413
- package/lib/commands/mcp.js +5 -5
- package/lib/commands/microservice-restart.js +359 -0
- package/lib/commands/model-config.js +313 -0
- package/lib/commands/retired-kb-sync.js +134 -0
- package/lib/commands/serve.js +26 -1
- package/lib/commands/status.js +23 -51
- package/lib/commands/update.js +36 -107
- package/lib/core/Chunker.js +491 -17
- package/lib/core/CorpusDenyLint.js +326 -0
- package/lib/core/CorpusWalker.js +357 -0
- package/lib/core/Hydrator.js +75 -29
- package/lib/core/ManifestLoader.js +533 -0
- package/lib/core/SiteWalker.js +218 -0
- package/lib/core/Syncer.js +163 -11
- package/lib/diagnostic-log.js +41 -0
- package/lib/environment-report.js +100 -0
- package/lib/global-config.js +4 -1
- package/lib/oauth-client.js +164 -0
- package/lib/origin.js +143 -0
- package/lib/service-api-client.js +95 -0
- package/lib/wallet-environment.js +49 -0
- package/lib/wallet-file.js +16 -2
- package/lib/wizard/setup.js +10 -9
- package/lib/workspace-config.js +380 -235
- package/lib/workspace-identity.js +92 -0
- package/lib/workspace-utils.js +41 -61
- package/package.json +19 -6
- package/templates/agent-claude.md +157 -9
- package/templates/agent-cline.md +68 -8
- package/templates/agent-copilot.md +68 -8
- package/templates/agent-cursor.md +68 -8
- package/templates/alignment-schema.json +20 -0
- package/templates/cloud-brain-hook.sh +20 -0
- package/templates/drive/README.md +1 -1
- package/templates/drive_templates/README.md +2 -2
- package/templates/scaffolds/README.md +6 -10
- package/templates/scaffolds/microservice/SERVICE_README_sdk.md +104 -149
- package/templates/scaffolds/microservice/app.js +51 -10
- package/templates/scaffolds/microservice/app.yaml +2 -2
- package/templates/scaffolds/microservice/defaults-config-dev.json +4 -0
- package/templates/scaffolds/microservice/dev-overrides.example.json +5 -0
- package/templates/scaffolds/microservice/manifest.json +0 -1
- package/templates/scaffolds/microservice/package.json +3 -3
- package/templates/scaffolds/microservice/scripts/register.js +56 -41
- package/templates/scaffolds/microservice/services/mcpClient.js +55 -65
- package/templates/scaffolds/microservice/services/utils.js +20 -238
- package/templates/scaffolds/microservice/templates/SERVICE_README_TEMPLATE.md +24 -0
- package/lib/commands/app-wizard.js +0 -627
- package/lib/commands/folder.js +0 -291
- package/lib/core/PathContext.js +0 -335
- package/templates/scaffolds/microservice/dev-overrides.json.example +0 -5
- package/templates/scaffolds/site/DeSciXAppSDK.js +0 -62
- package/templates/scaffolds/site/README.md +0 -51
- package/templates/scaffolds/site/app.js +0 -22
- package/templates/scaffolds/site/index.html +0 -42
- package/templates/scaffolds/site/styles.css +0 -123
package/lib/commands/update.js
CHANGED
|
@@ -24,7 +24,7 @@ import crypto from 'crypto';
|
|
|
24
24
|
import { DeSciXApiClient } from '../api-client.js';
|
|
25
25
|
import { requireAuth } from '../auth-guard.js';
|
|
26
26
|
import { WorkspaceConfig } from '../workspace-config.js';
|
|
27
|
-
import {
|
|
27
|
+
import { refuseRetiredKbSync } from './retired-kb-sync.js';
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Helper to load workspace context with options override
|
|
@@ -36,26 +36,13 @@ async function loadWorkspaceContext(options = {}) {
|
|
|
36
36
|
const workspaceConfig = await WorkspaceConfig.load();
|
|
37
37
|
const ctx = workspaceConfig.requireContext(options);
|
|
38
38
|
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
if (!appConfig && ctx.communityId) {
|
|
42
|
-
appConfig = workspaceConfig.getApp(ctx.communityId, ctx.appId);
|
|
43
|
-
if (appConfig) {
|
|
44
|
-
appConfig = {
|
|
45
|
-
localPath: appConfig.localPath,
|
|
46
|
-
absolutePath: appConfig.absolutePath || (workspaceConfig.workspaceRoot && appConfig.localPath
|
|
47
|
-
? path.join(workspaceConfig.workspaceRoot, appConfig.localPath)
|
|
48
|
-
: null),
|
|
49
|
-
communityId: ctx.communityId,
|
|
50
|
-
kbId: appConfig.kbId || 'General'
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
}
|
|
39
|
+
// Unified Registry: getAppByAppId only — v1 community-keyed fallback removed
|
|
40
|
+
const appConfig = workspaceConfig.getAppByAppId(ctx.appId);
|
|
54
41
|
|
|
55
42
|
if (!appConfig) {
|
|
56
43
|
throw new Error(
|
|
57
44
|
`App "${ctx.appId}" not found in workspace.json.\n` +
|
|
58
|
-
'
|
|
45
|
+
'Use `descix app init` to register, or `descix app set-localpath -a <id> -p <path>` to repoint.'
|
|
59
46
|
);
|
|
60
47
|
}
|
|
61
48
|
|
|
@@ -183,11 +170,17 @@ export async function updateAuto(options = {}) {
|
|
|
183
170
|
case 'app':
|
|
184
171
|
return await updateApp(options);
|
|
185
172
|
case 'kb':
|
|
186
|
-
|
|
173
|
+
// kb sync has exactly ONE surface. Auto-detect lands here whenever the user is
|
|
174
|
+
// standing in the app's kb/ directory, so this path is REACHED in normal use —
|
|
175
|
+
// it is the single most likely way someone still tries to sync a KB via `update`.
|
|
176
|
+
// Refuses through the one owner so this branch and the explicit `update kb`
|
|
177
|
+
// branch cannot drift apart.
|
|
178
|
+
spinner.stop();
|
|
179
|
+
return refuseRetiredKbSync('descix update kb', chalk.red);
|
|
187
180
|
case 'site':
|
|
188
181
|
return await updateSite(options);
|
|
189
182
|
case 'microservice':
|
|
190
|
-
console.log(chalk.yellow(' Microservice deployment not supported via update. Use \'descix deploy\'.\n'));
|
|
183
|
+
console.log(chalk.yellow(' Microservice deployment not supported via update. Use \'descix microservice deploy\'.\n'));
|
|
191
184
|
return { success: false, reason: 'use_deploy' };
|
|
192
185
|
default:
|
|
193
186
|
console.log(chalk.yellow(` Unknown sync type: ${syncType}. Use 'descix update app/kb/site' explicitly.\n`));
|
|
@@ -278,12 +271,17 @@ export async function updateApp(options = {}) {
|
|
|
278
271
|
let baseFolderId = ctx.workspaceConfig.driveConfig?.base_folder_id;
|
|
279
272
|
|
|
280
273
|
if (!baseFolderId) {
|
|
281
|
-
|
|
282
|
-
|
|
274
|
+
// `get_my_profile` was a call to a verb NOTHING SERVES: it is absent from Cloud's command
|
|
275
|
+
// registry and had zero references anywhere in DeSciX_Cloud, DeSciX_Core or DeSciX_Powch
|
|
276
|
+
// outside this one call site (measured 2026-08-29). `get_folder_info` is the served,
|
|
277
|
+
// AUTHENTICATED verb that owns this fact — registry.js maps it to appCommands.js, and for
|
|
278
|
+
// entity_type 'user' it returns the caller's own base_folder_id as `folder_id`.
|
|
279
|
+
const folderInfo = await apiClient.invoke('get_folder_info', { entity_type: 'user' });
|
|
280
|
+
baseFolderId = folderInfo.message?.folder_id;
|
|
283
281
|
}
|
|
284
282
|
|
|
285
283
|
if (!baseFolderId) {
|
|
286
|
-
throw new Error('No base Drive folder configured
|
|
284
|
+
throw new Error('No base Drive folder configured: set driveConfig.base_folder_id in .descix/workspace.json.');
|
|
287
285
|
}
|
|
288
286
|
|
|
289
287
|
// Navigate to assets folder: {base}/{community}/{app}/assets
|
|
@@ -359,61 +357,8 @@ export async function updateApp(options = {}) {
|
|
|
359
357
|
}
|
|
360
358
|
}
|
|
361
359
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
*
|
|
365
|
-
* Drive Mode (Drive → GCS → Pinecone) is server-side only for PWA users.
|
|
366
|
-
* CLI mandates Git Mode: local files are chunked locally and upserted directly.
|
|
367
|
-
*
|
|
368
|
-
* Convention: KB files are in {appPath}/kb/{kbId}/
|
|
369
|
-
*/
|
|
370
|
-
export async function updateKB(options = {}) {
|
|
371
|
-
const apiClient = new DeSciXApiClient();
|
|
372
|
-
await requireAuth(apiClient);
|
|
373
|
-
|
|
374
|
-
const spinner = ora('Loading context...').start();
|
|
375
|
-
|
|
376
|
-
try {
|
|
377
|
-
const ctx = await loadWorkspaceContext(options);
|
|
378
|
-
const kbId = ctx.kbId;
|
|
379
|
-
|
|
380
|
-
spinner.succeed(`KB: ${ctx.appId}/${kbId}`);
|
|
381
|
-
|
|
382
|
-
// Resolve community_id from Products when missing (Unified Registry - app_id only)
|
|
383
|
-
if (!ctx.communityId) {
|
|
384
|
-
try {
|
|
385
|
-
const productCtx = await apiClient.invoke('get_product_context', { app_id: ctx.appId });
|
|
386
|
-
ctx.communityId = productCtx?.community_id || productCtx?.message?.community_id;
|
|
387
|
-
if (!ctx.communityId) {
|
|
388
|
-
throw new Error(`Product "${ctx.appId}" not found in Products registry. Run bootstrap.`);
|
|
389
|
-
}
|
|
390
|
-
} catch (err) {
|
|
391
|
-
if (err.message?.includes('not found')) throw err;
|
|
392
|
-
throw new Error(`Could not resolve community for app "${ctx.appId}". Run bootstrap.`);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
console.log(chalk.cyan('\n📤 Updating Knowledge Base\n'));
|
|
397
|
-
console.log(chalk.gray(` Community: ${ctx.communityId}`));
|
|
398
|
-
console.log(chalk.gray(` App: ${ctx.appId}`));
|
|
399
|
-
console.log(chalk.gray(` KB: ${kbId}`));
|
|
400
|
-
console.log(chalk.gray(` Source: ${path.join(ctx.appPath, 'kb', kbId)}\n`));
|
|
401
|
-
|
|
402
|
-
// Git Mode: chunk local files → kb_sync_chunks → Pinecone
|
|
403
|
-
// (Drive → GCS → Pinecone is server-side only for PWA users)
|
|
404
|
-
const kbOptions = { ...options, app: ctx.appId, community: ctx.communityId, kb: kbId, quiet: true };
|
|
405
|
-
await runKbChunk(kbOptions);
|
|
406
|
-
await runKbSync(apiClient, kbOptions);
|
|
407
|
-
|
|
408
|
-
console.log(chalk.green('\n✓ Knowledge base updated successfully\n'));
|
|
409
|
-
return { success: true };
|
|
410
|
-
|
|
411
|
-
} catch (error) {
|
|
412
|
-
spinner.fail('Update failed');
|
|
413
|
-
console.error(chalk.red(`\n❌ ${error.message}\n`));
|
|
414
|
-
throw error;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
360
|
+
// updateKB is DELETED. `update kb` refuses and names `descix kb corpus sync`; `update all`
|
|
361
|
+
// and `update auto` no longer touch the KB. No exported symbol survives without a caller.
|
|
417
362
|
|
|
418
363
|
/**
|
|
419
364
|
* Update site (deploy to GCS)
|
|
@@ -431,25 +376,12 @@ export async function updateSite(options = {}) {
|
|
|
431
376
|
// Convention: site folder path
|
|
432
377
|
const siteDir = path.join(ctx.appPath, 'site');
|
|
433
378
|
|
|
434
|
-
// Handle local port registration
|
|
379
|
+
// Handle local port registration — setSitePort mutates the live env entry and saves
|
|
435
380
|
if (options.port) {
|
|
436
381
|
spinner.text = `Registering local port: ${options.port}`;
|
|
437
382
|
try {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
if (appConfig) {
|
|
441
|
-
if (!appConfig.site) appConfig.site = {};
|
|
442
|
-
appConfig.site.port = options.port;
|
|
443
|
-
// Also set devCommand if not present (default guess)
|
|
444
|
-
if (!appConfig.site.devCommand) {
|
|
445
|
-
appConfig.site.devCommand = 'npm run dev';
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
await ctx.workspaceConfig.save();
|
|
449
|
-
console.log(chalk.green(`\n✅ Local port ${options.port} registered in workspace.json`));
|
|
450
|
-
} else {
|
|
451
|
-
console.log(chalk.yellow(`\n⚠️ App not found in workspace.json. Run 'descix init' first.`));
|
|
452
|
-
}
|
|
383
|
+
await ctx.workspaceConfig.setSitePort(ctx.appId, options.port);
|
|
384
|
+
console.log(chalk.green(`\n✅ Local port ${options.port} registered in workspace.json`));
|
|
453
385
|
} catch (err) {
|
|
454
386
|
console.log(chalk.yellow(`\n⚠️ Could not register port: ${err.message}`));
|
|
455
387
|
}
|
|
@@ -512,7 +444,7 @@ export async function updateSite(options = {}) {
|
|
|
512
444
|
preview: options.preview || false
|
|
513
445
|
});
|
|
514
446
|
|
|
515
|
-
const { signed_urls, existing_manifest, token_id, site_url } = tokenResponse.message;
|
|
447
|
+
const { signed_urls, upload_headers, existing_manifest, token_id, site_url } = tokenResponse.message;
|
|
516
448
|
|
|
517
449
|
// Determine delta
|
|
518
450
|
let filesToUpload = fileList;
|
|
@@ -543,10 +475,15 @@ export async function updateSite(options = {}) {
|
|
|
543
475
|
if (!signedUrl) continue;
|
|
544
476
|
|
|
545
477
|
const content = await fs.readFile(path.join(siteDir, file.path));
|
|
546
|
-
|
|
478
|
+
|
|
479
|
+
// Canonical contract (WS-DEPLOY-HARDENING item 4): the server binds Cache-Control into
|
|
480
|
+
// the v4 signed URL signature (generateSiteUploadUrls/siteAssetCacheControl). Ferry the
|
|
481
|
+
// exact header bag the server minted — never re-derive the policy client-side, and never
|
|
482
|
+
// send a header the signature doesn't expect (GCS returns 403 signature-mismatch).
|
|
483
|
+
const headers = (upload_headers && upload_headers[file.path]) || { 'Content-Type': file.content_type };
|
|
547
484
|
const response = await fetch(signedUrl, {
|
|
548
485
|
method: 'PUT',
|
|
549
|
-
headers
|
|
486
|
+
headers,
|
|
550
487
|
body: content
|
|
551
488
|
});
|
|
552
489
|
|
|
@@ -613,16 +550,9 @@ export async function updateAll(options = {}) {
|
|
|
613
550
|
// assets folder doesn't exist, skip
|
|
614
551
|
}
|
|
615
552
|
|
|
616
|
-
//
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
await fs.access(kbDir);
|
|
620
|
-
console.log(chalk.white('\n─── Knowledge Base ───\n'));
|
|
621
|
-
results.kb = await updateKB(options);
|
|
622
|
-
} catch {
|
|
623
|
-
// kb folder doesn't exist, skip
|
|
624
|
-
}
|
|
625
|
-
|
|
553
|
+
// Knowledge bases are NOT part of `update all`. The one KB sync surface is
|
|
554
|
+
// `descix kb corpus sync` (git-manifest); this composite keeps doing app and site.
|
|
555
|
+
|
|
626
556
|
// Check for site folder and update if exists
|
|
627
557
|
const siteDir = path.join(ctx.appPath, 'site');
|
|
628
558
|
try {
|
|
@@ -647,7 +577,6 @@ export async function updateAll(options = {}) {
|
|
|
647
577
|
export default {
|
|
648
578
|
updateAuto,
|
|
649
579
|
updateApp,
|
|
650
|
-
updateKB,
|
|
651
580
|
updateSite,
|
|
652
581
|
updateAll
|
|
653
582
|
};
|