@descix/cli 1.0.6 → 1.0.8

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 (59) hide show
  1. package/README.md +1 -1
  2. package/agent-assets/guides/README.md +1 -1
  3. package/agent-assets/guides/dynamic-site-pattern.md +17 -30
  4. package/agent-assets/guides/knowledge-only-pattern.md +11 -15
  5. package/agent-assets/guides/microservice-pattern.md +12 -14
  6. package/agent-assets/guides/static-site-pattern.md +12 -15
  7. package/agent-assets/instructions/app-asset-validation.md +1 -1
  8. package/agent-assets/instructions/onboarding-flow.md +4 -4
  9. package/agent-assets/reference/app-creation.md +36 -101
  10. package/agent-assets/reference/architecture.md +43 -51
  11. package/agent-assets/reference/local-dev.md +1 -6
  12. package/agent-assets/reference/mcp-integration.md +21 -23
  13. package/agent-assets/reference/workspace-config.md +97 -340
  14. package/bin/descix.js +337 -618
  15. package/lib/api-client.js +30 -22
  16. package/lib/command-visibility.js +213 -0
  17. package/lib/commands/airdrop.js +10 -0
  18. package/lib/commands/auth.js +16 -2
  19. package/lib/commands/config.js +13 -31
  20. package/lib/commands/corpus.js +163 -59
  21. package/lib/commands/health.js +116 -21
  22. package/lib/commands/init.js +17 -45
  23. package/lib/commands/kb.js +7 -0
  24. package/lib/commands/retired-kb-sync.js +5 -27
  25. package/lib/commands/status.js +0 -9
  26. package/lib/core/Chunker.js +1 -1
  27. package/lib/core/CorpusWalker.js +238 -47
  28. package/lib/core/ManifestLoader.js +68 -0
  29. package/lib/core/Syncer.js +147 -46
  30. package/lib/interactive.js +158 -0
  31. package/lib/origin.js +3 -3
  32. package/lib/sdk-assets.js +28 -0
  33. package/lib/verb-invokes.generated.json +233 -0
  34. package/lib/wallet-file.js +36 -37
  35. package/lib/workspace-config.js +266 -199
  36. package/lib/workspace-identity.js +0 -1
  37. package/package.json +7 -3
  38. package/templates/agent-claude.md +1 -3
  39. package/templates/agent-cline.md +1 -2
  40. package/templates/agent-copilot.md +1 -2
  41. package/templates/agent-cursor.md +1 -2
  42. package/templates/scaffolds/microservice/SERVICE_README_sdk.md +1 -1
  43. package/templates/scaffolds/microservice/templates/SERVICE_README_TEMPLATE.md +2 -3
  44. package/agent-assets/rules/descix_mcp.template.mdc +0 -243
  45. package/lib/commands/briefer/errors.js +0 -88
  46. package/lib/commands/briefer/index.js +0 -319
  47. package/lib/commands/briefer/sources/canonical-sources.js +0 -129
  48. package/lib/commands/briefer/sources/entitlements.js +0 -220
  49. package/lib/commands/briefer/sources/environments.js +0 -205
  50. package/lib/commands/briefer/sources/identifiers.js +0 -214
  51. package/lib/commands/briefer/sources/microservice-deploy.js +0 -267
  52. package/lib/commands/briefer/sources/routing.js +0 -275
  53. package/lib/commands/briefer/sources/what-is-not.js +0 -223
  54. package/lib/commands/briefer/stitcher.js +0 -134
  55. package/lib/commands/briefer/util/source-reader.js +0 -502
  56. package/lib/commands/mcp.js +0 -273
  57. package/lib/commands/update.js +0 -581
  58. package/lib/wizard/setup.js +0 -503
  59. package/templates/descix_mcp.mdc +0 -122
@@ -159,7 +159,7 @@ To see your app in a browser:
159
159
  | Goal | Command |
160
160
  |------|---------|
161
161
  | Serve `site/` locally | `npx serve site/` or `python3 -m http.server -d site/` on any port |
162
- | Register port with DeSciX | `descix site servelocal <port> -c <community> -a <app>` |
162
+ | Register a framework dev-server port with DeSciX | `descix app set-site -a <app> --port <port>` (writes `env.products[].site.port`) |
163
163
  | Run your app on the DeSciX gateway | `cd <app dir> && descix serve` — one HTTPS origin, the shell opens ON your app (**standalone** = initial view, not a reduced mode — platform views stay reachable) |
