@descryy/mcp 0.5.0 → 0.7.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/dist/action-handshake.d.ts +8 -75
- package/dist/action-handshake.d.ts.map +1 -1
- package/dist/action-handshake.js +9 -79
- package/dist/action-handshake.js.map +1 -1
- package/dist/bin/descry-mcp.d.ts +4 -15
- package/dist/bin/descry-mcp.d.ts.map +1 -1
- package/dist/bin/descry-mcp.js +12 -42
- package/dist/bin/descry-mcp.js.map +1 -1
- package/dist/browser/driver.d.ts +62 -178
- package/dist/browser/driver.d.ts.map +1 -1
- package/dist/browser/driver.js +14 -46
- package/dist/browser/driver.js.map +1 -1
- package/dist/browser/evidence.d.ts +11 -35
- package/dist/browser/evidence.d.ts.map +1 -1
- package/dist/browser/evidence.js +25 -51
- package/dist/browser/evidence.js.map +1 -1
- package/dist/browser/fake-driver.d.ts +12 -16
- package/dist/browser/fake-driver.d.ts.map +1 -1
- package/dist/browser/fake-driver.js +24 -17
- package/dist/browser/fake-driver.js.map +1 -1
- package/dist/browser/graph-write.d.ts +4 -45
- package/dist/browser/graph-write.d.ts.map +1 -1
- package/dist/browser/graph-write.js +8 -53
- package/dist/browser/graph-write.js.map +1 -1
- package/dist/browser/playwright-driver.d.ts +17 -67
- package/dist/browser/playwright-driver.d.ts.map +1 -1
- package/dist/browser/playwright-driver.js +169 -166
- package/dist/browser/playwright-driver.js.map +1 -1
- package/dist/browser/provider.d.ts +5 -34
- package/dist/browser/provider.d.ts.map +1 -1
- package/dist/browser/provider.js +4 -24
- package/dist/browser/provider.js.map +1 -1
- package/dist/browser/registry.d.ts +26 -106
- package/dist/browser/registry.d.ts.map +1 -1
- package/dist/browser/registry.js +20 -77
- package/dist/browser/registry.js.map +1 -1
- package/dist/browser/scenario-resolve.d.ts +10 -44
- package/dist/browser/scenario-resolve.d.ts.map +1 -1
- package/dist/browser/scenario-resolve.js +10 -41
- package/dist/browser/scenario-resolve.js.map +1 -1
- package/dist/browser/scenario-runner.d.ts +12 -70
- package/dist/browser/scenario-runner.d.ts.map +1 -1
- package/dist/browser/scenario-runner.js +33 -91
- package/dist/browser/scenario-runner.js.map +1 -1
- package/dist/browser/stack-parser.d.ts +4 -28
- package/dist/browser/stack-parser.d.ts.map +1 -1
- package/dist/browser/stack-parser.js +12 -39
- package/dist/browser/stack-parser.js.map +1 -1
- package/dist/browser/tool-support.d.ts +20 -67
- package/dist/browser/tool-support.d.ts.map +1 -1
- package/dist/browser/tool-support.js +22 -66
- package/dist/browser/tool-support.js.map +1 -1
- package/dist/browser/url-scheme.d.ts +14 -0
- package/dist/browser/url-scheme.d.ts.map +1 -0
- package/dist/browser/url-scheme.js +38 -0
- package/dist/browser/url-scheme.js.map +1 -0
- package/dist/cancellation.d.ts +11 -46
- package/dist/cancellation.d.ts.map +1 -1
- package/dist/cancellation.js +11 -46
- package/dist/cancellation.js.map +1 -1
- package/dist/capped.d.ts +17 -0
- package/dist/capped.d.ts.map +1 -0
- package/dist/capped.js +15 -0
- package/dist/capped.js.map +1 -0
- package/dist/disclosure-ledger.d.ts +6 -30
- package/dist/disclosure-ledger.d.ts.map +1 -1
- package/dist/disclosure-ledger.js +4 -26
- package/dist/disclosure-ledger.js.map +1 -1
- package/dist/index.d.ts +10 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -17
- package/dist/index.js.map +1 -1
- package/dist/module-trust.d.ts +24 -0
- package/dist/module-trust.d.ts.map +1 -0
- package/dist/module-trust.js +60 -0
- package/dist/module-trust.js.map +1 -0
- package/dist/path-confinement.d.ts +31 -0
- package/dist/path-confinement.d.ts.map +1 -0
- package/dist/path-confinement.js +44 -0
- package/dist/path-confinement.js.map +1 -0
- package/dist/protocol.d.ts +10 -53
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +14 -60
- package/dist/protocol.js.map +1 -1
- package/dist/registry.d.ts +10 -58
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +38 -90
- package/dist/registry.js.map +1 -1
- package/dist/render.d.ts +79 -11
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +126 -14
- package/dist/render.js.map +1 -1
- package/dist/runtime-registry.d.ts +8 -49
- package/dist/runtime-registry.d.ts.map +1 -1
- package/dist/runtime-registry.js +72 -63
- package/dist/runtime-registry.js.map +1 -1
- package/dist/scenarios/index.d.ts +1 -1
- package/dist/scenarios/index.d.ts.map +1 -1
- package/dist/scenarios/index.js +1 -1
- package/dist/scenarios/index.js.map +1 -1
- package/dist/scenarios/parse.d.ts +4 -18
- package/dist/scenarios/parse.d.ts.map +1 -1
- package/dist/scenarios/parse.js +14 -34
- package/dist/scenarios/parse.js.map +1 -1
- package/dist/scenarios/scenario.d.ts +18 -74
- package/dist/scenarios/scenario.d.ts.map +1 -1
- package/dist/scenarios/scenario.js +7 -34
- package/dist/scenarios/scenario.js.map +1 -1
- package/dist/scenarios/storage.d.ts +11 -41
- package/dist/scenarios/storage.d.ts.map +1 -1
- package/dist/scenarios/storage.js +57 -47
- package/dist/scenarios/storage.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +55 -13
- package/dist/server.js.map +1 -1
- package/dist/session.d.ts +69 -239
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +76 -231
- package/dist/session.js.map +1 -1
- package/dist/tools/analyze.d.ts +27 -101
- package/dist/tools/analyze.d.ts.map +1 -1
- package/dist/tools/analyze.js +58 -148
- package/dist/tools/analyze.js.map +1 -1
- package/dist/tools/browser-click.d.ts +3 -21
- package/dist/tools/browser-click.d.ts.map +1 -1
- package/dist/tools/browser-click.js +10 -31
- package/dist/tools/browser-click.js.map +1 -1
- package/dist/tools/browser-close-session.d.ts +4 -13
- package/dist/tools/browser-close-session.d.ts.map +1 -1
- package/dist/tools/browser-close-session.js +4 -13
- package/dist/tools/browser-close-session.js.map +1 -1
- package/dist/tools/browser-fill.d.ts +5 -36
- package/dist/tools/browser-fill.d.ts.map +1 -1
- package/dist/tools/browser-fill.js +9 -44
- package/dist/tools/browser-fill.js.map +1 -1
- package/dist/tools/browser-navigate.d.ts +6 -27
- package/dist/tools/browser-navigate.d.ts.map +1 -1
- package/dist/tools/browser-navigate.js +6 -23
- package/dist/tools/browser-navigate.js.map +1 -1
- package/dist/tools/browser-run-scenario.d.ts +5 -31
- package/dist/tools/browser-run-scenario.d.ts.map +1 -1
- package/dist/tools/browser-run-scenario.js +10 -46
- package/dist/tools/browser-run-scenario.js.map +1 -1
- package/dist/tools/browser-save-scenario.d.ts +3 -28
- package/dist/tools/browser-save-scenario.d.ts.map +1 -1
- package/dist/tools/browser-save-scenario.js +102 -55
- package/dist/tools/browser-save-scenario.js.map +1 -1
- package/dist/tools/browser-snapshot.d.ts +6 -39
- package/dist/tools/browser-snapshot.d.ts.map +1 -1
- package/dist/tools/browser-snapshot.js +4 -31
- package/dist/tools/browser-snapshot.js.map +1 -1
- package/dist/tools/browser-start-session.d.ts +4 -23
- package/dist/tools/browser-start-session.d.ts.map +1 -1
- package/dist/tools/browser-start-session.js +38 -51
- package/dist/tools/browser-start-session.js.map +1 -1
- package/dist/tools/browser-type.d.ts +5 -35
- package/dist/tools/browser-type.d.ts.map +1 -1
- package/dist/tools/browser-type.js +10 -45
- package/dist/tools/browser-type.js.map +1 -1
- package/dist/tools/contracts.d.ts +17 -63
- package/dist/tools/contracts.d.ts.map +1 -1
- package/dist/tools/contracts.js +91 -47
- package/dist/tools/contracts.js.map +1 -1
- package/dist/tools/cross-pr.d.ts +56 -15
- package/dist/tools/cross-pr.d.ts.map +1 -1
- package/dist/tools/cross-pr.js +141 -38
- package/dist/tools/cross-pr.js.map +1 -1
- package/dist/tools/git-diff.d.ts +18 -2
- package/dist/tools/git-diff.d.ts.map +1 -1
- package/dist/tools/git-diff.js +143 -23
- package/dist/tools/git-diff.js.map +1 -1
- package/dist/tools/git-history.d.ts +5 -16
- package/dist/tools/git-history.d.ts.map +1 -1
- package/dist/tools/git-history.js +3 -10
- package/dist/tools/git-history.js.map +1 -1
- package/dist/tools/history.d.ts +4 -33
- package/dist/tools/history.d.ts.map +1 -1
- package/dist/tools/history.js +6 -31
- package/dist/tools/history.js.map +1 -1
- package/dist/tools/impact.d.ts +7 -51
- package/dist/tools/impact.d.ts.map +1 -1
- package/dist/tools/impact.js +15 -67
- package/dist/tools/impact.js.map +1 -1
- package/dist/tools/index.d.ts +3 -8
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -8
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/kit.d.ts +66 -113
- package/dist/tools/kit.d.ts.map +1 -1
- package/dist/tools/kit.js +60 -28
- package/dist/tools/kit.js.map +1 -1
- package/dist/tools/link-workspace.d.ts +7 -45
- package/dist/tools/link-workspace.d.ts.map +1 -1
- package/dist/tools/link-workspace.js +10 -48
- package/dist/tools/link-workspace.js.map +1 -1
- package/dist/tools/lookup.d.ts +4 -14
- package/dist/tools/lookup.d.ts.map +1 -1
- package/dist/tools/lookup.js +4 -14
- package/dist/tools/lookup.js.map +1 -1
- package/dist/tools/mark-incident.d.ts +7 -54
- package/dist/tools/mark-incident.d.ts.map +1 -1
- package/dist/tools/mark-incident.js +15 -68
- package/dist/tools/mark-incident.js.map +1 -1
- package/dist/tools/observe-runtime.d.ts +27 -210
- package/dist/tools/observe-runtime.d.ts.map +1 -1
- package/dist/tools/observe-runtime.js +258 -436
- package/dist/tools/observe-runtime.js.map +1 -1
- package/dist/tools/observe-tests.d.ts +9 -88
- package/dist/tools/observe-tests.d.ts.map +1 -1
- package/dist/tools/observe-tests.js +34 -108
- package/dist/tools/observe-tests.js.map +1 -1
- package/dist/tools/pr-analysis.d.ts +18 -2
- package/dist/tools/pr-analysis.d.ts.map +1 -1
- package/dist/tools/pr-analysis.js +73 -23
- package/dist/tools/pr-analysis.js.map +1 -1
- package/dist/tools/pre-push.d.ts +94 -9
- package/dist/tools/pre-push.d.ts.map +1 -1
- package/dist/tools/pre-push.js +139 -34
- package/dist/tools/pre-push.js.map +1 -1
- package/dist/tools/propagation.d.ts +11 -53
- package/dist/tools/propagation.d.ts.map +1 -1
- package/dist/tools/propagation.js +14 -57
- package/dist/tools/propagation.js.map +1 -1
- package/dist/tools/questions.d.ts +13 -63
- package/dist/tools/questions.d.ts.map +1 -1
- package/dist/tools/questions.js +33 -105
- package/dist/tools/questions.js.map +1 -1
- package/dist/tools/refusal-fetch.d.ts +4 -40
- package/dist/tools/refusal-fetch.d.ts.map +1 -1
- package/dist/tools/refusal-fetch.js +4 -40
- package/dist/tools/refusal-fetch.js.map +1 -1
- package/dist/tools/runtime-incident.d.ts +4 -63
- package/dist/tools/runtime-incident.d.ts.map +1 -1
- package/dist/tools/runtime-incident.js +10 -87
- package/dist/tools/runtime-incident.js.map +1 -1
- package/dist/tools/scope.d.ts +7 -25
- package/dist/tools/scope.d.ts.map +1 -1
- package/dist/tools/scope.js +17 -20
- package/dist/tools/scope.js.map +1 -1
- package/dist/tools/similar-incidents.d.ts +11 -86
- package/dist/tools/similar-incidents.d.ts.map +1 -1
- package/dist/tools/similar-incidents.js +7 -71
- package/dist/tools/similar-incidents.js.map +1 -1
- package/dist/tools/validate.d.ts +31 -47
- package/dist/tools/validate.d.ts.map +1 -1
- package/dist/tools/validate.js +133 -61
- package/dist/tools/validate.js.map +1 -1
- package/dist/tools/verification-status.d.ts +9 -64
- package/dist/tools/verification-status.d.ts.map +1 -1
- package/dist/tools/verification-status.js +9 -62
- package/dist/tools/verification-status.js.map +1 -1
- package/dist/tools/verify-claim.d.ts +5 -52
- package/dist/tools/verify-claim.d.ts.map +1 -1
- package/dist/tools/verify-claim.js +6 -56
- package/dist/tools/verify-claim.js.map +1 -1
- package/dist/transport.d.ts +15 -52
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +16 -60
- package/dist/transport.js.map +1 -1
- package/package.json +33 -16
package/dist/registry.js
CHANGED
|
@@ -1,47 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* where it matters most — the process that runs everything. So sources are named
|
|
7
|
-
* in configuration as module specifiers and loaded at runtime. The engine knows
|
|
8
|
-
* `IRSource`; it never knows the word "python".
|
|
9
|
-
*
|
|
10
|
-
* ## The factory convention, and why it is a convention rather than an interface
|
|
11
|
-
*
|
|
12
|
-
* Every adapter in `descry-adapters` exports `ADAPTER_ID`, `ADAPTER_VERSION` and
|
|
13
|
-
* a factory named `create<Something>Adapter` — `createGoAdapter`,
|
|
14
|
-
* `createTypeScriptAdapter`, `createOpenApiAdapter`. There is no uniform name,
|
|
15
|
-
* and inventing one now would be a breaking change across twelve packages to
|
|
16
|
-
* save a regular expression. So: an explicit `export` in config wins; failing
|
|
17
|
-
* that, the single export matching `create*Adapter` is used; **two matches is an
|
|
18
|
-
* error, not a coin toss.**
|
|
19
|
-
*
|
|
20
|
-
* ## Failing to load a source is a disclosure, never a shrug
|
|
21
|
-
*
|
|
22
|
-
* An adapter that will not import is the difference between "we found no problem
|
|
23
|
-
* in your Python service" and "we could not read your Python service" — §20.2
|
|
24
|
-
* keeps those in different categories, and a registry that quietly skipped a
|
|
25
|
-
* broken specifier would collapse them at the very bottom of the stack, where no
|
|
26
|
-
* layer above could ever recover the distinction. Every failure comes back as a
|
|
27
|
-
* `SourceLoadFailure` carrying the specifier and the reason, and the caller is
|
|
28
|
-
* structurally unable to take the loaded sources without also taking the list of
|
|
29
|
-
* ones that are missing.
|
|
30
|
-
*
|
|
31
|
-
* ## Two places to look, because the server and the repository are not the same tree
|
|
32
|
-
*
|
|
33
|
-
* `import(spec.module)` resolves relative to *this package's* location. That is
|
|
34
|
-
* right for a side-by-side install — `npm i @descryy/mcp @descryy/adapter-x` puts
|
|
35
|
-
* both under the repository's own `node_modules` — and useless under `npx -y
|
|
36
|
-
* @descryy/mcp <repo>`, where the server runs out of an isolated npx cache
|
|
37
|
-
* directory that contains no adapter the user ever installed. So a specifier is
|
|
38
|
-
* resolved from the **repository root first** when one is known: that is where the
|
|
39
|
-
* user installed the adapter and where their lockfile pins its version. The
|
|
40
|
-
* server's own closure stays as the fallback, so the side-by-side install and the
|
|
41
|
-
* absolute-path and `file:` specifiers that never needed a repository keep working
|
|
42
|
-
* unchanged. When both fail, both are disclosed — a resolution nobody attempted is
|
|
43
|
-
* the worst thing to make somebody debug.
|
|
44
|
-
*/
|
|
1
|
+
/** How the server reaches adapters without depending on them: `descry-core` must never
|
|
2
|
+
* import `descry-adapters` (rule 1, IR boundary) — sources are named as module specifiers
|
|
3
|
+
* in config and loaded at runtime via a `create*Adapter` convention (an ambiguous match
|
|
4
|
+
* errors, never guesses). A failed load is disclosed as `SourceLoadFailure`, never silently
|
|
5
|
+
* skipped (§20.2). Specifiers resolve from the repo root first (npx isolates adapters there), then this package's own closure. */
|
|
45
6
|
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
46
7
|
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
47
8
|
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
@@ -52,19 +13,15 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
52
13
|
};
|
|
53
14
|
import { createRequire } from "node:module";
|
|
54
15
|
import { join } from "node:path";
|
|
55
|
-
import { pathToFileURL } from "node:url";
|
|
16
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
17
|
+
import { checkModuleTrust, checkRepoResolvedModuleTrust } from "./module-trust.js";
|
|
56
18
|
const FACTORY_PATTERN = /^create[A-Za-z0-9]*Adapter$/;
|
|
57
19
|
export function normaliseSpec(entry) {
|
|
58
20
|
return typeof entry === "string" ? { module: entry } : entry;
|
|
59
21
|
}
|
|
60
|
-
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* Duck-typed on the two methods that matter rather than on a marker, because the
|
|
64
|
-
* adapters are compiled separately and `instanceof` across package boundaries is
|
|
65
|
-
* a well-known way to be wrong. `detect` and `capabilities` are the two the
|
|
66
|
-
* server actually calls; a source with both is one it can treat as an adapter.
|
|
67
|
-
*/
|
|
22
|
+
/** A loaded module is a `LanguageAdapter` when it can be asked what it supports. Duck-typed
|
|
23
|
+
* on `detect`/`capabilities` — the two methods the server calls — since `instanceof` across
|
|
24
|
+
* separately-compiled adapter packages is unreliable. */
|
|
68
25
|
function asAdapter(source) {
|
|
69
26
|
const candidate = source;
|
|
70
27
|
return typeof candidate.detect === "function" && typeof candidate.capabilities === "function"
|
|
@@ -78,11 +35,8 @@ function describe(error) {
|
|
|
78
35
|
}
|
|
79
36
|
return String(error);
|
|
80
37
|
}
|
|
81
|
-
/**
|
|
82
|
-
*
|
|
83
|
-
* resolved from here first; without it only the server's own closure is searched,
|
|
84
|
-
* which is correct for callers that name modules by absolute path or `file:` URL.
|
|
85
|
-
*/
|
|
38
|
+
/** @param repoPath Repo being analysed, when known — specifiers resolve from here first;
|
|
39
|
+
* without it only this package's closure is searched (correct for absolute-path/`file:` callers). */
|
|
86
40
|
export async function loadSources(entries, repoPath) {
|
|
87
41
|
const loaded = [];
|
|
88
42
|
const failed = [];
|
|
@@ -97,20 +51,9 @@ export async function loadSources(entries, repoPath) {
|
|
|
97
51
|
}
|
|
98
52
|
return { loaded, failed };
|
|
99
53
|
}
|
|
100
|
-
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* `createRequire` anchored at the repository's `package.json` is the resolution a
|
|
104
|
-
* script run inside that repository would get. It is CommonJS resolution, so it
|
|
105
|
-
* reads `exports` under the `require`/`default` conditions — every adapter here
|
|
106
|
-
* publishes a `default`, and one that did not would fall through to the server's
|
|
107
|
-
* closure rather than fail the load. The resolved path is imported as a URL, so
|
|
108
|
-
* the module itself is still loaded as ESM.
|
|
109
|
-
*
|
|
110
|
-
* Returns the reason on failure rather than throwing: a specifier the repository
|
|
111
|
-
* cannot see is not yet a failure, only a fact worth disclosing if the second
|
|
112
|
-
* attempt fails too.
|
|
113
|
-
*/
|
|
54
|
+
/** Resolves a specifier as the repo's own `node_modules` would, via `createRequire` anchored
|
|
55
|
+
* at its `package.json` (CJS resolution, `require`/`default` conditions), then imports the
|
|
56
|
+
* resolved path as ESM. Returns the reason on failure rather than throwing — not yet a failure until the fallback also fails. */
|
|
114
57
|
function resolveFromRepo(specifier, repoPath) {
|
|
115
58
|
try {
|
|
116
59
|
const require = createRequire(pathToFileURL(join(repoPath, "package.json")));
|
|
@@ -145,18 +88,29 @@ async function instantiate(spec, repoPath) {
|
|
|
145
88
|
}
|
|
146
89
|
return { source, adapter: asAdapter(source) };
|
|
147
90
|
}
|
|
148
|
-
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* Only a *resolution* failure falls through. A module that resolves and then
|
|
152
|
-
* throws while evaluating is that module's failure, and reporting it as "could
|
|
153
|
-
* not be found" — or quietly loading a different copy from the server's closure
|
|
154
|
-
* instead — would hide a broken adapter behind a wrong explanation.
|
|
155
|
-
*/
|
|
91
|
+
/** Repository root first, the server's own closure second. Only a resolution failure falls
|
|
92
|
+
* through — a module that resolves and then throws is that module's own failure, not "could not be found". */
|
|
156
93
|
async function importSource(specifier, repoPath) {
|
|
94
|
+
// A-F1: specifier can come straight from the repo's own .descry/config.json (module-trust.ts).
|
|
95
|
+
// Checked on the raw string before either resolution attempt, since `resolveFromRepo` always
|
|
96
|
+
// turns its result into a `file:` URL regardless of whether the specifier was path-like.
|
|
97
|
+
const trust = checkModuleTrust(specifier);
|
|
98
|
+
if (!trust.allowed)
|
|
99
|
+
throw new Error(trust.reason);
|
|
157
100
|
const fromRepo = repoPath === undefined ? { reason: "no repository root" } : resolveFromRepo(specifier, repoPath);
|
|
158
|
-
if ("url" in fromRepo)
|
|
101
|
+
if ("url" in fromRepo) {
|
|
102
|
+
// A-F1 follow-up: checkModuleTrust only sees the raw specifier, not that it resolves into
|
|
103
|
+
// the repo's own git-tracked node_modules — closes the gap where a hostile repo commits
|
|
104
|
+
// node_modules/<name> and delivers a payload on clone alone; override: DESCRY_ALLOW_TRACKED_NODE_MODULES=1.
|
|
105
|
+
const repoTrust = await checkRepoResolvedModuleTrust({
|
|
106
|
+
specifier,
|
|
107
|
+
repoPath: repoPath,
|
|
108
|
+
resolvedAbsolutePath: fileURLToPath(fromRepo.url),
|
|
109
|
+
});
|
|
110
|
+
if (!repoTrust.allowed)
|
|
111
|
+
throw new Error(repoTrust.reason);
|
|
159
112
|
return await import(__rewriteRelativeImportExtension(fromRepo.url));
|
|
113
|
+
}
|
|
160
114
|
try {
|
|
161
115
|
return await import(__rewriteRelativeImportExtension(specifier));
|
|
162
116
|
}
|
|
@@ -167,15 +121,9 @@ async function importSource(specifier, repoPath) {
|
|
|
167
121
|
`(${fromRepo.reason})`, { cause: error });
|
|
168
122
|
}
|
|
169
123
|
}
|
|
170
|
-
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* A source that is not a `LanguageAdapter` — the git history reader is the
|
|
174
|
-
* standing example — has nothing to detect and always runs. A `detect` that
|
|
175
|
-
* throws is treated as "did not detect", **with the reason recorded**: a broken
|
|
176
|
-
* detector must not be able to fail the whole run, and must not be able to hide
|
|
177
|
-
* either.
|
|
178
|
-
*/
|
|
124
|
+
/** Asks each loaded adapter whether it claims this repository. A non-`LanguageAdapter`
|
|
125
|
+
* source (the git reader) always runs. A throwing `detect` counts as "did not detect",
|
|
126
|
+
* with the reason recorded — it can't fail the whole run, and can't hide either. */
|
|
179
127
|
export async function detectSources(sources, root) {
|
|
180
128
|
const applicable = [];
|
|
181
129
|
const skipped = [];
|
package/dist/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/render.d.ts
CHANGED
|
@@ -35,6 +35,20 @@
|
|
|
35
35
|
* 4. `class == "action"` returning anything other than a handshake envelope on
|
|
36
36
|
* the first call → throw (§7) — enforced in `action-handshake.ts` and
|
|
37
37
|
* `server.ts`, not here: this module never sees a mint, only a redeemed run.
|
|
38
|
+
*
|
|
39
|
+
* ## A fifth invariant, B6: a truncated answer must carry real counts
|
|
40
|
+
*
|
|
41
|
+
* `result.truncated === true` with no `answer.truncatedDetail` used to fall
|
|
42
|
+
* back to a sentinel, `{shown: -1, total: -1}` — chosen to be "unmistakably
|
|
43
|
+
* fake," except that it is a number, so it passes any presence check and then
|
|
44
|
+
* poisons whatever arithmetic reads `total - shown`. A field that lies is
|
|
45
|
+
* worse than a field that is absent, which is the same argument the five
|
|
46
|
+
* result states rest on. So the sentinel is gone: a tool that sets
|
|
47
|
+
* `result.truncated` without a `truncatedDetail` is a programming error,
|
|
48
|
+
* thrown in every environment except production, where the envelope instead
|
|
49
|
+
* reports `truncated: null` plus a disclosure naming the gap — degraded
|
|
50
|
+
* honestly rather than dishonestly precise. See `capped()` in `./capped.ts`
|
|
51
|
+
* for how a tool is meant to avoid ever hitting this.
|
|
38
52
|
*/
|
|
39
53
|
import { type ReliabilityClass, type ReportCategory } from "@descryy/ir";
|
|
40
54
|
import type { ResultState, SignalTypeCount, ToolClass } from "@descryy/ir";
|
|
@@ -231,6 +245,19 @@ export interface AnswerEnvelope<T = unknown> {
|
|
|
231
245
|
readonly tool: string;
|
|
232
246
|
/** Contract §6, rule 8. A behaviour change is a version bump; recorded with the run. */
|
|
233
247
|
readonly toolVersion: string;
|
|
248
|
+
/**
|
|
249
|
+
* B10 — this call's own id in `Session#recordedCalls()`, minted before
|
|
250
|
+
* rendering (`Session#allocateCallId`) so it can be carried here rather
|
|
251
|
+
* than only discovered after the fact. A caller reads this off a real
|
|
252
|
+
* reply and cites it in `verify_claim`'s `callId` — the positive path that
|
|
253
|
+
* was previously unreachable because the id used to be minted only when
|
|
254
|
+
* `Session#recordCall` ran, one step after the envelope that would have
|
|
255
|
+
* carried it was already built and sent. Not recorded here — `verify_claim`
|
|
256
|
+
* itself is excluded from `Session#recordCall` (MK-12) and every other
|
|
257
|
+
* path still records under this same value, so the id an agent reads is
|
|
258
|
+
* always the id `recordedCall` will actually find.
|
|
259
|
+
*/
|
|
260
|
+
readonly callId: string;
|
|
234
261
|
readonly state: ResultState;
|
|
235
262
|
/** DEC-278's three classes — §6's retry table reads this. */
|
|
236
263
|
readonly class: ToolClass;
|
|
@@ -332,13 +359,16 @@ export interface AnswerEnvelope<T = unknown> {
|
|
|
332
359
|
*/
|
|
333
360
|
export declare const ANSWER_ENVELOPE_SCHEMA: Record<string, unknown>;
|
|
334
361
|
/**
|
|
335
|
-
* The other shape a `tools/call` can return — `renderToolError`'s
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
362
|
+
* The other shape a `tools/call` can return — `renderToolError`'s, now
|
|
363
|
+
* narrowed to the two cases where no tool was ever resolved (`name` not a
|
|
364
|
+
* string, or a name the registry does not have): there is no `ToolDefinition`
|
|
365
|
+
* to draw a real envelope from. A bad argument against a *resolved* tool goes
|
|
366
|
+
* through `renderRefusedInput` instead and is a real `state: "refused"`
|
|
367
|
+
* envelope — see that function's doc.
|
|
368
|
+
*
|
|
369
|
+
* Declared rather than quietly excluded. A schema that admitted only the
|
|
370
|
+
* envelope would be one the server itself violates on this narrower path.
|
|
371
|
+
* Declaring a union that is true beats declaring a single shape that is tidy.
|
|
342
372
|
*/
|
|
343
373
|
export declare const TOOL_ERROR_SCHEMA: Record<string, unknown>;
|
|
344
374
|
/**
|
|
@@ -360,6 +390,16 @@ export interface RenderOptions {
|
|
|
360
390
|
readonly toolTier: ToolTier;
|
|
361
391
|
readonly elapsedMs: number;
|
|
362
392
|
readonly limitMs: number;
|
|
393
|
+
/**
|
|
394
|
+
* B10 — the id this call will be recorded under, minted by
|
|
395
|
+
* `Session#allocateCallId()` before `renderAnswer` runs so it can be
|
|
396
|
+
* threaded into the envelope's own `callId`. Optional so every direct
|
|
397
|
+
* `renderAnswer` call in a test — none of which has a session's id
|
|
398
|
+
* sequence to draw from, and none of which asserts on `callId` — keeps
|
|
399
|
+
* compiling unchanged; a random id fills the gap there. `server.ts` is the
|
|
400
|
+
* one caller for which this matters and it always supplies a real one.
|
|
401
|
+
*/
|
|
402
|
+
readonly callId?: string;
|
|
363
403
|
/**
|
|
364
404
|
* This connection's record of which standing disclosures it has already been
|
|
365
405
|
* given in full. Optional: a caller with no session to dedupe within (every
|
|
@@ -389,18 +429,46 @@ export interface RenderOptions {
|
|
|
389
429
|
*/
|
|
390
430
|
export declare function renderAnswer<T>(tool: string, answer: ToolAnswer<T>, options: RenderOptions): CallToolResult;
|
|
391
431
|
/**
|
|
392
|
-
* A
|
|
432
|
+
* A malformed call the server cannot even attribute to one tool — the RPC
|
|
433
|
+
* named no string tool, or named a tool that does not exist in the registry.
|
|
393
434
|
*
|
|
394
435
|
* Returned as a tool result with `isError`, not as a JSON-RPC error, which is
|
|
395
436
|
* what the MCP spec asks for: protocol errors are for malformed protocol, tool
|
|
396
437
|
* errors are for tools, and an agent can act on the second only if it arrives as
|
|
397
438
|
* content it can read.
|
|
398
439
|
*
|
|
399
|
-
* Deliberately outside the five-state envelope
|
|
400
|
-
*
|
|
401
|
-
*
|
|
440
|
+
* Deliberately outside the five-state envelope, and narrowly so: there is no
|
|
441
|
+
* resolved `ToolDefinition` here to draw `toolVersion`/`class`/`tier` from, so
|
|
442
|
+
* no real envelope can be built — inventing placeholder values for them would
|
|
443
|
+
* be worse than the bare shape. Once a tool *is* identified, a bad argument
|
|
444
|
+
* against it is `renderRefusedInput`'s case, not this one — see that
|
|
445
|
+
* function's doc for why the two are different claims.
|
|
402
446
|
*/
|
|
403
447
|
export declare function renderToolError(tool: string, message: string): CallToolResult;
|
|
448
|
+
/**
|
|
449
|
+
* `state: "refused"` — the call named a real, resolved tool, but its input
|
|
450
|
+
* was wrong, so the tool never ran (`ToolInputError`, thrown by a tool's own
|
|
451
|
+
* argument reading, or by the dispatcher's own shape check on `arguments`
|
|
452
|
+
* once a tool is known).
|
|
453
|
+
*
|
|
454
|
+
* This used to fall through to `renderToolError`'s bare `{tool, status,
|
|
455
|
+
* message}` shape — measured as a real defect (a live `observe_runtime` call
|
|
456
|
+
* with a malformed `profile` field returned that bare shape instead of an
|
|
457
|
+
* envelope), because unlike the two cases `renderToolError` still covers, a
|
|
458
|
+
* `ToolDefinition` *is* available here: `toolVersion`, `class` and `tier` are
|
|
459
|
+
* all real, so a real envelope can be built rather than invented. "The tool
|
|
460
|
+
* was never run because its input was wrong" is a fact about this call, not
|
|
461
|
+
* about the code being examined — exactly what `state: "refused"` already
|
|
462
|
+
* means everywhere else in this file, so it is rendered the same way rather
|
|
463
|
+
* than through a second, parallel shape.
|
|
464
|
+
*
|
|
465
|
+
* `data` is always `null` (§2.2): nothing ran, so there is nothing to stamp.
|
|
466
|
+
* `isError` stays `true` for the same reason `renderFailed`/`renderTimedOut`
|
|
467
|
+
* set it — a generic client that only reads the transport-level signal still
|
|
468
|
+
* sees a failure; an AI-layer-aware caller additionally gets the real
|
|
469
|
+
* `state`/`disclosures`/`reportCategory` to reason about.
|
|
470
|
+
*/
|
|
471
|
+
export declare function renderRefusedInput(tool: string, message: string, options: RenderOptions): CallToolResult;
|
|
404
472
|
/**
|
|
405
473
|
* `state: "failed"` — §1.1: "promoted from a transport error to a result."
|
|
406
474
|
*
|
package/dist/render.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|
package/dist/render.js
CHANGED
|
@@ -35,7 +35,22 @@
|
|
|
35
35
|
* 4. `class == "action"` returning anything other than a handshake envelope on
|
|
36
36
|
* the first call → throw (§7) — enforced in `action-handshake.ts` and
|
|
37
37
|
* `server.ts`, not here: this module never sees a mint, only a redeemed run.
|
|
38
|
+
*
|
|
39
|
+
* ## A fifth invariant, B6: a truncated answer must carry real counts
|
|
40
|
+
*
|
|
41
|
+
* `result.truncated === true` with no `answer.truncatedDetail` used to fall
|
|
42
|
+
* back to a sentinel, `{shown: -1, total: -1}` — chosen to be "unmistakably
|
|
43
|
+
* fake," except that it is a number, so it passes any presence check and then
|
|
44
|
+
* poisons whatever arithmetic reads `total - shown`. A field that lies is
|
|
45
|
+
* worse than a field that is absent, which is the same argument the five
|
|
46
|
+
* result states rest on. So the sentinel is gone: a tool that sets
|
|
47
|
+
* `result.truncated` without a `truncatedDetail` is a programming error,
|
|
48
|
+
* thrown in every environment except production, where the envelope instead
|
|
49
|
+
* reports `truncated: null` plus a disclosure naming the gap — degraded
|
|
50
|
+
* honestly rather than dishonestly precise. See `capped()` in `./capped.ts`
|
|
51
|
+
* for how a tool is meant to avoid ever hitting this.
|
|
38
52
|
*/
|
|
53
|
+
import { randomUUID } from "node:crypto";
|
|
39
54
|
import { RELIABILITY_CLASSES, REPORT_CATEGORIES, RESULT_STATES, TOOL_CLASSES, reliabilityCap, reliabilityDisclosure, reportCategory as deriveReportCategory, } from "@descryy/ir";
|
|
40
55
|
/**
|
|
41
56
|
* MK-5 — which of the sixteen tools states a conclusion about the user's code
|
|
@@ -136,6 +151,11 @@ export const ANSWER_ENVELOPE_SCHEMA = {
|
|
|
136
151
|
type: "string",
|
|
137
152
|
description: "Bumped on any behaviour change; recorded with the run.",
|
|
138
153
|
},
|
|
154
|
+
callId: {
|
|
155
|
+
type: "string",
|
|
156
|
+
description: "This call's own id in this session's recorded tool calls. Cite it in verify_claim's " +
|
|
157
|
+
"\"callId\" to check a claim against this exact call's real result.",
|
|
158
|
+
},
|
|
139
159
|
state: {
|
|
140
160
|
type: "string",
|
|
141
161
|
enum: [...RESULT_STATES],
|
|
@@ -233,6 +253,7 @@ export const ANSWER_ENVELOPE_SCHEMA = {
|
|
|
233
253
|
required: [
|
|
234
254
|
"tool",
|
|
235
255
|
"toolVersion",
|
|
256
|
+
"callId",
|
|
236
257
|
"state",
|
|
237
258
|
"class",
|
|
238
259
|
"headline",
|
|
@@ -247,13 +268,16 @@ export const ANSWER_ENVELOPE_SCHEMA = {
|
|
|
247
268
|
],
|
|
248
269
|
};
|
|
249
270
|
/**
|
|
250
|
-
* The other shape a `tools/call` can return — `renderToolError`'s
|
|
271
|
+
* The other shape a `tools/call` can return — `renderToolError`'s, now
|
|
272
|
+
* narrowed to the two cases where no tool was ever resolved (`name` not a
|
|
273
|
+
* string, or a name the registry does not have): there is no `ToolDefinition`
|
|
274
|
+
* to draw a real envelope from. A bad argument against a *resolved* tool goes
|
|
275
|
+
* through `renderRefusedInput` instead and is a real `state: "refused"`
|
|
276
|
+
* envelope — see that function's doc.
|
|
251
277
|
*
|
|
252
|
-
* Declared rather than quietly excluded. A
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
* be one the server itself violates on that path. Declaring a union that is
|
|
256
|
-
* true beats declaring a single shape that is tidy.
|
|
278
|
+
* Declared rather than quietly excluded. A schema that admitted only the
|
|
279
|
+
* envelope would be one the server itself violates on this narrower path.
|
|
280
|
+
* Declaring a union that is true beats declaring a single shape that is tidy.
|
|
257
281
|
*/
|
|
258
282
|
export const TOOL_ERROR_SCHEMA = {
|
|
259
283
|
type: "object",
|
|
@@ -342,6 +366,26 @@ export function renderAnswer(tool, answer, options) {
|
|
|
342
366
|
'"we found nothing" from "we could not look" from "something broke"; with no reason attached ' +
|
|
343
367
|
"this reply says none of them.");
|
|
344
368
|
}
|
|
369
|
+
// B6, fifth invariant (module header): a truncated answer must carry real
|
|
370
|
+
// counts. The old fallback here was a sentinel, `{shown: -1, total: -1}` —
|
|
371
|
+
// worse than absent, because it passes a presence check and then poisons
|
|
372
|
+
// arithmetic. A tool that sets `result.truncated` without supplying
|
|
373
|
+
// `answer.truncatedDetail` has not held the two together the way
|
|
374
|
+
// `capped()` (`./capped.ts`) makes automatic, so this is a defect in that
|
|
375
|
+
// tool, caught here rather than shipped: thrown everywhere except
|
|
376
|
+
// production, where the honest degradation is `null` plus a disclosure
|
|
377
|
+
// that the count itself is unavailable — never a fabricated one.
|
|
378
|
+
let missingTruncationDetail = null;
|
|
379
|
+
if (result.truncated && answer.truncatedDetail === undefined) {
|
|
380
|
+
if (process.env["NODE_ENV"] !== "production") {
|
|
381
|
+
throw new DisclosureError(`${tool} set result.truncated without a truncatedDetail (shown/total). Build the capped ` +
|
|
382
|
+
'slice and its detail together — see capped() in "./capped.ts" — rather than capping ' +
|
|
383
|
+
"and reporting separately, where one of the two can be forgotten.");
|
|
384
|
+
}
|
|
385
|
+
missingTruncationDetail =
|
|
386
|
+
"this reply was truncated, but how much was withheld is unavailable — a defect in this " +
|
|
387
|
+
"tool, not a fact about your code";
|
|
388
|
+
}
|
|
345
389
|
const resolutionFloor = result.stamp.resolutionFloor;
|
|
346
390
|
const cap = reliabilityCap(resolutionFloor, nameLevel);
|
|
347
391
|
// Full the first time this connection meets this category, a short reference
|
|
@@ -350,6 +394,7 @@ export function renderAnswer(tool, answer, options) {
|
|
|
350
394
|
const reliability = reliabilityDisclosure(resolutionFloor, nameLevel);
|
|
351
395
|
const disclosures = [
|
|
352
396
|
...result.notes,
|
|
397
|
+
...(missingTruncationDetail === null ? [] : [missingTruncationDetail]),
|
|
353
398
|
options.disclosureLedger?.firstSighting(reliability.key) === false
|
|
354
399
|
? reliability.brief
|
|
355
400
|
: reliability.full,
|
|
@@ -360,9 +405,15 @@ export function renderAnswer(tool, answer, options) {
|
|
|
360
405
|
]
|
|
361
406
|
: []),
|
|
362
407
|
];
|
|
408
|
+
// B10 — minted by the caller before this call, so it is threaded through
|
|
409
|
+
// rather than generated here; a fallback exists only for the direct callers
|
|
410
|
+
// (tests) that have no session id sequence to draw from. See `callId`'s own
|
|
411
|
+
// doc on `AnswerEnvelope` and `RenderOptions`.
|
|
412
|
+
const callId = options.callId ?? randomUUID();
|
|
363
413
|
const build = (data, extraNotes, fitTruncation) => ({
|
|
364
414
|
tool,
|
|
365
415
|
toolVersion: options.toolVersion,
|
|
416
|
+
callId,
|
|
366
417
|
state,
|
|
367
418
|
class: options.toolClass,
|
|
368
419
|
headline: answer.headline,
|
|
@@ -376,10 +427,7 @@ export function renderAnswer(tool, answer, options) {
|
|
|
376
427
|
resolutionFloor,
|
|
377
428
|
reliabilityCap: cap,
|
|
378
429
|
},
|
|
379
|
-
truncated: fitTruncation ??
|
|
380
|
-
(!result.truncated
|
|
381
|
-
? null
|
|
382
|
-
: (answer.truncatedDetail ?? { shown: -1, total: -1, more: null })),
|
|
430
|
+
truncated: fitTruncation ?? (!result.truncated ? null : (answer.truncatedDetail ?? null)),
|
|
383
431
|
refusals: answer.refusalSummary ?? null,
|
|
384
432
|
budget: { elapsedMs: options.elapsedMs, limitMs: options.limitMs },
|
|
385
433
|
// The fit's own notes go first among the disclosures it added, ahead of
|
|
@@ -464,16 +512,20 @@ function narrate(envelope) {
|
|
|
464
512
|
return lines.join("\n");
|
|
465
513
|
}
|
|
466
514
|
/**
|
|
467
|
-
* A
|
|
515
|
+
* A malformed call the server cannot even attribute to one tool — the RPC
|
|
516
|
+
* named no string tool, or named a tool that does not exist in the registry.
|
|
468
517
|
*
|
|
469
518
|
* Returned as a tool result with `isError`, not as a JSON-RPC error, which is
|
|
470
519
|
* what the MCP spec asks for: protocol errors are for malformed protocol, tool
|
|
471
520
|
* errors are for tools, and an agent can act on the second only if it arrives as
|
|
472
521
|
* content it can read.
|
|
473
522
|
*
|
|
474
|
-
* Deliberately outside the five-state envelope
|
|
475
|
-
*
|
|
476
|
-
*
|
|
523
|
+
* Deliberately outside the five-state envelope, and narrowly so: there is no
|
|
524
|
+
* resolved `ToolDefinition` here to draw `toolVersion`/`class`/`tier` from, so
|
|
525
|
+
* no real envelope can be built — inventing placeholder values for them would
|
|
526
|
+
* be worse than the bare shape. Once a tool *is* identified, a bad argument
|
|
527
|
+
* against it is `renderRefusedInput`'s case, not this one — see that
|
|
528
|
+
* function's doc for why the two are different claims.
|
|
477
529
|
*/
|
|
478
530
|
export function renderToolError(tool, message) {
|
|
479
531
|
return {
|
|
@@ -482,6 +534,63 @@ export function renderToolError(tool, message) {
|
|
|
482
534
|
isError: true,
|
|
483
535
|
};
|
|
484
536
|
}
|
|
537
|
+
/**
|
|
538
|
+
* `state: "refused"` — the call named a real, resolved tool, but its input
|
|
539
|
+
* was wrong, so the tool never ran (`ToolInputError`, thrown by a tool's own
|
|
540
|
+
* argument reading, or by the dispatcher's own shape check on `arguments`
|
|
541
|
+
* once a tool is known).
|
|
542
|
+
*
|
|
543
|
+
* This used to fall through to `renderToolError`'s bare `{tool, status,
|
|
544
|
+
* message}` shape — measured as a real defect (a live `observe_runtime` call
|
|
545
|
+
* with a malformed `profile` field returned that bare shape instead of an
|
|
546
|
+
* envelope), because unlike the two cases `renderToolError` still covers, a
|
|
547
|
+
* `ToolDefinition` *is* available here: `toolVersion`, `class` and `tier` are
|
|
548
|
+
* all real, so a real envelope can be built rather than invented. "The tool
|
|
549
|
+
* was never run because its input was wrong" is a fact about this call, not
|
|
550
|
+
* about the code being examined — exactly what `state: "refused"` already
|
|
551
|
+
* means everywhere else in this file, so it is rendered the same way rather
|
|
552
|
+
* than through a second, parallel shape.
|
|
553
|
+
*
|
|
554
|
+
* `data` is always `null` (§2.2): nothing ran, so there is nothing to stamp.
|
|
555
|
+
* `isError` stays `true` for the same reason `renderFailed`/`renderTimedOut`
|
|
556
|
+
* set it — a generic client that only reads the transport-level signal still
|
|
557
|
+
* sees a failure; an AI-layer-aware caller additionally gets the real
|
|
558
|
+
* `state`/`disclosures`/`reportCategory` to reason about.
|
|
559
|
+
*/
|
|
560
|
+
export function renderRefusedInput(tool, message, options) {
|
|
561
|
+
const envelope = {
|
|
562
|
+
tool,
|
|
563
|
+
toolVersion: options.toolVersion,
|
|
564
|
+
callId: options.callId ?? randomUUID(),
|
|
565
|
+
state: "refused",
|
|
566
|
+
class: options.toolClass,
|
|
567
|
+
headline: `${tool} could not run: ${message}`,
|
|
568
|
+
data: null,
|
|
569
|
+
graph: {
|
|
570
|
+
commitSha: null,
|
|
571
|
+
builtAt: null,
|
|
572
|
+
irSchemaVersion: 0,
|
|
573
|
+
resolutionFloor: null,
|
|
574
|
+
reliabilityCap: "C",
|
|
575
|
+
},
|
|
576
|
+
truncated: null,
|
|
577
|
+
refusals: null,
|
|
578
|
+
budget: { elapsedMs: options.elapsedMs, limitMs: options.limitMs },
|
|
579
|
+
disclosures: [message],
|
|
580
|
+
// Same rule `deriveEnvelopeCategory` applies everywhere else: a
|
|
581
|
+
// conclusion-tier tool states its verdict in `headline`'s own words, so
|
|
582
|
+
// this stays null there; an evidence-tier tool's refusal maps to "not
|
|
583
|
+
// analysable" — "could not look" either way, whether the graph refused
|
|
584
|
+
// the query or the call never reached the graph at all.
|
|
585
|
+
reportCategory: options.toolTier === "conclusion" ? null : "not analysable",
|
|
586
|
+
provenance: PROVENANCE,
|
|
587
|
+
};
|
|
588
|
+
return {
|
|
589
|
+
content: [{ type: "text", text: narrate(envelope) }],
|
|
590
|
+
structuredContent: envelope,
|
|
591
|
+
isError: true,
|
|
592
|
+
};
|
|
593
|
+
}
|
|
485
594
|
/**
|
|
486
595
|
* `state: "failed"` — §1.1: "promoted from a transport error to a result."
|
|
487
596
|
*
|
|
@@ -497,6 +606,7 @@ export function renderFailed(tool, message, options) {
|
|
|
497
606
|
const envelope = {
|
|
498
607
|
tool,
|
|
499
608
|
toolVersion: options.toolVersion,
|
|
609
|
+
callId: options.callId ?? randomUUID(),
|
|
500
610
|
state: "failed",
|
|
501
611
|
class: options.toolClass,
|
|
502
612
|
headline: `${tool} failed.`,
|
|
@@ -540,6 +650,7 @@ export function renderHandshake(tool, token, willDo, options) {
|
|
|
540
650
|
const envelope = {
|
|
541
651
|
tool,
|
|
542
652
|
toolVersion: options.toolVersion,
|
|
653
|
+
callId: options.callId ?? randomUUID(),
|
|
543
654
|
state: "ok",
|
|
544
655
|
class: options.toolClass,
|
|
545
656
|
headline: `Confirmation required: ${willDo}`,
|
|
@@ -580,6 +691,7 @@ export function renderTimedOut(tool, options) {
|
|
|
580
691
|
const envelope = {
|
|
581
692
|
tool,
|
|
582
693
|
toolVersion: options.toolVersion,
|
|
694
|
+
callId: options.callId ?? randomUUID(),
|
|
583
695
|
state: "timed_out",
|
|
584
696
|
class: options.toolClass,
|
|
585
697
|
headline: `${tool} timed out.`,
|