@solidnumber/cli 1.9.14 → 1.9.15

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 (193) hide show
  1. package/dist/commands/accounting.d.ts.map +1 -1
  2. package/dist/commands/accounting.js +4 -3
  3. package/dist/commands/accounting.js.map +1 -1
  4. package/dist/commands/agent.d.ts.map +1 -1
  5. package/dist/commands/agent.js +16 -15
  6. package/dist/commands/agent.js.map +1 -1
  7. package/dist/commands/analytics.d.ts.map +1 -1
  8. package/dist/commands/analytics.js +3 -2
  9. package/dist/commands/analytics.js.map +1 -1
  10. package/dist/commands/ant.d.ts.map +1 -1
  11. package/dist/commands/ant.js +2 -1
  12. package/dist/commands/ant.js.map +1 -1
  13. package/dist/commands/audit.d.ts.map +1 -1
  14. package/dist/commands/audit.js +4 -3
  15. package/dist/commands/audit.js.map +1 -1
  16. package/dist/commands/auth.d.ts.map +1 -1
  17. package/dist/commands/auth.js +5 -4
  18. package/dist/commands/auth.js.map +1 -1
  19. package/dist/commands/billing.d.ts.map +1 -1
  20. package/dist/commands/billing.js +8 -7
  21. package/dist/commands/billing.js.map +1 -1
  22. package/dist/commands/blog.d.ts.map +1 -1
  23. package/dist/commands/blog.js +49 -56
  24. package/dist/commands/blog.js.map +1 -1
  25. package/dist/commands/brand.d.ts.map +1 -1
  26. package/dist/commands/brand.js +3 -2
  27. package/dist/commands/brand.js.map +1 -1
  28. package/dist/commands/chains.d.ts.map +1 -1
  29. package/dist/commands/chains.js +37 -34
  30. package/dist/commands/chains.js.map +1 -1
  31. package/dist/commands/chat_widgets.d.ts.map +1 -1
  32. package/dist/commands/chat_widgets.js +3 -2
  33. package/dist/commands/chat_widgets.js.map +1 -1
  34. package/dist/commands/company.d.ts.map +1 -1
  35. package/dist/commands/company.js +8 -7
  36. package/dist/commands/company.js.map +1 -1
  37. package/dist/commands/context.d.ts.map +1 -1
  38. package/dist/commands/context.js +4 -3
  39. package/dist/commands/context.js.map +1 -1
  40. package/dist/commands/crm.d.ts.map +1 -1
  41. package/dist/commands/crm.js +19 -18
  42. package/dist/commands/crm.js.map +1 -1
  43. package/dist/commands/dashboard.d.ts.map +1 -1
  44. package/dist/commands/dashboard.js +2 -1
  45. package/dist/commands/dashboard.js.map +1 -1
  46. package/dist/commands/deploy.d.ts.map +1 -1
  47. package/dist/commands/deploy.js +5 -4
  48. package/dist/commands/deploy.js.map +1 -1
  49. package/dist/commands/dev.d.ts.map +1 -1
  50. package/dist/commands/dev.js +6 -5
  51. package/dist/commands/dev.js.map +1 -1
  52. package/dist/commands/diff.d.ts.map +1 -1
  53. package/dist/commands/diff.js +3 -2
  54. package/dist/commands/diff.js.map +1 -1
  55. package/dist/commands/domains.d.ts.map +1 -1
  56. package/dist/commands/domains.js +2 -1
  57. package/dist/commands/domains.js.map +1 -1
  58. package/dist/commands/drafts.d.ts.map +1 -1
  59. package/dist/commands/drafts.js +3 -2
  60. package/dist/commands/drafts.js.map +1 -1
  61. package/dist/commands/ecommerce.d.ts.map +1 -1
  62. package/dist/commands/ecommerce.js +16 -15
  63. package/dist/commands/ecommerce.js.map +1 -1
  64. package/dist/commands/emails.d.ts.map +1 -1
  65. package/dist/commands/emails.js +33 -30
  66. package/dist/commands/emails.js.map +1 -1
  67. package/dist/commands/flows.d.ts.map +1 -1
  68. package/dist/commands/flows.js +4 -3
  69. package/dist/commands/flows.js.map +1 -1
  70. package/dist/commands/forms.d.ts.map +1 -1
  71. package/dist/commands/forms.js +31 -28
  72. package/dist/commands/forms.js.map +1 -1
  73. package/dist/commands/health.d.ts.map +1 -1
  74. package/dist/commands/health.js +4 -3
  75. package/dist/commands/health.js.map +1 -1
  76. package/dist/commands/history.d.ts.map +1 -1
  77. package/dist/commands/history.js +7 -6
  78. package/dist/commands/history.js.map +1 -1
  79. package/dist/commands/inbound.d.ts.map +1 -1
  80. package/dist/commands/inbound.js +5 -4
  81. package/dist/commands/inbound.js.map +1 -1
  82. package/dist/commands/inbox.d.ts.map +1 -1
  83. package/dist/commands/inbox.js +8 -7
  84. package/dist/commands/inbox.js.map +1 -1
  85. package/dist/commands/insights.d.ts.map +1 -1
  86. package/dist/commands/insights.js +68 -28
  87. package/dist/commands/insights.js.map +1 -1
  88. package/dist/commands/integrations.d.ts.map +1 -1
  89. package/dist/commands/integrations.js +2 -1
  90. package/dist/commands/integrations.js.map +1 -1
  91. package/dist/commands/inventory.d.ts.map +1 -1
  92. package/dist/commands/inventory.js +33 -38
  93. package/dist/commands/inventory.js.map +1 -1
  94. package/dist/commands/keys.d.ts.map +1 -1
  95. package/dist/commands/keys.js +2 -1
  96. package/dist/commands/keys.js.map +1 -1
  97. package/dist/commands/landing.d.ts.map +1 -1
  98. package/dist/commands/landing.js +5 -4
  99. package/dist/commands/landing.js.map +1 -1
  100. package/dist/commands/leads.d.ts.map +1 -1
  101. package/dist/commands/leads.js +17 -16
  102. package/dist/commands/leads.js.map +1 -1
  103. package/dist/commands/llms.d.ts.map +1 -1
  104. package/dist/commands/llms.js +2 -1
  105. package/dist/commands/llms.js.map +1 -1
  106. package/dist/commands/logs.d.ts.map +1 -1
  107. package/dist/commands/logs.js +3 -2
  108. package/dist/commands/logs.js.map +1 -1
  109. package/dist/commands/marketplace.d.ts.map +1 -1
  110. package/dist/commands/marketplace.js +4 -3
  111. package/dist/commands/marketplace.js.map +1 -1
  112. package/dist/commands/migrate.d.ts.map +1 -1
  113. package/dist/commands/migrate.js +2 -1
  114. package/dist/commands/migrate.js.map +1 -1
  115. package/dist/commands/notifications.d.ts.map +1 -1
  116. package/dist/commands/notifications.js +2 -1
  117. package/dist/commands/notifications.js.map +1 -1
  118. package/dist/commands/onboarding.d.ts.map +1 -1
  119. package/dist/commands/onboarding.js +7 -6
  120. package/dist/commands/onboarding.js.map +1 -1
  121. package/dist/commands/orders.d.ts.map +1 -1
  122. package/dist/commands/orders.js +3 -2
  123. package/dist/commands/orders.js.map +1 -1
  124. package/dist/commands/pages.d.ts.map +1 -1
  125. package/dist/commands/pages.js +40 -46
  126. package/dist/commands/pages.js.map +1 -1
  127. package/dist/commands/payment.d.ts.map +1 -1
  128. package/dist/commands/payment.js +2 -1
  129. package/dist/commands/payment.js.map +1 -1
  130. package/dist/commands/payment_links.d.ts.map +1 -1
  131. package/dist/commands/payment_links.js +3 -2
  132. package/dist/commands/payment_links.js.map +1 -1
  133. package/dist/commands/products.d.ts.map +1 -1
  134. package/dist/commands/products.js +68 -35
  135. package/dist/commands/products.js.map +1 -1
  136. package/dist/commands/proposal.d.ts.map +1 -1
  137. package/dist/commands/proposal.js +2 -1
  138. package/dist/commands/proposal.js.map +1 -1
  139. package/dist/commands/reports.d.ts.map +1 -1
  140. package/dist/commands/reports.js +6 -5
  141. package/dist/commands/reports.js.map +1 -1
  142. package/dist/commands/schedule.d.ts.map +1 -1
  143. package/dist/commands/schedule.js +5 -4
  144. package/dist/commands/schedule.js.map +1 -1
  145. package/dist/commands/schema.d.ts.map +1 -1
  146. package/dist/commands/schema.js +3 -2
  147. package/dist/commands/schema.js.map +1 -1
  148. package/dist/commands/seo.d.ts.map +1 -1
  149. package/dist/commands/seo.js +6 -5
  150. package/dist/commands/seo.js.map +1 -1
  151. package/dist/commands/services.d.ts.map +1 -1
  152. package/dist/commands/services.js +3 -2
  153. package/dist/commands/services.js.map +1 -1
  154. package/dist/commands/site.d.ts.map +1 -1
  155. package/dist/commands/site.js +4 -3
  156. package/dist/commands/site.js.map +1 -1
  157. package/dist/commands/status.d.ts.map +1 -1
  158. package/dist/commands/status.js +3 -2
  159. package/dist/commands/status.js.map +1 -1
  160. package/dist/commands/storage.d.ts.map +1 -1
  161. package/dist/commands/storage.js +40 -39
  162. package/dist/commands/storage.js.map +1 -1
  163. package/dist/commands/subscriptions.d.ts.map +1 -1
  164. package/dist/commands/subscriptions.js +3 -2
  165. package/dist/commands/subscriptions.js.map +1 -1
  166. package/dist/commands/support.d.ts.map +1 -1
  167. package/dist/commands/support.js +3 -2
  168. package/dist/commands/support.js.map +1 -1
  169. package/dist/commands/switch.d.ts.map +1 -1
  170. package/dist/commands/switch.js +2 -1
  171. package/dist/commands/switch.js.map +1 -1
  172. package/dist/commands/users.d.ts.map +1 -1
  173. package/dist/commands/users.js +10 -9
  174. package/dist/commands/users.js.map +1 -1
  175. package/dist/commands/vibe.d.ts.map +1 -1
  176. package/dist/commands/vibe.js +2 -1
  177. package/dist/commands/vibe.js.map +1 -1
  178. package/dist/commands/voice.d.ts.map +1 -1
  179. package/dist/commands/voice.js +12 -11
  180. package/dist/commands/voice.js.map +1 -1
  181. package/dist/commands/webhooks.d.ts.map +1 -1
  182. package/dist/commands/webhooks.js +3 -2
  183. package/dist/commands/webhooks.js.map +1 -1
  184. package/dist/commands/widgets.d.ts.map +1 -1
  185. package/dist/commands/widgets.js +45 -50
  186. package/dist/commands/widgets.js.map +1 -1
  187. package/dist/lib/command-kit.d.ts +48 -0
  188. package/dist/lib/command-kit.d.ts.map +1 -1
  189. package/dist/lib/command-kit.js +64 -0
  190. package/dist/lib/command-kit.js.map +1 -1
  191. package/package.json +1 -1
  192. package/platform-docs/COOKBOOK.md +8 -3
  193. package/platform-docs/SCHEMAS.md +255 -103
