@wootsup/mcp 0.1.0-rc.8 → 0.1.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/README.md +7 -7
- package/dist/index.d.ts +19 -0
- package/dist/index.js +72 -6
- package/dist/index.js.map +1 -1
- package/dist/modules/apimapper/cache.d.ts +2 -2
- package/dist/modules/apimapper/cache.js +107 -25
- package/dist/modules/apimapper/cache.js.map +1 -1
- package/dist/modules/apimapper/client.d.ts +40 -0
- package/dist/modules/apimapper/client.js +82 -12
- package/dist/modules/apimapper/client.js.map +1 -1
- package/dist/modules/apimapper/connections-format.d.ts +51 -0
- package/dist/modules/apimapper/connections-format.js +261 -0
- package/dist/modules/apimapper/connections-format.js.map +1 -0
- package/dist/modules/apimapper/connections-trim.d.ts +82 -0
- package/dist/modules/apimapper/connections-trim.js +224 -0
- package/dist/modules/apimapper/connections-trim.js.map +1 -0
- package/dist/modules/apimapper/connections.d.ts +14 -2
- package/dist/modules/apimapper/connections.js +447 -143
- package/dist/modules/apimapper/connections.js.map +1 -1
- package/dist/modules/apimapper/credentials-format.d.ts +21 -0
- package/dist/modules/apimapper/credentials-format.js +145 -0
- package/dist/modules/apimapper/credentials-format.js.map +1 -0
- package/dist/modules/apimapper/credentials.d.ts +12 -2
- package/dist/modules/apimapper/credentials.js +253 -72
- package/dist/modules/apimapper/credentials.js.map +1 -1
- package/dist/modules/apimapper/diagnose.d.ts +54 -2
- package/dist/modules/apimapper/diagnose.js +193 -11
- package/dist/modules/apimapper/diagnose.js.map +1 -1
- package/dist/modules/apimapper/elicitation.d.ts +54 -0
- package/dist/modules/apimapper/elicitation.js +90 -0
- package/dist/modules/apimapper/elicitation.js.map +1 -0
- package/dist/modules/apimapper/flows-format.d.ts +50 -0
- package/dist/modules/apimapper/flows-format.js +318 -0
- package/dist/modules/apimapper/flows-format.js.map +1 -0
- package/dist/modules/apimapper/flows.d.ts +13 -2
- package/dist/modules/apimapper/flows.js +325 -118
- package/dist/modules/apimapper/flows.js.map +1 -1
- package/dist/modules/apimapper/gateway/advanced-tool.d.ts +9 -0
- package/dist/modules/apimapper/gateway/advanced-tool.js +214 -0
- package/dist/modules/apimapper/gateway/advanced-tool.js.map +1 -0
- package/dist/modules/apimapper/gateway/capturing-server.d.ts +81 -0
- package/dist/modules/apimapper/gateway/capturing-server.js +87 -0
- package/dist/modules/apimapper/gateway/capturing-server.js.map +1 -0
- package/dist/modules/apimapper/gateway/essentials.d.ts +4 -0
- package/dist/modules/apimapper/gateway/essentials.js +28 -0
- package/dist/modules/apimapper/gateway/essentials.js.map +1 -0
- package/dist/modules/apimapper/gateway/test-support.d.ts +17 -0
- package/dist/modules/apimapper/gateway/test-support.js +43 -0
- package/dist/modules/apimapper/gateway/test-support.js.map +1 -0
- package/dist/modules/apimapper/get-skill.d.ts +3 -3
- package/dist/modules/apimapper/get-skill.js +4 -2
- package/dist/modules/apimapper/get-skill.js.map +1 -1
- package/dist/modules/apimapper/graph-builder.js +1 -1
- package/dist/modules/apimapper/graph-builder.js.map +1 -1
- package/dist/modules/apimapper/graph.d.ts +2 -2
- package/dist/modules/apimapper/graph.js +165 -34
- package/dist/modules/apimapper/graph.js.map +1 -1
- package/dist/modules/apimapper/index.d.ts +17 -1
- package/dist/modules/apimapper/index.js +66 -17
- package/dist/modules/apimapper/index.js.map +1 -1
- package/dist/modules/apimapper/inspect.d.ts +3 -2
- package/dist/modules/apimapper/inspect.js +97 -13
- package/dist/modules/apimapper/inspect.js.map +1 -1
- package/dist/modules/apimapper/library.d.ts +2 -2
- package/dist/modules/apimapper/library.js +303 -60
- package/dist/modules/apimapper/library.js.map +1 -1
- package/dist/modules/apimapper/license-format.d.ts +22 -0
- package/dist/modules/apimapper/license-format.js +149 -0
- package/dist/modules/apimapper/license-format.js.map +1 -0
- package/dist/modules/apimapper/license.d.ts +16 -2
- package/dist/modules/apimapper/license.js +85 -37
- package/dist/modules/apimapper/license.js.map +1 -1
- package/dist/modules/apimapper/local-sources.d.ts +2 -2
- package/dist/modules/apimapper/local-sources.js +58 -30
- package/dist/modules/apimapper/local-sources.js.map +1 -1
- package/dist/modules/apimapper/misc.d.ts +30 -2
- package/dist/modules/apimapper/misc.js +129 -50
- package/dist/modules/apimapper/misc.js.map +1 -1
- package/dist/modules/apimapper/node-schema.d.ts +52 -0
- package/dist/modules/apimapper/node-schema.js +70 -2
- package/dist/modules/apimapper/node-schema.js.map +1 -1
- package/dist/modules/apimapper/normalizers.d.ts +1 -0
- package/dist/modules/apimapper/normalizers.js +51 -0
- package/dist/modules/apimapper/normalizers.js.map +1 -1
- package/dist/modules/apimapper/onboarding.d.ts +48 -2
- package/dist/modules/apimapper/onboarding.js +324 -17
- package/dist/modules/apimapper/onboarding.js.map +1 -1
- package/dist/modules/apimapper/read-cache.d.ts +31 -2
- package/dist/modules/apimapper/read-cache.js +20 -6
- package/dist/modules/apimapper/read-cache.js.map +1 -1
- package/dist/modules/apimapper/render/_shared.d.ts +24 -0
- package/dist/modules/apimapper/render/_shared.js +84 -0
- package/dist/modules/apimapper/render/_shared.js.map +1 -0
- package/dist/modules/apimapper/render/dag.d.ts +18 -0
- package/dist/modules/apimapper/render/dag.js +70 -0
- package/dist/modules/apimapper/render/dag.js.map +1 -0
- package/dist/modules/apimapper/render/index.d.ts +2 -0
- package/dist/modules/apimapper/render/index.js +112 -0
- package/dist/modules/apimapper/render/index.js.map +1 -0
- package/dist/modules/apimapper/render/renderers/chart-bar.d.ts +2 -0
- package/dist/modules/apimapper/render/renderers/chart-bar.js +70 -0
- package/dist/modules/apimapper/render/renderers/chart-bar.js.map +1 -0
- package/dist/modules/apimapper/render/renderers/chart-line.d.ts +2 -0
- package/dist/modules/apimapper/render/renderers/chart-line.js +71 -0
- package/dist/modules/apimapper/render/renderers/chart-line.js.map +1 -0
- package/dist/modules/apimapper/render/renderers/diff.d.ts +2 -0
- package/dist/modules/apimapper/render/renderers/diff.js +154 -0
- package/dist/modules/apimapper/render/renderers/diff.js.map +1 -0
- package/dist/modules/apimapper/render/renderers/flow-diagram.d.ts +1 -0
- package/dist/modules/apimapper/render/renderers/flow-diagram.js +180 -0
- package/dist/modules/apimapper/render/renderers/flow-diagram.js.map +1 -0
- package/dist/modules/apimapper/render/renderers/json-tree.d.ts +2 -0
- package/dist/modules/apimapper/render/renderers/json-tree.js +87 -0
- package/dist/modules/apimapper/render/renderers/json-tree.js.map +1 -0
- package/dist/modules/apimapper/render/renderers/schema-diagram.d.ts +2 -0
- package/dist/modules/apimapper/render/renderers/schema-diagram.js +83 -0
- package/dist/modules/apimapper/render/renderers/schema-diagram.js.map +1 -0
- package/dist/modules/apimapper/render/renderers/table.d.ts +2 -0
- package/dist/modules/apimapper/render/renderers/table.js +75 -0
- package/dist/modules/apimapper/render/renderers/table.js.map +1 -0
- package/dist/modules/apimapper/render/schemas.d.ts +23 -0
- package/dist/modules/apimapper/render/schemas.js +56 -0
- package/dist/modules/apimapper/render/schemas.js.map +1 -0
- package/dist/modules/apimapper/render/secret-masking.d.ts +5 -0
- package/dist/modules/apimapper/render/secret-masking.js +51 -0
- package/dist/modules/apimapper/render/secret-masking.js.map +1 -0
- package/dist/modules/apimapper/render/sidecar.d.ts +21 -0
- package/dist/modules/apimapper/render/sidecar.js +66 -0
- package/dist/modules/apimapper/render/sidecar.js.map +1 -0
- package/dist/modules/apimapper/render/token-cap.d.ts +21 -0
- package/dist/modules/apimapper/render/token-cap.js +57 -0
- package/dist/modules/apimapper/render/token-cap.js.map +1 -0
- package/dist/modules/apimapper/schema.d.ts +2 -2
- package/dist/modules/apimapper/schema.js +100 -32
- package/dist/modules/apimapper/schema.js.map +1 -1
- package/dist/modules/apimapper/settings-format.d.ts +23 -0
- package/dist/modules/apimapper/settings-format.js +135 -0
- package/dist/modules/apimapper/settings-format.js.map +1 -0
- package/dist/modules/apimapper/settings.d.ts +2 -2
- package/dist/modules/apimapper/settings.js +101 -40
- package/dist/modules/apimapper/settings.js.map +1 -1
- package/dist/modules/apimapper/skill-resources.d.ts +2 -2
- package/dist/modules/apimapper/skill-resources.js.map +1 -1
- package/dist/modules/apimapper/token-baseline.harness.d.ts +91 -0
- package/dist/modules/apimapper/token-baseline.harness.js +291 -0
- package/dist/modules/apimapper/token-baseline.harness.js.map +1 -0
- package/dist/modules/apimapper/toolslist-size.d.ts +55 -0
- package/dist/modules/apimapper/toolslist-size.js +190 -0
- package/dist/modules/apimapper/toolslist-size.js.map +1 -0
- package/dist/modules/apimapper/types.d.ts +23 -8
- package/dist/modules/apimapper/types.js +26 -1
- package/dist/modules/apimapper/types.js.map +1 -1
- package/dist/modules/apimapper/use-profile.d.ts +21 -0
- package/dist/modules/apimapper/use-profile.js +56 -2
- package/dist/modules/apimapper/use-profile.js.map +1 -1
- package/dist/modules/apimapper/workflows.d.ts +2 -2
- package/dist/modules/apimapper/workflows.js +143 -16
- package/dist/modules/apimapper/workflows.js.map +1 -1
- package/dist/platform/index.js +44 -5
- package/dist/platform/index.js.map +1 -1
- package/dist/setup-cli.d.ts +53 -0
- package/dist/setup-cli.js +135 -6
- package/dist/setup-cli.js.map +1 -1
- package/docs/architecture.md +1 -1
- package/docs/tools.md +1 -1
- package/manifest.json +12 -3
- package/package.json +9 -4
- package/skills/apimapper/SKILL.md +1 -1
- package/skills/apimapper/reference/render.md +132 -0
- package/skills/apimapper/reference/troubleshooting.md +1 -1
- package/skills/apimapper/reference/yootheme.md +1 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const RENDER_TYPES: readonly ["table", "chart-bar", "chart-line", "schema-diagram", "flow-diagram", "json-tree", "diff"];
|
|
2
|
+
export type RenderType = (typeof RENDER_TYPES)[number];
|
|
3
|
+
export interface RenderOptions {
|
|
4
|
+
title?: string;
|
|
5
|
+
max_rows?: number;
|
|
6
|
+
columns?: string[];
|
|
7
|
+
depth?: number;
|
|
8
|
+
mask_secrets?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Routes a render request to its type-specific renderer.
|
|
12
|
+
*
|
|
13
|
+
* Each renderer owns its own Zod validation of the `data` payload — this
|
|
14
|
+
* dispatcher passes the raw payload through unchanged. The MCP tool boundary
|
|
15
|
+
* has already validated `type` against RENDER_TYPES.
|
|
16
|
+
*
|
|
17
|
+
* All 7 RenderType members are wired. `options` is threaded to every
|
|
18
|
+
* renderer that consumes it (table/schema-diagram/json-tree/chart-bar/
|
|
19
|
+
* chart-line/diff); flow-diagram has no per-type options and ignores it.
|
|
20
|
+
* The `default` branch's `never` assignment is a compile-time guarantee
|
|
21
|
+
* that no enum member is left unhandled.
|
|
22
|
+
*/
|
|
23
|
+
export declare function dispatchRenderer(type: RenderType, data: unknown, options: RenderOptions): string;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// render/schemas.ts — dispatcher + per-type validation entrypoint
|
|
2
|
+
import { renderFlowDiagram } from "./renderers/flow-diagram.js";
|
|
3
|
+
import { renderTable } from "./renderers/table.js";
|
|
4
|
+
import { renderSchemaDiagram } from "./renderers/schema-diagram.js";
|
|
5
|
+
import { renderJsonTree } from "./renderers/json-tree.js";
|
|
6
|
+
import { renderChartBar } from "./renderers/chart-bar.js";
|
|
7
|
+
import { renderChartLine } from "./renderers/chart-line.js";
|
|
8
|
+
import { renderDiff } from "./renderers/diff.js";
|
|
9
|
+
export const RENDER_TYPES = [
|
|
10
|
+
"table",
|
|
11
|
+
"chart-bar",
|
|
12
|
+
"chart-line",
|
|
13
|
+
"schema-diagram",
|
|
14
|
+
"flow-diagram",
|
|
15
|
+
"json-tree",
|
|
16
|
+
"diff",
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Routes a render request to its type-specific renderer.
|
|
20
|
+
*
|
|
21
|
+
* Each renderer owns its own Zod validation of the `data` payload — this
|
|
22
|
+
* dispatcher passes the raw payload through unchanged. The MCP tool boundary
|
|
23
|
+
* has already validated `type` against RENDER_TYPES.
|
|
24
|
+
*
|
|
25
|
+
* All 7 RenderType members are wired. `options` is threaded to every
|
|
26
|
+
* renderer that consumes it (table/schema-diagram/json-tree/chart-bar/
|
|
27
|
+
* chart-line/diff); flow-diagram has no per-type options and ignores it.
|
|
28
|
+
* The `default` branch's `never` assignment is a compile-time guarantee
|
|
29
|
+
* that no enum member is left unhandled.
|
|
30
|
+
*/
|
|
31
|
+
export function dispatchRenderer(type, data, options) {
|
|
32
|
+
switch (type) {
|
|
33
|
+
case "flow-diagram":
|
|
34
|
+
return renderFlowDiagram(data);
|
|
35
|
+
case "table":
|
|
36
|
+
return renderTable(data, options);
|
|
37
|
+
case "schema-diagram":
|
|
38
|
+
return renderSchemaDiagram(data, options);
|
|
39
|
+
case "json-tree":
|
|
40
|
+
return renderJsonTree(data, options);
|
|
41
|
+
case "chart-bar":
|
|
42
|
+
return renderChartBar(data, options);
|
|
43
|
+
case "chart-line":
|
|
44
|
+
return renderChartLine(data, options);
|
|
45
|
+
case "diff":
|
|
46
|
+
return renderDiff(data, options);
|
|
47
|
+
default: {
|
|
48
|
+
// Exhaustiveness check: this `never` assignment compiles only when
|
|
49
|
+
// every RenderType enum member has a matching case above. Adding a
|
|
50
|
+
// new viz-type without wiring it here becomes a compile error.
|
|
51
|
+
const _exhaustive = type;
|
|
52
|
+
throw new Error(`Renderer not implemented for type: ${String(_exhaustive)}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../../src/modules/apimapper/render/schemas.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,OAAO;IACP,WAAW;IACX,YAAY;IACZ,gBAAgB;IAChB,cAAc;IACd,WAAW;IACX,MAAM;CACE,CAAC;AAYX;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAgB,EAChB,IAAa,EACb,OAAsB;IAEtB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,cAAc;YACjB,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACjC,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,KAAK,gBAAgB;YACnB,OAAO,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5C,KAAK,WAAW;YACd,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvC,KAAK,WAAW;YACd,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvC,KAAK,YAAY;YACf,OAAO,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,OAAO,CAAC,CAAC,CAAC;YACR,mEAAmE;YACnE,mEAAmE;YACnE,+DAA+D;YAC/D,MAAM,WAAW,GAAU,IAAI,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,sCAAsC,MAAM,CAAC,WAAW,CAAC,EAAE,CAC5D,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// secret-masking.ts — allowlist of sensitive field names for the diff renderer.
|
|
2
|
+
//
|
|
3
|
+
// The diff renderer masks a changed value as `***` when the last path segment
|
|
4
|
+
// of its key is a known secret-bearing field. Matching is EXACT (the whole
|
|
5
|
+
// segment must equal an allowlist entry, case-insensitively) — never a
|
|
6
|
+
// substring test. A substring rule would over-mask innocent fields such as
|
|
7
|
+
// "api_key_name" or "username", hiding information the user needs to see.
|
|
8
|
+
//
|
|
9
|
+
// SCOPE — masking is intentionally limited to the `diff` renderer.
|
|
10
|
+
// `apimapper_render` is a PURE DISPLAY function: the calling LLM already
|
|
11
|
+
// holds (and passed in) every byte of `data`, so masking cannot be a
|
|
12
|
+
// containment boundary — it cannot hide anything the caller does not
|
|
13
|
+
// already have. It is purely defense-in-depth: a focused before/after diff
|
|
14
|
+
// is the output most likely to be pasted into a chat log or ticket, so
|
|
15
|
+
// blanking changed secret values there reduces accidental exposure.
|
|
16
|
+
// `table` / `json-tree` / `schema-diagram` deliberately do NOT mask — they
|
|
17
|
+
// render whatever the caller chose to pass, verbatim, with no value
|
|
18
|
+
// rewriting. Adding masking there would silently corrupt legitimate data
|
|
19
|
+
// the caller explicitly asked to see.
|
|
20
|
+
/** Field names whose values are masked in diff output (lower-case canonical). */
|
|
21
|
+
const SECRET_ALLOWLIST = new Set([
|
|
22
|
+
"password",
|
|
23
|
+
"secret",
|
|
24
|
+
"token",
|
|
25
|
+
"api_key",
|
|
26
|
+
"apikey",
|
|
27
|
+
"credential",
|
|
28
|
+
"credentials",
|
|
29
|
+
"auth_data",
|
|
30
|
+
"bearer_token",
|
|
31
|
+
"refresh_token",
|
|
32
|
+
"access_token",
|
|
33
|
+
"client_secret",
|
|
34
|
+
"private_key",
|
|
35
|
+
"pat",
|
|
36
|
+
"personal_access_token",
|
|
37
|
+
"session_token",
|
|
38
|
+
"webhook_secret",
|
|
39
|
+
"consumer_secret",
|
|
40
|
+
"signing_key",
|
|
41
|
+
"oauth_token",
|
|
42
|
+
"service_account",
|
|
43
|
+
]);
|
|
44
|
+
/**
|
|
45
|
+
* True when `name` exactly equals a known secret-bearing field name,
|
|
46
|
+
* compared case-insensitively. Partial / substring matches return false.
|
|
47
|
+
*/
|
|
48
|
+
export function isSecretFieldName(name) {
|
|
49
|
+
return SECRET_ALLOWLIST.has(name.toLowerCase());
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=secret-masking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-masking.js","sourceRoot":"","sources":["../../../../src/modules/apimapper/render/secret-masking.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,EAAE;AACF,8EAA8E;AAC9E,2EAA2E;AAC3E,uEAAuE;AACvE,2EAA2E;AAC3E,0EAA0E;AAC1E,EAAE;AACF,mEAAmE;AACnE,yEAAyE;AACzE,qEAAqE;AACrE,qEAAqE;AACrE,2EAA2E;AAC3E,uEAAuE;AACvE,oEAAoE;AACpE,2EAA2E;AAC3E,oEAAoE;AACpE,yEAAyE;AACzE,sCAAsC;AAEtC,iFAAiF;AACjF,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC;IACpD,UAAU;IACV,QAAQ;IACR,OAAO;IACP,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,aAAa;IACb,WAAW;IACX,cAAc;IACd,eAAe;IACf,cAAc;IACd,eAAe;IACf,aAAa;IACb,KAAK;IACL,uBAAuB;IACvB,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,aAAa;IACb,aAAa;IACb,iBAAiB;CAClB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `maxChars` for a mutation-tool response that carries a flow-visualization
|
|
3
|
+
* sidecar (flow_create / flow_update / graph_validate). The diagram is
|
|
4
|
+
* char-capped at DIAGRAM_PREVIEW_CAP (6000); JSON pretty-print escaping
|
|
5
|
+
* inflates it (\n → \\n), so this leaves headroom for the core response
|
|
6
|
+
* fields plus the escaped diagram — formatResult therefore never slices
|
|
7
|
+
* the JSON envelope mid-token. Shared by all three sidecar call-sites so
|
|
8
|
+
* the budget stays defined in exactly one place.
|
|
9
|
+
*/
|
|
10
|
+
export declare const SIDECAR_RESPONSE_MAX_CHARS = 16000;
|
|
11
|
+
export interface FlowVisualization {
|
|
12
|
+
diagram: string;
|
|
13
|
+
/** Instruction to the LLM to render `diagram` for the user. */
|
|
14
|
+
display_hint: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function buildFlowVisualization(flowLike: {
|
|
17
|
+
nodes?: unknown;
|
|
18
|
+
edges?: unknown;
|
|
19
|
+
id?: string;
|
|
20
|
+
name?: string;
|
|
21
|
+
}): FlowVisualization | null;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// render/sidecar.ts — buildFlowVisualization helper.
|
|
2
|
+
//
|
|
3
|
+
// Wraps renderFlowDiagram (Stage 1) with three safety layers so a flow
|
|
4
|
+
// visualization can be attached to mutation-tool responses without
|
|
5
|
+
// ever risking the host tool:
|
|
6
|
+
//
|
|
7
|
+
// 1. ENV opt-out — APIMAPPER_AUTO_VISUALIZE_FLOWS="false" disables
|
|
8
|
+
// the sidecar entirely. Default ON (any other value, or unset).
|
|
9
|
+
// 2. Defensive shape-gate + try/catch — nodes/edges must both be
|
|
10
|
+
// arrays, and any renderer throw (e.g. Zod .min(1) on empty
|
|
11
|
+
// nodes) is swallowed to null. The sidecar is additive: a render
|
|
12
|
+
// failure must never break flow_create / flow_update /
|
|
13
|
+
// graph_validate.
|
|
14
|
+
// 3. Diagram char-cap — the diagram string is bounded BEFORE it
|
|
15
|
+
// enters the response JSON. formatResult truncates the serialized
|
|
16
|
+
// JSON with a character-blind slice(); an unbounded diagram could
|
|
17
|
+
// push the envelope past maxChars and get cut mid-token, which
|
|
18
|
+
// would corrupt the WHOLE response (core fields included). Capping
|
|
19
|
+
// the diagram here keeps the JSON envelope always parseable.
|
|
20
|
+
import { renderFlowDiagram } from "./renderers/flow-diagram.js";
|
|
21
|
+
import { capRendered } from "./token-cap.js";
|
|
22
|
+
// Sidecar diagram preview cap. Deliberately far below the 25KB
|
|
23
|
+
// apimapper_render hard-cap: the sidecar is an inline *preview* attached
|
|
24
|
+
// to a mutation response, not the full render. 6000 chars still shows a
|
|
25
|
+
// useful ~50-node diagram; flows beyond that should call apimapper_render
|
|
26
|
+
// with type:"flow-diagram" for the complete picture. Bounding the diagram
|
|
27
|
+
// here guarantees the response JSON stays under the handler maxChars
|
|
28
|
+
// ceiling and therefore always survives JSON.parse downstream.
|
|
29
|
+
const DIAGRAM_PREVIEW_CAP = 6000;
|
|
30
|
+
/**
|
|
31
|
+
* `maxChars` for a mutation-tool response that carries a flow-visualization
|
|
32
|
+
* sidecar (flow_create / flow_update / graph_validate). The diagram is
|
|
33
|
+
* char-capped at DIAGRAM_PREVIEW_CAP (6000); JSON pretty-print escaping
|
|
34
|
+
* inflates it (\n → \\n), so this leaves headroom for the core response
|
|
35
|
+
* fields plus the escaped diagram — formatResult therefore never slices
|
|
36
|
+
* the JSON envelope mid-token. Shared by all three sidecar call-sites so
|
|
37
|
+
* the budget stays defined in exactly one place.
|
|
38
|
+
*/
|
|
39
|
+
export const SIDECAR_RESPONSE_MAX_CHARS = 16_000;
|
|
40
|
+
/**
|
|
41
|
+
* Constant `display_hint` attached to every flow-visualization sidecar.
|
|
42
|
+
* The `_visualization.diagram` string is a ready-to-show ASCII diagram;
|
|
43
|
+
* this hint tells the LLM to surface it to the user rather than treat it
|
|
44
|
+
* as opaque internal data.
|
|
45
|
+
*/
|
|
46
|
+
const FLOW_DISPLAY_HINT = "Show this flow diagram to the user.";
|
|
47
|
+
export function buildFlowVisualization(flowLike) {
|
|
48
|
+
// ENV opt-out — explicit "false" only. Unset / any other value = ON.
|
|
49
|
+
if (process.env.APIMAPPER_AUTO_VISUALIZE_FLOWS === "false")
|
|
50
|
+
return null;
|
|
51
|
+
// Defensive: only render when nodes AND edges are both arrays.
|
|
52
|
+
if (!Array.isArray(flowLike.nodes) || !Array.isArray(flowLike.edges)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
// capRendered truncates at a line boundary (never mid-line) and
|
|
57
|
+
// appends a clear "call apimapper_render for the full diagram" hint.
|
|
58
|
+
const diagram = capRendered(renderFlowDiagram(flowLike), "Call apimapper_render with type:\"flow-diagram\" for the full diagram.", DIAGRAM_PREVIEW_CAP);
|
|
59
|
+
return { diagram, display_hint: FLOW_DISPLAY_HINT };
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// Never break the host mutation tool because of the sidecar.
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=sidecar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../../../src/modules/apimapper/render/sidecar.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,uEAAuE;AACvE,mEAAmE;AACnE,8BAA8B;AAC9B,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,mEAAmE;AACnE,iEAAiE;AACjE,sEAAsE;AACtE,4DAA4D;AAC5D,uBAAuB;AACvB,kEAAkE;AAClE,uEAAuE;AACvE,uEAAuE;AACvE,oEAAoE;AACpE,wEAAwE;AACxE,kEAAkE;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,+DAA+D;AAC/D,yEAAyE;AACzE,wEAAwE;AACxE,0EAA0E;AAC1E,0EAA0E;AAC1E,qEAAqE;AACrE,+DAA+D;AAC/D,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAEjC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,qCAAqC,CAAC;AAQhE,MAAM,UAAU,sBAAsB,CAAC,QAKtC;IACC,qEAAqE;IACrE,IAAI,OAAO,CAAC,GAAG,CAAC,8BAA8B,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IACxE,+DAA+D;IAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,gEAAgE;QAChE,qEAAqE;QACrE,MAAM,OAAO,GAAG,WAAW,CACzB,iBAAiB,CAAC,QAAQ,CAAC,EAC3B,wEAAwE,EACxE,mBAAmB,CACpB,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,6DAA6D;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hard byte budget for `apimapper_render` output. Exported so the tool
|
|
3
|
+
* handler's `formatResult` maxChars can be derived from it (see
|
|
4
|
+
* render/index.ts) rather than hand-copied — keeping the two in lock-step
|
|
5
|
+
* is then compiler-enforced.
|
|
6
|
+
*/
|
|
7
|
+
export declare const HARD_CAP = 25000;
|
|
8
|
+
/**
|
|
9
|
+
* Truncation-footer slack reserved below `limit` so the appended
|
|
10
|
+
* "⚠ Output truncated…" footer always fits. Exported alongside HARD_CAP
|
|
11
|
+
* for the same derive-don't-duplicate reason.
|
|
12
|
+
*/
|
|
13
|
+
export declare const RESERVE = 500;
|
|
14
|
+
/**
|
|
15
|
+
* Truncate `text` to `limit` bytes at a line boundary (never mid-line) and
|
|
16
|
+
* append a footer with a type-specific `hint`. Small text passes through
|
|
17
|
+
* unchanged. `limit` defaults to the 25KB render hard-cap; the sidecar
|
|
18
|
+
* passes a smaller preview limit.
|
|
19
|
+
*/
|
|
20
|
+
export declare function capRendered(text: string, hint: string, limit?: number): string;
|
|
21
|
+
export declare function hintFor(type: string): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// render/token-cap.ts — byte-bounded, line-aligned output truncation.
|
|
2
|
+
//
|
|
3
|
+
// Two consumers share the same line-boundary truncation logic:
|
|
4
|
+
// - apimapper_render — hard 25KB cap on full rendered output.
|
|
5
|
+
// - the flow-visualization sidecar — a much smaller preview cap so the
|
|
6
|
+
// diagram never grows large enough to push a mutation-tool response
|
|
7
|
+
// JSON past its maxChars (which would otherwise be sliced mid-token
|
|
8
|
+
// by formatResult and corrupt the whole envelope).
|
|
9
|
+
/**
|
|
10
|
+
* Hard byte budget for `apimapper_render` output. Exported so the tool
|
|
11
|
+
* handler's `formatResult` maxChars can be derived from it (see
|
|
12
|
+
* render/index.ts) rather than hand-copied — keeping the two in lock-step
|
|
13
|
+
* is then compiler-enforced.
|
|
14
|
+
*/
|
|
15
|
+
export const HARD_CAP = 25_000;
|
|
16
|
+
/**
|
|
17
|
+
* Truncation-footer slack reserved below `limit` so the appended
|
|
18
|
+
* "⚠ Output truncated…" footer always fits. Exported alongside HARD_CAP
|
|
19
|
+
* for the same derive-don't-duplicate reason.
|
|
20
|
+
*/
|
|
21
|
+
export const RESERVE = 500;
|
|
22
|
+
/**
|
|
23
|
+
* Truncate `text` to `limit` bytes at a line boundary (never mid-line) and
|
|
24
|
+
* append a footer with a type-specific `hint`. Small text passes through
|
|
25
|
+
* unchanged. `limit` defaults to the 25KB render hard-cap; the sidecar
|
|
26
|
+
* passes a smaller preview limit.
|
|
27
|
+
*/
|
|
28
|
+
export function capRendered(text, hint, limit = HARD_CAP) {
|
|
29
|
+
if (Buffer.byteLength(text, "utf8") <= limit)
|
|
30
|
+
return text;
|
|
31
|
+
const lines = text.split("\n");
|
|
32
|
+
const kept = [];
|
|
33
|
+
let bytes = 0;
|
|
34
|
+
for (const line of lines) {
|
|
35
|
+
const lineBytes = Buffer.byteLength(line + "\n", "utf8");
|
|
36
|
+
if (bytes + lineBytes > limit - RESERVE)
|
|
37
|
+
break;
|
|
38
|
+
kept.push(line);
|
|
39
|
+
bytes += lineBytes;
|
|
40
|
+
}
|
|
41
|
+
// Footer KB figure is derived from `limit` so the message stays accurate
|
|
42
|
+
// for any cap (25KB render, smaller sidecar preview).
|
|
43
|
+
const kb = Math.round(limit / 1000);
|
|
44
|
+
return (kept.join("\n") +
|
|
45
|
+
`\n\n⚠ Output truncated to ${kb}KB. ${hint}\n` +
|
|
46
|
+
"Reduce data via options.max_rows or filter input upstream.");
|
|
47
|
+
}
|
|
48
|
+
export function hintFor(type) {
|
|
49
|
+
switch (type) {
|
|
50
|
+
case "table": return "Use options.max_rows to limit rows.";
|
|
51
|
+
case "json-tree": return "Use options.depth to reduce nesting.";
|
|
52
|
+
case "diff": return "Filter datasets to relevant fields first.";
|
|
53
|
+
case "flow-diagram": return "Flow has many nodes — consider splitting.";
|
|
54
|
+
default: return "Reduce input size.";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=token-cap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-cap.js","sourceRoot":"","sources":["../../../../src/modules/apimapper/render/token-cap.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,+DAA+D;AAC/D,gEAAgE;AAChE,yEAAyE;AACzE,wEAAwE;AACxE,wEAAwE;AACxE,uDAAuD;AACvD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC;AAC/B;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,CAAC;AAE3B;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,IAAY,EACZ,IAAY,EACZ,QAAgB,QAAQ;IAExB,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;QACzD,IAAI,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO;YAAE,MAAM;QAC/C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,KAAK,IAAI,SAAS,CAAC;IACrB,CAAC;IACD,yEAAyE;IACzE,sDAAsD;IACtD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACpC,OAAO,CACL,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QACf,6BAA6B,EAAE,OAAO,IAAI,IAAI;QAC9C,4DAA4D,CAC7D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO,CAAC,CAAQ,OAAO,qCAAqC,CAAC;QAClE,KAAK,WAAW,CAAC,CAAI,OAAO,sCAAsC,CAAC;QACnE,KAAK,MAAM,CAAC,CAAS,OAAO,2CAA2C,CAAC;QACxE,KAAK,cAAc,CAAC,CAAC,OAAO,2CAA2C,CAAC;QACxE,OAAO,CAAC,CAAa,OAAO,oBAAoB,CAAC;IACnD,CAAC;AACH,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function registerSchemaTools(server:
|
|
1
|
+
import type { ToolRegistrar } from "./gateway/capturing-server.js";
|
|
2
|
+
export declare function registerSchemaTools(server: ToolRegistrar): void;
|
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { formatResult,
|
|
2
|
+
import { formatResult, tableResult, errorResult, readOnly, } from "@getimo/mcp-toolkit";
|
|
3
3
|
import { request, hintFor } from "./client.js";
|
|
4
|
+
// ── node_snapshot_list table shape ────────────────────────────────────
|
|
5
|
+
const NODE_SNAPSHOT_COLUMNS = [
|
|
6
|
+
{ key: "flow_id", label: "FLOW", width: 24 },
|
|
7
|
+
{ key: "node_id", label: "NODE", width: 24 },
|
|
8
|
+
{ key: "fetched_at", label: "FETCHED", width: 22 },
|
|
9
|
+
{ key: "ttl_seconds", label: "TTL", width: 6 },
|
|
10
|
+
{ key: "is_stale", label: "STALE", width: 5 },
|
|
11
|
+
{ key: "payload_bytes", label: "BYTES", width: 8 },
|
|
12
|
+
];
|
|
13
|
+
// W1.19 (F-33): defense-in-depth aggregate byte budget on top of the row-cap.
|
|
14
|
+
// Even at limit:50, a misbehaving source could return 50 fat snapshots that
|
|
15
|
+
// blow past the LLM context budget. Cap aggregate payload at 2MB total.
|
|
16
|
+
const SNAPSHOT_AGGREGATE_BYTES_CAP = 2 * 1024 * 1024;
|
|
17
|
+
/**
|
|
18
|
+
* F-33: cap aggregate snapshot payload by byte-budget. Returns kept rows
|
|
19
|
+
* + truncation metadata. Defense-in-depth on top of the limit:50 row cap.
|
|
20
|
+
*
|
|
21
|
+
* Walks items in input order, summing JSON-serialised payload bytes; stops
|
|
22
|
+
* before adding any row whose payload would push the running total past
|
|
23
|
+
* `maxBytes`. Rows after the cutoff are reported as truncated but not
|
|
24
|
+
* returned.
|
|
25
|
+
*/
|
|
26
|
+
function capByAggregateBytes(items, maxBytes) {
|
|
27
|
+
let runningBytes = 0;
|
|
28
|
+
const kept = [];
|
|
29
|
+
for (const item of items) {
|
|
30
|
+
let payloadBytes = 0;
|
|
31
|
+
try {
|
|
32
|
+
payloadBytes = JSON.stringify(item.payload ?? {}).length;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
payloadBytes = 0;
|
|
36
|
+
}
|
|
37
|
+
if (runningBytes + payloadBytes > maxBytes)
|
|
38
|
+
break;
|
|
39
|
+
runningBytes += payloadBytes;
|
|
40
|
+
kept.push(item);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
kept,
|
|
44
|
+
truncatedCount: items.length - kept.length,
|
|
45
|
+
aggregateBytes: runningBytes,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
4
48
|
export function registerSchemaTools(server) {
|
|
5
49
|
// ── apimapper_schema_profile ───────────────────────────────────────
|
|
6
50
|
// F-A5-03: Real PHP contract is `{nodes, edges, target_node_id, flow_id?}`.
|
|
@@ -28,7 +72,7 @@ export function registerSchemaTools(server) {
|
|
|
28
72
|
.optional()
|
|
29
73
|
.describe("Optional flow id — enables NodeSnapshotRepository writes for hydrate path."),
|
|
30
74
|
},
|
|
31
|
-
annotations: readOnly(),
|
|
75
|
+
annotations: readOnly({ title: "Profile Source Schema", openWorld: true }),
|
|
32
76
|
}, async ({ nodes, edges, target_node_id, flow_id }) => {
|
|
33
77
|
const body = { nodes, edges, target_node_id };
|
|
34
78
|
if (flow_id)
|
|
@@ -38,13 +82,16 @@ export function registerSchemaTools(server) {
|
|
|
38
82
|
body: JSON.stringify(body),
|
|
39
83
|
});
|
|
40
84
|
if (!r.success) {
|
|
41
|
-
return
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
85
|
+
return errorResult({
|
|
86
|
+
message: r.error ?? "schema profile failed",
|
|
87
|
+
code: r.errorCode ?? (r.status ? String(r.status) : undefined),
|
|
88
|
+
suggestion: hintFor(r.errorCode),
|
|
89
|
+
details: {
|
|
90
|
+
target_node_id,
|
|
91
|
+
flow_id,
|
|
92
|
+
node_count: Array.isArray(nodes) ? nodes.length : 0,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
48
95
|
}
|
|
49
96
|
const merged = r.data?.merged ?? {};
|
|
50
97
|
const fields = Array.isArray(merged.fields) ? merged.fields : [];
|
|
@@ -68,26 +115,56 @@ export function registerSchemaTools(server) {
|
|
|
68
115
|
"\n\nExample:\n apimapper_node_snapshot_list({ flow_id: 'flow_Z2fLg70M84' })",
|
|
69
116
|
inputSchema: {
|
|
70
117
|
flow_id: z.string().describe("Flow ID (required). Use apimapper_flow_list to find."),
|
|
71
|
-
|
|
118
|
+
// W1.19 (F-33): row-cap lowered from max(500) → max(50). Old cap
|
|
119
|
+
// allowed up to ~2MB token spend per call. The handler also enforces
|
|
120
|
+
// an aggregate-bytes cap (SNAPSHOT_AGGREGATE_BYTES_CAP = 2MB) as
|
|
121
|
+
// defense-in-depth.
|
|
122
|
+
limit: z
|
|
123
|
+
.number()
|
|
124
|
+
.int()
|
|
125
|
+
.min(1)
|
|
126
|
+
.max(50)
|
|
127
|
+
.default(20)
|
|
128
|
+
.describe("Max items (1-50). Capped at 50 to keep aggregate snapshot payload within 2MB. Default 20."),
|
|
72
129
|
},
|
|
73
|
-
annotations: readOnly(),
|
|
130
|
+
annotations: readOnly({ title: "List Node Snapshots", openWorld: true }),
|
|
74
131
|
}, async ({ flow_id, limit }) => {
|
|
75
132
|
const params = new URLSearchParams();
|
|
76
133
|
params.set("flow_id", flow_id);
|
|
77
134
|
params.set("limit", String(limit));
|
|
78
135
|
const r = await request(`/node-snapshots?${params.toString()}`);
|
|
79
136
|
if (!r.success) {
|
|
80
|
-
return
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}, true);
|
|
137
|
+
return errorResult({
|
|
138
|
+
message: r.error ?? "node snapshot list failed",
|
|
139
|
+
code: r.errorCode ?? (r.status ? String(r.status) : undefined),
|
|
140
|
+
suggestion: hintFor(r.errorCode),
|
|
141
|
+
details: { flow_id, limit },
|
|
142
|
+
});
|
|
87
143
|
}
|
|
88
144
|
const items = Array.isArray(r.data?.snapshots) ? r.data.snapshots : [];
|
|
89
|
-
const
|
|
90
|
-
|
|
145
|
+
const serverTruncated = Boolean(r.data?.truncated);
|
|
146
|
+
// W1.19 (F-33): apply aggregate-bytes defense before rendering.
|
|
147
|
+
const { kept, truncatedCount: aggregateTruncatedCount, aggregateBytes, } = capByAggregateBytes(items, SNAPSHOT_AGGREGATE_BYTES_CAP);
|
|
148
|
+
const footerParts = [];
|
|
149
|
+
if (aggregateTruncatedCount > 0) {
|
|
150
|
+
footerParts.push(`Aggregate payload truncated at ${SNAPSHOT_AGGREGATE_BYTES_CAP} bytes ` +
|
|
151
|
+
`(${aggregateBytes} kept, ${aggregateTruncatedCount} dropped). ` +
|
|
152
|
+
`Lower limit or filter to specific node_id for full payloads.`);
|
|
153
|
+
}
|
|
154
|
+
if (serverTruncated) {
|
|
155
|
+
footerParts.push(`Result truncated at the server cap (limit=${limit}). More snapshots may exist.`);
|
|
156
|
+
}
|
|
157
|
+
// W1.19 (F-33): also render the aggregate-cap notice in the header so
|
|
158
|
+
// it survives table-row truncation in compact rendering mode. Footers
|
|
159
|
+
// are appended at the end of the rendered output and may be cut off
|
|
160
|
+
// when many rows are returned.
|
|
161
|
+
const headerSuffix = aggregateTruncatedCount > 0
|
|
162
|
+
? ` (aggregate cap: ${aggregateTruncatedCount} dropped at ${SNAPSHOT_AGGREGATE_BYTES_CAP} bytes)`
|
|
163
|
+
: "";
|
|
164
|
+
// W3.1 — tableResult: ASCII table for the LLM + typed DataTable payload
|
|
165
|
+
// for the Rich Card. The F-33 aggregate-bytes cap + the header/footer
|
|
166
|
+
// truncation notices are preserved.
|
|
167
|
+
return tableResult(kept.map((s) => {
|
|
91
168
|
let payloadBytes = 0;
|
|
92
169
|
try {
|
|
93
170
|
payloadBytes = JSON.stringify(s.payload ?? {}).length;
|
|
@@ -104,18 +181,9 @@ export function registerSchemaTools(server) {
|
|
|
104
181
|
payload_bytes: payloadBytes,
|
|
105
182
|
};
|
|
106
183
|
}), {
|
|
107
|
-
columns:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
{ key: "fetched_at", label: "FETCHED", width: 22 },
|
|
111
|
-
{ key: "ttl_seconds", label: "TTL", width: 6 },
|
|
112
|
-
{ key: "is_stale", label: "STALE", width: 5 },
|
|
113
|
-
{ key: "payload_bytes", label: "BYTES", width: 8 },
|
|
114
|
-
],
|
|
115
|
-
header: (n) => `${n} snapshots`,
|
|
116
|
-
footer: truncated
|
|
117
|
-
? `Result truncated at the server cap (limit=${limit}). More snapshots may exist.`
|
|
118
|
-
: undefined,
|
|
184
|
+
columns: NODE_SNAPSHOT_COLUMNS,
|
|
185
|
+
header: (n) => `${n} snapshots${headerSuffix}`,
|
|
186
|
+
footer: footerParts.length > 0 ? footerParts.join(" ") : undefined,
|
|
119
187
|
});
|
|
120
188
|
});
|
|
121
189
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/modules/apimapper/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/modules/apimapper/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type TableColumn } from "@getimo/mcp-toolkit";
|
|
2
|
+
export declare const HEALTH_WARNINGS_COLUMNS: TableColumn[];
|
|
3
|
+
export declare const HEALTH_WARNINGS_NEXT_STEPS: string;
|
|
4
|
+
/** health_warnings_list row map: warning item → table row. */
|
|
5
|
+
export declare function mapHealthWarningRow(w: Record<string, unknown>): Record<string, unknown>;
|
|
6
|
+
/**
|
|
7
|
+
* Build a structured detail view for settings_get.
|
|
8
|
+
*
|
|
9
|
+
* The settings dict is a flat scalar map (cache_ttl, debug_mode, log_level,
|
|
10
|
+
* …) — each key becomes a detail entry. The active license tier is the
|
|
11
|
+
* badge; the canonical SETTABLE_KEYS list + next-step calls go into an
|
|
12
|
+
* IA-10 "Next steps" group so the LLM reads the affordance in the text.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildSettingsDetail(tier: string | undefined, settings: Record<string, unknown>, settableKeys: readonly string[]): import("@getimo/mcp-toolkit").StructuredCallToolResult;
|
|
15
|
+
/**
|
|
16
|
+
* Build a structured detail view for features_get.
|
|
17
|
+
*
|
|
18
|
+
* The feature dict mixes booleans (jmespath: true) and numeric limits
|
|
19
|
+
* (max_connections: -1) — each key becomes a detail entry. The active tier
|
|
20
|
+
* is the badge; a single IA-10 "Next steps" group points at the license
|
|
21
|
+
* tools for upgrading a gated feature.
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildFeaturesDetail(tier: string | undefined, features: Record<string, unknown>): import("@getimo/mcp-toolkit").StructuredCallToolResult;
|