@wootsup/mcp 0.1.0 → 0.4.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/CHANGELOG.md +157 -83
- package/README.md +31 -27
- package/SECURITY.md +15 -6
- package/dist/auth/keychain.d.ts +27 -1
- package/dist/auth/keychain.js +48 -2
- package/dist/auth/keychain.js.map +1 -1
- package/dist/catalog/build-catalog.d.ts +31 -0
- package/dist/catalog/build-catalog.js +68 -0
- package/dist/catalog/build-catalog.js.map +1 -0
- package/dist/cli-hint.d.ts +22 -0
- package/dist/cli-hint.js +55 -0
- package/dist/cli-hint.js.map +1 -0
- package/dist/index.js +129 -22
- package/dist/index.js.map +1 -1
- package/dist/install-skill.js +1 -1
- package/dist/modules/apimapper/auto-layout.d.ts +21 -0
- package/dist/modules/apimapper/auto-layout.js +54 -0
- package/dist/modules/apimapper/auto-layout.js.map +1 -0
- package/dist/modules/apimapper/cache.js +25 -17
- package/dist/modules/apimapper/cache.js.map +1 -1
- package/dist/modules/apimapper/client.d.ts +115 -4
- package/dist/modules/apimapper/client.js +699 -304
- package/dist/modules/apimapper/client.js.map +1 -1
- package/dist/modules/apimapper/connections-format.d.ts +31 -1
- package/dist/modules/apimapper/connections-format.js +97 -5
- package/dist/modules/apimapper/connections-format.js.map +1 -1
- package/dist/modules/apimapper/connections.d.ts +9 -7
- package/dist/modules/apimapper/connections.js +449 -127
- package/dist/modules/apimapper/connections.js.map +1 -1
- package/dist/modules/apimapper/credential-sanitizer.d.ts +5 -0
- package/dist/modules/apimapper/credential-sanitizer.js +60 -1
- package/dist/modules/apimapper/credential-sanitizer.js.map +1 -1
- package/dist/modules/apimapper/credentials.js +105 -61
- package/dist/modules/apimapper/credentials.js.map +1 -1
- package/dist/modules/apimapper/diagnose.js +21 -2
- package/dist/modules/apimapper/diagnose.js.map +1 -1
- package/dist/modules/apimapper/elicitation.d.ts +29 -0
- package/dist/modules/apimapper/elicitation.js +62 -0
- package/dist/modules/apimapper/elicitation.js.map +1 -1
- package/dist/modules/apimapper/example-extract.d.ts +13 -0
- package/dist/modules/apimapper/example-extract.js +111 -0
- package/dist/modules/apimapper/example-extract.js.map +1 -0
- package/dist/modules/apimapper/filter-operators.d.ts +24 -0
- package/dist/modules/apimapper/filter-operators.js +103 -0
- package/dist/modules/apimapper/filter-operators.js.map +1 -0
- package/dist/modules/apimapper/flows-format.js +92 -22
- package/dist/modules/apimapper/flows-format.js.map +1 -1
- package/dist/modules/apimapper/flows.d.ts +8 -7
- package/dist/modules/apimapper/flows.js +275 -120
- package/dist/modules/apimapper/flows.js.map +1 -1
- package/dist/modules/apimapper/gateway/advanced-read-tool.d.ts +9 -0
- package/dist/modules/apimapper/gateway/advanced-read-tool.js +172 -0
- package/dist/modules/apimapper/gateway/advanced-read-tool.js.map +1 -0
- package/dist/modules/apimapper/gateway/advanced-tool.js +66 -106
- package/dist/modules/apimapper/gateway/advanced-tool.js.map +1 -1
- package/dist/modules/apimapper/gateway/collect-module-tools.d.ts +17 -0
- package/dist/modules/apimapper/gateway/collect-module-tools.js +44 -0
- package/dist/modules/apimapper/gateway/collect-module-tools.js.map +1 -0
- package/dist/modules/apimapper/gateway/essentials.d.ts +1 -1
- package/dist/modules/apimapper/gateway/essentials.js +21 -2
- package/dist/modules/apimapper/gateway/essentials.js.map +1 -1
- package/dist/modules/apimapper/gateway/gateway-shared.d.ts +21 -0
- package/dist/modules/apimapper/gateway/gateway-shared.js +124 -0
- package/dist/modules/apimapper/gateway/gateway-shared.js.map +1 -0
- package/dist/modules/apimapper/gateway/test-support.d.ts +1 -17
- package/dist/modules/apimapper/gateway/test-support.js +4 -33
- package/dist/modules/apimapper/gateway/test-support.js.map +1 -1
- package/dist/modules/apimapper/get-skill-cores.d.ts +4 -0
- package/dist/modules/apimapper/get-skill-cores.js +220 -0
- package/dist/modules/apimapper/get-skill-cores.js.map +1 -0
- package/dist/modules/apimapper/get-skill.d.ts +1 -1
- package/dist/modules/apimapper/get-skill.js +74 -9
- package/dist/modules/apimapper/get-skill.js.map +1 -1
- package/dist/modules/apimapper/graph-builder.d.ts +85 -2
- package/dist/modules/apimapper/graph-builder.js +151 -15
- package/dist/modules/apimapper/graph-builder.js.map +1 -1
- package/dist/modules/apimapper/graph.js +152 -48
- package/dist/modules/apimapper/graph.js.map +1 -1
- package/dist/modules/apimapper/index.js +27 -13
- package/dist/modules/apimapper/index.js.map +1 -1
- package/dist/modules/apimapper/jmespath-test.d.ts +4 -0
- package/dist/modules/apimapper/jmespath-test.js +152 -0
- package/dist/modules/apimapper/jmespath-test.js.map +1 -0
- package/dist/modules/apimapper/library.js +553 -88
- package/dist/modules/apimapper/library.js.map +1 -1
- package/dist/modules/apimapper/license.js +12 -36
- package/dist/modules/apimapper/license.js.map +1 -1
- package/dist/modules/apimapper/list-footer.d.ts +27 -0
- package/dist/modules/apimapper/list-footer.js +57 -0
- package/dist/modules/apimapper/list-footer.js.map +1 -0
- package/dist/modules/apimapper/local-sources.js +100 -57
- package/dist/modules/apimapper/local-sources.js.map +1 -1
- package/dist/modules/apimapper/mcp-client-identity.d.ts +32 -0
- package/dist/modules/apimapper/mcp-client-identity.js +70 -0
- package/dist/modules/apimapper/mcp-client-identity.js.map +1 -0
- package/dist/modules/apimapper/merge-constants.d.ts +6 -0
- package/dist/modules/apimapper/merge-constants.js +26 -0
- package/dist/modules/apimapper/merge-constants.js.map +1 -0
- package/dist/modules/apimapper/misc.js +13 -27
- package/dist/modules/apimapper/misc.js.map +1 -1
- package/dist/modules/apimapper/node-schema.d.ts +52 -2
- package/dist/modules/apimapper/node-schema.js +95 -4
- package/dist/modules/apimapper/node-schema.js.map +1 -1
- package/dist/modules/apimapper/onboarding.d.ts +59 -1
- package/dist/modules/apimapper/onboarding.js +231 -28
- package/dist/modules/apimapper/onboarding.js.map +1 -1
- package/dist/modules/apimapper/read-cache.d.ts +16 -3
- package/dist/modules/apimapper/read-cache.js +59 -4
- package/dist/modules/apimapper/read-cache.js.map +1 -1
- package/dist/modules/apimapper/render/index.js +26 -5
- package/dist/modules/apimapper/render/index.js.map +1 -1
- package/dist/modules/apimapper/resource-id.d.ts +13 -0
- package/dist/modules/apimapper/resource-id.js +69 -0
- package/dist/modules/apimapper/resource-id.js.map +1 -0
- package/dist/modules/apimapper/schema.js +9 -18
- package/dist/modules/apimapper/schema.js.map +1 -1
- package/dist/modules/apimapper/settings.js +49 -52
- package/dist/modules/apimapper/settings.js.map +1 -1
- package/dist/modules/apimapper/sites-tools.d.ts +29 -0
- package/dist/modules/apimapper/sites-tools.js +165 -0
- package/dist/modules/apimapper/sites-tools.js.map +1 -0
- package/dist/modules/apimapper/tool-result.d.ts +66 -0
- package/dist/modules/apimapper/tool-result.js +125 -0
- package/dist/modules/apimapper/tool-result.js.map +1 -0
- package/dist/modules/apimapper/toolslist-size.d.ts +12 -11
- package/dist/modules/apimapper/toolslist-size.js +34 -21
- package/dist/modules/apimapper/toolslist-size.js.map +1 -1
- package/dist/modules/apimapper/types.d.ts +34 -0
- package/dist/modules/apimapper/types.js +1 -1
- package/dist/modules/apimapper/types.js.map +1 -1
- package/dist/modules/apimapper/whitelist-drift.d.ts +85 -0
- package/dist/modules/apimapper/whitelist-drift.js +375 -0
- package/dist/modules/apimapper/whitelist-drift.js.map +1 -0
- package/dist/modules/apimapper/workflows.js +302 -58
- package/dist/modules/apimapper/workflows.js.map +1 -1
- package/dist/modules/apimapper/yootheme-binding.d.ts +35 -0
- package/dist/modules/apimapper/yootheme-binding.js +267 -0
- package/dist/modules/apimapper/yootheme-binding.js.map +1 -0
- package/dist/platform/index.d.ts +56 -0
- package/dist/platform/index.js +158 -2
- package/dist/platform/index.js.map +1 -1
- package/dist/proxy/bridge.d.ts +35 -0
- package/dist/proxy/bridge.js +129 -0
- package/dist/proxy/bridge.js.map +1 -0
- package/dist/proxy/mode.d.ts +9 -0
- package/dist/proxy/mode.js +20 -0
- package/dist/proxy/mode.js.map +1 -0
- package/dist/setup/detect-clients.d.ts +40 -1
- package/dist/setup/detect-clients.js +148 -1
- package/dist/setup/detect-clients.js.map +1 -1
- package/dist/setup/probe-auth.d.ts +51 -0
- package/dist/setup/probe-auth.js +141 -0
- package/dist/setup/probe-auth.js.map +1 -0
- package/dist/setup/probe-handshake.js +40 -7
- package/dist/setup/probe-handshake.js.map +1 -1
- package/dist/setup/remove-config.d.ts +8 -0
- package/dist/setup/remove-config.js +145 -0
- package/dist/setup/remove-config.js.map +1 -0
- package/dist/setup/uninstall.d.ts +34 -0
- package/dist/setup/uninstall.js +147 -0
- package/dist/setup/uninstall.js.map +1 -0
- package/dist/setup-cli.d.ts +16 -0
- package/dist/setup-cli.js +63 -1
- package/dist/setup-cli.js.map +1 -1
- package/dist/sites/loader.d.ts +48 -0
- package/dist/sites/loader.js +134 -0
- package/dist/sites/loader.js.map +1 -0
- package/dist/sites/schema.d.ts +69 -0
- package/dist/sites/schema.js +71 -0
- package/dist/sites/schema.js.map +1 -0
- package/dist/sites/secret-resolver.d.ts +47 -0
- package/dist/sites/secret-resolver.js +150 -0
- package/dist/sites/secret-resolver.js.map +1 -0
- package/dist/skill-instructions.d.ts +14 -1
- package/dist/skill-instructions.js +35 -6
- package/dist/skill-instructions.js.map +1 -1
- package/dist/transports/stdio.js +4 -4
- package/dist/transports/stdio.js.map +1 -1
- package/dist/uninstall-skill.d.ts +27 -0
- package/dist/uninstall-skill.js +89 -0
- package/dist/uninstall-skill.js.map +1 -0
- package/docs/architecture.md +21 -21
- package/docs/customgraph-internal-migration.md +4 -4
- package/docs/security.md +2 -21
- package/docs/tools.md +40 -12
- package/manifest.json +77 -79
- package/package.json +69 -65
- package/skills/apimapper/SKILL.md +128 -7
- package/skills/apimapper/reference/conditional-style-multi-items.md +114 -0
- package/skills/apimapper/reference/dynamize-existing-layout.md +158 -0
- package/skills/apimapper/reference/jmespath-cookbook.md +241 -0
- package/skills/apimapper/reference/jmespath-pitfalls.md +189 -0
- package/skills/apimapper/reference/joomla.md +1 -1
- package/skills/apimapper/reference/library-template-discovery.md +65 -0
- package/skills/apimapper/reference/merge-two-sources-on-key.md +204 -0
- package/skills/apimapper/reference/oauth.md +143 -52
- package/skills/apimapper/reference/troubleshooting.md +22 -2
- package/skills/apimapper/reference/yootheme-source-to-builder-handoff.md +348 -0
- package/skills/apimapper/reference/yootheme.md +75 -44
- package/dist/auth/oauth-provider.d.ts +0 -68
- package/dist/auth/oauth-provider.js +0 -232
- package/dist/auth/oauth-provider.js.map +0 -1
- package/dist/server-http.d.ts +0 -22
- package/dist/server-http.js +0 -159
- package/dist/server-http.js.map +0 -1
- package/dist/transports/http.d.ts +0 -29
- package/dist/transports/http.js +0 -267
- package/dist/transports/http.js.map +0 -1
|
@@ -2,16 +2,34 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Single source of truth for the "essentials" surface: the tools kept as
|
|
4
4
|
// first-class entries in `tools/list`. Cursor caps MCP servers at ~40 tools;
|
|
5
|
-
// the API Mapper adapter has
|
|
6
|
-
//
|
|
5
|
+
// the API Mapper adapter has 81 registered tools (18 module-real = 16 module
|
|
6
|
+
// essentials + the apimapper_advanced gateway + the apimapper_advanced_read
|
|
7
|
+
// gateway, + 60 advanced-registry tools, + 3 tools registered directly in
|
|
8
|
+
// src/index.ts), so all but the essentials are routed through the gateways
|
|
9
|
+
// (see advanced-tool.ts / advanced-read-tool.ts). That keeps the first-class
|
|
10
|
+
// `tools/list` surface at 21 — well under the cap. The canonical counts are
|
|
11
|
+
// asserted live in gateway/gateway.test.ts (A2); this comment cites what that
|
|
12
|
+
// test proves.
|
|
13
|
+
//
|
|
14
|
+
// F115 (2026-06-11): apimapper_health promoted from the advanced registry to
|
|
15
|
+
// a module-registered essential — the documented "run this first" verify tool
|
|
16
|
+
// was itself only reachable via the gateway (first-call deadend). This shifts
|
|
17
|
+
// module essentials 15→16, advanced 60→59 (total then 79).
|
|
18
|
+
//
|
|
19
|
+
// F200b (2026-06-12): apimapper_advanced_read added as a 2nd module-real
|
|
20
|
+
// gateway — module-real 17→18, surface 20→21, total 80→81. It whitelists the
|
|
21
|
+
// read-only advanced subtools (readOnlyHint-derived) and carries a readOnly
|
|
22
|
+
// annotation so hosts stop prompting on every advanced read.
|
|
7
23
|
/** Tools kept as first-class entries in tools/list (Cursor-cap-safe surface). */
|
|
8
24
|
export const ESSENTIAL_TOOLS = [
|
|
9
25
|
"apimapper_onboarding",
|
|
10
26
|
"apimapper_diagnose",
|
|
11
27
|
"apimapper_list_profiles",
|
|
12
28
|
"apimapper_use_profile",
|
|
29
|
+
"apimapper_library_featured",
|
|
13
30
|
"apimapper_library_list",
|
|
14
31
|
"apimapper_library_activate",
|
|
32
|
+
"apimapper_health",
|
|
15
33
|
"apimapper_connection_list",
|
|
16
34
|
"apimapper_connection_create",
|
|
17
35
|
"apimapper_connection_data",
|
|
@@ -19,6 +37,7 @@ export const ESSENTIAL_TOOLS = [
|
|
|
19
37
|
"apimapper_oauth_authorize_begin",
|
|
20
38
|
"apimapper_flow_setup_with_sources",
|
|
21
39
|
"apimapper_flow_full_recompile_publish",
|
|
40
|
+
"apimapper_yootheme_binding_for_flow",
|
|
22
41
|
"apimapper_render",
|
|
23
42
|
"apimapper_get_skill",
|
|
24
43
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"essentials.js","sourceRoot":"","sources":["../../../../src/modules/apimapper/gateway/essentials.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,4EAA4E;AAC5E,8EAA8E;
|
|
1
|
+
{"version":3,"file":"essentials.js","sourceRoot":"","sources":["../../../../src/modules/apimapper/gateway/essentials.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,8EAA8E;AAC9E,eAAe;AACf,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,8EAA8E;AAC9E,2DAA2D;AAC3D,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,4EAA4E;AAC5E,6DAA6D;AAE7D,iFAAiF;AACjF,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,sBAAsB;IACtB,oBAAoB;IACpB,yBAAyB;IACzB,uBAAuB;IACvB,4BAA4B;IAC5B,wBAAwB;IACxB,4BAA4B;IAC5B,kBAAkB;IAClB,2BAA2B;IAC3B,6BAA6B;IAC7B,2BAA2B;IAC3B,2BAA2B;IAC3B,iCAAiC;IACjC,mCAAmC;IACnC,uCAAuC;IACvC,qCAAqC;IACrC,kBAAkB;IAClB,qBAAqB;CACb,CAAC;AAUX,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAQ,eAAqC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { type ZodRawShape } from "zod";
|
|
3
|
+
import type { AdvancedToolEntry } from "./capturing-server.js";
|
|
4
|
+
export declare const DOMAIN_ORDER: readonly ["connection", "credential", "flow", "graph", "library", "license", "settings", "cache", "local_source", "schema", "diagnostics", "release", "brandfetch", "feedback", "features", "health", "inspect", "node_snapshot", "platform", "workflow", "onboarding", "render", "yootheme", "misc"];
|
|
5
|
+
/** Maps a tool name to its display domain (the segment after `apimapper_`). */
|
|
6
|
+
export declare function domainOf(toolName: string): string;
|
|
7
|
+
/** Groups tool names by domain, in DOMAIN_ORDER, for stable output. */
|
|
8
|
+
export declare function groupByDomain(toolNames: string[]): Map<string, string[]>;
|
|
9
|
+
/** Renders the grouped tool list as readable text (used in description + errors). */
|
|
10
|
+
export declare function renderGroupedList(toolNames: string[]): string;
|
|
11
|
+
/** Reads the captured config's inputSchema as a Zod raw-shape (or empty). */
|
|
12
|
+
export declare function shapeOf(entry: AdvancedToolEntry): ZodRawShape;
|
|
13
|
+
/**
|
|
14
|
+
* F200b: a registry entry is read-only when its annotation carries
|
|
15
|
+
* `readOnlyHint === true`. This is the SOLE classifier for the read gateway's
|
|
16
|
+
* whitelist — derived from the subtool's own annotation, zero per-provider
|
|
17
|
+
* branching.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isReadOnlyEntry(entry: AdvancedToolEntry): boolean;
|
|
20
|
+
/** Builds the discovery-mode result for a target tool. */
|
|
21
|
+
export declare function discoveryResult(toolName: string, entry: AdvancedToolEntry): CallToolResult;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// src/modules/apimapper/gateway/gateway-shared.ts — F200b
|
|
2
|
+
//
|
|
3
|
+
// Shared machinery for the two gateway tools:
|
|
4
|
+
// - apimapper_advanced (advanced-tool.ts) — every advanced subtool.
|
|
5
|
+
// - apimapper_advanced_read (advanced-read-tool.ts) — the READ-ONLY subset.
|
|
6
|
+
//
|
|
7
|
+
// Both expose the same two modes (discovery / execution), group their tool list
|
|
8
|
+
// by domain, and project a target's Zod inputSchema to JSON-Schema for
|
|
9
|
+
// discovery. Factoring it here keeps the read gateway free of per-provider
|
|
10
|
+
// branching and guarantees the two surfaces never drift in their rendering.
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
// Domains used to group advanced tool names in descriptions + errors. Kept in
|
|
13
|
+
// one place so both gateways render identical groupings.
|
|
14
|
+
export const DOMAIN_ORDER = [
|
|
15
|
+
"connection",
|
|
16
|
+
"credential",
|
|
17
|
+
"flow",
|
|
18
|
+
"graph",
|
|
19
|
+
"library",
|
|
20
|
+
"license",
|
|
21
|
+
"settings",
|
|
22
|
+
"cache",
|
|
23
|
+
"local_source",
|
|
24
|
+
"schema",
|
|
25
|
+
"diagnostics",
|
|
26
|
+
"release",
|
|
27
|
+
"brandfetch",
|
|
28
|
+
"feedback",
|
|
29
|
+
"features",
|
|
30
|
+
"health",
|
|
31
|
+
"inspect",
|
|
32
|
+
"node_snapshot",
|
|
33
|
+
"platform",
|
|
34
|
+
"workflow",
|
|
35
|
+
"onboarding",
|
|
36
|
+
"render",
|
|
37
|
+
"yootheme",
|
|
38
|
+
"misc",
|
|
39
|
+
];
|
|
40
|
+
/** Maps a tool name to its display domain (the segment after `apimapper_`). */
|
|
41
|
+
export function domainOf(toolName) {
|
|
42
|
+
const stem = toolName.replace(/^apimapper_/, "");
|
|
43
|
+
for (const domain of DOMAIN_ORDER) {
|
|
44
|
+
if (stem === domain || stem.startsWith(`${domain}_`))
|
|
45
|
+
return domain;
|
|
46
|
+
}
|
|
47
|
+
return "misc";
|
|
48
|
+
}
|
|
49
|
+
/** Groups tool names by domain, in DOMAIN_ORDER, for stable output. */
|
|
50
|
+
export function groupByDomain(toolNames) {
|
|
51
|
+
const groups = new Map();
|
|
52
|
+
for (const domain of DOMAIN_ORDER)
|
|
53
|
+
groups.set(domain, []);
|
|
54
|
+
for (const name of [...toolNames].sort()) {
|
|
55
|
+
const domain = domainOf(name);
|
|
56
|
+
const bucket = groups.get(domain);
|
|
57
|
+
if (bucket)
|
|
58
|
+
bucket.push(name);
|
|
59
|
+
}
|
|
60
|
+
for (const [domain, names] of groups) {
|
|
61
|
+
if (names.length === 0)
|
|
62
|
+
groups.delete(domain);
|
|
63
|
+
}
|
|
64
|
+
return groups;
|
|
65
|
+
}
|
|
66
|
+
/** Renders the grouped tool list as readable text (used in description + errors). */
|
|
67
|
+
export function renderGroupedList(toolNames) {
|
|
68
|
+
const groups = groupByDomain(toolNames);
|
|
69
|
+
const lines = [];
|
|
70
|
+
for (const [domain, names] of groups) {
|
|
71
|
+
lines.push(` ${domain}: ${names.join(", ")}`);
|
|
72
|
+
}
|
|
73
|
+
return lines.join("\n");
|
|
74
|
+
}
|
|
75
|
+
/** Reads the captured config's inputSchema as a Zod raw-shape (or empty). */
|
|
76
|
+
export function shapeOf(entry) {
|
|
77
|
+
const schema = entry.config.inputSchema;
|
|
78
|
+
if (schema && typeof schema === "object")
|
|
79
|
+
return schema;
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* F200b: a registry entry is read-only when its annotation carries
|
|
84
|
+
* `readOnlyHint === true`. This is the SOLE classifier for the read gateway's
|
|
85
|
+
* whitelist — derived from the subtool's own annotation, zero per-provider
|
|
86
|
+
* branching.
|
|
87
|
+
*/
|
|
88
|
+
export function isReadOnlyEntry(entry) {
|
|
89
|
+
const annotations = entry.config.annotations;
|
|
90
|
+
return annotations?.readOnlyHint === true;
|
|
91
|
+
}
|
|
92
|
+
/** Builds the discovery-mode result for a target tool. */
|
|
93
|
+
export function discoveryResult(toolName, entry) {
|
|
94
|
+
const cfg = entry.config;
|
|
95
|
+
let schema;
|
|
96
|
+
try {
|
|
97
|
+
schema = z.toJSONSchema(z.object(shapeOf(entry)));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// A schema that cannot be JSON-projected still yields a usable discovery
|
|
101
|
+
// payload — the description and annotations carry the rest.
|
|
102
|
+
schema = { note: "input schema could not be derived" };
|
|
103
|
+
}
|
|
104
|
+
const payload = {
|
|
105
|
+
tool: toolName,
|
|
106
|
+
description: cfg.description ?? "",
|
|
107
|
+
inputSchema: schema,
|
|
108
|
+
annotations: cfg.annotations ?? {},
|
|
109
|
+
};
|
|
110
|
+
return {
|
|
111
|
+
content: [
|
|
112
|
+
{
|
|
113
|
+
type: "text",
|
|
114
|
+
text: `Discovery for ${toolName}\n\n` +
|
|
115
|
+
`${cfg.description ?? ""}\n\n` +
|
|
116
|
+
`Annotations: ${JSON.stringify(cfg.annotations ?? {})}\n\n` +
|
|
117
|
+
`Input schema:\n${JSON.stringify(schema, null, 2)}\n\n` +
|
|
118
|
+
`Call the gateway again with { tool: "${toolName}", arguments: {...} } to run it.`,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
structuredContent: payload,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=gateway-shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway-shared.js","sourceRoot":"","sources":["../../../../src/modules/apimapper/gateway/gateway-shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
-
import type { ApimapperRestModule } from "../index.js";
|
|
4
|
-
/** A tool entry as seen by tests: handler + the registered config. */
|
|
5
|
-
export interface CollectedTool {
|
|
6
|
-
handler: (args: Record<string, unknown>, extra?: unknown) => CallToolResult | Promise<CallToolResult>;
|
|
7
|
-
title?: string;
|
|
8
|
-
description?: string;
|
|
9
|
-
inputSchema?: unknown;
|
|
10
|
-
annotations?: Record<string, unknown>;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Returns every API Mapper tool — the essentials registered on the real
|
|
14
|
-
* McpServer plus the advanced tools captured in the gateway registry —
|
|
15
|
-
* keyed by tool name. `module.register(server)` must have run first.
|
|
16
|
-
*/
|
|
17
|
-
export declare function collectModuleTools(server: McpServer, module: ApimapperRestModule): Record<string, CollectedTool>;
|
|
1
|
+
export { collectModuleTools, type CollectedTool, } from "./collect-module-tools.js";
|
|
@@ -7,37 +7,8 @@
|
|
|
7
7
|
// every tool (essentials on the real server + advanced from the registry),
|
|
8
8
|
// keeping their lookup semantics identical to the pre-gateway behaviour.
|
|
9
9
|
//
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* keyed by tool name. `module.register(server)` must have run first.
|
|
15
|
-
*/
|
|
16
|
-
export function collectModuleTools(server, module) {
|
|
17
|
-
const result = {};
|
|
18
|
-
const realTools = server._registeredTools;
|
|
19
|
-
for (const [name, tool] of Object.entries(realTools)) {
|
|
20
|
-
result[name] = {
|
|
21
|
-
handler: tool.handler,
|
|
22
|
-
title: tool.title,
|
|
23
|
-
description: tool.description,
|
|
24
|
-
inputSchema: tool.inputSchema,
|
|
25
|
-
annotations: tool.annotations,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
const advanced = module.getAdvancedRegistry();
|
|
29
|
-
if (advanced) {
|
|
30
|
-
for (const [name, entry] of advanced) {
|
|
31
|
-
const cfg = entry.config;
|
|
32
|
-
result[name] = {
|
|
33
|
-
handler: entry.handler,
|
|
34
|
-
title: cfg.title,
|
|
35
|
-
description: cfg.description,
|
|
36
|
-
inputSchema: cfg.inputSchema,
|
|
37
|
-
annotations: cfg.annotations,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return result;
|
|
42
|
-
}
|
|
10
|
+
// `collectModuleTools` + `CollectedTool` now live in `collect-module-tools.ts`
|
|
11
|
+
// (the build/release path imports them too, so they are NOT test-only). This
|
|
12
|
+
// module re-exports them so existing test imports keep working unchanged.
|
|
13
|
+
export { collectModuleTools, } from "./collect-module-tools.js";
|
|
43
14
|
//# sourceMappingURL=test-support.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-support.js","sourceRoot":"","sources":["../../../../src/modules/apimapper/gateway/test-support.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,4EAA4E;AAC5E,sEAAsE;AACtE,8EAA8E;AAC9E,4EAA4E;AAC5E,2EAA2E;AAC3E,yEAAyE;AACzE,EAAE;AACF,+
|
|
1
|
+
{"version":3,"file":"test-support.js","sourceRoot":"","sources":["../../../../src/modules/apimapper/gateway/test-support.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,4EAA4E;AAC5E,sEAAsE;AACtE,8EAA8E;AAC9E,4EAA4E;AAC5E,2EAA2E;AAC3E,yEAAyE;AACzE,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,0EAA0E;AAE1E,OAAO,EACL,kBAAkB,GAEnB,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SkillTopic } from "./get-skill.js";
|
|
2
|
+
/** Appended to every core so the agent can reach the long form. */
|
|
3
|
+
export declare const FULL_DOC_POINTER = "\n\nFull doc (long form, examples, pitfalls): apimapper_get_skill({ topic, full: true }).";
|
|
4
|
+
export declare const SKILL_CORES: Record<SkillTopic, string>;
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
// src/modules/apimapper/get-skill-cores.ts — F196 (Desktop-E2E #2, 2026-06-12)
|
|
2
|
+
//
|
|
3
|
+
// Condensed CORE for each skill topic. `apimapper_get_skill` returns the core
|
|
4
|
+
// BY DEFAULT (full markdown only with `full: true`). The forensics showed
|
|
5
|
+
// get_skill responses dominated the transcript — merge-two-sources-on-key
|
|
6
|
+
// alone was 11 KB, returned multiple times. The core keeps the
|
|
7
|
+
// recipe/patterns (join-key rules, transform[] cue, the one-call tool name)
|
|
8
|
+
// and drops prose + repeated examples; the long form stays one flag away.
|
|
9
|
+
//
|
|
10
|
+
// CONTRACT (pinned by get-skill.test.ts):
|
|
11
|
+
// - every core is < 2500 chars,
|
|
12
|
+
// - the big topics shrink dramatically vs the full markdown,
|
|
13
|
+
// - the merge core keeps joinKey/strategy + flat-merge + transform cue,
|
|
14
|
+
// - the dynamize core keeps page_dynamize + leaf_map,
|
|
15
|
+
// - the conditional-style core keeps the recipe element names.
|
|
16
|
+
//
|
|
17
|
+
// Each core ends with a one-line "full doc" pointer so the agent knows the
|
|
18
|
+
// long form is reachable.
|
|
19
|
+
/** Appended to every core so the agent can reach the long form. */
|
|
20
|
+
export const FULL_DOC_POINTER = "\n\nFull doc (long form, examples, pitfalls): apimapper_get_skill({ topic, full: true }).";
|
|
21
|
+
export const SKILL_CORES = {
|
|
22
|
+
"getting-started": [
|
|
23
|
+
"# API Mapper — getting started (core)",
|
|
24
|
+
"",
|
|
25
|
+
"Bridge any REST API into YOOtheme via a saved flow: Source → Filter → Transform → Output.",
|
|
26
|
+
"",
|
|
27
|
+
"## Step 1 (MANDATORY): check the library FIRST",
|
|
28
|
+
"apimapper_library_featured() / apimapper_library_list({ search }) → if a template",
|
|
29
|
+
"covers your API, activate it: apimapper_library_activate({ id, credential_id?, extra_fields? }).",
|
|
30
|
+
"Templates ship OAuth wizard, auto-header detection, curated YOOtheme schema, caching, items_path.",
|
|
31
|
+
"",
|
|
32
|
+
"## Step 2: custom connection_create — ONLY when no template fits",
|
|
33
|
+
"A custom create on a covered host is 409-blocked; the error names the template + the",
|
|
34
|
+
"apimapper_library_activate({ id }) call. Override with acknowledge_no_library:true only after a real 409.",
|
|
35
|
+
"",
|
|
36
|
+
"## Common tools",
|
|
37
|
+
"apimapper_health (run first), apimapper_connection_list/_get/_data, apimapper_flow_setup_with_sources,",
|
|
38
|
+
"apimapper_flow_full_recompile_publish (Save ≠ Publish), apimapper_yootheme_binding_for_flow.",
|
|
39
|
+
"Most tools are gateway-only: apimapper_advanced({ tool, arguments }). Read-only ones: apimapper_advanced_read.",
|
|
40
|
+
].join("\n"),
|
|
41
|
+
oauth: [
|
|
42
|
+
"# OAuth sources (core)",
|
|
43
|
+
"",
|
|
44
|
+
"## Canonical path for a covered API: activate the template",
|
|
45
|
+
"apimapper_library_activate({ id, credential_id, extra_fields }). extra_fields carries the",
|
|
46
|
+
"placeholder values (Sheets: the BARE spreadsheet_id, not the Drive URL). Never touch connection_create for a covered API.",
|
|
47
|
+
"",
|
|
48
|
+
"## Tool surface",
|
|
49
|
+
"top-level: apimapper_library_*, apimapper_credential_list, apimapper_oauth_authorize_begin.",
|
|
50
|
+
"GATEWAY-only: apimapper_credential_create / _get, apimapper_connection_test — call via",
|
|
51
|
+
"apimapper_advanced({ tool: 'apimapper_credential_create', arguments: {...} }).",
|
|
52
|
+
"",
|
|
53
|
+
"## Create an OAuth credential (none reusable)",
|
|
54
|
+
"1. apimapper_advanced({ tool:'apimapper_credential_create', arguments:{ auth_type:'oauth2_code',",
|
|
55
|
+
" oauth_provider:'google', auth_data:{ client_id, client_secret } } }) → { id } (NO authorize_url here).",
|
|
56
|
+
"2. apimapper_oauth_authorize_begin({ credential_id }) → { authorize_url }. SURFACE the URL to the user;",
|
|
57
|
+
" they consent, the callback writes access_token+refresh_token. Skip it → credential stays pending → 401.",
|
|
58
|
+
"Re-authorize an expired credential IN PLACE (same credential_id) — never delete+recreate (drops refresh token).",
|
|
59
|
+
"Custom connection (no template): apimapper_connection_create({ ..., endpoint, auth_type }).",
|
|
60
|
+
].join("\n"),
|
|
61
|
+
yootheme: [
|
|
62
|
+
"# Expose API Mapper sources to YOOtheme (core)",
|
|
63
|
+
"",
|
|
64
|
+
"## Publish pipeline (REST)",
|
|
65
|
+
"1. apimapper_flow_setup_with_sources(...) builds + saves the flow.",
|
|
66
|
+
"2. apimapper_flow_full_recompile_publish({ flow_id }) — compile + register + invalidate, in ONE call.",
|
|
67
|
+
" Save ≠ Publish: saving stores the flow but does NOT register the YOOtheme Source. Always publish.",
|
|
68
|
+
"3. apimapper_yootheme_binding_for_flow({ flow_id }) → the source name + flat field list to bind.",
|
|
69
|
+
"",
|
|
70
|
+
"## Bind into a Builder element (yt-builder)",
|
|
71
|
+
"yootheme_builder_advanced({ tool:'yootheme_builder_element_bind_source', arguments:{ bindingLevel, field_mappings } }).",
|
|
72
|
+
"Multi-Items (grid_item/list_item) bind at item level. Rich popups: add a DERIVED Transform field, map_item onto it.",
|
|
73
|
+
"Map element: bind `location` or it renders 0 pins. Use only real REST apimapper_* tools — no app_* tools.",
|
|
74
|
+
].join("\n"),
|
|
75
|
+
joomla: [
|
|
76
|
+
"# Joomla gotchas (core)",
|
|
77
|
+
"",
|
|
78
|
+
"## Endpoint shape — com_ajax envelope",
|
|
79
|
+
"index.php?option=com_ajax&plugin=apimapper&format=json&task=connections.list (NOT /wp-json on Joomla).",
|
|
80
|
+
"The MCP server resolves paths for you; let it.",
|
|
81
|
+
"",
|
|
82
|
+
"## Auth tiers",
|
|
83
|
+
"Tier 1 — Bearer fast-path (what credential_create uses, headless).",
|
|
84
|
+
"Tier 2 — Joomla user session. Tier 3 — OAuth trampoline (System Plugin event, stable callback URL).",
|
|
85
|
+
"",
|
|
86
|
+
"## Pitfalls",
|
|
87
|
+
"OAuth callback can fail silently when SEF rewriting swallows query params — verify with/without SEF.",
|
|
88
|
+
"com_ajax caches by URL — add &_= cache-bust in dev. Plugin lives in plugins/system/apimapper/.",
|
|
89
|
+
].join("\n"),
|
|
90
|
+
troubleshooting: [
|
|
91
|
+
"# Troubleshooting (core)",
|
|
92
|
+
"",
|
|
93
|
+
"Run apimapper_health FIRST. Triage by HTTP status:",
|
|
94
|
+
"- 401: MCP key MISSING/invalid → regenerate token + update client env. Credential expired →",
|
|
95
|
+
" apimapper_oauth_authorize_begin({ credential_id }), surface URL. Do NOT delete+recreate.",
|
|
96
|
+
"- 403: license tier blocks the action (2nd connection / JMESPath on Free) → apimapper_license_status.",
|
|
97
|
+
"- 404: plugin disabled (health → plugin:enabled) or wrong flow id → apimapper_flow_list.",
|
|
98
|
+
"- 422/400: body failed validation — read validation_errors[]; check shape vs apimapper_local_source_schema.",
|
|
99
|
+
"- 429: rate-limited → retry, raise cache_ttl, or bind to a same-schema mirror connection.",
|
|
100
|
+
"Depth-limit 422 → split the JMESPath into a transform[] ARRAY of stages (pipe resets the depth counter).",
|
|
101
|
+
].join("\n"),
|
|
102
|
+
render: [
|
|
103
|
+
"# Render (core)",
|
|
104
|
+
"",
|
|
105
|
+
"Two-step: fetch data, then apimapper_render({ type, data }). `type` is one of 7 viz-types:",
|
|
106
|
+
"- table — data: array of objects (apimapper_connection_data / graph_preview / flow_trace).",
|
|
107
|
+
"- chart-bar / chart-line — data: { labels[], values[] } (equal length).",
|
|
108
|
+
"- schema-diagram — data: a schema profile with fields[] (apimapper_schema_profile, pass through).",
|
|
109
|
+
"- flow-diagram — data: a flow with nodes[]+edges[] (apimapper_flow_get, pass the flow object).",
|
|
110
|
+
"- json-tree — data: any JSON value (catch-all inspector).",
|
|
111
|
+
"- diff — data: { old, new }.",
|
|
112
|
+
].join("\n"),
|
|
113
|
+
"jmespath-pitfalls": [
|
|
114
|
+
"# JMESPath pitfalls (core)",
|
|
115
|
+
"",
|
|
116
|
+
"GIBT-ES-NICHT: arithmetic (+ - * /), split, regex, if-else — use conditional(cond, then, else) or ternary `(cond && a) || b` and primitives.",
|
|
117
|
+
"Date/number/logic primitives (resolve in Transform AND apimapper_jmespath_test):",
|
|
118
|
+
"- date_weekday(iso, tz) → 'Wednesday'; date_iso_to_time(iso, tz) → '09:00'; date_iso_to_date(iso, tz) → 'YYYY-MM-DD'.",
|
|
119
|
+
"- time_in_window(t, open, close) — left-closed/right-open; handles cross-midnight.",
|
|
120
|
+
"- format_number(890000) → '890,000'. coalesce_empty(a, b) for fallbacks.",
|
|
121
|
+
"- conditional(cond, then, else?) — flat if/else; returns a falsy then verbatim (sidesteps the ternary trap).",
|
|
122
|
+
"DEPTH CAP = 10. A deep reshape fails with a depth-limit 422 — SPLIT into a transform[] ARRAY of stages;",
|
|
123
|
+
"the pipe between stages resets the depth counter, so each stage gets its own budget.",
|
|
124
|
+
"Iterate risk-free with apimapper_jmespath_test({ expression, sample_rows }).",
|
|
125
|
+
].join("\n"),
|
|
126
|
+
"jmespath-cookbook": [
|
|
127
|
+
"# JMESPath cookbook (core)",
|
|
128
|
+
"",
|
|
129
|
+
"Copy-paste patterns (iterate via apimapper_jmespath_test):",
|
|
130
|
+
"- if/else: conditional(stock > `0`, 'in stock', 'sold out') - or ternary: color: (priority == `high` && `danger`) || `muted`",
|
|
131
|
+
"- join: join(', ', tags) - sort: sort_by(@, &price) - coordinates: [lat, lng]",
|
|
132
|
+
"- numbers: format_number(price) → '1,250,000' - dates: date_weekday/date_iso_to_time/date_iso_to_date.",
|
|
133
|
+
"GIBT-ES-NICHT: arithmetic, split, regex, if-else → use conditional(cond, then, else) or ternary + primitives.",
|
|
134
|
+
"Two-Transform split: when one expression overflows depth 10, pass transform as an ARRAY of stages —",
|
|
135
|
+
"each stage gets its own depth budget; the pipe between stages resets the counter.",
|
|
136
|
+
].join("\n"),
|
|
137
|
+
"merge-two-sources-on-key": [
|
|
138
|
+
"# Merge two sources on a shared key (core)",
|
|
139
|
+
"",
|
|
140
|
+
"## Recipe (REST, one call)",
|
|
141
|
+
"apimapper_flow_setup_with_sources({ name, sources:[{connection:A},{connection:B}],",
|
|
142
|
+
" merge:{ strategy:'join', joinKey:'<A-field>', joinKeyRight:'<B-field>', joinType:'left' },",
|
|
143
|
+
" filter?, output:{ type:'yootheme', name } }).",
|
|
144
|
+
"Vocabulary is strategy/joinKey (NOT the UI words mode/key). joinType 'left' keeps every A row; 'inner' drops unmatched.",
|
|
145
|
+
"Omit joinKeyRight when both sides name the field the same.",
|
|
146
|
+
"",
|
|
147
|
+
"## Discover the join key FIRST (guessing wrong = 0 rows, no error)",
|
|
148
|
+
"Sample both sides: apimapper_connection_data({ id:A, limit:3 }) and { id:B, limit:3 }.",
|
|
149
|
+
"Keys compare with === — string 'P-100' never equals number 42; case + whitespace matter.",
|
|
150
|
+
"Not comparable? Bridge with a Transform BEFORE merge (e.g. date_weekday for ISO↔weekday joins).",
|
|
151
|
+
"",
|
|
152
|
+
"## Flat-merge contract (no `b.` prefix)",
|
|
153
|
+
"B fields land FLAT on the A row. Bind to the bare name (`rating`), never `b.rating` (always null).",
|
|
154
|
+
"Same-name collision: A keeps the key, B becomes branch_1_<field>.",
|
|
155
|
+
"",
|
|
156
|
+
"## 0 rows? read merge_diagnostics[<node>] (reason: merge_no_match) with left/right_key_sample.",
|
|
157
|
+
"Deep reshape on either side overflows depth 10 → split into a transform[] ARRAY of stages.",
|
|
158
|
+
].join("\n"),
|
|
159
|
+
"conditional-style-multi-items": [
|
|
160
|
+
"# Conditional style on Multi-Items (core)",
|
|
161
|
+
"",
|
|
162
|
+
"TRAP: text_style does NOT accept 'primary' — text_style is a typographic role (meta/lead/small/large).",
|
|
163
|
+
"For a primary COLOR use text_color:'primary' on the text element, or wrap in grid_item with panel_style:'primary'.",
|
|
164
|
+
"Enums: text_color ∈ muted/emphasis/primary/secondary/success/warning/danger; panel_style ∈ default/primary/secondary.",
|
|
165
|
+
"",
|
|
166
|
+
"## Recipe A — text_color from a row field",
|
|
167
|
+
"Transform precomputes a valid enum: color: (priority==`high` && `danger`) || `warning`.",
|
|
168
|
+
"Multi-Items text child binds: text_color → ${item.color}; text_style stays a literal ('lead').",
|
|
169
|
+
"",
|
|
170
|
+
"## Recipe B — panel_style wrapper from a row field",
|
|
171
|
+
"Wrap the row in a grid_item; bind panel_style → ${item.panelKey} (precomputed enum). Inner text stays neutral.",
|
|
172
|
+
].join("\n"),
|
|
173
|
+
"library-template-discovery": [
|
|
174
|
+
"# Library template discovery (core)",
|
|
175
|
+
"",
|
|
176
|
+
"Before apimapper_library_activate, inspect the template to learn its auth + required placeholders.",
|
|
177
|
+
"Sequence: apimapper_library_list / _featured → pick id →",
|
|
178
|
+
"apimapper_library_connection_detail({ id }) → read base_url (which API), auth scheme, and extra_fields",
|
|
179
|
+
"(the placeholder values YOU must supply, e.g. spreadsheet_id, api_key — unset = broken connection).",
|
|
180
|
+
"Then ACTIVATE (not create): apimapper_library_activate({ id, credential_id?, extra_fields }).",
|
|
181
|
+
"Auth-protected templates: create/pick the credential first, pass credential_id explicitly.",
|
|
182
|
+
"The library-first guard 409-blocks a custom create on a covered host and names the activate call.",
|
|
183
|
+
].join("\n"),
|
|
184
|
+
"yootheme-source-to-builder-handoff": [
|
|
185
|
+
"# apimapper → yt-builder handoff (core)",
|
|
186
|
+
"",
|
|
187
|
+
"## Bridge: recompile → binding_for_flow → bind via the gateway",
|
|
188
|
+
"1. apimapper_flow_full_recompile_publish({ flow_id }).",
|
|
189
|
+
"2. apimapper_yootheme_binding_for_flow({ flow_id }) → source_name (apiMapperFlow<Id>List) + flat field list.",
|
|
190
|
+
"3. yootheme_builder_advanced({ tool:'yootheme_builder_element_bind_source',",
|
|
191
|
+
" arguments:{ element_id, bindingLevel, field_mappings } }).",
|
|
192
|
+
"field_mappings is a FULL REPLACE — every call replaces ALL mappings; resend every field you want to keep.",
|
|
193
|
+
"Multi-Items: bind at item level (grid_item/list_item); use map_item for derived/rich fields.",
|
|
194
|
+
"",
|
|
195
|
+
"## Dynamize an EXISTING designed layout (#parent repeater form)",
|
|
196
|
+
"The theme-canonical form: a column carries the iterating query; the child fragment clones via query.name '#parent';",
|
|
197
|
+
"leaves bind #parent + props. Per-row visibility rides on _condition with filters.condition '!' / '!!'",
|
|
198
|
+
"(booleans are unreliable — emit '' / 'next' string flags, empty/filled string semantics).",
|
|
199
|
+
"Find a design that lives inside another article via yootheme_builder_template_summary → named_sections.",
|
|
200
|
+
"WARN: article-context cells are ~20% narrower than category templates — verify visually at the target viewport.",
|
|
201
|
+
].join("\n"),
|
|
202
|
+
"dynamize-existing-layout": [
|
|
203
|
+
"# Dynamize an existing designed layout (core)",
|
|
204
|
+
"",
|
|
205
|
+
"ONE RULE: copy the reference subtree byte-identically, change ONLY leaf field names. Insert nothing, rebuild nothing.",
|
|
206
|
+
"",
|
|
207
|
+
"## The loop — 2 discovery steps, then ONE call",
|
|
208
|
+
"1. FIND the section: yootheme_builder_template_summary → named_sections (the design often lives inside another article).",
|
|
209
|
+
"2. READ the source + flat fields: apimapper_yootheme_binding_for_flow({ flow_id }) → source_name (apiMapperFlow<Id>List).",
|
|
210
|
+
"3. DYNAMIZE in ONE call: yootheme_builder_page_dynamize({ template_id, section_path, source_name,",
|
|
211
|
+
" leaf_map: { '<original nested leaf>': '<your flat flow field>', ... }, publish:true }).",
|
|
212
|
+
" The server copies the subtree, swaps the query name + leaf names from leaf_map, inserts nothing, publishes.",
|
|
213
|
+
"4. VERIFY: render the public URL, compare one row to the original at the customer's viewport (wrap/overlap = fail).",
|
|
214
|
+
"",
|
|
215
|
+
"leaf_map example: 'field.home_team.crest.imagefile' → 'home_crest'. A leaf with no flow field is left KEPT.",
|
|
216
|
+
"The tool guarantees the hard rules (flat≠nested is fine, insert nothing, never invent asset paths) BY CONSTRUCTION.",
|
|
217
|
+
"Per-row visibility: emit '' / 'next' string flags, highlight via copied _condition filters.condition '!!'.",
|
|
218
|
+
].join("\n"),
|
|
219
|
+
};
|
|
220
|
+
//# sourceMappingURL=get-skill-cores.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-skill-cores.js","sourceRoot":"","sources":["../../../src/modules/apimapper/get-skill-cores.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,8EAA8E;AAC9E,0EAA0E;AAC1E,0EAA0E;AAC1E,+DAA+D;AAC/D,4EAA4E;AAC5E,0EAA0E;AAC1E,EAAE;AACF,0CAA0C;AAC1C,kCAAkC;AAClC,+DAA+D;AAC/D,0EAA0E;AAC1E,wDAAwD;AACxD,iEAAiE;AACjE,EAAE;AACF,2EAA2E;AAC3E,0BAA0B;AAI1B,mEAAmE;AACnE,MAAM,CAAC,MAAM,gBAAgB,GAC3B,2FAA2F,CAAC;AAE9F,MAAM,CAAC,MAAM,WAAW,GAA+B;IACrD,iBAAiB,EAAE;QACjB,uCAAuC;QACvC,EAAE;QACF,2FAA2F;QAC3F,EAAE;QACF,gDAAgD;QAChD,mFAAmF;QACnF,kGAAkG;QAClG,mGAAmG;QACnG,EAAE;QACF,kEAAkE;QAClE,sFAAsF;QACtF,2GAA2G;QAC3G,EAAE;QACF,iBAAiB;QACjB,wGAAwG;QACxG,8FAA8F;QAC9F,gHAAgH;KACjH,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,KAAK,EAAE;QACL,wBAAwB;QACxB,EAAE;QACF,4DAA4D;QAC5D,2FAA2F;QAC3F,2HAA2H;QAC3H,EAAE;QACF,iBAAiB;QACjB,6FAA6F;QAC7F,wFAAwF;QACxF,gFAAgF;QAChF,EAAE;QACF,+CAA+C;QAC/C,kGAAkG;QAClG,2GAA2G;QAC3G,yGAAyG;QACzG,4GAA4G;QAC5G,iHAAiH;QACjH,6FAA6F;KAC9F,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,QAAQ,EAAE;QACR,gDAAgD;QAChD,EAAE;QACF,4BAA4B;QAC5B,oEAAoE;QACpE,uGAAuG;QACvG,sGAAsG;QACtG,kGAAkG;QAClG,EAAE;QACF,6CAA6C;QAC7C,yHAAyH;QACzH,qHAAqH;QACrH,2GAA2G;KAC5G,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,MAAM,EAAE;QACN,yBAAyB;QACzB,EAAE;QACF,uCAAuC;QACvC,wGAAwG;QACxG,gDAAgD;QAChD,EAAE;QACF,eAAe;QACf,oEAAoE;QACpE,qGAAqG;QACrG,EAAE;QACF,aAAa;QACb,sGAAsG;QACtG,gGAAgG;KACjG,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,eAAe,EAAE;QACf,0BAA0B;QAC1B,EAAE;QACF,oDAAoD;QACpD,6FAA6F;QAC7F,4FAA4F;QAC5F,uGAAuG;QACvG,0FAA0F;QAC1F,6GAA6G;QAC7G,2FAA2F;QAC3F,0GAA0G;KAC3G,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,MAAM,EAAE;QACN,iBAAiB;QACjB,EAAE;QACF,4FAA4F;QAC5F,4FAA4F;QAC5F,yEAAyE;QACzE,mGAAmG;QACnG,gGAAgG;QAChG,2DAA2D;QAC3D,8BAA8B;KAC/B,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,mBAAmB,EAAE;QACnB,4BAA4B;QAC5B,EAAE;QACF,8IAA8I;QAC9I,kFAAkF;QAClF,uHAAuH;QACvH,oFAAoF;QACpF,0EAA0E;QAC1E,8GAA8G;QAC9G,yGAAyG;QACzG,sFAAsF;QACtF,8EAA8E;KAC/E,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,mBAAmB,EAAE;QACnB,4BAA4B;QAC5B,EAAE;QACF,4DAA4D;QAC5D,+HAA+H;QAC/H,mFAAmF;QACnF,0GAA0G;QAC1G,+GAA+G;QAC/G,qGAAqG;QACrG,mFAAmF;KACpF,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,0BAA0B,EAAE;QAC1B,4CAA4C;QAC5C,EAAE;QACF,4BAA4B;QAC5B,oFAAoF;QACpF,8FAA8F;QAC9F,iDAAiD;QACjD,yHAAyH;QACzH,4DAA4D;QAC5D,EAAE;QACF,oEAAoE;QACpE,wFAAwF;QACxF,0FAA0F;QAC1F,iGAAiG;QACjG,EAAE;QACF,yCAAyC;QACzC,oGAAoG;QACpG,mEAAmE;QACnE,EAAE;QACF,gGAAgG;QAChG,4FAA4F;KAC7F,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,+BAA+B,EAAE;QAC/B,2CAA2C;QAC3C,EAAE;QACF,wGAAwG;QACxG,oHAAoH;QACpH,uHAAuH;QACvH,EAAE;QACF,2CAA2C;QAC3C,yFAAyF;QACzF,gGAAgG;QAChG,EAAE;QACF,oDAAoD;QACpD,gHAAgH;KACjH,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,4BAA4B,EAAE;QAC5B,qCAAqC;QACrC,EAAE;QACF,oGAAoG;QACpG,0DAA0D;QAC1D,wGAAwG;QACxG,qGAAqG;QACrG,+FAA+F;QAC/F,4FAA4F;QAC5F,mGAAmG;KACpG,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,oCAAoC,EAAE;QACpC,yCAAyC;QACzC,EAAE;QACF,gEAAgE;QAChE,wDAAwD;QACxD,8GAA8G;QAC9G,6EAA6E;QAC7E,+DAA+D;QAC/D,2GAA2G;QAC3G,8FAA8F;QAC9F,EAAE;QACF,iEAAiE;QACjE,qHAAqH;QACrH,uGAAuG;QACvG,2FAA2F;QAC3F,yGAAyG;QACzG,iHAAiH;KAClH,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,0BAA0B,EAAE;QAC1B,+CAA+C;QAC/C,EAAE;QACF,uHAAuH;QACvH,EAAE;QACF,gDAAgD;QAChD,0HAA0H;QAC1H,2HAA2H;QAC3H,mGAAmG;QACnG,4FAA4F;QAC5F,gHAAgH;QAChH,qHAAqH;QACrH,EAAE;QACF,6GAA6G;QAC7G,qHAAqH;QACrH,4GAA4G;KAC7G,CAAC,IAAI,CAAC,IAAI,CAAC;CACb,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ToolRegistrar } from "./gateway/capturing-server.js";
|
|
2
|
-
export declare const SKILL_TOPICS: readonly ["getting-started", "oauth", "yootheme", "joomla", "troubleshooting", "render"];
|
|
2
|
+
export declare const SKILL_TOPICS: readonly ["getting-started", "oauth", "yootheme", "joomla", "troubleshooting", "render", "jmespath-pitfalls", "jmespath-cookbook", "merge-two-sources-on-key", "conditional-style-multi-items", "library-template-discovery", "yootheme-source-to-builder-handoff", "dynamize-existing-layout"];
|
|
3
3
|
export type SkillTopic = (typeof SKILL_TOPICS)[number];
|
|
4
4
|
export declare function registerGetSkillTool(server: ToolRegistrar, rootDir?: string): void;
|