@remits/remits-cli 0.1.89 → 0.1.90
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 +33 -2
- package/package.json +1 -1
- package/skills/remits-cli/SKILL.md +40 -11
package/index.js
CHANGED
|
@@ -268,6 +268,19 @@ function printResolvedBaseUrl(baseUrl) {
|
|
|
268
268
|
console.log('Base URL:', normalizeBaseUrl(baseUrl || DEFAULT_BASE_URL));
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
+
// A tool's OWN verdict, which is separate from whether the call was dispatched. Only an explicit
|
|
272
|
+
// failure signal counts: tools legitimately return strings, arrays, and maps with no `success` key.
|
|
273
|
+
// Used as a fallback when the platform build predates the envelope's `toolSuccess`.
|
|
274
|
+
function toolResultFailed(result) {
|
|
275
|
+
if (!result || typeof result !== 'object' || Array.isArray(result)) return false;
|
|
276
|
+
return result.success === false || result.is_error === true;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function toolResultMessage(result) {
|
|
280
|
+
if (!toolResultFailed(result)) return null;
|
|
281
|
+
return result.message || result.error || 'The tool returned an error';
|
|
282
|
+
}
|
|
283
|
+
|
|
271
284
|
function readConfig() {
|
|
272
285
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
273
286
|
return {};
|
|
@@ -2485,7 +2498,12 @@ async function toolCommand(flags) {
|
|
|
2485
2498
|
if (data.threadGroupingId) console.log('Thread grouping ID:', data.threadGroupingId);
|
|
2486
2499
|
console.log('Session log:', sessionJsonlFile(cwd));
|
|
2487
2500
|
console.log('Tool response file:', statusResponse.responseFile);
|
|
2488
|
-
|
|
2501
|
+
// A completed run can still carry a tool-level refusal — see toolResultFailed.
|
|
2502
|
+
const polledFailed = data.toolSuccess === false || toolResultFailed(data.result);
|
|
2503
|
+
if (polledFailed) {
|
|
2504
|
+
console.log('Tool error:', data.toolMessage || toolResultMessage(data.result));
|
|
2505
|
+
}
|
|
2506
|
+
if (data.status === 'failed' || polledFailed) process.exitCode = 1;
|
|
2489
2507
|
return;
|
|
2490
2508
|
}
|
|
2491
2509
|
|
|
@@ -2507,9 +2525,19 @@ async function toolCommand(flags) {
|
|
|
2507
2525
|
throw new Error(data.message || 'Tool execution failed');
|
|
2508
2526
|
}
|
|
2509
2527
|
|
|
2528
|
+
// `data.success` only means the tool was found and DISPATCHED. A tool that ran and refused (unmet
|
|
2529
|
+
// precondition, rejected enum value, validation failure) still comes back 200 with its own
|
|
2530
|
+
// success:false, and printing "Tool call succeeded" for that has caused agents to report work as
|
|
2531
|
+
// done that never happened. Prefer the server's hoisted verdict; fall back to introspecting the
|
|
2532
|
+
// result so this still works against an older platform build.
|
|
2533
|
+
const toolFailed = data.toolSuccess === false || toolResultFailed(data.result);
|
|
2534
|
+
const toolFailureMessage = data.toolMessage || toolResultMessage(data.result);
|
|
2535
|
+
|
|
2510
2536
|
printSessionResolutionWarning(sessionContext);
|
|
2511
2537
|
printResolvedBaseUrl(baseUrl);
|
|
2512
|
-
console.log(asyncMode ? 'Tool call started.'
|
|
2538
|
+
console.log(asyncMode ? 'Tool call started.'
|
|
2539
|
+
: (toolFailed ? 'Tool call FAILED — the tool ran and returned an error.' : 'Tool call succeeded.'));
|
|
2540
|
+
if (toolFailed && toolFailureMessage) console.log('Tool error:', toolFailureMessage);
|
|
2513
2541
|
console.log('Call ID:', callId);
|
|
2514
2542
|
console.log('Data mode:', data.dataMode || dataMode);
|
|
2515
2543
|
if (data.variantBranch || variantBranch) console.log('Variant branch:', data.variantBranch || variantBranch);
|
|
@@ -2523,6 +2551,9 @@ async function toolCommand(flags) {
|
|
|
2523
2551
|
console.log('Session log:', sessionJsonlFile(cwd));
|
|
2524
2552
|
console.log('Tool response file:', response.responseFile);
|
|
2525
2553
|
|
|
2554
|
+
// Non-zero exit so scripted/agent callers that check status notice the refusal too.
|
|
2555
|
+
if (toolFailed) process.exitCode = 1;
|
|
2556
|
+
|
|
2526
2557
|
if (asyncMode && waitForAsync) {
|
|
2527
2558
|
const finalStatus = await waitForToolStatus(api, cwd, {
|
|
2528
2559
|
token: session.token,
|
package/package.json
CHANGED
|
@@ -917,6 +917,7 @@ summary: One-line statement of what this component is for.
|
|
|
917
917
|
description: |
|
|
918
918
|
Longer technical description with line-number references to the key logic.
|
|
919
919
|
path: /page/merchant-portal # Readers and Embeddables only
|
|
920
|
+
injectionType: DIRECT # Embeddables only: DIRECT or IFRAME
|
|
920
921
|
category: default
|
|
921
922
|
auxiliary: false # `true` means the sync SKIPS the file entirely — see Auxiliary
|
|
922
923
|
mermaid: |
|
|
@@ -1135,7 +1136,7 @@ account:<accountId>:cli:<cliUserId>:components:<branch>:<family>:name:<normalize
|
|
|
1135
1136
|
component's OWN type enum such as `ObjectType`/`RuleType`, or absent — **never** the family), `hash`,
|
|
1136
1137
|
`updatedAt`, the staged content field(s) (`source`/`prompt`/`html`/`javascript`/`schema`/
|
|
1137
1138
|
`inputSchema`/`previewData`), and `.meta.yml` metadata fields such as `description`, `summary`, `mermaid`,
|
|
1138
|
-
`path`, `category`, and Schema flags (`enableTrigger`, `enableFullText`, `enableRAG`, `enableRevisions`,
|
|
1139
|
+
`path`, Embeddable `injectionType`, `category`, and Schema flags (`enableTrigger`, `enableFullText`, `enableRAG`, `enableRevisions`,
|
|
1139
1140
|
`enableBigQuerySync`, `enableRules`, `anchor`, `auxiliary`).
|
|
1140
1141
|
|
|
1141
1142
|
### How the platform picks staged vs DB (the compile signature)
|
|
@@ -1406,7 +1407,7 @@ changes validation and where the subscriber's documents physically land. Treat s
|
|
|
1406
1407
|
same care as a trunk schema change.
|
|
1407
1408
|
|
|
1408
1409
|
**What a branch may override.** A variant speaks the same `.meta.yml` vocabulary trunk does — `name`,
|
|
1409
|
-
`description`, `summary`, `mermaid`, `category`, `type`, `path`, `collectionName`, `job`, `model`,
|
|
1410
|
+
`description`, `summary`, `mermaid`, `category`, `type`, `path`, `injectionType`, `collectionName`, `job`, `model`,
|
|
1410
1411
|
`agentTimeout`, `mcp`, `cli`, `global`, `purpose`, `auxiliary`, plus Schema flags (`enableTrigger`,
|
|
1411
1412
|
`enableFullText`, `enableRAG`, `enableRevisions`, `enableBigQuerySync`, `enableRules`, `anchor`) — and the
|
|
1412
1413
|
component's content files. Keys outside that set are ignored, deliberately: trunk cannot express them either,
|
|
@@ -1727,6 +1728,23 @@ remits-cli tool --name "mcp_firestore_search" --input '{"accountId": 37, "collec
|
|
|
1727
1728
|
|
|
1728
1729
|
Response saved to `./.remits-cli/tool-responses/<callId>.json`. Read the file to see results.
|
|
1729
1730
|
|
|
1731
|
+
**"Tool call succeeded" means DISPATCHED, not that the tool did what you asked.** A tool that runs
|
|
1732
|
+
and refuses — an unmet precondition, a rejected enum value, a failed validation — returns HTTP 200
|
|
1733
|
+
with its own `success: false` inside `result`. The CLI now prints `Tool call FAILED — the tool ran
|
|
1734
|
+
and returned an error.` plus a `Tool error:` line and exits non-zero, and the response envelope
|
|
1735
|
+
carries `toolSuccess` / `toolMessage`. **For any MUTATING call, confirm the tool's own verdict before
|
|
1736
|
+
reporting the work as done** — do not grep the terminal output for "succeeded":
|
|
1737
|
+
|
|
1738
|
+
```bash
|
|
1739
|
+
F=$(remits-cli tool --name mcp_support_ticket --input "$(cat payload.json)" --data-mode prod 2>&1 \
|
|
1740
|
+
| grep -o '[^ ]*tool-responses/[a-f0-9-]*\.json' | tail -1)
|
|
1741
|
+
python3 -c "import json;r=json.load(open('$F'))['result'];print(r.get('success'), r.get('message'))"
|
|
1742
|
+
```
|
|
1743
|
+
|
|
1744
|
+
Build non-trivial JSON into a file (e.g. with `python3 -c 'json.dumps(...)'`) and pass it as
|
|
1745
|
+
`--input "$(cat payload.json)"`. Long inline single-quoted JSON intermittently produces no response
|
|
1746
|
+
file at all.
|
|
1747
|
+
|
|
1730
1748
|
For long-running Action/Agent runners, use the tool's own async mode (`executionMode:"async"`), which returns
|
|
1731
1749
|
the `actionRunId`/`agentRunId` (and, for agents, `sessionId`) immediately:
|
|
1732
1750
|
|
|
@@ -2141,10 +2159,10 @@ Create and manage the full lifecycle of account-relative `support_tickets`.
|
|
|
2141
2159
|
| `affectedComponent` | no | Component or platform area affected (`create`) |
|
|
2142
2160
|
| `implementationAccountId` / `implementationAccountName` | no | Owning `PLATFORM`/`PRODUCT` account when the ticket concerns shared implementation (e.g. a back-stage platform fix) |
|
|
2143
2161
|
| `stepsToReproduce` / `acceptanceCriteria` / `tags` | no | Extra `create` fields for defect/enhancement tickets |
|
|
2144
|
-
| `assignee` | no | Required for `accept` |
|
|
2145
|
-
| `status` | no | Required for `update_status`. Valid values: `in_progress`, `pending_review` |
|
|
2162
|
+
| `assignee` | no | Required for `accept`. The agent's own name by convention — `claude`, `codex`, `gemini` |
|
|
2163
|
+
| `status` | no | Required for `update_status`. Valid values: `in_progress`, `pending_review`. **The ticket must be `accept`ed first** — otherwise the call is rejected with *"Ticket must be accepted before updating status"* |
|
|
2146
2164
|
| `resolution` | no | Required for `complete` |
|
|
2147
|
-
| `category` / `summary` / `details` / `findings` / `nextStep` | no | Worklog fields for `record_progress` (`category` + `summary` required) |
|
|
2165
|
+
| `category` / `summary` / `details` / `findings` / `nextStep` | no | Worklog fields for `record_progress` (`category` + `summary` required). `category` is a **fixed enum** — `triage`, `investigation`, `reproduction`, `fix`, `verification`, `handoff`, `other` — and any other value fails the whole call. `findings` is a **list of strings**, not a paragraph |
|
|
2148
2166
|
| `artifactType` / `artifactLabel` / `contentBase64` / `gcsPath` / `url` | no | Evidence fields for `add_artifact` (screenshot/trace/log/test_result/link) |
|
|
2149
2167
|
| `notes` | no | Optional lifecycle note stored with the ticket activity |
|
|
2150
2168
|
| `attachmentIndex` | no | Zero-based index of the attachment to download. Used with `get_attachment`. |
|
|
@@ -2159,13 +2177,24 @@ Create and manage the full lifecycle of account-relative `support_tickets`.
|
|
|
2159
2177
|
|
|
2160
2178
|
This keeps file retrieval self-contained — no separate download endpoint is needed.
|
|
2161
2179
|
|
|
2162
|
-
**Recommended flow
|
|
2163
|
-
1. `read`
|
|
2164
|
-
2.
|
|
2180
|
+
**Recommended flow** — `accountId` is optional throughout; `ticketId` resolves the owning account:
|
|
2181
|
+
1. `read` — check ticket state and any attachments
|
|
2182
|
+
2. **`accept`** (with `assignee`) — this is a **hard precondition for `update_status`**, not just etiquette
|
|
2165
2183
|
3. `get_attachment` if attachments are present and relevant to the investigation
|
|
2166
|
-
4. `update_status`
|
|
2167
|
-
5.
|
|
2168
|
-
6.
|
|
2184
|
+
4. `update_status` — `in_progress` while working, `pending_review` when the fix is done but not yet deployed
|
|
2185
|
+
5. `record_progress` as you go — one `investigation` entry for the root cause, one `verification` entry for the proof
|
|
2186
|
+
6. investigate/fix/verify on the owning ticket account or its implementation account as appropriate
|
|
2187
|
+
7. `complete` (with `resolution`) or `release` if handing off
|
|
2188
|
+
|
|
2189
|
+
**Check each mutation actually landed.** Every action above is a write that can be refused while the
|
|
2190
|
+
CLI still reports the *call* as fine — see "Execute a Tool" for why, and read `result.success` from
|
|
2191
|
+
the response file. A silent no-op here means telling the user a ticket moved when it did not.
|
|
2192
|
+
|
|
2193
|
+
**Duplicates are common.** The same defect is often filed twice — once against the `CLIENT`/subscriber
|
|
2194
|
+
account where it was observed and once against the owning `PLATFORM`/`PRODUCT` account. Before
|
|
2195
|
+
starting, check `mcp_support_ticket_queue` for the same subject or affected component. Close the
|
|
2196
|
+
duplicate with a `resolution` naming the ticket that carries the real work, rather than investigating
|
|
2197
|
+
it twice.
|
|
2169
2198
|
|
|
2170
2199
|
**Automation rule:** If a ticket is involved, you should usually:
|
|
2171
2200
|
- `read` at the start
|