@descix/cli 1.0.17 → 1.0.18
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/agent-assets/guides/README.md +2 -1
- package/agent-assets/guides/dynamic-site-pattern.md +6 -10
- package/agent-assets/guides/knowledge-only-pattern.md +12 -11
- package/agent-assets/guides/microservice-pattern.md +13 -16
- package/agent-assets/guides/static-site-pattern.md +6 -7
- package/agent-assets/instructions/app-asset-validation.md +61 -59
- package/agent-assets/instructions/onboarding-flow.md +57 -73
- package/agent-assets/instructions/standard-folder-structure.md +39 -36
- package/agent-assets/reference/app-creation.md +27 -33
- package/agent-assets/reference/architecture.md +85 -148
- package/agent-assets/reference/local-dev.md +5 -83
- package/agent-assets/reference/mcp-integration.md +32 -39
- package/agent-assets/reference/workspace-config.md +9 -10
- package/bin/descix.js +5 -0
- package/lib/help-guard.js +85 -0
- package/package.json +1 -1
- package/templates/agent-claude.md +6 -4
- package/templates/agent-cline.md +2 -2
- package/templates/agent-copilot.md +2 -2
- package/templates/agent-cursor.md +2 -2
|
@@ -10,7 +10,7 @@ This document covers how AI agents interact with the DeSciX platform via MCP (Mo
|
|
|
10
10
|
|
|
11
11
|
## 1. Architecture Overview
|
|
12
12
|
|
|
13
|
-
DeSciX operates as a **Federated MCP Service Mesh**. The
|
|
13
|
+
DeSciX operates as a **Federated MCP Service Mesh**. The DeSciX backend acts as a broker that aggregates tools from all registered microservices into a unified catalog.
|
|
14
14
|
|
|
15
15
|
**Key Innovation:** AI agents discover and invoke capabilities across the entire mesh without knowing where individual services are hosted.
|
|
16
16
|
|
|
@@ -24,7 +24,7 @@ AI Agent (Cursor/MCP Client)
|
|
|
24
24
|
execute_remote_command
|
|
25
25
|
│
|
|
26
26
|
▼
|
|
27
|
-
|
|
27
|
+
DeSciX Backend (Federated Broker)
|
|
28
28
|
│
|
|
29
29
|
├──► Service 1 (Powch)
|
|
30
30
|
├──► Service 2 (SmartModel)
|
|
@@ -42,9 +42,9 @@ MCP provides the communication protocol between AI agents and the DeSciX platfor
|
|
|
42
42
|
**Key Tools:**
|
|
43
43
|
- `tell_me_how` - Semantic tool discovery
|
|
44
44
|
- `execute_remote_command` - Execute any backend command
|
|
45
|
-
- `
|
|
46
|
-
- `
|
|
47
|
-
- `
|
|
45
|
+
- `descix_doctor` - CLI-local startup diagnostic (auth, workspace, tools, warnings)
|
|
46
|
+
- `ask_question_to_app` - RAG chat with an app's knowledge base (synthesized answer, cited)
|
|
47
|
+
- `query_knowledge_base` - Raw vector search, returns chunks
|
|
48
48
|
|
|
49
49
|
### 2.2 Cursor/AI Agent Integration
|
|
50
50
|
|
|
@@ -91,13 +91,17 @@ Once signed in, `tell_me_how` is the **primary entry point** for discovering pla
|
|
|
91
91
|
|
|
92
92
|
**Rule:** Sign in, then ask `tell_me_how` first, then execute the recommended command.
|
|
93
93
|
|
|
94
|
-
### 3.2
|
|
94
|
+
### 3.2 Scopes
|
|
95
|
+
|
|
96
|
+
The validated `tell_me_how` scope enum has five values:
|
|
95
97
|
|
|
96
98
|
| Scope | Description | Use Case |
|
|
97
99
|
|-------|-------------|----------|
|
|
98
|
-
| `entitlements` (default) | Only tools user has access to | Production usage |
|
|
100
|
+
| `entitlements` (default) | Only tools the user has access to | Production usage |
|
|
99
101
|
| `project` | Tools filtered by workspace.json | Working within a project |
|
|
100
102
|
| `discovery` | All available tools | Exploring capabilities |
|
|
103
|
+
| `bootstrap` | Deterministic first-call on-ramp: platform summary, caller context, credit balance, essential tool schemas (no vector search; `question` is optional for this scope only) | First contact / first call in a session |
|
|
104
|
+
| `artifact` | Deterministic build/reproduce provenance for a published app (npm package + spec, artifact/notebook URLs, runnable `npx` commands), no vector search | "How do I build on / reproduce this app?" |
|
|
101
105
|
|
|
102
106
|
### 3.3 CLI Usage
|
|
103
107
|
|
|
@@ -151,7 +155,7 @@ After `descix quickstart` completes:
|
|
|
151
155
|
|
|
152
156
|
### 4.1 Federated MCP Broker
|
|
153
157
|
|
|
154
|
-
|
|
158
|
+
The DeSciX backend aggregates tools from all registered microservices:
|
|
155
159
|
|
|
156
160
|
```
|
|
157
161
|
Microservice A
|
|
@@ -161,7 +165,7 @@ Microservice A
|
|
|
161
165
|
Registers with Core
|
|
162
166
|
│
|
|
163
167
|
▼
|
|
164
|
-
|
|
168
|
+
DeSciX Backend (Broker)
|
|
165
169
|
└── Aggregated tools/list
|
|
166
170
|
│
|
|
167
171
|
▼
|
|
@@ -199,14 +203,11 @@ execute_remote_command({
|
|
|
199
203
|
|
|
200
204
|
### 4.3 Service Registration
|
|
201
205
|
|
|
202
|
-
Services self-register with the broker
|
|
206
|
+
Services self-register with the broker in one step — registration also vectorizes the README you
|
|
207
|
+
pass, so there is no separate developer-facing vectorize step:
|
|
203
208
|
|
|
204
209
|
```bash
|
|
205
|
-
|
|
206
|
-
descix microservice register -m ./manifest.json
|
|
207
|
-
|
|
208
|
-
# Vectorize SERVICE_README for discovery
|
|
209
|
-
descix microservice vectorize -r SERVICE_README.md
|
|
210
|
+
descix microservice register -r SERVICE_README.md
|
|
210
211
|
```
|
|
211
212
|
|
|
212
213
|
### 4.4 The execute_remote_command Pattern
|
|
@@ -309,11 +310,13 @@ When `--scope project` is used:
|
|
|
309
310
|
|
|
310
311
|
### 6.1 KB Operations via tell_me_how
|
|
311
312
|
|
|
312
|
-
|
|
313
|
+
`tell_me_how` can be asked about KB sync in plain language, but the actionable answer for a
|
|
314
|
+
developer is always the CLI verb, not the raw backend command names (`kb_sync_chunks` etc. are
|
|
315
|
+
internal to the backend, not something the CLI calls directly by name):
|
|
313
316
|
|
|
314
317
|
```bash
|
|
315
318
|
descix tell-me-how "How do I sync my knowledge base?"
|
|
316
|
-
#
|
|
319
|
+
# The developer-facing command either way: descix kb corpus sync
|
|
317
320
|
```
|
|
318
321
|
|
|
319
322
|
### 6.2 workspace.json from Hydration
|
|
@@ -324,7 +327,7 @@ descix tell-me-how "How do I sync my knowledge base?"
|
|
|
324
327
|
{
|
|
325
328
|
"env": { "apiUrl": "https://dev.descix.net", "products": [ /* one entry per app */ ] },
|
|
326
329
|
"driveConfig": {
|
|
327
|
-
"base_folder_id": "..." //
|
|
330
|
+
"base_folder_id": "..." // Only used by `descix drive pull/push` — unrelated to tell_me_how scope
|
|
328
331
|
}
|
|
329
332
|
}
|
|
330
333
|
```
|
|
@@ -334,9 +337,9 @@ descix tell-me-how "How do I sync my knowledge base?"
|
|
|
334
337
|
Custom services integrate with the same pattern:
|
|
335
338
|
|
|
336
339
|
1. Create `SERVICE_README_{name}.md`
|
|
337
|
-
2. Register with `descix microservice register`
|
|
338
|
-
|
|
339
|
-
|
|
340
|
+
2. Register with `descix microservice register -r SERVICE_README_{name}.md` — this both publishes
|
|
341
|
+
the manifest AND vectorizes the README in one step
|
|
342
|
+
3. Tools become discoverable via `tell_me_how`
|
|
340
343
|
|
|
341
344
|
---
|
|
342
345
|
|
|
@@ -355,7 +358,8 @@ Custom services integrate with the same pattern:
|
|
|
355
358
|
1. **Document all commands in SERVICE_README** - Required for discovery
|
|
356
359
|
2. **Use clear descriptions** - "Use when:" is crucial for semantic matching
|
|
357
360
|
3. **Include examples** - Helps AI agents understand usage
|
|
358
|
-
4. **
|
|
361
|
+
4. **Re-register after README changes** - `descix microservice register -r <file>` re-vectorizes
|
|
362
|
+
automatically; there is no separate vectorize step
|
|
359
363
|
|
|
360
364
|
### 7.3 Common Patterns
|
|
361
365
|
|
|
@@ -407,22 +411,11 @@ cd /path/to/workspace
|
|
|
407
411
|
|
|
408
412
|
### 8.3 "Command not found"
|
|
409
413
|
|
|
410
|
-
**Cause:** Service not registered or
|
|
414
|
+
**Cause:** Service not registered, or the README wasn't vectorized.
|
|
411
415
|
|
|
412
416
|
**Solution:**
|
|
413
|
-
1.
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
## 9. File References
|
|
420
|
-
|
|
421
|
-
| Component | Path |
|
|
422
|
-
|-----------|------|
|
|
423
|
-
| MCP Tools | `DeSciX_Core/descix-cli/bin/mcp-server.js` |
|
|
424
|
-
| tell_me_how Implementation | `DeSciX_Cloud/microservice/services/commandHandlers/ragCommands.js` |
|
|
425
|
-
| execute_remote_command | `DeSciX_Cloud/microservice/services/apiFront.js` |
|
|
426
|
-
| SERVICE_README Template | `DeSciX_Core/descix-cli/templates/scaffolds/microservice/templates/SERVICE_README_TEMPLATE.md` |
|
|
427
|
-
| Workspace Config | `DeSciX_Core/descix-cli/lib/workspace-config.js` |
|
|
428
|
-
| Service Registration | `DeSciX_Core/descix-cli/bin/descix.js` |
|
|
417
|
+
1. Re-run `descix microservice register -r SERVICE_README_<name>.md` — it re-publishes the
|
|
418
|
+
manifest and re-vectorizes the README (`descix microservice list` exists to enumerate
|
|
419
|
+
registered services, but it is an admin-only command, not something a developer runs)
|
|
420
|
+
2. Check `descix microservice health <name>` to confirm the service itself is reachable
|
|
421
|
+
3. Use `descix tell-me-how --scope discovery "..."` to find alternatives
|
|
@@ -160,13 +160,12 @@ descix site status -c egpt -a egpt-mydocs # site status/list need both when
|
|
|
160
160
|
|
|
161
161
|
---
|
|
162
162
|
|
|
163
|
-
## 7.
|
|
164
|
-
|
|
165
|
-
|
|
|
166
|
-
|
|
167
|
-
|
|
|
168
|
-
| Origin resolution
|
|
169
|
-
|
|
|
170
|
-
|
|
|
171
|
-
|
|
|
172
|
-
| Corpus sync | `DeSciX_Core/descix-cli/lib/commands/corpus.js` | manifests, sync-state |
|
|
163
|
+
## 7. Where each concept lives (conceptual, not a file map)
|
|
164
|
+
|
|
165
|
+
| Concept | Owner |
|
|
166
|
+
|---|---|
|
|
167
|
+
| Workspace loading, the v2.1 writer, app registration, context detection | `WorkspaceConfig`, internal to `@descix/cli` |
|
|
168
|
+
| Origin resolution precedence | flag → `DESCIX_API_URL` → `env.apiUrl` → default (`descix config` commands) |
|
|
169
|
+
| User-level settings (`~/.descixrc`) | `GlobalConfig`, internal to `@descix/cli` |
|
|
170
|
+
| `.descix/wallet.json` | written by `descix login` |
|
|
171
|
+
| Corpus manifests, sync-state | `descix kb corpus` commands, internal to `@descix/cli` |
|
package/bin/descix.js
CHANGED
|
@@ -35,6 +35,7 @@ import { registerAllRetiredKbSync, CANONICAL_KB_SYNC } from '../lib/commands/ret
|
|
|
35
35
|
import { runStatus } from '../lib/commands/status.js';
|
|
36
36
|
import { refreshCommunityIdentity, printIdentityReceipt } from '../lib/commands/communityIdentity.js';
|
|
37
37
|
import { runAppInit } from '../lib/commands/appInit.js';
|
|
38
|
+
import { assertKnownCommandForHelp } from '../lib/help-guard.js';
|
|
38
39
|
import { runDoctor } from '../lib/commands/doctor.js';
|
|
39
40
|
import { runHealth } from '../lib/commands/health.js';
|
|
40
41
|
import * as kbCommands from '../lib/commands/kb.js';
|
|
@@ -4650,6 +4651,10 @@ if (!adminMode && isHelpInvocation(program, rawArgv, { valueFlags: ['--env', '--
|
|
|
4650
4651
|
}
|
|
4651
4652
|
}
|
|
4652
4653
|
|
|
4654
|
+
// A command that does not exist must not appear to have help (see lib/help-guard.js). This runs
|
|
4655
|
+
// before the parse, because Commander resolves --help before it resolves the command.
|
|
4656
|
+
assertKnownCommandForHelp(program, process.argv.slice(2));
|
|
4657
|
+
|
|
4653
4658
|
// Parse arguments
|
|
4654
4659
|
await program.parseAsync(process.argv);
|
|
4655
4660
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A COMMAND THAT DOES NOT EXIST MUST NOT APPEAR TO HAVE HELP.
|
|
3
|
+
*
|
|
4
|
+
* Commander resolves `--help` before it resolves the command, so `descix update --help` printed the
|
|
5
|
+
* TOP-LEVEL help and exited 0 — indistinguishable, to a reader or a script, from a real verb with
|
|
6
|
+
* help. `descix update` alone correctly says `error: unknown command 'update'`.
|
|
7
|
+
*
|
|
8
|
+
* That exit 0 is not only wrong, it TAUGHT something wrong: the daita-sdk docs tell readers that
|
|
9
|
+
* `site upload --help` "silently prints top-level help" and to use `help <sub>` instead. It does no
|
|
10
|
+
* such thing for a real command; the author had been probing a command that did not exist (devx
|
|
11
|
+
* review 2026-09-19, I2 → S5).
|
|
12
|
+
*
|
|
13
|
+
* This guard runs ONLY when a help flag is present, so every other path keeps Commander's own
|
|
14
|
+
* behaviour (it already exits non-zero for an unknown command without `--help`).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const HELP_FLAGS = new Set(['-h', '--help']);
|
|
18
|
+
|
|
19
|
+
/** Does this option consume the next argv token as its value? */
|
|
20
|
+
function takesValue(option) {
|
|
21
|
+
return Boolean(option && option.required);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function findOption(command, token) {
|
|
25
|
+
const name = token.split('=')[0];
|
|
26
|
+
return command.options.find((o) => o.short === name || o.long === name);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function findSubcommand(command, token) {
|
|
30
|
+
return command.commands.find(
|
|
31
|
+
(c) => c.name() === token || (typeof c.aliases === 'function' && c.aliases().includes(token)),
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Walk argv down the command tree and return the first token that should name a subcommand but does
|
|
37
|
+
* not. Returns null when every command token resolves — including when a command takes positional
|
|
38
|
+
* arguments (a command with no subcommands ends the walk, so `descix chat hello` is not "unknown").
|
|
39
|
+
*
|
|
40
|
+
* @param {import('commander').Command} program
|
|
41
|
+
* @param {string[]} argv arguments after the node binary and script (process.argv.slice(2))
|
|
42
|
+
* @returns {{token: string, parent: import('commander').Command}|null}
|
|
43
|
+
*/
|
|
44
|
+
export function findUnknownCommand(program, argv) {
|
|
45
|
+
let command = program;
|
|
46
|
+
for (let i = 0; i < argv.length; i++) {
|
|
47
|
+
const token = argv[i];
|
|
48
|
+
if (token === '--') break;
|
|
49
|
+
if (token.startsWith('-')) {
|
|
50
|
+
if (takesValue(findOption(command, token)) && !token.includes('=')) i++;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
// A command with no subcommands takes positional arguments from here on.
|
|
54
|
+
if (command.commands.length === 0) break;
|
|
55
|
+
const sub = findSubcommand(command, token);
|
|
56
|
+
if (!sub) return { token, parent: command };
|
|
57
|
+
command = sub;
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The command names `parent` actually has, for the "did you mean" line. */
|
|
63
|
+
function nameList(parent) {
|
|
64
|
+
return parent.commands.map((c) => c.name()).sort();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* When argv asks for help on a command that does not exist, refuse by name and exit 1.
|
|
69
|
+
*
|
|
70
|
+
* @param {import('commander').Command} program
|
|
71
|
+
* @param {string[]} argv
|
|
72
|
+
* @param {{ error: (msg: string) => void, exit: (code: number) => void }} io
|
|
73
|
+
*/
|
|
74
|
+
export function assertKnownCommandForHelp(program, argv, io = { error: console.error, exit: process.exit }) {
|
|
75
|
+
if (!argv.some((a) => HELP_FLAGS.has(a))) return;
|
|
76
|
+
const unknown = findUnknownCommand(program, argv);
|
|
77
|
+
if (!unknown) return;
|
|
78
|
+
|
|
79
|
+
const path = [];
|
|
80
|
+
for (let c = unknown.parent; c && c.parent; c = c.parent) path.unshift(c.name());
|
|
81
|
+
const where = path.length ? `'descix ${path.join(' ')}'` : 'descix';
|
|
82
|
+
io.error(`error: unknown command '${unknown.token}'`);
|
|
83
|
+
io.error(`${where} has: ${nameList(unknown.parent).join(', ')}`);
|
|
84
|
+
io.exit(1);
|
|
85
|
+
}
|
package/package.json
CHANGED
|
@@ -226,8 +226,9 @@ const user = await powch.auth();
|
|
|
226
226
|
### KB Integration
|
|
227
227
|
|
|
228
228
|
If docs already exist (`docs/`, `README.md`, SDK reference files):
|
|
229
|
-
-
|
|
230
|
-
|
|
229
|
+
- Name the docs' folder as a source in a corpus manifest (`.descix/manifests/<KB>.json`), then run
|
|
230
|
+
`descix kb corpus sync`. The docs stay exactly where they are — there is no copy step and no
|
|
231
|
+
required KB folder.
|
|
231
232
|
- Ask: "I see docs in `docs/`. Want me to use those as your knowledge base?"
|
|
232
233
|
|
|
233
234
|
### Decision Guide
|
|
@@ -236,7 +237,7 @@ If docs already exist (`docs/`, `README.md`, SDK reference files):
|
|
|
236
237
|
|-----------------|---------------|-------------|
|
|
237
238
|
| HTML/JS app with `index.html` | Serve as-is, add DeSciXAppSDK.js | Use any `docs/` or `*.md` files |
|
|
238
239
|
| React/Vite app | Wrap root in `<AppShell>` | Use `docs/` or README |
|
|
239
|
-
| SDK package with docs + demo | Serve the SDK's demo page |
|
|
240
|
+
| SDK package with docs + demo | Serve the SDK's demo page | Name docs folder in a corpus manifest |
|
|
240
241
|
| Docs only (no frontend) | Skip or create minimal site | Docs ARE the KB |
|
|
241
242
|
| Empty repo | Scaffold from scratch | Create starter KB doc |
|
|
242
243
|
|
|
@@ -244,7 +245,8 @@ If docs already exist (`docs/`, `README.md`, SDK reference files):
|
|
|
244
245
|
|
|
245
246
|
Every app has three parts:
|
|
246
247
|
- `site/` — Frontend (any framework: React, VitePress, vanilla HTML)
|
|
247
|
-
- `
|
|
248
|
+
- A corpus manifest (`.descix/manifests/<KB>.json`) — names the git-tracked docs `descix kb corpus
|
|
249
|
+
sync` publishes; there is no required KB folder
|
|
248
250
|
- `microservice/` — Backend service (optional)
|
|
249
251
|
|
|
250
252
|
## App Context
|
package/templates/agent-cline.md
CHANGED
|
@@ -165,13 +165,13 @@ unverified step — see `.descix/sdk-assets/reference/local-dev.md` §3.3.
|
|
|
165
165
|
`DeSciXAppSDK.js` is GENERATED (from `descix-app-sdk/templates/DeSciXAppSDK.template.js`, with a `--check` drift gate) — copy it in, never hand-edit it; a local patch forks the bridge and stops inheriting its fixes.
|
|
166
166
|
- **React/Vite app:** Wrap root in `<AppShell appId="{{appId}}">` from `@descix/app-sdk/AppShell`.
|
|
167
167
|
- **Auth only (no DeSciX UI):** Use `PowchClient` from `@descix/app-sdk/powch-client`.
|
|
168
|
-
- **Existing docs:**
|
|
168
|
+
- **Existing docs:** Name the docs' folder as a source in a corpus manifest (`.descix/manifests/<KB>.json`), then `descix kb corpus sync`. Docs stay where they are — no copy step.
|
|
169
169
|
- **Empty repo:** Scaffold from scratch.
|
|
170
170
|
|
|
171
171
|
## App Structure
|
|
172
172
|
|
|
173
173
|
- `site/` — Frontend (any framework)
|
|
174
|
-
- `
|
|
174
|
+
- A corpus manifest (`.descix/manifests/<KB>.json`) — names the git-tracked docs `descix kb corpus sync` publishes (no required folder)
|
|
175
175
|
- `microservice/` — Backend service (optional)
|
|
176
176
|
|
|
177
177
|
## Context
|
|
@@ -165,13 +165,13 @@ unverified step — see `.descix/sdk-assets/reference/local-dev.md` §3.3.
|
|
|
165
165
|
`DeSciXAppSDK.js` is GENERATED (from `descix-app-sdk/templates/DeSciXAppSDK.template.js`, with a `--check` drift gate) — copy it in, never hand-edit it; a local patch forks the bridge and stops inheriting its fixes.
|
|
166
166
|
- **React/Vite app:** Wrap root in `<AppShell appId="{{appId}}">` from `@descix/app-sdk/AppShell`.
|
|
167
167
|
- **Auth only (no DeSciX UI):** Use `PowchClient` from `@descix/app-sdk/powch-client`.
|
|
168
|
-
- **Existing docs:**
|
|
168
|
+
- **Existing docs:** Name the docs' folder as a source in a corpus manifest (`.descix/manifests/<KB>.json`), then `descix kb corpus sync`. Docs stay where they are — no copy step.
|
|
169
169
|
- **Empty repo:** Scaffold from scratch.
|
|
170
170
|
|
|
171
171
|
## App Structure
|
|
172
172
|
|
|
173
173
|
- `site/` — Frontend (any framework)
|
|
174
|
-
- `
|
|
174
|
+
- A corpus manifest (`.descix/manifests/<KB>.json`) — names the git-tracked docs `descix kb corpus sync` publishes (no required folder)
|
|
175
175
|
- `microservice/` — Backend service (optional)
|
|
176
176
|
|
|
177
177
|
## Context
|
|
@@ -165,13 +165,13 @@ unverified step — see `.descix/sdk-assets/reference/local-dev.md` §3.3.
|
|
|
165
165
|
`DeSciXAppSDK.js` is GENERATED (from `descix-app-sdk/templates/DeSciXAppSDK.template.js`, with a `--check` drift gate) — copy it in, never hand-edit it; a local patch forks the bridge and stops inheriting its fixes.
|
|
166
166
|
- **React/Vite app:** Wrap root in `<AppShell appId="{{appId}}">` from `@descix/app-sdk/AppShell`.
|
|
167
167
|
- **Auth only (no DeSciX UI):** Use `PowchClient` from `@descix/app-sdk/powch-client`.
|
|
168
|
-
- **Existing docs:**
|
|
168
|
+
- **Existing docs:** Name the docs' folder as a source in a corpus manifest (`.descix/manifests/<KB>.json`), then `descix kb corpus sync`. Docs stay where they are — no copy step.
|
|
169
169
|
- **Empty repo:** Scaffold from scratch.
|
|
170
170
|
|
|
171
171
|
## App Structure
|
|
172
172
|
|
|
173
173
|
- `site/` — Frontend (any framework)
|
|
174
|
-
- `
|
|
174
|
+
- A corpus manifest (`.descix/manifests/<KB>.json`) — names the git-tracked docs `descix kb corpus sync` publishes (no required folder)
|
|
175
175
|
- `microservice/` — Backend service (optional)
|
|
176
176
|
|
|
177
177
|
## Context
|