164
164
 
165
165
  A plain static server is enough to look at your HTML. `descix serve` is what you
@@ -257,8 +257,6 @@ Every app has three parts:
257
257
 
258
258
  - `descix status` may report "No workspace found" even when `.descix/workspace.json`
259
259
  exists. This is a known bug — continue with explicit flags.
260
- - `descix status` may suggest `descix setup` — that command doesn't exist. Use
261
- `descix init -c <community> -a <app> -p .` instead.
262
260
 
263
261
  ## Cloud Brain Alignment
264
262
 
@@ -121,7 +121,7 @@ descix kb corpus status -c <community> -a <app>
121
121
  | Goal | Command |
122
122
  |------|---------|
123
123
  | Serve `site/` locally | `npx serve site/` or `python3 -m http.server -d site/` on any port |
124
- | Register port with DeSciX | `descix site servelocal <port> -c <community> -a <app>` |
124
+ | Register a framework dev-server port with DeSciX | `descix app set-site -a <app> --port <port>` (writes `env.products[].site.port`) |
125
125
  | Run your app on the DeSciX gateway | `cd <app dir> && descix serve` — one HTTPS origin, the shell opens ON your app (**standalone** = initial view, not a reduced mode — platform views stay reachable) |
126
126
 
127
127
  A plain static server is enough to look at your HTML. `descix serve` is what you
@@ -171,7 +171,6 @@ gateway does not rewrite paths.
171
171
  ## Known CLI Quirks
172
172
 
173
173
  - `descix status` may show "No workspace found" even when config exists — use explicit flags
174
- - `descix status` may suggest `descix setup` — use `descix init` instead
175
174
 
176
175
  ## Cloud Brain Alignment
177
176
 
@@ -121,7 +121,7 @@ descix kb corpus status -c <community> -a <app>
121
121
  | Goal | Command |
122
122
  |------|---------|
123
123
  | Serve `site/` locally | `npx serve site/` or `python3 -m http.server -d site/` on any port |
124
- | Register port with DeSciX | `descix site servelocal <port> -c <community> -a <app>` |
124
+ | Register a framework dev-server port with DeSciX | `descix app set-site -a <app> --port <port>` (writes `env.products[].site.port`) |
125
125
  | Run your app on the DeSciX gateway | `cd <app dir> && descix serve` — one HTTPS origin, the shell opens ON your app (**standalone** = initial view, not a reduced mode — platform views stay reachable) |
126
126
 
127
127
  A plain static server is enough to look at your HTML. `descix serve` is what you
@@ -171,7 +171,6 @@ gateway does not rewrite paths.
171
171
  ## Known CLI Quirks
172
172
 
173
173
  - `descix status` may show "No workspace found" even when config exists — use explicit flags
174
- - `descix status` may suggest `descix setup` — use `descix init` instead
175
174
 
176
175
  ## Cloud Brain Alignment
177
176
 
@@ -121,7 +121,7 @@ descix kb corpus status -c <community> -a <app>
121
121
  | Goal | Command |
122
122
  |------|---------|
123
123
  | Serve `site/` locally | `npx serve site/` or `python3 -m http.server -d site/` on any port |
124
- | Register port with DeSciX | `descix site servelocal <port> -c <community> -a <app>` |
124
+ | Register a framework dev-server port with DeSciX | `descix app set-site -a <app> --port <port>` (writes `env.products[].site.port`) |
125
125
  | Run your app on the DeSciX gateway | `cd <app dir> && descix serve` — one HTTPS origin, the shell opens ON your app (**standalone** = initial view, not a reduced mode — platform views stay reachable) |
126
126
 
127
127
  A plain static server is enough to look at your HTML. `descix serve` is what you
@@ -171,7 +171,6 @@ gateway does not rewrite paths.
171
171
  ## Known CLI Quirks
172
172
 
173
173
  - `descix status` may show "No workspace found" even when config exists — use explicit flags
174
- - `descix status` may suggest `descix setup` — use `descix init` instead
175
174
 
176
175
  ## Cloud Brain Alignment
177
176
 
@@ -112,7 +112,7 @@ descix tell-me-how --scope discovery "What AI training tools exist?"
112
112
  ### descix app init
113
113
 
