@descix/cli 3.0.0 → 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/README.md +7 -5
- package/agent-assets/guides/dynamic-site-pattern.md +1 -2
- package/agent-assets/guides/knowledge-only-pattern.md +2 -3
- package/agent-assets/guides/microservice-pattern.md +2 -3
- package/agent-assets/guides/static-site-pattern.md +2 -3
- package/agent-assets/instructions/onboarding-flow.md +51 -69
- package/agent-assets/instructions/standard-folder-structure.md +14 -11
- package/agent-assets/reference/app-creation.md +9 -8
- package/agent-assets/reference/architecture.md +14 -17
- package/agent-assets/reference/local-dev.md +36 -32
- package/agent-assets/reference/mcp-integration.md +8 -9
- package/agent-assets/reference/workspace-config.md +59 -25
- package/bin/descix.js +79 -18
- package/lib/commands/config.js +18 -0
- package/lib/descix-command.js +43 -0
- package/lib/verb-invokes.generated.json +3 -0
- package/lib/workspace-config.js +101 -4
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -30,7 +30,8 @@ npm install -g @descix/cli
|
|
|
30
30
|
```
|
|
31
31
|
An unconfigured workspace resolves to the declared default, PROD, and every network-bound
|
|
32
32
|
command prints the environment, origin and source it resolved on stderr. For a local backend,
|
|
33
|
-
name the URL: `descix
|
|
33
|
+
name the URL: per run `descix --api-url https://localhost:4000 <command>`, or persistently
|
|
34
|
+
`descix config set-env local --url https://localhost:4000` (`set-env` refuses a known name).
|
|
34
35
|
|
|
35
36
|
3. **Check your status**:
|
|
36
37
|
```bash
|
|
@@ -111,21 +112,22 @@ The command is idempotent, so re-running it on a half-made app finishes the job.
|
|
|
111
112
|
**server-side** as `{community}-{short}`; defaults to `--app`.
|
|
112
113
|
- `--overwrite`: when creating, overwrite an existing app record intentionally.
|
|
113
114
|
- `--kb <name>`: knowledge base name (default: `General`).
|
|
114
|
-
- `-p, --path <dir>`: local app directory (default: auto-detected, else the current directory).
|
|
115
115
|
|
|
116
116
|
**What it does, in order:**
|
|
117
117
|
|
|
118
118
|
1. **Creates the app** (only when `-c` is given and the app does not exist): the server composes
|
|
119
119
|
the unique `app_id` and writes `Products/{app_id}` and `Community/{community}/Apps/{app_id}`.
|
|
120
120
|
Every app is guaranteed a default knowledge base at creation.
|
|
121
|
-
2. **
|
|
121
|
+
2. **Writes it as `env.app` in `.descix/workspace.json`** — the current directory, the repo root,
|
|
122
|
+
becomes the workspace root. A workspace holds one app: a repo that already holds a different
|
|
123
|
+
app is refused, and so is a directory nested inside another DeSciX workspace.
|
|
122
124
|
3. **Scaffolds the app folder**: creates `site/`, `microservice/` and `assets/`, and writes
|
|
123
125
|
`assets/system_instructions.md` and `assets/app_description.md` when they do not exist.
|
|
124
126
|
4. **Creates the knowledge base record** for Git-mode sync.
|
|
125
127
|
|
|
126
128
|
It fails loud rather than guessing: initializing an app that does not exist without `-c` names the
|
|
127
129
|
`-c` invocation that would create it; a `-c` that disagrees with the app's real community is
|
|
128
|
-
refused
|
|
130
|
+
refused.
|
|
129
131
|
|
|
130
132
|
**Next step** — author a corpus manifest at `.descix/manifests/<kb_name>.json`, then
|
|
131
133
|
`descix kb corpus sync -a <app_id>`.
|
|
@@ -147,7 +149,7 @@ descix site upload --env dev
|
|
|
147
149
|
### `descix site init`
|
|
148
150
|
|
|
149
151
|
Copies the site scaffold — `index.html`, `app.js`, `styles.css`, `DeSciXAppSDK.js`, `README.md` —
|
|
150
|
-
into the app's `site/` directory. The
|
|
152
|
+
into the app's `site/` directory. The workspace must already hold the app (`env.app`, written by `descix app init`).
|
|
151
153
|
|
|
152
154
|
- `-f, --force`: overwrite an existing `site/` folder.
|
|
153
155
|
- `-c, --community <id>` / `-a, --app <id>`: auto-detected from context when omitted.
|
|
@@ -57,13 +57,12 @@ Keeping the scaffold's shape is what lets the service keep inheriting platform b
|
|
|
57
57
|
|
|
58
58
|
## Configuration (`workspace.json`)
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
The repo's `env.app`, written by `descix app init` (run from the repo root) and `descix app set-port` (never by hand):
|
|
61
61
|
|
|
62
62
|
```json
|
|
63
63
|
{
|
|
64
64
|
"appId": "my-community-my-dynamic-app",
|
|
65
65
|
"communityId": "my-community",
|
|
66
|
-
"localPath": "my-dynamic-app",
|
|
67
66
|
"kbId": "General",
|
|
68
67
|
"microservice": { "port": 4001 }
|
|
69
68
|
}
|
|
@@ -39,14 +39,13 @@ example; `kb/General/` also works if that's where content ends up, e.g. from `de
|
|
|
39
39
|
|
|
40
40
|
## Configuration (`workspace.json`)
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
`microservice` slot:
|
|
42
|
+
The repo's `env.app`, written by `descix app init` (run from the repo root; never by hand); no `site`
|
|
43
|
+
and no `microservice` slot:
|
|
44
44
|
|
|
45
45
|
```json
|
|
46
46
|
{
|
|
47
47
|
"appId": "my-community-my-docs",
|
|
48
48
|
"communityId": "my-community",
|
|
49
|
-
"localPath": "my-docs",
|
|
50
49
|
"kbId": "General"
|
|
51
50
|
}
|
|
52
51
|
```
|
|
@@ -82,14 +82,13 @@ out until something depends on the difference.
|
|
|
82
82
|
|
|
83
83
|
## Configuration (`workspace.json`)
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
frontend) `descix app set-site` — never by hand:
|
|
85
|
+
The repo's `env.app`, written by `descix app init` (run from the repo root), `descix app set-port` and
|
|
86
|
+
(for the optional frontend) `descix app set-site` — never by hand:
|
|
87
87
|
|
|
88
88
|
```json
|
|
89
89
|
{
|
|
90
90
|
"appId": "my-community-my-service",
|
|
91
91
|
"communityId": "my-community",
|
|
92
|
-
"localPath": "my-service",
|
|
93
92
|
"kbId": "General",
|
|
94
93
|
"site": { "static": "site" },
|
|
95
94
|
"microservice": { "port": 4001 }
|
|
@@ -44,20 +44,19 @@ my-site/
|
|
|
44
44
|
|
|
45
45
|
## Configuration (`workspace.json`)
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
The repo's `env.app`, written by `descix app init` (run from the repo root) and `descix app set-site` (never by hand):
|
|
48
48
|
|
|
49
49
|
```json
|
|
50
50
|
{
|
|
51
51
|
"appId": "my-community-my-site",
|
|
52
52
|
"communityId": "my-community",
|
|
53
|
-
"localPath": "my-site",
|
|
54
53
|
"kbId": "General",
|
|
55
54
|
"site": { "static": "site" }
|
|
56
55
|
}
|
|
57
56
|
```
|
|
58
57
|
|
|
59
58
|
For a framework dev server instead of files on disk, `descix app set-site -a <app_id> --port 3000`
|
|
60
|
-
writes `"site": { "port": 3000 }`; the gateway proxies `/p/<app_id>` to it without rewriting paths,
|
|
59
|
+
writes `"site": { "port": 3000 }`; `--static` takes a directory relative to the repo root (`site`, `site/dist`, `.`, `../scratch`) and refuses an absolute path; the gateway proxies `/p/<app_id>` to it without rewriting paths,
|
|
61
60
|
so the framework's base path must be `/p/<app_id>/`.
|
|
62
61
|
|
|
63
62
|
## CLI Workflow
|
|
@@ -12,22 +12,21 @@ DeSciX uses **workspace.json** as the sole configuration file.
|
|
|
12
12
|
|
|
13
13
|
Location: `{workspace_root}/.descix/workspace.json`
|
|
14
14
|
|
|
15
|
-
Purpose:
|
|
15
|
+
Purpose: names THE app this repository holds (v3 single-app: one repo, one app, and the repo root
|
|
16
|
+
is the workspace root) and stores its configuration.
|
|
16
17
|
|
|
17
18
|
```json
|
|
18
19
|
{
|
|
19
|
-
"version": "
|
|
20
|
+
"version": "3.0",
|
|
21
|
+
"type": "workspace",
|
|
20
22
|
"env": {
|
|
21
|
-
"environment": "
|
|
22
|
-
"apiUrl": "https://
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"kbId": "General"
|
|
29
|
-
}
|
|
30
|
-
]
|
|
23
|
+
"environment": "PROD",
|
|
24
|
+
"apiUrl": "https://descix.net",
|
|
25
|
+
"app": {
|
|
26
|
+
"appId": "daita-appsdk",
|
|
27
|
+
"communityId": "daita",
|
|
28
|
+
"kbId": "General"
|
|
29
|
+
}
|
|
31
30
|
},
|
|
32
31
|
"driveConfig": {
|
|
33
32
|
"base_folder_id": "..."
|
|
@@ -35,18 +34,19 @@ Purpose: Maps local folders to DeSciX apps and stores all configuration.
|
|
|
35
34
|
}
|
|
36
35
|
```
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
`v1 workspace format is not supported. Migrate to
|
|
37
|
+
The loader refuses the retired shapes by name: a `communities`-keyed block with no `env` block
|
|
38
|
+
(`v1 workspace format is not supported. Migrate to v3.`) and an `env.platform` / `env.products`
|
|
39
|
+
block (`v2.1 multi-app workspace format is not supported. Migrate to v3 (single-app).`).
|
|
40
40
|
|
|
41
41
|
**Used for:**
|
|
42
|
-
- CLI auto-detection of
|
|
42
|
+
- CLI auto-detection of the app from the current directory (anywhere under the repo root)
|
|
43
43
|
- `tell_me_how --scope project` to discover project-specific tools
|
|
44
|
-
- MCP server to know which
|
|
44
|
+
- MCP server to know which app is in scope
|
|
45
45
|
- CLI to find the workspace root
|
|
46
46
|
|
|
47
47
|
### Key Principle
|
|
48
48
|
|
|
49
|
-
**workspace.json** is the single configuration file
|
|
49
|
+
**workspace.json** is the single configuration file for the app this repo holds. `descix app init` creates it at the repo root during onboarding; inside another DeSciX workspace it refuses — app repos are sibling checkouts, never nested.
|
|
50
50
|
|
|
51
51
|
---
|
|
52
52
|
|
|
@@ -66,8 +66,8 @@ START
|
|
|
66
66
|
├── Is this a fresh workspace (no .descix/workspace.json)?
|
|
67
67
|
│ └── YES → Run Full Setup Flow
|
|
68
68
|
│
|
|
69
|
-
├── Does
|
|
70
|
-
│ └── YES → Run App Configuration Flow
|
|
69
|
+
├── Does the user want to work on an app this repo does not hold?
|
|
70
|
+
│ └── YES → Run App Configuration Flow (that app gets its own repo)
|
|
71
71
|
│
|
|
72
72
|
└── Is everything configured?
|
|
73
73
|
└── YES → Ready for development
|
|
@@ -109,69 +109,51 @@ Service Slots:
|
|
|
109
109
|
- {slot_count} available for microservice deployment
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
-
### Step 3:
|
|
112
|
+
### Step 3: Choose the App This Repo Holds
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
- Ignore: `node_modules`, `.git`, `dist`, `build`, `.descix`
|
|
117
|
-
- Note folders that are already registered in `workspace.json`
|
|
118
|
-
|
|
119
|
-
### Step 4: Ask User About Folder Mappings
|
|
120
|
-
|
|
121
|
-
Present options:
|
|
114
|
+
One repo holds one app. Ask which of the user's apps this repository is for — or whether it is a
|
|
115
|
+
new app.
|
|
122
116
|
|
|
123
117
|
```
|
|
124
|
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
|
|
129
|
-
Would you like to map any to your apps?
|
|
130
|
-
|
|
131
|
-
Suggested mappings based on folder contents:
|
|
132
|
-
- frontend/ → {community}/pwa (Static Site)
|
|
133
|
-
- backend/ → {community}/api (Microservice)
|
|
134
|
-
- docs/ → {community}/docs (Knowledge Only)
|
|
135
|
-
|
|
136
|
-
Which mappings should I create?
|
|
118
|
+
This repository will hold ONE DeSciX app. Which one?
|
|
119
|
+
- {community_id}/{app_id} ({app_name})
|
|
120
|
+
- ...
|
|
121
|
+
- a new app in {community_id}
|
|
137
122
|
```
|
|
138
123
|
|
|
139
|
-
### Step
|
|
124
|
+
### Step 4: Create the Configuration
|
|
140
125
|
|
|
141
|
-
|
|
126
|
+
`workspace.json` is written by CLI verbs, never by hand. From the **repo root**:
|
|
142
127
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
Each mapping becomes one `env.products[]` entry (`appId`, `communityId`, `localPath`, `kbId`).
|
|
128
|
+
```bash
|
|
129
|
+
descix config init --env prod # creates workspace.json, pins env.apiUrl
|
|
130
|
+
descix app init -a {app_id} # an existing app: writes env.app
|
|
131
|
+
descix app init -a {name} -c {community_id} # a new app: creates it, then writes env.app
|
|
132
|
+
```
|
|
149
133
|
|
|
150
134
|
## App Configuration Flow
|
|
151
135
|
|
|
152
136
|
For apps that exist in entitlements but aren't configured locally:
|
|
153
137
|
|
|
154
|
-
### Step 1: Identify
|
|
138
|
+
### Step 1: Identify the Other Apps
|
|
155
139
|
|
|
156
|
-
Compare
|
|
157
|
-
|
|
158
|
-
- Mappings in `workspace.json`
|
|
140
|
+
Compare the apps from `fetch_my_purchases` with `env.app` in this repo's `workspace.json`. Every
|
|
141
|
+
other app lives in its own repository.
|
|
159
142
|
|
|
160
|
-
### Step 2: Ask About Each
|
|
143
|
+
### Step 2: Ask About Each One
|
|
161
144
|
|
|
162
145
|
```
|
|
163
|
-
You have these apps that
|
|
146
|
+
You have these apps that this repository does not hold:
|
|
164
147
|
- {community}/{app} - {description}
|
|
165
148
|
|
|
166
|
-
Would you like to:
|
|
167
|
-
1.
|
|
168
|
-
2.
|
|
169
|
-
3. Skip for now
|
|
149
|
+
Each app is its own repository. Would you like to:
|
|
150
|
+
1. Clone or create that app's repo as a sibling of this one, then run `descix app init` from its root
|
|
151
|
+
2. Skip for now
|
|
170
152
|
```
|
|
171
153
|
|
|
172
154
|
### Step 3: Determine Packaging Type
|
|
173
155
|
|
|
174
|
-
For
|
|
156
|
+
For the app this repo holds:
|
|
175
157
|
|
|
176
158
|
1. Read [guides/README.md](../guides/README.md) for the decision tree (Knowledge-Only / Static
|
|
177
159
|
Site / Microservice / Dynamic Site)
|
|
@@ -186,7 +168,7 @@ For each folder being configured:
|
|
|
186
168
|
After determining packaging type, ensure the folder follows the [Standard Folder Structure](./standard-folder-structure.md):
|
|
187
169
|
|
|
188
170
|
```
|
|
189
|
-
{
|
|
171
|
+
{repo_root}/
|
|
190
172
|
├── assets/ # App identity (required)
|
|
191
173
|
├── .descix/manifests/<KB>.json # Corpus manifest — required for RAG, see below
|
|
192
174
|
├── site/ # Static site (required)
|
|
@@ -252,7 +234,7 @@ Your app structure is now ready. Run `descix app sync-assets` to sync.
|
|
|
252
234
|
## Key Principles
|
|
253
235
|
|
|
254
236
|
### Never Assume
|
|
255
|
-
- Always ask before
|
|
237
|
+
- Always ask which app a repo holds before running `descix app init`
|
|
256
238
|
- Present options, let user choose
|
|
257
239
|
- Explain trade-offs of each packaging type
|
|
258
240
|
|
|
@@ -273,8 +255,8 @@ User hasn't purchased anything yet. Direct them to the PWA store.
|
|
|
273
255
|
### "App not in entitlements"
|
|
274
256
|
User is trying to configure an app they don't own. Suggest purchase.
|
|
275
257
|
|
|
276
|
-
### "
|
|
277
|
-
|
|
258
|
+
### "This workspace already holds app '<id>'"
|
|
259
|
+
A repo holds one app. Work on the other app in its own repo (a sibling checkout).
|
|
278
260
|
|
|
279
261
|
### Powch sign-in under `descix serve` fails ("User cancelled", or "WebAuthn is not supported on sites with TLS certificate errors")
|
|
280
262
|
The gateway's dev certificate is not trusted. Run `descix dev-certs check`. If it is not trusted,
|
|
@@ -327,7 +309,7 @@ You have access to:
|
|
|
327
309
|
- {app_2} - {app_2_status}
|
|
328
310
|
|
|
329
311
|
Would you like me to help you:
|
|
330
|
-
1.
|
|
312
|
+
1. Connect this repository to one of your apps
|
|
331
313
|
2. Explore what you can do with a specific app
|
|
332
314
|
3. Something else
|
|
333
315
|
```
|
|
@@ -343,9 +325,9 @@ Based on your purchases, here's what you can work with:
|
|
|
343
325
|
| {name} | {role} | {count} |
|
|
344
326
|
|
|
345
327
|
**Your Apps:**
|
|
346
|
-
| App | Status | Local
|
|
347
|
-
|
|
348
|
-
| {app_id} |
|
|
328
|
+
| App | Status | Local Repo |
|
|
329
|
+
|-----|--------|------------|
|
|
330
|
+
| {app_id} | Held by this repo / Not here | {repo or "—"} |
|
|
349
331
|
|
|
350
332
|
Which app would you like to work on?
|
|
351
333
|
```
|
|
@@ -358,7 +340,7 @@ All done! Your app is configured.
|
|
|
358
340
|
**Summary:**
|
|
359
341
|
- App: {community}/{app}
|
|
360
342
|
- Type: {packaging_type}
|
|
361
|
-
-
|
|
343
|
+
- Repo: {repo_root}
|
|
362
344
|
|
|
363
345
|
**What you can do now:**
|
|
364
346
|
- Use `tell_me_how` to discover tools
|
|
@@ -101,25 +101,28 @@ descix kb corpus sync # Walk the manifest's sources, chunk what changed, upsert
|
|
|
101
101
|
|
|
102
102
|
## Configuration Files
|
|
103
103
|
|
|
104
|
-
### `.descix/workspace.json` (Root) —
|
|
104
|
+
### `.descix/workspace.json` (Root) — v3 single-app, the only supported format
|
|
105
105
|
|
|
106
106
|
```json
|
|
107
107
|
{
|
|
108
|
-
"version": "
|
|
108
|
+
"version": "3.0",
|
|
109
|
+
"type": "workspace",
|
|
109
110
|
"env": {
|
|
110
|
-
"environment": "
|
|
111
|
-
"apiUrl": "https://
|
|
112
|
-
"
|
|
113
|
-
{ "appId": "my-dao-governance", "communityId": "my-dao", "localPath": "my-dao/governance", "kbId": "General" },
|
|
114
|
-
{ "appId": "my-dao-treasury", "communityId": "my-dao", "localPath": "my-dao/treasury", "kbId": "General" }
|
|
115
|
-
]
|
|
111
|
+
"environment": "PROD",
|
|
112
|
+
"apiUrl": "https://descix.net",
|
|
113
|
+
"app": { "appId": "my-dao-governance", "communityId": "my-dao", "kbId": "General" }
|
|
116
114
|
}
|
|
117
115
|
}
|
|
118
116
|
```
|
|
119
117
|
|
|
120
|
-
|
|
121
|
-
`
|
|
122
|
-
|
|
118
|
+
One repo, one app: `env.app` is THE app and the repo root is the workspace root. A second app
|
|
119
|
+
(`my-dao-treasury`) is its own repo, a sibling checkout with its own `workspace.json`.
|
|
120
|
+
|
|
121
|
+
Written by CLI verbs only — `descix config init`, `descix app init` (from the repo root; refused
|
|
122
|
+
inside another workspace), `descix app set-site`, `descix app set-port`. The loader refuses the
|
|
123
|
+
retired shapes by name: a `communities`-keyed block with no `env` block (`v1 workspace format is not
|
|
124
|
+
supported. Migrate to v3.`) and an `env.platform` / `env.products` block (`v2.1 multi-app workspace
|
|
125
|
+
format is not supported. Migrate to v3 (single-app).`).
|
|
123
126
|
|
|
124
127
|
**Sync mode:** The CLI only performs **git-mode** operations (local files → corpus manifest →
|
|
125
128
|
Pinecone, via `descix kb corpus sync`). Drive-mode (Drive → GCS → Pinecone, fully server-side) is
|
|
@@ -12,7 +12,7 @@ This document describes how apps and communities are created in the DeSciX platf
|
|
|
12
12
|
|
|
13
13
|
**"One path to an app"**
|
|
14
14
|
|
|
15
|
-
- **Apps:** `descix app init -a <name> -c <community
|
|
15
|
+
- **Apps:** `descix app init -a <name> -c <community>`, run from the app repo's root, creates the app on the platform (`create_app_for_community`, which composes the id `<community>-<short>` and guarantees the default KB) and writes it as the repo's `env.app` in one idempotent step. The PWA creates apps too; both reach the same server command. Entitlement checks run server-side either way.
|
|
16
16
|
- **Communities:** created by platform admins only (`descix community create` is `[ADMIN]` and writes live Polygon). A developer builds inside an existing community.
|
|
17
17
|
- **Development:** the CLI is the tool for the local workspace, content, and syncing to the cloud.
|
|
18
18
|
|
|
@@ -211,18 +211,19 @@ sequenceDiagram
|
|
|
211
211
|
## 4. Local Workspace
|
|
212
212
|
|
|
213
213
|
There is no PWA "workspace builder" hand-off and no hydration step. The local workspace is built by
|
|
214
|
-
CLI verbs, each writing one part of `.descix/workspace.json` (
|
|
214
|
+
CLI verbs, each writing one part of `.descix/workspace.json` (v3 single-app — see `workspace-config.md`). Run them
|
|
215
|
+
from the repo root — it becomes the workspace root:
|
|
215
216
|
|
|
216
217
|
```bash
|
|
217
|
-
descix config init --env
|
|
218
|
+
descix config init --env prod # creates .descix/workspace.json, pins env.apiUrl
|
|
218
219
|
descix login # .descix/wallet.json (add it to .gitignore yourself)
|
|
219
|
-
descix app init -a <name> -c <community>
|
|
220
|
+
descix app init -a <name> -c <community> # env.app + site/ microservice/ assets/ + default KB
|
|
220
221
|
descix app set-site -a <app_id> --static site # what the gateway serves at /p/<app_id>
|
|
221
222
|
descix app set-port -a <app_id> -p 4001 # required before descix microservice init
|
|
222
223
|
```
|
|
223
224
|
|
|
224
225
|
`descix app init` creates `site/`, `microservice/` and `assets/` (with starter
|
|
225
|
-
`system_instructions.md` and `app_description.md`) under the
|
|
226
|
+
`system_instructions.md` and `app_description.md`) under the repo root. Knowledge-base content
|
|
226
227
|
is whatever your corpus manifest names (`.descix/manifests/<KB>.json`); Drive content arrives via
|
|
227
228
|
`descix drive pull -c <community> -a <app_id>` into `kb/<KB>/` and goes back via `descix drive push`.
|
|
228
229
|
The CLI auto-detects the app from the directory you are standing in; `-c`/`-a` flags win over
|
|
@@ -304,13 +305,13 @@ async function copyFolderRecursive(sourceFolderId, destParentId, newName) {
|
|
|
304
305
|
### App Creation
|
|
305
306
|
|
|
306
307
|
```bash
|
|
307
|
-
descix config init --env
|
|
308
|
+
descix config init --env prod # pin the environment first
|
|
308
309
|
descix login # device-code sign-in
|
|
309
|
-
descix app init -a <name> -c <community>
|
|
310
|
+
descix app init -a <name> -c <community> # create on the platform + write env.app + default KB
|
|
310
311
|
```
|
|
311
312
|
|
|
312
313
|
An app created in the PWA is initialized locally with the same verb, minus `-c`:
|
|
313
|
-
`descix app init -a <app_id
|
|
314
|
+
`descix app init -a <app_id>`, from the repo root.
|
|
314
315
|
|
|
315
316
|
### Post-Creation Commands
|
|
316
317
|
|
|
@@ -111,31 +111,28 @@ folder of JSON chunk files to manage.
|
|
|
111
111
|
|
|
112
112
|
```json
|
|
113
113
|
{
|
|
114
|
-
"version": "
|
|
114
|
+
"version": "3.0",
|
|
115
115
|
"type": "workspace",
|
|
116
|
-
"workspaceRoot": "/path/to/
|
|
116
|
+
"workspaceRoot": "/path/to/daita-agent-repo",
|
|
117
117
|
"env": {
|
|
118
|
-
"environment": "
|
|
119
|
-
"apiUrl": "https://
|
|
118
|
+
"environment": "PROD",
|
|
119
|
+
"apiUrl": "https://descix.net",
|
|
120
120
|
"gateway": { "port": 5599 },
|
|
121
|
-
"
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
"microservice": { "port": 4001 }
|
|
129
|
-
}
|
|
130
|
-
]
|
|
121
|
+
"app": {
|
|
122
|
+
"appId": "daita-agent",
|
|
123
|
+
"communityId": "daita",
|
|
124
|
+
"kbId": "General",
|
|
125
|
+
"site": { "port": 3000 },
|
|
126
|
+
"microservice": { "port": 4001 }
|
|
127
|
+
}
|
|
131
128
|
},
|
|
132
129
|
"driveConfig": { "base_folder_id": "1ABC..." }
|
|
133
130
|
}
|
|
134
131
|
```
|
|
135
132
|
|
|
136
|
-
Every key is written by a CLI verb (`descix config init --env …`, `descix app init`, `descix app set-site`, `descix app set-port`, …) — see `workspace-config.md` for the key → verb table. A `communities` block without `env` (the v1 shape)
|
|
133
|
+
Every key is written by a CLI verb (`descix config init --env …`, `descix app init`, `descix app set-site`, `descix app set-port`, …) — see `workspace-config.md` for the key → verb table. One repo holds one app (`env.app`), and the repo root is the workspace root. A `communities` block without `env` (the v1 shape) and an `env.platform` / `env.products` block (the v2.1 multi-app shape) are refused on load.
|
|
137
134
|
|
|
138
|
-
**Note:** `.descix.app/context.json` files are no longer used. All app configuration is stored in `workspace.json`. The CLI auto-detects app
|
|
135
|
+
**Note:** `.descix.app/context.json` files are no longer used. All app configuration is stored in `workspace.json`. The CLI auto-detects the app (`env.app`) when the current working directory is the repo root or below it.
|
|
139
136
|
|
|
140
137
|
---
|
|
141
138
|
|
|
@@ -169,7 +166,7 @@ The DeSciX CLI publishes content with one verb per plane. Each command resolves
|
|
|
169
166
|
|---------|-------------|
|
|
170
167
|
| `descix site init` | Copy site template to current app's `site/` folder |
|
|
171
168
|
| `descix site upload` | Deploy site to GCS |
|
|
172
|
-
| `descix app set-site -a <app_id> --port <port>` | Register the local dev-server port for the app's site (`env.
|
|
169
|
+
| `descix app set-site -a <app_id> --port <port>` | Register the local dev-server port for the app's site (`env.app.site.port`) |
|
|
173
170
|
| `descix microservice init` | Copy microservice template to current app's `microservice/` folder |
|
|
174
171
|
| `descix microservice register -r SERVICE_README.md` | Register microservice AND vectorize the README for `tell_me_how` discovery, in one step |
|
|
175
172
|
|
|
@@ -44,7 +44,7 @@ Instead of exposing implementation details (like GCS bucket URLs or specific por
|
|
|
44
44
|
|
|
45
45
|
**Port:** `--port` → `env.gateway.port` → built-in `5173`, with `strictPort` on. The resolved port and **its source** are printed at startup. Do not assume `:5173`; give a checkout its own with `descix config set-gateway-port <n>`.
|
|
46
46
|
|
|
47
|
-
**It serves ONE app, standalone — the shell opens ON your app instead of the store.** (Standalone is the INITIAL VIEW, not a reduced mode: the platform views stay reachable by navigation.) The app is detected from the directory you are standing in (the
|
|
47
|
+
**It serves ONE app, standalone — the shell opens ON your app instead of the store.** (Standalone is the INITIAL VIEW, not a reduced mode: the platform views stay reachable by navigation.) The app is detected from the directory you are standing in (the app whose repo root contains your cwd — your own repo's `env.app`, or on a gateway workspace the `env.gateway` repo you are inside; longest match wins), or named with `--app <id>`. Nothing is persisted to `workspace.json`. When it cannot name an app it fails loud and lists the workspace's apps rather than falling back to the store.
|
|
48
48
|
|
|
49
49
|
The binding is **served, not compiled**: the gateway answers `GET /__descix/app-binding.json` on the shell's own origin with `{mode:'standalone', appId, appUrl, source}`, and the shell reads it before it mounts. One pre-built cloud shell bundle therefore boots as the store on `descix.net` and as your app locally, with no rebuild. No binding (or a timeout, or a malformed body) means the store — the safe degradation. There is no `__STANDALONE_APP_ID__` build define; an app that builds itself standalone declares it at its own mount, `<AppShell appId="..." standalone>`.
|
|
50
50
|
|
|
@@ -71,10 +71,11 @@ the per-app host; keep `/p/` for the local gateway, where it is the correct and
|
|
|
71
71
|
Typical app-dev session, in full:
|
|
72
72
|
|
|
73
73
|
```bash
|
|
74
|
-
|
|
75
|
-
descix
|
|
76
|
-
descix app
|
|
77
|
-
|
|
74
|
+
cd my-app-repo # the repo root is the workspace root
|
|
75
|
+
descix config init --env prod # pins env.apiUrl
|
|
76
|
+
descix app init -a <app-id> # writes env.app
|
|
77
|
+
descix app set-site -a <app-id> --static site # relative to the repo root
|
|
78
|
+
descix serve
|
|
78
79
|
```
|
|
79
80
|
|
|
80
81
|
### 3.1. Configuration: `.descix/workspace.json`
|
|
@@ -90,39 +91,43 @@ The `workspace.json` file is the **single source of truth** for local routing an
|
|
|
90
91
|
|
|
91
92
|
| Key | Verb |
|
|
92
93
|
|---|---|
|
|
93
|
-
| `env.apiUrl` | `descix config
|
|
94
|
+
| `env.apiUrl` | `descix config init --env dev\|demo\|prod`, or `descix config set-env <custom-name> --url <url>` (`--url` is refused on a known name) |
|
|
94
95
|
| `env.gateway.port` | `descix config set-gateway-port <n\|none>` |
|
|
96
|
+
| `env.gateway.shell` | `descix config gateway set-shell <repo\|none>` (gateway workspaces only) |
|
|
97
|
+
| `env.gateway.appRepos[]` | `descix config gateway add-repo <repo>` / `remove-repo <repo>` (gateway workspaces only) |
|
|
95
98
|
| `env.devCerts` | `descix config set-dev-certs --dir\|--cert\|--key\|--clear` |
|
|
96
99
|
| `env.powchUrl` | `descix config set-powch-url <url\|none>` |
|
|
97
100
|
| `env.siteUrl` | `descix config set-site-url <url\|none>` |
|
|
98
|
-
| `env.
|
|
101
|
+
| `env.app` | `descix app init` / `app set-site` / `app set-port` |
|
|
99
102
|
|
|
100
|
-
#### Format (
|
|
103
|
+
#### Format (v3 — single-app)
|
|
101
104
|
|
|
102
105
|
```json
|
|
103
106
|
{
|
|
104
|
-
"version": "
|
|
107
|
+
"version": "3.0",
|
|
108
|
+
"type": "workspace",
|
|
105
109
|
"env": {
|
|
106
|
-
"environment": "
|
|
107
|
-
"apiUrl": "https://
|
|
110
|
+
"environment": "PROD",
|
|
111
|
+
"apiUrl": "https://descix.net",
|
|
108
112
|
"gateway": { "port": 5599 },
|
|
109
113
|
"devCerts": { "dir": "/Users/you/.descix/dev-certs-san" },
|
|
110
|
-
"
|
|
111
|
-
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
"site": { "
|
|
115
|
-
"microservice": { "port":
|
|
116
|
-
}
|
|
117
|
-
"products": [
|
|
118
|
-
{ "appId": "my-app", "localPath": "my-app", "site": { "static": "." } },
|
|
119
|
-
{ "appId": "other-app", "localPath": "other", "site": { "port": 5599 }, "microservice": { "port": 4001 } }
|
|
120
|
-
]
|
|
114
|
+
"app": {
|
|
115
|
+
"appId": "my-app",
|
|
116
|
+
"communityId": "egpt",
|
|
117
|
+
"kbId": "General",
|
|
118
|
+
"site": { "static": "site" },
|
|
119
|
+
"microservice": { "port": 4001 }
|
|
120
|
+
}
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
-
`env.
|
|
125
|
+
One repo, one app: `env.app` is THE app, and the repo root is the workspace root (`descix app init`
|
|
126
|
+
from the repo root; inside another workspace it refuses). A gateway workspace that serves several
|
|
127
|
+
local app repos lists them as `env.gateway.shell` and `env.gateway.appRepos[]` (paths relative to its
|
|
128
|
+
root), and each listed repo carries its own v3 workspace — see `reference/workspace-config.md`. A
|
|
129
|
+
top-level `apiUrl` key (the v1 shape) and an `env.platform` / `env.products` block (the v2.1
|
|
130
|
+
multi-app shape) fail loud on load, naming the migration.
|
|
126
131
|
|
|
127
132
|
#### KB sync is manifest-driven
|
|
128
133
|
|
|
@@ -164,15 +169,14 @@ the survey outranks the paper for exactly the reader who does not yet know the p
|
|
|
164
169
|
|
|
165
170
|
| Target | 1. flag / env | 2. workspace | 3. global | 4. default |
|
|
166
171
|
|---|---|---|---|---|
|
|
167
|
-
| **API** | `--api-url` / `--env` / `DESCIX_API_URL` | `env.apiUrl
|
|
168
|
-
| **Shell** (`/`) | `--site-url` | `env.siteUrl` | **the API origin, when the API is remote** | `env.
|
|
172
|
+
| **API** | `--api-url` / `--env` / `DESCIX_API_URL` | `env.apiUrl` | `~/.descix/config.json` `api_url` | **the declared default: PROD** |
|
|
173
|
+
| **Shell** (`/`) | `--site-url` | `env.siteUrl` | **the API origin, when the API is remote** | the `env.gateway.shell` repo's own `site.port`, else fail loud |
|
|
169
174
|
|
|
170
|
-
**There is no port-derived step for the API.** An environment NAME never becomes an origin
|
|
171
|
-
|
|
172
|
-
|
|
175
|
+
**There is no port-derived step for the API.** An environment NAME never becomes an origin: a
|
|
176
|
+
local backend is a URL you name — per run with `descix --api-url https://localhost:4000 <command>`,
|
|
177
|
+
or persistently under a custom name with `descix config set-env local --url https://localhost:4000`. **This is
|
|
173
178
|
platform-dev mode** — running your own local backend (Scenario 2 below), not part of standard app
|
|
174
|
-
development, which targets a hosted environment (`descix config
|
|
175
|
-
`demo`/`prod`). The single owner of this order is `lib/origin.js::PRECEDENCE`; this table is a
|
|
179
|
+
development, which targets a hosted environment (`descix config init --env dev|demo|prod`). The single owner of this order is `lib/origin.js::PRECEDENCE`; this table is a
|
|
176
180
|
description of it, not a second copy of the rule.
|
|
177
181
|
|
|
178
182
|
**Every resolution carries its SOURCE, and every network-bound command prints it on stderr** —
|
|
@@ -187,7 +191,7 @@ An unconfigured workspace resolving to PROD is the shipped product's declared ta
|
|
|
187
191
|
fallback; what makes it legitimate is that it is announced. A configured-but-unusable origin is
|
|
188
192
|
a different case and FAILS LOUD naming the remedy, rather than quietly becoming the default.
|
|
189
193
|
|
|
190
|
-
The derived Shell rule is the important one: point the API at a cloud environment and the shell comes from that same origin, so one origin carries shell + app + `/apifront` with nothing else configured. A
|
|
194
|
+
The derived Shell rule is the important one: point the API at a cloud environment and the shell comes from that same origin, so one origin carries shell + app + `/apifront` with nothing else configured. A local shell repo listed in `env.gateway.shell` does not hijack the root once the API is remote. Platform developers opt IN to a local shell by naming it (`--site-url https://localhost:5174` or `env.siteUrl`).
|
|
191
195
|
|
|
192
196
|
### 3.3. The dev certificate and passkey sign-in
|
|
193
197
|
|
|
@@ -233,7 +237,7 @@ human it is unverified.
|
|
|
233
237
|
|
|
234
238
|
### Scenario 1: App Dev (the common case)
|
|
235
239
|
* **User**: App developer. No platform checkout.
|
|
236
|
-
* **Setup**: `descix config
|
|
240
|
+
* **Setup**: from the app repo's root, `descix config init --env prod`, `descix app init`, `descix app set-site`, `descix dev-certs check` (if not trusted, the human runs `descix dev-certs trust` once — §3.3), then `descix serve`.
|
|
237
241
|
* **Result**: one HTTPS origin. `/` → the cloud App Shell, `/apifront` → the cloud API, `/p/my-app` → your app, and the shell boots **standalone into your app** — its INITIAL VIEW is your app rather than the store, with the platform views still reachable from there.
|
|
238
242
|
|
|
239
243
|
### Scenario 2: Platform Dev ("Dogfooding")
|