@@ -172,9 +172,14 @@ solid auth token create \
172
172
  export SOLID_TOKEN=$(jq -r .key /tmp/key.json)
173
173
  ```
174
174
 
175
- Now the agent has read-only access for a week. Agency tip: add
176
- `--require-approval` in the token request so every destructive call
177
- queues a human approval instead of firing.
175
+ Now the agent has read-only access for a week. For scripted use, the
176
+ CLI also honors `SOLID_TOKEN=<key>` and `SOLID_API_KEY=<key>` env vars
177
+ either takes precedence over the cached session for that process.
178
+
179
+ **Not yet shipped (don't reference in agent code yet):** a per-key
180
+ `require_approval` flag that queues every destructive call for a
181
+ human OK before firing. It's on the roadmap but does NOT exist on
182
+ `solid auth token create` today.
178
183
 
179
184
  ---
180
185
 
@@ -1,8 +1,16 @@
1
1
  # `--json` Output Schemas
2
2
 
3
- The contract: **every `--json` payload is the backend's response body, unmodified** no CLI-added wrapping, no "status" key glued on top. If you want the authoritative schema, that's the OpenAPI spec. This doc is the practical field guide — what you'll actually see in stdout when you run the command.
3
+ **Verified against live production responses** on 2026-04-18 using
4
+ `@solidnumber/cli@1.9.14`. If you find drift, the backend shape is the
5
+ ground truth — update this doc or open an issue.
4
6
 
5
- Schemas below use TypeScript interface shorthand. Optional fields are `?`. Values shown in samples are representative, not fixed.
7
+ The contract: **every `--json` payload is the backend's response body,
8
+ unmodified** (except for list commands using `--all`, which wrap the
9
+ flattened page as `{ items: T[], count: number }`).
10
+
11
+ Schemas are TypeScript interfaces for readability. Optional fields are
12
+ `?`. Backend inconsistencies (e.g. both `created_at` and `createdAt` on
13
+ the same record) are noted where they occur.
6
14
 
7
15
  ---
8
16
 
@@ -12,13 +20,13 @@ Schemas below use TypeScript interface shorthand. Optional fields are `?`. Value
12
20
 
13
21
  ```ts