114
114
  **Description:** Create (if needed) and initialize an app: platform record + default KB + local workspace registration and scaffold. Idempotent.
115
- **Use when:** Starting a new project or hydrating an existing app. This is the single canonical path — the old two-step `app create` then `app init` is deleted; `descix app create` now hard-fails naming this replacement.
115
+ **Use when:** Starting a new project or hydrating an existing app. This is the one command that creates an app.
116
116
  **Options:**
117
117
  - `-a, --app <app_id>` (required): App ID. With `-c` this is the app NAME to create.
118
118
  - `-c, --community <id>`: Community ID — required to create an app that does not exist yet
@@ -13,8 +13,7 @@ Run this sequence ONCE to stand up a microservice that can call the mesh
13
13
  `/apifront` broker:
14
14
 
15
15
  ```bash
16
- descix app create -c {community} -a {app} # create the app (or hydrate an existing one)
17
- descix app init -a {community}-{app} # scaffold site/ kb/ microservice/
16
+ descix app init -c {community} -a {app} # create the app (or hydrate an existing one) and scaffold it
18
17
  descix app set-port -a {community}-{app} -p {port} # assign the microservice's loopback port in workspace.json
19
18
  descix microservice register # register the service manifest with the Core gateway
20
19
  # then: cp dev-overrides.example.json dev-overrides.json and fill in the developer credential
@@ -117,7 +116,7 @@ descix microservice register # register the service manifest
117
116
  **Example:**
118
117
  ```bash
119
118
  # Using the CLI
120
- descix service call {command_name} --param1 value
119
+ descix mcp execute --tool {command_name} --params '{"param1": "value"}'
121
120
 
122
121
  # Or via tell_me_how
123
122
  tell_me_how("I want to {describe the workflow goal}")
