@remits/remits-cli 0.1.80 → 0.1.81

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/index.js CHANGED
@@ -413,6 +413,18 @@ function writeToolResponseFile(cwd, callId, responsePayload) {
413
413
  return file;
414
414
  }
415
415
 
416
+ function readToolResponseFile(cwd, callId) {
417
+ if (!callId) return null;
418
+ const paths = ensureLocalState(cwd);
419
+ const file = path.join(paths.toolResponsesDir, callId + '.json');
420
+ if (!fs.existsSync(file)) return null;
421
+ try {
422
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
423
+ } catch (_) {
424
+ return null;
425
+ }
426
+ }
427
+
416
428
  function normalizeName(name) {
417
429
  return name.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/\s+/g, ' ').trim();
418
430
  }
@@ -1191,9 +1203,14 @@ function collectComponents(cwd) {
1191
1203
  return components;
1192
1204
  }
1193
1205
 
1194
- function buildAxios(baseUrl, token) {
1206
+ function parsePositiveInt(value, fallback) {
1207
+ const parsed = Number(value);
1208
+ return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
1209
+ }
1210
+
1211
+ function buildAxios(baseUrl, token, timeoutMs = 60000) {
1195
1212
  const headers = token ? { Authorization: 'Bearer ' + token } : {};
1196
- return axios.create({ baseURL: baseUrl, timeout: 60000, headers });
1213
+ return axios.create({ baseURL: baseUrl, timeout: parsePositiveInt(timeoutMs, 60000), headers });
1197
1214
  }
1198
1215
 
1199
1216
  function describeError(err) {
@@ -1934,6 +1951,37 @@ async function waitForStatus(api, cwd, accountId, branchName, taskId, token, dat
1934
1951
  }
1935
1952
  }
1936
1953
 
1954
+ async function waitForToolStatus(api, cwd, options) {
1955
+ const started = Date.now();
1956
+ let pollDelayMs = parsePositiveInt(options.pollIntervalMs, 1000);
1957
+ const maxPollDelayMs = parsePositiveInt(options.maxPollIntervalMs, 5000);
1958
+ const deadline = options.waitTimeoutMs ? (started + parsePositiveInt(options.waitTimeoutMs, 0)) : null;
1959
+
1960
+ while (true) {
1961
+ const statusResponse = await loggedPost(api, cwd, '/cli/tool', {
1962
+ token: options.token,
1963
+ command: 'status',
1964
+ accountId: options.accountId,
1965
+ accountIdExplicit: options.accountIdExplicit,
1966
+ branchName: options.branchName,
1967
+ dataMode: options.dataMode,
1968
+ callId: options.callId
1969
+ }, { toolResponseFile: true, toolCallId: options.callId });
1970
+
1971
+ const status = statusResponse.data;
1972
+ if (status.status === 'completed' || status.status === 'failed') {
1973
+ return { data: status, responseFile: statusResponse.responseFile };
1974
+ }
1975
+
1976
+ if (deadline && Date.now() >= deadline) {
1977
+ throw new Error('Timed out waiting for async tool call ' + options.callId + ' after ' + (Date.now() - started) + 'ms');
1978
+ }
1979
+
1980
+ await new Promise((r) => setTimeout(r, pollDelayMs));
1981
+ pollDelayMs = Math.min(maxPollDelayMs, pollDelayMs + 500);
1982
+ }
1983
+ }
1984
+
1937
1985
  function watchWebsocket(baseUrl, topicId, taskId) {
1938
1986
  const client = new Client({
1939
1987
  brokerURL: webSocketUrl(baseUrl),
@@ -2130,8 +2178,10 @@ async function toolCommand(flags) {
2130
2178
  const sessionContext = resolveSessionContext(cwd, flags);
2131
2179
  const { session, accountId } = sessionContext;
2132
2180
 
2181
+ const subcommand = flags._ && flags._[1];
2182
+ const statusMode = subcommand === 'status' || flagEnabled(flags.status);
2133
2183
  const toolName = flags.name || flags.tool;
2134
- if (!toolName) {
2184
+ if (!toolName && !statusMode) {
2135
2185
  throw new Error('Missing --name <toolName>');
2136
2186
  }
2137
2187
 
@@ -2144,8 +2194,48 @@ async function toolCommand(flags) {
2144
2194
  const baseUrl = flags['base-url'] || session.baseUrl || DEFAULT_BASE_URL;
2145
2195
  const branchName = flags.branch || currentBranch(cwd);
2146
2196
  const dataMode = resolveDataMode(flags, session);
2147
- const callId = crypto.randomUUID();
2148
- const api = buildAxios(baseUrl, session.token);
2197
+ const timeoutMs = parsePositiveInt(flags['timeout-ms'] || flags.timeoutMs, 60000);
2198
+ const callId = String(flags['call-id'] || flags.callId || crypto.randomUUID());
2199
+ const asyncMode = flagEnabled(flags.async) || flagEnabled(input.async);
2200
+ const waitForAsync = flagEnabled(flags.wait);
2201
+ const pollIntervalMs = parsePositiveInt(flags['poll-interval-ms'] || flags.pollIntervalMs, 1000);
2202
+ const waitTimeoutMs = flags['wait-timeout-ms'] || flags.waitTimeoutMs;
2203
+ const api = buildAxios(baseUrl, session.token, timeoutMs);
2204
+
2205
+ if (statusMode) {
2206
+ const requestedCallId = String(flags['call-id'] || flags.callId || '');
2207
+ if (!requestedCallId) {
2208
+ throw new Error('Missing --call-id <callId>');
2209
+ }
2210
+
2211
+ const stored = readToolResponseFile(cwd, requestedCallId);
2212
+ const statusAccountId = flags['account-id'] || (stored && stored.accountId) || accountId;
2213
+ const statusResponse = await loggedPost(api, cwd, '/cli/tool', {
2214
+ token: session.token,
2215
+ command: 'status',
2216
+ accountId: statusAccountId,
2217
+ accountIdExplicit: accountIdExplicit || Boolean(stored && stored.accountId),
2218
+ branchName: flags.branch || (stored && stored.branchName) || branchName,
2219
+ dataMode: flags['data-mode'] || (stored && stored.dataMode) || dataMode,
2220
+ callId: requestedCallId
2221
+ }, { toolResponseFile: true, toolCallId: requestedCallId });
2222
+
2223
+ const data = statusResponse.data;
2224
+ if (!data.success) {
2225
+ throw new Error(data.message || 'Tool status lookup failed');
2226
+ }
2227
+
2228
+ printSessionResolutionWarning(sessionContext);
2229
+ printResolvedBaseUrl(baseUrl);
2230
+ console.log('Tool call status:', data.status);
2231
+ console.log('Call ID:', requestedCallId);
2232
+ console.log('Data mode:', data.dataMode || dataMode);
2233
+ if (data.threadGroupingId) console.log('Thread grouping ID:', data.threadGroupingId);
2234
+ console.log('Session log:', sessionJsonlFile(cwd));
2235
+ console.log('Tool response file:', statusResponse.responseFile);
2236
+ if (data.status === 'failed') process.exitCode = 1;
2237
+ return;
2238
+ }
2149
2239
 
2150
2240
  const response = await loggedPost(api, cwd, '/cli/tool', {
2151
2241
  token: session.token,
@@ -2155,7 +2245,8 @@ async function toolCommand(flags) {
2155
2245
  dataMode,
2156
2246
  name: String(toolName),
2157
2247
  input,
2158
- callId
2248
+ callId,
2249
+ async: asyncMode
2159
2250
  }, { toolResponseFile: true, toolCallId: callId });
2160
2251
 
2161
2252
  const data = response.data;
@@ -2165,9 +2256,11 @@ async function toolCommand(flags) {
2165
2256
 
2166
2257
  printSessionResolutionWarning(sessionContext);
2167
2258
  printResolvedBaseUrl(baseUrl);
2168
- console.log('Tool call succeeded.');
2259
+ console.log(asyncMode ? 'Tool call started.' : 'Tool call succeeded.');
2169
2260
  console.log('Call ID:', callId);
2170
- console.log('Data mode:', dataMode);
2261
+ console.log('Data mode:', data.dataMode || dataMode);
2262
+ if (data.status) console.log('Status:', data.status);
2263
+ if (data.threadGroupingId) console.log('Thread grouping ID:', data.threadGroupingId);
2171
2264
  // Make the resolved component version explicit so callers never assume staged vs DB.
2172
2265
  if (data.componentSource) {
2173
2266
  const sig = data.componentSignature ? ` (${data.componentSignature})` : '';
@@ -2175,6 +2268,25 @@ async function toolCommand(flags) {
2175
2268
  }
2176
2269
  console.log('Session log:', sessionJsonlFile(cwd));
2177
2270
  console.log('Tool response file:', response.responseFile);
2271
+
2272
+ if (asyncMode && waitForAsync) {
2273
+ const finalStatus = await waitForToolStatus(api, cwd, {
2274
+ token: session.token,
2275
+ accountId: data.accountId || accountId,
2276
+ accountIdExplicit: true,
2277
+ branchName: data.branchName || branchName,
2278
+ dataMode: data.dataMode || dataMode,
2279
+ callId,
2280
+ pollIntervalMs,
2281
+ waitTimeoutMs
2282
+ });
2283
+
2284
+ console.log('Final status:', finalStatus.data.status);
2285
+ console.log('Tool response file:', finalStatus.responseFile);
2286
+ if (finalStatus.data.status !== 'completed') {
2287
+ process.exitCode = 1;
2288
+ }
2289
+ }
2178
2290
  }
2179
2291
 
2180
2292
  async function dataModeCommand(flags, subcommand) {
@@ -4550,7 +4662,8 @@ async function main() {
4550
4662
  console.log(' remits-cli data-mode [set test|prod]');
4551
4663
  console.log(' remits-cli install --skills [--target codex|claude|gemini|all] [--overwrite true]');
4552
4664
  console.log(' remits-cli tools [--base-url URL] [--account-id ID] [--data-mode test|prod]');
4553
- console.log(' remits-cli tool --name <toolName> [--base-url URL] [--input \"{...}\"|--input-file file.json] [--data-mode test|prod]');
4665
+ console.log(' remits-cli tool --name <toolName> [--base-url URL] [--input \"{...}\"|--input-file file.json] [--data-mode test|prod] [--timeout-ms 60000] [--async true --wait true]');
4666
+ console.log(' remits-cli tool status --call-id <callId> [--base-url URL] [--account-id ID] [--data-mode test|prod]');
4554
4667
  console.log(' remits-cli components stage [--base-url URL] [--account-id ID] [--branch BRANCH] [--data-mode test|prod] [--json|--verbose]');
4555
4668
  console.log(' remits-cli components status [--base-url URL] [--account-id ID] [--branch BRANCH] [--component-type TYPE --component-id ID] [--json|--verbose]');
4556
4669
  console.log(' remits-cli components clear [--base-url URL] [--account-id ID] [--branch BRANCH] [--component-type TYPE] [--component-id ID] [--all] [--json|--verbose]');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remits/remits-cli",
3
- "version": "0.1.80",
3
+ "version": "0.1.81",
4
4
  "description": "Local CLI for auth, component sync, and live test execution against Remits",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -5,6 +5,85 @@ description: Use remits-cli for fast branch-scoped component staging, test execu
5
5
 
6
6
  # remits-cli
7
7
 
8
+ ## Table of Contents
9
+
10
+ - Line 89: Account Targeting Model
11
+ - Line 112: Component Integrity Rules: Repo ↔ Database Reconciliation (read before any sync/commit)
12
+ - Line 118: How the platform reconciles the repo into the database (the mechanism you must understand)
13
+ - Line 144: The surfaces and their intended behavior
14
+ - Line 166: Intended workflows
15
+ - Line 185: Pre-sync safety check (confirm ALL before `components sync` or `components commit`)
16
+ - Line 195: If something looks wrong — stop, don't paper over
17
+ - Line 219: Required Local Index Reads
18
+ - Line 253: Big Picture: How remits-cli State Is Organized
19
+ - Line 283: Support Ticket Mental Model
20
+ - Line 319: Efficiency Rules
21
+ - Line 331: Account Repository Index
22
+ - Line 356: Two Workflows
23
+ - Line 363: Test Mode vs Prod Mode
24
+ - Line 395: Platform Mental Model: Front Stage vs Back Stage
25
+ - Line 402: Documents vs Records
26
+ - Line 412: HTTP Audits
27
+ - Line 466: Record `content` / Context Mental Model
28
+ - Line 486: Provenance Fields
29
+ - Line 504: Why Persisted Context Looks Different From Runtime Context
30
+ - Line 525: Investigation Rule for Record Context
31
+ - Line 540: AI Request Response Records
32
+ - Line 547: AI Session Groupings
33
+ - Line 562: Correlation Keys
34
+ - Line 568: Node Reference Table
35
+ - Line 578: Repository vs External Context
36
+ - Line 585: Getting Started
37
+ - Line 587: Authentication
38
+ - Line 600: Host vs Data Mode
39
+ - Line 619: Tool Execution Lifecycle
40
+ - Line 660: Data Mode
41
+ - Line 670: Development Workflow
42
+ - Line 672: The Golden Rule: Writing Code Is Not Finishing the Job
43
+ - Line 684: The Development Fast Loop
44
+ - Line 843: User Confirmation Preferences
45
+ - Line 853: Component Resolution: Staging Cache vs DB (which "version" actually runs)
46
+ - Line 859: The two source layers + the compile cache
47
+ - Line 870: Staging cache key format
48
+ - Line 883: How the platform picks staged vs DB (the compile signature)
49
+ - Line 900: When staged overrides apply
50
+ - Line 924: Diagnosing which version is in play
51
+ - Line 945: Stage / commit / clear with the MCP tools
52
+ - Line 969: Stale after sync / commit (the in-memory compile cache)
53
+ - Line 979: Production Support Workflow
54
+ - Line 987: Investigation Strategy
55
+ - Line 1017: Presenting Findings
56
+ - Line 1025: Verifying a Production Issue Fix
57
+ - Line 1038: Tool Reference
58
+ - Line 1040: Execute a Tool
59
+ - Line 1067: `mcp_account_view`
60
+ - Line 1074: `mcp_firestore_search`
61
+ - Line 1112: `mcp_object_activity`
62
+ - Line 1121: `mcp_record_listing`
63
+ - Line 1146: `mcp_record_view`
64
+ - Line 1159: `mcp_ai_session_search`
65
+ - Line 1191: `mcp_run_action`
66
+ - Line 1229: `mcp_run_agent`
67
+ - Line 1267: `mcp_system_logs`
68
+ - Line 1290: `mcp_component_view`
69
+ - Line 1308: `mcp_component_grep`
70
+ - Line 1321: `mcp_support_ticket`
71
+ - Line 1370: `mcp_run_test`
72
+ - Line 1379: `mcp_component_edit`
73
+ - Line 1394: `mcp_component_create`
74
+ - Line 1408: `mcp_component_commit`
75
+ - Line 1416: `mcp_cache`
76
+ - Line 1428: Multi-Session Support
77
+ - Line 1448: Persistent Service, Control Center, and Agent Dispatch
78
+ - Line 1457: Starting the Service
79
+ - Line 1483: Control Center
80
+ - Line 1498: Agent Dispatch
81
+ - Line 1519: Configuring the Preferred Agent
82
+ - Line 1530: Local State Files
83
+ - Line 1578: Command Reference
84
+ - Line 1605: Troubleshooting
85
+ - Line 1632: When Something Doesn't Work as Expected
86
+
8
87
  `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
88
 
10
89
  ## Account Targeting Model
@@ -537,6 +616,47 @@ remits-cli tool --base-url http://localhost:8080 --name mcp_account_view --data-
537
616
 
538
617
  Do not assume `--data-mode prod` implies the deployed prod host, or that `--data-mode test` implies localhost. If host matters, read `~/.remits-cli/sessions.json` first and pass `--base-url` explicitly.
539
618
 
619
+ ### Tool Execution Lifecycle
620
+
621
+ `remits-cli tool` supports both synchronous and asynchronous execution.
622
+
623
+ Use normal synchronous execution for quick investigation tools:
624
+
625
+ ```bash
626
+ remits-cli tool --name "mcp_account_view" --input '{"accountId": 37}' --data-mode prod
627
+ ```
628
+
629
+ Use asynchronous execution for long-running tools, especially Action or Agent runners that can perform OCR,
630
+ AI calls, document writes, or multi-step workflows:
631
+
632
+ ```bash
633
+ remits-cli tool --name "mcp_run_action" --async true --input '{"accountId":49,"actionId":200,"executionMode":"async","actionInput":{"sourceDocumentId":"..."}}' --data-mode prod
634
+ ```
635
+
636
+ Async starts return immediately with a stable `callId`, `status:"running"`, `threadGroupingId`,
637
+ `accountId`, `branchName`, `dataMode`, and component provenance when available. The full response is saved to:
638
+
639
+ ```text
640
+ ./.remits-cli/tool-responses/<callId>.json
641
+ ```
642
+
643
+ Poll or resume an async CLI tool call by call id:
644
+
645
+ ```bash
646
+ remits-cli tool status --call-id <callId> --data-mode prod
647
+ ```
648
+
649
+ If you want the CLI process to wait locally while using short polling requests instead of one long HTTP
650
+ request, pass `--wait true`:
651
+
652
+ ```bash
653
+ remits-cli tool --name "mcp_run_agent" --async true --wait true --input '{"accountId":49,"agentName":"InvoiceAuditor","message":"...","executionMode":"async"}' --data-mode prod
654
+ ```
655
+
656
+ `--timeout-ms <ms>` controls the HTTP timeout for each individual CLI request. It is useful for slower
657
+ synchronous tools, but for multi-minute Actions/Agents prefer `--async true` so the server-side work is not
658
+ tied to one HTTP connection.
659
+
540
660
  ### Data Mode
541
661
 
542
662
  Controls whether you work with test data or production data. **Default is `test`.**
@@ -640,6 +760,13 @@ For changes to Readers, Actions, or Rules that process data rather than display
640
760
  remits-cli tool --name "mcp_firestore_search" --input '{"accountId": <ID>, "collection": "<collection>", "limit": 5, "sort": [{"field": "_lastModifiedAt", "direction": "DESC"}]}'
641
761
  ```
642
762
 
763
+ For long-running backend verification, prefer async tool execution and poll by `callId` rather than relying on
764
+ a single request to stay open:
765
+
766
+ ```bash
767
+ remits-cli tool --name "mcp_run_action" --async true --wait true --input '{"accountId": <ID>, "actionId": <ACTION_ID>, "executionMode": "async", "actionInput": {...}}' --data-mode test
768
+ ```
769
+
643
770
  #### Step 5: Iterate If Needed
644
771
 
645
772
  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.
@@ -918,6 +1045,17 @@ remits-cli tool --name "mcp_firestore_search" --input '{"accountId": 37, "collec
918
1045
 
919
1046
  Response saved to `./.remits-cli/tool-responses/<callId>.json`. Read the file to see results.
920
1047
 
1048
+ For long-running tools, use async mode:
1049
+
1050
+ ```bash
1051
+ remits-cli tool --name "mcp_run_action" --async true --input '{"accountId":37,"actionName":"Rebuild Invoice","executionMode":"async","actionInput":{"invoiceId":"abc"}}' --data-mode prod
1052
+ remits-cli tool status --call-id <callId> --data-mode prod
1053
+ ```
1054
+
1055
+ Use `--wait true` when you want the CLI to poll until completion and still avoid a single long HTTP request.
1056
+ Use `--timeout-ms <ms>` only to adjust the per-request client timeout; it is not a replacement for async mode
1057
+ on multi-minute workflows.
1058
+
921
1059
  **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:
922
1060
 
923
1061
  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).
@@ -1050,6 +1188,82 @@ Front-stage references:
1050
1188
 
1051
1189
  Use `action: "search"` first, then `action: "detail"` with the returned `groupingKey` when you want the human-readable export for investigation or tuning.
1052
1190
 
1191
+ ### `mcp_run_action`
1192
+ Run an Action on a target account, with explicit prod/test data mode, optional staged branch resolution, and
1193
+ staged-vs-DB provenance in the result.
1194
+
1195
+ Use direct mode only for quick Actions:
1196
+
1197
+ ```bash
1198
+ remits-cli tool --name mcp_run_action --input '{"accountId":49,"actionId":200,"executionMode":"direct","actionInput":{"sourceDocumentId":"..."}}' --data-mode prod
1199
+ ```
1200
+
1201
+ Use async mode for long-running direct Action execution:
1202
+
1203
+ ```bash
1204
+ remits-cli tool --name mcp_run_action --async true --input '{"accountId":49,"actionId":200,"executionMode":"async","actionRunId":"optional-stable-id","actionInput":{"sourceDocumentId":"..."}}' --data-mode prod
1205
+ ```
1206
+
1207
+ Then poll the CLI call:
1208
+
1209
+ ```bash
1210
+ remits-cli tool status --call-id <callId> --data-mode prod
1211
+ ```
1212
+
1213
+ Or poll the tool-level run from another tool/agent context:
1214
+
1215
+ ```json
1216
+ {"command":"status","accountId":49,"actionRunId":"<actionRunId>"}
1217
+ ```
1218
+
1219
+ For job-style Actions (`Action.job == true`), prefer `executionMode:"event"` when you want the durable Event
1220
+ lifecycle, Event status, and platform recovery behavior:
1221
+
1222
+ ```json
1223
+ {"accountId":49,"actionId":200,"executionMode":"event","actionInput":{...}}
1224
+ ```
1225
+
1226
+ Key returned fields: `actionRunId`, `status`, `executionMode`, `threadGroupingId`, `eventId`/`eventStatus`
1227
+ for Event mode, `componentSource`, `componentSignature`, `result`, `message`, and `error`.
1228
+
1229
+ ### `mcp_run_agent`
1230
+ Run one real Agent turn on a target account. The Agent hooks and tools execute for real against the requested
1231
+ `dataMode`; pass `dataMode:"test"` for safer tuning.
1232
+
1233
+ Use direct mode only for short turns:
1234
+
1235
+ ```bash
1236
+ remits-cli tool --name mcp_run_agent --input '{"accountId":49,"agentName":"InvoiceAuditor","message":"Summarize this invoice context","executionMode":"direct"}' --data-mode prod
1237
+ ```
1238
+
1239
+ Use async mode for autonomous or long Agent turns. Async mode returns both an `agentRunId` and a concrete
1240
+ `sessionId` immediately:
1241
+
1242
+ ```bash
1243
+ remits-cli tool --name mcp_run_agent --async true --input '{"accountId":49,"agentName":"InvoiceAuditor","message":"Audit this invoice","executionMode":"async","context":{"invoiceId":"..."}}' --data-mode prod
1244
+ ```
1245
+
1246
+ Poll the CLI call:
1247
+
1248
+ ```bash
1249
+ remits-cli tool status --call-id <callId> --data-mode prod
1250
+ ```
1251
+
1252
+ Or poll the tool-level agent run:
1253
+
1254
+ ```json
1255
+ {"command":"status","accountId":49,"agentRunId":"<agentRunId>"}
1256
+ ```
1257
+
1258
+ Inspect the AI session while it is running or after it completes:
1259
+
1260
+ ```bash
1261
+ remits-cli tool --name mcp_ai_session_search --input '{"action":"detail","sessionId":"<sessionId>","summaryOnly":true}' --data-mode prod
1262
+ ```
1263
+
1264
+ Key returned fields: `agentRunId`, `sessionId`, `status`, `threadGroupingId`, runtime pause/interruption
1265
+ hints, `lastAssistantMessage`, `toolCallCount`, `result`, `message`, and `error`.
1266
+
1053
1267
  ### `mcp_system_logs`
1054
1268
  Query Cloud Run service logs.
1055
1269
 
@@ -1380,7 +1594,8 @@ remits-cli components commit [--message "msg"] [--data-mode test|prod]
1380
1594
  remits-cli test run --test <id|name> [--names "a,b"] [--watch true|false] [--data-mode test|prod]
1381
1595
  remits-cli token [--path <embeddablePathOrId>] [--data-mode test|prod]
1382
1596
  remits-cli tools [--branch <name>] [--data-mode test|prod]
1383
- remits-cli tool --name <toolName> [--branch <name>] [--input "{...}"] [--data-mode test|prod]
1597
+ remits-cli tool --name <toolName> [--branch <name>] [--input "{...}"] [--data-mode test|prod] [--timeout-ms 60000] [--async true --wait true]
1598
+ remits-cli tool status --call-id <callId> [--data-mode test|prod]
1384
1599
  ```
1385
1600
 
1386
1601
  For tests specifically:
@@ -1402,6 +1617,8 @@ For tests specifically:
1402
1617
  | 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. |
1403
1618
  | Tool parameters rejected | Tool schemas may be cached. Run `remits-cli tools` to refresh `.remits-cli/tools/tools.json` with latest schemas. |
1404
1619
  | Tool response missing | Check `./.remits-cli/tool-responses/` |
1620
+ | Long-running tool times out | Prefer `remits-cli tool --async true` and poll with `remits-cli tool status --call-id <callId>`. Use `--timeout-ms` only for the per-request HTTP timeout. |
1621
+ | Need to continue tracking a long Action or Agent after terminal disconnect | Read `./.remits-cli/tool-responses/<callId>.json` for the returned `threadGroupingId`, `actionRunId`, `agentRunId`, or `sessionId`, then poll status or inspect with `mcp_ai_session_search`. |
1405
1622
  | Staged change has no effect in a live (non-CLI) run | Staged overrides resolve only under a CLI TestMode (`branchName`+`cliUserId`). Live webhooks and other non-CLI runtime paths still use the DB. `commit` to make it durable. See "Component Resolution". |
1406
1623
  | New source shown by `mcp_component_view` but old behavior persists after sync/commit | The compile cache (`CLOSURE_CACHE`) is keyed by `version:<N>:<sourceHash12>`, so a source change on the same version now invalidates it automatically — a run right after sync/commit picks up the new source. If old behavior still persists, confirm the run actually hit the synced instance and that no staged override is still shadowing DB (`remits-cli components status`). |
1407
1624
  | 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`. |