14
22
  interface WhoamiResponse {
15
- authenticated: boolean | 'offline'; // 'offline' = cached session, couldn't reach server
23
+ authenticated: boolean | 'offline'; // 'offline' = cached session, couldn't reach server
16
24
  email: string | null;
17
25
  company_id: number | null;
18
- user_id?: number;
26
+ user_id?: number; // only populated when the server confirmed auth
19
27
  environment: 'production' | 'sandbox' | 'development';
20
28
  api_url: string;
21
- token_expires_at: string | null; // ISO 8601, null if no expiry tracked
29
+ token_expires_at: string | null; // ISO 8601, null if no expiry tracked
22
30
  }
23
31
  ```
24
32
 
@@ -32,15 +40,15 @@ interface AuthRefreshResponse {
32
40
  }
33
41
  ```
34
42
 
35
- ### `solid auth token create` (always JSON in output)
43
+ ### `solid auth token create` (always emits JSON on success)
36
44
 
37
45
  ```ts
38
46
  interface ApiKeyCreateResponse {
39
47
  id: number;
40
48
  name: string;
41
- key: string; // sk_solid_... — shown once, never again
42
- key_prefix: string; // first 12 chars, safe to log
43
- scopes: string[]; // e.g. ['kb:read', 'pages:write']
49
+ key: string; // sk_solid_... — shown once, never again
50
+ key_prefix: string; // first 12 chars, safe to log
51
+ scopes: string[]; // e.g. ['kb:read', 'pages:write']
44
52
  expires_at: string | null;
45
53
  created_at: string;
46
54
  }
@@ -71,37 +79,31 @@ interface SwitchListResponse {
71
79
 
72
80
  ### `solid company info --json`
73
81
 
82
+ Top-level envelope has a `status` sibling alongside the `company` object:
83
+
74
84
  ```ts
