@descix/cli 3.0.1 → 3.0.2

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/bin/descix.js CHANGED
@@ -7,7 +7,8 @@
7
7
  * Combines CLI and MCP functionality with unified authentication.
8
8
  */
9
9
 
10
- import { Command, Option } from 'commander';
10
+ import { Option } from 'commander';
11
+ import { DescixCommand } from '../lib/descix-command.js';
11
12
  import chalk from 'chalk';
12
13
  import { DeSciXApiClient } from '../lib/api-client.js';
13
14
  import { requireAuth } from '../lib/auth-guard.js';
@@ -73,7 +74,7 @@ function fail(error) {
73
74
  process.exit(1);
74
75
  }
75
76
 
76
- const program = new Command();
77
+ const program = new DescixCommand();
77
78
 
78
79
  program
79
80
  .name('descix')
@@ -155,6 +156,7 @@ program.hook('preAction', (thisCommand) => {
155
156
 
156
157
  program
157
158
  .command('login')
159
+ .runbookAnchor('#_3-pin-production-then-sign-in')
158
160
  .description('Authenticate with DeSciX via device login (opens browser)')
159
161
  .option('-u, --url <url>', 'API URL override')
160
162
  .option('--wallet', 'Use direct wallet connection (advanced, not yet implemented)')
@@ -174,6 +176,7 @@ program
174
176
 
175
177
  program
176
178
  .command('logout')
179
+ .runbookAnchor('#_3-pin-production-then-sign-in')
177
180
  .description('Clear saved credentials')
178
181
  .action(async () => {
179
182
  try {
@@ -229,6 +232,7 @@ program
229
232
 
230
233
  program
231
234
  .command('whoami')
235
+ .runbookAnchor('#_3-pin-production-then-sign-in')
232
236
  .description('Show current authentication status')
233
237
  .action(async () => {
234
238
  try {
@@ -265,6 +269,7 @@ program
265
269
 
266
270
  program
267
271
  .command('doctor')
272
+ .runbookAnchor('#_3-pin-production-then-sign-in')
268
273
  .description('Diagnose environment issues (Node, Auth, gcloud, ADC)')
269
274
  .action(async () => {
270
275
  try {
@@ -1041,6 +1046,7 @@ appCommand
1041
1046
 
1042
1047
  appCommand
1043
1048
  .command('init')
1049
+ .runbookAnchor('#_4-connect-the-repository-to-its-app')
1044
1050
  // ONE PATH TO AN APP (CEO-D-2026-08-14): `app init` is THE app entry point — it creates the
1045
1051
  // app when it does not exist yet and then registers/scaffolds it locally. The separate
1046
1052
  // `app create` command is DELETED (no compat fence): two commands for one outcome is how apps
@@ -1151,6 +1157,7 @@ appCommand
1151
1157
 
1152
1158
  appCommand
1153
1159
  .command('set-listed')
1160
+ .runbookAnchor('#_9-list-it-and-discover-the-rest')
1154
1161
  .description('List or unlist your app in the app store (on: shown in the public store; off: not shown to non-admin visitors)')
1155
1162
  .argument('<state>', 'on or off')
1156
1163
  .requiredOption('-c, --community <id>', 'Community ID')
@@ -1532,6 +1539,7 @@ appCommand
1532
1539
  // Backed by WorkspaceConfig.setStaticSite. It writes ONLY the local workspace.json site.{} slot.
1533
1540
  appCommand
1534
1541
  .command('set-site')
1542
+ .runbookAnchor('#_5-run-it-locally-descix-serve')
1535
1543
  .description("Set this workspace app's site config (env.app.site). One active mode per write: --static <dir> (built site served at /p/<app>/) or --port <n> [--protocol http|https] (dev server proxied at /p/<app>); setting one clears the other. Pass both flags together to keep both — the gateway then serves the dev server (site.port wins). --unset clears site.{} entirely.")
1536
1544
  .requiredOption('-a, --app <app_id>', 'App ID (must be this workspace\'s app, env.app)')
1537
1545
  .option('--static <path>', 'Static mode: a dir relative to the workspace root (the repo root), e.g. "site" or "../scratch"; "." = the root itself. An absolute path is refused. Alone, it clears site.port and site.protocol (one active mode per write).')
@@ -1696,6 +1704,7 @@ const kbCommand = program
1696
1704
 
1697
1705
  kbCommand
1698
1706
  .command('list')
1707
+ .runbookAnchor('#_6-knowledge-bases')
1699
1708
  .description('List knowledge bases for an app')
1700
1709
  .requiredOption('-a, --app <app_id>', 'App ID')
1701
1710
  .option('--cached', 'Show the fast cached vector counter instead of the TRUE live Pinecone count. The cached counter is written ONLY by the CLI/PWA sync path, so it reports 0 for KBs ingested by any other route even when their vectors retrieve. Default is the live count.')
@@ -1992,6 +2001,7 @@ const corpusCommand = kbCommand
1992
2001
 
1993
2002
  corpusCommand
1994
2003
  .command('sync')
2004
+ .runbookAnchor('#_6-knowledge-bases')
1995
2005
  .description('Sync the files a corpus manifest names into the app\'s knowledge base')
1996
2006
  .requiredOption('-a, --app <id>', 'App ID')
1997
2007
  .option('-c, --community <community_id>', 'Community ID (optional; resolved from Products when omitted)')
@@ -2021,6 +2031,7 @@ corpusCommand
2021
2031
 
2022
2032
  corpusCommand
2023
2033
  .command('status')
2034
+ .runbookAnchor('#_6-knowledge-bases')
2024
2035
  .description('Show corpus sync state (files, chunks, last sync, resolved ref)')
2025
2036
  .requiredOption('-a, --app <id>', 'App ID')
2026
2037
  .option('-k, --kb <name>', 'KB name (default: all)')
@@ -2183,6 +2194,7 @@ siteCommand
2183
2194
  // site upload - Deploy to GCS (context-aware, manifest-aware)
2184
2195
  siteCommand
2185
2196
  .command('upload')
2197
+ .runbookAnchor('#_8-deploy-the-site')
2186
2198
  .description('Upload site to GCS and update app metadata (uses .descix/manifests/site.json when present)')
2187
2199
  .option('-c, --community <id>', 'Community ID (auto-detects from context)')
2188
2200
  .option('-a, --app <id>', 'App ID (auto-detects from context)')
@@ -2586,6 +2598,7 @@ siteCommand
2586
2598
  // site status - Get deployment status (context-aware)
2587
2599
  siteCommand
2588
2600
  .command('status')
2601
+ .runbookAnchor('#_8-deploy-the-site')
2589
2602
  .description('Get deployment status and manifest')
2590
2603
  .option('-c, --community <id>', 'Community ID (auto-detects from context)')
2591
2604
  .option('-a, --app <id>', 'App ID (auto-detects from context)')
@@ -3349,6 +3362,7 @@ program
3349
3362
 
3350
3363
  program
3351
3364
  .command('chat [question...]')
3365
+ .runbookAnchor('#_6-knowledge-bases')
3352
3366
  .description('Chat with an app agent. Usage: descix chat "Your question" or descix chat -q "Your question"')
3353
3367
  .option('-c, --community <id>', 'Community ID (optional; server resolves it from Products)')
3354
3368
  .option('-a, --app <id>', 'App ID (required unless run from inside a mapped app directory)')
@@ -3665,6 +3679,7 @@ const configCommand = program
3665
3679
 
3666
3680
  configCommand
3667
3681
  .command('show')
3682
+ .runbookAnchor('#_3-pin-production-then-sign-in')
3668
3683
  .description('Show current configuration')
3669
3684
  .action(async () => {
3670
3685
  try {
@@ -3676,6 +3691,7 @@ configCommand
3676
3691
 
3677
3692
  configCommand
3678
3693
  .command('init')
3694
+ .runbookAnchor('#_3-pin-production-then-sign-in')
3679
3695
  .description('Pin this workspace to an environment (requires the global --env dev|demo|prod)')
3680
3696
  // `--dev` DELETED, not deprecated: its absence meant PRODUCTION, so the most common
3681
3697
  // invocation (`descix config init`) wrote a prod origin nobody named. There is no default.
@@ -4096,6 +4112,7 @@ mcpCommand
4096
4112
 
4097
4113
  program
4098
4114
  .command('tell-me-how')
4115
+ .runbookAnchor('#_9-list-it-and-discover-the-rest')
4099
4116
  .description('Discover platform tools using natural language (Intelligent MCP Mesh)')
4100
4117
  .argument('<question>', 'What do you want to accomplish? Use natural language.')
4101
4118
  .option('-s, --scope <scope>', 'Search scope (validated against the published tell_me_how enum): bootstrap, artifact, project, entitlements (default), discovery', 'entitlements')
@@ -4236,6 +4253,7 @@ program
4236
4253
 
4237
4254
  program
4238
4255
  .command('serve')
4256
+ .runbookAnchor('#_5-run-it-locally-descix-serve')
4239
4257
  .description('Start the unified local gateway (one HTTPS origin: App Shell at /, your app at /p/<app>, /apifront to the API)')
4240
4258
  .option('-p, --port <port>', 'Gateway port for this run (default: env.gateway.port, else 5173)')
4241
4259
  .option('-w, --workspace <path>', 'Workspace root override')
@@ -4267,6 +4285,7 @@ const devCertsCommand = program
4267
4285
 
4268
4286
  devCertsCommand
4269
4287
  .command('check')
4288
+ .runbookAnchor('#_5-run-it-locally-descix-serve')
4270
4289
  .description('Check whether the dev-server cert is trusted for https://localhost (exit 0 only when trusted)')
4271
4290
  .option('--json', 'Output raw JSON')
4272
4291
  .action(async (options) => {
@@ -4280,6 +4299,7 @@ devCertsCommand
4280
4299
 
4281
4300
  devCertsCommand
4282
4301
  .command('trust')
4302
+ .runbookAnchor('#_5-run-it-locally-descix-serve')
4283
4303
  .description('Trust the dev-server cert in the macOS keychain (prompts for your password)')
4284
4304
  .action(async () => {
4285
4305
  try {
@@ -0,0 +1,43 @@
1
+ /**
2
+ * DescixCommand — the CLI's commander Command, carrying ONE extra fact per verb: the
3
+ * app-developer runbook section that documents it.
4
+ *
5
+ * The fact is declared BESIDE the verb's own definition in bin/descix.js
6
+ * (`.command('serve').runbookAnchor('#_5-run-it-locally-descix-serve')`), so the verb tree and
7
+ * its runbook pointers can never be two lists. `createCommand` makes every subcommand a
8
+ * DescixCommand (commander's documented subclassing hook), so `.runbookAnchor()` chains on any
9
+ * `.command(...)` in the tree.
10
+ *
11
+ * The value is the anchor VitePress renders for the runbook heading (leading '#'). Whether it
12
+ * names a REAL heading is gated by tests/cli-verbs-generated.test.js against the runbook
13
+ * source (scripts/lib/runbook-anchors.mjs owns the slug rule). A verb with no runbook section
14
+ * declares nothing — there is no placeholder anchor. Read only by
15
+ * scripts/lib/cli-verb-tree-hook.mjs, which publishes the tree into
16
+ * @descix/platform-api/mcp-tools (cli-verbs.generated.json).
17
+ */
18
+ import { Command } from 'commander';
19
+
20
+ const ANCHOR_SHAPE = /^#[^\sA-Z#]+$/;
21
+
22
+ export class DescixCommand extends Command {
23
+ createCommand(name) {
24
+ return new DescixCommand(name);
25
+ }
26
+
27
+ /** @param {string} anchor '#<slug>' as rendered by the docs site @returns {this} */
28
+ runbookAnchor(anchor) {
29
+ if (this._descixRunbookAnchor !== undefined) {
30
+ throw new Error(`descix ${this.name()}: runbookAnchor declared twice (${this._descixRunbookAnchor}, ${anchor}) — one verb, one section`);
31
+ }
32
+ if (typeof anchor !== 'string' || !ANCHOR_SHAPE.test(anchor)) {
33
+ throw new Error(`descix ${this.name()}: runbookAnchor must be a rendered anchor like "#_5-run-it-locally-descix-serve"; got ${JSON.stringify(anchor)}`);
34
+ }
35
+ this._descixRunbookAnchor = anchor;
36
+ return this;
37
+ }
38
+
39
+ /** @returns {string|null} the declared anchor, or null when the verb has no runbook section */
40
+ declaredRunbookAnchor() {
41
+ return this._descixRunbookAnchor ?? null;
42
+ }
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descix/cli",
3
- "version": "3.0.1",
3
+ "version": "3.0.2",
4
4
  "description": "DeSciX CLI and MCP Server - Unified command-line interface for DeSciX platform",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,6 +17,7 @@
17
17
  "test": "node --experimental-test-module-mocks --test \"tests/*.test.js\"",
18
18
  "pack": "npm pack",
19
19
  "check:doc-paths": "node scripts/check-doc-paths.js",
20
+ "generate:cli-verbs": "node scripts/generate-cli-verbs.mjs",
20
21
  "briefer": "node scripts/briefer/run.mjs"
21
22
  },
22
23
  "keywords": [