@descix/cli 1.0.0 → 1.0.3

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.
Files changed (103) hide show
  1. package/LICENSE.md +671 -0
  2. package/README.md +43 -4
  3. package/agent-assets/guides/README.md +2 -2
  4. package/agent-assets/guides/dynamic-site-pattern.md +29 -14
  5. package/agent-assets/guides/knowledge-only-pattern.md +5 -5
  6. package/agent-assets/guides/microservice-pattern.md +48 -4
  7. package/agent-assets/guides/static-site-pattern.md +8 -0
  8. package/agent-assets/instructions/app-asset-validation.md +5 -5
  9. package/agent-assets/instructions/onboarding-flow.md +4 -4
  10. package/agent-assets/instructions/standard-folder-structure.md +20 -11
  11. package/agent-assets/reference/app-creation.md +42 -20
  12. package/agent-assets/reference/architecture.md +24 -22
  13. package/agent-assets/reference/local-dev.md +230 -67
  14. package/agent-assets/reference/mcp-integration.md +9 -9
  15. package/agent-assets/reference/platform-api-consumer.md +244 -0
  16. package/agent-assets/reference/workspace-config.md +7 -7
  17. package/agent-assets/rules/descix_mcp.template.mdc +8 -8
  18. package/bin/descix.js +2559 -1435
  19. package/bin/kb-deny-lint.mjs +91 -0
  20. package/bin/mcp-server.js +175 -91
  21. package/lib/agent-files.js +37 -25
  22. package/lib/api-client.js +223 -56
  23. package/lib/auth-guard.js +13 -3
  24. package/lib/chat-session.js +187 -0
  25. package/lib/cli-version.js +59 -0
  26. package/lib/commands/airdrop.js +251 -0
  27. package/lib/commands/auth.js +254 -72
  28. package/lib/commands/briefer/errors.js +88 -0
  29. package/lib/commands/briefer/index.js +319 -0
  30. package/lib/commands/briefer/sources/canonical-sources.js +129 -0
  31. package/lib/commands/briefer/sources/entitlements.js +209 -0
  32. package/lib/commands/briefer/sources/environments.js +205 -0
  33. package/lib/commands/briefer/sources/identifiers.js +214 -0
  34. package/lib/commands/briefer/sources/microservice-deploy.js +267 -0
  35. package/lib/commands/briefer/sources/routing.js +275 -0
  36. package/lib/commands/briefer/sources/what-is-not.js +223 -0
  37. package/lib/commands/briefer/stitcher.js +134 -0
  38. package/lib/commands/briefer/util/source-reader.js +502 -0
  39. package/lib/commands/config.js +210 -90
  40. package/lib/commands/corpus.js +978 -0
  41. package/lib/commands/credits.js +122 -0
  42. package/lib/commands/health.js +627 -0
  43. package/lib/commands/kb-list-render.js +32 -0
  44. package/lib/commands/kb.js +190 -413
  45. package/lib/commands/mcp.js +5 -5
  46. package/lib/commands/microservice-restart.js +359 -0
  47. package/lib/commands/model-config.js +313 -0
  48. package/lib/commands/retired-kb-sync.js +134 -0
  49. package/lib/commands/serve.js +26 -1
  50. package/lib/commands/status.js +23 -51
  51. package/lib/commands/update.js +36 -107
  52. package/lib/core/Chunker.js +491 -17
  53. package/lib/core/CorpusDenyLint.js +326 -0
  54. package/lib/core/CorpusWalker.js +357 -0
  55. package/lib/core/Hydrator.js +75 -29
  56. package/lib/core/ManifestLoader.js +533 -0
  57. package/lib/core/SiteWalker.js +218 -0
  58. package/lib/core/Syncer.js +163 -11
  59. package/lib/diagnostic-log.js +41 -0
  60. package/lib/environment-report.js +100 -0
  61. package/lib/global-config.js +4 -1
  62. package/lib/oauth-client.js +164 -0
  63. package/lib/origin.js +143 -0
  64. package/lib/service-api-client.js +95 -0
  65. package/lib/wallet-environment.js +49 -0
  66. package/lib/wallet-file.js +16 -2
  67. package/lib/wizard/setup.js +10 -9
  68. package/lib/workspace-config.js +380 -235
  69. package/lib/workspace-identity.js +92 -0
  70. package/lib/workspace-utils.js +41 -61
  71. package/package.json +29 -9
  72. package/templates/agent-claude.md +157 -9
  73. package/templates/agent-cline.md +68 -8
  74. package/templates/agent-copilot.md +68 -8
  75. package/templates/agent-cursor.md +68 -8
  76. package/templates/alignment-schema.json +20 -0
  77. package/templates/cloud-brain-hook.sh +20 -0
  78. package/templates/drive/README.md +1 -1
  79. package/templates/drive_templates/README.md +2 -2
  80. package/templates/scaffolds/README.md +6 -10
  81. package/templates/scaffolds/microservice/SERVICE_README_sdk.md +30 -0
  82. package/templates/scaffolds/microservice/app.js +51 -10
  83. package/templates/scaffolds/microservice/app.yaml +2 -2
  84. package/templates/scaffolds/microservice/defaults-config-dev.json +4 -0
  85. package/templates/scaffolds/microservice/dev-overrides.example.json +5 -0
  86. package/templates/scaffolds/microservice/manifest.json +0 -1
  87. package/templates/scaffolds/microservice/package.json +3 -3
  88. package/templates/scaffolds/microservice/scripts/register.js +56 -41
  89. package/templates/scaffolds/microservice/services/mcpClient.js +55 -65
  90. package/templates/scaffolds/microservice/services/utils.js +20 -238
  91. package/templates/scaffolds/microservice/templates/SERVICE_README_TEMPLATE.md +24 -0
  92. package/SERVICE_README_sdk.md +0 -399
  93. package/descix-cli-1.0.0.tgz +0 -0
  94. package/lib/commands/app-wizard.js +0 -627
  95. package/lib/commands/folder.js +0 -291
  96. package/lib/core/PathContext.js +0 -335
  97. package/templates/scaffolds/microservice/dev-overrides.json.example +0 -5
  98. package/templates/scaffolds/site/DeSciXAppSDK.js +0 -62
  99. package/templates/scaffolds/site/README.md +0 -51
  100. package/templates/scaffolds/site/app.js +0 -22
  101. package/templates/scaffolds/site/index.html +0 -42
  102. package/templates/scaffolds/site/styles.css +0 -123
  103. package/test-hydration.js +0 -150