75
85
  interface CompanyInfoResponse {
86
+ status: 'ok' | 'error' | string;
76
87
  company: {
77
88
  id: number;
78
89
  name: string;
79
- kb_sub_code?: string; // industry slug (plumber, hvac, dentist, …)
80
- business_type?: string;
81
- industry_name?: string;
82
- mcc_code?: string;
83
- feature_settings?: Record<string, boolean>;
90
+ slug: string;
91
+ created_at: string;
92
+ is_demo: boolean;
93
+ logo_asset_id: number | null;
94
+ logo_url: string | null;
95
+ parent_id: number | null;
96
+ portal_type: string | null;
97
+ public_domain: string | null;
98
+ sandbox_enabled: boolean;
99
+ timezone: string;
84
100
  };
85
101
  }
86
102
  ```
87
103
 
88
- ### `solid company lock-status --json` (T10 agency-managed)
89
-
90
- ```ts
91
- interface LockStatus {
92
- company_id: number;
93
- agency_managed: boolean;
94
- agency_owner_user_id: number | null;
95
- locks: {
96
- pages: boolean;
97
- brand: boolean;
98
- domains: boolean;
99
- modules: boolean;
100
- design: boolean;
101
- billing_lock: boolean;
102
- };
103
- }
104
- ```
104
+ Note: `kb_sub_code`, `business_type`, `industry_name`, `mcc_code` are
105
+ NOT on this endpoint — fetch them via `solid company current` or the
106
+ direct `/api/v1/companies/me` endpoint instead.
105
107
 
106
108
  ---
107
109
 
@@ -109,32 +111,59 @@ interface LockStatus {
109
111
 
110
112
  ### `solid crm contacts list --json`
111
113
 
114
+ Two envelope shapes — single page returns the backend body as-is
115
+ (flexible), `--all` normalizes to `{ items, count }`.
116
+
112
117
  ```ts
