@ultimat3/action 22.9.1 → 22.10.0
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/package.json +7 -7
- package/src/action.ts +27 -0
- package/src/errors.ts +18 -2
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimat3/action",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.10.0",
|
|
4
4
|
"description": "The action primitive: one declaration projected to route, OpenAPI, client, MCP tool, job handle, tests",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"test": "bun test"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@ultimat3/cache": "22.
|
|
38
|
-
"@ultimat3/core": "22.
|
|
39
|
-
"@ultimat3/entity": "22.
|
|
40
|
-
"@ultimat3/http": "22.
|
|
41
|
-
"@ultimat3/policy": "22.
|
|
42
|
-
"@ultimat3/schema": "22.
|
|
37
|
+
"@ultimat3/cache": "22.10.0",
|
|
38
|
+
"@ultimat3/core": "22.10.0",
|
|
39
|
+
"@ultimat3/entity": "22.10.0",
|
|
40
|
+
"@ultimat3/http": "22.10.0",
|
|
41
|
+
"@ultimat3/policy": "22.10.0",
|
|
42
|
+
"@ultimat3/schema": "22.10.0"
|
|
43
43
|
}
|
|
44
44
|
}
|
package/src/action.ts
CHANGED
|
@@ -63,6 +63,33 @@ export interface ActionMcp {
|
|
|
63
63
|
* actor's admin permissions) hands `@ultimat3/mcp` a predicate instead.
|
|
64
64
|
*/
|
|
65
65
|
readonly visibleTo?: readonly string[];
|
|
66
|
+
/**
|
|
67
|
+
* The tool's display name in an MCP client's UI (`title`, MCP 2025-06-18). Contract text, like
|
|
68
|
+
* `description`. Omitted: none is published and the client shows the tool name.
|
|
69
|
+
*/
|
|
70
|
+
readonly title?: string;
|
|
71
|
+
/**
|
|
72
|
+
* MCP tool annotations, overriding what `@ultimat3/mcp` derives key by key. An action derives
|
|
73
|
+
* `readOnlyHint: false`, `destructiveHint: true` and `idempotentHint` from `idempotent`. Hints for
|
|
74
|
+
* a client's confirmation UI — the policy decides every call whatever they say.
|
|
75
|
+
*
|
|
76
|
+
* ```ts
|
|
77
|
+
* mcp: { expose: true, annotations: { destructiveHint: false, openWorldHint: true } },
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
readonly annotations?: McpAnnotationHints;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* MCP's four tool hints, as the spec spells them. Declared here (tier 3) and in `@ultimat3/query`
|
|
85
|
+
* because `@ultimat3/mcp` (tier 4) is the reader and cannot be imported; its `McpToolAnnotations`
|
|
86
|
+
* is the same shape.
|
|
87
|
+
*/
|
|
88
|
+
export interface McpAnnotationHints {
|
|
89
|
+
readonly readOnlyHint?: boolean;
|
|
90
|
+
readonly destructiveHint?: boolean;
|
|
91
|
+
readonly idempotentHint?: boolean;
|
|
92
|
+
readonly openWorldHint?: boolean;
|
|
66
93
|
}
|
|
67
94
|
|
|
68
95
|
export interface ActionRateLimit {
|
package/src/errors.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import {
|
|
8
8
|
assertNever,
|
|
9
|
+
deniedCallerFix,
|
|
9
10
|
ERROR_DOCS_URL,
|
|
10
11
|
hasErrorCode,
|
|
11
12
|
registerErrorCodes,
|
|
@@ -136,6 +137,7 @@ export class ActionDeniedError extends UltimateError {
|
|
|
136
137
|
code,
|
|
137
138
|
cause: `${action} denied: ${denialReason(denial)}`,
|
|
138
139
|
fix: `x policy explain ${action} --json # shows which clause decided and why`,
|
|
140
|
+
callerFix: deniedCallerFix(),
|
|
139
141
|
});
|
|
140
142
|
this.denial = denial;
|
|
141
143
|
}
|
|
@@ -203,11 +205,25 @@ export class InputInvalidError extends UltimateError {
|
|
|
203
205
|
* `formatIssues` here would pull that package's whole barrel into every browser bundle holding
|
|
204
206
|
* the typed client.
|
|
205
207
|
*/
|
|
206
|
-
constructor(
|
|
208
|
+
constructor(
|
|
209
|
+
name: string,
|
|
210
|
+
detail: string,
|
|
211
|
+
issues?: readonly ValidationIssue[],
|
|
212
|
+
/**
|
|
213
|
+
* What `name` names, in the cause: `'action'` (the default), or `'tool'` when `@ultimat3/mcp`
|
|
214
|
+
* refuses arguments against a tool's published schema — a query's or a meta tool's, not only an
|
|
215
|
+
* action's.
|
|
216
|
+
*/
|
|
217
|
+
subject: 'action' | 'tool' = 'action',
|
|
218
|
+
) {
|
|
207
219
|
super({
|
|
208
220
|
code: 'X_INPUT_INVALID',
|
|
209
|
-
cause: `input for
|
|
221
|
+
cause: `input for ${subject} "${name}" failed validation: ${detail}`,
|
|
210
222
|
fix: `x actions describe ${name} --json # prints the expected input schema`,
|
|
223
|
+
// A remote caller holds the published schema — the MCP `inputSchema`, the OpenAPI request
|
|
224
|
+
// body — and cannot run `x actions describe`.
|
|
225
|
+
callerFix:
|
|
226
|
+
'correct the fields named in cause to match the published input schema (the tool inputSchema, or the OpenAPI request body) and send again — the same input is refused the same way',
|
|
211
227
|
...(issues === undefined ? {} : { meta: { issues } }),
|
|
212
228
|
});
|
|
213
229
|
this.issues = issues;
|