@remits/remits-cli 0.1.69
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/LICENSE +21 -0
- package/README.md +180 -0
- package/index.js +4379 -0
- package/package.json +40 -0
- package/skills/remits-cli/SKILL.md +1278 -0
|
@@ -0,0 +1,1278 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: remits-cli
|
|
3
|
+
description: Use remits-cli for fast branch-scoped component staging, test execution, embeddable token flows, and tool-based investigation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# remits-cli
|
|
7
|
+
|
|
8
|
+
`remits-cli` is the brainstem for both **development** and **production support**. You might run it inside an account repository (where `account-info.json` and `/components` already exist) or from outside any repo when a user needs help on another account. Your users are business professionals — they think in terms of what they can see in a browser.
|
|
9
|
+
|
|
10
|
+
## Account Targeting Model
|
|
11
|
+
|
|
12
|
+
Before deciding which repo or account context to use, read the target account's `type` from `account-info.json` or `Account.getInformation` / `mcp_account_view`.
|
|
13
|
+
|
|
14
|
+
- **`PLATFORM`** = a use-case/platform implementation account. This is often where the shared Remits components live.
|
|
15
|
+
- **`PRODUCT`** = a product/use-case account under a platform. This can also hold shared implementation components.
|
|
16
|
+
- **`CLIENT`** = an actual customer account. This is usually where production data lives and where an issue is observed, but not necessarily where the shared implementation is authored.
|
|
17
|
+
|
|
18
|
+
Do not guess from the account name alone.
|
|
19
|
+
|
|
20
|
+
- If the work is a **feature, enhancement, component change, or shared behavior fix**, the implementation target is usually the relevant `PLATFORM` or `PRODUCT` account, not the `CLIENT` account that reported the issue.
|
|
21
|
+
- If the work is a **production investigation or client-specific data issue**, start with the affected `CLIENT` account's data and runtime history.
|
|
22
|
+
- If the request spans both, investigate in the `CLIENT` account first to confirm symptoms, then move to the owning `PLATFORM` or `PRODUCT` repo before making code changes.
|
|
23
|
+
|
|
24
|
+
Apply these rules before making remote tool calls:
|
|
25
|
+
|
|
26
|
+
- **Inside the target implementation repo**: read `account-info.json` (the same data that `mcp_account_view` returns) and inspect `/components` directly.
|
|
27
|
+
- **Inside one repo but supporting a different account**: switch to the correct repo for that account type if available; otherwise use `mcp_account_view` / `mcp_component_view` / `mcp_component_grep`.
|
|
28
|
+
- **Outside any repo**: rely on the tools for account structure and component source.
|
|
29
|
+
- **Never create a new local repo/directory just because a ticket references an account name.** First resolve the account type and parent hierarchy. Only work from an existing indexed repo unless the user explicitly asks you to create or clone one.
|
|
30
|
+
|
|
31
|
+
Use `remits-cli` for everything else: staging changes, running tests, generating embeddable tokens, committing work, and diagnosing production issues.
|
|
32
|
+
|
|
33
|
+
## Required Local Index Reads
|
|
34
|
+
|
|
35
|
+
These files are decision inputs. Read them when the related decision depends on them.
|
|
36
|
+
|
|
37
|
+
- `~/.remits-cli/account-repos.json`
|
|
38
|
+
- The inventory of every local Remits repo. Account repos are keyed by numeric account id.
|
|
39
|
+
- It also contains the reserved **`platform`** entry: the local clone of the core Remits platform repo (`type:'PLATFORM_REPO'`, with its `directory` path). `remits-cli` clones it on first authenticated run if it is missing (default `~/remits`, override with `REMITS_PLATFORM_DIR`). Read this entry when you need to analyze a back-stage seam or open a platform-fix PR.
|
|
40
|
+
- Read before choosing a repo outside the current working directory.
|
|
41
|
+
- Read when a support ticket references an account and you need to locate the correct local repo.
|
|
42
|
+
- Read before concluding that a repo does not exist locally.
|
|
43
|
+
- `~/.remits-cli/config.json`
|
|
44
|
+
- Read when service lifecycle, dashboard, listener, or agent-dispatch behavior matters.
|
|
45
|
+
- `~/.remits-cli/service-state.json`
|
|
46
|
+
- Read when the local control center URL, current dashboard port, repo-scan summary, or websocket status matters.
|
|
47
|
+
- Read when the user asks whether the remits-cli service is running or where to open the browser view.
|
|
48
|
+
- `~/.remits-cli/dispatch-panes.json`
|
|
49
|
+
- Read when support-ticket follow-up routing, pane reuse, or pane replacement behavior matters.
|
|
50
|
+
- `~/.remits-cli/tmux-activity.log`
|
|
51
|
+
- Read when diagnosing service lifecycle, websocket, tmux, ticket-routing, or dispatch failures.
|
|
52
|
+
- `~/.remits-cli/sessions.json`
|
|
53
|
+
- Read when authentication state, active accounts, base URLs, websocket topics, or per-account data mode matters.
|
|
54
|
+
- `./.remits-cli/current-session.txt`
|
|
55
|
+
- Read before opening repo-local session logs so you know which session file is current.
|
|
56
|
+
- `./.remits-cli/sessions/<current-session>.jsonl`
|
|
57
|
+
- Read when the question is about what HTTP calls the repo recently made through remits-cli, which payload was sent, or what response/error came back.
|
|
58
|
+
- `./.remits-cli/tool-responses/<callId>.json`
|
|
59
|
+
- Read when `remits-cli tool` says the full payload was stored externally.
|
|
60
|
+
- `./.remits-cli/tools/tools.json`
|
|
61
|
+
- Read when the question is about available tool names, cached schemas, or why a tool invocation shape may be invalid.
|
|
62
|
+
- `account-info.json`
|
|
63
|
+
- Read in the target repo before making component changes or assuming account ownership.
|
|
64
|
+
|
|
65
|
+
Do not rely on memory for these indexes. Read the file that governs the decision you are making.
|
|
66
|
+
|
|
67
|
+
## Big Picture: How remits-cli State Is Organized
|
|
68
|
+
|
|
69
|
+
Think about remits-cli as two cooperating layers:
|
|
70
|
+
|
|
71
|
+
1. **Global machine state** in `~/.remits-cli/`
|
|
72
|
+
- This is the cross-repo control plane.
|
|
73
|
+
- It answers questions like:
|
|
74
|
+
- which accounts are authenticated
|
|
75
|
+
- which repos exist locally
|
|
76
|
+
- whether the background service is running
|
|
77
|
+
- where the control center lives
|
|
78
|
+
- whether websocket/tmux dispatch is healthy
|
|
79
|
+
|
|
80
|
+
2. **Per-repo state** in `./.remits-cli/`
|
|
81
|
+
- This is the request/response and cache layer for one specific working tree.
|
|
82
|
+
- It answers questions like:
|
|
83
|
+
- which repo-local session log is current
|
|
84
|
+
- which `/cli/*` calls were made from this repo
|
|
85
|
+
- where a large tool response was written
|
|
86
|
+
- which tool schemas were most recently cached here
|
|
87
|
+
|
|
88
|
+
When a user asks an indirect question, map it to the right layer first:
|
|
89
|
+
|
|
90
|
+
- "Why did this ticket open in the wrong repo?" → start in global state.
|
|
91
|
+
- "What exact payload did this tool call send?" → start in per-repo state.
|
|
92
|
+
- "Why is the dashboard showing stale repos?" → start in `service-state.json` and `account-repos.json`.
|
|
93
|
+
- "Why is the browser page not showing websocket activity?" → start in `service-state.json` and `tmux-activity.log`.
|
|
94
|
+
|
|
95
|
+
Agents should use this mental model before guessing.
|
|
96
|
+
|
|
97
|
+
## Support Ticket Mental Model
|
|
98
|
+
|
|
99
|
+
The local agent workflow includes a lightweight support-ticket system:
|
|
100
|
+
|
|
101
|
+
- Support tickets are Firestore documents in `support_tickets`.
|
|
102
|
+
- Support tickets belong to the actual Remits account the work relates to.
|
|
103
|
+
- Tickets are created centrally from support intake and pushed to local agents over the `remits-cli` WebSocket channel.
|
|
104
|
+
- Each incoming ticket becomes a tmux workstream in the shared `remits-listener` session, so you can think of it as a localized Jira-style queue for active agent work.
|
|
105
|
+
- Review centralized listener/tmux activity in `~/.remits-cli/tmux-activity.log`.
|
|
106
|
+
|
|
107
|
+
Use `mcp_support_ticket` to manage lifecycle:
|
|
108
|
+
- `read` — always start here to load current state
|
|
109
|
+
- `accept` — claim the ticket so other agents do not work it concurrently
|
|
110
|
+
- `update_status` — move to `in_progress` or `pending_review`
|
|
111
|
+
- `complete` — resolve the ticket with a summary of what was done
|
|
112
|
+
- `release` — unassign if you cannot continue
|
|
113
|
+
- Always call `mcp_support_ticket` with the ticket's owning `accountId`.
|
|
114
|
+
- If a ticket is part of the request, manage the lifecycle proactively. Do not wait for the human user to remind you to read, accept, update, complete, or release it.
|
|
115
|
+
|
|
116
|
+
Ticket-routing context:
|
|
117
|
+
- `accountId` / `accountName` identify the account that owns the ticket.
|
|
118
|
+
- If present, `implementationAccountId` / `implementationAccountName` identify the owning `PLATFORM` or `PRODUCT` implementation context.
|
|
119
|
+
- The local listener should prefer `implementationAccountId` when choosing the initial working directory for a ticket, with fallback to `accountId` if the platform/product repo is not available locally.
|
|
120
|
+
- For enhancement work, prefer the platform/product implementation context when deciding where code changes belong.
|
|
121
|
+
- For defect investigations, start from the owning ticket account, then move to the platform/product context if the root cause is in shared components.
|
|
122
|
+
|
|
123
|
+
Sandbox note:
|
|
124
|
+
- `remits-cli` commands that call the Remits service (`auth`, `tools`, `tool`, `components`, `test`, `token`) require outbound network access.
|
|
125
|
+
- In Codex or similar sandboxed agent environments, `ENOTFOUND`, `EAI_AGAIN`, `ECONNREFUSED`, `EPERM`, or similar network errors usually mean the command must be retried with escalated permissions or outside the sandbox.
|
|
126
|
+
|
|
127
|
+
Use the same repo/context rules as other tools:
|
|
128
|
+
- If the ticket targets a `CLIENT` account, do not assume that client's repo is the implementation repo. Confirm the parent `PLATFORM` / `PRODUCT` relationship first.
|
|
129
|
+
- Read `~/.remits-cli/account-repos.json` before choosing which local repo to open.
|
|
130
|
+
- If the correct repo for the relevant account type exists locally, switch there and inspect `account-info.json` and `/components`.
|
|
131
|
+
- If the repo is not available locally, use `mcp_account_view`, `mcp_component_view`, and `mcp_component_grep`.
|
|
132
|
+
|
|
133
|
+
## Efficiency Rules
|
|
134
|
+
|
|
135
|
+
Keep support and development sessions lean:
|
|
136
|
+
|
|
137
|
+
- Prefer local repo files over remote tools whenever the target account repo exists locally.
|
|
138
|
+
- Do not read entire `.remits-cli/sessions/*.jsonl` or large tool response files unless you first narrow to the relevant request, endpoint, tool, or ticket.
|
|
139
|
+
- Prefer targeted Firestore queries: use `documentId`, tight `filters`, narrow `fields`, and low `limit` values instead of broad collection scans.
|
|
140
|
+
- Do not call `mcp_account_view` repeatedly once you already have the needed account/component context.
|
|
141
|
+
- For investigations, follow the shortest path: identify the exact document/ticket/object first, then drill in. Avoid exploratory “maybe this” queries across large collections.
|
|
142
|
+
- For ticket replies, read the current ticket state and the new reply, then continue from existing context instead of re-loading broad account state from scratch.
|
|
143
|
+
- Verification should be decisive. Avoid repeated identical test/status/tool calls when no new information is likely.
|
|
144
|
+
|
|
145
|
+
## Account Repository Index
|
|
146
|
+
|
|
147
|
+
The account repository index file is located at: `{{ACCOUNT_REPO_INDEX_PATH}}`
|
|
148
|
+
|
|
149
|
+
This JSON file is automatically maintained by `remits-cli` and tracks all known Remits account repositories on this machine. It is updated whenever any `remits-cli` command runs from an account repo directory. The file maps account IDs to their metadata:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"37": {
|
|
154
|
+
"accountId": 37,
|
|
155
|
+
"name": "Acme Corp",
|
|
156
|
+
"directory": "/Users/you/Projects/remits-acme-corp",
|
|
157
|
+
"updatedAt": "2026-03-23T12:00:00.000Z"
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Use this index to:**
|
|
163
|
+
- Discover which account repos exist on this machine when working from a different directory
|
|
164
|
+
- Navigate to another account's repo to read its `account-info.json` and component source
|
|
165
|
+
- Resolve account names and IDs without making remote API calls
|
|
166
|
+
- Support cross-account workflows where an agent in one repo needs context from another
|
|
167
|
+
|
|
168
|
+
If the index file doesn't exist yet, run any `remits-cli` command from an account repo to bootstrap it.
|
|
169
|
+
|
|
170
|
+
## Two Workflows
|
|
171
|
+
|
|
172
|
+
1. **Development** (test mode) — Build, modify, and verify components using isolated test data.
|
|
173
|
+
2. **Production Support** (prod mode) — Investigate live data, debug issues, trace execution.
|
|
174
|
+
|
|
175
|
+
Every CLI response includes `dataMode` so you always know which context you're in.
|
|
176
|
+
|
|
177
|
+
### Test Mode vs Prod Mode
|
|
178
|
+
|
|
179
|
+
Treat these as two different jobs:
|
|
180
|
+
|
|
181
|
+
- **Prod mode** is for investigation.
|
|
182
|
+
- Read live Firestore documents.
|
|
183
|
+
- Inspect live object activity, events, alerts, and logs.
|
|
184
|
+
- Confirm what actually happened to a customer.
|
|
185
|
+
- Do not use prod mode as your final verification environment for a code fix.
|
|
186
|
+
|
|
187
|
+
- **Test mode** is for verification.
|
|
188
|
+
- Stage local component changes.
|
|
189
|
+
- Run Test components.
|
|
190
|
+
- Generate token URLs and verify behavior in isolated browser flows.
|
|
191
|
+
- Confirm the fix without mutating or depending on live customer processing.
|
|
192
|
+
|
|
193
|
+
The correct support loop is usually:
|
|
194
|
+
1. Investigate in **prod mode**
|
|
195
|
+
2. Identify the responsible implementation repo and make the code change locally
|
|
196
|
+
3. Move back to **test mode** for verification
|
|
197
|
+
4. Verify with a Test component, Playwright/browser confirmation, or both
|
|
198
|
+
|
|
199
|
+
If a production issue needs realistic verification, do **not** copy live customer data from a production account into another account's test collection.
|
|
200
|
+
|
|
201
|
+
The right model is:
|
|
202
|
+
- investigate the source document in **prod mode**
|
|
203
|
+
- model the relevant conditions in a **Test** component
|
|
204
|
+
- or reproduce the scenario through a controlled **test-mode** embeddable/browser flow
|
|
205
|
+
- verify the fix there
|
|
206
|
+
|
|
207
|
+
Never treat "it looks right in prod data inspection" as sufficient proof that a code change is verified.
|
|
208
|
+
|
|
209
|
+
## Platform Mental Model: Front Stage vs Back Stage
|
|
210
|
+
|
|
211
|
+
| Layer | What It Contains | Purpose |
|
|
212
|
+
|-------|------------------|---------|
|
|
213
|
+
| **Front Stage** | Schemas, Readers, Actions, Embeddables, Rules, HtmlTemplates, Agents, Tests. Firestore **documents** are the business data (invoices, payments, vendors). | What the user sees and interacts with. Components are the building blocks; documents are the data. |
|
|
214
|
+
| **Back Stage** | Lifecycle **records**: Objects, ObjectLogs, Events, Alerts. Cloud Logging traces. | Audit trail of everything the platform executed. Used for debugging and investigation. |
|
|
215
|
+
|
|
216
|
+
### Documents vs Records
|
|
217
|
+
|
|
218
|
+
- **Documents** (Firestore) = business data. Always have `account_id`, `object_id`, `_lastModifiedAt`, `_lastModifiedBy`, `_lastModifiedOn`. Query with `mcp_firestore_search`.
|
|
219
|
+
- **Records** (MySQL) = execution audit trail, tied to `object_id`:
|
|
220
|
+
- **Object** — ingestion anchor (file, HTTP request). Has name, status, body/content.
|
|
221
|
+
- **ObjectLog** — log entries from Readers/Actions. Has `type`, `description`, `content`, `threadGroupingId`.
|
|
222
|
+
- **Event** — scheduled or executed actions. Has `action`, `status`, `eventDate`, `threadGroupingId`.
|
|
223
|
+
- **Alert** — notices (info/warning/error). Has `status`, `type`, `active`, `threadGroupingId`.
|
|
224
|
+
- Use `mcp_record_listing` when you need to find candidate records first, and `mcp_record_view` when you already have the exact record ID.
|
|
225
|
+
|
|
226
|
+
### HTTP Audits
|
|
227
|
+
|
|
228
|
+
HTTP Audits are a first-class Firestore investigation surface for raw HTTP traffic, but they are **opt-in** per account.
|
|
229
|
+
|
|
230
|
+
- The feature is controlled by `Account.enableHttpAudits`.
|
|
231
|
+
- If `enableHttpAudits` is `false`, do not expect Firestore HTTP audit documents to exist for that account.
|
|
232
|
+
- If `enableHttpAudits` is `true`, the platform writes normalized inbound and outbound HTTP audit documents to Firestore and also emits websocket `"http"` payloads using the same normalized shape.
|
|
233
|
+
|
|
234
|
+
What gets captured when enabled:
|
|
235
|
+
|
|
236
|
+
- **Inbound** HTTP handled by Readers
|
|
237
|
+
- **Outbound** HTTP made from front-stage code through the `rest(...)` DSL
|
|
238
|
+
|
|
239
|
+
Storage contract:
|
|
240
|
+
|
|
241
|
+
- HTTP audits live in monthly Firestore collections, not in one global collection.
|
|
242
|
+
- Collection path format is:
|
|
243
|
+
- `http-audits/http-audits-YYYY-MM/entries`
|
|
244
|
+
- Always start with the month that matches when the request likely ran.
|
|
245
|
+
- If the run may have crossed a month boundary, check the adjacent month collection too.
|
|
246
|
+
|
|
247
|
+
Normalized audit shape:
|
|
248
|
+
|
|
249
|
+
- top-level `timestamp`, `month`, `direction`, `transport`, `success`, `component`, `request`, `response`
|
|
250
|
+
- optional `error`, `durationMs`, `referenceId`, `category`
|
|
251
|
+
- `direction` is `INBOUND` or `OUTBOUND`
|
|
252
|
+
- `request` commonly contains `method`, `url`, `uri`, `path`, `queryString`, `headers`, `params`, `body`, `contentType`
|
|
253
|
+
- `response` commonly contains `statusCode`, `contentType`, `headers`, `body`
|
|
254
|
+
|
|
255
|
+
Investigation rules:
|
|
256
|
+
|
|
257
|
+
- Use `mcp_firestore_search` to query HTTP audits directly from Firestore when the account has `enableHttpAudits`.
|
|
258
|
+
- Prefer tight filters and low limits. Good filters include:
|
|
259
|
+
- `direction`
|
|
260
|
+
- `success`
|
|
261
|
+
- `request.method`
|
|
262
|
+
- `request.path`
|
|
263
|
+
- `component.name`
|
|
264
|
+
- `response.statusCode`
|
|
265
|
+
- Treat HTTP audits as the best source when the question is:
|
|
266
|
+
- what exact HTTP request came in
|
|
267
|
+
- what exact outbound request was sent
|
|
268
|
+
- what status code or response body came back
|
|
269
|
+
- whether a Reader or Action actually made the expected HTTP call
|
|
270
|
+
- Do not confuse HTTP audits with business documents. They are audit records stored in Firestore for investigation, not customer data collections like `invoices` or `freight_contracts`.
|
|
271
|
+
- Do not assume every HTTP call will appear. The platform intentionally excludes some paths from HTTP audit persistence, such as configured audit-exclusion endpoints.
|
|
272
|
+
|
|
273
|
+
How to combine them with the rest of the investigation stack:
|
|
274
|
+
|
|
275
|
+
- Use `mcp_firestore_search` on business collections to find the affected document.
|
|
276
|
+
- Use `object_id` to pivot into `mcp_object_activity` and lifecycle records.
|
|
277
|
+
- Use `mcp_firestore_search` on the monthly HTTP audit collection to inspect the raw HTTP request/response evidence around the same time.
|
|
278
|
+
- Use component source plus the HTTP audit payload to explain whether the problem is in request formation, partner response, or downstream document processing.
|
|
279
|
+
|
|
280
|
+
### Record `content` / Context Mental Model
|
|
281
|
+
|
|
282
|
+
When investigating lifecycle records, treat `content` as the **persisted workflow context**, not as a raw dump of everything that was in memory during execution.
|
|
283
|
+
|
|
284
|
+
- Runtime component context is the live data a component has available while it is executing.
|
|
285
|
+
- Persisted record context is the sanitized subset written to `Alert.content`, `Event.content`, `Object.content`, and `ObjectLog.content`.
|
|
286
|
+
- Persisted `content` should be assumed to be the platform's intentional investigation-friendly snapshot of that workflow step.
|
|
287
|
+
|
|
288
|
+
Understand record context this way:
|
|
289
|
+
|
|
290
|
+
- **Object.content** captures ingestion/request/file context at the time the `Object` was created or updated.
|
|
291
|
+
- **ObjectLog.content** captures `contextForSaving()` from the component that logged the object, so it reflects that component's point-in-time view of the workflow.
|
|
292
|
+
- **Event.content** captures `contextForSaving()` from the component that scheduled the event, plus explicit event options.
|
|
293
|
+
- **Alert.content** captures `contextForSaving()` from the component that raised the alert, plus explicit alert body data.
|
|
294
|
+
|
|
295
|
+
This is the key investigation question:
|
|
296
|
+
|
|
297
|
+
- not just "what keys are present?"
|
|
298
|
+
- but "what did the producing component know at that exact workflow step, and what did the platform intentionally keep for persistence?"
|
|
299
|
+
|
|
300
|
+
### Provenance Fields
|
|
301
|
+
|
|
302
|
+
Persisted record context should be read with provenance in mind:
|
|
303
|
+
|
|
304
|
+
- **`source_bcd`** = the immediate component that produced the persisted record context. Example: `[Action:18] DataPlus Invoice Posting`
|
|
305
|
+
- **`upstream_source_bcd`** = the prior workflow hop, when the current component inherited context that already had a `source_bcd`
|
|
306
|
+
- **`object_id`** = execution anchor linking documents and records
|
|
307
|
+
- **`threadGroupingId`** = processing-chain correlation key across records and system logs
|
|
308
|
+
|
|
309
|
+
Use these fields to reconstruct the path:
|
|
310
|
+
|
|
311
|
+
1. Identify the record you are inspecting.
|
|
312
|
+
2. Read `source_bcd` to determine the immediate producing component.
|
|
313
|
+
3. If present, read `upstream_source_bcd` to understand the prior workflow hop.
|
|
314
|
+
4. Use `object_id` to open the full object timeline.
|
|
315
|
+
5. Use `threadGroupingId` to correlate related events, alerts, object logs, and system logs.
|
|
316
|
+
6. Open the relevant component source to explain why that component saved that particular context.
|
|
317
|
+
|
|
318
|
+
### Why Persisted Context Looks Different From Runtime Context
|
|
319
|
+
|
|
320
|
+
Do not assume missing fields mean the component never had them in memory. Persisted context is deliberately sanitized before save:
|
|
321
|
+
|
|
322
|
+
- non-serializable runtime objects are removed
|
|
323
|
+
- configured removal keys such as `requestBody`, `params`, and `token` are removed recursively
|
|
324
|
+
- large strings may be summarized instead of stored in full
|
|
325
|
+
- oversized maps/collections may be pruned by serialization limits
|
|
326
|
+
- sensitive-looking keys such as `password`, `secret`, `authorization`, `cookie`, `clientSecret`, and similar values may be redacted
|
|
327
|
+
- Account/User schema fields marked `sensitive: true` may also be redacted before persistence
|
|
328
|
+
|
|
329
|
+
So if a user asks "why isn't the full payload here?" or "why is this value `[REDACTED]`?", the right answer is usually:
|
|
330
|
+
|
|
331
|
+
- the workflow may have had the full value at runtime
|
|
332
|
+
- the persisted record intentionally stores only the safe, investigation-friendly subset
|
|
333
|
+
|
|
334
|
+
When explaining a record, always distinguish between:
|
|
335
|
+
|
|
336
|
+
- what the workflow likely had at runtime
|
|
337
|
+
- what the platform intentionally kept in persistent `content`
|
|
338
|
+
|
|
339
|
+
### Investigation Rule for Record Context
|
|
340
|
+
|
|
341
|
+
Never interpret record `content` in isolation.
|
|
342
|
+
|
|
343
|
+
Always pair it with:
|
|
344
|
+
|
|
345
|
+
- the record type (`object`, `object_log`, `event`, `alert`)
|
|
346
|
+
- the immediate producer (`source_bcd`)
|
|
347
|
+
- the upstream producer when present (`upstream_source_bcd`)
|
|
348
|
+
- the object timeline (`object_id`)
|
|
349
|
+
- the execution chain (`threadGroupingId`)
|
|
350
|
+
- the producing component source (`mcp_component_view`, `mcp_component_grep`, or local `/components`)
|
|
351
|
+
|
|
352
|
+
The goal of an investigation is not only to find a suspicious record. It is to explain **why the context looks exactly the way it does relative to the workflow step that produced it**.
|
|
353
|
+
|
|
354
|
+
### AI Request Response Records
|
|
355
|
+
- AI activity is also persisted as `AI Request Response` records keyed by `sessionId`.
|
|
356
|
+
- In component code, use `ai_request_response([sessionId: id])` to load the stored request/response history for a session.
|
|
357
|
+
- Pass `first: true` or `last: true` when you need a single record.
|
|
358
|
+
- These records are especially useful during investigations, prompt tuning, and any workflow where you need to review a prior AI exchange or replay a stored provider response in tests.
|
|
359
|
+
- If a document or agent state already stores a session ID, treat that as a direct pivot into persisted AI session activity.
|
|
360
|
+
|
|
361
|
+
### AI Session Groupings
|
|
362
|
+
|
|
363
|
+
- For front-stage investigation and tuning work, use `mcp_ai_session_search` to search persisted AI session groupings and export grouping detail in human-readable form.
|
|
364
|
+
- This tool mirrors the admin AI Groupings UI:
|
|
365
|
+
- search filters: `search`, `sessionId`, `groupingId`, `user`, `account`, `agent`, `scope`
|
|
366
|
+
- detail/export sections: `full`, `conversation_messages`, `system`, `response`, `tools`
|
|
367
|
+
- Use it when you need to understand:
|
|
368
|
+
- what prompts, system instructions, tools, and responses were actually sent for a session
|
|
369
|
+
- how an Agent behaved across one grouping, including prompt-tuning and tool-usage opportunities
|
|
370
|
+
- whether a suspicious answer was caused by prompt design, tool definitions, missing context, or model behavior
|
|
371
|
+
- This is a front-stage builder tool, so interpret it alongside the front-stage guides:
|
|
372
|
+
- `docs/guides/components/agent-components.md` for how Agents are authored and structured
|
|
373
|
+
- `docs/guides/features/ai-support.md` for the platform AI surface (`ai()`, agent tooling, model behavior, and related patterns)
|
|
374
|
+
- Investigation rule: do not read raw AI session output in isolation. Pair it with the owning Agent component source and the AI support guide so you can explain why the session looked the way it did and where tuning should happen.
|
|
375
|
+
|
|
376
|
+
### Correlation Keys
|
|
377
|
+
|
|
378
|
+
- **`object_id`** — links documents to records. Pivot from `mcp_firestore_search` → `mcp_object_activity`.
|
|
379
|
+
- **`threadGroupingId`** — groups all records from the same processing chain. Use with `mcp_system_logs`.
|
|
380
|
+
- **`node`** → resolves to `serviceName` + `region` for log queries.
|
|
381
|
+
|
|
382
|
+
### Node Reference Table
|
|
383
|
+
|
|
384
|
+
| Node Name | Service Name | Region |
|
|
385
|
+
|---|---|---|
|
|
386
|
+
| remitsAdmin-east5 | remits | us-east5 |
|
|
387
|
+
| remitsActions | remits-actions | us-east1 |
|
|
388
|
+
| remitsAdmin | remits | us-east1 |
|
|
389
|
+
|
|
390
|
+
`mcp_system_logs` accepts `node` directly and resolves it automatically.
|
|
391
|
+
|
|
392
|
+
### Repository vs External Context
|
|
393
|
+
| Scenario | Preferred data source | When to call account/component tools |
|
|
394
|
+
|----------|----------------------|--------------------------------------|
|
|
395
|
+
| In the target account repo | Local `account-info.json` and `/components` | Only if files are missing or you need live prod insight not present locally |
|
|
396
|
+
| In Account A repo but question is for Account B | Switch to Account B repo if available; otherwise read its files from disk | If Account B repo isn't available, use `mcp_account_view`, `mcp_component_view`, `mcp_component_grep` for that account |
|
|
397
|
+
| Outside any repo | N/A | Always use the tools to load structure and source |
|
|
398
|
+
|
|
399
|
+
## Getting Started
|
|
400
|
+
|
|
401
|
+
### Authentication
|
|
402
|
+
|
|
403
|
+
Authenticate once per session. Opens the user's browser for OAuth login:
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
remits-cli auth --account-id <ACCOUNT_ID>
|
|
407
|
+
remits-cli auth --account-id <ACCOUNT_ID> --base-url http://localhost:8080
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
- `--account-id` is auto-resolved from `account-info.json` when you're inside an account repo, so you can usually just run `remits-cli auth`. Pass `--account-id <ID>` explicitly to target a different account (e.g., authenticating into a child account from a parent-account repo) — the explicit flag always wins over the repo's `account-info.json` and any prior session.
|
|
411
|
+
- `--base-url` targets a specific platform instance (e.g., localhost for development). Sessions are stored per account + base URL + data mode, so authenticating against localhost does not overwrite a production session for the same account.
|
|
412
|
+
- If any command returns a 401 error, re-run `remits-cli auth` (with the same `--base-url` if you were targeting a non-default instance).
|
|
413
|
+
|
|
414
|
+
### Data Mode
|
|
415
|
+
|
|
416
|
+
Controls whether you work with test data or production data. **Default is `test`.**
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
remits-cli data-mode # Show current mode
|
|
420
|
+
remits-cli data-mode set prod # Switch to prod for investigations
|
|
421
|
+
remits-cli data-mode set test # Switch back to test for development
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## Development Workflow
|
|
425
|
+
|
|
426
|
+
### The Golden Rule: Writing Code Is Not Finishing the Job
|
|
427
|
+
|
|
428
|
+
**A change is not complete until it is verified.** Writing or modifying a component is only the first step. You must always confirm the change actually works before telling the user it's done. There are two ways to verify:
|
|
429
|
+
|
|
430
|
+
1. **Test components** (preferred) — Write or update a Remits Test component that exercises the change. This creates a permanent regression check that protects against future breakage. Run it with `remits-cli test run`.
|
|
431
|
+
|
|
432
|
+
2. **Visual verification with Playwright** — Generate a browser URL with `remits-cli token`, then use `playwright-cli` to open the embeddable and verify the behavior visually. This is how most users think about verification — "let me see it working."
|
|
433
|
+
|
|
434
|
+
Both are valid. Use Test components when the behavior can be asserted programmatically. Use Playwright when the change is visual or when the user wants to see it. Often you'll do both.
|
|
435
|
+
|
|
436
|
+
**Never skip verification.** If the user says "just do it" or "that's fine, commit it" — verify anyway. Silent bugs erode trust. If you can't verify because there's no Test component and no relevant embeddable, tell the user what you'd need to verify and ask how they'd like to proceed.
|
|
437
|
+
|
|
438
|
+
### The Development Fast Loop
|
|
439
|
+
|
|
440
|
+
This is how every development task should flow:
|
|
441
|
+
|
|
442
|
+
#### Step 1: Understand the Request
|
|
443
|
+
Read the user's request. If you may need a repo other than the current one, read `~/.remits-cli/account-repos.json` first. Then review `account-info.json` and `README.md` to understand what components exist and how they relate. Read the source of any component you'll modify before changing it.
|
|
444
|
+
|
|
445
|
+
#### Step 2: Make the Change
|
|
446
|
+
Edit component files under `components/`. This is local file editing — the platform doesn't know about your changes yet.
|
|
447
|
+
|
|
448
|
+
#### Step 3: Stage to Platform
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
remits-cli components stage
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
This uploads your local file changes to the platform's staging cache (Redis, 240-minute TTL). It does NOT commit anything. The platform cannot see your local edits until you stage them.
|
|
455
|
+
|
|
456
|
+
**THE STAGE-BEFORE-RUN RULE:** You MUST run `remits-cli components stage` after EVERY file edit and BEFORE any test run or verification. The platform executes whatever version is in the staging cache at the moment the test starts. If you edit a file and run a test without staging first, the test runs the OLD code — not your changes. This is the single most common mistake. Never skip staging. The sequence is always: **edit → stage → run**.
|
|
457
|
+
|
|
458
|
+
This applies to:
|
|
459
|
+
- Creating new components (the platform won't find them until staged)
|
|
460
|
+
- Editing existing components (the platform runs the previously staged version until you re-stage)
|
|
461
|
+
- Every iteration of the fix loop — every edit requires a fresh stage before the next test run
|
|
462
|
+
|
|
463
|
+
#### Step 4: Verify the Change
|
|
464
|
+
|
|
465
|
+
**Option A — Run Tests** (if Test components exist for this area):
|
|
466
|
+
|
|
467
|
+
```bash
|
|
468
|
+
remits-cli test run --test <TEST_ID_OR_NAME>
|
|
469
|
+
remits-cli test run --test "Invoice Tests" --names "specific test case"
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
Tests run on the platform against your staged snapshot. They stream results in real-time. If they fail, fix the code, re-stage, and re-run.
|
|
473
|
+
|
|
474
|
+
If no relevant Test component exists yet, consider creating one. Test components live in `components/tests/` and follow the same component structure. They provide permanent regression protection — every test you write today saves debugging time tomorrow.
|
|
475
|
+
|
|
476
|
+
New test files use the `new_` prefix (e.g., `new_MyTest.groovy`). New tests have no database ID, so you must run them **by name**: `remits-cli test run --test "My Test"`. After committing, the platform assigns an ID and renames the file (e.g., `4_MyTest.groovy`) — then you can run by either ID or name.
|
|
477
|
+
|
|
478
|
+
**Option B — Visual verification with Playwright** (for UI changes or when the user wants to "see it"):
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
# Generate a browser-accessible URL for an embeddable
|
|
482
|
+
remits-cli token --path embeddable/index/<EMBEDDABLE_ID>
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
This returns an `embeddableUrl`. Use Playwright to open and interact with it:
|
|
486
|
+
|
|
487
|
+
```bash
|
|
488
|
+
# Open the embeddable in a headed browser
|
|
489
|
+
playwright-cli open --headed "<embeddableUrl>"
|
|
490
|
+
|
|
491
|
+
# Take a snapshot to see the current state
|
|
492
|
+
playwright-cli snapshot
|
|
493
|
+
|
|
494
|
+
# Interact with elements
|
|
495
|
+
playwright-cli click "text=Submit"
|
|
496
|
+
playwright-cli fill "#amount" "500.00"
|
|
497
|
+
|
|
498
|
+
# Verify specific content
|
|
499
|
+
playwright-cli eval "() => document.querySelector('.total-amount').textContent"
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
The `testMode` metadata confirms you're testing against staged changes, not production.
|
|
503
|
+
|
|
504
|
+
**Option C — Use investigation tools** (for backend/data changes):
|
|
505
|
+
|
|
506
|
+
For changes to Readers, Actions, or Rules that process data rather than display UI, verify by examining the data they produce:
|
|
507
|
+
|
|
508
|
+
```bash
|
|
509
|
+
# After triggering the component (via test or manual action), check the result
|
|
510
|
+
remits-cli tool --name "mcp_firestore_search" --input '{"accountId": <ID>, "collection": "<collection>", "limit": 5, "sort": [{"field": "_lastModifiedAt", "direction": "DESC"}]}'
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
#### Step 5: Iterate If Needed
|
|
514
|
+
|
|
515
|
+
If verification reveals issues, repeat the loop: **edit → stage → run**. Every iteration must include a fresh `remits-cli components stage` after your edits and before the next test run. Never run a test immediately after editing without staging first — the platform will execute the previous version, not your latest changes.
|
|
516
|
+
|
|
517
|
+
Don't ask the user for permission to re-iterate — just do it. Only stop to ask if you're stuck or unsure about the intended behavior.
|
|
518
|
+
|
|
519
|
+
If the work is tied to a support ticket:
|
|
520
|
+
- Use `mcp_support_ticket` to mark the ticket `in_progress` once you have started substantive work.
|
|
521
|
+
- If a new reply arrives, re-read the ticket and incorporate the reply into your current plan.
|
|
522
|
+
|
|
523
|
+
#### Step 6: Update Documentation
|
|
524
|
+
|
|
525
|
+
Before committing, update metadata so the next session understands what changed:
|
|
526
|
+
|
|
527
|
+
1. **`.meta.yml` sidecars** — Update `description` and `mermaid` for each modified component.
|
|
528
|
+
2. **`README.md`** — If the change affects account-level capabilities or workflows.
|
|
529
|
+
3. **New components** — Always fill in `.meta.yml` immediately.
|
|
530
|
+
|
|
531
|
+
`account-info.json` is read-only — never edit it. It regenerates automatically after sync.
|
|
532
|
+
|
|
533
|
+
#### Step 7: Commit and Sync
|
|
534
|
+
|
|
535
|
+
Once verified and documented:
|
|
536
|
+
|
|
537
|
+
```bash
|
|
538
|
+
git add -A
|
|
539
|
+
git commit -m "description of what changed and why"
|
|
540
|
+
git push origin <branch>
|
|
541
|
+
remits-cli components sync
|
|
542
|
+
git pull --ff-only origin <branch>
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
This separates the failure boundaries cleanly:
|
|
546
|
+
1. Local git commit
|
|
547
|
+
2. Remote push
|
|
548
|
+
3. Server sync from the git remote
|
|
549
|
+
4. Local fast-forward pull of the exact platform-generated commit, including updates such as `account-info.json`
|
|
550
|
+
|
|
551
|
+
`remits-cli components sync` is the authoritative platform-sync step. It does not perform local git operations.
|
|
552
|
+
|
|
553
|
+
The CLI now returns the post-sync branch SHA from the platform and verifies that your `git fetch` and final `git pull --ff-only` land on that exact commit. If that SHA does not match `origin/<branch>` or local `HEAD`, stop immediately and investigate the race or branch drift instead of guessing.
|
|
554
|
+
|
|
555
|
+
`remits-cli components commit` still exists as a convenience wrapper, but agents should prefer the explicit `git -> remits-cli components sync -> git pull` sequence so each phase is observable and retryable on its own.
|
|
556
|
+
|
|
557
|
+
**Git is required for durable sync.** The platform syncs by pulling from the git remote (`GitHubClient.syncFromRepository`). If `git push` fails, the server has nothing new to sync. You can still **stage** and **test** without git — only durable sync requires it.
|
|
558
|
+
|
|
559
|
+
#### Step 8: Close the Ticket
|
|
560
|
+
|
|
561
|
+
If the request came from a support ticket, the task is not complete until you update the ticket lifecycle yourself:
|
|
562
|
+
|
|
563
|
+
1. Re-read the ticket if needed to confirm the latest state and replies.
|
|
564
|
+
2. If the work is done and verified, call `mcp_support_ticket` with `complete` and include a concise resolution summary.
|
|
565
|
+
3. If you cannot finish, use `update_status` or `release` with clear notes so the next agent can continue.
|
|
566
|
+
4. Do this automatically. The human user should not need to instruct you to update the ticket.
|
|
567
|
+
|
|
568
|
+
Options:
|
|
569
|
+
```bash
|
|
570
|
+
--message "commit msg" # Commit message (default: auto-generated timestamp)
|
|
571
|
+
--allow-empty true # Allow empty git commits
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### User Confirmation Preferences
|
|
575
|
+
|
|
576
|
+
Some users want to review every change before staging. Others want you to move fast and only stop if something breaks. **Pay attention to how the user communicates:**
|
|
577
|
+
|
|
578
|
+
- If they say "just fix it" or "go ahead" — move through the loop without asking for confirmation at each step. Stage, verify, commit.
|
|
579
|
+
- If they say "show me first" or "wait before committing" — pause at the appropriate step.
|
|
580
|
+
- If they say "you don't need to ask me" or "stop asking" — remember this preference and work autonomously through the full loop.
|
|
581
|
+
|
|
582
|
+
The default should be: make the change, stage it, verify it, and present the results. Only block on the user when you're genuinely unsure about intent.
|
|
583
|
+
|
|
584
|
+
## Component Resolution: Staging Cache vs DB (which "version" actually runs)
|
|
585
|
+
|
|
586
|
+
When the platform executes a component it resolves the source from one of two places, then compiles it
|
|
587
|
+
behind an in-memory cache. Understanding this is the difference between "my change isn't working" guesses
|
|
588
|
+
and a precise diagnosis.
|
|
589
|
+
|
|
590
|
+
### The two source layers + the compile cache
|
|
591
|
+
|
|
592
|
+
1. **CLI staging cache (Redis, 240-min TTL).** Branch + user + account scoped overrides written by
|
|
593
|
+
`remits-cli components stage` and by the `mcp_component_edit` tool (`mode:'stage'`). These shadow the DB
|
|
594
|
+
source **only during CLI/test-mode execution** (see "When staged overrides apply" below).
|
|
595
|
+
2. **Database (the committed live component).** What `mcp_component_view` reads, what a pure prod run uses,
|
|
596
|
+
and what `commit` writes to.
|
|
597
|
+
3. **Compiled-closure cache (`BaseClosureDomain.CLOSURE_CACHE`).** An in-memory, **per-JVM-instance** Guava
|
|
598
|
+
cache of the parsed closure, keyed by `(componentId, type, compileSignature)`. This is why a change that
|
|
599
|
+
is correctly in the DB can still execute stale on a running instance — see "Stale after sync" below.
|
|
600
|
+
|
|
601
|
+
### Staging cache key format
|
|
602
|
+
|
|
603
|
+
```
|
|
604
|
+
account:<accountId>:cli:<cliUserId>:components:<branch>:<family>:id:<componentId>
|
|
605
|
+
account:<accountId>:cli:<cliUserId>:components:<branch>:<family>:name:<normalizedName>
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
`<family>` is the lowercased component family (`reader`, `action`, `test`, `embeddable`, ...). Both an
|
|
609
|
+
`id:` and a `name:` key are written per stage. The entry value carries: `kind` (the family), `type` (the
|
|
610
|
+
component's OWN type enum such as `ObjectType`/`RuleType`, or absent — **never** the family), `hash`,
|
|
611
|
+
`updatedAt`, and the staged content field(s) (`source`/`prompt`/`html`/`javascript`/`schema`/
|
|
612
|
+
`inputSchema`/`previewData`/`path`).
|
|
613
|
+
|
|
614
|
+
### How the platform picks staged vs DB (the compile signature)
|
|
615
|
+
|
|
616
|
+
At compile time the platform computes a **signature** that tells you which layer won:
|
|
617
|
+
|
|
618
|
+
- Staged override present → `compileSignature = "cli:<hash>"` (the staged content hash).
|
|
619
|
+
- No staged override → `compileSignature = "version:<N>"` (the DB row version).
|
|
620
|
+
|
|
621
|
+
That signature is logged. Querying for it is the single most reliable way to know what ran:
|
|
622
|
+
|
|
623
|
+
```bash
|
|
624
|
+
remits-cli tool --name mcp_system_logs --input '{"node":"remitsAdmin-east5","timeRange":"1h","filter":"textPayload:\"Using Cached BCD\""}' --data-mode prod
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
`Using Cached BCD [ID: 230, Type: Action, Signature: cli:08cc...]` → ran a **staged** override.
|
|
628
|
+
`...Signature: version:37]` → ran the **committed DB** version.
|
|
629
|
+
|
|
630
|
+
### When staged overrides apply
|
|
631
|
+
|
|
632
|
+
Staged overrides resolve **only when the execution carries a CLI TestMode** — i.e. `TestMode.branchName`
|
|
633
|
+
and `TestMode.cliUserId` are set (a `remits-cli test run`, a `mcp_run_test`, or a tokenized run minted with
|
|
634
|
+
those). A **pure production run with no TestMode always uses the DB source**, ignoring staging entirely. So
|
|
635
|
+
"I staged it but the live webhook still runs the old code" is expected — staging is a dev/verification
|
|
636
|
+
surface, not a deploy.
|
|
637
|
+
|
|
638
|
+
### Diagnosing which version is in play
|
|
639
|
+
|
|
640
|
+
- **See staging metadata for a component:** `mcp_component_view` (omit `fieldName`) returns `staging` /
|
|
641
|
+
`stagedFields`, telling you whether a staged entry exists and which fields are staged.
|
|
642
|
+
- **Inspect the raw staged entry + TTL in Redis:** use `mcp_cache`.
|
|
643
|
+
```bash
|
|
644
|
+
# find staged entries for one component
|
|
645
|
+
remits-cli tool --name mcp_cache --input '{"action":"scan","pattern":"account:52:cli:*:components:*:reader:id:181","includeValuePreview":true}' --data-mode prod
|
|
646
|
+
# dump one exact key
|
|
647
|
+
remits-cli tool --name mcp_cache --input '{"action":"inspect","key":"account:52:cli:23:components:main:reader:id:181"}' --data-mode prod
|
|
648
|
+
```
|
|
649
|
+
The preview shows `kind`/`type`/`hash`/`updatedAt` + a source snippet — confirm it's your content and
|
|
650
|
+
that `type` is NOT the family (a family value in `type` is a tool bug that crashes hydration, e.g.
|
|
651
|
+
`No enum constant ObjectType.reader`).
|
|
652
|
+
- **Confirm the DB version:** `mcp_component_view` reads the live DB source directly (no staging, no compile
|
|
653
|
+
cache), so it is the source of truth for "what was committed."
|
|
654
|
+
|
|
655
|
+
### Stage / commit / clear with the MCP tools
|
|
656
|
+
|
|
657
|
+
- `mcp_component_edit` `mode:'stage'` → writes the staging cache (Redis). `mode:'commit'` → writes the field
|
|
658
|
+
to the **live DB** and **clears** that component's staging entries. `editMode:'replace'` swaps the whole
|
|
659
|
+
field; `editMode:'targeted'` does anchor-verified line edits.
|
|
660
|
+
- `mcp_component_commit` (`read`/`commit`/`clear`) enumerates staged entries and can flush or clear them.
|
|
661
|
+
- **Commit bypasses the staged-override path entirely** (it writes the DB and clears staging), so committing
|
|
662
|
+
is the way to make a change durable and to stop a stale staged entry from shadowing the live component in
|
|
663
|
+
later test runs.
|
|
664
|
+
|
|
665
|
+
### Stale after sync / commit (the in-memory compile cache)
|
|
666
|
+
|
|
667
|
+
After a `git sync` or a `commit` updates the DB source, a **running instance can keep executing the
|
|
668
|
+
previously-compiled closure** until the version-keyed signature changes and that instance's
|
|
669
|
+
`CLOSURE_CACHE` misses (or the instance recycles). Symptoms: `mcp_component_view` shows the new source, but
|
|
670
|
+
behaviour (or a freshly-staged entry produced by an edited *tool*) still reflects the old code. This is the
|
|
671
|
+
standard Grails no-hot-reload caveat — it is environmental, not a code defect. Verify the live entry/source
|
|
672
|
+
with `mcp_cache` / `mcp_component_view`, and if a platform/tool source change must take effect immediately,
|
|
673
|
+
the platform owner recycles the instance.
|
|
674
|
+
|
|
675
|
+
## Production Support Workflow
|
|
676
|
+
|
|
677
|
+
Switch to prod mode for investigations:
|
|
678
|
+
|
|
679
|
+
```bash
|
|
680
|
+
remits-cli data-mode set prod
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
### Investigation Strategy
|
|
684
|
+
|
|
685
|
+
Before starting an investigation outside the confirmed current repo:
|
|
686
|
+
1. Read `~/.remits-cli/account-repos.json`
|
|
687
|
+
2. Switch to the best local repo candidate
|
|
688
|
+
3. Read that repo's `account-info.json`
|
|
689
|
+
4. Confirm whether you are in `CLIENT`, `PLATFORM`, or `PRODUCT` context
|
|
690
|
+
5. Then continue with the investigation flow below
|
|
691
|
+
|
|
692
|
+
**Document-First** (most common — user reports a data issue):
|
|
693
|
+
1. `mcp_account_view` — understand the account's schemas and components.
|
|
694
|
+
2. `mcp_firestore_search` — find the document, capture its `object_id`.
|
|
695
|
+
3. If the issue involves inbound or outbound HTTP behavior and the account has `enableHttpAudits`, query `http-audits/http-audits-YYYY-MM/entries` with `mcp_firestore_search`.
|
|
696
|
+
4. `mcp_object_activity` — scan the timeline for warnings, errors, unexpected events.
|
|
697
|
+
5. `mcp_record_listing` — search or filter alerts, events, object logs, or objects when you need to find the suspicious record first.
|
|
698
|
+
6. `mcp_record_view` — drill into suspicious entries for full content.
|
|
699
|
+
7. `mcp_ai_session_search` — if the workflow involves AI, inspect session groupings, prompts, tool definitions, and responses in human-readable form.
|
|
700
|
+
8. `mcp_system_logs` — correlate via `threadGroupingId` for execution traces.
|
|
701
|
+
9. `mcp_component_view`/`mcp_component_grep` — explain how the responsible component works.
|
|
702
|
+
|
|
703
|
+
**Error or Alert Investigation:**
|
|
704
|
+
1. `mcp_record_listing` — search by alert type, content, error text, action, status, `threadGroupingId`, or other exact-match record properties when you do not yet know the record ID.
|
|
705
|
+
2. `mcp_record_view` — inspect the chosen record/event/alert/object in full once you have its ID.
|
|
706
|
+
3. Use `object_id` + `threadGroupingId` to pull full timeline and logs.
|
|
707
|
+
4. Cross-check Firestore document state.
|
|
708
|
+
5. Identify `source_bcd` and any `upstream_source_bcd`.
|
|
709
|
+
6. Explain the record in terms of the workflow step that produced it, not as a generic JSON blob.
|
|
710
|
+
7. If the context looks missing, redacted, or truncated, consider sanitization rules before concluding data was never present.
|
|
711
|
+
8. If AI behavior is part of the symptom, use `mcp_ai_session_search` and compare the persisted session content against the Agent component implementation and `docs/guides/features/ai-support.md`.
|
|
712
|
+
|
|
713
|
+
### Presenting Findings
|
|
714
|
+
|
|
715
|
+
Users are not engineers. When reporting investigation results:
|
|
716
|
+
- Lead with what happened in plain language.
|
|
717
|
+
- Show the evidence (document values, timeline events, log excerpts).
|
|
718
|
+
- Explain why it happened if you can determine the cause.
|
|
719
|
+
- Recommend what to do next — in terms the user can act on.
|
|
720
|
+
|
|
721
|
+
### Verifying a Production Issue Fix
|
|
722
|
+
|
|
723
|
+
When a bug is reported from production, use this pattern:
|
|
724
|
+
|
|
725
|
+
1. Investigate the live issue in **prod mode** and identify the exact affected document IDs, collection names, account IDs, and component path.
|
|
726
|
+
2. Make the code change in the owning `PLATFORM` or `PRODUCT` repo when the defect is in shared implementation.
|
|
727
|
+
3. Verify in **test mode**, not prod.
|
|
728
|
+
4. Prefer a **Test component** when the behavior can be asserted programmatically, because that creates a durable regression suite and lets you explicitly construct the necessary data, operations, and assertions.
|
|
729
|
+
5. Use `remits-cli token` plus `playwright-cli` when the proof is visual or interaction-driven.
|
|
730
|
+
6. If useful, create or update a dedicated embeddable "playground" in test mode to reproduce the scenario in a controlled way.
|
|
731
|
+
|
|
732
|
+
Do not move production customer data into another account's test collection as a routine verification strategy. If you cannot verify with a Test component, Playwright flow, or controlled test-mode embeddable, explain the gap clearly instead of improvising with live production validation.
|
|
733
|
+
|
|
734
|
+
## Tool Reference
|
|
735
|
+
|
|
736
|
+
### Execute a Tool
|
|
737
|
+
|
|
738
|
+
```bash
|
|
739
|
+
remits-cli tool --name "mcp_firestore_search" --input '{"accountId": 37, "collection": "invoices"}' --data-mode prod
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
Response saved to `./.remits-cli/tool-responses/<callId>.json`. Read the file to see results.
|
|
743
|
+
|
|
744
|
+
**Account-id precedence for tool calls.** When the CLI and the tool input both carry an account id, the server resolves them in this order:
|
|
745
|
+
|
|
746
|
+
1. Explicit `--account-id <ID>` flag — always wins. Use this when you want to be certain the tool runs against a specific account (and the user's session covers it).
|
|
747
|
+
2. `input.accountId` (or `input.account_id`) — the tool's per-call execution target.
|
|
748
|
+
3. The current repo's `account-info.json` / active session — the default fallback.
|
|
749
|
+
|
|
750
|
+
So from inside a parent account's repo you can target a child account just by setting `input.accountId`, or force it with `--account-id` if you need it to override whatever the tool input says. Verify with the `accountId` field in the response envelope.
|
|
751
|
+
|
|
752
|
+
### `mcp_account_view`
|
|
753
|
+
Returns complete account structure — schemas, components, relationships.
|
|
754
|
+
|
|
755
|
+
| Parameter | Required | Description |
|
|
756
|
+
|-----------|----------|-------------|
|
|
757
|
+
| `accountId` | yes | Account ID |
|
|
758
|
+
|
|
759
|
+
### `mcp_firestore_search`
|
|
760
|
+
Query Firestore documents.
|
|
761
|
+
|
|
762
|
+
| Parameter | Required | Description |
|
|
763
|
+
|-----------|----------|-------------|
|
|
764
|
+
| `accountId` | yes | Account ID |
|
|
765
|
+
| `collection` | yes | Collection name (snake_case plural, e.g., `invoices`) |
|
|
766
|
+
| `documentId` | no | Fetch single document by ID |
|
|
767
|
+
| `filters` | no | `[{field, operation, value}]`. Operations: `EQUALS` (or `==`), `NOT_EQUALS` (or `!=`), `GREATER_THAN` (or `>`), `GREATER_THAN_EQUALS` (or `>=`), `LESS_THAN` (or `<`), `LESS_THAN_EQUALS` (or `<=`), `IN`, `NOT_IN`, `ARRAY_CONTAINS`, `ARRAY_CONTAINS_ANY`, `IS_NULL`, `IS_NOT_NULL`. `op` is accepted as alias for `operation`. |
|
|
768
|
+
| `sort` | no | `[{field, direction}]` — `ASC`/`DESC`. Also accepts top-level `orderBy` + `orderDirection`. |
|
|
769
|
+
| `pagination` | no | `{limit, offset}`. Default limit=25, max=200. Also accepts top-level `limit`/`offset`. |
|
|
770
|
+
| `fields` | no | Field names to return. If omitted, auto-selects up to 20 fields. |
|
|
771
|
+
| `aggregation` | no | `{sum: [...], avg: [...], min: [...], max: [...], count: true}` |
|
|
772
|
+
| `dateRanges` | no | `[{field, startDate, endDate}]` (yyyy-MM-dd) |
|
|
773
|
+
| `textSearch` | no | `[{field, prefix}]` for prefix matching |
|
|
774
|
+
|
|
775
|
+
HTTP audit usage notes:
|
|
776
|
+
|
|
777
|
+
- Use this same tool for monthly HTTP audit collections:
|
|
778
|
+
- `http-audits/http-audits-YYYY-MM/entries`
|
|
779
|
+
- Example investigation query:
|
|
780
|
+
|
|
781
|
+
```bash
|
|
782
|
+
remits-cli tool --name "mcp_firestore_search" --input '{"accountId": 37, "collection": "http-audits/http-audits-2026-05/entries", "filters": [{"field": "direction", "operation": "EQUALS", "value": "OUTBOUND"}, {"field": "request.path", "operation": "EQUALS", "value": "/api/orders"}, {"field": "success", "operation": "EQUALS", "value": false}], "sort": [{"field": "timestamp", "direction": "DESC"}], "pagination": {"limit": 10}}' --data-mode prod
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
- For Reader webhook investigations, commonly filter on:
|
|
786
|
+
- `direction = INBOUND`
|
|
787
|
+
- `request.method`
|
|
788
|
+
- `request.path`
|
|
789
|
+
- `response.statusCode`
|
|
790
|
+
- For outbound integration investigations, commonly filter on:
|
|
791
|
+
- `direction = OUTBOUND`
|
|
792
|
+
- `component.name`
|
|
793
|
+
- `request.path` or `request.url`
|
|
794
|
+
- `response.statusCode`
|
|
795
|
+
- `success`
|
|
796
|
+
|
|
797
|
+
### `mcp_object_activity`
|
|
798
|
+
Object lifecycle timeline — metadata + recent activity.
|
|
799
|
+
|
|
800
|
+
| Parameter | Required | Description |
|
|
801
|
+
|-----------|----------|-------------|
|
|
802
|
+
| `accountId` | yes | Account ID |
|
|
803
|
+
| `objectId` | yes | Object ID (from `object_id` in documents) |
|
|
804
|
+
| `activityOptions` | no | `{limit, offset, types, start, end, order}`. Default: limit=5, order=desc. Types: `OBJECT_LOG`, `EVENT`, `ALERT`. |
|
|
805
|
+
|
|
806
|
+
### `mcp_record_listing`
|
|
807
|
+
List and search lifecycle records when you do not already know the record ID.
|
|
808
|
+
|
|
809
|
+
Typical use:
|
|
810
|
+
- find active error alerts by `type` or `status`
|
|
811
|
+
- search alert/event/object_log content for an error phrase from an inbound support email
|
|
812
|
+
- narrow candidate records before switching to `mcp_record_view`
|
|
813
|
+
|
|
814
|
+
Tool ID: `88`
|
|
815
|
+
|
|
816
|
+
| Parameter | Required | Description |
|
|
817
|
+
|-----------|----------|-------------|
|
|
818
|
+
| `accountId` | yes | Account ID used for tenant scoping |
|
|
819
|
+
| `recordType` | yes | `object`, `object_log`, `event`, or `alert` |
|
|
820
|
+
| `filters` | no | Exact-match domain-property filters following the admin `listData` model, for example `status`, `type`, `active`, `threadGroupingId`, `action`, or enum fields using `_enum` |
|
|
821
|
+
| `ids` | no | Exact ID filter. Accepts a comma-separated string or array of numeric IDs |
|
|
822
|
+
| `query` | no | Lightweight text query over key searchable fields such as alert type/content/error text or object_log description/content |
|
|
823
|
+
| `page` | no | 1-based page number. Default: `1` |
|
|
824
|
+
| `pageSize` | no | Records per page. Default: `10`, max: `100` |
|
|
825
|
+
| `sort` | no | Domain property to sort by. Default: `id` |
|
|
826
|
+
| `order` | no | Sort direction: `asc` or `desc`. Default: `desc` |
|
|
827
|
+
| `includeChildren` | no | When `true`, include the specified account and child accounts |
|
|
828
|
+
| `scanLimit` | no | When using `query`, number of filtered candidate records to scan before text matching. Default: `200`, max: `500` |
|
|
829
|
+
| `maxPreviewChars` | no | Override preview length for returned content/body snippets. Max: `2048` |
|
|
830
|
+
|
|
831
|
+
### `mcp_record_view`
|
|
832
|
+
Inspect individual lifecycle records with line-range or grep.
|
|
833
|
+
|
|
834
|
+
| Parameter | Required | Description |
|
|
835
|
+
|-----------|----------|-------------|
|
|
836
|
+
| `accountId` | yes | Account ID |
|
|
837
|
+
| `recordType` | yes | `object`, `object_log`, `event`, or `alert` |
|
|
838
|
+
| `recordId` | yes | Record primary key |
|
|
839
|
+
| `field` | no | `content` (default) or `body` (objects only) |
|
|
840
|
+
| `revisionId` | no | Envers revision ID (not for object_log) |
|
|
841
|
+
| `lineRange` | no | `{start, end}` (1-based inclusive) |
|
|
842
|
+
| `grep` | no | `{pattern, caseSensitive, contextBefore, contextAfter}` |
|
|
843
|
+
|
|
844
|
+
### `mcp_ai_session_search`
|
|
845
|
+
Search AI session groupings and export grouping detail in human-readable form.
|
|
846
|
+
|
|
847
|
+
Typical use:
|
|
848
|
+
- find AI sessions by agent, user, account, session ID, or grouping ID
|
|
849
|
+
- inspect the exact prompts, system messages, tools, and responses used in a prior run
|
|
850
|
+
- identify tuning opportunities in Agent behavior by comparing session output with the front-stage guides and component source
|
|
851
|
+
|
|
852
|
+
Front-stage references:
|
|
853
|
+
- `docs/guides/components/agent-components.md`
|
|
854
|
+
- `docs/guides/features/ai-support.md`
|
|
855
|
+
|
|
856
|
+
| Parameter | Required | Description |
|
|
857
|
+
|-----------|----------|-------------|
|
|
858
|
+
| `action` | no | `search` (default) or `detail` |
|
|
859
|
+
| `search` | no | Broad text match against session IDs and grouping IDs |
|
|
860
|
+
| `sessionId` | no | Session ID filter in search mode, or grouping/session key in detail mode |
|
|
861
|
+
| `groupingId` | no | Grouping ID filter in search mode, or grouping key in detail mode |
|
|
862
|
+
| `groupingKey` | no | Preferred explicit grouping key for detail mode |
|
|
863
|
+
| `user` | no | User filter |
|
|
864
|
+
| `account` | no | Account filter |
|
|
865
|
+
| `agent` | no | Agent filter |
|
|
866
|
+
| `scope` | no | `all`, `agents`, or `internal` |
|
|
867
|
+
| `page` | no | 1-based page number. Default: `1` |
|
|
868
|
+
| `pageSize` | no | Results per page. Default: `25`, max: `100` |
|
|
869
|
+
| `recordIds` | no | Optional request/response record IDs to export from the selected grouping |
|
|
870
|
+
| `parts` | no | Export sections: `full`, `conversation_messages`, `system`, `response`, `tools` |
|
|
871
|
+
| `sections` | no | Alias for `parts` |
|
|
872
|
+
| `consolidateContext` | no | When `true`, collapses repeated XML-like prompt context into a consolidated section |
|
|
873
|
+
|
|
874
|
+
Use `action: "search"` first, then `action: "detail"` with the returned `groupingKey` when you want the human-readable export for investigation or tuning.
|
|
875
|
+
|
|
876
|
+
### `mcp_system_logs`
|
|
877
|
+
Query Cloud Run service logs.
|
|
878
|
+
|
|
879
|
+
| Parameter | Required | Description |
|
|
880
|
+
|-----------|----------|-------------|
|
|
881
|
+
| `node` | * | Node name (e.g., `remitsAdmin-east5`). Auto-resolves to serviceName+region. |
|
|
882
|
+
| `serviceName` | * | Cloud Run service. Not needed if `node` provided. |
|
|
883
|
+
| `region` | * | Cloud Run region. Not needed if `node` provided. |
|
|
884
|
+
| `timeRange` | * | Relative time: `1h`, `4h`, `30m`, `7d`. Auto-calculates startTime. |
|
|
885
|
+
| `startTime` | * | ISO 8601 timestamp. Not needed if `timeRange` provided. |
|
|
886
|
+
| `endTime` | no | ISO 8601 upper bound (defaults to now) |
|
|
887
|
+
| `severity` | no | Minimum: `INFO`, `WARNING`, `ERROR`, etc. |
|
|
888
|
+
| `threadGroupingId` | no | Filter by processing chain ID |
|
|
889
|
+
| `filter` | no | Additional Cloud Logging filter (LQL) |
|
|
890
|
+
| `pageSize` | no | Default 25, max 100. Also accepts `limit`. |
|
|
891
|
+
|
|
892
|
+
*Provide either `node` or `serviceName`+`region`. Provide either `timeRange` or `startTime`.
|
|
893
|
+
|
|
894
|
+
**Example:**
|
|
895
|
+
```json
|
|
896
|
+
{"node": "remitsAdmin-east5", "timeRange": "4h", "severity": "ERROR"}
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
### `mcp_component_view`
|
|
900
|
+
Read component field content with line numbers.
|
|
901
|
+
|
|
902
|
+
| Parameter | Required | Description |
|
|
903
|
+
|-----------|----------|-------------|
|
|
904
|
+
| `accountId` | yes | Account ID |
|
|
905
|
+
| `componentType` | yes | `Schema`, `Reader`, `Action`, `Embeddable`, `HtmlTemplate`, `Rule`, `Agent`, `Test`, `Tool`, `Prompt` |
|
|
906
|
+
| `componentId` | yes | Component ID |
|
|
907
|
+
| `fieldName` | no | `source`, `html`, `javascript`, `css`, `schema`, `description`, `mermaid`. Also accepts `field`. Omit for metadata. |
|
|
908
|
+
| `offset` | no | Start line (1-indexed). Also accepts `startLine`. |
|
|
909
|
+
| `limit` | no | Number of lines to return |
|
|
910
|
+
|
|
911
|
+
### `mcp_component_grep`
|
|
912
|
+
Search component source code with regex.
|
|
913
|
+
|
|
914
|
+
| Parameter | Required | Description |
|
|
915
|
+
|-----------|----------|-------------|
|
|
916
|
+
| `accountId` | yes | Account ID |
|
|
917
|
+
| `componentType` | yes | Component type |
|
|
918
|
+
| `pattern` | yes | Regex to search. Also accepts `searchTerm`, `query`, `search`. |
|
|
919
|
+
| `fieldName` | no | Field to search (default: `source`). Also accepts `field`. |
|
|
920
|
+
| `componentId` | no | Specific component. If omitted, searches ALL of the type. |
|
|
921
|
+
| `context` | no | Lines before AND after each match. Also accepts `contextLines`. |
|
|
922
|
+
| `caseSensitive` | no | Default: true |
|
|
923
|
+
|
|
924
|
+
### `mcp_support_ticket`
|
|
925
|
+
Create and manage the full lifecycle of account-relative `support_tickets`.
|
|
926
|
+
|
|
927
|
+
| Parameter | Required | Description |
|
|
928
|
+
|-----------|----------|-------------|
|
|
929
|
+
| `accountId` | yes | The account that owns the support ticket |
|
|
930
|
+
| `action` | yes | `create`, `read`, `accept`, `update_status`, `complete`, `release`, `record_progress`, `add_artifact`, or `get_attachment` |
|
|
931
|
+
| `ticketId` | conditional | Required for every action **except** `create` (which returns the new ticket ID) |
|
|
932
|
+
| `subject` | conditional | Short title. Required for `create`. |
|
|
933
|
+
| `type` | conditional | Required for `create`: `enhancement`, `defect`, `question`, `task`, or `incident` |
|
|
934
|
+
| `priority` | no | `low`/`medium`/`high`/`critical` for `create` (default `medium`) |
|
|
935
|
+
| `description` | no | Longer description of the request/issue for `create` |
|
|
936
|
+
| `affectedComponent` | no | Component or platform area affected (`create`) |
|
|
937
|
+
| `implementationAccountId` / `implementationAccountName` | no | Owning `PLATFORM`/`PRODUCT` account when the ticket concerns shared implementation (e.g. a back-stage platform fix) |
|
|
938
|
+
| `stepsToReproduce` / `acceptanceCriteria` / `tags` | no | Extra `create` fields for defect/enhancement tickets |
|
|
939
|
+
| `assignee` | no | Required for `accept` |
|
|
940
|
+
| `status` | no | Required for `update_status`. Valid values: `in_progress`, `pending_review` |
|
|
941
|
+
| `resolution` | no | Required for `complete` |
|
|
942
|
+
| `category` / `summary` / `details` / `findings` / `nextStep` | no | Worklog fields for `record_progress` (`category` + `summary` required) |
|
|
943
|
+
| `artifactType` / `artifactLabel` / `contentBase64` / `gcsPath` / `url` | no | Evidence fields for `add_artifact` (screenshot/trace/log/test_result/link) |
|
|
944
|
+
| `notes` | no | Optional lifecycle note stored with the ticket activity |
|
|
945
|
+
| `attachmentIndex` | no | Zero-based index of the attachment to download. Used with `get_attachment`. |
|
|
946
|
+
|
|
947
|
+
**Opening a ticket for your own work (`create`).** When you are asked to do work — or you discover a Remits **back-stage** defect while building front stage — and you were **not** handed an existing ticket, open one with `action:'create'` so the work is tracked end-to-end. For a platform fix, use `type:'defect'` (or `'enhancement'` for a gap), describe the seam and evidence, reference the fix PR, and set `implementationAccountId`/`implementationAccountName` to the owning `PLATFORM`/`PRODUCT` account.
|
|
948
|
+
|
|
949
|
+
**Attachments:** Support emails may include file attachments (screenshots, logs, documents). These are automatically extracted and stored in GCS when the email is ingested. The `read` action returns an `attachments` array on the ticket with metadata for each file (`index`, `filename`, `contentType`, `size`, `messageId`, `uploadedAt`). To retrieve the actual file content:
|
|
950
|
+
|
|
951
|
+
1. Use `read` to see the attachments list and their indices
|
|
952
|
+
2. Use `get_attachment` with the desired `attachmentIndex` to download the file content (returned base64-encoded)
|
|
953
|
+
3. If called without `attachmentIndex`, `get_attachment` lists all attachments with their indices
|
|
954
|
+
|
|
955
|
+
This keeps file retrieval self-contained — no separate download endpoint is needed.
|
|
956
|
+
|
|
957
|
+
**Recommended flow:**
|
|
958
|
+
1. `read` with the ticket's `accountId` — check ticket state and any attachments
|
|
959
|
+
2. `accept` with the ticket's `accountId`
|
|
960
|
+
3. `get_attachment` if attachments are present and relevant to the investigation
|
|
961
|
+
4. `update_status` with the ticket's `accountId`
|
|
962
|
+
5. investigate/fix/verify on the owning ticket account or its implementation account as appropriate
|
|
963
|
+
6. `complete` or `release` with the ticket's `accountId`
|
|
964
|
+
|
|
965
|
+
**Automation rule:** If a ticket is involved, you should usually:
|
|
966
|
+
- `read` at the start
|
|
967
|
+
- `accept` before substantive work
|
|
968
|
+
- `get_attachment` if there are attachments relevant to the issue (screenshots, error logs, etc.)
|
|
969
|
+
- `update_status` when actively working or blocked
|
|
970
|
+
- `complete` after verification
|
|
971
|
+
- `release` if you are handing it off or cannot continue
|
|
972
|
+
|
|
973
|
+
### `mcp_run_test`
|
|
974
|
+
Execute a Test component.
|
|
975
|
+
|
|
976
|
+
| Parameter | Required | Description |
|
|
977
|
+
|-----------|----------|-------------|
|
|
978
|
+
| `accountId` | yes | Account ID |
|
|
979
|
+
| `testId` | yes | Test component ID |
|
|
980
|
+
| `testNames` | no | Array of specific test case names |
|
|
981
|
+
|
|
982
|
+
### `mcp_component_edit`
|
|
983
|
+
Edit a component field, server-side, with stage or commit semantics. The agent counterpart to local file
|
|
984
|
+
edit → `remits-cli components stage`. Useful for components that don't live in the local repo (e.g.
|
|
985
|
+
auxiliary components). See "Component Resolution" for stage-vs-DB behavior.
|
|
986
|
+
|
|
987
|
+
| Parameter | Required | Description |
|
|
988
|
+
|-----------|----------|-------------|
|
|
989
|
+
| `accountId` | yes | Account ID of the component |
|
|
990
|
+
| `componentType` | yes | `Schema`/`Reader`/`Action`/`Embeddable`/`HtmlTemplate`/`Rule`/`Agent`/`Test`/`Tool`/`Prompt` |
|
|
991
|
+
| `componentId` | yes | Component ID |
|
|
992
|
+
| `fieldName` | yes | Field to edit (`source`, `html`, `javascript`, `schema`, `inputSchema`, `previewData`, `path`; metadata fields like `description`/`mermaid` require `mode:'commit'`) |
|
|
993
|
+
| `mode` | no | `stage` (default, Redis 240-min TTL) or `commit` (write live DB + clear staging) |
|
|
994
|
+
| `editMode` | no | `targeted` (default, anchor-verified line edit via `lineStart`/`lineEnd`/`anchorContent`/`newContent`) or `replace` (full-field `newContent`) |
|
|
995
|
+
| `auxiliary`/`category`/`partnerSlug` | no | Companion metadata applied alongside the edit |
|
|
996
|
+
|
|
997
|
+
### `mcp_component_commit`
|
|
998
|
+
Inspect, flush, or clear the CLI staging cache for components.
|
|
999
|
+
|
|
1000
|
+
| Parameter | Required | Description |
|
|
1001
|
+
|-----------|----------|-------------|
|
|
1002
|
+
| `accountId` | yes | Account ID |
|
|
1003
|
+
| `action` | yes | `read` (list staged entries), `commit` (flush staged → DB), or `clear` (drop staged entries without touching the DB) |
|
|
1004
|
+
|
|
1005
|
+
### `mcp_cache`
|
|
1006
|
+
Bounded read-only investigation of the platform Redis keyspace — the way to see exactly what a staged
|
|
1007
|
+
entry holds (and its TTL) or any other cache key. Read-only: no delete (use `mcp_component_commit clear`
|
|
1008
|
+
to remove staged entries).
|
|
1009
|
+
|
|
1010
|
+
| Parameter | Required | Description |
|
|
1011
|
+
|-----------|----------|-------------|
|
|
1012
|
+
| `action` | yes | `summary` (overview of matching keys), `scan` (paginated key list; add `includeValuePreview:true`), or `inspect` (one exact `key`) |
|
|
1013
|
+
| `pattern` | no | Redis glob for summary/scan (e.g. `account:52:cli:*:components:*:reader:id:181`). Alias: `keyPattern`/`query` |
|
|
1014
|
+
| `key` | no | Exact key for `action:'inspect'` |
|
|
1015
|
+
| `pageSize`/`sampleSize`/`previewChars` | no | Bounding controls |
|
|
1016
|
+
|
|
1017
|
+
## Multi-Session Support
|
|
1018
|
+
|
|
1019
|
+
The CLI supports multiple authenticated sessions simultaneously. Sessions are stored in `~/.remits-cli/sessions.json` as a map keyed by `accountId + dataMode + baseUrl`, so the same account can stay authenticated against both localhost and production without one session overwriting the other. When you run any command from an account repo, the CLI automatically resolves the best matching session based on the `account-info.json` in that directory and any `--base-url` or `--data-mode` flags provided.
|
|
1020
|
+
|
|
1021
|
+
```bash
|
|
1022
|
+
# Authenticate for an account (run from its repo, or pass --account-id)
|
|
1023
|
+
remits-cli auth
|
|
1024
|
+
remits-cli auth --account-id 42
|
|
1025
|
+
remits-cli auth --account-id 42 --base-url http://localhost:8080
|
|
1026
|
+
|
|
1027
|
+
# List all active sessions
|
|
1028
|
+
remits-cli sessions list
|
|
1029
|
+
|
|
1030
|
+
# Remove a session (removes all sessions for the account, or narrow with --base-url / --data-mode)
|
|
1031
|
+
remits-cli sessions remove --account-id 42
|
|
1032
|
+
remits-cli sessions remove --account-id 42 --base-url http://localhost:8080
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
You can work in multiple account repos simultaneously across different terminal windows — each uses its own session. You can also be authenticated against different base URLs (e.g., localhost for development and production) for the same account at the same time.
|
|
1036
|
+
|
|
1037
|
+
## Persistent Service, Control Center, and Agent Dispatch
|
|
1038
|
+
|
|
1039
|
+
The current mental model is a **background remits-cli service**, not just a listener.
|
|
1040
|
+
|
|
1041
|
+
That service does three jobs:
|
|
1042
|
+
- Maintains persistent WebSocket connections to the Remits platform
|
|
1043
|
+
- Manages tmux-based agent dispatch for inbound `remits-cli` support messages
|
|
1044
|
+
- Hosts a localhost browser **control center** that shows the full local integration state
|
|
1045
|
+
|
|
1046
|
+
### Starting the Service
|
|
1047
|
+
|
|
1048
|
+
```bash
|
|
1049
|
+
remits-cli start
|
|
1050
|
+
remits-cli start --foreground true
|
|
1051
|
+
remits-cli status
|
|
1052
|
+
remits-cli stop
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
Compatibility aliases still exist:
|
|
1056
|
+
|
|
1057
|
+
```bash
|
|
1058
|
+
remits-cli listen
|
|
1059
|
+
remits-cli listen status
|
|
1060
|
+
remits-cli listen stop
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
The service:
|
|
1064
|
+
- Scans the machine for `account-info.json` files and rebuilds `~/.remits-cli/account-repos.json`
|
|
1065
|
+
- Maintains one WebSocket connection per unique platform URL across all sessions
|
|
1066
|
+
- Subscribes to topics for every authenticated account
|
|
1067
|
+
- Handles `TestSuite` messages (test results) and `remits-cli` messages (agent dispatch)
|
|
1068
|
+
- Reconnects automatically if the connection drops
|
|
1069
|
+
- Uses a PID lock file (`~/.remits-cli/listener.pid`) to ensure only one service per machine
|
|
1070
|
+
- Writes `~/.remits-cli/service-state.json` so agents can discover the dashboard URL and current runtime status
|
|
1071
|
+
|
|
1072
|
+
### Control Center
|
|
1073
|
+
|
|
1074
|
+
`remits-cli start` should provide a localhost URL such as `http://127.0.0.1:8787/`.
|
|
1075
|
+
|
|
1076
|
+
The control center is the fastest way to understand the whole integration surface in one browser view. It shows:
|
|
1077
|
+
- whether the remits-cli service is running
|
|
1078
|
+
- the current dashboard URL and port
|
|
1079
|
+
- websocket connection and topic health
|
|
1080
|
+
- tmux availability, session state, and tracked panes
|
|
1081
|
+
- the discovered account repo index
|
|
1082
|
+
- the important global JSON/log files
|
|
1083
|
+
- the important per-repo remits-cli files for every indexed account repo
|
|
1084
|
+
|
|
1085
|
+
When a user asks a broad or vague question about remits-cli behavior, prefer opening or reasoning from the control center state before spelunking random files individually.
|
|
1086
|
+
|
|
1087
|
+
### Agent Dispatch
|
|
1088
|
+
|
|
1089
|
+
All dispatched agents run as **panes** within a single tmux session named `remits-listener`. This gives the user a single window where they can see and interact with all active agent workstreams side by side.
|
|
1090
|
+
|
|
1091
|
+
When a `remits-cli` WebSocket message arrives from the platform:
|
|
1092
|
+
|
|
1093
|
+
1. The message's `accountId` is used to look up the account's local directory from the account repo index
|
|
1094
|
+
2. If the message has a `ticketId` that already has an active pane, the new message is **delivered to the existing pane** (the agent receives the follow-up in-context)
|
|
1095
|
+
3. If no pane exists for the `ticketId`, a new pane is **split into the `remits-listener` tmux session**, running the preferred AI coding agent with the message prompt at the account's directory
|
|
1096
|
+
4. Panes are automatically tiled for a clean layout
|
|
1097
|
+
|
|
1098
|
+
**Ticket tracking:** Each support-ticket message should include a `ticketId`. The listener maps ticket workstreams to tmux pane IDs so follow-up messages for the same ticket are routed to the same agent session. Legacy payloads that only include `taskId` are still supported as a fallback. If the pane has been closed, a fresh pane is created.
|
|
1099
|
+
|
|
1100
|
+
**Inspecting activity:** Use `tail -f ~/.remits-cli/tmux-activity.log` to watch service start/stop, WebSocket subscriptions, ticket dispatch receipt, pane creation, follow-up delivery, and failures.
|
|
1101
|
+
|
|
1102
|
+
**Interacting with agents:** Attach to the tmux session to see all active agents:
|
|
1103
|
+
```bash
|
|
1104
|
+
tmux attach -t remits-listener
|
|
1105
|
+
```
|
|
1106
|
+
Use standard tmux navigation (`Ctrl-b` + arrow keys) to switch between panes.
|
|
1107
|
+
|
|
1108
|
+
### Configuring the Preferred Agent
|
|
1109
|
+
|
|
1110
|
+
```bash
|
|
1111
|
+
remits-cli config # Show current config
|
|
1112
|
+
remits-cli config set --agent claude # Use Claude Code (default)
|
|
1113
|
+
remits-cli config set --agent codex # Use OpenAI Codex CLI
|
|
1114
|
+
remits-cli config set --agent gemini # Use Gemini CLI
|
|
1115
|
+
```
|
|
1116
|
+
|
|
1117
|
+
The agent preference is stored in `~/.remits-cli/config.json` and applies globally.
|
|
1118
|
+
|
|
1119
|
+
## Local State Files
|
|
1120
|
+
|
|
1121
|
+
**Global** (`~/.remits-cli/`):
|
|
1122
|
+
- `sessions.json`
|
|
1123
|
+
- Source of truth for authenticated account sessions, keyed by `accountId + dataMode + baseUrl` so the same account can hold separate sessions for different environments (e.g., localhost vs production).
|
|
1124
|
+
- Each entry contains auth token, user info, websocket topic, data mode, base URL, and timestamp.
|
|
1125
|
+
- Read this when a question involves auth, account selection, websocket topic coverage, or which session a command should resolve.
|
|
1126
|
+
- `config.json`
|
|
1127
|
+
- Global CLI preferences.
|
|
1128
|
+
- Currently most important for preferred agent selection, but treat it as the general machine-level config file.
|
|
1129
|
+
- `service-state.json`
|
|
1130
|
+
- Runtime snapshot for the currently running remits-cli service.
|
|
1131
|
+
- Includes dashboard URL, chosen port, repo-discovery summary, and websocket connection state.
|
|
1132
|
+
- This is the first file to read when the user asks "is remits-cli running?", "what port is the dashboard on?", or "why isn't the browser page showing my connections?"
|
|
1133
|
+
- `account-repos.json`
|
|
1134
|
+
- Index of all known account repositories on this machine.
|
|
1135
|
+
- Built from `account-info.json` discovery plus best-effort updates when commands run inside an account repo.
|
|
1136
|
+
- This is the repo-resolution file. Read it before deciding that a repo is unavailable locally.
|
|
1137
|
+
- `listener.pid`
|
|
1138
|
+
- PID of the background remits-cli service process.
|
|
1139
|
+
- Use it only to confirm process presence; use `service-state.json` for richer service details.
|
|
1140
|
+
- `dispatch-panes.json`
|
|
1141
|
+
- Maps active ticket routing keys (`ticket:<id>` or legacy `task:<id>`) to tmux pane IDs.
|
|
1142
|
+
- Read this when follow-up messages appear to route to the wrong pane or when panes are being recreated.
|
|
1143
|
+
- `tmux-activity.log`
|
|
1144
|
+
- Human-readable chronological event log for service lifecycle, websocket events, tmux actions, and dispatch behavior.
|
|
1145
|
+
- This is usually the best forensic file for "what happened?" questions.
|
|
1146
|
+
|
|
1147
|
+
**Per-repo** (`./.remits-cli/`):
|
|
1148
|
+
- `tools/tools.json`
|
|
1149
|
+
- Cached tool definitions for this repo context.
|
|
1150
|
+
- Read this when tool availability or input shape is unclear.
|
|
1151
|
+
- `sessions/<name>.jsonl`
|
|
1152
|
+
- Repo-local HTTP request/response log for `/cli/*` calls.
|
|
1153
|
+
- Tokens are redacted and large content fields are summarized.
|
|
1154
|
+
- This is the first file to inspect when the question is "what exactly did remits-cli send or receive from this repo?"
|
|
1155
|
+
- `tool-responses/<callId>.json`
|
|
1156
|
+
- Full payload for `remits-cli tool` responses that were too large for the session log.
|
|
1157
|
+
- Prefer this over terminal summaries when investigating tool behavior.
|
|
1158
|
+
- `current-session.txt`
|
|
1159
|
+
- Pointer to the active repo-local session log name.
|
|
1160
|
+
- Always read this before opening `sessions/<name>.jsonl`.
|
|
1161
|
+
|
|
1162
|
+
Reading rules:
|
|
1163
|
+
- Read `current-session.txt` before opening a session log by name.
|
|
1164
|
+
- When a tool call says the response was stored externally, open `tool-responses/<callId>.json` instead of inferring from the terminal summary.
|
|
1165
|
+
- If a question spans both global and repo-local behavior, inspect both layers and explain which facts came from which layer.
|
|
1166
|
+
|
|
1167
|
+
## Command Reference
|
|
1168
|
+
|
|
1169
|
+
```
|
|
1170
|
+
remits-cli auth [--base-url URL] [--account-id ID] [--data-mode test|prod]
|
|
1171
|
+
remits-cli sessions [list|remove] [--account-id ID]
|
|
1172
|
+
remits-cli config [set] [--agent claude|codex|gemini]
|
|
1173
|
+
remits-cli start [--foreground true] [--port 8787]
|
|
1174
|
+
remits-cli stop
|
|
1175
|
+
remits-cli status
|
|
1176
|
+
remits-cli listen [stop|status] [--foreground true] # compatibility alias
|
|
1177
|
+
remits-cli data-mode [set test|prod]
|
|
1178
|
+
remits-cli components stage [--branch <name>] [--data-mode test|prod]
|
|
1179
|
+
remits-cli components sync [--branch <name>] [--data-mode test|prod]
|
|
1180
|
+
remits-cli components commit [--message "msg"] [--data-mode test|prod]
|
|
1181
|
+
remits-cli test run --test <id|name> [--names "a,b"] [--watch true|false] [--data-mode test|prod]
|
|
1182
|
+
remits-cli token [--path <embeddablePathOrId>] [--data-mode test|prod]
|
|
1183
|
+
remits-cli tools [--data-mode test|prod]
|
|
1184
|
+
remits-cli tool --name <toolName> [--input "{...}"] [--data-mode test|prod]
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
## Troubleshooting
|
|
1188
|
+
|
|
1189
|
+
| Symptom | Fix |
|
|
1190
|
+
|---|---|
|
|
1191
|
+
| 401 or `Not authenticated` | Run `remits-cli auth` |
|
|
1192
|
+
| `account-info.json not found` | Run from the account repo root |
|
|
1193
|
+
| Test not found (404) | New component not staged yet. Run `remits-cli components stage` first. For new tests (no ID), run by name not ID. |
|
|
1194
|
+
| Stage shows 0 updated | No changes since last stage (hash dedup) |
|
|
1195
|
+
| Test runs old code after edit | You forgot to stage. Run `remits-cli components stage` THEN re-run the test. The platform runs whatever was last staged, not your local files. |
|
|
1196
|
+
| "Git credentials" or `git push` error | Git auth is required for commit (server pulls from git remote). Fix git authentication (SSH keys or HTTPS credentials) before retrying. Staging and testing still work without git. |
|
|
1197
|
+
| 500 / `Internal Server Error` from Remits | Stop normal task work. Capture the exact command, error, and response artifact, then escalate to a Remits system admin. Do not invent a workaround. |
|
|
1198
|
+
| Tool parameters rejected | Tool schemas may be cached. Run `remits-cli tools` to refresh `.remits-cli/tools/tools.json` with latest schemas. |
|
|
1199
|
+
| Tool response missing | Check `./.remits-cli/tool-responses/` |
|
|
1200
|
+
| Staged change has no effect in a live (non-test) run | Staged overrides resolve only under a CLI TestMode (`branchName`+`cliUserId`). A pure prod run always uses the DB. `commit` to make it durable. See "Component Resolution". |
|
|
1201
|
+
| New source shown by `mcp_component_view` but old behavior persists after sync/commit | In-memory compile cache (`CLOSURE_CACHE`, version-keyed, per instance) still holds the prior closure. Environmental; the platform owner recycles the instance. |
|
|
1202
|
+
| Staged Reader test run throws `No enum constant ObjectType.<family>` | The staged entry has the component family in `type` (should be `kind`). Clear + re-stage; if it persists, the `mcp_component_edit` tool on that instance is on an old/cached version. Inspect with `mcp_cache`. |
|
|
1203
|
+
| Unsure whether a run used staged vs DB source | Query `mcp_system_logs` for `Using Cached BCD` — `Signature: cli:<hash>` = staged, `version:<N>` = DB. |
|
|
1204
|
+
| Service already running | Run `remits-cli status` to get the dashboard URL, or `remits-cli stop` before restarting. |
|
|
1205
|
+
| tmux not installed | Install tmux (`brew install tmux` on macOS). Required for agent dispatch. |
|
|
1206
|
+
| Control center URL unknown | Read `~/.remits-cli/service-state.json` or run `remits-cli status` |
|
|
1207
|
+
| Dashboard missing repos | Rebuild `~/.remits-cli/account-repos.json` with `remits-cli start` or the control center rescan action |
|
|
1208
|
+
| Agent dispatch to wrong directory | Check `~/.remits-cli/account-repos.json` has the correct directory and that you resolved the account type correctly. A `CLIENT` ticket may still belong to a parent `PLATFORM` or `PRODUCT` repo for code changes. |
|
|
1209
|
+
|
|
1210
|
+
### When Something Doesn't Work as Expected
|
|
1211
|
+
|
|
1212
|
+
All `remits-cli` capabilities (staging, test execution, committing, tool calls) have been tested and confirmed to work correctly. The most common issues are operational mistakes like forgetting to stage before running tests.
|
|
1213
|
+
|
|
1214
|
+
However, the Remits **platform itself** may have bugs or gaps that prevent certain behavior from working. If you've followed the correct workflow (edit → stage → run) and something still doesn't behave as expected after 2-3 attempts, **do not keep trying workarounds.** First decide which kind of problem it is:
|
|
1215
|
+
|
|
1216
|
+
- **A `remits-cli` / tooling operational issue** (staging, sync, dispatch, listener, the CLI itself misbehaving) → use the escalation-bundle path below and ask the user to escalate to a Remits system admin.
|
|
1217
|
+
- **A Remits back-stage platform defect or limitation** (the component runtime behaves wrong: Hibernate/session/optimistic-locking errors, detached-entity surprises, brittle lifecycle/tool behavior, a DSL method diverging from its guide) → run the **Back-Stage Escalation Workflow** below. Do **not** normalize it into a front-stage workaround.
|
|
1218
|
+
|
|
1219
|
+
Also apply the boy-scout rule to the guides themselves: **whenever you only solved the problem by reading the core back stage because a front-stage guide was unclear or missing — even if there was no platform defect at all — open a guide-only PR** updating the relevant `docs/guides/` guide so the next agent can succeed from the front stage. Better guides over time are an explicit goal.
|
|
1220
|
+
|
|
1221
|
+
#### Back-Stage Escalation Workflow (platform defect/limitation)
|
|
1222
|
+
|
|
1223
|
+
The core Remits platform repo is cloned on this machine and tracked in `~/.remits-cli/account-repos.json` under the reserved **`platform`** entry (default `~/remits`, or `REMITS_PLATFORM_DIR`). Use it:
|
|
1224
|
+
|
|
1225
|
+
1. **Analyze the back stage locally.** Open the platform repo and read every seam on the failing path — `src/main/groovy/remits/domain/BaseClosureDomain.groovy`, `src/main/groovy/remits/GormUtils.groovy`, the relevant controller/service/client, and `docs/back-stage-session-resilience.md` / `CLAUDE.md`. Map the runtime-compiled class name in any stack trace (`{componentType}_{componentId}_...`) back to the failing line, then trace it into the platform code to find the true root cause.
|
|
1226
|
+
2. **Propose the fix as a PR — and improve the guides (boy-scout rule).** Create a **feature branch** in the platform repo and open a **pull request** with the recommended back-stage fix that honors the resiliency contract (front stage stays clean; add/extend a reproducing spec or Test Account suite where it applies). The front-stage guides live in `docs/guides/` in that same repo and are the source of truth served to every account repo via `/cli/guides`, so the PR should **also** update the relevant component/feature guide whenever you had to read the back stage because the guides didn't make the answer obvious — document the new behavior for a real limitation, or fix the unclear/missing guidance even when no platform code changed (a guide bug is still a bug). **Do not merge it yourself.**
|
|
1227
|
+
3. **Raise a support ticket** with `mcp_support_ticket` `action:'create'` (`type:'defect'` for brittleness or `'enhancement'` for a gap). Include the subject, the seam, the evidence, and the PR; set `affectedComponent`, `priority`, and `implementationAccountId`/`implementationAccountName` for the owning `PLATFORM`/`PRODUCT` account. Use `record_progress`/`add_artifact` to attach the diagnosis and supporting evidence.
|
|
1228
|
+
4. **Tell the user about the PR** and the ticket so a Remits engineer can review and decide whether to approve and merge.
|
|
1229
|
+
|
|
1230
|
+
#### Escalation Bundle (tooling/operational issue)
|
|
1231
|
+
|
|
1232
|
+
1. **Create a single escalation bundle under `~/.remits-cli/issues/`.**
|
|
1233
|
+
Use a directory name like:
|
|
1234
|
+
- `~/.remits-cli/issues/<timestamp>-account-<accountId>-<short-slug>/`
|
|
1235
|
+
|
|
1236
|
+
Populate that directory with enough information that the user or a Remits system admin can continue without re-running your work. Include at minimum:
|
|
1237
|
+
- `summary.md`
|
|
1238
|
+
- What you were trying to do
|
|
1239
|
+
- Why you were trying to do it
|
|
1240
|
+
- The expected behavior
|
|
1241
|
+
- The actual behavior
|
|
1242
|
+
- The exact commands you ran, in order
|
|
1243
|
+
- The key error messages or unexpected outputs
|
|
1244
|
+
- Whether the failure blocks staging, testing, sync, ticket routing, listener dispatch, or production investigation
|
|
1245
|
+
- `context.json`
|
|
1246
|
+
- `cwd`
|
|
1247
|
+
- target repo directory
|
|
1248
|
+
- `accountId`
|
|
1249
|
+
- account name
|
|
1250
|
+
- account `type`
|
|
1251
|
+
- branch name
|
|
1252
|
+
- current data mode
|
|
1253
|
+
- ticket ID if applicable
|
|
1254
|
+
- component names / IDs involved
|
|
1255
|
+
- Copies or references for the relevant supporting artifacts:
|
|
1256
|
+
- `./.remits-cli/current-session.txt`
|
|
1257
|
+
- the active repo session log from `./.remits-cli/sessions/`
|
|
1258
|
+
- any `./.remits-cli/tool-responses/<callId>.json` files involved
|
|
1259
|
+
- `~/.remits-cli/account-repos.json` if repo resolution may be relevant
|
|
1260
|
+
- `~/.remits-cli/tmux-activity.log` if listener / websocket / dispatch behavior may be relevant
|
|
1261
|
+
|
|
1262
|
+
2. **Use the global Remits CLI state to make the bundle self-contained.**
|
|
1263
|
+
- Read `./.remits-cli/current-session.txt` to identify the active repo session log.
|
|
1264
|
+
- Record the exact repo directory and account context from `account-info.json`.
|
|
1265
|
+
- If repo selection or account targeting may be part of the issue, include the relevant entry from `~/.remits-cli/account-repos.json`.
|
|
1266
|
+
- If the problem involves support-ticket delivery, tmux panes, or websocket events, include the relevant lines from `~/.remits-cli/tmux-activity.log`.
|
|
1267
|
+
- If a tool call stored its full response externally, include that file path and summarize the important fields in `summary.md`.
|
|
1268
|
+
|
|
1269
|
+
3. **Stop and document the issue clearly for the user.**
|
|
1270
|
+
Tell the user where the escalation bundle lives and summarize:
|
|
1271
|
+
- what was attempted
|
|
1272
|
+
- what should have happened
|
|
1273
|
+
- what actually happened
|
|
1274
|
+
- why this appears to require a Remits system admin
|
|
1275
|
+
|
|
1276
|
+
4. **Ask the user to escalate to a Remits system admin.** The system admin has access to the Remits platform codebase and the `remits-cli` source code, and can diagnose and fix platform-level issues directly.
|
|
1277
|
+
|
|
1278
|
+
5. **Do not attempt creative workarounds** (renaming components, duplicating files, bypassing the CLI with raw API calls, etc.). If the platform has a real bug, workarounds mask the problem and make it harder to diagnose. It is better to have the issue fixed at the source than to build fragile workarounds around it.
|