118
+ // Single page (default)
113
119
  interface ContactsListResponse {
114
- items?: Contact[]; // pass-through; `--all` wraps as { items, count }
115
- contacts?: Contact[]; // some backend paths use this key
120
+ contacts?: Contact[]; // most responses use this key
121
+ items?: Contact[]; // some paths use this
122
+ total?: number;
123
+ }
124
+
125
+ // --all wrapper
126
+ interface ContactsAllResponse {
127
+ items: Contact[];
116
128
  count: number;
117
- offset?: number;
118
- page_size?: number;
119
129
  }
120
130
 
131
+ // Contact — snake_case and camelCase BOTH appear on the same record
132
+ // (legacy fields from the dashboard side kept for backwards compat)
121
133
  interface Contact {
122
134
  id: number;
123
135
  first_name: string | null;
124
136
  last_name: string | null;
137
+ full_name: string | null;
138
+ name: string | null; // camelCase alias
125
139
  email: string | null;
126
140
  phone: string | null;
141
+ company: string | null; // company name
142
+ company_id: number | null; // tenant id (Solid# owner)
127
143
  company_name: string | null;
128
- status?: 'active' | 'inactive' | 'blocked' | string;
129
- source?: string;
130
- contact_type?: string;
144
+ contact_type: string | null;
145
+ source: string | null;
146
+ status: string | null;
147
+ grade: string | null;
148
+ score: number | null;
149
+ tags: string[];
150
+ assigned_at: string | null;
151
+ assigned_to_user_id: number | null;
152
+ assigned_to_user_name: string | null;
153
+ assigned_to_agent: string | null;
154
+ totalOrders: number | null; // camelCase
155
+ totalSpent: number | null; // camelCase
156
+ lastOrderDate: string | null; // camelCase
131
157
  created_at: string;
158
+ createdAt: string; // dupe — camelCase
132
159
  updated_at: string;
133
160
  }
134
161
  ```
135
162
 
136
163
  ### `solid crm contacts import --json`
137
164
 
165
+ Same shape as `solid ecommerce orders import --json`:
166
+
138
167
  ```ts