@@ -0,0 +1,244 @@
1
+ # Calling the Platform API: what trips people up
2
+
3
+ The platform surface is broadly self-describing — unknown parameters are refused with the
4
+ accepted list, so a wrong guess costs one round trip rather than a silent wrong answer. What
5
+ follows is the set of things that are **not** guessable, each measured against the live platform
6
+ rather than read off a design doc.
7
+
8
+ ---
9
+
10
+ ## 1. The same concept has three parameter names
11
+
12
+ There is one idea — "which knowledge base" — and three spellings of it, depending on which command
13
+ you are calling. This is the single most common round-trip tax on the surface, and three separate
14
+ seats hit it independently in one day.
15
+
16
+ | Command family | Names the KB as | Notes |
17
+ |---|---|---|
18
+ | `app_records_put` / `_get` / `_query` / `_delete` | `kb_id` | The records surface calls it a *record collection*; it behaves like a table name. |
19
+ | `query_knowledge_base` | `kb_id`, or `kb_ids` for several | Retrieval — raw chunks. |
20
+ | `ask_question_to_app` | `knowledgebase_name`, or `knowledgebase_names` | Answering — synthesized and cited. **`kb_id` is rejected here**, not ignored. |
21
+
22
+ The rejection is deliberate and helpful: it names the parameter you should have used. It is still
23
+ a round trip, so check the table first.
24
+
25
+ ```
26
+ ask_question_to_app: unknown parameter 'kb_id' (did you mean 'knowledgebase_name'?).
27
+ Accepted parameters: app_id, knowledgebase_name, knowledgebase_names, user_input, ...
28
+ Rejected at the execute_remote_command gateway boundary — the parameter was NOT
29
+ applied, and no default was substituted.
30
+ ```
31
+
32
+ Note what that error gives you: the correction (`did you mean`), the full accepted set, and an
33
+ explicit statement that **nothing was written and no default was substituted**. You can act on it
34
+ without guessing what half-happened.
35
+
36
+ **A tool's handshake schema is not the whole surface.** The MCP handshake schema advertised for
37
+ `ask_question_to_app` currently omits the `media` parameter — while the platform accepts and bills
38
+ it. A consumer reading only that schema would conclude multimodal is unsupported, and be wrong.
39
+ The parameter is documented by `tell_me_how` with `scope: "discovery"`, and reaching it through
40
+ `execute_remote_command` works today.
41
+
42
+ The general lesson, since this cuts both ways: **an advertised parameter can be refused, and a
43
+ working one can go unadvertised.** Where a capability matters, probe it rather than inferring it
44
+ from the tool list.
45
+
46
+ **Unknown parameters are refused everywhere, with the accepted set in the error.** That is the
47
+ surface's most useful property: you can probe it. It also means a parameter you read about
48
+ somewhere but that the schema does not declare will fail loudly rather than be silently dropped —
49
+ so trust the error, not the prose.
50
+
51
+ ---
52
+
53
+ ## 2. Sending images and video
54
+
55
+ `ask_question_to_app` takes a `media` array — images and video for the model to **look at** on
56
+ this turn. Each entry supplies **exactly one** of `data` (raw base64, no `data:` URL prefix) or
57
+ `asset_ref` (an object in *this app's* own GCS asset space). Declaring both is refused: which one
58
+ did you mean?
59
+
60
+ ```jsonc
61
+ {
62
+ "app_id": "my-app",
63
+ "user_input": "What colour sequence does this show?",
64
+ "media": [
65
+ { "mime_type": "video/mp4", "asset_ref": "probe.mp4", "label": "probe clip" }
66
+ ]
67
+ }
68
+ ```
69
+
70
+ **Accepted today:** images (`png`, `jpeg`, `webp`, `heic`, `heif`, `gif`, `bmp`, `tiff`) and video
71
+ (`mp4`, `mpeg`, `mpg`, `mov`, `avi`, `x-flv`, `webm`, `wmv`, `3gpp`).
72
+
73
+ **Audio and PDF are refused on purpose, not by oversight.** The provider accepts them with a
74
+ structurally identical shape, but they have not been live-measured on this surface, and the
75
+ platform does not ship capabilities it has not observed working. The refusal names them
76
+ explicitly so you can tell a scope boundary from a typo.
77
+
78
+ **`asset_ref` is APP-SCOPED, and getting this wrong produces an error that reads like a broken
79
+ platform.** A reference must resolve inside *this* app's own assets prefix
80
+ (`gs://descix-assets-public/{env}/{appId}/assets/`). Two different failures, and telling them
81
+ apart saves an hour:
82
+
83
+ ```
84
+ # ref points outside the app's prefix
85
+ Asset reference '...' RESOLVES OUTSIDE app 'egpt-godsworld' assets prefix 'dev/egpt-godsworld/assets/'.
86
+
87
+ # ref is inside the prefix, but the object is not there
88
+ ASSET NOT FOUND at gs://... Upload it first with `descix app media-upload`.
89
+ ```
90
+
91
+ Both come back as `MEDIA_ASSET_UNREADABLE`. The first means you referenced the wrong app's asset;
92
+ the second means you have not uploaded yet. Upload into the app that will do the asking.
93
+
94
+ **The upload verb hands you both forms, and both work.** `descix app media-upload` returns a
95
+ `path` (relative to the app's assets prefix) and a `ref` (the `gs://` URI) for every file, plus a
96
+ `public_url`; `--json` prints them for scripting. Either `path` or `ref` is a valid `asset_ref` —
97
+ so if a rule in your head says the tool's own `ref` field is unusable, the rule is wrong, not the
98
+ tool.
99
+
100
+ **The `gs://` form is accepted.** A `gs://` URI works as an `asset_ref` — it is parsed and
101
+ scope-checked, and the handler then looks the object up by path. What is PROVEN is the form and
102
+ the scoping: two different `gs://` strings return two different errors (out-of-prefix vs
103
+ not-found), which is only possible if the URI was accepted, parsed and scope-checked first.
104
+ What is NOT proven is the last hop — nobody has yet demonstrated a successful fetch of a REAL
105
+ object through `asset_ref`, so treat resolution-to-bytes as the documented intent rather than a
106
+ measured result. That is worth stating plainly because the opposite rule circulates:
107
+ `gs://` is fatal as a *provider* URI (the provider refuses GCS references outright) and correct as
108
+ a *DeSciX-side* `asset_ref`. Those are two different layers, and collapsing them into "never
109
+ `gs://`" removes the very mechanism that makes `asset_ref` work — the platform resolves the
110
+ reference to bytes server-side precisely because the provider will not take the URI.
111
+
112
+ **The server is the single validation authority.** The client stages a contribution; every rule
113
+ above — accepted MIME types, size limits, `data` XOR `asset_ref`, asset resolution — is enforced
114
+ server-side. None of it lives in the browser bundle, and that is deliberate rather than a gap: the
115
+ package that owns the contract depends on `googleapis` and must never be pulled into a browser
116
+ build. If you go looking in the shipped client for `mime_type` or `asset_ref` you will not find
117
+ them, and finding nothing there is the correct result, not evidence of a missing check.
118
+
119
+ **Limits:** 8 attachments per turn, 8 MiB each, 16 MiB per turn. Oversized media is **rejected,
120
+ not truncated** — you will know. Media tokens bill as input tokens.
121
+
122
+ **Do not resend media on follow-up turns.** It persists in the conversation thread: continue with
123
+ `previous_interaction_id` and the model still has it. Resending costs you the tokens twice.
124
+
125
+ **`asset_ref` resolves server-side, and that is the whole point.** A `gs://` URI is a DeSciX-side
126
+ reference, never a provider one — the provider rejects GCS URIs outright, so the platform reads
127
+ the bytes for you. Upload with `descix app media-upload` (or `get_asset_upload_token`). If the
128
+ object is not there you get an error that names the exact path it looked at:
129
+
130
+ ```
131
+ [chatMedia] could not read media asset "probe.mp4" for app "my-app":
132
+ Asset not found at gs://descix-assets-public/dev/my-app/assets/probe.mp4.
133
+ Upload it first with `descix app media-upload`.
134
+ ```
135
+
136
+ ## 3. Writes merge per FIELD, so send only the keys you own
137
+
138
+ `app_records_put` in its default `upsert` mode is a **field-level merge**, not a record
139
+ replacement. A put carrying `{file_id, status}` changes `status` and leaves every other field on
140
+ that record intact.
141
+
142
+ This matters most for the common case of transitioning someone else's record — marking a message
143
+ read, setting a disposition, updating a lease:
144
+
145
+ ```jsonc
146
+ // Correct: touches one field, preserves the sender's text, timestamps, and everything else
147
+ { "file_id": "msg-...", "status": "read" }
148
+
149
+ // Unnecessary, and destructive if you reconstruct the record imperfectly:
150
+ // re-putting the WHOLE record just to change one field
151
+ ```
152
+
153
+ **Send only the keys you own.** Defensively re-putting a whole record is how a reader overwrites
154
+ an author's content with its own reconstruction of it.
155
+
156
+ **`app_records_query` operators, and what each kind of mistake now does.** The operator
157
+ vocabulary has one owner (`@descix/platform-api/mcp-tools` `SUPPORTED_FILTER_OPERATORS`) and the
158
+ tool description is generated from it — so the tool's own text is authoritative, not this table.
159
+
160
+ | Operator | Use it on | Example |
161
+ |---|---|---|
162
+ | `$eq` (or a bare value) / `$ne` / `$in` | a **scalar** field | `{ "type": "message" }`, `{ "status": { "$in": ["unread","read"] } }` |
163
+ | `$contains` | an **array** field (membership) | `{ "tags": { "$contains": "handoff" } }` |
164
+
165
+ Every mistake now FAILS LOUD rather than answering:
166
+
167
+ | What you pass | What happens |
168
+ |---|---|
169
+ | an unsupported operator (`$gt`, `$exists`, …) | **refused** `INVALID_PARAMS`, naming the operator and the accepted list. Range and existence predicates are not implemented — filter client-side. |
170
+ | a scalar operator on an **array** field (`{"tags":"handoff"}`) | **refused** `FILTER_UNSUPPORTED`, naming the field and telling you to use `$contains` |
171
+ | `$contains` on a **scalar** field | **refused** `FILTER_UNSUPPORTED`, naming `$eq` as the remedy |
172
+ | an unknown FIELD key | 0 rows — but the receipt says so unambiguously: `matched: 0` with `scanned: 40` means YOUR PREDICATE matched nothing, while `matched: 0` with `scanned: 0` means the collection is empty |
173
+
174
+ Read the receipt, not just `records`: `count <= matched <= scanned`, and `truncated` is true
175
+ exactly when `limit` cut the match set.
176
+
177
+ **A record's `status` tells you what the last writer wrote, not what anyone has read.** If you
178
+ send a record with `status: "unread"`, that value is *your own default* — it is evidence of
179
+ nothing about delivery or attention. The positive signal is the flip to `read`, which only the
180
+ recipient performs. If you need to know a message landed, look for that flip, or for the
181
+ recipient's own subsequent record referring to it. Absence of a flip is not absence of a reader,
182
+ and presence of `unread` is not proof anyone was told.
183
+
184
+ `mode: "create"` is different by design — an atomic first-claim-wins conditional create that
185
+ refuses rather than overwriting, for electing a single holder of a named resource (a lease, a
186
+ seat, an idempotency key).
187
+
188
+ ---
189
+
190
+ ## 4. Scoping a search to one document
191
+
192
+ `query_knowledge_base` takes `file_filter` to restrict a search to a single source.
193
+
194
+ **It takes the retrievable file id, not the human-readable file name.** The id is opaque and
195
+ looks like `corpus:ce66a173…`. You do not have to construct it: every result row carries it as
196
+ `file_path`, and every citation returns a ready-made `read_command` containing the correct
197
+ `file_filter`. **Copy the id the citation gave you** — never type the filename.
198
+
199
+ ```jsonc
200
+ { "app_id": "unk-beast", "kb_id": "DevX-Evangelist",
201
+ "query": "intake and triage", "file_filter": "corpus:ce66a173…" }
202
+ ```
203
+
204
+ Passing the display `file_name` instead returns empty or 404s, and the platform warns about
205
+ exactly this mistake in its own retrieval notes. If a scoped search comes back empty, check that
206
+ first before concluding the document is missing.
207
+
208
+ ## 5. Retrieval is vocabulary-sensitive, and fails quietly
209
+
210
+ Covered in depth in [local-dev.md](./local-dev.md) under KB sync, because it is as much a curation
211
+ concern as a calling one. The short version for callers: phrase queries in the source's own
212
+ vocabulary, pull `limit >= 3`, and **check `fileName`** — a confident, well-scored answer is not
213
+ evidence that the right document was retrieved.
214
+
215
+ ---
216
+
217
+ ## How the claims on this page were verified
218
+
219
+ Every statement here was executed against the live platform. Two techniques did most of the work
220
+ and are worth stealing:
221
+
222
+ **Send a deliberately wrong value and read which layer complains.** When you cannot test a
223
+ parameter properly — no fixture, no real asset — you can still find out whether it exists. Passing
224
+ a nonsense `asset_ref` returned `MEDIA_ASSET_UNREADABLE` naming the exact path it looked at: the
225
+ parameter was *accepted* and the handler *ran*. An undeclared parameter fails completely
226
+ differently, with `unknown parameter` and the accepted set. The two errors come from different
227
+ layers, and which layer answers is the measurement.
228
+
229
+ **Check the artifact that actually executes, not the one you changed.** A fix can be merged and
230
+ still unreachable; today one sat on the main branch for roughly five hours before a deploy carried
231
+ it. Code present in a shipped bundle proves it shipped, not that it works. So the order that holds
232
+ is: merged → deployed → shipped → working, and each arrow is a real gap somebody has to cross.
233
+
234
+ ## Scope of this page
235
+
236
+ Every claim above was executed against the live platform, not inferred from source or design
237
+ documents — including the two newest sections, whose behaviour was merged for hours before it was
238
+ actually reachable. Behaviour that is implemented but **not yet reachable on the deployed
239
+ surface** stays out of this page: documenting a call the platform currently refuses would hand you
240
+ an instruction that errors, which is the defect this page exists to avoid.
241
+
242
+ One consequence worth knowing as a reader: **a merge is not a deploy.** If something here does
243
+ not work for you, it is worth checking whether your environment has taken the deploy that carries
244
+ it, before concluding the doc is wrong.
@@ -193,10 +193,10 @@ DeSciX supports two sync modes, determined by how the app is managed:
193
193
 
194
194
  **Workflow:**
195
195
  1. User creates/edits documents in Google Drive
196
- 2. User runs `descix kb pull` to get text-converted content
196
+ 2. User runs `descix drive pull` to get text-converted content
197
197
  3. User edits text files locally (Git version control)
198
- 4. User runs `descix kb chunk` to generate chunks
199
- 5. User runs `descix kb sync` to push chunks to Pinecone
198
+ 4. User runs `descix kb corpus sync` to generate chunks
199
+ 5. User runs `descix kb corpus sync` to push chunks to Pinecone
200
200
  6. User commits changes to Git
201
201
 
202
202
  **When to Use:**
@@ -311,7 +311,7 @@ async function verifyDriveAuth() {
311
311
  |-------|-------|----------|
312
312
  | "Could not load default credentials" | ADC not configured | Run `gcloud auth application-default login` |
313
313
  | "Drive authentication failed" | Scopes missing | Re-run with Drive scopes |
314
- | "base_folder_id missing" | Not setup | Run `descix setup` |
314
+ | "base_folder_id missing" | Not setup | Run `descix mcp quickstart` |
315
315
 
316
316
  ---
317
317
 
@@ -395,11 +395,11 @@ resolveContextWithOptions(options = {}) {
395
395
  ```bash
396
396
  # From within an app directory - auto-detects community/app
397
397
  cd descix/appsdk
398
- descix kb build # Works without -c/-a flags
398
+ descix kb corpus sync # Works without -c/-a flags
399
399
 
400
400
  # From workspace root - requires flags
401
401
  cd /workspace
402
- descix kb build -c descix -a appsdk
402
+ descix kb corpus sync -c descix -a appsdk
403
403
  ```
404
404
 
405
405
  ---
@@ -411,5 +411,5 @@ descix kb build -c descix -a appsdk
411
411
  | WorkspaceConfig | `DeSciX_Core/descix-cli/lib/workspace-config.js` | Sole configuration class for CLI |
412
412
  | GlobalConfig | `DeSciX_Core/descix-cli/lib/global-config.js` | User-level settings (~/.descix) |
413
413
  | Workspace Utils | `DeSciX_Core/descix-cli/lib/workspace-utils.js` | Helper utilities |
414
- | Setup Command | `DeSciX_Core/descix-cli/lib/commands/setup.js` | Initial workspace setup |
414
+ | Setup Command | `DeSciX_Core/descix-cli/lib/wizard/setup.js` | Initial workspace setup |
415
415
  | Config Commands | `DeSciX_Core/descix-cli/lib/commands/config.js` | Configuration management |
@@ -36,7 +36,7 @@ my-app/
36
36
 
37
37
  **IMPORTANT**: Check `.descix/workspace.json` for `_needsAgentSetup: true`.
38
38
 
39
- When this flag is set, the user has just completed `descix setup` and needs your help configuring their workspace:
39
+ When this flag is set, the user has just completed `descix mcp quickstart` and needs your help configuring their workspace:
40
40
 
41
41
  1. **Greet the user** and confirm MCP is working: "I can see your DeSciX setup is complete. Let me help you configure your workspace."
42
42
  2. **Show their entitlements** from the cached JSON below (communities and apps they own)
@@ -169,12 +169,12 @@ Guide users to these git-mode commands:
169
169
  ### Knowledge Base Commands
170
170
  | Command | Purpose |
171
171
  |---------|---------|
172
- | `descix kb pull` | Pull text-converted content from Drive |
173
- | `descix kb push` | Push staging files to Drive |
174
- | `descix kb chunk` | Generate JSON chunks from text files |
175
- | `descix kb sync` | Push chunks to Pinecone |
176
- | `descix kb build` | Full pipeline: pull → chunk → sync |
177
- | `descix kb status` | Show local vs Pinecone sync status |
172
+ | `descix drive pull` | Pull text-converted content from Drive |
173
+ | `descix drive push` | Push staging files to Drive |
174
+ | `descix kb corpus sync` | Generate JSON chunks from text files |
175
+ | `descix kb corpus sync` | Push chunks to Pinecone |
176
+ | `descix kb corpus sync` | Full pipeline: pull → chunk → sync |
177
+ | `descix kb corpus status` | Show local vs Pinecone sync status |
178
178
 
179
179
  ### Site Commands
180
180
  | Command | Purpose |
@@ -234,7 +234,7 @@ If commands fail:
234
234
  | "Workspace not configured" | No workspace.json | Run `descix init` |
235
235
  | "Could not determine app context" | Not in app directory | `cd` to app or use `-c/-a` flags |
236
236
  | "ADC not configured" | Missing Google auth | Run `gcloud auth application-default login` |
237
- | "App not found in workspace" | App not registered | Run `descix setup` or add to workspace.json |
237
+ | "App not found in workspace" | App not registered | Run `descix mcp quickstart` or add to workspace.json |
238
238
 
239
239
  ---
240
240