@@ -1,243 +0,0 @@
1
- ---
2
- alwaysApply: true
3
- ---
4
-
5
- # DeSciX SDK Agent Instructions
6
-
7
- You have SDK agent assets available locally at `{{SDK_ASSETS_PATH}}/`.
8
-
9
- ## Key Architecture Concepts
10
-
11
- ### Configuration: workspace.json is the Config File
12
-
13
- - **`workspace.json`** at `.descix/workspace.json` is the configuration file
14
- - **Context auto-detection** - CLI commands detect community/app from current working directory
15
-
16
- ### CLI = Git Mode ONLY
17
-
18
- - The CLI only supports **git-mode** operations (local processing with Git version control)
19
- - **Drive-mode** apps are managed via PWA only (server-side processing)
20
- - All content starts on Drive - developers pull it locally, then manage with Git
21
-
22
- ### App Folder Structure (Convention-Based)
23
-
24
- ```
25
- my-app/
26
- ├── assets/ # App metadata (icon.png, app_description.md, system_instructions.md)
27
- ├── kb/ # Knowledge base
28
- │ ├── staging/ # Files to push TO Drive
29
- │ ├── General/ # Text files pulled FROM Drive
30
- │ └── chunks/ # Generated JSON chunks (Git-tracked)
31
- ├── site/ # CodeSite static files (optional)
32
- └── microservice/ # Backend service code (optional)
33
- ```
34
-
35
- ## Post-Setup Initialization
36
-
37
- **IMPORTANT**: Check `.descix/workspace.json` for `_needsAgentSetup: true`.
38
-
39
- When this flag is set, the user has just completed `descix mcp quickstart` and needs your help configuring their workspace:
40
-
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
- 2. **Show their entitlements** from the cached JSON below (communities and apps they own)
43
- 3. **Ask**: "Which app would you like to configure first?" or "Would you like me to scan your folders and suggest mappings?"
44
- 4. **For each app folder**:
45
- - Analyze the folder structure using heuristics from `{{SDK_ASSETS_PATH}}/instructions/folder-analysis.md`
46
- - Recommend a packaging type using the decision tree from `{{SDK_ASSETS_PATH}}/instructions/packaging-types.md`
47
- - Register the app in `workspace.json` with its localPath and absolutePath
48
- 5. **When done**, set `_needsAgentSetup: false` in workspace.json
49
-
50
- If user asks "Help me configure my workspace" or similar, follow this flow.
51
-
52
- ## Entitlements-First Principle
53
-
54
- **CRITICAL**: Users purchase apps/communities in the PWA first. Your role is to help configure local folders for apps they already own.
55
-
56
- ### On First Interaction
57
-
58
- 1. Check `.descix/workspace.json` for existing configuration
59
- 2. If `_needsAgentSetup: true`, follow the Post-Setup Initialization flow above
60
- 3. If unconfigured, read `{{SDK_ASSETS_PATH}}/instructions/onboarding-flow.md`
61
- 4. For fresh entitlements: `execute_remote_command({ command: "fetch_my_purchases" })`
62
- 5. Guide user through folder-to-app mapping in `workspace.json`
63
-
64
- ## Local Asset References
65
-
66
- For quick decisions, read these local files (no network required):
67
-
68
- | File | Purpose |
69
- |------|---------|
70
- | `{{SDK_ASSETS_PATH}}/instructions/packaging-types.md` | App type taxonomy and decision tree |
71
- | `{{SDK_ASSETS_PATH}}/instructions/folder-analysis.md` | Detect project type from files |
72
- | `{{SDK_ASSETS_PATH}}/instructions/conversation-guides.md` | Dialogue templates |
73
- | `{{SDK_ASSETS_PATH}}/instructions/onboarding-flow.md` | Full onboarding workflow |
74
-
75
- ## Template Usage
76
-
77
- When scaffolding apps, use templates from `{{SDK_ASSETS_PATH}}/templates/`:
78
-
79
- | Packaging Type | Templates Available |
80
- |----------------|---------------------|
81
- | `knowledge-only` | Assets folder only |
82
- | `static-site` | Site folder scaffold |
83
- | `microservice` | `manifest.json.template`, `SERVICE_README.template` |
84
- | `dynamic-site` | Site + microservice scaffolds |
85
-
86
- Replace `{{PLACEHOLDER}}` values with actual data from user input.
87
-
88
- ## User Entitlements (Cached at Setup)
89
-
90
- ```json
91
- {{ENTITLEMENTS_JSON}}
92
- ```
93
-
94
- **Primary Community**: {{PRIMARY_COMMUNITY}}
95
-
96
- Use this cached data for quick checks. For fresh data, call `fetch_my_purchases`.
97
-
98
- ## Tiered Access Pattern
99
-
100
- Use the appropriate tier based on what you need:
101
-
102
- ### Tier 1: Local Files (Instant)
103
- ```javascript
104
- // Read instructions directly
105
- Read("{{SDK_ASSETS_PATH}}/instructions/packaging-types.md")
106
- ```
107
- **Use for**: Quick lookups, decision trees, templates
108
-
109
- ### Tier 2: tell_me_how (Semantic Discovery)
110
- ```javascript
111
- tell_me_how({
112
- question: "How do I scaffold a microservice?",
113
- scope: "entitlements"
114
- })
115
- ```
116
- **Use for**: Finding the right tool for a task
117
-
118
- ### Tier 3: chat_with_kb (Rich Context)
119
- ```javascript
120
- chat_with_kb({
121
- communityId: "descix",
122
- appId: "docs",
123
- kbId: "sdk",
124
- message: "Explain the deployment workflow for dynamic sites"
125
- })
126
- ```
127
- **Use for**: Complex questions requiring reasoning
128
-
129
- ### Tier 4: execute_remote_command (Action)
130
- ```javascript
131
- execute_remote_command({
132
- command: "scaffold_app_type",
133
- params: { type: "microservice", app_id: "myapp", ... }
134
- })
135
- ```
136
- **Use for**: Actually creating/modifying things
137
-
138
- ## Tool Discovery
139
-
140
- Use `tell_me_how` to discover platform capabilities:
141
-
142
- ```javascript
143
- // Discover tools for a task
144
- tell_me_how({ question: "How do I deploy my app?", scope: "entitlements" })
145
-
146
- // Then execute the recommended command
147
- execute_remote_command({ command: "discovered_command", params: {...} })
148
- ```
149
-
150
- **Scope Options**:
151
- - `project`: Only tools for apps in workspace.json
152
- - `entitlements`: Tools for all apps user owns (default)
153
- - `discovery`: All platform tools (may show purchasable)
154
-
155
- ## App Configuration Workflow
156
-
157
- When user wants to configure a folder:
158
-
159
- 1. **Analyze folder** using heuristics from `folder-analysis.md`
160
- 2. **Recommend packaging type** using decision tree from `packaging-types.md`
161
- 3. **Present options** using dialogue from `conversation-guides.md`
162
- 4. **Register app** in `workspace.json` with localPath and absolutePath
163
- 5. **Guide CLI commands** based on packaging type
164
-
165
- ## Primary CLI Commands
166
-
167
- Guide users to these git-mode commands:
168
-
169
- ### Knowledge Base Commands
170
- | Command | Purpose |
171
- |---------|---------|
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
-
179
- ### Site Commands
180
- | Command | Purpose |
181
- |---------|---------|
182
- | `descix site init` | Copy site scaffold to app |
183
- | `descix site upload` | Deploy CodeSite to GCS |
184
- | `descix site servelocal [port]` | Register local dev server port |
185
- | `descix site list` | List deployed site files |
186
- | `descix site status` | Get deployment status |
187
-
188
- ### Microservice Commands
189
- | Command | Purpose |
190
- |---------|---------|
191
- | `descix microservice init` | Copy microservice scaffold to app |
192
- | `descix microservice register` | Register microservice with gateway |
193
- | `descix microservice vectorize` | Vectorize README for discovery |
194
- | `descix microservice list` | List registered microservices |
195
- | `descix microservice health <name>` | Check microservice health |
196
- | `descix microservice reload` | Reload manifests (admin) |
197
-
198
- **Context Auto-Detection**: When run from within an app directory, these commands auto-detect community/app from `workspace.json`. Otherwise use `-c` and `-a` flags.
199
-
200
- ## SDK Tools Available (Remote)
201
-
202
- These tools are auto-registered and discoverable via `tell_me_how`:
203
-
204
- | Tool | Purpose |
205
- |------|---------|
206
- | `scaffold_app_type` | Create boilerplate for chosen packaging type |
207
- | `analyze_folder_structure` | Detect project type from folder contents |
208
- | `get_app_sync_status` | Check what's synced (KB, site, service) |
209
- | `fetch_my_purchases` | Get user's entitlements |
210
- | `register_service` | Register microservice with gateway |
211
- | `vectorize_service_readme` | Enable tell_me_how discovery |
212
-
213
- ## Key Principles
214
-
215
- 1. **Never assume** - Always ask before creating mappings
216
- 2. **Entitlements are truth** - Can't configure apps user doesn't own
217
- 3. **Local first** - Read local assets before making network calls
218
- 4. **Guide, don't dictate** - Present options, let user choose
219
- 5. **workspace.json is truth** - All configuration goes here
220
-
221
- ## Error Recovery
222
-
223
- If commands fail:
224
- 1. Check authentication: Is `wallet.json` valid?
225
- 2. Check entitlements: Does user own the app?
226
- 3. Check configuration: Is app registered in `workspace.json`?
227
- 4. Check location: Are you in the app directory or using `-c/-a` flags?
228
- 5. Use `tell_me_how` to find alternative approaches
229
-
230
- ### Common Errors
231
-
232
- | Error | Cause | Solution |
233
- |-------|-------|----------|
234
- | "Workspace not configured" | No workspace.json | Run `descix init` |
235
- | "Could not determine app context" | Not in app directory | `cd` to app or use `-c/-a` flags |
236
- | "ADC not configured" | Missing Google auth | Run `gcloud auth application-default login` |
237
- | "App not found in workspace" | App not registered | Run `descix mcp quickstart` or add to workspace.json |
238
-
239
- ---
240
-
241
- *Generated by DeSciX SDK Setup*
242
- *SDK Version: {{SDK_VERSION}}*
243
- *Workspace: {{WORKSPACE_PATH}}*
@@ -1,88 +0,0 @@
1
- /**
2
- * BrieferExtractorError — canonical hard-fail surface for the `descix briefer` CLI.
3
- *
4
- * Per WS-DESCIX-BRIEFER-CLI scope doc §2.3 ("Hard-fail philosophy"), every data
5
- * source has exactly one extraction method and exactly one failure mode:
6
- * HARD-FAIL with an actionable error message.
7
- *
8
- * Per feedback_no-hardcoded-fallbacks: NO fallback values, NO best-effort prose,
9
- * NO try-catch-and-default. If a source moved or changed shape, the CLI exits
10
- * non-zero and the canonical briefer file remains untouched.
11
- *
12
- * Stable error codes (per scope doc §2.3) — grep-friendly for diagnostics:
13
- * BRIEFER-SRC-NOT-FOUND Source file missing / line range no longer matches
14
- * BRIEFER-GCLOUD-AUTH gcloud auth missing or insufficient scope
15
- * BRIEFER-GCLOUD-FAIL gcloud probe failed (auth/empty/timeout) when --env=demo|prod required it
16
- * BRIEFER-PARSE-FAIL Source file present but construct unparseable
17
- * BRIEFER-DRIFT-DETECTED --check diff against canonical briefer non-empty
18
- * BRIEFER-NEGATIVE-CLAIM Briefer claims X does not exist, but found at Y:Z
19
- * BRIEFER-FIRESTORE Firestore read via apifront failed
20
- * BRIEFER-NOT-IMPLEMENTED M1 stub — extractor scaffold-only, real impl in later milestone
21
- *
22
- * Per scope doc §2.3, every error message must include:
23
- * 1. The exact source path + line range that was being read.
24
- * 2. The construct shape that was expected.
25
- * 3. What the operator should do to recover.
26
- * 4. A stable error code from the list above.
27
- */
28
-
29
- export const BRIEFER_ERROR_CODES = Object.freeze({
30
- SRC_NOT_FOUND: 'BRIEFER-SRC-NOT-FOUND',
31
- GCLOUD_AUTH: 'BRIEFER-GCLOUD-AUTH',
32
- PARSE_FAIL: 'BRIEFER-PARSE-FAIL',
33
- DRIFT_DETECTED: 'BRIEFER-DRIFT-DETECTED',
34
- NEGATIVE_CLAIM: 'BRIEFER-NEGATIVE-CLAIM',
35
- FIRESTORE: 'BRIEFER-FIRESTORE',
36
- GCLOUD_FAIL: 'BRIEFER-GCLOUD-FAIL',
37
- NOT_IMPLEMENTED: 'BRIEFER-NOT-IMPLEMENTED',
38
- WORKSPACE_NOT_FOUND: 'BRIEFER-WORKSPACE-NOT-FOUND'
39
- });
40
-
41
- export class BrieferExtractorError extends Error {
42
- /**
43
- * @param {object} args
44
- * @param {string} args.code One of BRIEFER_ERROR_CODES (REQUIRED).
45
- * @param {string} args.section Briefer section being extracted (e.g., '§3 routing').
46
- * @param {string} args.source File path or 'gcloud' or 'firestore' (REQUIRED).
47
- * @param {string} args.expected Construct shape that was expected (REQUIRED).
48
- * @param {string} args.recovery Concrete next step for the operator (REQUIRED).
49
- * @param {string} [args.detail] Optional extra context (e.g., parser msg, exit code).
50
- */
51
- constructor({ code, section, source, expected, recovery, detail } = {}) {
52
- if (!code || !Object.values(BRIEFER_ERROR_CODES).includes(code)) {
53
- // Hard-fail loud on misuse — caller is constructing a bad error.
54
- // We do NOT default the code; per feedback_no-hardcoded-fallbacks the
55
- // absence of a code is itself a misconfiguration we want to surface.
56
- throw new Error(
57
- `BrieferExtractorError requires a valid 'code'. Got: ${JSON.stringify(code)}. ` +
58
- `Valid codes: ${Object.values(BRIEFER_ERROR_CODES).join(', ')}.`
59
- );
60
- }
61
- if (!source) {
62
- throw new Error(`BrieferExtractorError requires a 'source' (file path / 'gcloud' / 'firestore').`);
63
- }
64
- if (!expected) {
65
- throw new Error(`BrieferExtractorError requires an 'expected' construct shape description.`);
66
- }
67
- if (!recovery) {
68
- throw new Error(`BrieferExtractorError requires a 'recovery' instruction for the operator.`);
69
- }
70
-
71
- const lines = [
72
- `[${code}] ${section || '(section unspecified)'}`,
73
- ` source: ${source}`,
74
- ` expected: ${expected}`,
75
- ` recovery: ${recovery}`
76
- ];
77
- if (detail) lines.push(` detail: ${detail}`);
78
-
79
- super(lines.join('\n'));
80
- this.name = 'BrieferExtractorError';
81
- this.code = code;
82
- this.section = section || null;
83
- this.source = source;
84
- this.expected = expected;
85
- this.recovery = recovery;
86
- this.detail = detail || null;
87
- }
88
- }