139
168
  interface ImportResponse {
140
169
  summary: {
@@ -145,33 +174,46 @@ interface ImportResponse {
145
174
  dry_run: boolean;
146
175
  };
147
176
  results: Array<{
148
- row: number; // 1-indexed within the CSV (row 1 = header)
177
+ row: number; // 1-indexed within the CSV
149
178
  status: 'created' | 'failed' | 'skipped' | 'dry-run';
150
- id?: number; // only when status === 'created'
151
- error?: string; // only when status !== 'created'
179
+ id?: number; // only when status === 'created'
180
+ error?: string; // only when status !== 'created'
152
181
  }>;
153
182
  }
154
183
  ```
155
184
 
156
- Same shape for `solid ecommerce orders import --json`.
157
-
158
185
  ### `solid crm deals list --json`
159
186
 
187
+ Envelope is NOT `{ items, count }` like contacts — it's `{ deals, limit, offset, total }`.
188
+
160
189
  ```ts
161
190
  interface DealsListResponse {
162
- items: Deal[];
163
- count: number;
191
+ deals: Deal[];
192
+ limit: number;
193
+ offset: number;
194
+ total: number;
164
195
  }
165
196
 
166
197
  interface Deal {
167
198
  id: number;
168
199
  title: string;
169
- value: number | null;
170
200
  stage: string;
201
+ source: string | null;
202
+ amount: number | null; // dollars
203
+ amount_cents: number | null; // cents (authoritative)
204
+ lead_cost_cents: number | null;
205
+ notes: string | null;
171
206
  contact_id: number | null;
172
- contact_name?: string;
173
- closed_at?: string | null;
174
- outcome?: 'won' | 'lost' | null;
207
+ contact_name: string | null;
208
+ company_id: number; // tenant
209
+ company_name: string | null;
210
+ assigned_at: string | null;
211
+ assigned_to_user_id: number | null;
212
+ assigned_to_user_name: string | null;
213
+ assigned_to_agent: string | null;
214
+ follow_up_date: string | null;
215
+ created_at: string;
216
+ updated_at: string;
175
217
  }
176
218
  ```
177
219
 
@@ -181,19 +223,21 @@ interface Deal {
181
223
 
182
224
  ### `solid kb list --json`
183
225
 
226
+ Minimal envelope — just `{ results }`, no total / count / pagination
227
+ metadata returned:
228
+
184
229
  ```ts
185
230
  interface KBListResponse {
186
- entries: KBEntry[];
187
- total: number;
231
+ results: KBEntry[];
188
232
  }
189
233
 
190
234
  interface KBEntry {
191
235
  id: number;
192
236
  title: string;
193
237
  category: string | null;
194
- content: string; // may be truncated on list endpoint
195
- version: number;
196
- updated_at: string;
238
+ content: string;
239
+ // Other fields (version, updated_at) are returned by the /kb/entries/{id}
240
+ // detail endpoint, not the list endpoint.
197
241
  }
198
242
  ```
199
243
 
@@ -220,17 +264,23 @@ interface KBHistoryResponse {
220
264
 
221
265
  ### `solid pages list --json`
222
266
 
267
+ Pages list uses the `--all` envelope even for single-page requests
268
+ (we added this consistency in 1.9.14).
269
+
223
270
  ```ts
224
271
  interface PagesListResponse {
225
- pages: Array<{
226
- id: number;
227
- slug: string;
228
- title: string;
229
- is_published: boolean;
230
- current_version: number;
231
- updated_at: string;
232
- }>;
233
- total: number;
272
+ items: Page[];
273
+ count: number;
274
+ }
275
+
276
+ interface Page {
277
+ id: number;
278
+ slug: string;
279
+ title: string;
280
+ page_type: 'website' | 'landing' | 'blog' | 'booking' | string;
281
+ is_published: boolean;
282
+ current_version: number;
283
+ updated_at: string;
234
284
  }
235
285
  ```
236
286
 
@@ -263,17 +313,32 @@ interface PagesHistoryResponse {
263
313
 
264
314
  ### `solid billing status --json`
265
315
 
316
+ **Backend changed this shape recently — verified 2026-04-18.**
317
+
266
318
  ```ts
267
- interface BillingOverviewResponse {
319
+ interface BillingStatusResponse {
320
+ has_payment_method: boolean;
321
+ next_billing_date: string | null; // ISO
322
+ subscription: Subscription | null; // null = no active subscription
323
+ sms_pack: PackState | null;
324
+ voice_plan: PackState | null;
325
+ token_budget: PackState | null;
326
+ }
327
+
328
+ interface Subscription {
268
329
  tier: 'starter' | 'builder' | 'professional' | 'enterprise';
269
- plan?: string; // legacy field, mirrors tier
270
330
  status: 'active' | 'past_due' | 'cancelled' | 'trialing';
271
- current_period_end: string; // ISO
272
- amount: number; // monthly dollars
273
- processor?: string;
274
- mcc_code?: string;
275
- industry?: string;
276
- active?: boolean;
331
+ amount_cents: number;
332
+ current_period_start: string;
333
+ current_period_end: string;
334
+ cancel_at_period_end: boolean;
335
+ }
336
+
337
+ interface PackState {
338
+ included: number;
339
+ used: number;
340
+ remaining: number;
341
+ overage_price_cents: number;
277
342
  }
278
343
  ```
279
344
 
@@ -283,12 +348,12 @@ interface BillingOverviewResponse {
283
348
  interface InvoicesListResponse {
284
349
  invoices: Array<{
285
350
  id: number;
286
- invoice_id: string; // Stripe in_... id
351
+ invoice_id: string; // Stripe in_... id
287
352
  amount: number;
288
353
  total: number;
289
354
  currency: string;
290
355
  status: 'paid' | 'open' | 'void' | 'uncollectible';
291
- date: string; // ISO
356
+ date: string;
292
357
  hosted_url?: string;
293
358
  pdf_url?: string;
294
359
  }>;
@@ -306,10 +371,10 @@ Shape depends on the report. The envelope is stable:
306
371
 
307
372
  ```ts
308
373
  interface ReportRunResponse {
309
- rows?: Array<Record<string, unknown>>; // tabular reports
310
- data?: Array<Record<string, unknown>>; // some endpoints use this key
374
+ rows?: Array<Record<string, unknown>>;
375
+ data?: Array<Record<string, unknown>>;
311
376
  results?: Array<Record<string, unknown>>;
312
- summary?: Record<string, number | string>; // aggregates
377
+ summary?: Record<string, number | string>;
313
378
  meta?: {
314
379
  report: string;
315
380
  date_from: string;
@@ -323,17 +388,35 @@ Use `solid reports run --list --json` to enumerate types.
323
388
 
324
389
  ### `solid analytics dashboard --json`
325
390
 
391
+ **Re-verified 2026-04-18 — fully rewritten from the old `{ revenue, transactions, ... }` shape.** Everything is nested under `metrics`, `quick_stats`, `revenue_chart`, `recent_orders`, `top_products`:
392
+
326
393
  ```ts
327
394
  interface DashboardSummary {
328
- revenue?: number;
329
- transactions?: number;
330
- customers?: number;
331
- new_customers?: number;
332
- avg_transaction?: number;
333
- chargebacks?: number;
334
- period?: string; // days
335
- date_from?: string;
336
- date_to?: string;
395
+ period: string; // '7', '30', '90'
396
+ metrics: {
397
+ total_revenue: TrendMetric; // see below
398
+ total_orders: TrendMetric;
399
+ customers: { total: number; new: number; trend: number; trend_direction: 'up' | 'down' };
400
+ active_products: { value: number };
401
+ growth_rate: { value: number; formatted: string };
402
+ };
403
+ quick_stats: {
404
+ daily_sales: { value: number; formatted: string; orders: number; date: string };
405
+ month_previous: { value: number; formatted: string; orders: number; month: string };
406
+ };
407
+ revenue_chart: Array<{ date: string; revenue: number }>;
408
+ recent_orders: Array<{ id: number; total: number; customer: string; created_at: string }>;
409
+ top_products: Array<{ id: number; name: string; revenue: number; units: number }>;
410
+ }
411
+
412
+ interface TrendMetric {
413
+ value: number;
414
+ formatted?: string;
415
+ trend: number; // % change vs prior period
416
+ trend_direction: 'up' | 'down';
417
+ daily_average: number;
418
+ daily_average_formatted?: string;
419
+ prev_daily_average: number;
337
420
  }
338
421
  ```
339
422
 
@@ -363,8 +446,8 @@ interface AgentListResponse {
363
446
  ```ts
364
447
  interface AgentClonesResponse {
365
448
  profiles: Array<{
366
- agent_type: string; // base — e.g. 'customer_service'
367
- display_name: string; // company-specific rename
449
+ agent_type: string; // base — e.g. 'customer_service'
450
+ display_name: string; // company-specific rename
368
451
  system_prompt: string | null;
369
452
  personality: string | null;
370
453
  model: string | null;
@@ -376,14 +459,61 @@ interface AgentClonesResponse {
376
459
 
377
460
  ---
378
461
 
462
+ ## E-commerce
463
+
464
+ ### `solid ecommerce orders list --json`
465
+
466
+ Single-page envelope from the backend; `--all` normalizes as usual.
467
+
468
+ ```ts
469
+ interface OrdersListResponse {
470
+ orders?: Order[]; // backend key
471
+ items?: Order[]; // fallback key on some paths
472
+ }
473
+
474
+ interface Order {
475
+ id: number;
476
+ customer_email?: string;
477
+ customer_name?: string;
478
+ total: number;
479
+ status: 'pending' | 'paid' | 'shipped' | 'cancelled' | 'refunded';
480
+ currency: string;
481
+ created_at: string;
482
+ }
483
+ ```
484
+
485
+ ---
486
+
487
+ ## Conversation Insights
488
+
489
+ ### `solid insights list --json`
490
+
491
+ Uses the unified `{ items, count }` envelope from command-kit's
492
+ `runListCommand`:
493
+
494
+ ```ts
495
+ interface InsightListResponse {
496
+ items: Array<{
497
+ insight_type?: 'kb_gap' | 'pattern' | 'suggestion' | string;
498
+ type?: string; // some paths duplicate this
499
+ title?: string;
500
+ summary?: string;
501
+ recommendation?: string;
502
+ }>;
503
+ count: number;
504
+ }
505
+ ```
506
+
507
+ ---
508
+
379
509
  ## MCP Tools / Chains
380
510
 
381
511
  ### `solid chains execute <id> --json`
382
512
 
383
513
  ```ts
384
514
  interface ChainExecutionResponse {
385
- execution_id: string; // UUID — the job handle
386
- id?: string; // legacy alias for execution_id
515
+ execution_id: string; // UUID — the job handle
516
+ id?: string; // legacy alias
387
517
  status: 'queued' | 'running' | 'completed' | 'failed' | 'cancelled';
388
518
  chain_id: number;
389
519
  started_at: string;
@@ -397,36 +527,36 @@ interface ChainExecutionResponse {
397
527
  }
398
528
  ```
399
529
 
400
- ### `solid mcp-server health` / `GET /health` on mcp.solidnumber.com
530
+ ### MCP server `/health` on `mcp.solidnumber.com`
401
531
 
402
532
  ```ts
403
533
  interface MCPHealthResponse {
404
534
  status: 'healthy';
405
535
  server: string;
406
536
  version: string;
407
- tools: number; // 608+ for the main registry
537
+ tools: number; // 608+ for the main registry
408
538
  categories: number;
409
- backend: string; // internal URL
410
- uptime: number; // seconds
539
+ backend: string; // internal URL
540
+ uptime: number; // seconds
411
541
  timestamp: string;
412
542
  }
413
543
  ```
414
544
 
415
545
  ---
416
546
 
417
- ## Error responses
547
+ ## Error shapes
418
548
 
419
- Any command that hits the backend surfaces the backend's error payload
420
- inside the CLI's red-line formatter. The backend's structured shape:
549
+ Backend 4xx/5xx responses:
421
550
 
422
551
  ```ts
423
552
  interface ApiError {
424
- detail: string | Array<{ loc: string[]; msg: string; type: string }>; // FastAPI 422s
553
+ detail: string | Array<{ loc: string[]; msg: string; type: string }>;
425
554
  message?: string;
426
555
  }
427
556
  ```
428
557
 
429
- The CLI flattens `detail` arrays into `loc.path: msg` lines before printing. Structured MCP-protocol errors follow the JSON-RPC 2.0 envelope:
558
+ The CLI flattens `detail` arrays into `loc.path: msg` lines before
559
+ printing (on stderr). MCP protocol errors follow JSON-RPC 2.0:
430
560
 
431
561
  ```ts
432
562
  interface MCPError {
@@ -436,8 +566,8 @@ interface MCPError {
436
566
  code: number;
437
567
  message: string;
438
568
  data?: {
439
- error_class?: string; // stable identifier — branch on this, not message
440
- hint?: string; // human-readable remediation
569
+ error_class?: string; // stable identifier — branch on this, not message
570
+ hint?: string; // human-readable remediation
441
571
  };
442
572
  };
443
573
  }
@@ -445,12 +575,34 @@ interface MCPError {
445
575
 
446
576
  ---
447
577
 
448
- ## Pagination envelope (global)
578
+ ## `--all` envelope (universal)
449
579
 
450
- List endpoints that support `--limit` / `--offset` / `--all` return a common pagination shape when available. `--all` wraps the flattened collection as:
580
+ When you pass `--all`, command-kit's `runListCommand` normalizes the
581
+ flattened collection as:
451
582
 
452
583
  ```ts
453
584
  { items: T[]; count: number }
454
585
  ```
455
586
 
456
- Single-page responses keep whatever native shape the backend emits (`{ items }`, `{ contacts }`, `{ deals }`, etc.). Use `--all` for schema normalization.
587
+ regardless of the backend's native key (`contacts`, `deals`, `orders`,
588
+ `items`, etc.). This lets scripts write `jq '.items[]'` without
589
+ per-endpoint special-casing.
590
+
591
+ Single-page responses keep the backend's native shape — documented
592
+ above per command.
593
+
594
+ ---
595
+
596
+ ## Gotchas I actually hit while writing this
597
+
598
+ - `billing status` used to return `{ tier, status, amount, ... }` flat.
599
+ It's now `{ subscription: {...}, sms_pack, voice_plan, token_budget, ... }`.
600
+ If you wrote scripts against the old shape, they're broken.
601
+ - Contact records double-serialize both `created_at` (snake) AND
602
+ `createdAt` (camel), `totalOrders`/`totalSpent` (camel) alongside
603
+ snake_case fields from the same row. The backend is mid-migration.
604
+ - Deals use `deals` as the envelope key; contacts use `contacts` or
605
+ `items`; orders use `orders`; insights uses `items` (because we wrap it).
606
+ No universal naming — use `--all` if you want consistency.
607
+ - `kb list` returns just `{ results }` — no `total` or pagination
608
+ metadata. Use `solid history kb` if you need versioned history.